https://github.com/nocode-js/sequential-workflow-machine
Powerful sequential workflow machine for front-end and back-end applications.
https://github.com/nocode-js/sequential-workflow-machine
javascript lowcode nocode typescript workflow workflow-engine workflows
Last synced: 3 months ago
JSON representation
Powerful sequential workflow machine for front-end and back-end applications.
- Host: GitHub
- URL: https://github.com/nocode-js/sequential-workflow-machine
- Owner: nocode-js
- License: mit
- Created: 2023-03-04T10:22:37.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-17T13:32:44.000Z (9 months ago)
- Last Synced: 2025-02-07T12:12:52.842Z (3 months ago)
- Topics: javascript, lowcode, nocode, typescript, workflow, workflow-engine, workflows
- Language: TypeScript
- Homepage:
- Size: 188 KB
- Stars: 48
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Sequential Workflow Machine
[](https://actions-badge.atrox.dev/b4rtaz/sequential-workflow-machine/goto?ref=main) [](/LICENSE) [](https://npmjs.org/package/sequential-workflow-machine)
The powerful sequential workflow machine for frontend and backend applications. It provides a simple API for creating its own step execution handlers (activities). It supports multiple types of activities. Internally it uses the [xstate](https://github.com/statelyai/xstate) library.
This machine uses the same data model as the [Sequential Workflow Designer](https://github.com/nocode-js/sequential-workflow-designer). So you can create a workflow definition in the designer and then run it by this machine easily.
📝 Check the [documentation](https://nocode-js.com/docs/category/sequential-workflow-machine) for more details.
## 🚀 Installation
Install the following packages by NPM command:
```
npm i sequential-workflow-model sequential-workflow-machine
```## 🎬 Usage
You can use the machine in a JavaScript or TypeScript application. We recommend using TypeScript because a workflow uses a lot of data structures and it's hard to maintain data integrity.
At the beginning, you need to define the type of your workflow definition.
```ts
import { Definition } from 'sequential-workflow-model';interface MyDefinition extends Definition {
properties: {
verbose: boolean;
};
}
```Next, define your step types.
```ts
import { Step } from 'sequential-workflow-model';interface DownloadHtmlStep extends Step {
componentType: 'task';
type: 'downloadHtml';
properties: {
pageUrl: string;
};
}// ...
```Prepare the workflow definition.
```ts
const definition: MyDefinition = {
properties: {
verbose: true,
},
sequence: [
{
id: '0x00001',
componentType: 'task',
type: 'downloadHtml',
name: 'Download google.com',
properties: {
pageUrl: 'https://www.google.com',
},
},
],
};
```Prepare the global state interface.
```ts
interface WorkflowGlobalState {
html: string | null;
}
```Prepare activities for your steps. The machine supports multiple types of activities. The basic activity is the atom activity. It's a simple handler that executes an atomic step and updates the global state.
```ts
import { createAtomActivity } from 'sequential-workflow-machine';interface DownloadHtmlStepState {
attempt: number;
}const downloadHtmlActivity = createAtomActivity('downloadHtml', {
init: () => ({
attempt: 0,
}),
handler: async (step: DownloadHtmlStep, globalState: WorkflowGlobalState, activityState: DownloadHtmlStepState) => {
globalState.html = await downloadHtml(step.properties.pageUrl);
activityState.attempt++;
},
});
```Now we can create the activity set. The activity set is a collection of all supported activities.
```ts
import { createActivitySet } from 'sequential-workflow-machine';const activitySet = createActivitySet([
downloadHtmlActivity,
]);
```Finally, we can create the workflow machine and run it.
```ts
import { createWorkflowMachineBuilder } from 'sequential-workflow-machine';const builder = createWorkflowMachineBuilder(activitySet);
const machine = builder.build(definition);
const interpreter = machine.create({
init: () => {
return {
html: null,
};
}
});
interpreter.onChange(() => { /* ... */ });
interpreter.onDone(() => { /* ... */ });
interpreter.start();
```That's it!
## 💡 License
This project is released under the MIT license.