tabulark 0.1.0 → 0.2.1

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +67 -2
  2. package/README.md +125 -42
  3. package/dist/client.d.ts +71 -2
  4. package/dist/errors.d.ts +7 -1
  5. package/dist/experimental.js +1 -1
  6. package/dist/experimental.js.map +2 -2
  7. package/dist/http.d.ts +65 -0
  8. package/dist/http.js +2 -0
  9. package/dist/http.js.map +7 -0
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.js +2 -1
  12. package/dist/index.js.map +4 -4
  13. package/dist/model.d.ts +6 -3
  14. package/dist/protocol.d.ts +3 -3
  15. package/dist/range-cache.d.ts +24 -5
  16. package/dist/range-source.d.ts +64 -0
  17. package/dist/rpc-client.d.ts +15 -2
  18. package/dist/source.d.ts +13 -0
  19. package/dist/view/canvas-table-view-public.d.ts +6 -0
  20. package/dist/view/canvas-table-view.d.ts +8 -0
  21. package/dist/wasm/arrow/tabulark_arrow.d.ts +33 -6
  22. package/dist/wasm/arrow/tabulark_arrow.js +129 -17
  23. package/dist/wasm/arrow/tabulark_arrow_bg.wasm +0 -0
  24. package/dist/wasm/arrow/tabulark_arrow_bg.wasm.d.ts +6 -1
  25. package/dist/wasm/delimited/tabulark_delimited.d.ts +31 -5
  26. package/dist/wasm/delimited/tabulark_delimited.js +115 -8
  27. package/dist/wasm/delimited/tabulark_delimited_bg.wasm +0 -0
  28. package/dist/wasm/delimited/tabulark_delimited_bg.wasm.d.ts +6 -1
  29. package/dist/wasm/excel/tabulark_excel.d.ts +33 -8
  30. package/dist/wasm/excel/tabulark_excel.js +129 -19
  31. package/dist/wasm/excel/tabulark_excel_bg.wasm +0 -0
  32. package/dist/wasm/excel/tabulark_excel_bg.wasm.d.ts +6 -1
  33. package/dist/wasm/parquet/tabulark_parquet.d.ts +31 -6
  34. package/dist/wasm/parquet/tabulark_parquet.js +135 -17
  35. package/dist/wasm/parquet/tabulark_parquet_bg.wasm +0 -0
  36. package/dist/wasm/parquet/tabulark_parquet_bg.wasm.d.ts +6 -1
  37. package/dist/worker/blob-source-accessor.d.ts +10 -0
  38. package/dist/worker/source-accessor.d.ts +76 -0
  39. package/dist/worker/wasm-adapter.d.ts +39 -38
  40. package/dist/worker-range-source.d.ts +1 -0
  41. package/dist/worker-range-source.js +2 -0
  42. package/dist/worker-range-source.js.map +7 -0
  43. package/dist/worker.js +1 -1
  44. package/dist/worker.js.map +4 -4
  45. package/package.json +8 -1
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../js/errors.ts", "../js/official-adapters.json", "../js/official-adapter-manifest.ts", "../js/adapters.ts", "../js/protocol.ts", "../js/model.ts", "../js/range-cache.ts", "../js/rpc-client.ts", "../js/client.ts", "../js/view/selection.ts", "../js/view/accessible-grid.ts", "../js/view/canvas-painter.ts", "../js/view/types.ts", "../js/view/layout.ts", "../js/view/controller.ts", "../js/view/canvas-table-view.ts", "../js/view/canvas-table-view-public.ts"],
4
- "sourcesContent": ["import type { SerializedError } from \"./protocol.js\";\n\nexport type TabularkErrorCode =\n | \"INVALID_ARGUMENT\"\n | \"INVALID_RANGE\"\n | \"RANGE_NOT_INDEXED\"\n | \"RESOURCE_LIMIT\"\n | \"CANCELLED\"\n | \"HANDLE_CLOSED\"\n | \"PROTOCOL_INCOMPATIBLE\"\n | \"PARSE_FAILED\"\n | \"UNSUPPORTED_FEATURE\"\n | \"UNSUPPORTED_RUNTIME\"\n | \"RUNTIME_FAILURE\"\n | (string & {});\n\n/** A stable, serializable error returned by Tabulark. */\nexport class TabularkError extends Error {\n readonly code: TabularkErrorCode;\n readonly retryable: boolean;\n readonly details?: unknown;\n\n constructor(\n code: TabularkErrorCode,\n message: string,\n options: { retryable?: boolean; details?: unknown; cause?: unknown } = {},\n ) {\n super(message, { cause: options.cause });\n this.name = \"TabularkError\";\n this.code = code;\n this.retryable = options.retryable ?? false;\n this.details = code === \"RESOURCE_LIMIT\"\n ? normalizeResourceLimitDetails(options.details)\n : options.details;\n }\n\n static fromSerialized(error: SerializedError): TabularkError {\n return new TabularkError(error.code, error.message, {\n retryable: error.retryable,\n details: error.details,\n });\n }\n}\n\n/** @internal Ensures every resource-limit error has a stable capacity shape. */\nexport function normalizeResourceLimitDetails(details: unknown): Readonly<Record<string, unknown>> {\n const raw = isRecord(details) ? details : {};\n const resource = typeof raw.resource === \"string\" && raw.resource.length > 0\n ? raw.resource\n : typeof raw.resourceCategory === \"string\" && raw.resourceCategory.length > 0\n ? raw.resourceCategory\n : inferResource(raw);\n if (isQuantity(raw.requiredBytes) && isQuantity(raw.availableBytes)) {\n return Object.freeze({ ...raw, resource });\n }\n if (isQuantity(raw.required) && isQuantity(raw.available)) {\n return Object.freeze({ ...raw, resource });\n }\n\n const byteLimit = firstQuantity(raw, [\n \"maxDecodedBytes\",\n \"maxOutputBytes\",\n \"maxMetadataBytes\",\n \"maxBlockBytes\",\n \"maxDisplayCellBytes\",\n \"maxDisplayBytes\",\n \"maxSourceBytes\",\n \"maxFieldBytes\",\n \"maxBatchBytes\",\n \"maxOperationBytes\",\n \"maxZipEntryBytes\",\n \"maxZipUncompressedBytes\",\n \"maxCfbStreamBytes\",\n ]);\n if (byteLimit !== undefined) {\n const requiredBytes = firstQuantity(raw, [\n \"decodedBytes\",\n \"outputBytes\",\n \"metadataBytes\",\n \"blockBytes\",\n \"displayCellBytes\",\n \"displayBytes\",\n \"sourceBytes\",\n \"fieldBytes\",\n \"batchBytes\",\n \"operationBytes\",\n ]) ?? byteLimit + 1;\n return Object.freeze({\n ...raw,\n resource,\n requiredBytes,\n availableBytes: byteLimit,\n });\n }\n\n const available = firstQuantity(raw, [\n \"limit\",\n \"maxCells\",\n \"maxRangeCells\",\n \"maxSources\",\n \"maxActiveRanges\",\n \"maxRangeWaiters\",\n \"maxColumns\",\n \"maxFields\",\n \"maxNestingDepth\",\n \"maxWorksheetRows\",\n \"maxWorksheetColumns\",\n \"maxStyles\",\n \"maxMergedRegions\",\n ]) ?? 0;\n const required = firstQuantity(raw, [\n \"cells\",\n \"cellCount\",\n \"visibleCellCount\",\n \"sources\",\n \"activeRanges\",\n \"rangeWaiters\",\n \"columns\",\n \"fields\",\n \"nestingDepth\",\n \"worksheetRows\",\n \"worksheetColumns\",\n \"styles\",\n \"mergedRegions\",\n ]) ?? available + 1;\n return Object.freeze({ ...raw, resource, required, available });\n}\n\nfunction inferResource(details: Record<string, unknown>): string {\n const keys = Object.keys(details).join(\" \").toLowerCase();\n if (keys.includes(\"source\")) return keys.includes(\"byte\") ? \"source-staging\" : \"source-slots\";\n if (keys.includes(\"metadata\")) return \"metadata\";\n if (keys.includes(\"decoded\") || keys.includes(\"decompress\")) return \"decompression\";\n if (keys.includes(\"display\")) return \"display-values\";\n if (keys.includes(\"field\")) return \"field\";\n if (keys.includes(\"batch\")) return \"batch\";\n if (keys.includes(\"range\") || keys.includes(\"cell\")) return \"range-cells\";\n if (keys.includes(\"column\")) return \"columns\";\n if (keys.includes(\"nest\")) return \"descriptor-nesting\";\n if (keys.includes(\"worksheet\")) return \"worksheet-dimensions\";\n return \"adapter-resource\";\n}\n\nfunction firstQuantity(\n details: Record<string, unknown>,\n names: readonly string[],\n): number | undefined {\n for (const name of names) {\n if (isQuantity(details[name])) return details[name] as number;\n }\n return undefined;\n}\n\nfunction isQuantity(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function cancelledError(): TabularkError {\n return new TabularkError(\"CANCELLED\", \"The operation was cancelled\");\n}\n\nexport function closedError(resource: string): TabularkError {\n return new TabularkError(\"HANDLE_CLOSED\", `${resource} is closed`);\n}\n\nexport function invalidArgument(message: string, details?: unknown): TabularkError {\n return new TabularkError(\"INVALID_ARGUMENT\", message, { details });\n}\n", "{\n \"manifestVersion\": 1,\n \"adapters\": [\n {\n \"id\": \"tabulark:delimited\",\n \"entrypoint\": \".\",\n \"exportName\": \"delimitedAdapter\",\n \"wasm\": {\n \"packageName\": \"tabulark-delimited-wasm\",\n \"crateArtifact\": \"tabulark_delimited\",\n \"outputName\": \"tabulark_delimited\",\n \"outputDirectory\": \"dist/wasm/delimited\",\n \"modulePath\": \"./wasm/delimited/tabulark_delimited.js\",\n \"runtimeExport\": \"WasmRuntime\"\n },\n \"options\": {\n \"allowedKeys\": [\"dialect\", \"header\", \"mode\", \"delimiter\", \"sourceName\"]\n },\n \"resources\": {\n \"sourceAccess\": \"streaming\",\n \"supportsPresentation\": false,\n \"runtimeWeight\": 1\n }\n },\n {\n \"id\": \"tabulark:arrow-ipc\",\n \"entrypoint\": \"./arrow\",\n \"exportName\": \"arrowIpcAdapter\",\n \"wasm\": {\n \"packageName\": \"tabulark-arrow-wasm\",\n \"crateArtifact\": \"tabulark_arrow\",\n \"outputName\": \"tabulark_arrow\",\n \"outputDirectory\": \"dist/wasm/arrow\",\n \"modulePath\": \"./wasm/arrow/tabulark_arrow.js\",\n \"runtimeExport\": \"WasmRuntime\"\n },\n \"options\": {\n \"allowedKeys\": [\"container\", \"sourceName\"]\n },\n \"resources\": {\n \"sourceAccess\": \"range\",\n \"supportsPresentation\": false,\n \"runtimeWeight\": 1\n }\n },\n {\n \"id\": \"tabulark:parquet\",\n \"entrypoint\": \"./parquet\",\n \"exportName\": \"parquetAdapter\",\n \"wasm\": {\n \"packageName\": \"tabulark-parquet-wasm\",\n \"crateArtifact\": \"tabulark_parquet\",\n \"outputName\": \"tabulark_parquet\",\n \"outputDirectory\": \"dist/wasm/parquet\",\n \"modulePath\": \"./wasm/parquet/tabulark_parquet.js\",\n \"runtimeExport\": \"WasmRuntime\"\n },\n \"options\": {\n \"allowedKeys\": [\"sourceName\"]\n },\n \"resources\": {\n \"sourceAccess\": \"range\",\n \"supportsPresentation\": false,\n \"runtimeWeight\": 2\n }\n },\n {\n \"id\": \"tabulark:excel\",\n \"entrypoint\": \"./excel\",\n \"exportName\": \"excelAdapter\",\n \"wasm\": {\n \"packageName\": \"tabulark-excel-wasm\",\n \"crateArtifact\": \"tabulark_excel\",\n \"outputName\": \"tabulark_excel\",\n \"outputDirectory\": \"dist/wasm/excel\",\n \"modulePath\": \"./wasm/excel/tabulark_excel.js\",\n \"runtimeExport\": \"WasmRuntime\"\n },\n \"options\": {\n \"allowedKeys\": [\"format\", \"sourceName\"]\n },\n \"resources\": {\n \"sourceAccess\": \"staged\",\n \"supportsPresentation\": true,\n \"runtimeWeight\": 2\n }\n }\n ]\n}\n", "import manifestJson from \"./official-adapters.json\" with { type: \"json\" };\n\nexport type OfficialAdapterId =\n | \"tabulark:delimited\"\n | \"tabulark:arrow-ipc\"\n | \"tabulark:parquet\"\n | \"tabulark:excel\";\nexport type OfficialSourceAccess = \"streaming\" | \"range\" | \"staged\";\n\nexport interface OfficialAdapterManifestEntry {\n readonly id: OfficialAdapterId;\n readonly entrypoint: \".\" | \"./arrow\" | \"./parquet\" | \"./excel\";\n readonly exportName: string;\n readonly wasm: Readonly<{\n readonly packageName: string;\n readonly crateArtifact: string;\n readonly outputName: string;\n readonly outputDirectory: string;\n readonly modulePath: string;\n readonly runtimeExport: \"WasmRuntime\";\n }>;\n readonly options: Readonly<{ readonly allowedKeys: readonly string[] }>;\n readonly resources: Readonly<{\n readonly sourceAccess: OfficialSourceAccess;\n readonly supportsPresentation: boolean;\n readonly runtimeWeight: number;\n }>;\n}\n\nconst manifestEntries = validateManifest(manifestJson);\n\n/** Runtime IDs are derived from the manifest rather than repeated in code. */\nexport const OFFICIAL_ADAPTER_IDS: readonly OfficialAdapterId[] = Object.freeze(\n manifestEntries.map((entry) => entry.id),\n);\n\n/** The sole internal source of truth for built-in IDs, artifacts and host policy. */\nexport const OFFICIAL_ADAPTER_MANIFEST: readonly OfficialAdapterManifestEntry[] = Object.freeze(\n manifestEntries.map((entry) => Object.freeze({\n ...entry,\n wasm: Object.freeze({ ...entry.wasm }),\n options: Object.freeze({\n allowedKeys: Object.freeze([...entry.options.allowedKeys]),\n }),\n resources: Object.freeze({ ...entry.resources }),\n })),\n);\n\nconst byId = new Map(OFFICIAL_ADAPTER_MANIFEST.map((entry) => [entry.id, entry]));\n\nexport function isOfficialAdapterId(value: unknown): value is OfficialAdapterId {\n return typeof value === \"string\" && byId.has(value as OfficialAdapterId);\n}\n\nexport function officialAdapterManifestEntry(id: OfficialAdapterId): OfficialAdapterManifestEntry {\n const entry = byId.get(id);\n if (!entry) {\n throw new TypeError(`Unknown official adapter: ${id}`);\n }\n return entry;\n}\n\n/** Resolves an official wrapper relative to the bundle that hosts this code. */\nexport function officialAdapterModuleUrl(id: OfficialAdapterId): string {\n return new URL(officialAdapterManifestEntry(id).wasm.modulePath, import.meta.url).href;\n}\n\nfunction validateManifest(value: unknown): readonly OfficialAdapterManifestEntry[] {\n if (!isRecord(value) || value.manifestVersion !== 1 || !Array.isArray(value.adapters)) {\n throw new TypeError(\"The official adapter manifest has an unsupported shape or version\");\n }\n if (value.adapters.length === 0) {\n throw new TypeError(\"The official adapter manifest must contain at least one adapter\");\n }\n const ids = new Set<string>();\n const entrypoints = new Set<string>();\n const outputDirectories = new Set<string>();\n return value.adapters.map((candidate, index) => {\n if (!isRecord(candidate)) {\n throw new TypeError(`Official adapter manifest entry ${index} must be an object`);\n }\n const { id, entrypoint, exportName, wasm, options, resources } = candidate;\n if (!isKnownOfficialAdapterId(id) || ids.has(id)) {\n throw new TypeError(`Official adapter manifest entry ${index} has an invalid or duplicate id`);\n }\n if (\n (entrypoint !== \".\" && entrypoint !== \"./arrow\" && entrypoint !== \"./parquet\" && entrypoint !== \"./excel\")\n || entrypoints.has(entrypoint)\n || typeof exportName !== \"string\"\n || exportName.length === 0\n ) {\n throw new TypeError(`Official adapter manifest entry ${index} has an invalid entrypoint or export`);\n }\n if (\n !isRecord(wasm)\n || typeof wasm.packageName !== \"string\"\n || typeof wasm.crateArtifact !== \"string\"\n || typeof wasm.outputName !== \"string\"\n || typeof wasm.outputDirectory !== \"string\"\n || !wasm.outputDirectory.startsWith(\"dist/wasm/\")\n || wasm.outputDirectory.includes(\"..\")\n || outputDirectories.has(wasm.outputDirectory)\n || typeof wasm.modulePath !== \"string\"\n || !wasm.modulePath.startsWith(\"./wasm/\")\n || wasm.modulePath.includes(\"..\")\n || wasm.modulePath.includes(\"?\")\n || wasm.modulePath.includes(\"#\")\n || wasm.runtimeExport !== \"WasmRuntime\"\n || wasm.modulePath !== `./${wasm.outputDirectory.replace(/^dist\\//u, \"\")}/${wasm.outputName}.js`\n ) {\n throw new TypeError(`Official adapter manifest entry ${index} has an invalid WASM artifact`);\n }\n if (\n !isRecord(options)\n || !Array.isArray(options.allowedKeys)\n || options.allowedKeys.some((key) => typeof key !== \"string\")\n || new Set(options.allowedKeys).size !== options.allowedKeys.length\n ) {\n throw new TypeError(`Official adapter manifest entry ${index} has invalid option keys`);\n }\n if (\n !isRecord(resources)\n || (resources.sourceAccess !== \"streaming\"\n && resources.sourceAccess !== \"range\"\n && resources.sourceAccess !== \"staged\")\n || typeof resources.supportsPresentation !== \"boolean\"\n || !Number.isSafeInteger(resources.runtimeWeight)\n || (resources.runtimeWeight as number) <= 0\n ) {\n throw new TypeError(`Official adapter manifest entry ${index} has an invalid resource policy`);\n }\n ids.add(id);\n entrypoints.add(entrypoint);\n outputDirectories.add(wasm.outputDirectory);\n return candidate as unknown as OfficialAdapterManifestEntry;\n });\n}\n\nfunction isKnownOfficialAdapterId(value: unknown): value is OfficialAdapterId {\n return value === \"tabulark:delimited\"\n || value === \"tabulark:arrow-ipc\"\n || value === \"tabulark:parquet\"\n || value === \"tabulark:excel\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n", "import {\n isOfficialAdapterId,\n officialAdapterManifestEntry,\n type OfficialAdapterId,\n} from \"./official-adapter-manifest.js\";\n\nexport type { OfficialAdapterId } from \"./official-adapter-manifest.js\";\n\nexport type DelimitedDialect = \"csv\" | \"tsv\";\nexport type HeaderMode = \"first-row\" | \"none\";\nexport type ParseMode = \"lenient\" | \"strict\";\n\n/** Options understood by the built-in delimited adapter. */\nexport interface DelimitedAdapterOptions {\n /** Defaults to `csv`. No filename-based selection is performed. */\n readonly dialect?: DelimitedDialect;\n readonly header?: HeaderMode;\n readonly mode?: ParseMode;\n /** One ASCII delimiter byte. Overrides the dialect default when supplied. */\n readonly delimiter?: string;\n /** Optional display name for the source. */\n readonly sourceName?: string;\n}\n\nexport type ArrowIpcContainer = \"auto\" | \"file\" | \"stream\";\n\n/** Options understood by the built-in Arrow IPC adapter. */\nexport interface ArrowIpcAdapterOptions {\n /** Defaults to `auto`; format detection belongs to the Arrow adapter. */\n readonly container?: ArrowIpcContainer;\n /** Optional display name for the source. */\n readonly sourceName?: string;\n}\n\n/** Options understood by the built-in Parquet adapter. */\nexport interface ParquetAdapterOptions {\n /** Optional display name for the source. */\n readonly sourceName?: string;\n}\n\nexport type ExcelFormat = \"auto\" | \"xls\" | \"xlsx\";\n\n/** Options understood by the built-in Excel adapter. */\nexport interface ExcelAdapterOptions {\n /** Defaults to `auto`; the adapter identifies the file from its signature. */\n readonly format?: ExcelFormat;\n /** Optional display name for the source. */\n readonly sourceName?: string;\n}\n\n/**\n * A frozen descriptor for one built-in adapter.\n *\n * Descriptors select a named official artifact only. They are deliberately not\n * factories and cannot carry a module URL or a third-party implementation.\n */\nexport interface AdapterDescriptor<\n Id extends OfficialAdapterId = OfficialAdapterId,\n Options = unknown,\n> {\n readonly id: Id;\n readonly kind: \"official\";\n /** Carries the option type without exposing a runtime extension point. */\n readonly __options?: Options;\n}\n\ninterface InternalAdapterDescriptor<\n Id extends OfficialAdapterId = OfficialAdapterId,\n Options = unknown,\n> extends AdapterDescriptor<Id, Options> {\n readonly [OFFICIAL_ADAPTER]: Readonly<{ readonly id: Id }>;\n}\n\n/**\n * A process-global symbol permits descriptors from separately bundled stable\n * entrypoints to be recognized. It conveys no capability: the manifest below\n * still owns the selected module URL and resource policy.\n */\nconst OFFICIAL_ADAPTER = Symbol.for(\"tabulark.official-adapter.v2\");\n\nexport interface AdapterRegistration {\n readonly id: OfficialAdapterId;\n}\n\nfunction createOfficialAdapter<Id extends OfficialAdapterId, Options>(\n id: Id,\n): AdapterDescriptor<Id, Options> {\n const marker = Object.freeze({ id });\n return Object.freeze({\n id,\n kind: \"official\" as const,\n [OFFICIAL_ADAPTER]: marker,\n }) as InternalAdapterDescriptor<Id, Options>;\n}\n\n/** The built-in RFC-style delimited text adapter. */\nexport const delimitedAdapter = createOfficialAdapter<\n \"tabulark:delimited\",\n DelimitedAdapterOptions\n>(\"tabulark:delimited\");\n\n/** @internal Used by the stable `/arrow` entrypoint. */\nexport function createArrowIpcAdapter(): AdapterDescriptor<\"tabulark:arrow-ipc\", ArrowIpcAdapterOptions> {\n return createOfficialAdapter<\"tabulark:arrow-ipc\", ArrowIpcAdapterOptions>(\"tabulark:arrow-ipc\");\n}\n\n/** @internal Used by the stable `/parquet` entrypoint. */\nexport function createParquetAdapter(): AdapterDescriptor<\"tabulark:parquet\", ParquetAdapterOptions> {\n return createOfficialAdapter<\"tabulark:parquet\", ParquetAdapterOptions>(\"tabulark:parquet\");\n}\n\n/** @internal Used by the stable `/excel` entrypoint. */\nexport function createExcelAdapter(): AdapterDescriptor<\"tabulark:excel\", ExcelAdapterOptions> {\n return createOfficialAdapter<\"tabulark:excel\", ExcelAdapterOptions>(\"tabulark:excel\");\n}\n\n/** @internal Validates and extracts the non-public Worker registration. */\nexport function resolveOfficialAdapter(value: unknown): AdapterRegistration | undefined {\n if (!isRecord(value) || !Object.isFrozen(value) || !isOfficialAdapterId(value.id) || value.kind !== \"official\") {\n return undefined;\n }\n const marker = value[OFFICIAL_ADAPTER];\n if (!isRecord(marker) || marker.id !== value.id) {\n return undefined;\n }\n // A marker may be recreated by another bundle, but it conveys no URL or\n // implementation capability: it can select only a manifest-owned ID.\n officialAdapterManifestEntry(value.id);\n return Object.freeze({ id: value.id });\n}\n\nfunction isRecord(value: unknown): value is Record<PropertyKey, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n", "/** Version 3 introduces multi-table presentation and discriminated adapter steps. */\nexport const PROTOCOL_VERSION = 3 as const;\n\n/** Version of the private, built-in Rust adapter contract. */\nexport const ADAPTER_API_VERSION = 2 as const;\n\n/** Version of the descriptor + deduplicated-buffer batch transport. */\nexport const BATCH_LAYOUT_VERSION = 1 as const;\n\nexport type ProtocolVersion = typeof PROTOCOL_VERSION;\n\nexport type Operation =\n | \"hello\"\n | \"openSource\"\n | \"listTables\"\n | \"openTable\"\n | \"getMetadata\"\n | \"getPresentation\"\n | \"readPresentationRange\"\n | \"readRange\"\n | \"cancel\"\n | \"closeTable\"\n | \"closeSource\"\n | \"shutdown\";\n\nexport interface ProtocolRequest<T = unknown> {\n readonly protocolVersion: ProtocolVersion;\n readonly requestId: string;\n readonly op: Operation;\n readonly payload: T;\n}\n\nexport type ResponseKind =\n | \"hello\"\n | \"dataset\"\n | \"tables\"\n | \"table\"\n | \"metadata\"\n | \"presentation\"\n | \"presentationRange\"\n | \"batch\"\n | \"acknowledged\";\n\nexport interface ProtocolResult<T = unknown> {\n readonly kind: ResponseKind;\n readonly data?: T;\n}\n\nexport interface ProtocolSuccess<T = unknown> {\n readonly protocolVersion: ProtocolVersion;\n readonly requestId: string;\n readonly status: \"success\";\n readonly result: ProtocolResult<T>;\n}\n\nexport interface SerializedError {\n readonly code: string;\n readonly message: string;\n readonly retryable: boolean;\n readonly details?: unknown;\n}\n\nexport interface ProtocolFailure {\n readonly protocolVersion: ProtocolVersion;\n readonly requestId: string;\n readonly status: \"failure\";\n readonly error: SerializedError;\n}\n\nexport type ProtocolResponse<T = unknown> =\n | ProtocolSuccess<T>\n | ProtocolFailure;\n\nexport type RuntimeEventName =\n | \"progress\"\n | \"metadata\"\n | \"warning\"\n | \"closed\"\n | \"runtimeError\";\n\nexport interface ProtocolEvent<T = unknown> {\n readonly protocolVersion: ProtocolVersion;\n readonly requestId?: string;\n readonly event: RuntimeEventName;\n /** Required for dataset/table events; omitted only by a process-wide runtimeError. */\n readonly datasetHandle?: string;\n readonly tableHandle?: string;\n readonly tableId?: string;\n /** Revision associated with a table-scoped event, when known. */\n readonly revision?: number;\n readonly payload: T;\n}\n\nexport function isProtocolResponse(value: unknown): value is ProtocolResponse {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n value.protocolVersion === PROTOCOL_VERSION &&\n typeof value.requestId === \"string\" &&\n (value.status === \"success\" || value.status === \"failure\")\n );\n}\n\nexport function isProtocolEvent(value: unknown): value is ProtocolEvent {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n value.protocolVersion === PROTOCOL_VERSION &&\n typeof value.event === \"string\" &&\n \"payload\" in value\n );\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n", "import { TabularkError, invalidArgument } from \"./errors.js\";\nimport { BATCH_LAYOUT_VERSION } from \"./protocol.js\";\n\nexport const DEFAULT_MEMORY_BUDGET_BYTES = 256 * 1024 * 1024;\nexport const MAX_ARRAY_BUFFER_BYTES = 128 * 1024 * 1024;\nexport const MAX_RANGE_CELLS = 250_000;\nexport const DEFAULT_TO_ROWS_CELL_LIMIT = 10_000;\nexport const MAX_NESTING_DEPTH = 64;\n\nconst INDEX_BUDGET_MAX_BYTES = 64 * 1024 * 1024;\nconst WORKER_RANGE_CACHE_MAX_BYTES = 96 * 1024 * 1024;\nconst MAIN_THREAD_RANGE_CACHE_MAX_BYTES = 32 * 1024 * 1024;\nconst FIELD_AND_BATCH_MAX_BYTES = 8 * 1024 * 1024;\n\nexport const MAX_SOURCES = 2;\nexport const MAX_ACTIVE_RANGES = 2;\nexport const MAX_RANGE_WAITERS = 8;\n\nexport interface MemoryBudgetLimits {\n readonly memoryBudgetBytes: number;\n /** Shared retained capacity allocated among the adapters actually registered. */\n readonly adapterRuntimePoolBytes: number;\n /** Maximum transient/decoded budget retained by one active adapter operation. */\n readonly operationBudgetBytes: number;\n readonly indexBudgetBytes: number;\n readonly adapterTileCacheBudgetBytes: number;\n readonly workerRangeCacheBytes: number;\n readonly workerDatasetRangeCacheBytes: number;\n readonly mainThreadRangeCacheBytes: number;\n readonly maxFieldBytes: number;\n readonly maxBatchBytes: number;\n readonly maxArrayBufferBytes: number;\n readonly maxSources: number;\n readonly maxActiveRanges: number;\n readonly maxRangeWaiters: number;\n}\n\n/** Derives every bounded runtime allocation from one engine-wide budget. */\nexport function deriveMemoryBudgetLimits(memoryBudgetBytes: number): MemoryBudgetLimits {\n assertPositiveSafeInteger(memoryBudgetBytes, \"memoryBudgetBytes\");\n const oneEighth = Math.floor(memoryBudgetBytes / 8);\n const oneThirtySecond = Math.floor(memoryBudgetBytes / 32);\n // The Worker allocates this pool through one reservation ledger using the\n // adapters actually registered for an engine. This deliberately avoids a\n // hard-coded split based on a historic number of built-in adapters.\n const adapterRuntimePoolBytes = Math.max(1, Math.floor(memoryBudgetBytes / 2));\n const operationBudgetBytes = Math.max(1, Math.floor(memoryBudgetBytes / 8));\n const workerRangeCacheBytes = Math.min(\n WORKER_RANGE_CACHE_MAX_BYTES,\n Math.floor((memoryBudgetBytes / 8) * 3),\n );\n return Object.freeze({\n memoryBudgetBytes,\n adapterRuntimePoolBytes,\n operationBudgetBytes,\n indexBudgetBytes: Math.min(INDEX_BUDGET_MAX_BYTES, oneEighth),\n adapterTileCacheBudgetBytes: Math.min(WORKER_RANGE_CACHE_MAX_BYTES, operationBudgetBytes),\n workerRangeCacheBytes,\n workerDatasetRangeCacheBytes: Math.floor(workerRangeCacheBytes / MAX_SOURCES),\n mainThreadRangeCacheBytes: Math.min(MAIN_THREAD_RANGE_CACHE_MAX_BYTES, oneEighth),\n maxFieldBytes: Math.min(FIELD_AND_BATCH_MAX_BYTES, oneThirtySecond),\n maxBatchBytes: Math.min(FIELD_AND_BATCH_MAX_BYTES, oneThirtySecond),\n maxArrayBufferBytes: Math.min(MAX_ARRAY_BUFFER_BYTES, Math.floor(memoryBudgetBytes / 2)),\n maxSources: MAX_SOURCES,\n maxActiveRanges: MAX_ACTIVE_RANGES,\n maxRangeWaiters: MAX_RANGE_WAITERS,\n });\n}\n\nexport type MemoryResourceKind =\n | \"adapter-runtime\"\n | \"source-staging\"\n | \"compressed-page\"\n | \"decompression\"\n | \"opened-worksheet\"\n | \"batch\"\n | \"range-cache\";\n\nexport interface MemoryReservation {\n readonly resource: MemoryResourceKind;\n readonly bytes: number;\n release(): void;\n}\n\n/**\n * Single-accounting ledger for Worker-owned bounded allocations.\n *\n * A reservation is deliberately idempotent so cancellation, close and failure\n * races can all execute their normal cleanup paths without double accounting.\n */\nexport class MemoryReservationLedger {\n readonly #capacityBytes: number;\n #usedBytes = 0;\n\n constructor(capacityBytes: number) {\n assertPositiveSafeInteger(capacityBytes, \"capacityBytes\");\n this.#capacityBytes = capacityBytes;\n }\n\n get capacityBytes(): number {\n return this.#capacityBytes;\n }\n\n get usedBytes(): number {\n return this.#usedBytes;\n }\n\n get availableBytes(): number {\n return this.#capacityBytes - this.#usedBytes;\n }\n\n reserve(resource: MemoryResourceKind, bytes: number): MemoryReservation {\n if (!Number.isSafeInteger(bytes) || bytes < 0) {\n throw invalidArgument(\"Reservation bytes must be a non-negative safe integer\");\n }\n const availableBytes = this.availableBytes;\n if (bytes > availableBytes) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `Insufficient memory reservation capacity for ${resource}`,\n { details: { resource, requiredBytes: bytes, availableBytes } },\n );\n }\n this.#usedBytes += bytes;\n let released = false;\n return Object.freeze({\n resource,\n bytes,\n release: () => {\n if (released) return;\n released = true;\n this.#usedBytes -= bytes;\n },\n });\n }\n}\n\nexport type AxisExtent =\n | Readonly<{ kind: \"exact\"; value: number }>\n | Readonly<{ kind: \"at-least\"; value: number }>\n | Readonly<{ kind: \"unknown\" }>;\n\nexport interface TableExtent {\n readonly rows: AxisExtent;\n readonly columns: AxisExtent;\n}\n\nexport type TimeUnit = \"second\" | \"millisecond\" | \"microsecond\" | \"nanosecond\";\nexport type IntervalUnit = \"year-month\" | \"day-time\" | \"month-day-nano\";\n\nexport interface ArrowField {\n readonly name: string;\n readonly nullable: boolean;\n readonly dataType: ArrowDataType;\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\ninterface SimpleDataType<Type extends string> {\n readonly type: Type;\n}\n\n/** A recursive representation of every arrow-schema 59.1.0 built-in DataType. */\nexport type ArrowDataType =\n | SimpleDataType<\n | \"null\"\n | \"unknown\"\n | \"boolean\"\n | \"int8\"\n | \"int16\"\n | \"int32\"\n | \"int64\"\n | \"uint8\"\n | \"uint16\"\n | \"uint32\"\n | \"uint64\"\n | \"float16\"\n | \"float32\"\n | \"float64\"\n | \"date32\"\n | \"date64\"\n | \"binary\"\n | \"large-binary\"\n | \"binary-view\"\n | \"utf8\"\n | \"large-utf8\"\n | \"utf8-view\"\n >\n | Readonly<{ type: \"timestamp\"; unit: TimeUnit; timezone?: string }>\n | Readonly<{ type: \"time32\" | \"time64\" | \"duration\"; unit: TimeUnit }>\n | Readonly<{ type: \"interval\"; unit: IntervalUnit }>\n | Readonly<{ type: \"fixed-size-binary\"; byteWidth: number }>\n | Readonly<{ type: \"decimal32\" | \"decimal64\" | \"decimal128\" | \"decimal256\"; precision: number; scale: number }>\n | Readonly<{ type: \"list\" | \"large-list\" | \"list-view\" | \"large-list-view\"; field: ArrowField }>\n | Readonly<{ type: \"fixed-size-list\"; field: ArrowField; listSize: number }>\n | Readonly<{ type: \"struct\"; fields: readonly ArrowField[] }>\n | Readonly<{\n type: \"union\";\n mode: \"sparse\" | \"dense\";\n fields: readonly Readonly<{ typeId: number; field: ArrowField }>[];\n }>\n | Readonly<{\n type: \"dictionary\";\n indexType: ArrowDataType;\n valueType: ArrowDataType;\n ordered?: boolean;\n }>\n | Readonly<{ type: \"map\"; entries: ArrowField; keysSorted: boolean }>\n | Readonly<{ type: \"run-end-encoded\"; runEnds: ArrowField; values: ArrowField }>\n | Readonly<{\n type: \"extension\";\n name: string;\n metadata?: string;\n storageType: ArrowDataType;\n }>;\n\nexport interface ColumnSchema {\n readonly id: string;\n readonly name: string;\n readonly index: number;\n readonly dataType: ArrowDataType;\n readonly nullable: boolean;\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\nexport interface TableCapabilities {\n readonly randomAccess: \"indexed-prefix\" | \"full\";\n readonly typedValues: boolean;\n readonly search: boolean;\n readonly sort: boolean;\n readonly filter: boolean;\n readonly multiTable: boolean;\n readonly [name: string]: unknown;\n}\n\nexport interface TableMetadata {\n readonly tableId: string;\n readonly name: string;\n readonly revision: number;\n readonly extent: Readonly<TableExtent>;\n readonly schema: Readonly<{\n readonly version: number;\n readonly columns: readonly Readonly<ColumnSchema>[];\n }>;\n readonly capabilities: Readonly<TableCapabilities>;\n}\n\nexport type WorksheetVisibility = \"visible\" | \"hidden\" | \"very-hidden\";\n\n/** One sparse row or column override supplied by a spreadsheet presentation. */\nexport interface PresentationAxisEntry {\n readonly index: number;\n /** CSS pixel extent when the source supplies an explicit dimension. */\n readonly size?: number;\n readonly hidden?: boolean;\n}\n\nexport interface PresentationColor {\n /** CSS-compatible resolved color, when the workbook supplied one. */\n readonly css?: string;\n}\n\nexport interface PresentationFont {\n readonly family?: string;\n readonly size?: number;\n readonly bold?: boolean;\n readonly italic?: boolean;\n readonly underline?: boolean;\n readonly color?: PresentationColor;\n}\n\nexport interface PresentationBorderSide {\n readonly style?: \"none\" | \"thin\" | \"medium\" | \"thick\" | \"dashed\" | \"dotted\" | \"double\";\n readonly color?: PresentationColor;\n}\n\n/** Static cell styling that 0.1 preserves from spreadsheet input. */\nexport interface PresentationStyle {\n readonly numberFormat?: string;\n readonly font?: PresentationFont;\n readonly foregroundColor?: PresentationColor;\n readonly backgroundColor?: PresentationColor;\n readonly fillColor?: PresentationColor;\n readonly borders?: Readonly<{\n readonly top?: PresentationBorderSide;\n readonly right?: PresentationBorderSide;\n readonly bottom?: PresentationBorderSide;\n readonly left?: PresentationBorderSide;\n }>;\n readonly horizontalAlignment?: \"general\" | \"left\" | \"center\" | \"right\" | \"justify\";\n readonly verticalAlignment?: \"top\" | \"center\" | \"bottom\" | \"justify\";\n readonly wrapText?: boolean;\n}\n\nexport interface MergedCellRegion {\n readonly rowStart: number;\n readonly rowEnd: number;\n readonly columnStart: number;\n readonly columnEnd: number;\n}\n\n/**\n * Presentation metadata for a worksheet. It is intentionally static: formula\n * calculation and document round-tripping are outside the 0.1 contract.\n */\nexport interface SpreadsheetPresentation {\n readonly kind: \"spreadsheet-v1\";\n readonly tableId: string;\n readonly revision: number;\n readonly visibility: WorksheetVisibility;\n readonly frozenRows: number;\n readonly frozenColumns: number;\n readonly rows: readonly PresentationAxisEntry[];\n readonly columns: readonly PresentationAxisEntry[];\n /** Deduplicated styles addressed by `SpreadsheetPresentationRange.styleIds`. */\n readonly styles: readonly PresentationStyle[];\n}\n\nexport type TablePresentation = SpreadsheetPresentation;\n\nexport interface SpreadsheetPresentationRange {\n readonly kind: \"spreadsheet-v1\";\n readonly tableId: string;\n readonly revision: number;\n readonly range: Readonly<ReturnedRange>;\n /** Rows and columns are exactly aligned with `range`; null means no style. */\n readonly styleIds: readonly (readonly (number | null)[])[];\n readonly mergedCells: readonly MergedCellRegion[];\n /** Sparse layout entries that intersect this requested range. */\n readonly rows: readonly PresentationAxisEntry[];\n readonly columns: readonly PresentationAxisEntry[];\n}\n\nexport type PresentationRange = SpreadsheetPresentationRange;\n\nexport interface TableDescriptor {\n readonly id: string;\n readonly name: string;\n}\n\nexport interface RangeRequest {\n readonly rowStart: number;\n readonly rowCount: number;\n readonly columnStart: number;\n readonly columnCount: number;\n}\n\nexport interface ReturnedRange extends RangeRequest {}\n\n/** A byte region in the batch's deduplicated buffer pool. */\nexport interface BatchBufferRegion {\n readonly buffer: number;\n readonly byteOffset?: number;\n readonly byteLength?: number;\n /** First bit for bitmap regions; ignored for byte-oriented regions. */\n readonly bitOffset?: number;\n}\n\n/** UTF-8 text generated by Rust for rendering, ARIA, width measurement and copy. */\nexport interface DisplayColumnDescriptor {\n readonly encoding: \"utf8\";\n readonly data: BatchBufferRegion;\n readonly offsets: BatchBufferRegion;\n readonly validity?: BatchBufferRegion;\n /** Logical offset into the display arrays, for sliced batches. */\n readonly offset?: number;\n}\n\n/**\n * Recursive Arrow ArrayData layout. Buffer regions always point into the\n * enclosing TableBatch buffer pool; encoded dictionaries and run ends remain\n * visible in this descriptor even though `toRows()` returns logical values.\n */\nexport interface NativeColumnDescriptor {\n /** Rust ArrayData layout encoding (for example `dictionary` or `run-end-encoded`). */\n readonly encoding?: string;\n readonly dataType: ArrowDataType;\n readonly length: number;\n readonly offset?: number;\n readonly validity?: BatchBufferRegion;\n readonly values?: BatchBufferRegion;\n readonly offsets?: BatchBufferRegion;\n readonly sizes?: BatchBufferRegion;\n readonly data?: BatchBufferRegion;\n readonly typeIds?: BatchBufferRegion;\n readonly unionOffsets?: BatchBufferRegion;\n readonly variadicBuffers?: readonly BatchBufferRegion[];\n readonly children?: readonly NativeColumnDescriptor[];\n readonly dictionary?: NativeColumnDescriptor;\n readonly runEnds?: NativeColumnDescriptor;\n readonly typeId?: number;\n}\n\n/** @internal Layout-v1 column descriptor received from an official WASM runtime. */\nexport interface WireTableBatchColumn {\n readonly columnId: string;\n readonly native: NativeColumnDescriptor;\n readonly display: DisplayColumnDescriptor;\n}\n\nexport interface DecimalValue {\n readonly kind: \"decimal\";\n readonly unscaled: bigint;\n readonly precision: number;\n readonly scale: number;\n}\n\nexport interface TemporalValue {\n readonly kind: \"date32\" | \"date64\" | \"time32\" | \"time64\" | \"timestamp\" | \"duration\";\n readonly value: number | bigint;\n readonly unit?: TimeUnit;\n readonly timezone?: string;\n}\n\nexport interface IntervalValue {\n readonly kind: \"interval\";\n readonly unit: IntervalUnit;\n readonly months?: number;\n readonly days?: number;\n readonly milliseconds?: number;\n readonly nanoseconds?: bigint;\n}\n\nexport interface UnionValue {\n readonly kind: \"union\";\n readonly typeId: number;\n readonly value: NativeValue | null;\n}\n\nexport interface MapEntryValue {\n readonly key: NativeValue | null;\n readonly value: NativeValue | null;\n}\n\nexport interface NativeListValue extends ReadonlyArray<NativeValue | null> {}\nexport interface NativeStructValue {\n readonly [name: string]: NativeValue | null;\n}\nexport interface NativeMapValue extends ReadonlyArray<Readonly<MapEntryValue>> {}\n\nexport type NativeValue =\n | boolean\n | number\n | bigint\n | string\n | Uint8Array\n | DecimalValue\n | TemporalValue\n | IntervalValue\n | UnionValue\n | NativeListValue\n | NativeStructValue\n | NativeMapValue;\n\nexport interface ToRowsOptions {\n /** Maximum decoded cells. Defaults to 10,000. */\n readonly maxCells?: number;\n}\n\n/**\n * Logical, column-oriented access to one returned batch column.\n *\n * Values are indexed relative to `TableBatch.range.rowStart`; physical buffer\n * regions and adapter transport details intentionally remain private.\n */\nexport interface TableBatchColumn {\n readonly columnId: string;\n readonly columnIndex: number;\n readonly rowCount: number;\n getValue(rowOffset: number): NativeValue | null;\n getDisplayValue(rowOffset: number): string | null;\n toValues(options?: ToRowsOptions): (NativeValue | null)[];\n toDisplayValues(options?: ToRowsOptions): (string | null)[];\n}\n\n/** Stable logical batch contract. Wire buffers and ABI layout stay private. */\nexport interface TableBatch {\n readonly tableId: string;\n readonly revision: number;\n readonly schemaVersion: number;\n readonly range: Readonly<ReturnedRange>;\n readonly columns: readonly TableBatchColumn[];\n readonly complete: boolean;\n toRows(options?: ToRowsOptions): (NativeValue | null)[][];\n toDisplayRows(options?: ToRowsOptions): (string | null)[][];\n}\n\nexport type WireBatchBuffer = ArrayBuffer | ArrayBufferView;\n\nexport interface WireTableBatch {\n readonly layoutVersion: typeof BATCH_LAYOUT_VERSION;\n readonly tableId: string;\n readonly revision: number;\n readonly schemaVersion: number;\n readonly range: ReturnedRange;\n readonly buffers: readonly WireBatchBuffer[];\n readonly columns: readonly WireTableBatchColumn[];\n readonly complete: boolean;\n}\n\n/** Owns and validates one generic layout-v1 batch received from the Worker. */\nexport class ColumnarTableBatch implements TableBatch {\n readonly tableId: string;\n readonly revision: number;\n readonly schemaVersion: number;\n readonly range: Readonly<ReturnedRange>;\n readonly columns: readonly TableBatchColumn[];\n readonly complete: boolean;\n readonly #buffers: readonly Uint8Array[];\n readonly #wireColumns: readonly WireTableBatchColumn[];\n\n constructor(value: WireTableBatch) {\n if (value.layoutVersion !== BATCH_LAYOUT_VERSION) {\n throw invalidArgument(\n `Batch layout ${String(value.layoutVersion)} is incompatible with layout ${BATCH_LAYOUT_VERSION}`,\n );\n }\n this.tableId = value.tableId;\n this.revision = value.revision;\n this.schemaVersion = value.schemaVersion;\n this.range = Object.freeze({ ...value.range });\n this.#buffers = Object.freeze(value.buffers.map(asUint8Array));\n this.#wireColumns = Object.freeze(value.columns.map((column) => freezeWireColumn(column)));\n this.complete = value.complete;\n validateWireBatch(this.range, this.#buffers, this.#wireColumns);\n this.columns = Object.freeze(this.#wireColumns.map((column, index) => new LogicalBatchColumn(\n column,\n this.#buffers,\n this.range.rowCount,\n this.range.columnStart + index,\n )));\n }\n\n toRows(options: ToRowsOptions = {}): (NativeValue | null)[][] {\n const maxCells = normalizeCellLimit(options.maxCells);\n assertCellLimit(this.range.rowCount, this.columns.length, maxCells);\n const rows: (NativeValue | null)[][] = Array.from(\n { length: this.range.rowCount },\n () => Array<NativeValue | null>(this.columns.length),\n );\n for (let columnIndex = 0; columnIndex < this.columns.length; columnIndex += 1) {\n for (let rowIndex = 0; rowIndex < this.range.rowCount; rowIndex += 1) {\n rows[rowIndex]![columnIndex] = this.columns[columnIndex]!.getValue(rowIndex);\n }\n }\n return rows;\n }\n\n toDisplayRows(options: ToRowsOptions = {}): (string | null)[][] {\n const maxCells = normalizeCellLimit(options.maxCells);\n assertCellLimit(this.range.rowCount, this.columns.length, maxCells);\n const rows: (string | null)[][] = Array.from(\n { length: this.range.rowCount },\n () => Array<string | null>(this.columns.length),\n );\n\n for (let columnIndex = 0; columnIndex < this.columns.length; columnIndex += 1) {\n for (let rowIndex = 0; rowIndex < this.range.rowCount; rowIndex += 1) {\n rows[rowIndex]![columnIndex] = this.columns[columnIndex]!.getDisplayValue(rowIndex);\n }\n }\n return rows;\n }\n}\n\nclass LogicalBatchColumn implements TableBatchColumn {\n readonly columnId: string;\n readonly columnIndex: number;\n readonly rowCount: number;\n readonly #wire: WireTableBatchColumn;\n readonly #buffers: readonly Uint8Array[];\n\n constructor(\n wire: WireTableBatchColumn,\n buffers: readonly Uint8Array[],\n rowCount: number,\n columnIndex: number,\n ) {\n this.columnId = wire.columnId;\n this.columnIndex = columnIndex;\n this.rowCount = rowCount;\n this.#wire = wire;\n this.#buffers = buffers;\n Object.freeze(this);\n }\n\n getValue(rowOffset: number): NativeValue | null {\n assertBatchRowOffset(rowOffset, this.rowCount);\n return decodeNativeValue(this.#wire.native, rowOffset, this.#buffers, 0);\n }\n\n getDisplayValue(rowOffset: number): string | null {\n assertBatchRowOffset(rowOffset, this.rowCount);\n return decodeDisplayValue(this.#wire.display, rowOffset, this.#buffers, this.columnId);\n }\n\n toValues(options: ToRowsOptions = {}): (NativeValue | null)[] {\n const maxCells = normalizeCellLimit(options.maxCells);\n assertCellLimit(this.rowCount, 1, maxCells);\n return Array.from({ length: this.rowCount }, (_, index) => this.getValue(index));\n }\n\n toDisplayValues(options: ToRowsOptions = {}): (string | null)[] {\n const maxCells = normalizeCellLimit(options.maxCells);\n assertCellLimit(this.rowCount, 1, maxCells);\n return Array.from({ length: this.rowCount }, (_, index) => this.getDisplayValue(index));\n }\n}\n\nfunction assertBatchRowOffset(rowOffset: number, rowCount: number): void {\n if (!Number.isSafeInteger(rowOffset) || rowOffset < 0 || rowOffset >= rowCount) {\n throw invalidArgument(`Batch row offset must be an integer from 0 through ${Math.max(0, rowCount - 1)}`);\n }\n}\n\nfunction decodeDisplayValue(\n display: DisplayColumnDescriptor,\n rowOffset: number,\n buffers: readonly Uint8Array[],\n columnId: string,\n): string | null {\n const physicalIndex = (display.offset ?? 0) + rowOffset;\n if (!validAt(display.validity, physicalIndex, buffers)) {\n return null;\n }\n const offsets = regionView(display.offsets, buffers, \"display offsets\");\n const data = regionView(display.data, buffers, \"display data\");\n const start = readUnsignedOffset(offsets, physicalIndex, 4);\n const end = readUnsignedOffset(offsets, physicalIndex + 1, 4);\n if (end < start || end > data.byteLength) {\n throw invalidArgument(`Column ${columnId} has invalid display offsets`);\n }\n return new TextDecoder().decode(data.subarray(start, end));\n}\n\nexport function validateRange(request: RangeRequest): RangeRequest {\n for (const [name, value] of Object.entries(request)) {\n assertNonNegativeSafeInteger(value, name);\n }\n if (\n !Number.isSafeInteger(request.rowStart + request.rowCount)\n || !Number.isSafeInteger(request.columnStart + request.columnCount)\n ) {\n throw new TabularkError(\"INVALID_RANGE\", \"Range end must be a safe integer\");\n }\n const cells = request.rowCount * request.columnCount;\n if (!Number.isSafeInteger(cells) || cells > MAX_RANGE_CELLS) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `A range may contain at most ${MAX_RANGE_CELLS} cells`,\n {\n details: {\n resource: \"range-cells\",\n required: cells,\n available: MAX_RANGE_CELLS,\n cells,\n limit: MAX_RANGE_CELLS,\n },\n },\n );\n }\n return Object.freeze({ ...request });\n}\n\nexport function normalizeMetadata(value: TableMetadata): Readonly<TableMetadata> {\n return Object.freeze({\n ...value,\n extent: Object.freeze({\n rows: Object.freeze({ ...value.extent.rows }),\n columns: Object.freeze({ ...value.extent.columns }),\n }),\n schema: Object.freeze({\n version: value.schema.version,\n columns: Object.freeze(value.schema.columns.map((column) => Object.freeze({\n ...column,\n dataType: freezeDataType(column.dataType),\n ...(column.metadata ? { metadata: Object.freeze({ ...column.metadata }) } : {}),\n }))),\n }),\n capabilities: Object.freeze({ ...value.capabilities }),\n });\n}\n\n/** Normalizes a protocol DataType and rejects cycles or excessive nesting. */\nexport function normalizeDataType(value: unknown, depth = 0): ArrowDataType {\n if (depth >= MAX_NESTING_DEPTH) {\n throw invalidArgument(`Arrow data type nesting may not exceed ${MAX_NESTING_DEPTH}`);\n }\n if (!isRecord(value) || typeof value.type !== \"string\") {\n throw invalidArgument(\"Column dataType must be a recursive Arrow data type descriptor\");\n }\n const type: string = ({\n \"u-int8\": \"uint8\",\n \"u-int16\": \"uint16\",\n \"u-int32\": \"uint32\",\n \"u-int64\": \"uint64\",\n } as const)[value.type as \"u-int8\" | \"u-int16\" | \"u-int32\" | \"u-int64\"] ?? value.type;\n const simple = new Set([\n \"unknown\", \"null\", \"boolean\", \"int8\", \"int16\", \"int32\", \"int64\", \"uint8\", \"uint16\", \"uint32\", \"uint64\",\n \"float16\", \"float32\", \"float64\", \"date32\", \"date64\", \"binary\", \"large-binary\", \"binary-view\",\n \"utf8\", \"large-utf8\", \"utf8-view\",\n ]);\n if (simple.has(type)) {\n return Object.freeze({ type }) as ArrowDataType;\n }\n if (type === \"timestamp\") {\n return Object.freeze({\n type,\n unit: timeUnit(value.unit),\n ...(typeof value.timezone === \"string\" ? { timezone: value.timezone } : {}),\n });\n }\n if (type === \"time32\" || type === \"time64\" || type === \"duration\") {\n return Object.freeze({ type, unit: timeUnit(value.unit) });\n }\n if (type === \"interval\") {\n return Object.freeze({ type, unit: intervalUnit(value.unit) });\n }\n if (type === \"fixed-size-binary\") {\n return Object.freeze({\n type,\n byteWidth: positiveInteger(value.byteWidth ?? value.byte_width, \"byteWidth\"),\n });\n }\n if (type === \"decimal32\" || type === \"decimal64\" || type === \"decimal128\" || type === \"decimal256\") {\n return Object.freeze({\n type,\n precision: positiveInteger(value.precision, \"precision\"),\n scale: integer(value.scale, \"scale\"),\n });\n }\n if (type === \"list\" || type === \"large-list\" || type === \"list-view\" || type === \"large-list-view\") {\n return Object.freeze({ type, field: normalizeField(value.field, depth + 1) });\n }\n if (type === \"fixed-size-list\") {\n return Object.freeze({\n type,\n field: normalizeField(value.field, depth + 1),\n listSize: positiveInteger(value.listSize ?? value.list_size, \"listSize\"),\n });\n }\n if (type === \"struct\") {\n if (!Array.isArray(value.fields)) {\n throw invalidArgument(\"Struct fields must be an array\");\n }\n return Object.freeze({\n type,\n fields: Object.freeze(value.fields.map((field) => normalizeField(field, depth + 1))),\n });\n }\n if (type === \"union\") {\n if (!Array.isArray(value.fields) || (value.mode !== \"sparse\" && value.mode !== \"dense\")) {\n throw invalidArgument(\"Union dataType requires a mode and fields\");\n }\n return Object.freeze({\n type,\n mode: value.mode,\n fields: Object.freeze(value.fields.map((entry) => {\n if (!isRecord(entry)) {\n throw invalidArgument(\"Union field entries must be objects\");\n }\n return Object.freeze({\n typeId: integer(entry.typeId, \"typeId\"),\n field: normalizeField(entry.field, depth + 1),\n });\n })),\n });\n }\n if (type === \"dictionary\") {\n return Object.freeze({\n type,\n indexType: normalizeDataType(value.indexType, depth + 1),\n valueType: normalizeDataType(value.valueType, depth + 1),\n ...(value.ordered === true ? { ordered: true } : {}),\n });\n }\n if (type === \"map\") {\n return Object.freeze({\n type,\n entries: normalizeField(value.entries, depth + 1),\n keysSorted: value.keysSorted === true || value.keys_sorted === true,\n });\n }\n if (type === \"run-end-encoded\") {\n return Object.freeze({\n type,\n runEnds: normalizeField(value.runEnds ?? value.run_ends, depth + 1),\n values: normalizeField(value.values, depth + 1),\n });\n }\n if (type === \"extension\") {\n if (typeof value.name !== \"string\" || value.name.length === 0) {\n throw invalidArgument(\"Arrow extension name must be a non-empty string\");\n }\n return Object.freeze({\n type,\n name: value.name,\n ...(typeof value.metadata === \"string\" ? { metadata: value.metadata } : {}),\n storageType: normalizeDataType(value.storageType, depth + 1),\n });\n }\n throw invalidArgument(`Unknown Arrow data type: ${type}`);\n}\n\nfunction normalizeField(value: unknown, depth: number): ArrowField {\n if (!isRecord(value)) {\n throw invalidArgument(\"Arrow field must be an object\");\n }\n const metadata = isRecord(value.metadata)\n ? Object.freeze(Object.fromEntries(Object.entries(value.metadata).map(([key, entry]) => [key, String(entry)])))\n : undefined;\n return Object.freeze({\n name: typeof value.name === \"string\" ? value.name : \"\",\n nullable: value.nullable !== false,\n dataType: normalizeDataType(value.dataType, depth),\n ...(metadata ? { metadata } : {}),\n });\n}\n\nfunction validateWireBatch(\n range: Readonly<ReturnedRange>,\n buffers: readonly Uint8Array[],\n columns: readonly WireTableBatchColumn[],\n): void {\n validateRange(range);\n if (columns.length !== range.columnCount) {\n throw invalidArgument(\n `Batch has ${columns.length} columns; expected ${range.columnCount}`,\n );\n }\n for (const [index, column] of columns.entries()) {\n validateDisplay(column.display, range.rowCount, buffers, column.columnId);\n validateNative(column.native, buffers, 0, `columns[${index}].native`);\n if (column.native.length < range.rowCount) {\n throw invalidArgument(`Column ${column.columnId} is shorter than the returned range`);\n }\n }\n}\n\nfunction validateDisplay(\n display: DisplayColumnDescriptor,\n rows: number,\n buffers: readonly Uint8Array[],\n columnId: string,\n): void {\n const offset = display.offset ?? 0;\n assertNonNegativeSafeInteger(offset, \"display offset\");\n const offsets = regionView(display.offsets, buffers, \"display offsets\");\n if (offsets.byteLength < (offset + rows + 1) * 4) {\n throw invalidArgument(`Column ${columnId} has incomplete display offsets`);\n }\n const data = regionView(display.data, buffers, \"display data\");\n if (display.validity) {\n const validity = regionView(display.validity, buffers, \"display validity\");\n if (validity.byteLength < Math.ceil((offset + rows) / 8)) {\n throw invalidArgument(`Column ${columnId} has an incomplete display validity bitmap`);\n }\n }\n let previous = 0;\n for (let index = offset; index <= offset + rows; index += 1) {\n const next = readUnsignedOffset(offsets, index, 4);\n if (next < previous || next > data.byteLength) {\n throw invalidArgument(`Column ${columnId} has invalid display offsets`);\n }\n previous = next;\n }\n}\n\nfunction validateNative(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n depth: number,\n name: string,\n): void {\n if (depth >= MAX_NESTING_DEPTH) {\n throw invalidArgument(`Native column nesting may not exceed ${MAX_NESTING_DEPTH}`);\n }\n assertNonNegativeSafeInteger(descriptor.length, `${name}.length`);\n assertNonNegativeSafeInteger(descriptor.offset ?? 0, `${name}.offset`);\n normalizeDataType(descriptor.dataType, depth);\n const regions = [\n descriptor.validity,\n descriptor.values,\n descriptor.offsets,\n descriptor.sizes,\n descriptor.data,\n descriptor.typeIds,\n descriptor.unionOffsets,\n ...(descriptor.variadicBuffers ?? []),\n ];\n for (const region of regions) {\n if (region) {\n regionView(region, buffers, name);\n }\n }\n for (const [index, child] of (descriptor.children ?? []).entries()) {\n validateNative(child, buffers, depth + 1, `${name}.children[${index}]`);\n }\n if (descriptor.dictionary) {\n validateNative(descriptor.dictionary, buffers, depth + 1, `${name}.dictionary`);\n }\n if (descriptor.runEnds) {\n validateNative(descriptor.runEnds, buffers, depth + 1, `${name}.runEnds`);\n }\n}\n\nfunction decodeNativeValue(\n descriptor: NativeColumnDescriptor,\n logicalIndex: number,\n buffers: readonly Uint8Array[],\n depth: number,\n): NativeValue | null {\n if (depth >= MAX_NESTING_DEPTH) {\n throw invalidArgument(`Native value nesting may not exceed ${MAX_NESTING_DEPTH}`);\n }\n if (logicalIndex < 0 || logicalIndex >= descriptor.length) {\n throw invalidArgument(\"Native value index is outside its descriptor\");\n }\n const physicalIndex = (descriptor.offset ?? 0) + logicalIndex;\n if (!validAt(descriptor.validity, physicalIndex, buffers)) {\n return null;\n }\n const type = unwrapExtension(descriptor.dataType);\n switch (type.type) {\n case \"null\":\n return null;\n case \"unknown\": {\n const bytes = decodeVariableBytes(descriptor, buffers, physicalIndex, 4);\n return new TextDecoder().decode(bytes);\n }\n case \"boolean\": {\n const values = requiredRegion(descriptor.values, buffers, \"boolean values\");\n const bitIndex = (descriptor.values?.bitOffset ?? 0) + physicalIndex;\n return (values[bitIndex >>> 3]! & (1 << (bitIndex & 7))) !== 0;\n }\n case \"int8\": return readNumber(descriptor, buffers, physicalIndex, 1, \"signed\");\n case \"uint8\": return readNumber(descriptor, buffers, physicalIndex, 1, \"unsigned\");\n case \"int16\": return readNumber(descriptor, buffers, physicalIndex, 2, \"signed\");\n case \"uint16\": return readNumber(descriptor, buffers, physicalIndex, 2, \"unsigned\");\n case \"int32\": return readNumber(descriptor, buffers, physicalIndex, 4, \"signed\");\n case \"uint32\": return readNumber(descriptor, buffers, physicalIndex, 4, \"unsigned\");\n case \"int64\": return readBigInt(descriptor, buffers, physicalIndex, true);\n case \"uint64\": return readBigInt(descriptor, buffers, physicalIndex, false);\n case \"float16\": return decodeFloat16(readNumber(descriptor, buffers, physicalIndex, 2, \"unsigned\"));\n case \"float32\": return readFloat(descriptor, buffers, physicalIndex, 4);\n case \"float64\": return readFloat(descriptor, buffers, physicalIndex, 8);\n case \"utf8\":\n case \"large-utf8\": {\n const bytes = decodeVariableBytes(descriptor, buffers, physicalIndex, type.type === \"large-utf8\" ? 8 : 4);\n return new TextDecoder().decode(bytes);\n }\n case \"binary\":\n case \"large-binary\":\n return decodeVariableBytes(descriptor, buffers, physicalIndex, type.type === \"large-binary\" ? 8 : 4).slice();\n case \"utf8-view\":\n return new TextDecoder().decode(decodeViewBytes(descriptor, buffers, physicalIndex));\n case \"binary-view\":\n return decodeViewBytes(descriptor, buffers, physicalIndex).slice();\n case \"fixed-size-binary\": {\n const data = requiredRegion(descriptor.data ?? descriptor.values, buffers, \"fixed-size binary data\");\n const start = physicalIndex * type.byteWidth;\n return checkedSlice(data, start, start + type.byteWidth, \"fixed-size binary data\").slice();\n }\n case \"decimal32\":\n case \"decimal64\":\n case \"decimal128\":\n case \"decimal256\": {\n const width = { decimal32: 4, decimal64: 8, decimal128: 16, decimal256: 32 }[type.type];\n return Object.freeze({\n kind: \"decimal\",\n unscaled: readSignedLittleEndian(requiredRegion(descriptor.values, buffers, \"decimal values\"), physicalIndex * width, width),\n precision: type.precision,\n scale: type.scale,\n });\n }\n case \"date32\":\n return Object.freeze({ kind: \"date32\", value: readNumber(descriptor, buffers, physicalIndex, 4, \"signed\") });\n case \"date64\":\n return Object.freeze({ kind: \"date64\", value: readBigInt(descriptor, buffers, physicalIndex, true), unit: \"millisecond\" });\n case \"time32\":\n return Object.freeze({ kind: \"time32\", value: readNumber(descriptor, buffers, physicalIndex, 4, \"signed\"), unit: type.unit });\n case \"time64\":\n return Object.freeze({ kind: \"time64\", value: readBigInt(descriptor, buffers, physicalIndex, true), unit: type.unit });\n case \"timestamp\":\n return Object.freeze({\n kind: \"timestamp\",\n value: readBigInt(descriptor, buffers, physicalIndex, true),\n unit: type.unit,\n ...(type.timezone === undefined ? {} : { timezone: type.timezone }),\n });\n case \"duration\":\n return Object.freeze({ kind: \"duration\", value: readBigInt(descriptor, buffers, physicalIndex, true), unit: type.unit });\n case \"interval\":\n return decodeInterval(descriptor, buffers, physicalIndex, type.unit);\n case \"list\":\n case \"large-list\":\n case \"list-view\":\n case \"large-list-view\":\n case \"map\":\n return decodeListLike(descriptor, buffers, physicalIndex, type, depth);\n case \"fixed-size-list\": {\n const child = requiredChild(descriptor, 0, \"fixed-size list\");\n const start = physicalIndex * type.listSize;\n return Object.freeze(Array.from(\n { length: type.listSize },\n (_, index) => decodeNativeValue(child, start + index - (child.offset ?? 0), buffers, depth + 1),\n ));\n }\n case \"struct\": {\n const result: Record<string, NativeValue | null> = {};\n for (let index = 0; index < type.fields.length; index += 1) {\n const child = requiredChild(descriptor, index, \"struct\");\n result[type.fields[index]!.name] = decodeNativeValue(\n child,\n physicalIndex - (child.offset ?? 0),\n buffers,\n depth + 1,\n );\n }\n return Object.freeze(result);\n }\n case \"union\": {\n const typeIds = requiredRegion(descriptor.typeIds, buffers, \"union type ids\");\n if (physicalIndex >= typeIds.byteLength) {\n throw invalidArgument(\"Union type id is out of bounds\");\n }\n const typeId = new DataView(typeIds.buffer, typeIds.byteOffset, typeIds.byteLength).getInt8(physicalIndex);\n const fieldIndex = type.fields.findIndex((entry) => entry.typeId === typeId);\n if (fieldIndex < 0) {\n throw invalidArgument(`Union type id ${typeId} has no child`);\n }\n const child = requiredChild(descriptor, fieldIndex, \"union\");\n const childPhysical = type.mode === \"dense\"\n ? readSignedOffset(requiredRegion(descriptor.unionOffsets ?? descriptor.offsets, buffers, \"union offsets\"), physicalIndex, 4)\n : physicalIndex;\n return Object.freeze({\n kind: \"union\",\n typeId,\n value: decodeNativeValue(child, childPhysical - (child.offset ?? 0), buffers, depth + 1),\n });\n }\n case \"dictionary\": {\n const keys = descriptor.children?.[0] ?? descriptor;\n const dictionary = descriptor.dictionary ?? descriptor.children?.[1];\n if (!dictionary || !keys) {\n throw invalidArgument(\"Dictionary descriptor has no dictionary values\");\n }\n const index = readIndex(keys, buffers, physicalIndex, type.indexType);\n if (index < 0 || index >= dictionary.length) {\n throw invalidArgument(\"Dictionary index is out of bounds\");\n }\n return decodeNativeValue(dictionary, index, buffers, depth + 1);\n }\n case \"run-end-encoded\": {\n const runEnds = descriptor.runEnds ?? descriptor.children?.[0];\n const values = descriptor.children?.[descriptor.runEnds ? 0 : 1];\n if (!runEnds || !values) {\n throw invalidArgument(\"Run-end encoded descriptor is incomplete\");\n }\n const logicalPosition = physicalIndex + 1;\n let run = 0;\n while (run < runEnds.length && numericIndexValue(runEnds, buffers, run) < logicalPosition) {\n run += 1;\n }\n if (run >= values.length) {\n throw invalidArgument(\"Run-end encoded value is out of bounds\");\n }\n return decodeNativeValue(values, run, buffers, depth + 1);\n }\n case \"extension\":\n // unwrapExtension makes this unreachable while retaining exhaustive typing.\n throw invalidArgument(\"Nested extension data type could not be unwrapped\");\n }\n}\n\nfunction decodeListLike(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n physicalIndex: number,\n type: Extract<ArrowDataType, { type: \"list\" | \"large-list\" | \"list-view\" | \"large-list-view\" | \"map\" }>,\n depth: number,\n): NativeValue {\n const width = type.type === \"large-list\" || type.type === \"large-list-view\" ? 8 : 4;\n const offsets = requiredRegion(descriptor.offsets, buffers, \"list offsets\");\n const start = readSignedOffset(offsets, physicalIndex, width);\n const end = type.type === \"list-view\" || type.type === \"large-list-view\"\n ? start + readSignedOffset(requiredRegion(descriptor.sizes, buffers, \"list sizes\"), physicalIndex, width)\n : readSignedOffset(offsets, physicalIndex + 1, width);\n if (start < 0 || end < start) {\n throw invalidArgument(\"List offsets are invalid\");\n }\n const child = requiredChild(descriptor, 0, type.type);\n const values: NativeListValue = Object.freeze(Array.from(\n { length: end - start },\n (_, index) => decodeNativeValue(child, start + index - (child.offset ?? 0), buffers, depth + 1),\n ));\n if (type.type !== \"map\") {\n return values;\n }\n return Object.freeze(values.map((entry: NativeValue | null) => {\n if (!isRecord(entry)) {\n throw invalidArgument(\"Map entries must decode from a struct\");\n }\n const record = entry as NativeStructValue;\n const entryType = type.entries.dataType;\n const fields = entryType.type === \"struct\" ? entryType.fields : [];\n const keyName = fields[0]?.name ?? \"key\";\n const valueName = fields[1]?.name ?? \"value\";\n return Object.freeze({\n key: record[keyName] ?? null,\n value: record[valueName] ?? null,\n });\n }));\n}\n\nfunction decodeInterval(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n unit: IntervalUnit,\n): IntervalValue {\n const values = requiredRegion(descriptor.values, buffers, \"interval values\");\n const view = new DataView(values.buffer, values.byteOffset, values.byteLength);\n if (unit === \"year-month\") {\n ensureViewRange(view, index * 4, 4, \"year-month interval\");\n return Object.freeze({ kind: \"interval\", unit, months: view.getInt32(index * 4, true) });\n }\n if (unit === \"day-time\") {\n const offset = index * 8;\n ensureViewRange(view, offset, 8, \"day-time interval\");\n return Object.freeze({\n kind: \"interval\",\n unit,\n days: view.getInt32(offset, true),\n milliseconds: view.getInt32(offset + 4, true),\n });\n }\n const offset = index * 16;\n ensureViewRange(view, offset, 16, \"month-day-nano interval\");\n return Object.freeze({\n kind: \"interval\",\n unit,\n months: view.getInt32(offset, true),\n days: view.getInt32(offset + 4, true),\n nanoseconds: view.getBigInt64(offset + 8, true),\n });\n}\n\nfunction decodeVariableBytes(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n offsetWidth: 4 | 8,\n): Uint8Array {\n const offsets = requiredRegion(descriptor.offsets, buffers, \"variable offsets\");\n const data = requiredRegion(descriptor.data ?? descriptor.values, buffers, \"variable data\");\n const start = readUnsignedOffset(offsets, index, offsetWidth);\n const end = readUnsignedOffset(offsets, index + 1, offsetWidth);\n return checkedSlice(data, start, end, \"variable data\");\n}\n\nfunction decodeViewBytes(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n): Uint8Array {\n const views = requiredRegion(descriptor.values, buffers, \"view values\");\n const view = new DataView(views.buffer, views.byteOffset, views.byteLength);\n const offset = index * 16;\n ensureViewRange(view, offset, 16, \"view value\");\n const length = view.getInt32(offset, true);\n if (length < 0) {\n throw invalidArgument(\"View length must be non-negative\");\n }\n if (length <= 12) {\n return checkedSlice(views, offset + 4, offset + 4 + length, \"inline view\");\n }\n const bufferIndex = view.getInt32(offset + 8, true);\n const dataOffset = view.getInt32(offset + 12, true);\n const data = descriptor.variadicBuffers?.[bufferIndex];\n if (!data || dataOffset < 0) {\n throw invalidArgument(\"View references an invalid variadic buffer\");\n }\n return checkedSlice(regionView(data, buffers, \"view data\"), dataOffset, dataOffset + length, \"view data\");\n}\n\nfunction readNumber(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n width: 1 | 2 | 4,\n signedness: \"signed\" | \"unsigned\",\n): number {\n const values = requiredRegion(descriptor.values, buffers, \"numeric values\");\n const view = new DataView(values.buffer, values.byteOffset, values.byteLength);\n const offset = index * width;\n ensureViewRange(view, offset, width, \"numeric value\");\n if (width === 1) return signedness === \"signed\" ? view.getInt8(offset) : view.getUint8(offset);\n if (width === 2) return signedness === \"signed\" ? view.getInt16(offset, true) : view.getUint16(offset, true);\n return signedness === \"signed\" ? view.getInt32(offset, true) : view.getUint32(offset, true);\n}\n\nfunction readFloat(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n width: 4 | 8,\n): number {\n const values = requiredRegion(descriptor.values, buffers, \"floating-point values\");\n const view = new DataView(values.buffer, values.byteOffset, values.byteLength);\n const offset = index * width;\n ensureViewRange(view, offset, width, \"floating-point value\");\n return width === 4 ? view.getFloat32(offset, true) : view.getFloat64(offset, true);\n}\n\nfunction readBigInt(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n signed: boolean,\n): bigint {\n const values = requiredRegion(descriptor.values, buffers, \"64-bit values\");\n const view = new DataView(values.buffer, values.byteOffset, values.byteLength);\n const offset = index * 8;\n ensureViewRange(view, offset, 8, \"64-bit value\");\n return signed ? view.getBigInt64(offset, true) : view.getBigUint64(offset, true);\n}\n\nfunction readIndex(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n dataType: ArrowDataType,\n): number {\n const type = unwrapExtension(dataType).type;\n let value: number | bigint;\n if (type === \"int8\") value = readNumber(descriptor, buffers, index, 1, \"signed\");\n else if (type === \"uint8\") value = readNumber(descriptor, buffers, index, 1, \"unsigned\");\n else if (type === \"int16\") value = readNumber(descriptor, buffers, index, 2, \"signed\");\n else if (type === \"uint16\") value = readNumber(descriptor, buffers, index, 2, \"unsigned\");\n else if (type === \"int32\") value = readNumber(descriptor, buffers, index, 4, \"signed\");\n else if (type === \"uint32\") value = readNumber(descriptor, buffers, index, 4, \"unsigned\");\n else if (type === \"int64\") value = readBigInt(descriptor, buffers, index, true);\n else if (type === \"uint64\") value = readBigInt(descriptor, buffers, index, false);\n else throw invalidArgument(\"Dictionary index type must be an integer\");\n const numeric = typeof value === \"bigint\" ? Number(value) : value;\n if (!Number.isSafeInteger(numeric)) {\n throw invalidArgument(\"Dictionary index exceeds the JavaScript safe integer range\");\n }\n return numeric;\n}\n\nfunction numericIndexValue(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n): number {\n const type = unwrapExtension(descriptor.dataType);\n return readIndex({ ...descriptor, dataType: { type: \"dictionary\", indexType: type, valueType: { type: \"null\" } } }, buffers, index, type);\n}\n\nfunction readSignedLittleEndian(bytes: Uint8Array, offset: number, width: number): bigint {\n const slice = checkedSlice(bytes, offset, offset + width, \"signed integer\");\n let value = 0n;\n for (let index = slice.byteLength - 1; index >= 0; index -= 1) {\n value = (value << 8n) | BigInt(slice[index]!);\n }\n const sign = 1n << BigInt(width * 8 - 1);\n return (value & sign) === 0n ? value : value - (1n << BigInt(width * 8));\n}\n\nfunction readUnsignedOffset(bytes: Uint8Array, index: number, width: 4 | 8): number {\n const value = readOffset(bytes, index, width, false);\n if (value < 0) {\n throw invalidArgument(\"Offset must be non-negative\");\n }\n return value;\n}\n\nfunction readSignedOffset(bytes: Uint8Array, index: number, width: 4 | 8): number {\n return readOffset(bytes, index, width, true);\n}\n\nfunction readOffset(bytes: Uint8Array, index: number, width: 4 | 8, signed: boolean): number {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const offset = index * width;\n ensureViewRange(view, offset, width, \"offset\");\n const value = width === 4\n ? signed ? view.getInt32(offset, true) : view.getUint32(offset, true)\n : signed ? view.getBigInt64(offset, true) : view.getBigUint64(offset, true);\n const numeric = typeof value === \"bigint\" ? Number(value) : value;\n if (!Number.isSafeInteger(numeric)) {\n throw invalidArgument(\"Offset exceeds the JavaScript safe integer range\");\n }\n return numeric;\n}\n\nfunction validAt(\n validity: BatchBufferRegion | undefined,\n index: number,\n buffers: readonly Uint8Array[],\n): boolean {\n if (!validity) return true;\n const bitmap = regionView(validity, buffers, \"validity bitmap\");\n const bitIndex = (validity.bitOffset ?? 0) + index;\n if (bitIndex < 0 || (bitIndex >>> 3) >= bitmap.byteLength) {\n throw invalidArgument(\"Validity bitmap index is out of bounds\");\n }\n return (bitmap[bitIndex >>> 3]! & (1 << (bitIndex & 7))) !== 0;\n}\n\nfunction requiredRegion(\n region: BatchBufferRegion | undefined,\n buffers: readonly Uint8Array[],\n name: string,\n): Uint8Array {\n if (!region) throw invalidArgument(`${name} are missing`);\n return regionView(region, buffers, name);\n}\n\nfunction regionView(\n region: BatchBufferRegion,\n buffers: readonly Uint8Array[],\n name: string,\n): Uint8Array {\n if (!isRecord(region) || !Number.isSafeInteger(region.buffer) || region.buffer < 0) {\n throw invalidArgument(`${name} references an invalid buffer`);\n }\n const buffer = buffers[region.buffer];\n if (!buffer) throw invalidArgument(`${name} references a missing buffer`);\n const byteOffset = region.byteOffset ?? 0;\n const byteLength = region.byteLength ?? buffer.byteLength - byteOffset;\n if (\n !Number.isSafeInteger(byteOffset)\n || byteOffset < 0\n || !Number.isSafeInteger(byteLength)\n || byteLength < 0\n || byteOffset + byteLength > buffer.byteLength\n ) {\n throw invalidArgument(`${name} region is outside its buffer`);\n }\n return buffer.subarray(byteOffset, byteOffset + byteLength);\n}\n\nfunction requiredChild(descriptor: NativeColumnDescriptor, index: number, name: string): NativeColumnDescriptor {\n const child = descriptor.children?.[index];\n if (!child) throw invalidArgument(`${name} descriptor has no child ${index}`);\n return child;\n}\n\nfunction checkedSlice(bytes: Uint8Array, start: number, end: number, name: string): Uint8Array {\n if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end < start || end > bytes.byteLength) {\n throw invalidArgument(`${name} slice is out of bounds`);\n }\n return bytes.subarray(start, end);\n}\n\nfunction ensureViewRange(view: DataView, offset: number, width: number, name: string): void {\n if (offset < 0 || offset + width > view.byteLength) {\n throw invalidArgument(`${name} is out of bounds`);\n }\n}\n\nfunction unwrapExtension(dataType: ArrowDataType): ArrowDataType {\n let current = dataType;\n for (let depth = 0; current.type === \"extension\"; depth += 1) {\n if (depth >= MAX_NESTING_DEPTH) throw invalidArgument(\"Extension nesting is too deep\");\n current = current.storageType;\n }\n return current;\n}\n\nfunction freezeWireColumn(column: WireTableBatchColumn): WireTableBatchColumn {\n return Object.freeze({\n columnId: column.columnId,\n native: freezeNative(column.native),\n display: Object.freeze({\n ...column.display,\n data: freezeRegion(column.display.data),\n offsets: freezeRegion(column.display.offsets),\n ...(column.display.validity ? { validity: freezeRegion(column.display.validity) } : {}),\n }),\n });\n}\n\nfunction freezeNative(descriptor: NativeColumnDescriptor): NativeColumnDescriptor {\n const freezeOptionalRegion = (region: BatchBufferRegion | undefined) => region ? freezeRegion(region) : undefined;\n return Object.freeze({\n ...descriptor,\n dataType: freezeDataType(descriptor.dataType),\n ...(freezeOptionalRegion(descriptor.validity) ? { validity: freezeOptionalRegion(descriptor.validity)! } : {}),\n ...(freezeOptionalRegion(descriptor.values) ? { values: freezeOptionalRegion(descriptor.values)! } : {}),\n ...(freezeOptionalRegion(descriptor.offsets) ? { offsets: freezeOptionalRegion(descriptor.offsets)! } : {}),\n ...(freezeOptionalRegion(descriptor.sizes) ? { sizes: freezeOptionalRegion(descriptor.sizes)! } : {}),\n ...(freezeOptionalRegion(descriptor.data) ? { data: freezeOptionalRegion(descriptor.data)! } : {}),\n ...(freezeOptionalRegion(descriptor.typeIds) ? { typeIds: freezeOptionalRegion(descriptor.typeIds)! } : {}),\n ...(freezeOptionalRegion(descriptor.unionOffsets) ? { unionOffsets: freezeOptionalRegion(descriptor.unionOffsets)! } : {}),\n ...(descriptor.variadicBuffers\n ? { variadicBuffers: Object.freeze(descriptor.variadicBuffers.map(freezeRegion)) }\n : {}),\n ...(descriptor.children\n ? { children: Object.freeze(descriptor.children.map(freezeNative)) }\n : {}),\n ...(descriptor.dictionary ? { dictionary: freezeNative(descriptor.dictionary) } : {}),\n ...(descriptor.runEnds ? { runEnds: freezeNative(descriptor.runEnds) } : {}),\n });\n}\n\nfunction freezeRegion(region: BatchBufferRegion): BatchBufferRegion {\n return Object.freeze({ ...region });\n}\n\nfunction freezeDataType(dataType: ArrowDataType): ArrowDataType {\n return normalizeDataTypeUnchecked(dataType, 0);\n}\n\nfunction normalizeDataTypeUnchecked(value: ArrowDataType, depth: number): ArrowDataType {\n // Public construction already validates; metadata/batch normalization may\n // arrive from protocol values, so use the same validator for one canonical shape.\n return normalizeDataType(value, depth);\n}\n\nfunction timeUnit(value: unknown): TimeUnit {\n if (value === \"second\" || value === \"millisecond\" || value === \"microsecond\" || value === \"nanosecond\") {\n return value;\n }\n throw invalidArgument(\"Arrow time unit is invalid\");\n}\n\nfunction intervalUnit(value: unknown): IntervalUnit {\n if (value === \"year-month\" || value === \"day-time\" || value === \"month-day-nano\") return value;\n throw invalidArgument(\"Arrow interval unit is invalid\");\n}\n\nfunction decodeFloat16(bits: number): number {\n const sign = (bits & 0x8000) === 0 ? 1 : -1;\n const exponent = (bits >>> 10) & 0x1f;\n const fraction = bits & 0x03ff;\n if (exponent === 0) return sign * 2 ** -14 * (fraction / 1024);\n if (exponent === 0x1f) return fraction === 0 ? sign * Infinity : Number.NaN;\n return sign * 2 ** (exponent - 15) * (1 + fraction / 1024);\n}\n\nfunction normalizeCellLimit(value: number | undefined): number {\n const maxCells = value ?? DEFAULT_TO_ROWS_CELL_LIMIT;\n assertPositiveSafeInteger(maxCells, \"maxCells\");\n return maxCells;\n}\n\nfunction assertCellLimit(rows: number, columns: number, maxCells: number): void {\n const cellCount = rows * columns;\n if (!Number.isSafeInteger(cellCount) || cellCount > maxCells) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `Decoding ${cellCount} cells exceeds the toRows limit of ${maxCells}`,\n {\n details: {\n resource: \"row-materialization-cells\",\n required: cellCount,\n available: maxCells,\n cellCount,\n maxCells,\n },\n },\n );\n }\n}\n\nfunction integer(value: unknown, name: string): number {\n if (!Number.isSafeInteger(value)) throw invalidArgument(`${name} must be a safe integer`);\n return value as number;\n}\n\nfunction positiveInteger(value: unknown, name: string): number {\n const result = integer(value, name);\n if (result <= 0) throw invalidArgument(`${name} must be positive`);\n return result;\n}\n\nfunction asUint8Array(value: WireBatchBuffer): Uint8Array {\n if (value instanceof ArrayBuffer) return new Uint8Array(value);\n return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function assertNonNegativeSafeInteger(value: unknown, name: string): asserts value is number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n throw invalidArgument(`${name} must be a non-negative safe integer`, { name, value });\n }\n}\n\nexport function assertPositiveSafeInteger(value: unknown, name: string): asserts value is number {\n if (!Number.isSafeInteger(value) || (value as number) <= 0) {\n throw invalidArgument(`${name} must be a positive safe integer`, { name, value });\n }\n}\n", "import type { RangeRequest, WireTableBatch } from \"./model.js\";\n\ninterface CacheEntry<T> {\n readonly value: T;\n readonly byteLength: number;\n}\n\ninterface PermitWaiter {\n readonly key: string;\n readonly resolve: (release: () => void) => void;\n readonly reject: (reason: unknown) => void;\n}\n\nexport class PermitQueueFullError extends Error {\n constructor(readonly maxWaiters: number) {\n super(`The permit queue already has ${maxWaiters} waiters`);\n this.name = \"PermitQueueFullError\";\n }\n}\n\n/** A small FIFO permit queue whose pending acquisitions can be cancelled by key. */\nexport class AsyncPermitQueue {\n readonly #maxActive: number;\n readonly #maxWaiters: number;\n readonly #waiters: PermitWaiter[] = [];\n #active = 0;\n\n constructor(maxActive: number, maxWaiters: number) {\n if (!Number.isSafeInteger(maxActive) || maxActive <= 0) {\n throw new RangeError(\"maxActive must be a positive safe integer\");\n }\n if (!Number.isSafeInteger(maxWaiters) || maxWaiters < 0) {\n throw new RangeError(\"maxWaiters must be a non-negative safe integer\");\n }\n this.#maxActive = maxActive;\n this.#maxWaiters = maxWaiters;\n }\n\n acquire(key: string): Promise<() => void> {\n if (this.#active < this.#maxActive) {\n this.#active += 1;\n return Promise.resolve(this.#releaseOnce());\n }\n if (this.#waiters.length >= this.#maxWaiters) {\n return Promise.reject(new PermitQueueFullError(this.#maxWaiters));\n }\n return new Promise<() => void>((resolve, reject) => {\n this.#waiters.push({ key, resolve, reject });\n });\n }\n\n cancel(key: string, reason: unknown): boolean {\n const index = this.#waiters.findIndex((waiter) => waiter.key === key);\n if (index < 0) {\n return false;\n }\n const [waiter] = this.#waiters.splice(index, 1);\n waiter!.reject(reason);\n this.#wakeWaiters();\n return true;\n }\n\n #releaseOnce(): () => void {\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n this.#active -= 1;\n this.#wakeWaiters();\n };\n }\n\n #wakeWaiters(): void {\n while (this.#active < this.#maxActive && this.#waiters.length > 0) {\n const waiter = this.#waiters.shift()!;\n this.#active += 1;\n waiter.resolve(this.#releaseOnce());\n }\n }\n}\n\n/** A byte-bounded least-recently-used cache. */\nexport class ByteLruCache<T> {\n readonly #maxBytes: number;\n readonly #entries = new Map<string, CacheEntry<T>>();\n readonly #onRemove: ((key: string, value: T, byteLength: number) => void) | undefined;\n #byteLength = 0;\n\n constructor(\n maxBytes: number,\n options: Readonly<{\n onRemove?: (key: string, value: T, byteLength: number) => void;\n }> = {},\n ) {\n if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {\n throw new RangeError(\"maxBytes must be a non-negative safe integer\");\n }\n this.#maxBytes = maxBytes;\n this.#onRemove = options.onRemove;\n }\n\n get maxBytes(): number {\n return this.#maxBytes;\n }\n\n get(key: string): T | undefined {\n const entry = this.#entries.get(key);\n if (!entry) {\n return undefined;\n }\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n return entry.value;\n }\n\n set(key: string, value: T, byteLength: number): void {\n if (!Number.isSafeInteger(byteLength) || byteLength < 0) {\n throw new RangeError(\"byteLength must be a non-negative safe integer\");\n }\n if (byteLength > this.#maxBytes) {\n return;\n }\n\n const existing = this.#entries.get(key);\n if (existing) {\n this.#remove(key, existing);\n }\n\n while (this.#byteLength + byteLength > this.#maxBytes) {\n const oldestKey = this.#entries.keys().next().value as string | undefined;\n if (oldestKey === undefined) {\n break;\n }\n const oldest = this.#entries.get(oldestKey)!;\n this.#remove(oldestKey, oldest);\n }\n\n this.#entries.set(key, { value, byteLength });\n this.#byteLength += byteLength;\n }\n\n deleteWhere(predicate: (key: string, value: T) => boolean): void {\n for (const [key, entry] of this.#entries) {\n if (!predicate(key, entry.value)) {\n continue;\n }\n this.#remove(key, entry);\n }\n }\n\n clear(): void {\n for (const [key, entry] of this.#entries) {\n this.#onRemove?.(key, entry.value, entry.byteLength);\n }\n this.#entries.clear();\n this.#byteLength = 0;\n }\n\n #remove(key: string, entry: CacheEntry<T>): void {\n this.#entries.delete(key);\n this.#byteLength -= entry.byteLength;\n this.#onRemove?.(key, entry.value, entry.byteLength);\n }\n}\n\nexport function rangeCacheKey(\n owner: string,\n revision: number,\n schemaVersion: number,\n range: RangeRequest,\n): string {\n return JSON.stringify([\n owner,\n revision,\n schemaVersion,\n range.rowStart,\n range.rowCount,\n range.columnStart,\n range.columnCount,\n ]);\n}\n\nexport function rangeCacheKeyBelongsTo(key: string, owner: string): boolean {\n return key.startsWith(`[${JSON.stringify(owner)},`);\n}\n\nexport function cloneWireTableBatch(batch: WireTableBatch): WireTableBatch {\n return {\n layoutVersion: batch.layoutVersion,\n tableId: batch.tableId,\n revision: batch.revision,\n schemaVersion: batch.schemaVersion,\n range: { ...batch.range },\n // Clone each pool entry exactly once. Descriptor buffer indexes remain\n // valid and native/display aliases stay deduplicated.\n buffers: batch.buffers.map((buffer) => Uint8Array.from(asUint8Array(buffer)).buffer),\n columns: batch.columns,\n complete: batch.complete,\n };\n}\n\nexport function wireBatchByteLength(batch: WireTableBatch): number {\n return batch.buffers.reduce((total, buffer) => total + buffer.byteLength, 0);\n}\n\nfunction asUint8Array(value: ArrayBuffer | ArrayBufferView): Uint8Array {\n return value instanceof ArrayBuffer\n ? new Uint8Array(value)\n : new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n}\n", "import { TabularkError, cancelledError, closedError } from \"./errors.js\";\nimport {\n PROTOCOL_VERSION,\n isRecord,\n type Operation,\n type ProtocolEvent,\n type ProtocolResponse,\n type ResponseKind,\n} from \"./protocol.js\";\n\ntype EventListener = (event: ProtocolEvent) => void;\ntype FailureListener = (error: TabularkError) => void;\n\ninterface PendingRequest {\n readonly resolve: (value: unknown) => void;\n readonly reject: (reason: unknown) => void;\n readonly expectedKind: ResponseKind;\n readonly cleanup: () => void;\n}\n\ninterface RequestOptions {\n readonly transfer?: Transferable[];\n readonly signal?: AbortSignal;\n readonly timeoutMs?: number;\n}\n\nconst DEFAULT_SHUTDOWN_TIMEOUT_MS = 2_000;\nconst RESPONSE_KINDS = new Set<ResponseKind>([\n \"hello\",\n \"dataset\",\n \"tables\",\n \"table\",\n \"metadata\",\n \"presentation\",\n \"presentationRange\",\n \"batch\",\n \"acknowledged\",\n]);\nconst EVENT_NAMES = new Set([\n \"progress\",\n \"metadata\",\n \"warning\",\n \"closed\",\n \"runtimeError\",\n]);\n\n/** Main-thread request multiplexer for one dedicated Worker. */\nexport class WorkerRpcClient {\n readonly #worker: Worker;\n readonly #pending = new Map<string, PendingRequest>();\n readonly #onEvent: EventListener;\n readonly #onFailure: FailureListener;\n #nextRequestId = 1;\n #closed = false;\n\n constructor(worker: Worker, onEvent: EventListener, onFailure: FailureListener = () => {}) {\n this.#worker = worker;\n this.#onEvent = onEvent;\n this.#onFailure = onFailure;\n worker.addEventListener(\"message\", this.#handleMessage);\n worker.addEventListener(\"error\", this.#handleWorkerFailure);\n worker.addEventListener(\"messageerror\", this.#handleWorkerFailure);\n }\n\n async request<T>(\n op: Operation,\n payload: unknown,\n expectedKind: ResponseKind,\n options: RequestOptions = {},\n ): Promise<T> {\n if (this.#closed) {\n throw closedError(\"Engine\");\n }\n if (options.signal?.aborted) {\n throw cancelledError();\n }\n\n const requestId = `r${this.#nextRequestId++}`;\n return new Promise<T>((resolve, reject) => {\n const cleanups: Array<() => void> = [];\n const cleanup = () => {\n for (const dispose of cleanups.splice(0)) {\n dispose();\n }\n };\n if (options.signal) {\n const abort = () => {\n const pending = this.#pending.get(requestId);\n if (!pending) {\n return;\n }\n this.#pending.delete(requestId);\n pending.cleanup();\n this.#postCancel(requestId);\n reject(cancelledError());\n };\n options.signal.addEventListener(\"abort\", abort, { once: true });\n cleanups.push(() => options.signal?.removeEventListener(\"abort\", abort));\n }\n if (options.timeoutMs !== undefined) {\n const timeoutMs = Math.max(1, options.timeoutMs);\n const timeoutId = globalThis.setTimeout(() => {\n if (!this.#pending.has(requestId)) {\n return;\n }\n this.#failRuntime(\n new TabularkError(\n \"RUNTIME_FAILURE\",\n `The Tabulark Worker did not respond to ${op} within ${timeoutMs}ms`,\n ),\n );\n }, timeoutMs);\n cleanups.push(() => globalThis.clearTimeout(timeoutId));\n }\n\n this.#pending.set(requestId, {\n resolve: (value) => resolve(value as T),\n reject,\n expectedKind,\n cleanup,\n });\n try {\n this.#worker.postMessage(\n { protocolVersion: PROTOCOL_VERSION, requestId, op, payload },\n options.transfer ?? [],\n );\n } catch (error) {\n this.#pending.delete(requestId);\n cleanup();\n reject(\n new TabularkError(\"RUNTIME_FAILURE\", \"Could not send a request to the Worker\", {\n cause: error,\n }),\n );\n }\n });\n }\n\n async shutdown(timeoutMs = DEFAULT_SHUTDOWN_TIMEOUT_MS): Promise<void> {\n if (this.#closed) {\n return;\n }\n try {\n await this.request(\"shutdown\", {}, \"acknowledged\", { timeoutMs });\n } catch {\n // Termination below is still required after a failed graceful shutdown.\n } finally {\n this.terminate();\n }\n }\n\n terminate(\n error = new TabularkError(\"RUNTIME_FAILURE\", \"The Tabulark Worker was terminated\"),\n notifyFailure = false,\n ): void {\n if (this.#stop(error) && notifyFailure) {\n this.#notifyFailure(error);\n }\n }\n\n #handleMessage = (event: MessageEvent<unknown>): void => {\n const value = event.data;\n if (isValidProtocolEvent(value)) {\n try {\n this.#onEvent(value);\n } catch (error) {\n this.#failRuntime(\n new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n \"The Worker emitted an invalid runtime event\",\n { cause: error },\n ),\n );\n }\n return;\n }\n if (looksLikeProtocolEvent(value) || (looksLikeProtocolResponse(value) && !isValidProtocolResponse(value))) {\n this.#failRuntime(\n new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n \"The Worker returned a malformed or incompatible protocol message\",\n ),\n );\n return;\n }\n if (!isValidProtocolResponse(value)) {\n return;\n }\n const pending = this.#pending.get(value.requestId);\n if (!pending) {\n return;\n }\n this.#pending.delete(value.requestId);\n pending.cleanup();\n\n if (value.status === \"failure\") {\n pending.reject(TabularkError.fromSerialized(value.error));\n return;\n }\n if (value.result.kind !== pending.expectedKind) {\n const error = new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n `Expected a ${pending.expectedKind} response, received ${value.result.kind}`,\n );\n pending.reject(error);\n this.#failRuntime(error);\n return;\n }\n pending.resolve(value.result.data);\n };\n\n #handleWorkerFailure = (event: Event): void => {\n if (this.#closed) {\n return;\n }\n let message = \"The Tabulark Worker stopped unexpectedly\";\n if (typeof ErrorEvent !== \"undefined\" && event instanceof ErrorEvent && event.message) {\n message = event.message;\n } else if (event.type === \"messageerror\") {\n message = \"The Tabulark Worker could not deserialize a message\";\n }\n this.#failRuntime(new TabularkError(\"RUNTIME_FAILURE\", message));\n };\n\n #postCancel(targetRequestId: string): void {\n if (this.#closed) {\n return;\n }\n try {\n this.#worker.postMessage({\n protocolVersion: PROTOCOL_VERSION,\n requestId: `r${this.#nextRequestId++}`,\n op: \"cancel\",\n payload: { targetRequestId },\n });\n } catch {\n // The caller has already received its cancellation result.\n }\n }\n\n #failPending(error: TabularkError): void {\n for (const pending of this.#pending.values()) {\n pending.cleanup();\n pending.reject(error);\n }\n this.#pending.clear();\n }\n\n #failRuntime(error: TabularkError): void {\n if (this.#stop(error)) {\n this.#notifyFailure(error);\n }\n }\n\n #stop(error: TabularkError): boolean {\n if (this.#closed) {\n return false;\n }\n this.#closed = true;\n this.#worker.removeEventListener(\"message\", this.#handleMessage);\n this.#worker.removeEventListener(\"error\", this.#handleWorkerFailure);\n this.#worker.removeEventListener(\"messageerror\", this.#handleWorkerFailure);\n try {\n this.#worker.terminate();\n } catch {\n // A failed Worker is already unusable; pending callers still need a terminal result.\n }\n this.#failPending(error);\n return true;\n }\n\n #notifyFailure(error: TabularkError): void {\n try {\n this.#onFailure(error);\n } catch {\n // The Worker is already terminal; a client callback cannot recover it.\n }\n }\n}\n\nfunction isValidProtocolResponse(value: unknown): value is ProtocolResponse {\n if (\n !isRecord(value)\n || value.protocolVersion !== PROTOCOL_VERSION\n || typeof value.requestId !== \"string\"\n || value.requestId.length === 0\n ) {\n return false;\n }\n if (value.status === \"success\") {\n return isRecord(value.result)\n && typeof value.result.kind === \"string\"\n && RESPONSE_KINDS.has(value.result.kind as ResponseKind);\n }\n if (value.status === \"failure\") {\n return isSerializedError(value.error);\n }\n return false;\n}\n\nfunction isValidProtocolEvent(value: unknown): value is ProtocolEvent {\n if (\n !isRecord(value)\n || value.protocolVersion !== PROTOCOL_VERSION\n || typeof value.event !== \"string\"\n || !EVENT_NAMES.has(value.event)\n || !(\"payload\" in value)\n ) {\n return false;\n }\n if (\n !optionalNonEmptyString(value.requestId)\n || !optionalNonEmptyString(value.datasetHandle)\n || !optionalNonEmptyString(value.tableHandle)\n || !optionalNonEmptyString(value.tableId)\n || !optionalNonNegativeInteger(value.revision)\n ) {\n return false;\n }\n if (value.tableHandle !== undefined && value.datasetHandle === undefined) {\n return false;\n }\n if (value.event === \"runtimeError\") {\n return value.datasetHandle !== undefined\n || (value.tableHandle === undefined && value.tableId === undefined);\n }\n return value.datasetHandle !== undefined;\n}\n\nfunction isSerializedError(value: unknown): boolean {\n return isRecord(value)\n && typeof value.code === \"string\"\n && typeof value.message === \"string\"\n && typeof value.retryable === \"boolean\";\n}\n\nfunction optionalNonEmptyString(value: unknown): boolean {\n return value === undefined || (typeof value === \"string\" && value.length > 0);\n}\n\nfunction optionalNonNegativeInteger(value: unknown): boolean {\n return value === undefined || (Number.isSafeInteger(value) && (value as number) >= 0);\n}\n\nfunction looksLikeProtocolResponse(value: unknown): boolean {\n return isRecord(value)\n && (\"requestId\" in value || \"status\" in value || \"result\" in value || \"error\" in value);\n}\n\nfunction looksLikeProtocolEvent(value: unknown): boolean {\n return isRecord(value) && \"event\" in value;\n}\n", "import { TabularkError, cancelledError, closedError, invalidArgument } from \"./errors.js\";\nimport {\n resolveOfficialAdapter,\n type AdapterDescriptor,\n type AdapterRegistration,\n type ArrowIpcAdapterOptions,\n type DelimitedAdapterOptions,\n type ExcelAdapterOptions,\n type OfficialAdapterId,\n type ParquetAdapterOptions,\n} from \"./adapters.js\";\nimport {\n DEFAULT_MEMORY_BUDGET_BYTES,\n ColumnarTableBatch,\n deriveMemoryBudgetLimits,\n normalizeDataType,\n normalizeMetadata,\n validateRange,\n type RangeRequest,\n type MergedCellRegion,\n type PresentationAxisEntry,\n type PresentationRange,\n type PresentationStyle,\n type SpreadsheetPresentation,\n type TablePresentation,\n type TableBatch,\n type TableDescriptor,\n type TableMetadata,\n type WireTableBatch,\n type MemoryBudgetLimits,\n} from \"./model.js\";\nimport {\n ADAPTER_API_VERSION,\n BATCH_LAYOUT_VERSION,\n PROTOCOL_VERSION,\n isRecord,\n type ProtocolEvent,\n} from \"./protocol.js\";\nimport { officialAdapterManifestEntry } from \"./official-adapter-manifest.js\";\nimport {\n ByteLruCache,\n cloneWireTableBatch,\n rangeCacheKey,\n rangeCacheKeyBelongsTo,\n wireBatchByteLength,\n} from \"./range-cache.js\";\nimport { WorkerRpcClient } from \"./rpc-client.js\";\n\nconst MIN_MEMORY_BUDGET_BYTES = 8 * 1024 * 1024;\nconst LIFECYCLE_CLOSE_TIMEOUT_MS = 2_000;\nconst MAX_ORPHAN_HANDLES = 32;\nconst MAX_ORPHAN_EVENTS_PER_HANDLE = 16;\nconst MAX_ORPHAN_EVENTS = 256;\n\nexport interface OpenSourceOptions<Options = unknown> {\n /** One of the official descriptors registered when the engine was created. */\n readonly adapter: AdapterDescriptor<OfficialAdapterId, Options>;\n readonly adapterOptions?: Options;\n /** Detaches an ArrayBuffer input. Defaults to false; Blob input cannot be transferred. */\n readonly transferInput?: boolean;\n /** Cancels opening and releases any Worker-side source created by the request. */\n readonly signal?: AbortSignal;\n}\n\nexport interface EngineOptions {\n /** The engine's immutable allow-list. At least one official adapter is required. */\n readonly adapters: readonly AdapterDescriptor[];\n readonly memoryBudgetBytes?: number;\n readonly workerName?: string;\n}\n\nexport interface ReadRangeOptions {\n readonly signal?: AbortSignal;\n}\n\nexport interface RuntimeProgress {\n readonly sourceHandle: string;\n readonly tableId?: string;\n readonly revision?: number;\n readonly bytesScanned: number;\n readonly rowsDiscovered: number;\n readonly done: boolean;\n}\n\nexport interface SourceWarning {\n readonly handle: string;\n readonly kind: string;\n readonly message: string;\n readonly byteOffset?: number;\n readonly row?: number;\n}\n\nexport type DatasetEvent =\n | Readonly<{ type: \"progress\"; progress: RuntimeProgress }>\n | Readonly<{ type: \"metadata\"; metadata: Readonly<TableMetadata> }>\n | Readonly<{ type: \"warning\"; warning: SourceWarning }>\n | Readonly<{ type: \"closed\" }>\n | Readonly<{ type: \"runtimeError\"; error: TabularkError }>;\n\nexport type TableEvent = Exclude<DatasetEvent, Readonly<{ type: \"progress\" }>>;\n\nexport type Unsubscribe = () => void;\n\nexport interface DatasetSession {\n readonly tables: readonly Readonly<TableDescriptor>[];\n openTable(tableId: string): Promise<TableHandle>;\n subscribe(listener: (event: DatasetEvent) => void): Unsubscribe;\n close(): Promise<void>;\n}\n\nexport interface TableHandle {\n readonly metadata: Readonly<TableMetadata>;\n getPresentation(): Promise<TablePresentation | null>;\n readPresentationRange(\n request: RangeRequest,\n options?: ReadRangeOptions,\n ): Promise<PresentationRange | null>;\n readRange(request: RangeRequest, options?: ReadRangeOptions): Promise<TableBatch>;\n subscribe(listener: (event: TableEvent) => void): Unsubscribe;\n close(): Promise<void>;\n}\n\nexport interface TabularkEngine {\n open<Options>(source: Blob | ArrayBuffer, options: OpenSourceOptions<Options>): Promise<DatasetSession>;\n close(): Promise<void>;\n dispose(): Promise<void>;\n}\n\ninterface NormalizedEngineOptions {\n readonly memoryBudgetBytes: number;\n readonly limits: MemoryBudgetLimits;\n readonly adapters: readonly AdapterRegistration[];\n readonly workerUrl: string;\n readonly workerName: string;\n}\n\ninterface NormalizedOpenOptions {\n readonly adapter: AdapterRegistration;\n readonly options: Readonly<Record<string, unknown>>;\n}\n\nclass Engine implements TabularkEngine {\n readonly #rpc: WorkerRpcClient;\n readonly #rangeCache: ByteLruCache<WireTableBatch>;\n readonly #maxArrayBufferBytes: number;\n readonly #adapters: ReadonlyMap<OfficialAdapterId, AdapterRegistration>;\n readonly #sessions = new Map<string, DatasetSessionImpl>();\n readonly #orphanEvents = new Map<string, ProtocolEvent[]>();\n #orphanEventCount = 0;\n #closed = false;\n\n constructor(\n rpc: WorkerRpcClient,\n limits: MemoryBudgetLimits,\n adapters: readonly AdapterRegistration[],\n ) {\n this.#rpc = rpc;\n this.#rangeCache = new ByteLruCache(limits.mainThreadRangeCacheBytes);\n this.#maxArrayBufferBytes = limits.maxArrayBufferBytes;\n this.#adapters = new Map(adapters.map((adapter) => [adapter.id, adapter]));\n }\n\n static async create(options: EngineOptions): Promise<Engine> {\n const normalized = normalizeEngineOptions(options);\n if (\n typeof Worker === \"undefined\" ||\n typeof Blob === \"undefined\" ||\n typeof URL === \"undefined\"\n ) {\n throw new TabularkError(\n \"UNSUPPORTED_RUNTIME\",\n \"Tabulark createEngine() requires a browser with module Worker and Blob support\",\n );\n }\n\n let engine: Engine | undefined;\n const worker = new Worker(normalized.workerUrl, {\n type: \"module\",\n name: normalized.workerName,\n });\n const rpc = new WorkerRpcClient(worker, (event) => {\n if (engine !== undefined) {\n engine.#handleEvent(event);\n }\n }, (error) => {\n if (engine !== undefined) {\n engine.#handleRuntimeFailure(error);\n }\n });\n engine = new Engine(rpc, normalized.limits, normalized.adapters);\n try {\n const hello = await rpc.request<unknown>(\n \"hello\",\n {\n clientName: \"tabulark-js\",\n adapters: normalized.adapters.map(({ id }) => Object.freeze({ id })),\n memoryBudgetBytes: normalized.memoryBudgetBytes,\n },\n \"hello\",\n );\n const helloAdapters = isRecord(hello) && Array.isArray(hello.adapters)\n ? hello.adapters\n : undefined;\n if (\n !isRecord(hello)\n || hello.protocolVersion !== PROTOCOL_VERSION\n || hello.adapterApiVersion !== ADAPTER_API_VERSION\n || hello.batchLayoutVersion !== BATCH_LAYOUT_VERSION\n || !helloAdapters\n || helloAdapters.length !== normalized.adapters.length\n || normalized.adapters.some((adapter) => !helloAdapters.includes(adapter.id))\n ) {\n throw new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n \"The Worker did not accept the current Tabulark protocol version\",\n );\n }\n return engine;\n } catch (error) {\n rpc.terminate();\n throw error;\n }\n }\n\n async open<Options>(\n source: Blob | ArrayBuffer,\n options: OpenSourceOptions<Options>,\n ): Promise<DatasetSession> {\n this.#assertOpen();\n const normalizedOptions = normalizeOpenOptions(options, this.#adapters, inferSourceName(source));\n const transfer: Transferable[] = [];\n if (source instanceof ArrayBuffer) {\n if (source.byteLength > this.#maxArrayBufferBytes) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `ArrayBuffer sources larger than ${this.#maxArrayBufferBytes} bytes must be supplied as a Blob`,\n {\n details: {\n resource: \"source-staging\",\n requiredBytes: source.byteLength,\n availableBytes: this.#maxArrayBufferBytes,\n },\n },\n );\n }\n if (options.transferInput === true) {\n transfer.push(source);\n }\n } else if (!(source instanceof Blob)) {\n throw invalidArgument(\"source must be a Blob, File, or ArrayBuffer\");\n } else if (options.transferInput === true) {\n throw invalidArgument(\"transferInput may only be true for an ArrayBuffer source\");\n }\n\n const dataset = await this.#rpc.request<{ datasetHandle: string }>(\n \"openSource\",\n {\n source,\n adapterId: normalizedOptions.adapter.id,\n options: normalizedOptions.options,\n },\n \"dataset\",\n options.signal ? { transfer, signal: options.signal } : { transfer },\n );\n if (\n !isRecord(dataset)\n || typeof dataset.datasetHandle !== \"string\"\n || dataset.datasetHandle.length === 0\n ) {\n throw this.#terminateForProtocolFailure(\"Worker returned an invalid dataset handle\");\n }\n\n try {\n const tableResult = await this.#rpc.request<unknown>(\n \"listTables\",\n { datasetHandle: dataset.datasetHandle },\n \"tables\",\n options.signal ? { signal: options.signal } : {},\n );\n if (options.signal?.aborted) {\n throw cancelledError();\n }\n const tableDescriptors = normalizeDescriptors(tableResult);\n const session = new DatasetSessionImpl(this, dataset.datasetHandle, tableDescriptors);\n this.#sessions.set(dataset.datasetHandle, session);\n this.#deliverOrphanEvents(session);\n if (session.closed) {\n throw session.terminalError ?? closedError(\"Dataset session\");\n }\n return session;\n } catch (error) {\n const terminalError = this.#orphanRuntimeError(dataset.datasetHandle);\n const session = this.#sessions.get(dataset.datasetHandle);\n if (session) {\n session.closeLocally();\n this.#sessions.delete(dataset.datasetHandle);\n }\n await this.#discardOpenedDataset(dataset.datasetHandle);\n throw terminalError ?? error;\n }\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n for (const session of this.#sessions.values()) {\n session.closeLocally();\n }\n this.#sessions.clear();\n this.#rangeCache.clear();\n this.#clearOrphanEvents();\n await this.#rpc.shutdown();\n }\n\n dispose(): Promise<void> {\n return this.close();\n }\n\n async openTable(session: DatasetSessionImpl, tableId: string): Promise<TableHandle> {\n this.#assertOpen();\n session.assertOpen();\n if (!session.tables.some((table) => table.id === tableId)) {\n throw invalidArgument(`Unknown table: ${tableId}`);\n }\n let tableHandle: string | undefined;\n try {\n const table = await this.#rpc.request<{ tableHandle: string }>(\n \"openTable\",\n { datasetHandle: session.handle, tableId },\n \"table\",\n );\n if (\n !isRecord(table)\n || typeof table.tableHandle !== \"string\"\n || table.tableHandle.length === 0\n ) {\n throw this.#terminateForProtocolFailure(\"Worker returned an invalid table handle\");\n }\n tableHandle = table.tableHandle;\n const metadata = await this.#rpc.request<unknown>(\n \"getMetadata\",\n { tableHandle },\n \"metadata\",\n );\n const normalizedMetadata = normalizeMetadataWire(metadata);\n this.#assertOpen();\n session.assertOpen();\n const handle = new TableHandleImpl(\n this,\n session,\n tableHandle,\n normalizedMetadata,\n );\n session.addTableHandle(handle);\n return handle;\n } catch (error) {\n if (tableHandle !== undefined) {\n await this.#discardOpenedTable(tableHandle);\n }\n throw error;\n }\n }\n\n async readRange(\n table: TableHandleImpl,\n request: RangeRequest,\n options: ReadRangeOptions,\n ): Promise<TableBatch> {\n this.#assertOpen();\n table.assertOpen();\n const normalized = validateRange(request);\n if (options.signal?.aborted) {\n throw cancelledError();\n }\n const metadata = table.metadata;\n const key = rangeCacheKey(\n table.handle,\n metadata.revision,\n metadata.schema.version,\n normalized,\n );\n const cached = this.#rangeCache.get(key);\n if (cached) {\n return new ColumnarTableBatch(cloneWireTableBatch(cached));\n }\n const batch = await this.#rpc.request<WireTableBatch>(\n \"readRange\",\n { tableHandle: table.handle, range: normalized },\n \"batch\",\n options.signal ? { signal: options.signal } : {},\n );\n this.#assertOpen();\n table.assertOpen();\n // Incomplete batches end at a progressive indexed-prefix boundary. They\n // are valid results for this instant, but caching them would hide rows\n // discovered by subsequent Arrow Stream or delimited scan progress.\n if (batch.complete) {\n const cachedBatch = cloneWireTableBatch(batch);\n this.#rangeCache.set(\n rangeCacheKey(table.handle, batch.revision, batch.schemaVersion, normalized),\n cachedBatch,\n wireBatchByteLength(cachedBatch),\n );\n }\n return new ColumnarTableBatch(batch);\n }\n\n async getPresentation(table: TableHandleImpl): Promise<TablePresentation | null> {\n this.#assertOpen();\n table.assertOpen();\n const value = await this.#rpc.request<unknown>(\n \"getPresentation\",\n { tableHandle: table.handle },\n \"presentation\",\n );\n this.#assertOpen();\n table.assertOpen();\n return normalizePresentationWire(value, table.metadata);\n }\n\n async readPresentationRange(\n table: TableHandleImpl,\n request: RangeRequest,\n options: ReadRangeOptions,\n ): Promise<PresentationRange | null> {\n this.#assertOpen();\n table.assertOpen();\n const normalized = validateRange(request);\n if (options.signal?.aborted) {\n throw cancelledError();\n }\n const value = await this.#rpc.request<unknown>(\n \"readPresentationRange\",\n { tableHandle: table.handle, range: normalized },\n \"presentationRange\",\n options.signal ? { signal: options.signal } : {},\n );\n this.#assertOpen();\n table.assertOpen();\n return normalizePresentationRangeWire(value, table.metadata, normalized);\n }\n\n async closeTable(table: TableHandleImpl): Promise<void> {\n if (table.closed) {\n return;\n }\n table.closeLocally();\n if (this.#closed) {\n return;\n }\n await this.#requestRemoteClose(\"closeTable\", { tableHandle: table.handle });\n }\n\n clearTableCache(tableHandle: string): void {\n this.#rangeCache.deleteWhere((key) => rangeCacheKeyBelongsTo(key, tableHandle));\n }\n\n async closeSession(session: DatasetSessionImpl): Promise<void> {\n if (session.closed) {\n return;\n }\n session.closeLocally();\n if (this.#closed) {\n this.#sessions.delete(session.handle);\n return;\n }\n try {\n await this.#requestRemoteClose(\"closeSource\", { datasetHandle: session.handle });\n } finally {\n this.#sessions.delete(session.handle);\n this.#deleteOrphanEvents(session.handle);\n }\n }\n\n #assertOpen(): void {\n if (this.#closed) {\n throw closedError(\"Engine\");\n }\n }\n\n #handleEvent(event: ProtocolEvent): void {\n const handle = event.datasetHandle;\n if (!handle && event.event === \"runtimeError\") {\n this.#handleRuntimeFailure(errorFromWire(event.payload));\n return;\n }\n if (!handle) {\n return;\n }\n const session = this.#sessions.get(handle);\n if (!session) {\n this.#rememberOrphanEvent(handle, event);\n return;\n }\n session.handleEvent(event);\n if (event.event === \"closed\" && !event.tableHandle && session.closed) {\n this.#sessions.delete(handle);\n this.#deleteOrphanEvents(handle);\n }\n }\n\n #deliverOrphanEvents(session: DatasetSessionImpl): void {\n const events = this.#orphanEvents.get(session.handle);\n if (!events) {\n return;\n }\n this.#deleteOrphanEvents(session.handle);\n for (const event of events) {\n session.handleEvent(event);\n }\n }\n\n #orphanRuntimeError(handle: string): TabularkError | undefined {\n const event = this.#orphanEvents.get(handle)?.find((candidate) => (\n candidate.event === \"runtimeError\"\n ));\n return event ? errorFromWire(event.payload) : undefined;\n }\n\n async #discardOpenedTable(tableHandle: string): Promise<void> {\n if (this.#closed) {\n return;\n }\n try {\n await this.#rpc.request(\n \"closeTable\",\n { tableHandle },\n \"acknowledged\",\n { timeoutMs: LIFECYCLE_CLOSE_TIMEOUT_MS },\n );\n } catch (error) {\n if (!this.#closed) {\n this.#rpc.terminate(asTabularkError(error, \"Could not release an opened table\"), true);\n }\n }\n }\n\n async #discardOpenedDataset(datasetHandle: string): Promise<void> {\n this.#deleteOrphanEvents(datasetHandle);\n if (this.#closed) {\n return;\n }\n try {\n await this.#rpc.request(\n \"closeSource\",\n { datasetHandle },\n \"acknowledged\",\n { timeoutMs: LIFECYCLE_CLOSE_TIMEOUT_MS },\n );\n } catch (error) {\n if (!this.#closed) {\n this.#rpc.terminate(asTabularkError(error, \"Could not release an opened dataset\"), true);\n }\n } finally {\n // closeSource may emit a final closed event before its acknowledgement.\n // No DatasetSession will consume that event after a failed open.\n this.#deleteOrphanEvents(datasetHandle);\n }\n }\n\n async #requestRemoteClose(\n op: \"closeTable\" | \"closeSource\",\n payload: unknown,\n ): Promise<void> {\n try {\n await this.#rpc.request(op, payload, \"acknowledged\", {\n timeoutMs: LIFECYCLE_CLOSE_TIMEOUT_MS,\n });\n } catch (error) {\n if (!this.#closed) {\n this.#rpc.terminate(asTabularkError(error, `Could not complete ${op}`), true);\n }\n throw error;\n }\n }\n\n #terminateForProtocolFailure(message: string): TabularkError {\n const error = new TabularkError(\"PROTOCOL_INCOMPATIBLE\", message);\n this.#rpc.terminate(error, true);\n return error;\n }\n\n #rememberOrphanEvent(handle: string, event: ProtocolEvent): void {\n // No caller can subscribe until open() returns, so progress, metadata, and\n // warning events observed before a DatasetSession exists have no consumer.\n // Retaining only terminal state prevents an unknown-handle event stream\n // from becoming an unbounded main-thread cache while preserving the race\n // that must not return a dead session from open().\n if (event.event !== \"runtimeError\" && event.event !== \"closed\") {\n return;\n }\n let events = this.#orphanEvents.get(handle);\n if (!events) {\n while (this.#orphanEvents.size >= MAX_ORPHAN_HANDLES) {\n this.#evictOldestOrphanHandle();\n }\n events = [];\n this.#orphanEvents.set(handle, events);\n }\n if (events.length >= MAX_ORPHAN_EVENTS_PER_HANDLE) {\n events.shift();\n this.#orphanEventCount -= 1;\n }\n while (this.#orphanEventCount >= MAX_ORPHAN_EVENTS) {\n this.#evictOldestOrphanEvent();\n }\n events.push(event);\n this.#orphanEventCount += 1;\n }\n\n #evictOldestOrphanEvent(): void {\n const oldest = this.#orphanEvents.entries().next().value as\n | [string, ProtocolEvent[]]\n | undefined;\n if (!oldest) {\n this.#orphanEventCount = 0;\n return;\n }\n const [handle, events] = oldest;\n events.shift();\n this.#orphanEventCount -= 1;\n if (events.length === 0) {\n this.#orphanEvents.delete(handle);\n }\n }\n\n #evictOldestOrphanHandle(): void {\n const handle = this.#orphanEvents.keys().next().value as string | undefined;\n if (handle !== undefined) {\n this.#deleteOrphanEvents(handle);\n }\n }\n\n #deleteOrphanEvents(handle: string): void {\n const events = this.#orphanEvents.get(handle);\n if (!events) {\n return;\n }\n this.#orphanEventCount -= events.length;\n this.#orphanEvents.delete(handle);\n }\n\n #clearOrphanEvents(): void {\n this.#orphanEvents.clear();\n this.#orphanEventCount = 0;\n }\n\n #handleRuntimeFailure(error: TabularkError): void {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n this.#rangeCache.clear();\n this.#clearOrphanEvents();\n for (const session of this.#sessions.values()) {\n session.failLocally(error);\n }\n this.#sessions.clear();\n }\n}\n\nclass DatasetSessionImpl implements DatasetSession {\n readonly #engine: Engine;\n readonly handle: string;\n readonly tables: readonly Readonly<TableDescriptor>[];\n readonly #listeners = new Set<(event: DatasetEvent) => void>();\n readonly #tableHandles = new Set<TableHandleImpl>();\n closed = false;\n terminalError: TabularkError | undefined;\n\n constructor(engine: Engine, handle: string, tables: readonly TableDescriptor[]) {\n this.#engine = engine;\n this.handle = handle;\n this.tables = Object.freeze(tables.map((table) => Object.freeze({ ...table })));\n }\n\n openTable(tableId: string): Promise<TableHandle> {\n return this.#engine.openTable(this, tableId);\n }\n\n subscribe(listener: (event: DatasetEvent) => void): Unsubscribe {\n this.assertOpen();\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n close(): Promise<void> {\n return this.#engine.closeSession(this);\n }\n\n assertOpen(): void {\n if (this.closed) {\n throw closedError(\"Dataset session\");\n }\n }\n\n addTableHandle(handle: TableHandleImpl): void {\n this.#tableHandles.add(handle);\n }\n\n removeTableHandle(handle: TableHandleImpl): void {\n this.#tableHandles.delete(handle);\n }\n\n closeLocally(): void {\n if (this.closed) {\n return;\n }\n this.closed = true;\n for (const table of this.#tableHandles) {\n table.closeLocally();\n }\n this.#tableHandles.clear();\n this.#emit({ type: \"closed\" });\n }\n\n failLocally(error: TabularkError): void {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.terminalError = error;\n this.#emit({ type: \"runtimeError\", error });\n for (const table of [...this.#tableHandles]) {\n table.failLocally(error);\n }\n this.#tableHandles.clear();\n this.#emit({ type: \"closed\" });\n }\n\n handleEvent(event: ProtocolEvent): void {\n if (this.closed && event.event !== \"closed\") {\n return;\n }\n switch (event.event) {\n case \"progress\":\n this.#emit({\n type: \"progress\",\n progress: normalizeProgress(event.payload, event.tableId, event.revision),\n });\n break;\n case \"metadata\": {\n const metadata = normalizeMetadataWire(event.payload);\n this.#emit({ type: \"metadata\", metadata });\n if (!event.tableHandle) {\n for (const table of this.#tableHandles) {\n if (table.metadata.tableId === metadata.tableId) {\n table.updateMetadata(metadata);\n }\n }\n }\n break;\n }\n case \"warning\": {\n const warning = normalizeWarning(event.payload);\n this.#emit({ type: \"warning\", warning });\n for (const table of this.#tableHandles) {\n if (table.matchesWarning(warning)) {\n table.emitWarning(warning);\n }\n }\n break;\n }\n case \"runtimeError\": {\n const error = errorFromWire(event.payload);\n if (event.tableHandle) {\n this.#emit({ type: \"runtimeError\", error });\n } else {\n this.failLocally(error);\n }\n break;\n }\n case \"closed\":\n if (!event.tableHandle) {\n this.closeLocally();\n }\n break;\n }\n if (event.tableHandle) {\n for (const table of this.#tableHandles) {\n if (table.handle === event.tableHandle) {\n table.handleEvent(event);\n }\n }\n }\n }\n\n #emit(event: DatasetEvent): void {\n for (const listener of this.#listeners) {\n safelyCall(listener, event);\n }\n }\n}\n\nclass TableHandleImpl implements TableHandle {\n readonly #engine: Engine;\n readonly #session: DatasetSessionImpl;\n readonly handle: string;\n #metadata: Readonly<TableMetadata>;\n readonly #listeners = new Set<(event: TableEvent) => void>();\n closed = false;\n\n constructor(\n engine: Engine,\n session: DatasetSessionImpl,\n handle: string,\n metadata: Readonly<TableMetadata>,\n ) {\n this.#engine = engine;\n this.#session = session;\n this.handle = handle;\n this.#metadata = metadata;\n }\n\n get metadata(): Readonly<TableMetadata> {\n return this.#metadata;\n }\n\n readRange(request: RangeRequest, options: ReadRangeOptions = {}): Promise<TableBatch> {\n return this.#engine.readRange(this, request, options);\n }\n\n getPresentation(): Promise<TablePresentation | null> {\n return this.#engine.getPresentation(this);\n }\n\n readPresentationRange(\n request: RangeRequest,\n options: ReadRangeOptions = {},\n ): Promise<PresentationRange | null> {\n return this.#engine.readPresentationRange(this, request, options);\n }\n\n subscribe(listener: (event: TableEvent) => void): Unsubscribe {\n this.assertOpen();\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n close(): Promise<void> {\n return this.#engine.closeTable(this);\n }\n\n assertOpen(): void {\n if (this.closed) {\n throw closedError(\"Table handle\");\n }\n }\n\n closeLocally(): void {\n if (this.closed) {\n return;\n }\n this.#engine.clearTableCache(this.handle);\n this.closed = true;\n this.#session.removeTableHandle(this);\n this.#emit({ type: \"closed\" });\n }\n\n failLocally(error: TabularkError): void {\n if (this.closed) {\n return;\n }\n this.#engine.clearTableCache(this.handle);\n this.closed = true;\n this.#session.removeTableHandle(this);\n this.#emit({ type: \"runtimeError\", error });\n this.#emit({ type: \"closed\" });\n }\n\n updateMetadata(metadata: Readonly<TableMetadata>): void {\n if (this.closed) {\n return;\n }\n this.#metadata = metadata;\n this.#emit({ type: \"metadata\", metadata });\n }\n\n matchesWarning(warning: SourceWarning): boolean {\n return warning.handle === this.handle || warning.handle === this.#session.handle;\n }\n\n emitWarning(warning: SourceWarning): void {\n if (!this.closed) {\n this.#emit({ type: \"warning\", warning });\n }\n }\n\n handleEvent(event: ProtocolEvent): void {\n if (this.closed && event.event !== \"closed\") {\n return;\n }\n switch (event.event) {\n case \"metadata\":\n this.updateMetadata(normalizeMetadataWire(event.payload));\n break;\n case \"warning\":\n this.emitWarning(normalizeWarning(event.payload));\n break;\n case \"runtimeError\":\n this.failLocally(errorFromWire(event.payload));\n break;\n case \"closed\":\n this.closeLocally();\n break;\n case \"progress\":\n break;\n }\n }\n\n #emit(event: TableEvent): void {\n for (const listener of this.#listeners) {\n safelyCall(listener, event);\n }\n }\n}\n\nfunction normalizeEngineOptions(options: EngineOptions): NormalizedEngineOptions {\n if (!options || typeof options !== \"object\") {\n throw invalidArgument(\"createEngine options are required\");\n }\n if (\"wasmModuleUrl\" in options || \"workerUrl\" in options) {\n throw invalidArgument(\"wasmModuleUrl and workerUrl were removed; register an official adapter instead\");\n }\n if (!Array.isArray(options.adapters) || options.adapters.length === 0) {\n throw invalidArgument(\"adapters must contain at least one official adapter descriptor\");\n }\n const adapters: AdapterRegistration[] = [];\n const ids = new Set<OfficialAdapterId>();\n for (const [index, descriptor] of options.adapters.entries()) {\n const registration = resolveOfficialAdapter(descriptor);\n if (!registration) {\n throw invalidArgument(`adapters[${index}] is not an official frozen adapter descriptor`);\n }\n if (ids.has(registration.id)) {\n throw invalidArgument(`Adapter ${registration.id} is registered more than once`);\n }\n ids.add(registration.id);\n adapters.push(Object.freeze({ ...registration }));\n }\n const memoryBudgetBytes = options.memoryBudgetBytes ?? DEFAULT_MEMORY_BUDGET_BYTES;\n if (!Number.isSafeInteger(memoryBudgetBytes) || memoryBudgetBytes <= 0) {\n throw invalidArgument(\"memoryBudgetBytes must be a positive safe integer\");\n }\n if (memoryBudgetBytes < MIN_MEMORY_BUDGET_BYTES) {\n throw invalidArgument(\n `memoryBudgetBytes must be at least ${MIN_MEMORY_BUDGET_BYTES} bytes`,\n { minimum: MIN_MEMORY_BUDGET_BYTES, memoryBudgetBytes },\n );\n }\n return {\n memoryBudgetBytes,\n limits: deriveMemoryBudgetLimits(memoryBudgetBytes),\n adapters: Object.freeze(adapters),\n workerUrl: new URL(\"./worker.js\", import.meta.url).href,\n workerName: options.workerName ?? \"tabulark\",\n };\n}\n\nfunction normalizeOpenOptions<Options>(\n options: OpenSourceOptions<Options>,\n adapters: ReadonlyMap<OfficialAdapterId, AdapterRegistration>,\n inferredSourceName?: string,\n): NormalizedOpenOptions {\n if (!options || typeof options !== \"object\") {\n throw invalidArgument(\"open options are required\");\n }\n if (options.transferInput !== undefined && typeof options.transferInput !== \"boolean\") {\n throw invalidArgument(\"transferInput must be a boolean\");\n }\n const selected = resolveOfficialAdapter(options.adapter);\n if (!selected) {\n throw invalidArgument(\"adapter must be an official frozen adapter descriptor\");\n }\n const registered = adapters.get(selected.id);\n if (!registered) {\n throw invalidArgument(`Adapter ${selected.id} was not registered with this engine`);\n }\n const rawOptions = options.adapterOptions;\n if (rawOptions !== undefined && (!isRecord(rawOptions) || Array.isArray(rawOptions))) {\n throw invalidArgument(\"adapterOptions must be an object\");\n }\n let normalized: Readonly<Record<string, unknown>>;\n switch (selected.id) {\n case \"tabulark:delimited\":\n normalized = normalizeDelimitedOptions(\n rawOptions as DelimitedAdapterOptions | undefined,\n inferredSourceName,\n );\n break;\n case \"tabulark:arrow-ipc\":\n normalized = normalizeArrowOptions(\n rawOptions as ArrowIpcAdapterOptions | undefined,\n inferredSourceName,\n );\n break;\n case \"tabulark:parquet\":\n normalized = normalizeParquetOptions(\n rawOptions as ParquetAdapterOptions | undefined,\n inferredSourceName,\n );\n break;\n case \"tabulark:excel\":\n normalized = normalizeExcelOptions(\n rawOptions as ExcelAdapterOptions | undefined,\n inferredSourceName,\n );\n break;\n }\n return {\n adapter: registered,\n options: normalized,\n };\n}\n\nfunction normalizeDelimitedOptions(\n options: DelimitedAdapterOptions | undefined,\n inferredSourceName?: string,\n): Readonly<Record<string, unknown>> {\n const raw = options ?? {};\n assertManifestKeys(\"tabulark:delimited\", raw);\n const dialect = raw.dialect ?? \"csv\";\n const header = raw.header ?? \"first-row\";\n const mode = raw.mode ?? \"lenient\";\n if (dialect !== \"csv\" && dialect !== \"tsv\") {\n throw invalidArgument(\"dialect must be csv or tsv\");\n }\n if (header !== \"first-row\" && header !== \"none\") {\n throw invalidArgument(\"header must be first-row or none\");\n }\n if (mode !== \"lenient\" && mode !== \"strict\") {\n throw invalidArgument(\"mode must be lenient or strict\");\n }\n const delimiter = raw.delimiter ?? (dialect === \"csv\" ? \",\" : \"\\t\");\n if (!isValidDelimiter(delimiter)) {\n throw invalidArgument(\"delimiter must be one non-NUL ASCII byte other than CR, LF, or quote\");\n }\n const sourceName = normalizeSourceName(raw.sourceName ?? inferredSourceName);\n return Object.freeze({\n dialect,\n header,\n mode,\n delimiter,\n ...(sourceName === undefined ? {} : { sourceName }),\n });\n}\n\nfunction normalizeArrowOptions(\n options: ArrowIpcAdapterOptions | undefined,\n inferredSourceName?: string,\n): Readonly<Record<string, unknown>> {\n const raw = options ?? {};\n assertManifestKeys(\"tabulark:arrow-ipc\", raw);\n const container = raw.container ?? \"auto\";\n if (container !== \"auto\" && container !== \"file\" && container !== \"stream\") {\n throw invalidArgument(\"container must be auto, file, or stream\");\n }\n const sourceName = normalizeSourceName(raw.sourceName ?? inferredSourceName);\n return Object.freeze({\n container,\n ...(sourceName === undefined ? {} : { sourceName }),\n });\n}\n\nfunction normalizeParquetOptions(\n options: ParquetAdapterOptions | undefined,\n inferredSourceName?: string,\n): Readonly<Record<string, unknown>> {\n const raw = options ?? {};\n assertManifestKeys(\"tabulark:parquet\", raw);\n const sourceName = normalizeSourceName(raw.sourceName ?? inferredSourceName);\n return Object.freeze(sourceName === undefined ? {} : { sourceName });\n}\n\nfunction normalizeExcelOptions(\n options: ExcelAdapterOptions | undefined,\n inferredSourceName?: string,\n): Readonly<Record<string, unknown>> {\n const raw = options ?? {};\n assertManifestKeys(\"tabulark:excel\", raw);\n const format = raw.format ?? \"auto\";\n if (format !== \"auto\" && format !== \"xls\" && format !== \"xlsx\") {\n throw invalidArgument(\"format must be auto, xls, or xlsx\");\n }\n const sourceName = normalizeSourceName(raw.sourceName ?? inferredSourceName);\n return Object.freeze({\n format,\n ...(sourceName === undefined ? {} : { sourceName }),\n });\n}\n\nfunction normalizeSourceName(value: unknown): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== \"string\" || value.length === 0 || value.length > 1_024) {\n throw invalidArgument(\"sourceName must contain between 1 and 1024 characters\");\n }\n return value;\n}\n\nfunction assertManifestKeys(id: OfficialAdapterId, value: object): void {\n const allowedSet = new Set(officialAdapterManifestEntry(id).options.allowedKeys);\n for (const key of Object.keys(value)) {\n if (!allowedSet.has(key)) {\n throw invalidArgument(`Unknown adapter option: ${key}`);\n }\n }\n}\n\nfunction normalizeDescriptors(value: unknown): readonly TableDescriptor[] {\n if (!Array.isArray(value)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Worker returned invalid table descriptors\");\n }\n return value.map((entry, index) => {\n if (!isRecord(entry) || typeof entry.id !== \"string\" || typeof entry.name !== \"string\") {\n throw new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n `Worker returned an invalid table descriptor at index ${index}`,\n );\n }\n return { id: entry.id, name: entry.name };\n });\n}\n\nfunction normalizeMetadataWire(value: unknown): Readonly<TableMetadata> {\n if (!isRecord(value) || typeof value.tableId !== \"string\" || typeof value.name !== \"string\") {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Worker returned invalid table metadata\");\n }\n const rawExtent = isRecord(value.extent) ? value.extent : {};\n const rawSchema = isRecord(value.schema) ? value.schema : {};\n const rawCapabilities = isRecord(value.capabilities) ? value.capabilities : {};\n const columns = Array.isArray(rawSchema.columns)\n ? rawSchema.columns.map((column, index) => normalizeColumn(column, index))\n : [];\n return normalizeMetadata({\n tableId: value.tableId,\n name: value.name,\n revision: numeric(value.revision, 0),\n extent: {\n rows: normalizeAxis(rawExtent.rows, \"at-least\", 0),\n columns: normalizeAxis(rawExtent.columns, \"exact\", columns.length),\n },\n schema: { version: numeric(rawSchema.version, 0), columns },\n capabilities: {\n ...rawCapabilities,\n randomAccess: rawCapabilities.randomAccess === \"full\" ? \"full\" : \"indexed-prefix\",\n typedValues: rawCapabilities.typedValues === true,\n search: rawCapabilities.search === true,\n sort: rawCapabilities.sort === true,\n filter: rawCapabilities.filter === true,\n multiTable: rawCapabilities.multiTable === true,\n },\n });\n}\n\nfunction normalizePresentationWire(\n value: unknown,\n metadata: Readonly<TableMetadata>,\n): TablePresentation | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (!isRecord(value) || value.kind !== \"spreadsheet-v1\") {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Worker returned an invalid table presentation\");\n }\n if (value.tableId !== metadata.tableId) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Presentation tableId does not match its table\");\n }\n const visibility = value.visibility === \"hidden\" || value.visibility === \"very-hidden\"\n ? value.visibility\n : \"visible\";\n return Object.freeze({\n kind: \"spreadsheet-v1\" as const,\n tableId: metadata.tableId,\n revision: numeric(value.revision, metadata.revision),\n visibility,\n frozenRows: numeric(value.frozenRows, 0),\n frozenColumns: numeric(value.frozenColumns, 0),\n rows: normalizePresentationAxis(value.rows, \"rows\"),\n columns: normalizePresentationAxis(value.columns, \"columns\"),\n styles: normalizePresentationStyles(value.styles),\n } satisfies SpreadsheetPresentation);\n}\n\nfunction normalizePresentationRangeWire(\n value: unknown,\n metadata: Readonly<TableMetadata>,\n requested: RangeRequest,\n): PresentationRange | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (!isRecord(value) || value.kind !== \"spreadsheet-v1\" || value.tableId !== metadata.tableId) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Worker returned an invalid presentation range\");\n }\n const range = isRecord(value.range) ? value.range : {};\n for (const key of [\"rowStart\", \"rowCount\", \"columnStart\", \"columnCount\"] as const) {\n if (range[key] !== requested[key]) {\n throw new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n \"Presentation range must be aligned with its requested range\",\n );\n }\n }\n if (!Array.isArray(value.styleIds) || value.styleIds.length !== requested.rowCount) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Presentation style rows do not match the range\");\n }\n const styleIds = Object.freeze(value.styleIds.map((row, rowIndex) => {\n if (!Array.isArray(row) || row.length !== requested.columnCount) {\n throw new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n `Presentation style row ${rowIndex} does not match the range`,\n );\n }\n return Object.freeze(row.map((styleId) => (\n styleId === null || (Number.isSafeInteger(styleId) && (styleId as number) >= 0)\n ? styleId as number | null\n : invalidPresentationStyleId()\n )));\n }));\n const mergedCells = Array.isArray(value.mergedCells)\n ? Object.freeze(value.mergedCells.map((region, index) => normalizeMergedCell(region, index)))\n : Object.freeze([]);\n return Object.freeze({\n kind: \"spreadsheet-v1\" as const,\n tableId: metadata.tableId,\n revision: numeric(value.revision, metadata.revision),\n range: Object.freeze({ ...requested }),\n styleIds,\n mergedCells,\n rows: normalizePresentationAxis(value.rows, \"rows\"),\n columns: normalizePresentationAxis(value.columns, \"columns\"),\n });\n}\n\nfunction invalidPresentationStyleId(): never {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Presentation style IDs must be non-negative integers or null\");\n}\n\nfunction normalizePresentationAxis(value: unknown, name: string): readonly PresentationAxisEntry[] {\n if (value === undefined) return Object.freeze([]);\n if (!Array.isArray(value)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name} must be an array`);\n }\n const seen = new Set<number>();\n return Object.freeze(value.map((entry, index) => {\n if (!isRecord(entry) || !Number.isSafeInteger(entry.index) || (entry.index as number) < 0) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name}[${index}] has an invalid index`);\n }\n const axisIndex = entry.index as number;\n if (seen.has(axisIndex)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name} contains duplicate index ${axisIndex}`);\n }\n seen.add(axisIndex);\n if (entry.size !== undefined && (typeof entry.size !== \"number\" || !Number.isFinite(entry.size) || entry.size < 0)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name}[${index}] has an invalid size`);\n }\n if (entry.hidden !== undefined && typeof entry.hidden !== \"boolean\") {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name}[${index}] has an invalid hidden flag`);\n }\n return Object.freeze({\n index: axisIndex,\n ...(entry.size === undefined ? {} : { size: entry.size as number }),\n ...(entry.hidden === undefined ? {} : { hidden: entry.hidden as boolean }),\n });\n }));\n}\n\nfunction normalizePresentationStyles(value: unknown): readonly PresentationStyle[] {\n if (value === undefined) return Object.freeze([]);\n if (!Array.isArray(value)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Presentation styles must be an array\");\n }\n return Object.freeze(value.map((style, index) => {\n if (!isRecord(style)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation style ${index} must be an object`);\n }\n // Copy only the stable static style vocabulary. Unknown producer fields are\n // intentionally ignored so future adapters can enrich their private wire DTO.\n return Object.freeze({\n ...(typeof style.numberFormat === \"string\" ? { numberFormat: style.numberFormat } : {}),\n ...(normalizePresentationFont(style.font) ? { font: normalizePresentationFont(style.font)! } : {}),\n ...(normalizePresentationColor(style.foregroundColor) ? { foregroundColor: normalizePresentationColor(style.foregroundColor)! } : {}),\n ...(normalizePresentationColor(style.backgroundColor) ? { backgroundColor: normalizePresentationColor(style.backgroundColor)! } : {}),\n ...(normalizePresentationColor(style.fillColor) ? { fillColor: normalizePresentationColor(style.fillColor)! } : {}),\n ...(normalizePresentationBorders(style.borders) ? { borders: normalizePresentationBorders(style.borders)! } : {}),\n ...(isHorizontalAlignment(style.horizontalAlignment)\n ? { horizontalAlignment: style.horizontalAlignment }\n : {}),\n ...(isVerticalAlignment(style.verticalAlignment)\n ? { verticalAlignment: style.verticalAlignment }\n : {}),\n ...(typeof style.wrapText === \"boolean\" ? { wrapText: style.wrapText } : {}),\n });\n }));\n}\n\nfunction normalizePresentationColor(value: unknown): Readonly<{ css?: string }> | undefined {\n if (!isRecord(value) || typeof value.css !== \"string\" || value.css.length === 0 || value.css.length > 128) {\n return undefined;\n }\n return Object.freeze({ css: value.css });\n}\n\nfunction normalizePresentationFont(value: unknown): PresentationStyle[\"font\"] | undefined {\n if (!isRecord(value)) return undefined;\n const color = normalizePresentationColor(value.color);\n const size = typeof value.size === \"number\" && Number.isFinite(value.size) && value.size > 0\n ? value.size\n : undefined;\n const font = {\n ...(typeof value.family === \"string\" && value.family.length > 0 ? { family: value.family } : {}),\n ...(size === undefined ? {} : { size }),\n ...(typeof value.bold === \"boolean\" ? { bold: value.bold } : {}),\n ...(typeof value.italic === \"boolean\" ? { italic: value.italic } : {}),\n ...(typeof value.underline === \"boolean\" ? { underline: value.underline } : {}),\n ...(color === undefined ? {} : { color }),\n };\n return Object.keys(font).length === 0 ? undefined : Object.freeze(font);\n}\n\nfunction normalizePresentationBorders(value: unknown): PresentationStyle[\"borders\"] | undefined {\n if (!isRecord(value)) return undefined;\n const sides = [\"top\", \"right\", \"bottom\", \"left\"] as const;\n const result: Record<string, unknown> = {};\n for (const side of sides) {\n const raw = value[side];\n if (!isRecord(raw)) continue;\n const style = isBorderStyle(raw.style) ? raw.style : undefined;\n const color = normalizePresentationColor(raw.color);\n if (style !== undefined || color !== undefined) {\n result[side] = Object.freeze({\n ...(style === undefined ? {} : { style }),\n ...(color === undefined ? {} : { color }),\n });\n }\n }\n return Object.keys(result).length === 0 ? undefined : Object.freeze(result);\n}\n\nfunction normalizeMergedCell(value: unknown, index: number): MergedCellRegion {\n if (!isRecord(value)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Merged cell ${index} must be an object`);\n }\n const fields = [\"rowStart\", \"rowEnd\", \"columnStart\", \"columnEnd\"] as const;\n for (const field of fields) {\n if (!Number.isSafeInteger(value[field]) || (value[field] as number) < 0) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Merged cell ${index} has an invalid ${field}`);\n }\n }\n const region = {\n rowStart: value.rowStart as number,\n rowEnd: value.rowEnd as number,\n columnStart: value.columnStart as number,\n columnEnd: value.columnEnd as number,\n };\n if (region.rowEnd <= region.rowStart || region.columnEnd <= region.columnStart) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Merged cell ${index} must be non-empty`);\n }\n return Object.freeze(region);\n}\n\nfunction isBorderStyle(value: unknown): value is \"none\" | \"thin\" | \"medium\" | \"thick\" | \"dashed\" | \"dotted\" | \"double\" {\n return value === \"none\" || value === \"thin\" || value === \"medium\" || value === \"thick\"\n || value === \"dashed\" || value === \"dotted\" || value === \"double\";\n}\n\nfunction isHorizontalAlignment(value: unknown): value is \"general\" | \"left\" | \"center\" | \"right\" | \"justify\" {\n return value === \"general\" || value === \"left\" || value === \"center\" || value === \"right\" || value === \"justify\";\n}\n\nfunction isVerticalAlignment(value: unknown): value is \"top\" | \"center\" | \"bottom\" | \"justify\" {\n return value === \"top\" || value === \"center\" || value === \"bottom\" || value === \"justify\";\n}\n\nfunction normalizeColumn(value: unknown, index: number): TableMetadata[\"schema\"][\"columns\"][number] {\n const raw = isRecord(value) ? value : {};\n return {\n id: typeof raw.id === \"string\" ? raw.id : `c${index}`,\n name: typeof raw.name === \"string\" ? raw.name : `column_${index + 1}`,\n index: numeric(raw.index, index),\n dataType: normalizeDataType(raw.dataType ?? { type: \"unknown\" }),\n nullable: raw.nullable !== false,\n ...(isRecord(raw.metadata)\n ? { metadata: Object.freeze(Object.fromEntries(\n Object.entries(raw.metadata).map(([key, entry]) => [key, String(entry)]),\n )) }\n : {}),\n };\n}\n\nfunction normalizeAxis(\n value: unknown,\n fallbackKind: \"exact\" | \"at-least\",\n fallbackValue: number,\n): TableMetadata[\"extent\"][\"rows\"] {\n if (isRecord(value)) {\n if (value.kind === \"unknown\") {\n return { kind: \"unknown\" };\n }\n if (\n (value.kind === \"exact\" || value.kind === \"at-least\")\n && Number.isSafeInteger(value.value)\n && (value.value as number) >= 0\n ) {\n return { kind: value.kind, value: value.value as number };\n }\n }\n return { kind: fallbackKind, value: fallbackValue };\n}\n\nfunction isValidDelimiter(value: unknown): value is string {\n if (typeof value !== \"string\" || value.length !== 1) {\n return false;\n }\n const byte = value.charCodeAt(0);\n return byte <= 0x7f && byte !== 0 && byte !== 0x0d && byte !== 0x0a && byte !== 0x22;\n}\n\nfunction normalizeProgress(\n value: unknown,\n tableId?: string,\n revision?: number,\n): RuntimeProgress {\n const raw = isRecord(value) ? value : {};\n return {\n sourceHandle: typeof raw.sourceHandle === \"string\" ? raw.sourceHandle : \"\",\n ...(typeof raw.tableId === \"string\" && raw.tableId.length > 0\n ? { tableId: raw.tableId }\n : typeof tableId === \"string\" && tableId.length > 0 ? { tableId } : {}),\n ...(Number.isSafeInteger(raw.revision) && (raw.revision as number) >= 0\n ? { revision: raw.revision as number }\n : Number.isSafeInteger(revision) && (revision as number) >= 0\n ? { revision: revision as number }\n : {}),\n bytesScanned: numeric(raw.bytesScanned, 0),\n rowsDiscovered: numeric(raw.rowsDiscovered, 0),\n done: raw.done === true,\n };\n}\n\nfunction normalizeWarning(value: unknown): SourceWarning {\n const raw = isRecord(value) ? value : {};\n return {\n handle: typeof raw.handle === \"string\" ? raw.handle : \"\",\n kind: typeof raw.kind === \"string\" ? raw.kind : \"warning\",\n message: typeof raw.message === \"string\" ? raw.message : \"Source warning\",\n ...(Number.isSafeInteger(raw.byteOffset) ? { byteOffset: raw.byteOffset as number } : {}),\n ...(Number.isSafeInteger(raw.row) && (raw.row as number) >= 0\n ? { row: raw.row as number }\n : {}),\n };\n}\n\nfunction inferSourceName(source: unknown): string | undefined {\n if (typeof File !== \"undefined\" && source instanceof File && source.name.length > 0) {\n return source.name;\n }\n return undefined;\n}\n\nfunction errorFromWire(value: unknown): TabularkError {\n if (isRecord(value) && typeof value.code === \"string\" && typeof value.message === \"string\") {\n return TabularkError.fromSerialized({\n code: value.code,\n message: value.message,\n retryable: value.retryable === true,\n ...(value.details === undefined ? {} : { details: value.details }),\n });\n }\n return new TabularkError(\"RUNTIME_FAILURE\", \"The Worker reported a runtime failure\");\n}\n\nfunction asTabularkError(error: unknown, message: string): TabularkError {\n return error instanceof TabularkError\n ? error\n : new TabularkError(\"RUNTIME_FAILURE\", message, { cause: error });\n}\n\nfunction numeric(value: unknown, fallback: number): number {\n return Number.isSafeInteger(value) && (value as number) >= 0 ? value as number : fallback;\n}\n\nfunction safelyCall<T>(listener: (value: T) => void, value: T): void {\n try {\n listener(value);\n } catch (error) {\n if (typeof reportError === \"function\") {\n reportError(error);\n }\n }\n}\n\n/** Creates one dedicated Worker-backed Tabulark engine. */\nexport function createEngine(options: EngineOptions): Promise<TabularkEngine> {\n return Engine.create(options);\n}\n", "import { invalidArgument } from \"../errors.js\";\nimport type {\n CellPosition,\n GridRange,\n NavigationCommand,\n TableSelection,\n} from \"./types.js\";\n\nexport function createSelection(\n anchor: CellPosition,\n focus: CellPosition = anchor,\n): Readonly<TableSelection> {\n assertCellPosition(anchor, \"anchor\");\n assertCellPosition(focus, \"focus\");\n const normalizedAnchor = Object.freeze({ ...anchor });\n const normalizedFocus = Object.freeze({ ...focus });\n return Object.freeze({\n anchor: normalizedAnchor,\n focus: normalizedFocus,\n range: selectionRange(normalizedAnchor, normalizedFocus),\n });\n}\n\nexport function selectionRange(anchor: CellPosition, focus: CellPosition): Readonly<GridRange> {\n return Object.freeze({\n rowStart: Math.min(anchor.rowIndex, focus.rowIndex),\n rowEnd: Math.max(anchor.rowIndex, focus.rowIndex) + 1,\n columnStart: Math.min(anchor.columnIndex, focus.columnIndex),\n columnEnd: Math.max(anchor.columnIndex, focus.columnIndex) + 1,\n });\n}\n\nexport function containsCell(range: GridRange, cell: CellPosition): boolean {\n return cell.rowIndex >= range.rowStart\n && cell.rowIndex < range.rowEnd\n && cell.columnIndex >= range.columnStart\n && cell.columnIndex < range.columnEnd;\n}\n\nexport function clampCell(\n cell: CellPosition,\n rowCount: number,\n columnCount: number,\n): Readonly<CellPosition> | null {\n if (rowCount <= 0 || columnCount <= 0) {\n return null;\n }\n return Object.freeze({\n rowIndex: clampInteger(cell.rowIndex, 0, rowCount - 1),\n columnIndex: clampInteger(cell.columnIndex, 0, columnCount - 1),\n });\n}\n\nexport function moveCell(\n cell: CellPosition,\n command: NavigationCommand,\n rowCount: number,\n columnCount: number,\n pageRowCount: number,\n): Readonly<CellPosition> | null {\n const current = clampCell(cell, rowCount, columnCount);\n if (current === null) {\n return null;\n }\n const page = Math.max(1, Math.floor(pageRowCount));\n switch (command) {\n case \"left\":\n return clampCell({ rowIndex: current.rowIndex, columnIndex: current.columnIndex - 1 }, rowCount, columnCount);\n case \"right\":\n return clampCell({ rowIndex: current.rowIndex, columnIndex: current.columnIndex + 1 }, rowCount, columnCount);\n case \"up\":\n return clampCell({ rowIndex: current.rowIndex - 1, columnIndex: current.columnIndex }, rowCount, columnCount);\n case \"down\":\n return clampCell({ rowIndex: current.rowIndex + 1, columnIndex: current.columnIndex }, rowCount, columnCount);\n case \"page-up\":\n return clampCell({ rowIndex: current.rowIndex - page, columnIndex: current.columnIndex }, rowCount, columnCount);\n case \"page-down\":\n return clampCell({ rowIndex: current.rowIndex + page, columnIndex: current.columnIndex }, rowCount, columnCount);\n case \"row-start\":\n return Object.freeze({ rowIndex: current.rowIndex, columnIndex: 0 });\n case \"row-end\":\n return Object.freeze({ rowIndex: current.rowIndex, columnIndex: columnCount - 1 });\n case \"table-start\":\n return Object.freeze({ rowIndex: 0, columnIndex: 0 });\n case \"table-end\":\n return Object.freeze({ rowIndex: rowCount - 1, columnIndex: columnCount - 1 });\n }\n}\n\nexport function assertCellPosition(value: CellPosition, name: string): void {\n if (!Number.isSafeInteger(value.rowIndex) || value.rowIndex < 0) {\n throw invalidArgument(`${name}.rowIndex must be a non-negative safe integer`);\n }\n if (!Number.isSafeInteger(value.columnIndex) || value.columnIndex < 0) {\n throw invalidArgument(`${name}.columnIndex must be a non-negative safe integer`);\n }\n}\n\nfunction clampInteger(value: number, minimum: number, maximum: number): number {\n if (!Number.isFinite(value)) {\n return minimum;\n }\n return Math.min(maximum, Math.max(minimum, Math.trunc(value)));\n}\n", "export interface AccessibleGridColumn {\n readonly index: number;\n readonly name: string;\n}\n\nexport interface AccessibleGridCell {\n readonly rowIndex: number;\n readonly columnIndex: number;\n readonly value: string | null | undefined;\n readonly selected: boolean;\n readonly active: boolean;\n readonly rowSpan?: number;\n readonly columnSpan?: number;\n}\n\nexport interface AccessibleGridRow {\n readonly index: number;\n readonly cells: readonly AccessibleGridCell[];\n}\n\nexport interface AccessibleGridSnapshot {\n readonly label: string;\n readonly exactRowCount?: number;\n readonly columnCount: number;\n readonly columns: readonly AccessibleGridColumn[];\n readonly rows: readonly AccessibleGridRow[];\n readonly busy: boolean;\n readonly status?: string;\n}\n\nlet nextGridId = 1;\n\n/** A viewport-bounded semantic counterpart to the visual Canvas table. */\nexport class AccessibleViewportGrid {\n readonly element: HTMLDivElement;\n readonly statusElement: HTMLDivElement;\n\n readonly #idPrefix: string;\n #destroyed = false;\n\n constructor(ownerDocument: Document, label = \"Data table\") {\n this.#idPrefix = `tabulark-grid-${nextGridId}`;\n nextGridId += 1;\n\n this.element = ownerDocument.createElement(\"div\");\n this.element.className = \"tabulark-a11y-grid\";\n this.element.dataset.tabularkA11yGrid = \"\";\n this.element.id = this.#idPrefix;\n this.element.setAttribute(\"role\", \"grid\");\n this.element.setAttribute(\"aria-label\", label);\n this.element.tabIndex = 0;\n visuallyHide(this.element);\n\n this.statusElement = ownerDocument.createElement(\"div\");\n this.statusElement.className = \"tabulark-status\";\n this.statusElement.dataset.tabularkStatus = \"\";\n this.statusElement.setAttribute(\"role\", \"status\");\n this.statusElement.setAttribute(\"aria-live\", \"polite\");\n this.statusElement.setAttribute(\"aria-atomic\", \"true\");\n visuallyHide(this.statusElement);\n }\n\n update(snapshot: AccessibleGridSnapshot): void {\n if (this.#destroyed) {\n return;\n }\n\n this.element.setAttribute(\"aria-label\", snapshot.label);\n this.element.setAttribute(\"aria-colcount\", String(snapshot.columnCount));\n setOptionalAttribute(\n this.element,\n \"aria-rowcount\",\n snapshot.exactRowCount === undefined ? undefined : String(snapshot.exactRowCount + 1),\n );\n this.element.setAttribute(\"aria-busy\", String(snapshot.busy));\n\n const fragment = this.element.ownerDocument.createDocumentFragment();\n fragment.append(this.#createHeader(snapshot.columns));\n\n let activeId: string | undefined;\n for (const row of snapshot.rows) {\n const rowElement = this.element.ownerDocument.createElement(\"div\");\n rowElement.setAttribute(\"role\", \"row\");\n // ARIA row indices are one-based; index 1 belongs to the header row.\n rowElement.setAttribute(\"aria-rowindex\", String(row.index + 2));\n\n for (const cell of row.cells) {\n const cellElement = this.element.ownerDocument.createElement(\"div\");\n cellElement.setAttribute(\"role\", \"gridcell\");\n cellElement.setAttribute(\"aria-colindex\", String(cell.columnIndex + 1));\n cellElement.setAttribute(\"aria-selected\", String(cell.selected));\n setOptionalAttribute(\n cellElement,\n \"aria-rowspan\",\n cell.rowSpan === undefined || cell.rowSpan <= 1 ? undefined : String(cell.rowSpan),\n );\n setOptionalAttribute(\n cellElement,\n \"aria-colspan\",\n cell.columnSpan === undefined || cell.columnSpan <= 1 ? undefined : String(cell.columnSpan),\n );\n cellElement.textContent = cell.value === undefined\n ? \"Loading\"\n : cell.value === null\n ? \"Empty\"\n : cell.value;\n if (cell.active) {\n activeId = this.#cellId(cell.rowIndex, cell.columnIndex);\n cellElement.id = activeId;\n }\n rowElement.append(cellElement);\n }\n fragment.append(rowElement);\n }\n\n this.element.replaceChildren(fragment);\n setOptionalAttribute(this.element, \"aria-activedescendant\", activeId);\n if (snapshot.status !== undefined && snapshot.status !== this.statusElement.textContent) {\n this.statusElement.textContent = snapshot.status;\n }\n }\n\n focus(options?: FocusOptions): void {\n this.element.focus(options);\n }\n\n destroy(): void {\n if (this.#destroyed) {\n return;\n }\n this.#destroyed = true;\n this.element.remove();\n this.statusElement.remove();\n }\n\n #createHeader(columns: readonly AccessibleGridColumn[]): HTMLDivElement {\n const row = this.element.ownerDocument.createElement(\"div\");\n row.setAttribute(\"role\", \"row\");\n row.setAttribute(\"aria-rowindex\", \"1\");\n for (const column of columns) {\n const cell = this.element.ownerDocument.createElement(\"div\");\n cell.setAttribute(\"role\", \"columnheader\");\n cell.setAttribute(\"aria-colindex\", String(column.index + 1));\n cell.textContent = column.name;\n row.append(cell);\n }\n return row;\n }\n\n #cellId(rowIndex: number, columnIndex: number): string {\n return `${this.#idPrefix}-r${rowIndex}-c${columnIndex}`;\n }\n}\n\nfunction visuallyHide(element: HTMLElement): void {\n Object.assign(element.style, {\n border: \"0\",\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"-1px\",\n overflow: \"hidden\",\n padding: \"0\",\n pointerEvents: \"none\",\n position: \"absolute\",\n whiteSpace: \"nowrap\",\n width: \"1px\",\n });\n}\n\nfunction setOptionalAttribute(\n element: Element,\n name: string,\n value: string | undefined,\n): void {\n if (value === undefined) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value);\n }\n}\n", "import type {\n MergedCellRegion,\n PresentationBorderSide,\n PresentationStyle,\n} from \"../model.js\";\n\nexport interface CanvasPaintColumn {\n readonly index: number;\n readonly name: string;\n /** Viewport-relative x coordinate, including the pinned row gutter offset. */\n readonly x: number;\n readonly width: number;\n readonly frozen?: boolean;\n}\n\nexport interface CanvasPaintCell {\n readonly columnIndex: number;\n readonly value: string | null | undefined;\n readonly style?: PresentationStyle;\n /** The cell is painted by its merge anchor rather than its own grid slot. */\n readonly coveredByMerge?: boolean;\n}\n\nexport interface CanvasPaintRow {\n readonly index: number;\n /** Viewport-relative y coordinate, including the pinned header offset. */\n readonly y: number;\n readonly height: number;\n readonly frozen?: boolean;\n readonly cells: readonly CanvasPaintCell[];\n}\n\nexport interface CanvasPaintMergedCell {\n readonly region: Readonly<MergedCellRegion>;\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n readonly value: string | null | undefined;\n readonly style?: PresentationStyle;\n /** A pane-clipped continuation; only the anchor fragment paints the value. */\n readonly continuation?: boolean;\n}\n\nexport interface CanvasPaintSelection {\n readonly rowStart: number;\n /** Exclusive table row bound. */\n readonly rowEnd: number;\n readonly columnStart: number;\n /** Exclusive table column bound. */\n readonly columnEnd: number;\n}\n\nexport interface CanvasPaintActiveCell {\n readonly rowIndex: number;\n readonly columnIndex: number;\n}\n\nexport interface CanvasPaintSnapshot {\n readonly width: number;\n readonly height: number;\n readonly headerHeight: number;\n readonly rowGutterWidth: number;\n readonly columns: readonly CanvasPaintColumn[];\n readonly rows: readonly CanvasPaintRow[];\n readonly mergedCells?: readonly CanvasPaintMergedCell[];\n readonly selection?: CanvasPaintSelection;\n readonly activeCell?: CanvasPaintActiveCell;\n readonly busy: boolean;\n}\n\nexport interface CanvasTableTheme {\n readonly background: string;\n readonly foreground: string;\n readonly mutedForeground: string;\n readonly headerBackground: string;\n readonly headerForeground: string;\n readonly alternateRowBackground: string;\n readonly gridLine: string;\n readonly selectionBackground: string;\n readonly selectionBorder: string;\n readonly activeCellBorder: string;\n readonly loadingBackground: string;\n readonly font: string;\n readonly headerFont: string;\n}\n\nexport const DEFAULT_CANVAS_TABLE_THEME: Readonly<CanvasTableTheme> = Object.freeze({\n background: \"#ffffff\",\n foreground: \"#172033\",\n mutedForeground: \"#667085\",\n headerBackground: \"#f2f4f7\",\n headerForeground: \"#344054\",\n alternateRowBackground: \"#f9fafb\",\n gridLine: \"#d0d5dd\",\n selectionBackground: \"rgba(21, 112, 239, 0.14)\",\n selectionBorder: \"#1570ef\",\n activeCellBorder: \"#175cd3\",\n loadingBackground: \"#e4e7ec\",\n font: '13px ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n headerFont: '600 13px ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n});\n\n/** Resolves author-independent system colors for Windows High Contrast and other forced palettes. */\nexport function forcedColorsCanvasTableTheme(\n base: Readonly<CanvasTableTheme> = DEFAULT_CANVAS_TABLE_THEME,\n): Readonly<CanvasTableTheme> {\n return Object.freeze({\n ...base,\n background: \"Canvas\",\n foreground: \"CanvasText\",\n mutedForeground: \"GrayText\",\n headerBackground: \"Canvas\",\n headerForeground: \"CanvasText\",\n alternateRowBackground: \"Canvas\",\n gridLine: \"CanvasText\",\n selectionBackground: \"Highlight\",\n selectionBorder: \"Highlight\",\n activeCellBorder: \"CanvasText\",\n loadingBackground: \"GrayText\",\n });\n}\n\n/** Paints one viewport frame and keeps the backing store device-pixel aware. */\nexport class CanvasTablePainter {\n readonly canvas: HTMLCanvasElement;\n readonly #context: CanvasRenderingContext2D;\n #theme: Readonly<CanvasTableTheme>;\n readonly #maxDevicePixelRatio: number;\n #forcedColors: boolean;\n\n #cssWidth = 0;\n #cssHeight = 0;\n #devicePixelRatio = 1;\n\n constructor(\n canvas: HTMLCanvasElement,\n options: {\n readonly theme?: Partial<CanvasTableTheme>;\n readonly maxDevicePixelRatio?: number;\n readonly forcedColors?: boolean;\n } = {},\n ) {\n const context = canvas.getContext(\"2d\", { alpha: false });\n if (context === null) {\n throw new Error(\"Tabulark Canvas rendering requires a 2D rendering context\");\n }\n this.canvas = canvas;\n this.#context = context;\n this.#theme = Object.freeze({ ...DEFAULT_CANVAS_TABLE_THEME, ...options.theme });\n this.#maxDevicePixelRatio = positive(options.maxDevicePixelRatio, Number.POSITIVE_INFINITY);\n this.#forcedColors = options.forcedColors ?? false;\n }\n\n setTheme(theme: Readonly<CanvasTableTheme>, options: { readonly forcedColors?: boolean } = {}): void {\n this.#theme = Object.freeze({ ...theme });\n this.#forcedColors = options.forcedColors ?? false;\n }\n\n paint(snapshot: CanvasPaintSnapshot): void {\n this.#resize(snapshot.width, snapshot.height);\n const context = this.#context;\n const theme = this.#theme;\n\n context.save();\n context.setTransform(\n this.#devicePixelRatio,\n 0,\n 0,\n this.#devicePixelRatio,\n 0,\n 0,\n );\n context.clearRect(0, 0, snapshot.width, snapshot.height);\n context.fillStyle = theme.background;\n context.fillRect(0, 0, snapshot.width, snapshot.height);\n\n this.#paintRows(snapshot);\n this.#paintHeader(snapshot);\n this.#paintGrid(snapshot);\n this.#paintMergedCells(snapshot);\n this.#paintSelection(snapshot);\n context.restore();\n }\n\n #resize(width: number, height: number): void {\n const view = this.canvas.ownerDocument.defaultView;\n const browserRatio = view?.devicePixelRatio ?? 1;\n const ratio = Math.max(1, Math.min(browserRatio, this.#maxDevicePixelRatio));\n const cssWidth = Math.max(0, Math.floor(width));\n const cssHeight = Math.max(0, Math.floor(height));\n const pixelWidth = Math.max(1, Math.round(cssWidth * ratio));\n const pixelHeight = Math.max(1, Math.round(cssHeight * ratio));\n\n if (\n cssWidth === this.#cssWidth &&\n cssHeight === this.#cssHeight &&\n ratio === this.#devicePixelRatio &&\n this.canvas.width === pixelWidth &&\n this.canvas.height === pixelHeight\n ) {\n return;\n }\n\n this.#cssWidth = cssWidth;\n this.#cssHeight = cssHeight;\n this.#devicePixelRatio = ratio;\n this.canvas.width = pixelWidth;\n this.canvas.height = pixelHeight;\n this.canvas.style.width = `${cssWidth}px`;\n this.canvas.style.height = `${cssHeight}px`;\n }\n\n #paintRows(snapshot: CanvasPaintSnapshot): void {\n const context = this.#context;\n const theme = this.#theme;\n const columnsByIndex = new Map(snapshot.columns.map((column) => [column.index, column]));\n context.font = theme.font;\n context.textBaseline = \"middle\";\n\n const rows = [\n ...snapshot.rows.filter((row) => row.frozen !== true),\n ...snapshot.rows.filter((row) => row.frozen === true),\n ];\n for (const row of rows) {\n if (row.y + row.height <= snapshot.headerHeight || row.y >= snapshot.height) {\n continue;\n }\n context.fillStyle = row.index % 2 === 0 ? theme.background : theme.alternateRowBackground;\n context.fillRect(0, row.y, snapshot.width, row.height);\n\n context.fillStyle = theme.mutedForeground;\n context.textAlign = \"right\";\n context.fillText(\n String(row.index + 1),\n snapshot.rowGutterWidth - 10,\n row.y + row.height / 2,\n );\n\n const cells = [\n ...row.cells.filter((cell) => columnsByIndex.get(cell.columnIndex)?.frozen !== true),\n ...row.cells.filter((cell) => columnsByIndex.get(cell.columnIndex)?.frozen === true),\n ];\n for (const cell of cells) {\n const column = columnsByIndex.get(cell.columnIndex);\n if (\n column === undefined\n || column.x + column.width <= snapshot.rowGutterWidth\n || cell.coveredByMerge === true\n ) {\n continue;\n }\n this.#paintCellValue(\n cell.value,\n column.x,\n row.y,\n column.width,\n row.height,\n cell.style,\n );\n }\n }\n }\n\n #paintCellValue(\n value: string | null | undefined,\n x: number,\n y: number,\n width: number,\n height: number,\n style?: PresentationStyle,\n ): void {\n const context = this.#context;\n const theme = this.#theme;\n const horizontalPadding = 10;\n if (width <= horizontalPadding * 2) {\n return;\n }\n\n context.save();\n context.beginPath();\n context.rect(x + 1, y + 1, Math.max(0, width - 2), Math.max(0, height - 2));\n context.clip();\n this.#paintCellFill(x, y, width, height, style);\n this.#applyCellFont(style);\n context.textAlign = horizontalAlignment(style);\n context.textBaseline = verticalBaseline(style);\n if (value === undefined) {\n context.fillStyle = theme.loadingBackground;\n const skeletonWidth = Math.max(12, Math.min(width - horizontalPadding * 2, width * 0.42));\n context.fillRect(x + horizontalPadding, y + height / 2 - 3, skeletonWidth, 6);\n } else {\n context.fillStyle = value === null\n ? theme.mutedForeground\n : this.#cellForeground(style, theme.foreground);\n const label = value === null ? \"\u2205\" : value;\n const textX = horizontalTextX(context.textAlign, x, width, horizontalPadding);\n const textY = verticalTextY(context.textBaseline, y, height, 4);\n context.fillText(label, textX, textY, Math.max(0, width - horizontalPadding * 2));\n if (style?.font?.underline === true) {\n const measured = Math.min(context.measureText(label).width, width - horizontalPadding * 2);\n const start = underlineStart(context.textAlign, textX, measured);\n context.strokeStyle = String(context.fillStyle);\n context.lineWidth = 1;\n context.beginPath();\n context.moveTo(start, Math.min(y + height - 4, textY + 3));\n context.lineTo(start + measured, Math.min(y + height - 4, textY + 3));\n context.stroke();\n }\n }\n this.#paintCellBorders(x, y, width, height, style);\n context.restore();\n }\n\n #paintMergedCells(snapshot: CanvasPaintSnapshot): void {\n for (const merged of snapshot.mergedCells ?? []) {\n if (\n merged.width <= 0\n || merged.height <= 0\n || merged.x + merged.width <= snapshot.rowGutterWidth\n || merged.y + merged.height <= snapshot.headerHeight\n || merged.x >= snapshot.width\n || merged.y >= snapshot.height\n ) {\n continue;\n }\n this.#context.fillStyle = merged.region.rowStart % 2 === 0\n ? this.#theme.background\n : this.#theme.alternateRowBackground;\n this.#context.fillRect(merged.x, merged.y, merged.width, merged.height);\n if (merged.continuation === true) {\n this.#paintCellFill(merged.x, merged.y, merged.width, merged.height, merged.style);\n this.#paintCellBorders(merged.x, merged.y, merged.width, merged.height, merged.style);\n } else {\n this.#paintCellValue(\n merged.value,\n merged.x,\n merged.y,\n merged.width,\n merged.height,\n merged.style,\n );\n }\n this.#context.strokeStyle = this.#theme.gridLine;\n this.#context.lineWidth = 1 / this.#devicePixelRatio;\n this.#context.strokeRect(\n merged.x + 0.5 / this.#devicePixelRatio,\n merged.y + 0.5 / this.#devicePixelRatio,\n Math.max(0, merged.width - 1 / this.#devicePixelRatio),\n Math.max(0, merged.height - 1 / this.#devicePixelRatio),\n );\n }\n }\n\n #paintCellFill(\n x: number,\n y: number,\n width: number,\n height: number,\n style: PresentationStyle | undefined,\n ): void {\n if (this.#forcedColors || style === undefined) return;\n const color = cssColor(style.fillColor ?? style.backgroundColor);\n if (color === undefined) return;\n this.#context.fillStyle = color;\n this.#context.fillRect(x + 1, y + 1, Math.max(0, width - 2), Math.max(0, height - 2));\n }\n\n #applyCellFont(style: PresentationStyle | undefined): void {\n if (style?.font === undefined) {\n this.#context.font = this.#theme.font;\n return;\n }\n const font = style.font;\n const size = finitePositive(font.size) ?? 13;\n const family = font.family && font.family.trim().length > 0\n ? font.family\n : 'ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif';\n this.#context.font = `${font.italic === true ? \"italic \" : \"\"}${font.bold === true ? \"700 \" : \"400 \"}${size}px ${family}`;\n }\n\n #cellForeground(style: PresentationStyle | undefined, fallback: string): string {\n if (this.#forcedColors) return fallback;\n return cssColor(style?.font?.color)\n ?? cssColor(style?.foregroundColor)\n ?? fallback;\n }\n\n #paintCellBorders(\n x: number,\n y: number,\n width: number,\n height: number,\n style: PresentationStyle | undefined,\n ): void {\n if (style?.borders === undefined) return;\n const context = this.#context;\n const sides = style.borders;\n const paint = (\n side: \"top\" | \"right\" | \"bottom\" | \"left\",\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n ) => {\n const border = sides[side];\n if (border === undefined || border.style === \"none\") return;\n context.save();\n const widthForStyle = borderWidth(border.style);\n context.lineWidth = widthForStyle;\n context.strokeStyle = this.#forcedColors\n ? this.#theme.gridLine\n : cssColor(border.color) ?? this.#theme.gridLine;\n context.setLineDash(borderDash(border.style));\n context.beginPath();\n context.moveTo(startX, startY);\n context.lineTo(endX, endY);\n context.stroke();\n if (border.style === \"double\") {\n const offset = Math.max(2, widthForStyle + 1);\n const horizontal = startY === endY;\n context.beginPath();\n context.moveTo(horizontal ? startX : startX + offset, horizontal ? startY + offset : startY);\n context.lineTo(horizontal ? endX : endX + offset, horizontal ? endY + offset : endY);\n context.stroke();\n }\n context.restore();\n };\n paint(\"top\", x + 0.5, y + 0.5, x + width - 0.5, y + 0.5);\n paint(\"right\", x + width - 0.5, y + 0.5, x + width - 0.5, y + height - 0.5);\n paint(\"bottom\", x + 0.5, y + height - 0.5, x + width - 0.5, y + height - 0.5);\n paint(\"left\", x + 0.5, y + 0.5, x + 0.5, y + height - 0.5);\n }\n\n #paintHeader(snapshot: CanvasPaintSnapshot): void {\n const context = this.#context;\n const theme = this.#theme;\n context.fillStyle = theme.headerBackground;\n context.fillRect(0, 0, snapshot.width, snapshot.headerHeight);\n context.font = theme.headerFont;\n context.fillStyle = theme.headerForeground;\n context.textBaseline = \"middle\";\n context.textAlign = \"left\";\n\n const columns = [\n ...snapshot.columns.filter((column) => column.frozen !== true),\n ...snapshot.columns.filter((column) => column.frozen === true),\n ];\n for (const column of columns) {\n if (column.x + column.width <= snapshot.rowGutterWidth || column.x >= snapshot.width) {\n continue;\n }\n context.save();\n context.beginPath();\n context.rect(column.x + 1, 0, Math.max(0, column.width - 2), snapshot.headerHeight);\n context.clip();\n context.fillText(column.name, column.x + 10, snapshot.headerHeight / 2);\n context.restore();\n }\n\n context.textAlign = \"center\";\n context.fillText(\n \"#\",\n snapshot.rowGutterWidth / 2,\n snapshot.headerHeight / 2,\n snapshot.rowGutterWidth,\n );\n }\n\n #paintGrid(snapshot: CanvasPaintSnapshot): void {\n const context = this.#context;\n const theme = this.#theme;\n context.strokeStyle = theme.gridLine;\n context.lineWidth = 1 / this.#devicePixelRatio;\n context.beginPath();\n\n const snap = 0.5 / this.#devicePixelRatio;\n context.moveTo(snapshot.rowGutterWidth + snap, 0);\n context.lineTo(snapshot.rowGutterWidth + snap, snapshot.height);\n context.moveTo(0, snapshot.headerHeight + snap);\n context.lineTo(snapshot.width, snapshot.headerHeight + snap);\n\n for (const column of snapshot.columns) {\n const x = column.x + column.width + snap;\n if (x > snapshot.rowGutterWidth && x < snapshot.width) {\n context.moveTo(x, 0);\n context.lineTo(x, snapshot.height);\n }\n }\n for (const row of snapshot.rows) {\n const y = row.y + row.height + snap;\n if (y > snapshot.headerHeight && y < snapshot.height) {\n context.moveTo(0, y);\n context.lineTo(snapshot.width, y);\n }\n }\n context.stroke();\n }\n\n #paintSelection(snapshot: CanvasPaintSnapshot): void {\n const selection = snapshot.selection;\n const context = this.#context;\n const theme = this.#theme;\n if (selection !== undefined) {\n const selectedColumns = snapshot.columns.filter(\n (column) => column.index >= selection.columnStart && column.index < selection.columnEnd,\n );\n const selectedRows = snapshot.rows.filter(\n (row) => row.index >= selection.rowStart && row.index < selection.rowEnd,\n );\n if (selectedColumns.length > 0 && selectedRows.length > 0) {\n const firstColumn = selectedColumns[0]!;\n const lastColumn = selectedColumns.at(-1)!;\n const firstRow = selectedRows[0]!;\n const lastRow = selectedRows.at(-1)!;\n const x = Math.max(snapshot.rowGutterWidth, firstColumn.x);\n const y = Math.max(snapshot.headerHeight, firstRow.y);\n const right = Math.min(snapshot.width, lastColumn.x + lastColumn.width);\n const bottom = Math.min(snapshot.height, lastRow.y + lastRow.height);\n if (right > x && bottom > y) {\n context.save();\n context.fillStyle = theme.selectionBackground;\n if (this.#forcedColors) {\n context.globalAlpha = 0.28;\n }\n context.fillRect(x, y, right - x, bottom - y);\n context.restore();\n context.strokeStyle = theme.selectionBorder;\n context.lineWidth = this.#forcedColors ? 2 : 1;\n context.setLineDash(this.#forcedColors ? [4, 2] : []);\n context.strokeRect(\n x + context.lineWidth / 2,\n y + context.lineWidth / 2,\n Math.max(0, right - x - context.lineWidth),\n Math.max(0, bottom - y - context.lineWidth),\n );\n context.setLineDash([]);\n }\n }\n }\n\n const activeMerges = snapshot.activeCell === undefined\n ? []\n : snapshot.mergedCells?.filter((merged) => (\n snapshot.activeCell!.rowIndex >= merged.region.rowStart\n && snapshot.activeCell!.rowIndex < merged.region.rowEnd\n && snapshot.activeCell!.columnIndex >= merged.region.columnStart\n && snapshot.activeCell!.columnIndex < merged.region.columnEnd\n )) ?? [];\n const activeColumn = snapshot.activeCell === undefined\n ? undefined\n : snapshot.columns.find((column) => column.index === snapshot.activeCell!.columnIndex);\n const activeRow = snapshot.activeCell === undefined\n ? undefined\n : snapshot.rows.find((row) => row.index === snapshot.activeCell!.rowIndex);\n const activeRects = activeMerges.length > 0\n ? activeMerges\n : activeColumn !== undefined && activeRow !== undefined\n ? [{\n x: activeColumn.x,\n y: activeRow.y,\n width: activeColumn.width,\n height: activeRow.height,\n }]\n : [];\n for (const activeRect of activeRects) {\n const activeX = Math.max(snapshot.rowGutterWidth, activeRect.x);\n const activeY = Math.max(snapshot.headerHeight, activeRect.y);\n const activeRight = Math.min(snapshot.width, activeRect.x + activeRect.width);\n const activeBottom = Math.min(snapshot.height, activeRect.y + activeRect.height);\n context.strokeStyle = theme.activeCellBorder;\n context.lineWidth = this.#forcedColors ? 3 : 2;\n context.setLineDash([]);\n context.strokeRect(\n activeX + context.lineWidth / 2,\n activeY + context.lineWidth / 2,\n Math.max(0, activeRight - activeX - context.lineWidth),\n Math.max(0, activeBottom - activeY - context.lineWidth),\n );\n }\n }\n}\n\nfunction cssColor(color: { readonly css?: string } | undefined): string | undefined {\n const value = color?.css?.trim();\n if (!value) return undefined;\n const supports = globalThis.CSS?.supports;\n return typeof supports !== \"function\" || supports(\"color\", value) ? value : undefined;\n}\n\nfunction finitePositive(value: number | undefined): number | undefined {\n return value !== undefined && Number.isFinite(value) && value > 0 ? value : undefined;\n}\n\nfunction horizontalAlignment(style: PresentationStyle | undefined): CanvasTextAlign {\n switch (style?.horizontalAlignment) {\n case \"center\":\n return \"center\";\n case \"right\":\n return \"right\";\n case \"left\":\n case \"justify\":\n case \"general\":\n default:\n return \"left\";\n }\n}\n\nfunction verticalBaseline(style: PresentationStyle | undefined): CanvasTextBaseline {\n switch (style?.verticalAlignment) {\n case \"top\":\n return \"top\";\n case \"bottom\":\n return \"bottom\";\n case \"center\":\n case \"justify\":\n default:\n return \"middle\";\n }\n}\n\nfunction horizontalTextX(\n alignment: CanvasTextAlign,\n x: number,\n width: number,\n padding: number,\n): number {\n if (alignment === \"center\") return x + width / 2;\n if (alignment === \"right\" || alignment === \"end\") return x + width - padding;\n return x + padding;\n}\n\nfunction verticalTextY(\n baseline: CanvasTextBaseline,\n y: number,\n height: number,\n padding: number,\n): number {\n if (baseline === \"top\" || baseline === \"hanging\") return y + padding;\n if (baseline === \"bottom\" || baseline === \"ideographic\") return y + height - padding;\n return y + height / 2;\n}\n\nfunction underlineStart(alignment: CanvasTextAlign, textX: number, width: number): number {\n if (alignment === \"center\") return textX - width / 2;\n if (alignment === \"right\" || alignment === \"end\") return textX - width;\n return textX;\n}\n\nfunction borderWidth(style: PresentationBorderSide[\"style\"]): number {\n switch (style) {\n case \"medium\":\n return 2;\n case \"thick\":\n return 3;\n case \"double\":\n return 1;\n default:\n return 1;\n }\n}\n\nfunction borderDash(style: string | undefined): readonly number[] {\n if (style === \"dashed\") return [4, 2];\n if (style === \"dotted\") return [1, 2];\n return [];\n}\n\nfunction positive(value: number | undefined, fallback: number): number {\n return value !== undefined && Number.isFinite(value) && value > 0 ? value : fallback;\n}\n", "import type { TableMetadata } from \"../model.js\";\n\nexport const DEFAULT_ROW_HEIGHT = 28;\nexport const DEFAULT_HEADER_HEIGHT = 36;\nexport const DEFAULT_ROW_HEADER_WIDTH = 64;\nexport const DEFAULT_COLUMN_WIDTH = 160;\nexport const DEFAULT_MIN_COLUMN_WIDTH = 64;\nexport const DEFAULT_MAX_COLUMN_WIDTH = 640;\nexport const DEFAULT_SCROLL_PIXEL_LIMIT = 16_000_000;\nexport const DEFAULT_OVERSCAN_ROWS = 8;\nexport const DEFAULT_OVERSCAN_COLUMNS = 1;\n\n/** A zero-based table coordinate. */\nexport interface CellPosition {\n readonly rowIndex: number;\n readonly columnIndex: number;\n}\n\n/** A zero-based, half-open rectangular table range. */\nexport interface GridRange {\n readonly rowStart: number;\n readonly rowEnd: number;\n readonly columnStart: number;\n readonly columnEnd: number;\n}\n\nexport interface TableSelection {\n readonly anchor: Readonly<CellPosition>;\n readonly focus: Readonly<CellPosition>;\n readonly range: Readonly<GridRange>;\n}\n\nexport interface PixelRect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\nexport interface IndexRange {\n readonly start: number;\n readonly end: number;\n}\n\nexport interface ScrollAxisLayout {\n readonly logicalContentSize: number;\n readonly logicalViewportSize: number;\n readonly logicalOffset: number;\n readonly logicalMaxOffset: number;\n readonly physicalContentSize: number;\n readonly physicalOffset: number;\n readonly physicalMaxOffset: number;\n readonly compressed: boolean;\n}\n\nexport interface VisibleColumn {\n readonly index: number;\n readonly id: string;\n readonly name: string;\n /** Viewport-relative left edge in CSS pixels. */\n readonly x: number;\n readonly width: number;\n /** True when the column is pinned at the workbook's frozen boundary. */\n readonly frozen: boolean;\n}\n\nexport interface VisibleRow {\n readonly index: number;\n /** Viewport-relative top edge in CSS pixels. */\n readonly y: number;\n readonly height: number;\n /** True when the row is pinned at the workbook's frozen boundary. */\n readonly frozen: boolean;\n}\n\nexport interface SparseAxisOverride {\n readonly index: number;\n readonly size: number;\n /** Cumulative size delta through and including this override. */\n readonly cumulativeDelta: number;\n}\n\n/** Compact geometry for a potentially million-row spreadsheet axis. */\nexport interface SparseAxisGeometry {\n readonly count: number;\n readonly defaultSize: number;\n readonly contentSize: number;\n readonly overrides: readonly Readonly<SparseAxisOverride>[];\n}\n\nexport interface TableLayout {\n readonly width: number;\n readonly height: number;\n readonly devicePixelRatio: number;\n readonly rowHeight: number;\n readonly headerHeight: number;\n readonly rowHeaderWidth: number;\n readonly bodyWidth: number;\n readonly bodyHeight: number;\n readonly rowCount: number;\n readonly columnCount: number;\n readonly rows: Readonly<{\n readonly visible: Readonly<IndexRange>;\n readonly overscan: Readonly<IndexRange>;\n }>;\n readonly columns: Readonly<{\n readonly visible: Readonly<IndexRange>;\n readonly overscan: Readonly<IndexRange>;\n }>;\n readonly visibleColumns: readonly Readonly<VisibleColumn>[];\n readonly overscanColumns: readonly Readonly<VisibleColumn>[];\n readonly visibleRows: readonly Readonly<VisibleRow>[];\n readonly overscanRows: readonly Readonly<VisibleRow>[];\n /** Effective widths use zero for workbook-hidden columns. */\n readonly effectiveColumnWidths: readonly number[];\n readonly rowGeometry: Readonly<SparseAxisGeometry>;\n readonly frozenRowCount: number;\n readonly frozenColumnCount: number;\n readonly frozenRowExtent: number;\n readonly frozenColumnExtent: number;\n /** Frozen segments are loaded separately when the scroll window is distant. */\n readonly frozenRowRange: Readonly<IndexRange>;\n readonly frozenColumnRange: Readonly<IndexRange>;\n readonly horizontal: Readonly<ScrollAxisLayout>;\n readonly vertical: Readonly<ScrollAxisLayout>;\n /** Spacer dimensions for a native scroll host, including sticky headers. */\n readonly spacerWidth: number;\n readonly spacerHeight: number;\n}\n\nexport type HitTestResult =\n | Readonly<{ kind: \"outside\" }>\n | Readonly<{ kind: \"corner\" }>\n | Readonly<{ kind: \"column-header\"; columnIndex: number }>\n | Readonly<{ kind: \"column-resize\"; columnIndex: number; boundaryX: number }>\n | Readonly<{ kind: \"row-header\"; rowIndex: number }>\n | Readonly<{ kind: \"cell\"; rowIndex: number; columnIndex: number }>;\n\nexport type CellLoadState =\n | Readonly<{ status: \"loading\" }>\n | Readonly<{ status: \"unavailable\" }>\n | Readonly<{ status: \"loaded\"; value: string | null }>;\n\nexport type TableViewStatus = \"loading\" | \"ready\" | \"error\" | \"closed\";\n\nexport interface TableViewSnapshot {\n readonly generation: number;\n readonly status: TableViewStatus;\n readonly metadata: Readonly<TableMetadata>;\n readonly layout: Readonly<TableLayout>;\n readonly activeCell: Readonly<CellPosition> | null;\n readonly selection: Readonly<TableSelection> | null;\n readonly error?: unknown;\n}\n\nexport interface ViewportUpdate {\n readonly width: number;\n readonly height: number;\n /** Native scroll-host offset in CSS pixels. */\n readonly scrollLeft: number;\n /** Native scroll-host offset in CSS pixels. */\n readonly scrollTop: number;\n readonly devicePixelRatio?: number;\n}\n\nexport interface TableControllerOptions {\n readonly rowHeight?: number;\n readonly headerHeight?: number;\n readonly rowHeaderWidth?: number;\n readonly columnWidth?: number;\n readonly minColumnWidth?: number;\n readonly maxColumnWidth?: number;\n readonly columnWidths?: Readonly<Record<string, number>>;\n readonly scrollPixelLimit?: number;\n readonly overscanRows?: number;\n readonly overscanColumns?: number;\n /** Hard bound for decoded render/cache cells. */\n readonly maxWindowCells?: number;\n}\n\nexport type NavigationCommand =\n | \"left\"\n | \"right\"\n | \"up\"\n | \"down\"\n | \"page-up\"\n | \"page-down\"\n | \"row-start\"\n | \"row-end\"\n | \"table-start\"\n | \"table-end\";\n\nexport interface SetActiveCellOptions {\n readonly extendSelection?: boolean;\n readonly scrollIntoView?: boolean;\n}\n\nexport interface MoveActiveCellOptions extends SetActiveCellOptions {}\n", "import { invalidArgument } from \"../errors.js\";\nimport type { PresentationAxisEntry, TableMetadata } from \"../model.js\";\nimport {\n DEFAULT_COLUMN_WIDTH,\n DEFAULT_HEADER_HEIGHT,\n DEFAULT_OVERSCAN_COLUMNS,\n DEFAULT_OVERSCAN_ROWS,\n DEFAULT_ROW_HEADER_WIDTH,\n DEFAULT_ROW_HEIGHT,\n DEFAULT_SCROLL_PIXEL_LIMIT,\n type GridRange,\n type HitTestResult,\n type IndexRange,\n type PixelRect,\n type ScrollAxisLayout,\n type SparseAxisGeometry,\n type TableLayout,\n type ViewportUpdate,\n type VisibleColumn,\n type VisibleRow,\n} from \"./types.js\";\n\nexport interface LayoutOptions {\n readonly rowHeight?: number;\n readonly headerHeight?: number;\n readonly rowHeaderWidth?: number;\n readonly scrollPixelLimit?: number;\n readonly overscanRows?: number;\n readonly overscanColumns?: number;\n readonly rowEntries?: readonly PresentationAxisEntry[];\n readonly hiddenColumns?: readonly boolean[];\n readonly frozenRows?: number;\n readonly frozenColumns?: number;\n}\n\nexport function createTableLayout(\n metadata: Readonly<TableMetadata>,\n columnWidths: readonly number[],\n viewport: ViewportUpdate,\n options: LayoutOptions = {},\n): Readonly<TableLayout> {\n const rowHeight = positiveFinite(options.rowHeight ?? DEFAULT_ROW_HEIGHT, \"rowHeight\");\n const headerHeight = nonNegativeFinite(\n options.headerHeight ?? DEFAULT_HEADER_HEIGHT,\n \"headerHeight\",\n );\n const rowHeaderWidth = nonNegativeFinite(\n options.rowHeaderWidth ?? DEFAULT_ROW_HEADER_WIDTH,\n \"rowHeaderWidth\",\n );\n const scrollPixelLimit = positiveFinite(\n options.scrollPixelLimit ?? DEFAULT_SCROLL_PIXEL_LIMIT,\n \"scrollPixelLimit\",\n );\n const overscanRows = nonNegativeInteger(\n options.overscanRows ?? DEFAULT_OVERSCAN_ROWS,\n \"overscanRows\",\n );\n const overscanColumns = nonNegativeInteger(\n options.overscanColumns ?? DEFAULT_OVERSCAN_COLUMNS,\n \"overscanColumns\",\n );\n const width = nonNegativeFinite(viewport.width, \"viewport.width\");\n const height = nonNegativeFinite(viewport.height, \"viewport.height\");\n const devicePixelRatio = positiveFinite(\n viewport.devicePixelRatio ?? 1,\n \"viewport.devicePixelRatio\",\n );\n const columnCount = metadata.schema.columns.length;\n if (columnWidths.length !== columnCount) {\n throw invalidArgument(\n `columnWidths has ${columnWidths.length} entries; expected ${columnCount}`,\n );\n }\n for (let index = 0; index < columnWidths.length; index += 1) {\n positiveFinite(columnWidths[index]!, `columnWidths[${index}]`);\n }\n const hiddenColumns = options.hiddenColumns ?? [];\n if (hiddenColumns.length !== 0 && hiddenColumns.length !== columnCount) {\n throw invalidArgument(\n `hiddenColumns has ${hiddenColumns.length} entries; expected ${columnCount}`,\n );\n }\n const effectiveColumnWidths = Object.freeze(columnWidths.map(\n (width, index) => hiddenColumns[index] === true ? 0 : width,\n ));\n\n const rowCount = extentValue(metadata.extent.rows);\n const frozenRowCount = Math.min(\n rowCount,\n nonNegativeInteger(options.frozenRows ?? 0, \"frozenRows\"),\n );\n const frozenColumnCount = Math.min(\n columnCount,\n nonNegativeInteger(options.frozenColumns ?? 0, \"frozenColumns\"),\n );\n const bodyWidth = Math.max(0, width - rowHeaderWidth);\n const bodyHeight = Math.max(0, height - headerHeight);\n const prefixes = columnOffsets(effectiveColumnWidths);\n const rowGeometry = createSparseAxisGeometry(\n rowCount,\n rowHeight,\n options.rowEntries ?? [],\n );\n const logicalWidth = prefixes[prefixes.length - 1] ?? 0;\n const logicalHeight = rowGeometry.contentSize;\n const horizontal = createScrollAxis(\n logicalWidth,\n bodyWidth,\n viewport.scrollLeft,\n scrollPixelLimit,\n );\n const vertical = createScrollAxis(\n logicalHeight,\n bodyHeight,\n viewport.scrollTop,\n scrollPixelLimit,\n );\n const visibleRows = visibleRowRange(\n rowGeometry,\n vertical.logicalOffset,\n bodyHeight,\n );\n const visibleColumns = visibleColumnRange(\n prefixes,\n horizontal.logicalOffset,\n bodyWidth,\n );\n const overscanRowRange = expandRange(visibleRows, overscanRows, rowCount);\n const overscanColumnRange = expandRange(visibleColumns, overscanColumns, columnCount);\n const frozenRowExtent = axisPosition(rowGeometry, frozenRowCount);\n const frozenColumnExtent = prefixes[frozenColumnCount] ?? 0;\n const frozenRowRange = frozenRowCount === 0\n ? Object.freeze({ start: 0, end: 0 })\n : clampRangeEnd(\n visibleRowRange(rowGeometry, 0, Math.min(bodyHeight, frozenRowExtent)),\n frozenRowCount,\n );\n const frozenColumnRange = frozenColumnCount === 0\n ? Object.freeze({ start: 0, end: 0 })\n : clampRangeEnd(\n visibleColumnRange(prefixes, 0, Math.min(bodyWidth, frozenColumnExtent)),\n frozenColumnCount,\n );\n\n return Object.freeze({\n width,\n height,\n devicePixelRatio,\n rowHeight,\n headerHeight,\n rowHeaderWidth,\n bodyWidth,\n bodyHeight,\n rowCount,\n columnCount,\n rows: Object.freeze({ visible: visibleRows, overscan: overscanRowRange }),\n columns: Object.freeze({ visible: visibleColumns, overscan: overscanColumnRange }),\n visibleColumns: materializeColumns(\n metadata,\n effectiveColumnWidths,\n prefixes,\n visibleColumns,\n frozenColumnRange,\n rowHeaderWidth,\n horizontal.logicalOffset,\n frozenColumnCount,\n ),\n overscanColumns: materializeColumns(\n metadata,\n effectiveColumnWidths,\n prefixes,\n overscanColumnRange,\n frozenColumnRange,\n rowHeaderWidth,\n horizontal.logicalOffset,\n frozenColumnCount,\n ),\n visibleRows: materializeRows(\n rowGeometry,\n visibleRows,\n frozenRowRange,\n headerHeight,\n vertical.logicalOffset,\n frozenRowCount,\n ),\n overscanRows: materializeRows(\n rowGeometry,\n overscanRowRange,\n frozenRowRange,\n headerHeight,\n vertical.logicalOffset,\n frozenRowCount,\n ),\n effectiveColumnWidths,\n rowGeometry,\n frozenRowCount,\n frozenColumnCount,\n frozenRowExtent,\n frozenColumnExtent,\n frozenRowRange,\n frozenColumnRange,\n horizontal,\n vertical,\n spacerWidth: rowHeaderWidth + horizontal.physicalContentSize,\n spacerHeight: headerHeight + vertical.physicalContentSize,\n });\n}\n\nexport function createScrollAxis(\n logicalContentSize: number,\n logicalViewportSize: number,\n physicalOffset: number,\n pixelLimit = DEFAULT_SCROLL_PIXEL_LIMIT,\n): Readonly<ScrollAxisLayout> {\n nonNegativeFinite(logicalContentSize, \"logicalContentSize\");\n nonNegativeFinite(logicalViewportSize, \"logicalViewportSize\");\n positiveFinite(pixelLimit, \"pixelLimit\");\n const logicalMaxOffset = Math.max(0, logicalContentSize - logicalViewportSize);\n const largestUsableSize = Math.max(pixelLimit, logicalViewportSize + 1);\n const physicalContentSize = Math.min(logicalContentSize, largestUsableSize);\n const physicalMaxOffset = Math.max(0, physicalContentSize - logicalViewportSize);\n const normalizedPhysicalOffset = clampFinite(physicalOffset, 0, physicalMaxOffset);\n const compressed = logicalMaxOffset > physicalMaxOffset;\n const logicalOffset = physicalMaxOffset === 0\n ? 0\n : compressed\n ? (normalizedPhysicalOffset / physicalMaxOffset) * logicalMaxOffset\n : normalizedPhysicalOffset;\n return Object.freeze({\n logicalContentSize,\n logicalViewportSize,\n logicalOffset,\n logicalMaxOffset,\n physicalContentSize,\n physicalOffset: normalizedPhysicalOffset,\n physicalMaxOffset,\n compressed,\n });\n}\n\nexport function logicalToPhysicalOffset(axis: ScrollAxisLayout, logicalOffset: number): number {\n const normalized = clampFinite(logicalOffset, 0, axis.logicalMaxOffset);\n if (!axis.compressed) {\n return Math.min(normalized, axis.physicalMaxOffset);\n }\n return axis.logicalMaxOffset === 0\n ? 0\n : (normalized / axis.logicalMaxOffset) * axis.physicalMaxOffset;\n}\n\nexport function physicalToLogicalOffset(axis: ScrollAxisLayout, physicalOffset: number): number {\n const normalized = clampFinite(physicalOffset, 0, axis.physicalMaxOffset);\n if (!axis.compressed) {\n return Math.min(normalized, axis.logicalMaxOffset);\n }\n return axis.physicalMaxOffset === 0\n ? 0\n : (normalized / axis.physicalMaxOffset) * axis.logicalMaxOffset;\n}\n\nexport function hitTest(\n layout: TableLayout,\n x: number,\n y: number,\n _columnWidths: readonly number[],\n resizeHandleWidth = 6,\n): HitTestResult {\n if (!Number.isFinite(x) || !Number.isFinite(y) || x < 0 || y < 0\n || x >= layout.width || y >= layout.height) {\n return Object.freeze({ kind: \"outside\" });\n }\n const columnWidths = layout.effectiveColumnWidths;\n if (x < layout.rowHeaderWidth && y < layout.headerHeight) {\n return Object.freeze({ kind: \"corner\" });\n }\n if (y < layout.headerHeight) {\n const offsets = columnOffsets(columnWidths);\n const logicalX = x - layout.rowHeaderWidth + layout.horizontal.logicalOffset;\n const nextBoundary = lowerBound(offsets, logicalX);\n const handleWidth = Math.max(0, resizeHandleWidth);\n for (const boundaryIndex of [nextBoundary, nextBoundary - 1]) {\n if (boundaryIndex <= 0 || boundaryIndex >= offsets.length) {\n continue;\n }\n const boundaryX = layout.rowHeaderWidth\n + offsets[boundaryIndex]!\n - layout.horizontal.logicalOffset;\n if (Math.abs(x - boundaryX) <= handleWidth) {\n return Object.freeze({\n kind: \"column-resize\",\n columnIndex: boundaryIndex - 1,\n boundaryX,\n });\n }\n }\n const columnIndex = columnAtViewportX(layout, x, columnWidths);\n if (columnIndex === null) {\n return Object.freeze({ kind: \"outside\" });\n }\n return Object.freeze({ kind: \"column-header\", columnIndex });\n }\n const rowIndex = rowAtViewportY(layout, y);\n if (rowIndex === null) {\n return Object.freeze({ kind: \"outside\" });\n }\n if (x < layout.rowHeaderWidth) {\n return Object.freeze({ kind: \"row-header\", rowIndex });\n }\n const columnIndex = columnAtViewportX(layout, x, columnWidths);\n return columnIndex === null\n ? Object.freeze({ kind: \"outside\" })\n : Object.freeze({ kind: \"cell\", rowIndex, columnIndex });\n}\n\nexport function cellRect(\n layout: TableLayout,\n _columnWidths: readonly number[],\n rowIndex: number,\n columnIndex: number,\n): Readonly<PixelRect> {\n const columnWidths = layout.effectiveColumnWidths;\n const offsets = columnOffsets(columnWidths);\n const rowOffset = axisPosition(layout.rowGeometry, rowIndex);\n const columnOffset = offsets[columnIndex] ?? 0;\n return Object.freeze({\n x: layout.rowHeaderWidth + columnOffset\n - (columnIndex < layout.frozenColumnCount ? 0 : layout.horizontal.logicalOffset),\n y: layout.headerHeight + rowOffset\n - (rowIndex < layout.frozenRowCount ? 0 : layout.vertical.logicalOffset),\n width: columnWidths[columnIndex] ?? 0,\n height: axisSize(layout.rowGeometry, rowIndex),\n });\n}\n\nexport function columnHeaderRect(\n layout: TableLayout,\n _columnWidths: readonly number[],\n columnIndex: number,\n): Readonly<PixelRect> {\n const columnWidths = layout.effectiveColumnWidths;\n const offsets = columnOffsets(columnWidths);\n return Object.freeze({\n x: layout.rowHeaderWidth + offsets[columnIndex]!\n - (columnIndex < layout.frozenColumnCount ? 0 : layout.horizontal.logicalOffset),\n y: 0,\n width: columnWidths[columnIndex] ?? 0,\n height: layout.headerHeight,\n });\n}\n\nexport function rowHeaderRect(layout: TableLayout, rowIndex: number): Readonly<PixelRect> {\n const rowOffset = axisPosition(layout.rowGeometry, rowIndex);\n return Object.freeze({\n x: 0,\n y: layout.headerHeight + rowOffset\n - (rowIndex < layout.frozenRowCount ? 0 : layout.vertical.logicalOffset),\n width: layout.rowHeaderWidth,\n height: axisSize(layout.rowGeometry, rowIndex),\n });\n}\n\nexport function selectionRect(\n layout: TableLayout,\n _columnWidths: readonly number[],\n range: GridRange,\n): Readonly<PixelRect> | null {\n const columnWidths = layout.effectiveColumnWidths;\n if (range.rowStart >= range.rowEnd || range.columnStart >= range.columnEnd) {\n return null;\n }\n const offsets = columnOffsets(columnWidths);\n const columnStart = clampInteger(range.columnStart, 0, columnWidths.length);\n const columnEnd = clampInteger(range.columnEnd, columnStart, columnWidths.length);\n const rowStart = clampInteger(range.rowStart, 0, layout.rowCount);\n const rowEnd = clampInteger(range.rowEnd, rowStart, layout.rowCount);\n if (columnStart === columnEnd || rowStart === rowEnd) {\n return null;\n }\n const frozenColumns = columnEnd <= layout.frozenColumnCount;\n const frozenRows = rowEnd <= layout.frozenRowCount;\n const rowStartOffset = axisPosition(layout.rowGeometry, rowStart);\n const rowEndOffset = axisPosition(layout.rowGeometry, rowEnd);\n return Object.freeze({\n x: layout.rowHeaderWidth + offsets[columnStart]!\n - (frozenColumns ? 0 : layout.horizontal.logicalOffset),\n y: layout.headerHeight + rowStartOffset\n - (frozenRows ? 0 : layout.vertical.logicalOffset),\n width: offsets[columnEnd]! - offsets[columnStart]!,\n height: rowEndOffset - rowStartOffset,\n });\n}\n\nexport function columnOffsets(columnWidths: readonly number[]): readonly number[] {\n const offsets = new Array<number>(columnWidths.length + 1);\n offsets[0] = 0;\n for (let index = 0; index < columnWidths.length; index += 1) {\n offsets[index + 1] = offsets[index]! + (columnWidths[index] ?? DEFAULT_COLUMN_WIDTH);\n }\n return offsets;\n}\n\nexport function extentValue(extent: TableMetadata[\"extent\"][\"rows\"]): number {\n return extent.kind === \"unknown\" ? 0 : extent.value;\n}\n\n/** Builds a compact sparse axis without allocating one entry per worksheet row. */\nexport function createSparseAxisGeometry(\n count: number,\n defaultSize: number,\n entries: readonly PresentationAxisEntry[] = [],\n): Readonly<SparseAxisGeometry> {\n nonNegativeInteger(count, \"axis count\");\n positiveFinite(defaultSize, \"axis defaultSize\");\n const byIndex = new Map<number, number>();\n for (const entry of entries) {\n if (!entry || !Number.isSafeInteger(entry.index) || entry.index < 0 || entry.index >= count) {\n continue;\n }\n if (entry.hidden === true) {\n byIndex.set(entry.index, 0);\n continue;\n }\n if (entry.size !== undefined) {\n if (!Number.isFinite(entry.size) || entry.size < 0) {\n continue;\n }\n byIndex.set(entry.index, entry.size);\n }\n }\n let cumulativeDelta = 0;\n const overrides = [...byIndex.entries()]\n .sort(([left], [right]) => left - right)\n .map(([index, size]) => {\n cumulativeDelta += size - defaultSize;\n return Object.freeze({ index, size, cumulativeDelta });\n });\n const contentSize = count * defaultSize + cumulativeDelta;\n return Object.freeze({\n count,\n defaultSize,\n contentSize: Math.max(0, contentSize),\n overrides: Object.freeze(overrides),\n });\n}\n\n/** Logical offset at the start of an axis index. */\nexport function axisPosition(geometry: SparseAxisGeometry, index: number): number {\n const normalized = clampInteger(index, 0, geometry.count);\n const overrideIndex = lowerBoundOverride(geometry.overrides, normalized);\n const delta = overrideIndex === 0 ? 0 : geometry.overrides[overrideIndex - 1]!.cumulativeDelta;\n return normalized * geometry.defaultSize + delta;\n}\n\n/** Effective axis extent, zero when a row/column is hidden. */\nexport function axisSize(geometry: SparseAxisGeometry, index: number): number {\n if (!Number.isSafeInteger(index) || index < 0 || index >= geometry.count) {\n return 0;\n }\n const match = sparseOverrideAt(geometry, index);\n return match?.size ?? geometry.defaultSize;\n}\n\n/** Finds the visible axis index containing a logical pixel offset. */\nexport function axisIndexAtOffset(geometry: SparseAxisGeometry, offset: number): number | null {\n if (!Number.isFinite(offset) || offset < 0 || offset >= geometry.contentSize || geometry.count === 0) {\n return null;\n }\n let low = 0;\n let high = geometry.count;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (axisPosition(geometry, middle + 1) <= offset) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n for (let index = low; index < geometry.count; index += 1) {\n const size = axisSize(geometry, index);\n const start = axisPosition(geometry, index);\n if (size > 0 && offset >= start && offset < start + size) {\n return index;\n }\n if (start > offset) {\n return null;\n }\n }\n return null;\n}\n\nexport function nextVisibleAxisIndex(\n geometry: SparseAxisGeometry,\n from: number,\n direction: -1 | 1 = 1,\n): number | null {\n for (\n let index = clampInteger(from, 0, Math.max(0, geometry.count - 1));\n index >= 0 && index < geometry.count;\n index += direction\n ) {\n if (axisSize(geometry, index) > 0) {\n return index;\n }\n }\n return null;\n}\n\nfunction sparseOverrideAt(\n geometry: SparseAxisGeometry,\n index: number,\n): Readonly<SparseAxisGeometry[\"overrides\"][number]> | undefined {\n const low = lowerBoundOverride(geometry.overrides, index);\n const candidate = geometry.overrides[low];\n return candidate?.index === index ? candidate : undefined;\n}\n\nfunction lowerBoundOverride(\n entries: readonly Readonly<SparseAxisGeometry[\"overrides\"][number]>[],\n target: number,\n): number {\n let low = 0;\n let high = entries.length;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (entries[middle]!.index < target) low = middle + 1;\n else high = middle;\n }\n return low;\n}\n\nfunction clampRangeEnd(range: IndexRange, end: number): Readonly<IndexRange> {\n return Object.freeze({\n start: Math.min(range.start, end),\n end: Math.min(range.end, end),\n });\n}\n\nfunction visibleRowRange(\n geometry: SparseAxisGeometry,\n scrollTop: number,\n viewportHeight: number,\n): Readonly<IndexRange> {\n if (geometry.count === 0 || viewportHeight <= 0 || geometry.contentSize <= 0) {\n return Object.freeze({ start: 0, end: 0 });\n }\n const start = axisIndexAtOffset(geometry, scrollTop);\n if (start === null) {\n return Object.freeze({ start: geometry.count, end: geometry.count });\n }\n const last = axisIndexAtOffset(\n geometry,\n Math.max(\n scrollTop,\n Math.min(geometry.contentSize, scrollTop + viewportHeight)\n - Math.max(1e-7, Math.abs(scrollTop + viewportHeight) * Number.EPSILON * 4),\n ),\n );\n return Object.freeze({\n start,\n end: last === null ? start + 1 : Math.min(geometry.count, last + 1),\n });\n}\n\nfunction visibleColumnRange(\n offsets: readonly number[],\n scrollLeft: number,\n viewportWidth: number,\n): Readonly<IndexRange> {\n const count = Math.max(0, offsets.length - 1);\n if (count === 0 || viewportWidth <= 0) {\n return Object.freeze({ start: 0, end: 0 });\n }\n const start = columnAtLogicalX(offsets, scrollLeft) ?? count;\n const end = Math.min(count, lowerBound(offsets, scrollLeft + viewportWidth));\n return Object.freeze({ start, end: Math.max(start, end) });\n}\n\nfunction expandRange(range: IndexRange, amount: number, limit: number): Readonly<IndexRange> {\n return Object.freeze({\n start: Math.max(0, range.start - amount),\n end: Math.min(limit, range.end + amount),\n });\n}\n\nfunction materializeColumns(\n metadata: Readonly<TableMetadata>,\n widths: readonly number[],\n offsets: readonly number[],\n range: IndexRange,\n frozenRange: IndexRange,\n rowHeaderWidth: number,\n scrollLeft: number,\n frozenColumnCount: number,\n): readonly Readonly<VisibleColumn>[] {\n const indexes = rangeIndexes(range, frozenRange);\n const columns: VisibleColumn[] = [];\n for (const index of indexes) {\n const column = metadata.schema.columns[index]!;\n const width = widths[index] ?? 0;\n if (width <= 0) {\n continue;\n }\n const frozen = index < frozenColumnCount;\n columns.push(Object.freeze({\n index,\n id: column.id,\n name: column.name,\n x: rowHeaderWidth + offsets[index]! - (frozen ? 0 : scrollLeft),\n width,\n frozen,\n }));\n }\n return Object.freeze(columns);\n}\n\nfunction materializeRows(\n geometry: SparseAxisGeometry,\n range: IndexRange,\n frozenRange: IndexRange,\n headerHeight: number,\n scrollTop: number,\n frozenRowCount: number,\n): readonly Readonly<VisibleRow>[] {\n const rows: VisibleRow[] = [];\n for (const index of rangeIndexes(range, frozenRange)) {\n const height = axisSize(geometry, index);\n if (height <= 0) {\n continue;\n }\n const frozen = index < frozenRowCount;\n rows.push(Object.freeze({\n index,\n y: headerHeight + axisPosition(geometry, index) - (frozen ? 0 : scrollTop),\n height,\n frozen,\n }));\n }\n return Object.freeze(rows);\n}\n\nfunction rangeIndexes(primary: IndexRange, frozen: IndexRange): readonly number[] {\n const indexes = new Set<number>();\n for (let index = primary.start; index < primary.end; index += 1) {\n indexes.add(index);\n }\n for (let index = frozen.start; index < frozen.end; index += 1) {\n indexes.add(index);\n }\n return Object.freeze([...indexes].sort((left, right) => left - right));\n}\n\nfunction columnAtViewportX(\n layout: TableLayout,\n x: number,\n columnWidths: readonly number[],\n): number | null {\n if (x < layout.rowHeaderWidth) {\n return null;\n }\n const bodyX = x - layout.rowHeaderWidth;\n if (bodyX < Math.min(layout.bodyWidth, layout.frozenColumnExtent)) {\n const frozen = columnAtLogicalX(columnOffsets(columnWidths), bodyX);\n if (frozen !== null && frozen < layout.frozenColumnCount) {\n return frozen;\n }\n }\n return columnAtLogicalX(\n columnOffsets(columnWidths),\n bodyX + layout.horizontal.logicalOffset,\n );\n}\n\nfunction columnAtLogicalX(offsets: readonly number[], x: number): number | null {\n const count = Math.max(0, offsets.length - 1);\n if (x < 0 || count === 0 || x >= offsets[count]!) {\n return null;\n }\n let low = 0;\n let high = count;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (offsets[middle + 1]! <= x) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n return low;\n}\n\nfunction rowAtViewportY(layout: TableLayout, y: number): number | null {\n const bodyY = y - layout.headerHeight;\n if (bodyY < Math.min(layout.bodyHeight, layout.frozenRowExtent)) {\n const frozen = axisIndexAtOffset(layout.rowGeometry, bodyY);\n if (frozen !== null && frozen < layout.frozenRowCount) {\n return frozen;\n }\n }\n return axisIndexAtOffset(\n layout.rowGeometry,\n bodyY + layout.vertical.logicalOffset,\n );\n}\n\nfunction lowerBound(values: readonly number[], target: number): number {\n let low = 0;\n let high = values.length;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (values[middle]! < target) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n return low;\n}\n\nfunction positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) {\n throw invalidArgument(`${name} must be a positive finite number`);\n }\n return value;\n}\n\nfunction nonNegativeFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw invalidArgument(`${name} must be a non-negative finite number`);\n }\n return value;\n}\n\nfunction nonNegativeInteger(value: number, name: string): number {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw invalidArgument(`${name} must be a non-negative safe integer`);\n }\n return value;\n}\n\nfunction clampFinite(value: number, minimum: number, maximum: number): number {\n if (!Number.isFinite(value)) {\n return minimum;\n }\n return Math.min(maximum, Math.max(minimum, value));\n}\n\nfunction clampInteger(value: number, minimum: number, maximum: number): number {\n if (!Number.isFinite(value)) {\n return minimum;\n }\n return Math.min(maximum, Math.max(minimum, Math.trunc(value)));\n}\n", "import type { TableHandle, TableEvent, Unsubscribe } from \"../client.js\";\nimport { TabularkError, closedError, invalidArgument } from \"../errors.js\";\nimport {\n MAX_RANGE_CELLS,\n type MergedCellRegion,\n type PresentationAxisEntry,\n type RangeRequest,\n type SpreadsheetPresentation,\n type TableBatch,\n} from \"../model.js\";\nimport {\n axisPosition,\n axisSize,\n cellRect,\n columnOffsets,\n createTableLayout,\n extentValue,\n hitTest,\n logicalToPhysicalOffset,\n nextVisibleAxisIndex,\n selectionRect,\n type LayoutOptions,\n} from \"./layout.js\";\nimport { assertCellPosition, clampCell, createSelection, moveCell } from \"./selection.js\";\nimport {\n DEFAULT_COLUMN_WIDTH,\n DEFAULT_MAX_COLUMN_WIDTH,\n DEFAULT_MIN_COLUMN_WIDTH,\n type CellLoadState,\n type CellPosition,\n type GridRange,\n type HitTestResult,\n type MoveActiveCellOptions,\n type NavigationCommand,\n type PixelRect,\n type SetActiveCellOptions,\n type TableControllerOptions,\n type TableSelection,\n type TableViewSnapshot,\n type ViewportUpdate,\n} from \"./types.js\";\n\nconst DEFAULT_MAX_WINDOW_CELLS = 100_000;\n\ninterface LoadedWindow {\n readonly range: Readonly<GridRange>;\n readonly rows: readonly (readonly (string | null)[])[];\n}\n\ninterface NormalizedOptions extends LayoutOptions {\n readonly columnWidth: number;\n readonly minColumnWidth: number;\n readonly maxColumnWidth: number;\n readonly columnWidths: Readonly<Record<string, number>>;\n readonly maxWindowCells: number;\n}\n\nexport interface TableViewController {\n readonly metadata: TableHandle[\"metadata\"];\n readonly columnWidths: readonly number[];\n readonly minColumnWidth: number;\n readonly maxColumnWidth: number;\n getSnapshot(): Readonly<TableViewSnapshot>;\n subscribe(listener: (snapshot: Readonly<TableViewSnapshot>) => void): Unsubscribe;\n updateViewport(viewport: ViewportUpdate): void;\n setActiveCell(cell: CellPosition, options?: SetActiveCellOptions): void;\n extendSelection(cell: CellPosition, options?: Omit<SetActiveCellOptions, \"extendSelection\">): void;\n setSelection(anchor: CellPosition, focus?: CellPosition): void;\n clearSelection(): void;\n moveActive(command: NavigationCommand, options?: MoveActiveCellOptions): void;\n ensureCellVisible(cell: CellPosition): void;\n ensureColumnVisible(columnIndex: number): void;\n resizeColumn(columnIndex: number, width: number): void;\n autosizeColumn(columnIndex: number, measuredWidth: number): void;\n /** Applies validated static worksheet geometry in one controller generation. */\n applySpreadsheetPresentation(presentation: SpreadsheetPresentation): void;\n /** Updates merge interaction geometry for the currently loaded presentation window. */\n setMergedCells(regions: readonly MergedCellRegion[]): void;\n hitTest(x: number, y: number, resizeHandleWidth?: number): HitTestResult;\n cellRect(cell: CellPosition): Readonly<PixelRect>;\n selectionRect(selection?: TableSelection | null): Readonly<PixelRect> | null;\n getCell(rowIndex: number, columnIndex: number): CellLoadState;\n copySelection(options?: { readonly signal?: AbortSignal }): Promise<string>;\n dispose(): void;\n}\n\nclass Controller implements TableViewController {\n readonly #table: TableHandle;\n readonly #options: NormalizedOptions;\n readonly #listeners = new Set<(snapshot: Readonly<TableViewSnapshot>) => void>();\n readonly #unsubscribe: Unsubscribe;\n #viewport: Required<ViewportUpdate> = {\n width: 0,\n height: 0,\n scrollLeft: 0,\n scrollTop: 0,\n devicePixelRatio: 1,\n };\n #columnWidths: number[];\n #hiddenColumns: boolean[];\n #presentationRows: readonly PresentationAxisEntry[] = [];\n #frozenRows = 0;\n #frozenColumns = 0;\n #mergedCells: readonly MergedCellRegion[] = [];\n #snapshot: Readonly<TableViewSnapshot>;\n #activeCell: Readonly<CellPosition> | null = null;\n #selection: Readonly<TableSelection> | null = null;\n #windows: readonly LoadedWindow[] = [];\n #loadingRanges: readonly Readonly<GridRange>[] = [];\n #requestAbort: AbortController | null = null;\n #generation = 0;\n #loadQueued = false;\n #disposed = false;\n #tableClosed = false;\n\n constructor(table: TableHandle, options: TableControllerOptions) {\n this.#table = table;\n this.#options = normalizeOptions(options);\n this.#columnWidths = initialColumnWidths(table.metadata, this.#options);\n this.#hiddenColumns = Array.from({ length: this.#columnWidths.length }, () => false);\n const layout = createTableLayout(\n table.metadata,\n this.#columnWidths,\n this.#viewport,\n this.#layoutOptions(),\n );\n this.#snapshot = Object.freeze({\n generation: this.#generation,\n status: \"loading\",\n metadata: table.metadata,\n layout,\n activeCell: null,\n selection: null,\n });\n this.#unsubscribe = table.subscribe((event) => this.#handleTableEvent(event));\n }\n\n get metadata(): TableHandle[\"metadata\"] {\n return this.#table.metadata;\n }\n\n get columnWidths(): readonly number[] {\n return Object.freeze([...this.#columnWidths]);\n }\n\n get minColumnWidth(): number {\n return this.#options.minColumnWidth;\n }\n\n get maxColumnWidth(): number {\n return this.#options.maxColumnWidth;\n }\n\n getSnapshot(): Readonly<TableViewSnapshot> {\n return this.#snapshot;\n }\n\n subscribe(listener: (snapshot: Readonly<TableViewSnapshot>) => void): Unsubscribe {\n this.#assertOpen();\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n updateViewport(viewport: ViewportUpdate): void {\n this.#assertOpen();\n const normalized = normalizeViewport(viewport);\n if (sameViewport(normalized, this.#viewport)) {\n return;\n }\n this.#viewport = normalized;\n this.#advanceGeneration();\n }\n\n setActiveCell(cell: CellPosition, options: SetActiveCellOptions = {}): void {\n this.#assertOpen();\n assertCellPosition(cell, \"cell\");\n const clamped = clampCell(\n cell,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n if (clamped === null) {\n return;\n }\n const next = this.#visibleCell(this.#mergeAnchor(clamped), 1, 1);\n if (next === null) return;\n const anchor = options.extendSelection && this.#selection !== null\n ? this.#selection.anchor\n : next;\n this.#activeCell = next;\n this.#selection = createMergedSelection(anchor, next, this.#mergedCells);\n if (options.scrollIntoView !== false && this.#scrollCellIntoView(next)) {\n this.#advanceGeneration();\n return;\n }\n this.#publish();\n }\n\n extendSelection(\n cell: CellPosition,\n options: Omit<SetActiveCellOptions, \"extendSelection\"> = {},\n ): void {\n this.setActiveCell(cell, { ...options, extendSelection: true });\n }\n\n setSelection(anchor: CellPosition, focus: CellPosition = anchor): void {\n this.#assertOpen();\n assertCellPosition(anchor, \"anchor\");\n assertCellPosition(focus, \"focus\");\n const rawAnchor = clampCell(\n anchor,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n const rawFocus = clampCell(\n focus,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n if (rawAnchor === null || rawFocus === null) {\n this.clearSelection();\n return;\n }\n const clampedAnchor = this.#visibleCell(this.#mergeAnchor(rawAnchor), 1, 1);\n const clampedFocus = this.#visibleCell(this.#mergeAnchor(rawFocus), 1, 1);\n if (clampedAnchor === null || clampedFocus === null) {\n this.clearSelection();\n return;\n }\n this.#activeCell = clampedFocus;\n this.#selection = createMergedSelection(clampedAnchor, clampedFocus, this.#mergedCells);\n this.#publish();\n }\n\n clearSelection(): void {\n this.#assertOpen();\n if (this.#selection === null) {\n return;\n }\n this.#selection = null;\n this.#publish();\n }\n\n moveActive(command: NavigationCommand, options: MoveActiveCellOptions = {}): void {\n this.#assertOpen();\n const current = this.#activeCell ?? { rowIndex: 0, columnIndex: 0 };\n const origin = navigationOrigin(current, command, this.#mergedCells);\n const moved = moveCell(\n origin,\n command,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n Math.max(1, this.#snapshot.layout.visibleRows.filter((row) => !row.frozen).length),\n );\n const [rowDirection, columnDirection] = navigationDirections(command);\n const next = moved === null\n ? null\n : this.#visibleCell(this.#mergeAnchor(moved), rowDirection, columnDirection);\n if (next !== null) {\n this.setActiveCell(next, options);\n }\n }\n\n ensureCellVisible(cell: CellPosition): void {\n this.#assertOpen();\n assertCellPosition(cell, \"cell\");\n const next = clampCell(\n cell,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n if (next !== null && this.#scrollCellIntoView(next)) {\n this.#advanceGeneration();\n }\n }\n\n ensureColumnVisible(columnIndex: number): void {\n this.#assertOpen();\n assertColumnIndex(columnIndex, this.#columnWidths.length);\n if (this.#scrollColumnIntoView(columnIndex)) {\n this.#advanceGeneration();\n }\n }\n\n resizeColumn(columnIndex: number, width: number): void {\n this.#assertOpen();\n assertColumnIndex(columnIndex, this.#columnWidths.length);\n const normalized = clampWidth(width, this.#options);\n if (this.#columnWidths[columnIndex] === normalized) {\n return;\n }\n this.#columnWidths[columnIndex] = normalized;\n this.#advanceGeneration();\n }\n\n autosizeColumn(columnIndex: number, measuredWidth: number): void {\n this.resizeColumn(columnIndex, measuredWidth);\n }\n\n applySpreadsheetPresentation(presentation: SpreadsheetPresentation): void {\n this.#assertOpen();\n if (presentation.kind !== \"spreadsheet-v1\" || presentation.tableId !== this.metadata.tableId) {\n throw invalidArgument(\"presentation must belong to the controller table\");\n }\n const nextWidths = [...this.#columnWidths];\n const hiddenColumns = Array.from({ length: nextWidths.length }, () => false);\n for (const entry of presentation.columns) {\n if (!Number.isSafeInteger(entry.index) || entry.index < 0 || entry.index >= nextWidths.length) {\n continue;\n }\n hiddenColumns[entry.index] = entry.hidden === true;\n if (entry.size !== undefined && Number.isFinite(entry.size) && entry.size > 0) {\n nextWidths[entry.index] = clampWidth(entry.size, this.#options);\n }\n }\n this.#columnWidths = nextWidths;\n this.#hiddenColumns = hiddenColumns;\n this.#presentationRows = Object.freeze(presentation.rows.map((entry) => Object.freeze({ ...entry })));\n this.#frozenRows = presentation.frozenRows;\n this.#frozenColumns = presentation.frozenColumns;\n this.#mergedCells = [];\n this.#advanceGeneration();\n this.#normalizeInteractionForPresentation();\n this.#publish();\n }\n\n setMergedCells(regions: readonly MergedCellRegion[]): void {\n this.#assertOpen();\n const normalized = normalizeMergedCells(\n regions,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n if (sameMergedCells(normalized, this.#mergedCells)) {\n return;\n }\n this.#mergedCells = normalized;\n this.#normalizeInteractionForPresentation();\n // A merge may intersect the viewport while its value anchor is far\n // outside the ordinary visible/overscan windows. Start a new generation\n // so those anchors are requested along with the visible cells.\n this.#advanceGeneration();\n }\n\n hitTest(x: number, y: number, resizeHandleWidth?: number): HitTestResult {\n const result = hitTest(\n this.#snapshot.layout,\n x,\n y,\n this.#columnWidths,\n resizeHandleWidth,\n );\n if (result.kind !== \"cell\") {\n return result;\n }\n const anchor = this.#mergeAnchor(result);\n return Object.freeze({ kind: \"cell\", ...anchor });\n }\n\n cellRect(cell: CellPosition): Readonly<PixelRect> {\n assertCellPosition(cell, \"cell\");\n if (cell.rowIndex >= this.#snapshot.layout.rowCount\n || cell.columnIndex >= this.#snapshot.layout.columnCount) {\n throw invalidArgument(\"cell must be inside the current table extent\");\n }\n return cellRect(\n this.#snapshot.layout,\n this.#columnWidths,\n cell.rowIndex,\n cell.columnIndex,\n );\n }\n\n selectionRect(selection: TableSelection | null = this.#selection): Readonly<PixelRect> | null {\n return selection === null\n ? null\n : selectionRect(this.#snapshot.layout, this.#columnWidths, selection.range);\n }\n\n getCell(rowIndex: number, columnIndex: number): CellLoadState {\n if (!isValidCell(rowIndex, columnIndex, this.#snapshot.layout.rowCount, this.#columnWidths.length)) {\n return Object.freeze({ status: \"unavailable\" });\n }\n for (const window of this.#windows) {\n if (rangeContains(window.range, rowIndex, columnIndex)) {\n return Object.freeze({\n status: \"loaded\",\n value: window.rows[rowIndex - window.range.rowStart]![columnIndex - window.range.columnStart]!,\n });\n }\n }\n for (const range of this.#loadingRanges) {\n if (rangeContains(range, rowIndex, columnIndex)) {\n return Object.freeze({ status: \"loading\" });\n }\n }\n return Object.freeze({ status: \"unavailable\" });\n }\n\n async copySelection(options: { readonly signal?: AbortSignal } = {}): Promise<string> {\n this.#assertOpen();\n const selection = this.#selection;\n if (selection === null) {\n return \"\";\n }\n const request = gridRangeToRequest(selection.range);\n assertWindowCellLimit(request, MAX_RANGE_CELLS, \"selection\");\n const batch = await this.#table.readRange(\n request,\n options.signal ? { signal: options.signal } : {},\n );\n return rowsToTsv(batchRows(batch));\n }\n\n dispose(): void {\n if (this.#disposed) {\n return;\n }\n this.#disposed = true;\n this.#requestAbort?.abort();\n this.#requestAbort = null;\n this.#unsubscribe();\n this.#listeners.clear();\n this.#windows = [];\n this.#loadingRanges = [];\n this.#snapshot = Object.freeze({\n ...this.#snapshot,\n status: \"closed\",\n activeCell: null,\n selection: null,\n });\n }\n\n #advanceGeneration(): void {\n this.#generation += 1;\n this.#requestAbort?.abort();\n this.#requestAbort = null;\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"loading\");\n this.#queueLoad();\n }\n\n #queueLoad(): void {\n if (this.#loadQueued || this.#disposed) {\n return;\n }\n this.#loadQueued = true;\n queueMicrotask(() => {\n this.#loadQueued = false;\n if (!this.#disposed) {\n void this.#loadGeneration(this.#generation);\n }\n });\n }\n\n async #loadGeneration(generation: number): Promise<void> {\n let visible: readonly Readonly<GridRange>[];\n let overscan: readonly Readonly<GridRange>[];\n try {\n ({ visible, overscan } = layoutRanges(\n this.#snapshot.layout,\n this.#options.maxWindowCells,\n this.#mergedCells,\n ));\n } catch (error) {\n if (!this.#disposed && generation === this.#generation) {\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"error\", error);\n }\n return;\n }\n if (visible.length === 0) {\n this.#windows = [];\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"ready\");\n return;\n }\n const abort = new AbortController();\n this.#requestAbort = abort;\n const ranges = Object.freeze([\n ...visible,\n ...overscan.filter((candidate) => !visible.some(\n (required) => rangeContainsRange(candidate, required) && sameGridRange(candidate, required),\n )),\n ]);\n this.#loadingRanges = Object.freeze(ranges);\n this.#publish();\n let loaded: LoadedWindow[] = [];\n try {\n for (let index = 0; index < ranges.length; index += 1) {\n const range = ranges[index]!;\n const batch = await this.#table.readRange(\n gridRangeToRequest(range),\n { signal: abort.signal },\n );\n if (this.#disposed || generation !== this.#generation || abort.signal.aborted) {\n return;\n }\n const returnedRange = batchGridRange(batch);\n if (returnedRange.rowStart < returnedRange.rowEnd\n && returnedRange.columnStart < returnedRange.columnEnd) {\n const window = Object.freeze({ range: returnedRange, rows: batchRows(batch) });\n loaded = [window, ...loaded.filter(\n (candidate) => !rangeContainsRange(returnedRange, candidate.range),\n )];\n }\n this.#windows = Object.freeze([...loaded]);\n this.#loadingRanges = Object.freeze(ranges.slice(index + 1));\n this.#rebuildSnapshot(\"ready\");\n }\n } catch (error) {\n if (this.#disposed || generation !== this.#generation || abort.signal.aborted\n || (error instanceof TabularkError && error.code === \"CANCELLED\")) {\n return;\n }\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"error\", error);\n } finally {\n if (this.#requestAbort === abort) {\n this.#requestAbort = null;\n }\n }\n }\n\n #scrollCellIntoView(cell: CellPosition): boolean {\n const layout = this.#snapshot.layout;\n const offsets = columnOffsets(layout.effectiveColumnWidths);\n const cellLeft = offsets[cell.columnIndex]!;\n const cellRight = offsets[cell.columnIndex + 1]!;\n const cellTop = axisPosition(layout.rowGeometry, cell.rowIndex);\n const cellBottom = cellTop + axisSize(layout.rowGeometry, cell.rowIndex);\n const logicalLeft = cell.columnIndex < layout.frozenColumnCount\n ? layout.horizontal.logicalOffset\n : revealOffset(\n layout.horizontal.logicalOffset,\n layout.bodyWidth,\n cellLeft,\n cellRight,\n layout.horizontal.logicalMaxOffset,\n );\n const logicalTop = cell.rowIndex < layout.frozenRowCount\n ? layout.vertical.logicalOffset\n : revealOffset(\n layout.vertical.logicalOffset,\n layout.bodyHeight,\n cellTop,\n cellBottom,\n layout.vertical.logicalMaxOffset,\n );\n const scrollLeft = logicalToPhysicalOffset(layout.horizontal, logicalLeft);\n const scrollTop = logicalToPhysicalOffset(layout.vertical, logicalTop);\n if (scrollLeft === this.#viewport.scrollLeft && scrollTop === this.#viewport.scrollTop) {\n return false;\n }\n this.#viewport = Object.freeze({ ...this.#viewport, scrollLeft, scrollTop });\n return true;\n }\n\n #scrollColumnIntoView(columnIndex: number): boolean {\n const layout = this.#snapshot.layout;\n const offsets = columnOffsets(layout.effectiveColumnWidths);\n const logicalLeft = columnIndex < layout.frozenColumnCount\n ? layout.horizontal.logicalOffset\n : revealOffset(\n layout.horizontal.logicalOffset,\n layout.bodyWidth,\n offsets[columnIndex]!,\n offsets[columnIndex + 1]!,\n layout.horizontal.logicalMaxOffset,\n );\n const scrollLeft = logicalToPhysicalOffset(layout.horizontal, logicalLeft);\n if (scrollLeft === this.#viewport.scrollLeft) {\n return false;\n }\n this.#viewport = Object.freeze({ ...this.#viewport, scrollLeft });\n return true;\n }\n\n #handleTableEvent(event: TableEvent): void {\n if (this.#disposed) {\n return;\n }\n switch (event.type) {\n case \"metadata\": {\n const previousMetadata = this.#snapshot.metadata;\n this.#columnWidths = reconcileColumnWidths(\n previousMetadata,\n event.metadata,\n this.#columnWidths,\n this.#options,\n );\n const hiddenById = new Map(previousMetadata.schema.columns.map(\n (column, index) => [column.id, this.#hiddenColumns[index] === true] as const,\n ));\n this.#hiddenColumns = event.metadata.schema.columns.map(\n (column) => hiddenById.get(column.id) === true,\n );\n this.#advanceGeneration();\n this.#clampInteraction();\n this.#publish();\n break;\n }\n case \"runtimeError\":\n this.#requestAbort?.abort();\n this.#requestAbort = null;\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"error\", event.error);\n break;\n case \"closed\":\n this.#tableClosed = true;\n this.#requestAbort?.abort();\n this.#requestAbort = null;\n this.#loadingRanges = [];\n if (this.#snapshot.status !== \"error\") {\n this.#rebuildSnapshot(\"closed\");\n }\n break;\n case \"warning\":\n break;\n }\n }\n\n #clampInteraction(): void {\n if (this.#activeCell === null) {\n return;\n }\n const rowCount = extentValue(this.#table.metadata.extent.rows);\n const columnCount = this.#table.metadata.schema.columns.length;\n const rawActive = clampCell(this.#activeCell, rowCount, columnCount);\n const nextActive = rawActive === null\n ? null\n : this.#visibleCell(this.#mergeAnchor(rawActive), 1, 1);\n if (nextActive === null) {\n this.#activeCell = null;\n this.#selection = null;\n return;\n }\n this.#activeCell = nextActive;\n if (this.#selection !== null) {\n const rawAnchor = clampCell(this.#selection.anchor, rowCount, columnCount)!;\n const rawFocus = clampCell(this.#selection.focus, rowCount, columnCount)!;\n const anchor = this.#visibleCell(this.#mergeAnchor(rawAnchor), 1, 1);\n const focus = this.#visibleCell(this.#mergeAnchor(rawFocus), 1, 1);\n this.#selection = anchor === null || focus === null\n ? null\n : createMergedSelection(anchor, focus, this.#mergedCells);\n }\n }\n\n #layoutOptions(): LayoutOptions {\n return Object.freeze({\n ...this.#options,\n rowEntries: this.#presentationRows,\n hiddenColumns: this.#hiddenColumns,\n frozenRows: this.#frozenRows,\n frozenColumns: this.#frozenColumns,\n });\n }\n\n #mergeAnchor(cell: CellPosition): Readonly<CellPosition> {\n const region = mergeContaining(this.#mergedCells, cell);\n return region === undefined\n ? Object.freeze({ rowIndex: cell.rowIndex, columnIndex: cell.columnIndex })\n : Object.freeze({ rowIndex: region.rowStart, columnIndex: region.columnStart });\n }\n\n #visibleCell(\n cell: CellPosition,\n rowDirection: -1 | 1,\n columnDirection: -1 | 1,\n ): Readonly<CellPosition> | null {\n const layout = this.#snapshot.layout;\n const row = nextVisibleAxisIndex(layout.rowGeometry, cell.rowIndex, rowDirection)\n ?? nextVisibleAxisIndex(layout.rowGeometry, cell.rowIndex, rowDirection === 1 ? -1 : 1);\n if (row === null) return null;\n const column = nextVisibleColumn(\n layout.effectiveColumnWidths,\n cell.columnIndex,\n columnDirection,\n ) ?? nextVisibleColumn(\n layout.effectiveColumnWidths,\n cell.columnIndex,\n columnDirection === 1 ? -1 : 1,\n );\n return column === null ? null : Object.freeze({ rowIndex: row, columnIndex: column });\n }\n\n #normalizeInteractionForPresentation(): void {\n this.#clampInteraction();\n }\n\n #rebuildSnapshot(status: TableViewSnapshot[\"status\"], error?: unknown): void {\n const layout = createTableLayout(\n this.#table.metadata,\n this.#columnWidths,\n this.#viewport,\n this.#layoutOptions(),\n );\n this.#viewport = Object.freeze({\n ...this.#viewport,\n scrollLeft: layout.horizontal.physicalOffset,\n scrollTop: layout.vertical.physicalOffset,\n });\n this.#snapshot = Object.freeze({\n generation: this.#generation,\n status,\n metadata: this.#table.metadata,\n layout,\n activeCell: this.#activeCell,\n selection: this.#selection,\n ...(error === undefined ? {} : { error }),\n });\n this.#emit();\n }\n\n #publish(): void {\n this.#snapshot = Object.freeze({\n ...this.#snapshot,\n activeCell: this.#activeCell,\n selection: this.#selection,\n });\n this.#emit();\n }\n\n #emit(): void {\n for (const listener of this.#listeners) {\n try {\n listener(this.#snapshot);\n } catch (error) {\n if (typeof reportError === \"function\") {\n reportError(error);\n }\n }\n }\n }\n\n #assertOpen(): void {\n if (this.#disposed || this.#tableClosed || this.#snapshot.status === \"closed\") {\n throw closedError(\"Table view controller\");\n }\n }\n}\n\nexport function createTableController(\n table: TableHandle,\n options: TableControllerOptions = {},\n): TableViewController {\n if (!table || typeof table.readRange !== \"function\" || typeof table.subscribe !== \"function\") {\n throw invalidArgument(\"table must be a TableHandle\");\n }\n return new Controller(table, options);\n}\n\nfunction normalizeMergedCells(\n regions: readonly MergedCellRegion[],\n rowCount: number,\n columnCount: number,\n): readonly MergedCellRegion[] {\n const unique = new Map<string, MergedCellRegion>();\n for (const region of regions) {\n if (\n !region\n || !Number.isSafeInteger(region.rowStart)\n || !Number.isSafeInteger(region.rowEnd)\n || !Number.isSafeInteger(region.columnStart)\n || !Number.isSafeInteger(region.columnEnd)\n || region.rowStart < 0\n || region.columnStart < 0\n || region.rowEnd <= region.rowStart\n || region.columnEnd <= region.columnStart\n || region.rowEnd > rowCount\n || region.columnEnd > columnCount\n ) {\n continue;\n }\n const frozen = Object.freeze({ ...region });\n unique.set(mergeKey(frozen), frozen);\n }\n return Object.freeze([...unique.values()].sort(\n (left, right) => left.rowStart - right.rowStart\n || left.columnStart - right.columnStart\n || left.rowEnd - right.rowEnd\n || left.columnEnd - right.columnEnd,\n ));\n}\n\nfunction sameMergedCells(\n left: readonly MergedCellRegion[],\n right: readonly MergedCellRegion[],\n): boolean {\n return left.length === right.length\n && left.every((region, index) => mergeKey(region) === mergeKey(right[index]!));\n}\n\nfunction mergeKey(region: MergedCellRegion): string {\n return `${region.rowStart}:${region.rowEnd}:${region.columnStart}:${region.columnEnd}`;\n}\n\nfunction mergeContaining(\n regions: readonly MergedCellRegion[],\n cell: CellPosition,\n): MergedCellRegion | undefined {\n return regions.find((region) => (\n cell.rowIndex >= region.rowStart\n && cell.rowIndex < region.rowEnd\n && cell.columnIndex >= region.columnStart\n && cell.columnIndex < region.columnEnd\n ));\n}\n\nfunction createMergedSelection(\n anchor: CellPosition,\n focus: CellPosition,\n regions: readonly MergedCellRegion[],\n): Readonly<TableSelection> {\n const selection = createSelection(anchor, focus);\n let range = selection.range;\n for (;;) {\n let expanded = range;\n for (const region of regions) {\n if (!rangesIntersect(expanded, region)) continue;\n expanded = Object.freeze({\n rowStart: Math.min(expanded.rowStart, region.rowStart),\n rowEnd: Math.max(expanded.rowEnd, region.rowEnd),\n columnStart: Math.min(expanded.columnStart, region.columnStart),\n columnEnd: Math.max(expanded.columnEnd, region.columnEnd),\n });\n }\n if (sameGridRange(range, expanded)) break;\n range = expanded;\n }\n return Object.freeze({ ...selection, range });\n}\n\nfunction rangesIntersect(left: GridRange, right: MergedCellRegion): boolean {\n return left.rowStart < right.rowEnd\n && left.rowEnd > right.rowStart\n && left.columnStart < right.columnEnd\n && left.columnEnd > right.columnStart;\n}\n\nfunction navigationOrigin(\n current: CellPosition,\n command: NavigationCommand,\n regions: readonly MergedCellRegion[],\n): Readonly<CellPosition> {\n const merge = mergeContaining(regions, current);\n if (merge === undefined) return current;\n if (command === \"right\") {\n return Object.freeze({ rowIndex: current.rowIndex, columnIndex: merge.columnEnd - 1 });\n }\n if (command === \"down\" || command === \"page-down\") {\n return Object.freeze({ rowIndex: merge.rowEnd - 1, columnIndex: current.columnIndex });\n }\n return current;\n}\n\nfunction navigationDirections(command: NavigationCommand): readonly [-1 | 1, -1 | 1] {\n switch (command) {\n case \"left\":\n case \"row-start\":\n return [1, -1];\n case \"up\":\n case \"page-up\":\n return [-1, 1];\n case \"table-start\":\n return [-1, -1];\n default:\n return [1, 1];\n }\n}\n\nfunction nextVisibleColumn(\n widths: readonly number[],\n from: number,\n direction: -1 | 1,\n): number | null {\n for (\n let index = Math.min(widths.length - 1, Math.max(0, from));\n index >= 0 && index < widths.length;\n index += direction\n ) {\n if ((widths[index] ?? 0) > 0) return index;\n }\n return null;\n}\n\nfunction normalizeOptions(options: TableControllerOptions): NormalizedOptions {\n const minColumnWidth = positiveFinite(\n options.minColumnWidth ?? DEFAULT_MIN_COLUMN_WIDTH,\n \"minColumnWidth\",\n );\n const maxColumnWidth = positiveFinite(\n options.maxColumnWidth ?? DEFAULT_MAX_COLUMN_WIDTH,\n \"maxColumnWidth\",\n );\n if (maxColumnWidth < minColumnWidth) {\n throw invalidArgument(\"maxColumnWidth must be greater than or equal to minColumnWidth\");\n }\n const maxWindowCells = positiveInteger(\n options.maxWindowCells ?? DEFAULT_MAX_WINDOW_CELLS,\n \"maxWindowCells\",\n );\n if (maxWindowCells > MAX_RANGE_CELLS) {\n throw invalidArgument(`maxWindowCells cannot exceed ${MAX_RANGE_CELLS}`);\n }\n return Object.freeze({\n ...(options.rowHeight === undefined ? {} : { rowHeight: options.rowHeight }),\n ...(options.headerHeight === undefined ? {} : { headerHeight: options.headerHeight }),\n ...(options.rowHeaderWidth === undefined ? {} : { rowHeaderWidth: options.rowHeaderWidth }),\n ...(options.scrollPixelLimit === undefined ? {} : { scrollPixelLimit: options.scrollPixelLimit }),\n ...(options.overscanRows === undefined ? {} : { overscanRows: options.overscanRows }),\n ...(options.overscanColumns === undefined ? {} : { overscanColumns: options.overscanColumns }),\n columnWidth: positiveFinite(options.columnWidth ?? DEFAULT_COLUMN_WIDTH, \"columnWidth\"),\n minColumnWidth,\n maxColumnWidth,\n columnWidths: Object.freeze({ ...(options.columnWidths ?? {}) }),\n maxWindowCells,\n });\n}\n\nfunction initialColumnWidths(\n metadata: TableHandle[\"metadata\"],\n options: NormalizedOptions,\n): number[] {\n return metadata.schema.columns.map((column) => clampWidth(\n options.columnWidths[column.id] ?? options.columnWidth,\n options,\n ));\n}\n\nfunction reconcileColumnWidths(\n previousMetadata: TableHandle[\"metadata\"],\n nextMetadata: TableHandle[\"metadata\"],\n previousWidths: readonly number[],\n options: NormalizedOptions,\n): number[] {\n const byId = new Map(previousMetadata.schema.columns.map(\n (column, index) => [column.id, previousWidths[index]!] as const,\n ));\n return nextMetadata.schema.columns.map((column) => clampWidth(\n byId.get(column.id) ?? options.columnWidths[column.id] ?? options.columnWidth,\n options,\n ));\n}\n\nfunction normalizeViewport(viewport: ViewportUpdate): Required<ViewportUpdate> {\n return Object.freeze({\n width: nonNegativeFinite(viewport.width, \"viewport.width\"),\n height: nonNegativeFinite(viewport.height, \"viewport.height\"),\n scrollLeft: nonNegativeFinite(viewport.scrollLeft, \"viewport.scrollLeft\"),\n scrollTop: nonNegativeFinite(viewport.scrollTop, \"viewport.scrollTop\"),\n devicePixelRatio: positiveFinite(viewport.devicePixelRatio ?? 1, \"viewport.devicePixelRatio\"),\n });\n}\n\nfunction layoutRanges(\n layout: TableViewSnapshot[\"layout\"],\n maxCells: number,\n mergedCells: readonly MergedCellRegion[] = [],\n): Readonly<{\n visible: readonly Readonly<GridRange>[];\n overscan: readonly Readonly<GridRange>[];\n}> {\n const visible = windowRectangles(\n layout.rows.visible,\n layout.columns.visible,\n layout.frozenRowRange,\n layout.frozenColumnRange,\n );\n const anchors = mergeAnchorRanges(mergedCells, visible);\n const visibleWithAnchors = Object.freeze([\n ...visible,\n ...anchors.filter((anchor) => !visible.some((range) => rangeContainsRange(range, anchor))),\n ]);\n const visibleCellCount = visibleWithAnchors.reduce(\n (total, range) => total + rangeCellCount(range),\n 0,\n );\n if (visibleCellCount > maxCells) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `The viewport contains ${visibleCellCount} cells; the window limit is ${maxCells}`,\n {\n details: {\n resource: \"viewport-cells\",\n required: visibleCellCount,\n available: maxCells,\n visibleCellCount,\n maxCells,\n },\n },\n );\n }\n const fullOverscan = windowRectangles(\n layout.rows.overscan,\n layout.columns.overscan,\n layout.frozenRowRange,\n layout.frozenColumnRange,\n );\n const overscanCellCount = fullOverscan.reduce(\n (total, range) => total + rangeCellCount(range),\n 0,\n );\n const overscanWithAnchors = Object.freeze([\n ...fullOverscan,\n ...anchors.filter((anchor) => !fullOverscan.some(\n (range) => rangeContainsRange(range, anchor),\n )),\n ]);\n return Object.freeze({\n visible: visibleWithAnchors,\n overscan: overscanCellCount + anchors.length <= maxCells\n ? overscanWithAnchors\n : visibleWithAnchors,\n });\n}\n\nfunction mergeAnchorRanges(\n mergedCells: readonly MergedCellRegion[],\n visible: readonly Readonly<GridRange>[],\n): readonly Readonly<GridRange>[] {\n const anchors = new Map<string, Readonly<GridRange>>();\n for (const region of mergedCells) {\n if (!visible.some((range) => rangesIntersect(range, region))) continue;\n const range = Object.freeze({\n rowStart: region.rowStart,\n rowEnd: region.rowStart + 1,\n columnStart: region.columnStart,\n columnEnd: region.columnStart + 1,\n });\n anchors.set(`${range.rowStart}:${range.columnStart}`, range);\n }\n return Object.freeze([...anchors.values()]);\n}\n\nfunction windowRectangles(\n rows: Readonly<{ start: number; end: number }>,\n columns: Readonly<{ start: number; end: number }>,\n frozenRows: Readonly<{ start: number; end: number }>,\n frozenColumns: Readonly<{ start: number; end: number }>,\n): readonly Readonly<GridRange>[] {\n const rowBands = mergeIndexBands(rows, frozenRows);\n const columnBands = mergeIndexBands(columns, frozenColumns);\n const rectangles: GridRange[] = [];\n for (const row of rowBands) {\n for (const column of columnBands) {\n rectangles.push(Object.freeze({\n rowStart: row.start,\n rowEnd: row.end,\n columnStart: column.start,\n columnEnd: column.end,\n }));\n }\n }\n return Object.freeze(rectangles);\n}\n\nfunction mergeIndexBands(\n primary: Readonly<{ start: number; end: number }>,\n frozen: Readonly<{ start: number; end: number }>,\n): readonly Readonly<{ start: number; end: number }>[] {\n const bands = [primary, frozen]\n .filter((range) => range.start < range.end)\n .sort((left, right) => left.start - right.start);\n if (bands.length <= 1) return Object.freeze(bands.map((range) => Object.freeze({ ...range })));\n const [first, second] = bands as [typeof primary, typeof primary];\n return first.end >= second.start\n ? Object.freeze([Object.freeze({ start: first.start, end: Math.max(first.end, second.end) })])\n : Object.freeze(bands.map((range) => Object.freeze({ ...range })));\n}\n\nfunction gridRangeToRequest(range: GridRange): Readonly<RangeRequest> {\n return Object.freeze({\n rowStart: range.rowStart,\n rowCount: range.rowEnd - range.rowStart,\n columnStart: range.columnStart,\n columnCount: range.columnEnd - range.columnStart,\n });\n}\n\nfunction batchGridRange(batch: TableBatch): Readonly<GridRange> {\n return Object.freeze({\n rowStart: batch.range.rowStart,\n rowEnd: batch.range.rowStart + batch.range.rowCount,\n columnStart: batch.range.columnStart,\n columnEnd: batch.range.columnStart + batch.range.columnCount,\n });\n}\n\nfunction batchRows(batch: TableBatch): readonly (readonly (string | null)[])[] {\n return Object.freeze(batch.toDisplayRows({\n maxCells: Math.max(1, batch.range.rowCount * batch.range.columnCount),\n }).map((row) => Object.freeze(row)));\n}\n\nfunction rowsToTsv(rows: readonly (readonly (string | null)[])[]): string {\n return rows.map((row) => row.map(tsvField).join(\"\\t\")).join(\"\\n\");\n}\n\nfunction tsvField(value: string | null): string {\n if (value === null) {\n return \"\";\n }\n return /[\\t\\r\\n\"]/.test(value) ? `\"${value.replaceAll('\"', '\"\"')}\"` : value;\n}\n\nfunction revealOffset(\n current: number,\n viewportSize: number,\n itemStart: number,\n itemEnd: number,\n maximum: number,\n): number {\n if (viewportSize <= 0 || itemStart < current) {\n return Math.min(maximum, Math.max(0, itemStart));\n }\n if (itemEnd > current + viewportSize) {\n return Math.min(maximum, Math.max(0, itemEnd - viewportSize));\n }\n return current;\n}\n\nfunction rangeContains(range: GridRange, rowIndex: number, columnIndex: number): boolean {\n return rowIndex >= range.rowStart && rowIndex < range.rowEnd\n && columnIndex >= range.columnStart && columnIndex < range.columnEnd;\n}\n\nfunction rangeContainsRange(container: GridRange, candidate: GridRange): boolean {\n return candidate.rowStart >= container.rowStart\n && candidate.rowEnd <= container.rowEnd\n && candidate.columnStart >= container.columnStart\n && candidate.columnEnd <= container.columnEnd;\n}\n\nfunction rangeCellCount(range: GridRange): number {\n return (range.rowEnd - range.rowStart) * (range.columnEnd - range.columnStart);\n}\n\nfunction sameGridRange(left: GridRange, right: GridRange | null): boolean {\n return right !== null\n && left.rowStart === right.rowStart\n && left.rowEnd === right.rowEnd\n && left.columnStart === right.columnStart\n && left.columnEnd === right.columnEnd;\n}\n\nfunction sameViewport(left: Required<ViewportUpdate>, right: Required<ViewportUpdate>): boolean {\n return left.width === right.width\n && left.height === right.height\n && left.scrollLeft === right.scrollLeft\n && left.scrollTop === right.scrollTop\n && left.devicePixelRatio === right.devicePixelRatio;\n}\n\nfunction isValidCell(\n rowIndex: number,\n columnIndex: number,\n rowCount: number,\n columnCount: number,\n): boolean {\n return Number.isSafeInteger(rowIndex) && rowIndex >= 0 && rowIndex < rowCount\n && Number.isSafeInteger(columnIndex) && columnIndex >= 0 && columnIndex < columnCount;\n}\n\nfunction assertColumnIndex(columnIndex: number, columnCount: number): void {\n if (!Number.isSafeInteger(columnIndex) || columnIndex < 0 || columnIndex >= columnCount) {\n throw invalidArgument(`columnIndex must be between 0 and ${Math.max(0, columnCount - 1)}`);\n }\n}\n\nfunction assertWindowCellLimit(request: RangeRequest, limit: number, label: string): void {\n const cells = request.rowCount * request.columnCount;\n if (!Number.isSafeInteger(cells) || cells > limit) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `The ${label} contains ${cells} cells; the limit is ${limit}`,\n {\n details: {\n resource: \"view-window-cells\",\n required: cells,\n available: limit,\n cells,\n limit,\n },\n },\n );\n }\n}\n\nfunction clampWidth(width: number, options: NormalizedOptions): number {\n if (!Number.isFinite(width)) {\n throw invalidArgument(\"column width must be a finite number\");\n }\n return Math.min(options.maxColumnWidth, Math.max(options.minColumnWidth, width));\n}\n\nfunction positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) {\n throw invalidArgument(`${name} must be a positive finite number`);\n }\n return value;\n}\n\nfunction nonNegativeFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw invalidArgument(`${name} must be a non-negative finite number`);\n }\n return value;\n}\n\nfunction positiveInteger(value: number, name: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw invalidArgument(`${name} must be a positive safe integer`);\n }\n return value;\n}\n", "import type { TableHandle } from \"../client.js\";\nimport type {\n MergedCellRegion,\n PresentationRange,\n PresentationStyle,\n RangeRequest,\n SpreadsheetPresentation,\n} from \"../model.js\";\nimport { TabularkError, invalidArgument } from \"../errors.js\";\nimport { containsCell } from \"./selection.js\";\nimport { AccessibleViewportGrid, type AccessibleGridRow } from \"./accessible-grid.js\";\nimport {\n CanvasTablePainter,\n DEFAULT_CANVAS_TABLE_THEME,\n forcedColorsCanvasTableTheme,\n type CanvasPaintColumn,\n type CanvasPaintMergedCell,\n type CanvasPaintRow,\n type CanvasTableTheme,\n} from \"./canvas-painter.js\";\nimport { createTableController, type TableViewController } from \"./controller.js\";\nimport type {\n CellPosition,\n NavigationCommand,\n TableControllerOptions,\n TableViewSnapshot,\n} from \"./types.js\";\n\nconst RESIZE_HANDLE_WIDTH = 8;\nconst RESIZE_TARGET_SIZE = 44;\nconst KEYBOARD_RESIZE_STEP = 8;\nconst KEYBOARD_RESIZE_COARSE_STEP = 32;\nconst AUTOSIZE_HORIZONTAL_PADDING = 24;\nconst MAX_PRESENTATION_WINDOW_CELLS = 100_000;\n\nlet nextViewId = 1;\n\nexport interface CanvasTableViewOptions {\n readonly container: HTMLElement;\n /** Provide either a table or a preconfigured controller, never both. */\n readonly table?: TableHandle;\n /** Provide either a controller or a table, never both. */\n readonly controller?: TableViewController;\n readonly controllerOptions?: TableControllerOptions;\n /**\n * Applies static spreadsheet sizing metadata when a TableHandle provides it.\n * Workbook colors never override the system palette in forced-colors mode.\n */\n readonly presentation?: \"auto\" | \"ignore\";\n readonly ariaLabel?: string;\n readonly theme?: Partial<CanvasTableTheme>;\n readonly maxDevicePixelRatio?: number;\n /** Testable clipboard seam; navigator.clipboard.writeText is used by default. */\n readonly writeClipboard?: (text: string) => Promise<void> | void;\n readonly onError?: (error: unknown) => void;\n}\n\nexport interface CanvasTableView {\n readonly element: HTMLDivElement;\n readonly controller: TableViewController;\n focus(options?: FocusOptions): void;\n destroy(): void;\n dispose(): void;\n}\n\ntype PointerInteraction =\n | Readonly<{\n kind: \"resize\";\n pointerId: number;\n columnIndex: number;\n startClientX: number;\n startWidth: number;\n }>\n | Readonly<{\n kind: \"select\";\n pointerId: number;\n anchor: Readonly<CellPosition>;\n }>;\n\nclass View implements CanvasTableView {\n readonly element: HTMLDivElement;\n readonly controller: TableViewController;\n\n readonly #scrollHost: HTMLDivElement;\n readonly #spacer: HTMLDivElement;\n readonly #surface: HTMLDivElement;\n readonly #canvas: HTMLCanvasElement;\n readonly #resizeLayer: HTMLDivElement;\n readonly #resizeInstructions: HTMLDivElement;\n readonly #message: HTMLDivElement;\n readonly #accessibleGrid: AccessibleViewportGrid;\n readonly #painter: CanvasTablePainter;\n readonly #ownerWindow: Window & typeof globalThis;\n readonly #ownsController: boolean;\n readonly #writeClipboard: ((text: string) => Promise<void> | void) | undefined;\n readonly #onError: ((error: unknown) => void) | undefined;\n readonly #baseTheme: Readonly<CanvasTableTheme>;\n readonly #presentationTable: TableHandle | undefined;\n #theme: Readonly<CanvasTableTheme>;\n readonly #forcedColorsQuery: MediaQueryList;\n readonly #unsubscribe: () => void;\n readonly #resizeObserver?: ResizeObserver;\n readonly #resizeHandles = new Map<string, HTMLDivElement>();\n\n #snapshot: Readonly<TableViewSnapshot>;\n #frame = 0;\n #interaction: PointerInteraction | null = null;\n #copyAbort: AbortController | null = null;\n #announcementFrame = 0;\n #forcedColors = false;\n #presentation: SpreadsheetPresentation | null = null;\n #presentationRanges: readonly PresentationRange[] = [];\n #mergedCells: readonly MergedCellRegion[] = [];\n #presentationRequestKey = \"\";\n #presentationAbort: AbortController | null = null;\n #destroyed = false;\n\n constructor(options: CanvasTableViewOptions) {\n const ownerDocument = options.container.ownerDocument;\n const ownerWindow = ownerDocument.defaultView;\n if (ownerWindow === null) {\n throw invalidArgument(\"container must belong to an active browser document\");\n }\n this.#ownerWindow = ownerWindow;\n const presentation = options.presentation ?? \"auto\";\n if (presentation !== \"auto\" && presentation !== \"ignore\") {\n throw invalidArgument(\"presentation must be auto or ignore\");\n }\n this.#ownsController = options.table !== undefined;\n this.controller = options.controller\n ?? createTableController(options.table!, options.controllerOptions);\n this.#snapshot = this.controller.getSnapshot();\n this.#writeClipboard = options.writeClipboard;\n this.#onError = options.onError;\n this.#presentationTable = presentation === \"auto\" ? options.table : undefined;\n this.#baseTheme = Object.freeze({ ...DEFAULT_CANVAS_TABLE_THEME, ...options.theme });\n this.#forcedColorsQuery = ownerWindow.matchMedia(\"(forced-colors: active)\");\n this.#forcedColors = this.#forcedColorsQuery.matches;\n this.#theme = this.#forcedColors\n ? forcedColorsCanvasTableTheme(this.#baseTheme)\n : this.#baseTheme;\n\n this.element = ownerDocument.createElement(\"div\");\n this.element.className = \"tabulark-view\";\n this.element.dataset.tabularkView = \"\";\n this.element.setAttribute(\"aria-label\", options.ariaLabel ?? this.#tableLabel());\n Object.assign(this.element.style, {\n background: this.#theme.background,\n border: `1px solid ${this.#theme.gridLine}`,\n borderRadius: \"6px\",\n boxSizing: \"border-box\",\n color: this.#theme.foreground,\n contain: \"layout paint style\",\n height: \"100%\",\n minHeight: \"120px\",\n minWidth: \"0\",\n overflow: \"hidden\",\n position: \"relative\",\n width: \"100%\",\n });\n\n this.#scrollHost = ownerDocument.createElement(\"div\");\n this.#scrollHost.className = \"tabulark-scroll\";\n this.#scrollHost.dataset.tabularkScroll = \"\";\n this.#scrollHost.tabIndex = -1;\n Object.assign(this.#scrollHost.style, {\n inset: \"0\",\n overflow: \"auto\",\n overscrollBehavior: \"contain\",\n position: \"absolute\",\n scrollbarGutter: \"stable\",\n });\n\n this.#spacer = ownerDocument.createElement(\"div\");\n this.#spacer.className = \"tabulark-scroll-spacer\";\n this.#spacer.dataset.tabularkScrollSpacer = \"\";\n this.#spacer.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(this.#spacer.style, {\n left: \"0\",\n pointerEvents: \"none\",\n position: \"absolute\",\n top: \"0\",\n });\n\n this.#surface = ownerDocument.createElement(\"div\");\n this.#surface.className = \"tabulark-surface\";\n this.#surface.dataset.tabularkSurface = \"\";\n Object.assign(this.#surface.style, {\n left: \"0\",\n position: \"sticky\",\n top: \"0\",\n userSelect: \"none\",\n zIndex: \"1\",\n });\n\n this.#canvas = ownerDocument.createElement(\"canvas\");\n this.#canvas.className = \"tabulark-canvas\";\n this.#canvas.dataset.tabularkCanvas = \"\";\n this.#canvas.setAttribute(\"aria-hidden\", \"true\");\n this.#canvas.draggable = false;\n Object.assign(this.#canvas.style, {\n cursor: \"default\",\n display: \"block\",\n touchAction: \"pan-x pan-y\",\n });\n\n this.#resizeLayer = ownerDocument.createElement(\"div\");\n this.#resizeLayer.className = \"tabulark-resize-layer\";\n Object.assign(this.#resizeLayer.style, {\n left: \"0\",\n pointerEvents: \"none\",\n position: \"absolute\",\n top: \"0\",\n width: \"100%\",\n });\n\n this.#resizeInstructions = ownerDocument.createElement(\"div\");\n this.#resizeInstructions.id = `tabulark-resize-instructions-${nextViewId}`;\n nextViewId += 1;\n this.#resizeInstructions.textContent = \"Use Left and Right Arrow keys to resize. Hold Shift for larger steps. Home and End use the minimum and maximum widths. Enter fits the visible content.\";\n visuallyHide(this.#resizeInstructions);\n\n this.#message = ownerDocument.createElement(\"div\");\n this.#message.className = \"tabulark-message\";\n this.#message.dataset.tabularkMessage = \"\";\n this.#message.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(this.#message.style, {\n alignItems: \"center\",\n background: this.#theme.background,\n color: this.#theme.mutedForeground,\n display: \"none\",\n font: this.#theme.font,\n inset: \"0\",\n justifyContent: \"center\",\n padding: \"24px\",\n pointerEvents: \"none\",\n position: \"absolute\",\n textAlign: \"center\",\n zIndex: \"2\",\n });\n\n this.#accessibleGrid = new AccessibleViewportGrid(\n ownerDocument,\n options.ariaLabel ?? this.#tableLabel(),\n );\n this.#painter = new CanvasTablePainter(this.#canvas, {\n theme: this.#theme,\n forcedColors: this.#forcedColors,\n ...(options.maxDevicePixelRatio === undefined\n ? {}\n : { maxDevicePixelRatio: options.maxDevicePixelRatio }),\n });\n this.#applyThemeToElements();\n\n this.#surface.append(this.#canvas, this.#resizeLayer);\n this.#scrollHost.append(this.#spacer, this.#surface);\n this.element.append(\n this.#scrollHost,\n this.#message,\n this.#accessibleGrid.element,\n this.#accessibleGrid.statusElement,\n this.#resizeInstructions,\n );\n options.container.append(this.element);\n\n this.#unsubscribe = this.controller.subscribe((snapshot) => {\n this.#snapshot = snapshot;\n if (this.#isTerminal()) {\n if (this.#resizeLayer.contains(this.element.ownerDocument.activeElement)) {\n this.#accessibleGrid.focus({ preventScroll: true });\n }\n this.#cancelInteraction();\n this.#copyAbort?.abort();\n this.#copyAbort = null;\n }\n this.#schedulePresentationRanges();\n this.#scheduleFrame();\n });\n this.#scrollHost.addEventListener(\"scroll\", this.#onScroll, { passive: true });\n this.#surface.addEventListener(\"pointerdown\", this.#onPointerDown);\n this.#surface.addEventListener(\"pointermove\", this.#onPointerMove);\n this.#surface.addEventListener(\"pointerup\", this.#onPointerUp);\n this.#surface.addEventListener(\"pointercancel\", this.#onPointerUp);\n this.#surface.addEventListener(\"dblclick\", this.#onDoubleClick);\n this.element.addEventListener(\"keydown\", this.#onKeyDown);\n this.element.addEventListener(\"focusin\", this.#onFocusIn);\n this.element.addEventListener(\"focusout\", this.#onFocusOut);\n this.#forcedColorsQuery.addEventListener(\"change\", this.#onForcedColorsChange);\n\n if (typeof ownerWindow.ResizeObserver === \"function\") {\n this.#resizeObserver = new ownerWindow.ResizeObserver(() => this.#updateViewport());\n this.#resizeObserver.observe(this.#scrollHost);\n } else {\n ownerWindow.addEventListener(\"resize\", this.#onWindowResize);\n }\n\n this.#updateViewport();\n this.#scheduleFrame();\n if (this.#presentationTable !== undefined) {\n void this.#applyPresentation(this.#presentationTable);\n }\n }\n\n focus(options?: FocusOptions): void {\n this.#assertAlive();\n this.#accessibleGrid.focus(options);\n }\n\n destroy(): void {\n if (this.#destroyed) {\n return;\n }\n this.#destroyed = true;\n this.#presentationAbort?.abort();\n this.#presentationAbort = null;\n this.#copyAbort?.abort();\n this.#copyAbort = null;\n if (this.#frame !== 0) {\n this.#ownerWindow.cancelAnimationFrame(this.#frame);\n this.#frame = 0;\n }\n if (this.#announcementFrame !== 0) {\n this.#ownerWindow.cancelAnimationFrame(this.#announcementFrame);\n this.#announcementFrame = 0;\n }\n this.#resizeObserver?.disconnect();\n this.#ownerWindow.removeEventListener(\"resize\", this.#onWindowResize);\n this.#unsubscribe();\n this.#scrollHost.removeEventListener(\"scroll\", this.#onScroll);\n this.#surface.removeEventListener(\"pointerdown\", this.#onPointerDown);\n this.#surface.removeEventListener(\"pointermove\", this.#onPointerMove);\n this.#surface.removeEventListener(\"pointerup\", this.#onPointerUp);\n this.#surface.removeEventListener(\"pointercancel\", this.#onPointerUp);\n this.#surface.removeEventListener(\"dblclick\", this.#onDoubleClick);\n this.element.removeEventListener(\"keydown\", this.#onKeyDown);\n this.element.removeEventListener(\"focusin\", this.#onFocusIn);\n this.element.removeEventListener(\"focusout\", this.#onFocusOut);\n this.#forcedColorsQuery.removeEventListener(\"change\", this.#onForcedColorsChange);\n this.#accessibleGrid.destroy();\n this.element.remove();\n if (this.#ownsController) {\n this.controller.dispose();\n }\n }\n\n dispose(): void {\n this.destroy();\n }\n\n readonly #onScroll = (): void => {\n this.#updateViewport();\n };\n\n readonly #onWindowResize = (): void => {\n this.#updateViewport();\n };\n\n readonly #onForcedColorsChange = (event: MediaQueryListEvent): void => {\n if (this.#destroyed) {\n return;\n }\n this.#forcedColors = event.matches;\n this.#theme = this.#forcedColors\n ? forcedColorsCanvasTableTheme(this.#baseTheme)\n : this.#baseTheme;\n this.#painter.setTheme(this.#theme, { forcedColors: this.#forcedColors });\n this.#applyThemeToElements();\n this.#scheduleFrame();\n };\n\n readonly #onFocusIn = (event: FocusEvent): void => {\n this.element.style.outline = `2px solid ${this.#focusColor()}`;\n this.element.style.outlineOffset = \"-2px\";\n const resizeHandle = this.#resizeHandleFromTarget(event.target);\n if (resizeHandle !== null) {\n resizeHandle.style.outline = `2px solid ${this.#focusColor()}`;\n resizeHandle.style.outlineOffset = \"-2px\";\n return;\n }\n if (\n !this.#isTerminal()\n && this.#snapshot.activeCell === null\n && this.#hasCells()\n && event.target === this.#accessibleGrid.element\n ) {\n this.controller.setActiveCell({ rowIndex: 0, columnIndex: 0 });\n }\n };\n\n readonly #onFocusOut = (event: FocusEvent): void => {\n const resizeHandle = this.#resizeHandleFromTarget(event.target);\n if (resizeHandle !== null) {\n resizeHandle.style.outline = \"none\";\n }\n queueMicrotask(() => {\n if (!this.#destroyed && !this.element.contains(this.element.ownerDocument.activeElement)) {\n this.element.style.outline = \"none\";\n }\n });\n };\n\n readonly #onPointerDown = (event: PointerEvent): void => {\n if (event.button !== 0 || this.#isTerminal()) {\n return;\n }\n const position = this.#eventPosition(event);\n const resizeColumn = this.#resizeColumnFromTarget(event.target);\n const hit = resizeColumn === null\n ? this.controller.hitTest(position.x, position.y, RESIZE_HANDLE_WIDTH / 2)\n : { kind: \"column-resize\" as const, columnIndex: resizeColumn, boundaryX: position.x };\n\n if (hit.kind === \"column-resize\") {\n event.preventDefault();\n this.#interaction = Object.freeze({\n kind: \"resize\",\n pointerId: event.pointerId,\n columnIndex: hit.columnIndex,\n startClientX: event.clientX,\n startWidth: this.controller.columnWidths[hit.columnIndex]!,\n });\n this.#surface.setPointerCapture(event.pointerId);\n this.#surface.style.cursor = \"col-resize\";\n return;\n }\n\n const cell = this.#cellFromHit(hit);\n if (cell === null) {\n return;\n }\n this.focus({ preventScroll: true });\n this.controller.setActiveCell(cell, {\n extendSelection: event.shiftKey,\n scrollIntoView: false,\n });\n if (event.pointerType !== \"touch\") {\n this.#interaction = Object.freeze({\n kind: \"select\",\n pointerId: event.pointerId,\n anchor: event.shiftKey && this.#snapshot.selection !== null\n ? this.#snapshot.selection.anchor\n : cell,\n });\n this.#surface.setPointerCapture(event.pointerId);\n }\n };\n\n readonly #onPointerMove = (event: PointerEvent): void => {\n if (this.#isTerminal()) {\n this.#cancelInteraction();\n return;\n }\n if (this.#interaction?.pointerId === event.pointerId) {\n if (this.#interaction.kind === \"resize\") {\n const delta = event.clientX - this.#interaction.startClientX;\n this.controller.resizeColumn(\n this.#interaction.columnIndex,\n this.#interaction.startWidth + delta,\n );\n return;\n }\n const position = this.#eventPosition(event);\n const hit = this.controller.hitTest(position.x, position.y, 0);\n if (hit.kind === \"cell\") {\n this.controller.setSelection(this.#interaction.anchor, {\n rowIndex: hit.rowIndex,\n columnIndex: hit.columnIndex,\n });\n }\n return;\n }\n\n const position = this.#eventPosition(event);\n const hit = this.controller.hitTest(position.x, position.y, RESIZE_HANDLE_WIDTH / 2);\n this.#surface.style.cursor = hit.kind === \"column-resize\" ? \"col-resize\" : \"default\";\n };\n\n readonly #onPointerUp = (event: PointerEvent): void => {\n if (this.#interaction?.pointerId !== event.pointerId) {\n return;\n }\n const resizedColumn = this.#interaction.kind === \"resize\"\n ? this.#interaction.columnIndex\n : null;\n if (this.#surface.hasPointerCapture(event.pointerId)) {\n this.#surface.releasePointerCapture(event.pointerId);\n }\n this.#interaction = null;\n this.#surface.style.cursor = \"default\";\n if (resizedColumn !== null) {\n this.controller.ensureColumnVisible(resizedColumn);\n this.#announceColumnWidth(resizedColumn, false);\n }\n };\n\n readonly #onDoubleClick = (event: MouseEvent): void => {\n if (this.#isTerminal()) {\n return;\n }\n const position = this.#eventPosition(event);\n const fromTarget = this.#resizeColumnFromTarget(event.target);\n const hit = fromTarget === null\n ? this.controller.hitTest(position.x, position.y, RESIZE_HANDLE_WIDTH / 2)\n : { kind: \"column-resize\" as const, columnIndex: fromTarget };\n if (hit.kind !== \"column-resize\") {\n return;\n }\n event.preventDefault();\n this.controller.autosizeColumn(hit.columnIndex, this.#measureColumn(hit.columnIndex));\n this.controller.ensureColumnVisible(hit.columnIndex);\n this.#announceColumnWidth(hit.columnIndex, true);\n };\n\n readonly #onKeyDown = (event: KeyboardEvent): void => {\n const resizeColumn = this.#resizeColumnFromTarget(event.target);\n if (resizeColumn !== null) {\n if (this.#handleResizeKeyDown(event, resizeColumn)) {\n return;\n }\n if (keyboardCommand(event) !== null) {\n return;\n }\n }\n if (this.#isTerminal() || event.altKey) {\n return;\n }\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === \"c\") {\n event.preventDefault();\n void this.#copySelection();\n return;\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n this.controller.clearSelection();\n return;\n }\n const command = keyboardCommand(event);\n if (command === null) {\n return;\n }\n event.preventDefault();\n this.controller.moveActive(command, {\n extendSelection: event.shiftKey,\n scrollIntoView: true,\n });\n };\n\n #handleResizeKeyDown(event: KeyboardEvent, columnIndex: number): boolean {\n if (this.#isTerminal() || event.altKey || event.ctrlKey || event.metaKey) {\n return false;\n }\n const width = this.controller.columnWidths[columnIndex];\n if (width === undefined) {\n return false;\n }\n const step = event.shiftKey ? KEYBOARD_RESIZE_COARSE_STEP : KEYBOARD_RESIZE_STEP;\n let nextWidth: number | null = null;\n switch (event.key) {\n case \"ArrowLeft\":\n nextWidth = width - step;\n break;\n case \"ArrowRight\":\n nextWidth = width + step;\n break;\n case \"Home\":\n nextWidth = this.controller.minColumnWidth;\n break;\n case \"End\":\n nextWidth = this.controller.maxColumnWidth;\n break;\n case \"Enter\":\n nextWidth = this.#measureColumn(columnIndex);\n break;\n default:\n return false;\n }\n event.preventDefault();\n event.stopPropagation();\n if (event.key === \"Enter\") {\n this.controller.autosizeColumn(columnIndex, nextWidth);\n } else {\n this.controller.resizeColumn(columnIndex, nextWidth);\n }\n this.controller.ensureColumnVisible(columnIndex);\n this.#announceColumnWidth(columnIndex, event.key === \"Enter\");\n return true;\n }\n\n #updateViewport(): void {\n if (this.#isTerminal()) {\n return;\n }\n const width = this.#scrollHost.clientWidth;\n const height = this.#scrollHost.clientHeight;\n this.#surface.style.width = `${width}px`;\n this.#surface.style.height = `${height}px`;\n this.controller.updateViewport({\n width,\n height,\n scrollLeft: this.#scrollHost.scrollLeft,\n scrollTop: this.#scrollHost.scrollTop,\n devicePixelRatio: this.#ownerWindow.devicePixelRatio || 1,\n });\n }\n\n #scheduleFrame(): void {\n if (this.#destroyed || this.#frame !== 0) {\n return;\n }\n this.#frame = this.#ownerWindow.requestAnimationFrame(() => {\n this.#frame = 0;\n this.#render();\n });\n }\n\n async #applyPresentation(table: TableHandle): Promise<void> {\n try {\n const presentation = await table.getPresentation();\n if (this.#destroyed || presentation === null) {\n return;\n }\n this.#presentation = presentation;\n this.#applySpreadsheetPresentation(presentation);\n } catch (error) {\n // Presentation is an enhancement over the logical table contract. A\n // malformed or unavailable layout must not make the table inaccessible.\n if (!this.#destroyed) {\n this.#onError?.(error);\n }\n }\n }\n\n #applySpreadsheetPresentation(presentation: SpreadsheetPresentation): void {\n this.element.dataset.tabularkPresentation = presentation.kind;\n this.element.dataset.tabularkWorksheetVisibility = presentation.visibility;\n this.element.dataset.tabularkFrozenRows = String(presentation.frozenRows);\n this.element.dataset.tabularkFrozenColumns = String(presentation.frozenColumns);\n\n this.controller.applySpreadsheetPresentation(presentation);\n this.#schedulePresentationRanges();\n this.#scheduleFrame();\n }\n\n #schedulePresentationRanges(): void {\n const table = this.#presentationTable;\n const presentation = this.#presentation;\n if (this.#destroyed || table === undefined || presentation === null) return;\n const requests = presentationRequests(this.#snapshot.layout);\n const key = `${presentation.tableId}:${presentation.revision}:${requests.map(rangeKey).join(\"|\")}`;\n if (key === this.#presentationRequestKey) return;\n this.#presentationRequestKey = key;\n this.#presentationAbort?.abort();\n this.#presentationAbort = null;\n if (requests.length === 0) {\n this.#presentationRanges = [];\n this.#mergedCells = [];\n this.controller.setMergedCells([]);\n this.#scheduleFrame();\n return;\n }\n const abort = new AbortController();\n this.#presentationAbort = abort;\n void (async () => {\n const viewportRanges = await Promise.all(requests.map((request) => (\n table.readPresentationRange(request, { signal: abort.signal })\n )));\n const currentRanges = viewportRanges.filter(\n (range): range is PresentationRange => range !== null\n && range.revision === presentation.revision,\n );\n const anchorRequests = missingMergeAnchorRequests(\n collectMergedRegions(currentRanges),\n currentRanges,\n );\n const anchorRanges = await Promise.all(anchorRequests.map((request) => (\n table.readPresentationRange(request, { signal: abort.signal })\n )));\n return [...viewportRanges, ...anchorRanges];\n })().then((ranges) => {\n if (\n this.#destroyed\n || abort.signal.aborted\n || this.#presentationAbort !== abort\n || this.#presentationRequestKey !== key\n ) {\n return;\n }\n this.#presentationAbort = null;\n this.#presentationRanges = Object.freeze(ranges.filter(\n (range): range is PresentationRange => range !== null\n && range.revision === presentation.revision,\n ));\n this.#mergedCells = collectMergedRegions(this.#presentationRanges);\n this.controller.setMergedCells(this.#mergedCells);\n this.#scheduleFrame();\n }).catch((error) => {\n if (this.#presentationAbort === abort) this.#presentationAbort = null;\n if (\n this.#destroyed\n || abort.signal.aborted\n || (error instanceof TabularkError && error.code === \"CANCELLED\")\n ) {\n return;\n }\n this.#onError?.(error);\n });\n }\n\n #mergedRegions(): readonly MergedCellRegion[] {\n return this.#mergedCells;\n }\n\n #render(): void {\n if (this.#destroyed) {\n return;\n }\n const snapshot = this.#snapshot;\n const layout = snapshot.layout;\n this.#spacer.style.width = `${Math.max(layout.width, layout.spacerWidth)}px`;\n this.#spacer.style.height = `${Math.max(layout.height, layout.spacerHeight)}px`;\n this.#surface.style.width = `${layout.width}px`;\n this.#surface.style.height = `${layout.height}px`;\n this.#syncNativeScroll(snapshot);\n\n const columns: readonly CanvasPaintColumn[] = layout.overscanColumns.map((column) => ({\n index: column.index,\n name: column.name,\n x: column.x,\n width: column.width,\n frozen: column.frozen,\n }));\n const rows = this.#paintRows(snapshot, columns);\n const mergedCells = this.#paintMergedCells();\n this.#painter.paint({\n width: layout.width,\n height: layout.height,\n headerHeight: layout.headerHeight,\n rowGutterWidth: layout.rowHeaderWidth,\n columns,\n rows,\n mergedCells,\n ...(snapshot.selection === null ? {} : { selection: snapshot.selection.range }),\n ...(snapshot.activeCell === null\n ? {}\n : {\n activeCell: {\n rowIndex: snapshot.activeCell.rowIndex,\n columnIndex: snapshot.activeCell.columnIndex,\n },\n }),\n busy: snapshot.status === \"loading\",\n });\n this.#renderResizeHandles(snapshot);\n this.#renderAccessibleGrid(snapshot);\n this.#renderMessage(snapshot);\n }\n\n #paintRows(\n snapshot: Readonly<TableViewSnapshot>,\n columns: readonly CanvasPaintColumn[],\n ): readonly CanvasPaintRow[] {\n const layout = snapshot.layout;\n const rows: CanvasPaintRow[] = [];\n for (const row of layout.overscanRows) {\n const rowIndex = row.index;\n rows.push({\n index: rowIndex,\n y: row.y,\n height: row.height,\n frozen: row.frozen,\n cells: columns.map((column) => {\n const cell = this.controller.getCell(rowIndex, column.index);\n return {\n columnIndex: column.index,\n value: cell.status === \"loaded\" ? cell.value : undefined,\n ...(this.#styleAt(rowIndex, column.index) === undefined\n ? {}\n : { style: this.#styleAt(rowIndex, column.index)! }),\n ...(this.#mergeContaining(rowIndex, column.index) === undefined\n ? {}\n : { coveredByMerge: true }),\n };\n }),\n });\n }\n return rows;\n }\n\n #paintMergedCells(): readonly CanvasPaintMergedCell[] {\n const result: CanvasPaintMergedCell[] = [];\n const layout = this.#snapshot.layout;\n for (const region of this.#mergedRegions()) {\n const cell = this.controller.getCell(region.rowStart, region.columnStart);\n const style = this.#styleAt(region.rowStart, region.columnStart);\n for (const fragment of splitMergedRegion(\n region,\n layout.frozenRowCount,\n layout.frozenColumnCount,\n )) {\n const first = this.controller.cellRect({\n rowIndex: fragment.rowStart,\n columnIndex: fragment.columnStart,\n });\n const last = this.controller.cellRect({\n rowIndex: fragment.rowEnd - 1,\n columnIndex: fragment.columnEnd - 1,\n });\n const clip = mergePaneClip(layout, fragment);\n const x = Math.max(first.x, clip.left);\n const y = Math.max(first.y, clip.top);\n const right = Math.min(last.x + last.width, clip.right);\n const bottom = Math.min(last.y + last.height, clip.bottom);\n if (right <= x || bottom <= y) continue;\n result.push(Object.freeze({\n region,\n x,\n y,\n width: right - x,\n height: bottom - y,\n value: cell.status === \"loaded\" ? cell.value : undefined,\n ...(style === undefined ? {} : { style }),\n ...(fragment.rowStart === region.rowStart\n && fragment.columnStart === region.columnStart\n ? {}\n : { continuation: true }),\n }));\n }\n }\n return Object.freeze(result);\n }\n\n #styleAt(rowIndex: number, columnIndex: number): PresentationStyle | undefined {\n const presentation = this.#presentation;\n if (presentation === null) return undefined;\n for (const window of this.#presentationRanges) {\n const range = window.range;\n if (\n rowIndex < range.rowStart\n || rowIndex >= range.rowStart + range.rowCount\n || columnIndex < range.columnStart\n || columnIndex >= range.columnStart + range.columnCount\n ) {\n continue;\n }\n const id = window.styleIds[rowIndex - range.rowStart]?.[columnIndex - range.columnStart];\n return id === null || id === undefined ? undefined : presentation.styles[id];\n }\n return undefined;\n }\n\n #mergeContaining(rowIndex: number, columnIndex: number): MergedCellRegion | undefined {\n return this.#mergedRegions().find((region) => (\n rowIndex >= region.rowStart\n && rowIndex < region.rowEnd\n && columnIndex >= region.columnStart\n && columnIndex < region.columnEnd\n ));\n }\n\n #renderResizeHandles(snapshot: Readonly<TableViewSnapshot>): void {\n const visibleIds = new Set<string>();\n if (this.#isTerminal()) {\n this.#removeStaleResizeHandles(visibleIds);\n return;\n }\n for (const column of snapshot.layout.visibleColumns) {\n const boundary = column.x + column.width;\n if (boundary < snapshot.layout.rowHeaderWidth || boundary > snapshot.layout.width) {\n continue;\n }\n visibleIds.add(column.id);\n let handle = this.#resizeHandles.get(column.id);\n if (handle === undefined) {\n handle = this.element.ownerDocument.createElement(\"div\");\n handle.setAttribute(\"role\", \"separator\");\n handle.setAttribute(\"aria-orientation\", \"vertical\");\n handle.setAttribute(\"aria-controls\", this.#accessibleGrid.element.id);\n handle.setAttribute(\"aria-describedby\", this.#resizeInstructions.id);\n handle.setAttribute(\"aria-keyshortcuts\", \"ArrowLeft ArrowRight Home End Enter\");\n handle.tabIndex = 0;\n Object.assign(handle.style, {\n background: \"transparent\",\n boxSizing: \"border-box\",\n cursor: \"col-resize\",\n outline: \"none\",\n pointerEvents: \"auto\",\n position: \"absolute\",\n top: \"0\",\n touchAction: \"none\",\n width: `${RESIZE_TARGET_SIZE}px`,\n });\n const line = this.element.ownerDocument.createElement(\"div\");\n line.dataset.tabularkResizeLine = \"\";\n line.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(line.style, {\n pointerEvents: \"none\",\n position: \"absolute\",\n top: \"0\",\n });\n handle.append(line);\n this.#resizeHandles.set(column.id, handle);\n this.#resizeLayer.append(handle);\n }\n handle.dataset.columnResize = String(column.index);\n handle.dataset.columnId = column.id;\n handle.setAttribute(\"aria-label\", `Resize ${column.name} column`);\n handle.setAttribute(\"aria-valuemin\", String(this.controller.minColumnWidth));\n handle.setAttribute(\"aria-valuemax\", String(this.controller.maxColumnWidth));\n handle.setAttribute(\"aria-valuenow\", String(column.width));\n handle.setAttribute(\"aria-valuetext\", `${formatWidth(column.width)} CSS pixels`);\n Object.assign(handle.style, {\n height: `${Math.max(RESIZE_TARGET_SIZE, snapshot.layout.headerHeight)}px`,\n left: `${boundary - RESIZE_TARGET_SIZE / 2}px`,\n });\n const line = handle.firstElementChild as HTMLElement | null;\n if (line !== null) {\n Object.assign(line.style, {\n background: this.#theme.gridLine,\n height: `${snapshot.layout.headerHeight}px`,\n left: `${(RESIZE_TARGET_SIZE - (this.#forcedColors ? 2 : 1)) / 2}px`,\n width: `${this.#forcedColors ? 2 : 1}px`,\n });\n }\n }\n this.#resizeLayer.style.height = `${Math.max(RESIZE_TARGET_SIZE, snapshot.layout.headerHeight)}px`;\n this.#removeStaleResizeHandles(visibleIds);\n }\n\n #removeStaleResizeHandles(visibleIds: ReadonlySet<string>): void {\n for (const [columnId, handle] of this.#resizeHandles) {\n if (visibleIds.has(columnId)) {\n continue;\n }\n if (handle.contains(this.element.ownerDocument.activeElement)) {\n this.#accessibleGrid.focus({ preventScroll: true });\n }\n handle.remove();\n this.#resizeHandles.delete(columnId);\n }\n }\n\n #renderAccessibleGrid(snapshot: Readonly<TableViewSnapshot>): void {\n const layout = snapshot.layout;\n const visibleRowIndexes = new Set(layout.visibleRows.map((row) => row.index));\n const visibleColumnIndexes = new Set(layout.visibleColumns.map((column) => column.index));\n const accessibleMerges = this.#mergedRegions().filter((region) => (\n layout.visibleRows.some((row) => row.index >= region.rowStart && row.index < region.rowEnd)\n && layout.visibleColumns.some(\n (column) => column.index >= region.columnStart && column.index < region.columnEnd,\n )\n ));\n const columnIndexes = new Set(visibleColumnIndexes);\n const rowIndexes = new Set(visibleRowIndexes);\n for (const merge of accessibleMerges) {\n columnIndexes.add(merge.columnStart);\n rowIndexes.add(merge.rowStart);\n }\n const columns = [...columnIndexes]\n .sort((left, right) => left - right)\n .map((index) => ({\n index,\n name: snapshot.metadata.schema.columns[index]?.name ?? `Column ${index + 1}`,\n }));\n const rows: AccessibleGridRow[] = [];\n for (const rowIndex of [...rowIndexes].sort((left, right) => left - right)) {\n const candidateColumns = new Set<number>();\n if (visibleRowIndexes.has(rowIndex)) {\n for (const columnIndex of visibleColumnIndexes) candidateColumns.add(columnIndex);\n }\n for (const merge of accessibleMerges) {\n if (merge.rowStart === rowIndex) candidateColumns.add(merge.columnStart);\n }\n rows.push({\n index: rowIndex,\n cells: [...candidateColumns]\n .sort((left, right) => left - right)\n .flatMap((columnIndex) => {\n const merge = this.#mergeContaining(rowIndex, columnIndex);\n if (\n merge !== undefined\n && (rowIndex !== merge.rowStart || columnIndex !== merge.columnStart)\n ) {\n return [];\n }\n const cell = this.controller.getCell(rowIndex, columnIndex);\n return [{\n rowIndex,\n columnIndex,\n value: cell.status === \"loaded\" ? cell.value : undefined,\n selected: snapshot.selection !== null && containsCell(\n snapshot.selection.range,\n { rowIndex, columnIndex },\n ),\n active: snapshot.activeCell?.rowIndex === rowIndex\n && snapshot.activeCell.columnIndex === columnIndex,\n ...(merge === undefined ? {} : {\n rowSpan: merge.rowEnd - merge.rowStart,\n columnSpan: merge.columnEnd - merge.columnStart,\n }),\n }];\n }),\n });\n }\n this.#accessibleGrid.update({\n label: this.#tableLabel(),\n ...(snapshot.metadata.extent.rows.kind === \"exact\"\n ? { exactRowCount: snapshot.metadata.extent.rows.value }\n : {}),\n columnCount: layout.columnCount,\n columns,\n rows,\n busy: snapshot.status === \"loading\",\n status: this.#statusText(snapshot),\n });\n }\n\n #renderMessage(snapshot: Readonly<TableViewSnapshot>): void {\n let message = \"\";\n if (snapshot.status === \"error\") {\n message = `Unable to render table: ${errorMessage(snapshot.error)}`;\n } else if (snapshot.status === \"closed\") {\n message = \"Table closed.\";\n } else if (snapshot.layout.rowCount === 0 && snapshot.status === \"ready\") {\n message = \"No rows to display.\";\n } else if (snapshot.status === \"loading\" && snapshot.layout.rows.visible.start === snapshot.layout.rows.visible.end) {\n message = \"Loading data\u2026\";\n }\n this.#message.textContent = message;\n this.#message.style.display = message === \"\" ? \"none\" : \"flex\";\n }\n\n #syncNativeScroll(snapshot: Readonly<TableViewSnapshot>): void {\n const desiredLeft = snapshot.layout.horizontal.physicalOffset;\n const desiredTop = snapshot.layout.vertical.physicalOffset;\n if (Math.abs(this.#scrollHost.scrollLeft - desiredLeft) > 0.5) {\n this.#scrollHost.scrollLeft = desiredLeft;\n }\n if (Math.abs(this.#scrollHost.scrollTop - desiredTop) > 0.5) {\n this.#scrollHost.scrollTop = desiredTop;\n }\n }\n\n #cellFromHit(hit: ReturnType<TableViewController[\"hitTest\"]>): Readonly<CellPosition> | null {\n if (hit.kind === \"cell\") {\n return Object.freeze({ rowIndex: hit.rowIndex, columnIndex: hit.columnIndex });\n }\n if (hit.kind === \"row-header\" && this.#snapshot.layout.columnCount > 0) {\n return Object.freeze({\n rowIndex: hit.rowIndex,\n columnIndex: this.#snapshot.activeCell?.columnIndex ?? 0,\n });\n }\n if (hit.kind === \"column-header\" && this.#snapshot.layout.rowCount > 0) {\n return Object.freeze({\n rowIndex: this.#snapshot.activeCell?.rowIndex ?? 0,\n columnIndex: hit.columnIndex,\n });\n }\n return null;\n }\n\n #eventPosition(event: MouseEvent | PointerEvent): Readonly<{ x: number; y: number }> {\n const rect = this.#surface.getBoundingClientRect();\n return Object.freeze({ x: event.clientX - rect.left, y: event.clientY - rect.top });\n }\n\n #resizeColumnFromTarget(target: EventTarget | null): number | null {\n const handle = this.#resizeHandleFromTarget(target);\n if (handle === null) {\n return null;\n }\n const value = handle.dataset.columnResize;\n if (value === undefined) {\n return null;\n }\n const columnIndex = Number(value);\n return Number.isSafeInteger(columnIndex) ? columnIndex : null;\n }\n\n #resizeHandleFromTarget(target: EventTarget | null): HTMLDivElement | null {\n if (!(target instanceof this.#ownerWindow.HTMLElement)) {\n return null;\n }\n const handle = target.closest<HTMLElement>(\"[data-column-resize]\");\n return handle instanceof this.#ownerWindow.HTMLDivElement && this.#resizeLayer.contains(handle)\n ? handle\n : null;\n }\n\n #measureColumn(columnIndex: number): number {\n const context = this.#canvas.getContext(\"2d\");\n if (context === null) {\n return this.controller.columnWidths[columnIndex]!;\n }\n const column = this.#snapshot.metadata.schema.columns[columnIndex];\n if (column === undefined) {\n return this.controller.columnWidths[columnIndex]!;\n }\n context.save();\n context.font = this.#theme.headerFont;\n let width = context.measureText(column.name).width;\n context.font = this.#theme.font;\n const visible = this.#snapshot.layout.rows.visible;\n for (let rowIndex = visible.start; rowIndex < visible.end; rowIndex += 1) {\n const cell = this.controller.getCell(rowIndex, columnIndex);\n if (cell.status === \"loaded\") {\n width = Math.max(width, context.measureText(cell.value ?? \"\u2205\").width);\n }\n }\n context.restore();\n return Math.ceil(width + AUTOSIZE_HORIZONTAL_PADDING);\n }\n\n async #copySelection(): Promise<void> {\n this.#copyAbort?.abort();\n const abort = new AbortController();\n this.#copyAbort = abort;\n try {\n const text = await this.controller.copySelection({ signal: abort.signal });\n if (abort.signal.aborted || this.#destroyed || text === \"\") {\n return;\n }\n if (this.#writeClipboard !== undefined) {\n await this.#writeClipboard(text);\n } else {\n const clipboard = this.#ownerWindow.navigator.clipboard;\n if (clipboard === undefined) {\n throw new Error(\"Clipboard access is unavailable in this browser context\");\n }\n await clipboard.writeText(text);\n }\n this.#accessibleGrid.statusElement.textContent = \"Selection copied to clipboard.\";\n } catch (error) {\n if (!abort.signal.aborted) {\n this.#accessibleGrid.statusElement.textContent = `Copy failed: ${errorMessage(error)}`;\n this.#reportError(error);\n }\n } finally {\n if (this.#copyAbort === abort) {\n this.#copyAbort = null;\n }\n }\n }\n\n #statusText(snapshot: Readonly<TableViewSnapshot>): string {\n if (snapshot.status === \"error\") {\n return `Table error: ${errorMessage(snapshot.error)}`;\n }\n if (snapshot.status === \"closed\") {\n return \"Table closed.\";\n }\n if (snapshot.status === \"loading\") {\n return \"Loading visible table cells.\";\n }\n return `${snapshot.layout.rowCount} rows and ${snapshot.layout.columnCount} columns.`;\n }\n\n #announceColumnWidth(columnIndex: number, fitted: boolean): void {\n const column = this.#snapshot.metadata.schema.columns[columnIndex];\n const width = this.controller.columnWidths[columnIndex];\n if (column === undefined || width === undefined) {\n return;\n }\n if (this.#announcementFrame !== 0) {\n this.#ownerWindow.cancelAnimationFrame(this.#announcementFrame);\n }\n const action = fitted ? \"fit to\" : \"width\";\n const qualifier = fitted ? \" using visible content\" : \"\";\n this.#announcementFrame = this.#ownerWindow.requestAnimationFrame(() => {\n this.#announcementFrame = 0;\n if (!this.#destroyed) {\n this.#accessibleGrid.statusElement.textContent = `${column.name} column ${action} ${formatWidth(width)} CSS pixels${qualifier}.`;\n }\n });\n }\n\n #applyThemeToElements(): void {\n this.element.dataset.tabularkForcedColors = this.#forcedColors ? \"active\" : \"none\";\n this.element.style.background = this.#theme.background;\n this.element.style.borderColor = this.#theme.gridLine;\n this.element.style.color = this.#theme.foreground;\n this.#message.style.background = this.#theme.background;\n this.#message.style.color = this.#theme.mutedForeground;\n this.#canvas.style.forcedColorAdjust = this.#forcedColors ? \"none\" : \"auto\";\n if (this.element.contains(this.element.ownerDocument.activeElement)) {\n this.element.style.outline = `2px solid ${this.#focusColor()}`;\n const handle = this.#resizeHandleFromTarget(this.element.ownerDocument.activeElement);\n if (handle !== null) {\n handle.style.outline = `2px solid ${this.#focusColor()}`;\n }\n }\n }\n\n #focusColor(): string {\n return this.#forcedColors ? \"Highlight\" : this.#theme.activeCellBorder;\n }\n\n #tableLabel(): string {\n return `${this.controller.metadata.name || \"Data\"} table`;\n }\n\n #hasCells(): boolean {\n return this.#snapshot.layout.rowCount > 0 && this.#snapshot.layout.columnCount > 0;\n }\n\n #isTerminal(): boolean {\n return this.#destroyed\n || this.#snapshot.status === \"error\"\n || this.#snapshot.status === \"closed\";\n }\n\n #cancelInteraction(): void {\n if (this.#interaction !== null && this.#surface.hasPointerCapture(this.#interaction.pointerId)) {\n this.#surface.releasePointerCapture(this.#interaction.pointerId);\n }\n this.#interaction = null;\n this.#surface.style.cursor = \"default\";\n }\n\n #reportError(error: unknown): void {\n if (this.#onError !== undefined) {\n this.#onError(error);\n } else if (typeof this.#ownerWindow.reportError === \"function\") {\n this.#ownerWindow.reportError(error);\n }\n }\n\n #assertAlive(): void {\n if (this.#destroyed) {\n throw new Error(\"Canvas table view is destroyed\");\n }\n }\n}\n\nfunction splitMergedRegion(\n region: MergedCellRegion,\n frozenRowCount: number,\n frozenColumnCount: number,\n): readonly Readonly<MergedCellRegion>[] {\n const rows = splitIndexRange(region.rowStart, region.rowEnd, frozenRowCount);\n const columns = splitIndexRange(region.columnStart, region.columnEnd, frozenColumnCount);\n return Object.freeze(rows.flatMap((row) => columns.map((column) => Object.freeze({\n rowStart: row.start,\n rowEnd: row.end,\n columnStart: column.start,\n columnEnd: column.end,\n }))));\n}\n\nfunction splitIndexRange(\n start: number,\n end: number,\n boundary: number,\n): readonly Readonly<{ start: number; end: number }>[] {\n if (boundary <= start || boundary >= end) {\n return Object.freeze([Object.freeze({ start, end })]);\n }\n return Object.freeze([\n Object.freeze({ start, end: boundary }),\n Object.freeze({ start: boundary, end }),\n ]);\n}\n\nfunction mergePaneClip(\n layout: Readonly<TableViewSnapshot>[\"layout\"],\n fragment: MergedCellRegion,\n): Readonly<{ left: number; top: number; right: number; bottom: number }> {\n const frozenRight = layout.rowHeaderWidth\n + Math.min(layout.bodyWidth, layout.frozenColumnExtent);\n const frozenBottom = layout.headerHeight\n + Math.min(layout.bodyHeight, layout.frozenRowExtent);\n const frozenColumn = fragment.columnStart < layout.frozenColumnCount;\n const frozenRow = fragment.rowStart < layout.frozenRowCount;\n return Object.freeze({\n left: frozenColumn ? layout.rowHeaderWidth : frozenRight,\n right: frozenColumn ? frozenRight : layout.rowHeaderWidth + layout.bodyWidth,\n top: frozenRow ? layout.headerHeight : frozenBottom,\n bottom: frozenRow ? frozenBottom : layout.headerHeight + layout.bodyHeight,\n });\n}\n\nfunction presentationRequests(\n layout: Readonly<TableViewSnapshot>[\"layout\"],\n): readonly Readonly<RangeRequest>[] {\n const overscan = presentationRectangles(\n layout.rows.overscan,\n layout.columns.overscan,\n layout.frozenRowRange,\n layout.frozenColumnRange,\n );\n const overscanCells = overscan.reduce(\n (total, range) => total + range.rowCount * range.columnCount,\n 0,\n );\n if (overscanCells <= MAX_PRESENTATION_WINDOW_CELLS) return overscan;\n return presentationRectangles(\n layout.rows.visible,\n layout.columns.visible,\n layout.frozenRowRange,\n layout.frozenColumnRange,\n );\n}\n\nfunction presentationRectangles(\n rows: Readonly<{ start: number; end: number }>,\n columns: Readonly<{ start: number; end: number }>,\n frozenRows: Readonly<{ start: number; end: number }>,\n frozenColumns: Readonly<{ start: number; end: number }>,\n): readonly Readonly<RangeRequest>[] {\n const requests: RangeRequest[] = [];\n for (const row of presentationBands(rows, frozenRows)) {\n for (const column of presentationBands(columns, frozenColumns)) {\n requests.push(Object.freeze({\n rowStart: row.start,\n rowCount: row.end - row.start,\n columnStart: column.start,\n columnCount: column.end - column.start,\n }));\n }\n }\n return Object.freeze(requests);\n}\n\nfunction presentationBands(\n primary: Readonly<{ start: number; end: number }>,\n frozen: Readonly<{ start: number; end: number }>,\n): readonly Readonly<{ start: number; end: number }>[] {\n const bands = [primary, frozen]\n .filter((range) => range.start < range.end)\n .sort((left, right) => left.start - right.start);\n if (bands.length < 2) return Object.freeze(bands.map((range) => Object.freeze({ ...range })));\n const first = bands[0]!;\n const second = bands[1]!;\n return first.end >= second.start\n ? Object.freeze([Object.freeze({ start: first.start, end: Math.max(first.end, second.end) })])\n : Object.freeze(bands.map((range) => Object.freeze({ ...range })));\n}\n\nfunction rangeKey(range: RangeRequest): string {\n return `${range.rowStart}:${range.rowCount}:${range.columnStart}:${range.columnCount}`;\n}\n\nfunction mergeKey(region: MergedCellRegion): string {\n return `${region.rowStart}:${region.rowEnd}:${region.columnStart}:${region.columnEnd}`;\n}\n\nfunction collectMergedRegions(\n ranges: readonly PresentationRange[],\n): readonly MergedCellRegion[] {\n const unique = new Map<string, MergedCellRegion>();\n for (const window of ranges) {\n for (const region of window.mergedCells) unique.set(mergeKey(region), region);\n }\n return Object.freeze([...unique.values()]);\n}\n\nfunction missingMergeAnchorRequests(\n regions: readonly MergedCellRegion[],\n ranges: readonly PresentationRange[],\n): readonly Readonly<RangeRequest>[] {\n const requests = new Map<string, Readonly<RangeRequest>>();\n for (const region of regions) {\n const anchorLoaded = ranges.some((window) => (\n region.rowStart >= window.range.rowStart\n && region.rowStart < window.range.rowStart + window.range.rowCount\n && region.columnStart >= window.range.columnStart\n && region.columnStart < window.range.columnStart + window.range.columnCount\n ));\n if (anchorLoaded) continue;\n const request = Object.freeze({\n rowStart: region.rowStart,\n rowCount: 1,\n columnStart: region.columnStart,\n columnCount: 1,\n });\n requests.set(`${region.rowStart}:${region.columnStart}`, request);\n }\n return Object.freeze([...requests.values()]);\n}\n\n/** Mounts an accessible, viewport-driven Canvas preview. */\nexport function createCanvasTableView(options: CanvasTableViewOptions): CanvasTableView {\n if (!options || !options.container || typeof options.container.append !== \"function\") {\n throw invalidArgument(\"container must be an HTMLElement\");\n }\n const hasTable = options.table !== undefined;\n const hasController = options.controller !== undefined;\n if (hasTable === hasController) {\n throw invalidArgument(\"provide exactly one of table or controller\");\n }\n return new View(options);\n}\n\nfunction keyboardCommand(event: KeyboardEvent): NavigationCommand | null {\n switch (event.key) {\n case \"ArrowLeft\":\n return \"left\";\n case \"ArrowRight\":\n return \"right\";\n case \"ArrowUp\":\n return \"up\";\n case \"ArrowDown\":\n return \"down\";\n case \"PageUp\":\n return \"page-up\";\n case \"PageDown\":\n return \"page-down\";\n case \"Home\":\n return event.ctrlKey || event.metaKey ? \"table-start\" : \"row-start\";\n case \"End\":\n return event.ctrlKey || event.metaKey ? \"table-end\" : \"row-end\";\n default:\n return null;\n }\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return typeof error === \"string\" ? error : \"Unknown error\";\n}\n\nfunction formatWidth(width: number): string {\n return Number.isInteger(width)\n ? String(width)\n : width.toFixed(2).replace(/(?:\\.0+|(?<decimal>\\.\\d*?)0+)$/, \"$<decimal>\");\n}\n\nfunction visuallyHide(element: HTMLElement): void {\n Object.assign(element.style, {\n border: \"0\",\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"-1px\",\n overflow: \"hidden\",\n padding: \"0\",\n position: \"absolute\",\n whiteSpace: \"nowrap\",\n width: \"1px\",\n });\n}\n", "import type { TableHandle } from \"../client.js\";\nimport { createCanvasTableView as createInternalCanvasTableView } from \"./canvas-table-view.js\";\n\n/** Stable, high-level sizing and cache controls for the Canvas table view. */\nexport interface CanvasTableViewControllerOptions {\n readonly rowHeight?: number;\n readonly headerHeight?: number;\n readonly rowHeaderWidth?: number;\n readonly columnWidth?: number;\n readonly minColumnWidth?: number;\n readonly maxColumnWidth?: number;\n readonly columnWidths?: Readonly<Record<string, number>>;\n readonly scrollPixelLimit?: number;\n readonly overscanRows?: number;\n readonly overscanColumns?: number;\n /** Hard bound for decoded render/cache cells. */\n readonly maxWindowCells?: number;\n}\n\n/** Stable theme tokens accepted by the high-level Canvas table view. */\nexport interface CanvasTableViewTheme {\n readonly background: string;\n readonly foreground: string;\n readonly mutedForeground: string;\n readonly headerBackground: string;\n readonly headerForeground: string;\n readonly alternateRowBackground: string;\n readonly gridLine: string;\n readonly selectionBackground: string;\n readonly selectionBorder: string;\n readonly activeCellBorder: string;\n readonly loadingBackground: string;\n readonly font: string;\n readonly headerFont: string;\n}\n\n/** Stable options for mounting a Canvas preview from a logical table handle. */\nexport interface CanvasTableViewOptions {\n readonly container: HTMLElement;\n readonly table: TableHandle;\n readonly controllerOptions?: CanvasTableViewControllerOptions;\n /**\n * Applies static spreadsheet presentation metadata when available.\n * Workbook colors never override the system palette in forced-colors mode.\n */\n readonly presentation?: \"auto\" | \"ignore\";\n readonly ariaLabel?: string;\n readonly theme?: Partial<CanvasTableViewTheme>;\n readonly maxDevicePixelRatio?: number;\n /** Testable clipboard seam; navigator.clipboard.writeText is used by default. */\n readonly writeClipboard?: (text: string) => Promise<void> | void;\n readonly onError?: (error: unknown) => void;\n}\n\n/** Stable lifecycle surface for a mounted Canvas table view. */\nexport interface CanvasTableView {\n readonly element: HTMLDivElement;\n focus(options?: FocusOptions): void;\n destroy(): void;\n dispose(): void;\n}\n\n/** Mounts an accessible, viewport-driven Canvas preview. */\nexport function createCanvasTableView(options: CanvasTableViewOptions): CanvasTableView {\n return createInternalCanvasTableView(options);\n}\n"],
5
- "mappings": "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",
6
- "names": ["isRecord", "isRecord", "isRecord", "isRecord", "offset", "numeric", "asUint8Array", "isRecord", "isRecord", "width", "columnIndex", "clampInteger", "positiveFinite", "positiveInteger", "byId", "nonNegativeFinite", "range", "visuallyHide", "position", "hit", "line", "mergeKey", "createCanvasTableView"]
3
+ "sources": ["../js/errors.ts", "../js/official-adapters.json", "../js/official-adapter-manifest.ts", "../js/adapters.ts", "../js/protocol.ts", "../js/model.ts", "../js/range-cache.ts", "../js/rpc-client.ts", "../js/range-source.ts", "../js/source.ts", "../js/client.ts", "../js/view/selection.ts", "../js/view/accessible-grid.ts", "../js/view/canvas-painter.ts", "../js/view/layout.ts", "../js/view/controller.ts", "../js/view/canvas-table-view.ts", "../js/view/canvas-table-view-public.ts"],
4
+ "sourcesContent": ["import type { SerializedError } from \"./protocol.js\";\n\nexport type TabularkErrorCode =\n | \"INVALID_ARGUMENT\"\n | \"INVALID_RANGE\"\n | \"RANGE_NOT_INDEXED\"\n | \"RESOURCE_LIMIT\"\n | \"CANCELLED\"\n | \"HANDLE_CLOSED\"\n | \"PROTOCOL_INCOMPATIBLE\"\n | \"PARSE_FAILED\"\n | \"UNSUPPORTED_FEATURE\"\n | \"UNSUPPORTED_RUNTIME\"\n | \"RUNTIME_FAILURE\"\n /** A remote/source provider could not be reached or did not return bytes. */\n | \"SOURCE_UNAVAILABLE\"\n /** The provider validator or total length changed while a reader was open. */\n | \"SOURCE_CHANGED\"\n /** The provider did not honor the required single-range protocol. */\n | \"RANGE_UNSUPPORTED\"\n | (string & {});\n\n/** A stable, serializable error returned by Tabulark. */\nexport class TabularkError extends Error {\n readonly code: TabularkErrorCode;\n readonly retryable: boolean;\n readonly details?: unknown;\n\n constructor(\n code: TabularkErrorCode,\n message: string,\n options: { retryable?: boolean; details?: unknown; cause?: unknown } = {},\n ) {\n super(message, { cause: options.cause });\n this.name = \"TabularkError\";\n this.code = code;\n this.retryable = options.retryable ?? false;\n this.details = code === \"RESOURCE_LIMIT\"\n ? normalizeResourceLimitDetails(options.details)\n : options.details;\n }\n\n static fromSerialized(error: SerializedError): TabularkError {\n return new TabularkError(error.code, error.message, {\n retryable: error.retryable,\n details: error.details,\n });\n }\n}\n\n/** @internal Ensures every resource-limit error has a stable capacity shape. */\nexport function normalizeResourceLimitDetails(details: unknown): Readonly<Record<string, unknown>> {\n const raw = isRecord(details) ? details : {};\n const resource = typeof raw.resource === \"string\" && raw.resource.length > 0\n ? raw.resource\n : typeof raw.resourceCategory === \"string\" && raw.resourceCategory.length > 0\n ? raw.resourceCategory\n : inferResource(raw);\n if (isQuantity(raw.requiredBytes) && isQuantity(raw.availableBytes)) {\n return Object.freeze({ ...raw, resource });\n }\n if (isQuantity(raw.required) && isQuantity(raw.available)) {\n return Object.freeze({ ...raw, resource });\n }\n\n const byteLimit = firstQuantity(raw, [\n \"maxDecodedBytes\",\n \"maxOutputBytes\",\n \"maxMetadataBytes\",\n \"maxBlockBytes\",\n \"maxDisplayCellBytes\",\n \"maxDisplayBytes\",\n \"maxSourceBytes\",\n \"maxFieldBytes\",\n \"maxBatchBytes\",\n \"maxOperationBytes\",\n \"maxZipEntryBytes\",\n \"maxZipUncompressedBytes\",\n \"maxCfbStreamBytes\",\n ]);\n if (byteLimit !== undefined) {\n const requiredBytes = firstQuantity(raw, [\n \"decodedBytes\",\n \"outputBytes\",\n \"metadataBytes\",\n \"blockBytes\",\n \"displayCellBytes\",\n \"displayBytes\",\n \"sourceBytes\",\n \"fieldBytes\",\n \"batchBytes\",\n \"operationBytes\",\n ]) ?? byteLimit + 1;\n return Object.freeze({\n ...raw,\n resource,\n requiredBytes,\n availableBytes: byteLimit,\n });\n }\n\n const available = firstQuantity(raw, [\n \"limit\",\n \"maxCells\",\n \"maxRangeCells\",\n \"maxSources\",\n \"maxActiveRanges\",\n \"maxRangeWaiters\",\n \"maxColumns\",\n \"maxFields\",\n \"maxNestingDepth\",\n \"maxWorksheetRows\",\n \"maxWorksheetColumns\",\n \"maxStyles\",\n \"maxMergedRegions\",\n ]) ?? 0;\n const required = firstQuantity(raw, [\n \"cells\",\n \"cellCount\",\n \"visibleCellCount\",\n \"sources\",\n \"activeRanges\",\n \"rangeWaiters\",\n \"columns\",\n \"fields\",\n \"nestingDepth\",\n \"worksheetRows\",\n \"worksheetColumns\",\n \"styles\",\n \"mergedRegions\",\n ]) ?? available + 1;\n return Object.freeze({ ...raw, resource, required, available });\n}\n\nfunction inferResource(details: Record<string, unknown>): string {\n const keys = Object.keys(details).join(\" \").toLowerCase();\n if (keys.includes(\"source\")) return keys.includes(\"byte\") ? \"source-staging\" : \"source-slots\";\n if (keys.includes(\"metadata\")) return \"metadata\";\n if (keys.includes(\"decoded\") || keys.includes(\"decompress\")) return \"decompression\";\n if (keys.includes(\"display\")) return \"display-values\";\n if (keys.includes(\"field\")) return \"field\";\n if (keys.includes(\"batch\")) return \"batch\";\n if (keys.includes(\"range\") || keys.includes(\"cell\")) return \"range-cells\";\n if (keys.includes(\"column\")) return \"columns\";\n if (keys.includes(\"nest\")) return \"descriptor-nesting\";\n if (keys.includes(\"worksheet\")) return \"worksheet-dimensions\";\n return \"adapter-resource\";\n}\n\nfunction firstQuantity(\n details: Record<string, unknown>,\n names: readonly string[],\n): number | undefined {\n for (const name of names) {\n if (isQuantity(details[name])) return details[name] as number;\n }\n return undefined;\n}\n\nfunction isQuantity(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function cancelledError(): TabularkError {\n return new TabularkError(\"CANCELLED\", \"The operation was cancelled\");\n}\n\nexport function closedError(resource: string): TabularkError {\n return new TabularkError(\"HANDLE_CLOSED\", `${resource} is closed`);\n}\n\nexport function invalidArgument(message: string, details?: unknown): TabularkError {\n return new TabularkError(\"INVALID_ARGUMENT\", message, { details });\n}\n", "{\n \"manifestVersion\": 1,\n \"adapters\": [\n {\n \"id\": \"tabulark:delimited\",\n \"entrypoint\": \".\",\n \"exportName\": \"delimitedAdapter\",\n \"wasm\": {\n \"packageName\": \"tabulark-delimited-wasm\",\n \"crateArtifact\": \"tabulark_delimited\",\n \"outputName\": \"tabulark_delimited\",\n \"outputDirectory\": \"dist/wasm/delimited\",\n \"modulePath\": \"./wasm/delimited/tabulark_delimited.js\",\n \"runtimeExport\": \"WasmRuntime\"\n },\n \"options\": {\n \"allowedKeys\": [\"dialect\", \"header\", \"mode\", \"delimiter\", \"sourceName\"]\n },\n \"resources\": {\n \"sourceAccess\": \"streaming\",\n \"supportsPresentation\": false,\n \"runtimeWeight\": 1\n }\n },\n {\n \"id\": \"tabulark:arrow-ipc\",\n \"entrypoint\": \"./arrow\",\n \"exportName\": \"arrowIpcAdapter\",\n \"wasm\": {\n \"packageName\": \"tabulark-arrow-wasm\",\n \"crateArtifact\": \"tabulark_arrow\",\n \"outputName\": \"tabulark_arrow\",\n \"outputDirectory\": \"dist/wasm/arrow\",\n \"modulePath\": \"./wasm/arrow/tabulark_arrow.js\",\n \"runtimeExport\": \"WasmRuntime\"\n },\n \"options\": {\n \"allowedKeys\": [\"container\", \"sourceName\"]\n },\n \"resources\": {\n \"sourceAccess\": \"range\",\n \"supportsPresentation\": false,\n \"runtimeWeight\": 1\n }\n },\n {\n \"id\": \"tabulark:parquet\",\n \"entrypoint\": \"./parquet\",\n \"exportName\": \"parquetAdapter\",\n \"wasm\": {\n \"packageName\": \"tabulark-parquet-wasm\",\n \"crateArtifact\": \"tabulark_parquet\",\n \"outputName\": \"tabulark_parquet\",\n \"outputDirectory\": \"dist/wasm/parquet\",\n \"modulePath\": \"./wasm/parquet/tabulark_parquet.js\",\n \"runtimeExport\": \"WasmRuntime\"\n },\n \"options\": {\n \"allowedKeys\": [\"sourceName\"]\n },\n \"resources\": {\n \"sourceAccess\": \"range\",\n \"supportsPresentation\": false,\n \"runtimeWeight\": 2\n }\n },\n {\n \"id\": \"tabulark:excel\",\n \"entrypoint\": \"./excel\",\n \"exportName\": \"excelAdapter\",\n \"wasm\": {\n \"packageName\": \"tabulark-excel-wasm\",\n \"crateArtifact\": \"tabulark_excel\",\n \"outputName\": \"tabulark_excel\",\n \"outputDirectory\": \"dist/wasm/excel\",\n \"modulePath\": \"./wasm/excel/tabulark_excel.js\",\n \"runtimeExport\": \"WasmRuntime\"\n },\n \"options\": {\n \"allowedKeys\": [\"format\", \"sourceName\"]\n },\n \"resources\": {\n \"sourceAccess\": \"range\",\n \"supportsPresentation\": true,\n \"runtimeWeight\": 2\n }\n }\n ]\n}\n", "import manifestJson from \"./official-adapters.json\" with { type: \"json\" };\n\nexport type OfficialAdapterId =\n | \"tabulark:delimited\"\n | \"tabulark:arrow-ipc\"\n | \"tabulark:parquet\"\n | \"tabulark:excel\";\nexport type OfficialSourceAccess = \"streaming\" | \"range\" | \"staged\";\n\nexport interface OfficialAdapterManifestEntry {\n readonly id: OfficialAdapterId;\n readonly entrypoint: \".\" | \"./arrow\" | \"./parquet\" | \"./excel\";\n readonly exportName: string;\n readonly wasm: Readonly<{\n readonly packageName: string;\n readonly crateArtifact: string;\n readonly outputName: string;\n readonly outputDirectory: string;\n readonly modulePath: string;\n readonly runtimeExport: \"WasmRuntime\";\n }>;\n readonly options: Readonly<{ readonly allowedKeys: readonly string[] }>;\n readonly resources: Readonly<{\n readonly sourceAccess: OfficialSourceAccess;\n readonly supportsPresentation: boolean;\n readonly runtimeWeight: number;\n }>;\n}\n\nconst manifestEntries = validateManifest(manifestJson);\n\n/** Runtime IDs are derived from the manifest rather than repeated in code. */\nexport const OFFICIAL_ADAPTER_IDS: readonly OfficialAdapterId[] = Object.freeze(\n manifestEntries.map((entry) => entry.id),\n);\n\n/** The sole internal source of truth for built-in IDs, artifacts and host policy. */\nexport const OFFICIAL_ADAPTER_MANIFEST: readonly OfficialAdapterManifestEntry[] = Object.freeze(\n manifestEntries.map((entry) => Object.freeze({\n ...entry,\n wasm: Object.freeze({ ...entry.wasm }),\n options: Object.freeze({\n allowedKeys: Object.freeze([...entry.options.allowedKeys]),\n }),\n resources: Object.freeze({ ...entry.resources }),\n })),\n);\n\nconst byId = new Map(OFFICIAL_ADAPTER_MANIFEST.map((entry) => [entry.id, entry]));\n\nexport function isOfficialAdapterId(value: unknown): value is OfficialAdapterId {\n return typeof value === \"string\" && byId.has(value as OfficialAdapterId);\n}\n\nexport function officialAdapterManifestEntry(id: OfficialAdapterId): OfficialAdapterManifestEntry {\n const entry = byId.get(id);\n if (!entry) {\n throw new TypeError(`Unknown official adapter: ${id}`);\n }\n return entry;\n}\n\n/** Resolves an official wrapper relative to the bundle that hosts this code. */\nexport function officialAdapterModuleUrl(id: OfficialAdapterId): string {\n return new URL(officialAdapterManifestEntry(id).wasm.modulePath, import.meta.url).href;\n}\n\nfunction validateManifest(value: unknown): readonly OfficialAdapterManifestEntry[] {\n if (!isRecord(value) || value.manifestVersion !== 1 || !Array.isArray(value.adapters)) {\n throw new TypeError(\"The official adapter manifest has an unsupported shape or version\");\n }\n if (value.adapters.length === 0) {\n throw new TypeError(\"The official adapter manifest must contain at least one adapter\");\n }\n const ids = new Set<string>();\n const entrypoints = new Set<string>();\n const outputDirectories = new Set<string>();\n return value.adapters.map((candidate, index) => {\n if (!isRecord(candidate)) {\n throw new TypeError(`Official adapter manifest entry ${index} must be an object`);\n }\n const { id, entrypoint, exportName, wasm, options, resources } = candidate;\n if (!isKnownOfficialAdapterId(id) || ids.has(id)) {\n throw new TypeError(`Official adapter manifest entry ${index} has an invalid or duplicate id`);\n }\n if (\n (entrypoint !== \".\" && entrypoint !== \"./arrow\" && entrypoint !== \"./parquet\" && entrypoint !== \"./excel\")\n || entrypoints.has(entrypoint)\n || typeof exportName !== \"string\"\n || exportName.length === 0\n ) {\n throw new TypeError(`Official adapter manifest entry ${index} has an invalid entrypoint or export`);\n }\n if (\n !isRecord(wasm)\n || typeof wasm.packageName !== \"string\"\n || typeof wasm.crateArtifact !== \"string\"\n || typeof wasm.outputName !== \"string\"\n || typeof wasm.outputDirectory !== \"string\"\n || !wasm.outputDirectory.startsWith(\"dist/wasm/\")\n || wasm.outputDirectory.includes(\"..\")\n || outputDirectories.has(wasm.outputDirectory)\n || typeof wasm.modulePath !== \"string\"\n || !wasm.modulePath.startsWith(\"./wasm/\")\n || wasm.modulePath.includes(\"..\")\n || wasm.modulePath.includes(\"?\")\n || wasm.modulePath.includes(\"#\")\n || wasm.runtimeExport !== \"WasmRuntime\"\n || wasm.modulePath !== `./${wasm.outputDirectory.replace(/^dist\\//u, \"\")}/${wasm.outputName}.js`\n ) {\n throw new TypeError(`Official adapter manifest entry ${index} has an invalid WASM artifact`);\n }\n if (\n !isRecord(options)\n || !Array.isArray(options.allowedKeys)\n || options.allowedKeys.some((key) => typeof key !== \"string\")\n || new Set(options.allowedKeys).size !== options.allowedKeys.length\n ) {\n throw new TypeError(`Official adapter manifest entry ${index} has invalid option keys`);\n }\n if (\n !isRecord(resources)\n || (resources.sourceAccess !== \"streaming\"\n && resources.sourceAccess !== \"range\"\n && resources.sourceAccess !== \"staged\")\n || typeof resources.supportsPresentation !== \"boolean\"\n || !Number.isSafeInteger(resources.runtimeWeight)\n || (resources.runtimeWeight as number) <= 0\n ) {\n throw new TypeError(`Official adapter manifest entry ${index} has an invalid resource policy`);\n }\n ids.add(id);\n entrypoints.add(entrypoint);\n outputDirectories.add(wasm.outputDirectory);\n return candidate as unknown as OfficialAdapterManifestEntry;\n });\n}\n\nfunction isKnownOfficialAdapterId(value: unknown): value is OfficialAdapterId {\n return value === \"tabulark:delimited\"\n || value === \"tabulark:arrow-ipc\"\n || value === \"tabulark:parquet\"\n || value === \"tabulark:excel\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n", "import {\n isOfficialAdapterId,\n officialAdapterManifestEntry,\n type OfficialAdapterId,\n} from \"./official-adapter-manifest.js\";\n\nexport type { OfficialAdapterId } from \"./official-adapter-manifest.js\";\n\nexport type DelimitedDialect = \"csv\" | \"tsv\";\nexport type HeaderMode = \"first-row\" | \"none\";\nexport type ParseMode = \"lenient\" | \"strict\";\n\n/** Options understood by the built-in delimited adapter. */\nexport interface DelimitedAdapterOptions {\n /** Defaults to `csv`. No filename-based selection is performed. */\n readonly dialect?: DelimitedDialect;\n readonly header?: HeaderMode;\n readonly mode?: ParseMode;\n /** One ASCII delimiter byte. Overrides the dialect default when supplied. */\n readonly delimiter?: string;\n /** Optional display name for the source. */\n readonly sourceName?: string;\n}\n\nexport type ArrowIpcContainer = \"auto\" | \"file\" | \"stream\";\n\n/** Options understood by the built-in Arrow IPC adapter. */\nexport interface ArrowIpcAdapterOptions {\n /** Defaults to `auto`; format detection belongs to the Arrow adapter. */\n readonly container?: ArrowIpcContainer;\n /** Optional display name for the source. */\n readonly sourceName?: string;\n}\n\n/** Options understood by the built-in Parquet adapter. */\nexport interface ParquetAdapterOptions {\n /** Optional display name for the source. */\n readonly sourceName?: string;\n}\n\nexport type ExcelFormat = \"auto\" | \"xls\" | \"xlsx\";\n\n/** Options understood by the built-in Excel adapter. */\nexport interface ExcelAdapterOptions {\n /** Defaults to `auto`; the adapter identifies the file from its signature. */\n readonly format?: ExcelFormat;\n /** Optional display name for the source. */\n readonly sourceName?: string;\n}\n\n/**\n * A frozen descriptor for one built-in adapter.\n *\n * Descriptors select a named official artifact only. They are deliberately not\n * factories and cannot carry a module URL or a third-party implementation.\n */\nexport interface AdapterDescriptor<\n Id extends OfficialAdapterId = OfficialAdapterId,\n Options = unknown,\n> {\n readonly id: Id;\n readonly kind: \"official\";\n /** Carries the option type without exposing a runtime extension point. */\n readonly __options?: Options;\n}\n\ninterface InternalAdapterDescriptor<\n Id extends OfficialAdapterId = OfficialAdapterId,\n Options = unknown,\n> extends AdapterDescriptor<Id, Options> {\n readonly [OFFICIAL_ADAPTER]: Readonly<{ readonly id: Id }>;\n}\n\n/**\n * A process-global symbol permits descriptors from separately bundled stable\n * entrypoints to be recognized. It conveys no capability: the manifest below\n * still owns the selected module URL and resource policy.\n */\nconst OFFICIAL_ADAPTER = Symbol.for(\"tabulark.official-adapter.v2\");\n\nexport interface AdapterRegistration {\n readonly id: OfficialAdapterId;\n}\n\nfunction createOfficialAdapter<Id extends OfficialAdapterId, Options>(\n id: Id,\n): AdapterDescriptor<Id, Options> {\n const marker = Object.freeze({ id });\n return Object.freeze({\n id,\n kind: \"official\" as const,\n [OFFICIAL_ADAPTER]: marker,\n }) as InternalAdapterDescriptor<Id, Options>;\n}\n\n/** The built-in RFC-style delimited text adapter. */\nexport const delimitedAdapter = createOfficialAdapter<\n \"tabulark:delimited\",\n DelimitedAdapterOptions\n>(\"tabulark:delimited\");\n\n/** @internal Used by the stable `/arrow` entrypoint. */\nexport function createArrowIpcAdapter(): AdapterDescriptor<\"tabulark:arrow-ipc\", ArrowIpcAdapterOptions> {\n return createOfficialAdapter<\"tabulark:arrow-ipc\", ArrowIpcAdapterOptions>(\"tabulark:arrow-ipc\");\n}\n\n/** @internal Used by the stable `/parquet` entrypoint. */\nexport function createParquetAdapter(): AdapterDescriptor<\"tabulark:parquet\", ParquetAdapterOptions> {\n return createOfficialAdapter<\"tabulark:parquet\", ParquetAdapterOptions>(\"tabulark:parquet\");\n}\n\n/** @internal Used by the stable `/excel` entrypoint. */\nexport function createExcelAdapter(): AdapterDescriptor<\"tabulark:excel\", ExcelAdapterOptions> {\n return createOfficialAdapter<\"tabulark:excel\", ExcelAdapterOptions>(\"tabulark:excel\");\n}\n\n/** @internal Validates and extracts the non-public Worker registration. */\nexport function resolveOfficialAdapter(value: unknown): AdapterRegistration | undefined {\n if (!isRecord(value) || !Object.isFrozen(value) || !isOfficialAdapterId(value.id) || value.kind !== \"official\") {\n return undefined;\n }\n const marker = value[OFFICIAL_ADAPTER];\n if (!isRecord(marker) || marker.id !== value.id) {\n return undefined;\n }\n // A marker may be recreated by another bundle, but it conveys no URL or\n // implementation capability: it can select only a manifest-owned ID.\n officialAdapterManifestEntry(value.id);\n return Object.freeze({ id: value.id });\n}\n\nfunction isRecord(value: unknown): value is Record<PropertyKey, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n", "/** Version 4 introduces resumable, revisioned operations and main-thread batch ownership. */\nexport const PROTOCOL_VERSION = 4 as const;\n\n/** Version of the private, built-in Rust adapter contract. */\nexport const ADAPTER_API_VERSION = 3 as const;\n\n/** Version of the descriptor + deduplicated-buffer batch transport. */\nexport const BATCH_LAYOUT_VERSION = 1 as const;\n\nexport type ProtocolVersion = typeof PROTOCOL_VERSION;\n\nexport type Operation =\n | \"hello\"\n | \"openSource\"\n | \"listTables\"\n | \"openTable\"\n | \"getMetadata\"\n | \"getPresentation\"\n | \"readPresentationRange\"\n | \"readRange\"\n | \"cancel\"\n | \"closeTable\"\n | \"closeSource\"\n | \"shutdown\";\n\nexport interface ProtocolRequest<T = unknown> {\n readonly protocolVersion: ProtocolVersion;\n readonly requestId: string;\n readonly op: Operation;\n readonly payload: T;\n}\n\nexport type ResponseKind =\n | \"hello\"\n | \"dataset\"\n | \"tables\"\n | \"table\"\n | \"metadata\"\n | \"presentation\"\n | \"presentationRange\"\n | \"batch\"\n | \"acknowledged\";\n\nexport interface ProtocolResult<T = unknown> {\n readonly kind: ResponseKind;\n readonly data?: T;\n}\n\nexport interface ProtocolSuccess<T = unknown> {\n readonly protocolVersion: ProtocolVersion;\n readonly requestId: string;\n readonly status: \"success\";\n readonly result: ProtocolResult<T>;\n}\n\nexport interface SerializedError {\n readonly code: string;\n readonly message: string;\n readonly retryable: boolean;\n readonly details?: unknown;\n}\n\nexport interface ProtocolFailure {\n readonly protocolVersion: ProtocolVersion;\n readonly requestId: string;\n readonly status: \"failure\";\n readonly error: SerializedError;\n}\n\nexport type ProtocolResponse<T = unknown> =\n | ProtocolSuccess<T>\n | ProtocolFailure;\n\nexport type RuntimeEventName =\n | \"progress\"\n | \"metadata\"\n | \"warning\"\n | \"closed\"\n | \"runtimeError\";\n\nexport interface ProtocolEvent<T = unknown> {\n readonly protocolVersion: ProtocolVersion;\n readonly requestId?: string;\n readonly event: RuntimeEventName;\n /** Required for dataset/table events; omitted only by a process-wide runtimeError. */\n readonly datasetHandle?: string;\n readonly tableHandle?: string;\n readonly tableId?: string;\n /** Revision associated with a table-scoped event, when known. */\n readonly revision?: number;\n readonly payload: T;\n}\n\nexport function isProtocolResponse(value: unknown): value is ProtocolResponse {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n value.protocolVersion === PROTOCOL_VERSION &&\n typeof value.requestId === \"string\" &&\n (value.status === \"success\" || value.status === \"failure\")\n );\n}\n\nexport function isProtocolEvent(value: unknown): value is ProtocolEvent {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n value.protocolVersion === PROTOCOL_VERSION &&\n typeof value.event === \"string\" &&\n \"payload\" in value\n );\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n", "import { TabularkError, invalidArgument } from \"./errors.js\";\nimport { BATCH_LAYOUT_VERSION } from \"./protocol.js\";\n\nexport const DEFAULT_MEMORY_BUDGET_BYTES = 256 * 1024 * 1024;\nexport const MAX_ARRAY_BUFFER_BYTES = 128 * 1024 * 1024;\nexport const MAX_RANGE_CELLS = 250_000;\nexport const DEFAULT_TO_ROWS_CELL_LIMIT = 10_000;\nexport const MAX_NESTING_DEPTH = 64;\n\nconst INDEX_BUDGET_MAX_BYTES = 64 * 1024 * 1024;\nconst ADAPTER_TILE_CACHE_MAX_BYTES = 96 * 1024 * 1024;\nconst MAIN_THREAD_RANGE_CACHE_MAX_BYTES = 32 * 1024 * 1024;\nconst FIELD_AND_BATCH_MAX_BYTES = 8 * 1024 * 1024;\n\n// Batch values are decoded one cell at a time by the logical facade. Reusing\n// these immutable helpers avoids constructing a TextDecoder/DataView for every\n// UTF-8 value and primitive read while keeping the cache weakly tied to the\n// transferred backing buffer's lifetime.\nconst UTF8_DECODER = new TextDecoder();\nconst DATA_VIEW_CACHE = new WeakMap<object, Map<number, Map<number, DataView>>>();\n\nexport const MAX_SOURCES = 2;\nexport const MAX_ACTIVE_RANGES = 2;\nexport const MAX_RANGE_WAITERS = 8;\n\nexport interface MemoryBudgetLimits {\n readonly memoryBudgetBytes: number;\n /** Cross-thread accounting slices used by RangeSource brokers. */\n readonly workerBudgetBytes: number;\n readonly mainThreadSourceBytes: number;\n readonly mainThreadRetainedBytes: number;\n readonly sourceRangeCacheBytes: number;\n /** Shared retained capacity allocated among the adapters actually registered. */\n readonly adapterRuntimePoolBytes: number;\n /** Maximum transient/decoded budget retained by one active adapter operation. */\n readonly operationBudgetBytes: number;\n readonly indexBudgetBytes: number;\n readonly adapterTileCacheBudgetBytes: number;\n readonly mainThreadRangeCacheBytes: number;\n readonly maxFieldBytes: number;\n readonly maxBatchBytes: number;\n readonly maxArrayBufferBytes: number;\n readonly maxSources: number;\n readonly maxActiveRanges: number;\n readonly maxRangeWaiters: number;\n}\n\n/** Derives every bounded runtime allocation from one engine-wide budget. */\nexport function deriveMemoryBudgetLimits(memoryBudgetBytes: number): MemoryBudgetLimits {\n assertPositiveSafeInteger(memoryBudgetBytes, \"memoryBudgetBytes\");\n const oneEighth = Math.floor(memoryBudgetBytes / 8);\n const oneThirtySecond = Math.floor(memoryBudgetBytes / 32);\n // The Worker allocates this pool through one reservation ledger using the\n // adapters actually registered for an engine. This deliberately avoids a\n // hard-coded split based on a historic number of built-in adapters.\n const adapterRuntimePoolBytes = Math.max(1, Math.floor(memoryBudgetBytes / 2));\n const operationBudgetBytes = Math.max(1, Math.floor(memoryBudgetBytes / 8));\n const workerBudgetBytes = Math.max(1, Math.floor(memoryBudgetBytes * 3 / 4));\n const mainThreadSourceBytes = Math.max(1, oneEighth);\n const mainThreadRetainedBytes = Math.max(\n 1,\n memoryBudgetBytes - workerBudgetBytes - mainThreadSourceBytes,\n );\n return Object.freeze({\n memoryBudgetBytes,\n workerBudgetBytes,\n mainThreadSourceBytes,\n mainThreadRetainedBytes,\n sourceRangeCacheBytes: Math.max(1, Math.floor(workerBudgetBytes / 8)),\n adapterRuntimePoolBytes,\n operationBudgetBytes,\n indexBudgetBytes: Math.min(INDEX_BUDGET_MAX_BYTES, oneEighth),\n adapterTileCacheBudgetBytes: Math.min(ADAPTER_TILE_CACHE_MAX_BYTES, operationBudgetBytes),\n mainThreadRangeCacheBytes: Math.min(MAIN_THREAD_RANGE_CACHE_MAX_BYTES, oneEighth),\n maxFieldBytes: Math.min(FIELD_AND_BATCH_MAX_BYTES, oneThirtySecond),\n maxBatchBytes: Math.min(FIELD_AND_BATCH_MAX_BYTES, oneThirtySecond),\n maxArrayBufferBytes: Math.min(MAX_ARRAY_BUFFER_BYTES, Math.floor(memoryBudgetBytes / 2)),\n maxSources: MAX_SOURCES,\n maxActiveRanges: MAX_ACTIVE_RANGES,\n maxRangeWaiters: MAX_RANGE_WAITERS,\n });\n}\n\nexport type MemoryResourceKind =\n | \"adapter-runtime\"\n | \"source-staging\"\n | \"compressed-page\"\n | \"decompression\"\n | \"batch\";\n\nexport interface MemoryReservation {\n readonly resource: MemoryResourceKind;\n readonly bytes: number;\n release(): void;\n}\n\n/**\n * Single-accounting ledger for Worker-owned bounded allocations.\n *\n * A reservation is deliberately idempotent so cancellation, close and failure\n * races can all execute their normal cleanup paths without double accounting.\n */\nexport class MemoryReservationLedger {\n readonly #capacityBytes: number;\n #usedBytes = 0;\n\n constructor(capacityBytes: number) {\n assertPositiveSafeInteger(capacityBytes, \"capacityBytes\");\n this.#capacityBytes = capacityBytes;\n }\n\n get capacityBytes(): number {\n return this.#capacityBytes;\n }\n\n get usedBytes(): number {\n return this.#usedBytes;\n }\n\n get availableBytes(): number {\n return this.#capacityBytes - this.#usedBytes;\n }\n\n reserve(resource: MemoryResourceKind, bytes: number): MemoryReservation {\n if (!Number.isSafeInteger(bytes) || bytes < 0) {\n throw invalidArgument(\"Reservation bytes must be a non-negative safe integer\");\n }\n const availableBytes = this.availableBytes;\n if (bytes > availableBytes) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `Insufficient memory reservation capacity for ${resource}`,\n { details: { resource, requiredBytes: bytes, availableBytes } },\n );\n }\n this.#usedBytes += bytes;\n let released = false;\n return Object.freeze({\n resource,\n bytes,\n release: () => {\n if (released) return;\n released = true;\n this.#usedBytes -= bytes;\n },\n });\n }\n}\n\nexport type AxisExtent =\n | Readonly<{ kind: \"exact\"; value: number }>\n | Readonly<{ kind: \"at-least\"; value: number }>\n | Readonly<{ kind: \"unknown\" }>;\n\nexport interface TableExtent {\n readonly rows: AxisExtent;\n readonly columns: AxisExtent;\n}\n\nexport type TimeUnit = \"second\" | \"millisecond\" | \"microsecond\" | \"nanosecond\";\nexport type IntervalUnit = \"year-month\" | \"day-time\" | \"month-day-nano\";\n\nexport interface ArrowField {\n readonly name: string;\n readonly nullable: boolean;\n readonly dataType: ArrowDataType;\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\ninterface SimpleDataType<Type extends string> {\n readonly type: Type;\n}\n\n/** A recursive representation of every arrow-schema 59.1.0 built-in DataType. */\nexport type ArrowDataType =\n | SimpleDataType<\n | \"null\"\n | \"unknown\"\n | \"boolean\"\n | \"int8\"\n | \"int16\"\n | \"int32\"\n | \"int64\"\n | \"uint8\"\n | \"uint16\"\n | \"uint32\"\n | \"uint64\"\n | \"float16\"\n | \"float32\"\n | \"float64\"\n | \"date32\"\n | \"date64\"\n | \"binary\"\n | \"large-binary\"\n | \"binary-view\"\n | \"utf8\"\n | \"large-utf8\"\n | \"utf8-view\"\n >\n | Readonly<{ type: \"timestamp\"; unit: TimeUnit; timezone?: string }>\n | Readonly<{ type: \"time32\" | \"time64\" | \"duration\"; unit: TimeUnit }>\n | Readonly<{ type: \"interval\"; unit: IntervalUnit }>\n | Readonly<{ type: \"fixed-size-binary\"; byteWidth: number }>\n | Readonly<{ type: \"decimal32\" | \"decimal64\" | \"decimal128\" | \"decimal256\"; precision: number; scale: number }>\n | Readonly<{ type: \"list\" | \"large-list\" | \"list-view\" | \"large-list-view\"; field: ArrowField }>\n | Readonly<{ type: \"fixed-size-list\"; field: ArrowField; listSize: number }>\n | Readonly<{ type: \"struct\"; fields: readonly ArrowField[] }>\n | Readonly<{\n type: \"union\";\n mode: \"sparse\" | \"dense\";\n fields: readonly Readonly<{ typeId: number; field: ArrowField }>[];\n }>\n | Readonly<{\n type: \"dictionary\";\n indexType: ArrowDataType;\n valueType: ArrowDataType;\n ordered?: boolean;\n }>\n | Readonly<{ type: \"map\"; entries: ArrowField; keysSorted: boolean }>\n | Readonly<{ type: \"run-end-encoded\"; runEnds: ArrowField; values: ArrowField }>\n | Readonly<{\n type: \"extension\";\n name: string;\n metadata?: string;\n storageType: ArrowDataType;\n }>;\n\nexport interface ColumnSchema {\n readonly id: string;\n readonly name: string;\n readonly index: number;\n readonly dataType: ArrowDataType;\n readonly nullable: boolean;\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\nexport interface TableCapabilities {\n readonly randomAccess: \"indexed-prefix\" | \"full\";\n readonly typedValues: boolean;\n readonly search: boolean;\n readonly sort: boolean;\n readonly filter: boolean;\n readonly multiTable: boolean;\n readonly [name: string]: unknown;\n}\n\nexport interface TableMetadata {\n readonly tableId: string;\n readonly name: string;\n readonly revision: number;\n readonly extent: Readonly<TableExtent>;\n readonly schema: Readonly<{\n readonly version: number;\n readonly columns: readonly Readonly<ColumnSchema>[];\n }>;\n readonly capabilities: Readonly<TableCapabilities>;\n}\n\nexport type WorksheetVisibility = \"visible\" | \"hidden\" | \"very-hidden\";\n\n/** One sparse row or column override supplied by a spreadsheet presentation. */\nexport interface PresentationAxisEntry {\n readonly index: number;\n /** CSS pixel extent when the source supplies an explicit dimension. */\n readonly size?: number;\n readonly hidden?: boolean;\n}\n\nexport interface PresentationColor {\n /** CSS-compatible resolved color, when the workbook supplied one. */\n readonly css?: string;\n}\n\nexport interface PresentationFont {\n readonly family?: string;\n readonly size?: number;\n readonly bold?: boolean;\n readonly italic?: boolean;\n readonly underline?: boolean;\n readonly color?: PresentationColor;\n}\n\nexport interface PresentationBorderSide {\n readonly style?: \"none\" | \"thin\" | \"medium\" | \"thick\" | \"dashed\" | \"dotted\" | \"double\";\n readonly color?: PresentationColor;\n}\n\n/** Static cell styling that 0.1 preserves from spreadsheet input. */\nexport interface PresentationStyle {\n readonly numberFormat?: string;\n readonly font?: PresentationFont;\n readonly foregroundColor?: PresentationColor;\n readonly backgroundColor?: PresentationColor;\n readonly fillColor?: PresentationColor;\n readonly borders?: Readonly<{\n readonly top?: PresentationBorderSide;\n readonly right?: PresentationBorderSide;\n readonly bottom?: PresentationBorderSide;\n readonly left?: PresentationBorderSide;\n }>;\n readonly horizontalAlignment?: \"general\" | \"left\" | \"center\" | \"right\" | \"justify\";\n readonly verticalAlignment?: \"top\" | \"center\" | \"bottom\" | \"justify\";\n readonly wrapText?: boolean;\n}\n\nexport interface MergedCellRegion {\n readonly rowStart: number;\n readonly rowEnd: number;\n readonly columnStart: number;\n readonly columnEnd: number;\n}\n\n/**\n * Presentation metadata for a worksheet. It is intentionally static: formula\n * calculation and document round-tripping are outside the 0.1 contract.\n */\nexport interface SpreadsheetPresentation {\n readonly kind: \"spreadsheet-v1\";\n readonly tableId: string;\n readonly revision: number;\n readonly visibility: WorksheetVisibility;\n readonly frozenRows: number;\n readonly frozenColumns: number;\n readonly rows: readonly PresentationAxisEntry[];\n readonly columns: readonly PresentationAxisEntry[];\n /** Deduplicated styles addressed by `SpreadsheetPresentationRange.styleIds`. */\n readonly styles: readonly PresentationStyle[];\n}\n\nexport type TablePresentation = SpreadsheetPresentation;\n\nexport interface SpreadsheetPresentationRange {\n readonly kind: \"spreadsheet-v1\";\n readonly tableId: string;\n readonly revision: number;\n readonly range: Readonly<ReturnedRange>;\n /** Rows and columns are exactly aligned with `range`; null means no style. */\n readonly styleIds: readonly (readonly (number | null)[])[];\n readonly mergedCells: readonly MergedCellRegion[];\n /** Sparse layout entries that intersect this requested range. */\n readonly rows: readonly PresentationAxisEntry[];\n readonly columns: readonly PresentationAxisEntry[];\n}\n\nexport type PresentationRange = SpreadsheetPresentationRange;\n\nexport interface TableDescriptor {\n readonly id: string;\n readonly name: string;\n}\n\nexport interface RangeRequest {\n readonly rowStart: number;\n readonly rowCount: number;\n readonly columnStart: number;\n readonly columnCount: number;\n}\n\nexport interface ReturnedRange extends RangeRequest {}\n\n/** A byte region in the batch's deduplicated buffer pool. */\nexport interface BatchBufferRegion {\n readonly buffer: number;\n readonly byteOffset?: number;\n readonly byteLength?: number;\n /** First bit for bitmap regions; ignored for byte-oriented regions. */\n readonly bitOffset?: number;\n}\n\n/** UTF-8 text generated by Rust for rendering, ARIA, width measurement and copy. */\nexport interface DisplayColumnDescriptor {\n readonly encoding: \"utf8\";\n readonly data: BatchBufferRegion;\n readonly offsets: BatchBufferRegion;\n readonly validity?: BatchBufferRegion;\n /** Logical offset into the display arrays, for sliced batches. */\n readonly offset?: number;\n}\n\n/**\n * Recursive Arrow ArrayData layout. Buffer regions always point into the\n * enclosing TableBatch buffer pool; encoded dictionaries and run ends remain\n * visible in this descriptor even though `toRows()` returns logical values.\n */\nexport interface NativeColumnDescriptor {\n /** Rust ArrayData layout encoding (for example `dictionary` or `run-end-encoded`). */\n readonly encoding?: string;\n readonly dataType: ArrowDataType;\n readonly length: number;\n readonly offset?: number;\n readonly validity?: BatchBufferRegion;\n readonly values?: BatchBufferRegion;\n readonly offsets?: BatchBufferRegion;\n readonly sizes?: BatchBufferRegion;\n readonly data?: BatchBufferRegion;\n readonly typeIds?: BatchBufferRegion;\n readonly unionOffsets?: BatchBufferRegion;\n readonly variadicBuffers?: readonly BatchBufferRegion[];\n readonly children?: readonly NativeColumnDescriptor[];\n readonly dictionary?: NativeColumnDescriptor;\n readonly runEnds?: NativeColumnDescriptor;\n readonly typeId?: number;\n}\n\n/** @internal Layout-v1 column descriptor received from an official WASM runtime. */\nexport interface WireTableBatchColumn {\n readonly columnId: string;\n readonly native: NativeColumnDescriptor;\n readonly display: DisplayColumnDescriptor;\n}\n\nexport interface DecimalValue {\n readonly kind: \"decimal\";\n readonly unscaled: bigint;\n readonly precision: number;\n readonly scale: number;\n}\n\nexport interface TemporalValue {\n readonly kind: \"date32\" | \"date64\" | \"time32\" | \"time64\" | \"timestamp\" | \"duration\";\n readonly value: number | bigint;\n readonly unit?: TimeUnit;\n readonly timezone?: string;\n}\n\nexport interface IntervalValue {\n readonly kind: \"interval\";\n readonly unit: IntervalUnit;\n readonly months?: number;\n readonly days?: number;\n readonly milliseconds?: number;\n readonly nanoseconds?: bigint;\n}\n\nexport interface UnionValue {\n readonly kind: \"union\";\n readonly typeId: number;\n readonly value: NativeValue | null;\n}\n\nexport interface MapEntryValue {\n readonly key: NativeValue | null;\n readonly value: NativeValue | null;\n}\n\nexport interface NativeListValue extends ReadonlyArray<NativeValue | null> {}\nexport interface NativeStructValue {\n readonly [name: string]: NativeValue | null;\n}\nexport interface NativeMapValue extends ReadonlyArray<Readonly<MapEntryValue>> {}\n\nexport type NativeValue =\n | boolean\n | number\n | bigint\n | string\n | Uint8Array\n | DecimalValue\n | TemporalValue\n | IntervalValue\n | UnionValue\n | NativeListValue\n | NativeStructValue\n | NativeMapValue;\n\nexport interface ToRowsOptions {\n /** Maximum decoded cells. Defaults to 10,000. */\n readonly maxCells?: number;\n}\n\n/**\n * Logical, column-oriented access to one returned batch column.\n *\n * Values are indexed relative to `TableBatch.range.rowStart`; physical buffer\n * regions and adapter transport details intentionally remain private.\n */\nexport interface TableBatchColumn {\n readonly columnId: string;\n readonly columnIndex: number;\n readonly rowCount: number;\n getValue(rowOffset: number): NativeValue | null;\n getDisplayValue(rowOffset: number): string | null;\n toValues(options?: ToRowsOptions): (NativeValue | null)[];\n toDisplayValues(options?: ToRowsOptions): (string | null)[];\n}\n\n/** Stable logical batch contract. Wire buffers and ABI layout stay private. */\nexport interface TableBatch {\n readonly tableId: string;\n readonly revision: number;\n readonly schemaVersion: number;\n readonly range: Readonly<ReturnedRange>;\n readonly columns: readonly TableBatchColumn[];\n readonly complete: boolean;\n toRows(options?: ToRowsOptions): (NativeValue | null)[][];\n toDisplayRows(options?: ToRowsOptions): (string | null)[][];\n}\n\nexport type WireBatchBuffer = ArrayBuffer | ArrayBufferView;\n\nexport interface WireTableBatch {\n readonly layoutVersion: typeof BATCH_LAYOUT_VERSION;\n readonly tableId: string;\n readonly revision: number;\n readonly schemaVersion: number;\n readonly range: ReturnedRange;\n readonly buffers: readonly WireBatchBuffer[];\n readonly columns: readonly WireTableBatchColumn[];\n readonly complete: boolean;\n}\n\n/** Owns and validates one generic layout-v1 batch received from the Worker. */\nexport class ColumnarTableBatch implements TableBatch {\n readonly tableId: string;\n readonly revision: number;\n readonly schemaVersion: number;\n readonly range: Readonly<ReturnedRange>;\n readonly columns: readonly TableBatchColumn[];\n readonly complete: boolean;\n readonly #buffers: readonly Uint8Array[];\n readonly #wireColumns: readonly WireTableBatchColumn[];\n\n constructor(value: WireTableBatch) {\n if (value.layoutVersion !== BATCH_LAYOUT_VERSION) {\n throw invalidArgument(\n `Batch layout ${String(value.layoutVersion)} is incompatible with layout ${BATCH_LAYOUT_VERSION}`,\n );\n }\n this.tableId = value.tableId;\n this.revision = value.revision;\n this.schemaVersion = value.schemaVersion;\n this.range = Object.freeze({ ...value.range });\n this.#buffers = Object.freeze(value.buffers.map(asUint8Array));\n this.#wireColumns = Object.freeze(value.columns.map((column) => freezeWireColumn(column)));\n this.complete = value.complete;\n validateWireBatch(this.range, this.#buffers, this.#wireColumns);\n this.columns = Object.freeze(this.#wireColumns.map((column, index) => new LogicalBatchColumn(\n column,\n this.#buffers,\n this.range.rowCount,\n this.range.columnStart + index,\n )));\n }\n\n toRows(options: ToRowsOptions = {}): (NativeValue | null)[][] {\n const maxCells = normalizeCellLimit(options.maxCells);\n assertCellLimit(this.range.rowCount, this.columns.length, maxCells);\n const rows: (NativeValue | null)[][] = Array.from(\n { length: this.range.rowCount },\n () => Array<NativeValue | null>(this.columns.length),\n );\n for (let columnIndex = 0; columnIndex < this.columns.length; columnIndex += 1) {\n for (let rowIndex = 0; rowIndex < this.range.rowCount; rowIndex += 1) {\n rows[rowIndex]![columnIndex] = this.columns[columnIndex]!.getValue(rowIndex);\n }\n }\n return rows;\n }\n\n toDisplayRows(options: ToRowsOptions = {}): (string | null)[][] {\n const maxCells = normalizeCellLimit(options.maxCells);\n assertCellLimit(this.range.rowCount, this.columns.length, maxCells);\n const rows: (string | null)[][] = Array.from(\n { length: this.range.rowCount },\n () => Array<string | null>(this.columns.length),\n );\n\n for (let columnIndex = 0; columnIndex < this.columns.length; columnIndex += 1) {\n for (let rowIndex = 0; rowIndex < this.range.rowCount; rowIndex += 1) {\n rows[rowIndex]![columnIndex] = this.columns[columnIndex]!.getDisplayValue(rowIndex);\n }\n }\n return rows;\n }\n}\n\nclass LogicalBatchColumn implements TableBatchColumn {\n readonly columnId: string;\n readonly columnIndex: number;\n readonly rowCount: number;\n readonly #wire: WireTableBatchColumn;\n readonly #buffers: readonly Uint8Array[];\n\n constructor(\n wire: WireTableBatchColumn,\n buffers: readonly Uint8Array[],\n rowCount: number,\n columnIndex: number,\n ) {\n this.columnId = wire.columnId;\n this.columnIndex = columnIndex;\n this.rowCount = rowCount;\n this.#wire = wire;\n this.#buffers = buffers;\n Object.freeze(this);\n }\n\n getValue(rowOffset: number): NativeValue | null {\n assertBatchRowOffset(rowOffset, this.rowCount);\n return decodeNativeValue(this.#wire.native, rowOffset, this.#buffers, 0);\n }\n\n getDisplayValue(rowOffset: number): string | null {\n assertBatchRowOffset(rowOffset, this.rowCount);\n return decodeDisplayValue(this.#wire.display, rowOffset, this.#buffers, this.columnId);\n }\n\n toValues(options: ToRowsOptions = {}): (NativeValue | null)[] {\n const maxCells = normalizeCellLimit(options.maxCells);\n assertCellLimit(this.rowCount, 1, maxCells);\n return Array.from({ length: this.rowCount }, (_, index) => this.getValue(index));\n }\n\n toDisplayValues(options: ToRowsOptions = {}): (string | null)[] {\n const maxCells = normalizeCellLimit(options.maxCells);\n assertCellLimit(this.rowCount, 1, maxCells);\n return Array.from({ length: this.rowCount }, (_, index) => this.getDisplayValue(index));\n }\n}\n\nfunction assertBatchRowOffset(rowOffset: number, rowCount: number): void {\n if (!Number.isSafeInteger(rowOffset) || rowOffset < 0 || rowOffset >= rowCount) {\n throw invalidArgument(`Batch row offset must be an integer from 0 through ${Math.max(0, rowCount - 1)}`);\n }\n}\n\nfunction decodeDisplayValue(\n display: DisplayColumnDescriptor,\n rowOffset: number,\n buffers: readonly Uint8Array[],\n columnId: string,\n): string | null {\n const physicalIndex = (display.offset ?? 0) + rowOffset;\n if (!validAt(display.validity, physicalIndex, buffers)) {\n return null;\n }\n const offsets = regionView(display.offsets, buffers, \"display offsets\");\n const data = regionView(display.data, buffers, \"display data\");\n const start = readUnsignedOffset(offsets, physicalIndex, 4);\n const end = readUnsignedOffset(offsets, physicalIndex + 1, 4);\n if (end < start || end > data.byteLength) {\n throw invalidArgument(`Column ${columnId} has invalid display offsets`);\n }\n return UTF8_DECODER.decode(data.subarray(start, end));\n}\n\nexport function validateRange(request: RangeRequest): RangeRequest {\n for (const [name, value] of Object.entries(request)) {\n assertNonNegativeSafeInteger(value, name);\n }\n if (\n request.rowCount > Number.MAX_SAFE_INTEGER - request.rowStart\n || request.columnCount > Number.MAX_SAFE_INTEGER - request.columnStart\n ) {\n throw new TabularkError(\"INVALID_RANGE\", \"Range end must be a safe integer\");\n }\n const cells = request.rowCount * request.columnCount;\n // Bound each dimension as well as the product. A zero-height/zero-width\n // range still reaches adapter loops and must not smuggle an unbounded axis\n // through the `0 * Number.MAX_SAFE_INTEGER` product.\n if (\n request.rowCount > MAX_RANGE_CELLS\n || request.columnCount > MAX_RANGE_CELLS\n || !Number.isSafeInteger(cells)\n || cells > MAX_RANGE_CELLS\n ) {\n const required = Number.isSafeInteger(cells)\n ? Math.max(cells, request.rowCount, request.columnCount)\n : Number.MAX_SAFE_INTEGER;\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `A range may contain at most ${MAX_RANGE_CELLS} cells`,\n {\n details: {\n resource: \"range-cells\",\n required,\n available: MAX_RANGE_CELLS,\n cells: Number.isSafeInteger(cells) ? cells : Number.MAX_SAFE_INTEGER,\n limit: MAX_RANGE_CELLS,\n },\n },\n );\n }\n return Object.freeze({ ...request });\n}\n\nexport function normalizeMetadata(value: TableMetadata): Readonly<TableMetadata> {\n return Object.freeze({\n ...value,\n extent: Object.freeze({\n rows: Object.freeze({ ...value.extent.rows }),\n columns: Object.freeze({ ...value.extent.columns }),\n }),\n schema: Object.freeze({\n version: value.schema.version,\n columns: Object.freeze(value.schema.columns.map((column) => Object.freeze({\n ...column,\n dataType: freezeDataType(column.dataType),\n ...(column.metadata ? { metadata: Object.freeze({ ...column.metadata }) } : {}),\n }))),\n }),\n capabilities: Object.freeze({ ...value.capabilities }),\n });\n}\n\n/** Normalizes a protocol DataType and rejects cycles or excessive nesting. */\nexport function normalizeDataType(value: unknown, depth = 0): ArrowDataType {\n if (depth >= MAX_NESTING_DEPTH) {\n throw invalidArgument(`Arrow data type nesting may not exceed ${MAX_NESTING_DEPTH}`);\n }\n if (!isRecord(value) || typeof value.type !== \"string\") {\n throw invalidArgument(\"Column dataType must be a recursive Arrow data type descriptor\");\n }\n const type: string = ({\n \"u-int8\": \"uint8\",\n \"u-int16\": \"uint16\",\n \"u-int32\": \"uint32\",\n \"u-int64\": \"uint64\",\n } as const)[value.type as \"u-int8\" | \"u-int16\" | \"u-int32\" | \"u-int64\"] ?? value.type;\n const simple = new Set([\n \"unknown\", \"null\", \"boolean\", \"int8\", \"int16\", \"int32\", \"int64\", \"uint8\", \"uint16\", \"uint32\", \"uint64\",\n \"float16\", \"float32\", \"float64\", \"date32\", \"date64\", \"binary\", \"large-binary\", \"binary-view\",\n \"utf8\", \"large-utf8\", \"utf8-view\",\n ]);\n if (simple.has(type)) {\n return Object.freeze({ type }) as ArrowDataType;\n }\n if (type === \"timestamp\") {\n return Object.freeze({\n type,\n unit: timeUnit(value.unit),\n ...(typeof value.timezone === \"string\" ? { timezone: value.timezone } : {}),\n });\n }\n if (type === \"time32\" || type === \"time64\" || type === \"duration\") {\n return Object.freeze({ type, unit: timeUnit(value.unit) });\n }\n if (type === \"interval\") {\n return Object.freeze({ type, unit: intervalUnit(value.unit) });\n }\n if (type === \"fixed-size-binary\") {\n return Object.freeze({\n type,\n byteWidth: positiveInteger(value.byteWidth ?? value.byte_width, \"byteWidth\"),\n });\n }\n if (type === \"decimal32\" || type === \"decimal64\" || type === \"decimal128\" || type === \"decimal256\") {\n return Object.freeze({\n type,\n precision: positiveInteger(value.precision, \"precision\"),\n scale: integer(value.scale, \"scale\"),\n });\n }\n if (type === \"list\" || type === \"large-list\" || type === \"list-view\" || type === \"large-list-view\") {\n return Object.freeze({ type, field: normalizeField(value.field, depth + 1) });\n }\n if (type === \"fixed-size-list\") {\n return Object.freeze({\n type,\n field: normalizeField(value.field, depth + 1),\n listSize: positiveInteger(value.listSize ?? value.list_size, \"listSize\"),\n });\n }\n if (type === \"struct\") {\n if (!Array.isArray(value.fields)) {\n throw invalidArgument(\"Struct fields must be an array\");\n }\n return Object.freeze({\n type,\n fields: Object.freeze(value.fields.map((field) => normalizeField(field, depth + 1))),\n });\n }\n if (type === \"union\") {\n if (!Array.isArray(value.fields) || (value.mode !== \"sparse\" && value.mode !== \"dense\")) {\n throw invalidArgument(\"Union dataType requires a mode and fields\");\n }\n return Object.freeze({\n type,\n mode: value.mode,\n fields: Object.freeze(value.fields.map((entry) => {\n if (!isRecord(entry)) {\n throw invalidArgument(\"Union field entries must be objects\");\n }\n return Object.freeze({\n typeId: integer(entry.typeId, \"typeId\"),\n field: normalizeField(entry.field, depth + 1),\n });\n })),\n });\n }\n if (type === \"dictionary\") {\n return Object.freeze({\n type,\n indexType: normalizeDataType(value.indexType, depth + 1),\n valueType: normalizeDataType(value.valueType, depth + 1),\n ...(value.ordered === true ? { ordered: true } : {}),\n });\n }\n if (type === \"map\") {\n return Object.freeze({\n type,\n entries: normalizeField(value.entries, depth + 1),\n keysSorted: value.keysSorted === true || value.keys_sorted === true,\n });\n }\n if (type === \"run-end-encoded\") {\n return Object.freeze({\n type,\n runEnds: normalizeField(value.runEnds ?? value.run_ends, depth + 1),\n values: normalizeField(value.values, depth + 1),\n });\n }\n if (type === \"extension\") {\n if (typeof value.name !== \"string\" || value.name.length === 0) {\n throw invalidArgument(\"Arrow extension name must be a non-empty string\");\n }\n return Object.freeze({\n type,\n name: value.name,\n ...(typeof value.metadata === \"string\" ? { metadata: value.metadata } : {}),\n storageType: normalizeDataType(value.storageType, depth + 1),\n });\n }\n throw invalidArgument(`Unknown Arrow data type: ${type}`);\n}\n\nfunction normalizeField(value: unknown, depth: number): ArrowField {\n if (!isRecord(value)) {\n throw invalidArgument(\"Arrow field must be an object\");\n }\n const metadata = isRecord(value.metadata)\n ? Object.freeze(Object.fromEntries(Object.entries(value.metadata).map(([key, entry]) => [key, String(entry)])))\n : undefined;\n return Object.freeze({\n name: typeof value.name === \"string\" ? value.name : \"\",\n nullable: value.nullable !== false,\n dataType: normalizeDataType(value.dataType, depth),\n ...(metadata ? { metadata } : {}),\n });\n}\n\nfunction validateWireBatch(\n range: Readonly<ReturnedRange>,\n buffers: readonly Uint8Array[],\n columns: readonly WireTableBatchColumn[],\n): void {\n validateRange(range);\n if (columns.length !== range.columnCount) {\n throw invalidArgument(\n `Batch has ${columns.length} columns; expected ${range.columnCount}`,\n );\n }\n for (const [index, column] of columns.entries()) {\n validateDisplay(column.display, range.rowCount, buffers, column.columnId);\n validateNative(column.native, buffers, 0, `columns[${index}].native`);\n if (column.native.length < range.rowCount) {\n throw invalidArgument(`Column ${column.columnId} is shorter than the returned range`);\n }\n }\n}\n\nfunction validateDisplay(\n display: DisplayColumnDescriptor,\n rows: number,\n buffers: readonly Uint8Array[],\n columnId: string,\n): void {\n const offset = display.offset ?? 0;\n assertNonNegativeSafeInteger(offset, \"display offset\");\n const offsets = regionView(display.offsets, buffers, \"display offsets\");\n if (offsets.byteLength < (offset + rows + 1) * 4) {\n throw invalidArgument(`Column ${columnId} has incomplete display offsets`);\n }\n const data = regionView(display.data, buffers, \"display data\");\n if (display.validity) {\n const validity = regionView(display.validity, buffers, \"display validity\");\n if (validity.byteLength < Math.ceil((offset + rows) / 8)) {\n throw invalidArgument(`Column ${columnId} has an incomplete display validity bitmap`);\n }\n }\n let previous = 0;\n for (let index = offset; index <= offset + rows; index += 1) {\n const next = readUnsignedOffset(offsets, index, 4);\n if (next < previous || next > data.byteLength) {\n throw invalidArgument(`Column ${columnId} has invalid display offsets`);\n }\n previous = next;\n }\n}\n\nfunction validateNative(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n depth: number,\n name: string,\n): void {\n if (depth >= MAX_NESTING_DEPTH) {\n throw invalidArgument(`Native column nesting may not exceed ${MAX_NESTING_DEPTH}`);\n }\n assertNonNegativeSafeInteger(descriptor.length, `${name}.length`);\n assertNonNegativeSafeInteger(descriptor.offset ?? 0, `${name}.offset`);\n normalizeDataType(descriptor.dataType, depth);\n const regions = [\n descriptor.validity,\n descriptor.values,\n descriptor.offsets,\n descriptor.sizes,\n descriptor.data,\n descriptor.typeIds,\n descriptor.unionOffsets,\n ...(descriptor.variadicBuffers ?? []),\n ];\n for (const region of regions) {\n if (region) {\n regionView(region, buffers, name);\n }\n }\n for (const [index, child] of (descriptor.children ?? []).entries()) {\n validateNative(child, buffers, depth + 1, `${name}.children[${index}]`);\n }\n if (descriptor.dictionary) {\n validateNative(descriptor.dictionary, buffers, depth + 1, `${name}.dictionary`);\n }\n if (descriptor.runEnds) {\n validateNative(descriptor.runEnds, buffers, depth + 1, `${name}.runEnds`);\n }\n}\n\nfunction decodeNativeValue(\n descriptor: NativeColumnDescriptor,\n logicalIndex: number,\n buffers: readonly Uint8Array[],\n depth: number,\n): NativeValue | null {\n if (depth >= MAX_NESTING_DEPTH) {\n throw invalidArgument(`Native value nesting may not exceed ${MAX_NESTING_DEPTH}`);\n }\n if (logicalIndex < 0 || logicalIndex >= descriptor.length) {\n throw invalidArgument(\"Native value index is outside its descriptor\");\n }\n const physicalIndex = (descriptor.offset ?? 0) + logicalIndex;\n if (!validAt(descriptor.validity, physicalIndex, buffers)) {\n return null;\n }\n const type = unwrapExtension(descriptor.dataType);\n switch (type.type) {\n case \"null\":\n return null;\n case \"unknown\": {\n const bytes = decodeVariableBytes(descriptor, buffers, physicalIndex, 4);\n return UTF8_DECODER.decode(bytes);\n }\n case \"boolean\": {\n const values = requiredRegion(descriptor.values, buffers, \"boolean values\");\n const bitIndex = (descriptor.values?.bitOffset ?? 0) + physicalIndex;\n return (values[bitIndex >>> 3]! & (1 << (bitIndex & 7))) !== 0;\n }\n case \"int8\": return readNumber(descriptor, buffers, physicalIndex, 1, \"signed\");\n case \"uint8\": return readNumber(descriptor, buffers, physicalIndex, 1, \"unsigned\");\n case \"int16\": return readNumber(descriptor, buffers, physicalIndex, 2, \"signed\");\n case \"uint16\": return readNumber(descriptor, buffers, physicalIndex, 2, \"unsigned\");\n case \"int32\": return readNumber(descriptor, buffers, physicalIndex, 4, \"signed\");\n case \"uint32\": return readNumber(descriptor, buffers, physicalIndex, 4, \"unsigned\");\n case \"int64\": return readBigInt(descriptor, buffers, physicalIndex, true);\n case \"uint64\": return readBigInt(descriptor, buffers, physicalIndex, false);\n case \"float16\": return decodeFloat16(readNumber(descriptor, buffers, physicalIndex, 2, \"unsigned\"));\n case \"float32\": return readFloat(descriptor, buffers, physicalIndex, 4);\n case \"float64\": return readFloat(descriptor, buffers, physicalIndex, 8);\n case \"utf8\":\n case \"large-utf8\": {\n const bytes = decodeVariableBytes(descriptor, buffers, physicalIndex, type.type === \"large-utf8\" ? 8 : 4);\n return UTF8_DECODER.decode(bytes);\n }\n case \"binary\":\n case \"large-binary\":\n return decodeVariableBytes(descriptor, buffers, physicalIndex, type.type === \"large-binary\" ? 8 : 4).slice();\n case \"utf8-view\":\n return UTF8_DECODER.decode(decodeViewBytes(descriptor, buffers, physicalIndex));\n case \"binary-view\":\n return decodeViewBytes(descriptor, buffers, physicalIndex).slice();\n case \"fixed-size-binary\": {\n const data = requiredRegion(descriptor.data ?? descriptor.values, buffers, \"fixed-size binary data\");\n const start = physicalIndex * type.byteWidth;\n return checkedSlice(data, start, start + type.byteWidth, \"fixed-size binary data\").slice();\n }\n case \"decimal32\":\n case \"decimal64\":\n case \"decimal128\":\n case \"decimal256\": {\n const width = { decimal32: 4, decimal64: 8, decimal128: 16, decimal256: 32 }[type.type];\n return Object.freeze({\n kind: \"decimal\",\n unscaled: readSignedLittleEndian(requiredRegion(descriptor.values, buffers, \"decimal values\"), physicalIndex * width, width),\n precision: type.precision,\n scale: type.scale,\n });\n }\n case \"date32\":\n return Object.freeze({ kind: \"date32\", value: readNumber(descriptor, buffers, physicalIndex, 4, \"signed\") });\n case \"date64\":\n return Object.freeze({ kind: \"date64\", value: readBigInt(descriptor, buffers, physicalIndex, true), unit: \"millisecond\" });\n case \"time32\":\n return Object.freeze({ kind: \"time32\", value: readNumber(descriptor, buffers, physicalIndex, 4, \"signed\"), unit: type.unit });\n case \"time64\":\n return Object.freeze({ kind: \"time64\", value: readBigInt(descriptor, buffers, physicalIndex, true), unit: type.unit });\n case \"timestamp\":\n return Object.freeze({\n kind: \"timestamp\",\n value: readBigInt(descriptor, buffers, physicalIndex, true),\n unit: type.unit,\n ...(type.timezone === undefined ? {} : { timezone: type.timezone }),\n });\n case \"duration\":\n return Object.freeze({ kind: \"duration\", value: readBigInt(descriptor, buffers, physicalIndex, true), unit: type.unit });\n case \"interval\":\n return decodeInterval(descriptor, buffers, physicalIndex, type.unit);\n case \"list\":\n case \"large-list\":\n case \"list-view\":\n case \"large-list-view\":\n case \"map\":\n return decodeListLike(descriptor, buffers, physicalIndex, type, depth);\n case \"fixed-size-list\": {\n const child = requiredChild(descriptor, 0, \"fixed-size list\");\n const start = physicalIndex * type.listSize;\n return Object.freeze(Array.from(\n { length: type.listSize },\n (_, index) => decodeNativeValue(child, start + index - (child.offset ?? 0), buffers, depth + 1),\n ));\n }\n case \"struct\": {\n const result: Record<string, NativeValue | null> = {};\n for (let index = 0; index < type.fields.length; index += 1) {\n const child = requiredChild(descriptor, index, \"struct\");\n result[type.fields[index]!.name] = decodeNativeValue(\n child,\n physicalIndex - (child.offset ?? 0),\n buffers,\n depth + 1,\n );\n }\n return Object.freeze(result);\n }\n case \"union\": {\n const typeIds = requiredRegion(descriptor.typeIds, buffers, \"union type ids\");\n if (physicalIndex >= typeIds.byteLength) {\n throw invalidArgument(\"Union type id is out of bounds\");\n }\n const typeId = dataViewFor(typeIds).getInt8(physicalIndex);\n const fieldIndex = type.fields.findIndex((entry) => entry.typeId === typeId);\n if (fieldIndex < 0) {\n throw invalidArgument(`Union type id ${typeId} has no child`);\n }\n const child = requiredChild(descriptor, fieldIndex, \"union\");\n const childPhysical = type.mode === \"dense\"\n ? readSignedOffset(requiredRegion(descriptor.unionOffsets ?? descriptor.offsets, buffers, \"union offsets\"), physicalIndex, 4)\n : physicalIndex;\n return Object.freeze({\n kind: \"union\",\n typeId,\n value: decodeNativeValue(child, childPhysical - (child.offset ?? 0), buffers, depth + 1),\n });\n }\n case \"dictionary\": {\n const keys = descriptor.children?.[0] ?? descriptor;\n const dictionary = descriptor.dictionary ?? descriptor.children?.[1];\n if (!dictionary || !keys) {\n throw invalidArgument(\"Dictionary descriptor has no dictionary values\");\n }\n const index = readIndex(keys, buffers, physicalIndex, type.indexType);\n if (index < 0 || index >= dictionary.length) {\n throw invalidArgument(\"Dictionary index is out of bounds\");\n }\n return decodeNativeValue(dictionary, index, buffers, depth + 1);\n }\n case \"run-end-encoded\": {\n const runEnds = descriptor.runEnds ?? descriptor.children?.[0];\n const values = descriptor.children?.[descriptor.runEnds ? 0 : 1];\n if (!runEnds || !values) {\n throw invalidArgument(\"Run-end encoded descriptor is incomplete\");\n }\n const logicalPosition = physicalIndex + 1;\n let run = 0;\n while (run < runEnds.length && numericIndexValue(runEnds, buffers, run) < logicalPosition) {\n run += 1;\n }\n if (run >= values.length) {\n throw invalidArgument(\"Run-end encoded value is out of bounds\");\n }\n return decodeNativeValue(values, run, buffers, depth + 1);\n }\n case \"extension\":\n // unwrapExtension makes this unreachable while retaining exhaustive typing.\n throw invalidArgument(\"Nested extension data type could not be unwrapped\");\n }\n}\n\nfunction decodeListLike(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n physicalIndex: number,\n type: Extract<ArrowDataType, { type: \"list\" | \"large-list\" | \"list-view\" | \"large-list-view\" | \"map\" }>,\n depth: number,\n): NativeValue {\n const width = type.type === \"large-list\" || type.type === \"large-list-view\" ? 8 : 4;\n const offsets = requiredRegion(descriptor.offsets, buffers, \"list offsets\");\n const start = readSignedOffset(offsets, physicalIndex, width);\n const end = type.type === \"list-view\" || type.type === \"large-list-view\"\n ? start + readSignedOffset(requiredRegion(descriptor.sizes, buffers, \"list sizes\"), physicalIndex, width)\n : readSignedOffset(offsets, physicalIndex + 1, width);\n if (start < 0 || end < start) {\n throw invalidArgument(\"List offsets are invalid\");\n }\n const child = requiredChild(descriptor, 0, type.type);\n const values: NativeListValue = Object.freeze(Array.from(\n { length: end - start },\n (_, index) => decodeNativeValue(child, start + index - (child.offset ?? 0), buffers, depth + 1),\n ));\n if (type.type !== \"map\") {\n return values;\n }\n return Object.freeze(values.map((entry: NativeValue | null) => {\n if (!isRecord(entry)) {\n throw invalidArgument(\"Map entries must decode from a struct\");\n }\n const record = entry as NativeStructValue;\n const entryType = type.entries.dataType;\n const fields = entryType.type === \"struct\" ? entryType.fields : [];\n const keyName = fields[0]?.name ?? \"key\";\n const valueName = fields[1]?.name ?? \"value\";\n return Object.freeze({\n key: record[keyName] ?? null,\n value: record[valueName] ?? null,\n });\n }));\n}\n\nfunction decodeInterval(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n unit: IntervalUnit,\n): IntervalValue {\n const values = requiredRegion(descriptor.values, buffers, \"interval values\");\n const view = dataViewFor(values);\n if (unit === \"year-month\") {\n ensureViewRange(view, index * 4, 4, \"year-month interval\");\n return Object.freeze({ kind: \"interval\", unit, months: view.getInt32(index * 4, true) });\n }\n if (unit === \"day-time\") {\n const offset = index * 8;\n ensureViewRange(view, offset, 8, \"day-time interval\");\n return Object.freeze({\n kind: \"interval\",\n unit,\n days: view.getInt32(offset, true),\n milliseconds: view.getInt32(offset + 4, true),\n });\n }\n const offset = index * 16;\n ensureViewRange(view, offset, 16, \"month-day-nano interval\");\n return Object.freeze({\n kind: \"interval\",\n unit,\n months: view.getInt32(offset, true),\n days: view.getInt32(offset + 4, true),\n nanoseconds: view.getBigInt64(offset + 8, true),\n });\n}\n\nfunction decodeVariableBytes(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n offsetWidth: 4 | 8,\n): Uint8Array {\n const offsets = requiredRegion(descriptor.offsets, buffers, \"variable offsets\");\n const data = requiredRegion(descriptor.data ?? descriptor.values, buffers, \"variable data\");\n const start = readUnsignedOffset(offsets, index, offsetWidth);\n const end = readUnsignedOffset(offsets, index + 1, offsetWidth);\n return checkedSlice(data, start, end, \"variable data\");\n}\n\nfunction decodeViewBytes(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n): Uint8Array {\n const views = requiredRegion(descriptor.values, buffers, \"view values\");\n const view = dataViewFor(views);\n const offset = index * 16;\n ensureViewRange(view, offset, 16, \"view value\");\n const length = view.getInt32(offset, true);\n if (length < 0) {\n throw invalidArgument(\"View length must be non-negative\");\n }\n if (length <= 12) {\n return checkedSlice(views, offset + 4, offset + 4 + length, \"inline view\");\n }\n const bufferIndex = view.getInt32(offset + 8, true);\n const dataOffset = view.getInt32(offset + 12, true);\n const data = descriptor.variadicBuffers?.[bufferIndex];\n if (!data || dataOffset < 0) {\n throw invalidArgument(\"View references an invalid variadic buffer\");\n }\n return checkedSlice(regionView(data, buffers, \"view data\"), dataOffset, dataOffset + length, \"view data\");\n}\n\nfunction readNumber(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n width: 1 | 2 | 4,\n signedness: \"signed\" | \"unsigned\",\n): number {\n const values = requiredRegion(descriptor.values, buffers, \"numeric values\");\n const view = dataViewFor(values);\n const offset = index * width;\n ensureViewRange(view, offset, width, \"numeric value\");\n if (width === 1) return signedness === \"signed\" ? view.getInt8(offset) : view.getUint8(offset);\n if (width === 2) return signedness === \"signed\" ? view.getInt16(offset, true) : view.getUint16(offset, true);\n return signedness === \"signed\" ? view.getInt32(offset, true) : view.getUint32(offset, true);\n}\n\nfunction readFloat(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n width: 4 | 8,\n): number {\n const values = requiredRegion(descriptor.values, buffers, \"floating-point values\");\n const view = dataViewFor(values);\n const offset = index * width;\n ensureViewRange(view, offset, width, \"floating-point value\");\n return width === 4 ? view.getFloat32(offset, true) : view.getFloat64(offset, true);\n}\n\nfunction readBigInt(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n signed: boolean,\n): bigint {\n const values = requiredRegion(descriptor.values, buffers, \"64-bit values\");\n const view = dataViewFor(values);\n const offset = index * 8;\n ensureViewRange(view, offset, 8, \"64-bit value\");\n return signed ? view.getBigInt64(offset, true) : view.getBigUint64(offset, true);\n}\n\nfunction readIndex(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n dataType: ArrowDataType,\n): number {\n const type = unwrapExtension(dataType).type;\n let value: number | bigint;\n if (type === \"int8\") value = readNumber(descriptor, buffers, index, 1, \"signed\");\n else if (type === \"uint8\") value = readNumber(descriptor, buffers, index, 1, \"unsigned\");\n else if (type === \"int16\") value = readNumber(descriptor, buffers, index, 2, \"signed\");\n else if (type === \"uint16\") value = readNumber(descriptor, buffers, index, 2, \"unsigned\");\n else if (type === \"int32\") value = readNumber(descriptor, buffers, index, 4, \"signed\");\n else if (type === \"uint32\") value = readNumber(descriptor, buffers, index, 4, \"unsigned\");\n else if (type === \"int64\") value = readBigInt(descriptor, buffers, index, true);\n else if (type === \"uint64\") value = readBigInt(descriptor, buffers, index, false);\n else throw invalidArgument(\"Dictionary index type must be an integer\");\n const numeric = typeof value === \"bigint\" ? Number(value) : value;\n if (!Number.isSafeInteger(numeric)) {\n throw invalidArgument(\"Dictionary index exceeds the JavaScript safe integer range\");\n }\n return numeric;\n}\n\nfunction numericIndexValue(\n descriptor: NativeColumnDescriptor,\n buffers: readonly Uint8Array[],\n index: number,\n): number {\n const type = unwrapExtension(descriptor.dataType);\n return readIndex({ ...descriptor, dataType: { type: \"dictionary\", indexType: type, valueType: { type: \"null\" } } }, buffers, index, type);\n}\n\nfunction readSignedLittleEndian(bytes: Uint8Array, offset: number, width: number): bigint {\n const slice = checkedSlice(bytes, offset, offset + width, \"signed integer\");\n let value = 0n;\n for (let index = slice.byteLength - 1; index >= 0; index -= 1) {\n value = (value << 8n) | BigInt(slice[index]!);\n }\n const sign = 1n << BigInt(width * 8 - 1);\n return (value & sign) === 0n ? value : value - (1n << BigInt(width * 8));\n}\n\nfunction readUnsignedOffset(bytes: Uint8Array, index: number, width: 4 | 8): number {\n const value = readOffset(bytes, index, width, false);\n if (value < 0) {\n throw invalidArgument(\"Offset must be non-negative\");\n }\n return value;\n}\n\nfunction readSignedOffset(bytes: Uint8Array, index: number, width: 4 | 8): number {\n return readOffset(bytes, index, width, true);\n}\n\nfunction dataViewFor(bytes: Uint8Array): DataView {\n // Uint8Array.buffer is an ArrayBufferLike object (ArrayBuffer or\n // SharedArrayBuffer). The nested numeric maps avoid allocating a string key\n // on every primitive decode while preserving distinct subview boundaries.\n const backing = bytes.buffer as unknown as object;\n let byOffset = DATA_VIEW_CACHE.get(backing);\n if (byOffset === undefined) {\n byOffset = new Map();\n DATA_VIEW_CACHE.set(backing, byOffset);\n }\n let byLength = byOffset.get(bytes.byteOffset);\n if (byLength === undefined) {\n byLength = new Map();\n byOffset.set(bytes.byteOffset, byLength);\n }\n let view = byLength.get(bytes.byteLength);\n if (view === undefined) {\n view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n byLength.set(bytes.byteLength, view);\n }\n return view;\n}\n\nfunction readOffset(bytes: Uint8Array, index: number, width: 4 | 8, signed: boolean): number {\n const view = dataViewFor(bytes);\n const offset = index * width;\n ensureViewRange(view, offset, width, \"offset\");\n const value = width === 4\n ? signed ? view.getInt32(offset, true) : view.getUint32(offset, true)\n : signed ? view.getBigInt64(offset, true) : view.getBigUint64(offset, true);\n const numeric = typeof value === \"bigint\" ? Number(value) : value;\n if (!Number.isSafeInteger(numeric)) {\n throw invalidArgument(\"Offset exceeds the JavaScript safe integer range\");\n }\n return numeric;\n}\n\nfunction validAt(\n validity: BatchBufferRegion | undefined,\n index: number,\n buffers: readonly Uint8Array[],\n): boolean {\n if (!validity) return true;\n const bitmap = regionView(validity, buffers, \"validity bitmap\");\n const bitIndex = (validity.bitOffset ?? 0) + index;\n if (bitIndex < 0 || (bitIndex >>> 3) >= bitmap.byteLength) {\n throw invalidArgument(\"Validity bitmap index is out of bounds\");\n }\n return (bitmap[bitIndex >>> 3]! & (1 << (bitIndex & 7))) !== 0;\n}\n\nfunction requiredRegion(\n region: BatchBufferRegion | undefined,\n buffers: readonly Uint8Array[],\n name: string,\n): Uint8Array {\n if (!region) throw invalidArgument(`${name} are missing`);\n return regionView(region, buffers, name);\n}\n\nfunction regionView(\n region: BatchBufferRegion,\n buffers: readonly Uint8Array[],\n name: string,\n): Uint8Array {\n if (!isRecord(region) || !Number.isSafeInteger(region.buffer) || region.buffer < 0) {\n throw invalidArgument(`${name} references an invalid buffer`);\n }\n const buffer = buffers[region.buffer];\n if (!buffer) throw invalidArgument(`${name} references a missing buffer`);\n const byteOffset = region.byteOffset ?? 0;\n const byteLength = region.byteLength ?? buffer.byteLength - byteOffset;\n if (\n !Number.isSafeInteger(byteOffset)\n || byteOffset < 0\n || !Number.isSafeInteger(byteLength)\n || byteLength < 0\n || byteOffset + byteLength > buffer.byteLength\n ) {\n throw invalidArgument(`${name} region is outside its buffer`);\n }\n return buffer.subarray(byteOffset, byteOffset + byteLength);\n}\n\nfunction requiredChild(descriptor: NativeColumnDescriptor, index: number, name: string): NativeColumnDescriptor {\n const child = descriptor.children?.[index];\n if (!child) throw invalidArgument(`${name} descriptor has no child ${index}`);\n return child;\n}\n\nfunction checkedSlice(bytes: Uint8Array, start: number, end: number, name: string): Uint8Array {\n if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end < start || end > bytes.byteLength) {\n throw invalidArgument(`${name} slice is out of bounds`);\n }\n return bytes.subarray(start, end);\n}\n\nfunction ensureViewRange(view: DataView, offset: number, width: number, name: string): void {\n if (offset < 0 || offset + width > view.byteLength) {\n throw invalidArgument(`${name} is out of bounds`);\n }\n}\n\nfunction unwrapExtension(dataType: ArrowDataType): ArrowDataType {\n let current = dataType;\n for (let depth = 0; current.type === \"extension\"; depth += 1) {\n if (depth >= MAX_NESTING_DEPTH) throw invalidArgument(\"Extension nesting is too deep\");\n current = current.storageType;\n }\n return current;\n}\n\nfunction freezeWireColumn(column: WireTableBatchColumn): WireTableBatchColumn {\n return Object.freeze({\n columnId: column.columnId,\n native: freezeNative(column.native),\n display: Object.freeze({\n ...column.display,\n data: freezeRegion(column.display.data),\n offsets: freezeRegion(column.display.offsets),\n ...(column.display.validity ? { validity: freezeRegion(column.display.validity) } : {}),\n }),\n });\n}\n\nfunction freezeNative(descriptor: NativeColumnDescriptor): NativeColumnDescriptor {\n const freezeOptionalRegion = (region: BatchBufferRegion | undefined) => region ? freezeRegion(region) : undefined;\n return Object.freeze({\n ...descriptor,\n dataType: freezeDataType(descriptor.dataType),\n ...(freezeOptionalRegion(descriptor.validity) ? { validity: freezeOptionalRegion(descriptor.validity)! } : {}),\n ...(freezeOptionalRegion(descriptor.values) ? { values: freezeOptionalRegion(descriptor.values)! } : {}),\n ...(freezeOptionalRegion(descriptor.offsets) ? { offsets: freezeOptionalRegion(descriptor.offsets)! } : {}),\n ...(freezeOptionalRegion(descriptor.sizes) ? { sizes: freezeOptionalRegion(descriptor.sizes)! } : {}),\n ...(freezeOptionalRegion(descriptor.data) ? { data: freezeOptionalRegion(descriptor.data)! } : {}),\n ...(freezeOptionalRegion(descriptor.typeIds) ? { typeIds: freezeOptionalRegion(descriptor.typeIds)! } : {}),\n ...(freezeOptionalRegion(descriptor.unionOffsets) ? { unionOffsets: freezeOptionalRegion(descriptor.unionOffsets)! } : {}),\n ...(descriptor.variadicBuffers\n ? { variadicBuffers: Object.freeze(descriptor.variadicBuffers.map(freezeRegion)) }\n : {}),\n ...(descriptor.children\n ? { children: Object.freeze(descriptor.children.map(freezeNative)) }\n : {}),\n ...(descriptor.dictionary ? { dictionary: freezeNative(descriptor.dictionary) } : {}),\n ...(descriptor.runEnds ? { runEnds: freezeNative(descriptor.runEnds) } : {}),\n });\n}\n\nfunction freezeRegion(region: BatchBufferRegion): BatchBufferRegion {\n return Object.freeze({ ...region });\n}\n\nfunction freezeDataType(dataType: ArrowDataType): ArrowDataType {\n return normalizeDataTypeUnchecked(dataType, 0);\n}\n\nfunction normalizeDataTypeUnchecked(value: ArrowDataType, depth: number): ArrowDataType {\n // Public construction already validates; metadata/batch normalization may\n // arrive from protocol values, so use the same validator for one canonical shape.\n return normalizeDataType(value, depth);\n}\n\nfunction timeUnit(value: unknown): TimeUnit {\n if (value === \"second\" || value === \"millisecond\" || value === \"microsecond\" || value === \"nanosecond\") {\n return value;\n }\n throw invalidArgument(\"Arrow time unit is invalid\");\n}\n\nfunction intervalUnit(value: unknown): IntervalUnit {\n if (value === \"year-month\" || value === \"day-time\" || value === \"month-day-nano\") return value;\n throw invalidArgument(\"Arrow interval unit is invalid\");\n}\n\nfunction decodeFloat16(bits: number): number {\n const sign = (bits & 0x8000) === 0 ? 1 : -1;\n const exponent = (bits >>> 10) & 0x1f;\n const fraction = bits & 0x03ff;\n if (exponent === 0) return sign * 2 ** -14 * (fraction / 1024);\n if (exponent === 0x1f) return fraction === 0 ? sign * Infinity : Number.NaN;\n return sign * 2 ** (exponent - 15) * (1 + fraction / 1024);\n}\n\nfunction normalizeCellLimit(value: number | undefined): number {\n const maxCells = value ?? DEFAULT_TO_ROWS_CELL_LIMIT;\n assertPositiveSafeInteger(maxCells, \"maxCells\");\n return maxCells;\n}\n\nfunction assertCellLimit(rows: number, columns: number, maxCells: number): void {\n const cellCount = rows * columns;\n if (!Number.isSafeInteger(cellCount) || cellCount > maxCells) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `Decoding ${cellCount} cells exceeds the toRows limit of ${maxCells}`,\n {\n details: {\n resource: \"row-materialization-cells\",\n required: cellCount,\n available: maxCells,\n cellCount,\n maxCells,\n },\n },\n );\n }\n}\n\nfunction integer(value: unknown, name: string): number {\n if (!Number.isSafeInteger(value)) throw invalidArgument(`${name} must be a safe integer`);\n return value as number;\n}\n\nfunction positiveInteger(value: unknown, name: string): number {\n const result = integer(value, name);\n if (result <= 0) throw invalidArgument(`${name} must be positive`);\n return result;\n}\n\nfunction asUint8Array(value: WireBatchBuffer): Uint8Array {\n if (value instanceof ArrayBuffer) return new Uint8Array(value);\n return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function assertNonNegativeSafeInteger(value: unknown, name: string): asserts value is number {\n if (!Number.isSafeInteger(value) || (value as number) < 0) {\n throw invalidArgument(`${name} must be a non-negative safe integer`, { name, value });\n }\n}\n\nexport function assertPositiveSafeInteger(value: unknown, name: string): asserts value is number {\n if (!Number.isSafeInteger(value) || (value as number) <= 0) {\n throw invalidArgument(`${name} must be a positive safe integer`, { name, value });\n }\n}\n", "import type {\n RangeRequest,\n WireTableBatch,\n WireTableBatchColumn,\n} from \"./model.js\";\n\ninterface CacheEntry<T> {\n readonly value: T;\n readonly byteLength: number;\n}\n\ninterface PermitWaiter {\n readonly key: string;\n readonly resolve: (release: () => void) => void;\n readonly reject: (reason: unknown) => void;\n}\n\nexport class PermitQueueFullError extends Error {\n constructor(readonly maxWaiters: number) {\n super(`The permit queue already has ${maxWaiters} waiters`);\n this.name = \"PermitQueueFullError\";\n }\n}\n\n/** A small FIFO permit queue whose pending acquisitions can be cancelled by key. */\nexport class AsyncPermitQueue {\n readonly #maxActive: number;\n readonly #maxWaiters: number;\n readonly #waiters: PermitWaiter[] = [];\n #active = 0;\n\n constructor(maxActive: number, maxWaiters: number) {\n if (!Number.isSafeInteger(maxActive) || maxActive <= 0) {\n throw new RangeError(\"maxActive must be a positive safe integer\");\n }\n if (!Number.isSafeInteger(maxWaiters) || maxWaiters < 0) {\n throw new RangeError(\"maxWaiters must be a non-negative safe integer\");\n }\n this.#maxActive = maxActive;\n this.#maxWaiters = maxWaiters;\n }\n\n acquire(key: string): Promise<() => void> {\n if (this.#active < this.#maxActive) {\n this.#active += 1;\n return Promise.resolve(this.#releaseOnce());\n }\n if (this.#waiters.length >= this.#maxWaiters) {\n return Promise.reject(new PermitQueueFullError(this.#maxWaiters));\n }\n return new Promise<() => void>((resolve, reject) => {\n this.#waiters.push({ key, resolve, reject });\n });\n }\n\n cancel(key: string, reason: unknown): boolean {\n const index = this.#waiters.findIndex((waiter) => waiter.key === key);\n if (index < 0) {\n return false;\n }\n const [waiter] = this.#waiters.splice(index, 1);\n waiter!.reject(reason);\n this.#wakeWaiters();\n return true;\n }\n\n #releaseOnce(): () => void {\n let released = false;\n return () => {\n if (released) {\n return;\n }\n released = true;\n this.#active -= 1;\n this.#wakeWaiters();\n };\n }\n\n #wakeWaiters(): void {\n while (this.#active < this.#maxActive && this.#waiters.length > 0) {\n const waiter = this.#waiters.shift()!;\n this.#active += 1;\n waiter.resolve(this.#releaseOnce());\n }\n }\n}\n\n/** A byte-bounded least-recently-used cache. */\nexport class ByteLruCache<T> {\n readonly #maxBytes: number;\n readonly #maxEntries: number;\n readonly #minimumEntryBytes: number;\n readonly #entries = new Map<string, CacheEntry<T>>();\n readonly #onRemove: ((key: string, value: T, byteLength: number) => void) | undefined;\n #byteLength = 0;\n\n constructor(\n maxBytes: number,\n options: Readonly<{\n maxEntries?: number;\n minimumEntryBytes?: number;\n onRemove?: (key: string, value: T, byteLength: number) => void;\n }> = {},\n ) {\n if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {\n throw new RangeError(\"maxBytes must be a non-negative safe integer\");\n }\n const maxEntries = options.maxEntries ?? Number.MAX_SAFE_INTEGER;\n if (!Number.isSafeInteger(maxEntries) || maxEntries < 0) {\n throw new RangeError(\"maxEntries must be a non-negative safe integer\");\n }\n const minimumEntryBytes = options.minimumEntryBytes ?? 0;\n if (!Number.isSafeInteger(minimumEntryBytes) || minimumEntryBytes < 0) {\n throw new RangeError(\"minimumEntryBytes must be a non-negative safe integer\");\n }\n this.#maxBytes = maxBytes;\n this.#maxEntries = maxEntries;\n this.#minimumEntryBytes = minimumEntryBytes;\n this.#onRemove = options.onRemove;\n }\n\n get maxBytes(): number {\n return this.#maxBytes;\n }\n\n get maxEntries(): number {\n return this.#maxEntries;\n }\n\n get(key: string): T | undefined {\n const entry = this.#entries.get(key);\n if (!entry) {\n return undefined;\n }\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n return entry.value;\n }\n\n set(key: string, value: T, byteLength: number, maxBytes = this.#maxBytes): void {\n if (!Number.isSafeInteger(byteLength) || byteLength < 0) {\n throw new RangeError(\"byteLength must be a non-negative safe integer\");\n }\n if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {\n throw new RangeError(\"maxBytes must be a non-negative safe integer\");\n }\n const effectiveMaxBytes = Math.min(this.#maxBytes, maxBytes);\n const chargedBytes = Math.max(byteLength, this.#minimumEntryBytes);\n if (chargedBytes > effectiveMaxBytes || this.#maxEntries === 0) {\n return;\n }\n\n const existing = this.#entries.get(key);\n if (existing) {\n this.#remove(key, existing);\n }\n\n while (\n this.#entries.size >= this.#maxEntries\n || this.#byteLength + chargedBytes > effectiveMaxBytes\n ) {\n const oldestKey = this.#entries.keys().next().value as string | undefined;\n if (oldestKey === undefined) {\n break;\n }\n const oldest = this.#entries.get(oldestKey)!;\n this.#remove(oldestKey, oldest);\n }\n\n this.#entries.set(key, { value, byteLength: chargedBytes });\n this.#byteLength += chargedBytes;\n }\n\n /** Evicts least-recently-used entries until the requested live cap is met. */\n trimTo(maxBytes: number): void {\n if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {\n throw new RangeError(\"maxBytes must be a non-negative safe integer\");\n }\n const effectiveMaxBytes = Math.min(this.#maxBytes, maxBytes);\n while (this.#byteLength > effectiveMaxBytes) {\n const oldestKey = this.#entries.keys().next().value as string | undefined;\n if (oldestKey === undefined) break;\n const oldest = this.#entries.get(oldestKey)!;\n this.#remove(oldestKey, oldest);\n }\n }\n\n deleteWhere(predicate: (key: string, value: T) => boolean): void {\n for (const [key, entry] of this.#entries) {\n if (!predicate(key, entry.value)) {\n continue;\n }\n this.#remove(key, entry);\n }\n }\n\n clear(): void {\n for (const [key, entry] of this.#entries) {\n this.#onRemove?.(key, entry.value, entry.byteLength);\n }\n this.#entries.clear();\n this.#byteLength = 0;\n }\n\n #remove(key: string, entry: CacheEntry<T>): void {\n this.#entries.delete(key);\n this.#byteLength -= entry.byteLength;\n this.#onRemove?.(key, entry.value, entry.byteLength);\n }\n}\n\nexport function rangeCacheKey(\n datasetHandle: string,\n tableId: string,\n revision: number,\n schemaVersion: number,\n range: RangeRequest,\n): string {\n return JSON.stringify([\n datasetHandle,\n tableId,\n revision,\n schemaVersion,\n range.rowStart,\n range.rowCount,\n range.columnStart,\n range.columnCount,\n ]);\n}\n\nexport function rangeCacheKeyBelongsToDataset(key: string, datasetHandle: string): boolean {\n return key.startsWith(`[${JSON.stringify(datasetHandle)},`);\n}\n\nexport function rangeCacheKeyBelongsToTable(\n key: string,\n datasetHandle: string,\n tableId: string,\n): boolean {\n return key.startsWith(\n `[${JSON.stringify(datasetHandle)},${JSON.stringify(tableId)},`,\n );\n}\n\nexport function rangeCacheKeyMatchesVersion(\n key: string,\n revision: number,\n schemaVersion: number,\n): boolean {\n try {\n const fields = JSON.parse(key) as unknown;\n return Array.isArray(fields)\n && fields.length === 8\n && fields[2] === revision\n && fields[3] === schemaVersion;\n } catch {\n return false;\n }\n}\n\n/**\n * Main-thread-owned immutable backing for a logical batch.\n *\n * The ArrayBuffers arrive as independently transferable Worker output and are\n * intentionally not cloned here. They remain unreachable through the public\n * batch facade; binary getters perform their own defensive copy.\n */\nexport type BatchBacking = Omit<WireTableBatch, \"buffers\" | \"columns\" | \"range\"> & Readonly<{\n range: Readonly<WireTableBatch[\"range\"]>;\n buffers: readonly ArrayBuffer[];\n columns: readonly WireTableBatchColumn[];\n}>;\n\nexport function createBatchBacking(batch: WireTableBatch): BatchBacking {\n const buffers = batch.buffers.map((buffer, index) => {\n if (!(buffer instanceof ArrayBuffer)) {\n throw new TypeError(`Transferred batch buffer ${index} must own an ArrayBuffer backing`);\n }\n return buffer;\n });\n const columns = batch.columns.map((column) => freezeBatchDescriptor(column));\n return Object.freeze({\n layoutVersion: batch.layoutVersion,\n tableId: batch.tableId,\n revision: batch.revision,\n schemaVersion: batch.schemaVersion,\n range: Object.freeze({ ...batch.range }),\n buffers: Object.freeze(buffers),\n columns: Object.freeze(columns),\n complete: batch.complete,\n });\n}\n\nexport function wireBatchByteLength(batch: WireTableBatch): number {\n return batch.buffers.reduce((total, buffer) => total + buffer.byteLength, 0);\n}\n\nfunction freezeBatchDescriptor<T extends object>(value: T): T {\n const seen = new WeakSet<object>();\n const freeze = (entry: unknown): void => {\n if (typeof entry !== \"object\" || entry === null || seen.has(entry)) {\n return;\n }\n // Buffer contents are owned by the backing and deliberately remain\n // readable by the logical facade. Freezing a non-empty typed array also\n // throws in current engines, so only descriptor objects are traversed.\n if (entry instanceof ArrayBuffer || ArrayBuffer.isView(entry)) {\n return;\n }\n seen.add(entry);\n for (const child of Object.values(entry)) {\n freeze(child);\n }\n Object.freeze(entry);\n };\n freeze(value);\n return value;\n}\n", "import { TabularkError, cancelledError, closedError } from \"./errors.js\";\nimport {\n PROTOCOL_VERSION,\n isRecord,\n type Operation,\n type ProtocolEvent,\n type ProtocolResponse,\n type ResponseKind,\n} from \"./protocol.js\";\n\ntype EventListener = (event: ProtocolEvent) => void;\ntype FailureListener = (error: TabularkError) => void;\n/** Private messages exchanged by the Worker source-byte broker. */\nexport type SourceBrokerListener = (value: unknown) => void;\n\ninterface PendingRequest {\n readonly resolve: (value: unknown) => void;\n readonly reject: (reason: unknown) => void;\n readonly expectedKind: ResponseKind;\n readonly cleanup: () => void;\n readonly onTelemetry?: (telemetry: OperationTelemetry | undefined) => void;\n}\n\ninterface RequestOptions {\n readonly transfer?: Transferable[];\n readonly signal?: AbortSignal;\n readonly timeoutMs?: number;\n /** Private opt-in operation telemetry callback. */\n readonly measure?: boolean;\n readonly onTelemetry?: (telemetry: OperationTelemetry | undefined) => void;\n}\n\nexport interface OperationTelemetry {\n readonly bytesRead: number;\n readonly peakReservationBytes: number;\n readonly sourceReads: number;\n readonly sourceCacheHitBytes: number;\n}\n\nconst DEFAULT_SHUTDOWN_TIMEOUT_MS = 2_000;\nconst RESPONSE_KINDS = new Set<ResponseKind>([\n \"hello\",\n \"dataset\",\n \"tables\",\n \"table\",\n \"metadata\",\n \"presentation\",\n \"presentationRange\",\n \"batch\",\n \"acknowledged\",\n]);\nconst EVENT_NAMES = new Set([\n \"progress\",\n \"metadata\",\n \"warning\",\n \"closed\",\n \"runtimeError\",\n]);\n\n/** Main-thread request multiplexer for one dedicated Worker. */\nexport class WorkerRpcClient {\n readonly #worker: Worker;\n readonly #pending = new Map<string, PendingRequest>();\n readonly #onEvent: EventListener;\n readonly #onFailure: FailureListener;\n readonly #onSourceMessage: SourceBrokerListener;\n #nextRequestId = 1;\n #closed = false;\n\n constructor(\n worker: Worker,\n onEvent: EventListener,\n onFailure: FailureListener = () => {},\n onSourceMessage: SourceBrokerListener = () => {},\n ) {\n this.#worker = worker;\n this.#onEvent = onEvent;\n this.#onFailure = onFailure;\n this.#onSourceMessage = onSourceMessage;\n worker.addEventListener(\"message\", this.#handleMessage);\n worker.addEventListener(\"error\", this.#handleWorkerFailure);\n worker.addEventListener(\"messageerror\", this.#handleWorkerFailure);\n }\n\n /** Sends one private broker response without exposing the Worker object. */\n postMessage(value: unknown, transfer: Transferable[] = []): void {\n if (this.#closed) return;\n try {\n this.#worker.postMessage(value, transfer);\n } catch {\n // The Worker failure path settles all pending protocol work. A broker\n // response that cannot be delivered is therefore already terminal.\n }\n }\n\n async request<T>(\n op: Operation,\n payload: unknown,\n expectedKind: ResponseKind,\n options: RequestOptions = {},\n ): Promise<T> {\n if (this.#closed) {\n throw closedError(\"Engine\");\n }\n if (options.signal?.aborted) {\n throw cancelledError();\n }\n\n const requestId = `r${this.#nextRequestId++}`;\n return new Promise<T>((resolve, reject) => {\n const cleanups: Array<() => void> = [];\n const cleanup = () => {\n for (const dispose of cleanups.splice(0)) {\n dispose();\n }\n };\n if (options.signal) {\n const abort = () => {\n const pending = this.#pending.get(requestId);\n if (!pending) {\n return;\n }\n this.#pending.delete(requestId);\n pending.cleanup();\n this.#postCancel(requestId);\n reject(cancelledError());\n };\n options.signal.addEventListener(\"abort\", abort, { once: true });\n cleanups.push(() => options.signal?.removeEventListener(\"abort\", abort));\n }\n if (options.timeoutMs !== undefined) {\n const timeoutMs = Math.max(1, options.timeoutMs);\n const timeoutId = globalThis.setTimeout(() => {\n if (!this.#pending.has(requestId)) {\n return;\n }\n this.#failRuntime(\n new TabularkError(\n \"RUNTIME_FAILURE\",\n `The Tabulark Worker did not respond to ${op} within ${timeoutMs}ms`,\n ),\n );\n }, timeoutMs);\n cleanups.push(() => globalThis.clearTimeout(timeoutId));\n }\n\n this.#pending.set(requestId, {\n resolve: (value) => resolve(value as T),\n reject,\n expectedKind,\n cleanup,\n ...(options.onTelemetry === undefined ? {} : { onTelemetry: options.onTelemetry }),\n });\n try {\n this.#worker.postMessage(\n {\n protocolVersion: PROTOCOL_VERSION,\n requestId,\n op,\n payload,\n ...(options.measure === true ? { measure: true } : {}),\n },\n options.transfer ?? [],\n );\n } catch (error) {\n this.#pending.delete(requestId);\n cleanup();\n reject(\n new TabularkError(\"RUNTIME_FAILURE\", \"Could not send a request to the Worker\", {\n cause: error,\n }),\n );\n }\n });\n }\n\n async shutdown(\n timeoutMs = DEFAULT_SHUTDOWN_TIMEOUT_MS,\n options: Pick<RequestOptions, \"measure\" | \"onTelemetry\"> = {},\n ): Promise<void> {\n if (this.#closed) {\n return;\n }\n try {\n await this.request(\"shutdown\", {}, \"acknowledged\", { timeoutMs, ...options });\n } catch {\n // Termination below is still required after a failed graceful shutdown.\n } finally {\n this.terminate();\n }\n }\n\n terminate(\n error = new TabularkError(\"RUNTIME_FAILURE\", \"The Tabulark Worker was terminated\"),\n notifyFailure = false,\n ): void {\n if (this.#stop(error) && notifyFailure) {\n this.#notifyFailure(error);\n }\n }\n\n #handleMessage = (event: MessageEvent<unknown>): void => {\n const value = event.data;\n if (isSourceBrokerMessage(value)) {\n try {\n this.#onSourceMessage(value);\n } catch (error) {\n this.#failRuntime(new TabularkError(\n \"RUNTIME_FAILURE\",\n \"The Worker source broker failed\",\n { cause: error },\n ));\n }\n return;\n }\n if (isValidProtocolEvent(value)) {\n try {\n this.#onEvent(value);\n } catch (error) {\n this.#failRuntime(\n new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n \"The Worker emitted an invalid runtime event\",\n { cause: error },\n ),\n );\n }\n return;\n }\n if (looksLikeProtocolEvent(value) || (looksLikeProtocolResponse(value) && !isValidProtocolResponse(value))) {\n this.#failRuntime(\n new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n \"The Worker returned a malformed or incompatible protocol message\",\n ),\n );\n return;\n }\n if (!isValidProtocolResponse(value)) {\n return;\n }\n const pending = this.#pending.get(value.requestId);\n if (!pending) {\n return;\n }\n this.#pending.delete(value.requestId);\n pending.cleanup();\n\n if (value.status === \"failure\") {\n optionsTelemetry(\n pending,\n (value as ProtocolFailureWithTelemetry).telemetry,\n );\n pending.reject(TabularkError.fromSerialized(value.error));\n return;\n }\n if (value.result.kind !== pending.expectedKind) {\n const error = new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n `Expected a ${pending.expectedKind} response, received ${value.result.kind}`,\n );\n pending.reject(error);\n this.#failRuntime(error);\n return;\n }\n optionsTelemetry(\n pending,\n (value.result as ProtocolResultWithTelemetry).telemetry,\n );\n pending.resolve(value.result.data);\n };\n\n #handleWorkerFailure = (event: Event): void => {\n if (this.#closed) {\n return;\n }\n let message = \"The Tabulark Worker stopped unexpectedly\";\n if (typeof ErrorEvent !== \"undefined\" && event instanceof ErrorEvent && event.message) {\n message = event.message;\n } else if (event.type === \"messageerror\") {\n message = \"The Tabulark Worker could not deserialize a message\";\n }\n this.#failRuntime(new TabularkError(\"RUNTIME_FAILURE\", message));\n };\n\n #postCancel(targetRequestId: string): void {\n if (this.#closed) {\n return;\n }\n try {\n this.#worker.postMessage({\n protocolVersion: PROTOCOL_VERSION,\n requestId: `r${this.#nextRequestId++}`,\n op: \"cancel\",\n payload: { targetRequestId },\n });\n } catch {\n // The caller has already received its cancellation result.\n }\n }\n\n #failPending(error: TabularkError): void {\n for (const pending of this.#pending.values()) {\n pending.cleanup();\n pending.reject(error);\n }\n this.#pending.clear();\n }\n\n #failRuntime(error: TabularkError): void {\n if (this.#stop(error)) {\n this.#notifyFailure(error);\n }\n }\n\n #stop(error: TabularkError): boolean {\n if (this.#closed) {\n return false;\n }\n this.#closed = true;\n this.#worker.removeEventListener(\"message\", this.#handleMessage);\n this.#worker.removeEventListener(\"error\", this.#handleWorkerFailure);\n this.#worker.removeEventListener(\"messageerror\", this.#handleWorkerFailure);\n try {\n this.#worker.terminate();\n } catch {\n // A failed Worker is already unusable; pending callers still need a terminal result.\n }\n this.#failPending(error);\n return true;\n }\n\n #notifyFailure(error: TabularkError): void {\n try {\n this.#onFailure(error);\n } catch {\n // The Worker is already terminal; a client callback cannot recover it.\n }\n }\n}\n\nfunction isSourceBrokerMessage(value: unknown): boolean {\n return isRecord(value)\n && (value.type === \"source-read\" || value.type === \"source-read-cancel\" || value.type === \"source-close\");\n}\n\nfunction optionsTelemetry(\n pending: PendingRequest,\n value: unknown,\n): void {\n if (!pending.onTelemetry) {\n return;\n }\n if (\n typeof value === \"object\"\n && value !== null\n && !Array.isArray(value)\n && Number.isSafeInteger((value as { bytesRead?: unknown }).bytesRead)\n && Number.isSafeInteger((value as { peakReservationBytes?: unknown }).peakReservationBytes)\n ) {\n const bytesRead = (value as { bytesRead: number }).bytesRead;\n const peakReservationBytes = (value as { peakReservationBytes: number }).peakReservationBytes;\n pending.onTelemetry({\n bytesRead: bytesRead >= 0 ? bytesRead : 0,\n peakReservationBytes: peakReservationBytes >= 0 ? peakReservationBytes : 0,\n sourceReads: telemetryQuantity(value, \"sourceReads\"),\n sourceCacheHitBytes: telemetryQuantity(value, \"sourceCacheHitBytes\"),\n });\n } else {\n pending.onTelemetry(undefined);\n }\n}\n\nfunction telemetryQuantity(value: object, key: string): number {\n const candidate = (value as Record<string, unknown>)[key];\n return Number.isSafeInteger(candidate) && (candidate as number) >= 0\n ? candidate as number\n : 0;\n}\n\ntype ProtocolResultWithTelemetry = {\n readonly telemetry?: unknown;\n};\n\ntype ProtocolFailureWithTelemetry = {\n readonly telemetry?: unknown;\n};\n\nfunction isValidProtocolResponse(value: unknown): value is ProtocolResponse {\n if (\n !isRecord(value)\n || value.protocolVersion !== PROTOCOL_VERSION\n || typeof value.requestId !== \"string\"\n || value.requestId.length === 0\n ) {\n return false;\n }\n if (value.status === \"success\") {\n return isRecord(value.result)\n && typeof value.result.kind === \"string\"\n && RESPONSE_KINDS.has(value.result.kind as ResponseKind);\n }\n if (value.status === \"failure\") {\n return isSerializedError(value.error);\n }\n return false;\n}\n\nfunction isValidProtocolEvent(value: unknown): value is ProtocolEvent {\n if (\n !isRecord(value)\n || value.protocolVersion !== PROTOCOL_VERSION\n || typeof value.event !== \"string\"\n || !EVENT_NAMES.has(value.event)\n || !(\"payload\" in value)\n ) {\n return false;\n }\n if (\n !optionalNonEmptyString(value.requestId)\n || !optionalNonEmptyString(value.datasetHandle)\n || !optionalNonEmptyString(value.tableHandle)\n || !optionalNonEmptyString(value.tableId)\n || !optionalNonNegativeInteger(value.revision)\n ) {\n return false;\n }\n if (value.tableHandle !== undefined && value.datasetHandle === undefined) {\n return false;\n }\n if (value.event === \"runtimeError\") {\n return value.datasetHandle !== undefined\n || (value.tableHandle === undefined && value.tableId === undefined);\n }\n return value.datasetHandle !== undefined;\n}\n\nfunction isSerializedError(value: unknown): boolean {\n return isRecord(value)\n && typeof value.code === \"string\"\n && typeof value.message === \"string\"\n && typeof value.retryable === \"boolean\";\n}\n\nfunction optionalNonEmptyString(value: unknown): boolean {\n return value === undefined || (typeof value === \"string\" && value.length > 0);\n}\n\nfunction optionalNonNegativeInteger(value: unknown): boolean {\n return value === undefined || (Number.isSafeInteger(value) && (value as number) >= 0);\n}\n\nfunction looksLikeProtocolResponse(value: unknown): boolean {\n return isRecord(value)\n && (\"requestId\" in value || \"status\" in value || \"result\" in value || \"error\" in value);\n}\n\nfunction looksLikeProtocolEvent(value: unknown): boolean {\n return isRecord(value) && \"event\" in value;\n}\n", "/**\n * Bounded, repeatable byte-range sources.\n *\n * A RangeSource is intentionally a very small host-side capability. The\n * worker never receives the implementation (or a URL); it is given an opaque\n * reader handle by the client and asks the host for bounded byte ranges.\n */\n\n/** The largest addressable source (2^32 - 1 bytes). */\nexport const MAX_RANGE_SOURCE_BYTES = 0xffff_ffff;\n\n/** A half-open byte interval [offset, offset + length). */\nexport interface ByteRange {\n readonly offset: number;\n readonly length: number;\n}\n\n/** A stable identity for one opened view of a source. */\nexport interface RangeSourceSnapshot {\n readonly id: string;\n readonly strength: \"strong\" | \"weak\";\n}\n\n/** Options supplied to every reader operation. */\nexport interface RangeSourceReadOptions {\n readonly signal: AbortSignal;\n}\n\n/** A reader returned by a RangeSource.open() call. */\nexport interface RangeSourceReader {\n /** Exact source size in bytes. */\n readonly size: number;\n /** Validator captured while opening the source. */\n readonly snapshot: RangeSourceSnapshot;\n /** Maximum number of provider reads that may run concurrently. Defaults to 1. */\n readonly maxConcurrency?: number;\n /** Reads exactly range.length bytes, or rejects. */\n read(\n range: ByteRange,\n options: RangeSourceReadOptions,\n ): Promise<ArrayBuffer | ArrayBufferView>;\n /** Releases all resources. Calling close more than once is harmless. */\n close(): Promise<void> | void;\n}\n\n/** Open-time limits owned by the engine. */\nexport interface RangeSourceOpenOptions {\n readonly signal: AbortSignal;\n readonly maxSourceBytes: number;\n readonly maxStagingBytes: number;\n}\n\n/** A repeatably openable source addressed by bounded byte ranges. */\nexport interface RangeSource {\n readonly kind: \"range\";\n readonly name?: string;\n open(options: RangeSourceOpenOptions): Promise<RangeSourceReader>;\n}\n\n/** Runtime check used at the public engine boundary. */\nexport function isRangeSource(value: unknown): value is RangeSource {\n if (typeof value !== \"object\" || value === null) return false;\n try {\n const candidate = value as { kind?: unknown; open?: unknown };\n return candidate.kind === \"range\" && typeof candidate.open === \"function\";\n } catch {\n return false;\n }\n}\n\n/**\n * Validates a byte range without coercing values. Keeping this check in one\n * place prevents unsafe floating-point arithmetic at both HTTP and Worker\n * boundaries.\n */\nexport function validateByteRange(\n range: unknown,\n size: number,\n): asserts range is ByteRange {\n if (!isSafeNonNegativeInteger(size) || size > MAX_RANGE_SOURCE_BYTES) {\n throw new RangeError(\"source size is outside the supported range\");\n }\n if (typeof range !== \"object\" || range === null) {\n throw new RangeError(\"range must be an object\");\n }\n const candidate = range as { offset?: unknown; length?: unknown };\n let offset: unknown;\n let length: unknown;\n try {\n offset = candidate.offset;\n length = candidate.length;\n } catch {\n throw new RangeError(\"range is outside the source\");\n }\n if (!isSafeNonNegativeInteger(offset)\n || !isSafeNonNegativeInteger(length)\n || offset > MAX_RANGE_SOURCE_BYTES\n || length > MAX_RANGE_SOURCE_BYTES\n || offset + length > size) {\n throw new RangeError(\"range is outside the source\");\n }\n}\n\n/** Validates and freezes a reader snapshot. */\nexport function normalizeRangeSourceSnapshot(value: unknown): RangeSourceSnapshot {\n if (typeof value !== \"object\" || value === null) {\n throw new RangeError(\"reader snapshot must be an object\");\n }\n const candidate = value as { id?: unknown; strength?: unknown };\n if (typeof candidate.id !== \"string\"\n || candidate.id.length === 0\n || candidate.id.length > 256\n || candidate.strength !== \"strong\" && candidate.strength !== \"weak\") {\n throw new RangeError(\"reader snapshot is invalid\");\n }\n return Object.freeze({ id: candidate.id, strength: candidate.strength });\n}\n\n/** Validates a reader object returned by an adapter/broker. */\nexport function validateRangeSourceReader(value: unknown): value is RangeSourceReader {\n if (typeof value !== \"object\" || value === null) return false;\n try {\n const candidate = value as {\n size?: unknown;\n snapshot?: unknown;\n maxConcurrency?: unknown;\n read?: unknown;\n close?: unknown;\n };\n if (!isSafeNonNegativeInteger(candidate.size)\n || candidate.size > MAX_RANGE_SOURCE_BYTES\n || !isValidSnapshot(candidate.snapshot)\n || typeof candidate.read !== \"function\"\n || typeof candidate.close !== \"function\") {\n return false;\n }\n return candidate.maxConcurrency === undefined\n || (isSafeNonNegativeInteger(candidate.maxConcurrency)\n && candidate.maxConcurrency >= 1\n && candidate.maxConcurrency <= 4);\n } catch {\n // A hostile proxy/getter is an invalid reader, not an unstructured host\n // exception that should escape the public open() contract.\n return false;\n }\n}\n\n/** Converts an ArrayBuffer or view to a fresh, exact-length ArrayBuffer. */\nexport function copyRangeBytes(value: ArrayBuffer | ArrayBufferView): ArrayBuffer {\n if (value instanceof ArrayBuffer) return value.slice(0);\n if (!ArrayBuffer.isView(value)) {\n throw new RangeError(\"reader returned a non-buffer value\");\n }\n const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy.buffer;\n}\n\n/** Returns whether a value is a safe non-negative integer. */\nexport function isSafeNonNegativeInteger(value: unknown): value is number {\n return typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction isValidSnapshot(value: unknown): value is RangeSourceSnapshot {\n if (typeof value !== \"object\" || value === null) return false;\n const candidate = value as { id?: unknown; strength?: unknown };\n return typeof candidate.id === \"string\"\n && candidate.id.length > 0\n && candidate.id.length <= 256\n && (candidate.strength === \"strong\" || candidate.strength === \"weak\");\n}\n", "/**\n * Host-side source policy shared by the stable client and its Worker.\n *\n * This is deliberately a binary constant (rather than a decimal \"2G\" value):\n * the large-source contract is exactly 2 * 1024^3 bytes. Keeping the value\n * in one module prevents the client and Worker from drifting at the boundary.\n */\nexport const MAX_LARGE_SOURCE_BYTES = 2 * 1024 * 1024 * 1024;\n\n// RangeSource is kept in a small standalone module so the stable client and\n// the optional HTTP entrypoint share one structural contract without pulling\n// HTTP/fetch code into the core bundle.\nexport {\n MAX_RANGE_SOURCE_BYTES,\n isRangeSource,\n validateByteRange,\n validateRangeSourceReader,\n copyRangeBytes,\n} from \"./range-source.js\";\nexport type {\n ByteRange,\n RangeSource,\n RangeSourceOpenOptions,\n RangeSourceReader,\n RangeSourceReadOptions,\n RangeSourceSnapshot,\n} from \"./range-source.js\";\n\n/** Selects the bounded default path or the large local-Blob path. */\nexport type SourceMode = \"auto\" | \"large\";\n\nexport function isSourceMode(value: unknown): value is SourceMode {\n return value === \"auto\" || value === \"large\";\n}\n", "import { TabularkError, cancelledError, closedError, invalidArgument } from \"./errors.js\";\nimport {\n resolveOfficialAdapter,\n type AdapterDescriptor,\n type AdapterRegistration,\n type ArrowIpcAdapterOptions,\n type DelimitedAdapterOptions,\n type ExcelAdapterOptions,\n type OfficialAdapterId,\n type ParquetAdapterOptions,\n} from \"./adapters.js\";\nimport {\n DEFAULT_MEMORY_BUDGET_BYTES,\n MAX_ARRAY_BUFFER_BYTES,\n ColumnarTableBatch,\n deriveMemoryBudgetLimits,\n normalizeDataType,\n normalizeMetadata,\n validateRange,\n type RangeRequest,\n type MergedCellRegion,\n type PresentationAxisEntry,\n type PresentationRange,\n type PresentationStyle,\n type SpreadsheetPresentation,\n type TablePresentation,\n type TableBatch,\n type TableCapabilities,\n type TableDescriptor,\n type TableMetadata,\n type WireTableBatch,\n type MemoryBudgetLimits,\n} from \"./model.js\";\nimport {\n ADAPTER_API_VERSION,\n BATCH_LAYOUT_VERSION,\n PROTOCOL_VERSION,\n isRecord,\n type ProtocolEvent,\n} from \"./protocol.js\";\nimport {\n officialAdapterManifestEntry,\n type OfficialSourceAccess,\n} from \"./official-adapter-manifest.js\";\nimport {\n type BatchBacking,\n ByteLruCache,\n createBatchBacking,\n rangeCacheKey,\n rangeCacheKeyBelongsToDataset,\n rangeCacheKeyBelongsToTable,\n rangeCacheKeyMatchesVersion,\n wireBatchByteLength,\n} from \"./range-cache.js\";\nimport { WorkerRpcClient, type OperationTelemetry } from \"./rpc-client.js\";\nimport {\n MAX_LARGE_SOURCE_BYTES,\n isSourceMode,\n type SourceMode,\n} from \"./source.js\";\nimport {\n MAX_RANGE_SOURCE_BYTES,\n copyRangeBytes,\n isRangeSource,\n isSafeNonNegativeInteger,\n normalizeRangeSourceSnapshot,\n validateRangeSourceReader,\n type RangeSource,\n type RangeSourceReader,\n} from \"./range-source.js\";\n\nexport type { SourceMode } from \"./source.js\";\nexport type {\n ByteRange,\n RangeSource,\n RangeSourceReader,\n RangeSourceSnapshot,\n} from \"./range-source.js\";\n\nconst MIN_MEMORY_BUDGET_BYTES = 8 * 1024 * 1024;\nconst LIFECYCLE_CLOSE_TIMEOUT_MS = 2_000;\nconst MAX_ORPHAN_HANDLES = 32;\nconst MAX_ORPHAN_EVENTS_PER_HANDLE = 16;\nconst MAX_ORPHAN_EVENTS = 256;\n/** Keep diagnostics useful without allowing an untrusted source to grow memory without bound. */\nconst MAX_DIAGNOSTICS = 1_000;\nconst MAX_DIAGNOSTIC_MESSAGE_LENGTH = 512;\nconst MAX_PERFORMANCE_SAMPLES = 128;\nconst MIN_BATCH_CACHE_ENTRY_BYTES = 4 * 1024;\nconst MAX_BATCH_CACHE_ENTRIES = 512;\n// The core and HTTP helper are separate bundles. A shared weak store lets both\n// see the same open-options reservation without adding any observable key to\n// the public RangeSourceOpenOptions object.\nconst RANGE_SOURCE_HOST_RESERVATION_STORE = Symbol.for(\n \"tabulark.internal.range-source-reservation-store.v1\",\n);\n\ninterface RangeSourceHostReservations {\n reserveStaging(bytes: number, signal: AbortSignal): Promise<() => void>;\n reserveRetained(bytes: number): () => void;\n}\n\nfunction attachRangeSourceHostReservations<T extends object>(\n options: T,\n reservations: RangeSourceHostReservations,\n): T {\n rangeSourceHostReservationStore().set(options, Object.freeze(reservations));\n return options;\n}\n\nfunction rangeSourceHostReservationStore(): WeakMap<object, RangeSourceHostReservations> {\n const host = globalThis as typeof globalThis & {\n [RANGE_SOURCE_HOST_RESERVATION_STORE]?: WeakMap<object, RangeSourceHostReservations>;\n };\n const existing = host[RANGE_SOURCE_HOST_RESERVATION_STORE];\n if (existing instanceof WeakMap) return existing;\n const store = new WeakMap<object, RangeSourceHostReservations>();\n Object.defineProperty(host, RANGE_SOURCE_HOST_RESERVATION_STORE, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: store,\n });\n return store;\n}\n\nexport interface OpenSourceOptions<Options = unknown> {\n /** One of the official descriptors registered when the engine was created. */\n readonly adapter: AdapterDescriptor<OfficialAdapterId, Options>;\n readonly adapterOptions?: Options;\n /**\n * Selects the bounded default source path or the local Blob path that may\n * address files up to 2 GiB. Defaults to `auto`.\n *\n * Large mode is reserved for local `File`/`Blob` inputs and never changes\n * ArrayBuffer staging limits.\n */\n readonly sourceMode?: SourceMode;\n /** Detaches an ArrayBuffer input. Defaults to false; Blob input cannot be transferred. */\n readonly transferInput?: boolean;\n /** Cancels opening and releases any Worker-side source created by the request. */\n readonly signal?: AbortSignal;\n}\n\nexport interface EngineOptions {\n /** The engine's immutable allow-list. At least one official adapter is required. */\n readonly adapters: readonly AdapterDescriptor[];\n readonly memoryBudgetBytes?: number;\n readonly workerName?: string;\n}\n\nexport interface ReadRangeOptions {\n readonly signal?: AbortSignal;\n}\n\nexport interface RuntimeProgress {\n readonly sourceHandle: string;\n readonly tableId?: string;\n readonly revision?: number;\n readonly bytesScanned: number;\n readonly rowsDiscovered: number;\n readonly done: boolean;\n}\n\nexport interface SourceWarning {\n readonly handle: string;\n readonly kind: string;\n readonly message: string;\n readonly tableId?: string;\n readonly resource?: string;\n readonly requiredBytes?: number;\n readonly availableBytes?: number;\n readonly byteOffset?: number;\n /** Compatible alias used by structured diagnostics. */\n readonly sourceOffset?: number;\n readonly row?: number;\n readonly column?: number;\n}\n\n/** A safe, structured source or runtime diagnostic. */\nexport interface TabularkDiagnostic {\n readonly code: string;\n readonly severity: \"warning\" | \"error\";\n readonly message: string;\n readonly recoverable: boolean;\n readonly resource?: string;\n readonly requiredBytes?: number;\n readonly availableBytes?: number;\n readonly sourceOffset?: number;\n readonly tableId?: string;\n readonly revision?: number;\n readonly row?: number;\n readonly column?: number;\n}\n\n/** Logical capabilities of an opened dataset. */\nexport interface DatasetCapabilities {\n readonly adapterId: OfficialAdapterId;\n readonly sourceAccess: OfficialSourceAccess;\n readonly progressive: boolean;\n readonly maxSourceBytes: number;\n readonly multiTable: boolean;\n readonly presentation: boolean;\n readonly typedValues: boolean;\n}\n\n/** Optional, privacy-preserving operation timing sample. */\nexport interface PerformanceSample {\n /** Logical operation stage; implementation and transport names are omitted. */\n readonly stage: string;\n /** Elapsed duration relative to the operation start, in milliseconds. */\n readonly durationMs: number;\n /** Bytes read from the source during this stage, when known. */\n readonly bytesRead: number;\n /** Whether the result came from a retained range cache. */\n readonly cacheHit: boolean;\n /** Peak reservation observed by the host, when known. */\n readonly peakReservationBytes: number;\n /** Number of provider range reads represented by this operation. */\n readonly sourceReads: number;\n /** Bytes served from the Worker source-range cache. */\n readonly sourceCacheHitBytes: number;\n}\n\nexport type DatasetEvent =\n | Readonly<{ type: \"progress\"; progress: RuntimeProgress }>\n | Readonly<{ type: \"metadata\"; metadata: Readonly<TableMetadata> }>\n | Readonly<{ type: \"warning\"; warning: SourceWarning }>\n | Readonly<{ type: \"closed\" }>\n | Readonly<{ type: \"runtimeError\"; error: TabularkError }>;\n\nexport type TableEvent = Exclude<DatasetEvent, Readonly<{ type: \"progress\" }>>;\n\nexport type Unsubscribe = () => void;\n\nexport interface DatasetSession {\n readonly tables: readonly Readonly<TableDescriptor>[];\n openTable(tableId: string): Promise<TableHandle>;\n subscribe(listener: (event: DatasetEvent) => void): Unsubscribe;\n getDiagnostics(): readonly TabularkDiagnostic[];\n subscribeDiagnostics(listener: (diagnostic: TabularkDiagnostic) => void): Unsubscribe;\n getCapabilities(): Readonly<DatasetCapabilities>;\n close(): Promise<void>;\n}\n\nexport interface TableHandle {\n readonly metadata: Readonly<TableMetadata>;\n getPresentation(): Promise<TablePresentation | null>;\n readPresentationRange(\n request: RangeRequest,\n options?: ReadRangeOptions,\n ): Promise<PresentationRange | null>;\n readRange(request: RangeRequest, options?: ReadRangeOptions): Promise<TableBatch>;\n subscribe(listener: (event: TableEvent) => void): Unsubscribe;\n getDiagnostics(): readonly TabularkDiagnostic[];\n subscribeDiagnostics(listener: (diagnostic: TabularkDiagnostic) => void): Unsubscribe;\n getCapabilities(): Readonly<TableCapabilities>;\n close(): Promise<void>;\n}\n\nexport interface TabularkEngine {\n open<Options>(source: Blob | ArrayBuffer | RangeSource, options: OpenSourceOptions<Options>): Promise<DatasetSession>;\n subscribePerformance(listener: (sample: PerformanceSample) => void): Unsubscribe;\n close(): Promise<void>;\n dispose(): Promise<void>;\n}\n\ninterface NormalizedEngineOptions {\n readonly memoryBudgetBytes: number;\n readonly limits: MemoryBudgetLimits;\n readonly adapters: readonly AdapterRegistration[];\n readonly workerUrl: string;\n readonly workerName: string;\n}\n\ninterface NormalizedOpenOptions {\n readonly adapter: AdapterRegistration;\n readonly options: Readonly<Record<string, unknown>>;\n readonly sourceMode: SourceMode;\n readonly isRangeSource: boolean;\n}\n\ninterface SourceReaderRecord {\n readonly handle: string;\n readonly size: number;\n readonly maxConcurrency: number;\n readonly reader: RangeSourceReader;\n readonly pending: Map<string, AbortController>;\n readonly concurrency: SourceReadConcurrencyLimiter;\n closed: boolean;\n}\n\ninterface SourceStagingPermit {\n readonly release: () => void;\n}\n\ninterface SourceStagingWaiter {\n readonly bytes: number;\n readonly signal: AbortSignal;\n readonly resolve: (permit: SourceStagingPermit) => void;\n readonly reject: (error: unknown) => void;\n onAbort: () => void;\n}\n\n/**\n * Aggregates transient host-side source buffers across every opened reader.\n * A per-request length check is insufficient: several readers can otherwise\n * each consume the full staging slice at once. Waiting here keeps the bound\n * hard without making a valid adapter operation fail merely because another\n * read is currently transferring bytes.\n */\nclass SourceStagingLimiter {\n readonly #capacity: number;\n readonly #queue: SourceStagingWaiter[] = [];\n #used = 0;\n #closed = false;\n\n constructor(capacity: number) {\n this.#capacity = Math.max(1, Number.isSafeInteger(capacity) ? capacity : 1);\n }\n\n acquire(bytes: number, signal: AbortSignal): Promise<SourceStagingPermit> {\n if (!Number.isSafeInteger(bytes) || bytes < 0) {\n return Promise.reject(new TabularkError(\n \"RANGE_UNSUPPORTED\",\n \"The source range length is invalid\",\n ));\n }\n if (bytes > this.#capacity) {\n return Promise.reject(new TabularkError(\n \"RESOURCE_LIMIT\",\n \"The source exceeds its staging budget\",\n {\n details: {\n resource: \"source-staging\",\n requiredBytes: bytes,\n availableBytes: this.#capacity,\n },\n },\n ));\n }\n if (this.#closed) return Promise.reject(closedError(\"Source staging\"));\n if (signal.aborted) return Promise.reject(cancelledError());\n if (this.#used + bytes <= this.#capacity) {\n return Promise.resolve(this.#grant(bytes));\n }\n return new Promise<SourceStagingPermit>((resolve, reject) => {\n const waiter: SourceStagingWaiter = {\n bytes,\n signal,\n resolve,\n reject,\n onAbort: () => undefined,\n };\n const onAbort = (): void => {\n const index = this.#queue.indexOf(waiter);\n if (index >= 0) this.#queue.splice(index, 1);\n signal.removeEventListener(\"abort\", onAbort);\n reject(cancelledError());\n };\n waiter.onAbort = onAbort;\n signal.addEventListener(\"abort\", onAbort, { once: true });\n this.#queue.push(waiter);\n this.#drain();\n });\n }\n\n close(): void {\n if (this.#closed) return;\n this.#closed = true;\n for (const waiter of this.#queue.splice(0)) {\n waiter.signal.removeEventListener(\"abort\", waiter.onAbort);\n waiter.reject(closedError(\"Source staging\"));\n }\n }\n\n #grant(bytes: number): SourceStagingPermit {\n this.#used += bytes;\n let released = false;\n return Object.freeze({\n release: () => {\n if (released) return;\n released = true;\n this.#used = Math.max(0, this.#used - bytes);\n this.#drain();\n },\n });\n }\n\n #drain(): void {\n if (this.#closed) return;\n for (;;) {\n let selected = -1;\n for (let index = 0; index < this.#queue.length; index += 1) {\n const waiter = this.#queue[index]!;\n if (waiter.signal.aborted) {\n this.#queue.splice(index, 1);\n waiter.signal.removeEventListener(\"abort\", waiter.onAbort);\n waiter.reject(cancelledError());\n index -= 1;\n continue;\n }\n if (this.#used + waiter.bytes <= this.#capacity) {\n selected = index;\n break;\n }\n }\n if (selected < 0) return;\n const waiter = this.#queue.splice(selected, 1)[0]!;\n waiter.signal.removeEventListener(\"abort\", waiter.onAbort);\n waiter.resolve(this.#grant(waiter.bytes));\n }\n }\n}\n\n/** Enforces a reader's advertised 1\u20134 provider concurrency at the broker. */\nclass SourceReadConcurrencyLimiter {\n readonly #limit: number;\n readonly #queue: Array<{\n readonly signal: AbortSignal;\n readonly resolve: (release: () => void) => void;\n readonly reject: (error: unknown) => void;\n onAbort: () => void;\n }> = [];\n #active = 0;\n #closed = false;\n\n constructor(limit: number) {\n this.#limit = Math.min(4, Math.max(1, Number.isSafeInteger(limit) ? limit : 1));\n }\n\n acquire(signal: AbortSignal): Promise<() => void> {\n if (this.#closed) return Promise.reject(closedError(\"Range source reader\"));\n if (signal.aborted) return Promise.reject(cancelledError());\n if (this.#active < this.#limit) {\n this.#active += 1;\n return Promise.resolve(this.#grant());\n }\n return new Promise<() => void>((resolve, reject) => {\n const entry: {\n readonly signal: AbortSignal;\n readonly resolve: (release: () => void) => void;\n readonly reject: (error: unknown) => void;\n onAbort: () => void;\n } = {\n signal,\n resolve,\n reject,\n onAbort: () => undefined,\n };\n const onAbort = (): void => {\n const index = this.#queue.indexOf(entry);\n if (index >= 0) this.#queue.splice(index, 1);\n signal.removeEventListener(\"abort\", onAbort);\n reject(cancelledError());\n };\n entry.onAbort = onAbort;\n signal.addEventListener(\"abort\", onAbort, { once: true });\n this.#queue.push(entry);\n });\n }\n\n close(): void {\n if (this.#closed) return;\n this.#closed = true;\n for (const entry of this.#queue.splice(0)) {\n entry.signal.removeEventListener(\"abort\", entry.onAbort);\n entry.reject(closedError(\"Range source reader\"));\n }\n }\n\n #grant(): () => void {\n let released = false;\n return () => {\n if (released) return;\n released = true;\n this.#active = Math.max(0, this.#active - 1);\n this.#drain();\n };\n }\n\n #drain(): void {\n if (this.#closed) return;\n while (this.#active < this.#limit && this.#queue.length > 0) {\n const entry = this.#queue.shift()!;\n entry.signal.removeEventListener(\"abort\", entry.onAbort);\n if (entry.signal.aborted) {\n entry.reject(cancelledError());\n continue;\n }\n this.#active += 1;\n entry.resolve(this.#grant());\n }\n }\n}\n\ninterface PerformanceRequestOptions {\n readonly measure?: boolean;\n readonly onTelemetry?: (telemetry: OperationTelemetry | undefined) => void;\n}\n\ninterface DatasetCapabilitySeed {\n readonly adapterId: OfficialAdapterId;\n readonly sourceAccess: OfficialSourceAccess;\n readonly progressive: boolean;\n readonly maxSourceBytes: number;\n readonly multiTable: boolean;\n readonly presentation: boolean;\n readonly typedValues: boolean;\n}\n\ninterface RangeSingleflight {\n readonly key: string;\n readonly datasetHandle: string;\n readonly tableId: string;\n readonly controller: AbortController;\n readonly callers: Set<symbol>;\n promise: Promise<BatchBacking>;\n settled: boolean;\n bytesRead: number;\n peakReservationBytes: number;\n sourceReads: number;\n sourceCacheHitBytes: number;\n}\n\nclass Engine implements TabularkEngine {\n readonly #rpc: WorkerRpcClient;\n readonly #rangeCache: ByteLruCache<BatchBacking>;\n readonly #rangeSingleflight = new Map<string, RangeSingleflight>();\n readonly #limits: MemoryBudgetLimits;\n readonly #maxArrayBufferBytes: number;\n readonly #adapters: ReadonlyMap<OfficialAdapterId, AdapterRegistration>;\n readonly #sourceStaging: SourceStagingLimiter;\n #retainedSourceBytes = 0;\n readonly #sourceReaders = new Map<string, SourceReaderRecord>();\n readonly #datasetSources = new Map<string, string>();\n readonly #openingSources = new Set<AbortController>();\n #nextSourceHandle = 1;\n readonly #sessions = new Map<string, DatasetSessionImpl>();\n readonly #orphanEvents = new Map<string, ProtocolEvent[]>();\n readonly #performanceListeners = new Set<(sample: PerformanceSample) => void>();\n readonly #performanceQueue: PerformanceSample[] = [];\n #orphanEventCount = 0;\n #closed = false;\n #sourceCleanupPromise: Promise<void> | undefined;\n\n constructor(\n rpc: WorkerRpcClient,\n limits: MemoryBudgetLimits,\n adapters: readonly AdapterRegistration[],\n ) {\n this.#rpc = rpc;\n this.#limits = limits;\n this.#sourceStaging = new SourceStagingLimiter(limits.mainThreadSourceBytes);\n this.#rangeCache = new ByteLruCache(\n Math.min(limits.mainThreadRangeCacheBytes, limits.mainThreadRetainedBytes),\n {\n maxEntries: Math.min(\n MAX_BATCH_CACHE_ENTRIES,\n Math.max(1, Math.floor(\n Math.min(limits.mainThreadRangeCacheBytes, limits.mainThreadRetainedBytes)\n / MIN_BATCH_CACHE_ENTRY_BYTES,\n )),\n ),\n minimumEntryBytes: MIN_BATCH_CACHE_ENTRY_BYTES,\n },\n );\n this.#maxArrayBufferBytes = limits.maxArrayBufferBytes;\n this.#adapters = new Map(adapters.map((adapter) => [adapter.id, adapter]));\n }\n\n subscribePerformance(listener: (sample: PerformanceSample) => void): Unsubscribe {\n if (this.#closed) {\n throw closedError(\"Engine\");\n }\n if (typeof listener !== \"function\") {\n throw invalidArgument(\"performance listener must be a function\");\n }\n this.#performanceListeners.add(listener);\n // Samples are delivered synchronously while an operation is active. Any\n // bounded queue entries are drained for a subscriber added after a turn.\n for (const sample of this.#performanceQueue.splice(0)) {\n safelyCall(listener, sample);\n }\n return () => this.#performanceListeners.delete(listener);\n }\n\n /** Emits a privacy-preserving sample only while at least one listener exists. */\n #emitPerformanceSample(\n stage: string,\n startedAt: number | undefined,\n options: Partial<Pick<PerformanceSample, \"bytesRead\" | \"cacheHit\" | \"peakReservationBytes\" | \"sourceReads\" | \"sourceCacheHitBytes\">> = {},\n ): void {\n // If no operation was being measured, avoid even taking a timestamp or\n // allocating a sample. A listener can still unsubscribe while an already\n // measured operation settles; retain that terminal sample in the bounded\n // queue until a future subscriber drains it.\n if (this.#performanceListeners.size === 0 && startedAt === undefined) {\n return;\n }\n const durationMs = startedAt === undefined\n ? 0\n : Math.max(0, finitePerformanceNow() - startedAt);\n const sample = Object.freeze({\n stage: sanitizePerformanceStage(stage),\n durationMs,\n bytesRead: nonNegativeSafeQuantity(options.bytesRead),\n cacheHit: options.cacheHit === true,\n peakReservationBytes: nonNegativeSafeQuantity(options.peakReservationBytes),\n sourceReads: nonNegativeSafeQuantity(options.sourceReads),\n sourceCacheHitBytes: nonNegativeSafeQuantity(options.sourceCacheHitBytes),\n });\n // Keep a bounded history for a listener that is temporarily reentrant or\n // detached while a request settles. No source/path/protocol data enters it.\n if (this.#performanceListeners.size === 0) {\n if (this.#performanceQueue.length >= MAX_PERFORMANCE_SAMPLES) {\n this.#performanceQueue.shift();\n }\n this.#performanceQueue.push(sample);\n return;\n }\n for (const listener of this.#performanceListeners) {\n safelyCall(listener, sample);\n }\n }\n\n static async create(options: EngineOptions): Promise<Engine> {\n const normalized = normalizeEngineOptions(options);\n if (\n typeof Worker === \"undefined\" ||\n typeof Blob === \"undefined\" ||\n typeof URL === \"undefined\"\n ) {\n throw new TabularkError(\n \"UNSUPPORTED_RUNTIME\",\n \"Tabulark createEngine() requires a browser with module Worker and Blob support\",\n );\n }\n\n let engine: Engine | undefined;\n const worker = new Worker(normalized.workerUrl, {\n type: \"module\",\n name: normalized.workerName,\n });\n const rpc = new WorkerRpcClient(worker, (event) => {\n if (engine !== undefined) {\n engine.#handleEvent(event);\n }\n }, (error) => {\n if (engine !== undefined) {\n engine.#handleRuntimeFailure(error);\n }\n }, (message) => {\n if (engine !== undefined) {\n engine.#handleSourceBrokerMessage(message);\n }\n });\n engine = new Engine(rpc, normalized.limits, normalized.adapters);\n try {\n const hello = await rpc.request<unknown>(\n \"hello\",\n {\n clientName: \"tabulark-js\",\n adapters: normalized.adapters.map(({ id }) => Object.freeze({ id })),\n memoryBudgetBytes: normalized.memoryBudgetBytes,\n },\n \"hello\",\n );\n const helloAdapters = isRecord(hello) && Array.isArray(hello.adapters)\n ? hello.adapters\n : undefined;\n if (\n !isRecord(hello)\n || hello.protocolVersion !== PROTOCOL_VERSION\n || hello.adapterApiVersion !== ADAPTER_API_VERSION\n || hello.batchLayoutVersion !== BATCH_LAYOUT_VERSION\n || !helloAdapters\n || helloAdapters.length !== normalized.adapters.length\n || normalized.adapters.some((adapter) => !helloAdapters.includes(adapter.id))\n ) {\n throw new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n \"The Worker did not accept the current Tabulark protocol version\",\n );\n }\n return engine;\n } catch (error) {\n rpc.terminate();\n throw error;\n }\n }\n\n async open<Options>(\n source: Blob | ArrayBuffer | RangeSource,\n options: OpenSourceOptions<Options>,\n ): Promise<DatasetSession> {\n this.#assertOpen();\n const startedAt = this.#performanceListeners.size > 0 ? finitePerformanceNow() : undefined;\n let bytesRead = 0;\n let peakReservationBytes = 0;\n let sourceReads = 0;\n let sourceCacheHitBytes = 0;\n const onTelemetry = (telemetry: OperationTelemetry | undefined): void => {\n if (!telemetry) return;\n // `open()` spans the source request and the table-list handshake. Each\n // private Worker telemetry envelope is per request, so add source bytes\n // rather than taking the largest individual read (which would silently\n // under-report a footer plus metadata scan).\n bytesRead = addPerformanceBytes(bytesRead, telemetry.bytesRead);\n peakReservationBytes = Math.max(peakReservationBytes, telemetry.peakReservationBytes);\n sourceReads = addPerformanceBytes(sourceReads, telemetry.sourceReads);\n sourceCacheHitBytes = addPerformanceBytes(sourceCacheHitBytes, telemetry.sourceCacheHitBytes);\n };\n try {\n const rangeSourceInput = isRangeSource(source);\n const normalizedOptions = normalizeOpenOptions(\n options,\n this.#adapters,\n rangeSourceInput ? undefined : inferSourceName(source),\n rangeSourceInput,\n );\n // Capture the logical source length before an optional ArrayBuffer\n // transfer. Structured-cloning with a transfer list detaches the caller's\n // buffer, so reading `byteLength` after the Worker request would make the\n // capability seed disagree with the source that the Worker actually saw.\n // Keep this capture inside the validated source branches so malformed\n // JavaScript values still produce the public INVALID_ARGUMENT error.\n let sourceBytes: number;\n let sourcePayload: Blob | ArrayBuffer | Record<string, unknown> = source as Blob | ArrayBuffer;\n let sourceRecord: SourceReaderRecord | undefined;\n const transfer: Transferable[] = [];\n if (rangeSourceInput) {\n if (options.sourceMode !== undefined || options.transferInput !== undefined) {\n throw invalidArgument(\"sourceMode and transferInput do not apply to RangeSource inputs\");\n }\n const openController = new AbortController();\n this.#openingSources.add(openController);\n const signal = combineAbortSignals(options.signal, openController.signal);\n let reader: RangeSourceReader;\n try {\n const openOptions = attachRangeSourceHostReservations({\n signal,\n maxSourceBytes: MAX_RANGE_SOURCE_BYTES,\n maxStagingBytes: sourceStagingBudget(this.#limits),\n }, {\n reserveStaging: async (bytes, reservationSignal) => {\n const permit = await this.#sourceStaging.acquire(bytes, reservationSignal);\n return permit.release;\n },\n reserveRetained: (bytes) => this.#reserveRetainedSourceBytes(bytes),\n });\n reader = await openRangeReaderWithCancellation(source, openOptions, signal);\n } catch (error) {\n if (this.#closed) throw closedError(\"Engine\");\n if (options.signal?.aborted || openController.signal.aborted) throw cancelledError();\n throw normalizeRangeSourceOpenError(error);\n } finally {\n this.#openingSources.delete(openController);\n }\n if (this.#closed) {\n await closeRangeReaderBestEffort(reader);\n throw closedError(\"Engine\");\n }\n if (options.signal?.aborted || openController.signal.aborted) {\n await closeRangeReaderBestEffort(reader);\n throw cancelledError();\n }\n const readerValue: unknown = reader;\n let reportedSize: unknown;\n try {\n reportedSize = isRecord(readerValue) ? readerValue.size : undefined;\n } catch {\n await closeRangeReaderBestEffort(readerValue);\n throw new TabularkError(\"RUNTIME_FAILURE\", \"The range source returned an invalid reader\");\n }\n if (typeof reportedSize === \"number\" && reportedSize > MAX_RANGE_SOURCE_BYTES) {\n await closeRangeReaderBestEffort(readerValue);\n throw new TabularkError(\"RESOURCE_LIMIT\", \"The range source exceeds the addressable byte limit\", {\n details: {\n resource: \"source-address-space\",\n requiredBytes: Number.isSafeInteger(reportedSize)\n ? reportedSize\n : Number.MAX_SAFE_INTEGER,\n availableBytes: MAX_RANGE_SOURCE_BYTES,\n },\n });\n }\n if (!validateRangeSourceReader(readerValue)) {\n await closeRangeReaderBestEffort(readerValue);\n throw new TabularkError(\"RUNTIME_FAILURE\", \"The range source returned an invalid reader\");\n }\n try {\n // Snapshot validation stays on the host. The opaque validator is\n // deliberately never serialized into the Worker descriptor.\n normalizeRangeSourceSnapshot(reader.snapshot);\n } catch (error) {\n await closeRangeReaderBestEffort(readerValue);\n throw new TabularkError(\"RUNTIME_FAILURE\", \"The range source returned an invalid snapshot\");\n }\n let readerMaxConcurrency: number | undefined;\n try {\n // Capture immutable reader facts before publishing the host handle.\n // A stateful/hostile getter must not throw after registration and\n // leave a reader that the lifecycle cleanup cannot reach.\n sourceBytes = reader.size;\n readerMaxConcurrency = reader.maxConcurrency;\n } catch {\n await closeRangeReaderBestEffort(readerValue);\n throw new TabularkError(\"RUNTIME_FAILURE\", \"The range source returned an invalid reader\");\n }\n if (!isSafeNonNegativeInteger(sourceBytes)) {\n await closeRangeReaderBestEffort(readerValue);\n throw new TabularkError(\"RUNTIME_FAILURE\", \"The range source returned an invalid reader\");\n }\n if (readerMaxConcurrency !== undefined\n && (!Number.isSafeInteger(readerMaxConcurrency)\n || readerMaxConcurrency < 1\n || readerMaxConcurrency > 4)) {\n await closeRangeReaderBestEffort(readerValue);\n throw new TabularkError(\"RUNTIME_FAILURE\", \"The range source returned an invalid reader\");\n }\n if (sourceBytes > MAX_RANGE_SOURCE_BYTES) {\n await closeRangeReaderBestEffort(readerValue);\n throw new TabularkError(\"RESOURCE_LIMIT\", \"The range source exceeds the addressable byte limit\", {\n details: { resource: \"source-address-space\", requiredBytes: sourceBytes, availableBytes: MAX_RANGE_SOURCE_BYTES },\n });\n }\n const handle = this.#allocateSourceHandle();\n sourceRecord = {\n handle,\n size: sourceBytes,\n maxConcurrency: readerMaxConcurrency ?? 1,\n reader,\n pending: new Map(),\n concurrency: new SourceReadConcurrencyLimiter(readerMaxConcurrency ?? 1),\n closed: false,\n };\n this.#sourceReaders.set(handle, sourceRecord);\n sourcePayload = Object.freeze({\n kind: \"range\",\n handle,\n size: sourceBytes,\n ...(readerMaxConcurrency === undefined ? {} : { maxConcurrency: readerMaxConcurrency }),\n });\n } else if (source instanceof ArrayBuffer) {\n if (normalizedOptions.sourceMode === \"large\") {\n throw invalidArgument(\"sourceMode large requires a local Blob or File source\");\n }\n sourceBytes = source.byteLength;\n if (source.byteLength > this.#maxArrayBufferBytes) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `ArrayBuffer sources larger than ${this.#maxArrayBufferBytes} bytes must be supplied as a Blob`,\n {\n details: {\n resource: \"source-staging\",\n requiredBytes: source.byteLength,\n availableBytes: this.#maxArrayBufferBytes,\n },\n },\n );\n }\n if (options.transferInput === true) {\n transfer.push(source);\n }\n } else if (!(source instanceof Blob)) {\n throw invalidArgument(\"source must be a Blob, File, or ArrayBuffer\");\n } else {\n sourceBytes = source.size;\n if (options.transferInput === true) {\n throw invalidArgument(\"transferInput may only be true for an ArrayBuffer source\");\n }\n const sourceSize = sourceBytes;\n if (\n normalizedOptions.sourceMode === \"large\"\n && (!Number.isSafeInteger(sourceSize) || sourceSize < 0 || sourceSize > MAX_LARGE_SOURCE_BYTES)\n ) {\n throw largeSourceLimitError(sourceSize);\n }\n if (\n (normalizedOptions.adapter.id === \"tabulark:arrow-ipc\"\n || normalizedOptions.adapter.id === \"tabulark:excel\")\n && Number.isSafeInteger(sourceSize)\n && sourceSize > MAX_LARGE_SOURCE_BYTES\n ) {\n // The range-capable Rust runtimes accept 4 GiB-1 for a remote\n // descriptor. Keep the established local Arrow/Excel Blob contract\n // at the exact 2 GiB boundary regardless of sourceMode.\n throw largeSourceLimitError(sourceSize);\n }\n }\n\n let dataset: { datasetHandle: string };\n try {\n const opened = await this.#rpc.request<unknown>(\n \"openSource\",\n {\n source: sourcePayload,\n adapterId: normalizedOptions.adapter.id,\n options: normalizedOptions.options,\n ...(normalizedOptions.isRangeSource ? {} : { sourceMode: normalizedOptions.sourceMode }),\n },\n \"dataset\",\n {\n ...(options.signal ? { signal: options.signal } : {}),\n transfer,\n ...(startedAt === undefined ? {} : { measure: true, onTelemetry }),\n },\n );\n if (\n !isRecord(opened)\n || typeof opened.datasetHandle !== \"string\"\n || opened.datasetHandle.length === 0\n ) {\n throw this.#terminateForProtocolFailure(\"Worker returned an invalid dataset handle\");\n }\n dataset = { datasetHandle: opened.datasetHandle };\n if (sourceRecord !== undefined) {\n // The Worker now owns the dataset lifetime; retain the host reader\n // until its explicit close message or a terminal engine failure.\n sourceRecord = this.#sourceReaders.get(sourceRecord.handle);\n if (sourceRecord !== undefined) {\n this.#datasetSources.set(dataset.datasetHandle, sourceRecord.handle);\n }\n }\n } catch (error) {\n if (sourceRecord !== undefined) {\n await this.#closeSourceReader(sourceRecord.handle);\n }\n throw error;\n }\n\n try {\n const tableResult = await this.#rpc.request<unknown>(\n \"listTables\",\n { datasetHandle: dataset.datasetHandle },\n \"tables\",\n {\n ...(options.signal ? { signal: options.signal } : {}),\n ...(startedAt === undefined ? {} : { measure: true, onTelemetry }),\n },\n );\n if (options.signal?.aborted) {\n throw cancelledError();\n }\n const tableDescriptors = normalizeDescriptors(tableResult);\n const session = new DatasetSessionImpl(\n this,\n dataset.datasetHandle,\n tableDescriptors,\n createDatasetCapabilitySeed(\n normalizedOptions.adapter.id,\n normalizedOptions.options,\n tableDescriptors,\n normalizedOptions.sourceMode,\n this.#stagedSourceLimit(normalizedOptions.adapter.id),\n normalizedOptions.isRangeSource,\n ),\n );\n this.#sessions.set(dataset.datasetHandle, session);\n this.#deliverOrphanEvents(session);\n if (session.closed) {\n throw session.terminalError ?? closedError(\"Dataset session\");\n }\n return session;\n } catch (error) {\n const terminalError = this.#orphanRuntimeError(dataset.datasetHandle);\n const session = this.#sessions.get(dataset.datasetHandle);\n if (session) {\n session.closeLocally();\n this.#sessions.delete(dataset.datasetHandle);\n }\n await this.#discardOpenedDataset(dataset.datasetHandle);\n if (sourceRecord !== undefined) {\n await this.#closeSourceReader(sourceRecord.handle);\n }\n throw terminalError ?? error;\n }\n } finally {\n this.#emitPerformanceSample(\"open\", startedAt, {\n bytesRead,\n peakReservationBytes,\n sourceReads,\n sourceCacheHitBytes,\n });\n }\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n await this.#sourceCleanupPromise;\n return;\n }\n const startedAt = this.#performanceListeners.size > 0 ? finitePerformanceNow() : undefined;\n let peakReservationBytes = 0;\n const onTelemetry = (telemetry: OperationTelemetry | undefined): void => {\n if (telemetry) peakReservationBytes = Math.max(peakReservationBytes, telemetry.peakReservationBytes);\n };\n this.#closed = true;\n this.#sourceStaging.close();\n for (const controller of this.#openingSources) controller.abort();\n for (const session of this.#sessions.values()) {\n session.closeLocally();\n }\n this.#sessions.clear();\n this.#abortRangeSingleflights();\n this.#rangeCache.clear();\n this.#clearOrphanEvents();\n await this.#closeAllSourceReaders();\n try {\n await this.#rpc.shutdown(\n LIFECYCLE_CLOSE_TIMEOUT_MS,\n startedAt === undefined ? {} : { measure: true, onTelemetry },\n );\n } finally {\n // A close (including a shutdown failure) has exactly one terminal sample.\n this.#emitPerformanceSample(\"close\", startedAt, { peakReservationBytes });\n this.#performanceListeners.clear();\n }\n }\n\n dispose(): Promise<void> {\n return this.close();\n }\n\n async openTable(session: DatasetSessionImpl, tableId: string): Promise<TableHandle> {\n this.#assertOpen();\n session.assertOpen();\n const startedAt = this.#performanceListeners.size > 0 ? finitePerformanceNow() : undefined;\n let peakReservationBytes = 0;\n const onTelemetry = (telemetry: OperationTelemetry | undefined): void => {\n if (telemetry) peakReservationBytes = Math.max(peakReservationBytes, telemetry.peakReservationBytes);\n };\n if (!session.tables.some((table) => table.id === tableId)) {\n const error = invalidArgument(`Unknown table: ${tableId}`);\n this.#emitPerformanceSample(\"open-table\", startedAt, { peakReservationBytes });\n throw error;\n }\n let tableHandle: string | undefined;\n try {\n const table = await this.#rpc.request<{ tableHandle: string }>(\n \"openTable\",\n { datasetHandle: session.handle, tableId },\n \"table\",\n startedAt === undefined ? {} : { measure: true, onTelemetry },\n );\n if (\n !isRecord(table)\n || typeof table.tableHandle !== \"string\"\n || table.tableHandle.length === 0\n ) {\n throw this.#terminateForProtocolFailure(\"Worker returned an invalid table handle\");\n }\n tableHandle = table.tableHandle;\n const metadata = await this.#rpc.request<unknown>(\n \"getMetadata\",\n { tableHandle },\n \"metadata\",\n startedAt === undefined ? {} : { measure: true, onTelemetry },\n );\n const normalizedMetadata = normalizeMetadataWire(metadata);\n this.#assertOpen();\n session.assertOpen();\n const handle = new TableHandleImpl(\n this,\n session,\n tableHandle,\n normalizedMetadata,\n );\n session.addTableHandle(handle);\n this.#emitPerformanceSample(\"open-table\", startedAt, { peakReservationBytes });\n return handle;\n } catch (error) {\n if (tableHandle !== undefined) {\n await this.#discardOpenedTable(tableHandle);\n }\n this.#emitPerformanceSample(\"open-table\", startedAt, { peakReservationBytes });\n throw error;\n }\n }\n\n async readRange(\n table: TableHandleImpl,\n request: RangeRequest,\n options: ReadRangeOptions,\n ): Promise<TableBatch> {\n this.#assertOpen();\n table.assertOpen();\n const startedAt = this.#performanceListeners.size > 0 ? finitePerformanceNow() : undefined;\n let bytesRead = 0;\n let cacheHit = false;\n let peakReservationBytes = 0;\n let sourceReads = 0;\n let sourceCacheHitBytes = 0;\n let flight: RangeSingleflight | undefined;\n try {\n const normalized = validateRange(request);\n if (options.signal?.aborted) {\n throw cancelledError();\n }\n const metadata = table.metadata;\n const key = rangeCacheKey(\n table.datasetHandle,\n metadata.tableId,\n metadata.revision,\n metadata.schema.version,\n normalized,\n );\n const cached = this.#rangeCache.get(key);\n if (cached) {\n cacheHit = true;\n return new ColumnarTableBatch(cached);\n }\n flight = this.#rangeSingleflight.get(key);\n if (!flight) {\n flight = this.#createRangeSingleflight(\n table,\n normalized,\n key,\n metadata.revision,\n metadata.schema.version,\n startedAt !== undefined,\n );\n }\n const backing = await this.#joinRangeSingleflight(flight, options.signal);\n bytesRead = flight.bytesRead;\n peakReservationBytes = flight.peakReservationBytes;\n sourceReads = flight.sourceReads;\n sourceCacheHitBytes = flight.sourceCacheHitBytes;\n this.#assertOpen();\n table.assertOpen();\n return new ColumnarTableBatch(backing);\n } finally {\n if (flight) {\n bytesRead = flight.bytesRead;\n peakReservationBytes = flight.peakReservationBytes;\n sourceReads = flight.sourceReads;\n sourceCacheHitBytes = flight.sourceCacheHitBytes;\n }\n this.#emitPerformanceSample(\"read-range\", startedAt, {\n bytesRead,\n cacheHit,\n peakReservationBytes,\n sourceReads,\n sourceCacheHitBytes,\n });\n }\n }\n\n #createRangeSingleflight(\n table: TableHandleImpl,\n range: RangeRequest,\n key: string,\n revision: number,\n schemaVersion: number,\n measure: boolean,\n ): RangeSingleflight {\n const controller = new AbortController();\n const flight: RangeSingleflight = {\n key,\n datasetHandle: table.datasetHandle,\n tableId: table.metadata.tableId,\n controller,\n callers: new Set(),\n promise: undefined as unknown as Promise<BatchBacking>,\n settled: false,\n bytesRead: 0,\n peakReservationBytes: 0,\n sourceReads: 0,\n sourceCacheHitBytes: 0,\n };\n const onTelemetry = (telemetry: OperationTelemetry | undefined): void => {\n if (!telemetry) return;\n flight.bytesRead = addPerformanceBytes(flight.bytesRead, telemetry.bytesRead);\n flight.peakReservationBytes = Math.max(\n flight.peakReservationBytes,\n telemetry.peakReservationBytes,\n );\n flight.sourceReads = addPerformanceBytes(flight.sourceReads, telemetry.sourceReads);\n flight.sourceCacheHitBytes = addPerformanceBytes(\n flight.sourceCacheHitBytes,\n telemetry.sourceCacheHitBytes,\n );\n };\n flight.promise = this.#rpc.request<WireTableBatch>(\n \"readRange\",\n { tableHandle: table.handle, range },\n \"batch\",\n {\n signal: controller.signal,\n ...(measure ? { measure: true, onTelemetry } : {}),\n },\n ).then((batch) => {\n const backing = this.#validateBatchBacking(\n batch,\n table.metadata.tableId,\n revision,\n schemaVersion,\n range,\n );\n // Incomplete batches end at a progressive indexed-prefix boundary. They\n // are valid for this instant but must not hide subsequently indexed rows.\n if (\n backing.complete\n && backing.revision === revision\n && backing.schemaVersion === schemaVersion\n && table.metadata.revision === revision\n && table.metadata.schema.version === schemaVersion\n && !table.datasetClosed\n ) {\n this.#rangeCache.set(\n key,\n backing,\n wireBatchByteLength(backing),\n this.#availableRetainedCacheBytes(),\n );\n }\n return backing;\n }).finally(() => {\n flight.settled = true;\n if (this.#rangeSingleflight.get(key) === flight) {\n this.#rangeSingleflight.delete(key);\n }\n });\n this.#rangeSingleflight.set(key, flight);\n return flight;\n }\n\n async #joinRangeSingleflight(\n flight: RangeSingleflight,\n signal: AbortSignal | undefined,\n ): Promise<BatchBacking> {\n if (signal?.aborted) {\n if (!flight.settled && flight.callers.size === 0) {\n if (this.#rangeSingleflight.get(flight.key) === flight) {\n this.#rangeSingleflight.delete(flight.key);\n }\n flight.controller.abort();\n }\n throw cancelledError();\n }\n const caller = Symbol(\"range-caller\");\n flight.callers.add(caller);\n let abort: (() => void) | undefined;\n try {\n if (!signal) {\n return await flight.promise;\n }\n const cancellation = new Promise<never>((_resolve, reject) => {\n abort = () => reject(cancelledError());\n signal.addEventListener(\"abort\", abort, { once: true });\n if (signal.aborted) abort();\n });\n return await Promise.race([flight.promise, cancellation]);\n } finally {\n if (abort) signal?.removeEventListener(\"abort\", abort);\n flight.callers.delete(caller);\n if (!flight.settled && flight.callers.size === 0) {\n if (this.#rangeSingleflight.get(flight.key) === flight) {\n this.#rangeSingleflight.delete(flight.key);\n }\n // WorkerRpcClient owns the one protocol cancel message. Aborting this\n // shared controller is idempotent even when several callers cancel in\n // the same task turn.\n flight.controller.abort();\n }\n }\n }\n\n #validateBatchBacking(\n batch: WireTableBatch,\n tableId: string,\n revision: number,\n schemaVersion: number,\n requested: RangeRequest,\n ): BatchBacking {\n if (\n !isRecord(batch)\n || batch.tableId !== tableId\n || !Number.isSafeInteger(batch.revision)\n || batch.revision < revision\n || !Number.isSafeInteger(batch.schemaVersion)\n || batch.schemaVersion < schemaVersion\n || !isReturnedRangeWithin(batch.range, requested)\n ) {\n throw this.#terminateForProtocolFailure(\"Worker returned a stale or out-of-range batch\");\n }\n try {\n const backing = createBatchBacking(batch);\n // Validate every layout descriptor once before the backing can enter the\n // cache. Subsequent facades reuse the same inaccessible ArrayBuffers.\n new ColumnarTableBatch(backing);\n return backing;\n } catch {\n throw this.#terminateForProtocolFailure(\"Worker returned an invalid batch backing\");\n }\n }\n\n async getPresentation(table: TableHandleImpl): Promise<TablePresentation | null> {\n this.#assertOpen();\n table.assertOpen();\n const startedAt = this.#performanceListeners.size > 0 ? finitePerformanceNow() : undefined;\n let peakReservationBytes = 0;\n const onTelemetry = (telemetry: OperationTelemetry | undefined): void => {\n if (telemetry) peakReservationBytes = Math.max(peakReservationBytes, telemetry.peakReservationBytes);\n };\n try {\n const value = await this.#rpc.request<unknown>(\n \"getPresentation\",\n { tableHandle: table.handle },\n \"presentation\",\n startedAt === undefined ? {} : { measure: true, onTelemetry },\n );\n this.#assertOpen();\n table.assertOpen();\n return normalizePresentationWire(value, table.metadata);\n } finally {\n this.#emitPerformanceSample(\"presentation\", startedAt, { peakReservationBytes });\n }\n }\n\n async readPresentationRange(\n table: TableHandleImpl,\n request: RangeRequest,\n options: ReadRangeOptions,\n ): Promise<PresentationRange | null> {\n this.#assertOpen();\n table.assertOpen();\n const startedAt = this.#performanceListeners.size > 0 ? finitePerformanceNow() : undefined;\n let peakReservationBytes = 0;\n const onTelemetry = (telemetry: OperationTelemetry | undefined): void => {\n if (telemetry) peakReservationBytes = Math.max(peakReservationBytes, telemetry.peakReservationBytes);\n };\n try {\n const normalized = validateRange(request);\n if (options.signal?.aborted) {\n throw cancelledError();\n }\n const value = await this.#rpc.request<unknown>(\n \"readPresentationRange\",\n { tableHandle: table.handle, range: normalized },\n \"presentationRange\",\n {\n ...(options.signal ? { signal: options.signal } : {}),\n ...(startedAt === undefined ? {} : { measure: true, onTelemetry }),\n },\n );\n this.#assertOpen();\n table.assertOpen();\n return normalizePresentationRangeWire(value, table.metadata, normalized);\n } finally {\n this.#emitPerformanceSample(\"presentation-range\", startedAt, { peakReservationBytes });\n }\n }\n\n async closeTable(table: TableHandleImpl): Promise<void> {\n if (table.closed) {\n return;\n }\n const startedAt = this.#performanceListeners.size > 0 ? finitePerformanceNow() : undefined;\n let peakReservationBytes = 0;\n const onTelemetry = (telemetry: OperationTelemetry | undefined): void => {\n if (telemetry) peakReservationBytes = Math.max(peakReservationBytes, telemetry.peakReservationBytes);\n };\n table.closeLocally();\n if (this.#closed) {\n this.#emitPerformanceSample(\"close-table\", startedAt, { peakReservationBytes });\n return;\n }\n try {\n await this.#requestRemoteClose(\n \"closeTable\",\n { tableHandle: table.handle },\n startedAt === undefined ? {} : { measure: true, onTelemetry },\n );\n } finally {\n this.#emitPerformanceSample(\"close-table\", startedAt, { peakReservationBytes });\n }\n }\n\n clearDatasetCache(datasetHandle: string): void {\n this.#rangeCache.deleteWhere((key) => rangeCacheKeyBelongsToDataset(key, datasetHandle));\n for (const flight of [...this.#rangeSingleflight.values()]) {\n if (flight.datasetHandle !== datasetHandle || flight.settled) continue;\n if (this.#rangeSingleflight.get(flight.key) === flight) {\n this.#rangeSingleflight.delete(flight.key);\n }\n flight.controller.abort();\n }\n }\n\n updateTableCacheVersion(\n datasetHandle: string,\n tableId: string,\n revision: number,\n schemaVersion: number,\n ): void {\n this.#rangeCache.deleteWhere((key) => (\n rangeCacheKeyBelongsToTable(key, datasetHandle, tableId)\n && !rangeCacheKeyMatchesVersion(key, revision, schemaVersion)\n ));\n }\n\n #abortRangeSingleflights(): void {\n for (const flight of this.#rangeSingleflight.values()) {\n if (!flight.settled) flight.controller.abort();\n }\n this.#rangeSingleflight.clear();\n }\n\n async closeSession(session: DatasetSessionImpl): Promise<void> {\n if (session.closed) {\n return;\n }\n const startedAt = this.#performanceListeners.size > 0 ? finitePerformanceNow() : undefined;\n let peakReservationBytes = 0;\n const onTelemetry = (telemetry: OperationTelemetry | undefined): void => {\n if (telemetry) peakReservationBytes = Math.max(peakReservationBytes, telemetry.peakReservationBytes);\n };\n session.closeLocally();\n if (this.#closed) {\n this.#sessions.delete(session.handle);\n await this.#closeDatasetSource(session.handle);\n this.#emitPerformanceSample(\"close-session\", startedAt, { peakReservationBytes });\n return;\n }\n try {\n await this.#requestRemoteClose(\n \"closeSource\",\n { datasetHandle: session.handle },\n startedAt === undefined ? {} : { measure: true, onTelemetry },\n );\n } finally {\n this.#sessions.delete(session.handle);\n this.#deleteOrphanEvents(session.handle);\n await this.#closeDatasetSource(session.handle);\n this.#emitPerformanceSample(\"close-session\", startedAt, { peakReservationBytes });\n }\n }\n\n #assertOpen(): void {\n if (this.#closed) {\n throw closedError(\"Engine\");\n }\n }\n\n /** Mirrors the Worker's conservative auto-mode Excel source ceiling. */\n #stagedSourceLimit(adapterId: OfficialAdapterId): number {\n if (adapterId !== \"tabulark:excel\") {\n return this.#maxArrayBufferBytes;\n }\n const totalWeight = [...this.#adapters.values()].reduce(\n (total, adapter) => total + officialAdapterManifestEntry(adapter.id).resources.runtimeWeight,\n 0,\n );\n const weight = officialAdapterManifestEntry(adapterId).resources.runtimeWeight;\n const runtimeBudget = Math.max(\n 1,\n Math.floor(this.#limits.adapterRuntimePoolBytes * weight / Math.max(1, totalWeight)),\n );\n // `maxArrayBufferBytes` is the public host bound. Auto mode also respects\n // the adapter's weighted runtime budget; explicit large mode is range-backed.\n return Math.min(this.#maxArrayBufferBytes, runtimeBudget);\n }\n\n #allocateSourceHandle(): string {\n // This is an opaque process-local capability. It intentionally contains no\n // URL, validator, source name, or user-controlled text.\n return `s${(this.#nextSourceHandle++).toString(36)}`;\n }\n\n /** Shares the retained 12.5% slice between logical batches and HTTP fallback bodies. */\n #reserveRetainedSourceBytes(bytes: number): () => void {\n if (!Number.isSafeInteger(bytes) || bytes < 0) {\n throw new TabularkError(\"RESOURCE_LIMIT\", \"The source retained-byte request is invalid\", {\n details: {\n resource: \"source-retained\",\n requiredBytes: Number.MAX_SAFE_INTEGER,\n availableBytes: this.#availableRetainedCacheBytes(),\n },\n });\n }\n if (this.#closed) throw closedError(\"Engine\");\n const availableBytes = this.#limits.mainThreadRetainedBytes - this.#retainedSourceBytes;\n if (bytes > availableBytes) {\n throw new TabularkError(\"RESOURCE_LIMIT\", \"The source exceeds the retained-byte budget\", {\n details: { resource: \"source-retained\", requiredBytes: bytes, availableBytes },\n });\n }\n // Retained fallback data has a live reader and cannot be evicted. Logical\n // batches are an LRU, so reclaim those first and keep the aggregate slice\n // within the engine budget without waiting for another dataset to close.\n this.#rangeCache.trimTo(availableBytes - bytes);\n this.#retainedSourceBytes += bytes;\n let released = false;\n return () => {\n if (released) return;\n released = true;\n this.#retainedSourceBytes = Math.max(0, this.#retainedSourceBytes - bytes);\n };\n }\n\n #availableRetainedCacheBytes(): number {\n return Math.max(0, this.#limits.mainThreadRetainedBytes - this.#retainedSourceBytes);\n }\n\n #handleSourceBrokerMessage(value: unknown): void {\n if (!isRecord(value) || typeof value.type !== \"string\") return;\n if (value.type === \"source-close\") {\n if (typeof value.sourceHandle === \"string\") {\n void this.#closeSourceReader(value.sourceHandle);\n }\n return;\n }\n if (value.type === \"source-read-cancel\") {\n if (typeof value.sourceHandle !== \"string\" || typeof value.requestId !== \"string\") return;\n const record = this.#sourceReaders.get(value.sourceHandle);\n record?.pending.get(value.requestId)?.abort();\n return;\n }\n if (value.type !== \"source-read\") return;\n const sourceHandle = value.sourceHandle;\n const requestId = value.requestId;\n const offset = value.offset;\n const length = value.length;\n if (\n typeof sourceHandle !== \"string\"\n || typeof requestId !== \"string\"\n || requestId.length === 0\n || requestId.length > 256\n || !isSafeNonNegativeInteger(offset)\n || !isSafeNonNegativeInteger(length)\n ) {\n // Without a valid pair of opaque identifiers there is no safe pending\n // entry to settle. Treat the private broker message as a protocol fault\n // instead of leaving a Worker request waiting forever.\n this.#rpc.terminate(\n new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"The Worker sent an invalid source read request\"),\n true,\n );\n return;\n }\n const record = this.#sourceReaders.get(sourceHandle);\n if (record === undefined || record.closed) {\n this.#postSourceFailure(requestId, sourceHandle, offset, length, \"HANDLE_CLOSED\");\n return;\n }\n if (record.pending.has(requestId)) {\n this.#rpc.terminate(\n new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"The Worker reused a source request identifier\"),\n true,\n );\n return;\n }\n if (\n offset > record.size\n || length > record.size - offset\n ) {\n this.#postSourceFailure(requestId, sourceHandle, offset, length, \"RANGE_UNSUPPORTED\");\n return;\n }\n if (length > sourceStagingBudget(this.#limits)) {\n this.#postSourceFailure(requestId, sourceHandle, offset, length, \"RESOURCE_LIMIT\", false, {\n resource: \"source-staging\",\n requiredBytes: length,\n availableBytes: sourceStagingBudget(this.#limits),\n });\n return;\n }\n const controller = new AbortController();\n record.pending.set(requestId, controller);\n this.#runSourceRead(record, requestId, sourceHandle, offset, length, controller);\n }\n\n /** Admits one bounded host buffer, then performs and settles the provider read. */\n #runSourceRead(\n record: SourceReaderRecord,\n requestId: string,\n sourceHandle: string,\n offset: number,\n length: number,\n controller: AbortController,\n ): void {\n void (async () => {\n let concurrencyRelease: (() => void) | undefined;\n let stagingPermit: SourceStagingPermit | undefined;\n try {\n concurrencyRelease = await record.concurrency.acquire(controller.signal);\n stagingPermit = await this.#sourceStaging.acquire(length, controller.signal);\n // A queued request may have been cancelled or its dataset may have\n // closed before staging became available. Do not invoke user code in\n // that case; the Worker-side cancellation already settled its wait.\n if (\n record.closed\n || record.pending.get(requestId) !== controller\n || controller.signal.aborted\n ) {\n return;\n }\n const value = await Promise.resolve().then(() => record.reader.read(\n { offset, length },\n { signal: controller.signal },\n ));\n // A cancelled/closed broker request no longer has a Worker waiter;\n // discard a late provider result instead of transferring bytes into\n // a dead operation or exposing a stale snapshot response.\n if (\n record.closed\n || record.pending.get(requestId) !== controller\n || controller.signal.aborted\n ) {\n return;\n }\n // Validate the provider's reported byte length before copying. A\n // hostile reader can otherwise return a very large backing buffer;\n // copying it first would temporarily exceed the aggregate staging\n // reservation even though the request itself was bounded.\n const buffer = copyExactRangeBytes(value, length);\n this.#rpc.postMessage({\n type: \"source-read-result\",\n requestId,\n sourceHandle,\n offset,\n length,\n buffer,\n }, [buffer]);\n } catch (error) {\n if (!record.closed && record.pending.get(requestId) === controller) {\n const normalized = normalizeSourceProviderError(error);\n this.#postSourceFailure(\n requestId,\n sourceHandle,\n offset,\n length,\n normalized.code,\n normalized.retryable,\n );\n if (normalized.code === \"SOURCE_CHANGED\") {\n void this.#closeSourceReader(sourceHandle);\n }\n }\n } finally {\n stagingPermit?.release();\n concurrencyRelease?.();\n if (record.pending.get(requestId) === controller) record.pending.delete(requestId);\n }\n })();\n }\n\n #postSourceFailure(\n requestId: unknown,\n sourceHandle: unknown,\n offset: unknown,\n length: unknown,\n code: string,\n retryable = false,\n details?: Readonly<Record<string, unknown>>,\n ): void {\n if (typeof requestId !== \"string\" || typeof sourceHandle !== \"string\") return;\n this.#rpc.postMessage({\n type: \"source-read-failure\",\n requestId,\n sourceHandle,\n ...(isSafeNonNegativeInteger(offset) ? { offset } : {}),\n ...(isSafeNonNegativeInteger(length) ? { length } : {}),\n error: {\n code: sourceErrorCode(code),\n message: sourceErrorMessage(code),\n retryable,\n ...(details === undefined ? {} : { details }),\n },\n });\n }\n\n async #closeDatasetSource(datasetHandle: string): Promise<void> {\n const handle = this.#datasetSources.get(datasetHandle);\n if (handle !== undefined) {\n this.#datasetSources.delete(datasetHandle);\n await this.#closeSourceReader(handle);\n }\n }\n\n async #closeSourceReader(handle: string): Promise<void> {\n const record = this.#sourceReaders.get(handle);\n if (record === undefined || record.closed) return;\n record.closed = true;\n this.#sourceReaders.delete(handle);\n for (const controller of record.pending.values()) controller.abort();\n record.pending.clear();\n record.concurrency.close();\n await closeRangeReaderBestEffort(record.reader);\n }\n\n async #closeAllSourceReaders(): Promise<void> {\n if (this.#sourceCleanupPromise !== undefined) {\n await this.#sourceCleanupPromise;\n return;\n }\n this.#sourceCleanupPromise = (async () => {\n for (const controller of this.#openingSources) controller.abort();\n this.#datasetSources.clear();\n await Promise.all([...this.#sourceReaders.keys()].map((handle) => this.#closeSourceReader(handle)));\n })();\n await this.#sourceCleanupPromise;\n }\n\n #handleEvent(event: ProtocolEvent): void {\n const handle = event.datasetHandle;\n if (!handle && event.event === \"runtimeError\") {\n this.#handleRuntimeFailure(errorFromWire(event.payload));\n return;\n }\n if (!handle) {\n return;\n }\n const session = this.#sessions.get(handle);\n if (!session) {\n this.#rememberOrphanEvent(handle, event);\n return;\n }\n session.handleEvent(event);\n if (event.event === \"runtimeError\" && !event.tableHandle && session.closed) {\n // A source validator failure emits runtimeError before the Worker's\n // closed event. Release the host reader immediately even if the latter\n // is lost during Worker termination.\n void this.#closeDatasetSource(handle);\n }\n if (event.event === \"closed\" && !event.tableHandle && session.closed) {\n this.#sessions.delete(handle);\n this.#deleteOrphanEvents(handle);\n void this.#closeDatasetSource(handle);\n }\n }\n\n #deliverOrphanEvents(session: DatasetSessionImpl): void {\n const events = this.#orphanEvents.get(session.handle);\n if (!events) {\n return;\n }\n this.#deleteOrphanEvents(session.handle);\n for (const event of events) {\n session.handleEvent(event);\n }\n }\n\n #orphanRuntimeError(handle: string): TabularkError | undefined {\n const event = this.#orphanEvents.get(handle)?.find((candidate) => (\n candidate.event === \"runtimeError\"\n ));\n return event ? errorFromWire(event.payload) : undefined;\n }\n\n async #discardOpenedTable(tableHandle: string): Promise<void> {\n if (this.#closed) {\n return;\n }\n try {\n await this.#rpc.request(\n \"closeTable\",\n { tableHandle },\n \"acknowledged\",\n { timeoutMs: LIFECYCLE_CLOSE_TIMEOUT_MS },\n );\n } catch (error) {\n if (!this.#closed) {\n this.#rpc.terminate(asTabularkError(error, \"Could not release an opened table\"), true);\n }\n }\n }\n\n async #discardOpenedDataset(datasetHandle: string): Promise<void> {\n this.#deleteOrphanEvents(datasetHandle);\n if (this.#closed) {\n return;\n }\n try {\n await this.#rpc.request(\n \"closeSource\",\n { datasetHandle },\n \"acknowledged\",\n { timeoutMs: LIFECYCLE_CLOSE_TIMEOUT_MS },\n );\n } catch (error) {\n if (!this.#closed) {\n this.#rpc.terminate(asTabularkError(error, \"Could not release an opened dataset\"), true);\n }\n } finally {\n // closeSource may emit a final closed event before its acknowledgement.\n // No DatasetSession will consume that event after a failed open.\n this.#deleteOrphanEvents(datasetHandle);\n await this.#closeDatasetSource(datasetHandle);\n }\n }\n\n async #requestRemoteClose(\n op: \"closeTable\" | \"closeSource\",\n payload: unknown,\n options: PerformanceRequestOptions = {},\n ): Promise<void> {\n try {\n await this.#rpc.request(op, payload, \"acknowledged\", {\n timeoutMs: LIFECYCLE_CLOSE_TIMEOUT_MS,\n ...options,\n });\n } catch (error) {\n if (!this.#closed) {\n this.#rpc.terminate(asTabularkError(error, `Could not complete ${op}`), true);\n }\n throw error;\n }\n }\n\n #terminateForProtocolFailure(message: string): TabularkError {\n const error = new TabularkError(\"PROTOCOL_INCOMPATIBLE\", message);\n this.#rpc.terminate(error, true);\n return error;\n }\n\n #rememberOrphanEvent(handle: string, event: ProtocolEvent): void {\n // No caller can subscribe until open() returns, so progress, metadata, and\n // warning events observed before a DatasetSession exists have no consumer.\n // Retaining only terminal state prevents an unknown-handle event stream\n // from becoming an unbounded main-thread cache while preserving the race\n // that must not return a dead session from open().\n if (event.event !== \"runtimeError\" && event.event !== \"closed\") {\n return;\n }\n let events = this.#orphanEvents.get(handle);\n if (!events) {\n while (this.#orphanEvents.size >= MAX_ORPHAN_HANDLES) {\n this.#evictOldestOrphanHandle();\n }\n events = [];\n this.#orphanEvents.set(handle, events);\n }\n if (events.length >= MAX_ORPHAN_EVENTS_PER_HANDLE) {\n events.shift();\n this.#orphanEventCount -= 1;\n }\n while (this.#orphanEventCount >= MAX_ORPHAN_EVENTS) {\n this.#evictOldestOrphanEvent();\n }\n events.push(event);\n this.#orphanEventCount += 1;\n }\n\n #evictOldestOrphanEvent(): void {\n const oldest = this.#orphanEvents.entries().next().value as\n | [string, ProtocolEvent[]]\n | undefined;\n if (!oldest) {\n this.#orphanEventCount = 0;\n return;\n }\n const [handle, events] = oldest;\n events.shift();\n this.#orphanEventCount -= 1;\n if (events.length === 0) {\n this.#orphanEvents.delete(handle);\n }\n }\n\n #evictOldestOrphanHandle(): void {\n const handle = this.#orphanEvents.keys().next().value as string | undefined;\n if (handle !== undefined) {\n this.#deleteOrphanEvents(handle);\n }\n }\n\n #deleteOrphanEvents(handle: string): void {\n const events = this.#orphanEvents.get(handle);\n if (!events) {\n return;\n }\n this.#orphanEventCount -= events.length;\n this.#orphanEvents.delete(handle);\n }\n\n #clearOrphanEvents(): void {\n this.#orphanEvents.clear();\n this.#orphanEventCount = 0;\n }\n\n #handleRuntimeFailure(error: TabularkError): void {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n this.#sourceStaging.close();\n for (const controller of this.#openingSources) controller.abort();\n this.#abortRangeSingleflights();\n this.#rangeCache.clear();\n this.#clearOrphanEvents();\n void this.#closeAllSourceReaders();\n for (const session of this.#sessions.values()) {\n session.failLocally(error);\n }\n this.#sessions.clear();\n }\n}\n\nclass DatasetSessionImpl implements DatasetSession {\n readonly #engine: Engine;\n readonly handle: string;\n readonly tables: readonly Readonly<TableDescriptor>[];\n readonly #listeners = new Set<(event: DatasetEvent) => void>();\n readonly #diagnosticListeners = new Set<(diagnostic: TabularkDiagnostic) => void>();\n readonly #diagnostics: TabularkDiagnostic[] = [];\n readonly #capabilitySeed: DatasetCapabilitySeed;\n readonly #tableHandles = new Set<TableHandleImpl>();\n #observedTypedValues: boolean | undefined;\n #observedMultiTable: boolean | undefined;\n #observedProgressive: boolean | undefined;\n closed = false;\n terminalError: TabularkError | undefined;\n\n constructor(\n engine: Engine,\n handle: string,\n tables: readonly TableDescriptor[],\n capabilitySeed?: DatasetCapabilitySeed,\n ) {\n this.#engine = engine;\n this.handle = handle;\n this.tables = Object.freeze(tables.map((table) => Object.freeze({ ...table })));\n this.#capabilitySeed = capabilitySeed ?? createFallbackDatasetCapabilitySeed(this.tables);\n }\n\n openTable(tableId: string): Promise<TableHandle> {\n return this.#engine.openTable(this, tableId);\n }\n\n subscribe(listener: (event: DatasetEvent) => void): Unsubscribe {\n this.assertOpen();\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n getDiagnostics(): readonly TabularkDiagnostic[] {\n return Object.freeze([...this.#diagnostics]);\n }\n\n subscribeDiagnostics(listener: (diagnostic: TabularkDiagnostic) => void): Unsubscribe {\n this.assertOpen();\n if (typeof listener !== \"function\") {\n throw invalidArgument(\"diagnostic listener must be a function\");\n }\n this.#diagnosticListeners.add(listener);\n return () => this.#diagnosticListeners.delete(listener);\n }\n\n getCapabilities(): Readonly<DatasetCapabilities> {\n const openedTables = [...this.#tableHandles];\n const typedValues = openedTables.length > 0\n ? openedTables.every((table) => table.getCapabilities().typedValues)\n : this.#observedTypedValues ?? this.#capabilitySeed.typedValues;\n const multiTable = this.tables.length > 1\n || openedTables.some((table) => table.getCapabilities().multiTable)\n || this.#observedMultiTable === true\n || this.#capabilitySeed.multiTable;\n return Object.freeze({\n ...this.#capabilitySeed,\n progressive: this.#observedProgressive ?? this.#capabilitySeed.progressive,\n typedValues,\n multiTable,\n });\n }\n\n close(): Promise<void> {\n return this.#engine.closeSession(this);\n }\n\n assertOpen(): void {\n if (this.closed) {\n throw closedError(\"Dataset session\");\n }\n }\n\n addTableHandle(handle: TableHandleImpl): void {\n this.#tableHandles.add(handle);\n }\n\n removeTableHandle(handle: TableHandleImpl): void {\n this.#tableHandles.delete(handle);\n }\n\n closeLocally(): void {\n if (this.closed) {\n return;\n }\n this.#engine.clearDatasetCache(this.handle);\n this.closed = true;\n for (const table of this.#tableHandles) {\n table.closeLocally();\n }\n this.#tableHandles.clear();\n this.#emit({ type: \"closed\" });\n }\n\n failLocally(error: TabularkError): void {\n if (this.closed) {\n return;\n }\n this.#engine.clearDatasetCache(this.handle);\n this.closed = true;\n this.terminalError = error;\n this.#recordDiagnostic(diagnosticFromError(error));\n this.#emit({ type: \"runtimeError\", error });\n for (const table of [...this.#tableHandles]) {\n table.failLocally(error);\n }\n this.#tableHandles.clear();\n this.#emit({ type: \"closed\" });\n }\n\n handleEvent(event: ProtocolEvent): void {\n if (this.closed && event.event !== \"closed\") {\n return;\n }\n switch (event.event) {\n case \"progress\":\n this.#emit({\n type: \"progress\",\n progress: normalizeProgress(event.payload, event.tableId, event.revision),\n });\n break;\n case \"metadata\": {\n const metadata = normalizeMetadataWire(event.payload);\n this.#observedTypedValues = this.#observedTypedValues === undefined\n ? metadata.capabilities.typedValues\n : this.#observedTypedValues && metadata.capabilities.typedValues;\n if (this.#capabilitySeed.adapterId === \"tabulark:arrow-ipc\") {\n this.#observedProgressive = metadata.capabilities.randomAccess === \"indexed-prefix\";\n }\n this.#observedMultiTable = this.#observedMultiTable === true\n || metadata.capabilities.multiTable;\n this.#emit({ type: \"metadata\", metadata });\n if (!event.tableHandle) {\n for (const table of this.#tableHandles) {\n if (table.metadata.tableId === metadata.tableId) {\n table.updateMetadata(metadata);\n }\n }\n }\n break;\n }\n case \"warning\": {\n const warning = normalizeWarning(event.payload);\n const routedTable = event.tableHandle === undefined\n ? undefined\n : [...this.#tableHandles].find((table) => table.handle === event.tableHandle);\n this.#recordDiagnostic(diagnosticFromWarning(\n warning,\n event.tableId ?? routedTable?.metadata.tableId,\n event.revision ?? routedTable?.metadata.revision,\n ));\n this.#emit({ type: \"warning\", warning });\n for (const table of this.#tableHandles) {\n if (table.matchesWarning(warning) && !event.tableHandle) {\n const recordDiagnostic = event.tableId !== undefined\n && table.metadata.tableId === event.tableId;\n table.emitWarning(\n warning,\n recordDiagnostic,\n event.tableId,\n event.revision,\n );\n }\n }\n break;\n }\n case \"runtimeError\": {\n const error = errorFromWire(event.payload);\n if (event.tableHandle) {\n const routedTable = [...this.#tableHandles].find((table) => table.handle === event.tableHandle);\n this.#recordDiagnostic(diagnosticFromError(\n error,\n event.tableId ?? routedTable?.metadata.tableId,\n event.revision ?? routedTable?.metadata.revision,\n ));\n this.#emit({ type: \"runtimeError\", error });\n } else {\n this.failLocally(error);\n }\n break;\n }\n case \"closed\":\n if (!event.tableHandle) {\n this.closeLocally();\n }\n break;\n }\n if (event.tableHandle) {\n for (const table of this.#tableHandles) {\n if (table.handle === event.tableHandle) {\n table.handleEvent(event);\n }\n }\n }\n }\n\n #emit(event: DatasetEvent): void {\n for (const listener of this.#listeners) {\n safelyCall(listener, event);\n }\n }\n\n #recordDiagnostic(diagnostic: TabularkDiagnostic): void {\n if (this.#diagnostics.length >= MAX_DIAGNOSTICS) {\n this.#diagnostics.shift();\n }\n this.#diagnostics.push(diagnostic);\n for (const listener of this.#diagnosticListeners) {\n safelyCall(listener, diagnostic);\n }\n }\n}\n\nclass TableHandleImpl implements TableHandle {\n readonly #engine: Engine;\n readonly #session: DatasetSessionImpl;\n readonly handle: string;\n #metadata: Readonly<TableMetadata>;\n readonly #listeners = new Set<(event: TableEvent) => void>();\n readonly #diagnosticListeners = new Set<(diagnostic: TabularkDiagnostic) => void>();\n readonly #diagnostics: TabularkDiagnostic[] = [];\n closed = false;\n\n constructor(\n engine: Engine,\n session: DatasetSessionImpl,\n handle: string,\n metadata: Readonly<TableMetadata>,\n ) {\n this.#engine = engine;\n this.#session = session;\n this.handle = handle;\n this.#metadata = metadata;\n // Scan warnings can arrive before a caller opens a particular worksheet.\n // Seed only diagnostics explicitly routed to this logical table; a\n // dataset-level diagnostic must not be duplicated into every worksheet.\n for (const diagnostic of session.getDiagnostics()) {\n if (diagnostic.tableId === metadata.tableId) {\n this.#diagnostics.push(diagnostic);\n }\n }\n }\n\n get metadata(): Readonly<TableMetadata> {\n return this.#metadata;\n }\n\n get datasetHandle(): string {\n return this.#session.handle;\n }\n\n get datasetClosed(): boolean {\n return this.#session.closed;\n }\n\n readRange(request: RangeRequest, options: ReadRangeOptions = {}): Promise<TableBatch> {\n return this.#engine.readRange(this, request, options);\n }\n\n getPresentation(): Promise<TablePresentation | null> {\n return this.#engine.getPresentation(this);\n }\n\n readPresentationRange(\n request: RangeRequest,\n options: ReadRangeOptions = {},\n ): Promise<PresentationRange | null> {\n return this.#engine.readPresentationRange(this, request, options);\n }\n\n subscribe(listener: (event: TableEvent) => void): Unsubscribe {\n this.assertOpen();\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n getDiagnostics(): readonly TabularkDiagnostic[] {\n return Object.freeze([...this.#diagnostics]);\n }\n\n subscribeDiagnostics(listener: (diagnostic: TabularkDiagnostic) => void): Unsubscribe {\n this.assertOpen();\n if (typeof listener !== \"function\") {\n throw invalidArgument(\"diagnostic listener must be a function\");\n }\n this.#diagnosticListeners.add(listener);\n return () => this.#diagnosticListeners.delete(listener);\n }\n\n getCapabilities(): Readonly<TableCapabilities> {\n const capabilities = this.#metadata.capabilities;\n // Preserve logical extension flags supplied by an adapter while excluding\n // names that would expose private transport/runtime implementation state.\n const logicalExtensions = Object.fromEntries(\n Object.entries(capabilities)\n .filter(([name, value]) => !isPrivateCapabilityName(name) && isLogicalCapabilityValue(value))\n .map(([name, value]) => [name, freezeLogicalCapabilityValue(value)]),\n );\n return Object.freeze({\n ...logicalExtensions,\n randomAccess: capabilities.randomAccess,\n typedValues: capabilities.typedValues,\n search: capabilities.search,\n sort: capabilities.sort,\n filter: capabilities.filter,\n multiTable: capabilities.multiTable,\n });\n }\n\n close(): Promise<void> {\n return this.#engine.closeTable(this);\n }\n\n assertOpen(): void {\n if (this.closed) {\n throw closedError(\"Table handle\");\n }\n }\n\n closeLocally(): void {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.#session.removeTableHandle(this);\n this.#emit({ type: \"closed\" });\n }\n\n failLocally(error: TabularkError): void {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.#session.removeTableHandle(this);\n this.#recordDiagnostic(diagnosticFromError(error, this.metadata.tableId, this.metadata.revision));\n this.#emit({ type: \"runtimeError\", error });\n this.#emit({ type: \"closed\" });\n }\n\n updateMetadata(metadata: Readonly<TableMetadata>): void {\n if (this.closed) {\n return;\n }\n this.#engine.updateTableCacheVersion(\n this.#session.handle,\n metadata.tableId,\n metadata.revision,\n metadata.schema.version,\n );\n this.#metadata = metadata;\n this.#emit({ type: \"metadata\", metadata });\n }\n\n matchesWarning(warning: SourceWarning): boolean {\n return warning.handle === this.handle || warning.handle === this.#session.handle;\n }\n\n emitWarning(\n warning: SourceWarning,\n recordDiagnostic = true,\n tableId = this.metadata.tableId,\n revision = this.metadata.revision,\n ): void {\n if (!this.closed) {\n if (recordDiagnostic) {\n this.#recordDiagnostic(diagnosticFromWarning(\n warning,\n tableId,\n revision,\n ));\n }\n this.#emit({ type: \"warning\", warning });\n }\n }\n\n handleEvent(event: ProtocolEvent): void {\n if (this.closed && event.event !== \"closed\") {\n return;\n }\n switch (event.event) {\n case \"metadata\":\n this.updateMetadata(normalizeMetadataWire(event.payload));\n break;\n case \"warning\":\n this.emitWarning(\n normalizeWarning(event.payload),\n true,\n event.tableId ?? this.metadata.tableId,\n event.revision ?? this.metadata.revision,\n );\n break;\n case \"runtimeError\":\n this.failLocally(errorFromWire(event.payload));\n break;\n case \"closed\":\n this.closeLocally();\n break;\n case \"progress\":\n break;\n }\n }\n\n #emit(event: TableEvent): void {\n for (const listener of this.#listeners) {\n safelyCall(listener, event);\n }\n }\n\n #recordDiagnostic(diagnostic: TabularkDiagnostic): void {\n if (this.#diagnostics.length >= MAX_DIAGNOSTICS) {\n this.#diagnostics.shift();\n }\n this.#diagnostics.push(diagnostic);\n for (const listener of this.#diagnosticListeners) {\n safelyCall(listener, diagnostic);\n }\n }\n}\n\nfunction normalizeEngineOptions(options: EngineOptions): NormalizedEngineOptions {\n if (!options || typeof options !== \"object\") {\n throw invalidArgument(\"createEngine options are required\");\n }\n if (\"wasmModuleUrl\" in options || \"workerUrl\" in options) {\n throw invalidArgument(\"wasmModuleUrl and workerUrl were removed; register an official adapter instead\");\n }\n if (!Array.isArray(options.adapters) || options.adapters.length === 0) {\n throw invalidArgument(\"adapters must contain at least one official adapter descriptor\");\n }\n const adapters: AdapterRegistration[] = [];\n const ids = new Set<OfficialAdapterId>();\n for (const [index, descriptor] of options.adapters.entries()) {\n const registration = resolveOfficialAdapter(descriptor);\n if (!registration) {\n throw invalidArgument(`adapters[${index}] is not an official frozen adapter descriptor`);\n }\n if (ids.has(registration.id)) {\n throw invalidArgument(`Adapter ${registration.id} is registered more than once`);\n }\n ids.add(registration.id);\n adapters.push(Object.freeze({ ...registration }));\n }\n const memoryBudgetBytes = options.memoryBudgetBytes ?? DEFAULT_MEMORY_BUDGET_BYTES;\n if (!Number.isSafeInteger(memoryBudgetBytes) || memoryBudgetBytes <= 0) {\n throw invalidArgument(\"memoryBudgetBytes must be a positive safe integer\");\n }\n if (memoryBudgetBytes < MIN_MEMORY_BUDGET_BYTES) {\n throw invalidArgument(\n `memoryBudgetBytes must be at least ${MIN_MEMORY_BUDGET_BYTES} bytes`,\n { minimum: MIN_MEMORY_BUDGET_BYTES, memoryBudgetBytes },\n );\n }\n return {\n memoryBudgetBytes,\n limits: deriveMemoryBudgetLimits(memoryBudgetBytes),\n adapters: Object.freeze(adapters),\n workerUrl: new URL(\"./worker.js\", import.meta.url).href,\n workerName: options.workerName ?? \"tabulark\",\n };\n}\n\nfunction normalizeOpenOptions<Options>(\n options: OpenSourceOptions<Options>,\n adapters: ReadonlyMap<OfficialAdapterId, AdapterRegistration>,\n inferredSourceName?: string,\n rangeSource = false,\n): NormalizedOpenOptions {\n if (!options || typeof options !== \"object\") {\n throw invalidArgument(\"open options are required\");\n }\n if (options.transferInput !== undefined && typeof options.transferInput !== \"boolean\") {\n throw invalidArgument(\"transferInput must be a boolean\");\n }\n const sourceMode = options.sourceMode === undefined ? \"auto\" : options.sourceMode;\n if (!isSourceMode(sourceMode)) {\n throw invalidArgument(\"sourceMode must be auto or large\");\n }\n if (rangeSource && (options.sourceMode !== undefined || options.transferInput !== undefined)) {\n throw invalidArgument(\"sourceMode and transferInput do not apply to RangeSource inputs\");\n }\n const selected = resolveOfficialAdapter(options.adapter);\n if (!selected) {\n throw invalidArgument(\"adapter must be an official frozen adapter descriptor\");\n }\n const registered = adapters.get(selected.id);\n if (!registered) {\n throw invalidArgument(`Adapter ${selected.id} was not registered with this engine`);\n }\n const rawOptions = options.adapterOptions;\n if (rawOptions !== undefined && (!isRecord(rawOptions) || Array.isArray(rawOptions))) {\n throw invalidArgument(\"adapterOptions must be an object\");\n }\n let normalized: Readonly<Record<string, unknown>>;\n switch (selected.id) {\n case \"tabulark:delimited\":\n normalized = normalizeDelimitedOptions(\n rawOptions as DelimitedAdapterOptions | undefined,\n inferredSourceName,\n );\n break;\n case \"tabulark:arrow-ipc\":\n normalized = normalizeArrowOptions(\n rawOptions as ArrowIpcAdapterOptions | undefined,\n inferredSourceName,\n );\n break;\n case \"tabulark:parquet\":\n normalized = normalizeParquetOptions(\n rawOptions as ParquetAdapterOptions | undefined,\n inferredSourceName,\n );\n break;\n case \"tabulark:excel\":\n normalized = normalizeExcelOptions(\n rawOptions as ExcelAdapterOptions | undefined,\n inferredSourceName,\n );\n break;\n }\n return {\n adapter: registered,\n options: normalized,\n sourceMode,\n isRangeSource: rangeSource,\n };\n}\n\nfunction largeSourceLimitError(requiredBytes: unknown): TabularkError {\n // Error details cross the public JS boundary as numbers. Clamp malformed or\n // rounded Blob sizes to a safe sentinel rather than exposing an unsafe\n // quantity that could not be represented reliably by a range request.\n const required = typeof requiredBytes === \"number\"\n && Number.isFinite(requiredBytes)\n && requiredBytes >= 0\n ? Math.min(Math.floor(requiredBytes), Number.MAX_SAFE_INTEGER)\n : Number.MAX_SAFE_INTEGER;\n return new TabularkError(\n \"RESOURCE_LIMIT\",\n `Large source mode supports Blob inputs up to ${MAX_LARGE_SOURCE_BYTES} bytes`,\n {\n details: {\n resource: \"source-staging\",\n requiredBytes: required,\n availableBytes: MAX_LARGE_SOURCE_BYTES,\n },\n },\n );\n}\n\nfunction normalizeDelimitedOptions(\n options: DelimitedAdapterOptions | undefined,\n inferredSourceName?: string,\n): Readonly<Record<string, unknown>> {\n const raw = options ?? {};\n assertManifestKeys(\"tabulark:delimited\", raw);\n const dialect = raw.dialect ?? \"csv\";\n const header = raw.header ?? \"first-row\";\n const mode = raw.mode ?? \"lenient\";\n if (dialect !== \"csv\" && dialect !== \"tsv\") {\n throw invalidArgument(\"dialect must be csv or tsv\");\n }\n if (header !== \"first-row\" && header !== \"none\") {\n throw invalidArgument(\"header must be first-row or none\");\n }\n if (mode !== \"lenient\" && mode !== \"strict\") {\n throw invalidArgument(\"mode must be lenient or strict\");\n }\n const delimiter = raw.delimiter ?? (dialect === \"csv\" ? \",\" : \"\\t\");\n if (!isValidDelimiter(delimiter)) {\n throw invalidArgument(\"delimiter must be one non-NUL ASCII byte other than CR, LF, or quote\");\n }\n const sourceName = normalizeSourceName(raw.sourceName ?? inferredSourceName);\n return Object.freeze({\n dialect,\n header,\n mode,\n delimiter,\n ...(sourceName === undefined ? {} : { sourceName }),\n });\n}\n\nfunction normalizeArrowOptions(\n options: ArrowIpcAdapterOptions | undefined,\n inferredSourceName?: string,\n): Readonly<Record<string, unknown>> {\n const raw = options ?? {};\n assertManifestKeys(\"tabulark:arrow-ipc\", raw);\n const container = raw.container ?? \"auto\";\n if (container !== \"auto\" && container !== \"file\" && container !== \"stream\") {\n throw invalidArgument(\"container must be auto, file, or stream\");\n }\n const sourceName = normalizeSourceName(raw.sourceName ?? inferredSourceName);\n return Object.freeze({\n container,\n ...(sourceName === undefined ? {} : { sourceName }),\n });\n}\n\nfunction normalizeParquetOptions(\n options: ParquetAdapterOptions | undefined,\n inferredSourceName?: string,\n): Readonly<Record<string, unknown>> {\n const raw = options ?? {};\n assertManifestKeys(\"tabulark:parquet\", raw);\n const sourceName = normalizeSourceName(raw.sourceName ?? inferredSourceName);\n return Object.freeze(sourceName === undefined ? {} : { sourceName });\n}\n\nfunction normalizeExcelOptions(\n options: ExcelAdapterOptions | undefined,\n inferredSourceName?: string,\n): Readonly<Record<string, unknown>> {\n const raw = options ?? {};\n assertManifestKeys(\"tabulark:excel\", raw);\n const format = raw.format ?? \"auto\";\n if (format !== \"auto\" && format !== \"xls\" && format !== \"xlsx\") {\n throw invalidArgument(\"format must be auto, xls, or xlsx\");\n }\n const sourceName = normalizeSourceName(raw.sourceName ?? inferredSourceName);\n return Object.freeze({\n format,\n ...(sourceName === undefined ? {} : { sourceName }),\n });\n}\n\nfunction normalizeSourceName(value: unknown): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== \"string\" || value.length === 0 || value.length > 1_024) {\n throw invalidArgument(\"sourceName must contain between 1 and 1024 characters\");\n }\n return value;\n}\n\nfunction assertManifestKeys(id: OfficialAdapterId, value: object): void {\n const allowedSet = new Set(officialAdapterManifestEntry(id).options.allowedKeys);\n for (const key of Object.keys(value)) {\n if (!allowedSet.has(key)) {\n throw invalidArgument(`Unknown adapter option: ${key}`);\n }\n }\n}\n\nfunction normalizeDescriptors(value: unknown): readonly TableDescriptor[] {\n if (!Array.isArray(value)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Worker returned invalid table descriptors\");\n }\n return value.map((entry, index) => {\n if (!isRecord(entry) || typeof entry.id !== \"string\" || typeof entry.name !== \"string\") {\n throw new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n `Worker returned an invalid table descriptor at index ${index}`,\n );\n }\n return { id: entry.id, name: entry.name };\n });\n}\n\nfunction normalizeMetadataWire(value: unknown): Readonly<TableMetadata> {\n if (!isRecord(value) || typeof value.tableId !== \"string\" || typeof value.name !== \"string\") {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Worker returned invalid table metadata\");\n }\n const rawExtent = isRecord(value.extent) ? value.extent : {};\n const rawSchema = isRecord(value.schema) ? value.schema : {};\n const rawCapabilities = isRecord(value.capabilities) ? value.capabilities : {};\n const columns = Array.isArray(rawSchema.columns)\n ? rawSchema.columns.map((column, index) => normalizeColumn(column, index))\n : [];\n return normalizeMetadata({\n tableId: value.tableId,\n name: value.name,\n revision: numeric(value.revision, 0),\n extent: {\n rows: normalizeAxis(rawExtent.rows, \"at-least\", 0),\n columns: normalizeAxis(rawExtent.columns, \"exact\", columns.length),\n },\n schema: { version: numeric(rawSchema.version, 0), columns },\n capabilities: {\n ...rawCapabilities,\n randomAccess: rawCapabilities.randomAccess === \"full\" ? \"full\" : \"indexed-prefix\",\n typedValues: rawCapabilities.typedValues === true,\n search: rawCapabilities.search === true,\n sort: rawCapabilities.sort === true,\n filter: rawCapabilities.filter === true,\n multiTable: rawCapabilities.multiTable === true,\n },\n });\n}\n\nfunction normalizePresentationWire(\n value: unknown,\n metadata: Readonly<TableMetadata>,\n): TablePresentation | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (!isRecord(value) || value.kind !== \"spreadsheet-v1\") {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Worker returned an invalid table presentation\");\n }\n if (value.tableId !== metadata.tableId) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Presentation tableId does not match its table\");\n }\n const visibility = value.visibility === \"hidden\" || value.visibility === \"very-hidden\"\n ? value.visibility\n : \"visible\";\n return Object.freeze({\n kind: \"spreadsheet-v1\" as const,\n tableId: metadata.tableId,\n revision: numeric(value.revision, metadata.revision),\n visibility,\n frozenRows: numeric(value.frozenRows, 0),\n frozenColumns: numeric(value.frozenColumns, 0),\n rows: normalizePresentationAxis(value.rows, \"rows\"),\n columns: normalizePresentationAxis(value.columns, \"columns\"),\n styles: normalizePresentationStyles(value.styles),\n } satisfies SpreadsheetPresentation);\n}\n\nfunction normalizePresentationRangeWire(\n value: unknown,\n metadata: Readonly<TableMetadata>,\n requested: RangeRequest,\n): PresentationRange | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (!isRecord(value) || value.kind !== \"spreadsheet-v1\" || value.tableId !== metadata.tableId) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Worker returned an invalid presentation range\");\n }\n const range = isRecord(value.range) ? value.range : {};\n for (const key of [\"rowStart\", \"rowCount\", \"columnStart\", \"columnCount\"] as const) {\n if (range[key] !== requested[key]) {\n throw new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n \"Presentation range must be aligned with its requested range\",\n );\n }\n }\n if (!Array.isArray(value.styleIds) || value.styleIds.length !== requested.rowCount) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Presentation style rows do not match the range\");\n }\n const styleIds = Object.freeze(value.styleIds.map((row, rowIndex) => {\n if (!Array.isArray(row) || row.length !== requested.columnCount) {\n throw new TabularkError(\n \"PROTOCOL_INCOMPATIBLE\",\n `Presentation style row ${rowIndex} does not match the range`,\n );\n }\n return Object.freeze(row.map((styleId) => (\n styleId === null || (Number.isSafeInteger(styleId) && (styleId as number) >= 0)\n ? styleId as number | null\n : invalidPresentationStyleId()\n )));\n }));\n const mergedCells = Array.isArray(value.mergedCells)\n ? Object.freeze(value.mergedCells.map((region, index) => normalizeMergedCell(region, index)))\n : Object.freeze([]);\n return Object.freeze({\n kind: \"spreadsheet-v1\" as const,\n tableId: metadata.tableId,\n revision: numeric(value.revision, metadata.revision),\n range: Object.freeze({ ...requested }),\n styleIds,\n mergedCells,\n rows: normalizePresentationAxis(value.rows, \"rows\"),\n columns: normalizePresentationAxis(value.columns, \"columns\"),\n });\n}\n\nfunction invalidPresentationStyleId(): never {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Presentation style IDs must be non-negative integers or null\");\n}\n\nfunction normalizePresentationAxis(value: unknown, name: string): readonly PresentationAxisEntry[] {\n if (value === undefined) return Object.freeze([]);\n if (!Array.isArray(value)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name} must be an array`);\n }\n const seen = new Set<number>();\n return Object.freeze(value.map((entry, index) => {\n if (!isRecord(entry) || !Number.isSafeInteger(entry.index) || (entry.index as number) < 0) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name}[${index}] has an invalid index`);\n }\n const axisIndex = entry.index as number;\n if (seen.has(axisIndex)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name} contains duplicate index ${axisIndex}`);\n }\n seen.add(axisIndex);\n if (entry.size !== undefined && (typeof entry.size !== \"number\" || !Number.isFinite(entry.size) || entry.size < 0)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name}[${index}] has an invalid size`);\n }\n if (entry.hidden !== undefined && typeof entry.hidden !== \"boolean\") {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation ${name}[${index}] has an invalid hidden flag`);\n }\n return Object.freeze({\n index: axisIndex,\n ...(entry.size === undefined ? {} : { size: entry.size as number }),\n ...(entry.hidden === undefined ? {} : { hidden: entry.hidden as boolean }),\n });\n }));\n}\n\nfunction normalizePresentationStyles(value: unknown): readonly PresentationStyle[] {\n if (value === undefined) return Object.freeze([]);\n if (!Array.isArray(value)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", \"Presentation styles must be an array\");\n }\n return Object.freeze(value.map((style, index) => {\n if (!isRecord(style)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Presentation style ${index} must be an object`);\n }\n // Copy only the stable static style vocabulary. Unknown producer fields are\n // intentionally ignored so future adapters can enrich their private wire DTO.\n return Object.freeze({\n ...(typeof style.numberFormat === \"string\" ? { numberFormat: style.numberFormat } : {}),\n ...(normalizePresentationFont(style.font) ? { font: normalizePresentationFont(style.font)! } : {}),\n ...(normalizePresentationColor(style.foregroundColor) ? { foregroundColor: normalizePresentationColor(style.foregroundColor)! } : {}),\n ...(normalizePresentationColor(style.backgroundColor) ? { backgroundColor: normalizePresentationColor(style.backgroundColor)! } : {}),\n ...(normalizePresentationColor(style.fillColor) ? { fillColor: normalizePresentationColor(style.fillColor)! } : {}),\n ...(normalizePresentationBorders(style.borders) ? { borders: normalizePresentationBorders(style.borders)! } : {}),\n ...(isHorizontalAlignment(style.horizontalAlignment)\n ? { horizontalAlignment: style.horizontalAlignment }\n : {}),\n ...(isVerticalAlignment(style.verticalAlignment)\n ? { verticalAlignment: style.verticalAlignment }\n : {}),\n ...(typeof style.wrapText === \"boolean\" ? { wrapText: style.wrapText } : {}),\n });\n }));\n}\n\nfunction normalizePresentationColor(value: unknown): Readonly<{ css?: string }> | undefined {\n if (!isRecord(value) || typeof value.css !== \"string\" || value.css.length === 0 || value.css.length > 128) {\n return undefined;\n }\n return Object.freeze({ css: value.css });\n}\n\nfunction normalizePresentationFont(value: unknown): PresentationStyle[\"font\"] | undefined {\n if (!isRecord(value)) return undefined;\n const color = normalizePresentationColor(value.color);\n const size = typeof value.size === \"number\" && Number.isFinite(value.size) && value.size > 0\n ? value.size\n : undefined;\n const font = {\n ...(typeof value.family === \"string\" && value.family.length > 0 ? { family: value.family } : {}),\n ...(size === undefined ? {} : { size }),\n ...(typeof value.bold === \"boolean\" ? { bold: value.bold } : {}),\n ...(typeof value.italic === \"boolean\" ? { italic: value.italic } : {}),\n ...(typeof value.underline === \"boolean\" ? { underline: value.underline } : {}),\n ...(color === undefined ? {} : { color }),\n };\n return Object.keys(font).length === 0 ? undefined : Object.freeze(font);\n}\n\nfunction normalizePresentationBorders(value: unknown): PresentationStyle[\"borders\"] | undefined {\n if (!isRecord(value)) return undefined;\n const sides = [\"top\", \"right\", \"bottom\", \"left\"] as const;\n const result: Record<string, unknown> = {};\n for (const side of sides) {\n const raw = value[side];\n if (!isRecord(raw)) continue;\n const style = isBorderStyle(raw.style) ? raw.style : undefined;\n const color = normalizePresentationColor(raw.color);\n if (style !== undefined || color !== undefined) {\n result[side] = Object.freeze({\n ...(style === undefined ? {} : { style }),\n ...(color === undefined ? {} : { color }),\n });\n }\n }\n return Object.keys(result).length === 0 ? undefined : Object.freeze(result);\n}\n\nfunction normalizeMergedCell(value: unknown, index: number): MergedCellRegion {\n if (!isRecord(value)) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Merged cell ${index} must be an object`);\n }\n const fields = [\"rowStart\", \"rowEnd\", \"columnStart\", \"columnEnd\"] as const;\n for (const field of fields) {\n if (!Number.isSafeInteger(value[field]) || (value[field] as number) < 0) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Merged cell ${index} has an invalid ${field}`);\n }\n }\n const region = {\n rowStart: value.rowStart as number,\n rowEnd: value.rowEnd as number,\n columnStart: value.columnStart as number,\n columnEnd: value.columnEnd as number,\n };\n if (region.rowEnd <= region.rowStart || region.columnEnd <= region.columnStart) {\n throw new TabularkError(\"PROTOCOL_INCOMPATIBLE\", `Merged cell ${index} must be non-empty`);\n }\n return Object.freeze(region);\n}\n\nfunction isBorderStyle(value: unknown): value is \"none\" | \"thin\" | \"medium\" | \"thick\" | \"dashed\" | \"dotted\" | \"double\" {\n return value === \"none\" || value === \"thin\" || value === \"medium\" || value === \"thick\"\n || value === \"dashed\" || value === \"dotted\" || value === \"double\";\n}\n\nfunction isHorizontalAlignment(value: unknown): value is \"general\" | \"left\" | \"center\" | \"right\" | \"justify\" {\n return value === \"general\" || value === \"left\" || value === \"center\" || value === \"right\" || value === \"justify\";\n}\n\nfunction isVerticalAlignment(value: unknown): value is \"top\" | \"center\" | \"bottom\" | \"justify\" {\n return value === \"top\" || value === \"center\" || value === \"bottom\" || value === \"justify\";\n}\n\nfunction normalizeColumn(value: unknown, index: number): TableMetadata[\"schema\"][\"columns\"][number] {\n const raw = isRecord(value) ? value : {};\n return {\n id: typeof raw.id === \"string\" ? raw.id : `c${index}`,\n name: typeof raw.name === \"string\" ? raw.name : `column_${index + 1}`,\n index: numeric(raw.index, index),\n dataType: normalizeDataType(raw.dataType ?? { type: \"unknown\" }),\n nullable: raw.nullable !== false,\n ...(isRecord(raw.metadata)\n ? { metadata: Object.freeze(Object.fromEntries(\n Object.entries(raw.metadata).map(([key, entry]) => [key, String(entry)]),\n )) }\n : {}),\n };\n}\n\nfunction normalizeAxis(\n value: unknown,\n fallbackKind: \"exact\" | \"at-least\",\n fallbackValue: number,\n): TableMetadata[\"extent\"][\"rows\"] {\n if (isRecord(value)) {\n if (value.kind === \"unknown\") {\n return { kind: \"unknown\" };\n }\n if (\n (value.kind === \"exact\" || value.kind === \"at-least\")\n && Number.isSafeInteger(value.value)\n && (value.value as number) >= 0\n ) {\n return { kind: value.kind, value: value.value as number };\n }\n }\n return { kind: fallbackKind, value: fallbackValue };\n}\n\nfunction isValidDelimiter(value: unknown): value is string {\n if (typeof value !== \"string\" || value.length !== 1) {\n return false;\n }\n const byte = value.charCodeAt(0);\n return byte <= 0x7f && byte !== 0 && byte !== 0x0d && byte !== 0x0a && byte !== 0x22;\n}\n\nfunction normalizeProgress(\n value: unknown,\n tableId?: string,\n revision?: number,\n): RuntimeProgress {\n const raw = isRecord(value) ? value : {};\n return {\n sourceHandle: typeof raw.sourceHandle === \"string\" ? raw.sourceHandle : \"\",\n ...(typeof raw.tableId === \"string\" && raw.tableId.length > 0\n ? { tableId: raw.tableId }\n : typeof tableId === \"string\" && tableId.length > 0 ? { tableId } : {}),\n ...(Number.isSafeInteger(raw.revision) && (raw.revision as number) >= 0\n ? { revision: raw.revision as number }\n : Number.isSafeInteger(revision) && (revision as number) >= 0\n ? { revision: revision as number }\n : {}),\n bytesScanned: numeric(raw.bytesScanned, 0),\n rowsDiscovered: numeric(raw.rowsDiscovered, 0),\n done: raw.done === true,\n };\n}\n\nfunction normalizeWarning(value: unknown): SourceWarning {\n const raw = isRecord(value) ? value : {};\n // Preserve the historical warning shape (including any adapter-supplied\n // integer offset); the structured diagnostic applies its own safe bounds.\n const byteOffset = Number.isSafeInteger(raw.byteOffset)\n ? raw.byteOffset as number\n : undefined;\n const sourceOffset = Number.isSafeInteger(raw.sourceOffset) && (raw.sourceOffset as number) >= 0\n ? raw.sourceOffset as number\n : undefined;\n const row = Number.isSafeInteger(raw.row) && (raw.row as number) >= 0\n ? raw.row as number\n : undefined;\n const column = Number.isSafeInteger(raw.column) && (raw.column as number) >= 0\n ? raw.column as number\n : undefined;\n const tableId = safeDiagnosticTableId(raw.tableId);\n const resource = safeDiagnosticResource(raw.resource);\n const requiredBytes = firstNonNegativeSafeInteger(raw.requiredBytes);\n const availableBytes = firstNonNegativeSafeInteger(raw.availableBytes);\n return {\n handle: typeof raw.handle === \"string\" ? raw.handle : \"\",\n kind: typeof raw.kind === \"string\" ? raw.kind : \"warning\",\n message: typeof raw.message === \"string\" ? raw.message : \"Source warning\",\n ...(tableId === undefined ? {} : { tableId }),\n ...(resource === undefined ? {} : { resource }),\n ...(requiredBytes === undefined ? {} : { requiredBytes }),\n ...(availableBytes === undefined ? {} : { availableBytes }),\n ...(byteOffset === undefined ? {} : { byteOffset }),\n ...(sourceOffset === undefined ? {} : { sourceOffset }),\n ...(row === undefined ? {} : { row }),\n ...(column === undefined ? {} : { column }),\n };\n}\n\nfunction diagnosticFromWarning(\n warning: SourceWarning,\n tableId?: string,\n revision?: number,\n): TabularkDiagnostic {\n const byteOffset = warning.sourceOffset ?? warning.byteOffset;\n const sourceOffset = typeof byteOffset === \"number\" && Number.isSafeInteger(byteOffset) && byteOffset >= 0\n ? byteOffset\n : undefined;\n const warningRow = warning.row;\n const row = typeof warningRow === \"number\" && Number.isSafeInteger(warningRow) && warningRow >= 0\n ? warningRow\n : undefined;\n const warningColumn = warning.column;\n const column = typeof warningColumn === \"number\"\n && Number.isSafeInteger(warningColumn)\n && warningColumn >= 0\n ? warningColumn\n : undefined;\n const diagnosticRevision = typeof revision === \"number\"\n && Number.isSafeInteger(revision)\n && revision >= 0\n ? revision\n : undefined;\n const code = safeDiagnosticCode(warning.kind, \"SOURCE_WARNING\");\n const safeTableId = safeDiagnosticTableId(tableId ?? warning.tableId);\n const resource = safeDiagnosticResource(warning.resource);\n const requiredBytes = firstNonNegativeSafeInteger(warning.requiredBytes);\n const availableBytes = firstNonNegativeSafeInteger(warning.availableBytes);\n return Object.freeze({\n code,\n severity: \"warning\" as const,\n // Keep the legacy warning event available to callers that need its full\n // text, but expose only a stable category sentence here. Adapter warning\n // strings can contain worksheet names or source excerpts and therefore\n // are not safe to retain in the public diagnostic snapshot.\n message: safeDiagnosticMessage(warning.message, diagnosticFallback(code, \"warning\"), code),\n recoverable: true,\n ...(resource === undefined ? {} : { resource }),\n ...(requiredBytes === undefined ? {} : { requiredBytes }),\n ...(availableBytes === undefined ? {} : { availableBytes }),\n ...(sourceOffset === undefined ? {} : { sourceOffset }),\n ...(safeTableId === undefined ? {} : { tableId: safeTableId }),\n ...(diagnosticRevision === undefined ? {} : { revision: diagnosticRevision }),\n ...(row === undefined ? {} : { row }),\n ...(column === undefined ? {} : { column }),\n });\n}\n\nfunction diagnosticFromError(\n error: TabularkError,\n tableId?: string,\n revision?: number,\n): TabularkDiagnostic {\n const details = isRecord(error.details) ? error.details : {};\n const detailOffset = firstNonNegativeSafeInteger(details.sourceOffset)\n ?? firstNonNegativeSafeInteger(details.byteOffset);\n const detailRow = firstNonNegativeSafeInteger(details.row);\n const detailColumn = firstNonNegativeSafeInteger(details.column);\n const detailTableId = typeof details.tableId === \"string\" && details.tableId.length > 0\n ? details.tableId\n : undefined;\n const detailRevision = firstNonNegativeSafeInteger(details.revision);\n const diagnosticRevision = typeof revision === \"number\"\n && Number.isSafeInteger(revision)\n && revision >= 0\n ? revision\n : detailRevision;\n const code = safeDiagnosticCode(error.code, \"RUNTIME_FAILURE\");\n const safeTableId = safeDiagnosticTableId(tableId);\n const safeDetailTableId = safeDiagnosticTableId(detailTableId);\n return Object.freeze({\n code,\n severity: \"error\" as const,\n message: safeErrorDiagnosticMessage(error, code),\n recoverable: error.retryable,\n ...(safeTableId !== undefined\n ? { tableId: safeTableId }\n : safeDetailTableId === undefined\n ? {}\n : { tableId: safeDetailTableId }),\n ...(detailOffset === undefined ? {} : { sourceOffset: detailOffset }),\n ...(diagnosticRevision === undefined ? {} : { revision: diagnosticRevision }),\n ...(detailRow === undefined ? {} : { row: detailRow }),\n ...(detailColumn === undefined ? {} : { column: detailColumn }),\n });\n}\n\nfunction safeErrorDiagnosticMessage(error: TabularkError, code: string): string {\n // Protocol/ABI details are intentionally kept out of the stable diagnostic\n // surface; callers can still inspect the original DatasetEvent error.\n return safeDiagnosticMessage(\n error.message,\n diagnosticFallback(code, \"error\"),\n code,\n );\n}\n\nfunction safeDiagnosticCode(value: unknown, fallback: string): string {\n if (typeof value !== \"string\" || value.length === 0) return fallback;\n const normalized = value.replace(/[^A-Za-z0-9_.:-]/gu, \"_\").slice(0, 96);\n // Protocol/ABI names describe the private transport, not a stable source\n // diagnostic. Keep the original TabularkError code on the compatibility\n // DatasetEvent, but collapse it before it can enter a public snapshot.\n if (normalized === \"PROTOCOL_INCOMPATIBLE\") return \"RUNTIME_FAILURE\";\n return normalized.length > 0 && SAFE_DIAGNOSTIC_CODES.has(normalized)\n ? normalized\n : fallback;\n}\n\n// Adapter-provided text is deliberately not an open-ended public code space:\n// a malicious container must not smuggle a path, worksheet name, or source\n// excerpt into a supposedly safe diagnostic snapshot.\nconst SAFE_DIAGNOSTIC_CODES = new Set([\n \"SOURCE_WARNING\",\n \"RUNTIME_FAILURE\",\n \"ragged-row\",\n \"quote-in-unquoted-field\",\n \"unexpected-data-after-closing-quote\",\n \"unterminated-quote\",\n \"skipped-sheet\",\n \"missing-formula-cache\",\n \"presentation-resource-limit\",\n \"RESOURCE_LIMIT\",\n \"CANCELLED\",\n \"HANDLE_CLOSED\",\n \"RANGE_NOT_INDEXED\",\n \"PARSE_FAILED\",\n \"UNSUPPORTED_FEATURE\",\n \"INVALID_RANGE\",\n \"INVALID_ARGUMENT\",\n \"UNSUPPORTED_RUNTIME\",\n \"SOURCE_UNAVAILABLE\",\n \"SOURCE_CHANGED\",\n \"RANGE_UNSUPPORTED\",\n]);\n\nfunction safeDiagnosticMessage(value: unknown, fallback: string, code?: string): string {\n // Only a small, code-keyed vocabulary is retained. This prevents a source\n // cell, worksheet name, path, URL, or parser buffer excerpt from entering a\n // snapshot even when an adapter sends it as its warning/error message.\n const stable = diagnosticFallback(code, \"warning\");\n return stable.length <= MAX_DIAGNOSTIC_MESSAGE_LENGTH ? stable : fallback;\n}\n\nfunction diagnosticFallback(code: string | undefined, severity: \"warning\" | \"error\"): string {\n switch (code) {\n case \"ragged-row\":\n return \"Rows contain inconsistent field counts\";\n case \"quote-in-unquoted-field\":\n return \"A quoted value appeared in an unquoted field\";\n case \"unexpected-data-after-closing-quote\":\n return \"Unexpected data followed a closing quote\";\n case \"unterminated-quote\":\n return \"A quoted field was not terminated\";\n case \"skipped-sheet\":\n return \"A workbook sheet was skipped\";\n case \"missing-formula-cache\":\n return \"A formula has no cached result\";\n case \"presentation-resource-limit\":\n return \"Spreadsheet presentation exceeded its resource budget\";\n case \"RESOURCE_LIMIT\":\n return \"A configured resource limit was reached\";\n case \"CANCELLED\":\n return \"The operation was cancelled\";\n case \"HANDLE_CLOSED\":\n return \"The handle is closed\";\n case \"RANGE_NOT_INDEXED\":\n return \"The requested range is not indexed yet\";\n case \"PARSE_FAILED\":\n return \"The source could not be parsed\";\n case \"UNSUPPORTED_FEATURE\":\n return \"The source uses an unsupported feature\";\n case \"INVALID_RANGE\":\n return \"The requested range is invalid\";\n case \"INVALID_ARGUMENT\":\n return \"An operation argument is invalid\";\n case \"UNSUPPORTED_RUNTIME\":\n return \"The current runtime is unsupported\";\n case \"SOURCE_UNAVAILABLE\":\n return \"The source is unavailable\";\n case \"SOURCE_CHANGED\":\n return \"The source changed while it was open\";\n case \"RANGE_UNSUPPORTED\":\n return \"The source does not support the requested byte range\";\n case \"RUNTIME_FAILURE\":\n return \"The runtime reported a failure\";\n default:\n return severity === \"warning\" ? \"Source warning\" : \"The operation failed\";\n }\n}\n\nfunction safeDiagnosticTableId(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length === 0 || value.length > 128) {\n return undefined;\n }\n // Table IDs are logical handles, not a channel for source names or paths.\n // Keep the stable identifier alphabet while omitting values that look like\n // filenames, URLs, or traversal fragments instead of returning a lossy copy\n // of potentially sensitive source text.\n return /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/u.test(value) ? value : undefined;\n}\n\nfunction safeDiagnosticResource(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length === 0 || value.length > 96) {\n return undefined;\n }\n return /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/u.test(value) ? value : undefined;\n}\n\nfunction createDatasetCapabilitySeed(\n adapterId: OfficialAdapterId,\n options: Readonly<Record<string, unknown>>,\n tables: readonly TableDescriptor[],\n sourceMode: SourceMode = \"auto\",\n stagedSourceLimit = MAX_ARRAY_BUFFER_BYTES,\n rangeSource = false,\n): DatasetCapabilitySeed {\n const manifest = officialAdapterManifestEntry(adapterId);\n // `auto` is intentionally conservative: a File may resolve to an IPC file\n // (non-progressive) or a stream envelope, and the definitive metadata event\n // updates the snapshot once the adapter has inspected its magic bytes.\n const progressive = adapterId === \"tabulark:delimited\"\n || (adapterId === \"tabulark:arrow-ipc\" && options.container === \"stream\");\n const sourceAccess = adapterId === \"tabulark:arrow-ipc\" && options.container === \"stream\"\n ? \"streaming\"\n : manifest.resources.sourceAccess;\n const maxSourceBytes = rangeSource\n ? MAX_RANGE_SOURCE_BYTES\n : sourceMode === \"large\"\n ? MAX_LARGE_SOURCE_BYTES\n : adapterId === \"tabulark:excel\"\n ? stagedSourceLimit\n : adapterId === \"tabulark:arrow-ipc\" ? 0xffff_ffff : Number.MAX_SAFE_INTEGER;\n return Object.freeze({\n adapterId,\n sourceAccess,\n progressive,\n maxSourceBytes,\n multiTable: tables.length > 1 || adapterId === \"tabulark:excel\",\n presentation: manifest.resources.supportsPresentation,\n typedValues: adapterId === \"tabulark:arrow-ipc\" || adapterId === \"tabulark:parquet\",\n });\n}\n\nfunction createFallbackDatasetCapabilitySeed(\n tables: readonly TableDescriptor[],\n): DatasetCapabilitySeed {\n return Object.freeze({\n adapterId: \"tabulark:delimited\",\n sourceAccess: \"streaming\",\n progressive: true,\n maxSourceBytes: Number.MAX_SAFE_INTEGER,\n multiTable: tables.length > 1,\n presentation: false,\n typedValues: false,\n });\n}\n\nfunction finitePerformanceNow(): number {\n const now = typeof performance !== \"undefined\" && typeof performance.now === \"function\"\n ? performance.now()\n : Date.now();\n return Number.isFinite(now) ? now : 0;\n}\n\nfunction nonNegativeFinite(value: unknown): number {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0 ? value : 0;\n}\n\nfunction nonNegativeSafeQuantity(value: unknown): number {\n return Number.isSafeInteger(value) && (value as number) >= 0 ? value as number : 0;\n}\n\nfunction addPerformanceBytes(current: number, next: number): number {\n const value = nonNegativeFinite(current) + nonNegativeFinite(next);\n return Number.isSafeInteger(value) ? value : Number.MAX_SAFE_INTEGER;\n}\n\nfunction firstNonNegativeSafeInteger(value: unknown): number | undefined {\n return Number.isSafeInteger(value) && (value as number) >= 0 ? value as number : undefined;\n}\n\nfunction sanitizePerformanceStage(value: string): string {\n const normalized = value.replace(/[^A-Za-z0-9_.:-]/gu, \"_\").slice(0, 64);\n return normalized.length > 0 ? normalized : \"operation\";\n}\n\nfunction isPrivateCapabilityName(name: string): boolean {\n // Metadata is adapter-controlled input. Preserve small logical extension\n // flags (for example `customCapability`) but keep transport/runtime state,\n // source paths, and allocation details out of the stable capability view.\n return /(?:protocol|abi|layout|worker|wire|buffer|transport|runtime|module|wasm|memory|source|path|url|resource|reservation|offset|handle|request|response)/iu.test(name);\n}\n\nfunction isLogicalCapabilityValue(value: unknown): boolean {\n if (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n if (typeof value === \"number\") return Number.isFinite(value);\n return Array.isArray(value)\n && value.length <= 64\n && value.every((entry) => entry === null\n || typeof entry === \"boolean\"\n || typeof entry === \"string\"\n || (typeof entry === \"number\" && Number.isFinite(entry)));\n}\n\nfunction freezeLogicalCapabilityValue<T>(value: T): T {\n if (!Array.isArray(value)) return value;\n return Object.freeze([...value]) as T;\n}\n\nfunction inferSourceName(source: unknown): string | undefined {\n if (typeof File !== \"undefined\" && source instanceof File && source.name.length > 0) {\n return source.name;\n }\n return undefined;\n}\n\nfunction errorFromWire(value: unknown): TabularkError {\n if (isRecord(value) && typeof value.code === \"string\" && typeof value.message === \"string\") {\n return TabularkError.fromSerialized({\n code: value.code,\n message: value.message,\n retryable: value.retryable === true,\n ...(value.details === undefined ? {} : { details: value.details }),\n });\n }\n return new TabularkError(\"RUNTIME_FAILURE\", \"The Worker reported a runtime failure\");\n}\n\nfunction asTabularkError(error: unknown, message: string): TabularkError {\n return error instanceof TabularkError\n ? error\n : new TabularkError(\"RUNTIME_FAILURE\", message, { cause: error });\n}\n\n/** Sanitizes arbitrary provider failures before they cross the public boundary. */\nfunction normalizeRangeSourceOpenError(error: unknown): TabularkError {\n const structured = rangeSourceErrorLike(error);\n if (structured !== undefined) {\n const code = sourceErrorCode(structured.code);\n if (code === \"CANCELLED\") return cancelledError();\n if (code === \"HANDLE_CLOSED\") return closedError(\"Range source reader\");\n if (code === \"SOURCE_CHANGED\") {\n return new TabularkError(\"SOURCE_CHANGED\", \"The source changed while it was opening\", {\n retryable: structured.retryable,\n });\n }\n if (code === \"RANGE_UNSUPPORTED\") {\n return new TabularkError(\"RANGE_UNSUPPORTED\", \"The source does not support the requested range\", {\n retryable: structured.retryable,\n });\n }\n if (code === \"RESOURCE_LIMIT\") {\n return new TabularkError(\"RESOURCE_LIMIT\", \"The source exceeds its configured limit\", {\n details: safeSourceLimitDetails(structured.details),\n });\n }\n if (code === \"RUNTIME_FAILURE\") {\n return new TabularkError(\"RUNTIME_FAILURE\", \"The source provider returned invalid bytes\", {\n retryable: structured.retryable,\n });\n }\n return new TabularkError(\"SOURCE_UNAVAILABLE\", \"The source could not be opened\", {\n retryable: structured.retryable,\n });\n }\n if (isAbortLikeError(error)) return cancelledError();\n return new TabularkError(\"SOURCE_UNAVAILABLE\", \"The source could not be opened\", { retryable: true });\n}\n\n/**\n * RangeSource implementations may come from a separately bundled entrypoint,\n * so their TabularkError constructor does not necessarily share identity with\n * core. Capture only the constrained public fields; callers rebuild messages\n * and sanitize any retained details before exposing them.\n */\nfunction rangeSourceErrorLike(value: unknown): {\n readonly code: string;\n readonly retryable: boolean;\n readonly details: unknown;\n} | undefined {\n if (!isRecord(value)) return undefined;\n try {\n const code = value.code;\n const retryable = value.retryable;\n if (typeof code !== \"string\" || typeof retryable !== \"boolean\") return undefined;\n return { code, retryable, details: value.details };\n } catch {\n return undefined;\n }\n}\n\nfunction safeSourceLimitDetails(value: unknown): Readonly<Record<string, unknown>> {\n if (!isRecord(value)) {\n return { resource: \"source-staging\", requiredBytes: 0, availableBytes: 0 };\n }\n const resource = typeof value.resource === \"string\"\n && /^[A-Za-z0-9_.:-]{1,64}$/u.test(value.resource)\n ? value.resource\n : \"source-staging\";\n const requiredBytes = isSafeNonNegativeInteger(value.requiredBytes) ? value.requiredBytes : 0;\n const availableBytes = isSafeNonNegativeInteger(value.availableBytes) ? value.availableBytes : 0;\n return { resource, requiredBytes, availableBytes };\n}\n\nfunction isAbortLikeError(value: unknown): boolean {\n return typeof value === \"object\"\n && value !== null\n && ((value as { name?: unknown }).name === \"AbortError\"\n || (value as { code?: unknown }).code === 20);\n}\n\nfunction numeric(value: unknown, fallback: number): number {\n return Number.isSafeInteger(value) && (value as number) >= 0 ? value as number : fallback;\n}\n\nfunction isReturnedRangeWithin(value: unknown, requested: RangeRequest): boolean {\n if (!isRecord(value)) return false;\n const rowStart = value.rowStart;\n const rowCount = value.rowCount;\n const columnStart = value.columnStart;\n const columnCount = value.columnCount;\n return Number.isSafeInteger(rowStart)\n && rowStart === requested.rowStart\n && Number.isSafeInteger(rowCount)\n && (rowCount as number) >= 0\n && (rowCount as number) <= requested.rowCount\n && Number.isSafeInteger(columnStart)\n && columnStart === requested.columnStart\n && Number.isSafeInteger(columnCount)\n && (columnCount as number) >= 0\n && (columnCount as number) <= requested.columnCount;\n}\n\nfunction safelyCall<T>(listener: (value: T) => void, value: T): void {\n try {\n listener(value);\n } catch (error) {\n if (typeof reportError === \"function\") {\n reportError(error);\n }\n }\n}\n\nfunction sourceStagingBudget(limits: MemoryBudgetLimits): number {\n return limits.mainThreadSourceBytes;\n}\n\n/**\n * Calls a provider's close hook without allowing a malformed reader (or a\n * throwing getter) to replace the structured open/cleanup result. The\n * public contract requires close to be best-effort and idempotent; this\n * helper also covers the invalid-reader path before a typed reader exists.\n */\nasync function closeRangeReaderBestEffort(value: unknown): Promise<void> {\n if (typeof value !== \"object\" || value === null) return;\n let close: unknown;\n try {\n close = (value as { close?: unknown }).close;\n } catch {\n return;\n }\n if (typeof close !== \"function\") return;\n let closeResult: Promise<unknown>;\n try {\n // A provider is allowed to return a Promise, but a non-cooperative close\n // must not make engine shutdown unbounded. Attach a rejection handler even\n // when the timeout wins so a late rejection cannot become unhandled.\n closeResult = Promise.resolve((close as () => unknown).call(value));\n } catch {\n return;\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, LIFECYCLE_CLOSE_TIMEOUT_MS);\n });\n await Promise.race([closeResult.then(() => undefined, () => undefined), timeout]);\n if (timer !== undefined) clearTimeout(timer);\n}\n\n/**\n * Races an open against its AbortSignal. JavaScript Promises cannot be\n * forcibly cancelled, so a late reader is closed when the provider eventually\n * resolves; this keeps cancellation prompt while preserving the exactly-once\n * reader lifecycle guarantee.\n */\nfunction openRangeReaderWithCancellation(\n source: RangeSource,\n options: {\n readonly signal: AbortSignal;\n readonly maxSourceBytes: number;\n readonly maxStagingBytes: number;\n },\n signal: AbortSignal,\n): Promise<RangeSourceReader> {\n let finished = false;\n const opening = signal.aborted\n ? Promise.reject<RangeSourceReader>(cancelledError())\n : Promise.resolve().then(() => source.open(options));\n return new Promise<RangeSourceReader>((resolve, reject) => {\n const cleanup = (): void => {\n signal.removeEventListener(\"abort\", onAbort);\n };\n const onAbort = (): void => {\n if (finished) return;\n finished = true;\n cleanup();\n reject(cancelledError());\n };\n if (signal.aborted) {\n onAbort();\n // Still attach handlers below so a provider that ignores cancellation\n // cannot produce an unhandled rejection.\n } else {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n opening.then(\n (value) => {\n if (finished) {\n void closeRangeReaderBestEffort(value);\n return;\n }\n finished = true;\n cleanup();\n resolve(value);\n },\n (error) => {\n if (finished) return;\n finished = true;\n cleanup();\n reject(error);\n },\n );\n });\n}\n\nfunction copyExactRangeBytes(\n value: ArrayBuffer | ArrayBufferView,\n expectedLength: number,\n): ArrayBuffer {\n const actualLength = value instanceof ArrayBuffer\n ? value.byteLength\n : ArrayBuffer.isView(value)\n ? value.byteLength\n : undefined;\n if (actualLength !== expectedLength) {\n throw new TabularkError(\n \"RUNTIME_FAILURE\",\n \"The source provider returned an invalid byte length\",\n );\n }\n // The broker owns an exact ArrayBuffer returned by the provider and\n // immediately transfers it to the Worker. Reusing that allocation avoids a\n // second main-thread buffer that would temporarily double the staging\n // slice. Exact whole-buffer views can use the same ownership transfer; only\n // offset/shared views need a bounded copy.\n if (value instanceof ArrayBuffer) return value;\n if (\n value.buffer instanceof ArrayBuffer\n && value.byteOffset === 0\n && value.byteLength === value.buffer.byteLength\n ) {\n return value.buffer;\n }\n return copyRangeBytes(value);\n}\n\nfunction combineAbortSignals(first: AbortSignal | undefined, second: AbortSignal): AbortSignal {\n if (first === undefined) return second;\n if (first === second) return first;\n const any = (AbortSignal as typeof AbortSignal & {\n any?: (signals: readonly AbortSignal[]) => AbortSignal;\n }).any;\n if (typeof any === \"function\") return any([first, second]);\n const controller = new AbortController();\n const abort = (): void => controller.abort();\n if (first.aborted || second.aborted) {\n controller.abort();\n } else {\n first.addEventListener(\"abort\", abort, { once: true });\n second.addEventListener(\"abort\", abort, { once: true });\n }\n return controller.signal;\n}\n\nfunction normalizeSourceProviderError(error: unknown): { code: string; retryable: boolean } {\n const structured = rangeSourceErrorLike(error);\n if (structured !== undefined) {\n const code = sourceErrorCode(structured.code);\n return { code, retryable: structured.retryable };\n }\n if (typeof error === \"object\" && error !== null && (error as { name?: unknown }).name === \"AbortError\") {\n return { code: \"CANCELLED\", retryable: false };\n }\n return { code: \"SOURCE_UNAVAILABLE\", retryable: true };\n}\n\nfunction sourceErrorCode(value: unknown): string {\n return value === \"SOURCE_CHANGED\"\n || value === \"RANGE_UNSUPPORTED\"\n || value === \"SOURCE_UNAVAILABLE\"\n || value === \"RESOURCE_LIMIT\"\n || value === \"CANCELLED\"\n || value === \"HANDLE_CLOSED\"\n || value === \"RUNTIME_FAILURE\"\n ? value\n : \"SOURCE_UNAVAILABLE\";\n}\n\nfunction sourceErrorMessage(code: unknown): string {\n switch (sourceErrorCode(code)) {\n case \"SOURCE_CHANGED\": return \"The source changed while it was open\";\n case \"RANGE_UNSUPPORTED\": return \"The source range is unsupported\";\n case \"CANCELLED\": return \"The source read was cancelled\";\n case \"HANDLE_CLOSED\": return \"The source is closed\";\n case \"RUNTIME_FAILURE\": return \"The source provider returned invalid bytes\";\n case \"RESOURCE_LIMIT\": return \"The source exceeds its configured limit\";\n default: return \"The source provider is unavailable\";\n }\n}\n\n/** Creates one dedicated Worker-backed Tabulark engine. */\nexport function createEngine(options: EngineOptions): Promise<TabularkEngine> {\n return Engine.create(options);\n}\n", "import { invalidArgument } from \"../errors.js\";\nimport type {\n CellPosition,\n GridRange,\n NavigationCommand,\n TableSelection,\n} from \"./types.js\";\n\nexport function createSelection(\n anchor: CellPosition,\n focus: CellPosition = anchor,\n): Readonly<TableSelection> {\n assertCellPosition(anchor, \"anchor\");\n assertCellPosition(focus, \"focus\");\n const normalizedAnchor = Object.freeze({ ...anchor });\n const normalizedFocus = Object.freeze({ ...focus });\n return Object.freeze({\n anchor: normalizedAnchor,\n focus: normalizedFocus,\n range: selectionRange(normalizedAnchor, normalizedFocus),\n });\n}\n\nexport function selectionRange(anchor: CellPosition, focus: CellPosition): Readonly<GridRange> {\n return Object.freeze({\n rowStart: Math.min(anchor.rowIndex, focus.rowIndex),\n rowEnd: Math.max(anchor.rowIndex, focus.rowIndex) + 1,\n columnStart: Math.min(anchor.columnIndex, focus.columnIndex),\n columnEnd: Math.max(anchor.columnIndex, focus.columnIndex) + 1,\n });\n}\n\nexport function containsCell(range: GridRange, cell: CellPosition): boolean {\n return cell.rowIndex >= range.rowStart\n && cell.rowIndex < range.rowEnd\n && cell.columnIndex >= range.columnStart\n && cell.columnIndex < range.columnEnd;\n}\n\nexport function clampCell(\n cell: CellPosition,\n rowCount: number,\n columnCount: number,\n): Readonly<CellPosition> | null {\n if (rowCount <= 0 || columnCount <= 0) {\n return null;\n }\n return Object.freeze({\n rowIndex: clampInteger(cell.rowIndex, 0, rowCount - 1),\n columnIndex: clampInteger(cell.columnIndex, 0, columnCount - 1),\n });\n}\n\nexport function moveCell(\n cell: CellPosition,\n command: NavigationCommand,\n rowCount: number,\n columnCount: number,\n pageRowCount: number,\n): Readonly<CellPosition> | null {\n const current = clampCell(cell, rowCount, columnCount);\n if (current === null) {\n return null;\n }\n const page = Math.max(1, Math.floor(pageRowCount));\n switch (command) {\n case \"left\":\n return clampCell({ rowIndex: current.rowIndex, columnIndex: current.columnIndex - 1 }, rowCount, columnCount);\n case \"right\":\n return clampCell({ rowIndex: current.rowIndex, columnIndex: current.columnIndex + 1 }, rowCount, columnCount);\n case \"up\":\n return clampCell({ rowIndex: current.rowIndex - 1, columnIndex: current.columnIndex }, rowCount, columnCount);\n case \"down\":\n return clampCell({ rowIndex: current.rowIndex + 1, columnIndex: current.columnIndex }, rowCount, columnCount);\n case \"page-up\":\n return clampCell({ rowIndex: current.rowIndex - page, columnIndex: current.columnIndex }, rowCount, columnCount);\n case \"page-down\":\n return clampCell({ rowIndex: current.rowIndex + page, columnIndex: current.columnIndex }, rowCount, columnCount);\n case \"row-start\":\n return Object.freeze({ rowIndex: current.rowIndex, columnIndex: 0 });\n case \"row-end\":\n return Object.freeze({ rowIndex: current.rowIndex, columnIndex: columnCount - 1 });\n case \"table-start\":\n return Object.freeze({ rowIndex: 0, columnIndex: 0 });\n case \"table-end\":\n return Object.freeze({ rowIndex: rowCount - 1, columnIndex: columnCount - 1 });\n }\n}\n\nexport function assertCellPosition(value: CellPosition, name: string): void {\n if (!Number.isSafeInteger(value.rowIndex) || value.rowIndex < 0) {\n throw invalidArgument(`${name}.rowIndex must be a non-negative safe integer`);\n }\n if (!Number.isSafeInteger(value.columnIndex) || value.columnIndex < 0) {\n throw invalidArgument(`${name}.columnIndex must be a non-negative safe integer`);\n }\n}\n\nfunction clampInteger(value: number, minimum: number, maximum: number): number {\n if (!Number.isFinite(value)) {\n return minimum;\n }\n return Math.min(maximum, Math.max(minimum, Math.trunc(value)));\n}\n", "export interface AccessibleGridColumn {\n readonly index: number;\n readonly name: string;\n}\n\nexport interface AccessibleGridCell {\n readonly rowIndex: number;\n readonly columnIndex: number;\n readonly value: string | null | undefined;\n readonly selected: boolean;\n readonly active: boolean;\n readonly rowSpan?: number;\n readonly columnSpan?: number;\n}\n\nexport interface AccessibleGridRow {\n readonly index: number;\n readonly cells: readonly AccessibleGridCell[];\n}\n\nexport interface AccessibleGridSnapshot {\n readonly label: string;\n readonly exactRowCount?: number;\n readonly columnCount: number;\n readonly columns: readonly AccessibleGridColumn[];\n readonly rows: readonly AccessibleGridRow[];\n readonly busy: boolean;\n readonly status?: string;\n}\n\nlet nextGridId = 1;\n\n/** A viewport-bounded semantic counterpart to the visual Canvas table. */\nexport class AccessibleViewportGrid {\n readonly element: HTMLDivElement;\n readonly statusElement: HTMLDivElement;\n\n readonly #idPrefix: string;\n #destroyed = false;\n\n constructor(ownerDocument: Document, label = \"Data table\") {\n this.#idPrefix = `tabulark-grid-${nextGridId}`;\n nextGridId += 1;\n\n this.element = ownerDocument.createElement(\"div\");\n this.element.className = \"tabulark-a11y-grid\";\n this.element.dataset.tabularkA11yGrid = \"\";\n this.element.id = this.#idPrefix;\n this.element.setAttribute(\"role\", \"grid\");\n this.element.setAttribute(\"aria-label\", label);\n this.element.tabIndex = 0;\n visuallyHide(this.element);\n\n this.statusElement = ownerDocument.createElement(\"div\");\n this.statusElement.className = \"tabulark-status\";\n this.statusElement.dataset.tabularkStatus = \"\";\n this.statusElement.setAttribute(\"role\", \"status\");\n this.statusElement.setAttribute(\"aria-live\", \"polite\");\n this.statusElement.setAttribute(\"aria-atomic\", \"true\");\n visuallyHide(this.statusElement);\n }\n\n update(snapshot: AccessibleGridSnapshot): void {\n if (this.#destroyed) {\n return;\n }\n\n this.element.setAttribute(\"aria-label\", snapshot.label);\n this.element.setAttribute(\"aria-colcount\", String(snapshot.columnCount));\n setOptionalAttribute(\n this.element,\n \"aria-rowcount\",\n snapshot.exactRowCount === undefined ? undefined : String(snapshot.exactRowCount + 1),\n );\n this.element.setAttribute(\"aria-busy\", String(snapshot.busy));\n\n const fragment = this.element.ownerDocument.createDocumentFragment();\n fragment.append(this.#createHeader(snapshot.columns));\n\n let activeId: string | undefined;\n for (const row of snapshot.rows) {\n const rowElement = this.element.ownerDocument.createElement(\"div\");\n rowElement.setAttribute(\"role\", \"row\");\n // ARIA row indices are one-based; index 1 belongs to the header row.\n rowElement.setAttribute(\"aria-rowindex\", String(row.index + 2));\n\n for (const cell of row.cells) {\n const cellElement = this.element.ownerDocument.createElement(\"div\");\n cellElement.setAttribute(\"role\", \"gridcell\");\n cellElement.setAttribute(\"aria-colindex\", String(cell.columnIndex + 1));\n cellElement.setAttribute(\"aria-selected\", String(cell.selected));\n setOptionalAttribute(\n cellElement,\n \"aria-rowspan\",\n cell.rowSpan === undefined || cell.rowSpan <= 1 ? undefined : String(cell.rowSpan),\n );\n setOptionalAttribute(\n cellElement,\n \"aria-colspan\",\n cell.columnSpan === undefined || cell.columnSpan <= 1 ? undefined : String(cell.columnSpan),\n );\n cellElement.textContent = cell.value === undefined\n ? \"Loading\"\n : cell.value === null\n ? \"Empty\"\n : cell.value;\n if (cell.active) {\n activeId = this.#cellId(cell.rowIndex, cell.columnIndex);\n cellElement.id = activeId;\n }\n rowElement.append(cellElement);\n }\n fragment.append(rowElement);\n }\n\n this.element.replaceChildren(fragment);\n setOptionalAttribute(this.element, \"aria-activedescendant\", activeId);\n if (snapshot.status !== undefined && snapshot.status !== this.statusElement.textContent) {\n this.statusElement.textContent = snapshot.status;\n }\n }\n\n focus(options?: FocusOptions): void {\n this.element.focus(options);\n }\n\n destroy(): void {\n if (this.#destroyed) {\n return;\n }\n this.#destroyed = true;\n this.element.remove();\n this.statusElement.remove();\n }\n\n #createHeader(columns: readonly AccessibleGridColumn[]): HTMLDivElement {\n const row = this.element.ownerDocument.createElement(\"div\");\n row.setAttribute(\"role\", \"row\");\n row.setAttribute(\"aria-rowindex\", \"1\");\n for (const column of columns) {\n const cell = this.element.ownerDocument.createElement(\"div\");\n cell.setAttribute(\"role\", \"columnheader\");\n cell.setAttribute(\"aria-colindex\", String(column.index + 1));\n cell.textContent = column.name;\n row.append(cell);\n }\n return row;\n }\n\n #cellId(rowIndex: number, columnIndex: number): string {\n return `${this.#idPrefix}-r${rowIndex}-c${columnIndex}`;\n }\n}\n\nfunction visuallyHide(element: HTMLElement): void {\n Object.assign(element.style, {\n border: \"0\",\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"-1px\",\n overflow: \"hidden\",\n padding: \"0\",\n pointerEvents: \"none\",\n position: \"absolute\",\n whiteSpace: \"nowrap\",\n width: \"1px\",\n });\n}\n\nfunction setOptionalAttribute(\n element: Element,\n name: string,\n value: string | undefined,\n): void {\n if (value === undefined) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value);\n }\n}\n", "import type {\n MergedCellRegion,\n PresentationBorderSide,\n PresentationStyle,\n} from \"../model.js\";\n\nexport interface CanvasPaintColumn {\n readonly index: number;\n readonly name: string;\n /** Viewport-relative x coordinate, including the pinned row gutter offset. */\n readonly x: number;\n readonly width: number;\n readonly frozen?: boolean;\n}\n\nexport interface CanvasPaintCell {\n readonly columnIndex: number;\n readonly value: string | null | undefined;\n readonly style?: PresentationStyle;\n /** The cell is painted by its merge anchor rather than its own grid slot. */\n readonly coveredByMerge?: boolean;\n}\n\nexport interface CanvasPaintRow {\n readonly index: number;\n /** Viewport-relative y coordinate, including the pinned header offset. */\n readonly y: number;\n readonly height: number;\n readonly frozen?: boolean;\n readonly cells: readonly CanvasPaintCell[];\n}\n\nexport interface CanvasPaintMergedCell {\n readonly region: Readonly<MergedCellRegion>;\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n readonly value: string | null | undefined;\n readonly style?: PresentationStyle;\n /** A pane-clipped continuation; only the anchor fragment paints the value. */\n readonly continuation?: boolean;\n}\n\nexport interface CanvasPaintSelection {\n readonly rowStart: number;\n /** Exclusive table row bound. */\n readonly rowEnd: number;\n readonly columnStart: number;\n /** Exclusive table column bound. */\n readonly columnEnd: number;\n}\n\nexport interface CanvasPaintActiveCell {\n readonly rowIndex: number;\n readonly columnIndex: number;\n}\n\nexport interface CanvasPaintSnapshot {\n readonly width: number;\n readonly height: number;\n readonly headerHeight: number;\n readonly rowGutterWidth: number;\n readonly columns: readonly CanvasPaintColumn[];\n readonly rows: readonly CanvasPaintRow[];\n readonly mergedCells?: readonly CanvasPaintMergedCell[];\n readonly selection?: CanvasPaintSelection;\n readonly activeCell?: CanvasPaintActiveCell;\n readonly busy: boolean;\n}\n\nexport interface CanvasTableTheme {\n readonly background: string;\n readonly foreground: string;\n readonly mutedForeground: string;\n readonly headerBackground: string;\n readonly headerForeground: string;\n readonly alternateRowBackground: string;\n readonly gridLine: string;\n readonly selectionBackground: string;\n readonly selectionBorder: string;\n readonly activeCellBorder: string;\n readonly loadingBackground: string;\n readonly font: string;\n readonly headerFont: string;\n}\n\nexport const DEFAULT_CANVAS_TABLE_THEME: Readonly<CanvasTableTheme> = Object.freeze({\n background: \"#ffffff\",\n foreground: \"#172033\",\n mutedForeground: \"#667085\",\n headerBackground: \"#f2f4f7\",\n headerForeground: \"#344054\",\n alternateRowBackground: \"#f9fafb\",\n gridLine: \"#d0d5dd\",\n selectionBackground: \"rgba(21, 112, 239, 0.14)\",\n selectionBorder: \"#1570ef\",\n activeCellBorder: \"#175cd3\",\n loadingBackground: \"#e4e7ec\",\n font: '13px ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n headerFont: '600 13px ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n});\n\n/** Resolves author-independent system colors for Windows High Contrast and other forced palettes. */\nexport function forcedColorsCanvasTableTheme(\n base: Readonly<CanvasTableTheme> = DEFAULT_CANVAS_TABLE_THEME,\n): Readonly<CanvasTableTheme> {\n return Object.freeze({\n ...base,\n background: \"Canvas\",\n foreground: \"CanvasText\",\n mutedForeground: \"GrayText\",\n headerBackground: \"Canvas\",\n headerForeground: \"CanvasText\",\n alternateRowBackground: \"Canvas\",\n gridLine: \"CanvasText\",\n selectionBackground: \"Highlight\",\n selectionBorder: \"Highlight\",\n activeCellBorder: \"CanvasText\",\n loadingBackground: \"GrayText\",\n });\n}\n\n/** Paints one viewport frame and keeps the backing store device-pixel aware. */\nexport class CanvasTablePainter {\n readonly canvas: HTMLCanvasElement;\n readonly #context: CanvasRenderingContext2D;\n #theme: Readonly<CanvasTableTheme>;\n readonly #maxDevicePixelRatio: number;\n #forcedColors: boolean;\n\n #cssWidth = 0;\n #cssHeight = 0;\n #devicePixelRatio = 1;\n\n constructor(\n canvas: HTMLCanvasElement,\n options: {\n readonly theme?: Partial<CanvasTableTheme>;\n readonly maxDevicePixelRatio?: number;\n readonly forcedColors?: boolean;\n } = {},\n ) {\n const context = canvas.getContext(\"2d\", { alpha: false });\n if (context === null) {\n throw new Error(\"Tabulark Canvas rendering requires a 2D rendering context\");\n }\n this.canvas = canvas;\n this.#context = context;\n this.#theme = Object.freeze({ ...DEFAULT_CANVAS_TABLE_THEME, ...options.theme });\n this.#maxDevicePixelRatio = positive(options.maxDevicePixelRatio, Number.POSITIVE_INFINITY);\n this.#forcedColors = options.forcedColors ?? false;\n }\n\n setTheme(theme: Readonly<CanvasTableTheme>, options: { readonly forcedColors?: boolean } = {}): void {\n this.#theme = Object.freeze({ ...theme });\n this.#forcedColors = options.forcedColors ?? false;\n }\n\n paint(snapshot: CanvasPaintSnapshot): void {\n this.#resize(snapshot.width, snapshot.height);\n const context = this.#context;\n const theme = this.#theme;\n\n context.save();\n context.setTransform(\n this.#devicePixelRatio,\n 0,\n 0,\n this.#devicePixelRatio,\n 0,\n 0,\n );\n context.clearRect(0, 0, snapshot.width, snapshot.height);\n context.fillStyle = theme.background;\n context.fillRect(0, 0, snapshot.width, snapshot.height);\n\n this.#paintRows(snapshot);\n this.#paintHeader(snapshot);\n this.#paintGrid(snapshot);\n this.#paintMergedCells(snapshot);\n this.#paintSelection(snapshot);\n context.restore();\n }\n\n #resize(width: number, height: number): void {\n const view = this.canvas.ownerDocument.defaultView;\n const browserRatio = view?.devicePixelRatio ?? 1;\n const ratio = Math.max(1, Math.min(browserRatio, this.#maxDevicePixelRatio));\n const cssWidth = Math.max(0, Math.floor(width));\n const cssHeight = Math.max(0, Math.floor(height));\n const pixelWidth = Math.max(1, Math.round(cssWidth * ratio));\n const pixelHeight = Math.max(1, Math.round(cssHeight * ratio));\n\n if (\n cssWidth === this.#cssWidth &&\n cssHeight === this.#cssHeight &&\n ratio === this.#devicePixelRatio &&\n this.canvas.width === pixelWidth &&\n this.canvas.height === pixelHeight\n ) {\n return;\n }\n\n this.#cssWidth = cssWidth;\n this.#cssHeight = cssHeight;\n this.#devicePixelRatio = ratio;\n this.canvas.width = pixelWidth;\n this.canvas.height = pixelHeight;\n this.canvas.style.width = `${cssWidth}px`;\n this.canvas.style.height = `${cssHeight}px`;\n }\n\n #paintRows(snapshot: CanvasPaintSnapshot): void {\n const context = this.#context;\n const theme = this.#theme;\n const columnsByIndex = new Map(snapshot.columns.map((column) => [column.index, column]));\n context.font = theme.font;\n context.textBaseline = \"middle\";\n\n const rows = [\n ...snapshot.rows.filter((row) => row.frozen !== true),\n ...snapshot.rows.filter((row) => row.frozen === true),\n ];\n for (const row of rows) {\n if (row.y + row.height <= snapshot.headerHeight || row.y >= snapshot.height) {\n continue;\n }\n context.fillStyle = row.index % 2 === 0 ? theme.background : theme.alternateRowBackground;\n context.fillRect(0, row.y, snapshot.width, row.height);\n\n context.fillStyle = theme.mutedForeground;\n context.textAlign = \"right\";\n context.fillText(\n String(row.index + 1),\n snapshot.rowGutterWidth - 10,\n row.y + row.height / 2,\n );\n\n const cells = [\n ...row.cells.filter((cell) => columnsByIndex.get(cell.columnIndex)?.frozen !== true),\n ...row.cells.filter((cell) => columnsByIndex.get(cell.columnIndex)?.frozen === true),\n ];\n for (const cell of cells) {\n const column = columnsByIndex.get(cell.columnIndex);\n if (\n column === undefined\n || column.x + column.width <= snapshot.rowGutterWidth\n || cell.coveredByMerge === true\n ) {\n continue;\n }\n this.#paintCellValue(\n cell.value,\n column.x,\n row.y,\n column.width,\n row.height,\n cell.style,\n );\n }\n }\n }\n\n #paintCellValue(\n value: string | null | undefined,\n x: number,\n y: number,\n width: number,\n height: number,\n style?: PresentationStyle,\n ): void {\n const context = this.#context;\n const theme = this.#theme;\n const horizontalPadding = 10;\n if (width <= horizontalPadding * 2) {\n return;\n }\n\n context.save();\n context.beginPath();\n context.rect(x + 1, y + 1, Math.max(0, width - 2), Math.max(0, height - 2));\n context.clip();\n this.#paintCellFill(x, y, width, height, style);\n this.#applyCellFont(style);\n context.textAlign = horizontalAlignment(style);\n context.textBaseline = verticalBaseline(style);\n if (value === undefined) {\n context.fillStyle = theme.loadingBackground;\n const skeletonWidth = Math.max(12, Math.min(width - horizontalPadding * 2, width * 0.42));\n context.fillRect(x + horizontalPadding, y + height / 2 - 3, skeletonWidth, 6);\n } else {\n context.fillStyle = value === null\n ? theme.mutedForeground\n : this.#cellForeground(style, theme.foreground);\n const label = value === null ? \"\u2205\" : value;\n const textX = horizontalTextX(context.textAlign, x, width, horizontalPadding);\n const textY = verticalTextY(context.textBaseline, y, height, 4);\n context.fillText(label, textX, textY, Math.max(0, width - horizontalPadding * 2));\n if (style?.font?.underline === true) {\n const measured = Math.min(context.measureText(label).width, width - horizontalPadding * 2);\n const start = underlineStart(context.textAlign, textX, measured);\n context.strokeStyle = String(context.fillStyle);\n context.lineWidth = 1;\n context.beginPath();\n context.moveTo(start, Math.min(y + height - 4, textY + 3));\n context.lineTo(start + measured, Math.min(y + height - 4, textY + 3));\n context.stroke();\n }\n }\n this.#paintCellBorders(x, y, width, height, style);\n context.restore();\n }\n\n #paintMergedCells(snapshot: CanvasPaintSnapshot): void {\n for (const merged of snapshot.mergedCells ?? []) {\n if (\n merged.width <= 0\n || merged.height <= 0\n || merged.x + merged.width <= snapshot.rowGutterWidth\n || merged.y + merged.height <= snapshot.headerHeight\n || merged.x >= snapshot.width\n || merged.y >= snapshot.height\n ) {\n continue;\n }\n this.#context.fillStyle = merged.region.rowStart % 2 === 0\n ? this.#theme.background\n : this.#theme.alternateRowBackground;\n this.#context.fillRect(merged.x, merged.y, merged.width, merged.height);\n if (merged.continuation === true) {\n this.#paintCellFill(merged.x, merged.y, merged.width, merged.height, merged.style);\n this.#paintCellBorders(merged.x, merged.y, merged.width, merged.height, merged.style);\n } else {\n this.#paintCellValue(\n merged.value,\n merged.x,\n merged.y,\n merged.width,\n merged.height,\n merged.style,\n );\n }\n this.#context.strokeStyle = this.#theme.gridLine;\n this.#context.lineWidth = 1 / this.#devicePixelRatio;\n this.#context.strokeRect(\n merged.x + 0.5 / this.#devicePixelRatio,\n merged.y + 0.5 / this.#devicePixelRatio,\n Math.max(0, merged.width - 1 / this.#devicePixelRatio),\n Math.max(0, merged.height - 1 / this.#devicePixelRatio),\n );\n }\n }\n\n #paintCellFill(\n x: number,\n y: number,\n width: number,\n height: number,\n style: PresentationStyle | undefined,\n ): void {\n if (this.#forcedColors || style === undefined) return;\n const color = cssColor(style.fillColor ?? style.backgroundColor);\n if (color === undefined) return;\n this.#context.fillStyle = color;\n this.#context.fillRect(x + 1, y + 1, Math.max(0, width - 2), Math.max(0, height - 2));\n }\n\n #applyCellFont(style: PresentationStyle | undefined): void {\n if (style?.font === undefined) {\n this.#context.font = this.#theme.font;\n return;\n }\n const font = style.font;\n const size = finitePositive(font.size) ?? 13;\n const family = font.family && font.family.trim().length > 0\n ? font.family\n : 'ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif';\n this.#context.font = `${font.italic === true ? \"italic \" : \"\"}${font.bold === true ? \"700 \" : \"400 \"}${size}px ${family}`;\n }\n\n #cellForeground(style: PresentationStyle | undefined, fallback: string): string {\n if (this.#forcedColors) return fallback;\n return cssColor(style?.font?.color)\n ?? cssColor(style?.foregroundColor)\n ?? fallback;\n }\n\n #paintCellBorders(\n x: number,\n y: number,\n width: number,\n height: number,\n style: PresentationStyle | undefined,\n ): void {\n if (style?.borders === undefined) return;\n const context = this.#context;\n const sides = style.borders;\n const paint = (\n side: \"top\" | \"right\" | \"bottom\" | \"left\",\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n ) => {\n const border = sides[side];\n if (border === undefined || border.style === \"none\") return;\n context.save();\n const widthForStyle = borderWidth(border.style);\n context.lineWidth = widthForStyle;\n context.strokeStyle = this.#forcedColors\n ? this.#theme.gridLine\n : cssColor(border.color) ?? this.#theme.gridLine;\n context.setLineDash(borderDash(border.style));\n context.beginPath();\n context.moveTo(startX, startY);\n context.lineTo(endX, endY);\n context.stroke();\n if (border.style === \"double\") {\n const offset = Math.max(2, widthForStyle + 1);\n const horizontal = startY === endY;\n context.beginPath();\n context.moveTo(horizontal ? startX : startX + offset, horizontal ? startY + offset : startY);\n context.lineTo(horizontal ? endX : endX + offset, horizontal ? endY + offset : endY);\n context.stroke();\n }\n context.restore();\n };\n paint(\"top\", x + 0.5, y + 0.5, x + width - 0.5, y + 0.5);\n paint(\"right\", x + width - 0.5, y + 0.5, x + width - 0.5, y + height - 0.5);\n paint(\"bottom\", x + 0.5, y + height - 0.5, x + width - 0.5, y + height - 0.5);\n paint(\"left\", x + 0.5, y + 0.5, x + 0.5, y + height - 0.5);\n }\n\n #paintHeader(snapshot: CanvasPaintSnapshot): void {\n const context = this.#context;\n const theme = this.#theme;\n context.fillStyle = theme.headerBackground;\n context.fillRect(0, 0, snapshot.width, snapshot.headerHeight);\n context.font = theme.headerFont;\n context.fillStyle = theme.headerForeground;\n context.textBaseline = \"middle\";\n context.textAlign = \"left\";\n\n const columns = [\n ...snapshot.columns.filter((column) => column.frozen !== true),\n ...snapshot.columns.filter((column) => column.frozen === true),\n ];\n for (const column of columns) {\n if (column.x + column.width <= snapshot.rowGutterWidth || column.x >= snapshot.width) {\n continue;\n }\n context.save();\n context.beginPath();\n context.rect(column.x + 1, 0, Math.max(0, column.width - 2), snapshot.headerHeight);\n context.clip();\n context.fillText(column.name, column.x + 10, snapshot.headerHeight / 2);\n context.restore();\n }\n\n context.textAlign = \"center\";\n context.fillText(\n \"#\",\n snapshot.rowGutterWidth / 2,\n snapshot.headerHeight / 2,\n snapshot.rowGutterWidth,\n );\n }\n\n #paintGrid(snapshot: CanvasPaintSnapshot): void {\n const context = this.#context;\n const theme = this.#theme;\n context.strokeStyle = theme.gridLine;\n context.lineWidth = 1 / this.#devicePixelRatio;\n context.beginPath();\n\n const snap = 0.5 / this.#devicePixelRatio;\n context.moveTo(snapshot.rowGutterWidth + snap, 0);\n context.lineTo(snapshot.rowGutterWidth + snap, snapshot.height);\n context.moveTo(0, snapshot.headerHeight + snap);\n context.lineTo(snapshot.width, snapshot.headerHeight + snap);\n\n for (const column of snapshot.columns) {\n const x = column.x + column.width + snap;\n if (x > snapshot.rowGutterWidth && x < snapshot.width) {\n context.moveTo(x, 0);\n context.lineTo(x, snapshot.height);\n }\n }\n for (const row of snapshot.rows) {\n const y = row.y + row.height + snap;\n if (y > snapshot.headerHeight && y < snapshot.height) {\n context.moveTo(0, y);\n context.lineTo(snapshot.width, y);\n }\n }\n context.stroke();\n }\n\n #paintSelection(snapshot: CanvasPaintSnapshot): void {\n const selection = snapshot.selection;\n const context = this.#context;\n const theme = this.#theme;\n if (selection !== undefined) {\n const selectedColumns = snapshot.columns.filter(\n (column) => column.index >= selection.columnStart && column.index < selection.columnEnd,\n );\n const selectedRows = snapshot.rows.filter(\n (row) => row.index >= selection.rowStart && row.index < selection.rowEnd,\n );\n if (selectedColumns.length > 0 && selectedRows.length > 0) {\n const firstColumn = selectedColumns[0]!;\n const lastColumn = selectedColumns.at(-1)!;\n const firstRow = selectedRows[0]!;\n const lastRow = selectedRows.at(-1)!;\n const x = Math.max(snapshot.rowGutterWidth, firstColumn.x);\n const y = Math.max(snapshot.headerHeight, firstRow.y);\n const right = Math.min(snapshot.width, lastColumn.x + lastColumn.width);\n const bottom = Math.min(snapshot.height, lastRow.y + lastRow.height);\n if (right > x && bottom > y) {\n context.save();\n context.fillStyle = theme.selectionBackground;\n if (this.#forcedColors) {\n context.globalAlpha = 0.28;\n }\n context.fillRect(x, y, right - x, bottom - y);\n context.restore();\n context.strokeStyle = theme.selectionBorder;\n context.lineWidth = this.#forcedColors ? 2 : 1;\n context.setLineDash(this.#forcedColors ? [4, 2] : []);\n context.strokeRect(\n x + context.lineWidth / 2,\n y + context.lineWidth / 2,\n Math.max(0, right - x - context.lineWidth),\n Math.max(0, bottom - y - context.lineWidth),\n );\n context.setLineDash([]);\n }\n }\n }\n\n const activeMerges = snapshot.activeCell === undefined\n ? []\n : snapshot.mergedCells?.filter((merged) => (\n snapshot.activeCell!.rowIndex >= merged.region.rowStart\n && snapshot.activeCell!.rowIndex < merged.region.rowEnd\n && snapshot.activeCell!.columnIndex >= merged.region.columnStart\n && snapshot.activeCell!.columnIndex < merged.region.columnEnd\n )) ?? [];\n const activeColumn = snapshot.activeCell === undefined\n ? undefined\n : snapshot.columns.find((column) => column.index === snapshot.activeCell!.columnIndex);\n const activeRow = snapshot.activeCell === undefined\n ? undefined\n : snapshot.rows.find((row) => row.index === snapshot.activeCell!.rowIndex);\n const activeRects = activeMerges.length > 0\n ? activeMerges\n : activeColumn !== undefined && activeRow !== undefined\n ? [{\n x: activeColumn.x,\n y: activeRow.y,\n width: activeColumn.width,\n height: activeRow.height,\n }]\n : [];\n for (const activeRect of activeRects) {\n const activeX = Math.max(snapshot.rowGutterWidth, activeRect.x);\n const activeY = Math.max(snapshot.headerHeight, activeRect.y);\n const activeRight = Math.min(snapshot.width, activeRect.x + activeRect.width);\n const activeBottom = Math.min(snapshot.height, activeRect.y + activeRect.height);\n context.strokeStyle = theme.activeCellBorder;\n context.lineWidth = this.#forcedColors ? 3 : 2;\n context.setLineDash([]);\n context.strokeRect(\n activeX + context.lineWidth / 2,\n activeY + context.lineWidth / 2,\n Math.max(0, activeRight - activeX - context.lineWidth),\n Math.max(0, activeBottom - activeY - context.lineWidth),\n );\n }\n }\n}\n\nfunction cssColor(color: { readonly css?: string } | undefined): string | undefined {\n const value = color?.css?.trim();\n if (!value) return undefined;\n const supports = globalThis.CSS?.supports;\n return typeof supports !== \"function\" || supports(\"color\", value) ? value : undefined;\n}\n\nfunction finitePositive(value: number | undefined): number | undefined {\n return value !== undefined && Number.isFinite(value) && value > 0 ? value : undefined;\n}\n\nfunction horizontalAlignment(style: PresentationStyle | undefined): CanvasTextAlign {\n switch (style?.horizontalAlignment) {\n case \"center\":\n return \"center\";\n case \"right\":\n return \"right\";\n case \"left\":\n case \"justify\":\n case \"general\":\n default:\n return \"left\";\n }\n}\n\nfunction verticalBaseline(style: PresentationStyle | undefined): CanvasTextBaseline {\n switch (style?.verticalAlignment) {\n case \"top\":\n return \"top\";\n case \"bottom\":\n return \"bottom\";\n case \"center\":\n case \"justify\":\n default:\n return \"middle\";\n }\n}\n\nfunction horizontalTextX(\n alignment: CanvasTextAlign,\n x: number,\n width: number,\n padding: number,\n): number {\n if (alignment === \"center\") return x + width / 2;\n if (alignment === \"right\" || alignment === \"end\") return x + width - padding;\n return x + padding;\n}\n\nfunction verticalTextY(\n baseline: CanvasTextBaseline,\n y: number,\n height: number,\n padding: number,\n): number {\n if (baseline === \"top\" || baseline === \"hanging\") return y + padding;\n if (baseline === \"bottom\" || baseline === \"ideographic\") return y + height - padding;\n return y + height / 2;\n}\n\nfunction underlineStart(alignment: CanvasTextAlign, textX: number, width: number): number {\n if (alignment === \"center\") return textX - width / 2;\n if (alignment === \"right\" || alignment === \"end\") return textX - width;\n return textX;\n}\n\nfunction borderWidth(style: PresentationBorderSide[\"style\"]): number {\n switch (style) {\n case \"medium\":\n return 2;\n case \"thick\":\n return 3;\n case \"double\":\n return 1;\n default:\n return 1;\n }\n}\n\nfunction borderDash(style: string | undefined): readonly number[] {\n if (style === \"dashed\") return [4, 2];\n if (style === \"dotted\") return [1, 2];\n return [];\n}\n\nfunction positive(value: number | undefined, fallback: number): number {\n return value !== undefined && Number.isFinite(value) && value > 0 ? value : fallback;\n}\n", "import { invalidArgument } from \"../errors.js\";\nimport type { PresentationAxisEntry, TableMetadata } from \"../model.js\";\nimport {\n DEFAULT_COLUMN_WIDTH,\n DEFAULT_HEADER_HEIGHT,\n DEFAULT_OVERSCAN_COLUMNS,\n DEFAULT_OVERSCAN_ROWS,\n DEFAULT_ROW_HEADER_WIDTH,\n DEFAULT_ROW_HEIGHT,\n DEFAULT_SCROLL_PIXEL_LIMIT,\n type GridRange,\n type HitTestResult,\n type IndexRange,\n type PixelRect,\n type ScrollAxisLayout,\n type SparseAxisGeometry,\n type TableLayout,\n type ViewportUpdate,\n type VisibleColumn,\n type VisibleRow,\n} from \"./types.js\";\n\nexport interface LayoutOptions {\n readonly rowHeight?: number;\n readonly headerHeight?: number;\n readonly rowHeaderWidth?: number;\n readonly scrollPixelLimit?: number;\n readonly overscanRows?: number;\n readonly overscanColumns?: number;\n readonly rowEntries?: readonly PresentationAxisEntry[];\n readonly hiddenColumns?: readonly boolean[];\n readonly frozenRows?: number;\n readonly frozenColumns?: number;\n}\n\nexport function createTableLayout(\n metadata: Readonly<TableMetadata>,\n columnWidths: readonly number[],\n viewport: ViewportUpdate,\n options: LayoutOptions = {},\n): Readonly<TableLayout> {\n const rowHeight = positiveFinite(options.rowHeight ?? DEFAULT_ROW_HEIGHT, \"rowHeight\");\n const headerHeight = nonNegativeFinite(\n options.headerHeight ?? DEFAULT_HEADER_HEIGHT,\n \"headerHeight\",\n );\n const rowHeaderWidth = nonNegativeFinite(\n options.rowHeaderWidth ?? DEFAULT_ROW_HEADER_WIDTH,\n \"rowHeaderWidth\",\n );\n const scrollPixelLimit = positiveFinite(\n options.scrollPixelLimit ?? DEFAULT_SCROLL_PIXEL_LIMIT,\n \"scrollPixelLimit\",\n );\n const overscanRows = nonNegativeInteger(\n options.overscanRows ?? DEFAULT_OVERSCAN_ROWS,\n \"overscanRows\",\n );\n const overscanColumns = nonNegativeInteger(\n options.overscanColumns ?? DEFAULT_OVERSCAN_COLUMNS,\n \"overscanColumns\",\n );\n const width = nonNegativeFinite(viewport.width, \"viewport.width\");\n const height = nonNegativeFinite(viewport.height, \"viewport.height\");\n const devicePixelRatio = positiveFinite(\n viewport.devicePixelRatio ?? 1,\n \"viewport.devicePixelRatio\",\n );\n const columnCount = metadata.schema.columns.length;\n if (columnWidths.length !== columnCount) {\n throw invalidArgument(\n `columnWidths has ${columnWidths.length} entries; expected ${columnCount}`,\n );\n }\n for (let index = 0; index < columnWidths.length; index += 1) {\n positiveFinite(columnWidths[index]!, `columnWidths[${index}]`);\n }\n const hiddenColumns = options.hiddenColumns ?? [];\n if (hiddenColumns.length !== 0 && hiddenColumns.length !== columnCount) {\n throw invalidArgument(\n `hiddenColumns has ${hiddenColumns.length} entries; expected ${columnCount}`,\n );\n }\n const effectiveColumnWidths = Object.freeze(columnWidths.map(\n (width, index) => hiddenColumns[index] === true ? 0 : width,\n ));\n\n const rowCount = extentValue(metadata.extent.rows);\n const frozenRowCount = Math.min(\n rowCount,\n nonNegativeInteger(options.frozenRows ?? 0, \"frozenRows\"),\n );\n const frozenColumnCount = Math.min(\n columnCount,\n nonNegativeInteger(options.frozenColumns ?? 0, \"frozenColumns\"),\n );\n const bodyWidth = Math.max(0, width - rowHeaderWidth);\n const bodyHeight = Math.max(0, height - headerHeight);\n const prefixes = columnOffsets(effectiveColumnWidths);\n const rowGeometry = createSparseAxisGeometry(\n rowCount,\n rowHeight,\n options.rowEntries ?? [],\n );\n const logicalWidth = prefixes[prefixes.length - 1] ?? 0;\n const logicalHeight = rowGeometry.contentSize;\n const horizontal = createScrollAxis(\n logicalWidth,\n bodyWidth,\n viewport.scrollLeft,\n scrollPixelLimit,\n );\n const vertical = createScrollAxis(\n logicalHeight,\n bodyHeight,\n viewport.scrollTop,\n scrollPixelLimit,\n );\n const visibleRows = visibleRowRange(\n rowGeometry,\n vertical.logicalOffset,\n bodyHeight,\n );\n const visibleColumns = visibleColumnRange(\n prefixes,\n horizontal.logicalOffset,\n bodyWidth,\n );\n const overscanRowRange = expandRange(visibleRows, overscanRows, rowCount);\n const overscanColumnRange = expandRange(visibleColumns, overscanColumns, columnCount);\n const frozenRowExtent = axisPosition(rowGeometry, frozenRowCount);\n const frozenColumnExtent = prefixes[frozenColumnCount] ?? 0;\n const frozenRowRange = frozenRowCount === 0\n ? Object.freeze({ start: 0, end: 0 })\n : clampRangeEnd(\n visibleRowRange(rowGeometry, 0, Math.min(bodyHeight, frozenRowExtent)),\n frozenRowCount,\n );\n const frozenColumnRange = frozenColumnCount === 0\n ? Object.freeze({ start: 0, end: 0 })\n : clampRangeEnd(\n visibleColumnRange(prefixes, 0, Math.min(bodyWidth, frozenColumnExtent)),\n frozenColumnCount,\n );\n\n return Object.freeze({\n width,\n height,\n devicePixelRatio,\n rowHeight,\n headerHeight,\n rowHeaderWidth,\n bodyWidth,\n bodyHeight,\n rowCount,\n columnCount,\n rows: Object.freeze({ visible: visibleRows, overscan: overscanRowRange }),\n columns: Object.freeze({ visible: visibleColumns, overscan: overscanColumnRange }),\n visibleColumns: materializeColumns(\n metadata,\n effectiveColumnWidths,\n prefixes,\n visibleColumns,\n frozenColumnRange,\n rowHeaderWidth,\n horizontal.logicalOffset,\n frozenColumnCount,\n ),\n overscanColumns: materializeColumns(\n metadata,\n effectiveColumnWidths,\n prefixes,\n overscanColumnRange,\n frozenColumnRange,\n rowHeaderWidth,\n horizontal.logicalOffset,\n frozenColumnCount,\n ),\n visibleRows: materializeRows(\n rowGeometry,\n visibleRows,\n frozenRowRange,\n headerHeight,\n vertical.logicalOffset,\n frozenRowCount,\n ),\n overscanRows: materializeRows(\n rowGeometry,\n overscanRowRange,\n frozenRowRange,\n headerHeight,\n vertical.logicalOffset,\n frozenRowCount,\n ),\n effectiveColumnWidths,\n rowGeometry,\n frozenRowCount,\n frozenColumnCount,\n frozenRowExtent,\n frozenColumnExtent,\n frozenRowRange,\n frozenColumnRange,\n horizontal,\n vertical,\n spacerWidth: rowHeaderWidth + horizontal.physicalContentSize,\n spacerHeight: headerHeight + vertical.physicalContentSize,\n });\n}\n\nexport function createScrollAxis(\n logicalContentSize: number,\n logicalViewportSize: number,\n physicalOffset: number,\n pixelLimit = DEFAULT_SCROLL_PIXEL_LIMIT,\n): Readonly<ScrollAxisLayout> {\n nonNegativeFinite(logicalContentSize, \"logicalContentSize\");\n nonNegativeFinite(logicalViewportSize, \"logicalViewportSize\");\n positiveFinite(pixelLimit, \"pixelLimit\");\n const logicalMaxOffset = Math.max(0, logicalContentSize - logicalViewportSize);\n const largestUsableSize = Math.max(pixelLimit, logicalViewportSize + 1);\n const physicalContentSize = Math.min(logicalContentSize, largestUsableSize);\n const physicalMaxOffset = Math.max(0, physicalContentSize - logicalViewportSize);\n const normalizedPhysicalOffset = clampFinite(physicalOffset, 0, physicalMaxOffset);\n const compressed = logicalMaxOffset > physicalMaxOffset;\n const logicalOffset = physicalMaxOffset === 0\n ? 0\n : compressed\n ? (normalizedPhysicalOffset / physicalMaxOffset) * logicalMaxOffset\n : normalizedPhysicalOffset;\n return Object.freeze({\n logicalContentSize,\n logicalViewportSize,\n logicalOffset,\n logicalMaxOffset,\n physicalContentSize,\n physicalOffset: normalizedPhysicalOffset,\n physicalMaxOffset,\n compressed,\n });\n}\n\nexport function logicalToPhysicalOffset(axis: ScrollAxisLayout, logicalOffset: number): number {\n const normalized = clampFinite(logicalOffset, 0, axis.logicalMaxOffset);\n if (!axis.compressed) {\n return Math.min(normalized, axis.physicalMaxOffset);\n }\n return axis.logicalMaxOffset === 0\n ? 0\n : (normalized / axis.logicalMaxOffset) * axis.physicalMaxOffset;\n}\n\nexport function physicalToLogicalOffset(axis: ScrollAxisLayout, physicalOffset: number): number {\n const normalized = clampFinite(physicalOffset, 0, axis.physicalMaxOffset);\n if (!axis.compressed) {\n return Math.min(normalized, axis.logicalMaxOffset);\n }\n return axis.physicalMaxOffset === 0\n ? 0\n : (normalized / axis.physicalMaxOffset) * axis.logicalMaxOffset;\n}\n\nexport function hitTest(\n layout: TableLayout,\n x: number,\n y: number,\n _columnWidths: readonly number[],\n resizeHandleWidth = 6,\n): HitTestResult {\n if (!Number.isFinite(x) || !Number.isFinite(y) || x < 0 || y < 0\n || x >= layout.width || y >= layout.height) {\n return Object.freeze({ kind: \"outside\" });\n }\n const columnWidths = layout.effectiveColumnWidths;\n if (x < layout.rowHeaderWidth && y < layout.headerHeight) {\n return Object.freeze({ kind: \"corner\" });\n }\n if (y < layout.headerHeight) {\n const offsets = columnOffsets(columnWidths);\n const logicalX = x - layout.rowHeaderWidth + layout.horizontal.logicalOffset;\n const nextBoundary = lowerBound(offsets, logicalX);\n const handleWidth = Math.max(0, resizeHandleWidth);\n for (const boundaryIndex of [nextBoundary, nextBoundary - 1]) {\n if (boundaryIndex <= 0 || boundaryIndex >= offsets.length) {\n continue;\n }\n const boundaryX = layout.rowHeaderWidth\n + offsets[boundaryIndex]!\n - layout.horizontal.logicalOffset;\n if (Math.abs(x - boundaryX) <= handleWidth) {\n return Object.freeze({\n kind: \"column-resize\",\n columnIndex: boundaryIndex - 1,\n boundaryX,\n });\n }\n }\n const columnIndex = columnAtViewportX(layout, x, columnWidths);\n if (columnIndex === null) {\n return Object.freeze({ kind: \"outside\" });\n }\n return Object.freeze({ kind: \"column-header\", columnIndex });\n }\n const rowIndex = rowAtViewportY(layout, y);\n if (rowIndex === null) {\n return Object.freeze({ kind: \"outside\" });\n }\n if (x < layout.rowHeaderWidth) {\n return Object.freeze({ kind: \"row-header\", rowIndex });\n }\n const columnIndex = columnAtViewportX(layout, x, columnWidths);\n return columnIndex === null\n ? Object.freeze({ kind: \"outside\" })\n : Object.freeze({ kind: \"cell\", rowIndex, columnIndex });\n}\n\nexport function cellRect(\n layout: TableLayout,\n _columnWidths: readonly number[],\n rowIndex: number,\n columnIndex: number,\n): Readonly<PixelRect> {\n const columnWidths = layout.effectiveColumnWidths;\n const offsets = columnOffsets(columnWidths);\n const rowOffset = axisPosition(layout.rowGeometry, rowIndex);\n const columnOffset = offsets[columnIndex] ?? 0;\n return Object.freeze({\n x: layout.rowHeaderWidth + columnOffset\n - (columnIndex < layout.frozenColumnCount ? 0 : layout.horizontal.logicalOffset),\n y: layout.headerHeight + rowOffset\n - (rowIndex < layout.frozenRowCount ? 0 : layout.vertical.logicalOffset),\n width: columnWidths[columnIndex] ?? 0,\n height: axisSize(layout.rowGeometry, rowIndex),\n });\n}\n\nexport function columnHeaderRect(\n layout: TableLayout,\n _columnWidths: readonly number[],\n columnIndex: number,\n): Readonly<PixelRect> {\n const columnWidths = layout.effectiveColumnWidths;\n const offsets = columnOffsets(columnWidths);\n return Object.freeze({\n x: layout.rowHeaderWidth + offsets[columnIndex]!\n - (columnIndex < layout.frozenColumnCount ? 0 : layout.horizontal.logicalOffset),\n y: 0,\n width: columnWidths[columnIndex] ?? 0,\n height: layout.headerHeight,\n });\n}\n\nexport function rowHeaderRect(layout: TableLayout, rowIndex: number): Readonly<PixelRect> {\n const rowOffset = axisPosition(layout.rowGeometry, rowIndex);\n return Object.freeze({\n x: 0,\n y: layout.headerHeight + rowOffset\n - (rowIndex < layout.frozenRowCount ? 0 : layout.vertical.logicalOffset),\n width: layout.rowHeaderWidth,\n height: axisSize(layout.rowGeometry, rowIndex),\n });\n}\n\nexport function selectionRect(\n layout: TableLayout,\n _columnWidths: readonly number[],\n range: GridRange,\n): Readonly<PixelRect> | null {\n const columnWidths = layout.effectiveColumnWidths;\n if (range.rowStart >= range.rowEnd || range.columnStart >= range.columnEnd) {\n return null;\n }\n const offsets = columnOffsets(columnWidths);\n const columnStart = clampInteger(range.columnStart, 0, columnWidths.length);\n const columnEnd = clampInteger(range.columnEnd, columnStart, columnWidths.length);\n const rowStart = clampInteger(range.rowStart, 0, layout.rowCount);\n const rowEnd = clampInteger(range.rowEnd, rowStart, layout.rowCount);\n if (columnStart === columnEnd || rowStart === rowEnd) {\n return null;\n }\n const frozenColumns = columnEnd <= layout.frozenColumnCount;\n const frozenRows = rowEnd <= layout.frozenRowCount;\n const rowStartOffset = axisPosition(layout.rowGeometry, rowStart);\n const rowEndOffset = axisPosition(layout.rowGeometry, rowEnd);\n return Object.freeze({\n x: layout.rowHeaderWidth + offsets[columnStart]!\n - (frozenColumns ? 0 : layout.horizontal.logicalOffset),\n y: layout.headerHeight + rowStartOffset\n - (frozenRows ? 0 : layout.vertical.logicalOffset),\n width: offsets[columnEnd]! - offsets[columnStart]!,\n height: rowEndOffset - rowStartOffset,\n });\n}\n\nexport function columnOffsets(columnWidths: readonly number[]): readonly number[] {\n const offsets = new Array<number>(columnWidths.length + 1);\n offsets[0] = 0;\n for (let index = 0; index < columnWidths.length; index += 1) {\n offsets[index + 1] = offsets[index]! + (columnWidths[index] ?? DEFAULT_COLUMN_WIDTH);\n }\n return offsets;\n}\n\nexport function extentValue(extent: TableMetadata[\"extent\"][\"rows\"]): number {\n return extent.kind === \"unknown\" ? 0 : extent.value;\n}\n\n/** Builds a compact sparse axis without allocating one entry per worksheet row. */\nexport function createSparseAxisGeometry(\n count: number,\n defaultSize: number,\n entries: readonly PresentationAxisEntry[] = [],\n): Readonly<SparseAxisGeometry> {\n nonNegativeInteger(count, \"axis count\");\n positiveFinite(defaultSize, \"axis defaultSize\");\n const byIndex = new Map<number, number>();\n for (const entry of entries) {\n if (!entry || !Number.isSafeInteger(entry.index) || entry.index < 0 || entry.index >= count) {\n continue;\n }\n if (entry.hidden === true) {\n byIndex.set(entry.index, 0);\n continue;\n }\n if (entry.size !== undefined) {\n if (!Number.isFinite(entry.size) || entry.size < 0) {\n continue;\n }\n byIndex.set(entry.index, entry.size);\n }\n }\n let cumulativeDelta = 0;\n const overrides = [...byIndex.entries()]\n .sort(([left], [right]) => left - right)\n .map(([index, size]) => {\n cumulativeDelta += size - defaultSize;\n return Object.freeze({ index, size, cumulativeDelta });\n });\n const contentSize = count * defaultSize + cumulativeDelta;\n return Object.freeze({\n count,\n defaultSize,\n contentSize: Math.max(0, contentSize),\n overrides: Object.freeze(overrides),\n });\n}\n\n/** Logical offset at the start of an axis index. */\nexport function axisPosition(geometry: SparseAxisGeometry, index: number): number {\n const normalized = clampInteger(index, 0, geometry.count);\n const overrideIndex = lowerBoundOverride(geometry.overrides, normalized);\n const delta = overrideIndex === 0 ? 0 : geometry.overrides[overrideIndex - 1]!.cumulativeDelta;\n return normalized * geometry.defaultSize + delta;\n}\n\n/** Effective axis extent, zero when a row/column is hidden. */\nexport function axisSize(geometry: SparseAxisGeometry, index: number): number {\n if (!Number.isSafeInteger(index) || index < 0 || index >= geometry.count) {\n return 0;\n }\n const match = sparseOverrideAt(geometry, index);\n return match?.size ?? geometry.defaultSize;\n}\n\n/** Finds the visible axis index containing a logical pixel offset. */\nexport function axisIndexAtOffset(geometry: SparseAxisGeometry, offset: number): number | null {\n if (!Number.isFinite(offset) || offset < 0 || offset >= geometry.contentSize || geometry.count === 0) {\n return null;\n }\n let low = 0;\n let high = geometry.count;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (axisPosition(geometry, middle + 1) <= offset) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n for (let index = low; index < geometry.count; index += 1) {\n const size = axisSize(geometry, index);\n const start = axisPosition(geometry, index);\n if (size > 0 && offset >= start && offset < start + size) {\n return index;\n }\n if (start > offset) {\n return null;\n }\n }\n return null;\n}\n\nexport function nextVisibleAxisIndex(\n geometry: SparseAxisGeometry,\n from: number,\n direction: -1 | 1 = 1,\n): number | null {\n for (\n let index = clampInteger(from, 0, Math.max(0, geometry.count - 1));\n index >= 0 && index < geometry.count;\n index += direction\n ) {\n if (axisSize(geometry, index) > 0) {\n return index;\n }\n }\n return null;\n}\n\nfunction sparseOverrideAt(\n geometry: SparseAxisGeometry,\n index: number,\n): Readonly<SparseAxisGeometry[\"overrides\"][number]> | undefined {\n const low = lowerBoundOverride(geometry.overrides, index);\n const candidate = geometry.overrides[low];\n return candidate?.index === index ? candidate : undefined;\n}\n\nfunction lowerBoundOverride(\n entries: readonly Readonly<SparseAxisGeometry[\"overrides\"][number]>[],\n target: number,\n): number {\n let low = 0;\n let high = entries.length;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (entries[middle]!.index < target) low = middle + 1;\n else high = middle;\n }\n return low;\n}\n\nfunction clampRangeEnd(range: IndexRange, end: number): Readonly<IndexRange> {\n return Object.freeze({\n start: Math.min(range.start, end),\n end: Math.min(range.end, end),\n });\n}\n\nfunction visibleRowRange(\n geometry: SparseAxisGeometry,\n scrollTop: number,\n viewportHeight: number,\n): Readonly<IndexRange> {\n if (geometry.count === 0 || viewportHeight <= 0 || geometry.contentSize <= 0) {\n return Object.freeze({ start: 0, end: 0 });\n }\n const start = axisIndexAtOffset(geometry, scrollTop);\n if (start === null) {\n return Object.freeze({ start: geometry.count, end: geometry.count });\n }\n const last = axisIndexAtOffset(\n geometry,\n Math.max(\n scrollTop,\n Math.min(geometry.contentSize, scrollTop + viewportHeight)\n - Math.max(1e-7, Math.abs(scrollTop + viewportHeight) * Number.EPSILON * 4),\n ),\n );\n return Object.freeze({\n start,\n end: last === null ? start + 1 : Math.min(geometry.count, last + 1),\n });\n}\n\nfunction visibleColumnRange(\n offsets: readonly number[],\n scrollLeft: number,\n viewportWidth: number,\n): Readonly<IndexRange> {\n const count = Math.max(0, offsets.length - 1);\n if (count === 0 || viewportWidth <= 0) {\n return Object.freeze({ start: 0, end: 0 });\n }\n const start = columnAtLogicalX(offsets, scrollLeft) ?? count;\n const end = Math.min(count, lowerBound(offsets, scrollLeft + viewportWidth));\n return Object.freeze({ start, end: Math.max(start, end) });\n}\n\nfunction expandRange(range: IndexRange, amount: number, limit: number): Readonly<IndexRange> {\n return Object.freeze({\n start: Math.max(0, range.start - amount),\n end: Math.min(limit, range.end + amount),\n });\n}\n\nfunction materializeColumns(\n metadata: Readonly<TableMetadata>,\n widths: readonly number[],\n offsets: readonly number[],\n range: IndexRange,\n frozenRange: IndexRange,\n rowHeaderWidth: number,\n scrollLeft: number,\n frozenColumnCount: number,\n): readonly Readonly<VisibleColumn>[] {\n const indexes = rangeIndexes(range, frozenRange);\n const columns: VisibleColumn[] = [];\n for (const index of indexes) {\n const column = metadata.schema.columns[index]!;\n const width = widths[index] ?? 0;\n if (width <= 0) {\n continue;\n }\n const frozen = index < frozenColumnCount;\n columns.push(Object.freeze({\n index,\n id: column.id,\n name: column.name,\n x: rowHeaderWidth + offsets[index]! - (frozen ? 0 : scrollLeft),\n width,\n frozen,\n }));\n }\n return Object.freeze(columns);\n}\n\nfunction materializeRows(\n geometry: SparseAxisGeometry,\n range: IndexRange,\n frozenRange: IndexRange,\n headerHeight: number,\n scrollTop: number,\n frozenRowCount: number,\n): readonly Readonly<VisibleRow>[] {\n const rows: VisibleRow[] = [];\n for (const index of rangeIndexes(range, frozenRange)) {\n const height = axisSize(geometry, index);\n if (height <= 0) {\n continue;\n }\n const frozen = index < frozenRowCount;\n rows.push(Object.freeze({\n index,\n y: headerHeight + axisPosition(geometry, index) - (frozen ? 0 : scrollTop),\n height,\n frozen,\n }));\n }\n return Object.freeze(rows);\n}\n\nfunction rangeIndexes(primary: IndexRange, frozen: IndexRange): readonly number[] {\n const indexes = new Set<number>();\n for (let index = primary.start; index < primary.end; index += 1) {\n indexes.add(index);\n }\n for (let index = frozen.start; index < frozen.end; index += 1) {\n indexes.add(index);\n }\n return Object.freeze([...indexes].sort((left, right) => left - right));\n}\n\nfunction columnAtViewportX(\n layout: TableLayout,\n x: number,\n columnWidths: readonly number[],\n): number | null {\n if (x < layout.rowHeaderWidth) {\n return null;\n }\n const bodyX = x - layout.rowHeaderWidth;\n if (bodyX < Math.min(layout.bodyWidth, layout.frozenColumnExtent)) {\n const frozen = columnAtLogicalX(columnOffsets(columnWidths), bodyX);\n if (frozen !== null && frozen < layout.frozenColumnCount) {\n return frozen;\n }\n }\n return columnAtLogicalX(\n columnOffsets(columnWidths),\n bodyX + layout.horizontal.logicalOffset,\n );\n}\n\nfunction columnAtLogicalX(offsets: readonly number[], x: number): number | null {\n const count = Math.max(0, offsets.length - 1);\n if (x < 0 || count === 0 || x >= offsets[count]!) {\n return null;\n }\n let low = 0;\n let high = count;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (offsets[middle + 1]! <= x) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n return low;\n}\n\nfunction rowAtViewportY(layout: TableLayout, y: number): number | null {\n const bodyY = y - layout.headerHeight;\n if (bodyY < Math.min(layout.bodyHeight, layout.frozenRowExtent)) {\n const frozen = axisIndexAtOffset(layout.rowGeometry, bodyY);\n if (frozen !== null && frozen < layout.frozenRowCount) {\n return frozen;\n }\n }\n return axisIndexAtOffset(\n layout.rowGeometry,\n bodyY + layout.vertical.logicalOffset,\n );\n}\n\nfunction lowerBound(values: readonly number[], target: number): number {\n let low = 0;\n let high = values.length;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (values[middle]! < target) {\n low = middle + 1;\n } else {\n high = middle;\n }\n }\n return low;\n}\n\nfunction positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) {\n throw invalidArgument(`${name} must be a positive finite number`);\n }\n return value;\n}\n\nfunction nonNegativeFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw invalidArgument(`${name} must be a non-negative finite number`);\n }\n return value;\n}\n\nfunction nonNegativeInteger(value: number, name: string): number {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw invalidArgument(`${name} must be a non-negative safe integer`);\n }\n return value;\n}\n\nfunction clampFinite(value: number, minimum: number, maximum: number): number {\n if (!Number.isFinite(value)) {\n return minimum;\n }\n return Math.min(maximum, Math.max(minimum, value));\n}\n\nfunction clampInteger(value: number, minimum: number, maximum: number): number {\n if (!Number.isFinite(value)) {\n return minimum;\n }\n return Math.min(maximum, Math.max(minimum, Math.trunc(value)));\n}\n", "import type { TableHandle, TableEvent, Unsubscribe } from \"../client.js\";\nimport { TabularkError, closedError, invalidArgument } from \"../errors.js\";\nimport {\n MAX_RANGE_CELLS,\n type MergedCellRegion,\n type PresentationAxisEntry,\n type RangeRequest,\n type SpreadsheetPresentation,\n type TableBatch,\n} from \"../model.js\";\nimport {\n axisPosition,\n axisSize,\n cellRect,\n columnOffsets,\n createTableLayout,\n extentValue,\n hitTest,\n logicalToPhysicalOffset,\n nextVisibleAxisIndex,\n selectionRect,\n type LayoutOptions,\n} from \"./layout.js\";\nimport { assertCellPosition, clampCell, createSelection, moveCell } from \"./selection.js\";\nimport {\n DEFAULT_COLUMN_WIDTH,\n DEFAULT_MAX_COLUMN_WIDTH,\n DEFAULT_MIN_COLUMN_WIDTH,\n type CellLoadState,\n type CellPosition,\n type GridRange,\n type HitTestResult,\n type MoveActiveCellOptions,\n type NavigationCommand,\n type PixelRect,\n type SetActiveCellOptions,\n type TableControllerOptions,\n type TableSelection,\n type TableViewSnapshot,\n type ViewportUpdate,\n} from \"./types.js\";\n\nconst DEFAULT_MAX_WINDOW_CELLS = 100_000;\n\ninterface LoadedWindow {\n readonly range: Readonly<GridRange>;\n readonly rows: readonly (readonly (string | null)[])[];\n}\n\ninterface NormalizedOptions extends LayoutOptions {\n readonly columnWidth: number;\n readonly minColumnWidth: number;\n readonly maxColumnWidth: number;\n readonly columnWidths: Readonly<Record<string, number>>;\n readonly maxWindowCells: number;\n}\n\nexport interface TableViewController {\n readonly metadata: TableHandle[\"metadata\"];\n readonly columnWidths: readonly number[];\n readonly minColumnWidth: number;\n readonly maxColumnWidth: number;\n getSnapshot(): Readonly<TableViewSnapshot>;\n subscribe(listener: (snapshot: Readonly<TableViewSnapshot>) => void): Unsubscribe;\n updateViewport(viewport: ViewportUpdate): void;\n setActiveCell(cell: CellPosition, options?: SetActiveCellOptions): void;\n extendSelection(cell: CellPosition, options?: Omit<SetActiveCellOptions, \"extendSelection\">): void;\n setSelection(anchor: CellPosition, focus?: CellPosition): void;\n clearSelection(): void;\n moveActive(command: NavigationCommand, options?: MoveActiveCellOptions): void;\n ensureCellVisible(cell: CellPosition): void;\n ensureColumnVisible(columnIndex: number): void;\n resizeColumn(columnIndex: number, width: number): void;\n autosizeColumn(columnIndex: number, measuredWidth: number): void;\n /** Applies validated static worksheet geometry in one controller generation. */\n applySpreadsheetPresentation(presentation: SpreadsheetPresentation): void;\n /** Updates merge interaction geometry for the currently loaded presentation window. */\n setMergedCells(regions: readonly MergedCellRegion[]): void;\n hitTest(x: number, y: number, resizeHandleWidth?: number): HitTestResult;\n cellRect(cell: CellPosition): Readonly<PixelRect>;\n selectionRect(selection?: TableSelection | null): Readonly<PixelRect> | null;\n getCell(rowIndex: number, columnIndex: number): CellLoadState;\n copySelection(options?: { readonly signal?: AbortSignal }): Promise<string>;\n dispose(): void;\n}\n\nclass Controller implements TableViewController {\n readonly #table: TableHandle;\n readonly #options: NormalizedOptions;\n readonly #listeners = new Set<(snapshot: Readonly<TableViewSnapshot>) => void>();\n readonly #unsubscribe: Unsubscribe;\n #viewport: Required<ViewportUpdate> = {\n width: 0,\n height: 0,\n scrollLeft: 0,\n scrollTop: 0,\n devicePixelRatio: 1,\n };\n #columnWidths: number[];\n #hiddenColumns: boolean[];\n #presentationRows: readonly PresentationAxisEntry[] = [];\n #frozenRows = 0;\n #frozenColumns = 0;\n #mergedCells: readonly MergedCellRegion[] = [];\n #snapshot: Readonly<TableViewSnapshot>;\n #activeCell: Readonly<CellPosition> | null = null;\n #selection: Readonly<TableSelection> | null = null;\n #windows: readonly LoadedWindow[] = [];\n #loadingRanges: readonly Readonly<GridRange>[] = [];\n #requestAbort: AbortController | null = null;\n #generation = 0;\n #loadQueued = false;\n #disposed = false;\n #tableClosed = false;\n\n constructor(table: TableHandle, options: TableControllerOptions) {\n this.#table = table;\n this.#options = normalizeOptions(options);\n this.#columnWidths = initialColumnWidths(table.metadata, this.#options);\n this.#hiddenColumns = Array.from({ length: this.#columnWidths.length }, () => false);\n const layout = createTableLayout(\n table.metadata,\n this.#columnWidths,\n this.#viewport,\n this.#layoutOptions(),\n );\n this.#snapshot = Object.freeze({\n generation: this.#generation,\n status: \"loading\",\n metadata: table.metadata,\n layout,\n activeCell: null,\n selection: null,\n });\n this.#unsubscribe = table.subscribe((event) => this.#handleTableEvent(event));\n }\n\n get metadata(): TableHandle[\"metadata\"] {\n return this.#table.metadata;\n }\n\n get columnWidths(): readonly number[] {\n return Object.freeze([...this.#columnWidths]);\n }\n\n get minColumnWidth(): number {\n return this.#options.minColumnWidth;\n }\n\n get maxColumnWidth(): number {\n return this.#options.maxColumnWidth;\n }\n\n getSnapshot(): Readonly<TableViewSnapshot> {\n return this.#snapshot;\n }\n\n subscribe(listener: (snapshot: Readonly<TableViewSnapshot>) => void): Unsubscribe {\n this.#assertOpen();\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n updateViewport(viewport: ViewportUpdate): void {\n this.#assertOpen();\n const normalized = normalizeViewport(viewport);\n if (sameViewport(normalized, this.#viewport)) {\n return;\n }\n this.#viewport = normalized;\n this.#advanceGeneration();\n }\n\n setActiveCell(cell: CellPosition, options: SetActiveCellOptions = {}): void {\n this.#assertOpen();\n assertCellPosition(cell, \"cell\");\n const clamped = clampCell(\n cell,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n if (clamped === null) {\n return;\n }\n const next = this.#visibleCell(this.#mergeAnchor(clamped), 1, 1);\n if (next === null) return;\n const anchor = options.extendSelection && this.#selection !== null\n ? this.#selection.anchor\n : next;\n this.#activeCell = next;\n this.#selection = createMergedSelection(anchor, next, this.#mergedCells);\n if (options.scrollIntoView !== false && this.#scrollCellIntoView(next)) {\n this.#advanceGeneration();\n return;\n }\n this.#publish();\n }\n\n extendSelection(\n cell: CellPosition,\n options: Omit<SetActiveCellOptions, \"extendSelection\"> = {},\n ): void {\n this.setActiveCell(cell, { ...options, extendSelection: true });\n }\n\n setSelection(anchor: CellPosition, focus: CellPosition = anchor): void {\n this.#assertOpen();\n assertCellPosition(anchor, \"anchor\");\n assertCellPosition(focus, \"focus\");\n const rawAnchor = clampCell(\n anchor,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n const rawFocus = clampCell(\n focus,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n if (rawAnchor === null || rawFocus === null) {\n this.clearSelection();\n return;\n }\n const clampedAnchor = this.#visibleCell(this.#mergeAnchor(rawAnchor), 1, 1);\n const clampedFocus = this.#visibleCell(this.#mergeAnchor(rawFocus), 1, 1);\n if (clampedAnchor === null || clampedFocus === null) {\n this.clearSelection();\n return;\n }\n this.#activeCell = clampedFocus;\n this.#selection = createMergedSelection(clampedAnchor, clampedFocus, this.#mergedCells);\n this.#publish();\n }\n\n clearSelection(): void {\n this.#assertOpen();\n if (this.#selection === null) {\n return;\n }\n this.#selection = null;\n this.#publish();\n }\n\n moveActive(command: NavigationCommand, options: MoveActiveCellOptions = {}): void {\n this.#assertOpen();\n const current = this.#activeCell ?? { rowIndex: 0, columnIndex: 0 };\n const origin = navigationOrigin(current, command, this.#mergedCells);\n const moved = moveCell(\n origin,\n command,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n Math.max(1, this.#snapshot.layout.visibleRows.filter((row) => !row.frozen).length),\n );\n const [rowDirection, columnDirection] = navigationDirections(command);\n const next = moved === null\n ? null\n : this.#visibleCell(this.#mergeAnchor(moved), rowDirection, columnDirection);\n if (next !== null) {\n this.setActiveCell(next, options);\n }\n }\n\n ensureCellVisible(cell: CellPosition): void {\n this.#assertOpen();\n assertCellPosition(cell, \"cell\");\n const next = clampCell(\n cell,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n if (next !== null && this.#scrollCellIntoView(next)) {\n this.#advanceGeneration();\n }\n }\n\n ensureColumnVisible(columnIndex: number): void {\n this.#assertOpen();\n assertColumnIndex(columnIndex, this.#columnWidths.length);\n if (this.#scrollColumnIntoView(columnIndex)) {\n this.#advanceGeneration();\n }\n }\n\n resizeColumn(columnIndex: number, width: number): void {\n this.#assertOpen();\n assertColumnIndex(columnIndex, this.#columnWidths.length);\n const normalized = clampWidth(width, this.#options);\n if (this.#columnWidths[columnIndex] === normalized) {\n return;\n }\n this.#columnWidths[columnIndex] = normalized;\n this.#advanceGeneration();\n }\n\n autosizeColumn(columnIndex: number, measuredWidth: number): void {\n this.resizeColumn(columnIndex, measuredWidth);\n }\n\n applySpreadsheetPresentation(presentation: SpreadsheetPresentation): void {\n this.#assertOpen();\n if (presentation.kind !== \"spreadsheet-v1\" || presentation.tableId !== this.metadata.tableId) {\n throw invalidArgument(\"presentation must belong to the controller table\");\n }\n const nextWidths = [...this.#columnWidths];\n const hiddenColumns = Array.from({ length: nextWidths.length }, () => false);\n for (const entry of presentation.columns) {\n if (!Number.isSafeInteger(entry.index) || entry.index < 0 || entry.index >= nextWidths.length) {\n continue;\n }\n hiddenColumns[entry.index] = entry.hidden === true;\n if (entry.size !== undefined && Number.isFinite(entry.size) && entry.size > 0) {\n nextWidths[entry.index] = clampWidth(entry.size, this.#options);\n }\n }\n this.#columnWidths = nextWidths;\n this.#hiddenColumns = hiddenColumns;\n this.#presentationRows = Object.freeze(presentation.rows.map((entry) => Object.freeze({ ...entry })));\n this.#frozenRows = presentation.frozenRows;\n this.#frozenColumns = presentation.frozenColumns;\n this.#mergedCells = [];\n this.#advanceGeneration();\n this.#normalizeInteractionForPresentation();\n this.#publish();\n }\n\n setMergedCells(regions: readonly MergedCellRegion[]): void {\n this.#assertOpen();\n const normalized = normalizeMergedCells(\n regions,\n this.#snapshot.layout.rowCount,\n this.#snapshot.layout.columnCount,\n );\n if (sameMergedCells(normalized, this.#mergedCells)) {\n return;\n }\n this.#mergedCells = normalized;\n this.#normalizeInteractionForPresentation();\n // A merge may intersect the viewport while its value anchor is far\n // outside the ordinary visible/overscan windows. Start a new generation\n // so those anchors are requested along with the visible cells.\n this.#advanceGeneration();\n }\n\n hitTest(x: number, y: number, resizeHandleWidth?: number): HitTestResult {\n const result = hitTest(\n this.#snapshot.layout,\n x,\n y,\n this.#columnWidths,\n resizeHandleWidth,\n );\n if (result.kind !== \"cell\") {\n return result;\n }\n const anchor = this.#mergeAnchor(result);\n return Object.freeze({ kind: \"cell\", ...anchor });\n }\n\n cellRect(cell: CellPosition): Readonly<PixelRect> {\n assertCellPosition(cell, \"cell\");\n if (cell.rowIndex >= this.#snapshot.layout.rowCount\n || cell.columnIndex >= this.#snapshot.layout.columnCount) {\n throw invalidArgument(\"cell must be inside the current table extent\");\n }\n return cellRect(\n this.#snapshot.layout,\n this.#columnWidths,\n cell.rowIndex,\n cell.columnIndex,\n );\n }\n\n selectionRect(selection: TableSelection | null = this.#selection): Readonly<PixelRect> | null {\n return selection === null\n ? null\n : selectionRect(this.#snapshot.layout, this.#columnWidths, selection.range);\n }\n\n getCell(rowIndex: number, columnIndex: number): CellLoadState {\n if (!isValidCell(rowIndex, columnIndex, this.#snapshot.layout.rowCount, this.#columnWidths.length)) {\n return Object.freeze({ status: \"unavailable\" });\n }\n for (const window of this.#windows) {\n if (rangeContains(window.range, rowIndex, columnIndex)) {\n return Object.freeze({\n status: \"loaded\",\n value: window.rows[rowIndex - window.range.rowStart]![columnIndex - window.range.columnStart]!,\n });\n }\n }\n for (const range of this.#loadingRanges) {\n if (rangeContains(range, rowIndex, columnIndex)) {\n return Object.freeze({ status: \"loading\" });\n }\n }\n return Object.freeze({ status: \"unavailable\" });\n }\n\n async copySelection(options: { readonly signal?: AbortSignal } = {}): Promise<string> {\n this.#assertOpen();\n const selection = this.#selection;\n if (selection === null) {\n return \"\";\n }\n const request = gridRangeToRequest(selection.range);\n assertWindowCellLimit(request, MAX_RANGE_CELLS, \"selection\");\n const batch = await this.#table.readRange(\n request,\n options.signal ? { signal: options.signal } : {},\n );\n return rowsToTsv(batchRows(batch));\n }\n\n dispose(): void {\n if (this.#disposed) {\n return;\n }\n this.#disposed = true;\n this.#requestAbort?.abort();\n this.#requestAbort = null;\n this.#unsubscribe();\n this.#listeners.clear();\n this.#windows = [];\n this.#loadingRanges = [];\n this.#snapshot = Object.freeze({\n ...this.#snapshot,\n status: \"closed\",\n activeCell: null,\n selection: null,\n });\n }\n\n #advanceGeneration(): void {\n this.#generation += 1;\n this.#requestAbort?.abort();\n this.#requestAbort = null;\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"loading\");\n this.#queueLoad();\n }\n\n #queueLoad(): void {\n if (this.#loadQueued || this.#disposed) {\n return;\n }\n this.#loadQueued = true;\n queueMicrotask(() => {\n this.#loadQueued = false;\n if (!this.#disposed) {\n void this.#loadGeneration(this.#generation);\n }\n });\n }\n\n async #loadGeneration(generation: number): Promise<void> {\n let visible: readonly Readonly<GridRange>[];\n let overscan: readonly Readonly<GridRange>[];\n try {\n ({ visible, overscan } = layoutRanges(\n this.#snapshot.layout,\n this.#options.maxWindowCells,\n this.#mergedCells,\n ));\n } catch (error) {\n if (!this.#disposed && generation === this.#generation) {\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"error\", error);\n }\n return;\n }\n if (visible.length === 0) {\n this.#windows = [];\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"ready\");\n return;\n }\n const abort = new AbortController();\n this.#requestAbort = abort;\n const ranges = Object.freeze([\n ...visible,\n ...overscan.filter((candidate) => !visible.some(\n (required) => rangeContainsRange(candidate, required) && sameGridRange(candidate, required),\n )),\n ]);\n this.#loadingRanges = Object.freeze(ranges);\n this.#publish();\n let loaded: LoadedWindow[] = [];\n try {\n for (let index = 0; index < ranges.length; index += 1) {\n const range = ranges[index]!;\n const batch = await this.#table.readRange(\n gridRangeToRequest(range),\n { signal: abort.signal },\n );\n if (this.#disposed || generation !== this.#generation || abort.signal.aborted) {\n return;\n }\n const returnedRange = batchGridRange(batch);\n if (returnedRange.rowStart < returnedRange.rowEnd\n && returnedRange.columnStart < returnedRange.columnEnd) {\n const window = Object.freeze({ range: returnedRange, rows: batchRows(batch) });\n loaded = [window, ...loaded.filter(\n (candidate) => !rangeContainsRange(returnedRange, candidate.range),\n )];\n }\n this.#windows = Object.freeze([...loaded]);\n this.#loadingRanges = Object.freeze(ranges.slice(index + 1));\n this.#rebuildSnapshot(\"ready\");\n }\n } catch (error) {\n if (this.#disposed || generation !== this.#generation || abort.signal.aborted\n || (error instanceof TabularkError && error.code === \"CANCELLED\")) {\n return;\n }\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"error\", error);\n } finally {\n if (this.#requestAbort === abort) {\n this.#requestAbort = null;\n }\n }\n }\n\n #scrollCellIntoView(cell: CellPosition): boolean {\n const layout = this.#snapshot.layout;\n const offsets = columnOffsets(layout.effectiveColumnWidths);\n const cellLeft = offsets[cell.columnIndex]!;\n const cellRight = offsets[cell.columnIndex + 1]!;\n const cellTop = axisPosition(layout.rowGeometry, cell.rowIndex);\n const cellBottom = cellTop + axisSize(layout.rowGeometry, cell.rowIndex);\n const logicalLeft = cell.columnIndex < layout.frozenColumnCount\n ? layout.horizontal.logicalOffset\n : revealOffset(\n layout.horizontal.logicalOffset,\n layout.bodyWidth,\n cellLeft,\n cellRight,\n layout.horizontal.logicalMaxOffset,\n );\n const logicalTop = cell.rowIndex < layout.frozenRowCount\n ? layout.vertical.logicalOffset\n : revealOffset(\n layout.vertical.logicalOffset,\n layout.bodyHeight,\n cellTop,\n cellBottom,\n layout.vertical.logicalMaxOffset,\n );\n const scrollLeft = logicalToPhysicalOffset(layout.horizontal, logicalLeft);\n const scrollTop = logicalToPhysicalOffset(layout.vertical, logicalTop);\n if (scrollLeft === this.#viewport.scrollLeft && scrollTop === this.#viewport.scrollTop) {\n return false;\n }\n this.#viewport = Object.freeze({ ...this.#viewport, scrollLeft, scrollTop });\n return true;\n }\n\n #scrollColumnIntoView(columnIndex: number): boolean {\n const layout = this.#snapshot.layout;\n const offsets = columnOffsets(layout.effectiveColumnWidths);\n const logicalLeft = columnIndex < layout.frozenColumnCount\n ? layout.horizontal.logicalOffset\n : revealOffset(\n layout.horizontal.logicalOffset,\n layout.bodyWidth,\n offsets[columnIndex]!,\n offsets[columnIndex + 1]!,\n layout.horizontal.logicalMaxOffset,\n );\n const scrollLeft = logicalToPhysicalOffset(layout.horizontal, logicalLeft);\n if (scrollLeft === this.#viewport.scrollLeft) {\n return false;\n }\n this.#viewport = Object.freeze({ ...this.#viewport, scrollLeft });\n return true;\n }\n\n #handleTableEvent(event: TableEvent): void {\n if (this.#disposed) {\n return;\n }\n switch (event.type) {\n case \"metadata\": {\n const previousMetadata = this.#snapshot.metadata;\n this.#columnWidths = reconcileColumnWidths(\n previousMetadata,\n event.metadata,\n this.#columnWidths,\n this.#options,\n );\n const hiddenById = new Map(previousMetadata.schema.columns.map(\n (column, index) => [column.id, this.#hiddenColumns[index] === true] as const,\n ));\n this.#hiddenColumns = event.metadata.schema.columns.map(\n (column) => hiddenById.get(column.id) === true,\n );\n this.#advanceGeneration();\n this.#clampInteraction();\n this.#publish();\n break;\n }\n case \"runtimeError\":\n this.#requestAbort?.abort();\n this.#requestAbort = null;\n this.#loadingRanges = [];\n this.#rebuildSnapshot(\"error\", event.error);\n break;\n case \"closed\":\n this.#tableClosed = true;\n this.#requestAbort?.abort();\n this.#requestAbort = null;\n this.#loadingRanges = [];\n if (this.#snapshot.status !== \"error\") {\n this.#rebuildSnapshot(\"closed\");\n }\n break;\n case \"warning\":\n break;\n }\n }\n\n #clampInteraction(): void {\n if (this.#activeCell === null) {\n return;\n }\n const rowCount = extentValue(this.#table.metadata.extent.rows);\n const columnCount = this.#table.metadata.schema.columns.length;\n const rawActive = clampCell(this.#activeCell, rowCount, columnCount);\n const nextActive = rawActive === null\n ? null\n : this.#visibleCell(this.#mergeAnchor(rawActive), 1, 1);\n if (nextActive === null) {\n this.#activeCell = null;\n this.#selection = null;\n return;\n }\n this.#activeCell = nextActive;\n if (this.#selection !== null) {\n const rawAnchor = clampCell(this.#selection.anchor, rowCount, columnCount)!;\n const rawFocus = clampCell(this.#selection.focus, rowCount, columnCount)!;\n const anchor = this.#visibleCell(this.#mergeAnchor(rawAnchor), 1, 1);\n const focus = this.#visibleCell(this.#mergeAnchor(rawFocus), 1, 1);\n this.#selection = anchor === null || focus === null\n ? null\n : createMergedSelection(anchor, focus, this.#mergedCells);\n }\n }\n\n #layoutOptions(): LayoutOptions {\n return Object.freeze({\n ...this.#options,\n rowEntries: this.#presentationRows,\n hiddenColumns: this.#hiddenColumns,\n frozenRows: this.#frozenRows,\n frozenColumns: this.#frozenColumns,\n });\n }\n\n #mergeAnchor(cell: CellPosition): Readonly<CellPosition> {\n const region = mergeContaining(this.#mergedCells, cell);\n return region === undefined\n ? Object.freeze({ rowIndex: cell.rowIndex, columnIndex: cell.columnIndex })\n : Object.freeze({ rowIndex: region.rowStart, columnIndex: region.columnStart });\n }\n\n #visibleCell(\n cell: CellPosition,\n rowDirection: -1 | 1,\n columnDirection: -1 | 1,\n ): Readonly<CellPosition> | null {\n const layout = this.#snapshot.layout;\n const row = nextVisibleAxisIndex(layout.rowGeometry, cell.rowIndex, rowDirection)\n ?? nextVisibleAxisIndex(layout.rowGeometry, cell.rowIndex, rowDirection === 1 ? -1 : 1);\n if (row === null) return null;\n const column = nextVisibleColumn(\n layout.effectiveColumnWidths,\n cell.columnIndex,\n columnDirection,\n ) ?? nextVisibleColumn(\n layout.effectiveColumnWidths,\n cell.columnIndex,\n columnDirection === 1 ? -1 : 1,\n );\n return column === null ? null : Object.freeze({ rowIndex: row, columnIndex: column });\n }\n\n #normalizeInteractionForPresentation(): void {\n this.#clampInteraction();\n }\n\n #rebuildSnapshot(status: TableViewSnapshot[\"status\"], error?: unknown): void {\n const layout = createTableLayout(\n this.#table.metadata,\n this.#columnWidths,\n this.#viewport,\n this.#layoutOptions(),\n );\n this.#viewport = Object.freeze({\n ...this.#viewport,\n scrollLeft: layout.horizontal.physicalOffset,\n scrollTop: layout.vertical.physicalOffset,\n });\n this.#snapshot = Object.freeze({\n generation: this.#generation,\n status,\n metadata: this.#table.metadata,\n layout,\n activeCell: this.#activeCell,\n selection: this.#selection,\n ...(error === undefined ? {} : { error }),\n });\n this.#emit();\n }\n\n #publish(): void {\n this.#snapshot = Object.freeze({\n ...this.#snapshot,\n activeCell: this.#activeCell,\n selection: this.#selection,\n });\n this.#emit();\n }\n\n #emit(): void {\n for (const listener of this.#listeners) {\n try {\n listener(this.#snapshot);\n } catch (error) {\n if (typeof reportError === \"function\") {\n reportError(error);\n }\n }\n }\n }\n\n #assertOpen(): void {\n if (this.#disposed || this.#tableClosed || this.#snapshot.status === \"closed\") {\n throw closedError(\"Table view controller\");\n }\n }\n}\n\nexport function createTableController(\n table: TableHandle,\n options: TableControllerOptions = {},\n): TableViewController {\n if (!table || typeof table.readRange !== \"function\" || typeof table.subscribe !== \"function\") {\n throw invalidArgument(\"table must be a TableHandle\");\n }\n return new Controller(table, options);\n}\n\nfunction normalizeMergedCells(\n regions: readonly MergedCellRegion[],\n rowCount: number,\n columnCount: number,\n): readonly MergedCellRegion[] {\n const unique = new Map<string, MergedCellRegion>();\n for (const region of regions) {\n if (\n !region\n || !Number.isSafeInteger(region.rowStart)\n || !Number.isSafeInteger(region.rowEnd)\n || !Number.isSafeInteger(region.columnStart)\n || !Number.isSafeInteger(region.columnEnd)\n || region.rowStart < 0\n || region.columnStart < 0\n || region.rowEnd <= region.rowStart\n || region.columnEnd <= region.columnStart\n || region.rowEnd > rowCount\n || region.columnEnd > columnCount\n ) {\n continue;\n }\n const frozen = Object.freeze({ ...region });\n unique.set(mergeKey(frozen), frozen);\n }\n return Object.freeze([...unique.values()].sort(\n (left, right) => left.rowStart - right.rowStart\n || left.columnStart - right.columnStart\n || left.rowEnd - right.rowEnd\n || left.columnEnd - right.columnEnd,\n ));\n}\n\nfunction sameMergedCells(\n left: readonly MergedCellRegion[],\n right: readonly MergedCellRegion[],\n): boolean {\n return left.length === right.length\n && left.every((region, index) => mergeKey(region) === mergeKey(right[index]!));\n}\n\nfunction mergeKey(region: MergedCellRegion): string {\n return `${region.rowStart}:${region.rowEnd}:${region.columnStart}:${region.columnEnd}`;\n}\n\nfunction mergeContaining(\n regions: readonly MergedCellRegion[],\n cell: CellPosition,\n): MergedCellRegion | undefined {\n return regions.find((region) => (\n cell.rowIndex >= region.rowStart\n && cell.rowIndex < region.rowEnd\n && cell.columnIndex >= region.columnStart\n && cell.columnIndex < region.columnEnd\n ));\n}\n\nfunction createMergedSelection(\n anchor: CellPosition,\n focus: CellPosition,\n regions: readonly MergedCellRegion[],\n): Readonly<TableSelection> {\n const selection = createSelection(anchor, focus);\n let range = selection.range;\n for (;;) {\n let expanded = range;\n for (const region of regions) {\n if (!rangesIntersect(expanded, region)) continue;\n expanded = Object.freeze({\n rowStart: Math.min(expanded.rowStart, region.rowStart),\n rowEnd: Math.max(expanded.rowEnd, region.rowEnd),\n columnStart: Math.min(expanded.columnStart, region.columnStart),\n columnEnd: Math.max(expanded.columnEnd, region.columnEnd),\n });\n }\n if (sameGridRange(range, expanded)) break;\n range = expanded;\n }\n return Object.freeze({ ...selection, range });\n}\n\nfunction rangesIntersect(left: GridRange, right: MergedCellRegion): boolean {\n return left.rowStart < right.rowEnd\n && left.rowEnd > right.rowStart\n && left.columnStart < right.columnEnd\n && left.columnEnd > right.columnStart;\n}\n\nfunction navigationOrigin(\n current: CellPosition,\n command: NavigationCommand,\n regions: readonly MergedCellRegion[],\n): Readonly<CellPosition> {\n const merge = mergeContaining(regions, current);\n if (merge === undefined) return current;\n if (command === \"right\") {\n return Object.freeze({ rowIndex: current.rowIndex, columnIndex: merge.columnEnd - 1 });\n }\n if (command === \"down\" || command === \"page-down\") {\n return Object.freeze({ rowIndex: merge.rowEnd - 1, columnIndex: current.columnIndex });\n }\n return current;\n}\n\nfunction navigationDirections(command: NavigationCommand): readonly [-1 | 1, -1 | 1] {\n switch (command) {\n case \"left\":\n case \"row-start\":\n return [1, -1];\n case \"up\":\n case \"page-up\":\n return [-1, 1];\n case \"table-start\":\n return [-1, -1];\n default:\n return [1, 1];\n }\n}\n\nfunction nextVisibleColumn(\n widths: readonly number[],\n from: number,\n direction: -1 | 1,\n): number | null {\n for (\n let index = Math.min(widths.length - 1, Math.max(0, from));\n index >= 0 && index < widths.length;\n index += direction\n ) {\n if ((widths[index] ?? 0) > 0) return index;\n }\n return null;\n}\n\nfunction normalizeOptions(options: TableControllerOptions): NormalizedOptions {\n const minColumnWidth = positiveFinite(\n options.minColumnWidth ?? DEFAULT_MIN_COLUMN_WIDTH,\n \"minColumnWidth\",\n );\n const maxColumnWidth = positiveFinite(\n options.maxColumnWidth ?? DEFAULT_MAX_COLUMN_WIDTH,\n \"maxColumnWidth\",\n );\n if (maxColumnWidth < minColumnWidth) {\n throw invalidArgument(\"maxColumnWidth must be greater than or equal to minColumnWidth\");\n }\n const maxWindowCells = positiveInteger(\n options.maxWindowCells ?? DEFAULT_MAX_WINDOW_CELLS,\n \"maxWindowCells\",\n );\n if (maxWindowCells > MAX_RANGE_CELLS) {\n throw invalidArgument(`maxWindowCells cannot exceed ${MAX_RANGE_CELLS}`);\n }\n return Object.freeze({\n ...(options.rowHeight === undefined ? {} : { rowHeight: options.rowHeight }),\n ...(options.headerHeight === undefined ? {} : { headerHeight: options.headerHeight }),\n ...(options.rowHeaderWidth === undefined ? {} : { rowHeaderWidth: options.rowHeaderWidth }),\n ...(options.scrollPixelLimit === undefined ? {} : { scrollPixelLimit: options.scrollPixelLimit }),\n ...(options.overscanRows === undefined ? {} : { overscanRows: options.overscanRows }),\n ...(options.overscanColumns === undefined ? {} : { overscanColumns: options.overscanColumns }),\n columnWidth: positiveFinite(options.columnWidth ?? DEFAULT_COLUMN_WIDTH, \"columnWidth\"),\n minColumnWidth,\n maxColumnWidth,\n columnWidths: Object.freeze({ ...(options.columnWidths ?? {}) }),\n maxWindowCells,\n });\n}\n\nfunction initialColumnWidths(\n metadata: TableHandle[\"metadata\"],\n options: NormalizedOptions,\n): number[] {\n return metadata.schema.columns.map((column) => clampWidth(\n options.columnWidths[column.id] ?? options.columnWidth,\n options,\n ));\n}\n\nfunction reconcileColumnWidths(\n previousMetadata: TableHandle[\"metadata\"],\n nextMetadata: TableHandle[\"metadata\"],\n previousWidths: readonly number[],\n options: NormalizedOptions,\n): number[] {\n const byId = new Map(previousMetadata.schema.columns.map(\n (column, index) => [column.id, previousWidths[index]!] as const,\n ));\n return nextMetadata.schema.columns.map((column) => clampWidth(\n byId.get(column.id) ?? options.columnWidths[column.id] ?? options.columnWidth,\n options,\n ));\n}\n\nfunction normalizeViewport(viewport: ViewportUpdate): Required<ViewportUpdate> {\n return Object.freeze({\n width: nonNegativeFinite(viewport.width, \"viewport.width\"),\n height: nonNegativeFinite(viewport.height, \"viewport.height\"),\n scrollLeft: nonNegativeFinite(viewport.scrollLeft, \"viewport.scrollLeft\"),\n scrollTop: nonNegativeFinite(viewport.scrollTop, \"viewport.scrollTop\"),\n devicePixelRatio: positiveFinite(viewport.devicePixelRatio ?? 1, \"viewport.devicePixelRatio\"),\n });\n}\n\nfunction layoutRanges(\n layout: TableViewSnapshot[\"layout\"],\n maxCells: number,\n mergedCells: readonly MergedCellRegion[] = [],\n): Readonly<{\n visible: readonly Readonly<GridRange>[];\n overscan: readonly Readonly<GridRange>[];\n}> {\n const visible = windowRectangles(\n layout.rows.visible,\n layout.columns.visible,\n layout.frozenRowRange,\n layout.frozenColumnRange,\n );\n const anchors = mergeAnchorRanges(mergedCells, visible);\n const visibleWithAnchors = Object.freeze([\n ...visible,\n ...anchors.filter((anchor) => !visible.some((range) => rangeContainsRange(range, anchor))),\n ]);\n const visibleCellCount = visibleWithAnchors.reduce(\n (total, range) => total + rangeCellCount(range),\n 0,\n );\n if (visibleCellCount > maxCells) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `The viewport contains ${visibleCellCount} cells; the window limit is ${maxCells}`,\n {\n details: {\n resource: \"viewport-cells\",\n required: visibleCellCount,\n available: maxCells,\n visibleCellCount,\n maxCells,\n },\n },\n );\n }\n const fullOverscan = windowRectangles(\n layout.rows.overscan,\n layout.columns.overscan,\n layout.frozenRowRange,\n layout.frozenColumnRange,\n );\n const overscanCellCount = fullOverscan.reduce(\n (total, range) => total + rangeCellCount(range),\n 0,\n );\n const overscanWithAnchors = Object.freeze([\n ...fullOverscan,\n ...anchors.filter((anchor) => !fullOverscan.some(\n (range) => rangeContainsRange(range, anchor),\n )),\n ]);\n return Object.freeze({\n visible: visibleWithAnchors,\n overscan: overscanCellCount + anchors.length <= maxCells\n ? overscanWithAnchors\n : visibleWithAnchors,\n });\n}\n\nfunction mergeAnchorRanges(\n mergedCells: readonly MergedCellRegion[],\n visible: readonly Readonly<GridRange>[],\n): readonly Readonly<GridRange>[] {\n const anchors = new Map<string, Readonly<GridRange>>();\n for (const region of mergedCells) {\n if (!visible.some((range) => rangesIntersect(range, region))) continue;\n const range = Object.freeze({\n rowStart: region.rowStart,\n rowEnd: region.rowStart + 1,\n columnStart: region.columnStart,\n columnEnd: region.columnStart + 1,\n });\n anchors.set(`${range.rowStart}:${range.columnStart}`, range);\n }\n return Object.freeze([...anchors.values()]);\n}\n\nfunction windowRectangles(\n rows: Readonly<{ start: number; end: number }>,\n columns: Readonly<{ start: number; end: number }>,\n frozenRows: Readonly<{ start: number; end: number }>,\n frozenColumns: Readonly<{ start: number; end: number }>,\n): readonly Readonly<GridRange>[] {\n const rowBands = mergeIndexBands(rows, frozenRows);\n const columnBands = mergeIndexBands(columns, frozenColumns);\n const rectangles: GridRange[] = [];\n for (const row of rowBands) {\n for (const column of columnBands) {\n rectangles.push(Object.freeze({\n rowStart: row.start,\n rowEnd: row.end,\n columnStart: column.start,\n columnEnd: column.end,\n }));\n }\n }\n return Object.freeze(rectangles);\n}\n\nfunction mergeIndexBands(\n primary: Readonly<{ start: number; end: number }>,\n frozen: Readonly<{ start: number; end: number }>,\n): readonly Readonly<{ start: number; end: number }>[] {\n const bands = [primary, frozen]\n .filter((range) => range.start < range.end)\n .sort((left, right) => left.start - right.start);\n if (bands.length <= 1) return Object.freeze(bands.map((range) => Object.freeze({ ...range })));\n const [first, second] = bands as [typeof primary, typeof primary];\n return first.end >= second.start\n ? Object.freeze([Object.freeze({ start: first.start, end: Math.max(first.end, second.end) })])\n : Object.freeze(bands.map((range) => Object.freeze({ ...range })));\n}\n\nfunction gridRangeToRequest(range: GridRange): Readonly<RangeRequest> {\n return Object.freeze({\n rowStart: range.rowStart,\n rowCount: range.rowEnd - range.rowStart,\n columnStart: range.columnStart,\n columnCount: range.columnEnd - range.columnStart,\n });\n}\n\nfunction batchGridRange(batch: TableBatch): Readonly<GridRange> {\n return Object.freeze({\n rowStart: batch.range.rowStart,\n rowEnd: batch.range.rowStart + batch.range.rowCount,\n columnStart: batch.range.columnStart,\n columnEnd: batch.range.columnStart + batch.range.columnCount,\n });\n}\n\nfunction batchRows(batch: TableBatch): readonly (readonly (string | null)[])[] {\n return Object.freeze(batch.toDisplayRows({\n maxCells: Math.max(1, batch.range.rowCount * batch.range.columnCount),\n }).map((row) => Object.freeze(row)));\n}\n\nfunction rowsToTsv(rows: readonly (readonly (string | null)[])[]): string {\n return rows.map((row) => row.map(tsvField).join(\"\\t\")).join(\"\\n\");\n}\n\nfunction tsvField(value: string | null): string {\n if (value === null) {\n return \"\";\n }\n return /[\\t\\r\\n\"]/.test(value) ? `\"${value.replaceAll('\"', '\"\"')}\"` : value;\n}\n\nfunction revealOffset(\n current: number,\n viewportSize: number,\n itemStart: number,\n itemEnd: number,\n maximum: number,\n): number {\n if (viewportSize <= 0 || itemStart < current) {\n return Math.min(maximum, Math.max(0, itemStart));\n }\n if (itemEnd > current + viewportSize) {\n return Math.min(maximum, Math.max(0, itemEnd - viewportSize));\n }\n return current;\n}\n\nfunction rangeContains(range: GridRange, rowIndex: number, columnIndex: number): boolean {\n return rowIndex >= range.rowStart && rowIndex < range.rowEnd\n && columnIndex >= range.columnStart && columnIndex < range.columnEnd;\n}\n\nfunction rangeContainsRange(container: GridRange, candidate: GridRange): boolean {\n return candidate.rowStart >= container.rowStart\n && candidate.rowEnd <= container.rowEnd\n && candidate.columnStart >= container.columnStart\n && candidate.columnEnd <= container.columnEnd;\n}\n\nfunction rangeCellCount(range: GridRange): number {\n return (range.rowEnd - range.rowStart) * (range.columnEnd - range.columnStart);\n}\n\nfunction sameGridRange(left: GridRange, right: GridRange | null): boolean {\n return right !== null\n && left.rowStart === right.rowStart\n && left.rowEnd === right.rowEnd\n && left.columnStart === right.columnStart\n && left.columnEnd === right.columnEnd;\n}\n\nfunction sameViewport(left: Required<ViewportUpdate>, right: Required<ViewportUpdate>): boolean {\n return left.width === right.width\n && left.height === right.height\n && left.scrollLeft === right.scrollLeft\n && left.scrollTop === right.scrollTop\n && left.devicePixelRatio === right.devicePixelRatio;\n}\n\nfunction isValidCell(\n rowIndex: number,\n columnIndex: number,\n rowCount: number,\n columnCount: number,\n): boolean {\n return Number.isSafeInteger(rowIndex) && rowIndex >= 0 && rowIndex < rowCount\n && Number.isSafeInteger(columnIndex) && columnIndex >= 0 && columnIndex < columnCount;\n}\n\nfunction assertColumnIndex(columnIndex: number, columnCount: number): void {\n if (!Number.isSafeInteger(columnIndex) || columnIndex < 0 || columnIndex >= columnCount) {\n throw invalidArgument(`columnIndex must be between 0 and ${Math.max(0, columnCount - 1)}`);\n }\n}\n\nfunction assertWindowCellLimit(request: RangeRequest, limit: number, label: string): void {\n const cells = request.rowCount * request.columnCount;\n if (!Number.isSafeInteger(cells) || cells > limit) {\n throw new TabularkError(\n \"RESOURCE_LIMIT\",\n `The ${label} contains ${cells} cells; the limit is ${limit}`,\n {\n details: {\n resource: \"view-window-cells\",\n required: cells,\n available: limit,\n cells,\n limit,\n },\n },\n );\n }\n}\n\nfunction clampWidth(width: number, options: NormalizedOptions): number {\n if (!Number.isFinite(width)) {\n throw invalidArgument(\"column width must be a finite number\");\n }\n return Math.min(options.maxColumnWidth, Math.max(options.minColumnWidth, width));\n}\n\nfunction positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) {\n throw invalidArgument(`${name} must be a positive finite number`);\n }\n return value;\n}\n\nfunction nonNegativeFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw invalidArgument(`${name} must be a non-negative finite number`);\n }\n return value;\n}\n\nfunction positiveInteger(value: number, name: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw invalidArgument(`${name} must be a positive safe integer`);\n }\n return value;\n}\n", "import type { TableHandle } from \"../client.js\";\nimport type {\n MergedCellRegion,\n PresentationRange,\n PresentationStyle,\n RangeRequest,\n SpreadsheetPresentation,\n} from \"../model.js\";\nimport { TabularkError, invalidArgument } from \"../errors.js\";\nimport { containsCell } from \"./selection.js\";\nimport { AccessibleViewportGrid, type AccessibleGridRow } from \"./accessible-grid.js\";\nimport {\n CanvasTablePainter,\n DEFAULT_CANVAS_TABLE_THEME,\n forcedColorsCanvasTableTheme,\n type CanvasPaintColumn,\n type CanvasPaintMergedCell,\n type CanvasPaintRow,\n type CanvasTableTheme,\n} from \"./canvas-painter.js\";\nimport { createTableController, type TableViewController } from \"./controller.js\";\nimport type {\n CellPosition,\n NavigationCommand,\n TableControllerOptions,\n TableViewSnapshot,\n} from \"./types.js\";\n\nconst RESIZE_HANDLE_WIDTH = 8;\nconst RESIZE_TARGET_SIZE = 44;\nconst KEYBOARD_RESIZE_STEP = 8;\nconst KEYBOARD_RESIZE_COARSE_STEP = 32;\nconst AUTOSIZE_HORIZONTAL_PADDING = 24;\nconst MAX_PRESENTATION_WINDOW_CELLS = 100_000;\n\n/**\n * Palette used when a high-level view is explicitly or automatically dark.\n * Keep these tokens aligned with the Playground's dark CSS palette so the\n * Canvas surface does not look like a separate theme from its host page.\n */\nconst DARK_CANVAS_TABLE_THEME: Readonly<CanvasTableTheme> = Object.freeze({\n background: \"#182235\",\n foreground: \"#edf0f7\",\n mutedForeground: \"#b5c0d4\",\n headerBackground: \"#202c42\",\n headerForeground: \"#edf0f7\",\n alternateRowBackground: \"#202c42\",\n gridLine: \"#526079\",\n selectionBackground: \"rgba(167, 139, 250, 0.24)\",\n selectionBorder: \"#a78bfa\",\n activeCellBorder: \"#c4b5fd\",\n loadingBackground: \"#526079\",\n font: '13px ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n headerFont: '600 13px ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n});\n\ntype CanvasColorScheme = \"auto\" | \"light\" | \"dark\";\ntype ResolvedCanvasColorScheme = Exclude<CanvasColorScheme, \"auto\">;\n\nlet nextViewId = 1;\n\nexport interface CanvasTableViewOptions {\n readonly container: HTMLElement;\n /** Provide either a table or a preconfigured controller, never both. */\n readonly table?: TableHandle;\n /** Provide either a controller or a table, never both. */\n readonly controller?: TableViewController;\n readonly controllerOptions?: TableControllerOptions;\n /**\n * Selects the table palette. `light` is the compatibility default;\n * `auto` follows the browser's `prefers-color-scheme` media query.\n * Forced-colors mode always takes precedence over this setting.\n */\n readonly colorScheme?: CanvasColorScheme;\n /**\n * Applies static spreadsheet sizing metadata when a TableHandle provides it.\n * Workbook colors never override the system palette in forced-colors mode.\n */\n readonly presentation?: \"auto\" | \"ignore\";\n readonly ariaLabel?: string;\n readonly theme?: Partial<CanvasTableTheme>;\n readonly maxDevicePixelRatio?: number;\n /** Testable clipboard seam; navigator.clipboard.writeText is used by default. */\n readonly writeClipboard?: (text: string) => Promise<void> | void;\n readonly onError?: (error: unknown) => void;\n}\n\nexport interface CanvasTableView {\n readonly element: HTMLDivElement;\n readonly controller: TableViewController;\n focus(options?: FocusOptions): void;\n destroy(): void;\n dispose(): void;\n}\n\ntype PointerInteraction =\n | Readonly<{\n kind: \"resize\";\n pointerId: number;\n columnIndex: number;\n startClientX: number;\n startWidth: number;\n }>\n | Readonly<{\n kind: \"select\";\n pointerId: number;\n anchor: Readonly<CellPosition>;\n }>;\n\nclass View implements CanvasTableView {\n readonly element: HTMLDivElement;\n readonly controller: TableViewController;\n\n readonly #scrollHost: HTMLDivElement;\n readonly #spacer: HTMLDivElement;\n readonly #surface: HTMLDivElement;\n readonly #canvas: HTMLCanvasElement;\n readonly #resizeLayer: HTMLDivElement;\n readonly #resizeInstructions: HTMLDivElement;\n readonly #message: HTMLDivElement;\n readonly #accessibleGrid: AccessibleViewportGrid;\n readonly #painter: CanvasTablePainter;\n readonly #ownerWindow: Window & typeof globalThis;\n readonly #ownsController: boolean;\n readonly #writeClipboard: ((text: string) => Promise<void> | void) | undefined;\n readonly #onError: ((error: unknown) => void) | undefined;\n readonly #themeOverrides: Readonly<Partial<CanvasTableTheme>>;\n readonly #colorScheme: CanvasColorScheme;\n readonly #colorSchemeQuery: MediaQueryList | undefined;\n readonly #presentationTable: TableHandle | undefined;\n #theme: Readonly<CanvasTableTheme>;\n readonly #forcedColorsQuery: MediaQueryList;\n readonly #unsubscribe: () => void;\n readonly #resizeObserver?: ResizeObserver;\n readonly #resizeHandles = new Map<string, HTMLDivElement>();\n\n #snapshot: Readonly<TableViewSnapshot>;\n #frame = 0;\n #interaction: PointerInteraction | null = null;\n #copyAbort: AbortController | null = null;\n #announcementFrame = 0;\n #forcedColors = false;\n #resolvedColorScheme: ResolvedCanvasColorScheme = \"light\";\n #presentation: SpreadsheetPresentation | null = null;\n #presentationRanges: readonly PresentationRange[] = [];\n #mergedCells: readonly MergedCellRegion[] = [];\n #presentationRequestKey = \"\";\n #presentationAbort: AbortController | null = null;\n #destroyed = false;\n\n constructor(options: CanvasTableViewOptions) {\n const ownerDocument = options.container.ownerDocument;\n const ownerWindow = ownerDocument.defaultView;\n if (ownerWindow === null) {\n throw invalidArgument(\"container must belong to an active browser document\");\n }\n this.#ownerWindow = ownerWindow;\n const presentation = options.presentation ?? \"auto\";\n if (presentation !== \"auto\" && presentation !== \"ignore\") {\n throw invalidArgument(\"presentation must be auto or ignore\");\n }\n const colorScheme = options.colorScheme ?? \"light\";\n if (colorScheme !== \"auto\" && colorScheme !== \"light\" && colorScheme !== \"dark\") {\n throw invalidArgument(\"colorScheme must be auto, light, or dark\");\n }\n this.#ownsController = options.table !== undefined;\n this.controller = options.controller\n ?? createTableController(options.table!, options.controllerOptions);\n this.#snapshot = this.controller.getSnapshot();\n this.#writeClipboard = options.writeClipboard;\n this.#onError = options.onError;\n this.#presentationTable = presentation === \"auto\" ? options.table : undefined;\n this.#colorScheme = colorScheme;\n this.#themeOverrides = Object.freeze({ ...options.theme });\n this.#forcedColorsQuery = ownerWindow.matchMedia(\"(forced-colors: active)\");\n this.#forcedColors = this.#forcedColorsQuery.matches;\n this.#colorSchemeQuery = colorScheme === \"auto\"\n ? ownerWindow.matchMedia(\"(prefers-color-scheme: dark)\")\n : undefined;\n this.#resolvedColorScheme = colorScheme === \"dark\"\n ? \"dark\"\n : colorScheme === \"auto\" && this.#colorSchemeQuery?.matches === true\n ? \"dark\"\n : \"light\";\n this.#theme = this.#resolveTheme();\n\n this.element = ownerDocument.createElement(\"div\");\n this.element.className = \"tabulark-view\";\n this.element.dataset.tabularkView = \"\";\n this.element.setAttribute(\"aria-label\", options.ariaLabel ?? this.#tableLabel());\n Object.assign(this.element.style, {\n background: this.#theme.background,\n border: `1px solid ${this.#theme.gridLine}`,\n borderRadius: \"6px\",\n boxSizing: \"border-box\",\n color: this.#theme.foreground,\n contain: \"layout paint style\",\n height: \"100%\",\n minHeight: \"120px\",\n minWidth: \"0\",\n overflow: \"hidden\",\n position: \"relative\",\n width: \"100%\",\n });\n\n this.#scrollHost = ownerDocument.createElement(\"div\");\n this.#scrollHost.className = \"tabulark-scroll\";\n this.#scrollHost.dataset.tabularkScroll = \"\";\n this.#scrollHost.tabIndex = -1;\n Object.assign(this.#scrollHost.style, {\n inset: \"0\",\n overflow: \"auto\",\n overscrollBehavior: \"contain\",\n position: \"absolute\",\n scrollbarGutter: \"stable\",\n });\n\n this.#spacer = ownerDocument.createElement(\"div\");\n this.#spacer.className = \"tabulark-scroll-spacer\";\n this.#spacer.dataset.tabularkScrollSpacer = \"\";\n this.#spacer.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(this.#spacer.style, {\n left: \"0\",\n pointerEvents: \"none\",\n position: \"absolute\",\n top: \"0\",\n });\n\n this.#surface = ownerDocument.createElement(\"div\");\n this.#surface.className = \"tabulark-surface\";\n this.#surface.dataset.tabularkSurface = \"\";\n Object.assign(this.#surface.style, {\n left: \"0\",\n position: \"sticky\",\n top: \"0\",\n userSelect: \"none\",\n zIndex: \"1\",\n });\n\n this.#canvas = ownerDocument.createElement(\"canvas\");\n this.#canvas.className = \"tabulark-canvas\";\n this.#canvas.dataset.tabularkCanvas = \"\";\n this.#canvas.setAttribute(\"aria-hidden\", \"true\");\n this.#canvas.draggable = false;\n Object.assign(this.#canvas.style, {\n cursor: \"default\",\n display: \"block\",\n touchAction: \"pan-x pan-y\",\n });\n\n this.#resizeLayer = ownerDocument.createElement(\"div\");\n this.#resizeLayer.className = \"tabulark-resize-layer\";\n Object.assign(this.#resizeLayer.style, {\n left: \"0\",\n pointerEvents: \"none\",\n position: \"absolute\",\n top: \"0\",\n width: \"100%\",\n });\n\n this.#resizeInstructions = ownerDocument.createElement(\"div\");\n this.#resizeInstructions.id = `tabulark-resize-instructions-${nextViewId}`;\n nextViewId += 1;\n this.#resizeInstructions.textContent = \"Use Left and Right Arrow keys to resize. Hold Shift for larger steps. Home and End use the minimum and maximum widths. Enter fits the visible content.\";\n visuallyHide(this.#resizeInstructions);\n\n this.#message = ownerDocument.createElement(\"div\");\n this.#message.className = \"tabulark-message\";\n this.#message.dataset.tabularkMessage = \"\";\n this.#message.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(this.#message.style, {\n alignItems: \"center\",\n background: this.#theme.background,\n color: this.#theme.mutedForeground,\n display: \"none\",\n font: this.#theme.font,\n inset: \"0\",\n justifyContent: \"center\",\n padding: \"24px\",\n pointerEvents: \"none\",\n position: \"absolute\",\n textAlign: \"center\",\n zIndex: \"2\",\n });\n\n this.#accessibleGrid = new AccessibleViewportGrid(\n ownerDocument,\n options.ariaLabel ?? this.#tableLabel(),\n );\n this.#painter = new CanvasTablePainter(this.#canvas, {\n theme: this.#theme,\n forcedColors: this.#forcedColors,\n ...(options.maxDevicePixelRatio === undefined\n ? {}\n : { maxDevicePixelRatio: options.maxDevicePixelRatio }),\n });\n this.#applyThemeToElements();\n\n this.#surface.append(this.#canvas, this.#resizeLayer);\n this.#scrollHost.append(this.#spacer, this.#surface);\n this.element.append(\n this.#scrollHost,\n this.#message,\n this.#accessibleGrid.element,\n this.#accessibleGrid.statusElement,\n this.#resizeInstructions,\n );\n options.container.append(this.element);\n\n this.#unsubscribe = this.controller.subscribe((snapshot) => {\n this.#snapshot = snapshot;\n if (this.#isTerminal()) {\n if (this.#resizeLayer.contains(this.element.ownerDocument.activeElement)) {\n this.#accessibleGrid.focus({ preventScroll: true });\n }\n this.#cancelInteraction();\n this.#copyAbort?.abort();\n this.#copyAbort = null;\n }\n this.#schedulePresentationRanges();\n this.#scheduleFrame();\n });\n this.#scrollHost.addEventListener(\"scroll\", this.#onScroll, { passive: true });\n this.#surface.addEventListener(\"pointerdown\", this.#onPointerDown);\n this.#surface.addEventListener(\"pointermove\", this.#onPointerMove);\n this.#surface.addEventListener(\"pointerup\", this.#onPointerUp);\n this.#surface.addEventListener(\"pointercancel\", this.#onPointerUp);\n this.#surface.addEventListener(\"dblclick\", this.#onDoubleClick);\n this.element.addEventListener(\"keydown\", this.#onKeyDown);\n this.element.addEventListener(\"focusin\", this.#onFocusIn);\n this.element.addEventListener(\"focusout\", this.#onFocusOut);\n addMediaQueryListener(this.#forcedColorsQuery, this.#onForcedColorsChange);\n if (this.#colorSchemeQuery !== undefined) {\n addMediaQueryListener(this.#colorSchemeQuery, this.#onColorSchemeChange);\n }\n\n if (typeof ownerWindow.ResizeObserver === \"function\") {\n this.#resizeObserver = new ownerWindow.ResizeObserver(() => this.#updateViewport());\n this.#resizeObserver.observe(this.#scrollHost);\n } else {\n ownerWindow.addEventListener(\"resize\", this.#onWindowResize);\n }\n\n this.#updateViewport();\n this.#scheduleFrame();\n if (this.#presentationTable !== undefined) {\n void this.#applyPresentation(this.#presentationTable);\n }\n }\n\n focus(options?: FocusOptions): void {\n this.#assertAlive();\n this.#accessibleGrid.focus(options);\n }\n\n destroy(): void {\n if (this.#destroyed) {\n return;\n }\n this.#destroyed = true;\n this.#presentationAbort?.abort();\n this.#presentationAbort = null;\n this.#copyAbort?.abort();\n this.#copyAbort = null;\n if (this.#frame !== 0) {\n this.#ownerWindow.cancelAnimationFrame(this.#frame);\n this.#frame = 0;\n }\n if (this.#announcementFrame !== 0) {\n this.#ownerWindow.cancelAnimationFrame(this.#announcementFrame);\n this.#announcementFrame = 0;\n }\n this.#resizeObserver?.disconnect();\n this.#ownerWindow.removeEventListener(\"resize\", this.#onWindowResize);\n this.#unsubscribe();\n this.#scrollHost.removeEventListener(\"scroll\", this.#onScroll);\n this.#surface.removeEventListener(\"pointerdown\", this.#onPointerDown);\n this.#surface.removeEventListener(\"pointermove\", this.#onPointerMove);\n this.#surface.removeEventListener(\"pointerup\", this.#onPointerUp);\n this.#surface.removeEventListener(\"pointercancel\", this.#onPointerUp);\n this.#surface.removeEventListener(\"dblclick\", this.#onDoubleClick);\n this.element.removeEventListener(\"keydown\", this.#onKeyDown);\n this.element.removeEventListener(\"focusin\", this.#onFocusIn);\n this.element.removeEventListener(\"focusout\", this.#onFocusOut);\n removeMediaQueryListener(this.#forcedColorsQuery, this.#onForcedColorsChange);\n if (this.#colorSchemeQuery !== undefined) {\n removeMediaQueryListener(this.#colorSchemeQuery, this.#onColorSchemeChange);\n }\n this.#accessibleGrid.destroy();\n this.element.remove();\n if (this.#ownsController) {\n this.controller.dispose();\n }\n }\n\n dispose(): void {\n this.destroy();\n }\n\n readonly #onScroll = (): void => {\n this.#updateViewport();\n };\n\n readonly #onWindowResize = (): void => {\n this.#updateViewport();\n };\n\n readonly #onForcedColorsChange = (event: MediaQueryListEvent): void => {\n if (this.#destroyed) {\n return;\n }\n this.#forcedColors = event.matches;\n this.#theme = this.#resolveTheme();\n this.#painter.setTheme(this.#theme, { forcedColors: this.#forcedColors });\n this.#applyThemeToElements();\n this.#scheduleFrame();\n };\n\n readonly #onColorSchemeChange = (event: MediaQueryListEvent): void => {\n if (this.#destroyed || this.#colorScheme !== \"auto\") {\n return;\n }\n this.#resolvedColorScheme = event.matches ? \"dark\" : \"light\";\n this.#theme = this.#resolveTheme();\n this.#painter.setTheme(this.#theme, { forcedColors: this.#forcedColors });\n this.#applyThemeToElements();\n this.#scheduleFrame();\n };\n\n readonly #onFocusIn = (event: FocusEvent): void => {\n this.element.style.outline = `2px solid ${this.#focusColor()}`;\n this.element.style.outlineOffset = \"-2px\";\n const resizeHandle = this.#resizeHandleFromTarget(event.target);\n if (resizeHandle !== null) {\n resizeHandle.style.outline = `2px solid ${this.#focusColor()}`;\n resizeHandle.style.outlineOffset = \"-2px\";\n return;\n }\n if (\n !this.#isTerminal()\n && this.#snapshot.activeCell === null\n && this.#hasCells()\n && event.target === this.#accessibleGrid.element\n ) {\n this.controller.setActiveCell({ rowIndex: 0, columnIndex: 0 });\n }\n };\n\n readonly #onFocusOut = (event: FocusEvent): void => {\n const resizeHandle = this.#resizeHandleFromTarget(event.target);\n if (resizeHandle !== null) {\n resizeHandle.style.outline = \"none\";\n }\n queueMicrotask(() => {\n if (!this.#destroyed && !this.element.contains(this.element.ownerDocument.activeElement)) {\n this.element.style.outline = \"none\";\n }\n });\n };\n\n readonly #onPointerDown = (event: PointerEvent): void => {\n if (event.button !== 0 || this.#isTerminal()) {\n return;\n }\n const position = this.#eventPosition(event);\n const resizeColumn = this.#resizeColumnFromTarget(event.target);\n const hit = resizeColumn === null\n ? this.controller.hitTest(position.x, position.y, RESIZE_HANDLE_WIDTH / 2)\n : { kind: \"column-resize\" as const, columnIndex: resizeColumn, boundaryX: position.x };\n\n if (hit.kind === \"column-resize\") {\n event.preventDefault();\n this.#interaction = Object.freeze({\n kind: \"resize\",\n pointerId: event.pointerId,\n columnIndex: hit.columnIndex,\n startClientX: event.clientX,\n startWidth: this.controller.columnWidths[hit.columnIndex]!,\n });\n this.#surface.setPointerCapture(event.pointerId);\n this.#surface.style.cursor = \"col-resize\";\n return;\n }\n\n const cell = this.#cellFromHit(hit);\n if (cell === null) {\n return;\n }\n this.focus({ preventScroll: true });\n this.controller.setActiveCell(cell, {\n extendSelection: event.shiftKey,\n scrollIntoView: false,\n });\n if (event.pointerType !== \"touch\") {\n this.#interaction = Object.freeze({\n kind: \"select\",\n pointerId: event.pointerId,\n anchor: event.shiftKey && this.#snapshot.selection !== null\n ? this.#snapshot.selection.anchor\n : cell,\n });\n this.#surface.setPointerCapture(event.pointerId);\n }\n };\n\n readonly #onPointerMove = (event: PointerEvent): void => {\n if (this.#isTerminal()) {\n this.#cancelInteraction();\n return;\n }\n if (this.#interaction?.pointerId === event.pointerId) {\n if (this.#interaction.kind === \"resize\") {\n const delta = event.clientX - this.#interaction.startClientX;\n this.controller.resizeColumn(\n this.#interaction.columnIndex,\n this.#interaction.startWidth + delta,\n );\n return;\n }\n const position = this.#eventPosition(event);\n const hit = this.controller.hitTest(position.x, position.y, 0);\n if (hit.kind === \"cell\") {\n this.controller.setSelection(this.#interaction.anchor, {\n rowIndex: hit.rowIndex,\n columnIndex: hit.columnIndex,\n });\n }\n return;\n }\n\n const position = this.#eventPosition(event);\n const hit = this.controller.hitTest(position.x, position.y, RESIZE_HANDLE_WIDTH / 2);\n this.#surface.style.cursor = hit.kind === \"column-resize\" ? \"col-resize\" : \"default\";\n };\n\n readonly #onPointerUp = (event: PointerEvent): void => {\n if (this.#interaction?.pointerId !== event.pointerId) {\n return;\n }\n const resizedColumn = this.#interaction.kind === \"resize\"\n ? this.#interaction.columnIndex\n : null;\n if (this.#surface.hasPointerCapture(event.pointerId)) {\n this.#surface.releasePointerCapture(event.pointerId);\n }\n this.#interaction = null;\n this.#surface.style.cursor = \"default\";\n if (resizedColumn !== null) {\n this.controller.ensureColumnVisible(resizedColumn);\n this.#announceColumnWidth(resizedColumn, false);\n }\n };\n\n readonly #onDoubleClick = (event: MouseEvent): void => {\n if (this.#isTerminal()) {\n return;\n }\n const position = this.#eventPosition(event);\n const fromTarget = this.#resizeColumnFromTarget(event.target);\n const hit = fromTarget === null\n ? this.controller.hitTest(position.x, position.y, RESIZE_HANDLE_WIDTH / 2)\n : { kind: \"column-resize\" as const, columnIndex: fromTarget };\n if (hit.kind !== \"column-resize\") {\n return;\n }\n event.preventDefault();\n this.controller.autosizeColumn(hit.columnIndex, this.#measureColumn(hit.columnIndex));\n this.controller.ensureColumnVisible(hit.columnIndex);\n this.#announceColumnWidth(hit.columnIndex, true);\n };\n\n readonly #onKeyDown = (event: KeyboardEvent): void => {\n const resizeColumn = this.#resizeColumnFromTarget(event.target);\n if (resizeColumn !== null) {\n if (this.#handleResizeKeyDown(event, resizeColumn)) {\n return;\n }\n if (keyboardCommand(event) !== null) {\n return;\n }\n }\n if (this.#isTerminal() || event.altKey) {\n return;\n }\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === \"c\") {\n event.preventDefault();\n void this.#copySelection();\n return;\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n this.controller.clearSelection();\n return;\n }\n const command = keyboardCommand(event);\n if (command === null) {\n return;\n }\n event.preventDefault();\n this.controller.moveActive(command, {\n extendSelection: event.shiftKey,\n scrollIntoView: true,\n });\n };\n\n #handleResizeKeyDown(event: KeyboardEvent, columnIndex: number): boolean {\n if (this.#isTerminal() || event.altKey || event.ctrlKey || event.metaKey) {\n return false;\n }\n const width = this.controller.columnWidths[columnIndex];\n if (width === undefined) {\n return false;\n }\n const step = event.shiftKey ? KEYBOARD_RESIZE_COARSE_STEP : KEYBOARD_RESIZE_STEP;\n let nextWidth: number | null = null;\n switch (event.key) {\n case \"ArrowLeft\":\n nextWidth = width - step;\n break;\n case \"ArrowRight\":\n nextWidth = width + step;\n break;\n case \"Home\":\n nextWidth = this.controller.minColumnWidth;\n break;\n case \"End\":\n nextWidth = this.controller.maxColumnWidth;\n break;\n case \"Enter\":\n nextWidth = this.#measureColumn(columnIndex);\n break;\n default:\n return false;\n }\n event.preventDefault();\n event.stopPropagation();\n if (event.key === \"Enter\") {\n this.controller.autosizeColumn(columnIndex, nextWidth);\n } else {\n this.controller.resizeColumn(columnIndex, nextWidth);\n }\n this.controller.ensureColumnVisible(columnIndex);\n this.#announceColumnWidth(columnIndex, event.key === \"Enter\");\n return true;\n }\n\n #updateViewport(): void {\n if (this.#isTerminal()) {\n return;\n }\n const width = this.#scrollHost.clientWidth;\n const height = this.#scrollHost.clientHeight;\n this.#surface.style.width = `${width}px`;\n this.#surface.style.height = `${height}px`;\n this.controller.updateViewport({\n width,\n height,\n scrollLeft: this.#scrollHost.scrollLeft,\n scrollTop: this.#scrollHost.scrollTop,\n devicePixelRatio: this.#ownerWindow.devicePixelRatio || 1,\n });\n }\n\n #scheduleFrame(): void {\n if (this.#destroyed || this.#frame !== 0) {\n return;\n }\n this.#frame = this.#ownerWindow.requestAnimationFrame(() => {\n this.#frame = 0;\n this.#render();\n });\n }\n\n async #applyPresentation(table: TableHandle): Promise<void> {\n try {\n const presentation = await table.getPresentation();\n if (this.#destroyed || presentation === null) {\n return;\n }\n this.#presentation = presentation;\n this.#applySpreadsheetPresentation(presentation);\n } catch (error) {\n // Presentation is an enhancement over the logical table contract. A\n // malformed or unavailable layout must not make the table inaccessible.\n if (!this.#destroyed) {\n this.#onError?.(error);\n }\n }\n }\n\n #applySpreadsheetPresentation(presentation: SpreadsheetPresentation): void {\n this.element.dataset.tabularkPresentation = presentation.kind;\n this.element.dataset.tabularkWorksheetVisibility = presentation.visibility;\n this.element.dataset.tabularkFrozenRows = String(presentation.frozenRows);\n this.element.dataset.tabularkFrozenColumns = String(presentation.frozenColumns);\n\n this.controller.applySpreadsheetPresentation(presentation);\n this.#schedulePresentationRanges();\n this.#scheduleFrame();\n }\n\n #schedulePresentationRanges(): void {\n const table = this.#presentationTable;\n const presentation = this.#presentation;\n if (this.#destroyed || table === undefined || presentation === null) return;\n const requests = presentationRequests(this.#snapshot.layout);\n const key = `${presentation.tableId}:${presentation.revision}:${requests.map(rangeKey).join(\"|\")}`;\n if (key === this.#presentationRequestKey) return;\n this.#presentationRequestKey = key;\n this.#presentationAbort?.abort();\n this.#presentationAbort = null;\n if (requests.length === 0) {\n this.#presentationRanges = [];\n this.#mergedCells = [];\n this.controller.setMergedCells([]);\n this.#scheduleFrame();\n return;\n }\n const abort = new AbortController();\n this.#presentationAbort = abort;\n void (async () => {\n const viewportRanges = await Promise.all(requests.map((request) => (\n table.readPresentationRange(request, { signal: abort.signal })\n )));\n const currentRanges = viewportRanges.filter(\n (range): range is PresentationRange => range !== null\n && range.revision === presentation.revision,\n );\n const anchorRequests = missingMergeAnchorRequests(\n collectMergedRegions(currentRanges),\n currentRanges,\n );\n const anchorRanges = await Promise.all(anchorRequests.map((request) => (\n table.readPresentationRange(request, { signal: abort.signal })\n )));\n return [...viewportRanges, ...anchorRanges];\n })().then((ranges) => {\n if (\n this.#destroyed\n || abort.signal.aborted\n || this.#presentationAbort !== abort\n || this.#presentationRequestKey !== key\n ) {\n return;\n }\n this.#presentationAbort = null;\n this.#presentationRanges = Object.freeze(ranges.filter(\n (range): range is PresentationRange => range !== null\n && range.revision === presentation.revision,\n ));\n this.#mergedCells = collectMergedRegions(this.#presentationRanges);\n this.controller.setMergedCells(this.#mergedCells);\n this.#scheduleFrame();\n }).catch((error) => {\n if (this.#presentationAbort === abort) this.#presentationAbort = null;\n if (\n this.#destroyed\n || abort.signal.aborted\n || (error instanceof TabularkError && error.code === \"CANCELLED\")\n ) {\n return;\n }\n this.#onError?.(error);\n });\n }\n\n #mergedRegions(): readonly MergedCellRegion[] {\n return this.#mergedCells;\n }\n\n #render(): void {\n if (this.#destroyed) {\n return;\n }\n const snapshot = this.#snapshot;\n const layout = snapshot.layout;\n this.#spacer.style.width = `${Math.max(layout.width, layout.spacerWidth)}px`;\n this.#spacer.style.height = `${Math.max(layout.height, layout.spacerHeight)}px`;\n this.#surface.style.width = `${layout.width}px`;\n this.#surface.style.height = `${layout.height}px`;\n this.#syncNativeScroll(snapshot);\n\n const columns: readonly CanvasPaintColumn[] = layout.overscanColumns.map((column) => ({\n index: column.index,\n name: column.name,\n x: column.x,\n width: column.width,\n frozen: column.frozen,\n }));\n const rows = this.#paintRows(snapshot, columns);\n const mergedCells = this.#paintMergedCells();\n this.#painter.paint({\n width: layout.width,\n height: layout.height,\n headerHeight: layout.headerHeight,\n rowGutterWidth: layout.rowHeaderWidth,\n columns,\n rows,\n mergedCells,\n ...(snapshot.selection === null ? {} : { selection: snapshot.selection.range }),\n ...(snapshot.activeCell === null\n ? {}\n : {\n activeCell: {\n rowIndex: snapshot.activeCell.rowIndex,\n columnIndex: snapshot.activeCell.columnIndex,\n },\n }),\n busy: snapshot.status === \"loading\",\n });\n this.#renderResizeHandles(snapshot);\n this.#renderAccessibleGrid(snapshot);\n this.#renderMessage(snapshot);\n }\n\n #paintRows(\n snapshot: Readonly<TableViewSnapshot>,\n columns: readonly CanvasPaintColumn[],\n ): readonly CanvasPaintRow[] {\n const layout = snapshot.layout;\n const rows: CanvasPaintRow[] = [];\n for (const row of layout.overscanRows) {\n const rowIndex = row.index;\n rows.push({\n index: rowIndex,\n y: row.y,\n height: row.height,\n frozen: row.frozen,\n cells: columns.map((column) => {\n const cell = this.controller.getCell(rowIndex, column.index);\n return {\n columnIndex: column.index,\n value: cell.status === \"loaded\" ? cell.value : undefined,\n ...(this.#styleAt(rowIndex, column.index) === undefined\n ? {}\n : { style: this.#styleAt(rowIndex, column.index)! }),\n ...(this.#mergeContaining(rowIndex, column.index) === undefined\n ? {}\n : { coveredByMerge: true }),\n };\n }),\n });\n }\n return rows;\n }\n\n #paintMergedCells(): readonly CanvasPaintMergedCell[] {\n const result: CanvasPaintMergedCell[] = [];\n const layout = this.#snapshot.layout;\n for (const region of this.#mergedRegions()) {\n const cell = this.controller.getCell(region.rowStart, region.columnStart);\n const style = this.#styleAt(region.rowStart, region.columnStart);\n for (const fragment of splitMergedRegion(\n region,\n layout.frozenRowCount,\n layout.frozenColumnCount,\n )) {\n const first = this.controller.cellRect({\n rowIndex: fragment.rowStart,\n columnIndex: fragment.columnStart,\n });\n const last = this.controller.cellRect({\n rowIndex: fragment.rowEnd - 1,\n columnIndex: fragment.columnEnd - 1,\n });\n const clip = mergePaneClip(layout, fragment);\n const x = Math.max(first.x, clip.left);\n const y = Math.max(first.y, clip.top);\n const right = Math.min(last.x + last.width, clip.right);\n const bottom = Math.min(last.y + last.height, clip.bottom);\n if (right <= x || bottom <= y) continue;\n result.push(Object.freeze({\n region,\n x,\n y,\n width: right - x,\n height: bottom - y,\n value: cell.status === \"loaded\" ? cell.value : undefined,\n ...(style === undefined ? {} : { style }),\n ...(fragment.rowStart === region.rowStart\n && fragment.columnStart === region.columnStart\n ? {}\n : { continuation: true }),\n }));\n }\n }\n return Object.freeze(result);\n }\n\n #styleAt(rowIndex: number, columnIndex: number): PresentationStyle | undefined {\n const presentation = this.#presentation;\n if (presentation === null) return undefined;\n for (const window of this.#presentationRanges) {\n const range = window.range;\n if (\n rowIndex < range.rowStart\n || rowIndex >= range.rowStart + range.rowCount\n || columnIndex < range.columnStart\n || columnIndex >= range.columnStart + range.columnCount\n ) {\n continue;\n }\n const id = window.styleIds[rowIndex - range.rowStart]?.[columnIndex - range.columnStart];\n return id === null || id === undefined ? undefined : presentation.styles[id];\n }\n return undefined;\n }\n\n #mergeContaining(rowIndex: number, columnIndex: number): MergedCellRegion | undefined {\n return this.#mergedRegions().find((region) => (\n rowIndex >= region.rowStart\n && rowIndex < region.rowEnd\n && columnIndex >= region.columnStart\n && columnIndex < region.columnEnd\n ));\n }\n\n #renderResizeHandles(snapshot: Readonly<TableViewSnapshot>): void {\n const visibleIds = new Set<string>();\n if (this.#isTerminal()) {\n this.#removeStaleResizeHandles(visibleIds);\n return;\n }\n for (const column of snapshot.layout.visibleColumns) {\n const boundary = column.x + column.width;\n if (boundary < snapshot.layout.rowHeaderWidth || boundary > snapshot.layout.width) {\n continue;\n }\n visibleIds.add(column.id);\n let handle = this.#resizeHandles.get(column.id);\n if (handle === undefined) {\n handle = this.element.ownerDocument.createElement(\"div\");\n handle.setAttribute(\"role\", \"separator\");\n handle.setAttribute(\"aria-orientation\", \"vertical\");\n handle.setAttribute(\"aria-controls\", this.#accessibleGrid.element.id);\n handle.setAttribute(\"aria-describedby\", this.#resizeInstructions.id);\n handle.setAttribute(\"aria-keyshortcuts\", \"ArrowLeft ArrowRight Home End Enter\");\n handle.tabIndex = 0;\n Object.assign(handle.style, {\n background: \"transparent\",\n boxSizing: \"border-box\",\n cursor: \"col-resize\",\n outline: \"none\",\n pointerEvents: \"auto\",\n position: \"absolute\",\n top: \"0\",\n touchAction: \"none\",\n width: `${RESIZE_TARGET_SIZE}px`,\n });\n const line = this.element.ownerDocument.createElement(\"div\");\n line.dataset.tabularkResizeLine = \"\";\n line.setAttribute(\"aria-hidden\", \"true\");\n Object.assign(line.style, {\n pointerEvents: \"none\",\n position: \"absolute\",\n top: \"0\",\n });\n handle.append(line);\n this.#resizeHandles.set(column.id, handle);\n this.#resizeLayer.append(handle);\n }\n handle.dataset.columnResize = String(column.index);\n handle.dataset.columnId = column.id;\n handle.setAttribute(\"aria-label\", `Resize ${column.name} column`);\n handle.setAttribute(\"aria-valuemin\", String(this.controller.minColumnWidth));\n handle.setAttribute(\"aria-valuemax\", String(this.controller.maxColumnWidth));\n handle.setAttribute(\"aria-valuenow\", String(column.width));\n handle.setAttribute(\"aria-valuetext\", `${formatWidth(column.width)} CSS pixels`);\n Object.assign(handle.style, {\n height: `${Math.max(RESIZE_TARGET_SIZE, snapshot.layout.headerHeight)}px`,\n left: `${boundary - RESIZE_TARGET_SIZE / 2}px`,\n });\n const line = handle.firstElementChild as HTMLElement | null;\n if (line !== null) {\n Object.assign(line.style, {\n background: this.#theme.gridLine,\n height: `${snapshot.layout.headerHeight}px`,\n left: `${(RESIZE_TARGET_SIZE - (this.#forcedColors ? 2 : 1)) / 2}px`,\n width: `${this.#forcedColors ? 2 : 1}px`,\n });\n }\n }\n this.#resizeLayer.style.height = `${Math.max(RESIZE_TARGET_SIZE, snapshot.layout.headerHeight)}px`;\n this.#removeStaleResizeHandles(visibleIds);\n }\n\n #removeStaleResizeHandles(visibleIds: ReadonlySet<string>): void {\n for (const [columnId, handle] of this.#resizeHandles) {\n if (visibleIds.has(columnId)) {\n continue;\n }\n if (handle.contains(this.element.ownerDocument.activeElement)) {\n this.#accessibleGrid.focus({ preventScroll: true });\n }\n handle.remove();\n this.#resizeHandles.delete(columnId);\n }\n }\n\n #renderAccessibleGrid(snapshot: Readonly<TableViewSnapshot>): void {\n const layout = snapshot.layout;\n const visibleRowIndexes = new Set(layout.visibleRows.map((row) => row.index));\n const visibleColumnIndexes = new Set(layout.visibleColumns.map((column) => column.index));\n const accessibleMerges = this.#mergedRegions().filter((region) => (\n layout.visibleRows.some((row) => row.index >= region.rowStart && row.index < region.rowEnd)\n && layout.visibleColumns.some(\n (column) => column.index >= region.columnStart && column.index < region.columnEnd,\n )\n ));\n const columnIndexes = new Set(visibleColumnIndexes);\n const rowIndexes = new Set(visibleRowIndexes);\n for (const merge of accessibleMerges) {\n columnIndexes.add(merge.columnStart);\n rowIndexes.add(merge.rowStart);\n }\n const columns = [...columnIndexes]\n .sort((left, right) => left - right)\n .map((index) => ({\n index,\n name: snapshot.metadata.schema.columns[index]?.name ?? `Column ${index + 1}`,\n }));\n const rows: AccessibleGridRow[] = [];\n for (const rowIndex of [...rowIndexes].sort((left, right) => left - right)) {\n const candidateColumns = new Set<number>();\n if (visibleRowIndexes.has(rowIndex)) {\n for (const columnIndex of visibleColumnIndexes) candidateColumns.add(columnIndex);\n }\n for (const merge of accessibleMerges) {\n if (merge.rowStart === rowIndex) candidateColumns.add(merge.columnStart);\n }\n rows.push({\n index: rowIndex,\n cells: [...candidateColumns]\n .sort((left, right) => left - right)\n .flatMap((columnIndex) => {\n const merge = this.#mergeContaining(rowIndex, columnIndex);\n if (\n merge !== undefined\n && (rowIndex !== merge.rowStart || columnIndex !== merge.columnStart)\n ) {\n return [];\n }\n const cell = this.controller.getCell(rowIndex, columnIndex);\n return [{\n rowIndex,\n columnIndex,\n value: cell.status === \"loaded\" ? cell.value : undefined,\n selected: snapshot.selection !== null && containsCell(\n snapshot.selection.range,\n { rowIndex, columnIndex },\n ),\n active: snapshot.activeCell?.rowIndex === rowIndex\n && snapshot.activeCell.columnIndex === columnIndex,\n ...(merge === undefined ? {} : {\n rowSpan: merge.rowEnd - merge.rowStart,\n columnSpan: merge.columnEnd - merge.columnStart,\n }),\n }];\n }),\n });\n }\n this.#accessibleGrid.update({\n label: this.#tableLabel(),\n ...(snapshot.metadata.extent.rows.kind === \"exact\"\n ? { exactRowCount: snapshot.metadata.extent.rows.value }\n : {}),\n columnCount: layout.columnCount,\n columns,\n rows,\n busy: snapshot.status === \"loading\",\n status: this.#statusText(snapshot),\n });\n }\n\n #renderMessage(snapshot: Readonly<TableViewSnapshot>): void {\n let message = \"\";\n if (snapshot.status === \"error\") {\n message = `Unable to render table: ${errorMessage(snapshot.error)}`;\n } else if (snapshot.status === \"closed\") {\n message = \"Table closed.\";\n } else if (snapshot.layout.rowCount === 0 && snapshot.status === \"ready\") {\n message = \"No rows to display.\";\n } else if (snapshot.status === \"loading\" && snapshot.layout.rows.visible.start === snapshot.layout.rows.visible.end) {\n message = \"Loading data\u2026\";\n }\n this.#message.textContent = message;\n this.#message.style.display = message === \"\" ? \"none\" : \"flex\";\n }\n\n #syncNativeScroll(snapshot: Readonly<TableViewSnapshot>): void {\n const desiredLeft = snapshot.layout.horizontal.physicalOffset;\n const desiredTop = snapshot.layout.vertical.physicalOffset;\n if (Math.abs(this.#scrollHost.scrollLeft - desiredLeft) > 0.5) {\n this.#scrollHost.scrollLeft = desiredLeft;\n }\n if (Math.abs(this.#scrollHost.scrollTop - desiredTop) > 0.5) {\n this.#scrollHost.scrollTop = desiredTop;\n }\n }\n\n #cellFromHit(hit: ReturnType<TableViewController[\"hitTest\"]>): Readonly<CellPosition> | null {\n if (hit.kind === \"cell\") {\n return Object.freeze({ rowIndex: hit.rowIndex, columnIndex: hit.columnIndex });\n }\n if (hit.kind === \"row-header\" && this.#snapshot.layout.columnCount > 0) {\n return Object.freeze({\n rowIndex: hit.rowIndex,\n columnIndex: this.#snapshot.activeCell?.columnIndex ?? 0,\n });\n }\n if (hit.kind === \"column-header\" && this.#snapshot.layout.rowCount > 0) {\n return Object.freeze({\n rowIndex: this.#snapshot.activeCell?.rowIndex ?? 0,\n columnIndex: hit.columnIndex,\n });\n }\n return null;\n }\n\n #eventPosition(event: MouseEvent | PointerEvent): Readonly<{ x: number; y: number }> {\n const rect = this.#surface.getBoundingClientRect();\n return Object.freeze({ x: event.clientX - rect.left, y: event.clientY - rect.top });\n }\n\n #resizeColumnFromTarget(target: EventTarget | null): number | null {\n const handle = this.#resizeHandleFromTarget(target);\n if (handle === null) {\n return null;\n }\n const value = handle.dataset.columnResize;\n if (value === undefined) {\n return null;\n }\n const columnIndex = Number(value);\n return Number.isSafeInteger(columnIndex) ? columnIndex : null;\n }\n\n #resizeHandleFromTarget(target: EventTarget | null): HTMLDivElement | null {\n if (!(target instanceof this.#ownerWindow.HTMLElement)) {\n return null;\n }\n const handle = target.closest<HTMLElement>(\"[data-column-resize]\");\n return handle instanceof this.#ownerWindow.HTMLDivElement && this.#resizeLayer.contains(handle)\n ? handle\n : null;\n }\n\n #measureColumn(columnIndex: number): number {\n const context = this.#canvas.getContext(\"2d\");\n if (context === null) {\n return this.controller.columnWidths[columnIndex]!;\n }\n const column = this.#snapshot.metadata.schema.columns[columnIndex];\n if (column === undefined) {\n return this.controller.columnWidths[columnIndex]!;\n }\n context.save();\n context.font = this.#theme.headerFont;\n let width = context.measureText(column.name).width;\n context.font = this.#theme.font;\n const visible = this.#snapshot.layout.rows.visible;\n for (let rowIndex = visible.start; rowIndex < visible.end; rowIndex += 1) {\n const cell = this.controller.getCell(rowIndex, columnIndex);\n if (cell.status === \"loaded\") {\n width = Math.max(width, context.measureText(cell.value ?? \"\u2205\").width);\n }\n }\n context.restore();\n return Math.ceil(width + AUTOSIZE_HORIZONTAL_PADDING);\n }\n\n async #copySelection(): Promise<void> {\n this.#copyAbort?.abort();\n const abort = new AbortController();\n this.#copyAbort = abort;\n try {\n const text = await this.controller.copySelection({ signal: abort.signal });\n if (abort.signal.aborted || this.#destroyed || text === \"\") {\n return;\n }\n if (this.#writeClipboard !== undefined) {\n await this.#writeClipboard(text);\n } else {\n const clipboard = this.#ownerWindow.navigator.clipboard;\n if (clipboard === undefined) {\n throw new Error(\"Clipboard access is unavailable in this browser context\");\n }\n await clipboard.writeText(text);\n }\n this.#accessibleGrid.statusElement.textContent = \"Selection copied to clipboard.\";\n } catch (error) {\n if (!abort.signal.aborted) {\n this.#accessibleGrid.statusElement.textContent = `Copy failed: ${errorMessage(error)}`;\n this.#reportError(error);\n }\n } finally {\n if (this.#copyAbort === abort) {\n this.#copyAbort = null;\n }\n }\n }\n\n #statusText(snapshot: Readonly<TableViewSnapshot>): string {\n if (snapshot.status === \"error\") {\n return `Table error: ${errorMessage(snapshot.error)}`;\n }\n if (snapshot.status === \"closed\") {\n return \"Table closed.\";\n }\n if (snapshot.status === \"loading\") {\n return \"Loading visible table cells.\";\n }\n return `${snapshot.layout.rowCount} rows and ${snapshot.layout.columnCount} columns.`;\n }\n\n #announceColumnWidth(columnIndex: number, fitted: boolean): void {\n const column = this.#snapshot.metadata.schema.columns[columnIndex];\n const width = this.controller.columnWidths[columnIndex];\n if (column === undefined || width === undefined) {\n return;\n }\n if (this.#announcementFrame !== 0) {\n this.#ownerWindow.cancelAnimationFrame(this.#announcementFrame);\n }\n const action = fitted ? \"fit to\" : \"width\";\n const qualifier = fitted ? \" using visible content\" : \"\";\n this.#announcementFrame = this.#ownerWindow.requestAnimationFrame(() => {\n this.#announcementFrame = 0;\n if (!this.#destroyed) {\n this.#accessibleGrid.statusElement.textContent = `${column.name} column ${action} ${formatWidth(width)} CSS pixels${qualifier}.`;\n }\n });\n }\n\n #applyThemeToElements(): void {\n this.element.dataset.tabularkColorScheme = this.#resolvedColorScheme;\n this.element.dataset.tabularkForcedColors = this.#forcedColors ? \"active\" : \"none\";\n this.element.style.background = this.#theme.background;\n this.element.style.borderColor = this.#theme.gridLine;\n this.element.style.color = this.#theme.foreground;\n this.#message.style.background = this.#theme.background;\n this.#message.style.color = this.#theme.mutedForeground;\n this.#canvas.style.forcedColorAdjust = this.#forcedColors ? \"none\" : \"auto\";\n if (this.element.contains(this.element.ownerDocument.activeElement)) {\n this.element.style.outline = `2px solid ${this.#focusColor()}`;\n const handle = this.#resizeHandleFromTarget(this.element.ownerDocument.activeElement);\n if (handle !== null) {\n handle.style.outline = `2px solid ${this.#focusColor()}`;\n }\n }\n }\n\n #resolveTheme(): Readonly<CanvasTableTheme> {\n const palette = this.#resolvedColorScheme === \"dark\"\n ? DARK_CANVAS_TABLE_THEME\n : DEFAULT_CANVAS_TABLE_THEME;\n const baseTheme = Object.freeze({ ...palette, ...this.#themeOverrides });\n return this.#forcedColors\n ? forcedColorsCanvasTableTheme(baseTheme)\n : baseTheme;\n }\n\n #focusColor(): string {\n return this.#forcedColors ? \"Highlight\" : this.#theme.activeCellBorder;\n }\n\n #tableLabel(): string {\n return `${this.controller.metadata.name || \"Data\"} table`;\n }\n\n #hasCells(): boolean {\n return this.#snapshot.layout.rowCount > 0 && this.#snapshot.layout.columnCount > 0;\n }\n\n #isTerminal(): boolean {\n return this.#destroyed\n || this.#snapshot.status === \"error\"\n || this.#snapshot.status === \"closed\";\n }\n\n #cancelInteraction(): void {\n if (this.#interaction !== null && this.#surface.hasPointerCapture(this.#interaction.pointerId)) {\n this.#surface.releasePointerCapture(this.#interaction.pointerId);\n }\n this.#interaction = null;\n this.#surface.style.cursor = \"default\";\n }\n\n #reportError(error: unknown): void {\n if (this.#onError !== undefined) {\n this.#onError(error);\n } else if (typeof this.#ownerWindow.reportError === \"function\") {\n this.#ownerWindow.reportError(error);\n }\n }\n\n #assertAlive(): void {\n if (this.#destroyed) {\n throw new Error(\"Canvas table view is destroyed\");\n }\n }\n}\n\nfunction splitMergedRegion(\n region: MergedCellRegion,\n frozenRowCount: number,\n frozenColumnCount: number,\n): readonly Readonly<MergedCellRegion>[] {\n const rows = splitIndexRange(region.rowStart, region.rowEnd, frozenRowCount);\n const columns = splitIndexRange(region.columnStart, region.columnEnd, frozenColumnCount);\n return Object.freeze(rows.flatMap((row) => columns.map((column) => Object.freeze({\n rowStart: row.start,\n rowEnd: row.end,\n columnStart: column.start,\n columnEnd: column.end,\n }))));\n}\n\nfunction splitIndexRange(\n start: number,\n end: number,\n boundary: number,\n): readonly Readonly<{ start: number; end: number }>[] {\n if (boundary <= start || boundary >= end) {\n return Object.freeze([Object.freeze({ start, end })]);\n }\n return Object.freeze([\n Object.freeze({ start, end: boundary }),\n Object.freeze({ start: boundary, end }),\n ]);\n}\n\nfunction mergePaneClip(\n layout: Readonly<TableViewSnapshot>[\"layout\"],\n fragment: MergedCellRegion,\n): Readonly<{ left: number; top: number; right: number; bottom: number }> {\n const frozenRight = layout.rowHeaderWidth\n + Math.min(layout.bodyWidth, layout.frozenColumnExtent);\n const frozenBottom = layout.headerHeight\n + Math.min(layout.bodyHeight, layout.frozenRowExtent);\n const frozenColumn = fragment.columnStart < layout.frozenColumnCount;\n const frozenRow = fragment.rowStart < layout.frozenRowCount;\n return Object.freeze({\n left: frozenColumn ? layout.rowHeaderWidth : frozenRight,\n right: frozenColumn ? frozenRight : layout.rowHeaderWidth + layout.bodyWidth,\n top: frozenRow ? layout.headerHeight : frozenBottom,\n bottom: frozenRow ? frozenBottom : layout.headerHeight + layout.bodyHeight,\n });\n}\n\nfunction presentationRequests(\n layout: Readonly<TableViewSnapshot>[\"layout\"],\n): readonly Readonly<RangeRequest>[] {\n const overscan = presentationRectangles(\n layout.rows.overscan,\n layout.columns.overscan,\n layout.frozenRowRange,\n layout.frozenColumnRange,\n );\n const overscanCells = overscan.reduce(\n (total, range) => total + range.rowCount * range.columnCount,\n 0,\n );\n if (overscanCells <= MAX_PRESENTATION_WINDOW_CELLS) return overscan;\n return presentationRectangles(\n layout.rows.visible,\n layout.columns.visible,\n layout.frozenRowRange,\n layout.frozenColumnRange,\n );\n}\n\nfunction presentationRectangles(\n rows: Readonly<{ start: number; end: number }>,\n columns: Readonly<{ start: number; end: number }>,\n frozenRows: Readonly<{ start: number; end: number }>,\n frozenColumns: Readonly<{ start: number; end: number }>,\n): readonly Readonly<RangeRequest>[] {\n const requests: RangeRequest[] = [];\n for (const row of presentationBands(rows, frozenRows)) {\n for (const column of presentationBands(columns, frozenColumns)) {\n requests.push(Object.freeze({\n rowStart: row.start,\n rowCount: row.end - row.start,\n columnStart: column.start,\n columnCount: column.end - column.start,\n }));\n }\n }\n return Object.freeze(requests);\n}\n\nfunction presentationBands(\n primary: Readonly<{ start: number; end: number }>,\n frozen: Readonly<{ start: number; end: number }>,\n): readonly Readonly<{ start: number; end: number }>[] {\n const bands = [primary, frozen]\n .filter((range) => range.start < range.end)\n .sort((left, right) => left.start - right.start);\n if (bands.length < 2) return Object.freeze(bands.map((range) => Object.freeze({ ...range })));\n const first = bands[0]!;\n const second = bands[1]!;\n return first.end >= second.start\n ? Object.freeze([Object.freeze({ start: first.start, end: Math.max(first.end, second.end) })])\n : Object.freeze(bands.map((range) => Object.freeze({ ...range })));\n}\n\nfunction rangeKey(range: RangeRequest): string {\n return `${range.rowStart}:${range.rowCount}:${range.columnStart}:${range.columnCount}`;\n}\n\nfunction mergeKey(region: MergedCellRegion): string {\n return `${region.rowStart}:${region.rowEnd}:${region.columnStart}:${region.columnEnd}`;\n}\n\nfunction collectMergedRegions(\n ranges: readonly PresentationRange[],\n): readonly MergedCellRegion[] {\n const unique = new Map<string, MergedCellRegion>();\n for (const window of ranges) {\n for (const region of window.mergedCells) unique.set(mergeKey(region), region);\n }\n return Object.freeze([...unique.values()]);\n}\n\nfunction missingMergeAnchorRequests(\n regions: readonly MergedCellRegion[],\n ranges: readonly PresentationRange[],\n): readonly Readonly<RangeRequest>[] {\n const requests = new Map<string, Readonly<RangeRequest>>();\n for (const region of regions) {\n const anchorLoaded = ranges.some((window) => (\n region.rowStart >= window.range.rowStart\n && region.rowStart < window.range.rowStart + window.range.rowCount\n && region.columnStart >= window.range.columnStart\n && region.columnStart < window.range.columnStart + window.range.columnCount\n ));\n if (anchorLoaded) continue;\n const request = Object.freeze({\n rowStart: region.rowStart,\n rowCount: 1,\n columnStart: region.columnStart,\n columnCount: 1,\n });\n requests.set(`${region.rowStart}:${region.columnStart}`, request);\n }\n return Object.freeze([...requests.values()]);\n}\n\n/** Mounts an accessible, viewport-driven Canvas preview. */\nexport function createCanvasTableView(options: CanvasTableViewOptions): CanvasTableView {\n if (!options || !options.container || typeof options.container.append !== \"function\") {\n throw invalidArgument(\"container must be an HTMLElement\");\n }\n const hasTable = options.table !== undefined;\n const hasController = options.controller !== undefined;\n if (hasTable === hasController) {\n throw invalidArgument(\"provide exactly one of table or controller\");\n }\n return new View(options);\n}\n\nfunction addMediaQueryListener(\n query: MediaQueryList,\n listener: (event: MediaQueryListEvent) => void,\n): void {\n if (typeof query.addEventListener === \"function\") {\n query.addEventListener(\"change\", listener);\n return;\n }\n query.addListener?.(listener);\n}\n\nfunction removeMediaQueryListener(\n query: MediaQueryList,\n listener: (event: MediaQueryListEvent) => void,\n): void {\n if (typeof query.removeEventListener === \"function\") {\n query.removeEventListener(\"change\", listener);\n return;\n }\n query.removeListener?.(listener);\n}\n\nfunction keyboardCommand(event: KeyboardEvent): NavigationCommand | null {\n switch (event.key) {\n case \"ArrowLeft\":\n return \"left\";\n case \"ArrowRight\":\n return \"right\";\n case \"ArrowUp\":\n return \"up\";\n case \"ArrowDown\":\n return \"down\";\n case \"PageUp\":\n return \"page-up\";\n case \"PageDown\":\n return \"page-down\";\n case \"Home\":\n return event.ctrlKey || event.metaKey ? \"table-start\" : \"row-start\";\n case \"End\":\n return event.ctrlKey || event.metaKey ? \"table-end\" : \"row-end\";\n default:\n return null;\n }\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return typeof error === \"string\" ? error : \"Unknown error\";\n}\n\nfunction formatWidth(width: number): string {\n return Number.isInteger(width)\n ? String(width)\n : width.toFixed(2).replace(/(?:\\.0+|(?<decimal>\\.\\d*?)0+)$/, \"$<decimal>\");\n}\n\nfunction visuallyHide(element: HTMLElement): void {\n Object.assign(element.style, {\n border: \"0\",\n clip: \"rect(0 0 0 0)\",\n clipPath: \"inset(50%)\",\n height: \"1px\",\n margin: \"-1px\",\n overflow: \"hidden\",\n padding: \"0\",\n position: \"absolute\",\n whiteSpace: \"nowrap\",\n width: \"1px\",\n });\n}\n", "import type { TableHandle } from \"../client.js\";\nimport { createCanvasTableView as createInternalCanvasTableView } from \"./canvas-table-view.js\";\n\n/** Stable, high-level sizing and cache controls for the Canvas table view. */\nexport interface CanvasTableViewControllerOptions {\n readonly rowHeight?: number;\n readonly headerHeight?: number;\n readonly rowHeaderWidth?: number;\n readonly columnWidth?: number;\n readonly minColumnWidth?: number;\n readonly maxColumnWidth?: number;\n readonly columnWidths?: Readonly<Record<string, number>>;\n readonly scrollPixelLimit?: number;\n readonly overscanRows?: number;\n readonly overscanColumns?: number;\n /** Hard bound for decoded render/cache cells. */\n readonly maxWindowCells?: number;\n}\n\n/** Stable theme tokens accepted by the high-level Canvas table view. */\nexport interface CanvasTableViewTheme {\n readonly background: string;\n readonly foreground: string;\n readonly mutedForeground: string;\n readonly headerBackground: string;\n readonly headerForeground: string;\n readonly alternateRowBackground: string;\n readonly gridLine: string;\n readonly selectionBackground: string;\n readonly selectionBorder: string;\n readonly activeCellBorder: string;\n readonly loadingBackground: string;\n readonly font: string;\n readonly headerFont: string;\n}\n\n/** Stable options for mounting a Canvas preview from a logical table handle. */\nexport interface CanvasTableViewOptions {\n readonly container: HTMLElement;\n readonly table: TableHandle;\n readonly controllerOptions?: CanvasTableViewControllerOptions;\n /**\n * Selects the table palette. `light` is the compatibility default;\n * `auto` follows the browser's `prefers-color-scheme` media query.\n * Forced-colors mode always takes precedence over this setting.\n */\n readonly colorScheme?: \"auto\" | \"light\" | \"dark\";\n /**\n * Applies static spreadsheet presentation metadata when available.\n * Workbook colors never override the system palette in forced-colors mode.\n */\n readonly presentation?: \"auto\" | \"ignore\";\n readonly ariaLabel?: string;\n readonly theme?: Partial<CanvasTableViewTheme>;\n readonly maxDevicePixelRatio?: number;\n /** Testable clipboard seam; navigator.clipboard.writeText is used by default. */\n readonly writeClipboard?: (text: string) => Promise<void> | void;\n readonly onError?: (error: unknown) => void;\n}\n\n/** Stable lifecycle surface for a mounted Canvas table view. */\nexport interface CanvasTableView {\n readonly element: HTMLDivElement;\n focus(options?: FocusOptions): void;\n destroy(): void;\n dispose(): void;\n}\n\n/** Mounts an accessible, viewport-driven Canvas preview. */\nexport function createCanvasTableView(options: CanvasTableViewOptions): CanvasTableView {\n return createInternalCanvasTableView(options);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["TabularkError", "_TabularkError", "code", "message", "options", "normalizeResourceLimitDetails", "error", "details", "raw", "isRecord", "resource", "inferResource", "isQuantity", "byteLimit", "firstQuantity", "requiredBytes", "available", "required", "keys", "names", "name", "value", "cancelledError", "closedError", "invalidArgument", "official_adapters_default", "manifestEntries", "validateManifest", "official_adapters_default", "OFFICIAL_ADAPTER_IDS", "entry", "OFFICIAL_ADAPTER_MANIFEST", "byId", "isOfficialAdapterId", "value", "officialAdapterManifestEntry", "id", "validateManifest", "value", "isRecord", "ids", "entrypoints", "outputDirectories", "candidate", "index", "id", "entrypoint", "exportName", "wasm", "options", "resources", "isKnownOfficialAdapterId", "key", "OFFICIAL_ADAPTER", "createOfficialAdapter", "id", "marker", "delimitedAdapter", "resolveOfficialAdapter", "value", "isRecord", "isOfficialAdapterId", "marker", "OFFICIAL_ADAPTER", "officialAdapterManifestEntry", "isRecord", "value", "DEFAULT_MEMORY_BUDGET_BYTES", "MAX_ARRAY_BUFFER_BYTES", "MAX_RANGE_CELLS", "DEFAULT_TO_ROWS_CELL_LIMIT", "MAX_NESTING_DEPTH", "INDEX_BUDGET_MAX_BYTES", "ADAPTER_TILE_CACHE_MAX_BYTES", "MAIN_THREAD_RANGE_CACHE_MAX_BYTES", "FIELD_AND_BATCH_MAX_BYTES", "UTF8_DECODER", "DATA_VIEW_CACHE", "MAX_SOURCES", "MAX_ACTIVE_RANGES", "MAX_RANGE_WAITERS", "deriveMemoryBudgetLimits", "memoryBudgetBytes", "assertPositiveSafeInteger", "oneEighth", "oneThirtySecond", "adapterRuntimePoolBytes", "operationBudgetBytes", "workerBudgetBytes", "mainThreadSourceBytes", "mainThreadRetainedBytes", "ColumnarTableBatch", "#buffers", "#wireColumns", "value", "invalidArgument", "asUint8Array", "column", "freezeWireColumn", "validateWireBatch", "index", "LogicalBatchColumn", "options", "maxCells", "normalizeCellLimit", "assertCellLimit", "rows", "columnIndex", "rowIndex", "#wire", "wire", "buffers", "rowCount", "rowOffset", "assertBatchRowOffset", "decodeNativeValue", "decodeDisplayValue", "_", "display", "columnId", "physicalIndex", "validAt", "offsets", "regionView", "data", "start", "readUnsignedOffset", "end", "UTF8_DECODER", "validateRange", "request", "name", "assertNonNegativeSafeInteger", "TabularkError", "cells", "MAX_RANGE_CELLS", "required", "normalizeMetadata", "freezeDataType", "normalizeDataType", "depth", "MAX_NESTING_DEPTH", "isRecord", "type", "timeUnit", "intervalUnit", "positiveInteger", "integer", "normalizeField", "field", "entry", "metadata", "key", "range", "columns", "validateDisplay", "validateNative", "offset", "previous", "next", "descriptor", "regions", "region", "child", "logicalIndex", "unwrapExtension", "bytes", "decodeVariableBytes", "values", "requiredRegion", "bitIndex", "readNumber", "readBigInt", "decodeFloat16", "readFloat", "decodeViewBytes", "checkedSlice", "width", "readSignedLittleEndian", "decodeInterval", "decodeListLike", "requiredChild", "result", "typeIds", "typeId", "dataViewFor", "fieldIndex", "childPhysical", "readSignedOffset", "keys", "dictionary", "readIndex", "runEnds", "logicalPosition", "run", "numericIndexValue", "record", "entryType", "fields", "keyName", "valueName", "unit", "view", "ensureViewRange", "offsetWidth", "views", "length", "bufferIndex", "dataOffset", "signedness", "signed", "dataType", "numeric", "slice", "sign", "readOffset", "backing", "byOffset", "DATA_VIEW_CACHE", "byLength", "validity", "bitmap", "buffer", "byteOffset", "byteLength", "current", "freezeNative", "freezeRegion", "freezeOptionalRegion", "normalizeDataTypeUnchecked", "bits", "exponent", "fraction", "DEFAULT_TO_ROWS_CELL_LIMIT", "assertPositiveSafeInteger", "cellCount", "ByteLruCache", "#maxBytes", "#maxEntries", "#minimumEntryBytes", "#entries", "#onRemove", "#byteLength", "maxBytes", "options", "maxEntries", "minimumEntryBytes", "key", "entry", "value", "byteLength", "effectiveMaxBytes", "chargedBytes", "existing", "#remove", "oldestKey", "oldest", "predicate", "rangeCacheKey", "datasetHandle", "tableId", "revision", "schemaVersion", "range", "rangeCacheKeyBelongsToDataset", "rangeCacheKeyBelongsToTable", "rangeCacheKeyMatchesVersion", "fields", "createBatchBacking", "batch", "buffers", "buffer", "index", "columns", "column", "freezeBatchDescriptor", "wireBatchByteLength", "total", "seen", "freeze", "child", "DEFAULT_SHUTDOWN_TIMEOUT_MS", "RESPONSE_KINDS", "EVENT_NAMES", "WorkerRpcClient", "#worker", "#pending", "#onEvent", "#onFailure", "#onSourceMessage", "#nextRequestId", "#closed", "worker", "onEvent", "onFailure", "onSourceMessage", "#handleMessage", "#handleWorkerFailure", "value", "transfer", "op", "payload", "expectedKind", "options", "closedError", "cancelledError", "requestId", "resolve", "reject", "cleanups", "cleanup", "dispose", "abort", "pending", "#postCancel", "timeoutMs", "timeoutId", "#failRuntime", "TabularkError", "error", "notifyFailure", "#stop", "#notifyFailure", "event", "isSourceBrokerMessage", "isValidProtocolEvent", "looksLikeProtocolEvent", "looksLikeProtocolResponse", "isValidProtocolResponse", "optionsTelemetry", "message", "targetRequestId", "#failPending", "isRecord", "bytesRead", "peakReservationBytes", "telemetryQuantity", "key", "candidate", "isSerializedError", "optionalNonEmptyString", "optionalNonNegativeInteger", "isRangeSource", "value", "candidate", "normalizeRangeSourceSnapshot", "value", "candidate", "validateRangeSourceReader", "isSafeNonNegativeInteger", "isValidSnapshot", "copyRangeBytes", "bytes", "copy", "MAX_LARGE_SOURCE_BYTES", "isSourceMode", "value", "MIN_MEMORY_BUDGET_BYTES", "LIFECYCLE_CLOSE_TIMEOUT_MS", "MAX_ORPHAN_HANDLES", "MAX_ORPHAN_EVENTS_PER_HANDLE", "MAX_ORPHAN_EVENTS", "MAX_DIAGNOSTICS", "MAX_DIAGNOSTIC_MESSAGE_LENGTH", "MAX_PERFORMANCE_SAMPLES", "MIN_BATCH_CACHE_ENTRY_BYTES", "MAX_BATCH_CACHE_ENTRIES", "RANGE_SOURCE_HOST_RESERVATION_STORE", "attachRangeSourceHostReservations", "options", "reservations", "rangeSourceHostReservationStore", "host", "existing", "store", "SourceStagingLimiter", "#capacity", "#queue", "#used", "#closed", "capacity", "bytes", "signal", "TabularkError", "closedError", "cancelledError", "#grant", "resolve", "reject", "waiter", "onAbort", "index", "#drain", "released", "selected", "SourceReadConcurrencyLimiter", "#limit", "#active", "limit", "entry", "Engine", "_Engine", "#rpc", "#rangeCache", "#rangeSingleflight", "#limits", "#maxArrayBufferBytes", "#adapters", "#sourceStaging", "#retainedSourceBytes", "#sourceReaders", "#datasetSources", "#openingSources", "#nextSourceHandle", "#sessions", "#orphanEvents", "#performanceListeners", "#performanceQueue", "#orphanEventCount", "#sourceCleanupPromise", "rpc", "limits", "adapters", "ByteLruCache", "adapter", "listener", "invalidArgument", "sample", "safelyCall", "#emitPerformanceSample", "stage", "startedAt", "durationMs", "finitePerformanceNow", "sanitizePerformanceStage", "nonNegativeSafeQuantity", "normalized", "normalizeEngineOptions", "engine", "worker", "WorkerRpcClient", "event", "#handleEvent", "error", "#handleRuntimeFailure", "message", "#handleSourceBrokerMessage", "hello", "id", "helloAdapters", "isRecord", "source", "#assertOpen", "bytesRead", "peakReservationBytes", "sourceReads", "sourceCacheHitBytes", "onTelemetry", "telemetry", "addPerformanceBytes", "rangeSourceInput", "isRangeSource", "normalizedOptions", "normalizeOpenOptions", "inferSourceName", "sourceBytes", "sourcePayload", "sourceRecord", "transfer", "openController", "combineAbortSignals", "reader", "openOptions", "sourceStagingBudget", "reservationSignal", "#reserveRetainedSourceBytes", "openRangeReaderWithCancellation", "normalizeRangeSourceOpenError", "closeRangeReaderBestEffort", "readerValue", "reportedSize", "validateRangeSourceReader", "normalizeRangeSourceSnapshot", "readerMaxConcurrency", "isSafeNonNegativeInteger", "handle", "#allocateSourceHandle", "sourceSize", "MAX_LARGE_SOURCE_BYTES", "largeSourceLimitError", "dataset", "opened", "#terminateForProtocolFailure", "#closeSourceReader", "tableResult", "tableDescriptors", "normalizeDescriptors", "session", "DatasetSessionImpl", "createDatasetCapabilitySeed", "#stagedSourceLimit", "#deliverOrphanEvents", "terminalError", "#orphanRuntimeError", "#discardOpenedDataset", "controller", "#abortRangeSingleflights", "#clearOrphanEvents", "#closeAllSourceReaders", "tableId", "table", "tableHandle", "metadata", "normalizedMetadata", "normalizeMetadataWire", "TableHandleImpl", "#discardOpenedTable", "request", "cacheHit", "flight", "validateRange", "key", "rangeCacheKey", "cached", "ColumnarTableBatch", "#createRangeSingleflight", "backing", "#joinRangeSingleflight", "range", "revision", "schemaVersion", "measure", "batch", "#validateBatchBacking", "wireBatchByteLength", "#availableRetainedCacheBytes", "caller", "abort", "cancellation", "_resolve", "requested", "isReturnedRangeWithin", "createBatchBacking", "value", "normalizePresentationWire", "normalizePresentationRangeWire", "#requestRemoteClose", "datasetHandle", "rangeCacheKeyBelongsToDataset", "rangeCacheKeyBelongsToTable", "rangeCacheKeyMatchesVersion", "#closeDatasetSource", "#deleteOrphanEvents", "adapterId", "totalWeight", "total", "officialAdapterManifestEntry", "weight", "runtimeBudget", "availableBytes", "sourceHandle", "requestId", "offset", "length", "record", "#postSourceFailure", "#runSourceRead", "concurrencyRelease", "stagingPermit", "buffer", "copyExactRangeBytes", "normalizeSourceProviderError", "code", "retryable", "details", "sourceErrorCode", "sourceErrorMessage", "errorFromWire", "#rememberOrphanEvent", "events", "candidate", "asTabularkError", "op", "payload", "#evictOldestOrphanHandle", "#evictOldestOrphanEvent", "oldest", "#engine", "#listeners", "#diagnosticListeners", "#diagnostics", "#capabilitySeed", "#tableHandles", "#observedTypedValues", "#observedMultiTable", "#observedProgressive", "tables", "capabilitySeed", "createFallbackDatasetCapabilitySeed", "openedTables", "typedValues", "multiTable", "#emit", "#recordDiagnostic", "diagnosticFromError", "normalizeProgress", "warning", "normalizeWarning", "routedTable", "diagnosticFromWarning", "recordDiagnostic", "diagnostic", "#session", "#metadata", "capabilities", "logicalExtensions", "name", "isPrivateCapabilityName", "isLogicalCapabilityValue", "freezeLogicalCapabilityValue", "ids", "descriptor", "registration", "resolveOfficialAdapter", "memoryBudgetBytes", "DEFAULT_MEMORY_BUDGET_BYTES", "deriveMemoryBudgetLimits", "inferredSourceName", "rangeSource", "sourceMode", "isSourceMode", "registered", "rawOptions", "normalizeDelimitedOptions", "normalizeArrowOptions", "normalizeParquetOptions", "normalizeExcelOptions", "requiredBytes", "required", "raw", "assertManifestKeys", "dialect", "header", "mode", "delimiter", "isValidDelimiter", "sourceName", "normalizeSourceName", "container", "format", "allowedSet", "rawExtent", "rawSchema", "rawCapabilities", "columns", "column", "normalizeColumn", "normalizeMetadata", "numeric", "normalizeAxis", "visibility", "normalizePresentationAxis", "normalizePresentationStyles", "styleIds", "row", "rowIndex", "styleId", "invalidPresentationStyleId", "mergedCells", "region", "normalizeMergedCell", "seen", "axisIndex", "style", "normalizePresentationFont", "normalizePresentationColor", "normalizePresentationBorders", "isHorizontalAlignment", "isVerticalAlignment", "color", "size", "font", "sides", "result", "side", "isBorderStyle", "fields", "field", "normalizeDataType", "fallbackKind", "fallbackValue", "byte", "byteOffset", "sourceOffset", "safeDiagnosticTableId", "resource", "safeDiagnosticResource", "firstNonNegativeSafeInteger", "warningRow", "warningColumn", "diagnosticRevision", "safeDiagnosticCode", "safeTableId", "safeDiagnosticMessage", "diagnosticFallback", "detailOffset", "detailRow", "detailColumn", "detailTableId", "detailRevision", "safeDetailTableId", "safeErrorDiagnosticMessage", "fallback", "SAFE_DIAGNOSTIC_CODES", "stable", "severity", "stagedSourceLimit", "MAX_ARRAY_BUFFER_BYTES", "manifest", "progressive", "sourceAccess", "maxSourceBytes", "now", "nonNegativeFinite", "current", "next", "structured", "rangeSourceErrorLike", "safeSourceLimitDetails", "isAbortLikeError", "rowStart", "rowCount", "columnStart", "columnCount", "close", "closeResult", "timer", "timeout", "finished", "opening", "cleanup", "expectedLength", "copyRangeBytes", "first", "second", "any", "createEngine", "createSelection", "anchor", "focus", "assertCellPosition", "normalizedAnchor", "normalizedFocus", "selectionRange", "containsCell", "range", "cell", "clampCell", "rowCount", "columnCount", "clampInteger", "moveCell", "command", "pageRowCount", "current", "page", "value", "name", "invalidArgument", "minimum", "maximum", "nextGridId", "AccessibleViewportGrid", "#idPrefix", "#destroyed", "ownerDocument", "label", "visuallyHide", "snapshot", "setOptionalAttribute", "fragment", "#createHeader", "activeId", "row", "rowElement", "cell", "cellElement", "#cellId", "options", "columns", "column", "rowIndex", "columnIndex", "element", "name", "value", "DEFAULT_CANVAS_TABLE_THEME", "forcedColorsCanvasTableTheme", "base", "CanvasTablePainter", "#context", "#theme", "#maxDevicePixelRatio", "#forcedColors", "#cssWidth", "#cssHeight", "#devicePixelRatio", "canvas", "options", "context", "positive", "theme", "snapshot", "#resize", "#paintRows", "#paintHeader", "#paintGrid", "#paintMergedCells", "#paintSelection", "width", "height", "browserRatio", "ratio", "cssWidth", "cssHeight", "pixelWidth", "pixelHeight", "columnsByIndex", "column", "rows", "row", "cells", "cell", "#paintCellValue", "value", "x", "y", "style", "horizontalPadding", "#paintCellFill", "#applyCellFont", "horizontalAlignment", "verticalBaseline", "skeletonWidth", "#cellForeground", "label", "textX", "horizontalTextX", "textY", "verticalTextY", "measured", "start", "underlineStart", "#paintCellBorders", "merged", "color", "cssColor", "font", "size", "finitePositive", "family", "fallback", "sides", "paint", "side", "startX", "startY", "endX", "endY", "border", "widthForStyle", "borderWidth", "borderDash", "offset", "horizontal", "columns", "snap", "selection", "selectedColumns", "selectedRows", "firstColumn", "lastColumn", "firstRow", "lastRow", "right", "bottom", "activeMerges", "activeColumn", "activeRow", "activeRects", "activeRect", "activeX", "activeY", "activeRight", "activeBottom", "supports", "alignment", "padding", "baseline", "createTableLayout", "metadata", "columnWidths", "viewport", "options", "rowHeight", "positiveFinite", "headerHeight", "nonNegativeFinite", "rowHeaderWidth", "scrollPixelLimit", "overscanRows", "nonNegativeInteger", "overscanColumns", "width", "height", "devicePixelRatio", "columnCount", "invalidArgument", "index", "hiddenColumns", "effectiveColumnWidths", "rowCount", "extentValue", "frozenRowCount", "frozenColumnCount", "bodyWidth", "bodyHeight", "prefixes", "columnOffsets", "rowGeometry", "createSparseAxisGeometry", "logicalWidth", "logicalHeight", "horizontal", "createScrollAxis", "vertical", "visibleRows", "visibleRowRange", "visibleColumns", "visibleColumnRange", "overscanRowRange", "expandRange", "overscanColumnRange", "frozenRowExtent", "axisPosition", "frozenColumnExtent", "frozenRowRange", "clampRangeEnd", "frozenColumnRange", "materializeColumns", "materializeRows", "logicalContentSize", "logicalViewportSize", "physicalOffset", "pixelLimit", "logicalMaxOffset", "largestUsableSize", "physicalContentSize", "physicalMaxOffset", "normalizedPhysicalOffset", "clampFinite", "compressed", "logicalOffset", "logicalToPhysicalOffset", "axis", "normalized", "hitTest", "layout", "x", "y", "_columnWidths", "resizeHandleWidth", "columnWidths", "offsets", "columnOffsets", "logicalX", "nextBoundary", "lowerBound", "handleWidth", "boundaryIndex", "boundaryX", "columnIndex", "columnAtViewportX", "rowIndex", "rowAtViewportY", "cellRect", "rowOffset", "axisPosition", "columnOffset", "axisSize", "selectionRect", "layout", "_columnWidths", "range", "columnWidths", "offsets", "columnOffsets", "columnStart", "clampInteger", "columnEnd", "rowStart", "rowEnd", "frozenColumns", "frozenRows", "rowStartOffset", "axisPosition", "rowEndOffset", "index", "extentValue", "extent", "createSparseAxisGeometry", "count", "defaultSize", "entries", "nonNegativeInteger", "positiveFinite", "byIndex", "entry", "cumulativeDelta", "overrides", "left", "right", "size", "contentSize", "geometry", "normalized", "overrideIndex", "lowerBoundOverride", "delta", "axisSize", "sparseOverrideAt", "axisIndexAtOffset", "offset", "low", "high", "middle", "start", "nextVisibleAxisIndex", "from", "direction", "candidate", "target", "clampRangeEnd", "end", "visibleRowRange", "scrollTop", "viewportHeight", "last", "visibleColumnRange", "scrollLeft", "viewportWidth", "columnAtLogicalX", "lowerBound", "expandRange", "amount", "limit", "materializeColumns", "metadata", "widths", "frozenRange", "rowHeaderWidth", "frozenColumnCount", "indexes", "rangeIndexes", "columns", "column", "width", "frozen", "materializeRows", "headerHeight", "frozenRowCount", "rows", "height", "primary", "columnAtViewportX", "x", "bodyX", "rowAtViewportY", "y", "bodyY", "values", "value", "name", "invalidArgument", "nonNegativeFinite", "clampFinite", "minimum", "maximum", "DEFAULT_MAX_WINDOW_CELLS", "Controller", "#table", "#options", "#listeners", "#unsubscribe", "#viewport", "#columnWidths", "#hiddenColumns", "#presentationRows", "#frozenRows", "#frozenColumns", "#mergedCells", "#snapshot", "#activeCell", "#selection", "#windows", "#loadingRanges", "#requestAbort", "#generation", "#loadQueued", "#disposed", "#tableClosed", "table", "options", "normalizeOptions", "initialColumnWidths", "layout", "createTableLayout", "#layoutOptions", "event", "#handleTableEvent", "listener", "#assertOpen", "viewport", "normalized", "normalizeViewport", "sameViewport", "#advanceGeneration", "cell", "assertCellPosition", "clamped", "clampCell", "next", "#visibleCell", "#mergeAnchor", "anchor", "createMergedSelection", "#scrollCellIntoView", "#publish", "focus", "rawAnchor", "rawFocus", "clampedAnchor", "clampedFocus", "command", "current", "origin", "navigationOrigin", "moved", "moveCell", "row", "rowDirection", "columnDirection", "navigationDirections", "columnIndex", "assertColumnIndex", "#scrollColumnIntoView", "width", "clampWidth", "measuredWidth", "presentation", "invalidArgument", "nextWidths", "hiddenColumns", "entry", "#normalizeInteractionForPresentation", "regions", "normalizeMergedCells", "sameMergedCells", "x", "y", "resizeHandleWidth", "result", "hitTest", "cellRect", "selection", "selectionRect", "rowIndex", "isValidCell", "window", "rangeContains", "range", "request", "gridRangeToRequest", "assertWindowCellLimit", "MAX_RANGE_CELLS", "batch", "rowsToTsv", "batchRows", "#rebuildSnapshot", "#queueLoad", "#loadGeneration", "generation", "visible", "overscan", "layoutRanges", "error", "abort", "ranges", "candidate", "required", "rangeContainsRange", "sameGridRange", "loaded", "index", "returnedRange", "batchGridRange", "TabularkError", "offsets", "columnOffsets", "cellLeft", "cellRight", "cellTop", "axisPosition", "cellBottom", "axisSize", "logicalLeft", "revealOffset", "logicalTop", "scrollLeft", "logicalToPhysicalOffset", "scrollTop", "previousMetadata", "reconcileColumnWidths", "hiddenById", "column", "#clampInteraction", "rowCount", "extentValue", "columnCount", "rawActive", "nextActive", "region", "mergeContaining", "nextVisibleAxisIndex", "nextVisibleColumn", "status", "#emit", "closedError", "createTableController", "unique", "frozen", "mergeKey", "left", "right", "createSelection", "expanded", "rangesIntersect", "merge", "widths", "from", "direction", "minColumnWidth", "positiveFinite", "maxColumnWidth", "maxWindowCells", "positiveInteger", "metadata", "nextMetadata", "previousWidths", "byId", "nonNegativeFinite", "maxCells", "mergedCells", "windowRectangles", "anchors", "mergeAnchorRanges", "visibleWithAnchors", "visibleCellCount", "total", "rangeCellCount", "fullOverscan", "overscanCellCount", "overscanWithAnchors", "rows", "columns", "frozenRows", "frozenColumns", "rowBands", "mergeIndexBands", "columnBands", "rectangles", "primary", "bands", "first", "second", "tsvField", "value", "viewportSize", "itemStart", "itemEnd", "maximum", "container", "limit", "label", "cells", "name", "RESIZE_HANDLE_WIDTH", "RESIZE_TARGET_SIZE", "KEYBOARD_RESIZE_STEP", "KEYBOARD_RESIZE_COARSE_STEP", "AUTOSIZE_HORIZONTAL_PADDING", "MAX_PRESENTATION_WINDOW_CELLS", "DARK_CANVAS_TABLE_THEME", "nextViewId", "View", "#scrollHost", "#spacer", "#surface", "#canvas", "#resizeLayer", "#resizeInstructions", "#message", "#accessibleGrid", "#painter", "#ownerWindow", "#ownsController", "#writeClipboard", "#onError", "#themeOverrides", "#colorScheme", "#colorSchemeQuery", "#presentationTable", "#theme", "#forcedColorsQuery", "#unsubscribe", "#resizeObserver", "#resizeHandles", "#snapshot", "#frame", "#interaction", "#copyAbort", "#announcementFrame", "#forcedColors", "#resolvedColorScheme", "#presentation", "#presentationRanges", "#mergedCells", "#presentationRequestKey", "#presentationAbort", "#destroyed", "options", "ownerDocument", "ownerWindow", "invalidArgument", "presentation", "colorScheme", "createTableController", "#resolveTheme", "#tableLabel", "visuallyHide", "AccessibleViewportGrid", "CanvasTablePainter", "#applyThemeToElements", "snapshot", "#isTerminal", "#cancelInteraction", "#schedulePresentationRanges", "#scheduleFrame", "#onScroll", "#onPointerDown", "#onPointerMove", "#onPointerUp", "#onDoubleClick", "#onKeyDown", "#onFocusIn", "#onFocusOut", "addMediaQueryListener", "#onForcedColorsChange", "#onColorSchemeChange", "#updateViewport", "#onWindowResize", "#applyPresentation", "#assertAlive", "removeMediaQueryListener", "event", "#focusColor", "resizeHandle", "#resizeHandleFromTarget", "#hasCells", "position", "#eventPosition", "resizeColumn", "#resizeColumnFromTarget", "hit", "cell", "#cellFromHit", "delta", "resizedColumn", "#announceColumnWidth", "fromTarget", "#measureColumn", "#handleResizeKeyDown", "keyboardCommand", "#copySelection", "command", "columnIndex", "width", "step", "nextWidth", "height", "#render", "table", "#applySpreadsheetPresentation", "error", "requests", "presentationRequests", "key", "rangeKey", "abort", "viewportRanges", "request", "currentRanges", "range", "anchorRequests", "missingMergeAnchorRequests", "collectMergedRegions", "anchorRanges", "ranges", "TabularkError", "#mergedRegions", "layout", "#syncNativeScroll", "columns", "column", "rows", "#paintRows", "mergedCells", "#paintMergedCells", "#renderResizeHandles", "#renderAccessibleGrid", "#renderMessage", "row", "rowIndex", "#styleAt", "#mergeContaining", "result", "region", "style", "fragment", "splitMergedRegion", "first", "last", "clip", "mergePaneClip", "x", "y", "right", "bottom", "window", "id", "visibleIds", "#removeStaleResizeHandles", "boundary", "handle", "line", "formatWidth", "columnId", "visibleRowIndexes", "visibleColumnIndexes", "accessibleMerges", "columnIndexes", "rowIndexes", "merge", "left", "index", "candidateColumns", "containsCell", "#statusText", "message", "errorMessage", "desiredLeft", "desiredTop", "rect", "target", "value", "context", "visible", "text", "clipboard", "#reportError", "fitted", "action", "qualifier", "palette", "DEFAULT_CANVAS_TABLE_THEME", "baseTheme", "forcedColorsCanvasTableTheme", "frozenRowCount", "frozenColumnCount", "splitIndexRange", "start", "end", "frozenRight", "frozenBottom", "frozenColumn", "frozenRow", "overscan", "presentationRectangles", "total", "frozenRows", "frozenColumns", "presentationBands", "primary", "frozen", "bands", "second", "mergeKey", "unique", "regions", "createCanvasTableView", "hasTable", "hasController", "query", "listener", "element", "createCanvasTableView", "options"]
7
7
  }