sandboxedjs 0.1.28 → 0.1.29
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 +52 -7
- package/dist/index.cjs +904 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +198 -8
- package/dist/index.d.ts +198 -8
- package/dist/index.js +903 -53
- package/dist/index.js.map +1 -1
- package/dist/worker-entry.js +30822 -0
- package/dist/worker-entry.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -27,7 +27,30 @@ interface ChildSpawnConfig {
|
|
|
27
27
|
parentPid?: number;
|
|
28
28
|
}
|
|
29
29
|
type SpawnChild = (config: ChildSpawnConfig) => ChildHandle;
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Run a child to completion without returning to the event loop.
|
|
32
|
+
*
|
|
33
|
+
* Supplied only by a pod that can actually block — one whose guest runs on its
|
|
34
|
+
* own thread. Where it is absent the synchronous entry points keep reporting
|
|
35
|
+
* that they are unavailable, which is the honest answer for an in-realm pod.
|
|
36
|
+
*/
|
|
37
|
+
type SyncSpawn = (request: {
|
|
38
|
+
command: string;
|
|
39
|
+
args: string[];
|
|
40
|
+
cwd: string;
|
|
41
|
+
env?: Record<string, string>;
|
|
42
|
+
input?: string;
|
|
43
|
+
}) => {
|
|
44
|
+
status: number | null;
|
|
45
|
+
stdout: string;
|
|
46
|
+
stderr: string;
|
|
47
|
+
signal: string | null;
|
|
48
|
+
error?: {
|
|
49
|
+
code?: string;
|
|
50
|
+
message: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
declare function createChildProcessModule(spawnChild: SpawnChild, defaultCwd: () => string, syncSpawn?: SyncSpawn): Record<string, unknown>;
|
|
31
54
|
|
|
32
55
|
/**
|
|
33
56
|
* Clean-room contracts between SandboxedJS and its JavaScript runtime.
|
|
@@ -1639,6 +1662,24 @@ interface ContainerOptions {
|
|
|
1639
1662
|
* ```
|
|
1640
1663
|
*/
|
|
1641
1664
|
pod?: RuntimePod;
|
|
1665
|
+
/**
|
|
1666
|
+
* Where guest programs run.
|
|
1667
|
+
*
|
|
1668
|
+
* `"worker"` (the default) gives each program its own thread, which is what
|
|
1669
|
+
* makes synchronous child processes work and keeps guest code out of the
|
|
1670
|
+
* host's realm; it falls back automatically where the host cannot support it.
|
|
1671
|
+
* `"realm"` forces the in-realm runtime.
|
|
1672
|
+
*/
|
|
1673
|
+
isolation?: "worker" | "realm";
|
|
1674
|
+
/**
|
|
1675
|
+
* Where to load the guest worker bundle from.
|
|
1676
|
+
*
|
|
1677
|
+
* Defaults to the copy shipped beside the main bundle, which is what a
|
|
1678
|
+
* published package wants. Worth setting when a bundler has moved or
|
|
1679
|
+
* rewritten it — or when running from source, where the built file is the
|
|
1680
|
+
* only one a Worker can load.
|
|
1681
|
+
*/
|
|
1682
|
+
workerUrl?: string | URL;
|
|
1642
1683
|
/** Python runtime settings; a browser host uses this to locate the wasm. */
|
|
1643
1684
|
python?: PythonOptions;
|
|
1644
1685
|
}
|
|
@@ -2457,6 +2498,14 @@ interface CoreModulesOptions {
|
|
|
2457
2498
|
};
|
|
2458
2499
|
/** Backs `child_process`; without it the module reports as unavailable. */
|
|
2459
2500
|
spawnChild?: SpawnChild;
|
|
2501
|
+
/**
|
|
2502
|
+
* Backs the `*Sync` half of `child_process`.
|
|
2503
|
+
*
|
|
2504
|
+
* Only a pod whose guest runs on its own thread can supply this — blocking
|
|
2505
|
+
* requires somewhere else for the child's work to happen. Without it the
|
|
2506
|
+
* synchronous entry points keep reporting that they are unavailable.
|
|
2507
|
+
*/
|
|
2508
|
+
syncSpawn?: SyncSpawn;
|
|
2460
2509
|
/** File holding the process's standard input, exposed as descriptor 0. */
|
|
2461
2510
|
stdinPath?: string;
|
|
2462
2511
|
/** Keep `process.stdin` open and fed by {@link writeStdin} rather than ending it. */
|
|
@@ -2496,6 +2545,13 @@ declare function createCoreModules(options: CoreModulesOptions): {
|
|
|
2496
2545
|
pendingHandles(): number;
|
|
2497
2546
|
/** Active timers which called `unref()` and therefore only merit startup grace. */
|
|
2498
2547
|
pendingUnrefed(): number;
|
|
2548
|
+
/**
|
|
2549
|
+
* Cancel every timer this process still holds.
|
|
2550
|
+
*
|
|
2551
|
+
* Called when a process is killed: the process is finished, but its
|
|
2552
|
+
* scheduled work would otherwise keep running on the host's event loop.
|
|
2553
|
+
*/
|
|
2554
|
+
cancelTimers(): void;
|
|
2499
2555
|
/**
|
|
2500
2556
|
* Client requests sent but not yet read to completion.
|
|
2501
2557
|
*
|
|
@@ -2533,6 +2589,99 @@ declare function looksLikeEsm(source: string): boolean;
|
|
|
2533
2589
|
*/
|
|
2534
2590
|
declare function transformEsm(source: string, filename?: string): EsmTransformResult | null;
|
|
2535
2591
|
|
|
2592
|
+
/**
|
|
2593
|
+
* A volume that keeps a second, foreign filesystem in step with itself.
|
|
2594
|
+
*
|
|
2595
|
+
* Rolldown's browser WebAssembly binding owns a `memfs` volume of its own —
|
|
2596
|
+
* its Rust resolver reads through WASI, not through anything JavaScript can
|
|
2597
|
+
* hand it. So the sandbox project has to exist in two places at once, and the
|
|
2598
|
+
* copy has to stay current: a dev server reads `index.html` when the request
|
|
2599
|
+
* arrives, not when the process started.
|
|
2600
|
+
*
|
|
2601
|
+
* Mirroring on write rather than copying up-front is what makes that true. The
|
|
2602
|
+
* previous approach took one deep snapshot per spawn, which was both expensive
|
|
2603
|
+
* — every `npm run dev` re-copied `node_modules` — and already stale by the
|
|
2604
|
+
* time it mattered, so an edit during a session was served from the old tree.
|
|
2605
|
+
*
|
|
2606
|
+
* The mirror is deliberately one-way and best-effort. It is a cache for a
|
|
2607
|
+
* consumer that only reads; a write that fails to reach it must never fail the
|
|
2608
|
+
* write that the container itself made.
|
|
2609
|
+
*/
|
|
2610
|
+
|
|
2611
|
+
/** The slice of a `memfs`-style filesystem the mirror writes through. */
|
|
2612
|
+
interface MirrorFs {
|
|
2613
|
+
mkdirSync(path: string, options?: {
|
|
2614
|
+
recursive?: boolean;
|
|
2615
|
+
}): void;
|
|
2616
|
+
writeFileSync(path: string, data: Uint8Array): void;
|
|
2617
|
+
symlinkSync(target: string, path: string): void;
|
|
2618
|
+
rmSync?(path: string, options?: {
|
|
2619
|
+
recursive?: boolean;
|
|
2620
|
+
force?: boolean;
|
|
2621
|
+
}): void;
|
|
2622
|
+
unlinkSync?(path: string): void;
|
|
2623
|
+
rmdirSync?(path: string): void;
|
|
2624
|
+
}
|
|
2625
|
+
/**
|
|
2626
|
+
* A `RuntimeVolume` that forwards every mutation to an optional mirror.
|
|
2627
|
+
*
|
|
2628
|
+
* Wrapping rather than modifying `MemoryVolume` keeps the mirroring concern out
|
|
2629
|
+
* of the filesystem, and keeps this transparent to the kernel, whose `Vfs`
|
|
2630
|
+
* takes any `RuntimeVolume`.
|
|
2631
|
+
*/
|
|
2632
|
+
declare class MirroringVolume implements RuntimeVolume {
|
|
2633
|
+
private readonly inner;
|
|
2634
|
+
private mirror;
|
|
2635
|
+
private root;
|
|
2636
|
+
constructor(inner?: MemoryVolume);
|
|
2637
|
+
/**
|
|
2638
|
+
* Start mirroring the tree under `root`, seeding it with what is there now.
|
|
2639
|
+
*
|
|
2640
|
+
* Called once the Rolldown binding is known to be in play; before that a
|
|
2641
|
+
* container pays nothing for this.
|
|
2642
|
+
*/
|
|
2643
|
+
attach(mirror: MirrorFs, root: string): void;
|
|
2644
|
+
detach(): void;
|
|
2645
|
+
/** Copy the whole subtree across. The only bulk operation that remains. */
|
|
2646
|
+
private seed;
|
|
2647
|
+
/** Is this path inside the mirrored subtree? */
|
|
2648
|
+
private mirrored;
|
|
2649
|
+
/**
|
|
2650
|
+
* Run a mirror update, swallowing failure.
|
|
2651
|
+
*
|
|
2652
|
+
* The mirror is a read-only cache for another engine. If it rejects
|
|
2653
|
+
* something — an unsupported operation, a path it has not seen — the
|
|
2654
|
+
* container's own write has still happened and must still succeed.
|
|
2655
|
+
*/
|
|
2656
|
+
private safely;
|
|
2657
|
+
/** Push a path's current state across, whatever it is now. */
|
|
2658
|
+
private sync;
|
|
2659
|
+
readFileSync(path: string): Uint8Array;
|
|
2660
|
+
readdirSync(path: string): string[];
|
|
2661
|
+
lstatSync(path: string): VolumeStat;
|
|
2662
|
+
readlinkSync(path: string): string;
|
|
2663
|
+
getStats(): VolumeStats;
|
|
2664
|
+
writeFileSync(path: string, data: string | Uint8Array): void;
|
|
2665
|
+
appendFileSync(path: string, data: string | Uint8Array): void;
|
|
2666
|
+
mkdirSync(path: string, options?: {
|
|
2667
|
+
mode?: number;
|
|
2668
|
+
}): void;
|
|
2669
|
+
rmdirSync(path: string): void;
|
|
2670
|
+
unlinkSync(path: string): void;
|
|
2671
|
+
renameSync(from: string, to: string): void;
|
|
2672
|
+
symlinkSync(target: string, path: string): void;
|
|
2673
|
+
linkSync(existing: string, path: string): void;
|
|
2674
|
+
truncateSync(path: string, length?: number): void;
|
|
2675
|
+
chmodSync(path: string, mode: number): void;
|
|
2676
|
+
lchmodSync(path: string, mode: number): void;
|
|
2677
|
+
chownSync(path: string, uid: number, gid: number): void;
|
|
2678
|
+
lchownSync(path: string, uid: number, gid: number): void;
|
|
2679
|
+
utimesSync(path: string, atime: Date, mtime: Date): void;
|
|
2680
|
+
snapshot(): MemoryVolumeSnapshotEntry[];
|
|
2681
|
+
/** A restore replaces everything, so the mirror is rebuilt rather than patched. */
|
|
2682
|
+
restore(entries: MemoryVolumeSnapshotEntry[]): void;
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2536
2685
|
interface LocalRuntimeOptions {
|
|
2537
2686
|
workdir?: string;
|
|
2538
2687
|
env?: Record<string, string>;
|
|
@@ -2569,10 +2718,10 @@ declare const WASM_ALIASES: Record<string, string>;
|
|
|
2569
2718
|
* dedicated Worker before this becomes the default untrusted-code path.
|
|
2570
2719
|
*/
|
|
2571
2720
|
declare class LocalRuntimePod implements RuntimePod {
|
|
2572
|
-
readonly volume:
|
|
2721
|
+
readonly volume: MirroringVolume;
|
|
2573
2722
|
readonly packages: RuntimePackageInstaller;
|
|
2574
2723
|
readonly instanceId: string;
|
|
2575
|
-
|
|
2724
|
+
protected readonly router: VirtualHttpRouter;
|
|
2576
2725
|
readonly proxy: {
|
|
2577
2726
|
activePorts: (_instanceId?: string) => number[];
|
|
2578
2727
|
};
|
|
@@ -2585,15 +2734,15 @@ declare class LocalRuntimePod implements RuntimePod {
|
|
|
2585
2734
|
spawn(config: ChildSpawnConfig): ChildHandle;
|
|
2586
2735
|
};
|
|
2587
2736
|
private disposed;
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2737
|
+
protected readonly workdir: string;
|
|
2738
|
+
protected readonly env: Record<string, string>;
|
|
2739
|
+
protected readonly aliases: Record<string, string>;
|
|
2591
2740
|
private readonly modules;
|
|
2592
2741
|
private readonly esbuild;
|
|
2593
2742
|
private rolldownBinding;
|
|
2594
2743
|
/** Backs outbound `http`/`https` client requests from inside the sandbox. */
|
|
2595
2744
|
private readonly fetch;
|
|
2596
|
-
|
|
2745
|
+
protected constructor(options: LocalRuntimeOptions);
|
|
2597
2746
|
static boot(options?: LocalRuntimeOptions): Promise<LocalRuntimePod>;
|
|
2598
2747
|
spawn(command: string, args?: string[], options?: Record<string, unknown>): Promise<RuntimeProcess>;
|
|
2599
2748
|
/**
|
|
@@ -2678,6 +2827,47 @@ declare class CleanPackageInstaller implements RuntimePackageInstaller {
|
|
|
2678
2827
|
}
|
|
2679
2828
|
declare function extractNpmTarball(volume: RuntimeVolume, compressed: Uint8Array, destination: string): void;
|
|
2680
2829
|
|
|
2830
|
+
/**
|
|
2831
|
+
* Starting the guest Worker, in whichever environment the host happens to be.
|
|
2832
|
+
*
|
|
2833
|
+
* The awkward part of shipping a Worker from a library is not creating it, but
|
|
2834
|
+
* naming it. `new URL("./worker-entry.js", import.meta.url)` is the form every
|
|
2835
|
+
* bundler recognises, and it resolves correctly from `dist/` — but a bundler
|
|
2836
|
+
* that *pre-bundles* this package rewrites `import.meta.url` to point into its
|
|
2837
|
+
* own dependency cache, where no such file exists. That is the same trap
|
|
2838
|
+
* Rolldown's WASI binding falls into, and it surfaces just as obliquely.
|
|
2839
|
+
*
|
|
2840
|
+
* So this never assumes it worked. The caller treats a failure to start as
|
|
2841
|
+
* "this host cannot run the Worker pod" and uses the in-realm pod instead.
|
|
2842
|
+
*/
|
|
2843
|
+
interface RuntimeWorker {
|
|
2844
|
+
postMessage(message: unknown): void;
|
|
2845
|
+
onMessage(listener: (message: unknown) => void): void;
|
|
2846
|
+
onError(listener: (error: unknown) => void): void;
|
|
2847
|
+
terminate(): unknown;
|
|
2848
|
+
}
|
|
2849
|
+
/**
|
|
2850
|
+
* Start the guest Worker and wait for it to say it is alive.
|
|
2851
|
+
*
|
|
2852
|
+
* Rejects rather than hanging when the script cannot be loaded: a Worker whose
|
|
2853
|
+
* script 404s reports an `error` event and would otherwise leave the caller
|
|
2854
|
+
* waiting for a ready message that can never arrive.
|
|
2855
|
+
*/
|
|
2856
|
+
declare function startRuntimeWorker(options?: {
|
|
2857
|
+
url?: string | URL;
|
|
2858
|
+
workerData?: Record<string, unknown>;
|
|
2859
|
+
timeoutMs?: number;
|
|
2860
|
+
}): Promise<RuntimeWorker>;
|
|
2861
|
+
|
|
2862
|
+
/**
|
|
2863
|
+
* Can this environment support a blocking client at all?
|
|
2864
|
+
*
|
|
2865
|
+
* `SharedArrayBuffer` needs cross-origin isolation in a browser, and
|
|
2866
|
+
* `Atomics.wait` is forbidden on a browser's main thread — which is why the
|
|
2867
|
+
* client is always the Worker.
|
|
2868
|
+
*/
|
|
2869
|
+
declare function syncChannelSupported(): boolean;
|
|
2870
|
+
|
|
2681
2871
|
/**
|
|
2682
2872
|
* sandboxedjs — a Linux-like container that runs entirely inside Node.js.
|
|
2683
2873
|
*
|
|
@@ -2696,4 +2886,4 @@ declare function extractNpmTarball(volume: RuntimeVolume, compressed: Uint8Array
|
|
|
2696
2886
|
* ```
|
|
2697
2887
|
*/
|
|
2698
2888
|
|
|
2699
|
-
export { ArithError, BufferSink, type CPythonOptions, CallbackSink, type ChildHandle, type ChildSpawnConfig, type CleanInstallerOptions, CleanPackageInstaller, type Command, CommandRegistry, CommonJsEngine, type CommonJsEngineOptions, type CommonJsModule, Container, ContainerFs, type ContainerOptions, type ContextInit, type CoreModulesOptions, type Cred, type DirEntry, ERRNO, type Env, type ErrnoCode, type EsmTransformResult, type ExecContext, type ExecOptions, type ExecResult, type FileData, FileInput, FileOutput, type GroupEntry, type HttpResponse, IncompleteInputError, type InputStream, type InstallOptions, type Job, KERNEL_NAME, KERNEL_RELEASE, Kernel, type KernelOptions, type ListeningPort, type LocalRuntimeOptions, LocalRuntimePod, MemoryVolume, type MountEntry, NODE_VERSION, NPM_VERSION, type NetInterface, type NetworkOptions, NetworkStack, NullInput, NullOutput, OS_RELEASE, type OutputStream, PYTHON_VERSION, type PasswdEntry, Pipe, Process, type ProcessKind, type ProcessOptions, type ProcessState, ProcessTable, type PythonOptions, ROOT_CRED, type ResolvedExecutable, type RootfsOptions, type RunOptions, type RunResult, type RuntimePackageInstaller, type RuntimePod, type RuntimeProcess, type RuntimeProcessManager, type RuntimeProcessResult, type RuntimeVolume, SIGNALS, SIGNAL_NAMES, Session, type SessionInit, type SessionResult, type SessionRunOptions, Shell, ShellExit, type ShellIO, type ShellInit, Lexer as ShellLexer, type ShellOptions, ShellSyntaxError, type SpawnChild, type SpawnHandle, Stats, type Stdio, SysError, TeeOutput, Terminal, type TerminalOptions, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, type VirtualNode, type VirtualProvider, VirtualServerResponse, WASM_ALIASES, type WriteOptions, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, createContainer as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path as posixPath, resetPidCounter, shellQuote, strerror, transformEsm, unameInfo };
|
|
2889
|
+
export { ArithError, BufferSink, type CPythonOptions, CallbackSink, type ChildHandle, type ChildSpawnConfig, type CleanInstallerOptions, CleanPackageInstaller, type Command, CommandRegistry, CommonJsEngine, type CommonJsEngineOptions, type CommonJsModule, Container, ContainerFs, type ContainerOptions, type ContextInit, type CoreModulesOptions, type Cred, type DirEntry, ERRNO, type Env, type ErrnoCode, type EsmTransformResult, type ExecContext, type ExecOptions, type ExecResult, type FileData, FileInput, FileOutput, type GroupEntry, type HttpResponse, IncompleteInputError, type InputStream, type InstallOptions, type Job, KERNEL_NAME, KERNEL_RELEASE, Kernel, type KernelOptions, type ListeningPort, type LocalRuntimeOptions, LocalRuntimePod, MemoryVolume, type MountEntry, NODE_VERSION, NPM_VERSION, type NetInterface, type NetworkOptions, NetworkStack, NullInput, NullOutput, OS_RELEASE, type OutputStream, PYTHON_VERSION, type PasswdEntry, Pipe, Process, type ProcessKind, type ProcessOptions, type ProcessState, ProcessTable, type PythonOptions, ROOT_CRED, type ResolvedExecutable, type RootfsOptions, type RunOptions, type RunResult, type RuntimePackageInstaller, type RuntimePod, type RuntimeProcess, type RuntimeProcessManager, type RuntimeProcessResult, type RuntimeVolume, SIGNALS, SIGNAL_NAMES, Session, type SessionInit, type SessionResult, type SessionRunOptions, Shell, ShellExit, type ShellIO, type ShellInit, Lexer as ShellLexer, type ShellOptions, ShellSyntaxError, type SpawnChild, type SpawnHandle, Stats, type Stdio, SysError, TeeOutput, Terminal, type TerminalOptions, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, type VirtualNode, type VirtualProvider, VirtualServerResponse, WASM_ALIASES, type WriteOptions, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, createContainer as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path as posixPath, resetPidCounter, shellQuote, startRuntimeWorker, strerror, syncChannelSupported, transformEsm, unameInfo };
|
package/dist/index.d.ts
CHANGED
|
@@ -27,7 +27,30 @@ interface ChildSpawnConfig {
|
|
|
27
27
|
parentPid?: number;
|
|
28
28
|
}
|
|
29
29
|
type SpawnChild = (config: ChildSpawnConfig) => ChildHandle;
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Run a child to completion without returning to the event loop.
|
|
32
|
+
*
|
|
33
|
+
* Supplied only by a pod that can actually block — one whose guest runs on its
|
|
34
|
+
* own thread. Where it is absent the synchronous entry points keep reporting
|
|
35
|
+
* that they are unavailable, which is the honest answer for an in-realm pod.
|
|
36
|
+
*/
|
|
37
|
+
type SyncSpawn = (request: {
|
|
38
|
+
command: string;
|
|
39
|
+
args: string[];
|
|
40
|
+
cwd: string;
|
|
41
|
+
env?: Record<string, string>;
|
|
42
|
+
input?: string;
|
|
43
|
+
}) => {
|
|
44
|
+
status: number | null;
|
|
45
|
+
stdout: string;
|
|
46
|
+
stderr: string;
|
|
47
|
+
signal: string | null;
|
|
48
|
+
error?: {
|
|
49
|
+
code?: string;
|
|
50
|
+
message: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
declare function createChildProcessModule(spawnChild: SpawnChild, defaultCwd: () => string, syncSpawn?: SyncSpawn): Record<string, unknown>;
|
|
31
54
|
|
|
32
55
|
/**
|
|
33
56
|
* Clean-room contracts between SandboxedJS and its JavaScript runtime.
|
|
@@ -1639,6 +1662,24 @@ interface ContainerOptions {
|
|
|
1639
1662
|
* ```
|
|
1640
1663
|
*/
|
|
1641
1664
|
pod?: RuntimePod;
|
|
1665
|
+
/**
|
|
1666
|
+
* Where guest programs run.
|
|
1667
|
+
*
|
|
1668
|
+
* `"worker"` (the default) gives each program its own thread, which is what
|
|
1669
|
+
* makes synchronous child processes work and keeps guest code out of the
|
|
1670
|
+
* host's realm; it falls back automatically where the host cannot support it.
|
|
1671
|
+
* `"realm"` forces the in-realm runtime.
|
|
1672
|
+
*/
|
|
1673
|
+
isolation?: "worker" | "realm";
|
|
1674
|
+
/**
|
|
1675
|
+
* Where to load the guest worker bundle from.
|
|
1676
|
+
*
|
|
1677
|
+
* Defaults to the copy shipped beside the main bundle, which is what a
|
|
1678
|
+
* published package wants. Worth setting when a bundler has moved or
|
|
1679
|
+
* rewritten it — or when running from source, where the built file is the
|
|
1680
|
+
* only one a Worker can load.
|
|
1681
|
+
*/
|
|
1682
|
+
workerUrl?: string | URL;
|
|
1642
1683
|
/** Python runtime settings; a browser host uses this to locate the wasm. */
|
|
1643
1684
|
python?: PythonOptions;
|
|
1644
1685
|
}
|
|
@@ -2457,6 +2498,14 @@ interface CoreModulesOptions {
|
|
|
2457
2498
|
};
|
|
2458
2499
|
/** Backs `child_process`; without it the module reports as unavailable. */
|
|
2459
2500
|
spawnChild?: SpawnChild;
|
|
2501
|
+
/**
|
|
2502
|
+
* Backs the `*Sync` half of `child_process`.
|
|
2503
|
+
*
|
|
2504
|
+
* Only a pod whose guest runs on its own thread can supply this — blocking
|
|
2505
|
+
* requires somewhere else for the child's work to happen. Without it the
|
|
2506
|
+
* synchronous entry points keep reporting that they are unavailable.
|
|
2507
|
+
*/
|
|
2508
|
+
syncSpawn?: SyncSpawn;
|
|
2460
2509
|
/** File holding the process's standard input, exposed as descriptor 0. */
|
|
2461
2510
|
stdinPath?: string;
|
|
2462
2511
|
/** Keep `process.stdin` open and fed by {@link writeStdin} rather than ending it. */
|
|
@@ -2496,6 +2545,13 @@ declare function createCoreModules(options: CoreModulesOptions): {
|
|
|
2496
2545
|
pendingHandles(): number;
|
|
2497
2546
|
/** Active timers which called `unref()` and therefore only merit startup grace. */
|
|
2498
2547
|
pendingUnrefed(): number;
|
|
2548
|
+
/**
|
|
2549
|
+
* Cancel every timer this process still holds.
|
|
2550
|
+
*
|
|
2551
|
+
* Called when a process is killed: the process is finished, but its
|
|
2552
|
+
* scheduled work would otherwise keep running on the host's event loop.
|
|
2553
|
+
*/
|
|
2554
|
+
cancelTimers(): void;
|
|
2499
2555
|
/**
|
|
2500
2556
|
* Client requests sent but not yet read to completion.
|
|
2501
2557
|
*
|
|
@@ -2533,6 +2589,99 @@ declare function looksLikeEsm(source: string): boolean;
|
|
|
2533
2589
|
*/
|
|
2534
2590
|
declare function transformEsm(source: string, filename?: string): EsmTransformResult | null;
|
|
2535
2591
|
|
|
2592
|
+
/**
|
|
2593
|
+
* A volume that keeps a second, foreign filesystem in step with itself.
|
|
2594
|
+
*
|
|
2595
|
+
* Rolldown's browser WebAssembly binding owns a `memfs` volume of its own —
|
|
2596
|
+
* its Rust resolver reads through WASI, not through anything JavaScript can
|
|
2597
|
+
* hand it. So the sandbox project has to exist in two places at once, and the
|
|
2598
|
+
* copy has to stay current: a dev server reads `index.html` when the request
|
|
2599
|
+
* arrives, not when the process started.
|
|
2600
|
+
*
|
|
2601
|
+
* Mirroring on write rather than copying up-front is what makes that true. The
|
|
2602
|
+
* previous approach took one deep snapshot per spawn, which was both expensive
|
|
2603
|
+
* — every `npm run dev` re-copied `node_modules` — and already stale by the
|
|
2604
|
+
* time it mattered, so an edit during a session was served from the old tree.
|
|
2605
|
+
*
|
|
2606
|
+
* The mirror is deliberately one-way and best-effort. It is a cache for a
|
|
2607
|
+
* consumer that only reads; a write that fails to reach it must never fail the
|
|
2608
|
+
* write that the container itself made.
|
|
2609
|
+
*/
|
|
2610
|
+
|
|
2611
|
+
/** The slice of a `memfs`-style filesystem the mirror writes through. */
|
|
2612
|
+
interface MirrorFs {
|
|
2613
|
+
mkdirSync(path: string, options?: {
|
|
2614
|
+
recursive?: boolean;
|
|
2615
|
+
}): void;
|
|
2616
|
+
writeFileSync(path: string, data: Uint8Array): void;
|
|
2617
|
+
symlinkSync(target: string, path: string): void;
|
|
2618
|
+
rmSync?(path: string, options?: {
|
|
2619
|
+
recursive?: boolean;
|
|
2620
|
+
force?: boolean;
|
|
2621
|
+
}): void;
|
|
2622
|
+
unlinkSync?(path: string): void;
|
|
2623
|
+
rmdirSync?(path: string): void;
|
|
2624
|
+
}
|
|
2625
|
+
/**
|
|
2626
|
+
* A `RuntimeVolume` that forwards every mutation to an optional mirror.
|
|
2627
|
+
*
|
|
2628
|
+
* Wrapping rather than modifying `MemoryVolume` keeps the mirroring concern out
|
|
2629
|
+
* of the filesystem, and keeps this transparent to the kernel, whose `Vfs`
|
|
2630
|
+
* takes any `RuntimeVolume`.
|
|
2631
|
+
*/
|
|
2632
|
+
declare class MirroringVolume implements RuntimeVolume {
|
|
2633
|
+
private readonly inner;
|
|
2634
|
+
private mirror;
|
|
2635
|
+
private root;
|
|
2636
|
+
constructor(inner?: MemoryVolume);
|
|
2637
|
+
/**
|
|
2638
|
+
* Start mirroring the tree under `root`, seeding it with what is there now.
|
|
2639
|
+
*
|
|
2640
|
+
* Called once the Rolldown binding is known to be in play; before that a
|
|
2641
|
+
* container pays nothing for this.
|
|
2642
|
+
*/
|
|
2643
|
+
attach(mirror: MirrorFs, root: string): void;
|
|
2644
|
+
detach(): void;
|
|
2645
|
+
/** Copy the whole subtree across. The only bulk operation that remains. */
|
|
2646
|
+
private seed;
|
|
2647
|
+
/** Is this path inside the mirrored subtree? */
|
|
2648
|
+
private mirrored;
|
|
2649
|
+
/**
|
|
2650
|
+
* Run a mirror update, swallowing failure.
|
|
2651
|
+
*
|
|
2652
|
+
* The mirror is a read-only cache for another engine. If it rejects
|
|
2653
|
+
* something — an unsupported operation, a path it has not seen — the
|
|
2654
|
+
* container's own write has still happened and must still succeed.
|
|
2655
|
+
*/
|
|
2656
|
+
private safely;
|
|
2657
|
+
/** Push a path's current state across, whatever it is now. */
|
|
2658
|
+
private sync;
|
|
2659
|
+
readFileSync(path: string): Uint8Array;
|
|
2660
|
+
readdirSync(path: string): string[];
|
|
2661
|
+
lstatSync(path: string): VolumeStat;
|
|
2662
|
+
readlinkSync(path: string): string;
|
|
2663
|
+
getStats(): VolumeStats;
|
|
2664
|
+
writeFileSync(path: string, data: string | Uint8Array): void;
|
|
2665
|
+
appendFileSync(path: string, data: string | Uint8Array): void;
|
|
2666
|
+
mkdirSync(path: string, options?: {
|
|
2667
|
+
mode?: number;
|
|
2668
|
+
}): void;
|
|
2669
|
+
rmdirSync(path: string): void;
|
|
2670
|
+
unlinkSync(path: string): void;
|
|
2671
|
+
renameSync(from: string, to: string): void;
|
|
2672
|
+
symlinkSync(target: string, path: string): void;
|
|
2673
|
+
linkSync(existing: string, path: string): void;
|
|
2674
|
+
truncateSync(path: string, length?: number): void;
|
|
2675
|
+
chmodSync(path: string, mode: number): void;
|
|
2676
|
+
lchmodSync(path: string, mode: number): void;
|
|
2677
|
+
chownSync(path: string, uid: number, gid: number): void;
|
|
2678
|
+
lchownSync(path: string, uid: number, gid: number): void;
|
|
2679
|
+
utimesSync(path: string, atime: Date, mtime: Date): void;
|
|
2680
|
+
snapshot(): MemoryVolumeSnapshotEntry[];
|
|
2681
|
+
/** A restore replaces everything, so the mirror is rebuilt rather than patched. */
|
|
2682
|
+
restore(entries: MemoryVolumeSnapshotEntry[]): void;
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2536
2685
|
interface LocalRuntimeOptions {
|
|
2537
2686
|
workdir?: string;
|
|
2538
2687
|
env?: Record<string, string>;
|
|
@@ -2569,10 +2718,10 @@ declare const WASM_ALIASES: Record<string, string>;
|
|
|
2569
2718
|
* dedicated Worker before this becomes the default untrusted-code path.
|
|
2570
2719
|
*/
|
|
2571
2720
|
declare class LocalRuntimePod implements RuntimePod {
|
|
2572
|
-
readonly volume:
|
|
2721
|
+
readonly volume: MirroringVolume;
|
|
2573
2722
|
readonly packages: RuntimePackageInstaller;
|
|
2574
2723
|
readonly instanceId: string;
|
|
2575
|
-
|
|
2724
|
+
protected readonly router: VirtualHttpRouter;
|
|
2576
2725
|
readonly proxy: {
|
|
2577
2726
|
activePorts: (_instanceId?: string) => number[];
|
|
2578
2727
|
};
|
|
@@ -2585,15 +2734,15 @@ declare class LocalRuntimePod implements RuntimePod {
|
|
|
2585
2734
|
spawn(config: ChildSpawnConfig): ChildHandle;
|
|
2586
2735
|
};
|
|
2587
2736
|
private disposed;
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2737
|
+
protected readonly workdir: string;
|
|
2738
|
+
protected readonly env: Record<string, string>;
|
|
2739
|
+
protected readonly aliases: Record<string, string>;
|
|
2591
2740
|
private readonly modules;
|
|
2592
2741
|
private readonly esbuild;
|
|
2593
2742
|
private rolldownBinding;
|
|
2594
2743
|
/** Backs outbound `http`/`https` client requests from inside the sandbox. */
|
|
2595
2744
|
private readonly fetch;
|
|
2596
|
-
|
|
2745
|
+
protected constructor(options: LocalRuntimeOptions);
|
|
2597
2746
|
static boot(options?: LocalRuntimeOptions): Promise<LocalRuntimePod>;
|
|
2598
2747
|
spawn(command: string, args?: string[], options?: Record<string, unknown>): Promise<RuntimeProcess>;
|
|
2599
2748
|
/**
|
|
@@ -2678,6 +2827,47 @@ declare class CleanPackageInstaller implements RuntimePackageInstaller {
|
|
|
2678
2827
|
}
|
|
2679
2828
|
declare function extractNpmTarball(volume: RuntimeVolume, compressed: Uint8Array, destination: string): void;
|
|
2680
2829
|
|
|
2830
|
+
/**
|
|
2831
|
+
* Starting the guest Worker, in whichever environment the host happens to be.
|
|
2832
|
+
*
|
|
2833
|
+
* The awkward part of shipping a Worker from a library is not creating it, but
|
|
2834
|
+
* naming it. `new URL("./worker-entry.js", import.meta.url)` is the form every
|
|
2835
|
+
* bundler recognises, and it resolves correctly from `dist/` — but a bundler
|
|
2836
|
+
* that *pre-bundles* this package rewrites `import.meta.url` to point into its
|
|
2837
|
+
* own dependency cache, where no such file exists. That is the same trap
|
|
2838
|
+
* Rolldown's WASI binding falls into, and it surfaces just as obliquely.
|
|
2839
|
+
*
|
|
2840
|
+
* So this never assumes it worked. The caller treats a failure to start as
|
|
2841
|
+
* "this host cannot run the Worker pod" and uses the in-realm pod instead.
|
|
2842
|
+
*/
|
|
2843
|
+
interface RuntimeWorker {
|
|
2844
|
+
postMessage(message: unknown): void;
|
|
2845
|
+
onMessage(listener: (message: unknown) => void): void;
|
|
2846
|
+
onError(listener: (error: unknown) => void): void;
|
|
2847
|
+
terminate(): unknown;
|
|
2848
|
+
}
|
|
2849
|
+
/**
|
|
2850
|
+
* Start the guest Worker and wait for it to say it is alive.
|
|
2851
|
+
*
|
|
2852
|
+
* Rejects rather than hanging when the script cannot be loaded: a Worker whose
|
|
2853
|
+
* script 404s reports an `error` event and would otherwise leave the caller
|
|
2854
|
+
* waiting for a ready message that can never arrive.
|
|
2855
|
+
*/
|
|
2856
|
+
declare function startRuntimeWorker(options?: {
|
|
2857
|
+
url?: string | URL;
|
|
2858
|
+
workerData?: Record<string, unknown>;
|
|
2859
|
+
timeoutMs?: number;
|
|
2860
|
+
}): Promise<RuntimeWorker>;
|
|
2861
|
+
|
|
2862
|
+
/**
|
|
2863
|
+
* Can this environment support a blocking client at all?
|
|
2864
|
+
*
|
|
2865
|
+
* `SharedArrayBuffer` needs cross-origin isolation in a browser, and
|
|
2866
|
+
* `Atomics.wait` is forbidden on a browser's main thread — which is why the
|
|
2867
|
+
* client is always the Worker.
|
|
2868
|
+
*/
|
|
2869
|
+
declare function syncChannelSupported(): boolean;
|
|
2870
|
+
|
|
2681
2871
|
/**
|
|
2682
2872
|
* sandboxedjs — a Linux-like container that runs entirely inside Node.js.
|
|
2683
2873
|
*
|
|
@@ -2696,4 +2886,4 @@ declare function extractNpmTarball(volume: RuntimeVolume, compressed: Uint8Array
|
|
|
2696
2886
|
* ```
|
|
2697
2887
|
*/
|
|
2698
2888
|
|
|
2699
|
-
export { ArithError, BufferSink, type CPythonOptions, CallbackSink, type ChildHandle, type ChildSpawnConfig, type CleanInstallerOptions, CleanPackageInstaller, type Command, CommandRegistry, CommonJsEngine, type CommonJsEngineOptions, type CommonJsModule, Container, ContainerFs, type ContainerOptions, type ContextInit, type CoreModulesOptions, type Cred, type DirEntry, ERRNO, type Env, type ErrnoCode, type EsmTransformResult, type ExecContext, type ExecOptions, type ExecResult, type FileData, FileInput, FileOutput, type GroupEntry, type HttpResponse, IncompleteInputError, type InputStream, type InstallOptions, type Job, KERNEL_NAME, KERNEL_RELEASE, Kernel, type KernelOptions, type ListeningPort, type LocalRuntimeOptions, LocalRuntimePod, MemoryVolume, type MountEntry, NODE_VERSION, NPM_VERSION, type NetInterface, type NetworkOptions, NetworkStack, NullInput, NullOutput, OS_RELEASE, type OutputStream, PYTHON_VERSION, type PasswdEntry, Pipe, Process, type ProcessKind, type ProcessOptions, type ProcessState, ProcessTable, type PythonOptions, ROOT_CRED, type ResolvedExecutable, type RootfsOptions, type RunOptions, type RunResult, type RuntimePackageInstaller, type RuntimePod, type RuntimeProcess, type RuntimeProcessManager, type RuntimeProcessResult, type RuntimeVolume, SIGNALS, SIGNAL_NAMES, Session, type SessionInit, type SessionResult, type SessionRunOptions, Shell, ShellExit, type ShellIO, type ShellInit, Lexer as ShellLexer, type ShellOptions, ShellSyntaxError, type SpawnChild, type SpawnHandle, Stats, type Stdio, SysError, TeeOutput, Terminal, type TerminalOptions, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, type VirtualNode, type VirtualProvider, VirtualServerResponse, WASM_ALIASES, type WriteOptions, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, createContainer as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path as posixPath, resetPidCounter, shellQuote, strerror, transformEsm, unameInfo };
|
|
2889
|
+
export { ArithError, BufferSink, type CPythonOptions, CallbackSink, type ChildHandle, type ChildSpawnConfig, type CleanInstallerOptions, CleanPackageInstaller, type Command, CommandRegistry, CommonJsEngine, type CommonJsEngineOptions, type CommonJsModule, Container, ContainerFs, type ContainerOptions, type ContextInit, type CoreModulesOptions, type Cred, type DirEntry, ERRNO, type Env, type ErrnoCode, type EsmTransformResult, type ExecContext, type ExecOptions, type ExecResult, type FileData, FileInput, FileOutput, type GroupEntry, type HttpResponse, IncompleteInputError, type InputStream, type InstallOptions, type Job, KERNEL_NAME, KERNEL_RELEASE, Kernel, type KernelOptions, type ListeningPort, type LocalRuntimeOptions, LocalRuntimePod, MemoryVolume, type MountEntry, NODE_VERSION, NPM_VERSION, type NetInterface, type NetworkOptions, NetworkStack, NullInput, NullOutput, OS_RELEASE, type OutputStream, PYTHON_VERSION, type PasswdEntry, Pipe, Process, type ProcessKind, type ProcessOptions, type ProcessState, ProcessTable, type PythonOptions, ROOT_CRED, type ResolvedExecutable, type RootfsOptions, type RunOptions, type RunResult, type RuntimePackageInstaller, type RuntimePod, type RuntimeProcess, type RuntimeProcessManager, type RuntimeProcessResult, type RuntimeVolume, SIGNALS, SIGNAL_NAMES, Session, type SessionInit, type SessionResult, type SessionRunOptions, Shell, ShellExit, type ShellIO, type ShellInit, Lexer as ShellLexer, type ShellOptions, ShellSyntaxError, type SpawnChild, type SpawnHandle, Stats, type Stdio, SysError, TeeOutput, Terminal, type TerminalOptions, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, type VirtualNode, type VirtualProvider, VirtualServerResponse, WASM_ALIASES, type WriteOptions, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, createContainer as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path as posixPath, resetPidCounter, shellQuote, startRuntimeWorker, strerror, syncChannelSupported, transformEsm, unameInfo };
|