import { createMachine, assign } from 'xstate'; export type FileContext = { files: File[]; multiple: boolean; allowedTypes: string[]; data: any; }; export const fileMachine = createMachine( { tsTypes: {} as import("./file.machine.typegen").Typegen0, schema: { context: {} as FileContext, events: {} as { type: 'FILE_LOADING' } | { type: 'FILE_CHANGE', files: File[] } | { type: 'FILE_SUCCESS' } | { type: 'FILE_FAILURE' } }, initial: 'idle', context: { files: [], multiple: false, allowedTypes: ['*'], data: null }, states: { idle: { on: { 'FILE_LOADING': 'loading' } }, loading: { on: { 'FILE_CHANGE': { target: 'reading', actions: [ 'fileChange' ] }, 'FILE_FAILURE': { target: 'failure' } } }, reading: { invoke: { id: 'read', src: 'read', onDone: { actions: [ 'assignData' ], target: 'success' }, onError: { target: 'failure' } } }, success: { type: 'final', data: (context, event) => (event as any).data }, failure: { on: { 'FILE_CHANGE': 'loading' } } } }, { services: { read: async (context, event) => new Promise(( resolve, reject) => { // do file reader thingy here console.log("READ FUNCTION: ", context, event); const input = context.files[0]; const reader = new FileReader(); reader.onload = function (e) { const text: any = e.target.result; resolve( text ) }; reader.readAsText(input); }) }, actions: { fileChange: assign({ files: (context, event) => event.files }), assignData: assign({ data: (context, event) => { return event.data } }) } });