zarr-metadata 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/dist/chunk-grids.d.ts +40 -0
- package/dist/chunk-grids.d.ts.map +1 -0
- package/dist/chunk-grids.js +133 -0
- package/dist/chunk-grids.js.map +1 -0
- package/dist/codecs.d.ts +37 -0
- package/dist/codecs.d.ts.map +1 -0
- package/dist/codecs.js +182 -0
- package/dist/codecs.js.map +1 -0
- package/dist/data-types.d.ts +12 -0
- package/dist/data-types.d.ts.map +1 -0
- package/dist/data-types.js +70 -0
- package/dist/data-types.js.map +1 -0
- package/dist/guards.d.ts +21 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +39 -0
- package/dist/guards.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/semantics.d.ts +12 -34
- package/dist/semantics.d.ts.map +1 -1
- package/dist/semantics.js +19 -353
- package/dist/semantics.js.map +1 -1
- package/package.json +1 -1
- package/src/chunk-grids.ts +158 -0
- package/src/codecs.ts +214 -0
- package/src/data-types.ts +81 -0
- package/src/guards.ts +48 -0
- package/src/index.ts +11 -0
- package/src/semantics.ts +21 -372
package/dist/semantics.d.ts
CHANGED
|
@@ -1,43 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Semantic (cross-field) validation for v3 array metadata
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - the `rectilinear` chunk grid requires a configuration with `kind` and
|
|
12
|
-
* `chunk_shapes`; `chunk_shapes` has one entry per dimension, and each
|
|
13
|
-
* explicit chunk list (integers and `[size, count]` run-length pairs)
|
|
14
|
-
* sums exactly to that dimension's length (the bare-integer uniform
|
|
15
|
-
* shorthand carries no sum constraint, like the regular grid);
|
|
16
|
-
* - a `transpose` codec's `order` is a permutation of `0..n-1`, with one
|
|
17
|
-
* entry per array dimension;
|
|
18
|
-
* - a `sharding_indexed` codec's inner `chunk_shape` matches the array's
|
|
19
|
-
* dimensionality and evenly divides every chunk it shards — the grid's
|
|
20
|
-
* chunk at the top level (each distinct per-dimension size, for
|
|
21
|
-
* rectilinear grids), the parent shard's inner chunk when sharding
|
|
22
|
-
* nests;
|
|
23
|
-
* - `fill_value` has a JSON shape permitted for the named core data type
|
|
24
|
-
* (booleans for `bool`, ranged integers for the int types, numbers /
|
|
25
|
-
* the "NaN"-family sentinels / width-checked "0x…" strings for the
|
|
26
|
-
* float types, two-element arrays for the complex types).
|
|
27
|
-
*
|
|
28
|
-
* Dimensional context is THREADED through codec pipelines rather than
|
|
29
|
-
* assumed constant (mirroring zarr-python's chunk-spec threading): a valid
|
|
30
|
-
* `transpose` permutes the per-dimension chunk sizes for the codecs after
|
|
31
|
-
* it, and any codec this layer cannot reason about — `reshape` may change
|
|
32
|
-
* a chunk's rank, and unknown codecs may do anything — invalidates the
|
|
33
|
-
* dimensional context for the rest of the pipeline instead of letting
|
|
34
|
-
* stale array-level facts produce false verdicts.
|
|
2
|
+
* Semantic (cross-field) validation for v3 array metadata: the
|
|
3
|
+
* orchestrator. The rules themselves live with their content —
|
|
4
|
+
* `chunk-grids.ts`, `codecs.ts`, and `data-types.ts` each hold the syntax
|
|
5
|
+
* (types) and semantics (procedures) for the names this package
|
|
6
|
+
* interprets, mirroring how the spec, the Python reference's type layout,
|
|
7
|
+
* and the zarr-extensions registry are organized. This module only walks
|
|
8
|
+
* documents: extract shape, ask each content module for its verdicts,
|
|
9
|
+
* thread the chunk-size context into codec pipelines, and descend into a
|
|
10
|
+
* group's inline consolidated entries.
|
|
35
11
|
*
|
|
36
12
|
* Unrecognized names are skipped everywhere — the extension name space is
|
|
37
13
|
* open, and a rule that guessed would lie. This layer has no counterpart
|
|
38
14
|
* in the Python reference implementation (which stops at structure), so it
|
|
39
15
|
* is covered by this package's own tests rather than the conformance
|
|
40
|
-
* corpus.
|
|
16
|
+
* corpus. The structural document layer (validation.ts) stays
|
|
17
|
+
* content-agnostic and corpus-governed; it never reads the content
|
|
18
|
+
* modules.
|
|
41
19
|
*/
|
|
42
20
|
import { type ErrorTree } from "./errors.js";
|
|
43
21
|
/**
|
package/dist/semantics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantics.d.ts","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"semantics.d.ts","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAU,KAAK,SAAS,EAAoB,MAAM,aAAa,CAAC;AA4BvE;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAElE;AA0BD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAE7D"}
|
package/dist/semantics.js
CHANGED
|
@@ -1,368 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Semantic (cross-field) validation for v3 array metadata
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - the `rectilinear` chunk grid requires a configuration with `kind` and
|
|
12
|
-
* `chunk_shapes`; `chunk_shapes` has one entry per dimension, and each
|
|
13
|
-
* explicit chunk list (integers and `[size, count]` run-length pairs)
|
|
14
|
-
* sums exactly to that dimension's length (the bare-integer uniform
|
|
15
|
-
* shorthand carries no sum constraint, like the regular grid);
|
|
16
|
-
* - a `transpose` codec's `order` is a permutation of `0..n-1`, with one
|
|
17
|
-
* entry per array dimension;
|
|
18
|
-
* - a `sharding_indexed` codec's inner `chunk_shape` matches the array's
|
|
19
|
-
* dimensionality and evenly divides every chunk it shards — the grid's
|
|
20
|
-
* chunk at the top level (each distinct per-dimension size, for
|
|
21
|
-
* rectilinear grids), the parent shard's inner chunk when sharding
|
|
22
|
-
* nests;
|
|
23
|
-
* - `fill_value` has a JSON shape permitted for the named core data type
|
|
24
|
-
* (booleans for `bool`, ranged integers for the int types, numbers /
|
|
25
|
-
* the "NaN"-family sentinels / width-checked "0x…" strings for the
|
|
26
|
-
* float types, two-element arrays for the complex types).
|
|
27
|
-
*
|
|
28
|
-
* Dimensional context is THREADED through codec pipelines rather than
|
|
29
|
-
* assumed constant (mirroring zarr-python's chunk-spec threading): a valid
|
|
30
|
-
* `transpose` permutes the per-dimension chunk sizes for the codecs after
|
|
31
|
-
* it, and any codec this layer cannot reason about — `reshape` may change
|
|
32
|
-
* a chunk's rank, and unknown codecs may do anything — invalidates the
|
|
33
|
-
* dimensional context for the rest of the pipeline instead of letting
|
|
34
|
-
* stale array-level facts produce false verdicts.
|
|
2
|
+
* Semantic (cross-field) validation for v3 array metadata: the
|
|
3
|
+
* orchestrator. The rules themselves live with their content —
|
|
4
|
+
* `chunk-grids.ts`, `codecs.ts`, and `data-types.ts` each hold the syntax
|
|
5
|
+
* (types) and semantics (procedures) for the names this package
|
|
6
|
+
* interprets, mirroring how the spec, the Python reference's type layout,
|
|
7
|
+
* and the zarr-extensions registry are organized. This module only walks
|
|
8
|
+
* documents: extract shape, ask each content module for its verdicts,
|
|
9
|
+
* thread the chunk-size context into codec pipelines, and descend into a
|
|
10
|
+
* group's inline consolidated entries.
|
|
35
11
|
*
|
|
36
12
|
* Unrecognized names are skipped everywhere — the extension name space is
|
|
37
13
|
* open, and a rule that guessed would lie. This layer has no counterpart
|
|
38
14
|
* in the Python reference implementation (which stops at structure), so it
|
|
39
15
|
* is covered by this package's own tests rather than the conformance
|
|
40
|
-
* corpus.
|
|
16
|
+
* corpus. The structural document layer (validation.ts) stays
|
|
17
|
+
* content-agnostic and corpus-governed; it never reads the content
|
|
18
|
+
* modules.
|
|
41
19
|
*/
|
|
20
|
+
import { chunkGridVerdict } from "./chunk-grids.js";
|
|
21
|
+
import { pipelineIssues } from "./codecs.js";
|
|
22
|
+
import { fillValueIssue } from "./data-types.js";
|
|
42
23
|
import { treeOf } from "./errors.js";
|
|
43
|
-
|
|
44
|
-
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
45
|
-
return false;
|
|
46
|
-
const proto = Object.getPrototypeOf(value);
|
|
47
|
-
return proto === null || proto === Object.prototype;
|
|
48
|
-
}
|
|
49
|
-
function isIntArray(value) {
|
|
50
|
-
return (Array.isArray(value) &&
|
|
51
|
-
Object.keys(value).length === value.length &&
|
|
52
|
-
value.every((item) => Number.isInteger(item)));
|
|
53
|
-
}
|
|
54
|
-
/** The `{name, configuration}` of a metadata field, when extractable. */
|
|
55
|
-
function fieldParts(field) {
|
|
56
|
-
if (typeof field === "string")
|
|
57
|
-
return { name: field, configuration: undefined };
|
|
58
|
-
if (isPlainObject(field) && typeof field["name"] === "string") {
|
|
59
|
-
const configuration = field["configuration"];
|
|
60
|
-
return {
|
|
61
|
-
name: field["name"],
|
|
62
|
-
configuration: isPlainObject(configuration) ? configuration : undefined,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
return undefined;
|
|
66
|
-
}
|
|
67
|
-
// --- fill_value vs data_type ----------------------------------------------
|
|
68
|
-
const INT_RANGES = {
|
|
69
|
-
int8: [-128, 127],
|
|
70
|
-
int16: [-32768, 32767],
|
|
71
|
-
int32: [-2147483648, 2147483647],
|
|
72
|
-
int64: [-9223372036854775808, 9223372036854775807],
|
|
73
|
-
uint8: [0, 255],
|
|
74
|
-
uint16: [0, 65535],
|
|
75
|
-
uint32: [0, 4294967295],
|
|
76
|
-
uint64: [0, 18446744073709551615],
|
|
77
|
-
};
|
|
78
|
-
const FLOAT_HEX_DIGITS = {
|
|
79
|
-
float16: 4,
|
|
80
|
-
float32: 8,
|
|
81
|
-
float64: 16,
|
|
82
|
-
};
|
|
83
|
-
/** Hex digit width of each complex type's component floats. */
|
|
84
|
-
const COMPLEX_COMPONENT_HEX_DIGITS = {
|
|
85
|
-
complex64: 8,
|
|
86
|
-
complex128: 16,
|
|
87
|
-
};
|
|
88
|
-
function isFloatFill(value, hexDigits) {
|
|
89
|
-
if (typeof value === "number")
|
|
90
|
-
return true;
|
|
91
|
-
if (typeof value !== "string")
|
|
92
|
-
return false;
|
|
93
|
-
if (value === "NaN" || value === "Infinity" || value === "-Infinity")
|
|
94
|
-
return true;
|
|
95
|
-
return new RegExp(`^0x[0-9a-fA-F]{${hexDigits}}$`).test(value);
|
|
96
|
-
}
|
|
97
|
-
function floatFillMessage(name, hexDigits) {
|
|
98
|
-
return (`expected a number, "NaN", "Infinity", "-Infinity", or a ` +
|
|
99
|
-
`${hexDigits}-hex-digit "0x..." string for data type ${JSON.stringify(name)}`);
|
|
100
|
-
}
|
|
101
|
-
/** The fill_value issue for a KNOWN core data type, if any; undefined otherwise. */
|
|
102
|
-
function fillValueIssue(dataTypeName, fill) {
|
|
103
|
-
if (dataTypeName === "bool") {
|
|
104
|
-
return typeof fill === "boolean"
|
|
105
|
-
? undefined
|
|
106
|
-
: 'expected a boolean fill value for data type "bool"';
|
|
107
|
-
}
|
|
108
|
-
const intRange = INT_RANGES[dataTypeName];
|
|
109
|
-
if (intRange !== undefined) {
|
|
110
|
-
const [low, high] = intRange;
|
|
111
|
-
return Number.isInteger(fill) && fill >= low && fill <= high
|
|
112
|
-
? undefined
|
|
113
|
-
: `expected an integer in [${low}, ${high}] for data type ${JSON.stringify(dataTypeName)}`;
|
|
114
|
-
}
|
|
115
|
-
const floatDigits = FLOAT_HEX_DIGITS[dataTypeName];
|
|
116
|
-
if (floatDigits !== undefined) {
|
|
117
|
-
return isFloatFill(fill, floatDigits)
|
|
118
|
-
? undefined
|
|
119
|
-
: floatFillMessage(dataTypeName, floatDigits);
|
|
120
|
-
}
|
|
121
|
-
const complexDigits = COMPLEX_COMPONENT_HEX_DIGITS[dataTypeName];
|
|
122
|
-
if (complexDigits !== undefined) {
|
|
123
|
-
const ok = Array.isArray(fill) &&
|
|
124
|
-
fill.length === 2 &&
|
|
125
|
-
fill.every((part) => isFloatFill(part, complexDigits));
|
|
126
|
-
return ok
|
|
127
|
-
? undefined
|
|
128
|
-
: `expected a two-element [real, imaginary] array for data type ${JSON.stringify(dataTypeName)}`;
|
|
129
|
-
}
|
|
130
|
-
return undefined; // unrecognized data type: no verdict
|
|
131
|
-
}
|
|
132
|
-
// --- codec pipelines (transpose / sharding) --------------------------------
|
|
133
|
-
function isPermutation(order) {
|
|
134
|
-
const seen = new Set(order);
|
|
135
|
-
return seen.size === order.length && order.every((entry) => entry >= 0 && entry < order.length);
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Walk one codec pipeline. `dims` is the array dimensionality at this point
|
|
139
|
-
* (undefined when unknowable); `outerChunkSizes` holds the distinct chunk
|
|
140
|
-
* lengths per dimension this pipeline may encode — what a sharding codec's
|
|
141
|
-
* inner chunks must divide. A regular grid contributes one size per
|
|
142
|
-
* dimension; a rectilinear grid may contribute several.
|
|
143
|
-
*/
|
|
144
|
-
function pipelineIssues(pipeline, path, initialDims, initialChunkSizes) {
|
|
145
|
-
const issues = [];
|
|
146
|
-
// The dimensional context THREADS through the pipeline: transpose permutes
|
|
147
|
-
// it, and anything this layer cannot reason about invalidates it for the
|
|
148
|
-
// remaining codecs.
|
|
149
|
-
let dims = initialDims;
|
|
150
|
-
let chunkSizes = initialChunkSizes;
|
|
151
|
-
const dropContext = () => {
|
|
152
|
-
dims = undefined;
|
|
153
|
-
chunkSizes = undefined;
|
|
154
|
-
};
|
|
155
|
-
pipeline.forEach((entry, index) => {
|
|
156
|
-
const parts = fieldParts(entry);
|
|
157
|
-
if (parts === undefined) {
|
|
158
|
-
dropContext(); // structurally invalid entry: no further reasoning
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
const { name, configuration } = parts;
|
|
162
|
-
if (name === "transpose") {
|
|
163
|
-
const order = configuration?.["order"];
|
|
164
|
-
if (!isIntArray(order)) {
|
|
165
|
-
dropContext(); // shape errors are the schema layer's
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const orderPath = [...path, index, "configuration", "order"];
|
|
169
|
-
let sound = true;
|
|
170
|
-
if (!isPermutation(order)) {
|
|
171
|
-
sound = false;
|
|
172
|
-
issues.push({
|
|
173
|
-
path: orderPath,
|
|
174
|
-
message: `expected a permutation of the integers 0..${order.length - 1}`,
|
|
175
|
-
kind: "invalid_value",
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
if (dims !== undefined && order.length !== dims) {
|
|
179
|
-
sound = false;
|
|
180
|
-
issues.push({
|
|
181
|
-
path: orderPath,
|
|
182
|
-
message: `expected one entry per array dimension (${dims})`,
|
|
183
|
-
kind: "invalid_value",
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
if (!sound) {
|
|
187
|
-
dropContext();
|
|
188
|
-
}
|
|
189
|
-
else if (chunkSizes !== undefined) {
|
|
190
|
-
const sizes = chunkSizes;
|
|
191
|
-
chunkSizes =
|
|
192
|
-
order.length === sizes.length
|
|
193
|
-
? order.map((axis) => sizes[axis])
|
|
194
|
-
: undefined;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
else if (name === "sharding_indexed") {
|
|
198
|
-
const chunkShape = configuration?.["chunk_shape"];
|
|
199
|
-
if (!isIntArray(chunkShape)) {
|
|
200
|
-
dropContext();
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const chunkShapePath = [...path, index, "configuration", "chunk_shape"];
|
|
204
|
-
if (dims !== undefined && chunkShape.length !== dims) {
|
|
205
|
-
issues.push({
|
|
206
|
-
path: chunkShapePath,
|
|
207
|
-
message: `expected one length per array dimension (${dims})`,
|
|
208
|
-
kind: "invalid_value",
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
else if (chunkSizes !== undefined &&
|
|
212
|
-
chunkShape.length === chunkSizes.length &&
|
|
213
|
-
chunkShape.every((length) => length > 0)) {
|
|
214
|
-
let violation;
|
|
215
|
-
chunkSizes.forEach((sizes, axis) => {
|
|
216
|
-
if (violation !== undefined)
|
|
217
|
-
return;
|
|
218
|
-
const bad = sizes.find((size) => size % chunkShape[axis] !== 0);
|
|
219
|
-
if (bad !== undefined)
|
|
220
|
-
violation = { axis, size: bad };
|
|
221
|
-
});
|
|
222
|
-
if (violation !== undefined) {
|
|
223
|
-
const { axis, size } = violation;
|
|
224
|
-
const sizesNow = chunkSizes;
|
|
225
|
-
const uniform = sizesNow.every((sizes) => sizes.length === 1);
|
|
226
|
-
issues.push({
|
|
227
|
-
path: chunkShapePath,
|
|
228
|
-
message: uniform
|
|
229
|
-
? `expected ${JSON.stringify(chunkShape)} to evenly divide the outer chunk shape ${JSON.stringify(sizesNow.map((sizes) => sizes[0]))}`
|
|
230
|
-
: `expected ${JSON.stringify(chunkShape)} to evenly divide every chunk size of the grid (dimension ${axis} has chunk size ${size})`,
|
|
231
|
-
kind: "invalid_value",
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
const inner = configuration?.["codecs"];
|
|
236
|
-
if (Array.isArray(inner)) {
|
|
237
|
-
issues.push(...pipelineIssues(inner, [...path, index, "configuration", "codecs"], chunkShape.length, chunkShape.map((length) => [length])));
|
|
238
|
-
}
|
|
239
|
-
// index_codecs encode the shard index, whose shape differs from the
|
|
240
|
-
// array's — no dimensional context applies there. After the
|
|
241
|
-
// array -> bytes boundary the dimensional context is spent.
|
|
242
|
-
dropContext();
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
// A codec this layer cannot reason about (reshape may change a
|
|
246
|
-
// chunk's rank; unknown codecs may do anything): stale array-level
|
|
247
|
-
// facts must not judge the codecs after it.
|
|
248
|
-
dropContext();
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
return issues;
|
|
252
|
-
}
|
|
24
|
+
import { fieldParts, isIntArray, isPlainObject } from "./guards.js";
|
|
253
25
|
function arraySemanticsIssues(value) {
|
|
254
26
|
if (!isPlainObject(value) || value["node_type"] !== "array")
|
|
255
27
|
return [];
|
|
256
28
|
const issues = [];
|
|
257
29
|
const shape = isIntArray(value["shape"]) ? value["shape"] : undefined;
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
const grid = fieldParts(rawGrid);
|
|
261
|
-
// Whether the field genuinely lacks a configuration member (a malformed
|
|
262
|
-
// one — configuration: 5 — is the structural layer's complaint, not ours).
|
|
263
|
-
const configMissing = typeof rawGrid === "string" ||
|
|
264
|
-
(isPlainObject(rawGrid) && !Object.hasOwn(rawGrid, "configuration"));
|
|
265
|
-
let chunkSizes;
|
|
266
|
-
if (grid?.name === "regular") {
|
|
267
|
-
if (configMissing) {
|
|
268
|
-
issues.push({
|
|
269
|
-
path: ["chunk_grid"],
|
|
270
|
-
message: '"regular" requires a configuration with "chunk_shape"',
|
|
271
|
-
kind: "missing_key",
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
else if (grid.configuration !== undefined && !Object.hasOwn(grid.configuration, "chunk_shape")) {
|
|
275
|
-
issues.push({
|
|
276
|
-
path: ["chunk_grid", "configuration", "chunk_shape"],
|
|
277
|
-
message: "missing required key",
|
|
278
|
-
kind: "missing_key",
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
const configured = grid.configuration?.["chunk_shape"];
|
|
282
|
-
if (isIntArray(configured)) {
|
|
283
|
-
if (dims !== undefined && configured.length !== dims) {
|
|
284
|
-
issues.push({
|
|
285
|
-
path: ["chunk_grid", "configuration", "chunk_shape"],
|
|
286
|
-
message: `expected one length per dimension of shape (${dims})`,
|
|
287
|
-
kind: "invalid_value",
|
|
288
|
-
});
|
|
289
|
-
// wrong arity: unusable as division context
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
chunkSizes = configured.map((length) => [length]);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
else if (grid?.name === "rectilinear") {
|
|
297
|
-
if (configMissing) {
|
|
298
|
-
issues.push({
|
|
299
|
-
path: ["chunk_grid"],
|
|
300
|
-
message: '"rectilinear" requires a configuration with "kind" and "chunk_shapes"',
|
|
301
|
-
kind: "missing_key",
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
else if (grid.configuration !== undefined) {
|
|
305
|
-
for (const key of ["kind", "chunk_shapes"]) {
|
|
306
|
-
if (!Object.hasOwn(grid.configuration, key)) {
|
|
307
|
-
issues.push({
|
|
308
|
-
path: ["chunk_grid", "configuration", key],
|
|
309
|
-
message: "missing required key",
|
|
310
|
-
kind: "missing_key",
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
const specs = grid.configuration?.["chunk_shapes"];
|
|
316
|
-
if (Array.isArray(specs)) {
|
|
317
|
-
if (dims !== undefined && specs.length !== dims) {
|
|
318
|
-
issues.push({
|
|
319
|
-
path: ["chunk_grid", "configuration", "chunk_shapes"],
|
|
320
|
-
message: `expected one entry per dimension of shape (${dims})`,
|
|
321
|
-
kind: "invalid_value",
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
const perDim = specs.map((spec, dim) => {
|
|
326
|
-
// Bare integer: uniform shorthand, no sum constraint (edge chunks
|
|
327
|
-
// are permitted, as with the regular grid).
|
|
328
|
-
if (Number.isInteger(spec))
|
|
329
|
-
return spec > 0 ? [spec] : undefined;
|
|
330
|
-
if (!Array.isArray(spec))
|
|
331
|
-
return undefined; // registry schema's problem
|
|
332
|
-
const sizes = new Set();
|
|
333
|
-
let total = 0;
|
|
334
|
-
for (const entry of spec) {
|
|
335
|
-
if (Number.isInteger(entry)) {
|
|
336
|
-
sizes.add(entry);
|
|
337
|
-
total += entry;
|
|
338
|
-
}
|
|
339
|
-
else if (Array.isArray(entry) &&
|
|
340
|
-
entry.length === 2 &&
|
|
341
|
-
Number.isInteger(entry[0]) &&
|
|
342
|
-
Number.isInteger(entry[1])) {
|
|
343
|
-
sizes.add(entry[0]);
|
|
344
|
-
total += entry[0] * entry[1];
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
return undefined; // malformed entry: registry schema's problem
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
const extent = shape?.[dim];
|
|
351
|
-
if (extent !== undefined && total !== extent) {
|
|
352
|
-
issues.push({
|
|
353
|
-
path: ["chunk_grid", "configuration", "chunk_shapes", dim],
|
|
354
|
-
message: `expected chunk sizes summing to ${extent} along dimension ${dim}, got ${total}`,
|
|
355
|
-
kind: "invalid_value",
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
return [...sizes];
|
|
359
|
-
});
|
|
360
|
-
if (perDim.every((sizes) => sizes !== undefined)) {
|
|
361
|
-
chunkSizes = perDim;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
30
|
+
const grid = chunkGridVerdict(value["chunk_grid"], shape);
|
|
31
|
+
issues.push(...grid.issues.map((issue) => ({ ...issue, path: ["chunk_grid", ...issue.path] })));
|
|
366
32
|
const dataType = fieldParts(value["data_type"]);
|
|
367
33
|
if (dataType !== undefined && "fill_value" in value) {
|
|
368
34
|
const message = fillValueIssue(dataType.name, value["fill_value"]);
|
|
@@ -372,7 +38,7 @@ function arraySemanticsIssues(value) {
|
|
|
372
38
|
}
|
|
373
39
|
const codecs = value["codecs"];
|
|
374
40
|
if (Array.isArray(codecs)) {
|
|
375
|
-
issues.push(...pipelineIssues(codecs, ["codecs"],
|
|
41
|
+
issues.push(...pipelineIssues(codecs, ["codecs"], shape?.length, grid.chunkSizes));
|
|
376
42
|
}
|
|
377
43
|
return issues;
|
|
378
44
|
}
|
package/dist/semantics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantics.js","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"semantics.js","sourceRoot":"","sources":["../src/semantics.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chunk grids this package interprets: syntax (configuration types) and
|
|
3
|
+
* semantics (the spec's prose rules) for `regular` and `rectilinear`, in
|
|
4
|
+
* one place per grid. The structural document layer never reads this
|
|
5
|
+
* module — extension points are uninterpreted there by spec design.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { PathedIssue } from "./errors.js";
|
|
9
|
+
import { configurationMissing, fieldParts, isIntArray, isPlainObject } from "./guards.js";
|
|
10
|
+
|
|
11
|
+
/** Configuration of the core `regular` chunk grid. */
|
|
12
|
+
export interface RegularChunkGridConfiguration {
|
|
13
|
+
chunk_shape: number[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* One dimension's spec in a rectilinear grid: a bare integer (uniform
|
|
18
|
+
* shorthand, no sum constraint) or a list of chunk sizes and
|
|
19
|
+
* `[size, count]` run-length pairs that must sum to the dimension length.
|
|
20
|
+
*/
|
|
21
|
+
export type RectilinearDimSpec = number | Array<number | [number, number]>;
|
|
22
|
+
|
|
23
|
+
/** Configuration of the zarr-extensions `rectilinear` chunk grid. */
|
|
24
|
+
export interface RectilinearChunkGridConfiguration {
|
|
25
|
+
kind: "inline";
|
|
26
|
+
chunk_shapes: RectilinearDimSpec[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** What interpreting a chunk grid yields for the rest of the semantic layer. */
|
|
30
|
+
export interface ChunkGridVerdict {
|
|
31
|
+
/** Issues, pathed relative to the `chunk_grid` field. */
|
|
32
|
+
issues: PathedIssue[];
|
|
33
|
+
/**
|
|
34
|
+
* Distinct chunk lengths per dimension — the division context a
|
|
35
|
+
* sharding codec's inner chunks must satisfy — when derivable.
|
|
36
|
+
*/
|
|
37
|
+
chunkSizes: number[][] | undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function regularIssues(rawGrid: unknown, shape: number[] | undefined): ChunkGridVerdict {
|
|
41
|
+
const issues: PathedIssue[] = [];
|
|
42
|
+
let chunkSizes: number[][] | undefined;
|
|
43
|
+
const configuration = fieldParts(rawGrid)?.configuration;
|
|
44
|
+
if (configurationMissing(rawGrid)) {
|
|
45
|
+
issues.push({
|
|
46
|
+
path: [],
|
|
47
|
+
message: '"regular" requires a configuration with "chunk_shape"',
|
|
48
|
+
kind: "missing_key",
|
|
49
|
+
});
|
|
50
|
+
} else if (configuration !== undefined && !Object.hasOwn(configuration, "chunk_shape")) {
|
|
51
|
+
issues.push({
|
|
52
|
+
path: ["configuration", "chunk_shape"],
|
|
53
|
+
message: "missing required key",
|
|
54
|
+
kind: "missing_key",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const configured = configuration?.["chunk_shape"];
|
|
58
|
+
if (isIntArray(configured)) {
|
|
59
|
+
if (shape !== undefined && configured.length !== shape.length) {
|
|
60
|
+
issues.push({
|
|
61
|
+
path: ["configuration", "chunk_shape"],
|
|
62
|
+
message: `expected one length per dimension of shape (${shape.length})`,
|
|
63
|
+
kind: "invalid_value",
|
|
64
|
+
});
|
|
65
|
+
// wrong arity: unusable as division context
|
|
66
|
+
} else {
|
|
67
|
+
chunkSizes = configured.map((length) => [length]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { issues, chunkSizes };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function rectilinearIssues(rawGrid: unknown, shape: number[] | undefined): ChunkGridVerdict {
|
|
74
|
+
const issues: PathedIssue[] = [];
|
|
75
|
+
let chunkSizes: number[][] | undefined;
|
|
76
|
+
const configuration = fieldParts(rawGrid)?.configuration;
|
|
77
|
+
if (configurationMissing(rawGrid)) {
|
|
78
|
+
issues.push({
|
|
79
|
+
path: [],
|
|
80
|
+
message: '"rectilinear" requires a configuration with "kind" and "chunk_shapes"',
|
|
81
|
+
kind: "missing_key",
|
|
82
|
+
});
|
|
83
|
+
} else if (configuration !== undefined) {
|
|
84
|
+
for (const key of ["kind", "chunk_shapes"]) {
|
|
85
|
+
if (!Object.hasOwn(configuration, key)) {
|
|
86
|
+
issues.push({
|
|
87
|
+
path: ["configuration", key],
|
|
88
|
+
message: "missing required key",
|
|
89
|
+
kind: "missing_key",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const specs = configuration?.["chunk_shapes"];
|
|
95
|
+
if (Array.isArray(specs)) {
|
|
96
|
+
if (shape !== undefined && specs.length !== shape.length) {
|
|
97
|
+
issues.push({
|
|
98
|
+
path: ["configuration", "chunk_shapes"],
|
|
99
|
+
message: `expected one entry per dimension of shape (${shape.length})`,
|
|
100
|
+
kind: "invalid_value",
|
|
101
|
+
});
|
|
102
|
+
} else {
|
|
103
|
+
const perDim: (number[] | undefined)[] = specs.map((spec, dim) => {
|
|
104
|
+
// Bare integer: uniform shorthand, no sum constraint (edge chunks
|
|
105
|
+
// are permitted, as with the regular grid).
|
|
106
|
+
if (Number.isInteger(spec)) return (spec as number) > 0 ? [spec as number] : undefined;
|
|
107
|
+
if (!Array.isArray(spec)) return undefined; // registry schema's problem
|
|
108
|
+
const sizes = new Set<number>();
|
|
109
|
+
let total = 0;
|
|
110
|
+
for (const entry of spec) {
|
|
111
|
+
if (Number.isInteger(entry)) {
|
|
112
|
+
sizes.add(entry as number);
|
|
113
|
+
total += entry as number;
|
|
114
|
+
} else if (
|
|
115
|
+
Array.isArray(entry) &&
|
|
116
|
+
entry.length === 2 &&
|
|
117
|
+
Number.isInteger(entry[0]) &&
|
|
118
|
+
Number.isInteger(entry[1])
|
|
119
|
+
) {
|
|
120
|
+
sizes.add(entry[0] as number);
|
|
121
|
+
total += (entry[0] as number) * (entry[1] as number);
|
|
122
|
+
} else {
|
|
123
|
+
return undefined; // malformed entry: registry schema's problem
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const extent = shape?.[dim];
|
|
127
|
+
if (extent !== undefined && total !== extent) {
|
|
128
|
+
issues.push({
|
|
129
|
+
path: ["configuration", "chunk_shapes", dim],
|
|
130
|
+
message: `expected chunk sizes summing to ${extent} along dimension ${dim}, got ${total}`,
|
|
131
|
+
kind: "invalid_value",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return [...sizes];
|
|
135
|
+
});
|
|
136
|
+
if (perDim.every((sizes) => sizes !== undefined)) {
|
|
137
|
+
chunkSizes = perDim as number[][];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return { issues, chunkSizes };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Interpret a document's `chunk_grid` field: required members, cross-field
|
|
146
|
+
* rules against `shape`, and the division context for codec pipelines.
|
|
147
|
+
* Unrecognized grid names yield no issues and no context — the extension
|
|
148
|
+
* name space is open.
|
|
149
|
+
*/
|
|
150
|
+
export function chunkGridVerdict(rawGrid: unknown, shape: number[] | undefined): ChunkGridVerdict {
|
|
151
|
+
if (!isPlainObject(rawGrid) && typeof rawGrid !== "string") {
|
|
152
|
+
return { issues: [], chunkSizes: undefined }; // structural layer's problem
|
|
153
|
+
}
|
|
154
|
+
const name = fieldParts(rawGrid)?.name;
|
|
155
|
+
if (name === "regular") return regularIssues(rawGrid, shape);
|
|
156
|
+
if (name === "rectilinear") return rectilinearIssues(rawGrid, shape);
|
|
157
|
+
return { issues: [], chunkSizes: undefined };
|
|
158
|
+
}
|