@datakable/core 1.0.0 → 1.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.
- package/README.md +4 -2
- package/dist/catalog/codes.cjs +12 -8
- package/dist/catalog/codes.cjs.map +1 -1
- package/dist/catalog/codes.js +12 -8
- package/dist/catalog/codes.js.map +1 -1
- package/dist/catalog/slots.cjs +10 -6
- package/dist/catalog/slots.cjs.map +1 -1
- package/dist/catalog/slots.js +10 -6
- package/dist/catalog/slots.js.map +1 -1
- package/dist/{codes-BKdS9EiO.d.cts → codes-B9bCK73-.d.cts} +46 -8
- package/dist/{codes-BKdS9EiO.d.ts → codes-B9bCK73-.d.ts} +46 -8
- package/dist/column/column-def.cjs.map +1 -1
- package/dist/column/get-value.cjs +6 -1
- package/dist/column/get-value.cjs.map +1 -1
- package/dist/column/get-value.js +6 -1
- package/dist/column/get-value.js.map +1 -1
- package/dist/column-filters.d.cts +2 -2
- package/dist/column-filters.d.ts +2 -2
- package/dist/diagnostics/build.cjs +10 -4
- package/dist/diagnostics/build.cjs.map +1 -1
- package/dist/diagnostics/build.js +8 -3
- package/dist/diagnostics/build.js.map +1 -1
- package/dist/diagnostics/catalog.cjs +11 -5
- package/dist/diagnostics/catalog.cjs.map +1 -1
- package/dist/diagnostics/catalog.js +10 -5
- package/dist/diagnostics/catalog.js.map +1 -1
- package/dist/diagnostics/codes.cjs +12 -8
- package/dist/diagnostics/codes.cjs.map +1 -1
- package/dist/diagnostics/codes.js +12 -8
- package/dist/diagnostics/codes.js.map +1 -1
- package/dist/diagnostics/console.cjs +13 -6
- package/dist/diagnostics/console.cjs.map +1 -1
- package/dist/diagnostics/console.js +13 -6
- package/dist/diagnostics/console.js.map +1 -1
- package/dist/diagnostics/env.cjs +1 -0
- package/dist/diagnostics/env.cjs.map +1 -1
- package/dist/diagnostics/env.js +1 -0
- package/dist/diagnostics/env.js.map +1 -1
- package/dist/diagnostics/explain-text.cjs +2 -1
- package/dist/diagnostics/explain-text.cjs.map +1 -1
- package/dist/diagnostics/explain-text.js +2 -1
- package/dist/diagnostics/explain-text.js.map +1 -1
- package/dist/diagnostics/explain.cjs +3 -2
- package/dist/diagnostics/explain.cjs.map +1 -1
- package/dist/diagnostics/explain.js +3 -2
- package/dist/diagnostics/explain.js.map +1 -1
- package/dist/diagnostics/hub.cjs +6 -5
- package/dist/diagnostics/hub.cjs.map +1 -1
- package/dist/diagnostics/hub.js +7 -6
- package/dist/diagnostics/hub.js.map +1 -1
- package/dist/diagnostics/process-guard.cjs +26 -0
- package/dist/diagnostics/process-guard.cjs.map +1 -0
- package/dist/diagnostics/process-guard.js +9 -0
- package/dist/diagnostics/process-guard.js.map +1 -0
- package/dist/diagnostics/prose.cjs +120 -0
- package/dist/diagnostics/prose.cjs.map +1 -0
- package/dist/diagnostics/prose.js +93 -0
- package/dist/diagnostics/prose.js.map +1 -0
- package/dist/diagnostics/redact.cjs +7 -4
- package/dist/diagnostics/redact.cjs.map +1 -1
- package/dist/diagnostics/redact.js +6 -4
- package/dist/diagnostics/redact.js.map +1 -1
- package/dist/diagnostics/trace-store.cjs +6 -0
- package/dist/diagnostics/trace-store.cjs.map +1 -1
- package/dist/diagnostics/trace-store.js +4 -0
- package/dist/diagnostics/trace-store.js.map +1 -1
- package/dist/diagnostics/tracer.cjs +74 -13
- package/dist/diagnostics/tracer.cjs.map +1 -1
- package/dist/diagnostics/tracer.js +75 -14
- package/dist/diagnostics/tracer.js.map +1 -1
- package/dist/diagnostics/types.cjs.map +1 -1
- package/dist/{explain-aagaYHcy.d.cts → explain-Q8Cg0cZy.d.cts} +13 -4
- package/dist/{explain-DcUZfFh5.d.ts → explain-i0OATi_W.d.ts} +13 -4
- package/dist/feature/codes.cjs +1 -0
- package/dist/feature/codes.cjs.map +1 -1
- package/dist/feature/codes.js +1 -0
- package/dist/feature/codes.js.map +1 -1
- package/dist/feature/define.cjs +3 -1
- package/dist/feature/define.cjs.map +1 -1
- package/dist/feature/define.js +3 -1
- package/dist/feature/define.js.map +1 -1
- package/dist/feature/install.cjs +4 -3
- package/dist/feature/install.cjs.map +1 -1
- package/dist/feature/install.js +4 -3
- package/dist/feature/install.js.map +1 -1
- package/dist/feature/runtime.cjs.map +1 -1
- package/dist/feature/runtime.js.map +1 -1
- package/dist/features/column-filters/codes.cjs +1 -0
- package/dist/features/column-filters/codes.cjs.map +1 -1
- package/dist/features/column-filters/codes.js +1 -0
- package/dist/features/column-filters/codes.js.map +1 -1
- package/dist/features/column-filters/column-filters.cjs +4 -2
- package/dist/features/column-filters/column-filters.cjs.map +1 -1
- package/dist/features/column-filters/column-filters.js +4 -2
- package/dist/features/column-filters/column-filters.js.map +1 -1
- package/dist/features/column-filters/match.cjs +5 -5
- package/dist/features/column-filters/match.cjs.map +1 -1
- package/dist/features/column-filters/match.js +5 -5
- package/dist/features/column-filters/match.js.map +1 -1
- package/dist/features/pagination/codes.cjs +6 -3
- package/dist/features/pagination/codes.cjs.map +1 -1
- package/dist/features/pagination/codes.js +6 -3
- package/dist/features/pagination/codes.js.map +1 -1
- package/dist/features/pagination/pagination.cjs +19 -14
- package/dist/features/pagination/pagination.cjs.map +1 -1
- package/dist/features/pagination/pagination.js +19 -14
- package/dist/features/pagination/pagination.js.map +1 -1
- package/dist/features/search/codes.cjs +1 -0
- package/dist/features/search/codes.cjs.map +1 -1
- package/dist/features/search/codes.js +1 -0
- package/dist/features/search/codes.js.map +1 -1
- package/dist/features/search/search-index.cjs +105 -48
- package/dist/features/search/search-index.cjs.map +1 -1
- package/dist/features/search/search-index.js +106 -49
- package/dist/features/search/search-index.js.map +1 -1
- package/dist/features/search/search.cjs +82 -24
- package/dist/features/search/search.cjs.map +1 -1
- package/dist/features/search/search.js +82 -24
- package/dist/features/search/search.js.map +1 -1
- package/dist/features/search/skipped-codes.cjs +45 -0
- package/dist/features/search/skipped-codes.cjs.map +1 -0
- package/dist/features/search/skipped-codes.js +20 -0
- package/dist/features/search/skipped-codes.js.map +1 -0
- package/dist/features/sorting/codes.cjs +1 -0
- package/dist/features/sorting/codes.cjs.map +1 -1
- package/dist/features/sorting/codes.js +1 -0
- package/dist/features/sorting/codes.js.map +1 -1
- package/dist/features/sorting/sorting.cjs +19 -23
- package/dist/features/sorting/sorting.cjs.map +1 -1
- package/dist/features/sorting/sorting.js +19 -23
- package/dist/features/sorting/sorting.js.map +1 -1
- package/dist/features/sorting/strategy.cjs +4 -4
- package/dist/features/sorting/strategy.cjs.map +1 -1
- package/dist/features/sorting/strategy.js +4 -4
- package/dist/features/sorting/strategy.js.map +1 -1
- package/dist/features/validity/codes.cjs +1 -0
- package/dist/features/validity/codes.cjs.map +1 -1
- package/dist/features/validity/codes.js +1 -0
- package/dist/features/validity/codes.js.map +1 -1
- package/dist/features/validity/validity.cjs +3 -3
- package/dist/features/validity/validity.cjs.map +1 -1
- package/dist/features/validity/validity.js +3 -3
- package/dist/features/validity/validity.js.map +1 -1
- package/dist/index.d.cts +16 -11
- package/dist/index.d.ts +16 -11
- package/dist/ingest/data-check-codes.cjs +4 -2
- package/dist/ingest/data-check-codes.cjs.map +1 -1
- package/dist/ingest/data-check-codes.js +4 -2
- package/dist/ingest/data-check-codes.js.map +1 -1
- package/dist/ingest/data-checks.cjs +1 -1
- package/dist/ingest/data-checks.cjs.map +1 -1
- package/dist/ingest/data-checks.js +1 -1
- package/dist/ingest/data-checks.js.map +1 -1
- package/dist/ingest/row-key-codes.cjs +1 -0
- package/dist/ingest/row-key-codes.cjs.map +1 -1
- package/dist/ingest/row-key-codes.js +1 -0
- package/dist/ingest/row-key-codes.js.map +1 -1
- package/dist/ingest/row-key.cjs +23 -20
- package/dist/ingest/row-key.cjs.map +1 -1
- package/dist/ingest/row-key.js +23 -20
- package/dist/ingest/row-key.js.map +1 -1
- package/dist/ingest/schema-codes.cjs +1 -0
- package/dist/ingest/schema-codes.cjs.map +1 -1
- package/dist/ingest/schema-codes.js +1 -0
- package/dist/ingest/schema-codes.js.map +1 -1
- package/dist/ingest/unique-fields.cjs +2 -2
- package/dist/ingest/unique-fields.cjs.map +1 -1
- package/dist/ingest/unique-fields.js +2 -2
- package/dist/ingest/unique-fields.js.map +1 -1
- package/dist/intercept/boundary.cjs +4 -2
- package/dist/intercept/boundary.cjs.map +1 -1
- package/dist/intercept/boundary.js +4 -2
- package/dist/intercept/boundary.js.map +1 -1
- package/dist/intercept/cell-batch.cjs +7 -4
- package/dist/intercept/cell-batch.cjs.map +1 -1
- package/dist/intercept/cell-batch.js +7 -4
- package/dist/intercept/cell-batch.js.map +1 -1
- package/dist/intercept/codes.cjs +1 -0
- package/dist/intercept/codes.cjs.map +1 -1
- package/dist/intercept/codes.js +1 -0
- package/dist/intercept/codes.js.map +1 -1
- package/dist/intercept/fallbacks.cjs +12 -20
- package/dist/intercept/fallbacks.cjs.map +1 -1
- package/dist/intercept/fallbacks.js +12 -20
- package/dist/intercept/fallbacks.js.map +1 -1
- package/dist/intercept/runtime.cjs +7 -9
- package/dist/intercept/runtime.cjs.map +1 -1
- package/dist/intercept/runtime.js +7 -9
- package/dist/intercept/runtime.js.map +1 -1
- package/dist/messages/index.cjs +4 -1
- package/dist/messages/index.cjs.map +1 -1
- package/dist/messages/index.js +4 -1
- package/dist/messages/index.js.map +1 -1
- package/dist/pagination.d.cts +2 -2
- package/dist/pagination.d.ts +2 -2
- package/dist/pipeline/codes.cjs +1 -0
- package/dist/pipeline/codes.cjs.map +1 -1
- package/dist/pipeline/codes.js +1 -0
- package/dist/pipeline/codes.js.map +1 -1
- package/dist/pipeline/column-cache.cjs +94 -76
- package/dist/pipeline/column-cache.cjs.map +1 -1
- package/dist/pipeline/column-cache.js +92 -75
- package/dist/pipeline/column-cache.js.map +1 -1
- package/dist/pipeline/dev-checks.cjs +1 -0
- package/dist/pipeline/dev-checks.cjs.map +1 -1
- package/dist/pipeline/dev-checks.js +1 -0
- package/dist/pipeline/dev-checks.js.map +1 -1
- package/dist/pipeline/env-codes.cjs +3 -2
- package/dist/pipeline/env-codes.cjs.map +1 -1
- package/dist/pipeline/env-codes.js +3 -2
- package/dist/pipeline/env-codes.js.map +1 -1
- package/dist/pipeline/perf-codes.cjs +1 -0
- package/dist/pipeline/perf-codes.cjs.map +1 -1
- package/dist/pipeline/perf-codes.js +1 -0
- package/dist/pipeline/perf-codes.js.map +1 -1
- package/dist/pipeline/row.cjs +8 -7
- package/dist/pipeline/row.cjs.map +1 -1
- package/dist/pipeline/row.js +8 -7
- package/dist/pipeline/row.js.map +1 -1
- package/dist/pipeline/runner.cjs +17 -9
- package/dist/pipeline/runner.cjs.map +1 -1
- package/dist/pipeline/runner.js +17 -9
- package/dist/pipeline/runner.js.map +1 -1
- package/dist/pipeline/slice.cjs +3 -1
- package/dist/pipeline/slice.cjs.map +1 -1
- package/dist/pipeline/slice.js +3 -1
- package/dist/pipeline/slice.js.map +1 -1
- package/dist/schema.d.cts +2 -2
- package/dist/schema.d.ts +2 -2
- package/dist/{search-async-entry-C3mXxLP8.d.cts → search-async-entry-CuLYPfY_.d.cts} +2 -2
- package/dist/{search-async-entry-BmQYT120.d.ts → search-async-entry-Cx7xpuVZ.d.ts} +2 -2
- package/dist/search-async.d.cts +3 -3
- package/dist/search-async.d.ts +3 -3
- package/dist/search.d.cts +8 -6
- package/dist/search.d.ts +8 -6
- package/dist/server.d.cts +3 -3
- package/dist/server.d.ts +3 -3
- package/dist/sorting.d.cts +6 -3
- package/dist/sorting.d.ts +6 -3
- package/dist/source/codes.cjs +1 -0
- package/dist/source/codes.cjs.map +1 -1
- package/dist/source/codes.js +1 -0
- package/dist/source/codes.js.map +1 -1
- package/dist/source/fetch-codes.cjs +1 -0
- package/dist/source/fetch-codes.cjs.map +1 -1
- package/dist/source/fetch-codes.js +1 -0
- package/dist/source/fetch-codes.js.map +1 -1
- package/dist/table/codes.cjs +1 -0
- package/dist/table/codes.cjs.map +1 -1
- package/dist/table/codes.js +1 -0
- package/dist/table/codes.js.map +1 -1
- package/dist/table/create-table.cjs +39 -9
- package/dist/table/create-table.cjs.map +1 -1
- package/dist/table/create-table.js +39 -9
- package/dist/table/create-table.js.map +1 -1
- package/dist/table/data-mutation.cjs +1 -0
- package/dist/table/data-mutation.cjs.map +1 -1
- package/dist/table/data-mutation.js +1 -0
- package/dist/table/data-mutation.js.map +1 -1
- package/dist/table/internals.cjs.map +1 -1
- package/dist/table/internals.js.map +1 -1
- package/dist/table/ssr-codes.cjs +1 -0
- package/dist/table/ssr-codes.cjs.map +1 -1
- package/dist/table/ssr-codes.js +1 -0
- package/dist/table/ssr-codes.js.map +1 -1
- package/dist/table/ssr.cjs +4 -1
- package/dist/table/ssr.cjs.map +1 -1
- package/dist/table/ssr.js +4 -1
- package/dist/table/ssr.js.map +1 -1
- package/dist/table/state-feedback.cjs +19 -0
- package/dist/table/state-feedback.cjs.map +1 -1
- package/dist/table/state-feedback.js +19 -0
- package/dist/table/state-feedback.js.map +1 -1
- package/dist/table/types.cjs.map +1 -1
- package/dist/table/types.js.map +1 -1
- package/dist/validity.d.cts +2 -2
- package/dist/validity.d.ts +2 -2
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/versioning/codes.cjs +18 -0
- package/dist/versioning/codes.cjs.map +1 -1
- package/dist/versioning/codes.js +18 -0
- package/dist/versioning/codes.js.map +1 -1
- package/dist/versioning/registry.cjs +4 -2
- package/dist/versioning/registry.cjs.map +1 -1
- package/dist/versioning/registry.js +4 -2
- package/dist/versioning/registry.js.map +1 -1
- package/package.json +39 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/dev-checks.ts"],"sourcesContent":["import { describeReturn } from '../catalog/slots'\nimport { defineDiagnostic } from '../diagnostics/catalog'\nimport type { Emit } from '../diagnostics/types'\n\n/**\n * `devChecks` on `pipeline:step` (§3.4, §8.3): a feature `rowModel` must return a `Uint32Array` of\n * row indices and must not write to its input (the input is the previous step's memoised output).\n * Dev only: the definitions, their text and the checks sit behind `(process.env.NODE_ENV !== \"production\")`, so a production bundle has\n * none of it. They run only when a step is recomputed (memo misses), with bounded cost.\n */\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_FEATURE_BAD_OUTPUT: {\n feature: string\n /** What `rowModel` returned, as a type (`an Array`); never the value. */\n received: string\n /** An out-of-range index (a `Uint32Array` output): its value and the row count. */\n index?: number\n rowCount?: number\n }\n DK_FEATURE_MUTATED_INPUT: {\n feature: string\n }\n }\n}\n\nexport const stepDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_FEATURE_BAD_OUTPUT',\n level: 'error',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n problem: (d) =>\n d.index === undefined\n ? `feature \"${d.feature}\" rowModel() returned ${d.received}, not a Uint32Array of ` +\n 'row indices'\n : `feature \"${d.feature}\" rowModel() returned row index ${d.index}, but the data has ` +\n `${d.rowCount} rows`,\n impact: () => 'the step passed its input through (the feature had no effect this run)',\n fix: (d) => [\n `return a Uint32Array of row indices from rowModel() of feature \"${d.feature}\": ` +\n 'indices.subarray(0, n), a new Uint32Array(n) you filled, or Uint32Array.from(list)',\n d.index === undefined\n ? 'rowModel() is synchronous; return the input indices when the feature is inactive'\n : 'only return indices taken from the input (each is a position in options.data)',\n ],\n }),\n defineDiagnostic({\n code: 'DK_FEATURE_MUTATED_INPUT',\n level: 'warn',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n problem: (d) => `feature \"${d.feature}\" rowModel() wrote to its input indices`,\n impact: () =>\n \"the input is the previous step's memoised output: later runs can show rows in the \" +\n 'wrong order or the wrong rows until the data changes',\n fix: (d) => [\n `copy before changing in feature \"${d.feature}\": indices.slice().sort(...) instead of ` +\n 'indices.sort(...)',\n 'or write the result into a new Uint32Array',\n ],\n }),\n ]\n : []\n\n/** At most this many input positions are hashed per step. */\nconst SAMPLES = 64\n\n/**\n * A bounded fingerprint of an index array: FNV-1a over the length and at most {@link SAMPLES}\n * evenly spaced positions (every position when shorter; position 0 always).\n */\nexport function indexPrint(indices: Uint32Array): number {\n const n = indices.length\n const stride = n <= SAMPLES ? 1 : Math.floor(n / SAMPLES)\n let h = Math.imul(0x811c9dc5 ^ n, 0x01000193)\n for (let i = 0, k = 0; i < n && k < SAMPLES; i += stride, k++) {\n h = Math.imul(h ^ (indices[i] as number), 0x01000193)\n }\n return h >>> 0\n}\n\n/** The first index `>= rowCount`, or -1. */\nfunction outOfRange(out: Uint32Array, rowCount: number): number {\n for (let i = 0; i < out.length; i++) if ((out[i] as number) >= rowCount) return out[i] as number\n return -1\n}\n\n/**\n * Checks one recomputed step (dev): reports a mutated input (`before` = {@link indexPrint} of the\n * input before `rowModel` ran) and a bad output. Returns whether `out` can be used.\n */\nexport function checkStep(\n emit: Emit,\n feature: string,\n input: Uint32Array,\n before: number,\n out: unknown,\n rowCount: number,\n): boolean {\n if (indexPrint(input) !== before) emit('DK_FEATURE_MUTATED_INPUT', { feature })\n if (!(out instanceof Uint32Array)) {\n emit('DK_FEATURE_BAD_OUTPUT', { feature, received: describeReturn(out) })\n return false\n }\n const index = outOfRange(out, rowCount)\n if (index < 0) return true\n emit('DK_FEATURE_BAD_OUTPUT', { feature, received: 'a Uint32Array', index, rowCount })\n return false\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAC/B,qBAAiC;
|
|
1
|
+
{"version":3,"sources":["../../src/pipeline/dev-checks.ts"],"sourcesContent":["import { describeReturn } from '../catalog/slots'\nimport { defineDiagnostic } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport type { Emit } from '../diagnostics/types'\n\n/**\n * `devChecks` on `pipeline:step` (§3.4, §8.3): a feature `rowModel` must return a `Uint32Array` of\n * row indices and must not write to its input (the input is the previous step's memoised output).\n * Dev only: the definitions, their text and the checks sit behind `(process.env.NODE_ENV !== \"production\")`, so a production bundle has\n * none of it. They run only when a step is recomputed (memo misses), with bounded cost.\n */\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_FEATURE_BAD_OUTPUT: {\n feature: string\n /** What `rowModel` returned, as a type (`an Array`); never the value. */\n received: string\n /** An out-of-range index (a `Uint32Array` output): its value and the row count. */\n index?: number\n rowCount?: number\n }\n DK_FEATURE_MUTATED_INPUT: {\n feature: string\n }\n }\n}\n\nexport const stepDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_FEATURE_BAD_OUTPUT',\n level: 'error',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n problem: (d) =>\n d.index === undefined\n ? `feature \"${d.feature}\" rowModel() returned ${d.received}, not a Uint32Array of ` +\n 'row indices'\n : `feature \"${d.feature}\" rowModel() returned row index ${d.index}, but the data has ` +\n `${d.rowCount} rows`,\n impact: () => 'the step passed its input through (the feature had no effect this run)',\n fix: (d) => [\n `return a Uint32Array of row indices from rowModel() of feature \"${d.feature}\": ` +\n 'indices.subarray(0, n), a new Uint32Array(n) you filled, or Uint32Array.from(list)',\n d.index === undefined\n ? 'rowModel() is synchronous; return the input indices when the feature is inactive'\n : 'only return indices taken from the input (each is a position in options.data)',\n ],\n }),\n defineDiagnostic({\n code: 'DK_FEATURE_MUTATED_INPUT',\n level: 'warn',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n problem: (d) => `feature \"${d.feature}\" rowModel() wrote to its input indices`,\n impact: () =>\n \"the input is the previous step's memoised output: later runs can show rows in the \" +\n 'wrong order or the wrong rows until the data changes',\n fix: (d) => [\n `copy before changing in feature \"${d.feature}\": indices.slice().sort(...) instead of ` +\n 'indices.sort(...)',\n 'or write the result into a new Uint32Array',\n ],\n }),\n ]\n : []\n\n/** At most this many input positions are hashed per step. */\nconst SAMPLES = 64\n\n/**\n * A bounded fingerprint of an index array: FNV-1a over the length and at most {@link SAMPLES}\n * evenly spaced positions (every position when shorter; position 0 always).\n */\nexport function indexPrint(indices: Uint32Array): number {\n const n = indices.length\n const stride = n <= SAMPLES ? 1 : Math.floor(n / SAMPLES)\n let h = Math.imul(0x811c9dc5 ^ n, 0x01000193)\n for (let i = 0, k = 0; i < n && k < SAMPLES; i += stride, k++) {\n h = Math.imul(h ^ (indices[i] as number), 0x01000193)\n }\n return h >>> 0\n}\n\n/** The first index `>= rowCount`, or -1. */\nfunction outOfRange(out: Uint32Array, rowCount: number): number {\n for (let i = 0; i < out.length; i++) if ((out[i] as number) >= rowCount) return out[i] as number\n return -1\n}\n\n/**\n * Checks one recomputed step (dev): reports a mutated input (`before` = {@link indexPrint} of the\n * input before `rowModel` ran) and a bad output. Returns whether `out` can be used.\n */\nexport function checkStep(\n emit: Emit,\n feature: string,\n input: Uint32Array,\n before: number,\n out: unknown,\n rowCount: number,\n): boolean {\n if (indexPrint(input) !== before) emit('DK_FEATURE_MUTATED_INPUT', { feature })\n if (!(out instanceof Uint32Array)) {\n emit('DK_FEATURE_BAD_OUTPUT', { feature, received: describeReturn(out) })\n return false\n }\n const index = outOfRange(out, rowCount)\n if (index < 0) return true\n emit('DK_FEATURE_BAD_OUTPUT', { feature, received: 'a Uint32Array', index, rowCount })\n return false\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAC/B,qBAAiC;AACjC,2BAAO;AA0BA,IAAM,kBAAmB,QAAQ,IAAI,aAAa,eACrD;AAAA,MACE,iCAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IAClD,SAAS,CAAC,MACR,EAAE,UAAU,SACR,YAAY,EAAE,OAAO,yBAAyB,EAAE,QAAQ,uCAExD,YAAY,EAAE,OAAO,mCAAmC,EAAE,KAAK,sBAC5D,EAAE,QAAQ;AAAA,IACnB,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,mEAAmE,EAAE,OAAO;AAAA,MAE5E,EAAE,UAAU,SACR,qFACA;AAAA,IACN;AAAA,EACF,CAAC;AAAA,MACD,iCAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IAClD,SAAS,CAAC,MAAM,YAAY,EAAE,OAAO;AAAA,IACrC,QAAQ,MACN;AAAA,IAEF,KAAK,CAAC,MAAM;AAAA,MACV,oCAAoC,EAAE,OAAO;AAAA,MAE7C;AAAA,IACF;AAAA,EACF,CAAC;AACH,IACA,CAAC;AAGL,IAAM,UAAU;AAMT,SAAS,WAAW,SAA8B;AACvD,QAAM,IAAI,QAAQ;AAClB,QAAM,SAAS,KAAK,UAAU,IAAI,KAAK,MAAM,IAAI,OAAO;AACxD,MAAI,IAAI,KAAK,KAAK,aAAa,GAAG,QAAU;AAC5C,WAAS,IAAI,GAAG,IAAI,GAAG,IAAI,KAAK,IAAI,SAAS,KAAK,QAAQ,KAAK;AAC7D,QAAI,KAAK,KAAK,IAAK,QAAQ,CAAC,GAAc,QAAU;AAAA,EACtD;AACA,SAAO,MAAM;AACf;AAGA,SAAS,WAAW,KAAkB,UAA0B;AAC9D,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,KAAK,IAAI,CAAC,KAAgB,SAAU,QAAO,IAAI,CAAC;AACrF,SAAO;AACT;AAMO,SAAS,UACd,MACA,SACA,OACA,QACA,KACA,UACS;AACT,MAAI,WAAW,KAAK,MAAM,OAAQ,MAAK,4BAA4B,EAAE,QAAQ,CAAC;AAC9E,MAAI,EAAE,eAAe,cAAc;AACjC,SAAK,yBAAyB,EAAE,SAAS,cAAU,6BAAe,GAAG,EAAE,CAAC;AACxE,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,WAAW,KAAK,QAAQ;AACtC,MAAI,QAAQ,EAAG,QAAO;AACtB,OAAK,yBAAyB,EAAE,SAAS,UAAU,iBAAiB,OAAO,SAAS,CAAC;AACrF,SAAO;AACT;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/pipeline/dev-checks.ts
|
|
2
2
|
import { describeReturn } from "../catalog/slots.js";
|
|
3
3
|
import { defineDiagnostic } from "../diagnostics/catalog.js";
|
|
4
|
+
import "../diagnostics/process-guard.js";
|
|
4
5
|
var stepDiagnostics = process.env.NODE_ENV !== "production" ? [
|
|
5
6
|
defineDiagnostic({
|
|
6
7
|
code: "DK_FEATURE_BAD_OUTPUT",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/dev-checks.ts"],"sourcesContent":["import { describeReturn } from '../catalog/slots'\nimport { defineDiagnostic } from '../diagnostics/catalog'\nimport type { Emit } from '../diagnostics/types'\n\n/**\n * `devChecks` on `pipeline:step` (§3.4, §8.3): a feature `rowModel` must return a `Uint32Array` of\n * row indices and must not write to its input (the input is the previous step's memoised output).\n * Dev only: the definitions, their text and the checks sit behind `(process.env.NODE_ENV !== \"production\")`, so a production bundle has\n * none of it. They run only when a step is recomputed (memo misses), with bounded cost.\n */\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_FEATURE_BAD_OUTPUT: {\n feature: string\n /** What `rowModel` returned, as a type (`an Array`); never the value. */\n received: string\n /** An out-of-range index (a `Uint32Array` output): its value and the row count. */\n index?: number\n rowCount?: number\n }\n DK_FEATURE_MUTATED_INPUT: {\n feature: string\n }\n }\n}\n\nexport const stepDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_FEATURE_BAD_OUTPUT',\n level: 'error',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n problem: (d) =>\n d.index === undefined\n ? `feature \"${d.feature}\" rowModel() returned ${d.received}, not a Uint32Array of ` +\n 'row indices'\n : `feature \"${d.feature}\" rowModel() returned row index ${d.index}, but the data has ` +\n `${d.rowCount} rows`,\n impact: () => 'the step passed its input through (the feature had no effect this run)',\n fix: (d) => [\n `return a Uint32Array of row indices from rowModel() of feature \"${d.feature}\": ` +\n 'indices.subarray(0, n), a new Uint32Array(n) you filled, or Uint32Array.from(list)',\n d.index === undefined\n ? 'rowModel() is synchronous; return the input indices when the feature is inactive'\n : 'only return indices taken from the input (each is a position in options.data)',\n ],\n }),\n defineDiagnostic({\n code: 'DK_FEATURE_MUTATED_INPUT',\n level: 'warn',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n problem: (d) => `feature \"${d.feature}\" rowModel() wrote to its input indices`,\n impact: () =>\n \"the input is the previous step's memoised output: later runs can show rows in the \" +\n 'wrong order or the wrong rows until the data changes',\n fix: (d) => [\n `copy before changing in feature \"${d.feature}\": indices.slice().sort(...) instead of ` +\n 'indices.sort(...)',\n 'or write the result into a new Uint32Array',\n ],\n }),\n ]\n : []\n\n/** At most this many input positions are hashed per step. */\nconst SAMPLES = 64\n\n/**\n * A bounded fingerprint of an index array: FNV-1a over the length and at most {@link SAMPLES}\n * evenly spaced positions (every position when shorter; position 0 always).\n */\nexport function indexPrint(indices: Uint32Array): number {\n const n = indices.length\n const stride = n <= SAMPLES ? 1 : Math.floor(n / SAMPLES)\n let h = Math.imul(0x811c9dc5 ^ n, 0x01000193)\n for (let i = 0, k = 0; i < n && k < SAMPLES; i += stride, k++) {\n h = Math.imul(h ^ (indices[i] as number), 0x01000193)\n }\n return h >>> 0\n}\n\n/** The first index `>= rowCount`, or -1. */\nfunction outOfRange(out: Uint32Array, rowCount: number): number {\n for (let i = 0; i < out.length; i++) if ((out[i] as number) >= rowCount) return out[i] as number\n return -1\n}\n\n/**\n * Checks one recomputed step (dev): reports a mutated input (`before` = {@link indexPrint} of the\n * input before `rowModel` ran) and a bad output. Returns whether `out` can be used.\n */\nexport function checkStep(\n emit: Emit,\n feature: string,\n input: Uint32Array,\n before: number,\n out: unknown,\n rowCount: number,\n): boolean {\n if (indexPrint(input) !== before) emit('DK_FEATURE_MUTATED_INPUT', { feature })\n if (!(out instanceof Uint32Array)) {\n emit('DK_FEATURE_BAD_OUTPUT', { feature, received: describeReturn(out) })\n return false\n }\n const index = outOfRange(out, rowCount)\n if (index < 0) return true\n emit('DK_FEATURE_BAD_OUTPUT', { feature, received: 'a Uint32Array', index, rowCount })\n return false\n}\n"],"mappings":";AAAA,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;
|
|
1
|
+
{"version":3,"sources":["../../src/pipeline/dev-checks.ts"],"sourcesContent":["import { describeReturn } from '../catalog/slots'\nimport { defineDiagnostic } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport type { Emit } from '../diagnostics/types'\n\n/**\n * `devChecks` on `pipeline:step` (§3.4, §8.3): a feature `rowModel` must return a `Uint32Array` of\n * row indices and must not write to its input (the input is the previous step's memoised output).\n * Dev only: the definitions, their text and the checks sit behind `(process.env.NODE_ENV !== \"production\")`, so a production bundle has\n * none of it. They run only when a step is recomputed (memo misses), with bounded cost.\n */\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_FEATURE_BAD_OUTPUT: {\n feature: string\n /** What `rowModel` returned, as a type (`an Array`); never the value. */\n received: string\n /** An out-of-range index (a `Uint32Array` output): its value and the row count. */\n index?: number\n rowCount?: number\n }\n DK_FEATURE_MUTATED_INPUT: {\n feature: string\n }\n }\n}\n\nexport const stepDiagnostics = (process.env.NODE_ENV !== \"production\")\n ? [\n defineDiagnostic({\n code: 'DK_FEATURE_BAD_OUTPUT',\n level: 'error',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n problem: (d) =>\n d.index === undefined\n ? `feature \"${d.feature}\" rowModel() returned ${d.received}, not a Uint32Array of ` +\n 'row indices'\n : `feature \"${d.feature}\" rowModel() returned row index ${d.index}, but the data has ` +\n `${d.rowCount} rows`,\n impact: () => 'the step passed its input through (the feature had no effect this run)',\n fix: (d) => [\n `return a Uint32Array of row indices from rowModel() of feature \"${d.feature}\": ` +\n 'indices.subarray(0, n), a new Uint32Array(n) you filled, or Uint32Array.from(list)',\n d.index === undefined\n ? 'rowModel() is synchronous; return the input indices when the feature is inactive'\n : 'only return indices taken from the input (each is a position in options.data)',\n ],\n }),\n defineDiagnostic({\n code: 'DK_FEATURE_MUTATED_INPUT',\n level: 'warn',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n problem: (d) => `feature \"${d.feature}\" rowModel() wrote to its input indices`,\n impact: () =>\n \"the input is the previous step's memoised output: later runs can show rows in the \" +\n 'wrong order or the wrong rows until the data changes',\n fix: (d) => [\n `copy before changing in feature \"${d.feature}\": indices.slice().sort(...) instead of ` +\n 'indices.sort(...)',\n 'or write the result into a new Uint32Array',\n ],\n }),\n ]\n : []\n\n/** At most this many input positions are hashed per step. */\nconst SAMPLES = 64\n\n/**\n * A bounded fingerprint of an index array: FNV-1a over the length and at most {@link SAMPLES}\n * evenly spaced positions (every position when shorter; position 0 always).\n */\nexport function indexPrint(indices: Uint32Array): number {\n const n = indices.length\n const stride = n <= SAMPLES ? 1 : Math.floor(n / SAMPLES)\n let h = Math.imul(0x811c9dc5 ^ n, 0x01000193)\n for (let i = 0, k = 0; i < n && k < SAMPLES; i += stride, k++) {\n h = Math.imul(h ^ (indices[i] as number), 0x01000193)\n }\n return h >>> 0\n}\n\n/** The first index `>= rowCount`, or -1. */\nfunction outOfRange(out: Uint32Array, rowCount: number): number {\n for (let i = 0; i < out.length; i++) if ((out[i] as number) >= rowCount) return out[i] as number\n return -1\n}\n\n/**\n * Checks one recomputed step (dev): reports a mutated input (`before` = {@link indexPrint} of the\n * input before `rowModel` ran) and a bad output. Returns whether `out` can be used.\n */\nexport function checkStep(\n emit: Emit,\n feature: string,\n input: Uint32Array,\n before: number,\n out: unknown,\n rowCount: number,\n): boolean {\n if (indexPrint(input) !== before) emit('DK_FEATURE_MUTATED_INPUT', { feature })\n if (!(out instanceof Uint32Array)) {\n emit('DK_FEATURE_BAD_OUTPUT', { feature, received: describeReturn(out) })\n return false\n }\n const index = outOfRange(out, rowCount)\n if (index < 0) return true\n emit('DK_FEATURE_BAD_OUTPUT', { feature, received: 'a Uint32Array', index, rowCount })\n return false\n}\n"],"mappings":";AAAA,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,OAAO;AA0BA,IAAM,kBAAmB,QAAQ,IAAI,aAAa,eACrD;AAAA,EACE,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IAClD,SAAS,CAAC,MACR,EAAE,UAAU,SACR,YAAY,EAAE,OAAO,yBAAyB,EAAE,QAAQ,uCAExD,YAAY,EAAE,OAAO,mCAAmC,EAAE,KAAK,sBAC5D,EAAE,QAAQ;AAAA,IACnB,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,mEAAmE,EAAE,OAAO;AAAA,MAE5E,EAAE,UAAU,SACR,qFACA;AAAA,IACN;AAAA,EACF,CAAC;AAAA,EACD,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IAClD,SAAS,CAAC,MAAM,YAAY,EAAE,OAAO;AAAA,IACrC,QAAQ,MACN;AAAA,IAEF,KAAK,CAAC,MAAM;AAAA,MACV,oCAAoC,EAAE,OAAO;AAAA,MAE7C;AAAA,IACF;AAAA,EACF,CAAC;AACH,IACA,CAAC;AAGL,IAAM,UAAU;AAMT,SAAS,WAAW,SAA8B;AACvD,QAAM,IAAI,QAAQ;AAClB,QAAM,SAAS,KAAK,UAAU,IAAI,KAAK,MAAM,IAAI,OAAO;AACxD,MAAI,IAAI,KAAK,KAAK,aAAa,GAAG,QAAU;AAC5C,WAAS,IAAI,GAAG,IAAI,GAAG,IAAI,KAAK,IAAI,SAAS,KAAK,QAAQ,KAAK;AAC7D,QAAI,KAAK,KAAK,IAAK,QAAQ,CAAC,GAAc,QAAU;AAAA,EACtD;AACA,SAAO,MAAM;AACf;AAGA,SAAS,WAAW,KAAkB,UAA0B;AAC9D,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,KAAK,IAAI,CAAC,KAAgB,SAAU,QAAO,IAAI,CAAC;AACrF,SAAO;AACT;AAMO,SAAS,UACd,MACA,SACA,OACA,QACA,KACA,UACS;AACT,MAAI,WAAW,KAAK,MAAM,OAAQ,MAAK,4BAA4B,EAAE,QAAQ,CAAC;AAC9E,MAAI,EAAE,eAAe,cAAc;AACjC,SAAK,yBAAyB,EAAE,SAAS,UAAU,eAAe,GAAG,EAAE,CAAC;AACxE,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,WAAW,KAAK,QAAQ;AACtC,MAAI,QAAQ,EAAG,QAAO;AACtB,OAAK,yBAAyB,EAAE,SAAS,UAAU,iBAAiB,OAAO,SAAS,CAAC;AACrF,SAAO;AACT;","names":[]}
|
|
@@ -25,6 +25,7 @@ __export(env_codes_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(env_codes_exports);
|
|
27
27
|
var import_catalog = require("../diagnostics/catalog.cjs");
|
|
28
|
+
var import_process_guard = require("../diagnostics/process-guard.cjs");
|
|
28
29
|
var ms = (n) => `${n.toFixed(1)} ms`;
|
|
29
30
|
var envMessages = {
|
|
30
31
|
DK_ENV_FALLBACK: {
|
|
@@ -39,11 +40,11 @@ var envMessages = {
|
|
|
39
40
|
]
|
|
40
41
|
},
|
|
41
42
|
DK_PERF_HINT: {
|
|
42
|
-
problem: (d) =>
|
|
43
|
+
problem: (d) => `${d.sliced ? "a time slice of " : ""}the "${d.feature}" step took ${ms(d.ms)} on ${d.rows} rows, over the ${ms(d.budget)} budget of one task` + (d.slot ? `; ${Math.round((d.share ?? 1) * 100)} % of it in ${d.slot} (column "${d.column}")` : ""),
|
|
43
44
|
impact: () => "the page could not respond to input while it ran (a long task)",
|
|
44
45
|
fix: (d) => [
|
|
45
46
|
d.stage === "none" ? `move the work of "${d.feature}" out of rowModel (precompute it, or run it in a Worker)` : `let the server do it: ${d.feature}({ mode: 'server' }) with options.fetcher`,
|
|
46
|
-
`make the per-row work of "${d.feature}" cheaper (precompute keys, avoid Intl / regex per row), or run it in a Worker`
|
|
47
|
+
d.slot ? `make ${d.slot} cheaper (precompute it, avoid Intl / regex per call), or run it in a Worker` : `make the per-row work of "${d.feature}" cheaper (precompute keys, avoid Intl / regex per row), or run it in a Worker`
|
|
47
48
|
]
|
|
48
49
|
}
|
|
49
50
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/env-codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../diagnostics/catalog'\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_ENV_FALLBACK: {\n /** The missing runtime capability, e.g. `'scheduler.yield'` or `'Intl.Collator'`. */\n api: string\n /** The feature that needed it (`where`). */\n feature: string\n /** What was asked for, e.g. the requested collator locale. */\n requested?: string\n /** What is used instead, e.g. `'setTimeout'` or the resolved locale. */\n fallback: string\n }\n DK_PERF_HINT: {\n /** The feature whose step exceeded the budget (`where`). */\n feature: string\n /** Its pipeline stage. */\n stage: string\n /** Measured step time, in milliseconds. */\n ms: number\n /** Rows the step received. */\n rows: number\n /** The budget, in milliseconds (§9.3: the longest task). */\n budget: number\n }\n }\n}\n\nconst ms = (n: number) => `${n.toFixed(1)} ms`\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const envMessages: DiagnosticMessages<'DK_ENV_FALLBACK' | 'DK_PERF_HINT'> = {\n DK_ENV_FALLBACK: {\n problem: (d) =>\n `${d.api}${d.requested === undefined ? '' : ` (${JSON.stringify(d.requested)})`} is not ` +\n `available in this environment (feature \"${d.feature}\")`,\n impact: (d) => `DataKable uses ${d.fallback} instead; results are the same`,\n fix: (d) =>\n d.api === 'Intl.Collator'\n ? [\n `use a locale this runtime supports (Intl.Collator.supportedLocalesOf(${JSON.stringify(d.requested)}) is empty)`,\n 'or ship full ICU data (Node: the default full-icu build; browsers: a polyfill such as @formatjs/intl)',\n ]\n : [\n `nothing to do: ${d.fallback} is a correct fallback for ${d.api}`,\n `${d.api} is used automatically where the runtime provides it`,\n ],\n },\n DK_PERF_HINT: {\n problem: (d) =>\n
|
|
1
|
+
{"version":3,"sources":["../../src/pipeline/env-codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_ENV_FALLBACK: {\n /** The missing runtime capability, e.g. `'scheduler.yield'` or `'Intl.Collator'`. */\n api: string\n /** The feature that needed it (`where`). */\n feature: string\n /** What was asked for, e.g. the requested collator locale. */\n requested?: string\n /** What is used instead, e.g. `'setTimeout'` or the resolved locale. */\n fallback: string\n }\n DK_PERF_HINT: {\n /** The feature whose step exceeded the budget (`where`). */\n feature: string\n /** Its pipeline stage. */\n stage: string\n /** Measured step time, in milliseconds. */\n ms: number\n /** Rows the step received. */\n rows: number\n /** The budget, in milliseconds (§9.3: the longest task). */\n budget: number\n /** One slice of the step's time-sliced work, run between pipeline runs (#61). */\n sliced?: boolean\n /** The column slot at least half of the time went to, e.g. `columns[0].format` (#62). */\n slot?: string\n /** Its column id. */\n column?: string\n /** Its share of {@link ms}, 0.5 to 1. */\n share?: number\n }\n }\n}\n\nconst ms = (n: number) => `${n.toFixed(1)} ms`\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const envMessages: DiagnosticMessages<'DK_ENV_FALLBACK' | 'DK_PERF_HINT'> = {\n DK_ENV_FALLBACK: {\n problem: (d) =>\n `${d.api}${d.requested === undefined ? '' : ` (${JSON.stringify(d.requested)})`} is not ` +\n `available in this environment (feature \"${d.feature}\")`,\n impact: (d) => `DataKable uses ${d.fallback} instead; results are the same`,\n fix: (d) =>\n d.api === 'Intl.Collator'\n ? [\n `use a locale this runtime supports (Intl.Collator.supportedLocalesOf(${JSON.stringify(d.requested)}) is empty)`,\n 'or ship full ICU data (Node: the default full-icu build; browsers: a polyfill such as @formatjs/intl)',\n ]\n : [\n `nothing to do: ${d.fallback} is a correct fallback for ${d.api}`,\n `${d.api} is used automatically where the runtime provides it`,\n ],\n },\n DK_PERF_HINT: {\n problem: (d) =>\n `${d.sliced ? 'a time slice of ' : ''}the \"${d.feature}\" step took ${ms(d.ms)} on ` +\n `${d.rows} rows, over the ${ms(d.budget)} budget of one task` +\n (d.slot\n ? `; ${Math.round((d.share ?? 1) * 100)} % of it in ${d.slot} (column \"${d.column}\")`\n : ''),\n impact: () => 'the page could not respond to input while it ran (a long task)',\n fix: (d) => [\n d.stage === 'none'\n ? `move the work of \"${d.feature}\" out of rowModel (precompute it, or run it in a Worker)`\n : `let the server do it: ${d.feature}({ mode: 'server' }) with options.fetcher`,\n d.slot\n ? `make ${d.slot} cheaper (precompute it, avoid Intl / regex per call), or run it in a Worker`\n : `make the per-row work of \"${d.feature}\" cheaper (precompute keys, avoid Intl / regex per row), or run it in a Worker`,\n ],\n },\n}\n\n/** `DK_ENV_FALLBACK` (§8.3): a missing runtime capability and the fallback used. */\nexport const envDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_ENV_FALLBACK',\n level: 'info',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n },\n (process.env.NODE_ENV !== \"production\") && envMessages.DK_ENV_FALLBACK,\n ),\n]\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA0D;AAC1D,2BAAO;AAqCP,IAAM,KAAK,CAAC,MAAc,GAAG,EAAE,QAAQ,CAAC,CAAC;AAGlC,IAAM,cAAsE;AAAA,EACjF,iBAAiB;AAAA,IACf,SAAS,CAAC,MACR,GAAG,EAAE,GAAG,GAAG,EAAE,cAAc,SAAY,KAAK,KAAK,KAAK,UAAU,EAAE,SAAS,CAAC,GAAG,mDACpC,EAAE,OAAO;AAAA,IACtD,QAAQ,CAAC,MAAM,kBAAkB,EAAE,QAAQ;AAAA,IAC3C,KAAK,CAAC,MACJ,EAAE,QAAQ,kBACN;AAAA,MACE,wEAAwE,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,MACnG;AAAA,IACF,IACA;AAAA,MACE,kBAAkB,EAAE,QAAQ,8BAA8B,EAAE,GAAG;AAAA,MAC/D,GAAG,EAAE,GAAG;AAAA,IACV;AAAA,EACR;AAAA,EACA,cAAc;AAAA,IACZ,SAAS,CAAC,MACR,GAAG,EAAE,SAAS,qBAAqB,EAAE,QAAQ,EAAE,OAAO,eAAe,GAAG,EAAE,EAAE,CAAC,OAC1E,EAAE,IAAI,mBAAmB,GAAG,EAAE,MAAM,CAAC,yBACvC,EAAE,OACC,KAAK,KAAK,OAAO,EAAE,SAAS,KAAK,GAAG,CAAC,eAAe,EAAE,IAAI,aAAa,EAAE,MAAM,OAC/E;AAAA,IACN,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,EAAE,UAAU,SACR,qBAAqB,EAAE,OAAO,6DAC9B,yBAAyB,EAAE,OAAO;AAAA,MACtC,EAAE,OACE,QAAQ,EAAE,IAAI,iFACd,6BAA6B,EAAE,OAAO;AAAA,IAC5C;AAAA,EACF;AACF;AAGO,IAAM,iBAAiB;AAAA,MAC5B;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IACpD;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,YAAY;AAAA,EACzD;AACF;","names":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/pipeline/env-codes.ts
|
|
2
2
|
import { defineDiagnostic } from "../diagnostics/catalog.js";
|
|
3
|
+
import "../diagnostics/process-guard.js";
|
|
3
4
|
var ms = (n) => `${n.toFixed(1)} ms`;
|
|
4
5
|
var envMessages = {
|
|
5
6
|
DK_ENV_FALLBACK: {
|
|
@@ -14,11 +15,11 @@ var envMessages = {
|
|
|
14
15
|
]
|
|
15
16
|
},
|
|
16
17
|
DK_PERF_HINT: {
|
|
17
|
-
problem: (d) =>
|
|
18
|
+
problem: (d) => `${d.sliced ? "a time slice of " : ""}the "${d.feature}" step took ${ms(d.ms)} on ${d.rows} rows, over the ${ms(d.budget)} budget of one task` + (d.slot ? `; ${Math.round((d.share ?? 1) * 100)} % of it in ${d.slot} (column "${d.column}")` : ""),
|
|
18
19
|
impact: () => "the page could not respond to input while it ran (a long task)",
|
|
19
20
|
fix: (d) => [
|
|
20
21
|
d.stage === "none" ? `move the work of "${d.feature}" out of rowModel (precompute it, or run it in a Worker)` : `let the server do it: ${d.feature}({ mode: 'server' }) with options.fetcher`,
|
|
21
|
-
`make the per-row work of "${d.feature}" cheaper (precompute keys, avoid Intl / regex per row), or run it in a Worker`
|
|
22
|
+
d.slot ? `make ${d.slot} cheaper (precompute it, avoid Intl / regex per call), or run it in a Worker` : `make the per-row work of "${d.feature}" cheaper (precompute keys, avoid Intl / regex per row), or run it in a Worker`
|
|
22
23
|
]
|
|
23
24
|
}
|
|
24
25
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/env-codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../diagnostics/catalog'\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_ENV_FALLBACK: {\n /** The missing runtime capability, e.g. `'scheduler.yield'` or `'Intl.Collator'`. */\n api: string\n /** The feature that needed it (`where`). */\n feature: string\n /** What was asked for, e.g. the requested collator locale. */\n requested?: string\n /** What is used instead, e.g. `'setTimeout'` or the resolved locale. */\n fallback: string\n }\n DK_PERF_HINT: {\n /** The feature whose step exceeded the budget (`where`). */\n feature: string\n /** Its pipeline stage. */\n stage: string\n /** Measured step time, in milliseconds. */\n ms: number\n /** Rows the step received. */\n rows: number\n /** The budget, in milliseconds (§9.3: the longest task). */\n budget: number\n }\n }\n}\n\nconst ms = (n: number) => `${n.toFixed(1)} ms`\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const envMessages: DiagnosticMessages<'DK_ENV_FALLBACK' | 'DK_PERF_HINT'> = {\n DK_ENV_FALLBACK: {\n problem: (d) =>\n `${d.api}${d.requested === undefined ? '' : ` (${JSON.stringify(d.requested)})`} is not ` +\n `available in this environment (feature \"${d.feature}\")`,\n impact: (d) => `DataKable uses ${d.fallback} instead; results are the same`,\n fix: (d) =>\n d.api === 'Intl.Collator'\n ? [\n `use a locale this runtime supports (Intl.Collator.supportedLocalesOf(${JSON.stringify(d.requested)}) is empty)`,\n 'or ship full ICU data (Node: the default full-icu build; browsers: a polyfill such as @formatjs/intl)',\n ]\n : [\n `nothing to do: ${d.fallback} is a correct fallback for ${d.api}`,\n `${d.api} is used automatically where the runtime provides it`,\n ],\n },\n DK_PERF_HINT: {\n problem: (d) =>\n
|
|
1
|
+
{"version":3,"sources":["../../src/pipeline/env-codes.ts"],"sourcesContent":["import { type DiagnosticMessages, defineDiagnostic } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\n\ndeclare module '../diagnostics/catalog' {\n interface DiagnosticCatalog {\n DK_ENV_FALLBACK: {\n /** The missing runtime capability, e.g. `'scheduler.yield'` or `'Intl.Collator'`. */\n api: string\n /** The feature that needed it (`where`). */\n feature: string\n /** What was asked for, e.g. the requested collator locale. */\n requested?: string\n /** What is used instead, e.g. `'setTimeout'` or the resolved locale. */\n fallback: string\n }\n DK_PERF_HINT: {\n /** The feature whose step exceeded the budget (`where`). */\n feature: string\n /** Its pipeline stage. */\n stage: string\n /** Measured step time, in milliseconds. */\n ms: number\n /** Rows the step received. */\n rows: number\n /** The budget, in milliseconds (§9.3: the longest task). */\n budget: number\n /** One slice of the step's time-sliced work, run between pipeline runs (#61). */\n sliced?: boolean\n /** The column slot at least half of the time went to, e.g. `columns[0].format` (#62). */\n slot?: string\n /** Its column id. */\n column?: string\n /** Its share of {@link ms}, 0.5 to 1. */\n share?: number\n }\n }\n}\n\nconst ms = (n: number) => `${n.toFixed(1)} ms`\n\n/** Message text (§8.2): development builds, or production via `@datakable/core/messages`. */\nexport const envMessages: DiagnosticMessages<'DK_ENV_FALLBACK' | 'DK_PERF_HINT'> = {\n DK_ENV_FALLBACK: {\n problem: (d) =>\n `${d.api}${d.requested === undefined ? '' : ` (${JSON.stringify(d.requested)})`} is not ` +\n `available in this environment (feature \"${d.feature}\")`,\n impact: (d) => `DataKable uses ${d.fallback} instead; results are the same`,\n fix: (d) =>\n d.api === 'Intl.Collator'\n ? [\n `use a locale this runtime supports (Intl.Collator.supportedLocalesOf(${JSON.stringify(d.requested)}) is empty)`,\n 'or ship full ICU data (Node: the default full-icu build; browsers: a polyfill such as @formatjs/intl)',\n ]\n : [\n `nothing to do: ${d.fallback} is a correct fallback for ${d.api}`,\n `${d.api} is used automatically where the runtime provides it`,\n ],\n },\n DK_PERF_HINT: {\n problem: (d) =>\n `${d.sliced ? 'a time slice of ' : ''}the \"${d.feature}\" step took ${ms(d.ms)} on ` +\n `${d.rows} rows, over the ${ms(d.budget)} budget of one task` +\n (d.slot\n ? `; ${Math.round((d.share ?? 1) * 100)} % of it in ${d.slot} (column \"${d.column}\")`\n : ''),\n impact: () => 'the page could not respond to input while it ran (a long task)',\n fix: (d) => [\n d.stage === 'none'\n ? `move the work of \"${d.feature}\" out of rowModel (precompute it, or run it in a Worker)`\n : `let the server do it: ${d.feature}({ mode: 'server' }) with options.fetcher`,\n d.slot\n ? `make ${d.slot} cheaper (precompute it, avoid Intl / regex per call), or run it in a Worker`\n : `make the per-row work of \"${d.feature}\" cheaper (precompute keys, avoid Intl / regex per row), or run it in a Worker`,\n ],\n },\n}\n\n/** `DK_ENV_FALLBACK` (§8.3): a missing runtime capability and the fallback used. */\nexport const envDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_ENV_FALLBACK',\n level: 'info',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n },\n (process.env.NODE_ENV !== \"production\") && envMessages.DK_ENV_FALLBACK,\n ),\n]\n"],"mappings":";AAAA,SAAkC,wBAAwB;AAC1D,OAAO;AAqCP,IAAM,KAAK,CAAC,MAAc,GAAG,EAAE,QAAQ,CAAC,CAAC;AAGlC,IAAM,cAAsE;AAAA,EACjF,iBAAiB;AAAA,IACf,SAAS,CAAC,MACR,GAAG,EAAE,GAAG,GAAG,EAAE,cAAc,SAAY,KAAK,KAAK,KAAK,UAAU,EAAE,SAAS,CAAC,GAAG,mDACpC,EAAE,OAAO;AAAA,IACtD,QAAQ,CAAC,MAAM,kBAAkB,EAAE,QAAQ;AAAA,IAC3C,KAAK,CAAC,MACJ,EAAE,QAAQ,kBACN;AAAA,MACE,wEAAwE,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,MACnG;AAAA,IACF,IACA;AAAA,MACE,kBAAkB,EAAE,QAAQ,8BAA8B,EAAE,GAAG;AAAA,MAC/D,GAAG,EAAE,GAAG;AAAA,IACV;AAAA,EACR;AAAA,EACA,cAAc;AAAA,IACZ,SAAS,CAAC,MACR,GAAG,EAAE,SAAS,qBAAqB,EAAE,QAAQ,EAAE,OAAO,eAAe,GAAG,EAAE,EAAE,CAAC,OAC1E,EAAE,IAAI,mBAAmB,GAAG,EAAE,MAAM,CAAC,yBACvC,EAAE,OACC,KAAK,KAAK,OAAO,EAAE,SAAS,KAAK,GAAG,CAAC,eAAe,EAAE,IAAI,aAAa,EAAE,MAAM,OAC/E;AAAA,IACN,QAAQ,MAAM;AAAA,IACd,KAAK,CAAC,MAAM;AAAA,MACV,EAAE,UAAU,SACR,qBAAqB,EAAE,OAAO,6DAC9B,yBAAyB,EAAE,OAAO;AAAA,MACtC,EAAE,OACE,QAAQ,EAAE,IAAI,iFACd,6BAA6B,EAAE,OAAO;AAAA,IAC5C;AAAA,EACF;AACF;AAGO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IACpD;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,YAAY;AAAA,EACzD;AACF;","names":[]}
|
|
@@ -24,6 +24,7 @@ __export(perf_codes_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(perf_codes_exports);
|
|
26
26
|
var import_catalog = require("../diagnostics/catalog.cjs");
|
|
27
|
+
var import_process_guard = require("../diagnostics/process-guard.cjs");
|
|
27
28
|
var import_env_codes = require("./env-codes.cjs");
|
|
28
29
|
var perfDiagnostics = [
|
|
29
30
|
(0, import_catalog.defineDiagnostic)(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/perf-codes.ts"],"sourcesContent":["import { defineDiagnostic } from '../diagnostics/catalog'\nimport { envMessages } from './env-codes'\n\n// Apart from env-codes.ts: only the tracer uses this definition, and the tracer is off in\n// production unless installed (`interceptors: [tracer()]`), so a production bundle without it\n// carries no DK_PERF_HINT.\n\n/** `DK_PERF_HINT` (§8.3): a traced step over its budget (the tracer reports it). */\nexport const perfDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_PERF_HINT',\n level: 'info',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n },\n (process.env.NODE_ENV !== \"production\") && envMessages.DK_PERF_HINT,\n ),\n]\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAiC;AACjC,uBAA4B;AAOrB,IAAM,kBAAkB;AAAA,MAC7B;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IACpD;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,6BAAY;AAAA,EACzD;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/pipeline/perf-codes.ts"],"sourcesContent":["import { defineDiagnostic } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport { envMessages } from './env-codes'\n\n// Apart from env-codes.ts: only the tracer uses this definition, and the tracer is off in\n// production unless installed (`interceptors: [tracer()]`), so a production bundle without it\n// carries no DK_PERF_HINT.\n\n/** `DK_PERF_HINT` (§8.3): a traced step over its budget (the tracer reports it). */\nexport const perfDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_PERF_HINT',\n level: 'info',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n },\n (process.env.NODE_ENV !== \"production\") && envMessages.DK_PERF_HINT,\n ),\n]\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAiC;AACjC,2BAAO;AACP,uBAA4B;AAOrB,IAAM,kBAAkB;AAAA,MAC7B;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IACpD;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,6BAAY;AAAA,EACzD;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/perf-codes.ts"],"sourcesContent":["import { defineDiagnostic } from '../diagnostics/catalog'\nimport { envMessages } from './env-codes'\n\n// Apart from env-codes.ts: only the tracer uses this definition, and the tracer is off in\n// production unless installed (`interceptors: [tracer()]`), so a production bundle without it\n// carries no DK_PERF_HINT.\n\n/** `DK_PERF_HINT` (§8.3): a traced step over its budget (the tracer reports it). */\nexport const perfDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_PERF_HINT',\n level: 'info',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n },\n (process.env.NODE_ENV !== \"production\") && envMessages.DK_PERF_HINT,\n ),\n]\n"],"mappings":";AAAA,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAOrB,IAAM,kBAAkB;AAAA,EAC7B;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IACpD;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,YAAY;AAAA,EACzD;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/pipeline/perf-codes.ts"],"sourcesContent":["import { defineDiagnostic } from '../diagnostics/catalog'\nimport '../diagnostics/process-guard'\nimport { envMessages } from './env-codes'\n\n// Apart from env-codes.ts: only the tracer uses this definition, and the tracer is off in\n// production unless installed (`interceptors: [tracer()]`), so a production bundle without it\n// carries no DK_PERF_HINT.\n\n/** `DK_PERF_HINT` (§8.3): a traced step over its budget (the tracer reports it). */\nexport const perfDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_PERF_HINT',\n level: 'info',\n where: (d) => ({ kind: 'feature', name: d.feature }),\n },\n (process.env.NODE_ENV !== \"production\") && envMessages.DK_PERF_HINT,\n ),\n]\n"],"mappings":";AAAA,SAAS,wBAAwB;AACjC,OAAO;AACP,SAAS,mBAAmB;AAOrB,IAAM,kBAAkB;AAAA,EAC7B;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,OAAO,EAAE,MAAM,WAAW,MAAM,EAAE,QAAQ;AAAA,IACpD;AAAA,IACC,QAAQ,IAAI,aAAa,gBAAiB,YAAY;AAAA,EACzD;AACF;","names":[]}
|
package/dist/pipeline/row.cjs
CHANGED
|
@@ -27,29 +27,30 @@ __export(row_exports, {
|
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(row_exports);
|
|
29
29
|
var NO_ISSUES = Object.freeze([]);
|
|
30
|
+
var SOURCE = /* @__PURE__ */ Symbol();
|
|
31
|
+
SOURCE;
|
|
30
32
|
var Row = class {
|
|
31
|
-
#source;
|
|
32
33
|
/** @internal Rows are created by the pipeline. */
|
|
33
34
|
constructor(source, index, key, original) {
|
|
34
35
|
this.key = key;
|
|
35
36
|
this.index = index;
|
|
36
37
|
this.original = original;
|
|
37
|
-
this
|
|
38
|
+
this[SOURCE] = source;
|
|
38
39
|
}
|
|
39
40
|
/** `false` for a row flagged by schema validation (`invalidRows: 'flag'`). */
|
|
40
41
|
get valid() {
|
|
41
|
-
return this
|
|
42
|
+
return this[SOURCE].issues(this.index) === void 0;
|
|
42
43
|
}
|
|
43
44
|
/** The row's schema issues (empty for a valid row). */
|
|
44
45
|
get issues() {
|
|
45
|
-
return this
|
|
46
|
+
return this[SOURCE].issues(this.index) ?? NO_ISSUES;
|
|
46
47
|
}
|
|
47
48
|
/**
|
|
48
49
|
* The value of column `id` for this row (`key` path or `accessor`); `undefined` for an unknown
|
|
49
50
|
* column. Never throws: a throwing accessor reports `DK_CALLBACK_FAILED` and reads `undefined`.
|
|
50
51
|
*/
|
|
51
52
|
getValue(id) {
|
|
52
|
-
return this
|
|
53
|
+
return this[SOURCE].value(this.index, this.original, id);
|
|
53
54
|
}
|
|
54
55
|
/**
|
|
55
56
|
* The schema issues whose path points into column `id`, matched segment by segment: the issue
|
|
@@ -58,8 +59,8 @@ var Row = class {
|
|
|
58
59
|
* so they get only those. Empty for a valid row or an unknown column.
|
|
59
60
|
*/
|
|
60
61
|
getCellIssues(id) {
|
|
61
|
-
const issues = this
|
|
62
|
-
return issues === void 0 ? NO_ISSUES : this
|
|
62
|
+
const issues = this[SOURCE].issues(this.index);
|
|
63
|
+
return issues === void 0 ? NO_ISSUES : this[SOURCE].cellIssues(issues, id);
|
|
63
64
|
}
|
|
64
65
|
};
|
|
65
66
|
function sparse(length) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/row.ts"],"sourcesContent":["/** A row identity: the `rowKey` value, or the fallback (§5.2). */\nexport type RowKey = string | number\n\n/** A validation issue of a row (Standard Schema v1 issue shape, §5.1). */\nexport interface RowIssue {\n readonly message: string\n readonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[] | undefined\n}\n\n/** What a {@link Row} reads its cells through (internal; one per `columns` reference). */\nexport interface RowSource {\n value(index: number, original: unknown, id: string): unknown\n /** Schema issues of a flagged row (`invalidRows: 'flag'`); `undefined` for a valid row. */\n issues(index: number): readonly RowIssue[] | undefined\n /** The issues of a flagged row that touch column `id` (`matchCellIssues`). */\n cellIssues(issues: readonly RowIssue[], id: string): readonly RowIssue[]\n}\n\nexport const NO_ISSUES: readonly RowIssue[] = Object.freeze([])\n\n/**\n * One visible row (§6.6). Created only for the rows `getRowModel()` returns, never for the whole\n * data set (§9.1), and only when read ({@link lazyRows}); the methods live on the prototype, so a\n * row costs its four fields.\n */\nexport class Row<T = unknown> {\n /** The row's `rowKey` value (the row index without `rowKey`). */\n readonly key: RowKey\n /** Position in the ingested data. */\n readonly index: number\n /** The row object as passed in `data`. */\n readonly original: T\n readonly
|
|
1
|
+
{"version":3,"sources":["../../src/pipeline/row.ts"],"sourcesContent":["/** A row identity: the `rowKey` value, or the fallback (§5.2). */\nexport type RowKey = string | number\n\n/** A validation issue of a row (Standard Schema v1 issue shape, §5.1). */\nexport interface RowIssue {\n readonly message: string\n readonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[] | undefined\n}\n\n/** What a {@link Row} reads its cells through (internal; one per `columns` reference). */\nexport interface RowSource {\n value(index: number, original: unknown, id: string): unknown\n /** Schema issues of a flagged row (`invalidRows: 'flag'`); `undefined` for a valid row. */\n issues(index: number): readonly RowIssue[] | undefined\n /** The issues of a flagged row that touch column `id` (`matchCellIssues`). */\n cellIssues(issues: readonly RowIssue[], id: string): readonly RowIssue[]\n}\n\nexport const NO_ISSUES: readonly RowIssue[] = Object.freeze([])\n\n/**\n * The key a {@link Row} keeps its {@link RowSource} under. A symbol, not a `#private` field: a\n * proxy-based store (Vue `ref` / `reactive`, Pinia, MobX) calls the getters and methods with\n * `this` = its proxy, which has no private slot, so `#source` threw there (#11). A symbol key\n * reads through any proxy, stays out of `Object.keys` and JSON, and is not exported.\n */\nconst SOURCE = Symbol()\n\n/**\n * One visible row (§6.6). Created only for the rows `getRowModel()` returns, never for the whole\n * data set (§9.1), and only when read ({@link lazyRows}); the methods live on the prototype, so a\n * row costs its four fields.\n */\nexport class Row<T = unknown> {\n /** The row's `rowKey` value (the row index without `rowKey`). */\n readonly key: RowKey\n /** Position in the ingested data. */\n readonly index: number\n /** The row object as passed in `data`. */\n readonly original: T\n /** @internal */\n private readonly [SOURCE]: RowSource\n\n /** @internal Rows are created by the pipeline. */\n constructor(source: RowSource, index: number, key: RowKey, original: T) {\n this.key = key\n this.index = index\n this.original = original\n this[SOURCE] = source\n }\n\n /** `false` for a row flagged by schema validation (`invalidRows: 'flag'`). */\n get valid(): boolean {\n return this[SOURCE].issues(this.index) === undefined\n }\n\n /** The row's schema issues (empty for a valid row). */\n get issues(): readonly RowIssue[] {\n return this[SOURCE].issues(this.index) ?? NO_ISSUES\n }\n\n /**\n * The value of column `id` for this row (`key` path or `accessor`); `undefined` for an unknown\n * column. Never throws: a throwing accessor reports `DK_CALLBACK_FAILED` and reads `undefined`.\n */\n getValue(id: string): unknown {\n return this[SOURCE].value(this.index, this.original, id)\n }\n\n /**\n * The schema issues whose path points into column `id`, matched segment by segment: the issue\n * path equals the column key, or one contains the other (`address` ↔ `address.city`, never\n * `addressLine`). Row-level issues (no path) count for every cell; accessor columns have no key,\n * so they get only those. Empty for a valid row or an unknown column.\n */\n getCellIssues(id: string): readonly RowIssue[] {\n const issues = this[SOURCE].issues(this.index)\n return issues === undefined ? NO_ISSUES : this[SOURCE].cellIssues(issues, id)\n }\n}\n\n/** A valid row under `invalidRows: 'flag'`: `original` is the schema output. */\nexport type ValidRow<T> = Row<T> & { readonly valid: true }\n\n/** A flagged row (`invalidRows: 'flag'`): `original` is the raw, unvalidated value. */\nexport type FlaggedInvalidRow = Row<unknown> & { readonly valid: false }\n\n/** `getRowModel().rows` under `invalidRows: 'flag'` (§5.1): narrow on `row.valid`. */\nexport type FlaggedRow<T> = ValidRow<T> | FlaggedInvalidRow\n\n/**\n * An empty array of `length` without a backing store: setting `length` (or `new Array(n)`)\n * allocates `n` slots; a write at `n - 1` then deleting it leaves sparse (dictionary) elements. V8\n * turns it back into a plain array once it is filled.\n */\nfunction sparse<R>(length: number): R[] {\n const a: R[] = []\n if (length > 0) {\n a[length - 1] = undefined as R\n delete a[length - 1]\n }\n return a\n}\n\n/** `p` as an index below `length` (a canonical array index string), else `-1`. */\nexport function arrayIndex(p: string | symbol, length: number): number {\n const i = typeof p === 'string' ? Number(p) : -1\n return i >= 0 && i < length && String(i) === p ? i : -1\n}\n\n/**\n * `RowModel.rows` without a `Row` per visible row up front (§9.3 memory: 90k rows unpaginated): a\n * real array (`Array.isArray`, `length`, index reads, iteration, every array method) over a sparse\n * target that builds row `i` with `make(i)` the first time it is read and keeps it, so identity is\n * stable. `Object.keys` / `ownKeys` build every row first.\n */\nexport function lazyRows<R>(length: number, make: (i: number) => R): R[] {\n const t = sparse<R>(length)\n /** Builds row `i` (an index from {@link arrayIndex}; `-1` is not one) unless it exists. */\n const build = (i: number) => {\n if (i >= 0 && !(i in t)) t[i] = make(i)\n }\n return new Proxy(t, {\n get(_, p, receiver) {\n build(arrayIndex(p, length))\n return Reflect.get(t, p, receiver)\n },\n has: (_, p) => arrayIndex(p, length) >= 0 || Reflect.has(t, p),\n getOwnPropertyDescriptor(_, p) {\n build(arrayIndex(p, length))\n return Reflect.getOwnPropertyDescriptor(t, p)\n },\n ownKeys() {\n for (let i = 0; i < length; i++) build(i)\n return Reflect.ownKeys(t)\n },\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBO,IAAM,YAAiC,OAAO,OAAO,CAAC,CAAC;AAQ9D,IAAM,SAAS,uBAAO;AAeF;AARb,IAAM,MAAN,MAAuB;AAAA;AAAA,EAW5B,YAAY,QAAmB,OAAe,KAAa,UAAa;AACtE,SAAK,MAAM;AACX,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,MAAM,IAAI;AAAA,EACjB;AAAA;AAAA,EAGA,IAAI,QAAiB;AACnB,WAAO,KAAK,MAAM,EAAE,OAAO,KAAK,KAAK,MAAM;AAAA,EAC7C;AAAA;AAAA,EAGA,IAAI,SAA8B;AAChC,WAAO,KAAK,MAAM,EAAE,OAAO,KAAK,KAAK,KAAK;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,IAAqB;AAC5B,WAAO,KAAK,MAAM,EAAE,MAAM,KAAK,OAAO,KAAK,UAAU,EAAE;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,IAAiC;AAC7C,UAAM,SAAS,KAAK,MAAM,EAAE,OAAO,KAAK,KAAK;AAC7C,WAAO,WAAW,SAAY,YAAY,KAAK,MAAM,EAAE,WAAW,QAAQ,EAAE;AAAA,EAC9E;AACF;AAgBA,SAAS,OAAU,QAAqB;AACtC,QAAM,IAAS,CAAC;AAChB,MAAI,SAAS,GAAG;AACd,MAAE,SAAS,CAAC,IAAI;AAChB,WAAO,EAAE,SAAS,CAAC;AAAA,EACrB;AACA,SAAO;AACT;AAGO,SAAS,WAAW,GAAoB,QAAwB;AACrE,QAAM,IAAI,OAAO,MAAM,WAAW,OAAO,CAAC,IAAI;AAC9C,SAAO,KAAK,KAAK,IAAI,UAAU,OAAO,CAAC,MAAM,IAAI,IAAI;AACvD;AAQO,SAAS,SAAY,QAAgB,MAA6B;AACvE,QAAM,IAAI,OAAU,MAAM;AAE1B,QAAM,QAAQ,CAAC,MAAc;AAC3B,QAAI,KAAK,KAAK,EAAE,KAAK,GAAI,GAAE,CAAC,IAAI,KAAK,CAAC;AAAA,EACxC;AACA,SAAO,IAAI,MAAM,GAAG;AAAA,IAClB,IAAI,GAAG,GAAG,UAAU;AAClB,YAAM,WAAW,GAAG,MAAM,CAAC;AAC3B,aAAO,QAAQ,IAAI,GAAG,GAAG,QAAQ;AAAA,IACnC;AAAA,IACA,KAAK,CAAC,GAAG,MAAM,WAAW,GAAG,MAAM,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC;AAAA,IAC7D,yBAAyB,GAAG,GAAG;AAC7B,YAAM,WAAW,GAAG,MAAM,CAAC;AAC3B,aAAO,QAAQ,yBAAyB,GAAG,CAAC;AAAA,IAC9C;AAAA,IACA,UAAU;AACR,eAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,OAAM,CAAC;AACxC,aAAO,QAAQ,QAAQ,CAAC;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;","names":[]}
|
package/dist/pipeline/row.js
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
// src/pipeline/row.ts
|
|
2
2
|
var NO_ISSUES = Object.freeze([]);
|
|
3
|
+
var SOURCE = /* @__PURE__ */ Symbol();
|
|
4
|
+
SOURCE;
|
|
3
5
|
var Row = class {
|
|
4
|
-
#source;
|
|
5
6
|
/** @internal Rows are created by the pipeline. */
|
|
6
7
|
constructor(source, index, key, original) {
|
|
7
8
|
this.key = key;
|
|
8
9
|
this.index = index;
|
|
9
10
|
this.original = original;
|
|
10
|
-
this
|
|
11
|
+
this[SOURCE] = source;
|
|
11
12
|
}
|
|
12
13
|
/** `false` for a row flagged by schema validation (`invalidRows: 'flag'`). */
|
|
13
14
|
get valid() {
|
|
14
|
-
return this
|
|
15
|
+
return this[SOURCE].issues(this.index) === void 0;
|
|
15
16
|
}
|
|
16
17
|
/** The row's schema issues (empty for a valid row). */
|
|
17
18
|
get issues() {
|
|
18
|
-
return this
|
|
19
|
+
return this[SOURCE].issues(this.index) ?? NO_ISSUES;
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
21
22
|
* The value of column `id` for this row (`key` path or `accessor`); `undefined` for an unknown
|
|
22
23
|
* column. Never throws: a throwing accessor reports `DK_CALLBACK_FAILED` and reads `undefined`.
|
|
23
24
|
*/
|
|
24
25
|
getValue(id) {
|
|
25
|
-
return this
|
|
26
|
+
return this[SOURCE].value(this.index, this.original, id);
|
|
26
27
|
}
|
|
27
28
|
/**
|
|
28
29
|
* The schema issues whose path points into column `id`, matched segment by segment: the issue
|
|
@@ -31,8 +32,8 @@ var Row = class {
|
|
|
31
32
|
* so they get only those. Empty for a valid row or an unknown column.
|
|
32
33
|
*/
|
|
33
34
|
getCellIssues(id) {
|
|
34
|
-
const issues = this
|
|
35
|
-
return issues === void 0 ? NO_ISSUES : this
|
|
35
|
+
const issues = this[SOURCE].issues(this.index);
|
|
36
|
+
return issues === void 0 ? NO_ISSUES : this[SOURCE].cellIssues(issues, id);
|
|
36
37
|
}
|
|
37
38
|
};
|
|
38
39
|
function sparse(length) {
|
package/dist/pipeline/row.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/row.ts"],"sourcesContent":["/** A row identity: the `rowKey` value, or the fallback (§5.2). */\nexport type RowKey = string | number\n\n/** A validation issue of a row (Standard Schema v1 issue shape, §5.1). */\nexport interface RowIssue {\n readonly message: string\n readonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[] | undefined\n}\n\n/** What a {@link Row} reads its cells through (internal; one per `columns` reference). */\nexport interface RowSource {\n value(index: number, original: unknown, id: string): unknown\n /** Schema issues of a flagged row (`invalidRows: 'flag'`); `undefined` for a valid row. */\n issues(index: number): readonly RowIssue[] | undefined\n /** The issues of a flagged row that touch column `id` (`matchCellIssues`). */\n cellIssues(issues: readonly RowIssue[], id: string): readonly RowIssue[]\n}\n\nexport const NO_ISSUES: readonly RowIssue[] = Object.freeze([])\n\n/**\n * One visible row (§6.6). Created only for the rows `getRowModel()` returns, never for the whole\n * data set (§9.1), and only when read ({@link lazyRows}); the methods live on the prototype, so a\n * row costs its four fields.\n */\nexport class Row<T = unknown> {\n /** The row's `rowKey` value (the row index without `rowKey`). */\n readonly key: RowKey\n /** Position in the ingested data. */\n readonly index: number\n /** The row object as passed in `data`. */\n readonly original: T\n readonly
|
|
1
|
+
{"version":3,"sources":["../../src/pipeline/row.ts"],"sourcesContent":["/** A row identity: the `rowKey` value, or the fallback (§5.2). */\nexport type RowKey = string | number\n\n/** A validation issue of a row (Standard Schema v1 issue shape, §5.1). */\nexport interface RowIssue {\n readonly message: string\n readonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[] | undefined\n}\n\n/** What a {@link Row} reads its cells through (internal; one per `columns` reference). */\nexport interface RowSource {\n value(index: number, original: unknown, id: string): unknown\n /** Schema issues of a flagged row (`invalidRows: 'flag'`); `undefined` for a valid row. */\n issues(index: number): readonly RowIssue[] | undefined\n /** The issues of a flagged row that touch column `id` (`matchCellIssues`). */\n cellIssues(issues: readonly RowIssue[], id: string): readonly RowIssue[]\n}\n\nexport const NO_ISSUES: readonly RowIssue[] = Object.freeze([])\n\n/**\n * The key a {@link Row} keeps its {@link RowSource} under. A symbol, not a `#private` field: a\n * proxy-based store (Vue `ref` / `reactive`, Pinia, MobX) calls the getters and methods with\n * `this` = its proxy, which has no private slot, so `#source` threw there (#11). A symbol key\n * reads through any proxy, stays out of `Object.keys` and JSON, and is not exported.\n */\nconst SOURCE = Symbol()\n\n/**\n * One visible row (§6.6). Created only for the rows `getRowModel()` returns, never for the whole\n * data set (§9.1), and only when read ({@link lazyRows}); the methods live on the prototype, so a\n * row costs its four fields.\n */\nexport class Row<T = unknown> {\n /** The row's `rowKey` value (the row index without `rowKey`). */\n readonly key: RowKey\n /** Position in the ingested data. */\n readonly index: number\n /** The row object as passed in `data`. */\n readonly original: T\n /** @internal */\n private readonly [SOURCE]: RowSource\n\n /** @internal Rows are created by the pipeline. */\n constructor(source: RowSource, index: number, key: RowKey, original: T) {\n this.key = key\n this.index = index\n this.original = original\n this[SOURCE] = source\n }\n\n /** `false` for a row flagged by schema validation (`invalidRows: 'flag'`). */\n get valid(): boolean {\n return this[SOURCE].issues(this.index) === undefined\n }\n\n /** The row's schema issues (empty for a valid row). */\n get issues(): readonly RowIssue[] {\n return this[SOURCE].issues(this.index) ?? NO_ISSUES\n }\n\n /**\n * The value of column `id` for this row (`key` path or `accessor`); `undefined` for an unknown\n * column. Never throws: a throwing accessor reports `DK_CALLBACK_FAILED` and reads `undefined`.\n */\n getValue(id: string): unknown {\n return this[SOURCE].value(this.index, this.original, id)\n }\n\n /**\n * The schema issues whose path points into column `id`, matched segment by segment: the issue\n * path equals the column key, or one contains the other (`address` ↔ `address.city`, never\n * `addressLine`). Row-level issues (no path) count for every cell; accessor columns have no key,\n * so they get only those. Empty for a valid row or an unknown column.\n */\n getCellIssues(id: string): readonly RowIssue[] {\n const issues = this[SOURCE].issues(this.index)\n return issues === undefined ? NO_ISSUES : this[SOURCE].cellIssues(issues, id)\n }\n}\n\n/** A valid row under `invalidRows: 'flag'`: `original` is the schema output. */\nexport type ValidRow<T> = Row<T> & { readonly valid: true }\n\n/** A flagged row (`invalidRows: 'flag'`): `original` is the raw, unvalidated value. */\nexport type FlaggedInvalidRow = Row<unknown> & { readonly valid: false }\n\n/** `getRowModel().rows` under `invalidRows: 'flag'` (§5.1): narrow on `row.valid`. */\nexport type FlaggedRow<T> = ValidRow<T> | FlaggedInvalidRow\n\n/**\n * An empty array of `length` without a backing store: setting `length` (or `new Array(n)`)\n * allocates `n` slots; a write at `n - 1` then deleting it leaves sparse (dictionary) elements. V8\n * turns it back into a plain array once it is filled.\n */\nfunction sparse<R>(length: number): R[] {\n const a: R[] = []\n if (length > 0) {\n a[length - 1] = undefined as R\n delete a[length - 1]\n }\n return a\n}\n\n/** `p` as an index below `length` (a canonical array index string), else `-1`. */\nexport function arrayIndex(p: string | symbol, length: number): number {\n const i = typeof p === 'string' ? Number(p) : -1\n return i >= 0 && i < length && String(i) === p ? i : -1\n}\n\n/**\n * `RowModel.rows` without a `Row` per visible row up front (§9.3 memory: 90k rows unpaginated): a\n * real array (`Array.isArray`, `length`, index reads, iteration, every array method) over a sparse\n * target that builds row `i` with `make(i)` the first time it is read and keeps it, so identity is\n * stable. `Object.keys` / `ownKeys` build every row first.\n */\nexport function lazyRows<R>(length: number, make: (i: number) => R): R[] {\n const t = sparse<R>(length)\n /** Builds row `i` (an index from {@link arrayIndex}; `-1` is not one) unless it exists. */\n const build = (i: number) => {\n if (i >= 0 && !(i in t)) t[i] = make(i)\n }\n return new Proxy(t, {\n get(_, p, receiver) {\n build(arrayIndex(p, length))\n return Reflect.get(t, p, receiver)\n },\n has: (_, p) => arrayIndex(p, length) >= 0 || Reflect.has(t, p),\n getOwnPropertyDescriptor(_, p) {\n build(arrayIndex(p, length))\n return Reflect.getOwnPropertyDescriptor(t, p)\n },\n ownKeys() {\n for (let i = 0; i < length; i++) build(i)\n return Reflect.ownKeys(t)\n },\n })\n}\n"],"mappings":";AAkBO,IAAM,YAAiC,OAAO,OAAO,CAAC,CAAC;AAQ9D,IAAM,SAAS,uBAAO;AAeF;AARb,IAAM,MAAN,MAAuB;AAAA;AAAA,EAW5B,YAAY,QAAmB,OAAe,KAAa,UAAa;AACtE,SAAK,MAAM;AACX,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,MAAM,IAAI;AAAA,EACjB;AAAA;AAAA,EAGA,IAAI,QAAiB;AACnB,WAAO,KAAK,MAAM,EAAE,OAAO,KAAK,KAAK,MAAM;AAAA,EAC7C;AAAA;AAAA,EAGA,IAAI,SAA8B;AAChC,WAAO,KAAK,MAAM,EAAE,OAAO,KAAK,KAAK,KAAK;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,IAAqB;AAC5B,WAAO,KAAK,MAAM,EAAE,MAAM,KAAK,OAAO,KAAK,UAAU,EAAE;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,IAAiC;AAC7C,UAAM,SAAS,KAAK,MAAM,EAAE,OAAO,KAAK,KAAK;AAC7C,WAAO,WAAW,SAAY,YAAY,KAAK,MAAM,EAAE,WAAW,QAAQ,EAAE;AAAA,EAC9E;AACF;AAgBA,SAAS,OAAU,QAAqB;AACtC,QAAM,IAAS,CAAC;AAChB,MAAI,SAAS,GAAG;AACd,MAAE,SAAS,CAAC,IAAI;AAChB,WAAO,EAAE,SAAS,CAAC;AAAA,EACrB;AACA,SAAO;AACT;AAGO,SAAS,WAAW,GAAoB,QAAwB;AACrE,QAAM,IAAI,OAAO,MAAM,WAAW,OAAO,CAAC,IAAI;AAC9C,SAAO,KAAK,KAAK,IAAI,UAAU,OAAO,CAAC,MAAM,IAAI,IAAI;AACvD;AAQO,SAAS,SAAY,QAAgB,MAA6B;AACvE,QAAM,IAAI,OAAU,MAAM;AAE1B,QAAM,QAAQ,CAAC,MAAc;AAC3B,QAAI,KAAK,KAAK,EAAE,KAAK,GAAI,GAAE,CAAC,IAAI,KAAK,CAAC;AAAA,EACxC;AACA,SAAO,IAAI,MAAM,GAAG;AAAA,IAClB,IAAI,GAAG,GAAG,UAAU;AAClB,YAAM,WAAW,GAAG,MAAM,CAAC;AAC3B,aAAO,QAAQ,IAAI,GAAG,GAAG,QAAQ;AAAA,IACnC;AAAA,IACA,KAAK,CAAC,GAAG,MAAM,WAAW,GAAG,MAAM,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC;AAAA,IAC7D,yBAAyB,GAAG,GAAG;AAC7B,YAAM,WAAW,GAAG,MAAM,CAAC;AAC3B,aAAO,QAAQ,yBAAyB,GAAG,CAAC;AAAA,IAC9C;AAAA,IACA,UAAU;AACR,eAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,OAAM,CAAC;AACxC,aAAO,QAAQ,QAAQ,CAAC;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;","names":[]}
|
package/dist/pipeline/runner.cjs
CHANGED
|
@@ -25,6 +25,8 @@ __export(runner_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(runner_exports);
|
|
26
26
|
var import_get_value = require("../column/get-value.cjs");
|
|
27
27
|
var import_catalog = require("../diagnostics/catalog.cjs");
|
|
28
|
+
var import_process_guard = require("../diagnostics/process-guard.cjs");
|
|
29
|
+
var import_trace_store = require("../diagnostics/trace-store.cjs");
|
|
28
30
|
var import_codes = require("../feature/codes.cjs");
|
|
29
31
|
var import_cell_issues = require("../ingest/cell-issues.cjs");
|
|
30
32
|
var import_row_key = require("../ingest/row-key.cjs");
|
|
@@ -76,7 +78,8 @@ function createPipeline(host) {
|
|
|
76
78
|
// Not during SSR, and not for the first row model (the hydrated client matches the server).
|
|
77
79
|
enabled: () => refresh !== void 0 && last !== void 0 && host.base().phase === "client",
|
|
78
80
|
trigger: () => host.base().trigger,
|
|
79
|
-
done: (trigger) => refresh?.(trigger)
|
|
81
|
+
done: (trigger) => refresh?.(trigger),
|
|
82
|
+
timed: (feature, ms) => import_trace_store.sliceTimer.current?.(host.base(), feature, ms)
|
|
80
83
|
});
|
|
81
84
|
function reportCell(col, index, e, field) {
|
|
82
85
|
const name = (0, import_classify.errorName)(e);
|
|
@@ -87,7 +90,7 @@ function createPipeline(host) {
|
|
|
87
90
|
column: col.id,
|
|
88
91
|
rows: [index],
|
|
89
92
|
count: 1,
|
|
90
|
-
fallback: "
|
|
93
|
+
fallback: "cell-undefined",
|
|
91
94
|
...name === void 0 ? {} : { errorName: name }
|
|
92
95
|
},
|
|
93
96
|
{ cause: e }
|
|
@@ -142,7 +145,7 @@ function createPipeline(host) {
|
|
|
142
145
|
slot: "rowKey",
|
|
143
146
|
rows: Array.from(keyFailures.sample()),
|
|
144
147
|
count: keyFailures.count,
|
|
145
|
-
fallback: "
|
|
148
|
+
fallback: "row-key-index",
|
|
146
149
|
...name === void 0 ? {} : { errorName: name }
|
|
147
150
|
},
|
|
148
151
|
{ cause: keyError }
|
|
@@ -202,6 +205,10 @@ function createPipeline(host) {
|
|
|
202
205
|
const col = cols.byId.get(id);
|
|
203
206
|
return col ? cache.formatted(data, col) : void 0;
|
|
204
207
|
},
|
|
208
|
+
*formattedSliced(id) {
|
|
209
|
+
const col = cols.byId.get(id);
|
|
210
|
+
return col ? yield* cache.formattedSliced(data, col) : void 0;
|
|
211
|
+
},
|
|
205
212
|
batch: (id, slot, rows, body) => {
|
|
206
213
|
const col = cols.byId.get(id);
|
|
207
214
|
if (col) cache.batch(col, slot, slot, rows, body);
|
|
@@ -245,13 +252,14 @@ function createPipeline(host) {
|
|
|
245
252
|
{
|
|
246
253
|
feature: f.name,
|
|
247
254
|
hook: "rowModel",
|
|
248
|
-
fallback: "
|
|
255
|
+
fallback: "step-passthrough",
|
|
249
256
|
...name === void 0 ? {} : { errorName: name }
|
|
250
257
|
},
|
|
251
258
|
{ cause: e }
|
|
252
259
|
);
|
|
253
260
|
return input;
|
|
254
261
|
}
|
|
262
|
+
if (waiting > waited) ctx2.meta.set(import_trace_store.SLICED, true);
|
|
255
263
|
if (process.env.NODE_ENV !== "production" && !(0, import_dev_checks.checkStep)(stepEmit, f.name, input, before, out, data.length)) return input;
|
|
256
264
|
ok = true;
|
|
257
265
|
return out instanceof Uint32Array ? out : input;
|
|
@@ -286,11 +294,11 @@ function createPipeline(host) {
|
|
|
286
294
|
});
|
|
287
295
|
} finally {
|
|
288
296
|
slicer?.end();
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
297
|
+
if (result) model = result;
|
|
298
|
+
else {
|
|
299
|
+
const isInitialLoad = host.isInitialLoad();
|
|
300
|
+
model = last ? { ...last.model, status: "error", isInitialLoad } : { rows: EMPTY, filteredCount: 0, totalCount: 0, status: "error", isInitialLoad };
|
|
301
|
+
}
|
|
294
302
|
}
|
|
295
303
|
return model;
|
|
296
304
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pipeline/runner.ts"],"sourcesContent":["import { getValue } from '../column/get-value'\nimport { keepDiagnostics } from '../diagnostics/catalog'\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 } 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 })\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: 'the cell reads as 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: \"those rows use the fallback 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 => ({\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 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: 'the step passed its input through',\n ...(name === undefined ? {} : { errorName: name }),\n },\n { cause: e },\n )\n return input\n }\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 }\n if (result) model = result\n else {\n // pipeline:run failed: the boundary reported it; keep the last good rows.\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 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 /** 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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAyB;AACzB,qBAAgC;AAChC,2BAAO;AACP,yBAAmC;AAEnC,mBAAmC;AAGnC,yBAAgC;AAChC,qBAA2C;AAC3C,wBAA6B;AAC7B,sBAA0B;AAC1B,qBAAgD;AAChD,uBAAyB;AAIzB,qBAA0E;AAC1E,wBAAuD;AACvD,qBAAwB;AACxB,iBAA6D;AAE7D,yBAA0C;AAAA,IAG1C,gCAAgB,iCAAoB,iCAAe;AAEnD,IAAM,QAA0B,CAAC;AACjC,IAAM,WAAW,MAAM;AAiGhB,SAAS,eAAkB,MAAiC;AAKjE,QAAM,QAAQ,EAAE,OAAO,EAAE;AAEzB,QAAM,YAAY,CAAC,MAAM,SAAS,YAAY;AAC5C,YAAI,8CAA0B,IAAI,EAAG,OAAM;AAC3C,SAAK,KAAK,MAAM,SAAS,OAAO;AAAA,EAClC;AACA,QAAM,KAAK,KAAK;AAEhB,QAAM,QAAQ,IAAI,kBAAkB;AAAA,IAClC,SAAS,KAAK;AAAA,IACd,MAAM;AAAA,IACN,MAAM,MAAM,KAAK,KAAK;AAAA,IACtB;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,KAAK,SAAS;AAAA,IAC1B,CAAC,MAAM,EAAE,UAAU,UAAU,EAAE,SAAS,YAAY,OAAO,EAAE,aAAa;AAAA,EAC5E;AACA,QAAM,QAAQ,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,YAAY,KAAK,OAAO,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC;AAC3F,QAAM,OAAO,oBAAI,IAA0B;AAC3C,QAAM,UAAU,oBAAI,QAAoC;AACxD,QAAM,cAAc,IAAI,+BAAa;AAErC,MAAI;AACJ,QAAM,YAAY,CAAC,OAAe,MAAe;AAC/C,QAAI,YAAY,UAAU,EAAG,YAAW;AACxC,gBAAY,IAAI,OAAO,CAAC;AAAA,EAC1B;AACA,MAAI;AAEJ,MAAI;AACJ,MAAI;AAEJ,MAAI;AAEJ,MAAI,UAAU;AACd,QAAM,UAAU,KAAK;AACrB,QAAM,SAA6B,IAAI,aAAa;AAAA,IAClD,MAAM;AAAA;AAAA,IAEN,SAAS,MAAM,YAAY,UAAa,SAAS,UAAa,KAAK,KAAK,EAAE,UAAU;AAAA,IACpF,SAAS,MAAM,KAAK,KAAK,EAAE;AAAA,IAC3B,MAAM,CAAC,YAAY,UAAU,OAAO;AAAA,IACpC,OAAO,CAAC,SAAS,OAAO,8BAAW,UAAU,KAAK,KAAK,GAAG,SAAS,EAAE;AAAA,EACvE,CAAC;AAGD,WAAS,WAAW,KAAqB,OAAe,GAAY,OAAe;AACjF,UAAM,WAAO,2BAAU,CAAC;AACxB,SAAK;AAAA,MACH;AAAA,MACA;AAAA,QACE,MAAM,WAAW,IAAI,KAAK,KAAK,KAAK;AAAA,QACpC,QAAQ,IAAI;AAAA,QACZ,MAAM,CAAC,KAAK;AAAA,QACZ,OAAO;AAAA,QACP,UAAU;AAAA,QACV,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,WAAW,KAAK;AAAA,MAClD;AAAA,MACA,EAAE,OAAO,EAAE;AAAA,IACb;AAAA,EACF;AAGA,MAAI,aAAa;AACjB,MAAI;AACJ,QAAM,cAAc,CAAC,MAAe;AAClC,iBAAa;AACb,gBAAY;AAAA,EACd;AAEA,WAAS,UAAU,MAAkC;AACnD,QAAI,IAAI,QAAQ,IAAI,IAAI;AACxB,QAAI,EAAG,QAAO;AACd,QAAI;AAAA,MACF,MAAM,OAAO,UAAU,IAAI;AACzB,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,YAAI,CAAC,IAAK,QAAO;AACjB,YAAI,IAAI,MAAM;AACZ,gBAAM,QAAI,2BAAS,UAAU,IAAI,MAAM,WAAW;AAClD,cAAI,YAAY;AACd,kBAAM,IAAI;AACV,yBAAa;AACb,wBAAY;AACZ,uBAAW,KAAK,OAAO,GAAG,KAAK;AAAA,UACjC;AACA,iBAAO;AAAA,QACT;AACA,YAAI,CAAC,IAAI,SAAU,QAAO;AAC1B,YAAI;AACF,iBAAO,IAAI,SAAS,QAAQ;AAAA,QAC9B,SAAS,GAAG;AACV,qBAAW,KAAK,OAAO,GAAG,UAAU;AACpC,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,QAAQ,CAAC,UAAU,KAAK,OAAO,KAAK;AAAA,MACpC,WAAW,QAAQ,IAAI;AACrB,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,eAAO,UAAM,oCAAgB,QAAQ,IAAI,IAAI,IAAI;AAAA,MACnD;AAAA,IACF;AACA,YAAQ,IAAI,MAAM,CAAC;AACnB,WAAO;AAAA,EACT;AAEA,WAAS,oBAAoB;AAC3B,QAAI,YAAY,UAAU,EAAG;AAC7B,UAAM,WAAO,2BAAU,QAAQ;AAC/B,SAAK;AAAA,MACH;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM,MAAM,KAAK,YAAY,OAAO,CAAC;AAAA,QACrC,OAAO,YAAY;AAAA,QACnB,UAAU;AAAA,QACV,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,WAAW,KAAK;AAAA,MAClD;AAAA,MACA,EAAE,OAAO,SAAS;AAAA,IACpB;AACA,gBAAY,MAAM;AAClB,eAAW;AAAA,EACb;AAEA,WAAS,MACP,MACA,SACA,SACA,eACA,QACa;AACb,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,gBAAgB,KAAK,cAAc;AACzC,UAAM,OAAO;AACb,QACE,QACA,KAAK,YAAY,WACjB,KAAK,SAAS,QACd,KAAK,YAAY,WACjB,KAAK,WAAW,UAChB,KAAK,MAAM,WAAW,UACtB,KAAK,MAAM,kBAAkB,eAC7B;AACA,aAAO,KAAK;AAAA,IACd;AACA,UAAM,SAAS,cAAU,+BAAe,OAAO,CAAC;AAChD,gBAAY,MAAM;AAClB,QAAI,MAAM,SAAS,QAAQ,KAAK,WAAW,QAAQ;AACjD,aAAO,EAAE,MAAM,QAAQ,WAAO,+BAAe,MAAM,QAAQ,KAAK,MAAM,SAAS,EAAE;AAAA,IACnF;AACA,UAAM,QAAQ,KAAK;AACnB,sBAAkB;AAGlB,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,MAAK,KAAK,QAAQ,CAAC,CAAW;AAGvE,UAAM,WAAO,qBAAS,QAAQ,QAAQ,CAAC,MAAM;AAC3C,YAAM,IAAI,QAAQ,CAAC;AACnB,YAAM,WAAW,KAAK,CAAC;AACvB,YAAM,MAAM,IAAI,eAAO,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,QAAQ;AAC9D,wBAAkB;AAClB,aAAO;AAAA,IACT,CAAC;AACD,UAAM,IAAiB,EAAE,MAAM,eAAe,YAAY,KAAK,QAAQ,QAAQ,cAAc;AAC7F,WAAO,EAAE,OAAO,GAAG,MAAM,SAAS,SAAS,OAAO;AAClD,WAAO;AAAA,EACT;AAEA,WAAS,MAAmB;AAC1B,SAAK,QAAQ;AACb,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,UAAU,KAAK,WAAW,KAAK;AACrC,UAAM,WAAO,+BAAe,OAAO;AACnC,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,SAAS;AACb,QAAI;AACJ,UAAM,UAAwB,CAAC;AAC/B,UAAM,EAAE,KAAK,OAAO,QAAQ,IAAI,KAAK,KAAK;AAC1C,cAAU,EAAE,KAAK,OAAO,SAAS,OAAO,QAAQ;AAEhD,UAAM,kBAAkB,CAAC,UAAsD;AAAA,MAC7E;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,GAAI,KAAK,WAAW,EAAE,SAAS,CAAC,MAAc,KAAK,OAAO,CAAC,EAAE,IAAI,CAAC;AAAA,MAClE,KAAK,KAAK,KAAK,EAAE;AAAA,MACjB;AAAA,MACA,iBAAiB,CAAC,OAAO;AACvB,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,eAAO,MAAM,MAAM,OAAO,MAAM,GAAG,IAAI;AAAA,MACzC;AAAA,MACA,oBAAoB,CAAC,OAAO;AAC1B,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,eAAO,MAAM,MAAM,UAAU,MAAM,GAAG,IAAI;AAAA,MAC5C;AAAA,MACA,CAAC,gBAAgB,IAAI;AACnB,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,eAAO,MAAM,OAAO,MAAM,gBAAgB,MAAM,GAAG,IAAI;AAAA,MACzD;AAAA,MACA,OAAO,CAAC,IAAI,MAAM,MAAM,SAAS;AAC/B,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,YAAI,IAAK,OAAM,MAAM,KAAK,MAAM,MAAM,MAAM,IAAI;AAChD,eAAO,QAAQ;AAAA,MACjB;AAAA,MACA,OAAO,CAAC,KAAK,QAAQ;AACnB,cAAM,IAAK,OAAkB,IAAI,KAAK,KAAK,IAAI;AAC/C,YAAI,MAAM,OAAW;AACrB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,aAAS,KAAK,GAAe,OAAiC;AAC5D,YAAM,QAAQ,MAAM,EAAE,IAAI;AAC1B,YAAM,IAAI,KAAK,IAAI,CAAC;AACpB,UAAI,KAAK,EAAE,UAAU,SAAS,OAAO,GAAG,EAAE,OAAO,KAAK,KAAK,EAAE,YAAY,SAAS;AAChF,gBAAQ,KAAK,EAAE,SAAS,GAAG,OAAO,QAAQ,EAAE,QAAQ,QAAQ,MAAM,QAAQ,MAAM,CAAC;AACjF,eAAO,EAAE;AAAA,MACX;AACA,UAAI,KAAK;AACT,YAAM,UAAU,MAAM;AACtB,YAAM,SAAS;AACf,YAAMA,WAAM;AAAA,QACV;AAAA,QACA,EAAE,OAAO,EAAE,OAAO,SAAS,EAAE,MAAM,SAAS,MAAM;AAAA,QAClD,MAAM,IAAI,CAAC;AAAA,QACX,KAAK,KAAK;AAAA,MACZ;AACA,YAAM,SAAS,KAAK,QAAQ,IAAI,iBAAiBA,MAAK,MAAM;AAC1D,YAAI;AAEJ,cAAM,SAAU,QAAQ,IAAI,aAAa,mBAAgB,8BAAW,KAAK,IAAI;AAC7E,YAAI;AACF,gBAAO,EAAE;AAAA,YACP;AAAA,YACA;AAAA,YACA,gBAAgB,EAAE,IAAI;AAAA,UACxB;AAAA,QACF,SAAS,GAAG;AACV,gBAAM,WAAO,2BAAU,CAAC;AACxB,eAAK;AAAA,YACH;AAAA,YACA;AAAA,cACE,SAAS,EAAE;AAAA,cACX,MAAM;AAAA,cACN,UAAU;AAAA,cACV,GAAI,SAAS,SAAY,CAAC,IAAI,EAAE,WAAW,KAAK;AAAA,YAClD;AAAA,YACA,EAAE,OAAO,EAAE;AAAA,UACb;AACA,iBAAO;AAAA,QACT;AAEA,YAAI,UAAU,OAAQ,CAAAA,KAAI,KAAK,IAAI,2BAAQ,IAAI;AAE/C,YAAK,QAAQ,IAAI,aAAa,gBAAiB,KAAC,6BAAU,UAAU,EAAE,MAAM,OAAO,QAAQ,KAAK,KAAK,MAAM,EAAG,QAAO;AACrH,aAAK;AACL,eAAO,eAAe,cAAc,MAAM;AAAA,MAC5C,CAAC;AAGD,UAAI,MAAM,MAAM,UAAU,SAAS;AACjC,YAAI,YAAY,OAAQ,MAAK,IAAI,GAAG,EAAE,OAAO,OAAO,OAAO,SAAS,OAAO,CAAC;AAAA,YACvE,MAAK,OAAO,CAAC;AAAA,MACpB,OAAO;AACL,iBAAS;AACT,aAAK,OAAO,CAAC;AAAA,MACf;AACA,cAAQ,KAAK,EAAE,SAAS,GAAG,OAAO,QAAQ,QAAQ,OAAO,QAAQ,CAAC,GAAG,CAAC;AACtE,aAAO;AAAA,IACT;AAEA,UAAM,UAAM,8BAAc,gBAAgB,EAAE,UAAU,KAAK,OAAO,GAAG,YAAY,KAAK,KAAK,CAAC;AAE5F,QAAI,KAAM,KAAI,KAAK,IAAI,2BAAU,KAAK,OAAO;AAC7C,cAAU;AACV,YAAQ,MAAM;AACd,QAAI;AACF,WAAK,KAAK,QAAQ,IAAI,gBAAgB,KAAK,MAAM;AAC/C,YAAI,cAAU,wBAAQ,IAAI;AAC1B,YAAI,gBAAgB;AACpB,mBAAW,KAAK,OAAO;AACrB,cAAI,EAAE,UAAU,cAAc,gBAAgB,EAAG,iBAAgB,QAAQ;AACzE,oBAAU,KAAK,GAAG,OAAO;AAAA,QAC3B;AACA,YAAI,gBAAgB,EAAG,iBAAgB,QAAQ;AAE/C,cAAM,UAAU,KAAK,OAAO;AAC5B,cAAM,SAAS,SAAS,UAAU,UAAU,KAAK,YAAY,SAAS,YAAY;AAClF,iBAAS,MAAM,MAAM,SAAS,SAAS,eAAe,MAAM;AAC5D,eAAO;AAAA,MACT,CAAC;AAAA,IACH,UAAE;AAEA,cAAQ,IAAI;AACZ,UAAI,OAAQ,SAAQ;AAAA,WACf;AAGH,cAAM,gBAAgB,KAAK,cAAc;AACzC,gBAAQ,OACJ,EAAE,GAAG,KAAK,OAAO,QAAQ,SAAS,cAAc,IAChD,EAAE,MAAM,OAAO,eAAe,GAAG,YAAY,GAAG,QAAQ,SAAS,cAAc;AAAA,MACrF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,WAAS,cAAc,MAA+B;AACpD,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,UAAU,KAAK,WAAW,KAAK;AACrC,UAAM,WAAO,+BAAe,OAAO;AACnC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,GAAI,KAAK,WAAW,EAAE,SAAS,CAAC,MAAc,KAAK,OAAO,CAAC,EAAE,IAAI,CAAC;AAAA,MAClE,KAAK,KAAK,KAAK,EAAE;AAAA,MACjB;AAAA,MACA,iBAAiB,CAAC,OAAO;AACvB,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,eAAO,MAAM,MAAM,OAAO,MAAM,GAAG,IAAI;AAAA,MACzC;AAAA,MACA,oBAAoB,CAAC,OAAO;AAC1B,cAAM,MAAM,KAAK,KAAK,IAAI,EAAE;AAC5B,eAAO,MAAM,MAAM,UAAU,MAAM,GAAG,IAAI;AAAA,MAC5C;AAAA,MACA,OAAO,CAAC,IAAI,OAAO,OAAO,SAAS;AACjC,YAAI,CAAC,KAAK,KAAK,IAAI,EAAE,EAAG,QAAO;AAC/B,aAAK;AACL,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf;AAAA,IACA,SAAS,MAAM,QAAQ,OAAO;AAAA,EAChC;AACF;","names":["ctx"]}
|