@run0/jiki 0.1.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/dist/browser-bundle.d.ts +40 -0
- package/dist/builtins.d.ts +22 -0
- package/dist/code-transform.d.ts +7 -0
- package/dist/config/cdn.d.ts +13 -0
- package/dist/container.d.ts +101 -0
- package/dist/dev-server.d.ts +69 -0
- package/dist/errors.d.ts +19 -0
- package/dist/frameworks/code-transforms.d.ts +32 -0
- package/dist/frameworks/next-api-handler.d.ts +72 -0
- package/dist/frameworks/next-dev-server.d.ts +141 -0
- package/dist/frameworks/next-html-generator.d.ts +36 -0
- package/dist/frameworks/next-route-resolver.d.ts +19 -0
- package/dist/frameworks/next-shims.d.ts +78 -0
- package/dist/frameworks/remix-dev-server.d.ts +47 -0
- package/dist/frameworks/sveltekit-dev-server.d.ts +43 -0
- package/dist/frameworks/vite-dev-server.d.ts +50 -0
- package/dist/fs-errors.d.ts +36 -0
- package/dist/index.cjs +14916 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.mjs +14898 -0
- package/dist/index.mjs.map +1 -0
- package/dist/kernel.d.ts +48 -0
- package/dist/memfs.d.ts +144 -0
- package/dist/metrics.d.ts +78 -0
- package/dist/module-resolver.d.ts +60 -0
- package/dist/network-interceptor.d.ts +71 -0
- package/dist/npm/cache.d.ts +76 -0
- package/dist/npm/index.d.ts +60 -0
- package/dist/npm/lockfile-reader.d.ts +32 -0
- package/dist/npm/pnpm.d.ts +18 -0
- package/dist/npm/registry.d.ts +45 -0
- package/dist/npm/resolver.d.ts +39 -0
- package/dist/npm/sync-installer.d.ts +18 -0
- package/dist/npm/tarball.d.ts +4 -0
- package/dist/npm/workspaces.d.ts +46 -0
- package/dist/persistence.d.ts +94 -0
- package/dist/plugin.d.ts +156 -0
- package/dist/polyfills/assert.d.ts +30 -0
- package/dist/polyfills/child_process.d.ts +116 -0
- package/dist/polyfills/chokidar.d.ts +18 -0
- package/dist/polyfills/crypto.d.ts +49 -0
- package/dist/polyfills/events.d.ts +28 -0
- package/dist/polyfills/fs.d.ts +82 -0
- package/dist/polyfills/http.d.ts +147 -0
- package/dist/polyfills/module.d.ts +29 -0
- package/dist/polyfills/net.d.ts +53 -0
- package/dist/polyfills/os.d.ts +91 -0
- package/dist/polyfills/path.d.ts +96 -0
- package/dist/polyfills/perf_hooks.d.ts +21 -0
- package/dist/polyfills/process.d.ts +99 -0
- package/dist/polyfills/querystring.d.ts +15 -0
- package/dist/polyfills/readdirp.d.ts +18 -0
- package/dist/polyfills/readline.d.ts +32 -0
- package/dist/polyfills/stream.d.ts +106 -0
- package/dist/polyfills/stubs.d.ts +737 -0
- package/dist/polyfills/tty.d.ts +25 -0
- package/dist/polyfills/url.d.ts +41 -0
- package/dist/polyfills/util.d.ts +61 -0
- package/dist/polyfills/v8.d.ts +43 -0
- package/dist/polyfills/vm.d.ts +76 -0
- package/dist/polyfills/worker-threads.d.ts +77 -0
- package/dist/polyfills/ws.d.ts +32 -0
- package/dist/polyfills/zlib.d.ts +87 -0
- package/dist/runtime-helpers.d.ts +4 -0
- package/dist/runtime-interface.d.ts +39 -0
- package/dist/sandbox.d.ts +69 -0
- package/dist/server-bridge.d.ts +55 -0
- package/dist/shell-commands.d.ts +2 -0
- package/dist/shell.d.ts +101 -0
- package/dist/transpiler.d.ts +47 -0
- package/dist/type-checker.d.ts +57 -0
- package/dist/types/package-json.d.ts +17 -0
- package/dist/utils/binary-encoding.d.ts +4 -0
- package/dist/utils/hash.d.ts +6 -0
- package/dist/utils/safe-path.d.ts +6 -0
- package/dist/worker-runtime.d.ts +34 -0
- package/package.json +59 -0
- package/src/browser-bundle.ts +498 -0
- package/src/builtins.ts +222 -0
- package/src/code-transform.ts +183 -0
- package/src/config/cdn.ts +17 -0
- package/src/container.ts +343 -0
- package/src/dev-server.ts +322 -0
- package/src/errors.ts +604 -0
- package/src/frameworks/code-transforms.ts +667 -0
- package/src/frameworks/next-api-handler.ts +366 -0
- package/src/frameworks/next-dev-server.ts +1252 -0
- package/src/frameworks/next-html-generator.ts +585 -0
- package/src/frameworks/next-route-resolver.ts +521 -0
- package/src/frameworks/next-shims.ts +1084 -0
- package/src/frameworks/remix-dev-server.ts +163 -0
- package/src/frameworks/sveltekit-dev-server.ts +197 -0
- package/src/frameworks/vite-dev-server.ts +370 -0
- package/src/fs-errors.ts +118 -0
- package/src/index.ts +188 -0
- package/src/kernel.ts +381 -0
- package/src/memfs.ts +1006 -0
- package/src/metrics.ts +140 -0
- package/src/module-resolver.ts +511 -0
- package/src/network-interceptor.ts +143 -0
- package/src/npm/cache.ts +172 -0
- package/src/npm/index.ts +377 -0
- package/src/npm/lockfile-reader.ts +105 -0
- package/src/npm/pnpm.ts +108 -0
- package/src/npm/registry.ts +120 -0
- package/src/npm/resolver.ts +339 -0
- package/src/npm/sync-installer.ts +217 -0
- package/src/npm/tarball.ts +136 -0
- package/src/npm/workspaces.ts +255 -0
- package/src/persistence.ts +235 -0
- package/src/plugin.ts +293 -0
- package/src/polyfills/assert.ts +164 -0
- package/src/polyfills/child_process.ts +535 -0
- package/src/polyfills/chokidar.ts +52 -0
- package/src/polyfills/crypto.ts +433 -0
- package/src/polyfills/events.ts +178 -0
- package/src/polyfills/fs.ts +297 -0
- package/src/polyfills/http.ts +478 -0
- package/src/polyfills/module.ts +97 -0
- package/src/polyfills/net.ts +123 -0
- package/src/polyfills/os.ts +108 -0
- package/src/polyfills/path.ts +169 -0
- package/src/polyfills/perf_hooks.ts +30 -0
- package/src/polyfills/process.ts +349 -0
- package/src/polyfills/querystring.ts +66 -0
- package/src/polyfills/readdirp.ts +72 -0
- package/src/polyfills/readline.ts +80 -0
- package/src/polyfills/stream.ts +610 -0
- package/src/polyfills/stubs.ts +600 -0
- package/src/polyfills/tty.ts +43 -0
- package/src/polyfills/url.ts +97 -0
- package/src/polyfills/util.ts +173 -0
- package/src/polyfills/v8.ts +62 -0
- package/src/polyfills/vm.ts +111 -0
- package/src/polyfills/worker-threads.ts +189 -0
- package/src/polyfills/ws.ts +73 -0
- package/src/polyfills/zlib.ts +244 -0
- package/src/runtime-helpers.ts +83 -0
- package/src/runtime-interface.ts +46 -0
- package/src/sandbox.ts +178 -0
- package/src/server-bridge.ts +473 -0
- package/src/service-worker.ts +153 -0
- package/src/shell-commands.ts +708 -0
- package/src/shell.ts +795 -0
- package/src/transpiler.ts +282 -0
- package/src/type-checker.ts +241 -0
- package/src/types/package-json.ts +17 -0
- package/src/utils/binary-encoding.ts +38 -0
- package/src/utils/hash.ts +24 -0
- package/src/utils/safe-path.ts +38 -0
- package/src/worker-runtime.ts +42 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { MemFS } from "./memfs";
|
|
2
|
+
export interface BrowserBundle {
|
|
3
|
+
modules: Map<string, string>;
|
|
4
|
+
entryPath: string;
|
|
5
|
+
depMap: Map<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export interface BundleError {
|
|
8
|
+
packageName: string;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function extractPackageName(id: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Bundle a package from the VFS for browser consumption.
|
|
14
|
+
* Reads the package entry point, transforms ESM to CJS, and recursively
|
|
15
|
+
* bundles all local dependencies. External packages and Node builtins are skipped.
|
|
16
|
+
*/
|
|
17
|
+
export declare function bundlePackageForBrowser(vfs: MemFS, packageName: string, externals: Set<string>): BrowserBundle;
|
|
18
|
+
/**
|
|
19
|
+
* Generate a `<script>` containing a require() shim and all bundled modules.
|
|
20
|
+
* Globals map package names to window properties (e.g. { "react": "React" }).
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateRequireScript(bundles: Map<string, BrowserBundle>, globals: Record<string, string>): string;
|
|
23
|
+
/**
|
|
24
|
+
* Transform ES module `import` statements into `window.require()` calls.
|
|
25
|
+
* Used to pre-process component source before host-side JSX transpilation
|
|
26
|
+
* via esbuild. The output is plain JS that can run in a regular `<script>` tag.
|
|
27
|
+
*
|
|
28
|
+
* Uses `var` (not `const`) so declarations hoist to function/global scope.
|
|
29
|
+
* Uses `window.require` (not bare `require`) to avoid strict-mode scoping issues.
|
|
30
|
+
*/
|
|
31
|
+
export declare function preprocessImports(code: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Scan source files for bare-specifier imports (e.g. `import { X } from 'pkg'`
|
|
34
|
+
* or `import { Y } from '@scope/pkg/subpath'`).
|
|
35
|
+
* Returns a set of unique full import specifiers found, preserving subpaths
|
|
36
|
+
* so they can be individually resolved and bundled.
|
|
37
|
+
* Handles: named imports, default imports, namespace imports, multi-line destructuring.
|
|
38
|
+
* Skips: `import type` (TS type-only imports), side-effect imports without a specifier.
|
|
39
|
+
*/
|
|
40
|
+
export declare function scanBareImports(sources: string[]): Set<string>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { bufferModule as _bufferMod } from "./polyfills/stream";
|
|
2
|
+
export { _bufferMod as bufferPolyfill };
|
|
3
|
+
export declare function resolveBuiltin(name: string): unknown | undefined;
|
|
4
|
+
export declare function isBuiltinModule(name: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Register a custom polyfill for a built-in module name.
|
|
7
|
+
* Replaces any existing polyfill for the same name.
|
|
8
|
+
* The factory is called lazily on first `require()`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerBuiltin(name: string, factory: () => unknown): void;
|
|
11
|
+
/**
|
|
12
|
+
* Register multiple custom polyfills at once.
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerBuiltins(map: Record<string, () => unknown>): void;
|
|
15
|
+
/**
|
|
16
|
+
* Unregister a custom polyfill, reverting to the default (if any was
|
|
17
|
+
* overridden) or removing the module entirely.
|
|
18
|
+
*/
|
|
19
|
+
export declare function unregisterBuiltin(name: string): void;
|
|
20
|
+
/** Return a list of all registered builtin module names. */
|
|
21
|
+
export declare function listBuiltins(): string[];
|
|
22
|
+
export declare const builtinModules: Record<string, unknown>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const tsCache: Map<string, string>;
|
|
2
|
+
export { tsCache as transpileCache };
|
|
3
|
+
export declare function removeShebang(source: string): string;
|
|
4
|
+
export declare function transformEsmToCjs(source: string, file: string): string;
|
|
5
|
+
export declare function processSource(source: string, file: string, sourceMaps?: boolean): string;
|
|
6
|
+
export declare function getProcessedSource(rawSource: string, filepath: string, cache: Map<string, string>, sourceMaps?: boolean): string;
|
|
7
|
+
export declare function ensureTranspiled(file: string, source: string): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized CDN version pins and URLs.
|
|
3
|
+
* Change versions here to update them across the entire platform.
|
|
4
|
+
*/
|
|
5
|
+
export declare const REACT_VERSION = "18.2.0";
|
|
6
|
+
export declare const ESBUILD_WASM_VERSION = "0.20.0";
|
|
7
|
+
export declare const REACT_REFRESH_VERSION = "0.14.0";
|
|
8
|
+
export declare const REACT_CDN = "https://esm.sh/react@18.2.0";
|
|
9
|
+
export declare const REACT_DOM_CDN = "https://esm.sh/react-dom@18.2.0";
|
|
10
|
+
export declare const REACT_REFRESH_CDN = "https://esm.sh/react-refresh@0.14.0/runtime";
|
|
11
|
+
export declare const ESBUILD_WASM_ESM_CDN = "https://esm.sh/esbuild-wasm@0.20.0";
|
|
12
|
+
export declare const ESBUILD_WASM_BINARY_CDN = "https://unpkg.com/esbuild-wasm@0.20.0/esbuild.wasm";
|
|
13
|
+
export declare const TAILWIND_CDN_URL = "https://cdn.tailwindcss.com";
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { MemFS } from "./memfs";
|
|
2
|
+
import { Kernel } from "./kernel";
|
|
3
|
+
import { PackageManager, InstallOptions, InstallResult } from "./npm/index";
|
|
4
|
+
import { Shell, ShellOptions } from "./shell";
|
|
5
|
+
import type { IExecuteResult, VFSSnapshot } from "./runtime-interface";
|
|
6
|
+
import { PluginRegistry, type JikiPlugin } from "./plugin";
|
|
7
|
+
import type { PersistenceAdapter } from "./persistence";
|
|
8
|
+
import { SandboxGuard, type SandboxOptions } from "./sandbox";
|
|
9
|
+
import { Metrics } from "./metrics";
|
|
10
|
+
import { NetworkInterceptor, type MockResponse } from "./network-interceptor";
|
|
11
|
+
export interface ContainerOptions {
|
|
12
|
+
cwd?: string;
|
|
13
|
+
env?: Record<string, string>;
|
|
14
|
+
registry?: string;
|
|
15
|
+
/** `'npm'` (default) or `'pnpm'` */
|
|
16
|
+
packageManager?: "npm" | "pnpm";
|
|
17
|
+
/** Automatically install missing packages on require() */
|
|
18
|
+
autoInstall?: boolean;
|
|
19
|
+
onConsole?: (method: string, args: unknown[]) => void;
|
|
20
|
+
onStdout?: (data: string) => void;
|
|
21
|
+
onStderr?: (data: string) => void;
|
|
22
|
+
/** Plugins to register on this container. */
|
|
23
|
+
plugins?: JikiPlugin[];
|
|
24
|
+
/** Persistence adapter for surviving page refreshes. */
|
|
25
|
+
persistence?: PersistenceAdapter;
|
|
26
|
+
/** Enable inline source maps for TypeScript/JSX transpilation (default: false). */
|
|
27
|
+
sourceMaps?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Worker mode for CPU-intensive operations.
|
|
30
|
+
* - `false` (default) — everything on the main thread
|
|
31
|
+
* - `true` — transpilation runs in a Web Worker
|
|
32
|
+
* - `'auto'` — use workers when available (browser), skip in Node.js
|
|
33
|
+
*/
|
|
34
|
+
worker?: boolean | "auto";
|
|
35
|
+
/** Resource limits and access controls. */
|
|
36
|
+
sandbox?: SandboxOptions;
|
|
37
|
+
}
|
|
38
|
+
export interface RunOptions extends ShellOptions {
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
}
|
|
41
|
+
export interface RunResult {
|
|
42
|
+
stdout: string;
|
|
43
|
+
stderr: string;
|
|
44
|
+
exitCode: number;
|
|
45
|
+
}
|
|
46
|
+
export declare class Container {
|
|
47
|
+
readonly vfs: MemFS;
|
|
48
|
+
readonly runtime: Kernel;
|
|
49
|
+
readonly packageManager: PackageManager;
|
|
50
|
+
readonly shell: Shell;
|
|
51
|
+
/** Plugin registry for this container. */
|
|
52
|
+
readonly plugins: PluginRegistry;
|
|
53
|
+
/** Sandbox guard enforcing resource limits. */
|
|
54
|
+
readonly sandbox: SandboxGuard;
|
|
55
|
+
/** Performance metrics for this container. */
|
|
56
|
+
readonly metrics: Metrics;
|
|
57
|
+
/** Network request interceptor for mocking fetch calls. */
|
|
58
|
+
readonly network: NetworkInterceptor;
|
|
59
|
+
private _pnpmPm?;
|
|
60
|
+
private _containerCwd;
|
|
61
|
+
private _containerRegistry?;
|
|
62
|
+
private _workerMode;
|
|
63
|
+
constructor(options?: ContainerOptions);
|
|
64
|
+
private get lazyPnpmPm();
|
|
65
|
+
init(options?: {
|
|
66
|
+
wasmURL?: string | URL;
|
|
67
|
+
}): Promise<void>;
|
|
68
|
+
writeFile(path: string, content: string | Uint8Array): void;
|
|
69
|
+
readFile(path: string): string;
|
|
70
|
+
readFile(path: string, encoding: null): Uint8Array;
|
|
71
|
+
mkdir(path: string): void;
|
|
72
|
+
readdir(path: string): string[];
|
|
73
|
+
exists(path: string): boolean;
|
|
74
|
+
rm(path: string): void;
|
|
75
|
+
execute(code: string, filename?: string): IExecuteResult;
|
|
76
|
+
runFile(filename: string): IExecuteResult;
|
|
77
|
+
run(command: string, options?: RunOptions): Promise<RunResult>;
|
|
78
|
+
sendInput(data: string): void;
|
|
79
|
+
/** Register a custom polyfill for a built-in module. */
|
|
80
|
+
registerPolyfill(name: string, factory: () => unknown): void;
|
|
81
|
+
/** Register multiple custom polyfills at once. */
|
|
82
|
+
registerPolyfills(map: Record<string, () => unknown>): void;
|
|
83
|
+
/** Unregister a custom polyfill. */
|
|
84
|
+
unregisterPolyfill(name: string): void;
|
|
85
|
+
/** Mock a fetch URL with a static response. */
|
|
86
|
+
mockFetch(pattern: string | RegExp, response: MockResponse): void;
|
|
87
|
+
/** Register a dynamic fetch interceptor. */
|
|
88
|
+
onFetch(handler: (url: string, init?: RequestInit) => MockResponse | null | undefined | Promise<MockResponse | null | undefined>): void;
|
|
89
|
+
/** Get a snapshot of performance metrics. */
|
|
90
|
+
getMetrics(): import("./metrics").MetricsSnapshot;
|
|
91
|
+
install(packages: string | string[], options?: InstallOptions): Promise<InstallResult>;
|
|
92
|
+
installDependencies(options?: InstallOptions): Promise<InstallResult>;
|
|
93
|
+
toSnapshot(): VFSSnapshot;
|
|
94
|
+
static fromSnapshot(snapshot: VFSSnapshot, options?: ContainerOptions): Container;
|
|
95
|
+
export(path?: string): Record<string, unknown>;
|
|
96
|
+
destroy(): void;
|
|
97
|
+
}
|
|
98
|
+
/** Register a plugin on an existing container (post-construction). */
|
|
99
|
+
export declare function registerPlugin(container: Container, plugin: JikiPlugin): void;
|
|
100
|
+
export declare function boot(options?: ContainerOptions): Container;
|
|
101
|
+
export { boot as createContainer };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { EventEmitter } from "./polyfills/events";
|
|
2
|
+
import { MemFS } from "./memfs";
|
|
3
|
+
import { BufferImpl as Buffer } from "./polyfills/stream";
|
|
4
|
+
export interface DevServerOptions {
|
|
5
|
+
port: number;
|
|
6
|
+
root?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ResponseData {
|
|
9
|
+
statusCode: number;
|
|
10
|
+
statusMessage: string;
|
|
11
|
+
headers: Record<string, string>;
|
|
12
|
+
body: Buffer;
|
|
13
|
+
}
|
|
14
|
+
export interface HMRUpdate {
|
|
15
|
+
type: "update" | "full-reload";
|
|
16
|
+
path: string;
|
|
17
|
+
timestamp?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check if a filename contains a content hash (e.g., app.a1b2c3d4.js, chunk-HASH.css).
|
|
21
|
+
* Content-hashed files are safe to cache immutably since the hash changes when content changes.
|
|
22
|
+
*/
|
|
23
|
+
declare function hasContentHash(filepath: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Determine the appropriate Cache-Control header for a given file path.
|
|
26
|
+
* - Content-hashed assets get immutable caching (1 year)
|
|
27
|
+
* - HTML and non-hashed assets get no-cache for development freshness
|
|
28
|
+
*/
|
|
29
|
+
declare function inferCacheControl(filepath: string): string;
|
|
30
|
+
export declare abstract class DevServer extends EventEmitter {
|
|
31
|
+
protected vfs: MemFS;
|
|
32
|
+
protected port: number;
|
|
33
|
+
protected root: string;
|
|
34
|
+
protected running: boolean;
|
|
35
|
+
constructor(vfs: MemFS, options: DevServerOptions);
|
|
36
|
+
abstract handleRequest(method: string, url: string, headers: Record<string, string>, body?: Buffer): Promise<ResponseData>;
|
|
37
|
+
abstract startWatching(): void;
|
|
38
|
+
/**
|
|
39
|
+
* CORS headers added to all responses for cross-origin iframe support.
|
|
40
|
+
* This is essential since the dev server is typically accessed from
|
|
41
|
+
* a sandboxed iframe on a different origin.
|
|
42
|
+
*/
|
|
43
|
+
private static readonly CORS_HEADERS;
|
|
44
|
+
/**
|
|
45
|
+
* Add CORS headers to a response.
|
|
46
|
+
*/
|
|
47
|
+
protected addCorsHeaders(response: ResponseData): ResponseData;
|
|
48
|
+
/**
|
|
49
|
+
* Handle CORS preflight OPTIONS requests.
|
|
50
|
+
*/
|
|
51
|
+
protected handleOptionsRequest(): ResponseData;
|
|
52
|
+
stop(): void;
|
|
53
|
+
start(): void;
|
|
54
|
+
isRunning(): boolean;
|
|
55
|
+
getPort(): number;
|
|
56
|
+
protected serveFile(filePath: string): ResponseData;
|
|
57
|
+
protected resolvePath(urlPath: string): string;
|
|
58
|
+
protected notFound(path: string): ResponseData;
|
|
59
|
+
protected serverError(error: unknown): ResponseData;
|
|
60
|
+
protected redirect(location: string, status?: 301 | 302 | 307 | 308): ResponseData;
|
|
61
|
+
protected getMimeType(path: string): string;
|
|
62
|
+
protected exists(path: string): boolean;
|
|
63
|
+
protected isDirectory(path: string): boolean;
|
|
64
|
+
protected broadcastChange(update: HMRUpdate): void;
|
|
65
|
+
/** @deprecated Use broadcastChange instead */
|
|
66
|
+
protected emitHMRUpdate(update: HMRUpdate): void;
|
|
67
|
+
}
|
|
68
|
+
export { hasContentHash, inferCacheControl };
|
|
69
|
+
export default DevServer;
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type ErrorCategory = "build" | "runtime" | "bundle" | "install" | "filesystem";
|
|
2
|
+
export interface ContainerError {
|
|
3
|
+
id: string;
|
|
4
|
+
category: ErrorCategory;
|
|
5
|
+
title: string;
|
|
6
|
+
message: string;
|
|
7
|
+
file?: string;
|
|
8
|
+
line?: number;
|
|
9
|
+
column?: number;
|
|
10
|
+
stack?: string;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
raw?: unknown;
|
|
13
|
+
/** Actionable fix suggestions for the error. */
|
|
14
|
+
suggestions?: string[];
|
|
15
|
+
}
|
|
16
|
+
export declare function parseError(category: ErrorCategory, raw: unknown): ContainerError;
|
|
17
|
+
export declare function formatErrorText(error: ContainerError): string;
|
|
18
|
+
export declare function formatErrorHtml(error: ContainerError): string;
|
|
19
|
+
export declare function errorOverlayScript(): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code transformation utilities for ESM/CJS conversion, CSS imports,
|
|
3
|
+
* npm import redirection, and React Refresh registration.
|
|
4
|
+
*/
|
|
5
|
+
export interface CssModuleContext {
|
|
6
|
+
readFile: (path: string) => string;
|
|
7
|
+
exists: (path: string) => boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function transformEsmToCjsSimple(code: string): string;
|
|
10
|
+
export declare function resolveRelativePath(dir: string, relativePath: string): string;
|
|
11
|
+
export declare function resolveCssModulePath(cssPath: string, currentFile: string | undefined, ctx: CssModuleContext): string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Generate replacement code for a CSS Module import.
|
|
14
|
+
* Parses the CSS file, extracts class names via regex (no css-tree dependency),
|
|
15
|
+
* generates scoped names, and injects the scoped CSS via a style tag.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateCssModuleReplacement(varName: string, cssPath: string, currentFile: string | undefined, ctx: CssModuleContext): string;
|
|
18
|
+
/**
|
|
19
|
+
* Strip CSS imports from code. CSS Module imports (*.module.css) are converted
|
|
20
|
+
* to inline objects with class name mappings. Regular CSS imports are removed.
|
|
21
|
+
*/
|
|
22
|
+
export declare function stripCssImports(code: string, currentFile: string | undefined, ctx: CssModuleContext): string;
|
|
23
|
+
/**
|
|
24
|
+
* Redirect bare npm package imports to esm.sh CDN URLs.
|
|
25
|
+
* Uses acorn AST for precision, falls back to regex.
|
|
26
|
+
*/
|
|
27
|
+
export declare function redirectNpmImports(code: string, additionalLocalPackages?: string[], dependencies?: Record<string, string>, esmShDeps?: string, installedPackages?: Set<string>): string;
|
|
28
|
+
/**
|
|
29
|
+
* Add React Refresh registration to transformed code.
|
|
30
|
+
* Enables true HMR (state-preserving) for React components.
|
|
31
|
+
*/
|
|
32
|
+
export declare function addReactRefresh(code: string, filename: string): string;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js API route handling
|
|
3
|
+
* Standalone functions extracted from NextDevServer for creating mock
|
|
4
|
+
* request/response objects and executing API handlers.
|
|
5
|
+
*/
|
|
6
|
+
import { ResponseData } from "../dev-server";
|
|
7
|
+
import { BufferImpl as Buffer } from "../polyfills/stream";
|
|
8
|
+
/**
|
|
9
|
+
* Parse cookie header into key-value pairs
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseCookies(cookieHeader: string): Record<string, string>;
|
|
12
|
+
/**
|
|
13
|
+
* Create mock Next.js request object
|
|
14
|
+
*/
|
|
15
|
+
export declare function createMockRequest(method: string, pathname: string, headers: Record<string, string>, body?: Buffer): {
|
|
16
|
+
method: string;
|
|
17
|
+
url: string;
|
|
18
|
+
headers: Record<string, string>;
|
|
19
|
+
query: {
|
|
20
|
+
[k: string]: string;
|
|
21
|
+
};
|
|
22
|
+
body: any;
|
|
23
|
+
cookies: Record<string, string>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Create mock Next.js response object with streaming support
|
|
27
|
+
*/
|
|
28
|
+
export declare function createMockResponse(): {
|
|
29
|
+
headersSent: boolean;
|
|
30
|
+
status(code: number): /*elided*/ any;
|
|
31
|
+
setHeader(name: string, value: string): /*elided*/ any;
|
|
32
|
+
getHeader(name: string): string;
|
|
33
|
+
write(chunk: string | Buffer): boolean;
|
|
34
|
+
readonly writable: boolean;
|
|
35
|
+
json(data: unknown): /*elided*/ any;
|
|
36
|
+
send(data: string | object): /*elided*/ any;
|
|
37
|
+
end(data?: string): /*elided*/ any;
|
|
38
|
+
redirect(statusOrUrl: number | string, url?: string): /*elided*/ any;
|
|
39
|
+
isEnded(): boolean;
|
|
40
|
+
waitForEnd(): Promise<void>;
|
|
41
|
+
toResponse(): ResponseData;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Create a streaming mock response that calls callbacks as data is written
|
|
45
|
+
*/
|
|
46
|
+
export declare function createStreamingMockResponse(onStart: (statusCode: number, statusMessage: string, headers: Record<string, string>) => void, onChunk: (chunk: string | Uint8Array) => void, onEnd: () => void): {
|
|
47
|
+
headersSent: boolean;
|
|
48
|
+
status(code: number): /*elided*/ any;
|
|
49
|
+
setHeader(name: string, value: string): /*elided*/ any;
|
|
50
|
+
getHeader(name: string): string;
|
|
51
|
+
write(chunk: string | Buffer): boolean;
|
|
52
|
+
readonly writable: boolean;
|
|
53
|
+
json(data: unknown): /*elided*/ any;
|
|
54
|
+
send(data: string | object): /*elided*/ any;
|
|
55
|
+
end(data?: string): /*elided*/ any;
|
|
56
|
+
redirect(statusOrUrl: number | string, url?: string): /*elided*/ any;
|
|
57
|
+
isEnded(): boolean;
|
|
58
|
+
waitForEnd(): Promise<void>;
|
|
59
|
+
toResponse(): ResponseData;
|
|
60
|
+
};
|
|
61
|
+
/** Type for mock response objects */
|
|
62
|
+
export type MockResponse = ReturnType<typeof createMockResponse>;
|
|
63
|
+
export type MockRequest = ReturnType<typeof createMockRequest>;
|
|
64
|
+
export type StreamingMockResponse = ReturnType<typeof createStreamingMockResponse>;
|
|
65
|
+
/**
|
|
66
|
+
* Create builtin modules map for API handler execution.
|
|
67
|
+
*/
|
|
68
|
+
export declare function createBuiltinModules(): Record<string, unknown>;
|
|
69
|
+
/**
|
|
70
|
+
* Execute API handler code in a sandboxed context
|
|
71
|
+
*/
|
|
72
|
+
export declare function executeApiHandler(code: string, req: MockRequest, res: MockResponse | StreamingMockResponse, env: Record<string, string> | undefined, builtinModules: Record<string, unknown>, vfsRequire?: (id: string) => unknown): Promise<unknown>;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NextDevServer - Next.js-compatible dev server for the web-containers environment.
|
|
3
|
+
* Implements file-based routing, API routes, and HMR via postMessage.
|
|
4
|
+
*
|
|
5
|
+
* ## Framework Dev Server Roadmap
|
|
6
|
+
*
|
|
7
|
+
* Currently supported:
|
|
8
|
+
* - **Next.js** (Pages Router + App Router) — implemented in this file.
|
|
9
|
+
*
|
|
10
|
+
* Planned framework support:
|
|
11
|
+
* - **Vite SSR** — generic Vite-based dev server with SSR support.
|
|
12
|
+
* - **Remix** — loader/action-based routing with nested layouts.
|
|
13
|
+
* - **SvelteKit** — file-based routing with server-side load functions.
|
|
14
|
+
* - **Nuxt** — Vue-based file-system routing and server routes.
|
|
15
|
+
* - **Astro** — content-focused with island architecture.
|
|
16
|
+
* - **SolidStart** — SolidJS file-based routing with SSR.
|
|
17
|
+
*
|
|
18
|
+
* To add a new framework dev server, implement the {@link DevServer} base class
|
|
19
|
+
* from `../dev-server.ts`. The base class provides `handleRequest()` dispatch,
|
|
20
|
+
* static file serving, HMR event emission, and port management. The subclass
|
|
21
|
+
* must implement route resolution, code transformation, and HTML generation.
|
|
22
|
+
*
|
|
23
|
+
* ## Unsupported Next.js Features
|
|
24
|
+
*
|
|
25
|
+
* The following Next.js features are NOT supported in this browser-based runtime:
|
|
26
|
+
*
|
|
27
|
+
* - **Middleware** (`middleware.ts`): Edge runtime middleware is not executed.
|
|
28
|
+
* Requests go directly to route handlers without middleware interception.
|
|
29
|
+
*
|
|
30
|
+
* - **Server Actions**: React Server Actions (`"use server"` directive) are not
|
|
31
|
+
* supported. Form submissions using server actions will not work.
|
|
32
|
+
*
|
|
33
|
+
* - **React Server Components (RSC)**: All components run as client components.
|
|
34
|
+
* The `"use client"` directive is accepted but has no effect since everything
|
|
35
|
+
* is already client-side.
|
|
36
|
+
*
|
|
37
|
+
* - **Incremental Static Regeneration (ISR)**: `revalidate` options in
|
|
38
|
+
* `getStaticProps` or route segment configs are ignored. Pages are always
|
|
39
|
+
* rendered on demand.
|
|
40
|
+
*
|
|
41
|
+
* - **Internationalization (i18n)**: The `i18n` configuration in `next.config.js`
|
|
42
|
+
* is not processed. Locale detection and routing are not performed.
|
|
43
|
+
*
|
|
44
|
+
* - **Rewrites and Redirects**: Configuration-based rewrites and redirects from
|
|
45
|
+
* `next.config.js` are not applied. Use client-side routing instead.
|
|
46
|
+
*
|
|
47
|
+
* - **Parallel Routes and Intercepting Routes**: Advanced App Router patterns
|
|
48
|
+
* like `@slot` parallel routes and `(..)` intercepting routes are not supported.
|
|
49
|
+
*
|
|
50
|
+
* - **Image Optimization**: The `next/image` component renders a plain `<img>` tag.
|
|
51
|
+
* No server-side image optimization is performed.
|
|
52
|
+
*
|
|
53
|
+
* - **Edge Runtime**: API routes and pages cannot use `export const runtime = 'edge'`.
|
|
54
|
+
* All execution happens in the browser's main thread.
|
|
55
|
+
*/
|
|
56
|
+
import { DevServer, type DevServerOptions, type ResponseData } from "../dev-server";
|
|
57
|
+
import { MemFS } from "../memfs";
|
|
58
|
+
import { BufferImpl as Buffer } from "../polyfills/stream";
|
|
59
|
+
declare global {
|
|
60
|
+
interface Window {
|
|
61
|
+
__esbuild?: typeof import("esbuild-wasm");
|
|
62
|
+
__esbuildInitPromise?: Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export interface NextDevServerOptions extends DevServerOptions {
|
|
66
|
+
pagesDir?: string;
|
|
67
|
+
appDir?: string;
|
|
68
|
+
publicDir?: string;
|
|
69
|
+
preferAppRouter?: boolean;
|
|
70
|
+
env?: Record<string, string>;
|
|
71
|
+
basePath?: string;
|
|
72
|
+
additionalImportMap?: Record<string, string>;
|
|
73
|
+
additionalLocalPackages?: string[];
|
|
74
|
+
esmShDeps?: string;
|
|
75
|
+
/** Timeout in milliseconds for API handler execution. Defaults to 30000 (30s). */
|
|
76
|
+
apiHandlerTimeout?: number;
|
|
77
|
+
}
|
|
78
|
+
export declare class NextDevServer extends DevServer {
|
|
79
|
+
private pagesDir;
|
|
80
|
+
private appDir;
|
|
81
|
+
private publicDir;
|
|
82
|
+
private useAppRouter;
|
|
83
|
+
private watcherCleanup;
|
|
84
|
+
private hmrTargetWindow;
|
|
85
|
+
private options;
|
|
86
|
+
private transformCache;
|
|
87
|
+
private pathAliases;
|
|
88
|
+
private basePath;
|
|
89
|
+
private get routeCtx();
|
|
90
|
+
constructor(vfs: MemFS, options: NextDevServerOptions);
|
|
91
|
+
private loadPathAliases;
|
|
92
|
+
private resolvePathAliases;
|
|
93
|
+
setEnv(key: string, value: string): void;
|
|
94
|
+
getEnv(): Record<string, string>;
|
|
95
|
+
/**
|
|
96
|
+
* Set the target window for HMR updates (typically iframe.contentWindow).
|
|
97
|
+
* Enables postMessage-based HMR delivery to sandboxed iframes.
|
|
98
|
+
*/
|
|
99
|
+
setHMRTarget(targetWindow: Window): void;
|
|
100
|
+
private generateEnvScript;
|
|
101
|
+
handleRequest(method: string, url: string, headers: Record<string, string>, body?: Buffer): Promise<ResponseData>;
|
|
102
|
+
private serveNextShim;
|
|
103
|
+
private serveRouteInfo;
|
|
104
|
+
private servePageComponent;
|
|
105
|
+
private serveAppComponent;
|
|
106
|
+
private handleApiRoute;
|
|
107
|
+
private handleAppRouteHandler;
|
|
108
|
+
private handlePageRoute;
|
|
109
|
+
private handleAppRouterPage;
|
|
110
|
+
private _tailwindConfigCache;
|
|
111
|
+
private loadTailwindConfig;
|
|
112
|
+
private htmlContext;
|
|
113
|
+
private generateAppRouterHtml;
|
|
114
|
+
private generatePageHtml;
|
|
115
|
+
private serve404Page;
|
|
116
|
+
private transformAndServe;
|
|
117
|
+
private transformCode;
|
|
118
|
+
private _dependencies;
|
|
119
|
+
private getDependencies;
|
|
120
|
+
private _installedPackages;
|
|
121
|
+
private getInstalledPackages;
|
|
122
|
+
invalidatePackageCache(): void;
|
|
123
|
+
private doRedirectNpmImports;
|
|
124
|
+
private doStripCssImports;
|
|
125
|
+
private getCssModuleContext;
|
|
126
|
+
private transformApiHandler;
|
|
127
|
+
protected serveFile(filePath: string): ResponseData;
|
|
128
|
+
/**
|
|
129
|
+
* Serve an npm module from /node_modules/ with ESM-to-CJS transform.
|
|
130
|
+
* Accessed via /_npm/{package}/{file} URLs from the import map.
|
|
131
|
+
*/
|
|
132
|
+
private serveNpmModule;
|
|
133
|
+
/**
|
|
134
|
+
* Start file watching for HMR.
|
|
135
|
+
* Watches /pages, /app, and /public for changes and emits HMR updates.
|
|
136
|
+
*/
|
|
137
|
+
startWatching(): void;
|
|
138
|
+
private handleFileChange;
|
|
139
|
+
stop(): void;
|
|
140
|
+
}
|
|
141
|
+
export default NextDevServer;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js HTML page generation
|
|
3
|
+
* Standalone functions extracted from NextDevServer for generating
|
|
4
|
+
* App Router HTML, Pages Router HTML, and 404 pages.
|
|
5
|
+
*/
|
|
6
|
+
import { ResponseData } from "../dev-server";
|
|
7
|
+
/** Resolved App Router route with page, layouts, and UI convention files */
|
|
8
|
+
export interface AppRoute {
|
|
9
|
+
page: string;
|
|
10
|
+
layouts: string[];
|
|
11
|
+
params: Record<string, string | string[]>;
|
|
12
|
+
loading?: string;
|
|
13
|
+
error?: string;
|
|
14
|
+
notFound?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Context needed by HTML generation functions */
|
|
17
|
+
export interface HtmlGeneratorContext {
|
|
18
|
+
port: number;
|
|
19
|
+
exists: (path: string) => boolean;
|
|
20
|
+
generateEnvScript: () => string;
|
|
21
|
+
loadTailwindConfigIfNeeded: () => Promise<string>;
|
|
22
|
+
/** Additional import map entries (e.g., framework-specific CDN mappings) */
|
|
23
|
+
additionalImportMap?: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Generate HTML for App Router with nested layouts
|
|
27
|
+
*/
|
|
28
|
+
export declare function generateAppRouterHtml(ctx: HtmlGeneratorContext, route: AppRoute, pathname: string): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Generate HTML shell for a Pages Router page
|
|
31
|
+
*/
|
|
32
|
+
export declare function generatePageHtml(ctx: HtmlGeneratorContext, pageFile: string, pathname: string): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Serve a basic 404 page
|
|
35
|
+
*/
|
|
36
|
+
export declare function serve404Page(port: number): ResponseData;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js route resolution
|
|
3
|
+
* Standalone functions for resolving App Router routes, Pages Router routes,
|
|
4
|
+
* API routes, and file extensions.
|
|
5
|
+
*/
|
|
6
|
+
import { type AppRoute } from "./next-html-generator";
|
|
7
|
+
/** Context needed by route resolution functions */
|
|
8
|
+
export interface RouteResolverContext {
|
|
9
|
+
exists: (path: string) => boolean;
|
|
10
|
+
isDirectory: (path: string) => boolean;
|
|
11
|
+
readdir: (path: string) => string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function hasAppRouter(appDir: string, ctx: RouteResolverContext): boolean;
|
|
14
|
+
export declare function resolveAppRoute(appDir: string, pathname: string, ctx: RouteResolverContext): AppRoute | null;
|
|
15
|
+
export declare function resolveAppRouteHandler(appDir: string, pathname: string, ctx: RouteResolverContext): string | null;
|
|
16
|
+
export declare function resolvePageFile(pagesDir: string, pathname: string, ctx: RouteResolverContext): string | null;
|
|
17
|
+
export declare function resolveApiFile(pagesDir: string, pathname: string, ctx: RouteResolverContext): string | null;
|
|
18
|
+
export declare function resolveFileWithExtension(pathname: string, ctx: RouteResolverContext): string | null;
|
|
19
|
+
export declare function needsTransform(path: string): boolean;
|