DynamoDbJournal
Defined in: src/persistence/journals/DynamoDbJournal.ts:70
Journal backed by Amazon DynamoDB.
Optimistic concurrency is a conditional write, and it is stronger than the
relational backends’. append sends every event in one
TransactWriteItems, each Put carrying
ConditionExpression: attribute_not_exists(pid) — “only if this
(pid, seq) item does not exist”. A racing writer therefore cannot win a
partial append: the transaction is atomic across all items, so either the
whole batch lands or none of it does, and the cancellation is translated into
JournalConcurrencyError. The preceding head read is only an optimization
that turns the common stale-append into one cheap query instead of a rejected
transaction.
That atomicity is why this backend needs no equivalent of MongoDB’s “a mid-batch failure can persist a prefix” caveat.
The high-water mark is an item, not a table. Compaction stores
deletedTo at the reserved sort key 0, updated with
ConditionExpression: attribute_not_exists(deletedTo) OR deletedTo < :value,
which is GREATEST / $max expressed as a condition: a lower value is
rejected, and the rejection is expected rather than an error.
Reads and deletes page. DynamoDB returns at most 1 MB per Query, so a
recovery over a long stream loops on LastEvaluatedKey; skipping that is the
classic way to silently truncate a replay.
Being a remote, cross-process store, it exposes no in-process event bus, so the query layer polls. There is no indexed tag path yet — see the class docs for what that would take.
Extends
Section titled “Extends”Implements
Section titled “Implements”Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new DynamoDbJournal(
options?):DynamoDbJournal
Defined in: src/persistence/journals/DynamoDbJournal.ts:75
Parameters
Section titled “Parameters”options?
Section titled “options?”Returns
Section titled “Returns”DynamoDbJournal
Overrides
Section titled “Overrides”DynamoDbStore.constructor
Methods
Section titled “Methods”append()
Section titled “append()”append<
E>(persistenceId,events,expectedSeq,tags?):Promise<PersistentEvent<E>[]>
Defined in: src/persistence/journals/DynamoDbJournal.ts:95
Append events to the stream of persistenceId, enforcing optimistic
concurrency: the current highest sequence number MUST equal expectedSeq
or the call throws JournalConcurrencyError. Returns the written events
with their assigned sequence numbers.
Type Parameters
Section titled “Type Parameters”E
Parameters
Section titled “Parameters”persistenceId
Section titled “persistenceId”string
events
Section titled “events”readonly E[]
expectedSeq
Section titled “expectedSeq”number
readonly string[]
Returns
Section titled “Returns”Promise<PersistentEvent<E>[]>
Implementation of
Section titled “Implementation of”close()
Section titled “close()”close():
Promise<void>
Defined in: src/persistence/LazyStore.ts:66
Best-effort teardown; idempotent.
Returns
Section titled “Returns”Promise<void>
Implementation of
Section titled “Implementation of”Inherited from
Section titled “Inherited from”delete()
Section titled “delete()”delete(
persistenceId,toSeq):Promise<void>
Defined in: src/persistence/journals/DynamoDbJournal.ts:200
Delete events up to and including toSeq — used when compacting past
a snapshot. Only ever a prefix, so what survives is a suffix that
read still returns contiguously, and sequence numbers never rewind:
highestSeq keeps reporting the high-water mark afterwards.
Parameters
Section titled “Parameters”persistenceId
Section titled “persistenceId”string
number
Returns
Section titled “Returns”Promise<void>
Implementation of
Section titled “Implementation of”highestSeq()
Section titled “highestSeq()”highestSeq(
persistenceId):Promise<number>
Defined in: src/persistence/journals/DynamoDbJournal.ts:191
Current highest sequence number for persistenceId — 0 if no events exist.
Parameters
Section titled “Parameters”persistenceId
Section titled “persistenceId”string
Returns
Section titled “Returns”Promise<number>
Implementation of
Section titled “Implementation of”persistenceIds()
Section titled “persistenceIds()”persistenceIds():
Promise<string[]>
Defined in: src/persistence/journals/DynamoDbJournal.ts:230
No persistenceIdsPaginated counterpart, deliberately. Paging needs a
sorted index over the ids, and a DynamoDB table has no order across
partition keys at all — Scan hands rows back in hash order, and its
LastEvaluatedKey cursor is not comparable to a persistence id. Slicing
a scan by page would therefore return arbitrary, overlapping subsets; the
query layer’s fallback (scan once, sort, cut) is the honest shape, and
leaving the method off is what selects it.
Returns
Section titled “Returns”Promise<string[]>
Implementation of
Section titled “Implementation of”read()
Section titled “read()”read<
E>(persistenceId,fromSeq,toSeq?):Promise<PersistentEvent<E>[]>
Defined in: src/persistence/journals/DynamoDbJournal.ts:162
Return the events in [fromSeq, …, toSeq], ascending by sequence
number. toSeq defaults to the current highest sequence number.
Both bounds are inclusive — fromSeq is the first event returned,
not an “after” cursor.
Ordering and contiguity are part of the contract, and replay
enforces them (#122). Consecutive entries must differ by exactly
one, every sequenceNr must be a safe integer ≥ 1, and nothing may
fall outside the requested window. delete compacts a prefix,
never a hole in the middle, so a gap inside the returned slice can
only mean a defect — a missing ORDER BY, a half-written append, a
store someone else can write. replayState raises
JournalIntegrityError instead of folding it, because an actor
that recovers from a shuffled or holed stream reaches a state that
never existed and then fails every later persist with a
JournalConcurrencyError that has no visible cause.
Type Parameters
Section titled “Type Parameters”E
Parameters
Section titled “Parameters”persistenceId
Section titled “persistenceId”string
fromSeq
Section titled “fromSeq”number
toSeq?
Section titled “toSeq?”number
Returns
Section titled “Returns”Promise<PersistentEvent<E>[]>
