vite 6.0.0-beta.7 → 6.0.0-beta.9

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/client.d.ts CHANGED
@@ -247,6 +247,16 @@ declare module '*?inline' {
247
247
  export default src
248
248
  }
249
249
 
250
+ declare module '*?no-inline' {
251
+ const src: string
252
+ export default src
253
+ }
254
+
255
+ declare module '*?url&inline' {
256
+ const src: string
257
+ export default src
258
+ }
259
+
250
260
  declare interface VitePreloadErrorEvent extends Event {
251
261
  payload: Error
252
262
  }
@@ -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,9 @@ class HMRClient {
145
129
  await Promise.allSettled(cbs.map((cb) => cb(data)));
146
130
  }
147
131
  }
132
+ send(payload) {
133
+ this.transport.send(payload);
134
+ }
148
135
  clear() {
149
136
  this.hotModulesMap.clear();
150
137
  this.disposeMap.clear();
@@ -226,6 +213,252 @@ class HMRClient {
226
213
  }
227
214
  }
228
215
 
216
+ let urlAlphabet =
217
+ 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
218
+ let nanoid = (size = 21) => {
219
+ let id = '';
220
+ let i = size;
221
+ while (i--) {
222
+ id += urlAlphabet[(Math.random() * 64) | 0];
223
+ }
224
+ return id
225
+ };
226
+
227
+ typeof process !== "undefined" && process.platform === "win32";
228
+ function promiseWithResolvers() {
229
+ let resolve;
230
+ let reject;
231
+ const promise = new Promise((_resolve, _reject) => {
232
+ resolve = _resolve;
233
+ reject = _reject;
234
+ });
235
+ return { promise, resolve, reject };
236
+ }
237
+
238
+ const createInvokeableTransport = (transport) => {
239
+ if (transport.invoke) {
240
+ return {
241
+ ...transport,
242
+ async invoke(name, data) {
243
+ const result = await transport.invoke({
244
+ type: "custom",
245
+ event: "vite:invoke",
246
+ data: {
247
+ id: "send",
248
+ name,
249
+ data
250
+ }
251
+ });
252
+ if ("e" in result) {
253
+ throw result.e;
254
+ }
255
+ return result.r;
256
+ }
257
+ };
258
+ }
259
+ if (!transport.send || !transport.connect) {
260
+ throw new Error(
261
+ "transport must implement send and connect when invoke is not implemented"
262
+ );
263
+ }
264
+ const rpcPromises = /* @__PURE__ */ new Map();
265
+ return {
266
+ ...transport,
267
+ connect({ onMessage, onDisconnection }) {
268
+ return transport.connect({
269
+ onMessage(payload) {
270
+ if (payload.type === "custom" && payload.event === "vite:invoke") {
271
+ const data = payload.data;
272
+ if (data.id.startsWith("response:")) {
273
+ const invokeId = data.id.slice("response:".length);
274
+ const promise = rpcPromises.get(invokeId);
275
+ if (!promise) return;
276
+ if (promise.timeoutId) clearTimeout(promise.timeoutId);
277
+ rpcPromises.delete(invokeId);
278
+ const { e, r } = data.data;
279
+ if (e) {
280
+ promise.reject(e);
281
+ } else {
282
+ promise.resolve(r);
283
+ }
284
+ return;
285
+ }
286
+ }
287
+ onMessage(payload);
288
+ },
289
+ onDisconnection
290
+ });
291
+ },
292
+ disconnect() {
293
+ rpcPromises.forEach((promise) => {
294
+ promise.reject(
295
+ new Error(
296
+ `transport was disconnected, cannot call ${JSON.stringify(promise.name)}`
297
+ )
298
+ );
299
+ });
300
+ rpcPromises.clear();
301
+ return transport.disconnect?.();
302
+ },
303
+ send(data) {
304
+ return transport.send(data);
305
+ },
306
+ async invoke(name, data) {
307
+ const promiseId = nanoid();
308
+ const wrappedData = {
309
+ type: "custom",
310
+ event: "vite:invoke",
311
+ data: {
312
+ name,
313
+ id: `send:${promiseId}`,
314
+ data
315
+ }
316
+ };
317
+ const sendPromise = transport.send(wrappedData);
318
+ const { promise, resolve, reject } = promiseWithResolvers();
319
+ const timeout = transport.timeout ?? 6e4;
320
+ let timeoutId;
321
+ if (timeout > 0) {
322
+ timeoutId = setTimeout(() => {
323
+ rpcPromises.delete(promiseId);
324
+ reject(
325
+ new Error(
326
+ `transport invoke timed out after ${timeout}ms (data: ${JSON.stringify(wrappedData)})`
327
+ )
328
+ );
329
+ }, timeout);
330
+ timeoutId?.unref?.();
331
+ }
332
+ rpcPromises.set(promiseId, { resolve, reject, name, timeoutId });
333
+ if (sendPromise) {
334
+ sendPromise.catch((err) => {
335
+ clearTimeout(timeoutId);
336
+ rpcPromises.delete(promiseId);
337
+ reject(err);
338
+ });
339
+ }
340
+ return await promise;
341
+ }
342
+ };
343
+ };
344
+ const normalizeModuleRunnerTransport = (transport) => {
345
+ const invokeableTransport = createInvokeableTransport(transport);
346
+ let isConnected = !invokeableTransport.connect;
347
+ let connectingPromise;
348
+ return {
349
+ ...transport,
350
+ ...invokeableTransport.connect ? {
351
+ async connect(onMessage) {
352
+ if (isConnected) return;
353
+ if (connectingPromise) {
354
+ await connectingPromise;
355
+ return;
356
+ }
357
+ const maybePromise = invokeableTransport.connect({
358
+ onMessage: onMessage ?? (() => {
359
+ }),
360
+ onDisconnection() {
361
+ isConnected = false;
362
+ }
363
+ });
364
+ if (maybePromise) {
365
+ connectingPromise = maybePromise;
366
+ await connectingPromise;
367
+ connectingPromise = void 0;
368
+ }
369
+ isConnected = true;
370
+ }
371
+ } : {},
372
+ ...invokeableTransport.disconnect ? {
373
+ async disconnect() {
374
+ if (!isConnected) return;
375
+ if (connectingPromise) {
376
+ await connectingPromise;
377
+ }
378
+ isConnected = false;
379
+ await invokeableTransport.disconnect();
380
+ }
381
+ } : {},
382
+ async send(data) {
383
+ if (!invokeableTransport.send) return;
384
+ if (!isConnected) {
385
+ if (connectingPromise) {
386
+ await connectingPromise;
387
+ } else {
388
+ throw new Error("send was called before connect");
389
+ }
390
+ }
391
+ await invokeableTransport.send(data);
392
+ },
393
+ async invoke(name, data) {
394
+ if (!isConnected) {
395
+ if (connectingPromise) {
396
+ await connectingPromise;
397
+ } else {
398
+ throw new Error("invoke was called before connect");
399
+ }
400
+ }
401
+ return invokeableTransport.invoke(name, data);
402
+ }
403
+ };
404
+ };
405
+ const createWebSocketModuleRunnerTransport = (options) => {
406
+ const pingInterval = options.pingInterval ?? 3e4;
407
+ let ws;
408
+ let pingIntervalId;
409
+ return {
410
+ async connect({ onMessage, onDisconnection }) {
411
+ const socket = options.createConnection();
412
+ socket.addEventListener("message", async ({ data }) => {
413
+ onMessage(JSON.parse(data));
414
+ });
415
+ let isOpened = socket.readyState === socket.OPEN;
416
+ if (!isOpened) {
417
+ await new Promise((resolve, reject) => {
418
+ socket.addEventListener(
419
+ "open",
420
+ () => {
421
+ isOpened = true;
422
+ resolve();
423
+ },
424
+ { once: true }
425
+ );
426
+ socket.addEventListener("close", async () => {
427
+ if (!isOpened) {
428
+ reject(new Error("WebSocket closed without opened."));
429
+ return;
430
+ }
431
+ onMessage({
432
+ type: "custom",
433
+ event: "vite:ws:disconnect",
434
+ data: { webSocket: socket }
435
+ });
436
+ onDisconnection();
437
+ });
438
+ });
439
+ }
440
+ onMessage({
441
+ type: "custom",
442
+ event: "vite:ws:connect",
443
+ data: { webSocket: socket }
444
+ });
445
+ ws = socket;
446
+ pingIntervalId = setInterval(() => {
447
+ if (socket.readyState === socket.OPEN) {
448
+ socket.send(JSON.stringify({ type: "ping" }));
449
+ }
450
+ }, pingInterval);
451
+ },
452
+ disconnect() {
453
+ clearInterval(pingIntervalId);
454
+ ws?.close();
455
+ },
456
+ send(data) {
457
+ ws.send(JSON.stringify(data));
458
+ }
459
+ };
460
+ };
461
+
229
462
  const hmrConfigName = __HMR_CONFIG_NAME__;
230
463
  const base$1 = __BASE__ || "/";
231
464
  function h(e, attrs = {}, ...children) {
@@ -501,65 +734,64 @@ const hmrPort = __HMR_PORT__;
501
734
  const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}`;
502
735
  const directSocketHost = __HMR_DIRECT_TARGET__;
503
736
  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.
737
+ const hmrTimeout = __HMR_TIMEOUT__;
738
+ const transport = normalizeModuleRunnerTransport(
739
+ (() => {
740
+ let wsTransport = createWebSocketModuleRunnerTransport({
741
+ createConnection: () => new WebSocket(`${socketProtocol}://${socketHost}`, "vite-hmr"),
742
+ pingInterval: hmrTimeout
743
+ });
744
+ return {
745
+ async connect(handlers) {
746
+ try {
747
+ await wsTransport.connect(handlers);
748
+ } catch (e) {
749
+ if (!hmrPort) {
750
+ wsTransport = createWebSocketModuleRunnerTransport({
751
+ createConnection: () => new WebSocket(
752
+ `${socketProtocol}://${directSocketHost}`,
753
+ "vite-hmr"
754
+ ),
755
+ pingInterval: hmrTimeout
756
+ });
757
+ try {
758
+ await wsTransport.connect(handlers);
759
+ console.info(
760
+ "[vite] Direct websocket connection fallback. Check out https://vite.dev/config/server-options.html#server-hmr to remove the previous connection error."
761
+ );
762
+ } catch (e2) {
763
+ if (e2 instanceof Error && e2.message.includes("WebSocket closed without opened.")) {
764
+ const currentScriptHostURL = new URL(import.meta.url);
765
+ const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
766
+ console.error(
767
+ `[vite] failed to connect to websocket.
514
768
  your current setup:
515
769
  (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)
516
770
  (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)
517
771
  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
- );
772
+ );
773
+ }
774
+ }
775
+ return;
776
+ }
777
+ console.error(`[vite] failed to connect to websocket (${e}). `);
778
+ throw e;
779
+ }
780
+ },
781
+ async disconnect() {
782
+ await wsTransport.disconnect();
783
+ },
784
+ send(data) {
785
+ wsTransport.send(data);
786
+ }
529
787
  };
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
- }
788
+ })()
789
+ );
790
+ let willUnload = false;
791
+ if (typeof window !== "undefined") {
792
+ window.addEventListener("beforeunload", () => {
793
+ willUnload = true;
561
794
  });
562
- return socket2;
563
795
  }
564
796
  function cleanUrl(pathname) {
565
797
  const url = new URL(pathname, "http://vite.dev");
@@ -586,10 +818,7 @@ const hmrClient = new HMRClient(
586
818
  error: (err) => console.error("[vite]", err),
587
819
  debug: (...msg) => console.debug("[vite]", ...msg)
588
820
  },
589
- {
590
- isReady: () => socket && socket.readyState === 1,
591
- send: (payload) => socket.send(JSON.stringify(payload))
592
- },
821
+ transport,
593
822
  async function importUpdatedModule({
594
823
  acceptedPath,
595
824
  timestamp,
@@ -612,16 +841,11 @@ const hmrClient = new HMRClient(
612
841
  return await importPromise;
613
842
  }
614
843
  );
844
+ transport.connect(handleMessage);
615
845
  async function handleMessage(payload) {
616
846
  switch (payload.type) {
617
847
  case "connected":
618
848
  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
849
  break;
626
850
  case "update":
627
851
  notifyListeners("vite:beforeUpdate", payload);
@@ -671,6 +895,14 @@ async function handleMessage(payload) {
671
895
  break;
672
896
  case "custom": {
673
897
  notifyListeners(payload.event, payload.data);
898
+ if (payload.event === "vite:ws:disconnect") {
899
+ if (hasDocument && !willUnload) {
900
+ console.log(`[vite] server connection lost. Polling for restart...`);
901
+ const socket = payload.data.webSocket;
902
+ await waitForSuccessfulPing(socket.url);
903
+ location.reload();
904
+ }
905
+ }
674
906
  break;
675
907
  }
676
908
  case "full-reload":
@@ -708,6 +940,8 @@ ${err.stack}`
708
940
  }
709
941
  break;
710
942
  }
943
+ case "ping":
944
+ break;
711
945
  default: {
712
946
  const check = payload;
713
947
  return check;
@@ -729,12 +963,9 @@ function clearErrorOverlay() {
729
963
  function hasErrorOverlay() {
730
964
  return document.querySelectorAll(overlayId).length;
731
965
  }
732
- async function waitForSuccessfulPing(socketProtocol2, hostAndPath, ms = 1e3) {
966
+ async function waitForSuccessfulPing(socketUrl, ms = 1e3) {
733
967
  async function ping() {
734
- const socket2 = new WebSocket(
735
- `${socketProtocol2}://${hostAndPath}`,
736
- "vite-ping"
737
- );
968
+ const socket = new WebSocket(socketUrl, "vite-ping");
738
969
  return new Promise((resolve) => {
739
970
  function onOpen() {
740
971
  resolve(true);
@@ -745,12 +976,12 @@ async function waitForSuccessfulPing(socketProtocol2, hostAndPath, ms = 1e3) {
745
976
  close();
746
977
  }
747
978
  function close() {
748
- socket2.removeEventListener("open", onOpen);
749
- socket2.removeEventListener("error", onError);
750
- socket2.close();
979
+ socket.removeEventListener("open", onOpen);
980
+ socket.removeEventListener("error", onError);
981
+ socket.close();
751
982
  }
752
- socket2.addEventListener("open", onOpen);
753
- socket2.addEventListener("error", onError);
983
+ socket.addEventListener("open", onOpen);
984
+ socket.addEventListener("error", onError);
754
985
  });
755
986
  }
756
987
  if (await ping()) {