SqliteJournal
이 콘텐츠는 아직 번역되지 않았습니다.
Defined in: src/persistence/journals/SqliteJournal.ts:56
Journal backed by SQLite — zero-dependency, single-file persistence.
Works on all three runtimes via the SqliteDriver abstraction in
src/runtime/sqlite/ — Bun (bun:sqlite), Node (better-sqlite3, or the
built-in node:sqlite when it is not installed) and Deno (node:sqlite).
Every driver shares the same prepared-statement + transaction shape, so the
journal code itself is unchanged across runtimes.
Construction is lazy: the native DB is opened on the first append /
read / highestSeq / delete / persistenceIds call. This keeps
new SqliteJournal(SqliteJournalOptions.create().withPath(path))
sync-friendly (matches the pre-abstraction shape) while still
supporting the async driver-resolution flow Node requires.
Implements
Section titled “Implements”Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new SqliteJournal(
options?):SqliteJournal
Defined in: src/persistence/journals/SqliteJournal.ts:73
Parameters
Section titled “Parameters”options?
Section titled “options?”SqliteJournalOptions = {}
Returns
Section titled “Returns”SqliteJournal
Properties
Section titled “Properties”events
Section titled “events”
readonlyevents:JournalEventBus
Defined in: src/persistence/journals/SqliteJournal.ts:67
In-process event bus — published-to inside append so the query
layer can do sub-poll-interval push delivery in the same process.
Cross-process subscribers (separate Bun/Node instance reading
the same SQLite file) still need to poll; that’s the inherent
limit of in-process notifications.
Implementation of
Section titled “Implementation of”Accessors
Section titled “Accessors”serializer
Section titled “serializer”Get Signature
Section titled “Get Signature”get serializer():
Serializer<unknown> |undefined
Defined in: src/persistence/journals/SqliteJournal.ts:84
The configured payload serializer — read by SqliteQuery so tag reads decode like the journal.
Returns
Section titled “Returns”Serializer<unknown> | undefined
Methods
Section titled “Methods”append()
Section titled “append()”append<
E>(persistenceId,events,expectedSeq,tags?):Promise<PersistentEvent<E>[]>
Defined in: src/persistence/journals/SqliteJournal.ts:86
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/journals/SqliteJournal.ts:237
Best-effort teardown; idempotent.
Returns
Section titled “Returns”Promise<void>
Implementation of
Section titled “Implementation of”delete()
Section titled “delete()”delete(
persistenceId,toSeq):Promise<void>
Defined in: src/persistence/journals/SqliteJournal.ts:190
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/SqliteJournal.ts:177
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/SqliteJournal.ts:209
Persistence IDs currently known to the journal (useful for projections).
Returns
Section titled “Returns”Promise<string[]>
Implementation of
Section titled “Implementation of”persistenceIdsPaginated()
Section titled “persistenceIdsPaginated()”persistenceIdsPaginated(
afterPersistenceId,limit):Promise<string[]>
Defined in: src/persistence/journals/SqliteJournal.ts:219
One ascending page of persistence ids: those strictly greater than
afterPersistenceId — all of them when it is undefined — capped at
limit. Returning fewer than limit means the journal is exhausted.
Optional on purpose. Not every store can enumerate ids in order:
DynamoDB reaches partition keys only through a full table scan, and
MongoDB’s distinct has no cursor. A journal without a sorted index
over its ids omits this, and the query layer falls back to
persistenceIds() plus an in-process slice — correct, just not cheaper
than the full list. Implement it wherever a sorted key exists; that is
what keeps currentPersistenceIdsPaginated from materialising a million
rows to hand back the first 256.
Which ascending order is the backend’s business. afterPersistenceId
is compared in the same order the page is sorted by, so Postgres’ collated
ORDER BY and SQLite’s byte-wise one are both fine — a paginated walk only
needs the order to be total and stable within one journal. What a
journal must not do is mix two orders across calls, which would make the
cursor skip ids.
Parameters
Section titled “Parameters”afterPersistenceId
Section titled “afterPersistenceId”string | undefined
number
Returns
Section titled “Returns”Promise<string[]>
Implementation of
Section titled “Implementation of”Journal.persistenceIdsPaginated
read()
Section titled “read()”read<
E>(persistenceId,fromSeq,toSeq?):Promise<PersistentEvent<E>[]>
Defined in: src/persistence/journals/SqliteJournal.ts:146
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>[]>
