@datakable/core 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/pipeline/runner.ts"],"sourcesContent":["import { getValue } from '../column/get-value'\nimport { keepDiagnostics } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport { SLICED, sliceTimer } from '../diagnostics/trace-store'\nimport type { Emit, Trigger } from '../diagnostics/types'\nimport { featureDiagnostics } from '../feature/codes'\nimport type { FeatureRuntime } from '../feature/runtime'\nimport type { AnyFeature, RowModelContext } from '../feature/types'\nimport { matchCellIssues } from '../ingest/cell-issues'\nimport { type KeyOf, resolveRowKeys } from '../ingest/row-key'\nimport { CellFailures } from '../intercept/cell-batch'\nimport { errorName } from '../intercept/classify'\nimport { type ContextBase, createContext } from '../intercept/context'\nimport { FALLBACK } from '../intercept/fallbacks'\nimport type { InterceptorRuntime } from '../intercept/runtime'\nimport type { TableState } from '../table/types'\nimport type { ColumnCache, SlicedFormatting } from './column-cache'\nimport { type ResolvedColumn, type ResolvedColumns, resolveColumns } from './columns'\nimport { checkStep, indexPrint, stepDiagnostics } from './dev-checks'\nimport { allRows } from './indices'\nimport { lazyRows, Row, type RowIssue, type RowSource } from './row'\nimport type { Slicer } from './slice'\nimport { inStepDiagnosticSetsError } from './status-rule'\nimport type { RowModel, RowModelStatus } from './types'\n\nkeepDiagnostics(featureDiagnostics, stepDiagnostics)\n\nconst EMPTY: readonly never[] = []\nconst NO_EMIT = (() => undefined) as Emit\n\n/** What `createTable` gives the runner. */\nexport interface PipelineHost {\n readonly runtime: InterceptorRuntime\n /**\n * What the features brought (`runtimeFor`): the column cache and time-slicing of their steps.\n * Always set when a feature has a `rowModel`; a table without features runs no step.\n */\n readonly featureRuntime?: FeatureRuntime | undefined\n readonly emit: Emit\n /** Installed features in pipeline (stage) order. */\n readonly features: readonly AnyFeature[]\n /** `options.features` in the listed order: `where` = `features[<listed index>].rowModel`. */\n readonly listed: readonly AnyFeature[]\n base(): ContextBase\n /** Starts a pipeline run: increments and returns the run id. */\n nextRun(): number\n getData(): readonly unknown[]\n getState(): TableState\n getColumns(): readonly unknown[] | undefined\n getRowKey(): unknown\n /** `RowModel.isInitialLoad`: no data applied yet (§6.6). */\n isInitialLoad(): boolean\n /**\n * The table's status outside the pipeline (`'validating'`, `'error'` after a failed ingest, …);\n * a step failing in this run makes the row model `'error'` regardless.\n */\n status(): RowModelStatus\n /** Schema issues of a flagged row by data index (`invalidRows: 'flag'`); else `undefined`. */\n issues(index: number): readonly RowIssue[] | undefined\n /** `schema` + `invalidRows: 'flag'` (read once): steps get `RowModelContext.flagged`. */\n readonly flagMode?: boolean\n /**\n * Time-sliced work (§9.1, `RowModelContext.slice`) ended: recompute the row model and notify,\n * under the trigger of the run that started it. Without it nothing is sliced.\n */\n refresh?(trigger: Trigger): void\n}\n\nexport interface Pipeline<T> {\n /** Runs `pipeline:run` and returns the row model (the previous object when nothing changed). */\n run(): RowModel<T>\n /** The last row model, if the pipeline ran. */\n current(): RowModel<T> | undefined\n /** The last run (`explain`, §8.4); `undefined` before the first. */\n lastRun(): RunRecord | undefined\n /**\n * A `rowModel` context over the current data and columns for replaying a step on chosen rows\n * (`explainRow`, §8.4): diagnostics are dropped and `batch` runs its body directly (no\n * interceptors), so a replay reports nothing and changes nothing.\n */\n replayContext(name: string): RowModelContext\n /** Cancels time-sliced work in progress (`destroy()`). */\n dispose(): void\n}\n\n/**\n * One step of the last run (`explain` / `explainRow`, §8.4): references to the index arrays the\n * step memo holds anyway, never copies. `cached`: served from the memo; `failed`: the step threw or\n * returned a bad output and passed its input through.\n */\nexport interface RunRecord {\n readonly run: number\n readonly trigger: Trigger\n /** The client steps that ran, in order (fewer when `pipeline:run` itself failed). */\n readonly steps: readonly StepRecord[]\n}\n\nexport interface StepRecord {\n readonly feature: AnyFeature\n readonly input: Uint32Array\n readonly output: Uint32Array\n readonly cached: boolean\n readonly failed: boolean\n}\n\ninterface StepMemo {\n input: Uint32Array\n state: unknown\n columns: readonly unknown[]\n output: Uint32Array\n}\n\ninterface Built<T> {\n model: RowModel<T>\n data: readonly unknown[]\n indices: Uint32Array\n columns: readonly unknown[]\n rowKey: unknown\n}\n\n/**\n * The index-based pipeline (§3.3, §9.1): each step consumes and produces a `Uint32Array` of row\n * indices, is memoised on (input reference, own slice, columns), and `Row` objects are created only\n * for the final (visible) indices, each when it is first read.\n */\nexport function createPipeline<T>(host: PipelineHost): Pipeline<T> {\n /**\n * In-step diagnostics the §6.6 status rule counts (`inStepDiagnosticSetsError`), ever reported:\n * a step whose run moved it makes the row model `'error'` and is not memoised.\n */\n const flags = { count: 0 }\n /** `emit` for steps and the column cache: counts through the status rule. */\n const stepEmit = ((code, details, options) => {\n if (inStepDiagnosticSetsError(code)) flags.count++\n host.emit(code, details, options)\n }) as Emit\n const rt = host.featureRuntime\n // Only steps (and explainRow's replay of them) read the cache: they exist only with a runtime.\n const cache = rt?.createColumnCache({\n runtime: host.runtime,\n emit: stepEmit,\n base: () => host.base(),\n flags,\n }) as ColumnCache\n // A server-mode feature (§7.1) only holds state: the server ran its step.\n const steps = host.features.filter(\n (f) => f.stage !== 'none' && f.mode !== 'server' && typeof f.rowModel === 'function',\n )\n const where = new Map(steps.map((f) => [f, `features[${host.listed.indexOf(f)}].rowModel`]))\n const memo = new Map<AnyFeature, StepMemo>()\n const sources = new WeakMap<ResolvedColumns, RowSource>()\n const keyFailures = new CellFailures()\n /** The first `rowKey` error of the current build (its `cause`). */\n let keyError: unknown\n const keyFailed = (index: number, e: unknown) => {\n if (keyFailures.count === 0) keyError = e\n keyFailures.add(index, e)\n }\n let last: Built<T> | undefined\n /** Row keys resolved over all rows (§5.2), per (data, rowKey) reference. */\n let keys: { data: readonly unknown[]; rowKey: unknown; keyOf: KeyOf } | undefined\n let model: RowModel<T> | undefined\n /** The last run (replaced per run; a few references per step). */\n let lastRun: RunRecord | undefined\n /** Steps of the current run waiting on time-sliced work (§9.1): the row model is 'pending'. */\n let waiting = 0\n const refresh = host.refresh\n const slicer: Slicer | undefined = rt?.createSlicer({\n emit: stepEmit,\n // Not during SSR, and not for the first row model (the hydrated client matches the server).\n enabled: () => refresh !== undefined && last !== undefined && host.base().phase === 'client',\n trigger: () => host.base().trigger,\n done: (trigger) => refresh?.(trigger),\n timed: (feature, ms) => sliceTimer.current?.(host.base(), feature, ms),\n })\n\n /** `Row.getValue` failures: one emit per failing cell, built only when a cell fails. */\n function reportCell(col: ResolvedColumn, index: number, e: unknown, field: string) {\n const name = errorName(e)\n host.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: `columns[${col.index}].${field}`,\n column: col.id,\n rows: [index],\n count: 1,\n fallback: 'cell-undefined',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n }\n // A key-path read error, captured by a closure made once (Row.getValue is per cell: no\n // allocation per call).\n let pathFailed = false\n let pathError: unknown\n const onPathError = (e: unknown) => {\n pathFailed = true\n pathError = e\n }\n\n function rowSource(cols: ResolvedColumns): RowSource {\n let s = sources.get(cols)\n if (s) return s\n s = {\n value(index, original, id) {\n const col = cols.byId.get(id)\n if (!col) return undefined\n if (col.path) {\n const v = getValue(original, col.path, onPathError)\n if (pathFailed) {\n const e = pathError\n pathFailed = false\n pathError = undefined\n reportCell(col, index, e, 'key')\n }\n return v\n }\n if (!col.accessor) return undefined\n try {\n return col.accessor(original)\n } catch (e) {\n reportCell(col, index, e, 'accessor')\n return undefined\n }\n },\n issues: (index) => host.issues(index),\n cellIssues(issues, id) {\n const col = cols.byId.get(id)\n return col ? matchCellIssues(issues, col.path) : EMPTY\n },\n }\n sources.set(cols, s)\n return s\n }\n\n function reportKeyFailures() {\n if (keyFailures.count === 0) return\n const name = errorName(keyError)\n host.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: 'rowKey',\n rows: Array.from(keyFailures.sample()),\n count: keyFailures.count,\n fallback: 'row-key-index',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: keyError },\n )\n keyFailures.reset()\n keyError = undefined\n }\n\n function build(\n data: readonly unknown[],\n indices: Uint32Array,\n columns: readonly unknown[],\n filteredCount: number,\n status: RowModelStatus,\n ): RowModel<T> {\n const rowKey = host.getRowKey()\n const isInitialLoad = host.isInitialLoad()\n const prev = last\n if (\n prev &&\n prev.indices === indices &&\n prev.data === data &&\n prev.columns === columns &&\n prev.rowKey === rowKey &&\n prev.model.status === status &&\n prev.model.isInitialLoad === isInitialLoad\n ) {\n return prev.model\n }\n const source = rowSource(resolveColumns(columns))\n keyFailures.reset()\n if (keys?.data !== data || keys.rowKey !== rowKey) {\n keys = { data, rowKey, keyOf: resolveRowKeys(data, rowKey, host.emit, keyFailed) }\n }\n const keyOf = keys.keyOf\n reportKeyFailures()\n // A data array whose rows cannot be read fails this run (the last good row model is kept),\n // not a later read of `rows[i]`.\n for (let i = 0; i < indices.length; i++) void data[indices[i] as number]\n // Rows are built when read (§9.3: no Row per visible row up front). The key scan above read\n // every key; one that throws only now is reported now.\n const rows = lazyRows(indices.length, (i) => {\n const r = indices[i] as number\n const original = data[r] as T\n const row = new Row<T>(source, r, keyOf(original, r), original)\n reportKeyFailures()\n return row\n })\n const m: RowModel<T> = { rows, filteredCount, totalCount: data.length, status, isInitialLoad }\n last = { model: m, data, indices, columns, rowKey }\n return m\n }\n\n function run(): RowModel<T> {\n host.nextRun()\n const data = host.getData()\n const columns = host.getColumns() ?? EMPTY\n const cols = resolveColumns(columns)\n const state = host.getState()\n let failed = false\n let result: RowModel<T> | undefined\n const records: StepRecord[] = []\n const { run: runId, trigger } = host.base()\n lastRun = { run: runId, trigger, steps: records }\n\n const rowModelContext = (name: string): RowModelContext & SlicedFormatting => ({\n name,\n data,\n emit: stepEmit,\n ...(host.flagMode ? { flagged: (i: number) => host.issues(i) } : {}),\n run: host.base().run,\n columns,\n getColumnValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.values(data, col) : undefined\n },\n getFormattedValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.formatted(data, col) : undefined\n },\n *formattedSliced(id) {\n const col = cols.byId.get(id)\n return col ? yield* cache.formattedSliced(data, col) : undefined\n },\n batch: (id, slot, rows, body) => {\n const col = cols.byId.get(id)\n if (col) cache.batch(col, slot, slot, rows, body)\n return col !== undefined\n },\n slice: (key, job) => {\n const r = (slicer as Slicer).run(key, job, name)\n if (r === undefined) waiting++\n return r\n },\n })\n\n function step(f: AnyFeature, input: Uint32Array): Uint32Array {\n const slice = state[f.name]\n const m = memo.get(f)\n if (m && m.input === input && Object.is(m.state, slice) && m.columns === columns) {\n records.push({ feature: f, input, output: m.output, cached: true, failed: false })\n return m.output\n }\n let ok = false\n const flagged = flags.count\n const waited = waiting\n const ctx = createContext(\n 'pipeline:step',\n { stage: f.stage, feature: f.name, indices: input },\n where.get(f) as string,\n host.base(),\n )\n const output = host.runtime.run('pipeline:step', ctx, () => {\n let out: unknown\n // Dev check (§3.4 devChecks): a bounded fingerprint of the input before rowModel runs.\n const before = (process.env.NODE_ENV !== \"production\") ? indexPrint(input) : 0\n try {\n out = (f.rowModel as NonNullable<AnyFeature['rowModel']>)(\n input,\n slice,\n rowModelContext(f.name),\n )\n } catch (e) {\n const name = errorName(e)\n host.emit(\n 'DK_FEATURE_FAILED',\n {\n feature: f.name,\n hook: 'rowModel',\n fallback: 'step-passthrough',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n return input\n }\n // The tracer adds the time of this sliced work to the step (#61).\n if (waiting > waited) ctx.meta.set(SLICED, true)\n // Dev: a mutated input warns; a bad output passes the input through, not memoised.\n if ((process.env.NODE_ENV !== \"production\") && !checkStep(stepEmit, f.name, input, before, out, data.length)) return input\n ok = true\n return out instanceof Uint32Array ? out : input\n })\n // A counted in-step diagnostic (status rule): 'error' with the step's output, re-run next time.\n // A step waiting on sliced work returned a stand-in: re-run next time too.\n if (ok && flags.count === flagged) {\n if (waiting === waited) memo.set(f, { input, state: slice, columns, output })\n else memo.delete(f)\n } else {\n failed = true\n memo.delete(f)\n }\n records.push({ feature: f, input, output, cached: false, failed: !ok })\n return output\n }\n\n const ctx = createContext('pipeline:run', { rowCount: data.length }, 'features', host.base())\n // The last good row model (§3.4): its indices; the runner keeps the matching rows below.\n if (last) ctx.meta.set(FALLBACK, last.indices)\n waiting = 0\n slicer?.begin()\n try {\n void host.runtime.run('pipeline:run', ctx, () => {\n let indices = allRows(data)\n let filteredCount = -1\n for (const f of steps) {\n if (f.stage === 'paginate' && filteredCount < 0) filteredCount = indices.length\n indices = step(f, indices)\n }\n if (filteredCount < 0) filteredCount = indices.length\n // Sliced work in progress is 'pending', below every other status (§6.6 precedence).\n const outside = host.status()\n const status = failed ? 'error' : waiting > 0 && outside === 'idle' ? 'pending' : outside\n result = build(data, indices, columns, filteredCount, status)\n return indices\n })\n } finally {\n // Sliced work no step asked for in this run is stale: cancelled.\n slicer?.end()\n if (result) model = result\n else {\n // pipeline:run failed: the boundary reported it, or a strict throw is leaving the run\n // (#43). Either way the last good rows with status 'error', never an empty 'idle' model.\n const isInitialLoad = host.isInitialLoad()\n model = last\n ? { ...last.model, status: 'error', isInitialLoad }\n : { rows: EMPTY, filteredCount: 0, totalCount: 0, status: 'error', isInitialLoad }\n }\n }\n return model\n }\n\n function replayContext(name: string): RowModelContext {\n const data = host.getData()\n const columns = host.getColumns() ?? EMPTY\n const cols = resolveColumns(columns)\n return {\n name,\n data,\n emit: NO_EMIT,\n ...(host.flagMode ? { flagged: (i: number) => host.issues(i) } : {}),\n run: host.base().run,\n columns,\n getColumnValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.values(data, col) : undefined\n },\n getFormattedValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.formatted(data, col) : undefined\n },\n batch: (id, _slot, _rows, body) => {\n if (!cols.byId.has(id)) return false\n body()\n return true\n },\n }\n }\n\n return {\n run,\n current: () => model,\n lastRun: () => lastRun,\n replayContext,\n dispose: () => slicer?.cancel(),\n }\n}\n"],"mappings":"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","names":["ctx"]}
1
+ {"version":3,"sources":["../../src/pipeline/runner.ts"],"sourcesContent":["import { getValue } from '../column/get-value'\nimport { keepDiagnostics } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport { SLICED, sliceTimer } from '../diagnostics/trace-store'\nimport type { Emit, Trigger } from '../diagnostics/types'\nimport { featureDiagnostics } from '../feature/codes'\nimport type { FeatureRuntime } from '../feature/runtime'\nimport type { AnyFeature, RowModelContext } from '../feature/types'\nimport { matchCellIssues } from '../ingest/cell-issues'\nimport { type KeyOf, resolveRowKeys } from '../ingest/row-key'\nimport { CellFailures } from '../intercept/cell-batch'\nimport { errorName } from '../intercept/classify'\nimport { type ContextBase, createContext } from '../intercept/context'\nimport { FALLBACK } from '../intercept/fallbacks'\nimport type { InterceptorRuntime } from '../intercept/runtime'\nimport type { TableState } from '../table/types'\nimport type { ColumnCache, SlicedFormatting } from './column-cache'\nimport { type ResolvedColumn, type ResolvedColumns, resolveColumns } from './columns'\nimport { checkStep, indexPrint, stepDiagnostics } from './dev-checks'\nimport { allRows } from './indices'\nimport { lazyRows, Row, type RowIssue, type RowSource } from './row'\nimport type { Slicer } from './slice'\nimport { inStepDiagnosticSetsError } from './status-rule'\nimport type { RowModel, RowModelStatus } from './types'\n\nkeepDiagnostics(featureDiagnostics, stepDiagnostics)\n\nconst EMPTY: readonly never[] = []\nconst NO_EMIT = (() => undefined) as Emit\n\n/** What `createTable` gives the runner. */\nexport interface PipelineHost {\n readonly runtime: InterceptorRuntime\n /**\n * What the features brought (`runtimeFor`): the column cache and time-slicing of their steps.\n * Always set when a feature has a `rowModel`; a table without features runs no step.\n */\n readonly featureRuntime?: FeatureRuntime | undefined\n readonly emit: Emit\n /** Installed features in pipeline (stage) order. */\n readonly features: readonly AnyFeature[]\n /** `options.features` in the listed order: `where` = `features[<listed index>].rowModel`. */\n readonly listed: readonly AnyFeature[]\n base(): ContextBase\n /** Starts a pipeline run: increments and returns the run id. */\n nextRun(): number\n getData(): readonly unknown[]\n getState(): TableState\n getColumns(): readonly unknown[] | undefined\n getRowKey(): unknown\n /** `RowModel.isInitialLoad`: no data applied yet (§6.6). */\n isInitialLoad(): boolean\n /**\n * The table's status outside the pipeline (`'validating'`, `'error'` after a failed ingest, …);\n * a step failing in this run makes the row model `'error'` regardless.\n */\n status(): RowModelStatus\n /** Schema issues of a flagged row by data index (`invalidRows: 'flag'`); else `undefined`. */\n issues(index: number): readonly RowIssue[] | undefined\n /** `schema` + `invalidRows: 'flag'` (read once): steps get `RowModelContext.flagged`. */\n readonly flagMode?: boolean\n /**\n * Time-sliced work (§9.1, `RowModelContext.slice`) ended: recompute the row model and notify,\n * under the trigger of the run that started it. Without it nothing is sliced.\n */\n refresh?(trigger: Trigger): void\n}\n\nexport interface Pipeline<T> {\n /** Runs `pipeline:run` and returns the row model (the previous object when nothing changed). */\n run(): RowModel<T>\n /** The last row model, if the pipeline ran. */\n current(): RowModel<T> | undefined\n /** The last run (`explain`, §8.4); `undefined` before the first. */\n lastRun(): RunRecord | undefined\n /**\n * A `rowModel` context over the current data and columns for replaying a step on chosen rows\n * (`explainRow`, §8.4): diagnostics are dropped and `batch` runs its body directly (no\n * interceptors), so a replay reports nothing and changes nothing.\n */\n replayContext(name: string): RowModelContext\n /**\n * `destroy()`: cancels time-sliced work in progress and releases the column cache, the step memo\n * and the row keys (#98). {@link current} stays readable.\n */\n dispose(): void\n /** Development only, for tests (#98): what the runner still holds. */\n probe?(): { memo: number; keys: boolean; last: boolean; cached: boolean }\n}\n\n/**\n * One step of the last run (`explain` / `explainRow`, §8.4): references to the index arrays the\n * step memo holds anyway, never copies. `cached`: served from the memo; `failed`: the step threw or\n * returned a bad output and passed its input through.\n */\nexport interface RunRecord {\n readonly run: number\n readonly trigger: Trigger\n /** The client steps that ran, in order (fewer when `pipeline:run` itself failed). */\n readonly steps: readonly StepRecord[]\n}\n\nexport interface StepRecord {\n readonly feature: AnyFeature\n readonly input: Uint32Array\n readonly output: Uint32Array\n readonly cached: boolean\n readonly failed: boolean\n}\n\ninterface StepMemo {\n input: Uint32Array\n state: unknown\n columns: readonly unknown[]\n output: Uint32Array\n}\n\ninterface Built<T> {\n model: RowModel<T>\n data: readonly unknown[]\n indices: Uint32Array\n columns: readonly unknown[]\n rowKey: unknown\n}\n\n/**\n * The index-based pipeline (§3.3, §9.1): each step consumes and produces a `Uint32Array` of row\n * indices, is memoised on (input reference, own slice, columns), and `Row` objects are created only\n * for the final (visible) indices, each when it is first read.\n */\nexport function createPipeline<T>(host: PipelineHost): Pipeline<T> {\n /**\n * In-step diagnostics the §6.6 status rule counts (`inStepDiagnosticSetsError`), ever reported:\n * a step whose run moved it makes the row model `'error'` and is not memoised.\n */\n const flags = { count: 0 }\n /** `emit` for steps and the column cache: counts through the status rule. */\n const stepEmit = ((code, details, options) => {\n if (inStepDiagnosticSetsError(code)) flags.count++\n host.emit(code, details, options)\n }) as Emit\n const rt = host.featureRuntime\n // Only steps (and explainRow's replay of them) read the cache: they exist only with a runtime.\n const cache = rt?.createColumnCache({\n runtime: host.runtime,\n emit: stepEmit,\n base: () => host.base(),\n flags,\n }) as ColumnCache\n // A server-mode feature (§7.1) only holds state: the server ran its step.\n const steps = host.features.filter(\n (f) => f.stage !== 'none' && f.mode !== 'server' && typeof f.rowModel === 'function',\n )\n const where = new Map(steps.map((f) => [f, `features[${host.listed.indexOf(f)}].rowModel`]))\n const memo = new Map<AnyFeature, StepMemo>()\n const sources = new WeakMap<ResolvedColumns, RowSource>()\n const keyFailures = new CellFailures()\n /** The first `rowKey` error of the current build (its `cause`). */\n let keyError: unknown\n const keyFailed = (index: number, e: unknown) => {\n if (keyFailures.count === 0) keyError = e\n keyFailures.add(index, e)\n }\n let last: Built<T> | undefined\n /** Row keys resolved over all rows (§5.2), per (data, rowKey) reference. */\n let keys: { data: readonly unknown[]; rowKey: unknown; keyOf: KeyOf } | undefined\n let model: RowModel<T> | undefined\n /** The last run (replaced per run; a few references per step). */\n let lastRun: RunRecord | undefined\n /** Steps of the current run waiting on time-sliced work (§9.1): the row model is 'pending'. */\n let waiting = 0\n const refresh = host.refresh\n const slicer: Slicer | undefined = rt?.createSlicer({\n emit: stepEmit,\n // Not during SSR, and not for the first row model (the hydrated client matches the server).\n enabled: () => refresh !== undefined && last !== undefined && host.base().phase === 'client',\n trigger: () => host.base().trigger,\n done: (trigger) => refresh?.(trigger),\n timed: (feature, ms) => sliceTimer.current?.(host.base(), feature, ms),\n })\n\n /** `Row.getValue` failures: one emit per failing cell, built only when a cell fails. */\n function reportCell(col: ResolvedColumn, index: number, e: unknown, field: string) {\n const name = errorName(e)\n host.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: `columns[${col.index}].${field}`,\n column: col.id,\n rows: [index],\n count: 1,\n fallback: 'cell-undefined',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n }\n // A key-path read error, captured by a closure made once (Row.getValue is per cell: no\n // allocation per call).\n let pathFailed = false\n let pathError: unknown\n const onPathError = (e: unknown) => {\n pathFailed = true\n pathError = e\n }\n\n function rowSource(cols: ResolvedColumns): RowSource {\n let s = sources.get(cols)\n if (s) return s\n s = {\n value(index, original, id) {\n const col = cols.byId.get(id)\n if (!col) return undefined\n if (col.path) {\n const v = getValue(original, col.path, onPathError)\n if (pathFailed) {\n const e = pathError\n pathFailed = false\n pathError = undefined\n reportCell(col, index, e, 'key')\n }\n return v\n }\n if (!col.accessor) return undefined\n try {\n return col.accessor(original)\n } catch (e) {\n reportCell(col, index, e, 'accessor')\n return undefined\n }\n },\n issues: (index) => host.issues(index),\n cellIssues(issues, id) {\n const col = cols.byId.get(id)\n return col ? matchCellIssues(issues, col.path) : EMPTY\n },\n }\n sources.set(cols, s)\n return s\n }\n\n function reportKeyFailures() {\n if (keyFailures.count === 0) return\n const name = errorName(keyError)\n host.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: 'rowKey',\n rows: Array.from(keyFailures.sample()),\n count: keyFailures.count,\n fallback: 'row-key-index',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: keyError },\n )\n keyFailures.reset()\n keyError = undefined\n }\n\n function build(\n data: readonly unknown[],\n indices: Uint32Array,\n columns: readonly unknown[],\n filteredCount: number,\n status: RowModelStatus,\n ): RowModel<T> {\n const rowKey = host.getRowKey()\n const isInitialLoad = host.isInitialLoad()\n const prev = last\n if (\n prev &&\n prev.indices === indices &&\n prev.data === data &&\n prev.columns === columns &&\n prev.rowKey === rowKey &&\n prev.model.status === status &&\n prev.model.isInitialLoad === isInitialLoad\n ) {\n return prev.model\n }\n const source = rowSource(resolveColumns(columns))\n keyFailures.reset()\n if (keys?.data !== data || keys.rowKey !== rowKey) {\n keys = { data, rowKey, keyOf: resolveRowKeys(data, rowKey, host.emit, keyFailed) }\n }\n const keyOf = keys.keyOf\n reportKeyFailures()\n // A data array whose rows cannot be read fails this run (the last good row model is kept),\n // not a later read of `rows[i]`.\n for (let i = 0; i < indices.length; i++) void data[indices[i] as number]\n // Rows are built when read (§9.3: no Row per visible row up front). The key scan above read\n // every key; one that throws only now is reported now.\n const rows = lazyRows(indices.length, (i) => {\n const r = indices[i] as number\n const original = data[r] as T\n const row = new Row<T>(source, r, keyOf(original, r), original)\n reportKeyFailures()\n return row\n })\n const m: RowModel<T> = { rows, filteredCount, totalCount: data.length, status, isInitialLoad }\n last = { model: m, data, indices, columns, rowKey }\n return m\n }\n\n function run(): RowModel<T> {\n host.nextRun()\n const data = host.getData()\n const columns = host.getColumns() ?? EMPTY\n const cols = resolveColumns(columns)\n const state = host.getState()\n let failed = false\n let result: RowModel<T> | undefined\n const records: StepRecord[] = []\n const { run: runId, trigger } = host.base()\n lastRun = { run: runId, trigger, steps: records }\n\n const rowModelContext = (name: string): RowModelContext & SlicedFormatting => ({\n name,\n data,\n emit: stepEmit,\n ...(host.flagMode ? { flagged: (i: number) => host.issues(i) } : {}),\n run: host.base().run,\n columns,\n getColumnValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.values(data, col) : undefined\n },\n getFormattedValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.formatted(data, col) : undefined\n },\n *formattedSliced(id) {\n const col = cols.byId.get(id)\n return col ? yield* cache.formattedSliced(data, col) : undefined\n },\n batch: (id, slot, rows, body) => {\n const col = cols.byId.get(id)\n if (col) cache.batch(col, slot, slot, rows, body)\n return col !== undefined\n },\n slice: (key, job) => {\n const r = (slicer as Slicer).run(key, job, name)\n if (r === undefined) waiting++\n return r\n },\n })\n\n function step(f: AnyFeature, input: Uint32Array): Uint32Array {\n const slice = state[f.name]\n const m = memo.get(f)\n if (m && m.input === input && Object.is(m.state, slice) && m.columns === columns) {\n records.push({ feature: f, input, output: m.output, cached: true, failed: false })\n return m.output\n }\n let ok = false\n const flagged = flags.count\n const waited = waiting\n const ctx = createContext(\n 'pipeline:step',\n { stage: f.stage, feature: f.name, indices: input },\n where.get(f) as string,\n host.base(),\n )\n const output = host.runtime.run('pipeline:step', ctx, () => {\n let out: unknown\n // Dev check (§3.4 devChecks): a bounded fingerprint of the input before rowModel runs.\n const before = (process.env.NODE_ENV !== \"production\") ? indexPrint(input) : 0\n try {\n out = (f.rowModel as NonNullable<AnyFeature['rowModel']>)(\n input,\n slice,\n rowModelContext(f.name),\n )\n } catch (e) {\n const name = errorName(e)\n host.emit(\n 'DK_FEATURE_FAILED',\n {\n feature: f.name,\n hook: 'rowModel',\n fallback: 'step-passthrough',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n return input\n }\n // The tracer adds the time of this sliced work to the step (#61).\n if (waiting > waited) ctx.meta.set(SLICED, true)\n // Dev: a mutated input warns; a bad output passes the input through, not memoised.\n if ((process.env.NODE_ENV !== \"production\") && !checkStep(stepEmit, f.name, input, before, out, data.length)) return input\n ok = true\n return out instanceof Uint32Array ? out : input\n })\n // A counted in-step diagnostic (status rule): 'error' with the step's output, re-run next time.\n // A step waiting on sliced work returned a stand-in: re-run next time too.\n if (ok && flags.count === flagged) {\n if (waiting === waited) memo.set(f, { input, state: slice, columns, output })\n else memo.delete(f)\n } else {\n failed = true\n memo.delete(f)\n }\n records.push({ feature: f, input, output, cached: false, failed: !ok })\n return output\n }\n\n const ctx = createContext('pipeline:run', { rowCount: data.length }, 'features', host.base())\n // The last good row model (§3.4): its indices; the runner keeps the matching rows below.\n if (last) ctx.meta.set(FALLBACK, last.indices)\n waiting = 0\n slicer?.begin()\n try {\n void host.runtime.run('pipeline:run', ctx, () => {\n let indices = allRows(data)\n let filteredCount = -1\n for (const f of steps) {\n if (f.stage === 'paginate' && filteredCount < 0) filteredCount = indices.length\n indices = step(f, indices)\n }\n if (filteredCount < 0) filteredCount = indices.length\n // Sliced work in progress is 'pending', below every other status (§6.6 precedence).\n const outside = host.status()\n const status = failed ? 'error' : waiting > 0 && outside === 'idle' ? 'pending' : outside\n result = build(data, indices, columns, filteredCount, status)\n return indices\n })\n } finally {\n // Sliced work no step asked for in this run is stale: cancelled.\n slicer?.end()\n if (result) model = result\n else {\n // pipeline:run failed: the boundary reported it, or a strict throw is leaving the run\n // (#43). Either way the last good rows with status 'error', never an empty 'idle' model.\n const isInitialLoad = host.isInitialLoad()\n model = last\n ? { ...last.model, status: 'error', isInitialLoad }\n : { rows: EMPTY, filteredCount: 0, totalCount: 0, status: 'error', isInitialLoad }\n }\n }\n return model\n }\n\n function replayContext(name: string): RowModelContext {\n const data = host.getData()\n const columns = host.getColumns() ?? EMPTY\n const cols = resolveColumns(columns)\n return {\n name,\n data,\n emit: NO_EMIT,\n ...(host.flagMode ? { flagged: (i: number) => host.issues(i) } : {}),\n run: host.base().run,\n columns,\n getColumnValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.values(data, col) : undefined\n },\n getFormattedValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.formatted(data, col) : undefined\n },\n batch: (id, _slot, _rows, body) => {\n if (!cols.byId.has(id)) return false\n body()\n return true\n },\n }\n }\n\n return {\n run,\n current: () => model,\n lastRun: () => lastRun,\n replayContext,\n dispose: () => {\n slicer?.cancel()\n cache?.release()\n memo.clear()\n keys = undefined\n last = undefined\n },\n ...((process.env.NODE_ENV !== \"production\")\n ? {\n probe: () => ({\n memo: memo.size,\n keys: keys !== undefined,\n last: last !== undefined,\n cached: cache?.holds?.(host.getData()) === true,\n }),\n }\n : {}),\n }\n}\n"],"mappings":"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","names":["ctx"]}
@@ -309,7 +309,21 @@ function createPipeline(host) {
309
309
  current: () => model,
310
310
  lastRun: () => lastRun,
311
311
  replayContext,
312
- dispose: () => slicer?.cancel()
312
+ dispose: () => {
313
+ slicer?.cancel();
314
+ cache?.release();
315
+ memo.clear();
316
+ keys = void 0;
317
+ last = void 0;
318
+ },
319
+ ...process.env.NODE_ENV !== "production" ? {
320
+ probe: () => ({
321
+ memo: memo.size,
322
+ keys: keys !== void 0,
323
+ last: last !== void 0,
324
+ cached: cache?.holds?.(host.getData()) === true
325
+ })
326
+ } : {}
313
327
  };
314
328
  }
315
329
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/pipeline/runner.ts"],"sourcesContent":["import { getValue } from '../column/get-value'\nimport { keepDiagnostics } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport { SLICED, sliceTimer } from '../diagnostics/trace-store'\nimport type { Emit, Trigger } from '../diagnostics/types'\nimport { featureDiagnostics } from '../feature/codes'\nimport type { FeatureRuntime } from '../feature/runtime'\nimport type { AnyFeature, RowModelContext } from '../feature/types'\nimport { matchCellIssues } from '../ingest/cell-issues'\nimport { type KeyOf, resolveRowKeys } from '../ingest/row-key'\nimport { CellFailures } from '../intercept/cell-batch'\nimport { errorName } from '../intercept/classify'\nimport { type ContextBase, createContext } from '../intercept/context'\nimport { FALLBACK } from '../intercept/fallbacks'\nimport type { InterceptorRuntime } from '../intercept/runtime'\nimport type { TableState } from '../table/types'\nimport type { ColumnCache, SlicedFormatting } from './column-cache'\nimport { type ResolvedColumn, type ResolvedColumns, resolveColumns } from './columns'\nimport { checkStep, indexPrint, stepDiagnostics } from './dev-checks'\nimport { allRows } from './indices'\nimport { lazyRows, Row, type RowIssue, type RowSource } from './row'\nimport type { Slicer } from './slice'\nimport { inStepDiagnosticSetsError } from './status-rule'\nimport type { RowModel, RowModelStatus } from './types'\n\nkeepDiagnostics(featureDiagnostics, stepDiagnostics)\n\nconst EMPTY: readonly never[] = []\nconst NO_EMIT = (() => undefined) as Emit\n\n/** What `createTable` gives the runner. */\nexport interface PipelineHost {\n readonly runtime: InterceptorRuntime\n /**\n * What the features brought (`runtimeFor`): the column cache and time-slicing of their steps.\n * Always set when a feature has a `rowModel`; a table without features runs no step.\n */\n readonly featureRuntime?: FeatureRuntime | undefined\n readonly emit: Emit\n /** Installed features in pipeline (stage) order. */\n readonly features: readonly AnyFeature[]\n /** `options.features` in the listed order: `where` = `features[<listed index>].rowModel`. */\n readonly listed: readonly AnyFeature[]\n base(): ContextBase\n /** Starts a pipeline run: increments and returns the run id. */\n nextRun(): number\n getData(): readonly unknown[]\n getState(): TableState\n getColumns(): readonly unknown[] | undefined\n getRowKey(): unknown\n /** `RowModel.isInitialLoad`: no data applied yet (§6.6). */\n isInitialLoad(): boolean\n /**\n * The table's status outside the pipeline (`'validating'`, `'error'` after a failed ingest, …);\n * a step failing in this run makes the row model `'error'` regardless.\n */\n status(): RowModelStatus\n /** Schema issues of a flagged row by data index (`invalidRows: 'flag'`); else `undefined`. */\n issues(index: number): readonly RowIssue[] | undefined\n /** `schema` + `invalidRows: 'flag'` (read once): steps get `RowModelContext.flagged`. */\n readonly flagMode?: boolean\n /**\n * Time-sliced work (§9.1, `RowModelContext.slice`) ended: recompute the row model and notify,\n * under the trigger of the run that started it. Without it nothing is sliced.\n */\n refresh?(trigger: Trigger): void\n}\n\nexport interface Pipeline<T> {\n /** Runs `pipeline:run` and returns the row model (the previous object when nothing changed). */\n run(): RowModel<T>\n /** The last row model, if the pipeline ran. */\n current(): RowModel<T> | undefined\n /** The last run (`explain`, §8.4); `undefined` before the first. */\n lastRun(): RunRecord | undefined\n /**\n * A `rowModel` context over the current data and columns for replaying a step on chosen rows\n * (`explainRow`, §8.4): diagnostics are dropped and `batch` runs its body directly (no\n * interceptors), so a replay reports nothing and changes nothing.\n */\n replayContext(name: string): RowModelContext\n /** Cancels time-sliced work in progress (`destroy()`). */\n dispose(): void\n}\n\n/**\n * One step of the last run (`explain` / `explainRow`, §8.4): references to the index arrays the\n * step memo holds anyway, never copies. `cached`: served from the memo; `failed`: the step threw or\n * returned a bad output and passed its input through.\n */\nexport interface RunRecord {\n readonly run: number\n readonly trigger: Trigger\n /** The client steps that ran, in order (fewer when `pipeline:run` itself failed). */\n readonly steps: readonly StepRecord[]\n}\n\nexport interface StepRecord {\n readonly feature: AnyFeature\n readonly input: Uint32Array\n readonly output: Uint32Array\n readonly cached: boolean\n readonly failed: boolean\n}\n\ninterface StepMemo {\n input: Uint32Array\n state: unknown\n columns: readonly unknown[]\n output: Uint32Array\n}\n\ninterface Built<T> {\n model: RowModel<T>\n data: readonly unknown[]\n indices: Uint32Array\n columns: readonly unknown[]\n rowKey: unknown\n}\n\n/**\n * The index-based pipeline (§3.3, §9.1): each step consumes and produces a `Uint32Array` of row\n * indices, is memoised on (input reference, own slice, columns), and `Row` objects are created only\n * for the final (visible) indices, each when it is first read.\n */\nexport function createPipeline<T>(host: PipelineHost): Pipeline<T> {\n /**\n * In-step diagnostics the §6.6 status rule counts (`inStepDiagnosticSetsError`), ever reported:\n * a step whose run moved it makes the row model `'error'` and is not memoised.\n */\n const flags = { count: 0 }\n /** `emit` for steps and the column cache: counts through the status rule. */\n const stepEmit = ((code, details, options) => {\n if (inStepDiagnosticSetsError(code)) flags.count++\n host.emit(code, details, options)\n }) as Emit\n const rt = host.featureRuntime\n // Only steps (and explainRow's replay of them) read the cache: they exist only with a runtime.\n const cache = rt?.createColumnCache({\n runtime: host.runtime,\n emit: stepEmit,\n base: () => host.base(),\n flags,\n }) as ColumnCache\n // A server-mode feature (§7.1) only holds state: the server ran its step.\n const steps = host.features.filter(\n (f) => f.stage !== 'none' && f.mode !== 'server' && typeof f.rowModel === 'function',\n )\n const where = new Map(steps.map((f) => [f, `features[${host.listed.indexOf(f)}].rowModel`]))\n const memo = new Map<AnyFeature, StepMemo>()\n const sources = new WeakMap<ResolvedColumns, RowSource>()\n const keyFailures = new CellFailures()\n /** The first `rowKey` error of the current build (its `cause`). */\n let keyError: unknown\n const keyFailed = (index: number, e: unknown) => {\n if (keyFailures.count === 0) keyError = e\n keyFailures.add(index, e)\n }\n let last: Built<T> | undefined\n /** Row keys resolved over all rows (§5.2), per (data, rowKey) reference. */\n let keys: { data: readonly unknown[]; rowKey: unknown; keyOf: KeyOf } | undefined\n let model: RowModel<T> | undefined\n /** The last run (replaced per run; a few references per step). */\n let lastRun: RunRecord | undefined\n /** Steps of the current run waiting on time-sliced work (§9.1): the row model is 'pending'. */\n let waiting = 0\n const refresh = host.refresh\n const slicer: Slicer | undefined = rt?.createSlicer({\n emit: stepEmit,\n // Not during SSR, and not for the first row model (the hydrated client matches the server).\n enabled: () => refresh !== undefined && last !== undefined && host.base().phase === 'client',\n trigger: () => host.base().trigger,\n done: (trigger) => refresh?.(trigger),\n timed: (feature, ms) => sliceTimer.current?.(host.base(), feature, ms),\n })\n\n /** `Row.getValue` failures: one emit per failing cell, built only when a cell fails. */\n function reportCell(col: ResolvedColumn, index: number, e: unknown, field: string) {\n const name = errorName(e)\n host.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: `columns[${col.index}].${field}`,\n column: col.id,\n rows: [index],\n count: 1,\n fallback: 'cell-undefined',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n }\n // A key-path read error, captured by a closure made once (Row.getValue is per cell: no\n // allocation per call).\n let pathFailed = false\n let pathError: unknown\n const onPathError = (e: unknown) => {\n pathFailed = true\n pathError = e\n }\n\n function rowSource(cols: ResolvedColumns): RowSource {\n let s = sources.get(cols)\n if (s) return s\n s = {\n value(index, original, id) {\n const col = cols.byId.get(id)\n if (!col) return undefined\n if (col.path) {\n const v = getValue(original, col.path, onPathError)\n if (pathFailed) {\n const e = pathError\n pathFailed = false\n pathError = undefined\n reportCell(col, index, e, 'key')\n }\n return v\n }\n if (!col.accessor) return undefined\n try {\n return col.accessor(original)\n } catch (e) {\n reportCell(col, index, e, 'accessor')\n return undefined\n }\n },\n issues: (index) => host.issues(index),\n cellIssues(issues, id) {\n const col = cols.byId.get(id)\n return col ? matchCellIssues(issues, col.path) : EMPTY\n },\n }\n sources.set(cols, s)\n return s\n }\n\n function reportKeyFailures() {\n if (keyFailures.count === 0) return\n const name = errorName(keyError)\n host.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: 'rowKey',\n rows: Array.from(keyFailures.sample()),\n count: keyFailures.count,\n fallback: 'row-key-index',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: keyError },\n )\n keyFailures.reset()\n keyError = undefined\n }\n\n function build(\n data: readonly unknown[],\n indices: Uint32Array,\n columns: readonly unknown[],\n filteredCount: number,\n status: RowModelStatus,\n ): RowModel<T> {\n const rowKey = host.getRowKey()\n const isInitialLoad = host.isInitialLoad()\n const prev = last\n if (\n prev &&\n prev.indices === indices &&\n prev.data === data &&\n prev.columns === columns &&\n prev.rowKey === rowKey &&\n prev.model.status === status &&\n prev.model.isInitialLoad === isInitialLoad\n ) {\n return prev.model\n }\n const source = rowSource(resolveColumns(columns))\n keyFailures.reset()\n if (keys?.data !== data || keys.rowKey !== rowKey) {\n keys = { data, rowKey, keyOf: resolveRowKeys(data, rowKey, host.emit, keyFailed) }\n }\n const keyOf = keys.keyOf\n reportKeyFailures()\n // A data array whose rows cannot be read fails this run (the last good row model is kept),\n // not a later read of `rows[i]`.\n for (let i = 0; i < indices.length; i++) void data[indices[i] as number]\n // Rows are built when read (§9.3: no Row per visible row up front). The key scan above read\n // every key; one that throws only now is reported now.\n const rows = lazyRows(indices.length, (i) => {\n const r = indices[i] as number\n const original = data[r] as T\n const row = new Row<T>(source, r, keyOf(original, r), original)\n reportKeyFailures()\n return row\n })\n const m: RowModel<T> = { rows, filteredCount, totalCount: data.length, status, isInitialLoad }\n last = { model: m, data, indices, columns, rowKey }\n return m\n }\n\n function run(): RowModel<T> {\n host.nextRun()\n const data = host.getData()\n const columns = host.getColumns() ?? EMPTY\n const cols = resolveColumns(columns)\n const state = host.getState()\n let failed = false\n let result: RowModel<T> | undefined\n const records: StepRecord[] = []\n const { run: runId, trigger } = host.base()\n lastRun = { run: runId, trigger, steps: records }\n\n const rowModelContext = (name: string): RowModelContext & SlicedFormatting => ({\n name,\n data,\n emit: stepEmit,\n ...(host.flagMode ? { flagged: (i: number) => host.issues(i) } : {}),\n run: host.base().run,\n columns,\n getColumnValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.values(data, col) : undefined\n },\n getFormattedValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.formatted(data, col) : undefined\n },\n *formattedSliced(id) {\n const col = cols.byId.get(id)\n return col ? yield* cache.formattedSliced(data, col) : undefined\n },\n batch: (id, slot, rows, body) => {\n const col = cols.byId.get(id)\n if (col) cache.batch(col, slot, slot, rows, body)\n return col !== undefined\n },\n slice: (key, job) => {\n const r = (slicer as Slicer).run(key, job, name)\n if (r === undefined) waiting++\n return r\n },\n })\n\n function step(f: AnyFeature, input: Uint32Array): Uint32Array {\n const slice = state[f.name]\n const m = memo.get(f)\n if (m && m.input === input && Object.is(m.state, slice) && m.columns === columns) {\n records.push({ feature: f, input, output: m.output, cached: true, failed: false })\n return m.output\n }\n let ok = false\n const flagged = flags.count\n const waited = waiting\n const ctx = createContext(\n 'pipeline:step',\n { stage: f.stage, feature: f.name, indices: input },\n where.get(f) as string,\n host.base(),\n )\n const output = host.runtime.run('pipeline:step', ctx, () => {\n let out: unknown\n // Dev check (§3.4 devChecks): a bounded fingerprint of the input before rowModel runs.\n const before = (process.env.NODE_ENV !== \"production\") ? indexPrint(input) : 0\n try {\n out = (f.rowModel as NonNullable<AnyFeature['rowModel']>)(\n input,\n slice,\n rowModelContext(f.name),\n )\n } catch (e) {\n const name = errorName(e)\n host.emit(\n 'DK_FEATURE_FAILED',\n {\n feature: f.name,\n hook: 'rowModel',\n fallback: 'step-passthrough',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n return input\n }\n // The tracer adds the time of this sliced work to the step (#61).\n if (waiting > waited) ctx.meta.set(SLICED, true)\n // Dev: a mutated input warns; a bad output passes the input through, not memoised.\n if ((process.env.NODE_ENV !== \"production\") && !checkStep(stepEmit, f.name, input, before, out, data.length)) return input\n ok = true\n return out instanceof Uint32Array ? out : input\n })\n // A counted in-step diagnostic (status rule): 'error' with the step's output, re-run next time.\n // A step waiting on sliced work returned a stand-in: re-run next time too.\n if (ok && flags.count === flagged) {\n if (waiting === waited) memo.set(f, { input, state: slice, columns, output })\n else memo.delete(f)\n } else {\n failed = true\n memo.delete(f)\n }\n records.push({ feature: f, input, output, cached: false, failed: !ok })\n return output\n }\n\n const ctx = createContext('pipeline:run', { rowCount: data.length }, 'features', host.base())\n // The last good row model (§3.4): its indices; the runner keeps the matching rows below.\n if (last) ctx.meta.set(FALLBACK, last.indices)\n waiting = 0\n slicer?.begin()\n try {\n void host.runtime.run('pipeline:run', ctx, () => {\n let indices = allRows(data)\n let filteredCount = -1\n for (const f of steps) {\n if (f.stage === 'paginate' && filteredCount < 0) filteredCount = indices.length\n indices = step(f, indices)\n }\n if (filteredCount < 0) filteredCount = indices.length\n // Sliced work in progress is 'pending', below every other status (§6.6 precedence).\n const outside = host.status()\n const status = failed ? 'error' : waiting > 0 && outside === 'idle' ? 'pending' : outside\n result = build(data, indices, columns, filteredCount, status)\n return indices\n })\n } finally {\n // Sliced work no step asked for in this run is stale: cancelled.\n slicer?.end()\n if (result) model = result\n else {\n // pipeline:run failed: the boundary reported it, or a strict throw is leaving the run\n // (#43). Either way the last good rows with status 'error', never an empty 'idle' model.\n const isInitialLoad = host.isInitialLoad()\n model = last\n ? { ...last.model, status: 'error', isInitialLoad }\n : { rows: EMPTY, filteredCount: 0, totalCount: 0, status: 'error', isInitialLoad }\n }\n }\n return model\n }\n\n function replayContext(name: string): RowModelContext {\n const data = host.getData()\n const columns = host.getColumns() ?? EMPTY\n const cols = resolveColumns(columns)\n return {\n name,\n data,\n emit: NO_EMIT,\n ...(host.flagMode ? { flagged: (i: number) => host.issues(i) } : {}),\n run: host.base().run,\n columns,\n getColumnValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.values(data, col) : undefined\n },\n getFormattedValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.formatted(data, col) : undefined\n },\n batch: (id, _slot, _rows, body) => {\n if (!cols.byId.has(id)) return false\n body()\n return true\n },\n }\n }\n\n return {\n run,\n current: () => model,\n lastRun: () => lastRun,\n replayContext,\n dispose: () => slicer?.cancel(),\n }\n}\n"],"mappings":"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","names":["ctx"]}
1
+ {"version":3,"sources":["../../src/pipeline/runner.ts"],"sourcesContent":["import { getValue } from '../column/get-value'\nimport { keepDiagnostics } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport { SLICED, sliceTimer } from '../diagnostics/trace-store'\nimport type { Emit, Trigger } from '../diagnostics/types'\nimport { featureDiagnostics } from '../feature/codes'\nimport type { FeatureRuntime } from '../feature/runtime'\nimport type { AnyFeature, RowModelContext } from '../feature/types'\nimport { matchCellIssues } from '../ingest/cell-issues'\nimport { type KeyOf, resolveRowKeys } from '../ingest/row-key'\nimport { CellFailures } from '../intercept/cell-batch'\nimport { errorName } from '../intercept/classify'\nimport { type ContextBase, createContext } from '../intercept/context'\nimport { FALLBACK } from '../intercept/fallbacks'\nimport type { InterceptorRuntime } from '../intercept/runtime'\nimport type { TableState } from '../table/types'\nimport type { ColumnCache, SlicedFormatting } from './column-cache'\nimport { type ResolvedColumn, type ResolvedColumns, resolveColumns } from './columns'\nimport { checkStep, indexPrint, stepDiagnostics } from './dev-checks'\nimport { allRows } from './indices'\nimport { lazyRows, Row, type RowIssue, type RowSource } from './row'\nimport type { Slicer } from './slice'\nimport { inStepDiagnosticSetsError } from './status-rule'\nimport type { RowModel, RowModelStatus } from './types'\n\nkeepDiagnostics(featureDiagnostics, stepDiagnostics)\n\nconst EMPTY: readonly never[] = []\nconst NO_EMIT = (() => undefined) as Emit\n\n/** What `createTable` gives the runner. */\nexport interface PipelineHost {\n readonly runtime: InterceptorRuntime\n /**\n * What the features brought (`runtimeFor`): the column cache and time-slicing of their steps.\n * Always set when a feature has a `rowModel`; a table without features runs no step.\n */\n readonly featureRuntime?: FeatureRuntime | undefined\n readonly emit: Emit\n /** Installed features in pipeline (stage) order. */\n readonly features: readonly AnyFeature[]\n /** `options.features` in the listed order: `where` = `features[<listed index>].rowModel`. */\n readonly listed: readonly AnyFeature[]\n base(): ContextBase\n /** Starts a pipeline run: increments and returns the run id. */\n nextRun(): number\n getData(): readonly unknown[]\n getState(): TableState\n getColumns(): readonly unknown[] | undefined\n getRowKey(): unknown\n /** `RowModel.isInitialLoad`: no data applied yet (§6.6). */\n isInitialLoad(): boolean\n /**\n * The table's status outside the pipeline (`'validating'`, `'error'` after a failed ingest, …);\n * a step failing in this run makes the row model `'error'` regardless.\n */\n status(): RowModelStatus\n /** Schema issues of a flagged row by data index (`invalidRows: 'flag'`); else `undefined`. */\n issues(index: number): readonly RowIssue[] | undefined\n /** `schema` + `invalidRows: 'flag'` (read once): steps get `RowModelContext.flagged`. */\n readonly flagMode?: boolean\n /**\n * Time-sliced work (§9.1, `RowModelContext.slice`) ended: recompute the row model and notify,\n * under the trigger of the run that started it. Without it nothing is sliced.\n */\n refresh?(trigger: Trigger): void\n}\n\nexport interface Pipeline<T> {\n /** Runs `pipeline:run` and returns the row model (the previous object when nothing changed). */\n run(): RowModel<T>\n /** The last row model, if the pipeline ran. */\n current(): RowModel<T> | undefined\n /** The last run (`explain`, §8.4); `undefined` before the first. */\n lastRun(): RunRecord | undefined\n /**\n * A `rowModel` context over the current data and columns for replaying a step on chosen rows\n * (`explainRow`, §8.4): diagnostics are dropped and `batch` runs its body directly (no\n * interceptors), so a replay reports nothing and changes nothing.\n */\n replayContext(name: string): RowModelContext\n /**\n * `destroy()`: cancels time-sliced work in progress and releases the column cache, the step memo\n * and the row keys (#98). {@link current} stays readable.\n */\n dispose(): void\n /** Development only, for tests (#98): what the runner still holds. */\n probe?(): { memo: number; keys: boolean; last: boolean; cached: boolean }\n}\n\n/**\n * One step of the last run (`explain` / `explainRow`, §8.4): references to the index arrays the\n * step memo holds anyway, never copies. `cached`: served from the memo; `failed`: the step threw or\n * returned a bad output and passed its input through.\n */\nexport interface RunRecord {\n readonly run: number\n readonly trigger: Trigger\n /** The client steps that ran, in order (fewer when `pipeline:run` itself failed). */\n readonly steps: readonly StepRecord[]\n}\n\nexport interface StepRecord {\n readonly feature: AnyFeature\n readonly input: Uint32Array\n readonly output: Uint32Array\n readonly cached: boolean\n readonly failed: boolean\n}\n\ninterface StepMemo {\n input: Uint32Array\n state: unknown\n columns: readonly unknown[]\n output: Uint32Array\n}\n\ninterface Built<T> {\n model: RowModel<T>\n data: readonly unknown[]\n indices: Uint32Array\n columns: readonly unknown[]\n rowKey: unknown\n}\n\n/**\n * The index-based pipeline (§3.3, §9.1): each step consumes and produces a `Uint32Array` of row\n * indices, is memoised on (input reference, own slice, columns), and `Row` objects are created only\n * for the final (visible) indices, each when it is first read.\n */\nexport function createPipeline<T>(host: PipelineHost): Pipeline<T> {\n /**\n * In-step diagnostics the §6.6 status rule counts (`inStepDiagnosticSetsError`), ever reported:\n * a step whose run moved it makes the row model `'error'` and is not memoised.\n */\n const flags = { count: 0 }\n /** `emit` for steps and the column cache: counts through the status rule. */\n const stepEmit = ((code, details, options) => {\n if (inStepDiagnosticSetsError(code)) flags.count++\n host.emit(code, details, options)\n }) as Emit\n const rt = host.featureRuntime\n // Only steps (and explainRow's replay of them) read the cache: they exist only with a runtime.\n const cache = rt?.createColumnCache({\n runtime: host.runtime,\n emit: stepEmit,\n base: () => host.base(),\n flags,\n }) as ColumnCache\n // A server-mode feature (§7.1) only holds state: the server ran its step.\n const steps = host.features.filter(\n (f) => f.stage !== 'none' && f.mode !== 'server' && typeof f.rowModel === 'function',\n )\n const where = new Map(steps.map((f) => [f, `features[${host.listed.indexOf(f)}].rowModel`]))\n const memo = new Map<AnyFeature, StepMemo>()\n const sources = new WeakMap<ResolvedColumns, RowSource>()\n const keyFailures = new CellFailures()\n /** The first `rowKey` error of the current build (its `cause`). */\n let keyError: unknown\n const keyFailed = (index: number, e: unknown) => {\n if (keyFailures.count === 0) keyError = e\n keyFailures.add(index, e)\n }\n let last: Built<T> | undefined\n /** Row keys resolved over all rows (§5.2), per (data, rowKey) reference. */\n let keys: { data: readonly unknown[]; rowKey: unknown; keyOf: KeyOf } | undefined\n let model: RowModel<T> | undefined\n /** The last run (replaced per run; a few references per step). */\n let lastRun: RunRecord | undefined\n /** Steps of the current run waiting on time-sliced work (§9.1): the row model is 'pending'. */\n let waiting = 0\n const refresh = host.refresh\n const slicer: Slicer | undefined = rt?.createSlicer({\n emit: stepEmit,\n // Not during SSR, and not for the first row model (the hydrated client matches the server).\n enabled: () => refresh !== undefined && last !== undefined && host.base().phase === 'client',\n trigger: () => host.base().trigger,\n done: (trigger) => refresh?.(trigger),\n timed: (feature, ms) => sliceTimer.current?.(host.base(), feature, ms),\n })\n\n /** `Row.getValue` failures: one emit per failing cell, built only when a cell fails. */\n function reportCell(col: ResolvedColumn, index: number, e: unknown, field: string) {\n const name = errorName(e)\n host.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: `columns[${col.index}].${field}`,\n column: col.id,\n rows: [index],\n count: 1,\n fallback: 'cell-undefined',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n }\n // A key-path read error, captured by a closure made once (Row.getValue is per cell: no\n // allocation per call).\n let pathFailed = false\n let pathError: unknown\n const onPathError = (e: unknown) => {\n pathFailed = true\n pathError = e\n }\n\n function rowSource(cols: ResolvedColumns): RowSource {\n let s = sources.get(cols)\n if (s) return s\n s = {\n value(index, original, id) {\n const col = cols.byId.get(id)\n if (!col) return undefined\n if (col.path) {\n const v = getValue(original, col.path, onPathError)\n if (pathFailed) {\n const e = pathError\n pathFailed = false\n pathError = undefined\n reportCell(col, index, e, 'key')\n }\n return v\n }\n if (!col.accessor) return undefined\n try {\n return col.accessor(original)\n } catch (e) {\n reportCell(col, index, e, 'accessor')\n return undefined\n }\n },\n issues: (index) => host.issues(index),\n cellIssues(issues, id) {\n const col = cols.byId.get(id)\n return col ? matchCellIssues(issues, col.path) : EMPTY\n },\n }\n sources.set(cols, s)\n return s\n }\n\n function reportKeyFailures() {\n if (keyFailures.count === 0) return\n const name = errorName(keyError)\n host.emit(\n 'DK_CALLBACK_FAILED',\n {\n slot: 'rowKey',\n rows: Array.from(keyFailures.sample()),\n count: keyFailures.count,\n fallback: 'row-key-index',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: keyError },\n )\n keyFailures.reset()\n keyError = undefined\n }\n\n function build(\n data: readonly unknown[],\n indices: Uint32Array,\n columns: readonly unknown[],\n filteredCount: number,\n status: RowModelStatus,\n ): RowModel<T> {\n const rowKey = host.getRowKey()\n const isInitialLoad = host.isInitialLoad()\n const prev = last\n if (\n prev &&\n prev.indices === indices &&\n prev.data === data &&\n prev.columns === columns &&\n prev.rowKey === rowKey &&\n prev.model.status === status &&\n prev.model.isInitialLoad === isInitialLoad\n ) {\n return prev.model\n }\n const source = rowSource(resolveColumns(columns))\n keyFailures.reset()\n if (keys?.data !== data || keys.rowKey !== rowKey) {\n keys = { data, rowKey, keyOf: resolveRowKeys(data, rowKey, host.emit, keyFailed) }\n }\n const keyOf = keys.keyOf\n reportKeyFailures()\n // A data array whose rows cannot be read fails this run (the last good row model is kept),\n // not a later read of `rows[i]`.\n for (let i = 0; i < indices.length; i++) void data[indices[i] as number]\n // Rows are built when read (§9.3: no Row per visible row up front). The key scan above read\n // every key; one that throws only now is reported now.\n const rows = lazyRows(indices.length, (i) => {\n const r = indices[i] as number\n const original = data[r] as T\n const row = new Row<T>(source, r, keyOf(original, r), original)\n reportKeyFailures()\n return row\n })\n const m: RowModel<T> = { rows, filteredCount, totalCount: data.length, status, isInitialLoad }\n last = { model: m, data, indices, columns, rowKey }\n return m\n }\n\n function run(): RowModel<T> {\n host.nextRun()\n const data = host.getData()\n const columns = host.getColumns() ?? EMPTY\n const cols = resolveColumns(columns)\n const state = host.getState()\n let failed = false\n let result: RowModel<T> | undefined\n const records: StepRecord[] = []\n const { run: runId, trigger } = host.base()\n lastRun = { run: runId, trigger, steps: records }\n\n const rowModelContext = (name: string): RowModelContext & SlicedFormatting => ({\n name,\n data,\n emit: stepEmit,\n ...(host.flagMode ? { flagged: (i: number) => host.issues(i) } : {}),\n run: host.base().run,\n columns,\n getColumnValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.values(data, col) : undefined\n },\n getFormattedValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.formatted(data, col) : undefined\n },\n *formattedSliced(id) {\n const col = cols.byId.get(id)\n return col ? yield* cache.formattedSliced(data, col) : undefined\n },\n batch: (id, slot, rows, body) => {\n const col = cols.byId.get(id)\n if (col) cache.batch(col, slot, slot, rows, body)\n return col !== undefined\n },\n slice: (key, job) => {\n const r = (slicer as Slicer).run(key, job, name)\n if (r === undefined) waiting++\n return r\n },\n })\n\n function step(f: AnyFeature, input: Uint32Array): Uint32Array {\n const slice = state[f.name]\n const m = memo.get(f)\n if (m && m.input === input && Object.is(m.state, slice) && m.columns === columns) {\n records.push({ feature: f, input, output: m.output, cached: true, failed: false })\n return m.output\n }\n let ok = false\n const flagged = flags.count\n const waited = waiting\n const ctx = createContext(\n 'pipeline:step',\n { stage: f.stage, feature: f.name, indices: input },\n where.get(f) as string,\n host.base(),\n )\n const output = host.runtime.run('pipeline:step', ctx, () => {\n let out: unknown\n // Dev check (§3.4 devChecks): a bounded fingerprint of the input before rowModel runs.\n const before = (process.env.NODE_ENV !== \"production\") ? indexPrint(input) : 0\n try {\n out = (f.rowModel as NonNullable<AnyFeature['rowModel']>)(\n input,\n slice,\n rowModelContext(f.name),\n )\n } catch (e) {\n const name = errorName(e)\n host.emit(\n 'DK_FEATURE_FAILED',\n {\n feature: f.name,\n hook: 'rowModel',\n fallback: 'step-passthrough',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n return input\n }\n // The tracer adds the time of this sliced work to the step (#61).\n if (waiting > waited) ctx.meta.set(SLICED, true)\n // Dev: a mutated input warns; a bad output passes the input through, not memoised.\n if ((process.env.NODE_ENV !== \"production\") && !checkStep(stepEmit, f.name, input, before, out, data.length)) return input\n ok = true\n return out instanceof Uint32Array ? out : input\n })\n // A counted in-step diagnostic (status rule): 'error' with the step's output, re-run next time.\n // A step waiting on sliced work returned a stand-in: re-run next time too.\n if (ok && flags.count === flagged) {\n if (waiting === waited) memo.set(f, { input, state: slice, columns, output })\n else memo.delete(f)\n } else {\n failed = true\n memo.delete(f)\n }\n records.push({ feature: f, input, output, cached: false, failed: !ok })\n return output\n }\n\n const ctx = createContext('pipeline:run', { rowCount: data.length }, 'features', host.base())\n // The last good row model (§3.4): its indices; the runner keeps the matching rows below.\n if (last) ctx.meta.set(FALLBACK, last.indices)\n waiting = 0\n slicer?.begin()\n try {\n void host.runtime.run('pipeline:run', ctx, () => {\n let indices = allRows(data)\n let filteredCount = -1\n for (const f of steps) {\n if (f.stage === 'paginate' && filteredCount < 0) filteredCount = indices.length\n indices = step(f, indices)\n }\n if (filteredCount < 0) filteredCount = indices.length\n // Sliced work in progress is 'pending', below every other status (§6.6 precedence).\n const outside = host.status()\n const status = failed ? 'error' : waiting > 0 && outside === 'idle' ? 'pending' : outside\n result = build(data, indices, columns, filteredCount, status)\n return indices\n })\n } finally {\n // Sliced work no step asked for in this run is stale: cancelled.\n slicer?.end()\n if (result) model = result\n else {\n // pipeline:run failed: the boundary reported it, or a strict throw is leaving the run\n // (#43). Either way the last good rows with status 'error', never an empty 'idle' model.\n const isInitialLoad = host.isInitialLoad()\n model = last\n ? { ...last.model, status: 'error', isInitialLoad }\n : { rows: EMPTY, filteredCount: 0, totalCount: 0, status: 'error', isInitialLoad }\n }\n }\n return model\n }\n\n function replayContext(name: string): RowModelContext {\n const data = host.getData()\n const columns = host.getColumns() ?? EMPTY\n const cols = resolveColumns(columns)\n return {\n name,\n data,\n emit: NO_EMIT,\n ...(host.flagMode ? { flagged: (i: number) => host.issues(i) } : {}),\n run: host.base().run,\n columns,\n getColumnValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.values(data, col) : undefined\n },\n getFormattedValues: (id) => {\n const col = cols.byId.get(id)\n return col ? cache.formatted(data, col) : undefined\n },\n batch: (id, _slot, _rows, body) => {\n if (!cols.byId.has(id)) return false\n body()\n return true\n },\n }\n }\n\n return {\n run,\n current: () => model,\n lastRun: () => lastRun,\n replayContext,\n dispose: () => {\n slicer?.cancel()\n cache?.release()\n memo.clear()\n keys = undefined\n last = undefined\n },\n ...((process.env.NODE_ENV !== \"production\")\n ? {\n probe: () => ({\n memo: memo.size,\n keys: keys !== undefined,\n last: last !== undefined,\n cached: cache?.holds?.(host.getData()) === true,\n }),\n }\n : {}),\n }\n}\n"],"mappings":"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","names":["ctx"]}
@@ -41,6 +41,7 @@ var import_classify = require("../intercept/classify.cjs");
41
41
  var import_context = require("../intercept/context.cjs");
42
42
  var import_fallbacks = require("../intercept/fallbacks.cjs");
43
43
  var import_runtime2 = require("../intercept/runtime.cjs");
44
+ var import_release = require("../pipeline/release.cjs");
44
45
  var import_runner = require("../pipeline/runner.cjs");
45
46
  var import_fetcher = require("../source/fetcher.cjs");
46
47
  var import_server_brand = require("../source/server-brand.cjs");
@@ -391,6 +392,7 @@ function createTable(initialOptions) {
391
392
  });
392
393
  }
393
394
  });
395
+ if (process.env.NODE_ENV !== "production") table[import_release.PROBE] = () => runner.probe?.() ?? {};
394
396
  const explainHost = {
395
397
  table,
396
398
  features: pipeline,
@@ -608,6 +610,7 @@ function createTable(initialOptions) {
608
610
  ingestSeq++;
609
611
  listeners.clear();
610
612
  runner.dispose();
613
+ for (const f of pipeline) f[import_release.RELEASE]?.();
611
614
  if (process.env.NODE_ENV !== "production") feedback?.dispose();
612
615
  }
613
616
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/table/create-table.ts"],"sourcesContent":["import { optionDiagnostics } from '../catalog/codes'\nimport { validateOptionChange, validateOptions } from '../catalog/validator'\nimport { DatakableError, defaultPhase, throwConfigError } from '../diagnostics/build'\nimport { keepDiagnostics } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport { type ExplainHost, explainRow, explainTable } from '../diagnostics/explain'\nimport { createDiagnostics } from '../diagnostics/hub'\nimport { pathsOverlap, type RedactionOptions } from '../diagnostics/redact'\nimport { tracer } from '../diagnostics/tracer'\nimport type { Trigger } from '../diagnostics/types'\nimport { runtimeFor } from '../feature/runtime'\nimport type { AnyFeature, ApiOf, SliceUpdater, TableStateFor } from '../feature/types'\nimport { createDataChecks } from '../ingest/data-checks'\nimport { createDerivedColumns } from '../ingest/derive-columns'\nimport type { SchemaOutcome } from '../ingest/schema'\nimport { SCHEMA_INGEST, type TableSchema } from '../ingest/schema-brand'\nimport type { InvalidRowsMode } from '../ingest/schema-codes'\nimport type { StandardSchemaV1 } from '../ingest/standard-schema'\nimport { errorBoundary } from '../intercept/boundary'\nimport { callUser, errorName } from '../intercept/classify'\nimport { type ContextBase, createContext } from '../intercept/context'\nimport type { Interceptor } from '../intercept/define'\nimport { FAILED, FALLBACK } from '../intercept/fallbacks'\nimport type { OpInput, OpName, OpResult } from '../intercept/operations'\nimport { type Core, createInterceptorRuntime } from '../intercept/runtime'\nimport { createPipeline } from '../pipeline/runner'\nimport type { RowModel, RowModelStatus } from '../pipeline/types'\nimport { checkModeOrder, type FetchOutcome } from '../source/fetcher'\nimport type { ServerSource } from '../source/server'\nimport { SERVER_SOURCE, type ServerFetcher } from '../source/server-brand'\nimport { checkVersions } from '../versioning/registry'\nimport { tableDiagnostics } from './codes'\nimport { createDataMutationCheck, dataMutationDiagnostics } from './data-mutation'\nimport {\n deferral,\n type ExtensionFactory,\n setTableInternals,\n type TableExtension,\n type TableHost,\n} from './internals'\nimport { keepReadOnce } from './read-once'\nimport { PROTO_KEY, stateDiagnostics } from './state-codes'\nimport { createStateFeedbackCheck, stateFeedbackDiagnostics } from './state-feedback'\nimport {\n type ControlledState,\n type Listener,\n type Table,\n type TableOptions,\n type TableState,\n UPDATE_DEPTH_LIMIT,\n type Updater,\n} from './types'\n\nkeepDiagnostics(\n tableDiagnostics,\n dataMutationDiagnostics,\n stateFeedbackDiagnostics,\n optionDiagnostics,\n stateDiagnostics,\n)\n\nconst EMPTY: readonly never[] = []\n\n/** §6.6 status precedence, lowest first: the table shows the highest of its sources. */\nconst RANK: readonly RowModelStatus[] = [\n 'idle',\n 'pending',\n 'validating',\n 'searching',\n 'fetching',\n 'error',\n]\n\nconst isThenable = (v: unknown): v is PromiseLike<unknown> =>\n v != null && typeof (v as { then?: unknown }).then === 'function'\n\n/** Objects already deep-frozen (dev): an unchanged slice is not walked again on the next commit. */\nconst deepFrozen = (process.env.NODE_ENV !== \"production\") ? new WeakSet<object>() : undefined\n\n/**\n * Freezes plain objects and arrays reachable from `root` (dev). Class instances (Date, Map, typed\n * arrays, user classes) are left alone: freezing them would break their own methods. Iterative (an\n * explicit stack): restored state can be nested deeper than the call stack allows (#103).\n */\nfunction deepFreeze(root: unknown): void {\n const stack = [root]\n while (stack.length > 0) {\n const v = stack.pop()\n if (v === null || typeof v !== 'object' || deepFrozen?.has(v)) continue\n const isArray = Array.isArray(v)\n if (!isArray) {\n const proto = Object.getPrototypeOf(v)\n if (proto !== Object.prototype && proto !== null) continue\n }\n deepFrozen?.add(v)\n Object.freeze(v)\n if (isArray) for (let i = 0; i < v.length; i++) stack.push(v[i])\n else for (const k in v) stack.push((v as Record<string, unknown>)[k])\n }\n}\n\n/** Snapshots and their slices are immutable in development (#20); production skips the walk. */\nconst freeze = <S extends object>(s: S): S => {\n if ((process.env.NODE_ENV !== \"production\")) deepFreeze(s)\n return s\n}\n\n/** `undefined` exactly (not `any`, `never` or a union with it). */\ntype IsUndefined<X> =\n (<G>() => G extends X ? 1 : 2) extends <G>() => G extends undefined ? 1 : 2 ? true : false\n\n/**\n * `true` when `Sch` (the inferred `schema` option) is a schema. Its default, `undefined` (no\n * schema), is excluded explicitly: without `strictNullChecks` `undefined` is assignable to every\n * type, `TableSchema` included, which typed `data` as `unknown[]` and `T` as `unknown` (#93).\n */\nexport type HasSchema<Sch> = [Sch] extends [TableSchema]\n ? IsUndefined<Sch> extends true\n ? false\n : true\n : false\n\n/** The row type: the schema output with a `schema` (§5.1), else `T`. */\nexport type SchemaRow<T, Sch> = [Sch] extends [TableSchema]\n ? IsUndefined<Sch> extends true\n ? T\n : StandardSchemaV1.InferOutput<Sch>\n : T\n\n/**\n * `createTable` options: with a `schema`, the row type is its output and `data` is the raw input\n * (`unknown[]`, e.g. parsed JSON), validated per row.\n */\nexport type CreateTableOptions<T, S extends TableState, Sch, M extends InvalidRowsMode> = Omit<\n TableOptions<SchemaRow<T, Sch>, S>,\n 'data' | 'schema' | 'invalidRows' | 'fetcher' | 'initialData'\n> & {\n data?: readonly (HasSchema<Sch> extends true ? unknown : T)[]\n /** With a schema, the raw rows (validated like `data`). */\n initialData?: readonly (HasSchema<Sch> extends true ? unknown : T)[]\n /** With a schema, the fetcher returns raw rows (validated like `data`). */\n fetcher?: ServerFetcher<HasSchema<Sch> extends true ? unknown : T>\n // Without an inferred schema (explicit type arguments, a `TableOptions<T>` object) these keep\n // their `TableOptions` types.\n schema?: HasSchema<Sch> extends true ? Sch : TableSchema<unknown, T>\n invalidRows?: HasSchema<Sch> extends true ? M : InvalidRowsMode\n}\n\n/** Column id: `key` for key columns, `id` for accessor columns. */\nconst columnId = (c: { key?: unknown; id?: unknown }): unknown => c.key ?? c.id\n\n/**\n * Creates the table store (§3.2): immutable state snapshots, controlled slices, isolated listeners,\n * a re-entrancy guard and `destroy()`. Every unit of work runs as an operation (§3.4) through the\n * table's interceptor runtime, with the errorBoundary outermost and diagnostics on a per-table hub.\n *\n * `ctx.where` is always a constant option path or method name (`options`, `options.data`,\n * `setState`, `destroy`): it reaches fingerprints, docs URLs and issue links unredacted, so it must\n * never carry row keys or cell values.\n */\nexport function createTable<\n T,\n S extends TableState = never,\n const Fs extends readonly AnyFeature[] = [],\n const Sch extends TableSchema | undefined = undefined,\n const M extends InvalidRowsMode = 'drop',\n>(\n options: CreateTableOptions<T, TableStateFor<S, Fs, SchemaRow<T, Sch>>, Sch, M> & {\n features?: Fs\n },\n): Table<\n SchemaRow<T, Sch>,\n TableStateFor<S, Fs, SchemaRow<T, Sch>>,\n M,\n HasSchema<Sch> extends true ? unknown : T\n> &\n ApiOf<Fs, SchemaRow<T, Sch>>\nexport function createTable<T, S extends TableState>(\n initialOptions: TableOptions<T, S>,\n): Table<T, S> {\n let options: TableOptions<T, S> = { ...initialOptions }\n let destroyed = false\n let trigger: Trigger = 'init'\n /** Pipeline run id; each `pipeline:run` increments it. */\n let run = 0\n let data: readonly T[] = EMPTY\n let ingestSeq = 0\n /** Data given by the user has been applied once (`RowModel.isInitialLoad`, §6.6). */\n let loaded = false\n /** The last `data:ingest` failed (op fallback): `status: 'error'` until one succeeds (§6.6). */\n let ingestFailed = false\n /** The ingest whose async schema validation is in flight (`status: 'validating'`); 0: none. */\n let validatingSeq = 0\n /** Rows of the current data that failed the schema (`getInvalidRows`, §5.1). */\n let schemaOutcome: SchemaOutcome | undefined\n /**\n * SSR (§7.2): `options.initialData` until the creation ingest read it (`undefined` with `data`),\n * then its ingested rows while they are the table's data (`initialRows`).\n */\n let initialInput = options.data == null ? options.initialData : undefined\n let initialRows: readonly unknown[] | undefined\n /** Created inside `createDeferred` (§7.2): async work waits for `startTable`. */\n let deferring = deferral.depth > 0\n /**\n * Opt-in parts of the store (`TableInternals.use`): the async request machinery and the server\n * source. A table without an async source creates none (§9.3).\n */\n const extensions = new Map<ExtensionFactory<TableExtension>, TableExtension>()\n /** The server source (`withFetcher`, §7.1), once a fetcher was given. */\n let server: ServerSource | undefined\n\n let controlled = new Set<string>()\n let snapshot: S\n /** The snapshot listeners last saw (`prev` of the next notification). */\n let notified: S\n /** A committed change (state or data) not yet notified. */\n let pending = false\n let notifying = false\n let rounds = 0\n let loopReported = false\n let current: number | undefined\n let listenerSeq = 0\n const listeners = new Map<number, Listener<S>>()\n /** Depth of feature API calls in progress: listeners are notified when the outermost returns. */\n let apiDepth = 0\n /** Data, state or columns changed since the row model was computed. */\n let rowModelDirty = true\n /** Diagnostic context (§8.1): the data mode of each pipeline feature (set once features load). */\n const modes: Record<string, 'client' | 'server'> = {}\n\n const table: Table<T, S> = {\n getState: () => snapshot,\n setState,\n subscribe,\n setOptions,\n getOptions: () => options,\n getData: () => data,\n // Core method: on the literal before installApis, so no feature can take the name.\n getRowModel,\n getInvalidRows: () => schemaOutcome?.invalid ?? EMPTY,\n getDiagnostics: () => hub.getDiagnostics(),\n // Core methods (§8.4), read-only: also on the literal before installApis.\n explain: () => explainTable(explainHost),\n explainRow: (key) => explainRow(explainHost, key),\n refetch,\n destroy,\n }\n\n // Redaction (§8.2): `diagnostics.redact` gives the level or a custom rule; column defs give the\n // sensitive columns and whether the rowKey column is sensitive. Both are read per emit, so\n // `setOptions({ columns })` is followed.\n const redactOption = options.diagnostics?.redact\n const redaction: RedactionOptions = {\n ...(typeof redactOption === 'string' ? { level: redactOption } : {}),\n ...(typeof redactOption === 'function' ? { redact: redactOption } : {}),\n sensitiveColumns,\n // A rowKey path into (or above) a sensitive column reads its data too (#45).\n rowKeySensitive: () => {\n const k = options.rowKey\n return typeof k === 'string' && sensitiveColumns().some((c) => pathsOverlap(k, c))\n },\n }\n const hub = createDiagnostics({\n ...(options.name === undefined ? {} : { name: options.name }),\n table,\n onDiagnostic: (d) => options.onDiagnostic?.(d),\n ...(options.strict === undefined ? {} : { strict: options.strict }),\n getContext: () => ({ trigger, run, mode: modes }),\n getDataRef: () => data,\n redaction,\n })\n // Option validator (§3.4, `table:init`), development only: before anything reads the options.\n // Invalid values throw DK_INVALID_OPTION; unknown / no-effect options are reported on the hub.\n if ((process.env.NODE_ENV !== \"production\")) validateOptions(options, { table: hub.table, emit: hub.emit })\n // Features (§3.3) are read once, at creation. `features` is the listed order (API install, conflict\n // reports); `pipeline` is stage order for the runner. Duplicates throw here (config error).\n const features: readonly AnyFeature[] = options.features ?? EMPTY\n // The feature runtime comes with the features (`defineFeature`): none for a table without.\n const rt = runtimeFor(features)\n const pipeline = rt ? rt.orderFeatures(features, hub.table) : EMPTY\n // Data modes (§7.1): DK_MODE_ORDER (a config error, development). A fetcher without a server-mode\n // feature (DK_FETCHER_WITHOUT_SERVER_MODE) is checked by the server source.\n if ((process.env.NODE_ENV !== \"production\")) checkModeOrder(pipeline, hub.table)\n for (const f of pipeline) if (f.stage !== 'none') modes[f.name] = f.mode ?? 'client'\n // Extension interceptors come first (asyncControl, one per table, installed with the first async\n // source: user / feature interceptors and the core see its signal); the boundary stays\n // outermost. Feature interceptors (pipeline order) come next, then the user's.\n const front: Interceptor<OpName>[] = []\n const featureInterceptors = pipeline.flatMap((f) => f.interceptors ?? EMPTY)\n // The tracer (§3.4, explain timings) is development-only: `(process.env.NODE_ENV !== \"production\")` folds to `false` in production\n // builds, which drops it from the bundle; there it is opt-in with `interceptors: [tracer()]`.\n const traced = (process.env.NODE_ENV !== \"production\") ? [tracer() as Interceptor<OpName>] : EMPTY\n const withFront = (list: readonly Interceptor<OpName>[] | undefined) => [\n ...front,\n ...traced,\n ...featureInterceptors,\n ...(list ?? EMPTY),\n ]\n const runtime = createInterceptorRuntime({\n interceptors: withFront(options.interceptors),\n emit: hub.emit,\n })\n runtime.installBoundary(errorBoundary)\n hub.attach(runtime)\n // Dev check (§5.3): the same `data` array passed again with changed contents (DK_DATA_MUTATED).\n const dataCheck = (process.env.NODE_ENV !== \"production\") ? createDataMutationCheck(hub.emit) : undefined\n // Feature `requires.core` (throws DK_FEATURE_INCOMPATIBLE), duplicate cores, version mismatch\n // (§8.5): development checks (changed 2026-10-13 for §9.3).\n if ((process.env.NODE_ENV !== \"production\")) checkVersions(features, hub.emit, hub.table)\n // Ingest data checks (§5.3) and zero-config columns (§4.1): both read only the first rows.\n // The data checks are developer hints: development only (changed 2026-10-13 for §9.3).\n const dataChecks = (process.env.NODE_ENV !== \"production\") ? createDataChecks(hub.emit) : undefined\n /** Controlled changes not fed back (DK_CONTROLLED_NOT_FED_BACK, development). */\n const feedback = (process.env.NODE_ENV !== \"production\") ? createStateFeedbackCheck(hub.emit) : undefined\n const derivedColumns = createDerivedColumns()\n // Schema ingest (§5.1): `schema` and `invalidRows` are read once (validated above). The step\n // comes with the schema (`withSchema`, `@datakable/core/schema`): a table without one never\n // bundles it.\n const schemaIngest = (options.schema as Partial<TableSchema> | undefined)?.[SCHEMA_INGEST]?.(\n options.invalidRows ?? 'drop',\n () => options.columns,\n )\n // Never silent (§8.6): in production (no option validator) an unwrapped schema would be ignored.\n if (options.schema && !schemaIngest) unwrapped('schema', options.schema, 'withSchema')\n\n function sensitiveColumns(): string[] {\n const out: string[] = []\n for (const c of options.columns ?? EMPTY) {\n const id = columnId(c as { key?: unknown; id?: unknown })\n if (c.sensitive && typeof id === 'string') out.push(id)\n }\n return out\n }\n\n function base(): ContextBase {\n return { table, run, trigger, phase: defaultPhase(), emit: hub.emit }\n }\n\n function op<O extends OpName>(\n name: O,\n input: OpInput<O>,\n where: string,\n core: Core<O>,\n fallback?: unknown,\n ): OpResult<O> {\n const ctx = createContext(name, input, where, base())\n if (fallback !== undefined) ctx.meta.set(FALLBACK, fallback)\n return runtime.run(name, ctx, core)\n }\n\n function withTrigger<R>(t: Trigger, fn: () => R): R {\n const prev = trigger\n trigger = t\n try {\n return fn()\n } finally {\n trigger = prev\n }\n }\n\n // --- state -------------------------------------------------------------------------------------\n\n /** A `__proto__` key (JSON.parse makes it own) is never written into state (#102). */\n function protoKey(k: string): boolean {\n if (k !== PROTO_KEY) return false\n hub.emit('DK_STATE_UNKNOWN_KEY', { slice: '', key: k, known: EMPTY })\n return true\n }\n\n function controlledKeys(state: ControlledState<S> | undefined): Set<string> {\n const keys = new Set<string>()\n if (state) {\n for (const k of Object.keys(state)) if (state[k] !== undefined && !protoKey(k)) keys.add(k)\n }\n return keys\n }\n\n /** `s` with the controlled slices from `options.state`; `s` itself when none differ. */\n function overlay(s: S): S {\n let next: TableState | undefined\n const state = options.state as TableState | undefined\n if (state) {\n for (const k of controlled) {\n if (!Object.is(s[k], state[k])) {\n next ??= { ...s }\n next[k] = state[k]\n }\n }\n }\n return next ? freeze(next as S) : s\n }\n\n function commit(next: S) {\n snapshot = next\n pending = true\n rowModelDirty = true\n }\n\n function warnControlled(dropped: string[] | undefined) {\n if (options.onStateChange || controlled.size === 0) return\n const slices = dropped ?? [...controlled]\n hub.emit('DK_CONTROLLED_WITHOUT_HANDLER', { slices, dropped: dropped !== undefined })\n }\n\n function syncControlled() {\n controlled = controlledKeys(options.state)\n const next = overlay(snapshot)\n if (next !== snapshot) commit(next)\n if ((process.env.NODE_ENV !== \"production\")) feedback?.settle(options.state as TableState | undefined, controlled)\n warnControlled(undefined)\n }\n\n function dispatch(updater: Updater<S>, slot: string) {\n // A method argument, not an option: `where` = `operation table.setState at updater`.\n const partial: Partial<S> =\n typeof updater === 'function'\n ? callUser(\n 'updater',\n updater,\n snapshot,\n undefined,\n slot === 'setState' ? 'table.setState' : `${slot}.setState`,\n )\n : updater\n if (partial === null || typeof partial !== 'object') return\n let next: TableState | undefined\n let changes: TableState | undefined\n let dropped: string[] | undefined\n for (const k of Object.keys(partial)) {\n if (protoKey(k)) continue\n const v = (partial as TableState)[k]\n if (Object.is(snapshot[k], v)) continue\n if (controlled.has(k)) {\n if (options.onStateChange) {\n changes ??= {}\n changes[k] = v\n } else {\n dropped ??= []\n dropped.push(k)\n }\n continue\n }\n next ??= { ...snapshot }\n next[k] = v\n }\n // The owner is told first: if onStateChange throws, nothing is committed (state unchanged).\n if (changes && options.onStateChange) {\n const c = changes as Partial<S>\n if ((process.env.NODE_ENV !== \"production\")) feedback?.ask(Object.keys(changes), trigger)\n callUser('onStateChange', options.onStateChange, (prev: Partial<S>) => ({ ...prev, ...c }))\n if ((process.env.NODE_ENV !== \"production\")) feedback?.asked()\n }\n if (next) commit(freeze(next as S))\n if (dropped) warnControlled(dropped)\n }\n\n /**\n * Notifies listeners until no change is pending. Updates made by listeners are committed at once\n * and notified in the next round (not nested), so every listener sees rounds in order.\n */\n function flush() {\n if (notifying) return\n sync()\n if (!pending) return\n notifying = true\n let rethrow: unknown\n try {\n while (pending && !destroyed) {\n // Server state changed (this round's state): the fetch starts in the same notification.\n sync()\n pending = false\n rounds++\n const prev = notified\n const state = snapshot\n notified = state\n // Listeners read the row model of the state they are notified with.\n ensureRowModel()\n for (const [id, listener] of [...listeners]) {\n // A listener may destroy the table: the rest of the round is not notified.\n if (destroyed) break\n current = id\n try {\n listener(state, prev)\n } catch (e) {\n // strict: a DatakableError (e.g. DK_UPDATE_LOOP) thrown inside the listener.\n if (e instanceof DatakableError) {\n rethrow ??= e\n continue\n }\n try {\n const name = errorName(e)\n hub.emit(\n 'DK_LISTENER_FAILED',\n { listener: id, ...(name === undefined ? {} : { errorName: name }) },\n { cause: e },\n )\n } catch (strictError) {\n rethrow ??= strictError\n }\n }\n }\n }\n } finally {\n notifying = false\n rounds = 0\n loopReported = false\n current = undefined\n }\n if (rethrow !== undefined) throw rethrow\n }\n\n /** `false` (and one `DK_UPDATE_LOOP`) when a re-entrant update would exceed the depth limit. */\n function admit(slices: string[]): boolean {\n if (!notifying || rounds < UPDATE_DEPTH_LIMIT) return true\n if (!loopReported) {\n loopReported = true\n hub.emit('DK_UPDATE_LOOP', {\n limit: UPDATE_DEPTH_LIMIT,\n slices,\n ...(current === undefined ? {} : { listener: current }),\n })\n }\n return false\n }\n\n function destroyedCall(method: string) {\n withTrigger(`api:${method}`, () => hub.emit('DK_TABLE_DESTROYED', { method }))\n }\n\n // --- data --------------------------------------------------------------------------------------\n\n /** Applies ingested data; `given`: it came from a user `options.data` (marks the first load). */\n function setData(next: readonly T[], given: boolean) {\n if (given && !loaded) {\n // isInitialLoad flips: a new row model and a notification even for the same reference.\n loaded = true\n pending = true\n rowModelDirty = true\n }\n if (next === data) return\n data = next\n pending = true\n // After `data` is set: diagnostics dedupe per data reference.\n if ((process.env.NODE_ENV !== \"production\")) dataChecks?.check(data, options.columns)\n // The pipeline runs before the next notification (or on getRowModel), as `pipeline:run` with\n // ctx.meta[FALLBACK] = the last good row model (pipeline/runner.ts).\n rowModelDirty = true\n }\n\n // --- row model ---------------------------------------------------------------------------------\n\n const runner = createPipeline<T>({\n runtime,\n featureRuntime: rt,\n emit: hub.emit,\n features: pipeline,\n listed: features,\n base,\n nextRun: () => ++run,\n getData: () => data,\n getState: () => snapshot,\n getColumns: () => options.columns ?? derivedColumns(data),\n getRowKey: () => options.rowKey,\n isInitialLoad: () => !loaded,\n status,\n issues: (index) => schemaOutcome?.flagged?.get(index),\n flagMode: schemaIngest !== undefined && options.invalidRows === 'flag',\n // Time-sliced work ended (§9.1): 'pending' → the finished row model, never silent (§6.6).\n refresh: (t) => {\n if (destroyed) return\n withTrigger(t, () => {\n touch()\n if (apiDepth === 0) flush()\n })\n },\n })\n\n const explainHost: ExplainHost = {\n table,\n features: pipeline,\n rowModel: getRowModel as () => RowModel<unknown>,\n lastRun: runner.lastRun,\n replay: runner.replayContext,\n data: () => data,\n state: () => snapshot,\n rowKey: () => options.rowKey,\n schemaMode: () => (schemaIngest ? (options.invalidRows ?? 'drop') : undefined),\n schema: () => schemaOutcome,\n diagnostics: () => hub.getDiagnostics(),\n redaction,\n ...(rt ? { detail: rt.explainDetail } : {}),\n }\n\n /**\n * Status from outside the pipeline (§6.6): a failed ingest, a running async schema, the search\n * slice (`pending` / `searching` / `error`), and the extensions' (a failed fetch, an in-flight\n * fetcher / `searchFn`, deferred async work). Precedence: error > fetching > searching >\n * validating > pending > idle.\n */\n function status(): RowModelStatus {\n const search = searchStatus()\n let s: RowModelStatus =\n ingestFailed || search === 'error'\n ? 'error'\n : search === 'searching'\n ? 'searching'\n : validatingSeq !== 0\n ? 'validating'\n : search === 'pending'\n ? 'pending'\n : 'idle'\n for (const e of extensions.values()) {\n const x = e.status?.()\n if (x !== undefined && RANK.indexOf(x) > RANK.indexOf(s)) s = x\n }\n return s\n }\n\n /** Extensions start work that follows state (the fetcher on server state, §7.1). */\n function sync() {\n for (const e of extensions.values()) e.sync?.()\n }\n\n /** The `status` of the first search-stage slice that reports one (§6.3). */\n function searchStatus(): unknown {\n for (const f of pipeline) {\n if (f.stage !== 'search') continue\n const s = (snapshot as Record<string, unknown> | undefined)?.[f.name]\n if (s !== null && typeof s === 'object' && 'status' in s) {\n const v = (s as { status: unknown }).status\n if (v !== 'idle') return v\n }\n }\n return 'idle'\n }\n\n /** A row model change not caused by state: recompute and notify on the next flush. */\n function touch() {\n pending = true\n rowModelDirty = true\n }\n\n /** Recomputes the row model if data, state or columns changed (never after destroy). */\n function ensureRowModel() {\n if (!rowModelDirty || destroyed) return\n rowModelDirty = false\n runner.run()\n }\n\n function getRowModel(): RowModel<T> {\n ensureRowModel()\n // Only empty when destroyed before the first run.\n return (\n runner.current() ?? {\n rows: EMPTY,\n filteredCount: 0,\n totalCount: 0,\n status: status(),\n isInitialLoad: !loaded,\n }\n )\n }\n\n /**\n * Applies the result of the latest `data:ingest`. A fallback (the boundary set `FAILED`) keeps\n * the previous data, sets `status: 'error'` and never marks the table loaded (§6.6, §8.6).\n */\n function applyIngest(out: readonly unknown[], failed: boolean, given: boolean, initial = false) {\n if (validatingSeq !== 0) {\n validatingSeq = 0\n touch()\n }\n if (failed) {\n ingestFailed = true\n touch()\n return\n }\n if (ingestFailed) {\n ingestFailed = false\n touch()\n }\n schemaOutcome = schemaIngest?.outcome(out)\n setData(out as readonly T[], given)\n // `initialData` is the initial async result only while it is the data (§7.2).\n initialRows = initial ? out : undefined\n }\n\n /**\n * `data:ingest` with the previous data as fallback: the schema step (§5.1) runs in its core. An\n * async result is applied if still latest. `fetched`: rows of an applied fetcher result (§7.1),\n * ingested like `options.data` (schema, data checks) and marking the table loaded.\n */\n function ingest(fetched?: readonly unknown[]) {\n const seq = ++ingestSeq\n // At creation, `initialData` stands in for a missing `data` (§7.2); read once.\n const initial = fetched === undefined && initialInput !== undefined\n const input = fetched ?? (initial ? initialInput : options.data)\n initialInput = undefined\n // `data: null` counts as not given (production has no option validator, #94).\n const given = input != null\n const source: Trigger = fetched ? 'fetch' : 'data-change'\n // A validation still in flight is superseded (its result is discarded): not 'validating' now,\n // unless this ingest's own schema step goes async.\n if (validatingSeq !== 0) {\n validatingSeq = 0\n touch()\n }\n try {\n withTrigger(source, () => {\n const ctx = createContext(\n 'data:ingest',\n { data: input ?? EMPTY },\n fetched ? 'fetcher' : initial ? 'options.initialData' : 'options.data',\n base(),\n )\n ctx.meta.set(FALLBACK, data)\n let sync = true\n const out = runtime.run('data:ingest', ctx, (c) => {\n const input = c.input.data as readonly unknown[]\n if (!schemaIngest) return input\n const r = schemaIngest.validate(input, c.emit)\n if (isThenable(r) && seq === ingestSeq && !destroyed) {\n // 'validating' is never silent: a new row model and a notification now (§6.6).\n validatingSeq = seq\n touch()\n if (!sync) flush()\n }\n return r\n })\n sync = false\n if (!isThenable(out)) {\n applyIngest(out, ctx.meta.has(FAILED), given, initial)\n return\n }\n const settle = (d: readonly unknown[], failed: boolean) => {\n if (seq !== ingestSeq || destroyed) return\n withTrigger(source, () => {\n applyIngest(d, failed, given, initial)\n flush()\n })\n }\n Promise.resolve(out).then(\n (d) => settle(d, ctx.meta.has(FAILED)),\n // A DatakableError the boundary rethrew (strict, or `invalidRows: 'throw'` with an async\n // schema, already reported): the previous data is kept with 'error'. No unhandled\n // rejection either way (§8.6).\n () => settle(data, true),\n )\n })\n } finally {\n // Dev (§5.3): fingerprint `data` after the core read it, so the check never takes reads\n // first; also when the ingest threw, so a later same-reference check compares this data.\n if ((process.env.NODE_ENV !== \"production\") && !fetched) dataCheck?.remember(options.data)\n }\n }\n\n // --- API ---------------------------------------------------------------------------------------\n\n /** `state:dispatch` (where = `slot`, a constant method / feature name); notifies unless batched. */\n function update(updater: Updater<S>, slot: string) {\n void op('state:dispatch', { updater }, slot, (): undefined => {\n dispatch(updater, slot)\n })\n if (apiDepth === 0) flush()\n }\n\n function setState(updater: Updater<S>) {\n if (destroyed) return destroyedCall('setState')\n if (!admit(typeof updater === 'function' ? [] : Object.keys(updater ?? {}))) return\n withTrigger('api:setState', () => update(updater, 'setState'))\n }\n\n // --- features ----------------------------------------------------------------------------------\n\n /** A feature's `ctx.setState`: replaces its own slice (trigger: the API call's, if any). */\n function setSlice(name: string, updater: SliceUpdater<unknown>) {\n if (destroyed) return destroyedCall(`${name}.setState`)\n if (!admit([name])) return\n const slice: Updater<S> =\n typeof updater === 'function'\n ? (prev) => ({ [name]: (updater as (p: unknown) => unknown)(prev[name]) }) as Partial<S>\n : ({ [name]: updater } as Partial<S>)\n update(slice, name)\n }\n\n /** Runs a feature API method (wrapped once by `installApis`). */\n function callApi(method: string, fn: () => unknown, ifDestroyed?: () => unknown): unknown {\n if (destroyed) {\n destroyedCall(method)\n return ifDestroyed?.()\n }\n return withTrigger(`api:${method}`, () => {\n apiDepth++\n try {\n return fn()\n } finally {\n apiDepth--\n if (apiDepth === 0) flush()\n }\n })\n }\n\n function subscribe(listener: Listener<S>): () => void {\n if (destroyed) {\n destroyedCall('subscribe')\n return () => {}\n }\n const id = ++listenerSeq\n listeners.set(id, listener)\n return () => {\n listeners.delete(id)\n }\n }\n\n function setOptions(partial: Partial<TableOptions<T, S>>) {\n if (destroyed) return destroyedCall('setOptions')\n if (!admit(Object.keys(partial.state ?? {}))) return\n withTrigger('setOptions', () => {\n const previous = options\n const next = { ...options, ...partial }\n // Option validator (§3.4, `table:setOptions`, development): an invalid value throws before\n // anything changes. Read-once options (`features`, `timeout`, `diagnostics`, …) keep their\n // value in every build.\n if ((process.env.NODE_ENV !== \"production\")) validateOptionChange(partial, next, previous, { table: hub.table, emit: hub.emit })\n else keepReadOnce(partial, next, previous)\n if ('fetcher' in partial) useServer(next.fetcher, 'setOptions')?.check(next.fetcher)\n void op('table:setOptions', { options: next, previous }, 'options', (): undefined => {\n options = next\n if (next.interceptors !== previous.interceptors) {\n runtime.setInterceptors(withFront(next.interceptors))\n }\n if ('state' in partial || 'onStateChange' in partial) syncControlled()\n if (next.columns !== previous.columns || next.rowKey !== previous.rowKey) {\n rowModelDirty = true\n pending = true\n }\n // The page count changed (§6.5): listeners re-read it (and pagination clamps).\n if (next.rowCount !== previous.rowCount) pending = true\n // A new fetcher reference runs at once, even with the same params (flush → sync).\n if (next.fetcher !== previous.fetcher) server?.reset()\n // New data is checked when applied (setData); same data with new columns is checked here.\n if (next.data !== previous.data) ingest()\n else if ((process.env.NODE_ENV !== \"production\")) {\n if ('data' in partial) dataCheck?.check(next.data)\n if (next.columns !== previous.columns) dataChecks?.check(data, next.columns)\n }\n })\n flush()\n })\n }\n\n function destroy() {\n if (destroyed) return\n withTrigger('api:destroy', () => {\n try {\n void op('table:destroy', undefined, 'destroy', (): undefined => {\n destroyed = true\n })\n } finally {\n // Even if an interceptor skipped the core: the table is destroyed.\n destroyed = true\n ingestSeq++\n listeners.clear()\n runner.dispose()\n if ((process.env.NODE_ENV !== \"production\")) feedback?.dispose()\n }\n })\n }\n\n // --- extensions (§9.3) ---------------------------------------------------------------------\n\n function batch<R>(t: Trigger, fn: () => R): R {\n return withTrigger(t, () => {\n apiDepth++\n try {\n return fn()\n } finally {\n apiDepth--\n if (apiDepth === 0) flush()\n }\n })\n }\n\n const host: TableHost = {\n table: table as unknown as Table<unknown, TableState>,\n name: hub.table,\n emit: hub.emit,\n runtime,\n features: pipeline,\n options: () => options as TableOptions<unknown>,\n state: () => snapshot,\n base,\n destroyed: () => destroyed,\n loaded: () => loaded,\n status,\n touch,\n notify: () => {\n if (apiDepth === 0) flush()\n },\n batch,\n ingest: (rows) => ingest(rows),\n intercept(interceptor) {\n front.push(interceptor)\n runtime.setInterceptors(withFront(options.interceptors))\n },\n deferring: () => deferring,\n use,\n }\n\n function use<E extends TableExtension>(factory: ExtensionFactory<E>): E {\n let e = extensions.get(factory as ExtensionFactory<TableExtension>) as E | undefined\n if (!e) {\n e = factory(host)\n extensions.set(factory as ExtensionFactory<TableExtension>, e)\n }\n return e\n }\n\n /** The server source a `withFetcher` fetcher brings (created once); else the current one. */\n function useServer(fetcher: unknown, phase?: 'setOptions'): ServerSource | undefined {\n const factory = (fetcher as Partial<ServerFetcher<unknown>> | undefined)?.[SERVER_SOURCE]\n if (factory) server = use(factory)\n // Never silent (§8.6): in production an unwrapped fetcher would never run.\n else if (fetcher) unwrapped('fetcher', fetcher, 'withFetcher', 'server', phase)\n return server\n }\n\n /**\n * `DK_INVALID_OPTION` for a schema / fetcher not wrapped with its opt-in import (§5.1, §7.1). A\n * production check: in development the option validator reports it first, with the full text.\n */\n function unwrapped(\n path: 'schema' | 'fetcher',\n value: unknown,\n wrap: string,\n entry: string = path,\n phase: 'init' | 'setOptions' = 'init',\n ): never {\n return throwConfigError(\n 'DK_INVALID_OPTION',\n {\n path,\n expected: `wrapped|${wrap}|${path}|${entry}`, // prose key (diagnostics/prose.ts)\n received: typeof value,\n suggestions: [],\n phase,\n },\n { table: hub.table, trigger: phase },\n )\n }\n\n /**\n * Runs the fetcher again with the current params (§7.1); never rejects. Without a fetcher:\n * `{ status: 'applied' }` at once. Deferred: settles after `startTable` (#90, `server.sync`).\n */\n function refetch(): Promise<FetchOutcome> {\n if (destroyed) {\n destroyedCall('refetch')\n return Promise.resolve({ status: 'superseded' })\n }\n return (\n withTrigger('api:refetch', () => server?.sync(true)) ?? Promise.resolve({ status: 'applied' })\n )\n }\n\n /** `startTable` (§7.2): the deferred work starts; listeners see the new status at once. */\n function start() {\n if (!deferring || destroyed) return\n deferring = false\n let had = false\n for (const e of extensions.values()) if (e.start?.()) had = true\n if (!had) return\n // The pipeline re-runs: 'pending' ends and the search feature's check starts its searchFn.\n touch()\n withTrigger('hydrate', () => flush())\n }\n\n setTableInternals(table, {\n features: pipeline,\n name: options.name,\n rowCount: () => (typeof options.fetcher === 'function' ? server?.rowCount() : options.rowCount),\n hasFetcher: () => typeof options.fetcher === 'function',\n emit: hub.emit,\n use,\n peek: (factory) => extensions.get(factory as ExtensionFactory<TableExtension>) as never,\n extensions: () => extensions.values(),\n start,\n initialRows: () =>\n initialRows !== undefined && initialRows === data ? initialRows : undefined,\n })\n\n // --- init --------------------------------------------------------------------------------------\n\n controlled = controlledKeys(options.state)\n if ((process.env.NODE_ENV !== \"production\")) feedback?.settle(options.state as TableState | undefined, controlled)\n // Feature `initialState()` slices, with `options.initialState` on top per slice.\n // A copy without a `__proto__` key (#102): safe for `Object.assign` in initialSlices.\n const restored: TableState = { ...options.initialState }\n if (Object.hasOwn(restored, PROTO_KEY) && protoKey(PROTO_KEY)) delete restored[PROTO_KEY]\n snapshot = overlay(freeze((rt ? rt.initialSlices(features, restored, hub.emit) : restored) as S))\n notified = snapshot\n // Merges the feature APIs onto the table; a name clash throws DK_FEATURE_API_CONFLICT.\n rt?.installApis(features, {\n table: table as unknown as Table<unknown, TableState>,\n tableName: hub.table,\n emit: hub.emit,\n getSlice: (name) => snapshot[name],\n setSlice,\n call: callApi,\n })\n // Server source (§7.1): with a `withFetcher` fetcher (throws DK_FETCHER_WITHOUT_SERVER_MODE).\n useServer(options.fetcher)\n withTrigger('init', () => {\n // `void`: sync ops never return a promise (op kinds, §3.4).\n void op('table:init', { options }, 'options', (): undefined => {\n // Ingest first: dedupe is per data reference, so warnings follow the initial data.\n ingest()\n warnControlled(undefined)\n })\n // Server source (§7.1): the first request starts now ('fetching', isInitialLoad: true), unless\n // initialData answered the initial server state (§7.2).\n sync()\n })\n pending = false\n return table\n}\n"],"mappings":"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","names":["import_runtime","import_codes","sync","input"]}
1
+ {"version":3,"sources":["../../src/table/create-table.ts"],"sourcesContent":["import { optionDiagnostics } from '../catalog/codes'\nimport { validateOptionChange, validateOptions } from '../catalog/validator'\nimport { DatakableError, defaultPhase, throwConfigError } from '../diagnostics/build'\nimport { keepDiagnostics } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport { type ExplainHost, explainRow, explainTable } from '../diagnostics/explain'\nimport { createDiagnostics } from '../diagnostics/hub'\nimport { pathsOverlap, type RedactionOptions } from '../diagnostics/redact'\nimport { tracer } from '../diagnostics/tracer'\nimport type { Trigger } from '../diagnostics/types'\nimport { runtimeFor } from '../feature/runtime'\nimport type { AnyFeature, ApiOf, SliceUpdater, TableStateFor } from '../feature/types'\nimport { createDataChecks } from '../ingest/data-checks'\nimport { createDerivedColumns } from '../ingest/derive-columns'\nimport type { SchemaOutcome } from '../ingest/schema'\nimport { SCHEMA_INGEST, type TableSchema } from '../ingest/schema-brand'\nimport type { InvalidRowsMode } from '../ingest/schema-codes'\nimport type { StandardSchemaV1 } from '../ingest/standard-schema'\nimport { errorBoundary } from '../intercept/boundary'\nimport { callUser, errorName } from '../intercept/classify'\nimport { type ContextBase, createContext } from '../intercept/context'\nimport type { Interceptor } from '../intercept/define'\nimport { FAILED, FALLBACK } from '../intercept/fallbacks'\nimport type { OpInput, OpName, OpResult } from '../intercept/operations'\nimport { type Core, createInterceptorRuntime } from '../intercept/runtime'\nimport { PROBE, RELEASE, type Releasable } from '../pipeline/release'\nimport { createPipeline } from '../pipeline/runner'\nimport type { RowModel, RowModelStatus } from '../pipeline/types'\nimport { checkModeOrder, type FetchOutcome } from '../source/fetcher'\nimport type { ServerSource } from '../source/server'\nimport { SERVER_SOURCE, type ServerFetcher } from '../source/server-brand'\nimport { checkVersions } from '../versioning/registry'\nimport { tableDiagnostics } from './codes'\nimport { createDataMutationCheck, dataMutationDiagnostics } from './data-mutation'\nimport {\n deferral,\n type ExtensionFactory,\n setTableInternals,\n type TableExtension,\n type TableHost,\n} from './internals'\nimport { keepReadOnce } from './read-once'\nimport { PROTO_KEY, stateDiagnostics } from './state-codes'\nimport { createStateFeedbackCheck, stateFeedbackDiagnostics } from './state-feedback'\nimport {\n type ControlledState,\n type Listener,\n type Table,\n type TableOptions,\n type TableState,\n UPDATE_DEPTH_LIMIT,\n type Updater,\n} from './types'\n\nkeepDiagnostics(\n tableDiagnostics,\n dataMutationDiagnostics,\n stateFeedbackDiagnostics,\n optionDiagnostics,\n stateDiagnostics,\n)\n\nconst EMPTY: readonly never[] = []\n\n/** §6.6 status precedence, lowest first: the table shows the highest of its sources. */\nconst RANK: readonly RowModelStatus[] = [\n 'idle',\n 'pending',\n 'validating',\n 'searching',\n 'fetching',\n 'error',\n]\n\nconst isThenable = (v: unknown): v is PromiseLike<unknown> =>\n v != null && typeof (v as { then?: unknown }).then === 'function'\n\n/** Objects already deep-frozen (dev): an unchanged slice is not walked again on the next commit. */\nconst deepFrozen = (process.env.NODE_ENV !== \"production\") ? new WeakSet<object>() : undefined\n\n/**\n * Freezes plain objects and arrays reachable from `root` (dev). Class instances (Date, Map, typed\n * arrays, user classes) are left alone: freezing them would break their own methods. Iterative (an\n * explicit stack): restored state can be nested deeper than the call stack allows (#103).\n */\nfunction deepFreeze(root: unknown): void {\n const stack = [root]\n while (stack.length > 0) {\n const v = stack.pop()\n if (v === null || typeof v !== 'object' || deepFrozen?.has(v)) continue\n const isArray = Array.isArray(v)\n if (!isArray) {\n const proto = Object.getPrototypeOf(v)\n if (proto !== Object.prototype && proto !== null) continue\n }\n deepFrozen?.add(v)\n Object.freeze(v)\n if (isArray) for (let i = 0; i < v.length; i++) stack.push(v[i])\n else for (const k in v) stack.push((v as Record<string, unknown>)[k])\n }\n}\n\n/** Snapshots and their slices are immutable in development (#20); production skips the walk. */\nconst freeze = <S extends object>(s: S): S => {\n if ((process.env.NODE_ENV !== \"production\")) deepFreeze(s)\n return s\n}\n\n/** `undefined` exactly (not `any`, `never` or a union with it). */\ntype IsUndefined<X> =\n (<G>() => G extends X ? 1 : 2) extends <G>() => G extends undefined ? 1 : 2 ? true : false\n\n/**\n * `true` when `Sch` (the inferred `schema` option) is a schema. Its default, `undefined` (no\n * schema), is excluded explicitly: without `strictNullChecks` `undefined` is assignable to every\n * type, `TableSchema` included, which typed `data` as `unknown[]` and `T` as `unknown` (#93).\n */\nexport type HasSchema<Sch> = [Sch] extends [TableSchema]\n ? IsUndefined<Sch> extends true\n ? false\n : true\n : false\n\n/** The row type: the schema output with a `schema` (§5.1), else `T`. */\nexport type SchemaRow<T, Sch> = [Sch] extends [TableSchema]\n ? IsUndefined<Sch> extends true\n ? T\n : StandardSchemaV1.InferOutput<Sch>\n : T\n\n/**\n * `createTable` options: with a `schema`, the row type is its output and `data` is the raw input\n * (`unknown[]`, e.g. parsed JSON), validated per row.\n */\nexport type CreateTableOptions<T, S extends TableState, Sch, M extends InvalidRowsMode> = Omit<\n TableOptions<SchemaRow<T, Sch>, S>,\n 'data' | 'schema' | 'invalidRows' | 'fetcher' | 'initialData'\n> & {\n data?: readonly (HasSchema<Sch> extends true ? unknown : T)[]\n /** With a schema, the raw rows (validated like `data`). */\n initialData?: readonly (HasSchema<Sch> extends true ? unknown : T)[]\n /** With a schema, the fetcher returns raw rows (validated like `data`). */\n fetcher?: ServerFetcher<HasSchema<Sch> extends true ? unknown : T>\n // Without an inferred schema (explicit type arguments, a `TableOptions<T>` object) these keep\n // their `TableOptions` types.\n schema?: HasSchema<Sch> extends true ? Sch : TableSchema<unknown, T>\n invalidRows?: HasSchema<Sch> extends true ? M : InvalidRowsMode\n}\n\n/** Column id: `key` for key columns, `id` for accessor columns. */\nconst columnId = (c: { key?: unknown; id?: unknown }): unknown => c.key ?? c.id\n\n/**\n * Creates the table store (§3.2): immutable state snapshots, controlled slices, isolated listeners,\n * a re-entrancy guard and `destroy()`. Every unit of work runs as an operation (§3.4) through the\n * table's interceptor runtime, with the errorBoundary outermost and diagnostics on a per-table hub.\n *\n * `ctx.where` is always a constant option path or method name (`options`, `options.data`,\n * `setState`, `destroy`): it reaches fingerprints, docs URLs and issue links unredacted, so it must\n * never carry row keys or cell values.\n */\nexport function createTable<\n T,\n S extends TableState = never,\n const Fs extends readonly AnyFeature[] = [],\n const Sch extends TableSchema | undefined = undefined,\n const M extends InvalidRowsMode = 'drop',\n>(\n options: CreateTableOptions<T, TableStateFor<S, Fs, SchemaRow<T, Sch>>, Sch, M> & {\n features?: Fs\n },\n): Table<\n SchemaRow<T, Sch>,\n TableStateFor<S, Fs, SchemaRow<T, Sch>>,\n M,\n HasSchema<Sch> extends true ? unknown : T\n> &\n ApiOf<Fs, SchemaRow<T, Sch>>\nexport function createTable<T, S extends TableState>(\n initialOptions: TableOptions<T, S>,\n): Table<T, S> {\n let options: TableOptions<T, S> = { ...initialOptions }\n let destroyed = false\n let trigger: Trigger = 'init'\n /** Pipeline run id; each `pipeline:run` increments it. */\n let run = 0\n let data: readonly T[] = EMPTY\n let ingestSeq = 0\n /** Data given by the user has been applied once (`RowModel.isInitialLoad`, §6.6). */\n let loaded = false\n /** The last `data:ingest` failed (op fallback): `status: 'error'` until one succeeds (§6.6). */\n let ingestFailed = false\n /** The ingest whose async schema validation is in flight (`status: 'validating'`); 0: none. */\n let validatingSeq = 0\n /** Rows of the current data that failed the schema (`getInvalidRows`, §5.1). */\n let schemaOutcome: SchemaOutcome | undefined\n /**\n * SSR (§7.2): `options.initialData` until the creation ingest read it (`undefined` with `data`),\n * then its ingested rows while they are the table's data (`initialRows`).\n */\n let initialInput = options.data == null ? options.initialData : undefined\n let initialRows: readonly unknown[] | undefined\n /** Created inside `createDeferred` (§7.2): async work waits for `startTable`. */\n let deferring = deferral.depth > 0\n /**\n * Opt-in parts of the store (`TableInternals.use`): the async request machinery and the server\n * source. A table without an async source creates none (§9.3).\n */\n const extensions = new Map<ExtensionFactory<TableExtension>, TableExtension>()\n /** The server source (`withFetcher`, §7.1), once a fetcher was given. */\n let server: ServerSource | undefined\n\n let controlled = new Set<string>()\n let snapshot: S\n /** The snapshot listeners last saw (`prev` of the next notification). */\n let notified: S\n /** A committed change (state or data) not yet notified. */\n let pending = false\n let notifying = false\n let rounds = 0\n let loopReported = false\n let current: number | undefined\n let listenerSeq = 0\n const listeners = new Map<number, Listener<S>>()\n /** Depth of feature API calls in progress: listeners are notified when the outermost returns. */\n let apiDepth = 0\n /** Data, state or columns changed since the row model was computed. */\n let rowModelDirty = true\n /** Diagnostic context (§8.1): the data mode of each pipeline feature (set once features load). */\n const modes: Record<string, 'client' | 'server'> = {}\n\n const table: Table<T, S> = {\n getState: () => snapshot,\n setState,\n subscribe,\n setOptions,\n getOptions: () => options,\n getData: () => data,\n // Core method: on the literal before installApis, so no feature can take the name.\n getRowModel,\n getInvalidRows: () => schemaOutcome?.invalid ?? EMPTY,\n getDiagnostics: () => hub.getDiagnostics(),\n // Core methods (§8.4), read-only: also on the literal before installApis.\n explain: () => explainTable(explainHost),\n explainRow: (key) => explainRow(explainHost, key),\n refetch,\n destroy,\n }\n\n // Redaction (§8.2): `diagnostics.redact` gives the level or a custom rule; column defs give the\n // sensitive columns and whether the rowKey column is sensitive. Both are read per emit, so\n // `setOptions({ columns })` is followed.\n const redactOption = options.diagnostics?.redact\n const redaction: RedactionOptions = {\n ...(typeof redactOption === 'string' ? { level: redactOption } : {}),\n ...(typeof redactOption === 'function' ? { redact: redactOption } : {}),\n sensitiveColumns,\n // A rowKey path into (or above) a sensitive column reads its data too (#45).\n rowKeySensitive: () => {\n const k = options.rowKey\n return typeof k === 'string' && sensitiveColumns().some((c) => pathsOverlap(k, c))\n },\n }\n const hub = createDiagnostics({\n ...(options.name === undefined ? {} : { name: options.name }),\n table,\n onDiagnostic: (d) => options.onDiagnostic?.(d),\n ...(options.strict === undefined ? {} : { strict: options.strict }),\n getContext: () => ({ trigger, run, mode: modes }),\n getDataRef: () => data,\n redaction,\n })\n // Option validator (§3.4, `table:init`), development only: before anything reads the options.\n // Invalid values throw DK_INVALID_OPTION; unknown / no-effect options are reported on the hub.\n if ((process.env.NODE_ENV !== \"production\")) validateOptions(options, { table: hub.table, emit: hub.emit })\n // Features (§3.3) are read once, at creation. `features` is the listed order (API install, conflict\n // reports); `pipeline` is stage order for the runner. Duplicates throw here (config error).\n const features: readonly AnyFeature[] = options.features ?? EMPTY\n // The feature runtime comes with the features (`defineFeature`): none for a table without.\n const rt = runtimeFor(features)\n const pipeline = rt ? rt.orderFeatures(features, hub.table) : EMPTY\n // Data modes (§7.1): DK_MODE_ORDER (a config error, development). A fetcher without a server-mode\n // feature (DK_FETCHER_WITHOUT_SERVER_MODE) is checked by the server source.\n if ((process.env.NODE_ENV !== \"production\")) checkModeOrder(pipeline, hub.table)\n for (const f of pipeline) if (f.stage !== 'none') modes[f.name] = f.mode ?? 'client'\n // Extension interceptors come first (asyncControl, one per table, installed with the first async\n // source: user / feature interceptors and the core see its signal); the boundary stays\n // outermost. Feature interceptors (pipeline order) come next, then the user's.\n const front: Interceptor<OpName>[] = []\n const featureInterceptors = pipeline.flatMap((f) => f.interceptors ?? EMPTY)\n // The tracer (§3.4, explain timings) is development-only: `(process.env.NODE_ENV !== \"production\")` folds to `false` in production\n // builds, which drops it from the bundle; there it is opt-in with `interceptors: [tracer()]`.\n const traced = (process.env.NODE_ENV !== \"production\") ? [tracer() as Interceptor<OpName>] : EMPTY\n const withFront = (list: readonly Interceptor<OpName>[] | undefined) => [\n ...front,\n ...traced,\n ...featureInterceptors,\n ...(list ?? EMPTY),\n ]\n const runtime = createInterceptorRuntime({\n interceptors: withFront(options.interceptors),\n emit: hub.emit,\n })\n runtime.installBoundary(errorBoundary)\n hub.attach(runtime)\n // Dev check (§5.3): the same `data` array passed again with changed contents (DK_DATA_MUTATED).\n const dataCheck = (process.env.NODE_ENV !== \"production\") ? createDataMutationCheck(hub.emit) : undefined\n // Feature `requires.core` (throws DK_FEATURE_INCOMPATIBLE), duplicate cores, version mismatch\n // (§8.5): development checks (changed 2026-10-13 for §9.3).\n if ((process.env.NODE_ENV !== \"production\")) checkVersions(features, hub.emit, hub.table)\n // Ingest data checks (§5.3) and zero-config columns (§4.1): both read only the first rows.\n // The data checks are developer hints: development only (changed 2026-10-13 for §9.3).\n const dataChecks = (process.env.NODE_ENV !== \"production\") ? createDataChecks(hub.emit) : undefined\n /** Controlled changes not fed back (DK_CONTROLLED_NOT_FED_BACK, development). */\n const feedback = (process.env.NODE_ENV !== \"production\") ? createStateFeedbackCheck(hub.emit) : undefined\n const derivedColumns = createDerivedColumns()\n // Schema ingest (§5.1): `schema` and `invalidRows` are read once (validated above). The step\n // comes with the schema (`withSchema`, `@datakable/core/schema`): a table without one never\n // bundles it.\n const schemaIngest = (options.schema as Partial<TableSchema> | undefined)?.[SCHEMA_INGEST]?.(\n options.invalidRows ?? 'drop',\n () => options.columns,\n )\n // Never silent (§8.6): in production (no option validator) an unwrapped schema would be ignored.\n if (options.schema && !schemaIngest) unwrapped('schema', options.schema, 'withSchema')\n\n function sensitiveColumns(): string[] {\n const out: string[] = []\n for (const c of options.columns ?? EMPTY) {\n const id = columnId(c as { key?: unknown; id?: unknown })\n if (c.sensitive && typeof id === 'string') out.push(id)\n }\n return out\n }\n\n function base(): ContextBase {\n return { table, run, trigger, phase: defaultPhase(), emit: hub.emit }\n }\n\n function op<O extends OpName>(\n name: O,\n input: OpInput<O>,\n where: string,\n core: Core<O>,\n fallback?: unknown,\n ): OpResult<O> {\n const ctx = createContext(name, input, where, base())\n if (fallback !== undefined) ctx.meta.set(FALLBACK, fallback)\n return runtime.run(name, ctx, core)\n }\n\n function withTrigger<R>(t: Trigger, fn: () => R): R {\n const prev = trigger\n trigger = t\n try {\n return fn()\n } finally {\n trigger = prev\n }\n }\n\n // --- state -------------------------------------------------------------------------------------\n\n /** A `__proto__` key (JSON.parse makes it own) is never written into state (#102). */\n function protoKey(k: string): boolean {\n if (k !== PROTO_KEY) return false\n hub.emit('DK_STATE_UNKNOWN_KEY', { slice: '', key: k, known: EMPTY })\n return true\n }\n\n function controlledKeys(state: ControlledState<S> | undefined): Set<string> {\n const keys = new Set<string>()\n if (state) {\n for (const k of Object.keys(state)) if (state[k] !== undefined && !protoKey(k)) keys.add(k)\n }\n return keys\n }\n\n /** `s` with the controlled slices from `options.state`; `s` itself when none differ. */\n function overlay(s: S): S {\n let next: TableState | undefined\n const state = options.state as TableState | undefined\n if (state) {\n for (const k of controlled) {\n if (!Object.is(s[k], state[k])) {\n next ??= { ...s }\n next[k] = state[k]\n }\n }\n }\n return next ? freeze(next as S) : s\n }\n\n function commit(next: S) {\n snapshot = next\n pending = true\n rowModelDirty = true\n }\n\n function warnControlled(dropped: string[] | undefined) {\n if (options.onStateChange || controlled.size === 0) return\n const slices = dropped ?? [...controlled]\n hub.emit('DK_CONTROLLED_WITHOUT_HANDLER', { slices, dropped: dropped !== undefined })\n }\n\n function syncControlled() {\n controlled = controlledKeys(options.state)\n const next = overlay(snapshot)\n if (next !== snapshot) commit(next)\n if ((process.env.NODE_ENV !== \"production\")) feedback?.settle(options.state as TableState | undefined, controlled)\n warnControlled(undefined)\n }\n\n function dispatch(updater: Updater<S>, slot: string) {\n // A method argument, not an option: `where` = `operation table.setState at updater`.\n const partial: Partial<S> =\n typeof updater === 'function'\n ? callUser(\n 'updater',\n updater,\n snapshot,\n undefined,\n slot === 'setState' ? 'table.setState' : `${slot}.setState`,\n )\n : updater\n if (partial === null || typeof partial !== 'object') return\n let next: TableState | undefined\n let changes: TableState | undefined\n let dropped: string[] | undefined\n for (const k of Object.keys(partial)) {\n if (protoKey(k)) continue\n const v = (partial as TableState)[k]\n if (Object.is(snapshot[k], v)) continue\n if (controlled.has(k)) {\n if (options.onStateChange) {\n changes ??= {}\n changes[k] = v\n } else {\n dropped ??= []\n dropped.push(k)\n }\n continue\n }\n next ??= { ...snapshot }\n next[k] = v\n }\n // The owner is told first: if onStateChange throws, nothing is committed (state unchanged).\n if (changes && options.onStateChange) {\n const c = changes as Partial<S>\n if ((process.env.NODE_ENV !== \"production\")) feedback?.ask(Object.keys(changes), trigger)\n callUser('onStateChange', options.onStateChange, (prev: Partial<S>) => ({ ...prev, ...c }))\n if ((process.env.NODE_ENV !== \"production\")) feedback?.asked()\n }\n if (next) commit(freeze(next as S))\n if (dropped) warnControlled(dropped)\n }\n\n /**\n * Notifies listeners until no change is pending. Updates made by listeners are committed at once\n * and notified in the next round (not nested), so every listener sees rounds in order.\n */\n function flush() {\n if (notifying) return\n sync()\n if (!pending) return\n notifying = true\n let rethrow: unknown\n try {\n while (pending && !destroyed) {\n // Server state changed (this round's state): the fetch starts in the same notification.\n sync()\n pending = false\n rounds++\n const prev = notified\n const state = snapshot\n notified = state\n // Listeners read the row model of the state they are notified with.\n ensureRowModel()\n for (const [id, listener] of [...listeners]) {\n // A listener may destroy the table: the rest of the round is not notified.\n if (destroyed) break\n current = id\n try {\n listener(state, prev)\n } catch (e) {\n // strict: a DatakableError (e.g. DK_UPDATE_LOOP) thrown inside the listener.\n if (e instanceof DatakableError) {\n rethrow ??= e\n continue\n }\n try {\n const name = errorName(e)\n hub.emit(\n 'DK_LISTENER_FAILED',\n { listener: id, ...(name === undefined ? {} : { errorName: name }) },\n { cause: e },\n )\n } catch (strictError) {\n rethrow ??= strictError\n }\n }\n }\n }\n } finally {\n notifying = false\n rounds = 0\n loopReported = false\n current = undefined\n }\n if (rethrow !== undefined) throw rethrow\n }\n\n /** `false` (and one `DK_UPDATE_LOOP`) when a re-entrant update would exceed the depth limit. */\n function admit(slices: string[]): boolean {\n if (!notifying || rounds < UPDATE_DEPTH_LIMIT) return true\n if (!loopReported) {\n loopReported = true\n hub.emit('DK_UPDATE_LOOP', {\n limit: UPDATE_DEPTH_LIMIT,\n slices,\n ...(current === undefined ? {} : { listener: current }),\n })\n }\n return false\n }\n\n function destroyedCall(method: string) {\n withTrigger(`api:${method}`, () => hub.emit('DK_TABLE_DESTROYED', { method }))\n }\n\n // --- data --------------------------------------------------------------------------------------\n\n /** Applies ingested data; `given`: it came from a user `options.data` (marks the first load). */\n function setData(next: readonly T[], given: boolean) {\n if (given && !loaded) {\n // isInitialLoad flips: a new row model and a notification even for the same reference.\n loaded = true\n pending = true\n rowModelDirty = true\n }\n if (next === data) return\n data = next\n pending = true\n // After `data` is set: diagnostics dedupe per data reference.\n if ((process.env.NODE_ENV !== \"production\")) dataChecks?.check(data, options.columns)\n // The pipeline runs before the next notification (or on getRowModel), as `pipeline:run` with\n // ctx.meta[FALLBACK] = the last good row model (pipeline/runner.ts).\n rowModelDirty = true\n }\n\n // --- row model ---------------------------------------------------------------------------------\n\n const runner = createPipeline<T>({\n runtime,\n featureRuntime: rt,\n emit: hub.emit,\n features: pipeline,\n listed: features,\n base,\n nextRun: () => ++run,\n getData: () => data,\n getState: () => snapshot,\n getColumns: () => options.columns ?? derivedColumns(data),\n getRowKey: () => options.rowKey,\n isInitialLoad: () => !loaded,\n status,\n issues: (index) => schemaOutcome?.flagged?.get(index),\n flagMode: schemaIngest !== undefined && options.invalidRows === 'flag',\n // Time-sliced work ended (§9.1): 'pending' → the finished row model, never silent (§6.6).\n refresh: (t) => {\n if (destroyed) return\n withTrigger(t, () => {\n touch()\n if (apiDepth === 0) flush()\n })\n },\n })\n\n // Development only, for tests (#98): what the runner still holds.\n if ((process.env.NODE_ENV !== \"production\")) (table as Releasable)[PROBE] = () => runner.probe?.() ?? {}\n\n const explainHost: ExplainHost = {\n table,\n features: pipeline,\n rowModel: getRowModel as () => RowModel<unknown>,\n lastRun: runner.lastRun,\n replay: runner.replayContext,\n data: () => data,\n state: () => snapshot,\n rowKey: () => options.rowKey,\n schemaMode: () => (schemaIngest ? (options.invalidRows ?? 'drop') : undefined),\n schema: () => schemaOutcome,\n diagnostics: () => hub.getDiagnostics(),\n redaction,\n ...(rt ? { detail: rt.explainDetail } : {}),\n }\n\n /**\n * Status from outside the pipeline (§6.6): a failed ingest, a running async schema, the search\n * slice (`pending` / `searching` / `error`), and the extensions' (a failed fetch, an in-flight\n * fetcher / `searchFn`, deferred async work). Precedence: error > fetching > searching >\n * validating > pending > idle.\n */\n function status(): RowModelStatus {\n const search = searchStatus()\n let s: RowModelStatus =\n ingestFailed || search === 'error'\n ? 'error'\n : search === 'searching'\n ? 'searching'\n : validatingSeq !== 0\n ? 'validating'\n : search === 'pending'\n ? 'pending'\n : 'idle'\n for (const e of extensions.values()) {\n const x = e.status?.()\n if (x !== undefined && RANK.indexOf(x) > RANK.indexOf(s)) s = x\n }\n return s\n }\n\n /** Extensions start work that follows state (the fetcher on server state, §7.1). */\n function sync() {\n for (const e of extensions.values()) e.sync?.()\n }\n\n /** The `status` of the first search-stage slice that reports one (§6.3). */\n function searchStatus(): unknown {\n for (const f of pipeline) {\n if (f.stage !== 'search') continue\n const s = (snapshot as Record<string, unknown> | undefined)?.[f.name]\n if (s !== null && typeof s === 'object' && 'status' in s) {\n const v = (s as { status: unknown }).status\n if (v !== 'idle') return v\n }\n }\n return 'idle'\n }\n\n /** A row model change not caused by state: recompute and notify on the next flush. */\n function touch() {\n pending = true\n rowModelDirty = true\n }\n\n /** Recomputes the row model if data, state or columns changed (never after destroy). */\n function ensureRowModel() {\n if (!rowModelDirty || destroyed) return\n rowModelDirty = false\n runner.run()\n }\n\n function getRowModel(): RowModel<T> {\n ensureRowModel()\n // Only empty when destroyed before the first run.\n return (\n runner.current() ?? {\n rows: EMPTY,\n filteredCount: 0,\n totalCount: 0,\n status: status(),\n isInitialLoad: !loaded,\n }\n )\n }\n\n /**\n * Applies the result of the latest `data:ingest`. A fallback (the boundary set `FAILED`) keeps\n * the previous data, sets `status: 'error'` and never marks the table loaded (§6.6, §8.6).\n */\n function applyIngest(out: readonly unknown[], failed: boolean, given: boolean, initial = false) {\n if (validatingSeq !== 0) {\n validatingSeq = 0\n touch()\n }\n if (failed) {\n ingestFailed = true\n touch()\n return\n }\n if (ingestFailed) {\n ingestFailed = false\n touch()\n }\n schemaOutcome = schemaIngest?.outcome(out)\n setData(out as readonly T[], given)\n // `initialData` is the initial async result only while it is the data (§7.2).\n initialRows = initial ? out : undefined\n }\n\n /**\n * `data:ingest` with the previous data as fallback: the schema step (§5.1) runs in its core. An\n * async result is applied if still latest. `fetched`: rows of an applied fetcher result (§7.1),\n * ingested like `options.data` (schema, data checks) and marking the table loaded.\n */\n function ingest(fetched?: readonly unknown[]) {\n const seq = ++ingestSeq\n // At creation, `initialData` stands in for a missing `data` (§7.2); read once.\n const initial = fetched === undefined && initialInput !== undefined\n const input = fetched ?? (initial ? initialInput : options.data)\n initialInput = undefined\n // `data: null` counts as not given (production has no option validator, #94).\n const given = input != null\n const source: Trigger = fetched ? 'fetch' : 'data-change'\n // A validation still in flight is superseded (its result is discarded): not 'validating' now,\n // unless this ingest's own schema step goes async.\n if (validatingSeq !== 0) {\n validatingSeq = 0\n touch()\n }\n try {\n withTrigger(source, () => {\n const ctx = createContext(\n 'data:ingest',\n { data: input ?? EMPTY },\n fetched ? 'fetcher' : initial ? 'options.initialData' : 'options.data',\n base(),\n )\n ctx.meta.set(FALLBACK, data)\n let sync = true\n const out = runtime.run('data:ingest', ctx, (c) => {\n const input = c.input.data as readonly unknown[]\n if (!schemaIngest) return input\n const r = schemaIngest.validate(input, c.emit)\n if (isThenable(r) && seq === ingestSeq && !destroyed) {\n // 'validating' is never silent: a new row model and a notification now (§6.6).\n validatingSeq = seq\n touch()\n if (!sync) flush()\n }\n return r\n })\n sync = false\n if (!isThenable(out)) {\n applyIngest(out, ctx.meta.has(FAILED), given, initial)\n return\n }\n const settle = (d: readonly unknown[], failed: boolean) => {\n if (seq !== ingestSeq || destroyed) return\n withTrigger(source, () => {\n applyIngest(d, failed, given, initial)\n flush()\n })\n }\n Promise.resolve(out).then(\n (d) => settle(d, ctx.meta.has(FAILED)),\n // A DatakableError the boundary rethrew (strict, or `invalidRows: 'throw'` with an async\n // schema, already reported): the previous data is kept with 'error'. No unhandled\n // rejection either way (§8.6).\n () => settle(data, true),\n )\n })\n } finally {\n // Dev (§5.3): fingerprint `data` after the core read it, so the check never takes reads\n // first; also when the ingest threw, so a later same-reference check compares this data.\n if ((process.env.NODE_ENV !== \"production\") && !fetched) dataCheck?.remember(options.data)\n }\n }\n\n // --- API ---------------------------------------------------------------------------------------\n\n /** `state:dispatch` (where = `slot`, a constant method / feature name); notifies unless batched. */\n function update(updater: Updater<S>, slot: string) {\n void op('state:dispatch', { updater }, slot, (): undefined => {\n dispatch(updater, slot)\n })\n if (apiDepth === 0) flush()\n }\n\n function setState(updater: Updater<S>) {\n if (destroyed) return destroyedCall('setState')\n if (!admit(typeof updater === 'function' ? [] : Object.keys(updater ?? {}))) return\n withTrigger('api:setState', () => update(updater, 'setState'))\n }\n\n // --- features ----------------------------------------------------------------------------------\n\n /** A feature's `ctx.setState`: replaces its own slice (trigger: the API call's, if any). */\n function setSlice(name: string, updater: SliceUpdater<unknown>) {\n if (destroyed) return destroyedCall(`${name}.setState`)\n if (!admit([name])) return\n const slice: Updater<S> =\n typeof updater === 'function'\n ? (prev) => ({ [name]: (updater as (p: unknown) => unknown)(prev[name]) }) as Partial<S>\n : ({ [name]: updater } as Partial<S>)\n update(slice, name)\n }\n\n /** Runs a feature API method (wrapped once by `installApis`). */\n function callApi(method: string, fn: () => unknown, ifDestroyed?: () => unknown): unknown {\n if (destroyed) {\n destroyedCall(method)\n return ifDestroyed?.()\n }\n return withTrigger(`api:${method}`, () => {\n apiDepth++\n try {\n return fn()\n } finally {\n apiDepth--\n if (apiDepth === 0) flush()\n }\n })\n }\n\n function subscribe(listener: Listener<S>): () => void {\n if (destroyed) {\n destroyedCall('subscribe')\n return () => {}\n }\n const id = ++listenerSeq\n listeners.set(id, listener)\n return () => {\n listeners.delete(id)\n }\n }\n\n function setOptions(partial: Partial<TableOptions<T, S>>) {\n if (destroyed) return destroyedCall('setOptions')\n if (!admit(Object.keys(partial.state ?? {}))) return\n withTrigger('setOptions', () => {\n const previous = options\n const next = { ...options, ...partial }\n // Option validator (§3.4, `table:setOptions`, development): an invalid value throws before\n // anything changes. Read-once options (`features`, `timeout`, `diagnostics`, …) keep their\n // value in every build.\n if ((process.env.NODE_ENV !== \"production\")) validateOptionChange(partial, next, previous, { table: hub.table, emit: hub.emit })\n else keepReadOnce(partial, next, previous)\n if ('fetcher' in partial) useServer(next.fetcher, 'setOptions')?.check(next.fetcher)\n void op('table:setOptions', { options: next, previous }, 'options', (): undefined => {\n options = next\n if (next.interceptors !== previous.interceptors) {\n runtime.setInterceptors(withFront(next.interceptors))\n }\n if ('state' in partial || 'onStateChange' in partial) syncControlled()\n if (next.columns !== previous.columns || next.rowKey !== previous.rowKey) {\n rowModelDirty = true\n pending = true\n }\n // The page count changed (§6.5): listeners re-read it (and pagination clamps).\n if (next.rowCount !== previous.rowCount) pending = true\n // A new fetcher reference runs at once, even with the same params (flush → sync).\n if (next.fetcher !== previous.fetcher) server?.reset()\n // New data is checked when applied (setData); same data with new columns is checked here.\n if (next.data !== previous.data) ingest()\n else if ((process.env.NODE_ENV !== \"production\")) {\n if ('data' in partial) dataCheck?.check(next.data)\n if (next.columns !== previous.columns) dataChecks?.check(data, next.columns)\n }\n })\n flush()\n })\n }\n\n function destroy() {\n if (destroyed) return\n withTrigger('api:destroy', () => {\n try {\n void op('table:destroy', undefined, 'destroy', (): undefined => {\n destroyed = true\n })\n } finally {\n // Even if an interceptor skipped the core: the table is destroyed.\n destroyed = true\n ingestSeq++\n listeners.clear()\n runner.dispose()\n // Features drop their per-instance caches (#98).\n for (const f of pipeline) (f as Releasable)[RELEASE]?.()\n if ((process.env.NODE_ENV !== \"production\")) feedback?.dispose()\n }\n })\n }\n\n // --- extensions (§9.3) ---------------------------------------------------------------------\n\n function batch<R>(t: Trigger, fn: () => R): R {\n return withTrigger(t, () => {\n apiDepth++\n try {\n return fn()\n } finally {\n apiDepth--\n if (apiDepth === 0) flush()\n }\n })\n }\n\n const host: TableHost = {\n table: table as unknown as Table<unknown, TableState>,\n name: hub.table,\n emit: hub.emit,\n runtime,\n features: pipeline,\n options: () => options as TableOptions<unknown>,\n state: () => snapshot,\n base,\n destroyed: () => destroyed,\n loaded: () => loaded,\n status,\n touch,\n notify: () => {\n if (apiDepth === 0) flush()\n },\n batch,\n ingest: (rows) => ingest(rows),\n intercept(interceptor) {\n front.push(interceptor)\n runtime.setInterceptors(withFront(options.interceptors))\n },\n deferring: () => deferring,\n use,\n }\n\n function use<E extends TableExtension>(factory: ExtensionFactory<E>): E {\n let e = extensions.get(factory as ExtensionFactory<TableExtension>) as E | undefined\n if (!e) {\n e = factory(host)\n extensions.set(factory as ExtensionFactory<TableExtension>, e)\n }\n return e\n }\n\n /** The server source a `withFetcher` fetcher brings (created once); else the current one. */\n function useServer(fetcher: unknown, phase?: 'setOptions'): ServerSource | undefined {\n const factory = (fetcher as Partial<ServerFetcher<unknown>> | undefined)?.[SERVER_SOURCE]\n if (factory) server = use(factory)\n // Never silent (§8.6): in production an unwrapped fetcher would never run.\n else if (fetcher) unwrapped('fetcher', fetcher, 'withFetcher', 'server', phase)\n return server\n }\n\n /**\n * `DK_INVALID_OPTION` for a schema / fetcher not wrapped with its opt-in import (§5.1, §7.1). A\n * production check: in development the option validator reports it first, with the full text.\n */\n function unwrapped(\n path: 'schema' | 'fetcher',\n value: unknown,\n wrap: string,\n entry: string = path,\n phase: 'init' | 'setOptions' = 'init',\n ): never {\n return throwConfigError(\n 'DK_INVALID_OPTION',\n {\n path,\n expected: `wrapped|${wrap}|${path}|${entry}`, // prose key (diagnostics/prose.ts)\n received: typeof value,\n suggestions: [],\n phase,\n },\n { table: hub.table, trigger: phase },\n )\n }\n\n /**\n * Runs the fetcher again with the current params (§7.1); never rejects. Without a fetcher:\n * `{ status: 'applied' }` at once. Deferred: settles after `startTable` (#90, `server.sync`).\n */\n function refetch(): Promise<FetchOutcome> {\n if (destroyed) {\n destroyedCall('refetch')\n return Promise.resolve({ status: 'superseded' })\n }\n return (\n withTrigger('api:refetch', () => server?.sync(true)) ?? Promise.resolve({ status: 'applied' })\n )\n }\n\n /** `startTable` (§7.2): the deferred work starts; listeners see the new status at once. */\n function start() {\n if (!deferring || destroyed) return\n deferring = false\n let had = false\n for (const e of extensions.values()) if (e.start?.()) had = true\n if (!had) return\n // The pipeline re-runs: 'pending' ends and the search feature's check starts its searchFn.\n touch()\n withTrigger('hydrate', () => flush())\n }\n\n setTableInternals(table, {\n features: pipeline,\n name: options.name,\n rowCount: () => (typeof options.fetcher === 'function' ? server?.rowCount() : options.rowCount),\n hasFetcher: () => typeof options.fetcher === 'function',\n emit: hub.emit,\n use,\n peek: (factory) => extensions.get(factory as ExtensionFactory<TableExtension>) as never,\n extensions: () => extensions.values(),\n start,\n initialRows: () =>\n initialRows !== undefined && initialRows === data ? initialRows : undefined,\n })\n\n // --- init --------------------------------------------------------------------------------------\n\n controlled = controlledKeys(options.state)\n if ((process.env.NODE_ENV !== \"production\")) feedback?.settle(options.state as TableState | undefined, controlled)\n // Feature `initialState()` slices, with `options.initialState` on top per slice.\n // A copy without a `__proto__` key (#102): safe for `Object.assign` in initialSlices.\n const restored: TableState = { ...options.initialState }\n if (Object.hasOwn(restored, PROTO_KEY) && protoKey(PROTO_KEY)) delete restored[PROTO_KEY]\n snapshot = overlay(freeze((rt ? rt.initialSlices(features, restored, hub.emit) : restored) as S))\n notified = snapshot\n // Merges the feature APIs onto the table; a name clash throws DK_FEATURE_API_CONFLICT.\n rt?.installApis(features, {\n table: table as unknown as Table<unknown, TableState>,\n tableName: hub.table,\n emit: hub.emit,\n getSlice: (name) => snapshot[name],\n setSlice,\n call: callApi,\n })\n // Server source (§7.1): with a `withFetcher` fetcher (throws DK_FETCHER_WITHOUT_SERVER_MODE).\n useServer(options.fetcher)\n withTrigger('init', () => {\n // `void`: sync ops never return a promise (op kinds, §3.4).\n void op('table:init', { options }, 'options', (): undefined => {\n // Ingest first: dedupe is per data reference, so warnings follow the initial data.\n ingest()\n warnControlled(undefined)\n })\n // Server source (§7.1): the first request starts now ('fetching', isInitialLoad: true), unless\n // initialData answered the initial server state (§7.2).\n sync()\n })\n pending = false\n return table\n}\n"],"mappings":"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","names":["import_runtime","import_codes","sync","input"]}