@dimina-kit/devtools 0.3.1-dev.20260518114324 → 0.3.2-dev.20260522085907

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 (89) hide show
  1. package/README.md +33 -71
  2. package/dist/main/app/app.js +5 -0
  3. package/dist/main/app/bootstrap.js +2 -1
  4. package/dist/main/app/launch.d.ts +1 -1
  5. package/dist/main/app/launch.js +6 -7
  6. package/dist/main/index.bundle.js +306 -317
  7. package/dist/main/ipc/panels.js +3 -5
  8. package/dist/main/ipc/projects.d.ts +1 -1
  9. package/dist/main/ipc/projects.js +5 -5
  10. package/dist/main/ipc/settings.d.ts +1 -1
  11. package/dist/main/ipc/settings.js +14 -1
  12. package/dist/main/ipc/simulator.d.ts +1 -1
  13. package/dist/main/ipc/simulator.js +1 -10
  14. package/dist/main/services/automation/exec.d.ts +2 -0
  15. package/dist/main/services/automation/exec.js +7 -9
  16. package/dist/main/services/automation/handlers/app.js +37 -51
  17. package/dist/main/services/automation/handlers/element.js +27 -41
  18. package/dist/main/services/default-adapter.js +3 -3
  19. package/dist/main/services/mcp/index.d.ts +1 -0
  20. package/dist/main/services/mcp/index.js +1 -0
  21. package/dist/main/services/mcp/server.js +5 -0
  22. package/dist/main/services/mcp/status.d.ts +10 -0
  23. package/dist/main/services/mcp/status.js +14 -0
  24. package/dist/main/services/mcp/target-manager.js +2 -1
  25. package/dist/main/services/notifications/renderer-notifier.d.ts +3 -3
  26. package/dist/main/services/notifications/renderer-notifier.js +3 -6
  27. package/dist/main/services/projects/local-provider.js +3 -3
  28. package/dist/main/services/projects/project-repository.d.ts +0 -1
  29. package/dist/main/services/settings/index.js +2 -1
  30. package/dist/main/services/simulator-storage/index.js +47 -77
  31. package/dist/main/services/views/view-manager.d.ts +3 -7
  32. package/dist/main/services/views/view-manager.js +20 -27
  33. package/dist/main/services/window-service.d.ts +3 -3
  34. package/dist/main/services/workbench-context.d.ts +3 -6
  35. package/dist/main/services/workbench-context.js +1 -3
  36. package/dist/main/services/workspace/workspace-service.js +8 -24
  37. package/dist/main/utils/theme.d.ts +24 -0
  38. package/dist/main/utils/theme.js +38 -1
  39. package/dist/preload/index.d.ts +5 -2
  40. package/dist/preload/index.js +3 -2
  41. package/dist/preload/instrumentation/app-data.d.ts +32 -2
  42. package/dist/preload/instrumentation/app-data.js +187 -172
  43. package/dist/preload/instrumentation/index.d.ts +2 -2
  44. package/dist/preload/instrumentation/index.js +2 -2
  45. package/dist/preload/instrumentation/wxml.d.ts +16 -4
  46. package/dist/preload/instrumentation/wxml.js +188 -178
  47. package/dist/preload/miniapp-snapshot/host.d.ts +12 -0
  48. package/dist/preload/miniapp-snapshot/host.js +117 -0
  49. package/dist/preload/miniapp-snapshot/types.d.ts +62 -0
  50. package/dist/preload/miniapp-snapshot/types.js +15 -0
  51. package/dist/preload/runtime/bridge.js +5 -24
  52. package/dist/preload/runtime/custom-apis.d.ts +1 -1
  53. package/dist/preload/runtime/custom-apis.js +3 -7
  54. package/dist/preload/shared/expose.d.ts +15 -0
  55. package/dist/preload/shared/expose.js +33 -0
  56. package/dist/preload/shared/page-iframe.d.ts +3 -0
  57. package/dist/preload/shared/page-iframe.js +6 -0
  58. package/dist/preload/shared/types.d.ts +2 -0
  59. package/dist/preload/windows/simulator.js +400 -348
  60. package/dist/renderer/assets/constants-DI382mTP.js +2 -0
  61. package/dist/renderer/assets/index-D8VFYBh-.js +46 -0
  62. package/dist/renderer/assets/{input-DqVQNCx_.js → input-CoWcfa8u.js} +2 -2
  63. package/dist/renderer/assets/ipc-transport-Cd2xPrsa.js +9 -0
  64. package/dist/renderer/assets/popover-Nq5gT9DO.js +2 -0
  65. package/dist/renderer/assets/select-By5KH-UG.js +2 -0
  66. package/dist/renderer/assets/{settings-BFNfnYvU.js → settings-Dj_N70qR.js} +2 -2
  67. package/dist/renderer/assets/settings-api-Do0_Smq1.js +2 -0
  68. package/dist/renderer/assets/workbenchSettings-CazSLGYt.js +8 -0
  69. package/dist/renderer/entries/main/index.html +5 -4
  70. package/dist/renderer/entries/popover/index.html +5 -4
  71. package/dist/renderer/entries/settings/index.html +4 -4
  72. package/dist/renderer/entries/workbench-settings/index.html +4 -3
  73. package/dist/shared/ipc-channels.d.ts +4 -12
  74. package/dist/shared/ipc-channels.js +10 -14
  75. package/dist/shared/simulator-route.d.ts +72 -0
  76. package/dist/shared/simulator-route.js +169 -0
  77. package/dist/shared/types.d.ts +2 -10
  78. package/dist/simulator/assets/simulator-DJCozrU5.js +9 -0
  79. package/dist/simulator/simulator.html +6 -43
  80. package/package.json +4 -4
  81. package/dist/preload/instrumentation/disposable.d.ts +0 -11
  82. package/dist/preload/instrumentation/disposable.js +0 -15
  83. package/dist/renderer/assets/index-Czz_bp6b.js +0 -46
  84. package/dist/renderer/assets/ipc-transport-CCHrCtDr.js +0 -9
  85. package/dist/renderer/assets/popover-BRg4XI_w.js +0 -2
  86. package/dist/renderer/assets/select-CvILHHZU.js +0 -2
  87. package/dist/renderer/assets/settings-api-DOAgmBst.js +0 -2
  88. package/dist/renderer/assets/workbenchSettings-DjVMgMMH.js +0 -8
  89. package/dist/simulator/assets/simulator-DL6kOCq-.js +0 -9
@@ -1,7 +1,30 @@
1
1
  "use strict";
2
2
 
3
- // src/preload/runtime/bridge.ts
3
+ // src/preload/shared/expose.ts
4
4
  var import_electron = require("electron");
5
+ function exposeOnMainWorld(key, value) {
6
+ let fellBack = false;
7
+ try {
8
+ import_electron.contextBridge.exposeInMainWorld(key, value);
9
+ } catch {
10
+ ;
11
+ window[key] = value;
12
+ fellBack = true;
13
+ }
14
+ return () => {
15
+ if (!fellBack) return;
16
+ const w = window;
17
+ if (w[key] === value) delete w[key];
18
+ };
19
+ }
20
+
21
+ // src/preload/shared/page-iframe.ts
22
+ function getActivePageIframe() {
23
+ const iframes = document.querySelectorAll(".dimina-native-webview__window");
24
+ return iframes.length > 0 ? iframes[iframes.length - 1] : null;
25
+ }
26
+
27
+ // src/preload/runtime/bridge.ts
5
28
  var state = {
6
29
  appdata: { gen: 0, ready: true, data: {} },
7
30
  storage: { gen: 0, ready: false, namespace: null, data: {} },
@@ -43,10 +66,6 @@ function clone(value) {
43
66
  return value;
44
67
  }
45
68
  }
46
- function getPageIframe() {
47
- const iframes = document.querySelectorAll(".dimina-native-webview__window");
48
- return iframes.length > 0 ? iframes[iframes.length - 1] : null;
49
- }
50
69
  function ensureOverlay(doc) {
51
70
  if (highlightOverlay && highlightOverlay.ownerDocument === doc) return highlightOverlay;
52
71
  highlightOverlay = doc.createElement("div");
@@ -57,7 +76,7 @@ function ensureOverlay(doc) {
57
76
  }
58
77
  function highlightElement(sid) {
59
78
  if (!sid) return null;
60
- const iframe = getPageIframe();
79
+ const iframe = getActivePageIframe();
61
80
  if (!iframe?.contentDocument) return null;
62
81
  const doc = iframe.contentDocument;
63
82
  const el = findElementBySid(doc, sid);
@@ -151,25 +170,10 @@ function installSimulatorBridge() {
151
170
  if (!exposedApi) {
152
171
  exposedApi = buildApi();
153
172
  }
154
- try {
155
- import_electron.contextBridge.exposeInMainWorld("__simulatorData", {
156
- ...exposedApi,
157
- getAppdata: () => clone(state.appdata.data),
158
- getAppdataSnapshot: () => clone(state.appdata),
159
- getStorageSnapshot: () => clone(state.storage),
160
- getWxml: () => clone(state.wxml.data),
161
- getWxmlSnapshot: () => clone(state.wxml)
162
- });
163
- } catch {
164
- ;
165
- window.__simulatorData = exposedApi;
166
- }
173
+ const dispose = exposeOnMainWorld("__simulatorData", exposedApi);
167
174
  return () => {
168
175
  resetBridgeState();
169
- const windowRef = window;
170
- if (windowRef.__simulatorData === exposedApi) {
171
- delete windowRef.__simulatorData;
172
- }
176
+ dispose();
173
177
  };
174
178
  }
175
179
 
@@ -182,19 +186,15 @@ var SimulatorChannel = {
182
186
  Detach: "simulator:detach",
183
187
  Resize: "simulator:resize",
184
188
  SetVisible: "simulator:setVisible",
185
- Console: "simulator:console",
186
- Wxml: "simulator:wxml",
187
- AppData: "simulator:appdata",
188
- AppDataAll: "simulator:appdata-all"
189
+ Console: "simulator:console"
189
190
  };
190
191
  var SimulatorCustomApiBridgeChannel = {
191
192
  Request: "simulator:custom-apis:bridge-request",
192
193
  Response: "simulator:custom-apis:bridge-response"
193
194
  };
194
- var BridgeChannel = {
195
- WxmlRefreshRequest: "wxml:refresh:request",
196
- AppDataGetAllRequest: "appdata:getAll:request",
197
- AppDataGetAllResponse: "appdata:getAll:response"
195
+ var MiniappSnapshotChannel = {
196
+ Push: "miniapp-snapshot:push",
197
+ Pull: "miniapp-snapshot:pull"
198
198
  };
199
199
 
200
200
  // src/preload/runtime/custom-apis.ts
@@ -227,11 +227,7 @@ function buildBridge() {
227
227
  }
228
228
  function installCustomApisBridge() {
229
229
  const bridge = buildBridge();
230
- try {
231
- import_electron2.contextBridge.exposeInMainWorld("__diminaCustomApis", bridge);
232
- } catch {
233
- window.__diminaCustomApis = bridge;
234
- }
230
+ return exposeOnMainWorld("__diminaCustomApis", bridge);
235
231
  }
236
232
 
237
233
  // src/preload/runtime/host.ts
@@ -319,60 +315,7 @@ function installConsoleInstrumentation() {
319
315
  };
320
316
  }
321
317
 
322
- // src/preload/instrumentation/disposable.ts
323
- function createDisposableSet() {
324
- const disposables2 = [];
325
- return {
326
- add: (fn) => disposables2.push(fn),
327
- disposeAll: () => {
328
- disposables2.forEach((fn) => fn());
329
- disposables2.length = 0;
330
- }
331
- };
332
- }
333
-
334
318
  // src/preload/instrumentation/app-data.ts
335
- var appDataCache = /* @__PURE__ */ new Map();
336
- var bridgeOrder = [];
337
- var bridgePagePath = /* @__PURE__ */ new Map();
338
- function recordBridge(bridgeId) {
339
- if (!bridgeOrder.includes(bridgeId)) bridgeOrder.push(bridgeId);
340
- }
341
- function buildSnapshot() {
342
- const bridges = [];
343
- for (const id of bridgeOrder) {
344
- bridges.push({ id, pagePath: bridgePagePath.get(id) ?? null });
345
- }
346
- const entries = {};
347
- for (const [key, entry] of appDataCache) {
348
- const slash = key.indexOf("/");
349
- if (slash < 0) continue;
350
- const bridgeId = key.slice(0, slash);
351
- const moduleId = key.slice(slash + 1);
352
- if (!entries[bridgeId]) entries[bridgeId] = {};
353
- const displayKey = entry.componentPath ?? moduleId;
354
- entries[bridgeId][displayKey] = entry.data;
355
- }
356
- return { bridges, entries };
357
- }
358
- function publishSnapshot() {
359
- const data = {};
360
- for (const [key, entry] of appDataCache) {
361
- data[key] = entry.data;
362
- }
363
- setAppDataSnapshot(data);
364
- }
365
- function clearBridge(bridgeId) {
366
- const prefix = `${bridgeId}/`;
367
- for (const key of [...appDataCache.keys()]) {
368
- if (key.startsWith(prefix)) appDataCache.delete(key);
369
- }
370
- const idx = bridgeOrder.indexOf(bridgeId);
371
- if (idx >= 0) bridgeOrder.splice(idx, 1);
372
- bridgePagePath.delete(bridgeId);
373
- publishSnapshot();
374
- sendToHost(SimulatorChannel.AppDataAll, buildSnapshot());
375
- }
376
319
  function decodeWorkerMessage(message) {
377
320
  let payload = message;
378
321
  if (typeof payload === "string") {
@@ -428,116 +371,155 @@ function decodeOutgoingMessage(message) {
428
371
  bridgeId: typeof r.body?.bridgeId === "string" ? r.body.bridgeId : void 0
429
372
  };
430
373
  }
431
- function instrumentPostMessage(worker) {
432
- const orig = worker.postMessage.bind(worker);
433
- worker.postMessage = function(msg, ...rest) {
434
- const decoded = decodeOutgoingMessage(msg);
435
- if (decoded?.type === "pageUnload" && decoded.bridgeId) {
436
- clearBridge(decoded.bridgeId);
374
+ function createAppDataSource() {
375
+ const appDataCache = /* @__PURE__ */ new Map();
376
+ const bridgeOrder = [];
377
+ const bridgePagePath = /* @__PURE__ */ new Map();
378
+ let emit = null;
379
+ let installed = false;
380
+ let originalHook;
381
+ let originalDescriptor;
382
+ let OriginalWorker;
383
+ function recordBridge(bridgeId) {
384
+ if (!bridgeOrder.includes(bridgeId)) bridgeOrder.push(bridgeId);
385
+ }
386
+ function buildSnapshot() {
387
+ const bridges = [];
388
+ for (const id of bridgeOrder) {
389
+ bridges.push({ id, pagePath: bridgePagePath.get(id) ?? null });
437
390
  }
438
- return orig(msg, ...rest);
439
- };
440
- }
441
- function createInstrumentedWorker(OriginalWorker) {
442
- function InstrumentedWorker(scriptURL, options) {
443
- const resolvedScriptURL = scriptURL instanceof URL ? scriptURL : new URL(scriptURL, window.location.href);
444
- const worker = Reflect.construct(
445
- OriginalWorker,
446
- [resolvedScriptURL, options],
447
- new.target ?? InstrumentedWorker
448
- );
449
- instrumentPostMessage(worker);
450
- worker.addEventListener("message", (event) => {
451
- const entries = decodeWorkerMessage(event.data);
452
- if (!entries) return;
453
- for (const entry of entries) {
454
- const hookBody = {
455
- bridgeId: entry.bridgeId,
456
- moduleId: entry.moduleId,
457
- data: entry.data,
458
- mode: entry.mode
459
- };
460
- if (entry.mode === "init") hookBody.componentPath = entry.componentPath;
461
- window.__simulatorHook?.appData(hookBody);
462
- }
463
- });
464
- return worker;
391
+ const entries = {};
392
+ for (const [key, entry] of appDataCache) {
393
+ const slash = key.indexOf("/");
394
+ if (slash < 0) continue;
395
+ const bridgeId = key.slice(0, slash);
396
+ const moduleId = key.slice(slash + 1);
397
+ if (!entries[bridgeId]) entries[bridgeId] = {};
398
+ const displayKey = entry.componentPath ?? moduleId;
399
+ entries[bridgeId][displayKey] = entry.data;
400
+ }
401
+ return { bridges, entries };
465
402
  }
466
- Object.setPrototypeOf(InstrumentedWorker, OriginalWorker);
467
- Object.defineProperty(InstrumentedWorker, "prototype", {
468
- value: OriginalWorker.prototype
469
- });
470
- return InstrumentedWorker;
471
- }
472
- function installAppDataInstrumentation() {
473
- const disposables2 = createDisposableSet();
474
- const originalHook = window.__simulatorHook;
475
- const originalDescriptor = Object.getOwnPropertyDescriptor(window, "Worker");
476
- const OriginalWorker = window.Worker;
477
- window.__simulatorHook = {
478
- appData: (body) => {
479
- const record = body;
480
- if (!record?.bridgeId || !record?.moduleId) return;
481
- if (record.mode !== "init" && !bridgePagePath.has(record.bridgeId)) return;
482
- const key = `${record.bridgeId}/${record.moduleId}`;
483
- const prev = appDataCache.get(key);
484
- const incoming = record.data && typeof record.data === "object" ? record.data : {};
485
- const merged = record.mode === "init" ? { ...incoming } : { ...prev?.data ?? {}, ...incoming };
486
- const componentPath = record.componentPath ?? prev?.componentPath;
487
- const next = componentPath !== void 0 ? { componentPath, data: merged } : { data: merged };
488
- appDataCache.set(key, next);
489
- recordBridge(record.bridgeId);
490
- if (record.mode === "init" && record.moduleId.startsWith("page_") && record.componentPath) {
491
- bridgePagePath.set(record.bridgeId, record.componentPath);
492
- }
493
- publishSnapshot();
494
- const payload = {
495
- bridgeId: record.bridgeId,
496
- moduleId: record.moduleId,
497
- data: merged
498
- };
499
- if (componentPath !== void 0) payload.componentPath = componentPath;
500
- sendToHost(SimulatorChannel.AppData, payload);
403
+ function publishSnapshot() {
404
+ const data = {};
405
+ for (const [key, entry] of appDataCache) {
406
+ data[key] = entry.data;
501
407
  }
502
- };
503
- Object.defineProperty(window, "Worker", {
504
- configurable: true,
505
- writable: true,
506
- value: createInstrumentedWorker(OriginalWorker)
507
- });
508
- disposables2.add(
509
- onHostMessage(BridgeChannel.AppDataGetAllRequest, () => sendAllAppData())
510
- );
511
- publishSnapshot();
512
- disposables2.add(() => {
513
- if (originalDescriptor) {
514
- Object.defineProperty(window, "Worker", originalDescriptor);
515
- } else {
516
- window.Worker = OriginalWorker;
408
+ setAppDataSnapshot(data);
409
+ }
410
+ function clearBridge(bridgeId) {
411
+ const prefix = `${bridgeId}/`;
412
+ for (const key of [...appDataCache.keys()]) {
413
+ if (key.startsWith(prefix)) appDataCache.delete(key);
517
414
  }
518
- });
519
- disposables2.add(() => {
520
- if (originalHook) {
521
- window.__simulatorHook = originalHook;
522
- } else {
523
- delete window.__simulatorHook;
415
+ const idx = bridgeOrder.indexOf(bridgeId);
416
+ if (idx >= 0) bridgeOrder.splice(idx, 1);
417
+ bridgePagePath.delete(bridgeId);
418
+ publishSnapshot();
419
+ emit?.();
420
+ }
421
+ function applyAppData(body) {
422
+ const record = body;
423
+ if (!record?.bridgeId || !record?.moduleId) return;
424
+ if (record.mode !== "init" && !bridgePagePath.has(record.bridgeId)) return;
425
+ const key = `${record.bridgeId}/${record.moduleId}`;
426
+ const prev = appDataCache.get(key);
427
+ const incoming = record.data && typeof record.data === "object" ? record.data : {};
428
+ const merged = record.mode === "init" ? { ...incoming } : { ...prev?.data ?? {}, ...incoming };
429
+ const componentPath = record.componentPath ?? prev?.componentPath;
430
+ const next = componentPath !== void 0 ? { componentPath, data: merged } : { data: merged };
431
+ appDataCache.set(key, next);
432
+ recordBridge(record.bridgeId);
433
+ if (record.mode === "init" && record.moduleId.startsWith("page_") && record.componentPath) {
434
+ bridgePagePath.set(record.bridgeId, record.componentPath);
524
435
  }
525
- });
526
- disposables2.add(() => {
527
- appDataCache.clear();
528
- bridgeOrder.length = 0;
529
- bridgePagePath.clear();
530
- clearAppDataSnapshot();
531
436
  publishSnapshot();
532
- });
533
- return () => {
534
- disposables2.disposeAll();
437
+ emit?.();
438
+ }
439
+ function instrumentPostMessage(worker) {
440
+ const orig = worker.postMessage.bind(worker);
441
+ worker.postMessage = function(msg, ...rest) {
442
+ const decoded = decodeOutgoingMessage(msg);
443
+ if (decoded?.type === "pageUnload" && decoded.bridgeId) {
444
+ clearBridge(decoded.bridgeId);
445
+ }
446
+ return orig(msg, ...rest);
447
+ };
448
+ }
449
+ function createInstrumentedWorker(Original) {
450
+ function InstrumentedWorker(scriptURL, options) {
451
+ const resolvedScriptURL = scriptURL instanceof URL ? scriptURL : new URL(scriptURL, window.location.href);
452
+ const worker = Reflect.construct(
453
+ Original,
454
+ [resolvedScriptURL, options],
455
+ new.target ?? InstrumentedWorker
456
+ );
457
+ instrumentPostMessage(worker);
458
+ worker.addEventListener("message", (event) => {
459
+ const entries = decodeWorkerMessage(event.data);
460
+ if (!entries) return;
461
+ for (const entry of entries) {
462
+ const hookBody = {
463
+ bridgeId: entry.bridgeId,
464
+ moduleId: entry.moduleId,
465
+ data: entry.data,
466
+ mode: entry.mode
467
+ };
468
+ if (entry.mode === "init") hookBody.componentPath = entry.componentPath;
469
+ window.__simulatorHook?.appData(hookBody);
470
+ }
471
+ });
472
+ return worker;
473
+ }
474
+ Object.setPrototypeOf(InstrumentedWorker, Original);
475
+ Object.defineProperty(InstrumentedWorker, "prototype", {
476
+ value: Original.prototype
477
+ });
478
+ return InstrumentedWorker;
479
+ }
480
+ return {
481
+ id: "appdata",
482
+ snapshot: () => buildSnapshot(),
483
+ start(onChange) {
484
+ if (installed) return;
485
+ installed = true;
486
+ emit = onChange;
487
+ originalHook = window.__simulatorHook;
488
+ originalDescriptor = Object.getOwnPropertyDescriptor(window, "Worker");
489
+ OriginalWorker = window.Worker;
490
+ window.__simulatorHook = {
491
+ appData: (body) => applyAppData(body)
492
+ };
493
+ Object.defineProperty(window, "Worker", {
494
+ configurable: true,
495
+ writable: true,
496
+ value: createInstrumentedWorker(OriginalWorker)
497
+ });
498
+ },
499
+ dispose() {
500
+ if (!installed) return;
501
+ installed = false;
502
+ if (originalDescriptor) {
503
+ Object.defineProperty(window, "Worker", originalDescriptor);
504
+ } else if (OriginalWorker) {
505
+ window.Worker = OriginalWorker;
506
+ }
507
+ if (originalHook) {
508
+ window.__simulatorHook = originalHook;
509
+ } else {
510
+ delete window.__simulatorHook;
511
+ }
512
+ originalDescriptor = void 0;
513
+ OriginalWorker = void 0;
514
+ originalHook = void 0;
515
+ appDataCache.clear();
516
+ bridgeOrder.length = 0;
517
+ bridgePagePath.clear();
518
+ clearAppDataSnapshot();
519
+ emit = null;
520
+ }
535
521
  };
536
522
  }
537
- function sendAllAppData() {
538
- publishSnapshot();
539
- sendToHost(SimulatorChannel.AppDataAll, buildSnapshot());
540
- }
541
523
 
542
524
  // src/preload/shared/constants.ts
543
525
  var WXML_DEBOUNCE_MS = 300;
@@ -746,10 +728,6 @@ function walkInstance(instance, depth) {
746
728
  }
747
729
 
748
730
  // src/preload/instrumentation/wxml.ts
749
- function findActivePageIframe() {
750
- const iframes = document.querySelectorAll(".dimina-native-webview__window");
751
- return iframes.length > 0 ? iframes[iframes.length - 1] : null;
752
- }
753
731
  function getVueAppFromIframe(iframe) {
754
732
  try {
755
733
  const doc = iframe.contentDocument;
@@ -765,181 +743,253 @@ function getVueAppFromIframe(iframe) {
765
743
  return null;
766
744
  }
767
745
  }
768
- var wxmlTimer;
769
- var currentObserver = null;
770
- var currentIframe = null;
771
- var topObserver = null;
772
- var retryTimer;
773
- var retryTimeout;
774
- var navigationWaitTimer;
775
- var navigationWaitTimeout;
776
- var disposables = createDisposableSet();
777
- function clearTimers() {
778
- if (wxmlTimer) clearTimeout(wxmlTimer);
779
- if (retryTimer) clearInterval(retryTimer);
780
- if (retryTimeout) clearTimeout(retryTimeout);
781
- if (navigationWaitTimer) clearInterval(navigationWaitTimer);
782
- if (navigationWaitTimeout) clearTimeout(navigationWaitTimeout);
783
- wxmlTimer = void 0;
784
- retryTimer = void 0;
785
- retryTimeout = void 0;
786
- navigationWaitTimer = void 0;
787
- navigationWaitTimeout = void 0;
788
- }
789
- function publishTree(tree) {
790
- if (tree) {
791
- const normalized = Array.isArray(tree) ? { tagName: "#fragment", attrs: {}, children: tree } : tree;
792
- setWxmlSnapshot(normalized, true);
793
- sendToHost(SimulatorChannel.Wxml, normalized);
794
- return;
795
- }
796
- clearWxmlSnapshot();
797
- unhighlightElement();
798
- }
799
- function sendWxmlTree() {
800
- const iframe = findActivePageIframe();
801
- if (!iframe) {
802
- publishTree(null);
803
- return;
804
- }
746
+ function computeWxmlTree() {
747
+ const iframe = getActivePageIframe();
748
+ if (!iframe) return null;
805
749
  const instance = getVueAppFromIframe(iframe);
806
- if (!instance) {
807
- publishTree(null);
808
- return;
809
- }
750
+ if (!instance) return null;
810
751
  const tree = walkInstance(instance, 0);
811
- if (!tree) {
812
- publishTree(null);
813
- return;
814
- }
815
- publishTree(tree);
752
+ if (!tree) return null;
753
+ return Array.isArray(tree) ? { tagName: "#fragment", attrs: {}, children: tree } : tree;
816
754
  }
817
- function observeIframe(iframe) {
818
- if (iframe === currentIframe) return;
819
- if (currentObserver) {
820
- currentObserver.disconnect();
821
- currentObserver = null;
822
- }
823
- if (navigationWaitTimer) {
824
- clearInterval(navigationWaitTimer);
755
+ function createWxmlSource() {
756
+ let tree = null;
757
+ let emit = null;
758
+ let wxmlTimer;
759
+ let currentObserver = null;
760
+ let currentIframe = null;
761
+ let topObserver = null;
762
+ let retryTimer;
763
+ let retryTimeout;
764
+ let navigationWaitTimer;
765
+ let navigationWaitTimeout;
766
+ function clearTimers() {
767
+ if (wxmlTimer) clearTimeout(wxmlTimer);
768
+ if (retryTimer) clearInterval(retryTimer);
769
+ if (retryTimeout) clearTimeout(retryTimeout);
770
+ if (navigationWaitTimer) clearInterval(navigationWaitTimer);
771
+ if (navigationWaitTimeout) clearTimeout(navigationWaitTimeout);
772
+ wxmlTimer = void 0;
773
+ retryTimer = void 0;
774
+ retryTimeout = void 0;
825
775
  navigationWaitTimer = void 0;
826
- }
827
- if (navigationWaitTimeout) {
828
- clearTimeout(navigationWaitTimeout);
829
776
  navigationWaitTimeout = void 0;
830
777
  }
831
- currentIframe = iframe;
832
- const doc = iframe.contentDocument;
833
- if (!doc?.body) {
834
- publishTree(null);
835
- return;
778
+ function refresh() {
779
+ tree = computeWxmlTree();
780
+ if (tree) {
781
+ setWxmlSnapshot(tree, true);
782
+ } else {
783
+ clearWxmlSnapshot();
784
+ unhighlightElement();
785
+ }
786
+ emit?.();
836
787
  }
837
- sendWxmlTree();
838
- currentObserver = new MutationObserver(() => {
839
- clearTimeout(wxmlTimer);
840
- wxmlTimer = setTimeout(sendWxmlTree, WXML_DEBOUNCE_MS);
841
- });
842
- currentObserver.observe(doc.body, { childList: true, subtree: true });
843
- }
844
- function tryAttach() {
845
- const iframe = findActivePageIframe();
846
- if (!iframe) return false;
847
- const instance = getVueAppFromIframe(iframe);
848
- if (!instance) return false;
849
- observeIframe(iframe);
850
- return true;
851
- }
852
- function scheduleAttach() {
853
- if (retryTimer) clearInterval(retryTimer);
854
- if (retryTimeout) clearTimeout(retryTimeout);
855
- retryTimer = setInterval(() => {
856
- if (tryAttach() && retryTimer) {
857
- clearInterval(retryTimer);
858
- retryTimer = void 0;
788
+ function observeIframe(iframe) {
789
+ if (iframe === currentIframe) return;
790
+ if (currentObserver) {
791
+ currentObserver.disconnect();
792
+ currentObserver = null;
859
793
  }
860
- }, WXML_RETRY_INTERVAL_MS);
861
- retryTimeout = setTimeout(() => {
862
- if (retryTimer) clearInterval(retryTimer);
863
- retryTimer = void 0;
864
- }, WXML_RETRY_TIMEOUT_MS);
865
- }
866
- function observeTopLevel() {
867
- if (topObserver) return;
868
- topObserver = new MutationObserver(() => {
869
- const iframe = findActivePageIframe();
870
- if (!iframe) {
871
- publishTree(null);
794
+ if (navigationWaitTimer) {
795
+ clearInterval(navigationWaitTimer);
796
+ navigationWaitTimer = void 0;
797
+ }
798
+ if (navigationWaitTimeout) {
799
+ clearTimeout(navigationWaitTimeout);
800
+ navigationWaitTimeout = void 0;
801
+ }
802
+ currentIframe = iframe;
803
+ const doc = iframe.contentDocument;
804
+ if (!doc?.body) {
805
+ refresh();
872
806
  return;
873
807
  }
874
- if (iframe !== currentIframe) {
875
- if (navigationWaitTimer) {
876
- clearInterval(navigationWaitTimer);
877
- navigationWaitTimer = void 0;
808
+ refresh();
809
+ currentObserver = new MutationObserver(() => {
810
+ clearTimeout(wxmlTimer);
811
+ wxmlTimer = setTimeout(refresh, WXML_DEBOUNCE_MS);
812
+ });
813
+ currentObserver.observe(doc.body, { childList: true, subtree: true });
814
+ }
815
+ function tryAttach() {
816
+ const iframe = getActivePageIframe();
817
+ if (!iframe) return false;
818
+ const instance = getVueAppFromIframe(iframe);
819
+ if (!instance) return false;
820
+ observeIframe(iframe);
821
+ return true;
822
+ }
823
+ function scheduleAttach() {
824
+ if (retryTimer) clearInterval(retryTimer);
825
+ if (retryTimeout) clearTimeout(retryTimeout);
826
+ retryTimer = setInterval(() => {
827
+ if (tryAttach() && retryTimer) {
828
+ clearInterval(retryTimer);
829
+ retryTimer = void 0;
878
830
  }
879
- if (navigationWaitTimeout) {
880
- clearTimeout(navigationWaitTimeout);
881
- navigationWaitTimeout = void 0;
831
+ }, WXML_RETRY_INTERVAL_MS);
832
+ retryTimeout = setTimeout(() => {
833
+ if (retryTimer) clearInterval(retryTimer);
834
+ retryTimer = void 0;
835
+ }, WXML_RETRY_TIMEOUT_MS);
836
+ }
837
+ function observeTopLevel() {
838
+ if (topObserver) return;
839
+ topObserver = new MutationObserver(() => {
840
+ const iframe = getActivePageIframe();
841
+ if (!iframe) {
842
+ refresh();
843
+ return;
882
844
  }
883
- navigationWaitTimer = setInterval(() => {
884
- if (getVueAppFromIframe(iframe)) {
845
+ if (iframe !== currentIframe) {
846
+ if (navigationWaitTimer) {
847
+ clearInterval(navigationWaitTimer);
848
+ navigationWaitTimer = void 0;
849
+ }
850
+ if (navigationWaitTimeout) {
851
+ clearTimeout(navigationWaitTimeout);
852
+ navigationWaitTimeout = void 0;
853
+ }
854
+ navigationWaitTimer = setInterval(() => {
855
+ if (getVueAppFromIframe(iframe)) {
856
+ if (navigationWaitTimer) {
857
+ clearInterval(navigationWaitTimer);
858
+ navigationWaitTimer = void 0;
859
+ }
860
+ if (navigationWaitTimeout) {
861
+ clearTimeout(navigationWaitTimeout);
862
+ navigationWaitTimeout = void 0;
863
+ }
864
+ observeIframe(iframe);
865
+ }
866
+ }, NAVIGATION_POLL_INTERVAL_MS);
867
+ navigationWaitTimeout = setTimeout(() => {
885
868
  if (navigationWaitTimer) {
886
869
  clearInterval(navigationWaitTimer);
887
870
  navigationWaitTimer = void 0;
888
871
  }
889
- if (navigationWaitTimeout) {
890
- clearTimeout(navigationWaitTimeout);
891
- navigationWaitTimeout = void 0;
892
- }
893
- observeIframe(iframe);
894
- }
895
- }, NAVIGATION_POLL_INTERVAL_MS);
896
- navigationWaitTimeout = setTimeout(() => {
897
- if (navigationWaitTimer) {
898
- clearInterval(navigationWaitTimer);
899
- navigationWaitTimer = void 0;
872
+ navigationWaitTimeout = void 0;
873
+ }, NAVIGATION_TIMEOUT_MS);
874
+ }
875
+ });
876
+ if (document.body) {
877
+ topObserver.observe(document.body, { childList: true, subtree: true });
878
+ } else {
879
+ document.addEventListener("DOMContentLoaded", () => {
880
+ if (document.body && topObserver) {
881
+ topObserver.observe(document.body, { childList: true, subtree: true });
900
882
  }
901
- navigationWaitTimeout = void 0;
902
- }, NAVIGATION_TIMEOUT_MS);
883
+ }, { once: true });
903
884
  }
904
- });
905
- if (document.body) {
906
- topObserver.observe(document.body, { childList: true, subtree: true });
907
- } else {
908
- document.addEventListener("DOMContentLoaded", () => {
909
- if (document.body && topObserver) {
910
- topObserver.observe(document.body, { childList: true, subtree: true });
885
+ }
886
+ return {
887
+ id: "wxml",
888
+ snapshot: () => tree,
889
+ start(onChange) {
890
+ emit = onChange;
891
+ if (!tryAttach()) {
892
+ scheduleAttach();
893
+ }
894
+ observeTopLevel();
895
+ },
896
+ dispose() {
897
+ if (currentObserver) {
898
+ currentObserver.disconnect();
899
+ currentObserver = null;
911
900
  }
912
- }, { once: true });
901
+ if (topObserver) {
902
+ topObserver.disconnect();
903
+ topObserver = null;
904
+ }
905
+ currentIframe = null;
906
+ clearTimers();
907
+ clearWxmlSnapshot();
908
+ unhighlightElement();
909
+ tree = null;
910
+ emit = null;
911
+ }
912
+ };
913
+ }
914
+
915
+ // src/preload/miniapp-snapshot/host.ts
916
+ var import_electron4 = require("electron");
917
+ var ACCESSOR_KEY = "__miniappSnapshot";
918
+ function exposeApi(api) {
919
+ try {
920
+ import_electron4.contextBridge.exposeInMainWorld(ACCESSOR_KEY, api);
921
+ } catch {
922
+ ;
923
+ window.__miniappSnapshot = api;
913
924
  }
925
+ return () => {
926
+ const windowRef = window;
927
+ if (windowRef[ACCESSOR_KEY] === api) {
928
+ delete windowRef[ACCESSOR_KEY];
929
+ }
930
+ };
914
931
  }
915
- function installWxmlInstrumentation() {
916
- if (!tryAttach()) {
917
- scheduleAttach();
932
+ function createMiniappSnapshotHost() {
933
+ const sources = [];
934
+ const byId = /* @__PURE__ */ new Map();
935
+ let installed = false;
936
+ let disposed = false;
937
+ let seq = 0;
938
+ function publish(source) {
939
+ if (disposed) return;
940
+ seq += 1;
941
+ const envelope = {
942
+ id: source.id,
943
+ seq,
944
+ ts: Date.now(),
945
+ data: source.snapshot()
946
+ };
947
+ sendToHost(MiniappSnapshotChannel.Push, envelope);
918
948
  }
919
- observeTopLevel();
920
- disposables.add(() => {
921
- if (currentObserver) {
922
- currentObserver.disconnect();
923
- currentObserver = null;
949
+ function register(source) {
950
+ if (installed) {
951
+ throw new Error("MiniappSnapshotHost: register() called after install()");
924
952
  }
925
- });
926
- disposables.add(() => {
927
- if (topObserver) {
928
- topObserver.disconnect();
929
- topObserver = null;
953
+ if (byId.has(source.id)) {
954
+ throw new Error(`MiniappSnapshotHost: duplicate source id "${source.id}"`);
930
955
  }
931
- });
932
- disposables.add(() => {
933
- currentIframe = null;
934
- clearTimers();
935
- });
936
- disposables.add(() => {
937
- clearWxmlSnapshot();
938
- unhighlightElement();
939
- });
940
- return () => {
941
- disposables.disposeAll();
942
- };
956
+ const erased = source;
957
+ byId.set(source.id, erased);
958
+ sources.push(erased);
959
+ }
960
+ function install() {
961
+ if (installed) {
962
+ throw new Error("MiniappSnapshotHost: install() called twice");
963
+ }
964
+ installed = true;
965
+ for (const source of sources) {
966
+ source.start(() => publish(source));
967
+ publish(source);
968
+ }
969
+ const disposePull = onHostMessage(MiniappSnapshotChannel.Pull, (...args) => {
970
+ const payload = args[0];
971
+ const id = payload?.id;
972
+ if (typeof id !== "string") return;
973
+ const source = byId.get(id);
974
+ if (!source) return;
975
+ publish(source);
976
+ });
977
+ const api = {
978
+ get: (id) => byId.get(id)?.snapshot(),
979
+ ids: () => sources.map((source) => source.id)
980
+ };
981
+ const disposeApi = exposeApi(api);
982
+ return () => {
983
+ if (disposed) return;
984
+ disposed = true;
985
+ disposePull();
986
+ disposeApi();
987
+ for (const source of sources) {
988
+ source.dispose();
989
+ }
990
+ };
991
+ }
992
+ return { register, install };
943
993
  }
944
994
 
945
995
  // src/preload/shared/api-compat.ts
@@ -1126,6 +1176,8 @@ setupApiCompatHook();
1126
1176
  installSimulatorBridge();
1127
1177
  installCustomApisBridge();
1128
1178
  installConsoleInstrumentation();
1129
- installAppDataInstrumentation();
1130
- installWxmlInstrumentation();
1179
+ var snapshotHost = createMiniappSnapshotHost();
1180
+ snapshotHost.register(createAppDataSource());
1181
+ snapshotHost.register(createWxmlSource());
1182
+ snapshotHost.install();
1131
1183
  //# sourceMappingURL=simulator.js.map