@dimina-kit/devtools 0.3.2-dev.20260525152421 → 0.3.2-dev.20260610082053
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 +43 -40
- package/dist/main/api.d.ts +0 -1
- package/dist/main/api.js +5 -1
- package/dist/main/app/app.d.ts +15 -5
- package/dist/main/app/app.js +247 -110
- package/dist/main/app/bootstrap.d.ts +16 -0
- package/dist/main/app/bootstrap.js +20 -0
- package/dist/main/app/launch.d.ts +8 -4
- package/dist/main/app/launch.js +9 -4
- package/dist/main/index.bundle.js +6607 -2102
- package/dist/main/index.js +9 -1
- package/dist/main/ipc/app.d.ts +1 -1
- package/dist/main/ipc/bridge-router.d.ts +61 -0
- package/dist/main/ipc/bridge-router.js +1300 -0
- package/dist/main/ipc/panels.d.ts +1 -1
- package/dist/main/ipc/panels.js +6 -2
- package/dist/main/ipc/popover.d.ts +1 -1
- package/dist/main/ipc/project-fs.d.ts +57 -0
- package/dist/main/ipc/project-fs.js +448 -0
- package/dist/main/ipc/projects.d.ts +1 -1
- package/dist/main/ipc/session.d.ts +1 -1
- package/dist/main/ipc/settings.d.ts +1 -1
- package/dist/main/ipc/simulator-module.d.ts +6 -0
- package/dist/main/ipc/simulator-module.js +11 -1
- package/dist/main/ipc/simulator.d.ts +2 -2
- package/dist/main/ipc/simulator.js +49 -5
- package/dist/main/ipc/toolbar.d.ts +1 -1
- package/dist/main/ipc/views.d.ts +19 -0
- package/dist/main/ipc/views.js +65 -0
- package/dist/main/runtime/devtools-backend.d.ts +17 -0
- package/dist/main/runtime/devtools-backend.js +49 -0
- package/dist/main/runtime/miniapp-runtime.d.ts +39 -0
- package/dist/main/runtime/miniapp-runtime.js +17 -0
- package/dist/main/services/automation/exec.d.ts +27 -2
- package/dist/main/services/automation/exec.js +37 -3
- package/dist/main/services/automation/handlers/app.js +127 -11
- package/dist/main/services/automation/handlers/page.js +36 -19
- package/dist/main/services/automation/index.js +40 -13
- package/dist/main/services/automation/wait-active-page.d.ts +56 -0
- package/dist/main/services/automation/wait-active-page.js +71 -0
- package/dist/main/services/console-forward/index.d.ts +36 -0
- package/dist/main/services/console-forward/index.js +81 -0
- package/dist/main/services/dimina-resource-server.d.ts +7 -0
- package/dist/main/services/dimina-resource-server.js +99 -0
- package/dist/main/services/elements-forward/index.d.ts +66 -0
- package/dist/main/services/elements-forward/index.js +583 -0
- package/dist/main/services/layout/index.d.ts +23 -1
- package/dist/main/services/layout/index.js +28 -3
- package/dist/main/services/mcp/index.d.ts +1 -0
- package/dist/main/services/mcp/index.js +3 -0
- package/dist/main/services/mcp/server.d.ts +1 -1
- package/dist/main/services/mcp/server.js +1 -1
- package/dist/main/services/mcp/target-manager.d.ts +35 -0
- package/dist/main/services/mcp/target-manager.js +63 -1
- package/dist/main/services/mcp/tools/context-tools.js +15 -1
- package/dist/main/services/module.d.ts +1 -1
- package/dist/main/services/network-forward/index.d.ts +190 -0
- package/dist/main/services/network-forward/index.js +765 -0
- package/dist/main/services/notifications/renderer-notifier.d.ts +11 -0
- package/dist/main/services/notifications/renderer-notifier.js +7 -1
- package/dist/main/services/render-inspect/index.d.ts +41 -0
- package/dist/main/services/render-inspect/index.js +88 -0
- package/dist/main/services/safe-area/index.d.ts +17 -0
- package/dist/main/services/safe-area/index.js +59 -0
- package/dist/main/services/service-host-pool/pool.d.ts +197 -0
- package/dist/main/services/service-host-pool/pool.js +364 -0
- package/dist/main/services/simulator/custom-apis.d.ts +34 -0
- package/dist/main/services/simulator/custom-apis.js +22 -0
- package/dist/main/services/simulator-appdata/index.d.ts +35 -0
- package/dist/main/services/simulator-appdata/index.js +71 -0
- package/dist/main/services/simulator-current-page/index.d.ts +24 -0
- package/dist/main/services/simulator-current-page/index.js +19 -0
- package/dist/main/services/simulator-storage/index.d.ts +37 -2
- package/dist/main/services/simulator-storage/index.js +209 -32
- package/dist/main/services/simulator-storage/service-storage-ops.d.ts +40 -0
- package/dist/main/services/simulator-storage/service-storage-ops.js +67 -0
- package/dist/main/services/simulator-temp-files/fs-channels.js +1 -1
- package/dist/main/services/simulator-temp-files/index.d.ts +1 -1
- package/dist/main/services/simulator-temp-files/index.js +1 -1
- package/dist/main/services/simulator-temp-files/request-handler.js +1 -1
- package/dist/main/services/simulator-wxml/index.d.ts +29 -0
- package/dist/main/services/simulator-wxml/index.js +28 -0
- package/dist/main/services/update/update-manager.d.ts +10 -0
- package/dist/main/services/update/update-manager.js +16 -3
- package/dist/main/services/views/devtools-tabs.d.ts +47 -0
- package/dist/main/services/views/devtools-tabs.js +95 -0
- package/dist/main/services/views/view-manager.d.ts +142 -4
- package/dist/main/services/views/view-manager.js +909 -17
- package/dist/main/services/workbench-context.d.ts +66 -1
- package/dist/main/services/workbench-context.js +6 -1
- package/dist/main/services/workspace/workspace-service.d.ts +8 -0
- package/dist/main/services/workspace/workspace-service.js +12 -0
- package/dist/main/utils/ipc-registry.d.ts +11 -2
- package/dist/main/utils/ipc-registry.js +63 -3
- package/dist/main/utils/paths.d.ts +15 -0
- package/dist/main/utils/paths.js +19 -0
- package/dist/main/utils/sender-policy.d.ts +9 -3
- package/dist/main/utils/sender-policy.js +18 -4
- package/dist/main/utils/theme.d.ts +1 -1
- package/dist/main/utils/theme.js +1 -1
- package/dist/main/windows/main-window/create.d.ts +0 -6
- package/dist/main/windows/main-window/create.js +11 -59
- package/dist/main/windows/main-window/events.d.ts +1 -1
- package/dist/main/windows/main-window/events.js +1 -1
- package/dist/main/windows/service-host-window/create.d.ts +52 -0
- package/dist/main/windows/service-host-window/create.js +112 -0
- package/dist/native-host/common/common.js +368 -0
- package/dist/native-host/container/pageFrame.css +1 -0
- package/dist/native-host/render/render.js +9334 -0
- package/dist/native-host/service/service.js +6 -0
- package/dist/preload/index.d.ts +2 -0
- package/dist/preload/index.js +6 -0
- package/dist/preload/instrumentation/app-data.d.ts +18 -20
- package/dist/preload/instrumentation/app-data.js +23 -160
- package/dist/preload/instrumentation/wxml-extract.d.ts +1 -1
- package/dist/preload/instrumentation/wxml-extract.js +1 -1
- package/dist/preload/runtime/bridge.d.ts +3 -8
- package/dist/preload/runtime/bridge.js +2 -32
- package/dist/preload/runtime/custom-apis.js +20 -17
- package/dist/preload/runtime/host-toolbar-advertiser.d.ts +27 -0
- package/dist/preload/runtime/host-toolbar-advertiser.js +55 -0
- package/dist/preload/runtime/main-api-runner.d.ts +9 -0
- package/dist/preload/runtime/main-api-runner.js +85 -0
- package/dist/preload/runtime/native-host.d.ts +43 -0
- package/dist/preload/runtime/native-host.js +83 -0
- package/dist/preload/shared/expose.d.ts +10 -5
- package/dist/preload/shared/expose.js +29 -11
- package/dist/preload/shared/sid-registry.d.ts +11 -0
- package/dist/preload/shared/sid-registry.js +38 -0
- package/dist/preload/windows/host-toolbar.cjs +161 -0
- package/dist/preload/windows/host-toolbar.cjs.map +7 -0
- package/dist/preload/windows/host-toolbar.d.ts +2 -0
- package/dist/preload/windows/host-toolbar.js +12 -0
- package/dist/preload/windows/main.cjs +1939 -0
- package/dist/preload/windows/main.cjs.map +4 -4
- package/dist/preload/windows/simulator.cjs +925 -0
- package/dist/preload/windows/simulator.cjs.map +7 -0
- package/dist/preload/windows/simulator.js +243 -573
- package/dist/render-host/pageFrame.html +29 -0
- package/dist/render-host/preload.cjs +154 -0
- package/dist/render-host/render-inspect.js +295 -0
- package/dist/renderer/assets/abap-DiwvWnMr.js +2 -0
- package/dist/renderer/assets/apex-CmtZjKlf.js +2 -0
- package/dist/renderer/assets/azcli-DL2My_i-.js +2 -0
- package/dist/renderer/assets/bat-B-nC98wG.js +2 -0
- package/dist/renderer/assets/bicep-Ju5MwOgh.js +3 -0
- package/dist/renderer/assets/cameligo-8Eu1TyBr.js +2 -0
- package/dist/renderer/assets/chunk-DPI0Y_ll.js +1 -0
- package/dist/renderer/assets/clojure-u-RpMkH3.js +2 -0
- package/dist/renderer/assets/codicon-ngg6Pgfi.ttf +0 -0
- package/dist/renderer/assets/coffee-CdA7bbTe.js +2 -0
- package/dist/renderer/assets/constants-CLAQX6VZ.js +2 -0
- package/dist/renderer/assets/cpp-CzNFP8ks.js +2 -0
- package/dist/renderer/assets/csharp-j1LThmcE.js +2 -0
- package/dist/renderer/assets/csp-CLRC61y6.js +2 -0
- package/dist/renderer/assets/css-r6rC_7P2.js +4 -0
- package/dist/renderer/assets/css.worker-DyDu5ynT.js +90 -0
- package/dist/renderer/assets/cssMode-BCBgxrnA.js +2 -0
- package/dist/renderer/assets/cypher-CW08XVUh.js +2 -0
- package/dist/renderer/assets/dart-Cs9aL5T_.js +2 -0
- package/dist/renderer/assets/dockerfile-BWM0M184.js +2 -0
- package/dist/renderer/assets/ecl-MJJuer5P.js +2 -0
- package/dist/renderer/assets/editor-CWI9TnMM.css +1 -0
- package/dist/renderer/assets/editor.api2-BTaYmRq7.js +873 -0
- package/dist/renderer/assets/editor.worker-Dpt_xPrs.js +27 -0
- package/dist/renderer/assets/elixir-D2AIuXqn.js +2 -0
- package/dist/renderer/assets/flow9-B2H24giC.js +2 -0
- package/dist/renderer/assets/freemarker2-DGDGzimW.js +4 -0
- package/dist/renderer/assets/fsharp-CMk2OIJN.js +2 -0
- package/dist/renderer/assets/go-BrMkuJg0.js +2 -0
- package/dist/renderer/assets/graphql-PSR1UKGv.js +2 -0
- package/dist/renderer/assets/handlebars-bOHhw3EG.js +2 -0
- package/dist/renderer/assets/hcl-DAQrbDOW.js +2 -0
- package/dist/renderer/assets/html-BMyuX0_c.js +2 -0
- package/dist/renderer/assets/html.worker-IWNXhnIC.js +503 -0
- package/dist/renderer/assets/htmlMode-DR4kXJ7l.js +2 -0
- package/dist/renderer/assets/index-CcJKzatF.js +50 -0
- package/dist/renderer/assets/ini-0TG5BxW0.js +2 -0
- package/dist/renderer/assets/input-QGx6FFX1.js +2 -0
- package/dist/renderer/assets/ipc-transport-BT4QYQqu.css +1 -0
- package/dist/renderer/assets/{ipc-transport-BzPzxPwf.js → ipc-transport-DvZvwK-Z.js} +5 -5
- package/dist/renderer/assets/java-rgorz17v.js +2 -0
- package/dist/renderer/assets/javascript-Bu-tl1P7.js +2 -0
- package/dist/renderer/assets/json.worker-c4h5s80L.js +59 -0
- package/dist/renderer/assets/jsonMode-MQV_ffLR.js +8 -0
- package/dist/renderer/assets/julia-C8VMdHm8.js +2 -0
- package/dist/renderer/assets/kotlin-AhhC4Qhm.js +2 -0
- package/dist/renderer/assets/less-Cgca25AP.js +3 -0
- package/dist/renderer/assets/lexon-D0GHdBaw.js +2 -0
- package/dist/renderer/assets/liquid-ClkfOvhB.js +2 -0
- package/dist/renderer/assets/lspLanguageFeatures-Bke_4Ie9.js +5 -0
- package/dist/renderer/assets/lua-DmRsNG-P.js +2 -0
- package/dist/renderer/assets/m3-BgL5dNKT.js +2 -0
- package/dist/renderer/assets/markdown-BuJfycGS.js +2 -0
- package/dist/renderer/assets/mdx-RZdUskPu.js +2 -0
- package/dist/renderer/assets/mips-C9m_93PR.js +2 -0
- package/dist/renderer/assets/monaco.contribution-B7rUMaEv.js +3 -0
- package/dist/renderer/assets/msdax-CpFHC9OI.js +2 -0
- package/dist/renderer/assets/mysql-qFvltsqN.js +2 -0
- package/dist/renderer/assets/objective-c-Bnmr858J.js +2 -0
- package/dist/renderer/assets/pascal-WP0_D5AO.js +2 -0
- package/dist/renderer/assets/pascaligo-Blom4Rij.js +2 -0
- package/dist/renderer/assets/perl-B-vk8g64.js +2 -0
- package/dist/renderer/assets/pgsql-Cgvz6v67.js +2 -0
- package/dist/renderer/assets/php-8a3Lrw9m.js +2 -0
- package/dist/renderer/assets/pla-DuFqEZ8V.js +2 -0
- package/dist/renderer/assets/popover-BOH1If1J.js +2 -0
- package/dist/renderer/assets/postiats-DkLtSgkp.js +2 -0
- package/dist/renderer/assets/powerquery-BJ1aNepW.js +2 -0
- package/dist/renderer/assets/powershell-rE98k687.js +2 -0
- package/dist/renderer/assets/protobuf-CUheFacr.js +3 -0
- package/dist/renderer/assets/pug-LDcAMD8w.js +2 -0
- package/dist/renderer/assets/python-Cobrm_-8.js +2 -0
- package/dist/renderer/assets/qsharp-DUKSQoR1.js +2 -0
- package/dist/renderer/assets/r-D-QApv87.js +2 -0
- package/dist/renderer/assets/razor-BEUIQFNJ.js +2 -0
- package/dist/renderer/assets/redis-SXdDyWR9.js +2 -0
- package/dist/renderer/assets/redshift-Y6lsCryn.js +2 -0
- package/dist/renderer/assets/restructuredtext-edObr9a8.js +2 -0
- package/dist/renderer/assets/ruby-CNnUfF-8.js +2 -0
- package/dist/renderer/assets/rust-IHUZWzBr.js +2 -0
- package/dist/renderer/assets/sb-DrUvY44N.js +2 -0
- package/dist/renderer/assets/scala-B4hbXGLM.js +2 -0
- package/dist/renderer/assets/scheme-BGrd12j3.js +2 -0
- package/dist/renderer/assets/scss-x5G1ES4U.js +4 -0
- package/dist/renderer/assets/select-C7JQ8G5N.js +2 -0
- package/dist/renderer/assets/settings-DpAbTJyF.js +2 -0
- package/dist/renderer/assets/{settings-api-BXCw9vOZ.js → settings-api-RD2IZF53.js} +2 -2
- package/dist/renderer/assets/shell-DOehe2Y8.js +2 -0
- package/dist/renderer/assets/solidity-BeRvcwWV.js +2 -0
- package/dist/renderer/assets/sophia-DZbkUNjy.js +2 -0
- package/dist/renderer/assets/sparql-B7_oi5-h.js +2 -0
- package/dist/renderer/assets/sql-CTlsFWVE.js +2 -0
- package/dist/renderer/assets/st-DJVEJdPE.js +2 -0
- package/dist/renderer/assets/swift-CwhT3fYa.js +2 -0
- package/dist/renderer/assets/systemverilog-BQN63pkN.js +2 -0
- package/dist/renderer/assets/tcl-DqwfpskA.js +2 -0
- package/dist/renderer/assets/ts.worker-BwM5Ha3L.js +67720 -0
- package/dist/renderer/assets/tsMode-BHa7dl9v.js +12 -0
- package/dist/renderer/assets/twig-BiyenUgc.js +2 -0
- package/dist/renderer/assets/typescript-15aT0Yj8.js +2 -0
- package/dist/renderer/assets/typespec-CWOJribt.js +2 -0
- package/dist/renderer/assets/vb-Cq5F87m3.js +2 -0
- package/dist/renderer/assets/wgsl-BAvW2lVr.js +299 -0
- package/dist/renderer/assets/workbenchSettings-CNJX4Qna.js +8 -0
- package/dist/renderer/assets/workers-CRBS0W-v.js +2 -0
- package/dist/renderer/assets/xml-bR2Zh-HV.js +2 -0
- package/dist/renderer/assets/yaml-Bdk54Qrb.js +2 -0
- package/dist/renderer/entries/main/index.html +29 -6
- package/dist/renderer/entries/popover/index.html +7 -6
- package/dist/renderer/entries/settings/index.html +6 -5
- package/dist/renderer/entries/workbench-settings/index.html +6 -5
- package/dist/service-host/preload.cjs +254 -0
- package/dist/service-host/service.html +10 -0
- package/dist/service-host/sourcemap-rewrite.cjs +58 -0
- package/dist/service-host/sync-api-patch.js +20 -0
- package/dist/service-host/sync-impls/menu-button.js +16 -0
- package/dist/service-host/sync-impls/storage.js +50 -0
- package/dist/service-host/sync-impls/system-info.js +54 -0
- package/dist/shared/appdata-accumulator.d.ts +95 -0
- package/dist/shared/appdata-accumulator.js +213 -0
- package/dist/shared/bridge-channels.d.ts +364 -0
- package/dist/shared/bridge-channels.js +54 -0
- package/dist/shared/constants.d.ts +0 -4
- package/dist/shared/constants.js +0 -4
- package/dist/shared/ipc-channels.d.ts +108 -1
- package/dist/shared/ipc-channels.js +127 -10
- package/dist/shared/ipc-schemas.d.ts +65 -2
- package/dist/shared/ipc-schemas.js +79 -3
- package/dist/shared/open-in-editor.d.ts +71 -0
- package/dist/shared/open-in-editor.js +138 -0
- package/dist/shared/simulator-api-metadata.d.ts +21 -0
- package/dist/shared/simulator-api-metadata.js +23 -0
- package/dist/shared/types.d.ts +2 -2
- package/dist/shared/vpath.d.ts +42 -0
- package/dist/shared/vpath.js +105 -0
- package/dist/simulator/assets/device-shell-DsdcNEkt.css +1 -0
- package/dist/simulator/assets/device-shell-vwYSOVrh.js +2 -0
- package/dist/simulator/assets/jsx-runtime-P6ZegaOf.js +2 -0
- package/dist/simulator/assets/simulator-DddliUL5.js +10 -0
- package/dist/simulator/assets/simulator-mini-app-BDNu5n26.js +2 -0
- package/dist/simulator/device-shell/menu-button-geometry.js +8 -0
- package/dist/simulator/simulator.html +2 -112
- package/package.json +9 -9
- package/dist/main/utils/disposable.d.ts +0 -18
- package/dist/main/utils/disposable.js +0 -67
- package/dist/renderer/assets/constants-DI382mTP.js +0 -2
- package/dist/renderer/assets/index-4lkyF644.js +0 -46
- package/dist/renderer/assets/input-D4byFOLS.js +0 -2
- package/dist/renderer/assets/ipc-transport-DqbRdZNO.css +0 -1
- package/dist/renderer/assets/popover-cxKrg_os.js +0 -2
- package/dist/renderer/assets/select-BgSkkdHW.js +0 -2
- package/dist/renderer/assets/settings-oD2K1jdT.js +0 -2
- package/dist/renderer/assets/workbenchSettings-CTNBpTft.js +0 -8
- package/dist/simulator/assets/simulator-CVOFTpSj.js +0 -9
|
@@ -1,12 +1,33 @@
|
|
|
1
|
-
import { SimulatorChannel, SimulatorCustomApiChannel } from '../../shared/ipc-channels.js';
|
|
2
|
-
import {
|
|
1
|
+
import { ServiceHostChannel, SimulatorChannel, SimulatorCustomApiChannel } from '../../shared/ipc-channels.js';
|
|
2
|
+
import { SimulatorAttachNativeSchema, SimulatorCustomApiInvokeSchema, SimulatorResizeSchema, SimulatorSetDeviceInfoSchema, SimulatorSetNativeBoundsSchema, SimulatorSetVisibleSchema, } from '../../shared/ipc-schemas.js';
|
|
3
3
|
import { validate } from '../utils/ipc-schema.js';
|
|
4
4
|
import { IpcRegistry } from '../utils/ipc-registry.js';
|
|
5
|
+
/**
|
|
6
|
+
* Map the renderer's logical device metrics onto the subset of a
|
|
7
|
+
* HostEnvSnapshot the service-host window's `getSystemInfoSync` consumes.
|
|
8
|
+
* `windowHeight` excludes the status bar (the page area); `windowWidth` has no
|
|
9
|
+
* horizontal chrome. Zoom is intentionally absent — it is a display scale, not
|
|
10
|
+
* a logical-size change.
|
|
11
|
+
*/
|
|
12
|
+
function deviceInfoToHostEnv(d) {
|
|
13
|
+
return {
|
|
14
|
+
brand: d.brand,
|
|
15
|
+
model: d.model,
|
|
16
|
+
system: d.system,
|
|
17
|
+
platform: d.platform,
|
|
18
|
+
pixelRatio: d.pixelRatio,
|
|
19
|
+
screenWidth: d.screenWidth,
|
|
20
|
+
screenHeight: d.screenHeight,
|
|
21
|
+
windowWidth: d.screenWidth,
|
|
22
|
+
windowHeight: Math.max(0, d.screenHeight - d.statusBarHeight),
|
|
23
|
+
statusBarHeight: d.statusBarHeight,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
5
26
|
export function registerSimulatorIpc(ctx) {
|
|
6
27
|
return new IpcRegistry(ctx.senderPolicy)
|
|
7
|
-
.handle(SimulatorChannel.
|
|
8
|
-
const [
|
|
9
|
-
ctx.views.
|
|
28
|
+
.handle(SimulatorChannel.AttachNative, (_, ...args) => {
|
|
29
|
+
const [simulatorUrl, simWidth] = validate(SimulatorChannel.AttachNative, SimulatorAttachNativeSchema, args);
|
|
30
|
+
ctx.views.attachNativeSimulator(simulatorUrl, simWidth);
|
|
10
31
|
})
|
|
11
32
|
.handle(SimulatorChannel.Detach, () => {
|
|
12
33
|
ctx.views.detachSimulator();
|
|
@@ -14,6 +35,29 @@ export function registerSimulatorIpc(ctx) {
|
|
|
14
35
|
.handle(SimulatorChannel.Resize, (_, ...args) => {
|
|
15
36
|
const [simWidth] = validate(SimulatorChannel.Resize, SimulatorResizeSchema, args);
|
|
16
37
|
ctx.views.resize(simWidth);
|
|
38
|
+
})
|
|
39
|
+
.handle(SimulatorChannel.SetNativeBounds, (_, ...args) => {
|
|
40
|
+
const [p] = validate(SimulatorChannel.SetNativeBounds, SimulatorSetNativeBoundsSchema, args);
|
|
41
|
+
ctx.views.setNativeSimulatorViewBounds(p);
|
|
42
|
+
})
|
|
43
|
+
.handle(SimulatorChannel.SetDeviceInfo, (_, ...args) => {
|
|
44
|
+
const [device] = validate(SimulatorChannel.SetDeviceInfo, SimulatorSetDeviceInfoSchema, args);
|
|
45
|
+
// Cache the selection (rides the next NATIVE_HOST_ENABLED reply for a
|
|
46
|
+
// race-free DeviceShell init) and push DEVICE_CHANGE to the live simulator
|
|
47
|
+
// WCV so the DeviceShell resizes the bezel + re-renders status bar / notch.
|
|
48
|
+
ctx.bridge?.setDevice(device);
|
|
49
|
+
// Re-push the CSS env(safe-area-inset-*) override to attached render-host
|
|
50
|
+
// guests so notch-aware page layout updates without a reload.
|
|
51
|
+
ctx.views.reapplySafeArea(device);
|
|
52
|
+
// Live-update the running service-host window's host-env snapshot so
|
|
53
|
+
// `wx.getSystemInfoSync()` reflects the selected device without a relaunch.
|
|
54
|
+
// The service-host preload mutates `__diminaSpawnContext` in place;
|
|
55
|
+
// `getSystemInfoSync` reads it fresh on each call. No service window yet
|
|
56
|
+
// (pre-spawn) → no-op.
|
|
57
|
+
const serviceWc = ctx.bridge?.getServiceWc();
|
|
58
|
+
if (serviceWc && !serviceWc.isDestroyed()) {
|
|
59
|
+
serviceWc.send(ServiceHostChannel.HostEnvUpdate, deviceInfoToHostEnv(device));
|
|
60
|
+
}
|
|
17
61
|
})
|
|
18
62
|
.handle(SimulatorChannel.SetVisible, (_, ...args) => {
|
|
19
63
|
const [visible, simWidth] = validate(SimulatorChannel.SetVisible, SimulatorSetVisibleSchema, args);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
2
|
-
import type { Disposable } from '
|
|
2
|
+
import type { Disposable } from '@dimina-kit/electron-deck/main';
|
|
3
3
|
export declare function registerToolbarIpc(ctx: Pick<WorkbenchContext, 'toolbar' | 'senderPolicy'>): Disposable;
|
|
4
4
|
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
2
|
+
import type { Disposable } from '@dimina-kit/electron-deck/main';
|
|
3
|
+
/**
|
|
4
|
+
* Renderer-driven overlay bounds.
|
|
5
|
+
*
|
|
6
|
+
* The main window's React layout is the source of truth for where the
|
|
7
|
+
* editor view and the simulator's Chromium DevTools overlay live on
|
|
8
|
+
* screen. A `ResizeObserver` in the renderer watches each placeholder
|
|
9
|
+
* `<div>` and publishes its client rect (in CSS pixels, relative to the
|
|
10
|
+
* window's content area) through these channels. The view manager caches
|
|
11
|
+
* the latest payload per kind and applies it to the WebContentsView.
|
|
12
|
+
*
|
|
13
|
+
* Width / height = 0 is the canonical "overlay hidden" signal — the React
|
|
14
|
+
* panel is collapsed or the tab is not selected. The view manager removes
|
|
15
|
+
* the child view from the contentView but keeps the WebContents alive so
|
|
16
|
+
* subsequent re-shows skip the OpenSumi DI bootstrap.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerViewsIpc(ctx: Pick<WorkbenchContext, 'views' | 'senderPolicy'>): Disposable;
|
|
19
|
+
//# sourceMappingURL=views.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ipcMain } from 'electron';
|
|
2
|
+
import { ViewChannel } from '../../shared/ipc-channels.js';
|
|
3
|
+
import { ViewBoundsSchema, HostToolbarAdvertiseHeightSchema, } from '../../shared/ipc-schemas.js';
|
|
4
|
+
import { validate } from '../utils/ipc-schema.js';
|
|
5
|
+
import { IpcRegistry } from '../utils/ipc-registry.js';
|
|
6
|
+
/**
|
|
7
|
+
* Renderer-driven overlay bounds.
|
|
8
|
+
*
|
|
9
|
+
* The main window's React layout is the source of truth for where the
|
|
10
|
+
* editor view and the simulator's Chromium DevTools overlay live on
|
|
11
|
+
* screen. A `ResizeObserver` in the renderer watches each placeholder
|
|
12
|
+
* `<div>` and publishes its client rect (in CSS pixels, relative to the
|
|
13
|
+
* window's content area) through these channels. The view manager caches
|
|
14
|
+
* the latest payload per kind and applies it to the WebContentsView.
|
|
15
|
+
*
|
|
16
|
+
* Width / height = 0 is the canonical "overlay hidden" signal — the React
|
|
17
|
+
* panel is collapsed or the tab is not selected. The view manager removes
|
|
18
|
+
* the child view from the contentView but keeps the WebContents alive so
|
|
19
|
+
* subsequent re-shows skip the OpenSumi DI bootstrap.
|
|
20
|
+
*/
|
|
21
|
+
export function registerViewsIpc(ctx) {
|
|
22
|
+
const registry = new IpcRegistry(ctx.senderPolicy)
|
|
23
|
+
.handle(ViewChannel.SimulatorDevtoolsBounds, (_event, ...args) => {
|
|
24
|
+
const [bounds] = validate(ViewChannel.SimulatorDevtoolsBounds, ViewBoundsSchema, args);
|
|
25
|
+
ctx.views.setSimulatorDevtoolsBounds(bounds);
|
|
26
|
+
})
|
|
27
|
+
// Host-controllable toolbar: forward anchor (the MAIN renderer measures the
|
|
28
|
+
// placeholder rect → toolbar WCV bounds). invoke, mirroring
|
|
29
|
+
// SimulatorDevtoolsBounds. Sender is the trusted main renderer.
|
|
30
|
+
.handle(ViewChannel.HostToolbarBounds, (_event, ...args) => {
|
|
31
|
+
const [bounds] = validate(ViewChannel.HostToolbarBounds, ViewBoundsSchema, args);
|
|
32
|
+
ctx.views.setHostToolbarBounds(bounds);
|
|
33
|
+
});
|
|
34
|
+
// Reverse size-advertiser: the toolbar WCV's OWN renderer sends this, and the
|
|
35
|
+
// host loads ARBITRARY content into that WCV. We DELIBERATELY do NOT add the
|
|
36
|
+
// toolbar wc to the global sender policy — that would trust it for ALL ~72
|
|
37
|
+
// IpcRegistry channels (project-fs / session / settings / panels
|
|
38
|
+
// executeJavaScript / storage …), a large blast radius if the host content is
|
|
39
|
+
// ever compromised. Instead this is a RAW `ipcMain.on` gated on the EXACT
|
|
40
|
+
// current host-toolbar wc id — the same precise-sender-id trust model the
|
|
41
|
+
// simulator custom-api bridge uses (view-manager `attachNativeCustomApiBridge`).
|
|
42
|
+
// The host content can reach ONLY this one channel, carrying only a
|
|
43
|
+
// non-negative integer height.
|
|
44
|
+
const onAdvertiseHeight = (event, ...args) => {
|
|
45
|
+
if (event.sender.id !== ctx.views.getHostToolbarWebContentsId())
|
|
46
|
+
return;
|
|
47
|
+
let extent;
|
|
48
|
+
try {
|
|
49
|
+
;
|
|
50
|
+
[{ extent }] = validate(ViewChannel.HostToolbarAdvertiseHeight, HostToolbarAdvertiseHeightSchema, args);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return; // malformed payload from the host's own content — drop it
|
|
54
|
+
}
|
|
55
|
+
ctx.views.setHostToolbarHeight(extent);
|
|
56
|
+
};
|
|
57
|
+
ipcMain.on(ViewChannel.HostToolbarAdvertiseHeight, onAdvertiseHeight);
|
|
58
|
+
return {
|
|
59
|
+
dispose() {
|
|
60
|
+
void registry.dispose();
|
|
61
|
+
ipcMain.removeListener(ViewChannel.HostToolbarAdvertiseHeight, onAdvertiseHeight);
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=views.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RuntimeBackend } from '@dimina-kit/electron-deck';
|
|
2
|
+
import type { WorkbenchAppConfig } from '../../shared/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adapts the devtools runtime into a {@link RuntimeBackend} the framework
|
|
5
|
+
* (`@dimina-kit/electron-deck`) orchestrates. The framework owns the process
|
|
6
|
+
* lifecycle gate (whenReady) + wire/trust primitives; the backend supplies the
|
|
7
|
+
* full devtools assembly — reusing the exact same `runDevtoolsBootstrap` / `createDevtoolsRuntime`
|
|
8
|
+
* assembly bodies (extracted from the former createWorkbenchApp), so the app is
|
|
9
|
+
* byte-identical to the pre-extraction behaviour (no behavioural re-creation).
|
|
10
|
+
*
|
|
11
|
+
* v2 scope: the backend owns window creation (the framework skips its own when a
|
|
12
|
+
* backend is present), so `assemble` ignores the framework `runtime` and builds
|
|
13
|
+
* the real devtools main window itself. Trust/frame unification and surfacing
|
|
14
|
+
* the runtime facade are deferred (see framework-extraction-v2.md §7).
|
|
15
|
+
*/
|
|
16
|
+
export declare function createDevtoolsBackend(config?: WorkbenchAppConfig): RuntimeBackend;
|
|
17
|
+
//# sourceMappingURL=devtools-backend.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { runDevtoolsBootstrap, createDevtoolsRuntime } from '../app/app.js';
|
|
2
|
+
import { registerAppLifecycle } from '../app/lifecycle.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adapts the devtools runtime into a {@link RuntimeBackend} the framework
|
|
5
|
+
* (`@dimina-kit/electron-deck`) orchestrates. The framework owns the process
|
|
6
|
+
* lifecycle gate (whenReady) + wire/trust primitives; the backend supplies the
|
|
7
|
+
* full devtools assembly — reusing the exact same `runDevtoolsBootstrap` / `createDevtoolsRuntime`
|
|
8
|
+
* assembly bodies (extracted from the former createWorkbenchApp), so the app is
|
|
9
|
+
* byte-identical to the pre-extraction behaviour (no behavioural re-creation).
|
|
10
|
+
*
|
|
11
|
+
* v2 scope: the backend owns window creation (the framework skips its own when a
|
|
12
|
+
* backend is present), so `assemble` ignores the framework `runtime` and builds
|
|
13
|
+
* the real devtools main window itself. Trust/frame unification and surfacing
|
|
14
|
+
* the runtime facade are deferred (see framework-extraction-v2.md §7).
|
|
15
|
+
*/
|
|
16
|
+
export function createDevtoolsBackend(config = {}) {
|
|
17
|
+
// Hoisted so `onShutdown` can reach the assembled context (assigned by `assemble`).
|
|
18
|
+
let instance = null;
|
|
19
|
+
return {
|
|
20
|
+
// The backend builds the devtools main window itself (framework skips its own).
|
|
21
|
+
// Its only construction-time needs are the host preload + `sandbox:false`
|
|
22
|
+
// (main-window/create.ts) and wrapping contentView in a `View` container.
|
|
23
|
+
// NOTE: `ownsWindows` is NOT structurally required — the framework's
|
|
24
|
+
// `mainWindowWebPreferences()` + `onMainWindowCreated()` hooks can supply both,
|
|
25
|
+
// and the project close→back lifecycle maps onto the Window facade's
|
|
26
|
+
// `onClose`/`newSession` (probe-validated). Retained for now; migrating to
|
|
27
|
+
// `runtime.windows.main` is the documented next step. (The `persist:simulator`
|
|
28
|
+
// partition is a fixed session used by child WCVs, not main-window state.)
|
|
29
|
+
ownsWindows: true,
|
|
30
|
+
// Pre-ready: app name / CDP port / CSP / privileged scheme — must run before
|
|
31
|
+
// the framework awaits app.whenReady().
|
|
32
|
+
beforeReady: () => {
|
|
33
|
+
runDevtoolsBootstrap(config);
|
|
34
|
+
},
|
|
35
|
+
// Setup (post-whenReady): app lifecycle (window-all-closed → quit) + the
|
|
36
|
+
// full devtools assembly.
|
|
37
|
+
assemble: async () => {
|
|
38
|
+
registerAppLifecycle();
|
|
39
|
+
instance = await createDevtoolsRuntime(config);
|
|
40
|
+
},
|
|
41
|
+
// Dispose the devtools context during the framework's deterministic shutdown
|
|
42
|
+
// (app.on('will-quit') → shutdown() → runShutdownCleanup(), awaited once).
|
|
43
|
+
// Without this, the compile session (a child process, torn down by
|
|
44
|
+
// closeProject) and the IPC registry would leak on exit. The framework awaits
|
|
45
|
+
// this hook, so teardown is no longer a best-effort before-quit reach-around.
|
|
46
|
+
onShutdown: () => instance?.dispose(),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=devtools-backend.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MiniappRuntime — the stable, host-facing contract surface (foundation.md §3
|
|
3
|
+
* "MiniappRuntime 契约" layer, P4).
|
|
4
|
+
*
|
|
5
|
+
* `WorkbenchContext` is the rich internal main-process state: runtime kernel +
|
|
6
|
+
* host config + trust/infra plumbing, all mixed. Downstream hosts (qdmp, a
|
|
7
|
+
* re-skin of devtools that depends ONLY on devtools) don't consume that whole
|
|
8
|
+
* grab-bag — they drive the miniapp KERNEL: the view lifecycle (including the
|
|
9
|
+
* host-controllable toolbar at `views.hostToolbar`), the cross-wc bridge, the
|
|
10
|
+
* workspace, the custom-API registry, async storage, the appdata tap, the
|
|
11
|
+
* connection layer, and the main→renderer notifier.
|
|
12
|
+
*
|
|
13
|
+
* This module NAMES that kernel as an explicit, documented contract so the
|
|
14
|
+
* surface a host depends on is compiler-enforced and versionable, instead of
|
|
15
|
+
* "whatever fields of WorkbenchContext you happen to reach for". Config inputs
|
|
16
|
+
* (appName / panels / apiNamespaces / branding / project templates) are the
|
|
17
|
+
* host's INPUT, not part of the runtime it consumes; trust/infra
|
|
18
|
+
* (senderPolicy / trustedWindowSenderIds / registry / toolbar action-table)
|
|
19
|
+
* stay internal.
|
|
20
|
+
*
|
|
21
|
+
* Derived via `Pick<WorkbenchContext, …>` so the field TYPES never drift from
|
|
22
|
+
* the real implementation — `MiniappRuntime` is a view onto `WorkbenchContext`,
|
|
23
|
+
* and the conformance assertion below fails to compile the moment the context
|
|
24
|
+
* stops satisfying the contract.
|
|
25
|
+
*
|
|
26
|
+
* The host-controllable toolbar WebContentsView hangs off `views.hostToolbar`
|
|
27
|
+
* (a ViewManager concern), so it's reachable through the contract WITHOUT a 9th
|
|
28
|
+
* top-level member — `runtime.views.hostToolbar.loadURL(...)`.
|
|
29
|
+
*/
|
|
30
|
+
import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
31
|
+
/** The stable miniapp-kernel surface a downstream host (qdmp) consumes. */
|
|
32
|
+
export type MiniappRuntime = Pick<WorkbenchContext, 'views' | 'bridge' | 'workspace' | 'simulatorApis' | 'storageApi' | 'appData' | 'connections' | 'notify'>;
|
|
33
|
+
/**
|
|
34
|
+
* Project a full `WorkbenchContext` down to its `MiniappRuntime` view. Hosts
|
|
35
|
+
* call this to get a value typed to exactly the contract — no wider access to
|
|
36
|
+
* the context's internals leaks through.
|
|
37
|
+
*/
|
|
38
|
+
export declare function asMiniappRuntime(ctx: WorkbenchContext): MiniappRuntime;
|
|
39
|
+
//# sourceMappingURL=miniapp-runtime.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project a full `WorkbenchContext` down to its `MiniappRuntime` view. Hosts
|
|
3
|
+
* call this to get a value typed to exactly the contract — no wider access to
|
|
4
|
+
* the context's internals leaks through.
|
|
5
|
+
*/
|
|
6
|
+
export function asMiniappRuntime(ctx) {
|
|
7
|
+
return ctx;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Compile-time conformance guard: if `WorkbenchContext` ever stops structurally
|
|
11
|
+
* satisfying `MiniappRuntime` (a kernel field renamed / its type narrowed),
|
|
12
|
+
* THIS line fails `tsc`, catching the contract break at build time. The runtime
|
|
13
|
+
* value is unused.
|
|
14
|
+
*/
|
|
15
|
+
const _conformance = (ctx) => ctx;
|
|
16
|
+
void _conformance;
|
|
17
|
+
//# sourceMappingURL=miniapp-runtime.js.map
|
|
@@ -1,10 +1,35 @@
|
|
|
1
|
+
import type { WebContents } from 'electron';
|
|
1
2
|
import type { WorkbenchContext } from '../workbench-context.js';
|
|
2
3
|
import type { ElementRef } from './shared.js';
|
|
3
4
|
export declare function getSimulator(ctx: WorkbenchContext): Electron.WebContents | null;
|
|
4
5
|
export declare function evalInSim<T = unknown>(ctx: WorkbenchContext, expression: string): Promise<T>;
|
|
5
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Native-host: the active page's DOM lives directly in the visible render-host
|
|
8
|
+
* <webview> guest (no iframe), so element/page automation must run in that
|
|
9
|
+
* WebContents' main world. Returns null on the default dimina-fe arch, where the
|
|
10
|
+
* page lives inside an iframe of the simulator guest and automation goes through
|
|
11
|
+
* `evalInSim` + `inIframe` instead.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getActivePageWc(ctx: WorkbenchContext): WebContents | null;
|
|
14
|
+
/**
|
|
15
|
+
* Wrap guest code so `_doc` is the page document. Under native-host the render
|
|
16
|
+
* guest IS the page document — no iframe lookup (cf. `inIframe`, which digs into
|
|
17
|
+
* the simulator guest's last iframe). Mirrors `inIframe`'s `_doc` contract so the
|
|
18
|
+
* same handler `body` strings work in both arches unchanged.
|
|
19
|
+
*/
|
|
20
|
+
export declare function wrapGuest(code: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Run page-level automation code against the right document for the current arch:
|
|
23
|
+
* - native-host with a live active render guest → run in that guest's main
|
|
24
|
+
* world via `wrapGuest` (the guest IS the page document).
|
|
25
|
+
* - otherwise (default dimina-fe, or native-host with no active guest yet) →
|
|
26
|
+
* fall back to `evalInSim(inIframe(code))` (the existing simulator-iframe path).
|
|
27
|
+
* The `code` is the same body either arch expects — it reads `_doc`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function evalInActivePage<T = unknown>(ctx: WorkbenchContext, code: string): Promise<T>;
|
|
30
|
+
/** Build JS that locates an element by selector+index inside the active page document. */
|
|
6
31
|
export declare function buildElAccess(ref: ElementRef, varName?: string): string;
|
|
7
|
-
/** Run `body` inside the active page
|
|
32
|
+
/** Run `body` inside the active page document with `varName` bound to the element at `ref`. */
|
|
8
33
|
export declare function evalInElement<T = unknown>(ctx: WorkbenchContext, ref: ElementRef, body: string, varName?: string): Promise<T>;
|
|
9
34
|
/** Wrap code to run inside the active page iframe (last iframe in the stack). */
|
|
10
35
|
export declare function inIframe(code: string): string;
|
|
@@ -10,13 +10,47 @@ export async function evalInSim(ctx, expression) {
|
|
|
10
10
|
throw new Error('Simulator not connected');
|
|
11
11
|
return sim.executeJavaScript(expression);
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Native-host: the active page's DOM lives directly in the visible render-host
|
|
15
|
+
* <webview> guest (no iframe), so element/page automation must run in that
|
|
16
|
+
* WebContents' main world. Returns null on the default dimina-fe arch, where the
|
|
17
|
+
* page lives inside an iframe of the simulator guest and automation goes through
|
|
18
|
+
* `evalInSim` + `inIframe` instead.
|
|
19
|
+
*/
|
|
20
|
+
export function getActivePageWc(ctx) {
|
|
21
|
+
return ctx.bridge?.isNativeHost() ? ctx.bridge.getActiveRenderWc() : null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Wrap guest code so `_doc` is the page document. Under native-host the render
|
|
25
|
+
* guest IS the page document — no iframe lookup (cf. `inIframe`, which digs into
|
|
26
|
+
* the simulator guest's last iframe). Mirrors `inIframe`'s `_doc` contract so the
|
|
27
|
+
* same handler `body` strings work in both arches unchanged.
|
|
28
|
+
*/
|
|
29
|
+
export function wrapGuest(code) {
|
|
30
|
+
return `(() => { const _doc = document; return (function(){ ${code} })() })()`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Run page-level automation code against the right document for the current arch:
|
|
34
|
+
* - native-host with a live active render guest → run in that guest's main
|
|
35
|
+
* world via `wrapGuest` (the guest IS the page document).
|
|
36
|
+
* - otherwise (default dimina-fe, or native-host with no active guest yet) →
|
|
37
|
+
* fall back to `evalInSim(inIframe(code))` (the existing simulator-iframe path).
|
|
38
|
+
* The `code` is the same body either arch expects — it reads `_doc`.
|
|
39
|
+
*/
|
|
40
|
+
export async function evalInActivePage(ctx, code) {
|
|
41
|
+
const renderWc = getActivePageWc(ctx);
|
|
42
|
+
if (renderWc) {
|
|
43
|
+
return renderWc.executeJavaScript(wrapGuest(code));
|
|
44
|
+
}
|
|
45
|
+
return evalInSim(ctx, inIframe(code));
|
|
46
|
+
}
|
|
47
|
+
/** Build JS that locates an element by selector+index inside the active page document. */
|
|
14
48
|
export function buildElAccess(ref, varName = 'el') {
|
|
15
49
|
return `const ${varName} = _doc.querySelectorAll(${JSON.stringify(ref.selector)})[${ref.index}]`;
|
|
16
50
|
}
|
|
17
|
-
/** Run `body` inside the active page
|
|
51
|
+
/** Run `body` inside the active page document with `varName` bound to the element at `ref`. */
|
|
18
52
|
export function evalInElement(ctx, ref, body, varName = 'el') {
|
|
19
|
-
return
|
|
53
|
+
return evalInActivePage(ctx, `${buildElAccess(ref, varName)}\n${body}`);
|
|
20
54
|
}
|
|
21
55
|
/** Wrap code to run inside the active page iframe (last iframe in the stack). */
|
|
22
56
|
export function inIframe(code) {
|
|
@@ -1,12 +1,41 @@
|
|
|
1
|
-
import { evalInSim,
|
|
2
|
-
import { parseLocationRoute } from '../../../../shared/simulator-route.js';
|
|
1
|
+
import { evalInSim, getActivePageWc, getSimulator } from '../exec.js';
|
|
2
|
+
import { decodePageSpec, parseLocationRoute } from '../../../../shared/simulator-route.js';
|
|
3
|
+
import { waitForActivePage } from '../wait-active-page.js';
|
|
3
4
|
export const appHandlers = {};
|
|
5
|
+
/** Nav methods that take a `{ url }` arg (navigateBack is handled separately). */
|
|
6
|
+
const NAV_METHODS = new Set(['navigateTo', 'redirectTo', 'reLaunch', 'switchTab']);
|
|
4
7
|
// -- App domain --
|
|
5
8
|
async function readRoute(ctx) {
|
|
6
9
|
const { search } = await evalInSim(ctx, `({ search: location.search })`);
|
|
7
10
|
return parseLocationRoute(search);
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Native-host: derive the visible page's `{ pagePath, query }` from the active
|
|
14
|
+
* render guest. The page-stack depth isn't surfaced by the bridge handle, so the
|
|
15
|
+
* native page stack is reported as the single active page (see App.getPageStack).
|
|
16
|
+
* Reads the guest's own `location.search` — the render-host preload encodes
|
|
17
|
+
* `pagePath` (+ per-page query) there.
|
|
18
|
+
*/
|
|
19
|
+
async function readNativeActivePage(ctx) {
|
|
20
|
+
const renderWc = getActivePageWc(ctx);
|
|
21
|
+
if (!renderWc)
|
|
22
|
+
return null;
|
|
23
|
+
const search = await renderWc
|
|
24
|
+
.executeJavaScript('location.search')
|
|
25
|
+
.catch(() => '');
|
|
26
|
+
const params = new URLSearchParams(search.startsWith('?') ? search.slice(1) : search);
|
|
27
|
+
const pagePath = params.get('pagePath') || '';
|
|
28
|
+
if (!pagePath)
|
|
29
|
+
return null;
|
|
30
|
+
// The guest URL carries the full page spec on `pagePath` (may include `?k=v`).
|
|
31
|
+
const spec = decodePageSpec(pagePath);
|
|
32
|
+
return { pagePath: spec.pagePath, query: spec.query };
|
|
33
|
+
}
|
|
9
34
|
appHandlers['App.getCurrentPage'] = async (ctx) => {
|
|
35
|
+
if (ctx.bridge?.isNativeHost()) {
|
|
36
|
+
const page = await readNativeActivePage(ctx);
|
|
37
|
+
return { pageId: 1, path: page?.pagePath ?? '', query: page?.query ?? {} };
|
|
38
|
+
}
|
|
10
39
|
const route = await readRoute(ctx);
|
|
11
40
|
const iframeCount = await evalInSim(ctx, `document.querySelectorAll('iframe').length`);
|
|
12
41
|
return {
|
|
@@ -16,8 +45,28 @@ appHandlers['App.getCurrentPage'] = async (ctx) => {
|
|
|
16
45
|
};
|
|
17
46
|
};
|
|
18
47
|
appHandlers['App.getPageStack'] = async (ctx) => {
|
|
19
|
-
const route = await readRoute(ctx);
|
|
20
48
|
const pageStack = [];
|
|
49
|
+
if (ctx.bridge?.isNativeHost()) {
|
|
50
|
+
// DeviceShell reports its full ordered stack (bottom→top) via PAGE_STACK;
|
|
51
|
+
// the bridge stores it. Report that. Before the first signal (or in a mock
|
|
52
|
+
// without the accessor) fall back to the single visible page.
|
|
53
|
+
const stack = ctx.bridge.getPageStack?.();
|
|
54
|
+
if (stack && stack.length > 0) {
|
|
55
|
+
stack.forEach((entry, i) => {
|
|
56
|
+
pageStack.push({
|
|
57
|
+
pageId: i + 1,
|
|
58
|
+
path: entry.pagePath,
|
|
59
|
+
query: Object.fromEntries(Object.entries(entry.query ?? {}).map(([k, v]) => [k, String(v)])),
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
return { pageStack };
|
|
63
|
+
}
|
|
64
|
+
const page = await readNativeActivePage(ctx);
|
|
65
|
+
if (page)
|
|
66
|
+
pageStack.push({ pageId: 1, path: page.pagePath, query: page.query });
|
|
67
|
+
return { pageStack };
|
|
68
|
+
}
|
|
69
|
+
const route = await readRoute(ctx);
|
|
21
70
|
if (!route)
|
|
22
71
|
return { pageStack };
|
|
23
72
|
// Mirrors upstream HashRouter.parseSearch: `[entry]` or `[entry, current]`.
|
|
@@ -30,24 +79,88 @@ appHandlers['App.getPageStack'] = async (ctx) => {
|
|
|
30
79
|
appHandlers['App.callWxMethod'] = async (ctx, params) => {
|
|
31
80
|
const method = params.method;
|
|
32
81
|
const args = params.args || [];
|
|
82
|
+
// NATIVE-HOST: the authoritative `wx.*` runs in the hidden service-host
|
|
83
|
+
// window (the simulator / render-guest context has no `wx`). Run EVERY method
|
|
84
|
+
// there — nav so the page stack goes through the real runtime path, and
|
|
85
|
+
// non-nav (setNavigationBarTitle / getSystemInfoSync / tabBar APIs / …) so
|
|
86
|
+
// they don't fall through to the default-arch eval-in-simulator path below,
|
|
87
|
+
// which throws "wx is not defined" under native-host.
|
|
88
|
+
if (ctx.bridge?.isNativeHost()) {
|
|
89
|
+
const serviceWc = ctx.bridge.getServiceWc();
|
|
90
|
+
if (!serviceWc)
|
|
91
|
+
throw new Error('Service host not connected');
|
|
92
|
+
if (NAV_METHODS.has(method) || method === 'navigateBack') {
|
|
93
|
+
const arg = method === 'navigateBack'
|
|
94
|
+
? (args[0] ?? { delta: 1 })
|
|
95
|
+
: (args[0] ?? {});
|
|
96
|
+
// Capture the active page BEFORE navigating so we can wait for it to
|
|
97
|
+
// actually change, instead of blindly sleeping a fixed duration.
|
|
98
|
+
const since = ctx.bridge.getActiveBridgeId();
|
|
99
|
+
await serviceWc.executeJavaScript(`wx.${method}(${JSON.stringify(arg)})`);
|
|
100
|
+
// Wait for the bridge's `activePage` signal (the new page mounted), with a
|
|
101
|
+
// timeout floor = the old blind-wait duration. Resolves as soon as the new
|
|
102
|
+
// page is active — far faster than the fixed sleep for the common case —
|
|
103
|
+
// and still bounded for edges (e.g. switchTab back to an already-mounted
|
|
104
|
+
// tab keeps the same bridgeId, so it falls through to the floor, same as
|
|
105
|
+
// the old behaviour). See wait-active-page.ts.
|
|
106
|
+
const timeoutMs = method === 'navigateBack' ? 1500 : 2000;
|
|
107
|
+
await waitForActivePage(ctx.bridge, {
|
|
108
|
+
since,
|
|
109
|
+
timeoutMs,
|
|
110
|
+
onTimeout: () => console.warn(`[automation] ${method}: activePage signal not seen within ${timeoutMs}ms — proceeding on timeout floor`),
|
|
111
|
+
});
|
|
112
|
+
return { result: undefined };
|
|
113
|
+
}
|
|
114
|
+
// Non-nav: invoke on the service-host wx and return its (sync) value. Async
|
|
115
|
+
// methods that report via a success callback return undefined here, same as
|
|
116
|
+
// the default-arch generic path below.
|
|
117
|
+
const argsStr = args.map((a) => JSON.stringify(a)).join(', ');
|
|
118
|
+
const result = await serviceWc.executeJavaScript(`
|
|
119
|
+
new Promise((resolve, reject) => {
|
|
120
|
+
try {
|
|
121
|
+
if (typeof wx === 'undefined' || typeof wx[${JSON.stringify(method)}] !== 'function') {
|
|
122
|
+
reject(new Error('wx.' + ${JSON.stringify(method)} + ' is not a function in service host'))
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
resolve(wx.${method}(${argsStr}))
|
|
126
|
+
} catch (e) { reject(e && e.message ? e.message : String(e)) }
|
|
127
|
+
})
|
|
128
|
+
`);
|
|
129
|
+
return { result };
|
|
130
|
+
}
|
|
33
131
|
// For navigation methods, handle specially via DOM click / wx.* on the iframe
|
|
34
132
|
if (['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].includes(method)) {
|
|
35
133
|
const opts = args[0];
|
|
36
134
|
const url = opts?.url;
|
|
37
135
|
if (url) {
|
|
38
136
|
const cleanUrl = url.startsWith('/') ? url : `/${url}`;
|
|
39
|
-
// Try clicking a matching DOM element first
|
|
40
|
-
|
|
137
|
+
// Try clicking a matching DOM element first. We can't use `inIframe`
|
|
138
|
+
// here — tabBar mini-apps keep prior tabs' iframes around (display:none)
|
|
139
|
+
// and `iframes[length-1]` ends up being the hidden, freshly-cached tab
|
|
140
|
+
// rather than the visible one. Pick the visible iframe explicitly.
|
|
141
|
+
const clicked = await evalInSim(ctx, `(() => {
|
|
142
|
+
const iframes = Array.from(document.querySelectorAll('iframe'))
|
|
143
|
+
const visible = iframes.filter((f) => {
|
|
144
|
+
const cs = window.getComputedStyle(f)
|
|
145
|
+
if (cs.display === 'none' || cs.visibility === 'hidden') return false
|
|
146
|
+
const rect = f.getBoundingClientRect()
|
|
147
|
+
return rect.width > 0 && rect.height > 0
|
|
148
|
+
})
|
|
149
|
+
const target = visible[visible.length - 1] || iframes[iframes.length - 1]
|
|
150
|
+
if (!target || !target.contentDocument) return false
|
|
41
151
|
const path = ${JSON.stringify(cleanUrl)}
|
|
42
|
-
const el = Array.from(
|
|
43
|
-
.find(e => e.getAttribute('data-path') === path)
|
|
152
|
+
const el = Array.from(target.contentDocument.querySelectorAll('[data-path]'))
|
|
153
|
+
.find((e) => e.getAttribute('data-path') === path)
|
|
44
154
|
if (el) { el.click(); return true }
|
|
45
155
|
return false
|
|
46
|
-
`)
|
|
156
|
+
})()`).catch(() => false);
|
|
47
157
|
if (!clicked) {
|
|
48
|
-
// Fallback
|
|
49
|
-
//
|
|
50
|
-
//
|
|
158
|
+
// Fallback cascade for navigation methods:
|
|
159
|
+
// 1. iframe wx[method] — page-iframe surface (older arch, where
|
|
160
|
+
// jdimina installed `window.wx` on each page frame).
|
|
161
|
+
// 2. top-window wx[method] — set up by simulator/main.tsx, binds
|
|
162
|
+
// MiniApp.switchTab / navigateTo / etc. Required for switchTab
|
|
163
|
+
// since page-iframe wx (jdimina) doesn't expose it.
|
|
51
164
|
const apiName = JSON.stringify(method);
|
|
52
165
|
const urlJson = JSON.stringify(cleanUrl);
|
|
53
166
|
await evalInSim(ctx, `(() => {
|
|
@@ -60,6 +173,9 @@ appHandlers['App.callWxMethod'] = async (ctx, params) => {
|
|
|
60
173
|
}
|
|
61
174
|
} catch (_) {}
|
|
62
175
|
}
|
|
176
|
+
if (typeof wx !== 'undefined' && wx && typeof wx[${apiName}] === 'function') {
|
|
177
|
+
wx[${apiName}]({ url: ${urlJson} })
|
|
178
|
+
}
|
|
63
179
|
})()`);
|
|
64
180
|
}
|
|
65
181
|
// Wait for navigation
|