### Install @zarrita/storage Source: https://github.com/manzt/zarrita.js/blob/main/packages/@zarrita-storage/README.md Install the package using npm. ```sh npm install @zarrita/storage ``` -------------------------------- ### Install Dependencies and Build Project Source: https://github.com/manzt/zarrita.js/blob/main/CONTRIBUTING.md Install project dependencies and build all packages using pnpm. ```bash pnpm install # install dependencies pnpm build # build all packages pnpm test # run tests ``` -------------------------------- ### Install @zarrita/ndarray Source: https://github.com/manzt/zarrita.js/blob/main/packages/@zarrita-ndarray/README.md Install the @zarrita/ndarray package using npm. ```sh npm install @zarrita/ndarray ``` -------------------------------- ### Install zarrita.js with npm Source: https://github.com/manzt/zarrita.js/blob/main/README.md Install the zarrita package using npm for Node.js applications. ```sh npm install zarrita ``` -------------------------------- ### Usage Example: Open Remote and Create Local Zarr Stores Source: https://github.com/manzt/zarrita.js/blob/main/packages/@zarrita-storage/README.md Demonstrates opening a remote Zarr array using FetchStore and creating a local Zarr array using FileSystemStore. Ensure the remote store is accessible and the local path is valid. ```javascript import * as zarr from "zarrita"; import { FetchStore, FileSystemStore } from "@zarrita/storage"; let remoteStore = new FetchStore("http://localhost:8080/data.zarr"); let arr = await zarr.open(remoteStore, { kind: "array" }); let localStore = new FileSystemStore("data.zarr"); await zarr.create(localStore, { data_type: "int64", shape: [100, 100], chunk_shape: [10, 10], }); ``` -------------------------------- ### Load Zarr Array with Import Map (unpkg) Source: https://github.com/manzt/zarrita.js/blob/main/docs/get-started.md This example demonstrates using an import map with unpkg to load Zarrita and its dependencies in vanilla HTML. It includes the necessary import map configuration and script to open a Zarr array. ```html ``` -------------------------------- ### Install Zarrita via yarn Source: https://github.com/manzt/zarrita.js/blob/main/docs/get-started.md Install Zarrita in your Node.js project using yarn. This command is for installing the package. ```sh yarn add zarrita ``` -------------------------------- ### Install Zarrita via pnpm Source: https://github.com/manzt/zarrita.js/blob/main/docs/get-started.md Install Zarrita in your Node.js project using pnpm. This command is for installing the package. ```sh pnpm add zarrita ``` -------------------------------- ### Load Zarr Array from CDN (esm.sh) Source: https://github.com/manzt/zarrita.js/blob/main/docs/get-started.md This HTML snippet shows how to load Zarrita from esm.sh, similar to the jsDelivr example, for use in vanilla HTML projects. It includes importing the library and opening a Zarr array. ```html ``` -------------------------------- ### Define Async Store Extension with Logging Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Create an extension that logs `get` operations. The caller owns the logging function, keeping the store type clean. ```typescript import * as zarr from "zarrita"; const withTrace = zarr.defineStoreExtension( (store, extOptions: { log: (key: string) => void }) => ({ async get(key, options) { extOptions.log(key); return store.get(key, options); }, }), ); let store = withTrace(new zarr.FetchStore("https://..."), { log: (key) => console.log("fetching", key), }); ``` -------------------------------- ### Define Virtual Zarr Store Extension for HDF5 Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Create a store extension to adapt HDF5 files as virtual Zarr arrays. This example demonstrates synthesizing metadata and providing chunk data through shared closure state, enabling downstream code to access HDF5 data as if it were Zarr. ```typescript import * as zarr from "zarrita"; const hdf5VirtualZarr = zarr.defineStoreExtension( (inner, opts: { root: string }) => { let parsed = parseHdf5(opts.root); // shared closure state return { async get(key, options) { if (isVirtualMetadataKey(key, parsed)) { return synthesizeJson(key, parsed); } return inner.get(key, options); }, arrayExtensions: [ zarr.defineArrayExtension(() => ({ async getChunk(coords) { return parsed.readChunk(coords); }, })), ], }; }, ); let store = await zarr.extendStore(raw, (s) => hdf5VirtualZarr(s, { root: "/my_image" }), ); // Downstream code knows nothing about the adapter; it just opens and reads. let arr = await zarr.open(store, { kind: "array", path: "/my_image" }); await zarr.get(arr, [null, zarr.slice(0, 10)]); ``` -------------------------------- ### Open and Slice Zarr Array Source: https://github.com/manzt/zarrita.js/blob/main/packages/@zarrita-ndarray/README.md Open a Zarr array and retrieve a specific region using the get and slice functions. Ensure the zarr module is imported. ```javascript import { get, slice } from "@zarrita/ndarray"; let arr = await zarr.open(group.resolve("foo"), { kind: "array" }); let region = await get(arr, [slice(10, 20), null, 0]); ``` -------------------------------- ### Get Array Region in zarrita Source: https://github.com/manzt/zarrita.js/blob/main/docs/what-is-zarrita.md Loads a specified region from a Zarr array. The `get` function handles chunk loading and data stitching. ```javascript const region = await get(arr, [null, null]); // { // data: Uint16Array([ 1, 2, 3, 4]), // shape: [2, 2], // stride: [2, 1], // } ``` -------------------------------- ### Define and Apply Chunk Cache Array Extension Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Implement a chunk caching extension for Zarr arrays. This example shows how to define a custom `getChunk` interceptor that caches chunks in a Map, improving performance for repeated accesses. ```typescript import * as zarr from "zarrita"; const withChunkCache = zarr.defineArrayExtension( (array, extOptions: { cache: Map> }) => ({ async getChunk(coords, options) { let key = coords.join(","); let hit = extOptions.cache.get(key); if (hit) return hit; let chunk = await array.getChunk(coords, options); extOptions.cache.set(key, chunk); return chunk; }, }), ); let arr = await zarr.extendArray( await zarr.open(store, { kind: "array" }), (a) => withChunkCache(a, { cache: new Map() }), ); await zarr.get(arr, null); // cache hits are served from the Map ``` -------------------------------- ### Define Store Extension with Namespaced Events Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md An extension that adds an `events` namespace to the store for subscribing to store operations like 'get' and 'error'. This keeps the top-level store API clean. ```typescript type StoreEvent = | { type: "get"; key: zarr.AbsolutePath; durationMs: number } | { type: "error"; key: zarr.AbsolutePath; error: unknown }; const withEvents = zarr.defineStoreExtension((store) => { let listeners = new Set<(event: StoreEvent) => void>(); return { async get(key, options) { let started = performance.now(); try { let value = await store.get(key, options); for (let fn of listeners) { fn({ type: "get", key, durationMs: performance.now() - started }); } return value; } catch (error) { for (let fn of listeners) fn({ type: "error", key, error }); throw error; } }, events: { subscribe(fn: (event: StoreEvent) => void): () => void { listeners.add(fn); return () => listeners.delete(fn); }, }, }; }); let store = withEvents(base); let unsubscribe = store.events.subscribe((e) => { if (e.type === "error") console.error("store error", e); }); ``` -------------------------------- ### Serve Demo Files Locally Source: https://github.com/manzt/zarrita.js/blob/main/CONTRIBUTING.md Serve the project's demo files locally using Python's http.server after building. Navigate to the specified localhost URL in your browser to test. ```bash uv run python -m http.server . # navigate to localhost:8000/demo.html ``` -------------------------------- ### Initialize ReferenceStore from Specification Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md The experimental ReferenceStore enables efficient random access from monolithic binary files mapped to Zarr, by reading a reference file specification produced by kerchunk. Fetch the JSON specification and then initialize the store. ```javascript import { ReferenceStore } from "@zarrita/storage"; const response = await fetch("http://localhost:8080/refs.json"); const store = await ReferenceStore.fromSpec(await response.json()); ``` -------------------------------- ### Initialize FileSystemStore Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md Use FileSystemStore for server-side JavaScript environments with file system access, such as Node.js, Bun, or Deno. It is built upon the Node.js `fs` module. ```javascript import { FileSystemStore } from "@zarrita/storage"; const store = new FileSystemStore("data.zarr"); ``` -------------------------------- ### Get Array Region as Ndarray Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/ndarray.md Retrieves a region of the array and returns it as a scijs/ndarray object. This is useful when you need to work with array data using ndarray's capabilities. ```javascript const region = await get(arr, [null, null]); // ndarray.NdArray ``` -------------------------------- ### FetchStore.get with options Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md When making individual requests using FetchStore.get, you can supply specific options as the second argument, such as additional headers or an AbortSignal. ```APIDOC ## FetchStore.get with options ### Description Allows specifying per-request options when fetching data from a store. ### Method `get(url: string, options?: RequestInit)` ### Parameters #### Request Options - **headers** (object) - Optional - Additional headers to send with the request. - **signal** (AbortSignal) - Optional - An AbortSignal to cancel the request. ### Request Example ```javascript const controller = new AbortController(); const bytes = await store.get("/zarr.json", { headers: { foo: "bar" }, signal: controller.signal, }); ``` ### Notes These per-request options are merged into the `Request` passed to your custom `fetch` (or the global `fetch` if none is provided). Headers are merged, with per-request headers taking precedence. ``` -------------------------------- ### Initialize FetchStore Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md Instantiates a FetchStore to access Zarr data over HTTP. This store is compatible with environments supporting the Fetch API. ```javascript import { FetchStore } from "@zarrita/storage"; const store = new FetchStore("http://localhost:8080/data.zarr"); ``` -------------------------------- ### Custom Byte Cache with QuickLRU Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Shows how to use a custom LRU cache with `zarr.withByteCaching` by passing an instance of `quick-lru`. This allows for bounded cache sizes and LRU eviction. The cache can be directly controlled via its reference. ```typescript import QuickLRU from "quick-lru"; let cache = new QuickLRU({ maxSize: 256 }); let store = await zarr.extendStore( new zarr.FetchStore("https://example.com/data.zarr"), (s) => zarr.withByteCaching(s, { cache }), ); cache.clear(); // direct control via the user-owned reference ``` -------------------------------- ### Specify Request Options for FetchStore.get Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md Pass specific options like custom headers or an AbortSignal as the second argument to `FetchStore.get` for individual requests. These options are merged with existing request configurations, with per-request options taking precedence. ```javascript const controller = new AbortController(); const bytes = await store.get("/zarr.json", { headers: { foo: "bar" }, signal: controller.signal, }); ``` -------------------------------- ### Composing Store Extensions Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Demonstrates how to compose multiple store extensions, including consolidated metadata, range coalescing, and byte caching, using `zarr.extendStore`. ```APIDOC ## Composing Store Extensions ### Description Wrap a store with `zarr.defineStoreExtension`, then compose with `zarr.extendStore`. **zarrita** ships three store extensions: consolidated metadata, range coalescing, and caching. ### Usage ```ts import * as zarr from "zarrita"; let store = await zarr.extendStore( new zarr.FetchStore("https://example.com/data.zarr"), zarr.withConsolidatedMetadata, (s) => zarr.withRangeCoalescing(s, { coalesceSize: 32768 }), (s) => zarr.withByteCaching(s), ); store.contents(); // from zarr.withConsolidatedMetadata ``` ### Byte Cache Interface By default `withByteCaching` caches every store request. To control the cache, for example to bound its size with LRU eviction, pass a `cache` option implementing the `ByteCache` interface: ```ts export interface ByteCache { has(key: string): boolean; get(key: string): Uint8Array | undefined; set(key: string, value: Uint8Array | undefined): void; } ``` ### Customizing Cache Policy To narrow or reshape the cache policy, for example to cache only metadata files and skip chunk data, pass your own `keyFor` function. It returns a string to cache the result under, or `undefined` to skip caching that call: ```ts let store = await zarr.extendStore( new zarr.FetchStore("https://example.com/data.zarr"), (s) => zarr.withByteCaching(s, { keyFor(path, range) { if (range !== undefined) return undefined; return /\/(zarr\.json|\.zarray|\.zattrs|\.zgroup)$/.test(path) ? path : undefined; }, }), ); ``` ### Async Handling Each extension wraps the previous result. `zarr.extendStore` handles async extensions (like `zarr.withConsolidatedMetadata`, which fetches metadata during initialization) automatically — returning a `Promise` only when at least one extension is async, and returning synchronously otherwise. An extension with no required options can be passed uncalled; otherwise wrap it in an arrow so the options are applied to the argument. ``` -------------------------------- ### FileSystemStore Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md The FileSystemStore is designed for JavaScript runtimes with file system access, such as Node.js, Bun, and Deno. It is built atop the Node.js 'fs' module. ```APIDOC ## FileSystemStore ### Description A store implementation for environments with file system access. ### Usage ```javascript import { FileSystemStore } from "@zarrita/storage"; const store = new FileSystemStore("data.zarr"); ``` ``` -------------------------------- ### Compose Zarrita Store Extensions Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Demonstrates composing multiple store extensions including consolidated metadata, range coalescing, and byte caching. Use `zarr.extendStore` to chain extensions, passing them as arguments. Extensions with options must be wrapped in an arrow function. ```typescript import * as zarr from "zarrita"; let store = await zarr.extendStore( new zarr.FetchStore("https://example.com/data.zarr"), zarr.withConsolidatedMetadata, (s) => zarr.withRangeCoalescing(s, { coalesceSize: 32768 }), (s) => zarr.withByteCaching(s), ); store.contents(); // from zarr.withConsolidatedMetadata ``` -------------------------------- ### FetchStore Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md The FetchStore enables Zarr to use HTTP-based storage. It's compatible with environments supporting the Fetch API, such as browsers, Node.js, and Deno. You can initialize it with a base URL for your Zarr data. ```APIDOC ## FetchStore ### Description A storage solution based on HTTP requests using the Fetch API. Compatible anywhere `fetch` is available. ### Usage ```javascript import { FetchStore } from "@zarrita/storage"; const store = new FetchStore("http://localhost:8080/data.zarr"); ``` ### Response Handling | Status | Meaning | | ------------- | ------------------------------------------ | | **404** | Missing key — returns `undefined` | | **200 / 206** | Success — body is read as `Uint8Array` | | **Any other** | Throws an error | ### Custom Fetch Handler Allows intercepting and modifying requests. Useful for authentication, presigning URLs, or remapping status codes. When transforming requests, preserve original options using `new Request(newUrl, originalRequest)`. #### Example: Custom Fetch with URL Presigning ```javascript const store = new FetchStore("https://my-bucket.s3.amazonaws.com/data.zarr", { await fetch(request) { const newUrl = await presign(request.url); // Preserves headers, abort signal, and other options from store.get(key, init) return fetch(new Request(newUrl, request)); } }); ``` #### Example: Adding Authentication Headers ```javascript const store = new FetchStore("https://example.com/data.zarr", { await fetch(request) { const token = await getAccessToken(); request.headers.set("Authorization", `Bearer ${token}`); return fetch(request); } }); ``` #### Example: Handling S3 403 Responses for Missing Keys ```javascript const store = new FetchStore("https://my-bucket.s3.amazonaws.com/data.zarr", { await fetch(request) { const response = await fetch(request); if (response.status === 403) { return new Response(null, { status: 404 }); } return response; } }); ``` ``` -------------------------------- ### Calling Store Extensions Directly Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Shows how individual store extensions can be called directly, bypassing the `zarr.extendStore` composition. ```APIDOC ## Calling Store Extensions Directly ### Description Extensions can also be called directly without using `zarr.extendStore`. ### Usage ```ts let consolidated = await zarr.withConsolidatedMetadata( new zarr.FetchStore("https://example.com/data.zarr"), { format: "v3" }, ); ``` ``` -------------------------------- ### Initialize ZipFileStore from URL or Blob Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md The experimental ZipFileStore allows reading a Zarr store from a single Zip archive. It supports remote reading via HTTP range-requests or in-memory from a Blob. ```javascript import { ZipFileStore } from "@zarrita/storage"; const store = ZipFileStore.fromUrl("http://localhost:8080/data.zarr.zip"); const store = ZipFileStore.fromBlob(blob); ``` -------------------------------- ### Load Zarr Array from CDN (jsDelivr) Source: https://github.com/manzt/zarrita.js/blob/main/docs/get-started.md Use this snippet in vanilla HTML to load Zarrita from jsDelivr and open a Zarr array from a remote URL. It demonstrates importing the library and accessing array data. ```html ``` -------------------------------- ### Directly Call Store Extension Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Demonstrates calling a store extension directly, bypassing `zarr.extendStore`. This is useful for applying a single extension or when the composition logic is simple. Note that async extensions will return a Promise. ```typescript let consolidated = await zarr.withConsolidatedMetadata( new zarr.FetchStore("https://example.com/data.zarr"), { format: "v3" }, ); ``` -------------------------------- ### ReferenceStore.fromSpec Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md The ReferenceStore supports reading the reference file specification produced by kerchunk. This method creates a store from a JSON specification. ```APIDOC ## ReferenceStore.fromSpec ### Description Creates a ReferenceStore instance from a JSON specification, enabling efficient random access from monolithic binary files. ### Usage ```javascript import { ReferenceStore } from "@zarrita/storage"; const response = await fetch("http://localhost:8080/refs.json"); const store = await ReferenceStore.fromSpec(await response.json()); ``` ``` -------------------------------- ### Open Zarr Store with Optional Consolidated Metadata Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Wraps a store to use consolidated metadata if available, otherwise falls back to standard metadata fetching. This is useful when consolidated metadata might be absent. ```js let store = await zarr.withMaybeConsolidatedMetadata( new zarr.FetchStore("https://localhost:8080/data.zarr"), ); ``` -------------------------------- ### Open and Read Zarr Array in JavaScript Source: https://github.com/manzt/zarrita.js/blob/main/README.md Demonstrates opening a Zarr array from a FetchStore and reading its chunks or full data. Supports built-in getters or optional scijs/ndarray integration. ```javascript import * as zarr from "zarrita"; const store = new zarr.FetchStore("http://localhost:8080/data.zarr"); const arr = await zarr.open(store, { kind: "array" }); // zarr.Array // read chunk const chunk = await arr.getChunk([0, 0]); // Option 1: Builtin getter, no dependencies const full = await zarr.get(arr); // { data: Int32Array, shape: number[], stride: number[] } // Option 2: scijs/ndarray getter, includes `ndarray` and `ndarray-ops` dependencies import { get } from "@zarrita/ndarray"; const full = await get(arr); // ndarray.Ndarray // read region const region = await get(arr, [null, zarr.slice(6)]); ``` -------------------------------- ### Navigation with Location Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/zarrita.md The `Location` primitive helps navigate through a storage hierarchy by associating a path with a store and provides a `resolve` helper. ```APIDOC ## Navigation with Location ### Description The `Location` primitive helps navigate through a storage hierarchy by associating a path with a store and provides a `resolve` helper. ### Method ```javascript import * as zarr from "zarrita"; let root = zarr.root(new zarr.FetchStore("http://localhost:8080/data.zarr")); root.store; // FetchStore root.path; // "/" let bar = root.resolve("foo/bar"); bar.store; // FetchStore bar.path; // "/foo/bar" let foo = bar.resolve("/foo"); foo.store; // FetchStore foo.path; // "/foo" ``` ``` -------------------------------- ### FetchStore with Authentication Headers Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md Adds authentication headers to requests made by FetchStore. The fetch handler can dynamically refresh credentials. ```javascript const store = new FetchStore("https://example.com/data.zarr", { await fetch(request) { const token = await getAccessToken(); request.headers.set("Authorization", `Bearer ${token}`); return fetch(request); } }); ``` -------------------------------- ### Open a Zarr Group Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Opens an existing Zarr group from a store. Useful for navigating Zarr hierarchies. Requires the store to be accessible. ```js import * as zarr from "zarrita"; const store = new zarr.FetchStore("http://localhost:8080/data.zarr"); const group = await zarr.open(store, { kind: "group" }); group; // zarr.Group ``` -------------------------------- ### Open a Zarr Array Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Opens an existing Zarr array from a store. Useful for reading data. Requires the store to be accessible. ```js import * as zarr from "zarrita"; const store = new zarr.FetchStore("http://localhost:8080/data.zarr"); const arr = await zarr.open(store, { kind: "array" }); arr; // zarr.Array arr.shape; // [5, 10] arr.chunks; // [2, 5] arr.dtype; // "int32" ``` -------------------------------- ### Navigate Zarr Hierarchy with Location Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/zarrita.md Use the `Location` primitive to associate a path with a store and resolve nested paths within the Zarr hierarchy. ```javascript import * as zarr from "zarrita"; let root = zarr.root(new zarr.FetchStore("http://localhost:8080/data.zarr")); root.store; // FetchStore root.path; // "/" let bar = root.resolve("foo/bar"); bar.store; // FetchStore bar.path; // "/foo/bar" let foo = bar.resolve("/foo"); foo.store; // FetchStore foo.path; // "/foo" ``` -------------------------------- ### Import Zarrita Namespace Source: https://github.com/manzt/zarrita.js/blob/main/docs/get-started.md Load the entire Zarrita module as a namespace in your JavaScript application. This is a common way to import libraries. ```javascript import * as zarr from "zarrita"; const arr = await zarr.open(store); ``` -------------------------------- ### Define Async Store Extension with Metadata Loading Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md An extension that asynchronously loads metadata from a specified key. The loaded metadata is accessible via a `metadata()` method. ```typescript const withMetadata = zarr.defineStoreExtension( async (store, extOptions: { key: zarr.AbsolutePath }) => { let bytes = await store.get(extOptions.key); let meta = JSON.parse(new TextDecoder().decode(bytes)); return { metadata() { return meta; }, }; }, ); let store = await withMetadata(rawStore, { key: "/meta.json" }); store.metadata(); // loaded during initialization ``` -------------------------------- ### Add a Changeset for User-Facing Changes Source: https://github.com/manzt/zarrita.js/blob/main/CONTRIBUTING.md Use this command to add a changeset for user-facing changes like bug fixes or new features. This will prompt for package selection and version bump type, creating a markdown file in the .changeset/ directory. ```bash pnpm changeset ``` -------------------------------- ### Open Zarr Store with Consolidated Metadata Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Wraps a store to use consolidated metadata, reducing network requests for metadata. It automatically detects v2 (.zmetadata) or v3 (consolidated_metadata) formats. ```js import * as zarr from "zarrita"; let store = await zarr.withConsolidatedMetadata( new zarr.FetchStore("https://localhost:8080/data.zarr") ); // The following do not incur network requests for metadata let root = await zarr.open(store, { kind: "group" }); let foo = await zarr.open(root.resolve("foo"), { kind: "array" }); ``` ```js store.contents(); // [{ path: "/", kind: "group" }, { path: "/foo", kind: "array" }, ...] ``` ```js // v2 only let store = await zarr.withConsolidatedMetadata(rawStore, { format: "v2" }); ``` ```js // v3 only let store = await zarr.withConsolidatedMetadata(rawStore, { format: "v3" }); ``` ```js // try v3 first, fall back to v2 let store = await zarr.withConsolidatedMetadata(rawStore, { format: ["v3", "v2"] }); ``` -------------------------------- ### Open an array or group Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/zarrita.md Using a `Location`, you can access an array or group with the `open` function. You can also specify the `kind` to enforce a specific node type. ```APIDOC ## Open an array or group ### Description Using a `Location`, you can access an array or group with the `open` function. You can also specify the `kind` to enforce a specific node type. ### Method ```javascript import * as zarr from "zarrita"; let root = zarr.root(new zarr.FetchStore("http://localhost:8080/data.zarr")); let node = await zarr.open(root); node; // zarr.Array | zarr.Group // Enforce specific node type let grp = await zarr.open(root.resolve("foo"), { kind: "group" }); let arr = await zarr.open(root.resolve("foo/bar"), { kind: "array" }); // Open specific Zarr versions let arr_v2 = await zarr.open.v2(root.resolve("foo/bar"), { kind: "array" }); ``` ``` -------------------------------- ### Define Store Extension with Logging (Externalized State) Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md A simple logging extension where the logging function is passed as an option, externalizing the state. ```typescript const withLogging = zarr.defineStoreExtension( (store, opts: { log: (msg: string) => void }) => ({ async get(key, options) { opts.log(`get ${key}`); return store.get(key, options); }, }), ); ``` -------------------------------- ### Byte Caching with Custom Key Function Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Illustrates how to customize the byte caching policy by providing a `keyFor` function. This function determines which requests are cached by returning a cache key string or `undefined` to skip caching. ```typescript let store = await zarr.extendStore( new zarr.FetchStore("https://example.com/data.zarr"), (s) => zarr.withByteCaching(s, { keyFor(path, range) { if (range !== undefined) return undefined; return /\/(zarr\.json|\.zarray|\.zattrs|\.zgroup)$/.test(path) ? path : undefined; }, }), ); ``` -------------------------------- ### Sync JSR Configuration Source: https://github.com/manzt/zarrita.js/blob/main/CONTRIBUTING.md Synchronize JSR configuration files (jsr.json) from package.json. This script is automatically run during the 'pnpm version' process to keep JSR configurations up-to-date with package versions and dependencies. ```bash node scripts/sync-jsr.mjs ``` -------------------------------- ### Create an array or group Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/zarrita.md Given a `Location`, you can create a new array or group using the `create` function. Specify `dtype`, `shape`, and `chunkShape` for arrays. ```APIDOC ## Create an array or group ### Description Given a `Location`, you can create a new array or group using the `create` function. Specify `dtype`, `shape`, and `chunkShape` for arrays. ### Method ```javascript import * as zarr from "zarrita"; let root = zarr.root(new Map()); let grp = await zarr.create(root); let arr = await zarr.create(root.resolve("foo"), { dtype: "int32", shape: [4, 4], chunkShape: [2, 2], }); console.log(root.store); // Map(2) { // '/zarr.json' => Uint8Array(66) [ ... ], // '/foo/zarr.json' => Uint8Array(392) [ ... ], // } ``` ``` -------------------------------- ### FetchStore with Custom Fetch Handler Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md Configures FetchStore with a custom fetch function to intercept requests. This is useful for adding authentication, presigning URLs, or transforming requests. ```javascript const store = new FetchStore("https://my-bucket.s3.amazonaws.com/data.zarr", { await fetch(request) { const newUrl = await presign(request.url); // Preserves headers, abort signal, and other options from store.get(key, init) return fetch(new Request(newUrl, request)); } }); ``` -------------------------------- ### Import Specific Zarrita Export Source: https://github.com/manzt/zarrita.js/blob/main/docs/get-started.md Import only the 'open' function from Zarrita to reduce bundle size. This method is useful for optimizing frontend applications. ```javascript import { open } from "zarrita"; const arr = await open(store); ``` -------------------------------- ### Open Zarr Array with Strict Version Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Opens a Zarr array while strictly enforcing Zarr v2 format. Use `open.v3` to enforce v3. This is useful when compatibility with a specific Zarr version is critical. ```js import * as zarr from "zarrita"; const store = new zarr.FetchStore("http://localhost:8080/data.zarr"); const arr = await zarr.open.v2(store, { kind: "array" }); ``` -------------------------------- ### Create a Zarr Group Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Creates a new Zarr group, optionally with attributes. Requires the store to implement the `Writable` interface. ```js import * as zarr from "zarrita"; import { FileSystemStore } from "@zarrita/storage"; const store = new FileSystemStore("tempstore"); const group = await zarr.create(store, { attributes: { answer: 42 }, }); group; // zarr.Group ``` -------------------------------- ### FetchStore Handling S3 403 Responses Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md Remaps S3's 403 status code for missing keys to 404, allowing FetchStore to correctly interpret 'not found' responses from private S3 buckets. ```javascript const store = new FetchStore("https://my-bucket.s3.amazonaws.com/data.zarr", { await fetch(request) { const response = await fetch(request); if (response.status === 403) { return new Response(null, { status: 404 }); } return response; } }); ``` -------------------------------- ### ZipFileStore.fromUrl Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md The ZipFileStore enables reading a Zarr store collected in a single Zip archive. This method allows reading remotely via HTTP range-requests. ```APIDOC ## ZipFileStore.fromUrl ### Description Creates a ZipFileStore instance from a URL pointing to a Zip archive. ### Usage ```javascript import { ZipFileStore } from "@zarrita/storage"; const store = ZipFileStore.fromUrl("http://localhost:8080/data.zarr.zip"); ``` ``` -------------------------------- ### Extend Store with Range Coalescing and Byte Caching Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Combines range coalescing to merge concurrent requests and byte caching to store results. Useful for optimizing chunked data reads over HTTP. ```javascript import * as zarr from "zarrita"; let store = await zarr.extendStore( new zarr.FetchStore("https://localhost:8080/data.zarr"), (s) => zarr.withRangeCoalescing(s), (s) => zarr.withByteCaching(s), ); let arr = await zarr.open(store, { kind: "array" }); ``` -------------------------------- ### Writable and AsyncWritable Interfaces Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md Defines the core interfaces for writing data to a store. `Writable` is synchronous, while `AsyncWritable` is asynchronous. ```typescript interface Writable { set(key: string, value: Uint8Array): void; } interface AsyncWritable { set(key: string, value: Uint8Array): Promise; } ``` -------------------------------- ### Create Zarr Array or Group Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/zarrita.md Create new Zarr arrays or groups within a store using the `create` function. This is useful for initializing new Zarr datasets. ```javascript import * as zarr from "zarrita"; let root = zarr.root(new Map()); let grp = await zarr.create(root); let arr = await zarr.create(root.resolve("foo"), { dtype: "int32", shape: [4, 4], chunkShape: [2, 2], }); console.log(root.store); // Map(2) { // '/zarr.json' => Uint8Array(66) [ ... ], // '/foo/zarr.json' => Uint8Array(392) [ ... ], // } ``` -------------------------------- ### Create a Zarr Array Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Creates a new Zarr array with specified data type, shape, and chunk shape. Requires the store to implement the `Writable` interface. ```js import * as zarr from "zarrita"; import { FileSystemStore } from "@zarrita/storage"; const store = new FileSystemStore("tempstore"); const arr = await zarr.create(store, { dtype: "int32", shape: [10, 10], chunkShape: [5, 5], }); arr; // zarr.Array<"int32", FileSystemStore> ``` -------------------------------- ### ZipFileStore.fromBlob Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md The ZipFileStore enables reading a Zarr store collected in a single Zip archive. This method allows reading in-memory from a Blob. ```APIDOC ## ZipFileStore.fromBlob ### Description Creates a ZipFileStore instance from a Blob object containing the Zip archive. ### Usage ```javascript import { ZipFileStore } from "@zarrita/storage"; const store = ZipFileStore.fromBlob(blob); ``` ``` -------------------------------- ### Open and Read Zarr V3 Data Source: https://github.com/manzt/zarrita.js/blob/main/demo.html Opens a Zarr group using the V3 API and iterates through various array fixtures. For each array, it retrieves data, shape, and stride, then displays this information in a preformatted HTML element. This demonstrates compatibility with the Zarr V3 specification. ```javascript { let grp = await zarr.open.v3(store.resolve("v3/data.zarr"), { kind: "group", }); for (let fixture of [ "1d.chunked.compressed.sharded.i2", "1d.chunked.filled.compressed.sharded.i2", "1d.chunked.i2", "1d.chunked.ragged.i2", "1d.contiguous.b1", "1d.contiguous.blosc.i2", "1d.contiguous.compressed.sharded.b1", "1d.contiguous.compressed.sharded.f4", "1d.contiguous.compressed.sharded.f8", "1d.contiguous.compressed.sharded.i2", "1d.contiguous.compressed.sharded.i4", "1d.contiguous.compressed.sharded.u1", "1d.contiguous.f4.be", "1d.contiguous.f4.le", "1d.contiguous.f8", "1d.contiguous.gzip.i2", "1d.contiguous.i4", "1d.contiguous.raw.i2", "1d.contiguous.u1", "2d.chunked.compressed.sharded.filled.i2", "2d.chunked.compressed.sharded.i2", "2d.chunked.i2", "2d.chunked.ragged.compressed.sharded.i2", "2d.chunked.ragged.i2", "2d.contiguous.compressed.sharded.i2", "2d.contiguous.i2", "3d.chunked.compressed.sharded.i2", "3d.chunked.i2", "3d.chunked.mixed.compressed.sharded.i2", "3d.chunked.mixed.i2.C", "3d.chunked.mixed.i2.F", "3d.contiguous.compressed.sharded.i2", "3d.contiguous.i2", ]) { let arr = await zarr.open.v3(grp.resolve(fixture), { kind: "array", }); let { data, shape, stride } = await zarr.get(arr); let pre = document.createElement("pre"); pre.textContent = `\ { path: ${JSON.stringify(arr.path)}, data: ${data.constructor.name}(${JSON.stringify(Array.from(data))}), shape: ${JSON.stringify(shape)}, stride: ${JSON.stringify(stride)}, }`; document.body.appendChild(pre); } } ``` -------------------------------- ### Open a Zarr Group or Array Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Opens a Zarr node (either an array or a group) from a store when the type is unknown. The function infers the type based on the store's contents. ```js import * as zarr from "zarrita"; const store = new zarr.FetchStore("http://localhost:8080/data.zarr"); const node = await zarr.open(store); node; // zarr.Array | zarr.Group ``` -------------------------------- ### Open Zarr Array or Group Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/zarrita.md Open a Zarr array or group from a given location. Specify the `kind` option to enforce a specific node type or use `open.v2`/`open.v3` for version-specific opening. ```javascript import * as zarr from "zarrita"; let root = zarr.root(new zarr.FetchStore("http://localhost:8080/data.zarr")); let node = await zarr.open(root); node; // zarr.Array | zarr.Group ``` ```javascript let grp = await zarr.open(root.resolve("foo"), { kind: "group" }); let arr = await zarr.open(root.resolve("foo/bar"), { kind: "array" }); ``` ```javascript let arr = await zarr.open.v2(root.resolve("foo/bar"), { kind: "array" }); ``` -------------------------------- ### Open and Read Zarr V2 Data Source: https://github.com/manzt/zarrita.js/blob/main/demo.html Opens a Zarr group using the V2 API and iterates through various array fixtures. For each array, it retrieves data, shape, and stride, then displays this information in a preformatted HTML element. This is useful for inspecting the contents of a Zarr archive. ```javascript import * as zarr from "zarrita"; let store = zarr.root(new zarr.FetchStore(new URL("fixtures", import.meta.url))); { let grp = await zarr.open.v2(store.resolve("v2/data.zarr"), { kind: "group", }); for (let fixture of [ "1d.chunked.i2", "1d.chunked.ragged.i2", "1d.contiguous.S7", "1d.contiguous.U13.be", "1d.contiguous.U13.le", "1d.contiguous.U7", "1d.contiguous.b1", "1d.contiguous.blosc.i2", "1d.contiguous.f4.be", "1d.contiguous.f4.le", "1d.contiguous.f8", "1d.contiguous.i4", "1d.contiguous.lz4.i2", "1d.contiguous.raw.i2", "1d.contiguous.u1", "1d.contiguous.zlib.i2", "1d.contiguous.zstd.i2", "2d.chunked.U7", "2d.chunked.i2", "2d.chunked.ragged.i2", "2d.contiguous.i2", "3d.chunked.i2", "3d.chunked.mixed.i2.C", "3d.chunked.mixed.i2.F", "3d.contiguous.i2", ]) { let arr = await zarr.open.v2(grp.resolve(fixture), { kind: "array", attrs: false, }); let { data, shape, stride } = await zarr.get(arr); let pre = document.createElement("pre"); pre.textContent = `\ { path: ${JSON.stringify(arr.path)}, data: ${data.constructor.name}(${JSON.stringify(Array.from(data))}), shape: ${JSON.stringify(shape)}, stride: ${JSON.stringify(stride)}, }`; document.body.appendChild(pre); } } ``` -------------------------------- ### Accessing Data Subsets with Zarrita.js Source: https://github.com/manzt/zarrita.js/blob/main/docs/slicing.md Use the `zarr.get` function with a selection of slices, indices, or null for each dimension to retrieve a specific subset of the array. The `zarr.slice` utility supports various forms of range specification. ```javascript import * as zarr from "zarrita"; const arr = await zarr.open(store, { kind: "array" }); const region = await zarr.get(arr, [zarr.slice(10, 20), null, 0]); ``` -------------------------------- ### Readable and AsyncReadable Interfaces Source: https://github.com/manzt/zarrita.js/blob/main/docs/packages/storage.md Defines the core interfaces for reading data from a store. `Readable` is synchronous, while `AsyncReadable` is asynchronous. ```typescript interface Readable { get(key: string, options?: { signal?: AbortSignal }): Uint8Array | undefined; } interface AsyncReadable { get(key: string, options?: { signal?: AbortSignal }): Promise; } ``` -------------------------------- ### Configure Range Coalescing Source: https://github.com/manzt/zarrita.js/blob/main/docs/cookbook.md Customizes range coalescing behavior by setting a custom coalesce size and providing a callback for flush reports. Use when default coalescing parameters are not optimal. ```javascript let store = zarr.withRangeCoalescing( new zarr.FetchStore("https://localhost:8080/data.zarr"), { coalesceSize: 65_536, // merge ranges within 64 KB of each other onFlush(report) { // { path, groupCount, requestCount, bytesFetched } console.log(report); }, }, ); ``` -------------------------------- ### Define ByteCache Interface Source: https://github.com/manzt/zarrita.js/blob/main/docs/store-extensions.md Defines the `ByteCache` interface required for customizing the byte caching extension. Any object implementing this interface, including a plain `Map` or an LRU cache, can be used. ```typescript export interface ByteCache { has(key: string): boolean; get(key: string): Uint8Array | undefined; set(key: string, value: Uint8Array | undefined): void; } ```