@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,6 +1,11 @@
|
|
|
1
1
|
import type { BrowserWindow } from 'electron';
|
|
2
2
|
import type { CompilationAdapter, WorkbenchConfig } from '../../shared/types.js';
|
|
3
|
-
import {
|
|
3
|
+
import type { BridgeRouterHandle } from '../ipc/bridge-router.js';
|
|
4
|
+
import type { ConsoleForwarder } from './console-forward/index.js';
|
|
5
|
+
import type { NetworkForwarder } from './network-forward/index.js';
|
|
6
|
+
import type { AppDataTap } from './simulator-appdata/index.js';
|
|
7
|
+
import type { StorageApi } from './simulator-storage/index.js';
|
|
8
|
+
import { DisposableRegistry, type ConnectionRegistry } from '@dimina-kit/electron-deck/main';
|
|
4
9
|
import type { SenderPolicy } from '../utils/ipc-registry.js';
|
|
5
10
|
import { type RendererNotifier } from './notifications/renderer-notifier.js';
|
|
6
11
|
import { type ViewManager } from './views/view-manager.js';
|
|
@@ -97,6 +102,66 @@ export interface WorkbenchContext {
|
|
|
97
102
|
toolbar: ToolbarStore;
|
|
98
103
|
/** Aggregates dispose handlers for every IPC handler, listener, watcher, and CDP session registered by the workbench. */
|
|
99
104
|
registry: DisposableRegistry;
|
|
105
|
+
/**
|
|
106
|
+
* Per-webContents connection registry. Each trusted webContents (main window,
|
|
107
|
+
* overlay views, native simulator/render guests) is one `Connection` that
|
|
108
|
+
* owns the resources tied to its lifetime and tears them down deterministically
|
|
109
|
+
* on `webContents.once('destroyed')` (hard) or `reset(id)` (soft pool reuse).
|
|
110
|
+
* The substrate for connection-scoped resource ownership — see
|
|
111
|
+
* packages/electron-deck/docs/foundation.md §4. Domain services consume it by
|
|
112
|
+
* `own()`-ing their per-endpoint resources and observing `reset`/`closed`.
|
|
113
|
+
*/
|
|
114
|
+
connections: ConnectionRegistry;
|
|
115
|
+
/**
|
|
116
|
+
* Accessor over the bridge-router's private state, set by `installBridgeRouter`.
|
|
117
|
+
* Lets other main services (simulator-storage, automation, appdata) resolve
|
|
118
|
+
* live render/service WebContents and the native-host flag without owning
|
|
119
|
+
* router state. Undefined until the bridge router is installed.
|
|
120
|
+
*/
|
|
121
|
+
bridge?: BridgeRouterHandle;
|
|
122
|
+
/**
|
|
123
|
+
* Native-host AppData tap, set by `setupSimulatorAppData` (app.ts) when
|
|
124
|
+
* native-host is on. bridge-router feeds it the service→render setData stream
|
|
125
|
+
* + page evictions so the AppData panel can be sourced from main. Undefined on
|
|
126
|
+
* the default dimina-fe path (which sniffs setData via a Worker hook).
|
|
127
|
+
*/
|
|
128
|
+
appData?: AppDataTap;
|
|
129
|
+
/**
|
|
130
|
+
* Native-host async-storage runtime hook, set by `setupSimulatorStorage` when
|
|
131
|
+
* native-host is on. bridge-router routes async `wx.setStorage`/etc. here so
|
|
132
|
+
* they hit the same service-host `file://` store as the sync APIs (one origin).
|
|
133
|
+
* Undefined on the default dimina-fe path (storage handled in the guest).
|
|
134
|
+
*/
|
|
135
|
+
storageApi?: StorageApi;
|
|
136
|
+
/**
|
|
137
|
+
* Native-host console sink. The render-host / service-host guest preloads
|
|
138
|
+
* monkeypatch `console.*` and post each entry to main as a `consoleLog`
|
|
139
|
+
* container message; bridge-router routes those here. Owned by the
|
|
140
|
+
* `ConsoleForwarder` (set in `installBridgeRouter`), whose `emit` fans every
|
|
141
|
+
* entry out to subscribers (automation WS) AND mirrors render-layer entries
|
|
142
|
+
* into the service host's own console for the embedded DevTools.
|
|
143
|
+
*/
|
|
144
|
+
guestConsole?: {
|
|
145
|
+
emit(entry: unknown): void;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Always-on console fan-out, set by `installBridgeRouter`. Other services
|
|
149
|
+
* (automation) call `subscribe` to receive every guest console entry instead
|
|
150
|
+
* of each clobbering `ctx.guestConsole`. Undefined until the bridge router is
|
|
151
|
+
* installed.
|
|
152
|
+
*/
|
|
153
|
+
consoleForwarder?: ConsoleForwarder;
|
|
154
|
+
/**
|
|
155
|
+
* Native-host network forwarder, set in app bootstrap. Attaches the CDP
|
|
156
|
+
* debugger to the simulator WCV (where `wx.request`/`downloadFile`/`uploadFile`
|
|
157
|
+
* run) and injects its raw Network.* CDP events into the DevTools FRONT-END wc
|
|
158
|
+
* (`window.DevToolsAPI.dispatchMessage`) so the native Network tab renders them;
|
|
159
|
+
* falls back to a `[网络]` service-host console line when the front-end is
|
|
160
|
+
* unavailable. The ViewManager calls `attachSimulator` + `setDevtoolsHost` from
|
|
161
|
+
* `attachNativeSimulator` once the simulator WCV + DevTools host exist.
|
|
162
|
+
* Undefined until bootstrap wires it.
|
|
163
|
+
*/
|
|
164
|
+
networkForward?: NetworkForwarder;
|
|
100
165
|
}
|
|
101
166
|
/**
|
|
102
167
|
* Inputs for `createWorkbenchContext`. The scalar config fields it shares with
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DisposableRegistry } from '
|
|
1
|
+
import { createConnectionRegistry, DisposableRegistry, } from '@dimina-kit/electron-deck/main';
|
|
2
2
|
import { createWorkbenchSenderPolicy } from '../utils/sender-policy.js';
|
|
3
3
|
import { defaultAdapter } from './default-adapter.js';
|
|
4
4
|
import { createRendererNotifier, } from './notifications/renderer-notifier.js';
|
|
@@ -32,6 +32,11 @@ export function createWorkbenchContext(opts) {
|
|
|
32
32
|
brandingProvider: opts.brandingProvider,
|
|
33
33
|
};
|
|
34
34
|
ctx.registry = new DisposableRegistry();
|
|
35
|
+
// Empty connection registry as a first-class context field. Connections are
|
|
36
|
+
// acquired by real wiring points (app bootstrap, view-manager endpoints),
|
|
37
|
+
// NOT here — the constructor stays side-effect-free so focused unit tests can
|
|
38
|
+
// build a context with a minimal mainWindow fake.
|
|
39
|
+
ctx.connections = createConnectionRegistry();
|
|
35
40
|
ctx.trustedWindowSenderIds = new Map();
|
|
36
41
|
ctx.simulatorApis = createSimulatorApiRegistry();
|
|
37
42
|
ctx.toolbar = createToolbarStore();
|
|
@@ -38,6 +38,14 @@ export interface WorkspaceService {
|
|
|
38
38
|
appInfo: unknown;
|
|
39
39
|
} | null;
|
|
40
40
|
getProjectPath(): string;
|
|
41
|
+
/**
|
|
42
|
+
* The project path most recently torn down by `closeProject`, or '' if none
|
|
43
|
+
* since the last `openProject`. Lets the project-fs sandbox accept an
|
|
44
|
+
* in-flight write (debounced/teardown flush) that targets the just-closed
|
|
45
|
+
* project even though `getProjectPath()` has already been cleared. Reset to
|
|
46
|
+
* '' on the next `openProject` so it never accumulates stale roots.
|
|
47
|
+
*/
|
|
48
|
+
getLastClosedProjectPath(): string;
|
|
41
49
|
hasActiveSession(): boolean;
|
|
42
50
|
captureThumbnail(projectPath: string): Promise<string | null>;
|
|
43
51
|
getThumbnail(projectPath: string): Promise<string | null>;
|
|
@@ -6,6 +6,10 @@ import { loadWorkbenchSettings } from '../settings/index.js';
|
|
|
6
6
|
export function createWorkspaceService(ctx) {
|
|
7
7
|
let currentSession = null;
|
|
8
8
|
let currentProjectPath = '';
|
|
9
|
+
// The last project path cleared by `closeProject`; consumed by project-fs to
|
|
10
|
+
// accept an in-flight write that targets the just-closed project. Reset at
|
|
11
|
+
// the start of every `openProject` so it never accumulates a stale root.
|
|
12
|
+
let lastClosedProjectPath = '';
|
|
9
13
|
function sendStatus(status, message, hotReload) {
|
|
10
14
|
ctx.notify.projectStatus(hotReload ? { status, message, hotReload: true } : { status, message });
|
|
11
15
|
}
|
|
@@ -61,6 +65,9 @@ export function createWorkspaceService(ctx) {
|
|
|
61
65
|
clearSimulatorServicewechatReferer();
|
|
62
66
|
await disposeSession();
|
|
63
67
|
currentProjectPath = '';
|
|
68
|
+
// A fresh open starts a clean sandbox window — drop any previously
|
|
69
|
+
// recorded last-closed root so it can't accept writes after this point.
|
|
70
|
+
lastClosedProjectPath = '';
|
|
64
71
|
// Reject obviously broken projects up front so we never spin up a
|
|
65
72
|
// compile/server that the simulator will then fetch asset-by-asset.
|
|
66
73
|
// Without this guard, deleted recent-list entries and typo'd CLI paths
|
|
@@ -109,11 +116,16 @@ export function createWorkspaceService(ctx) {
|
|
|
109
116
|
async closeProject() {
|
|
110
117
|
clearSimulatorServicewechatReferer();
|
|
111
118
|
await disposeSession();
|
|
119
|
+
// Record the root being torn down BEFORE clearing it, so a teardown/
|
|
120
|
+
// debounced write already in flight can still be accepted against it.
|
|
121
|
+
if (currentProjectPath !== '')
|
|
122
|
+
lastClosedProjectPath = currentProjectPath;
|
|
112
123
|
currentProjectPath = '';
|
|
113
124
|
ctx.views.disposeAll();
|
|
114
125
|
},
|
|
115
126
|
getSession: () => currentSession,
|
|
116
127
|
getProjectPath: () => currentProjectPath,
|
|
128
|
+
getLastClosedProjectPath: () => lastClosedProjectPath,
|
|
117
129
|
hasActiveSession: () => currentSession !== null,
|
|
118
130
|
async captureThumbnail(projectPath) {
|
|
119
131
|
const wc = ctx.views.getSimulatorWebContents();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { WebContents } from 'electron';
|
|
1
|
+
import type { IpcMainEvent, WebContents } from 'electron';
|
|
2
2
|
import { ipcMain } from 'electron';
|
|
3
|
-
import { type Disposable } from '
|
|
3
|
+
import { type Disposable } from '@dimina-kit/electron-deck/main';
|
|
4
4
|
type HandleFn = Parameters<typeof ipcMain.handle>[1];
|
|
5
5
|
type ListenerFn = Parameters<typeof ipcMain.on>[1];
|
|
6
6
|
/**
|
|
@@ -32,6 +32,15 @@ export declare class IpcRegistry implements Disposable {
|
|
|
32
32
|
private registry;
|
|
33
33
|
constructor(policy?: SenderPolicy | undefined);
|
|
34
34
|
handle(channel: string, fn: HandleFn): this;
|
|
35
|
+
/**
|
|
36
|
+
* Register a SYNCHRONOUS `ipcRenderer.sendSync` handler. Unlike {@link on}
|
|
37
|
+
* (fire-and-forget), the renderer is blocked until we set `event.returnValue`,
|
|
38
|
+
* so `fn` MUST be synchronous and return the value to hand back. The sender
|
|
39
|
+
* policy gates it like {@link handle}; a rejected sender or a thrown error
|
|
40
|
+
* yields a structured `{ ok: false, code, message }` returnValue instead of
|
|
41
|
+
* the silent drop `on` uses, so the blocked renderer always gets an answer.
|
|
42
|
+
*/
|
|
43
|
+
handleSync(channel: string, fn: (event: IpcMainEvent, ...args: unknown[]) => unknown): this;
|
|
35
44
|
on(channel: string, fn: ListenerFn): this;
|
|
36
45
|
dispose(): Promise<void>;
|
|
37
46
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ipcMain } from 'electron';
|
|
2
|
-
import { DisposableRegistry } from '
|
|
2
|
+
import { DisposableRegistry } from '@dimina-kit/electron-deck/main';
|
|
3
3
|
import { IpcValidationError } from './ipc-schema.js';
|
|
4
4
|
import { createLogger } from './logger.js';
|
|
5
5
|
const log = createLogger('ipc');
|
|
@@ -30,6 +30,23 @@ function summarizeSender(sender) {
|
|
|
30
30
|
const url = sender.getURL();
|
|
31
31
|
return `id=${sender.id} ${url.slice(0, 120)}`;
|
|
32
32
|
}
|
|
33
|
+
function isMainFrameSender(event) {
|
|
34
|
+
// Read via loose casts: the Electron types declare these always-present, but
|
|
35
|
+
// unit-test stubs legitimately omit them — and real events can carry a null
|
|
36
|
+
// senderFrame after navigation/destruction.
|
|
37
|
+
const frame = event.senderFrame;
|
|
38
|
+
const main = event.sender.mainFrame;
|
|
39
|
+
// Frame-unaware stub (NEITHER field modeled) → not a real frame boundary; the
|
|
40
|
+
// sender-id white-list is the gate. Real events always have both, so they fall
|
|
41
|
+
// through to the strict check; a partial/malformed event (only one field) also
|
|
42
|
+
// falls through and fail-closes below rather than escaping here.
|
|
43
|
+
if (frame === undefined && main === undefined)
|
|
44
|
+
return true;
|
|
45
|
+
// Real event, unresolvable frame (navigate-after-send / destroyed) → reject.
|
|
46
|
+
if (frame == null || main == null)
|
|
47
|
+
return false;
|
|
48
|
+
return frame.routingId === main.routingId && frame.processId === main.processId;
|
|
49
|
+
}
|
|
33
50
|
/**
|
|
34
51
|
* Tiny fluent helper that wraps every `ipcMain.handle` / `ipcMain.on` with a
|
|
35
52
|
* matching removeHandler/removeListener registered into an internal registry.
|
|
@@ -62,7 +79,7 @@ export class IpcRegistry {
|
|
|
62
79
|
const guarded = policy
|
|
63
80
|
? async (event, ...args) => {
|
|
64
81
|
const sender = event.sender;
|
|
65
|
-
if (!policy(sender)) {
|
|
82
|
+
if (!policy(sender) || !isMainFrameSender(event)) {
|
|
66
83
|
console.warn(`[ipc] sender rejected for channel '${channel}' (${summarizeSender(sender)})`);
|
|
67
84
|
throw new Error(`IPC sender rejected for channel ${channel}`);
|
|
68
85
|
}
|
|
@@ -73,6 +90,49 @@ export class IpcRegistry {
|
|
|
73
90
|
this.registry.add(() => ipcMain.removeHandler(channel));
|
|
74
91
|
return this;
|
|
75
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Register a SYNCHRONOUS `ipcRenderer.sendSync` handler. Unlike {@link on}
|
|
95
|
+
* (fire-and-forget), the renderer is blocked until we set `event.returnValue`,
|
|
96
|
+
* so `fn` MUST be synchronous and return the value to hand back. The sender
|
|
97
|
+
* policy gates it like {@link handle}; a rejected sender or a thrown error
|
|
98
|
+
* yields a structured `{ ok: false, code, message }` returnValue instead of
|
|
99
|
+
* the silent drop `on` uses, so the blocked renderer always gets an answer.
|
|
100
|
+
*/
|
|
101
|
+
handleSync(channel, fn) {
|
|
102
|
+
const policy = this.policy;
|
|
103
|
+
const listener = (event, ...args) => {
|
|
104
|
+
// Everything — including the policy check — runs inside the try so EVERY
|
|
105
|
+
// path sets `event.returnValue`. sendSync blocks the renderer until it is
|
|
106
|
+
// set, so an unset value (e.g. a throwing policy fn) would hang the
|
|
107
|
+
// renderer forever; the catch guarantees a sentinel instead.
|
|
108
|
+
try {
|
|
109
|
+
if (policy && (!policy(event.sender) || !isMainFrameSender(event))) {
|
|
110
|
+
console.warn(`[ipc] sender rejected for channel '${channel}' (${summarizeSender(event.sender)})`);
|
|
111
|
+
event.returnValue = {
|
|
112
|
+
ok: false,
|
|
113
|
+
code: 'EREJECTED',
|
|
114
|
+
message: `IPC sender rejected for channel ${channel}`,
|
|
115
|
+
};
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
event.returnValue = fn(event, ...args);
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
reportListenerError(channel, err);
|
|
122
|
+
const code = err?.code;
|
|
123
|
+
event.returnValue = {
|
|
124
|
+
ok: false,
|
|
125
|
+
code: typeof code === 'string' ? code : 'EUNKNOWN',
|
|
126
|
+
message: err instanceof Error ? err.message : String(err),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
ipcMain.on(channel, listener);
|
|
131
|
+
this.registry.add(() => {
|
|
132
|
+
ipcMain.removeListener(channel, listener);
|
|
133
|
+
});
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
76
136
|
on(channel, fn) {
|
|
77
137
|
const policy = this.policy;
|
|
78
138
|
const raw = fn;
|
|
@@ -93,7 +153,7 @@ export class IpcRegistry {
|
|
|
93
153
|
const guarded = policy
|
|
94
154
|
? (event, ...args) => {
|
|
95
155
|
const sender = event.sender;
|
|
96
|
-
if (!policy(sender)) {
|
|
156
|
+
if (!policy(sender) || !isMainFrameSender(event)) {
|
|
97
157
|
console.warn(`[ipc] sender rejected for channel '${channel}' (${summarizeSender(sender)})`);
|
|
98
158
|
return;
|
|
99
159
|
}
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
export declare const devtoolsPackageRoot: string;
|
|
2
2
|
export declare const rendererDir: string;
|
|
3
3
|
export declare const defaultPreloadPath: string;
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the CommonJS sibling (`*.cjs`) of a simulator preload bundle.
|
|
6
|
+
*
|
|
7
|
+
* A `<webview>`/session-frame preload is always loaded as CommonJS by Electron.
|
|
8
|
+
* The native-host simulator (the sole runtime) instead runs in a top-level
|
|
9
|
+
* WebContentsView whose `webPreferences.preload` obeys the `.js` +
|
|
10
|
+
* `"type":"module"` ESM rule — so the `.js` bundle would fail with
|
|
11
|
+
* `require is not defined`. We ship a byte-identical `.cjs` copy
|
|
12
|
+
* (build:preload emits both) and hand the WCV the `.cjs` sibling. If a host
|
|
13
|
+
* supplies a custom `.js` preload, we swap the extension; an already-`.cjs`
|
|
14
|
+
* path (or any non-`.js`) is returned unchanged.
|
|
15
|
+
*/
|
|
16
|
+
export declare function cjsSiblingPreloadPath(preloadPath: string): string;
|
|
4
17
|
/**
|
|
5
18
|
* Preload bundle for the main window, settings window, and the settings /
|
|
6
19
|
* popover overlay WebContentsViews. Exposes `window.devtools.ipc` via
|
|
7
20
|
* contextBridge so the renderer never needs `window.require('electron')`.
|
|
8
21
|
*/
|
|
9
22
|
export declare const mainPreloadPath: string;
|
|
23
|
+
/** Preload for the host-controllable toolbar WCV — runs the reverse size-advertiser. */
|
|
24
|
+
export declare const hostToolbarPreloadPath: string;
|
|
10
25
|
export declare const simulatorDir: string;
|
|
11
26
|
export declare function getRendererDir(): string;
|
|
12
27
|
export declare function getPreloadDir(): string;
|
package/dist/main/utils/paths.js
CHANGED
|
@@ -25,12 +25,31 @@ function resolveDevtoolsPackageRoot() {
|
|
|
25
25
|
export const devtoolsPackageRoot = resolveDevtoolsPackageRoot();
|
|
26
26
|
export const rendererDir = path.join(devtoolsPackageRoot, 'dist/renderer');
|
|
27
27
|
export const defaultPreloadPath = path.join(devtoolsPackageRoot, 'dist/preload/windows/simulator.js');
|
|
28
|
+
/**
|
|
29
|
+
* Resolve the CommonJS sibling (`*.cjs`) of a simulator preload bundle.
|
|
30
|
+
*
|
|
31
|
+
* A `<webview>`/session-frame preload is always loaded as CommonJS by Electron.
|
|
32
|
+
* The native-host simulator (the sole runtime) instead runs in a top-level
|
|
33
|
+
* WebContentsView whose `webPreferences.preload` obeys the `.js` +
|
|
34
|
+
* `"type":"module"` ESM rule — so the `.js` bundle would fail with
|
|
35
|
+
* `require is not defined`. We ship a byte-identical `.cjs` copy
|
|
36
|
+
* (build:preload emits both) and hand the WCV the `.cjs` sibling. If a host
|
|
37
|
+
* supplies a custom `.js` preload, we swap the extension; an already-`.cjs`
|
|
38
|
+
* path (or any non-`.js`) is returned unchanged.
|
|
39
|
+
*/
|
|
40
|
+
export function cjsSiblingPreloadPath(preloadPath) {
|
|
41
|
+
return preloadPath.endsWith('.js')
|
|
42
|
+
? preloadPath.slice(0, -'.js'.length) + '.cjs'
|
|
43
|
+
: preloadPath;
|
|
44
|
+
}
|
|
28
45
|
/**
|
|
29
46
|
* Preload bundle for the main window, settings window, and the settings /
|
|
30
47
|
* popover overlay WebContentsViews. Exposes `window.devtools.ipc` via
|
|
31
48
|
* contextBridge so the renderer never needs `window.require('electron')`.
|
|
32
49
|
*/
|
|
33
50
|
export const mainPreloadPath = path.join(devtoolsPackageRoot, 'dist/preload/windows/main.cjs');
|
|
51
|
+
/** Preload for the host-controllable toolbar WCV — runs the reverse size-advertiser. */
|
|
52
|
+
export const hostToolbarPreloadPath = path.join(devtoolsPackageRoot, 'dist/preload/windows/host-toolbar.cjs');
|
|
34
53
|
export const simulatorDir = path.join(devtoolsPackageRoot, 'dist/simulator');
|
|
35
54
|
export function getRendererDir() {
|
|
36
55
|
return rendererDir;
|
|
@@ -12,9 +12,15 @@ import type { SenderPolicy } from './ipc-registry.js';
|
|
|
12
12
|
*
|
|
13
13
|
* The simulator webview is intentionally NOT on this list. Anything it
|
|
14
14
|
* needs from main (currently just the custom-apis bridge — see
|
|
15
|
-
* `installCustomApisBridge` in `src/preload/runtime/custom-apis.ts`
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* `installCustomApisBridge` in `src/preload/runtime/custom-apis.ts`) reaches
|
|
16
|
+
* the host without being white-listed here via the native-host path:
|
|
17
|
+
* the simulator is a top-level WebContentsView (no embedder), and its
|
|
18
|
+
* custom-api traffic is dispatched by a `ctx.simulatorApis`-backed
|
|
19
|
+
* `ipcMain.on` listener bound to that exact simWc in view-manager
|
|
20
|
+
* `attachNativeCustomApiBridge` — it gates on the precise sender id rather
|
|
21
|
+
* than this white-list. (Historically a `<webview>` simulator proxied through
|
|
22
|
+
* the trusted main-window renderer via `ipcRenderer.sendToHost` + `<webview>.send`;
|
|
23
|
+
* that renderer-proxied path no longer exists — native-host is the sole runtime.)
|
|
18
24
|
* Keeping the guest off this list contains the blast radius if the
|
|
19
25
|
* simulator content is ever compromised.
|
|
20
26
|
*
|
|
@@ -10,9 +10,15 @@
|
|
|
10
10
|
*
|
|
11
11
|
* The simulator webview is intentionally NOT on this list. Anything it
|
|
12
12
|
* needs from main (currently just the custom-apis bridge — see
|
|
13
|
-
* `installCustomApisBridge` in `src/preload/runtime/custom-apis.ts`
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* `installCustomApisBridge` in `src/preload/runtime/custom-apis.ts`) reaches
|
|
14
|
+
* the host without being white-listed here via the native-host path:
|
|
15
|
+
* the simulator is a top-level WebContentsView (no embedder), and its
|
|
16
|
+
* custom-api traffic is dispatched by a `ctx.simulatorApis`-backed
|
|
17
|
+
* `ipcMain.on` listener bound to that exact simWc in view-manager
|
|
18
|
+
* `attachNativeCustomApiBridge` — it gates on the precise sender id rather
|
|
19
|
+
* than this white-list. (Historically a `<webview>` simulator proxied through
|
|
20
|
+
* the trusted main-window renderer via `ipcRenderer.sendToHost` + `<webview>.send`;
|
|
21
|
+
* that renderer-proxied path no longer exists — native-host is the sole runtime.)
|
|
16
22
|
* Keeping the guest off this list contains the blast radius if the
|
|
17
23
|
* simulator content is ever compromised.
|
|
18
24
|
*
|
|
@@ -43,7 +49,15 @@ export function createWorkbenchSenderPolicy(ctx) {
|
|
|
43
49
|
const popoverViewId = ctx.views.getPopoverWebContentsId();
|
|
44
50
|
if (popoverViewId != null && sender.id === popoverViewId)
|
|
45
51
|
return true;
|
|
46
|
-
//
|
|
52
|
+
// The host-toolbar overlay is DELIBERATELY NOT trusted here. The host loads
|
|
53
|
+
// arbitrary content into it, so granting it the global white-list would open
|
|
54
|
+
// all ~72 IpcRegistry channels to that content. Its one channel (the reverse
|
|
55
|
+
// size-advertiser) is instead a raw `ipcMain.on` gated on its exact wc id in
|
|
56
|
+
// `registerViewsIpc` — same blast-radius containment as the simulator guest.
|
|
57
|
+
// The simulator (a top-level WebContentsView under native-host) is also
|
|
58
|
+
// DELIBERATELY off this white-list; its custom-api traffic is gated on the
|
|
59
|
+
// exact simWc id elsewhere (see file header). There is no longer a
|
|
60
|
+
// renderer-proxied <webview> simulator path.
|
|
47
61
|
return false;
|
|
48
62
|
};
|
|
49
63
|
}
|
package/dist/main/utils/theme.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BrowserWindow, nativeTheme } from 'electron';
|
|
2
|
-
import { toDisposable } from '
|
|
2
|
+
import { toDisposable } from '@dimina-kit/electron-deck/main';
|
|
3
3
|
/**
|
|
4
4
|
* Background color that matches the current system color scheme.
|
|
5
5
|
* Pass as `backgroundColor` when creating BrowserWindows to prevent
|
|
@@ -6,12 +6,6 @@ export interface WindowOptions {
|
|
|
6
6
|
minWidth?: number;
|
|
7
7
|
minHeight?: number;
|
|
8
8
|
indexHtml: string;
|
|
9
|
-
/**
|
|
10
|
-
* Absolute path to the simulator preload bundle. Registered at the session
|
|
11
|
-
* level so every frame inside the simulator <webview> gets the preload that
|
|
12
|
-
* exposes the `wx` runtime to the mini-program.
|
|
13
|
-
*/
|
|
14
|
-
simulatorPreloadPath: string;
|
|
15
9
|
}
|
|
16
10
|
export declare function createMainWindow(opts: WindowOptions): BrowserWindow;
|
|
17
11
|
//# sourceMappingURL=create.d.ts.map
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
import { app, BrowserWindow, View, session
|
|
1
|
+
import { app, BrowserWindow, View, session } from 'electron';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { getSimulatorServicewechatReferer } from '../../services/simulator/referer.js';
|
|
4
4
|
import { mainPreloadPath } from '../../utils/paths.js';
|
|
5
5
|
import { themeBg } from '../../utils/theme.js';
|
|
6
|
-
import { applyNavigationHardening
|
|
6
|
+
import { applyNavigationHardening } from '../navigation-hardening.js';
|
|
7
7
|
let simulatorSessionConfigured = false;
|
|
8
|
-
function configureSimulatorSession(
|
|
8
|
+
function configureSimulatorSession() {
|
|
9
9
|
if (simulatorSessionConfigured)
|
|
10
10
|
return;
|
|
11
11
|
simulatorSessionConfigured = true;
|
|
12
12
|
const simulatorSession = session.fromPartition('persist:simulator');
|
|
13
|
-
// Inject the simulator preload on every frame in this session. This is the
|
|
14
|
-
// mini-program runtime entry point (exposes `wx`, page registers, etc.).
|
|
15
|
-
simulatorSession.registerPreloadScript({
|
|
16
|
-
type: 'frame',
|
|
17
|
-
filePath: simulatorPreloadPath,
|
|
18
|
-
});
|
|
19
13
|
simulatorSession.webRequest.onBeforeSendHeaders((details, callback) => {
|
|
20
14
|
const forcedReferer = getSimulatorServicewechatReferer();
|
|
21
15
|
if (forcedReferer) {
|
|
@@ -25,16 +19,17 @@ function configureSimulatorSession(simulatorPreloadPath) {
|
|
|
25
19
|
});
|
|
26
20
|
simulatorSession.webRequest.onHeadersReceived((details, callback) => {
|
|
27
21
|
const headers = details.responseHeaders ?? {};
|
|
22
|
+
// CORS for the native render/service hosts to fetch compiled app resources
|
|
23
|
+
// cross-origin. (The COOP/COEP cross-origin-isolation headers were only for
|
|
24
|
+
// the removed default-path SharedArrayBuffer sync Worker — dropped.)
|
|
28
25
|
headers['access-control-allow-origin'] = ['*'];
|
|
29
26
|
headers['access-control-allow-headers'] = ['*'];
|
|
30
27
|
headers['access-control-allow-methods'] = ['*'];
|
|
31
|
-
headers['Cross-Origin-Opener-Policy'] = ['same-origin'];
|
|
32
|
-
headers['Cross-Origin-Embedder-Policy'] = ['credentialless'];
|
|
33
28
|
callback({ responseHeaders: headers });
|
|
34
29
|
});
|
|
35
30
|
}
|
|
36
31
|
export function createMainWindow(opts) {
|
|
37
|
-
configureSimulatorSession(
|
|
32
|
+
configureSimulatorSession();
|
|
38
33
|
const mainWindow = new BrowserWindow({
|
|
39
34
|
width: opts.width ?? 1280,
|
|
40
35
|
height: opts.height ?? 980,
|
|
@@ -50,8 +45,6 @@ export function createMainWindow(opts) {
|
|
|
50
45
|
// to access contextBridge/ipcRenderer. The renderer itself runs isolated.
|
|
51
46
|
sandbox: false,
|
|
52
47
|
preload: mainPreloadPath,
|
|
53
|
-
// The simulator <webview> still relies on the webview tag; keep it enabled.
|
|
54
|
-
webviewTag: true,
|
|
55
48
|
},
|
|
56
49
|
});
|
|
57
50
|
mainWindow.once('ready-to-show', () => {
|
|
@@ -60,7 +53,10 @@ export function createMainWindow(opts) {
|
|
|
60
53
|
}
|
|
61
54
|
else {
|
|
62
55
|
mainWindow.show();
|
|
63
|
-
|
|
56
|
+
// Don't auto-open a detached DevTools for the devtools UI shell itself —
|
|
57
|
+
// it's noise for normal use (the mini-app's Console lives in the embedded
|
|
58
|
+
// right-panel DevTools, not here). Opt in via env for debugging the shell.
|
|
59
|
+
if (!app.isPackaged && process.env.DIMINA_DEVTOOLS_MAIN_INSPECTOR === '1') {
|
|
64
60
|
mainWindow.webContents.openDevTools({ mode: 'detach' });
|
|
65
61
|
}
|
|
66
62
|
}
|
|
@@ -69,50 +65,6 @@ export function createMainWindow(opts) {
|
|
|
69
65
|
// Restrict the main renderer to file:// URLs under the renderer bundle and
|
|
70
66
|
// route every popup through the OS browser. See navigation-hardening.ts.
|
|
71
67
|
applyNavigationHardening(mainWindow.webContents, rendererDir);
|
|
72
|
-
mainWindow.webContents.on('will-attach-webview', (event, webPreferences, params) => {
|
|
73
|
-
// Pin the simulator <webview> onto `persist:simulator` so it shares storage
|
|
74
|
-
// with the rest of the session and picks up the session-registered preload.
|
|
75
|
-
// Empirically (Electron 41) `webPreferences.partition` is the field the
|
|
76
|
-
// guest session actually consults; `params.partition` alone is a no-op,
|
|
77
|
-
// so we write both belt-and-braces.
|
|
78
|
-
;
|
|
79
|
-
webPreferences.partition = 'persist:simulator';
|
|
80
|
-
params.partition = 'persist:simulator';
|
|
81
|
-
// The simulator <webview> intentionally runs with `contextIsolation: false`
|
|
82
|
-
// because the dimina runtime and the user-authored preload scripts share
|
|
83
|
-
// the same JavaScript realm as the page — the mini-program SDK reaches
|
|
84
|
-
// into the page's globals (e.g. AudioContext, custom registers) and
|
|
85
|
-
// attaches helpers via window-level injection. Flipping isolation on
|
|
86
|
-
// would break that contract.
|
|
87
|
-
webPreferences.contextIsolation = false;
|
|
88
|
-
void event;
|
|
89
|
-
});
|
|
90
|
-
// The simulator webview's webContents only exists once attached; wire its
|
|
91
|
-
// window-open / will-navigate handlers here so popups + redirects don't
|
|
92
|
-
// pivot to file:// or arbitrary origins.
|
|
93
|
-
mainWindow.webContents.on('did-attach-webview', (_event, webviewWebContents) => {
|
|
94
|
-
webviewWebContents.setWindowOpenHandler(({ url }) => handleWindowOpenExternal(url));
|
|
95
|
-
webviewWebContents.on('will-navigate', (e, url) => {
|
|
96
|
-
try {
|
|
97
|
-
const u = new URL(url);
|
|
98
|
-
// Allow the simulator's own host (localhost dev server) plus the
|
|
99
|
-
// initial about:blank that Chromium uses before src loads.
|
|
100
|
-
if (u.protocol === 'about:')
|
|
101
|
-
return;
|
|
102
|
-
if ((u.protocol === 'http:' || u.protocol === 'https:') &&
|
|
103
|
-
(u.hostname === 'localhost' || u.hostname === '127.0.0.1')) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
e.preventDefault();
|
|
107
|
-
if (u.protocol === 'http:' || u.protocol === 'https:') {
|
|
108
|
-
void shell.openExternal(url);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
e.preventDefault();
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
68
|
mainWindow.loadFile(opts.indexHtml);
|
|
117
69
|
const container = new View();
|
|
118
70
|
const mainWebView = mainWindow.contentView;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BrowserWindow } from 'electron';
|
|
2
2
|
import type { WorkbenchContext } from '../../services/workbench-context.js';
|
|
3
|
-
import { type Disposable } from '
|
|
3
|
+
import { type Disposable } from '@dimina-kit/electron-deck/main';
|
|
4
4
|
export interface MainWindowEventState {
|
|
5
5
|
context?: WorkbenchContext;
|
|
6
6
|
onResize?: () => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { globalShortcut } from 'electron';
|
|
2
|
-
import { DisposableRegistry, toDisposable } from '
|
|
2
|
+
import { DisposableRegistry, toDisposable } from '@dimina-kit/electron-deck/main';
|
|
3
3
|
export function wireMainWindowEvents(win, state = {}) {
|
|
4
4
|
const registry = new DisposableRegistry();
|
|
5
5
|
const mainWebView = win.contentView.children[0];
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { BrowserWindow } from 'electron';
|
|
2
|
+
import type { ServiceHostSpec } from '../../services/service-host-pool/pool.js';
|
|
3
|
+
/** Session partition the service host shares with the simulator `<webview>`. */
|
|
4
|
+
export declare const SERVICE_HOST_PARTITION = "persist:simulator";
|
|
5
|
+
/** Absolute path to the service-host preload (loaded at runtime by path). */
|
|
6
|
+
export declare const serviceHostPreloadPath: string;
|
|
7
|
+
export interface ServiceHostWindowOptions {
|
|
8
|
+
bridgeId: string;
|
|
9
|
+
appId: string;
|
|
10
|
+
pagePath: string;
|
|
11
|
+
pkgRoot: string;
|
|
12
|
+
resourceBaseUrl: string;
|
|
13
|
+
hostEnvSnapshot?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Construct an (un-navigated) service-host BrowserWindow. Split out from
|
|
17
|
+
* `createServiceHostWindow` so a pre-warm pool can build the window once and
|
|
18
|
+
* navigate it per spawn (the spawn context lives in the URL — see
|
|
19
|
+
* `buildServiceHostSpawnUrl`). The process-model flags here are the contract
|
|
20
|
+
* the service-host preload depends on (it `require('electron')` and writes
|
|
21
|
+
* globals onto the page realm).
|
|
22
|
+
*/
|
|
23
|
+
export declare function constructServiceHostWindow(opts?: {
|
|
24
|
+
appId?: string;
|
|
25
|
+
partition?: string;
|
|
26
|
+
}): BrowserWindow;
|
|
27
|
+
/**
|
|
28
|
+
* Build the file:// spawn URL carrying the per-spawn context the preload reads
|
|
29
|
+
* from `location.search` at eval time (bridgeId/appId/pagePath/pkgRoot/
|
|
30
|
+
* resourceBaseUrl/hostEnv).
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildServiceHostSpawnUrl(opts: ServiceHostWindowOptions): string;
|
|
33
|
+
/**
|
|
34
|
+
* Navigate a (constructed or pooled) service-host window to its spawn URL. The
|
|
35
|
+
* preload re-evaluates on this navigation, rebuilding `__diminaSpawnContext`.
|
|
36
|
+
* Returns the load promise (resolves on did-finish-load). Attaches the dev-only
|
|
37
|
+
* detached-DevTools hook, matching the original behavior.
|
|
38
|
+
*/
|
|
39
|
+
export declare function navigateServiceHost(win: BrowserWindow, url: string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* The spec a `ServiceHostPool` uses to pre-warm service-host windows. Keeps the
|
|
42
|
+
* pooled window byte-equivalent to `constructServiceHostWindow`'s output, and
|
|
43
|
+
* opts out of the reset storage-clear because the service host shares the
|
|
44
|
+
* `persist:simulator` session with live projects (see ServiceHostSpec docs).
|
|
45
|
+
*/
|
|
46
|
+
export declare function serviceHostSpec(): ServiceHostSpec;
|
|
47
|
+
/**
|
|
48
|
+
* Construct + navigate a fresh service-host window (the non-pool path).
|
|
49
|
+
* Behavior-identical to the pre-refactor implementation.
|
|
50
|
+
*/
|
|
51
|
+
export declare function createServiceHostWindow(opts: ServiceHostWindowOptions): BrowserWindow;
|
|
52
|
+
//# sourceMappingURL=create.d.ts.map
|