@nimbus-sh/core 0.6.0 → 0.7.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.
- package/README.md +47 -26
- package/dist/_shared/byte-stream.d.ts +5 -4
- package/dist/_shared/byte-stream.d.ts.map +1 -1
- package/dist/_shared/real-node-imports.d.ts +7 -0
- package/dist/_shared/real-node-imports.d.ts.map +1 -1
- package/dist/_shared/real-node-imports.js +8 -0
- package/dist/_shared/tarball.d.ts +23 -5
- package/dist/_shared/tarball.d.ts.map +1 -1
- package/dist/_shared/tarball.js +38 -5
- package/dist/_shared/vfs-write-ledger.d.ts.map +1 -1
- package/dist/_shared/vfs-write-ledger.js +22 -16
- package/dist/runtime/comment-strip.d.ts +0 -35
- package/dist/runtime/comment-strip.d.ts.map +1 -1
- package/dist/runtime/comment-strip.js +48 -20
- package/dist/runtime/esbuild-service.d.ts +38 -42
- package/dist/runtime/esbuild-service.d.ts.map +1 -1
- package/dist/runtime/esbuild-service.js +494 -197
- package/dist/runtime/javascript-ast.d.ts.map +1 -1
- package/dist/runtime/javascript-ast.js +45 -7
- package/dist/runtime/opentui-wasm-backend.d.ts.map +1 -1
- package/dist/runtime/opentui-wasm-backend.js +18 -16
- package/dist/runtime/port-registry.d.ts +4 -2
- package/dist/runtime/port-registry.d.ts.map +1 -1
- package/dist/runtime/port-registry.js +60 -8
- package/dist/shell/stdin-adapter.d.ts +11 -0
- package/dist/shell/stdin-adapter.d.ts.map +1 -0
- package/dist/shell/stdin-adapter.js +59 -0
- package/dist/shell/unix-commands.d.ts +2 -1
- package/dist/shell/unix-commands.d.ts.map +1 -1
- package/dist/shell/unix-commands.js +1078 -50
- package/dist/substrate/lifo/commands/io/dd.js +1 -1
- package/dist/substrate/lifo/commands/net/curl.d.ts.map +1 -1
- package/dist/substrate/lifo/commands/net/curl.js +270 -54
- package/dist/substrate/lifo/commands/system/npm.d.ts +18 -1
- package/dist/substrate/lifo/commands/system/npm.d.ts.map +1 -1
- package/dist/substrate/lifo/commands/system/npm.js +26 -43
- package/dist/substrate/lifo/commands/text/head.d.ts.map +1 -1
- package/dist/substrate/lifo/commands/text/head.js +2 -1
- package/dist/substrate/lifo/commands/text/sed.d.ts.map +1 -1
- package/dist/substrate/lifo/commands/text/sed.js +499 -117
- package/dist/substrate/lifo/commands/types.d.ts +8 -4
- package/dist/substrate/lifo/commands/types.d.ts.map +1 -1
- package/dist/substrate/lifo/node-compat/zlib.d.ts +37 -18
- package/dist/substrate/lifo/node-compat/zlib.d.ts.map +1 -1
- package/dist/substrate/lifo/node-compat/zlib.js +122 -23
- package/dist/substrate/lifo/shell/interpreter.d.ts +9 -1
- package/dist/substrate/lifo/shell/interpreter.d.ts.map +1 -1
- package/dist/substrate/lifo/shell/interpreter.js +79 -29
- package/dist/substrate/lifo/shell/pipe.d.ts +16 -0
- package/dist/substrate/lifo/shell/pipe.d.ts.map +1 -1
- package/dist/substrate/lifo/shell/pipe.js +62 -18
- package/dist/substrate/lifo/shell/terminal-stdin.d.ts +20 -3
- package/dist/substrate/lifo/shell/terminal-stdin.d.ts.map +1 -1
- package/dist/substrate/lifo/shell/terminal-stdin.js +60 -24
- package/dist/vfs/sqlite-vfs.d.ts +19 -0
- package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
- package/dist/vfs/sqlite-vfs.js +106 -23
- package/dist/workspace/nimbus-workspace.d.ts +15 -0
- package/dist/workspace/nimbus-workspace.d.ts.map +1 -1
- package/dist/workspace/nimbus-workspace.js +20 -3
- package/dist/workspace/supervisor-op.d.ts +23 -0
- package/dist/workspace/supervisor-op.d.ts.map +1 -0
- package/dist/workspace/supervisor-op.js +92 -0
- package/package.json +2 -2
- package/src/_shared/byte-stream.ts +5 -4
- package/src/_shared/real-node-imports.ts +8 -0
- package/src/_shared/tarball.ts +56 -5
- package/src/_shared/vfs-write-ledger.ts +22 -16
- package/src/runtime/comment-strip.ts +42 -23
- package/src/runtime/esbuild-service.ts +566 -217
- package/src/runtime/javascript-ast.ts +40 -9
- package/src/runtime/opentui-wasm-backend.ts +19 -17
- package/src/runtime/port-registry.ts +66 -8
- package/src/shell/stdin-adapter.ts +58 -0
- package/src/shell/unix-commands.ts +1054 -50
- package/src/substrate/lifo/commands/io/dd.ts +2 -2
- package/src/substrate/lifo/commands/net/curl.ts +310 -58
- package/src/substrate/lifo/commands/system/npm.ts +58 -38
- package/src/substrate/lifo/commands/text/head.ts +2 -1
- package/src/substrate/lifo/commands/text/sed.ts +519 -109
- package/src/substrate/lifo/commands/types.ts +8 -5
- package/src/substrate/lifo/node-compat/zlib.ts +155 -26
- package/src/substrate/lifo/shell/interpreter.ts +74 -27
- package/src/substrate/lifo/shell/pipe.ts +65 -24
- package/src/substrate/lifo/shell/terminal-stdin.ts +66 -30
- package/src/vfs/sqlite-vfs.ts +104 -23
- package/src/workspace/nimbus-workspace.ts +26 -2
- package/src/workspace/supervisor-op.ts +117 -0
package/README.md
CHANGED
|
@@ -5,16 +5,23 @@
|
|
|
5
5
|
> presented as-is.
|
|
6
6
|
|
|
7
7
|
The backend-agnostic half of Nimbus: a durable POSIX-like filesystem, a shell
|
|
8
|
-
with 60+ Unix commands, and the WASI runtime layer
|
|
9
|
-
dependency.
|
|
10
|
-
Cloudflare that SQLite is `ctx.storage.sql` inside your Durable Object; in bun
|
|
11
|
-
or node it is `bun:sqlite` or `node:sqlite`.
|
|
8
|
+
with 60+ Unix commands, and the WASI runtime layer. It has no Cloudflare
|
|
9
|
+
dependency.
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
You hand it a SQLite and get back `.fs` and `.exec`. On Cloudflare that
|
|
12
|
+
SQLite is `ctx.storage.sql` inside your Durable Object; in bun or node it is
|
|
13
|
+
`bun:sqlite` or `node:sqlite`. The whole package rests on two narrow ports
|
|
14
|
+
(`SqlDatabase` and `SqlTransactions`), so the same code serves both hosts.
|
|
15
|
+
|
|
16
|
+
Use it when something you already run needs a real workspace. A Durable
|
|
17
|
+
Object that does something else and needs somewhere to work. A local script
|
|
18
|
+
that needs the filesystem semantics the hosted product has.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @nimbus-sh/core
|
|
24
|
+
```
|
|
18
25
|
|
|
19
26
|
## Quick start
|
|
20
27
|
|
|
@@ -73,13 +80,13 @@ export class Workspace extends DurableObject {
|
|
|
73
80
|
```
|
|
74
81
|
|
|
75
82
|
Files written through `.fs` are owned by the session user (uid 1000), not
|
|
76
|
-
root
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
root. The shell enforces the same permission model either way: a root-owned
|
|
84
|
+
`/etc/passwd` refuses a write from `.fs`, and `id` resolves names through
|
|
85
|
+
it.
|
|
79
86
|
|
|
80
87
|
## Real runtimes, off Cloudflare
|
|
81
88
|
|
|
82
|
-
The wasm runtimes are separate npm packages so nobody downloads a Python
|
|
89
|
+
The wasm runtimes are separate npm packages, so nobody downloads a Python
|
|
83
90
|
interpreter to get a filesystem. Install the ones you want and pass them in:
|
|
84
91
|
|
|
85
92
|
```bash
|
|
@@ -104,35 +111,49 @@ await ws.exec(`python -c "import sqlite3; print('live')"`); // CPython 3.13, re
|
|
|
104
111
|
`@nimbus-sh/runtime-ruby` (Ruby 3.3) and `@nimbus-sh/runtime-clang` (clang →
|
|
105
112
|
`wasm32-wasi`, compile and run C in the workspace) work the same way. Every
|
|
106
113
|
package carries the same manifest and the same sha256-verified blobs the
|
|
107
|
-
hosted product serves from R2
|
|
114
|
+
hosted product serves from R2.
|
|
115
|
+
|
|
116
|
+
Without `facets` and `runtimes` you still get the full shell and coreutils.
|
|
117
|
+
The wasm runtimes are a dependency you add.
|
|
108
118
|
|
|
109
|
-
|
|
110
|
-
the wasm runtimes are a dependency you add, not a mode you enable. One caveat:
|
|
111
|
-
`localFacetHost()` covers bun and node only — on workerd the CSP forbids
|
|
119
|
+
`localFacetHost()` covers bun and node only. On workerd the CSP forbids
|
|
112
120
|
request-time `WebAssembly.instantiate`, so wasm has to ride the Worker Loader
|
|
113
|
-
module map
|
|
114
|
-
`@nimbus-sh/fabric
|
|
121
|
+
module map. That machinery lives in `@nimbus-sh/worker` and
|
|
122
|
+
`@nimbus-sh/fabric`. The shell, coreutils, and filesystem need none of it.
|
|
115
123
|
|
|
116
124
|
## Sharing a database with your own app
|
|
117
125
|
|
|
118
|
-
The workspace is
|
|
119
|
-
of it:
|
|
126
|
+
The workspace is a tenant in a database you own:
|
|
120
127
|
|
|
121
128
|
- It creates and touches only its own tables (`inodes`, `file_chunks`,
|
|
122
129
|
`content_lifecycle`, `vfs_*`).
|
|
123
|
-
- `destroy()` drops
|
|
130
|
+
- `destroy()` drops those tables and does not call `deleteAll()`.
|
|
124
131
|
- `transactionSync` must be a real transaction. An implementation that only
|
|
125
132
|
calls the callback turns every atomic write into a torn one.
|
|
126
|
-
- `generation` must never repeat across restarts of your host
|
|
133
|
+
- `generation` must never repeat across restarts of your host. Pids derive
|
|
127
134
|
from it, and a repeated generation would hand a dead process live write
|
|
128
135
|
authority.
|
|
129
136
|
|
|
130
|
-
|
|
137
|
+
When your own SQL rows must commit with filesystem bytes, use
|
|
138
|
+
`SqliteVFS.withTransaction(callback)` instead of an outer
|
|
139
|
+
`storage.transactionSync`. Use the credentialed synchronous VFS methods inside
|
|
140
|
+
the callback, not the workspace's asynchronous file methods. The callback can
|
|
141
|
+
read its writes; revisions and watch events publish only after commit. On
|
|
142
|
+
rollback, Nimbus clears cached chunks and reloads the always-resident inode
|
|
143
|
+
tree from SQLite before rethrowing with the original error as `cause`.
|
|
144
|
+
|
|
145
|
+
The method must own the outermost transaction on the same SQL host. Do not
|
|
146
|
+
nest it or start asynchronous work inside it. The host's transaction primitive
|
|
147
|
+
must support nested savepoints for individual VFS writes. If rollback reload
|
|
148
|
+
also fails, Nimbus throws an `AggregateError` carrying both failures; discard
|
|
149
|
+
that VFS instance and reopen it after storage recovers.
|
|
150
|
+
|
|
151
|
+
## What the worker package adds
|
|
131
152
|
|
|
132
153
|
Resident processes (long-running servers, attached TUIs), the session
|
|
133
154
|
protocol, port routing to the public internet, and the hosted terminal all
|
|
134
|
-
live in [`@nimbus-sh/worker`](https://www.npmjs.com/package/@nimbus-sh/worker)
|
|
135
|
-
|
|
155
|
+
live in [`@nimbus-sh/worker`](https://www.npmjs.com/package/@nimbus-sh/worker).
|
|
156
|
+
That package composes on this one. If you want the full hosted product shape,
|
|
136
157
|
start from `npx create-nimbus-app`.
|
|
137
158
|
|
|
138
159
|
## License
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
/**
|
|
18
18
|
* A command's output destination.
|
|
19
19
|
*
|
|
20
|
-
* `writeBytes` is present on sinks that store bytes verbatim
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* fallback: a terminal has no way to hold a byte that is
|
|
20
|
+
* `writeBytes` is present on sinks that store bytes verbatim — files,
|
|
21
|
+
* `/dev/null`, and shell pipes, which carry the producer's exact bytes.
|
|
22
|
+
* Sinks without it take decoded text instead. This is a real capability
|
|
23
|
+
* difference, not a fallback: a terminal has no way to hold a byte that is
|
|
24
|
+
* not text.
|
|
24
25
|
*/
|
|
25
26
|
export interface ByteSink {
|
|
26
27
|
write(text: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"byte-stream.d.ts","sourceRoot":"","sources":["../../src/_shared/byte-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH
|
|
1
|
+
{"version":3,"file":"byte-stream.d.ts","sourceRoot":"","sources":["../../src/_shared/byte-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CACtC;AAED,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,UAAU,CAAC;AAEzE,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,QAAY,CAAC;AAE5C;;;;GAIG;AACH,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,OAAO,CAAK;gBAES,IAAI,EAAE,QAAQ;IAI3C,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAO9B,GAAG,IAAI,IAAI;CAKZ;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACvE,MAAM,CAkBR"}
|
|
@@ -38,6 +38,13 @@
|
|
|
38
38
|
* constructed Session's connect/post are inert.
|
|
39
39
|
* Tools (e.g. nuxi) that open a Session purely
|
|
40
40
|
* for optional profiling degrade cleanly.
|
|
41
|
+
* - node:zlib — full surface: every *Sync variant, brotli/zstd,
|
|
42
|
+
* crc32, constants, and streaming create* factories
|
|
43
|
+
* (probe-verified 2026-08-23 at compat date
|
|
44
|
+
* 2026-04-01). Forwarded verbatim by the zlib
|
|
45
|
+
* block in node-shims.ts; results are the host
|
|
46
|
+
* realm's own Buffers, which the widened
|
|
47
|
+
* __BufferMod.isBuffer recognizes.
|
|
41
48
|
*/
|
|
42
49
|
export declare function getRealNodeImportsCode(): string;
|
|
43
50
|
//# sourceMappingURL=real-node-imports.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"real-node-imports.d.ts","sourceRoot":"","sources":["../../src/_shared/real-node-imports.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"real-node-imports.d.ts","sourceRoot":"","sources":["../../src/_shared/real-node-imports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,wBAAgB,sBAAsB,IAAI,MAAM,CAW/C"}
|
|
@@ -38,6 +38,13 @@
|
|
|
38
38
|
* constructed Session's connect/post are inert.
|
|
39
39
|
* Tools (e.g. nuxi) that open a Session purely
|
|
40
40
|
* for optional profiling degrade cleanly.
|
|
41
|
+
* - node:zlib — full surface: every *Sync variant, brotli/zstd,
|
|
42
|
+
* crc32, constants, and streaming create* factories
|
|
43
|
+
* (probe-verified 2026-08-23 at compat date
|
|
44
|
+
* 2026-04-01). Forwarded verbatim by the zlib
|
|
45
|
+
* block in node-shims.ts; results are the host
|
|
46
|
+
* realm's own Buffers, which the widened
|
|
47
|
+
* __BufferMod.isBuffer recognizes.
|
|
41
48
|
*/
|
|
42
49
|
export function getRealNodeImportsCode() {
|
|
43
50
|
return `
|
|
@@ -48,5 +55,6 @@ import * as __real_diagnostics_channel from 'node:diagnostics_channel';
|
|
|
48
55
|
import * as __real_repl from 'node:repl';
|
|
49
56
|
import * as __real_vm from 'node:vm';
|
|
50
57
|
import * as __real_inspector from 'node:inspector';
|
|
58
|
+
import * as __real_zlib from 'node:zlib';
|
|
51
59
|
`.trim();
|
|
52
60
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Tarball extraction for streaming installers and buffered archive consumers.
|
|
3
3
|
*
|
|
4
4
|
* The streaming primitives it walks with (`parseTarHeader`, `streamTarEntries`,
|
|
5
5
|
* `readableStreamToAsyncIterable`) live in `./tarball-stream.ts` — a
|
|
@@ -7,11 +7,29 @@
|
|
|
7
7
|
* into a string the loader pool injects into dynamic workers, where an import
|
|
8
8
|
* would not resolve.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* once. An installer streaming a tarball it is still downloading should drive
|
|
13
|
-
* `streamTarEntries` itself and never hold the whole thing.
|
|
10
|
+
* Installers use writeTarballStream. extractTarball retains a map for callers
|
|
11
|
+
* such as gem install, which must open an archive nested inside another one.
|
|
14
12
|
*/
|
|
13
|
+
export interface TarballWriteTarget {
|
|
14
|
+
exists(path: string): boolean;
|
|
15
|
+
mkdir(path: string, options?: {
|
|
16
|
+
recursive?: boolean;
|
|
17
|
+
}): void;
|
|
18
|
+
writeFile(path: string, data: Uint8Array | string): unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface TarballWriteResult {
|
|
21
|
+
/** Regular files written, including the manifest. */
|
|
22
|
+
files: number;
|
|
23
|
+
/** Total decompressed bytes written. */
|
|
24
|
+
bytes: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Stream a gzipped npm archive into a package directory. Entry names are
|
|
28
|
+
* already canonical and prefix-stripped by streamTarEntries. Hold only the
|
|
29
|
+
* current entry and the manifest; write the manifest last so a failed install
|
|
30
|
+
* is not mistaken for a complete package on retry. Filesystem failures reject.
|
|
31
|
+
*/
|
|
32
|
+
export declare function writeTarballStream(body: ReadableStream<Uint8Array>, targetDir: string, vfs: TarballWriteTarget): Promise<TarballWriteResult>;
|
|
15
33
|
/** Extract every regular file. Gzipped input is decompressed first. */
|
|
16
34
|
export declare function extractTarball(tarball: ArrayBuffer): Promise<Map<string, Uint8Array>>;
|
|
17
35
|
//# sourceMappingURL=tarball.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tarball.d.ts","sourceRoot":"","sources":["../../src/_shared/tarball.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tarball.d.ts","sourceRoot":"","sources":["../../src/_shared/tarball.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;CAC7D;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,EAChC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAED,uEAAuE;AACvE,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAsBlC"}
|
package/dist/_shared/tarball.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Tarball extraction for streaming installers and buffered archive consumers.
|
|
3
3
|
*
|
|
4
4
|
* The streaming primitives it walks with (`parseTarHeader`, `streamTarEntries`,
|
|
5
5
|
* `readableStreamToAsyncIterable`) live in `./tarball-stream.ts` — a
|
|
@@ -7,12 +7,45 @@
|
|
|
7
7
|
* into a string the loader pool injects into dynamic workers, where an import
|
|
8
8
|
* would not resolve.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* once. An installer streaming a tarball it is still downloading should drive
|
|
13
|
-
* `streamTarEntries` itself and never hold the whole thing.
|
|
10
|
+
* Installers use writeTarballStream. extractTarball retains a map for callers
|
|
11
|
+
* such as gem install, which must open an archive nested inside another one.
|
|
14
12
|
*/
|
|
15
13
|
import { streamTarEntries, readableStreamToAsyncIterable, } from './tarball-stream.js';
|
|
14
|
+
const PACKAGE_MANIFEST = 'package.json';
|
|
15
|
+
/**
|
|
16
|
+
* Stream a gzipped npm archive into a package directory. Entry names are
|
|
17
|
+
* already canonical and prefix-stripped by streamTarEntries. Hold only the
|
|
18
|
+
* current entry and the manifest; write the manifest last so a failed install
|
|
19
|
+
* is not mistaken for a complete package on retry. Filesystem failures reject.
|
|
20
|
+
*/
|
|
21
|
+
export async function writeTarballStream(body, targetDir, vfs) {
|
|
22
|
+
const ensureDir = (path) => {
|
|
23
|
+
if (!vfs.exists(path))
|
|
24
|
+
vfs.mkdir(path, { recursive: true });
|
|
25
|
+
};
|
|
26
|
+
ensureDir(targetDir);
|
|
27
|
+
let files = 0;
|
|
28
|
+
let bytes = 0;
|
|
29
|
+
let manifest = null;
|
|
30
|
+
const entries = streamTarEntries(readableStreamToAsyncIterable(body.pipeThrough(new DecompressionStream('gzip'))));
|
|
31
|
+
for await (const entry of entries) {
|
|
32
|
+
if (entry.name === PACKAGE_MANIFEST) {
|
|
33
|
+
manifest = entry.data;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const fullPath = `${targetDir}/${entry.name}`;
|
|
37
|
+
const cut = fullPath.lastIndexOf('/');
|
|
38
|
+
if (cut > 0)
|
|
39
|
+
ensureDir(fullPath.slice(0, cut));
|
|
40
|
+
await vfs.writeFile(fullPath, entry.data);
|
|
41
|
+
files++;
|
|
42
|
+
bytes += entry.data.length;
|
|
43
|
+
}
|
|
44
|
+
if (!manifest)
|
|
45
|
+
throw new Error(`tarball for ${targetDir} carried no ${PACKAGE_MANIFEST}`);
|
|
46
|
+
await vfs.writeFile(`${targetDir}/${PACKAGE_MANIFEST}`, manifest);
|
|
47
|
+
return { files: files + 1, bytes: bytes + manifest.length };
|
|
48
|
+
}
|
|
16
49
|
/** Extract every regular file. Gzipped input is decompressed first. */
|
|
17
50
|
export async function extractTarball(tarball) {
|
|
18
51
|
const files = new Map();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vfs-write-ledger.d.ts","sourceRoot":"","sources":["../../src/_shared/vfs-write-ledger.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,+BAA+B,
|
|
1
|
+
{"version":3,"file":"vfs-write-ledger.d.ts","sourceRoot":"","sources":["../../src/_shared/vfs-write-ledger.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,+BAA+B,QA2ZpC,CAAC;AAET,eAAO,MAAM,uBAAuB,QAgC5B,CAAC"}
|
|
@@ -317,26 +317,32 @@ async function __nimbusPersistVfsWrite(supervisor, path, content, snapshot) {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
/**
|
|
320
|
-
* Write back
|
|
320
|
+
* Write back the cells parked at THIS instant, and only those.
|
|
321
321
|
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
322
|
+
* Bounded on purpose, and deliberately not routed through
|
|
323
|
+
* \`__nimbusDrainVfsWrites\`, whose \`while (pending > 0)\` waits for the mutation
|
|
324
|
+
* queue to be EMPTY. That wait is correct at process exit, where no new writes
|
|
325
|
+
* are coming. Anywhere else it is a livelock: a facet unpacking a tarball adds
|
|
326
|
+
* mutations faster than the loop retires them, so the loop never returns.
|
|
327
|
+
* Sited ahead of egress — where it was — that stopped the request from ever
|
|
328
|
+
* leaving the facet, and \`npx sv create\` ran, printed its intro, and then
|
|
329
|
+
* never reported an exit at all. A barrier may delay a request; it may not
|
|
330
|
+
* wait on a condition a busy process never reaches.
|
|
331
|
+
*
|
|
332
|
+
* Failures are retained rather than thrown. The two callers — the debounce
|
|
333
|
+
* below, and the RELEASE barrier ahead of egress — have no frame that could
|
|
334
|
+
* act on one: rejecting the fetch that happened to trigger the flush would
|
|
335
|
+
* blame the wrong operation. The exit drain reports what is retained, so a
|
|
336
|
+
* lost write is loud exactly once and never silent.
|
|
329
337
|
*/
|
|
330
338
|
async function __nimbusFlushVfsWriteBack(supervisor) {
|
|
331
339
|
if (!supervisor) return;
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
+
const paths = Object.keys(__vfsWrites);
|
|
341
|
+
if (paths.length === 0) return;
|
|
342
|
+
await Promise.allSettled(paths.map((path) => __nimbusFlushVfsWrite(
|
|
343
|
+
path,
|
|
344
|
+
(content, snapshot) => __nimbusPersistVfsWrite(supervisor, path, content, snapshot),
|
|
345
|
+
)));
|
|
340
346
|
}
|
|
341
347
|
|
|
342
348
|
/**
|
|
@@ -1,37 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Minimal byte-aligned comment stripper for prefetch's import detection.
|
|
3
|
-
*
|
|
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).
|
|
10
|
-
*
|
|
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.
|
|
17
|
-
*
|
|
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
|
|
23
|
-
*
|
|
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.
|
|
35
|
-
*/
|
|
36
1
|
export declare function stripCommentsForImports(src: string): string;
|
|
37
2
|
//# sourceMappingURL=comment-strip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comment-strip.d.ts","sourceRoot":"","sources":["../../src/runtime/comment-strip.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"comment-strip.d.ts","sourceRoot":"","sources":["../../src/runtime/comment-strip.ts"],"names":[],"mappings":"AAkDA,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyC3D"}
|
|
@@ -27,48 +27,76 @@
|
|
|
27
27
|
* so it's a minor wasted-work cost — see IMPORT_RE header comment in
|
|
28
28
|
* `require-resolver.ts:84-86`.
|
|
29
29
|
*
|
|
30
|
+
* Memory: the output is assembled from slices of the input — one per
|
|
31
|
+
* comment-free span — and joined once. It used to be built one character
|
|
32
|
+
* at a time with `out += c`, which every JS engine represents as a rope
|
|
33
|
+
* of one node per append: ~30 bytes of heap per character of output, all
|
|
34
|
+
* of it live until the string is first read. The require walk runs this
|
|
35
|
+
* over every file in the closure, and on typescript's 6.15 MB `lib/_tsc.js`
|
|
36
|
+
* that rope measured 174 MB (V8) / 172 MB (JSC) against a 128 MB isolate —
|
|
37
|
+
* the session Durable Object was killed inside `tsc`'s spawn before the
|
|
38
|
+
* facet existed. A span-sliced build holds the input, the output and a
|
|
39
|
+
* short array of slices, and nothing else.
|
|
40
|
+
*
|
|
30
41
|
* TODO(CLN-X): when the `src/runtime/esbuild-service.ts` anti-touch
|
|
31
42
|
* window opens, unify with the canonical
|
|
32
43
|
* `stripCommentsAndStrings(src)` helper there. Both implement the
|
|
33
44
|
* same logical pass over comments; only the string/regex-literal
|
|
34
45
|
* handling differs.
|
|
35
46
|
*/
|
|
47
|
+
const SLASH = 0x2f;
|
|
48
|
+
const STAR = 0x2a;
|
|
49
|
+
const NEWLINE = 0x0a;
|
|
36
50
|
export function stripCommentsForImports(src) {
|
|
37
|
-
let out = '';
|
|
38
|
-
let i = 0;
|
|
39
51
|
const N = src.length;
|
|
52
|
+
const parts = [];
|
|
53
|
+
// Start of the comment-free span not yet copied to `parts`.
|
|
54
|
+
let spanStart = 0;
|
|
55
|
+
let i = 0;
|
|
40
56
|
while (i < N) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
if (src.charCodeAt(i) !== SLASH) {
|
|
58
|
+
i++;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const next = src.charCodeAt(i + 1);
|
|
62
|
+
// Line comment: `//` to end-of-line, replaced by one space. The
|
|
63
|
+
// newline is not part of the comment and stays in the next span.
|
|
64
|
+
if (next === SLASH) {
|
|
65
|
+
parts.push(src.slice(spanStart, i), ' ');
|
|
45
66
|
i += 2;
|
|
46
|
-
while (i < N && src
|
|
67
|
+
while (i < N && src.charCodeAt(i) !== NEWLINE)
|
|
47
68
|
i++;
|
|
48
|
-
|
|
69
|
+
spanStart = i;
|
|
49
70
|
continue;
|
|
50
71
|
}
|
|
51
|
-
// Block comment: `/*` to
|
|
52
|
-
|
|
72
|
+
// Block comment: `/*` to `*/`, replaced by its own newlines (so line
|
|
73
|
+
// numbers stay aligned) and one space. An unterminated one runs to
|
|
74
|
+
// the end of input and gets no closing space.
|
|
75
|
+
if (next === STAR) {
|
|
76
|
+
parts.push(src.slice(spanStart, i));
|
|
53
77
|
i += 2;
|
|
78
|
+
let newlines = 0;
|
|
79
|
+
let closed = false;
|
|
54
80
|
while (i < N) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (src[i] === '*' && src[i + 1] === '/') {
|
|
81
|
+
const c = src.charCodeAt(i);
|
|
82
|
+
if (c === NEWLINE)
|
|
83
|
+
newlines++;
|
|
84
|
+
else if (c === STAR && src.charCodeAt(i + 1) === SLASH) {
|
|
62
85
|
i += 2;
|
|
63
|
-
|
|
86
|
+
closed = true;
|
|
64
87
|
break;
|
|
65
88
|
}
|
|
66
89
|
i++;
|
|
67
90
|
}
|
|
91
|
+
if (newlines > 0)
|
|
92
|
+
parts.push('\n'.repeat(newlines));
|
|
93
|
+
if (closed)
|
|
94
|
+
parts.push(' ');
|
|
95
|
+
spanStart = i;
|
|
68
96
|
continue;
|
|
69
97
|
}
|
|
70
|
-
out += c;
|
|
71
98
|
i++;
|
|
72
99
|
}
|
|
73
|
-
|
|
100
|
+
parts.push(src.slice(spanStart));
|
|
101
|
+
return parts.join('');
|
|
74
102
|
}
|
|
@@ -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 {
|
|
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 = "
|
|
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
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
*
|
|
81
|
-
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
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
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
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
|
-
*
|
|
99
|
-
*
|
|
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
|
|
103
|
-
|
|
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
|
-
|
|
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
|
|
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":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"esbuild-service.d.ts","sourceRoot":"","sources":["../../src/runtime/esbuild-service.ts"],"names":[],"mappings":"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"}
|