/** * The sync lookup snapshot + join/locale seam (#650 Task 6, spec §5 — "the * snapshot+locale seam"). Retires the #626 kernel→via grandfather: * `kernel/query/join.ts` no longer imports `via/i18n/core.js` directly * — it calls the `presentForJoin` hook this file's `buildPresentForJoin` * builds instead (seam map Part 2 item 4, the #626 reviewer-spec'd shape: * a sync `presentI18nForJoin`-class hook on `JoinableSource`). * * `LookupSnapshot` is the sync materialized `key -> row` view over ONE * lookup dimension's ALREADY-LIVE backing data (the `active.ts` * `_syncCache`/`snapshotEntries` write-through-cache pattern — never a * second copy of the data: `LookupViaConfig.snapshotFor`'s vault-built * closure reads the SAME `LookupHandle._syncCache` / * first-class-collection cache every other lookup consumer * (`dictLabelResolver`, `resolveDictSource`, `getAltIndex`) already reads). * Serves (reserved AND matrix tier since #650 Task 7 — `registry.ts`'s * `buildLookupSnapshotRows` routes both; static tier is read straight off * `descriptor.table` by every consumer below, never through this cache): * - join dressing (`presentForJoin`, consumed by `kernel/query/join.ts` * via `JoinableSource.presentForJoin`) * - dimension sort (`compareForOrder`, consumed by * `via/lookup/binding.ts`'s `ViaBinding.compareForOrder` closure) * - per-call-locale order-label resolution (`resolveOrderLabel`, #650 * Task 7 — the `orderBy(..., {by:'label'})` channel `compareForOrder` * structurally can't serve, no locale param; consumed by * `kernel/query/builder.ts`'s `buildOrderLabelMaps`) * - membership: reserved/static-tier membership (#650 Task 3, * `checkLookupMembership`) already reads the identical sync caches * directly — not re-plumbed through this file; see * `.superpowers/sdd/task-6-report.md`'s "bridge disposition" section. * * Sync end-to-end (#553) — every function here is a pure, synchronous * transform over already-materialized rows; no store read, no Promise. */ import type { LookupDescriptor } from './descriptor.js'; import { type I18nTextDescriptor } from '../i18n/core.js'; /** A lookup dimension's sync materialized view — see file header. */ export interface LookupSnapshot { /** The full backing row for `key`, or `undefined` when `key` isn't (yet) present in the snapshot. */ row(key: string): Record | undefined; /** The dimension's declared presentation label for `key` at `locale` — mirrors `binding.ts`'s `fetchLookupLabel` (matrix-row branch), generalized to any tier's already-materialized rows. */ label(key: string, locale: string, fallback?: unknown): string | undefined; /** * Exact ordering for two canonical keys against `descriptor.sortBy` * (falls back to `present.label`, then to the raw keys) at `locale`. * Never throws — degrades to comparing the raw keys when no sortable * value resolves for either side. */ compareKeys(a: string, b: string, locale: string): number; } /** * Build a sync `LookupSnapshot` over one dimension's already-materialized * rows (canonical-key -> row, the SAME keying `materializeBackingTable` * (`registry.ts`, #650 Task 3) uses). Pure — never reads a store. */ export declare function buildLookupSnapshot(dimension: string, rows: ReadonlyMap>, descriptor: LookupDescriptor): LookupSnapshot; /** * Build the combined sync `presentForJoin(record, locale)` hook a * `Collection` attaches to the `JoinableSource` it exposes * (`querySourceForJoin()`) — the i18n-text half (`presentI18nForJoin`, the * exact `applyI18nLocale(..., 'join')` partial application * `kernel/query/join.ts` used to call directly, #626) composed with the * lookup-label half above. `undefined` when the collection declares * neither — `JoinableSource.presentForJoin` then stays unset, matching * today's `i18nFields`-absent behavior exactly (#626 parity lock). */ export declare function buildPresentForJoin(i18nFields: Record | undefined, lookupFields: Record | undefined, getSnapshotRows: ((descriptor: LookupDescriptor) => ReadonlyMap> | undefined) | undefined): ((record: unknown, locale: string) => unknown) | undefined;