Skip to content

SqliteQuery

Defined in: src/persistence/query/SqliteQuery.ts:50

SQLite-backed query. Inherits the per-pid read path from InMemoryQuery (which delegates straight to Journal.read) and overrides the tag path with an indexed JOIN against the ${eventsTable}_tags join table that SqliteJournal maintains.

Index shape. The journal’s tags table has primary key (tag, timestamp, persistence_id, sequence_nr), so a WHERE tag = ? AND timestamp >= ? filter walks a contiguous range of the index — bounded cost per query no matter how big the events table grows. We then JOIN to events to pull the payload + the original CSV tags column.

Backwards-compat. SqliteJournal upgrades existing v0 databases (CSV-only, no join table) by backfilling the join table on init() — see SqliteJournal.backfillTagsTableIfNeeded. From the query layer’s POV the table is always present once the journal is open.

Multi-tag filters. The TagFilter operators (all / any / not) are pushed into SQL with one of three strategies:

  • At least one all tag → walk the join-table for all[0], JS-refine the rest of the filter against events.tags. The SQL is the same as the single-tag fast path; only the JS step is wider.
  • No all, but any is non-empty → walk the join-table with t.tag IN (?, ?, …) (DISTINCT to dedupe events tagged with more than one of the listed values), JS-refine for not.
  • Only not (or empty filter) → fall back to the inherited InMemoryQuery scan path, which iterates persistence ids and reads each one. Less efficient, but only-not queries don’t have a selective index to use anyway.

new SqliteQuery(sqlite): SqliteQuery

Defined in: src/persistence/query/SqliteQuery.ts:65

SqliteJournal

SqliteQuery

InMemoryQuery.constructor

currentEventsByPersistenceId<E>(pid, fromSeq, toSeq?): Promise<PersistentEvent<E>[]>

Defined in: src/persistence/query/InMemoryQuery.ts:41

One-shot read of every event for persistenceId whose sequenceNr >= fromSeq (and <= toSeq if given). Resolves once with the events known at call time.

E

string

number

number

Promise<PersistentEvent<E>[]>

InMemoryQuery.currentEventsByPersistenceId


currentEventsByTag<E>(filter, fromOffset): Promise<TaggedEvent<E>[]>

Defined in: src/persistence/query/SqliteQuery.ts:69

One-shot read of every event matching filter whose offset is >= fromOffset. See TagFilter for the operator semantics.

E

TagFilter

Offset

Promise<TaggedEvent<E>[]>

InMemoryQuery.currentEventsByTag


currentPersistenceIds(): Promise<string[]>

Defined in: src/persistence/query/InMemoryQuery.ts:107

Snapshot of every persistence id known to the journal. Resolves once. Useful for fan-out projections that subscribe to one stream per id; pair with eventsByPersistenceId for the continuous read.

Promise<string[]>

InMemoryQuery.currentPersistenceIds


eventsByPersistenceId<E>(pid, fromSeq, options?): AsyncIterable<PersistentEvent<E>>

Defined in: src/persistence/query/InMemoryQuery.ts:47

Live stream of every event for persistenceId whose sequenceNr >= fromSeq. Past events are emitted first (chronological by sequenceNr), then new events as they are appended. The stream never completes on its own — break out of the loop or call return() on the iterator to stop polling.

E

string

number

LiveQueryOptions = {}

AsyncIterable<PersistentEvent<E>>

InMemoryQuery.eventsByPersistenceId


eventsByTag<E>(filter, fromOffset, options?): AsyncIterable<TaggedEvent<E>>

Defined in: src/persistence/query/InMemoryQuery.ts:84

Live stream of every event matching filter whose offset is >= fromOffset. Yields events ordered by (timestamp, persistenceId, sequenceNr). See Offset for offset semantics — the stream emits the offset alongside the event so the consumer can persist progress.

filter accepts either a single tag string (back-compat shortcut for { all: [tag] }) or a TagFilter object that combines all (intersect), any (union), and not (exclusion) operators.

E

TagFilter

Offset

LiveQueryOptions = {}

AsyncIterable<TaggedEvent<E>>

InMemoryQuery.eventsByTag