@dimina-kit/devtools 0.4.0 → 0.5.0-dev.20260908120530
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 +51 -660
- package/dist/main/api.d.ts +2 -1
- package/dist/main/app/app.d.ts +41 -12
- package/dist/main/app/app.js +299 -514
- package/dist/main/app/bootstrap.d.ts +8 -5
- package/dist/main/app/bootstrap.js +15 -15
- package/dist/main/app/editor-view.d.ts +21 -0
- package/dist/main/app/editor-view.js +71 -0
- package/dist/main/app/global-mirrors.d.ts +23 -0
- package/dist/main/app/global-mirrors.js +37 -0
- package/dist/main/app/host-sidebar-default.d.ts +19 -0
- package/dist/main/app/host-sidebar-default.js +44 -0
- package/dist/main/app/lifecycle.d.ts +12 -1
- package/dist/main/app/lifecycle.js +27 -1
- package/dist/main/app/menu-setup.d.ts +13 -0
- package/dist/main/app/menu-setup.js +49 -0
- package/dist/main/app/native-overview.d.ts +1 -1
- package/dist/main/app/open-project-ipc.d.ts +13 -0
- package/dist/main/app/open-project-ipc.js +21 -0
- package/dist/main/app/project-list-surface.d.ts +31 -0
- package/dist/main/app/project-list-surface.js +20 -0
- package/dist/main/app/project-window.d.ts +36 -0
- package/dist/main/app/project-window.js +93 -0
- package/dist/main/app/servers.d.ts +17 -0
- package/dist/main/app/servers.js +60 -0
- package/dist/main/app/ui-extension-targets.d.ts +42 -0
- package/dist/main/app/ui-extension-targets.js +101 -0
- package/dist/main/app/window-close-reveal.harness.d.ts +34 -0
- package/dist/main/app/window-close-reveal.harness.js +65 -0
- package/dist/main/app/window-events.d.ts +15 -0
- package/dist/main/app/window-events.js +45 -0
- package/dist/main/app/window-runtime-services.d.ts +41 -0
- package/dist/main/app/window-runtime-services.js +197 -0
- package/dist/main/app/workbench-modules.d.ts +24 -0
- package/dist/main/app/workbench-modules.js +51 -0
- package/dist/main/app/workbench-window.d.ts +85 -0
- package/dist/main/app/workbench-window.js +310 -0
- package/dist/main/index.bundle.js +11712 -9986
- package/dist/main/index.js +49 -1
- package/dist/main/ipc/app-lifecycle.d.ts +1 -31
- package/dist/main/ipc/app-lifecycle.js +1 -53
- package/dist/main/ipc/app.d.ts +4 -1
- package/dist/main/ipc/app.js +4 -3
- package/dist/main/ipc/bridge-router.d.ts +19 -116
- package/dist/main/ipc/bridge-router.js +28 -2128
- package/dist/main/ipc/device-picker.d.ts +16 -0
- package/dist/main/ipc/device-picker.js +27 -0
- package/dist/main/ipc/index.d.ts +5 -0
- package/dist/main/ipc/index.js +5 -0
- package/dist/main/ipc/internal-devtools.d.ts +16 -0
- package/dist/main/ipc/internal-devtools.js +10 -0
- package/dist/main/ipc/page-scroll.d.ts +1 -13
- package/dist/main/ipc/page-scroll.js +1 -16
- package/dist/main/ipc/popover.d.ts +4 -1
- package/dist/main/ipc/popover.js +26 -19
- package/dist/main/ipc/project-create.d.ts +16 -0
- package/dist/main/ipc/project-create.js +27 -0
- package/dist/main/ipc/project-fs.d.ts +38 -3
- package/dist/main/ipc/project-fs.js +53 -22
- package/dist/main/ipc/projects.d.ts +3 -3
- package/dist/main/ipc/projects.js +47 -11
- package/dist/main/ipc/session-listener-bag.d.ts +1 -40
- package/dist/main/ipc/session-listener-bag.js +1 -39
- package/dist/main/ipc/session.d.ts +4 -1
- package/dist/main/ipc/session.js +26 -26
- package/dist/main/ipc/settings.d.ts +4 -1
- package/dist/main/ipc/settings.js +17 -19
- package/dist/main/ipc/simulator-module.d.ts +9 -3
- package/dist/main/ipc/simulator-module.js +13 -10
- package/dist/main/ipc/simulator.d.ts +4 -1
- package/dist/main/ipc/simulator.js +12 -18
- package/dist/main/ipc/tooltip.d.ts +14 -0
- package/dist/main/ipc/tooltip.js +29 -0
- package/dist/main/ipc/views.d.ts +19 -2
- package/dist/main/ipc/views.js +76 -8
- package/dist/main/runtime/devtools-backend-before-quit.harness.d.ts +43 -0
- package/dist/main/runtime/devtools-backend-before-quit.harness.js +87 -0
- package/dist/main/runtime/devtools-backend.js +60 -4
- package/dist/main/runtime/devtools-runtime-mock.harness.d.ts +21 -0
- package/dist/main/runtime/devtools-runtime-mock.harness.js +313 -0
- package/dist/main/runtime/miniapp-runtime.d.ts +91 -22
- package/dist/main/services/app-services.d.ts +62 -0
- package/dist/main/services/app-services.js +64 -0
- package/dist/main/services/automation/connection-target.d.ts +36 -0
- package/dist/main/services/automation/connection-target.js +29 -0
- package/dist/main/services/automation/console-bridge.d.ts +28 -0
- package/dist/main/services/automation/console-bridge.js +91 -0
- package/dist/main/services/automation/handlers/app.js +4 -4
- package/dist/main/services/automation/handlers/element.js +55 -21
- package/dist/main/services/automation/index.d.ts +12 -1
- package/dist/main/services/automation/index.js +54 -133
- package/dist/main/services/cdp-session/index.d.ts +87 -0
- package/dist/main/services/cdp-session/index.js +173 -0
- package/dist/main/services/compile-standby.js +4 -0
- package/dist/main/services/console-forward/cdp-inject.d.ts +18 -0
- package/dist/main/services/console-forward/cdp-inject.js +30 -0
- package/dist/main/services/console-forward/global-console-mirror.d.ts +33 -0
- package/dist/main/services/console-forward/global-console-mirror.js +71 -0
- package/dist/main/services/console-forward/global-diagnostics-mirror.d.ts +33 -0
- package/dist/main/services/console-forward/global-diagnostics-mirror.js +73 -0
- package/dist/main/services/console-forward/index.d.ts +1 -46
- package/dist/main/services/console-forward/index.js +1 -185
- package/dist/main/services/console-forward/internal-log.d.ts +2 -0
- package/dist/main/services/console-forward/internal-log.js +2 -0
- package/dist/main/services/console-forward/open-gated-relay.d.ts +67 -0
- package/dist/main/services/console-forward/open-gated-relay.js +55 -0
- package/dist/main/services/default-adapter.js +1 -1
- package/dist/main/services/diagnostics/index.d.ts +1 -48
- package/dist/main/services/diagnostics/index.js +1 -60
- package/dist/main/services/dimina-resource-server.d.ts +1 -6
- package/dist/main/services/dimina-resource-server.js +1 -98
- package/dist/main/services/elements-forward/index.d.ts +132 -15
- package/dist/main/services/elements-forward/index.js +155 -304
- package/dist/main/services/fs-bridge-protocol.d.ts +61 -0
- package/dist/main/services/fs-bridge-protocol.js +34 -0
- package/dist/main/services/fs-watch-sse.d.ts +40 -0
- package/dist/main/services/fs-watch-sse.js +113 -0
- package/dist/main/services/http-json.d.ts +9 -0
- package/dist/main/services/http-json.js +6 -0
- package/dist/main/services/layout/index.d.ts +11 -0
- package/dist/main/services/layout/index.js +23 -0
- package/dist/main/services/mcp/connection-owner.d.ts +38 -0
- package/dist/main/services/mcp/connection-owner.js +79 -0
- package/dist/main/services/mcp/index.d.ts +3 -1
- package/dist/main/services/mcp/index.js +4 -3
- package/dist/main/services/mcp/opened-project.d.ts +88 -0
- package/dist/main/services/mcp/opened-project.js +60 -0
- package/dist/main/services/mcp/server.d.ts +2 -1
- package/dist/main/services/mcp/server.js +29 -4
- package/dist/main/services/mcp/target-manager.d.ts +71 -23
- package/dist/main/services/mcp/target-manager.js +269 -138
- package/dist/main/services/mcp/target-selection.d.ts +47 -0
- package/dist/main/services/mcp/target-selection.js +71 -0
- package/dist/main/services/mcp/tools/context-tools.js +20 -5
- package/dist/main/services/mcp/tools/project-tools.d.ts +72 -0
- package/dist/main/services/mcp/tools/project-tools.js +133 -0
- package/dist/main/services/module.d.ts +13 -5
- package/dist/main/services/network-forward/body-cache.d.ts +72 -0
- package/dist/main/services/network-forward/body-cache.js +179 -0
- package/dist/main/services/network-forward/frontend-dispatch.d.ts +91 -0
- package/dist/main/services/network-forward/frontend-dispatch.js +148 -0
- package/dist/main/services/network-forward/global-body-gate.d.ts +46 -0
- package/dist/main/services/network-forward/global-body-gate.js +93 -0
- package/dist/main/services/network-forward/global-mirror-test-fixtures.d.ts +48 -0
- package/dist/main/services/network-forward/global-mirror-test-fixtures.js +96 -0
- package/dist/main/services/network-forward/http.d.ts +47 -0
- package/dist/main/services/network-forward/http.js +162 -0
- package/dist/main/services/network-forward/index.d.ts +135 -15
- package/dist/main/services/network-forward/index.js +854 -224
- package/dist/main/services/network-forward/request-ids.d.ts +5 -0
- package/dist/main/services/network-forward/request-ids.js +5 -0
- package/dist/main/services/network-forward/user-facing.d.ts +21 -0
- package/dist/main/services/network-forward/user-facing.js +50 -0
- package/dist/main/services/network-forward/websocket.d.ts +36 -0
- package/dist/main/services/network-forward/websocket.js +120 -0
- package/dist/main/services/notifications/renderer-notifier.d.ts +71 -9
- package/dist/main/services/notifications/renderer-notifier.js +45 -8
- package/dist/main/services/projects/create-project-service.js +19 -5
- package/dist/main/services/projects/local-provider.js +8 -4
- package/dist/main/services/projects/project-repository.d.ts +59 -7
- package/dist/main/services/projects/project-repository.js +285 -51
- package/dist/main/services/projects/types.d.ts +44 -34
- package/dist/main/services/render-inspect/index.d.ts +12 -2
- package/dist/main/services/render-inspect/index.js +21 -102
- package/dist/main/services/safe-area/index.d.ts +21 -6
- package/dist/main/services/safe-area/index.js +92 -46
- package/dist/main/services/service-host-pool/pool.d.ts +1 -196
- package/dist/main/services/service-host-pool/pool.js +1 -363
- package/dist/main/services/settings/index.d.ts +7 -1
- package/dist/main/services/settings/index.js +22 -2
- package/dist/main/services/simulator/custom-apis.d.ts +1 -42
- package/dist/main/services/simulator/custom-apis.js +1 -46
- package/dist/main/services/simulator/referer.d.ts +1 -9
- package/dist/main/services/simulator/referer.js +1 -19
- package/dist/main/services/simulator/ui-extensions.d.ts +21 -0
- package/dist/main/services/simulator/ui-extensions.js +176 -0
- package/dist/main/services/simulator-appdata/index.d.ts +6 -0
- package/dist/main/services/simulator-appdata/index.js +21 -2
- package/dist/main/services/simulator-current-page/index.d.ts +5 -3
- package/dist/main/services/simulator-current-page/index.js +8 -1
- package/dist/main/services/simulator-storage/index.d.ts +34 -5
- package/dist/main/services/simulator-storage/index.js +73 -71
- package/dist/main/services/simulator-storage/service-storage-ops.d.ts +1 -39
- package/dist/main/services/simulator-storage/service-storage-ops.js +1 -66
- package/dist/main/services/simulator-storage/window-scope.d.ts +20 -0
- package/dist/main/services/simulator-storage/window-scope.js +20 -0
- package/dist/main/services/simulator-temp-files/disk.d.ts +1 -54
- package/dist/main/services/simulator-temp-files/disk.js +1 -237
- package/dist/main/services/simulator-temp-files/fs-channels.d.ts +1 -68
- package/dist/main/services/simulator-temp-files/fs-channels.js +1 -107
- package/dist/main/services/simulator-temp-files/index.d.ts +1 -32
- package/dist/main/services/simulator-temp-files/index.js +1 -181
- package/dist/main/services/simulator-temp-files/request-handler.d.ts +1 -29
- package/dist/main/services/simulator-temp-files/request-handler.js +1 -177
- package/dist/main/services/simulator-temp-files/resolver.d.ts +1 -21
- package/dist/main/services/simulator-temp-files/resolver.js +1 -21
- package/dist/main/services/simulator-temp-files/store.d.ts +1 -13
- package/dist/main/services/simulator-temp-files/store.js +1 -23
- package/dist/main/services/update/github-release-checker.js +22 -3
- package/dist/main/services/update/update-manager.d.ts +21 -4
- package/dist/main/services/update/update-manager.js +55 -11
- package/dist/main/services/views/clear-console-filter.d.ts +44 -0
- package/dist/main/services/views/clear-console-filter.js +86 -0
- package/dist/main/services/views/console-filter-test-fixtures.d.ts +94 -0
- package/dist/main/services/views/console-filter-test-fixtures.js +82 -0
- package/dist/main/services/views/console-filter.d.ts +94 -0
- package/dist/main/services/views/console-filter.js +190 -0
- package/dist/main/services/views/devtools-tabs.d.ts +24 -4
- package/dist/main/services/views/devtools-tabs.js +40 -21
- package/dist/main/services/views/frontend-bootstrap-gate.d.ts +59 -0
- package/dist/main/services/views/frontend-bootstrap-gate.js +117 -0
- package/dist/main/services/views/host-dialog-port-channel.d.ts +18 -0
- package/dist/main/services/views/host-dialog-port-channel.js +15 -0
- package/dist/main/services/views/host-dialog-session-runtime.d.ts +10 -0
- package/dist/main/services/views/host-dialog-session-runtime.js +17 -0
- package/dist/main/services/views/host-dialog-view.d.ts +95 -0
- package/dist/main/services/views/host-dialog-view.js +147 -0
- package/dist/main/services/views/host-sidebar-port-channel.d.ts +18 -0
- package/dist/main/services/views/host-sidebar-port-channel.js +15 -0
- package/dist/main/services/views/host-sidebar-session-runtime.d.ts +10 -0
- package/dist/main/services/views/host-sidebar-session-runtime.js +17 -0
- package/dist/main/services/views/host-sidebar-view.d.ts +59 -0
- package/dist/main/services/views/host-sidebar-view.js +44 -0
- package/dist/main/services/views/host-slot-port-channel.d.ts +124 -0
- package/dist/main/services/views/host-slot-port-channel.js +289 -0
- package/dist/main/services/views/host-slot-session-runtime.d.ts +40 -0
- package/dist/main/services/views/host-slot-session-runtime.js +50 -0
- package/dist/main/services/views/host-slot-view.d.ts +109 -0
- package/dist/main/services/views/host-slot-view.js +147 -0
- package/dist/main/services/views/host-toolbar-port-channel.d.ts +6 -91
- package/dist/main/services/views/host-toolbar-port-channel.js +10 -243
- package/dist/main/services/views/host-toolbar-session-runtime.d.ts +5 -30
- package/dist/main/services/views/host-toolbar-session-runtime.js +9 -47
- package/dist/main/services/views/host-toolbar-view.d.ts +34 -7
- package/dist/main/services/views/host-toolbar-view.js +30 -237
- package/dist/main/services/views/managed-web-contents-view.d.ts +48 -0
- package/dist/main/services/views/managed-web-contents-view.js +143 -0
- package/dist/main/services/views/miniapp-partition.d.ts +1 -89
- package/dist/main/services/views/miniapp-partition.js +1 -158
- package/dist/main/services/views/native-simulator-devtools-host.js +206 -68
- package/dist/main/services/views/native-simulator-view.d.ts +6 -0
- package/dist/main/services/views/native-simulator-view.js +47 -40
- package/dist/main/services/views/native-view-tree.d.ts +25 -0
- package/dist/main/services/views/native-view-tree.js +69 -0
- package/dist/main/services/views/overlay-panels-view.d.ts +63 -4
- package/dist/main/services/views/overlay-panels-view.js +257 -108
- package/dist/main/services/views/placement-reconciler.d.ts +18 -18
- package/dist/main/services/views/placement-reconciler.js +91 -29
- package/dist/main/services/views/placement-test-driver.d.ts +27 -0
- package/dist/main/services/views/placement-test-driver.js +29 -0
- package/dist/main/services/views/refresh-styles.d.ts +10 -0
- package/dist/main/services/views/refresh-styles.js +57 -0
- package/dist/main/services/views/simulator-session-policy.d.ts +1 -27
- package/dist/main/services/views/simulator-session-policy.js +1 -98
- package/dist/main/services/views/view-manager-devtools-host-test-fixtures.d.ts +76 -0
- package/dist/main/services/views/view-manager-devtools-host-test-fixtures.js +184 -0
- package/dist/main/services/views/view-manager.d.ts +69 -88
- package/dist/main/services/views/view-manager.js +62 -7
- package/dist/main/services/views/workbench-view.d.ts +2 -0
- package/dist/main/services/views/workbench-view.js +104 -17
- package/dist/main/services/window-contexts/context-router.d.ts +36 -0
- package/dist/main/services/window-contexts/context-router.js +55 -0
- package/dist/main/services/workbench-coi-host.d.ts +52 -0
- package/dist/main/services/workbench-coi-host.js +227 -0
- package/dist/main/services/workbench-coi-server.d.ts +11 -0
- package/dist/main/services/workbench-coi-server.js +126 -126
- package/dist/main/services/workbench-coi-shutdown.d.ts +40 -0
- package/dist/main/services/workbench-coi-shutdown.js +69 -0
- package/dist/main/services/workbench-coi-static.d.ts +23 -0
- package/dist/main/services/workbench-coi-static.js +87 -0
- package/dist/main/services/workbench-context.d.ts +88 -8
- package/dist/main/services/workbench-context.js +54 -6
- package/dist/main/services/workspace/compile-log-buffer.d.ts +40 -0
- package/dist/main/services/workspace/compile-log-buffer.js +41 -0
- package/dist/main/services/workspace/compile-mode-adapter.d.ts +18 -0
- package/dist/main/services/workspace/compile-mode-adapter.js +57 -0
- package/dist/main/services/workspace/compile-mode-store.d.ts +25 -0
- package/dist/main/services/workspace/compile-mode-store.js +71 -0
- package/dist/main/services/workspace/open-project-guards.d.ts +16 -0
- package/dist/main/services/workspace/open-project-guards.js +42 -0
- package/dist/main/services/workspace/rebuild-status.d.ts +37 -0
- package/dist/main/services/workspace/rebuild-status.js +36 -0
- package/dist/main/services/workspace/session-status-store.d.ts +47 -0
- package/dist/main/services/workspace/session-status-store.js +73 -0
- package/dist/main/services/workspace/status-tap.d.ts +20 -0
- package/dist/main/services/workspace/status-tap.js +32 -0
- package/dist/main/services/workspace/workspace-compile-modes.d.ts +59 -0
- package/dist/main/services/workspace/workspace-compile-modes.js +93 -0
- package/dist/main/services/workspace/workspace-lifecycle-race.testutil.d.ts +22 -0
- package/dist/main/services/workspace/workspace-lifecycle-race.testutil.js +62 -0
- package/dist/main/services/workspace/workspace-referer.d.ts +17 -0
- package/dist/main/services/workspace/workspace-referer.js +26 -0
- package/dist/main/services/workspace/workspace-service.d.ts +7 -5
- package/dist/main/services/workspace/workspace-service.js +96 -135
- package/dist/main/services/workspace/workspace-thumbnails.d.ts +22 -0
- package/dist/main/services/workspace/workspace-thumbnails.js +67 -0
- package/dist/main/utils/ipc-context-source.d.ts +40 -0
- package/dist/main/utils/ipc-context-source.js +23 -0
- package/dist/main/utils/ipc-registry.d.ts +46 -21
- package/dist/main/utils/ipc-registry.js +166 -76
- package/dist/main/utils/paths.d.ts +18 -0
- package/dist/main/utils/paths.js +18 -0
- package/dist/main/utils/sender-policy.d.ts +10 -1
- package/dist/main/utils/sender-policy.js +42 -4
- package/dist/main/utils/theme.d.ts +18 -8
- package/dist/main/utils/theme.js +19 -9
- package/dist/main/windows/internal-devtools-window/index.d.ts +66 -0
- package/dist/main/windows/internal-devtools-window/index.js +160 -0
- package/dist/main/windows/main-window/create.d.ts +16 -0
- package/dist/main/windows/main-window/create.js +19 -11
- package/dist/main/windows/main-window/events.d.ts +1 -1
- package/dist/main/windows/main-window/events.js +26 -13
- package/dist/main/windows/main-window/index.d.ts +1 -1
- package/dist/main/windows/main-window/index.js +1 -1
- package/dist/main/windows/service-host-window/create.d.ts +1 -92
- package/dist/main/windows/service-host-window/create.js +1 -154
- package/dist/native-host/common/common.js +173 -53
- package/dist/native-host/container/pageFrame.css +1 -1
- package/dist/native-host/render/render.js +8278 -3659
- package/dist/native-host/service/service.js +2 -2
- package/dist/preload/index.d.ts +2 -0
- package/dist/preload/index.js +1 -0
- package/dist/preload/instrumentation/app-data.d.ts +2 -2
- package/dist/preload/instrumentation/app-data.js +1 -1
- package/dist/preload/instrumentation/wxml.js +1 -1
- package/dist/preload/runtime/bridge.d.ts +3 -3
- package/dist/preload/runtime/bridge.js +2 -2
- package/dist/preload/runtime/clipboard.d.ts +6 -0
- package/dist/preload/runtime/clipboard.js +12 -0
- package/dist/preload/runtime/host-dialog-advertiser.d.ts +22 -0
- package/dist/preload/runtime/host-dialog-advertiser.js +37 -0
- package/dist/preload/runtime/host-dialog-port.d.ts +44 -0
- package/dist/preload/runtime/host-dialog-port.js +53 -0
- package/dist/preload/runtime/host-dialog-runtime.d.ts +28 -0
- package/dist/preload/runtime/host-dialog-runtime.js +36 -0
- package/dist/preload/runtime/host-sidebar-advertiser.d.ts +19 -0
- package/dist/preload/runtime/host-sidebar-advertiser.js +35 -0
- package/dist/preload/runtime/host-sidebar-port.d.ts +44 -0
- package/dist/preload/runtime/host-sidebar-port.js +53 -0
- package/dist/preload/runtime/host-sidebar-runtime.d.ts +28 -0
- package/dist/preload/runtime/host-sidebar-runtime.js +36 -0
- package/dist/preload/runtime/host-slot-port-bridge.d.ts +18 -0
- package/dist/preload/runtime/host-slot-port-bridge.js +112 -0
- package/dist/preload/runtime/host-toolbar-advertiser.d.ts +5 -13
- package/dist/preload/runtime/host-toolbar-advertiser.js +18 -38
- package/dist/preload/runtime/host-toolbar-port.d.ts +9 -0
- package/dist/preload/runtime/host-toolbar-port.js +11 -95
- package/dist/preload/runtime/native-host.d.ts +14 -0
- package/dist/preload/runtime/native-host.js +5 -8
- package/dist/preload/runtime/node-bindings.d.ts +18 -0
- package/dist/preload/runtime/node-bindings.js +44 -0
- package/dist/preload/runtime/temp-files.js +9 -2
- package/dist/preload/runtime/wait-for-slot-root.d.ts +23 -0
- package/dist/preload/runtime/wait-for-slot-root.js +80 -0
- package/dist/preload/shared/api-compat.js +63 -41
- package/dist/preload/windows/host-dialog-runtime.cjs +360 -0
- package/dist/preload/windows/host-dialog-runtime.cjs.map +7 -0
- package/dist/preload/windows/host-dialog-runtime.d.ts +2 -0
- package/dist/preload/windows/host-dialog-runtime.js +13 -0
- package/dist/preload/windows/host-sidebar-runtime.cjs +361 -0
- package/dist/preload/windows/host-sidebar-runtime.cjs.map +7 -0
- package/dist/preload/windows/host-sidebar-runtime.d.ts +2 -0
- package/dist/preload/windows/host-sidebar-runtime.js +13 -0
- package/dist/preload/windows/host-toolbar-runtime.cjs +142 -52
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +3 -3
- package/dist/preload/windows/main.cjs +4922 -1246
- package/dist/preload/windows/main.cjs.map +4 -4
- package/dist/preload/windows/main.css +428 -0
- package/dist/preload/windows/main.css.map +7 -0
- package/dist/preload/windows/simulator.cjs +376 -322
- package/dist/preload/windows/simulator.cjs.map +4 -4
- package/dist/preload/windows/simulator.js +376 -322
- package/dist/render-host/pageFrame.html +4 -4
- package/dist/render-host/preload.cjs +30 -0
- package/dist/render-host/render-inspect.js +184 -115
- package/dist/renderer/assets/button-CB2MWjHY.js +2 -0
- package/dist/renderer/assets/constants-CkoGPQTS.js +2 -0
- package/dist/renderer/assets/constants-zQZ2-y21.js +2 -0
- package/dist/renderer/assets/createLucideIcon-cZ9FlZZw.js +2 -0
- package/dist/renderer/assets/devicePicker-H2eIO4e1.js +2 -0
- package/dist/renderer/assets/dialog-pHzEA8Vx.js +46 -0
- package/dist/renderer/assets/dist-B5HADirS.js +2 -0
- package/dist/renderer/assets/dist-DIFlRMKe.js +2 -0
- package/dist/renderer/assets/hostSidebarDefault-DRWh6OCt.js +2 -0
- package/dist/renderer/assets/index-CEL_XFge.js +2 -0
- package/dist/renderer/assets/input-CAObw95L.js +2 -0
- package/dist/renderer/assets/ipc-channels-overlays-gIPUFnqc.js +2 -0
- package/dist/renderer/assets/jsx-runtime-DICEQH_0.css +1 -0
- package/dist/renderer/assets/jsx-runtime-DIw5wnYl.js +9 -0
- package/dist/renderer/assets/plus-BQ9u5EbL.js +2 -0
- package/dist/renderer/assets/popover-Cw7G2Ctp.js +2 -0
- package/dist/renderer/assets/presets-DMZOb9ay.js +2 -0
- package/dist/renderer/assets/project-api-YTOr_Yvo.js +2 -0
- package/dist/renderer/assets/projectCreateDialog-BmLqiYxn.js +2 -0
- package/dist/renderer/assets/search-BMvuYF48.js +2 -0
- package/dist/renderer/assets/select-nFP95TxM.js +2 -0
- package/dist/renderer/assets/settings-CnpVfSWt.js +2 -0
- package/dist/renderer/assets/settings-api-Ccsf-Nsj.js +2 -0
- package/dist/renderer/assets/settings-tab-bar-CAzrv32m.js +2 -0
- package/dist/renderer/assets/smartphone-Bb2GdIKy.js +2 -0
- package/dist/renderer/assets/tabs-CPKN3Mmq.js +2 -0
- package/dist/renderer/assets/tooltip-D6AxXRk5.js +2 -0
- package/dist/renderer/assets/types-Bh0hA7El.js +2 -0
- package/dist/renderer/assets/updateDialog-CwndJ0Bl.js +2 -0
- package/dist/renderer/assets/utils-sEB5OZEQ.js +2 -0
- package/dist/renderer/assets/view-api-B-2zPBR5.js +2 -0
- package/dist/renderer/assets/view-ids-BfaDVV5P.js +2 -0
- package/dist/renderer/assets/workbench-C0Jkdlps.js +5 -0
- package/dist/renderer/assets/workbenchSettings-YD0Ctbm_.js +8 -0
- package/dist/renderer/entries/device-picker/index.html +28 -0
- package/dist/renderer/entries/host-sidebar-default/index.html +22 -0
- package/dist/renderer/entries/main/index.html +16 -7
- package/dist/renderer/entries/popover/index.html +16 -6
- package/dist/renderer/entries/project-create-dialog/index.html +27 -0
- package/dist/renderer/entries/settings/index.html +10 -5
- package/dist/renderer/entries/tooltip/index.html +21 -0
- package/dist/renderer/entries/update-dialog/index.html +25 -0
- package/dist/renderer/entries/workbench/index.html +49 -0
- package/dist/renderer/entries/workbench-settings/index.html +12 -5
- package/dist/service-host/appdata-set-data.cjs +39 -0
- package/dist/service-host/host-env-update.cjs +23 -0
- package/dist/service-host/preload.cjs +54 -48
- package/dist/service-host/service-message-queue.cjs +71 -0
- package/dist/service-host/sync-impls/menu-button-geometry.js +16 -5
- package/dist/service-host/sync-impls/menu-button.js +5 -3
- package/dist/service-host/sync-impls/system-info.js +31 -9
- package/dist/shared/bridge-channels.d.ts +1 -416
- package/dist/shared/bridge-channels.js +1 -89
- package/dist/shared/compile-mode-state.d.ts +73 -0
- package/dist/shared/compile-mode-state.js +100 -0
- package/dist/shared/compile-modes.d.ts +152 -0
- package/dist/shared/compile-modes.js +237 -0
- package/dist/shared/constants.d.ts +22 -0
- package/dist/shared/constants.js +22 -0
- package/dist/shared/dmb-resource-url.d.ts +2 -0
- package/dist/shared/dmb-resource-url.js +2 -0
- package/dist/shared/ipc-channels-overlays.d.ts +162 -0
- package/dist/shared/ipc-channels-overlays.js +203 -0
- package/dist/shared/ipc-channels.d.ts +24 -154
- package/dist/shared/ipc-channels.js +48 -96
- package/dist/shared/ipc-schemas.d.ts +143 -54
- package/dist/shared/ipc-schemas.js +137 -45
- package/dist/shared/node-bindings.d.ts +2 -0
- package/dist/shared/node-bindings.js +2 -0
- package/dist/shared/project-window-types.d.ts +42 -0
- package/dist/shared/project-window-types.js +2 -0
- package/dist/shared/simulator-route.d.ts +8 -0
- package/dist/shared/simulator-route.js +15 -0
- package/dist/shared/simulator-ui.d.ts +61 -0
- package/dist/shared/simulator-ui.js +12 -0
- package/dist/shared/types.d.ts +126 -41
- package/dist/shared/view-ids.d.ts +10 -0
- package/dist/shared/view-ids.js +23 -0
- package/dist/simulator/assets/bridge-channels-B3JAmRfl.js +2 -0
- package/dist/simulator/assets/device-shell-ATEhHV2_.css +1 -0
- package/dist/simulator/assets/device-shell-DucLepkm.js +431 -0
- package/dist/simulator/assets/simulator-B4rbcOVt.js +10 -0
- package/dist/simulator/assets/simulator-mini-app-DFo7fhi5.js +2 -0
- package/dist/simulator/assets/simulator-ui-BupATgKo.css +1 -0
- package/dist/simulator/assets/simulator-ui-i3GCc7YJ.js +2 -0
- package/dist/simulator/simulator.html +4 -3
- package/dist/simulator/temp-files.d.ts +35 -0
- package/dist/simulator/temp-files.js +121 -0
- package/dist/simulator/types.d.ts +50 -0
- package/dist/simulator/types.js +2 -0
- package/dist/vscode-workbench/assets/__vite-browser-external-JIkWewFf.js +1 -0
- package/dist/vscode-workbench/assets/{dist-TpGpmMGi.js → dist-CXG-u1VB.js} +3 -3
- package/dist/vscode-workbench/assets/fs-core-worker-urls-DZ1nod84.js +1 -0
- package/dist/vscode-workbench/assets/fs-core.worker-Bnmpp6fo.js +1 -0
- package/dist/vscode-workbench/assets/fs-query.worker-cZ-7Fjch.js +2 -0
- package/dist/vscode-workbench/assets/{iconv-lite-umd-C9tiCAJa.js → iconv-lite-umd-Dxx9Qyb4.js} +1 -1
- package/dist/vscode-workbench/assets/{index-DJ1HyMZ7.js → index-6VJMsaWj.js} +475 -475
- package/dist/vscode-workbench/assets/{jschardet-DE1jV513.js → jschardet-Ba3D16vt.js} +1 -1
- package/dist/vscode-workbench/index.html +21 -1
- package/package.json +23 -13
- package/dist/main/services/views/destroy-child-view.d.ts +0 -9
- package/dist/main/services/views/destroy-child-view.js +0 -23
- package/dist/preload/instrumentation/wxml-extract.d.ts +0 -11
- package/dist/preload/instrumentation/wxml-extract.js +0 -382
- package/dist/preload/shared/sid-registry.d.ts +0 -11
- package/dist/preload/shared/sid-registry.js +0 -38
- package/dist/renderer/assets/constants-EAMiwL9_.js +0 -2
- package/dist/renderer/assets/index-BMqyDx71.js +0 -49
- package/dist/renderer/assets/input-CDAEwpBO.js +0 -2
- package/dist/renderer/assets/ipc-transport-B7eFOR68.css +0 -1
- package/dist/renderer/assets/ipc-transport-_G1k5V1p.js +0 -9
- package/dist/renderer/assets/popover-DEdjK14m.js +0 -2
- package/dist/renderer/assets/select-DpKPCh3y.js +0 -2
- package/dist/renderer/assets/settings-M5q2elUr.js +0 -2
- package/dist/renderer/assets/settings-api-CDlZoHiO.js +0 -2
- package/dist/renderer/assets/workbenchSettings-CT_H1WhV.js +0 -8
- package/dist/shared/appdata-accumulator.d.ts +0 -95
- package/dist/shared/appdata-accumulator.js +0 -218
- package/dist/shared/request-core.d.ts +0 -84
- package/dist/shared/request-core.js +0 -168
- package/dist/shared/simulator-api-metadata.d.ts +0 -26
- package/dist/shared/simulator-api-metadata.js +0 -59
- package/dist/shared/vpath.d.ts +0 -42
- package/dist/shared/vpath.js +0 -105
- package/dist/simulator/assets/bridge-channels-zhsumfky.js +0 -2
- package/dist/simulator/assets/device-shell-C-wcFq3Z.js +0 -2
- package/dist/simulator/assets/device-shell-CS1rqAQz.css +0 -1
- package/dist/simulator/assets/jsx-runtime-BDTY6fEq.js +0 -2
- package/dist/simulator/assets/simulator-DU3-fS3v.js +0 -10
- package/dist/simulator/assets/simulator-mini-app-DzfMfnVM.js +0 -2
- package/dist/simulator/device-shell/menu-button-geometry.js +0 -8
- package/dist/vscode-workbench/assets/__vite-browser-external-CXi6Kz9W.js +0 -1
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { resolveNativeAppDataKeys, resolveNativeStorageOverview, } from "./native-overview.js";
|
|
2
|
+
import { registerMcpWindow, noteActiveBridgeId, } from "../services/mcp/index.js";
|
|
3
|
+
import { createRenderInspector } from "../services/render-inspect/index.js";
|
|
4
|
+
import { setupSimulatorStorage } from "../services/simulator-storage/index.js";
|
|
5
|
+
import { createNetworkForwarder } from "../services/network-forward/index.js";
|
|
6
|
+
import { setupSimulatorWxml } from "../services/simulator-wxml/index.js";
|
|
7
|
+
import { setupSimulatorAppData } from "../services/simulator-appdata/index.js";
|
|
8
|
+
import { setupSimulatorCurrentPage } from "../services/simulator-current-page/index.js";
|
|
9
|
+
import { toDisposable } from "@dimina-kit/electron-deck/main";
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the active project's appId. Shared by the storage panel filter, the
|
|
12
|
+
* native-host WXML/element-inspect services (which scope the active render
|
|
13
|
+
* guest by appId) and the editor's per-project workspace identity.
|
|
14
|
+
*/
|
|
15
|
+
export function createActiveAppIdResolver(context) {
|
|
16
|
+
return () => {
|
|
17
|
+
const session = context.workspace.getSession();
|
|
18
|
+
const appInfo = session?.appInfo;
|
|
19
|
+
return appInfo?.appId ?? null;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Panel-backing services that push into one window's renderer: storage, and
|
|
24
|
+
* under native-host the MCP target tracking plus the WXML / AppData /
|
|
25
|
+
* current-page streams.
|
|
26
|
+
*/
|
|
27
|
+
export function setupWindowRuntimeServices(context, mainWindow, getActiveAppId, projectPath) {
|
|
28
|
+
// MCP drives whichever project window the user is in, so each window records
|
|
29
|
+
// its own facts and this record dies with the window — other project windows
|
|
30
|
+
// keep theirs. The project path is the window's identity, taken from the
|
|
31
|
+
// project it opened with rather than read back off session state that does
|
|
32
|
+
// not exist until the first compile.
|
|
33
|
+
const mcpWindow = registerMcpWindow(context, {
|
|
34
|
+
nativeHost: false,
|
|
35
|
+
activeBridgeId: null,
|
|
36
|
+
nativeOverviewProvider: null,
|
|
37
|
+
projectPath,
|
|
38
|
+
getAppId: getActiveAppId,
|
|
39
|
+
});
|
|
40
|
+
context.registry.add(mcpWindow.dispose);
|
|
41
|
+
// Native-host: the real mini-app page runs in a nested render-host
|
|
42
|
+
// <webview> guest, not the localhost:7788 shell. Point the MCP
|
|
43
|
+
// `simulator` CDP target at the active render guest and keep it following
|
|
44
|
+
// the visible page across navigation/tab switches. Only wired under
|
|
45
|
+
// native-host so the default path stays byte-identical.
|
|
46
|
+
if (context.bridge?.isNativeHost()) {
|
|
47
|
+
mcpWindow.facts.nativeHost = true;
|
|
48
|
+
mcpWindow.facts.nativeOverviewProvider = async () => {
|
|
49
|
+
const appId = getActiveAppId();
|
|
50
|
+
const stack = context.bridge?.getPageStack?.(appId ?? undefined) ?? [];
|
|
51
|
+
const top = stack[stack.length - 1];
|
|
52
|
+
const overview = {
|
|
53
|
+
currentRoute: top?.pagePath ?? null,
|
|
54
|
+
pageStackDepth: stack.length,
|
|
55
|
+
storageKeys: [],
|
|
56
|
+
storageCount: 0,
|
|
57
|
+
appDataKeys: [],
|
|
58
|
+
};
|
|
59
|
+
if (appId) {
|
|
60
|
+
const storage = await resolveNativeStorageOverview(context, appId);
|
|
61
|
+
overview.storageKeys = storage.storageKeys;
|
|
62
|
+
overview.storageCount = storage.storageCount;
|
|
63
|
+
overview.appDataKeys = resolveNativeAppDataKeys(context, appId);
|
|
64
|
+
}
|
|
65
|
+
return overview;
|
|
66
|
+
};
|
|
67
|
+
const off = context.bridge.onRenderEvent((ev) => noteActiveBridgeId(context, ev.bridgeId));
|
|
68
|
+
context.registry.add(off);
|
|
69
|
+
}
|
|
70
|
+
// Native-host inspector: injects the render-guest IIFE and drives WXML /
|
|
71
|
+
// element-highlight against the active render-host <webview>. Reused by
|
|
72
|
+
// the storage panel (element inspect) and the WXML panel service.
|
|
73
|
+
const renderInspector = createRenderInspector({
|
|
74
|
+
connections: context.connections,
|
|
75
|
+
broker: context.cdpSessionBroker,
|
|
76
|
+
});
|
|
77
|
+
const storage = setupSimulatorStorage(mainWindow.webContents, {
|
|
78
|
+
senderPolicy: context.senderPolicy,
|
|
79
|
+
connections: context.connections,
|
|
80
|
+
broker: context.cdpSessionBroker,
|
|
81
|
+
// Scopes simulator-webview discovery to THIS window — otherwise a second
|
|
82
|
+
// project window can steal the first window's already-attached simulator
|
|
83
|
+
// (see setupSimulatorStorage's `window` option doc).
|
|
84
|
+
window: mainWindow,
|
|
85
|
+
// Per-project filter for the simulator-storage panel: the simulator
|
|
86
|
+
// uses a fixed `persist:simulator` partition + a fixed simulator.html
|
|
87
|
+
// origin, so localStorage is shared across every project that has
|
|
88
|
+
// ever opened. The dimina runtime isolates writes with `${appId}_`
|
|
89
|
+
// prefixes; this callback lets the storage panel filter the CDP
|
|
90
|
+
// snapshot/event stream to the active appId.
|
|
91
|
+
getActiveAppId,
|
|
92
|
+
// Native-host: route element inspection to the active render guest, and
|
|
93
|
+
// read/write storage from the service-host window's file:// store.
|
|
94
|
+
bridge: context.bridge,
|
|
95
|
+
renderInspector,
|
|
96
|
+
});
|
|
97
|
+
context.registry.add(storage);
|
|
98
|
+
// Native-host: expose the async-storage runtime hook so bridge-router
|
|
99
|
+
// routes async wx.setStorage/etc. to the unified service-host store.
|
|
100
|
+
if (storage.storageApi) {
|
|
101
|
+
context.storageApi = storage.storageApi;
|
|
102
|
+
context.registry.add(() => {
|
|
103
|
+
context.storageApi = undefined;
|
|
104
|
+
});
|
|
105
|
+
// SYNC wx storage writes bypass main (they hit the service-host localStorage
|
|
106
|
+
// directly); the service-host posts `storageChanged` and bridge-router routes
|
|
107
|
+
// it here so the Storage panel stays live without a manual reload.
|
|
108
|
+
context.onServiceStorageChanged = storage.onSyncStorageChange;
|
|
109
|
+
context.registry.add(() => {
|
|
110
|
+
context.onServiceStorageChanged = undefined;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// Native-host WXML + AppData panels: main sources the data (WXML pulled
|
|
114
|
+
// from the active render guest; AppData tapped from the service→render
|
|
115
|
+
// setData stream in bridge-router) and pushes it to the renderer. Inert on
|
|
116
|
+
// the default dimina-fe path (which sources both from the simulator
|
|
117
|
+
// miniappSnapshot transport), so only wire them when native-host is on.
|
|
118
|
+
if (context.bridge?.isNativeHost()) {
|
|
119
|
+
// Native-host: surface the simulator WCV's network (wx.request/download/
|
|
120
|
+
// upload run there, not in the service host) in the embedded DevTools by
|
|
121
|
+
// injecting its raw Network.* CDP events into the DevTools front-end so the
|
|
122
|
+
// native Network tab renders them (service-host console line is the
|
|
123
|
+
// fallback). The ViewManager calls the forwarder's attachSimulator +
|
|
124
|
+
// setDevtoolsHost from attachNativeSimulator once the simulator WCV +
|
|
125
|
+
// DevTools host exist; getServiceWc here is the fallback sink target.
|
|
126
|
+
const networkForward = createNetworkForwarder({
|
|
127
|
+
getServiceWc: (appId) => context.bridge?.getServiceWc(appId) ?? null,
|
|
128
|
+
getResourceServerBaseUrl: () => context.bridge?.getResourceBaseUrl?.() ?? null,
|
|
129
|
+
// The simulator shell's own static-asset server (serves simulator.html
|
|
130
|
+
// + its JS/CSS, independent from the resource server above — see
|
|
131
|
+
// NetworkForwarderBridge.getSimulatorServerBaseUrl's doc). Host is
|
|
132
|
+
// always 'localhost' — see shared/simulator-route.ts's
|
|
133
|
+
// buildSimulatorUrlFromSpec default. Absent (null port) when no
|
|
134
|
+
// project is open.
|
|
135
|
+
getSimulatorServerBaseUrl: () => {
|
|
136
|
+
const port = context.workspace?.getSession()?.port;
|
|
137
|
+
return typeof port === "number" ? `http://localhost:${port}/` : null;
|
|
138
|
+
},
|
|
139
|
+
connections: context.connections,
|
|
140
|
+
broker: context.cdpSessionBroker,
|
|
141
|
+
});
|
|
142
|
+
context.networkForward = networkForward;
|
|
143
|
+
context.registry.add(networkForward);
|
|
144
|
+
context.registry.add(() => {
|
|
145
|
+
context.networkForward = undefined;
|
|
146
|
+
});
|
|
147
|
+
// Global mirror: once the standalone internal
|
|
148
|
+
// DevTools window builds its own front-end host, mirror the full
|
|
149
|
+
// unfiltered Network stream into it. Attached AFTER context.networkForward
|
|
150
|
+
// is assigned above — the callback re-reads the mutable field on every
|
|
151
|
+
// fire, so ordering only matters for readability here, not correctness.
|
|
152
|
+
context.registry.add(toDisposable(context.internalDevtoolsWindow?.onHostChanged((hostWc) => {
|
|
153
|
+
context.networkForward?.setGlobalDevtoolsHost(hostWc);
|
|
154
|
+
}) ?? (() => { })));
|
|
155
|
+
// Main-process WebSocket traffic (wx.connectSocket runs on the Node `ws`
|
|
156
|
+
// transport, invisible to any webContents debugger): bridge-router fans
|
|
157
|
+
// the trace stream out here, and the forwarder synthesizes it into
|
|
158
|
+
// Network.webSocket* CDP events for the same Network panel sinks.
|
|
159
|
+
context.registry.add(toDisposable(context.bridge?.onNativeWebSocketTrace?.((ownerId, event) => {
|
|
160
|
+
context.networkForward?.reportWebSocketTrace(ownerId, event);
|
|
161
|
+
}) ?? (() => { })));
|
|
162
|
+
// Main-process HTTP traffic (wx.request runs on Node http/https,
|
|
163
|
+
// invisible to any webContents debugger — that's the whole point of the
|
|
164
|
+
// migration off renderer `fetch()`, since Chromium's Fetch/CORS algorithm
|
|
165
|
+
// was attaching a spurious OPTIONS preflight to it): same trace-stream
|
|
166
|
+
// fan-out as the WebSocket case above.
|
|
167
|
+
context.registry.add(toDisposable(context.bridge?.onNativeRequestTrace?.((ownerId, event) => {
|
|
168
|
+
context.networkForward?.reportNativeRequestTrace(ownerId, event);
|
|
169
|
+
}) ?? (() => { })));
|
|
170
|
+
context.registry.add(setupSimulatorWxml(mainWindow.webContents, {
|
|
171
|
+
senderPolicy: context.senderPolicy,
|
|
172
|
+
bridge: context.bridge,
|
|
173
|
+
inspector: renderInspector,
|
|
174
|
+
getActiveAppId,
|
|
175
|
+
}));
|
|
176
|
+
const appDataService = setupSimulatorAppData(mainWindow.webContents, {
|
|
177
|
+
senderPolicy: context.senderPolicy,
|
|
178
|
+
getActiveAppId,
|
|
179
|
+
// AppData-panel edit write-back target: the service-host window owning
|
|
180
|
+
// the edited page bridge.
|
|
181
|
+
bridge: context.bridge,
|
|
182
|
+
});
|
|
183
|
+
// bridge-router feeds this via ctx.appData (service→render tap + evict).
|
|
184
|
+
context.appData = appDataService;
|
|
185
|
+
context.registry.add(appDataService);
|
|
186
|
+
context.registry.add(() => {
|
|
187
|
+
context.appData = undefined;
|
|
188
|
+
});
|
|
189
|
+
// Push the visible page route to the toolbar on every navigation (the
|
|
190
|
+
// page stack lives in the DeviceShell WCV, invisible to renderer
|
|
191
|
+
// <webview> nav events).
|
|
192
|
+
context.registry.add(setupSimulatorCurrentPage(mainWindow.webContents, {
|
|
193
|
+
bridge: context.bridge,
|
|
194
|
+
}));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=window-runtime-services.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DisposableRegistry } from '@dimina-kit/electron-deck/main';
|
|
2
|
+
import type { WorkbenchAppConfig } from '../../shared/types.js';
|
|
3
|
+
import type { WindowContextRouter } from '../services/window-contexts/context-router.js';
|
|
4
|
+
import type { ProjectWindow } from './project-window.js';
|
|
5
|
+
/**
|
|
6
|
+
* The window context type, taken from `ProjectWindow` so this module doesn't
|
|
7
|
+
* import `WorkbenchContext` directly (see eslint-workbench-context-gate).
|
|
8
|
+
*/
|
|
9
|
+
type WindowContext = ProjectWindow['context'];
|
|
10
|
+
/**
|
|
11
|
+
* The IPC half of the built-in modules: registered ONCE for the application.
|
|
12
|
+
* Each handler answers whichever window a message came from (it takes the
|
|
13
|
+
* router), so a second window needs no second registration — and must not make
|
|
14
|
+
* one, since `ipcMain.handle` is a process-wide singleton per channel.
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerModuleIpc(config: WorkbenchAppConfig, router: WindowContextRouter<WindowContext>, appRegistry: DisposableRegistry): void;
|
|
17
|
+
/**
|
|
18
|
+
* The per-window half: wiring that mutates one concrete context (the
|
|
19
|
+
* simulator's bridge router assigning `ctx.bridge` / `ctx.consoleForwarder`).
|
|
20
|
+
* Runs once per window and is parked on that window's own registry.
|
|
21
|
+
*/
|
|
22
|
+
export declare function setupWindowModules(config: WorkbenchAppConfig, context: WindowContext): void;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=workbench-modules.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { popoverModule, projectsModule, sessionModule, settingsModule, simulatorModule, } from '../ipc/index.js';
|
|
2
|
+
const DEFAULT_MODULES = {
|
|
3
|
+
projects: true,
|
|
4
|
+
session: true,
|
|
5
|
+
simulator: true,
|
|
6
|
+
popover: true,
|
|
7
|
+
settings: true,
|
|
8
|
+
};
|
|
9
|
+
const BUILTIN_MODULES = {
|
|
10
|
+
projects: projectsModule,
|
|
11
|
+
session: sessionModule,
|
|
12
|
+
simulator: simulatorModule,
|
|
13
|
+
popover: popoverModule,
|
|
14
|
+
settings: settingsModule,
|
|
15
|
+
};
|
|
16
|
+
function resolveModules(config) {
|
|
17
|
+
return {
|
|
18
|
+
...DEFAULT_MODULES,
|
|
19
|
+
...config.modules,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The IPC half of the built-in modules: registered ONCE for the application.
|
|
24
|
+
* Each handler answers whichever window a message came from (it takes the
|
|
25
|
+
* router), so a second window needs no second registration — and must not make
|
|
26
|
+
* one, since `ipcMain.handle` is a process-wide singleton per channel.
|
|
27
|
+
*/
|
|
28
|
+
export function registerModuleIpc(config, router, appRegistry) {
|
|
29
|
+
const modules = resolveModules(config);
|
|
30
|
+
Object.keys(modules).forEach((moduleId) => {
|
|
31
|
+
if (!modules[moduleId])
|
|
32
|
+
return;
|
|
33
|
+
appRegistry.add(BUILTIN_MODULES[moduleId].setup(router));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The per-window half: wiring that mutates one concrete context (the
|
|
38
|
+
* simulator's bridge router assigning `ctx.bridge` / `ctx.consoleForwarder`).
|
|
39
|
+
* Runs once per window and is parked on that window's own registry.
|
|
40
|
+
*/
|
|
41
|
+
export function setupWindowModules(config, context) {
|
|
42
|
+
const modules = resolveModules(config);
|
|
43
|
+
Object.keys(modules).forEach((moduleId) => {
|
|
44
|
+
if (!modules[moduleId])
|
|
45
|
+
return;
|
|
46
|
+
const module = BUILTIN_MODULES[moduleId];
|
|
47
|
+
if (module.setupWindow)
|
|
48
|
+
context.registry.add(module.setupWindow(context));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=workbench-modules.js.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { BrowserWindow } from 'electron';
|
|
2
|
+
import type { WorkbenchAppConfig } from '../../shared/types.js';
|
|
3
|
+
import type { AppServices } from '../services/app-services.js';
|
|
4
|
+
import type { WindowContextRouter } from '../services/window-contexts/context-router.js';
|
|
5
|
+
import { type ProjectRef, type ProjectWindow } from './project-window.js';
|
|
6
|
+
/**
|
|
7
|
+
* The window context type, taken from `ProjectWindow` so this module doesn't
|
|
8
|
+
* import `WorkbenchContext` directly (see eslint-workbench-context-gate).
|
|
9
|
+
*/
|
|
10
|
+
type WindowContext = ProjectWindow['context'];
|
|
11
|
+
export interface WorkbenchWindowDeps {
|
|
12
|
+
config: WorkbenchAppConfig;
|
|
13
|
+
rendererDir: string;
|
|
14
|
+
appServices: AppServices;
|
|
15
|
+
router: WindowContextRouter<WindowContext>;
|
|
16
|
+
/**
|
|
17
|
+
* Per-window module wiring — the `setupWindow` half of the built-in modules
|
|
18
|
+
* (notably the simulator's `installBridgeRouter`, which assigns `ctx.bridge`
|
|
19
|
+
* / `ctx.consoleForwarder` / `ctx.diagnostics`). The IPC half is registered
|
|
20
|
+
* once against the router and is NOT repeated here.
|
|
21
|
+
*/
|
|
22
|
+
setupWindowModules: (ctx: WindowContext) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Told whenever `activeContext()` can have changed — a window opened, took
|
|
25
|
+
* focus, or was torn down. App-level services that hold something aimed at
|
|
26
|
+
* the active project window (the MCP CDP connections) re-aim on it.
|
|
27
|
+
*/
|
|
28
|
+
onActiveContextChanged?: () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Host hook, awaited before a window tears its project down, and told which
|
|
31
|
+
* project that is. A rejection is logged and swallowed: the hook runs on the
|
|
32
|
+
* way out, so it can react but never cancel the teardown behind it.
|
|
33
|
+
*/
|
|
34
|
+
onBeforeClose?: (win: ProjectWindow, project: ProjectRef) => Promise<void> | void;
|
|
35
|
+
/**
|
|
36
|
+
* Host hook, awaited once the window is fully wired and before `open()`
|
|
37
|
+
* reports success, and told which project it belongs to. Unlike
|
|
38
|
+
* `onBeforeClose` it CAN fail the open: there is no usable window to react
|
|
39
|
+
* in yet, so a rejection tears the half-built window down and travels back
|
|
40
|
+
* to the caller unchanged.
|
|
41
|
+
*/
|
|
42
|
+
setupProjectWindow?: (win: ProjectWindow, project: ProjectRef) => Promise<void> | void;
|
|
43
|
+
/**
|
|
44
|
+
* Gate every open waits on before it builds anything. The app registers the
|
|
45
|
+
* open-project IPC before it awaits the host's own setup hook, so a renderer
|
|
46
|
+
* that races ahead must be parked rather than handed a window the host has
|
|
47
|
+
* not finished extending. Omitted means there is nothing to wait for.
|
|
48
|
+
*/
|
|
49
|
+
ready?: Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
export interface WorkbenchWindowManager {
|
|
52
|
+
/**
|
|
53
|
+
* Open `project` in its own window, or focus the window already showing it.
|
|
54
|
+
* Resolves once the window exists and its per-window services are wired.
|
|
55
|
+
* Opens and closes of the same project are serialized, so a call arriving
|
|
56
|
+
* while that project's window is still closing waits it out and then opens a
|
|
57
|
+
* fresh window — never a second one alongside it. Rejects if the window
|
|
58
|
+
* cannot be brought up, leaving nothing behind.
|
|
59
|
+
*
|
|
60
|
+
* `awaitReady: false` skips parking on `deps.ready` (still queued behind
|
|
61
|
+
* other opens/closes of the same path). Only the host's own
|
|
62
|
+
* `instance.openProjectWindow` uses it — see `app.ts`'s call site for why.
|
|
63
|
+
* The renderer-facing IPC path always uses the default.
|
|
64
|
+
*/
|
|
65
|
+
open: (project: ProjectRef, options?: {
|
|
66
|
+
awaitReady?: boolean;
|
|
67
|
+
}) => Promise<BrowserWindow>;
|
|
68
|
+
list: () => ProjectWindow[];
|
|
69
|
+
/**
|
|
70
|
+
* The workbench context the user is working in — the focused one, or the
|
|
71
|
+
* most recently opened when focus sits on the project list. Null until the
|
|
72
|
+
* first project window opens.
|
|
73
|
+
*/
|
|
74
|
+
activeContext: () => WindowContext | null;
|
|
75
|
+
/**
|
|
76
|
+
* Tear every workbench window down (app quit / runtime disposal). Terminal
|
|
77
|
+
* and idempotent: once it starts, no `open()` — pending, queued or already
|
|
78
|
+
* in flight — leaves a live window behind, and it does not resolve until
|
|
79
|
+
* every in-flight open or close has settled.
|
|
80
|
+
*/
|
|
81
|
+
disposeAll: () => Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
export declare function createWorkbenchWindowManager(deps: WorkbenchWindowDeps): WorkbenchWindowManager;
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=workbench-window.d.ts.map
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { toDisposable } from '@dimina-kit/electron-deck/main';
|
|
3
|
+
import { createInternalDevtoolsWindow } from '../windows/internal-devtools-window/index.js';
|
|
4
|
+
import { revealMainWindow, wireMainWindowEvents } from '../windows/main-window/index.js';
|
|
5
|
+
import { isAppQuitting } from './lifecycle.js';
|
|
6
|
+
import { installGlobalMirrors } from './global-mirrors.js';
|
|
7
|
+
import { setupEditorView } from './editor-view.js';
|
|
8
|
+
import { createActiveAppIdResolver, setupWindowRuntimeServices } from './window-runtime-services.js';
|
|
9
|
+
import { createWorkbenchWindow } from './project-window.js';
|
|
10
|
+
/**
|
|
11
|
+
* Close semantics for a workbench window. Unlike the old single-window app —
|
|
12
|
+
* where closing meant "return this window to the project list" — closing a
|
|
13
|
+
* workbench window means the window itself goes away, so teardown must finish
|
|
14
|
+
* BEFORE the window is destroyed.
|
|
15
|
+
*
|
|
16
|
+
* Three guards, each covering a failure this app has actually shipped:
|
|
17
|
+
*
|
|
18
|
+
* 1. A real application quit (⌘Q / menu Quit / app.quit()) fires `before-quit`
|
|
19
|
+
* first. Let it through: converting a quit into a project close swallows the
|
|
20
|
+
* quit and the app can never exit with a project open.
|
|
21
|
+
* 2. A close arriving while teardown is already in flight (the user
|
|
22
|
+
* rapid-double-clicked) MUST keep the window. This runs BEFORE any
|
|
23
|
+
* session check on purpose: `closeProject()` → `disposeSession()`
|
|
24
|
+
* synchronously nulls the active session before it finishes awaiting
|
|
25
|
+
* `session.close()`, so a session-presence check would already read false
|
|
26
|
+
* by the time the second close arrives, fall through with no
|
|
27
|
+
* `preventDefault()`, and let Chromium destroy the window out from under a
|
|
28
|
+
* live teardown.
|
|
29
|
+
* 3. Teardown is UNCONDITIONAL — deliberately not gated on
|
|
30
|
+
* `hasActiveSession()`. A failed open (invalid/non-existent project) never
|
|
31
|
+
* creates a session, yet the window still owns views, an editor server and
|
|
32
|
+
* IPC registrations. Gating on session presence let that case skip teardown
|
|
33
|
+
* entirely, which is how closing an invalid project used to take the whole
|
|
34
|
+
* app down with it.
|
|
35
|
+
*/
|
|
36
|
+
function wireWorkbenchWindowEvents(win, ctx, teardown) {
|
|
37
|
+
let closing = false;
|
|
38
|
+
let torndown = false;
|
|
39
|
+
return wireMainWindowEvents(win, {
|
|
40
|
+
context: ctx,
|
|
41
|
+
onResize: () => ctx.views.repositionAll(),
|
|
42
|
+
onClose: async (e) => {
|
|
43
|
+
if (isAppQuitting())
|
|
44
|
+
return;
|
|
45
|
+
if (closing) {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Safety net for a `close()` that arrives after teardown finished (this
|
|
50
|
+
// module destroys the window itself, which emits no `close`).
|
|
51
|
+
if (torndown)
|
|
52
|
+
return;
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
closing = true;
|
|
55
|
+
try {
|
|
56
|
+
await teardown();
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
console.error('[workbench] workbench window teardown failed:', err);
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
closing = false;
|
|
63
|
+
torndown = true;
|
|
64
|
+
}
|
|
65
|
+
if (!win.isDestroyed())
|
|
66
|
+
win.destroy();
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
export function createWorkbenchWindowManager(deps) {
|
|
71
|
+
const { config, rendererDir, appServices, router } = deps;
|
|
72
|
+
// Keyed by project path: one window per project, so a second open of the
|
|
73
|
+
// same project focuses the existing window instead of racing two sessions
|
|
74
|
+
// (and two compile workers) over the same directory.
|
|
75
|
+
const windows = new Map();
|
|
76
|
+
// Serializes every open and close of one project path. The map alone cannot
|
|
77
|
+
// carry "one window per project": an open has awaits in it, and a close
|
|
78
|
+
// awaits host code, so overlapping requests (a re-click on the project list,
|
|
79
|
+
// MCP's project_open) must queue rather than each find "no window" and build
|
|
80
|
+
// one. Entries are dropped once a path goes idle.
|
|
81
|
+
const pathQueues = new Map();
|
|
82
|
+
// Terminal state owned by this manager, deliberately not `isAppQuitting()`:
|
|
83
|
+
// a runtime can be disposed while the app keeps running, and a manager that
|
|
84
|
+
// has torn everything down must never build another window either way.
|
|
85
|
+
let disposed = false;
|
|
86
|
+
function disposedError() {
|
|
87
|
+
return new Error('workbench window manager is disposed');
|
|
88
|
+
}
|
|
89
|
+
function enqueue(path, task) {
|
|
90
|
+
const previous = pathQueues.get(path) ?? Promise.resolve();
|
|
91
|
+
// Same task on either outcome: a failed open or close must not wedge the
|
|
92
|
+
// queue for its path.
|
|
93
|
+
const result = previous.then(task, task);
|
|
94
|
+
const settled = result.then(() => { }, () => { });
|
|
95
|
+
pathQueues.set(path, settled);
|
|
96
|
+
void settled.then(() => {
|
|
97
|
+
if (pathQueues.get(path) === settled)
|
|
98
|
+
pathQueues.delete(path);
|
|
99
|
+
});
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
async function openWindow(project) {
|
|
103
|
+
// Checked where the queued task starts running, not where it was queued:
|
|
104
|
+
// an open sitting behind a close on the same path can be dequeued long
|
|
105
|
+
// after `disposeAll()` began, and must fail instead of resurrecting a
|
|
106
|
+
// project the app just tore down.
|
|
107
|
+
if (disposed)
|
|
108
|
+
throw disposedError();
|
|
109
|
+
const existing = windows.get(project.path);
|
|
110
|
+
if (existing && !existing.window.isDestroyed()) {
|
|
111
|
+
if (existing.window.isMinimized())
|
|
112
|
+
existing.window.restore();
|
|
113
|
+
existing.window.focus();
|
|
114
|
+
router.setActive(existing.context);
|
|
115
|
+
deps.onActiveContextChanged?.();
|
|
116
|
+
return existing.window;
|
|
117
|
+
}
|
|
118
|
+
const projectWindow = createWorkbenchWindow({ config, rendererDir, appServices, router }, project);
|
|
119
|
+
const { window, context } = projectWindow;
|
|
120
|
+
windows.set(project.path, projectWindow);
|
|
121
|
+
// Reveal gate: the window is created hidden (see `createWorkbenchWindow`)
|
|
122
|
+
// and must stay hidden until BOTH the renderer has painted its first
|
|
123
|
+
// frame (`ready-to-show`) and `setupProjectWindow` has resolved —
|
|
124
|
+
// whichever finishes second triggers the reveal, exactly once. Wired
|
|
125
|
+
// before any `await` below so a renderer that paints before the hook
|
|
126
|
+
// settles (the common case) is never missed.
|
|
127
|
+
let rendererReady = false;
|
|
128
|
+
let setupDone = false;
|
|
129
|
+
let revealed = false;
|
|
130
|
+
// Flipped the moment a close is requested, not when teardown runs: the
|
|
131
|
+
// close queues behind this open on the same path, so the hook can still
|
|
132
|
+
// resolve first and would otherwise show a window whose close was
|
|
133
|
+
// already asked for, only for the queued teardown to destroy it.
|
|
134
|
+
let closeRequested = false;
|
|
135
|
+
const revealIfReady = () => {
|
|
136
|
+
if (revealed || !rendererReady || !setupDone)
|
|
137
|
+
return;
|
|
138
|
+
if (window.isDestroyed())
|
|
139
|
+
return;
|
|
140
|
+
// Same for a manager already tearing everything down: `disposeAll()`
|
|
141
|
+
// waits for this open to settle, and the window must not flash on the
|
|
142
|
+
// way out.
|
|
143
|
+
if (closeRequested || disposed)
|
|
144
|
+
return;
|
|
145
|
+
// Permanent opt-out: the framework must never show this window, no
|
|
146
|
+
// matter how many times the two gates above are satisfied.
|
|
147
|
+
if (config.projectWindow?.autoShow === false)
|
|
148
|
+
return;
|
|
149
|
+
revealed = true;
|
|
150
|
+
revealMainWindow(window);
|
|
151
|
+
};
|
|
152
|
+
window.once('ready-to-show', () => {
|
|
153
|
+
rendererReady = true;
|
|
154
|
+
revealIfReady();
|
|
155
|
+
});
|
|
156
|
+
const teardown = async () => {
|
|
157
|
+
// A close queued behind an open that then failed (or lost to
|
|
158
|
+
// `disposeAll()`) finds the window already removed and torn down by
|
|
159
|
+
// that open's own undo path. Nothing is left to close, and the host
|
|
160
|
+
// hook must not be handed a disposed context and a destroyed window.
|
|
161
|
+
if (windows.get(project.path) !== projectWindow)
|
|
162
|
+
return;
|
|
163
|
+
try {
|
|
164
|
+
await deps.onBeforeClose?.(projectWindow, project);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
// The hook is the host's chance to react, not a veto: everything below
|
|
168
|
+
// (compile session, bridge router, editor server, IPC and app-level
|
|
169
|
+
// listeners) has to go, and the map entry with it, or the window's
|
|
170
|
+
// resources outlive a window nothing can reach any more.
|
|
171
|
+
console.error('[workbench] host onBeforeClose hook failed:', err);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
await projectWindow.dispose();
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
// Dropped LAST: while teardown is in flight this project still has a
|
|
178
|
+
// window, and an open arriving mid-close must queue behind it (see
|
|
179
|
+
// `enqueue`) instead of finding an empty map and building a second one.
|
|
180
|
+
if (windows.get(project.path) === projectWindow)
|
|
181
|
+
windows.delete(project.path);
|
|
182
|
+
}
|
|
183
|
+
// After the map entry is gone, so listeners read the window that is left.
|
|
184
|
+
deps.onActiveContextChanged?.();
|
|
185
|
+
};
|
|
186
|
+
try {
|
|
187
|
+
// The standalone internal DevTools window debugs THIS window's renderer,
|
|
188
|
+
// so it is per-window wiring. `isAppQuitting` lets the controller stop
|
|
189
|
+
// intercepting 'close' during a real quit.
|
|
190
|
+
context.internalDevtoolsWindow = createInternalDevtoolsWindow(window, { isAppQuitting });
|
|
191
|
+
context.registry.add(toDisposable(() => context.internalDevtoolsWindow?.dispose()));
|
|
192
|
+
// Wired before the awaited steps below: the window is already closable
|
|
193
|
+
// even though it's still hidden behind the reveal gate above, so it
|
|
194
|
+
// must never exist without the close handling that disposes it.
|
|
195
|
+
context.registry.add(wireWorkbenchWindowEvents(window, context, () => {
|
|
196
|
+
closeRequested = true;
|
|
197
|
+
return enqueue(project.path, teardown);
|
|
198
|
+
}));
|
|
199
|
+
// Whichever workbench window the user is looking at answers the IPC that
|
|
200
|
+
// no single window owns (menus, app-level host windows).
|
|
201
|
+
const onFocus = () => {
|
|
202
|
+
router.setActive(context);
|
|
203
|
+
deps.onActiveContextChanged?.();
|
|
204
|
+
};
|
|
205
|
+
window.on('focus', onFocus);
|
|
206
|
+
context.registry.add(toDisposable(() => {
|
|
207
|
+
if (!window.isDestroyed())
|
|
208
|
+
window.removeListener('focus', onFocus);
|
|
209
|
+
}));
|
|
210
|
+
// Order matters: the bridge router assigns ctx.bridge / ctx.consoleForwarder
|
|
211
|
+
// / ctx.diagnostics, which both the mirrors and the runtime services read.
|
|
212
|
+
deps.setupWindowModules(context);
|
|
213
|
+
installGlobalMirrors(context, window);
|
|
214
|
+
const getActiveAppId = createActiveAppIdResolver(context);
|
|
215
|
+
setupWindowRuntimeServices(context, window, getActiveAppId, project.path);
|
|
216
|
+
await setupEditorView(config, context, getActiveAppId);
|
|
217
|
+
// `disposeAll()` can land while this open is parked above. It waits for
|
|
218
|
+
// this task to settle rather than reaching into a half-built window, so
|
|
219
|
+
// the undo below is this open's own job.
|
|
220
|
+
if (disposed)
|
|
221
|
+
throw disposedError();
|
|
222
|
+
// Last, so the host configures a window whose own services are all up.
|
|
223
|
+
// It runs while the window is already in `windows`: a hook that opens
|
|
224
|
+
// views or drives the session needs the window reachable, and a failure
|
|
225
|
+
// path below removes the entry again.
|
|
226
|
+
await deps.setupProjectWindow?.(projectWindow, project);
|
|
227
|
+
// Re-checked after the hook for the same reason as before it: the hook
|
|
228
|
+
// is host code of unbounded duration, and an open that lost the race
|
|
229
|
+
// must reject rather than hand back a window `disposeAll()` is about
|
|
230
|
+
// to destroy.
|
|
231
|
+
if (disposed)
|
|
232
|
+
throw disposedError();
|
|
233
|
+
// Does not block `open()` returning: if `ready-to-show` already fired,
|
|
234
|
+
// this reveals now; otherwise it just marks the gate and the pending
|
|
235
|
+
// `ready-to-show` listener above reveals once Chromium paints.
|
|
236
|
+
setupDone = true;
|
|
237
|
+
revealIfReady();
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
// A half-built window (the editor's http server can fail to bind) leaves
|
|
241
|
+
// live services behind and keeps the project counted as open — which is
|
|
242
|
+
// what the list window reads to decide whether to stay hidden. Undo the
|
|
243
|
+
// whole thing before handing the failure back.
|
|
244
|
+
windows.delete(project.path);
|
|
245
|
+
await projectWindow.dispose().catch((disposeErr) => {
|
|
246
|
+
console.warn('[workbench] failed to dispose a partially opened window:', disposeErr);
|
|
247
|
+
});
|
|
248
|
+
if (!window.isDestroyed())
|
|
249
|
+
window.destroy();
|
|
250
|
+
throw err;
|
|
251
|
+
}
|
|
252
|
+
deps.onActiveContextChanged?.();
|
|
253
|
+
return window;
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
// One project window per RESOLVED absolute path: two differently-spelled
|
|
257
|
+
// strings pointing at the same directory ('/a/b' vs '/a/b/.') must not
|
|
258
|
+
// race two windows (and two compile workers) over one project. Resolving
|
|
259
|
+
// here, before the path reaches `windows`/`pathQueues`/`openWindow`,
|
|
260
|
+
// keeps every downstream lookup keyed on the one canonical spelling.
|
|
261
|
+
open: (project, options) => {
|
|
262
|
+
const normalized = { ...project, path: path.resolve(project.path) };
|
|
263
|
+
// The readiness gate is awaited inside the queued task, not before
|
|
264
|
+
// queuing: opens of one path must keep their arrival order, and a
|
|
265
|
+
// `disposeAll()` landing meanwhile still finds this open in the queue it
|
|
266
|
+
// drains rather than floating loose outside it.
|
|
267
|
+
const awaitReady = options?.awaitReady ?? true;
|
|
268
|
+
return enqueue(normalized.path, async () => {
|
|
269
|
+
if (awaitReady)
|
|
270
|
+
await deps.ready;
|
|
271
|
+
return openWindow(normalized);
|
|
272
|
+
});
|
|
273
|
+
},
|
|
274
|
+
list: () => [...windows.values()],
|
|
275
|
+
activeContext: () => {
|
|
276
|
+
const active = router.active();
|
|
277
|
+
const all = [...windows.values()];
|
|
278
|
+
if (all.some((pw) => pw.context === active))
|
|
279
|
+
return active;
|
|
280
|
+
return all.length > 0 ? all[all.length - 1].context : null;
|
|
281
|
+
},
|
|
282
|
+
disposeAll: async () => {
|
|
283
|
+
// Set before waiting, never after: the in-flight opens and closes being
|
|
284
|
+
// waited on are exactly the code that has to observe the terminal state
|
|
285
|
+
// in order to finish instead of building on.
|
|
286
|
+
disposed = true;
|
|
287
|
+
// Drained repeatedly because settling one entry releases whatever was
|
|
288
|
+
// queued behind it on the same path; new opens reject at their task
|
|
289
|
+
// start, so the queues run dry.
|
|
290
|
+
while (pathQueues.size > 0) {
|
|
291
|
+
await Promise.allSettled([...pathQueues.values()]);
|
|
292
|
+
}
|
|
293
|
+
// Snapshotted only now: an open that lost the race above already removed
|
|
294
|
+
// and disposed itself, and a finished close already dropped its entry,
|
|
295
|
+
// so nothing here is disposed twice.
|
|
296
|
+
const all = [...windows.values()];
|
|
297
|
+
windows.clear();
|
|
298
|
+
// Serial: each teardown closes a devkit session and an http server, and
|
|
299
|
+
// a parallel storm during quit is exactly when those races bite.
|
|
300
|
+
for (const projectWindow of all) {
|
|
301
|
+
await projectWindow.dispose().catch((err) => {
|
|
302
|
+
console.warn('[workbench] failed to tear down workbench window:', err);
|
|
303
|
+
});
|
|
304
|
+
if (!projectWindow.window.isDestroyed())
|
|
305
|
+
projectWindow.window.destroy();
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=workbench-window.js.map
|