Distributed System Decorators
Define TypeScript Saga workflows, compensation, transactional outbox and inbox processing, checkpoints, and resumable distributed operations with AxilJS.
Distributed System Decorators
Distributed decorators describe workflows and transactional messaging patterns that span multiple services or execution boundaries.
AxilJS expresses these requirements as semantic metadata rather than coupling application code to a specific workflow engine, message broker, or distributed transaction implementation.
The core distributed decorators are:
@tSaga@tStep@tCompensate@tOutbox@tInbox@tCheckpoint
@tSaga
Declares a class as a distributed Saga workflow.
A Saga models a sequence of operations that may execute across services. If a later step cannot complete, previously completed work can be compensated.
The Saga decorator identifies the workflow while its step and compensation metadata describe the individual execution units.
A Saga is particularly useful when a traditional database transaction cannot span the complete operation because the workflow crosses service or infrastructure boundaries.
@tStep
Declares an ordered step within a Saga or durable workflow.
The step metadata defines the workflow structure without embedding orchestration logic directly into the method.
Step Options
| Option | Type | Description |
|---|---|---|
order | number | Execution order of the step |
optional | boolean | Indicates whether the workflow can continue when the step is unsuccessful |
The source defines ordered steps using order and supports explicit optionality through the optional property.
@tCompensate
Declares a compensating action for a previously completed workflow step.
If a later workflow step fails, the workflow consumer can use the compensation metadata to determine which action should reverse or compensate the affected step.
Compensation is a central part of Saga-based distributed transactions because the original operation may no longer be reversible through a single database rollback.
@tOutbox
Declares transactional event publication using the Outbox pattern.
The Outbox pattern coordinates event publication with the database transaction so that database state and the corresponding event are persisted consistently.
The source describes @tOutbox as providing at-least-once event delivery.
A typical implementation can persist the event in an outbox store as part of the transaction and publish it asynchronously afterward.
@tInbox
Declares processed-message tracking for incoming events.
The Inbox pattern tracks processed message identifiers so duplicate deliveries can be detected.
The source describes @tInbox as providing at-most-once event consumption by tracking processed message IDs.
This is useful when message brokers provide redelivery or at-least-once delivery semantics.
@tCheckpoint
Marks a resumable point in a long-running workflow.
If a workflow fails after reaching a checkpoint, a workflow consumer can resume from the checkpoint instead of restarting the entire workflow.
This is particularly useful for long-running processing pipelines where earlier steps are expensive or have already produced durable results.
Full Saga Example
The distributed decorators can be composed with other AxilJS semantics.
This workflow describes:
- Extract the document.
- Classify the document.
- Persist the indexing result.
- Create a checkpoint after classification.
- Remove the index if the indexing step must be compensated.
- Clear classification if that step must be compensated.
The source uses this same pattern to demonstrate Saga steps, checkpoints, timeouts, and compensation working together.
Transactional Messaging
Distributed applications commonly need to coordinate database state and message publication.
Consider an order creation operation:
The semantic declarations communicate two distinct requirements:
- The database mutation belongs to a transaction.
- The resulting event must participate in transactional outbox processing.
This allows the implementation to handle persistence and event delivery without forcing the business method to manage broker-specific mechanics.
Outbox and Inbox Together
For a distributed workflow, Outbox and Inbox semantics can be used on opposite sides of a message boundary.
Producer:
Consumer:
The producer expresses reliable event publication while the consumer expresses duplicate-message handling.
Together, these semantics provide a declarative foundation for reliable asynchronous communication.
Workflow Resumption
Long-running workflows can combine steps and checkpoints:
If the workflow fails during publication, a workflow consumer can use the checkpoint metadata to avoid repeating completed processing.
Distributed Decorator Reference
| Decorator | Purpose |
|---|---|
@tSaga | Declares a distributed Saga workflow |
@tStep | Defines an ordered workflow step |
@tCompensate | Defines compensation for a workflow step |
@tOutbox | Declares transactional event publication |
@tInbox | Tracks processed message identifiers |
@tCheckpoint | Defines a resumable workflow point |
These decorators form the distributed transaction category in AxilJS.
Design Principle
Distributed decorators should describe workflow intent, not implement the workflow engine.
For example:
The decorator does not need to know whether the workflow is ultimately executed by a database-backed orchestrator, a state machine, or another workflow runtime.
The source explicitly describes the workflow engine as a separate consumer and gives Temporal, a custom state machine, and a database-driven orchestrator as possible implementations.
This separation keeps business code focused on domain operations while allowing infrastructure implementations to evolve independently.