Skip to main content

Sequential Workflows

Sequential Workflows are the processing engines of Blue documents, defining how documents respond to events with a series of ordered steps. These workflows enable deterministic business logic that transforms static documents into dynamic, responsive entities.

The Workflow Concept

At its core, a Sequential Workflow is a contract that:

  1. Listens to a specific channel for events
  2. Processes those events through an ordered sequence of steps
  3. Updates the document or triggers additional events
  4. Produces deterministic results across all processors

Unlike traditional programming where execution can follow many paths, Sequential Workflows guarantee the same outcome for every processor given the same inputs—critical for maintaining Blue's trustless verification model.

A Practical Example: Online Lesson

Let's explore Sequential Workflows through a practical example—an online tutoring platform where teachers and students coordinate lessons.

First, let's define the confirmation event type that our workflow will process:

name: Online Lesson Confirmation
confirmLesson:
description: Determines if the lesson should be confirmed or not
type: Boolean
priceInUsd:
description: Price in USD
type: Double

Now, let's create our main document type:

name: Online Lesson
lessonDate:
description: Scheduled date and time for the lesson
type: DateTime
durationInMinutes:
description: Duration of the lesson in minutes
type: Positive Integer
approved:
description: Whether the teacher has approved this lesson
type: Boolean
default: false
priceInUsd:
description: Price of the lesson in USD
type: Double
teacherMessage:
description: Message from the teacher about the lesson
type: Text
contracts:
teacherChannel:
description: Channel for teacher communication
type: Timeline Channel

studentChannel:
description: Channel for student communication
type: Timeline Channel

confirmLessonWorkflow:
type: Sequential Workflow
channel: teacherChannel
event:
type: Online Lesson Confirmation
steps:
- name: ProcessConfirmation
type: JavaScript Code
code: |
// Extract confirmation data from the event
const confirmation = event;

// Prepare data for document update
return {
approved: confirmation.confirmLesson,
price: confirmation.confirmLesson ? confirmation.priceInUsd : null,
message: confirmation.confirmLesson ?
"Lesson confirmed at $" + confirmation.priceInUsd :
"Lesson declined by teacher"
};
- name: UpdateLessonStatus
type: Update Document
changeset:
- op: replace
path: /approved
val: ${steps.ProcessConfirmation.approved}
- op: replace
path: /priceInUsd
val: ${steps.ProcessConfirmation.price}
- op: replace
path: /teacherMessage
val: ${steps.ProcessConfirmation.message}

This document defines:

  • Basic properties for an online lesson (date, duration, approval status)
  • Channels for both teacher and student
  • A Sequential Workflow that processes confirmation events from the teacher

Creating a Specific Lesson

Using the Online Lesson type, we can create a specific lesson instance:

name: Alice-Bob Lesson
type: Online Lesson
lessonDate:
year: 2025
month: 5
day: 1
hour: 13
durationInMinutes: 90

Initially, this lesson is pending approval. The teacher (Alice) must send a confirmation event to approve or decline it:

# Approval message
type: Online Lesson Confirmation
confirmLesson: true
priceInUsd: 99.99

# Or, alternatively, rejection message
type: Online Lesson Confirmation
confirmLesson: false

When the workflow processes this event, it will:

  1. Extract confirmation details in the JavaScript step
  2. Update the document's approval status, price, and message in the Update Document step

After processing an approval, the document would look like this:

name: Alice-Bob Lesson
type: Online Lesson
lessonDate:
year: 2025
month: 5
day: 1
hour: 13
durationInMinutes: 90
approved: true
priceInUsd: 99.99
teacherMessage: "Lesson confirmed at $99.99"

The key benefit here is that both Alice and Bob can run this document using their own independent processors. As long as they have access to the same timeline events, they will always reach identical document states—ensuring consistent interpretation without requiring central coordination.

Workflow Components

Let's examine the key components of Sequential Workflows:

Channel Binding

Every workflow must specify which channel it listens to:

confirmLessonWorkflow:
type: Sequential Workflow
channel: teacherChannel

This binding determines which events will trigger the workflow. A single channel can trigger multiple workflows, and a document can contain many workflows listening to different channels.

Event Filtering (Optional)

Workflows can optionally filter for specific event types:

event:
type: Online Lesson Confirmation

When specified, only events matching this type will trigger the workflow. Without this filter, the workflow processes all events from the channel.

Steps

The heart of a workflow is its sequence of steps, executed in order:

steps:
- name: Step1
# Step details
- name: Step2
# Step details

Each step receives:

  • The triggering event
  • The current document state
  • Results from all previous steps

Common Step Types

Blue provides several standard step types that all processors must implement, but the architecture is extensible—allowing for custom step types as needed.

JavaScript Code Step

The JavaScript Code Step enables custom logic with full access to event data and document state:

- name: ProcessConfirmation
type: JavaScript Code
code: |
// Event data is available directly
const confirmation = event;

// Document access via document() function
const currentDuration = document('/durationInMinutes');

// Return data for use in subsequent steps
return {
approved: confirmation.confirmLesson,
price: confirmation.confirmLesson ? confirmation.priceInUsd : null
};

JavaScript Context

The JavaScript environment provides these capabilities:

Variable/FunctionDescription
eventThe triggering event object
document(path)Function to access document state at the specified path
stepsObject containing results from previous steps

The code must be deterministic—avoiding Date.now(), Math.random(), or other non-deterministic functions—to ensure all processors reach identical results.

Update Document Step

The Update Document Step modifies the document using standard JSON Patch operations:

- name: UpdateLessonStatus
type: Update Document
changeset:
- op: replace
path: /approved
val: ${steps.ProcessConfirmation.approved}
- op: replace
path: /priceInUsd
val: ${steps.ProcessConfirmation.price}

Available Operations

OperationDescription
replaceReplace an existing value
addAdd a new value (or create if path doesn't exist)
removeRemove a value
copyCopy from one location to another
moveMove from one location to another

Template Expressions

Within an Update Document step, you can use JavaScript template expressions with the ${...} syntax:

- op: replace
path: /total
val: ${document('/subtotal') * 1.1} # Add 10% tax

These expressions can reference:

  • Document values via document('/path')
  • Previous step results via steps.StepName.property
  • Event data via event.property

Custom and Specialized Steps

The Blue ecosystem supports extensible step types:

  • Standard Steps: Must be implemented by all processors (JavaScript Code, Update Document, Trigger Event)
  • Custom Steps: Can be created for specialized purposes
  • Platform-Specific Steps: Platforms like MyOS offer additional steps like "Call Agent" for integrating with their agent ecosystem

As with all other contracts, make sure that processors you and others you work with have support for the contract types and workflow step types defined in your documents - the more standard steps you use, the easier it will be to ensure compatibility across different environments.