@loaders.gl/zarr
Version:
Framework-independent loaders for Zarr
1,447 lines (1,443 loc) • 677 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd) define([], factory);
else if (typeof exports === 'object') exports['loaders'] = factory();
else root['loaders'] = factory();})(globalThis, function () {
"use strict";
var __exports__ = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// external-global-plugin:@loaders.gl/core
var require_core = __commonJS({
"external-global-plugin:@loaders.gl/core"(exports, module) {
module.exports = globalThis.loaders;
}
});
// bundle.ts
var bundle_exports = {};
__export(bundle_exports, {
ZarrPixelSource: () => zarr_pixel_source_default,
loadZarr: () => loadZarr
});
__reExport(bundle_exports, __toESM(require_core(), 1));
// ../../node_modules/zarr/core.mjs
var registry = /* @__PURE__ */ new Map();
function addCodec(id, importFn) {
registry.set(id, importFn);
}
async function getCodec(config) {
if (!registry.has(config.id)) {
throw new Error(`Compression codec ${config.id} is not supported by Zarr.js yet.`);
}
const codec = await registry.get(config.id)();
return codec.fromConfig(config);
}
function createProxy(mapping) {
return new Proxy(mapping, {
set(target, key, value, _receiver) {
return target.setItem(key, value);
},
get(target, key, _receiver) {
return target.getItem(key);
},
deleteProperty(target, key) {
return target.deleteItem(key);
},
has(target, key) {
return target.containsItem(key);
}
});
}
function isZarrError(err2) {
return typeof err2 === "object" && err2 !== null && "__zarr__" in err2;
}
function isKeyError(o) {
return isZarrError(o) && o.__zarr__ === "KeyError";
}
var ContainsArrayError = class extends Error {
constructor(path) {
super(`path ${path} contains an array`);
this.__zarr__ = "ContainsArrayError";
Object.setPrototypeOf(this, ContainsArrayError.prototype);
}
};
var ContainsGroupError = class extends Error {
constructor(path) {
super(`path ${path} contains a group`);
this.__zarr__ = "ContainsGroupError";
Object.setPrototypeOf(this, ContainsGroupError.prototype);
}
};
var GroupNotFoundError = class extends Error {
constructor(path) {
super(`ground not found at path ${path}`);
this.__zarr__ = "GroupNotFoundError";
Object.setPrototypeOf(this, GroupNotFoundError.prototype);
}
};
var PermissionError = class extends Error {
constructor(message) {
super(message);
this.__zarr__ = "PermissionError";
Object.setPrototypeOf(this, PermissionError.prototype);
}
};
var KeyError = class extends Error {
constructor(key) {
super(`key ${key} not present`);
this.__zarr__ = "KeyError";
Object.setPrototypeOf(this, KeyError.prototype);
}
};
var TooManyIndicesError = class extends RangeError {
constructor(selection, shape) {
super(`too many indices for array; expected ${shape.length}, got ${selection.length}`);
this.__zarr__ = "TooManyIndicesError";
Object.setPrototypeOf(this, TooManyIndicesError.prototype);
}
};
var BoundsCheckError = class extends RangeError {
constructor(message) {
super(message);
this.__zarr__ = "BoundsCheckError";
Object.setPrototypeOf(this, BoundsCheckError.prototype);
}
};
var InvalidSliceError = class extends RangeError {
constructor(from, to, stepSize, reason) {
super(`slice arguments slice(${from}, ${to}, ${stepSize}) invalid: ${reason}`);
this.__zarr__ = "InvalidSliceError";
Object.setPrototypeOf(this, InvalidSliceError.prototype);
}
};
var NegativeStepError = class extends Error {
constructor() {
super(`Negative step size is not supported when indexing.`);
this.__zarr__ = "NegativeStepError";
Object.setPrototypeOf(this, NegativeStepError.prototype);
}
};
var ValueError = class extends Error {
constructor(message) {
super(message);
this.__zarr__ = "ValueError";
Object.setPrototypeOf(this, ValueError.prototype);
}
};
var HTTPError = class extends Error {
constructor(code) {
super(code);
this.__zarr__ = "HTTPError";
Object.setPrototypeOf(this, HTTPError.prototype);
}
};
function slice(start, stop = void 0, step = null) {
if (start === void 0) {
throw new InvalidSliceError(start, stop, step, "The first argument must not be undefined");
}
if (typeof start === "string" && start !== ":" || typeof stop === "string" && stop !== ":") {
throw new InvalidSliceError(start, stop, step, 'Arguments can only be integers, ":" or null');
}
if (stop === void 0) {
stop = start;
start = null;
}
return {
start: start === ":" ? null : start,
stop: stop === ":" ? null : stop,
step,
_slice: true
};
}
function adjustIndices(start, stop, step, length) {
if (start < 0) {
start += length;
if (start < 0) {
start = step < 0 ? -1 : 0;
}
} else if (start >= length) {
start = step < 0 ? length - 1 : length;
}
if (stop < 0) {
stop += length;
if (stop < 0) {
stop = step < 0 ? -1 : 0;
}
} else if (stop >= length) {
stop = step < 0 ? length - 1 : length;
}
if (step < 0) {
if (stop < start) {
const length2 = Math.floor((start - stop - 1) / -step + 1);
return [start, stop, step, length2];
}
} else {
if (start < stop) {
const length2 = Math.floor((stop - start - 1) / step + 1);
return [start, stop, step, length2];
}
}
return [start, stop, step, 0];
}
function sliceIndices(slice2, length) {
let start;
let stop;
let step;
if (slice2.step === null) {
step = 1;
} else {
step = slice2.step;
}
if (slice2.start === null) {
start = step < 0 ? Number.MAX_SAFE_INTEGER : 0;
} else {
start = slice2.start;
if (start < 0) {
start += length;
}
}
if (slice2.stop === null) {
stop = step < 0 ? -Number.MAX_SAFE_INTEGER : Number.MAX_SAFE_INTEGER;
} else {
stop = slice2.stop;
if (stop < 0) {
stop += length;
}
}
const s = adjustIndices(start, stop, step, length);
start = s[0];
stop = s[1];
step = s[2];
length = s[3];
if (step === 0)
throw new Error("Step size 0 is invalid");
return [start, stop, step, length];
}
function ensureArray(selection) {
if (!Array.isArray(selection)) {
return [selection];
}
return selection;
}
function checkSelectionLength(selection, shape) {
if (selection.length > shape.length) {
throw new TooManyIndicesError(selection, shape);
}
}
function selectionToSliceIndices(selection, shape) {
const sliceIndicesResult = [];
const outShape = [];
for (let i = 0; i < selection.length; i++) {
const s = selection[i];
if (typeof s === "number") {
sliceIndicesResult.push(s);
} else {
const x = sliceIndices(s, shape[i]);
const dimLength = x[3];
outShape.push(dimLength);
sliceIndicesResult.push(x);
}
}
return [sliceIndicesResult, outShape];
}
function normalizeArraySelection(selection, shape, convertIntegerSelectionToSlices = false) {
selection = replaceEllipsis(selection, shape);
for (let i = 0; i < selection.length; i++) {
const dimSelection = selection[i];
if (typeof dimSelection === "number") {
if (convertIntegerSelectionToSlices) {
selection[i] = slice(dimSelection, dimSelection + 1, 1);
} else {
selection[i] = normalizeIntegerSelection(dimSelection, shape[i]);
}
} else if (isIntegerArray(dimSelection)) {
throw new TypeError("Integer array selections are not supported (yet)");
} else if (dimSelection === ":" || dimSelection === null) {
selection[i] = slice(null, null, 1);
}
}
return selection;
}
function replaceEllipsis(selection, shape) {
selection = ensureArray(selection);
let ellipsisIndex = -1;
let numEllipsis = 0;
for (let i = 0; i < selection.length; i++) {
if (selection[i] === "...") {
ellipsisIndex = i;
numEllipsis += 1;
}
}
if (numEllipsis > 1) {
throw new RangeError("an index can only have a single ellipsis ('...')");
}
if (numEllipsis === 1) {
const numItemsLeft = ellipsisIndex;
const numItemsRight = selection.length - (numItemsLeft + 1);
const numItems = selection.length - 1;
if (numItems >= shape.length) {
selection = selection.filter((x) => x !== "...");
} else {
const numNewItems = shape.length - numItems;
let newItem = selection.slice(0, numItemsLeft).concat(new Array(numNewItems).fill(null));
if (numItemsRight > 0) {
newItem = newItem.concat(selection.slice(selection.length - numItemsRight));
}
selection = newItem;
}
}
if (selection.length < shape.length) {
const numMissing = shape.length - selection.length;
selection = selection.concat(new Array(numMissing).fill(null));
}
checkSelectionLength(selection, shape);
return selection;
}
function normalizeIntegerSelection(dimSelection, dimLength) {
if (dimSelection < 0) {
dimSelection = dimLength + dimSelection;
}
if (dimSelection >= dimLength || dimSelection < 0) {
throw new BoundsCheckError(`index out of bounds for dimension with length ${dimLength}`);
}
return dimSelection;
}
function isInteger(s) {
return typeof s === "number";
}
function isIntegerArray(s) {
if (!Array.isArray(s)) {
return false;
}
for (const e of s) {
if (typeof e !== "number") {
return false;
}
}
return true;
}
function isSlice(s) {
if (s !== null && s["_slice"] === true) {
return true;
}
return false;
}
function isContiguousSlice(s) {
return isSlice(s) && (s.step === null || s.step === 1);
}
function isContiguousSelection(selection) {
selection = ensureArray(selection);
for (let i = 0; i < selection.length; i++) {
const s = selection[i];
if (!(isIntegerArray(s) || isContiguousSlice(s) || s === "...")) {
return false;
}
}
return true;
}
function* product(...iterables) {
if (iterables.length === 0) {
return;
}
const iterators = iterables.map((it) => it());
const results = iterators.map((it) => it.next());
for (let i = 0; ; ) {
if (results[i].done) {
iterators[i] = iterables[i]();
results[i] = iterators[i].next();
if (++i >= iterators.length) {
return;
}
} else {
yield results.map(({ value }) => value);
i = 0;
}
results[i] = iterators[i].next();
}
}
var BasicIndexer = class {
constructor(selection, array2) {
selection = normalizeArraySelection(selection, array2.shape);
this.dimIndexers = [];
const arrayShape = array2.shape;
for (let i = 0; i < arrayShape.length; i++) {
let dimSelection = selection[i];
const dimLength = arrayShape[i];
const dimChunkLength = array2.chunks[i];
if (dimSelection === null) {
dimSelection = slice(null);
}
if (isInteger(dimSelection)) {
this.dimIndexers.push(new IntDimIndexer(dimSelection, dimLength, dimChunkLength));
} else if (isSlice(dimSelection)) {
this.dimIndexers.push(new SliceDimIndexer(dimSelection, dimLength, dimChunkLength));
} else {
throw new RangeError(`Unspported selection item for basic indexing; expected integer or slice, got ${dimSelection}`);
}
}
this.shape = [];
for (const d of this.dimIndexers) {
if (d instanceof SliceDimIndexer) {
this.shape.push(d.numItems);
}
}
this.dropAxes = null;
}
*iter() {
const dimIndexerIterables = this.dimIndexers.map((x) => () => x.iter());
const dimIndexerProduct = product(...dimIndexerIterables);
for (const dimProjections of dimIndexerProduct) {
const chunkCoords = [];
const chunkSelection = [];
const outSelection = [];
for (const p of dimProjections) {
chunkCoords.push(p.dimChunkIndex);
chunkSelection.push(p.dimChunkSelection);
if (p.dimOutSelection !== null) {
outSelection.push(p.dimOutSelection);
}
}
yield {
chunkCoords,
chunkSelection,
outSelection
};
}
}
};
var IntDimIndexer = class {
constructor(dimSelection, dimLength, dimChunkLength) {
dimSelection = normalizeIntegerSelection(dimSelection, dimLength);
this.dimSelection = dimSelection;
this.dimLength = dimLength;
this.dimChunkLength = dimChunkLength;
this.numItems = 1;
}
*iter() {
const dimChunkIndex = Math.floor(this.dimSelection / this.dimChunkLength);
const dimOffset = dimChunkIndex * this.dimChunkLength;
const dimChunkSelection = this.dimSelection - dimOffset;
const dimOutSelection = null;
yield {
dimChunkIndex,
dimChunkSelection,
dimOutSelection
};
}
};
var SliceDimIndexer = class {
constructor(dimSelection, dimLength, dimChunkLength) {
const [start, stop, step] = sliceIndices(dimSelection, dimLength);
this.start = start;
this.stop = stop;
this.step = step;
if (this.step < 1) {
throw new NegativeStepError();
}
this.dimLength = dimLength;
this.dimChunkLength = dimChunkLength;
this.numItems = Math.max(0, Math.ceil((this.stop - this.start) / this.step));
this.numChunks = Math.ceil(this.dimLength / this.dimChunkLength);
}
*iter() {
const dimChunkIndexFrom = Math.floor(this.start / this.dimChunkLength);
const dimChunkIndexTo = Math.ceil(this.stop / this.dimChunkLength);
for (let dimChunkIndex = dimChunkIndexFrom; dimChunkIndex < dimChunkIndexTo; dimChunkIndex++) {
const dimOffset = dimChunkIndex * this.dimChunkLength;
const dimLimit = Math.min(this.dimLength, (dimChunkIndex + 1) * this.dimChunkLength);
const dimChunkLength = dimLimit - dimOffset;
let dimChunkSelStart;
let dimChunkSelStop;
let dimOutOffset;
if (this.start < dimOffset) {
dimChunkSelStart = 0;
const remainder = (dimOffset - this.start) % this.step;
if (remainder > 0) {
dimChunkSelStart += this.step - remainder;
}
dimOutOffset = Math.ceil((dimOffset - this.start) / this.step);
} else {
dimChunkSelStart = this.start - dimOffset;
dimOutOffset = 0;
}
if (this.stop > dimLimit) {
dimChunkSelStop = dimChunkLength;
} else {
dimChunkSelStop = this.stop - dimOffset;
}
const dimChunkSelection = slice(dimChunkSelStart, dimChunkSelStop, this.step);
const dimChunkNumItems = Math.ceil((dimChunkSelStop - dimChunkSelStart) / this.step);
const dimOutSelection = slice(dimOutOffset, dimOutOffset + dimChunkNumItems);
yield {
dimChunkIndex,
dimChunkSelection,
dimOutSelection
};
}
}
};
var IS_NODE = typeof process !== "undefined" && process.versions && process.versions.node;
function noop() {
}
function normalizeStoragePath(path) {
if (path === null) {
return "";
}
if (path instanceof String) {
path = path.valueOf();
}
path = path.replace(/\\/g, "/");
while (path.length > 0 && path[0] === "/") {
path = path.slice(1);
}
while (path.length > 0 && path[path.length - 1] === "/") {
path = path.slice(0, path.length - 1);
}
path = path.replace(/\/\/+/g, "/");
const segments = path.split("/");
for (const s of segments) {
if (s === "." || s === "..") {
throw Error("path containing '.' or '..' segment not allowed");
}
}
return path;
}
function normalizeShape(shape) {
if (typeof shape === "number") {
shape = [shape];
}
return shape.map((x) => Math.floor(x));
}
function normalizeChunks(chunks, shape) {
if (chunks === null || chunks === true) {
throw new Error("Chunk guessing is not supported yet");
}
if (chunks === false) {
return shape;
}
if (typeof chunks === "number") {
chunks = [chunks];
}
if (chunks.length < shape.length) {
chunks = chunks.concat(shape.slice(chunks.length));
}
return chunks.map((x, idx) => {
if (x === -1 || x === null) {
return shape[idx];
} else {
return Math.floor(x);
}
});
}
function normalizeOrder(order) {
order = order.toUpperCase();
return order;
}
function normalizeDtype(dtype) {
return dtype;
}
function normalizeFillValue(fillValue) {
return fillValue;
}
function isTotalSlice(item, shape) {
if (item === null) {
return true;
}
if (!Array.isArray(item)) {
item = [item];
}
for (let i = 0; i < Math.min(item.length, shape.length); i++) {
const it = item[i];
if (it === null)
continue;
if (isSlice(it)) {
const s = it;
const isStepOne = s.step === 1 || s.step === null;
if (s.start === null && s.stop === null && isStepOne) {
continue;
}
if (s.stop - s.start === shape[i] && isStepOne) {
continue;
}
return false;
}
return false;
}
return true;
}
function arrayEquals1D(a, b) {
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function getStrides(shape) {
const ndim = shape.length;
const strides = Array(ndim);
let step = 1;
for (let i = ndim - 1; i >= 0; i--) {
strides[i] = step;
step *= shape[i];
}
return strides;
}
function resolveUrl(root, path) {
const base = typeof root === "string" ? new URL(root) : root;
if (!base.pathname.endsWith("/")) {
base.pathname += "/";
}
const resolved = new URL(path, base);
resolved.search = base.search;
return resolved.href;
}
function byteSwapInplace(src) {
const b = src.BYTES_PER_ELEMENT;
if (b === 1)
return;
if (IS_NODE) {
const bytes = Buffer.from(src.buffer, src.byteOffset, src.length * b);
if (b === 2)
bytes.swap16();
if (b === 4)
bytes.swap32();
if (b === 8)
bytes.swap64();
return;
}
const flipper = new Uint8Array(src.buffer, src.byteOffset, src.length * b);
const numFlips = b / 2;
const endByteIndex = b - 1;
let t;
for (let i = 0; i < flipper.length; i += b) {
for (let j = 0; j < numFlips; j++) {
t = flipper[i + j];
flipper[i + j] = flipper[i + endByteIndex - j];
flipper[i + endByteIndex - j] = t;
}
}
}
function byteSwap(src) {
const copy = src.slice();
byteSwapInplace(copy);
return copy;
}
function convertColMajorToRowMajor2D(src, out, shape) {
let idx = 0;
const shape0 = shape[0];
const shape1 = shape[1];
const stride0 = shape1;
for (let i1 = 0; i1 < shape1; i1++) {
for (let i0 = 0; i0 < shape0; i0++) {
out[i0 * stride0 + i1] = src[idx++];
}
}
}
function convertColMajorToRowMajor3D(src, out, shape) {
let idx = 0;
const shape0 = shape[0];
const shape1 = shape[1];
const shape2 = shape[2];
const stride0 = shape2 * shape1;
const stride1 = shape2;
for (let i2 = 0; i2 < shape2; i2++) {
for (let i1 = 0; i1 < shape1; i1++) {
for (let i0 = 0; i0 < shape0; i0++) {
out[i0 * stride0 + i1 * stride1 + i2] = src[idx++];
}
}
}
}
function convertColMajorToRowMajor4D(src, out, shape) {
let idx = 0;
const shape0 = shape[0];
const shape1 = shape[1];
const shape2 = shape[2];
const shape3 = shape[3];
const stride0 = shape3 * shape2 * shape1;
const stride1 = shape3 * shape2;
const stride2 = shape3;
for (let i3 = 0; i3 < shape3; i3++) {
for (let i2 = 0; i2 < shape2; i2++) {
for (let i1 = 0; i1 < shape1; i1++) {
for (let i0 = 0; i0 < shape0; i0++) {
out[i0 * stride0 + i1 * stride1 + i2 * stride2 + i3] = src[idx++];
}
}
}
}
}
function convertColMajorToRowMajorGeneric(src, out, shape) {
const nDims = shape.length;
const size = shape.reduce((r, a) => r * a);
const rowMajorStrides = shape.map((_, i) => i + 1 === nDims ? 1 : shape.slice(i + 1).reduce((r, a) => r * a, 1));
const index = Array(nDims).fill(0);
for (let colMajorIdx = 0; colMajorIdx < size; colMajorIdx++) {
let rowMajorIdx = 0;
for (let dim = 0; dim < nDims; dim++) {
rowMajorIdx += index[dim] * rowMajorStrides[dim];
}
out[rowMajorIdx] = src[colMajorIdx];
index[0] += 1;
for (let dim = 0; dim < nDims; dim++) {
if (index[dim] === shape[dim]) {
if (dim + 1 === nDims) {
return;
}
index[dim] = 0;
index[dim + 1] += 1;
}
}
}
}
var colMajorToRowMajorConverters = {
[0]: noop,
[1]: noop,
[2]: convertColMajorToRowMajor2D,
[3]: convertColMajorToRowMajor3D,
[4]: convertColMajorToRowMajor4D
};
function convertColMajorToRowMajor(src, out, shape) {
return (colMajorToRowMajorConverters[shape.length] || convertColMajorToRowMajorGeneric)(src, out, shape);
}
function isArrayBufferLike(obj) {
if (obj === null) {
return false;
}
if (obj instanceof ArrayBuffer) {
return true;
}
if (typeof SharedArrayBuffer === "function" && obj instanceof SharedArrayBuffer) {
return true;
}
if (IS_NODE) {
return obj.toString().startsWith("[object ArrayBuffer]") || obj.toString().startsWith("[object SharedArrayBuffer]");
}
return false;
}
var ARRAY_META_KEY = ".zarray";
var GROUP_META_KEY = ".zgroup";
var ATTRS_META_KEY = ".zattrs";
async function containsArray(store, path = null) {
path = normalizeStoragePath(path);
const prefix = pathToPrefix(path);
const key = prefix + ARRAY_META_KEY;
return store.containsItem(key);
}
async function containsGroup(store, path = null) {
path = normalizeStoragePath(path);
const prefix = pathToPrefix(path);
const key = prefix + GROUP_META_KEY;
return store.containsItem(key);
}
function pathToPrefix(path) {
if (path.length > 0) {
return path + "/";
}
return "";
}
async function requireParentGroup(store, path, chunkStore, overwrite) {
if (path.length === 0) {
return;
}
const segments = path.split("/");
let p = "";
for (const s of segments.slice(0, segments.length - 1)) {
p += s;
if (await containsArray(store, p)) {
await initGroupMetadata(store, p, overwrite);
} else if (!await containsGroup(store, p)) {
await initGroupMetadata(store, p);
}
p += "/";
}
}
async function initGroupMetadata(store, path = null, overwrite = false) {
path = normalizeStoragePath(path);
if (overwrite) {
throw Error("Group overwriting not implemented yet :(");
} else if (await containsArray(store, path)) {
throw new ContainsArrayError(path);
} else if (await containsGroup(store, path)) {
throw new ContainsGroupError(path);
}
const metadata = { zarr_format: 2 };
const key = pathToPrefix(path) + GROUP_META_KEY;
await store.setItem(key, JSON.stringify(metadata));
}
async function initGroup(store, path = null, chunkStore = null, overwrite = false) {
path = normalizeStoragePath(path);
await requireParentGroup(store, path, chunkStore, overwrite);
await initGroupMetadata(store, path, overwrite);
}
async function initArrayMetadata(store, shape, chunks, dtype, path, compressor, fillValue, order, overwrite, chunkStore, filters, dimensionSeparator) {
if (overwrite) {
throw Error("Array overwriting not implemented yet :(");
} else if (await containsArray(store, path)) {
throw new ContainsArrayError(path);
} else if (await containsGroup(store, path)) {
throw new ContainsGroupError(path);
}
dtype = normalizeDtype(dtype);
shape = normalizeShape(shape);
chunks = normalizeChunks(chunks, shape);
order = normalizeOrder(order);
fillValue = normalizeFillValue(fillValue);
if (filters !== null && filters.length > 0) {
throw Error("Filters are not supported yet");
}
let serializedFillValue = fillValue;
if (typeof fillValue === "number") {
if (Number.isNaN(fillValue))
serializedFillValue = "NaN";
if (Number.POSITIVE_INFINITY === fillValue)
serializedFillValue = "Infinity";
if (Number.NEGATIVE_INFINITY === fillValue)
serializedFillValue = "-Infinity";
}
filters = null;
const metadata = {
zarr_format: 2,
shape,
chunks,
dtype,
fill_value: serializedFillValue,
order,
compressor,
filters
};
if (dimensionSeparator) {
metadata.dimension_separator = dimensionSeparator;
}
const metaKey = pathToPrefix(path) + ARRAY_META_KEY;
await store.setItem(metaKey, JSON.stringify(metadata));
}
async function initArray(store, shape, chunks, dtype, path = null, compressor = null, fillValue = null, order = "C", overwrite = false, chunkStore = null, filters = null, dimensionSeparator) {
path = normalizeStoragePath(path);
await requireParentGroup(store, path, chunkStore, overwrite);
await initArrayMetadata(store, shape, chunks, dtype, path, compressor, fillValue, order, overwrite, chunkStore, filters, dimensionSeparator);
}
function parseMetadata(s) {
if (typeof s !== "string") {
if (IS_NODE && Buffer.isBuffer(s)) {
return JSON.parse(s.toString());
} else if (isArrayBufferLike(s)) {
const utf8Decoder = new TextDecoder();
const bytes = new Uint8Array(s);
return JSON.parse(utf8Decoder.decode(bytes));
} else {
return s;
}
}
return JSON.parse(s);
}
var Attributes = class {
constructor(store, key, readOnly, cache = true) {
this.store = store;
this.key = key;
this.readOnly = readOnly;
this.cache = cache;
this.cachedValue = null;
}
/**
* Retrieve all attributes as a JSON object.
*/
async asObject() {
if (this.cache && this.cachedValue !== null) {
return this.cachedValue;
}
const o = await this.getNoSync();
if (this.cache) {
this.cachedValue = o;
}
return o;
}
async getNoSync() {
try {
const data = await this.store.getItem(this.key);
return parseMetadata(data);
} catch (error) {
return {};
}
}
async setNoSync(key, value) {
const d = await this.getNoSync();
d[key] = value;
await this.putNoSync(d);
return true;
}
async putNoSync(m) {
await this.store.setItem(this.key, JSON.stringify(m));
if (this.cache) {
this.cachedValue = m;
}
}
async delNoSync(key) {
const d = await this.getNoSync();
delete d[key];
await this.putNoSync(d);
return true;
}
/**
* Overwrite all attributes with the provided object in a single operation
*/
async put(d) {
if (this.readOnly) {
throw new PermissionError("attributes are read-only");
}
return this.putNoSync(d);
}
async setItem(key, value) {
if (this.readOnly) {
throw new PermissionError("attributes are read-only");
}
return this.setNoSync(key, value);
}
async getItem(key) {
return (await this.asObject())[key];
}
async deleteItem(key) {
if (this.readOnly) {
throw new PermissionError("attributes are read-only");
}
return this.delNoSync(key);
}
async containsItem(key) {
return (await this.asObject())[key] !== void 0;
}
proxy() {
return createProxy(this);
}
};
var DTYPE_TYPEDARRAY_MAPPING = {
"|b": Int8Array,
"|B": Uint8Array,
"|u1": Uint8Array,
"|i1": Int8Array,
"<b": Int8Array,
"<B": Uint8Array,
"<u1": Uint8Array,
"<i1": Int8Array,
"<u2": Uint16Array,
"<i2": Int16Array,
"<u4": Uint32Array,
"<i4": Int32Array,
"<f4": Float32Array,
"<f8": Float64Array,
">b": Int8Array,
">B": Uint8Array,
">u1": Uint8Array,
">i1": Int8Array,
">u2": Uint16Array,
">i2": Int16Array,
">u4": Uint32Array,
">i4": Int32Array,
">f4": Float32Array,
">f8": Float64Array
};
function getTypedArrayCtr(dtype) {
const ctr = DTYPE_TYPEDARRAY_MAPPING[dtype];
if (!ctr) {
throw Error(`Dtype not recognized or not supported in zarr.js, got ${dtype}.`);
}
return ctr;
}
function getTypedArrayDtypeString(t) {
if (t instanceof Uint8Array)
return "|u1";
if (t instanceof Int8Array)
return "|i1";
if (t instanceof Uint16Array)
return "<u2";
if (t instanceof Int16Array)
return "<i2";
if (t instanceof Uint32Array)
return "<u4";
if (t instanceof Int32Array)
return "<i4";
if (t instanceof Float32Array)
return "<f4";
if (t instanceof Float64Array)
return "<f8";
throw new ValueError("Mapping for TypedArray to Dtypestring not known");
}
function getNestedArrayConstructor(arr) {
if (arr.byteLength !== void 0) {
return arr.constructor;
}
return getNestedArrayConstructor(arr[0]);
}
function sliceNestedArray(arr, shape, selection) {
const normalizedSelection = normalizeArraySelection(selection, shape);
const [sliceIndices2, outShape] = selectionToSliceIndices(normalizedSelection, shape);
const outArray = _sliceNestedArray(arr, shape, sliceIndices2);
return [outArray, outShape];
}
function _sliceNestedArray(arr, shape, selection) {
const currentSlice = selection[0];
if (typeof currentSlice === "number") {
if (shape.length === 1) {
return arr[currentSlice];
} else {
return _sliceNestedArray(arr[currentSlice], shape.slice(1), selection.slice(1));
}
}
const [from, to, step, outputSize] = currentSlice;
if (outputSize === 0) {
return new (getNestedArrayConstructor(arr))(0);
}
if (shape.length === 1) {
if (step === 1) {
return arr.slice(from, to);
}
const newArrData = new arr.constructor(outputSize);
for (let i = 0; i < outputSize; i++) {
newArrData[i] = arr[from + i * step];
}
return newArrData;
}
let newArr = new Array(outputSize);
for (let i = 0; i < outputSize; i++) {
newArr[i] = _sliceNestedArray(arr[from + i * step], shape.slice(1), selection.slice(1));
}
if (outputSize > 0 && typeof newArr[0] === "number") {
const typedArrayConstructor = arr[0].constructor;
newArr = typedArrayConstructor.from(newArr);
}
return newArr;
}
function setNestedArrayToScalar(dstArr, value, destShape, selection) {
const normalizedSelection = normalizeArraySelection(selection, destShape, true);
const [sliceIndices2, _outShape] = selectionToSliceIndices(normalizedSelection, destShape);
_setNestedArrayToScalar(dstArr, value, destShape, sliceIndices2);
}
function setNestedArray(dstArr, sourceArr, destShape, sourceShape, selection) {
const normalizedSelection = normalizeArraySelection(selection, destShape, false);
const [sliceIndices2, outShape] = selectionToSliceIndices(normalizedSelection, destShape);
if (JSON.stringify(outShape) !== JSON.stringify(sourceShape)) {
throw new ValueError(`Shape mismatch in target and source NestedArray: ${outShape} and ${sourceShape}`);
}
_setNestedArray(dstArr, sourceArr, destShape, sliceIndices2);
}
function _setNestedArray(dstArr, sourceArr, shape, selection) {
const currentSlice = selection[0];
if (typeof sourceArr === "number") {
_setNestedArrayToScalar(dstArr, sourceArr, shape, selection.map((x) => typeof x === "number" ? [x, x + 1, 1, 1] : x));
return;
}
if (typeof currentSlice === "number") {
_setNestedArray(dstArr[currentSlice], sourceArr, shape.slice(1), selection.slice(1));
return;
}
const [from, _to, step, outputSize] = currentSlice;
if (shape.length === 1) {
if (step === 1) {
dstArr.set(sourceArr, from);
} else {
for (let i = 0; i < outputSize; i++) {
dstArr[from + i * step] = sourceArr[i];
}
}
return;
}
for (let i = 0; i < outputSize; i++) {
_setNestedArray(dstArr[from + i * step], sourceArr[i], shape.slice(1), selection.slice(1));
}
}
function _setNestedArrayToScalar(dstArr, value, shape, selection) {
const currentSlice = selection[0];
const [from, to, step, outputSize] = currentSlice;
if (shape.length === 1) {
if (step === 1) {
dstArr.fill(value, from, to);
} else {
for (let i = 0; i < outputSize; i++) {
dstArr[from + i * step] = value;
}
}
return;
}
for (let i = 0; i < outputSize; i++) {
_setNestedArrayToScalar(dstArr[from + i * step], value, shape.slice(1), selection.slice(1));
}
}
function flattenNestedArray(arr, shape, constr) {
if (constr === void 0) {
constr = getNestedArrayConstructor(arr);
}
const size = shape.reduce((x, y) => x * y, 1);
const outArr = new constr(size);
_flattenNestedArray(arr, shape, outArr, 0);
return outArr;
}
function _flattenNestedArray(arr, shape, outArr, offset) {
if (shape.length === 1) {
outArr.set(arr, offset);
return;
}
if (shape.length === 2) {
for (let i = 0; i < shape[0]; i++) {
outArr.set(arr[i], offset + shape[1] * i);
}
return arr;
}
const nextShape = shape.slice(1);
const mult = nextShape.reduce((x, y) => x * y, 1);
for (let i = 0; i < shape[0]; i++) {
_flattenNestedArray(arr[i], nextShape, outArr, offset + mult * i);
}
return arr;
}
var NestedArray = class {
constructor(data, shape, dtype) {
const dataIsTypedArray = data !== null && !!data.BYTES_PER_ELEMENT;
if (shape === void 0) {
if (!dataIsTypedArray) {
throw new ValueError("Shape argument is required unless you pass in a TypedArray");
}
shape = [data.length];
}
if (dtype === void 0) {
if (!dataIsTypedArray) {
throw new ValueError("Dtype argument is required unless you pass in a TypedArray");
}
dtype = getTypedArrayDtypeString(data);
}
shape = normalizeShape(shape);
this.shape = shape;
this.dtype = dtype;
if (dataIsTypedArray && shape.length !== 1) {
data = data.buffer;
}
if (this.shape.length === 0) {
this.data = new (getTypedArrayCtr(dtype))(1);
} else if (
// tslint:disable-next-line: strict-type-predicates
IS_NODE && Buffer.isBuffer(data) || isArrayBufferLike(data) || data === null
) {
const numShapeElements = shape.reduce((x, y) => x * y, 1);
if (data === null) {
data = new ArrayBuffer(numShapeElements * parseInt(dtype[dtype.length - 1], 10));
}
const numDataElements = data.byteLength / parseInt(dtype[dtype.length - 1], 10);
if (numShapeElements !== numDataElements) {
throw new Error(`Buffer has ${numDataElements} of dtype ${dtype}, shape is too large or small ${shape} (flat=${numShapeElements})`);
}
const typeConstructor = getTypedArrayCtr(dtype);
this.data = createNestedArray(data, typeConstructor, shape);
} else {
this.data = data;
}
}
get(selection) {
const [sliceResult, outShape] = sliceNestedArray(this.data, this.shape, selection);
if (outShape.length === 0) {
return sliceResult;
} else {
return new NestedArray(sliceResult, outShape, this.dtype);
}
}
set(selection = null, value) {
if (selection === null) {
selection = [slice(null)];
}
if (typeof value === "number") {
if (this.shape.length === 0) {
this.data[0] = value;
} else {
setNestedArrayToScalar(this.data, value, this.shape, selection);
}
} else {
setNestedArray(this.data, value.data, this.shape, value.shape, selection);
}
}
flatten() {
if (this.shape.length === 1) {
return this.data;
}
return flattenNestedArray(this.data, this.shape, getTypedArrayCtr(this.dtype));
}
/**
* Currently only supports a single integer as the size, TODO: support start, stop, step.
*/
static arange(size, dtype = "<i4") {
const constr = getTypedArrayCtr(dtype);
const data = rangeTypedArray([size], constr);
return new NestedArray(data, [size], dtype);
}
};
function rangeTypedArray(shape, tContructor) {
const size = shape.reduce((x, y) => x * y, 1);
const data = new tContructor(size);
data.set([...Array(size).keys()]);
return data;
}
function createNestedArray(data, t, shape, offset = 0) {
if (shape.length === 1) {
return new t(data.slice(offset, offset + shape[0] * t.BYTES_PER_ELEMENT));
}
const arr = new Array(shape[0]);
if (shape.length === 2) {
for (let i = 0; i < shape[0]; i++) {
arr[i] = new t(data.slice(offset + shape[1] * i * t.BYTES_PER_ELEMENT, offset + shape[1] * (i + 1) * t.BYTES_PER_ELEMENT));
}
return arr;
}
const nextShape = shape.slice(1);
const mult = nextShape.reduce((x, y) => x * y, 1);
for (let i = 0; i < shape[0]; i++) {
arr[i] = createNestedArray(data, t, nextShape, offset + mult * i * t.BYTES_PER_ELEMENT);
}
return arr;
}
function setRawArrayToScalar(dstArr, dstStrides, dstShape, dstSelection, value) {
const normalizedSelection = normalizeArraySelection(dstSelection, dstShape, true);
const [sliceIndices2] = selectionToSliceIndices(normalizedSelection, dstShape);
_setRawArrayToScalar(value, dstArr, dstStrides, sliceIndices2);
}
function setRawArray(dstArr, dstStrides, dstShape, dstSelection, sourceArr, sourceStrides, sourceShape) {
const normalizedDstSelection = normalizeArraySelection(dstSelection, dstShape, false);
const [dstSliceIndices, outShape] = selectionToSliceIndices(normalizedDstSelection, dstShape);
if (JSON.stringify(outShape) !== JSON.stringify(sourceShape)) {
throw new ValueError(`Shape mismatch in target and source RawArray: ${outShape} and ${sourceShape}`);
}
_setRawArray(dstArr, dstStrides, dstSliceIndices, sourceArr, sourceStrides);
}
function setRawArrayFromChunkItem(dstArr, dstStrides, dstShape, dstSelection, sourceArr, sourceStrides, sourceShape, sourceSelection) {
const normalizedDstSelection = normalizeArraySelection(dstSelection, dstShape, true);
const [dstSliceIndices] = selectionToSliceIndices(normalizedDstSelection, dstShape);
const normalizedSourceSelection = normalizeArraySelection(sourceSelection, sourceShape, false);
const [sourceSliceIndicies] = selectionToSliceIndices(normalizedSourceSelection, sourceShape);
_setRawArrayFromChunkItem(dstArr, dstStrides, dstSliceIndices, sourceArr, sourceStrides, sourceSliceIndicies);
}
function _setRawArrayToScalar(value, dstArr, dstStrides, dstSliceIndices) {
const [currentDstSlice, ...nextDstSliceIndices] = dstSliceIndices;
const [currentDstStride, ...nextDstStrides] = dstStrides;
const [from, _to, step, outputSize] = currentDstSlice;
if (dstStrides.length === 1) {
if (step === 1 && currentDstStride === 1) {
dstArr.fill(value, from, from + outputSize);
} else {
for (let i = 0; i < outputSize; i++) {
dstArr[currentDstStride * (from + step * i)] = value;
}
}
return;
}
for (let i = 0; i < outputSize; i++) {
_setRawArrayToScalar(value, dstArr.subarray(currentDstStride * (from + step * i)), nextDstStrides, nextDstSliceIndices);
}
}
function _setRawArray(dstArr, dstStrides, dstSliceIndices, sourceArr, sourceStrides) {
if (dstSliceIndices.length === 0) {
dstArr.set(sourceArr);
return;
}
const [currentDstSlice, ...nextDstSliceIndices] = dstSliceIndices;
const [currentDstStride, ...nextDstStrides] = dstStrides;
if (typeof currentDstSlice === "number") {
_setRawArray(dstArr.subarray(currentDstSlice * currentDstStride), nextDstStrides, nextDstSliceIndices, sourceArr, sourceStrides);
return;
}
const [currentSourceStride, ...nextSourceStrides] = sourceStrides;
const [from, _to, step, outputSize] = currentDstSlice;
if (dstStrides.length === 1) {
if (step === 1 && currentDstStride === 1 && currentSourceStride === 1) {
dstArr.set(sourceArr.subarray(0, outputSize), from);
} else {
for (let i = 0; i < outputSize; i++) {
dstArr[currentDstStride * (from + step * i)] = sourceArr[currentSourceStride * i];
}
}
return;
}
for (let i = 0; i < outputSize; i++) {
_setRawArray(dstArr.subarray(currentDstStride * (from + i * step)), nextDstStrides, nextDstSliceIndices, sourceArr.subarray(currentSourceStride * i), nextSourceStrides);
}
}
function _setRawArrayFromChunkItem(dstArr, dstStrides, dstSliceIndices, sourceArr, sourceStrides, sourceSliceIndices) {
if (sourceSliceIndices.length === 0) {
dstArr.set(sourceArr.subarray(0, dstArr.length));
return;
}
const [currentDstSlice, ...nextDstSliceIndices] = dstSliceIndices;
const [currentSourceSlice, ...nextSourceSliceIndices] = sourceSliceIndices;
const [currentDstStride, ...nextDstStrides] = dstStrides;
const [currentSourceStride, ...nextSourceStrides] = sourceStrides;
if (typeof currentSourceSlice === "number") {
_setRawArrayFromChunkItem(
// Don't update destination offset/slices, just source
dstArr,
dstStrides,
dstSliceIndices,
sourceArr.subarray(currentSourceStride * currentSourceSlice),
nextSourceStrides,
nextSourceSliceIndices
);
return;
}
const [from, _to, step, outputSize] = currentDstSlice;
const [sfrom, _sto, sstep, _soutputSize] = currentSourceSlice;
if (dstStrides.length === 1 && sourceStrides.length === 1) {
if (step === 1 && currentDstStride === 1 && sstep === 1 && currentSourceStride === 1) {
dstArr.set(sourceArr.subarray(sfrom, sfrom + outputSize), from);
} else {
for (let i = 0; i < outputSize; i++) {
dstArr[currentDstStride * (from + step * i)] = sourceArr[currentSourceStride * (sfrom + sstep * i)];
}
}
return;
}
for (let i = 0; i < outputSize; i++) {
_setRawArrayFromChunkItem(dstArr.subarray(currentDstStride * (from + i * step)), nextDstStrides, nextDstSliceIndices, sourceArr.subarray(currentSourceStride * (sfrom + i * sstep)), nextSourceStrides, nextSourceSliceIndices);
}
}
var RawArray = class {
constructor(data, shape, dtype, strides) {
const dataIsTypedArray = data !== null && !!data.BYTES_PER_ELEMENT;
if (shape === void 0) {
if (!dataIsTypedArray) {
throw new ValueError("Shape argument is required unless you pass in a TypedArray");
}
shape = [data.length];
}
shape = normalizeShape(shape);
if (dtype === void 0) {
if (!dataIsTypedArray) {
throw new ValueError("Dtype argument is required unless you pass in a TypedArray");
}
dtype = getTypedArrayDtypeString(data);
}
if (strides === void 0) {
strides = getStrides(shape);
}
this.shape = shape;
this.dtype = dtype;
this.strides = strides;
if (dataIsTypedArray && shape.length !== 1) {
data = data.buffer;
}
if (this.shape.length === 0) {
this.data = new (getTypedArrayCtr(dtype))(1);
} else if (
// tslint:disable-next-line: strict-type-predicates
IS_NODE && Buffer.isBuffer(data) || isArrayBufferLike(data) || data === null
) {
const numShapeElements = shape.reduce((x, y) => x * y, 1);
if (data === null) {
data = new ArrayBuffer(numShapeElements * parseInt(dtype[dtype.length - 1], 10));
}
const numDataElements = data.byteLength / parseInt(dtype[dtype.length - 1], 10);
if (numShapeElements !== numDataElements) {
throw new Error(`Buffer has ${numDataElements} of dtype ${dtype}, shape is too large or small ${shape} (flat=${numShapeElements})`);
}
const typeConstructor = getTypedArrayCtr(dtype);
this.data = new typeConstructor(data);
} else {
this.data = data;
}
}
set(selection = null, value, chunkSelection) {
if (selection === null) {
selection = [slice(null)];
}
if (typeof value === "number") {
if (this.shape.length === 0) {
this.data[0] = value;
} else {
setRawArrayToScalar(this.data, this.strides, this.shape, selection, value);
}
} else if (value instanceof RawArray && chunkSelection) {
setRawArrayFromChunkItem(this.data, this.strides, this.shape, selection, value.data, value.strides, value.shape, chunkSelection);
} else {
setRawArray(this.data, this.strides, this.shape, selection, value.data, value.strides, value.shape);
}
}
};
var eventemitter3 = { exports: {} };
(function(module) {
var has = Object.prototype.hasOwnProperty, prefix = "~";
function Events() {
}
if (Object.create) {
Events.prototype = /* @__PURE__ */ Object.create(null);
if (!new Events().__proto__)
prefix = false;
}
function EE(fn, context, once) {
this.fn = fn;
this.context = context;
this.once = once || false;
}
function addListener(emitter, event, fn, context, once) {
if (typeof fn !== "function") {
throw new TypeError("The listener must be a function");
}
var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
if (!emitter._events[evt])
emitter._events[evt] = listener, emitter._eventsCount++;
else if (!emitter._events[evt].fn)
emitter._events[evt].push(listener);
else
emitter._events[evt] = [emitter._events[evt], listener];
return emitter;
}
function clearEvent(emitter, evt) {
if (--emitter._eventsCount === 0)
emitter._events = new Events();
else
delete emitter._events[evt];
}
function EventEmitter2() {
this._events = new Events();
this._eventsCount = 0;
}
EventEmitter2.prototype.eventNames = function eventNames() {
var names = [], events, name;
if (this._eventsCount === 0)
return names;
for (name in events = this._events) {
if (has.call(events, name))
names.push(prefix ? name.slice(1) : name);
}
if (Object.getOwnPropertySymbols) {
return names.concat(Object.getOwnPropertySymbols(events));
}
return names;
};
EventEmitter2.prototype.listeners = function listeners(event) {
var evt = prefix ? prefix + event : event, handlers = this._events[evt];