env-runner 0.0.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/dist/THIRD-PARTY-LICENSES.md +33 -0
- package/dist/_chunks/base-runner.d.mts +105 -0
- package/dist/_chunks/base-runner.mjs +79 -0
- package/dist/_chunks/libs/std-env.mjs +171 -0
- package/dist/_chunks/runner.d.mts +19 -0
- package/dist/_chunks/runner.mjs +95 -0
- package/dist/_chunks/runner2.d.mts +21 -0
- package/dist/_chunks/runner2.mjs +146 -0
- package/dist/_chunks/server.mjs +186 -0
- package/dist/_chunks/worker-utils.mjs +16 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +71 -0
- package/dist/index.d.mts +100 -0
- package/dist/index.mjs +6 -0
- package/dist/runners/bun-process/runner.d.mts +19 -0
- package/dist/runners/bun-process/runner.mjs +138 -0
- package/dist/runners/bun-process/worker.d.mts +1 -0
- package/dist/runners/bun-process/worker.mjs +34 -0
- package/dist/runners/deno-process/runner.d.mts +3 -0
- package/dist/runners/deno-process/runner.mjs +4 -0
- package/dist/runners/deno-process/worker.d.mts +1 -0
- package/dist/runners/deno-process/worker.mjs +34 -0
- package/dist/runners/miniflare/runner.d.mts +3 -0
- package/dist/runners/miniflare/runner.mjs +4 -0
- package/dist/runners/node-process/runner.d.mts +19 -0
- package/dist/runners/node-process/runner.mjs +73 -0
- package/dist/runners/node-process/worker.d.mts +1 -0
- package/dist/runners/node-process/worker.mjs +34 -0
- package/dist/runners/node-worker/runner.d.mts +18 -0
- package/dist/runners/node-worker/runner.mjs +68 -0
- package/dist/runners/node-worker/worker.d.mts +1 -0
- package/dist/runners/node-worker/worker.mjs +35 -0
- package/dist/runners/self/runner.d.mts +18 -0
- package/dist/runners/self/runner.mjs +66 -0
- package/package.json +64 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import "../../_chunks/libs/std-env.mjs";
|
|
2
|
+
import { t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { execSync, spawn } from "node:child_process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
//#region src/runners/bun-process/runner.ts
|
|
9
|
+
let _defaultEntry;
|
|
10
|
+
let _bunPath;
|
|
11
|
+
const _isBun = typeof Bun !== "undefined";
|
|
12
|
+
function resolveBunPath() {
|
|
13
|
+
if (_bunPath) return _bunPath;
|
|
14
|
+
const candidates = [join(homedir(), ".bun", "bin", "bun")];
|
|
15
|
+
for (const p of candidates) if (existsSync(p)) return _bunPath = p;
|
|
16
|
+
try {
|
|
17
|
+
const resolved = execSync("which bun", { encoding: "utf8" }).trim();
|
|
18
|
+
if (resolved) return _bunPath = resolved;
|
|
19
|
+
} catch {}
|
|
20
|
+
return _bunPath = "bun";
|
|
21
|
+
}
|
|
22
|
+
var BunProcessEnvRunner = class extends BaseEnvRunner {
|
|
23
|
+
#process;
|
|
24
|
+
constructor(opts) {
|
|
25
|
+
_defaultEntry ||= fileURLToPath(import.meta.resolve("env-runner/runners/bun-process/worker"));
|
|
26
|
+
super({
|
|
27
|
+
...opts,
|
|
28
|
+
workerEntry: opts.workerEntry || _defaultEntry
|
|
29
|
+
});
|
|
30
|
+
this.#initProcess(opts.execArgv);
|
|
31
|
+
}
|
|
32
|
+
sendMessage(message) {
|
|
33
|
+
if (!this.#process) throw new Error("Bun env process should be initialized before sending messages.");
|
|
34
|
+
this.#process.send(message);
|
|
35
|
+
}
|
|
36
|
+
_hasRuntime() {
|
|
37
|
+
return Boolean(this.#process);
|
|
38
|
+
}
|
|
39
|
+
_runtimeType() {
|
|
40
|
+
return "process";
|
|
41
|
+
}
|
|
42
|
+
async _closeRuntime() {
|
|
43
|
+
if (!this.#process) return;
|
|
44
|
+
if (this.#process._exitCode == null) await this._requestGracefulShutdown(() => {
|
|
45
|
+
try {
|
|
46
|
+
this.#process.send({ event: "shutdown" });
|
|
47
|
+
} catch {}
|
|
48
|
+
}, (resolve) => {
|
|
49
|
+
this.#process?.exited.then(() => resolve());
|
|
50
|
+
}, () => this.#process?._exitCode != null);
|
|
51
|
+
this.#process.removeAllListeners?.();
|
|
52
|
+
try {
|
|
53
|
+
this.#process.kill();
|
|
54
|
+
} catch {}
|
|
55
|
+
this.#process = void 0;
|
|
56
|
+
}
|
|
57
|
+
#initProcess(execArgv) {
|
|
58
|
+
if (!existsSync(this._workerEntry)) {
|
|
59
|
+
this.close(`process entry not found in "${this._workerEntry}".`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const env = {
|
|
63
|
+
...process.env,
|
|
64
|
+
ENV_RUNNER_NAME: this._name,
|
|
65
|
+
ENV_RUNNER_DATA: JSON.stringify(this._data || {})
|
|
66
|
+
};
|
|
67
|
+
if (_isBun) this.#initBunProcess(execArgv, env);
|
|
68
|
+
else this.#initNodeProcess(execArgv, env);
|
|
69
|
+
}
|
|
70
|
+
#initBunProcess(execArgv, env) {
|
|
71
|
+
const proc = Bun.spawn({
|
|
72
|
+
cmd: [
|
|
73
|
+
resolveBunPath(),
|
|
74
|
+
...execArgv || [],
|
|
75
|
+
this._workerEntry
|
|
76
|
+
],
|
|
77
|
+
env,
|
|
78
|
+
stdio: [
|
|
79
|
+
"pipe",
|
|
80
|
+
"pipe",
|
|
81
|
+
"pipe"
|
|
82
|
+
],
|
|
83
|
+
ipc: (message) => {
|
|
84
|
+
this._handleMessage(message);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
const child = {
|
|
88
|
+
pid: proc.pid,
|
|
89
|
+
kill: () => proc.kill(),
|
|
90
|
+
send: (message) => proc.send(message),
|
|
91
|
+
exited: proc.exited,
|
|
92
|
+
_exitCode: void 0
|
|
93
|
+
};
|
|
94
|
+
proc.exited.then((code) => {
|
|
95
|
+
child._exitCode = code;
|
|
96
|
+
this.close(`process exited with code ${code}`);
|
|
97
|
+
});
|
|
98
|
+
this.#process = child;
|
|
99
|
+
}
|
|
100
|
+
#initNodeProcess(execArgv, env) {
|
|
101
|
+
const child = spawn(resolveBunPath(), [...execArgv || [], this._workerEntry], {
|
|
102
|
+
env,
|
|
103
|
+
stdio: [
|
|
104
|
+
"pipe",
|
|
105
|
+
"pipe",
|
|
106
|
+
"pipe",
|
|
107
|
+
"ipc"
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
const exited = new Promise((resolve) => {
|
|
111
|
+
child.once("exit", (code) => resolve(code ?? 1));
|
|
112
|
+
});
|
|
113
|
+
const handle = {
|
|
114
|
+
pid: child.pid,
|
|
115
|
+
kill: () => child.kill(),
|
|
116
|
+
send: (message) => child.send(message),
|
|
117
|
+
exited,
|
|
118
|
+
_exitCode: void 0,
|
|
119
|
+
removeAllListeners: () => child.removeAllListeners()
|
|
120
|
+
};
|
|
121
|
+
child.once("exit", (code) => {
|
|
122
|
+
handle._exitCode = code;
|
|
123
|
+
this.close(`process exited with code ${code}`);
|
|
124
|
+
});
|
|
125
|
+
child.on("error", (error) => {
|
|
126
|
+
if (!this.closed) {
|
|
127
|
+
console.error(`Process error:`, error);
|
|
128
|
+
this.close(error);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
child.on("message", (message) => {
|
|
132
|
+
this._handleMessage(message);
|
|
133
|
+
});
|
|
134
|
+
this.#process = handle;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
//#endregion
|
|
138
|
+
export { BunProcessEnvRunner };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { n as resolveEntry, t as parseServerAddress } from "../../_chunks/worker-utils.mjs";
|
|
2
|
+
import { serve } from "srvx";
|
|
3
|
+
//#region src/runners/bun-process/worker.ts
|
|
4
|
+
const entry = await resolveEntry(JSON.parse(process.env.ENV_RUNNER_DATA || "{}").entry);
|
|
5
|
+
const server = serve({
|
|
6
|
+
port: 0,
|
|
7
|
+
hostname: "127.0.0.1",
|
|
8
|
+
silent: true,
|
|
9
|
+
fetch: entry.fetch,
|
|
10
|
+
middleware: entry.middleware,
|
|
11
|
+
plugins: entry.plugins,
|
|
12
|
+
gracefulShutdown: false
|
|
13
|
+
});
|
|
14
|
+
await server.ready();
|
|
15
|
+
if (entry.ipc) await entry.ipc.onOpen?.({ sendMessage: (message) => process.send(message) });
|
|
16
|
+
process.send({ address: parseServerAddress(server) });
|
|
17
|
+
process.on("message", (message) => {
|
|
18
|
+
if (message?.event === "shutdown") {
|
|
19
|
+
Promise.resolve(entry.ipc?.onClose?.()).then(() => server.close()).then(() => {
|
|
20
|
+
process.send({ event: "exit" });
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (message?.type === "ping") {
|
|
25
|
+
process.send({
|
|
26
|
+
type: "pong",
|
|
27
|
+
data: message.data
|
|
28
|
+
});
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
entry.ipc?.onMessage?.(message);
|
|
32
|
+
});
|
|
33
|
+
//#endregion
|
|
34
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { n as resolveEntry, t as parseServerAddress } from "../../_chunks/worker-utils.mjs";
|
|
2
|
+
import { serve } from "srvx";
|
|
3
|
+
//#region src/runners/deno-process/worker.ts
|
|
4
|
+
const entry = await resolveEntry(JSON.parse(process.env.ENV_RUNNER_DATA || "{}").entry);
|
|
5
|
+
const server = serve({
|
|
6
|
+
port: 0,
|
|
7
|
+
hostname: "127.0.0.1",
|
|
8
|
+
silent: true,
|
|
9
|
+
fetch: entry.fetch,
|
|
10
|
+
middleware: entry.middleware,
|
|
11
|
+
plugins: entry.plugins,
|
|
12
|
+
gracefulShutdown: false
|
|
13
|
+
});
|
|
14
|
+
await server.ready();
|
|
15
|
+
if (entry.ipc) await entry.ipc.onOpen?.({ sendMessage: (message) => process.send(message) });
|
|
16
|
+
process.send({ address: parseServerAddress(server) });
|
|
17
|
+
process.on("message", (message) => {
|
|
18
|
+
if (message?.event === "shutdown") {
|
|
19
|
+
Promise.resolve(entry.ipc?.onClose?.()).then(() => server.close()).then(() => {
|
|
20
|
+
process.send({ event: "exit" });
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (message?.type === "ping") {
|
|
25
|
+
process.send({
|
|
26
|
+
type: "pong",
|
|
27
|
+
data: message.data
|
|
28
|
+
});
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
entry.ipc?.onMessage?.(message);
|
|
32
|
+
});
|
|
33
|
+
//#endregion
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { d as WorkerHooks, n as EnvRunnerData, t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/runners/node-process/runner.d.ts
|
|
4
|
+
declare class NodeProcessEnvRunner extends BaseEnvRunner {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(opts: {
|
|
7
|
+
name: string;
|
|
8
|
+
workerEntry?: string;
|
|
9
|
+
hooks?: WorkerHooks;
|
|
10
|
+
data?: EnvRunnerData;
|
|
11
|
+
execArgv?: string[];
|
|
12
|
+
});
|
|
13
|
+
sendMessage(message: unknown): void;
|
|
14
|
+
protected _hasRuntime(): boolean;
|
|
15
|
+
protected _runtimeType(): string;
|
|
16
|
+
protected _closeRuntime(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { NodeProcessEnvRunner, type EnvRunnerData as ProcessEnvRunnerData };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import "../../_chunks/libs/std-env.mjs";
|
|
2
|
+
import { t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { fork } from "node:child_process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
//#region src/runners/node-process/runner.ts
|
|
7
|
+
let _defaultEntry;
|
|
8
|
+
var NodeProcessEnvRunner = class extends BaseEnvRunner {
|
|
9
|
+
#process;
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
_defaultEntry ||= fileURLToPath(import.meta.resolve("env-runner/runners/node-process/worker"));
|
|
12
|
+
super({
|
|
13
|
+
...opts,
|
|
14
|
+
workerEntry: opts.workerEntry || _defaultEntry
|
|
15
|
+
});
|
|
16
|
+
this.#initProcess(opts.execArgv);
|
|
17
|
+
}
|
|
18
|
+
sendMessage(message) {
|
|
19
|
+
if (!this.#process) throw new Error("Node env process should be initialized before sending messages.");
|
|
20
|
+
this.#process.send(message);
|
|
21
|
+
}
|
|
22
|
+
_hasRuntime() {
|
|
23
|
+
return Boolean(this.#process);
|
|
24
|
+
}
|
|
25
|
+
_runtimeType() {
|
|
26
|
+
return "process";
|
|
27
|
+
}
|
|
28
|
+
async _closeRuntime() {
|
|
29
|
+
if (!this.#process) return;
|
|
30
|
+
await this._requestGracefulShutdown(() => this.#process.send({ event: "shutdown" }), (resolve) => {
|
|
31
|
+
this.#process?.on("message", (message) => {
|
|
32
|
+
if (message.event === "exit") resolve();
|
|
33
|
+
});
|
|
34
|
+
}, () => this.#process?._exitCode != null);
|
|
35
|
+
this.#process.removeAllListeners();
|
|
36
|
+
this.#process.kill();
|
|
37
|
+
this.#process = void 0;
|
|
38
|
+
}
|
|
39
|
+
#initProcess(execArgv) {
|
|
40
|
+
if (!existsSync(this._workerEntry)) {
|
|
41
|
+
this.close(`process entry not found in "${this._workerEntry}".`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const child = fork(this._workerEntry, [], {
|
|
45
|
+
env: {
|
|
46
|
+
...process.env,
|
|
47
|
+
ENV_RUNNER_NAME: this._name,
|
|
48
|
+
ENV_RUNNER_DATA: JSON.stringify(this._data || {})
|
|
49
|
+
},
|
|
50
|
+
stdio: [
|
|
51
|
+
"pipe",
|
|
52
|
+
"pipe",
|
|
53
|
+
"pipe",
|
|
54
|
+
"ipc"
|
|
55
|
+
],
|
|
56
|
+
execArgv: execArgv || []
|
|
57
|
+
});
|
|
58
|
+
child.once("exit", (code) => {
|
|
59
|
+
child._exitCode = code;
|
|
60
|
+
this.close(`process exited with code ${code}`);
|
|
61
|
+
});
|
|
62
|
+
child.once("error", (error) => {
|
|
63
|
+
console.error(`Process error:`, error);
|
|
64
|
+
this.close(error);
|
|
65
|
+
});
|
|
66
|
+
child.on("message", (message) => {
|
|
67
|
+
this._handleMessage(message);
|
|
68
|
+
});
|
|
69
|
+
this.#process = child;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
export { NodeProcessEnvRunner };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { n as resolveEntry, t as parseServerAddress } from "../../_chunks/worker-utils.mjs";
|
|
2
|
+
import { serve } from "srvx";
|
|
3
|
+
//#region src/runners/node-process/worker.ts
|
|
4
|
+
const entry = await resolveEntry(JSON.parse(process.env.ENV_RUNNER_DATA || "{}").entry);
|
|
5
|
+
const server = serve({
|
|
6
|
+
port: 0,
|
|
7
|
+
hostname: "127.0.0.1",
|
|
8
|
+
silent: true,
|
|
9
|
+
fetch: entry.fetch,
|
|
10
|
+
middleware: entry.middleware,
|
|
11
|
+
plugins: entry.plugins,
|
|
12
|
+
gracefulShutdown: false
|
|
13
|
+
});
|
|
14
|
+
await server.ready();
|
|
15
|
+
if (entry.ipc) await entry.ipc.onOpen?.({ sendMessage: (message) => process.send(message) });
|
|
16
|
+
process.send({ address: parseServerAddress(server) });
|
|
17
|
+
process.on("message", (message) => {
|
|
18
|
+
if (message?.event === "shutdown") {
|
|
19
|
+
Promise.resolve(entry.ipc?.onClose?.()).then(() => server.close()).then(() => {
|
|
20
|
+
process.send({ event: "exit" });
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (message?.type === "ping") {
|
|
25
|
+
process.send({
|
|
26
|
+
type: "pong",
|
|
27
|
+
data: message.data
|
|
28
|
+
});
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
entry.ipc?.onMessage?.(message);
|
|
32
|
+
});
|
|
33
|
+
//#endregion
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { d as WorkerHooks, n as EnvRunnerData, t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/runners/node-worker/runner.d.ts
|
|
4
|
+
declare class NodeWorkerEnvRunner extends BaseEnvRunner {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(opts: {
|
|
7
|
+
name: string;
|
|
8
|
+
workerEntry?: string;
|
|
9
|
+
hooks?: WorkerHooks;
|
|
10
|
+
data?: EnvRunnerData;
|
|
11
|
+
});
|
|
12
|
+
sendMessage(message: unknown): void;
|
|
13
|
+
protected _hasRuntime(): boolean;
|
|
14
|
+
protected _runtimeType(): string;
|
|
15
|
+
protected _closeRuntime(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { type EnvRunnerData, NodeWorkerEnvRunner };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import "../../_chunks/libs/std-env.mjs";
|
|
2
|
+
import { t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { Worker } from "node:worker_threads";
|
|
6
|
+
//#region src/runners/node-worker/runner.ts
|
|
7
|
+
let _defaultEntry;
|
|
8
|
+
var NodeWorkerEnvRunner = class extends BaseEnvRunner {
|
|
9
|
+
#worker;
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
_defaultEntry ||= fileURLToPath(import.meta.resolve("env-runner/runners/node-worker/worker"));
|
|
12
|
+
super({
|
|
13
|
+
...opts,
|
|
14
|
+
workerEntry: opts.workerEntry || _defaultEntry
|
|
15
|
+
});
|
|
16
|
+
this.#initWorker();
|
|
17
|
+
}
|
|
18
|
+
sendMessage(message) {
|
|
19
|
+
if (!this.#worker) throw new Error("Node env worker should be initialized before sending messages.");
|
|
20
|
+
this.#worker.postMessage(message);
|
|
21
|
+
}
|
|
22
|
+
_hasRuntime() {
|
|
23
|
+
return Boolean(this.#worker);
|
|
24
|
+
}
|
|
25
|
+
_runtimeType() {
|
|
26
|
+
return "worker";
|
|
27
|
+
}
|
|
28
|
+
async _closeRuntime() {
|
|
29
|
+
if (!this.#worker) return;
|
|
30
|
+
await this._requestGracefulShutdown(() => this.#worker.postMessage({ event: "shutdown" }), (resolve) => {
|
|
31
|
+
this.#worker?.on("message", (message) => {
|
|
32
|
+
if (message.event === "exit") resolve();
|
|
33
|
+
});
|
|
34
|
+
}, () => Boolean(this.#worker?._exitCode));
|
|
35
|
+
this.#worker.removeAllListeners();
|
|
36
|
+
await this.#worker.terminate().catch((error) => {
|
|
37
|
+
console.error(error);
|
|
38
|
+
});
|
|
39
|
+
this.#worker = void 0;
|
|
40
|
+
}
|
|
41
|
+
#initWorker() {
|
|
42
|
+
if (!existsSync(this._workerEntry)) {
|
|
43
|
+
this.close(`worker entry not found in "${this._workerEntry}".`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const worker = new Worker(this._workerEntry, {
|
|
47
|
+
env: { ...process.env },
|
|
48
|
+
workerData: {
|
|
49
|
+
name: this._name,
|
|
50
|
+
...this._data
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
worker.once("exit", (code) => {
|
|
54
|
+
worker._exitCode = code;
|
|
55
|
+
this.close(`worker exited with code ${code}`);
|
|
56
|
+
});
|
|
57
|
+
worker.once("error", (error) => {
|
|
58
|
+
console.error(`Worker error:`, error);
|
|
59
|
+
this.close(error);
|
|
60
|
+
});
|
|
61
|
+
worker.on("message", (message) => {
|
|
62
|
+
this._handleMessage(message);
|
|
63
|
+
});
|
|
64
|
+
this.#worker = worker;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { NodeWorkerEnvRunner };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { n as resolveEntry, t as parseServerAddress } from "../../_chunks/worker-utils.mjs";
|
|
2
|
+
import { parentPort, workerData } from "node:worker_threads";
|
|
3
|
+
import { serve } from "srvx";
|
|
4
|
+
//#region src/runners/node-worker/worker.ts
|
|
5
|
+
const entry = await resolveEntry((workerData || {}).entry);
|
|
6
|
+
const server = serve({
|
|
7
|
+
port: 0,
|
|
8
|
+
hostname: "127.0.0.1",
|
|
9
|
+
silent: true,
|
|
10
|
+
fetch: entry.fetch,
|
|
11
|
+
middleware: entry.middleware,
|
|
12
|
+
plugins: entry.plugins,
|
|
13
|
+
gracefulShutdown: false
|
|
14
|
+
});
|
|
15
|
+
await server.ready();
|
|
16
|
+
if (entry.ipc) await entry.ipc.onOpen?.({ sendMessage: (message) => parentPort?.postMessage(message) });
|
|
17
|
+
parentPort?.postMessage({ address: parseServerAddress(server) });
|
|
18
|
+
parentPort?.on("message", (message) => {
|
|
19
|
+
if (message?.event === "shutdown") {
|
|
20
|
+
Promise.resolve(entry.ipc?.onClose?.()).then(() => server.close()).then(() => {
|
|
21
|
+
parentPort?.postMessage({ event: "exit" });
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (message?.type === "ping") {
|
|
26
|
+
parentPort?.postMessage({
|
|
27
|
+
type: "pong",
|
|
28
|
+
data: message.data
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
entry.ipc?.onMessage?.(message);
|
|
33
|
+
});
|
|
34
|
+
//#endregion
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { d as WorkerHooks, n as EnvRunnerData, t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/runners/self/runner.d.ts
|
|
4
|
+
declare class SelfEnvRunner extends BaseEnvRunner {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(opts: {
|
|
7
|
+
name: string;
|
|
8
|
+
hooks?: WorkerHooks;
|
|
9
|
+
data?: EnvRunnerData;
|
|
10
|
+
});
|
|
11
|
+
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
12
|
+
sendMessage(message: unknown): void;
|
|
13
|
+
protected _hasRuntime(): boolean;
|
|
14
|
+
protected _runtimeType(): string;
|
|
15
|
+
protected _closeRuntime(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { SelfEnvRunner, type EnvRunnerData as SelfEnvRunnerData };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import "../../_chunks/libs/std-env.mjs";
|
|
2
|
+
import { t as BaseEnvRunner } from "../../_chunks/base-runner.mjs";
|
|
3
|
+
import { n as resolveEntry } from "../../_chunks/worker-utils.mjs";
|
|
4
|
+
//#region src/runners/self/runner.ts
|
|
5
|
+
var SelfEnvRunner = class extends BaseEnvRunner {
|
|
6
|
+
#active = false;
|
|
7
|
+
#entry;
|
|
8
|
+
constructor(opts) {
|
|
9
|
+
super({
|
|
10
|
+
...opts,
|
|
11
|
+
workerEntry: ""
|
|
12
|
+
});
|
|
13
|
+
this.#init();
|
|
14
|
+
}
|
|
15
|
+
async fetch(input, init) {
|
|
16
|
+
if (!this.#entry || this.closed) return new Response("self env runner is unavailable", { status: 503 });
|
|
17
|
+
const request = input instanceof Request ? input : new Request(input, init);
|
|
18
|
+
return this.#entry.fetch(request);
|
|
19
|
+
}
|
|
20
|
+
sendMessage(message) {
|
|
21
|
+
if (!this.#active) throw new Error("Self env runner should be initialized before sending messages.");
|
|
22
|
+
if (message?.type === "ping") {
|
|
23
|
+
queueMicrotask(() => this._handleMessage({
|
|
24
|
+
type: "pong",
|
|
25
|
+
data: message.data
|
|
26
|
+
}));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this.#entry?.ipc?.onMessage?.(message);
|
|
30
|
+
}
|
|
31
|
+
_hasRuntime() {
|
|
32
|
+
return this.#active;
|
|
33
|
+
}
|
|
34
|
+
_runtimeType() {
|
|
35
|
+
return "self";
|
|
36
|
+
}
|
|
37
|
+
async _closeRuntime() {
|
|
38
|
+
if (!this.#active) return;
|
|
39
|
+
this.#active = false;
|
|
40
|
+
await this.#entry?.ipc?.onClose?.();
|
|
41
|
+
this.#entry = void 0;
|
|
42
|
+
}
|
|
43
|
+
#init() {
|
|
44
|
+
const entryPath = this._data?.entry;
|
|
45
|
+
if (!entryPath) {
|
|
46
|
+
this.close("self runner requires data.entry");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.#active = true;
|
|
50
|
+
resolveEntry(entryPath).then(async (entry) => {
|
|
51
|
+
this.#entry = entry;
|
|
52
|
+
await entry.ipc?.onOpen?.({ sendMessage: (message) => {
|
|
53
|
+
queueMicrotask(() => this._handleMessage(message));
|
|
54
|
+
} });
|
|
55
|
+
this._handleMessage({ address: {
|
|
56
|
+
host: "127.0.0.1",
|
|
57
|
+
port: 0
|
|
58
|
+
} });
|
|
59
|
+
}).catch((error) => {
|
|
60
|
+
console.error("Self runner entry error:", error);
|
|
61
|
+
this.close(error);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { SelfEnvRunner };
|
package/package.json
CHANGED
|
@@ -1,4 +1,67 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "env-runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Generic environment runner for JavaScript runtimes.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": "unjs/env-runner",
|
|
7
|
+
"bin": {
|
|
8
|
+
"env-runner": "./dist/cli.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"exports": {
|
|
16
|
+
".": "./dist/index.mjs",
|
|
17
|
+
"./runners/node-worker": "./dist/runners/node-worker/runner.mjs",
|
|
18
|
+
"./runners/node-worker/worker": "./dist/runners/node-worker/worker.mjs",
|
|
19
|
+
"./runners/node-process": "./dist/runners/node-process/runner.mjs",
|
|
20
|
+
"./runners/node-process/worker": "./dist/runners/node-process/worker.mjs",
|
|
21
|
+
"./runners/bun-process": "./dist/runners/bun-process/runner.mjs",
|
|
22
|
+
"./runners/bun-process/worker": "./dist/runners/bun-process/worker.mjs",
|
|
23
|
+
"./runners/deno-process": "./dist/runners/deno-process/runner.mjs",
|
|
24
|
+
"./runners/deno-process/worker": "./dist/runners/deno-process/worker.mjs",
|
|
25
|
+
"./runners/self": "./dist/runners/self/runner.mjs",
|
|
26
|
+
"./runners/miniflare": "./dist/runners/miniflare/runner.mjs"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "obuild",
|
|
30
|
+
"dev": "vitest dev",
|
|
31
|
+
"fmt": "automd && oxlint . --fix && oxfmt .",
|
|
32
|
+
"lint": "oxlint . && oxfmt --check .",
|
|
33
|
+
"prepack": "pnpm build",
|
|
34
|
+
"env-runner": "node ./src/cli.ts",
|
|
35
|
+
"release": "pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags",
|
|
36
|
+
"test": "pnpm lint && pnpm typecheck && vitest run --coverage",
|
|
37
|
+
"typecheck": "tsgo --noEmit --skipLibCheck"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"httpxy": "^0.3.1",
|
|
41
|
+
"srvx": "^0.11.9"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "latest",
|
|
45
|
+
"@typescript/native-preview": "latest",
|
|
46
|
+
"@vitest/coverage-v8": "latest",
|
|
47
|
+
"automd": "latest",
|
|
48
|
+
"changelogen": "latest",
|
|
49
|
+
"env-runner-fixture": "link:.",
|
|
50
|
+
"miniflare": "^4.20260301.1",
|
|
51
|
+
"obuild": "latest",
|
|
52
|
+
"oxfmt": "latest",
|
|
53
|
+
"oxlint": "latest",
|
|
54
|
+
"std-env": "4.0.0-rc.1",
|
|
55
|
+
"typescript": "latest",
|
|
56
|
+
"vitest": "latest"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"miniflare": "^4.0.0"
|
|
60
|
+
},
|
|
61
|
+
"peerDependenciesMeta": {
|
|
62
|
+
"miniflare": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"packageManager": "pnpm@10.29.3"
|
|
4
67
|
}
|