@amalgm/live 0.2.59 → 0.2.60

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,31 +1,232 @@
1
1
  /**
2
2
  * Download a set of immutable artifacts into a machine cache.
3
3
  *
4
- * The set is the primitive: one plan phase proves every manifest and asks the
5
- * cache which chunks are gaps, one fetch phase obtains every gap across the
6
- * whole set under a single bound, and one seal phase 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.
4
+ * The set is the primitive and the plan is physical. Wave one proves every
5
+ * manifest: locally held ones are checked in place, missing ones are
6
+ * resolved as one want-list and fetched grouped by the pack that holds
7
+ * them. Wave two reads the proven manifests, asks the cache which chunks
8
+ * are gaps, resolves the whole gap list, and fetches it the same way: all
9
+ * members of one pack collapse into a few broad byte spans approximately
10
+ * one read per packwhile standalone objects remain one read each. A
11
+ * lone artifact is a set of one; there is no second download path.
12
12
  *
13
- * Fetches complete in whatever order the network answers, but each artifact
13
+ * Spans complete in whatever order storage answers, but each artifact
14
14
  * stores its chunks in chunk order: a verified chunk waits until every
15
- * earlier gap of the same artifact has been stored. Gaps are admitted round
16
- * robin across artifacts, so one large artifact cannot occupy the whole
17
- * window while unrelated work waits. Held bytes stay inside the in-flight
18
- * byte bound.
15
+ * earlier gap of the same artifact is stored, so a host assembling a
16
+ * whole-file digest never re-reads what landed early. The scheduler admits
17
+ * fetch units strictly in fair plan order, and the plan orders units so a
18
+ * chunk's predecessor always lives in the same or an earlier unit — an
19
+ * artifact whose gaps do not line up ascending inside one pack falls back
20
+ * to per-object reads at its own positions — so ordered stores can never
21
+ * deadlock. Chains enter the plan round-robin by depth, so one multi-chunk
22
+ * artifact cannot monopolize the bounded window while unrelated artifacts
23
+ * wait. In-flight span bytes stay inside one explicit bound; raising request
24
+ * concurrency never silently raises memory.
19
25
  *
20
- * Every chunk keeps one content-addressed identity, whether its sealed
21
- * envelope lives alone or as a byte range inside an immutable pack. The
22
- * host's ports resolve and fetch those identities; parallelism, storage
23
- * layout, transport, and decryption are the host's concern, while the
24
- * verification laws here remain singular.
26
+ * Every object keeps one content-addressed identity whether its sealed
27
+ * envelope lives alone or as a byte range inside an immutable pack, and
28
+ * placement is immutable: a retried read may refresh its URL but never its
29
+ * geometry. Wrong or shifted bytes cannot leak every dispensed slice is
30
+ * still an authenticated envelope the host opens and this engine
31
+ * hash-verifies before a single byte is stored.
25
32
  */
26
33
  import { CHUNK_BYTES, checkContentManifest } from '../contracts/content.js';
27
34
  import { assertTransferArtifact } from './artifacts.js';
28
35
  import { DEFAULT_TRANSFER_CONCURRENCY, parallelForEach, weightedParallelForEach, } from './parallel.js';
36
+ import { planPackSpans, RANGE_MERGE_GAP_BYTES } from './ranges.js';
37
+ import { resolveContentRefs } from './refs.js';
38
+ function checkRefLocation(ref, object) {
39
+ if (ref === undefined || typeof ref.url !== 'string' || ref.url.length === 0) {
40
+ throw new Error(`content ref for ${object.kind} ${object.sha256} named no location`);
41
+ }
42
+ if ((ref.offset === undefined) !== (ref.length === undefined)) {
43
+ throw new Error(`content ref for ${object.kind} ${object.sha256} named half a byte range`);
44
+ }
45
+ if (ref.offset === undefined || ref.length === undefined)
46
+ return { url: ref.url, span: null };
47
+ if (!Number.isSafeInteger(ref.offset) || ref.offset < 0
48
+ || !Number.isSafeInteger(ref.length) || ref.length < 1) {
49
+ throw new Error(`content ref for ${object.kind} ${object.sha256} named an invalid byte range`);
50
+ }
51
+ return { url: ref.url, span: { offset: ref.offset, length: ref.length } };
52
+ }
53
+ /** Resolve one wave's want-list and fetch it as planned units: pack members
54
+ * as broad spans, standalone objects whole. Deadlock-frame law: dependencies
55
+ * only run backward along a chain, chains join pack grouping only when their
56
+ * refs ascend inside one pack, a pack's spans stay contiguous in ascending
57
+ * offset order, and admission is strictly FIFO — so a chunk's predecessor is
58
+ * always in the same unit earlier, or in an already-admitted one. */
59
+ async function fetchWave(ports, chains, concurrency, maxInFlightBytes) {
60
+ // Fair admission is part of the set law: take one dependency depth from
61
+ // every artifact before taking the next. This preserves predecessor-first
62
+ // ordering within each chain without letting one large artifact occupy the
63
+ // whole byte window while unrelated work waits.
64
+ const flat = [];
65
+ const maxDepth = chains.reduce((maximum, chain) => Math.max(maximum, chain.length), 0);
66
+ for (let depth = 0; depth < maxDepth; depth += 1) {
67
+ chains.forEach((items, chain) => {
68
+ const item = items[depth];
69
+ if (item !== undefined)
70
+ flat.push({ chain, item });
71
+ });
72
+ }
73
+ if (flat.length === 0)
74
+ return { rangedReads: 0, packedObjects: 0, standaloneObjects: 0 };
75
+ const refs = await resolveContentRefs(ports, flat.map(({ item }) => item.object));
76
+ const byChain = chains.map(() => []);
77
+ flat.forEach(({ chain, item }, order) => {
78
+ const members = byChain[chain];
79
+ if (members === undefined)
80
+ throw new Error('download wave lost a chain');
81
+ members.push({ item, order, ...checkRefLocation(refs[order], item.object) });
82
+ });
83
+ // A chain rides pack grouping only when every gap sits in one pack with
84
+ // non-descending offsets; anything else falls back to per-object reads so
85
+ // store order can never depend on a later fetch unit.
86
+ const groups = new Map();
87
+ const singles = [];
88
+ for (const chain of byChain) {
89
+ const first = chain[0];
90
+ if (first === undefined)
91
+ continue;
92
+ const coherent = chain.every((member, index) => {
93
+ if (member.span === null || member.url !== first.url)
94
+ return false;
95
+ const previous = chain[index - 1];
96
+ return previous?.span == null || member.span.offset >= previous.span.offset;
97
+ });
98
+ if (!coherent) {
99
+ singles.push(...chain);
100
+ continue;
101
+ }
102
+ const members = groups.get(first.url);
103
+ if (members === undefined)
104
+ groups.set(first.url, [...chain]);
105
+ else
106
+ members.push(...chain);
107
+ }
108
+ const units = [];
109
+ let packedObjects = 0;
110
+ let standaloneObjects = 0;
111
+ for (const members of groups.values()) {
112
+ packedObjects += members.length;
113
+ members.sort((a, b) => (a.span?.offset ?? 0) - (b.span?.offset ?? 0) || a.order - b.order);
114
+ const spans = members.map((member) => {
115
+ if (member.span === null)
116
+ throw new Error('download wave grouped a standalone object');
117
+ return member.span;
118
+ });
119
+ const plan = planPackSpans(spans, RANGE_MERGE_GAP_BYTES, maxInFlightBytes);
120
+ const perSpan = plan.spans.map(() => []);
121
+ members.forEach((member, index) => {
122
+ const spanIndex = plan.memberSpan[index];
123
+ const list = spanIndex === undefined ? undefined : perSpan[spanIndex];
124
+ if (list === undefined)
125
+ throw new Error('download wave lost a span member');
126
+ list.push(member);
127
+ });
128
+ const primary = members.reduce((least, member) => Math.min(least, member.order), Number.MAX_SAFE_INTEGER);
129
+ plan.spans.forEach((span, index) => {
130
+ const list = perSpan[index];
131
+ const anchor = list?.[0];
132
+ if (list === undefined || anchor === undefined) {
133
+ throw new Error('download wave planned an empty span');
134
+ }
135
+ units.push({
136
+ url: anchor.url,
137
+ span,
138
+ members: list.map((member) => {
139
+ if (member.span === null)
140
+ throw new Error('download wave grouped a standalone object');
141
+ return {
142
+ item: member.item,
143
+ offset: member.span.offset - span.offset,
144
+ length: member.span.length,
145
+ };
146
+ }),
147
+ refresh: anchor,
148
+ weight: Math.min(span.length, maxInFlightBytes),
149
+ primary,
150
+ secondary: index,
151
+ ranged: true,
152
+ });
153
+ });
154
+ }
155
+ for (const member of singles) {
156
+ if (member.span !== null) {
157
+ packedObjects += 1;
158
+ units.push({
159
+ url: member.url,
160
+ span: member.span,
161
+ members: [{ item: member.item, offset: 0, length: member.span.length }],
162
+ refresh: member,
163
+ weight: Math.min(member.span.length, maxInFlightBytes),
164
+ primary: member.order,
165
+ secondary: 0,
166
+ ranged: true,
167
+ });
168
+ }
169
+ else {
170
+ standaloneObjects += 1;
171
+ units.push({
172
+ url: member.url,
173
+ span: null,
174
+ members: [{ item: member.item, offset: 0, length: null }],
175
+ refresh: member,
176
+ weight: Math.max(1, Math.min(member.item.standaloneWeight, maxInFlightBytes)),
177
+ primary: member.order,
178
+ secondary: 0,
179
+ ranged: false,
180
+ });
181
+ }
182
+ }
183
+ units.sort((a, b) => a.primary - b.primary || a.secondary - b.secondary);
184
+ await weightedParallelForEach(units, concurrency, maxInFlightBytes, (unit) => unit.weight, async (unit) => {
185
+ let delivered = 0;
186
+ try {
187
+ const refresh = async () => {
188
+ const [fresh] = await ports.requestRefs([unit.refresh.item.object]);
189
+ const location = checkRefLocation(fresh, unit.refresh.item.object);
190
+ const before = unit.refresh.span;
191
+ const moved = (location.span === null) !== (before === null)
192
+ || (location.span !== null && before !== null
193
+ && (location.span.offset !== before.offset
194
+ || location.span.length !== before.length));
195
+ if (moved) {
196
+ throw new Error(`content ${unit.refresh.item.object.kind} `
197
+ + `${unit.refresh.item.object.sha256} changed placement between fetch attempts`);
198
+ }
199
+ return location.url;
200
+ };
201
+ const bytes = await ports.fetchSpan(unit.url, unit.span, refresh);
202
+ if (!(bytes instanceof Uint8Array))
203
+ throw new Error('storage fetch answered no bytes');
204
+ if (unit.span !== null && bytes.byteLength !== unit.span.length) {
205
+ throw new Error('storage fetch answered the wrong byte count');
206
+ }
207
+ for (const member of unit.members) {
208
+ const sealed = member.length === null
209
+ ? bytes
210
+ : bytes.subarray(member.offset, member.offset + member.length);
211
+ if (member.length !== null && sealed.byteLength !== member.length) {
212
+ throw new Error('storage span cannot cover a planned member');
213
+ }
214
+ await member.item.deliver(sealed);
215
+ delivered += 1;
216
+ }
217
+ }
218
+ catch (error) {
219
+ for (const member of unit.members.slice(delivered))
220
+ member.item.fail(error);
221
+ throw error;
222
+ }
223
+ });
224
+ return {
225
+ rangedReads: units.reduce((count, unit) => count + (unit.ranged ? 1 : 0), 0),
226
+ packedObjects,
227
+ standaloneObjects,
228
+ };
229
+ }
29
230
  /** Download a set of immutable artifacts, fetching only machine-cache gaps.
30
231
  * Receipts return in input order; any failure fails the whole set after
31
232
  * letting in-flight effects settle. */
@@ -35,94 +236,148 @@ export async function downloadAll(artifacts, ports, options = {}) {
35
236
  ?? DEFAULT_TRANSFER_CONCURRENCY * CHUNK_BYTES;
36
237
  for (const artifact of artifacts)
37
238
  assertTransferArtifact(artifact);
38
- const plans = new Array(artifacts.length);
239
+ // Wave one: prove every manifest. Held manifests are checked in place;
240
+ // missing ones fetch as one planned wave grouped by pack.
241
+ const manifests = new Array(artifacts.length);
242
+ let localManifests = 0;
243
+ const manifestChains = [];
244
+ artifacts.forEach((artifact, slot) => {
245
+ const local = ports.localManifest(artifact);
246
+ if (local !== null && local !== undefined) {
247
+ const checked = checkContentManifest(local, artifact.contentHash);
248
+ if (!checked.ok)
249
+ throw new Error(checked.error);
250
+ manifests[slot] = checked.value;
251
+ localManifests += 1;
252
+ return;
253
+ }
254
+ const object = { kind: 'manifest', sha256: artifact.contentHash };
255
+ manifestChains.push([{
256
+ object,
257
+ standaloneWeight: 1,
258
+ deliver: async (sealed) => {
259
+ const plain = await ports.openEnvelope(object, sealed);
260
+ let parsed;
261
+ try {
262
+ parsed = JSON.parse(new TextDecoder().decode(plain));
263
+ }
264
+ catch {
265
+ throw new Error(`downloaded manifest for ${artifact.contentHash} is not valid JSON`);
266
+ }
267
+ const checked = checkContentManifest(parsed, artifact.contentHash);
268
+ if (!checked.ok)
269
+ throw new Error(checked.error);
270
+ manifests[slot] = checked.value;
271
+ await ports.manifestProven(artifact, checked.value);
272
+ },
273
+ fail: () => { },
274
+ }]);
275
+ });
276
+ const manifestWave = await fetchWave(ports, manifestChains, concurrency, maxInFlightBytes);
277
+ // Ask the cache which chunks are gaps, now that every manifest is proven.
278
+ const gaps = new Array(artifacts.length);
39
279
  await parallelForEach([...artifacts.keys()], concurrency, async (slot) => {
40
280
  const artifact = artifacts[slot];
41
- if (artifact === undefined)
42
- return;
43
- const checked = checkContentManifest(await ports.getManifest(artifact), artifact.contentHash);
44
- if (!checked.ok)
45
- throw new Error(checked.error);
46
- const manifest = checked.value;
281
+ const manifest = manifests[slot];
282
+ if (artifact === undefined || manifest === undefined) {
283
+ throw new Error('download set lost a manifest');
284
+ }
47
285
  const missing = [];
48
286
  for (const index of manifest.chunks.keys()) {
49
287
  if (!await ports.hasChunk(artifact, manifest, index))
50
288
  missing.push(index);
51
289
  }
52
- plans[slot] = { artifact, manifest, missing };
290
+ gaps[slot] = missing;
53
291
  });
54
- const gaps = [];
55
- const priorByPlan = new Map();
56
- const maxGaps = plans.reduce((maximum, plan) => Math.max(maximum, plan?.missing.length ?? 0), 0);
57
- for (let depth = 0; depth < maxGaps; depth += 1) {
58
- for (const plan of plans) {
59
- if (plan === undefined)
60
- continue;
61
- const index = plan.missing[depth];
62
- if (index === undefined)
63
- continue;
292
+ // Wave two: fetch every gap as one planned wave. Each artifact's gaps form
293
+ // one chain so chunks store in chunk order; `delivered` settles when a gap
294
+ // is stored, or rejects so no later chunk waits forever.
295
+ const blockChains = [];
296
+ artifacts.forEach((artifact, slot) => {
297
+ const manifest = manifests[slot];
298
+ const missing = gaps[slot];
299
+ if (manifest === undefined || missing === undefined || missing.length === 0)
300
+ return;
301
+ let prior;
302
+ const chain = [];
303
+ for (const index of missing) {
304
+ const expected = manifest.chunks[index];
305
+ if (expected === undefined)
306
+ throw new Error('download manifest named an unknown chunk index');
64
307
  let stored;
65
308
  let failed;
66
309
  const delivered = new Promise((resolve, reject) => {
67
310
  stored = resolve;
68
311
  failed = reject;
69
312
  });
70
- // A failed effect may leave no later chunk admitted to observe the
71
- // rejection; the set still fails through the effect's own throw.
313
+ // A failed unit may leave no later chunk admitted to observe the
314
+ // rejection; the set still fails through the unit's own throw.
72
315
  delivered.catch(() => { });
73
- gaps.push({ plan, index, priorStored: priorByPlan.get(plan), stored, failed });
74
- priorByPlan.set(plan, delivered);
75
- }
76
- }
77
- await weightedParallelForEach(gaps, concurrency, maxInFlightBytes, ({ plan, index }) => plan.manifest.chunks[index]?.bytes ?? 0, async ({ plan, index, priorStored, stored, failed }) => {
78
- try {
79
- const expected = plan.manifest.chunks[index];
80
- if (expected === undefined)
81
- throw new Error('download manifest named an unknown chunk index');
82
- const bytes = await ports.getChunk(plan.artifact, plan.manifest, index);
83
- if (!(bytes instanceof Uint8Array)
84
- || bytes.byteLength !== expected.bytes
85
- || ports.sha256Hex(bytes) !== expected.sha256) {
86
- throw new Error(`downloaded content chunk ${index} failed verification`);
87
- }
88
- if (priorStored !== undefined)
89
- await priorStored;
90
- await ports.putChunk(plan.artifact, plan.manifest, index, bytes);
91
- stored();
92
- }
93
- catch (error) {
94
- failed(error);
95
- throw error;
316
+ const priorStored = prior;
317
+ chain.push({
318
+ object: { kind: 'block', sha256: expected.sha256 },
319
+ standaloneWeight: expected.bytes,
320
+ deliver: async (sealed) => {
321
+ try {
322
+ const plain = await ports.openEnvelope({ kind: 'block', sha256: expected.sha256 }, sealed);
323
+ if (!(plain instanceof Uint8Array)
324
+ || plain.byteLength !== expected.bytes
325
+ || ports.sha256Hex(plain) !== expected.sha256) {
326
+ throw new Error(`downloaded content chunk ${index} failed verification`);
327
+ }
328
+ if (priorStored !== undefined)
329
+ await priorStored;
330
+ await ports.putChunk(artifact, manifest, index, plain);
331
+ stored();
332
+ }
333
+ catch (error) {
334
+ failed(error);
335
+ throw error;
336
+ }
337
+ },
338
+ fail: failed,
339
+ });
340
+ prior = delivered;
96
341
  }
342
+ blockChains.push(chain);
97
343
  });
344
+ const blockWave = await fetchWave(ports, blockChains, concurrency, maxInFlightBytes);
98
345
  const receipts = new Array(artifacts.length);
99
- await parallelForEach([...plans.keys()], concurrency, async (slot) => {
100
- const plan = plans[slot];
101
- if (plan === undefined)
102
- return;
103
- const sealed = await ports.sealArtifact(plan.artifact, plan.manifest);
104
- if (sealed.bytes !== plan.manifest.bytes || sealed.contentHash !== plan.manifest.contentHash) {
105
- throw new Error(`downloaded artifact ${plan.artifact.contentHash} failed verification`);
346
+ await parallelForEach([...artifacts.keys()], concurrency, async (slot) => {
347
+ const artifact = artifacts[slot];
348
+ const manifest = manifests[slot];
349
+ const missing = gaps[slot];
350
+ if (artifact === undefined || manifest === undefined || missing === undefined) {
351
+ throw new Error('download set lost a manifest');
352
+ }
353
+ const sealed = await ports.sealArtifact(artifact, manifest);
354
+ if (sealed.bytes !== manifest.bytes || sealed.contentHash !== manifest.contentHash) {
355
+ throw new Error(`downloaded artifact ${artifact.contentHash} failed verification`);
106
356
  }
107
357
  receipts[slot] = {
108
- artifact: plan.artifact,
109
- manifest: plan.manifest,
358
+ artifact,
359
+ manifest,
110
360
  local: sealed.local,
111
- downloadedChunks: plan.missing.length,
112
- reusedChunks: plan.manifest.chunks.length - plan.missing.length,
361
+ downloadedChunks: missing.length,
362
+ reusedChunks: manifest.chunks.length - missing.length,
113
363
  };
114
364
  });
115
- return receipts.map((receipt) => {
116
- if (receipt === undefined)
117
- throw new Error('download set lost an artifact receipt');
118
- return receipt;
119
- });
120
- }
121
- /** Download one immutable artifact — a set of one. */
122
- export async function download(artifact, ports, options = {}) {
123
- const [receipt] = await downloadAll([artifact], ports, options);
124
- if (receipt === undefined)
125
- throw new Error('download set lost an artifact receipt');
126
- return receipt;
365
+ return {
366
+ receipts: receipts.map((receipt) => {
367
+ if (receipt === undefined)
368
+ throw new Error('download set lost an artifact receipt');
369
+ return receipt;
370
+ }),
371
+ shape: {
372
+ localManifests,
373
+ fetchedManifests: manifestChains.length,
374
+ packedManifests: manifestWave.packedObjects,
375
+ standaloneManifests: manifestWave.standaloneObjects,
376
+ manifestSpans: manifestWave.rangedReads,
377
+ packedBlocks: blockWave.packedObjects,
378
+ standaloneBlocks: blockWave.standaloneObjects,
379
+ blockSpans: blockWave.rangedReads,
380
+ },
381
+ };
127
382
  }
128
383
  //# sourceMappingURL=download.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/transfer/download.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAwB,MAAM,yBAAyB,CAAC;AAElG,OAAO,EAAE,sBAAsB,EAAyB,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EACL,4BAA4B,EAC5B,eAAe,EACf,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAmEvB;;uCAEuC;AACvC,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAsC,EACtC,KAAmC,EACnC,UAA2B,EAAE;IAE7B,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,4BAA4B,CAAC;IACxE,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB;WAC5C,4BAA4B,GAAG,WAAW,CAAC;IAChD,KAAK,MAAM,QAAQ,IAAI,SAAS;QAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAEnE,MAAM,KAAK,GAAiC,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACxE,MAAM,eAAe,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACvE,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO;QACnC,MAAM,OAAO,GAAG,oBAAoB,CAClC,MAAM,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,EACjC,QAAQ,CAAC,WAAW,CACrB,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;QAC/B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,MAAM,WAAW,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAC7C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAChD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAClC,IAAI,MAAmB,CAAC;YACxB,IAAI,MAAiC,CAAC;YACtC,MAAM,SAAS,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtD,MAAM,GAAG,OAAO,CAAC;gBACjB,MAAM,GAAG,MAAM,CAAC;YAClB,CAAC,CAAC,CAAC;YACH,mEAAmE;YACnE,iEAAiE;YACjE,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC/E,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,MAAM,uBAAuB,CAC3B,IAAI,EACJ,WAAW,EACX,gBAAgB,EAChB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,EAC5D,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QACrD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7C,IAAI,QAAQ,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;YAC9F,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACxE,IAAI,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC;mBAC7B,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,KAAK;mBACnC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAChD,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,sBAAsB,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,WAAW,KAAK,SAAS;gBAAE,MAAM,WAAW,CAAC;YACjD,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YACjE,MAAM,EAAE,CAAC;QACX,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,CAAC;YACd,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,QAAQ,GAAmD,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7F,MAAM,eAAe,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACnE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtE,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC7F,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,QAAQ,CAAC,WAAW,sBAAsB,CAAC,CAAC;QAC1F,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,GAAG;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;YACrC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM;SAChE,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACpF,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,QAA0B,EAC1B,KAAmC,EACnC,UAA2B,EAAE;IAE7B,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAChE,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACpF,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/transfer/download.ts"],"names":[],"mappings":"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"}
@@ -1,47 +1,32 @@
1
1
  /**
2
- * Ranged pack reading.
2
+ * Pack span planning.
3
3
  *
4
- * Sealed envelopes of many small objects live inside one immutable pack.
5
- * Requests for ranges of the same pack URL made in the same event-loop turn
6
- * merge into minimal byte spans one ranged GET per spanand every
7
- * requester receives exactly its envelope slice. A small hole between wanted
8
- * ranges is cheaper to read through than to split a request over, so spans
9
- * merge across gaps up to RANGE_MERGE_GAP_BYTES. Wrong or shifted bytes can
10
- * never leak: every dispensed slice is still an authenticated envelope the
11
- * caller opens and hash-verifies.
4
+ * Sealed envelopes of many small objects live inside one immutable pack. A
5
+ * download wave knows every member it needs before any byte moves, so the
6
+ * members of one pack are planned into a few broad byte spans one ranged
7
+ * GET per span instead of a request per member. A small hole between
8
+ * wanted ranges is cheaper to read through than to split a request over, so
9
+ * spans merge across gaps up to RANGE_MERGE_GAP_BYTES; a span never grows
10
+ * past the caller's byte cap, so one planned read always fits the wave's
11
+ * in-flight memory bound. Wrong or shifted bytes can never leak: every
12
+ * dispensed slice is still an authenticated envelope the reader opens and
13
+ * hash-verifies.
12
14
  */
13
- import type { ContentRef } from './refs.js';
14
15
  /** Read through holes up to this size rather than splitting a range request. */
15
16
  export declare const RANGE_MERGE_GAP_BYTES: number;
16
- /** Merged span bytes one fetcher may hold in flight at once. Admission of
17
- * spans — not just of the objects above them — is byte-bounded, so a wide
18
- * same-turn fan-out can never hold every pack's sealed bytes at once. */
19
- export declare const SPAN_FETCH_MAX_IN_FLIGHT_BYTES: number;
20
17
  export interface ByteSpan {
21
18
  readonly offset: number;
22
19
  readonly length: number;
23
20
  }
24
- export interface SpanPlan {
21
+ export interface PackSpanPlan {
25
22
  /** Minimal disjoint fetch spans, ascending by offset. */
26
- readonly spans: ByteSpan[];
27
- /** Aligned with the input: which span serves each request, and where the
28
- * request's bytes start inside that span. */
29
- readonly slices: Array<{
30
- readonly span: number;
31
- readonly start: number;
32
- }>;
23
+ readonly spans: readonly ByteSpan[];
24
+ /** Aligned with the input: which span holds each member. */
25
+ readonly memberSpan: readonly number[];
33
26
  }
34
- /** Merge wanted ranges into minimal fetch spans. Pure planning — no IO. */
35
- export declare function planSpans(requests: readonly ByteSpan[], mergeGap: number): SpanPlan;
36
- export interface SpanFetcherPorts {
37
- /** Return exactly the requested bytes: the whole object when span is null,
38
- * otherwise precisely span.length bytes starting at span.offset. */
39
- fetchSpan(url: string, span: ByteSpan | null): Promise<Uint8Array>;
40
- }
41
- export interface SpanFetcher {
42
- /** The sealed envelope bytes a ref names — a whole standalone object, or
43
- * one exact slice of a pack. */
44
- fetch(ref: ContentRef): Promise<Uint8Array>;
45
- }
46
- export declare function createSpanFetcher(ports: SpanFetcherPorts): SpanFetcher;
27
+ /** Plan one pack's wanted member ranges into broad fetch spans. Pure
28
+ * planning no IO. Members merge across holes up to `mergeGap`; a span
29
+ * stops growing at `maxSpanBytes`, except that a single member larger than
30
+ * the cap still gets exactly one span of its own. */
31
+ export declare function planPackSpans(members: readonly ByteSpan[], mergeGap: number, maxSpanBytes: number): PackSpanPlan;
47
32
  //# sourceMappingURL=ranges.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ranges.d.ts","sourceRoot":"","sources":["../../src/transfer/ranges.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,QAAY,CAAC;AAE/C;;yEAEyE;AACzE,eAAO,MAAM,8BAA8B,QAAmB,CAAC;AAE/D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC3B;iDAC6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3E;AAQD,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,QAAQ,EAAE,SAAS,QAAQ,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAwBnF;AAED,MAAM,WAAW,gBAAgB;IAC/B;wEACoE;IACpE,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,WAAW;IAC1B;oCACgC;IAChC,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7C;AAQD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAyFtE"}
1
+ {"version":3,"file":"ranges.d.ts","sourceRoot":"","sources":["../../src/transfer/ranges.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,QAAY,CAAC;AAE/C,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAQD;;;qDAGqD;AACrD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,YAAY,CA6Bd"}