bundledDevClient.mjs 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606
  1. import { DevRuntime } from "rolldown/experimental/runtime";
  2. import "@vite/env";
  3. //#region ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/non-secure/index.js
  4. let urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
  5. let nanoid = (size = 21) => {
  6. let id = "";
  7. let i = size | 0;
  8. while (i-- > 0) id += urlAlphabet[Math.random() * 64 | 0];
  9. return id;
  10. };
  11. //#endregion
  12. //#region \0@oxc-project+runtime@0.151.0/helpers/esm/typeof.js
  13. function _typeof(o) {
  14. "@babel/helpers - typeof";
  15. return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
  16. return typeof o;
  17. } : function(o) {
  18. return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
  19. }, _typeof(o);
  20. }
  21. //#endregion
  22. //#region \0@oxc-project+runtime@0.151.0/helpers/esm/toPrimitive.js
  23. function toPrimitive(t, r) {
  24. if ("object" != _typeof(t) || !t) return t;
  25. var e = t[Symbol.toPrimitive];
  26. if (void 0 !== e) {
  27. var i = e.call(t, r || "default");
  28. if ("object" != _typeof(i)) return i;
  29. throw new TypeError("@@toPrimitive must return a primitive value.");
  30. }
  31. return ("string" === r ? String : Number)(t);
  32. }
  33. //#endregion
  34. //#region \0@oxc-project+runtime@0.151.0/helpers/esm/toPropertyKey.js
  35. function toPropertyKey(t) {
  36. var i = toPrimitive(t, "string");
  37. return "symbol" == _typeof(i) ? i : i + "";
  38. }
  39. //#endregion
  40. //#region \0@oxc-project+runtime@0.151.0/helpers/esm/defineProperty.js
  41. function _defineProperty(e, r, t) {
  42. return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
  43. value: t,
  44. enumerable: !0,
  45. configurable: !0,
  46. writable: !0
  47. }) : e[r] = t, e;
  48. }
  49. //#endregion
  50. //#region src/shared/hmr.ts
  51. var HMRContext = class {
  52. constructor(hmrClient, ownerPath) {
  53. this.hmrClient = hmrClient;
  54. this.ownerPath = ownerPath;
  55. _defineProperty(this, "newListeners", void 0);
  56. if (!hmrClient.dataMap.has(ownerPath)) hmrClient.dataMap.set(ownerPath, {});
  57. const mod = hmrClient.hotModulesMap.get(ownerPath);
  58. if (mod) mod.callbacks = [];
  59. const staleListeners = hmrClient.ctxToListenersMap.get(ownerPath);
  60. if (staleListeners) for (const [event, staleFns] of staleListeners) {
  61. const listeners = hmrClient.customListenersMap.get(event);
  62. if (listeners) hmrClient.customListenersMap.set(event, listeners.filter((l) => !staleFns.includes(l)));
  63. }
  64. this.newListeners = /* @__PURE__ */ new Map();
  65. hmrClient.ctxToListenersMap.set(ownerPath, this.newListeners);
  66. }
  67. get data() {
  68. return this.hmrClient.dataMap.get(this.ownerPath);
  69. }
  70. accept(deps, callback) {
  71. if (typeof deps === "function" || !deps) this.acceptDeps([this.ownerPath], ([mod]) => deps?.(mod));
  72. else if (typeof deps === "string") this.acceptDeps([deps], ([mod]) => callback?.(mod));
  73. else if (Array.isArray(deps)) this.acceptDeps(deps, callback);
  74. else throw new Error(`invalid hot.accept() usage.`);
  75. }
  76. acceptExports(_, callback) {
  77. this.acceptDeps([this.ownerPath], ([mod]) => callback?.(mod));
  78. }
  79. dispose(cb) {
  80. this.hmrClient.disposeMap.set(this.ownerPath, cb);
  81. }
  82. prune(cb) {
  83. this.hmrClient.pruneMap.set(this.ownerPath, cb);
  84. }
  85. decline() {}
  86. invalidate(message) {
  87. const firstInvalidatedBy = this.hmrClient.currentFirstInvalidatedBy ?? this.ownerPath;
  88. this.hmrClient.notifyListeners("vite:invalidate", {
  89. path: this.ownerPath,
  90. message,
  91. firstInvalidatedBy
  92. });
  93. this.send("vite:invalidate", {
  94. path: this.ownerPath,
  95. message,
  96. firstInvalidatedBy
  97. });
  98. this.hmrClient.logger.debug(`invalidate ${this.ownerPath}${message ? `: ${message}` : ""}`);
  99. }
  100. on(event, cb) {
  101. const addToMap = (map) => {
  102. const existing = map.get(event) || [];
  103. existing.push(cb);
  104. map.set(event, existing);
  105. };
  106. addToMap(this.hmrClient.customListenersMap);
  107. addToMap(this.newListeners);
  108. }
  109. off(event, cb) {
  110. const removeFromMap = (map) => {
  111. const existing = map.get(event);
  112. if (existing === void 0) return;
  113. const pruned = existing.filter((l) => l !== cb);
  114. if (pruned.length === 0) {
  115. map.delete(event);
  116. return;
  117. }
  118. map.set(event, pruned);
  119. };
  120. removeFromMap(this.hmrClient.customListenersMap);
  121. removeFromMap(this.newListeners);
  122. }
  123. send(event, data) {
  124. this.hmrClient.send({
  125. type: "custom",
  126. event,
  127. data
  128. });
  129. }
  130. acceptDeps(deps, callback = () => {}) {
  131. const mod = this.hmrClient.hotModulesMap.get(this.ownerPath) || {
  132. id: this.ownerPath,
  133. callbacks: []
  134. };
  135. mod.callbacks.push({
  136. deps,
  137. fn: callback
  138. });
  139. this.hmrClient.hotModulesMap.set(this.ownerPath, mod);
  140. }
  141. };
  142. var HMRClient = class {
  143. constructor(logger, transport, importUpdatedModule) {
  144. this.logger = logger;
  145. this.transport = transport;
  146. this.importUpdatedModule = importUpdatedModule;
  147. _defineProperty(this, "hotModulesMap", /* @__PURE__ */ new Map());
  148. _defineProperty(this, "disposeMap", /* @__PURE__ */ new Map());
  149. _defineProperty(this, "pruneMap", /* @__PURE__ */ new Map());
  150. _defineProperty(this, "dataMap", /* @__PURE__ */ new Map());
  151. _defineProperty(this, "customListenersMap", /* @__PURE__ */ new Map());
  152. _defineProperty(this, "ctxToListenersMap", /* @__PURE__ */ new Map());
  153. _defineProperty(this, "currentFirstInvalidatedBy", void 0);
  154. _defineProperty(this, "updateQueue", []);
  155. _defineProperty(this, "pendingUpdateQueue", false);
  156. }
  157. async notifyListeners(event, data) {
  158. const cbs = this.customListenersMap.get(event);
  159. if (cbs) await Promise.allSettled(cbs.map((cb) => cb(data)));
  160. }
  161. send(payload) {
  162. this.transport.send(payload).catch((err) => {
  163. this.logger.error(err);
  164. });
  165. }
  166. clear() {
  167. this.hotModulesMap.clear();
  168. this.disposeMap.clear();
  169. this.pruneMap.clear();
  170. this.dataMap.clear();
  171. this.customListenersMap.clear();
  172. this.ctxToListenersMap.clear();
  173. }
  174. async prunePaths(paths) {
  175. try {
  176. await Promise.all(paths.map((path) => {
  177. const disposer = this.disposeMap.get(path);
  178. if (disposer) return disposer(this.dataMap.get(path));
  179. }));
  180. await Promise.all(paths.map((path) => {
  181. const fn = this.pruneMap.get(path);
  182. if (fn) return fn(this.dataMap.get(path));
  183. }));
  184. } finally {
  185. paths.forEach((path) => this.dataMap.delete(path));
  186. }
  187. }
  188. warnFailedUpdate(err, path) {
  189. if (!(err instanceof Error) || !err.message.includes("fetch")) this.logger.error(err);
  190. this.logger.error(`Failed to reload ${path}. This could be due to syntax errors or importing non-existent modules. (see errors above)`);
  191. }
  192. /**
  193. * buffer multiple hot updates triggered by the same src change
  194. * so that they are invoked in the same order they were sent.
  195. * (otherwise the order may be inconsistent because of the http request round trip)
  196. */
  197. async queueUpdate(payload) {
  198. this.updateQueue.push(this.fetchUpdate(payload));
  199. if (!this.pendingUpdateQueue) {
  200. this.pendingUpdateQueue = true;
  201. await Promise.resolve();
  202. this.pendingUpdateQueue = false;
  203. const loading = [...this.updateQueue];
  204. this.updateQueue = [];
  205. (await Promise.all(loading)).forEach((fn) => fn && fn());
  206. }
  207. }
  208. async fetchUpdate(update) {
  209. const { path, acceptedPath, firstInvalidatedBy } = update;
  210. const mod = this.hotModulesMap.get(path);
  211. if (!mod) return;
  212. let fetchedModule;
  213. const isSelfUpdate = path === acceptedPath;
  214. const qualifiedCallbacks = mod.callbacks.filter(({ deps }) => deps.includes(acceptedPath));
  215. if (isSelfUpdate || qualifiedCallbacks.length > 0) {
  216. const disposer = this.disposeMap.get(acceptedPath);
  217. if (disposer) await disposer(this.dataMap.get(acceptedPath));
  218. try {
  219. fetchedModule = await this.importUpdatedModule(update);
  220. } catch (e) {
  221. this.warnFailedUpdate(e, acceptedPath);
  222. }
  223. }
  224. return () => {
  225. try {
  226. this.currentFirstInvalidatedBy = firstInvalidatedBy;
  227. for (const { deps, fn } of qualifiedCallbacks) fn(deps.map((dep) => dep === acceptedPath ? fetchedModule : void 0));
  228. const loggedPath = isSelfUpdate ? path : `${acceptedPath} via ${path}`;
  229. this.logger.debug(`hot updated: ${loggedPath}`);
  230. } finally {
  231. this.currentFirstInvalidatedBy = void 0;
  232. }
  233. };
  234. }
  235. };
  236. //#endregion
  237. //#region src/client/bundledDevHmrClient.ts
  238. var BundledDevHMRClient = class extends HMRClient {
  239. constructor(logger, transport, runtime, options) {
  240. super(logger, transport, async () => {
  241. throw new Error("unreachable: full-bundle mode applies patches through its own queue");
  242. });
  243. this.runtime = runtime;
  244. this.options = options;
  245. this.applyQueue = Promise.resolve();
  246. this.lastSeq = 0;
  247. this.reloadPending = false;
  248. }
  249. isSelfAccepted(id) {
  250. return this.hotModulesMap.get(id)?.callbacks.some((c) => c.deps.includes(id)) ?? false;
  251. }
  252. acceptsDep(parent, id) {
  253. return this.hotModulesMap.get(parent)?.callbacks.some((c) => c.deps.includes(id)) ?? false;
  254. }
  255. computeHmrUpdate(changedIds, opts) {
  256. const boundaries = [];
  257. const updateSet = /* @__PURE__ */ new Set();
  258. const traversedModules = /* @__PURE__ */ new Set();
  259. for (const changed of changedIds) {
  260. if (!this.runtime.isExecuted(changed)) continue;
  261. const fullReload = this.bubble(changed, [changed], updateSet, boundaries, opts?.firstInvalidatedBy, traversedModules);
  262. if (fullReload) return fullReload;
  263. }
  264. return boundaries.length ? {
  265. type: "boundaries",
  266. boundaries,
  267. updateSet: [...updateSet]
  268. } : { type: "noop" };
  269. }
  270. bubble(id, stack, updateSet, boundaries, firstInvalidatedBy, traversedModules) {
  271. if (traversedModules.has(id)) return;
  272. traversedModules.add(id);
  273. updateSet.add(id);
  274. if (firstInvalidatedBy !== void 0 && id === firstInvalidatedBy) return {
  275. type: "full-reload",
  276. reason: `update propagated back to ${firstInvalidatedBy}, which already called \`import.meta.hot.invalidate()\``
  277. };
  278. if (this.isSelfAccepted(id)) {
  279. boundaries.push({
  280. boundary: id,
  281. acceptedVia: id,
  282. isWithinCircularImport: this.isNodeWithinCircularImports(id, stack)
  283. });
  284. return;
  285. }
  286. const parents = this.runtime.getImporters(id).filter((p) => this.runtime.isExecuted(p));
  287. if (!parents.length) return {
  288. type: "full-reload",
  289. reason: `no hmr boundary found for module \`${id}\``
  290. };
  291. for (const parent of parents) {
  292. const subChain = [...stack, parent];
  293. if (this.acceptsDep(parent, id)) {
  294. boundaries.push({
  295. boundary: parent,
  296. acceptedVia: id,
  297. isWithinCircularImport: this.isNodeWithinCircularImports(parent, subChain)
  298. });
  299. continue;
  300. }
  301. if (!stack.includes(parent)) {
  302. const fullReload = this.bubble(parent, subChain, updateSet, boundaries, firstInvalidatedBy, traversedModules);
  303. if (fullReload) return fullReload;
  304. }
  305. }
  306. }
  307. /**
  308. * Check importers recursively if it's an import loop. An accepted module within
  309. * an import loop cannot recover its execution order and should be reloaded.
  310. *
  311. * @param node The node that accepts HMR and is a boundary
  312. * @param nodeChain The chain of nodes/imports that lead to the node.
  313. * (The last node in the chain imports the `node` parameter)
  314. * @param currentChain The current chain tracked from the `node` parameter
  315. * @param traversedModules The set of modules that have traversed
  316. */
  317. isNodeWithinCircularImports(node, nodeChain, currentChain = [node], traversedModules = /* @__PURE__ */ new Set()) {
  318. if (traversedModules.has(node)) return false;
  319. traversedModules.add(node);
  320. for (const importer of this.runtime.getImporters(node)) {
  321. if (importer === node) continue;
  322. const importerIndex = nodeChain.indexOf(importer);
  323. if (importerIndex > -1) {
  324. const importChain = [
  325. importer,
  326. ...currentChain.toReversed(),
  327. ...nodeChain.slice(importerIndex, -1).reverse()
  328. ];
  329. this.logger.debug(`circular imports detected: ${importChain.join(" -> ")}`);
  330. return true;
  331. }
  332. if (!currentChain.includes(importer)) {
  333. const result = this.isNodeWithinCircularImports(importer, nodeChain, [...currentChain, importer], traversedModules);
  334. if (result) return result;
  335. }
  336. }
  337. return false;
  338. }
  339. handlePush(payload) {
  340. this.applyQueue = this.applyQueue.then(() => this.applyPush(payload)).catch((err) => {
  341. this.warnFailedUpdate(err, payload.changedIds);
  342. });
  343. }
  344. invalidateLocally(id, message) {
  345. this.logger.debug(`invalidate ${id}${message ? `: ${message}` : ""}`);
  346. this.applyQueue = this.applyQueue.then(() => this.applyInvalidate(id)).catch((err) => {
  347. this.warnFailedUpdate(err, id);
  348. });
  349. }
  350. handleModuleCacheRemoval(id) {
  351. const disposer = this.disposeMap.get(id);
  352. if (disposer) disposer(this.dataMap.get(id));
  353. }
  354. async applyPush({ changedIds, url, seq }) {
  355. if (this.reloadPending) return;
  356. if (seq !== this.lastSeq + 1) {
  357. this.requestFullReload(`hmr update sequence gap (expected ${this.lastSeq + 1}, got ${seq})`);
  358. return;
  359. }
  360. this.lastSeq = seq;
  361. const update = this.computeHmrUpdate(changedIds);
  362. if (update.type === "noop") return;
  363. if (update.type === "full-reload") {
  364. this.requestFullReload(update.reason);
  365. return;
  366. }
  367. const listenerPayload = this.toUpdatePayload(update.boundaries, void 0);
  368. await this.notifyListeners("vite:beforeUpdate", listenerPayload);
  369. if (this.options.beforeApply() === "reload") return;
  370. try {
  371. await import(
  372. /* @vite-ignore */
  373. this.options.base + url
  374. );
  375. } catch {
  376. this.requestFullReload(`failed to import hmr patch ${url}`);
  377. return;
  378. }
  379. await this.applyUpdate(update);
  380. await this.notifyListeners("vite:afterUpdate", listenerPayload);
  381. }
  382. async applyInvalidate(id) {
  383. if (this.reloadPending) return;
  384. const firstInvalidatedBy = this.currentFirstInvalidatedBy ?? id;
  385. const importers = this.runtime.getImporters(id).filter((p) => this.runtime.isExecuted(p));
  386. if (!importers.length) {
  387. this.requestFullReload(`no importers to handle \`import.meta.hot.invalidate()\` called by \`${id}\``);
  388. return;
  389. }
  390. const update = this.computeHmrUpdate(importers, { firstInvalidatedBy });
  391. if (update.type === "noop") return;
  392. if (update.type === "full-reload") {
  393. this.requestFullReload(update.reason);
  394. return;
  395. }
  396. const listenerPayload = this.toUpdatePayload(update.boundaries, firstInvalidatedBy);
  397. await this.notifyListeners("vite:beforeUpdate", listenerPayload);
  398. if (this.options.beforeApply() === "reload") return;
  399. await this.applyUpdate(update, firstInvalidatedBy);
  400. await this.notifyListeners("vite:afterUpdate", listenerPayload);
  401. }
  402. async applyUpdate(update, firstInvalidatedBy) {
  403. for (const id of update.updateSet) if (!this.runtime.hasFactory(id)) {
  404. this.requestFullReload(`no factory for module \`${id}\``);
  405. return;
  406. }
  407. const applies = update.boundaries.map(({ boundary, acceptedVia, isWithinCircularImport }) => ({
  408. boundary,
  409. acceptedVia,
  410. isWithinCircularImport,
  411. callbacks: this.hotModulesMap.get(boundary)?.callbacks.filter((c) => c.deps.includes(acceptedVia)) ?? []
  412. }));
  413. for (const id of update.updateSet) this.runtime.removeModuleCache(id);
  414. for (const { boundary, acceptedVia, isWithinCircularImport, callbacks } of applies) {
  415. let fresh;
  416. try {
  417. this.runtime.initModule(acceptedVia);
  418. fresh = this.runtime.loadExports(acceptedVia);
  419. } catch (err) {
  420. if (isWithinCircularImport) {
  421. this.requestFullReload(`${acceptedVia} failed to apply HMR as it's within a circular import. Reloading page to reset the execution order.`);
  422. return;
  423. }
  424. throw err;
  425. }
  426. try {
  427. this.currentFirstInvalidatedBy = firstInvalidatedBy;
  428. for (const { deps, fn } of callbacks) fn(deps.map((dep) => dep === acceptedVia ? fresh : void 0));
  429. } finally {
  430. this.currentFirstInvalidatedBy = void 0;
  431. }
  432. this.logger.debug(`hot updated: ${boundary === acceptedVia ? boundary : `${acceptedVia} via ${boundary}`}`);
  433. }
  434. }
  435. toUpdatePayload(boundaries, firstInvalidatedBy) {
  436. return {
  437. type: "update",
  438. updates: boundaries.map(({ boundary, acceptedVia, isWithinCircularImport }) => ({
  439. type: "js-update",
  440. path: boundary,
  441. acceptedPath: acceptedVia,
  442. timestamp: Date.now(),
  443. isWithinCircularImport,
  444. firstInvalidatedBy
  445. }))
  446. };
  447. }
  448. requestFullReload(reason) {
  449. if (this.reloadPending) return;
  450. this.reloadPending = true;
  451. this.logger.debug(`full reload needed: ${reason}`);
  452. this.send({
  453. type: "custom",
  454. event: "vite:bundled-dev:reload-needed",
  455. data: { reason }
  456. });
  457. }
  458. };
  459. var BundledDevHMRContext = class extends HMRContext {
  460. constructor(bundledDevClient, owner) {
  461. super(bundledDevClient, owner);
  462. this.bundledDevClient = bundledDevClient;
  463. this.owner = owner;
  464. }
  465. invalidate(message) {
  466. this.bundledDevClient.notifyListeners("vite:invalidate", {
  467. path: this.owner,
  468. message,
  469. firstInvalidatedBy: this.bundledDevClient.currentFirstInvalidatedBy ?? this.owner
  470. });
  471. this.bundledDevClient.invalidateLocally(this.owner, message);
  472. }
  473. };
  474. //#endregion
  475. //#region src/shared/constants.ts
  476. /**
  477. * Prefix for resolved Ids that are not valid browser import specifiers
  478. */
  479. const VALID_ID_PREFIX = `/@id/`;
  480. /**
  481. * Plugins that use 'virtual modules' (e.g. for helper functions), prefix the
  482. * module ID with `\0`, a convention from the rollup ecosystem.
  483. * This prevents other plugins from trying to process the id (like node resolution),
  484. * and core features like sourcemaps can use this info to differentiate between
  485. * virtual modules and regular files.
  486. * `\0` is not a permitted char in import URLs so we have to replace them during
  487. * import analysis. The id will be decoded back before entering the plugins pipeline.
  488. * These encoded virtual ids are also prefixed by the VALID_ID_PREFIX, so virtual
  489. * modules in the browser end up encoded as `/@id/__x00__{id}`
  490. */
  491. const NULL_BYTE_PLACEHOLDER = `__x00__`;
  492. let SOURCEMAPPING_URL = "sourceMa";
  493. SOURCEMAPPING_URL += "ppingURL";
  494. typeof process !== "undefined" && process.platform;
  495. /**
  496. * Prepend `/@id/` and replace null byte so the id is URL-safe.
  497. * This is prepended to resolved ids that are not valid browser
  498. * import specifiers by the importAnalysis plugin.
  499. */
  500. function wrapId(id) {
  501. return id.startsWith(VALID_ID_PREFIX) ? id : VALID_ID_PREFIX + id.replace("\0", NULL_BYTE_PLACEHOLDER);
  502. }
  503. (async function() {}).constructor;
  504. function promiseWithResolvers() {
  505. let resolve;
  506. let reject;
  507. return {
  508. promise: new Promise((_resolve, _reject) => {
  509. resolve = _resolve;
  510. reject = _reject;
  511. }),
  512. resolve,
  513. reject
  514. };
  515. }
  516. //#endregion
  517. //#region src/shared/moduleRunnerTransport.ts
  518. function reviveInvokeError(e) {
  519. const error = new Error(e.message || "Unknown invoke error");
  520. Object.assign(error, e, { runnerError: /* @__PURE__ */ new Error("RunnerError") });
  521. return error;
  522. }
  523. const createInvokeableTransport = (transport) => {
  524. if (transport.invoke) return {
  525. ...transport,
  526. async invoke(name, data) {
  527. const result = await transport.invoke({
  528. type: "custom",
  529. event: "vite:invoke",
  530. data: {
  531. id: "send",
  532. name,
  533. data
  534. }
  535. });
  536. if ("error" in result) throw reviveInvokeError(result.error);
  537. return result.result;
  538. }
  539. };
  540. if (!transport.send || !transport.connect) throw new Error("transport must implement send and connect when invoke is not implemented");
  541. const rpcPromises = /* @__PURE__ */ new Map();
  542. return {
  543. ...transport,
  544. connect({ onMessage, onDisconnection }) {
  545. return transport.connect({
  546. onMessage(payload) {
  547. if (payload.type === "custom" && payload.event === "vite:invoke") {
  548. const data = payload.data;
  549. if (data.id.startsWith("response:")) {
  550. const invokeId = data.id.slice(9);
  551. const promise = rpcPromises.get(invokeId);
  552. if (!promise) return;
  553. if (promise.timeoutId) clearTimeout(promise.timeoutId);
  554. rpcPromises.delete(invokeId);
  555. const { error, result } = data.data;
  556. if (error) promise.reject(error);
  557. else promise.resolve(result);
  558. return;
  559. }
  560. }
  561. onMessage(payload);
  562. },
  563. onDisconnection
  564. });
  565. },
  566. disconnect() {
  567. rpcPromises.forEach((promise) => {
  568. promise.reject(/* @__PURE__ */ new Error(`transport was disconnected, cannot call ${JSON.stringify(promise.name)}`));
  569. });
  570. rpcPromises.clear();
  571. return transport.disconnect?.();
  572. },
  573. send(data) {
  574. return transport.send(data);
  575. },
  576. async invoke(name, data) {
  577. const promiseId = nanoid();
  578. const wrappedData = {
  579. type: "custom",
  580. event: "vite:invoke",
  581. data: {
  582. name,
  583. id: `send:${promiseId}`,
  584. data
  585. }
  586. };
  587. const sendPromise = transport.send(wrappedData);
  588. const { promise, resolve, reject } = promiseWithResolvers();
  589. const timeout = transport.timeout ?? 6e4;
  590. let timeoutId;
  591. if (timeout > 0) {
  592. timeoutId = setTimeout(() => {
  593. rpcPromises.delete(promiseId);
  594. reject(/* @__PURE__ */ new Error(`transport invoke timed out after ${timeout}ms (data: ${JSON.stringify(wrappedData)})`));
  595. }, timeout);
  596. timeoutId?.unref?.();
  597. }
  598. rpcPromises.set(promiseId, {
  599. resolve,
  600. reject,
  601. name,
  602. timeoutId
  603. });
  604. if (sendPromise) sendPromise.catch((err) => {
  605. clearTimeout(timeoutId);
  606. rpcPromises.delete(promiseId);
  607. reject(err);
  608. });
  609. try {
  610. return await promise;
  611. } catch (err) {
  612. throw reviveInvokeError(err);
  613. }
  614. }
  615. };
  616. };
  617. const normalizeModuleRunnerTransport = (transport) => {
  618. const invokeableTransport = createInvokeableTransport(transport);
  619. let isConnected = !invokeableTransport.connect;
  620. let connectingPromise;
  621. return {
  622. ...transport,
  623. ...invokeableTransport.connect ? { async connect(onMessage) {
  624. if (isConnected) return;
  625. if (connectingPromise) {
  626. await connectingPromise;
  627. return;
  628. }
  629. const maybePromise = invokeableTransport.connect({
  630. onMessage: onMessage ?? (() => {}),
  631. onDisconnection() {
  632. isConnected = false;
  633. }
  634. });
  635. if (maybePromise) {
  636. connectingPromise = maybePromise;
  637. await connectingPromise;
  638. connectingPromise = void 0;
  639. }
  640. isConnected = true;
  641. } } : {},
  642. ...invokeableTransport.disconnect ? { async disconnect() {
  643. if (!isConnected) return;
  644. if (connectingPromise) await connectingPromise;
  645. isConnected = false;
  646. await invokeableTransport.disconnect();
  647. } } : {},
  648. async send(data) {
  649. if (!invokeableTransport.send) return;
  650. if (!isConnected) {
  651. if (connectingPromise) await connectingPromise;
  652. else throw new SendBeforeConnectError("send was called before connect");
  653. }
  654. await invokeableTransport.send(data);
  655. },
  656. async invoke(name, data) {
  657. if (!isConnected) {
  658. if (connectingPromise) await connectingPromise;
  659. else throw new SendBeforeConnectError("invoke was called before connect");
  660. }
  661. return invokeableTransport.invoke(name, data);
  662. }
  663. };
  664. };
  665. var SendBeforeConnectError = class extends Error {
  666. constructor(message) {
  667. super(message);
  668. this.name = "SendBeforeConnectError";
  669. }
  670. };
  671. const createWebSocketModuleRunnerTransport = (options) => {
  672. const pingInterval = options.pingInterval ?? 3e4;
  673. let ws;
  674. let pingIntervalId;
  675. return {
  676. async connect({ onMessage, onDisconnection }) {
  677. const socket = options.createConnection();
  678. socket.addEventListener("message", ({ data }) => {
  679. onMessage(JSON.parse(data));
  680. });
  681. let isOpened = socket.readyState === socket.OPEN;
  682. if (!isOpened) await new Promise((resolve, reject) => {
  683. socket.addEventListener("open", () => {
  684. isOpened = true;
  685. resolve();
  686. }, { once: true });
  687. socket.addEventListener("close", () => {
  688. if (!isOpened) {
  689. reject(/* @__PURE__ */ new Error("WebSocket closed without opened."));
  690. return;
  691. }
  692. onMessage({
  693. type: "custom",
  694. event: "vite:ws:disconnect",
  695. data: { webSocket: socket }
  696. });
  697. onDisconnection();
  698. });
  699. });
  700. onMessage({
  701. type: "custom",
  702. event: "vite:ws:connect",
  703. data: { webSocket: socket }
  704. });
  705. ws = socket;
  706. pingIntervalId = setInterval(() => {
  707. if (socket.readyState === socket.OPEN) socket.send(JSON.stringify({ type: "ping" }));
  708. }, pingInterval);
  709. },
  710. disconnect() {
  711. clearInterval(pingIntervalId);
  712. ws?.close();
  713. },
  714. send(data) {
  715. ws.send(JSON.stringify(data));
  716. }
  717. };
  718. };
  719. //#endregion
  720. //#region src/shared/pretty-format.ts
  721. const DEFAULT_OPTIONS = {
  722. maxDepth: 3,
  723. maxWidth: 100
  724. };
  725. const objectToString = Object.prototype.toString;
  726. const errorToString = Error.prototype.toString;
  727. const identifierRE = /^[a-z_$][\w$]*$/i;
  728. function prettyFormat(value, options = {}) {
  729. return printer(value, {
  730. ...DEFAULT_OPTIONS,
  731. ...options
  732. }, 0, []);
  733. }
  734. function printer(value, config, depth, refs) {
  735. return printBasicValue(value) ?? printComplexValue(value, config, depth, refs);
  736. }
  737. function printBasicValue(value) {
  738. if (value == null) return String(value);
  739. if (typeof value === "string") return JSON.stringify(value);
  740. if (typeof value === "number") return Object.is(value, -0) ? "-0" : String(value);
  741. if (typeof value === "bigint") return `${value}n`;
  742. if (typeof value === "boolean" || typeof value === "symbol") return String(value);
  743. if (typeof value === "function") return value.name ? `[Function: ${value.name}]` : "[Function]";
  744. const type = objectToString.call(value);
  745. if (type === "[object Date]") return Number.isNaN(+value) ? "Date { NaN }" : value.toISOString();
  746. if (type === "[object Error]" || value instanceof Error) return `[${errorToString.call(value)}]`;
  747. }
  748. function printComplexValue(value, config, depth, refs) {
  749. if (refs.includes(value)) return "[Circular]";
  750. refs = [...refs, value];
  751. const hitMaxDepth = ++depth > config.maxDepth;
  752. if (Array.isArray(value)) return hitMaxDepth ? "[Array]" : `[${printListItems(value, config, depth, refs)}]`;
  753. return hitMaxDepth ? "[Object]" : `{${printObjectProperties(value, config, depth, refs)}}`;
  754. }
  755. function printListItems(value, config, depth, refs) {
  756. const width = Math.min(value.length, config.maxWidth);
  757. const result = [];
  758. for (let i = 0; i < width; i++) result.push(i in value ? printer(value[i], config, depth, refs) : "");
  759. if (width < value.length) result.push(`…(${value.length - width})`);
  760. return withSpacing(result);
  761. }
  762. function printObjectProperties(value, config, depth, refs) {
  763. const keys = Object.keys(value);
  764. const width = Math.min(keys.length, config.maxWidth);
  765. const result = [];
  766. for (let i = 0; i < width; i++) {
  767. const key = keys[i];
  768. const name = key !== "__proto__" && identifierRE.test(key) ? key : JSON.stringify(key);
  769. result.push(`${name}: ${printer(value[key], config, depth, refs)}`);
  770. }
  771. if (width < keys.length) result.push(`…(${keys.length - width})`);
  772. return withSpacing(result);
  773. }
  774. function withSpacing(values) {
  775. return values.length === 0 ? "" : ` ${values.join(", ")} `;
  776. }
  777. //#endregion
  778. //#region src/shared/forwardConsole.ts
  779. function setupForwardConsoleHandler(transport, options, console = globalThis.console) {
  780. if (!options.enabled) return;
  781. async function sendError(type, error) {
  782. await transport.send({
  783. type: "custom",
  784. event: "vite:forward-console",
  785. data: {
  786. type,
  787. data: {
  788. name: error?.name || "Unknown Error",
  789. message: error?.message || String(error),
  790. stack: error?.stack
  791. }
  792. }
  793. });
  794. }
  795. async function sendLog(level, args) {
  796. try {
  797. await transport.send({
  798. type: "custom",
  799. event: "vite:forward-console",
  800. data: {
  801. type: "log",
  802. data: {
  803. level,
  804. message: truncateConsoleMessage(formatConsoleArgs(args))
  805. }
  806. }
  807. });
  808. } catch (err) {
  809. try {
  810. await sendError("unhandled-rejection", err);
  811. } catch (err) {
  812. if (!(err instanceof SendBeforeConnectError)) originalConsoleError("Failed to send error to Vite server:", err);
  813. }
  814. }
  815. }
  816. const originalConsoleError = console.error;
  817. for (const level of options.logLevels) {
  818. const original = console[level];
  819. if (typeof original !== "function") continue;
  820. console[level] = (...args) => {
  821. original(...args);
  822. sendLog(level, args);
  823. };
  824. }
  825. if (options.unhandledErrors && typeof window !== "undefined") {
  826. window.addEventListener("error", async (event) => {
  827. const error = event.error ?? (event.message ? new Error(event.message) : event);
  828. try {
  829. await sendError("error", error);
  830. } catch (err) {
  831. if (!(err instanceof SendBeforeConnectError)) originalConsoleError("Failed to send error to Vite server:", err);
  832. }
  833. });
  834. window.addEventListener("unhandledrejection", async (event) => {
  835. try {
  836. await sendError("unhandled-rejection", event.reason);
  837. } catch (err) {
  838. if (!(err instanceof SendBeforeConnectError)) originalConsoleError("Failed to send error to Vite server:", err);
  839. }
  840. });
  841. }
  842. }
  843. function formatConsoleArgs(args) {
  844. if (args.length === 0) return "";
  845. if (typeof args[0] !== "string") return args.map((arg) => stringifyConsoleArg(arg)).join(" ");
  846. const len = args.length;
  847. let i = 1;
  848. let message = args[0].replace(/%[sdjifoOc%]/g, (specifier) => {
  849. if (specifier === "%%") return "%";
  850. if (i >= len) return specifier;
  851. const arg = args[i++];
  852. switch (specifier) {
  853. case "%s":
  854. if (typeof arg === "bigint") return `${arg.toString()}n`;
  855. return typeof arg === "object" && arg != null ? stringifyConsoleArg(arg) : String(arg);
  856. case "%d":
  857. if (typeof arg === "bigint") return `${arg.toString()}n`;
  858. if (typeof arg === "symbol") return "NaN";
  859. return Number(arg).toString();
  860. case "%i":
  861. if (typeof arg === "bigint") return `${arg.toString()}n`;
  862. return Number.parseInt(String(arg), 10).toString();
  863. case "%f": return Number.parseFloat(String(arg)).toString();
  864. case "%o":
  865. case "%O": return stringifyConsoleArg(arg);
  866. case "%j": try {
  867. return JSON.stringify(arg) ?? "undefined";
  868. } catch {
  869. return "[Circular]";
  870. }
  871. case "%c": return "";
  872. default: return specifier;
  873. }
  874. });
  875. for (let arg = args[i]; i < len; arg = args[++i]) if (arg == null || typeof arg !== "object") message += ` ${typeof arg === "symbol" ? arg.toString() : String(arg)}`;
  876. else message += ` ${stringifyConsoleArg(arg)}`;
  877. return message;
  878. }
  879. function stringifyConsoleArg(value) {
  880. if (typeof value === "string") return value;
  881. if (value instanceof Error) return value.stack || `${value.name}: ${value.message}`;
  882. try {
  883. return prettyFormat(value);
  884. } catch {
  885. return String(value);
  886. }
  887. }
  888. const MAX_CONSOLE_MESSAGE_LENGTH = 1e4;
  889. function truncateConsoleMessage(message) {
  890. if (message.length <= MAX_CONSOLE_MESSAGE_LENGTH) return message;
  891. let end = 9999;
  892. if (isHighSurrogate(message[end - 1])) end--;
  893. return `${message.slice(0, end)}…`;
  894. }
  895. function isHighSurrogate(value) {
  896. return value >= "\ud800" && value <= "\udbff";
  897. }
  898. //#endregion
  899. //#region src/shared/hmrHandler.ts
  900. function createHMRHandler(handler) {
  901. const queue = new Queue();
  902. return (payload) => queue.enqueue(() => handler(payload));
  903. }
  904. var Queue = class {
  905. constructor() {
  906. _defineProperty(this, "queue", []);
  907. _defineProperty(this, "pending", false);
  908. }
  909. enqueue(promise) {
  910. return new Promise((resolve, reject) => {
  911. this.queue.push({
  912. promise,
  913. resolve,
  914. reject
  915. });
  916. this.dequeue();
  917. });
  918. }
  919. dequeue() {
  920. if (this.pending) return false;
  921. const item = this.queue.shift();
  922. if (!item) return false;
  923. this.pending = true;
  924. item.promise().then(item.resolve).catch(item.reject).finally(() => {
  925. this.pending = false;
  926. this.dequeue();
  927. });
  928. return true;
  929. }
  930. };
  931. //#endregion
  932. //#region src/client/overlay.ts
  933. const hmrConfigName = __HMR_CONFIG_NAME__;
  934. const base$1 = __BASE__ || "/";
  935. const cspNonce = "document" in globalThis ? document.querySelector("meta[property=csp-nonce]")?.nonce : void 0;
  936. function h(e, attrs = {}, ...children) {
  937. const elem = document.createElement(e);
  938. for (const [k, v] of Object.entries(attrs)) if (v !== void 0) elem.setAttribute(k, v);
  939. elem.append(...children);
  940. return elem;
  941. }
  942. const templateStyle = `
  943. :host {
  944. position: fixed;
  945. top: 0;
  946. left: 0;
  947. width: 100%;
  948. height: 100%;
  949. z-index: 99999;
  950. --monospace: 'SFMono-Regular', Consolas,
  951. 'Liberation Mono', Menlo, Courier, monospace;
  952. --red: #ff5555;
  953. --yellow: #e2aa53;
  954. --purple: #cfa4ff;
  955. --cyan: #2dd9da;
  956. --dim: #c9c9c9;
  957. --window-background: #181818;
  958. --window-color: #d8d8d8;
  959. }
  960. .backdrop {
  961. position: fixed;
  962. z-index: 99999;
  963. top: 0;
  964. left: 0;
  965. width: 100%;
  966. height: 100%;
  967. overflow-y: scroll;
  968. margin: 0;
  969. background: rgba(0, 0, 0, 0.66);
  970. }
  971. .window {
  972. font-family: var(--monospace);
  973. line-height: 1.5;
  974. max-width: 80vw;
  975. color: var(--window-color);
  976. box-sizing: border-box;
  977. margin: 30px auto;
  978. padding: 2.5vh 4vw;
  979. position: relative;
  980. background: var(--window-background);
  981. border-radius: 6px 6px 8px 8px;
  982. box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22);
  983. overflow: hidden;
  984. border-top: 8px solid var(--red);
  985. direction: ltr;
  986. text-align: left;
  987. }
  988. pre {
  989. font-family: var(--monospace);
  990. font-size: 16px;
  991. margin-top: 0;
  992. margin-bottom: 1em;
  993. overflow-x: scroll;
  994. scrollbar-width: none;
  995. }
  996. pre::-webkit-scrollbar {
  997. display: none;
  998. }
  999. pre.frame::-webkit-scrollbar {
  1000. display: block;
  1001. height: 5px;
  1002. }
  1003. pre.frame::-webkit-scrollbar-thumb {
  1004. background: #999;
  1005. border-radius: 5px;
  1006. }
  1007. pre.frame {
  1008. scrollbar-width: thin;
  1009. }
  1010. .message {
  1011. line-height: 1.3;
  1012. font-weight: 400;
  1013. white-space: pre-wrap;
  1014. }
  1015. .message-body {
  1016. color: var(--red);
  1017. }
  1018. .plugin {
  1019. color: var(--purple);
  1020. }
  1021. .file {
  1022. color: var(--cyan);
  1023. margin-bottom: 0;
  1024. white-space: pre-wrap;
  1025. word-break: break-all;
  1026. }
  1027. .frame {
  1028. color: var(--yellow);
  1029. }
  1030. .stack {
  1031. font-size: 13px;
  1032. color: var(--dim);
  1033. }
  1034. .tip {
  1035. font-size: 13px;
  1036. color: #999;
  1037. border-top: 1px dotted #999;
  1038. padding-top: 13px;
  1039. line-height: 1.8;
  1040. }
  1041. code {
  1042. font-size: 13px;
  1043. font-family: var(--monospace);
  1044. color: var(--yellow);
  1045. }
  1046. .file-link {
  1047. text-decoration: underline;
  1048. cursor: pointer;
  1049. }
  1050. kbd {
  1051. line-height: 1.5;
  1052. font-family: ui-monospace, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  1053. font-size: 0.75rem;
  1054. font-weight: 700;
  1055. background-color: rgb(38, 40, 44);
  1056. color: rgb(166, 167, 171);
  1057. padding: 0.15rem 0.3rem;
  1058. border-radius: 0.25rem;
  1059. border-width: 0.0625rem 0.0625rem 0.1875rem;
  1060. border-style: solid;
  1061. border-color: rgb(54, 57, 64);
  1062. border-image: initial;
  1063. }
  1064. `;
  1065. const createTemplate = () => h("div", {
  1066. class: "backdrop",
  1067. part: "backdrop"
  1068. }, h("div", {
  1069. class: "window",
  1070. part: "window"
  1071. }, h("pre", {
  1072. class: "message",
  1073. part: "message"
  1074. }, h("span", {
  1075. class: "plugin",
  1076. part: "plugin"
  1077. }), h("span", {
  1078. class: "message-body",
  1079. part: "message-body"
  1080. })), h("pre", {
  1081. class: "file",
  1082. part: "file"
  1083. }), h("pre", {
  1084. class: "frame",
  1085. part: "frame"
  1086. }), h("pre", {
  1087. class: "stack",
  1088. part: "stack"
  1089. }), h("div", {
  1090. class: "tip",
  1091. part: "tip"
  1092. }, "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", { nonce: cspNonce }, templateStyle));
  1093. const fileRE = /(?:file:\/\/)?(?:[a-zA-Z]:\\|\/).*?:\d+:\d+/g;
  1094. const codeframeRE = /^(?:>?\s*\d+\s+\|.*|\s+\|\s*\^.*)\r?\n/gm;
  1095. const { HTMLElement = class {} } = globalThis;
  1096. var ErrorOverlay = class extends HTMLElement {
  1097. constructor(err, links = true) {
  1098. super();
  1099. this.root = this.attachShadow({ mode: "open" });
  1100. this.root.appendChild(createTemplate());
  1101. codeframeRE.lastIndex = 0;
  1102. const hasFrame = err.frame && codeframeRE.test(err.frame);
  1103. const message = hasFrame ? err.message.replace(codeframeRE, "") : err.message;
  1104. if (err.plugin) this.text(".plugin", `[plugin:${err.plugin}] `);
  1105. this.text(".message-body", message.trim());
  1106. const [file] = (err.loc?.file || err.id || "unknown file").split(`?`);
  1107. if (err.loc) this.text(".file", `${file}:${err.loc.line}:${err.loc.column}`, links);
  1108. else if (err.id) this.text(".file", file);
  1109. if (hasFrame) this.text(".frame", err.frame.trim());
  1110. this.text(".stack", err.stack, links);
  1111. this.root.querySelector(".window").addEventListener("click", (e) => {
  1112. e.stopPropagation();
  1113. });
  1114. this.addEventListener("click", () => {
  1115. this.close();
  1116. });
  1117. this.closeOnEsc = (e) => {
  1118. if (e.key === "Escape" || e.code === "Escape") this.close();
  1119. };
  1120. document.addEventListener("keydown", this.closeOnEsc);
  1121. }
  1122. text(selector, text, linkFiles = false) {
  1123. const el = this.root.querySelector(selector);
  1124. if (!linkFiles) el.textContent = text;
  1125. else {
  1126. let curIndex = 0;
  1127. let match;
  1128. fileRE.lastIndex = 0;
  1129. while (match = fileRE.exec(text)) {
  1130. const { 0: file, index } = match;
  1131. const frag = text.slice(curIndex, index);
  1132. el.appendChild(document.createTextNode(frag));
  1133. const link = document.createElement("a");
  1134. link.textContent = file;
  1135. link.className = "file-link";
  1136. link.onclick = () => {
  1137. fetch(new URL(`${base$1}__open-in-editor?file=${encodeURIComponent(file)}`, import.meta.url));
  1138. };
  1139. el.appendChild(link);
  1140. curIndex += frag.length + file.length;
  1141. }
  1142. if (curIndex < text.length) el.appendChild(document.createTextNode(text.slice(curIndex)));
  1143. }
  1144. }
  1145. close() {
  1146. this.parentNode?.removeChild(this);
  1147. document.removeEventListener("keydown", this.closeOnEsc);
  1148. }
  1149. };
  1150. const overlayId = "vite-error-overlay";
  1151. const { customElements } = globalThis;
  1152. if (customElements && !customElements.get("vite-error-overlay")) customElements.define(overlayId, ErrorOverlay);
  1153. //#endregion
  1154. //#region src/client/client.ts
  1155. console.debug("[vite] connecting...");
  1156. const importMetaUrl = new URL(import.meta.url);
  1157. const serverHost = __SERVER_HOST__;
  1158. const socketProtocol = __HMR_PROTOCOL__ || (importMetaUrl.protocol === "https:" ? "wss" : "ws");
  1159. const hmrPort = __HMR_PORT__;
  1160. const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}`;
  1161. const directSocketHost = __HMR_DIRECT_TARGET__;
  1162. const base = __BASE__ || "/";
  1163. const hmrTimeout = __HMR_TIMEOUT__;
  1164. const wsToken = __WS_TOKEN__;
  1165. const forwardConsole = __SERVER_FORWARD_CONSOLE__;
  1166. const transport = normalizeModuleRunnerTransport((() => {
  1167. let wsTransport = createWebSocketModuleRunnerTransport({
  1168. createConnection: () => new WebSocket(`${socketProtocol}://${socketHost}?token=${wsToken}`, "vite-hmr"),
  1169. pingInterval: hmrTimeout
  1170. });
  1171. return {
  1172. async connect(handlers) {
  1173. try {
  1174. await wsTransport.connect(handlers);
  1175. } catch (e) {
  1176. if (!hmrPort) {
  1177. wsTransport = createWebSocketModuleRunnerTransport({
  1178. createConnection: () => new WebSocket(`${socketProtocol}://${directSocketHost}?token=${wsToken}`, "vite-hmr"),
  1179. pingInterval: hmrTimeout
  1180. });
  1181. try {
  1182. await wsTransport.connect(handlers);
  1183. console.info("[vite] Direct websocket connection fallback. Check out https://vite.dev/config/server-options.html#server-hmr to remove the previous connection error.");
  1184. } catch (e) {
  1185. if (e instanceof Error && e.message.includes("WebSocket closed without opened.")) {
  1186. const currentScriptHostURL = new URL(import.meta.url);
  1187. const currentScriptHost = currentScriptHostURL.host + currentScriptHostURL.pathname.replace(/@vite\/client$/, "");
  1188. console.error(`[vite] failed to connect to websocket.
  1189. your current setup:
  1190. (browser) ${currentScriptHost} <--[HTTP]--> ${serverHost} (server)\n (browser) ${socketHost} <--[WebSocket (failing)]--> ${directSocketHost} (server)\nCheck out your Vite / network configuration and https://vite.dev/config/server-options.html#server-hmr .`);
  1191. }
  1192. }
  1193. return;
  1194. }
  1195. console.error(`[vite] failed to connect to websocket (${e}). `);
  1196. throw e;
  1197. }
  1198. },
  1199. async disconnect() {
  1200. await wsTransport.disconnect();
  1201. },
  1202. send(data) {
  1203. wsTransport.send(data);
  1204. }
  1205. };
  1206. })());
  1207. let willUnload = false;
  1208. if (typeof window !== "undefined") window.addEventListener?.("beforeunload", () => {
  1209. willUnload = true;
  1210. });
  1211. function cleanUrl(pathname) {
  1212. const url = new URL(pathname, "http://vite.dev");
  1213. url.searchParams.delete("direct");
  1214. return url.pathname + url.search;
  1215. }
  1216. let isFirstUpdate = true;
  1217. const outdatedLinkTags = /* @__PURE__ */ new WeakSet();
  1218. const debounceReload = (time) => {
  1219. let timer;
  1220. return () => {
  1221. if (timer) {
  1222. clearTimeout(timer);
  1223. timer = null;
  1224. }
  1225. timer = setTimeout(() => {
  1226. location.reload();
  1227. }, time);
  1228. };
  1229. };
  1230. const pageReload = debounceReload(20);
  1231. function wrapIdIfNeeded(id) {
  1232. return id[0] === "." || id[0] === "/" ? id : wrapId(id);
  1233. }
  1234. const hmrClient = new HMRClient({
  1235. error: (err) => console.error("[vite]", err),
  1236. debug: (...msg) => console.debug("[vite]", ...msg)
  1237. }, transport, async function importUpdatedModule({ acceptedPath, timestamp, explicitImportRequired, isWithinCircularImport }) {
  1238. const [acceptedPathWithoutQuery, query] = acceptedPath.split(`?`);
  1239. const browserPath = wrapIdIfNeeded(acceptedPathWithoutQuery);
  1240. const importPromise = import(
  1241. /* @vite-ignore */
  1242. base + browserPath.slice(1) + `?${explicitImportRequired ? "import&" : ""}t=${timestamp}${query ? `&${query}` : ""}`
  1243. );
  1244. if (isWithinCircularImport) importPromise.catch(() => {
  1245. console.info(`[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.`);
  1246. pageReload();
  1247. });
  1248. return await importPromise;
  1249. });
  1250. let bundledDevClient;
  1251. function registerBundledDevClient(client) {
  1252. bundledDevClient = client;
  1253. }
  1254. transport.connect(createHMRHandler(handleMessage));
  1255. setupForwardConsoleHandler(transport, forwardConsole);
  1256. function clearOverlayOrReloadOnFirstUpdate() {
  1257. if (hasDocument) {
  1258. if (isFirstUpdate && hasErrorOverlay()) {
  1259. location.reload();
  1260. return "reload";
  1261. }
  1262. if (enableOverlay) clearErrorOverlay();
  1263. isFirstUpdate = false;
  1264. }
  1265. return "continue";
  1266. }
  1267. async function handleMessage(payload) {
  1268. const activeHmrClient = bundledDevClient ?? hmrClient;
  1269. switch (payload.type) {
  1270. case "connected":
  1271. console.debug(`[vite] connected.`);
  1272. break;
  1273. case "bundled-dev-update":
  1274. bundledDevClient.handlePush(payload);
  1275. break;
  1276. case "update":
  1277. await activeHmrClient.notifyListeners("vite:beforeUpdate", payload);
  1278. if (clearOverlayOrReloadOnFirstUpdate() === "reload") return;
  1279. await Promise.all(payload.updates.map(async (update) => {
  1280. if (update.type === "js-update") return hmrClient.queueUpdate(update);
  1281. const { path, timestamp } = update;
  1282. const searchUrl = cleanUrl(path);
  1283. const el = Array.from(document.querySelectorAll("link")).find((e) => !outdatedLinkTags.has(e) && cleanUrl(e.href).includes(searchUrl));
  1284. if (!el) return;
  1285. const newPath = `${base}${searchUrl.slice(1)}${searchUrl.includes("?") ? "&" : "?"}t=${timestamp}`;
  1286. return new Promise((resolve) => {
  1287. const newLinkTag = el.cloneNode();
  1288. newLinkTag.href = new URL(newPath, el.href).href;
  1289. const removeOldEl = () => {
  1290. el.remove();
  1291. console.debug(`[vite] css hot updated: ${searchUrl}`);
  1292. resolve();
  1293. };
  1294. newLinkTag.addEventListener("load", removeOldEl);
  1295. newLinkTag.addEventListener("error", removeOldEl);
  1296. outdatedLinkTags.add(el);
  1297. el.after(newLinkTag);
  1298. });
  1299. }));
  1300. await activeHmrClient.notifyListeners("vite:afterUpdate", payload);
  1301. break;
  1302. case "custom":
  1303. await activeHmrClient.notifyListeners(payload.event, payload.data);
  1304. if (payload.event === "vite:ws:disconnect") {
  1305. if (hasDocument && !willUnload) {
  1306. console.log(`[vite] server connection lost. Polling for restart...`);
  1307. const socket = payload.data.webSocket;
  1308. const url = new URL(socket.url);
  1309. url.search = "";
  1310. await waitForSuccessfulPing(url.href);
  1311. location.reload();
  1312. }
  1313. }
  1314. break;
  1315. case "full-reload":
  1316. if (payload.ifFallback && !globalThis.__vite_is_fallback_page__) break;
  1317. await activeHmrClient.notifyListeners("vite:beforeFullReload", payload);
  1318. if (hasDocument) {
  1319. if (payload.path && payload.path.endsWith(".html")) {
  1320. const pagePath = decodeURI(location.pathname);
  1321. const payloadPath = base + payload.path.slice(1);
  1322. if (pagePath === payloadPath || payload.path === "/index.html" || pagePath.endsWith("/") && pagePath + "index.html" === payloadPath) pageReload();
  1323. return;
  1324. } else pageReload();
  1325. }
  1326. break;
  1327. case "prune":
  1328. await activeHmrClient.notifyListeners("vite:beforePrune", payload);
  1329. await activeHmrClient.prunePaths(payload.paths);
  1330. break;
  1331. case "error":
  1332. await activeHmrClient.notifyListeners("vite:error", payload);
  1333. if (hasDocument) {
  1334. const err = payload.err;
  1335. if (enableOverlay) createErrorOverlay(err);
  1336. else console.error(`[vite] Internal Server Error\n${err.message}\n${err.stack}`);
  1337. }
  1338. break;
  1339. case "ping": break;
  1340. default: return payload;
  1341. }
  1342. }
  1343. const enableOverlay = __HMR_ENABLE_OVERLAY__;
  1344. const hasDocument = "document" in globalThis;
  1345. function createErrorOverlay(err) {
  1346. clearErrorOverlay();
  1347. const { customElements } = globalThis;
  1348. if (customElements) {
  1349. const ErrorOverlayConstructor = customElements.get(overlayId);
  1350. document.body.appendChild(new ErrorOverlayConstructor(err));
  1351. }
  1352. }
  1353. function clearErrorOverlay() {
  1354. document.querySelectorAll(overlayId).forEach((n) => n.close());
  1355. }
  1356. function hasErrorOverlay() {
  1357. return document.querySelectorAll(overlayId).length;
  1358. }
  1359. function waitForSuccessfulPing(socketUrl) {
  1360. if (typeof SharedWorker === "undefined") {
  1361. const visibilityManager = {
  1362. currentState: document.visibilityState,
  1363. listeners: /* @__PURE__ */ new Set()
  1364. };
  1365. const onVisibilityChange = () => {
  1366. visibilityManager.currentState = document.visibilityState;
  1367. for (const listener of visibilityManager.listeners) listener(visibilityManager.currentState);
  1368. };
  1369. document.addEventListener("visibilitychange", onVisibilityChange);
  1370. return waitForSuccessfulPingInternal(socketUrl, visibilityManager);
  1371. }
  1372. const blob = new Blob([
  1373. "\"use strict\";",
  1374. `const waitForSuccessfulPingInternal = ${waitForSuccessfulPingInternal.toString()};`,
  1375. `const fn = ${pingWorkerContentMain.toString()};`,
  1376. `fn(${JSON.stringify(socketUrl)})`
  1377. ], { type: "application/javascript" });
  1378. const objURL = URL.createObjectURL(blob);
  1379. const sharedWorker = new SharedWorker(objURL);
  1380. return new Promise((resolve, reject) => {
  1381. const onVisibilityChange = () => {
  1382. sharedWorker.port.postMessage({ visibility: document.visibilityState });
  1383. };
  1384. document.addEventListener("visibilitychange", onVisibilityChange);
  1385. sharedWorker.port.addEventListener("message", (event) => {
  1386. document.removeEventListener("visibilitychange", onVisibilityChange);
  1387. sharedWorker.port.close();
  1388. const data = event.data;
  1389. if (data.type === "error") {
  1390. reject(data.error);
  1391. return;
  1392. }
  1393. resolve();
  1394. });
  1395. onVisibilityChange();
  1396. sharedWorker.port.start();
  1397. });
  1398. }
  1399. function pingWorkerContentMain(socketUrl) {
  1400. self.addEventListener("connect", (_event) => {
  1401. const port = _event.ports[0];
  1402. if (!socketUrl) {
  1403. port.postMessage({
  1404. type: "error",
  1405. error: /* @__PURE__ */ new Error("socketUrl not found")
  1406. });
  1407. return;
  1408. }
  1409. const visibilityManager = {
  1410. currentState: "visible",
  1411. listeners: /* @__PURE__ */ new Set()
  1412. };
  1413. port.addEventListener("message", (event) => {
  1414. const { visibility } = event.data;
  1415. visibilityManager.currentState = visibility;
  1416. console.debug("[vite] new window visibility", visibility);
  1417. for (const listener of visibilityManager.listeners) listener(visibility);
  1418. });
  1419. port.start();
  1420. console.debug("[vite] connected from window");
  1421. waitForSuccessfulPingInternal(socketUrl, visibilityManager).then(() => {
  1422. console.debug("[vite] ping successful");
  1423. try {
  1424. port.postMessage({ type: "success" });
  1425. } catch (error) {
  1426. port.postMessage({
  1427. type: "error",
  1428. error
  1429. });
  1430. }
  1431. }, (error) => {
  1432. console.debug("[vite] error happened", error);
  1433. try {
  1434. port.postMessage({
  1435. type: "error",
  1436. error
  1437. });
  1438. } catch (error) {
  1439. port.postMessage({
  1440. type: "error",
  1441. error
  1442. });
  1443. }
  1444. });
  1445. });
  1446. }
  1447. async function waitForSuccessfulPingInternal(socketUrl, visibilityManager, ms = 1e3) {
  1448. function wait(ms) {
  1449. return new Promise((resolve) => setTimeout(resolve, ms));
  1450. }
  1451. async function ping() {
  1452. try {
  1453. const socket = new WebSocket(socketUrl, "vite-ping");
  1454. return new Promise((resolve) => {
  1455. function onOpen() {
  1456. resolve(true);
  1457. close();
  1458. }
  1459. function onError() {
  1460. resolve(false);
  1461. close();
  1462. }
  1463. function close() {
  1464. socket.removeEventListener("open", onOpen);
  1465. socket.removeEventListener("error", onError);
  1466. socket.close();
  1467. }
  1468. socket.addEventListener("open", onOpen);
  1469. socket.addEventListener("error", onError);
  1470. });
  1471. } catch {
  1472. return false;
  1473. }
  1474. }
  1475. function waitForWindowShow(visibilityManager) {
  1476. return new Promise((resolve) => {
  1477. const onChange = (newVisibility) => {
  1478. if (newVisibility === "visible") {
  1479. resolve();
  1480. visibilityManager.listeners.delete(onChange);
  1481. }
  1482. };
  1483. visibilityManager.listeners.add(onChange);
  1484. });
  1485. }
  1486. if (await ping()) return;
  1487. await wait(ms);
  1488. while (true) if (visibilityManager.currentState === "visible") {
  1489. if (await ping()) break;
  1490. await wait(ms);
  1491. } else await waitForWindowShow(visibilityManager);
  1492. }
  1493. const sheetsMap = /* @__PURE__ */ new Map();
  1494. const linkSheetsMap = /* @__PURE__ */ new Map();
  1495. if ("document" in globalThis) {
  1496. document.querySelectorAll("style[data-vite-dev-id]").forEach((el) => {
  1497. sheetsMap.set(el.getAttribute("data-vite-dev-id"), el);
  1498. });
  1499. document.querySelectorAll("link[rel=\"stylesheet\"][data-vite-dev-id]").forEach((el) => {
  1500. linkSheetsMap.set(el.getAttribute("data-vite-dev-id"), el);
  1501. });
  1502. }
  1503. let lastInsertedStyle;
  1504. function updateStyle(id, content) {
  1505. if (linkSheetsMap.has(id)) return;
  1506. let style = sheetsMap.get(id);
  1507. if (!style) {
  1508. style = document.createElement("style");
  1509. style.setAttribute("type", "text/css");
  1510. style.setAttribute("data-vite-dev-id", id);
  1511. style.textContent = content;
  1512. if (cspNonce) style.setAttribute("nonce", cspNonce);
  1513. if (!lastInsertedStyle) {
  1514. document.head.appendChild(style);
  1515. setTimeout(() => {
  1516. lastInsertedStyle = void 0;
  1517. }, 0);
  1518. } else lastInsertedStyle.insertAdjacentElement("afterend", style);
  1519. lastInsertedStyle = style;
  1520. } else style.textContent = content;
  1521. sheetsMap.set(id, style);
  1522. }
  1523. function removeStyle(id) {
  1524. if (linkSheetsMap.has(id)) {
  1525. document.querySelectorAll(`link[rel="stylesheet"][data-vite-dev-id="${CSS.escape(id)}"]`).forEach((el) => el.remove());
  1526. linkSheetsMap.delete(id);
  1527. }
  1528. const style = sheetsMap.get(id);
  1529. if (style) {
  1530. document.head.removeChild(style);
  1531. sheetsMap.delete(id);
  1532. }
  1533. }
  1534. function createHotContext(ownerPath) {
  1535. return new HMRContext(hmrClient, ownerPath);
  1536. }
  1537. /**
  1538. * urls here are dynamic import() urls that couldn't be statically analyzed
  1539. */
  1540. function injectQuery(url, queryToInject) {
  1541. if (url[0] !== "." && url[0] !== "/") return url;
  1542. const pathname = url.replace(/[?#].*$/, "");
  1543. const { search, hash } = new URL(url, "http://vite.dev");
  1544. return `${pathname}?${queryToInject}${search ? `&` + search.slice(1) : ""}${hash || ""}`;
  1545. }
  1546. //#endregion
  1547. //#region src/client/bundledDevClient.ts
  1548. if (typeof DevRuntime !== "undefined") {
  1549. var _ref;
  1550. class ViteDevRuntime extends DevRuntime {
  1551. payloadDelivered(filename) {
  1552. transport.send({
  1553. type: "custom",
  1554. event: "vite:bundled-dev:payload-delivered",
  1555. data: { filename }
  1556. });
  1557. }
  1558. createModuleHotContext(moduleId) {
  1559. const ctx = new BundledDevHMRContext(bundledDevHmrClient, moduleId);
  1560. ctx._internal = {
  1561. updateStyle,
  1562. removeStyle
  1563. };
  1564. return ctx;
  1565. }
  1566. }
  1567. const clientId = nanoid();
  1568. transport.send({
  1569. type: "custom",
  1570. event: "vite:client-connected",
  1571. data: { clientId }
  1572. });
  1573. const runtime = (_ref = globalThis).__rolldown_runtime__ ?? (_ref.__rolldown_runtime__ = new ViteDevRuntime(clientId));
  1574. const bundledDevHmrClient = new BundledDevHMRClient({
  1575. error: (err) => console.error("[vite]", err),
  1576. debug: (...msg) => console.debug("[vite]", ...msg)
  1577. }, transport, runtime, {
  1578. base,
  1579. beforeApply: clearOverlayOrReloadOnFirstUpdate
  1580. });
  1581. registerBundledDevClient(bundledDevHmrClient);
  1582. runtime.hooks = {
  1583. createModuleHotContext: (id) => runtime.createModuleHotContext(id),
  1584. onModuleCacheRemoval: (id) => bundledDevHmrClient.handleModuleCacheRemoval(id)
  1585. };
  1586. }
  1587. //#endregion
  1588. export { ErrorOverlay, createHotContext, injectQuery, removeStyle, updateStyle };