source: node_modules/vite/dist/client/client.mjs@ 7deb3e2

Last change on this file since 7deb3e2 was 57e58a3, checked in by ste08 <sjovanoska@…>, 4 months ago

Initial commit

  • Property mode set to 100644
File size: 30.5 KB
Line 
1import '@vite/env';
2
3class HMRContext {
4 constructor(hmrClient, ownerPath) {
5 this.hmrClient = hmrClient;
6 this.ownerPath = ownerPath;
7 if (!hmrClient.dataMap.has(ownerPath)) {
8 hmrClient.dataMap.set(ownerPath, {});
9 }
10 const mod = hmrClient.hotModulesMap.get(ownerPath);
11 if (mod) {
12 mod.callbacks = [];
13 }
14 const staleListeners = hmrClient.ctxToListenersMap.get(ownerPath);
15 if (staleListeners) {
16 for (const [event, staleFns] of staleListeners) {
17 const listeners = hmrClient.customListenersMap.get(event);
18 if (listeners) {
19 hmrClient.customListenersMap.set(
20 event,
21 listeners.filter((l) => !staleFns.includes(l))
22 );
23 }
24 }
25 }
26 this.newListeners = /* @__PURE__ */ new Map();
27 hmrClient.ctxToListenersMap.set(ownerPath, this.newListeners);
28 }
29 get data() {
30 return this.hmrClient.dataMap.get(this.ownerPath);
31 }
32 accept(deps, callback) {
33 if (typeof deps === "function" || !deps) {
34 this.acceptDeps([this.ownerPath], ([mod]) => deps?.(mod));
35 } else if (typeof deps === "string") {
36 this.acceptDeps([deps], ([mod]) => callback?.(mod));
37 } else if (Array.isArray(deps)) {
38 this.acceptDeps(deps, callback);
39 } else {
40 throw new Error(`invalid hot.accept() usage.`);
41 }
42 }
43 // export names (first arg) are irrelevant on the client side, they're
44 // extracted in the server for propagation
45 acceptExports(_, callback) {
46 this.acceptDeps([this.ownerPath], ([mod]) => callback?.(mod));
47 }
48 dispose(cb) {
49 this.hmrClient.disposeMap.set(this.ownerPath, cb);
50 }
51 prune(cb) {
52 this.hmrClient.pruneMap.set(this.ownerPath, cb);
53 }
54 // Kept for backward compatibility (#11036)
55 // eslint-disable-next-line @typescript-eslint/no-empty-function
56 decline() {
57 }
58 invalidate(message) {
59 this.hmrClient.notifyListeners("vite:invalidate", {
60 path: this.ownerPath,
61 message
62 });
63 this.send("vite:invalidate", {
64 path: this.ownerPath,
65 message
66 });
67 this.hmrClient.logger.debug(
68 `invalidate ${this.ownerPath}${message ? `: ${message}` : ""}`
69 );
70 }
71 on(event, cb) {
72 const addToMap = (map) => {
73 const existing = map.get(event) || [];
74 existing.push(cb);
75 map.set(event, existing);
76 };
77 addToMap(this.hmrClient.customListenersMap);
78 addToMap(this.newListeners);
79 }
80 off(event, cb) {
81 const removeFromMap = (map) => {
82 const existing = map.get(event);
83 if (existing === undefined) {
84 return;
85 }
86 const pruned = existing.filter((l) => l !== cb);
87 if (pruned.length === 0) {
88 map.delete(event);
89 return;
90 }
91 map.set(event, pruned);
92 };
93 removeFromMap(this.hmrClient.customListenersMap);
94 removeFromMap(this.newListeners);
95 }
96 send(event, data) {
97 this.hmrClient.send({ type: "custom", event, data });
98 }
99 acceptDeps(deps, callback = () => {
100 }) {
101 const mod = this.hmrClient.hotModulesMap.get(this.ownerPath) || {
102 id: this.ownerPath,
103 callbacks: []
104 };
105 mod.callbacks.push({
106 deps,
107 fn: callback
108 });
109 this.hmrClient.hotModulesMap.set(this.ownerPath, mod);
110 }
111}
112class HMRClient {
113 constructor(logger, transport, importUpdatedModule) {
114 this.logger = logger;
115 this.transport = transport;
116 this.importUpdatedModule = importUpdatedModule;
117 this.hotModulesMap = /* @__PURE__ */ new Map();
118 this.disposeMap = /* @__PURE__ */ new Map();
119 this.pruneMap = /* @__PURE__ */ new Map();
120 this.dataMap = /* @__PURE__ */ new Map();
121 this.customListenersMap = /* @__PURE__ */ new Map();
122 this.ctxToListenersMap = /* @__PURE__ */ new Map();
123 this.updateQueue = [];
124 this.pendingUpdateQueue = false;
125 }
126 async notifyListeners(event, data) {
127 const cbs = this.customListenersMap.get(event);
128 if (cbs) {
129 await Promise.allSettled(cbs.map((cb) => cb(data)));
130 }
131 }
132 send(payload) {
133 this.transport.send(payload).catch((err) => {
134 this.logger.error(err);
135 });
136 }
137 clear() {
138 this.hotModulesMap.clear();
139 this.disposeMap.clear();
140 this.pruneMap.clear();
141 this.dataMap.clear();
142 this.customListenersMap.clear();
143 this.ctxToListenersMap.clear();
144 }
145 // After an HMR update, some modules are no longer imported on the page
146 // but they may have left behind side effects that need to be cleaned up
147 // (e.g. style injections)
148 async prunePaths(paths) {
149 await Promise.all(
150 paths.map((path) => {
151 const disposer = this.disposeMap.get(path);
152 if (disposer) return disposer(this.dataMap.get(path));
153 })
154 );
155 paths.forEach((path) => {
156 const fn = this.pruneMap.get(path);
157 if (fn) {
158 fn(this.dataMap.get(path));
159 }
160 });
161 }
162 warnFailedUpdate(err, path) {
163 if (!err.message.includes("fetch")) {
164 this.logger.error(err);
165 }
166 this.logger.error(
167 `Failed to reload ${path}. This could be due to syntax errors or importing non-existent modules. (see errors above)`
168 );
169 }
170 /**
171 * buffer multiple hot updates triggered by the same src change
172 * so that they are invoked in the same order they were sent.
173 * (otherwise the order may be inconsistent because of the http request round trip)
174 */
175 async queueUpdate(payload) {
176 this.updateQueue.push(this.fetchUpdate(payload));
177 if (!this.pendingUpdateQueue) {
178 this.pendingUpdateQueue = true;
179 await Promise.resolve();
180 this.pendingUpdateQueue = false;
181 const loading = [...this.updateQueue];
182 this.updateQueue = [];
183 (await Promise.all(loading)).forEach((fn) => fn && fn());
184 }
185 }
186 async fetchUpdate(update) {
187 const { path, acceptedPath } = update;
188 const mod = this.hotModulesMap.get(path);
189 if (!mod) {
190 return;
191 }
192 let fetchedModule;
193 const isSelfUpdate = path === acceptedPath;
194 const qualifiedCallbacks = mod.callbacks.filter(
195 ({ deps }) => deps.includes(acceptedPath)
196 );
197 if (isSelfUpdate || qualifiedCallbacks.length > 0) {
198 const disposer = this.disposeMap.get(acceptedPath);
199 if (disposer) await disposer(this.dataMap.get(acceptedPath));
200 try {
201 fetchedModule = await this.importUpdatedModule(update);
202 } catch (e) {
203 this.warnFailedUpdate(e, acceptedPath);
204 }
205 }
206 return () => {
207 for (const { deps, fn } of qualifiedCallbacks) {
208 fn(
209 deps.map((dep) => dep === acceptedPath ? fetchedModule : undefined)
210 );
211 }
212 const loggedPath = isSelfUpdate ? path : `${acceptedPath} via ${path}`;
213 this.logger.debug(`hot updated: ${loggedPath}`);
214 };
215 }
216}
217
218let urlAlphabet =
219 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
220let nanoid = (size = 21) => {
221 let id = '';
222 let i = size | 0;
223 while (i--) {
224 id += urlAlphabet[(Math.random() * 64) | 0];
225 }
226 return id
227};
228
229typeof process !== "undefined" && process.platform === "win32";
230function 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
240function 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}
249const 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 ("error" in result) {
264 throw reviveInvokeError(result.error);
265 }
266 return result.result;
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 { error, result } = data.data;
290 if (error) {
291 promise.reject(error);
292 } else {
293 promise.resolve(result);
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};
359const 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 = undefined;
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};
420const 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
477const hmrConfigName = __HMR_CONFIG_NAME__;
478const base$1 = __BASE__ || "/";
479function h(e, attrs = {}, ...children) {
480 const elem = document.createElement(e);
481 for (const [k, v] of Object.entries(attrs)) {
482 elem.setAttribute(k, v);
483 }
484 elem.append(...children);
485 return elem;
486}
487const templateStyle = (
488 /*css*/
489 `
490:host {
491 position: fixed;
492 top: 0;
493 left: 0;
494 width: 100%;
495 height: 100%;
496 z-index: 99999;
497 --monospace: 'SFMono-Regular', Consolas,
498 'Liberation Mono', Menlo, Courier, monospace;
499 --red: #ff5555;
500 --yellow: #e2aa53;
501 --purple: #cfa4ff;
502 --cyan: #2dd9da;
503 --dim: #c9c9c9;
504
505 --window-background: #181818;
506 --window-color: #d8d8d8;
507}
508
509.backdrop {
510 position: fixed;
511 z-index: 99999;
512 top: 0;
513 left: 0;
514 width: 100%;
515 height: 100%;
516 overflow-y: scroll;
517 margin: 0;
518 background: rgba(0, 0, 0, 0.66);
519}
520
521.window {
522 font-family: var(--monospace);
523 line-height: 1.5;
524 max-width: 80vw;
525 color: var(--window-color);
526 box-sizing: border-box;
527 margin: 30px auto;
528 padding: 2.5vh 4vw;
529 position: relative;
530 background: var(--window-background);
531 border-radius: 6px 6px 8px 8px;
532 box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22);
533 overflow: hidden;
534 border-top: 8px solid var(--red);
535 direction: ltr;
536 text-align: left;
537}
538
539pre {
540 font-family: var(--monospace);
541 font-size: 16px;
542 margin-top: 0;
543 margin-bottom: 1em;
544 overflow-x: scroll;
545 scrollbar-width: none;
546}
547
548pre::-webkit-scrollbar {
549 display: none;
550}
551
552pre.frame::-webkit-scrollbar {
553 display: block;
554 height: 5px;
555}
556
557pre.frame::-webkit-scrollbar-thumb {
558 background: #999;
559 border-radius: 5px;
560}
561
562pre.frame {
563 scrollbar-width: thin;
564}
565
566.message {
567 line-height: 1.3;
568 font-weight: 600;
569 white-space: pre-wrap;
570}
571
572.message-body {
573 color: var(--red);
574}
575
576.plugin {
577 color: var(--purple);
578}
579
580.file {
581 color: var(--cyan);
582 margin-bottom: 0;
583 white-space: pre-wrap;
584 word-break: break-all;
585}
586
587.frame {
588 color: var(--yellow);
589}
590
591.stack {
592 font-size: 13px;
593 color: var(--dim);
594}
595
596.tip {
597 font-size: 13px;
598 color: #999;
599 border-top: 1px dotted #999;
600 padding-top: 13px;
601 line-height: 1.8;
602}
603
604code {
605 font-size: 13px;
606 font-family: var(--monospace);
607 color: var(--yellow);
608}
609
610.file-link {
611 text-decoration: underline;
612 cursor: pointer;
613}
614
615kbd {
616 line-height: 1.5;
617 font-family: ui-monospace, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
618 font-size: 0.75rem;
619 font-weight: 700;
620 background-color: rgb(38, 40, 44);
621 color: rgb(166, 167, 171);
622 padding: 0.15rem 0.3rem;
623 border-radius: 0.25rem;
624 border-width: 0.0625rem 0.0625rem 0.1875rem;
625 border-style: solid;
626 border-color: rgb(54, 57, 64);
627 border-image: initial;
628}
629`
630);
631const createTemplate = () => h(
632 "div",
633 { class: "backdrop", part: "backdrop" },
634 h(
635 "div",
636 { class: "window", part: "window" },
637 h(
638 "pre",
639 { class: "message", part: "message" },
640 h("span", { class: "plugin", part: "plugin" }),
641 h("span", { class: "message-body", part: "message-body" })
642 ),
643 h("pre", { class: "file", part: "file" }),
644 h("pre", { class: "frame", part: "frame" }),
645 h("pre", { class: "stack", part: "stack" }),
646 h(
647 "div",
648 { class: "tip", part: "tip" },
649 "Click outside, press ",
650 h("kbd", {}, "Esc"),
651 " key, or fix the code to dismiss.",
652 h("br"),
653 "You can also disable this overlay by setting ",
654 h("code", { part: "config-option-name" }, "server.hmr.overlay"),
655 " to ",
656 h("code", { part: "config-option-value" }, "false"),
657 " in ",
658 h("code", { part: "config-file-name" }, hmrConfigName),
659 "."
660 )
661 ),
662 h("style", {}, templateStyle)
663);
664const fileRE = /(?:[a-zA-Z]:\\|\/).*?:\d+:\d+/g;
665const codeframeRE = /^(?:>?\s*\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm;
666const { HTMLElement = class {
667} } = globalThis;
668class ErrorOverlay extends HTMLElement {
669 constructor(err, links = true) {
670 super();
671 this.root = this.attachShadow({ mode: "open" });
672 this.root.appendChild(createTemplate());
673 codeframeRE.lastIndex = 0;
674 const hasFrame = err.frame && codeframeRE.test(err.frame);
675 const message = hasFrame ? err.message.replace(codeframeRE, "") : err.message;
676 if (err.plugin) {
677 this.text(".plugin", `[plugin:${err.plugin}] `);
678 }
679 this.text(".message-body", message.trim());
680 const [file] = (err.loc?.file || err.id || "unknown file").split(`?`);
681 if (err.loc) {
682 this.text(".file", `${file}:${err.loc.line}:${err.loc.column}`, links);
683 } else if (err.id) {
684 this.text(".file", file);
685 }
686 if (hasFrame) {
687 this.text(".frame", err.frame.trim());
688 }
689 this.text(".stack", err.stack, links);
690 this.root.querySelector(".window").addEventListener("click", (e) => {
691 e.stopPropagation();
692 });
693 this.addEventListener("click", () => {
694 this.close();
695 });
696 this.closeOnEsc = (e) => {
697 if (e.key === "Escape" || e.code === "Escape") {
698 this.close();
699 }
700 };
701 document.addEventListener("keydown", this.closeOnEsc);
702 }
703 text(selector, text, linkFiles = false) {
704 const el = this.root.querySelector(selector);
705 if (!linkFiles) {
706 el.textContent = text;
707 } else {
708 let curIndex = 0;
709 let match;
710 fileRE.lastIndex = 0;
711 while (match = fileRE.exec(text)) {
712 const { 0: file, index } = match;
713 const frag = text.slice(curIndex, index);
714 el.appendChild(document.createTextNode(frag));
715 const link = document.createElement("a");
716 link.textContent = file;
717 link.className = "file-link";
718 link.onclick = () => {
719 fetch(
720 new URL(
721 `${base$1}__open-in-editor?file=${encodeURIComponent(file)}`,
722 import.meta.url
723 )
724 );
725 };
726 el.appendChild(link);
727 curIndex += frag.length + file.length;
728 }
729 }
730 }
731 close() {
732 this.parentNode?.removeChild(this);
733 document.removeEventListener("keydown", this.closeOnEsc);
734 }
735}
736const overlayId = "vite-error-overlay";
737const { customElements } = globalThis;
738if (customElements && !customElements.get(overlayId)) {
739 customElements.define(overlayId, ErrorOverlay);
740}
741
742console.debug("[vite] connecting...");
743const importMetaUrl = new URL(import.meta.url);
744const serverHost = __SERVER_HOST__;
745const socketProtocol = __HMR_PROTOCOL__ || (importMetaUrl.protocol === "https:" ? "wss" : "ws");
746const hmrPort = __HMR_PORT__;
747const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}`;
748const directSocketHost = __HMR_DIRECT_TARGET__;
749const base = __BASE__ || "/";
750const hmrTimeout = __HMR_TIMEOUT__;
751const wsToken = __WS_TOKEN__;
752const transport = normalizeModuleRunnerTransport(
753 (() => {
754 let wsTransport = createWebSocketModuleRunnerTransport({
755 createConnection: () => new WebSocket(
756 `${socketProtocol}://${socketHost}?token=${wsToken}`,
757 "vite-hmr"
758 ),
759 pingInterval: hmrTimeout
760 });
761 return {
762 async connect(handlers) {
763 try {
764 await wsTransport.connect(handlers);
765 } catch (e) {
766 if (!hmrPort) {
767 wsTransport = createWebSocketModuleRunnerTransport({
768 createConnection: () => new WebSocket(
769 `${socketProtocol}://${directSocketHost}?token=${wsToken}`,
770 "vite-hmr"
771 ),
772 pingInterval: hmrTimeout
773 });
774 try {
775 await wsTransport.connect(handlers);
776 console.info(
777 "[vite] Direct websocket connection fallback. Check out https://vite.dev/config/server-options.html#server-hmr to remove the previous connection error."
778 );
779 } catch (e2) {
780 if (e2 instanceof Error && e2.message.includes("WebSocket closed without opened.")) {
781 const currentScriptHostURL = new URL(import.meta.url);
782 const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
783 console.error(
784 `[vite] failed to connect to websocket.
785your current setup:
786 (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)
787 (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)
788Check out your Vite / network configuration and https://vite.dev/config/server-options.html#server-hmr .`
789 );
790 }
791 }
792 return;
793 }
794 console.error(`[vite] failed to connect to websocket (${e}). `);
795 throw e;
796 }
797 },
798 async disconnect() {
799 await wsTransport.disconnect();
800 },
801 send(data) {
802 wsTransport.send(data);
803 }
804 };
805 })()
806);
807let willUnload = false;
808if (typeof window !== "undefined") {
809 window.addEventListener("beforeunload", () => {
810 willUnload = true;
811 });
812}
813function cleanUrl(pathname) {
814 const url = new URL(pathname, "http://vite.dev");
815 url.searchParams.delete("direct");
816 return url.pathname + url.search;
817}
818let isFirstUpdate = true;
819const outdatedLinkTags = /* @__PURE__ */ new WeakSet();
820const debounceReload = (time) => {
821 let timer;
822 return () => {
823 if (timer) {
824 clearTimeout(timer);
825 timer = null;
826 }
827 timer = setTimeout(() => {
828 location.reload();
829 }, time);
830 };
831};
832const pageReload = debounceReload(50);
833const hmrClient = new HMRClient(
834 {
835 error: (err) => console.error("[vite]", err),
836 debug: (...msg) => console.debug("[vite]", ...msg)
837 },
838 transport,
839 async function importUpdatedModule({
840 acceptedPath,
841 timestamp,
842 explicitImportRequired,
843 isWithinCircularImport
844 }) {
845 const [acceptedPathWithoutQuery, query] = acceptedPath.split(`?`);
846 const importPromise = import(
847 /* @vite-ignore */
848 base + acceptedPathWithoutQuery.slice(1) + `?${explicitImportRequired ? "import&" : ""}t=${timestamp}${query ? `&${query}` : ""}`
849 );
850 if (isWithinCircularImport) {
851 importPromise.catch(() => {
852 console.info(
853 `[hmr] ${acceptedPath} failed to apply HMR as it's within a circular import. Reloading page to reset the execution order. To debug and break the circular import, you can run \`vite --debug hmr\` to log the circular dependency path if a file change triggered it.`
854 );
855 pageReload();
856 });
857 }
858 return await importPromise;
859 }
860);
861transport.connect(handleMessage);
862async function handleMessage(payload) {
863 switch (payload.type) {
864 case "connected":
865 console.debug(`[vite] connected.`);
866 break;
867 case "update":
868 notifyListeners("vite:beforeUpdate", payload);
869 if (hasDocument) {
870 if (isFirstUpdate && hasErrorOverlay()) {
871 location.reload();
872 return;
873 } else {
874 if (enableOverlay) {
875 clearErrorOverlay();
876 }
877 isFirstUpdate = false;
878 }
879 }
880 await Promise.all(
881 payload.updates.map(async (update) => {
882 if (update.type === "js-update") {
883 return hmrClient.queueUpdate(update);
884 }
885 const { path, timestamp } = update;
886 const searchUrl = cleanUrl(path);
887 const el = Array.from(
888 document.querySelectorAll("link")
889 ).find(
890 (e) => !outdatedLinkTags.has(e) && cleanUrl(e.href).includes(searchUrl)
891 );
892 if (!el) {
893 return;
894 }
895 const newPath = `${base}${searchUrl.slice(1)}${searchUrl.includes("?") ? "&" : "?"}t=${timestamp}`;
896 return new Promise((resolve) => {
897 const newLinkTag = el.cloneNode();
898 newLinkTag.href = new URL(newPath, el.href).href;
899 const removeOldEl = () => {
900 el.remove();
901 console.debug(`[vite] css hot updated: ${searchUrl}`);
902 resolve();
903 };
904 newLinkTag.addEventListener("load", removeOldEl);
905 newLinkTag.addEventListener("error", removeOldEl);
906 outdatedLinkTags.add(el);
907 el.after(newLinkTag);
908 });
909 })
910 );
911 notifyListeners("vite:afterUpdate", payload);
912 break;
913 case "custom": {
914 notifyListeners(payload.event, payload.data);
915 if (payload.event === "vite:ws:disconnect") {
916 if (hasDocument && !willUnload) {
917 console.log(`[vite] server connection lost. Polling for restart...`);
918 const socket = payload.data.webSocket;
919 const url = new URL(socket.url);
920 url.search = "";
921 await waitForSuccessfulPing(url.href);
922 location.reload();
923 }
924 }
925 break;
926 }
927 case "full-reload":
928 notifyListeners("vite:beforeFullReload", payload);
929 if (hasDocument) {
930 if (payload.path && payload.path.endsWith(".html")) {
931 const pagePath = decodeURI(location.pathname);
932 const payloadPath = base + payload.path.slice(1);
933 if (pagePath === payloadPath || payload.path === "/index.html" || pagePath.endsWith("/") && pagePath + "index.html" === payloadPath) {
934 pageReload();
935 }
936 return;
937 } else {
938 pageReload();
939 }
940 }
941 break;
942 case "prune":
943 notifyListeners("vite:beforePrune", payload);
944 await hmrClient.prunePaths(payload.paths);
945 break;
946 case "error": {
947 notifyListeners("vite:error", payload);
948 if (hasDocument) {
949 const err = payload.err;
950 if (enableOverlay) {
951 createErrorOverlay(err);
952 } else {
953 console.error(
954 `[vite] Internal Server Error
955${err.message}
956${err.stack}`
957 );
958 }
959 }
960 break;
961 }
962 case "ping":
963 break;
964 default: {
965 const check = payload;
966 return check;
967 }
968 }
969}
970function notifyListeners(event, data) {
971 hmrClient.notifyListeners(event, data);
972}
973const enableOverlay = __HMR_ENABLE_OVERLAY__;
974const hasDocument = "document" in globalThis;
975function createErrorOverlay(err) {
976 clearErrorOverlay();
977 const { customElements } = globalThis;
978 if (customElements) {
979 const ErrorOverlayConstructor = customElements.get(overlayId);
980 document.body.appendChild(new ErrorOverlayConstructor(err));
981 }
982}
983function clearErrorOverlay() {
984 document.querySelectorAll(overlayId).forEach((n) => n.close());
985}
986function hasErrorOverlay() {
987 return document.querySelectorAll(overlayId).length;
988}
989async function waitForSuccessfulPing(socketUrl, ms = 1e3) {
990 async function ping() {
991 const socket = new WebSocket(socketUrl, "vite-ping");
992 return new Promise((resolve) => {
993 function onOpen() {
994 resolve(true);
995 close();
996 }
997 function onError() {
998 resolve(false);
999 close();
1000 }
1001 function close() {
1002 socket.removeEventListener("open", onOpen);
1003 socket.removeEventListener("error", onError);
1004 socket.close();
1005 }
1006 socket.addEventListener("open", onOpen);
1007 socket.addEventListener("error", onError);
1008 });
1009 }
1010 if (await ping()) {
1011 return;
1012 }
1013 await wait(ms);
1014 while (true) {
1015 if (document.visibilityState === "visible") {
1016 if (await ping()) {
1017 break;
1018 }
1019 await wait(ms);
1020 } else {
1021 await waitForWindowShow();
1022 }
1023 }
1024}
1025function wait(ms) {
1026 return new Promise((resolve) => setTimeout(resolve, ms));
1027}
1028function waitForWindowShow() {
1029 return new Promise((resolve) => {
1030 const onChange = async () => {
1031 if (document.visibilityState === "visible") {
1032 resolve();
1033 document.removeEventListener("visibilitychange", onChange);
1034 }
1035 };
1036 document.addEventListener("visibilitychange", onChange);
1037 });
1038}
1039const sheetsMap = /* @__PURE__ */ new Map();
1040if ("document" in globalThis) {
1041 document.querySelectorAll("style[data-vite-dev-id]").forEach((el) => {
1042 sheetsMap.set(el.getAttribute("data-vite-dev-id"), el);
1043 });
1044}
1045const cspNonce = "document" in globalThis ? document.querySelector("meta[property=csp-nonce]")?.nonce : undefined;
1046let lastInsertedStyle;
1047function updateStyle(id, content) {
1048 let style = sheetsMap.get(id);
1049 if (!style) {
1050 style = document.createElement("style");
1051 style.setAttribute("type", "text/css");
1052 style.setAttribute("data-vite-dev-id", id);
1053 style.textContent = content;
1054 if (cspNonce) {
1055 style.setAttribute("nonce", cspNonce);
1056 }
1057 if (!lastInsertedStyle) {
1058 document.head.appendChild(style);
1059 setTimeout(() => {
1060 lastInsertedStyle = undefined;
1061 }, 0);
1062 } else {
1063 lastInsertedStyle.insertAdjacentElement("afterend", style);
1064 }
1065 lastInsertedStyle = style;
1066 } else {
1067 style.textContent = content;
1068 }
1069 sheetsMap.set(id, style);
1070}
1071function removeStyle(id) {
1072 const style = sheetsMap.get(id);
1073 if (style) {
1074 document.head.removeChild(style);
1075 sheetsMap.delete(id);
1076 }
1077}
1078function createHotContext(ownerPath) {
1079 return new HMRContext(hmrClient, ownerPath);
1080}
1081function injectQuery(url, queryToInject) {
1082 if (url[0] !== "." && url[0] !== "/") {
1083 return url;
1084 }
1085 const pathname = url.replace(/[?#].*$/, "");
1086 const { search, hash } = new URL(url, "http://vite.dev");
1087 return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ""}${hash || ""}`;
1088}
1089
1090export { ErrorOverlay, createHotContext, injectQuery, removeStyle, updateStyle };
Note: See TracBrowser for help on using the repository browser.