Skip to content

Commit 6151346

Browse files
authored
Propagate getRange support in Listable when available (#252)
Previously, only `get` was propagated up. This makes sure we can also use `getRange` if supported when the store is consolidated.
1 parent 5f13737 commit 6151346

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

.changeset/rich-horses-count.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@zarrita/core": patch
3+
---
4+
5+
Propagate getRange support in `Listable` when available

packages/core/__tests__/consolidated.test.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as path from "node:path";
22
import * as url from "node:url";
3-
import { describe, expect, it } from "vitest";
3+
import { assert, describe, expect, it } from "vitest";
44

55
import { FileSystemStore } from "@zarrita/storage";
66
import { tryWithConsolidated, withConsolidated } from "../src/consolidated.js";
@@ -124,3 +124,15 @@ describe("tryWithConsolidated", () => {
124124
expect(store).toBeInstanceOf(FileSystemStore);
125125
});
126126
});
127+
128+
describe("Listable.getRange", () => {
129+
it("does not expose getRange if the underlying store does not support it", async () => {
130+
let store = await tryWithConsolidated(new Map());
131+
expect("getRange" in store).toBeFalsy();
132+
});
133+
it("retrieves a byte range from an underlying store", async () => {
134+
let root = path.join(__dirname, "../../../fixtures/v2/data.zarr");
135+
let store = await tryWithConsolidated(new FileSystemStore(root));
136+
assert(typeof store.getRange === "function");
137+
});
138+
});

packages/core/src/consolidated.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ type ConsolidatedMetadata = {
2424
*/
2525
export interface Listable<Store extends Readable> {
2626
/** Get the bytes at a given path. */
27-
get: Store["get"];
27+
get: (...args: Parameters<Store["get"]>) => Promise<Uint8Array | undefined>;
28+
/** Get a byte range at a given path. */
29+
getRange: Store["getRange"];
2830
/** List the contents of the store. */
2931
contents(): { path: AbsolutePath; kind: "array" | "group" }[];
3032
}
@@ -93,6 +95,7 @@ export async function withConsolidated<Store extends Readable>(
9395
for (let [key, value] of Object.entries(v2_meta.metadata)) {
9496
known_meta[`/${key}`] = value;
9597
}
98+
9699
return {
97100
async get(
98101
...args: Parameters<Store["get"]>
@@ -108,6 +111,10 @@ export async function withConsolidated<Store extends Readable>(
108111
}
109112
return maybe_bytes;
110113
},
114+
// Delegate range requests to the underlying store.
115+
// Note: Supporting range requests for consolidated metadata is possible
116+
// but unlikely to be useful enough to justify the effort.
117+
getRange: store.getRange?.bind(store),
111118
contents(): { path: AbsolutePath; kind: "array" | "group" }[] {
112119
let contents: { path: AbsolutePath; kind: "array" | "group" }[] = [];
113120
for (let [key, value] of Object.entries(known_meta)) {

0 commit comments

Comments
 (0)