@dimina-kit/devtools 0.4.0-dev.20260728110120 → 0.4.0-dev.20260731100034

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 (105) hide show
  1. package/README.md +68 -0
  2. package/dist/main/api.d.ts +1 -0
  3. package/dist/main/app/app.d.ts +3 -0
  4. package/dist/main/app/app.js +15 -0
  5. package/dist/main/app/bootstrap.d.ts +8 -5
  6. package/dist/main/app/bootstrap.js +15 -15
  7. package/dist/main/index.bundle.js +2359 -5132
  8. package/dist/main/ipc/app-lifecycle.d.ts +1 -31
  9. package/dist/main/ipc/app-lifecycle.js +1 -53
  10. package/dist/main/ipc/bridge-router.d.ts +19 -152
  11. package/dist/main/ipc/bridge-router.js +28 -2186
  12. package/dist/main/ipc/page-scroll.d.ts +1 -13
  13. package/dist/main/ipc/page-scroll.js +1 -16
  14. package/dist/main/ipc/session-listener-bag.d.ts +1 -40
  15. package/dist/main/ipc/session-listener-bag.js +1 -39
  16. package/dist/main/services/console-forward/index.d.ts +1 -60
  17. package/dist/main/services/console-forward/index.js +1 -225
  18. package/dist/main/services/console-forward/internal-log.d.ts +1 -10
  19. package/dist/main/services/console-forward/internal-log.js +1 -22
  20. package/dist/main/services/diagnostics/index.d.ts +1 -58
  21. package/dist/main/services/diagnostics/index.js +1 -60
  22. package/dist/main/services/dimina-resource-server.d.ts +1 -6
  23. package/dist/main/services/dimina-resource-server.js +1 -98
  24. package/dist/main/services/network-forward/index.d.ts +15 -3
  25. package/dist/main/services/network-forward/index.js +30 -4
  26. package/dist/main/services/network-forward/websocket.d.ts +36 -0
  27. package/dist/main/services/network-forward/websocket.js +120 -0
  28. package/dist/main/services/service-host-pool/pool.d.ts +1 -196
  29. package/dist/main/services/service-host-pool/pool.js +1 -363
  30. package/dist/main/services/simulator/custom-apis.d.ts +1 -42
  31. package/dist/main/services/simulator/custom-apis.js +1 -46
  32. package/dist/main/services/simulator/referer.d.ts +1 -9
  33. package/dist/main/services/simulator/referer.js +1 -19
  34. package/dist/main/services/simulator/ui-extensions.d.ts +13 -0
  35. package/dist/main/services/simulator/ui-extensions.js +166 -0
  36. package/dist/main/services/simulator-storage/service-storage-ops.d.ts +1 -39
  37. package/dist/main/services/simulator-storage/service-storage-ops.js +1 -66
  38. package/dist/main/services/simulator-temp-files/disk.d.ts +1 -54
  39. package/dist/main/services/simulator-temp-files/disk.js +1 -237
  40. package/dist/main/services/simulator-temp-files/fs-channels.d.ts +1 -68
  41. package/dist/main/services/simulator-temp-files/fs-channels.js +1 -107
  42. package/dist/main/services/simulator-temp-files/index.d.ts +1 -32
  43. package/dist/main/services/simulator-temp-files/index.js +1 -181
  44. package/dist/main/services/simulator-temp-files/request-handler.d.ts +1 -29
  45. package/dist/main/services/simulator-temp-files/request-handler.js +1 -177
  46. package/dist/main/services/simulator-temp-files/resolver.d.ts +1 -21
  47. package/dist/main/services/simulator-temp-files/resolver.js +1 -21
  48. package/dist/main/services/simulator-temp-files/store.d.ts +1 -13
  49. package/dist/main/services/simulator-temp-files/store.js +1 -23
  50. package/dist/main/services/views/miniapp-partition.d.ts +1 -89
  51. package/dist/main/services/views/miniapp-partition.js +1 -158
  52. package/dist/main/services/views/native-simulator-view.js +3 -0
  53. package/dist/main/services/views/simulator-session-policy.d.ts +1 -27
  54. package/dist/main/services/views/simulator-session-policy.js +1 -98
  55. package/dist/main/services/views/view-manager.d.ts +5 -0
  56. package/dist/main/services/workbench-context.d.ts +10 -1
  57. package/dist/main/services/workbench-context.js +20 -0
  58. package/dist/main/utils/ipc-registry.d.ts +21 -3
  59. package/dist/main/utils/ipc-registry.js +26 -23
  60. package/dist/main/utils/paths.d.ts +14 -0
  61. package/dist/main/utils/paths.js +14 -0
  62. package/dist/main/windows/service-host-window/create.d.ts +1 -92
  63. package/dist/main/windows/service-host-window/create.js +1 -154
  64. package/dist/native-host/render/render.js +51 -52
  65. package/dist/native-host/service/service.js +2 -2
  66. package/dist/preload/index.d.ts +2 -0
  67. package/dist/preload/index.js +1 -0
  68. package/dist/preload/runtime/clipboard.d.ts +6 -0
  69. package/dist/preload/runtime/clipboard.js +12 -0
  70. package/dist/preload/runtime/native-host.js +4 -10
  71. package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
  72. package/dist/preload/windows/main.cjs +46 -126
  73. package/dist/preload/windows/main.cjs.map +3 -3
  74. package/dist/preload/windows/simulator.cjs +83 -56
  75. package/dist/preload/windows/simulator.cjs.map +4 -4
  76. package/dist/preload/windows/simulator.js +83 -56
  77. package/dist/renderer/assets/{index-BJlFbXHb.js → index-BBg3YI5b.js} +2 -2
  78. package/dist/renderer/entries/main/index.html +1 -1
  79. package/dist/shared/bridge-channels.d.ts +1 -419
  80. package/dist/shared/bridge-channels.js +1 -89
  81. package/dist/shared/dmb-resource-url.d.ts +2 -0
  82. package/dist/shared/dmb-resource-url.js +2 -0
  83. package/dist/shared/ipc-channels.d.ts +2 -32
  84. package/dist/shared/ipc-channels.js +2 -5
  85. package/dist/shared/request-core.d.ts +1 -83
  86. package/dist/shared/request-core.js +1 -167
  87. package/dist/shared/simulator-ui.d.ts +61 -0
  88. package/dist/shared/simulator-ui.js +12 -0
  89. package/dist/shared/types.d.ts +7 -0
  90. package/dist/simulator/assets/device-shell-B03OuytR.js +2 -0
  91. package/dist/simulator/assets/device-shell-DbC5ccs8.css +1 -0
  92. package/dist/simulator/assets/{jsx-runtime-BDTY6fEq.js → jsx-runtime-hBv-rHqQ.js} +2 -2
  93. package/dist/simulator/assets/{simulator-CRyLSz1N.js → simulator-DpdXUf--.js} +5 -5
  94. package/dist/simulator/simulator.html +2 -2
  95. package/dist/simulator/temp-files.d.ts +29 -0
  96. package/dist/simulator/temp-files.js +79 -0
  97. package/dist/simulator/types.d.ts +43 -0
  98. package/dist/simulator/types.js +2 -0
  99. package/package.json +10 -5
  100. package/dist/shared/simulator-api-metadata.d.ts +0 -26
  101. package/dist/shared/simulator-api-metadata.js +0 -59
  102. package/dist/shared/vpath.d.ts +0 -42
  103. package/dist/shared/vpath.js +0 -105
  104. package/dist/simulator/assets/device-shell-DOy53Y0s.css +0 -1
  105. package/dist/simulator/assets/device-shell-Sbkjw8Nb.js +0 -2
package/README.md CHANGED
@@ -53,6 +53,13 @@ launch({
53
53
  // simulator 自定义 API:per-context
54
54
  instance.registerSimulatorApi('login', (params) => myLogin(params))
55
55
 
56
+ // simulator 下游 UI:框架管理 DeviceShell 挂载点与生命周期
57
+ const nativeUi = instance.registerSimulatorUiExtension({
58
+ id: 'my.native-ui',
59
+ rendererScriptPath: '/absolute/path/to/native-ui.js',
60
+ })
61
+ instance.registerSimulatorApi('share', params => nativeUi.invoke('share', params))
62
+
56
63
  // 自定义 IPC:经 gated 的 IpcRegistry,不再裸 ipcMain.handle
57
64
  instance.ipc.handle('my:action', () => collectStats())
58
65
 
@@ -207,6 +214,7 @@ src/
207
214
  | 方法 | 说明 |
208
215
  | --- | --- |
209
216
  | `instance.registerSimulatorApi(name, handler)` | 注册 simulator 自定义 API,小程序里 `wx.<name>()` 调用(详见下方"Simulator 自定义 API")。返回 `Disposable` |
217
+ | `instance.registerSimulatorUiExtension({ id, rendererScriptPath })` | 注册可信 renderer bundle。框架负责注入当前 simulator、稳定 Overlay Root、soft reload 的 current/pending 切换和销毁;返回可 `invoke()` 的句柄 |
210
218
  | `instance.ipc` | `IpcRegistry` 实例,`instance.ipc.handle(channel, fn)` 注册自定义 IPC;已绑定 `senderPolicy` 网关 |
211
219
  | `instance.registerTrustedWindow(win)` | 把 host 自有弹窗 `BrowserWindow` 加入受信 sender 集,否则其发起的 `instance.ipc` 调用会被网关拒绝。窗口关闭即移除 |
212
220
 
@@ -482,6 +490,66 @@ launch({
482
490
 
483
491
  ---
484
492
 
493
+ ## Simulator UI 扩展
494
+
495
+ 需要分享面板、授权弹窗等产品 UI 的下游 host,应同时使用两个正交接口:
496
+
497
+ - `registerSimulatorApi` 定义小程序侧 `wx.*` 命令。
498
+ - `registerSimulatorUiExtension` 安装下游 renderer bundle,并通过返回句柄把命令送到 UI。
499
+
500
+ 主进程只注册绝对路径指向的可信构建产物:
501
+
502
+ ```typescript
503
+ const nativeUi = instance.registerSimulatorUiExtension({
504
+ id: 'my.native-ui',
505
+ rendererScriptPath: fileURLToPath(
506
+ new URL('../renderer/native-ui.js', import.meta.url),
507
+ ),
508
+ })
509
+
510
+ instance.registerSimulatorApi('share', params =>
511
+ nativeUi.invoke('share', params),
512
+ )
513
+ ```
514
+
515
+ renderer bundle 使用 `@dimina-kit/devtools/simulator-ui` 注册实现:
516
+
517
+ ```typescript
518
+ import { registerSimulatorUiExtension } from '@dimina-kit/devtools/simulator-ui'
519
+
520
+ let runtime
521
+
522
+ registerSimulatorUiExtension({
523
+ id: 'my.native-ui',
524
+ mount({ overlayRoot, appId, signal }) {
525
+ runtime = createNativeUi({ root: overlayRoot, appId })
526
+ signal.addEventListener('abort', () => runtime.destroy(), { once: true })
527
+ return () => runtime.destroy()
528
+ },
529
+ invoke(method, params) {
530
+ return runtime.invoke(method, params)
531
+ },
532
+ onChromeAction(action) {
533
+ if (action.name !== 'capsule.more') return false
534
+ runtime.showMoreMenu(action)
535
+ return true
536
+ },
537
+ })
538
+ ```
539
+
540
+ 契约边界:
541
+
542
+ - 框架只提供设备内的稳定 Overlay Root,不接收 React Component,因而不绑定下游 React 版本。
543
+ - 只有可见的 current `DeviceShell` 持有挂载点;soft reload 提升 pending shell 时,旧 mount 先收到 abort/cleanup,再在新 root 上 mount。
544
+ - Overlay Root 默认不拦截页面点击;扩展实际创建的交互层需要设置 `pointer-events: auto`。
545
+ - 胶囊菜单通过语义动作 `capsule.more` 分发,不应查询 `.menu-capsule__more` 或拦截 DOM click。
546
+ - `id` 在一个 context 内唯一;script 必须用相同 `id` 注册 renderer 实现,否则安装失败。
547
+ - 每次 simulator 顶层文档完成加载时都会重新读取 `rendererScriptPath`,因此开发态重建
548
+ bundle 后执行硬 reload 即可加载新代码;soft reload 只切换 DeviceShell 挂载点,不重复执行 bundle。
549
+ - `dispose()` 会注销 renderer 实现;context 销毁时自动执行。`invoke()` 参数和返回值必须可跨 Electron IPC/`executeJavaScript` 序列化。
550
+
551
+ ---
552
+
485
553
  ## Host Toolbar(宿主自定义工具栏)
486
554
 
487
555
  下游通过 `instance.context.views.hostToolbar` 拥有 devtools 头部下方的工具栏条(一个 WebContentsView):`loadURL` / `loadFile` 加载自己的内容,`setPreloadPath` 注入自己的 preload,`setHeightMode` 钉死或自动跟随内容高度(自动模式要求内容自带 shrink-to-fit 的 `[data-host-toolbar-root]` 包裹元素;`{ fixed }` 校验入参——非有限数或负数同步抛 `TypeError` 且不污染既有模式)。主进程保留最后一次下发的高度(`views.getHostToolbarHeight()`),项目视图的占位条挂载时会主动拉取并回放——广播器对已上报的高度去重不再重发,没有这一步,冷启动在项目列表期间的上报、以及关闭项目再打开后的高度都会永久丢失(工具栏条塌缩为 0)。
@@ -11,6 +11,7 @@ export type { ViewManager } from './services/views/view-manager.js';
11
11
  export type { WorkspaceService } from './services/workspace/workspace-service.js';
12
12
  export type { Project, ProjectPages, ProjectSettings } from './services/projects/project-repository.js';
13
13
  export type { SimulatorApiHandler } from './services/simulator/custom-apis.js';
14
+ export type { SimulatorUiExtensionHandle, SimulatorUiExtensionRegistration, } from '../shared/simulator-ui.js';
14
15
  export { rendererDir, defaultPreloadPath, simulatorDir, getRendererDir, getPreloadDir, getRendererHtml, } from './utils/paths.js';
15
16
  export { IpcRegistry } from './utils/ipc-registry.js';
16
17
  export type { SenderPolicy } from './utils/ipc-registry.js';
@@ -1,5 +1,6 @@
1
1
  import { BrowserWindow } from 'electron';
2
2
  import type { WorkbenchAppConfig } from '../../shared/types.js';
3
+ import type { SimulatorUiExtensionHandle, SimulatorUiExtensionRegistration } from '../../shared/simulator-ui.js';
3
4
  import type { SimulatorApiHandler } from '../services/simulator/custom-apis.js';
4
5
  import { type WorkbenchContext } from '../services/workbench-context.js';
5
6
  import { type AutomationServer } from '../services/automation/index.js';
@@ -15,6 +16,8 @@ export interface WorkbenchAppInstance {
15
16
  registerTrustedWindow: (win: BrowserWindow) => Disposable;
16
17
  /** Registers a simulator custom API into this context's registry. */
17
18
  registerSimulatorApi: (name: string, handler: SimulatorApiHandler) => Disposable;
19
+ /** Registers a downstream renderer extension for the simulator device UI. */
20
+ registerSimulatorUiExtension: (registration: SimulatorUiExtensionRegistration) => SimulatorUiExtensionHandle;
18
21
  automationServer?: AutomationServer;
19
22
  updateManager?: UpdateManager;
20
23
  dispose: () => Promise<void>;
@@ -476,6 +476,14 @@ onInstanceCreated) {
476
476
  // teardown, so a single dispose leaves no dead entry behind.
477
477
  registerTrustedWindow: (win) => context.registry.add(registerTrustedWindow(context, win)),
478
478
  registerSimulatorApi: (name, handler) => context.registry.add(toDisposable(context.simulatorApis.register(name, handler))),
479
+ registerSimulatorUiExtension: (registration) => {
480
+ const extension = context.simulatorUiExtensions.register(registration);
481
+ const owned = context.registry.add(extension);
482
+ return {
483
+ dispose: () => owned.dispose(),
484
+ invoke: (method, params) => extension.invoke(method, params),
485
+ };
486
+ },
479
487
  dispose: () => disposeContext(context),
480
488
  };
481
489
  onInstanceCreated?.(instance);
@@ -614,6 +622,13 @@ onInstanceCreated) {
614
622
  context.registry.add(toDisposable(context.internalDevtoolsWindow?.onHostChanged((hostWc) => {
615
623
  context.networkForward?.setGlobalDevtoolsHost(hostWc);
616
624
  }) ?? (() => { })));
625
+ // Main-process WebSocket traffic (wx.connectSocket runs on the Node `ws`
626
+ // transport, invisible to any webContents debugger): bridge-router fans
627
+ // the trace stream out here, and the forwarder synthesizes it into
628
+ // Network.webSocket* CDP events for the same Network panel sinks.
629
+ context.registry.add(toDisposable(context.bridge?.onNativeWebSocketTrace?.((ownerId, event) => {
630
+ context.networkForward?.reportWebSocketTrace(ownerId, event);
631
+ }) ?? (() => { })));
617
632
  context.registry.add(setupSimulatorWxml(mainWindow.webContents, {
618
633
  senderPolicy: context.senderPolicy,
619
634
  bridge: context.bridge,
@@ -1,10 +1,13 @@
1
1
  /**
2
- * Register `difile://` as a privileged scheme so `simSession.protocol.handle`
3
- * can serve `difile://devtools/{uuid}` URLs from the simulator webview without
4
- * tripping CSP / fetch-API restrictions. Must be called before `app.whenReady`.
2
+ * Register privileged custom schemes before `app.whenReady`.
5
3
  *
6
- * Idempotent subsequent calls are no-ops because Electron throws if the same
7
- * scheme is registered twice.
4
+ * Electron allows only one process-global `registerSchemesAsPrivileged` call, so
5
+ * this merges the runtime's `difile` + `dmb-resource` descriptors (required for
6
+ * render-host documents / ES module fetches on `dmb-resource://`) and keeps
7
+ * `bypassCSP` on `difile` for the simulator temp-file path.
8
+ *
9
+ * Idempotent — subsequent calls are no-ops because Electron throws if schemes
10
+ * are registered twice.
8
11
  */
9
12
  export declare function registerDifileScheme(): void;
10
13
  /**
@@ -1,32 +1,32 @@
1
1
  import { app, protocol } from 'electron';
2
+ import { ELECTRON_RUNTIME_SCHEMES } from '@dimina-kit/electron-runtime';
2
3
  import { DEFAULT_CDP_PORT } from '../../shared/constants.js';
3
4
  import { loadWorkbenchSettings } from '../services/settings/index.js';
4
5
  let difileSchemeRegistered = false;
5
6
  /**
6
- * Register `difile://` as a privileged scheme so `simSession.protocol.handle`
7
- * can serve `difile://devtools/{uuid}` URLs from the simulator webview without
8
- * tripping CSP / fetch-API restrictions. Must be called before `app.whenReady`.
7
+ * Register privileged custom schemes before `app.whenReady`.
9
8
  *
10
- * Idempotent subsequent calls are no-ops because Electron throws if the same
11
- * scheme is registered twice.
9
+ * Electron allows only one process-global `registerSchemesAsPrivileged` call, so
10
+ * this merges the runtime's `difile` + `dmb-resource` descriptors (required for
11
+ * render-host documents / ES module fetches on `dmb-resource://`) and keeps
12
+ * `bypassCSP` on `difile` for the simulator temp-file path.
13
+ *
14
+ * Idempotent — subsequent calls are no-ops because Electron throws if schemes
15
+ * are registered twice.
12
16
  */
13
17
  export function registerDifileScheme() {
14
18
  if (difileSchemeRegistered)
15
19
  return;
16
20
  difileSchemeRegistered = true;
17
- protocol.registerSchemesAsPrivileged([
18
- {
19
- scheme: 'difile',
21
+ protocol.registerSchemesAsPrivileged(ELECTRON_RUNTIME_SCHEMES.map((entry) => (entry.scheme === 'difile'
22
+ ? {
23
+ scheme: entry.scheme,
20
24
  privileges: {
21
- standard: true,
22
- secure: true,
23
- supportFetchAPI: true,
24
- stream: true,
25
+ ...entry.privileges,
25
26
  bypassCSP: true,
26
- corsEnabled: true,
27
27
  },
28
- },
29
- ]);
28
+ }
29
+ : { scheme: entry.scheme, privileges: { ...entry.privileges } })));
30
30
  }
31
31
  /**
32
32
  * Suppress EPIPE errors on stdout/stderr.