@dimina-kit/devtools 0.3.1 → 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 (190) hide show
  1. package/README.md +297 -133
  2. package/dist/main/api.d.ts +6 -2
  3. package/dist/main/api.js +5 -2
  4. package/dist/main/app/app.d.ts +1 -1
  5. package/dist/main/app/app.js +84 -36
  6. package/dist/main/app/bootstrap.js +2 -1
  7. package/dist/main/app/launch.d.ts +2 -2
  8. package/dist/main/app/launch.js +10 -8
  9. package/dist/main/index.bundle.js +1567 -477
  10. package/dist/main/ipc/app.d.ts +2 -1
  11. package/dist/main/ipc/app.js +5 -4
  12. package/dist/main/ipc/index.d.ts +5 -4
  13. package/dist/main/ipc/index.js +5 -4
  14. package/dist/main/ipc/panels.d.ts +2 -1
  15. package/dist/main/ipc/panels.js +16 -13
  16. package/dist/main/ipc/popover.d.ts +4 -1
  17. package/dist/main/ipc/popover.js +15 -5
  18. package/dist/main/ipc/projects.d.ts +6 -1
  19. package/dist/main/ipc/projects.js +127 -6
  20. package/dist/main/ipc/session.d.ts +4 -1
  21. package/dist/main/ipc/session.js +34 -6
  22. package/dist/main/ipc/settings.d.ts +4 -1
  23. package/dist/main/ipc/settings.js +51 -23
  24. package/dist/main/ipc/simulator-module.d.ts +8 -0
  25. package/dist/main/ipc/simulator-module.js +19 -0
  26. package/dist/main/ipc/simulator.d.ts +2 -1
  27. package/dist/main/ipc/simulator.js +23 -18
  28. package/dist/main/ipc/toolbar.d.ts +2 -1
  29. package/dist/main/ipc/toolbar.js +3 -2
  30. package/dist/main/menu/index.js +11 -0
  31. package/dist/main/services/automation/exec.d.ts +2 -0
  32. package/dist/main/services/automation/exec.js +7 -9
  33. package/dist/main/services/automation/handlers/app.js +37 -51
  34. package/dist/main/services/automation/handlers/element.js +27 -41
  35. package/dist/main/services/automation/index.js +88 -13
  36. package/dist/main/services/default-adapter.js +3 -3
  37. package/dist/main/services/mcp/index.d.ts +1 -0
  38. package/dist/main/services/mcp/index.js +1 -0
  39. package/dist/main/services/mcp/server.d.ts +2 -1
  40. package/dist/main/services/mcp/server.js +10 -0
  41. package/dist/main/services/mcp/status.d.ts +10 -0
  42. package/dist/main/services/mcp/status.js +14 -0
  43. package/dist/main/services/mcp/target-manager.js +2 -1
  44. package/dist/main/services/module.d.ts +18 -0
  45. package/dist/main/services/module.js +2 -0
  46. package/dist/main/services/notifications/renderer-notifier.d.ts +5 -3
  47. package/dist/main/services/notifications/renderer-notifier.js +3 -6
  48. package/dist/main/services/projects/builtin-templates.d.ts +3 -0
  49. package/dist/main/services/projects/builtin-templates.js +24 -0
  50. package/dist/main/services/projects/create-project-service.d.ts +7 -0
  51. package/dist/main/services/projects/create-project-service.js +84 -0
  52. package/dist/main/services/projects/index.d.ts +7 -0
  53. package/dist/main/services/projects/index.js +9 -0
  54. package/dist/main/services/projects/local-provider.d.ts +3 -0
  55. package/dist/main/services/projects/local-provider.js +25 -0
  56. package/dist/main/services/projects/project-repository.d.ts +1 -1
  57. package/dist/main/services/projects/project-repository.js +3 -0
  58. package/dist/main/services/projects/templates.d.ts +21 -0
  59. package/dist/main/services/projects/templates.js +39 -0
  60. package/dist/main/services/projects/thumbnail.d.ts +8 -0
  61. package/dist/main/services/projects/thumbnail.js +37 -0
  62. package/dist/main/services/projects/types.d.ts +118 -0
  63. package/dist/main/services/projects/types.js +19 -0
  64. package/dist/main/services/settings/index.d.ts +11 -0
  65. package/dist/main/services/settings/index.js +18 -2
  66. package/dist/main/services/simulator/custom-apis.d.ts +10 -0
  67. package/dist/main/services/simulator/custom-apis.js +26 -0
  68. package/dist/main/services/simulator-storage/index.d.ts +22 -1
  69. package/dist/main/services/simulator-storage/index.js +334 -97
  70. package/dist/main/services/update/update-manager.d.ts +16 -1
  71. package/dist/main/services/update/update-manager.js +18 -15
  72. package/dist/main/services/views/view-manager.d.ts +7 -7
  73. package/dist/main/services/views/view-manager.js +53 -29
  74. package/dist/main/services/window-service.d.ts +24 -0
  75. package/dist/main/services/window-service.js +26 -0
  76. package/dist/main/services/workbench-context.d.ts +49 -2
  77. package/dist/main/services/workbench-context.js +15 -2
  78. package/dist/main/services/workspace/workspace-service.d.ts +9 -6
  79. package/dist/main/services/workspace/workspace-service.js +71 -11
  80. package/dist/main/simulator-apis.d.ts +23 -0
  81. package/dist/main/simulator-apis.js +24 -0
  82. package/dist/main/utils/disposable.d.ts +13 -0
  83. package/dist/main/utils/disposable.js +60 -0
  84. package/dist/main/utils/ipc-registry.d.ts +39 -0
  85. package/dist/main/utils/ipc-registry.js +109 -0
  86. package/dist/main/utils/ipc-schema.d.ts +28 -0
  87. package/dist/main/utils/ipc-schema.js +38 -0
  88. package/dist/main/utils/paths.d.ts +6 -0
  89. package/dist/main/utils/paths.js +6 -0
  90. package/dist/main/utils/sender-policy.d.ts +25 -0
  91. package/dist/main/utils/sender-policy.js +44 -0
  92. package/dist/main/utils/theme.d.ts +24 -0
  93. package/dist/main/utils/theme.js +38 -1
  94. package/dist/main/windows/main-window/create.d.ts +6 -0
  95. package/dist/main/windows/main-window/create.js +66 -10
  96. package/dist/main/windows/main-window/events.d.ts +2 -1
  97. package/dist/main/windows/main-window/events.js +25 -2
  98. package/dist/main/windows/navigation-hardening.d.ts +24 -0
  99. package/dist/main/windows/navigation-hardening.js +55 -0
  100. package/dist/main/windows/settings-window/create.js +11 -1
  101. package/dist/preload/index.d.ts +22 -0
  102. package/dist/preload/index.js +19 -0
  103. package/dist/preload/instrumentation/app-data.d.ts +32 -2
  104. package/dist/preload/instrumentation/app-data.js +253 -79
  105. package/dist/preload/instrumentation/index.d.ts +2 -2
  106. package/dist/preload/instrumentation/index.js +2 -2
  107. package/dist/preload/instrumentation/wxml.d.ts +16 -4
  108. package/dist/preload/instrumentation/wxml.js +188 -178
  109. package/dist/preload/miniapp-snapshot/host.d.ts +12 -0
  110. package/dist/preload/miniapp-snapshot/host.js +117 -0
  111. package/dist/preload/miniapp-snapshot/types.d.ts +62 -0
  112. package/dist/preload/miniapp-snapshot/types.js +15 -0
  113. package/dist/preload/runtime/bridge.js +5 -24
  114. package/dist/preload/runtime/custom-apis.d.ts +6 -0
  115. package/dist/preload/runtime/custom-apis.js +43 -0
  116. package/dist/preload/runtime/host.d.ts +1 -0
  117. package/dist/preload/runtime/host.js +13 -0
  118. package/dist/preload/shared/expose.d.ts +15 -0
  119. package/dist/preload/shared/expose.js +33 -0
  120. package/dist/preload/shared/page-iframe.d.ts +3 -0
  121. package/dist/preload/shared/page-iframe.js +6 -0
  122. package/dist/preload/shared/types.d.ts +2 -0
  123. package/dist/preload/windows/main.cjs +47 -0
  124. package/dist/preload/windows/main.cjs.map +7 -0
  125. package/dist/preload/windows/simulator.js +501 -272
  126. package/dist/renderer/assets/constants-DI382mTP.js +2 -0
  127. package/dist/renderer/assets/index-D8VFYBh-.js +46 -0
  128. package/dist/renderer/assets/{input-DxfYnzX_.js → input-CoWcfa8u.js} +2 -2
  129. package/dist/renderer/assets/ipc-transport-Cd2xPrsa.js +9 -0
  130. package/dist/renderer/assets/ipc-transport-DqbRdZNO.css +1 -0
  131. package/dist/renderer/assets/popover-Nq5gT9DO.js +2 -0
  132. package/dist/renderer/assets/select-By5KH-UG.js +2 -0
  133. package/dist/renderer/assets/{settings-DteGraEU.js → settings-Dj_N70qR.js} +2 -2
  134. package/dist/renderer/assets/settings-api-Do0_Smq1.js +2 -0
  135. package/dist/renderer/assets/workbenchSettings-CazSLGYt.js +8 -0
  136. package/dist/renderer/entries/main/index.html +13 -5
  137. package/dist/renderer/entries/popover/index.html +8 -5
  138. package/dist/renderer/entries/settings/index.html +7 -5
  139. package/dist/renderer/entries/workbench-settings/index.html +7 -4
  140. package/dist/shared/ipc-channels.d.ts +46 -13
  141. package/dist/shared/ipc-channels.js +60 -14
  142. package/dist/shared/ipc-schemas.d.ts +118 -0
  143. package/dist/shared/ipc-schemas.js +133 -0
  144. package/dist/shared/simulator-route.d.ts +72 -0
  145. package/dist/shared/simulator-route.js +169 -0
  146. package/dist/shared/types.d.ts +82 -8
  147. package/dist/simulator/assets/simulator-DJCozrU5.js +9 -0
  148. package/dist/simulator/simulator.html +6 -43
  149. package/package.json +18 -29
  150. package/templates/blank/app.js +6 -0
  151. package/templates/blank/app.json +11 -0
  152. package/templates/blank/app.wxss +5 -0
  153. package/templates/blank/pages/index/index.js +6 -0
  154. package/templates/blank/pages/index/index.json +3 -0
  155. package/templates/blank/pages/index/index.wxml +3 -0
  156. package/templates/blank/pages/index/index.wxss +11 -0
  157. package/templates/blank/project.config.json +13 -0
  158. package/templates/blank/sitemap.json +9 -0
  159. package/templates/taro-todo/app.js +1 -0
  160. package/templates/taro-todo/app.json +1 -0
  161. package/templates/taro-todo/app.wxss +1 -0
  162. package/templates/taro-todo/base.wxml +851 -0
  163. package/templates/taro-todo/common.js +1 -0
  164. package/templates/taro-todo/comp.js +1 -0
  165. package/templates/taro-todo/comp.json +1 -0
  166. package/templates/taro-todo/comp.wxml +2 -0
  167. package/templates/taro-todo/custom-wrapper.js +1 -0
  168. package/templates/taro-todo/custom-wrapper.json +1 -0
  169. package/templates/taro-todo/custom-wrapper.wxml +4 -0
  170. package/templates/taro-todo/pages/index/index.js +2 -0
  171. package/templates/taro-todo/pages/index/index.json +1 -0
  172. package/templates/taro-todo/pages/index/index.wxml +2 -0
  173. package/templates/taro-todo/pages/index/index.wxss +1 -0
  174. package/templates/taro-todo/project.config.json +44 -0
  175. package/templates/taro-todo/runtime.js +1 -0
  176. package/templates/taro-todo/taro.js +2 -0
  177. package/templates/taro-todo/utils.wxs +39 -0
  178. package/templates/taro-todo/vendors.js +2 -0
  179. package/dist/preload/instrumentation/disposable.d.ts +0 -11
  180. package/dist/preload/instrumentation/disposable.js +0 -15
  181. package/dist/preload/windows/main.d.ts +0 -6
  182. package/dist/preload/windows/main.js +0 -6
  183. package/dist/renderer/assets/index-D1p6crtf.js +0 -46
  184. package/dist/renderer/assets/ipc-transport-ClIvDcYY.js +0 -9
  185. package/dist/renderer/assets/ipc-transport-EiWxu_hG.css +0 -1
  186. package/dist/renderer/assets/popover-CtXcBJtM.js +0 -2
  187. package/dist/renderer/assets/select-DMfp49f1.js +0 -2
  188. package/dist/renderer/assets/settings-api-CY84UMpN.js +0 -2
  189. package/dist/renderer/assets/workbenchSettings-DjELLnSJ.js +0 -8
  190. package/dist/simulator/assets/simulator-C1eHXnuq.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,44 +170,82 @@ 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
 
180
+ // src/preload/runtime/custom-apis.ts
181
+ var import_electron2 = require("electron");
182
+
176
183
  // src/shared/ipc-channels.ts
177
184
  var SimulatorChannel = {
178
185
  Attach: "simulator:attach",
179
186
  Detach: "simulator:detach",
180
187
  Resize: "simulator:resize",
181
188
  SetVisible: "simulator:setVisible",
182
- Console: "simulator:console",
183
- Wxml: "simulator:wxml",
184
- AppData: "simulator:appdata",
185
- AppDataAll: "simulator:appdata-all"
189
+ Console: "simulator:console"
190
+ };
191
+ var SimulatorCustomApiBridgeChannel = {
192
+ Request: "simulator:custom-apis:bridge-request",
193
+ Response: "simulator:custom-apis:bridge-response"
194
+ };
195
+ var MiniappSnapshotChannel = {
196
+ Push: "miniapp-snapshot:push",
197
+ Pull: "miniapp-snapshot:pull"
186
198
  };
187
199
 
200
+ // src/preload/runtime/custom-apis.ts
201
+ function buildBridge() {
202
+ let nextId = 1;
203
+ const pending = /* @__PURE__ */ new Map();
204
+ import_electron2.ipcRenderer.on(SimulatorCustomApiBridgeChannel.Response, (_event, payload) => {
205
+ const entry = pending.get(payload.id);
206
+ if (!entry) return;
207
+ pending.delete(payload.id);
208
+ if ("error" in payload) {
209
+ entry.reject(new Error(payload.error));
210
+ } else {
211
+ entry.resolve(payload.result);
212
+ }
213
+ });
214
+ const send = (req) => {
215
+ return new Promise((resolve, reject) => {
216
+ pending.set(req.id, {
217
+ resolve: (value) => resolve(value),
218
+ reject
219
+ });
220
+ import_electron2.ipcRenderer.sendToHost(SimulatorCustomApiBridgeChannel.Request, req);
221
+ });
222
+ };
223
+ return {
224
+ list: () => send({ id: nextId++, op: "list" }),
225
+ invoke: (name, params) => send({ id: nextId++, op: "invoke", name, params })
226
+ };
227
+ }
228
+ function installCustomApisBridge() {
229
+ const bridge = buildBridge();
230
+ return exposeOnMainWorld("__diminaCustomApis", bridge);
231
+ }
232
+
188
233
  // src/preload/runtime/host.ts
189
- var import_electron2 = require("electron");
234
+ var import_electron3 = require("electron");
190
235
  function sendToHost(channel, data) {
191
- import_electron2.ipcRenderer.sendToHost(channel, data);
236
+ import_electron3.ipcRenderer.sendToHost(channel, data);
237
+ }
238
+ function onHostMessage(channel, handler) {
239
+ let active = true;
240
+ const wrapped = (_event, ...args) => {
241
+ if (!active) return;
242
+ handler(...args);
243
+ };
244
+ import_electron3.ipcRenderer.on(channel, wrapped);
245
+ return () => {
246
+ active = false;
247
+ import_electron3.ipcRenderer.removeListener(channel, wrapped);
248
+ };
192
249
  }
193
250
  function safeSerialize(val) {
194
251
  if (val === null || val === void 0) return val;
@@ -258,27 +315,7 @@ function installConsoleInstrumentation() {
258
315
  };
259
316
  }
260
317
 
261
- // src/preload/instrumentation/disposable.ts
262
- function createDisposableSet() {
263
- const disposables2 = [];
264
- return {
265
- add: (fn) => disposables2.push(fn),
266
- disposeAll: () => {
267
- disposables2.forEach((fn) => fn());
268
- disposables2.length = 0;
269
- }
270
- };
271
- }
272
-
273
318
  // src/preload/instrumentation/app-data.ts
274
- var appDataCache = /* @__PURE__ */ new Map();
275
- function publishSnapshot() {
276
- const data = {};
277
- for (const [key, value] of appDataCache) {
278
- data[key] = value;
279
- }
280
- setAppDataSnapshot(data);
281
- }
282
319
  function decodeWorkerMessage(message) {
283
320
  let payload = message;
284
321
  if (typeof payload === "string") {
@@ -288,78 +325,199 @@ function decodeWorkerMessage(message) {
288
325
  return null;
289
326
  }
290
327
  }
328
+ if (!payload || typeof payload !== "object") return null;
291
329
  const record = payload;
292
- if (record?.type !== "u" || !record.body) return null;
293
- return record.body;
294
- }
295
- function createInstrumentedWorker(OriginalWorker) {
296
- function InstrumentedWorker(scriptURL, options) {
297
- const resolvedScriptURL = scriptURL instanceof URL ? scriptURL : new URL(scriptURL, window.location.href);
298
- const worker = Reflect.construct(
299
- OriginalWorker,
300
- [resolvedScriptURL, options],
301
- new.target ?? InstrumentedWorker
302
- );
303
- worker.addEventListener("message", (event) => {
304
- const body = decodeWorkerMessage(event.data);
305
- if (!body) return;
306
- window.__simulatorHook?.appData({
307
- bridgeId: body.bridgeId,
308
- moduleId: body.moduleId,
309
- data: body.data
310
- });
311
- });
312
- return worker;
330
+ if (record.type === "ub") {
331
+ const body = record.body;
332
+ if (!body || typeof body !== "object") return null;
333
+ if (typeof body.bridgeId !== "string" || !Array.isArray(body.updates)) return null;
334
+ const out = [];
335
+ for (const u of body.updates) {
336
+ if (!u || typeof u.moduleId !== "string") continue;
337
+ if (!u.moduleId.startsWith("page_")) continue;
338
+ out.push({ mode: "patch", bridgeId: body.bridgeId, moduleId: u.moduleId, data: u.data });
339
+ }
340
+ return out.length > 0 ? out : null;
313
341
  }
314
- Object.setPrototypeOf(InstrumentedWorker, OriginalWorker);
315
- Object.defineProperty(InstrumentedWorker, "prototype", {
316
- value: OriginalWorker.prototype
317
- });
318
- return InstrumentedWorker;
319
- }
320
- function installAppDataInstrumentation() {
321
- const disposables2 = createDisposableSet();
322
- const originalHook = window.__simulatorHook;
323
- const originalDescriptor = Object.getOwnPropertyDescriptor(window, "Worker");
324
- const OriginalWorker = window.Worker;
325
- window.__simulatorHook = {
326
- appData: (body) => {
327
- const record = body;
328
- if (record?.bridgeId && record?.moduleId) {
329
- const key = `${record.bridgeId}/${record.moduleId}`;
330
- appDataCache.set(key, record.data);
331
- publishSnapshot();
332
- }
333
- sendToHost(SimulatorChannel.AppData, body);
342
+ if (typeof record.type === "string" && record.type.startsWith("page_")) {
343
+ const body = record.body;
344
+ if (!body || typeof body !== "object") return null;
345
+ if (typeof body.bridgeId !== "string" || typeof body.path !== "string") return null;
346
+ if (!body.data || typeof body.data !== "object") return null;
347
+ return [{
348
+ mode: "init",
349
+ bridgeId: body.bridgeId,
350
+ moduleId: record.type,
351
+ componentPath: body.path,
352
+ data: body.data
353
+ }];
354
+ }
355
+ return null;
356
+ }
357
+ function decodeOutgoingMessage(message) {
358
+ let payload = message;
359
+ if (typeof payload === "string") {
360
+ try {
361
+ payload = JSON.parse(payload);
362
+ } catch {
363
+ return null;
334
364
  }
365
+ }
366
+ if (!payload || typeof payload !== "object") return null;
367
+ const r = payload;
368
+ if (typeof r.type !== "string") return null;
369
+ return {
370
+ type: r.type,
371
+ bridgeId: typeof r.body?.bridgeId === "string" ? r.body.bridgeId : void 0
335
372
  };
336
- Object.defineProperty(window, "Worker", {
337
- configurable: true,
338
- writable: true,
339
- value: createInstrumentedWorker(OriginalWorker)
340
- });
341
- publishSnapshot();
342
- disposables2.add(() => {
343
- if (originalDescriptor) {
344
- Object.defineProperty(window, "Worker", originalDescriptor);
345
- } else {
346
- window.Worker = OriginalWorker;
373
+ }
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 });
347
390
  }
348
- });
349
- disposables2.add(() => {
350
- if (originalHook) {
351
- window.__simulatorHook = originalHook;
352
- } else {
353
- delete window.__simulatorHook;
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;
354
400
  }
355
- });
356
- disposables2.add(() => {
357
- appDataCache.clear();
358
- clearAppDataSnapshot();
401
+ return { bridges, entries };
402
+ }
403
+ function publishSnapshot() {
404
+ const data = {};
405
+ for (const [key, entry] of appDataCache) {
406
+ data[key] = entry.data;
407
+ }
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);
414
+ }
415
+ const idx = bridgeOrder.indexOf(bridgeId);
416
+ if (idx >= 0) bridgeOrder.splice(idx, 1);
417
+ bridgePagePath.delete(bridgeId);
359
418
  publishSnapshot();
360
- });
361
- return () => {
362
- disposables2.disposeAll();
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);
435
+ }
436
+ publishSnapshot();
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
+ }
363
521
  };
364
522
  }
365
523
 
@@ -570,10 +728,6 @@ function walkInstance(instance, depth) {
570
728
  }
571
729
 
572
730
  // src/preload/instrumentation/wxml.ts
573
- function findActivePageIframe() {
574
- const iframes = document.querySelectorAll(".dimina-native-webview__window");
575
- return iframes.length > 0 ? iframes[iframes.length - 1] : null;
576
- }
577
731
  function getVueAppFromIframe(iframe) {
578
732
  try {
579
733
  const doc = iframe.contentDocument;
@@ -589,181 +743,253 @@ function getVueAppFromIframe(iframe) {
589
743
  return null;
590
744
  }
591
745
  }
592
- var wxmlTimer;
593
- var currentObserver = null;
594
- var currentIframe = null;
595
- var topObserver = null;
596
- var retryTimer;
597
- var retryTimeout;
598
- var navigationWaitTimer;
599
- var navigationWaitTimeout;
600
- var disposables = createDisposableSet();
601
- function clearTimers() {
602
- if (wxmlTimer) clearTimeout(wxmlTimer);
603
- if (retryTimer) clearInterval(retryTimer);
604
- if (retryTimeout) clearTimeout(retryTimeout);
605
- if (navigationWaitTimer) clearInterval(navigationWaitTimer);
606
- if (navigationWaitTimeout) clearTimeout(navigationWaitTimeout);
607
- wxmlTimer = void 0;
608
- retryTimer = void 0;
609
- retryTimeout = void 0;
610
- navigationWaitTimer = void 0;
611
- navigationWaitTimeout = void 0;
612
- }
613
- function publishTree(tree) {
614
- if (tree) {
615
- const normalized = Array.isArray(tree) ? { tagName: "#fragment", attrs: {}, children: tree } : tree;
616
- setWxmlSnapshot(normalized, true);
617
- sendToHost(SimulatorChannel.Wxml, normalized);
618
- return;
619
- }
620
- clearWxmlSnapshot();
621
- unhighlightElement();
622
- }
623
- function sendWxmlTree() {
624
- const iframe = findActivePageIframe();
625
- if (!iframe) {
626
- publishTree(null);
627
- return;
628
- }
746
+ function computeWxmlTree() {
747
+ const iframe = getActivePageIframe();
748
+ if (!iframe) return null;
629
749
  const instance = getVueAppFromIframe(iframe);
630
- if (!instance) {
631
- publishTree(null);
632
- return;
633
- }
750
+ if (!instance) return null;
634
751
  const tree = walkInstance(instance, 0);
635
- if (!tree) {
636
- publishTree(null);
637
- return;
638
- }
639
- publishTree(tree);
752
+ if (!tree) return null;
753
+ return Array.isArray(tree) ? { tagName: "#fragment", attrs: {}, children: tree } : tree;
640
754
  }
641
- function observeIframe(iframe) {
642
- if (iframe === currentIframe) return;
643
- if (currentObserver) {
644
- currentObserver.disconnect();
645
- currentObserver = null;
646
- }
647
- if (navigationWaitTimer) {
648
- 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;
649
775
  navigationWaitTimer = void 0;
650
- }
651
- if (navigationWaitTimeout) {
652
- clearTimeout(navigationWaitTimeout);
653
776
  navigationWaitTimeout = void 0;
654
777
  }
655
- currentIframe = iframe;
656
- const doc = iframe.contentDocument;
657
- if (!doc?.body) {
658
- publishTree(null);
659
- return;
660
- }
661
- sendWxmlTree();
662
- currentObserver = new MutationObserver(() => {
663
- clearTimeout(wxmlTimer);
664
- wxmlTimer = setTimeout(sendWxmlTree, WXML_DEBOUNCE_MS);
665
- });
666
- currentObserver.observe(doc.body, { childList: true, subtree: true });
667
- }
668
- function tryAttach() {
669
- const iframe = findActivePageIframe();
670
- if (!iframe) return false;
671
- const instance = getVueAppFromIframe(iframe);
672
- if (!instance) return false;
673
- observeIframe(iframe);
674
- return true;
675
- }
676
- function scheduleAttach() {
677
- if (retryTimer) clearInterval(retryTimer);
678
- if (retryTimeout) clearTimeout(retryTimeout);
679
- retryTimer = setInterval(() => {
680
- if (tryAttach() && retryTimer) {
681
- clearInterval(retryTimer);
682
- retryTimer = void 0;
778
+ function refresh() {
779
+ tree = computeWxmlTree();
780
+ if (tree) {
781
+ setWxmlSnapshot(tree, true);
782
+ } else {
783
+ clearWxmlSnapshot();
784
+ unhighlightElement();
683
785
  }
684
- }, WXML_RETRY_INTERVAL_MS);
685
- retryTimeout = setTimeout(() => {
686
- if (retryTimer) clearInterval(retryTimer);
687
- retryTimer = void 0;
688
- }, WXML_RETRY_TIMEOUT_MS);
689
- }
690
- function observeTopLevel() {
691
- if (topObserver) return;
692
- topObserver = new MutationObserver(() => {
693
- const iframe = findActivePageIframe();
694
- if (!iframe) {
695
- publishTree(null);
786
+ emit?.();
787
+ }
788
+ function observeIframe(iframe) {
789
+ if (iframe === currentIframe) return;
790
+ if (currentObserver) {
791
+ currentObserver.disconnect();
792
+ currentObserver = null;
793
+ }
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();
696
806
  return;
697
807
  }
698
- if (iframe !== currentIframe) {
699
- if (navigationWaitTimer) {
700
- clearInterval(navigationWaitTimer);
701
- 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;
702
830
  }
703
- if (navigationWaitTimeout) {
704
- clearTimeout(navigationWaitTimeout);
705
- 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;
706
844
  }
707
- navigationWaitTimer = setInterval(() => {
708
- 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(() => {
709
868
  if (navigationWaitTimer) {
710
869
  clearInterval(navigationWaitTimer);
711
870
  navigationWaitTimer = void 0;
712
871
  }
713
- if (navigationWaitTimeout) {
714
- clearTimeout(navigationWaitTimeout);
715
- navigationWaitTimeout = void 0;
716
- }
717
- observeIframe(iframe);
718
- }
719
- }, NAVIGATION_POLL_INTERVAL_MS);
720
- navigationWaitTimeout = setTimeout(() => {
721
- if (navigationWaitTimer) {
722
- clearInterval(navigationWaitTimer);
723
- 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 });
724
882
  }
725
- navigationWaitTimeout = void 0;
726
- }, NAVIGATION_TIMEOUT_MS);
883
+ }, { once: true });
727
884
  }
728
- });
729
- if (document.body) {
730
- topObserver.observe(document.body, { childList: true, subtree: true });
731
- } else {
732
- document.addEventListener("DOMContentLoaded", () => {
733
- if (document.body && topObserver) {
734
- 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();
735
893
  }
736
- }, { once: true });
894
+ observeTopLevel();
895
+ },
896
+ dispose() {
897
+ if (currentObserver) {
898
+ currentObserver.disconnect();
899
+ currentObserver = null;
900
+ }
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;
737
924
  }
925
+ return () => {
926
+ const windowRef = window;
927
+ if (windowRef[ACCESSOR_KEY] === api) {
928
+ delete windowRef[ACCESSOR_KEY];
929
+ }
930
+ };
738
931
  }
739
- function installWxmlInstrumentation() {
740
- if (!tryAttach()) {
741
- 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);
742
948
  }
743
- observeTopLevel();
744
- disposables.add(() => {
745
- if (currentObserver) {
746
- currentObserver.disconnect();
747
- currentObserver = null;
949
+ function register(source) {
950
+ if (installed) {
951
+ throw new Error("MiniappSnapshotHost: register() called after install()");
748
952
  }
749
- });
750
- disposables.add(() => {
751
- if (topObserver) {
752
- topObserver.disconnect();
753
- topObserver = null;
953
+ if (byId.has(source.id)) {
954
+ throw new Error(`MiniappSnapshotHost: duplicate source id "${source.id}"`);
754
955
  }
755
- });
756
- disposables.add(() => {
757
- currentIframe = null;
758
- clearTimers();
759
- });
760
- disposables.add(() => {
761
- clearWxmlSnapshot();
762
- unhighlightElement();
763
- });
764
- return () => {
765
- disposables.disposeAll();
766
- };
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 };
767
993
  }
768
994
 
769
995
  // src/preload/shared/api-compat.ts
@@ -948,7 +1174,10 @@ function setupApiCompatHook() {
948
1174
  // src/preload/windows/simulator.ts
949
1175
  setupApiCompatHook();
950
1176
  installSimulatorBridge();
1177
+ installCustomApisBridge();
951
1178
  installConsoleInstrumentation();
952
- installAppDataInstrumentation();
953
- installWxmlInstrumentation();
1179
+ var snapshotHost = createMiniappSnapshotHost();
1180
+ snapshotHost.register(createAppDataSource());
1181
+ snapshotHost.register(createWxmlSource());
1182
+ snapshotHost.install();
954
1183
  //# sourceMappingURL=simulator.js.map