sandboxedjs 0.1.45 → 0.1.47

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/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Shell, a as ShellIO, b as Session, V as Vfs, c as Cred, N as Node, d as Command, K as Kernel, R as RuntimeVolume, e as VolumeStat, f as VolumeStats, g as RuntimeHttpResponse, h as SpawnChild, i as SyncSpawn, j as RuntimePod, k as RuntimePackageInstaller, l as ChildSpawnConfig, m as ChildHandle, n as RuntimeProcess, E as ExecContext, O as OutputStream, C as Container, o as createContainer } from './container-CZn9USBQ.cjs';
2
- export { B as BufferSink, p as CPythonOptions, q as CallbackSink, r as CommandRegistry, s as ContainerFs, t as ContainerOptions, u as ContextInit, D as DirEntry, v as Env, w as ExecOptions, x as ExecResult, F as FileData, y as FileInput, z as FileOutput, G as GroupEntry, H as HttpResponse, I as InputStream, J as Job, A as KernelOptions, L as ListeningPort, M as MountEntry, P as NetInterface, Q as NetworkOptions, T as NetworkStack, U as NullInput, W as NullOutput, X as PYTHON_VERSION, Y as PasswdEntry, Z as Pipe, _ as Process, $ as ProcessKind, a0 as ProcessOptions, a1 as ProcessState, a2 as ProcessTable, a3 as PythonOptions, a4 as ROOT_CRED, a5 as ResolvedExecutable, a6 as RunOptions, a7 as RunResult, a8 as RuntimeProcessManager, a9 as RuntimeProcessResult, aa as SessionInit, ab as SessionResult, ac as SessionRunOptions, ad as ShellExit, ae as ShellInit, af as ShellOptions, ag as SpawnHandle, ah as Stats, ai as Stdio, aj as TeeOutput, ak as UserDatabase, al as Variables, am as VirtualNode, an as VirtualProvider, ao as WriteOptions, ap as applyChmod, aq as braceExpand, ar as captureStdio, as as configureCPython, at as configurePython, au as createChildProcessModule, av as createContext, aw as defineCommand, ax as expandWord, ay as expandWords, az as formatMode, aA as isCPythonAvailable, aB as isPythonAvailable, aC as makeCred, aD as octalMode, aE as parseUmask, aF as resetPidCounter, aG as shellQuote } from './container-CZn9USBQ.cjs';
1
+ import { S as Shell, a as ShellIO, b as Session, V as Vfs, c as Cred, N as Node, d as Command, K as Kernel, R as RuntimeVolume, e as VolumeStat, f as VolumeStats, g as RuntimeHttpResponse, h as SpawnChild, i as SyncSpawn, j as RuntimePod, k as RuntimePackageInstaller, l as ChildSpawnConfig, m as ChildHandle, n as RuntimeProcess, o as RuntimeSocketPeer, p as RuntimeConnection, E as ExecContext, O as OutputStream, C as Container, q as createContainer } from './container-DyRF-bY0.cjs';
2
+ export { B as BufferSink, r as CPythonOptions, s as CallbackSink, t as CommandRegistry, u as ContainerFs, v as ContainerOptions, w as ContextInit, D as DirEntry, x as Env, y as ExecOptions, z as ExecResult, F as FileData, A as FileInput, G as FileOutput, H as GroupEntry, I as HttpResponse, J as InputStream, L as Job, M as KernelOptions, P as ListeningPort, Q as MountEntry, T as NetInterface, U as NetworkOptions, W as NetworkStack, X as NullInput, Y as NullOutput, Z as PYTHON_VERSION, _ as PasswdEntry, $ as Pipe, a0 as Process, a1 as ProcessKind, a2 as ProcessOptions, a3 as ProcessState, a4 as ProcessTable, a5 as PythonOptions, a6 as ROOT_CRED, a7 as ResolvedExecutable, a8 as RunOptions, a9 as RunResult, aa as RuntimeProcessManager, ab as RuntimeProcessResult, ac as SessionInit, ad as SessionResult, ae as SessionRunOptions, af as ShellExit, ag as ShellInit, ah as ShellOptions, ai as SpawnHandle, aj as Stats, ak as Stdio, al as TeeOutput, am as UserDatabase, an as Variables, ao as VirtualNode, ap as VirtualProvider, aq as WriteOptions, ar as applyChmod, as as braceExpand, at as captureStdio, au as configureCPython, av as configurePython, aw as createChildProcessModule, ax as createContext, ay as defineCommand, az as expandWord, aA as expandWords, aB as formatMode, aC as isCPythonAvailable, aD as isPythonAvailable, aE as makeCred, aF as octalMode, aG as parseUmask, aH as resetPidCounter, aI as shellQuote } from './container-DyRF-bY0.cjs';
3
3
  import EventEmitter from 'events/events.js';
4
4
  import streamModule from 'stream-browserify';
5
5
 
@@ -648,8 +648,8 @@ declare class VirtualIncomingMessage extends streamModule.Readable {
648
648
  readonly httpVersionMajor = 1;
649
649
  readonly httpVersionMinor = 1;
650
650
  readonly complete = true;
651
- readonly socket: Record<string, unknown>;
652
- readonly connection: Record<string, unknown>;
651
+ socket: Record<string, unknown> | VirtualSocket;
652
+ get connection(): Record<string, unknown> | VirtualSocket;
653
653
  constructor(init: VirtualRequestInit);
654
654
  _read(): void;
655
655
  setTimeout(_milliseconds: number, callback?: () => void): this;
@@ -683,6 +683,60 @@ declare class VirtualServerResponse extends streamModule.Writable {
683
683
  addTrailers(_headers: Record<string, string>): void;
684
684
  setTimeout(_milliseconds: number, callback?: () => void): this;
685
685
  }
686
+ /** Where a {@link VirtualSocket} puts the bytes the server writes. */
687
+ interface VirtualSocketPeer {
688
+ /** The server sent these. */
689
+ data(bytes: Uint8Array): void;
690
+ /** The server hung up. */
691
+ close(): void;
692
+ }
693
+ /**
694
+ * The server half of a connection that has stopped being HTTP.
695
+ *
696
+ * Everything else in this file models one request and one response, because
697
+ * that is all a container's servers were ever asked for. A protocol upgrade is
698
+ * the case that does not fit: after the `101` there is no request and no
699
+ * response, only two peers writing bytes at each other for as long as they
700
+ * both stay interested.
701
+ *
702
+ * So this is a real `Duplex` rather than another stub. It has to be — the
703
+ * libraries that speak WebSocket do not merely read `req.headers` and reply,
704
+ * they take the socket and run a framing protocol over it, and a stub that
705
+ * accepts `write()` and drops it produces a server that completes its
706
+ * handshake and is then silent forever, which looks exactly like a network
707
+ * problem and is the hardest possible thing to attribute.
708
+ *
709
+ * Writes go out through {@link VirtualSocketPeer}; {@link deliver} pushes what
710
+ * comes back. Nothing here knows what the bytes mean, which is the point: `ws`,
711
+ * `socket.io` and Vite's HMR server all work over it unmodified.
712
+ */
713
+ declare class VirtualSocket extends streamModule.Duplex {
714
+ readonly remoteAddress = "127.0.0.1";
715
+ readonly remotePort = 0;
716
+ readonly localAddress = "127.0.0.1";
717
+ readonly localPort = 0;
718
+ readonly encrypted = false;
719
+ readonly bufferSize = 0;
720
+ private peer;
721
+ /** Set once the peer is told, so `end()` then `destroy()` reports once. */
722
+ private hungUp;
723
+ constructor(peer: VirtualSocketPeer);
724
+ _read(): void;
725
+ _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void;
726
+ _final(callback: (error?: Error | null) => void): void;
727
+ _destroy(error: Error | null, callback: (error?: Error | null) => void): void;
728
+ private hangUp;
729
+ /** Bytes arriving from the far end. */
730
+ deliver(bytes: Uint8Array): void;
731
+ /** The far end went away; let the server's stream end cleanly. */
732
+ peerClosed(): void;
733
+ setNoDelay(): this;
734
+ setKeepAlive(): this;
735
+ setTimeout(_milliseconds: number, callback?: () => void): this;
736
+ destroySoon(): void;
737
+ ref(): this;
738
+ unref(): this;
739
+ }
686
740
  declare class VirtualHttpServer extends EventEmitter {
687
741
  private readonly router;
688
742
  readonly owner: string;
@@ -716,6 +770,28 @@ declare class VirtualHttpRouter {
716
770
  closeOwner(owner: string): void;
717
771
  closeAll(): void;
718
772
  request(port: number, init?: VirtualRequestInit): Promise<RuntimeHttpResponse>;
773
+ /**
774
+ * Open a connection that leaves HTTP behind — a WebSocket, in practice.
775
+ *
776
+ * The counterpart to {@link request}, and the thing whose absence made a dev
777
+ * server look broken. Every Node WebSocket library is built the same way: it
778
+ * hands `http.Server` an `upgrade` listener and waits. Nothing here ever
779
+ * emitted one, so `ws` sat holding a server that could not receive a single
780
+ * connection, and Vite lost the channel it uses to tell a page to reload —
781
+ * which is the only way it can recover after re-optimizing dependencies.
782
+ *
783
+ * Null means there is nothing to connect to: no server on the port, or a
784
+ * server that never asked for upgrades. Both are refusals the caller should
785
+ * report rather than wait out.
786
+ */
787
+ connect(port: number, init: VirtualRequestInit, peer: VirtualSocketPeer): VirtualConnection | null;
788
+ }
789
+ /** A connection handed back by {@link VirtualHttpRouter.connect}. */
790
+ interface VirtualConnection {
791
+ /** Bytes from the far end, into the container. */
792
+ send(bytes: Uint8Array): void;
793
+ /** The far end went away. */
794
+ close(): void;
719
795
  }
720
796
 
721
797
  interface CoreModulesOptions {
@@ -1029,6 +1105,7 @@ declare class LocalRuntimePod implements RuntimePod {
1029
1105
  */
1030
1106
  private settle;
1031
1107
  request(_port: number, _init?: Record<string, unknown>): Promise<RuntimeHttpResponse>;
1108
+ connect(port: number, init: Record<string, unknown>, peer: RuntimeSocketPeer): RuntimeConnection | null;
1032
1109
  snapshot(): MemoryVolumeSnapshotEntry[];
1033
1110
  restore(snapshot: unknown): Promise<void>;
1034
1111
  teardown(): void;
@@ -1076,6 +1153,8 @@ declare class WorkerRuntimePod extends LocalRuntimePod {
1076
1153
  private runChildToCompletion;
1077
1154
  private readonly proxies;
1078
1155
  private readonly waiting;
1156
+ /** Upgraded connections, by the id the Worker knows them as. */
1157
+ private readonly upgraded;
1079
1158
  private nextRequestId;
1080
1159
  /**
1081
1160
  * Register a stand-in for a server that is actually running in the Worker.
@@ -1085,6 +1164,14 @@ declare class WorkerRuntimePod extends LocalRuntimePod {
1085
1164
  */
1086
1165
  private proxyPort;
1087
1166
  private forward;
1167
+ /**
1168
+ * Tunnel one upgraded connection to the server that actually holds the port.
1169
+ *
1170
+ * Unlike {@link forward} there is no reply to wait for: both ends write
1171
+ * whenever they have something, until one of them stops. The id is what ties
1172
+ * the two directions together across the Worker boundary.
1173
+ */
1174
+ private upgrade;
1088
1175
  private settleProxied;
1089
1176
  private closeProxies;
1090
1177
  teardown(): void;
@@ -1127,11 +1214,28 @@ declare class CleanPackageInstaller implements RuntimePackageInstaller {
1127
1214
  private readonly fetcher;
1128
1215
  private readonly metadata;
1129
1216
  private readonly tarballs;
1217
+ /** Single-version manifests, for the fields the packument omits. */
1218
+ private readonly details;
1130
1219
  constructor(volume: RuntimeVolume, options?: CleanInstallerOptions);
1131
1220
  forCwd(cwd: string): CleanPackageInstaller;
1132
1221
  install(name: string, version?: string, options?: InstallOptions): Promise<RegistryManifest>;
1133
1222
  installFromManifest(path: string, options?: InstallOptions): Promise<void>;
1134
1223
  private installAt;
1224
+ /**
1225
+ * The `libc` and `main` fields, which the abbreviated packument leaves out.
1226
+ *
1227
+ * Fetched per version rather than as a full packument: the single-version
1228
+ * document is a few kilobytes, while the full one for a popular package runs
1229
+ * to megabytes. Only packages that already declare `os` or `cpu` ask for it,
1230
+ * so an ordinary install of pure-JavaScript dependencies makes no extra
1231
+ * requests at all — it is the prebuilt binaries, a handful per project, that
1232
+ * need the answer.
1233
+ *
1234
+ * A failure here is not fatal. Being unable to read `libc` puts the check
1235
+ * back where it was before this existed, which is worth strictly less than
1236
+ * being right and strictly more than refusing to install.
1237
+ */
1238
+ private platformDetail;
1135
1239
  private getMetadata;
1136
1240
  private getTarball;
1137
1241
  private createBinLinks;
@@ -1465,6 +1569,19 @@ interface PreviewOptions {
1465
1569
  * the moment, and it can stop after a few attempts rather than looping.
1466
1570
  */
1467
1571
  onStale?: () => void;
1572
+ /**
1573
+ * Let pages inside the preview open WebSockets to the container.
1574
+ *
1575
+ * On by default. A service worker cannot answer a WebSocket handshake, so
1576
+ * previewed documents are given a `WebSocket` that tunnels through this page
1577
+ * instead — which means the HTML they are served is modified on the way
1578
+ * through, one `<script>` at the top of `<head>`.
1579
+ *
1580
+ * Turn it off to serve documents byte for byte. The cost is that a dev
1581
+ * server loses its HMR channel, and with it the `full-reload` it sends after
1582
+ * re-optimizing dependencies; {@link onStale} is the fallback for that.
1583
+ */
1584
+ websocket?: boolean;
1468
1585
  }
1469
1586
  interface Preview {
1470
1587
  /** The URL an iframe should be pointed at to see `port`. */
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Shell, a as ShellIO, b as Session, V as Vfs, c as Cred, N as Node, d as Command, K as Kernel, R as RuntimeVolume, e as VolumeStat, f as VolumeStats, g as RuntimeHttpResponse, h as SpawnChild, i as SyncSpawn, j as RuntimePod, k as RuntimePackageInstaller, l as ChildSpawnConfig, m as ChildHandle, n as RuntimeProcess, E as ExecContext, O as OutputStream, C as Container, o as createContainer } from './container-CZn9USBQ.js';
2
- export { B as BufferSink, p as CPythonOptions, q as CallbackSink, r as CommandRegistry, s as ContainerFs, t as ContainerOptions, u as ContextInit, D as DirEntry, v as Env, w as ExecOptions, x as ExecResult, F as FileData, y as FileInput, z as FileOutput, G as GroupEntry, H as HttpResponse, I as InputStream, J as Job, A as KernelOptions, L as ListeningPort, M as MountEntry, P as NetInterface, Q as NetworkOptions, T as NetworkStack, U as NullInput, W as NullOutput, X as PYTHON_VERSION, Y as PasswdEntry, Z as Pipe, _ as Process, $ as ProcessKind, a0 as ProcessOptions, a1 as ProcessState, a2 as ProcessTable, a3 as PythonOptions, a4 as ROOT_CRED, a5 as ResolvedExecutable, a6 as RunOptions, a7 as RunResult, a8 as RuntimeProcessManager, a9 as RuntimeProcessResult, aa as SessionInit, ab as SessionResult, ac as SessionRunOptions, ad as ShellExit, ae as ShellInit, af as ShellOptions, ag as SpawnHandle, ah as Stats, ai as Stdio, aj as TeeOutput, ak as UserDatabase, al as Variables, am as VirtualNode, an as VirtualProvider, ao as WriteOptions, ap as applyChmod, aq as braceExpand, ar as captureStdio, as as configureCPython, at as configurePython, au as createChildProcessModule, av as createContext, aw as defineCommand, ax as expandWord, ay as expandWords, az as formatMode, aA as isCPythonAvailable, aB as isPythonAvailable, aC as makeCred, aD as octalMode, aE as parseUmask, aF as resetPidCounter, aG as shellQuote } from './container-CZn9USBQ.js';
1
+ import { S as Shell, a as ShellIO, b as Session, V as Vfs, c as Cred, N as Node, d as Command, K as Kernel, R as RuntimeVolume, e as VolumeStat, f as VolumeStats, g as RuntimeHttpResponse, h as SpawnChild, i as SyncSpawn, j as RuntimePod, k as RuntimePackageInstaller, l as ChildSpawnConfig, m as ChildHandle, n as RuntimeProcess, o as RuntimeSocketPeer, p as RuntimeConnection, E as ExecContext, O as OutputStream, C as Container, q as createContainer } from './container-DyRF-bY0.js';
2
+ export { B as BufferSink, r as CPythonOptions, s as CallbackSink, t as CommandRegistry, u as ContainerFs, v as ContainerOptions, w as ContextInit, D as DirEntry, x as Env, y as ExecOptions, z as ExecResult, F as FileData, A as FileInput, G as FileOutput, H as GroupEntry, I as HttpResponse, J as InputStream, L as Job, M as KernelOptions, P as ListeningPort, Q as MountEntry, T as NetInterface, U as NetworkOptions, W as NetworkStack, X as NullInput, Y as NullOutput, Z as PYTHON_VERSION, _ as PasswdEntry, $ as Pipe, a0 as Process, a1 as ProcessKind, a2 as ProcessOptions, a3 as ProcessState, a4 as ProcessTable, a5 as PythonOptions, a6 as ROOT_CRED, a7 as ResolvedExecutable, a8 as RunOptions, a9 as RunResult, aa as RuntimeProcessManager, ab as RuntimeProcessResult, ac as SessionInit, ad as SessionResult, ae as SessionRunOptions, af as ShellExit, ag as ShellInit, ah as ShellOptions, ai as SpawnHandle, aj as Stats, ak as Stdio, al as TeeOutput, am as UserDatabase, an as Variables, ao as VirtualNode, ap as VirtualProvider, aq as WriteOptions, ar as applyChmod, as as braceExpand, at as captureStdio, au as configureCPython, av as configurePython, aw as createChildProcessModule, ax as createContext, ay as defineCommand, az as expandWord, aA as expandWords, aB as formatMode, aC as isCPythonAvailable, aD as isPythonAvailable, aE as makeCred, aF as octalMode, aG as parseUmask, aH as resetPidCounter, aI as shellQuote } from './container-DyRF-bY0.js';
3
3
  import EventEmitter from 'events/events.js';
4
4
  import streamModule from 'stream-browserify';
5
5
 
@@ -648,8 +648,8 @@ declare class VirtualIncomingMessage extends streamModule.Readable {
648
648
  readonly httpVersionMajor = 1;
649
649
  readonly httpVersionMinor = 1;
650
650
  readonly complete = true;
651
- readonly socket: Record<string, unknown>;
652
- readonly connection: Record<string, unknown>;
651
+ socket: Record<string, unknown> | VirtualSocket;
652
+ get connection(): Record<string, unknown> | VirtualSocket;
653
653
  constructor(init: VirtualRequestInit);
654
654
  _read(): void;
655
655
  setTimeout(_milliseconds: number, callback?: () => void): this;
@@ -683,6 +683,60 @@ declare class VirtualServerResponse extends streamModule.Writable {
683
683
  addTrailers(_headers: Record<string, string>): void;
684
684
  setTimeout(_milliseconds: number, callback?: () => void): this;
685
685
  }
686
+ /** Where a {@link VirtualSocket} puts the bytes the server writes. */
687
+ interface VirtualSocketPeer {
688
+ /** The server sent these. */
689
+ data(bytes: Uint8Array): void;
690
+ /** The server hung up. */
691
+ close(): void;
692
+ }
693
+ /**
694
+ * The server half of a connection that has stopped being HTTP.
695
+ *
696
+ * Everything else in this file models one request and one response, because
697
+ * that is all a container's servers were ever asked for. A protocol upgrade is
698
+ * the case that does not fit: after the `101` there is no request and no
699
+ * response, only two peers writing bytes at each other for as long as they
700
+ * both stay interested.
701
+ *
702
+ * So this is a real `Duplex` rather than another stub. It has to be — the
703
+ * libraries that speak WebSocket do not merely read `req.headers` and reply,
704
+ * they take the socket and run a framing protocol over it, and a stub that
705
+ * accepts `write()` and drops it produces a server that completes its
706
+ * handshake and is then silent forever, which looks exactly like a network
707
+ * problem and is the hardest possible thing to attribute.
708
+ *
709
+ * Writes go out through {@link VirtualSocketPeer}; {@link deliver} pushes what
710
+ * comes back. Nothing here knows what the bytes mean, which is the point: `ws`,
711
+ * `socket.io` and Vite's HMR server all work over it unmodified.
712
+ */
713
+ declare class VirtualSocket extends streamModule.Duplex {
714
+ readonly remoteAddress = "127.0.0.1";
715
+ readonly remotePort = 0;
716
+ readonly localAddress = "127.0.0.1";
717
+ readonly localPort = 0;
718
+ readonly encrypted = false;
719
+ readonly bufferSize = 0;
720
+ private peer;
721
+ /** Set once the peer is told, so `end()` then `destroy()` reports once. */
722
+ private hungUp;
723
+ constructor(peer: VirtualSocketPeer);
724
+ _read(): void;
725
+ _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void;
726
+ _final(callback: (error?: Error | null) => void): void;
727
+ _destroy(error: Error | null, callback: (error?: Error | null) => void): void;
728
+ private hangUp;
729
+ /** Bytes arriving from the far end. */
730
+ deliver(bytes: Uint8Array): void;
731
+ /** The far end went away; let the server's stream end cleanly. */
732
+ peerClosed(): void;
733
+ setNoDelay(): this;
734
+ setKeepAlive(): this;
735
+ setTimeout(_milliseconds: number, callback?: () => void): this;
736
+ destroySoon(): void;
737
+ ref(): this;
738
+ unref(): this;
739
+ }
686
740
  declare class VirtualHttpServer extends EventEmitter {
687
741
  private readonly router;
688
742
  readonly owner: string;
@@ -716,6 +770,28 @@ declare class VirtualHttpRouter {
716
770
  closeOwner(owner: string): void;
717
771
  closeAll(): void;
718
772
  request(port: number, init?: VirtualRequestInit): Promise<RuntimeHttpResponse>;
773
+ /**
774
+ * Open a connection that leaves HTTP behind — a WebSocket, in practice.
775
+ *
776
+ * The counterpart to {@link request}, and the thing whose absence made a dev
777
+ * server look broken. Every Node WebSocket library is built the same way: it
778
+ * hands `http.Server` an `upgrade` listener and waits. Nothing here ever
779
+ * emitted one, so `ws` sat holding a server that could not receive a single
780
+ * connection, and Vite lost the channel it uses to tell a page to reload —
781
+ * which is the only way it can recover after re-optimizing dependencies.
782
+ *
783
+ * Null means there is nothing to connect to: no server on the port, or a
784
+ * server that never asked for upgrades. Both are refusals the caller should
785
+ * report rather than wait out.
786
+ */
787
+ connect(port: number, init: VirtualRequestInit, peer: VirtualSocketPeer): VirtualConnection | null;
788
+ }
789
+ /** A connection handed back by {@link VirtualHttpRouter.connect}. */
790
+ interface VirtualConnection {
791
+ /** Bytes from the far end, into the container. */
792
+ send(bytes: Uint8Array): void;
793
+ /** The far end went away. */
794
+ close(): void;
719
795
  }
720
796
 
721
797
  interface CoreModulesOptions {
@@ -1029,6 +1105,7 @@ declare class LocalRuntimePod implements RuntimePod {
1029
1105
  */
1030
1106
  private settle;
1031
1107
  request(_port: number, _init?: Record<string, unknown>): Promise<RuntimeHttpResponse>;
1108
+ connect(port: number, init: Record<string, unknown>, peer: RuntimeSocketPeer): RuntimeConnection | null;
1032
1109
  snapshot(): MemoryVolumeSnapshotEntry[];
1033
1110
  restore(snapshot: unknown): Promise<void>;
1034
1111
  teardown(): void;
@@ -1076,6 +1153,8 @@ declare class WorkerRuntimePod extends LocalRuntimePod {
1076
1153
  private runChildToCompletion;
1077
1154
  private readonly proxies;
1078
1155
  private readonly waiting;
1156
+ /** Upgraded connections, by the id the Worker knows them as. */
1157
+ private readonly upgraded;
1079
1158
  private nextRequestId;
1080
1159
  /**
1081
1160
  * Register a stand-in for a server that is actually running in the Worker.
@@ -1085,6 +1164,14 @@ declare class WorkerRuntimePod extends LocalRuntimePod {
1085
1164
  */
1086
1165
  private proxyPort;
1087
1166
  private forward;
1167
+ /**
1168
+ * Tunnel one upgraded connection to the server that actually holds the port.
1169
+ *
1170
+ * Unlike {@link forward} there is no reply to wait for: both ends write
1171
+ * whenever they have something, until one of them stops. The id is what ties
1172
+ * the two directions together across the Worker boundary.
1173
+ */
1174
+ private upgrade;
1088
1175
  private settleProxied;
1089
1176
  private closeProxies;
1090
1177
  teardown(): void;
@@ -1127,11 +1214,28 @@ declare class CleanPackageInstaller implements RuntimePackageInstaller {
1127
1214
  private readonly fetcher;
1128
1215
  private readonly metadata;
1129
1216
  private readonly tarballs;
1217
+ /** Single-version manifests, for the fields the packument omits. */
1218
+ private readonly details;
1130
1219
  constructor(volume: RuntimeVolume, options?: CleanInstallerOptions);
1131
1220
  forCwd(cwd: string): CleanPackageInstaller;
1132
1221
  install(name: string, version?: string, options?: InstallOptions): Promise<RegistryManifest>;
1133
1222
  installFromManifest(path: string, options?: InstallOptions): Promise<void>;
1134
1223
  private installAt;
1224
+ /**
1225
+ * The `libc` and `main` fields, which the abbreviated packument leaves out.
1226
+ *
1227
+ * Fetched per version rather than as a full packument: the single-version
1228
+ * document is a few kilobytes, while the full one for a popular package runs
1229
+ * to megabytes. Only packages that already declare `os` or `cpu` ask for it,
1230
+ * so an ordinary install of pure-JavaScript dependencies makes no extra
1231
+ * requests at all — it is the prebuilt binaries, a handful per project, that
1232
+ * need the answer.
1233
+ *
1234
+ * A failure here is not fatal. Being unable to read `libc` puts the check
1235
+ * back where it was before this existed, which is worth strictly less than
1236
+ * being right and strictly more than refusing to install.
1237
+ */
1238
+ private platformDetail;
1135
1239
  private getMetadata;
1136
1240
  private getTarball;
1137
1241
  private createBinLinks;
@@ -1465,6 +1569,19 @@ interface PreviewOptions {
1465
1569
  * the moment, and it can stop after a few attempts rather than looping.
1466
1570
  */
1467
1571
  onStale?: () => void;
1572
+ /**
1573
+ * Let pages inside the preview open WebSockets to the container.
1574
+ *
1575
+ * On by default. A service worker cannot answer a WebSocket handshake, so
1576
+ * previewed documents are given a `WebSocket` that tunnels through this page
1577
+ * instead — which means the HTML they are served is modified on the way
1578
+ * through, one `<script>` at the top of `<head>`.
1579
+ *
1580
+ * Turn it off to serve documents byte for byte. The cost is that a dev
1581
+ * server loses its HMR channel, and with it the `full-reload` it sends after
1582
+ * re-optimizing dependencies; {@link onStale} is the fallback for that.
1583
+ */
1584
+ websocket?: boolean;
1468
1585
  }
1469
1586
  interface Preview {
1470
1587
  /** The URL an iframe should be pointed at to see `port`. */