@dimina-kit/devtools 0.3.2-dev.20260611063505 → 0.4.0-dev.20260612025610
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -41
- package/dist/main/api.d.ts +4 -2
- package/dist/main/api.js +5 -1
- package/dist/main/app/app.d.ts +1 -5
- package/dist/main/app/app.js +25 -30
- package/dist/main/app/launch.d.ts +4 -4
- package/dist/main/app/launch.js +5 -17
- package/dist/main/index.bundle.js +535 -593
- package/dist/main/ipc/app.d.ts +1 -1
- package/dist/main/ipc/app.js +0 -7
- package/dist/main/ipc/index.d.ts +0 -2
- package/dist/main/ipc/index.js +0 -2
- package/dist/main/ipc/settings.d.ts +1 -1
- package/dist/main/ipc/settings.js +1 -13
- package/dist/main/ipc/simulator-module.d.ts +3 -3
- package/dist/main/ipc/simulator-module.js +3 -7
- package/dist/main/ipc/simulator.js +1 -12
- package/dist/main/menu/index.d.ts +2 -2
- package/dist/main/menu/index.js +4 -2
- package/dist/main/runtime/miniapp-runtime.d.ts +206 -28
- package/dist/main/runtime/miniapp-runtime.js +6 -11
- package/dist/main/services/layout/index.d.ts +0 -11
- package/dist/main/services/layout/index.js +0 -23
- package/dist/main/services/notifications/renderer-notifier.d.ts +0 -6
- package/dist/main/services/notifications/renderer-notifier.js +1 -10
- package/dist/main/services/service-host-pool/pool.d.ts +5 -4
- package/dist/main/services/views/host-toolbar-port-channel.d.ts +103 -0
- package/dist/main/services/views/host-toolbar-port-channel.js +248 -0
- package/dist/main/services/views/host-toolbar-session-runtime.d.ts +35 -0
- package/dist/main/services/views/host-toolbar-session-runtime.js +55 -0
- package/dist/main/services/views/view-manager.d.ts +80 -39
- package/dist/main/services/views/view-manager.js +153 -182
- package/dist/main/services/workbench-context.d.ts +13 -26
- package/dist/main/services/workbench-context.js +5 -14
- package/dist/main/services/workspace/workspace-service.d.ts +3 -7
- package/dist/main/services/workspace/workspace-service.js +34 -13
- package/dist/main/utils/paths.d.ts +11 -2
- package/dist/main/utils/paths.js +11 -2
- package/dist/main/windows/settings-window/index.d.ts +33 -0
- package/dist/main/windows/settings-window/index.js +59 -0
- package/dist/preload/index.d.ts +15 -0
- package/dist/preload/index.js +15 -0
- package/dist/preload/runtime/host-toolbar-port.d.ts +49 -0
- package/dist/preload/runtime/host-toolbar-port.js +151 -0
- package/dist/preload/runtime/host-toolbar-runtime.d.ts +41 -0
- package/dist/preload/runtime/host-toolbar-runtime.js +49 -0
- package/dist/preload/windows/{host-toolbar.cjs → host-toolbar-runtime.cjs} +103 -3
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +7 -0
- package/dist/preload/windows/host-toolbar-runtime.d.ts +2 -0
- package/dist/preload/windows/host-toolbar-runtime.js +13 -0
- package/dist/preload/windows/simulator.cjs +0 -2
- package/dist/preload/windows/simulator.cjs.map +2 -2
- package/dist/preload/windows/simulator.js +0 -2
- package/dist/renderer/assets/constants-DI382mTP.js +2 -0
- package/dist/renderer/assets/index-DLzjz1wv.js +50 -0
- package/dist/renderer/assets/{input-CFHmbOgz.js → input-6fpCXV-n.js} +2 -2
- package/dist/renderer/assets/ipc-transport-Bs8Sf1B2.css +1 -0
- package/dist/renderer/assets/{ipc-transport-BkKKww3u.js → ipc-transport-D22e4dv7.js} +6 -6
- package/dist/renderer/assets/popover-CdGdKkkc.js +2 -0
- package/dist/renderer/assets/select-X0sbjwdP.js +2 -0
- package/dist/renderer/assets/{settings-Cl4IcWnG.js → settings-CS4jYaCw.js} +2 -2
- package/dist/renderer/assets/settings-api-CCWTAao_.js +2 -0
- package/dist/renderer/assets/workbenchSettings-Bpzaj3bm.js +8 -0
- package/dist/renderer/entries/main/index.html +7 -6
- package/dist/renderer/entries/popover/index.html +6 -6
- package/dist/renderer/entries/settings/index.html +5 -5
- package/dist/renderer/entries/workbench-settings/index.html +5 -5
- package/dist/shared/constants.d.ts +18 -0
- package/dist/shared/constants.js +18 -0
- package/dist/shared/ipc-channels.d.ts +10 -23
- package/dist/shared/ipc-channels.js +13 -34
- package/dist/shared/ipc-schemas.d.ts +0 -12
- package/dist/shared/ipc-schemas.js +0 -12
- package/dist/shared/types.d.ts +60 -76
- package/package.json +6 -6
- package/dist/main/ipc/panels.d.ts +0 -4
- package/dist/main/ipc/panels.js +0 -46
- package/dist/main/ipc/toolbar.d.ts +0 -4
- package/dist/main/ipc/toolbar.js +0 -21
- package/dist/main/services/toolbar/toolbar-store.d.ts +0 -23
- package/dist/main/services/toolbar/toolbar-store.js +0 -40
- package/dist/preload/windows/host-toolbar.cjs.map +0 -7
- package/dist/preload/windows/host-toolbar.d.ts +0 -2
- package/dist/preload/windows/host-toolbar.js +0 -12
- package/dist/renderer/assets/constants-CLAQX6VZ.js +0 -2
- package/dist/renderer/assets/index-CZQOpCvg.js +0 -50
- package/dist/renderer/assets/ipc-transport-Bv_BVu4T.css +0 -1
- package/dist/renderer/assets/popover-h1M7n3tt.js +0 -2
- package/dist/renderer/assets/select-kj0n1oYf.js +0 -2
- package/dist/renderer/assets/settings-api-CCwo2eOi.js +0 -2
- package/dist/renderer/assets/workbenchSettings-BzlpQnve.js +0 -8
package/README.md
CHANGED
|
@@ -41,7 +41,6 @@ launch({
|
|
|
41
41
|
preloadPath: '/path/to/my-preload.js',
|
|
42
42
|
rendererDir,
|
|
43
43
|
apiNamespaces: ['my'],
|
|
44
|
-
headerHeight: 72,
|
|
45
44
|
brandingProvider: () => ({ appName: '我的开发工具' }),
|
|
46
45
|
icon: '/path/to/icon.png',
|
|
47
46
|
menuBuilder: (mainWindow, menuCtx) => {
|
|
@@ -54,17 +53,6 @@ launch({
|
|
|
54
53
|
// simulator 自定义 API:per-context
|
|
55
54
|
instance.registerSimulatorApi('login', (params) => myLogin(params))
|
|
56
55
|
|
|
57
|
-
// 工具栏:整表替换,随 host 状态(如登录态)重算时再 set 一次
|
|
58
|
-
const refreshToolbar = () => {
|
|
59
|
-
const currentUser = getCurrentUser()
|
|
60
|
-
instance.toolbar.set([
|
|
61
|
-
{ id: 'account', label: '当前用户', kind: 'avatar', placement: 'leading', displayInitial: currentUser?.name, avatarUrl: currentUser?.avatar, handler: () => showAccount() },
|
|
62
|
-
{ id: 'preview', label: '预览', placement: 'primary', handler: () => preview() },
|
|
63
|
-
{ id: 'deploy', label: '发布', placement: 'trailing', handler: () => deploy() },
|
|
64
|
-
])
|
|
65
|
-
}
|
|
66
|
-
refreshToolbar()
|
|
67
|
-
|
|
68
56
|
// 自定义 IPC:经 gated 的 IpcRegistry,不再裸 ipcMain.handle
|
|
69
57
|
instance.ipc.handle('my:action', () => collectStats())
|
|
70
58
|
|
|
@@ -72,12 +60,6 @@ launch({
|
|
|
72
60
|
// const win = createDialogWindow(/* ... */)
|
|
73
61
|
// instance.registerTrustedWindow(win)
|
|
74
62
|
},
|
|
75
|
-
onBeforeOpenProject: async ({ projectPath, instance }) => {
|
|
76
|
-
const ok = await canOpenProject(projectPath)
|
|
77
|
-
return ok
|
|
78
|
-
? { allow: true }
|
|
79
|
-
: { allow: false, reason: '当前账号没有项目权限' }
|
|
80
|
-
},
|
|
81
63
|
onBeforeClose: ({ context }) => {
|
|
82
64
|
// 窗口关闭前的自定义清理;session 关闭和 view 销毁由框架自动处理
|
|
83
65
|
},
|
|
@@ -105,9 +87,7 @@ src/
|
|
|
105
87
|
lifecycle.ts # Electron app 生命周期注册
|
|
106
88
|
ipc/ # 只做 handler 注册,不写业务
|
|
107
89
|
index.ts # 聚合 register 函数导出
|
|
108
|
-
simulator.ts # simulator attach/detach
|
|
109
|
-
panels.ts # panel:list / panel:eval / selectSimulator
|
|
110
|
-
toolbar.ts # 品牌 / 工具栏配置
|
|
90
|
+
simulator.ts # simulator attach/detach/设备信息/custom-api invoke
|
|
111
91
|
popover.ts # 编译配置弹窗
|
|
112
92
|
settings.ts # 项目设置 + workbench 设置
|
|
113
93
|
projects.ts # 项目列表管理
|
|
@@ -197,11 +177,11 @@ src/
|
|
|
197
177
|
| ------------------ | -------------------- | ------------------- | ---------------------------------- |
|
|
198
178
|
| `appName` | `string` | `'Dimina DevTools'` | 窗口标题 |
|
|
199
179
|
| `adapter` | `CompilationAdapter` | 内置 | 项目编译适配器 |
|
|
200
|
-
| `panels` | `BuiltinPanelId[]` |
|
|
180
|
+
| `panels` | `BuiltinPanelId[]` | — | **已废弃,运行时忽略**:界面恒显示全部四个内置面板;保留字段仅为兼容仍传它的 host |
|
|
201
181
|
| `preloadPath` | `string` | 内置 | 统一的 host 级 preload 入口;native-host simulator(WCV)自动跑其 `.cjs` sibling(`cjsSiblingPreloadPath`) |
|
|
202
182
|
| `apiNamespaces` | `string[]` | `[]` | 自定义 API 命名空间(如 `['qd']`) |
|
|
203
183
|
| `brandingProvider` | `() => { appName }` | — | 品牌信息 provider |
|
|
204
|
-
| `headerHeight` | `number` |
|
|
184
|
+
| `headerHeight` | `number` | — | **已废弃,运行时忽略**:头部栏恒为 40px(`HEADER_H`);需要自定义工具栏请用 host toolbar WCV |
|
|
205
185
|
|
|
206
186
|
### WorkbenchAppConfig(扩展 WorkbenchConfig)
|
|
207
187
|
|
|
@@ -212,10 +192,9 @@ src/
|
|
|
212
192
|
| `modules` | `Partial<Record<BuiltinModuleId, boolean>>` | 全部 `true` | 开关内置 IPC 模块组 |
|
|
213
193
|
| `rendererDir` | `string` | 内置 | 自定义 renderer HTML 目录 |
|
|
214
194
|
| `icon` | `string` | — | 窗口/任务栏图标路径(macOS 使用 app bundle 图标) |
|
|
215
|
-
| `menuBuilder` | `(mainWindow, menuContext: MenuContext) => void` | 内置菜单 | 自定义菜单构建器;`menuContext`
|
|
216
|
-
| `onSetup` | `(instance) => void
|
|
217
|
-
| `
|
|
218
|
-
| `onBeforeClose` | `(instance) => void \| Promise<void>` | — | 窗口关闭前的回调,session 关闭由框架自动处理 |
|
|
195
|
+
| `menuBuilder` | `(mainWindow, menuContext: MenuContext) => void` | 内置菜单 | 自定义菜单构建器;`menuContext` 为手写窄契约 `MenuContext`(`appName` + workspace 窄集 + `openSettings` + `notify.{projectStatus, windowNavigateBack}`),不含内部管线 |
|
|
196
|
+
| `onSetup` | `(instance) => void` | — | 窗口和 context 创建后的回调,用于注册 Contribution(见下文)|
|
|
197
|
+
| `onBeforeClose` | `(instance) => void` | — | 窗口关闭前的回调,session 关闭由框架自动处理 |
|
|
219
198
|
| `window` | `WorkbenchWindowConfig` | — | 窗口尺寸覆盖 |
|
|
220
199
|
| `updateChecker` | `UpdateChecker` | — | 自定义更新检查器;提供后启用"检查更新"功能 |
|
|
221
200
|
| `updateOptions` | `{ checkInterval?, initialDelay?, getCurrentVersion? }` | — | 仅当 `updateChecker` 提供时生效,默认 1h / 5s |
|
|
@@ -227,12 +206,9 @@ src/
|
|
|
227
206
|
| 方法 | 说明 |
|
|
228
207
|
| --- | --- |
|
|
229
208
|
| `instance.registerSimulatorApi(name, handler)` | 注册 simulator 自定义 API,小程序里 `wx.<name>()` 调用(详见下方"Simulator 自定义 API")。返回 `Disposable` |
|
|
230
|
-
| `instance.toolbar.set(actions)` | 原子整表替换工具栏;`actions` 为 `ToolbarActionInput[]`(`{ id, label, handler }`),`id` 重复抛错。host 状态变化(如登录态)时构造新表再 `set` 一次 |
|
|
231
209
|
| `instance.ipc` | `IpcRegistry` 实例,`instance.ipc.handle(channel, fn)` 注册自定义 IPC;已绑定 `senderPolicy` 网关 |
|
|
232
210
|
| `instance.registerTrustedWindow(win)` | 把 host 自有弹窗 `BrowserWindow` 加入受信 sender 集,否则其发起的 `instance.ipc` 调用会被网关拒绝。窗口关闭即移除 |
|
|
233
211
|
|
|
234
|
-
`onSetup` 可以返回 Promise;`createWorkbenchApp().start()` 会等待 `onSetup` 解析完成后才继续后续启动流程,因此宿主在 `onSetup` 内注册的 simulator API 会早于 simulator `<webview>` 首次枚举自定义 API。
|
|
235
|
-
|
|
236
212
|
### 内置面板 ID
|
|
237
213
|
|
|
238
214
|
`'wxml'` \| `'console'` \| `'appdata'` \| `'storage'`
|
|
@@ -505,6 +481,34 @@ launch({
|
|
|
505
481
|
|
|
506
482
|
---
|
|
507
483
|
|
|
484
|
+
## Host Toolbar(宿主自定义工具栏)
|
|
485
|
+
|
|
486
|
+
下游通过 `instance.context.views.hostToolbar` 拥有 devtools 头部下方的工具栏条(一个 WebContentsView):`loadURL` / `loadFile` 加载自己的内容,`setPreloadPath` 注入自己的 preload,`setHeightMode` 钉死或自动跟随内容高度(自动模式要求内容自带 shrink-to-fit 的 `[data-host-toolbar-root]` 包裹元素;`{ fixed }` 校验入参——非有限数或负数同步抛 `TypeError` 且不污染既有模式)。
|
|
487
|
+
|
|
488
|
+
### 双向消息:onMessage / send
|
|
489
|
+
|
|
490
|
+
主进程与工具栏页面之间有一条门控窄通道(按 load 握手的 MessagePort,信封 `{ channel, payload }`):
|
|
491
|
+
|
|
492
|
+
- `hostToolbar.onMessage(channel, handler): { dispose() }` — 接收页面消息。控制面级注册:可在 view 创建前调用,且跨页面 reload 自动续接,无需重新注册。空串/非 string channel 抛错。
|
|
493
|
+
- `hostToolbar.send(channel, payload): boolean` — 发消息给页面。门控不排队:没有活的工具栏 webContents、本次 load 的握手未完成、或正处于换文档导航窗口期(`loadURL`/`loadFile` 发起后、以及页面自发的主框架跨文档导航开始后,直到新文档握手完成)时返回 `false`(不投递、不建 view);返回 `true` 即已发出。返回值本身就是就绪信号,下游不再需要拿 `getHostToolbarWebContentsId()` 手工判断工具栏是否就绪(该 API 保留)。
|
|
494
|
+
- `hostToolbar.onReady(handler): { dispose() }` — 握手完成的推送信号(每个 load generation fire 一次;已就绪后注册在微任务上补发一次,补发前复查订阅与 generation)。在 handler 内 `send()` 必然返回 `true`,可用于推送初始状态,替代轮询 retry loop。
|
|
495
|
+
|
|
496
|
+
页面侧由框架自动注入 `window.diminaHostToolbar`(仅 `{ send, onMessage }` 两个函数;类型可从根入口导入 `DiminaHostToolbarPageBridge`,并附带 optional 的 `Window` 增强。握手前的 `send` 进队列、握手后按序送达。队列上限 128 条:超限丢弃最新一条、首次超限 console.warn 一次,不抛错。`send`/`onMessage` 对空串/非 string channel 同步抛 `TypeError`,与主进程同语义):
|
|
497
|
+
|
|
498
|
+
```js
|
|
499
|
+
// 工具栏页面内
|
|
500
|
+
window.diminaHostToolbar.onMessage('host:cmd', (payload) => { /* ... */ })
|
|
501
|
+
window.diminaHostToolbar.send('page:event', { clicked: 'compile' })
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
```ts
|
|
505
|
+
// 主进程(onSetup 内)
|
|
506
|
+
const sub = instance.context.views.hostToolbar.onMessage('page:event', (payload) => { /* ... */ })
|
|
507
|
+
instance.context.views.hostToolbar.send('host:cmd', { theme: 'dark' }) // false = 未送达
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
508
512
|
## 模块导出一览
|
|
509
513
|
|
|
510
514
|
`@dimina-kit/devtools` 的公共入口。`api.ts`(根入口)聚合了所有公共 API,优先从根入口导入。
|
|
@@ -512,14 +516,15 @@ launch({
|
|
|
512
516
|
```
|
|
513
517
|
@dimina-kit/devtools launch, buildDefaultMenu,
|
|
514
518
|
openSettingsWindow, suppressEpipe, setupCdpPort,
|
|
519
|
+
asMiniappRuntime, MiniappRuntime / MiniappSessionAppInfo /
|
|
520
|
+
DiminaHostToolbarPageBridge(type),
|
|
515
521
|
createWorkbenchContext, createMainWindow,
|
|
516
522
|
createViewManager, IpcRegistry,
|
|
517
523
|
UpdateManager, createGitHubReleaseChecker, ...
|
|
518
524
|
@dimina-kit/devtools/launch launch(config?), buildDefaultMenu, openSettingsWindow
|
|
519
525
|
@dimina-kit/devtools/types TypeScript 类型定义
|
|
520
526
|
@dimina-kit/devtools/bootstrap suppressEpipe(), setupCdpPort()
|
|
521
|
-
@dimina-kit/devtools/context createWorkbenchContext(opts)
|
|
522
|
-
hasBuiltinPanel(ctx, panelId), getDefaultTab(ctx)
|
|
527
|
+
@dimina-kit/devtools/context createWorkbenchContext(opts)
|
|
523
528
|
@dimina-kit/devtools/create-window createMainWindow(opts)
|
|
524
529
|
@dimina-kit/devtools/paths rendererDir, defaultPreloadPath, simulatorDir,
|
|
525
530
|
getRendererDir, getPreloadDir, getRendererHtml
|
|
@@ -540,19 +545,32 @@ launch({
|
|
|
540
545
|
|
|
541
546
|
---
|
|
542
547
|
|
|
548
|
+
## MiniappRuntime(宿主集成推荐契约)
|
|
549
|
+
|
|
550
|
+
下游宿主(如 qdmp)集成时,推荐依赖手写的稳定契约 `MiniappRuntime`,而不是整个 `WorkbenchContext`——后者携带全部内部 service 类型,内部重构会直接破坏下游编译。`asMiniappRuntime(ctx)` 恒等返回(typed view,非拷贝),宿主对 `runtime.workspace.openProject` 的 monkey-patch 会落在真实对象上:
|
|
551
|
+
|
|
552
|
+
```typescript
|
|
553
|
+
import { asMiniappRuntime, type MiniappRuntime } from '@dimina-kit/devtools'
|
|
554
|
+
|
|
555
|
+
const runtime: MiniappRuntime = asMiniappRuntime(instance.context)
|
|
556
|
+
runtime.workspace.openProject = gated(runtime.workspace.openProject) // 权限闸(契约保证可写)
|
|
557
|
+
runtime.views.hostToolbar.send('host:cmd', { theme: 'dark' })
|
|
558
|
+
runtime.notify.projectStatus({ status: 'ready', message: '编译完成' })
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
契约面:`views.hostToolbar`(7 成员,含 `onReady`,无 `webContents`)/ `workspace`(7 方法,`getSession().appInfo` 为结构化 `MiniappSessionAppInfo`,`appId` 必有)/ `notify.projectStatus` / `registry.add`(接受 `{ dispose }` 对象或裸函数两种习语)/ `openSettings()`。零 Electron 类型。0.4.0 起不再含 `rendererDir`(用 `/paths` 导出)与 `windows`(用 `openSettings()`)。
|
|
562
|
+
|
|
543
563
|
## WorkbenchContext
|
|
544
564
|
|
|
545
|
-
`WorkbenchContext` 是所有扩展点的唯一容器。配置字段直接暴露,运行时状态通过 service 访问。host hook 拿到的 `instance.context` 即此类型;`menuBuilder`
|
|
565
|
+
`WorkbenchContext` 是所有扩展点的唯一容器。配置字段直接暴露,运行时状态通过 service 访问。host hook 拿到的 `instance.context` 即此类型;`menuBuilder` 拿到的是手写窄契约 `MenuContext`(`appName` + workspace 窄集 + `openSettings` + `notify.{projectStatus, windowNavigateBack}`,不再是 `WorkbenchContext` 的 Omit 投影)。
|
|
546
566
|
|
|
547
567
|
```typescript
|
|
548
568
|
interface WorkbenchContext {
|
|
549
569
|
adapter: CompilationAdapter
|
|
550
570
|
preloadPath: string
|
|
551
571
|
rendererDir: string
|
|
552
|
-
panels: string[]
|
|
553
572
|
apiNamespaces: string[]
|
|
554
573
|
appName: string
|
|
555
|
-
headerHeight: number
|
|
556
574
|
brandingProvider?: () => Promise<{ appName: string }> | { appName: string }
|
|
557
575
|
|
|
558
576
|
// ── Services(运行时状态封装在内部,通过方法访问)──
|
|
@@ -563,7 +581,6 @@ interface WorkbenchContext {
|
|
|
563
581
|
|
|
564
582
|
// ── 扩展容器(host 通过 instance 上的方法写入,不直接操作)──
|
|
565
583
|
simulatorApis: SimulatorApiRegistry // instance.registerSimulatorApi 写入
|
|
566
|
-
toolbar: ToolbarStore // instance.toolbar.set 写入
|
|
567
584
|
trustedWindowSenderIds: Map<number, number> // instance.registerTrustedWindow 写入(webContents.id → 引用计数)
|
|
568
585
|
|
|
569
586
|
// ── Internal lifecycle / security (host 不直接消费) ──
|
|
@@ -575,7 +592,7 @@ interface WorkbenchContext {
|
|
|
575
592
|
会话和视图状态封装在对应 service 的私有闭包中,通过方法访问,例如:
|
|
576
593
|
|
|
577
594
|
- `ctx.workspace.getProjectPath()` / `ctx.workspace.getSession()` / `ctx.workspace.hasActiveSession()`
|
|
578
|
-
- `ctx.views.getSimulatorWebContentsId()` / `ctx.views.
|
|
595
|
+
- `ctx.views.getSimulatorWebContentsId()` / `ctx.views.getSimulatorWebContents()`
|
|
579
596
|
- `ctx.windows.mainWindow` / `ctx.windows.settingsWindow`
|
|
580
597
|
|
|
581
598
|
---
|
|
@@ -617,13 +634,11 @@ flowchart TB
|
|
|
617
634
|
| Storage | 拉取 + 推送 | renderer `ipcInvoke(SimulatorStorageChannel.GetSnapshot)` → 主进程 CDP `DOMStorage` 域;变更事件由主进程通过 `SimulatorStorageChannel.Event` 推回 renderer |
|
|
618
635
|
| 元素选区 / `Page.getData` / MCP overview | 拉取 | 主进程 `webContents.executeJavaScript(...)` 或 `Runtime.evaluate(...)` 读 `window.__simulatorData.*`(由 `installSimulatorBridge` 暴露) |
|
|
619
636
|
|
|
620
|
-
> `src/main/ipc/panels.ts` 暴露 `panel:eval` handler 供外部 host 自定义面板复用,内置 renderer 不消费它。
|
|
621
|
-
|
|
622
637
|
---
|
|
623
638
|
|
|
624
639
|
## IPC 通信总览
|
|
625
640
|
|
|
626
|
-
IPC 频道名常量集中定义在 `src/shared/ipc-channels.ts`,按域分组(`SimulatorChannel` / `ProjectChannel` / `
|
|
641
|
+
IPC 频道名常量集中定义在 `src/shared/ipc-channels.ts`,按域分组(`SimulatorChannel` / `ProjectChannel` / `WorkbenchSettingsChannel` 等)。该文件是频道清单的唯一真相源;此处不再维护手抄表,以免与代码漂移。
|
|
627
642
|
|
|
628
643
|
---
|
|
629
644
|
|
|
@@ -633,7 +648,7 @@ Electron 对 `chrome.devtools.panels.create()` 的支持**长期不稳定**。
|
|
|
633
648
|
|
|
634
649
|
**影响范围**:从 Electron 7 到 39 均有报告([#23662](https://github.com/electron/electron/issues/23662)、[#41613](https://github.com/electron/electron/issues/41613)、[#48705](https://github.com/electron/electron/issues/48705)),非特定版本 bug,而是系统性实现缺陷。官方文档声称完全支持,但实际因竞态条件和实现不完整导致面板无法可靠渲染。Electron 团队无修复计划。
|
|
635
650
|
|
|
636
|
-
**当前方案**:内置面板(WXML / AppData / Storage)直接在主窗口 React 中渲染,数据由主进程服务直接供给——WXML / AppData 走 `SimulatorWxmlChannel` / `SimulatorAppDataChannel`(main → renderer 的 seed `GetSnapshot` + push `Event`),Storage 走 CDP `DOMStorage` 域(详见上方「数据流」);Chrome DevTools 仍作为独立 `WebContentsView` 通过 `setDevToolsWebContents()` 挂载。面板切换由 renderer toolbar 的 tab 栏控制,主进程负责 nativeSimulator/settings/popover View 的创建、定位和显隐。详见 `src/main/ipc/
|
|
651
|
+
**当前方案**:内置面板(WXML / AppData / Storage)直接在主窗口 React 中渲染,数据由主进程服务直接供给——WXML / AppData 走 `SimulatorWxmlChannel` / `SimulatorAppDataChannel`(main → renderer 的 seed `GetSnapshot` + push `Event`),Storage 走 CDP `DOMStorage` 域(详见上方「数据流」);Chrome DevTools 仍作为独立 `WebContentsView` 通过 `setDevToolsWebContents()` 挂载。面板切换由 renderer toolbar 的 tab 栏控制,主进程负责 nativeSimulator/settings/popover View 的创建、定位和显隐。详见 `src/main/ipc/simulator.ts`。
|
|
637
652
|
|
|
638
653
|
---
|
|
639
654
|
|
package/dist/main/api.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { launch, buildDefaultMenu, openSettingsWindow } from './app/launch.js';
|
|
2
2
|
export type { WorkbenchAppInstance } from './app/app.js';
|
|
3
3
|
export { suppressEpipe, setupCdpPort } from './app/bootstrap.js';
|
|
4
|
-
export {
|
|
4
|
+
export { asMiniappRuntime } from './runtime/miniapp-runtime.js';
|
|
5
|
+
export type { MiniappRuntime, MiniappSessionAppInfo, DiminaHostToolbarPageBridge, } from './runtime/miniapp-runtime.js';
|
|
6
|
+
export { createWorkbenchContext } from './services/workbench-context.js';
|
|
5
7
|
export type { WorkbenchContext, CreateContextOptions } from './services/workbench-context.js';
|
|
6
8
|
export { createMainWindow } from './windows/main-window/index.js';
|
|
7
9
|
export { createViewManager } from './services/views/view-manager.js';
|
|
@@ -14,5 +16,5 @@ export { IpcRegistry } from './utils/ipc-registry.js';
|
|
|
14
16
|
export type { SenderPolicy } from './utils/ipc-registry.js';
|
|
15
17
|
export { UpdateManager, createGitHubReleaseChecker } from './services/update/index.js';
|
|
16
18
|
export type { UpdateManagerOptions, GitHubReleaseCheckerOptions, PickAssetContext, VersionScheme, } from './services/update/index.js';
|
|
17
|
-
export type {
|
|
19
|
+
export type { WorkbenchConfig, WorkbenchAppConfig, CompilationAdapter, ProjectSession, BuiltinPanelId, BuiltinModuleId, UpdateChecker, UpdateInfo, } from '../shared/types.js';
|
|
18
20
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/main/api.js
CHANGED
|
@@ -7,8 +7,12 @@
|
|
|
7
7
|
export { launch, buildDefaultMenu, openSettingsWindow } from './app/launch.js';
|
|
8
8
|
// ── Bootstrap utilities ──────────────────────────────────────────────────
|
|
9
9
|
export { suppressEpipe, setupCdpPort } from './app/bootstrap.js';
|
|
10
|
+
// ── Miniapp runtime contract (host-facing, stable) ───────────────────────
|
|
11
|
+
// The hand-written kernel surface a downstream host consumes; prefer this
|
|
12
|
+
// over depending on the full `WorkbenchContext`.
|
|
13
|
+
export { asMiniappRuntime } from './runtime/miniapp-runtime.js';
|
|
10
14
|
// ── Context & views (for module-assembly consumers) ──────────────────────
|
|
11
|
-
export { createWorkbenchContext
|
|
15
|
+
export { createWorkbenchContext } from './services/workbench-context.js';
|
|
12
16
|
export { createMainWindow } from './windows/main-window/index.js';
|
|
13
17
|
export { createViewManager } from './services/views/view-manager.js';
|
|
14
18
|
// ── Paths ────────────────────────────────────────────────────────────────
|
package/dist/main/app/app.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BrowserWindow } from 'electron';
|
|
2
|
-
import type {
|
|
2
|
+
import type { WorkbenchAppConfig } from '../../shared/types.js';
|
|
3
3
|
import type { SimulatorApiHandler } from '../services/simulator/custom-apis.js';
|
|
4
4
|
import { type WorkbenchContext } from '../services/workbench-context.js';
|
|
5
5
|
import { type AutomationServer } from '../services/automation/index.js';
|
|
@@ -15,10 +15,6 @@ export interface WorkbenchAppInstance {
|
|
|
15
15
|
registerTrustedWindow: (win: BrowserWindow) => Disposable;
|
|
16
16
|
/** Registers a simulator custom API into this context's registry. */
|
|
17
17
|
registerSimulatorApi: (name: string, handler: SimulatorApiHandler) => Disposable;
|
|
18
|
-
/** Per-context toolbar surface — `set()` atomically replaces the table. */
|
|
19
|
-
readonly toolbar: {
|
|
20
|
-
set(actions: ToolbarActionInput[]): void;
|
|
21
|
-
};
|
|
22
18
|
automationServer?: AutomationServer;
|
|
23
19
|
updateManager?: UpdateManager;
|
|
24
20
|
dispose: () => Promise<void>;
|
package/dist/main/app/app.js
CHANGED
|
@@ -6,6 +6,7 @@ import path from 'path';
|
|
|
6
6
|
import { rendererDir as defaultRendererDir, defaultPreloadPath } from '../utils/paths.js';
|
|
7
7
|
import { installThemeBackgroundSync } from '../utils/theme.js';
|
|
8
8
|
import { createMainWindow, wireMainWindowEvents } from '../windows/main-window/index.js';
|
|
9
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered(workbench-context): shrink-only
|
|
9
10
|
import { createWorkbenchContext } from '../services/workbench-context.js';
|
|
10
11
|
import { loadWorkbenchSettings, applyTheme } from '../services/settings/index.js';
|
|
11
12
|
import { installAppMenu } from '../menu/index.js';
|
|
@@ -145,10 +146,8 @@ function createContext(config, mainWindow, rendererDir) {
|
|
|
145
146
|
adapter: config.adapter,
|
|
146
147
|
preloadPath: config.preloadPath ?? defaultPreloadPath,
|
|
147
148
|
rendererDir,
|
|
148
|
-
panels: config.panels,
|
|
149
149
|
appName: config.appName,
|
|
150
150
|
apiNamespaces: config.apiNamespaces,
|
|
151
|
-
headerHeight: config.headerHeight,
|
|
152
151
|
brandingProvider: config.brandingProvider,
|
|
153
152
|
// The host-supplied ProjectsProvider / template types in `shared/types`
|
|
154
153
|
// are structurally compatible with the main-process equivalents —
|
|
@@ -168,21 +167,29 @@ function registerBuiltinModules(config, context) {
|
|
|
168
167
|
});
|
|
169
168
|
}
|
|
170
169
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
170
|
+
* Build the hand-written narrow `MenuContext` a host menu builder receives —
|
|
171
|
+
* explicit construction (not clone+delete), so the runtime object carries
|
|
172
|
+
* EXACTLY the contract members and nothing else. Every member is a lazy
|
|
173
|
+
* closure over the live context: a host monkey-patch of
|
|
174
|
+
* `context.workspace.openProject` (the documented permission-gate pattern)
|
|
175
|
+
* still intercepts calls made through this menu surface.
|
|
175
176
|
*/
|
|
176
177
|
function toMenuContext(context) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
178
|
+
return {
|
|
179
|
+
appName: context.appName,
|
|
180
|
+
workspace: {
|
|
181
|
+
hasActiveSession: () => context.workspace.hasActiveSession(),
|
|
182
|
+
getProjectPath: () => context.workspace.getProjectPath(),
|
|
183
|
+
openProject: (projectPath) => context.workspace.openProject(projectPath),
|
|
184
|
+
closeProject: () => context.workspace.closeProject(),
|
|
185
|
+
getSession: () => context.workspace.getSession(),
|
|
186
|
+
},
|
|
187
|
+
openSettings: () => context.openSettings(),
|
|
188
|
+
notify: {
|
|
189
|
+
projectStatus: (payload) => context.notify.projectStatus(payload),
|
|
190
|
+
windowNavigateBack: () => context.notify.windowNavigateBack(),
|
|
191
|
+
},
|
|
192
|
+
};
|
|
186
193
|
}
|
|
187
194
|
function installMenu(config, mainWindow, context) {
|
|
188
195
|
// Menu: use host-provided builder or fall back to default
|
|
@@ -345,20 +352,8 @@ export async function createDevtoolsRuntime(config = {}) {
|
|
|
345
352
|
// teardown, so a single dispose leaves no dead entry behind.
|
|
346
353
|
registerTrustedWindow: (win) => context.registry.add(registerTrustedWindow(context, win)),
|
|
347
354
|
registerSimulatorApi: (name, handler) => context.registry.add(toDisposable(context.simulatorApis.register(name, handler))),
|
|
348
|
-
toolbar: {
|
|
349
|
-
set: (actions) => {
|
|
350
|
-
// `context.toolbar.set` validates id-uniqueness and throws on a
|
|
351
|
-
// duplicate BEFORE mutating, so a rejected batch never reaches
|
|
352
|
-
// the notify below — no phantom ActionsChanged.
|
|
353
|
-
context.toolbar.set(actions);
|
|
354
|
-
context.notify.toolbarActionsChanged();
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
355
|
dispose: () => disposeContext(context),
|
|
358
356
|
};
|
|
359
|
-
if (config.onBeforeOpenProject) {
|
|
360
|
-
context.beforeOpenProject = (projectPath) => config.onBeforeOpenProject({ projectPath, instance });
|
|
361
|
-
}
|
|
362
357
|
if (config.onSetup) {
|
|
363
358
|
await config.onSetup(instance);
|
|
364
359
|
}
|
|
@@ -473,9 +468,9 @@ export async function createDevtoolsRuntime(config = {}) {
|
|
|
473
468
|
// upload run there, not in the service host) in the embedded DevTools by
|
|
474
469
|
// injecting its raw Network.* CDP events into the DevTools front-end so the
|
|
475
470
|
// native Network tab renders them (service-host console line is the
|
|
476
|
-
// fallback). The ViewManager calls attachSimulator +
|
|
477
|
-
// attachNativeSimulator once the simulator WCV +
|
|
478
|
-
// getServiceWc here is the fallback sink target.
|
|
471
|
+
// fallback). The ViewManager calls the forwarder's attachSimulator +
|
|
472
|
+
// setDevtoolsHost from attachNativeSimulator once the simulator WCV +
|
|
473
|
+
// DevTools host exist; getServiceWc here is the fallback sink target.
|
|
479
474
|
const networkForward = createNetworkForwarder({
|
|
480
475
|
getServiceWc: (appId) => context.bridge?.getServiceWc(appId) ?? null,
|
|
481
476
|
connections: context.connections,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { WorkbenchAppConfig } from '../../shared/types.js';
|
|
2
|
-
import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
1
|
+
import type { MenuContext, WorkbenchAppConfig } from '../../shared/types.js';
|
|
3
2
|
/**
|
|
4
3
|
* Host-shell entry for the devtools app. Boots through the
|
|
5
4
|
* `@dimina-kit/electron-deck` framework orchestrator (process lifecycle gate +
|
|
@@ -9,6 +8,7 @@ import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
|
9
8
|
* passing `WorkbenchAppConfig` (incl. `onSetup`, `apiNamespaces`, `menuBuilder`, …).
|
|
10
9
|
*/
|
|
11
10
|
export declare function launch(config?: WorkbenchAppConfig): Promise<void>;
|
|
12
|
-
export declare function buildDefaultMenu(ctx:
|
|
13
|
-
export
|
|
11
|
+
export declare function buildDefaultMenu(ctx: MenuContext): void;
|
|
12
|
+
export { openSettingsWindow } from '../windows/settings-window/index.js';
|
|
13
|
+
export type { OpenSettingsWindowDeps } from '../windows/settings-window/index.js';
|
|
14
14
|
//# sourceMappingURL=launch.d.ts.map
|
package/dist/main/app/launch.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { electronDeck as frameworkElectronDeck } from '@dimina-kit/electron-deck';
|
|
2
2
|
import { createDevtoolsBackend } from '../runtime/devtools-backend.js';
|
|
3
3
|
import { installAppMenu } from '../menu/index.js';
|
|
4
|
-
import { createSettingsWindow, wireSettingsWindowEvents } from '../windows/settings-window/index.js';
|
|
5
|
-
import { loadWorkbenchSettings } from '../services/settings/index.js';
|
|
6
4
|
/**
|
|
7
5
|
* Host-shell entry for the devtools app. Boots through the
|
|
8
6
|
* `@dimina-kit/electron-deck` framework orchestrator (process lifecycle gate +
|
|
@@ -17,19 +15,9 @@ export function launch(config = {}) {
|
|
|
17
15
|
export function buildDefaultMenu(ctx) {
|
|
18
16
|
installAppMenu(ctx);
|
|
19
17
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
wireSettingsWindowEvents(win, () => {
|
|
26
|
-
ctx.windows.setSettingsWindow(null);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
win.show();
|
|
30
|
-
win.focus();
|
|
31
|
-
ctx.notify.workbenchSettingsInit(win, {
|
|
32
|
-
settings: loadWorkbenchSettings(),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
18
|
+
// The implementation lives with the settings-window domain module and takes
|
|
19
|
+
// its own narrow `OpenSettingsWindowDeps` (a full WorkbenchContext satisfies
|
|
20
|
+
// it structurally). Re-exported here so the public barrel path is unchanged.
|
|
21
|
+
// Contract holders should prefer `ctx.openSettings()` / `runtime.openSettings()`.
|
|
22
|
+
export { openSettingsWindow } from '../windows/settings-window/index.js';
|
|
35
23
|
//# sourceMappingURL=launch.js.map
|