@nimbus-sh/core 0.6.0 → 0.8.0

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.
Files changed (96) hide show
  1. package/README.md +47 -26
  2. package/dist/_shared/byte-stream.d.ts +5 -4
  3. package/dist/_shared/byte-stream.d.ts.map +1 -1
  4. package/dist/_shared/real-node-imports.d.ts +7 -0
  5. package/dist/_shared/real-node-imports.d.ts.map +1 -1
  6. package/dist/_shared/real-node-imports.js +8 -0
  7. package/dist/_shared/tarball.d.ts +24 -5
  8. package/dist/_shared/tarball.d.ts.map +1 -1
  9. package/dist/_shared/tarball.js +42 -5
  10. package/dist/_shared/vfs-write-ledger.d.ts.map +1 -1
  11. package/dist/_shared/vfs-write-ledger.js +22 -16
  12. package/dist/runtime/comment-strip.d.ts +32 -29
  13. package/dist/runtime/comment-strip.d.ts.map +1 -1
  14. package/dist/runtime/comment-strip.js +273 -51
  15. package/dist/runtime/cpython-runner.d.ts +1 -0
  16. package/dist/runtime/cpython-runner.d.ts.map +1 -1
  17. package/dist/runtime/cpython-runner.js +1 -1
  18. package/dist/runtime/esbuild-service.d.ts +38 -42
  19. package/dist/runtime/esbuild-service.d.ts.map +1 -1
  20. package/dist/runtime/esbuild-service.js +500 -388
  21. package/dist/runtime/javascript-ast.d.ts.map +1 -1
  22. package/dist/runtime/javascript-ast.js +45 -7
  23. package/dist/runtime/opentui-wasm-backend.d.ts.map +1 -1
  24. package/dist/runtime/opentui-wasm-backend.js +18 -16
  25. package/dist/runtime/port-registry.d.ts +4 -2
  26. package/dist/runtime/port-registry.d.ts.map +1 -1
  27. package/dist/runtime/port-registry.js +60 -8
  28. package/dist/runtime/ruby-runner.d.ts +1 -0
  29. package/dist/runtime/ruby-runner.d.ts.map +1 -1
  30. package/dist/runtime/ruby-runner.js +1 -0
  31. package/dist/shell/stdin-adapter.d.ts +11 -0
  32. package/dist/shell/stdin-adapter.d.ts.map +1 -0
  33. package/dist/shell/stdin-adapter.js +59 -0
  34. package/dist/shell/unix-commands.d.ts +2 -1
  35. package/dist/shell/unix-commands.d.ts.map +1 -1
  36. package/dist/shell/unix-commands.js +1078 -50
  37. package/dist/substrate/lifo/commands/io/dd.js +1 -1
  38. package/dist/substrate/lifo/commands/net/curl.d.ts.map +1 -1
  39. package/dist/substrate/lifo/commands/net/curl.js +270 -54
  40. package/dist/substrate/lifo/commands/system/npm.d.ts +18 -1
  41. package/dist/substrate/lifo/commands/system/npm.d.ts.map +1 -1
  42. package/dist/substrate/lifo/commands/system/npm.js +25 -43
  43. package/dist/substrate/lifo/commands/text/head.d.ts.map +1 -1
  44. package/dist/substrate/lifo/commands/text/head.js +2 -1
  45. package/dist/substrate/lifo/commands/text/sed.d.ts.map +1 -1
  46. package/dist/substrate/lifo/commands/text/sed.js +499 -117
  47. package/dist/substrate/lifo/commands/types.d.ts +8 -4
  48. package/dist/substrate/lifo/commands/types.d.ts.map +1 -1
  49. package/dist/substrate/lifo/node-compat/zlib.d.ts +37 -18
  50. package/dist/substrate/lifo/node-compat/zlib.d.ts.map +1 -1
  51. package/dist/substrate/lifo/node-compat/zlib.js +122 -23
  52. package/dist/substrate/lifo/shell/interpreter.d.ts +9 -1
  53. package/dist/substrate/lifo/shell/interpreter.d.ts.map +1 -1
  54. package/dist/substrate/lifo/shell/interpreter.js +79 -29
  55. package/dist/substrate/lifo/shell/pipe.d.ts +16 -0
  56. package/dist/substrate/lifo/shell/pipe.d.ts.map +1 -1
  57. package/dist/substrate/lifo/shell/pipe.js +62 -18
  58. package/dist/substrate/lifo/shell/terminal-stdin.d.ts +20 -3
  59. package/dist/substrate/lifo/shell/terminal-stdin.d.ts.map +1 -1
  60. package/dist/substrate/lifo/shell/terminal-stdin.js +60 -24
  61. package/dist/vfs/sqlite-vfs.d.ts +19 -0
  62. package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
  63. package/dist/vfs/sqlite-vfs.js +106 -23
  64. package/dist/workspace/nimbus-workspace.d.ts +22 -1
  65. package/dist/workspace/nimbus-workspace.d.ts.map +1 -1
  66. package/dist/workspace/nimbus-workspace.js +19 -3
  67. package/dist/workspace/supervisor-op.d.ts +107 -0
  68. package/dist/workspace/supervisor-op.d.ts.map +1 -0
  69. package/dist/workspace/supervisor-op.js +224 -0
  70. package/package.json +2 -2
  71. package/src/_shared/byte-stream.ts +5 -4
  72. package/src/_shared/real-node-imports.ts +8 -0
  73. package/src/_shared/tarball.ts +60 -5
  74. package/src/_shared/vfs-write-ledger.ts +22 -16
  75. package/src/runtime/comment-strip.ts +218 -52
  76. package/src/runtime/cpython-runner.ts +2 -1
  77. package/src/runtime/esbuild-service.ts +572 -372
  78. package/src/runtime/javascript-ast.ts +40 -9
  79. package/src/runtime/opentui-wasm-backend.ts +19 -17
  80. package/src/runtime/port-registry.ts +66 -8
  81. package/src/runtime/ruby-runner.ts +2 -0
  82. package/src/shell/stdin-adapter.ts +58 -0
  83. package/src/shell/unix-commands.ts +1054 -50
  84. package/src/substrate/lifo/commands/io/dd.ts +2 -2
  85. package/src/substrate/lifo/commands/net/curl.ts +310 -58
  86. package/src/substrate/lifo/commands/system/npm.ts +55 -38
  87. package/src/substrate/lifo/commands/text/head.ts +2 -1
  88. package/src/substrate/lifo/commands/text/sed.ts +519 -109
  89. package/src/substrate/lifo/commands/types.ts +8 -5
  90. package/src/substrate/lifo/node-compat/zlib.ts +155 -26
  91. package/src/substrate/lifo/shell/interpreter.ts +74 -27
  92. package/src/substrate/lifo/shell/pipe.ts +65 -24
  93. package/src/substrate/lifo/shell/terminal-stdin.ts +66 -30
  94. package/src/vfs/sqlite-vfs.ts +104 -23
  95. package/src/workspace/nimbus-workspace.ts +30 -3
  96. package/src/workspace/supervisor-op.ts +309 -0
@@ -1,74 +1,296 @@
1
1
  /**
2
- * Minimal byte-aligned comment stripper for prefetch's import detection.
2
+ * One JavaScript source scanner shared by the two comment-stripping
3
+ * call sites — prefetch's import detection and the esbuild transform
4
+ * pipeline's classifiers.
3
5
  *
4
- * Scope: strip `//` line comments and `/* … *\/` block comments by
5
- * replacing each comment with a single space. Newlines INSIDE the
6
- * comment are preserved so that line numbers stay aligned with the
7
- * input (matches the strip-and-classify pattern used by
8
- * `esbuild-service.ts:stripCommentsAndStrings` for the transform
9
- * pipeline).
6
+ * `scanJsSource(src, literals)` walks `src` once and returns a
7
+ * byte-aligned copy in which `//` and `/* *\/` comments are blanked
8
+ * (each comment becomes a space; newlines inside a block comment are
9
+ * preserved so line numbers still match the input). String, template
10
+ * and regex literals are what `literals` decides:
10
11
  *
11
- * Why a separate, smaller scanner: prefetch's IMPORT_RE / REQUIRE_RE
12
- * in `require-resolver.ts:41,87` are detection-only they extract
13
- * specifier strings, not shapes. The full string-and-template-literal
14
- * stripper in `esbuild-service.ts` is overkill for that, and crossing
15
- * the anti-touch boundary on `esbuild-service.ts` to extend a single
16
- * shared helper isn't worth it right now.
12
+ * - `'blank'`: literal content is replaced too templates keep their
13
+ * `${…}` interpolation expression as code so a depth-tracked caller
14
+ * sees `await` etc. inside it. This is the transform pipeline's
15
+ * classification view: nothing quoted can read as an `import`.
16
+ * - `'keep'`: literals are copied verbatim. This is prefetch's
17
+ * import-detection view: IMPORT_RE/REQUIRE_RE must see the
18
+ * specifier string, and a `//` or `/*` inside a literal must NOT
19
+ * open a comment that swallows a following real import.
17
20
  *
18
- * Empirical justification (esbuild-ast-rewrite wave, P2 measurement):
19
- * - Per-file AST-based extraction: ~5 ms warm avg
20
- * - 100-file session bootstrap with AST: ~553 ms (over the 500 ms gate)
21
- * - Regex with this stripper: ~0.1 ms per file
22
- * - Correctness gap closed: chalk `import { // eslint-disable\n a,\n b\n} from './utilities.js'` now matches
21
+ * The output is assembled from input slices and joined once. It used to
22
+ * be built one character at a time (`stripped += c`), which V8 keeps as
23
+ * a rope of one node per append — ~30 bytes of heap per character, all
24
+ * live until the string is first read. On typescript's 6.15 MB
25
+ * `lib/_tsc.js` that rope measured 174 MB against a 128 MB isolate
26
+ * the session Durable Object was killed inside `tsc`'s spawn before the
27
+ * facet existed. Spans hold the input, the output and a short array.
23
28
  *
24
- * String-literal handling is intentionally OUT of scope. A literal
25
- * `import x from 'y'` inside a JavaScript string would still produce
26
- * a false-positive prefetch attempt. The resolver no-ops on misses,
27
- * so it's a minor wasted-work cost — see IMPORT_RE header comment in
28
- * `require-resolver.ts:84-86`.
29
- *
30
- * TODO(CLN-X): when the `src/runtime/esbuild-service.ts` anti-touch
31
- * window opens, unify with the canonical
32
- * `stripCommentsAndStrings(src)` helper there. Both implement the
33
- * same logical pass over comments; only the string/regex-literal
34
- * handling differs.
29
+ * Serialized by name: `generateEsbuildTransformRuntimeSource` embeds
30
+ * this function's `.toString()` in the transform runtime, so every
31
+ * constant it reads is declared inside the body.
35
32
  */
36
- export function stripCommentsForImports(src) {
37
- let out = '';
33
+ export function scanJsSource(src, literals) {
34
+ const NEWLINE = 0x0a;
35
+ // Identifier-suffix detection: `/` after one of these is division;
36
+ // after anything else (operators, punctuators, keywords, start-of-file)
37
+ // it opens a regex literal. Word chars + `)` + `]` cover `foo()/x` and
38
+ // `a[i]/y`; the quote characters cover `'…' /re/` and `` `…` /re/ ``.
39
+ const DIVISION_AFTER = /[A-Za-z0-9_$\)\]'\"`]/;
40
+ const parts = [];
41
+ // Start of the span not yet copied to `parts`.
42
+ let spanStart = 0;
38
43
  let i = 0;
39
44
  const N = src.length;
45
+ let lastNonWs = '';
46
+ const record = (ch) => {
47
+ if (ch !== ' ' && ch !== '\t' && ch !== '\n' && ch !== '\r')
48
+ lastNonWs = ch;
49
+ };
50
+ // The division/regex discriminator needs the last non-ws char the loop
51
+ // has passed — stepped chars record themselves; spans already landed in
52
+ // `parts` only need their final char re-derived.
53
+ const step = () => { record(src[i]); i++; };
54
+ const copy = (end) => {
55
+ if (end > spanStart)
56
+ parts.push(src.slice(spanStart, end));
57
+ };
58
+ const emit = (ch) => { parts.push(ch); };
59
+ // A shebang is the file's first line and never a comment or a regex —
60
+ // `#!/` at offset 0 is copied whole before the loop sees the `/`.
61
+ if (src.charCodeAt(0) === 0x23 && src.charCodeAt(1) === 0x21) {
62
+ i = 2;
63
+ while (i < N && src.charCodeAt(i) !== NEWLINE)
64
+ i++;
65
+ record('!');
66
+ }
40
67
  while (i < N) {
41
- const c = src[i];
42
- // Line comment: `//` to end-of-line.
43
- if (c === '/' && src[i + 1] === '/') {
44
- out += ' ';
45
- i += 2;
46
- while (i < N && src[i] !== '\n')
68
+ if (src.charCodeAt(i) === 0x2f /* / */) {
69
+ const next = src.charCodeAt(i + 1);
70
+ if (next === 0x2f) {
71
+ // Line comment: to end-of-line, one space. The newline itself is
72
+ // not part of the comment and stays in the next span.
73
+ copy(i);
74
+ i += 2;
75
+ while (i < N && src.charCodeAt(i) !== NEWLINE)
76
+ i++;
77
+ emit(' ');
78
+ spanStart = i;
79
+ continue;
80
+ }
81
+ if (next === 0x2a) {
82
+ // Block comment: replaced by its own newlines plus one space; an
83
+ // unterminated one runs to the end of input and gets no space.
84
+ copy(i);
85
+ i += 2;
86
+ let newlines = 0;
87
+ let closed = false;
88
+ while (i < N) {
89
+ const bc = src.charCodeAt(i);
90
+ if (bc === NEWLINE)
91
+ newlines++;
92
+ else if (bc === 0x2a && src.charCodeAt(i + 1) === 0x2f) {
93
+ i += 2;
94
+ closed = true;
95
+ break;
96
+ }
97
+ i++;
98
+ }
99
+ if (newlines > 0)
100
+ parts.push('\n'.repeat(newlines));
101
+ if (closed)
102
+ emit(' ');
103
+ spanStart = i;
104
+ continue;
105
+ }
106
+ // Regex literal when the previous non-ws char can't end a value.
107
+ if (!DIVISION_AFTER.test(lastNonWs)) {
108
+ // A regex needs its closing `/` on the same line; without one the
109
+ // slash is division (or a lone `/`), and treating the rest of the
110
+ // line as a literal would drop real code — imports included.
111
+ let j = i + 1;
112
+ let closes = false;
113
+ while (j < N) {
114
+ const rc = src.charCodeAt(j);
115
+ if (rc === 0x5c) {
116
+ j += 2;
117
+ continue;
118
+ }
119
+ if (rc === 0x5b) {
120
+ j++;
121
+ while (j < N && src.charCodeAt(j) !== 0x5d) {
122
+ if (src.charCodeAt(j) === 0x5c) {
123
+ j += 2;
124
+ continue;
125
+ }
126
+ j++;
127
+ }
128
+ if (j < N)
129
+ j++;
130
+ continue;
131
+ }
132
+ if (rc === 0x2f) {
133
+ closes = true;
134
+ break;
135
+ }
136
+ if (rc === NEWLINE)
137
+ break;
138
+ j++;
139
+ }
140
+ if (!closes) {
141
+ step();
142
+ continue;
143
+ }
144
+ copy(i);
145
+ emit(' ');
47
146
  i++;
48
- // Newline preserved by falling through; do NOT consume it.
147
+ while (i < N) {
148
+ const rc = src.charCodeAt(i);
149
+ if (rc === 0x5c) {
150
+ i += 2;
151
+ continue;
152
+ }
153
+ if (rc === 0x5b) {
154
+ // Character class: `/` inside it is content.
155
+ i++;
156
+ while (i < N && src.charCodeAt(i) !== 0x5d) {
157
+ if (src.charCodeAt(i) === 0x5c) {
158
+ i += 2;
159
+ continue;
160
+ }
161
+ i++;
162
+ }
163
+ if (i < N)
164
+ i++;
165
+ continue;
166
+ }
167
+ if (rc === 0x2f) {
168
+ i++;
169
+ break;
170
+ }
171
+ i++;
172
+ }
173
+ // Flags: g, i, m, s, u, y, d.
174
+ while (i < N && /[gimsuyd]/.test(src[i]))
175
+ i++;
176
+ record('/');
177
+ spanStart = i;
178
+ continue;
179
+ }
180
+ // Division or a lone slash — plain source.
181
+ step();
49
182
  continue;
50
183
  }
51
- // Block comment: `/*` to `*/`.
52
- if (c === '/' && src[i + 1] === '*') {
53
- i += 2;
54
- while (i < N) {
55
- if (src[i] === '\n') {
56
- // Preserve newlines so line numbers stay aligned.
57
- out += '\n';
184
+ const ch = src[i];
185
+ if (ch === '"' || ch === "'" || ch === '`') {
186
+ if (literals === 'keep') {
187
+ i++;
188
+ while (i < N) {
189
+ const cc = src[i];
190
+ if (cc === '\\') {
191
+ i += 2;
192
+ continue;
193
+ }
194
+ if (cc === ch) {
195
+ i++;
196
+ break;
197
+ }
58
198
  i++;
59
- continue;
60
199
  }
61
- if (src[i] === '*' && src[i + 1] === '/') {
200
+ // The literal ends a value: a following `/` is division.
201
+ record(ch);
202
+ continue;
203
+ }
204
+ // blank: the delimiters and content become one space; a template's
205
+ // `${…}` interpolation keeps its expression as code.
206
+ copy(i);
207
+ emit(' ');
208
+ i++;
209
+ while (i < N) {
210
+ const cc = src[i];
211
+ if (cc === '\\') {
62
212
  i += 2;
63
- out += ' ';
213
+ continue;
214
+ }
215
+ if (cc === ch) {
216
+ i++;
64
217
  break;
65
218
  }
219
+ if (ch === '`' && cc === '$' && src[i + 1] === '{') {
220
+ emit('${');
221
+ i += 2;
222
+ let depth = 1;
223
+ while (i < N && depth > 0) {
224
+ const ic = src[i];
225
+ // Nested string inside the interpolation: blank its content
226
+ // so a `}` inside it doesn't drop the depth early.
227
+ if (ic === '"' || ic === "'" || ic === '`') {
228
+ const iq = ic;
229
+ emit(' ');
230
+ i++;
231
+ while (i < N) {
232
+ const icc = src[i];
233
+ if (icc === '\\') {
234
+ i += 2;
235
+ continue;
236
+ }
237
+ if (icc === iq) {
238
+ i++;
239
+ break;
240
+ }
241
+ // A nested template's own ${…} recurses once more —
242
+ // deeper nesting falls back to brace counting.
243
+ if (iq === '`' && icc === '$' && src[i + 1] === '{') {
244
+ emit('${');
245
+ i += 2;
246
+ let d2 = 1;
247
+ while (i < N && d2 > 0) {
248
+ const i2 = src[i];
249
+ if (i2 === '{')
250
+ d2++;
251
+ else if (i2 === '}')
252
+ d2--;
253
+ if (d2 > 0)
254
+ emit(i2);
255
+ i++;
256
+ }
257
+ emit('}');
258
+ continue;
259
+ }
260
+ if (icc === '\n')
261
+ emit('\n');
262
+ i++;
263
+ }
264
+ continue;
265
+ }
266
+ if (ic === '{')
267
+ depth++;
268
+ else if (ic === '}')
269
+ depth--;
270
+ if (depth > 0)
271
+ emit(ic);
272
+ i++;
273
+ }
274
+ emit('}');
275
+ continue;
276
+ }
277
+ if (cc === '\n')
278
+ emit('\n');
66
279
  i++;
67
280
  }
281
+ spanStart = i;
68
282
  continue;
69
283
  }
70
- out += c;
71
- i++;
284
+ step();
72
285
  }
73
- return out;
286
+ copy(N);
287
+ return parts.join('');
288
+ }
289
+ /**
290
+ * Strip comments for import/require detection. Literals are kept: the
291
+ * specifier the regexes extract lives inside a string, and a comment
292
+ * marker inside a string must not swallow the code that follows it.
293
+ */
294
+ export function stripCommentsForImports(src) {
295
+ return scanJsSource(src, 'keep');
74
296
  }
@@ -71,6 +71,7 @@ export interface CPythonFacetResult {
71
71
  * that has none does not get a degraded version — it gets none, and says so.
72
72
  */
73
73
  export type CPythonResidentStart = (spawn: {
74
+ argv: string[];
74
75
  /** VFS path of the interpreter. By path, not by value: it is 10.6 MiB. */
75
76
  wasmVfsPath: string;
76
77
  startArgs: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"cpython-runner.d.ts","sourceRoot":"","sources":["../../src/runtime/cpython-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,qCAAqC,CAAC;AAEnF,OAAO,KAAK,EAAmB,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAKvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AASjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAsB7D;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAkFD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsCD;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE;IACzC,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAElC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,SAAS,CAAC;IACf,iFAAiF;IACjF,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,KAC7F,OAAO,CAkQV"}
1
+ {"version":3,"file":"cpython-runner.d.ts","sourceRoot":"","sources":["../../src/runtime/cpython-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,qCAAqC,CAAC;AAEnF,OAAO,KAAK,EAAmB,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAKvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AASjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAsB7D;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAkFD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsCD;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE;IACzC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAElC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,SAAS,CAAC;IACf,iFAAiF;IACjF,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC,GAAG,CAAC,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,KAC7F,OAAO,CAkQV"}
@@ -391,7 +391,7 @@ export function makeCPythonRunnerFactory(deps) {
391
391
  return 1;
392
392
  }
393
393
  const command = [binName, ...argv].map((part) => (/^[A-Za-z0-9_./:=@+-]+$/.test(part) ? part : JSON.stringify(part))).join(' ');
394
- const spawnResult = await deps.startResident({ wasmVfsPath: wasmVfs, startArgs: facetArgs, cwd, command });
394
+ const spawnResult = await deps.startResident({ wasmVfsPath: wasmVfs, startArgs: facetArgs, cwd, command, argv: [binName, ...argv] });
395
395
  if (spawnResult.stdout)
396
396
  ctx.stdout.write(spawnResult.stdout);
397
397
  if (spawnResult.stderr)
@@ -16,7 +16,7 @@
16
16
  * this is acceptable for Phase 3. Phase 4+ can move it to a dedicated
17
17
  * facet once wasm module passing to dynamic workers is stable.
18
18
  */
19
- import type { SqliteVFS } from '../vfs/sqlite-vfs.js';
19
+ import type { CredentialedVfs } from '../vfs/sqlite-vfs.js';
20
20
  /**
21
21
  * Bundler version tag. BUMP THIS whenever bundling semantics change —
22
22
  * the esbuild plugin's resolver logic, the shared-externals rules, the
@@ -49,7 +49,7 @@ import type { SqliteVFS } from '../vfs/sqlite-vfs.js';
49
49
  * rows hold post-rewrite text and must be re-bundled. user_module_
50
50
  * transforms is likewise re-keyed by mount base.
51
51
  */
52
- export declare const BUNDLER_VERSION = "v8";
52
+ export declare const BUNDLER_VERSION = "v9";
53
53
  /**
54
54
  * Returns the list of specifiers that must be marked `external` when bundling
55
55
  * `specifier` so that React / React-DOM / Scheduler share a single instance
@@ -72,35 +72,38 @@ export declare const BUNDLER_VERSION = "v8";
72
72
  */
73
73
  export declare function getSharedRuntimeExternals(specifier: string): string[];
74
74
  /**
75
- * Detect top-level await in source. Used by `EsbuildService.transform`
76
- * to decide whether to async-IIFE-wrap CJS-target sources (see
77
- * transform()'s header comment).
78
- *
79
- * Token scan over a comment-and-string-stripped source. Tracks paren
80
- * depth AND function-body depth so a `{` inside a parameter list (a
81
- * default-value object literal — `async function f(opts = {})`) is NOT
82
- * mistaken for the function body. The earlier heuristic lacked the paren
83
- * guard: the `= {}` braces consumed the body-tracking slot, leaving the
84
- * real body untracked so an internal `await` read as top-level. That
85
- * wrongly routed such files (e.g. @bluwy/giget-core's
86
- * download-template.js, reached by create-astro) into the two-pass
87
- * ESM→require rewrite, whose assembled output still carried export/import
88
- * statements → "Cannot use import statement outside a module" at startup.
75
+ * Converts bundler-emitted ESM without constructing an AST or loading
76
+ * esbuild-wasm. Returns null for module declarations that are not the compact,
77
+ * semicolon-terminated shapes emitted by current JS bundlers.
78
+ */
79
+ export declare function rewriteBundledEsmToCjs(source: string, absoluteUrl: string): TransformResult | null;
80
+ import type * as esbuild from 'esbuild-wasm/esm/browser.js';
81
+ /**
82
+ * Load the esbuild-wasm namespace. Safe to call many times; concurrent
83
+ * callers share a single in-flight Promise, and a rejection clears the
84
+ * cache so a later call can retry.
89
85
  *
90
- * Arrow bodies are distinguished from arrow expression bodies (the
91
- * `arrowPending` flag): only a `{` immediately following `=>` opens a
92
- * function scope. The idiomatic object-returning arrow `x => ({ ... })`
93
- * has its `{` at parenDepth 1, so it opens no body slot — otherwise the
94
- * leaked slot would be consumed by a later top-level `{ ... }` block,
95
- * making a real top-level `await` inside it read as non-TLA (false
96
- * negative) and routing genuine ESM-with-TLA into the wrong transform.
86
+ * Exported so `tests/unit/esbuild-wasm-entrypoint.mjs` can drive the real
87
+ * specifier under a Node-style resolver. A test that restated the specifier
88
+ * would grade its own copy of it, and this defect reached production
89
+ * precisely because nothing graded the resolution.
97
90
  *
98
- * A regex/token scan (not acorn) is kept here deliberately: pulling
99
- * acorn into the esbuild-service bundle chunk duplicates its ~15 KiB
100
- * Unicode identifier tables.
91
+ * The specifier stays a literal: a computed one would defeat the host
92
+ * bundler's static analysis and leave the module out of the deployed worker.
101
93
  */
102
- export declare function hasTopLevelAwait(src: string): boolean;
103
- import type * as esbuild from 'esbuild-wasm';
94
+ export declare function loadEsbuild(): Promise<typeof esbuild>;
95
+ export interface EsbuildTransformOptions {
96
+ loader?: 'ts' | 'tsx' | 'jsx' | 'js' | 'css' | 'json';
97
+ format?: 'esm' | 'cjs' | 'iife';
98
+ target?: string;
99
+ sourcemap?: boolean | 'inline' | 'external';
100
+ minify?: boolean;
101
+ jsx?: 'transform' | 'preserve' | 'automatic';
102
+ jsxFactory?: string;
103
+ jsxFragment?: string;
104
+ tsconfigRaw?: string;
105
+ define?: Record<string, string>;
106
+ }
104
107
  export interface TransformResult {
105
108
  code: string;
106
109
  map: string;
@@ -124,13 +127,16 @@ export interface BuildResult {
124
127
  location?: esbuild.Location | null;
125
128
  }[];
126
129
  }
130
+ /** Source needed by the slim Worker Loader transform isolate. */
131
+ export declare function generateEsbuildTransformRuntimeSource(): string;
127
132
  export declare class EsbuildService {
128
133
  private vfs;
129
134
  private initialized;
130
135
  private initPromise;
131
136
  /** Resolved esbuild namespace — populated by ensureInit() after loadEsbuild(). */
132
137
  private _esbuild;
133
- constructor(vfs: SqliteVFS);
138
+ /** Build reads use only the caller-supplied view; omit it for transform-only use. */
139
+ constructor(vfs?: CredentialedVfs);
134
140
  /**
135
141
  * Initialize esbuild-wasm (lazy, on first use). Loads the namespace
136
142
  * via `loadEsbuild()` (which itself is deferred) and caches it on
@@ -201,18 +207,7 @@ export declare class EsbuildService {
201
207
  * This is bytes-stable for sources outside the TLA+ESM-imports
202
208
  * intersection.
203
209
  */
204
- transform(code: string, options?: {
205
- loader?: 'ts' | 'tsx' | 'jsx' | 'js' | 'css' | 'json';
206
- format?: 'esm' | 'cjs' | 'iife';
207
- target?: string;
208
- sourcemap?: boolean | 'inline' | 'external';
209
- minify?: boolean;
210
- jsx?: 'transform' | 'preserve' | 'automatic';
211
- jsxFactory?: string;
212
- jsxFragment?: string;
213
- tsconfigRaw?: string;
214
- define?: Record<string, string>;
215
- }): Promise<TransformResult>;
210
+ transform(code: string, options?: EsbuildTransformOptions): Promise<TransformResult>;
216
211
  /**
217
212
  * Bundle entry points from the VFS.
218
213
  */
@@ -232,9 +227,10 @@ export declare class EsbuildService {
232
227
  alias?: Record<string, string>;
233
228
  keepNames?: boolean;
234
229
  }): Promise<BuildResult>;
230
+ private requireVfs;
235
231
  /**
236
232
  * VFS resolver plugin for esbuild.
237
- * Reads directly from the SqliteVFS (synchronous, co-located — no snapshot needed).
233
+ * Reads through the caller's credentialed view (synchronous, no snapshot needed).
238
234
  * Handles: absolute paths, relative paths, bare specifiers (node_modules).
239
235
  */
240
236
  private makeVfsPlugin;
@@ -1 +1 @@
1
- {"version":3,"file":"esbuild-service.d.ts","sourceRoot":"","sources":["../../src/runtime/esbuild-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"esbuild-service.d.ts","sourceRoot":"","sources":["../../src/runtime/esbuild-service.ts"],"names":[],"mappings":"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"}