Saga
Sagas: reactions that span several aggregates and outlive one command, run as
durable workflows from effect/workflow.
A saga has two halves. Its trigger is a view model that follows the log from a
checkpoint and starts a workflow for each event it cares about. The workflow is
the process itself: each command it runs is an Activity, so when the engine
replays the workflow after a restart it skips the commands that already
finished, and withCompensation undoes earlier steps when a later one fails.
Triggers see an event at least once, and the workflow’s idempotency key turns
a second start into a join of the first execution. That only holds while the
engine remembers the execution, so pair WorkflowEngine.layerMemory with
in-memory checkpoints, as for view models, and a durable engine such as
ClusterWorkflowEngine from effect/cluster with durable ones.
An activity that is cut off before its result is saved runs again, so the
commands a saga runs should be idempotent: give each a commandId made from the
execution id and the step, so that running it again returns the first result,
or record the id of the transfer it belongs to.
Classes
Section titled “Classes”Defined in: src/Saga.ts:144
The triggers that layer runs, managed like view models: their status,
the events they parked and retrying those. It is ViewModel.ViewModels under
another name, so it doesn’t stand in for the view models’ own.
Extends
Section titled “Extends”Shape<"effect-cqrs/Sagas", {status:Effect<readonlyStatus[]>;caughtUp(position?):Effect<void,EventStoreError>;parked(viewModel?):Effect<readonlyobject[],EventStoreError|UnknownViewModel>;replay(options):Effect<ReplayResult,UnknownViewModel|ViewModelError>;retryParked(options):Effect<RetryParkedResult,EventStoreError|UnknownViewModel|ViewModelError>; },this>
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new Sagas(
_):Sagas
Defined in: node_modules/.pnpm/effect@4.0.6/node_modules/effect/dist/Context.d.ts:121
Parameters
Section titled “Parameters”never
Returns
Section titled “Returns”Inherited from
Section titled “Inherited from”Context.Service<Sagas, ViewModel.ViewModels["Service"]>()("effect-cqrs/Sagas").constructor
Type Aliases
Section titled “Type Aliases”SagaWorkflow
Section titled “SagaWorkflow”SagaWorkflow<
Tag,Fields,Success,Error> =Workflow.Workflow<Tag,Schema.Struct<Fields&object>,Success,Error>
Defined in: src/Saga.ts:46
A workflow whose payload carries the causation of the event that started it.
Type Parameters
Section titled “Type Parameters”Tag extends string = string
Fields
Section titled “Fields”Fields extends Schema.Struct.Fields = Schema.Struct.Fields
Success
Section titled “Success”Success extends Schema.Top = Schema.Top
Error extends Schema.Top = Schema.Top
Variables
Section titled “Variables”CausationSchema
Section titled “CausationSchema”
constCausationSchema:Struct<{causationId:String;correlationId:String; }>
Defined in: src/Saga.ts:40
The causation a workflow carries in its payload. A workflow body runs in the engine’s fibers, not in the trigger’s, so this is how commands it runs learn which event caused them.
CommandOutcome
Section titled “CommandOutcome”
constCommandOutcome:Struct<{aggregateId:String;position:Int;version:Int; }>
Defined in: src/Saga.ts:160
What a saga keeps of a command it ran: enough to wait for view models to see it.
Functions
Section titled “Functions”command()
Section titled “command()”command<
Err,E,R>(name,options):Activity<Struct<{aggregateId:String;position:Int;version:Int; }>,Err,R>
Defined in: src/Saga.ts:180
Runs a command as an activity of a saga’s workflow, so a replay of the workflow returns the saved outcome instead of running it again.
Failures matching error, such as a domain error the saga reacts to, are
saved like a success. A lost race or a store error is retried a few times.
Anything else ends the workflow as a defect, which runs its compensations.
Type Parameters
Section titled “Type Parameters”Err extends Top = Never
E = never
R = never
Parameters
Section titled “Parameters”string
options
Section titled “options”error?
Section titled “error?”Err
execute
Section titled “execute”Effect<CommandResult<unknown>, E, R>
Returns
Section titled “Returns”Activity<Struct<{ aggregateId: String; position: Int; version: Int; }>, Err, R>
layer()
Section titled “layer()”layer<
Triggers>(sagas):Layer<Sagas,EventStoreError,EventStore|Checkpoints|Context<Triggers[number]>>
Defined in: src/Saga.ts:152
Runs triggers in the background for as long as the layer lives, apart from the view models, and provides Sagas to manage them. Workflows usually run commands, so they sit on top of the command side, which view models are often provided to.
Type Parameters
Section titled “Type Parameters”Triggers
Section titled “Triggers”Triggers extends readonly Any[]
Parameters
Section titled “Parameters”Triggers
Returns
Section titled “Returns”Layer<Sagas, EventStoreError, EventStore | Checkpoints | Context<Triggers[number]>>
make()
Section titled “make()”make<
Name,Aggregates,H>(options):ViewModel<Name,HandlerError<H>,HandlerContext<H>>
Defined in: src/Saga.ts:127
The trigger of a saga: a view model whose handlers start workflows with
start, so it keeps a checkpoint and retries like view models do. Run it
with layer, or with ViewModel.layer next to the other view models,
where replaying it starts every saga again and joins the executions the engine
still remembers.
Type Parameters
Section titled “Type Parameters”Name extends string
Aggregates
Section titled “Aggregates”Aggregates extends readonly Any[]
H extends Handlers<Event<Aggregates[number]>>
Parameters
Section titled “Parameters”options
Section titled “options”aggregates
Section titled “aggregates”Aggregates
handlers
Section titled “handlers”H
Name
onFailure?
Section titled “onFailure?”What to do with an event that keeps failing, see ViewModel.park.
Returns
Section titled “Returns”ViewModel<Name, HandlerError<H>, HandlerContext<H>>
start()
Section titled “start()”start<
Tag,Fields,Success,Error>(self,payload):Effect<string,never,WorkflowEngine>
Defined in: src/Saga.ts:104
Starts a saga’s workflow without waiting for it, and returns its execution id. Inside a trigger the event being handled becomes the saga’s cause; elsewhere the current causation does, or a new correlation when there is none.
Type Parameters
Section titled “Type Parameters”Tag extends string
Fields
Section titled “Fields”Fields extends Fields
Success
Section titled “Success”Success extends Top
Error extends Top
Parameters
Section titled “Parameters”SagaWorkflow<Tag, Fields, Success, Error>
payload
Section titled “payload”MakeInView<Fields>
Returns
Section titled “Returns”Effect<string, never, WorkflowEngine>
toLayer()
Section titled “toLayer()”toLayer<
Tag,Fields,Success,Error,R>(self,execute):Layer<never,never,WorkflowEngine|DecodingServices<Fields&object> |EncodingServices<Fields&object> |Success["DecodingServices"] |Success["EncodingServices"] |Error["DecodingServices"] |Error["EncodingServices"] |Exclude<R,Scope|WorkflowEngine|WorkflowInstance|Execution<Tag>>>
Defined in: src/Saga.ts:79
Registers the body of a saga’s workflow with the engine. Commands the body runs record the event that started the saga as their cause.
Type Parameters
Section titled “Type Parameters”Tag extends string
Fields
Section titled “Fields”Fields extends Fields
Success
Section titled “Success”Success extends Top
Error extends Top
R
Parameters
Section titled “Parameters”SagaWorkflow<Tag, Fields, Success, Error>
execute
Section titled “execute”(payload, executionId) => Effect<Success["Type"], Error["Type"], R>
Returns
Section titled “Returns”Layer<never, never, WorkflowEngine | DecodingServices<Fields & object> | EncodingServices<Fields & object> | Success["DecodingServices"] | Success["EncodingServices"] | Error["DecodingServices"] | Error["EncodingServices"] | Exclude<R, Scope | WorkflowEngine | WorkflowInstance | Execution<Tag>>>
workflow()
Section titled “workflow()”workflow<
Tag,Fields,Success,Error>(tag,options):SagaWorkflow<Tag,Fields,Success,Error>
Defined in: src/Saga.ts:57
Defines the workflow of a saga. It is Workflow.make with a causation field
added to the payload, which start fills in and toLayer applies.
Type Parameters
Section titled “Type Parameters”Tag extends string
Fields
Section titled “Fields”Fields extends Fields
Success
Section titled “Success”Success extends Top = Void
Error extends Top = Never
Parameters
Section titled “Parameters”Tag
options
Section titled “options”error?
Section titled “error?”Error
idempotencyKey
Section titled “idempotencyKey”(payload) => string
Identifies one run of the saga, such as a transfer id. Starting it again joins that run.
payload
Section titled “payload”Fields
success?
Section titled “success?”Success
suspendedRetrySchedule?
Section titled “suspendedRetrySchedule?”Schedule<any, unknown, never, never>
Returns
Section titled “Returns”SagaWorkflow<Tag, Fields, Success, Error>