/** * The `'lookup'` `ViaBinding` — wires the lookup engine (present-time label * dressing across all three backing tiers) into the kernel's generic Via * port. Mirrors `via/i18n/binding.ts`'s #553 static-link pattern; the * present-time label-dressing algorithm below is adapted from * `via-i18n/binding.ts:253-337` (the same wildcard/array/scalar handling, * the same `onMissing`/`substitute` policy engine), generalized to branch on * `backing` instead of a static-vs-dynamic descriptor-shape check. For the * `'static'` and `'reserved'` tiers this delegates to `cfg.lookupLabelResolver` * — the SAME vault-built closure the i18n binding's `dictLabelResolver` uses * (static table first, else the `vault.dictionary()` handle) — so a native * `dict()`/`lookup(static)` field resolves through the identical label data * as its `dictKey()`/`staticDict()` alias (the byte-equivalence lock). * * `lookup()`/`enumOf()`/`dict()` each call {@link linkLookupVia} first — the * same #553 pattern `money()`/`dictKey()` use. * * `buildClause` (label-predicate queries) is still undeclared — out of scope * for #650. `compareForOrder` (#650 Task 6, spec §5; matrix tier added Task * 7) resolves a `sortBy`-declared field's ordering via `cfg.snapshotFor`'s * sync snapshot; the hook signature is UNCHANGED (`via/index.ts:128-129` — no * locale param), so it closes over each descriptor's own `displayLocale` * (the same locale-less-hinge default `runLookupPresent`'s * `hasStaticDisplay` branch already uses). `resolveOrderLabel` (#650 Task * 7) is the PER-CALL-locale sibling `orderBy(..., {by:'label'})` needs — * see its own doc comment below. `describeFragment` (#650 Task 7) is the * first-ever consumed `ViaBinding.describeFragment` implementation — see * `with-shape/introspection/describe.ts`'s `buildDescription`. */ import type { ViaBinding } from '../../kernel/via/index.js'; import type { LookupDescriptor, LookupBacking, Vocabulary, OnDelete } from './descriptor.js'; import type { MaterializedBacking } from './registry.js'; /** * Config a collection's lookup declarations resolve to — the binding's * construction input. `lookupLabelResolver`/`getLookupBacking`/`membership`/ * `snapshotFor` are vault-built closures (never a `Collection` handle, * keyring, or DEK/CEK — the zero-knowledge boundary). */ export interface LookupViaConfig { readonly lookupFields: Record; readonly lookupLabelResolver?: (dimension: string, key: string, locale: string, fallback?: unknown) => Promise; /** * The matrix (collection) tier's present-time backing-row source, keyed by the full * descriptor (not a bare dimension name) so the closure can resolve by `descriptor.key`, * not the backing row's PUT-id (#651 Task 3 — the same descriptor-gaining dispatch Task 7 * already applied to `snapshotFor`). */ readonly getLookupBacking?: (descriptor: LookupDescriptor) => (key: string) => Promise | undefined>; /** Closed-vocabulary write-time membership test (#650 Task 3) — `(field, key) => known?`. */ readonly membership?: (field: string, key: string) => boolean | Promise; /** Sync per-descriptor altKey index — `ingest`'s normalization source (#650 Task 3). */ readonly getAltIndex?: (desc: LookupDescriptor) => MaterializedBacking | undefined; /** * Sync materialized `key -> row` rows for a lookup descriptor (#650 Task * 6, spec §5; matrix-tier routing added #650 Task 7) — `compareForOrder` * and `resolveOrderLabel` below, and `snapshot.ts`'s `presentForJoin` * builder, all read this same vault-built closure. Reserved AND * collection (matrix) tier route here (the vault wires * `dimension -> LookupHandle.snapshotEntries()` / `dimension -> * collection.querySourceForJoin().snapshot()` respectively, keyed by * `descriptor.key` for the matrix case — see `registry.ts`'s * `buildLookupSnapshotRows`); static tier is resolved locally from * `descriptor.table` without calling this. */ readonly snapshotFor?: (descriptor: LookupDescriptor) => ReadonlyMap> | undefined; readonly collectionName: string; } /** * One field's `lookup` descriptor as it appears on a `ViaBinding. * describeFragment()` payload (#650 Task 7 — the first real consumer, * `with-shape/introspection/describe.ts`'s `buildDescription`, imports this * type directly; `describe.ts` is NOT under `kernel/**`, so it's free to * import concrete via/ types the way it already does for * `LookupDescriptor`/`MoneyDescriptor`/etc.). `dimension` is OMITTED (not * emitted as `''`) for a bare `enumOf()` descriptor — the #650 Task 2 * `dimension:''` sentinel resolved: no dimension name means no `dimension` * key, not a meaningless empty string (T2 carry, #650 Task 7). */ export interface LookupDescribeFragmentEntry { readonly dimension?: string; readonly backing: LookupBacking; readonly vocabulary: Vocabulary; readonly key: string; readonly altKeys?: readonly string[]; readonly present?: { readonly label: string; readonly by?: string; }; readonly sortBy?: string; readonly onDelete: OnDelete; /** Statically-known closed-vocabulary key set (declared `keys`, or a static table's own keys). Omitted when membership lives only in the backing collection/dictionary (open vocabulary, or closed with no declared `keys`). */ readonly keys?: readonly string[]; } /** The `'lookup'` binding's `describeFragment()` payload shape. */ export interface LookupDescribeFragment { readonly lookupFields: Record; } export declare function lookupBinding(cfg: LookupViaConfig): ViaBinding; export declare function linkLookupVia(): void;