examples/workflow-media-scanner/README.md
This is a small example of a back-end workflow that uses a state machine to execute long running tasks. This project crawls a directory full of movies and separates out videos over 1080p for potential processing down the line.
NOTE:This project is not intended for production use.
This project requires ffprobe, a binary that ships alongside ffmpeg, which is the golden standard for media file manipulation.
yarn (or use your package manager of choice) in a terminal at the project's root.basePath and destinationPath in the mediaScannerMachine.ts file with your own paths.yarn start in the terminalThis project convers how to implement the following with XState:
Initializing a XState machine as an actor
// index.ts
// ...
const mediaScannerActor = createActor(mediaScannerMachine);
Injecting context information into the actor on initialization
// index.ts
// ...
const mediaScannerActor = createActor(mediaScannerMachine, {
input: {
basePath: 'YOUR BASE PATH HERE',
destinationPath: 'YOUR DESTINATION PATH HERE'
}
});
Sending events to the XState actor
// index.ts
// ...
mediaScannerActor.send({ type: 'START_SCAN' });
Subscribing to a running actor for state change and context information
// index.ts
// ...
mediaScannerActor.subscribe((state) => {
console.log({
state: state.value,
error: state.error,
context: state.context
});
});
Invoking services and capturing results
mediaScannerMachine.ts
invoke: {
id: 'checkFilePermissions',
input: ({ context: { directoriesToCheck } }) => ({
directoriesToCheck
}),
src: fromPromise(async ({ input: { directoriesToCheck } }) =>
await checkFilePermissions(directoriesToCheck)
),
onDone: [
{
target: 'EvaluatingFiles',
actions: assign(({ event }) => {
return {
dirsToEvaluate: event.output['dirsToEvaluate'],
dirsToReport: event.output['dirsToReport']
};
})
}
],
onError: [
{
target: 'ReportingErrors',
actions: assign(({ event }) => {
return {
dirsToReport: event.error['dirsToReport']
};
})
}
]
}
Batching results and assigning multiple properties to the actor's context
fileHandlers.ts
...
return { dirsToEvaluate, dirsToReport };
mediaScannerMachine.ts
actions: assign(({ event }) => {
return {
dirsToEvaluate: event.output['dirsToEvaluate'],
dirsToReport: event.output['dirsToReport']
};
});