env-runner 0.1.9 → 0.1.10
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 +112 -15
- package/dist/_chunks/base-runner.d.mts +46 -3
- package/dist/_chunks/base-runner.mjs +28 -1
- package/dist/_chunks/libs/cjs-module-lexer.mjs +1 -1
- package/dist/_chunks/runner.d.mts +3 -3
- package/dist/_chunks/runner.mjs +6 -3
- package/dist/_chunks/runner2.d.mts +3 -3
- package/dist/_chunks/runner2.mjs +66 -16
- package/dist/_chunks/runner3.d.mts +3 -3
- package/dist/_chunks/runner3.mjs +3 -3
- package/dist/_chunks/runner4.d.mts +4 -4
- package/dist/_chunks/runner4.mjs +2 -2
- package/dist/_chunks/runner5.d.mts +4 -4
- package/dist/_chunks/runner5.mjs +2 -2
- package/dist/_chunks/server.mjs +25 -9
- package/dist/_chunks/types.d.mts +4 -2
- package/dist/_chunks/virtual-loader.mjs +39 -0
- package/dist/_chunks/worker-utils.mjs +86 -9
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +23 -11
- package/dist/index.mjs +6 -6
- package/dist/runners/bun-process/runner.d.mts +2 -2
- package/dist/runners/bun-process/runner.mjs +12 -2
- package/dist/runners/bun-process/worker.mjs +19 -3
- package/dist/runners/deno-process/runner.d.mts +2 -2
- package/dist/runners/deno-process/runner.mjs +1 -1
- package/dist/runners/deno-process/worker.mjs +18 -3
- package/dist/runners/miniflare/runner.d.mts +2 -2
- package/dist/runners/miniflare/runner.mjs +1 -1
- package/dist/runners/netlify/runner.d.mts +2 -2
- package/dist/runners/netlify/runner.mjs +1 -1
- package/dist/runners/node-process/runner.d.mts +2 -2
- package/dist/runners/node-process/runner.mjs +4 -2
- package/dist/runners/node-process/worker.mjs +19 -3
- package/dist/runners/node-worker/runner.d.mts +2 -2
- package/dist/runners/node-worker/runner.mjs +1 -1
- package/dist/runners/node-worker/worker.mjs +18 -3
- package/dist/runners/self/runner.d.mts +2 -2
- package/dist/runners/self/runner.mjs +2 -2
- package/dist/runners/vercel/runner.d.mts +2 -2
- package/dist/runners/vercel/runner.mjs +1 -1
- package/dist/vite.d.mts +1 -1
- package/package.json +11 -11
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { WorkerHooks } from "./types.mjs";
|
|
2
|
+
import { EnvRunnerData } from "./base-runner.mjs";
|
|
3
|
+
import { NodeWorkerEnvRunner } from "./runner3.mjs";
|
|
4
4
|
declare class NetlifyEnvRunner extends NodeWorkerEnvRunner {
|
|
5
5
|
constructor(opts: {
|
|
6
6
|
name: string;
|
|
@@ -11,4 +11,4 @@ declare class NetlifyEnvRunner extends NodeWorkerEnvRunner {
|
|
|
11
11
|
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
12
12
|
protected _runtimeType(): string;
|
|
13
13
|
}
|
|
14
|
-
export { NetlifyEnvRunner
|
|
14
|
+
export { NetlifyEnvRunner };
|
package/dist/_chunks/runner5.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NodeWorkerEnvRunner } from "./runner3.mjs";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
let _defaultEntry;
|
|
4
4
|
var NetlifyEnvRunner = class extends NodeWorkerEnvRunner {
|
|
@@ -42,4 +42,4 @@ var NetlifyEnvRunner = class extends NodeWorkerEnvRunner {
|
|
|
42
42
|
return "netlify";
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
-
export { NetlifyEnvRunner
|
|
45
|
+
export { NetlifyEnvRunner };
|
package/dist/_chunks/server.mjs
CHANGED
|
@@ -24,11 +24,12 @@ var RunnerManager = class {
|
|
|
24
24
|
this._reloading = false;
|
|
25
25
|
if (prev) await prev.close();
|
|
26
26
|
}
|
|
27
|
-
fetch =
|
|
27
|
+
fetch = (input, init) => this._fetch(input, init);
|
|
28
|
+
async _fetch(input, init) {
|
|
28
29
|
const runner = await this._waitForRunner();
|
|
29
30
|
if (!runner) return new Response("Runner is unavailable", { status: 503 });
|
|
30
31
|
return runner.fetch(input, init);
|
|
31
|
-
}
|
|
32
|
+
}
|
|
32
33
|
upgrade = (context) => {
|
|
33
34
|
this._runner?.upgrade?.(context);
|
|
34
35
|
};
|
|
@@ -102,6 +103,9 @@ var RunnerManager = class {
|
|
|
102
103
|
this._detach();
|
|
103
104
|
if (runner) await runner.close();
|
|
104
105
|
}
|
|
106
|
+
async [Symbol.asyncDispose]() {
|
|
107
|
+
await this.close();
|
|
108
|
+
}
|
|
105
109
|
onClose(listener) {
|
|
106
110
|
this._closeListeners.add(listener);
|
|
107
111
|
}
|
|
@@ -179,6 +183,7 @@ var EnvServer = class extends RunnerManager {
|
|
|
179
183
|
_watchers = [];
|
|
180
184
|
_reloadTimeout;
|
|
181
185
|
_reloadListeners = /* @__PURE__ */ new Set();
|
|
186
|
+
_startPromise;
|
|
182
187
|
runner = null;
|
|
183
188
|
onReload(listener) {
|
|
184
189
|
this._reloadListeners.add(listener);
|
|
@@ -190,18 +195,29 @@ var EnvServer = class extends RunnerManager {
|
|
|
190
195
|
super();
|
|
191
196
|
this._opts = opts;
|
|
192
197
|
}
|
|
193
|
-
|
|
194
|
-
this.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
start() {
|
|
199
|
+
this._startPromise ??= this._start().catch((error) => {
|
|
200
|
+
this._startPromise = void 0;
|
|
201
|
+
throw error;
|
|
202
|
+
});
|
|
203
|
+
return this._startPromise;
|
|
198
204
|
}
|
|
199
205
|
async close() {
|
|
200
206
|
this._stopWatching();
|
|
201
207
|
await super.close();
|
|
202
208
|
}
|
|
209
|
+
async _fetch(input, init) {
|
|
210
|
+
if (!this.closed) await this.start();
|
|
211
|
+
return super._fetch(input, init);
|
|
212
|
+
}
|
|
213
|
+
async _start() {
|
|
214
|
+
this.runner = await this._createRunner();
|
|
215
|
+
await this.reload(this.runner);
|
|
216
|
+
if (this._opts.watch) this._startWatching();
|
|
217
|
+
return this;
|
|
218
|
+
}
|
|
203
219
|
async _createRunner() {
|
|
204
|
-
return loadRunner(this._opts.runner, {
|
|
220
|
+
return loadRunner(this._opts.runner || "node-worker", {
|
|
205
221
|
name: this._opts.name || this._opts.entry,
|
|
206
222
|
hooks: this._opts.hooks,
|
|
207
223
|
data: {
|
|
@@ -238,4 +254,4 @@ var EnvServer = class extends RunnerManager {
|
|
|
238
254
|
}, 100);
|
|
239
255
|
}
|
|
240
256
|
};
|
|
241
|
-
export {
|
|
257
|
+
export { EnvServer, RunnerManager, loadRunner };
|
package/dist/_chunks/types.d.mts
CHANGED
|
@@ -52,7 +52,7 @@ interface RPCOptions {
|
|
|
52
52
|
timeout?: number;
|
|
53
53
|
}
|
|
54
54
|
/** Core runner interface combining lifecycle hooks, RPC, and request proxying. */
|
|
55
|
-
interface EnvRunner extends RunnerRPCHooks {
|
|
55
|
+
interface EnvRunner extends RunnerRPCHooks, AsyncDisposable {
|
|
56
56
|
/** Whether the worker is ready to accept requests. */
|
|
57
57
|
readonly ready: boolean;
|
|
58
58
|
/** Whether the runner has been closed. */
|
|
@@ -69,5 +69,7 @@ interface EnvRunner extends RunnerRPCHooks {
|
|
|
69
69
|
reloadModule?(timeout?: number): Promise<void>;
|
|
70
70
|
/** Gracefully shut down the worker. */
|
|
71
71
|
close(): Promise<void>;
|
|
72
|
+
/** Alias for `close()`, enabling `await using` (explicit resource management). */
|
|
73
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
72
74
|
}
|
|
73
|
-
export {
|
|
75
|
+
export { EnvRunner, FetchHandler, NodeUpgradeContext, RPCOptions, RunnerMessageListener, RunnerRPCHooks, UpgradeContext, UpgradeHandler, WorkerAddress, WorkerHooks };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
async function resolveVirtualModules(virtual) {
|
|
2
|
+
const entries = await Promise.all(Object.entries(virtual).map(async ([key, value]) => [key, typeof value === "function" ? await value() : value]));
|
|
3
|
+
return Object.fromEntries(entries);
|
|
4
|
+
}
|
|
5
|
+
const VIRTUAL_SCHEME = "virtual:";
|
|
6
|
+
function createVirtualHooks(virtual) {
|
|
7
|
+
const resolve = (specifier, context, nextResolve) => {
|
|
8
|
+
if (Object.hasOwn(virtual, _stripQuery(specifier))) return {
|
|
9
|
+
url: VIRTUAL_SCHEME + encodeURIComponent(specifier),
|
|
10
|
+
shortCircuit: true
|
|
11
|
+
};
|
|
12
|
+
return nextResolve(specifier, context);
|
|
13
|
+
};
|
|
14
|
+
const load = (url, context, nextLoad) => {
|
|
15
|
+
if (url.startsWith(VIRTUAL_SCHEME)) {
|
|
16
|
+
const key = _stripQuery(decodeURIComponent(url.slice(8)));
|
|
17
|
+
if (Object.hasOwn(virtual, key)) return {
|
|
18
|
+
format: virtualModuleFormat(key),
|
|
19
|
+
source: virtual[key],
|
|
20
|
+
shortCircuit: true
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return nextLoad(url, context);
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
resolve,
|
|
27
|
+
load
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function virtualModuleFormat(specifier) {
|
|
31
|
+
if (specifier.endsWith(".json")) return "json";
|
|
32
|
+
if (specifier.endsWith(".ts") || specifier.endsWith(".mts")) return "module-typescript";
|
|
33
|
+
return "module";
|
|
34
|
+
}
|
|
35
|
+
function _stripQuery(specifier) {
|
|
36
|
+
const qIndex = specifier.indexOf("?");
|
|
37
|
+
return qIndex === -1 ? specifier : specifier.slice(0, qIndex);
|
|
38
|
+
}
|
|
39
|
+
export { createVirtualHooks, resolveVirtualModules, virtualModuleFormat };
|
|
@@ -1,8 +1,78 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createVirtualHooks, virtualModuleFormat } from "./virtual-loader.mjs";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
3
|
import { pathToFileURL } from "node:url";
|
|
3
4
|
import { isAbsolute } from "node:path";
|
|
4
|
-
async function
|
|
5
|
-
|
|
5
|
+
async function registerVirtualModules(virtual) {
|
|
6
|
+
if (!virtual || Object.keys(virtual).length === 0) return _noop;
|
|
7
|
+
const { registerHooks, stripTypeScriptTypes } = await import("node:module");
|
|
8
|
+
if (typeof registerHooks === "function") {
|
|
9
|
+
if ("Deno" in globalThis) virtual = _transformForDeno(virtual, stripTypeScriptTypes);
|
|
10
|
+
const hooks = registerHooks(createVirtualHooks(virtual));
|
|
11
|
+
return _once(() => hooks.deregister());
|
|
12
|
+
}
|
|
13
|
+
if (typeof globalThis.Bun?.plugin === "function") {
|
|
14
|
+
_bunVirtual = virtual;
|
|
15
|
+
_registerBunModules(Object.keys(virtual));
|
|
16
|
+
return _once(() => {
|
|
17
|
+
if (_bunVirtual === virtual) _bunVirtual = void 0;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
console.warn("[env-runner] virtual modules require `module.registerHooks` (Node.js >= 22.15 / Deno >= 2.x) or `Bun.plugin`; skipping registration.");
|
|
21
|
+
return _noop;
|
|
22
|
+
}
|
|
23
|
+
function refreshVirtualModule(specifier) {
|
|
24
|
+
if (_bunVirtual?.[specifier] === void 0) return false;
|
|
25
|
+
_registerBunModules([specifier]);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
let _bunVirtual;
|
|
29
|
+
function _registerBunModules(specifiers) {
|
|
30
|
+
globalThis.Bun.plugin({
|
|
31
|
+
name: "env-runner-virtual",
|
|
32
|
+
setup(build) {
|
|
33
|
+
for (const specifier of specifiers) build.module(specifier, () => {
|
|
34
|
+
const source = _bunVirtual?.[specifier];
|
|
35
|
+
if (source === void 0) throw new Error(`Cannot find virtual module "${specifier}" (unregistered)`);
|
|
36
|
+
const format = virtualModuleFormat(specifier);
|
|
37
|
+
if (format === "json") return {
|
|
38
|
+
exports: { default: JSON.parse(source) },
|
|
39
|
+
loader: "object"
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
contents: source,
|
|
43
|
+
loader: format === "module-typescript" ? "ts" : "js"
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function _transformForDeno(virtual, stripTypeScriptTypes) {
|
|
50
|
+
const out = {};
|
|
51
|
+
for (const [specifier, source] of Object.entries(virtual)) {
|
|
52
|
+
const format = virtualModuleFormat(specifier);
|
|
53
|
+
if (format === "module-typescript") {
|
|
54
|
+
if (typeof stripTypeScriptTypes !== "function") throw new TypeError(`[env-runner] virtual TypeScript module "${specifier}" requires \`module.stripTypeScriptTypes\` (custom load hooks bypass Deno's native type stripping); upgrade Deno or provide a pre-transpiled JavaScript source instead.`);
|
|
55
|
+
out[specifier] = stripTypeScriptTypes(source);
|
|
56
|
+
} else if (format === "json") out[specifier] = `export default JSON.parse(${JSON.stringify(source)});`;
|
|
57
|
+
else out[specifier] = source;
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
const _noop = () => {};
|
|
62
|
+
function _once(fn) {
|
|
63
|
+
let done = false;
|
|
64
|
+
return () => {
|
|
65
|
+
if (!done) {
|
|
66
|
+
done = true;
|
|
67
|
+
fn();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function isVirtualSpecifier(specifier, virtual) {
|
|
72
|
+
return Boolean(specifier && virtual && Object.hasOwn(virtual, specifier));
|
|
73
|
+
}
|
|
74
|
+
async function resolveEntry(entryPath, virtual) {
|
|
75
|
+
const mod = await (virtual ? import(entryPath) : import(_toImportPath(entryPath)));
|
|
6
76
|
const entry = mod.default || mod;
|
|
7
77
|
if (typeof entry.fetch !== "function") throw new Error(`[env-runner] Entry module "${entryPath}" must export a \`fetch\` handler (export default { fetch(req) { ... } }).`);
|
|
8
78
|
return entry;
|
|
@@ -14,9 +84,9 @@ function parseServerAddress(server) {
|
|
|
14
84
|
port: Number(url.port)
|
|
15
85
|
};
|
|
16
86
|
}
|
|
17
|
-
async function reloadEntryModule(entryPath, currentEntry, sendMessage) {
|
|
87
|
+
async function reloadEntryModule(entryPath, currentEntry, sendMessage, virtual) {
|
|
18
88
|
await currentEntry.ipc?.onClose?.();
|
|
19
|
-
const newEntry = await _importFresh(entryPath);
|
|
89
|
+
const newEntry = await _importFresh(entryPath, virtual);
|
|
20
90
|
await newEntry.ipc?.onOpen?.({ sendMessage });
|
|
21
91
|
return newEntry;
|
|
22
92
|
}
|
|
@@ -27,11 +97,18 @@ function _toImportPath(entryPath) {
|
|
|
27
97
|
if (isAbsolute(filePath)) return pathToFileURL(filePath).href + query;
|
|
28
98
|
return entryPath;
|
|
29
99
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
100
|
+
let _reloadCounter = 0;
|
|
101
|
+
async function _importFresh(entryPath, virtual) {
|
|
102
|
+
const qIndex = entryPath.indexOf("?");
|
|
103
|
+
const filePath = qIndex === -1 ? entryPath : entryPath.slice(0, qIndex);
|
|
104
|
+
let mod;
|
|
105
|
+
if (!virtual && existsSync(filePath)) {
|
|
106
|
+
const code = readFileSync(filePath, "utf8");
|
|
107
|
+
mod = await import("data:text/javascript;base64," + Buffer.from(code).toString("base64"));
|
|
108
|
+
} else if (virtual && refreshVirtualModule(filePath)) mod = await import(filePath);
|
|
109
|
+
else mod = await import(entryPath + (qIndex === -1 ? "?" : "&") + "__envRunnerReload=" + _reloadCounter++);
|
|
33
110
|
const entry = mod.default || mod;
|
|
34
111
|
if (typeof entry.fetch !== "function") throw new Error(`[env-runner] Entry module "${entryPath}" must export a \`fetch\` handler (export default { fetch(req) { ... } }).`);
|
|
35
112
|
return entry;
|
|
36
113
|
}
|
|
37
|
-
export {
|
|
114
|
+
export { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry };
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { EnvRunner, FetchHandler, NodeUpgradeContext, RPCOptions, RunnerMessageListener, RunnerRPCHooks, UpgradeContext, UpgradeHandler, WorkerAddress, WorkerHooks } from "./_chunks/types.mjs";
|
|
2
|
+
import { BaseEnvRunner, EnvRunnerData, VirtualModuleSource, VirtualModules } from "./_chunks/base-runner.mjs";
|
|
3
|
+
import { DenoProcessEnvRunner } from "./_chunks/runner.mjs";
|
|
4
|
+
import { MiniflareEnvRunner, MiniflareEnvRunnerOptions, MiniflareExportInfo, TransformResult } from "./_chunks/runner2.mjs";
|
|
5
|
+
import { VercelEnvRunner } from "./_chunks/runner4.mjs";
|
|
6
|
+
import { NetlifyEnvRunner } from "./_chunks/runner5.mjs";
|
|
7
7
|
import { ServerOptions } from "srvx";
|
|
8
8
|
import { Hooks } from "crossws";
|
|
9
9
|
/**
|
|
10
10
|
* Manages an active `EnvRunner` instance, proxying all calls to it.
|
|
11
11
|
* Supports hot-reload, auto-restart on unexpected exit, and message queueing.
|
|
12
12
|
*/
|
|
13
|
-
declare class RunnerManager implements EnvRunner {
|
|
13
|
+
declare class RunnerManager implements EnvRunner, AsyncDisposable {
|
|
14
14
|
private _runner;
|
|
15
15
|
private _messageQueue;
|
|
16
16
|
private _messageListeners;
|
|
@@ -24,6 +24,7 @@ declare class RunnerManager implements EnvRunner {
|
|
|
24
24
|
/** Replace the active runner with a new one. Closes the previous runner. */
|
|
25
25
|
reload(runner: EnvRunner): Promise<void>;
|
|
26
26
|
fetch: FetchHandler;
|
|
27
|
+
protected _fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
27
28
|
upgrade: UpgradeHandler;
|
|
28
29
|
sendMessage(message: unknown): void;
|
|
29
30
|
onMessage(listener: RunnerMessageListener): void;
|
|
@@ -34,6 +35,7 @@ declare class RunnerManager implements EnvRunner {
|
|
|
34
35
|
}): Promise<T>;
|
|
35
36
|
reloadModule(timeout?: number): Promise<void>;
|
|
36
37
|
close(): Promise<void>;
|
|
38
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
37
39
|
onClose(listener: (runner: EnvRunner, cause?: unknown) => void): void;
|
|
38
40
|
offClose(listener: (runner: EnvRunner, cause?: unknown) => void): void;
|
|
39
41
|
onReady(listener: (runner: EnvRunner, address?: WorkerAddress) => void): void;
|
|
@@ -56,8 +58,8 @@ interface LoadRunnerOptions {
|
|
|
56
58
|
}
|
|
57
59
|
declare function loadRunner(runner: RunnerName, opts: LoadRunnerOptions): Promise<EnvRunner>;
|
|
58
60
|
interface EnvServerOptions {
|
|
59
|
-
/** Runner implementation to use. */
|
|
60
|
-
runner
|
|
61
|
+
/** Runner implementation to use (defaults to `"node-worker"`). */
|
|
62
|
+
runner?: RunnerName;
|
|
61
63
|
/** Path to the user entry module (passed as `data.entry`). */
|
|
62
64
|
entry: string;
|
|
63
65
|
/** Runner instance name. */
|
|
@@ -78,15 +80,25 @@ declare class EnvServer extends RunnerManager {
|
|
|
78
80
|
private _watchers;
|
|
79
81
|
private _reloadTimeout;
|
|
80
82
|
private _reloadListeners;
|
|
83
|
+
private _startPromise;
|
|
81
84
|
runner: Awaited<ReturnType<typeof loadRunner>> | null;
|
|
82
85
|
/** Register a listener called when the runner is reloaded due to a file change. */
|
|
83
86
|
onReload(listener: () => void): void;
|
|
84
87
|
/** Remove a previously registered reload listener. */
|
|
85
88
|
offReload(listener: () => void): void;
|
|
86
89
|
constructor(opts: EnvServerOptions);
|
|
87
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* Start the server by loading and attaching the runner.
|
|
92
|
+
*
|
|
93
|
+
* Idempotent — concurrent and repeated calls share one startup. Calling
|
|
94
|
+
* `start()` explicitly is optional: the first `fetch()` auto-starts the
|
|
95
|
+
* server. A failed start resets so a later call can retry.
|
|
96
|
+
*/
|
|
88
97
|
start(): Promise<this>;
|
|
89
98
|
close(): Promise<void>;
|
|
99
|
+
/** Auto-start on first fetch so an explicit `start()` call is optional. */
|
|
100
|
+
protected _fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
101
|
+
private _start;
|
|
90
102
|
private _createRunner;
|
|
91
103
|
private _startWatching;
|
|
92
104
|
private _stopWatching;
|
|
@@ -108,4 +120,4 @@ interface AppEntry {
|
|
|
108
120
|
plugins?: ServerOptions["plugins"];
|
|
109
121
|
ipc?: AppEntryIPC;
|
|
110
122
|
}
|
|
111
|
-
export { type AppEntry, type AppEntryIPC, type AppEntryIPCContext, BaseEnvRunner, DenoProcessEnvRunner, type EnvRunnerData as DenoProcessEnvRunnerData, type
|
|
123
|
+
export { type AppEntry, type AppEntryIPC, type AppEntryIPCContext, BaseEnvRunner, DenoProcessEnvRunner, type EnvRunnerData as DenoProcessEnvRunnerData, type EnvRunner, type EnvRunnerData, EnvServer, type EnvServerOptions, type FetchHandler, type LoadRunnerOptions, MiniflareEnvRunner, type MiniflareEnvRunnerOptions, type MiniflareExportInfo, NetlifyEnvRunner, type NodeUpgradeContext, type RPCOptions, RunnerManager, type RunnerMessageListener, type RunnerName, type RunnerRPCHooks, type TransformResult, type UpgradeContext, type UpgradeHandler, VercelEnvRunner, type VirtualModuleSource, type VirtualModules, type WorkerAddress, type WorkerHooks, loadRunner };
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { BaseEnvRunner } from "./_chunks/base-runner.mjs";
|
|
2
|
+
import { EnvServer, RunnerManager, loadRunner } from "./_chunks/server.mjs";
|
|
3
|
+
import { DenoProcessEnvRunner } from "./_chunks/runner.mjs";
|
|
4
|
+
import { MiniflareEnvRunner } from "./_chunks/runner2.mjs";
|
|
5
|
+
import { VercelEnvRunner } from "./_chunks/runner4.mjs";
|
|
6
|
+
import { NetlifyEnvRunner } from "./_chunks/runner5.mjs";
|
|
7
7
|
export { BaseEnvRunner, DenoProcessEnvRunner, EnvServer, MiniflareEnvRunner, NetlifyEnvRunner, RunnerManager, VercelEnvRunner, loadRunner };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { WorkerHooks } from "../../_chunks/types.mjs";
|
|
2
|
+
import { BaseEnvRunner, EnvRunnerData } from "../../_chunks/base-runner.mjs";
|
|
3
3
|
declare class BunProcessEnvRunner extends BaseEnvRunner {
|
|
4
4
|
#private;
|
|
5
5
|
constructor(opts: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { execSync, spawn } from "node:child_process";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -7,6 +7,12 @@ import { homedir } from "node:os";
|
|
|
7
7
|
let _defaultEntry;
|
|
8
8
|
let _bunPath;
|
|
9
9
|
const _isBun = typeof Bun !== "undefined";
|
|
10
|
+
async function forwardStream(stream, dest) {
|
|
11
|
+
if (!stream) return;
|
|
12
|
+
try {
|
|
13
|
+
for await (const chunk of stream) dest.write(chunk);
|
|
14
|
+
} catch {}
|
|
15
|
+
}
|
|
10
16
|
function resolveBunPath() {
|
|
11
17
|
if (_bunPath) return _bunPath;
|
|
12
18
|
const candidates = [join(homedir(), ".bun", "bin", "bun")];
|
|
@@ -25,7 +31,7 @@ var BunProcessEnvRunner = class extends BaseEnvRunner {
|
|
|
25
31
|
...opts,
|
|
26
32
|
workerEntry: opts.workerEntry || _defaultEntry
|
|
27
33
|
});
|
|
28
|
-
this.#initProcess(opts.execArgv);
|
|
34
|
+
this._initWithVirtualData(() => this.#initProcess(opts.execArgv));
|
|
29
35
|
}
|
|
30
36
|
sendMessage(message) {
|
|
31
37
|
if (!this.#process) throw new Error("Bun env process should be initialized before sending messages.");
|
|
@@ -86,6 +92,8 @@ var BunProcessEnvRunner = class extends BaseEnvRunner {
|
|
|
86
92
|
child._exitCode = code;
|
|
87
93
|
this.close(`process exited with code ${code}`);
|
|
88
94
|
});
|
|
95
|
+
forwardStream(proc.stdout, process.stdout);
|
|
96
|
+
forwardStream(proc.stderr, process.stderr);
|
|
89
97
|
this.#process = child;
|
|
90
98
|
}
|
|
91
99
|
#initNodeProcess(execArgv, env) {
|
|
@@ -122,6 +130,8 @@ var BunProcessEnvRunner = class extends BaseEnvRunner {
|
|
|
122
130
|
child.on("message", (message) => {
|
|
123
131
|
this._handleMessage(message);
|
|
124
132
|
});
|
|
133
|
+
child.stdout?.pipe(process.stdout);
|
|
134
|
+
child.stderr?.pipe(process.stderr);
|
|
125
135
|
this.#process = handle;
|
|
126
136
|
}
|
|
127
137
|
};
|
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs";
|
|
2
2
|
import { serve } from "srvx";
|
|
3
3
|
import { plugin } from "crossws/server";
|
|
4
|
+
process.on("disconnect", () => process.exit(0));
|
|
4
5
|
const data = JSON.parse(process.env.ENV_RUNNER_DATA || "{}");
|
|
5
|
-
let entry = await resolveEntry(data.entry);
|
|
6
6
|
const sendMessage = (message) => process.send(message);
|
|
7
|
+
const virtualEntry = isVirtualSpecifier(data.entry, data.virtual);
|
|
8
|
+
let unregisterVirtualModules;
|
|
9
|
+
let entry;
|
|
10
|
+
try {
|
|
11
|
+
unregisterVirtualModules = await registerVirtualModules(data.virtual);
|
|
12
|
+
entry = await resolveEntry(data.entry, virtualEntry);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
const message = error?.message || String(error);
|
|
15
|
+
sendMessage({
|
|
16
|
+
event: "init-error",
|
|
17
|
+
error: message
|
|
18
|
+
});
|
|
19
|
+
console.error(`[env-runner] worker init failed: ${message}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
7
22
|
const server = serve({
|
|
8
23
|
port: 0,
|
|
9
24
|
hostname: "127.0.0.1",
|
|
@@ -26,13 +41,14 @@ process.send({ address: parseServerAddress(server) });
|
|
|
26
41
|
process.on("message", async (message) => {
|
|
27
42
|
if (message?.event === "shutdown") {
|
|
28
43
|
Promise.resolve(entry.ipc?.onClose?.()).then(() => server.close()).then(() => {
|
|
44
|
+
unregisterVirtualModules();
|
|
29
45
|
process.send({ event: "exit" });
|
|
30
46
|
});
|
|
31
47
|
return;
|
|
32
48
|
}
|
|
33
49
|
if (message?.event === "reload-module") {
|
|
34
50
|
try {
|
|
35
|
-
entry = await reloadEntryModule(data.entry, entry, sendMessage);
|
|
51
|
+
entry = await reloadEntryModule(data.entry, entry, sendMessage, virtualEntry);
|
|
36
52
|
process.send({ event: "module-reloaded" });
|
|
37
53
|
} catch (error) {
|
|
38
54
|
process.send({
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { EnvRunnerData } from "../../_chunks/base-runner.mjs";
|
|
2
|
+
import { DenoProcessEnvRunner } from "../../_chunks/runner.mjs";
|
|
3
3
|
export { DenoProcessEnvRunner, type EnvRunnerData as DenoProcessEnvRunnerData };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DenoProcessEnvRunner } from "../../_chunks/runner.mjs";
|
|
2
2
|
export { DenoProcessEnvRunner };
|
|
@@ -1,11 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs";
|
|
2
2
|
import { serve } from "srvx";
|
|
3
3
|
import { plugin } from "crossws/server";
|
|
4
4
|
const data = JSON.parse(process.env.ENV_RUNNER_DATA || "{}");
|
|
5
|
-
let entry = await resolveEntry(data.entry);
|
|
6
5
|
const _stdout = globalThis.Deno?.stdout ? { write: (s) => globalThis.Deno.stdout.writeSync(new TextEncoder().encode(s)) } : process.stdout;
|
|
7
6
|
const sendMessage = (message) => _stdout.write(JSON.stringify(message) + "\n");
|
|
8
7
|
const _stdin = globalThis.Deno?.stdin?.readable || process.stdin;
|
|
8
|
+
const virtualEntry = isVirtualSpecifier(data.entry, data.virtual);
|
|
9
|
+
let unregisterVirtualModules;
|
|
10
|
+
let entry;
|
|
11
|
+
try {
|
|
12
|
+
unregisterVirtualModules = await registerVirtualModules(data.virtual);
|
|
13
|
+
entry = await resolveEntry(data.entry, virtualEntry);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
const message = error?.message || String(error);
|
|
16
|
+
sendMessage({
|
|
17
|
+
event: "init-error",
|
|
18
|
+
error: message
|
|
19
|
+
});
|
|
20
|
+
console.error(`[env-runner] worker init failed: ${message}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
9
23
|
const server = serve({
|
|
10
24
|
port: 0,
|
|
11
25
|
hostname: "127.0.0.1",
|
|
@@ -48,13 +62,14 @@ async function readMessages() {
|
|
|
48
62
|
async function handleMessage(message) {
|
|
49
63
|
if (message?.event === "shutdown") {
|
|
50
64
|
Promise.resolve(entry.ipc?.onClose?.()).then(() => server.close()).then(() => {
|
|
65
|
+
unregisterVirtualModules();
|
|
51
66
|
sendMessage({ event: "exit" });
|
|
52
67
|
});
|
|
53
68
|
return;
|
|
54
69
|
}
|
|
55
70
|
if (message?.event === "reload-module") {
|
|
56
71
|
try {
|
|
57
|
-
entry = await reloadEntryModule(data.entry, entry, sendMessage);
|
|
72
|
+
entry = await reloadEntryModule(data.entry, entry, sendMessage, virtualEntry);
|
|
58
73
|
sendMessage({ event: "module-reloaded" });
|
|
59
74
|
} catch (error) {
|
|
60
75
|
sendMessage({
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { EnvRunnerData } from "../../_chunks/base-runner.mjs";
|
|
2
|
+
import { MiniflareEnvRunner, MiniflareEnvRunnerOptions, MiniflareExportInfo, TransformResult } from "../../_chunks/runner2.mjs";
|
|
3
3
|
export { MiniflareEnvRunner, type EnvRunnerData as MiniflareEnvRunnerData, MiniflareEnvRunnerOptions, MiniflareExportInfo, TransformResult };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MiniflareEnvRunner } from "../../_chunks/runner2.mjs";
|
|
2
2
|
export { MiniflareEnvRunner };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { EnvRunnerData } from "../../_chunks/base-runner.mjs";
|
|
2
|
+
import { NetlifyEnvRunner } from "../../_chunks/runner5.mjs";
|
|
3
3
|
export { type EnvRunnerData, NetlifyEnvRunner };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NetlifyEnvRunner } from "../../_chunks/runner5.mjs";
|
|
2
2
|
export { NetlifyEnvRunner };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { WorkerHooks } from "../../_chunks/types.mjs";
|
|
2
|
+
import { BaseEnvRunner, EnvRunnerData } from "../../_chunks/base-runner.mjs";
|
|
3
3
|
declare class NodeProcessEnvRunner extends BaseEnvRunner {
|
|
4
4
|
#private;
|
|
5
5
|
constructor(opts: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { fork } from "node:child_process";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -11,7 +11,7 @@ var NodeProcessEnvRunner = class extends BaseEnvRunner {
|
|
|
11
11
|
...opts,
|
|
12
12
|
workerEntry: opts.workerEntry || _defaultEntry
|
|
13
13
|
});
|
|
14
|
-
this.#initProcess(opts.execArgv);
|
|
14
|
+
this._initWithVirtualData(() => this.#initProcess(opts.execArgv));
|
|
15
15
|
}
|
|
16
16
|
sendMessage(message) {
|
|
17
17
|
if (!this.#process) throw new Error("Node env process should be initialized before sending messages.");
|
|
@@ -59,6 +59,8 @@ var NodeProcessEnvRunner = class extends BaseEnvRunner {
|
|
|
59
59
|
child.on("message", (message) => {
|
|
60
60
|
this._handleMessage(message);
|
|
61
61
|
});
|
|
62
|
+
child.stdout?.pipe(process.stdout);
|
|
63
|
+
child.stderr?.pipe(process.stderr);
|
|
62
64
|
this.#process = child;
|
|
63
65
|
}
|
|
64
66
|
};
|
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry } from "../../_chunks/worker-utils.mjs";
|
|
2
2
|
import { serve } from "srvx";
|
|
3
3
|
import { plugin } from "crossws/server/node";
|
|
4
|
+
process.on("disconnect", () => process.exit(0));
|
|
4
5
|
const data = JSON.parse(process.env.ENV_RUNNER_DATA || "{}");
|
|
5
|
-
let entry = await resolveEntry(data.entry);
|
|
6
6
|
const sendMessage = (message) => process.send(message);
|
|
7
|
+
const virtualEntry = isVirtualSpecifier(data.entry, data.virtual);
|
|
8
|
+
let unregisterVirtualModules;
|
|
9
|
+
let entry;
|
|
10
|
+
try {
|
|
11
|
+
unregisterVirtualModules = await registerVirtualModules(data.virtual);
|
|
12
|
+
entry = await resolveEntry(data.entry, virtualEntry);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
const message = error?.message || String(error);
|
|
15
|
+
sendMessage({
|
|
16
|
+
event: "init-error",
|
|
17
|
+
error: message
|
|
18
|
+
});
|
|
19
|
+
console.error(`[env-runner] worker init failed: ${message}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
7
22
|
const server = serve({
|
|
8
23
|
port: 0,
|
|
9
24
|
hostname: "127.0.0.1",
|
|
@@ -26,13 +41,14 @@ process.send({ address: parseServerAddress(server) });
|
|
|
26
41
|
process.on("message", async (message) => {
|
|
27
42
|
if (message?.event === "shutdown") {
|
|
28
43
|
Promise.resolve(entry.ipc?.onClose?.()).then(() => server.close()).then(() => {
|
|
44
|
+
unregisterVirtualModules();
|
|
29
45
|
process.send({ event: "exit" });
|
|
30
46
|
});
|
|
31
47
|
return;
|
|
32
48
|
}
|
|
33
49
|
if (message?.event === "reload-module") {
|
|
34
50
|
try {
|
|
35
|
-
entry = await reloadEntryModule(data.entry, entry, sendMessage);
|
|
51
|
+
entry = await reloadEntryModule(data.entry, entry, sendMessage, virtualEntry);
|
|
36
52
|
process.send({ event: "module-reloaded" });
|
|
37
53
|
} catch (error) {
|
|
38
54
|
process.send({
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { EnvRunnerData } from "../../_chunks/base-runner.mjs";
|
|
2
|
+
import { NodeWorkerEnvRunner } from "../../_chunks/runner3.mjs";
|
|
3
3
|
export { type EnvRunnerData, NodeWorkerEnvRunner };
|