import type { Collection } from '../../kernel/collection.js'; import type { OverlayedViewStrategy } from './types.js'; /** * Virtual-collection proxy returned by `vault.collection(overlayName)` * when `overlayName` is a registered `withOverlayedView`. * * Implements the core `Collection`-shaped read/write surface with * merge-on-read semantics: * - `get(id)`: overlay row wins iff `overlay[shadowField] === shadowValue`; * when `spec.mergeMode` is set, an intermediate status may instead pull * a declared subset of fields from the overlay over the base * - `list()` / `.query()`: union of ids, per-id merge applied * - `put(record)` / `put(id, record)`: routes to overlay; id derived * via the base MV's `rowKey` (validated on the two-arg form) * - `delete(id)`: removes the overlay row only; base stays * * Reactive APIs (`live`, `subscribe`, `query().live()`) are out of * scope for this release and surface as "not yet implemented" — wired in a * future sub-issue. */ export declare class OverlayedCollection = any> { private readonly spec; private readonly baseCollection; private readonly overlayCollection; private readonly baseRowKey; constructor(spec: OverlayedViewStrategy, baseCollection: Collection, overlayCollection: Collection, baseRowKey: ((row: Record) => string) | undefined); /** * Convenience accessors for advanced callers that need to bypass the * virtual layer (bulk imports, direct overlay queries). Mirrors the * spec's "direct writes to the underlying overlay collection skip * the validation" escape hatch. */ readonly overlay: { rowKey: (row: Record) => string; }; /** Get the merged row by id. */ get(id: string): Promise; /** List union of base + overlay ids, applying the merge per row. */ list(): Promise; /** * Write to the overlay. Two forms: * - `put(record)`: id is derived via the base MV's `rowKey(record)`. * Throws if the base isn't an MV. * - `put(id, record)`: validates `id === rowKey(record)`; throws * `OverlayIdMismatchError` on mismatch. */ put(idOrRecord: string | T, maybeRecord?: T): Promise; /** * Remove the overlay row only. Idempotent (no-op on absent). * The base row is untouched — if a base row exists for `id`, * subsequent reads return it. */ delete(id: string): Promise; /** * Merge a single id's overlay + base rows into the visible row. * * Priority (first match wins): * 1. Binary shadow win — overlay present AND * `overlay[shadowField] === shadowValue` → return the overlay row * entirely. This stays FIRST so the original binary behaviour is * unchanged whether or not `mergeMode` is configured. * 2. Field-level merge — overlay present, `mergeMode` configured, * and a rule whose `whenStatus` equals `overlay[shadowField]`. * The matched rule pulls its `overlayFields` (those present on * the overlay row) on top of the base row. With no base row, the * overlay row is returned as-is. * 3. Fallback — return the base row (possibly `null`). An * overlay-only row that qualifies under neither (1) nor (2) and * has no base is therefore NOT surfaced. */ private mergeRows; /** @throws — chainable Query over a virtual collection is deferred. */ query(): never; /** @throws — change-stream subscription over a virtual collection is deferred. */ subscribe(): never; /** @throws — live query over a virtual collection is deferred. */ live(): never; /** @throws — async iteration over a virtual collection is deferred. */ scan(): never; /** @throws — lazy-mode query is not applicable to virtual collections. */ lazyQuery(): never; /** @throws — bulk-atomic put is deferred to a future MV sub-issue. */ putManyAtomic(): never; /** @throws — bulk delete is deferred to a future MV sub-issue. */ deleteMany(): never; /** @throws — `.first()` over a virtual collection is deferred. */ first(): never; /** @throws — `.count()` over a virtual collection is deferred. */ count(): never; }