State
The workflow state keeps track of the state of the workflow as it progresses. The state is stored in the configured persistence, and can be used to map incoming messages to handlers.
A workflow state is created by extending WorkflowState. The
$name
property should be unique among all of your workflows. import { WorkflowState } from '@node-ts/bus-core'
export class FulfilmentWorkflowState extends WorkflowState {
static NAME = 'FulfilmentWorkflowState'
$name = FulfilmentWorkflowState.NAME
// Set of user-defined state properties
itemId: string
customerId: string
status: 'posting-item' | 'sending-receipt' | 'complete'
}
The state is available as the second parameter to all handlers of a workflow. For example:
import { Workflow } from '@node-ts/bus-core'
export class FulfilmentWorkflow extends Workflow<FulfilmentWorkflowState> {
configureWorkflow (
mapper: WorkflowMapper<FulfilmentWorkflowState, FulfilmentWorkflow>
): void {
mapper
.withState(FulfilmentWorkflowState)
// ...
.when(ItemShipped, 'emailReceipt')
}
// Workflow state is passed in as the second parameter to a workflow handler
async emailReceipt (_: ItemShipped, state: FulfilmentWorkflowState) {
// ...
}
}
The state cannot be modified directly within a handling scope but can be updated by returning the intended changes from a handler. Returning an updated state is optional, and if omitted then no changes to the state will be persisted.
import { Workflow } from '@node-ts/bus-core'
export class FulfilmentWorkflow extends Workflow<FulfilmentWorkflowState> {
configureWorkflow (
mapper: WorkflowMapper<FulfilmentWorkflowState, FulfilmentWorkflow>
): void {
mapper
.withState(FulfilmentWorkflowState)
// ...
.when(ItemShipped, 'emailReceipt')
}
// Workflow state is passed in as the second parameter to a workflow handler
async emailReceipt (_: ItemShipped, state: FulfilmentWorkflowState) {
return { status: 'sending-receipt' }
}
}
There are times when the workflow data shouldn't persist after a message has been handled. This is particularly relevant in cases where a workflow should only handle a message under certain circumstances.
For example, if your workflow is started by an S3ObjectCreated event, but should only create a new workflow if the object key is prefixed with
/documents
, then this can be achieved by returning this.discardWorkflow()
in the workflow like so:import { Workflow, BusInstance } from '@node-ts/bus-core'
export class ProcessDocumentWorkflow extends Workflow<ProcessDocumentWorkflowState> {
constructor (bus: BusInstance) {}
configureWorkflow (
mapper: WorkflowMapper<ProcessDocumentWorkflowState, ProcessDocumentWorkflow>
): void {
mapper
.withState(ProcessDocumentWorkflowState)
.startedBy(S3ObjectCreated, 'readDocument')
}
async readDocument (event: S3ObjectCreated) {
if (event.s3Key.indexOf('/documents') === 0 {
await this.bus.send(new ReadDocument(event.s3Key))
} else {
// Ignore this message and avoid persisting the workflow state
return this.discardWorkflow()
}
}
}
Last modified 1yr ago