@dimina-kit/devtools 0.4.0-dev.20260701083540 → 0.4.0-dev.20260702145840

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.
Files changed (81) hide show
  1. package/dist/main/app/app.js +11 -0
  2. package/dist/main/app/max-listeners-diagnostic.d.ts +32 -0
  3. package/dist/main/app/max-listeners-diagnostic.js +63 -0
  4. package/dist/main/index.bundle.js +1657 -1158
  5. package/dist/main/ipc/bridge-router.d.ts +33 -4
  6. package/dist/main/ipc/bridge-router.js +200 -51
  7. package/dist/main/ipc/session-listener-bag.d.ts +41 -0
  8. package/dist/main/ipc/session-listener-bag.js +40 -0
  9. package/dist/main/ipc/simulator.js +5 -5
  10. package/dist/main/ipc/views.js +8 -19
  11. package/dist/main/services/automation/wait-active-page.d.ts +4 -2
  12. package/dist/main/services/elements-forward/index.js +19 -0
  13. package/dist/main/services/network-forward/index.js +13 -0
  14. package/dist/main/services/render-inspect/index.d.ts +9 -0
  15. package/dist/main/services/render-inspect/index.js +13 -1
  16. package/dist/main/services/simulator-storage/index.d.ts +9 -0
  17. package/dist/main/services/simulator-storage/index.js +26 -1
  18. package/dist/main/services/simulator-wxml/index.js +117 -11
  19. package/dist/main/services/views/apply-view-ops.d.ts +11 -0
  20. package/dist/main/services/views/apply-view-ops.js +22 -0
  21. package/dist/main/services/views/destroy-child-view.d.ts +9 -0
  22. package/dist/main/services/views/destroy-child-view.js +23 -0
  23. package/dist/main/services/views/host-toolbar-view.d.ts +21 -0
  24. package/dist/main/services/views/host-toolbar-view.js +249 -0
  25. package/dist/main/services/views/inject-when-ready.d.ts +41 -0
  26. package/dist/main/services/views/inject-when-ready.js +62 -0
  27. package/dist/main/services/views/native-simulator-devtools-host.d.ts +26 -0
  28. package/dist/main/services/views/native-simulator-devtools-host.js +484 -0
  29. package/dist/main/services/views/native-simulator-view.d.ts +28 -0
  30. package/dist/main/services/views/native-simulator-view.js +428 -0
  31. package/dist/main/services/views/overlay-panels-view.d.ts +29 -0
  32. package/dist/main/services/views/overlay-panels-view.js +150 -0
  33. package/dist/main/services/views/placement-reconciler.d.ts +73 -0
  34. package/dist/main/services/views/placement-reconciler.js +120 -0
  35. package/dist/main/services/views/placement-test-driver.d.ts +25 -0
  36. package/dist/main/services/views/placement-test-driver.js +48 -0
  37. package/dist/main/services/views/resolve-project-editor-target.d.ts +13 -0
  38. package/dist/main/services/views/resolve-project-editor-target.js +33 -0
  39. package/dist/main/services/views/view-manager.d.ts +28 -70
  40. package/dist/main/services/views/view-manager.js +66 -1514
  41. package/dist/main/services/views/workbench-view.d.ts +15 -0
  42. package/dist/main/services/views/workbench-view.js +170 -0
  43. package/dist/main/services/workbench-context.d.ts +10 -0
  44. package/dist/preload/windows/host-toolbar-runtime.cjs +6 -13
  45. package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
  46. package/dist/preload/windows/main.cjs +10 -1
  47. package/dist/preload/windows/main.cjs.map +2 -2
  48. package/dist/preload/windows/simulator.cjs +6 -3
  49. package/dist/preload/windows/simulator.cjs.map +2 -2
  50. package/dist/preload/windows/simulator.js +6 -3
  51. package/dist/render-host/render-inspect.js +35 -1
  52. package/dist/renderer/assets/index-ChF9V4r-.js +49 -0
  53. package/dist/renderer/assets/{input-DR7bfyQE.js → input-Cjk0wSEh.js} +2 -2
  54. package/dist/renderer/assets/ipc-transport-D5dKIti1.css +1 -0
  55. package/dist/renderer/assets/{ipc-transport-3Arg8jPC.js → ipc-transport-OZS-KmOW.js} +2 -2
  56. package/dist/renderer/assets/{popover-CPZX3MrT.js → popover-CQVvOe90.js} +2 -2
  57. package/dist/renderer/assets/{select-BxyPlVyJ.js → select-BQDXi5ih.js} +2 -2
  58. package/dist/renderer/assets/{settings-api-CtPPJF-F.js → settings-api-B6x2mhaD.js} +2 -2
  59. package/dist/renderer/assets/{settings-CG_OR03F.js → settings-tP3Px2KR.js} +2 -2
  60. package/dist/renderer/assets/{workbenchSettings-ClqCBGOa.js → workbenchSettings-Bim9ol9R.js} +2 -2
  61. package/dist/renderer/entries/main/index.html +6 -6
  62. package/dist/renderer/entries/popover/index.html +5 -5
  63. package/dist/renderer/entries/settings/index.html +5 -5
  64. package/dist/renderer/entries/workbench-settings/index.html +4 -4
  65. package/dist/service-host/sync-api-patch.js +33 -3
  66. package/dist/shared/bridge-channels.d.ts +17 -0
  67. package/dist/shared/bridge-channels.js +9 -0
  68. package/dist/shared/ipc-channels.d.ts +29 -14
  69. package/dist/shared/ipc-channels.js +16 -17
  70. package/dist/shared/ipc-schemas.d.ts +25 -17
  71. package/dist/shared/ipc-schemas.js +38 -22
  72. package/dist/shared/view-ids.d.ts +19 -0
  73. package/dist/shared/view-ids.js +25 -0
  74. package/dist/simulator/assets/{bridge-channels-BUQ5AbvJ.js → bridge-channels-zhsumfky.js} +2 -2
  75. package/dist/simulator/assets/{device-shell-CT3LRnTB.js → device-shell-CUl0ILfn.js} +2 -2
  76. package/dist/simulator/assets/{simulator-BizhGGE3.js → simulator-Dz8iGcgy.js} +5 -5
  77. package/dist/simulator/assets/{simulator-mini-app-BfNuDF3R.js → simulator-mini-app-Bt639XL_.js} +2 -2
  78. package/dist/simulator/simulator.html +2 -1
  79. package/package.json +4 -4
  80. package/dist/renderer/assets/index-HE9Xr9bQ.js +0 -49
  81. package/dist/renderer/assets/ipc-transport-Dt0jR7Ir.css +0 -1
@@ -22,9 +22,11 @@
22
22
  * - Resolve exactly once; later events are inert and the subscription is torn
23
23
  * down on resolve.
24
24
  */
25
- /** The render-event shape `waitForActivePage` reads (subset of `RenderEvent`). */
25
+ /** The render-event shape `waitForActivePage` reads (subset of `RenderEvent`).
26
+ * Only `activePage` events end the wait; other kinds (`domReady`/`domMutated`)
27
+ * are inert but included so a full `RenderEvent` is assignable here. */
26
28
  export interface ActivePageEventLike {
27
- kind: 'domReady' | 'activePage';
29
+ kind: 'domReady' | 'activePage' | 'domMutated';
28
30
  appId: string;
29
31
  bridgeId: string;
30
32
  pagePath?: string;
@@ -49,6 +49,7 @@
49
49
  * hook + dispatch scripts) as self-contained code.
50
50
  */
51
51
  import { webContents as electronWebContents } from 'electron';
52
+ import { isFrontendSettled } from '../views/inject-when-ready.js';
52
53
  /**
53
54
  * CDP domains that target the RENDER GUEST'S document tree. A command in one of
54
55
  * these is intercepted and sent to the active render guest's debugger instead of
@@ -274,6 +275,12 @@ export function installElementsForward(deps) {
274
275
  function dispatchToFrontend(message) {
275
276
  if (disposed || devtoolsWc.isDestroyed())
276
277
  return;
278
+ // Unified settled gate (same predicate as the reconcile tick): an unsettled
279
+ // front-end wipes its state on load anyway, so the message is meaningless
280
+ // there — and the executeJavaScript would queue one did-stop-loading waiter
281
+ // per push (an activePage burst piles them). The post-settle tick re-primes.
282
+ if (!isFrontendSettled(devtoolsWc))
283
+ return;
277
284
  let json;
278
285
  try {
279
286
  json = JSON.stringify(message);
@@ -309,6 +316,10 @@ export function installElementsForward(deps) {
309
316
  function pushDocumentUpdated() {
310
317
  if (disposed || devtoolsWc.isDestroyed())
311
318
  return;
319
+ // Same unified settled gate as dispatchToFrontend — render events (the
320
+ // activePage burst) drive this during churn.
321
+ if (!isFrontendSettled(devtoolsWc))
322
+ return;
312
323
  let script;
313
324
  try {
314
325
  script = buildDocumentUpdatedScript();
@@ -594,6 +605,14 @@ export function installElementsForward(deps) {
594
605
  stop();
595
606
  return;
596
607
  }
608
+ // An unsettled front-end can't run the script anyway, and executeJavaScript
609
+ // against it queues one did-stop-loading waiter PER TICK on the emitter
610
+ // (150ms × a seconds-long reload piles past the MaxListeners ceiling).
611
+ // MUST be the shared Electron-aligned predicate — a bare isLoading()
612
+ // probe diverges from Electron's internal isLoadingMainFrame gate and
613
+ // keeps piling. Skip; the first post-settle tick re-establishes the hook.
614
+ if (!isFrontendSettled(devtoolsWc))
615
+ return;
597
616
  devtoolsWc
598
617
  .executeJavaScript(buildReconcileScript())
599
618
  .then((res) => {
@@ -1,4 +1,5 @@
1
1
  import { DisposableRegistry, toDisposable } from '@dimina-kit/electron-deck/main';
2
+ import { isFrontendSettled } from '../views/inject-when-ready.js';
2
3
  // ── requestId namespacing (pure, testable) ──────────────────────────────────
3
4
  /**
4
5
  * CDP events whose `params.requestId` we rewrite into the virtual namespace.
@@ -359,6 +360,18 @@ export function createNetworkForwarder(bridge) {
359
360
  trimQueue();
360
361
  return;
361
362
  }
363
+ if (!isFrontendSettled(wc)) {
364
+ // An unsettled front-end can't run the dispatch script anyway — and every
365
+ // executeJavaScript against it queues one did-stop-loading waiter on the
366
+ // emitter, so a relaunch's network burst piles them past the MaxListeners
367
+ // ceiling. MUST be the shared Electron-aligned predicate (a bare
368
+ // isLoading() probe diverges from the internal isLoadingMainFrame gate).
369
+ // Hold the (bounded) queue; the next event's flush or the ready-retry
370
+ // delivers after the load.
371
+ trimQueue();
372
+ scheduleReadyRetry();
373
+ return;
374
+ }
362
375
  if (sink === 'idle')
363
376
  beginProbing();
364
377
  // Pack greedily up to MAX_BATCH_CHARS so one executeJavaScript stays sized;
@@ -24,6 +24,15 @@ export interface RenderInspector {
24
24
  highlight(wc: WebContents, sid: string): Promise<ElementInspection | null>;
25
25
  /** Clear any highlight overlay in the guest. */
26
26
  unhighlight(wc: WebContents): Promise<void>;
27
+ /**
28
+ * Toggle the guest-side WXML MutationObserver. When on, the injected IIFE
29
+ * watches `document.body` and posts a debounced `wxmlChanged` over
30
+ * `DiminaRenderBridge` on every DOM mutation (setData), which bridge-router
31
+ * turns into a `domMutated` render event so the WXML panel re-pulls. Only
32
+ * enabled while the WXML panel is visible, so an unseen panel never drives a
33
+ * full Vue-tree walk. Injects the IIFE first if needed; no-op on a dead guest.
34
+ */
35
+ setWxmlObserving(wc: WebContents, on: boolean): Promise<void>;
27
36
  }
28
37
  export interface RenderInspectorOptions {
29
38
  /** Override the injected IIFE source (default: read the built bundle). Test seam. */
@@ -259,6 +259,18 @@ export function createRenderInspector(options = {}) {
259
259
  // best-effort
260
260
  }
261
261
  }
262
- return { getWxml, highlight, unhighlight };
262
+ async function setWxmlObserving(wc, on) {
263
+ if (wc.isDestroyed())
264
+ return;
265
+ if (!(await ensureInjected(wc)))
266
+ return;
267
+ try {
268
+ await wc.executeJavaScript(`window.__diminaRenderInspect && window.__diminaRenderInspect.setWxmlObserving(${on ? 'true' : 'false'})`);
269
+ }
270
+ catch {
271
+ // best-effort: a guest mid-teardown just stops observing on its own.
272
+ }
273
+ }
274
+ return { getWxml, highlight, unhighlight, setWxmlObserving };
263
275
  }
264
276
  //# sourceMappingURL=index.js.map
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { type WebContents } from 'electron';
17
17
  import { type ConnectionRegistry, type Disposable } from '@dimina-kit/electron-deck/main';
18
+ import { type SyncStorageChange } from '../../../shared/ipc-channels.js';
18
19
  import { type SenderPolicy } from '../../utils/ipc-registry.js';
19
20
  import type { BridgeRouterHandle } from '../../ipc/bridge-router.js';
20
21
  import type { RenderInspector } from '../render-inspect/index.js';
@@ -34,6 +35,14 @@ export declare const STORAGE_API_NAMES: Set<string>;
34
35
  export interface SimulatorStorageHandle extends Disposable {
35
36
  /** Present only under native-host; wired to ctx.storageApi for bridge-router. */
36
37
  storageApi: StorageApi | null;
38
+ /**
39
+ * Native-host SYNC-storage liveness: bridge-router calls this on each
40
+ * `storageChanged` container message the service-host posts after a
41
+ * `setStorageSync`/`removeStorageSync`/`clearStorageSync`. Those write the
42
+ * service-host `localStorage` directly (bypassing main), so they'd otherwise
43
+ * leave the panel stale until reload — this pushes the matching `StorageEvent`.
44
+ */
45
+ onSyncStorageChange(appId: string, change: SyncStorageChange): void;
37
46
  }
38
47
  export interface SimulatorStorageOptions {
39
48
  /**
@@ -573,7 +573,32 @@ export function setupSimulatorStorage(host, options) {
573
573
  const storageApi = options.bridge?.isNativeHost()
574
574
  ? { invoke: runtimeInvoke }
575
575
  : null;
576
- return { dispose: () => registry.dispose(), storageApi };
576
+ /**
577
+ * SYNC wx storage APIs run inside the service-host window and write
578
+ * `localStorage` directly, so they never reach `setItem`/`runtimeInvoke` here.
579
+ * The service-host posts the change over `DiminaServiceBridge` and bridge-router
580
+ * routes it here so the panel stays live. Only the ACTIVE app's changes are
581
+ * surfaced (the panel shows one app); the key already carries the `${appId}_`
582
+ * prefix, matching the CDP / async event shape.
583
+ */
584
+ function onSyncStorageChange(appId, change) {
585
+ if (appId !== getActiveAppId())
586
+ return;
587
+ if (host.isDestroyed())
588
+ return;
589
+ switch (change.op) {
590
+ case 'set':
591
+ pushSyntheticEvent({ type: 'added', key: change.key, newValue: change.value });
592
+ break;
593
+ case 'remove':
594
+ pushSyntheticEvent({ type: 'removed', key: change.key });
595
+ break;
596
+ case 'clear':
597
+ host.send(SimulatorStorageChannel.Event, { type: 'cleared' });
598
+ break;
599
+ }
600
+ }
601
+ return { dispose: () => registry.dispose(), storageApi, onSyncStorageChange };
577
602
  }
578
603
  // Element inspection delegates to the simulator preload's __simulatorData
579
604
  // bridge via executeJavaScript. Looked up independently from `attachedWc` so
@@ -4,25 +4,131 @@ import { IpcRegistry } from '../../utils/ipc-registry.js';
4
4
  export function setupSimulatorWxml(host, options) {
5
5
  const { bridge, inspector, getActiveAppId } = options;
6
6
  const registry = new DisposableRegistry();
7
- /** Read the WXML tree of the visible page of the active app, or null. */
8
- async function pull() {
9
- const wc = bridge.getActiveRenderWc(getActiveAppId() ?? undefined);
7
+ // Whether the WXML panel is currently visible (renderer drives this via
8
+ // SetActive). Live tree pushes + the render-guest DOM observer only run while
9
+ // active, so an unseen panel never triggers a full Vue-tree walk.
10
+ let active = false;
11
+ // latest-wins: only the newest pull's result is pushed (a slow walk that
12
+ // resolves after a newer one must not clobber the fresher tree).
13
+ let seq = 0;
14
+ // in-flight coalescing: at most one pull runs at a time; a request that lands
15
+ // mid-pull sets `again` so exactly one follow-up pull runs after it settles.
16
+ let pulling = false;
17
+ let again = false;
18
+ // The render guest currently being observed, so we can stop it on page change
19
+ // / deactivation (single owner).
20
+ let observedWc = null;
21
+ /** The visible page's render WebContents of the active app, or null. */
22
+ function activeWc() {
23
+ return bridge.getActiveRenderWc(getActiveAppId() ?? undefined);
24
+ }
25
+ /** Read the WXML tree of a render guest, or null when there is none. */
26
+ async function pull(wc) {
10
27
  if (!wc)
11
28
  return null;
12
29
  return inspector.getWxml(wc);
13
30
  }
31
+ /**
32
+ * Pull the active tree and push it, gated by `active` and reconciled by
33
+ * latest-wins + in-flight coalescing so a burst of render events (setData)
34
+ * collapses to a single fresh push instead of a pile of overlapping walks.
35
+ */
36
+ function schedulePull() {
37
+ if (!active)
38
+ return;
39
+ const mySeq = ++seq;
40
+ if (pulling) {
41
+ again = true;
42
+ return;
43
+ }
44
+ pulling = true;
45
+ void pull(activeWc())
46
+ .then((tree) => {
47
+ // Re-check `active` at send time: a pull started while visible must NOT
48
+ // push after the panel was hidden / disposed (deactivate bumps `seq`, so
49
+ // `mySeq === seq` also guards, but the explicit `active` check is the
50
+ // clear invariant).
51
+ if (mySeq === seq && active && !host.isDestroyed()) {
52
+ host.send(SimulatorWxmlChannel.Event, tree);
53
+ }
54
+ })
55
+ .finally(() => {
56
+ pulling = false;
57
+ if (again) {
58
+ again = false;
59
+ schedulePull();
60
+ }
61
+ });
62
+ }
63
+ function startObserving(wc) {
64
+ if (!wc)
65
+ return;
66
+ observedWc = wc;
67
+ // The guest IIFE defers observe() until document.body exists, so a wc whose
68
+ // DOM isn't up yet still starts observing once it loads — no retry needed here.
69
+ void inspector.setWxmlObserving(wc, true);
70
+ }
71
+ function stopObserving() {
72
+ const wc = observedWc;
73
+ observedWc = null;
74
+ if (wc)
75
+ void inspector.setWxmlObserving(wc, false);
76
+ }
77
+ /**
78
+ * Point the DOM observer at the CURRENT active render guest. Called on every
79
+ * render event while active, so the observer installs even when SetActive fired
80
+ * before the guest existed (the guest appears on `domReady`) and follows the
81
+ * active page across navigation (`activePage`).
82
+ */
83
+ function reconcileObserving() {
84
+ if (!active)
85
+ return;
86
+ const wc = activeWc();
87
+ if (wc !== observedWc) {
88
+ stopObserving();
89
+ startObserving(wc);
90
+ }
91
+ }
92
+ /** Invalidate any in-flight pull + queued re-pull so nothing pushes post-hide. */
93
+ function cancelPending() {
94
+ seq++;
95
+ again = false;
96
+ }
14
97
  const ipc = new IpcRegistry(options.senderPolicy);
15
- ipc.handle(SimulatorWxmlChannel.GetSnapshot, () => pull());
98
+ ipc.handle(SimulatorWxmlChannel.GetSnapshot, () => pull(activeWc()));
99
+ ipc.handle(SimulatorWxmlChannel.SetActive, (_event, on) => {
100
+ if (on) {
101
+ active = true;
102
+ reconcileObserving();
103
+ schedulePull(); // seed the now-visible panel
104
+ }
105
+ else {
106
+ active = false;
107
+ cancelPending();
108
+ stopObserving();
109
+ }
110
+ });
16
111
  registry.add(ipc);
17
- // Re-read + push when a page's DOM mounts or the visible page changes.
18
- const unsubscribe = bridge.onRenderEvent(() => {
19
- void pull().then((tree) => {
20
- if (host.isDestroyed())
21
- return;
22
- host.send(SimulatorWxmlChannel.Event, tree);
23
- });
112
+ // Re-read + push on render-side activity: a page's DOM mounted (`domReady`),
113
+ // the visible page changed (`activePage`), or the active page's DOM mutated in
114
+ // place (`domMutated`, from the render-guest observer). Gated by `active` and
115
+ // scoped to the ACTIVE app so a background app's / stale bridge's event never
116
+ // drives a spurious full walk of the visible page.
117
+ const unsubscribe = bridge.onRenderEvent((event) => {
118
+ if (!active)
119
+ return;
120
+ const appId = getActiveAppId();
121
+ if (appId && event.appId !== appId)
122
+ return;
123
+ // domReady: the guest may have just appeared → (re)install the observer.
124
+ // activePage: the active guest changed → move the observer.
125
+ // domMutated: same guest → reconcile is a no-op, then pull.
126
+ reconcileObserving();
127
+ schedulePull();
24
128
  });
25
129
  registry.add(unsubscribe);
130
+ // Stop observing + invalidate in-flight pulls on teardown (best-effort).
131
+ registry.add(() => { active = false; cancelPending(); stopObserving(); });
26
132
  return registry;
27
133
  }
28
134
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ import type { Bounds, ViewOp } from '@dimina-kit/electron-deck/layout';
2
+ import type { DevtoolsExtra } from '../../../shared/view-ids.js';
3
+ export interface ViewOpTarget {
4
+ attach(viewId: string): void;
5
+ detach(viewId: string): void;
6
+ setBounds(viewId: string, bounds: Bounds, extra?: DevtoolsExtra): void;
7
+ setVisible(viewId: string, visible: boolean): void;
8
+ reorder(order: string[]): void;
9
+ }
10
+ export declare function applyViewOps(ops: ViewOp<DevtoolsExtra>[], target: ViewOpTarget): void;
11
+ //# sourceMappingURL=apply-view-ops.d.ts.map
@@ -0,0 +1,22 @@
1
+ export function applyViewOps(ops, target) {
2
+ for (const op of ops) {
3
+ switch (op.kind) {
4
+ case 'detach':
5
+ target.detach(op.viewId);
6
+ break;
7
+ case 'setVisible':
8
+ target.setVisible(op.viewId, op.visible);
9
+ break;
10
+ case 'setBounds':
11
+ target.setBounds(op.viewId, op.bounds, op.extra);
12
+ break;
13
+ case 'attach':
14
+ target.attach(op.viewId);
15
+ break;
16
+ case 'reorder':
17
+ target.reorder(op.order);
18
+ break;
19
+ }
20
+ }
21
+ }
22
+ //# sourceMappingURL=apply-view-ops.js.map
@@ -0,0 +1,9 @@
1
+ import type { BrowserWindow, WebContentsView } from 'electron';
2
+ /**
3
+ * Detach a child overlay WebContentsView from the main window's contentView and
4
+ * close its webContents. Tolerates an already-removed view and a destroyed
5
+ * webContents (best-effort teardown). The single low-level view-destroy path
6
+ * shared by every overlay domain.
7
+ */
8
+ export declare function destroyChildView(mainWindow: BrowserWindow, view: WebContentsView | null): void;
9
+ //# sourceMappingURL=destroy-child-view.d.ts.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Detach a child overlay WebContentsView from the main window's contentView and
3
+ * close its webContents. Tolerates an already-removed view and a destroyed
4
+ * webContents (best-effort teardown). The single low-level view-destroy path
5
+ * shared by every overlay domain.
6
+ */
7
+ export function destroyChildView(mainWindow, view) {
8
+ if (!view)
9
+ return;
10
+ if (!mainWindow.isDestroyed()) {
11
+ try {
12
+ mainWindow.contentView.removeChildView(view);
13
+ }
14
+ catch { /* already removed */ }
15
+ }
16
+ try {
17
+ if (!view.webContents.isDestroyed()) {
18
+ view.webContents.close();
19
+ }
20
+ }
21
+ catch { /* ignore */ }
22
+ }
23
+ //# sourceMappingURL=destroy-child-view.js.map
@@ -0,0 +1,21 @@
1
+ import type { PlacementReconciler } from './placement-reconciler.js';
2
+ import type { HostToolbarControl, ViewManagerContext } from './view-manager.js';
3
+ /**
4
+ * A strip above the devtools header that the downstream host loads its own
5
+ * content into and fully controls. Bounds come from a renderer DOM anchor
6
+ * (forward anchor, like the simulator DevTools overlay); its height is dynamic
7
+ * via a reverse size-advertiser the toolbar's own renderer drives.
8
+ */
9
+ export interface HostToolbarView {
10
+ readonly control: HostToolbarControl;
11
+ setHostToolbarHeight(extent: number): void;
12
+ getHostToolbarHeight(): number;
13
+ getHostToolbarWebContentsId(): number | null;
14
+ /** Teardown for `disposeAll`: sweep the port, destroy the view, release the runtime ref. */
15
+ dispose(): void;
16
+ }
17
+ export declare function createHostToolbarView(ctx: ViewManagerContext, reconciler: PlacementReconciler, deps: {
18
+ /** Re-apply the settings/popover overlays whose height depends on the toolbar strip. */
19
+ reapplyPresentOverlays(): void;
20
+ }): HostToolbarView;
21
+ //# sourceMappingURL=host-toolbar-view.d.ts.map