EventStore
The append-only log every aggregate and view model is built on.
Each event belongs to a stream, identified by aggregate name and id, and has
two coordinates: a version that orders it inside its stream and a position
that orders it across the whole store. Writers use the version for optimistic
concurrency, readers use the position as a durable cursor.
Classes
Section titled “Classes”ConcurrencyConflict
Section titled “ConcurrencyConflict”Defined in: src/EventStore.ts:43
Extends
Section titled “Extends”object&YieldableError<this>
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new ConcurrencyConflict(…
args):ConcurrencyConflict
Defined in: node_modules/.pnpm/effect@4.0.6/node_modules/effect/dist/Schema.d.ts:10979
Parameters
Section titled “Parameters”…[props: object, options?: MakeOptions]
Returns
Section titled “Returns”Inherited from
Section titled “Inherited from”Schema.TaggedError<ConcurrencyConflict>()("ConcurrencyConflict", { aggregateName: Schema.String, aggregateId: Schema.String, expectedVersion: Schema.Int }).constructor
Properties
Section titled “Properties”aggregateId
Section titled “aggregateId”
readonlyaggregateId:string=Schema.String
Defined in: src/EventStore.ts:45
Inherited from
Section titled “Inherited from”Schema.TaggedError<ConcurrencyConflict>()("ConcurrencyConflict", { aggregateName: Schema.String, aggregateId: Schema.String, expectedVersion: Schema.Int }).aggregateId
aggregateName
Section titled “aggregateName”
readonlyaggregateName:string=Schema.String
Defined in: src/EventStore.ts:44
Inherited from
Section titled “Inherited from”Schema.TaggedError<ConcurrencyConflict>()("ConcurrencyConflict", { aggregateName: Schema.String, aggregateId: Schema.String, expectedVersion: Schema.Int }).aggregateName
expectedVersion
Section titled “expectedVersion”
readonlyexpectedVersion:number=Schema.Int
Defined in: src/EventStore.ts:46
Inherited from
Section titled “Inherited from”Schema.TaggedError<ConcurrencyConflict>()("ConcurrencyConflict", { aggregateName: Schema.String, aggregateId: Schema.String, expectedVersion: Schema.Int }).expectedVersion
EventStore
Section titled “EventStore”Defined in: src/EventStore.ts:139
Extends
Section titled “Extends”Shape<"effect-cqrs/EventStore", {afterCommit?: <R>(effect) =>Effect<void,never,R>;changes:Stream<number>;head:Effect<number,EventStoreError>;append(input):Effect<readonlyobject[],EventStoreError|ConcurrencyConflict>;read(filter?):Stream<{aggregateId:string;aggregateName:string;causationId:string|null;correlationId:string|null;metadata: {[key:string]:Json; };payload:Json;position:number;schemaVersion:number;timestamp:Utc;type:string;version:number; },EventStoreError>;subscribe(filter?):Stream<{aggregateId:string;aggregateName:string;causationId:string|null;correlationId:string|null;metadata: {[key:string]:Json; };payload:Json;position:number;schemaVersion:number;timestamp:Utc;type:string;version:number; },EventStoreError>; },this>
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new EventStore(
_):EventStore
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<EventStore, { /** Appends atomically, failing if the stream moved past `expectedVersion`. */ append(input: AppendInput): Effect.Effect<ReadonlyArray<StoredEvent>, ConcurrencyConflict | EventStoreError> /** Reads the events stored so far, ordered by position, then completes. */ read(filter?: EventFilter): Stream.Stream<StoredEvent, EventStoreError> /** Reads the events stored so far, then keeps following new ones. Never completes. */ subscribe(filter?: EventFilter): Stream.Stream<StoredEvent, EventStoreError> /** The position of the latest event, `0` when the store is empty. */ readonly head: Effect.Effect<number, EventStoreError> /** * Emits the current latest position, then each newer one. Consumers can treat an * element as “there may be something new”. Appends from this process are always * observed, appends from other processes when the backend announces them or the * store polls for them: see `MakeOptions`. */ readonly changes: Stream.Stream<number> /** * Runs an effect once what was just appended can be read by everyone: at once, * or when the caller’s transaction commits, and never if it rolls back. Services * that keep what they read or wrote in memory go through it, so they don’t keep * what a rollback undid. Missing on stores without transactions. */ readonly afterCommit?: (<R>(effect: Effect.Effect<void, never, R>) => Effect.Effect<void, never, R>) | undefined }>()(“effect-cqrs/EventStore”).constructor
EventStoreError
Section titled “EventStoreError”Defined in: src/EventStore.ts:38
Extends
Section titled “Extends”object&YieldableError<this>
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new EventStoreError(…
args):EventStoreError
Defined in: node_modules/.pnpm/effect@4.0.6/node_modules/effect/dist/Schema.d.ts:10979
Parameters
Section titled “Parameters”…[props: object, options?: MakeOptions]
Returns
Section titled “Returns”Inherited from
Section titled “Inherited from”Schema.TaggedError<EventStoreError>()("EventStoreError", { operation: Schema.String, cause: Schema.Defect() }).constructor
Properties
Section titled “Properties”cause:
unknown
Defined in: src/EventStore.ts:40
Inherited from
Section titled “Inherited from”Schema.TaggedError<EventStoreError>()("EventStoreError", { operation: Schema.String, cause: Schema.Defect() }).cause
operation
Section titled “operation”
readonlyoperation:string=Schema.String
Defined in: src/EventStore.ts:39
Inherited from
Section titled “Inherited from”Schema.TaggedError<EventStoreError>()("EventStoreError", { operation: Schema.String, cause: Schema.Defect() }).operation
Interfaces
Section titled “Interfaces”AppendInput
Section titled “AppendInput”Defined in: src/EventStore.ts:75
Properties
Section titled “Properties”aggregateId
Section titled “aggregateId”
readonlyaggregateId:string
Defined in: src/EventStore.ts:77
aggregateName
Section titled “aggregateName”
readonlyaggregateName:string
Defined in: src/EventStore.ts:76
causationId?
Section titled “causationId?”
readonlyoptionalcausationId?:string
Defined in: src/EventStore.ts:82
correlationId?
Section titled “correlationId?”
readonlyoptionalcorrelationId?:string
Defined in: src/EventStore.ts:81
events
Section titled “events”
readonlyevents: readonlyNewEvent[]
Defined in: src/EventStore.ts:80
expectedVersion
Section titled “expectedVersion”
readonlyexpectedVersion:number
Defined in: src/EventStore.ts:79
The stream version the writer based its decision on, 0 for a new stream.
metadata?
Section titled “metadata?”
readonlyoptionalmetadata?:JsonObject
Defined in: src/EventStore.ts:84
Recorded on every event of the append. Defaults to {}.
Backend
Section titled “Backend”Defined in: src/EventStore.ts:165
What a storage adapter implements. make builds the rest on top.
Properties
Section titled “Properties”afterCommit?
Section titled “afterCommit?”
readonlyoptionalafterCommit?: <R>(effect) =>Effect<void,never,R>
Defined in: src/EventStore.ts:185
Runs an effect once an append made now can be read by everyone: at once, or when
the caller’s transaction commits, and never if it rolls back. SqlClient.afterCommit
is one. Without it appends are announced as soon as they return, which makes
subscribers skip those of a transaction that is still open.
Type Parameters
Section titled “Type Parameters”R
Parameters
Section titled “Parameters”effect
Section titled “effect”Effect<void, never, R>
Returns
Section titled “Returns”Effect<void, never, R>
append
Section titled “append”
readonlyappend: (input) =>Effect<readonlyobject[],EventStoreError|ConcurrencyConflict>
Defined in: src/EventStore.ts:166
Appends atomically, failing if the stream moved past expectedVersion.
Parameters
Section titled “Parameters”Returns
Section titled “Returns”Effect<readonly object[], EventStoreError | ConcurrencyConflict>
changes?
Section titled “changes?”
readonlyoptionalchanges?:Stream<number,EventStoreError,never>
Defined in: src/EventStore.ts:178
Head positions written by other processes, as the database announces them. It should start with the head once it listens, so nothing between two runs is missed. When it fails or ends, the store logs it and runs it again a second later.
readonlyhead:Effect<number,EventStoreError>
Defined in: src/EventStore.ts:172
readBatch
Section titled “readBatch”
readonlyreadBatch: (filter,afterPosition,limit) =>Effect<readonlyobject[],EventStoreError>
Defined in: src/EventStore.ts:167
Parameters
Section titled “Parameters”filter
Section titled “filter”afterPosition
Section titled “afterPosition”number
number
Returns
Section titled “Returns”Effect<readonly object[], EventStoreError>
EventFilter
Section titled “EventFilter”Defined in: src/EventStore.ts:121
Selects events by stream, type and time. Omitted fields match everything.
startTime is inclusive and finishTime is exclusive, so adding one
millisecond to a history timestamp selects up to and including that event.
Properties
Section titled “Properties”afterPosition?
Section titled “afterPosition?”
readonlyoptionalafterPosition?:number
Defined in: src/EventStore.ts:127
afterVersion?
Section titled “afterVersion?”
readonlyoptionalafterVersion?:number
Defined in: src/EventStore.ts:132
For a filter on one stream: where to continue in it. Versions follow the stream’s own index, so resuming there costs the same however far the log has moved on.
aggregateIds?
Section titled “aggregateIds?”
readonlyoptionalaggregateIds?: readonlystring[]
Defined in: src/EventStore.ts:123
aggregateNames?
Section titled “aggregateNames?”
readonlyoptionalaggregateNames?: readonlystring[]
Defined in: src/EventStore.ts:122
eventTypes?
Section titled “eventTypes?”
readonlyoptionaleventTypes?: readonlystring[]
Defined in: src/EventStore.ts:124
finishTime?
Section titled “finishTime?”
readonlyoptionalfinishTime?:Utc
Defined in: src/EventStore.ts:126
startTime?
Section titled “startTime?”
readonlyoptionalstartTime?:Utc
Defined in: src/EventStore.ts:125
MakeOptions
Section titled “MakeOptions”Defined in: src/EventStore.ts:188
Properties
Section titled “Properties”batchSize?
Section titled “batchSize?”
readonlyoptionalbatchSize?:number
Defined in: src/EventStore.ts:190
Events per read. Defaults to 500.
pollInterval?
Section titled “pollInterval?”
readonlyoptionalpollInterval?:Input
Defined in: src/EventStore.ts:195
Reads the head this often, to notice appends from other processes when the backend doesn’t announce them, or as a safety net when it does. Off by default.
Migration
Section titled “Migration”Defined in: src/EventStore.ts:32
A schema change for a SQL table, with the table names filled in. Each module that
keeps a table exports its migrations in the order to apply them, for teams that
run them with their own tooling and turn off migrate.
Properties
Section titled “Properties”
readonlyid:number
Defined in: src/EventStore.ts:33
readonlyname:string
Defined in: src/EventStore.ts:34
statements
Section titled “statements”
readonlystatements: readonlystring[]
Defined in: src/EventStore.ts:35
NewEvent
Section titled “NewEvent”Defined in: src/EventStore.ts:68
Properties
Section titled “Properties”payload
Section titled “payload”
readonlypayload:Json
Defined in: src/EventStore.ts:70
schemaVersion?
Section titled “schemaVersion?”
readonlyoptionalschemaVersion?:number
Defined in: src/EventStore.ts:72
Defaults to 1.
readonlytype:string
Defined in: src/EventStore.ts:69
Type Aliases
Section titled “Type Aliases”StoredEvent
Section titled “StoredEvent”StoredEvent = typeof
StoredEvent.Type
Defined in: src/EventStore.ts:49
Variables
Section titled “Variables”groupCommit
Section titled “groupCommit”
constgroupCommit: (…args) =>Effect<(input) =>Effect<readonlyobject[],EventStoreError|ConcurrencyConflict>,never,Scope>
Defined in: src/EventStore.ts:331
Group commit for a backend. An append that finds nothing being written goes
straight through appendGroup, in its own fiber. Appends that arrive meanwhile
wait, then go together into the next call, which writes them in one transaction
and returns an exit for each, in order: however many wait, they pay for one
commit.
A group holds at most one append per stream, so they can’t conflict with each
other, and at most maxEvents events unless a single append has more. An append
left out waits for the next group, where it comes first, so appends to a stream
are written in the order they came. Groups of waiting appends are written by a
fiber of the Scope. An append interrupted while it waits is not written, while
one interrupted once its group is being written may be: a caller that times out
should retry with a commandId, which finds the first result if there is one.
The others in its group are written and answered as if nothing happened.
Parameters
Section titled “Parameters”…[appendGroup: (inputs) => Effect<readonly AppendExit[]>, options?: object]
Returns
Section titled “Returns”Effect<(input) => Effect<readonly object[], EventStoreError | ConcurrencyConflict>, never, Scope>
layerMemory
Section titled “layerMemory”
constlayerMemory:Layer.Layer<EventStore,EventStoreError>
Defined in: src/EventStore.ts:540
Keeps events in process memory. They do not survive a restart.
constmake: (…args) =>Effect<{afterCommit?: <R>(effect) =>Effect<void,never,R>;changes:Stream<number>;head:Effect<number,EventStoreError>;append(input):Effect<readonlyobject[],EventStoreError|ConcurrencyConflict>;read(filter?):Stream<{aggregateId:string;aggregateName:string;causationId:string|null;correlationId:string|null;metadata: {[key:string]:Json; };payload:Json;position:number;schemaVersion:number;timestamp:Utc;type:string;version:number; },EventStoreError>;subscribe(filter?):Stream<{aggregateId:string;aggregateName:string;causationId:string|null;correlationId:string|null;metadata: {[key:string]:Json; };payload:Json;position:number;schemaVersion:number;timestamp:Utc;type:string;version:number; },EventStoreError>; },EventStoreError,Scope>
Defined in: src/EventStore.ts:208
Builds a store on a backend. Watching for appends from other processes takes
fibers that live as long as the Scope, which Layer.effect provides.
Parameters
Section titled “Parameters”…[backend: Backend, options?: MakeOptions]
Returns
Section titled “Returns”Effect<{ afterCommit?: <R>(effect) => Effect<void, never, R>; changes: Stream<number>; head: Effect<number, EventStoreError>; append(input): Effect<readonly object[], EventStoreError | ConcurrencyConflict>; read(filter?): Stream<{ aggregateId: string; aggregateName: string; causationId: string | null; correlationId: string | null; metadata: {[key: string]: Json; }; payload: Json; position: number; schemaVersion: number; timestamp: Utc; type: string; version: number; }, EventStoreError>; subscribe(filter?): Stream<{ aggregateId: string; aggregateName: string; causationId: string | null; correlationId: string | null; metadata: {[key: string]: Json; }; payload: Json; position: number; schemaVersion: number; timestamp: Utc; type: string; version: number; }, EventStoreError>; }, EventStoreError, Scope>
makeMemory
Section titled “makeMemory”
constmakeMemory:Effect.Effect<EventStore["Service"],EventStoreError>
Defined in: src/EventStore.ts:487
StoredEvent
Section titled “StoredEvent”
constStoredEvent:Struct<{aggregateId:String;aggregateName:String;causationId:NullOr<String>;correlationId:NullOr<String>;metadata:$Record<String,Codec<Json,Json,never,never>>;payload:Codec<Json,Json,never,never>;position:Int;schemaVersion:Int;timestamp:DateTimeUtcFromMillis;type:String;version:Int; }>
Defined in: src/EventStore.ts:49
Functions
Section titled “Functions”eventId()
Section titled “eventId()”eventId(
event):string
Defined in: src/EventStore.ts:92
Identifies an event wherever it is stored, as the causationId of what it causes:
account/alice@4. Name and id are URI-encoded, so a / or @ inside one can’t
make two events look alike.
Parameters
Section titled “Parameters”Pick<StoredEvent, "aggregateName" | "aggregateId" | "version">
Returns
Section titled “Returns”string
isOneStream()
Section titled “isOneStream()”isOneStream(
__namedParameters):boolean
Defined in: src/EventStore.ts:136
A filter on exactly one stream, which a store can read through that stream’s index.
Parameters
Section titled “Parameters”__namedParameters
Section titled “__namedParameters”Returns
Section titled “Returns”boolean
toStored()
Section titled “toStored()”toStored(
input,event,index,position,timestamp):object
Defined in: src/EventStore.ts:96
The columns every adapter stores for a new event, with the defaults filled in.
Parameters
Section titled “Parameters”number
position
Section titled “position”number
timestamp
Section titled “timestamp”Utc
Returns
Section titled “Returns”aggregateId
Section titled “aggregateId”
readonlyaggregateId:string=Schema.String
aggregateName
Section titled “aggregateName”
readonlyaggregateName:string=Schema.String
causationId
Section titled “causationId”
readonlycausationId:string|null
What directly caused the command that recorded the event: a request, a command or another event.
correlationId
Section titled “correlationId”
readonlycorrelationId:string|null
Shared by everything that follows from one original request.
metadata
Section titled “metadata”
readonlymetadata:object=Schema.JsonObject
What the command carried beside its payload, see Metadata. Events from before metadata existed have {}.
Index Signature
Section titled “Index Signature”[key: string]: Json
payload
Section titled “payload”
readonlypayload:Json=Schema.Json
position
Section titled “position”
readonlyposition:number=Schema.Int
schemaVersion
Section titled “schemaVersion”
readonlyschemaVersion:number=Schema.Int
The version of the event’s schema the payload was written with. Events from before versions existed are 1.
timestamp
Section titled “timestamp”
readonlytimestamp:Utc=Schema.DateTimeUtcFromMillis
readonlytype:string=Schema.String
version
Section titled “version”
readonlyversion:number=Schema.Int