@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/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,89 @@ 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
+ const pkgPath = __require.resolve("react-refresh/package.json");
767
+ cjsPath = import_node_path4.default.join(import_node_path4.default.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
768
+ } catch (err) {
769
+ cjsPath = import_node_path4.default.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
770
+ if (!import_node_fs4.default.existsSync(cjsPath)) {
771
+ const origMsg = err instanceof Error ? err.message : String(err);
772
+ throw new Error(
773
+ `[nasti] Missing dependency "react-refresh". Install it with: npm install react-refresh
774
+ Original resolve error: ${origMsg}`
775
+ );
776
+ }
777
+ }
778
+ const cjsSource = import_node_fs4.default.readFileSync(cjsPath, "utf-8");
779
+ __refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM
780
+ const exports = {};
781
+ const module = { exports };
782
+ const process = { env: { NODE_ENV: 'development' } };
783
+ ${cjsSource}
784
+ const __rt = module.exports;
785
+ export const injectIntoGlobalHook = __rt.injectIntoGlobalHook;
786
+ export const register = __rt.register;
787
+ export const createSignatureFunctionForTransform = __rt.createSignatureFunctionForTransform;
788
+ export const performReactRefresh = __rt.performReactRefresh;
789
+ export const isLikelyComponentType = __rt.isLikelyComponentType;
790
+ export const hasUnrecoverableErrors = __rt.hasUnrecoverableErrors;
791
+ export const setSignature = __rt.setSignature;
792
+ export const getFamilyByID = __rt.getFamilyByID;
793
+ export const getFamilyByType = __rt.getFamilyByType;
794
+ export const findAffectedHostInstances = __rt.findAffectedHostInstances;
795
+ export const collectCustomHooksForSignature = __rt.collectCustomHooksForSignature;
796
+ export default __rt;
797
+ `;
798
+ return __refreshRuntimeCache;
799
+ }
800
+ function buildReactRefreshWrapper(moduleUrl, transformedCode) {
801
+ const urlLit = JSON.stringify(moduleUrl);
802
+ const userCode = transformedCode.replace(/\bimport\.meta\.hot\b/g, "__nasti_hot__");
803
+ return `import * as RefreshRuntime from "/@react-refresh";
804
+ import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
805
+ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
806
+
807
+ if (!window.__vite_plugin_react_preamble_installed__) {
808
+ throw new Error("[nasti] React Fast Refresh preamble missing. Make sure nasti:html is wired with framework: 'react'.");
809
+ }
810
+
811
+ const prevRefreshReg = window.$RefreshReg$;
812
+ const prevRefreshSig = window.$RefreshSig$;
813
+ window.$RefreshReg$ = (type, id) => {
814
+ RefreshRuntime.register(type, ${urlLit} + " " + id);
815
+ };
816
+ window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
817
+
818
+ ${userCode}
819
+
820
+ window.$RefreshReg$ = prevRefreshReg;
821
+ window.$RefreshSig$ = prevRefreshSig;
822
+
823
+ if (__nasti_hot__) {
824
+ __nasti_hot__.accept(() => {
825
+ clearTimeout(window.__nasti_refresh_timer__);
826
+ window.__nasti_refresh_timer__ = setTimeout(() => {
827
+ RefreshRuntime.performReactRefresh();
828
+ }, 30);
829
+ });
830
+ }
831
+ `;
832
+ }
833
+ function injectImportMetaHot(code, moduleUrl) {
834
+ if (!/\bimport\.meta\.hot\b/.test(code)) return code;
835
+ const urlLit = JSON.stringify(moduleUrl);
836
+ const header = `import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
837
+ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
838
+ `;
839
+ return header + code.replace(/\bimport\.meta\.hot\b/g, "__nasti_hot__");
840
+ }
670
841
  function transformMiddleware(ctx) {
671
842
  ctx.envDefine = buildEnvDefine(
672
843
  loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
@@ -740,7 +911,7 @@ async function transformRequest(url, ctx) {
740
911
  return cached.transformResult;
741
912
  }
742
913
  if (cleanReqUrl === "/@react-refresh") {
743
- return { code: REACT_REFRESH_RUNTIME };
914
+ return { code: getReactRefreshRuntimeEsm() };
744
915
  }
745
916
  const filePath = resolveUrlToFile(url, config.root);
746
917
  if (!filePath || !import_node_fs4.default.existsSync(filePath)) return null;
@@ -757,6 +928,8 @@ async function transformRequest(url, ctx) {
757
928
  if (pluginResult) {
758
929
  code = typeof pluginResult === "string" ? pluginResult : pluginResult.code;
759
930
  }
931
+ const stableUrl = cleanReqUrl;
932
+ let wrappedWithRefresh = false;
760
933
  if (shouldTransform(filePath)) {
761
934
  const isJsx = /\.[jt]sx$/.test(filePath);
762
935
  const useRefresh = isJsx && config.framework !== "vue";
@@ -768,9 +941,14 @@ async function transformRequest(url, ctx) {
768
941
  });
769
942
  code = result.code;
770
943
  if (useRefresh) {
771
- code = REACT_REFRESH_PREAMBLE + code + REACT_REFRESH_FOOTER;
944
+ code = buildReactRefreshWrapper(stableUrl, code);
945
+ wrappedWithRefresh = true;
946
+ mod.isSelfAccepting = true;
772
947
  }
773
948
  }
949
+ if (!wrappedWithRefresh) {
950
+ code = injectImportMetaHot(code, stableUrl);
951
+ }
774
952
  const envDefine = ctx.envDefine ?? buildEnvDefine(
775
953
  loadEnv(config.mode, config.root, config.envPrefix),
776
954
  config.mode
@@ -838,8 +1016,8 @@ function rewriteExternalRequires(code) {
838
1016
  }
839
1017
  async function injectCjsNamedExports(code, entryFile) {
840
1018
  try {
841
- const { createRequire: createRequire3 } = await import("module");
842
- const req = createRequire3(entryFile);
1019
+ const { createRequire: createRequire4 } = await import("module");
1020
+ const req = createRequire4(entryFile);
843
1021
  const cjsExports = req(entryFile);
844
1022
  if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
845
1023
  const namedKeys = Object.keys(cjsExports).filter(
@@ -1002,12 +1180,15 @@ function getHmrClientCode() {
1002
1180
  // Nasti HMR Client
1003
1181
  const socket = new WebSocket(\`ws://\${location.host}\`, 'nasti-hmr');
1004
1182
  const hotModulesMap = new Map();
1183
+ const disposeMap = new Map();
1184
+ const pruneMap = new Map();
1005
1185
 
1006
1186
  socket.addEventListener('message', ({ data }) => {
1007
1187
  const payload = JSON.parse(data);
1008
1188
  switch (payload.type) {
1009
1189
  case 'connected':
1010
1190
  console.log('[nasti] connected.');
1191
+ clearErrorOverlay();
1011
1192
  break;
1012
1193
  case 'update':
1013
1194
  payload.updates.forEach((update) => {
@@ -1017,11 +1198,18 @@ socket.addEventListener('message', ({ data }) => {
1017
1198
  updateCss(update.path);
1018
1199
  }
1019
1200
  });
1201
+ clearErrorOverlay();
1020
1202
  break;
1021
1203
  case 'full-reload':
1022
1204
  console.log('[nasti] full reload');
1023
1205
  location.reload();
1024
1206
  break;
1207
+ case 'prune':
1208
+ payload.paths.forEach((p) => {
1209
+ const cb = pruneMap.get(p);
1210
+ if (cb) cb();
1211
+ });
1212
+ break;
1025
1213
  case 'error':
1026
1214
  console.error('[nasti] error:', payload.err.message);
1027
1215
  showErrorOverlay(payload.err);
@@ -1029,14 +1217,23 @@ socket.addEventListener('message', ({ data }) => {
1029
1217
  }
1030
1218
  });
1031
1219
 
1220
+ // \u81EA\u52A8\u91CD\u8FDE\uFF08\u65AD\u7EBF\u65F6\u6307\u6570\u9000\u907F\uFF09
1221
+ let reconnectTimer = 0;
1222
+ socket.addEventListener('close', () => {
1223
+ clearTimeout(reconnectTimer);
1224
+ reconnectTimer = setTimeout(() => location.reload(), 1000);
1225
+ });
1226
+
1032
1227
  async function fetchUpdate(update) {
1033
1228
  const mod = hotModulesMap.get(update.path);
1229
+ // \u5148\u8DD1 dispose\uFF08\u7ED9\u6A21\u5757\u673A\u4F1A\u6E05\u7406\u526F\u4F5C\u7528\uFF09
1230
+ const dispose = disposeMap.get(update.path);
1231
+ if (dispose) dispose();
1232
+
1233
+ const newMod = await import(update.acceptedPath + '?t=' + update.timestamp);
1034
1234
  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);
1235
+ // \u590D\u5236\u56DE\u8C03\u6570\u7EC4\u907F\u514D\u56DE\u8C03\u5185\u90E8\u53C8\u4FEE\u6539 hotModulesMap \u9020\u6210\u8FED\u4EE3\u5F02\u5E38
1236
+ [...mod.callbacks].forEach((cb) => cb(newMod));
1040
1237
  }
1041
1238
  }
1042
1239
 
@@ -1049,7 +1246,13 @@ function updateCss(path) {
1049
1246
  }
1050
1247
  }
1051
1248
 
1249
+ function clearErrorOverlay() {
1250
+ const el = document.getElementById('nasti-error-overlay');
1251
+ if (el) el.remove();
1252
+ }
1253
+
1052
1254
  function showErrorOverlay(err) {
1255
+ clearErrorOverlay();
1053
1256
  const overlay = document.createElement('div');
1054
1257
  overlay.id = 'nasti-error-overlay';
1055
1258
  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 +1271,60 @@ function showErrorOverlay(err) {
1068
1271
  document.body.appendChild(overlay);
1069
1272
  }
1070
1273
 
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 };
1274
+ /**
1275
+ * \u751F\u6210 import.meta.hot \u7684 hot context\u3002
1276
+ * \u5173\u952E\u7EA6\u675F\uFF1A\u540C\u4E00 ownerPath \u7684 accept \u56DE\u8C03\u5FC5\u987B\u66FF\u6362\uFF08\u4E0D\u662F append\uFF09\u3002
1277
+ * \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
1278
+ * \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
1279
+ */
1280
+ export function createHotContext(ownerPath) {
1281
+ return {
1282
+ accept(deps, callback) {
1283
+ // \u81EA\u63A5\u53D7: hot.accept() \u6216 hot.accept(callback)
1284
+ if (typeof deps === 'function' || deps === undefined) {
1285
+ hotModulesMap.set(ownerPath, { callbacks: [deps || (() => {})] });
1286
+ return;
1287
+ }
1288
+ // \u4F9D\u8D56\u63A5\u53D7: hot.accept(deps, callback)\uFF0C\u591A\u6B21\u8C03\u7528\u8FFD\u52A0
1289
+ const existing = hotModulesMap.get(ownerPath)?.callbacks ?? [];
1290
+ hotModulesMap.set(ownerPath, { callbacks: [...existing, callback] });
1291
+ },
1292
+ prune(callback) {
1293
+ pruneMap.set(ownerPath, callback);
1294
+ },
1295
+ dispose(callback) {
1296
+ disposeMap.set(ownerPath, callback);
1297
+ },
1298
+ invalidate() {
1299
+ location.reload();
1300
+ },
1301
+ data: {},
1302
+ };
1303
+ }
1096
1304
  `;
1097
1305
  }
1098
- var import_node_path4, import_node_fs4, REACT_REFRESH_RUNTIME, REACT_REFRESH_PREAMBLE, REACT_REFRESH_FOOTER, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
1306
+ 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
1307
  var init_middleware = __esm({
1100
1308
  "src/server/middleware.ts"() {
1101
1309
  "use strict";
1102
1310
  import_node_path4 = __toESM(require("path"), 1);
1103
1311
  import_node_fs4 = __toESM(require("fs"), 1);
1312
+ import_node_module = require("module");
1313
+ import_node_url2 = require("url");
1104
1314
  init_transformer();
1105
1315
  init_html();
1106
1316
  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
- `;
1317
+ import_meta = {};
1318
+ __dirname_esm = import_node_path4.default.dirname((0, import_node_url2.fileURLToPath)(import_meta.url));
1319
+ __require = (0, import_node_module.createRequire)(import_meta.url);
1320
+ __refreshRuntimeCache = null;
1321
+ REACT_REFRESH_GLOBAL_PREAMBLE = `
1322
+ import RefreshRuntime from "/@react-refresh";
1323
+ RefreshRuntime.injectIntoGlobalHook(window);
1324
+ window.$RefreshReg$ = () => {};
1325
+ window.$RefreshSig$ = () => (type) => type;
1326
+ window.__vite_plugin_react_preamble_installed__ = true;
1327
+ `.trim();
1126
1328
  esmBundleCache = /* @__PURE__ */ new Map();
1127
1329
  VALID_IDENT = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
1128
1330
  RESOLVE_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".json", ".vue"];
@@ -1190,7 +1392,7 @@ var init_hmr = __esm({
1190
1392
  // src/plugins/resolve.ts
1191
1393
  function resolvePlugin(config) {
1192
1394
  const { alias, extensions } = config.resolve;
1193
- const require2 = (0, import_node_module.createRequire)(import_node_path6.default.resolve(config.root, "package.json"));
1395
+ const require2 = (0, import_node_module2.createRequire)(import_node_path6.default.resolve(config.root, "package.json"));
1194
1396
  return {
1195
1397
  name: "nasti:resolve",
1196
1398
  enforce: "pre",
@@ -1256,13 +1458,13 @@ function tryResolveFile(file, extensions) {
1256
1458
  }
1257
1459
  return null;
1258
1460
  }
1259
- var import_node_path6, import_node_fs6, import_node_module;
1461
+ var import_node_path6, import_node_fs6, import_node_module2;
1260
1462
  var init_resolve = __esm({
1261
1463
  "src/plugins/resolve.ts"() {
1262
1464
  "use strict";
1263
1465
  import_node_path6 = __toESM(require("path"), 1);
1264
1466
  import_node_fs6 = __toESM(require("fs"), 1);
1265
- import_node_module = require("module");
1467
+ import_node_module2 = require("module");
1266
1468
  }
1267
1469
  });
1268
1470
 
@@ -1455,7 +1657,7 @@ async function createServer(inlineConfig = {}) {
1455
1657
  const localUrl = `http://localhost:${actualPort}`;
1456
1658
  const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}` : null;
1457
1659
  console.log();
1458
- console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.5.0"}`));
1660
+ console.log(import_picocolors.default.cyan(" nasti dev server") + import_picocolors.default.dim(` v${"1.5.2"}`));
1459
1661
  console.log();
1460
1662
  console.log(` ${import_picocolors.default.green(">")} Local: ${import_picocolors.default.cyan(localUrl)}`);
1461
1663
  if (networkUrl) {
@@ -1556,14 +1758,14 @@ function electronPlugin(config) {
1556
1758
  }
1557
1759
  };
1558
1760
  }
1559
- var import_node_module2, NODE_BUILTINS, ELECTRON_MODULES;
1761
+ var import_node_module3, NODE_BUILTINS, ELECTRON_MODULES;
1560
1762
  var init_electron = __esm({
1561
1763
  "src/plugins/electron.ts"() {
1562
1764
  "use strict";
1563
- import_node_module2 = require("module");
1765
+ import_node_module3 = require("module");
1564
1766
  NODE_BUILTINS = /* @__PURE__ */ new Set([
1565
- ...import_node_module2.builtinModules,
1566
- ...import_node_module2.builtinModules.map((m) => `node:${m}`)
1767
+ ...import_node_module3.builtinModules,
1768
+ ...import_node_module3.builtinModules.map((m) => `node:${m}`)
1567
1769
  ]);
1568
1770
  ELECTRON_MODULES = /* @__PURE__ */ new Set([
1569
1771
  "electron",
@@ -1582,7 +1784,7 @@ __export(build_exports, {
1582
1784
  async function build(inlineConfig = {}) {
1583
1785
  const config = await resolveConfig(inlineConfig, "build");
1584
1786
  const startTime = performance.now();
1585
- console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.5.0"}`));
1787
+ console.log(import_picocolors2.default.cyan("\n\u{1F528} nasti build") + import_picocolors2.default.dim(` v${"1.5.2"}`));
1586
1788
  console.log(import_picocolors2.default.dim(` root: ${config.root}`));
1587
1789
  console.log(import_picocolors2.default.dim(` mode: ${config.mode}`));
1588
1790
  const outDir = import_node_path10.default.resolve(config.root, config.build.outDir);
@@ -1743,7 +1945,7 @@ async function buildElectron(inlineConfig = {}) {
1743
1945
  const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
1744
1946
  const startTime = performance.now();
1745
1947
  assertElectronVersion(config);
1746
- console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.5.0"}`));
1948
+ console.log(import_picocolors3.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors3.default.dim(` v${"1.5.2"}`));
1747
1949
  console.log(import_picocolors3.default.dim(` root: ${config.root}`));
1748
1950
  console.log(import_picocolors3.default.dim(` mode: ${config.mode}`));
1749
1951
  console.log(import_picocolors3.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
@@ -1895,7 +2097,7 @@ async function startElectronDev(inlineConfig = {}) {
1895
2097
  const { noSpawn, ...rest } = inlineConfig;
1896
2098
  const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
1897
2099
  warnElectronVersion(config);
1898
- console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.5.0"}`));
2100
+ console.log(import_picocolors4.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors4.default.dim(` v${"1.5.2"}`));
1899
2101
  const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
1900
2102
  const server = await createServer2({ ...rest, target: "electron" });
1901
2103
  await server.listen();
@@ -1959,11 +2161,16 @@ async function startElectronDev(inlineConfig = {}) {
1959
2161
  const watchTargets = [mainEntry, ...preloadEntries].filter(import_node_fs10.default.existsSync);
1960
2162
  const watcher = import_chokidar2.default.watch(watchTargets, { ignoreInitial: true });
1961
2163
  let restarting = null;
1962
- watcher.on("all", async () => {
1963
- if (restarting) return;
2164
+ let pending = false;
2165
+ const restart = async () => {
2166
+ if (restarting) {
2167
+ pending = true;
2168
+ return;
2169
+ }
1964
2170
  restarting = (async () => {
1965
- console.log(import_picocolors4.default.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1966
- try {
2171
+ do {
2172
+ pending = false;
2173
+ console.log(import_picocolors4.default.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
1967
2174
  if (child && !child.killed) {
1968
2175
  ;
1969
2176
  child.__nastiKilled = true;
@@ -1977,12 +2184,24 @@ async function startElectronDev(inlineConfig = {}) {
1977
2184
  dying.kill();
1978
2185
  });
1979
2186
  }
1980
- await compileAll();
1981
- spawnElectron();
1982
- } finally {
1983
- restarting = null;
1984
- }
2187
+ try {
2188
+ await compileAll();
2189
+ spawnElectron();
2190
+ } catch (e) {
2191
+ console.warn(import_picocolors4.default.yellow(` \u26A0 \u91CD\u542F\u7F16\u8BD1\u5931\u8D25\uFF0C\u4FDD\u7559\u4E0A\u4E00\u6B21\u8FDB\u7A0B: ${e.message}`));
2192
+ }
2193
+ } while (pending);
2194
+ restarting = null;
1985
2195
  })();
2196
+ return restarting;
2197
+ };
2198
+ let debounceTimer = null;
2199
+ watcher.on("all", () => {
2200
+ if (debounceTimer) clearTimeout(debounceTimer);
2201
+ debounceTimer = setTimeout(() => {
2202
+ debounceTimer = null;
2203
+ void restart();
2204
+ }, 80);
1986
2205
  });
1987
2206
  }
1988
2207
  }
@@ -2030,7 +2249,7 @@ function resolveElectronBinary(config) {
2030
2249
  return config.electron.electronPath;
2031
2250
  }
2032
2251
  try {
2033
- const require2 = (0, import_node_module3.createRequire)(import_node_path12.default.resolve(config.root, "package.json"));
2252
+ const require2 = (0, import_node_module4.createRequire)(import_node_path12.default.resolve(config.root, "package.json"));
2034
2253
  const pathFile = require2.resolve("electron");
2035
2254
  const electronModule = require2(pathFile);
2036
2255
  if (typeof electronModule === "string" && import_node_fs10.default.existsSync(electronModule)) {
@@ -2058,13 +2277,13 @@ function warnElectronVersion(config) {
2058
2277
  );
2059
2278
  }
2060
2279
  }
2061
- var import_node_path12, import_node_fs10, import_node_module3, import_node_child_process, import_chokidar2, import_picocolors4, import_rolldown3;
2280
+ var import_node_path12, import_node_fs10, import_node_module4, import_node_child_process, import_chokidar2, import_picocolors4, import_rolldown3;
2062
2281
  var init_electron_dev = __esm({
2063
2282
  "src/server/electron-dev.ts"() {
2064
2283
  "use strict";
2065
2284
  import_node_path12 = __toESM(require("path"), 1);
2066
2285
  import_node_fs10 = __toESM(require("fs"), 1);
2067
- import_node_module3 = require("module");
2286
+ import_node_module4 = require("module");
2068
2287
  import_node_child_process = require("child_process");
2069
2288
  import_chokidar2 = __toESM(require("chokidar"), 1);
2070
2289
  import_picocolors4 = __toESM(require("picocolors"), 1);
@@ -2211,6 +2430,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
2211
2430
  }
2212
2431
  });
2213
2432
  cli.help();
2214
- cli.version("1.5.0");
2433
+ cli.version("1.5.2");
2215
2434
  cli.parse();
2216
2435
  //# sourceMappingURL=cli.cjs.map