@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.js CHANGED
@@ -164,6 +164,14 @@ async function resolveConfig(inlineConfig = {}, command) {
164
164
  return p.apply === command;
165
165
  });
166
166
  resolved.plugins = filteredPlugins;
167
+ if (resolved.target === "electron") {
168
+ const autoExternal = detectNativeDeps(root);
169
+ if (autoExternal.length > 0) {
170
+ const current = new Set(resolved.electron.external ?? []);
171
+ for (const dep of autoExternal) current.add(dep);
172
+ resolved.electron.external = [...current];
173
+ }
174
+ }
167
175
  for (const plugin of resolved.plugins) {
168
176
  if (plugin.configResolved) {
169
177
  await plugin.configResolved(resolved);
@@ -171,6 +179,73 @@ async function resolveConfig(inlineConfig = {}, command) {
171
179
  }
172
180
  return resolved;
173
181
  }
182
+ function detectNativeDeps(root) {
183
+ const result = /* @__PURE__ */ new Set();
184
+ const pkgJsonPath = path.resolve(root, "package.json");
185
+ if (!fs.existsSync(pkgJsonPath)) return [];
186
+ let pkg;
187
+ try {
188
+ pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
189
+ } catch {
190
+ return [];
191
+ }
192
+ const deps = {
193
+ ...pkg.dependencies ?? {},
194
+ ...pkg.optionalDependencies ?? {}
195
+ };
196
+ const KNOWN_NATIVE = /* @__PURE__ */ new Set([
197
+ "node-pty",
198
+ "better-sqlite3",
199
+ "sharp",
200
+ "serialport",
201
+ "@vscode/tree-sitter-wasm",
202
+ "keytar",
203
+ "nodegit",
204
+ "sqlite3",
205
+ "fsevents"
206
+ ]);
207
+ for (const dep of Object.keys(deps)) {
208
+ if (KNOWN_NATIVE.has(dep)) {
209
+ result.add(dep);
210
+ continue;
211
+ }
212
+ const depDir = path.resolve(root, "node_modules", dep);
213
+ if (!fs.existsSync(depDir)) continue;
214
+ if (fs.existsSync(path.join(depDir, "binding.gyp"))) {
215
+ result.add(dep);
216
+ continue;
217
+ }
218
+ const subPkg = path.join(depDir, "package.json");
219
+ if (fs.existsSync(subPkg)) {
220
+ try {
221
+ const sub = JSON.parse(fs.readFileSync(subPkg, "utf-8"));
222
+ if (sub.gypfile === true || sub.binary?.module_name) {
223
+ result.add(dep);
224
+ continue;
225
+ }
226
+ } catch {
227
+ }
228
+ }
229
+ if (hasDotNodeFile(depDir)) {
230
+ result.add(dep);
231
+ }
232
+ }
233
+ return [...result];
234
+ }
235
+ function hasDotNodeFile(dir, depth = 0) {
236
+ if (depth > 3) return false;
237
+ try {
238
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
239
+ for (const e of entries) {
240
+ if (e.isFile() && e.name.endsWith(".node")) return true;
241
+ if (e.isDirectory() && (e.name === "build" || e.name === "prebuilds" || e.name === "Release")) {
242
+ if (hasDotNodeFile(path.join(dir, e.name), depth + 1)) return true;
243
+ }
244
+ }
245
+ } catch {
246
+ }
247
+ return false;
248
+ }
174
249
  function deepMerge(target, source) {
175
250
  const result = { ...target };
176
251
  for (const key of Object.keys(source)) {
@@ -415,6 +490,15 @@ function htmlPlugin(config) {
415
490
  transformIndexHtml(html) {
416
491
  const tags = [];
417
492
  if (config.command === "serve") {
493
+ const isReactLike = config.framework === "react" || config.framework === "auto";
494
+ if (isReactLike) {
495
+ tags.push({
496
+ tag: "script",
497
+ attrs: { type: "module" },
498
+ children: REACT_REFRESH_HTML_PREAMBLE,
499
+ injectTo: "head-prepend"
500
+ });
501
+ }
418
502
  tags.push({
419
503
  tag: "script",
420
504
  attrs: { type: "module", src: "/@nasti/client" },
@@ -465,9 +549,17 @@ async function readHtmlFile(root) {
465
549
  if (!fs4.existsSync(htmlPath)) return null;
466
550
  return fs4.readFileSync(htmlPath, "utf-8");
467
551
  }
552
+ var REACT_REFRESH_HTML_PREAMBLE;
468
553
  var init_html = __esm({
469
554
  "src/plugins/html.ts"() {
470
555
  "use strict";
556
+ REACT_REFRESH_HTML_PREAMBLE = `
557
+ import RefreshRuntime from "/@react-refresh";
558
+ RefreshRuntime.injectIntoGlobalHook(window);
559
+ window.$RefreshReg$ = () => {};
560
+ window.$RefreshSig$ = () => (type) => type;
561
+ window.__vite_plugin_react_preamble_installed__ = true;
562
+ `.trim();
471
563
  }
472
564
  });
473
565
 
@@ -701,7 +793,7 @@ import pc from "picocolors";
701
793
  async function build(inlineConfig = {}) {
702
794
  const config = await resolveConfig(inlineConfig, "build");
703
795
  const startTime = performance.now();
704
- console.log(pc.cyan("\n\u{1F528} nasti build") + pc.dim(` v${"1.5.0"}`));
796
+ console.log(pc.cyan("\n\u{1F528} nasti build") + pc.dim(` v${"1.5.2"}`));
705
797
  console.log(pc.dim(` root: ${config.root}`));
706
798
  console.log(pc.dim(` mode: ${config.mode}`));
707
799
  const outDir = path7.resolve(config.root, config.build.outDir);
@@ -1005,11 +1097,93 @@ var init_ws = __esm({
1005
1097
  // src/server/middleware.ts
1006
1098
  var middleware_exports = {};
1007
1099
  __export(middleware_exports, {
1100
+ REACT_REFRESH_GLOBAL_PREAMBLE: () => REACT_REFRESH_GLOBAL_PREAMBLE,
1008
1101
  transformMiddleware: () => transformMiddleware,
1009
1102
  transformRequest: () => transformRequest
1010
1103
  });
1011
1104
  import path9 from "path";
1012
1105
  import fs8 from "fs";
1106
+ import { createRequire as createRequire2 } from "module";
1107
+ import { fileURLToPath } from "url";
1108
+ function getReactRefreshRuntimeEsm() {
1109
+ if (__refreshRuntimeCache) return __refreshRuntimeCache;
1110
+ let cjsPath;
1111
+ try {
1112
+ const pkgPath = __require.resolve("react-refresh/package.json");
1113
+ cjsPath = path9.join(path9.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
1114
+ } catch (err) {
1115
+ cjsPath = path9.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
1116
+ if (!fs8.existsSync(cjsPath)) {
1117
+ const origMsg = err instanceof Error ? err.message : String(err);
1118
+ throw new Error(
1119
+ `[nasti] Missing dependency "react-refresh". Install it with: npm install react-refresh
1120
+ Original resolve error: ${origMsg}`
1121
+ );
1122
+ }
1123
+ }
1124
+ const cjsSource = fs8.readFileSync(cjsPath, "utf-8");
1125
+ __refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM
1126
+ const exports = {};
1127
+ const module = { exports };
1128
+ const process = { env: { NODE_ENV: 'development' } };
1129
+ ${cjsSource}
1130
+ const __rt = module.exports;
1131
+ export const injectIntoGlobalHook = __rt.injectIntoGlobalHook;
1132
+ export const register = __rt.register;
1133
+ export const createSignatureFunctionForTransform = __rt.createSignatureFunctionForTransform;
1134
+ export const performReactRefresh = __rt.performReactRefresh;
1135
+ export const isLikelyComponentType = __rt.isLikelyComponentType;
1136
+ export const hasUnrecoverableErrors = __rt.hasUnrecoverableErrors;
1137
+ export const setSignature = __rt.setSignature;
1138
+ export const getFamilyByID = __rt.getFamilyByID;
1139
+ export const getFamilyByType = __rt.getFamilyByType;
1140
+ export const findAffectedHostInstances = __rt.findAffectedHostInstances;
1141
+ export const collectCustomHooksForSignature = __rt.collectCustomHooksForSignature;
1142
+ export default __rt;
1143
+ `;
1144
+ return __refreshRuntimeCache;
1145
+ }
1146
+ function buildReactRefreshWrapper(moduleUrl, transformedCode) {
1147
+ const urlLit = JSON.stringify(moduleUrl);
1148
+ const userCode = transformedCode.replace(/\bimport\.meta\.hot\b/g, "__nasti_hot__");
1149
+ return `import * as RefreshRuntime from "/@react-refresh";
1150
+ import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
1151
+ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
1152
+
1153
+ if (!window.__vite_plugin_react_preamble_installed__) {
1154
+ throw new Error("[nasti] React Fast Refresh preamble missing. Make sure nasti:html is wired with framework: 'react'.");
1155
+ }
1156
+
1157
+ const prevRefreshReg = window.$RefreshReg$;
1158
+ const prevRefreshSig = window.$RefreshSig$;
1159
+ window.$RefreshReg$ = (type, id) => {
1160
+ RefreshRuntime.register(type, ${urlLit} + " " + id);
1161
+ };
1162
+ window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
1163
+
1164
+ ${userCode}
1165
+
1166
+ window.$RefreshReg$ = prevRefreshReg;
1167
+ window.$RefreshSig$ = prevRefreshSig;
1168
+
1169
+ if (__nasti_hot__) {
1170
+ __nasti_hot__.accept(() => {
1171
+ clearTimeout(window.__nasti_refresh_timer__);
1172
+ window.__nasti_refresh_timer__ = setTimeout(() => {
1173
+ RefreshRuntime.performReactRefresh();
1174
+ }, 30);
1175
+ });
1176
+ }
1177
+ `;
1178
+ }
1179
+ function injectImportMetaHot(code, moduleUrl) {
1180
+ if (!/\bimport\.meta\.hot\b/.test(code)) return code;
1181
+ const urlLit = JSON.stringify(moduleUrl);
1182
+ const header = `import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
1183
+ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
1184
+ `;
1185
+ return header + code.replace(/\bimport\.meta\.hot\b/g, "__nasti_hot__");
1186
+ }
1013
1187
  function transformMiddleware(ctx) {
1014
1188
  ctx.envDefine = buildEnvDefine(
1015
1189
  loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
@@ -1083,7 +1257,7 @@ async function transformRequest(url, ctx) {
1083
1257
  return cached.transformResult;
1084
1258
  }
1085
1259
  if (cleanReqUrl === "/@react-refresh") {
1086
- return { code: REACT_REFRESH_RUNTIME };
1260
+ return { code: getReactRefreshRuntimeEsm() };
1087
1261
  }
1088
1262
  const filePath = resolveUrlToFile(url, config.root);
1089
1263
  if (!filePath || !fs8.existsSync(filePath)) return null;
@@ -1100,6 +1274,8 @@ async function transformRequest(url, ctx) {
1100
1274
  if (pluginResult) {
1101
1275
  code = typeof pluginResult === "string" ? pluginResult : pluginResult.code;
1102
1276
  }
1277
+ const stableUrl = cleanReqUrl;
1278
+ let wrappedWithRefresh = false;
1103
1279
  if (shouldTransform(filePath)) {
1104
1280
  const isJsx = /\.[jt]sx$/.test(filePath);
1105
1281
  const useRefresh = isJsx && config.framework !== "vue";
@@ -1111,9 +1287,14 @@ async function transformRequest(url, ctx) {
1111
1287
  });
1112
1288
  code = result.code;
1113
1289
  if (useRefresh) {
1114
- code = REACT_REFRESH_PREAMBLE + code + REACT_REFRESH_FOOTER;
1290
+ code = buildReactRefreshWrapper(stableUrl, code);
1291
+ wrappedWithRefresh = true;
1292
+ mod.isSelfAccepting = true;
1115
1293
  }
1116
1294
  }
1295
+ if (!wrappedWithRefresh) {
1296
+ code = injectImportMetaHot(code, stableUrl);
1297
+ }
1117
1298
  const envDefine = ctx.envDefine ?? buildEnvDefine(
1118
1299
  loadEnv(config.mode, config.root, config.envPrefix),
1119
1300
  config.mode
@@ -1181,8 +1362,8 @@ function rewriteExternalRequires(code) {
1181
1362
  }
1182
1363
  async function injectCjsNamedExports(code, entryFile) {
1183
1364
  try {
1184
- const { createRequire: createRequire4 } = await import("module");
1185
- const req = createRequire4(entryFile);
1365
+ const { createRequire: createRequire5 } = await import("module");
1366
+ const req = createRequire5(entryFile);
1186
1367
  const cjsExports = req(entryFile);
1187
1368
  if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
1188
1369
  const namedKeys = Object.keys(cjsExports).filter(
@@ -1345,12 +1526,15 @@ function getHmrClientCode() {
1345
1526
  // Nasti HMR Client
1346
1527
  const socket = new WebSocket(\`ws://\${location.host}\`, 'nasti-hmr');
1347
1528
  const hotModulesMap = new Map();
1529
+ const disposeMap = new Map();
1530
+ const pruneMap = new Map();
1348
1531
 
1349
1532
  socket.addEventListener('message', ({ data }) => {
1350
1533
  const payload = JSON.parse(data);
1351
1534
  switch (payload.type) {
1352
1535
  case 'connected':
1353
1536
  console.log('[nasti] connected.');
1537
+ clearErrorOverlay();
1354
1538
  break;
1355
1539
  case 'update':
1356
1540
  payload.updates.forEach((update) => {
@@ -1360,11 +1544,18 @@ socket.addEventListener('message', ({ data }) => {
1360
1544
  updateCss(update.path);
1361
1545
  }
1362
1546
  });
1547
+ clearErrorOverlay();
1363
1548
  break;
1364
1549
  case 'full-reload':
1365
1550
  console.log('[nasti] full reload');
1366
1551
  location.reload();
1367
1552
  break;
1553
+ case 'prune':
1554
+ payload.paths.forEach((p) => {
1555
+ const cb = pruneMap.get(p);
1556
+ if (cb) cb();
1557
+ });
1558
+ break;
1368
1559
  case 'error':
1369
1560
  console.error('[nasti] error:', payload.err.message);
1370
1561
  showErrorOverlay(payload.err);
@@ -1372,14 +1563,23 @@ socket.addEventListener('message', ({ data }) => {
1372
1563
  }
1373
1564
  });
1374
1565
 
1566
+ // \u81EA\u52A8\u91CD\u8FDE\uFF08\u65AD\u7EBF\u65F6\u6307\u6570\u9000\u907F\uFF09
1567
+ let reconnectTimer = 0;
1568
+ socket.addEventListener('close', () => {
1569
+ clearTimeout(reconnectTimer);
1570
+ reconnectTimer = setTimeout(() => location.reload(), 1000);
1571
+ });
1572
+
1375
1573
  async function fetchUpdate(update) {
1376
1574
  const mod = hotModulesMap.get(update.path);
1575
+ // \u5148\u8DD1 dispose\uFF08\u7ED9\u6A21\u5757\u673A\u4F1A\u6E05\u7406\u526F\u4F5C\u7528\uFF09
1576
+ const dispose = disposeMap.get(update.path);
1577
+ if (dispose) dispose();
1578
+
1579
+ const newMod = await import(update.acceptedPath + '?t=' + update.timestamp);
1377
1580
  if (mod) {
1378
- const newMod = await import(update.acceptedPath + '?t=' + update.timestamp);
1379
- mod.callbacks.forEach((cb) => cb(newMod));
1380
- } else {
1381
- // \u6CA1\u6709\u6CE8\u518C hot \u56DE\u8C03\uFF0C\u5C1D\u8BD5\u91CD\u65B0 import
1382
- await import(update.path + '?t=' + update.timestamp);
1581
+ // \u590D\u5236\u56DE\u8C03\u6570\u7EC4\u907F\u514D\u56DE\u8C03\u5185\u90E8\u53C8\u4FEE\u6539 hotModulesMap \u9020\u6210\u8FED\u4EE3\u5F02\u5E38
1582
+ [...mod.callbacks].forEach((cb) => cb(newMod));
1383
1583
  }
1384
1584
  }
1385
1585
 
@@ -1392,7 +1592,13 @@ function updateCss(path) {
1392
1592
  }
1393
1593
  }
1394
1594
 
1595
+ function clearErrorOverlay() {
1596
+ const el = document.getElementById('nasti-error-overlay');
1597
+ if (el) el.remove();
1598
+ }
1599
+
1395
1600
  function showErrorOverlay(err) {
1601
+ clearErrorOverlay();
1396
1602
  const overlay = document.createElement('div');
1397
1603
  overlay.id = 'nasti-error-overlay';
1398
1604
  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;';
@@ -1411,59 +1617,55 @@ function showErrorOverlay(err) {
1411
1617
  document.body.appendChild(overlay);
1412
1618
  }
1413
1619
 
1414
- // import.meta.hot API
1415
- const createHotContext = (ownerPath) => ({
1416
- accept(deps, callback) {
1417
- if (typeof deps === 'function' || !deps) {
1418
- // self-accepting
1419
- const callbacks = hotModulesMap.get(ownerPath)?.callbacks || [];
1420
- callbacks.push(deps || (() => {}));
1421
- hotModulesMap.set(ownerPath, { callbacks });
1422
- }
1423
- },
1424
- prune(callback) {
1425
- // \u6A21\u5757\u88AB\u79FB\u9664\u65F6\u6267\u884C
1426
- },
1427
- dispose(callback) {
1428
- // \u6A21\u5757\u66F4\u65B0\u524D\u6267\u884C\u6E05\u7406
1429
- },
1430
- invalidate() {
1431
- location.reload();
1432
- },
1433
- data: {},
1434
- });
1435
-
1436
- // \u66B4\u9732\u7ED9\u6A21\u5757\u4F7F\u7528
1437
- if (!window.__nasti_hot_map) window.__nasti_hot_map = new Map();
1438
- window.__NASTI_HMR__ = { createHotContext };
1620
+ /**
1621
+ * \u751F\u6210 import.meta.hot \u7684 hot context\u3002
1622
+ * \u5173\u952E\u7EA6\u675F\uFF1A\u540C\u4E00 ownerPath \u7684 accept \u56DE\u8C03\u5FC5\u987B\u66FF\u6362\uFF08\u4E0D\u662F append\uFF09\u3002
1623
+ * \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
1624
+ * \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
1625
+ */
1626
+ export function createHotContext(ownerPath) {
1627
+ return {
1628
+ accept(deps, callback) {
1629
+ // \u81EA\u63A5\u53D7: hot.accept() \u6216 hot.accept(callback)
1630
+ if (typeof deps === 'function' || deps === undefined) {
1631
+ hotModulesMap.set(ownerPath, { callbacks: [deps || (() => {})] });
1632
+ return;
1633
+ }
1634
+ // \u4F9D\u8D56\u63A5\u53D7: hot.accept(deps, callback)\uFF0C\u591A\u6B21\u8C03\u7528\u8FFD\u52A0
1635
+ const existing = hotModulesMap.get(ownerPath)?.callbacks ?? [];
1636
+ hotModulesMap.set(ownerPath, { callbacks: [...existing, callback] });
1637
+ },
1638
+ prune(callback) {
1639
+ pruneMap.set(ownerPath, callback);
1640
+ },
1641
+ dispose(callback) {
1642
+ disposeMap.set(ownerPath, callback);
1643
+ },
1644
+ invalidate() {
1645
+ location.reload();
1646
+ },
1647
+ data: {},
1648
+ };
1649
+ }
1439
1650
  `;
1440
1651
  }
1441
- var REACT_REFRESH_RUNTIME, REACT_REFRESH_PREAMBLE, REACT_REFRESH_FOOTER, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
1652
+ var __dirname_esm, __require, __refreshRuntimeCache, REACT_REFRESH_GLOBAL_PREAMBLE, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
1442
1653
  var init_middleware = __esm({
1443
1654
  "src/server/middleware.ts"() {
1444
1655
  "use strict";
1445
1656
  init_transformer();
1446
1657
  init_html();
1447
1658
  init_env();
1448
- REACT_REFRESH_RUNTIME = `
1449
- export function createSignatureFunctionForTransform() {
1450
- return function(type, key, forceReset, getCustomHooks) { return type; };
1451
- }
1452
- export function register(type, id) {}
1453
- export default { createSignatureFunctionForTransform, register };
1454
- `;
1455
- REACT_REFRESH_PREAMBLE = `
1456
- import RefreshRuntime from '/@react-refresh';
1457
- if (!window.$RefreshReg$) {
1458
- window.$RefreshReg$ = (type, id) => RefreshRuntime.register(type, import.meta.url + ' ' + id);
1459
- window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
1460
- }
1461
- `;
1462
- REACT_REFRESH_FOOTER = `
1463
- if (import.meta.hot) {
1464
- import.meta.hot.accept();
1465
- }
1466
- `;
1659
+ __dirname_esm = path9.dirname(fileURLToPath(import.meta.url));
1660
+ __require = createRequire2(import.meta.url);
1661
+ __refreshRuntimeCache = null;
1662
+ REACT_REFRESH_GLOBAL_PREAMBLE = `
1663
+ import RefreshRuntime from "/@react-refresh";
1664
+ RefreshRuntime.injectIntoGlobalHook(window);
1665
+ window.$RefreshReg$ = () => {};
1666
+ window.$RefreshSig$ = () => (type) => type;
1667
+ window.__vite_plugin_react_preamble_installed__ = true;
1668
+ `.trim();
1467
1669
  esmBundleCache = /* @__PURE__ */ new Map();
1468
1670
  VALID_IDENT = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
1469
1671
  RESOLVE_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".json", ".vue"];
@@ -1595,7 +1797,7 @@ async function createServer(inlineConfig = {}) {
1595
1797
  const localUrl = `http://localhost:${actualPort}`;
1596
1798
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
1597
1799
  console.log();
1598
- console.log(pc3.cyan(" nasti dev server") + pc3.dim(` v${"1.5.0"}`));
1800
+ console.log(pc3.cyan(" nasti dev server") + pc3.dim(` v${"1.5.2"}`));
1599
1801
  console.log();
1600
1802
  console.log(` ${pc3.green(">")} Local: ${pc3.cyan(localUrl)}`);
1601
1803
  if (networkUrl) {
@@ -1719,7 +1921,7 @@ async function buildElectron(inlineConfig = {}) {
1719
1921
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
1720
1922
  const startTime = performance.now();
1721
1923
  assertElectronVersion(config);
1722
- console.log(pc2.cyan("\n\u26A1 nasti build (electron)") + pc2.dim(` v${"1.5.0"}`));
1924
+ console.log(pc2.cyan("\n\u26A1 nasti build (electron)") + pc2.dim(` v${"1.5.2"}`));
1723
1925
  console.log(pc2.dim(` root: ${config.root}`));
1724
1926
  console.log(pc2.dim(` mode: ${config.mode}`));
1725
1927
  console.log(pc2.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -1854,7 +2056,7 @@ init_server();
1854
2056
  init_config();
1855
2057
  import path12 from "path";
1856
2058
  import fs10 from "fs";
1857
- import { createRequire as createRequire2 } from "module";
2059
+ import { createRequire as createRequire3 } from "module";
1858
2060
  import { spawn } from "child_process";
1859
2061
  import chokidar from "chokidar";
1860
2062
  import pc4 from "picocolors";
@@ -1866,7 +2068,7 @@ async function startElectronDev(inlineConfig = {}) {
1866
2068
  const { noSpawn, ...rest } = inlineConfig;
1867
2069
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
1868
2070
  warnElectronVersion(config);
1869
- console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.5.0"}`));
2071
+ console.log(pc4.cyan("\n\u26A1 nasti electron dev") + pc4.dim(` v${"1.5.2"}`));
1870
2072
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
1871
2073
  const server = await createServer2({ ...rest, target: "electron" });
1872
2074
  await server.listen();
@@ -1930,11 +2132,16 @@ async function startElectronDev(inlineConfig = {}) {
1930
2132
  const watchTargets = [mainEntry, ...preloadEntries].filter(fs10.existsSync);
1931
2133
  const watcher = chokidar.watch(watchTargets, { ignoreInitial: true });
1932
2134
  let restarting = null;
1933
- watcher.on("all", async () => {
1934
- if (restarting) return;
2135
+ let pending = false;
2136
+ const restart = async () => {
2137
+ if (restarting) {
2138
+ pending = true;
2139
+ return;
2140
+ }
1935
2141
  restarting = (async () => {
1936
- console.log(pc4.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1937
- try {
2142
+ do {
2143
+ pending = false;
2144
+ console.log(pc4.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1938
2145
  if (child && !child.killed) {
1939
2146
  ;
1940
2147
  child.__nastiKilled = true;
@@ -1948,12 +2155,24 @@ async function startElectronDev(inlineConfig = {}) {
1948
2155
  dying.kill();
1949
2156
  });
1950
2157
  }
1951
- await compileAll();
1952
- spawnElectron();
1953
- } finally {
1954
- restarting = null;
1955
- }
2158
+ try {
2159
+ await compileAll();
2160
+ spawnElectron();
2161
+ } catch (e) {
2162
+ console.warn(pc4.yellow(` \u26A0 \u91CD\u542F\u7F16\u8BD1\u5931\u8D25\uFF0C\u4FDD\u7559\u4E0A\u4E00\u6B21\u8FDB\u7A0B: ${e.message}`));
2163
+ }
2164
+ } while (pending);
2165
+ restarting = null;
1956
2166
  })();
2167
+ return restarting;
2168
+ };
2169
+ let debounceTimer = null;
2170
+ watcher.on("all", () => {
2171
+ if (debounceTimer) clearTimeout(debounceTimer);
2172
+ debounceTimer = setTimeout(() => {
2173
+ debounceTimer = null;
2174
+ void restart();
2175
+ }, 80);
1957
2176
  });
1958
2177
  }
1959
2178
  }
@@ -2001,7 +2220,7 @@ function resolveElectronBinary(config) {
2001
2220
  return config.electron.electronPath;
2002
2221
  }
2003
2222
  try {
2004
- const require2 = createRequire2(path12.resolve(config.root, "package.json"));
2223
+ const require2 = createRequire3(path12.resolve(config.root, "package.json"));
2005
2224
  const pathFile = require2.resolve("electron");
2006
2225
  const electronModule = require2(pathFile);
2007
2226
  if (typeof electronModule === "string" && fs10.existsSync(electronModule)) {
@@ -2034,7 +2253,7 @@ function warnElectronVersion(config) {
2034
2253
  import path13 from "path";
2035
2254
  import fs11 from "fs";
2036
2255
  import crypto2 from "crypto";
2037
- import { createRequire as createRequire3 } from "module";
2256
+ import { createRequire as createRequire4 } from "module";
2038
2257
  var DEFAULT_WORKERS = {
2039
2258
  editorWorkerService: "monaco-editor/esm/vs/editor/editor.worker",
2040
2259
  css: "monaco-editor/esm/vs/language/css/css.worker",
@@ -2053,7 +2272,7 @@ function normalizePublicPath(p) {
2053
2272
  }
2054
2273
  function readMonacoVersion(root) {
2055
2274
  try {
2056
- const require2 = createRequire3(path13.resolve(root, "package.json"));
2275
+ const require2 = createRequire4(path13.resolve(root, "package.json"));
2057
2276
  const pkgJsonPath = require2.resolve("monaco-editor/package.json", { paths: [root] });
2058
2277
  const pkg = JSON.parse(fs11.readFileSync(pkgJsonPath, "utf-8"));
2059
2278
  return typeof pkg.version === "string" ? pkg.version : "unknown";
@@ -2081,7 +2300,7 @@ function monacoEditorPlugin(options = {}) {
2081
2300
  if (existing) return existing;
2082
2301
  const task = (async () => {
2083
2302
  const { rolldown: rolldown4 } = await import("rolldown");
2084
- const require2 = createRequire3(path13.resolve(resolvedConfig.root, "package.json"));
2303
+ const require2 = createRequire4(path13.resolve(resolvedConfig.root, "package.json"));
2085
2304
  let entry;
2086
2305
  try {
2087
2306
  entry = require2.resolve(worker.entry, { paths: [resolvedConfig.root] });