@dimina-kit/devtools 0.3.1-dev.20260515105504 → 0.3.1-dev.20260517100756

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 CHANGED
@@ -83,6 +83,7 @@ import { app, globalShortcut } from 'electron'
83
83
  import path from 'path'
84
84
  import { createMainWindow } from '@dimina-kit/devtools/create-window'
85
85
  import { createWorkbenchContext } from '@dimina-kit/devtools/context'
86
+ import { registerAppIpc } from '@dimina-kit/devtools'
86
87
  import { registerSimulatorIpc } from '@dimina-kit/devtools/ipc-simulator'
87
88
  import { registerPanelsIpc } from '@dimina-kit/devtools/ipc-panels'
88
89
  import { registerToolbarIpc } from '@dimina-kit/devtools/ipc-toolbar'
@@ -95,7 +96,7 @@ import { rendererDir, defaultPreloadPath } from '@dimina-kit/devtools/paths'
95
96
  app.whenReady().then(() => {
96
97
  const mainWindow = createMainWindow({
97
98
  title: 'My DevTools',
98
- indexHtml: path.join(rendererDir, 'index.html'),
99
+ indexHtml: path.join(rendererDir, 'entries/main/index.html'),
99
100
  })
100
101
 
101
102
  const ctx = createWorkbenchContext({
@@ -105,6 +106,9 @@ app.whenReady().then(() => {
105
106
  rendererDir,
106
107
  })
107
108
 
109
+ // registerAppIpc 必装:renderer 启动时调用 app:getPreloadPath / app:getBranding,
110
+ // 缺它会卡在加载阶段。
111
+ registerAppIpc(ctx)
108
112
  registerProjectsIpc(ctx)
109
113
  registerSessionIpc(ctx)
110
114
  registerSimulatorIpc(ctx)
@@ -112,6 +116,11 @@ app.whenReady().then(() => {
112
116
  registerToolbarIpc(ctx)
113
117
  registerPopoverIpc(ctx)
114
118
 
119
+ // Storage / 元素选区面板的后端 handler 由 setupSimulatorStorage 单独装。
120
+ // 该函数当前**未列入稳定公共 API**(在 `@dimina-kit/devtools` 之外)。
121
+ // 若需要这两个面板,建议改用上方的 `createWorkbenchApp({ onSetup })` 路线,
122
+ // 框架会自动注册;模块组装路线下你只能用不依赖它们的精简面板集。
123
+
115
124
  // 添加自定义 IPC — 通过 ctx.workspace 访问会话状态
116
125
  ipcMain.handle('my:action', () => {
117
126
  console.log('current project:', ctx.workspace.getProjectPath())
@@ -197,19 +206,20 @@ src/
197
206
  types.ts
198
207
  instrumentation/ # 注入到小程序 runtime 的探针
199
208
  console.ts # 控制台拦截
200
- storage.ts # localStorage 拦截
201
209
  app-data.ts # Worker setData 拦截
202
- wxml.ts # Vue 组件树提取
210
+ wxml.ts # Vue 组件树提取 + WXML 高亮 overlay
211
+ disposable.ts # instrumentation 共用的清理工具
203
212
  runtime/
204
- bridge.ts # installSimulatorBridge
205
- host.ts
213
+ bridge.ts # installSimulatorBridge → window.__simulatorData
214
+ custom-apis.ts # installCustomApisBridge → window.__diminaCustomApis
215
+ host.ts # sendToHost 推送封装
206
216
 
207
217
  renderer/
208
218
  entries/ # 各窗口 HTML + React 挂载点
209
219
  main/ popover/ settings/ workbench-settings/
210
220
  modules/ # 先按窗口分,再按区域
211
221
  main/
212
- app/ # 主窗口 App
222
+ main.tsx # 主窗口 React
213
223
  features/ # 主窗口内的业务区域
214
224
  project-runtime/ # 项目视图 + 工具栏 + 右侧面板切换
215
225
  right-panel/ # WXML / AppData / Storage 面板
@@ -261,6 +271,8 @@ src/
261
271
  | `onSetup` | `(instance) => void` | — | 窗口和 context 创建后的回调,用于注册自定义 IPC |
262
272
  | `onBeforeClose` | `(instance) => void` | — | 窗口关闭前的回调,session 关闭由框架自动处理 |
263
273
  | `window` | `WorkbenchWindowConfig` | — | 窗口尺寸覆盖 |
274
+ | `updateChecker` | `UpdateChecker` | — | 自定义更新检查器;提供后启用"检查更新"功能 |
275
+ | `updateOptions` | `{ checkInterval?, initialDelay?, getCurrentVersion? }` | — | 仅当 `updateChecker` 提供时生效,默认 1h / 5s |
264
276
 
265
277
  ### 内置面板 ID
266
278
 
@@ -298,37 +310,56 @@ const myAdapter: CompilationAdapter = {
298
310
 
299
311
  ## Preload Instrumentation
300
312
 
301
- 模拟器 webview 注入 preload 脚本在全局安装 instrumentation。内置 preload(`preload/windows/simulator.ts`)组装了以下模块:
313
+ 模拟器 webview 注入 preload 脚本,在 webview 全局上安装两类东西:**桥接**(把数据通道暴露到 webview)+ **instrumentation**(监听运行时事件并写入桥接)。内置 preload 见 `src/preload/windows/simulator.ts`。
314
+
315
+ ### 必装:桥接
316
+
317
+ | 函数 | 作用 | 不装会怎样 |
318
+ | --- | --- | --- |
319
+ | `installSimulatorBridge()` | 暴露 `window.__simulatorData`,承载 `highlightElement` / `unhighlightElement` / `getAppdata` / `getWxml` / `getStorageSnapshot` 等只读 API(供主进程 `executeJavaScript` 拉取) | 元素选区 overlay 不显示;automation `Page.getData` 返回空对象;MCP `simulator_get_overview` 在 hints 中追加 `simulator bridge not ready (window.__simulatorData missing)`。注:Storage 面板走主进程 CDP,不受影响;Console/AppData/WXML 推送走 `sendToHost`,也不受影响 |
320
+ | `installCustomApisBridge()` | 暴露 `window.__diminaCustomApis`,承载 `list` / `invoke`,让模拟器侧把主进程注册的 API 代理回小程序 runtime | `registerSimulatorApi` 注册的业务 API 在小程序里调用全部 no-op(参见下方 "Simulator 自定义 API") |
321
+ | `setupApiCompatHook()` | 兼容上游 API 名称变更 | 部分 API 调用兼容性问题 |
322
+
323
+ 下游写自定义 preload 时,这三项原则上都要装。若不需要 `registerSimulatorApi`,`installCustomApisBridge` 可省略。
324
+
325
+ ### 按需:instrumentation
326
+
327
+ | Instrumentation | 捕获内容 | 数据通道 |
328
+ | --- | --- | --- |
329
+ | `installConsoleInstrumentation` | `console.*`、`window.onerror`、未捕获 rejection | IPC sendToHost |
330
+ | `installAppDataInstrumentation` | Worker `type='u'` 消息、setData 调用 | IPC sendToHost + 写入 bridge state |
331
+ | `installWxmlInstrumentation` | Vue 组件树提取、MutationObserver 自动更新 | IPC sendToHost + 写入 bridge state |
302
332
 
303
- | Instrumentation | 捕获内容 |
304
- | ----------------------------------------- | ----------------------------------------------- |
305
- | Console (`installConsoleInstrumentation`) | `console.*`、`window.onerror`、未捕获 rejection |
306
- | Storage (`installStorageInstrumentation`) | `localStorage.setItem/removeItem`、全量快照 |
307
- | AppData (`installAppDataInstrumentation`) | Worker `type='u'` 消息、setData 调用 |
308
- | WXML (`installWxmlInstrumentation`) | Vue 组件树提取、MutationObserver 自动更新 |
333
+ > Storage 面板的数据由主进程通过 CDP `DOMStorage` 域抓取(`src/main/services/simulator-storage`),**不需要 preload 侧 instrumentation**。
309
334
 
310
- 所有 install\* 函数从 `@dimina-kit/devtools/preload` 统一导出,调用后通过 `installSimulatorBridge` 暴露的内部桥接通道把数据推到宿主。面板打开时调用 `panel:eval` 通过 `executeJavaScript` 拉取当前状态。
335
+ 各面板的数据流详见下方 "数据流" 章节。
311
336
 
312
337
  ### 自定义 Preload
313
338
 
314
- 按需组合或追加自定义逻辑(`src/preload/windows/simulator.ts` 作为参考):
339
+ 参考 `src/preload/windows/simulator.ts`:
315
340
 
316
341
  ```typescript
317
342
  // my-preload.ts
318
343
  import {
319
344
  installSimulatorBridge,
345
+ installCustomApisBridge,
320
346
  installConsoleInstrumentation,
321
- installStorageInstrumentation,
347
+ installAppDataInstrumentation,
348
+ installWxmlInstrumentation,
322
349
  setupApiCompatHook,
323
350
  } from '@dimina-kit/devtools/preload'
324
- // 不需要 WXML/AppData,不导入
325
351
 
352
+ // 1. 兼容 hook + 桥接(必装,且应在 instrumentation 之前)
326
353
  setupApiCompatHook()
327
354
  installSimulatorBridge()
355
+ installCustomApisBridge() // 若用到 registerSimulatorApi,必装
356
+
357
+ // 2. instrumentation(按需)
328
358
  installConsoleInstrumentation()
329
- installStorageInstrumentation()
359
+ installAppDataInstrumentation()
360
+ installWxmlInstrumentation()
330
361
 
331
- // 自定义 hook
362
+ // 3. 自定义 hook
332
363
  window.addEventListener('error', (e) => {
333
364
  console.error('[my-preload]', e.message)
334
365
  })
@@ -346,6 +377,8 @@ launch({ preloadPath: '/absolute/path/to/my-preload.js' })
346
377
 
347
378
  下游可以通过 `registerSimulatorApi` 把业务 API 注入到模拟器内运行的小程序。Handler 在 Electron **主进程**执行,能用任何 Node 能力(fs、net、原生模块、持久状态);模拟器侧拿到 `wx.<name>(params)` 调用后通过 IPC 转发到主进程,await 返回结果,handler 抛错则原型回传给小程序。
348
379
 
380
+ > ⚠️ 使用本功能要求模拟器 preload 调用 `installCustomApisBridge()`(详见上方 "Preload Instrumentation")。内置 preload 已包含此调用;若你用了自定义 preload 又忘记调用,注册的 API 在小程序运行时**没有任何反应**,且不会报错。
381
+
349
382
  ```typescript
350
383
  import { registerSimulatorApi } from '@dimina-kit/devtools/simulator-apis'
351
384
 
@@ -392,12 +425,14 @@ dispose()
392
425
  getRendererDir, getPreloadDir, getRendererHtml
393
426
  @dimina-kit/devtools/simulator-apis registerSimulatorApi(name, handler) →
394
427
  注入由主进程托管的小程序 API(详见上方"Simulator 自定义 API")
395
- @dimina-kit/devtools/preload installConsoleInstrumentation,
396
- installStorageInstrumentation,
428
+ @dimina-kit/devtools/preload installSimulatorBridge,
429
+ installCustomApisBridge,
430
+ installConsoleInstrumentation,
397
431
  installAppDataInstrumentation, sendAllAppData,
398
432
  installWxmlInstrumentation, sendWxmlTree,
399
- setupWxmlObserver, installSimulatorBridge,
433
+ setupWxmlObserver,
400
434
  setupApiCompatHook
435
+ (storage 面板数据由主进程 CDP 抓取,无 preload 侧 hook)
401
436
  ```
402
437
 
403
438
  ### Experimental exports (v0.x — signatures may change in minor versions)
@@ -414,18 +449,10 @@ dispose()
414
449
  @dimina-kit/devtools/ipc-popover registerPopoverIpc(ctx)
415
450
  @dimina-kit/devtools/ipc-settings registerSettingsIpc(ctx)
416
451
  @dimina-kit/devtools/ipc-projects registerProjectsIpc(ctx)
417
- @dimina-kit/devtools/ipc-session registerSessionIpc(ctx), sendStatus(ctx, status, msg)
452
+ @dimina-kit/devtools/ipc-session registerSessionIpc(ctx), sessionModule
418
453
  @dimina-kit/devtools/workbench-settings loadWorkbenchSettings(), saveWorkbenchSettings(), applyTheme()
419
454
  ```
420
455
 
421
- > 注:以下子路径在过去版本曾被导出,已收敛到根 barrel 或内部实现,请改从 `@dimina-kit/devtools` 根入口导入(`createViewManager`、`registerAppIpc`、`simulatorDir`、`Project` 等类型):
422
- >
423
- > - `@dimina-kit/devtools/view-manager` → `import { createViewManager, type ViewManager } from '@dimina-kit/devtools'`
424
- > - `@dimina-kit/devtools/ipc-app` → `import { registerAppIpc } from '@dimina-kit/devtools'`
425
- > - `@dimina-kit/devtools/projects` → 通过 `ctx.workspace.listProjects()` 等服务方法访问;`Project` 类型从 `@dimina-kit/devtools` 根入口导入
426
- > - `@dimina-kit/devtools/layout` → `import { setHeaderHeight } from '@dimina-kit/devtools'`(其余布局细节回归内部实现)
427
- > - `@dimina-kit/devtools/simulator-dir` → `import { simulatorDir } from '@dimina-kit/devtools/paths'`
428
-
429
456
  ---
430
457
 
431
458
  ## WorkbenchContext
@@ -452,15 +479,10 @@ interface WorkbenchContext {
452
479
  // ── Internal lifecycle / security (host 不直接消费) ──
453
480
  registry: DisposableRegistry // 框架在创建时统一聚合 dispose
454
481
  senderPolicy: SenderPolicy // IpcRegistry 自动校验 sender 白名单
455
-
456
- /** @deprecated 用 ctx.windows.mainWindow */
457
- mainWindow: BrowserWindow
458
- /** @deprecated 用 ctx.windows.settingsWindow / setSettingsWindow */
459
- workbenchSettingsWindow: BrowserWindow | null
460
482
  }
461
483
  ```
462
484
 
463
- 会话和视图状态不再作为 ctx 的直接字段暴露,而是封装在对应 service 的私有闭包中:
485
+ 会话和视图状态封装在对应 service 的私有闭包中,通过方法访问:
464
486
 
465
487
  | 旧写法 | 新写法 |
466
488
  | ---------------------------- | ----------------------------------------------------------------- |
@@ -500,28 +522,15 @@ flowchart TB
500
522
 
501
523
  ### 数据流
502
524
 
503
- 内置面板采用**拉取式**数据流,避免长期订阅:
525
+ 按面板拆分,分**三条独立路径**:
504
526
 
505
- ```mermaid
506
- sequenceDiagram
507
- autonumber
508
- actor User as 用户
509
- participant UI as 面板 UI (React)
510
- participant R as renderer
511
- participant M as main<br/>ipc/panels.ts
512
- participant P as preload<br/>instrumentation
513
-
514
- User->>UI: 打开面板 / 刷新
515
- UI->>R: invokeMain('panel:eval', expression)
516
- R->>M: IPC: panel:eval
517
- M->>P: webContents.executeJavaScript(expression)
518
- Note over P: window 上已挂好取值函数
519
- P-->>M: 结构化数据
520
- M-->>R: 返回结果
521
- R-->>UI: 渲染
522
- ```
527
+ | 面板 / 场景 | 模式 | 路径 |
528
+ | --- | --- | --- |
529
+ | Console / AppData / WXML 树 | 推送 | preload instrumentation 通过 `runtime/host.ts:sendToHost` 经 webview `ipcRenderer.sendToHost` 推到宿主 → renderer 监听 `ipc-message` 分发 |
530
+ | Storage | 拉取 + 推送 | renderer `ipcInvoke(SimulatorStorageChannel.GetSnapshot)` → 主进程 CDP `DOMStorage` 域;变更事件由主进程通过 `SimulatorStorageChannel.Event` 推回 renderer |
531
+ | 元素选区 / `Page.getData` / MCP overview | 拉取 | 主进程 `webContents.executeJavaScript(...)` 或 `Runtime.evaluate(...)` 读 `window.__simulatorData.*`(由 `installSimulatorBridge` 暴露) |
523
532
 
524
- Console 输出等推送场景仍由 preload 通过 `installSimulatorBridge()` 经由 webview ipcRenderer 送至宿主,再由 renderer 分发到相应面板。
533
+ > `src/main/ipc/panels.ts` 暴露 `panel:eval` handler 供外部 host 自定义面板复用,内置 renderer 不消费它。
525
534
 
526
535
  ---
527
536
 
@@ -13,5 +13,7 @@ export { installConsoleInstrumentation } from './instrumentation/console.js';
13
13
  export { installAppDataInstrumentation, sendAllAppData } from './instrumentation/app-data.js';
14
14
  export { installWxmlInstrumentation, sendWxmlTree, setupWxmlObserver } from './instrumentation/wxml.js';
15
15
  export { installSimulatorBridge } from './runtime/bridge.js';
16
+ export { installCustomApisBridge } from './runtime/custom-apis.js';
17
+ export type { DiminaCustomApisBridge } from './runtime/custom-apis.js';
16
18
  export { setupApiCompatHook } from './shared/api-compat.js';
17
19
  //# sourceMappingURL=index.d.ts.map
@@ -13,5 +13,6 @@ export { installConsoleInstrumentation } from './instrumentation/console.js';
13
13
  export { installAppDataInstrumentation, sendAllAppData } from './instrumentation/app-data.js';
14
14
  export { installWxmlInstrumentation, sendWxmlTree, setupWxmlObserver } from './instrumentation/wxml.js';
15
15
  export { installSimulatorBridge } from './runtime/bridge.js';
16
+ export { installCustomApisBridge } from './runtime/custom-apis.js';
16
17
  export { setupApiCompatHook } from './shared/api-compat.js';
17
18
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dimina-kit/devtools",
3
- "version": "0.3.1-dev.20260515105504",
3
+ "version": "0.3.1-dev.20260517100756",
4
4
  "description": "Dimina DevTools - modular developer tools for mini app debugging",
5
5
  "keywords": [
6
6
  "dimina",
@@ -116,7 +116,7 @@
116
116
  "chrome-remote-interface": "^0.34.0",
117
117
  "ws": "^8.20.0",
118
118
  "zod": "^4.3.6",
119
- "@dimina-kit/devkit": "0.1.1-dev.20260515105504"
119
+ "@dimina-kit/devkit": "0.1.1-dev.20260517100756"
120
120
  },
121
121
  "devDependencies": {
122
122
  "@playwright/test": "^1.59.1",