# State

The workflow state keeps track of the state of the workflow as it progresses. The state is stored in the configured [persistence](/guide/persistence.md), and can be used to map incoming messages to [handlers](/guide/workflows/handling.md).&#x20;

### Defining the state

A workflow state is created by extending **WorkflowState.** The `$name` property should be unique among all of your workflows.&#x20;

```typescript
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:

```typescript
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.

```typescript
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:

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bus.node-ts.com/guide/workflows/state.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
