import { createMachine, assign, send, sendParent, spawn } from 'xstate'; import { textMachine } from '$lib/State/textMachine'; import { choiceMachine } from '$lib/State/choiceMachine'; import type { SelectModel } from '$lib/Models'; import { ChoiceModel } from '$lib/Models'; export type SelectContext = { field: SelectModel, choiceModel: ChoiceModel, textMachine: any, choiceMachine: any, broadcastEvent: { type: string, key: string } } export type SelectState = { value: 'idle'; context: SelectContext } | { value: 'typing'; context: SelectContext }; export const selectMachine = createMachine( { tsTypes: {} as import("./selectMachine.typegen").Typegen0, schema: { context: {} as SelectContext, events: {} as { type: 'TEXT_CHANGE'; field: any } | { type: 'CHOICE_CHANGE'; field: any } | { type: 'FOCUS'; value: any } }, id: '', initial: 'idle', context: { field: null, textMachine: null, choiceModel: null, choiceMachine: null, broadcastEvent: { type: 'CHANGE', key: 'value' } }, states: { idle: { entry: [ 'assignChoiceModel', 'assignTextMachine', 'assignChoiceMachine' ], always: 'active' }, active: { on: { TEXT_CHANGE: { actions: [ (c,e) => console.log("getting text changes: ", e), 'forwardTextToChoiceMachine' ] }, CHOICE_CHANGE: { actions: [ 'assignSelected', 'notifyParent' ] } }, }, submitted: { type: 'final' }, }, }, { actions: { assignChoiceModel: assign({ choiceModel: (context, event) => new ChoiceModel({ dataSourceUrl: context.field.endpoint, dataKey: 'title' }) }), assignTextMachine: assign({ textMachine: (context, event) => spawn( textMachine.withContext({ ...textMachine.context, broadcastEvent: { type: 'TEXT_CHANGE', key: 'field' } }), { name: 'textMachineId', sync: true } ) }), assignChoiceMachine: assign({ choiceMachine: (context, event) => spawn( choiceMachine.withContext({ ...choiceMachine.context, field: context.choiceModel, broadcastEvent: { type: 'CHOICE_CHANGE', key: 'field' } }), { name: 'choiceMachineId', sync: true } ) }), forwardTextToChoiceMachine: send((context, event) => { context.choiceModel.dataSourceUrl = `${context.field.endpoint}/${ event.field.value }`; console.log("FORWARDING TO CHOICE MACHINE NOW: ", ); return { type: 'FETCH_DATA_FROM_REMOTE_URL' }; }, { to: (context, event) => context.choiceMachine }), assignSelected: assign({ // TODO: get Text machine to accept setting it's text without causing cascading changes field: (context, event) => { context.field.value = event.field.value; return context.field; } }), notifyParent: sendParent((context, event) => { return { type: context.broadcastEvent.type, [ context.broadcastEvent.key ]: context.field }; }) } });