@nasti-toolchain/nasti 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -183,6 +183,14 @@ async function resolveConfig(inlineConfig = {}, command) {
183
183
  return p.apply === command;
184
184
  });
185
185
  resolved.plugins = filteredPlugins;
186
+ if (resolved.target === "electron") {
187
+ const autoExternal = detectNativeDeps(root);
188
+ if (autoExternal.length > 0) {
189
+ const current = new Set(resolved.electron.external ?? []);
190
+ for (const dep of autoExternal) current.add(dep);
191
+ resolved.electron.external = [...current];
192
+ }
193
+ }
186
194
  for (const plugin of resolved.plugins) {
187
195
  if (plugin.configResolved) {
188
196
  await plugin.configResolved(resolved);
@@ -190,6 +198,73 @@ async function resolveConfig(inlineConfig = {}, command) {
190
198
  }
191
199
  return resolved;
192
200
  }
201
+ function detectNativeDeps(root) {
202
+ const result = /* @__PURE__ */ new Set();
203
+ const pkgJsonPath = import_node_path.default.resolve(root, "package.json");
204
+ if (!import_node_fs.default.existsSync(pkgJsonPath)) return [];
205
+ let pkg;
206
+ try {
207
+ pkg = JSON.parse(import_node_fs.default.readFileSync(pkgJsonPath, "utf-8"));
208
+ } catch {
209
+ return [];
210
+ }
211
+ const deps = {
212
+ ...pkg.dependencies ?? {},
213
+ ...pkg.optionalDependencies ?? {}
214
+ };
215
+ const KNOWN_NATIVE = /* @__PURE__ */ new Set([
216
+ "node-pty",
217
+ "better-sqlite3",
218
+ "sharp",
219
+ "serialport",
220
+ "@vscode/tree-sitter-wasm",
221
+ "keytar",
222
+ "nodegit",
223
+ "sqlite3",
224
+ "fsevents"
225
+ ]);
226
+ for (const dep of Object.keys(deps)) {
227
+ if (KNOWN_NATIVE.has(dep)) {
228
+ result.add(dep);
229
+ continue;
230
+ }
231
+ const depDir = import_node_path.default.resolve(root, "node_modules", dep);
232
+ if (!import_node_fs.default.existsSync(depDir)) continue;
233
+ if (import_node_fs.default.existsSync(import_node_path.default.join(depDir, "binding.gyp"))) {
234
+ result.add(dep);
235
+ continue;
236
+ }
237
+ const subPkg = import_node_path.default.join(depDir, "package.json");
238
+ if (import_node_fs.default.existsSync(subPkg)) {
239
+ try {
240
+ const sub = JSON.parse(import_node_fs.default.readFileSync(subPkg, "utf-8"));
241
+ if (sub.gypfile === true || sub.binary?.module_name) {
242
+ result.add(dep);
243
+ continue;
244
+ }
245
+ } catch {
246
+ }
247
+ }
248
+ if (hasDotNodeFile(depDir)) {
249
+ result.add(dep);
250
+ }
251
+ }
252
+ return [...result];
253
+ }
254
+ function hasDotNodeFile(dir, depth = 0) {
255
+ if (depth > 3) return false;
256
+ try {
257
+ const entries = import_node_fs.default.readdirSync(dir, { withFileTypes: true });
258
+ for (const e of entries) {
259
+ if (e.isFile() && e.name.endsWith(".node")) return true;
260
+ if (e.isDirectory() && (e.name === "build" || e.name === "prebuilds" || e.name === "Release")) {
261
+ if (hasDotNodeFile(import_node_path.default.join(dir, e.name), depth + 1)) return true;
262
+ }
263
+ }
264
+ } catch {
265
+ }
266
+ return false;
267
+ }
193
268
  function deepMerge(target, source) {
194
269
  const result = { ...target };
195
270
  for (const key of Object.keys(source)) {
@@ -437,6 +512,15 @@ function htmlPlugin(config) {
437
512
  transformIndexHtml(html) {
438
513
  const tags = [];
439
514
  if (config.command === "serve") {
515
+ const isReactLike = config.framework === "react" || config.framework === "auto";
516
+ if (isReactLike) {
517
+ tags.push({
518
+ tag: "script",
519
+ attrs: { type: "module" },
520
+ children: REACT_REFRESH_HTML_PREAMBLE,
521
+ injectTo: "head-prepend"
522
+ });
523
+ }
440
524
  tags.push({
441
525
  tag: "script",
442
526
  attrs: { type: "module", src: "/@nasti/client" },
@@ -487,12 +571,19 @@ async function readHtmlFile(root) {
487
571
  if (!import_node_fs4.default.existsSync(htmlPath)) return null;
488
572
  return import_node_fs4.default.readFileSync(htmlPath, "utf-8");
489
573
  }
490
- var import_node_path5, import_node_fs4;
574
+ var import_node_path5, import_node_fs4, REACT_REFRESH_HTML_PREAMBLE;
491
575
  var init_html = __esm({
492
576
  "src/plugins/html.ts"() {
493
577
  "use strict";
494
578
  import_node_path5 = __toESM(require("path"), 1);
495
579
  import_node_fs4 = __toESM(require("fs"), 1);
580
+ REACT_REFRESH_HTML_PREAMBLE = `
581
+ import RefreshRuntime from "/@react-refresh";
582
+ RefreshRuntime.injectIntoGlobalHook(window);
583
+ window.$RefreshReg$ = () => {};
584
+ window.$RefreshSig$ = () => (type) => type;
585
+ window.__vite_plugin_react_preamble_installed__ = true;
586
+ `.trim();
496
587
  }
497
588
  });
498
589
 
@@ -723,7 +814,7 @@ __export(build_exports, {
723
814
  async function build(inlineConfig = {}) {
724
815
  const config = await resolveConfig(inlineConfig, "build");
725
816
  const startTime = performance.now();
726
- console.log(import_picocolors.default.cyan("\n\u{1F528} nasti build") + import_picocolors.default.dim(` v${"1.5.0"}`));
817
+ console.log(import_picocolors.default.cyan("\n\u{1F528} nasti build") + import_picocolors.default.dim(` v${"1.5.2"}`));
727
818
  console.log(import_picocolors.default.dim(` root: ${config.root}`));
728
819
  console.log(import_picocolors.default.dim(` mode: ${config.mode}`));
729
820
  const outDir = import_node_path7.default.resolve(config.root, config.build.outDir);
@@ -1033,9 +1124,89 @@ var init_ws = __esm({
1033
1124
  // src/server/middleware.ts
1034
1125
  var middleware_exports = {};
1035
1126
  __export(middleware_exports, {
1127
+ REACT_REFRESH_GLOBAL_PREAMBLE: () => REACT_REFRESH_GLOBAL_PREAMBLE,
1036
1128
  transformMiddleware: () => transformMiddleware,
1037
1129
  transformRequest: () => transformRequest
1038
1130
  });
1131
+ function getReactRefreshRuntimeEsm() {
1132
+ if (__refreshRuntimeCache) return __refreshRuntimeCache;
1133
+ let cjsPath;
1134
+ try {
1135
+ const pkgPath = __require.resolve("react-refresh/package.json");
1136
+ cjsPath = import_node_path9.default.join(import_node_path9.default.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
1137
+ } catch (err) {
1138
+ cjsPath = import_node_path9.default.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
1139
+ if (!import_node_fs8.default.existsSync(cjsPath)) {
1140
+ const origMsg = err instanceof Error ? err.message : String(err);
1141
+ throw new Error(
1142
+ `[nasti] Missing dependency "react-refresh". Install it with: npm install react-refresh
1143
+ Original resolve error: ${origMsg}`
1144
+ );
1145
+ }
1146
+ }
1147
+ const cjsSource = import_node_fs8.default.readFileSync(cjsPath, "utf-8");
1148
+ __refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM
1149
+ const exports = {};
1150
+ const module = { exports };
1151
+ const process = { env: { NODE_ENV: 'development' } };
1152
+ ${cjsSource}
1153
+ const __rt = module.exports;
1154
+ export const injectIntoGlobalHook = __rt.injectIntoGlobalHook;
1155
+ export const register = __rt.register;
1156
+ export const createSignatureFunctionForTransform = __rt.createSignatureFunctionForTransform;
1157
+ export const performReactRefresh = __rt.performReactRefresh;
1158
+ export const isLikelyComponentType = __rt.isLikelyComponentType;
1159
+ export const hasUnrecoverableErrors = __rt.hasUnrecoverableErrors;
1160
+ export const setSignature = __rt.setSignature;
1161
+ export const getFamilyByID = __rt.getFamilyByID;
1162
+ export const getFamilyByType = __rt.getFamilyByType;
1163
+ export const findAffectedHostInstances = __rt.findAffectedHostInstances;
1164
+ export const collectCustomHooksForSignature = __rt.collectCustomHooksForSignature;
1165
+ export default __rt;
1166
+ `;
1167
+ return __refreshRuntimeCache;
1168
+ }
1169
+ function buildReactRefreshWrapper(moduleUrl, transformedCode) {
1170
+ const urlLit = JSON.stringify(moduleUrl);
1171
+ const userCode = transformedCode.replace(/\bimport\.meta\.hot\b/g, "__nasti_hot__");
1172
+ return `import * as RefreshRuntime from "/@react-refresh";
1173
+ import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
1174
+ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
1175
+
1176
+ if (!window.__vite_plugin_react_preamble_installed__) {
1177
+ throw new Error("[nasti] React Fast Refresh preamble missing. Make sure nasti:html is wired with framework: 'react'.");
1178
+ }
1179
+
1180
+ const prevRefreshReg = window.$RefreshReg$;
1181
+ const prevRefreshSig = window.$RefreshSig$;
1182
+ window.$RefreshReg$ = (type, id) => {
1183
+ RefreshRuntime.register(type, ${urlLit} + " " + id);
1184
+ };
1185
+ window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
1186
+
1187
+ ${userCode}
1188
+
1189
+ window.$RefreshReg$ = prevRefreshReg;
1190
+ window.$RefreshSig$ = prevRefreshSig;
1191
+
1192
+ if (__nasti_hot__) {
1193
+ __nasti_hot__.accept(() => {
1194
+ clearTimeout(window.__nasti_refresh_timer__);
1195
+ window.__nasti_refresh_timer__ = setTimeout(() => {
1196
+ RefreshRuntime.performReactRefresh();
1197
+ }, 30);
1198
+ });
1199
+ }
1200
+ `;
1201
+ }
1202
+ function injectImportMetaHot(code, moduleUrl) {
1203
+ if (!/\bimport\.meta\.hot\b/.test(code)) return code;
1204
+ const urlLit = JSON.stringify(moduleUrl);
1205
+ const header = `import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
1206
+ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
1207
+ `;
1208
+ return header + code.replace(/\bimport\.meta\.hot\b/g, "__nasti_hot__");
1209
+ }
1039
1210
  function transformMiddleware(ctx) {
1040
1211
  ctx.envDefine = buildEnvDefine(
1041
1212
  loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
@@ -1109,7 +1280,7 @@ async function transformRequest(url, ctx) {
1109
1280
  return cached.transformResult;
1110
1281
  }
1111
1282
  if (cleanReqUrl === "/@react-refresh") {
1112
- return { code: REACT_REFRESH_RUNTIME };
1283
+ return { code: getReactRefreshRuntimeEsm() };
1113
1284
  }
1114
1285
  const filePath = resolveUrlToFile(url, config.root);
1115
1286
  if (!filePath || !import_node_fs8.default.existsSync(filePath)) return null;
@@ -1126,6 +1297,8 @@ async function transformRequest(url, ctx) {
1126
1297
  if (pluginResult) {
1127
1298
  code = typeof pluginResult === "string" ? pluginResult : pluginResult.code;
1128
1299
  }
1300
+ const stableUrl = cleanReqUrl;
1301
+ let wrappedWithRefresh = false;
1129
1302
  if (shouldTransform(filePath)) {
1130
1303
  const isJsx = /\.[jt]sx$/.test(filePath);
1131
1304
  const useRefresh = isJsx && config.framework !== "vue";
@@ -1137,9 +1310,14 @@ async function transformRequest(url, ctx) {
1137
1310
  });
1138
1311
  code = result.code;
1139
1312
  if (useRefresh) {
1140
- code = REACT_REFRESH_PREAMBLE + code + REACT_REFRESH_FOOTER;
1313
+ code = buildReactRefreshWrapper(stableUrl, code);
1314
+ wrappedWithRefresh = true;
1315
+ mod.isSelfAccepting = true;
1141
1316
  }
1142
1317
  }
1318
+ if (!wrappedWithRefresh) {
1319
+ code = injectImportMetaHot(code, stableUrl);
1320
+ }
1143
1321
  const envDefine = ctx.envDefine ?? buildEnvDefine(
1144
1322
  loadEnv(config.mode, config.root, config.envPrefix),
1145
1323
  config.mode
@@ -1207,8 +1385,8 @@ function rewriteExternalRequires(code) {
1207
1385
  }
1208
1386
  async function injectCjsNamedExports(code, entryFile) {
1209
1387
  try {
1210
- const { createRequire: createRequire4 } = await import("module");
1211
- const req = createRequire4(entryFile);
1388
+ const { createRequire: createRequire5 } = await import("module");
1389
+ const req = createRequire5(entryFile);
1212
1390
  const cjsExports = req(entryFile);
1213
1391
  if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
1214
1392
  const namedKeys = Object.keys(cjsExports).filter(
@@ -1371,12 +1549,15 @@ function getHmrClientCode() {
1371
1549
  // Nasti HMR Client
1372
1550
  const socket = new WebSocket(\`ws://\${location.host}\`, 'nasti-hmr');
1373
1551
  const hotModulesMap = new Map();
1552
+ const disposeMap = new Map();
1553
+ const pruneMap = new Map();
1374
1554
 
1375
1555
  socket.addEventListener('message', ({ data }) => {
1376
1556
  const payload = JSON.parse(data);
1377
1557
  switch (payload.type) {
1378
1558
  case 'connected':
1379
1559
  console.log('[nasti] connected.');
1560
+ clearErrorOverlay();
1380
1561
  break;
1381
1562
  case 'update':
1382
1563
  payload.updates.forEach((update) => {
@@ -1386,11 +1567,18 @@ socket.addEventListener('message', ({ data }) => {
1386
1567
  updateCss(update.path);
1387
1568
  }
1388
1569
  });
1570
+ clearErrorOverlay();
1389
1571
  break;
1390
1572
  case 'full-reload':
1391
1573
  console.log('[nasti] full reload');
1392
1574
  location.reload();
1393
1575
  break;
1576
+ case 'prune':
1577
+ payload.paths.forEach((p) => {
1578
+ const cb = pruneMap.get(p);
1579
+ if (cb) cb();
1580
+ });
1581
+ break;
1394
1582
  case 'error':
1395
1583
  console.error('[nasti] error:', payload.err.message);
1396
1584
  showErrorOverlay(payload.err);
@@ -1398,14 +1586,23 @@ socket.addEventListener('message', ({ data }) => {
1398
1586
  }
1399
1587
  });
1400
1588
 
1589
+ // \u81EA\u52A8\u91CD\u8FDE\uFF08\u65AD\u7EBF\u65F6\u6307\u6570\u9000\u907F\uFF09
1590
+ let reconnectTimer = 0;
1591
+ socket.addEventListener('close', () => {
1592
+ clearTimeout(reconnectTimer);
1593
+ reconnectTimer = setTimeout(() => location.reload(), 1000);
1594
+ });
1595
+
1401
1596
  async function fetchUpdate(update) {
1402
1597
  const mod = hotModulesMap.get(update.path);
1598
+ // \u5148\u8DD1 dispose\uFF08\u7ED9\u6A21\u5757\u673A\u4F1A\u6E05\u7406\u526F\u4F5C\u7528\uFF09
1599
+ const dispose = disposeMap.get(update.path);
1600
+ if (dispose) dispose();
1601
+
1602
+ const newMod = await import(update.acceptedPath + '?t=' + update.timestamp);
1403
1603
  if (mod) {
1404
- const newMod = await import(update.acceptedPath + '?t=' + update.timestamp);
1405
- mod.callbacks.forEach((cb) => cb(newMod));
1406
- } else {
1407
- // \u6CA1\u6709\u6CE8\u518C hot \u56DE\u8C03\uFF0C\u5C1D\u8BD5\u91CD\u65B0 import
1408
- await import(update.path + '?t=' + update.timestamp);
1604
+ // \u590D\u5236\u56DE\u8C03\u6570\u7EC4\u907F\u514D\u56DE\u8C03\u5185\u90E8\u53C8\u4FEE\u6539 hotModulesMap \u9020\u6210\u8FED\u4EE3\u5F02\u5E38
1605
+ [...mod.callbacks].forEach((cb) => cb(newMod));
1409
1606
  }
1410
1607
  }
1411
1608
 
@@ -1418,7 +1615,13 @@ function updateCss(path) {
1418
1615
  }
1419
1616
  }
1420
1617
 
1618
+ function clearErrorOverlay() {
1619
+ const el = document.getElementById('nasti-error-overlay');
1620
+ if (el) el.remove();
1621
+ }
1622
+
1421
1623
  function showErrorOverlay(err) {
1624
+ clearErrorOverlay();
1422
1625
  const overlay = document.createElement('div');
1423
1626
  overlay.id = 'nasti-error-overlay';
1424
1627
  overlay.style.cssText = 'position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,0.85);color:#fff;font-family:monospace;padding:2rem;overflow:auto;';
@@ -1437,61 +1640,60 @@ function showErrorOverlay(err) {
1437
1640
  document.body.appendChild(overlay);
1438
1641
  }
1439
1642
 
1440
- // import.meta.hot API
1441
- const createHotContext = (ownerPath) => ({
1442
- accept(deps, callback) {
1443
- if (typeof deps === 'function' || !deps) {
1444
- // self-accepting
1445
- const callbacks = hotModulesMap.get(ownerPath)?.callbacks || [];
1446
- callbacks.push(deps || (() => {}));
1447
- hotModulesMap.set(ownerPath, { callbacks });
1448
- }
1449
- },
1450
- prune(callback) {
1451
- // \u6A21\u5757\u88AB\u79FB\u9664\u65F6\u6267\u884C
1452
- },
1453
- dispose(callback) {
1454
- // \u6A21\u5757\u66F4\u65B0\u524D\u6267\u884C\u6E05\u7406
1455
- },
1456
- invalidate() {
1457
- location.reload();
1458
- },
1459
- data: {},
1460
- });
1461
-
1462
- // \u66B4\u9732\u7ED9\u6A21\u5757\u4F7F\u7528
1463
- if (!window.__nasti_hot_map) window.__nasti_hot_map = new Map();
1464
- window.__NASTI_HMR__ = { createHotContext };
1643
+ /**
1644
+ * \u751F\u6210 import.meta.hot \u7684 hot context\u3002
1645
+ * \u5173\u952E\u7EA6\u675F\uFF1A\u540C\u4E00 ownerPath \u7684 accept \u56DE\u8C03\u5FC5\u987B\u66FF\u6362\uFF08\u4E0D\u662F append\uFF09\u3002
1646
+ * \u6BCF\u6B21\u6A21\u5757\u91CD\u65B0 import \u90FD\u4F1A\u8C03\u7528 createHotContext\uFF0C\u65E7\u56DE\u8C03\u4F1A\u88AB fetchUpdate \u8C03\u7528\u540E\u7ACB\u5373\u88AB\u65B0 import
1647
+ * \u91CC\u7684 accept \u66FF\u6362\u3002\u4E0D\u66FF\u6362\u7684\u8BDD\u6BCF\u7F16\u8F91\u4E00\u6B21\u5C31\u591A\u4E00\u4E2A\u56DE\u8C03\uFF0C\u8D8A\u8DD1\u8D8A\u6162\u3002
1648
+ */
1649
+ export function createHotContext(ownerPath) {
1650
+ return {
1651
+ accept(deps, callback) {
1652
+ // \u81EA\u63A5\u53D7: hot.accept() \u6216 hot.accept(callback)
1653
+ if (typeof deps === 'function' || deps === undefined) {
1654
+ hotModulesMap.set(ownerPath, { callbacks: [deps || (() => {})] });
1655
+ return;
1656
+ }
1657
+ // \u4F9D\u8D56\u63A5\u53D7: hot.accept(deps, callback)\uFF0C\u591A\u6B21\u8C03\u7528\u8FFD\u52A0
1658
+ const existing = hotModulesMap.get(ownerPath)?.callbacks ?? [];
1659
+ hotModulesMap.set(ownerPath, { callbacks: [...existing, callback] });
1660
+ },
1661
+ prune(callback) {
1662
+ pruneMap.set(ownerPath, callback);
1663
+ },
1664
+ dispose(callback) {
1665
+ disposeMap.set(ownerPath, callback);
1666
+ },
1667
+ invalidate() {
1668
+ location.reload();
1669
+ },
1670
+ data: {},
1671
+ };
1672
+ }
1465
1673
  `;
1466
1674
  }
1467
- var import_node_path9, import_node_fs8, REACT_REFRESH_RUNTIME, REACT_REFRESH_PREAMBLE, REACT_REFRESH_FOOTER, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
1675
+ var import_node_path9, import_node_fs8, import_node_module3, import_node_url2, import_meta, __dirname_esm, __require, __refreshRuntimeCache, REACT_REFRESH_GLOBAL_PREAMBLE, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
1468
1676
  var init_middleware = __esm({
1469
1677
  "src/server/middleware.ts"() {
1470
1678
  "use strict";
1471
1679
  import_node_path9 = __toESM(require("path"), 1);
1472
1680
  import_node_fs8 = __toESM(require("fs"), 1);
1681
+ import_node_module3 = require("module");
1682
+ import_node_url2 = require("url");
1473
1683
  init_transformer();
1474
1684
  init_html();
1475
1685
  init_env();
1476
- REACT_REFRESH_RUNTIME = `
1477
- export function createSignatureFunctionForTransform() {
1478
- return function(type, key, forceReset, getCustomHooks) { return type; };
1479
- }
1480
- export function register(type, id) {}
1481
- export default { createSignatureFunctionForTransform, register };
1482
- `;
1483
- REACT_REFRESH_PREAMBLE = `
1484
- import RefreshRuntime from '/@react-refresh';
1485
- if (!window.$RefreshReg$) {
1486
- window.$RefreshReg$ = (type, id) => RefreshRuntime.register(type, import.meta.url + ' ' + id);
1487
- window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
1488
- }
1489
- `;
1490
- REACT_REFRESH_FOOTER = `
1491
- if (import.meta.hot) {
1492
- import.meta.hot.accept();
1493
- }
1494
- `;
1686
+ import_meta = {};
1687
+ __dirname_esm = import_node_path9.default.dirname((0, import_node_url2.fileURLToPath)(import_meta.url));
1688
+ __require = (0, import_node_module3.createRequire)(import_meta.url);
1689
+ __refreshRuntimeCache = null;
1690
+ REACT_REFRESH_GLOBAL_PREAMBLE = `
1691
+ import RefreshRuntime from "/@react-refresh";
1692
+ RefreshRuntime.injectIntoGlobalHook(window);
1693
+ window.$RefreshReg$ = () => {};
1694
+ window.$RefreshSig$ = () => (type) => type;
1695
+ window.__vite_plugin_react_preamble_installed__ = true;
1696
+ `.trim();
1495
1697
  esmBundleCache = /* @__PURE__ */ new Map();
1496
1698
  VALID_IDENT = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
1497
1699
  RESOLVE_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".json", ".vue"];
@@ -1617,7 +1819,7 @@ async function createServer(inlineConfig = {}) {
1617
1819
  const localUrl = `http://localhost:${actualPort}`;
1618
1820
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
1619
1821
  console.log();
1620
- console.log(import_picocolors3.default.cyan(" nasti dev server") + import_picocolors3.default.dim(` v${"1.5.0"}`));
1822
+ console.log(import_picocolors3.default.cyan(" nasti dev server") + import_picocolors3.default.dim(` v${"1.5.2"}`));
1621
1823
  console.log();
1622
1824
  console.log(` ${import_picocolors3.default.green(">")} Local: ${import_picocolors3.default.cyan(localUrl)}`);
1623
1825
  if (networkUrl) {
@@ -1761,7 +1963,7 @@ async function buildElectron(inlineConfig = {}) {
1761
1963
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
1762
1964
  const startTime = performance.now();
1763
1965
  assertElectronVersion(config);
1764
- console.log(import_picocolors2.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors2.default.dim(` v${"1.5.0"}`));
1966
+ console.log(import_picocolors2.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors2.default.dim(` v${"1.5.2"}`));
1765
1967
  console.log(import_picocolors2.default.dim(` root: ${config.root}`));
1766
1968
  console.log(import_picocolors2.default.dim(` mode: ${config.mode}`));
1767
1969
  console.log(import_picocolors2.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -1895,7 +2097,7 @@ init_server();
1895
2097
  // src/server/electron-dev.ts
1896
2098
  var import_node_path12 = __toESM(require("path"), 1);
1897
2099
  var import_node_fs10 = __toESM(require("fs"), 1);
1898
- var import_node_module3 = require("module");
2100
+ var import_node_module4 = require("module");
1899
2101
  var import_node_child_process = require("child_process");
1900
2102
  var import_chokidar2 = __toESM(require("chokidar"), 1);
1901
2103
  var import_picocolors4 = __toESM(require("picocolors"), 1);
@@ -1908,7 +2110,7 @@ async function startElectronDev(inlineConfig = {}) {
1908
2110
  const { noSpawn, ...rest } = inlineConfig;
1909
2111
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
1910
2112
  warnElectronVersion(config);
1911
- console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.5.0"}`));
2113
+ console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.5.2"}`));
1912
2114
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
1913
2115
  const server = await createServer2({ ...rest, target: "electron" });
1914
2116
  await server.listen();
@@ -1972,11 +2174,16 @@ async function startElectronDev(inlineConfig = {}) {
1972
2174
  const watchTargets = [mainEntry, ...preloadEntries].filter(import_node_fs10.default.existsSync);
1973
2175
  const watcher = import_chokidar2.default.watch(watchTargets, { ignoreInitial: true });
1974
2176
  let restarting = null;
1975
- watcher.on("all", async () => {
1976
- if (restarting) return;
2177
+ let pending = false;
2178
+ const restart = async () => {
2179
+ if (restarting) {
2180
+ pending = true;
2181
+ return;
2182
+ }
1977
2183
  restarting = (async () => {
1978
- console.log(import_picocolors4.default.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1979
- try {
2184
+ do {
2185
+ pending = false;
2186
+ console.log(import_picocolors4.default.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1980
2187
  if (child && !child.killed) {
1981
2188
  ;
1982
2189
  child.__nastiKilled = true;
@@ -1990,12 +2197,24 @@ async function startElectronDev(inlineConfig = {}) {
1990
2197
  dying.kill();
1991
2198
  });
1992
2199
  }
1993
- await compileAll();
1994
- spawnElectron();
1995
- } finally {
1996
- restarting = null;
1997
- }
2200
+ try {
2201
+ await compileAll();
2202
+ spawnElectron();
2203
+ } catch (e) {
2204
+ console.warn(import_picocolors4.default.yellow(` \u26A0 \u91CD\u542F\u7F16\u8BD1\u5931\u8D25\uFF0C\u4FDD\u7559\u4E0A\u4E00\u6B21\u8FDB\u7A0B: ${e.message}`));
2205
+ }
2206
+ } while (pending);
2207
+ restarting = null;
1998
2208
  })();
2209
+ return restarting;
2210
+ };
2211
+ let debounceTimer = null;
2212
+ watcher.on("all", () => {
2213
+ if (debounceTimer) clearTimeout(debounceTimer);
2214
+ debounceTimer = setTimeout(() => {
2215
+ debounceTimer = null;
2216
+ void restart();
2217
+ }, 80);
1999
2218
  });
2000
2219
  }
2001
2220
  }
@@ -2043,7 +2262,7 @@ function resolveElectronBinary(config) {
2043
2262
  return config.electron.electronPath;
2044
2263
  }
2045
2264
  try {
2046
- const require2 = (0, import_node_module3.createRequire)(import_node_path12.default.resolve(config.root, "package.json"));
2265
+ const require2 = (0, import_node_module4.createRequire)(import_node_path12.default.resolve(config.root, "package.json"));
2047
2266
  const pathFile = require2.resolve("electron");
2048
2267
  const electronModule = require2(pathFile);
2049
2268
  if (typeof electronModule === "string" && import_node_fs10.default.existsSync(electronModule)) {
@@ -2076,7 +2295,7 @@ function warnElectronVersion(config) {
2076
2295
  var import_node_path13 = __toESM(require("path"), 1);
2077
2296
  var import_node_fs11 = __toESM(require("fs"), 1);
2078
2297
  var import_node_crypto2 = __toESM(require("crypto"), 1);
2079
- var import_node_module4 = require("module");
2298
+ var import_node_module5 = require("module");
2080
2299
  var DEFAULT_WORKERS = {
2081
2300
  editorWorkerService: "monaco-editor/esm/vs/editor/editor.worker",
2082
2301
  css: "monaco-editor/esm/vs/language/css/css.worker",
@@ -2095,7 +2314,7 @@ function normalizePublicPath(p) {
2095
2314
  }
2096
2315
  function readMonacoVersion(root) {
2097
2316
  try {
2098
- const require2 = (0, import_node_module4.createRequire)(import_node_path13.default.resolve(root, "package.json"));
2317
+ const require2 = (0, import_node_module5.createRequire)(import_node_path13.default.resolve(root, "package.json"));
2099
2318
  const pkgJsonPath = require2.resolve("monaco-editor/package.json", { paths: [root] });
2100
2319
  const pkg = JSON.parse(import_node_fs11.default.readFileSync(pkgJsonPath, "utf-8"));
2101
2320
  return typeof pkg.version === "string" ? pkg.version : "unknown";
@@ -2123,7 +2342,7 @@ function monacoEditorPlugin(options = {}) {
2123
2342
  if (existing) return existing;
2124
2343
  const task = (async () => {
2125
2344
  const { rolldown: rolldown4 } = await import("rolldown");
2126
- const require2 = (0, import_node_module4.createRequire)(import_node_path13.default.resolve(resolvedConfig.root, "package.json"));
2345
+ const require2 = (0, import_node_module5.createRequire)(import_node_path13.default.resolve(resolvedConfig.root, "package.json"));
2127
2346
  let entry;
2128
2347
  try {
2129
2348
  entry = require2.resolve(worker.entry, { paths: [resolvedConfig.root] });