@amalgm/live 0.2.47 → 0.2.48
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.
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Download
|
|
2
|
+
* Download a set of immutable artifacts into a machine cache.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The set is the primitive: one plan wave proves every manifest and asks the
|
|
5
|
+
* cache which chunks are gaps, one chunk wave fetches every gap across the
|
|
6
|
+
* whole set under a single bound, and one seal wave verifies each complete
|
|
7
|
+
* artifact. A lone artifact is a set of one — there is no second path. This
|
|
8
|
+
* shape removes per-artifact serialization: no artifact waits behind
|
|
9
|
+
* another's plan or seal, only behind the shared fetch bound. Each chunk is
|
|
10
|
+
* still its own storage request — the set changes scheduling, not the
|
|
11
|
+
* request count.
|
|
8
12
|
*
|
|
9
13
|
* Every chunk is one content-addressed storage object, so the host's ports
|
|
10
14
|
* fetch chunks independently — parallelism, transport, and decryption are the
|
|
@@ -38,6 +42,10 @@ export interface DownloadReceipt<LocalArtifact> {
|
|
|
38
42
|
readonly downloadedChunks: number;
|
|
39
43
|
readonly reusedChunks: number;
|
|
40
44
|
}
|
|
41
|
-
/** Download
|
|
45
|
+
/** Download a set of immutable artifacts, fetching only machine-cache gaps.
|
|
46
|
+
* Receipts return in input order; any failure fails the whole set after
|
|
47
|
+
* letting in-flight effects settle. */
|
|
48
|
+
export declare function downloadAll<LocalArtifact>(artifacts: readonly TransferArtifact[], ports: DownloadPorts<LocalArtifact>, options?: DownloadOptions): Promise<readonly DownloadReceipt<LocalArtifact>[]>;
|
|
49
|
+
/** Download one immutable artifact — a set of one. */
|
|
42
50
|
export declare function download<LocalArtifact>(artifact: TransferArtifact, ports: DownloadPorts<LocalArtifact>, options?: DownloadOptions): Promise<DownloadReceipt<LocalArtifact>>;
|
|
43
51
|
//# sourceMappingURL=download.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/transfer/download.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/transfer/download.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAG/E,MAAM,WAAW,aAAa,CAAC,aAAa;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,6EAA6E;IAC7E,QAAQ,CACN,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,QAAQ,CACN,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB,QAAQ,CACN,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,8EAA8E;IAC9E,YAAY,CACV,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,cAAc,CAAC,aAAa;IAC3C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe,CAAC,aAAa;IAC5C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAQD;;uCAEuC;AACvC,wBAAsB,WAAW,CAAC,aAAa,EAC7C,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,EACnC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,SAAS,eAAe,CAAC,aAAa,CAAC,EAAE,CAAC,CAuDpD;AAED,sDAAsD;AACtD,wBAAsB,QAAQ,CAAC,aAAa,EAC1C,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,EACnC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAIzC"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Download
|
|
2
|
+
* Download a set of immutable artifacts into a machine cache.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The set is the primitive: one plan wave proves every manifest and asks the
|
|
5
|
+
* cache which chunks are gaps, one chunk wave fetches every gap across the
|
|
6
|
+
* whole set under a single bound, and one seal wave verifies each complete
|
|
7
|
+
* artifact. A lone artifact is a set of one — there is no second path. This
|
|
8
|
+
* shape removes per-artifact serialization: no artifact waits behind
|
|
9
|
+
* another's plan or seal, only behind the shared fetch bound. Each chunk is
|
|
10
|
+
* still its own storage request — the set changes scheduling, not the
|
|
11
|
+
* request count.
|
|
8
12
|
*
|
|
9
13
|
* Every chunk is one content-addressed storage object, so the host's ports
|
|
10
14
|
* fetch chunks independently — parallelism, transport, and decryption are the
|
|
@@ -13,40 +17,70 @@
|
|
|
13
17
|
import { checkContentManifest } from '../contracts/content.js';
|
|
14
18
|
import { assertTransferArtifact } from './artifacts.js';
|
|
15
19
|
import { DEFAULT_TRANSFER_CONCURRENCY, parallelForEach } from './parallel.js';
|
|
16
|
-
/** Download
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
/** Download a set of immutable artifacts, fetching only machine-cache gaps.
|
|
21
|
+
* Receipts return in input order; any failure fails the whole set after
|
|
22
|
+
* letting in-flight effects settle. */
|
|
23
|
+
export async function downloadAll(artifacts, ports, options = {}) {
|
|
24
|
+
const concurrency = options.concurrency ?? DEFAULT_TRANSFER_CONCURRENCY;
|
|
25
|
+
for (const artifact of artifacts)
|
|
26
|
+
assertTransferArtifact(artifact);
|
|
27
|
+
const plans = new Array(artifacts.length);
|
|
28
|
+
await parallelForEach([...artifacts.keys()], concurrency, async (slot) => {
|
|
29
|
+
const artifact = artifacts[slot];
|
|
30
|
+
if (artifact === undefined)
|
|
31
|
+
return;
|
|
32
|
+
const checked = checkContentManifest(await ports.getManifest(artifact), artifact.contentHash);
|
|
33
|
+
if (!checked.ok)
|
|
34
|
+
throw new Error(checked.error);
|
|
35
|
+
const manifest = checked.value;
|
|
36
|
+
const missing = [];
|
|
37
|
+
for (const index of manifest.chunks.keys()) {
|
|
38
|
+
if (!await ports.hasChunk(artifact, manifest, index))
|
|
39
|
+
missing.push(index);
|
|
40
|
+
}
|
|
41
|
+
plans[slot] = { artifact, manifest, missing };
|
|
42
|
+
});
|
|
43
|
+
const gaps = plans.flatMap((plan) => plan === undefined ? [] : plan.missing.map((index) => ({ plan, index })));
|
|
44
|
+
await parallelForEach(gaps, concurrency, async ({ plan, index }) => {
|
|
45
|
+
const expected = plan.manifest.chunks[index];
|
|
30
46
|
if (expected === undefined)
|
|
31
47
|
throw new Error('download manifest named an unknown chunk index');
|
|
32
|
-
const bytes = await ports.getChunk(artifact, manifest, index);
|
|
48
|
+
const bytes = await ports.getChunk(plan.artifact, plan.manifest, index);
|
|
33
49
|
if (!(bytes instanceof Uint8Array)
|
|
34
50
|
|| bytes.byteLength !== expected.bytes
|
|
35
51
|
|| ports.sha256Hex(bytes) !== expected.sha256) {
|
|
36
52
|
throw new Error(`downloaded content chunk ${index} failed verification`);
|
|
37
53
|
}
|
|
38
|
-
await ports.putChunk(artifact, manifest, index, bytes);
|
|
54
|
+
await ports.putChunk(plan.artifact, plan.manifest, index, bytes);
|
|
55
|
+
});
|
|
56
|
+
const receipts = new Array(artifacts.length);
|
|
57
|
+
await parallelForEach([...plans.keys()], concurrency, async (slot) => {
|
|
58
|
+
const plan = plans[slot];
|
|
59
|
+
if (plan === undefined)
|
|
60
|
+
return;
|
|
61
|
+
const sealed = await ports.sealArtifact(plan.artifact, plan.manifest);
|
|
62
|
+
if (sealed.bytes !== plan.manifest.bytes || sealed.contentHash !== plan.manifest.contentHash) {
|
|
63
|
+
throw new Error(`downloaded artifact ${plan.artifact.contentHash} failed verification`);
|
|
64
|
+
}
|
|
65
|
+
receipts[slot] = {
|
|
66
|
+
artifact: plan.artifact,
|
|
67
|
+
manifest: plan.manifest,
|
|
68
|
+
local: sealed.local,
|
|
69
|
+
downloadedChunks: plan.missing.length,
|
|
70
|
+
reusedChunks: plan.manifest.chunks.length - plan.missing.length,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
return receipts.map((receipt) => {
|
|
74
|
+
if (receipt === undefined)
|
|
75
|
+
throw new Error('download set lost an artifact receipt');
|
|
76
|
+
return receipt;
|
|
39
77
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
artifact
|
|
46
|
-
|
|
47
|
-
local: sealed.local,
|
|
48
|
-
downloadedChunks: missing.length,
|
|
49
|
-
reusedChunks: manifest.chunks.length - missing.length,
|
|
50
|
-
};
|
|
78
|
+
}
|
|
79
|
+
/** Download one immutable artifact — a set of one. */
|
|
80
|
+
export async function download(artifact, ports, options = {}) {
|
|
81
|
+
const [receipt] = await downloadAll([artifact], ports, options);
|
|
82
|
+
if (receipt === undefined)
|
|
83
|
+
throw new Error('download set lost an artifact receipt');
|
|
84
|
+
return receipt;
|
|
51
85
|
}
|
|
52
86
|
//# sourceMappingURL=download.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/transfer/download.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/transfer/download.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,55 +1,90 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Download
|
|
3
|
+
* Download a set of immutable artifacts into a machine cache.
|
|
4
4
|
*
|
|
5
|
-
* The
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* The set is the primitive: one plan wave proves every manifest and asks the
|
|
6
|
+
* cache which chunks are gaps, one chunk wave fetches every gap across the
|
|
7
|
+
* whole set under a single bound, and one seal wave verifies each complete
|
|
8
|
+
* artifact. A lone artifact is a set of one — there is no second path. This
|
|
9
|
+
* shape removes per-artifact serialization: no artifact waits behind
|
|
10
|
+
* another's plan or seal, only behind the shared fetch bound. Each chunk is
|
|
11
|
+
* still its own storage request — the set changes scheduling, not the
|
|
12
|
+
* request count.
|
|
9
13
|
*
|
|
10
14
|
* Every chunk is one content-addressed storage object, so the host's ports
|
|
11
15
|
* fetch chunks independently — parallelism, transport, and decryption are the
|
|
12
16
|
* host's concern; the verification laws here are not.
|
|
13
17
|
*/
|
|
14
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.downloadAll = downloadAll;
|
|
15
20
|
exports.download = download;
|
|
16
21
|
const content_js_1 = require("../contracts/content.js");
|
|
17
22
|
const artifacts_js_1 = require("./artifacts.js");
|
|
18
23
|
const parallel_js_1 = require("./parallel.js");
|
|
19
|
-
/** Download
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
/** Download a set of immutable artifacts, fetching only machine-cache gaps.
|
|
25
|
+
* Receipts return in input order; any failure fails the whole set after
|
|
26
|
+
* letting in-flight effects settle. */
|
|
27
|
+
async function downloadAll(artifacts, ports, options = {}) {
|
|
28
|
+
const concurrency = options.concurrency ?? parallel_js_1.DEFAULT_TRANSFER_CONCURRENCY;
|
|
29
|
+
for (const artifact of artifacts)
|
|
30
|
+
(0, artifacts_js_1.assertTransferArtifact)(artifact);
|
|
31
|
+
const plans = new Array(artifacts.length);
|
|
32
|
+
await (0, parallel_js_1.parallelForEach)([...artifacts.keys()], concurrency, async (slot) => {
|
|
33
|
+
const artifact = artifacts[slot];
|
|
34
|
+
if (artifact === undefined)
|
|
35
|
+
return;
|
|
36
|
+
const checked = (0, content_js_1.checkContentManifest)(await ports.getManifest(artifact), artifact.contentHash);
|
|
37
|
+
if (!checked.ok)
|
|
38
|
+
throw new Error(checked.error);
|
|
39
|
+
const manifest = checked.value;
|
|
40
|
+
const missing = [];
|
|
41
|
+
for (const index of manifest.chunks.keys()) {
|
|
42
|
+
if (!await ports.hasChunk(artifact, manifest, index))
|
|
43
|
+
missing.push(index);
|
|
44
|
+
}
|
|
45
|
+
plans[slot] = { artifact, manifest, missing };
|
|
46
|
+
});
|
|
47
|
+
const gaps = plans.flatMap((plan) => plan === undefined ? [] : plan.missing.map((index) => ({ plan, index })));
|
|
48
|
+
await (0, parallel_js_1.parallelForEach)(gaps, concurrency, async ({ plan, index }) => {
|
|
49
|
+
const expected = plan.manifest.chunks[index];
|
|
33
50
|
if (expected === undefined)
|
|
34
51
|
throw new Error('download manifest named an unknown chunk index');
|
|
35
|
-
const bytes = await ports.getChunk(artifact, manifest, index);
|
|
52
|
+
const bytes = await ports.getChunk(plan.artifact, plan.manifest, index);
|
|
36
53
|
if (!(bytes instanceof Uint8Array)
|
|
37
54
|
|| bytes.byteLength !== expected.bytes
|
|
38
55
|
|| ports.sha256Hex(bytes) !== expected.sha256) {
|
|
39
56
|
throw new Error(`downloaded content chunk ${index} failed verification`);
|
|
40
57
|
}
|
|
41
|
-
await ports.putChunk(artifact, manifest, index, bytes);
|
|
58
|
+
await ports.putChunk(plan.artifact, plan.manifest, index, bytes);
|
|
59
|
+
});
|
|
60
|
+
const receipts = new Array(artifacts.length);
|
|
61
|
+
await (0, parallel_js_1.parallelForEach)([...plans.keys()], concurrency, async (slot) => {
|
|
62
|
+
const plan = plans[slot];
|
|
63
|
+
if (plan === undefined)
|
|
64
|
+
return;
|
|
65
|
+
const sealed = await ports.sealArtifact(plan.artifact, plan.manifest);
|
|
66
|
+
if (sealed.bytes !== plan.manifest.bytes || sealed.contentHash !== plan.manifest.contentHash) {
|
|
67
|
+
throw new Error(`downloaded artifact ${plan.artifact.contentHash} failed verification`);
|
|
68
|
+
}
|
|
69
|
+
receipts[slot] = {
|
|
70
|
+
artifact: plan.artifact,
|
|
71
|
+
manifest: plan.manifest,
|
|
72
|
+
local: sealed.local,
|
|
73
|
+
downloadedChunks: plan.missing.length,
|
|
74
|
+
reusedChunks: plan.manifest.chunks.length - plan.missing.length,
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
return receipts.map((receipt) => {
|
|
78
|
+
if (receipt === undefined)
|
|
79
|
+
throw new Error('download set lost an artifact receipt');
|
|
80
|
+
return receipt;
|
|
42
81
|
});
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
artifact
|
|
49
|
-
|
|
50
|
-
local: sealed.local,
|
|
51
|
-
downloadedChunks: missing.length,
|
|
52
|
-
reusedChunks: manifest.chunks.length - missing.length,
|
|
53
|
-
};
|
|
82
|
+
}
|
|
83
|
+
/** Download one immutable artifact — a set of one. */
|
|
84
|
+
async function download(artifact, ports, options = {}) {
|
|
85
|
+
const [receipt] = await downloadAll([artifact], ports, options);
|
|
86
|
+
if (receipt === undefined)
|
|
87
|
+
throw new Error('download set lost an artifact receipt');
|
|
88
|
+
return receipt;
|
|
54
89
|
}
|
|
55
90
|
//# sourceMappingURL=download.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/transfer/download.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/transfer/download.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amalgm/live",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.48",
|
|
4
4
|
"description": "Portable realtime SDK for Amalgm — wire contracts, mutation discipline, and delivery state machines behind host-injected adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist-cjs/index.js",
|