env-runner 0.2.3 → 0.3.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/README.md +154 -19
- package/dist/_chunks/common-base-runner.d.mts +52 -14
- package/dist/_chunks/common-base-runner.mjs +123 -32
- package/dist/_chunks/common-process-data.mjs +13 -0
- package/dist/_chunks/common-worker-utils.mjs +464 -73
- package/dist/_chunks/deno-process-runner.mjs +2 -6
- package/dist/_chunks/lexer.mjs +2 -0
- package/dist/_chunks/libs/cjs-module-lexer.mjs +6 -1
- package/dist/_chunks/miniflare-runner.d.mts +21 -12
- package/dist/_chunks/miniflare-runner.mjs +266 -96
- package/dist/_chunks/node-worker-runner.mjs +1 -2
- package/dist/_chunks/server.mjs +20 -5
- package/dist/_chunks/types.d.mts +36 -0
- package/dist/_chunks/virtual-loader.mjs +303 -29
- package/dist/index.d.mts +17 -4
- package/dist/runners/bun-process/runner.mjs +4 -8
- package/dist/runners/bun-process/worker.mjs +8 -8
- package/dist/runners/deno-process/worker.mjs +8 -8
- package/dist/runners/node-process/runner.mjs +2 -6
- package/dist/runners/node-process/worker.mjs +8 -8
- package/dist/runners/node-worker/worker.mjs +6 -7
- package/dist/runners/self/runner.d.mts +2 -1
- package/dist/runners/self/runner.mjs +8 -0
- package/package.json +11 -11
- package/dist/_chunks/common-host-env.mjs +0 -11
|
@@ -1,25 +1,37 @@
|
|
|
1
|
-
import { createVirtualHooks, expandVirtualInvalidation, stripVirtualTypeScript, virtualModuleFormat } from "./virtual-loader.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { createVirtualHooks, decodeVirtualModules, expandVirtualInvalidation, findVirtualPathKey, stripVirtualTypeScript, unsupportedVirtualJSXError, virtualKeyURL, virtualModuleCacheId, virtualModuleCode, virtualModuleFormat } from "./virtual-loader.mjs";
|
|
2
|
+
import { basename, dirname, isAbsolute, resolve, sep } from "node:path";
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
+
async function registerVirtualModules(wire) {
|
|
5
|
+
if (!wire || Object.keys(wire).length === 0) return _once(() => {
|
|
6
|
+
for (const unregister of _lazyUnregisters.splice(0)) unregister();
|
|
7
|
+
});
|
|
8
|
+
let virtual = decodeVirtualModules(wire);
|
|
9
|
+
const { registerHooks, stripTypeScriptTypes, createRequire } = await import("node:module");
|
|
8
10
|
if (typeof registerHooks === "function") {
|
|
9
11
|
const isDeno = "Deno" in globalThis;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const prepare = isDeno ? (key, module) => _prepareForDeno(key, module, stripTypeScriptTypes) : _prepareForNode;
|
|
13
|
+
virtual = await _prepareVirtualModules(virtual, prepare);
|
|
14
|
+
const versions = /* @__PURE__ */ new Map();
|
|
15
|
+
const importers = /* @__PURE__ */ new Map();
|
|
16
|
+
const { resolve, load, updateKeys } = createVirtualHooks(virtual, {
|
|
17
|
+
versions,
|
|
18
|
+
importers,
|
|
19
|
+
forcePlainModule: isDeno,
|
|
20
|
+
opaquePathURL: isDeno ? (url) => url.endsWith(".cjs") || url.endsWith(".cts") : void 0
|
|
21
|
+
});
|
|
22
|
+
const hooks = registerHooks({
|
|
23
|
+
resolve,
|
|
24
|
+
load
|
|
25
|
+
});
|
|
17
26
|
const registration = {
|
|
18
27
|
virtual,
|
|
19
|
-
versions
|
|
20
|
-
|
|
28
|
+
versions,
|
|
29
|
+
version: 0,
|
|
30
|
+
importers,
|
|
31
|
+
prepare,
|
|
32
|
+
updateKeys,
|
|
33
|
+
cache: createRequire(import.meta.url).cache
|
|
21
34
|
};
|
|
22
|
-
const hooks = registerHooks(createVirtualHooks(virtual, registration.versions, void 0, isDeno));
|
|
23
35
|
_hooksRegistrations.unshift(registration);
|
|
24
36
|
return _once(() => {
|
|
25
37
|
const index = _hooksRegistrations.indexOf(registration);
|
|
@@ -28,74 +40,429 @@ async function registerVirtualModules(virtual) {
|
|
|
28
40
|
});
|
|
29
41
|
}
|
|
30
42
|
if (typeof globalThis.Bun?.plugin === "function") {
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
virtual = await _prepareVirtualModules(virtual, _prepareForBun);
|
|
44
|
+
const registration = _createBunRegistration(virtual, createRequire(import.meta.url).cache);
|
|
45
|
+
globalThis.Bun.plugin({
|
|
46
|
+
name: "env-runner-virtual",
|
|
47
|
+
setup: (build) => _setupBunPlugin(build, registration)
|
|
48
|
+
});
|
|
49
|
+
_bunRegistrations.unshift(registration);
|
|
33
50
|
return _once(() => {
|
|
34
|
-
|
|
51
|
+
const index = _bunRegistrations.indexOf(registration);
|
|
52
|
+
if (index !== -1) _bunRegistrations.splice(index, 1);
|
|
53
|
+
for (const path of [...registration.paths.keys(), ...registration.removed.keys()]) _bunReleasedPaths.add(path);
|
|
35
54
|
});
|
|
36
55
|
}
|
|
37
|
-
console.warn("[env-runner] virtual modules require `module.registerHooks` (Node.js >= 22.15 / Deno >= 2.
|
|
56
|
+
console.warn("[env-runner] virtual modules require `module.registerHooks` (Node.js >= 22.15 / Deno >= 2.8) or `Bun.plugin`; skipping registration.");
|
|
38
57
|
return _noop;
|
|
39
58
|
}
|
|
40
59
|
function refreshVirtualModule(specifier) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
function invalidateVirtualModule(specifier, source) {
|
|
46
|
-
for (const registration of _hooksRegistrations) {
|
|
47
|
-
if (!Object.hasOwn(registration.virtual, specifier)) continue;
|
|
48
|
-
const { virtual, versions, transformSource } = registration;
|
|
49
|
-
if (source !== void 0) virtual[specifier] = transformSource ? transformSource(specifier, source) : source;
|
|
50
|
-
for (const key of expandVirtualInvalidation(virtual, specifier)) versions.set(key, (versions.get(key) ?? 0) + 1);
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
if (_bunVirtual && Object.hasOwn(_bunVirtual, specifier)) {
|
|
54
|
-
if (source !== void 0) _bunVirtual[specifier] = source;
|
|
55
|
-
_registerBunModules(expandVirtualInvalidation(_bunVirtual, specifier));
|
|
60
|
+
for (const registration of _bunRegistrations) if (Object.hasOwn(registration.virtual, specifier)) {
|
|
61
|
+
_bustBunModules(registration, [specifier]);
|
|
56
62
|
return true;
|
|
57
63
|
}
|
|
58
64
|
return false;
|
|
59
65
|
}
|
|
60
|
-
function
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
async function updateVirtualModules(wire) {
|
|
67
|
+
const changes = decodeVirtualModules(wire);
|
|
68
|
+
if (_hooksRegistrations.length === 0 && _bunRegistrations.length === 0) {
|
|
69
|
+
const added = Object.fromEntries(Object.entries(changes).filter((entry) => entry[1] !== null));
|
|
70
|
+
if (Object.keys(added).length === 0) return;
|
|
71
|
+
const unregister = await registerVirtualModules(added);
|
|
72
|
+
if (_hooksRegistrations.length === 0 && _bunRegistrations.length === 0) throw new Error("Cannot update virtual modules: this runtime can't serve them");
|
|
73
|
+
_lazyUnregisters.push(unregister);
|
|
74
|
+
}
|
|
75
|
+
const registrations = _hooksRegistrations.length > 0 ? _hooksRegistrations : _bunRegistrations;
|
|
76
|
+
const groups = /* @__PURE__ */ new Map();
|
|
77
|
+
for (const [key, module] of Object.entries(changes)) {
|
|
78
|
+
const owner = registrations.find((registration) => Object.hasOwn(registration.virtual, key)) ?? (module === null ? void 0 : registrations[0]);
|
|
79
|
+
if (owner) {
|
|
80
|
+
let group = groups.get(owner);
|
|
81
|
+
if (!group) groups.set(owner, group = {});
|
|
82
|
+
group[key] = module;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const prepared = [];
|
|
86
|
+
for (const [registration, group] of groups) {
|
|
87
|
+
const prepare = "prepare" in registration ? registration.prepare : _prepareForBun;
|
|
88
|
+
prepared.push([registration, await _prepareVirtualModules(group, prepare)]);
|
|
89
|
+
}
|
|
90
|
+
for (const [registration, sources] of prepared) if ("updateKeys" in registration) _updateHooksRegistration(registration, sources);
|
|
91
|
+
else _updateBunRegistration(registration, sources);
|
|
92
|
+
}
|
|
93
|
+
function handleUpdateVirtualModules(message, sendMessage) {
|
|
94
|
+
_pendingUpdate = _pendingUpdate.then(() => updateVirtualModules(message.changes ?? {})).then(() => sendMessage({
|
|
95
|
+
event: "virtual-modules-updated",
|
|
96
|
+
id: message.id
|
|
97
|
+
}), (error) => sendMessage({
|
|
98
|
+
event: "virtual-modules-updated",
|
|
99
|
+
id: message.id,
|
|
100
|
+
error: error?.message || String(error)
|
|
101
|
+
})).catch(() => {});
|
|
102
|
+
return _pendingUpdate;
|
|
103
|
+
}
|
|
104
|
+
function registeredVirtualModules() {
|
|
105
|
+
const merged = {};
|
|
106
|
+
for (const registration of [..._hooksRegistrations, ..._bunRegistrations].reverse()) Object.assign(merged, registration.virtual);
|
|
107
|
+
return merged;
|
|
108
|
+
}
|
|
109
|
+
let _pendingUpdate = Promise.resolve();
|
|
110
|
+
const _lazyUnregisters = [];
|
|
111
|
+
function _updateHooksRegistration(registration, changes) {
|
|
112
|
+
const { virtual, versions, importers } = registration;
|
|
113
|
+
const added = [];
|
|
114
|
+
const removed = [];
|
|
115
|
+
for (const [key, module] of Object.entries(changes)) {
|
|
116
|
+
if (module === null) {
|
|
117
|
+
removed.push(key);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (!Object.hasOwn(virtual, key)) added.push(key);
|
|
121
|
+
virtual[key] = module;
|
|
122
|
+
}
|
|
123
|
+
registration.updateKeys(added);
|
|
124
|
+
const targets = Object.keys(changes).flatMap((key) => {
|
|
125
|
+
const url = virtualKeyURL(key);
|
|
126
|
+
return url && url !== key ? [key, url] : [key];
|
|
66
127
|
});
|
|
128
|
+
for (const node of expandVirtualInvalidation(virtual, targets, importers)) {
|
|
129
|
+
versions.set(node, ++registration.version);
|
|
130
|
+
if (Object.hasOwn(virtual, node)) delete registration.cache[virtualModuleCacheId(node)];
|
|
131
|
+
}
|
|
132
|
+
for (const key of removed) delete virtual[key];
|
|
133
|
+
registration.updateKeys(removed);
|
|
67
134
|
}
|
|
68
135
|
const _hooksRegistrations = [];
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
136
|
+
const _bunRegistrations = [];
|
|
137
|
+
const BUN_NAMESPACE = "env-runner-virtual";
|
|
138
|
+
const BUN_VIRTUAL_MARKER = "__env_runner_virtual";
|
|
139
|
+
const BUN_DISK_MARKER = "__env_runner_disk";
|
|
140
|
+
let _bunNamespaceLoader = false;
|
|
141
|
+
let _bunDynamicCallbacks = false;
|
|
142
|
+
const _bunDynamicNames = /* @__PURE__ */ new Set();
|
|
143
|
+
const _bunReleasedPaths = /* @__PURE__ */ new Set();
|
|
144
|
+
function _createBunRegistration(virtual, cache) {
|
|
145
|
+
const registration = {
|
|
146
|
+
virtual,
|
|
147
|
+
paths: /* @__PURE__ */ new Map(),
|
|
148
|
+
namespaced: /* @__PURE__ */ new Set(),
|
|
149
|
+
modules: /* @__PURE__ */ new Set(),
|
|
150
|
+
dynamic: /* @__PURE__ */ new Set(),
|
|
151
|
+
removed: /* @__PURE__ */ new Map(),
|
|
152
|
+
versions: /* @__PURE__ */ new Map(),
|
|
153
|
+
version: 0,
|
|
154
|
+
importers: /* @__PURE__ */ new Map(),
|
|
155
|
+
served: /* @__PURE__ */ new Map(),
|
|
156
|
+
cache
|
|
157
|
+
};
|
|
158
|
+
for (const key of Object.keys(virtual)) _addBunKey(registration, key);
|
|
159
|
+
return registration;
|
|
160
|
+
}
|
|
161
|
+
function _addBunKey(registration, key) {
|
|
162
|
+
const path = _keyPath(key);
|
|
163
|
+
if (path === void 0) {
|
|
164
|
+
(!key.includes(":") && _bunResolvable(key) ? registration.namespaced : registration.modules).add(key);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (_bunResolvable(basename(path))) {
|
|
168
|
+
registration.paths.set(path, key);
|
|
169
|
+
registration.removed.delete(path);
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
registration.modules.add(key);
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
function _setupBunPlugin(build, registration) {
|
|
176
|
+
registration.build = build;
|
|
177
|
+
const query = String.raw`(?:\?.*)?$`;
|
|
178
|
+
const resolveFilters = [...[...registration.namespaced].map((key) => `^${_escapeRegExp(key)}${query}`), ...[...registration.paths.keys()].map((path) => String.raw`(?:^|[\\/])${_escapeRegExp(basename(path))}${query}`)];
|
|
179
|
+
if (resolveFilters.length > 0) build.onResolve({ filter: new RegExp(resolveFilters.join("|")) }, _resolveBunModule);
|
|
180
|
+
if (registration.paths.size > 0) {
|
|
181
|
+
const paths = [...registration.paths.keys()].map(_escapeRegExp).join("|");
|
|
182
|
+
const loadQuery = String.raw`(?:\?(?!${BUN_DISK_MARKER}(?:&|$)).*)?$`;
|
|
183
|
+
build.onLoad({ filter: new RegExp(`^(?:${paths})${loadQuery}`) }, _loadBunPath);
|
|
184
|
+
}
|
|
185
|
+
if (registration.namespaced.size > 0 && !_bunNamespaceLoader) {
|
|
186
|
+
_bunNamespaceLoader = true;
|
|
187
|
+
build.onLoad({
|
|
188
|
+
filter: /.*/,
|
|
189
|
+
namespace: BUN_NAMESPACE
|
|
190
|
+
}, _loadBunNamespaced);
|
|
191
|
+
}
|
|
192
|
+
for (const key of registration.modules) build.module(key, () => _loadBunModule(key));
|
|
193
|
+
}
|
|
194
|
+
function _installBunDynamicCallbacks(build) {
|
|
195
|
+
if (!_bunDynamicCallbacks) {
|
|
196
|
+
_bunDynamicCallbacks = true;
|
|
197
|
+
build.onResolve({ filter: /.*/ }, _resolveBunDynamic);
|
|
198
|
+
const marker = new RegExp(String.raw`\?${BUN_VIRTUAL_MARKER}(?:&|$)`);
|
|
199
|
+
build.onLoad({ filter: marker }, _loadBunPath);
|
|
200
|
+
}
|
|
201
|
+
if (!_bunNamespaceLoader) {
|
|
202
|
+
_bunNamespaceLoader = true;
|
|
203
|
+
build.onLoad({
|
|
204
|
+
filter: /.*/,
|
|
205
|
+
namespace: BUN_NAMESPACE
|
|
206
|
+
}, _loadBunNamespaced);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function _updateBunRegistration(registration, changes) {
|
|
210
|
+
const { virtual } = registration;
|
|
211
|
+
const removed = [];
|
|
212
|
+
let dynamic = false;
|
|
213
|
+
for (const [key, source] of Object.entries(changes)) {
|
|
214
|
+
if (source === null) {
|
|
215
|
+
removed.push(key);
|
|
216
|
+
continue;
|
|
87
217
|
}
|
|
88
|
-
|
|
218
|
+
if (!Object.hasOwn(virtual, key)) {
|
|
219
|
+
const path = _keyPath(key);
|
|
220
|
+
if (_addBunKey(registration, key)) {
|
|
221
|
+
registration.dynamic.add(path);
|
|
222
|
+
_bunDynamicNames.add(_bunSpecifierName(path));
|
|
223
|
+
} else if (registration.namespaced.has(key)) _bunDynamicNames.add(_bunSpecifierName(key));
|
|
224
|
+
dynamic ||= !registration.modules.has(key);
|
|
225
|
+
}
|
|
226
|
+
virtual[key] = source;
|
|
227
|
+
}
|
|
228
|
+
if (dynamic) _installBunDynamicCallbacks(registration.build);
|
|
229
|
+
_bustBunModules(registration, expandVirtualInvalidation(virtual, Object.keys(changes), registration.importers));
|
|
230
|
+
for (const key of removed) _removeBunKey(registration, key);
|
|
231
|
+
}
|
|
232
|
+
function _removeBunKey(registration, key) {
|
|
233
|
+
const { virtual, paths } = registration;
|
|
234
|
+
delete virtual[key];
|
|
235
|
+
registration.namespaced.delete(key);
|
|
236
|
+
registration.modules.delete(key);
|
|
237
|
+
const path = _keyPath(key);
|
|
238
|
+
if (path === void 0 || paths.get(path) !== key) return;
|
|
239
|
+
paths.delete(path);
|
|
240
|
+
registration.dynamic.delete(path);
|
|
241
|
+
registration.removed.set(path, key);
|
|
242
|
+
for (const other of Object.keys(virtual)) if (_keyPath(other) === path) {
|
|
243
|
+
paths.set(path, other);
|
|
244
|
+
registration.removed.delete(path);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function _resolveBunModule(args) {
|
|
248
|
+
const specifier = _stripQuery(args.path);
|
|
249
|
+
const query = _stripBunMarker(args.path.slice(specifier.length));
|
|
250
|
+
let path;
|
|
251
|
+
if (isAbsolute(specifier)) path = resolve(specifier);
|
|
252
|
+
else if (/^\.\.?[\\/]/.test(specifier)) path = resolve(_bunImporterDir(args.importer), specifier);
|
|
253
|
+
for (const registration of _bunRegistrations) {
|
|
254
|
+
const namespaced = registration.namespaced.has(specifier);
|
|
255
|
+
const key = namespaced ? specifier : path && registration.paths.get(path);
|
|
256
|
+
if (!key) continue;
|
|
257
|
+
_addBunImporter(registration, key, args.importer);
|
|
258
|
+
const marker = !namespaced && registration.dynamic.has(path) ? BUN_VIRTUAL_MARKER : void 0;
|
|
259
|
+
const served = _bunVersioned((namespaced ? specifier : path) + _withBunMarker(query, marker), registration.versions.get(key));
|
|
260
|
+
_addToSetMap(registration.served, key, namespaced ? `${BUN_NAMESPACE}:${served}` : served);
|
|
261
|
+
return namespaced ? {
|
|
262
|
+
path: served,
|
|
263
|
+
namespace: BUN_NAMESPACE
|
|
264
|
+
} : { path: served };
|
|
265
|
+
}
|
|
266
|
+
for (const registration of _bunRegistrations) {
|
|
267
|
+
const key = path && registration.removed.get(path);
|
|
268
|
+
if (!key) continue;
|
|
269
|
+
_addBunImporter(registration, key, args.importer);
|
|
270
|
+
const served = _bunVersioned(path + _withBunMarker(query, BUN_DISK_MARKER), registration.versions.get(key));
|
|
271
|
+
_addToSetMap(registration.served, key, served);
|
|
272
|
+
return { path: served };
|
|
273
|
+
}
|
|
274
|
+
if (path && _bunReleasedPaths.has(path)) return { path: path + _withBunMarker(query, BUN_DISK_MARKER) };
|
|
275
|
+
}
|
|
276
|
+
function _resolveBunDynamic(args) {
|
|
277
|
+
const name = _bunSpecifierName(_stripQuery(args.path));
|
|
278
|
+
return _bunDynamicNames.has(name) ? _resolveBunModule(args) : void 0;
|
|
279
|
+
}
|
|
280
|
+
function _bunSpecifierName(specifier) {
|
|
281
|
+
return specifier.slice(Math.max(specifier.lastIndexOf("/"), specifier.lastIndexOf("\\")) + 1);
|
|
282
|
+
}
|
|
283
|
+
function _addBunImporter(registration, key, importerId) {
|
|
284
|
+
const importer = _bunKeyOf(registration, importerId);
|
|
285
|
+
if (importer !== void 0 && importer !== key) _addToSetMap(registration.importers, key, importer);
|
|
286
|
+
}
|
|
287
|
+
function _withBunMarker(query, marker) {
|
|
288
|
+
if (!marker) return query;
|
|
289
|
+
return `?${marker}` + (query ? `&${query.slice(1)}` : "");
|
|
290
|
+
}
|
|
291
|
+
function _stripBunMarker(query) {
|
|
292
|
+
for (const marker of [BUN_VIRTUAL_MARKER, BUN_DISK_MARKER]) {
|
|
293
|
+
if (query === `?${marker}`) return "";
|
|
294
|
+
if (query.startsWith(`?${marker}&`)) return `?${query.slice(marker.length + 2)}`;
|
|
295
|
+
}
|
|
296
|
+
return query;
|
|
297
|
+
}
|
|
298
|
+
function _loadBunPath(args) {
|
|
299
|
+
const path = _stripQuery(args.path);
|
|
300
|
+
for (const registration of _bunRegistrations) {
|
|
301
|
+
const key = registration.paths.get(path);
|
|
302
|
+
if (key !== void 0) return _serveBunModule(key, registration.virtual[key]);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function _loadBunNamespaced(args) {
|
|
306
|
+
const key = _stripQuery(args.path);
|
|
307
|
+
return _serveBunModule(key, _bunRegistrations.find((r) => r.namespaced.has(key))?.virtual[key]);
|
|
308
|
+
}
|
|
309
|
+
function _loadBunModule(key) {
|
|
310
|
+
return _serveBunModule(key, _bunRegistrations.find((r) => r.modules.has(key))?.virtual[key]);
|
|
311
|
+
}
|
|
312
|
+
function _serveBunModule(key, module) {
|
|
313
|
+
if (module === void 0) throw new Error(`Cannot find virtual module "${key}" (unregistered)`);
|
|
314
|
+
const format = virtualModuleFormat(key, module);
|
|
315
|
+
const source = typeof module === "string" ? module : module.source;
|
|
316
|
+
switch (format) {
|
|
317
|
+
case "json": return {
|
|
318
|
+
exports: { default: _parseBunJSON(key, source) },
|
|
319
|
+
loader: "object"
|
|
320
|
+
};
|
|
321
|
+
case "text": return {
|
|
322
|
+
exports: { default: source },
|
|
323
|
+
loader: "object"
|
|
324
|
+
};
|
|
325
|
+
case "bytes": return {
|
|
326
|
+
exports: { default: source.slice() },
|
|
327
|
+
loader: "object"
|
|
328
|
+
};
|
|
329
|
+
case "wasm": return {
|
|
330
|
+
exports: { default: new WebAssembly.Module(source) },
|
|
331
|
+
loader: "object"
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
contents: source,
|
|
336
|
+
loader: format === "module-typescript" ? "ts" : format === "module" ? "js" : format
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
function _parseBunJSON(key, source) {
|
|
340
|
+
try {
|
|
341
|
+
return JSON.parse(source);
|
|
342
|
+
} catch (error) {
|
|
343
|
+
const message = `[env-runner] invalid JSON in virtual module "${key}": ${error?.message}`;
|
|
344
|
+
throw new SyntaxError(message, { cause: error });
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function _bustBunModules(registration, keys) {
|
|
348
|
+
for (const key of keys) {
|
|
349
|
+
if (registration.modules.has(key)) {
|
|
350
|
+
registration.build.module(key, () => _loadBunModule(key));
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
registration.versions.set(key, ++registration.version);
|
|
354
|
+
for (const id of registration.served.get(key) ?? []) delete registration.cache[id];
|
|
355
|
+
registration.served.delete(key);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
function _bunVersioned(id, version) {
|
|
359
|
+
const param = `v=${version}`;
|
|
360
|
+
if (!version || id.endsWith(`?${param}`) || id.endsWith(`&${param}`)) return id;
|
|
361
|
+
return id + (id.includes("?") ? "&" : "?") + param;
|
|
362
|
+
}
|
|
363
|
+
function _keyPath(key) {
|
|
364
|
+
if (key.startsWith("file:")) try {
|
|
365
|
+
return fileURLToPath(key);
|
|
366
|
+
} catch {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
return isAbsolute(key) ? resolve(key) : void 0;
|
|
370
|
+
}
|
|
371
|
+
function _bunKeyOf(registration, importer) {
|
|
372
|
+
const prefix = `${BUN_NAMESPACE}:`;
|
|
373
|
+
const id = _stripQuery(importer.startsWith(prefix) ? importer.slice(prefix.length) : importer);
|
|
374
|
+
return registration.paths.get(id) ?? (Object.hasOwn(registration.virtual, id) ? id : void 0);
|
|
89
375
|
}
|
|
90
|
-
function
|
|
91
|
-
const
|
|
92
|
-
|
|
376
|
+
function _bunImporterDir(importer) {
|
|
377
|
+
const path = _stripQuery(importer);
|
|
378
|
+
return isAbsolute(path) ? dirname(path) : process.cwd();
|
|
379
|
+
}
|
|
380
|
+
function _bunResolvable(specifier) {
|
|
381
|
+
const dot = specifier.lastIndexOf(".");
|
|
382
|
+
const code = dot === -1 ? 0 : specifier.charCodeAt(dot + 1);
|
|
383
|
+
return code >= 65 && code <= 90 || code >= 97 && code <= 122 || code > 127;
|
|
384
|
+
}
|
|
385
|
+
function _stripQuery(specifier) {
|
|
386
|
+
const qIndex = specifier.indexOf("?");
|
|
387
|
+
return qIndex === -1 ? specifier : specifier.slice(0, qIndex);
|
|
388
|
+
}
|
|
389
|
+
function _addToSetMap(map, key, value) {
|
|
390
|
+
let set = map.get(key);
|
|
391
|
+
if (!set) map.set(key, set = /* @__PURE__ */ new Set());
|
|
392
|
+
set.add(value);
|
|
393
|
+
}
|
|
394
|
+
function _escapeRegExp(value) {
|
|
395
|
+
return value.replace(/[$()*+.?[\\\]^{|}]/g, String.raw`\$&`);
|
|
396
|
+
}
|
|
397
|
+
async function _prepareVirtualModules(virtual, prepare) {
|
|
398
|
+
if (prepare !== _prepareForNode && !_cjsLexer) {
|
|
399
|
+
if (Object.entries(virtual).some(([key, module]) => module !== null && virtualModuleFormat(key, module).startsWith("commonjs"))) {
|
|
400
|
+
const lexer = await import("./lexer.mjs");
|
|
401
|
+
await lexer.init();
|
|
402
|
+
_cjsLexer = lexer;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
const out = {};
|
|
406
|
+
for (const [key, module] of Object.entries(virtual)) out[key] = module === null ? module : prepare(key, module);
|
|
407
|
+
return out;
|
|
408
|
+
}
|
|
409
|
+
let _cjsLexer;
|
|
410
|
+
function _prepareForNode(key, module) {
|
|
411
|
+
const format = virtualModuleFormat(key, module);
|
|
412
|
+
if (format === "jsx" || format === "tsx") throw unsupportedVirtualJSXError(key, format, "Node.js");
|
|
413
|
+
return module;
|
|
414
|
+
}
|
|
415
|
+
function _prepareForBun(key, module) {
|
|
416
|
+
const format = virtualModuleFormat(key, module);
|
|
417
|
+
if (format !== "commonjs" && format !== "commonjs-typescript") return module;
|
|
418
|
+
return {
|
|
419
|
+
source: _commonJSToESM(key, typeof module === "string" ? module : module.source),
|
|
420
|
+
format: format === "commonjs" ? "module" : "module-typescript"
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
function _prepareForDeno(key, module, stripTypeScriptTypes) {
|
|
424
|
+
const format = virtualModuleFormat(key, module);
|
|
425
|
+
const source = typeof module === "string" ? module : module.source;
|
|
426
|
+
const strip = () => stripVirtualTypeScript(key, source, stripTypeScriptTypes, {
|
|
93
427
|
requirement: "(custom load hooks bypass Deno's native type stripping)",
|
|
94
428
|
remedy: "upgrade Deno"
|
|
95
429
|
});
|
|
96
|
-
|
|
430
|
+
switch (format) {
|
|
431
|
+
case "module-typescript": return strip();
|
|
432
|
+
case "commonjs": return _commonJSToESM(key, source);
|
|
433
|
+
case "commonjs-typescript": return _commonJSToESM(key, strip());
|
|
434
|
+
case "json": return `export default JSON.parse(${JSON.stringify(source)});`;
|
|
435
|
+
case "text":
|
|
436
|
+
case "bytes":
|
|
437
|
+
case "wasm": return virtualModuleCode(format, source);
|
|
438
|
+
case "jsx":
|
|
439
|
+
case "tsx": throw unsupportedVirtualJSXError(key, format, "Deno");
|
|
440
|
+
}
|
|
97
441
|
return source;
|
|
98
442
|
}
|
|
443
|
+
function _commonJSToESM(key, source) {
|
|
444
|
+
const path = _keyPath(key);
|
|
445
|
+
const filename = JSON.stringify(path ?? key);
|
|
446
|
+
const dir = JSON.stringify(path ? dirname(path) : process.cwd());
|
|
447
|
+
const base = JSON.stringify(path ?? process.cwd() + sep);
|
|
448
|
+
let names = [];
|
|
449
|
+
try {
|
|
450
|
+
names = _cjsLexer.parse(source).exports;
|
|
451
|
+
} catch {}
|
|
452
|
+
const p = "__envRunner";
|
|
453
|
+
const lines = [
|
|
454
|
+
`import { createRequire as ${p}CreateRequire } from "node:module"; const ${p}Module = { exports: {} }; (function (exports, require, module, __filename, __dirname) {${source}`,
|
|
455
|
+
`}).call(${p}Module.exports, ${p}Module.exports, ${p}CreateRequire(${base}), ${p}Module, ${filename}, ${dir});`,
|
|
456
|
+
`const ${p}Exports = ${p}Module.exports;`,
|
|
457
|
+
`export { ${p}Exports as default, ${p}Exports as "module.exports" };`
|
|
458
|
+
];
|
|
459
|
+
let index = 0;
|
|
460
|
+
for (const name of new Set(names)) if (name !== "default" && name !== "module.exports") {
|
|
461
|
+
const local = `${p}Export${index++}`;
|
|
462
|
+
lines.push(`const ${local} = ${p}Exports?.[${JSON.stringify(name)}];`, `export { ${local} as ${JSON.stringify(name)} };`);
|
|
463
|
+
}
|
|
464
|
+
return lines.join("\n") + "\n";
|
|
465
|
+
}
|
|
99
466
|
const _noop = () => {};
|
|
100
467
|
function _once(fn) {
|
|
101
468
|
let done = false;
|
|
@@ -155,8 +522,13 @@ function toServerOptions(entry) {
|
|
|
155
522
|
gracefulShutdown: false
|
|
156
523
|
};
|
|
157
524
|
}
|
|
158
|
-
function isVirtualSpecifier(specifier, virtual) {
|
|
159
|
-
|
|
525
|
+
function isVirtualSpecifier(specifier, virtual, matchPaths = false) {
|
|
526
|
+
if (!specifier || !virtual) return false;
|
|
527
|
+
return Object.hasOwn(virtual, specifier) || matchPaths && findVirtualPathKey(virtual, specifier) !== void 0;
|
|
528
|
+
}
|
|
529
|
+
function isVirtualEntry(entry, virtual = registeredVirtualModules()) {
|
|
530
|
+
const registerHooks = process.getBuiltinModule?.("node:module")?.registerHooks;
|
|
531
|
+
return isVirtualSpecifier(entry, virtual, typeof registerHooks === "function");
|
|
160
532
|
}
|
|
161
533
|
async function resolveEntry(entryPath, virtual) {
|
|
162
534
|
const mod = await (virtual ? import(entryPath) : import(_toImportPath(entryPath)));
|
|
@@ -164,6 +536,19 @@ async function resolveEntry(entryPath, virtual) {
|
|
|
164
536
|
if (typeof entry.fetch !== "function") throw new Error(`[env-runner] Entry module "${entryPath}" must export a \`fetch\` handler (export default { fetch(req) { ... } }).`);
|
|
165
537
|
return entry;
|
|
166
538
|
}
|
|
539
|
+
function formatInitError(error) {
|
|
540
|
+
const message = error?.message || String(error);
|
|
541
|
+
if (message.startsWith("[env-runner]") || /:\d+:\d+/.test(message)) return message;
|
|
542
|
+
const location = _errorLocation(error);
|
|
543
|
+
return location ? `${message} (at ${location})` : message;
|
|
544
|
+
}
|
|
545
|
+
function _errorLocation(error) {
|
|
546
|
+
const position = error?.position;
|
|
547
|
+
if (position?.file) return `${position.file}:${position.line}:${position.column}`;
|
|
548
|
+
const stack = typeof error?.stack === "string" ? error.stack : "";
|
|
549
|
+
const location = stack.startsWith(String(error?.name)) ? /\n\s+at (?:async )?(?:.* \()?([^\n()]+:\d+:\d+)\)?/.exec(stack)?.[1] : /^([^\n]+:\d+)\n/.exec(stack)?.[1];
|
|
550
|
+
return location && !/^(?:node|ext|native):/.test(location) ? location : void 0;
|
|
551
|
+
}
|
|
167
552
|
function parseServerAddress(server) {
|
|
168
553
|
const url = new URL(server.url);
|
|
169
554
|
return {
|
|
@@ -184,18 +569,24 @@ function _toImportPath(entryPath) {
|
|
|
184
569
|
if (isAbsolute(filePath)) return pathToFileURL(filePath).href + query;
|
|
185
570
|
return entryPath;
|
|
186
571
|
}
|
|
572
|
+
function _toReloadPath(entryPath) {
|
|
573
|
+
if (!("Bun" in globalThis)) return _toImportPath(entryPath);
|
|
574
|
+
if (!entryPath.startsWith("file:")) return entryPath;
|
|
575
|
+
const qIndex = entryPath.indexOf("?");
|
|
576
|
+
return qIndex === -1 ? fileURLToPath(entryPath) : fileURLToPath(entryPath.slice(0, qIndex)) + entryPath.slice(qIndex);
|
|
577
|
+
}
|
|
187
578
|
let _reloadCounter = 0;
|
|
188
579
|
async function _importFresh(entryPath, virtual) {
|
|
189
580
|
const qIndex = entryPath.indexOf("?");
|
|
190
581
|
const filePath = qIndex === -1 ? entryPath : entryPath.slice(0, qIndex);
|
|
191
582
|
let mod;
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
583
|
+
if (virtual && refreshVirtualModule(filePath)) mod = await import(filePath);
|
|
584
|
+
else {
|
|
585
|
+
const importPath = virtual ? entryPath : _toReloadPath(entryPath);
|
|
586
|
+
mod = await import(importPath + (importPath.includes("?") ? "&" : "?") + "__envRunnerReload=" + _reloadCounter++);
|
|
587
|
+
}
|
|
197
588
|
const entry = mod.default || mod;
|
|
198
589
|
if (typeof entry.fetch !== "function") throw new Error(`[env-runner] Entry module "${entryPath}" must export a \`fetch\` handler (export default { fetch(req) { ... } }).`);
|
|
199
590
|
return entry;
|
|
200
591
|
}
|
|
201
|
-
export { RESERVED_RUNTIME_OPTIONS, RESERVED_SERVER_OPTIONS,
|
|
592
|
+
export { RESERVED_RUNTIME_OPTIONS, RESERVED_SERVER_OPTIONS, formatInitError, handleUpdateVirtualModules, isVirtualEntry, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry, toServerOptions };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { BaseEnvRunner } from "./common-base-runner.mjs";
|
|
2
|
-
import { hostEnv } from "./common-host-env.mjs";
|
|
3
2
|
import { fileURLToPath } from "node:url";
|
|
4
3
|
import { existsSync } from "node:fs";
|
|
5
4
|
import { spawn } from "node:child_process";
|
|
@@ -45,10 +44,7 @@ var DenoProcessEnvRunner = class extends BaseEnvRunner {
|
|
|
45
44
|
...execArgv || [],
|
|
46
45
|
this._workerEntry
|
|
47
46
|
], {
|
|
48
|
-
env:
|
|
49
|
-
ENV_RUNNER_NAME: this._name,
|
|
50
|
-
ENV_RUNNER_DATA: JSON.stringify(this._data || {})
|
|
51
|
-
}),
|
|
47
|
+
env: this._processEnv(),
|
|
52
48
|
stdio: [
|
|
53
49
|
"pipe",
|
|
54
50
|
"pipe",
|
|
@@ -68,7 +64,7 @@ var DenoProcessEnvRunner = class extends BaseEnvRunner {
|
|
|
68
64
|
}
|
|
69
65
|
});
|
|
70
66
|
child.on("message", (message) => {
|
|
71
|
-
this.
|
|
67
|
+
this._handleProcessMessage(message);
|
|
72
68
|
});
|
|
73
69
|
child.stdout?.pipe(process.stdout);
|
|
74
70
|
child.stderr?.pipe(process.stderr);
|
|
@@ -142,4 +142,9 @@ function init() {
|
|
|
142
142
|
A = Q;
|
|
143
143
|
})());
|
|
144
144
|
}
|
|
145
|
-
|
|
145
|
+
function initSync() {
|
|
146
|
+
if (A) return;
|
|
147
|
+
const B = new WebAssembly.Module(w()), { exports: Q } = new WebAssembly.Instance(B);
|
|
148
|
+
A = Q;
|
|
149
|
+
}
|
|
150
|
+
export { init, initSync, parse };
|