콘텐츠로 이동
한국어

LibSqlJournal

이 콘텐츠는 아직 번역되지 않았습니다.

Defined in: src/persistence/journals/LibSqlJournal.ts:30

Journal backed by libSQL / Turso — SQLite over HTTP or WebSocket.

Behaviour lives in RelationalJournal; this class supplies the SQLite dialect and the client. The schema and statements match SqliteJournal’s, so a local database can be pushed to Turso (or a Turso one pulled down and opened locally) without a migration.

Why this is not just SqliteJournal with another driver. SqliteDriver is synchronous, which a local file affords and a network service does not. Running on the relational base instead also means libSQL gets a durable-state store, which the local SQLite backend still lacks.

Being a remote, cross-process store, it exposes no in-process event bus, so the query layer polls — same as Postgres and Cassandra.

For a local file or :memory:, use SqliteJournal: the @libsql/client/web entry point cannot open them, and the options validator says so rather than letting the driver fail obscurely on the first append.

  • RelationalJournal

new LibSqlJournal(options?): LibSqlJournal

Defined in: src/persistence/journals/LibSqlJournal.ts:31

LibSqlJournalOptions = {}

LibSqlJournal

RelationalJournal.constructor

append<E>(persistenceId, events, expectedSeq, tags?): Promise<PersistentEvent<E>[]>

Defined in: src/persistence/relational/RelationalJournal.ts:102

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.

E

string

readonly E[]

number

readonly string[]

Promise<PersistentEvent<E>[]>

RelationalJournal.append


close(): Promise<void>

Defined in: src/persistence/LazyStore.ts:66

Promise<void>

RelationalJournal.close


delete(persistenceId, toSeq): Promise<void>

Defined in: src/persistence/relational/RelationalJournal.ts:195

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.

string

number

Promise<void>

RelationalJournal.delete


highestSeq(persistenceId): Promise<number>

Defined in: src/persistence/relational/RelationalJournal.ts:186

Current highest sequence number for persistenceId — 0 if no events exist.

string

Promise<number>

RelationalJournal.highestSeq


persistenceIds(): Promise<string[]>

Defined in: src/persistence/relational/RelationalJournal.ts:211

Persistence IDs currently known to the journal (useful for projections).

Promise<string[]>

RelationalJournal.persistenceIds


persistenceIdsPaginated(afterPersistenceId, limit): Promise<string[]>

Defined in: src/persistence/relational/RelationalJournal.ts:221

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.

string | undefined

number

Promise<string[]>

RelationalJournal.persistenceIdsPaginated


read<E>(persistenceId, fromSeq, toSeq?): Promise<PersistentEvent<E>[]>

Defined in: src/persistence/relational/RelationalJournal.ts:168

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.

E

string

number

number

Promise<PersistentEvent<E>[]>

RelationalJournal.read