import type { IFieldBase } from '$lib/Models'; import { ArrayModel, ChoiceModel, FormModel, NestModel, NumberModel, SelectModel, TextModel } from '$lib/Models'; import { createMachine, assign, spawn, send } from 'xstate'; import { nanoid } from '../Services/nanoid'; import { hierarchyMachine } from './hierarchy.machine'; const builderArrayName = "builderArrayName"; const nestName = "nest"; const forkName = "fork"; const rootId = 'rootId'; // field // placeholder?: string; // imageUrl?: string; // order: number; // type: string; // text, file, choice, list etc // subType?: string; // text (password, email, url etc), file (image, pdf, csv etc) etc // label: string; // required // name: string; // required // description: string; // value: any; // optional // fork?: { [key: string]: StreamQuery } | null; // validation?: any[]; // optional // isValid?: boolean; // progress: number; // waitForHowManyMSBeforeSubmit: number; // nest // image // array // classExample: () => any; // addText?: string; // value: any[]; // wrangleResult: Function; // number // min?: number; // max?: number; // step?: number; // debounceFor: number; // customVisual?: any; // select // autocomplete?: boolean, // optional // optionIdentifier: string; // endpoint: string; // TODO: this should be a fork const typeRegistry = { 'text': [ 'singleLine', 'multiLine' ], 'choice': [ 'radio', 'checkbox' ], 'form': [ 'section', 'branch' ] } type FieldBuildStream = { main: IFieldBase[], [ key: string ]: IFieldBase[], } export type BuilderContext = { streamBuildMachine: any, streamNestMachine: any, streamForkMachine: any, streamPreviewMachine: any, builderStream: IFieldBase[], nestStream: IFieldBase[], forkStream: IFieldBase[], previewStream: IFieldBase[], choiceStream: FieldBuildStream, fieldValueMap: { [key:string]: any } } export type BuilderState = { value: 'initialising'; context: BuilderContext; } | { value: 'active'; context: BuilderContext; }; export const builderMachine = createMachine({ context: { streamBuildMachine: null, streamNestMachine: null, streamForkMachine: null, streamPreviewMachine: null, builderStream: [ // perfectly working builder vv new ArrayModel({ id: 'nameId', placeholder: 'Type the question fields here', imageUrl: '', type: 'text', subType: 'singleLine', name: builderArrayName, description: 'Please describe this question', label: '', value: [], fork: null, validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], waitForHowManyMSBeforeSubmit: 1000, classExample: () => [ new TextModel({ id: 'createAccount_emailId', parentId: "detailStream", placeholder: "What's your name?", imageUrl: '', type: "text", subType: 'singleLine', name: "one", description: "Please type your name", label: "", value: [], fork: null, validation: [ { operator: 'required', anchorValues: [1], message: 'This is not a valid email address' } ], waitForHowManyMSBeforeSubmit: 1000, debounceFor: 300 }), new TextModel({ id: 'createAccount_passwordId', parentId: "detailStream", placeholder: "And your surname?", imageUrl: '', type: "text", subType: 'singleLine', name: "two", description: "And your surname?", label: "", value: [], fork: null, validation: [ { operator: 'required', anchorValues: [1], message: 'A surname is required' } ], waitForHowManyMSBeforeSubmit: 1000, debounceFor: 300 }), new ChoiceModel({ id: 'checkboxId', parentId: "detailStream", placeholder: 'Pick from one of the options!', imageUrl: '', type: "choice", subType: 'checkbox', name: "three", description: "What kind of crew are you?", label: "", value: [], fork: { "deck_options": { operator: 'equalTo', anchorValues: ['Deck'], message: 'This field is required'}, "engineering_options": { operator: 'equalTo', anchorValues: ['Engineering'], message: 'This field is required'}, "kitchen_options": { operator: 'equalTo', anchorValues: ['Kitchen'], message: 'This field is required'}, }, validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], waitForHowManyMSBeforeSubmit: 1000, data: [ { name: 'Deck' }, { name: 'Engineering' }, { name: 'Kitchen' } ], scale: [], dataKey: 'name', }), new ChoiceModel({ id: "deck_options", parentId: "detailStream", placeholder: "Pick from one of the options!", imageUrl: '', type: "choice", subType: 'checkbox', name: "Select deck position", description: "What best describes your position?", label: "", value: [], fork: {}, validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], waitForHowManyMSBeforeSubmit: 1000, data: [ { name: 'Captain'}, { name: 'First mate'}, { name: 'A Deckhand!'} ], scale: [], dataKey: 'name', }), new ChoiceModel({ id: 'kitchen_options', parentId: "detailStream", placeholder: 'Pick from one of the options!', imageUrl: '', type: "choice", subType: 'checkbox', name: "Select kitchen position", description: "What best describes your position?", label: "", value: [], fork: {}, validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], waitForHowManyMSBeforeSubmit: 1000, data: [ { name: 'Head chef'}, { name: 'Sous chef'}, { name: 'Pastry chef'}, { name: 'Kitchen porter'} ], scale: [], dataKey: 'name', }), new FormModel({ id: 'engineering_options', parentId: 'detailStream', name: 'onboarding', subType: 'stepper', autosubmit: true, order: 1 }), new ChoiceModel({ id: 'engineering_options_1', parentId: "engineering_options", placeholder: 'Pick from one of the options!', imageUrl: '', type: "choice", subType: 'checkbox', name: "Select engineering position", description: "What best describes your position?", label: "", value: [], fork: {}, validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], waitForHowManyMSBeforeSubmit: 1000, data: [ { name: 'Chief engineer'}, { name: '2nd engineer'}, { name: '3rd engineer'}, { name: 'QMed'} ], scale: [], dataKey: 'name', }), new ChoiceModel({ id: 'engineering_options_2', parentId: "engineering_options", placeholder: 'Pick from one of the options!', imageUrl: '', type: "choice", subType: 'checkbox', name: "engineering options 2", description: "What best describes your position?", label: "", value: [], fork: { // 'deeply_nested': { operator: 'equalTo', anchorValues: ['1st Second question'], message: 'This field is required'}, }, validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], waitForHowManyMSBeforeSubmit: 1000, data: [ { name: '1st Second question'}, { name: '2nd Second question'}, { name: '3rd Second question'} ], scale: [], dataKey: 'name', }), new TextModel({ id: 'arrayClassExampleTextModel', parentId: "detailStream", placeholder: 'Type your forken name here', imageUrl: '', type: "text", subType: 'singleLine', name: "four k", description: "Please type your name", label: "", value: "", fork: { 'forkedQuestion': { operator: 'equalTo', anchorValues: ['fork'], message: 'This field is required'} }, validation: [ { operator: 'required', message: 'This field is required'}], waitForHowManyMSBeforeSubmit: 1000, debounceFor: 300 }), new TextModel({ id: 'forkedQuestion', parentId: "detailStream", placeholder: 'Type your forkedQuestion here', imageUrl: '', type: "text", subType: 'singleLine', name: "forkedQuestion", description: "Please type your name", label: "", value: [], fork: null, validation: [], waitForHowManyMSBeforeSubmit: 1000, debounceFor: 300 }), new ChoiceModel({ id: 'checkboxId2', parentId: "detailStream", placeholder: '', imageUrl: '', type: 'choice', subType: 'radio', name: 'five', description: 'Please choose your type', label: '', value: [], fork: null, validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], waitForHowManyMSBeforeSubmit: 1000, data: [ { typeName: 'form' }, { typeName: 'text' }, { typeName: 'choice' } ], dataKey: 'typeName', scale: [], // order: 1 }), new FormModel({ id: 'detailStream', name: 'onboarding', subType: 'stepper', autosubmit: true, order: 1 }) ], wrangleResult: (result: { arr: IFieldBase[]; acc: any }) => { let field; switch (result.acc.type) { case 'select': { field = new SelectModel(result.acc); break; } case 'choice': { field = new ChoiceModel(result.acc); break; } case 'text': { field = new TextModel(result.acc); break; } case 'form': { field = new FormModel(result.acc); break; } } return field; } }) ], // builderStream: [ // // perfectly working builder vv // new ArrayModel({ // id: 'nameId', // placeholder: 'Type your name here', // imageUrl: '', // type: 'text', // subType: 'singleLine', // name: builderArrayName, // description: 'Please type your name', // label: '', // value: [], // fork: null, // validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], // waitForHowManyMSBeforeSubmit: 1000, // classExample: () => [ // // new SelectModel({ // // id: 'selectId', // // placeholder: 'Type your select here', // // imageUrl: '', // // type: "select", // // subType: 'singleLine', // // name: builderArrayName, // // description: "Please type your name", // // label: "", // // value: [], // // fork: null, // // validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], // // waitForHowManyMSBeforeSubmit: 1000, // // endpoint: 'https://jsonplaceholder.typicode.com/todos' // // }) // new TextModel({ // id: 'arrayClassExampleTextModel', // parentId: "detailStream", // placeholder: 'Type your forken name here', // imageUrl: '', // type: "text", // subType: 'singleLine', // name: "a fork parent", // description: "Please type your name", // label: "", // value: "", // fork: { // 'forkedQuestion': { operator: 'equalTo', anchorValues: ['fork'], message: 'This field is required'} // }, // validation: [ { operator: 'required', message: 'This field is required'}], // waitForHowManyMSBeforeSubmit: 1000, // debounceFor: 300 // }), // new TextModel({ // id: 'forkedQuestion', // parentId: "detailStream", // placeholder: 'Type your forkedQuestion here', // imageUrl: '', // type: "text", // subType: 'singleLine', // name: "forkedQuestion", // description: "Please type your name", // label: "", // value: [], // fork: null, // validation: [], // waitForHowManyMSBeforeSubmit: 1000, // debounceFor: 300 // }), // new ChoiceModel({ // id: 'checkboxId', // parentId: "detailStream", // placeholder: '', // imageUrl: '', // type: 'choice', // subType: 'radio', // name: 'type', // description: 'Please choose your type', // label: '', // value: [], // fork: null, // validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { typeName: 'form' }, // { typeName: 'text' }, // { typeName: 'choice' } // ], // dataKey: 'typeName', // // data: null, // // dataSourceId: 'test', // // dataSourceUrl: 'https://jsonplaceholder.typicode.com/todos', // // dataKey: 'title', // scale: [], // order: 1 // }), // // new ChoiceModel({ // // id: 'subtypecheckboxId', // // placeholder: '', // // imageUrl: '', // // type: "choice", // // subType: 'radio', // // name: "subType", // // description: "Please choose your sub type", // // label: "", // // value: [], // // fork: null, // // validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], // // waitForHowManyMSBeforeSubmit: 1000, // // // data: [ // // // { typeName: 'step'}, // // // { typeName: 'text'}, // // // { typeName: 'choice'} // // // ], // // // dataKey: 'typeName', // // data: null, // // dataRegistry: typeRegistry, // // dataSourceId: 'checkboxId', // // // dataSourceUrl: 'https://jsonplaceholder.typicode.com/todos', // // // dataKey: 'title', // // scale: [], // // order: 2 // // }), // new TextModel({ // id: 'nameId', // parentId: "detailStream", // placeholder: 'This question is called...', // imageUrl: '', // type: "text", // subType: 'singleLine', // name: "name", // description: "What is the question called?", // label: "", // value: "", // fork: null, // validation: [ { operator: 'required', message: 'This field is required'}], // waitForHowManyMSBeforeSubmit: 3000, // debounceFor: 300, // order: 3 // }), // // new TextModel({ // // id: 'descriptionId', // // placeholder: 'Description please!', // // imageUrl: '', // // type: "text", // // subType: 'singleLine', // // name: "description", // // description: "What is the question about?", // // label: "", // // value: "", // // fork: null, // // validation: [ { operator: 'required', message: 'This field is required'} ], // // waitForHowManyMSBeforeSubmit: 3000, // // debounceFor: 300, // // order: 4 // // }), // // new NumberModel({ // // id: 'waitforId', // // placeholder: 'Wait for...?', // // imageUrl: '', // // name: 'Wait for?', // // description: 'How long must the question waits before it submits itself?', // // label: '', // // value: [], // // fork: null, // // validation: [{ operator: 'required', message: 'This field is required' }], // // waitForHowManyMSBeforeSubmit: 3000, // // min: 100, // // max: 10000, // // debounceFor: 200, // // customVisual: null, // // order: 5 // // }) // new TextModel({ // id: 'createAccount_emailId', // parentId: "detailStream", // placeholder: "What's your name?", // imageUrl: '', // type: "text", // subType: 'singleLine', // name: "Name", // description: "Please type your name", // label: "", // value: [], // fork: null, // validation: [ { operator: 'required', anchorValues: [1], message: 'This is not a valid email address' } ], // waitForHowManyMSBeforeSubmit: 1000, // debounceFor: 300 // }), // new TextModel({ // id: 'createAccount_passwordId', // parentId: "detailStream", // placeholder: "And your surname?", // imageUrl: '', // type: "text", // subType: 'singleLine', // name: "Surname", // description: "And your surname?", // label: "", // value: [], // fork: null, // validation: [ // { operator: 'required', anchorValues: [1], message: 'A surname is required' } // ], // waitForHowManyMSBeforeSubmit: 1000, // debounceFor: 300 // }), // new ChoiceModel({ // id: 'checkboxId2', // parentId: "detailStream", // placeholder: 'Pick from one of the options!', // imageUrl: '', // type: "choice", // subType: 'checkbox', // name: "Select Profession", // description: "What kind of crew are you?", // label: "", // value: [], // fork: { // "deck_options": { operator: 'equalTo', anchorValues: ['Deck'], message: 'This field is required'}, // "engineering_options": { operator: 'equalTo', anchorValues: ['Engineering'], message: 'This field is required'}, // "kitchen_options": { operator: 'equalTo', anchorValues: ['Kitchen'], message: 'This field is required'}, // }, // validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { name: 'Deck' }, // { name: 'Engineering' }, // { name: 'Kitchen' } // ], // scale: [], // dataKey: 'name', // }), // new ChoiceModel({ // id: "deck_options", // parentId: "detailStream", // placeholder: "Pick from one of the options!", // imageUrl: '', // type: "choice", // subType: 'checkbox', // name: "Select deck position", // description: "What best describes your position?", // label: "", // value: [], // fork: {}, // validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { name: 'Captain'}, // { name: 'First mate'}, // { name: 'A Deckhand!'} // ], // scale: [], // dataKey: 'name', // }), // new ChoiceModel({ // id: 'kitchen_options', // parentId: "detailStream", // placeholder: 'Pick from one of the options!', // imageUrl: '', // type: "choice", // subType: 'checkbox', // name: "Select kitchen position", // description: "What best describes your position?", // label: "", // value: [], // fork: {}, // validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { name: 'Head chef'}, // { name: 'Sous chef'}, // { name: 'Pastry chef'}, // { name: 'Kitchen porter'} // ], // scale: [], // dataKey: 'name', // }), // new FormModel({ // id: 'engineering_options', // parentId: 'detailStream', // name: 'onboarding', // subType: 'stepper', // autosubmit: true, // order: 1 // }), // new ChoiceModel({ // id: 'engineering_options_1', // parentId: "engineering_options", // placeholder: 'Pick from one of the options!', // imageUrl: '', // type: "choice", // subType: 'checkbox', // name: "Select engineering position", // description: "What best describes your position?", // label: "", // value: [], // fork: {}, // validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { name: 'Chief engineer'}, // { name: '2nd engineer'}, // { name: '3rd engineer'}, // { name: 'QMed'} // ], // scale: [], // dataKey: 'name', // }), // new ChoiceModel({ // id: 'engineering_options_2', // parentId: "engineering_options", // placeholder: 'Pick from one of the options!', // imageUrl: '', // type: "choice", // subType: 'checkbox', // name: "engineering options 2", // description: "What best describes your position?", // label: "", // value: [], // fork: { // // 'deeply_nested': { operator: 'equalTo', anchorValues: ['1st Second question'], message: 'This field is required'}, // }, // validation: [ { operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' } ], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { name: '1st Second question'}, // { name: '2nd Second question'}, // { name: '3rd Second question'} // ], // scale: [], // dataKey: 'name', // }), // new FormModel({ // id: 'detailStream', // name: 'onboarding', // subType: 'stepper', // autosubmit: true, // order: 1 // }) // ], // wrangleResult: (result: { arr: IFieldBase[]; acc: any }) => { // let field; // switch (result.acc.type) { // case 'select': { // field = new SelectModel(result.acc); // break; // } // case 'choice': { // field = new ChoiceModel(result.acc); // break; // } // case 'text': { // field = new TextModel(result.acc); // break; // } // case 'form': { // field = new FormModel(result.acc); // break; // } // } // return field; // } // }) // ], // builderStream: [ // // new ChoiceModel({ // // id: 'choice_data', // // placeholder: '', // // imageUrl: '', // // type: 'choice', // // subType: 'radio', // // name: 'Please specify the source of the datakey', // // description: 'Please choose your data source', // // label: '', // // value: [], // // fork: { // // 'choice_data_specify': { operator: 'equalTo', anchorValues: ['specify data'], message: 'This field is required'}, // // 'choice_data_dataSourceId': { operator: 'equalTo', anchorValues: ['get data from previous answer'], message: 'This field is required'}, // // 'choice_data_url': { operator: 'equalTo', anchorValues: ['get data from remote url'], message: 'This field is required'} // // }, // // validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], // // waitForHowManyMSBeforeSubmit: 1000, // // data: [ // // { typeName: 'specify data' }, // this needs a choice between simple and complex object type and then an array builder // // { typeName: 'get data from previous answer' }, // this needs an id of a previous question and potentially a datakey (choice_data_datakey) // // { typeName: 'get data from remote url' }, // this needs an url (choice_data_url) and potentially a datakey (choice_data_datakey) // // ], // // dataKey: 'typeName', // // scale: [], // // order: 1 // // }), // // // datakey // // new ChoiceModel({ // // id: 'choice_data_specify', // // placeholder: '', // // imageUrl: '', // // type: 'choice', // // subType: 'radio', // // name: 'Please specify the source of the datakey', // // description: 'Please choose your data source', // // label: '', // // value: [], // // fork: { // // 'forkedQuestion': { operator: 'equalTo', anchorValues: ['fork'], message: 'This field is required'} // // }, // // validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], // // waitForHowManyMSBeforeSubmit: 1000, // // data: [ // // { typeName: 'specify datakey' }, // // { typeName: 'get datakey from previous answer' } // // ], // // dataKey: 'typeName', // // scale: [], // // order: 1 // // }), // new FormModel({ // id: 'formExampleId', // subType: 'stepper', // autosubmit: false // }), // new ChoiceModel({ // id: 'choice_data_specify', // placeholder: '', // parentId: 'formExampleId', // imageUrl: '', // type: 'choice', // subType: 'radio', // name: 'Please specify the source of the datakey', // description: 'Please choose your data source', // label: '', // value: [], // fork: { // 'forkedQuestion': { operator: 'equalTo', anchorValues: ['fork'], message: 'This field is required'} // }, // validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { typeName: 'specify datakey' }, // { typeName: 'get datakey from previous answer' } // ], // dataKey: 'typeName', // scale: [], // order: 1 // }) // ], previewStream: [], nestStream: [ new NestModel({ id: 'nestId', placeholder: 'Nest away!', imageUrl: '', name: nestName, description: 'Please nest these objects', label: '', value: [], fork: null, validation: [], waitForHowManyMSBeforeSubmit: 5000 }) ], forkStream: [ // new ForkModel({ // id: 'forkId', // placeholder: 'Fork away!', // imageUrl: '', // name: forkName, // description: 'Please fork these objects', // label: '', // value: [], // fork: null, // validation: [], // waitForHowManyMSBeforeSubmit: 5000 // }) ], choiceStream: { main: [ // new ChoiceModel({ // id: 'choice_data', // placeholder: '', // imageUrl: '', // type: 'choice', // subType: 'radio', // name: 'Please specify the source of the datakey', // description: 'Please choose your data source', // label: '', // value: [], // fork: { // 'choice_data_specify': { operator: 'equalTo', anchorValues: ['specify data'], message: 'This field is required'}, // 'choice_data_dataSourceId': { operator: 'equalTo', anchorValues: ['get data from previous answer'], message: 'This field is required'}, // 'choice_data_url': { operator: 'equalTo', anchorValues: ['get data from remote url'], message: 'This field is required'} // }, // validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { typeName: 'specify data' }, // this needs a choice between simple and complex object type and then an array builder // { typeName: 'get data from previous answer' }, // this needs an id of a previous question and potentially a datakey (choice_data_datakey) // { typeName: 'get data from remote url' }, // this needs an url (choice_data_url) and potentially a datakey (choice_data_datakey) // ], // dataKey: 'typeName', // scale: [], // order: 1 // }), // // datakey // new ChoiceModel({ // id: 'choice_data_specify', // placeholder: '', // imageUrl: '', // type: 'choice', // subType: 'radio', // name: 'Please specify the source of the datakey', // description: 'Please choose your data source', // label: '', // value: [], // fork: { // 'forkedQuestion': { operator: 'equalTo', anchorValues: ['fork'], message: 'This field is required'} // }, // validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], // waitForHowManyMSBeforeSubmit: 1000, // data: [ // { typeName: 'specify datakey' }, // { typeName: 'get datakey from previous answer' } // ], // dataKey: 'typeName', // scale: [], // order: 1 // }), new FormModel({ id: 'formExample', placeholder: 'Your form here', imageUrl: '', subType: 'singleLine', name: "form example", description: "Please type your name", label: "", value: [ new ChoiceModel({ id: 'choice_data_specify', placeholder: '', imageUrl: '', type: 'choice', subType: 'radio', name: 'Please specify the source of the datakey', description: 'Please choose your data source', label: '', value: [], fork: { 'forkedQuestion': { operator: 'equalTo', anchorValues: ['fork'], message: 'This field is required'} }, validation: [{ operator: 'chosenAtLeast', anchorValues: [1], message: 'we can try' }], waitForHowManyMSBeforeSubmit: 1000, data: [ { typeName: 'specify datakey' }, { typeName: 'get datakey from previous answer' } ], dataKey: 'typeName', scale: [], order: 1 }), ], validation: [ { operator: 'required', message: 'This field is required'}], waitForHowManyMSBeforeSubmit: 1000, }), ], }, fieldValueMap: {} }, tsTypes: {} as import('./builder.machine.typegen').Typegen0, schema: { context: {} as BuilderContext, events: {} as | { type: 'ADD_FIELD' } | { type: 'REMOVE_FIELD' } | { type: 'PRINT_STREAM' } | { type: 'STREAM_BUILD_RESULT'; data: { arr: IFieldBase[]; acc: any } } | { type: 'STREAM_NEST_RESULT'; data: { arr: IFieldBase[]; acc: any } } | { type: 'STREAM_FORK_RESULT'; data: { arr: IFieldBase[]; acc: any } } | { type: 'STREAM_PREVIEW_RESULT'; data: { arr: IFieldBase[]; acc: any } } }, id: '(machine)', initial: 'initialising', states: { initialising: { entry: ['assignBuilderMachine', 'assignMachines'], always: { target: 'active' } }, active: { on: { ADD_FIELD: { actions: 'getActive' }, REMOVE_FIELD: { actions: 'getActive' }, PRINT_STREAM: { actions: 'clearBuilder' }, STREAM_BUILD_RESULT: { actions: ['addNewField', 'broadcastFields'] }, STREAM_NEST_RESULT: { actions: [ 'updateNewField', 'assignPreviewMachine' ] }, STREAM_FORK_RESULT: { actions: [ 'updateNewField', 'assignPreviewMachine' ] } } } } }, { actions: { assignBuilderMachine: assign({ streamBuildMachine: (context,event) => spawn( hierarchyMachine.withContext({ ...hierarchyMachine.context, data: context.builderStream, publishDraftResult: true, hasParent: true, id: 'streamBuilderMachine_context_id', notifyParentEventType: 'STREAM_BUILD_RESULT' }), { name: 'streamBuildMachine', sync: true } ) }), assignMachines: assign({ streamBuildMachine: (context,event) => { console.log(" context in assignMachines: ", context); return spawn( hierarchyMachine.withContext({ ...hierarchyMachine.context, data: context.builderStream, publishDraftResult: true, hasParent: true, id: 'streamBuilderMachine_context_id', notifyParentEventType: 'STREAM_BUILD_RESULT' }), { name: 'streamBuildMachine', sync: true } ) }, streamNestMachine: (context,event) => spawn( hierarchyMachine.withContext({ ...hierarchyMachine.context, data: context.nestStream, publishDraftResult: true, hasParent: true, notifyParentEventType: 'STREAM_NEST_RESULT' }), { name: 'streamNestMachine', sync: true } ), streamForkMachine: (context,event) => spawn( hierarchyMachine.withContext({ ...hierarchyMachine.context, data: context.forkStream, publishDraftResult: true, hasParent: true, notifyParentEventType: 'STREAM_FORK_RESULT' }), { name: 'streamForkMachine', sync: true } ), streamPreviewMachine: (context,event) => spawn( hierarchyMachine.withContext({ ...hierarchyMachine.context, data: context.previewStream, hasParent: true, notifyParentEventType: 'STREAM_PREVIEW_RESULT' }), { name: 'streamPreviewMachine', sync: true } ) }), assignPreviewMachine: assign({ streamPreviewMachine: (context,event) => spawn( hierarchyMachine.withContext({ ...hierarchyMachine.context, data: context.previewStream, hasParent: true, notifyParentEventType: 'STREAM_PREVIEW_RESULT' }), { name: 'streamPreviewMachine', sync: true } ) }), // addNewField: assign((context, event) => { // const newField = event.data.acc[ builderArrayName ].filter(item => { // return !context.nestStream[0].value.find(d => d.id === item.id) // })[0]; // const newStream = [ // ...context.nestStream[0].value, // newField // ]; // // context.nestStream[0].value = newStream; // context.previewStream = newStream; // // exp // // context.forkStream[0].value = newStream; // // end // return context; // }), // addNewField: send((context, event) => { // const newField = event.data.acc[ builderArrayName ].filter(item => { // return !context.fieldValueMap[item.id]; // })[0]; // return { type: 'ADD_NEW_FIELD', item: newField }; // }, { to: (context, event) => context.streamNestMachine }), addNewField: assign((context, event) => { const newField = event.data.acc[ builderArrayName ].filter(item => { return !context.fieldValueMap[item.id]; })[0]; context.fieldValueMap[ newField.id ] = newField; return context; }), // updateNewField: assign((context, event) => { // const newStream = [ ...event.data.acc[ nestName ] ]; // console.log("newStream: ", newStream); // context.nestStream[0].value = newStream; // context.previewStream = newStream; // return context; // }), updateNewField: assign((context, event) => { const newStream = [ ...event.data.acc[ forkName ] ]; console.log("newStream: ", newStream); context.forkStream[0].value = newStream; context.previewStream = newStream; return context; }), broadcastFields: send((context, event) => { return { type: 'REFRESH_FIELDS', fieldMap: context.fieldValueMap }; }, { to: (context, event) => context.streamForkMachine }) // }, { to: (context, event) => context.streamNestMachine }) } });