@nimbus-sh/worker 0.2.1 → 0.2.3
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/README.md +5 -2
- package/dist/facets/manager.d.ts +24 -0
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +73 -14
- package/dist/loaders/generated-workers.d.ts +2 -2
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +3 -3
- package/dist/runtime/facet-loader-host.d.ts +3 -2
- package/dist/runtime/facet-loader-host.d.ts.map +1 -1
- package/dist/runtime/facet-loader-host.js +1 -0
- package/dist/runtime/ruby-repl.js +1 -1
- package/dist/runtime/ruby-resident.d.ts +20 -0
- package/dist/runtime/ruby-resident.d.ts.map +1 -0
- package/dist/runtime/ruby-resident.js +278 -0
- package/dist/session/init.d.ts +16 -7
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +192 -208
- package/dist/session/keys.d.ts +11 -9
- package/dist/session/keys.d.ts.map +1 -1
- package/dist/session/keys.js +11 -9
- package/dist/session/nimbus-session.d.ts +11 -1
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +13 -57
- package/dist/session/programmatic.d.ts +1 -1
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +1 -1
- package/dist/session/routes.js +1 -1
- package/package.json +2 -2
- package/scripts/bundle-facet-workers.mjs +4 -3
- package/scripts/bundle-runtime.mjs +279 -44
- package/dist/npm/tarball-stream.d.ts +0 -93
- package/dist/npm/tarball-stream.d.ts.map +0 -1
- package/dist/npm/tarball-stream.js +0 -235
- package/dist/npm/tarball.d.ts +0 -34
- package/dist/npm/tarball.d.ts.map +0 -1
- package/dist/npm/tarball.js +0 -97
- package/dist/runtime/clang-runner.d.ts +0 -37
- package/dist/runtime/clang-runner.d.ts.map +0 -1
- package/dist/runtime/clang-runner.js +0 -865
- package/dist/runtime/ruby-gems.d.ts +0 -30
- package/dist/runtime/ruby-gems.d.ts.map +0 -1
- package/dist/runtime/ruby-gems.js +0 -636
- package/dist/runtime/ruby-runner.d.ts +0 -75
- package/dist/runtime/ruby-runner.d.ts.map +0 -1
- package/dist/runtime/ruby-runner.js +0 -1577
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* npm-tarball-stream.ts — pure streaming tar primitives.
|
|
3
|
-
*
|
|
4
|
-
* Extracted from npm-tarball.ts so these helpers can be esbuild-bundled
|
|
5
|
-
* WITHOUT dragging in NpmCache / NpmResolver / SqliteVFS. Consumed by
|
|
6
|
-
* scripts/bundle-facet-workers.mjs which emits a string constant the
|
|
7
|
-
* NimbusLoaderPool uses to inject the tar parser into dynamic workers.
|
|
8
|
-
*
|
|
9
|
-
* Zero dependencies. Works identically on the supervisor and inside a
|
|
10
|
-
* facet isolate. Never buffers the full decompressed tarball — peak
|
|
11
|
-
* transient heap is one file's bytes plus a 512-byte carry.
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Maximum size of a single file inside a tarball. Larger entries are skipped.
|
|
15
|
-
*
|
|
16
|
-
* History: 5 MB was too low — it silently dropped `esbuild-wasm/esbuild.wasm`
|
|
17
|
-
* (11.35 MB on v0.24.2), which made Nimbus-in-Nimbus `npm run dev` fail with
|
|
18
|
-
* `No such module "esbuild-wasm/esbuild.wasm"` since the missing file caused
|
|
19
|
-
* esbuild's VFS plugin to mark the import `external`, and workerd's LOADER
|
|
20
|
-
* has no entry for that specifier. 20 MB covers esbuild-wasm with headroom
|
|
21
|
-
* while keeping per-facet peak heap bounded for the streaming extractor.
|
|
22
|
-
*/
|
|
23
|
-
export const MAX_FILE_BYTES = 20_000_000;
|
|
24
|
-
/**
|
|
25
|
-
* Read one tar header (USTAR) out of `block`. Returns parsed fields or
|
|
26
|
-
* `null` for an end-of-archive block (all zeros).
|
|
27
|
-
*/
|
|
28
|
-
/**
|
|
29
|
-
* Collapse "."/".." segments in a tar entry's package-relative path.
|
|
30
|
-
* Returns the canonical relative path, or '' when the entry escapes its
|
|
31
|
-
* package root (a leading ".." that pops above the root) — the caller
|
|
32
|
-
* treats '' as a no-name entry and skips it. Mirrors the segment logic in
|
|
33
|
-
* w7-frame's canonicalPath so joined write paths are always accepted.
|
|
34
|
-
*/
|
|
35
|
-
export function canonicalTarName(name) {
|
|
36
|
-
const out = [];
|
|
37
|
-
for (const seg of name.split('/')) {
|
|
38
|
-
if (seg === '..') {
|
|
39
|
-
if (out.length === 0)
|
|
40
|
-
return '';
|
|
41
|
-
out.pop();
|
|
42
|
-
}
|
|
43
|
-
else if (seg !== '' && seg !== '.') {
|
|
44
|
-
out.push(seg);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return out.join('/');
|
|
48
|
-
}
|
|
49
|
-
export function parseTarHeader(block) {
|
|
50
|
-
if (block[0] === 0)
|
|
51
|
-
return null;
|
|
52
|
-
let name = '';
|
|
53
|
-
for (let i = 0; i < 100 && block[i] !== 0; i++) {
|
|
54
|
-
name += String.fromCharCode(block[i]);
|
|
55
|
-
}
|
|
56
|
-
let prefix = '';
|
|
57
|
-
for (let i = 345; i < 500 && block[i] !== 0; i++) {
|
|
58
|
-
prefix += String.fromCharCode(block[i]);
|
|
59
|
-
}
|
|
60
|
-
if (prefix)
|
|
61
|
-
name = prefix + '/' + name;
|
|
62
|
-
// Strip the npm `package/` convention.
|
|
63
|
-
name = name.replace(/^package\//, '');
|
|
64
|
-
// Canonicalize the entry-relative path. npm tarballs legitimately carry
|
|
65
|
-
// entries like "./dist/index.js" (agent-base, http-proxy-agent,
|
|
66
|
-
// protobufjs, ...); left as-is the "./" survives into the VFS write path
|
|
67
|
-
// and the w7-frame writer rejects the noncanonical path, failing the
|
|
68
|
-
// whole shared install wave and dropping shard-mates' completion markers.
|
|
69
|
-
// Collapsing here (the one place entry names are assembled) keeps every
|
|
70
|
-
// downstream join canonical. An entry that escapes its package root via
|
|
71
|
-
// ".." is dropped to '' → skipped as a no-name entry.
|
|
72
|
-
name = canonicalTarName(name);
|
|
73
|
-
let sizeStr = '';
|
|
74
|
-
for (let i = 124; i < 136 && block[i] !== 0; i++) {
|
|
75
|
-
sizeStr += String.fromCharCode(block[i]);
|
|
76
|
-
}
|
|
77
|
-
const size = parseInt(sizeStr.trim(), 8) || 0;
|
|
78
|
-
const typeFlag = block[156];
|
|
79
|
-
return { name, size, typeFlag };
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Wrap a `ReadableStream<Uint8Array>` as an async iterable. Workerd and
|
|
83
|
-
* Node both support `Symbol.asyncIterator` on ReadableStream, but we
|
|
84
|
-
* spell the reader loop out so we don't depend on ambient lib typings.
|
|
85
|
-
*/
|
|
86
|
-
export async function* readableStreamToAsyncIterable(rs) {
|
|
87
|
-
const reader = rs.getReader();
|
|
88
|
-
try {
|
|
89
|
-
while (true) {
|
|
90
|
-
const { value, done } = await reader.read();
|
|
91
|
-
if (done)
|
|
92
|
-
return;
|
|
93
|
-
if (value && value.length > 0)
|
|
94
|
-
yield value;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
finally {
|
|
98
|
-
try {
|
|
99
|
-
reader.releaseLock();
|
|
100
|
-
}
|
|
101
|
-
catch { /* ignore */ }
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Streaming tar extractor.
|
|
106
|
-
*
|
|
107
|
-
* Consumes an async iterable of Uint8Array chunks (the decompressed tar
|
|
108
|
-
* byte stream) and yields one `{ name, data }` entry per regular file,
|
|
109
|
-
* as each file completes.
|
|
110
|
-
*
|
|
111
|
-
* Memory invariant: holds at most one pending file's bytes (≤ MAX_FILE_BYTES)
|
|
112
|
-
* plus a small carry buffer for the tar header being assembled.
|
|
113
|
-
*
|
|
114
|
-
* Skips: symlinks, directories, hardlinks, long-name extensions (PaxHeader),
|
|
115
|
-
* and any file whose declared size exceeds MAX_FILE_BYTES.
|
|
116
|
-
*
|
|
117
|
-
* If `onSkip` is provided, it is invoked for each skipped entry with the
|
|
118
|
-
* name, declared size, and reason code. Callers that need to surface
|
|
119
|
-
* dropped-file warnings to users should pass one; legacy callers that
|
|
120
|
-
* omit the arg still behave exactly as before (silent skip).
|
|
121
|
-
*/
|
|
122
|
-
export async function* streamTarEntries(source, onSkip) {
|
|
123
|
-
let carry = new Uint8Array(0);
|
|
124
|
-
let state = { kind: 'header' };
|
|
125
|
-
function concat(a, b) {
|
|
126
|
-
if (a.length === 0)
|
|
127
|
-
return b;
|
|
128
|
-
if (b.length === 0)
|
|
129
|
-
return a;
|
|
130
|
-
const out = new Uint8Array(a.length + b.length);
|
|
131
|
-
out.set(a, 0);
|
|
132
|
-
out.set(b, a.length);
|
|
133
|
-
return out;
|
|
134
|
-
}
|
|
135
|
-
for await (const chunkRaw of source) {
|
|
136
|
-
let buf = concat(carry, chunkRaw);
|
|
137
|
-
let cursor = 0;
|
|
138
|
-
while (true) {
|
|
139
|
-
if (state.kind === 'header') {
|
|
140
|
-
if (buf.length - cursor < 512)
|
|
141
|
-
break;
|
|
142
|
-
const header = buf.subarray(cursor, cursor + 512);
|
|
143
|
-
const parsed = parseTarHeader(header);
|
|
144
|
-
cursor += 512;
|
|
145
|
-
if (!parsed)
|
|
146
|
-
return; // end-of-archive
|
|
147
|
-
const { name, size, typeFlag } = parsed;
|
|
148
|
-
const pad = size === 0 ? 0 : (512 - (size % 512)) % 512;
|
|
149
|
-
const isRegularFile = (typeFlag === 48 /* '0' */ || typeFlag === 0);
|
|
150
|
-
if (size === 0) {
|
|
151
|
-
if (isRegularFile && name) {
|
|
152
|
-
yield { name, data: new Uint8Array(0) };
|
|
153
|
-
}
|
|
154
|
-
state = { kind: 'header' };
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
if (!isRegularFile || !name || size > MAX_FILE_BYTES) {
|
|
158
|
-
if (onSkip) {
|
|
159
|
-
// Classify before entering the skip state so the reason is
|
|
160
|
-
// exact. Precedence matches the condition order above:
|
|
161
|
-
// non-regular first (directories/symlinks/PaxHeaders are
|
|
162
|
-
// skipped regardless of size), then no-name, then too-large.
|
|
163
|
-
const reason = !isRegularFile
|
|
164
|
-
? 'non-regular'
|
|
165
|
-
: !name
|
|
166
|
-
? 'no-name'
|
|
167
|
-
: 'too-large';
|
|
168
|
-
try {
|
|
169
|
-
onSkip(name, size, reason);
|
|
170
|
-
}
|
|
171
|
-
catch { /* best-effort */ }
|
|
172
|
-
}
|
|
173
|
-
state = { kind: 'skip', remaining: size + pad };
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
state = {
|
|
177
|
-
kind: 'file',
|
|
178
|
-
name,
|
|
179
|
-
remaining: size,
|
|
180
|
-
fileBuf: new Uint8Array(size),
|
|
181
|
-
fileOffset: 0,
|
|
182
|
-
pad,
|
|
183
|
-
skip: false,
|
|
184
|
-
};
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
if (state.kind === 'file') {
|
|
188
|
-
const avail = buf.length - cursor;
|
|
189
|
-
if (avail === 0)
|
|
190
|
-
break;
|
|
191
|
-
if (state.remaining > 0) {
|
|
192
|
-
const take = Math.min(state.remaining, avail);
|
|
193
|
-
state.fileBuf.set(buf.subarray(cursor, cursor + take), state.fileOffset);
|
|
194
|
-
state.fileOffset += take;
|
|
195
|
-
state.remaining -= take;
|
|
196
|
-
cursor += take;
|
|
197
|
-
if (state.remaining > 0)
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
if (state.pad > 0) {
|
|
201
|
-
const avail2 = buf.length - cursor;
|
|
202
|
-
if (avail2 === 0)
|
|
203
|
-
break;
|
|
204
|
-
const take = Math.min(state.pad, avail2);
|
|
205
|
-
state.pad -= take;
|
|
206
|
-
cursor += take;
|
|
207
|
-
if (state.pad > 0)
|
|
208
|
-
break;
|
|
209
|
-
}
|
|
210
|
-
yield { name: state.name, data: state.fileBuf };
|
|
211
|
-
state = { kind: 'header' };
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
// state.kind === 'skip'
|
|
215
|
-
const avail = buf.length - cursor;
|
|
216
|
-
if (avail === 0)
|
|
217
|
-
break;
|
|
218
|
-
const take = Math.min(state.remaining, avail);
|
|
219
|
-
cursor += take;
|
|
220
|
-
state.remaining -= take;
|
|
221
|
-
if (state.remaining > 0)
|
|
222
|
-
break;
|
|
223
|
-
state = { kind: 'header' };
|
|
224
|
-
}
|
|
225
|
-
if (cursor >= buf.length) {
|
|
226
|
-
carry = new Uint8Array(0);
|
|
227
|
-
}
|
|
228
|
-
else if (cursor === 0) {
|
|
229
|
-
carry = buf;
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
carry = buf.slice(cursor);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
package/dist/npm/tarball.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* npm-tarball.ts — streaming tarball extraction (gunzip + tar).
|
|
3
|
-
*
|
|
4
|
-
* `extractTarball` / `extractTarballFromResponse` walk a gzipped tar stream
|
|
5
|
-
* entry-by-entry, holding at most one file's bytes at a time. Used by the
|
|
6
|
-
* install-batch facet (whose own 128 MiB envelope, not the supervisor's,
|
|
7
|
-
* holds the bytes) and the ruby-gems runtime.
|
|
8
|
-
*
|
|
9
|
-
* The legacy supervisor-resident `fetchWaves` / `buildBatchPayload` and the
|
|
10
|
-
* `buildCacheRestorePayload` fast path were removed — they ran in supervisor
|
|
11
|
-
* heap and held tarball bytes long enough to OOM the DO on large installs.
|
|
12
|
-
* The single batch-facet path (install-batch-facet.ts) supersedes them and
|
|
13
|
-
* consults the shared L2/L3 tarball cache directly.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* Streaming extractor driven by a `Response` body.
|
|
17
|
-
*
|
|
18
|
-
* Pipes `resp.body` through `DecompressionStream('gzip')` (npm tarballs are
|
|
19
|
-
* always gzipped) and walks the tar stream entry-by-entry. Never buffers the
|
|
20
|
-
* full decompressed tarball — peak transient heap is one file's bytes plus a
|
|
21
|
-
* small carry buffer.
|
|
22
|
-
*
|
|
23
|
-
* The returned Map is per-file Uint8Arrays. If the response has no body
|
|
24
|
-
* (unusual but possible with some proxies), we fall back to `arrayBuffer()`
|
|
25
|
-
* + `extractTarball` so we still make progress.
|
|
26
|
-
*/
|
|
27
|
-
export declare function extractTarballFromResponse(resp: Response): Promise<Map<string, Uint8Array>>;
|
|
28
|
-
/**
|
|
29
|
-
* Legacy buffered extractor. Kept for code paths that receive a fully-buffered
|
|
30
|
-
* tarball (e.g. the tarball cache restore path, which already stores bytes in
|
|
31
|
-
* SQLite as Uint8Arrays). New install paths use `streamTarEntries` instead.
|
|
32
|
-
*/
|
|
33
|
-
export declare function extractTarball(tarball: ArrayBuffer): Promise<Map<string, Uint8Array>>;
|
|
34
|
-
//# sourceMappingURL=tarball.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tarball.d.ts","sourceRoot":"","sources":["../../src/npm/tarball.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAeH;;;;;;;;;;;GAWG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAmClC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAsBlC"}
|
package/dist/npm/tarball.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* npm-tarball.ts — streaming tarball extraction (gunzip + tar).
|
|
3
|
-
*
|
|
4
|
-
* `extractTarball` / `extractTarballFromResponse` walk a gzipped tar stream
|
|
5
|
-
* entry-by-entry, holding at most one file's bytes at a time. Used by the
|
|
6
|
-
* install-batch facet (whose own 128 MiB envelope, not the supervisor's,
|
|
7
|
-
* holds the bytes) and the ruby-gems runtime.
|
|
8
|
-
*
|
|
9
|
-
* The legacy supervisor-resident `fetchWaves` / `buildBatchPayload` and the
|
|
10
|
-
* `buildCacheRestorePayload` fast path were removed — they ran in supervisor
|
|
11
|
-
* heap and held tarball bytes long enough to OOM the DO on large installs.
|
|
12
|
-
* The single batch-facet path (install-batch-facet.ts) supersedes them and
|
|
13
|
-
* consults the shared L2/L3 tarball cache directly.
|
|
14
|
-
*/
|
|
15
|
-
import { streamTarEntries, readableStreamToAsyncIterable, } from './tarball-stream.js';
|
|
16
|
-
// ── Tarball extraction ──────────────────────────────────────────────────
|
|
17
|
-
//
|
|
18
|
-
// The streaming primitives (parseTarHeader, streamTarEntries,
|
|
19
|
-
// readableStreamToAsyncIterable, MAX_FILE_BYTES) live in
|
|
20
|
-
// ./npm-tarball-stream.ts — a dependency-free leaf so
|
|
21
|
-
// scripts/bundle-facet-workers.mjs can esbuild it into a string the facet
|
|
22
|
-
// pool injects into dynamic workers. Import them directly from that module.
|
|
23
|
-
/**
|
|
24
|
-
* Streaming extractor driven by a `Response` body.
|
|
25
|
-
*
|
|
26
|
-
* Pipes `resp.body` through `DecompressionStream('gzip')` (npm tarballs are
|
|
27
|
-
* always gzipped) and walks the tar stream entry-by-entry. Never buffers the
|
|
28
|
-
* full decompressed tarball — peak transient heap is one file's bytes plus a
|
|
29
|
-
* small carry buffer.
|
|
30
|
-
*
|
|
31
|
-
* The returned Map is per-file Uint8Arrays. If the response has no body
|
|
32
|
-
* (unusual but possible with some proxies), we fall back to `arrayBuffer()`
|
|
33
|
-
* + `extractTarball` so we still make progress.
|
|
34
|
-
*/
|
|
35
|
-
export async function extractTarballFromResponse(resp) {
|
|
36
|
-
const files = new Map();
|
|
37
|
-
const body = resp.body;
|
|
38
|
-
if (!body) {
|
|
39
|
-
// Fallback: no streamable body (shouldn't happen, but handle it).
|
|
40
|
-
const buf = await resp.arrayBuffer();
|
|
41
|
-
return extractTarball(buf);
|
|
42
|
-
}
|
|
43
|
-
// Time-bound the whole extraction to detect hung gunzip streams.
|
|
44
|
-
const controller = new AbortController();
|
|
45
|
-
const timer = setTimeout(() => controller.abort(), 60_000);
|
|
46
|
-
try {
|
|
47
|
-
const decompressed = body.pipeThrough(new DecompressionStream('gzip'));
|
|
48
|
-
const source = readableStreamToAsyncIterable(decompressed);
|
|
49
|
-
for await (const entry of streamTarEntries(source)) {
|
|
50
|
-
if (controller.signal.aborted)
|
|
51
|
-
throw new Error('tarball extract timeout');
|
|
52
|
-
files.set(entry.name, entry.data);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch (e) {
|
|
56
|
-
// On any error, just return whatever we managed to extract. Callers
|
|
57
|
-
// treat `files.size === 0` as a failed fetch and mark the package failed.
|
|
58
|
-
// If partial data is present (some files succeeded before the stream
|
|
59
|
-
// broke), we propagate it; the installer will re-fetch on mismatch.
|
|
60
|
-
if (files.size === 0) {
|
|
61
|
-
clearTimeout(timer);
|
|
62
|
-
throw e;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
finally {
|
|
66
|
-
clearTimeout(timer);
|
|
67
|
-
}
|
|
68
|
-
return files;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Legacy buffered extractor. Kept for code paths that receive a fully-buffered
|
|
72
|
-
* tarball (e.g. the tarball cache restore path, which already stores bytes in
|
|
73
|
-
* SQLite as Uint8Arrays). New install paths use `streamTarEntries` instead.
|
|
74
|
-
*/
|
|
75
|
-
export async function extractTarball(tarball) {
|
|
76
|
-
const files = new Map();
|
|
77
|
-
const raw = new Uint8Array(tarball);
|
|
78
|
-
// Adapter: wrap the single buffer as an async iterable. If gzipped, pipe
|
|
79
|
-
// through DecompressionStream so the streaming parser still sees tar bytes.
|
|
80
|
-
let source;
|
|
81
|
-
if (raw[0] === 0x1f && raw[1] === 0x8b) {
|
|
82
|
-
const rs = new Blob([tarball]).stream().pipeThrough(new DecompressionStream('gzip'));
|
|
83
|
-
source = readableStreamToAsyncIterable(rs);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
source = (async function* () { yield raw; })();
|
|
87
|
-
}
|
|
88
|
-
try {
|
|
89
|
-
for await (const entry of streamTarEntries(source)) {
|
|
90
|
-
files.set(entry.name, entry.data);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
return files;
|
|
95
|
-
}
|
|
96
|
-
return files;
|
|
97
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* clang-runner.ts — compile, link, and execute C programs for Nimbus WASI.
|
|
3
|
-
*
|
|
4
|
-
* Architecture (compile-link-run, two facet calls):
|
|
5
|
-
*
|
|
6
|
-
* compile : clang.wasm + sysroot subset for C includes + user .c
|
|
7
|
-
* → produces .o bytes (returned to supervisor).
|
|
8
|
-
* link : lld.wasm + sysroot subset for link (crt1.o + libc.a)
|
|
9
|
-
* + .o from compile → produces .wasm executable.
|
|
10
|
-
* write : final .wasm flushed to user VFS at the requested path.
|
|
11
|
-
*
|
|
12
|
-
* The filesystem both halves see is the one WASI layer every other
|
|
13
|
-
* non-node runtime uses (wasi-instance.ts), seeded and sealed.
|
|
14
|
-
*
|
|
15
|
-
* Splitting compile and link into separate LOADER calls keeps each
|
|
16
|
-
* call under the empirical loader payload ceiling. Each ships:
|
|
17
|
-
*
|
|
18
|
-
* - compile: 31 MiB clang.wasm + ~1.3 MiB sysroot subset (C includes).
|
|
19
|
-
* - link : 19 MiB lld.wasm + ~0.75 MiB libs + tiny .o.
|
|
20
|
-
*
|
|
21
|
-
* Sysroot subset extraction happens supervisor-side via a small ustar
|
|
22
|
-
* parser. The full sysroot.tar is parsed once when the clang runtime
|
|
23
|
-
* warms for a session; compile/link calls reuse the filtered subsets.
|
|
24
|
-
*
|
|
25
|
-
* Dispatch stays direct: no sleeps, no caller-side retries, and no
|
|
26
|
-
* catch-and-continue around loader failures.
|
|
27
|
-
*/
|
|
28
|
-
import type { RuntimeManifest } from '@nimbus-sh/core/runtime/runtime-manifest.js';
|
|
29
|
-
import type { SqliteVFS } from '@nimbus-sh/core/vfs/sqlite-vfs.js';
|
|
30
|
-
import type { FacetManager } from '../facets/manager.js';
|
|
31
|
-
/** Build the runner factory. Closes over facetMgr + vfs. */
|
|
32
|
-
export declare function makeClangRunnerFactory(deps: {
|
|
33
|
-
facetMgr: FacetManager;
|
|
34
|
-
vfs: SqliteVFS;
|
|
35
|
-
}): (manifest: RuntimeManifest, installRoot: string, binName: string, binKind: string | undefined) => (ctx: any) => Promise<number>;
|
|
36
|
-
export declare const CLANG_RUNNER_PREAMBLE: string;
|
|
37
|
-
//# sourceMappingURL=clang-runner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clang-runner.d.ts","sourceRoot":"","sources":["../../src/runtime/clang-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,KAAK,EAAmB,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AASzD,4DAA4D;AAC5D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,SAAS,CAAC;CAChB,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,KAC7F,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,MAAM,CAAC,CAkThC;AAyjBD,eAAO,MAAM,qBAAqB,QAAiE,CAAC"}
|