@dimina-kit/devtools 0.3.2-dev.20260611063505 → 0.3.2-dev.20260611135124

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 (84) hide show
  1. package/README.md +53 -40
  2. package/dist/main/api.d.ts +4 -2
  3. package/dist/main/api.js +5 -1
  4. package/dist/main/app/app.d.ts +1 -5
  5. package/dist/main/app/app.js +4 -19
  6. package/dist/main/index.bundle.js +238 -392
  7. package/dist/main/ipc/app.d.ts +1 -1
  8. package/dist/main/ipc/app.js +0 -7
  9. package/dist/main/ipc/index.d.ts +0 -2
  10. package/dist/main/ipc/index.js +0 -2
  11. package/dist/main/ipc/settings.d.ts +1 -1
  12. package/dist/main/ipc/settings.js +1 -13
  13. package/dist/main/ipc/simulator-module.d.ts +3 -3
  14. package/dist/main/ipc/simulator-module.js +3 -7
  15. package/dist/main/ipc/simulator.js +1 -12
  16. package/dist/main/runtime/miniapp-runtime.d.ts +138 -28
  17. package/dist/main/runtime/miniapp-runtime.js +6 -11
  18. package/dist/main/services/layout/index.d.ts +0 -11
  19. package/dist/main/services/layout/index.js +0 -23
  20. package/dist/main/services/notifications/renderer-notifier.d.ts +0 -6
  21. package/dist/main/services/notifications/renderer-notifier.js +1 -10
  22. package/dist/main/services/service-host-pool/pool.d.ts +5 -4
  23. package/dist/main/services/views/host-toolbar-port-channel.d.ts +93 -0
  24. package/dist/main/services/views/host-toolbar-port-channel.js +169 -0
  25. package/dist/main/services/views/host-toolbar-session-runtime.d.ts +35 -0
  26. package/dist/main/services/views/host-toolbar-session-runtime.js +55 -0
  27. package/dist/main/services/views/view-manager.d.ts +68 -39
  28. package/dist/main/services/views/view-manager.js +143 -182
  29. package/dist/main/services/workbench-context.d.ts +6 -26
  30. package/dist/main/services/workbench-context.js +0 -14
  31. package/dist/main/services/workspace/workspace-service.js +7 -13
  32. package/dist/main/utils/paths.d.ts +11 -2
  33. package/dist/main/utils/paths.js +11 -2
  34. package/dist/preload/index.d.ts +15 -0
  35. package/dist/preload/index.js +15 -0
  36. package/dist/preload/runtime/host-toolbar-port.d.ts +44 -0
  37. package/dist/preload/runtime/host-toolbar-port.js +127 -0
  38. package/dist/preload/runtime/host-toolbar-runtime.d.ts +41 -0
  39. package/dist/preload/runtime/host-toolbar-runtime.js +49 -0
  40. package/dist/preload/windows/{host-toolbar.cjs → host-toolbar-runtime.cjs} +94 -3
  41. package/dist/preload/windows/host-toolbar-runtime.cjs.map +7 -0
  42. package/dist/preload/windows/host-toolbar-runtime.d.ts +2 -0
  43. package/dist/preload/windows/host-toolbar-runtime.js +13 -0
  44. package/dist/preload/windows/simulator.cjs +0 -2
  45. package/dist/preload/windows/simulator.cjs.map +2 -2
  46. package/dist/preload/windows/simulator.js +0 -2
  47. package/dist/renderer/assets/constants-DI382mTP.js +2 -0
  48. package/dist/renderer/assets/index-DLzjz1wv.js +50 -0
  49. package/dist/renderer/assets/{input-CFHmbOgz.js → input-6fpCXV-n.js} +2 -2
  50. package/dist/renderer/assets/ipc-transport-Bs8Sf1B2.css +1 -0
  51. package/dist/renderer/assets/{ipc-transport-BkKKww3u.js → ipc-transport-D22e4dv7.js} +6 -6
  52. package/dist/renderer/assets/popover-CdGdKkkc.js +2 -0
  53. package/dist/renderer/assets/select-X0sbjwdP.js +2 -0
  54. package/dist/renderer/assets/{settings-Cl4IcWnG.js → settings-CS4jYaCw.js} +2 -2
  55. package/dist/renderer/assets/settings-api-CCWTAao_.js +2 -0
  56. package/dist/renderer/assets/workbenchSettings-Bpzaj3bm.js +8 -0
  57. package/dist/renderer/entries/main/index.html +7 -6
  58. package/dist/renderer/entries/popover/index.html +6 -6
  59. package/dist/renderer/entries/settings/index.html +5 -5
  60. package/dist/renderer/entries/workbench-settings/index.html +5 -5
  61. package/dist/shared/constants.d.ts +18 -0
  62. package/dist/shared/constants.js +18 -0
  63. package/dist/shared/ipc-channels.d.ts +10 -23
  64. package/dist/shared/ipc-channels.js +13 -34
  65. package/dist/shared/ipc-schemas.d.ts +0 -12
  66. package/dist/shared/ipc-schemas.js +0 -12
  67. package/dist/shared/types.d.ts +14 -67
  68. package/package.json +6 -6
  69. package/dist/main/ipc/panels.d.ts +0 -4
  70. package/dist/main/ipc/panels.js +0 -46
  71. package/dist/main/ipc/toolbar.d.ts +0 -4
  72. package/dist/main/ipc/toolbar.js +0 -21
  73. package/dist/main/services/toolbar/toolbar-store.d.ts +0 -23
  74. package/dist/main/services/toolbar/toolbar-store.js +0 -40
  75. package/dist/preload/windows/host-toolbar.cjs.map +0 -7
  76. package/dist/preload/windows/host-toolbar.d.ts +0 -2
  77. package/dist/preload/windows/host-toolbar.js +0 -12
  78. package/dist/renderer/assets/constants-CLAQX6VZ.js +0 -2
  79. package/dist/renderer/assets/index-CZQOpCvg.js +0 -50
  80. package/dist/renderer/assets/ipc-transport-Bv_BVu4T.css +0 -1
  81. package/dist/renderer/assets/popover-h1M7n3tt.js +0 -2
  82. package/dist/renderer/assets/select-kj0n1oYf.js +0 -2
  83. package/dist/renderer/assets/settings-api-CCwo2eOi.js +0 -2
  84. package/dist/renderer/assets/workbenchSettings-BzlpQnve.js +0 -8
@@ -4,11 +4,11 @@ import type { WorkbenchContext } from '../main/services/workbench-context.js';
4
4
  /**
5
5
  * The narrowed view of `WorkbenchContext` handed to a host `menuBuilder`.
6
6
  * Strips the internal pipeline fields (`registry`, `senderPolicy`,
7
- * `trustedWindowSenderIds`, `simulatorApis`, `toolbar`) so a menu builder can
7
+ * `trustedWindowSenderIds`, `simulatorApis`) so a menu builder can
8
8
  * read menu-relevant state (workspace, views, windows, notify, appName, …)
9
9
  * without reaching into devtools-internal plumbing.
10
10
  */
11
- export type MenuContext = Omit<WorkbenchContext, 'registry' | 'senderPolicy' | 'trustedWindowSenderIds' | 'simulatorApis' | 'toolbar'>;
11
+ export type MenuContext = Omit<WorkbenchContext, 'registry' | 'senderPolicy' | 'trustedWindowSenderIds' | 'simulatorApis'>;
12
12
  export interface AppInfo {
13
13
  appName?: string;
14
14
  [key: string]: unknown;
@@ -23,59 +23,17 @@ export interface CompilationAdapter {
23
23
  }
24
24
  export type BuiltinPanelId = 'wxml' | 'console' | 'appdata' | 'storage';
25
25
  export type BuiltinModuleId = 'projects' | 'session' | 'simulator' | 'popover' | 'settings';
26
- /**
27
- * Cross-IPC / renderer shape of a toolbar action. Carries no `handler` — the
28
- * handler is non-serialisable and never crosses the IPC boundary.
29
- */
30
- export type ToolbarActionPlacement = 'leading' | 'primary' | 'trailing';
31
- export type ToolbarActionKind = 'button' | 'avatar';
32
- export type BeforeOpenProjectResult = {
33
- allow: true;
34
- statusMessage?: string;
35
- } | {
36
- allow: false;
37
- reason: string;
38
- userMessage?: string;
39
- };
40
- export interface ToolbarAction {
41
- id: string;
42
- label: string;
43
- /** Visual treatment. `avatar` keeps an account entry circular even without an image URL. */
44
- kind?: ToolbarActionKind;
45
- /**
46
- * Optional visual placement in the project-window header.
47
- * Omitted actions default to `primary` so existing hosts remain visible
48
- * near the compile controls.
49
- */
50
- placement?: ToolbarActionPlacement;
51
- /** Short text glyph rendered before the label for compact host actions. */
52
- icon?: string;
53
- /** Explicit fallback text for avatar actions when no image URL is available. */
54
- displayInitial?: string;
55
- /** Avatar image URL for account-style actions. Falls back to label initials. */
56
- avatarUrl?: string;
57
- }
58
- /**
59
- * Host-facing toolbar action passed to `instance.toolbar.set()`. Includes the
60
- * `handler` (kept main-process side); only `{id,label}` is projected to the
61
- * renderer.
62
- */
63
- export interface ToolbarActionInput {
64
- id: string;
65
- label: string;
66
- kind?: ToolbarActionKind;
67
- placement?: ToolbarActionPlacement;
68
- icon?: string;
69
- displayInitial?: string;
70
- avatarUrl?: string;
71
- handler: () => void | Promise<void>;
72
- }
73
26
  export interface WorkbenchConfig {
74
27
  /** Window title, default 'Dimina DevTools' */
75
28
  appName?: string;
76
29
  /** Compilation adapter */
77
30
  adapter?: CompilationAdapter;
78
- /** Built-in panel IDs to display, default all four */
31
+ /**
32
+ * @deprecated Ignored at runtime. The workbench UI always renders all four
33
+ * built-in panels (WXML / Console / AppData / Storage); the config no longer
34
+ * filters them and never lands on the context. Kept only so existing hosts
35
+ * passing it keep compiling.
36
+ */
79
37
  panels?: BuiltinPanelId[];
80
38
  /** Absolute path to a custom preload script (overrides built-in simulator.js) */
81
39
  preloadPath?: string;
@@ -87,7 +45,12 @@ export interface WorkbenchConfig {
87
45
  }> | {
88
46
  appName: string;
89
47
  };
90
- /** Header bar height in px, used for view layout. Default 40. */
48
+ /**
49
+ * @deprecated Ignored. The devtools toolbar header is fixed at 40px
50
+ * (`HEADER_H` in `shared/constants`). Hosts that need their own toolbar
51
+ * should use the host toolbar WCV instead. Kept only so existing hosts
52
+ * passing it keep compiling; it has no runtime effect.
53
+ */
91
54
  headerHeight?: number;
92
55
  }
93
56
  export interface CompileConfig {
@@ -152,19 +115,7 @@ export interface WorkbenchHostInstance {
152
115
  * The returned Disposable removes only the registration it created.
153
116
  */
154
117
  registerSimulatorApi(name: string, handler: SimulatorApiHandler): import('@dimina-kit/electron-deck/main').Disposable;
155
- /**
156
- * Per-context toolbar surface. `set()` atomically replaces the whole table
157
- * of toolbar actions stored on THIS context (duplicate `id` → throws),
158
- * then notifies the renderer to re-fetch.
159
- */
160
- readonly toolbar: {
161
- set(actions: ToolbarActionInput[]): void;
162
- };
163
118
  }
164
- export type BeforeOpenProjectHook = (ctx: {
165
- projectPath: string;
166
- instance: WorkbenchHostInstance;
167
- }) => BeforeOpenProjectResult | Promise<BeforeOpenProjectResult>;
168
119
  /**
169
120
  * Pluggable backend for the project-list panel. Hosts may supply this to
170
121
  * take over project storage from the default `<userData>/dimina-projects.json`.
@@ -182,8 +133,6 @@ export interface ProjectsProvider {
182
133
  updateLastOpened?(dirPath: string): void | Promise<void>;
183
134
  getCompileConfig?(dirPath: string): unknown;
184
135
  saveCompileConfig?(dirPath: string, cfg: unknown): void | Promise<void>;
185
- saveThumbnail?(dirPath: string, imageDataUrl: string): void | Promise<void>;
186
- getThumbnail?(dirPath: string): string | null | Promise<string | null>;
187
136
  }
188
137
  export interface ProjectTemplate {
189
138
  id: string;
@@ -217,8 +166,6 @@ export interface WorkbenchAppConfig extends WorkbenchConfig {
217
166
  menuBuilder?: (mainWindow: import('electron').BrowserWindow, menuContext: MenuContext) => void;
218
167
  /** Called after window and context are created but before start() resolves. Use to register custom IPC handlers. */
219
168
  onSetup?: (instance: WorkbenchHostInstance) => void | Promise<void>;
220
- /** Called after project-directory validation but before an active session is closed and a new project compile starts. */
221
- onBeforeOpenProject?: BeforeOpenProjectHook;
222
169
  /** Called before window close when a session is active. Session disposal happens automatically after this hook. */
223
170
  onBeforeClose?: (instance: WorkbenchHostInstance) => void | Promise<void>;
224
171
  /** Custom update checker. If provided, enables the check-for-updates feature. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dimina-kit/devtools",
3
- "version": "0.3.2-dev.20260611063505",
3
+ "version": "0.3.2-dev.20260611135124",
4
4
  "description": "Dimina DevTools - modular developer tools for mini app debugging",
5
5
  "keywords": [
6
6
  "dimina",
@@ -86,9 +86,9 @@
86
86
  "monaco-editor": "^0.55.1",
87
87
  "ws": "^8.20.0",
88
88
  "zod": "^4.3.6",
89
- "@dimina-kit/view-anchor": "0.1.0-dev.20260611063505",
90
- "@dimina-kit/electron-deck": "0.1.0-dev.20260611063505",
91
- "@dimina-kit/devkit": "0.1.2-dev.20260611063505"
89
+ "@dimina-kit/devkit": "0.1.2-dev.20260611135124",
90
+ "@dimina-kit/view-anchor": "0.1.0-dev.20260611135124",
91
+ "@dimina-kit/electron-deck": "0.1.0-dev.20260611135124"
92
92
  },
93
93
  "devDependencies": {
94
94
  "@playwright/test": "^1.59.1",
@@ -149,9 +149,9 @@
149
149
  "pack": "electron-builder --dir",
150
150
  "dist": "electron-builder",
151
151
  "build:main": "tsc -p tsconfig.main.json && esbuild src/main/index.ts --bundle --platform=node --format=esm --target=node24 --external:electron --packages=external --outfile=dist/main/index.bundle.js",
152
- "build:preload": "tsc -p tsconfig.preload.json && esbuild src/preload/windows/simulator.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/simulator.js && esbuild src/preload/windows/simulator.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/simulator.cjs && esbuild src/preload/windows/main.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/main.cjs && esbuild src/preload/windows/host-toolbar.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/host-toolbar.cjs",
152
+ "build:preload": "tsc -p tsconfig.preload.json && esbuild src/preload/windows/simulator.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/simulator.js && esbuild src/preload/windows/simulator.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/simulator.cjs && esbuild src/preload/windows/main.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/main.cjs && esbuild src/preload/windows/host-toolbar-runtime.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/host-toolbar-runtime.cjs",
153
153
  "build:renderer": "vite build",
154
- "dev": "pnpm build && concurrently \"vite build --watch\" \"vite build --watch --config vite.config.simulator.ts\" \"tsc -p tsconfig.main.json --watch\" \"tsc -p tsconfig.preload.json --watch\" \"esbuild src/preload/windows/simulator.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/simulator.js --watch\" \"esbuild src/preload/windows/simulator.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/simulator.cjs --watch\" \"esbuild src/preload/windows/main.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/main.cjs --watch\" \"electron dist/main/index.js\"",
154
+ "dev": "pnpm build && concurrently \"vite build --watch\" \"vite build --watch --config vite.config.simulator.ts\" \"tsc -p tsconfig.main.json --watch\" \"tsc -p tsconfig.preload.json --watch\" \"esbuild src/preload/windows/simulator.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/simulator.js --watch\" \"esbuild src/preload/windows/simulator.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/simulator.cjs --watch\" \"esbuild src/preload/windows/main.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/main.cjs --watch\" \"esbuild src/preload/windows/host-toolbar-runtime.ts --bundle --platform=node --format=cjs --sourcemap --external:electron --outfile=dist/preload/windows/host-toolbar-runtime.cjs --watch\" \"electron dist/main/index.js\"",
155
155
  "build:core": "pnpm --filter @dimina-kit/devkit build",
156
156
  "check-types": "tsc --noEmit",
157
157
  "lint": "eslint . --max-warnings 0",
@@ -1,4 +0,0 @@
1
- import type { WorkbenchContext } from '../services/workbench-context.js';
2
- import type { Disposable } from '@dimina-kit/electron-deck/main';
3
- export declare function registerPanelsIpc(ctx: Pick<WorkbenchContext, 'panels' | 'views' | 'workspace' | 'senderPolicy'>): Disposable;
4
- //# sourceMappingURL=panels.d.ts.map
@@ -1,46 +0,0 @@
1
- import { PanelChannel, WorkbenchRuntimeChannel } from '../../shared/ipc-channels.js';
2
- import { PanelEvalSchema, PanelSelectSchema, } from '../../shared/ipc-schemas.js';
3
- import { validate } from '../utils/ipc-schema.js';
4
- import { IpcRegistry } from '../utils/ipc-registry.js';
5
- const BUILTIN_PANELS = [
6
- { id: 'wxml', label: 'WXML' },
7
- { id: 'appdata', label: 'AppData' },
8
- { id: 'storage', label: 'Storage' },
9
- ];
10
- export function registerPanelsIpc(ctx) {
11
- return new IpcRegistry(ctx.senderPolicy)
12
- .handle(PanelChannel.List, () => {
13
- return BUILTIN_PANELS
14
- .filter((p) => ctx.panels.includes(p.id));
15
- })
16
- .handle(PanelChannel.Eval, async (_event, ...args) => {
17
- const [expression] = validate(PanelChannel.Eval, PanelEvalSchema, args);
18
- if (!ctx.workspace.hasActiveSession())
19
- return undefined;
20
- const sim = ctx.views.getSimulatorWebContents();
21
- if (!sim)
22
- return undefined;
23
- try {
24
- return await sim.executeJavaScript(expression);
25
- }
26
- catch {
27
- return undefined;
28
- }
29
- })
30
- .handle(PanelChannel.Select, (_event, ...args) => {
31
- validate(PanelChannel.Select, PanelSelectSchema, args);
32
- if (ctx.views.hasSimulatorView() && ctx.views.isSimulatorAdded()) {
33
- ctx.views.hideSimulator();
34
- }
35
- })
36
- .handle(PanelChannel.SelectSimulator, () => {
37
- if (ctx.views.hasSimulatorView() && !ctx.views.isSimulatorAdded()) {
38
- ctx.views.showSimulator(ctx.views.getLastSimWidth());
39
- }
40
- })
41
- // Renderer reads this once to pick panel data sources: native-host is the
42
- // sole runtime, so WXML + AppData always come from the main process (the
43
- // page/service logic live in separate webContents).
44
- .handle(WorkbenchRuntimeChannel.GetNativeHost, () => true);
45
- }
46
- //# sourceMappingURL=panels.js.map
@@ -1,4 +0,0 @@
1
- import type { WorkbenchContext } from '../services/workbench-context.js';
2
- import type { Disposable } from '@dimina-kit/electron-deck/main';
3
- export declare function registerToolbarIpc(ctx: Pick<WorkbenchContext, 'toolbar' | 'senderPolicy'>): Disposable;
4
- //# sourceMappingURL=toolbar.d.ts.map
@@ -1,21 +0,0 @@
1
- import { ToolbarChannel } from '../../shared/ipc-channels.js';
2
- import { ToolbarInvokeSchema } from '../../shared/ipc-schemas.js';
3
- import { validate } from '../utils/ipc-schema.js';
4
- import { IpcRegistry } from '../utils/ipc-registry.js';
5
- export function registerToolbarIpc(ctx) {
6
- return new IpcRegistry(ctx.senderPolicy)
7
- .handle(ToolbarChannel.GetActions, () => {
8
- // Project to {id,label}[] — the non-serialisable handler never leaves
9
- // the main process.
10
- return ctx.toolbar.list();
11
- })
12
- .handle(ToolbarChannel.Invoke, async (_, ...args) => {
13
- const [id] = validate(ToolbarChannel.Invoke, ToolbarInvokeSchema, args);
14
- const handler = ctx.toolbar.getHandler(id);
15
- if (!handler) {
16
- throw new Error(`Toolbar action "${id}" is not registered`);
17
- }
18
- await handler();
19
- });
20
- }
21
- //# sourceMappingURL=toolbar.js.map
@@ -1,23 +0,0 @@
1
- import type { ToolbarAction, ToolbarActionInput } from '../../../shared/types.js';
2
- /**
3
- * Per-context store for host-registered toolbar actions.
4
- *
5
- * The toolbar is modelled as "one table the host recomputes from its current
6
- * state": `set()` replaces the whole table atomically. The non-serialisable
7
- * `handler` is kept main-process side; `list()` projects display metadata for
8
- * the IPC boundary, and `getHandler()` resolves a handler by id.
9
- */
10
- export interface ToolbarStore {
11
- /**
12
- * Atomically replace the whole toolbar table. Validates that every `id` is
13
- * unique up-front; on a duplicate it throws WITHOUT mutating the store, so
14
- * a rejected batch leaves the previous table intact.
15
- */
16
- set(actions: ToolbarActionInput[]): void;
17
- /** Project the current table to serialisable display metadata — no `handler` leaks out. */
18
- list(): ToolbarAction[];
19
- /** Resolve the handler stored under `id`, or `undefined` if unknown. */
20
- getHandler(id: string): (() => void | Promise<void>) | undefined;
21
- }
22
- export declare function createToolbarStore(): ToolbarStore;
23
- //# sourceMappingURL=toolbar-store.d.ts.map
@@ -1,40 +0,0 @@
1
- function toPublicAction(action) {
2
- const projected = {
3
- id: action.id,
4
- label: action.label,
5
- };
6
- if (action.kind)
7
- projected.kind = action.kind;
8
- if (action.placement)
9
- projected.placement = action.placement;
10
- if (action.icon)
11
- projected.icon = action.icon;
12
- if (action.displayInitial)
13
- projected.displayInitial = action.displayInitial;
14
- if (action.avatarUrl)
15
- projected.avatarUrl = action.avatarUrl;
16
- return projected;
17
- }
18
- export function createToolbarStore() {
19
- let actions = [];
20
- return {
21
- set(next) {
22
- const seen = new Set();
23
- for (const action of next) {
24
- if (seen.has(action.id)) {
25
- throw new Error(`Duplicate toolbar action id "${action.id}"`);
26
- }
27
- seen.add(action.id);
28
- }
29
- // Copy so a later host mutation of the passed array can't reach in.
30
- actions = next.slice();
31
- },
32
- list() {
33
- return actions.map(toPublicAction);
34
- },
35
- getHandler(id) {
36
- return actions.find((a) => a.id === id)?.handler;
37
- },
38
- };
39
- }
40
- //# sourceMappingURL=toolbar-store.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/preload/runtime/host-toolbar-advertiser.ts", "../../../../view-anchor/src/measure-loop.ts", "../../../../view-anchor/src/size-advertiser.ts", "../../../src/shared/ipc-channels.ts", "../../../src/preload/windows/host-toolbar.ts"],
4
- "sourcesContent": ["/**\n * Reverse size-advertiser preload for the host-controllable toolbar\n * WebContentsView. Runs in that WCV's OWN renderer (the toolbar content's\n * preload), measures the toolbar's intrinsic block (height) extent and sends it\n * to the main process. Main pushes the value back to the main-window renderer as\n * `HostToolbarHeightChanged`, which resizes the toolbar placeholder, re-measures\n * the forward anchor, and re-overlays this WCV \u2014 closing the dynamic-height loop\n * (see `@dimina-kit/view-anchor` `createSizeAdvertiser`).\n */\n\nimport { ipcRenderer } from 'electron'\nimport { createSizeAdvertiser } from '@dimina-kit/view-anchor'\nimport { ViewChannel } from '../../shared/ipc-channels.js'\n\n/**\n * Attach the advertiser to the toolbar content's shrink-to-fit root\n * (`[data-host-toolbar-root]`). That element MUST be shrink-to-fit on the block\n * axis \u2014 its height must reflect the content, not the host-applied view height,\n * or the cross-process loop never converges (`createSizeAdvertiser`'s footgun).\n * If the element is missing we warn and no-op rather than measure `<body>`,\n * whose block size IS the view size and would advertise nonsense.\n *\n * Returns a disposer that tears the advertiser down.\n */\nexport function installHostToolbarAdvertiser(): () => void {\n const root = document.querySelector<HTMLElement>('[data-host-toolbar-root]')\n if (!root) {\n console.warn(\n '[host-toolbar-advertiser] no `[data-host-toolbar-root]` element found \u2014 ' +\n 'not advertising a height. The toolbar content must wrap itself in a ' +\n 'shrink-to-fit `[data-host-toolbar-root]` element so its block size is ' +\n 'the content height, not the host-given view size.',\n )\n return () => {}\n }\n\n const advertiser = createSizeAdvertiser(root, {\n axis: 'block',\n publish: (size) => {\n ipcRenderer.send(ViewChannel.HostToolbarAdvertiseHeight, size)\n },\n })\n\n return () => advertiser.dispose()\n}\n\n/**\n * Install once the DOM is ready (the root element must exist before we query).\n * Self-gating: if the document is already past `loading`, install synchronously;\n * otherwise wait for `DOMContentLoaded`.\n */\nexport function installHostToolbarAdvertiserWhenReady(): void {\n if (document.readyState === 'loading') {\n document.addEventListener(\n 'DOMContentLoaded',\n () => {\n installHostToolbarAdvertiser()\n },\n { once: true },\n )\n } else {\n installHostToolbarAdvertiser()\n }\n}\n", "/**\n * Internal \u2014 the RAF-coalesced measure/dedupe/dispose engine behind the REVERSE\n * primitive `createSizeAdvertiser`.\n *\n * The forward `createViewAnchor` deliberately does NOT use this: it publishes\n * SYNCHRONOUSLY (a native overlay's `setBounds` already lands a cross-process\n * frame late, and a RAF stacked a second frame of visible trailing). The\n * reverse direction is different \u2014 it is a cross-process FEEDBACK loop\n * (advertise \u2192 host resizes the view \u2192 content re-measures \u2192 re-advertise), so\n * the RAF's one-publish-per-frame coalescing is a useful damper. The two\n * directions thus have different optimal emit timing; this engine serves only\n * the reverse.\n *\n * NOT exported from the package: it is pure mechanism with no knowledge of\n * direction, the DOM, `ResizeObserver`, or the structure of the value `T` it\n * carries. The wrapping primitive injects `produce` / `same` / `sink` and\n * drives the lifecycle.\n *\n * - `schedule()` \u2014 coalesce a burst of triggers into ONE RAF; the frame\n * body re-`produce()`s, dedupes against the last emit (`same`), and `sink`s.\n * Bails if inactive or disposed (stale-RAF safe).\n * - `emitNow(v)` \u2014 explicit synchronous emit (create / update path). Always\n * fires, bypassing the dedupe check, and refreshes the dedupe baseline.\n * - `setActive` \u2014 gate the observer stream; a queued frame bails on `!active`.\n * - `cancel` \u2014 drop any in-flight RAF.\n * - `dispose` \u2014 cancel + go inert; after dispose nothing emits again.\n */\nexport interface MeasureLoop<T> {\n schedule(): void\n emitNow(value: T): void\n setActive(on: boolean): void\n cancel(): void\n dispose(): void\n}\n\nexport function createMeasureLoop<T>(cfg: {\n /** Produce the value to emit in the RAF body. Return `null` to decline the\n * frame entirely (no dedupe, no sink, baseline untouched) \u2014 e.g. a\n * non-finite or unavailable measurement. */\n produce: () => T | null\n same: (a: T, b: T) => boolean\n sink: (value: T) => void\n}): MeasureLoop<T> {\n const { produce, same, sink } = cfg\n let rafId: number | null = null\n let active = false\n let disposed = false\n let last: T | null = null\n\n const cancel = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n rafId = null\n }\n }\n\n return {\n schedule(): void {\n if (disposed || !active || rafId !== null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n if (disposed || !active) return\n const value = produce()\n if (value === null) return // producer declined this frame\n // last-value dedupe: a frame whose produced value equals the last one\n // we emitted costs nothing (no IPC / setBounds).\n if (last !== null && same(value, last)) return\n last = value\n sink(value)\n })\n },\n emitNow(value: T): void {\n if (disposed) return\n last = value\n sink(value)\n },\n setActive(on: boolean): void {\n active = on\n },\n cancel,\n dispose(): void {\n if (disposed) return\n disposed = true\n cancel()\n },\n }\n}\n", "import type {\n AdvertisedSize,\n SizeAdvertiserOptions,\n SizeAdvertiserHandle,\n} from './types.js'\nimport { createMeasureLoop } from './measure-loop.js'\n\n/**\n * Reverse of `createViewAnchor`: runs in a downstream WebContentsView's own\n * renderer, measures the content's own size on ONE owned axis (from the\n * `ResizeObserver` border-box \u2014 no `getBoundingClientRect`, no forced reflow),\n * and advertises it via the injected `publish`. Shares the forward primitive's\n * measure/coalesce/dedupe/dispose engine (`createMeasureLoop`).\n *\n * The extent is `Math.round`ed and clamped to `>= 0`; non-finite measurements\n * drop the frame.\n *\n * FOOTGUN \u2014 `target` must be shrink-to-fit on the owned axis: its owned-axis\n * size must NOT be driven by the host-applied view size, or the cross-process\n * loop (advertise \u2192 host resizes view \u2192 remeasure) never converges (it\n * oscillates or stays \"stable but wrong\"). Measuring `<body>`/`<html>` is the\n * classic mistake \u2014 their size *is* the view size. See\n * `docs/bidirectional-design.md` \u00A74/\u00A75.\n */\nexport function createSizeAdvertiser(\n target: HTMLElement,\n opts: SizeAdvertiserOptions,\n): SizeAdvertiserHandle {\n const axis = opts.axis // immutable for the advertiser's life\n let publish = opts.publish\n let observer: ResizeObserver | null = null\n let disposed = false\n // Latest border-box, stashed by the RO callback and read by `produce` in the\n // RAF body (keep the entry out of the shared, DOM-agnostic loop).\n let latest: ResizeObserverSize | null = null\n\n const produce = (): AdvertisedSize | null => {\n if (!latest) return null\n const raw = axis === 'block' ? latest.blockSize : latest.inlineSize\n if (!Number.isFinite(raw)) return null\n return { axis, extent: Math.max(0, Math.round(raw)) }\n }\n\n const loop = createMeasureLoop<AdvertisedSize>({\n produce,\n same: (a, b) => a.extent === b.extent, // axis is constant\n sink: (size) => publish(size),\n })\n\n const onResize: ResizeObserverCallback = (entries) => {\n const entry = entries[entries.length - 1]\n if (entry) {\n latest = entry.borderBoxSize?.[0] ?? entry.contentBoxSize?.[0] ?? latest\n }\n loop.schedule()\n }\n\n // One cheap, once-per-advertiser guard for the textbook feedback-loop footgun.\n const doc = target.ownerDocument\n if (target === doc.body || target === doc.documentElement) {\n console.warn(\n `[view-anchor] size-advertiser: <${target === doc.body ? 'body' : 'html'}>'s ` +\n `${axis} size is the host-given view size, not the content size \u2014 the ` +\n `advertiser will never shrink to content. Measure a shrink-to-fit wrapper. ` +\n `See bidirectional-design.md \u00A74.`,\n )\n }\n\n loop.setActive(true)\n observer = new ResizeObserver(onResize)\n observer.observe(target)\n\n return {\n update(nextPublish: (size: AdvertisedSize) => void): void {\n if (disposed) return\n publish = nextPublish\n // Re-advertise the current size to the new sink immediately (mirrors the\n // forward anchor's re-publish on update) so the new channel is not left\n // sizeless until the next ResizeObserver tick.\n const cur = produce()\n if (cur) loop.emitNow(cur)\n },\n dispose(): void {\n if (disposed) return\n disposed = true\n loop.cancel()\n if (observer) {\n observer.disconnect()\n observer = null\n }\n loop.dispose()\n },\n }\n}\n", "/**\n * Centralised IPC channel name constants for dimina-devtools.\n *\n * Every raw channel string used across main, renderer, preload and e2e code\n * should reference one of these constants so that renaming a channel only\n * requires a single edit.\n */\n\n// \u2500\u2500 Simulator (preload \u2192 host / renderer \u2194 main) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const SimulatorChannel = {\n // Ask main to create the simulator as a top-level WebContentsView (so nested\n // render-host <webview>s can attach). Native-host is the sole runtime.\n AttachNative: 'simulator:attach-native',\n // Renderer reports the device-bezel inner-screen rect (CSS px from content\n // top-left) + zoom so main can overlay the simulator WCV on it.\n SetNativeBounds: 'simulator:set-native-bounds',\n // Renderer pushes the selected device's LOGICAL metrics (screen size,\n // pixelRatio, statusBarHeight, \u2026) when the device dropdown changes. Main\n // maps it to a HostEnvSnapshot and live-updates the running service-host\n // window \u2014 the authoritative `wx.getSystemInfoSync()` source \u2014 so the\n // mini-app sees the selected device without a relaunch.\n SetDeviceInfo: 'simulator:set-device-info',\n Detach: 'simulator:detach',\n Resize: 'simulator:resize',\n SetVisible: 'simulator:setVisible',\n Console: 'simulator:console',\n // Main \u2192 renderer push of the visible top-of-stack page route whenever the\n // mini-app navigates (navigateTo / switchTab / back). Payload: the page path\n // string (same bare format as `getCurrentPagePath`), or '' when unknown.\n CurrentPage: 'simulator:current-page',\n} as const\n\n/** iPhone bezel cutout family driving the device-shell notch visual. */\nexport type NotchType = 'none' | 'notch' | 'dynamic-island'\n\n/** Per-device safe-area insets in CSS px (portrait). */\nexport interface SafeAreaInsets {\n top: number\n right: number\n bottom: number\n left: number\n}\n\n/**\n * Logical device metrics pushed by the renderer device dropdown under\n * native-host (`SimulatorChannel.SetDeviceInfo`). Mirrors a row of the renderer\n * `DEVICES` table; main maps it onto a `HostEnvSnapshot` for the service-host\n * window so `wx.getSystemInfoSync()` reflects the selected device, relays it to\n * the simulator WCV (DeviceShell: bezel size + status bar + notch), and drives\n * the CSS `env(safe-area-inset-*)` override on render-host guests.\n */\nexport interface NativeDeviceInfo {\n brand: string\n model: string\n system: string\n platform: string\n pixelRatio: number\n screenWidth: number\n screenHeight: number\n statusBarHeight: number\n safeAreaBottom: number\n notchType: NotchType\n safeAreaInsets: SafeAreaInsets\n}\n\n// \u2500\u2500 Service host (main \u2192 hidden service-host window) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const ServiceHostChannel = {\n /**\n * NATIVE-HOST ONLY. Live-update the service-host window's host-env snapshot\n * (device metrics) so subsequent `wx.getSystemInfoSync()` reflects a device\n * change without a relaunch. The service-host preload mutates\n * `__diminaSpawnContext.hostEnvSnapshot` in place (see `service-host/preload.cjs`).\n */\n HostEnvUpdate: 'service-host:host-env:update',\n} as const\n\n// \u2500\u2500 Custom simulator APIs (downstream-registered, main-process handlers) \u2500\u2500\n// list: simulator queries the names registered via instance.registerSimulatorApi().\n// invoke: simulator forwards an API call to the registry; result/reject propagates.\n//\n// These are ipcMain.handle channels invoked by the **main-window renderer**\n// only (trusted host). The simulator guest never reaches them directly \u2014 it\n// reaches the host via the bridge channels below, so the sender-policy can keep\n// the simulator off the IPC white-list.\nexport const SimulatorCustomApiChannel = {\n List: 'simulator:custom-apis:list',\n Invoke: 'simulator:custom-apis:invoke',\n} as const\n\n// \u2500\u2500 Custom APIs bridge (simulator \u2192 host) \u2500\u2500\n// payload = { id, op: 'list' } | { id, op: 'invoke', name, params } for Request,\n// { id, result } | { id, error } for Response. Transport (in\n// `src/preload/runtime/custom-apis.ts`): native-host \u2014 the simulator is a\n// top-level WebContentsView (no embedder), so Request goes via\n// `ipcRenderer.send` \u2192 `ipcMain.on` dispatcher bound to that simWc (view-manager\n// `attachNativeCustomApiBridge`) \u2192 Response via `simWc.send`. (The old\n// renderer-proxied `<webview>` transport, `ipcRenderer.sendToHost` \u2192\n// `<webview>.send`, no longer exists \u2014 native-host is the sole runtime.)\n//\n// Request/response are correlated by `id` so multiple concurrent invokes can\n// be in flight at once.\nexport const SimulatorCustomApiBridgeChannel = {\n Request: 'simulator:custom-apis:bridge-request',\n Response: 'simulator:custom-apis:bridge-response',\n} as const\n\n// \u2500\u2500 Storage (CDP-backed; main process attaches the debugger to the\n// simulator guest and forwards DOMStorage events to the renderer) \u2500\u2500\nexport const SimulatorStorageChannel = {\n GetSnapshot: 'simulator:storage:snapshot',\n GetActivePrefix: 'simulator:storage:activePrefix',\n Set: 'simulator:storage:set',\n Remove: 'simulator:storage:remove',\n Clear: 'simulator:storage:clear',\n ClearAll: 'simulator:storage:clearAll',\n Event: 'simulator:storage:event',\n} as const\n\nexport interface StorageItem { key: string; value: string }\nexport type StorageEvent =\n | { type: 'added'; key: string; newValue: string }\n | { type: 'updated'; key: string; oldValue: string; newValue: string }\n | { type: 'removed'; key: string }\n | { type: 'cleared' }\n\nexport type StorageWriteResult =\n | { ok: true }\n | { ok: false; error: string }\n\n// \u2500\u2500 Element inspection (CDP-backed; WXML tree nodes map to real DOM by sid) \u2500\u2500\nexport const SimulatorElementChannel = {\n Inspect: 'simulator:element:inspect',\n Clear: 'simulator:element:clear',\n} as const\n\n// \u2500\u2500 Workbench runtime info (renderer reads once to pick panel data sources) \u2500\u2500\n// Under native-host the page DOM / service logic live in separate webContents,\n// so WXML + AppData are sourced from the main process instead of the simulator\n// guest's miniappSnapshot transport. The renderer queries this flag once and\n// branches usePanelData accordingly.\nexport const WorkbenchRuntimeChannel = {\n GetNativeHost: 'workbench:runtime:native-host',\n} as const\n\n// \u2500\u2500 WXML tree (native-host: main pulls the tree from the active render-host\n// <webview> guest via render-inspect, and pushes/answers here \u2014 mirroring the\n// Storage panel's main\u2192renderer contract so the renderer panel is unchanged) \u2500\u2500\nexport const SimulatorWxmlChannel = {\n GetSnapshot: 'simulator:wxml:snapshot',\n Event: 'simulator:wxml:event',\n} as const\n\n// \u2500\u2500 AppData (native-host: main taps the service\u2192render setData stream in\n// bridge-router and pushes the cumulative snapshot here \u2014 the service logic runs\n// in the hidden service-host window, not a Worker in the simulator guest) \u2500\u2500\nexport const SimulatorAppDataChannel = {\n GetSnapshot: 'simulator:appdata:snapshot',\n Event: 'simulator:appdata:event',\n} as const\n\nexport interface ElementInspection {\n sid: string\n rect: {\n x: number\n y: number\n width: number\n height: number\n }\n style: {\n display: string\n position: string\n boxSizing: string\n margin: string\n padding: string\n color: string\n backgroundColor: string\n fontSize: string\n }\n}\n\n// \u2500\u2500 Workbench settings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const WorkbenchSettingsChannel = {\n Get: 'workbenchSettings:get',\n Save: 'workbenchSettings:save',\n SetTheme: 'workbenchSettings:setTheme',\n GetCdpStatus: 'workbenchSettings:getCdpStatus',\n GetMcpStatus: 'workbenchSettings:getMcpStatus',\n SetVisible: 'workbenchSettings:setVisible',\n Init: 'workbenchSettings:init',\n} as const\n\n// \u2500\u2500 Project session \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const ProjectChannel = {\n Open: 'project:open',\n Close: 'project:close',\n GetPages: 'project:getPages',\n GetCompileConfig: 'project:getCompileConfig',\n SaveCompileConfig: 'project:saveCompileConfig',\n Status: 'project:status',\n CaptureThumbnail: 'project:captureThumbnail',\n GetThumbnail: 'project:getThumbnail',\n} as const\n\n// \u2500\u2500 Project file system (sandboxed to active project root) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Read/write access to the active project's files, used by the in-renderer\n// Monaco editor. Every path is verified against the active project root in\n// the main process (see `services/project-fs`). Replaces the OpenSumi\n// editor's `editor:fs:*` bridge \u2014 same sandbox, callable from the main\n// renderer instead of a separate WebContentsView.\n\nexport const ProjectFsChannel = {\n GetRoot: 'project:fs:getRoot',\n ReadFile: 'project:fs:readFile',\n WriteFile: 'project:fs:writeFile',\n /**\n * Synchronous (blocking) write, used ONLY by the editor's `beforeunload`\n * flush: a hard window/app close tears the renderer down before an async\n * `WriteFile` IPC can round-trip, so the last in-debounce-window edit would\n * be lost. `sendSync` blocks page teardown until the bytes hit disk. Runs the\n * SAME sandbox as `WriteFile` (see project-fs `writeFileSync`).\n */\n WriteFileSync: 'project:fs:writeFileSync',\n ListFiles: 'project:fs:listFiles',\n} as const\n\n// \u2500\u2500 Editor (main \u2192 renderer) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Drives the in-renderer Monaco editor from the main process. Used by the\n// \"click a console file link \u2192 open the file at line:col\" pipeline: the\n// embedded DevTools front-end routes a source-link click through an open-\n// resource handler \u2192 Electron `devtools-open-url` on the service host \u2192 main\n// maps the resource URL to a project-relative path \u2192 this event opens it in\n// Monaco. Payload: `EditorOpenFilePayload`.\n\nexport const EditorChannel = {\n /** main \u2192 renderer: open `path` (project-relative POSIX) at `line`/`column`. */\n OpenFile: 'editor:openFile',\n} as const\n\n/** Payload for `editor:openFile`. `line`/`column` are 1-based for Monaco. */\nexport interface EditorOpenFilePayload {\n /** Project-relative POSIX path (the same key Monaco opens files by). */\n path: string\n /** 1-based line to reveal; omitted/<=0 means open without moving the cursor. */\n line?: number\n /** 1-based column to reveal; defaults to 1 when a line is given. */\n column?: number\n}\n\n// \u2500\u2500 Project list / workspace \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const ProjectsChannel = {\n List: 'projects:list',\n Add: 'projects:add',\n Remove: 'projects:remove',\n /** Phase 3: merged + sanitized template catalog for the create-project dialog. */\n ListTemplates: 'projects:listTemplates',\n /** Phase 3: host-supplied create-project dialog hook (returns input or null). */\n OpenCreateDialog: 'projects:openCreateDialog',\n /** Phase 3: server-side scaffold + register (delegates to create-project-service). */\n Create: 'projects:create',\n /** Default values used to pre-fill the create-project dialog (baseDir). */\n GetCreateDefaults: 'projects:getCreateDefaults',\n} as const\n\n/** Renderer-facing payload for `projects:getCreateDefaults`. */\nexport interface ProjectCreateDefaults {\n /** Absolute directory used as the parent for new projects. */\n baseDir: string\n}\n\n// \u2500\u2500 Dialog \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const DialogChannel = {\n OpenDirectory: 'dialog:openDirectory',\n} as const\n\n// \u2500\u2500 Panels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PanelChannel = {\n List: 'panel:list',\n Eval: 'panel:eval',\n Select: 'panel:select',\n SelectSimulator: 'panel:selectSimulator',\n} as const\n\n// \u2500\u2500 Embedded views (renderer \u2192 main) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// The main window's React layout owns the *positions* of the editor +\n// simulator-DevTools WebContentsView overlays \u2014 each visible placeholder\n// `<div>` measures its client rect via ResizeObserver and pushes the\n// rectangle to the main process. The view manager caches the latest\n// payload per kind and applies it to the overlay; no payload means the\n// overlay is hidden.\n//\n// Payload (after schema validation): `{ x, y, width, height }` in CSS\n// pixels relative to the window's content area (origin = top-left,\n// not including the OS chrome).\nexport const ViewChannel = {\n /** Update the simulator DevTools view's bounds (or hide if w/h = 0). */\n SimulatorDevtoolsBounds: 'view:simulator:devtools-bounds',\n /**\n * Host-controllable toolbar WebContentsView (sits ABOVE the devtools built-in\n * header). Forward anchor: the main renderer reports the toolbar placeholder's\n * bounds (or w/h=0 to hide). invoke.\n */\n HostToolbarBounds: 'view:host-toolbar:bounds',\n /**\n * Reverse size-advertiser: the host-toolbar WCV's OWN renderer advertises its\n * intrinsic content height so main reserves exactly that much. Payload\n * `{ axis: 'block', extent }`. fire-and-forget (send), NOT invoke.\n */\n HostToolbarAdvertiseHeight: 'view:host-toolbar:advertise-height',\n /**\n * main \u2192 main-window renderer: push the reserved host-toolbar height so the\n * renderer placeholder div resizes (closing the dynamic-height loop).\n */\n HostToolbarHeightChanged: 'view:host-toolbar:height-changed',\n} as const\n\nexport interface ViewBounds {\n x: number\n y: number\n width: number\n height: number\n}\n\n// \u2500\u2500 Popover \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PopoverChannel = {\n Show: 'popover:show',\n Hide: 'popover:hide',\n Relaunch: 'popover:relaunch',\n Closed: 'popover:closed',\n Init: 'popover:init',\n} as const\n\n// \u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const ToolbarChannel = {\n GetActions: 'toolbar:getActions',\n ActionsChanged: 'toolbar:actionsChanged',\n /** Invoke a toolbar action by id: `invoke(Invoke, actionId)`. */\n Invoke: 'toolbar:invoke',\n} as const\n\n// \u2500\u2500 Window \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const WindowChannel = {\n NavigateBack: 'window:navigateBack',\n} as const\n\n// \u2500\u2500 App \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const AppChannel = {\n GetPreloadPath: 'app:getPreloadPath',\n GetBranding: 'app:getBranding',\n GetHeaderHeight: 'app:getHeaderHeight',\n} as const\n\n// \u2500\u2500 miniappSnapshot (unified panel snapshot framework) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Two generic channels shared by every snapshot source (AppData, WXML, \u2026).\n// Adding a new panel needs no new channel.\n// Push: preload \u2192 renderer (`sendToHost`), payload: SnapshotEnvelope\n// Pull: renderer \u2192 preload (`webview.send`), payload: { id }\n\nexport const MiniappSnapshotChannel = {\n Push: 'miniapp-snapshot:push',\n Pull: 'miniapp-snapshot:pull',\n} as const\n\n// \u2500\u2500 Automation (WebSocket server) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const AutomationChannel = {\n GetPort: 'automation:port',\n} as const\n\n// \u2500\u2500 Embedded settings overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const SettingsChannel = {\n SetVisible: 'settings:setVisible',\n ConfigChanged: 'settings:configChanged',\n ProjectSettingsChanged: 'settings:projectSettingsChanged',\n Init: 'settings:init',\n Closed: 'settings:closed',\n Changed: 'settings:changed',\n} as const\n\n// \u2500\u2500 Updates (UpdateManager) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// String values are FROZEN: shipped builds key off them. Add new entries\n// here, never rename existing ones.\nexport const UpdateChannel = {\n Check: 'updates:check',\n Download: 'updates:download',\n Install: 'updates:install',\n DownloadProgress: 'updates:downloadProgress',\n Available: 'updates:available',\n} as const\n", "// Preload for the host-controllable toolbar WebContentsView.\n//\n// Bundled into a single CJS file via build:preload (esbuild) and loaded as the\n// toolbar WCV's `preload`. Its only job is to run the reverse size-advertiser:\n// it measures the host content's intrinsic height (a shrink-to-fit element the\n// host marks `[data-host-toolbar-root]`) and posts it to main on the\n// `view:host-toolbar:advertise-height` channel, so the main renderer reserves\n// exactly that height and the toolbar tracks it (dynamic height, foundation\n// ViewAnchor reverse-advertiser).\nimport { installHostToolbarAdvertiserWhenReady } from '../runtime/host-toolbar-advertiser.js'\n\ninstallHostToolbarAdvertiserWhenReady()\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=host-toolbar.d.ts.map
@@ -1,12 +0,0 @@
1
- // Preload for the host-controllable toolbar WebContentsView.
2
- //
3
- // Bundled into a single CJS file via build:preload (esbuild) and loaded as the
4
- // toolbar WCV's `preload`. Its only job is to run the reverse size-advertiser:
5
- // it measures the host content's intrinsic height (a shrink-to-fit element the
6
- // host marks `[data-host-toolbar-root]`) and posts it to main on the
7
- // `view:host-toolbar:advertise-height` channel, so the main renderer reserves
8
- // exactly that height and the toolbar tracks it (dynamic height, foundation
9
- // ViewAnchor reverse-advertiser).
10
- import { installHostToolbarAdvertiserWhenReady } from '../runtime/host-toolbar-advertiser.js';
11
- installHostToolbarAdvertiserWhenReady();
12
- //# sourceMappingURL=host-toolbar.js.map
@@ -1,2 +0,0 @@
1
- var e=9222,t=1001;export{t as n,e as t};
2
- //# sourceMappingURL=constants-CLAQX6VZ.js.map