vite 6.0.0-beta.1 → 6.0.0-beta.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.
@@ -16,11 +16,24 @@ function cleanUrl(url) {
16
16
  function isPrimitive(value) {
17
17
  return !value || typeof value != "object" && typeof value != "function";
18
18
  }
19
- function withTrailingSlash(path) {
20
- return path[path.length - 1] !== "/" ? `${path}/` : path;
21
- }
22
19
  const AsyncFunction = async function() {
23
- }.constructor, _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
20
+ }.constructor;
21
+ let asyncFunctionDeclarationPaddingLineCount;
22
+ function getAsyncFunctionDeclarationPaddingLineCount() {
23
+ if (typeof asyncFunctionDeclarationPaddingLineCount > "u") {
24
+ const body = "/*code*/", source = new AsyncFunction("a", "b", body).toString();
25
+ asyncFunctionDeclarationPaddingLineCount = source.slice(0, source.indexOf(body)).split(`
26
+ `).length - 1;
27
+ }
28
+ return asyncFunctionDeclarationPaddingLineCount;
29
+ }
30
+ function promiseWithResolvers() {
31
+ let resolve2, reject;
32
+ return { promise: new Promise((_resolve, _reject) => {
33
+ resolve2 = _resolve, reject = _reject;
34
+ }), resolve: resolve2, reject };
35
+ }
36
+ const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
24
37
  function normalizeWindowsPath(input = "") {
25
38
  return input && input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
26
39
  }
@@ -236,94 +249,97 @@ function getOriginalPosition(map, needle) {
236
249
  const MODULE_RUNNER_SOURCEMAPPING_REGEXP = new RegExp(
237
250
  `//# ${SOURCEMAPPING_URL}=data:application/json;base64,(.+)`
238
251
  );
239
- class ModuleCacheMap extends Map {
240
- root;
241
- constructor(root, entries) {
242
- super(entries), this.root = withTrailingSlash(root);
243
- }
244
- normalize(fsPath) {
245
- return normalizeModuleId(fsPath, this.root);
246
- }
252
+ class EvaluatedModuleNode {
253
+ constructor(id, url) {
254
+ this.id = id, this.url = url, this.file = cleanUrl(id);
255
+ }
256
+ importers = /* @__PURE__ */ new Set();
257
+ imports = /* @__PURE__ */ new Set();
258
+ evaluated = !1;
259
+ meta;
260
+ promise;
261
+ exports;
262
+ file;
263
+ map;
264
+ }
265
+ class EvaluatedModules {
266
+ idToModuleMap = /* @__PURE__ */ new Map();
267
+ fileToModulesMap = /* @__PURE__ */ new Map();
268
+ urlToIdModuleMap = /* @__PURE__ */ new Map();
247
269
  /**
248
- * Assign partial data to the map
270
+ * Returns the module node by the resolved module ID. Usually, module ID is
271
+ * the file system path with query and/or hash. It can also be a virtual module.
272
+ *
273
+ * Module runner graph will have 1 to 1 mapping with the server module graph.
274
+ * @param id Resolved module ID
249
275
  */
250
- update(fsPath, mod) {
251
- return fsPath = this.normalize(fsPath), super.has(fsPath) ? Object.assign(super.get(fsPath), mod) : this.setByModuleId(fsPath, mod), this;
252
- }
253
- setByModuleId(modulePath, mod) {
254
- return super.set(modulePath, mod);
255
- }
256
- set(fsPath, mod) {
257
- return this.setByModuleId(this.normalize(fsPath), mod);
258
- }
259
- getByModuleId(modulePath) {
260
- super.has(modulePath) || this.setByModuleId(modulePath, {});
261
- const mod = super.get(modulePath);
262
- return mod.imports || Object.assign(mod, {
263
- imports: /* @__PURE__ */ new Set(),
264
- importers: /* @__PURE__ */ new Set(),
265
- timestamp: 0
266
- }), mod;
267
- }
268
- get(fsPath) {
269
- return this.getByModuleId(this.normalize(fsPath));
270
- }
271
- deleteByModuleId(modulePath) {
272
- return super.delete(modulePath);
273
- }
274
- delete(fsPath) {
275
- return this.deleteByModuleId(this.normalize(fsPath));
276
+ getModuleById(id) {
277
+ return this.idToModuleMap.get(id);
276
278
  }
277
- invalidateUrl(id) {
278
- const module = this.get(id);
279
- this.invalidateModule(module);
280
- }
281
- invalidateModule(module) {
282
- module.evaluated = !1, module.meta = void 0, module.map = void 0, module.promise = void 0, module.exports = void 0, module.imports?.clear();
279
+ /**
280
+ * Returns all modules related to the file system path. Different modules
281
+ * might have different query parameters or hash, so it's possible to have
282
+ * multiple modules for the same file.
283
+ * @param file The file system path of the module
284
+ */
285
+ getModulesByFile(file) {
286
+ return this.fileToModulesMap.get(file);
283
287
  }
284
288
  /**
285
- * Invalidate modules that dependent on the given modules, up to the main entry
289
+ * Returns the module node by the URL that was used in the import statement.
290
+ * Unlike module graph on the server, the URL is not resolved and is used as is.
291
+ * @param url Server URL that was used in the import statement
286
292
  */
287
- invalidateDepTree(ids, invalidated = /* @__PURE__ */ new Set()) {
288
- for (const _id of ids) {
289
- const id = this.normalize(_id);
290
- if (invalidated.has(id)) continue;
291
- invalidated.add(id);
292
- const mod = super.get(id);
293
- mod?.importers && this.invalidateDepTree(mod.importers, invalidated), this.invalidateUrl(id);
294
- }
295
- return invalidated;
293
+ getModuleByUrl(url) {
294
+ return this.urlToIdModuleMap.get(unwrapId(url));
296
295
  }
297
296
  /**
298
- * Invalidate dependency modules of the given modules, down to the bottom-level dependencies
297
+ * Ensure that module is in the graph. If the module is already in the graph,
298
+ * it will return the existing module node. Otherwise, it will create a new
299
+ * module node and add it to the graph.
300
+ * @param id Resolved module ID
301
+ * @param url URL that was used in the import statement
299
302
  */
300
- invalidateSubDepTree(ids, invalidated = /* @__PURE__ */ new Set()) {
301
- for (const _id of ids) {
302
- const id = this.normalize(_id);
303
- if (invalidated.has(id)) continue;
304
- invalidated.add(id);
305
- const subIds = Array.from(super.entries()).filter(([, mod]) => mod.importers?.has(id)).map(([key]) => key);
306
- subIds.length && this.invalidateSubDepTree(subIds, invalidated), super.delete(id);
303
+ ensureModule(id, url) {
304
+ if (id = normalizeModuleId(id), this.idToModuleMap.has(id)) {
305
+ const moduleNode2 = this.idToModuleMap.get(id);
306
+ return this.urlToIdModuleMap.set(url, moduleNode2), moduleNode2;
307
307
  }
308
- return invalidated;
308
+ const moduleNode = new EvaluatedModuleNode(id, url);
309
+ this.idToModuleMap.set(id, moduleNode), this.urlToIdModuleMap.set(url, moduleNode);
310
+ const fileModules = this.fileToModulesMap.get(moduleNode.file) || /* @__PURE__ */ new Set();
311
+ return fileModules.add(moduleNode), this.fileToModulesMap.set(moduleNode.file, fileModules), moduleNode;
309
312
  }
310
- getSourceMap(moduleId) {
311
- const mod = this.get(moduleId);
313
+ invalidateModule(node) {
314
+ node.evaluated = !1, node.meta = void 0, node.map = void 0, node.promise = void 0, node.exports = void 0, node.imports.clear();
315
+ }
316
+ /**
317
+ * Extracts the inlined source map from the module code and returns the decoded
318
+ * source map. If the source map is not inlined, it will return null.
319
+ * @param id Resolved module ID
320
+ */
321
+ getModuleSourceMapById(id) {
322
+ const mod = this.getModuleById(id);
323
+ if (!mod) return null;
312
324
  if (mod.map) return mod.map;
313
325
  if (!mod.meta || !("code" in mod.meta)) return null;
314
326
  const mapString = MODULE_RUNNER_SOURCEMAPPING_REGEXP.exec(
315
327
  mod.meta.code
316
328
  )?.[1];
317
- if (!mapString) return null;
318
- const baseFile = mod.meta.file || moduleId.split("?")[0];
319
- return mod.map = new DecodedMap(JSON.parse(decodeBase64(mapString)), baseFile), mod.map;
329
+ return mapString ? (mod.map = new DecodedMap(JSON.parse(decodeBase64(mapString)), mod.file), mod.map) : null;
330
+ }
331
+ clear() {
332
+ this.idToModuleMap.clear(), this.fileToModulesMap.clear(), this.urlToIdModuleMap.clear();
320
333
  }
321
334
  }
322
- const prefixedBuiltins = /* @__PURE__ */ new Set(["node:test", "node:sqlite"]);
323
- function normalizeModuleId(file, root) {
324
- if (prefixedBuiltins.has(file)) return file;
325
- let unixFile = slash(file).replace(/^\/@fs\//, isWindows ? "" : "/").replace(/^node:/, "").replace(/^\/+/, "/");
326
- return unixFile.startsWith(root) && (unixFile = unixFile.slice(root.length - 1)), unixFile.replace(/^file:\//, "/");
335
+ const prefixedBuiltins = /* @__PURE__ */ new Set([
336
+ "node:sea",
337
+ "node:sqlite",
338
+ "node:test",
339
+ "node:test/reporters"
340
+ ]);
341
+ function normalizeModuleId(file) {
342
+ return prefixedBuiltins.has(file) ? file : slash(file).replace(/^\/@fs\//, isWindows ? "" : "/").replace(/^node:/, "").replace(/^\/+/, "/").replace(/^file:\//, "/");
327
343
  }
328
344
  class HMRContext {
329
345
  constructor(hmrClient, ownerPath) {
@@ -403,9 +419,7 @@ class HMRContext {
403
419
  removeFromMap(this.hmrClient.customListenersMap), removeFromMap(this.newListeners);
404
420
  }
405
421
  send(event, data) {
406
- this.hmrClient.messenger.send(
407
- JSON.stringify({ type: "custom", event, data })
408
- );
422
+ this.hmrClient.send({ type: "custom", event, data });
409
423
  }
410
424
  acceptDeps(deps, callback = () => {
411
425
  }) {
@@ -419,21 +433,9 @@ class HMRContext {
419
433
  }), this.hmrClient.hotModulesMap.set(this.ownerPath, mod);
420
434
  }
421
435
  }
422
- class HMRMessenger {
423
- constructor(connection) {
424
- this.connection = connection;
425
- }
426
- queue = [];
427
- send(message) {
428
- this.queue.push(message), this.flush();
429
- }
430
- flush() {
431
- this.connection.isReady() && (this.queue.forEach((msg) => this.connection.send(msg)), this.queue = []);
432
- }
433
- }
434
436
  class HMRClient {
435
- constructor(logger, connection, importUpdatedModule) {
436
- this.logger = logger, this.importUpdatedModule = importUpdatedModule, this.messenger = new HMRMessenger(connection);
437
+ constructor(logger, transport, importUpdatedModule) {
438
+ this.logger = logger, this.transport = transport, this.importUpdatedModule = importUpdatedModule;
437
439
  }
438
440
  hotModulesMap = /* @__PURE__ */ new Map();
439
441
  disposeMap = /* @__PURE__ */ new Map();
@@ -441,17 +443,19 @@ class HMRClient {
441
443
  dataMap = /* @__PURE__ */ new Map();
442
444
  customListenersMap = /* @__PURE__ */ new Map();
443
445
  ctxToListenersMap = /* @__PURE__ */ new Map();
444
- messenger;
445
446
  async notifyListeners(event, data) {
446
447
  const cbs = this.customListenersMap.get(event);
447
448
  cbs && await Promise.allSettled(cbs.map((cb) => cb(data)));
448
449
  }
450
+ send(payload) {
451
+ this.transport.send(payload);
452
+ }
449
453
  clear() {
450
454
  this.hotModulesMap.clear(), this.disposeMap.clear(), this.pruneMap.clear(), this.dataMap.clear(), this.customListenersMap.clear(), this.ctxToListenersMap.clear();
451
455
  }
452
456
  // After an HMR update, some modules are no longer imported on the page
453
457
  // but they may have left behind side effects that need to be cleaned up
454
- // (.e.g style injections)
458
+ // (e.g. style injections)
455
459
  async prunePaths(paths) {
456
460
  await Promise.all(
457
461
  paths.map((path) => {
@@ -525,7 +529,184 @@ const {${missingBindings.join(", ")}} = pkg;
525
529
  }
526
530
  }
527
531
  }
528
- const ssrModuleExportsKey = "__vite_ssr_exports__", ssrImportKey = "__vite_ssr_import__", ssrDynamicImportKey = "__vite_ssr_dynamic_import__", ssrExportAllKey = "__vite_ssr_exportAll__", ssrImportMetaKey = "__vite_ssr_import_meta__", noop = () => {
532
+ let urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", nanoid = (size = 21) => {
533
+ let id = "", i = size;
534
+ for (; i--; )
535
+ id += urlAlphabet[Math.random() * 64 | 0];
536
+ return id;
537
+ };
538
+ function reviveInvokeError(e) {
539
+ return Object.assign(new Error(e.message || "Unknown invoke error"), e);
540
+ }
541
+ const createInvokeableTransport = (transport) => {
542
+ if (transport.invoke)
543
+ return {
544
+ ...transport,
545
+ async invoke(name, data) {
546
+ const result = await transport.invoke({
547
+ type: "custom",
548
+ event: "vite:invoke",
549
+ data: {
550
+ id: "send",
551
+ name,
552
+ data
553
+ }
554
+ });
555
+ if ("e" in result)
556
+ throw reviveInvokeError(result.e);
557
+ return result.r;
558
+ }
559
+ };
560
+ if (!transport.send || !transport.connect)
561
+ throw new Error(
562
+ "transport must implement send and connect when invoke is not implemented"
563
+ );
564
+ const rpcPromises = /* @__PURE__ */ new Map();
565
+ return {
566
+ ...transport,
567
+ connect({ onMessage, onDisconnection }) {
568
+ return transport.connect({
569
+ onMessage(payload) {
570
+ if (payload.type === "custom" && payload.event === "vite:invoke") {
571
+ const data = payload.data;
572
+ if (data.id.startsWith("response:")) {
573
+ const invokeId = data.id.slice(9), promise = rpcPromises.get(invokeId);
574
+ if (!promise) return;
575
+ promise.timeoutId && clearTimeout(promise.timeoutId), rpcPromises.delete(invokeId);
576
+ const { e, r } = data.data;
577
+ e ? promise.reject(reviveInvokeError(e)) : promise.resolve(r);
578
+ return;
579
+ }
580
+ }
581
+ onMessage(payload);
582
+ },
583
+ onDisconnection
584
+ });
585
+ },
586
+ disconnect() {
587
+ return rpcPromises.forEach((promise) => {
588
+ promise.reject(
589
+ new Error(
590
+ `transport was disconnected, cannot call ${JSON.stringify(promise.name)}`
591
+ )
592
+ );
593
+ }), rpcPromises.clear(), transport.disconnect?.();
594
+ },
595
+ send(data) {
596
+ return transport.send(data);
597
+ },
598
+ async invoke(name, data) {
599
+ const promiseId = nanoid(), wrappedData = {
600
+ type: "custom",
601
+ event: "vite:invoke",
602
+ data: {
603
+ name,
604
+ id: `send:${promiseId}`,
605
+ data
606
+ }
607
+ }, sendPromise = transport.send(wrappedData), { promise, resolve: resolve2, reject } = promiseWithResolvers(), timeout = transport.timeout ?? 6e4;
608
+ let timeoutId;
609
+ return timeout > 0 && (timeoutId = setTimeout(() => {
610
+ rpcPromises.delete(promiseId), reject(
611
+ new Error(
612
+ `transport invoke timed out after ${timeout}ms (data: ${JSON.stringify(wrappedData)})`
613
+ )
614
+ );
615
+ }, timeout), timeoutId?.unref?.()), rpcPromises.set(promiseId, { resolve: resolve2, reject, name, timeoutId }), sendPromise && sendPromise.catch((err) => {
616
+ clearTimeout(timeoutId), rpcPromises.delete(promiseId), reject(err);
617
+ }), await promise;
618
+ }
619
+ };
620
+ }, normalizeModuleRunnerTransport = (transport) => {
621
+ const invokeableTransport = createInvokeableTransport(transport);
622
+ let isConnected = !invokeableTransport.connect, connectingPromise;
623
+ return {
624
+ ...transport,
625
+ ...invokeableTransport.connect ? {
626
+ async connect(onMessage) {
627
+ if (isConnected) return;
628
+ if (connectingPromise) {
629
+ await connectingPromise;
630
+ return;
631
+ }
632
+ const maybePromise = invokeableTransport.connect({
633
+ onMessage: onMessage ?? (() => {
634
+ }),
635
+ onDisconnection() {
636
+ isConnected = !1;
637
+ }
638
+ });
639
+ maybePromise && (connectingPromise = maybePromise, await connectingPromise, connectingPromise = void 0), isConnected = !0;
640
+ }
641
+ } : {},
642
+ ...invokeableTransport.disconnect ? {
643
+ async disconnect() {
644
+ isConnected && (connectingPromise && await connectingPromise, isConnected = !1, await invokeableTransport.disconnect());
645
+ }
646
+ } : {},
647
+ async send(data) {
648
+ if (invokeableTransport.send) {
649
+ if (!isConnected)
650
+ if (connectingPromise)
651
+ await connectingPromise;
652
+ else
653
+ throw new Error("send was called before connect");
654
+ await invokeableTransport.send(data);
655
+ }
656
+ },
657
+ async invoke(name, data) {
658
+ if (!isConnected)
659
+ if (connectingPromise)
660
+ await connectingPromise;
661
+ else
662
+ throw new Error("invoke was called before connect");
663
+ return invokeableTransport.invoke(name, data);
664
+ }
665
+ };
666
+ }, createWebSocketModuleRunnerTransport = (options) => {
667
+ const pingInterval = options.pingInterval ?? 3e4;
668
+ let ws, pingIntervalId;
669
+ return {
670
+ async connect({ onMessage, onDisconnection }) {
671
+ const socket = options.createConnection();
672
+ socket.addEventListener("message", async ({ data }) => {
673
+ onMessage(JSON.parse(data));
674
+ });
675
+ let isOpened = socket.readyState === socket.OPEN;
676
+ isOpened || await new Promise((resolve2, reject) => {
677
+ socket.addEventListener(
678
+ "open",
679
+ () => {
680
+ isOpened = !0, resolve2();
681
+ },
682
+ { once: !0 }
683
+ ), socket.addEventListener("close", async () => {
684
+ if (!isOpened) {
685
+ reject(new Error("WebSocket closed without opened."));
686
+ return;
687
+ }
688
+ onMessage({
689
+ type: "custom",
690
+ event: "vite:ws:disconnect",
691
+ data: { webSocket: socket }
692
+ }), onDisconnection();
693
+ });
694
+ }), onMessage({
695
+ type: "custom",
696
+ event: "vite:ws:connect",
697
+ data: { webSocket: socket }
698
+ }), ws = socket, pingIntervalId = setInterval(() => {
699
+ socket.readyState === socket.OPEN && socket.send(JSON.stringify({ type: "ping" }));
700
+ }, pingInterval);
701
+ },
702
+ disconnect() {
703
+ clearInterval(pingIntervalId), ws?.close();
704
+ },
705
+ send(data) {
706
+ ws.send(JSON.stringify(data));
707
+ }
708
+ };
709
+ }, ssrModuleExportsKey = "__vite_ssr_exports__", ssrImportKey = "__vite_ssr_import__", ssrDynamicImportKey = "__vite_ssr_dynamic_import__", ssrExportAllKey = "__vite_ssr_exportAll__", ssrImportMetaKey = "__vite_ssr_import_meta__", noop = () => {
529
710
  }, silentConsole = {
530
711
  debug: noop,
531
712
  error: noop
@@ -539,10 +720,10 @@ function createHMRHandler(runner) {
539
720
  }
540
721
  async function handleHotPayload(runner, payload) {
541
722
  const hmrClient = runner.hmrClient;
542
- if (!(!hmrClient || runner.isDestroyed()))
723
+ if (!(!hmrClient || runner.isClosed()))
543
724
  switch (payload.type) {
544
725
  case "connected":
545
- hmrClient.logger.debug("connected."), hmrClient.messenger.flush();
726
+ hmrClient.logger.debug("connected.");
546
727
  break;
547
728
  case "update":
548
729
  await hmrClient.notifyListeners("vite:beforeUpdate", payload), await Promise.all(
@@ -558,14 +739,14 @@ async function handleHotPayload(runner, payload) {
558
739
  break;
559
740
  }
560
741
  case "full-reload": {
561
- const { triggeredBy } = payload, clearEntrypoints = triggeredBy ? getModulesEntrypoints(
742
+ const { triggeredBy } = payload, clearEntrypointUrls = triggeredBy ? getModulesEntrypoints(
562
743
  runner,
563
744
  getModulesByFile(runner, slash(triggeredBy))
564
745
  ) : findAllEntrypoints(runner);
565
- if (!clearEntrypoints.size) break;
566
- hmrClient.logger.debug("program reload"), await hmrClient.notifyListeners("vite:beforeFullReload", payload), runner.moduleCache.clear();
567
- for (const id of clearEntrypoints)
568
- await runner.import(id);
746
+ if (!clearEntrypointUrls.size) break;
747
+ hmrClient.logger.debug("program reload"), await hmrClient.notifyListeners("vite:beforeFullReload", payload), runner.evaluatedModules.clear();
748
+ for (const url of clearEntrypointUrls)
749
+ await runner.import(url);
569
750
  break;
570
751
  }
571
752
  case "prune":
@@ -581,6 +762,8 @@ ${err.stack}`
581
762
  );
582
763
  break;
583
764
  }
765
+ case "ping":
766
+ break;
584
767
  default:
585
768
  return payload;
586
769
  }
@@ -607,31 +790,31 @@ class Queue {
607
790
  }
608
791
  }
609
792
  function getModulesByFile(runner, file) {
610
- const modules = [];
611
- for (const [id, mod] of runner.moduleCache.entries())
612
- mod.meta && "file" in mod.meta && mod.meta.file === file && modules.push(id);
613
- return modules;
793
+ const nodes = runner.evaluatedModules.getModulesByFile(file);
794
+ return nodes ? [...nodes].map((node) => node.id) : [];
614
795
  }
615
796
  function getModulesEntrypoints(runner, modules, visited = /* @__PURE__ */ new Set(), entrypoints = /* @__PURE__ */ new Set()) {
616
797
  for (const moduleId of modules) {
617
798
  if (visited.has(moduleId)) continue;
618
799
  visited.add(moduleId);
619
- const module = runner.moduleCache.getByModuleId(moduleId);
620
- if (module.importers && !module.importers.size) {
621
- entrypoints.add(moduleId);
622
- continue;
800
+ const module = runner.evaluatedModules.getModuleById(moduleId);
801
+ if (module) {
802
+ if (module.importers && !module.importers.size) {
803
+ entrypoints.add(module.url);
804
+ continue;
805
+ }
806
+ for (const importer of module.importers || [])
807
+ getModulesEntrypoints(runner, [importer], visited, entrypoints);
623
808
  }
624
- for (const importer of module.importers || [])
625
- getModulesEntrypoints(runner, [importer], visited, entrypoints);
626
809
  }
627
810
  return entrypoints;
628
811
  }
629
812
  function findAllEntrypoints(runner, entrypoints = /* @__PURE__ */ new Set()) {
630
- for (const [id, mod] of runner.moduleCache.entries())
631
- mod.importers && !mod.importers.size && entrypoints.add(id);
813
+ for (const mod of runner.evaluatedModules.idToModuleMap.values())
814
+ mod.importers && !mod.importers.size && entrypoints.add(mod.url);
632
815
  return entrypoints;
633
816
  }
634
- const sourceMapCache = {}, fileContentsCache = {}, moduleGraphs = /* @__PURE__ */ new Set(), retrieveFileHandlers = /* @__PURE__ */ new Set(), retrieveSourceMapHandlers = /* @__PURE__ */ new Set(), createExecHandlers = (handlers) => (...args) => {
817
+ const sourceMapCache = {}, fileContentsCache = {}, evaluatedModulesCache = /* @__PURE__ */ new Set(), retrieveFileHandlers = /* @__PURE__ */ new Set(), retrieveSourceMapHandlers = /* @__PURE__ */ new Set(), createExecHandlers = (handlers) => (...args) => {
635
818
  for (const handler of handlers) {
636
819
  const result = handler(...args);
637
820
  if (result) return result;
@@ -643,10 +826,10 @@ const sourceMapCache = {}, fileContentsCache = {}, moduleGraphs = /* @__PURE__ *
643
826
  let overridden = !1;
644
827
  const originalPrepare = Error.prepareStackTrace;
645
828
  function resetInterceptor(runner, options) {
646
- moduleGraphs.delete(runner.moduleCache), options.retrieveFile && retrieveFileHandlers.delete(options.retrieveFile), options.retrieveSourceMap && retrieveSourceMapHandlers.delete(options.retrieveSourceMap), moduleGraphs.size === 0 && (Error.prepareStackTrace = originalPrepare, overridden = !1);
829
+ evaluatedModulesCache.delete(runner.evaluatedModules), options.retrieveFile && retrieveFileHandlers.delete(options.retrieveFile), options.retrieveSourceMap && retrieveSourceMapHandlers.delete(options.retrieveSourceMap), evaluatedModulesCache.size === 0 && (Error.prepareStackTrace = originalPrepare, overridden = !1);
647
830
  }
648
831
  function interceptStackTrace(runner, options = {}) {
649
- return overridden || (Error.prepareStackTrace = prepareStackTrace, overridden = !0), moduleGraphs.add(runner.moduleCache), options.retrieveFile && retrieveFileHandlers.add(options.retrieveFile), options.retrieveSourceMap && retrieveSourceMapHandlers.add(options.retrieveSourceMap), () => resetInterceptor(runner, options);
832
+ return overridden || (Error.prepareStackTrace = prepareStackTrace, overridden = !0), evaluatedModulesCache.add(runner.evaluatedModules), options.retrieveFile && retrieveFileHandlers.add(options.retrieveFile), options.retrieveSourceMap && retrieveSourceMapHandlers.add(options.retrieveSourceMap), () => resetInterceptor(runner, options);
650
833
  }
651
834
  function supportRelativeURL(file, url) {
652
835
  if (!file) return url;
@@ -656,8 +839,8 @@ function supportRelativeURL(file, url) {
656
839
  return protocol && /^\/\w:/.test(startPath) ? (protocol += "/", protocol + slash(posixResolve(startPath, url))) : protocol + posixResolve(startPath, url);
657
840
  }
658
841
  function getRunnerSourceMap(position) {
659
- for (const moduleCache of moduleGraphs) {
660
- const sourceMap = moduleCache.getSourceMap(position.source);
842
+ for (const moduleGraph of evaluatedModulesCache) {
843
+ const sourceMap = moduleGraph.getModuleSourceMapById(position.source);
661
844
  if (sourceMap)
662
845
  return {
663
846
  url: position.source,
@@ -848,20 +1031,23 @@ class ModuleRunner {
848
1031
  constructor(options, evaluator, debug) {
849
1032
  this.options = options, this.evaluator = evaluator, this.debug = debug;
850
1033
  const root = this.options.root;
851
- this.root = root[root.length - 1] === "/" ? root : `${root}/`, this.moduleCache = options.moduleCache ?? new ModuleCacheMap(options.root), this.transport = options.transport, typeof options.hmr == "object" && (this.hmrClient = new HMRClient(
852
- options.hmr.logger === !1 ? silentConsole : options.hmr.logger || hmrLogger,
853
- options.hmr.connection,
854
- ({ acceptedPath }) => this.import(acceptedPath)
855
- ), options.hmr.connection.onUpdate(createHMRHandler(this))), options.sourcemapInterceptor !== !1 && (this.resetSourceMapSupport = enableSourceMapSupport(this));
1034
+ if (this.root = root[root.length - 1] === "/" ? root : `${root}/`, this.evaluatedModules = options.evaluatedModules ?? new EvaluatedModules(), this.transport = normalizeModuleRunnerTransport(options.transport), options.hmr) {
1035
+ const resolvedHmrLogger = options.hmr === !0 || options.hmr.logger === void 0 ? hmrLogger : options.hmr.logger === !1 ? silentConsole : options.hmr.logger;
1036
+ if (this.hmrClient = new HMRClient(
1037
+ resolvedHmrLogger,
1038
+ this.transport,
1039
+ ({ acceptedPath }) => this.import(acceptedPath)
1040
+ ), !this.transport.connect)
1041
+ throw new Error(
1042
+ "HMR is not supported by this runner transport, but `hmr` option was set to true"
1043
+ );
1044
+ this.transport.connect(createHMRHandler(this));
1045
+ } else
1046
+ this.transport.connect?.();
1047
+ options.sourcemapInterceptor !== !1 && (this.resetSourceMapSupport = enableSourceMapSupport(this));
856
1048
  }
857
- /**
858
- * Holds the cache of modules
859
- * Keys of the map are ids
860
- */
861
- moduleCache;
1049
+ evaluatedModules;
862
1050
  hmrClient;
863
- urlToIdMap = /* @__PURE__ */ new Map();
864
- fileToIdMap = /* @__PURE__ */ new Map();
865
1051
  envProxy = new Proxy({}, {
866
1052
  get(_, p) {
867
1053
  throw new Error(
@@ -872,8 +1058,8 @@ class ModuleRunner {
872
1058
  transport;
873
1059
  resetSourceMapSupport;
874
1060
  root;
875
- moduleInfoCache = /* @__PURE__ */ new Map();
876
- destroyed = !1;
1061
+ concurrentModuleNodePromises = /* @__PURE__ */ new Map();
1062
+ closed = !1;
877
1063
  /**
878
1064
  * URL to execute. Accepts file path, server path or id relative to the root.
879
1065
  */
@@ -885,26 +1071,26 @@ class ModuleRunner {
885
1071
  * Clear all caches including HMR listeners.
886
1072
  */
887
1073
  clearCache() {
888
- this.moduleCache.clear(), this.urlToIdMap.clear(), this.hmrClient?.clear();
1074
+ this.evaluatedModules.clear(), this.hmrClient?.clear();
889
1075
  }
890
1076
  /**
891
1077
  * Clears all caches, removes all HMR listeners, and resets source map support.
892
1078
  * This method doesn't stop the HMR connection.
893
1079
  */
894
- async destroy() {
895
- this.resetSourceMapSupport?.(), this.clearCache(), this.hmrClient = void 0, this.destroyed = !0;
1080
+ async close() {
1081
+ this.resetSourceMapSupport?.(), this.clearCache(), this.hmrClient = void 0, this.closed = !0, await this.transport.disconnect?.();
896
1082
  }
897
1083
  /**
898
- * Returns `true` if the runtime has been destroyed by calling `destroy()` method.
1084
+ * Returns `true` if the runtime has been closed by calling `close()` method.
899
1085
  */
900
- isDestroyed() {
901
- return this.destroyed;
1086
+ isClosed() {
1087
+ return this.closed;
902
1088
  }
903
1089
  processImport(exports, fetchResult, metadata) {
904
1090
  if (!("externalize" in fetchResult))
905
1091
  return exports;
906
- const { url: id, type } = fetchResult;
907
- return type !== "module" && type !== "commonjs" || analyzeImportedModDifference(exports, id, type, metadata), exports;
1092
+ const { url, type } = fetchResult;
1093
+ return type !== "module" && type !== "commonjs" || analyzeImportedModDifference(exports, url, type, metadata), exports;
908
1094
  }
909
1095
  isCircularModule(mod) {
910
1096
  for (const importedFile of mod.imports)
@@ -918,32 +1104,30 @@ class ModuleRunner {
918
1104
  continue;
919
1105
  if (visited.add(importer), importer === moduleUrl)
920
1106
  return !0;
921
- const mod = this.moduleCache.getByModuleId(
922
- importer
923
- );
924
- if (mod.importers.size && this.isCircularImport(mod.importers, moduleUrl, visited))
1107
+ const mod = this.evaluatedModules.getModuleById(importer);
1108
+ if (mod && mod.importers.size && this.isCircularImport(mod.importers, moduleUrl, visited))
925
1109
  return !0;
926
1110
  }
927
1111
  return !1;
928
1112
  }
929
- async cachedRequest(id, mod_, callstack = [], metadata) {
930
- const mod = mod_, meta = mod.meta, moduleUrl = meta.url, { importers } = mod, importee = callstack[callstack.length - 1];
931
- if (importee && importers.add(importee), (callstack.includes(moduleUrl) || this.isCircularModule(mod) || this.isCircularImport(importers, moduleUrl)) && mod.exports)
1113
+ async cachedRequest(url, mod, callstack = [], metadata) {
1114
+ const meta = mod.meta, moduleId = meta.id, { importers } = mod, importee = callstack[callstack.length - 1];
1115
+ if (importee && importers.add(importee), (callstack.includes(moduleId) || this.isCircularModule(mod) || this.isCircularImport(importers, moduleId)) && mod.exports)
932
1116
  return this.processImport(mod.exports, meta, metadata);
933
1117
  let debugTimer;
934
1118
  this.debug && (debugTimer = setTimeout(() => {
935
1119
  const getStack = () => `stack:
936
- ${[...callstack, moduleUrl].reverse().map((p) => ` - ${p}`).join(`
1120
+ ${[...callstack, moduleId].reverse().map((p) => ` - ${p}`).join(`
937
1121
  `)}`;
938
1122
  this.debug(
939
- `[module runner] module ${moduleUrl} takes over 2s to load.
1123
+ `[module runner] module ${moduleId} takes over 2s to load.
940
1124
  ${getStack()}`
941
1125
  );
942
1126
  }, 2e3));
943
1127
  try {
944
1128
  if (mod.promise)
945
1129
  return this.processImport(await mod.promise, meta, metadata);
946
- const promise = this.directRequest(id, mod, callstack);
1130
+ const promise = this.directRequest(url, mod, callstack);
947
1131
  return mod.promise = promise, mod.evaluated = !1, this.processImport(await promise, meta, metadata);
948
1132
  } finally {
949
1133
  mod.evaluated = !0, debugTimer && clearTimeout(debugTimer);
@@ -951,25 +1135,33 @@ ${getStack()}`
951
1135
  }
952
1136
  async cachedModule(url, importer) {
953
1137
  url = normalizeAbsoluteUrl(url, this.root);
954
- const normalized = this.urlToIdMap.get(url);
955
- let cachedModule = normalized && this.moduleCache.getByModuleId(normalized);
956
- cachedModule || (cachedModule = this.moduleCache.getByModuleId(url));
957
- let cached = this.moduleInfoCache.get(url);
958
- return cached ? this.debug?.("[module runner] using cached module info for", url) : (cached = this.getModuleInformation(url, importer, cachedModule).finally(
959
- () => {
960
- this.moduleInfoCache.delete(url);
961
- }
962
- ), this.moduleInfoCache.set(url, cached)), cached;
1138
+ let cached = this.concurrentModuleNodePromises.get(url);
1139
+ if (cached)
1140
+ this.debug?.("[module runner] using cached module info for", url);
1141
+ else {
1142
+ const cachedModule = this.evaluatedModules.getModuleByUrl(url);
1143
+ cached = this.getModuleInformation(url, importer, cachedModule).finally(
1144
+ () => {
1145
+ this.concurrentModuleNodePromises.delete(url);
1146
+ }
1147
+ ), this.concurrentModuleNodePromises.set(url, cached);
1148
+ }
1149
+ return cached;
963
1150
  }
964
1151
  async getModuleInformation(url, importer, cachedModule) {
965
- if (this.destroyed)
966
- throw new Error("Vite module runner has been destroyed.");
1152
+ if (this.closed)
1153
+ throw new Error("Vite module runner has been closed.");
967
1154
  this.debug?.("[module runner] fetching", url);
968
1155
  const isCached = !!(typeof cachedModule == "object" && cachedModule.meta), fetchedModule = (
969
1156
  // fast return for established externalized pattern
970
- url.startsWith("data:") ? { externalize: url, type: "builtin" } : await this.transport.fetchModule(url, importer, {
971
- cached: isCached
972
- })
1157
+ url.startsWith("data:") ? { externalize: url, type: "builtin" } : await this.transport.invoke("fetchModule", [
1158
+ url,
1159
+ importer,
1160
+ {
1161
+ cached: isCached,
1162
+ startOffset: this.evaluator.startOffset
1163
+ }
1164
+ ])
973
1165
  );
974
1166
  if ("cache" in fetchedModule) {
975
1167
  if (!cachedModule || !cachedModule.meta)
@@ -978,19 +1170,15 @@ ${getStack()}`
978
1170
  );
979
1171
  return cachedModule;
980
1172
  }
981
- const idQuery = url.split("?")[1], query = idQuery ? `?${idQuery}` : "", file = "file" in fetchedModule ? fetchedModule.file : void 0, fileId = file ? `${file}${query}` : url, moduleUrl = this.moduleCache.normalize(fileId), mod = this.moduleCache.getByModuleId(moduleUrl);
982
- if ("invalidate" in fetchedModule && fetchedModule.invalidate && this.moduleCache.invalidateModule(mod), fetchedModule.url = moduleUrl, mod.meta = fetchedModule, file) {
983
- const fileModules = this.fileToIdMap.get(file) || [];
984
- fileModules.push(moduleUrl), this.fileToIdMap.set(file, fileModules);
985
- }
986
- return this.urlToIdMap.set(url, moduleUrl), this.urlToIdMap.set(unwrapId(url), moduleUrl), mod;
1173
+ const moduleId = "externalize" in fetchedModule ? fetchedModule.externalize : fetchedModule.id, moduleUrl = "url" in fetchedModule ? fetchedModule.url : url, module = this.evaluatedModules.ensureModule(moduleId, moduleUrl);
1174
+ return "invalidate" in fetchedModule && fetchedModule.invalidate && this.evaluatedModules.invalidateModule(module), fetchedModule.url = moduleUrl, fetchedModule.id = moduleId, module.meta = fetchedModule, module;
987
1175
  }
988
1176
  // override is allowed, consider this a public API
989
- async directRequest(id, mod, _callstack) {
990
- const fetchResult = mod.meta, moduleUrl = fetchResult.url, callstack = [..._callstack, moduleUrl], request = async (dep, metadata) => {
991
- const importer = "file" in fetchResult && fetchResult.file || moduleUrl, fetchedModule = await this.cachedModule(dep, importer), resolvedId = fetchedModule.meta.url;
992
- return this.moduleCache.getByModuleId(resolvedId).importers.add(moduleUrl), mod.imports.add(resolvedId), this.cachedRequest(dep, fetchedModule, callstack, metadata);
993
- }, dynamicRequest = async (dep) => (dep = String(dep), dep[0] === "." && (dep = posixResolve(posixDirname(id), dep)), request(dep, { isDynamicImport: !0 }));
1177
+ async directRequest(url, mod, _callstack) {
1178
+ const fetchResult = mod.meta, moduleId = fetchResult.id, callstack = [..._callstack, moduleId], request = async (dep, metadata) => {
1179
+ const importer = "file" in fetchResult && fetchResult.file || moduleId, depMod = await this.cachedModule(dep, importer);
1180
+ return depMod.importers.add(moduleId), mod.imports.add(depMod.id), this.cachedRequest(dep, depMod, callstack, metadata);
1181
+ }, dynamicRequest = async (dep) => (dep = String(dep), dep[0] === "." && (dep = posixResolve(posixDirname(url), dep)), request(dep, { isDynamicImport: !0 }));
994
1182
  if ("externalize" in fetchResult) {
995
1183
  const { externalize } = fetchResult;
996
1184
  this.debug?.("[module runner] externalizing", externalize);
@@ -1001,10 +1189,10 @@ ${getStack()}`
1001
1189
  if (code == null) {
1002
1190
  const importer = callstack[callstack.length - 2];
1003
1191
  throw new Error(
1004
- `[module runner] Failed to load "${id}"${importer ? ` imported from ${importer}` : ""}`
1192
+ `[module runner] Failed to load "${url}"${importer ? ` imported from ${importer}` : ""}`
1005
1193
  );
1006
1194
  }
1007
- const modulePath = cleanUrl(file || moduleUrl), href = posixPathToFileHref(modulePath), filename = modulePath, dirname2 = posixDirname(modulePath), meta = {
1195
+ const modulePath = cleanUrl(file || moduleId), href = posixPathToFileHref(modulePath), filename = modulePath, dirname2 = posixDirname(modulePath), meta = {
1008
1196
  filename: isWindows ? toWindowsPath(filename) : filename,
1009
1197
  dirname: isWindows ? toWindowsPath(dirname2) : dirname2,
1010
1198
  url: href,
@@ -1016,7 +1204,9 @@ ${getStack()}`
1016
1204
  },
1017
1205
  // should be replaced during transformation
1018
1206
  glob() {
1019
- throw new Error('[module runner] "import.meta.glob" is not supported.');
1207
+ throw new Error(
1208
+ '[module runner] "import.meta.glob" is statically replaced during file transformation. Make sure to reference it by the full name.'
1209
+ );
1020
1210
  }
1021
1211
  }, exports = /* @__PURE__ */ Object.create(null);
1022
1212
  Object.defineProperty(exports, Symbol.toStringTag, {
@@ -1029,8 +1219,8 @@ ${getStack()}`
1029
1219
  enumerable: !0,
1030
1220
  get: () => {
1031
1221
  if (!this.hmrClient)
1032
- throw new Error("[module runner] HMR client was destroyed.");
1033
- return this.debug?.("[module runner] creating hmr context for", moduleUrl), hotContext ||= new HMRContext(this.hmrClient, moduleUrl), hotContext;
1222
+ throw new Error("[module runner] HMR client was closed.");
1223
+ return this.debug?.("[module runner] creating hmr context for", mod.url), hotContext ||= new HMRContext(this.hmrClient, mod.url), hotContext;
1034
1224
  },
1035
1225
  set: (value) => {
1036
1226
  hotContext = value;
@@ -1043,7 +1233,7 @@ ${getStack()}`
1043
1233
  [ssrExportAllKey]: (obj) => exportAll(exports, obj),
1044
1234
  [ssrImportMetaKey]: meta
1045
1235
  };
1046
- return this.debug?.("[module runner] executing", href), await this.evaluator.runInlinedModule(context, code, id), exports;
1236
+ return this.debug?.("[module runner] executing", href), await this.evaluator.runInlinedModule(context, code, mod), exports;
1047
1237
  }
1048
1238
  }
1049
1239
  function exportAll(exports, sourceModule) {
@@ -1061,6 +1251,7 @@ function exportAll(exports, sourceModule) {
1061
1251
  }
1062
1252
  }
1063
1253
  class ESModulesEvaluator {
1254
+ startOffset = getAsyncFunctionDeclarationPaddingLineCount();
1064
1255
  async runInlinedModule(context, code) {
1065
1256
  await new AsyncFunction(
1066
1257
  ssrModuleExportsKey,
@@ -1082,49 +1273,11 @@ class ESModulesEvaluator {
1082
1273
  return import(filepath);
1083
1274
  }
1084
1275
  }
1085
- let urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict", nanoid = (size = 21) => {
1086
- let id = "", i = size;
1087
- for (; i--; )
1088
- id += urlAlphabet[Math.random() * 64 | 0];
1089
- return id;
1090
- };
1091
- class RemoteRunnerTransport {
1092
- constructor(options) {
1093
- this.options = options, this.options.onMessage(async (data) => {
1094
- if (typeof data != "object" || !data || !data.__v) return;
1095
- const promise = this.rpcPromises.get(data.i);
1096
- promise && (promise.timeoutId && clearTimeout(promise.timeoutId), this.rpcPromises.delete(data.i), data.e ? promise.reject(data.e) : promise.resolve(data.r));
1097
- });
1098
- }
1099
- rpcPromises = /* @__PURE__ */ new Map();
1100
- resolve(method, ...args) {
1101
- const promiseId = nanoid();
1102
- return this.options.send({
1103
- __v: !0,
1104
- m: method,
1105
- a: args,
1106
- i: promiseId
1107
- }), new Promise((resolve2, reject) => {
1108
- const timeout = this.options.timeout ?? 6e4;
1109
- let timeoutId;
1110
- timeout > 0 && (timeoutId = setTimeout(() => {
1111
- this.rpcPromises.delete(promiseId), reject(
1112
- new Error(
1113
- `${method}(${args.map((arg) => JSON.stringify(arg)).join(", ")}) timed out after ${timeout}ms`
1114
- )
1115
- );
1116
- }, timeout), timeoutId?.unref?.()), this.rpcPromises.set(promiseId, { resolve: resolve2, reject, timeoutId });
1117
- });
1118
- }
1119
- fetchModule(id, importer) {
1120
- return this.resolve("fetchModule", id, importer);
1121
- }
1122
- }
1123
1276
  export {
1124
1277
  ESModulesEvaluator,
1125
- ModuleCacheMap,
1278
+ EvaluatedModules,
1126
1279
  ModuleRunner,
1127
- RemoteRunnerTransport,
1280
+ createWebSocketModuleRunnerTransport,
1128
1281
  ssrDynamicImportKey,
1129
1282
  ssrExportAllKey,
1130
1283
  ssrImportKey,