@amalgm/shell 0.1.134 → 0.1.135
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/content-direct.d.ts +21 -13
- package/dist/content-direct.js +70 -68
- package/dist/content-direct.js.map +1 -1
- package/dist/user-ground-host.d.ts +12 -7
- package/dist/user-ground-host.js +181 -73
- package/dist/user-ground-host.js.map +1 -1
- package/dist/wire-client.js +1 -1
- package/npm-shrinkwrap.json +6 -6
- package/package.json +2 -2
package/dist/content-direct.d.ts
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Downloads no longer relay bytes through the gateway. This plane asks the
|
|
5
5
|
* gateway for two control facts only — the per-resource content key, handed
|
|
6
|
-
* once per resource over the authenticated wire, and content refs
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* once per resource over the authenticated wire, and content refs: a
|
|
7
|
+
* short-lived storage URL per object plus, for objects packed inside one
|
|
8
|
+
* immutable pack, the exact byte range holding their sealed envelope. The
|
|
9
|
+
* download engine plans whole waves against these primitives — one refs
|
|
10
|
+
* frame per batch of the want-list, one ranged GET per planned pack span —
|
|
11
|
+
* and every envelope is opened locally. Bytes travel storage → this
|
|
12
|
+
* machine; the gateway signs and revokes, nothing more.
|
|
12
13
|
*/
|
|
13
|
-
import { type ContentObjectName } from "@amalgm/live";
|
|
14
|
+
import { type ByteSpan, type ContentObjectName, type ContentRef } from "@amalgm/live";
|
|
14
15
|
interface DirectContentWire {
|
|
15
16
|
request(frame: Record<string, unknown> & {
|
|
16
17
|
type: string;
|
|
@@ -31,17 +32,24 @@ export declare class DirectContentPlane {
|
|
|
31
32
|
/** Key material is stable for a resource's lifetime, so one handoff per
|
|
32
33
|
* process is enough; it lives only in memory, never at rest. */
|
|
33
34
|
private readonly keys;
|
|
34
|
-
private readonly brokers;
|
|
35
|
-
private readonly spans;
|
|
36
35
|
private readonly wire;
|
|
37
36
|
private readonly counters;
|
|
38
37
|
constructor(wire: DirectContentWire);
|
|
39
38
|
metrics(): DirectContentMetrics;
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
|
|
39
|
+
/** Resolve one batch of named objects to storage locations, aligned by
|
|
40
|
+
* index — one wire frame per call; the download engine owns batching. */
|
|
41
|
+
requestRefs(resourceId: string, objects: readonly ContentObjectName[]): Promise<readonly ContentRef[]>;
|
|
42
|
+
/** One storage read: the whole object, or exactly one pack span. Counts
|
|
43
|
+
* physical attempts, including failures that retry; successful bytes are
|
|
44
|
+
* counted once storage answers. */
|
|
45
|
+
fetchSpan(url: string, span: ByteSpan | null): Promise<Uint8Array>;
|
|
46
|
+
/** Open one sealed envelope with the resource's content key. */
|
|
47
|
+
openEnvelope(resourceId: string, sealed: Uint8Array): Promise<Buffer>;
|
|
48
|
+
/** Fetch one sealed storage object and open it — a planned wave of one,
|
|
49
|
+
* for single-object reads like registry graph pages. Every attempt asks
|
|
50
|
+
* for a fresh ref — URL expiry is the gateway's revocation lever, so URLs
|
|
51
|
+
* are used immediately and never reused. */
|
|
43
52
|
fetchObject(resourceId: string, object: ContentObjectName): Promise<Buffer>;
|
|
44
53
|
private contentKey;
|
|
45
|
-
private broker;
|
|
46
54
|
}
|
|
47
55
|
export {};
|
package/dist/content-direct.js
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Downloads no longer relay bytes through the gateway. This plane asks the
|
|
5
5
|
* gateway for two control facts only — the per-resource content key, handed
|
|
6
|
-
* once per resource over the authenticated wire, and content refs
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* once per resource over the authenticated wire, and content refs: a
|
|
7
|
+
* short-lived storage URL per object plus, for objects packed inside one
|
|
8
|
+
* immutable pack, the exact byte range holding their sealed envelope. The
|
|
9
|
+
* download engine plans whole waves against these primitives — one refs
|
|
10
|
+
* frame per batch of the want-list, one ranged GET per planned pack span —
|
|
11
|
+
* and every envelope is opened locally. Bytes travel storage → this
|
|
12
|
+
* machine; the gateway signs and revokes, nothing more.
|
|
12
13
|
*/
|
|
13
|
-
import {
|
|
14
|
+
import { openProtectedEnvelopeBytes, } from "@amalgm/live";
|
|
14
15
|
import { WireRequestError } from "./wire-client.js";
|
|
15
16
|
function decodeRefs(frame) {
|
|
16
17
|
const urls = frame.urls;
|
|
@@ -39,45 +40,78 @@ export class DirectContentPlane {
|
|
|
39
40
|
/** Key material is stable for a resource's lifetime, so one handoff per
|
|
40
41
|
* process is enough; it lives only in memory, never at rest. */
|
|
41
42
|
keys = new Map();
|
|
42
|
-
brokers = new Map();
|
|
43
|
-
spans;
|
|
44
43
|
wire;
|
|
45
44
|
counters = {
|
|
46
45
|
rangedGets: 0, wholeGets: 0, fetchedBytes: 0, refsFrames: 0, refsMs: 0, decryptMs: 0,
|
|
47
46
|
};
|
|
48
47
|
constructor(wire) {
|
|
49
48
|
this.wire = wire;
|
|
50
|
-
this.spans = createSpanFetcher({
|
|
51
|
-
fetchSpan: async (url, span) => {
|
|
52
|
-
// Count physical attempts, including failures that retry. Successful
|
|
53
|
-
// bytes are counted separately once storage answers.
|
|
54
|
-
if (span)
|
|
55
|
-
this.counters.rangedGets += 1;
|
|
56
|
-
else
|
|
57
|
-
this.counters.wholeGets += 1;
|
|
58
|
-
const bytes = await fetchStorageSpan(url, span);
|
|
59
|
-
this.counters.fetchedBytes += bytes.byteLength;
|
|
60
|
-
return bytes;
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
49
|
}
|
|
64
50
|
metrics() {
|
|
65
51
|
return { ...this.counters };
|
|
66
52
|
}
|
|
67
|
-
/**
|
|
68
|
-
*
|
|
69
|
-
|
|
53
|
+
/** Resolve one batch of named objects to storage locations, aligned by
|
|
54
|
+
* index — one wire frame per call; the download engine owns batching. */
|
|
55
|
+
async requestRefs(resourceId, objects) {
|
|
56
|
+
const refsStarted = performance.now();
|
|
57
|
+
this.counters.refsFrames += 1;
|
|
58
|
+
try {
|
|
59
|
+
const frame = await this.wire.request({
|
|
60
|
+
type: "private.entity-content.refs",
|
|
61
|
+
resource_id: resourceId,
|
|
62
|
+
objects: objects.map((object) => ({ kind: object.kind, sha256: object.sha256 })),
|
|
63
|
+
}, ["private.entity-content.refs-result"]);
|
|
64
|
+
return decodeRefs(frame);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
this.counters.refsMs += performance.now() - refsStarted;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** One storage read: the whole object, or exactly one pack span. Counts
|
|
71
|
+
* physical attempts, including failures that retry; successful bytes are
|
|
72
|
+
* counted once storage answers. */
|
|
73
|
+
async fetchSpan(url, span) {
|
|
74
|
+
if (span)
|
|
75
|
+
this.counters.rangedGets += 1;
|
|
76
|
+
else
|
|
77
|
+
this.counters.wholeGets += 1;
|
|
78
|
+
const bytes = await fetchStorageSpan(url, span);
|
|
79
|
+
this.counters.fetchedBytes += bytes.byteLength;
|
|
80
|
+
return bytes;
|
|
81
|
+
}
|
|
82
|
+
/** Open one sealed envelope with the resource's content key. */
|
|
83
|
+
async openEnvelope(resourceId, sealed) {
|
|
84
|
+
const { key, contract } = await this.contentKey(resourceId);
|
|
85
|
+
const decryptStarted = performance.now();
|
|
86
|
+
try {
|
|
87
|
+
const opened = await openProtectedEnvelopeBytes(key, sealed, {
|
|
88
|
+
resourceId,
|
|
89
|
+
contract,
|
|
90
|
+
purpose: "entity-content",
|
|
91
|
+
});
|
|
92
|
+
return Buffer.from(opened.buffer, opened.byteOffset, opened.byteLength);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
this.counters.decryptMs += performance.now() - decryptStarted;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Fetch one sealed storage object and open it — a planned wave of one,
|
|
99
|
+
* for single-object reads like registry graph pages. Every attempt asks
|
|
100
|
+
* for a fresh ref — URL expiry is the gateway's revocation lever, so URLs
|
|
101
|
+
* are used immediately and never reused. */
|
|
70
102
|
async fetchObject(resourceId, object) {
|
|
71
|
-
const [
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
103
|
+
const [ref] = await this.requestRefs(resourceId, [object]);
|
|
104
|
+
if (ref === undefined)
|
|
105
|
+
throw new Error("content authority answered an invalid refs reply");
|
|
106
|
+
const span = ref.offset !== undefined && ref.length !== undefined
|
|
107
|
+
? { offset: ref.offset, length: ref.length }
|
|
108
|
+
: null;
|
|
75
109
|
let sealed;
|
|
76
110
|
try {
|
|
77
|
-
sealed = await this.
|
|
111
|
+
sealed = await this.fetchSpan(ref.url, span);
|
|
78
112
|
}
|
|
79
113
|
catch (error) {
|
|
80
|
-
// The
|
|
114
|
+
// The storage fetch cannot name the object it served; restore the
|
|
81
115
|
// caller-facing identity on the authority's established missing code.
|
|
82
116
|
if (error instanceof WireRequestError && error.code === "entity_content_not_found") {
|
|
83
117
|
throw new WireRequestError({
|
|
@@ -90,18 +124,10 @@ export class DirectContentPlane {
|
|
|
90
124
|
}
|
|
91
125
|
throw error;
|
|
92
126
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const opened = await openProtectedEnvelopeBytes(key, sealed, {
|
|
96
|
-
resourceId,
|
|
97
|
-
contract,
|
|
98
|
-
purpose: "entity-content",
|
|
99
|
-
});
|
|
100
|
-
return Buffer.from(opened.buffer, opened.byteOffset, opened.byteLength);
|
|
101
|
-
}
|
|
102
|
-
finally {
|
|
103
|
-
this.counters.decryptMs += performance.now() - decryptStarted;
|
|
127
|
+
if (span !== null && sealed.byteLength !== span.length) {
|
|
128
|
+
throw new Error("content storage answered the wrong byte count for a pack span");
|
|
104
129
|
}
|
|
130
|
+
return this.openEnvelope(resourceId, sealed);
|
|
105
131
|
}
|
|
106
132
|
contentKey(resourceId) {
|
|
107
133
|
let pending = this.keys.get(resourceId);
|
|
@@ -128,35 +154,11 @@ export class DirectContentPlane {
|
|
|
128
154
|
}
|
|
129
155
|
return pending;
|
|
130
156
|
}
|
|
131
|
-
broker(resourceId) {
|
|
132
|
-
let broker = this.brokers.get(resourceId);
|
|
133
|
-
if (!broker) {
|
|
134
|
-
broker = createRefsBroker({
|
|
135
|
-
requestRefs: async (objects) => {
|
|
136
|
-
const refsStarted = performance.now();
|
|
137
|
-
this.counters.refsFrames += 1;
|
|
138
|
-
try {
|
|
139
|
-
const frame = await this.wire.request({
|
|
140
|
-
type: "private.entity-content.refs",
|
|
141
|
-
resource_id: resourceId,
|
|
142
|
-
objects: objects.map((object) => ({ kind: object.kind, sha256: object.sha256 })),
|
|
143
|
-
}, ["private.entity-content.refs-result"]);
|
|
144
|
-
return decodeRefs(frame);
|
|
145
|
-
}
|
|
146
|
-
finally {
|
|
147
|
-
this.counters.refsMs += performance.now() - refsStarted;
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
});
|
|
151
|
-
this.brokers.set(resourceId, broker);
|
|
152
|
-
}
|
|
153
|
-
return broker;
|
|
154
|
-
}
|
|
155
157
|
}
|
|
156
158
|
/** One HTTP GET against content storage: the whole object, or exactly one
|
|
157
159
|
* pack span. A server that ignores the Range header and answers the full
|
|
158
|
-
* object is sliced here — the
|
|
159
|
-
*
|
|
160
|
+
* object is sliced here — the engine's length law rejects anything short
|
|
161
|
+
* or shifted. */
|
|
160
162
|
async function fetchStorageSpan(url, span) {
|
|
161
163
|
const response = await fetch(url, span ? {
|
|
162
164
|
headers: { range: `bytes=${span.offset}-${span.offset + span.length - 1}` },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-direct.js","sourceRoot":"","sources":["../src/content-direct.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"content-direct.js","sourceRoot":"","sources":["../src/content-direct.ts"],"names":[],"mappings":"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"}
|
|
@@ -235,10 +235,11 @@ export declare class UserGroundHost {
|
|
|
235
235
|
private putContentManifest;
|
|
236
236
|
private uploadSnapshotContent;
|
|
237
237
|
/** Download a set of immutable artifacts straight from content storage.
|
|
238
|
-
* The set is the primitive
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
238
|
+
* The set is the primitive and the plan is physical: the engine resolves
|
|
239
|
+
* the whole want-list in two planned waves — manifests grouped by the
|
|
240
|
+
* pack that holds them, then blocks the same way — so all members of one
|
|
241
|
+
* pack collapse into a few broad ranged reads while standalone objects
|
|
242
|
+
* stay one read each. A lone artifact is a set of one. */
|
|
242
243
|
private downloadContentSet;
|
|
243
244
|
private downloadContent;
|
|
244
245
|
private ensureWatchers;
|
|
@@ -259,9 +260,13 @@ export declare class UserGroundHost {
|
|
|
259
260
|
* preparation names the slow part instead of one opaque number. */
|
|
260
261
|
private finishPreparation;
|
|
261
262
|
/** Which of these heads does the authority hold sealed under the current
|
|
262
|
-
* content contract
|
|
263
|
-
*
|
|
264
|
-
|
|
263
|
+
* content contract — and which of the sealed ones are packed, their whole
|
|
264
|
+
* closure inside immutable packs? Batched so a whole workspace costs a
|
|
265
|
+
* handful of frames. `sealed` is the only permission to skip an upload
|
|
266
|
+
* for correctness; `packed` is placement knowledge only. The packed
|
|
267
|
+
* answer is a protocol 16 capability and is required: a missing field
|
|
268
|
+
* means an older gateway, and this machine refuses to guess placement. */
|
|
269
|
+
private sealInventory;
|
|
265
270
|
private publishPendingSnapshots;
|
|
266
271
|
/** Seal this publication's graph pages. Pages are immutable, content
|
|
267
272
|
* addressed, and already in memory, so the authority's seal inventory alone
|