@freqhole/reliquary 0.0.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/dist/automerge/acl-filtering.d.ts +87 -0
- package/dist/automerge/acl-filtering.d.ts.map +1 -0
- package/dist/automerge/acl-filtering.js +138 -0
- package/dist/automerge/acl-filtering.test.d.ts +2 -0
- package/dist/automerge/acl-filtering.test.d.ts.map +1 -0
- package/dist/automerge/acl-filtering.test.js +302 -0
- package/dist/automerge/index.d.ts +5 -0
- package/dist/automerge/index.d.ts.map +1 -0
- package/dist/automerge/index.js +7 -0
- package/dist/automerge/iroh-network-adapter.d.ts +178 -0
- package/dist/automerge/iroh-network-adapter.d.ts.map +1 -0
- package/dist/automerge/iroh-network-adapter.js +691 -0
- package/dist/automerge/iroh-network-adapter.test.d.ts +2 -0
- package/dist/automerge/iroh-network-adapter.test.d.ts.map +1 -0
- package/dist/automerge/iroh-network-adapter.test.js +818 -0
- package/dist/automerge/types.d.ts +66 -0
- package/dist/automerge/types.d.ts.map +1 -0
- package/dist/automerge/types.js +10 -0
- package/dist/blobs/bytes-backend.d.ts +41 -0
- package/dist/blobs/bytes-backend.d.ts.map +1 -0
- package/dist/blobs/bytes-backend.js +252 -0
- package/dist/blobs/bytes-backend.test.d.ts +2 -0
- package/dist/blobs/bytes-backend.test.d.ts.map +1 -0
- package/dist/blobs/bytes-backend.test.js +241 -0
- package/dist/blobs/db.d.ts +8 -0
- package/dist/blobs/db.d.ts.map +1 -0
- package/dist/blobs/db.js +141 -0
- package/dist/blobs/db.test.d.ts +2 -0
- package/dist/blobs/db.test.d.ts.map +1 -0
- package/dist/blobs/db.test.js +120 -0
- package/dist/blobs/index.d.ts +5 -0
- package/dist/blobs/index.d.ts.map +1 -0
- package/dist/blobs/index.js +2 -0
- package/dist/blobs/store.d.ts +47 -0
- package/dist/blobs/store.d.ts.map +1 -0
- package/dist/blobs/store.js +263 -0
- package/dist/blobs/store.test.d.ts +2 -0
- package/dist/blobs/store.test.d.ts.map +1 -0
- package/dist/blobs/store.test.js +377 -0
- package/dist/blobs/types.d.ts +55 -0
- package/dist/blobs/types.d.ts.map +1 -0
- package/dist/blobs/types.js +8 -0
- package/dist/ensure/client.d.ts +19 -0
- package/dist/ensure/client.d.ts.map +1 -0
- package/dist/ensure/client.js +74 -0
- package/dist/ensure/client.test.d.ts +2 -0
- package/dist/ensure/client.test.d.ts.map +1 -0
- package/dist/ensure/client.test.js +133 -0
- package/dist/ensure/index.d.ts +4 -0
- package/dist/ensure/index.d.ts.map +1 -0
- package/dist/ensure/index.js +4 -0
- package/dist/ensure/responder.d.ts +20 -0
- package/dist/ensure/responder.d.ts.map +1 -0
- package/dist/ensure/responder.js +100 -0
- package/dist/ensure/responder.test.d.ts +2 -0
- package/dist/ensure/responder.test.d.ts.map +1 -0
- package/dist/ensure/responder.test.js +191 -0
- package/dist/ensure/types.d.ts +19 -0
- package/dist/ensure/types.d.ts.map +1 -0
- package/dist/ensure/types.js +4 -0
- package/dist/ensure/types.test.d.ts +2 -0
- package/dist/ensure/types.test.d.ts.map +1 -0
- package/dist/ensure/types.test.js +81 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +7 -0
- package/dist/solid/blob-url.d.ts +10 -0
- package/dist/solid/blob-url.d.ts.map +1 -0
- package/dist/solid/blob-url.js +34 -0
- package/dist/solid/blob-url.test.d.ts +2 -0
- package/dist/solid/blob-url.test.d.ts.map +1 -0
- package/dist/solid/blob-url.test.js +62 -0
- package/dist/solid/connection-summary.d.ts +25 -0
- package/dist/solid/connection-summary.d.ts.map +1 -0
- package/dist/solid/connection-summary.js +29 -0
- package/dist/solid/connection-summary.test.d.ts +2 -0
- package/dist/solid/connection-summary.test.d.ts.map +1 -0
- package/dist/solid/connection-summary.test.js +57 -0
- package/dist/solid/doc-store.d.ts +29 -0
- package/dist/solid/doc-store.d.ts.map +1 -0
- package/dist/solid/doc-store.js +79 -0
- package/dist/solid/doc-store.test.d.ts +2 -0
- package/dist/solid/doc-store.test.d.ts.map +1 -0
- package/dist/solid/doc-store.test.js +234 -0
- package/dist/solid/index.d.ts +4 -0
- package/dist/solid/index.d.ts.map +1 -0
- package/dist/solid/index.js +9 -0
- package/dist/solid/transfer-progress.d.ts +21 -0
- package/dist/solid/transfer-progress.d.ts.map +1 -0
- package/dist/solid/transfer-progress.js +32 -0
- package/dist/solid/transfer-progress.test.d.ts +2 -0
- package/dist/solid/transfer-progress.test.d.ts.map +1 -0
- package/dist/solid/transfer-progress.test.js +76 -0
- package/dist/testing/blob-fixtures.d.ts +19 -0
- package/dist/testing/blob-fixtures.d.ts.map +1 -0
- package/dist/testing/blob-fixtures.js +46 -0
- package/dist/testing/blob-fixtures.test.d.ts +2 -0
- package/dist/testing/blob-fixtures.test.d.ts.map +1 -0
- package/dist/testing/blob-fixtures.test.js +46 -0
- package/dist/testing/idb-harness.d.ts +10 -0
- package/dist/testing/idb-harness.d.ts.map +1 -0
- package/dist/testing/idb-harness.js +17 -0
- package/dist/testing/idb-harness.test.d.ts +2 -0
- package/dist/testing/idb-harness.test.d.ts.map +1 -0
- package/dist/testing/idb-harness.test.js +48 -0
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +11 -0
- package/dist/testing/media.d.ts +15 -0
- package/dist/testing/media.d.ts.map +1 -0
- package/dist/testing/media.js +37 -0
- package/dist/testing/media.test.d.ts +2 -0
- package/dist/testing/media.test.d.ts.map +1 -0
- package/dist/testing/media.test.js +47 -0
- package/dist/testing/mock-blob-fetch.d.ts +33 -0
- package/dist/testing/mock-blob-fetch.d.ts.map +1 -0
- package/dist/testing/mock-blob-fetch.js +39 -0
- package/dist/testing/mock-blob-fetch.test.d.ts +2 -0
- package/dist/testing/mock-blob-fetch.test.d.ts.map +1 -0
- package/dist/testing/mock-blob-fetch.test.js +65 -0
- package/dist/testing/mock-node.d.ts +36 -0
- package/dist/testing/mock-node.d.ts.map +1 -0
- package/dist/testing/mock-node.js +97 -0
- package/dist/testing/mock-node.test.d.ts +2 -0
- package/dist/testing/mock-node.test.d.ts.map +1 -0
- package/dist/testing/mock-node.test.js +66 -0
- package/dist/testing/streams.d.ts +68 -0
- package/dist/testing/streams.d.ts.map +1 -0
- package/dist/testing/streams.js +99 -0
- package/dist/testing/streams.test.d.ts +2 -0
- package/dist/testing/streams.test.d.ts.map +1 -0
- package/dist/testing/streams.test.js +82 -0
- package/dist/transfer/cancellation.d.ts +8 -0
- package/dist/transfer/cancellation.d.ts.map +1 -0
- package/dist/transfer/cancellation.js +19 -0
- package/dist/transfer/index.d.ts +8 -0
- package/dist/transfer/index.d.ts.map +1 -0
- package/dist/transfer/index.js +4 -0
- package/dist/transfer/prefetch.d.ts +38 -0
- package/dist/transfer/prefetch.d.ts.map +1 -0
- package/dist/transfer/prefetch.js +61 -0
- package/dist/transfer/prefetch.test.d.ts +2 -0
- package/dist/transfer/prefetch.test.d.ts.map +1 -0
- package/dist/transfer/prefetch.test.js +136 -0
- package/dist/transfer/serve.d.ts +66 -0
- package/dist/transfer/serve.d.ts.map +1 -0
- package/dist/transfer/serve.js +126 -0
- package/dist/transfer/serve.test.d.ts +2 -0
- package/dist/transfer/serve.test.d.ts.map +1 -0
- package/dist/transfer/serve.test.js +101 -0
- package/dist/transfer/snatch.d.ts +39 -0
- package/dist/transfer/snatch.d.ts.map +1 -0
- package/dist/transfer/snatch.js +289 -0
- package/dist/transfer/snatch.test.d.ts +2 -0
- package/dist/transfer/snatch.test.d.ts.map +1 -0
- package/dist/transfer/snatch.test.js +337 -0
- package/dist/transfer/types.d.ts +85 -0
- package/dist/transfer/types.d.ts.map +1 -0
- package/dist/transfer/types.js +15 -0
- package/dist/utils/hash.d.ts +13 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +31 -0
- package/dist/utils/hash.test.d.ts +2 -0
- package/dist/utils/hash.test.d.ts.map +1 -0
- package/dist/utils/hash.test.js +56 -0
- package/dist/utils/image-utils.d.ts +28 -0
- package/dist/utils/image-utils.d.ts.map +1 -0
- package/dist/utils/image-utils.js +113 -0
- package/dist/utils/image-utils.test.d.ts +2 -0
- package/dist/utils/image-utils.test.d.ts.map +1 -0
- package/dist/utils/image-utils.test.js +181 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/log.d.ts +22 -0
- package/dist/utils/log.d.ts.map +1 -0
- package/dist/utils/log.js +100 -0
- package/dist/utils/log.test.d.ts +2 -0
- package/dist/utils/log.test.d.ts.map +1 -0
- package/dist/utils/log.test.js +113 -0
- package/dist/worker/blob-worker-client.d.ts +118 -0
- package/dist/worker/blob-worker-client.d.ts.map +1 -0
- package/dist/worker/blob-worker-client.js +361 -0
- package/dist/worker/blob-worker-client.test.d.ts +2 -0
- package/dist/worker/blob-worker-client.test.d.ts.map +1 -0
- package/dist/worker/blob-worker-client.test.js +137 -0
- package/dist/worker/blob-worker-logic.d.ts +120 -0
- package/dist/worker/blob-worker-logic.d.ts.map +1 -0
- package/dist/worker/blob-worker-logic.js +368 -0
- package/dist/worker/blob-worker-logic.test.d.ts +2 -0
- package/dist/worker/blob-worker-logic.test.d.ts.map +1 -0
- package/dist/worker/blob-worker-logic.test.js +191 -0
- package/dist/worker/blob-worker.d.ts +21 -0
- package/dist/worker/blob-worker.d.ts.map +1 -0
- package/dist/worker/blob-worker.js +44 -0
- package/dist/worker/index.d.ts +12 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +6 -0
- package/dist/worker/midden-blake3.d.ts +23 -0
- package/dist/worker/midden-blake3.d.ts.map +1 -0
- package/dist/worker/midden-blake3.js +47 -0
- package/dist/worker/midden-blake3.test.d.ts +2 -0
- package/dist/worker/midden-blake3.test.d.ts.map +1 -0
- package/dist/worker/midden-blake3.test.js +25 -0
- package/dist/worker/midden-not-bundled.stub.d.ts +1 -0
- package/dist/worker/midden-not-bundled.stub.d.ts.map +1 -0
- package/dist/worker/midden-not-bundled.stub.js +10 -0
- package/dist/worker/midden-stub.d.ts +10 -0
- package/dist/worker/midden-stub.d.ts.map +1 -0
- package/dist/worker/midden-stub.js +31 -0
- package/dist/worker/midden-stub.test.d.ts +2 -0
- package/dist/worker/midden-stub.test.d.ts.map +1 -0
- package/dist/worker/midden-stub.test.js +25 -0
- package/dist/worker/midden-worker-client.d.ts +103 -0
- package/dist/worker/midden-worker-client.d.ts.map +1 -0
- package/dist/worker/midden-worker-client.js +246 -0
- package/dist/worker/midden-worker-client.test.d.ts +2 -0
- package/dist/worker/midden-worker-client.test.d.ts.map +1 -0
- package/dist/worker/midden-worker-client.test.js +151 -0
- package/dist/worker/midden-worker-contract.d.ts +87 -0
- package/dist/worker/midden-worker-contract.d.ts.map +1 -0
- package/dist/worker/midden-worker-contract.js +30 -0
- package/package.json +90 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** structural view of the pieces of a midden-shaped module this worker uses. */
|
|
2
|
+
export interface MiddenBlake3Module {
|
|
3
|
+
hash_blake3?(data: Uint8Array): string;
|
|
4
|
+
Blake3Hasher?: new () => Blake3HasherLike;
|
|
5
|
+
opfs_store_selftest?(): Promise<string> | string;
|
|
6
|
+
opfs_store_selftest_persistence?(): Promise<string> | string;
|
|
7
|
+
}
|
|
8
|
+
/** incremental blake3 hasher, matching the shape midden's wasm bindings expose. */
|
|
9
|
+
export interface Blake3HasherLike {
|
|
10
|
+
update(chunk: Uint8Array): void;
|
|
11
|
+
finalize(): string;
|
|
12
|
+
free(): void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* dynamically load the embedding app's midden module, if one is bundled.
|
|
16
|
+
* resolved once and cached; call `resetMiddenBlake3Cache()` to force a
|
|
17
|
+
* fresh attempt (mainly useful in tests).
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadMiddenBlake3(): Promise<MiddenBlake3Module | null>;
|
|
20
|
+
/** test-only hook: forget the cached resolution so a test can simulate a
|
|
21
|
+
* fresh worker environment with midden present or absent. */
|
|
22
|
+
export declare function resetMiddenBlake3Cache(): void;
|
|
23
|
+
//# sourceMappingURL=midden-blake3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midden-blake3.d.ts","sourceRoot":"","sources":["../../src/worker/midden-blake3.ts"],"names":[],"mappings":"AAyBA,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;IACvC,YAAY,CAAC,EAAE,UAAU,gBAAgB,CAAC;IAC1C,mBAAmB,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACjD,+BAA+B,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC9D;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,QAAQ,IAAI,MAAM,CAAC;IACnB,IAAI,IAAI,IAAI,CAAC;CACd;AAID;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAW3E;AAED;8DAC8D;AAC9D,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// optional blake3 hashing backend for the blob worker.
|
|
2
|
+
//
|
|
3
|
+
// this package does not declare a hard dependency on any specific midden
|
|
4
|
+
// wasm build. blake3 hashing (and the opfs-store selftest hooks used
|
|
5
|
+
// during development) are provided by whatever midden-shaped module the
|
|
6
|
+
// embedding app bundles alongside this worker. the loader below resolves
|
|
7
|
+
// that module dynamically at runtime; every caller degrades gracefully
|
|
8
|
+
// (an empty hash string, or a clearly thrown error where there is no
|
|
9
|
+
// meaningful fallback) when it is not available.
|
|
10
|
+
//
|
|
11
|
+
// the specifier must be a literal string at the `import()` call site, not
|
|
12
|
+
// a variable: bundlers only apply their own alias/resolution config (e.g.
|
|
13
|
+
// vite's `resolve.alias`) to dynamic imports they can statically analyze,
|
|
14
|
+
// and a variable defeats that analysis entirely - the import then falls
|
|
15
|
+
// through to the runtime's native module resolution, which cannot resolve
|
|
16
|
+
// a bare specifier without an import map and fails with "failed to
|
|
17
|
+
// resolve module specifier". `@ts-ignore` (not `@vite-ignore`) is what's
|
|
18
|
+
// needed here: this package never bundles a real "midden" module itself,
|
|
19
|
+
// so typechecking a literal import of it is expected to fail, but the
|
|
20
|
+
// bundler must still see and rewrite the literal specifier.
|
|
21
|
+
import { log } from "../utils/log.js";
|
|
22
|
+
const TAG = "blob.worker.midden";
|
|
23
|
+
let cached;
|
|
24
|
+
/**
|
|
25
|
+
* dynamically load the embedding app's midden module, if one is bundled.
|
|
26
|
+
* resolved once and cached; call `resetMiddenBlake3Cache()` to force a
|
|
27
|
+
* fresh attempt (mainly useful in tests).
|
|
28
|
+
*/
|
|
29
|
+
export async function loadMiddenBlake3() {
|
|
30
|
+
if (cached !== undefined)
|
|
31
|
+
return cached;
|
|
32
|
+
try {
|
|
33
|
+
// @ts-ignore - this package never bundles a real "midden" module; the
|
|
34
|
+
// embedding app aliases the literal specifier below to its own build.
|
|
35
|
+
cached = (await import("midden"));
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
log.warn(TAG, "midden module failed to load, blake3 hashing will degrade:", err);
|
|
39
|
+
cached = null;
|
|
40
|
+
}
|
|
41
|
+
return cached;
|
|
42
|
+
}
|
|
43
|
+
/** test-only hook: forget the cached resolution so a test can simulate a
|
|
44
|
+
* fresh worker environment with midden present or absent. */
|
|
45
|
+
export function resetMiddenBlake3Cache() {
|
|
46
|
+
cached = undefined;
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midden-blake3.test.d.ts","sourceRoot":"","sources":["../../src/worker/midden-blake3.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { loadMiddenBlake3, resetMiddenBlake3Cache } from "./midden-blake3.js";
|
|
3
|
+
afterEach(() => {
|
|
4
|
+
resetMiddenBlake3Cache();
|
|
5
|
+
});
|
|
6
|
+
describe("loadMiddenBlake3", () => {
|
|
7
|
+
it("resolves to null when no midden-shaped module is bundled", async () => {
|
|
8
|
+
const midden = await loadMiddenBlake3();
|
|
9
|
+
expect(midden).toBeNull();
|
|
10
|
+
});
|
|
11
|
+
it("caches the (null) resolution across calls until reset", async () => {
|
|
12
|
+
const first = await loadMiddenBlake3();
|
|
13
|
+
const second = await loadMiddenBlake3();
|
|
14
|
+
expect(first).toBeNull();
|
|
15
|
+
expect(second).toBeNull();
|
|
16
|
+
});
|
|
17
|
+
it("resetMiddenBlake3Cache() allows a fresh resolution attempt", async () => {
|
|
18
|
+
await loadMiddenBlake3();
|
|
19
|
+
resetMiddenBlake3Cache();
|
|
20
|
+
// this just confirms the reset doesn't throw and a subsequent call
|
|
21
|
+
// still resolves cleanly (still null - no midden module in this env).
|
|
22
|
+
const after = await loadMiddenBlake3();
|
|
23
|
+
expect(after).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=midden-not-bundled.stub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midden-not-bundled.stub.d.ts","sourceRoot":"","sources":["../../src/worker/midden-not-bundled.stub.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// test-only stand-in for the "midden" bare specifier that `midden-blake3.ts`
|
|
3
|
+
// dynamically imports. aliased in vitest.config.ts so that import resolves
|
|
4
|
+
// to a real, existing module (satisfying the bundler's static import
|
|
5
|
+
// analysis) instead of failing the transform outright - but this module
|
|
6
|
+
// throws on evaluation, so `loadMiddenBlake3()`'s dynamic import still
|
|
7
|
+
// rejects and is caught the same way it would be in a real embedding app
|
|
8
|
+
// that hasn't aliased "midden" to anything, exercising the genuine
|
|
9
|
+
// "no midden module bundled" degraded-behavior path.
|
|
10
|
+
throw new Error("midden not bundled in this test environment");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class MiddenNode {
|
|
2
|
+
static create(): Promise<MiddenNode>;
|
|
3
|
+
static create_from_key(_key: Uint8Array): Promise<MiddenNode>;
|
|
4
|
+
static create_with_alpns(_key: Uint8Array, _extra_alpns: string[]): Promise<MiddenNode>;
|
|
5
|
+
node_id(): string;
|
|
6
|
+
secret_key(): Uint8Array;
|
|
7
|
+
open_bi(_peer_addr: string, _alpn: string): Promise<never>;
|
|
8
|
+
accept(): Promise<never>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=midden-stub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midden-stub.d.ts","sourceRoot":"","sources":["../../src/worker/midden-stub.ts"],"names":[],"mappings":"AASA,qBAAa,UAAU;WACR,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC;WAI7B,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;WAItD,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7F,OAAO,IAAI,MAAM;IAIjB,UAAU,IAAI,UAAU;IAIlB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAI1D,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC;CAG/B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// stub for midden in builds that don't need its wasm module (e.g. a
|
|
2
|
+
// tauri build, where native code handles iroh/blob work instead).
|
|
3
|
+
//
|
|
4
|
+
// this stub exists so a bundler alias for the "midden" module (e.g. vite's
|
|
5
|
+
// `resolve.alias: { midden: "@freqhole/reliquary/worker" }`) resolves to
|
|
6
|
+
// something during dev/build without requiring a real wasm binary. every
|
|
7
|
+
// method throws - callers in a build that aliases to this stub shouldn't
|
|
8
|
+
// be calling it at all.
|
|
9
|
+
export class MiddenNode {
|
|
10
|
+
static async create() {
|
|
11
|
+
throw new Error("midden wasm is not available in this build");
|
|
12
|
+
}
|
|
13
|
+
static async create_from_key(_key) {
|
|
14
|
+
throw new Error("midden wasm is not available in this build");
|
|
15
|
+
}
|
|
16
|
+
static async create_with_alpns(_key, _extra_alpns) {
|
|
17
|
+
throw new Error("midden wasm is not available in this build");
|
|
18
|
+
}
|
|
19
|
+
node_id() {
|
|
20
|
+
throw new Error("midden wasm is not available in this build");
|
|
21
|
+
}
|
|
22
|
+
secret_key() {
|
|
23
|
+
throw new Error("midden wasm is not available in this build");
|
|
24
|
+
}
|
|
25
|
+
async open_bi(_peer_addr, _alpn) {
|
|
26
|
+
throw new Error("midden wasm is not available in this build");
|
|
27
|
+
}
|
|
28
|
+
async accept() {
|
|
29
|
+
throw new Error("midden wasm is not available in this build");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midden-stub.test.d.ts","sourceRoot":"","sources":["../../src/worker/midden-stub.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { MiddenNode } from "./midden-stub.js";
|
|
3
|
+
// every method on the stub throws - it exists only so a bundler alias for
|
|
4
|
+
// the "midden" module (e.g. in a tauri build with no wasm binary) resolves
|
|
5
|
+
// to something during dev/build. these tests pin down that every method
|
|
6
|
+
// throws a clear, consistent error rather than something more confusing
|
|
7
|
+
// (undefined is not a function, etc.).
|
|
8
|
+
describe("midden stub MiddenNode", () => {
|
|
9
|
+
it("create() rejects", async () => {
|
|
10
|
+
await expect(MiddenNode.create()).rejects.toThrow(/midden wasm is not available/);
|
|
11
|
+
});
|
|
12
|
+
it("create_from_key() rejects", async () => {
|
|
13
|
+
await expect(MiddenNode.create_from_key(new Uint8Array(32))).rejects.toThrow(/midden wasm is not available/);
|
|
14
|
+
});
|
|
15
|
+
it("create_with_alpns() rejects", async () => {
|
|
16
|
+
await expect(MiddenNode.create_with_alpns(new Uint8Array(32), ["alpn/1"])).rejects.toThrow(/midden wasm is not available/);
|
|
17
|
+
});
|
|
18
|
+
it("instance methods all throw", async () => {
|
|
19
|
+
const node = Object.create(MiddenNode.prototype);
|
|
20
|
+
expect(() => node.node_id()).toThrow(/midden wasm is not available/);
|
|
21
|
+
expect(() => node.secret_key()).toThrow(/midden wasm is not available/);
|
|
22
|
+
await expect(node.open_bi("peer", "alpn/1")).rejects.toThrow(/midden wasm is not available/);
|
|
23
|
+
await expect(node.accept()).rejects.toThrow(/midden wasm is not available/);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as Comlink from "comlink";
|
|
2
|
+
import { type MiddenWorkerApi, type StreamInfo } from "./midden-worker-contract.js";
|
|
3
|
+
type Api = Comlink.Remote<MiddenWorkerApi>;
|
|
4
|
+
/** main-thread face of a worker-held BiStream. implements BiStreamLike. */
|
|
5
|
+
export declare class WorkerBiStream {
|
|
6
|
+
private readonly api;
|
|
7
|
+
private readonly info;
|
|
8
|
+
constructor(api: Api, info: StreamInfo);
|
|
9
|
+
peer_node_id(): string;
|
|
10
|
+
alpn(): string;
|
|
11
|
+
read_message(): Promise<Uint8Array | null>;
|
|
12
|
+
write_message(data: Uint8Array): Promise<void>;
|
|
13
|
+
read_to_end(maxSize: number): Promise<Uint8Array>;
|
|
14
|
+
write_raw_and_finish(data: Uint8Array): Promise<void>;
|
|
15
|
+
/** fire-and-forget, matching a wasm BiStream's sync close(). */
|
|
16
|
+
close(): void;
|
|
17
|
+
}
|
|
18
|
+
/** main-thread face of a worker-held ImportSession. `start_import()` stays
|
|
19
|
+
* synchronous (like a wasm ImportSession) by resolving the session id
|
|
20
|
+
* lazily. */
|
|
21
|
+
export declare class WorkerImportSession {
|
|
22
|
+
private readonly api;
|
|
23
|
+
private readonly sessionId;
|
|
24
|
+
constructor(api: Api);
|
|
25
|
+
push(chunk: Uint8Array): Promise<void>;
|
|
26
|
+
finish(): Promise<string>;
|
|
27
|
+
abort(): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* constructs (or otherwise obtains) the Worker instance hosting the midden
|
|
31
|
+
* worker entry. this package doesn't own that entry file (see
|
|
32
|
+
* `midden-worker-contract.ts`), so it can't spawn it via a relative
|
|
33
|
+
* `new Worker(new URL(...))` the way this subpath's own blob worker does -
|
|
34
|
+
* the embedding app supplies this, typically:
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* const node = await WorkerMiddenNode.create(secretKey, () =>
|
|
38
|
+
* new Worker(new URL("./midden-worker.js", import.meta.url), { type: "module" })
|
|
39
|
+
* );
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export type CreateMiddenWorker = () => Worker;
|
|
43
|
+
/**
|
|
44
|
+
* main-thread face of a worker-hosted MiddenNode. same snake_case method
|
|
45
|
+
* names as a wasm node so existing call sites and capability probes
|
|
46
|
+
* (`typeof node.method === "function"`) keep working.
|
|
47
|
+
*
|
|
48
|
+
* sync->async flips vs a wasm node (call sites must be audited/adjusted):
|
|
49
|
+
* - has_active_blob returns a Promise<boolean> (must be awaited)
|
|
50
|
+
* - release_blob / restrict_blob_to_peers / clear_blob_restriction return
|
|
51
|
+
* promises that fire-and-forget callers may ignore
|
|
52
|
+
*/
|
|
53
|
+
export declare class WorkerMiddenNode {
|
|
54
|
+
private readonly api;
|
|
55
|
+
private readonly worker;
|
|
56
|
+
private readonly nodeId;
|
|
57
|
+
private readonly secretKey;
|
|
58
|
+
private constructor();
|
|
59
|
+
/** spawn the worker (via `createWorker`), wait for the ready handshake,
|
|
60
|
+
* create the node. */
|
|
61
|
+
static create(secretKey: Uint8Array | null, createWorker: CreateMiddenWorker): Promise<WorkerMiddenNode>;
|
|
62
|
+
/** tear the worker down (identity delete/import). in-flight calls reject. */
|
|
63
|
+
terminate(): void;
|
|
64
|
+
node_id(): string;
|
|
65
|
+
secret_key(): Uint8Array;
|
|
66
|
+
open_bi(peerAddr: string, alpn: string): Promise<WorkerBiStream>;
|
|
67
|
+
accept(): Promise<WorkerBiStream | null>;
|
|
68
|
+
import_blob(data: Uint8Array): Promise<string>;
|
|
69
|
+
import_blob_and_export_bao(data: Uint8Array): Promise<{
|
|
70
|
+
hash: string;
|
|
71
|
+
bao: Uint8Array;
|
|
72
|
+
}>;
|
|
73
|
+
import_bao(blake3Hash: string, baoData: Uint8Array): Promise<string>;
|
|
74
|
+
/** NOTE: async here (sync on a wasm node) - callers must await. */
|
|
75
|
+
has_active_blob(blake3Hash: string): Promise<boolean>;
|
|
76
|
+
has_complete_blob(blake3Hash: string): Promise<boolean>;
|
|
77
|
+
release_blob(blake3Hash: string): Promise<void>;
|
|
78
|
+
restrict_blob_to_peers(blake3Hash: string, peerNodeIds: string[]): Promise<void>;
|
|
79
|
+
clear_blob_restriction(blake3Hash: string): Promise<void>;
|
|
80
|
+
start_import(): WorkerImportSession;
|
|
81
|
+
ensure_blob(peerAddr: string, blake3Hash: string): Promise<boolean>;
|
|
82
|
+
download_verified_with_ensure(peerAddr: string, blake3Hash: string): Promise<Uint8Array>;
|
|
83
|
+
download_verified_with_ensure_progress(peerAddr: string, blake3Hash: string, totalSize: number, onProgress: (fraction: number) => void, downloadId?: string): Promise<Uint8Array>;
|
|
84
|
+
download_verified_by_id(peerAddr: string, blobId: string): Promise<[Uint8Array, string]>;
|
|
85
|
+
download_verified_by_id_progress(peerAddr: string, blobId: string, totalSize: number, onProgress: (fraction: number) => void): Promise<[Uint8Array, string]>;
|
|
86
|
+
download_verified_streaming_with_ensure(peerAddr: string, blake3Hash: string, totalSize: number, onChunk: (chunk: Uint8Array, offset: number) => void, onProgress: (fraction: number) => void, downloadId?: string): Promise<number>;
|
|
87
|
+
/** pause/cancel an in-flight download by the id passed to the download
|
|
88
|
+
* call. returns false when the download already settled. the partial
|
|
89
|
+
* stays in the persistent store, pinned against gc - a later download
|
|
90
|
+
* of the same hash resumes from the persisted bitfield. */
|
|
91
|
+
download_cancel(downloadId: string): Promise<boolean>;
|
|
92
|
+
/** pin a hash against gc (keep a paused partial alive). */
|
|
93
|
+
protect_blob(blake3Hash: string): Promise<void>;
|
|
94
|
+
/** remove a gc pin added by protect_blob or a cancelled download. */
|
|
95
|
+
unprotect_blob(blake3Hash: string): Promise<void>;
|
|
96
|
+
compute_blake3(peerAddr: string, blobId: string): Promise<string | null>;
|
|
97
|
+
proxy_request(peerAddr: string, method: string, path: string, body?: string | null): Promise<{
|
|
98
|
+
status: number;
|
|
99
|
+
body: string;
|
|
100
|
+
}>;
|
|
101
|
+
}
|
|
102
|
+
export {};
|
|
103
|
+
//# sourceMappingURL=midden-worker-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midden-worker-client.d.ts","sourceRoot":"","sources":["../../src/worker/midden-worker-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// midden-worker-client - main-thread wrapper around a midden worker entry.
|
|
2
|
+
//
|
|
3
|
+
// see `midden-worker-contract.ts` for the full comlink message-shape
|
|
4
|
+
// contract this file codes against. the entry itself lives with whichever
|
|
5
|
+
// app hosts it (its lifecycle is entangled with that app's own boot and
|
|
6
|
+
// identity wiring) - this facade only knows how to talk to it once it's
|
|
7
|
+
// running, so the caller of `WorkerMiddenNode.create()` supplies a factory
|
|
8
|
+
// that constructs the entry's Worker instance.
|
|
9
|
+
//
|
|
10
|
+
// `WorkerMiddenNode` implements the same snake_case surface as a wasm
|
|
11
|
+
// MiddenNode (MiddenNodeLike / MiddenStreamNode), and `WorkerBiStream` /
|
|
12
|
+
// `WorkerImportSession` reconstruct the stateful objects over the entry's
|
|
13
|
+
// flat id-keyed api. call sites - network adapters, protocol handlers,
|
|
14
|
+
// transfer/blob glue, test bridges - keep working unchanged, except for
|
|
15
|
+
// the documented sync->async flips (`has_active_blob`).
|
|
16
|
+
import * as Comlink from "comlink";
|
|
17
|
+
import { MIDDEN_WORKER_READY_MESSAGE, MIDDEN_WORKER_READY_TIMEOUT_MS, } from "./midden-worker-contract.js";
|
|
18
|
+
import { log } from "../utils/log.js";
|
|
19
|
+
const TAG = "midden.worker";
|
|
20
|
+
/** copy a view to an exact-length buffer and mark it for transfer. the
|
|
21
|
+
* copy is required for correctness, not just safety: transferring the
|
|
22
|
+
* caller's own buffer would detach it (callers legitimately reuse their
|
|
23
|
+
* buffers after a send), and a bare structured clone of a subarray view
|
|
24
|
+
* would clone the ENTIRE underlying buffer, not just the view. one exact
|
|
25
|
+
* copy + zero-copy transfer is the cheapest correct option. */
|
|
26
|
+
function toTransferable(bytes) {
|
|
27
|
+
const copy = bytes.slice();
|
|
28
|
+
return Comlink.transfer(copy, [copy.buffer]);
|
|
29
|
+
}
|
|
30
|
+
/** main-thread face of a worker-held BiStream. implements BiStreamLike. */
|
|
31
|
+
export class WorkerBiStream {
|
|
32
|
+
api;
|
|
33
|
+
info;
|
|
34
|
+
constructor(api, info) {
|
|
35
|
+
this.api = api;
|
|
36
|
+
this.info = info;
|
|
37
|
+
}
|
|
38
|
+
peer_node_id() {
|
|
39
|
+
return this.info.peerNodeId;
|
|
40
|
+
}
|
|
41
|
+
alpn() {
|
|
42
|
+
return this.info.alpn;
|
|
43
|
+
}
|
|
44
|
+
async read_message() {
|
|
45
|
+
return this.api.streamReadMessage(this.info.streamId);
|
|
46
|
+
}
|
|
47
|
+
async write_message(data) {
|
|
48
|
+
await this.api.streamWriteMessage(this.info.streamId, toTransferable(data));
|
|
49
|
+
}
|
|
50
|
+
async read_to_end(maxSize) {
|
|
51
|
+
return this.api.streamReadToEnd(this.info.streamId, maxSize);
|
|
52
|
+
}
|
|
53
|
+
async write_raw_and_finish(data) {
|
|
54
|
+
await this.api.streamWriteRawAndFinish(this.info.streamId, toTransferable(data));
|
|
55
|
+
}
|
|
56
|
+
/** fire-and-forget, matching a wasm BiStream's sync close(). */
|
|
57
|
+
close() {
|
|
58
|
+
this.api.streamClose(this.info.streamId).catch(() => {
|
|
59
|
+
// worker gone - nothing to close
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** main-thread face of a worker-held ImportSession. `start_import()` stays
|
|
64
|
+
* synchronous (like a wasm ImportSession) by resolving the session id
|
|
65
|
+
* lazily. */
|
|
66
|
+
export class WorkerImportSession {
|
|
67
|
+
api;
|
|
68
|
+
sessionId;
|
|
69
|
+
constructor(api) {
|
|
70
|
+
this.api = api;
|
|
71
|
+
this.sessionId = api.startImport();
|
|
72
|
+
}
|
|
73
|
+
async push(chunk) {
|
|
74
|
+
const id = await this.sessionId;
|
|
75
|
+
await this.api.importPush(id, toTransferable(chunk));
|
|
76
|
+
}
|
|
77
|
+
async finish() {
|
|
78
|
+
const id = await this.sessionId;
|
|
79
|
+
return this.api.importFinish(id);
|
|
80
|
+
}
|
|
81
|
+
abort() {
|
|
82
|
+
void this.sessionId.then((id) => this.api.importAbort(id)).catch(() => { });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* main-thread face of a worker-hosted MiddenNode. same snake_case method
|
|
87
|
+
* names as a wasm node so existing call sites and capability probes
|
|
88
|
+
* (`typeof node.method === "function"`) keep working.
|
|
89
|
+
*
|
|
90
|
+
* sync->async flips vs a wasm node (call sites must be audited/adjusted):
|
|
91
|
+
* - has_active_blob returns a Promise<boolean> (must be awaited)
|
|
92
|
+
* - release_blob / restrict_blob_to_peers / clear_blob_restriction return
|
|
93
|
+
* promises that fire-and-forget callers may ignore
|
|
94
|
+
*/
|
|
95
|
+
export class WorkerMiddenNode {
|
|
96
|
+
api;
|
|
97
|
+
worker;
|
|
98
|
+
nodeId;
|
|
99
|
+
secretKey;
|
|
100
|
+
constructor(api, worker, nodeId, secretKey) {
|
|
101
|
+
this.api = api;
|
|
102
|
+
this.worker = worker;
|
|
103
|
+
this.nodeId = nodeId;
|
|
104
|
+
this.secretKey = secretKey;
|
|
105
|
+
}
|
|
106
|
+
/** spawn the worker (via `createWorker`), wait for the ready handshake,
|
|
107
|
+
* create the node. */
|
|
108
|
+
static async create(secretKey, createWorker) {
|
|
109
|
+
const worker = createWorker();
|
|
110
|
+
const ready = await new Promise((resolve) => {
|
|
111
|
+
const timeout = setTimeout(() => {
|
|
112
|
+
worker.removeEventListener("message", onMessage);
|
|
113
|
+
worker.removeEventListener("error", onError);
|
|
114
|
+
log.warn(TAG, `worker did not signal ready within ${MIDDEN_WORKER_READY_TIMEOUT_MS}ms`);
|
|
115
|
+
resolve(false);
|
|
116
|
+
}, MIDDEN_WORKER_READY_TIMEOUT_MS);
|
|
117
|
+
const onMessage = (e) => {
|
|
118
|
+
if (e.data !== MIDDEN_WORKER_READY_MESSAGE)
|
|
119
|
+
return;
|
|
120
|
+
clearTimeout(timeout);
|
|
121
|
+
worker.removeEventListener("error", onError);
|
|
122
|
+
worker.removeEventListener("message", onMessage);
|
|
123
|
+
resolve(true);
|
|
124
|
+
};
|
|
125
|
+
// a worker script that fails to load (network error, blocked by a dev
|
|
126
|
+
// server's file-serving restrictions, syntax error, etc.) fires an
|
|
127
|
+
// `error` event, never a `message` - without this listener the promise
|
|
128
|
+
// above would otherwise sit unresolved for the full ready-timeout with
|
|
129
|
+
// no indication anything went wrong.
|
|
130
|
+
const onError = (e) => {
|
|
131
|
+
clearTimeout(timeout);
|
|
132
|
+
worker.removeEventListener("message", onMessage);
|
|
133
|
+
worker.removeEventListener("error", onError);
|
|
134
|
+
log.warn(TAG, "worker failed to load:", e.message || e);
|
|
135
|
+
resolve(false);
|
|
136
|
+
};
|
|
137
|
+
worker.addEventListener("message", onMessage);
|
|
138
|
+
worker.addEventListener("error", onError);
|
|
139
|
+
});
|
|
140
|
+
if (!ready) {
|
|
141
|
+
worker.terminate();
|
|
142
|
+
throw new Error("midden worker did not become ready in time");
|
|
143
|
+
}
|
|
144
|
+
const api = Comlink.wrap(worker);
|
|
145
|
+
try {
|
|
146
|
+
const identity = await api.init(secretKey);
|
|
147
|
+
log.debug(TAG, "worker node ready:", identity.nodeId.slice(0, 16) + "...");
|
|
148
|
+
return new WorkerMiddenNode(api, worker, identity.nodeId, identity.secretKey);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
worker.terminate();
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** tear the worker down (identity delete/import). in-flight calls reject. */
|
|
156
|
+
terminate() {
|
|
157
|
+
this.worker.terminate();
|
|
158
|
+
}
|
|
159
|
+
// ---- identity (sync, cached at init) ----
|
|
160
|
+
node_id() {
|
|
161
|
+
return this.nodeId;
|
|
162
|
+
}
|
|
163
|
+
secret_key() {
|
|
164
|
+
return this.secretKey;
|
|
165
|
+
}
|
|
166
|
+
// ---- streams ----
|
|
167
|
+
async open_bi(peerAddr, alpn) {
|
|
168
|
+
return new WorkerBiStream(this.api, await this.api.openBi(peerAddr, alpn));
|
|
169
|
+
}
|
|
170
|
+
async accept() {
|
|
171
|
+
const info = await this.api.accept();
|
|
172
|
+
if (!info)
|
|
173
|
+
return null;
|
|
174
|
+
return new WorkerBiStream(this.api, info);
|
|
175
|
+
}
|
|
176
|
+
// ---- blob store ----
|
|
177
|
+
async import_blob(data) {
|
|
178
|
+
return this.api.importBlob(toTransferable(data));
|
|
179
|
+
}
|
|
180
|
+
async import_blob_and_export_bao(data) {
|
|
181
|
+
return this.api.importBlobAndExportBao(toTransferable(data));
|
|
182
|
+
}
|
|
183
|
+
async import_bao(blake3Hash, baoData) {
|
|
184
|
+
return this.api.importBao(blake3Hash, toTransferable(baoData));
|
|
185
|
+
}
|
|
186
|
+
/** NOTE: async here (sync on a wasm node) - callers must await. */
|
|
187
|
+
has_active_blob(blake3Hash) {
|
|
188
|
+
return this.api.hasActiveBlob(blake3Hash);
|
|
189
|
+
}
|
|
190
|
+
has_complete_blob(blake3Hash) {
|
|
191
|
+
return this.api.hasCompleteBlob(blake3Hash);
|
|
192
|
+
}
|
|
193
|
+
release_blob(blake3Hash) {
|
|
194
|
+
return this.api.releaseBlob(blake3Hash);
|
|
195
|
+
}
|
|
196
|
+
restrict_blob_to_peers(blake3Hash, peerNodeIds) {
|
|
197
|
+
return this.api.restrictBlobToPeers(blake3Hash, peerNodeIds);
|
|
198
|
+
}
|
|
199
|
+
clear_blob_restriction(blake3Hash) {
|
|
200
|
+
return this.api.clearBlobRestriction(blake3Hash);
|
|
201
|
+
}
|
|
202
|
+
start_import() {
|
|
203
|
+
return new WorkerImportSession(this.api);
|
|
204
|
+
}
|
|
205
|
+
// ---- downloads ----
|
|
206
|
+
async ensure_blob(peerAddr, blake3Hash) {
|
|
207
|
+
return this.api.ensureBlob(peerAddr, blake3Hash);
|
|
208
|
+
}
|
|
209
|
+
async download_verified_with_ensure(peerAddr, blake3Hash) {
|
|
210
|
+
return this.api.downloadVerifiedWithEnsure(peerAddr, blake3Hash);
|
|
211
|
+
}
|
|
212
|
+
async download_verified_with_ensure_progress(peerAddr, blake3Hash, totalSize, onProgress, downloadId) {
|
|
213
|
+
return this.api.downloadVerifiedWithEnsureProgress(peerAddr, blake3Hash, totalSize, Comlink.proxy(onProgress), downloadId);
|
|
214
|
+
}
|
|
215
|
+
async download_verified_by_id(peerAddr, blobId) {
|
|
216
|
+
return this.api.downloadVerifiedById(peerAddr, blobId);
|
|
217
|
+
}
|
|
218
|
+
async download_verified_by_id_progress(peerAddr, blobId, totalSize, onProgress) {
|
|
219
|
+
return this.api.downloadVerifiedByIdProgress(peerAddr, blobId, totalSize, Comlink.proxy(onProgress));
|
|
220
|
+
}
|
|
221
|
+
async download_verified_streaming_with_ensure(peerAddr, blake3Hash, totalSize, onChunk, onProgress, downloadId) {
|
|
222
|
+
return this.api.downloadVerifiedStreamingWithEnsure(peerAddr, blake3Hash, totalSize, Comlink.proxy(onChunk), Comlink.proxy(onProgress), downloadId);
|
|
223
|
+
}
|
|
224
|
+
/** pause/cancel an in-flight download by the id passed to the download
|
|
225
|
+
* call. returns false when the download already settled. the partial
|
|
226
|
+
* stays in the persistent store, pinned against gc - a later download
|
|
227
|
+
* of the same hash resumes from the persisted bitfield. */
|
|
228
|
+
async download_cancel(downloadId) {
|
|
229
|
+
return this.api.downloadCancel(downloadId);
|
|
230
|
+
}
|
|
231
|
+
/** pin a hash against gc (keep a paused partial alive). */
|
|
232
|
+
async protect_blob(blake3Hash) {
|
|
233
|
+
return this.api.protectBlob(blake3Hash);
|
|
234
|
+
}
|
|
235
|
+
/** remove a gc pin added by protect_blob or a cancelled download. */
|
|
236
|
+
async unprotect_blob(blake3Hash) {
|
|
237
|
+
return this.api.unprotectBlob(blake3Hash);
|
|
238
|
+
}
|
|
239
|
+
async compute_blake3(peerAddr, blobId) {
|
|
240
|
+
return this.api.computeBlake3(peerAddr, blobId);
|
|
241
|
+
}
|
|
242
|
+
// ---- proxy requests ----
|
|
243
|
+
async proxy_request(peerAddr, method, path, body) {
|
|
244
|
+
return this.api.proxyRequest(peerAddr, method, path, body ?? null);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midden-worker-client.test.d.ts","sourceRoot":"","sources":["../../src/worker/midden-worker-client.test.ts"],"names":[],"mappings":""}
|