@dimina-kit/devtools 0.4.0-dev.20260615070430 → 0.4.0-dev.20260616024534

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 (60) hide show
  1. package/README.md +0 -82
  2. package/dist/main/api.d.ts +1 -1
  3. package/dist/main/app/app.d.ts +0 -4
  4. package/dist/main/app/app.js +11 -6
  5. package/dist/main/app/lifecycle.d.ts +1 -0
  6. package/dist/main/app/lifecycle.js +10 -0
  7. package/dist/main/index.bundle.js +111 -143
  8. package/dist/main/ipc/app.d.ts +1 -3
  9. package/dist/main/ipc/app.js +0 -80
  10. package/dist/main/runtime/miniapp-runtime.d.ts +4 -2
  11. package/dist/main/services/notifications/renderer-notifier.d.ts +0 -4
  12. package/dist/main/services/notifications/renderer-notifier.js +1 -7
  13. package/dist/main/services/safe-area/index.d.ts +6 -4
  14. package/dist/main/services/safe-area/index.js +20 -14
  15. package/dist/main/services/simulator-storage/index.js +4 -2
  16. package/dist/main/services/views/view-manager.js +40 -8
  17. package/dist/main/services/workbench-context.d.ts +10 -13
  18. package/dist/main/services/workbench-context.js +1 -4
  19. package/dist/main/services/workspace/workspace-service.js +13 -0
  20. package/dist/main/utils/theme.d.ts +15 -0
  21. package/dist/main/utils/theme.js +34 -1
  22. package/dist/main/windows/main-window/create.d.ts +6 -0
  23. package/dist/main/windows/main-window/create.js +5 -1
  24. package/dist/preload/runtime/native-host.d.ts +3 -0
  25. package/dist/preload/runtime/native-host.js +2 -0
  26. package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
  27. package/dist/preload/windows/main.cjs +3 -3
  28. package/dist/preload/windows/main.cjs.map +2 -2
  29. package/dist/preload/windows/simulator.cjs +1 -0
  30. package/dist/preload/windows/simulator.cjs.map +2 -2
  31. package/dist/preload/windows/simulator.js +1 -0
  32. package/dist/renderer/assets/index-BFwsvw4p.js +50 -0
  33. package/dist/renderer/assets/{input-J1MQ5fra.js → input-hGF71bn3.js} +2 -2
  34. package/dist/renderer/assets/{ipc-transport-21qDpt9Y.js → ipc-transport-BKWkvwKK.js} +2 -2
  35. package/dist/renderer/assets/ipc-transport-Cg1q1gwD.css +1 -0
  36. package/dist/renderer/assets/{popover-ChIUUEdj.js → popover-NNQNyjgI.js} +2 -2
  37. package/dist/renderer/assets/select-Bb1AKeSq.js +2 -0
  38. package/dist/renderer/assets/{settings-CGea5k_R.js → settings-7uwimev-.js} +2 -2
  39. package/dist/renderer/assets/settings-api-DkrPHroq.js +2 -0
  40. package/dist/renderer/assets/{workbenchSettings-CFrdVOiP.js → workbenchSettings-EaMYvKHG.js} +2 -2
  41. package/dist/renderer/entries/main/index.html +6 -6
  42. package/dist/renderer/entries/popover/index.html +5 -5
  43. package/dist/renderer/entries/settings/index.html +5 -5
  44. package/dist/renderer/entries/workbench-settings/index.html +4 -4
  45. package/dist/shared/ipc-channels.d.ts +1 -7
  46. package/dist/shared/ipc-channels.js +7 -6
  47. package/dist/shared/ipc-schemas.d.ts +0 -1
  48. package/dist/shared/ipc-schemas.js +0 -1
  49. package/dist/shared/types.d.ts +17 -61
  50. package/dist/simulator/assets/device-shell-BWX7Yopg.js +2 -0
  51. package/dist/simulator/assets/{device-shell-DsdcNEkt.css → device-shell-BiFE9Otv.css} +1 -1
  52. package/dist/simulator/assets/{simulator-mini-app-CYtW6bMd.js → simulator-mini-app-BfNuDF3R.js} +2 -2
  53. package/dist/simulator/assets/{simulator-cV1PERi6.js → simulator-sf-D0mhw.js} +3 -3
  54. package/dist/simulator/simulator.html +1 -1
  55. package/package.json +4 -4
  56. package/dist/renderer/assets/index-Bx4XqFQ2.js +0 -50
  57. package/dist/renderer/assets/ipc-transport-CVp38I_M.css +0 -1
  58. package/dist/renderer/assets/select-BgWAbMot.js +0 -2
  59. package/dist/renderer/assets/settings-api-Dit4oL6S.js +0 -2
  60. package/dist/simulator/assets/device-shell-BEnc2k-W.js +0 -2
package/README.md CHANGED
@@ -42,12 +42,6 @@ launch({
42
42
  rendererDir,
43
43
  apiNamespaces: ['my'],
44
44
  brandingProvider: () => ({ appName: '我的开发工具' }),
45
- headerAvatarProvider: () => {
46
- const user = getCurrentUser()
47
- return user
48
- ? { displayName: user.name, displayInitial: user.name, avatarUrl: user.avatarUrl }
49
- : null
50
- },
51
45
  icon: '/path/to/icon.png',
52
46
  menuBuilder: (mainWindow, menuCtx) => {
53
47
  // menuCtx 是 MenuContext(只读 menu 相关状态)
@@ -187,10 +181,6 @@ src/
187
181
  | `preloadPath` | `string` | 内置 | 统一的 host 级 preload 入口;native-host simulator(WCV)自动跑其 `.cjs` sibling(`cjsSiblingPreloadPath`) |
188
182
  | `apiNamespaces` | `string[]` | `[]` | 自定义 API 命名空间(如 `['qd']`) |
189
183
  | `brandingProvider` | `() => { appName }` | — | 品牌信息 provider |
190
- | `headerAvatarProvider` | `() => HeaderAvatarInfo \| null \| Promise<HeaderAvatarInfo \| null>` | — | 内置 header 头像 slot 的宿主数据源;返回 `null` / `undefined` 时隐藏 |
191
- | `headerAvatarActionHandler` | `() => void \| Promise<void>` | — | 内置 header 头像 slot 的点击处理;未提供时点击无业务副作用 |
192
- | `headerActionsProvider` | `() => HeaderActionInfo[] \| null \| Promise<HeaderActionInfo[] \| null>` | — | 内置 header 三栏里的少量宿主命令按钮 |
193
- | `headerActionHandler` | `(id: string) => void \| Promise<void>` | — | 处理 `headerActionsProvider` 返回按钮的点击 |
194
184
  | `headerHeight` | `number` | — | **已废弃,运行时忽略**:头部栏恒为 40px(`HEADER_H`);需要自定义工具栏请用 host toolbar WCV |
195
185
 
196
186
  ### WorkbenchAppConfig(扩展 WorkbenchConfig)
@@ -218,78 +208,6 @@ src/
218
208
  | `instance.registerSimulatorApi(name, handler)` | 注册 simulator 自定义 API,小程序里 `wx.<name>()` 调用(详见下方"Simulator 自定义 API")。返回 `Disposable` |
219
209
  | `instance.ipc` | `IpcRegistry` 实例,`instance.ipc.handle(channel, fn)` 注册自定义 IPC;已绑定 `senderPolicy` 网关 |
220
210
  | `instance.registerTrustedWindow(win)` | 把 host 自有弹窗 `BrowserWindow` 加入受信 sender 集,否则其发起的 `instance.ipc` 调用会被网关拒绝。窗口关闭即移除 |
221
- | `instance.refreshHeaderAvatar()` | 通知 main renderer 重新调用 `headerAvatarProvider`,用于宿主登录态 / 头像变更后刷新内置 header 头像 |
222
- | `instance.refreshHeaderActions()` | 通知 main renderer 重新调用 `headerActionsProvider`,用于宿主 action 文案 / disabled 状态变化后刷新 |
223
-
224
- ### Header Avatar
225
-
226
- `headerAvatarProvider` 是内置 project header 头像 slot 的唯一数据源。devtools 会通过 `app:getHeaderAvatar` 拉取一个可序列化 DTO 并在固定 header toolbar 内渲染;宿主不需要、也不应该依赖 renderer 内部组件。
227
-
228
- 该 slot 只承载当前账号 / 身份入口,不是通用业务按钮扩展点。少量必须贴合内置 header 三栏布局的命令按钮使用下方的 `headerActionsProvider`;完整自定义工具栏、复杂状态展示、表单/筛选器、可变高度内容仍应使用 host toolbar WCV(`instance.context.views.hostToolbar.loadURL/loadFile` + `send/onMessage`),由宿主拥有内容、样式和高度。
229
-
230
- ```typescript
231
- launch({
232
- headerAvatarProvider: () => {
233
- const user = qdmpSession.currentUser()
234
- return user
235
- ? {
236
- displayName: user.nickname,
237
- displayInitial: user.nickname,
238
- avatarUrl: user.avatarUrl,
239
- tooltip: user.nickname,
240
- }
241
- : null
242
- },
243
- onSetup(instance) {
244
- qdmpSession.onUserChanged(() => instance.refreshHeaderAvatar())
245
- },
246
- })
247
- ```
248
-
249
- `HeaderAvatarInfo` 字段:
250
-
251
- | 字段 | 说明 |
252
- | --- | --- |
253
- | `displayName` | 用户名;用于 tooltip / aria 文本和 fallback 首字 |
254
- | `displayInitial` | 可选 fallback 文本;头像图片缺失或加载失败时取首字显示 |
255
- | `avatarUrl` | 头像图片 URL 或 data URL |
256
- | `tooltip` | 可选 tooltip 覆盖;默认用 `displayName` |
257
-
258
- ### Header Actions
259
-
260
- `headerActionsProvider` 用于把少量宿主命令渲染到内置 project header 的三栏中。它不是 host toolbar WCV 的替代品:只适合 1-4 个短文本命令,且按钮高度固定、宽度受 header 约束。
261
-
262
- placement 对应内置 header 的三个区域:
263
-
264
- | placement | 渲染位置 |
265
- | --- | --- |
266
- | `left` | 左区最右侧,位于头像 / 面板显隐 controls 之后 |
267
- | `center` | 中区最右侧,位于编译模式 / 重新编译 / 编译状态之后 |
268
- | `right` | 右区最左侧,位于布局 controls / 设置按钮之前 |
269
-
270
- ```typescript
271
- launch({
272
- headerActionsProvider: () => [
273
- { id: 'open', label: '打开', placement: 'left' },
274
- { id: 'bindApp', label: '绑定应用', placement: 'left' },
275
- { id: 'preview', label: '真机预览', placement: 'center' },
276
- { id: 'upload', label: '上传', placement: 'right' },
277
- ],
278
- headerActionHandler: async (id) => {
279
- await commands.run(id)
280
- },
281
- })
282
- ```
283
-
284
- `HeaderActionInfo` 字段:
285
-
286
- | 字段 | 说明 |
287
- | --- | --- |
288
- | `id` | 稳定 action id;点击时传给 `headerActionHandler` |
289
- | `label` | 短按钮文案 |
290
- | `tooltip` | 可选 tooltip 覆盖;默认用 `label` |
291
- | `placement` | `left` / `center` / `right`;默认 `right` |
292
- | `disabled` | 可选禁用态 |
293
211
 
294
212
  ### 内置面板 ID
295
213
 
@@ -16,5 +16,5 @@ export { IpcRegistry } from './utils/ipc-registry.js';
16
16
  export type { SenderPolicy } from './utils/ipc-registry.js';
17
17
  export { UpdateManager, createGitHubReleaseChecker } from './services/update/index.js';
18
18
  export type { UpdateManagerOptions, GitHubReleaseCheckerOptions, PickAssetContext, VersionScheme, } from './services/update/index.js';
19
- export type { WorkbenchConfig, WorkbenchAppConfig, CompilationAdapter, ProjectSession, HeaderAvatarInfo, HeaderAvatarProvider, HeaderActionInfo, HeaderActionPlacement, HeaderActionsProvider, BuiltinPanelId, BuiltinModuleId, UpdateChecker, UpdateInfo, } from '../shared/types.js';
19
+ export type { WorkbenchConfig, WorkbenchAppConfig, CompilationAdapter, ProjectSession, BuiltinPanelId, BuiltinModuleId, UpdateChecker, UpdateInfo, } from '../shared/types.js';
20
20
  //# sourceMappingURL=api.d.ts.map
@@ -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
- /** Ask the main renderer to re-read the header avatar provider. */
19
- refreshHeaderAvatar: () => void;
20
- /** Ask the main renderer to re-read the header actions provider. */
21
- refreshHeaderActions: () => void;
22
18
  automationServer?: AutomationServer;
23
19
  updateManager?: UpdateManager;
24
20
  dispose: () => Promise<void>;
@@ -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
+ import { isAppQuitting } from './lifecycle.js';
9
10
  // eslint-disable-next-line no-restricted-syntax -- grandfathered(workbench-context): shrink-only
10
11
  import { createWorkbenchContext } from '../services/workbench-context.js';
11
12
  import { loadWorkbenchSettings, applyTheme } from '../services/settings/index.js';
@@ -131,6 +132,7 @@ function createConfiguredMainWindow(config, rendererDir) {
131
132
  height: config.window?.height,
132
133
  minWidth: config.window?.minWidth,
133
134
  minHeight: config.window?.minHeight,
135
+ autoShow: config.window?.autoShow,
134
136
  });
135
137
  // Set window/taskbar icon if provided (Linux/Windows; macOS uses app bundle icon)
136
138
  if (config.icon) {
@@ -149,10 +151,6 @@ function createContext(config, mainWindow, rendererDir) {
149
151
  appName: config.appName,
150
152
  apiNamespaces: config.apiNamespaces,
151
153
  brandingProvider: config.brandingProvider,
152
- headerAvatarProvider: config.headerAvatarProvider,
153
- headerAvatarActionHandler: config.headerAvatarActionHandler,
154
- headerActionsProvider: config.headerActionsProvider,
155
- headerActionHandler: config.headerActionHandler,
156
154
  // The host-supplied ProjectsProvider / template types in `shared/types`
157
155
  // are structurally compatible with the main-process equivalents —
158
156
  // these casts are safe; we re-narrow at the workspace-service /
@@ -161,6 +159,7 @@ function createContext(config, mainWindow, rendererDir) {
161
159
  projectTemplates: config.projectTemplates,
162
160
  builtinTemplates: config.builtinTemplates,
163
161
  customCreateProjectDialog: config.customCreateProjectDialog,
162
+ onBeforeOpenProject: config.onBeforeOpenProject,
164
163
  });
165
164
  }
166
165
  function registerBuiltinModules(config, context) {
@@ -233,6 +232,14 @@ function wireAppWindowEvents(config, instance) {
233
232
  context,
234
233
  onResize: () => context.views.repositionAll(),
235
234
  onClose: async (e) => {
235
+ // A real application quit (⌘Q / menu "Quit" / app.quit()) fires
236
+ // `before-quit` first, then this window's `close`. Let it through so the
237
+ // app actually exits — do NOT convert it into "close the project".
238
+ // Without this, `hasActiveSession()` would be true and the quit gets
239
+ // swallowed into closeProject(), so the app can never be quit while a
240
+ // project is open.
241
+ if (isAppQuitting())
242
+ return;
236
243
  if (!context.workspace.hasActiveSession())
237
244
  return;
238
245
  // Close button while a project session is open: stay in the workbench
@@ -356,8 +363,6 @@ export async function createDevtoolsRuntime(config = {}) {
356
363
  // teardown, so a single dispose leaves no dead entry behind.
357
364
  registerTrustedWindow: (win) => context.registry.add(registerTrustedWindow(context, win)),
358
365
  registerSimulatorApi: (name, handler) => context.registry.add(toDisposable(context.simulatorApis.register(name, handler))),
359
- refreshHeaderAvatar: () => context.notify.headerAvatarChanged(),
360
- refreshHeaderActions: () => context.notify.headerActionsChanged(),
361
366
  dispose: () => disposeContext(context),
362
367
  };
363
368
  if (config.onSetup) {
@@ -1,2 +1,3 @@
1
+ export declare function isAppQuitting(): boolean;
1
2
  export declare function registerAppLifecycle(): void;
2
3
  //# sourceMappingURL=lifecycle.d.ts.map
@@ -1,10 +1,20 @@
1
1
  import { app, globalShortcut } from 'electron';
2
+ // Flips to `true` once Electron's `before-quit` fires — a real application
3
+ // quit (⌘Q / menu "Quit" / app.quit()) is underway. `before-quit` is emitted
4
+ // BEFORE each window's `close` event, so the main-window onClose handler can
5
+ // read this to tell "the whole app is exiting" apart from "the user closed a
6
+ // single project window" and avoid swallowing the quit.
7
+ let appIsQuitting = false;
8
+ export function isAppQuitting() {
9
+ return appIsQuitting;
10
+ }
2
11
  export function registerAppLifecycle() {
3
12
  app.on('window-all-closed', () => {
4
13
  globalShortcut.unregisterAll();
5
14
  app.quit();
6
15
  });
7
16
  app.on('before-quit', () => {
17
+ appIsQuitting = true;
8
18
  globalShortcut.unregisterAll();
9
19
  });
10
20
  }