@dimina-kit/devtools 0.3.1 → 0.3.2-dev.20260522110734
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +298 -133
- package/dist/main/api.d.ts +6 -2
- package/dist/main/api.js +5 -2
- package/dist/main/app/app.d.ts +1 -1
- package/dist/main/app/app.js +84 -36
- package/dist/main/app/bootstrap.js +2 -1
- package/dist/main/app/launch.d.ts +2 -2
- package/dist/main/app/launch.js +10 -8
- package/dist/main/index.bundle.js +1567 -477
- package/dist/main/ipc/app.d.ts +2 -1
- package/dist/main/ipc/app.js +5 -4
- package/dist/main/ipc/index.d.ts +5 -4
- package/dist/main/ipc/index.js +5 -4
- package/dist/main/ipc/panels.d.ts +2 -1
- package/dist/main/ipc/panels.js +16 -13
- package/dist/main/ipc/popover.d.ts +4 -1
- package/dist/main/ipc/popover.js +15 -5
- package/dist/main/ipc/projects.d.ts +6 -1
- package/dist/main/ipc/projects.js +127 -6
- package/dist/main/ipc/session.d.ts +4 -1
- package/dist/main/ipc/session.js +34 -6
- package/dist/main/ipc/settings.d.ts +4 -1
- package/dist/main/ipc/settings.js +51 -23
- package/dist/main/ipc/simulator-module.d.ts +8 -0
- package/dist/main/ipc/simulator-module.js +19 -0
- package/dist/main/ipc/simulator.d.ts +2 -1
- package/dist/main/ipc/simulator.js +23 -18
- package/dist/main/ipc/toolbar.d.ts +2 -1
- package/dist/main/ipc/toolbar.js +3 -2
- package/dist/main/menu/index.js +11 -0
- package/dist/main/services/automation/exec.d.ts +2 -0
- package/dist/main/services/automation/exec.js +7 -9
- package/dist/main/services/automation/handlers/app.js +37 -51
- package/dist/main/services/automation/handlers/element.js +27 -41
- package/dist/main/services/automation/index.js +88 -13
- package/dist/main/services/default-adapter.js +3 -3
- package/dist/main/services/mcp/index.d.ts +1 -0
- package/dist/main/services/mcp/index.js +1 -0
- package/dist/main/services/mcp/server.d.ts +2 -1
- package/dist/main/services/mcp/server.js +10 -0
- package/dist/main/services/mcp/status.d.ts +10 -0
- package/dist/main/services/mcp/status.js +14 -0
- package/dist/main/services/mcp/target-manager.js +2 -1
- package/dist/main/services/module.d.ts +18 -0
- package/dist/main/services/module.js +2 -0
- package/dist/main/services/notifications/renderer-notifier.d.ts +5 -3
- package/dist/main/services/notifications/renderer-notifier.js +3 -6
- package/dist/main/services/projects/builtin-templates.d.ts +3 -0
- package/dist/main/services/projects/builtin-templates.js +24 -0
- package/dist/main/services/projects/create-project-service.d.ts +7 -0
- package/dist/main/services/projects/create-project-service.js +84 -0
- package/dist/main/services/projects/index.d.ts +7 -0
- package/dist/main/services/projects/index.js +9 -0
- package/dist/main/services/projects/local-provider.d.ts +3 -0
- package/dist/main/services/projects/local-provider.js +25 -0
- package/dist/main/services/projects/project-repository.d.ts +1 -1
- package/dist/main/services/projects/project-repository.js +3 -0
- package/dist/main/services/projects/templates.d.ts +21 -0
- package/dist/main/services/projects/templates.js +39 -0
- package/dist/main/services/projects/thumbnail.d.ts +8 -0
- package/dist/main/services/projects/thumbnail.js +37 -0
- package/dist/main/services/projects/types.d.ts +118 -0
- package/dist/main/services/projects/types.js +19 -0
- package/dist/main/services/settings/index.d.ts +11 -0
- package/dist/main/services/settings/index.js +18 -2
- package/dist/main/services/simulator/custom-apis.d.ts +10 -0
- package/dist/main/services/simulator/custom-apis.js +26 -0
- package/dist/main/services/simulator-storage/index.d.ts +22 -1
- package/dist/main/services/simulator-storage/index.js +334 -97
- package/dist/main/services/update/update-manager.d.ts +16 -1
- package/dist/main/services/update/update-manager.js +18 -15
- package/dist/main/services/views/view-manager.d.ts +7 -7
- package/dist/main/services/views/view-manager.js +53 -29
- package/dist/main/services/window-service.d.ts +24 -0
- package/dist/main/services/window-service.js +26 -0
- package/dist/main/services/workbench-context.d.ts +49 -2
- package/dist/main/services/workbench-context.js +15 -2
- package/dist/main/services/workspace/workspace-service.d.ts +9 -6
- package/dist/main/services/workspace/workspace-service.js +71 -11
- package/dist/main/simulator-apis.d.ts +23 -0
- package/dist/main/simulator-apis.js +24 -0
- package/dist/main/utils/disposable.d.ts +13 -0
- package/dist/main/utils/disposable.js +60 -0
- package/dist/main/utils/ipc-registry.d.ts +39 -0
- package/dist/main/utils/ipc-registry.js +109 -0
- package/dist/main/utils/ipc-schema.d.ts +28 -0
- package/dist/main/utils/ipc-schema.js +38 -0
- package/dist/main/utils/paths.d.ts +6 -0
- package/dist/main/utils/paths.js +6 -0
- package/dist/main/utils/sender-policy.d.ts +25 -0
- package/dist/main/utils/sender-policy.js +44 -0
- package/dist/main/utils/theme.d.ts +24 -0
- package/dist/main/utils/theme.js +38 -1
- package/dist/main/windows/main-window/create.d.ts +6 -0
- package/dist/main/windows/main-window/create.js +66 -10
- package/dist/main/windows/main-window/events.d.ts +2 -1
- package/dist/main/windows/main-window/events.js +25 -2
- package/dist/main/windows/navigation-hardening.d.ts +24 -0
- package/dist/main/windows/navigation-hardening.js +55 -0
- package/dist/main/windows/settings-window/create.js +11 -1
- package/dist/preload/index.d.ts +22 -0
- package/dist/preload/index.js +19 -0
- package/dist/preload/instrumentation/app-data.d.ts +32 -2
- package/dist/preload/instrumentation/app-data.js +253 -79
- package/dist/preload/instrumentation/index.d.ts +2 -2
- package/dist/preload/instrumentation/index.js +2 -2
- package/dist/preload/instrumentation/wxml.d.ts +16 -4
- package/dist/preload/instrumentation/wxml.js +188 -178
- package/dist/preload/miniapp-snapshot/host.d.ts +12 -0
- package/dist/preload/miniapp-snapshot/host.js +117 -0
- package/dist/preload/miniapp-snapshot/types.d.ts +62 -0
- package/dist/preload/miniapp-snapshot/types.js +15 -0
- package/dist/preload/runtime/bridge.js +5 -24
- package/dist/preload/runtime/custom-apis.d.ts +6 -0
- package/dist/preload/runtime/custom-apis.js +43 -0
- package/dist/preload/runtime/host.d.ts +1 -0
- package/dist/preload/runtime/host.js +13 -0
- package/dist/preload/shared/expose.d.ts +15 -0
- package/dist/preload/shared/expose.js +33 -0
- package/dist/preload/shared/page-iframe.d.ts +3 -0
- package/dist/preload/shared/page-iframe.js +6 -0
- package/dist/preload/shared/types.d.ts +2 -0
- package/dist/preload/windows/main.cjs +47 -0
- package/dist/preload/windows/main.cjs.map +7 -0
- package/dist/preload/windows/simulator.js +501 -272
- package/dist/renderer/assets/constants-DI382mTP.js +2 -0
- package/dist/renderer/assets/index-D8VFYBh-.js +46 -0
- package/dist/renderer/assets/{input-DxfYnzX_.js → input-CoWcfa8u.js} +2 -2
- package/dist/renderer/assets/ipc-transport-Cd2xPrsa.js +9 -0
- package/dist/renderer/assets/ipc-transport-DqbRdZNO.css +1 -0
- package/dist/renderer/assets/popover-Nq5gT9DO.js +2 -0
- package/dist/renderer/assets/select-By5KH-UG.js +2 -0
- package/dist/renderer/assets/{settings-DteGraEU.js → settings-Dj_N70qR.js} +2 -2
- package/dist/renderer/assets/settings-api-Do0_Smq1.js +2 -0
- package/dist/renderer/assets/workbenchSettings-CazSLGYt.js +8 -0
- package/dist/renderer/entries/main/index.html +13 -5
- package/dist/renderer/entries/popover/index.html +8 -5
- package/dist/renderer/entries/settings/index.html +7 -5
- package/dist/renderer/entries/workbench-settings/index.html +7 -4
- package/dist/shared/ipc-channels.d.ts +46 -13
- package/dist/shared/ipc-channels.js +60 -14
- package/dist/shared/ipc-schemas.d.ts +118 -0
- package/dist/shared/ipc-schemas.js +133 -0
- package/dist/shared/simulator-route.d.ts +72 -0
- package/dist/shared/simulator-route.js +169 -0
- package/dist/shared/types.d.ts +82 -8
- package/dist/simulator/assets/simulator-CZc88Jeh.js +9 -0
- package/dist/simulator/simulator.html +6 -43
- package/package.json +16 -27
- package/templates/blank/app.js +6 -0
- package/templates/blank/app.json +11 -0
- package/templates/blank/app.wxss +5 -0
- package/templates/blank/pages/index/index.js +6 -0
- package/templates/blank/pages/index/index.json +3 -0
- package/templates/blank/pages/index/index.wxml +3 -0
- package/templates/blank/pages/index/index.wxss +11 -0
- package/templates/blank/project.config.json +13 -0
- package/templates/blank/sitemap.json +9 -0
- package/templates/taro-todo/app.js +1 -0
- package/templates/taro-todo/app.json +1 -0
- package/templates/taro-todo/app.wxss +1 -0
- package/templates/taro-todo/base.wxml +851 -0
- package/templates/taro-todo/common.js +1 -0
- package/templates/taro-todo/comp.js +1 -0
- package/templates/taro-todo/comp.json +1 -0
- package/templates/taro-todo/comp.wxml +2 -0
- package/templates/taro-todo/custom-wrapper.js +1 -0
- package/templates/taro-todo/custom-wrapper.json +1 -0
- package/templates/taro-todo/custom-wrapper.wxml +4 -0
- package/templates/taro-todo/pages/index/index.js +2 -0
- package/templates/taro-todo/pages/index/index.json +1 -0
- package/templates/taro-todo/pages/index/index.wxml +2 -0
- package/templates/taro-todo/pages/index/index.wxss +1 -0
- package/templates/taro-todo/project.config.json +44 -0
- package/templates/taro-todo/runtime.js +1 -0
- package/templates/taro-todo/taro.js +2 -0
- package/templates/taro-todo/utils.wxs +39 -0
- package/templates/taro-todo/vendors.js +2 -0
- package/dist/preload/instrumentation/disposable.d.ts +0 -11
- package/dist/preload/instrumentation/disposable.js +0 -15
- package/dist/preload/windows/main.d.ts +0 -6
- package/dist/preload/windows/main.js +0 -6
- package/dist/renderer/assets/index-D1p6crtf.js +0 -46
- package/dist/renderer/assets/ipc-transport-ClIvDcYY.js +0 -9
- package/dist/renderer/assets/ipc-transport-EiWxu_hG.css +0 -1
- package/dist/renderer/assets/popover-CtXcBJtM.js +0 -2
- package/dist/renderer/assets/select-DMfp49f1.js +0 -2
- package/dist/renderer/assets/settings-api-CY84UMpN.js +0 -2
- package/dist/renderer/assets/workbenchSettings-DjELLnSJ.js +0 -8
- package/dist/simulator/assets/simulator-C1eHXnuq.js +0 -9
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { BrowserWindow } from 'electron';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { mainPreloadPath } from '../../utils/paths.js';
|
|
3
4
|
import { themeBg } from '../../utils/theme.js';
|
|
5
|
+
import { applyNavigationHardening } from '../navigation-hardening.js';
|
|
4
6
|
export async function createSettingsWindow(parent, rendererDir) {
|
|
5
7
|
const win = new BrowserWindow({
|
|
6
8
|
width: 420,
|
|
@@ -10,8 +12,16 @@ export async function createSettingsWindow(parent, rendererDir) {
|
|
|
10
12
|
parent: parent ?? undefined,
|
|
11
13
|
title: '开发工具设置',
|
|
12
14
|
backgroundColor: themeBg(),
|
|
13
|
-
webPreferences: {
|
|
15
|
+
webPreferences: {
|
|
16
|
+
nodeIntegration: false,
|
|
17
|
+
contextIsolation: true,
|
|
18
|
+
sandbox: false,
|
|
19
|
+
preload: mainPreloadPath,
|
|
20
|
+
},
|
|
14
21
|
});
|
|
22
|
+
// Standalone settings window loads mainPreloadPath, so the same
|
|
23
|
+
// navigation rules as the main window apply — see navigation-hardening.ts.
|
|
24
|
+
applyNavigationHardening(win.webContents, rendererDir);
|
|
15
25
|
await win.loadFile(path.join(rendererDir, 'entries/workbench-settings/index.html'));
|
|
16
26
|
return win;
|
|
17
27
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public preload API surface for `@dimina-kit/devtools/preload`.
|
|
3
|
+
*
|
|
4
|
+
* External consumers compose their own simulator <webview> preload by
|
|
5
|
+
* importing the `install*` helpers from here. The built-in simulator
|
|
6
|
+
* preload at `windows/simulator.ts` is one such composition.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: do NOT add main-window preload concerns (contextBridge / ipc
|
|
9
|
+
* exposure) to this file — that lives in `windows/main.ts` and is
|
|
10
|
+
* bundled by esbuild, never re-exported through this barrel.
|
|
11
|
+
*/
|
|
12
|
+
export { installConsoleInstrumentation } from './instrumentation/console.js';
|
|
13
|
+
export { createAppDataSource } from './instrumentation/app-data.js';
|
|
14
|
+
export type { AppDataSnapshot } from './instrumentation/app-data.js';
|
|
15
|
+
export { createWxmlSource } from './instrumentation/wxml.js';
|
|
16
|
+
export { createMiniappSnapshotHost } from './miniapp-snapshot/host.js';
|
|
17
|
+
export type { MiniappSnapshotHost, MiniappSnapshotSource, SnapshotEnvelope, SnapshotSourceId, } from './miniapp-snapshot/types.js';
|
|
18
|
+
export { installSimulatorBridge } from './runtime/bridge.js';
|
|
19
|
+
export { installCustomApisBridge } from './runtime/custom-apis.js';
|
|
20
|
+
export type { DiminaCustomApisBridge } from './runtime/custom-apis.js';
|
|
21
|
+
export { setupApiCompatHook } from './shared/api-compat.js';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public preload API surface for `@dimina-kit/devtools/preload`.
|
|
3
|
+
*
|
|
4
|
+
* External consumers compose their own simulator <webview> preload by
|
|
5
|
+
* importing the `install*` helpers from here. The built-in simulator
|
|
6
|
+
* preload at `windows/simulator.ts` is one such composition.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: do NOT add main-window preload concerns (contextBridge / ipc
|
|
9
|
+
* exposure) to this file — that lives in `windows/main.ts` and is
|
|
10
|
+
* bundled by esbuild, never re-exported through this barrel.
|
|
11
|
+
*/
|
|
12
|
+
export { installConsoleInstrumentation } from './instrumentation/console.js';
|
|
13
|
+
export { createAppDataSource } from './instrumentation/app-data.js';
|
|
14
|
+
export { createWxmlSource } from './instrumentation/wxml.js';
|
|
15
|
+
export { createMiniappSnapshotHost } from './miniapp-snapshot/host.js';
|
|
16
|
+
export { installSimulatorBridge } from './runtime/bridge.js';
|
|
17
|
+
export { installCustomApisBridge } from './runtime/custom-apis.js';
|
|
18
|
+
export { setupApiCompatHook } from './shared/api-compat.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1,3 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import type { MiniappSnapshotSource } from '../miniapp-snapshot/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The AppData snapshot — the full, cumulative panel state.
|
|
4
|
+
*
|
|
5
|
+
* - `bridges` lists every page bridge in chronological (insertion) order, each
|
|
6
|
+
* carrying its page route (`pagePath`), so renderer tabs render in a stable
|
|
7
|
+
* sequence.
|
|
8
|
+
* - `entries` maps `bridgeId → (componentPath | moduleId) → setData state`.
|
|
9
|
+
*/
|
|
10
|
+
export interface AppDataSnapshot {
|
|
11
|
+
bridges: Array<{
|
|
12
|
+
id: string;
|
|
13
|
+
pagePath: string | null;
|
|
14
|
+
}>;
|
|
15
|
+
entries: Record<string, Record<string, unknown>>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The AppData snapshot data source.
|
|
19
|
+
*
|
|
20
|
+
* Instruments `window.Worker` (incoming `message` decoding + outgoing
|
|
21
|
+
* `postMessage` interception) and installs `window.__simulatorHook.appData`,
|
|
22
|
+
* accumulating per-(bridgeId, moduleId) setData state in an internal cache.
|
|
23
|
+
* Every cache mutation — an accepted `ub`/`page_*` worker message, or a
|
|
24
|
+
* `pageUnload` evicting a bridge — calls `emit()` so the `miniappSnapshot`
|
|
25
|
+
* host republishes the full snapshot. The source itself never touches IPC:
|
|
26
|
+
* the host owns push, pull and the install-time publish.
|
|
27
|
+
*
|
|
28
|
+
* It keeps the `__simulatorData.getAppdata()` automation surface working by
|
|
29
|
+
* mirroring the flat cache into the simulator bridge via `setAppDataSnapshot`
|
|
30
|
+
* / `clearAppDataSnapshot`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createAppDataSource(): MiniappSnapshotSource<AppDataSnapshot>;
|
|
3
33
|
//# sourceMappingURL=app-data.d.ts.map
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
1
|
+
import { clearAppDataSnapshot, setAppDataSnapshot, } from '../runtime/bridge.js';
|
|
2
|
+
// dimina runtime emits two kinds of service→main messages relevant to the
|
|
3
|
+
// AppData panel:
|
|
4
|
+
// • update batches `{type:'ub', body:{bridgeId, updates:[{moduleId,data}]}}`
|
|
5
|
+
// where each `data` is a partial setData patch.
|
|
6
|
+
// • instance init: type === instance id (prefixed `page_`/`component_`),
|
|
7
|
+
// body `{bridgeId, path, data}` with the COMPLETE initial state.
|
|
8
|
+
//
|
|
9
|
+
// Policy: surface PAGE entries only. Component entries are dropped — they
|
|
10
|
+
// sometimes flow on a bridge id distinct from their owning page's and never
|
|
11
|
+
// receive pageUnload, which would manifest as ghost tabs in the panel.
|
|
13
12
|
function decodeWorkerMessage(message) {
|
|
14
13
|
let payload = message;
|
|
15
14
|
if (typeof payload === 'string') {
|
|
@@ -20,84 +19,259 @@ function decodeWorkerMessage(message) {
|
|
|
20
19
|
return null;
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
|
-
|
|
24
|
-
if (record?.type !== 'u' || !record.body)
|
|
22
|
+
if (!payload || typeof payload !== 'object')
|
|
25
23
|
return null;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
const record = payload;
|
|
25
|
+
if (record.type === 'ub') {
|
|
26
|
+
const body = record.body;
|
|
27
|
+
if (!body || typeof body !== 'object')
|
|
28
|
+
return null;
|
|
29
|
+
if (typeof body.bridgeId !== 'string' || !Array.isArray(body.updates))
|
|
30
|
+
return null;
|
|
31
|
+
const out = [];
|
|
32
|
+
for (const u of body.updates) {
|
|
33
|
+
if (!u || typeof u.moduleId !== 'string')
|
|
34
|
+
continue;
|
|
35
|
+
if (!u.moduleId.startsWith('page_'))
|
|
36
|
+
continue;
|
|
37
|
+
out.push({ mode: 'patch', bridgeId: body.bridgeId, moduleId: u.moduleId, data: u.data });
|
|
38
|
+
}
|
|
39
|
+
return out.length > 0 ? out : null;
|
|
40
|
+
}
|
|
41
|
+
if (typeof record.type === 'string' && record.type.startsWith('page_')) {
|
|
42
|
+
const body = record.body;
|
|
43
|
+
if (!body || typeof body !== 'object')
|
|
44
|
+
return null;
|
|
45
|
+
if (typeof body.bridgeId !== 'string' || typeof body.path !== 'string')
|
|
46
|
+
return null;
|
|
47
|
+
if (!body.data || typeof body.data !== 'object')
|
|
48
|
+
return null;
|
|
49
|
+
return [{
|
|
50
|
+
mode: 'init',
|
|
39
51
|
bridgeId: body.bridgeId,
|
|
40
|
-
moduleId:
|
|
52
|
+
moduleId: record.type,
|
|
53
|
+
componentPath: body.path,
|
|
41
54
|
data: body.data,
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
return worker;
|
|
55
|
+
}];
|
|
45
56
|
}
|
|
46
|
-
|
|
47
|
-
Object.defineProperty(InstrumentedWorker, 'prototype', {
|
|
48
|
-
value: OriginalWorker.prototype,
|
|
49
|
-
});
|
|
50
|
-
return InstrumentedWorker;
|
|
57
|
+
return null;
|
|
51
58
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
// main→worker direction: container signals page teardown so cache can evict.
|
|
60
|
+
function decodeOutgoingMessage(message) {
|
|
61
|
+
let payload = message;
|
|
62
|
+
if (typeof payload === 'string') {
|
|
63
|
+
try {
|
|
64
|
+
payload = JSON.parse(payload);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!payload || typeof payload !== 'object')
|
|
71
|
+
return null;
|
|
72
|
+
const r = payload;
|
|
73
|
+
if (typeof r.type !== 'string')
|
|
74
|
+
return null;
|
|
75
|
+
return {
|
|
76
|
+
type: r.type,
|
|
77
|
+
bridgeId: typeof r.body?.bridgeId === 'string' ? r.body.bridgeId : undefined,
|
|
67
78
|
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The AppData snapshot data source.
|
|
82
|
+
*
|
|
83
|
+
* Instruments `window.Worker` (incoming `message` decoding + outgoing
|
|
84
|
+
* `postMessage` interception) and installs `window.__simulatorHook.appData`,
|
|
85
|
+
* accumulating per-(bridgeId, moduleId) setData state in an internal cache.
|
|
86
|
+
* Every cache mutation — an accepted `ub`/`page_*` worker message, or a
|
|
87
|
+
* `pageUnload` evicting a bridge — calls `emit()` so the `miniappSnapshot`
|
|
88
|
+
* host republishes the full snapshot. The source itself never touches IPC:
|
|
89
|
+
* the host owns push, pull and the install-time publish.
|
|
90
|
+
*
|
|
91
|
+
* It keeps the `__simulatorData.getAppdata()` automation surface working by
|
|
92
|
+
* mirroring the flat cache into the simulator bridge via `setAppDataSnapshot`
|
|
93
|
+
* / `clearAppDataSnapshot`.
|
|
94
|
+
*/
|
|
95
|
+
export function createAppDataSource() {
|
|
96
|
+
const appDataCache = new Map();
|
|
97
|
+
// Bridges in insertion order — drives the `bridges` array in snapshots so
|
|
98
|
+
// renderer tabs render in a stable, chronological sequence.
|
|
99
|
+
const bridgeOrder = [];
|
|
100
|
+
// Page path per bridge: set from `page_*` init's body.path. Component init
|
|
101
|
+
// also carries a path but it's the component's own path, not the page route.
|
|
102
|
+
const bridgePagePath = new Map();
|
|
103
|
+
let emit = null;
|
|
104
|
+
let installed = false;
|
|
105
|
+
let originalHook;
|
|
106
|
+
let originalDescriptor;
|
|
107
|
+
let OriginalWorker;
|
|
108
|
+
function recordBridge(bridgeId) {
|
|
109
|
+
if (!bridgeOrder.includes(bridgeId))
|
|
110
|
+
bridgeOrder.push(bridgeId);
|
|
111
|
+
}
|
|
112
|
+
function buildSnapshot() {
|
|
113
|
+
const bridges = [];
|
|
114
|
+
for (const id of bridgeOrder) {
|
|
115
|
+
bridges.push({ id, pagePath: bridgePagePath.get(id) ?? null });
|
|
77
116
|
}
|
|
78
|
-
|
|
79
|
-
|
|
117
|
+
const entries = {};
|
|
118
|
+
for (const [key, entry] of appDataCache) {
|
|
119
|
+
const slash = key.indexOf('/');
|
|
120
|
+
if (slash < 0)
|
|
121
|
+
continue;
|
|
122
|
+
const bridgeId = key.slice(0, slash);
|
|
123
|
+
const moduleId = key.slice(slash + 1);
|
|
124
|
+
if (!entries[bridgeId])
|
|
125
|
+
entries[bridgeId] = {};
|
|
126
|
+
const displayKey = entry.componentPath ?? moduleId;
|
|
127
|
+
entries[bridgeId][displayKey] = entry.data;
|
|
80
128
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
129
|
+
return { bridges, entries };
|
|
130
|
+
}
|
|
131
|
+
// Mirror the flat cache into the `__simulatorData.getAppdata()` automation
|
|
132
|
+
// surface so MCP / e2e reads keep working after the snapshot migration.
|
|
133
|
+
function publishSnapshot() {
|
|
134
|
+
const data = {};
|
|
135
|
+
for (const [key, entry] of appDataCache) {
|
|
136
|
+
data[key] = entry.data;
|
|
85
137
|
}
|
|
86
|
-
|
|
87
|
-
|
|
138
|
+
setAppDataSnapshot(data);
|
|
139
|
+
}
|
|
140
|
+
function clearBridge(bridgeId) {
|
|
141
|
+
const prefix = `${bridgeId}/`;
|
|
142
|
+
for (const key of [...appDataCache.keys()]) {
|
|
143
|
+
if (key.startsWith(prefix))
|
|
144
|
+
appDataCache.delete(key);
|
|
88
145
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
146
|
+
const idx = bridgeOrder.indexOf(bridgeId);
|
|
147
|
+
if (idx >= 0)
|
|
148
|
+
bridgeOrder.splice(idx, 1);
|
|
149
|
+
bridgePagePath.delete(bridgeId);
|
|
93
150
|
publishSnapshot();
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
151
|
+
// The eviction is a cache mutation — notify the host so the renderer can
|
|
152
|
+
// drop the evicted bridge's tab immediately.
|
|
153
|
+
emit?.();
|
|
154
|
+
}
|
|
155
|
+
function applyAppData(body) {
|
|
156
|
+
const record = body;
|
|
157
|
+
if (!record?.bridgeId || !record?.moduleId)
|
|
158
|
+
return;
|
|
159
|
+
// R6: drop ub patches whose bridge has never been initialised. dimina
|
|
160
|
+
// dispatches pageUnload to the service worker, which fires onUnload —
|
|
161
|
+
// and onUnload's setData (e.g. console-test's stopTimer) produces a
|
|
162
|
+
// late `ub` that arrives AFTER our clearBridge. Without this gate the
|
|
163
|
+
// late patch would resurrect the unloaded bridge as a ghost tab.
|
|
164
|
+
if (record.mode !== 'init' && !bridgePagePath.has(record.bridgeId))
|
|
165
|
+
return;
|
|
166
|
+
const key = `${record.bridgeId}/${record.moduleId}`;
|
|
167
|
+
const prev = appDataCache.get(key);
|
|
168
|
+
const incoming = (record.data && typeof record.data === 'object'
|
|
169
|
+
? record.data
|
|
170
|
+
: {});
|
|
171
|
+
// init = full-state replace; patch = merge into previous (setData semantics)
|
|
172
|
+
const merged = record.mode === 'init'
|
|
173
|
+
? { ...incoming }
|
|
174
|
+
: { ...(prev?.data ?? {}), ...incoming };
|
|
175
|
+
const componentPath = record.componentPath ?? prev?.componentPath;
|
|
176
|
+
const next = componentPath !== undefined
|
|
177
|
+
? { componentPath, data: merged }
|
|
178
|
+
: { data: merged };
|
|
179
|
+
appDataCache.set(key, next);
|
|
180
|
+
recordBridge(record.bridgeId);
|
|
181
|
+
if (record.mode === 'init'
|
|
182
|
+
&& record.moduleId.startsWith('page_')
|
|
183
|
+
&& record.componentPath) {
|
|
184
|
+
bridgePagePath.set(record.bridgeId, record.componentPath);
|
|
185
|
+
}
|
|
186
|
+
publishSnapshot();
|
|
187
|
+
emit?.();
|
|
188
|
+
}
|
|
189
|
+
function instrumentPostMessage(worker) {
|
|
190
|
+
const orig = worker.postMessage.bind(worker);
|
|
191
|
+
worker.postMessage = function (msg, ...rest) {
|
|
192
|
+
const decoded = decodeOutgoingMessage(msg);
|
|
193
|
+
if (decoded?.type === 'pageUnload' && decoded.bridgeId) {
|
|
194
|
+
clearBridge(decoded.bridgeId);
|
|
195
|
+
}
|
|
196
|
+
return orig(msg, ...rest);
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function createInstrumentedWorker(Original) {
|
|
200
|
+
function InstrumentedWorker(scriptURL, options) {
|
|
201
|
+
const resolvedScriptURL = scriptURL instanceof URL
|
|
202
|
+
? scriptURL
|
|
203
|
+
: new URL(scriptURL, window.location.href);
|
|
204
|
+
const worker = Reflect.construct(Original, [resolvedScriptURL, options], new.target ?? InstrumentedWorker);
|
|
205
|
+
instrumentPostMessage(worker);
|
|
206
|
+
worker.addEventListener('message', (event) => {
|
|
207
|
+
const entries = decodeWorkerMessage(event.data);
|
|
208
|
+
if (!entries)
|
|
209
|
+
return;
|
|
210
|
+
for (const entry of entries) {
|
|
211
|
+
const hookBody = {
|
|
212
|
+
bridgeId: entry.bridgeId,
|
|
213
|
+
moduleId: entry.moduleId,
|
|
214
|
+
data: entry.data,
|
|
215
|
+
mode: entry.mode,
|
|
216
|
+
};
|
|
217
|
+
if (entry.mode === 'init')
|
|
218
|
+
hookBody.componentPath = entry.componentPath;
|
|
219
|
+
window.__simulatorHook?.appData(hookBody);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
return worker;
|
|
223
|
+
}
|
|
224
|
+
Object.setPrototypeOf(InstrumentedWorker, Original);
|
|
225
|
+
Object.defineProperty(InstrumentedWorker, 'prototype', {
|
|
226
|
+
value: Original.prototype,
|
|
227
|
+
});
|
|
228
|
+
return InstrumentedWorker;
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
id: 'appdata',
|
|
232
|
+
snapshot: () => buildSnapshot(),
|
|
233
|
+
start(onChange) {
|
|
234
|
+
if (installed)
|
|
235
|
+
return;
|
|
236
|
+
installed = true;
|
|
237
|
+
emit = onChange;
|
|
238
|
+
originalHook = window.__simulatorHook;
|
|
239
|
+
originalDescriptor = Object.getOwnPropertyDescriptor(window, 'Worker');
|
|
240
|
+
OriginalWorker = window.Worker;
|
|
241
|
+
window.__simulatorHook = {
|
|
242
|
+
appData: (body) => applyAppData(body),
|
|
243
|
+
};
|
|
244
|
+
Object.defineProperty(window, 'Worker', {
|
|
245
|
+
configurable: true,
|
|
246
|
+
writable: true,
|
|
247
|
+
value: createInstrumentedWorker(OriginalWorker),
|
|
248
|
+
});
|
|
249
|
+
},
|
|
250
|
+
dispose() {
|
|
251
|
+
if (!installed)
|
|
252
|
+
return;
|
|
253
|
+
installed = false;
|
|
254
|
+
if (originalDescriptor) {
|
|
255
|
+
Object.defineProperty(window, 'Worker', originalDescriptor);
|
|
256
|
+
}
|
|
257
|
+
else if (OriginalWorker) {
|
|
258
|
+
window.Worker = OriginalWorker;
|
|
259
|
+
}
|
|
260
|
+
if (originalHook) {
|
|
261
|
+
window.__simulatorHook = originalHook;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
delete window.__simulatorHook;
|
|
265
|
+
}
|
|
266
|
+
originalDescriptor = undefined;
|
|
267
|
+
OriginalWorker = undefined;
|
|
268
|
+
originalHook = undefined;
|
|
269
|
+
appDataCache.clear();
|
|
270
|
+
bridgeOrder.length = 0;
|
|
271
|
+
bridgePagePath.clear();
|
|
272
|
+
clearAppDataSnapshot();
|
|
273
|
+
emit = null;
|
|
274
|
+
},
|
|
97
275
|
};
|
|
98
276
|
}
|
|
99
|
-
export function sendAllAppData() {
|
|
100
|
-
publishSnapshot();
|
|
101
|
-
sendToHost(BridgeChannel.AppDataGetAllResponse, simulatorBridge.appdata.data);
|
|
102
|
-
}
|
|
103
277
|
//# sourceMappingURL=app-data.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { installConsoleInstrumentation } from './console.js';
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
2
|
+
export { createAppDataSource, type AppDataSnapshot } from './app-data.js';
|
|
3
|
+
export { createWxmlSource } from './wxml.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { installConsoleInstrumentation } from './console.js';
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
2
|
+
export { createAppDataSource } from './app-data.js';
|
|
3
|
+
export { createWxmlSource } from './wxml.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { type WxmlNode } from '../runtime/bridge.js';
|
|
2
|
+
import type { MiniappSnapshotSource } from '../miniapp-snapshot/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The WXML snapshot data source.
|
|
5
|
+
*
|
|
6
|
+
* Observes the simulator page's Vue tree (retry-attach + MutationObserver +
|
|
7
|
+
* top-level navigation observer), recomputes a normalized {@link WxmlNode}
|
|
8
|
+
* tree on every (debounced) change, stores it internally, and calls `emit()`
|
|
9
|
+
* so the `miniappSnapshot` host publishes it. The source itself never touches
|
|
10
|
+
* IPC — the host owns the push/pull transport and the install-time publish.
|
|
11
|
+
*
|
|
12
|
+
* It keeps the `__simulatorData.getWxml()` automation surface working by
|
|
13
|
+
* mirroring each computed tree into the simulator bridge via
|
|
14
|
+
* `setWxmlSnapshot` / `clearWxmlSnapshot`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createWxmlSource(): MiniappSnapshotSource<WxmlNode | null>;
|
|
5
17
|
//# sourceMappingURL=wxml.d.ts.map
|