FcqrsModule
PackageFCQRS
Summary
| Name | Signature | Synopsis |
|---|---|---|
| connect | connect dbType connectionString | Build a SQLite/etc. |
| actor | actor config loggerFactory connection clusterName | Create the actor system from plain values (cluster name as a string). |
| newCid | newCid () | A fresh correlation id (UUID v7). |
| cid | cid s | A correlation id from a string you already have (a request id, a trace id). |
| aggregateId | aggregateId s | An aggregate id from a string (e.g. |
| aggregate | aggregate api def | Register an aggregate and return its typed handle. |
| handler | handler api def | Register an aggregate immediately and return a reusable application handler. |
| sendIfVersion | sendIfVersion api handle expectedVersion cid id command filter | Send only if the aggregate's persisted version equals expectedVersion (initially zero). |
| aggregateWithEffects | aggregateWithEffects api def runner | Register an aggregate whose `decide` uses `dispatch` (the RunAsync effect), supplying the runner that turns an effect DESCRIPTION into a command sent back to the aggregate. |
| saga | saga api def | Register a saga and return its handle. |
| wireSagaStarters | wireSagaStarters api sagas | Wire every registered saga into one saga-starter (or the empty starter if none). |
| journalTypes | journalTypes mappings | Register stable journal names for payload types (see JournalTypes): Fcqrs.journalTypes [ journalType<Document.Event> "doc.event"; ... |
| withEventUpcaster | withEventUpcaster api convert | Register a deterministic, one-to-one historical event conversion for this actor system. |
| projection | projection api p | Register the read-model projection and return the subscription stream. |
| transactionalProjection | transactionalProjection api options handler | Starts a transactional projection with journal-wide CatchUpAsync support. |
| sendAwaiting | sendAwaiting subscription handle cid id command filter | Read-your-writes in one call: subscribe on the CID BEFORE sending, send, then await the projection ONLY if the delivered ack was journaled. |
Build a SQLite/etc. Connection from a raw connection string (ShortString hidden).
Parameters
| Name | Type | Description |
|---|---|---|
| dbType | DBType | |
| connectionString | string |
Returns
Connection
Create the actor system from plain values (cluster name as a string).
Parameters
| Name | Type | Description |
|---|---|---|
| config | IConfiguration | |
| loggerFactory | ILoggerFactory | |
| connection | Connection option | |
| clusterName | string |
Returns
IActor
A correlation id from a string you already have (a request id, a trace id).
Rejects '~': the separator FCQRS builds saga entity names and pub-sub
topics from, so a CID containing one is parsed back wrong and leaves the
saga permanently deaf. `newCid` needs no such check — a UUID has none.
Parameters
| Name | Type | Description |
|---|---|---|
| s | string |
Returns
CID
An aggregate id from a string (e.g. a document/user key).
Any non-blank id works: the shard names entity actors
Uri.EscapeDataString(entityId), so characters Akka actor names would
reject directly (spaces, %) are escaped before they reach an actor path.
Parameters
| Name | Type | Description |
|---|---|---|
| s | string |
Returns
AggregateId
Register an aggregate and return its typed handle. Calling this IS the
registration (it initializes the sharding region).
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| def | Aggregate<'State, 'Command, 'Event> |
Returns
AggregateHandle<'Command, 'Event>
Register an aggregate immediately and return a reusable application handler.
The returned function takes filter, cid, aggregate id, and command, in that order,
and sends when its Async is executed. It returns EventDetails from the first
matching reply; it does not wait for a projection or wire saga starters.
Use aggregate instead when the caller needs the envelope or entity-ref factory.
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| def | Aggregate<'State, 'Command, 'Event> |
Returns
Handler<'Command, 'Event>
Send only if the aggregate's persisted version equals expectedVersion (initially zero).
A mismatch raises AggregateVersionConflictException before the domain handler or filter runs.
The check and handler run in the same actor turn. Deferred replies do not advance the
version; a persisted batch advances it once per event. Stashed commands and RunAsync
result commands recheck the original expected version. This is not command deduplication
or a projection wait. Cancellation or timeout after dispatch does not undo a write.
A caller-built PublishEvent reply must retain the incoming command's Id and CorrelationId.
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| handle | AggregateHandle<'Command, 'Event> | |
| expectedVersion | int64 | |
| cid | CID | |
| id | AggregateId | |
| command | 'Command | |
| filter | 'Event -> bool |
Returns
Async<Event<'Event>>
Register an aggregate whose `decide` uses `dispatch` (the RunAsync
effect), supplying the runner that turns an effect DESCRIPTION into a
command sent back to the aggregate. `decide` stays pure; the oracle or
side effect lives only here. The runner MUST be total (wrap it with
`total` so an oracle error becomes a command, never an escaping
exception). See `EventAction.RunAsync` for the ephemeral contract.
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| def | Aggregate<'State, 'Command, 'Event> | |
| runner | 'description -> Async<'Command> |
Returns
AggregateHandle<'Command, 'Event>
Register a saga and return its handle. The originator-event type is inferred
from `def.StartOn`, so there are no type arguments to supply:
`Fcqrs.saga api def`.
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| def | Saga<'Data, 'State, 'OriginatorEvent> |
Returns
SagaHandle
Wire every registered saga into one saga-starter (or the empty starter if
none). Call after the aggregates + sagas are registered.
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| sagas | SagaHandle list |
Returns
unit
Register stable journal names for payload types (see JournalTypes):
Fcqrs.journalTypes [ journalType<Document.Event> "doc.event"; ... ]
Call before the actor system writes anything.
Parameters
| Name | Type | Description |
|---|---|---|
| mappings | (Type * string) list |
Returns
unit
Register a deterministic, one-to-one historical event conversion for this actor system.
Call after creating the actor API and before registering any aggregate, saga, or projection.
Chains follow the envelope's declared payload type; duplicate sources and cycles are rejected.
FCQRS converts journal events during recovery and projection reads, preserving every envelope
field except EventDetails. Stored events, live messages, and application-owned snapshot state
remain unchanged. Historical payloads must still deserialize before conversion can run.
Converters may run concurrently across consumers and must be thread-safe.
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| convert | 'Old -> 'New |
Returns
IActor
Register the read-model projection and return the subscription stream.
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| p | Projection |
Returns
ISubscribe
Starts a transactional projection with journal-wide CatchUpAsync support.
Write the read model through the supplied connection and transaction; FCQRS
commits those updates and contiguous per-persistence-ID progress together.
Retain unprocessed journal history. Events have per-persistence-ID ordering,
with no ordering between different persistence IDs. See TransactionalProjectionOptions.
Parameters
| Name | Type | Description |
|---|---|---|
| api | IActor | |
| options | TransactionalProjectionOptions | |
| handler | DbConnection -> DbTransaction -> EventEnvelope -> Task |
Returns
IProjection
Read-your-writes in one call: subscribe on the CID BEFORE sending, send,
then await the projection ONLY if the delivered ack was journaled. A
deferred (rejection-style) ack never reaches the journal, so a naive
await would hang until timeout. The subscribe-before-send ordering is
what makes the wait race-free; owning it here means callers cannot get
it backwards. Awaits exactly ONE projected event: a batch persist
(PersistAllEvents) caller should Subscribe with an explicit take
instead. Envelopes without the delivery stamp (pre-stamp FCQRS) are
treated as journaled.
The projection wait is bounded by `akka.fcqrs.command-timeout` (default
30s, bare number = seconds): a projection that suppresses or filters
out the matching notification raises TimeoutException instead of
hanging the caller forever.
Parameters
| Name | Type | Description |
|---|---|---|
| subscription | ISubscribe<IMessageWithCID> | |
| handle | AggregateHandle<'Command, 'Event> | |
| cid | CID | |
| id | AggregateId | |
| command | 'Command | |
| filter | 'Event -> bool |
Returns
Async<Event<'Event>>