index.mjs 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457
  1. import process from 'node:process';
  2. import { debounce } from 'perfect-debounce';
  3. import c from 'picocolors';
  4. import sirv from 'sirv';
  5. import { dirname, resolve, isAbsolute, join } from 'node:path';
  6. import { fileURLToPath } from 'node:url';
  7. import fs from 'fs-extra';
  8. import { Buffer as Buffer$1 } from 'node:buffer';
  9. import { createFilter } from '@rollup/pluginutils';
  10. import Debug from 'debug';
  11. import { parse } from 'error-stack-parser-es';
  12. import { createServer } from 'node:http';
  13. const DEFAULT_TIMEOUT = 6e4;
  14. function defaultSerialize(i) {
  15. return i;
  16. }
  17. const defaultDeserialize = defaultSerialize;
  18. const { clearTimeout, setTimeout: setTimeout$1 } = globalThis;
  19. const random = Math.random.bind(Math);
  20. function createBirpc(functions, options) {
  21. const {
  22. post,
  23. on,
  24. off = () => {
  25. },
  26. eventNames = [],
  27. serialize = defaultSerialize,
  28. deserialize = defaultDeserialize,
  29. resolver,
  30. bind = "rpc",
  31. timeout = DEFAULT_TIMEOUT
  32. } = options;
  33. const rpcPromiseMap = /* @__PURE__ */ new Map();
  34. let _promise;
  35. let closed = false;
  36. const rpc = new Proxy({}, {
  37. get(_, method) {
  38. if (method === "$functions")
  39. return functions;
  40. if (method === "$close")
  41. return close;
  42. if (method === "then" && !eventNames.includes("then") && !("then" in functions))
  43. return void 0;
  44. const sendEvent = (...args) => {
  45. post(serialize({ m: method, a: args, t: "q" }));
  46. };
  47. if (eventNames.includes(method)) {
  48. sendEvent.asEvent = sendEvent;
  49. return sendEvent;
  50. }
  51. const sendCall = async (...args) => {
  52. if (closed)
  53. throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
  54. if (_promise) {
  55. try {
  56. await _promise;
  57. } finally {
  58. _promise = void 0;
  59. }
  60. }
  61. return new Promise((resolve, reject) => {
  62. const id = nanoid();
  63. let timeoutId;
  64. if (timeout >= 0) {
  65. timeoutId = setTimeout$1(() => {
  66. try {
  67. options.onTimeoutError?.(method, args);
  68. throw new Error(`[birpc] timeout on calling "${method}"`);
  69. } catch (e) {
  70. reject(e);
  71. }
  72. rpcPromiseMap.delete(id);
  73. }, timeout);
  74. if (typeof timeoutId === "object")
  75. timeoutId = timeoutId.unref?.();
  76. }
  77. rpcPromiseMap.set(id, { resolve, reject, timeoutId, method });
  78. post(serialize({ m: method, a: args, i: id, t: "q" }));
  79. });
  80. };
  81. sendCall.asEvent = sendEvent;
  82. return sendCall;
  83. }
  84. });
  85. function close() {
  86. closed = true;
  87. rpcPromiseMap.forEach(({ reject, method }) => {
  88. reject(new Error(`[birpc] rpc is closed, cannot call "${method}"`));
  89. });
  90. rpcPromiseMap.clear();
  91. off(onMessage);
  92. }
  93. async function onMessage(data, ...extra) {
  94. const msg = deserialize(data);
  95. if (msg.t === "q") {
  96. const { m: method, a: args } = msg;
  97. let result, error;
  98. const fn = resolver ? resolver(method, functions[method]) : functions[method];
  99. if (!fn) {
  100. error = new Error(`[birpc] function "${method}" not found`);
  101. } else {
  102. try {
  103. result = await fn.apply(bind === "rpc" ? rpc : functions, args);
  104. } catch (e) {
  105. error = e;
  106. }
  107. }
  108. if (msg.i) {
  109. if (error && options.onError)
  110. options.onError(error, method, args);
  111. post(serialize({ t: "s", i: msg.i, r: result, e: error }), ...extra);
  112. }
  113. } else {
  114. const { i: ack, r: result, e: error } = msg;
  115. const promise = rpcPromiseMap.get(ack);
  116. if (promise) {
  117. clearTimeout(promise.timeoutId);
  118. if (error)
  119. promise.reject(error);
  120. else
  121. promise.resolve(result);
  122. }
  123. rpcPromiseMap.delete(ack);
  124. }
  125. }
  126. _promise = on(onMessage);
  127. return rpc;
  128. }
  129. const cacheMap = /* @__PURE__ */ new WeakMap();
  130. function cachedMap(items, fn) {
  131. return items.map((i) => {
  132. let r = cacheMap.get(i);
  133. if (!r) {
  134. r = fn(i);
  135. cacheMap.set(i, r);
  136. }
  137. return r;
  138. });
  139. }
  140. function createBirpcGroup(functions, channels, options = {}) {
  141. const getChannels = () => typeof channels === "function" ? channels() : channels;
  142. const getClients = (channels2 = getChannels()) => cachedMap(channels2, (s) => createBirpc(functions, { ...options, ...s }));
  143. const broadcastProxy = new Proxy({}, {
  144. get(_, method) {
  145. const client = getClients();
  146. const callbacks = client.map((c) => c[method]);
  147. const sendCall = (...args) => {
  148. return Promise.all(callbacks.map((i) => i(...args)));
  149. };
  150. sendCall.asEvent = (...args) => {
  151. callbacks.map((i) => i.asEvent(...args));
  152. };
  153. return sendCall;
  154. }
  155. });
  156. function updateChannels(fn) {
  157. const channels2 = getChannels();
  158. fn?.(channels2);
  159. return getClients(channels2);
  160. }
  161. getClients();
  162. return {
  163. get clients() {
  164. return getClients();
  165. },
  166. functions,
  167. updateChannels,
  168. broadcast: broadcastProxy,
  169. /**
  170. * @deprecated use `broadcast`
  171. */
  172. // @ts-expect-error deprecated
  173. boardcast: broadcastProxy
  174. };
  175. }
  176. const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
  177. function nanoid(size = 21) {
  178. let id = "";
  179. let i = size;
  180. while (i--)
  181. id += urlAlphabet[random() * 64 | 0];
  182. return id;
  183. }
  184. function createRPCServer(name, ws, functions, options = {}) {
  185. const event = `${name}:rpc`;
  186. const group = createBirpcGroup(
  187. functions,
  188. () => cachedMap(
  189. Array.from(ws?.clients || []),
  190. (channel) => {
  191. if (channel.socket.readyState === channel.socket.CLOSED)
  192. return void 0;
  193. return {
  194. on: (fn) => {
  195. function handler(data, source) {
  196. if (!source.socket)
  197. throw new Error("source.socket is undefined");
  198. if (channel.socket === source.socket)
  199. fn(data, source);
  200. }
  201. ws.on(event, handler);
  202. channel.socket.on("close", () => {
  203. ws.off(event, handler);
  204. });
  205. },
  206. post: (data) => {
  207. channel.send(event, data);
  208. }
  209. };
  210. }
  211. ).filter((c) => !!c),
  212. options
  213. );
  214. ws.on("connection", () => {
  215. group.updateChannels();
  216. });
  217. return group.broadcast;
  218. }
  219. const DIR_DIST = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
  220. const DIR_CLIENT = resolve(DIR_DIST, "../dist/client");
  221. const defaults = Object.freeze({
  222. ignoreUnknown: false,
  223. respectType: false,
  224. respectFunctionNames: false,
  225. respectFunctionProperties: false,
  226. unorderedObjects: true,
  227. unorderedArrays: false,
  228. unorderedSets: false,
  229. excludeKeys: void 0,
  230. excludeValues: void 0,
  231. replacer: void 0
  232. });
  233. function objectHash(object, options) {
  234. if (options) {
  235. options = { ...defaults, ...options };
  236. } else {
  237. options = defaults;
  238. }
  239. const hasher = createHasher(options);
  240. hasher.dispatch(object);
  241. return hasher.toString();
  242. }
  243. const defaultPrototypesKeys = Object.freeze([
  244. "prototype",
  245. "__proto__",
  246. "constructor"
  247. ]);
  248. function createHasher(options) {
  249. let buff = "";
  250. let context = /* @__PURE__ */ new Map();
  251. const write = (str) => {
  252. buff += str;
  253. };
  254. return {
  255. toString() {
  256. return buff;
  257. },
  258. getContext() {
  259. return context;
  260. },
  261. dispatch(value) {
  262. if (options.replacer) {
  263. value = options.replacer(value);
  264. }
  265. const type = value === null ? "null" : typeof value;
  266. return this[type](value);
  267. },
  268. object(object) {
  269. if (object && typeof object.toJSON === "function") {
  270. return this.object(object.toJSON());
  271. }
  272. const objString = Object.prototype.toString.call(object);
  273. let objType = "";
  274. const objectLength = objString.length;
  275. if (objectLength < 10) {
  276. objType = "unknown:[" + objString + "]";
  277. } else {
  278. objType = objString.slice(8, objectLength - 1);
  279. }
  280. objType = objType.toLowerCase();
  281. let objectNumber = null;
  282. if ((objectNumber = context.get(object)) === void 0) {
  283. context.set(object, context.size);
  284. } else {
  285. return this.dispatch("[CIRCULAR:" + objectNumber + "]");
  286. }
  287. if (typeof Buffer !== "undefined" && Buffer.isBuffer && Buffer.isBuffer(object)) {
  288. write("buffer:");
  289. return write(object.toString("utf8"));
  290. }
  291. if (objType !== "object" && objType !== "function" && objType !== "asyncfunction") {
  292. if (this[objType]) {
  293. this[objType](object);
  294. } else if (!options.ignoreUnknown) {
  295. this.unkown(object, objType);
  296. }
  297. } else {
  298. let keys = Object.keys(object);
  299. if (options.unorderedObjects) {
  300. keys = keys.sort();
  301. }
  302. let extraKeys = [];
  303. if (options.respectType !== false && !isNativeFunction(object)) {
  304. extraKeys = defaultPrototypesKeys;
  305. }
  306. if (options.excludeKeys) {
  307. keys = keys.filter((key) => {
  308. return !options.excludeKeys(key);
  309. });
  310. extraKeys = extraKeys.filter((key) => {
  311. return !options.excludeKeys(key);
  312. });
  313. }
  314. write("object:" + (keys.length + extraKeys.length) + ":");
  315. const dispatchForKey = (key) => {
  316. this.dispatch(key);
  317. write(":");
  318. if (!options.excludeValues) {
  319. this.dispatch(object[key]);
  320. }
  321. write(",");
  322. };
  323. for (const key of keys) {
  324. dispatchForKey(key);
  325. }
  326. for (const key of extraKeys) {
  327. dispatchForKey(key);
  328. }
  329. }
  330. },
  331. array(arr, unordered) {
  332. unordered = unordered === void 0 ? options.unorderedArrays !== false : unordered;
  333. write("array:" + arr.length + ":");
  334. if (!unordered || arr.length <= 1) {
  335. for (const entry of arr) {
  336. this.dispatch(entry);
  337. }
  338. return;
  339. }
  340. const contextAdditions = /* @__PURE__ */ new Map();
  341. const entries = arr.map((entry) => {
  342. const hasher = createHasher(options);
  343. hasher.dispatch(entry);
  344. for (const [key, value] of hasher.getContext()) {
  345. contextAdditions.set(key, value);
  346. }
  347. return hasher.toString();
  348. });
  349. context = contextAdditions;
  350. entries.sort();
  351. return this.array(entries, false);
  352. },
  353. date(date) {
  354. return write("date:" + date.toJSON());
  355. },
  356. symbol(sym) {
  357. return write("symbol:" + sym.toString());
  358. },
  359. unkown(value, type) {
  360. write(type);
  361. if (!value) {
  362. return;
  363. }
  364. write(":");
  365. if (value && typeof value.entries === "function") {
  366. return this.array(
  367. Array.from(value.entries()),
  368. true
  369. /* ordered */
  370. );
  371. }
  372. },
  373. error(err) {
  374. return write("error:" + err.toString());
  375. },
  376. boolean(bool) {
  377. return write("bool:" + bool);
  378. },
  379. string(string) {
  380. write("string:" + string.length + ":");
  381. write(string);
  382. },
  383. function(fn) {
  384. write("fn:");
  385. if (isNativeFunction(fn)) {
  386. this.dispatch("[native]");
  387. } else {
  388. this.dispatch(fn.toString());
  389. }
  390. if (options.respectFunctionNames !== false) {
  391. this.dispatch("function-name:" + String(fn.name));
  392. }
  393. if (options.respectFunctionProperties) {
  394. this.object(fn);
  395. }
  396. },
  397. number(number) {
  398. return write("number:" + number);
  399. },
  400. xml(xml) {
  401. return write("xml:" + xml.toString());
  402. },
  403. null() {
  404. return write("Null");
  405. },
  406. undefined() {
  407. return write("Undefined");
  408. },
  409. regexp(regex) {
  410. return write("regex:" + regex.toString());
  411. },
  412. uint8array(arr) {
  413. write("uint8array:");
  414. return this.dispatch(Array.prototype.slice.call(arr));
  415. },
  416. uint8clampedarray(arr) {
  417. write("uint8clampedarray:");
  418. return this.dispatch(Array.prototype.slice.call(arr));
  419. },
  420. int8array(arr) {
  421. write("int8array:");
  422. return this.dispatch(Array.prototype.slice.call(arr));
  423. },
  424. uint16array(arr) {
  425. write("uint16array:");
  426. return this.dispatch(Array.prototype.slice.call(arr));
  427. },
  428. int16array(arr) {
  429. write("int16array:");
  430. return this.dispatch(Array.prototype.slice.call(arr));
  431. },
  432. uint32array(arr) {
  433. write("uint32array:");
  434. return this.dispatch(Array.prototype.slice.call(arr));
  435. },
  436. int32array(arr) {
  437. write("int32array:");
  438. return this.dispatch(Array.prototype.slice.call(arr));
  439. },
  440. float32array(arr) {
  441. write("float32array:");
  442. return this.dispatch(Array.prototype.slice.call(arr));
  443. },
  444. float64array(arr) {
  445. write("float64array:");
  446. return this.dispatch(Array.prototype.slice.call(arr));
  447. },
  448. arraybuffer(arr) {
  449. write("arraybuffer:");
  450. return this.dispatch(new Uint8Array(arr));
  451. },
  452. url(url) {
  453. return write("url:" + url.toString());
  454. },
  455. map(map) {
  456. write("map:");
  457. const arr = [...map];
  458. return this.array(arr, options.unorderedSets !== false);
  459. },
  460. set(set) {
  461. write("set:");
  462. const arr = [...set];
  463. return this.array(arr, options.unorderedSets !== false);
  464. },
  465. file(file) {
  466. write("file:");
  467. return this.dispatch([file.name, file.size, file.type, file.lastModfied]);
  468. },
  469. blob() {
  470. if (options.ignoreUnknown) {
  471. return write("[blob]");
  472. }
  473. throw new Error(
  474. 'Hashing Blob objects is currently not supported\nUse "options.replacer" or "options.ignoreUnknown"\n'
  475. );
  476. },
  477. domwindow() {
  478. return write("domwindow");
  479. },
  480. bigint(number) {
  481. return write("bigint:" + number.toString());
  482. },
  483. /* Node.js standard native objects */
  484. process() {
  485. return write("process");
  486. },
  487. timer() {
  488. return write("timer");
  489. },
  490. pipe() {
  491. return write("pipe");
  492. },
  493. tcp() {
  494. return write("tcp");
  495. },
  496. udp() {
  497. return write("udp");
  498. },
  499. tty() {
  500. return write("tty");
  501. },
  502. statwatcher() {
  503. return write("statwatcher");
  504. },
  505. securecontext() {
  506. return write("securecontext");
  507. },
  508. connection() {
  509. return write("connection");
  510. },
  511. zlib() {
  512. return write("zlib");
  513. },
  514. context() {
  515. return write("context");
  516. },
  517. nodescript() {
  518. return write("nodescript");
  519. },
  520. httpparser() {
  521. return write("httpparser");
  522. },
  523. dataview() {
  524. return write("dataview");
  525. },
  526. signal() {
  527. return write("signal");
  528. },
  529. fsevent() {
  530. return write("fsevent");
  531. },
  532. tlswrap() {
  533. return write("tlswrap");
  534. }
  535. };
  536. }
  537. const nativeFunc = "[native code] }";
  538. const nativeFuncLength = nativeFunc.length;
  539. function isNativeFunction(f) {
  540. if (typeof f !== "function") {
  541. return false;
  542. }
  543. return Function.prototype.toString.call(f).slice(-nativeFuncLength) === nativeFunc;
  544. }
  545. var __defProp$1$1 = Object.defineProperty;
  546. var __defNormalProp$1$1 = (obj, key, value) => key in obj ? __defProp$1$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  547. var __publicField$1$1 = (obj, key, value) => {
  548. __defNormalProp$1$1(obj, typeof key !== "symbol" ? key + "" : key, value);
  549. return value;
  550. };
  551. class WordArray {
  552. constructor(words, sigBytes) {
  553. __publicField$1$1(this, "words");
  554. __publicField$1$1(this, "sigBytes");
  555. words = this.words = words || [];
  556. this.sigBytes = sigBytes === void 0 ? words.length * 4 : sigBytes;
  557. }
  558. toString(encoder) {
  559. return (encoder || Hex).stringify(this);
  560. }
  561. concat(wordArray) {
  562. this.clamp();
  563. if (this.sigBytes % 4) {
  564. for (let i = 0; i < wordArray.sigBytes; i++) {
  565. const thatByte = wordArray.words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
  566. this.words[this.sigBytes + i >>> 2] |= thatByte << 24 - (this.sigBytes + i) % 4 * 8;
  567. }
  568. } else {
  569. for (let j = 0; j < wordArray.sigBytes; j += 4) {
  570. this.words[this.sigBytes + j >>> 2] = wordArray.words[j >>> 2];
  571. }
  572. }
  573. this.sigBytes += wordArray.sigBytes;
  574. return this;
  575. }
  576. clamp() {
  577. this.words[this.sigBytes >>> 2] &= 4294967295 << 32 - this.sigBytes % 4 * 8;
  578. this.words.length = Math.ceil(this.sigBytes / 4);
  579. }
  580. clone() {
  581. return new WordArray([...this.words]);
  582. }
  583. }
  584. const Hex = {
  585. stringify(wordArray) {
  586. const hexChars = [];
  587. for (let i = 0; i < wordArray.sigBytes; i++) {
  588. const bite = wordArray.words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
  589. hexChars.push((bite >>> 4).toString(16), (bite & 15).toString(16));
  590. }
  591. return hexChars.join("");
  592. }
  593. };
  594. const Base64 = {
  595. stringify(wordArray) {
  596. const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  597. const base64Chars = [];
  598. for (let i = 0; i < wordArray.sigBytes; i += 3) {
  599. const byte1 = wordArray.words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
  600. const byte2 = wordArray.words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 255;
  601. const byte3 = wordArray.words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 255;
  602. const triplet = byte1 << 16 | byte2 << 8 | byte3;
  603. for (let j = 0; j < 4 && i * 8 + j * 6 < wordArray.sigBytes * 8; j++) {
  604. base64Chars.push(keyStr.charAt(triplet >>> 6 * (3 - j) & 63));
  605. }
  606. }
  607. return base64Chars.join("");
  608. }
  609. };
  610. const Latin1 = {
  611. parse(latin1Str) {
  612. const latin1StrLength = latin1Str.length;
  613. const words = [];
  614. for (let i = 0; i < latin1StrLength; i++) {
  615. words[i >>> 2] |= (latin1Str.charCodeAt(i) & 255) << 24 - i % 4 * 8;
  616. }
  617. return new WordArray(words, latin1StrLength);
  618. }
  619. };
  620. const Utf8 = {
  621. parse(utf8Str) {
  622. return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
  623. }
  624. };
  625. class BufferedBlockAlgorithm {
  626. constructor() {
  627. __publicField$1$1(this, "_data", new WordArray());
  628. __publicField$1$1(this, "_nDataBytes", 0);
  629. __publicField$1$1(this, "_minBufferSize", 0);
  630. __publicField$1$1(this, "blockSize", 512 / 32);
  631. }
  632. reset() {
  633. this._data = new WordArray();
  634. this._nDataBytes = 0;
  635. }
  636. _append(data) {
  637. if (typeof data === "string") {
  638. data = Utf8.parse(data);
  639. }
  640. this._data.concat(data);
  641. this._nDataBytes += data.sigBytes;
  642. }
  643. _doProcessBlock(_dataWords, _offset) {
  644. }
  645. _process(doFlush) {
  646. let processedWords;
  647. let nBlocksReady = this._data.sigBytes / (this.blockSize * 4);
  648. if (doFlush) {
  649. nBlocksReady = Math.ceil(nBlocksReady);
  650. } else {
  651. nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
  652. }
  653. const nWordsReady = nBlocksReady * this.blockSize;
  654. const nBytesReady = Math.min(nWordsReady * 4, this._data.sigBytes);
  655. if (nWordsReady) {
  656. for (let offset = 0; offset < nWordsReady; offset += this.blockSize) {
  657. this._doProcessBlock(this._data.words, offset);
  658. }
  659. processedWords = this._data.words.splice(0, nWordsReady);
  660. this._data.sigBytes -= nBytesReady;
  661. }
  662. return new WordArray(processedWords, nBytesReady);
  663. }
  664. }
  665. class Hasher extends BufferedBlockAlgorithm {
  666. update(messageUpdate) {
  667. this._append(messageUpdate);
  668. this._process();
  669. return this;
  670. }
  671. finalize(messageUpdate) {
  672. if (messageUpdate) {
  673. this._append(messageUpdate);
  674. }
  675. }
  676. }
  677. var __defProp$2 = Object.defineProperty;
  678. var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  679. var __publicField$2 = (obj, key, value) => {
  680. __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
  681. return value;
  682. };
  683. const H = [
  684. 1779033703,
  685. -1150833019,
  686. 1013904242,
  687. -1521486534,
  688. 1359893119,
  689. -1694144372,
  690. 528734635,
  691. 1541459225
  692. ];
  693. const K = [
  694. 1116352408,
  695. 1899447441,
  696. -1245643825,
  697. -373957723,
  698. 961987163,
  699. 1508970993,
  700. -1841331548,
  701. -1424204075,
  702. -670586216,
  703. 310598401,
  704. 607225278,
  705. 1426881987,
  706. 1925078388,
  707. -2132889090,
  708. -1680079193,
  709. -1046744716,
  710. -459576895,
  711. -272742522,
  712. 264347078,
  713. 604807628,
  714. 770255983,
  715. 1249150122,
  716. 1555081692,
  717. 1996064986,
  718. -1740746414,
  719. -1473132947,
  720. -1341970488,
  721. -1084653625,
  722. -958395405,
  723. -710438585,
  724. 113926993,
  725. 338241895,
  726. 666307205,
  727. 773529912,
  728. 1294757372,
  729. 1396182291,
  730. 1695183700,
  731. 1986661051,
  732. -2117940946,
  733. -1838011259,
  734. -1564481375,
  735. -1474664885,
  736. -1035236496,
  737. -949202525,
  738. -778901479,
  739. -694614492,
  740. -200395387,
  741. 275423344,
  742. 430227734,
  743. 506948616,
  744. 659060556,
  745. 883997877,
  746. 958139571,
  747. 1322822218,
  748. 1537002063,
  749. 1747873779,
  750. 1955562222,
  751. 2024104815,
  752. -2067236844,
  753. -1933114872,
  754. -1866530822,
  755. -1538233109,
  756. -1090935817,
  757. -965641998
  758. ];
  759. const W = [];
  760. class SHA256 extends Hasher {
  761. constructor() {
  762. super(...arguments);
  763. __publicField$2(this, "_hash", new WordArray([...H]));
  764. }
  765. /**
  766. * Resets the internal state of the hash object to initial values.
  767. */
  768. reset() {
  769. super.reset();
  770. this._hash = new WordArray([...H]);
  771. }
  772. _doProcessBlock(M, offset) {
  773. const H2 = this._hash.words;
  774. let a = H2[0];
  775. let b = H2[1];
  776. let c = H2[2];
  777. let d = H2[3];
  778. let e = H2[4];
  779. let f = H2[5];
  780. let g = H2[6];
  781. let h = H2[7];
  782. for (let i = 0; i < 64; i++) {
  783. if (i < 16) {
  784. W[i] = M[offset + i] | 0;
  785. } else {
  786. const gamma0x = W[i - 15];
  787. const gamma0 = (gamma0x << 25 | gamma0x >>> 7) ^ (gamma0x << 14 | gamma0x >>> 18) ^ gamma0x >>> 3;
  788. const gamma1x = W[i - 2];
  789. const gamma1 = (gamma1x << 15 | gamma1x >>> 17) ^ (gamma1x << 13 | gamma1x >>> 19) ^ gamma1x >>> 10;
  790. W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
  791. }
  792. const ch = e & f ^ ~e & g;
  793. const maj = a & b ^ a & c ^ b & c;
  794. const sigma0 = (a << 30 | a >>> 2) ^ (a << 19 | a >>> 13) ^ (a << 10 | a >>> 22);
  795. const sigma1 = (e << 26 | e >>> 6) ^ (e << 21 | e >>> 11) ^ (e << 7 | e >>> 25);
  796. const t1 = h + sigma1 + ch + K[i] + W[i];
  797. const t2 = sigma0 + maj;
  798. h = g;
  799. g = f;
  800. f = e;
  801. e = d + t1 | 0;
  802. d = c;
  803. c = b;
  804. b = a;
  805. a = t1 + t2 | 0;
  806. }
  807. H2[0] = H2[0] + a | 0;
  808. H2[1] = H2[1] + b | 0;
  809. H2[2] = H2[2] + c | 0;
  810. H2[3] = H2[3] + d | 0;
  811. H2[4] = H2[4] + e | 0;
  812. H2[5] = H2[5] + f | 0;
  813. H2[6] = H2[6] + g | 0;
  814. H2[7] = H2[7] + h | 0;
  815. }
  816. /**
  817. * Finishes the hash calculation and returns the hash as a WordArray.
  818. *
  819. * @param {string} messageUpdate - Additional message content to include in the hash.
  820. * @returns {WordArray} The finalised hash as a WordArray.
  821. */
  822. finalize(messageUpdate) {
  823. super.finalize(messageUpdate);
  824. const nBitsTotal = this._nDataBytes * 8;
  825. const nBitsLeft = this._data.sigBytes * 8;
  826. this._data.words[nBitsLeft >>> 5] |= 128 << 24 - nBitsLeft % 32;
  827. this._data.words[(nBitsLeft + 64 >>> 9 << 4) + 14] = Math.floor(
  828. nBitsTotal / 4294967296
  829. );
  830. this._data.words[(nBitsLeft + 64 >>> 9 << 4) + 15] = nBitsTotal;
  831. this._data.sigBytes = this._data.words.length * 4;
  832. this._process();
  833. return this._hash;
  834. }
  835. }
  836. function sha256base64(message) {
  837. return new SHA256().finalize(message).toString(Base64);
  838. }
  839. function hash(object, options = {}) {
  840. const hashed = typeof object === "string" ? object : objectHash(object, options);
  841. return sha256base64(hashed).slice(0, 10);
  842. }
  843. const DUMMY_LOAD_PLUGIN_NAME = "__load__";
  844. async function generateBuild(ctx, config) {
  845. const {
  846. outputDir = ".vite-inspect"
  847. } = ctx.options;
  848. const targetDir = isAbsolute(outputDir) ? outputDir : resolve(config.root, outputDir);
  849. const reportsDir = join(targetDir, "reports");
  850. await fs.emptyDir(targetDir);
  851. await fs.ensureDir(reportsDir);
  852. await fs.copy(DIR_CLIENT, targetDir);
  853. const isVirtual = (pluginName, transformName) => pluginName !== DUMMY_LOAD_PLUGIN_NAME && transformName !== "vite:load-fallback";
  854. function list() {
  855. return {
  856. root: config.root,
  857. modules: ctx.getModulesInfo(ctx.recorderClient, null, isVirtual),
  858. ssrModules: ctx.getModulesInfo(ctx.recorderServer, null, isVirtual)
  859. };
  860. }
  861. async function dumpModuleInfo(dir, recorder, ssr = false) {
  862. await fs.ensureDir(dir);
  863. return Promise.all(
  864. Object.entries(recorder.transform).map(
  865. ([id, info]) => fs.writeJSON(
  866. join(dir, `${hash(id)}.json`),
  867. {
  868. resolvedId: ctx.resolveId(id, ssr),
  869. transforms: info
  870. },
  871. { spaces: 2 }
  872. )
  873. )
  874. );
  875. }
  876. await Promise.all([
  877. fs.writeFile(
  878. join(targetDir, "index.html"),
  879. (await fs.readFile(join(targetDir, "index.html"), "utf-8")).replace(
  880. 'data-vite-inspect-mode="DEV"',
  881. 'data-vite-inspect-mode="BUILD"'
  882. )
  883. ),
  884. fs.writeJSON(
  885. join(reportsDir, "list.json"),
  886. list(),
  887. { spaces: 2 }
  888. ),
  889. fs.writeJSON(
  890. join(reportsDir, "metrics.json"),
  891. ctx.getPluginMetrics(false),
  892. { spaces: 2 }
  893. ),
  894. fs.writeJSON(
  895. join(reportsDir, "metrics-ssr.json"),
  896. ctx.getPluginMetrics(true),
  897. { spaces: 2 }
  898. ),
  899. dumpModuleInfo(join(reportsDir, "transform"), ctx.recorderClient),
  900. dumpModuleInfo(join(reportsDir, "transform-ssr"), ctx.recorderServer, true)
  901. ]);
  902. return targetDir;
  903. }
  904. var __defProp$1 = Object.defineProperty;
  905. var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  906. var __publicField$1 = (obj, key, value) => {
  907. __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
  908. return value;
  909. };
  910. class Recorder {
  911. constructor(context) {
  912. this.context = context;
  913. __publicField$1(this, "transform", {});
  914. __publicField$1(this, "resolveId", {});
  915. __publicField$1(this, "transformCounter", {});
  916. this.context = context;
  917. }
  918. recordTransform(id, info, preTransformCode) {
  919. id = this.context.normalizeId(id);
  920. if (!this.transform[id] || !this.transform[id].some((tr) => tr.result)) {
  921. this.transform[id] = [{
  922. name: DUMMY_LOAD_PLUGIN_NAME,
  923. result: preTransformCode,
  924. start: info.start,
  925. end: info.start,
  926. sourcemaps: info.sourcemaps
  927. }];
  928. this.transformCounter[id] = (this.transformCounter[id] || 0) + 1;
  929. }
  930. this.transform[id].push(info);
  931. }
  932. recordLoad(id, info) {
  933. id = this.context.normalizeId(id);
  934. this.transform[id] = [info];
  935. this.transformCounter[id] = (this.transformCounter[id] || 0) + 1;
  936. }
  937. recordResolveId(id, info) {
  938. id = this.context.normalizeId(id);
  939. if (!this.resolveId[id])
  940. this.resolveId[id] = [];
  941. this.resolveId[id].push(info);
  942. }
  943. invalidate(id) {
  944. id = this.context.normalizeId(id);
  945. delete this.transform[id];
  946. }
  947. }
  948. async function openBrowser(address) {
  949. await import('open').then((r) => r.default(address, { newInstance: true })).catch(() => {
  950. });
  951. }
  952. function removeVersionQuery(url) {
  953. if (url.includes("v=")) {
  954. return url.replace(/&v=\w+/, "").replace(/\?v=\w+/, "?").replace(/\?$/, "");
  955. }
  956. return url;
  957. }
  958. var __defProp = Object.defineProperty;
  959. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  960. var __publicField = (obj, key, value) => {
  961. __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  962. return value;
  963. };
  964. class ViteInspectContext {
  965. constructor(options) {
  966. this.options = options;
  967. __publicField(this, "filter");
  968. __publicField(this, "config");
  969. __publicField(this, "recorderClient");
  970. __publicField(this, "recorderServer");
  971. this.filter = createFilter(options.include, options.exclude);
  972. this.recorderClient = new Recorder(this);
  973. this.recorderServer = new Recorder(this);
  974. }
  975. normalizeId(id) {
  976. if (this.options.removeVersionQuery !== false)
  977. return removeVersionQuery(id);
  978. return id;
  979. }
  980. getRecorder(ssr) {
  981. return ssr ? this.recorderServer : this.recorderClient;
  982. }
  983. resolveId(id = "", ssr = false) {
  984. if (id.startsWith("./"))
  985. id = resolve(this.config.root, id).replace(/\\/g, "/");
  986. return this.resolveIdRecursive(id, ssr);
  987. }
  988. resolveIdRecursive(id, ssr = false) {
  989. const rec = this.getRecorder(ssr);
  990. const resolved = rec.resolveId[id]?.[0]?.result;
  991. return resolved ? this.resolveIdRecursive(resolved, ssr) : id;
  992. }
  993. getList(server) {
  994. const isVirtual = (pluginName) => pluginName !== DUMMY_LOAD_PLUGIN_NAME;
  995. const getDeps = (id) => Array.from(server.moduleGraph.getModuleById(id)?.importedModules || []).map((i) => i.id || "").filter(Boolean);
  996. return {
  997. root: this.config.root,
  998. modules: this.getModulesInfo(this.recorderClient, getDeps, isVirtual),
  999. ssrModules: this.getModulesInfo(this.recorderServer, getDeps, isVirtual)
  1000. };
  1001. }
  1002. getModulesInfo(recorder, getDeps, isVirtual) {
  1003. function transformIdMap(recorder2) {
  1004. return Object.values(recorder2.resolveId).reduce((map, ids2) => {
  1005. ids2.forEach((id) => {
  1006. var _a;
  1007. map[_a = id.result] ?? (map[_a] = []);
  1008. map[id.result].push(id);
  1009. });
  1010. return map;
  1011. }, {});
  1012. }
  1013. const transformedIdMap = transformIdMap(recorder);
  1014. const ids = new Set(Object.keys(recorder.transform).concat(Object.keys(transformedIdMap)));
  1015. return Array.from(ids).sort().map((id) => {
  1016. let totalTime = 0;
  1017. const plugins = (recorder.transform[id] || []).filter((tr) => tr.result).map((transItem) => {
  1018. const delta = transItem.end - transItem.start;
  1019. totalTime += delta;
  1020. return { name: transItem.name, transform: delta };
  1021. }).concat(
  1022. // @ts-expect-error transform is optional
  1023. (transformedIdMap[id] || []).map((idItem) => {
  1024. return { name: idItem.name, resolveId: idItem.end - idItem.start };
  1025. })
  1026. );
  1027. function getSize(str) {
  1028. if (!str)
  1029. return 0;
  1030. return Buffer$1.byteLength(str, "utf8");
  1031. }
  1032. return {
  1033. id,
  1034. deps: getDeps ? getDeps(id) : [],
  1035. plugins,
  1036. virtual: isVirtual(plugins[0]?.name || "", recorder.transform[id]?.[0].name || ""),
  1037. totalTime,
  1038. invokeCount: recorder.transformCounter?.[id] || 0,
  1039. sourceSize: getSize(recorder.transform[id]?.[0]?.result),
  1040. distSize: getSize(recorder.transform[id]?.[recorder.transform[id].length - 1]?.result)
  1041. };
  1042. });
  1043. }
  1044. getPluginMetrics(ssr = false) {
  1045. const map = {};
  1046. const defaultMetricInfo = () => ({
  1047. transform: { invokeCount: 0, totalTime: 0 },
  1048. resolveId: { invokeCount: 0, totalTime: 0 }
  1049. });
  1050. this.config.plugins.forEach((i) => {
  1051. map[i.name] = {
  1052. ...defaultMetricInfo(),
  1053. name: i.name,
  1054. enforce: i.enforce
  1055. };
  1056. });
  1057. const recorder = this.getRecorder(ssr);
  1058. Object.values(recorder.transform).forEach((transformInfos) => {
  1059. transformInfos.forEach(({ name, start, end }) => {
  1060. if (name === DUMMY_LOAD_PLUGIN_NAME)
  1061. return;
  1062. if (!map[name])
  1063. map[name] = { ...defaultMetricInfo(), name };
  1064. map[name].transform.totalTime += end - start;
  1065. map[name].transform.invokeCount += 1;
  1066. });
  1067. });
  1068. Object.values(recorder.resolveId).forEach((resolveIdInfos) => {
  1069. resolveIdInfos.forEach(({ name, start, end }) => {
  1070. if (!map[name])
  1071. map[name] = { ...defaultMetricInfo(), name };
  1072. map[name].resolveId.totalTime += end - start;
  1073. map[name].resolveId.invokeCount += 1;
  1074. });
  1075. });
  1076. const metrics = Object.values(map).filter(Boolean).sort((a, b) => a.name.localeCompare(b.name));
  1077. return metrics;
  1078. }
  1079. }
  1080. const debug = Debug("vite-plugin-inspect");
  1081. function hijackHook(plugin, name, wrapper) {
  1082. if (!plugin[name])
  1083. return;
  1084. debug(`hijack plugin "${name}"`, plugin.name);
  1085. let order = plugin.order || plugin.enforce || "normal";
  1086. const hook = plugin[name];
  1087. if ("handler" in hook) {
  1088. const oldFn = hook.handler;
  1089. order += `-${hook.order || hook.enforce || "normal"}`;
  1090. hook.handler = function(...args) {
  1091. return wrapper(oldFn, this, args, order);
  1092. };
  1093. } else if ("transform" in hook) {
  1094. const oldFn = hook.transform;
  1095. order += `-${hook.order || hook.enforce || "normal"}`;
  1096. hook.transform = function(...args) {
  1097. return wrapper(oldFn, this, args, order);
  1098. };
  1099. } else {
  1100. const oldFn = hook;
  1101. plugin[name] = function(...args) {
  1102. return wrapper(oldFn, this, args, order);
  1103. };
  1104. }
  1105. }
  1106. function hijackPlugin(plugin, ctx) {
  1107. hijackHook(plugin, "transform", async (fn, context, args, order) => {
  1108. const code = args[0];
  1109. const id = args[1];
  1110. const ssr = args[2]?.ssr;
  1111. let _result;
  1112. let error;
  1113. const start = Date.now();
  1114. try {
  1115. _result = await fn.apply(context, args);
  1116. } catch (_err) {
  1117. error = _err;
  1118. }
  1119. const end = Date.now();
  1120. const result = error ? "[Error]" : typeof _result === "string" ? _result : _result?.code;
  1121. if (ctx.filter(id)) {
  1122. const sourcemaps = typeof _result === "string" ? null : _result?.map;
  1123. const rec = ctx.getRecorder(ssr);
  1124. rec.recordTransform(id, {
  1125. name: plugin.name,
  1126. result,
  1127. start,
  1128. end,
  1129. order,
  1130. sourcemaps,
  1131. error: error ? parseError(error) : void 0
  1132. }, code);
  1133. }
  1134. if (error)
  1135. throw error;
  1136. return _result;
  1137. });
  1138. hijackHook(plugin, "load", async (fn, context, args) => {
  1139. const id = args[0];
  1140. const ssr = args[1]?.ssr;
  1141. let _result;
  1142. let error;
  1143. const start = Date.now();
  1144. try {
  1145. _result = await fn.apply(context, args);
  1146. } catch (err) {
  1147. error = err;
  1148. }
  1149. const end = Date.now();
  1150. const result = error ? "[Error]" : typeof _result === "string" ? _result : _result?.code;
  1151. const sourcemaps = typeof _result === "string" ? null : _result?.map;
  1152. if (result) {
  1153. ctx.getRecorder(ssr).recordLoad(id, {
  1154. name: plugin.name,
  1155. result,
  1156. start,
  1157. end,
  1158. sourcemaps,
  1159. error: error ? parseError(error) : void 0
  1160. });
  1161. }
  1162. if (error)
  1163. throw error;
  1164. return _result;
  1165. });
  1166. hijackHook(plugin, "resolveId", async (fn, context, args) => {
  1167. const id = args[0];
  1168. const ssr = args[2]?.ssr;
  1169. let _result;
  1170. let error;
  1171. const start = Date.now();
  1172. try {
  1173. _result = await fn.apply(context, args);
  1174. } catch (err) {
  1175. error = err;
  1176. }
  1177. const end = Date.now();
  1178. if (!ctx.filter(id)) {
  1179. if (error)
  1180. throw error;
  1181. return _result;
  1182. }
  1183. const result = error ? stringifyError(error) : typeof _result === "object" ? _result?.id : _result;
  1184. if (result && result !== id) {
  1185. ctx.getRecorder(ssr).recordResolveId(id, {
  1186. name: plugin.name,
  1187. result,
  1188. start,
  1189. end,
  1190. error
  1191. });
  1192. }
  1193. if (error)
  1194. throw error;
  1195. return _result;
  1196. });
  1197. }
  1198. function parseError(error) {
  1199. const stack = parse(error, { allowEmpty: true });
  1200. const message = error.message || String(error);
  1201. return {
  1202. message,
  1203. stack,
  1204. raw: error
  1205. };
  1206. }
  1207. function stringifyError(err) {
  1208. return String(err.stack ? err.stack : err);
  1209. }
  1210. function createPreviewServer(staticPath) {
  1211. const server = createServer();
  1212. const statics = sirv(staticPath);
  1213. server.on("request", (req, res) => {
  1214. statics(req, res, () => {
  1215. res.statusCode = 404;
  1216. res.end("File not found");
  1217. });
  1218. });
  1219. server.listen(0, () => {
  1220. const { port } = server.address();
  1221. const url = `http://localhost:${port}`;
  1222. console.log(` ${c.green("\u279C")} ${c.bold("Inspect Preview Started")}: ${url}`);
  1223. openBrowser(url);
  1224. });
  1225. }
  1226. const NAME = "vite-plugin-inspect";
  1227. const isCI = !!process.env.CI;
  1228. function PluginInspect(options = {}) {
  1229. const {
  1230. dev = true,
  1231. build = false,
  1232. silent = false,
  1233. open: _open = false
  1234. } = options;
  1235. if (!dev && !build) {
  1236. return {
  1237. name: NAME
  1238. };
  1239. }
  1240. const ctx = new ViteInspectContext(options);
  1241. const timestampRE = /\bt=\d{13}&?\b/;
  1242. const trailingSeparatorRE = /[?&]$/;
  1243. let config;
  1244. const serverPerf = {
  1245. middleware: {}
  1246. };
  1247. function setupMiddlewarePerf(middlewares) {
  1248. let firstMiddlewareIndex = -1;
  1249. middlewares.forEach((middleware, index) => {
  1250. const { handle: originalHandle } = middleware;
  1251. if (typeof originalHandle !== "function" || !originalHandle.name)
  1252. return middleware;
  1253. middleware.handle = (...middlewareArgs) => {
  1254. var _a;
  1255. let req;
  1256. if (middlewareArgs.length === 4)
  1257. [, req] = middlewareArgs;
  1258. else
  1259. [req] = middlewareArgs;
  1260. const start = Date.now();
  1261. const url = req.url?.replace(timestampRE, "").replace(trailingSeparatorRE, "");
  1262. (_a = serverPerf.middleware)[url] ?? (_a[url] = []);
  1263. if (firstMiddlewareIndex < 0)
  1264. firstMiddlewareIndex = index;
  1265. if (index === firstMiddlewareIndex)
  1266. serverPerf.middleware[url] = [];
  1267. const result = originalHandle(...middlewareArgs);
  1268. Promise.resolve(result).then(() => {
  1269. const total = Date.now() - start;
  1270. const metrics = serverPerf.middleware[url];
  1271. serverPerf.middleware[url].push({
  1272. self: metrics.length ? Math.max(total - metrics[metrics.length - 1].total, 0) : total,
  1273. total,
  1274. name: originalHandle.name
  1275. });
  1276. });
  1277. return result;
  1278. };
  1279. Object.defineProperty(middleware.handle, "name", {
  1280. value: originalHandle.name,
  1281. configurable: true,
  1282. enumerable: true
  1283. });
  1284. return middleware;
  1285. });
  1286. }
  1287. function configureServer(server) {
  1288. const _invalidateModule = server.moduleGraph.invalidateModule;
  1289. server.moduleGraph.invalidateModule = function(...args) {
  1290. const mod = args[0];
  1291. if (mod?.id) {
  1292. ctx.recorderClient.invalidate(mod.id);
  1293. ctx.recorderServer.invalidate(mod.id);
  1294. }
  1295. return _invalidateModule.apply(this, args);
  1296. };
  1297. const base = (options.base ?? server.config.base) || "/";
  1298. server.middlewares.use(`${base}__inspect`, sirv(DIR_CLIENT, {
  1299. single: true,
  1300. dev: true
  1301. }));
  1302. const rpcFunctions = {
  1303. list: () => ctx.getList(server),
  1304. getIdInfo,
  1305. getPluginMetrics: (ssr = false) => ctx.getPluginMetrics(ssr),
  1306. getServerMetrics,
  1307. resolveId: (id, ssr = false) => ctx.resolveId(id, ssr),
  1308. clear: clearId,
  1309. moduleUpdated: () => {
  1310. }
  1311. };
  1312. const rpcServer = createRPCServer("vite-plugin-inspect", server.ws, rpcFunctions);
  1313. const debouncedModuleUpdated = debounce(() => {
  1314. rpcServer.moduleUpdated.asEvent();
  1315. }, 100);
  1316. server.middlewares.use((req, res, next) => {
  1317. debouncedModuleUpdated();
  1318. next();
  1319. });
  1320. function getServerMetrics() {
  1321. return serverPerf || {};
  1322. }
  1323. async function getIdInfo(id, ssr = false, clear = false) {
  1324. if (clear) {
  1325. clearId(id, ssr);
  1326. try {
  1327. await server.transformRequest(id, { ssr });
  1328. } catch {
  1329. }
  1330. }
  1331. const resolvedId = ctx.resolveId(id, ssr);
  1332. const recorder = ctx.getRecorder(ssr);
  1333. return {
  1334. resolvedId,
  1335. transforms: recorder.transform[resolvedId] || []
  1336. };
  1337. }
  1338. function clearId(_id, ssr = false) {
  1339. const id = ctx.resolveId(_id);
  1340. if (id) {
  1341. const mod = server.moduleGraph.getModuleById(id);
  1342. if (mod)
  1343. server.moduleGraph.invalidateModule(mod);
  1344. ctx.getRecorder(ssr).invalidate(id);
  1345. }
  1346. }
  1347. const _print = server.printUrls;
  1348. server.printUrls = () => {
  1349. let host = `${config.server.https ? "https" : "http"}://localhost:${config.server.port || "80"}`;
  1350. const url = server.resolvedUrls?.local[0];
  1351. if (url) {
  1352. try {
  1353. const u = new URL(url);
  1354. host = `${u.protocol}//${u.host}`;
  1355. } catch (error) {
  1356. config.logger.warn(`Parse resolved url failed: ${error}`);
  1357. }
  1358. }
  1359. _print();
  1360. if (!silent) {
  1361. const colorUrl = (url2) => c.green(url2.replace(/:(\d+)\//, (_, port) => `:${c.bold(port)}/`));
  1362. config.logger.info(` ${c.green("\u279C")} ${c.bold("Inspect")}: ${colorUrl(`${host}${base}__inspect/`)}`);
  1363. }
  1364. if (_open && !isCI) {
  1365. setTimeout(() => {
  1366. openBrowser(`${host}${base}__inspect/`);
  1367. }, 500);
  1368. }
  1369. };
  1370. return rpcFunctions;
  1371. }
  1372. const plugin = {
  1373. name: NAME,
  1374. enforce: "pre",
  1375. apply(_, { command }) {
  1376. if (command === "serve" && dev)
  1377. return true;
  1378. if (command === "build" && build)
  1379. return true;
  1380. return false;
  1381. },
  1382. configResolved(_config) {
  1383. config = ctx.config = _config;
  1384. config.plugins.forEach((plugin2) => hijackPlugin(plugin2, ctx));
  1385. const _createResolver = config.createResolver;
  1386. config.createResolver = function(...args) {
  1387. const _resolver = _createResolver.apply(this, args);
  1388. return async function(...args2) {
  1389. const id = args2[0];
  1390. const aliasOnly = args2[2];
  1391. const ssr = args2[3];
  1392. const start = Date.now();
  1393. const result = await _resolver.apply(this, args2);
  1394. const end = Date.now();
  1395. if (result && result !== id) {
  1396. const pluginName = aliasOnly ? "alias" : "vite:resolve (+alias)";
  1397. ctx.getRecorder(ssr).recordResolveId(id, { name: pluginName, result, start, end });
  1398. }
  1399. return result;
  1400. };
  1401. };
  1402. },
  1403. configureServer(server) {
  1404. const rpc = configureServer(server);
  1405. plugin.api = {
  1406. rpc
  1407. };
  1408. return () => {
  1409. setupMiddlewarePerf(server.middlewares.stack);
  1410. };
  1411. },
  1412. load: {
  1413. order: "pre",
  1414. handler(id, { ssr } = {}) {
  1415. ctx.getRecorder(ssr).invalidate(id);
  1416. return null;
  1417. }
  1418. },
  1419. handleHotUpdate({ modules, server }) {
  1420. const ids = modules.map((module) => module.id);
  1421. server.ws.send({
  1422. type: "custom",
  1423. event: "vite-plugin-inspect:update",
  1424. data: { ids }
  1425. });
  1426. },
  1427. async buildEnd() {
  1428. if (!build)
  1429. return;
  1430. const dir = await generateBuild(ctx, config);
  1431. config.logger.info(`${c.green("Inspect report generated at")} ${c.dim(`${dir}`)}`);
  1432. if (_open && !isCI)
  1433. createPreviewServer(dir);
  1434. }
  1435. };
  1436. return plugin;
  1437. }
  1438. PluginInspect.getViteInspectAPI = function(plugins) {
  1439. return plugins.find((p) => p.name === NAME)?.api;
  1440. };
  1441. export { PluginInspect as default };