@volter/browser-substrate 0.1.119 → 0.1.120

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.
@@ -0,0 +1,8 @@
1
+ /** Claim before mkdir/write; pre-ledger cache entries remain unknown. */
2
+ export declare function registerPreparationCacheEntry(directory: string, created?: boolean): void;
3
+ /** A complete result still holds its files until its serving/copying caller releases. */
4
+ export declare function retainPreparationCache<T>(projectDirectory: string, cacheDirectory: string, work: () => Promise<T>, report?: (text: string) => void): Promise<{
5
+ value: T;
6
+ release(): void;
7
+ }>;
8
+ //# sourceMappingURL=cache-lifetime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-lifetime.d.ts","sourceRoot":"","sources":["../../src/cli/cache-lifetime.ts"],"names":[],"mappings":"AAoFA,yEAAyE;AACzE,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,IAAI,CAetF;AA6BD,yFAAyF;AACzF,wBAAsB,sBAAsB,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAyC,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,CAAC,CAAC;IAAC,OAAO,IAAI,IAAI,CAAA;CAAE,CAAC,CA6BrO"}
@@ -0,0 +1,214 @@
1
+ /** ADR-0095: creation evidence and live use, never age or logical size. */
2
+ import { AsyncLocalStorage } from "node:async_hooks";
3
+ import { randomUUID, createHash } from "node:crypto";
4
+ import { existsSync, linkSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, statfsSync, unlinkSync, writeFileSync } from "node:fs";
5
+ import { dirname, join, relative, resolve, sep } from "node:path";
6
+ const invocations = new AsyncLocalStorage();
7
+ const namespaces = new Set(["built", "packs", "work"]);
8
+ const liveHolds = new Set();
9
+ process.once("exit", () => { for (const release of liveHolds)
10
+ release(); });
11
+ function alive(pid) {
12
+ if (!Number.isSafeInteger(pid) || pid < 1)
13
+ return true;
14
+ try {
15
+ process.kill(pid, 0);
16
+ return true;
17
+ }
18
+ catch (cause) {
19
+ return cause.code !== "ESRCH";
20
+ }
21
+ }
22
+ function validEntry(root, path) {
23
+ const name = relative(root, path);
24
+ return resolve(path) === path && name !== "" && !name.startsWith("..") && namespaces.has(name.split(sep)[0]) && name.split(sep).length > 1;
25
+ }
26
+ function ledger(root) { return join(root, ".lifetime", "state.json"); }
27
+ function readState(root) {
28
+ if (!existsSync(ledger(root)))
29
+ return { version: 1, entries: [], current: {}, leases: {} };
30
+ const state = JSON.parse(readFileSync(ledger(root), "utf8"));
31
+ if (state.version !== 1 || !Array.isArray(state.entries) || !state.current || !state.leases || state.entries.some(path => !validEntry(root, path))
32
+ || [...Object.values(state.current), ...Object.values(state.leases)].some(value => !Array.isArray(value.entries) || value.entries.some(path => !validEntry(root, path))))
33
+ throw new Error(`Unreadable cache ownership ledger; retained ${ledger(root)}.`);
34
+ return state;
35
+ }
36
+ /** The small synchronous mutation never holds the lock across async work. */
37
+ function mutate(root, change) {
38
+ const directory = dirname(ledger(root));
39
+ mkdirSync(directory, { recursive: true });
40
+ const lock = join(directory, "lock.json"), claim = join(directory, `claim-${randomUUID()}.json`);
41
+ const owner = JSON.stringify({ pid: process.pid, nonce: randomUUID() });
42
+ writeFileSync(claim, owner);
43
+ try {
44
+ for (;;) {
45
+ try {
46
+ linkSync(claim, lock);
47
+ break;
48
+ }
49
+ catch (cause) {
50
+ if (cause.code !== "EEXIST")
51
+ throw cause;
52
+ let prior;
53
+ try {
54
+ prior = JSON.parse(readFileSync(lock, "utf8"));
55
+ }
56
+ catch (failure) {
57
+ if (failure.code === "ENOENT")
58
+ continue;
59
+ throw failure;
60
+ }
61
+ if (!alive(prior.pid)) {
62
+ // Serialize stale-lock retirement too: a second reclaimer must never
63
+ // unlink a new writer's claim after the first reclaimer releases it.
64
+ const retiring = join(directory, "retiring.json");
65
+ try {
66
+ linkSync(claim, retiring);
67
+ try {
68
+ if (existsSync(lock) && !alive(JSON.parse(readFileSync(lock, "utf8")).pid))
69
+ unlinkSync(lock);
70
+ }
71
+ finally {
72
+ unlinkSync(retiring);
73
+ }
74
+ }
75
+ catch (failure) {
76
+ const code = failure.code;
77
+ if (code === "EEXIST") {
78
+ try {
79
+ if (!alive(JSON.parse(readFileSync(retiring, "utf8")).pid))
80
+ throw new Error(`Interrupted cache ledger recovery; ownership retained in ${retiring}.`);
81
+ }
82
+ catch (reading) {
83
+ if (reading.code !== "ENOENT")
84
+ throw reading;
85
+ }
86
+ }
87
+ else if (code !== "ENOENT")
88
+ throw failure;
89
+ }
90
+ }
91
+ // Polling interval is not a retention limit; live writers keep their lock.
92
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10);
93
+ }
94
+ }
95
+ }
96
+ finally {
97
+ unlinkSync(claim);
98
+ }
99
+ try {
100
+ const state = readState(root), value = change(state);
101
+ const temporary = `${ledger(root)}.${randomUUID()}.tmp`;
102
+ writeFileSync(temporary, JSON.stringify(state));
103
+ renameSync(temporary, ledger(root));
104
+ return value;
105
+ }
106
+ finally {
107
+ if (existsSync(lock) && readFileSync(lock, "utf8") === owner)
108
+ unlinkSync(lock);
109
+ }
110
+ }
111
+ /** Claim before mkdir/write; pre-ledger cache entries remain unknown. */
112
+ export function registerPreparationCacheEntry(directory, created = false) {
113
+ const active = invocations.getStore();
114
+ if (!active)
115
+ return;
116
+ const path = resolve(active.root, relative(active.selected, resolve(directory)));
117
+ if (!validEntry(active.root, path))
118
+ return;
119
+ mutate(active.root, state => {
120
+ const lease = state.leases[active.id];
121
+ if (!lease.entries.includes(path))
122
+ lease.entries.push(path);
123
+ mkdirSync(dirname(path), { recursive: true });
124
+ if (realpathSync(dirname(path)) !== dirname(path))
125
+ throw new Error(`Cache entry crosses an unowned symlink: ${path}.`);
126
+ if (created || !existsSync(path)) {
127
+ mkdirSync(path, { recursive: true });
128
+ if (!state.entries.includes(path))
129
+ state.entries.push(path);
130
+ }
131
+ else if (lstatSync(path).isSymbolicLink())
132
+ throw new Error(`Cache entry is a symlink; ownership retained: ${path}.`);
133
+ });
134
+ }
135
+ function reap(root, report) {
136
+ try {
137
+ const result = mutate(root, state => {
138
+ // Completion proves World teardown; only then may caller loss retire a hold.
139
+ for (const [id, lease] of Object.entries(state.leases))
140
+ if (lease.complete && !lease.retained && !alive(lease.pid))
141
+ delete state.leases[id];
142
+ const held = [...Object.values(state.current), ...Object.values(state.leases)].flatMap(value => value.entries);
143
+ const removable = state.entries.filter(path => !held.some(use => path === use || use.startsWith(path + sep) || path.startsWith(use + sep)));
144
+ const before = statfsSync(root, { bigint: true });
145
+ let removed = 0;
146
+ const retained = [];
147
+ for (const path of removable) {
148
+ try {
149
+ if (existsSync(path)) {
150
+ if (realpathSync(dirname(path)) !== dirname(path))
151
+ throw new Error("parent directory changed to a symlink");
152
+ rmSync(path, { recursive: true });
153
+ removed++;
154
+ }
155
+ state.entries = state.entries.filter(entry => entry !== path);
156
+ }
157
+ catch (cause) {
158
+ retained.push(`${path}: ${cause instanceof Error ? cause.message : String(cause)}`);
159
+ }
160
+ }
161
+ const after = statfsSync(root, { bigint: true });
162
+ return { removed, retained, delta: after.bavail * after.bsize - before.bavail * before.bsize };
163
+ });
164
+ if (result.removed)
165
+ report(` cache: released ${result.removed} superseded entries; filesystem available-space change ${result.delta >= 0n ? "+" : ""}${result.delta} bytes\n`);
166
+ for (const entry of result.retained)
167
+ report(` cache: retained ${entry}\n`);
168
+ }
169
+ catch (cause) {
170
+ report(` cache: reclaim deferred; ownership retained: ${cause instanceof Error ? cause.message : String(cause)}\n`);
171
+ }
172
+ }
173
+ /** A complete result still holds its files until its serving/copying caller releases. */
174
+ export async function retainPreparationCache(projectDirectory, cacheDirectory, work, report = text => process.stdout.write(text)) {
175
+ mkdirSync(cacheDirectory, { recursive: true });
176
+ const root = realpathSync(cacheDirectory), project = createHash("sha256").update(realpathSync(projectDirectory)).digest("hex"), id = randomUUID();
177
+ mutate(root, state => { state.leases[id] = { project, pid: process.pid, entries: [], complete: false }; });
178
+ try {
179
+ const value = await invocations.run({ root, selected: resolve(cacheDirectory), id }, work);
180
+ mutate(root, state => {
181
+ const lease = state.leases[id];
182
+ lease.complete = true;
183
+ state.current[project] = { generation: id, entries: [...lease.entries].filter(path => existsSync(path)) };
184
+ });
185
+ let released = false;
186
+ const release = () => {
187
+ if (released)
188
+ return;
189
+ try {
190
+ mutate(root, state => { delete state.leases[id]; });
191
+ }
192
+ catch (cause) {
193
+ report(` cache: release deferred; ownership retained: ${cause instanceof Error ? cause.message : String(cause)}\n`);
194
+ return;
195
+ }
196
+ released = true;
197
+ liveHolds.delete(release);
198
+ reap(root, report);
199
+ };
200
+ liveHolds.add(release);
201
+ reap(root, report);
202
+ return { value, release };
203
+ }
204
+ catch (cause) {
205
+ try {
206
+ mutate(root, state => { if (state.leases[id])
207
+ state.leases[id].retained = true; });
208
+ }
209
+ catch { /* Preserve the original preparation failure and its active lease. */ }
210
+ report(` cache: incomplete preparation ownership retained in ${ledger(root)}\n`);
211
+ throw cause;
212
+ }
213
+ }
214
+ //# sourceMappingURL=cache-lifetime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-lifetime.js","sourceRoot":"","sources":["../../src/cli/cache-lifetime.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cache-root.d.ts","sourceRoot":"","sources":["../../src/cli/cache-root.ts"],"names":[],"mappings":"AAIA,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKnE;AAED,mEAAmE;AACnE,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAElF;AAED,uFAAuF;AACvF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9E"}
1
+ {"version":3,"file":"cache-root.d.ts","sourceRoot":"","sources":["../../src/cli/cache-root.ts"],"names":[],"mappings":"AAKA,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKnE;AAED,mEAAmE;AACnE,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAElF;AAED,uFAAuF;AACvF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ9E"}
@@ -1,3 +1,4 @@
1
+ import { registerPreparationCacheEntry } from "./cache-lifetime.js";
1
2
  import { mkdirSync, mkdtempSync } from "node:fs";
2
3
  import { homedir, tmpdir } from "node:os";
3
4
  import { join, resolve } from "node:path";
@@ -19,6 +20,9 @@ export function preparationWorkDirectory(prefix, root) {
19
20
  const selected = selectedCacheRoot(root);
20
21
  const parent = selected ? join(selected, "work") : tmpdir();
21
22
  mkdirSync(parent, { recursive: true });
22
- return mkdtempSync(join(parent, prefix));
23
+ const directory = mkdtempSync(join(parent, prefix));
24
+ // mkdtemp created this directory, so register creation before it is used.
25
+ registerPreparationCacheEntry(directory, true);
26
+ return directory;
23
27
  }
24
28
  //# sourceMappingURL=cache-root.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache-root.js","sourceRoot":"","sources":["../../src/cli/cache-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB,CAAC,IAAa;IAC7C,IAAI,IAAI,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAClE,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAChE,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,yBAAyB,CAAC,SAAiB,EAAE,IAAa;IACxE,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,mBAAmB,CAAC,EAAE,SAAS,CAAC,CAAC;AACpG,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,wBAAwB,CAAC,MAAc,EAAE,IAAa;IACpE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5D,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"cache-root.js","sourceRoot":"","sources":["../../src/cli/cache-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB,CAAC,IAAa;IAC7C,IAAI,IAAI,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAClE,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAChE,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,yBAAyB,CAAC,SAAiB,EAAE,IAAa;IACxE,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,mBAAmB,CAAC,EAAE,SAAS,CAAC,CAAC;AACpG,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,wBAAwB,CAAC,MAAc,EAAE,IAAa;IACpE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5D,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,0EAA0E;IAC1E,6BAA6B,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC/C,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -89,6 +89,8 @@ export interface BuildImageOptions {
89
89
  appUrl?: string;
90
90
  };
91
91
  }
92
+ /** A serving or copying caller releases after its last read of the image's files. */
93
+ export declare function releaseImageCache(image: BuiltImage): void;
92
94
  export declare function buildImageWith(folder: string, name: string, settings: PageSettings, project: string | undefined, options: BuildImageOptions): Promise<BuiltImage>;
93
95
  /** Every file of the image and its World by the path it is served at, and where the folder holds it. */
94
96
  export declare function imageBlobs(image: BuiltImage): Map<string, string>;
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
package/dist/cli/main.js CHANGED
@@ -5,6 +5,7 @@
5
5
  // `build` writes the same page and image to ./dist as static files. `init`
6
6
  // writes a playground: a Dockerfile whose CMD fetches what to run.
7
7
  import { createHash } from "node:crypto";
8
+ import { retainPreparationCache } from "./cache-lifetime.js";
8
9
  import { preparationCacheDirectory, selectedCacheRoot } from "./cache-root.js";
9
10
  import { preparationBounded, preparationCheckpoint, preparationMemoryLimit, preparationPhase, withPreparationMemory } from "./preparation-memory.js";
10
11
  import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, statSync, watch, writeFileSync } from "node:fs";
@@ -219,7 +220,15 @@ function folderProjectId(folder, name) {
219
220
  export async function buildImage(folder, name, settings, project) {
220
221
  return buildImageWith(folder, name, settings, project, {});
221
222
  }
223
+ const imageCacheHolds = new WeakMap();
224
+ /** A serving or copying caller releases after its last read of the image's files. */
225
+ export function releaseImageCache(image) { imageCacheHolds.get(image)?.(); imageCacheHolds.delete(image); }
222
226
  export async function buildImageWith(folder, name, settings, project, options) {
227
+ const held = await retainPreparationCache(folder, preparationCacheDirectory("", options.cacheRoot), () => prepareImage(folder, name, settings, project, options));
228
+ imageCacheHolds.set(held.value, held.release);
229
+ return held.value;
230
+ }
231
+ async function prepareImage(folder, name, settings, project, options) {
223
232
  assertShell();
224
233
  options = { ...options, provisionCatalog: options.provisionCatalog ?? defaultProvisionCatalog() };
225
234
  // Host program metadata translates to exact catalog requests. Its
@@ -931,12 +940,16 @@ async function dev(cwd, args) {
931
940
  if (next.manifest.archive.integrity === image.manifest.archive.integrity
932
941
  && JSON.stringify(next.manifest.preparation) === JSON.stringify(image.manifest.preparation)
933
942
  && JSON.stringify(next.manifest.registry) === JSON.stringify(image.manifest.registry)
934
- && next.manifest.dependencies?.key === image.manifest.dependencies?.key)
943
+ && next.manifest.dependencies?.key === image.manifest.dependencies?.key) {
944
+ releaseImageCache(next);
935
945
  return;
946
+ }
947
+ const previous = image;
936
948
  image = next;
937
949
  for (const [path, bytes] of imageFiles(image))
938
950
  files.set(path, bytes);
939
951
  blobs = imageBlobs(image);
952
+ releaseImageCache(previous);
940
953
  server.broadcast({ integrity: image.manifest.archive.integrity, entries: image.manifest.archive.entries });
941
954
  process.stdout.write(` ${new Date().toLocaleTimeString()} changed: ${image.manifest.archive.entries} entries, ${formatBytes(image.manifest.archive.fileBytes)}; noticed by ${noticed}, quiet after ${quietAfter} ms, built in ${Date.now() - startedAt} ms\n`);
942
955
  }
@@ -995,7 +1008,7 @@ async function dev(cwd, args) {
995
1008
  let pollTimer = setTimeout(poll, 1000);
996
1009
  await new Promise((resolveClose) => {
997
1010
  const stop = () => { watcher.close(); if (pollTimer)
998
- clearTimeout(pollTimer); server.close(); resolveClose(); };
1011
+ clearTimeout(pollTimer); server.close(); releaseImageCache(image); resolveClose(); };
999
1012
  process.once("SIGINT", stop);
1000
1013
  process.once("SIGTERM", stop);
1001
1014
  });
@@ -1007,30 +1020,35 @@ async function build(cwd, args) {
1007
1020
  // the folder's own packages, which its install resolves as `dev`'s does.
1008
1021
  const packages = resolve(cwd, PACKAGES_DIRECTORY);
1009
1022
  const image = await buildImageWith(cwd, args.name, args.settings, args.project, imageOptions(args, packages));
1010
- const index = originRegistryIndex(packages);
1011
- if (index)
1012
- image.manifest.registry = index;
1013
- // A World the app attaches to is imaged beside it, as `dev` images it, whatever built the app
1014
- // (a Dockerfile's image too): the tab runs the World first and the image's command under it.
1015
- // build arguments are Docker's; an image Docker did not build here never read them
1016
- if (Object.keys(args.buildArgs).length > 0 && image.manifest.setup.kind !== "image") {
1017
- throw new Error(`--build-arg ${Object.keys(args.buildArgs).join(", ")} applies to a Dockerfile whose build half runs here (a RUN step); this one's setup is ${image.manifest.setup.kind}, built in the tab with its ARG defaults`);
1023
+ try {
1024
+ const index = originRegistryIndex(packages);
1025
+ if (index)
1026
+ image.manifest.registry = index;
1027
+ // A World the app attaches to is imaged beside it, as `dev` images it, whatever built the app
1028
+ // (a Dockerfile's image too): the tab runs the World first and the image's command under it.
1029
+ // build arguments are Docker's; an image Docker did not build here never read them
1030
+ if (Object.keys(args.buildArgs).length > 0 && image.manifest.setup.kind !== "image") {
1031
+ throw new Error(`--build-arg ${Object.keys(args.buildArgs).join(", ")} applies to a Dockerfile whose build half runs here (a RUN step); this one's setup is ${image.manifest.setup.kind}, built in the tab with its ARG defaults`);
1032
+ }
1033
+ if (args.world) {
1034
+ const world = await buildWorldImage(args.world, args.name, args.cacheRoot);
1035
+ image.manifest.world = world.world;
1036
+ image.world = { archive: world.archive, blobs: world.blobs, ...(world.plan ? { plan: world.plan } : {}) };
1037
+ for (const [served, source] of world.tarballs)
1038
+ image.tarballs.set(served, source);
1039
+ }
1040
+ const out = resolve(cwd, args.out);
1041
+ preparationPhase("final copy");
1042
+ const written = writeBuild({ shell: SHELL_DIRECTORY, files: imageFiles(image), blobs: imageBlobs(image), out, manifest: image.manifest });
1043
+ preparationCheckpoint();
1044
+ process.stdout.write(`\n browser-substrate build\n\n ${out}\n ${written.files} files, ${formatBytes(written.bytes)}\n ${image.manifest.setup.playground
1045
+ ? `a playground: deploy on your page's origin and on ${image.manifest.settings.sandboxOrigin ?? "a sandbox. subdomain of it"}`
1046
+ : "one origin, static; _headers carries the isolation headers"}\n\n`);
1047
+ return 0;
1018
1048
  }
1019
- if (args.world) {
1020
- const world = await buildWorldImage(args.world, args.name, args.cacheRoot);
1021
- image.manifest.world = world.world;
1022
- image.world = { archive: world.archive, blobs: world.blobs, ...(world.plan ? { plan: world.plan } : {}) };
1023
- for (const [served, source] of world.tarballs)
1024
- image.tarballs.set(served, source);
1049
+ finally {
1050
+ releaseImageCache(image);
1025
1051
  }
1026
- const out = resolve(cwd, args.out);
1027
- preparationPhase("final copy");
1028
- const written = writeBuild({ shell: SHELL_DIRECTORY, files: imageFiles(image), blobs: imageBlobs(image), out, manifest: image.manifest });
1029
- preparationCheckpoint();
1030
- process.stdout.write(`\n browser-substrate build\n\n ${out}\n ${written.files} files, ${formatBytes(written.bytes)}\n ${image.manifest.setup.playground
1031
- ? `a playground: deploy on your page's origin and on ${image.manifest.settings.sandboxOrigin ?? "a sandbox. subdomain of it"}`
1032
- : "one origin, static; _headers carries the isolation headers"}\n\n`);
1033
- return 0;
1034
1052
  }
1035
1053
  /**
1036
1054
  * The image's dry run (ADR-0043): opened once in a real browser, every
@@ -1052,10 +1070,11 @@ async function dryRunCommand(cwd, args) {
1052
1070
  for (let round = 1; round <= rounds; round += 1) {
1053
1071
  let url = args.page;
1054
1072
  let server;
1073
+ let image;
1055
1074
  if (!url) {
1056
1075
  // The image `dev` would serve: its packages answered by this origin.
1057
1076
  const packages = resolve(cwd, PACKAGES_DIRECTORY);
1058
- const image = await buildImageWith(cwd, args.name, args.settings, folderProjectId(cwd, args.name), { ...imageOptions(args, packages), capturedFile: file });
1077
+ image = await buildImageWith(cwd, args.name, args.settings, folderProjectId(cwd, args.name), { ...imageOptions(args, packages), capturedFile: file });
1059
1078
  const index = originRegistryIndex(packages);
1060
1079
  if (index)
1061
1080
  image.manifest.registry = index;
@@ -1123,6 +1142,8 @@ async function dryRunCommand(cwd, args) {
1123
1142
  }
1124
1143
  finally {
1125
1144
  server?.close();
1145
+ if (image)
1146
+ releaseImageCache(image);
1126
1147
  }
1127
1148
  }
1128
1149
  say(`\n Not sealed after ${rounds} rounds: each captured something new.\n\n`);