zarrextra 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -92,8 +92,14 @@ const encoded = await encodeHtj2kPlane(plane, { width, height }, {
92
92
 
93
93
  ## Worker-backed chunk decode (browser)
94
94
 
95
- JP2K and other codec work can block the main thread for a long time. For browser
96
- apps, use the optional `zarrextra/workers` entry with
95
+ Decoding and marshalling chunk data can block the main thread for a long time.
96
+ If you use `@spatialdata/vis`, its renderer path enables the bundled codec worker
97
+ automatically in browsers. You do not need to call this API for normal vis usage.
98
+
99
+ If we find that users get unexpected results or need more control we may revise this pattern.
100
+
101
+ For lower-level browser apps using `zarrextra` directly, use the optional
102
+ `zarrextra/workers` entry with
97
103
  [`@fideus-labs/fizarrita`](https://www.npmjs.com/package/@fideus-labs/fizarrita)
98
104
  to offload chunk decode to a Web Worker pool:
99
105
 
@@ -115,8 +121,14 @@ required for that path.
115
121
  | Context | Setup |
116
122
  |---------|-------|
117
123
  | Node / CI | `registerJpeg2kCodec()` / `registerExperimentalHtj2kCodec()` on the main thread |
118
- | Browser | `enableWorkerChunkDecode()` from `zarrextra/workers` before loading JP2K or HTJ2K data |
124
+ | Browser with `@spatialdata/vis` | no setup for normal `SpatialCanvas` usage; optional `ensureCodecWorkers()` for eager activation |
125
+ | Browser without `@spatialdata/vis` | `enableWorkerChunkDecode()` from `zarrextra/workers` before loading JP2K or HTJ2K data |
119
126
 
120
127
  Optional dependencies: `@fideus-labs/fizarrita`, `@fideus-labs/worker-pool`,
121
128
  `@cornerstonejs/codec-openjpeg`, and `@cornerstonejs/codec-openjph` (bundled into
122
- the worker script).
129
+ the default worker script). Future worker entries may let applications opt into
130
+ lighter worker bundles when JP2K or HTJ2K codecs are not needed.
131
+
132
+ Contributor note: new worker-backed entry points should follow the documented
133
+ [worker bundling pattern](https://github.com/Taylor-CCB-Group/SpatialData.js/blob/main/docs/docs/worker-bundling.mdx)
134
+ so consumers can use package APIs without passing private worker URLs.
@@ -43,4 +43,4 @@ async function s(t, r, a) {
43
43
  //#endregion
44
44
  export { r as n, a as r, s as t };
45
45
 
46
- //# sourceMappingURL=chunkDecode-Dtm8HfWS.js.map
46
+ //# sourceMappingURL=chunkDecode-CvE5qLLQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chunkDecode-Dtm8HfWS.js","names":[],"sources":["../src/chunkDecode.ts"],"sourcesContent":["import * as zarr from 'zarrita';\nimport type { WorkerPool } from '@fideus-labs/worker-pool';\nimport type { ChunkCache, GetWorkerOptions } from '@fideus-labs/fizarrita';\n\nexport type ZarrGetOptions = {\n signal?: AbortSignal;\n};\n\nexport type FizarritaGetWorkerOptions = Pick<\n GetWorkerOptions,\n 'workerUrl' | 'useSharedArrayBuffer' | 'cache'\n> & {\n pool: WorkerPool;\n};\n\nexport type ChunkDecodeBackend =\n | { kind: 'main' }\n | {\n kind: 'fizarrita';\n pool: WorkerPool;\n options?: Omit<FizarritaGetWorkerOptions, 'pool'>;\n };\n\nlet chunkDecodeBackend: ChunkDecodeBackend = { kind: 'main' };\n\nexport function getChunkDecodeBackend(): ChunkDecodeBackend {\n return chunkDecodeBackend;\n}\n\nexport function setChunkDecodeBackend(backend: ChunkDecodeBackend): void {\n chunkDecodeBackend = backend;\n}\n\ntype GetWorkerFn = (\n arr: zarr.Array<zarr.DataType>,\n selection: Array<number | zarr.Slice | null> | null,\n options: FizarritaGetWorkerOptions\n) => Promise<zarr.Chunk<zarr.DataType>>;\n\nlet getWorkerImpl: GetWorkerFn | undefined;\n\nexport function setFizarritaGetWorker(impl: GetWorkerFn): void {\n getWorkerImpl = impl;\n}\n\nfunction rejectOnAbort<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) {\n return promise;\n }\n if (signal.aborted) {\n return Promise.reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n }\n return new Promise((resolve, reject) => {\n const onAbort = () => {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', onAbort);\n reject(error);\n }\n );\n });\n}\n\nexport async function getZarrChunk<D extends zarr.DataType>(\n arr: zarr.Array<D>,\n selection: Array<number | zarr.Slice | null>,\n opts?: ZarrGetOptions\n): Promise<zarr.Chunk<D>> {\n const backend = getChunkDecodeBackend();\n if (backend.kind === 'fizarrita') {\n if (!getWorkerImpl) {\n throw new Error(\n 'Worker chunk decode is enabled but fizarrita getWorker is not loaded. ' +\n 'Import from zarrextra/workers instead of setting the backend directly.'\n );\n }\n const result = await rejectOnAbort(\n getWorkerImpl(arr, selection, {\n pool: backend.pool,\n workerUrl: backend.options?.workerUrl,\n useSharedArrayBuffer: backend.options?.useSharedArrayBuffer,\n cache: backend.options?.cache,\n }),\n opts?.signal\n );\n if (typeof result !== 'object' || result === null || !('data' in result)) {\n throw new Error('Expected chunk object from fizarrita getWorker().');\n }\n return result as zarr.Chunk<D>;\n }\n\n const result = await zarr.get(arr, selection, opts);\n if (typeof result !== 'object' || result === null || !('data' in result)) {\n throw new Error('Expected chunk object from zarr.get().');\n }\n return result as zarr.Chunk<D>;\n}\n"],"mappings":";;AAuBA,IAAI,IAAyC,EAAE,MAAM,QAAQ;AAE7D,SAAgB,IAA4C;AAC1D,QAAO;;AAGT,SAAgB,EAAsB,GAAmC;AACvE,KAAqB;;AASvB,IAAI;AAEJ,SAAgB,EAAsB,GAAyB;AAC7D,KAAgB;;AAGlB,SAAS,EAAiB,GAAqB,GAAkC;AAO/E,QANK,IAGD,EAAO,UACF,QAAQ,OAAO,EAAO,UAAU,IAAI,aAAa,WAAW,aAAa,CAAC,GAE5E,IAAI,SAAS,GAAS,MAAW;EACtC,IAAM,UAAgB;AACpB,KAAO,EAAO,UAAU,IAAI,aAAa,WAAW,aAAa,CAAC;;AAGpE,EADA,EAAO,iBAAiB,SAAS,GAAS,EAAE,MAAM,IAAM,CAAC,EACzD,EAAQ,MACL,MAAU;AAET,GADA,EAAO,oBAAoB,SAAS,EAAQ,EAC5C,EAAQ,EAAM;MAEf,MAAmB;AAElB,GADA,EAAO,oBAAoB,SAAS,EAAQ,EAC5C,EAAO,EAAM;IAEhB;GACD,GApBO;;AAuBX,eAAsB,EACpB,GACA,GACA,GACwB;CACxB,IAAM,IAAU,GAAuB;AACvC,KAAI,EAAQ,SAAS,aAAa;AAChC,MAAI,CAAC,EACH,OAAU,MACR,+IAED;EAEH,IAAM,IAAS,MAAM,EACnB,EAAc,GAAK,GAAW;GAC5B,MAAM,EAAQ;GACd,WAAW,EAAQ,SAAS;GAC5B,sBAAsB,EAAQ,SAAS;GACvC,OAAO,EAAQ,SAAS;GACzB,CAAC,EACF,GAAM,OACP;AACD,MAAI,OAAO,KAAW,aAAY,KAAmB,EAAE,UAAU,GAC/D,OAAU,MAAM,oDAAoD;AAEtE,SAAO;;CAGT,IAAM,IAAS,MAAM,EAAK,IAAI,GAAK,GAAW,EAAK;AACnD,KAAI,OAAO,KAAW,aAAY,KAAmB,EAAE,UAAU,GAC/D,OAAU,MAAM,yCAAyC;AAE3D,QAAO"}
1
+ {"version":3,"file":"chunkDecode-CvE5qLLQ.js","names":[],"sources":["../src/chunkDecode.ts"],"sourcesContent":["import * as zarr from 'zarrita';\nimport type { WorkerPool } from '@fideus-labs/worker-pool';\nimport type { ChunkCache, GetWorkerOptions } from '@fideus-labs/fizarrita';\n\nexport type ZarrGetOptions = {\n signal?: AbortSignal;\n};\n\nexport type FizarritaGetWorkerOptions = Pick<\n GetWorkerOptions,\n 'workerUrl' | 'useSharedArrayBuffer' | 'cache'\n> & {\n pool: WorkerPool;\n};\n\nexport type ChunkDecodeBackend =\n | { kind: 'main' }\n | {\n kind: 'fizarrita';\n pool: WorkerPool;\n options?: Omit<FizarritaGetWorkerOptions, 'pool'>;\n };\n\nlet chunkDecodeBackend: ChunkDecodeBackend = { kind: 'main' };\n\nexport function getChunkDecodeBackend(): ChunkDecodeBackend {\n return chunkDecodeBackend;\n}\n\nexport function setChunkDecodeBackend(backend: ChunkDecodeBackend): void {\n chunkDecodeBackend = backend;\n}\n\ntype GetWorkerFn = (\n arr: zarr.Array<zarr.DataType>,\n selection: Array<number | zarr.Slice | null> | null,\n options: FizarritaGetWorkerOptions\n) => Promise<zarr.Chunk<zarr.DataType>>;\n\nlet getWorkerImpl: GetWorkerFn | undefined;\n\nexport function setFizarritaGetWorker(impl: GetWorkerFn): void {\n getWorkerImpl = impl;\n}\n\nfunction rejectOnAbort<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) {\n return promise;\n }\n if (signal.aborted) {\n return Promise.reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n }\n return new Promise((resolve, reject) => {\n const onAbort = () => {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', onAbort);\n reject(error);\n }\n );\n });\n}\n\nexport async function getZarrChunk<D extends zarr.DataType>(\n arr: zarr.Array<D>,\n selection: Array<number | zarr.Slice | null>,\n opts?: ZarrGetOptions\n): Promise<zarr.Chunk<D>> {\n const backend = getChunkDecodeBackend();\n if (backend.kind === 'fizarrita') {\n if (!getWorkerImpl) {\n throw new Error(\n 'Worker chunk decode is enabled but fizarrita getWorker is not loaded. ' +\n 'Import from zarrextra/workers instead of setting the backend directly.'\n );\n }\n const result = await rejectOnAbort(\n getWorkerImpl(arr, selection, {\n pool: backend.pool,\n workerUrl: backend.options?.workerUrl,\n useSharedArrayBuffer: backend.options?.useSharedArrayBuffer,\n cache: backend.options?.cache,\n }),\n opts?.signal\n );\n if (typeof result !== 'object' || result === null || !('data' in result)) {\n throw new Error('Expected chunk object from fizarrita getWorker().');\n }\n return result as zarr.Chunk<D>;\n }\n\n const result = await zarr.get(arr, selection, opts);\n if (typeof result !== 'object' || result === null || !('data' in result)) {\n throw new Error('Expected chunk object from zarr.get().');\n }\n return result as zarr.Chunk<D>;\n}\n"],"mappings":";;AAuBA,IAAI,IAAyC,EAAE,MAAM,QAAQ;AAE7D,SAAgB,IAA4C;AAC1D,QAAO;;AAGT,SAAgB,EAAsB,GAAmC;AACvE,KAAqB;;AASvB,IAAI;AAEJ,SAAgB,EAAsB,GAAyB;AAC7D,KAAgB;;AAGlB,SAAS,EAAiB,GAAqB,GAAkC;AAO/E,QANK,IAGD,EAAO,UACF,QAAQ,OAAO,EAAO,UAAU,IAAI,aAAa,WAAW,aAAa,CAAC,GAE5E,IAAI,SAAS,GAAS,MAAW;EACtC,IAAM,UAAgB;AACpB,KAAO,EAAO,UAAU,IAAI,aAAa,WAAW,aAAa,CAAC;;AAGpE,EADA,EAAO,iBAAiB,SAAS,GAAS,EAAE,MAAM,IAAM,CAAC,EACzD,EAAQ,MACL,MAAU;AAET,GADA,EAAO,oBAAoB,SAAS,EAAQ,EAC5C,EAAQ,EAAM;MAEf,MAAmB;AAElB,GADA,EAAO,oBAAoB,SAAS,EAAQ,EAC5C,EAAO,EAAM;IAEhB;GACD,GApBO;;AAuBX,eAAsB,EACpB,GACA,GACA,GACwB;CACxB,IAAM,IAAU,GAAuB;AACvC,KAAI,EAAQ,SAAS,aAAa;AAChC,MAAI,CAAC,EACH,OAAU,MACR,+IAED;EAEH,IAAM,IAAS,MAAM,EACnB,EAAc,GAAK,GAAW;GAC5B,MAAM,EAAQ;GACd,WAAW,EAAQ,SAAS;GAC5B,sBAAsB,EAAQ,SAAS;GACvC,OAAO,EAAQ,SAAS;GACzB,CAAC,EACF,GAAM,OACP;AACD,MAAI,OAAO,KAAW,aAAY,KAAmB,EAAE,UAAU,GAC/D,OAAU,MAAM,oDAAoD;AAEtE,SAAO;;CAGT,IAAM,IAAS,MAAM,EAAK,IAAI,GAAK,GAAW,EAAK;AACnD,KAAI,OAAO,KAAW,aAAY,KAAmB,EAAE,UAAU,GAC/D,OAAU,MAAM,yCAAyC;AAE3D,QAAO"}