vite 5.3.0-beta.1 → 5.3.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.
@@ -1,245 +1,243 @@
1
1
  import '@vite/env';
2
2
 
3
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, {});
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
+ );
9
23
  }
10
- // when a file is hot updated, a new context is created
11
- // clear its stale callbacks
12
- const mod = hmrClient.hotModulesMap.get(ownerPath);
13
- if (mod) {
14
- mod.callbacks = [];
15
- }
16
- // clear stale custom event listeners
17
- const staleListeners = hmrClient.ctxToListenersMap.get(ownerPath);
18
- if (staleListeners) {
19
- for (const [event, staleFns] of staleListeners) {
20
- const listeners = hmrClient.customListenersMap.get(event);
21
- if (listeners) {
22
- hmrClient.customListenersMap.set(event, listeners.filter((l) => !staleFns.includes(l)));
23
- }
24
- }
25
- }
26
- this.newListeners = 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
- // self-accept: hot.accept(() => {})
35
- this.acceptDeps([this.ownerPath], ([mod]) => deps === null || deps === void 0 ? void 0 : deps(mod));
36
- }
37
- else if (typeof deps === 'string') {
38
- // explicit deps
39
- this.acceptDeps([deps], ([mod]) => callback === null || callback === void 0 ? void 0 : callback(mod));
40
- }
41
- else if (Array.isArray(deps)) {
42
- this.acceptDeps(deps, callback);
43
- }
44
- else {
45
- throw new Error(`invalid hot.accept() usage.`);
46
- }
47
- }
48
- // export names (first arg) are irrelevant on the client side, they're
49
- // extracted in the server for propagation
50
- acceptExports(_, callback) {
51
- this.acceptDeps([this.ownerPath], ([mod]) => callback === null || callback === void 0 ? void 0 : callback(mod));
52
- }
53
- dispose(cb) {
54
- this.hmrClient.disposeMap.set(this.ownerPath, cb);
55
- }
56
- prune(cb) {
57
- this.hmrClient.pruneMap.set(this.ownerPath, cb);
58
- }
59
- // Kept for backward compatibility (#11036)
60
- // eslint-disable-next-line @typescript-eslint/no-empty-function
61
- decline() { }
62
- invalidate(message) {
63
- this.hmrClient.notifyListeners('vite:invalidate', {
64
- path: this.ownerPath,
65
- message,
66
- });
67
- this.send('vite:invalidate', { path: this.ownerPath, message });
68
- this.hmrClient.logger.debug(`[vite] invalidate ${this.ownerPath}${message ? `: ${message}` : ''}`);
69
- }
70
- on(event, cb) {
71
- const addToMap = (map) => {
72
- const existing = map.get(event) || [];
73
- existing.push(cb);
74
- map.set(event, existing);
75
- };
76
- addToMap(this.hmrClient.customListenersMap);
77
- addToMap(this.newListeners);
78
- }
79
- off(event, cb) {
80
- const removeFromMap = (map) => {
81
- const existing = map.get(event);
82
- if (existing === undefined) {
83
- return;
84
- }
85
- const pruned = existing.filter((l) => l !== cb);
86
- if (pruned.length === 0) {
87
- map.delete(event);
88
- return;
89
- }
90
- map.set(event, pruned);
91
- };
92
- removeFromMap(this.hmrClient.customListenersMap);
93
- removeFromMap(this.newListeners);
94
- }
95
- send(event, data) {
96
- this.hmrClient.messenger.send(JSON.stringify({ type: 'custom', event, data }));
97
- }
98
- acceptDeps(deps, callback = () => { }) {
99
- const mod = this.hmrClient.hotModulesMap.get(this.ownerPath) || {
100
- id: this.ownerPath,
101
- callbacks: [],
102
- };
103
- mod.callbacks.push({
104
- deps,
105
- fn: callback,
106
- });
107
- this.hmrClient.hotModulesMap.set(this.ownerPath, mod);
108
- }
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", { path: this.ownerPath, message });
64
+ this.hmrClient.logger.debug(
65
+ `[vite] invalidate ${this.ownerPath}${message ? `: ${message}` : ""}`
66
+ );
67
+ }
68
+ on(event, cb) {
69
+ const addToMap = (map) => {
70
+ const existing = map.get(event) || [];
71
+ existing.push(cb);
72
+ map.set(event, existing);
73
+ };
74
+ addToMap(this.hmrClient.customListenersMap);
75
+ addToMap(this.newListeners);
76
+ }
77
+ off(event, cb) {
78
+ const removeFromMap = (map) => {
79
+ const existing = map.get(event);
80
+ if (existing === void 0) {
81
+ return;
82
+ }
83
+ const pruned = existing.filter((l) => l !== cb);
84
+ if (pruned.length === 0) {
85
+ map.delete(event);
86
+ return;
87
+ }
88
+ map.set(event, pruned);
89
+ };
90
+ removeFromMap(this.hmrClient.customListenersMap);
91
+ removeFromMap(this.newListeners);
92
+ }
93
+ send(event, data) {
94
+ this.hmrClient.messenger.send(
95
+ JSON.stringify({ type: "custom", event, data })
96
+ );
97
+ }
98
+ acceptDeps(deps, callback = () => {
99
+ }) {
100
+ const mod = this.hmrClient.hotModulesMap.get(this.ownerPath) || {
101
+ id: this.ownerPath,
102
+ callbacks: []
103
+ };
104
+ mod.callbacks.push({
105
+ deps,
106
+ fn: callback
107
+ });
108
+ this.hmrClient.hotModulesMap.set(this.ownerPath, mod);
109
+ }
109
110
  }
110
111
  class HMRMessenger {
111
- constructor(connection) {
112
- this.connection = connection;
113
- this.queue = [];
114
- }
115
- send(message) {
116
- this.queue.push(message);
117
- this.flush();
118
- }
119
- flush() {
120
- if (this.connection.isReady()) {
121
- this.queue.forEach((msg) => this.connection.send(msg));
122
- this.queue = [];
123
- }
124
- }
112
+ constructor(connection) {
113
+ this.connection = connection;
114
+ this.queue = [];
115
+ }
116
+ send(message) {
117
+ this.queue.push(message);
118
+ this.flush();
119
+ }
120
+ flush() {
121
+ if (this.connection.isReady()) {
122
+ this.queue.forEach((msg) => this.connection.send(msg));
123
+ this.queue = [];
124
+ }
125
+ }
125
126
  }
126
127
  class HMRClient {
127
- constructor(logger, connection,
128
- // This allows implementing reloading via different methods depending on the environment
129
- importUpdatedModule) {
130
- this.logger = logger;
131
- this.importUpdatedModule = importUpdatedModule;
132
- this.hotModulesMap = new Map();
133
- this.disposeMap = new Map();
134
- this.pruneMap = new Map();
135
- this.dataMap = new Map();
136
- this.customListenersMap = new Map();
137
- this.ctxToListenersMap = new Map();
138
- this.updateQueue = [];
139
- this.pendingUpdateQueue = false;
140
- this.messenger = new HMRMessenger(connection);
141
- }
142
- async notifyListeners(event, data) {
143
- const cbs = this.customListenersMap.get(event);
144
- if (cbs) {
145
- await Promise.allSettled(cbs.map((cb) => cb(data)));
146
- }
147
- }
148
- clear() {
149
- this.hotModulesMap.clear();
150
- this.disposeMap.clear();
151
- this.pruneMap.clear();
152
- this.dataMap.clear();
153
- this.customListenersMap.clear();
154
- this.ctxToListenersMap.clear();
155
- }
156
- // After an HMR update, some modules are no longer imported on the page
157
- // but they may have left behind side effects that need to be cleaned up
158
- // (.e.g style injections)
159
- async prunePaths(paths) {
160
- await Promise.all(paths.map((path) => {
161
- const disposer = this.disposeMap.get(path);
162
- if (disposer)
163
- return disposer(this.dataMap.get(path));
164
- }));
165
- paths.forEach((path) => {
166
- const fn = this.pruneMap.get(path);
167
- if (fn) {
168
- fn(this.dataMap.get(path));
169
- }
170
- });
171
- }
172
- warnFailedUpdate(err, path) {
173
- if (!err.message.includes('fetch')) {
174
- this.logger.error(err);
175
- }
176
- this.logger.error(`[hmr] Failed to reload ${path}. ` +
177
- `This could be due to syntax errors or importing non-existent ` +
178
- `modules. (see errors above)`);
179
- }
180
- /**
181
- * buffer multiple hot updates triggered by the same src change
182
- * so that they are invoked in the same order they were sent.
183
- * (otherwise the order may be inconsistent because of the http request round trip)
184
- */
185
- async queueUpdate(payload) {
186
- this.updateQueue.push(this.fetchUpdate(payload));
187
- if (!this.pendingUpdateQueue) {
188
- this.pendingUpdateQueue = true;
189
- await Promise.resolve();
190
- this.pendingUpdateQueue = false;
191
- const loading = [...this.updateQueue];
192
- this.updateQueue = [];
193
- (await Promise.all(loading)).forEach((fn) => fn && fn());
194
- }
195
- }
196
- async fetchUpdate(update) {
197
- const { path, acceptedPath } = update;
198
- const mod = this.hotModulesMap.get(path);
199
- if (!mod) {
200
- // In a code-splitting project,
201
- // it is common that the hot-updating module is not loaded yet.
202
- // https://github.com/vitejs/vite/issues/721
203
- return;
204
- }
205
- let fetchedModule;
206
- const isSelfUpdate = path === acceptedPath;
207
- // determine the qualified callbacks before we re-import the modules
208
- const qualifiedCallbacks = mod.callbacks.filter(({ deps }) => deps.includes(acceptedPath));
209
- if (isSelfUpdate || qualifiedCallbacks.length > 0) {
210
- const disposer = this.disposeMap.get(acceptedPath);
211
- if (disposer)
212
- await disposer(this.dataMap.get(acceptedPath));
213
- try {
214
- fetchedModule = await this.importUpdatedModule(update);
215
- }
216
- catch (e) {
217
- this.warnFailedUpdate(e, acceptedPath);
218
- }
219
- }
220
- return () => {
221
- for (const { deps, fn } of qualifiedCallbacks) {
222
- fn(deps.map((dep) => (dep === acceptedPath ? fetchedModule : undefined)));
223
- }
224
- const loggedPath = isSelfUpdate ? path : `${acceptedPath} via ${path}`;
225
- this.logger.debug(`[vite] hot updated: ${loggedPath}`);
226
- };
128
+ constructor(logger, connection, importUpdatedModule) {
129
+ this.logger = logger;
130
+ this.importUpdatedModule = importUpdatedModule;
131
+ this.hotModulesMap = /* @__PURE__ */ new Map();
132
+ this.disposeMap = /* @__PURE__ */ new Map();
133
+ this.pruneMap = /* @__PURE__ */ new Map();
134
+ this.dataMap = /* @__PURE__ */ new Map();
135
+ this.customListenersMap = /* @__PURE__ */ new Map();
136
+ this.ctxToListenersMap = /* @__PURE__ */ new Map();
137
+ this.updateQueue = [];
138
+ this.pendingUpdateQueue = false;
139
+ this.messenger = new HMRMessenger(connection);
140
+ }
141
+ async notifyListeners(event, data) {
142
+ const cbs = this.customListenersMap.get(event);
143
+ if (cbs) {
144
+ await Promise.allSettled(cbs.map((cb) => cb(data)));
145
+ }
146
+ }
147
+ clear() {
148
+ this.hotModulesMap.clear();
149
+ this.disposeMap.clear();
150
+ this.pruneMap.clear();
151
+ this.dataMap.clear();
152
+ this.customListenersMap.clear();
153
+ this.ctxToListenersMap.clear();
154
+ }
155
+ // After an HMR update, some modules are no longer imported on the page
156
+ // but they may have left behind side effects that need to be cleaned up
157
+ // (.e.g style injections)
158
+ async prunePaths(paths) {
159
+ await Promise.all(
160
+ paths.map((path) => {
161
+ const disposer = this.disposeMap.get(path);
162
+ if (disposer) return disposer(this.dataMap.get(path));
163
+ })
164
+ );
165
+ paths.forEach((path) => {
166
+ const fn = this.pruneMap.get(path);
167
+ if (fn) {
168
+ fn(this.dataMap.get(path));
169
+ }
170
+ });
171
+ }
172
+ warnFailedUpdate(err, path) {
173
+ if (!err.message.includes("fetch")) {
174
+ this.logger.error(err);
175
+ }
176
+ this.logger.error(
177
+ `[hmr] Failed to reload ${path}. This could be due to syntax errors or importing non-existent modules. (see errors above)`
178
+ );
179
+ }
180
+ /**
181
+ * buffer multiple hot updates triggered by the same src change
182
+ * so that they are invoked in the same order they were sent.
183
+ * (otherwise the order may be inconsistent because of the http request round trip)
184
+ */
185
+ async queueUpdate(payload) {
186
+ this.updateQueue.push(this.fetchUpdate(payload));
187
+ if (!this.pendingUpdateQueue) {
188
+ this.pendingUpdateQueue = true;
189
+ await Promise.resolve();
190
+ this.pendingUpdateQueue = false;
191
+ const loading = [...this.updateQueue];
192
+ this.updateQueue = [];
193
+ (await Promise.all(loading)).forEach((fn) => fn && fn());
194
+ }
195
+ }
196
+ async fetchUpdate(update) {
197
+ const { path, acceptedPath } = update;
198
+ const mod = this.hotModulesMap.get(path);
199
+ if (!mod) {
200
+ return;
201
+ }
202
+ let fetchedModule;
203
+ const isSelfUpdate = path === acceptedPath;
204
+ const qualifiedCallbacks = mod.callbacks.filter(
205
+ ({ deps }) => deps.includes(acceptedPath)
206
+ );
207
+ if (isSelfUpdate || qualifiedCallbacks.length > 0) {
208
+ const disposer = this.disposeMap.get(acceptedPath);
209
+ if (disposer) await disposer(this.dataMap.get(acceptedPath));
210
+ try {
211
+ fetchedModule = await this.importUpdatedModule(update);
212
+ } catch (e) {
213
+ this.warnFailedUpdate(e, acceptedPath);
214
+ }
227
215
  }
216
+ return () => {
217
+ for (const { deps, fn } of qualifiedCallbacks) {
218
+ fn(
219
+ deps.map((dep) => dep === acceptedPath ? fetchedModule : void 0)
220
+ );
221
+ }
222
+ const loggedPath = isSelfUpdate ? path : `${acceptedPath} via ${path}`;
223
+ this.logger.debug(`[vite] hot updated: ${loggedPath}`);
224
+ };
225
+ }
228
226
  }
229
227
 
230
228
  const hmrConfigName = __HMR_CONFIG_NAME__;
231
- const base$1 = __BASE__ || '/';
232
- // Create an element with provided attributes and optional children
229
+ const base$1 = __BASE__ || "/";
233
230
  function h(e, attrs = {}, ...children) {
234
- const elem = document.createElement(e);
235
- for (const [k, v] of Object.entries(attrs)) {
236
- elem.setAttribute(k, v);
237
- }
238
- elem.append(...children);
239
- return elem;
240
- }
241
- // set :host styles to make playwright detect the element as visible
242
- const templateStyle = /*css*/ `
231
+ const elem = document.createElement(e);
232
+ for (const [k, v] of Object.entries(attrs)) {
233
+ elem.setAttribute(k, v);
234
+ }
235
+ elem.append(...children);
236
+ return elem;
237
+ }
238
+ const templateStyle = (
239
+ /*css*/
240
+ `
243
241
  :host {
244
242
  position: fixed;
245
243
  top: 0;
@@ -379,445 +377,449 @@ kbd {
379
377
  border-color: rgb(54, 57, 64);
380
378
  border-image: initial;
381
379
  }
382
- `;
383
- // Error Template
384
- const createTemplate = () => h('div', { class: 'backdrop', part: 'backdrop' }, h('div', { class: 'window', part: 'window' }, h('pre', { class: 'message', part: 'message' }, h('span', { class: 'plugin', part: 'plugin' }), h('span', { class: 'message-body', part: 'message-body' })), h('pre', { class: 'file', part: 'file' }), h('pre', { class: 'frame', part: 'frame' }), h('pre', { class: 'stack', part: 'stack' }), h('div', { class: 'tip', part: 'tip' }, 'Click outside, press ', h('kbd', {}, 'Esc'), ' key, or fix the code to dismiss.', h('br'), 'You can also disable this overlay by setting ', h('code', { part: 'config-option-name' }, 'server.hmr.overlay'), ' to ', h('code', { part: 'config-option-value' }, 'false'), ' in ', h('code', { part: 'config-file-name' }, hmrConfigName), '.')), h('style', {}, templateStyle));
380
+ `
381
+ );
382
+ const createTemplate = () => h(
383
+ "div",
384
+ { class: "backdrop", part: "backdrop" },
385
+ h(
386
+ "div",
387
+ { class: "window", part: "window" },
388
+ h(
389
+ "pre",
390
+ { class: "message", part: "message" },
391
+ h("span", { class: "plugin", part: "plugin" }),
392
+ h("span", { class: "message-body", part: "message-body" })
393
+ ),
394
+ h("pre", { class: "file", part: "file" }),
395
+ h("pre", { class: "frame", part: "frame" }),
396
+ h("pre", { class: "stack", part: "stack" }),
397
+ h(
398
+ "div",
399
+ { class: "tip", part: "tip" },
400
+ "Click outside, press ",
401
+ h("kbd", {}, "Esc"),
402
+ " key, or fix the code to dismiss.",
403
+ h("br"),
404
+ "You can also disable this overlay by setting ",
405
+ h("code", { part: "config-option-name" }, "server.hmr.overlay"),
406
+ " to ",
407
+ h("code", { part: "config-option-value" }, "false"),
408
+ " in ",
409
+ h("code", { part: "config-file-name" }, hmrConfigName),
410
+ "."
411
+ )
412
+ ),
413
+ h("style", {}, templateStyle)
414
+ );
385
415
  const fileRE = /(?:[a-zA-Z]:\\|\/).*?:\d+:\d+/g;
386
416
  const codeframeRE = /^(?:>?\s*\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm;
387
- // Allow `ErrorOverlay` to extend `HTMLElement` even in environments where
388
- // `HTMLElement` was not originally defined.
389
417
  const { HTMLElement = class {
390
418
  } } = globalThis;
391
419
  class ErrorOverlay extends HTMLElement {
392
- constructor(err, links = true) {
393
- var _a;
394
- super();
395
- this.root = this.attachShadow({ mode: 'open' });
396
- this.root.appendChild(createTemplate());
397
- codeframeRE.lastIndex = 0;
398
- const hasFrame = err.frame && codeframeRE.test(err.frame);
399
- const message = hasFrame
400
- ? err.message.replace(codeframeRE, '')
401
- : err.message;
402
- if (err.plugin) {
403
- this.text('.plugin', `[plugin:${err.plugin}] `);
404
- }
405
- this.text('.message-body', message.trim());
406
- const [file] = (((_a = err.loc) === null || _a === void 0 ? void 0 : _a.file) || err.id || 'unknown file').split(`?`);
407
- if (err.loc) {
408
- this.text('.file', `${file}:${err.loc.line}:${err.loc.column}`, links);
409
- }
410
- else if (err.id) {
411
- this.text('.file', file);
412
- }
413
- if (hasFrame) {
414
- this.text('.frame', err.frame.trim());
415
- }
416
- this.text('.stack', err.stack, links);
417
- this.root.querySelector('.window').addEventListener('click', (e) => {
418
- e.stopPropagation();
419
- });
420
- this.addEventListener('click', () => {
421
- this.close();
422
- });
423
- this.closeOnEsc = (e) => {
424
- if (e.key === 'Escape' || e.code === 'Escape') {
425
- this.close();
426
- }
427
- };
428
- document.addEventListener('keydown', this.closeOnEsc);
429
- }
430
- text(selector, text, linkFiles = false) {
431
- const el = this.root.querySelector(selector);
432
- if (!linkFiles) {
433
- el.textContent = text;
434
- }
435
- else {
436
- let curIndex = 0;
437
- let match;
438
- fileRE.lastIndex = 0;
439
- while ((match = fileRE.exec(text))) {
440
- const { 0: file, index } = match;
441
- if (index != null) {
442
- const frag = text.slice(curIndex, index);
443
- el.appendChild(document.createTextNode(frag));
444
- const link = document.createElement('a');
445
- link.textContent = file;
446
- link.className = 'file-link';
447
- link.onclick = () => {
448
- fetch(new URL(`${base$1}__open-in-editor?file=${encodeURIComponent(file)}`, import.meta.url));
449
- };
450
- el.appendChild(link);
451
- curIndex += frag.length + file.length;
452
- }
453
- }
420
+ constructor(err, links = true) {
421
+ super();
422
+ this.root = this.attachShadow({ mode: "open" });
423
+ this.root.appendChild(createTemplate());
424
+ codeframeRE.lastIndex = 0;
425
+ const hasFrame = err.frame && codeframeRE.test(err.frame);
426
+ const message = hasFrame ? err.message.replace(codeframeRE, "") : err.message;
427
+ if (err.plugin) {
428
+ this.text(".plugin", `[plugin:${err.plugin}] `);
429
+ }
430
+ this.text(".message-body", message.trim());
431
+ const [file] = (err.loc?.file || err.id || "unknown file").split(`?`);
432
+ if (err.loc) {
433
+ this.text(".file", `${file}:${err.loc.line}:${err.loc.column}`, links);
434
+ } else if (err.id) {
435
+ this.text(".file", file);
436
+ }
437
+ if (hasFrame) {
438
+ this.text(".frame", err.frame.trim());
439
+ }
440
+ this.text(".stack", err.stack, links);
441
+ this.root.querySelector(".window").addEventListener("click", (e) => {
442
+ e.stopPropagation();
443
+ });
444
+ this.addEventListener("click", () => {
445
+ this.close();
446
+ });
447
+ this.closeOnEsc = (e) => {
448
+ if (e.key === "Escape" || e.code === "Escape") {
449
+ this.close();
450
+ }
451
+ };
452
+ document.addEventListener("keydown", this.closeOnEsc);
453
+ }
454
+ text(selector, text, linkFiles = false) {
455
+ const el = this.root.querySelector(selector);
456
+ if (!linkFiles) {
457
+ el.textContent = text;
458
+ } else {
459
+ let curIndex = 0;
460
+ let match;
461
+ fileRE.lastIndex = 0;
462
+ while (match = fileRE.exec(text)) {
463
+ const { 0: file, index } = match;
464
+ if (index != null) {
465
+ const frag = text.slice(curIndex, index);
466
+ el.appendChild(document.createTextNode(frag));
467
+ const link = document.createElement("a");
468
+ link.textContent = file;
469
+ link.className = "file-link";
470
+ link.onclick = () => {
471
+ fetch(
472
+ new URL(
473
+ `${base$1}__open-in-editor?file=${encodeURIComponent(file)}`,
474
+ import.meta.url
475
+ )
476
+ );
477
+ };
478
+ el.appendChild(link);
479
+ curIndex += frag.length + file.length;
454
480
  }
481
+ }
455
482
  }
456
- close() {
457
- var _a;
458
- (_a = this.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this);
459
- document.removeEventListener('keydown', this.closeOnEsc);
460
- }
483
+ }
484
+ close() {
485
+ this.parentNode?.removeChild(this);
486
+ document.removeEventListener("keydown", this.closeOnEsc);
487
+ }
461
488
  }
462
- const overlayId = 'vite-error-overlay';
463
- const { customElements } = globalThis; // Ensure `customElements` is defined before the next line.
489
+ const overlayId = "vite-error-overlay";
490
+ const { customElements } = globalThis;
464
491
  if (customElements && !customElements.get(overlayId)) {
465
- customElements.define(overlayId, ErrorOverlay);
492
+ customElements.define(overlayId, ErrorOverlay);
466
493
  }
467
494
 
468
- var _a;
469
- console.debug('[vite] connecting...');
495
+ console.debug("[vite] connecting...");
470
496
  const importMetaUrl = new URL(import.meta.url);
471
- // use server configuration, then fallback to inference
472
497
  const serverHost = __SERVER_HOST__;
473
- const socketProtocol = __HMR_PROTOCOL__ || (importMetaUrl.protocol === 'https:' ? 'wss' : 'ws');
498
+ const socketProtocol = __HMR_PROTOCOL__ || (importMetaUrl.protocol === "https:" ? "wss" : "ws");
474
499
  const hmrPort = __HMR_PORT__;
475
500
  const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}`;
476
501
  const directSocketHost = __HMR_DIRECT_TARGET__;
477
- const base = __BASE__ || '/';
502
+ const base = __BASE__ || "/";
478
503
  let socket;
479
504
  try {
480
- let fallback;
481
- // only use fallback when port is inferred to prevent confusion
482
- if (!hmrPort) {
483
- fallback = () => {
484
- // fallback to connecting directly to the hmr server
485
- // for servers which does not support proxying websocket
486
- socket = setupWebSocket(socketProtocol, directSocketHost, () => {
487
- const currentScriptHostURL = new URL(import.meta.url);
488
- const currentScriptHost = currentScriptHostURL.host +
489
- currentScriptHostURL.pathname.replace(/@vite\/client$/, '');
490
- console.error('[vite] failed to connect to websocket.\n' +
491
- 'your current setup:\n' +
492
- ` (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)\n` +
493
- ` (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)\n` +
494
- 'Check out your Vite / network configuration and https://vitejs.dev/config/server-options.html#server-hmr .');
495
- });
496
- socket.addEventListener('open', () => {
497
- console.info('[vite] Direct websocket connection fallback. Check out https://vitejs.dev/config/server-options.html#server-hmr to remove the previous connection error.');
498
- }, { once: true });
499
- };
500
- }
501
- socket = setupWebSocket(socketProtocol, socketHost, fallback);
502
- }
503
- catch (error) {
504
- console.error(`[vite] failed to connect to websocket (${error}). `);
505
+ let fallback;
506
+ if (!hmrPort) {
507
+ fallback = () => {
508
+ socket = setupWebSocket(socketProtocol, directSocketHost, () => {
509
+ const currentScriptHostURL = new URL(import.meta.url);
510
+ const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
511
+ console.error(
512
+ `[vite] failed to connect to websocket.
513
+ your current setup:
514
+ (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)
515
+ (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)
516
+ Check out your Vite / network configuration and https://vitejs.dev/config/server-options.html#server-hmr .`
517
+ );
518
+ });
519
+ socket.addEventListener(
520
+ "open",
521
+ () => {
522
+ console.info(
523
+ "[vite] Direct websocket connection fallback. Check out https://vitejs.dev/config/server-options.html#server-hmr to remove the previous connection error."
524
+ );
525
+ },
526
+ { once: true }
527
+ );
528
+ };
529
+ }
530
+ socket = setupWebSocket(socketProtocol, socketHost, fallback);
531
+ } catch (error) {
532
+ console.error(`[vite] failed to connect to websocket (${error}). `);
505
533
  }
506
534
  function setupWebSocket(protocol, hostAndPath, onCloseWithoutOpen) {
507
- const socket = new WebSocket(`${protocol}://${hostAndPath}`, 'vite-hmr');
508
- let isOpened = false;
509
- socket.addEventListener('open', () => {
510
- isOpened = true;
511
- notifyListeners('vite:ws:connect', { webSocket: socket });
512
- }, { once: true });
513
- // Listen for messages
514
- socket.addEventListener('message', async ({ data }) => {
515
- handleMessage(JSON.parse(data));
516
- });
517
- // ping server
518
- socket.addEventListener('close', async ({ wasClean }) => {
519
- if (wasClean)
520
- return;
521
- if (!isOpened && onCloseWithoutOpen) {
522
- onCloseWithoutOpen();
523
- return;
524
- }
525
- notifyListeners('vite:ws:disconnect', { webSocket: socket });
526
- if (hasDocument) {
527
- console.log(`[vite] server connection lost. polling for restart...`);
528
- await waitForSuccessfulPing(protocol, hostAndPath);
529
- location.reload();
530
- }
531
- });
532
- return socket;
535
+ const socket2 = new WebSocket(`${protocol}://${hostAndPath}`, "vite-hmr");
536
+ let isOpened = false;
537
+ socket2.addEventListener(
538
+ "open",
539
+ () => {
540
+ isOpened = true;
541
+ notifyListeners("vite:ws:connect", { webSocket: socket2 });
542
+ },
543
+ { once: true }
544
+ );
545
+ socket2.addEventListener("message", async ({ data }) => {
546
+ handleMessage(JSON.parse(data));
547
+ });
548
+ socket2.addEventListener("close", async ({ wasClean }) => {
549
+ if (wasClean) return;
550
+ if (!isOpened && onCloseWithoutOpen) {
551
+ onCloseWithoutOpen();
552
+ return;
553
+ }
554
+ notifyListeners("vite:ws:disconnect", { webSocket: socket2 });
555
+ if (hasDocument) {
556
+ console.log(`[vite] server connection lost. Polling for restart...`);
557
+ await waitForSuccessfulPing(protocol, hostAndPath);
558
+ location.reload();
559
+ }
560
+ });
561
+ return socket2;
533
562
  }
534
563
  function cleanUrl(pathname) {
535
- const url = new URL(pathname, 'http://vitejs.dev');
536
- url.searchParams.delete('direct');
537
- return url.pathname + url.search;
564
+ const url = new URL(pathname, "http://vitejs.dev");
565
+ url.searchParams.delete("direct");
566
+ return url.pathname + url.search;
538
567
  }
539
568
  let isFirstUpdate = true;
540
- const outdatedLinkTags = new WeakSet();
569
+ const outdatedLinkTags = /* @__PURE__ */ new WeakSet();
541
570
  const debounceReload = (time) => {
542
- let timer;
543
- return () => {
544
- if (timer) {
545
- clearTimeout(timer);
546
- timer = null;
547
- }
548
- timer = setTimeout(() => {
549
- location.reload();
550
- }, time);
551
- };
571
+ let timer;
572
+ return () => {
573
+ if (timer) {
574
+ clearTimeout(timer);
575
+ timer = null;
576
+ }
577
+ timer = setTimeout(() => {
578
+ location.reload();
579
+ }, time);
580
+ };
552
581
  };
553
582
  const pageReload = debounceReload(50);
554
- const hmrClient = new HMRClient(console, {
583
+ const hmrClient = new HMRClient(
584
+ console,
585
+ {
555
586
  isReady: () => socket && socket.readyState === 1,
556
- send: (message) => socket.send(message),
557
- }, async function importUpdatedModule({ acceptedPath, timestamp, explicitImportRequired, isWithinCircularImport, }) {
587
+ send: (message) => socket.send(message)
588
+ },
589
+ async function importUpdatedModule({
590
+ acceptedPath,
591
+ timestamp,
592
+ explicitImportRequired,
593
+ isWithinCircularImport
594
+ }) {
558
595
  const [acceptedPathWithoutQuery, query] = acceptedPath.split(`?`);
559
596
  const importPromise = import(
560
- /* @vite-ignore */
561
- base +
562
- acceptedPathWithoutQuery.slice(1) +
563
- `?${explicitImportRequired ? 'import&' : ''}t=${timestamp}${query ? `&${query}` : ''}`);
597
+ /* @vite-ignore */
598
+ base + acceptedPathWithoutQuery.slice(1) + `?${explicitImportRequired ? "import&" : ""}t=${timestamp}${query ? `&${query}` : ""}`
599
+ );
564
600
  if (isWithinCircularImport) {
565
- importPromise.catch(() => {
566
- console.info(`[hmr] ${acceptedPath} failed to apply HMR as it's within a circular import. Reloading page to reset the execution order. ` +
567
- `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.`);
568
- pageReload();
569
- });
601
+ importPromise.catch(() => {
602
+ console.info(
603
+ `[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.`
604
+ );
605
+ pageReload();
606
+ });
570
607
  }
571
608
  return await importPromise;
572
- });
609
+ }
610
+ );
573
611
  async function handleMessage(payload) {
574
- switch (payload.type) {
575
- case 'connected':
576
- console.debug(`[vite] connected.`);
577
- hmrClient.messenger.flush();
578
- // proxy(nginx, docker) hmr ws maybe caused timeout,
579
- // so send ping package let ws keep alive.
580
- setInterval(() => {
581
- if (socket.readyState === socket.OPEN) {
582
- socket.send('{"type":"ping"}');
583
- }
584
- }, __HMR_TIMEOUT__);
585
- break;
586
- case 'update':
587
- notifyListeners('vite:beforeUpdate', payload);
588
- if (hasDocument) {
589
- // if this is the first update and there's already an error overlay, it
590
- // means the page opened with existing server compile error and the whole
591
- // module script failed to load (since one of the nested imports is 500).
592
- // in this case a normal update won't work and a full reload is needed.
593
- if (isFirstUpdate && hasErrorOverlay()) {
594
- window.location.reload();
595
- return;
596
- }
597
- else {
598
- if (enableOverlay) {
599
- clearErrorOverlay();
600
- }
601
- isFirstUpdate = false;
602
- }
603
- }
604
- await Promise.all(payload.updates.map(async (update) => {
605
- if (update.type === 'js-update') {
606
- return hmrClient.queueUpdate(update);
607
- }
608
- // css-update
609
- // this is only sent when a css file referenced with <link> is updated
610
- const { path, timestamp } = update;
611
- const searchUrl = cleanUrl(path);
612
- // can't use querySelector with `[href*=]` here since the link may be
613
- // using relative paths so we need to use link.href to grab the full
614
- // URL for the include check.
615
- const el = Array.from(document.querySelectorAll('link')).find((e) => !outdatedLinkTags.has(e) && cleanUrl(e.href).includes(searchUrl));
616
- if (!el) {
617
- return;
618
- }
619
- const newPath = `${base}${searchUrl.slice(1)}${searchUrl.includes('?') ? '&' : '?'}t=${timestamp}`;
620
- // rather than swapping the href on the existing tag, we will
621
- // create a new link tag. Once the new stylesheet has loaded we
622
- // will remove the existing link tag. This removes a Flash Of
623
- // Unstyled Content that can occur when swapping out the tag href
624
- // directly, as the new stylesheet has not yet been loaded.
625
- return new Promise((resolve) => {
626
- const newLinkTag = el.cloneNode();
627
- newLinkTag.href = new URL(newPath, el.href).href;
628
- const removeOldEl = () => {
629
- el.remove();
630
- console.debug(`[vite] css hot updated: ${searchUrl}`);
631
- resolve();
632
- };
633
- newLinkTag.addEventListener('load', removeOldEl);
634
- newLinkTag.addEventListener('error', removeOldEl);
635
- outdatedLinkTags.add(el);
636
- el.after(newLinkTag);
637
- });
638
- }));
639
- notifyListeners('vite:afterUpdate', payload);
640
- break;
641
- case 'custom': {
642
- notifyListeners(payload.event, payload.data);
643
- break;
612
+ switch (payload.type) {
613
+ case "connected":
614
+ console.debug(`[vite] connected.`);
615
+ hmrClient.messenger.flush();
616
+ setInterval(() => {
617
+ if (socket.readyState === socket.OPEN) {
618
+ socket.send('{"type":"ping"}');
619
+ }
620
+ }, __HMR_TIMEOUT__);
621
+ break;
622
+ case "update":
623
+ notifyListeners("vite:beforeUpdate", payload);
624
+ if (hasDocument) {
625
+ if (isFirstUpdate && hasErrorOverlay()) {
626
+ window.location.reload();
627
+ return;
628
+ } else {
629
+ if (enableOverlay) {
630
+ clearErrorOverlay();
631
+ }
632
+ isFirstUpdate = false;
644
633
  }
645
- case 'full-reload':
646
- notifyListeners('vite:beforeFullReload', payload);
647
- if (hasDocument) {
648
- if (payload.path && payload.path.endsWith('.html')) {
649
- // if html file is edited, only reload the page if the browser is
650
- // currently on that page.
651
- const pagePath = decodeURI(location.pathname);
652
- const payloadPath = base + payload.path.slice(1);
653
- if (pagePath === payloadPath ||
654
- payload.path === '/index.html' ||
655
- (pagePath.endsWith('/') && pagePath + 'index.html' === payloadPath)) {
656
- pageReload();
657
- }
658
- return;
659
- }
660
- else {
661
- pageReload();
662
- }
663
- }
664
- break;
665
- case 'prune':
666
- notifyListeners('vite:beforePrune', payload);
667
- await hmrClient.prunePaths(payload.paths);
668
- break;
669
- case 'error': {
670
- notifyListeners('vite:error', payload);
671
- if (hasDocument) {
672
- const err = payload.err;
673
- if (enableOverlay) {
674
- createErrorOverlay(err);
675
- }
676
- else {
677
- console.error(`[vite] Internal Server Error\n${err.message}\n${err.stack}`);
678
- }
679
- }
680
- break;
634
+ }
635
+ await Promise.all(
636
+ payload.updates.map(async (update) => {
637
+ if (update.type === "js-update") {
638
+ return hmrClient.queueUpdate(update);
639
+ }
640
+ const { path, timestamp } = update;
641
+ const searchUrl = cleanUrl(path);
642
+ const el = Array.from(
643
+ document.querySelectorAll("link")
644
+ ).find(
645
+ (e) => !outdatedLinkTags.has(e) && cleanUrl(e.href).includes(searchUrl)
646
+ );
647
+ if (!el) {
648
+ return;
649
+ }
650
+ const newPath = `${base}${searchUrl.slice(1)}${searchUrl.includes("?") ? "&" : "?"}t=${timestamp}`;
651
+ return new Promise((resolve) => {
652
+ const newLinkTag = el.cloneNode();
653
+ newLinkTag.href = new URL(newPath, el.href).href;
654
+ const removeOldEl = () => {
655
+ el.remove();
656
+ console.debug(`[vite] css hot updated: ${searchUrl}`);
657
+ resolve();
658
+ };
659
+ newLinkTag.addEventListener("load", removeOldEl);
660
+ newLinkTag.addEventListener("error", removeOldEl);
661
+ outdatedLinkTags.add(el);
662
+ el.after(newLinkTag);
663
+ });
664
+ })
665
+ );
666
+ notifyListeners("vite:afterUpdate", payload);
667
+ break;
668
+ case "custom": {
669
+ notifyListeners(payload.event, payload.data);
670
+ break;
671
+ }
672
+ case "full-reload":
673
+ notifyListeners("vite:beforeFullReload", payload);
674
+ if (hasDocument) {
675
+ if (payload.path && payload.path.endsWith(".html")) {
676
+ const pagePath = decodeURI(location.pathname);
677
+ const payloadPath = base + payload.path.slice(1);
678
+ if (pagePath === payloadPath || payload.path === "/index.html" || pagePath.endsWith("/") && pagePath + "index.html" === payloadPath) {
679
+ pageReload();
680
+ }
681
+ return;
682
+ } else {
683
+ pageReload();
681
684
  }
682
- default: {
683
- const check = payload;
684
- return check;
685
+ }
686
+ break;
687
+ case "prune":
688
+ notifyListeners("vite:beforePrune", payload);
689
+ await hmrClient.prunePaths(payload.paths);
690
+ break;
691
+ case "error": {
692
+ notifyListeners("vite:error", payload);
693
+ if (hasDocument) {
694
+ const err = payload.err;
695
+ if (enableOverlay) {
696
+ createErrorOverlay(err);
697
+ } else {
698
+ console.error(
699
+ `[vite] Internal Server Error
700
+ ${err.message}
701
+ ${err.stack}`
702
+ );
685
703
  }
704
+ }
705
+ break;
706
+ }
707
+ default: {
708
+ const check = payload;
709
+ return check;
686
710
  }
711
+ }
687
712
  }
688
713
  function notifyListeners(event, data) {
689
- hmrClient.notifyListeners(event, data);
714
+ hmrClient.notifyListeners(event, data);
690
715
  }
691
716
  const enableOverlay = __HMR_ENABLE_OVERLAY__;
692
- const hasDocument = 'document' in globalThis;
717
+ const hasDocument = "document" in globalThis;
693
718
  function createErrorOverlay(err) {
694
- clearErrorOverlay();
695
- document.body.appendChild(new ErrorOverlay(err));
719
+ clearErrorOverlay();
720
+ document.body.appendChild(new ErrorOverlay(err));
696
721
  }
697
722
  function clearErrorOverlay() {
698
- document.querySelectorAll(overlayId).forEach((n) => n.close());
723
+ document.querySelectorAll(overlayId).forEach((n) => n.close());
699
724
  }
700
725
  function hasErrorOverlay() {
701
- return document.querySelectorAll(overlayId).length;
702
- }
703
- async function waitForSuccessfulPing(socketProtocol, hostAndPath, ms = 1000) {
704
- const pingHostProtocol = socketProtocol === 'wss' ? 'https' : 'http';
705
- const ping = async () => {
706
- // A fetch on a websocket URL will return a successful promise with status 400,
707
- // but will reject a networking error.
708
- // When running on middleware mode, it returns status 426, and an cors error happens if mode is not no-cors
709
- try {
710
- await fetch(`${pingHostProtocol}://${hostAndPath}`, {
711
- mode: 'no-cors',
712
- headers: {
713
- // Custom headers won't be included in a request with no-cors so (ab)use one of the
714
- // safelisted headers to identify the ping request
715
- Accept: 'text/x-vite-ping',
716
- },
717
- });
718
- return true;
719
- }
720
- catch { }
721
- return false;
722
- };
723
- if (await ping()) {
724
- return;
725
- }
726
- await wait(ms);
727
- // eslint-disable-next-line no-constant-condition
728
- while (true) {
729
- if (document.visibilityState === 'visible') {
730
- if (await ping()) {
731
- break;
732
- }
733
- await wait(ms);
734
- }
735
- else {
736
- await waitForWindowShow();
726
+ return document.querySelectorAll(overlayId).length;
727
+ }
728
+ async function waitForSuccessfulPing(socketProtocol2, hostAndPath, ms = 1e3) {
729
+ const pingHostProtocol = socketProtocol2 === "wss" ? "https" : "http";
730
+ const ping = async () => {
731
+ try {
732
+ await fetch(`${pingHostProtocol}://${hostAndPath}`, {
733
+ mode: "no-cors",
734
+ headers: {
735
+ // Custom headers won't be included in a request with no-cors so (ab)use one of the
736
+ // safelisted headers to identify the ping request
737
+ Accept: "text/x-vite-ping"
737
738
  }
738
- }
739
+ });
740
+ return true;
741
+ } catch {
742
+ }
743
+ return false;
744
+ };
745
+ if (await ping()) {
746
+ return;
747
+ }
748
+ await wait(ms);
749
+ while (true) {
750
+ if (document.visibilityState === "visible") {
751
+ if (await ping()) {
752
+ break;
753
+ }
754
+ await wait(ms);
755
+ } else {
756
+ await waitForWindowShow();
757
+ }
758
+ }
739
759
  }
740
760
  function wait(ms) {
741
- return new Promise((resolve) => setTimeout(resolve, ms));
761
+ return new Promise((resolve) => setTimeout(resolve, ms));
742
762
  }
743
763
  function waitForWindowShow() {
744
- return new Promise((resolve) => {
745
- const onChange = async () => {
746
- if (document.visibilityState === 'visible') {
747
- resolve();
748
- document.removeEventListener('visibilitychange', onChange);
749
- }
750
- };
751
- document.addEventListener('visibilitychange', onChange);
752
- });
764
+ return new Promise((resolve) => {
765
+ const onChange = async () => {
766
+ if (document.visibilityState === "visible") {
767
+ resolve();
768
+ document.removeEventListener("visibilitychange", onChange);
769
+ }
770
+ };
771
+ document.addEventListener("visibilitychange", onChange);
772
+ });
753
773
  }
754
- const sheetsMap = new Map();
755
- // collect existing style elements that may have been inserted during SSR
756
- // to avoid FOUC or duplicate styles
757
- if ('document' in globalThis) {
758
- document
759
- .querySelectorAll('style[data-vite-dev-id]')
760
- .forEach((el) => {
761
- sheetsMap.set(el.getAttribute('data-vite-dev-id'), el);
762
- });
774
+ const sheetsMap = /* @__PURE__ */ new Map();
775
+ if ("document" in globalThis) {
776
+ document.querySelectorAll("style[data-vite-dev-id]").forEach((el) => {
777
+ sheetsMap.set(el.getAttribute("data-vite-dev-id"), el);
778
+ });
763
779
  }
764
- const cspNonce = 'document' in globalThis
765
- ? (_a = document.querySelector('meta[property=csp-nonce]')) === null || _a === void 0 ? void 0 : _a.nonce
766
- : undefined;
767
- // all css imports should be inserted at the same position
768
- // because after build it will be a single css file
780
+ const cspNonce = "document" in globalThis ? document.querySelector("meta[property=csp-nonce]")?.nonce : void 0;
769
781
  let lastInsertedStyle;
770
782
  function updateStyle(id, content) {
771
- let style = sheetsMap.get(id);
772
- if (!style) {
773
- style = document.createElement('style');
774
- style.setAttribute('type', 'text/css');
775
- style.setAttribute('data-vite-dev-id', id);
776
- style.textContent = content;
777
- if (cspNonce) {
778
- style.setAttribute('nonce', cspNonce);
779
- }
780
- if (!lastInsertedStyle) {
781
- document.head.appendChild(style);
782
- // reset lastInsertedStyle after async
783
- // because dynamically imported css will be splitted into a different file
784
- setTimeout(() => {
785
- lastInsertedStyle = undefined;
786
- }, 0);
787
- }
788
- else {
789
- lastInsertedStyle.insertAdjacentElement('afterend', style);
790
- }
791
- lastInsertedStyle = style;
792
- }
793
- else {
794
- style.textContent = content;
795
- }
796
- sheetsMap.set(id, style);
783
+ let style = sheetsMap.get(id);
784
+ if (!style) {
785
+ style = document.createElement("style");
786
+ style.setAttribute("type", "text/css");
787
+ style.setAttribute("data-vite-dev-id", id);
788
+ style.textContent = content;
789
+ if (cspNonce) {
790
+ style.setAttribute("nonce", cspNonce);
791
+ }
792
+ if (!lastInsertedStyle) {
793
+ document.head.appendChild(style);
794
+ setTimeout(() => {
795
+ lastInsertedStyle = void 0;
796
+ }, 0);
797
+ } else {
798
+ lastInsertedStyle.insertAdjacentElement("afterend", style);
799
+ }
800
+ lastInsertedStyle = style;
801
+ } else {
802
+ style.textContent = content;
803
+ }
804
+ sheetsMap.set(id, style);
797
805
  }
798
806
  function removeStyle(id) {
799
- const style = sheetsMap.get(id);
800
- if (style) {
801
- document.head.removeChild(style);
802
- sheetsMap.delete(id);
803
- }
807
+ const style = sheetsMap.get(id);
808
+ if (style) {
809
+ document.head.removeChild(style);
810
+ sheetsMap.delete(id);
811
+ }
804
812
  }
805
813
  function createHotContext(ownerPath) {
806
- return new HMRContext(hmrClient, ownerPath);
814
+ return new HMRContext(hmrClient, ownerPath);
807
815
  }
808
- /**
809
- * urls here are dynamic import() urls that couldn't be statically analyzed
810
- */
811
816
  function injectQuery(url, queryToInject) {
812
- // skip urls that won't be handled by vite
813
- if (url[0] !== '.' && url[0] !== '/') {
814
- return url;
815
- }
816
- // can't use pathname from URL since it may be relative like ../
817
- const pathname = url.replace(/[?#].*$/, '');
818
- const { search, hash } = new URL(url, 'http://vitejs.dev');
819
- return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ''}${hash || ''}`;
817
+ if (url[0] !== "." && url[0] !== "/") {
818
+ return url;
819
+ }
820
+ const pathname = url.replace(/[?#].*$/, "");
821
+ const { search, hash } = new URL(url, "http://vitejs.dev");
822
+ return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ""}${hash || ""}`;
820
823
  }
821
824
 
822
825
  export { ErrorOverlay, createHotContext, injectQuery, removeStyle, updateStyle };
823
- //# sourceMappingURL=client.mjs.map