📘
@node-test/bus
  • @node-ts/bus
  • Getting started
    • Installation
    • Handling messages
    • Shutting down cleanly
  • Reference
    • Bus
    • BusConfiguration
    • BusInstance
  • Getting help
  • Guide
    • Messages
      • Events
      • Commands
      • System messages
    • Message attributes
      • Correlation id
      • Attributes
      • Sticky attributes
    • Workflows
      • Creating a workflow
      • Starting
      • Handling
      • State
      • Completing
      • Example
    • Transports
      • RabbitMQ
      • Amazon SQS
      • Redis
      • Custom transports
    • Persistence
      • Postgres
      • MongoDB
      • Creating a persistence
    • Serializers
      • Class serializer
    • Loggers
      • Custom loggers
    • Middleware
    • Lifecycle hooks
    • Retry Strategies
    • Dependency injection
    • Long running processes
Powered by GitBook
On this page
  • Defining the state
  • Accessing the state
  • Updating the state
  • Discarding state

Was this helpful?

  1. Guide
  2. Workflows

State

PreviousHandlingNextCompleting

Last updated 3 years ago

Was this helpful?

The workflow state keeps track of the state of the workflow as it progresses. The state is stored in the configured , and can be used to map incoming messages to .

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'

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'
}

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'

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) {
    // ...
  }
}

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'

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' }
  }
}

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'

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()
    }
  }
}

persistence
handlers