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.
Files changed (43) hide show
  1. package/README.md +112 -15
  2. package/dist/_chunks/base-runner.d.mts +46 -3
  3. package/dist/_chunks/base-runner.mjs +28 -1
  4. package/dist/_chunks/libs/cjs-module-lexer.mjs +1 -1
  5. package/dist/_chunks/runner.d.mts +3 -3
  6. package/dist/_chunks/runner.mjs +6 -3
  7. package/dist/_chunks/runner2.d.mts +3 -3
  8. package/dist/_chunks/runner2.mjs +66 -16
  9. package/dist/_chunks/runner3.d.mts +3 -3
  10. package/dist/_chunks/runner3.mjs +3 -3
  11. package/dist/_chunks/runner4.d.mts +4 -4
  12. package/dist/_chunks/runner4.mjs +2 -2
  13. package/dist/_chunks/runner5.d.mts +4 -4
  14. package/dist/_chunks/runner5.mjs +2 -2
  15. package/dist/_chunks/server.mjs +25 -9
  16. package/dist/_chunks/types.d.mts +4 -2
  17. package/dist/_chunks/virtual-loader.mjs +39 -0
  18. package/dist/_chunks/worker-utils.mjs +86 -9
  19. package/dist/cli.mjs +1 -1
  20. package/dist/index.d.mts +23 -11
  21. package/dist/index.mjs +6 -6
  22. package/dist/runners/bun-process/runner.d.mts +2 -2
  23. package/dist/runners/bun-process/runner.mjs +12 -2
  24. package/dist/runners/bun-process/worker.mjs +19 -3
  25. package/dist/runners/deno-process/runner.d.mts +2 -2
  26. package/dist/runners/deno-process/runner.mjs +1 -1
  27. package/dist/runners/deno-process/worker.mjs +18 -3
  28. package/dist/runners/miniflare/runner.d.mts +2 -2
  29. package/dist/runners/miniflare/runner.mjs +1 -1
  30. package/dist/runners/netlify/runner.d.mts +2 -2
  31. package/dist/runners/netlify/runner.mjs +1 -1
  32. package/dist/runners/node-process/runner.d.mts +2 -2
  33. package/dist/runners/node-process/runner.mjs +4 -2
  34. package/dist/runners/node-process/worker.mjs +19 -3
  35. package/dist/runners/node-worker/runner.d.mts +2 -2
  36. package/dist/runners/node-worker/runner.mjs +1 -1
  37. package/dist/runners/node-worker/worker.mjs +18 -3
  38. package/dist/runners/self/runner.d.mts +2 -2
  39. package/dist/runners/self/runner.mjs +2 -2
  40. package/dist/runners/vercel/runner.d.mts +2 -2
  41. package/dist/runners/vercel/runner.mjs +1 -1
  42. package/dist/vite.d.mts +1 -1
  43. package/package.json +11 -11
@@ -1,6 +1,6 @@
1
- import { u as WorkerHooks } from "./types.mjs";
2
- import { n as EnvRunnerData } from "./base-runner.mjs";
3
- import { t as NodeWorkerEnvRunner } from "./runner3.mjs";
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 as t };
14
+ export { NetlifyEnvRunner };
@@ -1,4 +1,4 @@
1
- import { t as NodeWorkerEnvRunner } from "./runner3.mjs";
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 as t };
45
+ export { NetlifyEnvRunner };
@@ -24,11 +24,12 @@ var RunnerManager = class {
24
24
  this._reloading = false;
25
25
  if (prev) await prev.close();
26
26
  }
27
- fetch = async (input, init) => {
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
- async start() {
194
- this.runner = await this._createRunner();
195
- await this.reload(this.runner);
196
- if (this._opts.watch) this._startWatching();
197
- return this;
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 { loadRunner as n, RunnerManager as r, EnvServer as t };
257
+ export { EnvServer, RunnerManager, loadRunner };
@@ -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 { RunnerMessageListener as a, UpgradeHandler as c, RPCOptions as i, WorkerAddress as l, FetchHandler as n, RunnerRPCHooks as o, NodeUpgradeContext as r, UpgradeContext as s, EnvRunner as t, WorkerHooks as u };
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 { readFileSync } from "node:fs";
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 resolveEntry(entryPath) {
5
- const mod = await import(_toImportPath(entryPath));
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
- async function _importFresh(entryPath) {
31
- const code = readFileSync(entryPath, "utf8");
32
- const mod = await import("data:text/javascript;base64," + Buffer.from(code).toString("base64"));
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 { reloadEntryModule as n, resolveEntry as r, parseServerAddress as t };
114
+ export { isVirtualSpecifier, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry };
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as EnvServer } from "./_chunks/server.mjs";
1
+ import { EnvServer } from "./_chunks/server.mjs";
2
2
  import { resolve } from "node:path";
3
3
  import { serve } from "srvx";
4
4
  import { parseArgs } from "node:util";
package/dist/index.d.mts CHANGED
@@ -1,16 +1,16 @@
1
- import { a as RunnerMessageListener, c as UpgradeHandler, i as RPCOptions, l as WorkerAddress, n as FetchHandler, o as RunnerRPCHooks, r as NodeUpgradeContext, s as UpgradeContext, t as EnvRunner, u as WorkerHooks } from "./_chunks/types.mjs";
2
- import { n as EnvRunnerData, t as BaseEnvRunner } from "./_chunks/base-runner.mjs";
3
- import { t as DenoProcessEnvRunner } from "./_chunks/runner.mjs";
4
- import { i as TransformResult, n as MiniflareEnvRunnerOptions, r as MiniflareExportInfo, t as MiniflareEnvRunner } from "./_chunks/runner2.mjs";
5
- import { t as VercelEnvRunner } from "./_chunks/runner4.mjs";
6
- import { t as NetlifyEnvRunner } from "./_chunks/runner5.mjs";
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: RunnerName;
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
- /** Start the server by loading and attaching the runner. */
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 EnvRunnerData, type EnvRunner, 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 WorkerAddress, type WorkerHooks, loadRunner };
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 { t as BaseEnvRunner } from "./_chunks/base-runner.mjs";
2
- import { n as loadRunner, r as RunnerManager, t as EnvServer } from "./_chunks/server.mjs";
3
- import { t as DenoProcessEnvRunner } from "./_chunks/runner.mjs";
4
- import { t as MiniflareEnvRunner } from "./_chunks/runner2.mjs";
5
- import { t as VercelEnvRunner } from "./_chunks/runner4.mjs";
6
- import { t as NetlifyEnvRunner } from "./_chunks/runner5.mjs";
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 { u as WorkerHooks } from "../../_chunks/types.mjs";
2
- import { n as EnvRunnerData, t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
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 { t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
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 { n as reloadEntryModule, r as resolveEntry, t as parseServerAddress } from "../../_chunks/worker-utils.mjs";
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 { n as EnvRunnerData } from "../../_chunks/base-runner.mjs";
2
- import { t as DenoProcessEnvRunner } from "../../_chunks/runner.mjs";
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 { t as DenoProcessEnvRunner } from "../../_chunks/runner.mjs";
1
+ import { DenoProcessEnvRunner } from "../../_chunks/runner.mjs";
2
2
  export { DenoProcessEnvRunner };
@@ -1,11 +1,25 @@
1
- import { n as reloadEntryModule, r as resolveEntry, t as parseServerAddress } from "../../_chunks/worker-utils.mjs";
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 { n as EnvRunnerData } from "../../_chunks/base-runner.mjs";
2
- import { i as TransformResult, n as MiniflareEnvRunnerOptions, r as MiniflareExportInfo, t as MiniflareEnvRunner } from "../../_chunks/runner2.mjs";
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 { t as MiniflareEnvRunner } from "../../_chunks/runner2.mjs";
1
+ import { MiniflareEnvRunner } from "../../_chunks/runner2.mjs";
2
2
  export { MiniflareEnvRunner };
@@ -1,3 +1,3 @@
1
- import { n as EnvRunnerData } from "../../_chunks/base-runner.mjs";
2
- import { t as NetlifyEnvRunner } from "../../_chunks/runner5.mjs";
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 { t as NetlifyEnvRunner } from "../../_chunks/runner5.mjs";
1
+ import { NetlifyEnvRunner } from "../../_chunks/runner5.mjs";
2
2
  export { NetlifyEnvRunner };
@@ -1,5 +1,5 @@
1
- import { u as WorkerHooks } from "../../_chunks/types.mjs";
2
- import { n as EnvRunnerData, t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
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 { t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
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 { n as reloadEntryModule, r as resolveEntry, t as parseServerAddress } from "../../_chunks/worker-utils.mjs";
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 { n as EnvRunnerData } from "../../_chunks/base-runner.mjs";
2
- import { t as NodeWorkerEnvRunner } from "../../_chunks/runner3.mjs";
1
+ import { EnvRunnerData } from "../../_chunks/base-runner.mjs";
2
+ import { NodeWorkerEnvRunner } from "../../_chunks/runner3.mjs";
3
3
  export { type EnvRunnerData, NodeWorkerEnvRunner };