vite 6.0.0-beta.8 → 6.0.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.

Potentially problematic release.


This version of vite might be problematic. Click here for more details.

@@ -94,7 +94,7 @@ class HMRContext {
94
94
  removeFromMap(this.newListeners);
95
95
  }
96
96
  send(event, data) {
97
- this.hmrClient.messenger.send({ type: "custom", event, data });
97
+ this.hmrClient.send({ type: "custom", event, data });
98
98
  }
99
99
  acceptDeps(deps, callback = () => {
100
100
  }) {
@@ -109,25 +109,10 @@ class HMRContext {
109
109
  this.hmrClient.hotModulesMap.set(this.ownerPath, mod);
110
110
  }
111
111
  }
112
- class HMRMessenger {
113
- constructor(connection) {
114
- this.connection = connection;
115
- this.queue = [];
116
- }
117
- send(payload) {
118
- this.queue.push(payload);
119
- this.flush();
120
- }
121
- flush() {
122
- if (this.connection.isReady()) {
123
- this.queue.forEach((msg) => this.connection.send(msg));
124
- this.queue = [];
125
- }
126
- }
127
- }
128
112
  class HMRClient {
129
- constructor(logger, connection, importUpdatedModule) {
113
+ constructor(logger, transport, importUpdatedModule) {
130
114
  this.logger = logger;
115
+ this.transport = transport;
131
116
  this.importUpdatedModule = importUpdatedModule;
132
117
  this.hotModulesMap = /* @__PURE__ */ new Map();
133
118
  this.disposeMap = /* @__PURE__ */ new Map();
@@ -137,7 +122,6 @@ class HMRClient {
137
122
  this.ctxToListenersMap = /* @__PURE__ */ new Map();
138
123
  this.updateQueue = [];
139
124
  this.pendingUpdateQueue = false;
140
- this.messenger = new HMRMessenger(connection);
141
125
  }
142
126
  async notifyListeners(event, data) {
143
127
  const cbs = this.customListenersMap.get(event);
@@ -145,6 +129,11 @@ class HMRClient {
145
129
  await Promise.allSettled(cbs.map((cb) => cb(data)));
146
130
  }
147
131
  }
132
+ send(payload) {
133
+ this.transport.send(payload).catch((err) => {
134
+ this.logger.error(err);
135
+ });
136
+ }
148
137
  clear() {
149
138
  this.hotModulesMap.clear();
150
139
  this.disposeMap.clear();
@@ -226,6 +215,265 @@ class HMRClient {
226
215
  }
227
216
  }
228
217
 
218
+ let urlAlphabet =
219
+ 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
220
+ let nanoid = (size = 21) => {
221
+ let id = '';
222
+ let i = size;
223
+ while (i--) {
224
+ id += urlAlphabet[(Math.random() * 64) | 0];
225
+ }
226
+ return id
227
+ };
228
+
229
+ typeof process !== "undefined" && process.platform === "win32";
230
+ function promiseWithResolvers() {
231
+ let resolve;
232
+ let reject;
233
+ const promise = new Promise((_resolve, _reject) => {
234
+ resolve = _resolve;
235
+ reject = _reject;
236
+ });
237
+ return { promise, resolve, reject };
238
+ }
239
+
240
+ function reviveInvokeError(e) {
241
+ const error = new Error(e.message || "Unknown invoke error");
242
+ Object.assign(error, e, {
243
+ // pass the whole error instead of just the stacktrace
244
+ // so that it gets formatted nicely with console.log
245
+ runnerError: new Error("RunnerError")
246
+ });
247
+ return error;
248
+ }
249
+ const createInvokeableTransport = (transport) => {
250
+ if (transport.invoke) {
251
+ return {
252
+ ...transport,
253
+ async invoke(name, data) {
254
+ const result = await transport.invoke({
255
+ type: "custom",
256
+ event: "vite:invoke",
257
+ data: {
258
+ id: "send",
259
+ name,
260
+ data
261
+ }
262
+ });
263
+ if ("e" in result) {
264
+ throw reviveInvokeError(result.e);
265
+ }
266
+ return result.r;
267
+ }
268
+ };
269
+ }
270
+ if (!transport.send || !transport.connect) {
271
+ throw new Error(
272
+ "transport must implement send and connect when invoke is not implemented"
273
+ );
274
+ }
275
+ const rpcPromises = /* @__PURE__ */ new Map();
276
+ return {
277
+ ...transport,
278
+ connect({ onMessage, onDisconnection }) {
279
+ return transport.connect({
280
+ onMessage(payload) {
281
+ if (payload.type === "custom" && payload.event === "vite:invoke") {
282
+ const data = payload.data;
283
+ if (data.id.startsWith("response:")) {
284
+ const invokeId = data.id.slice("response:".length);
285
+ const promise = rpcPromises.get(invokeId);
286
+ if (!promise) return;
287
+ if (promise.timeoutId) clearTimeout(promise.timeoutId);
288
+ rpcPromises.delete(invokeId);
289
+ const { e, r } = data.data;
290
+ if (e) {
291
+ promise.reject(e);
292
+ } else {
293
+ promise.resolve(r);
294
+ }
295
+ return;
296
+ }
297
+ }
298
+ onMessage(payload);
299
+ },
300
+ onDisconnection
301
+ });
302
+ },
303
+ disconnect() {
304
+ rpcPromises.forEach((promise) => {
305
+ promise.reject(
306
+ new Error(
307
+ `transport was disconnected, cannot call ${JSON.stringify(promise.name)}`
308
+ )
309
+ );
310
+ });
311
+ rpcPromises.clear();
312
+ return transport.disconnect?.();
313
+ },
314
+ send(data) {
315
+ return transport.send(data);
316
+ },
317
+ async invoke(name, data) {
318
+ const promiseId = nanoid();
319
+ const wrappedData = {
320
+ type: "custom",
321
+ event: "vite:invoke",
322
+ data: {
323
+ name,
324
+ id: `send:${promiseId}`,
325
+ data
326
+ }
327
+ };
328
+ const sendPromise = transport.send(wrappedData);
329
+ const { promise, resolve, reject } = promiseWithResolvers();
330
+ const timeout = transport.timeout ?? 6e4;
331
+ let timeoutId;
332
+ if (timeout > 0) {
333
+ timeoutId = setTimeout(() => {
334
+ rpcPromises.delete(promiseId);
335
+ reject(
336
+ new Error(
337
+ `transport invoke timed out after ${timeout}ms (data: ${JSON.stringify(wrappedData)})`
338
+ )
339
+ );
340
+ }, timeout);
341
+ timeoutId?.unref?.();
342
+ }
343
+ rpcPromises.set(promiseId, { resolve, reject, name, timeoutId });
344
+ if (sendPromise) {
345
+ sendPromise.catch((err) => {
346
+ clearTimeout(timeoutId);
347
+ rpcPromises.delete(promiseId);
348
+ reject(err);
349
+ });
350
+ }
351
+ try {
352
+ return await promise;
353
+ } catch (err) {
354
+ throw reviveInvokeError(err);
355
+ }
356
+ }
357
+ };
358
+ };
359
+ const normalizeModuleRunnerTransport = (transport) => {
360
+ const invokeableTransport = createInvokeableTransport(transport);
361
+ let isConnected = !invokeableTransport.connect;
362
+ let connectingPromise;
363
+ return {
364
+ ...transport,
365
+ ...invokeableTransport.connect ? {
366
+ async connect(onMessage) {
367
+ if (isConnected) return;
368
+ if (connectingPromise) {
369
+ await connectingPromise;
370
+ return;
371
+ }
372
+ const maybePromise = invokeableTransport.connect({
373
+ onMessage: onMessage ?? (() => {
374
+ }),
375
+ onDisconnection() {
376
+ isConnected = false;
377
+ }
378
+ });
379
+ if (maybePromise) {
380
+ connectingPromise = maybePromise;
381
+ await connectingPromise;
382
+ connectingPromise = void 0;
383
+ }
384
+ isConnected = true;
385
+ }
386
+ } : {},
387
+ ...invokeableTransport.disconnect ? {
388
+ async disconnect() {
389
+ if (!isConnected) return;
390
+ if (connectingPromise) {
391
+ await connectingPromise;
392
+ }
393
+ isConnected = false;
394
+ await invokeableTransport.disconnect();
395
+ }
396
+ } : {},
397
+ async send(data) {
398
+ if (!invokeableTransport.send) return;
399
+ if (!isConnected) {
400
+ if (connectingPromise) {
401
+ await connectingPromise;
402
+ } else {
403
+ throw new Error("send was called before connect");
404
+ }
405
+ }
406
+ await invokeableTransport.send(data);
407
+ },
408
+ async invoke(name, data) {
409
+ if (!isConnected) {
410
+ if (connectingPromise) {
411
+ await connectingPromise;
412
+ } else {
413
+ throw new Error("invoke was called before connect");
414
+ }
415
+ }
416
+ return invokeableTransport.invoke(name, data);
417
+ }
418
+ };
419
+ };
420
+ const createWebSocketModuleRunnerTransport = (options) => {
421
+ const pingInterval = options.pingInterval ?? 3e4;
422
+ let ws;
423
+ let pingIntervalId;
424
+ return {
425
+ async connect({ onMessage, onDisconnection }) {
426
+ const socket = options.createConnection();
427
+ socket.addEventListener("message", async ({ data }) => {
428
+ onMessage(JSON.parse(data));
429
+ });
430
+ let isOpened = socket.readyState === socket.OPEN;
431
+ if (!isOpened) {
432
+ await new Promise((resolve, reject) => {
433
+ socket.addEventListener(
434
+ "open",
435
+ () => {
436
+ isOpened = true;
437
+ resolve();
438
+ },
439
+ { once: true }
440
+ );
441
+ socket.addEventListener("close", async () => {
442
+ if (!isOpened) {
443
+ reject(new Error("WebSocket closed without opened."));
444
+ return;
445
+ }
446
+ onMessage({
447
+ type: "custom",
448
+ event: "vite:ws:disconnect",
449
+ data: { webSocket: socket }
450
+ });
451
+ onDisconnection();
452
+ });
453
+ });
454
+ }
455
+ onMessage({
456
+ type: "custom",
457
+ event: "vite:ws:connect",
458
+ data: { webSocket: socket }
459
+ });
460
+ ws = socket;
461
+ pingIntervalId = setInterval(() => {
462
+ if (socket.readyState === socket.OPEN) {
463
+ socket.send(JSON.stringify({ type: "ping" }));
464
+ }
465
+ }, pingInterval);
466
+ },
467
+ disconnect() {
468
+ clearInterval(pingIntervalId);
469
+ ws?.close();
470
+ },
471
+ send(data) {
472
+ ws.send(JSON.stringify(data));
473
+ }
474
+ };
475
+ };
476
+
229
477
  const hmrConfigName = __HMR_CONFIG_NAME__;
230
478
  const base$1 = __BASE__ || "/";
231
479
  function h(e, attrs = {}, ...children) {
@@ -501,65 +749,64 @@ const hmrPort = __HMR_PORT__;
501
749
  const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}`;
502
750
  const directSocketHost = __HMR_DIRECT_TARGET__;
503
751
  const base = __BASE__ || "/";
504
- let socket;
505
- try {
506
- let fallback;
507
- if (!hmrPort) {
508
- fallback = () => {
509
- socket = setupWebSocket(socketProtocol, directSocketHost, () => {
510
- const currentScriptHostURL = new URL(import.meta.url);
511
- const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
512
- console.error(
513
- `[vite] failed to connect to websocket.
752
+ const hmrTimeout = __HMR_TIMEOUT__;
753
+ const transport = normalizeModuleRunnerTransport(
754
+ (() => {
755
+ let wsTransport = createWebSocketModuleRunnerTransport({
756
+ createConnection: () => new WebSocket(`${socketProtocol}://${socketHost}`, "vite-hmr"),
757
+ pingInterval: hmrTimeout
758
+ });
759
+ return {
760
+ async connect(handlers) {
761
+ try {
762
+ await wsTransport.connect(handlers);
763
+ } catch (e) {
764
+ if (!hmrPort) {
765
+ wsTransport = createWebSocketModuleRunnerTransport({
766
+ createConnection: () => new WebSocket(
767
+ `${socketProtocol}://${directSocketHost}`,
768
+ "vite-hmr"
769
+ ),
770
+ pingInterval: hmrTimeout
771
+ });
772
+ try {
773
+ await wsTransport.connect(handlers);
774
+ console.info(
775
+ "[vite] Direct websocket connection fallback. Check out https://vite.dev/config/server-options.html#server-hmr to remove the previous connection error."
776
+ );
777
+ } catch (e2) {
778
+ if (e2 instanceof Error && e2.message.includes("WebSocket closed without opened.")) {
779
+ const currentScriptHostURL = new URL(import.meta.url);
780
+ const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
781
+ console.error(
782
+ `[vite] failed to connect to websocket.
514
783
  your current setup:
515
784
  (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)
516
785
  (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)
517
786
  Check out your Vite / network configuration and https://vite.dev/config/server-options.html#server-hmr .`
518
- );
519
- });
520
- socket.addEventListener(
521
- "open",
522
- () => {
523
- console.info(
524
- "[vite] Direct websocket connection fallback. Check out https://vite.dev/config/server-options.html#server-hmr to remove the previous connection error."
525
- );
526
- },
527
- { once: true }
528
- );
787
+ );
788
+ }
789
+ }
790
+ return;
791
+ }
792
+ console.error(`[vite] failed to connect to websocket (${e}). `);
793
+ throw e;
794
+ }
795
+ },
796
+ async disconnect() {
797
+ await wsTransport.disconnect();
798
+ },
799
+ send(data) {
800
+ wsTransport.send(data);
801
+ }
529
802
  };
530
- }
531
- socket = setupWebSocket(socketProtocol, socketHost, fallback);
532
- } catch (error) {
533
- console.error(`[vite] failed to connect to websocket (${error}). `);
534
- }
535
- function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {
536
- const socket2 = new WebSocket(`${protocol}://${hostAndPath}`, "vite-hmr");
537
- let isOpened = false;
538
- socket2.addEventListener(
539
- "open",
540
- () => {
541
- isOpened = true;
542
- notifyListeners("vite:ws:connect", { webSocket: socket2 });
543
- },
544
- { once: true }
545
- );
546
- socket2.addEventListener("message", async ({ data }) => {
547
- handleMessage(JSON.parse(data));
548
- });
549
- socket2.addEventListener("close", async ({ wasClean }) => {
550
- if (wasClean) return;
551
- if (!isOpened && onCloseWithoutOpen) {
552
- onCloseWithoutOpen();
553
- return;
554
- }
555
- notifyListeners("vite:ws:disconnect", { webSocket: socket2 });
556
- if (hasDocument) {
557
- console.log(`[vite] server connection lost. Polling for restart...`);
558
- await waitForSuccessfulPing(protocol, hostAndPath);
559
- location.reload();
560
- }
803
+ })()
804
+ );
805
+ let willUnload = false;
806
+ if (typeof window !== "undefined") {
807
+ window.addEventListener("beforeunload", () => {
808
+ willUnload = true;
561
809
  });
562
- return socket2;
563
810
  }
564
811
  function cleanUrl(pathname) {
565
812
  const url = new URL(pathname, "http://vite.dev");
@@ -586,10 +833,7 @@ const hmrClient = new HMRClient(
586
833
  error: (err) => console.error("[vite]", err),
587
834
  debug: (...msg) => console.debug("[vite]", ...msg)
588
835
  },
589
- {
590
- isReady: () => socket && socket.readyState === 1,
591
- send: (payload) => socket.send(JSON.stringify(payload))
592
- },
836
+ transport,
593
837
  async function importUpdatedModule({
594
838
  acceptedPath,
595
839
  timestamp,
@@ -612,16 +856,11 @@ const hmrClient = new HMRClient(
612
856
  return await importPromise;
613
857
  }
614
858
  );
859
+ transport.connect(handleMessage);
615
860
  async function handleMessage(payload) {
616
861
  switch (payload.type) {
617
862
  case "connected":
618
863
  console.debug(`[vite] connected.`);
619
- hmrClient.messenger.flush();
620
- setInterval(() => {
621
- if (socket.readyState === socket.OPEN) {
622
- socket.send('{"type":"ping"}');
623
- }
624
- }, __HMR_TIMEOUT__);
625
864
  break;
626
865
  case "update":
627
866
  notifyListeners("vite:beforeUpdate", payload);
@@ -671,6 +910,14 @@ async function handleMessage(payload) {
671
910
  break;
672
911
  case "custom": {
673
912
  notifyListeners(payload.event, payload.data);
913
+ if (payload.event === "vite:ws:disconnect") {
914
+ if (hasDocument && !willUnload) {
915
+ console.log(`[vite] server connection lost. Polling for restart...`);
916
+ const socket = payload.data.webSocket;
917
+ await waitForSuccessfulPing(socket.url);
918
+ location.reload();
919
+ }
920
+ }
674
921
  break;
675
922
  }
676
923
  case "full-reload":
@@ -708,6 +955,8 @@ ${err.stack}`
708
955
  }
709
956
  break;
710
957
  }
958
+ case "ping":
959
+ break;
711
960
  default: {
712
961
  const check = payload;
713
962
  return check;
@@ -721,7 +970,11 @@ const enableOverlay = __HMR_ENABLE_OVERLAY__;
721
970
  const hasDocument = "document" in globalThis;
722
971
  function createErrorOverlay(err) {
723
972
  clearErrorOverlay();
724
- document.body.appendChild(new ErrorOverlay(err));
973
+ const { customElements } = globalThis;
974
+ if (customElements) {
975
+ const ErrorOverlayConstructor = customElements.get(overlayId);
976
+ document.body.appendChild(new ErrorOverlayConstructor(err));
977
+ }
725
978
  }
726
979
  function clearErrorOverlay() {
727
980
  document.querySelectorAll(overlayId).forEach((n) => n.close());
@@ -729,12 +982,9 @@ function clearErrorOverlay() {
729
982
  function hasErrorOverlay() {
730
983
  return document.querySelectorAll(overlayId).length;
731
984
  }
732
- async function waitForSuccessfulPing(socketProtocol2, hostAndPath, ms = 1e3) {
985
+ async function waitForSuccessfulPing(socketUrl, ms = 1e3) {
733
986
  async function ping() {
734
- const socket2 = new WebSocket(
735
- `${socketProtocol2}://${hostAndPath}`,
736
- "vite-ping"
737
- );
987
+ const socket = new WebSocket(socketUrl, "vite-ping");
738
988
  return new Promise((resolve) => {
739
989
  function onOpen() {
740
990
  resolve(true);
@@ -745,12 +995,12 @@ async function waitForSuccessfulPing(socketProtocol2, hostAndPath, ms = 1e3) {
745
995
  close();
746
996
  }
747
997
  function close() {
748
- socket2.removeEventListener("open", onOpen);
749
- socket2.removeEventListener("error", onError);
750
- socket2.close();
998
+ socket.removeEventListener("open", onOpen);
999
+ socket.removeEventListener("error", onError);
1000
+ socket.close();
751
1001
  }
752
- socket2.addEventListener("open", onOpen);
753
- socket2.addEventListener("error", onError);
1002
+ socket.addEventListener("open", onOpen);
1003
+ socket.addEventListener("error", onError);
754
1004
  });
755
1005
  }
756
1006
  if (await ping()) {