env-runner 0.3.0 → 0.3.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.
@@ -1,478 +1,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";
1
+ import { PLUGINS_DATA_KEY, findVirtualPathKey, refreshVirtualModule, registerPluginHooks, registerVirtualModules, registeredVirtualModules, servedByPluginHooks } from "./plugin-hooks.mjs";
2
+ import { createRequire } from "node:module";
3
+ import { isAbsolute } from "node:path";
3
4
  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");
10
- if (typeof registerHooks === "function") {
11
- const isDeno = "Deno" in globalThis;
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
- });
26
- const registration = {
27
- virtual,
28
- versions,
29
- version: 0,
30
- importers,
31
- prepare,
32
- updateKeys,
33
- cache: createRequire(import.meta.url).cache
34
- };
35
- _hooksRegistrations.unshift(registration);
36
- return _once(() => {
37
- const index = _hooksRegistrations.indexOf(registration);
38
- if (index !== -1) _hooksRegistrations.splice(index, 1);
39
- hooks.deregister();
40
- });
41
- }
42
- if (typeof globalThis.Bun?.plugin === "function") {
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);
50
- return _once(() => {
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);
54
- });
55
- }
56
- console.warn("[env-runner] virtual modules require `module.registerHooks` (Node.js >= 22.15 / Deno >= 2.8) or `Bun.plugin`; skipping registration.");
57
- return _noop;
58
- }
59
- function refreshVirtualModule(specifier) {
60
- for (const registration of _bunRegistrations) if (Object.hasOwn(registration.virtual, specifier)) {
61
- _bustBunModules(registration, [specifier]);
62
- return true;
63
- }
64
- return false;
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];
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);
134
- }
135
- const _hooksRegistrations = [];
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;
217
- }
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);
375
- }
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, {
427
- requirement: "(custom load hooks bypass Deno's native type stripping)",
428
- remedy: "upgrade Deno"
429
- });
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
- }
441
- return source;
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
- }
466
- const _noop = () => {};
467
- function _once(fn) {
468
- let done = false;
469
- return () => {
470
- if (!done) {
471
- done = true;
472
- fn();
473
- }
474
- };
475
- }
476
5
  const RESERVED_SERVER_OPTIONS = [
477
6
  "port",
478
7
  "hostname",
@@ -530,6 +59,15 @@ function isVirtualEntry(entry, virtual = registeredVirtualModules()) {
530
59
  const registerHooks = process.getBuiltinModule?.("node:module")?.registerHooks;
531
60
  return isVirtualSpecifier(entry, virtual, typeof registerHooks === "function");
532
61
  }
62
+ async function registerWorkerHooks(data) {
63
+ const unregisterVirtualFirst = "Bun" in globalThis ? await registerVirtualModules(data.virtual) : void 0;
64
+ const unregisterPlugins = await registerPluginHooks(data[PLUGINS_DATA_KEY], data.entry);
65
+ const unregisterVirtual = unregisterVirtualFirst ?? await registerVirtualModules(data.virtual);
66
+ return () => {
67
+ unregisterVirtual();
68
+ unregisterPlugins();
69
+ };
70
+ }
533
71
  async function resolveEntry(entryPath, virtual) {
534
72
  const mod = await (virtual ? import(entryPath) : import(_toImportPath(entryPath)));
535
73
  const entry = mod.default || mod;
@@ -537,7 +75,7 @@ async function resolveEntry(entryPath, virtual) {
537
75
  return entry;
538
76
  }
539
77
  function formatInitError(error) {
540
- const message = error?.message || String(error);
78
+ const message = (error?.message || String(error)).replace(/^(?:Error: )+(?=\[env-runner\])/, "");
541
79
  if (message.startsWith("[env-runner]") || /:\d+:\d+/.test(message)) return message;
542
80
  const location = _errorLocation(error);
543
81
  return location ? `${message} (at ${location})` : message;
@@ -580,7 +118,11 @@ async function _importFresh(entryPath, virtual) {
580
118
  const qIndex = entryPath.indexOf("?");
581
119
  const filePath = qIndex === -1 ? entryPath : entryPath.slice(0, qIndex);
582
120
  let mod;
583
- if (virtual && refreshVirtualModule(filePath)) mod = await import(filePath);
121
+ const bunPath = filePath.startsWith("file:") ? fileURLToPath(filePath) : filePath;
122
+ if (!virtual && "Bun" in globalThis && servedByPluginHooks(bunPath)) {
123
+ delete createRequire(import.meta.url).cache[bunPath];
124
+ mod = await import(bunPath);
125
+ } else if (virtual && refreshVirtualModule(filePath)) mod = await import(filePath);
584
126
  else {
585
127
  const importPath = virtual ? entryPath : _toReloadPath(entryPath);
586
128
  mod = await import(importPath + (importPath.includes("?") ? "&" : "?") + "__envRunnerReload=" + _reloadCounter++);
@@ -589,4 +131,4 @@ async function _importFresh(entryPath, virtual) {
589
131
  if (typeof entry.fetch !== "function") throw new Error(`[env-runner] Entry module "${entryPath}" must export a \`fetch\` handler (export default { fetch(req) { ... } }).`);
590
132
  return entry;
591
133
  }
592
- export { RESERVED_RUNTIME_OPTIONS, RESERVED_SERVER_OPTIONS, formatInitError, handleUpdateVirtualModules, isVirtualEntry, parseServerAddress, registerVirtualModules, reloadEntryModule, resolveEntry, toServerOptions };
134
+ export { RESERVED_RUNTIME_OPTIONS, RESERVED_SERVER_OPTIONS, formatInitError, isVirtualEntry, parseServerAddress, registerWorkerHooks, reloadEntryModule, resolveEntry, toServerOptions };
@@ -1,5 +1,5 @@
1
1
  import { WorkerHooks } from "./types.mjs";
2
- import { BaseEnvRunner, EnvRunnerData } from "./common-base-runner.mjs";
2
+ import { BaseEnvRunner, EnvRunnerData, EnvRunnerPluginOption } from "./common-base-runner.mjs";
3
3
  export declare class DenoProcessEnvRunner extends BaseEnvRunner {
4
4
  #private;
5
5
  constructor(opts: {
@@ -7,10 +7,13 @@ export declare class DenoProcessEnvRunner extends BaseEnvRunner {
7
7
  workerEntry?: string;
8
8
  hooks?: WorkerHooks;
9
9
  data?: EnvRunnerData;
10
+ /** Host-side transform plugins (see `EnvRunnerPluginOption`). */
11
+ plugins?: EnvRunnerPluginOption[];
10
12
  execArgv?: string[];
11
13
  });
12
14
  sendMessage(message: unknown): void;
13
15
  protected _hasRuntime(): boolean;
14
16
  protected _runtimeType(): string;
17
+ protected _resolveConditions(): string[];
15
18
  protected _closeRuntime(): Promise<void>;
16
19
  }
@@ -23,6 +23,13 @@ var DenoProcessEnvRunner = class extends BaseEnvRunner {
23
23
  _runtimeType() {
24
24
  return "process";
25
25
  }
26
+ _resolveConditions() {
27
+ return [
28
+ "deno",
29
+ "node",
30
+ "import"
31
+ ];
32
+ }
26
33
  async _closeRuntime() {
27
34
  if (!this.#process) return;
28
35
  this.#process.removeAllListeners();
@@ -1,8 +1,8 @@
1
1
  import { ResolvedVirtualModule, WorkerHooks } from "./types.mjs";
2
- import { BaseEnvRunner, EnvRunnerData } from "./common-base-runner.mjs";
2
+ import { BaseEnvRunner, EnvRunnerData, EnvRunnerPluginOption } from "./common-base-runner.mjs";
3
3
  import { RuntimeDep } from "./common-runtime-deps.mjs";
4
- import { IncomingMessage } from "node:http";
5
4
  import { Socket } from "node:net";
5
+ import { IncomingMessage } from "node:http";
6
6
  /** The `wrangler` package namespace, as imported by the app. */
7
7
  export interface WranglerModule {
8
8
  unstable_readConfig?: (...args: any[]) => any;
@@ -32,6 +32,8 @@ export interface MiniflareEnvRunnerOptions {
32
32
  name: string;
33
33
  hooks?: WorkerHooks;
34
34
  data?: EnvRunnerData;
35
+ /** Host-side transform plugins (see `EnvRunnerPluginOption`). */
36
+ plugins?: EnvRunnerPluginOption[];
35
37
  /**
36
38
  * The `miniflare` package (`import * as miniflare from "miniflare"`) or a
37
39
  * specifier resolved from cwd. Omitted: imported optionally.
@@ -123,6 +125,7 @@ export declare class MiniflareEnvRunner extends BaseEnvRunner {
123
125
  protected _applyVirtualUpdates(changes: Record<string, ResolvedVirtualModule | null>): Promise<void>;
124
126
  protected _hasRuntime(): boolean;
125
127
  protected _runtimeType(): string;
128
+ protected _resolveConditions(): string[];
126
129
  protected _closeRuntime(): Promise<void>;
127
130
  upgrade(context: {
128
131
  node: {