@start.dev/container 0.0.1
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/_wc-vendored-types.d.ts +38 -0
- package/dist/command-resolver.d.ts +85 -0
- package/dist/index.d.ts +147 -0
- package/dist/index.js +1805 -0
- package/dist/runtime-assets.d.ts +44 -0
- package/dist/runtime-assets.js +27 -0
- package/dist/types.d.ts +230 -0
- package/dist/workers/runtime-sw.js +269 -0
- package/dist/workers/shell-host.worker.js +42835 -0
- package/dist/workers/streaming-process.worker.js +31493 -0
- package/dist/workers/vite-serve.worker.js +35697 -0
- package/package.json +27 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/container/build.ts — do not edit.
|
|
2
|
+
// Vendored public types from @wc/network and @wc/fs so @start.dev/container's emitted
|
|
3
|
+
// declarations are self-contained for external consumers (no monorepo required).
|
|
4
|
+
|
|
5
|
+
// ── from @wc/network ──
|
|
6
|
+
export interface RelayRequest {
|
|
7
|
+
requestId: string;
|
|
8
|
+
method: string;
|
|
9
|
+
url: string;
|
|
10
|
+
headers: Record<string, string>;
|
|
11
|
+
bodyBase64?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RelayResponse {
|
|
14
|
+
requestId: string;
|
|
15
|
+
ok: boolean;
|
|
16
|
+
status: number;
|
|
17
|
+
statusText: string;
|
|
18
|
+
headers: Record<string, string>;
|
|
19
|
+
bodyBase64: string;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare const RELAY_PROXY_PATH = '/__wc_relay_proxy';
|
|
23
|
+
export interface RelayTransport {
|
|
24
|
+
send(request: RelayRequest): Promise<RelayResponse>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ── from @wc/fs ──
|
|
28
|
+
export type WatchEventType = 'rename' | 'change';
|
|
29
|
+
export type WatchListener = (eventType: WatchEventType, filename: string) => void;
|
|
30
|
+
export interface WatchOptions {
|
|
31
|
+
recursive?: boolean;
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
encoding?: 'utf8' | 'buffer';
|
|
34
|
+
persistent?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface FsWatcher {
|
|
37
|
+
close(): void;
|
|
38
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The spawn() COMMAND RESOLVER for @start.dev/container (WS2).
|
|
3
|
+
*
|
|
4
|
+
* Turns a high-level `spawn(command, args)` into a concrete plan the facade can
|
|
5
|
+
* execute against the mounted MemoryFS, mirroring how a real shell/Node would
|
|
6
|
+
* resolve it — but browser-pure and over the virtual filesystem:
|
|
7
|
+
*
|
|
8
|
+
* - `node <file> [args]` → run the real file on the node-compat loader.
|
|
9
|
+
* - `npm run <script>` / test / start → read package.json scripts, resolve the
|
|
10
|
+
* script's command line, and recurse.
|
|
11
|
+
* - `npx <bin> [args]` / direct bin → resolve `node_modules/.bin/<cmd>` (or the
|
|
12
|
+
* package's `bin` field) to a JS entry.
|
|
13
|
+
* - `jsh` / `bash` / `sh` → run the real shell (@wc/shell / just-bash).
|
|
14
|
+
* - `npm install` → an HONEST stub (pre-vendoring covers deps).
|
|
15
|
+
*
|
|
16
|
+
* Anything genuinely unsupported is reported as an explicit error — NEVER faked.
|
|
17
|
+
*
|
|
18
|
+
* This module is pure (no DOM/worker): it only reads the VFS to compute a plan, so
|
|
19
|
+
* it is unit-testable. The facade executes the returned plan.
|
|
20
|
+
*/
|
|
21
|
+
/** A minimal read-only view of the mounted filesystem the resolver needs. */
|
|
22
|
+
export interface ResolverFs {
|
|
23
|
+
exists(path: string): boolean;
|
|
24
|
+
readFile(path: string): string;
|
|
25
|
+
lstat(path: string): {
|
|
26
|
+
kind: 'file' | 'dir' | 'symlink';
|
|
27
|
+
};
|
|
28
|
+
readlink(path: string): string;
|
|
29
|
+
list(path: string): {
|
|
30
|
+
name: string;
|
|
31
|
+
}[];
|
|
32
|
+
}
|
|
33
|
+
/** Run a real Node entry file (script or resolved bin) on the node-compat loader. */
|
|
34
|
+
export interface NodePlan {
|
|
35
|
+
kind: 'node';
|
|
36
|
+
/** Absolute VFS path of the entry to evaluate. */
|
|
37
|
+
entry: string;
|
|
38
|
+
/** argv after the entry (does NOT include `node` or the entry). */
|
|
39
|
+
args: string[];
|
|
40
|
+
/** Working directory for the process. */
|
|
41
|
+
cwd: string;
|
|
42
|
+
/** A human label for output/logging (e.g. 'node src/main.js', 'vite build'). */
|
|
43
|
+
label: string;
|
|
44
|
+
}
|
|
45
|
+
/** Run the real dev server (the existing Vite worker path). */
|
|
46
|
+
export interface DevServerPlan {
|
|
47
|
+
kind: 'dev-server';
|
|
48
|
+
label: string;
|
|
49
|
+
}
|
|
50
|
+
/** Run the real shell (@wc/shell / just-bash). */
|
|
51
|
+
export interface ShellPlan {
|
|
52
|
+
kind: 'shell';
|
|
53
|
+
/** A command line to execute, or undefined for an interactive shell. */
|
|
54
|
+
commandLine?: string;
|
|
55
|
+
cwd: string;
|
|
56
|
+
label: string;
|
|
57
|
+
}
|
|
58
|
+
/** An honest "not implemented" outcome carrying the exact reason. */
|
|
59
|
+
export interface UnsupportedPlan {
|
|
60
|
+
kind: 'unsupported';
|
|
61
|
+
message: string;
|
|
62
|
+
}
|
|
63
|
+
export type SpawnPlan = NodePlan | DevServerPlan | ShellPlan | UnsupportedPlan;
|
|
64
|
+
/** Normalize an absolute-ish path to a clean VFS absolute path. */
|
|
65
|
+
export declare function cleanPath(p: string): string;
|
|
66
|
+
/** Is this command+args the real dev-server path (Vite worker), not a generic node run? */
|
|
67
|
+
export declare function isDevServerCommand(command: string, args: string[]): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Tokenize a command line into argv, honoring single/double quotes. Throws on
|
|
70
|
+
* shell control operators we do not parse yet (&&, ||, |, ;, >, <, &) so a script
|
|
71
|
+
* that needs a real shell pipeline gets an honest error instead of a wrong run.
|
|
72
|
+
*/
|
|
73
|
+
export declare function tokenize(commandLine: string): string[];
|
|
74
|
+
/**
|
|
75
|
+
* Resolve a bin command (e.g. `vite`, `eslint`) to its JS entry file over the VFS.
|
|
76
|
+
* Tries `node_modules/.bin/<cmd>` (a symlink we follow to the package script),
|
|
77
|
+
* then the package's own `bin` field (`node_modules/<cmd>/package.json`). Returns
|
|
78
|
+
* the absolute entry path, or undefined if not found.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveBin(fs: ResolverFs, cwd: string, cmd: string): string | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Resolve a `spawn(command, args)` into an executable plan over the mounted FS.
|
|
83
|
+
* `cwd` is the absolute VFS working directory (the container's workdir by default).
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveSpawn(fs: ResolverFs, cwd: string, command: string, args: string[]): SpawnPlan;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { RELAY_PROXY_PATH, type RelayTransport } from './_wc-vendored-types';
|
|
2
|
+
import type { BootOptions, FileSystemAPI, FileSystemTree, MountOptions, Port, SpawnOptions, WebContainerEventMap, WebContainerProcess } from './types';
|
|
3
|
+
export * from './types';
|
|
4
|
+
export { RELAY_PROXY_PATH };
|
|
5
|
+
export type { RelayTransport };
|
|
6
|
+
/**
|
|
7
|
+
* The same-origin egress relay transport (the StackBlitz remote-proxy model):
|
|
8
|
+
* POSTs a serialized outbound request to `RELAY_PROXY_PATH` so the host performs
|
|
9
|
+
* the real external network call and returns it with CORS injected. The Vite
|
|
10
|
+
* worker auto-wires this internally (loopback/preview stay direct); it is
|
|
11
|
+
* re-exported here so a consumer can register it in other worker hosts too.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createSameOriginRelayTransport(fetchImpl?: typeof fetch, proxyPath?: string): RelayTransport;
|
|
14
|
+
/** The documented per-file write cap of the runtime (honest limit, not silent truncation). */
|
|
15
|
+
export declare const MAX_FILE_BYTES: number;
|
|
16
|
+
/**
|
|
17
|
+
* The kind of a preview-origin postMessage payload, identical to
|
|
18
|
+
* `@webcontainer/api`'s `PreviewMessageType`. Preview iframes post these to the
|
|
19
|
+
* embedding page; `isPreviewMessage` narrows an arbitrary message to one of them.
|
|
20
|
+
*/
|
|
21
|
+
export declare enum PreviewMessageType {
|
|
22
|
+
UncaughtException = "PREVIEW_UNCAUGHT_EXCEPTION",
|
|
23
|
+
UnhandledRejection = "PREVIEW_UNHANDLED_REJECTION",
|
|
24
|
+
ConsoleError = "PREVIEW_CONSOLE_ERROR"
|
|
25
|
+
}
|
|
26
|
+
/** The base shape every preview message carries (mirrors @webcontainer/api). */
|
|
27
|
+
export interface BasePreviewMessage {
|
|
28
|
+
type: PreviewMessageType;
|
|
29
|
+
/** The preview origin port the message originated from. */
|
|
30
|
+
previewId?: string;
|
|
31
|
+
/** The preview port the message originated from. */
|
|
32
|
+
port?: number;
|
|
33
|
+
/** The preview path the message originated from. */
|
|
34
|
+
pathname?: string;
|
|
35
|
+
/** The full preview url the message originated from. */
|
|
36
|
+
search?: string;
|
|
37
|
+
hash?: string;
|
|
38
|
+
}
|
|
39
|
+
/** A preview-origin uncaught exception, mirroring @webcontainer/api. */
|
|
40
|
+
export interface UncaughtExceptionMessage extends BasePreviewMessage {
|
|
41
|
+
type: PreviewMessageType.UncaughtException;
|
|
42
|
+
message: string;
|
|
43
|
+
stack: string | undefined;
|
|
44
|
+
}
|
|
45
|
+
/** A preview-origin unhandled promise rejection, mirroring @webcontainer/api. */
|
|
46
|
+
export interface UnhandledRejectionMessage extends BasePreviewMessage {
|
|
47
|
+
type: PreviewMessageType.UnhandledRejection;
|
|
48
|
+
message: string;
|
|
49
|
+
stack: string | undefined;
|
|
50
|
+
}
|
|
51
|
+
/** A preview-origin console.error, mirroring @webcontainer/api. */
|
|
52
|
+
export interface ConsoleErrorMessage extends BasePreviewMessage {
|
|
53
|
+
type: PreviewMessageType.ConsoleError;
|
|
54
|
+
args: unknown[];
|
|
55
|
+
stack: string | undefined;
|
|
56
|
+
}
|
|
57
|
+
export type PreviewMessage = UncaughtExceptionMessage | UnhandledRejectionMessage | ConsoleErrorMessage;
|
|
58
|
+
/**
|
|
59
|
+
* Narrow an arbitrary postMessage payload to a `PreviewMessage`. Exact behavior
|
|
60
|
+
* of `@webcontainer/api`'s `isPreviewMessage`: a non-null object whose `type` is
|
|
61
|
+
* one of the `PreviewMessageType` values.
|
|
62
|
+
*/
|
|
63
|
+
export declare function isPreviewMessage(data: unknown): data is PreviewMessage;
|
|
64
|
+
/**
|
|
65
|
+
* Reload a preview `<iframe>` element, mirroring `@webcontainer/api`'s
|
|
66
|
+
* `reloadPreview`. Pure client-side: it re-points `iframe.src` (optionally to a
|
|
67
|
+
* new `pathname`) so the browser re-navigates the frame. The optional `hardness`
|
|
68
|
+
* delay matches the upstream signature.
|
|
69
|
+
*/
|
|
70
|
+
export declare function reloadPreview(preview: HTMLIFrameElement, hardnessMs?: number): Promise<void>;
|
|
71
|
+
/** Mirrors @webcontainer/api's auth namespace shape; honest unsupported stubs. */
|
|
72
|
+
export declare const auth: {
|
|
73
|
+
/** No hosted auth in this runtime; throws an honest unsupported error. */
|
|
74
|
+
readonly init: () => never;
|
|
75
|
+
/** No hosted auth in this runtime; throws an honest unsupported error. */
|
|
76
|
+
readonly startAuthFlow: () => never;
|
|
77
|
+
/** No hosted auth in this runtime; throws an honest unsupported error. */
|
|
78
|
+
readonly logout: () => never;
|
|
79
|
+
/** No session in this runtime; returns null (no token), never a fake one. */
|
|
80
|
+
readonly loggedIn: () => Promise<void>;
|
|
81
|
+
/** No event bus in this runtime; registering returns a no-op unsubscribe. */
|
|
82
|
+
readonly on: () => () => void;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Mirrors @webcontainer/api's `configureAPIKey`. This unhosted runtime has no
|
|
86
|
+
* hosted API to key into, so it is an honest no-op kept for import compatibility
|
|
87
|
+
* (it does not throw, so harmless setup code that always calls it still works,
|
|
88
|
+
* but it configures nothing — there is no hosted backend to authenticate to).
|
|
89
|
+
*/
|
|
90
|
+
export declare function configureAPIKey(_apiKey: string): void;
|
|
91
|
+
export declare class WebContainer {
|
|
92
|
+
#private;
|
|
93
|
+
/** Absolute working directory (e.g. '/proj'); mirrors @webcontainer/api.workdir. */
|
|
94
|
+
readonly workdir: string;
|
|
95
|
+
/** The FileSystemAPI facade over the in-page MemoryFS. */
|
|
96
|
+
readonly fs: FileSystemAPI;
|
|
97
|
+
/**
|
|
98
|
+
* Live map of open dev-server port → preview url. Populated when a dev server
|
|
99
|
+
* becomes ready (the `server-ready` payload's `url`). The start.dev adapter
|
|
100
|
+
* reads this to point its preview iframe.
|
|
101
|
+
*/
|
|
102
|
+
readonly routes: Record<Port, string>;
|
|
103
|
+
private constructor();
|
|
104
|
+
/**
|
|
105
|
+
* Boot a WebContainer: assert cross-origin isolation, register the substrate
|
|
106
|
+
* Service Worker under the preview base, and construct the in-page filesystem.
|
|
107
|
+
* Mirrors `@webcontainer/api`'s `WebContainer.boot()`.
|
|
108
|
+
*/
|
|
109
|
+
static boot(options?: BootOptions): Promise<WebContainer>;
|
|
110
|
+
/**
|
|
111
|
+
* Mount a nested FileSystemTree into the filesystem (under `workdir`, or
|
|
112
|
+
* `options.mountPoint`). Identical tree shape to `@webcontainer/api`:
|
|
113
|
+
* `{ name: { file: { contents } } | { directory: {...} } }`.
|
|
114
|
+
*/
|
|
115
|
+
mount(tree: FileSystemTree, options?: MountOptions): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Spawn a command (WS2 — the real command resolver). Resolves `command`+`args`
|
|
118
|
+
* against the mounted MemoryFS the way a real shell/Node would, then executes the
|
|
119
|
+
* REAL program (never faked output):
|
|
120
|
+
*
|
|
121
|
+
* - `npm run dev` / `pnpm dev` / `yarn dev` / `vite` → the genuine Vite-serve
|
|
122
|
+
* worker (preview + HMR bridges, fires `server-ready`). Unchanged.
|
|
123
|
+
* - `node <file> [args]` → runs the real file on the node-compat module loader
|
|
124
|
+
* over the mounted FS; output streams; exit resolves with the real code.
|
|
125
|
+
* - `npm run <script>` / `npm test` / `npm start` → reads package.json scripts,
|
|
126
|
+
* resolves the script's command line (which may invoke a local .bin), runs it.
|
|
127
|
+
* - `npx <bin>` and direct local bins → resolves `node_modules/.bin/<cmd>` (or a
|
|
128
|
+
* package `bin` field, walking up node_modules) to a JS entry and runs it.
|
|
129
|
+
* - `jsh` / `bash` / `sh` → the real @wc/shell (just-bash); jsh is StackBlitz's
|
|
130
|
+
* shell name, we substitute the real bash interpreter (documented).
|
|
131
|
+
* - `npm install` → an HONEST stub (deps are pre-vendored; WS5 owns a real
|
|
132
|
+
* installer). Anything genuinely unsupported throws a clear error.
|
|
133
|
+
*/
|
|
134
|
+
spawn(command: string, args?: string[], options?: SpawnOptions): Promise<WebContainerProcess>;
|
|
135
|
+
/** Register a listener for a WebContainer event; returns an unsubscribe fn. */
|
|
136
|
+
on<E extends keyof WebContainerEventMap>(event: E, listener: WebContainerEventMap[E]): () => void;
|
|
137
|
+
/** Tear down workers + Service Worker + state. Mirrors @webcontainer/api.teardown(). */
|
|
138
|
+
teardown(): void;
|
|
139
|
+
/**
|
|
140
|
+
* `export(path, options)` — serialize a subtree to a FileSystemTree / binary
|
|
141
|
+
* snapshot, mirroring @webcontainer/api. NOT yet implemented as a public facade
|
|
142
|
+
* member; MemoryFS does have `snapshot()`, but the @webcontainer/api `export`
|
|
143
|
+
* format/options (binary, includes/excludes) are not yet mapped. Documented
|
|
144
|
+
* seam, not faked.
|
|
145
|
+
*/
|
|
146
|
+
export(): never;
|
|
147
|
+
}
|