Ir al contenido
Español

SqliteQuery

Esta página aún no está disponible en tu idioma.

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

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:66

SqliteJournal

SqliteQuery

InMemoryQuery.constructor

allPersistenceIds(options?): AsyncIterable<string>

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

Live stream of every persistence id the journal has ever seen, plus each new one as it first appears. The stream never completes on its own — break out of the loop or call return() on the iterator.

This is the fan-out primitive: start a per-entity projection as its entity shows up, instead of polling currentPersistenceIds and diffing the result yourself.

Once per stream, not once per journal. A fresh subscription re-emits every id, so a consumer that must not act twice across a restart needs its own checkpoint — the same at-least-once posture the event queries have.

Memory. “Once per stream” is enforced with an in-process set of the ids emitted so far, so a stream over a journal with a million ids holds a million strings for as long as it runs. A lexicographic watermark would be cheaper and wrong: ids are not created in sorted order, so an id that sorts below the mark would be skipped forever, and a fan-out projection that silently never starts is the worst failure this API could have. The catch-up sweep is paged, so the peak is the set plus one page — and a one-shot enumeration that needs no set at all is currentPersistenceIdsPaginated.

LiveQueryOptions = {}

AsyncIterable<string>

InMemoryQuery.allPersistenceIds


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

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

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:70

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:127

Snapshot of every persistence id known to the journal, as one array. Resolves once.

Kept, and not deprecated: for a journal with a handful of ids this is simply the convenient shape, and “small journal” is a permanent case rather than a legacy one. It is, however, the only method here with no bound on what it materialises — at a million ids that is a million strings in one allocation. Past the point where the array itself is a cost, use currentPersistenceIdsPaginated, which walks the same data one page at a time.

Promise<string[]>

InMemoryQuery.currentPersistenceIds


currentPersistenceIdsPaginated(options?): AsyncIterable<string>

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

Cursor-paginated snapshot of the persistence ids currently in the journal, ascending, yielded one at a time. Fetches pageSize ids per round-trip, so peak memory is one page rather than the whole set. Completes when the journal is exhausted — unlike allPersistenceIds it does not wait for new ids.

The cursor is a persistence id, not an opaque token. Resume a partial walk by passing the last id you handled as afterPersistenceId. Encoding it would have bought per-backend freedom that no backend here needs — every one of them enumerates ids through an index keyed on the id itself — at the price of a checkpoint no operator can read and no other process can construct.

PaginationOptions = {}

AsyncIterable<string>

InMemoryQuery.currentPersistenceIdsPaginated


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

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

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:104

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