@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
|
@@ -1,113 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cross-Origin-Isolation static server for the embedded VS Code workbench.
|
|
3
|
-
*
|
|
4
|
-
* The workbench needs `SharedArrayBuffer` for the TS web ext-host's
|
|
5
|
-
* project-wide IntelliSense. Chromium only serves that to a document fetched
|
|
6
|
-
* over http(s) carrying COOP `same-origin` + COEP `require-corp` (a custom
|
|
7
|
-
* `protocol.handle` response does NOT unlock it), so the workbench bundle is
|
|
8
|
-
* served from this in-process http server bound to 127.0.0.1 on a random port.
|
|
9
|
-
* Every response carries the three isolation headers so same-origin
|
|
10
|
-
* sub-resources and workers satisfy COEP `require-corp`.
|
|
11
|
-
*
|
|
12
|
-
* Kept separate from `dimina-resource-server` on purpose: that server sends
|
|
13
|
-
* CORP `cross-origin` for the simulator bundles, which is incompatible with the
|
|
14
|
-
* workbench's `same-origin` isolation requirement.
|
|
15
|
-
*
|
|
16
|
-
* `/__fs/*` bridges a `diminafs:`-style FileSystemProvider in the workbench to
|
|
17
|
-
* the live active project on disk, reusing the renderer `project:fs:*`
|
|
18
|
-
* sandbox's realpath-based guards (`resolveWithinProjectRoot`,
|
|
19
|
-
* `assertWritableAncestor`, and the `O_NOFOLLOW` + post-open re-check inside
|
|
20
|
-
* `readFileBuffer`/`writeFile`) so there is a SINGLE sandbox implementation: a
|
|
21
|
-
* symlink inside the root pointing outside it cannot be followed to read or
|
|
22
|
-
* write past the sandbox. The active project root is read per-request (via the
|
|
23
|
-
* injected getter) so project switches take effect immediately.
|
|
24
|
-
*
|
|
25
|
-
* Mutating actions (write/mkdir/delete/rename) additionally require a non-GET
|
|
26
|
-
* method and a same-origin (or origin-less) request, so an arbitrary localhost
|
|
27
|
-
* page cannot drive a destructive `/__fs` call. GET serves only the read-only
|
|
28
|
-
* stat/readdir/read actions.
|
|
29
|
-
*/
|
|
30
|
-
import http from 'node:http';
|
|
31
|
-
import nodeFs from 'node:fs';
|
|
32
1
|
import fs from 'node:fs/promises';
|
|
33
2
|
import path from 'node:path';
|
|
34
|
-
import { readFileBufferWithin, writeFileWithin, statWithin, readdirWithin, mkdirWithin, deleteWithin, renameWithin, } from '../ipc/project-fs.js';
|
|
3
|
+
import { readFileBufferWithin, writeFileWithin, statWithin, readdirWithin, mkdirWithin, deleteWithin, renameWithin, SKIP_DIRS, } from '../ipc/project-fs.js';
|
|
4
|
+
import { handleFsWatchRequest } from './fs-watch-sse.js';
|
|
5
|
+
import { createCoiServerShutdown } from './workbench-coi-shutdown.js';
|
|
6
|
+
import { serveStaticFile } from './workbench-coi-static.js';
|
|
7
|
+
import { registerCoiHostSession } from './workbench-coi-host.js';
|
|
8
|
+
import { FS_TYPE_DIR, FS_TYPE_FILE, toFsBridgeEntry } from './fs-bridge-protocol.js';
|
|
9
|
+
import { jsonRes } from './http-json.js';
|
|
10
|
+
import { miniappPartitionKey } from './views/miniapp-partition.js';
|
|
35
11
|
/** Max `/__fs/write` body; enough to save large source files without OOM. */
|
|
36
12
|
const MAX_FS_WRITE_BYTES = 32 * 1024 * 1024;
|
|
37
|
-
const MIME = {
|
|
38
|
-
'.html': 'text/html; charset=utf-8',
|
|
39
|
-
'.js': 'text/javascript; charset=utf-8',
|
|
40
|
-
'.mjs': 'text/javascript; charset=utf-8',
|
|
41
|
-
'.css': 'text/css; charset=utf-8',
|
|
42
|
-
'.json': 'application/json; charset=utf-8',
|
|
43
|
-
'.map': 'application/json; charset=utf-8',
|
|
44
|
-
'.wasm': 'application/wasm',
|
|
45
|
-
'.svg': 'image/svg+xml',
|
|
46
|
-
'.png': 'image/png',
|
|
47
|
-
'.ttf': 'font/ttf',
|
|
48
|
-
'.woff': 'font/woff',
|
|
49
|
-
'.woff2': 'font/woff2',
|
|
50
|
-
'.ico': 'image/x-icon',
|
|
51
|
-
};
|
|
52
|
-
function setIsolationHeaders(res) {
|
|
53
|
-
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
|
54
|
-
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
|
|
55
|
-
res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
|
|
56
|
-
}
|
|
57
|
-
/** Resolve a request pathname inside `root`, rejecting lexical traversal escapes. */
|
|
58
|
-
function containedStaticPath(root, pathname) {
|
|
59
|
-
const rel = pathname.replace(/^\/+/, '') || 'index.html';
|
|
60
|
-
const resolved = path.resolve(root, rel);
|
|
61
|
-
if (resolved !== root && !resolved.startsWith(root + path.sep))
|
|
62
|
-
return null;
|
|
63
|
-
return resolved;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Serve a static file under `root`: lexical containment, then `fs.realpath`
|
|
67
|
-
* BOTH the root and the resolved file before stat/stream, so a symlink inside
|
|
68
|
-
* `root` pointing outside it cannot be served (the lexical check alone follows
|
|
69
|
-
* symlinks because `stat`/`createReadStream` do). Sends the response itself.
|
|
70
|
-
*/
|
|
71
|
-
function serveStaticFile(res, root, pathname) {
|
|
72
|
-
const candidate = containedStaticPath(root, pathname);
|
|
73
|
-
if (!candidate) {
|
|
74
|
-
res.writeHead(403);
|
|
75
|
-
res.end('Forbidden');
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
Promise.all([fs.realpath(root), fs.realpath(candidate)])
|
|
79
|
-
.then(([realRoot, realFile]) => {
|
|
80
|
-
if (realFile !== realRoot && !realFile.startsWith(realRoot + path.sep)) {
|
|
81
|
-
res.writeHead(403);
|
|
82
|
-
res.end('Forbidden');
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
nodeFs.stat(realFile, (err, stat) => {
|
|
86
|
-
if (err || !stat.isFile()) {
|
|
87
|
-
res.writeHead(404);
|
|
88
|
-
res.end('Not Found');
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
res.writeHead(200, {
|
|
92
|
-
'Content-Type': MIME[path.extname(realFile)] ?? 'application/octet-stream',
|
|
93
|
-
'Content-Length': stat.size,
|
|
94
|
-
'Cache-Control': 'no-store',
|
|
95
|
-
});
|
|
96
|
-
// Stream the realpath'd file (already resolved to its real on-disk
|
|
97
|
-
// location, so a symlink inside the root cannot redirect it outside).
|
|
98
|
-
nodeFs.createReadStream(realFile).pipe(res);
|
|
99
|
-
});
|
|
100
|
-
})
|
|
101
|
-
.catch(() => { if (!res.headersSent) {
|
|
102
|
-
res.writeHead(404);
|
|
103
|
-
res.end('Not Found');
|
|
104
|
-
} });
|
|
105
|
-
}
|
|
106
|
-
function jsonRes(res, code, obj) {
|
|
107
|
-
const body = Buffer.from(JSON.stringify(obj));
|
|
108
|
-
res.writeHead(code, { 'Content-Type': 'application/json; charset=utf-8', 'Content-Length': body.length });
|
|
109
|
-
res.end(body);
|
|
110
|
-
}
|
|
111
13
|
/** Thrown by {@link readBody} when the accumulated body exceeds the cap. */
|
|
112
14
|
class BodyTooLargeError extends Error {
|
|
113
15
|
constructor() {
|
|
@@ -178,6 +80,22 @@ function rejectUnsafeMutation(req) {
|
|
|
178
80
|
return null;
|
|
179
81
|
}
|
|
180
82
|
/** Map a node fs error to the HTTP status the provider expects. */
|
|
83
|
+
/**
|
|
84
|
+
* Percent-decode a request path, answering the client on a malformed escape.
|
|
85
|
+
* A stray `%` is the client's error and belongs here, not at the shared
|
|
86
|
+
* listener's exception boundary, which cannot tell a bad request from a bug in
|
|
87
|
+
* this handler. Returns `null` once the 400 has been sent.
|
|
88
|
+
*/
|
|
89
|
+
function decodePath(res, pathname) {
|
|
90
|
+
try {
|
|
91
|
+
return decodeURIComponent(pathname);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
res.writeHead(400);
|
|
95
|
+
res.end('Bad Request');
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
181
99
|
function fsErrorStatus(e) {
|
|
182
100
|
const code = e.code;
|
|
183
101
|
if (code === 'ENOACTIVE')
|
|
@@ -186,15 +104,33 @@ function fsErrorStatus(e) {
|
|
|
186
104
|
return 403;
|
|
187
105
|
if (code === 'ENOENT')
|
|
188
106
|
return 404;
|
|
107
|
+
// Reading a path that is (now) a DIRECTORY: as a *file* it does not exist.
|
|
108
|
+
// 404 lets the sync engine's not-found discipline retire the stale ledger
|
|
109
|
+
// FILE record when an external change replaces a file with a same-named
|
|
110
|
+
// directory — a 500 would make it skip forever ("transient failure").
|
|
111
|
+
if (code === 'EISDIR')
|
|
112
|
+
return 404;
|
|
189
113
|
return 500;
|
|
190
114
|
}
|
|
191
115
|
async function fsStat(ctx) {
|
|
192
116
|
const st = await statWithin(ctx.projectRoot, ctx.rel);
|
|
193
|
-
|
|
117
|
+
const payload = {
|
|
118
|
+
type: st.isDirectory() ? FS_TYPE_DIR : FS_TYPE_FILE,
|
|
119
|
+
size: st.size,
|
|
120
|
+
ctime: st.ctimeMs,
|
|
121
|
+
mtime: st.mtimeMs,
|
|
122
|
+
};
|
|
123
|
+
jsonRes(ctx.res, 200, payload);
|
|
194
124
|
}
|
|
195
125
|
async function fsReaddir(ctx) {
|
|
196
126
|
const entries = await readdirWithin(ctx.projectRoot, ctx.rel);
|
|
197
|
-
|
|
127
|
+
// Directories in SKIP_DIRS (node_modules, .git, dist, ...) are omitted at
|
|
128
|
+
// every level: the workbench mirror and the WAL ledger seed walk whatever
|
|
129
|
+
// this returns, so listing them would pull entire dependency trees into the
|
|
130
|
+
// editor memfs and the OPFS ledger. Same-named FILES stay visible.
|
|
131
|
+
const visible = entries.filter((e) => !(e.isDirectory && SKIP_DIRS.has(e.name)));
|
|
132
|
+
// Wire shape and why it carries stats: see fs-bridge-protocol.ts.
|
|
133
|
+
jsonRes(ctx.res, 200, visible.map(toFsBridgeEntry));
|
|
198
134
|
}
|
|
199
135
|
async function fsRead(ctx) {
|
|
200
136
|
const buf = await readFileBufferWithin(ctx.projectRoot, ctx.rel);
|
|
@@ -317,12 +253,46 @@ async function readContributedExtensions(extensionsDir) {
|
|
|
317
253
|
}
|
|
318
254
|
return out;
|
|
319
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* The `/__project` workspace id: the miniapp partition key of the active
|
|
258
|
+
* project, or null when there is no committed project identity yet.
|
|
259
|
+
*
|
|
260
|
+
* Reuses `miniappPartitionKey` (the same derivation the per-project Electron
|
|
261
|
+
* session partition uses) so the editor's storage bucket and the runtime's
|
|
262
|
+
* storage partition are named off the same project identity: the `appId`,
|
|
263
|
+
* disambiguated by the project path because `appId` comes from the manifest and
|
|
264
|
+
* two checkouts can declare the same one.
|
|
265
|
+
*/
|
|
266
|
+
function workspaceIdOf(identity) {
|
|
267
|
+
if (!identity?.appId)
|
|
268
|
+
return null;
|
|
269
|
+
return miniappPartitionKey(identity.appId, identity.projectPath || null);
|
|
270
|
+
}
|
|
320
271
|
export async function startWorkbenchCoiServer(options) {
|
|
321
272
|
const root = path.resolve(options.rootDir);
|
|
322
273
|
const contribRoot = options.extensionsDir ? path.resolve(options.extensionsDir) : null;
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
274
|
+
const shutdown = createCoiServerShutdown();
|
|
275
|
+
const handle = (req, res, url) => {
|
|
276
|
+
// This window is tearing down. Anything accepted from here on would act on
|
|
277
|
+
// a project the user has already closed, and a new SSE stream would outlive
|
|
278
|
+
// the drain that was supposed to end them all.
|
|
279
|
+
if (shutdown.closing) {
|
|
280
|
+
res.writeHead(503);
|
|
281
|
+
res.end('Closing');
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
// Special-cased ahead of the generic `/__fs/*` dispatch: unlike every other
|
|
285
|
+
// action, this is a long-lived SSE stream, not a one-shot JSON response.
|
|
286
|
+
if (url.pathname === '/__fs/watch') {
|
|
287
|
+
const endStream = handleFsWatchRequest(req, res, options.getProjectRoot);
|
|
288
|
+
if (endStream)
|
|
289
|
+
shutdown.trackWatchStream(res, endStream);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
// Everything below answers once. Shutdown lets these land rather than
|
|
293
|
+
// dropping the socket under them — a `/__fs/write` mid-body is the file the
|
|
294
|
+
// user just saved.
|
|
295
|
+
shutdown.trackRequest(res);
|
|
326
296
|
if (url.pathname.startsWith('/__fs/')) {
|
|
327
297
|
handleFsRequest(req, res, options.getProjectRoot(), url).catch((e) => {
|
|
328
298
|
if (!res.headersSent)
|
|
@@ -336,6 +306,22 @@ export async function startWorkbenchCoiServer(options) {
|
|
|
336
306
|
jsonRes(res, 200, options.getFileTypes?.() ?? {});
|
|
337
307
|
return;
|
|
338
308
|
}
|
|
309
|
+
// Identity of the active project, as the id the editor names its VS Code
|
|
310
|
+
// workspace after. Every project is mirrored at the same constant
|
|
311
|
+
// `file:///workspace` root, and VS Code keys WORKSPACE-scope storage (open
|
|
312
|
+
// editors, view state, explorer expansion) off the workspace identity — so
|
|
313
|
+
// without a distinct id per project, one project's tabs are restored into
|
|
314
|
+
// the next, stranded behind "the file was not found".
|
|
315
|
+
//
|
|
316
|
+
// Served here rather than baked into the editor's load URL because the
|
|
317
|
+
// editor view can attach BEFORE the open commits its session (its attach
|
|
318
|
+
// gate self-releases on a slow compile), when there is no identity to hand
|
|
319
|
+
// it; `null` then tells the page to keep polling, the same way its disk
|
|
320
|
+
// mirror already polls `/__fs` for the project root to appear.
|
|
321
|
+
if (url.pathname === '/__project') {
|
|
322
|
+
jsonRes(res, 200, { workspaceId: workspaceIdOf(options.getProjectIdentity?.()) });
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
339
325
|
// Host-contributed web extensions: manifest + static files (same-origin so
|
|
340
326
|
// they satisfy the workbench's COEP require-corp).
|
|
341
327
|
if (url.pathname.startsWith('/__contrib/')) {
|
|
@@ -351,25 +337,39 @@ export async function startWorkbenchCoiServer(options) {
|
|
|
351
337
|
jsonRes(res, 500, { error: String(e) }); });
|
|
352
338
|
return;
|
|
353
339
|
}
|
|
354
|
-
const rel =
|
|
340
|
+
const rel = decodePath(res, url.pathname.slice('/__contrib/'.length));
|
|
341
|
+
if (rel === null)
|
|
342
|
+
return;
|
|
355
343
|
serveStaticFile(res, contribRoot, rel);
|
|
356
344
|
return;
|
|
357
345
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
});
|
|
367
|
-
const addr = server.address();
|
|
368
|
-
const port = typeof addr === 'object' && addr ? addr.port : 0;
|
|
346
|
+
const filePath = decodePath(res, url.pathname);
|
|
347
|
+
if (filePath === null)
|
|
348
|
+
return;
|
|
349
|
+
serveStaticFile(res, root, filePath);
|
|
350
|
+
};
|
|
351
|
+
// The listener is shared with every other project window so they land on one
|
|
352
|
+
// origin; this window is reached through its own path prefix. See
|
|
353
|
+
// workbench-coi-host.ts for why the port cannot be per-window.
|
|
354
|
+
const registration = await registerCoiHostSession({ rootDir: root, extensionsDir: contribRoot, session: { handle } });
|
|
369
355
|
return {
|
|
370
|
-
baseUrl:
|
|
371
|
-
port,
|
|
372
|
-
|
|
356
|
+
baseUrl: `${registration.origin}/w/${registration.token}/`,
|
|
357
|
+
port: registration.port,
|
|
358
|
+
// Why this is not a bare `server.close()`: see workbench-coi-shutdown.ts.
|
|
359
|
+
// Drain first so this window's SSE streams end and its in-flight writes
|
|
360
|
+
// land, THEN drop the route — the listener itself only goes away with the
|
|
361
|
+
// last window.
|
|
362
|
+
close: async () => {
|
|
363
|
+
// `finally`: a drain that throws must still drop this window's route.
|
|
364
|
+
// Leaving it registered would keep a torn-down window's bridge reachable
|
|
365
|
+
// on the shared listener for the rest of the process.
|
|
366
|
+
try {
|
|
367
|
+
await shutdown.drain();
|
|
368
|
+
}
|
|
369
|
+
finally {
|
|
370
|
+
await registration.release();
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
373
|
};
|
|
374
374
|
}
|
|
375
375
|
//# sourceMappingURL=workbench-coi-server.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shutdown bookkeeping for the workbench COI bridge, at two levels.
|
|
3
|
+
*
|
|
4
|
+
* A project window's bridge is closed as part of that window's teardown, which
|
|
5
|
+
* awaits it. Two things pull against each other at that moment. `/__fs/watch`
|
|
6
|
+
* is an SSE stream that only ever ends when its client disconnects, so waiting
|
|
7
|
+
* on it waits on the editor being destroyed in the same breath — the window
|
|
8
|
+
* hangs. Dropping every socket outright instead loses a `/__fs/write` whose
|
|
9
|
+
* body is still arriving, which is the file the user just saved.
|
|
10
|
+
*
|
|
11
|
+
* So neither extreme: {@link CoiServerShutdown.drain} ends the streams this
|
|
12
|
+
* owner started, lets a request already being served finish, and returns once
|
|
13
|
+
* it has — or once the grace window expires, so teardown is bounded no matter
|
|
14
|
+
* what a client does. The shared listener behind every window (see
|
|
15
|
+
* workbench-coi-host.ts) then uses {@link CoiServerShutdown.close}, which adds
|
|
16
|
+
* the server close and takes the sockets that outlived it.
|
|
17
|
+
*/
|
|
18
|
+
import type http from 'node:http';
|
|
19
|
+
export interface CoiServerShutdown {
|
|
20
|
+
/** A live `/__fs/watch` stream, with the call that ends it server-side. */
|
|
21
|
+
trackWatchStream: (res: http.ServerResponse, endStream: () => void) => void;
|
|
22
|
+
/** A one-shot request whose response must be allowed to land. */
|
|
23
|
+
trackRequest: (res: http.ServerResponse) => void;
|
|
24
|
+
/**
|
|
25
|
+
* True once {@link drain} has started. The owner refuses new requests from
|
|
26
|
+
* here on: this bridge is bound to a window that is going away, and a
|
|
27
|
+
* request accepted now would act on a project the user has closed.
|
|
28
|
+
*/
|
|
29
|
+
readonly closing: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* End the tracked streams and wait for the tracked one-shot responses to
|
|
32
|
+
* land, bounded by the grace window. Leaves the listener alone — one window
|
|
33
|
+
* going away must not take the shared server with it.
|
|
34
|
+
*/
|
|
35
|
+
drain: () => Promise<void>;
|
|
36
|
+
/** {@link drain}, plus closing the server and taking any surviving sockets. */
|
|
37
|
+
close: (server: http.Server) => Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
export declare function createCoiServerShutdown(graceMs?: number): CoiServerShutdown;
|
|
40
|
+
//# sourceMappingURL=workbench-coi-shutdown.d.ts.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** How long a request already in flight may hold up the window's teardown. */
|
|
2
|
+
const DEFAULT_GRACE_MS = 2_000;
|
|
3
|
+
export function createCoiServerShutdown(graceMs = DEFAULT_GRACE_MS) {
|
|
4
|
+
const watchStreams = new Set();
|
|
5
|
+
const inFlight = new Set();
|
|
6
|
+
let onDrained = null;
|
|
7
|
+
let closing = false;
|
|
8
|
+
const drain = () => new Promise((resolve) => {
|
|
9
|
+
closing = true;
|
|
10
|
+
for (const endStream of watchStreams)
|
|
11
|
+
endStream();
|
|
12
|
+
watchStreams.clear();
|
|
13
|
+
// Nothing is being served: the sockets that remain are a client's to
|
|
14
|
+
// keep alive, and waiting on them is waiting on nobody.
|
|
15
|
+
if (inFlight.size === 0) {
|
|
16
|
+
resolve();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
let deadline = null;
|
|
20
|
+
const finish = () => {
|
|
21
|
+
onDrained = null;
|
|
22
|
+
if (deadline)
|
|
23
|
+
clearTimeout(deadline);
|
|
24
|
+
resolve();
|
|
25
|
+
};
|
|
26
|
+
const expire = () => {
|
|
27
|
+
// The grace window is up and something is still mid-request — a client
|
|
28
|
+
// that stalled halfway through a body, most likely. Destroying it here
|
|
29
|
+
// is the point: the handler still holds the closing window's project,
|
|
30
|
+
// so a body that lands minutes from now would write into a project the
|
|
31
|
+
// user has closed, and the socket would outlive the window on the
|
|
32
|
+
// shared listener.
|
|
33
|
+
for (const res of [...inFlight])
|
|
34
|
+
res.destroy();
|
|
35
|
+
inFlight.clear();
|
|
36
|
+
finish();
|
|
37
|
+
};
|
|
38
|
+
deadline = setTimeout(expire, graceMs);
|
|
39
|
+
onDrained = finish;
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
get closing() {
|
|
43
|
+
return closing;
|
|
44
|
+
},
|
|
45
|
+
trackWatchStream(res, endStream) {
|
|
46
|
+
watchStreams.add(endStream);
|
|
47
|
+
res.on('close', () => watchStreams.delete(endStream));
|
|
48
|
+
},
|
|
49
|
+
trackRequest(res) {
|
|
50
|
+
inFlight.add(res);
|
|
51
|
+
res.on('close', () => {
|
|
52
|
+
inFlight.delete(res);
|
|
53
|
+
if (inFlight.size === 0)
|
|
54
|
+
onDrained?.();
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
drain,
|
|
58
|
+
async close(server) {
|
|
59
|
+
// Stop accepting first, so nothing new arrives during the drain; the
|
|
60
|
+
// callback only fires once every connection is gone, which is why the
|
|
61
|
+
// sockets are taken below rather than waited on.
|
|
62
|
+
const closed = new Promise((resolve) => server.close(() => resolve()));
|
|
63
|
+
await drain();
|
|
64
|
+
server.closeAllConnections();
|
|
65
|
+
await closed;
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=workbench-coi-shutdown.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static-file serving and the cross-origin-isolation headers shared by the
|
|
3
|
+
* workbench COI host and every window's bridge.
|
|
4
|
+
*
|
|
5
|
+
* Split out of `workbench-coi-server.ts` so the host module can serve the
|
|
6
|
+
* bundle without importing the per-window bridge (which imports the host).
|
|
7
|
+
*/
|
|
8
|
+
import http from 'node:http';
|
|
9
|
+
/**
|
|
10
|
+
* The workbench needs `SharedArrayBuffer` for the TS web ext-host's
|
|
11
|
+
* project-wide IntelliSense, and Chromium only serves that to a
|
|
12
|
+
* cross-origin-isolated document. Every response carries the three headers so
|
|
13
|
+
* same-origin sub-resources and workers satisfy COEP `require-corp`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function setIsolationHeaders(res: http.ServerResponse): void;
|
|
16
|
+
/**
|
|
17
|
+
* Serve a static file under `root`: lexical containment, then `fs.realpath`
|
|
18
|
+
* BOTH the root and the resolved file before stat/stream, so a symlink inside
|
|
19
|
+
* `root` pointing outside it cannot be served (the lexical check alone follows
|
|
20
|
+
* symlinks because `stat`/`createReadStream` do). Sends the response itself.
|
|
21
|
+
*/
|
|
22
|
+
export declare function serveStaticFile(res: http.ServerResponse, root: string, pathname: string): void;
|
|
23
|
+
//# sourceMappingURL=workbench-coi-static.d.ts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import nodeFs from 'node:fs';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
const MIME = {
|
|
5
|
+
'.html': 'text/html; charset=utf-8',
|
|
6
|
+
'.js': 'text/javascript; charset=utf-8',
|
|
7
|
+
'.mjs': 'text/javascript; charset=utf-8',
|
|
8
|
+
'.css': 'text/css; charset=utf-8',
|
|
9
|
+
'.json': 'application/json; charset=utf-8',
|
|
10
|
+
'.map': 'application/json; charset=utf-8',
|
|
11
|
+
'.wasm': 'application/wasm',
|
|
12
|
+
'.svg': 'image/svg+xml',
|
|
13
|
+
'.png': 'image/png',
|
|
14
|
+
'.ttf': 'font/ttf',
|
|
15
|
+
'.woff': 'font/woff',
|
|
16
|
+
'.woff2': 'font/woff2',
|
|
17
|
+
'.ico': 'image/x-icon',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The workbench needs `SharedArrayBuffer` for the TS web ext-host's
|
|
21
|
+
* project-wide IntelliSense, and Chromium only serves that to a
|
|
22
|
+
* cross-origin-isolated document. Every response carries the three headers so
|
|
23
|
+
* same-origin sub-resources and workers satisfy COEP `require-corp`.
|
|
24
|
+
*/
|
|
25
|
+
export function setIsolationHeaders(res) {
|
|
26
|
+
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
|
27
|
+
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
|
|
28
|
+
res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
|
|
29
|
+
}
|
|
30
|
+
/** Resolve a request pathname inside `root`, rejecting lexical traversal escapes. */
|
|
31
|
+
function containedStaticPath(root, pathname) {
|
|
32
|
+
const rel = pathname.replace(/^\/+/, '') || 'index.html';
|
|
33
|
+
const resolved = path.resolve(root, rel);
|
|
34
|
+
if (resolved !== root && !resolved.startsWith(root + path.sep))
|
|
35
|
+
return null;
|
|
36
|
+
return resolved;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Serve a static file under `root`: lexical containment, then `fs.realpath`
|
|
40
|
+
* BOTH the root and the resolved file before stat/stream, so a symlink inside
|
|
41
|
+
* `root` pointing outside it cannot be served (the lexical check alone follows
|
|
42
|
+
* symlinks because `stat`/`createReadStream` do). Sends the response itself.
|
|
43
|
+
*/
|
|
44
|
+
export function serveStaticFile(res, root, pathname) {
|
|
45
|
+
const candidate = containedStaticPath(root, pathname);
|
|
46
|
+
if (!candidate) {
|
|
47
|
+
res.writeHead(403);
|
|
48
|
+
res.end('Forbidden');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
Promise.all([fs.realpath(root), fs.realpath(candidate)])
|
|
52
|
+
.then(([realRoot, realFile]) => {
|
|
53
|
+
if (realFile !== realRoot && !realFile.startsWith(realRoot + path.sep)) {
|
|
54
|
+
res.writeHead(403);
|
|
55
|
+
res.end('Forbidden');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
nodeFs.stat(realFile, (err, stat) => {
|
|
59
|
+
if (err || !stat.isFile()) {
|
|
60
|
+
res.writeHead(404);
|
|
61
|
+
res.end('Not Found');
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
res.writeHead(200, {
|
|
65
|
+
'Content-Type': MIME[path.extname(realFile)] ?? 'application/octet-stream',
|
|
66
|
+
'Content-Length': stat.size,
|
|
67
|
+
'Cache-Control': 'no-store',
|
|
68
|
+
});
|
|
69
|
+
// Stream the realpath'd file (already resolved to its real on-disk
|
|
70
|
+
// location, so a symlink inside the root cannot redirect it outside).
|
|
71
|
+
const stream = nodeFs.createReadStream(realFile);
|
|
72
|
+
// The file can vanish or lose permissions between the stat and the
|
|
73
|
+
// open. The stream reports that asynchronously, once the 200 and the
|
|
74
|
+
// Content-Length are already on the wire, so no status can be changed
|
|
75
|
+
// — and an unhandled 'error' on a stream is an uncaught exception in
|
|
76
|
+
// the main process. Take the socket instead, which is what a client
|
|
77
|
+
// sees for a truncated body anyway.
|
|
78
|
+
stream.on('error', () => { res.destroy(); });
|
|
79
|
+
stream.pipe(res);
|
|
80
|
+
});
|
|
81
|
+
})
|
|
82
|
+
.catch(() => { if (!res.headersSent) {
|
|
83
|
+
res.writeHead(404);
|
|
84
|
+
res.end('Not Found');
|
|
85
|
+
} });
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=workbench-coi-static.js.map
|