@dimina-kit/devtools 0.4.0-dev.20260703051110 → 0.4.0-dev.20260706064107

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.
Files changed (58) hide show
  1. package/dist/main/app/app.js +6 -0
  2. package/dist/main/index.bundle.js +445 -49
  3. package/dist/main/ipc/bridge-router.d.ts +8 -0
  4. package/dist/main/ipc/bridge-router.js +352 -38
  5. package/dist/main/services/compile-standby.d.ts +26 -0
  6. package/dist/main/services/compile-standby.js +57 -0
  7. package/dist/main/services/console-forward/index.d.ts +12 -1
  8. package/dist/main/services/console-forward/index.js +99 -1
  9. package/dist/main/services/diagnostics/index.d.ts +49 -0
  10. package/dist/main/services/diagnostics/index.js +61 -0
  11. package/dist/main/services/network-forward/index.js +32 -0
  12. package/dist/main/services/notifications/renderer-notifier.d.ts +39 -0
  13. package/dist/main/services/notifications/renderer-notifier.js +4 -1
  14. package/dist/main/services/projects/project-repository.js +2 -1
  15. package/dist/main/services/views/simulator-session-policy.js +17 -0
  16. package/dist/main/services/workbench-context.d.ts +10 -0
  17. package/dist/main/services/workspace/workspace-service.js +12 -3
  18. package/dist/main/windows/service-host-window/create.d.ts +15 -1
  19. package/dist/main/windows/service-host-window/create.js +11 -3
  20. package/dist/preload/shared/api-compat.js +18 -55
  21. package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
  22. package/dist/preload/windows/main.cjs.map +1 -1
  23. package/dist/preload/windows/simulator.cjs +117 -44
  24. package/dist/preload/windows/simulator.cjs.map +3 -3
  25. package/dist/preload/windows/simulator.js +117 -44
  26. package/dist/renderer/assets/index-BwzPwCmM.js +49 -0
  27. package/dist/renderer/assets/{input-Cjk0wSEh.js → input-CTb_le7F.js} +2 -2
  28. package/dist/renderer/assets/ipc-transport-BPWIV5hA.css +1 -0
  29. package/dist/renderer/assets/{ipc-transport-OZS-KmOW.js → ipc-transport-Ck5Xa8Tu.js} +2 -2
  30. package/dist/renderer/assets/popover-B1Zu2UQu.js +2 -0
  31. package/dist/renderer/assets/{select-BQDXi5ih.js → select-ozSk5Pt6.js} +2 -2
  32. package/dist/renderer/assets/{settings-tP3Px2KR.js → settings-CNwGOI22.js} +2 -2
  33. package/dist/renderer/assets/settings-api-DMbMp1Eq.js +2 -0
  34. package/dist/renderer/assets/{workbenchSettings-COhuFF-i.js → workbenchSettings-Cr4EHo5w.js} +2 -2
  35. package/dist/renderer/entries/main/index.html +6 -6
  36. package/dist/renderer/entries/popover/index.html +5 -5
  37. package/dist/renderer/entries/settings/index.html +5 -5
  38. package/dist/renderer/entries/workbench-settings/index.html +4 -4
  39. package/dist/shared/bridge-channels.d.ts +22 -0
  40. package/dist/shared/ipc-channels.d.ts +3 -0
  41. package/dist/shared/ipc-channels.js +9 -0
  42. package/dist/shared/request-core.d.ts +84 -0
  43. package/dist/shared/request-core.js +168 -0
  44. package/dist/shared/simulator-api-metadata.d.ts +22 -17
  45. package/dist/shared/simulator-api-metadata.js +36 -0
  46. package/dist/shared/types.d.ts +7 -4
  47. package/dist/simulator/assets/{device-shell-CiLAPa0I.js → device-shell-C-wcFq3Z.js} +2 -2
  48. package/dist/simulator/assets/{jsx-runtime-CDK-o-S0.js → jsx-runtime-BDTY6fEq.js} +2 -2
  49. package/dist/simulator/assets/simulator-DU3-fS3v.js +10 -0
  50. package/dist/simulator/assets/simulator-mini-app-DzfMfnVM.js +2 -0
  51. package/dist/simulator/simulator.html +2 -2
  52. package/package.json +5 -5
  53. package/dist/renderer/assets/index-D-ksyN1p.js +0 -49
  54. package/dist/renderer/assets/ipc-transport-D5dKIti1.css +0 -1
  55. package/dist/renderer/assets/popover-CQVvOe90.js +0 -2
  56. package/dist/renderer/assets/settings-api-B6x2mhaD.js +0 -2
  57. package/dist/simulator/assets/simulator-Dvnxry3y.js +0 -10
  58. package/dist/simulator/assets/simulator-mini-app-Bt639XL_.js +0 -2
@@ -393,6 +393,9 @@ var ProjectChannel = {
393
393
  CaptureThumbnail: "project:captureThumbnail",
394
394
  GetThumbnail: "project:getThumbnail"
395
395
  };
396
+ var SessionChannel = {
397
+ RuntimeStatus: "session:runtimeStatus"
398
+ };
396
399
  var ProjectFsChannel = {
397
400
  GetRoot: "project:fs:getRoot",
398
401
  ReadFile: "project:fs:readFile",
@@ -1105,6 +1108,9 @@ function createRendererNotifier(ctx) {
1105
1108
  projectStatus(payload) {
1106
1109
  sendToMain(ProjectChannel.Status, payload);
1107
1110
  },
1111
+ sessionRuntimeStatus(payload) {
1112
+ sendToMain(SessionChannel.RuntimeStatus, payload);
1113
+ },
1108
1114
  compileLog(payload) {
1109
1115
  sendToMain(ProjectChannel.CompileLog, payload);
1110
1116
  },
@@ -3927,7 +3933,8 @@ function getProjectPages(dirPath) {
3927
3933
  pages: appJson.pages || [],
3928
3934
  entryPagePath: appJson.entryPagePath || appJson.pages?.[0] || ""
3929
3935
  };
3930
- } catch {
3936
+ } catch (err2) {
3937
+ log2.warn(`Failed to read project pages from ${appJsonPath}`, err2);
3931
3938
  return { pages: [], entryPagePath: "" };
3932
3939
  }
3933
3940
  }
@@ -4029,8 +4036,8 @@ function createWorkspaceService(ctx) {
4029
4036
  let lastClosedProjectPath = "";
4030
4037
  let logGeneration = 0;
4031
4038
  const opLock = createOpLock();
4032
- function sendStatus(status2, message, hotReload) {
4033
- ctx.notify.projectStatus(hotReload ? { status: status2, message, hotReload: true } : { status: status2, message });
4039
+ function sendStatus(status2, message, hotReload, pages, watcherDead) {
4040
+ ctx.notify.projectStatus({ status: status2, message, ...hotReload ? { hotReload: true } : {}, ...pages ? { pages } : {}, ...watcherDead ? { watcher: "dead" } : {} });
4034
4041
  }
4035
4042
  function bestEffort(label, fn) {
4036
4043
  try {
@@ -4091,8 +4098,13 @@ function createWorkspaceService(ctx) {
4091
4098
  sourcemap: true,
4092
4099
  fileTypes: ctx.fileTypes,
4093
4100
  watch: compile.watch,
4094
- onRebuild: () => sendStatus("ready", "\u7F16\u8BD1\u5B8C\u6210\uFF0C\u5DF2\u91CD\u542F", true),
4101
+ onRebuild: () => {
4102
+ const { pages } = getProjectPages(projectPath);
4103
+ sendStatus("ready", "\u7F16\u8BD1\u5B8C\u6210\uFF0C\u5DF2\u91CD\u542F", true, pages.length ? pages : void 0);
4104
+ },
4095
4105
  onBuildError: (err2) => sendStatus("error", String(err2)),
4106
+ // Watcher died mid-session (EMFILE, permission loss, …): non-fatal, so 'ready' stays but `watcher: 'dead'` flags that saves no longer auto-rebuild.
4107
+ onWatcherError: () => sendStatus("ready", "\u6587\u4EF6\u76D1\u542C\u5DF2\u505C\u6B62\uFF0C\u4FDD\u5B58\u4E0D\u518D\u89E6\u53D1\u81EA\u52A8\u7F16\u8BD1", false, void 0, true),
4096
4108
  onLog: (entry) => {
4097
4109
  if (sessionGeneration !== logGeneration) return;
4098
4110
  ctx.notify.compileLog({ stream: entry.stream, text: entry.text, at: Date.now() });
@@ -4379,6 +4391,55 @@ function createWorkbenchContext(opts) {
4379
4391
  return ctx;
4380
4392
  }
4381
4393
 
4394
+ // src/main/services/compile-standby.ts
4395
+ var EVENT_SEVERITY = {
4396
+ "spawned": "info",
4397
+ "prewarmed": "info",
4398
+ "adopted": "info",
4399
+ "died": "warn",
4400
+ "health-check-failed": "warn",
4401
+ "degraded": "error"
4402
+ };
4403
+ function setupCompileWorkerStandby(ctx, deps = {}) {
4404
+ const loadDevkit = deps.loadDevkit ?? (() => import("@dimina-kit/devkit"));
4405
+ let manager = null;
4406
+ let disposed = false;
4407
+ const forward = (ev) => {
4408
+ try {
4409
+ const detail = [
4410
+ `compile standby ${ev.type}`,
4411
+ typeof ev.pid === "number" ? `pid=${ev.pid}` : null,
4412
+ ev.reason ? `\u2014 ${ev.reason}` : null
4413
+ ].filter(Boolean).join(" ");
4414
+ ctx.diagnostics?.report({
4415
+ severity: EVENT_SEVERITY[ev.type] ?? "info",
4416
+ code: "compile-standby",
4417
+ message: detail
4418
+ });
4419
+ } catch {
4420
+ }
4421
+ };
4422
+ void (async () => {
4423
+ let enable;
4424
+ try {
4425
+ const devkit = await loadDevkit();
4426
+ enable = devkit.enableCompileWorkerStandby;
4427
+ } catch {
4428
+ return;
4429
+ }
4430
+ if (typeof enable !== "function") return;
4431
+ manager = enable({ onEvent: forward });
4432
+ if (disposed) void manager.dispose();
4433
+ })();
4434
+ return {
4435
+ dispose: async () => {
4436
+ if (disposed) return;
4437
+ disposed = true;
4438
+ await manager?.dispose();
4439
+ }
4440
+ };
4441
+ }
4442
+
4382
4443
  // src/main/menu/index.ts
4383
4444
  import { Menu } from "electron";
4384
4445
  function installAppMenu(ctx) {
@@ -4957,11 +5018,30 @@ import { app as app12, ipcMain as ipcMain3, protocol as protocol2, session as el
4957
5018
  import path17 from "node:path";
4958
5019
  import { pathToFileURL as pathToFileURL3 } from "node:url";
4959
5020
 
5021
+ // src/shared/request-core.ts
5022
+ var DEFAULT_REQUEST_TIMEOUT_MS = 6e4;
5023
+ var MAX_TIMEOUT_MS = 2147483647;
5024
+ function resolveTimeoutBudgetMs(timeout) {
5025
+ const t = Number(timeout);
5026
+ return Number.isFinite(t) && t > 0 && t <= MAX_TIMEOUT_MS ? t : DEFAULT_REQUEST_TIMEOUT_MS;
5027
+ }
5028
+
4960
5029
  // src/shared/simulator-api-metadata.ts
4961
5030
  var PERSISTENT_SIMULATOR_APIS = /* @__PURE__ */ new Set(["audioListen"]);
4962
5031
  function isPersistentSimulatorApi(name) {
4963
5032
  return PERSISTENT_SIMULATOR_APIS.has(name);
4964
5033
  }
5034
+ var NETWORK_BUDGET_SIMULATOR_APIS = /* @__PURE__ */ new Set([
5035
+ "request",
5036
+ "downloadFile",
5037
+ "uploadFile"
5038
+ ]);
5039
+ var API_CALL_WATCHDOG_MS = 5e3;
5040
+ function apiCallWatchdogMs(name, params) {
5041
+ if (!NETWORK_BUDGET_SIMULATOR_APIS.has(name)) return API_CALL_WATCHDOG_MS;
5042
+ const budget = resolveTimeoutBudgetMs(params?.timeout);
5043
+ return Math.min(budget + API_CALL_WATCHDOG_MS, MAX_TIMEOUT_MS);
5044
+ }
4965
5045
 
4966
5046
  // src/main/ipc/session-listener-bag.ts
4967
5047
  function createSessionListenerBag() {
@@ -5128,10 +5208,13 @@ function buildServiceHostSpawnUrl(opts) {
5128
5208
  }
5129
5209
  return url.toString();
5130
5210
  }
5131
- function navigateServiceHost(win, url) {
5211
+ function navigateServiceHost(win, url, opts) {
5132
5212
  const loaded = Promise.resolve(win.loadURL(url)).then(
5133
5213
  () => void 0,
5134
- () => void 0
5214
+ (err2) => {
5215
+ opts?.onLoadFailed?.(err2);
5216
+ return void 0;
5217
+ }
5135
5218
  );
5136
5219
  if (!app10.isPackaged && process.env.NODE_ENV !== "test") {
5137
5220
  const w = win;
@@ -5170,7 +5253,7 @@ function serviceHostSpec(appId, projectPath) {
5170
5253
  }
5171
5254
  function createServiceHostWindow(opts) {
5172
5255
  const win = constructServiceHostWindow({ appId: opts.appId, partition: miniappPartition(opts.appId, opts.projectPath) });
5173
- void navigateServiceHost(win, buildServiceHostSpawnUrl(opts));
5256
+ void navigateServiceHost(win, buildServiceHostSpawnUrl(opts), { onLoadFailed: opts.onLoadFailed });
5174
5257
  return win;
5175
5258
  }
5176
5259
 
@@ -5487,9 +5570,49 @@ function buildForwardScript(level, args) {
5487
5570
  return `(()=>{try{const a=JSON.parse(${JSON.stringify(argsJson)});console[${JSON.stringify(method)}]('[\u89C6\u56FE]',...a)}catch(_){}})()
5488
5571
  //# sourceURL=${RENDER_FORWARD_SOURCE_URL}`;
5489
5572
  }
5490
- function createConsoleForwarder(bridge) {
5573
+ var DIAGNOSTIC_CONSOLE_CALL = {
5574
+ error: "console.error",
5575
+ warn: "console.warn",
5576
+ info: "console.info"
5577
+ };
5578
+ function buildDiagnosticScript(severity, message) {
5579
+ const call = DIAGNOSTIC_CONSOLE_CALL[severity];
5580
+ const argsJson = JSON.stringify([`[dimina-kit] ${message}`]);
5581
+ return `(()=>{try{const a=JSON.parse(${JSON.stringify(argsJson)});${call}(...a)}catch(_){}})()
5582
+ //# sourceURL=${RENDER_FORWARD_SOURCE_URL}`;
5583
+ }
5584
+ function createConsoleForwarder(bridge, diagnostics) {
5491
5585
  const sinks = /* @__PURE__ */ new Set();
5492
5586
  const registry = new DisposableRegistry4();
5587
+ const pendingBySession = /* @__PURE__ */ new Map();
5588
+ const pendingGlobal = [];
5589
+ const readySessions = /* @__PURE__ */ new Set();
5590
+ function injectDiagnostic(wc, d) {
5591
+ wc.executeJavaScript(buildDiagnosticScript(d.severity, d.message), true).catch(() => {
5592
+ });
5593
+ }
5594
+ function handleDiagnostic(d) {
5595
+ if (d.appSessionId) {
5596
+ const wc2 = readySessions.has(d.appSessionId) && bridge.getServiceWcForBridge ? bridge.getServiceWcForBridge(d.appSessionId) : null;
5597
+ if (wc2 && !wc2.isDestroyed()) {
5598
+ injectDiagnostic(wc2, d);
5599
+ return;
5600
+ }
5601
+ const bucket = pendingBySession.get(d.appSessionId);
5602
+ if (bucket) bucket.push(d);
5603
+ else pendingBySession.set(d.appSessionId, [d]);
5604
+ return;
5605
+ }
5606
+ const wc = bridge.getServiceWc();
5607
+ if (wc && !wc.isDestroyed()) {
5608
+ injectDiagnostic(wc, d);
5609
+ return;
5610
+ }
5611
+ pendingGlobal.push(d);
5612
+ }
5613
+ if (diagnostics) {
5614
+ registry.add(diagnostics.subscribe(handleDiagnostic, { replay: true }));
5615
+ }
5493
5616
  function forwardRenderToServiceHost(entry) {
5494
5617
  let wc = null;
5495
5618
  if (entry.bridgeId && bridge.getServiceWcForBridge) {
@@ -5526,13 +5649,84 @@ function createConsoleForwarder(bridge) {
5526
5649
  sinks.delete(sink);
5527
5650
  }));
5528
5651
  },
5652
+ notifyServiceHostReady(appSessionId) {
5653
+ readySessions.add(appSessionId);
5654
+ const wc = bridge.getServiceWcForBridge ? bridge.getServiceWcForBridge(appSessionId) : null;
5655
+ if (!wc) return;
5656
+ const sessionEntries = pendingBySession.get(appSessionId);
5657
+ if (sessionEntries) {
5658
+ for (const d of sessionEntries) injectDiagnostic(wc, d);
5659
+ pendingBySession.delete(appSessionId);
5660
+ }
5661
+ if (pendingGlobal.length) {
5662
+ for (const d of pendingGlobal) injectDiagnostic(wc, d);
5663
+ pendingGlobal.length = 0;
5664
+ }
5665
+ },
5529
5666
  dispose() {
5530
5667
  sinks.clear();
5668
+ pendingBySession.clear();
5669
+ pendingGlobal.length = 0;
5670
+ readySessions.clear();
5531
5671
  return registry.disposeAll();
5532
5672
  }
5533
5673
  };
5534
5674
  }
5535
5675
 
5676
+ // src/main/services/diagnostics/index.ts
5677
+ var DEFAULT_BUFFER_CAP = 200;
5678
+ var CONSOLE_METHOD = {
5679
+ error: "error",
5680
+ warn: "warn",
5681
+ info: "info"
5682
+ };
5683
+ function createDiagnosticsBus(opts) {
5684
+ const bufferCap = opts?.bufferCap && opts.bufferCap > 0 ? opts.bufferCap : DEFAULT_BUFFER_CAP;
5685
+ const buffer = [];
5686
+ const sinks = /* @__PURE__ */ new Set();
5687
+ let disposed = false;
5688
+ return {
5689
+ report(d) {
5690
+ if (disposed) return;
5691
+ const entry = { ...d, ts: Date.now() };
5692
+ buffer.push(entry);
5693
+ if (buffer.length > bufferCap) buffer.shift();
5694
+ console[CONSOLE_METHOD[entry.severity]](`[dimina-kit:${entry.code}] ${entry.message}`);
5695
+ for (const sink of sinks) {
5696
+ try {
5697
+ sink(entry);
5698
+ } catch {
5699
+ }
5700
+ }
5701
+ },
5702
+ subscribe(sink, subOpts) {
5703
+ const replay = subOpts?.replay ?? true;
5704
+ if (replay) {
5705
+ for (const entry of buffer) {
5706
+ try {
5707
+ sink(entry);
5708
+ } catch {
5709
+ }
5710
+ }
5711
+ }
5712
+ sinks.add(sink);
5713
+ let released = false;
5714
+ return {
5715
+ dispose() {
5716
+ if (released) return;
5717
+ released = true;
5718
+ sinks.delete(sink);
5719
+ }
5720
+ };
5721
+ },
5722
+ dispose() {
5723
+ disposed = true;
5724
+ sinks.clear();
5725
+ buffer.length = 0;
5726
+ }
5727
+ };
5728
+ }
5729
+
5536
5730
  // src/main/services/simulator-storage/index.ts
5537
5731
  import { app as app11, webContents as wcStatic } from "electron";
5538
5732
  import { DisposableRegistry as DisposableRegistry5 } from "@dimina-kit/electron-deck/main";
@@ -6103,6 +6297,7 @@ function rewriteSourceMappingUrl(source, scriptUrl) {
6103
6297
  //# sourceMappingURL=${absolute}`;
6104
6298
  }
6105
6299
  var STACK_ID = "stack_0";
6300
+ var LAUNCH_TIMEOUT_MS = 2e4;
6106
6301
  var PREWARM_MAX_POOL_SIZE = 4;
6107
6302
  function resolvePrewarmPoolSize() {
6108
6303
  if (process.env.DIMINA_PREWARM_DISABLE === "1") return 0;
@@ -6124,7 +6319,6 @@ function summarizeBridgeMsg(payload) {
6124
6319
  const parts = [type, bridgeId ? `bridge=${bridgeId}` : void 0].filter(Boolean);
6125
6320
  return parts.length > 0 ? parts.join(" ") : void 0;
6126
6321
  }
6127
- var API_CALL_TIMEOUT_MS = 5e3;
6128
6322
  function findAppSessionByAppId(state, appId) {
6129
6323
  let match;
6130
6324
  for (const ap of state.appSessions.values()) if (ap.appId === appId) match = ap;
@@ -6294,13 +6488,20 @@ function installBridgeRouter(ctx) {
6294
6488
  ;
6295
6489
  globalThis.__diminaResourceCensus = () => bridgeHandle.census?.();
6296
6490
  }
6297
- const consoleForwarder = createConsoleForwarder(bridgeHandle);
6491
+ const ownsDiagnosticsBus = ctx.diagnostics === void 0;
6492
+ const diagnosticsBus = ctx.diagnostics ?? createDiagnosticsBus();
6493
+ ctx.diagnostics = diagnosticsBus;
6494
+ const consoleForwarder = createConsoleForwarder(bridgeHandle, diagnosticsBus);
6298
6495
  ctx.consoleForwarder = consoleForwarder;
6299
6496
  ctx.guestConsole = consoleForwarder;
6300
6497
  ctx.registry.add(() => {
6301
6498
  void consoleForwarder.dispose();
6302
6499
  ctx.consoleForwarder = void 0;
6303
6500
  ctx.guestConsole = void 0;
6501
+ if (ownsDiagnosticsBus) {
6502
+ diagnosticsBus.dispose();
6503
+ ctx.diagnostics = void 0;
6504
+ }
6304
6505
  });
6305
6506
  const onActivePage = (event, payload) => {
6306
6507
  const ap = state.appSessions.get(payload.appSessionId);
@@ -6460,6 +6661,39 @@ function installBridgeRouter(ctx) {
6460
6661
  );
6461
6662
  });
6462
6663
  }
6664
+ function clearLaunchTimer(ap) {
6665
+ if (ap.launchTimer === null) return;
6666
+ clearTimeout(ap.launchTimer);
6667
+ ap.launchTimer = null;
6668
+ }
6669
+ function startLaunchTimer(state, ctx, ap) {
6670
+ ap.launchTimer = setTimeout(() => {
6671
+ ap.launchTimer = null;
6672
+ if (ap.running) return;
6673
+ if (state.appSessions.get(ap.appSessionId) !== ap) return;
6674
+ const reason = `Service host did not report readiness within ${LAUNCH_TIMEOUT_MS}ms`;
6675
+ ctx.diagnostics?.report({
6676
+ severity: "error",
6677
+ code: "launch-timeout",
6678
+ message: reason,
6679
+ appSessionId: ap.appSessionId
6680
+ });
6681
+ pushRuntimeStatus(ctx, ap, { phase: "launch-failed", code: "timeout", reason });
6682
+ }, LAUNCH_TIMEOUT_MS);
6683
+ }
6684
+ function markSessionRunning(ctx, ap, page) {
6685
+ if (!page.isRoot || ap.running) return;
6686
+ ap.running = true;
6687
+ clearLaunchTimer(ap);
6688
+ pushRuntimeStatus(ctx, ap, { phase: "running" });
6689
+ }
6690
+ function pushRuntimeStatus(ctx, session5, status2) {
6691
+ ctx.notify?.sessionRuntimeStatus?.({
6692
+ appId: session5.appId,
6693
+ ...status2,
6694
+ ...session5.pageFallback ? { pageFallback: session5.pageFallback } : {}
6695
+ });
6696
+ }
6463
6697
  async function handleSpawn(state, ctx, event, opts) {
6464
6698
  const appId = opts.appId;
6465
6699
  if (!appId) throw new Error("[bridge-router] spawn requires appId");
@@ -6485,20 +6719,48 @@ async function handleSpawn(state, ctx, event, opts) {
6485
6719
  ...selectedDevice ? deviceInfoToHostEnv(selectedDevice) : {}
6486
6720
  });
6487
6721
  const appConfig = await loadAppConfig(
6488
- resourceServer ? resourceServer.baseUrl : `${resourceBaseUrl}${appId}/${root}/`
6722
+ resourceServer ? resourceServer.baseUrl : `${resourceBaseUrl}${appId}/${root}/`,
6723
+ ({ url, error }) => {
6724
+ ctx.diagnostics?.report({
6725
+ severity: "error",
6726
+ code: "app-config-unreachable",
6727
+ message: `app-config.json unreachable at ${url}: ${String(error)}`,
6728
+ appSessionId
6729
+ });
6730
+ }
6489
6731
  );
6490
6732
  const manifest = buildAppManifest(appConfig, pagePath);
6491
- const rootWindowConfig = resolvePageWindowConfig(appConfig, pagePath);
6492
- const isTab = isTabPage(appConfig, pagePath);
6733
+ const { resolvedPagePath, pageFallbackApplied } = resolveRootPagePath(manifest, pagePath);
6734
+ if (pageFallbackApplied) {
6735
+ reportPageNotFound(ctx, appSessionId, pagePath, resolvedPagePath);
6736
+ }
6737
+ const rootWindowConfig = resolvePageWindowConfig(appConfig, resolvedPagePath);
6738
+ const isTab = isTabPage(appConfig, resolvedPagePath);
6493
6739
  const usedPool = state.pool !== null;
6494
6740
  let poolEntryId = null;
6495
6741
  let serviceWindow;
6742
+ const reportServiceHostNavigationFailed = (spawnUrl, err2) => {
6743
+ const message = `Failed to navigate service host to ${spawnUrl}: ${String(err2)}`;
6744
+ ctx.diagnostics?.report({
6745
+ severity: "error",
6746
+ code: "service-host-navigation-failed",
6747
+ message,
6748
+ appSessionId
6749
+ });
6750
+ const ap = state.appSessions.get(appSessionId);
6751
+ if (ap) clearLaunchTimer(ap);
6752
+ pushRuntimeStatus(
6753
+ ctx,
6754
+ ap ?? { appId, pageFallback: pageFallbackApplied ? { requested: pagePath, resolved: resolvedPagePath } : null },
6755
+ { phase: "launch-failed", code: "service-host-navigation-failed", reason: message }
6756
+ );
6757
+ };
6496
6758
  if (state.pool) {
6497
6759
  const acquired = await state.pool.acquire(serviceHostSpec());
6498
6760
  serviceWindow = acquired.win;
6499
6761
  poolEntryId = acquired.entryId;
6500
6762
  } else {
6501
- serviceWindow = createServiceHostWindow({
6763
+ const freshWindowOptions = {
6502
6764
  bridgeId,
6503
6765
  appId,
6504
6766
  // Same (appId, projectPath) pair the simulator WCV uses, so this project's
@@ -6508,12 +6770,16 @@ async function handleSpawn(state, ctx, event, opts) {
6508
6770
  // awaits above would otherwise give the service host a different path than
6509
6771
  // the simulator WCV was built with, splitting the partition.
6510
6772
  projectPath: workspaceProjectPath || void 0,
6511
- pagePath,
6773
+ pagePath: resolvedPagePath,
6512
6774
  pkgRoot,
6513
6775
  root,
6514
6776
  resourceBaseUrl,
6515
6777
  hostEnvSnapshot: hostEnv,
6516
6778
  apiNamespaces
6779
+ };
6780
+ serviceWindow = createServiceHostWindow({
6781
+ ...freshWindowOptions,
6782
+ onLoadFailed: (err2) => reportServiceHostNavigationFailed(buildServiceHostSpawnUrl(freshWindowOptions), err2)
6517
6783
  });
6518
6784
  }
6519
6785
  const appSession = {
@@ -6537,12 +6803,15 @@ async function handleSpawn(state, ctx, event, opts) {
6537
6803
  poolEntryId,
6538
6804
  onServiceBoot: null,
6539
6805
  listenerBag: createSessionListenerBag(),
6540
- registryHandle: null
6806
+ registryHandle: null,
6807
+ running: false,
6808
+ launchTimer: null,
6809
+ pageFallback: pageFallbackApplied ? { requested: pagePath, resolved: resolvedPagePath } : null
6541
6810
  };
6542
6811
  const rootPage = {
6543
6812
  bridgeId,
6544
6813
  appSessionId,
6545
- pagePath,
6814
+ pagePath: resolvedPagePath,
6546
6815
  query: opts.query ?? {},
6547
6816
  isRoot: true,
6548
6817
  isTab,
@@ -6587,28 +6856,43 @@ async function handleSpawn(state, ctx, event, opts) {
6587
6856
  };
6588
6857
  appSession.onServiceBoot = bootOnServiceLoad;
6589
6858
  serviceWindow.webContents.on("did-finish-load", bootOnServiceLoad);
6590
- void navigateServiceHost(
6591
- serviceWindow,
6592
- buildServiceHostSpawnUrl({
6593
- bridgeId,
6594
- appId,
6595
- pagePath,
6596
- pkgRoot,
6597
- root,
6598
- resourceBaseUrl,
6599
- hostEnvSnapshot: hostEnv,
6600
- apiNamespaces
6601
- })
6602
- );
6859
+ const spawnUrl = buildServiceHostSpawnUrl({
6860
+ bridgeId,
6861
+ appId,
6862
+ pagePath: resolvedPagePath,
6863
+ pkgRoot,
6864
+ root,
6865
+ resourceBaseUrl,
6866
+ hostEnvSnapshot: hostEnv,
6867
+ apiNamespaces
6868
+ });
6869
+ void navigateServiceHost(serviceWindow, spawnUrl, {
6870
+ onLoadFailed: (err2) => reportServiceHostNavigationFailed(spawnUrl, err2)
6871
+ });
6603
6872
  } else {
6604
6873
  serviceWindow.webContents.once("did-finish-load", () => {
6605
6874
  void bootServiceHost(state, appSession, ctx);
6606
6875
  });
6607
6876
  }
6877
+ const onServiceCrashed = () => {
6878
+ clearLaunchTimer(appSession);
6879
+ ctx.diagnostics?.report({
6880
+ severity: "error",
6881
+ code: "service-host-crashed",
6882
+ message: `Service host renderer process gone for appSessionId=${appSessionId}`,
6883
+ appSessionId
6884
+ });
6885
+ pushRuntimeStatus(ctx, appSession, { phase: "crashed", code: "service-host-crashed" });
6886
+ };
6887
+ appSession.listenerBag.on(serviceWindow.webContents, "render-process-gone", onServiceCrashed);
6888
+ pushRuntimeStatus(ctx, appSession, { phase: "launching" });
6889
+ startLaunchTimer(state, ctx, appSession);
6608
6890
  return {
6609
6891
  appSessionId,
6610
6892
  bridgeId,
6611
6893
  pagePath,
6894
+ resolvedPagePath,
6895
+ pageFallbackApplied,
6612
6896
  serviceWcId: serviceWindow.webContents.id,
6613
6897
  resourceBaseUrl,
6614
6898
  manifest,
@@ -6622,6 +6906,9 @@ async function handlePageOpen(state, event, opts) {
6622
6906
  throw new Error("[bridge-router] PAGE_OPEN rejected: caller not bound to app session");
6623
6907
  }
6624
6908
  const pagePath = normalizePagePath(opts.pagePath);
6909
+ if (ap.manifest.source === "app-config" && !ap.manifest.pages.includes(pagePath)) {
6910
+ throw new Error(`[bridge-router] PAGE_OPEN rejected: page-not-found "${pagePath}" is not in the compiled manifest`);
6911
+ }
6625
6912
  const bridgeId = opts.bridgeId || newBridgeId();
6626
6913
  const windowConfig = resolvePageWindowConfig(ap.appConfig, pagePath);
6627
6914
  const isTab = isTabPage(ap.appConfig, pagePath);
@@ -6681,15 +6968,18 @@ function handleNavCallback(state, sender, payload) {
6681
6968
  }
6682
6969
  async function bootServiceHost(state, ap, ctx) {
6683
6970
  if (state.appSessions.get(ap.appSessionId) !== ap) return;
6971
+ ctx.consoleForwarder?.notifyServiceHostReady?.(ap.appSessionId);
6684
6972
  ap.logicInjected = await injectLogicBundle(ap);
6685
6973
  if (!ap.logicInjected) {
6686
- reportLogicLoadFailure(ap, ctx);
6974
+ const reason = reportLogicLoadFailure(ap, ctx);
6975
+ clearLaunchTimer(ap);
6976
+ pushRuntimeStatus(ctx, ap, { phase: "launch-failed", code: "logic-bundle-unreachable", reason });
6687
6977
  return;
6688
6978
  }
6689
6979
  const rootPage = ap.pages.get(ap.appSessionId);
6690
6980
  const rootMissing = !!rootPage && !pageInManifest(ap, rootPage.pagePath);
6691
6981
  if (rootMissing) {
6692
- reportPageNotFound(ap, ctx, rootPage.pagePath);
6982
+ reportPageNotFound(ctx, ap.appSessionId, rootPage.pagePath);
6693
6983
  } else if (rootPage) {
6694
6984
  forwardToService(ap, makeLoadResource(ap, rootPage, "service"));
6695
6985
  }
@@ -6723,16 +7013,30 @@ async function injectLogicBundle(ap) {
6723
7013
  }
6724
7014
  function reportLogicLoadFailure(ap, ctx) {
6725
7015
  const hint = ap.appId === "unknown" ? ' appId could not be resolved (it fell back to "unknown") \u2014 the mini-program likely failed to compile or its project manifest/app config is missing.' : "";
6726
- const message = `[dimina-kit] Failed to load the mini-program logic bundle from ${logicBundleUrl(ap)}. The service runtime has no registered modules, so no page can mount.` + hint + ` Verify the project compiled successfully and that the resource server serves "${ap.appId}/${ap.root}/".`;
6727
- console.error(message);
7016
+ const shortReason = `[dimina-kit] Failed to load the mini-program logic bundle from ${logicBundleUrl(ap)}.`;
7017
+ const message = `${shortReason} The service runtime has no registered modules, so no page can mount.` + hint + ` Verify the project compiled successfully and that the resource server serves "${ap.appId}/${ap.root}/".`;
7018
+ ctx.diagnostics?.report({
7019
+ severity: "error",
7020
+ code: "logic-bundle-unreachable",
7021
+ message,
7022
+ appSessionId: ap.appSessionId
7023
+ });
6728
7024
  ctx.guestConsole?.emit({ source: "service", level: "error", args: [message] });
7025
+ return shortReason;
6729
7026
  }
6730
7027
  function pageInManifest(ap, pagePath) {
7028
+ if (ap.manifest.source !== "app-config") return true;
6731
7029
  return ap.manifest.pages.includes(normalizePagePath(pagePath));
6732
7030
  }
6733
- function reportPageNotFound(ap, ctx, pagePath) {
6734
- const message = `Page[${pagePath}] not found. May be caused by: 1. Forgetting to add page route in app.json. 2. Invoking Page() in async task.`;
6735
- console.error(`[bridge-router] ${message}`);
7031
+ function reportPageNotFound(ctx, appSessionId, pagePath, fallbackTo) {
7032
+ const base = `Page[${pagePath}] not found. May be caused by: 1. Forgetting to add page route in app.json. 2. Invoking Page() in async task.`;
7033
+ const message = fallbackTo ? `${base} Falling back to "${fallbackTo}".` : base;
7034
+ ctx.diagnostics?.report({
7035
+ severity: "error",
7036
+ code: "page-not-found",
7037
+ message,
7038
+ appSessionId
7039
+ });
6736
7040
  ctx.guestConsole?.emit({ source: "service", level: "error", args: [message] });
6737
7041
  }
6738
7042
  function maybeSendResourceLoaded(ap, page) {
@@ -6789,6 +7093,11 @@ function routeFromRender(state, ap, page, msg, ctx) {
6789
7093
  handleContainerMsg(ap, page, msg, ctx, state);
6790
7094
  }
6791
7095
  }
7096
+ function reportServiceUncaughtError(ctx, ap, body) {
7097
+ const severity = body.level === "error" ? "error" : body.level === "warn" ? "warn" : "info";
7098
+ const message = Array.isArray(body.args) ? body.args.map((a) => String(a)).join(" ") : String(body.args ?? "");
7099
+ ctx.diagnostics?.report({ severity, code: "service-uncaught-error", message, appSessionId: ap.appSessionId });
7100
+ }
6792
7101
  function handleContainerMsg(ap, page, msg, ctx, state) {
6793
7102
  switch (msg.type) {
6794
7103
  case "serviceResourceLoaded":
@@ -6807,22 +7116,31 @@ function handleContainerMsg(ap, page, msg, ctx, state) {
6807
7116
  ap.simulatorWc.send(SIMULATOR_EVENTS.DOM_READY, { bridgeId: page.bridgeId });
6808
7117
  }
6809
7118
  state.emitRenderEvent({ kind: "domReady", appId: ap.appId, bridgeId: page.bridgeId });
7119
+ markSessionRunning(ctx, ap, page);
6810
7120
  break;
6811
7121
  case "invokeAPI":
6812
7122
  void handleSimulatorApi(state, ap, page, msg.body, ctx);
6813
7123
  break;
6814
7124
  case "serviceHostError": {
6815
- console.warn("[bridge-router] service host error:", msg.body);
6816
7125
  const errBody = msg.body;
6817
7126
  const errArg = errBody?.message ?? msg.body;
7127
+ ctx.diagnostics?.report({
7128
+ severity: "error",
7129
+ code: "service-host-error",
7130
+ message: String(errArg),
7131
+ appSessionId: ap.appSessionId
7132
+ });
6818
7133
  for (const id of state.appLifecycle.listeners(ap.appSessionId, "onError")) {
6819
7134
  sendCallback(ap, id, errArg);
6820
7135
  }
6821
7136
  break;
6822
7137
  }
6823
- case "consoleLog":
7138
+ case "consoleLog": {
6824
7139
  ctx.guestConsole?.emit(msg.body);
7140
+ const body = msg.body;
7141
+ if (body?.source === "service") reportServiceUncaughtError(ctx, ap, body);
6825
7142
  break;
7143
+ }
6826
7144
  case "storageChanged":
6827
7145
  ctx.onServiceStorageChanged?.(ap.appId, msg.body);
6828
7146
  break;
@@ -6903,16 +7221,44 @@ function handleNavBarApi(ap, page, name, params) {
6903
7221
  sendCallback(ap, params.success, successResult);
6904
7222
  sendCallback(ap, params.complete, successResult);
6905
7223
  }
7224
+ function failActionCallback(ap, params, errMsg) {
7225
+ const fail = { errMsg };
7226
+ sendCallback(ap, params.fail, fail);
7227
+ sendCallback(ap, params.complete, fail);
7228
+ }
6906
7229
  function sendActionOrFail(ap, eventName, payload, name, params) {
6907
7230
  if (!ap.simulatorWc.isDestroyed()) {
6908
7231
  ap.simulatorWc.send(eventName, payload);
6909
7232
  return;
6910
7233
  }
6911
- const fail = { errMsg: `${name}:fail simulator window destroyed` };
6912
- sendCallback(ap, params.fail, fail);
6913
- sendCallback(ap, params.complete, fail);
7234
+ failActionCallback(ap, params, `${name}:fail simulator window destroyed`);
7235
+ }
7236
+ function extractNavTargetPagePath(params) {
7237
+ const raw = params.url;
7238
+ if (typeof raw !== "string" || !raw) return void 0;
7239
+ return normalizePagePath(raw.split("?")[0] ?? raw);
7240
+ }
7241
+ function checkNavTarget(ap, name, targetPagePath) {
7242
+ if (ap.manifest.source !== "app-config") return { ok: true };
7243
+ if (!ap.manifest.pages.includes(targetPagePath)) {
7244
+ return { ok: false, errMsg: `${name}:fail page "${targetPagePath}" is not found`, reportNotFound: true };
7245
+ }
7246
+ if (name === "switchTab") {
7247
+ const inTabBar = ap.manifest.tabBar?.list.some((item) => normalizePagePath(item.pagePath) === targetPagePath) ?? false;
7248
+ if (!inTabBar) return { ok: false, errMsg: "switchTab:fail can not switch to no-tabBar page" };
7249
+ }
7250
+ return { ok: true };
6914
7251
  }
6915
- function handleNavActionApi(ap, page, name, params) {
7252
+ function handleNavActionApi(ap, ctx, page, name, params) {
7253
+ const targetPagePath = extractNavTargetPagePath(params);
7254
+ if (targetPagePath !== void 0) {
7255
+ const verdict = checkNavTarget(ap, name, targetPagePath);
7256
+ if (!verdict.ok) {
7257
+ if (verdict.reportNotFound) reportPageNotFound(ctx, ap.appSessionId, targetPagePath);
7258
+ failActionCallback(ap, params, verdict.errMsg);
7259
+ return;
7260
+ }
7261
+ }
6916
7262
  const payload = {
6917
7263
  appSessionId: ap.appSessionId,
6918
7264
  bridgeId: page.bridgeId,
@@ -6974,7 +7320,7 @@ async function handleSimulatorApi(state, ap, page, body, ctx) {
6974
7320
  return;
6975
7321
  }
6976
7322
  if (NAV_ACTION_NAMES.has(name)) {
6977
- handleNavActionApi(ap, page, name, params);
7323
+ handleNavActionApi(ap, ctx, page, name, params);
6978
7324
  return;
6979
7325
  }
6980
7326
  if (TAB_ACTION_NAMES.has(name)) {
@@ -7016,7 +7362,7 @@ function forwardApiCallToSimulator(state, ap, page, name, params) {
7016
7362
  const fail = { errMsg: `${pending.name}:fail no handler (timeout)` };
7017
7363
  sendCallback(target, pending.callbacks.fail, fail);
7018
7364
  sendCallback(target, pending.callbacks.complete, fail);
7019
- }, API_CALL_TIMEOUT_MS);
7365
+ }, apiCallWatchdogMs(name, params));
7020
7366
  state.pendingApiCalls.set(requestId, {
7021
7367
  appSessionId: ap.appSessionId,
7022
7368
  callbacks,
@@ -7065,7 +7411,12 @@ function handleApiResponse(state, sender, payload) {
7065
7411
  sendCallback(ap, pending.callbacks.success, payload.result);
7066
7412
  sendCallback(ap, pending.callbacks.complete, payload.result ?? { errMsg: `${pending.name}:ok` });
7067
7413
  } else {
7068
- const fail = { errMsg: payload.errMsg ?? `${pending.name}:fail` };
7414
+ const result = payload.result && typeof payload.result === "object" && !Array.isArray(payload.result) ? payload.result : void 0;
7415
+ const resultErrMsg = typeof result?.errMsg === "string" ? result.errMsg : void 0;
7416
+ const fail = {
7417
+ ...result,
7418
+ errMsg: payload.errMsg || resultErrMsg || `${pending.name}:fail`
7419
+ };
7069
7420
  sendCallback(ap, pending.callbacks.fail, fail);
7070
7421
  sendCallback(ap, pending.callbacks.complete, fail);
7071
7422
  }
@@ -7259,6 +7610,7 @@ async function disposeAppSession(state, appSessionId, opts = {}) {
7259
7610
  const ap = state.appSessions.get(appSessionId);
7260
7611
  if (!ap) return;
7261
7612
  state.appSessions.delete(appSessionId);
7613
+ clearLaunchTimer(ap);
7262
7614
  const registryHandle = ap.registryHandle;
7263
7615
  ap.registryHandle = null;
7264
7616
  void registryHandle?.dispose();
@@ -7276,25 +7628,45 @@ async function disposeAppSession(state, appSessionId, opts = {}) {
7276
7628
  });
7277
7629
  }
7278
7630
  }
7279
- async function loadAppConfig(resourceBase) {
7631
+ async function loadAppConfig(resourceBase, onUnreachable) {
7280
7632
  const cfgUrl = new URL("app-config.json", resourceBase.endsWith("/") ? resourceBase : `${resourceBase}/`).toString();
7281
7633
  try {
7282
7634
  const res = await fetch(cfgUrl);
7283
7635
  if (!res.ok) {
7636
+ const error = new Error(`app-config.json fetch ${res.status} at ${cfgUrl}`);
7284
7637
  console.warn(`[bridge-router] no app-config.json at ${cfgUrl} (${res.status})`);
7638
+ onUnreachable?.({ url: cfgUrl, error });
7285
7639
  return {};
7286
7640
  }
7287
7641
  return await res.json();
7288
7642
  } catch (error) {
7289
7643
  console.warn("[bridge-router] failed to fetch/parse app-config.json:", error);
7644
+ onUnreachable?.({ url: cfgUrl, error });
7290
7645
  return {};
7291
7646
  }
7292
7647
  }
7293
7648
  function buildAppManifest(appConfig, fallbackEntry) {
7294
7649
  const entry = appConfig.app?.entryPagePath || fallbackEntry;
7295
- const pages = appConfig.app?.pages?.length ? appConfig.app.pages : [entry];
7650
+ const hasCompiledPages = !!appConfig.app?.pages?.length;
7651
+ const pages = hasCompiledPages ? appConfig.app.pages : [entry];
7296
7652
  const tabBar = appConfig.app?.tabBar && Array.isArray(appConfig.app.tabBar.list) && appConfig.app.tabBar.list.length > 0 ? appConfig.app.tabBar : void 0;
7297
- return { entryPagePath: normalizePagePath(entry), pages: pages.map(normalizePagePath), tabBar };
7653
+ return {
7654
+ entryPagePath: normalizePagePath(entry),
7655
+ pages: pages.map(normalizePagePath),
7656
+ tabBar,
7657
+ // 'app-config' means `pages` above is the real compiled list mount gates
7658
+ // can trust; 'fallback' means app-config.json was unreachable and `pages`
7659
+ // is just the single requested page — nothing to validate membership
7660
+ // against, so every gate keyed on this source lets it through unchanged.
7661
+ source: hasCompiledPages ? "app-config" : "fallback"
7662
+ };
7663
+ }
7664
+ function resolveRootPagePath(manifest, requestedPagePath) {
7665
+ if (manifest.source !== "app-config" || manifest.pages.includes(requestedPagePath)) {
7666
+ return { resolvedPagePath: requestedPagePath, pageFallbackApplied: false };
7667
+ }
7668
+ const resolvedPagePath = manifest.pages.includes(manifest.entryPagePath) ? manifest.entryPagePath : manifest.pages[0];
7669
+ return { resolvedPagePath, pageFallbackApplied: true };
7298
7670
  }
7299
7671
  function resolvePageWindowConfig(appConfig, pagePath) {
7300
7672
  const normalized = normalizePagePath(pagePath);
@@ -8971,6 +9343,7 @@ function createNetworkForwarder(bridge) {
8971
9343
  let sink = "idle";
8972
9344
  let probeConsoleBuffer = [];
8973
9345
  let readyTimeoutTimer = null;
9346
+ let probeDeadline = null;
8974
9347
  let dispatchQueue = [];
8975
9348
  let flushScheduled = false;
8976
9349
  let readyRetryTimer = null;
@@ -8981,6 +9354,7 @@ function createNetworkForwarder(bridge) {
8981
9354
  function beginProbing() {
8982
9355
  if (sink === "probing") return;
8983
9356
  sink = "probing";
9357
+ probeDeadline = Date.now() + DEVTOOLS_READY_TIMEOUT_MS;
8984
9358
  if (readyTimeoutTimer) clearTimeout(readyTimeoutTimer);
8985
9359
  readyTimeoutTimer = setTimeout(() => {
8986
9360
  readyTimeoutTimer = null;
@@ -8989,6 +9363,7 @@ function createNetworkForwarder(bridge) {
8989
9363
  }
8990
9364
  function markReady() {
8991
9365
  sink = "ready";
9366
+ probeDeadline = null;
8992
9367
  if (readyTimeoutTimer) {
8993
9368
  clearTimeout(readyTimeoutTimer);
8994
9369
  readyTimeoutTimer = null;
@@ -9001,6 +9376,7 @@ function createNetworkForwarder(bridge) {
9001
9376
  }
9002
9377
  function degradeToConsole() {
9003
9378
  sink = "degraded";
9379
+ probeDeadline = null;
9004
9380
  dispatchQueue = [];
9005
9381
  if (readyTimeoutTimer) {
9006
9382
  clearTimeout(readyTimeoutTimer);
@@ -9105,9 +9481,17 @@ function createNetworkForwarder(bridge) {
9105
9481
  }
9106
9482
  function scheduleReadyRetry() {
9107
9483
  if (readyRetryTimer || sink === "ready" || sink === "degraded") return;
9484
+ if (probeDeadline !== null && Date.now() >= probeDeadline) {
9485
+ degradeToConsole();
9486
+ return;
9487
+ }
9108
9488
  readyRetryTimer = setTimeout(() => {
9109
9489
  readyRetryTimer = null;
9110
9490
  if (sink === "degraded") return;
9491
+ if (probeDeadline !== null && Date.now() >= probeDeadline) {
9492
+ degradeToConsole();
9493
+ return;
9494
+ }
9111
9495
  if (dispatchQueue.length > 0) scheduleFlush();
9112
9496
  }, READY_RETRY_MS);
9113
9497
  }
@@ -9146,6 +9530,7 @@ function createNetworkForwarder(bridge) {
9146
9530
  dispatchQueue = [];
9147
9531
  probeConsoleBuffer = [];
9148
9532
  sink = "idle";
9533
+ probeDeadline = null;
9149
9534
  if (readyRetryTimer) {
9150
9535
  clearTimeout(readyRetryTimer);
9151
9536
  readyRetryTimer = null;
@@ -9296,6 +9681,7 @@ function createNetworkForwarder(bridge) {
9296
9681
  clearTimeout(readyRetryTimer);
9297
9682
  readyRetryTimer = null;
9298
9683
  }
9684
+ probeDeadline = null;
9299
9685
  probeConsoleBuffer = [];
9300
9686
  if (!devtoolsWc) {
9301
9687
  sink = "idle";
@@ -9319,6 +9705,7 @@ function createNetworkForwarder(bridge) {
9319
9705
  }
9320
9706
  });
9321
9707
  }
9708
+ sink = "idle";
9322
9709
  beginProbing();
9323
9710
  if (dispatchQueue.length > 0) scheduleFlush();
9324
9711
  }
@@ -10388,6 +10775,11 @@ function setupSimulatorTempFiles(simSession) {
10388
10775
  // src/main/services/views/simulator-session-policy.ts
10389
10776
  import { session as session3 } from "electron";
10390
10777
  import { toDisposable as toDisposable7 } from "@dimina-kit/electron-deck/main";
10778
+ var CORS_OVERRIDE_HEADERS = /* @__PURE__ */ new Set([
10779
+ "access-control-allow-origin",
10780
+ "access-control-allow-headers",
10781
+ "access-control-allow-methods"
10782
+ ]);
10391
10783
  function applySimulatorWebRequestPolicy(simulatorSession) {
10392
10784
  simulatorSession.webRequest.onBeforeSendHeaders((details, callback) => {
10393
10785
  const forcedReferer = getSimulatorServicewechatReferer();
@@ -10398,6 +10790,9 @@ function applySimulatorWebRequestPolicy(simulatorSession) {
10398
10790
  });
10399
10791
  simulatorSession.webRequest.onHeadersReceived((details, callback) => {
10400
10792
  const headers = details.responseHeaders ?? {};
10793
+ for (const key of Object.keys(headers)) {
10794
+ if (CORS_OVERRIDE_HEADERS.has(key.toLowerCase())) delete headers[key];
10795
+ }
10401
10796
  headers["access-control-allow-origin"] = ["*"];
10402
10797
  headers["access-control-allow-headers"] = ["*"];
10403
10798
  headers["access-control-allow-methods"] = ["*"];
@@ -11033,6 +11428,7 @@ async function createDevtoolsRuntime(config = {}) {
11033
11428
  context.registry.add(registerProjectFsIpc(context));
11034
11429
  context.registry.add(setupSimulatorSessionPolicy());
11035
11430
  context.registry.add(installThemeBackgroundSync());
11431
+ if (!config.adapter) context.registry.add(setupCompileWorkerStandby(context));
11036
11432
  registerBuiltinModules(config, context);
11037
11433
  const simSession = session4.fromPartition(SHARED_MINIAPP_PARTITION);
11038
11434
  context.registry.add(setupSimulatorTempFiles(simSession));