tabulark 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +215 -110
- package/THIRD_PARTY_NOTICES.md +37 -0
- package/dist/adapters.d.ts +62 -0
- package/dist/arrow.d.ts +3 -0
- package/dist/arrow.js +2 -0
- package/dist/arrow.js.map +7 -0
- package/dist/client.d.ts +76 -0
- package/dist/errors.d.ts +19 -0
- package/dist/excel.d.ts +3 -0
- package/dist/excel.js +2 -0
- package/dist/excel.js.map +7 -0
- package/dist/experimental.d.ts +13 -0
- package/dist/experimental.js +2 -0
- package/dist/experimental.js.map +7 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/model.d.ts +389 -0
- package/dist/official-adapter-manifest.d.ts +31 -0
- package/dist/parquet.d.ts +3 -0
- package/dist/parquet.js +2 -0
- package/dist/parquet.js.map +7 -0
- package/dist/protocol.d.ts +54 -0
- package/dist/range-cache.d.ts +28 -0
- package/dist/rpc-client.d.ts +18 -0
- package/dist/view/accessible-grid.d.ts +36 -0
- package/dist/view/canvas-painter.d.ts +91 -0
- package/dist/view/canvas-table-view-public.d.ts +58 -0
- package/dist/view/canvas-table-view.d.ts +32 -0
- package/dist/view/controller.d.ts +34 -0
- package/dist/view/layout.d.ts +34 -0
- package/dist/view/selection.d.ts +7 -0
- package/dist/view/types.d.ts +184 -0
- package/dist/wasm/arrow/tabulark_arrow.d.ts +126 -0
- package/dist/wasm/arrow/tabulark_arrow.js +771 -0
- package/dist/wasm/arrow/tabulark_arrow_bg.wasm +0 -0
- package/dist/wasm/arrow/tabulark_arrow_bg.wasm.d.ts +25 -0
- package/dist/wasm/delimited/tabulark_delimited.d.ts +131 -0
- package/dist/wasm/delimited/tabulark_delimited.js +845 -0
- package/dist/wasm/delimited/tabulark_delimited_bg.wasm +0 -0
- package/dist/wasm/delimited/tabulark_delimited_bg.wasm.d.ts +26 -0
- package/dist/wasm/excel/tabulark_excel.d.ts +121 -0
- package/dist/wasm/excel/tabulark_excel.js +766 -0
- package/dist/wasm/excel/tabulark_excel_bg.wasm +0 -0
- package/dist/wasm/excel/tabulark_excel_bg.wasm.d.ts +25 -0
- package/dist/wasm/parquet/tabulark_parquet.d.ts +121 -0
- package/dist/wasm/parquet/tabulark_parquet.js +754 -0
- package/dist/wasm/parquet/tabulark_parquet_bg.wasm +0 -0
- package/dist/wasm/parquet/tabulark_parquet_bg.wasm.d.ts +25 -0
- package/dist/worker/wasm-adapter.d.ts +57 -0
- package/dist/worker/worker-errors.d.ts +9 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +2 -0
- package/dist/worker.js.map +7 -0
- package/package.json +55 -12
- package/js/index.d.ts +0 -18
- package/js/index.js +0 -26
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
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"]
|
|
7
|
+
}
|