@dimina-kit/devtools 0.4.0-dev.20260828161241 → 0.4.0-dev.20260907055341
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 +52 -729
- package/dist/main/app/app.d.ts +27 -7
- package/dist/main/app/app.js +285 -681
- 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/menu-setup.d.ts +13 -0
- package/dist/main/app/menu-setup.js +49 -0
- 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 +178 -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 +10669 -9096
- package/dist/main/ipc/app.d.ts +4 -1
- package/dist/main/ipc/app.js +4 -3
- 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 +1 -0
- package/dist/main/ipc/index.js +1 -0
- package/dist/main/ipc/internal-devtools.d.ts +2 -1
- package/dist/main/ipc/internal-devtools.js +4 -3
- package/dist/main/ipc/popover.d.ts +4 -1
- package/dist/main/ipc/popover.js +25 -9
- package/dist/main/ipc/project-create.d.ts +2 -1
- package/dist/main/ipc/project-create.js +6 -5
- package/dist/main/ipc/project-fs.d.ts +3 -1
- package/dist/main/ipc/project-fs.js +17 -17
- package/dist/main/ipc/projects.d.ts +3 -3
- package/dist/main/ipc/projects.js +13 -12
- package/dist/main/ipc/session.d.ts +4 -1
- package/dist/main/ipc/session.js +16 -11
- package/dist/main/ipc/settings.d.ts +4 -1
- package/dist/main/ipc/settings.js +12 -19
- package/dist/main/ipc/simulator-module.d.ts +5 -0
- package/dist/main/ipc/simulator-module.js +9 -5
- package/dist/main/ipc/simulator.d.ts +4 -1
- package/dist/main/ipc/simulator.js +12 -18
- package/dist/main/ipc/tooltip.d.ts +2 -1
- package/dist/main/ipc/tooltip.js +8 -7
- package/dist/main/ipc/views.d.ts +4 -1
- package/dist/main/ipc/views.js +20 -9
- package/dist/main/runtime/devtools-backend-before-quit.harness.d.ts +2 -20
- package/dist/main/runtime/devtools-backend-before-quit.harness.js +14 -283
- package/dist/main/runtime/devtools-backend.js +14 -3
- 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/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/default-adapter.js +1 -1
- 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 +8 -1
- package/dist/main/services/fs-watch-sse.js +19 -5
- 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/target-manager.d.ts +71 -23
- package/dist/main/services/mcp/target-manager.js +269 -142
- 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 +29 -6
- package/dist/main/services/mcp/tools/project-tools.js +37 -25
- package/dist/main/services/module.d.ts +13 -5
- package/dist/main/services/notifications/renderer-notifier.d.ts +28 -4
- package/dist/main/services/notifications/renderer-notifier.js +15 -3
- package/dist/main/services/projects/local-provider.js +2 -0
- package/dist/main/services/projects/project-repository.d.ts +31 -1
- package/dist/main/services/projects/project-repository.js +144 -20
- package/dist/main/services/projects/types.d.ts +31 -8
- package/dist/main/services/safe-area/index.d.ts +19 -5
- package/dist/main/services/safe-area/index.js +38 -13
- package/dist/main/services/simulator/ui-extensions.d.ts +8 -0
- package/dist/main/services/simulator/ui-extensions.js +16 -6
- package/dist/main/services/simulator-storage/index.d.ts +12 -1
- package/dist/main/services/simulator-storage/index.js +22 -7
- 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/views/host-slot-port-channel.d.ts +20 -3
- package/dist/main/services/views/host-slot-port-channel.js +33 -5
- package/dist/main/services/views/managed-web-contents-view.js +21 -1
- package/dist/main/services/views/native-simulator-view.js +13 -16
- package/dist/main/services/views/overlay-panels-view.d.ts +13 -0
- package/dist/main/services/views/overlay-panels-view.js +31 -0
- package/dist/main/services/views/view-manager.d.ts +1 -1
- package/dist/main/services/views/view-manager.js +3 -0
- 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.js +75 -133
- 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 +27 -3
- package/dist/main/services/workbench-context.js +10 -5
- 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/workspace-compile-modes.d.ts +59 -0
- package/dist/main/services/workspace/workspace-compile-modes.js +93 -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 +4 -0
- package/dist/main/services/workspace/workspace-service.js +51 -84
- 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 +42 -36
- package/dist/main/utils/ipc-registry.js +117 -50
- package/dist/main/utils/sender-policy.d.ts +9 -0
- package/dist/main/utils/sender-policy.js +26 -3
- package/dist/main/utils/theme.d.ts +3 -2
- package/dist/main/utils/theme.js +3 -2
- 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/native-host/common/common.js +94 -73
- package/dist/native-host/render/render.js +4079 -3171
- package/dist/native-host/service/service.js +2 -2
- package/dist/preload/runtime/native-host.d.ts +4 -0
- package/dist/preload/runtime/temp-files.js +9 -2
- package/dist/preload/runtime/wait-for-slot-root.d.ts +7 -4
- package/dist/preload/runtime/wait-for-slot-root.js +36 -8
- package/dist/preload/windows/host-dialog-runtime.cjs +10 -3
- package/dist/preload/windows/host-dialog-runtime.cjs.map +2 -2
- package/dist/preload/windows/host-sidebar-runtime.cjs +10 -3
- package/dist/preload/windows/host-sidebar-runtime.cjs.map +2 -2
- package/dist/preload/windows/host-toolbar-runtime.cjs +10 -3
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
- package/dist/preload/windows/main.cjs +181 -4
- package/dist/preload/windows/main.cjs.map +4 -4
- package/dist/preload/windows/simulator.cjs +10 -0
- package/dist/preload/windows/simulator.cjs.map +2 -2
- package/dist/preload/windows/simulator.js +10 -0
- package/dist/render-host/pageFrame.html +1 -1
- package/dist/render-host/preload.cjs +16 -4
- 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-Bqi8hpdi.js → createLucideIcon-cZ9FlZZw.js} +2 -2
- 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-DKWdE1TK.js → dist-DIFlRMKe.js} +2 -2
- package/dist/renderer/assets/hostSidebarDefault-DRWh6OCt.js +2 -0
- package/dist/renderer/assets/index-CEL_XFge.js +2 -0
- package/dist/renderer/assets/{input-Ct3alvkq.js → input-CAObw95L.js} +2 -2
- 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-DGLHmmOq.js → jsx-runtime-DIw5wnYl.js} +1 -1
- 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-Bbjz75bP.js → projectCreateDialog-BmLqiYxn.js} +2 -2
- 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-B_-_YVbw.js → tooltip-D6AxXRk5.js} +2 -2
- package/dist/renderer/assets/types-Bh0hA7El.js +2 -0
- package/dist/renderer/assets/updateDialog-CwndJ0Bl.js +2 -0
- package/dist/renderer/assets/{utils-kfQov6Pa.js → utils-sEB5OZEQ.js} +2 -2
- 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-BLJ0wKsg.js +5 -0
- package/dist/renderer/assets/{workbenchSettings-CV4LVA9b.js → workbenchSettings-YD0Ctbm_.js} +3 -3
- package/dist/renderer/entries/device-picker/index.html +28 -0
- package/dist/renderer/entries/host-sidebar-default/index.html +6 -5
- package/dist/renderer/entries/main/index.html +16 -17
- package/dist/renderer/entries/popover/index.html +16 -10
- package/dist/renderer/entries/project-create-dialog/index.html +12 -12
- package/dist/renderer/entries/settings/index.html +10 -10
- package/dist/renderer/entries/tooltip/index.html +5 -5
- package/dist/renderer/entries/update-dialog/index.html +10 -10
- package/dist/renderer/entries/workbench/index.html +49 -0
- package/dist/renderer/entries/workbench-settings/index.html +12 -11
- package/dist/service-host/host-env-update.cjs +23 -0
- package/dist/service-host/preload.cjs +24 -49
- package/dist/service-host/service-message-queue.cjs +71 -0
- package/dist/service-host/sync-impls/system-info.js +31 -9
- 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/ipc-channels-overlays.d.ts +8 -2
- package/dist/shared/ipc-channels-overlays.js +19 -2
- package/dist/shared/ipc-channels.d.ts +5 -10
- package/dist/shared/ipc-channels.js +17 -14
- package/dist/shared/ipc-schemas.d.ts +76 -24
- package/dist/shared/ipc-schemas.js +55 -10
- package/dist/shared/project-window-types.d.ts +42 -0
- package/dist/shared/project-window-types.js +2 -0
- package/dist/shared/types.d.ts +43 -17
- package/dist/shared/view-ids.d.ts +1 -0
- package/dist/shared/view-ids.js +3 -1
- 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-pxnZZp10.js +431 -0
- package/dist/simulator/assets/simulator-Dwp7lnvu.js +10 -0
- package/dist/simulator/assets/simulator-mini-app-DFo7fhi5.js +2 -0
- package/dist/simulator/assets/simulator-ui-B2ddJB1R.js +2 -0
- package/dist/simulator/simulator.html +3 -3
- package/dist/simulator/temp-files.d.ts +6 -0
- package/dist/simulator/temp-files.js +46 -4
- package/dist/simulator/types.d.ts +7 -0
- package/dist/vscode-workbench/assets/__vite-browser-external-JIkWewFf.js +1 -0
- package/dist/vscode-workbench/assets/{dist-CMfmHflW.js → dist-CXG-u1VB.js} +3 -3
- package/dist/vscode-workbench/assets/{iconv-lite-umd-Bx8CgaZq.js → iconv-lite-umd-Dxx9Qyb4.js} +1 -1
- package/dist/vscode-workbench/assets/{index-CdG6YWhW.js → index-6VJMsaWj.js} +460 -460
- package/dist/vscode-workbench/assets/{jschardet-M0qgd2lN.js → jschardet-Ba3D16vt.js} +1 -1
- package/dist/vscode-workbench/index.html +1 -1
- package/package.json +11 -8
- package/dist/renderer/assets/button-D5Q2wkXq.js +0 -2
- package/dist/renderer/assets/constants-D7DfVqMp.js +0 -2
- package/dist/renderer/assets/constants-D8zsejFq.js +0 -2
- package/dist/renderer/assets/dialog-e1TecTOY.js +0 -46
- package/dist/renderer/assets/hostSidebarDefault-B3yLfy8j.js +0 -2
- package/dist/renderer/assets/index-CsPD68N_.js +0 -5
- package/dist/renderer/assets/ipc-channels-overlays-LsDzGAtV.js +0 -2
- package/dist/renderer/assets/jsx-runtime-2vXHouwr.css +0 -1
- package/dist/renderer/assets/popover-Dix5cm_b.js +0 -2
- package/dist/renderer/assets/project-api-k7Oq9iaq.js +0 -2
- package/dist/renderer/assets/select-acGb0AmJ.js +0 -2
- package/dist/renderer/assets/settings-CQrTMr43.js +0 -2
- package/dist/renderer/assets/settings-api-CrUQ9rYV.js +0 -2
- package/dist/renderer/assets/settings-tab-bar-Cw1kVIf2.js +0 -2
- package/dist/renderer/assets/types-CsEKtFyr.js +0 -2
- package/dist/renderer/assets/updateDialog-NsF8223A.js +0 -2
- package/dist/renderer/assets/view-api-CLn3rcQE.js +0 -2
- package/dist/simulator/assets/bridge-channels-zhsumfky.js +0 -2
- package/dist/simulator/assets/device-shell-CmtM1QxP.js +0 -2
- package/dist/simulator/assets/device-shell-iFZo1igL.css +0 -1
- package/dist/simulator/assets/simulator-CIobn3Mh.js +0 -10
- package/dist/simulator/assets/simulator-mini-app-CRe6n9br.js +0 -2
- package/dist/simulator/assets/simulator-ui-C_cP602X.js +0 -2
- package/dist/vscode-workbench/assets/__vite-browser-external-Bc1vizTf.js +0 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single owner of one open project's compile modes: the only thing allowed
|
|
3
|
+
* to read/write the persisted file and to advance the in-memory snapshot.
|
|
4
|
+
* `apply()` calls are serialized through a queue so two commands issued
|
|
5
|
+
* back-to-back never interleave their persists, and persist-before-adopt
|
|
6
|
+
* means a write that fails on disk is never visible in `get()` or broadcast
|
|
7
|
+
* to `onChange` listeners — memory never runs ahead of what's on disk.
|
|
8
|
+
*/
|
|
9
|
+
import { type CompileModeChange, type CompileModeCommand, type CompileModeSnapshot, type MintId } from '../../../shared/compile-mode-state.js';
|
|
10
|
+
import type { CompileModes } from '../../../shared/types.js';
|
|
11
|
+
export type { CompileModeChange, CompileModeSnapshot };
|
|
12
|
+
export interface CompileModeStore {
|
|
13
|
+
readonly projectPath: string;
|
|
14
|
+
get(): CompileModeSnapshot;
|
|
15
|
+
apply(command: CompileModeCommand): Promise<CompileModeChange>;
|
|
16
|
+
onChange(listener: (change: CompileModeChange) => void): () => void;
|
|
17
|
+
dispose(): void;
|
|
18
|
+
}
|
|
19
|
+
export declare function openCompileModeStore(input: {
|
|
20
|
+
projectPath: string;
|
|
21
|
+
load(): Promise<unknown>;
|
|
22
|
+
persist(stored: CompileModes): Promise<void>;
|
|
23
|
+
mintId?: MintId;
|
|
24
|
+
}): Promise<CompileModeStore>;
|
|
25
|
+
//# sourceMappingURL=compile-mode-store.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single owner of one open project's compile modes: the only thing allowed
|
|
3
|
+
* to read/write the persisted file and to advance the in-memory snapshot.
|
|
4
|
+
* `apply()` calls are serialized through a queue so two commands issued
|
|
5
|
+
* back-to-back never interleave their persists, and persist-before-adopt
|
|
6
|
+
* means a write that fails on disk is never visible in `get()` or broadcast
|
|
7
|
+
* to `onChange` listeners — memory never runs ahead of what's on disk.
|
|
8
|
+
*/
|
|
9
|
+
import { applyCompileModeCommand, stateFromStored, storedFromState, } from '../../../shared/compile-mode-state.js';
|
|
10
|
+
let nextIdCounter = 0;
|
|
11
|
+
function defaultMintId() {
|
|
12
|
+
nextIdCounter += 1;
|
|
13
|
+
return `compile-mode-${nextIdCounter}`;
|
|
14
|
+
}
|
|
15
|
+
export async function openCompileModeStore(input) {
|
|
16
|
+
const mintId = input.mintId ?? defaultMintId;
|
|
17
|
+
const raw = await input.load();
|
|
18
|
+
let revision = 0;
|
|
19
|
+
let state = stateFromStored(raw, mintId);
|
|
20
|
+
let disposed = false;
|
|
21
|
+
const listeners = new Set();
|
|
22
|
+
// Serializes apply() calls: each call chains onto this promise so the next
|
|
23
|
+
// command's persist only starts after the previous one has fully settled.
|
|
24
|
+
let queue = Promise.resolve();
|
|
25
|
+
function get() {
|
|
26
|
+
return { revision, state };
|
|
27
|
+
}
|
|
28
|
+
// Not `async` on purpose: an async function wrapping a returned promise
|
|
29
|
+
// adds an extra microtask hop before a caller's `.then` fires, which is
|
|
30
|
+
// enough to let the queue's OWN downstream continuation (chaining the next
|
|
31
|
+
// apply()) run ahead of a caller that is racing to inspect order — this
|
|
32
|
+
// function must return `run` itself so a caller's `.then` is attached
|
|
33
|
+
// directly to it, same as the queue's internal continuation.
|
|
34
|
+
function apply(command) {
|
|
35
|
+
if (disposed) {
|
|
36
|
+
return Promise.reject(new Error('compile-mode store disposed'));
|
|
37
|
+
}
|
|
38
|
+
const run = queue.then(() => runApply(command));
|
|
39
|
+
// Keep the queue alive even if this command rejects, so a later apply()
|
|
40
|
+
// still runs instead of being stuck behind a broken link forever.
|
|
41
|
+
queue = run.then(() => undefined, () => undefined);
|
|
42
|
+
return run;
|
|
43
|
+
}
|
|
44
|
+
async function runApply(command) {
|
|
45
|
+
if (disposed) {
|
|
46
|
+
throw new Error('compile-mode store disposed');
|
|
47
|
+
}
|
|
48
|
+
const result = applyCompileModeCommand(state, command, mintId);
|
|
49
|
+
if (result.state === state) {
|
|
50
|
+
// No-op: nothing to persist or broadcast.
|
|
51
|
+
return { revision, state, relaunch: false };
|
|
52
|
+
}
|
|
53
|
+
await input.persist(storedFromState(result.state));
|
|
54
|
+
state = result.state;
|
|
55
|
+
revision += 1;
|
|
56
|
+
const change = { revision, state, relaunch: result.relaunch };
|
|
57
|
+
for (const listener of listeners)
|
|
58
|
+
listener(change);
|
|
59
|
+
return change;
|
|
60
|
+
}
|
|
61
|
+
function onChange(listener) {
|
|
62
|
+
listeners.add(listener);
|
|
63
|
+
return () => listeners.delete(listener);
|
|
64
|
+
}
|
|
65
|
+
function dispose() {
|
|
66
|
+
disposed = true;
|
|
67
|
+
listeners.clear();
|
|
68
|
+
}
|
|
69
|
+
return { projectPath: input.projectPath, get, apply, onChange, dispose };
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=compile-mode-store.js.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wires a `CompileModeStore` into `WorkspaceService` for whichever project is
|
|
3
|
+
* currently open. Extracted out of workspace-service.ts to keep that file
|
|
4
|
+
* under the repo's file-length ratchet — this is the sole owner of the
|
|
5
|
+
* store's lifecycle (open/replace/dispose); `WorkspaceService` only forwards
|
|
6
|
+
* to it.
|
|
7
|
+
*/
|
|
8
|
+
import { type CompileModeCommand } from '../../../shared/compile-mode-state.js';
|
|
9
|
+
import type { CompileConfig } from '../../../shared/types.js';
|
|
10
|
+
import type { ProjectsProvider } from '../projects/types.js';
|
|
11
|
+
import { type CompileModeChange, type CompileModeSnapshot, type CompileModeStore } from './compile-mode-store.js';
|
|
12
|
+
export interface CompileModeManager {
|
|
13
|
+
/**
|
|
14
|
+
* Creates and returns a store for `projectPath` as a standalone handle —
|
|
15
|
+
* it does NOT touch the current store or subscribe to `onChange`. The
|
|
16
|
+
* caller owns the handle until it either passes it to `adopt` or disposes
|
|
17
|
+
* it itself (e.g. because the open it belongs to was superseded).
|
|
18
|
+
*/
|
|
19
|
+
open(projectPath: string): Promise<CompileModeStore>;
|
|
20
|
+
/**
|
|
21
|
+
* Makes `store` the current one: disposes whatever was current (and its
|
|
22
|
+
* subscription) first, then wires `store` up. The current store must only
|
|
23
|
+
* ever change here, alongside the session it belongs to — never as a side
|
|
24
|
+
* effect of merely opening one.
|
|
25
|
+
*/
|
|
26
|
+
adopt(store: CompileModeStore): void;
|
|
27
|
+
/** Disposes the current store, if any. Safe to call when none is open. */
|
|
28
|
+
disposeCurrent(): void;
|
|
29
|
+
/**
|
|
30
|
+
* `projectPath` omitted returns the currently open project's snapshot
|
|
31
|
+
* (for callers, like the popover, that don't track a project path of
|
|
32
|
+
* their own); given, it must match the open store's project or this
|
|
33
|
+
* throws — a caller that DOES know the path never silently reads another
|
|
34
|
+
* project's modes.
|
|
35
|
+
*/
|
|
36
|
+
getCompileModeState(projectPath?: string): CompileModeSnapshot;
|
|
37
|
+
applyCompileModeCommand(command: CompileModeCommand): Promise<CompileModeChange>;
|
|
38
|
+
getCompileConfig(projectPath: string): Promise<CompileConfig>;
|
|
39
|
+
/** Untouched by the store redesign — a direct provider passthrough. */
|
|
40
|
+
saveCompileConfig(projectPath: string, config: CompileConfig): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
export declare function createCompileModeManager(provider: ProjectsProvider, onChange: (change: CompileModeChange) => void): CompileModeManager;
|
|
43
|
+
/**
|
|
44
|
+
* Opens a store handle for `projectPath` right after a compile succeeds,
|
|
45
|
+
* WITHOUT making it current — the caller decides whether to `adopt` it once
|
|
46
|
+
* it has confirmed (under the op lock) that its open is still the latest
|
|
47
|
+
* one; a superseded open disposes the handle itself instead. On failure,
|
|
48
|
+
* closes `session` (best-effort) and returns the error message. A session
|
|
49
|
+
* that compiled but whose store failed to open must not be left running, so
|
|
50
|
+
* this centralizes that cleanup for callers.
|
|
51
|
+
*/
|
|
52
|
+
export declare function openCompileModeStoreAfterCompile(manager: CompileModeManager, projectPath: string, session: {
|
|
53
|
+
close(): Promise<void>;
|
|
54
|
+
}): Promise<{
|
|
55
|
+
store: CompileModeStore;
|
|
56
|
+
} | {
|
|
57
|
+
error: string;
|
|
58
|
+
}>;
|
|
59
|
+
//# sourceMappingURL=workspace-compile-modes.d.ts.map
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wires a `CompileModeStore` into `WorkspaceService` for whichever project is
|
|
3
|
+
* currently open. Extracted out of workspace-service.ts to keep that file
|
|
4
|
+
* under the repo's file-length ratchet — this is the sole owner of the
|
|
5
|
+
* store's lifecycle (open/replace/dispose); `WorkspaceService` only forwards
|
|
6
|
+
* to it.
|
|
7
|
+
*/
|
|
8
|
+
import { selectedMode } from '../../../shared/compile-mode-state.js';
|
|
9
|
+
import { compileConfigFromMode } from '../../../shared/compile-modes.js';
|
|
10
|
+
import * as repo from '../projects/project-repository.js';
|
|
11
|
+
import { createCompileModeAdapter } from './compile-mode-adapter.js';
|
|
12
|
+
import { openCompileModeStore, } from './compile-mode-store.js';
|
|
13
|
+
export function createCompileModeManager(provider, onChange) {
|
|
14
|
+
const adapter = createCompileModeAdapter(provider);
|
|
15
|
+
let store = null;
|
|
16
|
+
let unsubscribe = null;
|
|
17
|
+
function disposeCurrent() {
|
|
18
|
+
unsubscribe?.();
|
|
19
|
+
unsubscribe = null;
|
|
20
|
+
store?.dispose();
|
|
21
|
+
store = null;
|
|
22
|
+
}
|
|
23
|
+
async function open(projectPath) {
|
|
24
|
+
return openCompileModeStore({
|
|
25
|
+
projectPath,
|
|
26
|
+
load: () => adapter.getCompileModes(projectPath),
|
|
27
|
+
persist: (stored) => adapter.saveCompileModes(projectPath, stored),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function adopt(handle) {
|
|
31
|
+
disposeCurrent();
|
|
32
|
+
store = handle;
|
|
33
|
+
unsubscribe = handle.onChange(onChange);
|
|
34
|
+
}
|
|
35
|
+
function getCompileModeState(projectPath) {
|
|
36
|
+
if (!store || (projectPath !== undefined && projectPath !== store.projectPath)) {
|
|
37
|
+
throw new Error(`no compile-mode store open for ${projectPath ?? ''}`);
|
|
38
|
+
}
|
|
39
|
+
return store.get();
|
|
40
|
+
}
|
|
41
|
+
function applyCompileModeCommand(command) {
|
|
42
|
+
if (!store)
|
|
43
|
+
return Promise.reject(new Error('no compile-mode store open'));
|
|
44
|
+
return store.apply(command);
|
|
45
|
+
}
|
|
46
|
+
// Mirrors project-repository.ts's own getCompileConfig: 普通编译 (and any
|
|
47
|
+
// selected mode that left its start page blank) resolves to an empty
|
|
48
|
+
// startPage, filled in here with the project's real entry page rather than
|
|
49
|
+
// a mini-program-only literal.
|
|
50
|
+
async function getCompileConfig(projectPath) {
|
|
51
|
+
if (store && store.projectPath === projectPath) {
|
|
52
|
+
const config = compileConfigFromMode(selectedMode(store.get().state));
|
|
53
|
+
if (config.startPage)
|
|
54
|
+
return config;
|
|
55
|
+
return { ...config, startPage: repo.getProjectPages(projectPath).entryPagePath };
|
|
56
|
+
}
|
|
57
|
+
return adapter.getCompileConfig(projectPath);
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
open,
|
|
61
|
+
adopt,
|
|
62
|
+
disposeCurrent,
|
|
63
|
+
getCompileModeState,
|
|
64
|
+
applyCompileModeCommand,
|
|
65
|
+
getCompileConfig,
|
|
66
|
+
saveCompileConfig: adapter.saveCompileConfig,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Opens a store handle for `projectPath` right after a compile succeeds,
|
|
71
|
+
* WITHOUT making it current — the caller decides whether to `adopt` it once
|
|
72
|
+
* it has confirmed (under the op lock) that its open is still the latest
|
|
73
|
+
* one; a superseded open disposes the handle itself instead. On failure,
|
|
74
|
+
* closes `session` (best-effort) and returns the error message. A session
|
|
75
|
+
* that compiled but whose store failed to open must not be left running, so
|
|
76
|
+
* this centralizes that cleanup for callers.
|
|
77
|
+
*/
|
|
78
|
+
export async function openCompileModeStoreAfterCompile(manager, projectPath, session) {
|
|
79
|
+
try {
|
|
80
|
+
const store = await manager.open(projectPath);
|
|
81
|
+
return { store };
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
try {
|
|
85
|
+
await session.close();
|
|
86
|
+
}
|
|
87
|
+
catch (closeErr) {
|
|
88
|
+
console.warn('[workspace] closing session after compile-mode store open failure (non-fatal):', closeErr);
|
|
89
|
+
}
|
|
90
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=workspace-compile-modes.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ProjectSession } from '../../../shared/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The forced `servicewechat.com` Referer is stored per project partition, so
|
|
4
|
+
* every workspace call must name the project it is acting for. Both helpers
|
|
5
|
+
* therefore take the session and project path explicitly: a workspace that
|
|
6
|
+
* reached for its own mutable `currentSession` after resetting it would clear
|
|
7
|
+
* nothing, and one that passed no project at all would be asking to wipe a
|
|
8
|
+
* partition that belongs to whichever project happens to be open elsewhere.
|
|
9
|
+
*/
|
|
10
|
+
/** Forces this project's Referer. No-op for a session without a usable appId. */
|
|
11
|
+
export declare function applyRefererForSession(session: ProjectSession, projectPath: string): void;
|
|
12
|
+
/**
|
|
13
|
+
* Clears only this project's own entry. Call BEFORE the caller resets its
|
|
14
|
+
* session/path state, otherwise there is no partition left to name.
|
|
15
|
+
*/
|
|
16
|
+
export declare function clearRefererForSession(session: ProjectSession | null, projectPath: string): void;
|
|
17
|
+
//# sourceMappingURL=workspace-referer.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { clearSimulatorServicewechatReferer, setSimulatorServicewechatReferer, } from '../simulator/referer.js';
|
|
2
|
+
/**
|
|
3
|
+
* The forced `servicewechat.com` Referer is stored per project partition, so
|
|
4
|
+
* every workspace call must name the project it is acting for. Both helpers
|
|
5
|
+
* therefore take the session and project path explicitly: a workspace that
|
|
6
|
+
* reached for its own mutable `currentSession` after resetting it would clear
|
|
7
|
+
* nothing, and one that passed no project at all would be asking to wipe a
|
|
8
|
+
* partition that belongs to whichever project happens to be open elsewhere.
|
|
9
|
+
*/
|
|
10
|
+
/** Forces this project's Referer. No-op for a session without a usable appId. */
|
|
11
|
+
export function applyRefererForSession(session, projectPath) {
|
|
12
|
+
const appInfo = session.appInfo;
|
|
13
|
+
if (!appInfo || typeof appInfo.appId !== 'string' || appInfo.appId.length === 0)
|
|
14
|
+
return;
|
|
15
|
+
setSimulatorServicewechatReferer(appInfo.appId, typeof appInfo.version === 'string' ? appInfo.version : undefined, projectPath);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Clears only this project's own entry. Call BEFORE the caller resets its
|
|
19
|
+
* session/path state, otherwise there is no partition left to name.
|
|
20
|
+
*/
|
|
21
|
+
export function clearRefererForSession(session, projectPath) {
|
|
22
|
+
if (!session)
|
|
23
|
+
return;
|
|
24
|
+
clearSimulatorServicewechatReferer(session.appInfo.appId, projectPath);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=workspace-referer.js.map
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { AppInfo, CompileConfig, ProjectSession } from '../../../shared/types.js';
|
|
2
|
+
import type { CompileModeCommand } from '../../../shared/compile-mode-state.js';
|
|
3
|
+
import type { CompileModeChange, CompileModeSnapshot } from './compile-mode-store.js';
|
|
2
4
|
import type { WorkbenchContext } from '../workbench-context.js';
|
|
3
5
|
import type { Project, ProjectPages, ProjectSettings } from '../projects/project-repository.js';
|
|
4
6
|
import type { ProjectPatch } from '../projects/types.js';
|
|
@@ -57,6 +59,8 @@ export interface WorkspaceService {
|
|
|
57
59
|
getProjectPages(projectPath: string): ProjectPages;
|
|
58
60
|
getCompileConfig(projectPath: string): Promise<CompileConfig>;
|
|
59
61
|
saveCompileConfig(projectPath: string, config: CompileConfig): Promise<void>;
|
|
62
|
+
getCompileModeState(projectPath?: string): CompileModeSnapshot;
|
|
63
|
+
applyCompileModeCommand(command: CompileModeCommand): Promise<CompileModeChange>;
|
|
60
64
|
getProjectSettings(projectPath: string): ProjectSettings;
|
|
61
65
|
updateProjectSettings(projectPath: string, patch: Partial<ProjectSettings>): void;
|
|
62
66
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { createCompileModeManager, openCompileModeStoreAfterCompile } from './workspace-compile-modes.js';
|
|
1
2
|
import { rejectInvalidAppId, validateProjectDirSafe } from './open-project-guards.js';
|
|
2
3
|
import * as repo from '../projects/project-repository.js';
|
|
3
4
|
import { reportRebuildStatus } from './rebuild-status.js';
|
|
4
|
-
import {
|
|
5
|
-
import { clearSimulatorServicewechatReferer, setSimulatorServicewechatReferer, } from '../simulator/referer.js';
|
|
5
|
+
import { applyRefererForSession, clearRefererForSession } from './workspace-referer.js';
|
|
6
6
|
import { loadWorkbenchSettings } from '../settings/index.js';
|
|
7
7
|
import { createOpLock } from './op-lock.js';
|
|
8
|
+
import { createThumbnailOps } from './workspace-thumbnails.js';
|
|
8
9
|
/** Build a workspace service bound to the given workbench context. */
|
|
9
10
|
export function createWorkspaceService(ctx) {
|
|
10
11
|
let currentSession = null;
|
|
@@ -69,7 +70,7 @@ export function createWorkspaceService(ctx) {
|
|
|
69
70
|
try {
|
|
70
71
|
if (!opLock.isOwner(mySeq))
|
|
71
72
|
return true;
|
|
72
|
-
|
|
73
|
+
clearRefererForSession(currentSession, currentProjectPath);
|
|
73
74
|
// Switching projects tears down the embedded workbench editor (mirrors one
|
|
74
75
|
// project's disk; saves would else hit the wrong project) AND the native
|
|
75
76
|
// simulator (its 'destroyed' hook owns the bridge session). Back-to-list
|
|
@@ -81,6 +82,8 @@ export function createWorkspaceService(ctx) {
|
|
|
81
82
|
// Invalidate the outgoing onLog generation before teardown so the dying
|
|
82
83
|
// worker's buffered lines can't pollute the incoming compile timeline.
|
|
83
84
|
logGeneration++;
|
|
85
|
+
// Dies with the outgoing session — no-op when none is open.
|
|
86
|
+
compileModes.disposeCurrent();
|
|
84
87
|
await disposeSession();
|
|
85
88
|
currentProjectPath = '';
|
|
86
89
|
lastClosedProjectPath = '';
|
|
@@ -91,17 +94,22 @@ export function createWorkspaceService(ctx) {
|
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
/**
|
|
94
|
-
* openProject critical section 2 — commit the new session
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
+
* openProject critical section 2 — commit the new session (and its
|
|
98
|
+
* compile-mode store handle) under the lock, only if still the latest
|
|
99
|
+
* request. Returns false when superseded (caller discards the
|
|
100
|
+
* freshly-opened session and store instead of clobbering the newer
|
|
101
|
+
* request's). `compileModes.adopt` must only run here, alongside
|
|
102
|
+
* `currentSession`/`currentProjectPath`, so the "current store" and
|
|
103
|
+
* "current session" always switch together.
|
|
97
104
|
*/
|
|
98
|
-
async function runOpenCommit(mySeq, session, projectPath) {
|
|
105
|
+
async function runOpenCommit(mySeq, session, projectPath, store) {
|
|
99
106
|
const release = await opLock.acquire();
|
|
100
107
|
try {
|
|
101
108
|
if (!opLock.isOwner(mySeq))
|
|
102
109
|
return false;
|
|
103
110
|
currentSession = session;
|
|
104
111
|
currentProjectPath = projectPath;
|
|
112
|
+
compileModes.adopt(store);
|
|
105
113
|
return true;
|
|
106
114
|
}
|
|
107
115
|
finally {
|
|
@@ -136,22 +144,26 @@ export function createWorkspaceService(ctx) {
|
|
|
136
144
|
return { session };
|
|
137
145
|
}
|
|
138
146
|
catch (err) {
|
|
139
|
-
|
|
147
|
+
// No appId resolved for this attempt; the outgoing project's own entry
|
|
148
|
+
// was already cleared by runOpenTeardown, so there is nothing to clear.
|
|
140
149
|
return { error: String(err) };
|
|
141
150
|
}
|
|
142
151
|
}
|
|
143
|
-
function applyRefererFromSession(session) {
|
|
144
|
-
const appInfo = session.appInfo;
|
|
145
|
-
if (appInfo && typeof appInfo.appId === 'string' && appInfo.appId.length > 0) {
|
|
146
|
-
setSimulatorServicewechatReferer(appInfo.appId, typeof appInfo.version === 'string' ? appInfo.version : undefined);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
152
|
// Delegate to the host-injected (or default LocalProjectsProvider)
|
|
150
153
|
// ProjectsProvider on the context. When the host omits an optional method,
|
|
151
154
|
// we apply a safe documented default — never silently fall back to
|
|
152
155
|
// `repo.*`, because a remote provider's project paths are not on the local
|
|
153
156
|
// filesystem.
|
|
154
157
|
const provider = ctx.projectsProvider;
|
|
158
|
+
// Owner of whichever project's compile modes are currently open; disposed/
|
|
159
|
+
// replaced alongside the session (teardown, openProject failures, close).
|
|
160
|
+
const compileModes = createCompileModeManager(provider, (change) => ctx.notify.compileModesChanged(change));
|
|
161
|
+
const thumbnails = createThumbnailOps({
|
|
162
|
+
ctx,
|
|
163
|
+
provider,
|
|
164
|
+
getSession: () => currentSession,
|
|
165
|
+
getProjectPath: () => currentProjectPath,
|
|
166
|
+
});
|
|
155
167
|
return {
|
|
156
168
|
listProjects: async () => provider.listProjects(),
|
|
157
169
|
addProject: async (dirPath) => provider.addProject(dirPath),
|
|
@@ -236,15 +248,27 @@ export function createWorkspaceService(ctx) {
|
|
|
236
248
|
return { success: false, error: compiled.error };
|
|
237
249
|
}
|
|
238
250
|
const session = compiled.session;
|
|
251
|
+
// Opened right after compile as a standalone handle — not yet current;
|
|
252
|
+
// every failure branch below disposes THIS handle, never the current
|
|
253
|
+
// store, since this open may no longer own "current" by the time it
|
|
254
|
+
// gets here.
|
|
255
|
+
const opened = await openCompileModeStoreAfterCompile(compileModes, projectPath, session);
|
|
256
|
+
if ('error' in opened) {
|
|
257
|
+
sendStatus('error', opened.error);
|
|
258
|
+
return { success: false, error: opened.error };
|
|
259
|
+
}
|
|
260
|
+
const store = opened.store;
|
|
239
261
|
const appIdError = await rejectInvalidAppId(session);
|
|
240
262
|
if (appIdError) {
|
|
263
|
+
store.dispose();
|
|
241
264
|
sendStatus('error', appIdError);
|
|
242
265
|
return { success: false, error: appIdError };
|
|
243
266
|
}
|
|
244
|
-
if (!(await runOpenCommit(mySeq, session, projectPath))) {
|
|
245
|
-
// Superseded
|
|
246
|
-
//
|
|
247
|
-
//
|
|
267
|
+
if (!(await runOpenCommit(mySeq, session, projectPath, store))) {
|
|
268
|
+
// Superseded — discard the freshly-opened session and its own store
|
|
269
|
+
// handle rather than clobber the newer request's (already-adopted)
|
|
270
|
+
// current store.
|
|
271
|
+
store.dispose();
|
|
248
272
|
try {
|
|
249
273
|
await session.close();
|
|
250
274
|
}
|
|
@@ -258,7 +282,7 @@ export function createWorkspaceService(ctx) {
|
|
|
258
282
|
provider.updateLastOpened(projectPath);
|
|
259
283
|
});
|
|
260
284
|
bestEffort('sendStatus', () => sendStatus('ready', '编译完成'));
|
|
261
|
-
bestEffort('applyReferer', () =>
|
|
285
|
+
bestEffort('applyReferer', () => applyRefererForSession(session, projectPath));
|
|
262
286
|
return {
|
|
263
287
|
success: true,
|
|
264
288
|
port: session.port,
|
|
@@ -292,7 +316,8 @@ export function createWorkspaceService(ctx) {
|
|
|
292
316
|
// Invalidate the active session's onLog BEFORE teardown starts — lines
|
|
293
317
|
// flushed by the dying compile worker must not reach the panel.
|
|
294
318
|
logGeneration++;
|
|
295
|
-
|
|
319
|
+
compileModes.disposeCurrent(); // dies with the session
|
|
320
|
+
clearRefererForSession(currentSession, currentProjectPath);
|
|
296
321
|
await disposeSession();
|
|
297
322
|
// Record the root being torn down BEFORE clearing it, so a teardown/
|
|
298
323
|
// debounced write already in flight can still be accepted against it.
|
|
@@ -314,73 +339,15 @@ export function createWorkspaceService(ctx) {
|
|
|
314
339
|
getLastClosedProjectPath: () => lastClosedProjectPath,
|
|
315
340
|
hasActiveSession: () => currentSession !== null,
|
|
316
341
|
isClosing: () => closing,
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return null;
|
|
320
|
-
const simulatorWc = ctx.views.getSimulatorWebContents();
|
|
321
|
-
if (!simulatorWc)
|
|
322
|
-
return null;
|
|
323
|
-
if (ctx.views.getSimulatorProjectPath() !== projectPath)
|
|
324
|
-
return null;
|
|
325
|
-
const session = currentSession;
|
|
326
|
-
// Capture the active render-host guest (the mini-program content); the
|
|
327
|
-
// simulator WCV only holds the device-shell chrome. In native-host with no
|
|
328
|
-
// active guest (not mounted / mid page-switch / destroyed) return null
|
|
329
|
-
// rather than persist a device-shell frame as the page — that wrong-content
|
|
330
|
-
// frame is the bug this path exists to avoid. Non-native-host: the sim WCV.
|
|
331
|
-
const bridge = ctx.bridge;
|
|
332
|
-
const nativeHost = bridge?.isNativeHost() ?? false;
|
|
333
|
-
const renderGuest = nativeHost ? (bridge?.getActiveRenderWc() ?? null) : null;
|
|
334
|
-
if (nativeHost && !renderGuest)
|
|
335
|
-
return null;
|
|
336
|
-
const captureTarget = renderGuest ?? simulatorWc;
|
|
337
|
-
// A destroyed target means teardown is in flight (no valid frame) — return
|
|
338
|
-
// null rather than let capturePage() throw indistinguishably into the catch.
|
|
339
|
-
if (captureTarget.isDestroyed())
|
|
340
|
-
return null;
|
|
341
|
-
try {
|
|
342
|
-
const image = await captureTarget.capturePage();
|
|
343
|
-
if (currentSession !== session
|
|
344
|
-
|| currentProjectPath !== projectPath
|
|
345
|
-
|| ctx.views.getSimulatorWebContents() !== simulatorWc
|
|
346
|
-
|| ctx.views.getSimulatorProjectPath() !== projectPath
|
|
347
|
-
// Captured target must still be the live one: a guest that navigated
|
|
348
|
-
// mid-capture would otherwise persist a frame from the wrong page.
|
|
349
|
-
|| (nativeHost ? (bridge?.getActiveRenderWc() ?? null) : simulatorWc) !== captureTarget) {
|
|
350
|
-
return null;
|
|
351
|
-
}
|
|
352
|
-
const dataUrl = `data:image/png;base64,${image.toPNG().toString('base64')}`;
|
|
353
|
-
if (provider.saveThumbnail) {
|
|
354
|
-
await provider.saveThumbnail(projectPath, dataUrl);
|
|
355
|
-
}
|
|
356
|
-
// Always hand the renderer back the freshly-captured frame so the
|
|
357
|
-
// UI updates immediately even if the host's saveThumbnail is
|
|
358
|
-
// async or stores out-of-band.
|
|
359
|
-
return dataUrl;
|
|
360
|
-
}
|
|
361
|
-
catch {
|
|
362
|
-
return null;
|
|
363
|
-
}
|
|
364
|
-
},
|
|
365
|
-
async getThumbnail(projectPath) {
|
|
366
|
-
if (provider.getThumbnail) {
|
|
367
|
-
return (await provider.getThumbnail(projectPath)) ?? null;
|
|
368
|
-
}
|
|
369
|
-
return null;
|
|
370
|
-
},
|
|
342
|
+
captureThumbnail: thumbnails.captureThumbnail,
|
|
343
|
+
getThumbnail: thumbnails.getThumbnail,
|
|
371
344
|
// `getProjectPages` reads the project's own `app.json` from disk and is
|
|
372
345
|
// independent of the project registry — it stays on the repo helper.
|
|
373
346
|
getProjectPages: (projectPath) => repo.getProjectPages(projectPath),
|
|
374
|
-
getCompileConfig:
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
if (provider.saveCompileConfig) {
|
|
379
|
-
await provider.saveCompileConfig(projectPath, config);
|
|
380
|
-
}
|
|
381
|
-
// No persistence when the host opts out; the renderer's edits then
|
|
382
|
-
// do not survive a reload, matching the documented contract.
|
|
383
|
-
},
|
|
347
|
+
getCompileConfig: (projectPath) => compileModes.getCompileConfig(projectPath),
|
|
348
|
+
saveCompileConfig: (projectPath, config) => compileModes.saveCompileConfig(projectPath, config),
|
|
349
|
+
getCompileModeState: (projectPath) => compileModes.getCompileModeState(projectPath),
|
|
350
|
+
applyCompileModeCommand: (command) => compileModes.applyCompileModeCommand(command),
|
|
384
351
|
// Per-project settings (uploadWithSourceMap etc.) live in the project's
|
|
385
352
|
// own `project.config.json`, not the registry — keep direct repo calls.
|
|
386
353
|
getProjectSettings: (projectPath) => repo.getProjectSettings(projectPath),
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ProjectSession } from '../../../shared/types.js';
|
|
2
|
+
import type { BridgeRouterHandle } from '../../ipc/bridge-router.js';
|
|
3
|
+
import type { ViewManager } from '../views/view-manager.js';
|
|
4
|
+
import type { ProjectsProvider } from '../projects/types.js';
|
|
5
|
+
import type { WorkspaceService } from './workspace-service.js';
|
|
6
|
+
/**
|
|
7
|
+
* `captureThumbnail`/`getThumbnail` split out of WorkspaceService purely to keep
|
|
8
|
+
* workspace-service.ts under the repo's file-length gate — the semantics (session/
|
|
9
|
+
* project-path ownership, provider round-trip) still belong entirely to that service.
|
|
10
|
+
* Takes a narrow slice of WorkbenchContext (views + bridge) rather than the whole
|
|
11
|
+
* grab-bag type, so this split doesn't grow the WorkbenchContext-import ratchet.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createThumbnailOps(input: {
|
|
14
|
+
ctx: {
|
|
15
|
+
views: Pick<ViewManager, 'getSimulatorWebContents' | 'getSimulatorProjectPath'>;
|
|
16
|
+
bridge?: BridgeRouterHandle;
|
|
17
|
+
};
|
|
18
|
+
provider: ProjectsProvider;
|
|
19
|
+
getSession(): ProjectSession | null;
|
|
20
|
+
getProjectPath(): string;
|
|
21
|
+
}): Pick<WorkspaceService, 'captureThumbnail' | 'getThumbnail'>;
|
|
22
|
+
//# sourceMappingURL=workspace-thumbnails.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `captureThumbnail`/`getThumbnail` split out of WorkspaceService purely to keep
|
|
3
|
+
* workspace-service.ts under the repo's file-length gate — the semantics (session/
|
|
4
|
+
* project-path ownership, provider round-trip) still belong entirely to that service.
|
|
5
|
+
* Takes a narrow slice of WorkbenchContext (views + bridge) rather than the whole
|
|
6
|
+
* grab-bag type, so this split doesn't grow the WorkbenchContext-import ratchet.
|
|
7
|
+
*/
|
|
8
|
+
export function createThumbnailOps(input) {
|
|
9
|
+
const { ctx, provider, getSession, getProjectPath } = input;
|
|
10
|
+
return {
|
|
11
|
+
async captureThumbnail(projectPath) {
|
|
12
|
+
if (!getSession() || projectPath !== getProjectPath())
|
|
13
|
+
return null;
|
|
14
|
+
const simulatorWc = ctx.views.getSimulatorWebContents();
|
|
15
|
+
if (!simulatorWc)
|
|
16
|
+
return null;
|
|
17
|
+
if (ctx.views.getSimulatorProjectPath() !== projectPath)
|
|
18
|
+
return null;
|
|
19
|
+
const session = getSession();
|
|
20
|
+
// Capture the active render-host guest (the mini-program content); the
|
|
21
|
+
// simulator WCV only holds the device-shell chrome. In native-host with no
|
|
22
|
+
// active guest (not mounted / mid page-switch / destroyed) return null
|
|
23
|
+
// rather than persist a device-shell frame as the page — that wrong-content
|
|
24
|
+
// frame is the bug this path exists to avoid. Non-native-host: the sim WCV.
|
|
25
|
+
const bridge = ctx.bridge;
|
|
26
|
+
const nativeHost = bridge?.isNativeHost() ?? false;
|
|
27
|
+
const renderGuest = nativeHost ? (bridge?.getActiveRenderWc() ?? null) : null;
|
|
28
|
+
if (nativeHost && !renderGuest)
|
|
29
|
+
return null;
|
|
30
|
+
const captureTarget = renderGuest ?? simulatorWc;
|
|
31
|
+
// A destroyed target means teardown is in flight (no valid frame) — return
|
|
32
|
+
// null rather than let capturePage() throw indistinguishably into the catch.
|
|
33
|
+
if (captureTarget.isDestroyed())
|
|
34
|
+
return null;
|
|
35
|
+
try {
|
|
36
|
+
const image = await captureTarget.capturePage();
|
|
37
|
+
if (getSession() !== session
|
|
38
|
+
|| getProjectPath() !== projectPath
|
|
39
|
+
|| ctx.views.getSimulatorWebContents() !== simulatorWc
|
|
40
|
+
|| ctx.views.getSimulatorProjectPath() !== projectPath
|
|
41
|
+
// Captured target must still be the live one: a guest that navigated
|
|
42
|
+
// mid-capture would otherwise persist a frame from the wrong page.
|
|
43
|
+
|| (nativeHost ? (bridge?.getActiveRenderWc() ?? null) : simulatorWc) !== captureTarget) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const dataUrl = `data:image/png;base64,${image.toPNG().toString('base64')}`;
|
|
47
|
+
if (provider.saveThumbnail) {
|
|
48
|
+
await provider.saveThumbnail(projectPath, dataUrl);
|
|
49
|
+
}
|
|
50
|
+
// Always hand the renderer back the freshly-captured frame so the
|
|
51
|
+
// UI updates immediately even if the host's saveThumbnail is
|
|
52
|
+
// async or stores out-of-band.
|
|
53
|
+
return dataUrl;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
async getThumbnail(projectPath) {
|
|
60
|
+
if (provider.getThumbnail) {
|
|
61
|
+
return (await provider.getThumbnail(projectPath)) ?? null;
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=workspace-thumbnails.js.map
|