import type { ViaGraph, FieldRef, EdgeKind, Grain } from '../../kernel/via/graph.js'; import type { FieldClause } from '../../kernel/query/predicate.js'; import type { MaterializedViewStrategy, MVQueryContext } from './types.js'; /** * One registered MV strategy alongside its derived metadata. Stored * type-erased on `TRow` so the registry can hold heterogeneous MVs. */ export interface RegisteredMV { readonly spec: MaterializedViewStrategy; /** Output collection name (`spec.output?.collection ?? spec.name`). */ readonly outputCollection: string; /** Set of source collections; populated at registration via the analyzer. */ readonly dependencies: ReadonlySet; /** Canonical `queryHash` — `_materializedFrom.queryHash` for every emitted row. */ readonly queryHash: string; /** * Top-level FieldClauses on the partition field, captured at * registration time. Used by the cycle detector to resolve * same-collection-as-source edges via the partition-discriminator * check. Empty when `spec.output?.partition` is undefined. */ readonly partitionClauses: readonly FieldClause[]; /** * #638 Task 2 — `'record'` for a row-per-source-row Query or * `unionSources` MV, `'aggregate'` for a `.groupBy().aggregate()` MV * (the shape that requires explicit `sources`, since the dependency * analyzer can't walk an aggregate plan). Feeds `edges()`'s grain. */ readonly grain: Grain; } /** * Vault-internal registry of MV strategies. Owned by `Vault`; not * exported. Parallel to v1's `DerivationRegistry`; the two graphs share * a single cycle-detection pass at vault open (see `validate`). * * @internal */ export declare class MaterializedViewRegistry { /** Keyed by `spec.name`. */ private readonly _byName; /** Keyed by dependency source-collection → MVs that depend on it. */ private readonly _bySource; /** * Register an MV. Invokes `spec.query()` once at registration time to * read the plan + join context; the resulting `Query` is discarded * after dependency extraction. `vault.collection(...)` must therefore * be functional by the time this runs — typically wired from * `Vault._initMaterializedViews` after collection bootstrap. * * Throws `MaterializedViewSourceUnknownError` if the analyzer * surfaces a dependency the vault doesn't know about (when a * `knownCollections` checker is supplied). */ register(spec: MaterializedViewStrategy, db: MVQueryContext, options?: { knownCollections?: (name: string) => boolean; }): Promise; /** All MVs that depend on `source`, in registration order. */ mvsForSource(source: string): ReadonlyArray; /** Single MV by name, or `undefined`. */ byName(name: string): RegisteredMV | undefined; /** Iterate over every registered MV. */ all(): ReadonlyArray; /** * Graph edges for #638 Task 2: one `'mv'` edge per registered MV — target * = the output collection (a `WHOLE_RECORD` artifact node), sources = * every dependency (also `WHOLE_RECORD` nodes). Same-collection edges * (`dep === outputCollection`) are skipped IFF the MV declares an * `output.partition` discriminator AND the query has a where-clause that * provably excludes the partition value (`partitionDisjoint`) — the SAME * condition the old local DFS used. Grain comes from the registration-time * `RegisteredMV.grain`. */ edges(): ReadonlyArray<{ readonly target: FieldRef; readonly sources: readonly FieldRef[]; readonly kind: EdgeKind; readonly grain: Grain; }>; /** * Cycle detection, delegated to `ViaGraph.assertAcyclic()` (#638 Task 2 — * retires the local DFS). `graph` is the caller's shared per-vault graph, * ALREADY carrying this registry's `edges()` AND `DerivationRegistry`'s * (registered by the caller — see `Vault._initMaterializedViews`, which * runs after `_initDerivations`, so a pure-derivation cycle already threw * `DerivationCycleError` there; any cycle surfacing here necessarily * touches an MV edge). Throws `MaterializedViewCycleError` — SAME class as * before. */ validate(graph: ViaGraph): void; } /** * Wrap an `MVQueryContext` so its `.collection().query()` returns a * Query with the MV's declared predicates attached. Bare Queries * (outside of any MV) don't gain `.wherePredicate()` — only Queries * obtained through this wrapped db do. * * @internal */ export declare function wrapDbWithPredicates(db: MVQueryContext, predicates: NonNullable>['predicates']>): MVQueryContext;