1 | import '@vite/env';
|
---|
2 |
|
---|
3 | class 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 | }
|
---|
112 | class 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 |
|
---|
218 | let urlAlphabet =
|
---|
219 | 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
|
---|
220 | let 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 |
|
---|
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 ("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 | };
|
---|
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 = 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 | };
|
---|
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 |
|
---|
477 | const hmrConfigName = __HMR_CONFIG_NAME__;
|
---|
478 | const base$1 = __BASE__ || "/";
|
---|
479 | function 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 | }
|
---|
487 | const 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 |
|
---|
539 | pre {
|
---|
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 |
|
---|
548 | pre::-webkit-scrollbar {
|
---|
549 | display: none;
|
---|
550 | }
|
---|
551 |
|
---|
552 | pre.frame::-webkit-scrollbar {
|
---|
553 | display: block;
|
---|
554 | height: 5px;
|
---|
555 | }
|
---|
556 |
|
---|
557 | pre.frame::-webkit-scrollbar-thumb {
|
---|
558 | background: #999;
|
---|
559 | border-radius: 5px;
|
---|
560 | }
|
---|
561 |
|
---|
562 | pre.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 |
|
---|
604 | code {
|
---|
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 |
|
---|
615 | kbd {
|
---|
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 | );
|
---|
631 | const 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 | );
|
---|
664 | const fileRE = /(?:[a-zA-Z]:\\|\/).*?:\d+:\d+/g;
|
---|
665 | const codeframeRE = /^(?:>?\s*\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm;
|
---|
666 | const { HTMLElement = class {
|
---|
667 | } } = globalThis;
|
---|
668 | class 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 | }
|
---|
736 | const overlayId = "vite-error-overlay";
|
---|
737 | const { customElements } = globalThis;
|
---|
738 | if (customElements && !customElements.get(overlayId)) {
|
---|
739 | customElements.define(overlayId, ErrorOverlay);
|
---|
740 | }
|
---|
741 |
|
---|
742 | console.debug("[vite] connecting...");
|
---|
743 | const importMetaUrl = new URL(import.meta.url);
|
---|
744 | const serverHost = __SERVER_HOST__;
|
---|
745 | const socketProtocol = __HMR_PROTOCOL__ || (importMetaUrl.protocol === "https:" ? "wss" : "ws");
|
---|
746 | const hmrPort = __HMR_PORT__;
|
---|
747 | const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}`;
|
---|
748 | const directSocketHost = __HMR_DIRECT_TARGET__;
|
---|
749 | const base = __BASE__ || "/";
|
---|
750 | const hmrTimeout = __HMR_TIMEOUT__;
|
---|
751 | const wsToken = __WS_TOKEN__;
|
---|
752 | const 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.
|
---|
785 | your current setup:
|
---|
786 | (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)
|
---|
787 | (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)
|
---|
788 | Check 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 | );
|
---|
807 | let willUnload = false;
|
---|
808 | if (typeof window !== "undefined") {
|
---|
809 | window.addEventListener("beforeunload", () => {
|
---|
810 | willUnload = true;
|
---|
811 | });
|
---|
812 | }
|
---|
813 | function cleanUrl(pathname) {
|
---|
814 | const url = new URL(pathname, "http://vite.dev");
|
---|
815 | url.searchParams.delete("direct");
|
---|
816 | return url.pathname + url.search;
|
---|
817 | }
|
---|
818 | let isFirstUpdate = true;
|
---|
819 | const outdatedLinkTags = /* @__PURE__ */ new WeakSet();
|
---|
820 | const 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 | };
|
---|
832 | const pageReload = debounceReload(50);
|
---|
833 | const 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 | );
|
---|
861 | transport.connect(handleMessage);
|
---|
862 | async 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 | }
|
---|
970 | function notifyListeners(event, data) {
|
---|
971 | hmrClient.notifyListeners(event, data);
|
---|
972 | }
|
---|
973 | const enableOverlay = __HMR_ENABLE_OVERLAY__;
|
---|
974 | const hasDocument = "document" in globalThis;
|
---|
975 | function 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 | }
|
---|
983 | function clearErrorOverlay() {
|
---|
984 | document.querySelectorAll(overlayId).forEach((n) => n.close());
|
---|
985 | }
|
---|
986 | function hasErrorOverlay() {
|
---|
987 | return document.querySelectorAll(overlayId).length;
|
---|
988 | }
|
---|
989 | async 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 | }
|
---|
1025 | function wait(ms) {
|
---|
1026 | return new Promise((resolve) => setTimeout(resolve, ms));
|
---|
1027 | }
|
---|
1028 | function 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 | }
|
---|
1039 | const sheetsMap = /* @__PURE__ */ new Map();
|
---|
1040 | if ("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 | }
|
---|
1045 | const cspNonce = "document" in globalThis ? document.querySelector("meta[property=csp-nonce]")?.nonce : undefined;
|
---|
1046 | let lastInsertedStyle;
|
---|
1047 | function 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 | }
|
---|
1071 | function removeStyle(id) {
|
---|
1072 | const style = sheetsMap.get(id);
|
---|
1073 | if (style) {
|
---|
1074 | document.head.removeChild(style);
|
---|
1075 | sheetsMap.delete(id);
|
---|
1076 | }
|
---|
1077 | }
|
---|
1078 | function createHotContext(ownerPath) {
|
---|
1079 | return new HMRContext(hmrClient, ownerPath);
|
---|
1080 | }
|
---|
1081 | function 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 |
|
---|
1090 | export { ErrorOverlay, createHotContext, injectQuery, removeStyle, updateStyle };
|
---|