@dimina-kit/electron-deck 0.1.0-dev.20260610082053

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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -0
  3. package/dist/client/index.d.ts +20 -0
  4. package/dist/client/index.d.ts.map +1 -0
  5. package/dist/client/index.js +310 -0
  6. package/dist/client/index.js.map +1 -0
  7. package/dist/client/layout-client.d.ts +51 -0
  8. package/dist/client/layout-client.d.ts.map +1 -0
  9. package/dist/electron-deck-DfFKeFEC.js +2295 -0
  10. package/dist/electron-deck-DfFKeFEC.js.map +1 -0
  11. package/dist/electron-deck.d.ts +57 -0
  12. package/dist/electron-deck.d.ts.map +1 -0
  13. package/dist/errors-NE2ig7L5.js +53 -0
  14. package/dist/errors-NE2ig7L5.js.map +1 -0
  15. package/dist/errors.d.ts +33 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/events.d.ts +14 -0
  18. package/dist/events.d.ts.map +1 -0
  19. package/dist/host/capability.d.ts +50 -0
  20. package/dist/host/capability.d.ts.map +1 -0
  21. package/dist/host/control-bus.d.ts +92 -0
  22. package/dist/host/control-bus.d.ts.map +1 -0
  23. package/dist/host/index.d.ts +42 -0
  24. package/dist/host/index.d.ts.map +1 -0
  25. package/dist/host/index.js +2 -0
  26. package/dist/index.d.ts +6 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +3 -0
  29. package/dist/internal/deck-app.d.ts +415 -0
  30. package/dist/internal/deck-app.d.ts.map +1 -0
  31. package/dist/internal/electron-types.d.ts +131 -0
  32. package/dist/internal/electron-types.d.ts.map +1 -0
  33. package/dist/internal/event-bus.d.ts +29 -0
  34. package/dist/internal/event-bus.d.ts.map +1 -0
  35. package/dist/internal/ipc-registry-memory.d.ts +25 -0
  36. package/dist/internal/ipc-registry-memory.d.ts.map +1 -0
  37. package/dist/internal/lifecycle-manager.d.ts +28 -0
  38. package/dist/internal/lifecycle-manager.d.ts.map +1 -0
  39. package/dist/internal/resource-registry.d.ts +9 -0
  40. package/dist/internal/resource-registry.d.ts.map +1 -0
  41. package/dist/internal/trust-set.d.ts +53 -0
  42. package/dist/internal/trust-set.d.ts.map +1 -0
  43. package/dist/internal/wire-transport.d.ts +159 -0
  44. package/dist/internal/wire-transport.d.ts.map +1 -0
  45. package/dist/main/compositor.d.ts +123 -0
  46. package/dist/main/compositor.d.ts.map +1 -0
  47. package/dist/main/connection.d.ts +37 -0
  48. package/dist/main/connection.d.ts.map +1 -0
  49. package/dist/main/debug-tap.d.ts +55 -0
  50. package/dist/main/debug-tap.d.ts.map +1 -0
  51. package/dist/main/disposable.d.ts +18 -0
  52. package/dist/main/disposable.d.ts.map +1 -0
  53. package/dist/main/index.d.ts +16 -0
  54. package/dist/main/index.d.ts.map +1 -0
  55. package/dist/main/index.js +152 -0
  56. package/dist/main/index.js.map +1 -0
  57. package/dist/main/logger.d.ts +15 -0
  58. package/dist/main/logger.d.ts.map +1 -0
  59. package/dist/main/scope.d.ts +52 -0
  60. package/dist/main/scope.d.ts.map +1 -0
  61. package/dist/main/view-handle.d.ts +131 -0
  62. package/dist/main/view-handle.d.ts.map +1 -0
  63. package/dist/preload/index.cjs +105 -0
  64. package/dist/preload/index.cjs.map +1 -0
  65. package/dist/preload/index.d.ts +43 -0
  66. package/dist/preload/index.d.ts.map +1 -0
  67. package/dist/preload/index.js +80 -0
  68. package/dist/preload/index.js.map +1 -0
  69. package/dist/protocol-BJqo-vP2.js +23 -0
  70. package/dist/protocol-BJqo-vP2.js.map +1 -0
  71. package/dist/shared/protocol.d.ts +76 -0
  72. package/dist/shared/protocol.d.ts.map +1 -0
  73. package/dist/types.d.ts +504 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/view-handle-CR-yWNfr.js +701 -0
  76. package/dist/view-handle-CR-yWNfr.js.map +1 -0
  77. package/package.json +86 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/preload/index.ts"],"sourcesContent":["import { contextBridge, ipcRenderer } from 'electron'\nimport {\n\tBRIDGE_PROTOCOL_VERSION,\n\tDEFAULT_BRIDGE_GLOBAL,\n\tDEFAULT_LAYOUT_BRIDGE_GLOBAL,\n\tDeckChannel,\n} from '../shared/protocol.js'\nimport type {\n\tEventEnvelope,\n\tInvokeRequest,\n\tInvokeResponse,\n\tProbeResponse,\n\tDeckBridge,\n} from '../shared/protocol.js'\nimport type { LayoutBridge, SlotGrant } from '../client/layout-client.js'\n\nexport interface ExposeBridgeOptions {\n\t/** 暴露到 window 的全局名,默认 `__electronDeckBridge` */\n\treadonly globalName?: string\n}\n\n/**\n * 在 host preload 内调用,把 framework typed RPC + event push bridge 暴露到\n * webview window:\n *\n * ```ts\n * import { contextBridge, ipcRenderer } from 'electron'\n * import { exposeDeckBridge } from '@dimina-kit/electron-deck/preload'\n * exposeDeckBridge()\n * ```\n *\n * 见 `DeckBridge` 接口(`shared/protocol.ts`)。\n */\nexport function exposeDeckBridge(options?: ExposeBridgeOptions): void {\n\tif (typeof contextBridge?.exposeInMainWorld !== 'function' || typeof ipcRenderer?.invoke !== 'function') {\n\t\tthrow new Error('exposeDeckBridge: must be called from a preload script (electron contextBridge / ipcRenderer unavailable)')\n\t}\n\n\tconst globalName = options?.globalName ?? DEFAULT_BRIDGE_GLOBAL\n\t// 自检 globalThis —— contextBridge 内部也维护去重,但我们抢先抛更明确的诊断\n\tconst g = globalThis as unknown as Record<string, unknown>\n\tif (g[globalName] !== undefined) {\n\t\tthrow new Error(`Deck bridge already exposed at \"${globalName}\"`)\n\t}\n\n\tconst bridge: DeckBridge = {\n\t\tversion: BRIDGE_PROTOCOL_VERSION,\n\t\tprobe(): Promise<ProbeResponse> {\n\t\t\treturn ipcRenderer.invoke(DeckChannel.Probe) as Promise<ProbeResponse>\n\t\t},\n\t\tinvoke(req: InvokeRequest): Promise<InvokeResponse> {\n\t\t\treturn ipcRenderer.invoke(DeckChannel.Invoke, req) as Promise<InvokeResponse>\n\t\t},\n\t\tonEvent(listener: (env: EventEnvelope) => void): () => void {\n\t\t\tconst wrapped = (_event: unknown, env: EventEnvelope): void => {\n\t\t\t\tlistener(env)\n\t\t\t}\n\t\t\tipcRenderer.on(DeckChannel.Event, wrapped)\n\t\t\treturn () => {\n\t\t\t\tipcRenderer.removeListener(DeckChannel.Event, wrapped)\n\t\t\t}\n\t\t},\n\t}\n\n\tcontextBridge.exposeInMainWorld(globalName, bridge)\n}\n\nexport interface ExposeLayoutBridgeOptions {\n\t/** 暴露到 window 的全局名,默认 `__electronDeckLayoutBridge` */\n\treadonly globalName?: string\n}\n\n/**\n * 在 host preload 内调用,把三条 slot-token LAYOUT channel(`slot-grant` PUSH /\n * `place` send / `layout-subscribe` invoke)封装成一个 `LayoutBridge`-shaped\n * 对象暴露到 webview window,供 renderer:\n *\n * ```ts\n * import { exposeDeckLayoutBridge } from '@dimina-kit/electron-deck/preload'\n * exposeDeckLayoutBridge()\n * // renderer:\n * createDeckLayoutClient({ bridge: window.__electronDeckLayoutBridge })\n * ```\n *\n * channel 名一律取自框架 `DeckChannel`(不手抄字符串)。`onSlotGrant` 返回一个\n * 纯 unsubscribe 函数(可跨 contextBridge),不是 Disposable 对象。\n */\nexport function exposeDeckLayoutBridge(options?: ExposeLayoutBridgeOptions): void {\n\tif (typeof contextBridge?.exposeInMainWorld !== 'function' || typeof ipcRenderer?.on !== 'function') {\n\t\tthrow new Error('exposeDeckLayoutBridge: must be called from a preload script (electron contextBridge / ipcRenderer unavailable)')\n\t}\n\n\tconst globalName = options?.globalName ?? DEFAULT_LAYOUT_BRIDGE_GLOBAL\n\tconst g = globalThis as unknown as Record<string, unknown>\n\tif (g[globalName] !== undefined) {\n\t\tthrow new Error(`Deck layout bridge already exposed at \"${globalName}\"`)\n\t}\n\n\tconst bridge: LayoutBridge = {\n\t\tonSlotGrant(cb: (grant: SlotGrant) => void): () => void {\n\t\t\tconst listener = (_event: unknown, grant: SlotGrant): void => {\n\t\t\t\tcb(grant)\n\t\t\t}\n\t\t\tipcRenderer.on(DeckChannel.SlotGrant, listener)\n\t\t\treturn () => {\n\t\t\t\tipcRenderer.removeListener(DeckChannel.SlotGrant, listener)\n\t\t\t}\n\t\t},\n\t\tsendPlace(msg): void {\n\t\t\tvoid ipcRenderer.invoke(DeckChannel.Place, msg).catch(() => {})\n\t\t},\n\t\tsubscribe(): void {\n\t\t\tvoid ipcRenderer.invoke(DeckChannel.LayoutSubscribe).catch(() => {})\n\t\t},\n\t}\n\n\tcontextBridge.exposeInMainWorld(globalName, bridge)\n}\n\nexport type {\n\tEventEnvelope,\n\tInvokeRequest,\n\tInvokeResponse,\n\tProbeResponse,\n\tDeckBridge,\n\tLayoutBridge,\n\tSlotGrant,\n}\nexport { BRIDGE_PROTOCOL_VERSION, DEFAULT_BRIDGE_GLOBAL, DEFAULT_LAYOUT_BRIDGE_GLOBAL, DeckChannel }\n"],"mappings":";;;;;;;;;;;;;;;AAiCA,SAAgB,iBAAiB,SAAqC;CACrE,IAAI,OAAO,eAAe,sBAAsB,cAAc,OAAO,aAAa,WAAW,YAC5F,MAAM,IAAI,MAAM,2GAA2G;CAG5H,MAAM,aAAa,SAAS,cAAA;CAG5B,IAAI,WAAE,gBAAgB,KAAA,GACrB,MAAM,IAAI,MAAM,mCAAmC,WAAW,EAAE;CAGjE,MAAM,SAAqB;EAC1B,SAAS;EACT,QAAgC;GAC/B,OAAO,YAAY,OAAO,YAAY,KAAK;EAC5C;EACA,OAAO,KAA6C;GACnD,OAAO,YAAY,OAAO,YAAY,QAAQ,GAAG;EAClD;EACA,QAAQ,UAAoD;GAC3D,MAAM,WAAW,QAAiB,QAA6B;IAC9D,SAAS,GAAG;GACb;GACA,YAAY,GAAG,YAAY,OAAO,OAAO;GACzC,aAAa;IACZ,YAAY,eAAe,YAAY,OAAO,OAAO;GACtD;EACD;CACD;CAEA,cAAc,kBAAkB,YAAY,MAAM;AACnD;;;;;;;;;;;;;;;;AAsBA,SAAgB,uBAAuB,SAA2C;CACjF,IAAI,OAAO,eAAe,sBAAsB,cAAc,OAAO,aAAa,OAAO,YACxF,MAAM,IAAI,MAAM,iHAAiH;CAGlI,MAAM,aAAa,SAAS,cAAA;CAE5B,IAAI,WAAE,gBAAgB,KAAA,GACrB,MAAM,IAAI,MAAM,0CAA0C,WAAW,EAAE;CAqBxE,cAAc,kBAAkB,YAAY;EAjB3C,YAAY,IAA4C;GACvD,MAAM,YAAY,QAAiB,UAA2B;IAC7D,GAAG,KAAK;GACT;GACA,YAAY,GAAG,YAAY,WAAW,QAAQ;GAC9C,aAAa;IACZ,YAAY,eAAe,YAAY,WAAW,QAAQ;GAC3D;EACD;EACA,UAAU,KAAW;GACpB,YAAiB,OAAO,YAAY,OAAO,GAAG,EAAE,YAAY,CAAC,CAAC;EAC/D;EACA,YAAkB;GACjB,YAAiB,OAAO,YAAY,eAAe,EAAE,YAAY,CAAC,CAAC;EACpE;CAG2C,CAAM;AACnD"}
@@ -0,0 +1,23 @@
1
+ //#region src/shared/protocol.ts
2
+ /** Bridge global 默认挂的全局名(contextBridge.exposeInMainWorld) */
3
+ var DEFAULT_BRIDGE_GLOBAL = "__electronDeckBridge";
4
+ /**
5
+ * Slot-token LAYOUT bridge 默认挂的全局名。`exposeDeckLayoutBridge()` 默认暴露到
6
+ * 此名,renderer 的 `createDeckLayoutClient({ bridge: window.__electronDeckLayoutBridge })`
7
+ * 读取同名。单一来源避免 preload helper 与 client 之间字符串漂移。
8
+ */
9
+ var DEFAULT_LAYOUT_BRIDGE_GLOBAL = "__electronDeckLayoutBridge";
10
+ /** Bridge protocol semver;client 在 ready() 时校验 major 一致 */
11
+ var BRIDGE_PROTOCOL_VERSION = "1.0.0";
12
+ var DeckChannel = {
13
+ Invoke: "__electron-deck:invoke",
14
+ Event: "__electron-deck:event",
15
+ Probe: "__electron-deck:probe",
16
+ Place: "__electron-deck:place",
17
+ SlotGrant: "__electron-deck:slot-grant",
18
+ LayoutSubscribe: "__electron-deck:layout-subscribe"
19
+ };
20
+ //#endregion
21
+ export { DeckChannel as i, DEFAULT_BRIDGE_GLOBAL as n, DEFAULT_LAYOUT_BRIDGE_GLOBAL as r, BRIDGE_PROTOCOL_VERSION as t };
22
+
23
+ //# sourceMappingURL=protocol-BJqo-vP2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol-BJqo-vP2.js","names":[],"sources":["../src/shared/protocol.ts"],"sourcesContent":["/**\n * Deck framework wire protocol —— main ↔ webview 之间的 channel 名 + 帧\n * 形态。SoT 在此,preload / client / main runtime 都从这里 import。\n *\n * 设计:把 declared `hostServices` / `simulatorApis` / `events` 三类全部走\n * **两个** 统一 channel,避免 channel name 爆炸 / 难以加 senderPolicy 白名单。\n * - `__electron-deck:invoke` — webview → main RPC (ipcRenderer.invoke)\n * - `__electron-deck:event` — main → webview event push (webContents.send)\n * - `__electron-deck:probe` — webview → main 探活,bridge ready 检查\n *\n * 帧用 JSON 对象一层 envelope,便于扩展 + 校验。\n *\n * @internal\n */\n\nimport type { JsonValue } from '../types.js'\n\n/** Bridge global 默认挂的全局名(contextBridge.exposeInMainWorld) */\nexport const DEFAULT_BRIDGE_GLOBAL = '__electronDeckBridge'\n\n/**\n * Slot-token LAYOUT bridge 默认挂的全局名。`exposeDeckLayoutBridge()` 默认暴露到\n * 此名,renderer 的 `createDeckLayoutClient({ bridge: window.__electronDeckLayoutBridge })`\n * 读取同名。单一来源避免 preload helper 与 client 之间字符串漂移。\n */\nexport const DEFAULT_LAYOUT_BRIDGE_GLOBAL = '__electronDeckLayoutBridge'\n\n/** Bridge protocol semver;client 在 ready() 时校验 major 一致 */\nexport const BRIDGE_PROTOCOL_VERSION = '1.0.0'\n\nexport const DeckChannel = {\n\tInvoke: '__electron-deck:invoke',\n\tEvent: '__electron-deck:event',\n\tProbe: '__electron-deck:probe',\n\tPlace: '__electron-deck:place',\n\tSlotGrant: '__electron-deck:slot-grant',\n\tLayoutSubscribe: '__electron-deck:layout-subscribe',\n} as const\n\nexport type InvokeKind = 'host' | 'simulator'\n\nexport interface InvokeRequest {\n\treadonly kind: InvokeKind\n\treadonly name: string\n\treadonly args: readonly JsonValue[]\n}\n\nexport interface InvokeSuccess<R extends JsonValue = JsonValue> {\n\treadonly ok: true\n\treadonly result: R\n}\n\nexport interface InvokeFailure {\n\treadonly ok: false\n\treadonly error: {\n\t\treadonly remoteName: string\n\t\treadonly message: string\n\t\treadonly code?: string\n\t}\n}\n\nexport type InvokeResponse<R extends JsonValue = JsonValue> =\n\t| InvokeSuccess<R>\n\t| InvokeFailure\n\nexport interface EventEnvelope<P extends JsonValue = JsonValue> {\n\treadonly name: string\n\treadonly payload: P\n}\n\nexport interface ProbeResponse {\n\treadonly ready: true\n\treadonly version: typeof BRIDGE_PROTOCOL_VERSION\n}\n\n/**\n * Bridge global 暴露到 webview window 的 shape。preload 把它通过\n * `contextBridge.exposeInMainWorld(globalName, bridge)` 注入;webview-side\n * `createDeckClient()` 通过 `globalThis[globalName]` 读取。\n *\n * 注意所有方法必须是 contextBridge-friendly(plain values + serializable\n * arguments),不要把 Map / Set / Date / Promise.race 等 leak 进 bridge 接口。\n */\nexport interface DeckBridge {\n\treadonly version: typeof BRIDGE_PROTOCOL_VERSION\n\tprobe(): Promise<ProbeResponse>\n\tinvoke(req: InvokeRequest): Promise<InvokeResponse>\n\t/** 订阅 event channel;返回 unsubscribe 函数(不是 Disposable,因为要跨 contextBridge) */\n\tonEvent(listener: (env: EventEnvelope) => void): () => void\n}\n"],"mappings":";;AAkBA,IAAa,wBAAwB;;;;;;AAOrC,IAAa,+BAA+B;;AAG5C,IAAa,0BAA0B;AAEvC,IAAa,cAAc;CAC1B,QAAQ;CACR,OAAO;CACP,OAAO;CACP,OAAO;CACP,WAAW;CACX,iBAAiB;AAClB"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Deck framework wire protocol —— main ↔ webview 之间的 channel 名 + 帧
3
+ * 形态。SoT 在此,preload / client / main runtime 都从这里 import。
4
+ *
5
+ * 设计:把 declared `hostServices` / `simulatorApis` / `events` 三类全部走
6
+ * **两个** 统一 channel,避免 channel name 爆炸 / 难以加 senderPolicy 白名单。
7
+ * - `__electron-deck:invoke` — webview → main RPC (ipcRenderer.invoke)
8
+ * - `__electron-deck:event` — main → webview event push (webContents.send)
9
+ * - `__electron-deck:probe` — webview → main 探活,bridge ready 检查
10
+ *
11
+ * 帧用 JSON 对象一层 envelope,便于扩展 + 校验。
12
+ *
13
+ * @internal
14
+ */
15
+ import type { JsonValue } from '../types.js';
16
+ /** Bridge global 默认挂的全局名(contextBridge.exposeInMainWorld) */
17
+ export declare const DEFAULT_BRIDGE_GLOBAL = "__electronDeckBridge";
18
+ /**
19
+ * Slot-token LAYOUT bridge 默认挂的全局名。`exposeDeckLayoutBridge()` 默认暴露到
20
+ * 此名,renderer 的 `createDeckLayoutClient({ bridge: window.__electronDeckLayoutBridge })`
21
+ * 读取同名。单一来源避免 preload helper 与 client 之间字符串漂移。
22
+ */
23
+ export declare const DEFAULT_LAYOUT_BRIDGE_GLOBAL = "__electronDeckLayoutBridge";
24
+ /** Bridge protocol semver;client 在 ready() 时校验 major 一致 */
25
+ export declare const BRIDGE_PROTOCOL_VERSION = "1.0.0";
26
+ export declare const DeckChannel: {
27
+ readonly Invoke: "__electron-deck:invoke";
28
+ readonly Event: "__electron-deck:event";
29
+ readonly Probe: "__electron-deck:probe";
30
+ readonly Place: "__electron-deck:place";
31
+ readonly SlotGrant: "__electron-deck:slot-grant";
32
+ readonly LayoutSubscribe: "__electron-deck:layout-subscribe";
33
+ };
34
+ export type InvokeKind = 'host' | 'simulator';
35
+ export interface InvokeRequest {
36
+ readonly kind: InvokeKind;
37
+ readonly name: string;
38
+ readonly args: readonly JsonValue[];
39
+ }
40
+ export interface InvokeSuccess<R extends JsonValue = JsonValue> {
41
+ readonly ok: true;
42
+ readonly result: R;
43
+ }
44
+ export interface InvokeFailure {
45
+ readonly ok: false;
46
+ readonly error: {
47
+ readonly remoteName: string;
48
+ readonly message: string;
49
+ readonly code?: string;
50
+ };
51
+ }
52
+ export type InvokeResponse<R extends JsonValue = JsonValue> = InvokeSuccess<R> | InvokeFailure;
53
+ export interface EventEnvelope<P extends JsonValue = JsonValue> {
54
+ readonly name: string;
55
+ readonly payload: P;
56
+ }
57
+ export interface ProbeResponse {
58
+ readonly ready: true;
59
+ readonly version: typeof BRIDGE_PROTOCOL_VERSION;
60
+ }
61
+ /**
62
+ * Bridge global 暴露到 webview window 的 shape。preload 把它通过
63
+ * `contextBridge.exposeInMainWorld(globalName, bridge)` 注入;webview-side
64
+ * `createDeckClient()` 通过 `globalThis[globalName]` 读取。
65
+ *
66
+ * 注意所有方法必须是 contextBridge-friendly(plain values + serializable
67
+ * arguments),不要把 Map / Set / Date / Promise.race 等 leak 进 bridge 接口。
68
+ */
69
+ export interface DeckBridge {
70
+ readonly version: typeof BRIDGE_PROTOCOL_VERSION;
71
+ probe(): Promise<ProbeResponse>;
72
+ invoke(req: InvokeRequest): Promise<InvokeResponse>;
73
+ /** 订阅 event channel;返回 unsubscribe 函数(不是 Disposable,因为要跨 contextBridge) */
74
+ onEvent(listener: (env: EventEnvelope) => void): () => void;
75
+ }
76
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,yBAAyB,CAAA;AAE3D;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,+BAA+B,CAAA;AAExE,2DAA2D;AAC3D,eAAO,MAAM,uBAAuB,UAAU,CAAA;AAE9C,eAAO,MAAM,WAAW;;;;;;;CAOd,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,WAAW,CAAA;AAE7C,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAA;CACnC;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IAC7D,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;IACjB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAA;IAClB,QAAQ,CAAC,KAAK,EAAE;QACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;QAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACD;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,IACvD,aAAa,CAAC,CAAC,CAAC,GAChB,aAAa,CAAA;AAEhB,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,uBAAuB,CAAA;CAChD;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,uBAAuB,CAAA;IAChD,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC,CAAA;IAC/B,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IACnD,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,GAAG,MAAM,IAAI,CAAA;CAC3D"}
@@ -0,0 +1,504 @@
1
+ import type { BrowserWindow, NativeImage, WebContents, WebContentsView, ipcMain } from 'electron';
2
+ import type { MinimalApp, MinimalElectron } from './internal/electron-types.js';
3
+ import type { MinimalIpcMain, MinimalWebContents } from './internal/wire-transport.js';
4
+ export type MaybePromise<T> = T | Promise<T>;
5
+ export type JsonPrimitive = string | number | boolean | null;
6
+ export type JsonValue = JsonPrimitive | {
7
+ readonly [k: string]: JsonValue;
8
+ } | readonly JsonValue[];
9
+ export interface Disposable {
10
+ dispose(): void | Promise<void>;
11
+ }
12
+ /** Opaque session handle minted by `runtime.scopes.create()` (app-root) or
13
+ * `DeckWindow.newSession()` (window-rooted). Wraps a child Scope, so disposing
14
+ * it (or app shutdown / window close) tears down every view bound to it. Does
15
+ * NOT expose the internal Scope (no adopt/child escape). */
16
+ export interface DeckSession {
17
+ /** Release THIS session's views (and any other owned resources of its current
18
+ * segment), keeping the session AND its window alive — a fresh segment opens. */
19
+ reset(): Promise<void>;
20
+ /** Terminal: dispose every view bound to the session and close it. */
21
+ dispose(): Promise<void>;
22
+ }
23
+ /** A per-window close decision. `'keep'` vetoes the close; `'close'` proceeds. */
24
+ export type WindowCloseDecision = 'keep' | 'close';
25
+ /** A cancelable per-window close decider registered via {@link DeckWindow.onClose}. */
26
+ export type WindowCloseDecider = () => MaybePromise<WindowCloseDecision>;
27
+ /**
28
+ * Opaque handle over a framework-registered window (`runtime.windows.create()`
29
+ * / `runtime.windows.main`). Exposes the BrowserWindow + its control wc, a
30
+ * window-rooted session factory, and a per-window cancelable close decider.
31
+ *
32
+ * **Never exposes** the raw windowScope / substrate / trust lease.
33
+ */
34
+ export interface DeckWindow {
35
+ /** The BrowserWindow this handle wraps. */
36
+ readonly window: BrowserWindow;
37
+ /** The window's primary control WebContents (=== `window.webContents`),
38
+ * captured once at registration. */
39
+ readonly controlWc: WebContents;
40
+ /** Mint a window-rooted {@link DeckSession} (a child of this window's lifetime).
41
+ * `runtime.view({ scope })` accepts it under the same provenance check as an
42
+ * app-root session; closing the window cascades every session minted here. */
43
+ newSession(): DeckSession;
44
+ /** Register a per-window cancelable close decider. On a close attempt the
45
+ * framework `preventDefault()`s, runs the registered deciders in registration
46
+ * order; any `'keep'` vetoes, else the window is destroyed. On the MAIN window
47
+ * a live decider supersedes {@link RuntimeBackend.onMainWindowClose}. */
48
+ onClose(decider: WindowCloseDecider): Disposable;
49
+ }
50
+ /**
51
+ * `defineEvent(name)` 创建的 HostEvent。pure factory,无 side effect —— 必须在
52
+ * `DeckConfig.events` 中显式列出 framework 才会绑 transport。
53
+ */
54
+ export interface HostEvent<P extends JsonValue> {
55
+ readonly name: string;
56
+ publish(payload: P): void;
57
+ on(listener: (payload: P) => void): Disposable;
58
+ }
59
+ /**
60
+ * Handler 形参故意宽松(`any[]`)—— host 写 `(p: { code: string }) => ...` 这种
61
+ * narrower 签名必须能赋值给 `Record<string, Handler>`。framework 在 IPC 边界
62
+ * 做 JSON 校验,narrower 类型在 webview-side `createDeckClient<HS, EV>()`
63
+ * 通过 `Parameters<HS[K]>` 推断。返回值 framework 不约束 TS 类型,但 runtime
64
+ * 强制要求 JSON-safe(非 JSON 值反序列化时报错)。
65
+ */
66
+ export type SimulatorApiHandler = (...args: any[]) => unknown;
67
+ export type HostServiceHandler = (...args: any[]) => unknown;
68
+ export interface AppConfig {
69
+ readonly name?: string;
70
+ readonly icon?: string;
71
+ /**
72
+ * Optional content source for the framework-built main window. When set AND
73
+ * the framework owns the main window (NOT an `ownsWindows:true` backend), the
74
+ * framework auto-loads it after the window is built, via the same safeLoad path
75
+ * the toolbar / declared windows use. Omitted → the host owns the load. Ignored
76
+ * under an `ownsWindows:true` backend (the backend builds + loads its own window).
77
+ */
78
+ readonly source?: WebviewSource;
79
+ /**
80
+ * Opt-in process-lifecycle: bind `window-all-closed`. Omitted → the framework
81
+ * does NOT touch `window-all-closed` (Electron's default, or the consumer's own
82
+ * handler, applies). `true` → quit when all windows close; `false` → bind but
83
+ * suppress the default quit.
84
+ */
85
+ readonly quitOnAllWindowsClosed?: boolean;
86
+ /**
87
+ * Opt-in single-instance lock. When true, `start()` acquires the OS
88
+ * single-instance lock before `whenReady`; a second instance quits immediately.
89
+ * `second-instance` is forwarded to {@link RuntimeBackend.onSecondInstance}.
90
+ */
91
+ readonly singleInstance?: boolean;
92
+ readonly window?: {
93
+ readonly width?: number;
94
+ readonly height?: number;
95
+ readonly minWidth?: number;
96
+ readonly minHeight?: number;
97
+ readonly show?: boolean;
98
+ readonly backgroundColor?: string;
99
+ readonly webPreferences?: Record<string, unknown>;
100
+ };
101
+ }
102
+ export type WebviewSource = {
103
+ readonly url: string;
104
+ } | {
105
+ readonly file: string;
106
+ };
107
+ export interface ToolbarContribution {
108
+ readonly source: WebviewSource;
109
+ /** 必填:host 完全控制 preload */
110
+ readonly preloadPath: string;
111
+ /** 必填:固定高度(px);宽度自动跟随主窗口 */
112
+ readonly height: number;
113
+ }
114
+ export interface WindowContribution {
115
+ readonly title?: string;
116
+ readonly source: WebviewSource;
117
+ readonly preloadPath?: string;
118
+ readonly width?: number;
119
+ readonly height?: number;
120
+ readonly modal?: boolean;
121
+ }
122
+ export interface MenuContribution {
123
+ build(ctx: MenuBuildContext): void;
124
+ }
125
+ export interface MenuBuildContext {
126
+ readonly mainWindow: BrowserWindow;
127
+ readonly appName: string;
128
+ readonly theme: 'light' | 'dark';
129
+ }
130
+ export interface LifecycleContribution {
131
+ /**
132
+ * 在主窗口关闭 / app 退出之前调用,await 完成;超时则 log error 后继续 shutdown 流程(不阻止关闭)。
133
+ * host 如需更细粒度(区分 close 与 quit),用 `setup(runtime)` 内
134
+ * `runtime.electron.app.on('before-quit', ...)` escape。
135
+ */
136
+ readonly beforeClose?: () => MaybePromise<void>;
137
+ /** beforeClose 超时(ms),默认 10_000 */
138
+ readonly timeoutMs?: number;
139
+ }
140
+ /**
141
+ * 顶层 `electronDeck(config, options?)` 的第二参数。
142
+ *
143
+ * **生产路径**:缺省即可——framework lazy `await import('electron')` 取真
144
+ * `ipcMain` / `BrowserWindow` / `WebContentsView`。host 在 Electron main 进程
145
+ * 入口直接 `electronDeck(config)`,不需要手动注入。
146
+ *
147
+ * **测试 / 非 Electron 环境**:完全显式注入 `{ electron, ipcMain }` 即可绕过
148
+ * lazy import(vitest 跑 `await import('electron')` 会解析到 Electron 安装包
149
+ * 的 entry stub —— 它导出可执行路径字符串而非 main-process module,所以
150
+ * `ipcMain` / `BrowserWindow` 都是 undefined。framework 用 lazy import 时若
151
+ * 取不到 `ipcMain` 会抛清晰错误,提示注入。
152
+ *
153
+ * `trustedWebContents` / `senderPolicy` 是可选 override —— 缺省 framework 用
154
+ * 内部维护的 trusted set + 默认 isTrusted 策略。
155
+ *
156
+ * 注意:`backend` 不在这里——它是「这个 deck 跑什么领域装配」的配置,属于
157
+ * {@link DeckConfig},不是测试注入旋钮。
158
+ */
159
+ export interface DeckOptions {
160
+ /** 注入自定义 Electron(测试 fake 或 production override)。缺省时 framework lazy import 真 electron。 */
161
+ readonly electron?: MinimalElectron;
162
+ /** 注入 ipcMain;缺省时 framework 用 lazy-imported electron.ipcMain。 */
163
+ readonly ipcMain?: MinimalIpcMain;
164
+ /** 自定义 trustedWebContents 回调;默认走 framework 内部维护 set。 */
165
+ readonly trustedWebContents?: () => readonly MinimalWebContents[];
166
+ /** 自定义 senderPolicy;默认按 trusted 集判断。 */
167
+ readonly senderPolicy?: SenderPolicy;
168
+ }
169
+ export interface DeckConfig {
170
+ readonly app?: AppConfig;
171
+ /**
172
+ * 领域 backend。提供后 framework 跑 `beforeReady`(pre-ready) + `assemble`
173
+ * (setup),并把 main-window 装配让给 backend(framework 不建自己的窗口)。
174
+ * backend host 的主入口字段:`electronDeck({ backend })`——无需空 `{}` + options。
175
+ */
176
+ readonly backend?: RuntimeBackend;
177
+ /** 暴露给小程序,自动投影为 `wx.<name>` */
178
+ readonly simulatorApis?: Record<string, SimulatorApiHandler>;
179
+ /** 暴露给 trusted webview(toolbar 等)的 RPC */
180
+ readonly hostServices?: Record<string, HostServiceHandler>;
181
+ /** main → webview 推送;必须显式列出,避免 module load order 隐式注册 */
182
+ readonly events?: readonly HostEvent<JsonValue>[];
183
+ readonly toolbar?: ToolbarContribution;
184
+ readonly windows?: Record<string, WindowContribution>;
185
+ readonly menu?: MenuContribution;
186
+ readonly lifecycle?: LifecycleContribution;
187
+ /** Imperative escape:声明表达不了的运行时操作 */
188
+ readonly setup?: (runtime: Runtime) => MaybePromise<void>;
189
+ }
190
+ export interface TypedIpcRegistry {
191
+ handle<A extends JsonValue[], R extends JsonValue>(channel: string, handler: (...args: A) => MaybePromise<R>, options?: {
192
+ validator?: (args: unknown[]) => A;
193
+ }): Disposable;
194
+ on<P extends JsonValue>(channel: string, listener: (payload: P) => void): Disposable;
195
+ send(target: 'mainWindow' | BrowserWindow, channel: string, payload: JsonValue): void;
196
+ }
197
+ export interface SettingsSnapshot {
198
+ readonly theme: 'light' | 'dark';
199
+ readonly [k: string]: JsonValue;
200
+ }
201
+ export interface SenderPolicy {
202
+ /** trusted webContentsId set,框架内部维护;@internal */
203
+ isTrusted(senderId: number): boolean;
204
+ }
205
+ export interface ResourceRegistry {
206
+ /** @internal LIFO dispose */
207
+ add(d: Disposable | (() => MaybePromise<void>)): Disposable;
208
+ disposeAll(): Promise<void>;
209
+ }
210
+ export interface DeckContext {
211
+ readonly settings: SettingsSnapshot;
212
+ readonly theme: 'light' | 'dark';
213
+ /** @internal unsupported escape;破坏 I1/I2/I3 服务承诺 */
214
+ readonly _registry: ResourceRegistry;
215
+ /** @internal unsupported escape */
216
+ readonly _senderPolicy: SenderPolicy;
217
+ }
218
+ export interface FrameworkEvents {
219
+ 'window-created': {
220
+ window: BrowserWindow;
221
+ role: 'main' | 'toolbar' | 'host';
222
+ };
223
+ 'window-closed': {
224
+ window: BrowserWindow;
225
+ };
226
+ /** webContents.loadURL/loadFile 失败时 emit。framework 不 reject start(),host 可订阅做兜底/重试 */
227
+ 'load-failed': {
228
+ source: WebviewSource;
229
+ error: unknown;
230
+ };
231
+ }
232
+ export interface WindowCreateOptions {
233
+ readonly source: WebviewSource;
234
+ readonly preloadPath?: string;
235
+ readonly width?: number;
236
+ readonly height?: number;
237
+ readonly modal?: boolean;
238
+ readonly parent?: BrowserWindow;
239
+ /** 默认 true */
240
+ readonly autoTrust?: boolean;
241
+ }
242
+ /** A screen-space rectangle (CSS px), mirroring the `view-handle` `Bounds`. */
243
+ export interface ViewBounds {
244
+ readonly x: number;
245
+ readonly y: number;
246
+ readonly width: number;
247
+ readonly height: number;
248
+ }
249
+ /**
250
+ * Explicit visibility + geometry for a host-managed native view. Structurally
251
+ * identical to the internal `view-handle` `Placement`; re-declared here so the
252
+ * public `Runtime` surface adds no internal-module dependency.
253
+ */
254
+ export type ViewPlacement = {
255
+ readonly visible: true;
256
+ readonly bounds: ViewBounds;
257
+ } | {
258
+ readonly visible: false;
259
+ };
260
+ /** Options for {@link Runtime.view}. */
261
+ export interface ViewCreateOptions {
262
+ readonly source: WebviewSource;
263
+ /** The view's home lifetime — a {@link DeckSession} from
264
+ * `runtime.scopes.create()`. Disposing the session detaches + unregisters the
265
+ * view (display teardown) and closes its native WebContents; because the
266
+ * session is a child of the app root, app shutdown also cascades into it.
267
+ * Omitting it binds the view to the app root (no per-session teardown; the
268
+ * view's display still tears down with its placeIn window, and shutdown closes
269
+ * it). A raw/foreign Scope is REJECTED — only a session minted by
270
+ * `runtime.scopes.create()` is accepted (provenance check). */
271
+ readonly scope?: DeckSession;
272
+ /**
273
+ * Opt-in keep-alive eviction policy (B3.2). When set, the framework disposes
274
+ * the least-recently-VISIBLE HIDDEN view in this view's group once the group's
275
+ * HIDDEN count exceeds `max` — destroying that view's native WebContents.
276
+ * Currently-visible views are NEVER evicted. Views sharing the same `max` form
277
+ * one group. Omitting `keepAlive` → the framework evicts nothing (pure host
278
+ * management; the host decides what to keep).
279
+ */
280
+ readonly keepAlive?: {
281
+ readonly policy: 'lru';
282
+ readonly max: number;
283
+ };
284
+ }
285
+ /**
286
+ * A host-API handle over ONE native view (`runtime.view(...)`). Chainable:
287
+ * `placeIn` and `applyPlacement` both return the handle so calls compose.
288
+ * `dispose` detaches the view and makes the placement sink inert.
289
+ */
290
+ export interface DeckViewHandle {
291
+ /** Mount the native view into `window`'s content view at the given zone.
292
+ * `anchor` is accepted + stored for the future slot-token step (unused in
293
+ * slice 1). Chainable. */
294
+ placeIn(window: BrowserWindow, opts: {
295
+ zone?: number;
296
+ anchor?: string;
297
+ }): DeckViewHandle;
298
+ /** Drive the native view's visibility + bounds. `visible:true` (re)mounts and
299
+ * sets bounds directly; `visible:false` detaches but keeps the view alive.
300
+ * A frame after `dispose` is dropped. Chainable. */
301
+ applyPlacement(placement: ViewPlacement): DeckViewHandle;
302
+ /** Migrate the placed view to another window (the ONLY re-placement path —
303
+ * placeIn twice throws). Moves the per-window substrate registration + re-issues
304
+ * the slot-token anchor for the dest; atomic (rolls back to the source on dest
305
+ * failure). `rehome:true` re-parents the view's lifetime to the dest window. */
306
+ moveTo(win: BrowserWindow, opts: {
307
+ zone?: number;
308
+ anchor?: string;
309
+ rehome?: boolean;
310
+ }): Promise<void>;
311
+ /** Tear down this placement (detach the native view, disable the sink). */
312
+ dispose(): Promise<void>;
313
+ /** The native view's `WebContents`. Available immediately — the handle owns
314
+ * its view before any `placeIn`, so a caller can recover the WebContents (and
315
+ * its bounds/screenshot below) without diffing `mainWindow.contentView.children`. */
316
+ readonly webContents: WebContents;
317
+ /** The view's LIVE screen-space rect when it is currently placed AND visible;
318
+ * `null` before any placement, after `applyPlacement({visible:false})`, and
319
+ * after `dispose()`. */
320
+ bounds(): ViewBounds | null;
321
+ /** Capture the native view as a `NativeImage` (pass-through to the view's
322
+ * `webContents.capturePage()`). */
323
+ capturePage(): Promise<NativeImage>;
324
+ }
325
+ export interface Runtime {
326
+ readonly electron: typeof import('electron');
327
+ readonly mainWindow: BrowserWindow;
328
+ readonly toolbarView: WebContentsView | null;
329
+ readonly ipc: TypedIpcRegistry;
330
+ readonly rawIpcMain: typeof ipcMain;
331
+ readonly call: {
332
+ simulator(name: string, ...args: JsonValue[]): Promise<JsonValue>;
333
+ host(name: string, ...args: JsonValue[]): Promise<JsonValue>;
334
+ };
335
+ readonly windows: {
336
+ create(opts: WindowCreateOptions): DeckWindow;
337
+ get(id: string): BrowserWindow | undefined;
338
+ all(): BrowserWindow[];
339
+ /** The framework-built main window's {@link DeckWindow}, or `null` when the
340
+ * framework does not own a main window (e.g. an `ownsWindows:true` backend). */
341
+ readonly main: DeckWindow | null;
342
+ trust(win: BrowserWindow): Disposable;
343
+ /**
344
+ * Register an EXTERNALLY-created window (one the host built itself, e.g.
345
+ * under a `ownsWindows:true` backend) into the framework: its windowScope,
346
+ * per-window native-view substrate, and TRUST lifecycle — so
347
+ * `runtime.view().placeIn(win)` works for it. Trust + slot-tokens + grants
348
+ * for the window's webContents are revoked SYNCHRONOUSLY and FIRST on the
349
+ * window's `'closed'` (the framework arms its revoke via `prependListener`,
350
+ * so it runs before any external `'closed'` listener the host registered
351
+ * earlier — a host listener must never observe a still-trusted wc whose id
352
+ * Electron may immediately reuse).
353
+ *
354
+ * Idempotent by webContents identity: adopting the same window twice returns
355
+ * the existing registration (no second substrate, no double trust lease).
356
+ * Throws if the window (or its webContents) is already destroyed — a dead
357
+ * wc.id could be reused, so admitting one would be a privilege-escalation
358
+ * hazard.
359
+ *
360
+ * `ownership`:
361
+ * - `'transfer'` → the framework owns the window's lifetime and destroys it
362
+ * at app shutdown (as it does for its own windows).
363
+ * - `'observe'` (default) → the HOST owns the window's lifetime; the
364
+ * framework NEVER calls `destroy()` on it, but still tears down the
365
+ * substrate + trust when the registration is disposed or the app shuts down.
366
+ *
367
+ * The returned {@link Disposable} un-adopts the window early (tears down its
368
+ * substrate + trust); it is idempotent.
369
+ */
370
+ adopt(win: BrowserWindow, opts?: {
371
+ ownership?: 'transfer' | 'observe';
372
+ }): Disposable;
373
+ };
374
+ /** Create a host-managed native view and return a chainable handle. Throws
375
+ * if the build has no Electron (mirrors `windows.create`). */
376
+ view(opts: ViewCreateOptions): DeckViewHandle;
377
+ /** Session factory. `create()` mints an opaque {@link DeckSession} (internally
378
+ * a child of the app root) — the ONLY legitimate source of a `scope` for
379
+ * `runtime.view`. Disposing the session tears down every view bound to it;
380
+ * app shutdown also cascades into it. */
381
+ readonly scopes: {
382
+ create(): DeckSession;
383
+ };
384
+ readonly grants: {
385
+ /** Authorize `controlWc` to invoke the given privileged commands. The grant
386
+ * is revoked automatically when the control wc's lifetime Scope resets
387
+ * (navigation) or closes (destroy) — wc.id-reuse safe. Throws if `controlWc`
388
+ * is not trusted.
389
+ *
390
+ * `targetScope` is OPTIONAL and reserved: when supplied it is stored as the
391
+ * authorization boundary for FUTURE per-target view-command checks; the
392
+ * current grant gate authorizes by (senderId, command-name) only — no command
393
+ * resolves a target view yet, so targetScope is not consulted at dispatch. */
394
+ issue(controlWc: WebContents, opts: {
395
+ commands: readonly string[];
396
+ targetScope?: DeckSession;
397
+ }): Disposable;
398
+ };
399
+ readonly layout: {
400
+ /** Register a PRIVILEGED command (must be a `layout.*` name) handled through
401
+ * the capability-gated ControlBus. A caller can only invoke it if a live
402
+ * grant covers (senderId, name); otherwise DECK_FORBIDDEN. Ordinary domain
403
+ * APIs go in `hostServices` (un-gated) — never register privileged names there. */
404
+ command(name: string, handler: (...args: JsonValue[]) => JsonValue | Promise<JsonValue>): Disposable;
405
+ };
406
+ readonly context: DeckContext;
407
+ on<E extends keyof FrameworkEvents>(event: E, listener: (payload: FrameworkEvents[E]) => void): Disposable;
408
+ add(d: Disposable | (() => MaybePromise<void>)): Disposable;
409
+ }
410
+ /**
411
+ * Frame-aware sender identity for trust checks. `frame` is null when the
412
+ * platform cannot resolve a sender frame (e.g. some sync paths / destroyed
413
+ * frames) — callers decide fail-closed vs sender-level fallback per channel.
414
+ */
415
+ export interface TrustedSenderRef {
416
+ readonly webContentsId: number;
417
+ readonly frame: {
418
+ readonly url: string;
419
+ readonly isMainFrame: boolean;
420
+ readonly processId: number;
421
+ readonly routingId: number;
422
+ } | null;
423
+ }
424
+ /**
425
+ * Domain backend injected into the framework. The framework owns process
426
+ * lifecycle / windows / wire / trust primitives; the backend supplies the
427
+ * domain assembly (real context, mainWindow content, projects/simulator/views,
428
+ * IPC modules) the framework is deliberately ignorant of. All hooks except
429
+ * `assemble` are optional; absent hooks fall back to framework defaults.
430
+ *
431
+ * @internal exported via `/host` for backend implementers.
432
+ */
433
+ export interface RuntimeBackend {
434
+ /**
435
+ * When true, the backend builds the main window itself (in `assemble`) and
436
+ * the framework skips its own window/toolbar/declared-window assembly — used
437
+ * by hosts whose window needs construction-time options the generic factory
438
+ * can't express (e.g. a per-session preload partition). Default false: the
439
+ * framework owns the window and the backend only reacts (onMainWindowClose).
440
+ */
441
+ readonly ownsWindows?: boolean;
442
+ /**
443
+ * Pre-ready side effects (scheme/protocol registration, command-line
444
+ * switches, app name). Runs after electron is resolved but BEFORE
445
+ * `app.whenReady()`; receives the framework's resolved {@link MinimalApp}.
446
+ * Throwing aborts start() via cleanupOnError.
447
+ */
448
+ beforeReady?(app: MinimalApp): MaybePromise<void>;
449
+ /**
450
+ * Domain assembly. Runs in setup phase, after the runtime skeleton is built
451
+ * and the wire transport is live. Loads the main renderer, registers domain
452
+ * IPC modules, stands up simulator/CDP/views, etc.
453
+ */
454
+ assemble(runtime: Runtime): MaybePromise<void>;
455
+ /**
456
+ * Construction-time `webPreferences` for the framework-built main window.
457
+ * Called once, synchronously, BEFORE `new BrowserWindow(...)` in the
458
+ * `ownsWindows` falsy path. The returned prefs are merged into the window's
459
+ * `webPreferences` and take precedence over `config.app.window.webPreferences`
460
+ * on key collision. Only consulted when the framework owns the main window.
461
+ */
462
+ mainWindowWebPreferences?(): Record<string, unknown> | undefined;
463
+ /**
464
+ * Called once, synchronously, AFTER the framework constructs the main window
465
+ * and BEFORE any content load (loadFile/loadURL). Receives the framework-built
466
+ * main window and the injected electron module so the backend can attach
467
+ * listeners / views / state before the renderer starts. Only fires in the
468
+ * `ownsWindows` falsy path.
469
+ */
470
+ onMainWindowCreated?(win: BrowserWindow, electron: typeof import('electron')): void;
471
+ /**
472
+ * Called when the framework edge-trusts one of its webContents — covers the
473
+ * framework-built main window as well as framework-built declared / host /
474
+ * runtime-created windows. Lets the backend mirror trust into the domain
475
+ * trust set. Returns a Disposable the framework disposes on untrust / window
476
+ * destroy.
477
+ */
478
+ onWindowTrusted?(wc: MinimalWebContents): Disposable;
479
+ /**
480
+ * Main-window `close` decision (cancelable). `'keep'` → framework keeps the
481
+ * window (backend has already torn down its session / navigated back);
482
+ * `'close'` → framework destroys the window and shuts down. Must NOT call
483
+ * close/destroy itself; must finish any flush before returning `'close'`.
484
+ */
485
+ onMainWindowClose?(): MaybePromise<'keep' | 'close'>;
486
+ /** Framework resize hook — backend repositions its overlays against the
487
+ * framework-built main window that emitted `resize`. */
488
+ repositionOverlays?(win: BrowserWindow): void;
489
+ /**
490
+ * Fired on `second-instance` when `config.app.singleInstance` is set and this
491
+ * process holds the lock — the backend typically focuses/restores its main
492
+ * window. Process-level: fires regardless of `ownsWindows`.
493
+ */
494
+ onSecondInstance?(): void;
495
+ /**
496
+ * Deterministic shutdown hook. AWAITED exactly ONCE during `app.shutdown()`'s
497
+ * cleanup, consistently with `config.lifecycle.beforeClose` — so a backend no
498
+ * longer hand-rolls `app.once('before-quit', ...)`. Best-effort: a throw/reject
499
+ * is logged and does NOT abort the rest of shutdown. Fires regardless of
500
+ * `ownsWindows`.
501
+ */
502
+ onShutdown?(): void | Promise<void>;
503
+ }
504
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}