@dimina-kit/devtools 0.4.0-dev.20260824071518 → 0.4.0-dev.20260828161241
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/dist/main/api.d.ts +1 -1
- package/dist/main/app/app.js +59 -2
- package/dist/main/index.bundle.js +986 -245
- package/dist/main/ipc/index.d.ts +2 -0
- package/dist/main/ipc/index.js +2 -0
- package/dist/main/ipc/popover.js +1 -1
- package/dist/main/ipc/project-create.d.ts +15 -0
- package/dist/main/ipc/project-create.js +26 -0
- package/dist/main/ipc/projects.d.ts +1 -1
- package/dist/main/ipc/projects.js +36 -1
- package/dist/main/ipc/settings.js +2 -1
- package/dist/main/ipc/simulator-module.d.ts +4 -3
- package/dist/main/ipc/simulator-module.js +4 -5
- package/dist/main/ipc/tooltip.js +1 -1
- package/dist/main/ipc/views.d.ts +15 -1
- package/dist/main/ipc/views.js +61 -4
- package/dist/main/runtime/miniapp-runtime.d.ts +87 -19
- package/dist/main/services/notifications/renderer-notifier.d.ts +30 -1
- package/dist/main/services/notifications/renderer-notifier.js +23 -1
- package/dist/main/services/projects/create-project-service.js +9 -2
- package/dist/main/services/projects/local-provider.js +6 -0
- package/dist/main/services/projects/project-repository.d.ts +29 -1
- package/dist/main/services/projects/project-repository.js +151 -17
- package/dist/main/services/projects/types.d.ts +13 -2
- package/dist/main/services/update/update-manager.d.ts +17 -3
- package/dist/main/services/update/update-manager.js +25 -6
- 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 +107 -0
- package/dist/main/services/views/host-slot-port-channel.js +261 -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 -224
- package/dist/main/services/views/managed-web-contents-view.d.ts +48 -0
- package/dist/main/services/views/managed-web-contents-view.js +123 -0
- package/dist/main/services/views/overlay-panels-view.d.ts +23 -0
- package/dist/main/services/views/overlay-panels-view.js +93 -4
- package/dist/main/services/views/placement-reconciler.d.ts +14 -2
- package/dist/main/services/views/placement-reconciler.js +27 -0
- package/dist/main/services/views/placement-test-driver.d.ts +1 -0
- package/dist/main/services/views/placement-test-driver.js +3 -0
- package/dist/main/services/views/view-manager-devtools-host-test-fixtures.js +3 -1
- package/dist/main/services/views/view-manager.d.ts +10 -78
- package/dist/main/services/views/view-manager.js +34 -3
- package/dist/main/services/workbench-context.d.ts +18 -4
- package/dist/main/services/workbench-context.js +1 -0
- package/dist/main/services/workspace/workspace-service.d.ts +2 -0
- package/dist/main/services/workspace/workspace-service.js +14 -0
- package/dist/main/utils/paths.d.ts +4 -0
- package/dist/main/utils/paths.js +4 -0
- package/dist/main/utils/sender-policy.js +10 -0
- package/dist/native-host/common/common.js +65 -62
- package/dist/native-host/render/render.js +2230 -2052
- package/dist/native-host/service/service.js +2 -2
- 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/wait-for-slot-root.d.ts +20 -0
- package/dist/preload/runtime/wait-for-slot-root.js +52 -0
- package/dist/preload/windows/host-dialog-runtime.cjs +353 -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 +354 -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 +134 -51
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +3 -3
- package/dist/preload/windows/simulator.cjs.map +1 -1
- package/dist/renderer/assets/button-D5Q2wkXq.js +2 -0
- package/dist/renderer/assets/constants-D7DfVqMp.js +2 -0
- package/dist/renderer/assets/constants-D8zsejFq.js +2 -0
- package/dist/renderer/assets/createLucideIcon-Bqi8hpdi.js +2 -0
- package/dist/renderer/assets/dialog-e1TecTOY.js +46 -0
- package/dist/renderer/assets/dist-DKWdE1TK.js +2 -0
- package/dist/renderer/assets/hostSidebarDefault-B3yLfy8j.js +2 -0
- package/dist/renderer/assets/index-CsPD68N_.js +5 -0
- package/dist/renderer/assets/input-Ct3alvkq.js +2 -0
- package/dist/renderer/assets/ipc-channels-overlays-LsDzGAtV.js +2 -0
- package/dist/renderer/assets/jsx-runtime-2vXHouwr.css +1 -0
- package/dist/renderer/assets/jsx-runtime-DGLHmmOq.js +9 -0
- package/dist/renderer/assets/popover-Dix5cm_b.js +2 -0
- package/dist/renderer/assets/project-api-k7Oq9iaq.js +2 -0
- package/dist/renderer/assets/projectCreateDialog-Bbjz75bP.js +2 -0
- package/dist/renderer/assets/select-acGb0AmJ.js +2 -0
- package/dist/renderer/assets/settings-CQrTMr43.js +2 -0
- package/dist/renderer/assets/settings-api-CrUQ9rYV.js +2 -0
- package/dist/renderer/assets/settings-tab-bar-Cw1kVIf2.js +2 -0
- package/dist/renderer/assets/tooltip-B_-_YVbw.js +2 -0
- package/dist/renderer/assets/types-CsEKtFyr.js +2 -0
- package/dist/renderer/assets/updateDialog-NsF8223A.js +2 -0
- package/dist/renderer/assets/utils-kfQov6Pa.js +2 -0
- package/dist/renderer/assets/view-api-CLn3rcQE.js +2 -0
- package/dist/renderer/assets/{workbenchSettings-oq_EyfKf.js → workbenchSettings-CV4LVA9b.js} +3 -3
- package/dist/renderer/entries/host-sidebar-default/index.html +21 -0
- package/dist/renderer/entries/main/index.html +17 -8
- package/dist/renderer/entries/popover/index.html +10 -7
- package/dist/renderer/entries/project-create-dialog/index.html +27 -0
- package/dist/renderer/entries/settings/index.html +10 -7
- package/dist/renderer/entries/tooltip/index.html +5 -4
- package/dist/renderer/entries/update-dialog/index.html +25 -0
- package/dist/renderer/entries/workbench-settings/index.html +11 -7
- package/dist/service-host/preload.cjs +10 -0
- package/dist/shared/constants.d.ts +22 -0
- package/dist/shared/constants.js +22 -0
- package/dist/shared/ipc-channels-overlays.d.ts +156 -0
- package/dist/shared/ipc-channels-overlays.js +186 -0
- package/dist/shared/ipc-channels.d.ts +4 -77
- package/dist/shared/ipc-channels.js +4 -98
- package/dist/shared/ipc-schemas.d.ts +44 -0
- package/dist/shared/ipc-schemas.js +55 -0
- package/dist/shared/types.d.ts +71 -0
- package/dist/shared/view-ids.d.ts +7 -0
- package/dist/shared/view-ids.js +10 -0
- package/package.json +8 -8
- package/dist/renderer/assets/constants-Bdz0LHdy.js +0 -2
- package/dist/renderer/assets/index-CtznrmHR.js +0 -49
- package/dist/renderer/assets/input-Dmm6nob5.js +0 -2
- package/dist/renderer/assets/ipc-transport-BOg0gR9W.js +0 -9
- package/dist/renderer/assets/ipc-transport-DgQhZaE9.css +0 -1
- package/dist/renderer/assets/popover-Cd1FEGOX.js +0 -2
- package/dist/renderer/assets/select-BaYox7If.js +0 -2
- package/dist/renderer/assets/settings-BXvwuFaz.js +0 -2
- package/dist/renderer/assets/settings-api-Bo9GbYqs.js +0 -2
- package/dist/renderer/assets/settings-tab-bar-Beia6lMr.js +0 -2
- package/dist/renderer/assets/tooltip-DfQqK3Sk.js +0 -2
- package/dist/renderer/assets/view-api-nn69je7A.js +0 -2
|
@@ -36,8 +36,10 @@ export interface ViewSlot {
|
|
|
36
36
|
* settings/popover are main-owned and live in `overlayDesired`. Any change
|
|
37
37
|
* merges the two, runs the pure reconcile core, and applies the ordered ops
|
|
38
38
|
* through `viewTarget`. `epochCounter` is a single monotonic tick — main is the
|
|
39
|
-
* only (serial) reconcile caller, so the core's stale guard passes by
|
|
40
|
-
* construction; `rendererGeneration`
|
|
39
|
+
* only (serial) reconcile caller, so the core's stale-epoch guard passes by
|
|
40
|
+
* construction; `rendererGeneration` is the high-water mark that drives both
|
|
41
|
+
* the reset on a genuinely newer generation and the hard rejection of a
|
|
42
|
+
* snapshot from behind it (see `setPlacementSnapshot`).
|
|
41
43
|
*/
|
|
42
44
|
export interface PlacementReconciler {
|
|
43
45
|
registerView(viewId: string, slot: ViewSlot): void;
|
|
@@ -56,6 +58,16 @@ export interface PlacementReconciler {
|
|
|
56
58
|
setOverlayDesired(viewId: string, desired: DesiredView<DevtoolsExtra>): void;
|
|
57
59
|
deleteOverlayDesired(viewId: string): void;
|
|
58
60
|
hasOverlayDesired(viewId: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Hand out a fresh generation seed for a renderer bootstrap (see
|
|
63
|
+
* renderer-placement-generation.ts). Strictly exceeds both the current
|
|
64
|
+
* high-water mark (`rendererGeneration`, which a full renderer reload does
|
|
65
|
+
* NOT reset — this reconciler lives in the long-lived main process) and
|
|
66
|
+
* every previously allocated seed, so a reload that races ahead of its own
|
|
67
|
+
* previous session's accepted snapshots can never be handed a value that
|
|
68
|
+
* `setPlacementSnapshot` would reject as stale.
|
|
69
|
+
*/
|
|
70
|
+
allocateGeneration(): number;
|
|
59
71
|
}
|
|
60
72
|
export declare function createPlacementReconciler(ctx: ViewManagerContext): PlacementReconciler;
|
|
61
73
|
//# sourceMappingURL=placement-reconciler.d.ts.map
|
|
@@ -5,6 +5,7 @@ export function createPlacementReconciler(ctx) {
|
|
|
5
5
|
let placementState = createInitialState();
|
|
6
6
|
let epochCounter = 0;
|
|
7
7
|
let rendererGeneration = 0;
|
|
8
|
+
let allocatedGeneration = 0;
|
|
8
9
|
const appliedActual = new Map();
|
|
9
10
|
const baseDesired = new Map();
|
|
10
11
|
const overlayDesired = new Map();
|
|
@@ -119,6 +120,28 @@ export function createPlacementReconciler(ctx) {
|
|
|
119
120
|
placementState = { ...placementState, actual: cloneAppliedActual() };
|
|
120
121
|
}
|
|
121
122
|
function setPlacementSnapshot(snapshot) {
|
|
123
|
+
// Hard reject a snapshot from BEHIND the current high-water mark — a
|
|
124
|
+
// complete no-op, touching neither `rendererGeneration` nor
|
|
125
|
+
// `baseDesired`. The renderer hands out one shared, strictly monotonic
|
|
126
|
+
// sequence across every screen (see renderer-placement-generation.ts),
|
|
127
|
+
// so under normal operation a lower generation can only be a LATE
|
|
128
|
+
// arrival from an already-superseded source (e.g. a dead screen's
|
|
129
|
+
// delayed `dispose()` empty-snapshot flush racing a successor screen's
|
|
130
|
+
// mount). The previous version of this guard clamped
|
|
131
|
+
// `rendererGeneration` to never regress but still unconditionally
|
|
132
|
+
// applied the stale snapshot's CONTENT into `baseDesired` under the
|
|
133
|
+
// clamped (i.e. current) generation number — which defeated the
|
|
134
|
+
// reconcile core's own generation-regression guard
|
|
135
|
+
// (placement-reconcile.ts: `snapshot.generation < prev.generation`) by
|
|
136
|
+
// never letting it see the snapshot's real, lower generation. That let a
|
|
137
|
+
// dead screen's stale/empty view list silently overwrite a currently
|
|
138
|
+
// active screen's real views. Dropping it here, before it ever reaches
|
|
139
|
+
// `baseDesired`, is what actually gives the stale snapshot zero side
|
|
140
|
+
// effects.
|
|
141
|
+
if (snapshot.generation < rendererGeneration) {
|
|
142
|
+
console.warn(`[placement-reconciler] snapshot generation ${snapshot.generation} is behind the current ${rendererGeneration}; dropping without applying its content`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
122
145
|
rendererGeneration = snapshot.generation;
|
|
123
146
|
baseDesired.clear();
|
|
124
147
|
for (const v of snapshot.views)
|
|
@@ -150,6 +173,10 @@ export function createPlacementReconciler(ctx) {
|
|
|
150
173
|
setOverlayDesired: (viewId, desired) => { overlayDesired.set(viewId, desired); },
|
|
151
174
|
deleteOverlayDesired: (viewId) => { overlayDesired.delete(viewId); },
|
|
152
175
|
hasOverlayDesired: (viewId) => overlayDesired.has(viewId),
|
|
176
|
+
allocateGeneration: () => {
|
|
177
|
+
allocatedGeneration = Math.max(allocatedGeneration, rendererGeneration) + 1;
|
|
178
|
+
return allocatedGeneration;
|
|
179
|
+
},
|
|
153
180
|
};
|
|
154
181
|
}
|
|
155
182
|
//# sourceMappingURL=placement-reconciler.js.map
|
|
@@ -31,6 +31,7 @@ interface OverlaySink {
|
|
|
31
31
|
}): void;
|
|
32
32
|
}
|
|
33
33
|
export declare function hostToolbarBounds(mgr: SnapshotSink, rect: Rect): void;
|
|
34
|
+
export declare function hostSidebarBounds(mgr: SnapshotSink, rect: Rect): void;
|
|
34
35
|
export declare function simulatorDevtoolsBounds(mgr: SnapshotSink, rect: Rect): void;
|
|
35
36
|
export declare function workbenchBounds(mgr: SnapshotSink, rect: Rect): void;
|
|
36
37
|
export declare function showSettingsReady(mgr: OverlaySink): Promise<void>;
|
|
@@ -28,6 +28,9 @@ function pushView(mgr, view, generation = 1) {
|
|
|
28
28
|
export function hostToolbarBounds(mgr, rect) {
|
|
29
29
|
pushView(mgr, { viewId: VIEW_ID.hostToolbar, placement: toPlacement(rect), layer: VIEW_LAYER.hostToolbar });
|
|
30
30
|
}
|
|
31
|
+
export function hostSidebarBounds(mgr, rect) {
|
|
32
|
+
pushView(mgr, { viewId: VIEW_ID.hostSidebar, placement: toPlacement(rect), layer: VIEW_LAYER.hostSidebar });
|
|
33
|
+
}
|
|
31
34
|
export function simulatorDevtoolsBounds(mgr, rect) {
|
|
32
35
|
pushView(mgr, { viewId: VIEW_ID.simulatorDevtools, placement: toPlacement(rect), layer: VIEW_LAYER.base });
|
|
33
36
|
}
|
|
@@ -95,7 +95,9 @@ export function electronModuleMock() {
|
|
|
95
95
|
export function pathsModuleMock() {
|
|
96
96
|
return {
|
|
97
97
|
mainPreloadPath: '/stub/preload.js',
|
|
98
|
-
|
|
98
|
+
hostToolbarRuntimePreloadPath: '/stub/host-toolbar-preload.js',
|
|
99
|
+
hostSidebarRuntimePreloadPath: '/stub/host-sidebar-preload.js',
|
|
100
|
+
hostDialogRuntimePreloadPath: '/stub/host-dialog-preload.js',
|
|
99
101
|
cjsSiblingPreloadPath: (p) => p.replace(/\.js$/, '.cjs'),
|
|
100
102
|
devtoolsPackageRoot: '/stub/devtools-pkg-root',
|
|
101
103
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { WebContents } from 'electron';
|
|
2
2
|
import type { NativeDeviceInfo } from '../../../shared/ipc-channels.js';
|
|
3
3
|
import { type WorkbenchContext } from '../workbench-context.js';
|
|
4
|
-
import type { HostToolbarMessageSubscription } from './host-toolbar-port-channel.js';
|
|
5
4
|
import type { PlacementSnapshot } from '@dimina-kit/electron-deck/layout';
|
|
6
5
|
import type { DevtoolsExtra } from '../../../shared/view-ids.js';
|
|
6
|
+
import { type HostToolbarControl } from './host-toolbar-view.js';
|
|
7
|
+
import { type HostSidebarViewManagerMembers } from './host-sidebar-view.js';
|
|
8
|
+
import { type HostDialogViewManagerMembers } from './host-dialog-view.js';
|
|
7
9
|
import { type OverlayPanelsView, type TooltipShowPayload } from './overlay-panels-view.js';
|
|
8
10
|
export type { TooltipShowPayload };
|
|
9
11
|
export { resolveProjectEditorTarget, type ProjectEditorTarget, } from './resolve-project-editor-target.js';
|
|
@@ -91,7 +93,7 @@ export interface ViewManagerContext {
|
|
|
91
93
|
* panels) and shares a single injected placement reconciler; this file wires
|
|
92
94
|
* them together and exposes their combined method surface.
|
|
93
95
|
*/
|
|
94
|
-
export interface ViewManager extends Pick<OverlayPanelsView, 'showSettings' | 'hideSettings' | 'showPopover' | 'hidePopover' | 'prepareTooltip' | 'showTooltip' | 'hideTooltip' | 'markOverlayReady' | 'applyTooltipMeasurement'
|
|
96
|
+
export interface ViewManager extends Pick<OverlayPanelsView, 'showSettings' | 'hideSettings' | 'showPopover' | 'hidePopover' | 'prepareTooltip' | 'showTooltip' | 'hideTooltip' | 'markOverlayReady' | 'applyTooltipMeasurement' | 'showProjectCreateDialog' | 'hideProjectCreateDialog' | 'showUpdateDialog' | 'hideUpdateDialog' | 'notifyUpdateDownloadProgress' | 'getProjectCreateDialogWebContentsId' | 'getUpdateDialogWebContentsId'>, HostSidebarViewManagerMembers, HostDialogViewManagerMembers {
|
|
95
97
|
/**
|
|
96
98
|
* NATIVE-HOST ONLY. Create the simulator itself as a top-level
|
|
97
99
|
* WebContentsView (not a renderer `<webview>` guest) loading `simulatorUrl`,
|
|
@@ -202,6 +204,12 @@ export interface ViewManager extends Pick<OverlayPanelsView, 'showSettings' | 'h
|
|
|
202
204
|
* view tree.
|
|
203
205
|
*/
|
|
204
206
|
setPlacementSnapshot(snapshot: PlacementSnapshot<DevtoolsExtra>): void;
|
|
207
|
+
/**
|
|
208
|
+
* Hand out a fresh generation seed for a renderer bootstrap. See
|
|
209
|
+
* `PlacementReconciler.allocateGeneration`'s doc-comment for why this
|
|
210
|
+
* replaces a wall-clock (`Date.now()`) seed.
|
|
211
|
+
*/
|
|
212
|
+
allocatePlacementGeneration(): number;
|
|
205
213
|
/**
|
|
206
214
|
* Lazily create the workbench WebContentsView, load `<url>index.html`, and
|
|
207
215
|
* add it to the contentView. `url` is the COI server's base URL (trailing
|
|
@@ -261,82 +269,6 @@ export interface ViewManager extends Pick<OverlayPanelsView, 'showSettings' | 'h
|
|
|
261
269
|
*/
|
|
262
270
|
readonly hostToolbar: HostToolbarControl;
|
|
263
271
|
}
|
|
264
|
-
/**
|
|
265
|
-
* Height mode for the host-toolbar placeholder strip. `'auto'` (default): the
|
|
266
|
-
* session-resident advertiser's reports drive the height. `{ fixed }`: the
|
|
267
|
-
* host pins the height; advertiser reports are ignored until `'auto'` again.
|
|
268
|
-
*/
|
|
269
|
-
export type HostToolbarHeightMode = 'auto' | {
|
|
270
|
-
fixed: number;
|
|
271
|
-
};
|
|
272
|
-
/**
|
|
273
|
-
* The control object the downstream host uses to own the toolbar
|
|
274
|
-
* WebContentsView. Lazily backed by the view-manager's `hostToolbarView`.
|
|
275
|
-
*/
|
|
276
|
-
export interface HostToolbarControl {
|
|
277
|
-
/** Load a URL into the toolbar view (lazy-creates the view). */
|
|
278
|
-
loadURL(url: string): Promise<void>;
|
|
279
|
-
/** Load a local file into the toolbar view (lazy-creates the view). */
|
|
280
|
-
loadFile(path: string): Promise<void>;
|
|
281
|
-
/** The toolbar view's live WebContents, or null if not yet created/destroyed. */
|
|
282
|
-
readonly webContents: WebContents | null;
|
|
283
|
-
/** Remove the toolbar view from the contentView and reset it (kept alive). */
|
|
284
|
-
hide(): void;
|
|
285
|
-
/**
|
|
286
|
-
* The HOST's own `webPreferences.preload` for the toolbar view (purely
|
|
287
|
-
* additive). The framework's height-advertiser runtime does NOT ride
|
|
288
|
-
* `webPreferences.preload` — it is session-resident (registered on
|
|
289
|
-
* `session.defaultSession`, self-guarded by the `--dimina-host-toolbar`
|
|
290
|
-
* marker + `isMainFrame`), so a host preload set here coexists with it and
|
|
291
|
-
* never replaces it. Must be set before the view is (re)created (first
|
|
292
|
-
* `loadURL`/`loadFile`, or the next one after the host closed the
|
|
293
|
-
* webContents); `null` (default) means "no host preload" — it does not and
|
|
294
|
-
* cannot restore any built-in preload.
|
|
295
|
-
*/
|
|
296
|
-
setPreloadPath(path: string | null): void;
|
|
297
|
-
/**
|
|
298
|
-
* Register a host-side handler for messages the toolbar PAGE sends via
|
|
299
|
-
* `window.diminaHostToolbar.send(channel, payload)`. Control-level: may be
|
|
300
|
-
* called before the view exists and survives page reloads / wc rebuilds
|
|
301
|
-
* (each per-load MessagePort handshake re-attaches the registry to the new
|
|
302
|
-
* port). Throws on an empty / non-string channel. `dispose()` detaches
|
|
303
|
-
* (idempotent).
|
|
304
|
-
*/
|
|
305
|
-
onMessage(channel: string, handler: (payload: unknown) => void): HostToolbarMessageSubscription;
|
|
306
|
-
/**
|
|
307
|
-
* Observe handshake readiness — the push counterpart to polling `send()`
|
|
308
|
-
* for `true`. Fires the handler once per load generation, exactly when
|
|
309
|
-
* that load's MessagePort handshake completes; registering while the
|
|
310
|
-
* channel is ALREADY ready fires once asynchronously on a microtask
|
|
311
|
-
* (missed-signal race guard, re-validated at fire time). A reload /
|
|
312
|
-
* re-handshake fires registered handlers again; a host-initiated
|
|
313
|
-
* `loadURL`/`loadFile` invalidates readiness at initiation, so handlers
|
|
314
|
-
* registered in that window wait for the NEW document's handshake.
|
|
315
|
-
* `dispose()` detaches (idempotent); `disposeAll` sweeps everything.
|
|
316
|
-
*/
|
|
317
|
-
onReady(handler: () => void): HostToolbarMessageSubscription;
|
|
318
|
-
/**
|
|
319
|
-
* Post `{ channel, payload }` to the toolbar page (received via
|
|
320
|
-
* `window.diminaHostToolbar.onMessage(channel, handler)`). Gated and
|
|
321
|
-
* non-queueing: returns false — delivering nothing, creating no view —
|
|
322
|
-
* while there is no live toolbar webContents, the current load's
|
|
323
|
-
* MessagePort handshake hasn't completed, or a document-replacing
|
|
324
|
-
* navigation is in flight (`loadURL`/`loadFile` was issued, or the page
|
|
325
|
-
* itself started a main-frame cross-document navigation, and the new
|
|
326
|
-
* document hasn't handshaked yet); true once the envelope went out.
|
|
327
|
-
* No manual `getHostToolbarWebContentsId` gating needed: the false/true
|
|
328
|
-
* result IS the readiness signal.
|
|
329
|
-
*/
|
|
330
|
-
send(channel: string, payload: unknown): boolean;
|
|
331
|
-
/**
|
|
332
|
-
* Pin or unpin the toolbar strip height. `{ fixed }` notifies the renderer
|
|
333
|
-
* placeholder with that height immediately (so a preload-less/static toolbar
|
|
334
|
-
* is visible without any advertiser report) and ignores subsequent advertiser
|
|
335
|
-
* reports. `'auto'` (default) re-enables advertiser-driven height starting
|
|
336
|
-
* from the NEXT report — it does not synthesize/replay a stale height.
|
|
337
|
-
*/
|
|
338
|
-
setHeightMode(mode: HostToolbarHeightMode): void;
|
|
339
|
-
}
|
|
340
272
|
/**
|
|
341
273
|
* Build a ViewManager bound to the given context. The returned object is the
|
|
342
274
|
* only component allowed to instantiate or add/remove overlay WebContentsViews.
|
|
@@ -3,6 +3,8 @@ import { createPlacementReconciler } from './placement-reconciler.js';
|
|
|
3
3
|
import { createWorkbenchView } from './workbench-view.js';
|
|
4
4
|
import { createDevtoolsHost } from './native-simulator-devtools-host.js';
|
|
5
5
|
import { createHostToolbarView } from './host-toolbar-view.js';
|
|
6
|
+
import { createHostSidebarView } from './host-sidebar-view.js';
|
|
7
|
+
import { createHostDialogView } from './host-dialog-view.js';
|
|
6
8
|
import { createOverlayPanelsView, } from './overlay-panels-view.js';
|
|
7
9
|
import { createNativeSimulatorView } from './native-simulator-view.js';
|
|
8
10
|
export { resolveProjectEditorTarget, } from './resolve-project-editor-target.js';
|
|
@@ -34,6 +36,11 @@ export function createViewManager(ctx) {
|
|
|
34
36
|
const hostToolbar = createHostToolbarView(ctx, reconciler, {
|
|
35
37
|
reapplyPresentOverlays: () => reapplyToolbarDependentOverlays(),
|
|
36
38
|
});
|
|
39
|
+
// Sidebar and dialog are host-scoped like the toolbar (survive project
|
|
40
|
+
// close/reopen) but carry no height-cycle dependency on the overlay panels,
|
|
41
|
+
// so unlike hostToolbar they need no thunk into this scope.
|
|
42
|
+
const hostSidebar = createHostSidebarView(ctx, reconciler);
|
|
43
|
+
const hostDialog = createHostDialogView(ctx, reconciler);
|
|
37
44
|
const overlayPanels = createOverlayPanelsView(ctx, reconciler, {
|
|
38
45
|
getHostToolbarHeight: hostToolbar.getHostToolbarHeight,
|
|
39
46
|
});
|
|
@@ -63,9 +70,15 @@ export function createViewManager(ctx) {
|
|
|
63
70
|
// a release/cap replay to rebuild.
|
|
64
71
|
workbench.cancelWorkbenchAttachHold();
|
|
65
72
|
disposeProjectViews();
|
|
66
|
-
// Host-scoped teardown: the toolbar
|
|
67
|
-
// ref-counted session-runtime preload
|
|
73
|
+
// Host-scoped teardown: the toolbar/sidebar/dialog views, their port
|
|
74
|
+
// channels, and their ref-counted session-runtime preload registrations.
|
|
68
75
|
hostToolbar.dispose();
|
|
76
|
+
hostSidebar.dispose();
|
|
77
|
+
hostDialog.dispose();
|
|
78
|
+
// Devtools-owned overlay-panel dialogs (project-create/update) — never
|
|
79
|
+
// torn down by disposeProjectViews(), they'd otherwise outlive every
|
|
80
|
+
// other view once the app tears down.
|
|
81
|
+
overlayPanels.destroyDialogs();
|
|
69
82
|
}
|
|
70
83
|
return {
|
|
71
84
|
attachNativeSimulator: nativeSimulator.attachNativeSimulator,
|
|
@@ -82,7 +95,17 @@ export function createViewManager(ctx) {
|
|
|
82
95
|
hideTooltip: overlayPanels.hideTooltip,
|
|
83
96
|
markOverlayReady: overlayPanels.markOverlayReady,
|
|
84
97
|
applyTooltipMeasurement: overlayPanels.applyTooltipMeasurement,
|
|
85
|
-
|
|
98
|
+
showProjectCreateDialog: overlayPanels.showProjectCreateDialog,
|
|
99
|
+
hideProjectCreateDialog: overlayPanels.hideProjectCreateDialog,
|
|
100
|
+
showUpdateDialog: overlayPanels.showUpdateDialog,
|
|
101
|
+
hideUpdateDialog: overlayPanels.hideUpdateDialog,
|
|
102
|
+
notifyUpdateDownloadProgress: overlayPanels.notifyUpdateDownloadProgress,
|
|
103
|
+
getProjectCreateDialogWebContentsId: overlayPanels.getProjectCreateDialogWebContentsId,
|
|
104
|
+
getUpdateDialogWebContentsId: overlayPanels.getUpdateDialogWebContentsId,
|
|
105
|
+
repositionAll: () => {
|
|
106
|
+
overlayPanels.reapplyPresentOverlays();
|
|
107
|
+
hostDialog.reposition();
|
|
108
|
+
},
|
|
86
109
|
disposeProjectViews,
|
|
87
110
|
disposeAll,
|
|
88
111
|
getSimulatorWebContentsId: nativeSimulator.getSimulatorWebContentsId,
|
|
@@ -96,6 +119,7 @@ export function createViewManager(ctx) {
|
|
|
96
119
|
getHostToolbarHeight: hostToolbar.getHostToolbarHeight,
|
|
97
120
|
resize: () => overlayPanels.applySettingsBoundsIfPresent(),
|
|
98
121
|
setPlacementSnapshot: reconciler.setPlacementSnapshot,
|
|
122
|
+
allocatePlacementGeneration: reconciler.allocateGeneration,
|
|
99
123
|
attachWorkbench: workbench.attachWorkbench,
|
|
100
124
|
setWorkbenchSource: workbench.setWorkbenchSource,
|
|
101
125
|
detachWorkbench: workbench.detachWorkbench,
|
|
@@ -104,6 +128,13 @@ export function createViewManager(ctx) {
|
|
|
104
128
|
cancelWorkbenchAttachHold: workbench.cancelWorkbenchAttachHold,
|
|
105
129
|
setHostToolbarHeight: hostToolbar.setHostToolbarHeight,
|
|
106
130
|
hostToolbar: hostToolbar.control,
|
|
131
|
+
getHostSidebarWebContentsId: hostSidebar.getHostSidebarWebContentsId,
|
|
132
|
+
getHostSidebarWidth: hostSidebar.getHostSidebarWidth,
|
|
133
|
+
setHostSidebarWidth: hostSidebar.setHostSidebarWidth,
|
|
134
|
+
hostSidebar: hostSidebar.control,
|
|
135
|
+
getHostDialogWebContentsId: hostDialog.getHostDialogWebContentsId,
|
|
136
|
+
reportHostDialogMeasuredExtent: hostDialog.reportMeasuredExtent,
|
|
137
|
+
hostDialog: hostDialog.control,
|
|
107
138
|
};
|
|
108
139
|
}
|
|
109
140
|
//# sourceMappingURL=view-manager.js.map
|
|
@@ -21,8 +21,8 @@ import { type WorkspaceService } from './workspace/workspace-service.js';
|
|
|
21
21
|
import { type SimulatorApiRegistry } from './simulator/custom-apis.js';
|
|
22
22
|
import { type SimulatorUiExtensionRegistry } from './simulator/ui-extensions.js';
|
|
23
23
|
import { sanitizeTemplates } from './projects/templates.js';
|
|
24
|
-
import type { ProjectsProvider, ProjectTemplate } from './projects/types.js';
|
|
25
|
-
import type { CustomCreateProjectDialogResult } from '../../shared/types.js';
|
|
24
|
+
import type { Project, ProjectsProvider, ProjectTemplate } from './projects/types.js';
|
|
25
|
+
import type { CustomCreateProjectDialogResult, CustomEditProjectDialogResult } from '../../shared/types.js';
|
|
26
26
|
/**
|
|
27
27
|
* Shared mutable state for the workbench application.
|
|
28
28
|
* Passed to each IPC module so they can read/write shared state without closures.
|
|
@@ -96,6 +96,17 @@ export interface WorkbenchContext extends RuntimeContext {
|
|
|
96
96
|
parentWindow: BrowserWindow;
|
|
97
97
|
templates: ProjectTemplate[];
|
|
98
98
|
}) => Promise<CustomCreateProjectDialogResult>;
|
|
99
|
+
/**
|
|
100
|
+
* Optional host hook for the "编辑项目" dialog. When present, the
|
|
101
|
+
* `projects:openEditDialog` IPC runs it and wraps whatever it resolves to
|
|
102
|
+
* as `{ result }`; when absent, the IPC returns `null` and the renderer
|
|
103
|
+
* shows the built-in dialog. `project` comes from `workspace.listProjects`,
|
|
104
|
+
* not the renderer's IPC args.
|
|
105
|
+
*/
|
|
106
|
+
customEditProjectDialog?: (ctx: {
|
|
107
|
+
parentWindow: BrowserWindow;
|
|
108
|
+
project: Project;
|
|
109
|
+
}) => Promise<CustomEditProjectDialogResult>;
|
|
99
110
|
/**
|
|
100
111
|
* Host permission gate consulted by `workspace.openProject` BEFORE any side
|
|
101
112
|
* effect. Throwing vetoes the open (see `WorkbenchAppConfig.onBeforeOpenProject`).
|
|
@@ -239,8 +250,9 @@ export interface WorkbenchContext extends RuntimeContext {
|
|
|
239
250
|
* because their shapes intentionally differ from the config:
|
|
240
251
|
* - `preloadPath` / `rendererDir` are REQUIRED here (the caller resolves the
|
|
241
252
|
* defaults before constructing the context) but optional in the config;
|
|
242
|
-
* - `projectsProvider` / `projectTemplates` / `customCreateProjectDialog`
|
|
243
|
-
* the main-process types, not the structural
|
|
253
|
+
* - `projectsProvider` / `projectTemplates` / `customCreateProjectDialog` /
|
|
254
|
+
* `customEditProjectDialog` use the main-process types, not the structural
|
|
255
|
+
* mirrors in `shared/types`.
|
|
244
256
|
*/
|
|
245
257
|
export interface CreateContextOptions extends Pick<WorkbenchConfig, 'adapter' | 'apiNamespaces' | 'appName' | 'fileTypes'> {
|
|
246
258
|
mainWindow: BrowserWindow;
|
|
@@ -255,6 +267,8 @@ export interface CreateContextOptions extends Pick<WorkbenchConfig, 'adapter' |
|
|
|
255
267
|
builtinTemplates?: 'all' | 'none' | readonly string[];
|
|
256
268
|
/** Host-supplied "新建项目" dialog hook. */
|
|
257
269
|
customCreateProjectDialog?: WorkbenchContext['customCreateProjectDialog'];
|
|
270
|
+
/** Host-supplied "编辑项目" dialog hook. */
|
|
271
|
+
customEditProjectDialog?: WorkbenchContext['customEditProjectDialog'];
|
|
258
272
|
/** Host permission gate run before a project opens (throw to veto). */
|
|
259
273
|
onBeforeOpenProject?: WorkbenchContext['onBeforeOpenProject'];
|
|
260
274
|
}
|
|
@@ -74,6 +74,7 @@ export function createWorkbenchContext(opts) {
|
|
|
74
74
|
ctx.projectsProvider = opts.projectsProvider ?? createLocalProjectsProvider();
|
|
75
75
|
ctx.projectTemplates = resolveTemplates(BUILTIN_TEMPLATES, opts.projectTemplates ?? [], opts.builtinTemplates ?? 'all');
|
|
76
76
|
ctx.customCreateProjectDialog = opts.customCreateProjectDialog;
|
|
77
|
+
ctx.customEditProjectDialog = opts.customEditProjectDialog;
|
|
77
78
|
ctx.onBeforeOpenProject = opts.onBeforeOpenProject;
|
|
78
79
|
ctx.workspace = createWorkspaceService(ctx);
|
|
79
80
|
ctx.senderPolicy = createWorkbenchSenderPolicy(ctx);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AppInfo, CompileConfig, ProjectSession } from '../../../shared/types.js';
|
|
2
2
|
import type { WorkbenchContext } from '../workbench-context.js';
|
|
3
3
|
import type { Project, ProjectPages, ProjectSettings } from '../projects/project-repository.js';
|
|
4
|
+
import type { ProjectPatch } from '../projects/types.js';
|
|
4
5
|
/**
|
|
5
6
|
* Result returned to the renderer after `project:open` finishes.
|
|
6
7
|
* Mirrors the previous inline shape in ipc/session.ts so no
|
|
@@ -28,6 +29,7 @@ export interface WorkspaceService {
|
|
|
28
29
|
listProjects(): Promise<Project[]>;
|
|
29
30
|
addProject(dirPath: string): Promise<Project>;
|
|
30
31
|
removeProject(dirPath: string): Promise<void>;
|
|
32
|
+
updateProject(dirPath: string, patch: ProjectPatch): Promise<Project>;
|
|
31
33
|
hasProject(dirPath: string): Promise<boolean>;
|
|
32
34
|
validateProjectDir(dirPath: string): Promise<string | null>;
|
|
33
35
|
openProject(projectPath: string): Promise<OpenProjectResult>;
|
|
@@ -158,6 +158,20 @@ export function createWorkspaceService(ctx) {
|
|
|
158
158
|
removeProject: async (dirPath) => {
|
|
159
159
|
await provider.removeProject(dirPath);
|
|
160
160
|
},
|
|
161
|
+
updateProject: async (dirPath, patch) => {
|
|
162
|
+
const projects = await provider.listProjects();
|
|
163
|
+
const existing = projects.find((p) => p.path === dirPath);
|
|
164
|
+
if (!existing)
|
|
165
|
+
throw new Error(`No such project: ${dirPath}`);
|
|
166
|
+
// A provider without `updateProject` cannot persist the edit. Returning
|
|
167
|
+
// the record unchanged would look like a successful save to the
|
|
168
|
+
// renderer (dialog closes, list reloads) while silently discarding the
|
|
169
|
+
// user's input, so this must fail loudly instead.
|
|
170
|
+
if (!provider.updateProject) {
|
|
171
|
+
throw new Error('当前宿主不支持编辑项目');
|
|
172
|
+
}
|
|
173
|
+
return provider.updateProject(dirPath, patch);
|
|
174
|
+
},
|
|
161
175
|
hasProject: async (dirPath) => {
|
|
162
176
|
const projects = await provider.listProjects();
|
|
163
177
|
return projects.some((p) => p.path === dirPath);
|
|
@@ -31,6 +31,10 @@ export declare const mainPreloadPath: string;
|
|
|
31
31
|
* npm/pnpm node_modules and ASAR packaging alike get an absolute, correct path.
|
|
32
32
|
*/
|
|
33
33
|
export declare const hostToolbarRuntimePreloadPath: string;
|
|
34
|
+
/** Session-registered sidebar-runtime preload bundle, mirroring {@link hostToolbarRuntimePreloadPath}. */
|
|
35
|
+
export declare const hostSidebarRuntimePreloadPath: string;
|
|
36
|
+
/** Session-registered dialog-runtime preload bundle, mirroring {@link hostToolbarRuntimePreloadPath}. */
|
|
37
|
+
export declare const hostDialogRuntimePreloadPath: string;
|
|
34
38
|
export declare const simulatorDir: string;
|
|
35
39
|
/**
|
|
36
40
|
* DevTools builds its own copy of every native mini-app runtime asset. Pin the
|
package/dist/main/utils/paths.js
CHANGED
|
@@ -59,6 +59,10 @@ export const mainPreloadPath = path.join(devtoolsPackageRoot, 'dist/preload/wind
|
|
|
59
59
|
* npm/pnpm node_modules and ASAR packaging alike get an absolute, correct path.
|
|
60
60
|
*/
|
|
61
61
|
export const hostToolbarRuntimePreloadPath = path.join(devtoolsPackageRoot, 'dist/preload/windows/host-toolbar-runtime.cjs');
|
|
62
|
+
/** Session-registered sidebar-runtime preload bundle, mirroring {@link hostToolbarRuntimePreloadPath}. */
|
|
63
|
+
export const hostSidebarRuntimePreloadPath = path.join(devtoolsPackageRoot, 'dist/preload/windows/host-sidebar-runtime.cjs');
|
|
64
|
+
/** Session-registered dialog-runtime preload bundle, mirroring {@link hostToolbarRuntimePreloadPath}. */
|
|
65
|
+
export const hostDialogRuntimePreloadPath = path.join(devtoolsPackageRoot, 'dist/preload/windows/host-dialog-runtime.cjs');
|
|
62
66
|
export const simulatorDir = path.join(devtoolsPackageRoot, 'dist/simulator');
|
|
63
67
|
/**
|
|
64
68
|
* DevTools builds its own copy of every native mini-app runtime asset. Pin the
|
|
@@ -54,6 +54,16 @@ export function createWorkbenchSenderPolicy(ctx) {
|
|
|
54
54
|
const tooltipViewId = ctx.views.getTooltipWebContentsId();
|
|
55
55
|
if (tooltipViewId != null && sender.id === tooltipViewId)
|
|
56
56
|
return true;
|
|
57
|
+
// Project-create-dialog overlay view. Devtools-owned bundled renderer
|
|
58
|
+
// (the WCV that replaced the Radix DOM-portal dialog), same trust level
|
|
59
|
+
// as settings/popover/tooltip.
|
|
60
|
+
const projectCreateDialogViewId = ctx.views.getProjectCreateDialogWebContentsId();
|
|
61
|
+
if (projectCreateDialogViewId != null && sender.id === projectCreateDialogViewId)
|
|
62
|
+
return true;
|
|
63
|
+
// Update-available overlay view. Same devtools-owned trust level.
|
|
64
|
+
const updateDialogViewId = ctx.views.getUpdateDialogWebContentsId();
|
|
65
|
+
if (updateDialogViewId != null && sender.id === updateDialogViewId)
|
|
66
|
+
return true;
|
|
57
67
|
// The host-toolbar overlay is DELIBERATELY NOT trusted here. The host loads
|
|
58
68
|
// arbitrary content into it, so granting it the global white-list would open
|
|
59
69
|
// all ~72 IpcRegistry channels to that content. Its one channel (the reverse
|