@nasti-toolchain/nasti 1.5.0 → 1.5.1

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/cli.cjs CHANGED
@@ -179,6 +179,14 @@ async function resolveConfig(inlineConfig = {}, command) {
179
179
  return p.apply === command;
180
180
  });
181
181
  resolved.plugins = filteredPlugins;
182
+ if (resolved.target === "electron") {
183
+ const autoExternal = detectNativeDeps(root);
184
+ if (autoExternal.length > 0) {
185
+ const current = new Set(resolved.electron.external ?? []);
186
+ for (const dep of autoExternal) current.add(dep);
187
+ resolved.electron.external = [...current];
188
+ }
189
+ }
182
190
  for (const plugin of resolved.plugins) {
183
191
  if (plugin.configResolved) {
184
192
  await plugin.configResolved(resolved);
@@ -186,6 +194,73 @@ async function resolveConfig(inlineConfig = {}, command) {
186
194
  }
187
195
  return resolved;
188
196
  }
197
+ function detectNativeDeps(root) {
198
+ const result = /* @__PURE__ */ new Set();
199
+ const pkgJsonPath = import_node_path.default.resolve(root, "package.json");
200
+ if (!import_node_fs.default.existsSync(pkgJsonPath)) return [];
201
+ let pkg;
202
+ try {
203
+ pkg = JSON.parse(import_node_fs.default.readFileSync(pkgJsonPath, "utf-8"));
204
+ } catch {
205
+ return [];
206
+ }
207
+ const deps = {
208
+ ...pkg.dependencies ?? {},
209
+ ...pkg.optionalDependencies ?? {}
210
+ };
211
+ const KNOWN_NATIVE = /* @__PURE__ */ new Set([
212
+ "node-pty",
213
+ "better-sqlite3",
214
+ "sharp",
215
+ "serialport",
216
+ "@vscode/tree-sitter-wasm",
217
+ "keytar",
218
+ "nodegit",
219
+ "sqlite3",
220
+ "fsevents"
221
+ ]);
222
+ for (const dep of Object.keys(deps)) {
223
+ if (KNOWN_NATIVE.has(dep)) {
224
+ result.add(dep);
225
+ continue;
226
+ }
227
+ const depDir = import_node_path.default.resolve(root, "node_modules", dep);
228
+ if (!import_node_fs.default.existsSync(depDir)) continue;
229
+ if (import_node_fs.default.existsSync(import_node_path.default.join(depDir, "binding.gyp"))) {
230
+ result.add(dep);
231
+ continue;
232
+ }
233
+ const subPkg = import_node_path.default.join(depDir, "package.json");
234
+ if (import_node_fs.default.existsSync(subPkg)) {
235
+ try {
236
+ const sub = JSON.parse(import_node_fs.default.readFileSync(subPkg, "utf-8"));
237
+ if (sub.gypfile === true || sub.binary?.module_name) {
238
+ result.add(dep);
239
+ continue;
240
+ }
241
+ } catch {
242
+ }
243
+ }
244
+ if (hasDotNodeFile(depDir)) {
245
+ result.add(dep);
246
+ }
247
+ }
248
+ return [...result];
249
+ }
250
+ function hasDotNodeFile(dir, depth = 0) {
251
+ if (depth > 3) return false;
252
+ try {
253
+ const entries = import_node_fs.default.readdirSync(dir, { withFileTypes: true });
254
+ for (const e of entries) {
255
+ if (e.isFile() && e.name.endsWith(".node")) return true;
256
+ if (e.isDirectory() && (e.name === "build" || e.name === "prebuilds" || e.name === "Release")) {
257
+ if (hasDotNodeFile(import_node_path.default.join(dir, e.name), depth + 1)) return true;
258
+ }
259
+ }
260
+ } catch {
261
+ }
262
+ return false;
263
+ }
189
264
  function deepMerge(target, source) {
190
265
  const result = { ...target };
191
266
  for (const key of Object.keys(source)) {
@@ -540,6 +615,15 @@ function htmlPlugin(config) {
540
615
  transformIndexHtml(html) {
541
616
  const tags = [];
542
617
  if (config.command === "serve") {
618
+ const isReactLike = config.framework === "react" || config.framework === "auto";
619
+ if (isReactLike) {
620
+ tags.push({
621
+ tag: "script",
622
+ attrs: { type: "module" },
623
+ children: REACT_REFRESH_HTML_PREAMBLE,
624
+ injectTo: "head-prepend"
625
+ });
626
+ }
543
627
  tags.push({
544
628
  tag: "script",
545
629
  attrs: { type: "module", src: "/@nasti/client" },
@@ -590,12 +674,19 @@ async function readHtmlFile(root) {
590
674
  if (!import_node_fs2.default.existsSync(htmlPath)) return null;
591
675
  return import_node_fs2.default.readFileSync(htmlPath, "utf-8");
592
676
  }
593
- var import_node_path2, import_node_fs2;
677
+ var import_node_path2, import_node_fs2, REACT_REFRESH_HTML_PREAMBLE;
594
678
  var init_html = __esm({
595
679
  "src/plugins/html.ts"() {
596
680
  "use strict";
597
681
  import_node_path2 = __toESM(require("path"), 1);
598
682
  import_node_fs2 = __toESM(require("fs"), 1);
683
+ REACT_REFRESH_HTML_PREAMBLE = `
684
+ import RefreshRuntime from "/@react-refresh";
685
+ RefreshRuntime.injectIntoGlobalHook(window);
686
+ window.$RefreshReg$ = () => {};
687
+ window.$RefreshSig$ = () => (type) => type;
688
+ window.__vite_plugin_react_preamble_installed__ = true;
689
+ `.trim();
599
690
  }
600
691
  });
601
692
 
@@ -664,9 +755,81 @@ var init_env = __esm({
664
755
  // src/server/middleware.ts
665
756
  var middleware_exports = {};
666
757
  __export(middleware_exports, {
758
+ REACT_REFRESH_GLOBAL_PREAMBLE: () => REACT_REFRESH_GLOBAL_PREAMBLE,
667
759
  transformMiddleware: () => transformMiddleware,
668
760
  transformRequest: () => transformRequest
669
761
  });
762
+ function getReactRefreshRuntimeEsm() {
763
+ if (__refreshRuntimeCache) return __refreshRuntimeCache;
764
+ let cjsPath;
765
+ try {
766
+ cjsPath = __require.resolve("react-refresh/cjs/react-refresh-runtime.development.js");
767
+ } catch {
768
+ cjsPath = import_node_path4.default.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
769
+ }
770
+ const cjsSource = import_node_fs4.default.readFileSync(cjsPath, "utf-8");
771
+ __refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM
772
+ const exports = {};
773
+ const module = { exports };
774
+ const process = { env: { NODE_ENV: 'development' } };
775
+ ${cjsSource}
776
+ const __rt = module.exports;
777
+ export const injectIntoGlobalHook = __rt.injectIntoGlobalHook;
778
+ export const register = __rt.register;
779
+ export const createSignatureFunctionForTransform = __rt.createSignatureFunctionForTransform;
780
+ export const performReactRefresh = __rt.performReactRefresh;
781
+ export const isLikelyComponentType = __rt.isLikelyComponentType;
782
+ export const hasUnrecoverableErrors = __rt.hasUnrecoverableErrors;
783
+ export const setSignature = __rt.setSignature;
784
+ export const getFamilyByID = __rt.getFamilyByID;
785
+ export const getFamilyByType = __rt.getFamilyByType;
786
+ export const findAffectedHostInstances = __rt.findAffectedHostInstances;
787
+ export const collectCustomHooksForSignature = __rt.collectCustomHooksForSignature;
788
+ export default __rt;
789
+ `;
790
+ return __refreshRuntimeCache;
791
+ }
792
+ function buildReactRefreshWrapper(moduleUrl, transformedCode) {
793
+ const urlLit = JSON.stringify(moduleUrl);
794
+ const userCode = transformedCode.replace(/\bimport\.meta\.hot\b/g, "__nasti_hot__");
795
+ return `import * as RefreshRuntime from "/@react-refresh";
796
+ import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
797
+ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
798
+
799
+ if (!window.__vite_plugin_react_preamble_installed__) {
800
+ throw new Error("[nasti] React Fast Refresh preamble missing. Make sure nasti:html is wired with framework: 'react'.");
801
+ }
802
+
803
+ const prevRefreshReg = window.$RefreshReg$;
804
+ const prevRefreshSig = window.$RefreshSig$;
805
+ window.$RefreshReg$ = (type, id) => {
806
+ RefreshRuntime.register(type, ${urlLit} + " " + id);
807
+ };
808
+ window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
809
+
810
+ ${userCode}
811
+
812
+ window.$RefreshReg$ = prevRefreshReg;
813
+ window.$RefreshSig$ = prevRefreshSig;
814
+
815
+ if (__nasti_hot__) {
816
+ __nasti_hot__.accept(() => {
817
+ clearTimeout(window.__nasti_refresh_timer__);
818
+ window.__nasti_refresh_timer__ = setTimeout(() => {
819
+ RefreshRuntime.performReactRefresh();
820
+ }, 30);
821
+ });
822
+ }
823
+ `;
824
+ }
825
+ function injectImportMetaHot(code, moduleUrl) {
826
+ if (!/\bimport\.meta\.hot\b/.test(code)) return code;
827
+ const urlLit = JSON.stringify(moduleUrl);
828
+ const header = `import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
829
+ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
830
+ `;
831
+ return header + code.replace(/\bimport\.meta\.hot\b/g, "__nasti_hot__");
832
+ }
670
833
  function transformMiddleware(ctx) {
671
834
  ctx.envDefine = buildEnvDefine(
672
835
  loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
@@ -740,7 +903,7 @@ async function transformRequest(url, ctx) {
740
903
  return cached.transformResult;
741
904
  }
742
905
  if (cleanReqUrl === "/@react-refresh") {
743
- return { code: REACT_REFRESH_RUNTIME };
906
+ return { code: getReactRefreshRuntimeEsm() };
744
907
  }
745
908
  const filePath = resolveUrlToFile(url, config.root);
746
909
  if (!filePath || !import_node_fs4.default.existsSync(filePath)) return null;
@@ -757,6 +920,8 @@ async function transformRequest(url, ctx) {
757
920
  if (pluginResult) {
758
921
  code = typeof pluginResult === "string" ? pluginResult : pluginResult.code;
759
922
  }
923
+ const stableUrl = cleanReqUrl;
924
+ let wrappedWithRefresh = false;
760
925
  if (shouldTransform(filePath)) {
761
926
  const isJsx = /\.[jt]sx$/.test(filePath);
762
927
  const useRefresh = isJsx && config.framework !== "vue";
@@ -768,9 +933,14 @@ async function transformRequest(url, ctx) {
768
933
  });
769
934
  code = result.code;
770
935
  if (useRefresh) {
771
- code = REACT_REFRESH_PREAMBLE + code + REACT_REFRESH_FOOTER;
936
+ code = buildReactRefreshWrapper(stableUrl, code);
937
+ wrappedWithRefresh = true;
938
+ mod.isSelfAccepting = true;
772
939
  }
773
940
  }
941
+ if (!wrappedWithRefresh) {
942
+ code = injectImportMetaHot(code, stableUrl);
943
+ }
774
944
  const envDefine = ctx.envDefine ?? buildEnvDefine(
775
945
  loadEnv(config.mode, config.root, config.envPrefix),
776
946
  config.mode
@@ -838,8 +1008,8 @@ function rewriteExternalRequires(code) {
838
1008
  }
839
1009
  async function injectCjsNamedExports(code, entryFile) {
840
1010
  try {
841
- const { createRequire: createRequire3 } = await import("module");
842
- const req = createRequire3(entryFile);
1011
+ const { createRequire: createRequire4 } = await import("module");
1012
+ const req = createRequire4(entryFile);
843
1013
  const cjsExports = req(entryFile);
844
1014
  if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
845
1015
  const namedKeys = Object.keys(cjsExports).filter(
@@ -1002,12 +1172,15 @@ function getHmrClientCode() {
1002
1172
  // Nasti HMR Client
1003
1173
  const socket = new WebSocket(\`ws://\${location.host}\`, 'nasti-hmr');
1004
1174
  const hotModulesMap = new Map();
1175
+ const disposeMap = new Map();
1176
+ const pruneMap = new Map();
1005
1177
 
1006
1178
  socket.addEventListener('message', ({ data }) => {
1007
1179
  const payload = JSON.parse(data);
1008
1180
  switch (payload.type) {
1009
1181
  case 'connected':
1010
1182
  console.log('[nasti] connected.');
1183
+ clearErrorOverlay();
1011
1184
  break;
1012
1185
  case 'update':
1013
1186
  payload.updates.forEach((update) => {
@@ -1017,11 +1190,18 @@ socket.addEventListener('message', ({ data }) => {
1017
1190
  updateCss(update.path);
1018
1191
  }
1019
1192
  });
1193
+ clearErrorOverlay();
1020
1194
  break;
1021
1195
  case 'full-reload':
1022
1196
  console.log('[nasti] full reload');
1023
1197
  location.reload();
1024
1198
  break;
1199
+ case 'prune':
1200
+ payload.paths.forEach((p) => {
1201
+ const cb = pruneMap.get(p);
1202
+ if (cb) cb();
1203
+ });
1204
+ break;
1025
1205
  case 'error':
1026
1206
  console.error('[nasti] error:', payload.err.message);
1027
1207
  showErrorOverlay(payload.err);
@@ -1029,14 +1209,23 @@ socket.addEventListener('message', ({ data }) => {
1029
1209
  }
1030
1210
  });
1031
1211
 
1212
+ // \u81EA\u52A8\u91CD\u8FDE\uFF08\u65AD\u7EBF\u65F6\u6307\u6570\u9000\u907F\uFF09
1213
+ let reconnectTimer = 0;
1214
+ socket.addEventListener('close', () => {
1215
+ clearTimeout(reconnectTimer);
1216
+ reconnectTimer = setTimeout(() => location.reload(), 1000);
1217
+ });
1218
+
1032
1219
  async function fetchUpdate(update) {
1033
1220
  const mod = hotModulesMap.get(update.path);
1221
+ // \u5148\u8DD1 dispose\uFF08\u7ED9\u6A21\u5757\u673A\u4F1A\u6E05\u7406\u526F\u4F5C\u7528\uFF09
1222
+ const dispose = disposeMap.get(update.path);
1223
+ if (dispose) dispose();
1224
+
1225
+ const newMod = await import(update.acceptedPath + '?t=' + update.timestamp);
1034
1226
  if (mod) {
1035
- const newMod = await import(update.acceptedPath + '?t=' + update.timestamp);
1036
- mod.callbacks.forEach((cb) => cb(newMod));
1037
- } else {
1038
- // \u6CA1\u6709\u6CE8\u518C hot \u56DE\u8C03\uFF0C\u5C1D\u8BD5\u91CD\u65B0 import
1039
- await import(update.path + '?t=' + update.timestamp);
1227
+ // \u590D\u5236\u56DE\u8C03\u6570\u7EC4\u907F\u514D\u56DE\u8C03\u5185\u90E8\u53C8\u4FEE\u6539 hotModulesMap \u9020\u6210\u8FED\u4EE3\u5F02\u5E38
1228
+ [...mod.callbacks].forEach((cb) => cb(newMod));
1040
1229
  }
1041
1230
  }
1042
1231
 
@@ -1049,7 +1238,13 @@ function updateCss(path) {
1049
1238
  }
1050
1239
  }
1051
1240
 
1241
+ function clearErrorOverlay() {
1242
+ const el = document.getElementById('nasti-error-overlay');
1243
+ if (el) el.remove();
1244
+ }
1245
+
1052
1246
  function showErrorOverlay(err) {
1247
+ clearErrorOverlay();
1053
1248
  const overlay = document.createElement('div');
1054
1249
  overlay.id = 'nasti-error-overlay';
1055
1250
  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;';
@@ -1068,61 +1263,60 @@ function showErrorOverlay(err) {
1068
1263
  document.body.appendChild(overlay);
1069
1264
  }
1070
1265
 
1071
- // import.meta.hot API
1072
- const createHotContext = (ownerPath) => ({
1073
- accept(deps, callback) {
1074
- if (typeof deps === 'function' || !deps) {
1075
- // self-accepting
1076
- const callbacks = hotModulesMap.get(ownerPath)?.callbacks || [];
1077
- callbacks.push(deps || (() => {}));
1078
- hotModulesMap.set(ownerPath, { callbacks });
1079
- }
1080
- },
1081
- prune(callback) {
1082
- // \u6A21\u5757\u88AB\u79FB\u9664\u65F6\u6267\u884C
1083
- },
1084
- dispose(callback) {
1085
- // \u6A21\u5757\u66F4\u65B0\u524D\u6267\u884C\u6E05\u7406
1086
- },
1087
- invalidate() {
1088
- location.reload();
1089
- },
1090
- data: {},
1091
- });
1092
-
1093
- // \u66B4\u9732\u7ED9\u6A21\u5757\u4F7F\u7528
1094
- if (!window.__nasti_hot_map) window.__nasti_hot_map = new Map();
1095
- window.__NASTI_HMR__ = { createHotContext };
1266
+ /**
1267
+ * \u751F\u6210 import.meta.hot \u7684 hot context\u3002
1268
+ * \u5173\u952E\u7EA6\u675F\uFF1A\u540C\u4E00 ownerPath \u7684 accept \u56DE\u8C03\u5FC5\u987B\u66FF\u6362\uFF08\u4E0D\u662F append\uFF09\u3002
1269
+ * \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
1270
+ * \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
1271
+ */
1272
+ export function createHotContext(ownerPath) {
1273
+ return {
1274
+ accept(deps, callback) {
1275
+ // \u81EA\u63A5\u53D7: hot.accept() \u6216 hot.accept(callback)
1276
+ if (typeof deps === 'function' || deps === undefined) {
1277
+ hotModulesMap.set(ownerPath, { callbacks: [deps || (() => {})] });
1278
+ return;
1279
+ }
1280
+ // \u4F9D\u8D56\u63A5\u53D7: hot.accept(deps, callback)\uFF0C\u591A\u6B21\u8C03\u7528\u8FFD\u52A0
1281
+ const existing = hotModulesMap.get(ownerPath)?.callbacks ?? [];
1282
+ hotModulesMap.set(ownerPath, { callbacks: [...existing, callback] });
1283
+ },
1284
+ prune(callback) {
1285
+ pruneMap.set(ownerPath, callback);
1286
+ },
1287
+ dispose(callback) {
1288
+ disposeMap.set(ownerPath, callback);
1289
+ },
1290
+ invalidate() {
1291
+ location.reload();
1292
+ },
1293
+ data: {},
1294
+ };
1295
+ }
1096
1296
  `;
1097
1297
  }
1098
- var import_node_path4, import_node_fs4, REACT_REFRESH_RUNTIME, REACT_REFRESH_PREAMBLE, REACT_REFRESH_FOOTER, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
1298
+ var import_node_path4, import_node_fs4, import_node_module, import_node_url2, import_meta, __dirname_esm, __require, __refreshRuntimeCache, REACT_REFRESH_GLOBAL_PREAMBLE, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
1099
1299
  var init_middleware = __esm({
1100
1300
  "src/server/middleware.ts"() {
1101
1301
  "use strict";
1102
1302
  import_node_path4 = __toESM(require("path"), 1);
1103
1303
  import_node_fs4 = __toESM(require("fs"), 1);
1304
+ import_node_module = require("module");
1305
+ import_node_url2 = require("url");
1104
1306
  init_transformer();
1105
1307
  init_html();
1106
1308
  init_env();
1107
- REACT_REFRESH_RUNTIME = `
1108
- export function createSignatureFunctionForTransform() {
1109
- return function(type, key, forceReset, getCustomHooks) { return type; };
1110
- }
1111
- export function register(type, id) {}
1112
- export default { createSignatureFunctionForTransform, register };
1113
- `;
1114
- REACT_REFRESH_PREAMBLE = `
1115
- import RefreshRuntime from '/@react-refresh';
1116
- if (!window.$RefreshReg$) {
1117
- window.$RefreshReg$ = (type, id) => RefreshRuntime.register(type, import.meta.url + ' ' + id);
1118
- window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
1119
- }
1120
- `;
1121
- REACT_REFRESH_FOOTER = `
1122
- if (import.meta.hot) {
1123
- import.meta.hot.accept();
1124
- }
1125
- `;
1309
+ import_meta = {};
1310
+ __dirname_esm = import_node_path4.default.dirname((0, import_node_url2.fileURLToPath)(import_meta.url));
1311
+ __require = (0, import_node_module.createRequire)(import_meta.url);
1312
+ __refreshRuntimeCache = null;
1313
+ REACT_REFRESH_GLOBAL_PREAMBLE = `
1314
+ import RefreshRuntime from "/@react-refresh";
1315
+ RefreshRuntime.injectIntoGlobalHook(window);
1316
+ window.$RefreshReg$ = () => {};
1317
+ window.$RefreshSig$ = () => (type) => type;
1318
+ window.__vite_plugin_react_preamble_installed__ = true;
1319
+ `.trim();
1126
1320
  esmBundleCache = /* @__PURE__ */ new Map();
1127
1321
  VALID_IDENT = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
1128
1322
  RESOLVE_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".json", ".vue"];
@@ -1190,7 +1384,7 @@ var init_hmr = __esm({
1190
1384
  // src/plugins/resolve.ts
1191
1385
  function resolvePlugin(config) {
1192
1386
  const { alias, extensions } = config.resolve;
1193
- const require2 = (0, import_node_module.createRequire)(import_node_path6.default.resolve(config.root, "package.json"));
1387
+ const require2 = (0, import_node_module2.createRequire)(import_node_path6.default.resolve(config.root, "package.json"));
1194
1388
  return {
1195
1389
  name: "nasti:resolve",
1196
1390
  enforce: "pre",
@@ -1256,13 +1450,13 @@ function tryResolveFile(file, extensions) {
1256
1450
  }
1257
1451
  return null;
1258
1452
  }
1259
- var import_node_path6, import_node_fs6, import_node_module;
1453
+ var import_node_path6, import_node_fs6, import_node_module2;
1260
1454
  var init_resolve = __esm({
1261
1455
  "src/plugins/resolve.ts"() {
1262
1456
  "use strict";
1263
1457
  import_node_path6 = __toESM(require("path"), 1);
1264
1458
  import_node_fs6 = __toESM(require("fs"), 1);
1265
- import_node_module = require("module");
1459
+ import_node_module2 = require("module");
1266
1460
  }
1267
1461
  });
1268
1462
 
@@ -1455,7 +1649,7 @@ async function createServer(inlineConfig = {}) {
1455
1649
  const localUrl = `http://localhost:${actualPort}`;
1456
1650
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
1457
1651
  console.log();
1458
- console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.5.0"}`));
1652
+ console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.5.1"}`));
1459
1653
  console.log();
1460
1654
  console.log(` ${import_picocolors.default.green(">")} Local: ${import_picocolors.default.cyan(localUrl)}`);
1461
1655
  if (networkUrl) {
@@ -1556,14 +1750,14 @@ function electronPlugin(config) {
1556
1750
  }
1557
1751
  };
1558
1752
  }
1559
- var import_node_module2, NODE_BUILTINS, ELECTRON_MODULES;
1753
+ var import_node_module3, NODE_BUILTINS, ELECTRON_MODULES;
1560
1754
  var init_electron = __esm({
1561
1755
  "src/plugins/electron.ts"() {
1562
1756
  "use strict";
1563
- import_node_module2 = require("module");
1757
+ import_node_module3 = require("module");
1564
1758
  NODE_BUILTINS = /* @__PURE__ */ new Set([
1565
- ...import_node_module2.builtinModules,
1566
- ...import_node_module2.builtinModules.map((m) => `node:${m}`)
1759
+ ...import_node_module3.builtinModules,
1760
+ ...import_node_module3.builtinModules.map((m) => `node:${m}`)
1567
1761
  ]);
1568
1762
  ELECTRON_MODULES = /* @__PURE__ */ new Set([
1569
1763
  "electron",
@@ -1582,7 +1776,7 @@ __export(build_exports, {
1582
1776
  async function build(inlineConfig = {}) {
1583
1777
  const config = await resolveConfig(inlineConfig, "build");
1584
1778
  const startTime = performance.now();
1585
- console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.5.0"}`));
1779
+ console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.5.1"}`));
1586
1780
  console.log(import_picocolors2.default.dim(` root: ${config.root}`));
1587
1781
  console.log(import_picocolors2.default.dim(` mode: ${config.mode}`));
1588
1782
  const outDir = import_node_path10.default.resolve(config.root, config.build.outDir);
@@ -1743,7 +1937,7 @@ async function buildElectron(inlineConfig = {}) {
1743
1937
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
1744
1938
  const startTime = performance.now();
1745
1939
  assertElectronVersion(config);
1746
- console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.5.0"}`));
1940
+ console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.5.1"}`));
1747
1941
  console.log(import_picocolors3.default.dim(` root: ${config.root}`));
1748
1942
  console.log(import_picocolors3.default.dim(` mode: ${config.mode}`));
1749
1943
  console.log(import_picocolors3.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -1895,7 +2089,7 @@ async function startElectronDev(inlineConfig = {}) {
1895
2089
  const { noSpawn, ...rest } = inlineConfig;
1896
2090
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
1897
2091
  warnElectronVersion(config);
1898
- console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.5.0"}`));
2092
+ console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.5.1"}`));
1899
2093
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
1900
2094
  const server = await createServer2({ ...rest, target: "electron" });
1901
2095
  await server.listen();
@@ -1959,11 +2153,16 @@ async function startElectronDev(inlineConfig = {}) {
1959
2153
  const watchTargets = [mainEntry, ...preloadEntries].filter(import_node_fs10.default.existsSync);
1960
2154
  const watcher = import_chokidar2.default.watch(watchTargets, { ignoreInitial: true });
1961
2155
  let restarting = null;
1962
- watcher.on("all", async () => {
1963
- if (restarting) return;
2156
+ let pending = false;
2157
+ const restart = async () => {
2158
+ if (restarting) {
2159
+ pending = true;
2160
+ return;
2161
+ }
1964
2162
  restarting = (async () => {
1965
- console.log(import_picocolors4.default.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1966
- try {
2163
+ do {
2164
+ pending = false;
2165
+ console.log(import_picocolors4.default.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1967
2166
  if (child && !child.killed) {
1968
2167
  ;
1969
2168
  child.__nastiKilled = true;
@@ -1977,12 +2176,24 @@ async function startElectronDev(inlineConfig = {}) {
1977
2176
  dying.kill();
1978
2177
  });
1979
2178
  }
1980
- await compileAll();
1981
- spawnElectron();
1982
- } finally {
1983
- restarting = null;
1984
- }
2179
+ try {
2180
+ await compileAll();
2181
+ spawnElectron();
2182
+ } catch (e) {
2183
+ console.warn(import_picocolors4.default.yellow(` \u26A0 \u91CD\u542F\u7F16\u8BD1\u5931\u8D25\uFF0C\u4FDD\u7559\u4E0A\u4E00\u6B21\u8FDB\u7A0B: ${e.message}`));
2184
+ }
2185
+ } while (pending);
2186
+ restarting = null;
1985
2187
  })();
2188
+ return restarting;
2189
+ };
2190
+ let debounceTimer = null;
2191
+ watcher.on("all", () => {
2192
+ if (debounceTimer) clearTimeout(debounceTimer);
2193
+ debounceTimer = setTimeout(() => {
2194
+ debounceTimer = null;
2195
+ void restart();
2196
+ }, 80);
1986
2197
  });
1987
2198
  }
1988
2199
  }
@@ -2030,7 +2241,7 @@ function resolveElectronBinary(config) {
2030
2241
  return config.electron.electronPath;
2031
2242
  }
2032
2243
  try {
2033
- const require2 = (0, import_node_module3.createRequire)(import_node_path12.default.resolve(config.root, "package.json"));
2244
+ const require2 = (0, import_node_module4.createRequire)(import_node_path12.default.resolve(config.root, "package.json"));
2034
2245
  const pathFile = require2.resolve("electron");
2035
2246
  const electronModule = require2(pathFile);
2036
2247
  if (typeof electronModule === "string" && import_node_fs10.default.existsSync(electronModule)) {
@@ -2058,13 +2269,13 @@ function warnElectronVersion(config) {
2058
2269
  );
2059
2270
  }
2060
2271
  }
2061
- var import_node_path12, import_node_fs10, import_node_module3, import_node_child_process, import_chokidar2, import_picocolors4, import_rolldown3;
2272
+ var import_node_path12, import_node_fs10, import_node_module4, import_node_child_process, import_chokidar2, import_picocolors4, import_rolldown3;
2062
2273
  var init_electron_dev = __esm({
2063
2274
  "src/server/electron-dev.ts"() {
2064
2275
  "use strict";
2065
2276
  import_node_path12 = __toESM(require("path"), 1);
2066
2277
  import_node_fs10 = __toESM(require("fs"), 1);
2067
- import_node_module3 = require("module");
2278
+ import_node_module4 = require("module");
2068
2279
  import_node_child_process = require("child_process");
2069
2280
  import_chokidar2 = __toESM(require("chokidar"), 1);
2070
2281
  import_picocolors4 = __toESM(require("picocolors"), 1);
@@ -2211,6 +2422,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
2211
2422
  }
2212
2423
  });
2213
2424
  cli.help();
2214
- cli.version("1.5.0");
2425
+ cli.version("1.5.1");
2215
2426
  cli.parse();
2216
2427
  //# sourceMappingURL=cli.cjs.map