Skip to content

Commit efdee80

Browse files
authored
Merge pull request #283 from keller-mark/keller-mark/zmetadata-key
Support a zmetadata key option for consolidated stores
2 parents 0e809ef + 8b1e74c commit efdee80

File tree

6 files changed

+43
-8
lines changed

6 files changed

+43
-8
lines changed

.changeset/sweet-beans-lick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"zarrita": patch
3+
---
4+
5+
Add support for options.metadataKey in withConsolidated and tryWithConsolidated"

.github/workflows/ci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,4 @@ jobs:
2727
steps:
2828
- uses: actions/checkout@v4
2929
- uses: biomejs/setup-biome@v2
30-
with:
31-
version: latest
3230
- run: biome ci .

biome.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
2+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
33
"organizeImports": {
44
"enabled": true
55
},

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"build": "tsc --build",
55
"clean": "pnpm --recursive exec rm -rf dist",
66
"test": "vitest --api",
7-
"format": "format .",
7+
"format": "biome format .",
88
"lint": "biome ci .",
99
"fix": "biome check --write .",
1010
"publint": "pnpm --recursive --filter=\"./packages/**\" exec publint",

packages/zarrita/__tests__/consolidated.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,22 @@ describe("tryWithConsolidated", () => {
123123
let store = await tryWithConsolidated(new FileSystemStore(root));
124124
expect(store).toBeInstanceOf(FileSystemStore);
125125
});
126+
127+
it("supports a zmetadataKey option", async () => {
128+
let root = path.join(__dirname, "../../../fixtures/v2/data.zarr");
129+
let store = await tryWithConsolidated(new FileSystemStore(root), {
130+
metadataKey: ".zmetadata",
131+
});
132+
expect(store).toHaveProperty("contents");
133+
});
134+
135+
it("falls back to original store if metadataKey is incorrect", async () => {
136+
let root = path.join(__dirname, "../../../fixtures/v2/data.zarr");
137+
let store = await tryWithConsolidated(new FileSystemStore(root), {
138+
metadataKey: ".nonexistent",
139+
});
140+
expect(store).toBeInstanceOf(FileSystemStore);
141+
});
126142
});
127143

128144
describe("Listable.getRange", () => {

packages/zarrita/src/consolidated.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ export interface Listable<Store extends Readable> {
3333

3434
async function get_consolidated_metadata(
3535
store: Readable,
36+
metadataKeyOption: string | undefined,
3637
): Promise<ConsolidatedMetadata> {
37-
let bytes = await store.get("/.zmetadata");
38+
const metadataKey = metadataKeyOption ?? ".zmetadata";
39+
let bytes = await store.get(`/${metadataKey}`);
3840
if (!bytes) {
3941
throw new NodeNotFoundError("v2 consolidated metadata", {
40-
cause: new KeyError("/.zmetadata"),
42+
cause: new KeyError(`/${metadataKey}`),
4143
});
4244
}
4345
let meta: ConsolidatedMetadata = json_decode_object(bytes);
@@ -68,13 +70,24 @@ function is_v3(meta: Metadata): meta is ArrayMetadata | GroupMetadata {
6870
return "zarr_format" in meta && meta.zarr_format === 3;
6971
}
7072

73+
/** Options for {@linkcode withConsolidated} and {@linkcode tryWithConsolidated}. */
74+
export interface WithConsolidatedOptions {
75+
/**
76+
* Key to read consolidated metadata from.
77+
*
78+
* @default {".zmetadata"}
79+
*/
80+
readonly metadataKey?: string;
81+
}
82+
7183
/**
7284
* Open a consolidated store.
7385
*
7486
* This will open a store with Zarr v2 consolidated metadata (`.zmetadata`).
7587
* @see {@link https://zarr.readthedocs.io/en/stable/spec/v2.html#consolidated-metadata}
7688
*
7789
* @param store The store to open.
90+
* @param opts Options object.
7891
* @returns A listable store.
7992
*
8093
* @example
@@ -89,8 +102,9 @@ function is_v3(meta: Metadata): meta is ArrayMetadata | GroupMetadata {
89102
*/
90103
export async function withConsolidated<Store extends Readable>(
91104
store: Store,
105+
opts: WithConsolidatedOptions = {},
92106
): Promise<Listable<Store>> {
93-
let v2_meta = await get_consolidated_metadata(store);
107+
let v2_meta = await get_consolidated_metadata(store, opts.metadataKey);
94108
let known_meta: Record<AbsolutePath, Metadata> = {};
95109
for (let [key, value] of Object.entries(v2_meta.metadata)) {
96110
known_meta[`/${key}`] = value;
@@ -142,12 +156,14 @@ export async function withConsolidated<Store extends Readable>(
142156
* additional network requests when accessing underlying groups and arrays.
143157
*
144158
* @param store The store to open.
159+
* @param opts Options to pass to withConsolidated.
145160
* @returns A listable store.
146161
*/
147162
export async function tryWithConsolidated<Store extends Readable>(
148163
store: Store,
164+
opts: WithConsolidatedOptions = {},
149165
): Promise<Listable<Store> | Store> {
150-
return withConsolidated(store).catch((error: unknown) => {
166+
return withConsolidated(store, opts).catch((error: unknown) => {
151167
rethrow_unless(error, NodeNotFoundError);
152168
return store;
153169
});

0 commit comments

Comments
 (0)