@dimina-kit/devtools 0.4.0-dev.20260824071518 → 0.4.0-dev.20260828092243
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 +55 -2
- package/dist/main/index.bundle.js +887 -234
- 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 +11 -0
- 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/project-repository.d.ts +4 -1
- package/dist/main/services/projects/project-repository.js +63 -5
- 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/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-DsNqZm7o.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-CYJeT1ji.js +2 -0
- package/dist/renderer/assets/dialog-pT4qWmka.js +46 -0
- package/dist/renderer/assets/dist-o70xmpc1.js +2 -0
- package/dist/renderer/assets/hostSidebarDefault-NvGZlE9O.js +2 -0
- package/dist/renderer/assets/index-zErhG3ta.js +5 -0
- package/dist/renderer/assets/input-4QxTXMZN.js +2 -0
- package/dist/renderer/assets/ipc-channels-overlays-Blr5TNoB.js +2 -0
- package/dist/renderer/assets/jsx-runtime-B-3rq1y5.css +1 -0
- package/dist/renderer/assets/jsx-runtime-CqVdW3eg.js +9 -0
- package/dist/renderer/assets/popover-CJiSWwuE.js +2 -0
- package/dist/renderer/assets/project-api-DZ1Zi6EC.js +2 -0
- package/dist/renderer/assets/projectCreateDialog-DMWNhw_1.js +2 -0
- package/dist/renderer/assets/select-C86pNcsu.js +2 -0
- package/dist/renderer/assets/settings-BoI8mLT1.js +2 -0
- package/dist/renderer/assets/settings-api-Bs_g4NHs.js +2 -0
- package/dist/renderer/assets/settings-tab-bar-DHLLygqv.js +2 -0
- package/dist/renderer/assets/tooltip-BhAyY0T4.js +2 -0
- package/dist/renderer/assets/types-YYjkvane.js +2 -0
- package/dist/renderer/assets/updateDialog-DPum3wx1.js +2 -0
- package/dist/renderer/assets/utils-kfQov6Pa.js +2 -0
- package/dist/renderer/assets/view-api-DFhb2R8-.js +2 -0
- package/dist/renderer/assets/{workbenchSettings-oq_EyfKf.js → workbenchSettings-DrajRQUk.js} +3 -3
- package/dist/renderer/entries/host-sidebar-default/index.html +21 -0
- package/dist/renderer/entries/main/index.html +15 -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 +0 -77
- package/dist/shared/ipc-channels.js +0 -98
- package/dist/shared/ipc-schemas.d.ts +33 -0
- package/dist/shared/ipc-schemas.js +41 -0
- package/dist/shared/types.d.ts +10 -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
|
@@ -5,6 +5,7 @@ import { applyNavigationHardening } from '../../windows/navigation-hardening.js'
|
|
|
5
5
|
import * as layout from '../layout/index.js';
|
|
6
6
|
import { HEADER_H } from '../../../shared/constants.js';
|
|
7
7
|
import { VIEW_ID, VIEW_LAYER } from '../../../shared/view-ids.js';
|
|
8
|
+
import { UpdateChannel } from '../../../shared/ipc-channels-overlays.js';
|
|
8
9
|
export function createOverlayPanelsView(ctx, reconciler, deps) {
|
|
9
10
|
function overlayHeaderHeight() {
|
|
10
11
|
return HEADER_H + deps.getHostToolbarHeight();
|
|
@@ -83,6 +84,50 @@ export function createOverlayPanelsView(ctx, reconciler, deps) {
|
|
|
83
84
|
pushData: (view, data) => ctx.notify.tooltipInit(view, data),
|
|
84
85
|
readyMode: 'manual',
|
|
85
86
|
});
|
|
87
|
+
/**
|
|
88
|
+
* Both devtools-owned dialog panels occupy the full main-window content
|
|
89
|
+
* rect (they render their own centered card + backdrop), so unlike
|
|
90
|
+
* settings/popover/tooltip they need no anchor-derived bounds computation —
|
|
91
|
+
* just the window's current content size, recomputed on every show/resize.
|
|
92
|
+
*/
|
|
93
|
+
function fullWindowBounds() {
|
|
94
|
+
const [width = 0, height = 0] = ctx.windows.mainWindow.getContentSize();
|
|
95
|
+
return { x: 0, y: 0, width: Math.max(1, width), height: Math.max(1, height) };
|
|
96
|
+
}
|
|
97
|
+
const projectCreateDialogPanel = createOverlayPanel({
|
|
98
|
+
electron: { createWebContentsView: (opts) => new WebContentsView(opts) },
|
|
99
|
+
rendererDir: ctx.rendererDir,
|
|
100
|
+
entry: 'entries/project-create-dialog/index.html',
|
|
101
|
+
webPreferences: {
|
|
102
|
+
nodeIntegration: false,
|
|
103
|
+
contextIsolation: true,
|
|
104
|
+
sandbox: false,
|
|
105
|
+
preload: mainPreloadPath,
|
|
106
|
+
},
|
|
107
|
+
hardenNavigation: (wc) => applyNavigationHardening(wc, ctx.rendererDir),
|
|
108
|
+
setDesired: overlayDesiredSetter(VIEW_ID.projectCreateDialog, VIEW_LAYER.dialog),
|
|
109
|
+
registerView: (getView) => reconciler.registerView(VIEW_ID.projectCreateDialog, { getView }),
|
|
110
|
+
destroyView: (view) => reconciler.destroyView(VIEW_ID.projectCreateDialog, view),
|
|
111
|
+
pushData: (view, data) => ctx.notify.projectCreateInit(view, data),
|
|
112
|
+
readyMode: 'manual',
|
|
113
|
+
});
|
|
114
|
+
const updateDialogPanel = createOverlayPanel({
|
|
115
|
+
electron: { createWebContentsView: (opts) => new WebContentsView(opts) },
|
|
116
|
+
rendererDir: ctx.rendererDir,
|
|
117
|
+
entry: 'entries/update-dialog/index.html',
|
|
118
|
+
webPreferences: {
|
|
119
|
+
nodeIntegration: false,
|
|
120
|
+
contextIsolation: true,
|
|
121
|
+
sandbox: false,
|
|
122
|
+
preload: mainPreloadPath,
|
|
123
|
+
},
|
|
124
|
+
hardenNavigation: (wc) => applyNavigationHardening(wc, ctx.rendererDir),
|
|
125
|
+
setDesired: overlayDesiredSetter(VIEW_ID.updateDialog, VIEW_LAYER.dialog),
|
|
126
|
+
registerView: (getView) => reconciler.registerView(VIEW_ID.updateDialog, { getView }),
|
|
127
|
+
destroyView: (view) => reconciler.destroyView(VIEW_ID.updateDialog, view),
|
|
128
|
+
pushData: (view, data) => ctx.notify.updateAvailable(view, data),
|
|
129
|
+
readyMode: 'manual',
|
|
130
|
+
});
|
|
86
131
|
let tooltipRequestId = 0;
|
|
87
132
|
let activeTooltip = null;
|
|
88
133
|
async function showSettings() {
|
|
@@ -126,10 +171,30 @@ export function createOverlayPanelsView(ctx, reconciler, deps) {
|
|
|
126
171
|
activeTooltip = null;
|
|
127
172
|
tooltipPanel.hide();
|
|
128
173
|
}
|
|
174
|
+
function showProjectCreateDialog(data) {
|
|
175
|
+
projectCreateDialogPanel.show(data, fullWindowBounds());
|
|
176
|
+
}
|
|
177
|
+
function hideProjectCreateDialog() {
|
|
178
|
+
projectCreateDialogPanel.hide();
|
|
179
|
+
}
|
|
180
|
+
function showUpdateDialog(data) {
|
|
181
|
+
updateDialogPanel.show(data, fullWindowBounds());
|
|
182
|
+
}
|
|
183
|
+
function hideUpdateDialog() {
|
|
184
|
+
updateDialogPanel.hide();
|
|
185
|
+
}
|
|
186
|
+
function notifyUpdateDownloadProgress(percent) {
|
|
187
|
+
const wc = updateDialogPanel.getWebContents();
|
|
188
|
+
if (!wc)
|
|
189
|
+
return;
|
|
190
|
+
wc.send(UpdateChannel.DownloadProgress, { percent });
|
|
191
|
+
}
|
|
129
192
|
function markOverlayReady(webContentsId) {
|
|
130
193
|
settingsPanel.markReady(webContentsId);
|
|
131
194
|
popoverPanel.markReady(webContentsId);
|
|
132
195
|
tooltipPanel.markReady(webContentsId);
|
|
196
|
+
projectCreateDialogPanel.markReady(webContentsId);
|
|
197
|
+
updateDialogPanel.markReady(webContentsId);
|
|
133
198
|
}
|
|
134
199
|
function applyTooltipMeasurement(webContentsId, measurement) {
|
|
135
200
|
const active = activeTooltip;
|
|
@@ -141,22 +206,38 @@ export function createOverlayPanelsView(ctx, reconciler, deps) {
|
|
|
141
206
|
tooltipPanel.reposition(layout.computeTooltipBounds(active.anchor, w, h, measurement));
|
|
142
207
|
}
|
|
143
208
|
function reapplyPresentOverlays() {
|
|
144
|
-
|
|
145
|
-
|
|
209
|
+
// Fire-and-forget re-trigger — a crash between this call and the panel
|
|
210
|
+
// becoming ready now rejects whenReady() (see overlay-panel.ts teardown);
|
|
211
|
+
// handleViewBroken() already logs it, nothing more to do here.
|
|
212
|
+
if (settingsPanel.isPresent() && reconciler.hasOverlayDesired(VIEW_ID.settings)) {
|
|
213
|
+
showSettings().catch(() => { });
|
|
214
|
+
}
|
|
146
215
|
if (popoverPanel.isPresent() && reconciler.hasOverlayDesired(VIEW_ID.popover)) {
|
|
147
216
|
const [w = 0, h = 0] = ctx.windows.mainWindow.getContentSize();
|
|
148
217
|
popoverPanel.reposition(layout.computePopoverBounds(w, h, overlayHeaderHeight()));
|
|
149
218
|
}
|
|
219
|
+
if (projectCreateDialogPanel.isPresent() && reconciler.hasOverlayDesired(VIEW_ID.projectCreateDialog)) {
|
|
220
|
+
projectCreateDialogPanel.reposition(fullWindowBounds());
|
|
221
|
+
}
|
|
222
|
+
if (updateDialogPanel.isPresent() && reconciler.hasOverlayDesired(VIEW_ID.updateDialog)) {
|
|
223
|
+
updateDialogPanel.reposition(fullWindowBounds());
|
|
224
|
+
}
|
|
150
225
|
}
|
|
151
226
|
function applySettingsBoundsIfPresent() {
|
|
152
|
-
|
|
153
|
-
|
|
227
|
+
// See reapplyPresentOverlays() above for why this swallows a rejection.
|
|
228
|
+
if (settingsPanel.isPresent() && reconciler.hasOverlayDesired(VIEW_ID.settings)) {
|
|
229
|
+
showSettings().catch(() => { });
|
|
230
|
+
}
|
|
154
231
|
}
|
|
155
232
|
function destroySettings() {
|
|
156
233
|
activeTooltip = null;
|
|
157
234
|
settingsPanel.destroy();
|
|
158
235
|
tooltipPanel.destroy();
|
|
159
236
|
}
|
|
237
|
+
function destroyDialogs() {
|
|
238
|
+
projectCreateDialogPanel.destroy();
|
|
239
|
+
updateDialogPanel.destroy();
|
|
240
|
+
}
|
|
160
241
|
return {
|
|
161
242
|
showSettings,
|
|
162
243
|
hideSettings,
|
|
@@ -167,13 +248,21 @@ export function createOverlayPanelsView(ctx, reconciler, deps) {
|
|
|
167
248
|
hideTooltip,
|
|
168
249
|
markOverlayReady,
|
|
169
250
|
applyTooltipMeasurement,
|
|
251
|
+
showProjectCreateDialog,
|
|
252
|
+
hideProjectCreateDialog,
|
|
253
|
+
showUpdateDialog,
|
|
254
|
+
hideUpdateDialog,
|
|
255
|
+
notifyUpdateDownloadProgress,
|
|
170
256
|
reapplyPresentOverlays,
|
|
171
257
|
applySettingsBoundsIfPresent,
|
|
172
258
|
destroySettings,
|
|
259
|
+
destroyDialogs,
|
|
173
260
|
getSettingsWebContents: () => settingsPanel.getWebContents(),
|
|
174
261
|
getSettingsWebContentsId: () => settingsPanel.getWebContentsId(),
|
|
175
262
|
getPopoverWebContentsId: () => popoverPanel.getWebContentsId(),
|
|
176
263
|
getTooltipWebContentsId: () => tooltipPanel.getWebContentsId(),
|
|
264
|
+
getProjectCreateDialogWebContentsId: () => projectCreateDialogPanel.getWebContentsId(),
|
|
265
|
+
getUpdateDialogWebContentsId: () => updateDialogPanel.getWebContentsId(),
|
|
177
266
|
};
|
|
178
267
|
}
|
|
179
268
|
//# sourceMappingURL=overlay-panels-view.js.map
|
|
@@ -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
|
|
@@ -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
|