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.
Defining the state
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'exportclassFulfilmentWorkflowStateextendsWorkflowState {static NAME ='FulfilmentWorkflowState' $name =FulfilmentWorkflowState.NAME// Set of user-defined state properties itemId:string customerId:string status:'posting-item'|'sending-receipt'|'complete'}
Accessing the state
The state is available as the second parameter to all handlers of a workflow. For example:
import { Workflow } from'@node-ts/bus-core'exportclassFulfilmentWorkflowextendsWorkflow<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 handlerasyncemailReceipt (_:ItemShipped, state:FulfilmentWorkflowState) {// ... }}
Updating the state
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'exportclassFulfilmentWorkflowextendsWorkflow<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 handlerasyncemailReceipt (_:ItemShipped, state:FulfilmentWorkflowState) {return { status:'sending-receipt' } }}
Discarding state
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'exportclassProcessDocumentWorkflowextendsWorkflow<ProcessDocumentWorkflowState> {constructor (bus:BusInstance) {}configureWorkflow ( mapper:WorkflowMapper<ProcessDocumentWorkflowState,ProcessDocumentWorkflow> ):void { mapper.withState(ProcessDocumentWorkflowState).startedBy(S3ObjectCreated,'readDocument') }asyncreadDocument (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() } }}