Skip to content

Instantly share code, notes, and snippets.

@UberMouse
Created January 7, 2024 22:54
Show Gist options
  • Save UberMouse/00c5f6b325cc3080bf87cf874f60186e to your computer and use it in GitHub Desktop.
Save UberMouse/00c5f6b325cc3080bf87cf874f60186e to your computer and use it in GitHub Desktop.
/**
* @public
*
* Wraps an xstate-tree returning Promise (generated by `import()` in an xstate-tree machine responsible for
* booting up the machine upon resolution
*
* @param factory - the factory function that returns the promise that resolves to the machine
* @param options - configure loading component and context to invoke machine with
* @returns an xstate-tree machine that wraps the promise, invoking the resulting machine when it resolves
*/
export function lazy<TMachine extends AnyXstateTreeMachine>(
factory: () => Promise<TMachine>,
{
Loader = () => null,
input,
}: Options<ContextFrom<TMachine>> = {}
): AnyXstateTreeMachine {
const loadedMachineSlot = singleSlot("loadedMachine");
const slots = [loadedMachineSlot];
let loadedMachine: AnyXstateTreeMachine | undefined = undefined;
const machine = createMachine({
initial: "loading",
states: {
loading: {
invoke: {
src: fromPromise(factory),
onDone: {target: "rendering", actions: ({event}) => loadedMachine = event.output},
},
},
rendering: {
entry: () => console.log("Lazy loaded", loadedMachine),
invoke: {
id: loadedMachineSlot.getId(),
src: (loadedMachine as unknown as AnyXstateTreeMachine),
onSnapshot: {actions: ({context, event}) => {
console.log("Snapshot", context, event);
}},
input
},
},
},
});
// <snip>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment