Skip to content

Instantly share code, notes, and snippets.

@ggoodman
Created March 10, 2020 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ggoodman/57e220d9d6bd218af4edd48279425db2 to your computer and use it in GitHub Desktop.
Save ggoodman/57e220d9d6bd218af4edd48279425db2 to your computer and use it in GitHub Desktop.
Example of generating a typed FSM for a Promise
type PromiseReject = {
eventName: '@@promiseReject';
err: unknown;
};
type PromiseResolve<T> = {
eventName: '@@promiseResolve';
value: T;
};
type PromisePending<T> = FSM.IntermediateState<{
stateName: '@@promisePending';
promise: Promise<T>;
}>;
type PromiseResolved<T> = FSM.FinalState<{
stateName: '@@promiseResolved';
value: T;
}>;
type PromiseRejected = FSM.FinalState<{
stateName: '@@promiseRejected';
err: unknown;
}>;
export function fromPromise<T>(promise: Promise<T>) {
const promiseMachine = createMachineFactory<
PromiseReject | PromiseResolve<T>,
PromisePending<T> | PromiseResolved<T> | PromiseRejected
>().state('@@promisePending', state =>
state
.onEnterExecute((state, _event, send) => {
state.promise.then(
value => send({ eventName: '@@promiseResolve', value }),
err => send({ eventName: '@@promiseReject', err })
);
})
.onEventTransition(
'@@promiseResolve',
(_state, event) => ({
stateName: '@@promiseResolved',
value: event.value,
}),
{
targetStates: ['@@promiseResolved'],
}
)
.onEventTransition(
'@@promiseReject',
(_state, event) => ({
stateName: '@@promiseRejected',
err: event.err,
}),
{
targetStates: ['@@promiseRejected'],
}
)
);
return promiseMachine.instantiate({
stateName: '@@promisePending',
promise,
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment