/** * @module projection-fold * @category Internal * * Fold engine behind `projection(name).of(state)` — maintains per-stream * folded states in a bounded in-memory cache and flushes one row per dirty * stream per round, so write amplification tracks the distinct-key count * instead of the event count. * * The flush payload deliberately has no type of its own: a state * projection flushes the cache layer outward — the rows ARE the * streams' {@link CacheEntry} values. * * Correctness discipline: * - The engine runs as the projection's batch handler, so the watermark * acks only after a fully-flushed batch — fold work is never * acknowledged before it is durable. * - On first sight of a stream the engine loads its head state through * the same `load()` the command path uses (cache, snapshots and all). * The loaded snapshot carries its own head position (`version` and the * global event `id`), captured atomically with `state`, so the engine * never pairs a stale state with a newer head id read separately from * the cache (ACT-1204). Fetched events at or below the loaded id are * skipped, later ones fold through the state's own patch reducers. * - Eviction under `maxCachedStates` pressure flushes the evictee first * (flush-before-evict) — eviction never loses folded work. */ import type { BatchHandler, CacheEntry, Schema, Schemas, State } from "../types/index.js"; import type { FoldConfig } from "./config.js"; import { type PatchFn } from "./event-sourcing.js"; /** * Internal handle a fold handler exposes so the orchestrator can drop its * process-local state (#1466). * * A rebuild must not trust a per-Act cache: `reset` rewinds the watermark and * replays from the beginning, and every replayed event is at or below the * cached head, so the fold takes its already-folded branch and re-flushes * whatever it happens to hold. If that cache is stale, the rebuild writes the * staleness back out — the one outcome a rebuild exists to prevent. Dropping * the cache makes the next batch re-load head state from the store, which is * authoritative by definition. * * A symbol on the function keeps `BatchHandler` a plain function type; nothing * here is re-exported from `src/index.ts`. */ export declare const FOLD_RESET: unique symbol; /** A batch handler that owns a fold cache it can be told to drop. */ export type ResettableBatchHandler = BatchHandler & { readonly [FOLD_RESET]?: () => void; }; /** * Build the batch handler that folds a state's events into per-stream rows. * The returned closure is long-lived (one per built projection): its cache * survives across drain cycles, so warm streams fold without I/O. It carries * a {@link FOLD_RESET} handle so a rebuild can drop that cache. */ export declare function make_fold_handler(me: State, flush: (rows: ReadonlyArray>) => Promise, config: FoldConfig, patch_fn: PatchFn | undefined, sensitive_fields: (event_name: string) => readonly string[]): BatchHandler; //# sourceMappingURL=projection-fold.d.ts.map