electron-infra-kit 0.0.2

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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +302 -0
  3. package/README.zh-CN.md +308 -0
  4. package/dist/core/error/WindowError.d.ts +56 -0
  5. package/dist/core/error/WindowError.js +71 -0
  6. package/dist/core/error/WindowError.js.map +1 -0
  7. package/dist/core/error/WindowError.mjs +71 -0
  8. package/dist/core/error/WindowError.mjs.map +1 -0
  9. package/dist/core/ipc/IpcHandler.d.ts +48 -0
  10. package/dist/core/ipc/IpcHandler.js +59 -0
  11. package/dist/core/ipc/IpcHandler.js.map +1 -0
  12. package/dist/core/ipc/IpcHandler.mjs +59 -0
  13. package/dist/core/ipc/IpcHandler.mjs.map +1 -0
  14. package/dist/core/ipc/IpcRouter.d.ts +70 -0
  15. package/dist/core/ipc/IpcRouter.js +143 -0
  16. package/dist/core/ipc/IpcRouter.js.map +1 -0
  17. package/dist/core/ipc/IpcRouter.mjs +143 -0
  18. package/dist/core/ipc/IpcRouter.mjs.map +1 -0
  19. package/dist/core/ipc/index.d.ts +3 -0
  20. package/dist/core/ipc/index.js +1 -0
  21. package/dist/core/ipc/index.js.map +1 -0
  22. package/dist/core/ipc/index.mjs +1 -0
  23. package/dist/core/ipc/index.mjs.map +1 -0
  24. package/dist/core/ipc/ipc-router.type.d.ts +73 -0
  25. package/dist/core/ipc/transport/index.d.ts +65 -0
  26. package/dist/core/ipc/transport/index.js +229 -0
  27. package/dist/core/ipc/transport/index.js.map +1 -0
  28. package/dist/core/ipc/transport/index.mjs +229 -0
  29. package/dist/core/ipc/transport/index.mjs.map +1 -0
  30. package/dist/core/ipc/transport/ipc.type.d.ts +36 -0
  31. package/dist/core/lifecycle/LifecycleManager.d.ts +66 -0
  32. package/dist/core/lifecycle/LifecycleManager.js +140 -0
  33. package/dist/core/lifecycle/LifecycleManager.js.map +1 -0
  34. package/dist/core/lifecycle/LifecycleManager.mjs +140 -0
  35. package/dist/core/lifecycle/LifecycleManager.mjs.map +1 -0
  36. package/dist/core/message-bus/MessageBus.d.ts +282 -0
  37. package/dist/core/message-bus/MessageBus.js +677 -0
  38. package/dist/core/message-bus/MessageBus.js.map +1 -0
  39. package/dist/core/message-bus/MessageBus.mjs +677 -0
  40. package/dist/core/message-bus/MessageBus.mjs.map +1 -0
  41. package/dist/core/message-bus/MessageBusClient.d.ts +100 -0
  42. package/dist/core/message-bus/MessageBusClient.js +280 -0
  43. package/dist/core/message-bus/MessageBusClient.js.map +1 -0
  44. package/dist/core/message-bus/MessageBusClient.mjs +280 -0
  45. package/dist/core/message-bus/MessageBusClient.mjs.map +1 -0
  46. package/dist/core/message-bus/core/DataStoreManager.d.ts +51 -0
  47. package/dist/core/message-bus/core/DataStoreManager.js +94 -0
  48. package/dist/core/message-bus/core/DataStoreManager.js.map +1 -0
  49. package/dist/core/message-bus/core/DataStoreManager.mjs +94 -0
  50. package/dist/core/message-bus/core/DataStoreManager.mjs.map +1 -0
  51. package/dist/core/message-bus/core/ManagedPort.d.ts +26 -0
  52. package/dist/core/message-bus/core/ManagedPort.js +55 -0
  53. package/dist/core/message-bus/core/ManagedPort.js.map +1 -0
  54. package/dist/core/message-bus/core/ManagedPort.mjs +55 -0
  55. package/dist/core/message-bus/core/ManagedPort.mjs.map +1 -0
  56. package/dist/core/message-bus/core/PortManager.d.ts +47 -0
  57. package/dist/core/message-bus/core/PortManager.js +114 -0
  58. package/dist/core/message-bus/core/PortManager.js.map +1 -0
  59. package/dist/core/message-bus/core/PortManager.mjs +114 -0
  60. package/dist/core/message-bus/core/PortManager.mjs.map +1 -0
  61. package/dist/core/message-bus/core/SubscriptionManager.d.ts +36 -0
  62. package/dist/core/message-bus/core/SubscriptionManager.js +78 -0
  63. package/dist/core/message-bus/core/SubscriptionManager.js.map +1 -0
  64. package/dist/core/message-bus/core/SubscriptionManager.mjs +78 -0
  65. package/dist/core/message-bus/core/SubscriptionManager.mjs.map +1 -0
  66. package/dist/core/message-bus/core/TransactionManager.d.ts +54 -0
  67. package/dist/core/message-bus/core/TransactionManager.js +95 -0
  68. package/dist/core/message-bus/core/TransactionManager.js.map +1 -0
  69. package/dist/core/message-bus/core/TransactionManager.mjs +95 -0
  70. package/dist/core/message-bus/core/TransactionManager.mjs.map +1 -0
  71. package/dist/core/message-bus/core/index.d.ts +5 -0
  72. package/dist/core/message-bus/index.d.ts +4 -0
  73. package/dist/core/message-bus/index.js +1 -0
  74. package/dist/core/message-bus/index.js.map +1 -0
  75. package/dist/core/message-bus/index.mjs +1 -0
  76. package/dist/core/message-bus/index.mjs.map +1 -0
  77. package/dist/core/message-bus/message-bus.type.d.ts +143 -0
  78. package/dist/core/message-bus/message-bus.type.js +26 -0
  79. package/dist/core/message-bus/message-bus.type.js.map +1 -0
  80. package/dist/core/message-bus/message-bus.type.mjs +26 -0
  81. package/dist/core/message-bus/message-bus.type.mjs.map +1 -0
  82. package/dist/core/message-bus/preload.d.ts +16 -0
  83. package/dist/core/message-bus/preload.js +27 -0
  84. package/dist/core/message-bus/preload.js.map +1 -0
  85. package/dist/core/message-bus/preload.mjs +27 -0
  86. package/dist/core/message-bus/preload.mjs.map +1 -0
  87. package/dist/core/message-bus/transport/ITransport.d.ts +40 -0
  88. package/dist/core/message-bus/transport/IpcTransport.d.ts +18 -0
  89. package/dist/core/message-bus/transport/IpcTransport.js +60 -0
  90. package/dist/core/message-bus/transport/IpcTransport.js.map +1 -0
  91. package/dist/core/message-bus/transport/IpcTransport.mjs +60 -0
  92. package/dist/core/message-bus/transport/IpcTransport.mjs.map +1 -0
  93. package/dist/core/message-bus/transport/MessagePortTransport.d.ts +15 -0
  94. package/dist/core/message-bus/transport/MessagePortTransport.js +35 -0
  95. package/dist/core/message-bus/transport/MessagePortTransport.js.map +1 -0
  96. package/dist/core/message-bus/transport/MessagePortTransport.mjs +35 -0
  97. package/dist/core/message-bus/transport/MessagePortTransport.mjs.map +1 -0
  98. package/dist/core/message-bus/transport/index.d.ts +3 -0
  99. package/dist/core/window/IpcSetup.d.ts +50 -0
  100. package/dist/core/window/IpcSetup.js +96 -0
  101. package/dist/core/window/IpcSetup.js.map +1 -0
  102. package/dist/core/window/IpcSetup.mjs +96 -0
  103. package/dist/core/window/IpcSetup.mjs.map +1 -0
  104. package/dist/core/window/WindowCreator.d.ts +66 -0
  105. package/dist/core/window/WindowCreator.js +168 -0
  106. package/dist/core/window/WindowCreator.js.map +1 -0
  107. package/dist/core/window/WindowCreator.mjs +168 -0
  108. package/dist/core/window/WindowCreator.mjs.map +1 -0
  109. package/dist/core/window/WindowManager.d.ts +214 -0
  110. package/dist/core/window/WindowManager.js +583 -0
  111. package/dist/core/window/WindowManager.js.map +1 -0
  112. package/dist/core/window/WindowManager.mjs +583 -0
  113. package/dist/core/window/WindowManager.mjs.map +1 -0
  114. package/dist/core/window/WindowStore.d.ts +136 -0
  115. package/dist/core/window/WindowStore.js +436 -0
  116. package/dist/core/window/WindowStore.js.map +1 -0
  117. package/dist/core/window/WindowStore.mjs +436 -0
  118. package/dist/core/window/WindowStore.mjs.map +1 -0
  119. package/dist/core/window/constants.d.ts +17 -0
  120. package/dist/core/window/constants.js +15 -0
  121. package/dist/core/window/constants.js.map +1 -0
  122. package/dist/core/window/constants.mjs +15 -0
  123. package/dist/core/window/constants.mjs.map +1 -0
  124. package/dist/core/window/core/MetricsManager.d.ts +14 -0
  125. package/dist/core/window/core/MetricsManager.js +27 -0
  126. package/dist/core/window/core/MetricsManager.js.map +1 -0
  127. package/dist/core/window/core/MetricsManager.mjs +27 -0
  128. package/dist/core/window/core/MetricsManager.mjs.map +1 -0
  129. package/dist/core/window/core/PluginExecutor.d.ts +22 -0
  130. package/dist/core/window/core/PluginExecutor.js +110 -0
  131. package/dist/core/window/core/PluginExecutor.js.map +1 -0
  132. package/dist/core/window/core/PluginExecutor.mjs +110 -0
  133. package/dist/core/window/core/PluginExecutor.mjs.map +1 -0
  134. package/dist/core/window/core/WindowContextManager.d.ts +26 -0
  135. package/dist/core/window/core/WindowContextManager.js +59 -0
  136. package/dist/core/window/core/WindowContextManager.js.map +1 -0
  137. package/dist/core/window/core/WindowContextManager.mjs +59 -0
  138. package/dist/core/window/core/WindowContextManager.mjs.map +1 -0
  139. package/dist/core/window/core/WindowLifecycle.d.ts +15 -0
  140. package/dist/core/window/core/WindowLifecycle.js +150 -0
  141. package/dist/core/window/core/WindowLifecycle.js.map +1 -0
  142. package/dist/core/window/core/WindowLifecycle.mjs +150 -0
  143. package/dist/core/window/core/WindowLifecycle.mjs.map +1 -0
  144. package/dist/core/window/core/WindowOperator.d.ts +90 -0
  145. package/dist/core/window/core/WindowOperator.js +154 -0
  146. package/dist/core/window/core/WindowOperator.js.map +1 -0
  147. package/dist/core/window/core/WindowOperator.mjs +154 -0
  148. package/dist/core/window/core/WindowOperator.mjs.map +1 -0
  149. package/dist/core/window/core/WindowRegistry.d.ts +168 -0
  150. package/dist/core/window/core/WindowRegistry.js +331 -0
  151. package/dist/core/window/core/WindowRegistry.js.map +1 -0
  152. package/dist/core/window/core/WindowRegistry.mjs +331 -0
  153. package/dist/core/window/core/WindowRegistry.mjs.map +1 -0
  154. package/dist/core/window/core/WindowStateManager.d.ts +40 -0
  155. package/dist/core/window/core/WindowStateManager.js +110 -0
  156. package/dist/core/window/core/WindowStateManager.js.map +1 -0
  157. package/dist/core/window/core/WindowStateManager.mjs +110 -0
  158. package/dist/core/window/core/WindowStateManager.mjs.map +1 -0
  159. package/dist/core/window/index.d.ts +7 -0
  160. package/dist/core/window/index.js +1 -0
  161. package/dist/core/window/index.js.map +1 -0
  162. package/dist/core/window/index.mjs +1 -0
  163. package/dist/core/window/index.mjs.map +1 -0
  164. package/dist/core/window/window-manager.schema.d.ts +50 -0
  165. package/dist/core/window/window-manager.schema.js +87 -0
  166. package/dist/core/window/window-manager.schema.js.map +1 -0
  167. package/dist/core/window/window-manager.schema.mjs +87 -0
  168. package/dist/core/window/window-manager.schema.mjs.map +1 -0
  169. package/dist/core/window/window-manager.type.d.ts +365 -0
  170. package/dist/index.d.ts +25 -0
  171. package/dist/index.js +33 -0
  172. package/dist/index.js.map +1 -0
  173. package/dist/index.mjs +33 -0
  174. package/dist/index.mjs.map +1 -0
  175. package/dist/index.umd.js +1 -0
  176. package/dist/infrastructure/config/ConfigManager.d.ts +133 -0
  177. package/dist/infrastructure/config/ConfigManager.js +218 -0
  178. package/dist/infrastructure/config/ConfigManager.js.map +1 -0
  179. package/dist/infrastructure/config/ConfigManager.mjs +218 -0
  180. package/dist/infrastructure/config/ConfigManager.mjs.map +1 -0
  181. package/dist/infrastructure/config/index.d.ts +1 -0
  182. package/dist/infrastructure/debug/EnhancedDebugHelper.d.ts +106 -0
  183. package/dist/infrastructure/debug/EnhancedDebugHelper.js +218 -0
  184. package/dist/infrastructure/debug/EnhancedDebugHelper.js.map +1 -0
  185. package/dist/infrastructure/debug/EnhancedDebugHelper.mjs +218 -0
  186. package/dist/infrastructure/debug/EnhancedDebugHelper.mjs.map +1 -0
  187. package/dist/infrastructure/debug/PerformanceMonitor.d.ts +45 -0
  188. package/dist/infrastructure/debug/PerformanceMonitor.js +67 -0
  189. package/dist/infrastructure/debug/PerformanceMonitor.js.map +1 -0
  190. package/dist/infrastructure/debug/PerformanceMonitor.mjs +67 -0
  191. package/dist/infrastructure/debug/PerformanceMonitor.mjs.map +1 -0
  192. package/dist/infrastructure/debug/index.d.ts +22 -0
  193. package/dist/infrastructure/debug/index.js +47 -0
  194. package/dist/infrastructure/debug/index.js.map +1 -0
  195. package/dist/infrastructure/debug/index.mjs +47 -0
  196. package/dist/infrastructure/debug/index.mjs.map +1 -0
  197. package/dist/infrastructure/errors/ErrorCodes.d.ts +74 -0
  198. package/dist/infrastructure/errors/ErrorCodes.js +78 -0
  199. package/dist/infrastructure/errors/ErrorCodes.js.map +1 -0
  200. package/dist/infrastructure/errors/ErrorCodes.mjs +78 -0
  201. package/dist/infrastructure/errors/ErrorCodes.mjs.map +1 -0
  202. package/dist/infrastructure/errors/StandardError.d.ts +61 -0
  203. package/dist/infrastructure/errors/StandardError.js +84 -0
  204. package/dist/infrastructure/errors/StandardError.js.map +1 -0
  205. package/dist/infrastructure/errors/StandardError.mjs +84 -0
  206. package/dist/infrastructure/errors/StandardError.mjs.map +1 -0
  207. package/dist/infrastructure/errors/index.d.ts +13 -0
  208. package/dist/infrastructure/errors/index.js +24 -0
  209. package/dist/infrastructure/errors/index.js.map +1 -0
  210. package/dist/infrastructure/errors/index.mjs +24 -0
  211. package/dist/infrastructure/errors/index.mjs.map +1 -0
  212. package/dist/infrastructure/logger/ElectronLogger.d.ts +39 -0
  213. package/dist/infrastructure/logger/ElectronLogger.js +65 -0
  214. package/dist/infrastructure/logger/ElectronLogger.js.map +1 -0
  215. package/dist/infrastructure/logger/ElectronLogger.mjs +65 -0
  216. package/dist/infrastructure/logger/ElectronLogger.mjs.map +1 -0
  217. package/dist/infrastructure/logger/index.d.ts +2 -0
  218. package/dist/infrastructure/logger/logger.type.d.ts +8 -0
  219. package/dist/internal/types/BrandedTypes.d.ts +64 -0
  220. package/dist/internal/types/BrandedTypes.js +54 -0
  221. package/dist/internal/types/BrandedTypes.js.map +1 -0
  222. package/dist/internal/types/BrandedTypes.mjs +54 -0
  223. package/dist/internal/types/BrandedTypes.mjs.map +1 -0
  224. package/dist/internal/types/PerformanceOptions.d.ts +87 -0
  225. package/dist/internal/types/branded.d.ts +42 -0
  226. package/dist/internal/utils/MessageDispatcher.d.ts +67 -0
  227. package/dist/internal/utils/MessageDispatcher.js +96 -0
  228. package/dist/internal/utils/MessageDispatcher.js.map +1 -0
  229. package/dist/internal/utils/MessageDispatcher.mjs +96 -0
  230. package/dist/internal/utils/MessageDispatcher.mjs.map +1 -0
  231. package/dist/internal/utils/RateLimiter.d.ts +41 -0
  232. package/dist/internal/utils/RateLimiter.js +83 -0
  233. package/dist/internal/utils/RateLimiter.js.map +1 -0
  234. package/dist/internal/utils/RateLimiter.mjs +83 -0
  235. package/dist/internal/utils/RateLimiter.mjs.map +1 -0
  236. package/dist/internal/utils/StateKeeper.d.ts +125 -0
  237. package/dist/internal/utils/StateKeeper.js +334 -0
  238. package/dist/internal/utils/StateKeeper.js.map +1 -0
  239. package/dist/internal/utils/StateKeeper.mjs +334 -0
  240. package/dist/internal/utils/StateKeeper.mjs.map +1 -0
  241. package/dist/internal/utils/branded-helpers.d.ts +33 -0
  242. package/dist/internal/utils/index.d.ts +5 -0
  243. package/dist/preload/index.d.ts +45 -0
  244. package/dist/preload/index.js +91 -0
  245. package/dist/preload/index.js.map +1 -0
  246. package/dist/preload/index.mjs +91 -0
  247. package/dist/preload/index.mjs.map +1 -0
  248. package/dist/preload/preload.type.d.ts +15 -0
  249. package/dist/types.d.ts +7 -0
  250. package/dist/types.js +1 -0
  251. package/dist/types.js.map +1 -0
  252. package/dist/types.mjs +1 -0
  253. package/dist/types.mjs.map +1 -0
  254. package/package.json +143 -0
@@ -0,0 +1,583 @@
1
+ 'use strict';var electron=require('electron'),tinyTypedEmitter=require('tiny-typed-emitter'),windowManager_schema=require('./window-manager.schema.js'),WindowStore=require('./WindowStore.js'),IpcSetup=require('./IpcSetup.js'),MetricsManager=require('./core/MetricsManager.js'),PluginExecutor=require('./core/PluginExecutor.js'),WindowLifecycle=require('./core/WindowLifecycle.js'),ElectronLogger=require('../../infrastructure/logger/ElectronLogger.js'),PerformanceMonitor=require('../../infrastructure/debug/PerformanceMonitor.js');/**
2
+ * WindowManager - Core class for managing Electron windows
3
+ * WindowManager - 管理 Electron 窗口的核心类
4
+ *
5
+ * Uses WindowStore via composition to handle window management
6
+ * 使用组合方式通过 WindowStore 处理窗口管理
7
+ */
8
+ class WindowManager extends tinyTypedEmitter.TypedEmitter {
9
+ config = {};
10
+ ipcRouter;
11
+ ipcTransport;
12
+ messageBus;
13
+ currentIpcChannel = null;
14
+ currentIpcSyncChannel = null;
15
+ logger;
16
+ // Composition: The internal WindowStore instance
17
+ // 组合:内部 WindowStore 实例
18
+ windowStore;
19
+ // Core Managers
20
+ metricsManager;
21
+ pluginExecutor;
22
+ lifecycle;
23
+ isInitialized = false;
24
+ initPromise;
25
+ initError = null;
26
+ /**
27
+ * Constructor
28
+ * 构造函数
29
+ * @param config - WindowManager configuration
30
+ */
31
+ constructor(config = {}) {
32
+ super();
33
+ // Validate config using Zod schema (Task 2)
34
+ // 使用 Zod schema 验证配置 (任务 2)
35
+ const validationResult = windowManager_schema.validateWindowManagerConfig(config);
36
+ if (!validationResult.success) {
37
+ throw new Error(`Invalid WindowManager configuration: ${validationResult.error}`);
38
+ }
39
+ this.config = validationResult.data;
40
+ this.ipcRouter = this.config.ipcRouter;
41
+ this.ipcTransport = this.config.ipcTransport;
42
+ this.messageBus = this.config.messageBus;
43
+ this.logger = this.config.logger || new ElectronLogger.ElectronLogger({ appName: 'WindowManager' });
44
+ // Runtime validation for optional dependencies
45
+ // 可选依赖的运行时验证
46
+ if (config.logger) {
47
+ const requiredMethods = ['info', 'warn', 'error', 'debug'];
48
+ for (const method of requiredMethods) {
49
+ if (typeof config.logger[method] !== 'function') {
50
+ throw new Error(`config.logger must have ${requiredMethods.join('/')} methods`);
51
+ }
52
+ }
53
+ }
54
+ if (config.ipcRouter && typeof config.ipcRouter.handle !== 'function') {
55
+ throw new Error('config.ipcRouter must have handle/addHandler methods');
56
+ }
57
+ // Initialize WindowStore with nested store configuration
58
+ // 使用嵌套的 store 配置初始化 WindowStore
59
+ this.windowStore = new WindowStore({
60
+ logger: this.logger,
61
+ ...(config.store || {}), // Spread nested store config
62
+ });
63
+ // Forward error events
64
+ this.windowStore.on('error', (err) => this.emit('error', err));
65
+ // Initialize Managers
66
+ this.metricsManager = new MetricsManager.MetricsManager();
67
+ this.pluginExecutor = new PluginExecutor.PluginExecutor(this.logger, config.plugins, config.hooks);
68
+ this.lifecycle = new WindowLifecycle.WindowLifecycle(this, this.pluginExecutor, this.metricsManager, this.logger);
69
+ // Initialize group resolver for MessageBus if available
70
+ // 如果 MessageBus 可用,初始化分组解析器
71
+ if (this.messageBus) {
72
+ this.messageBus.setGroupResolver((group) => this.windowStore.getGroup(group));
73
+ }
74
+ // Initialize plugins (Async, properly handle errors)
75
+ // 初始化插件(异步,正确处理错误)
76
+ this.initPromise = this.init()
77
+ .then(async () => {
78
+ // Auto-initialize IPC after plugins are ready
79
+ // 插件就绪后自动初始化 IPC
80
+ if (this.ipcRouter && this.config.ipc?.autoInit !== false) {
81
+ try {
82
+ this.setupIPC();
83
+ }
84
+ catch (e) {
85
+ this.logger.warn(`Auto IPC setup failed: ${e}`);
86
+ throw e;
87
+ }
88
+ }
89
+ })
90
+ .catch((err) => {
91
+ this.initError = err instanceof Error ? err : new Error(String(err));
92
+ this.logger.error(`WindowManager initialization failed: ${this.initError.message}`);
93
+ this.emit('error', this.initError);
94
+ throw this.initError;
95
+ });
96
+ }
97
+ /**
98
+ * Returns a promise that resolves when initialization is complete
99
+ * 返回一个 Promise,当初始化完成时 resolve
100
+ * @throws {Error} If initialization failed
101
+ */
102
+ async ready() {
103
+ if (this.initError) {
104
+ throw this.initError;
105
+ }
106
+ return this.initPromise;
107
+ }
108
+ /**
109
+ * Check if WindowManager is initialized
110
+ * 检查 WindowManager 是否已初始化
111
+ */
112
+ get initialized() {
113
+ return this.isInitialized && !this.initError;
114
+ }
115
+ /**
116
+ * Get initialization error if any
117
+ * 获取初始化错误(如果有)
118
+ */
119
+ get initializationError() {
120
+ return this.initError;
121
+ }
122
+ /**
123
+ * Initialize plugins
124
+ * 初始化插件
125
+ */
126
+ async init() {
127
+ if (this.isInitialized)
128
+ return;
129
+ this.isInitialized = true;
130
+ await this.pluginExecutor.initPlugins(this);
131
+ }
132
+ /**
133
+ * Register a plugin
134
+ * 注册插件
135
+ * @param plugin - Plugin instance
136
+ */
137
+ use(plugin) {
138
+ this.pluginExecutor.addPlugin(plugin);
139
+ // If already initialized, initialize the new plugin immediately
140
+ if (this.isInitialized) {
141
+ this.pluginExecutor.initPlugin(plugin, this);
142
+ }
143
+ return this;
144
+ }
145
+ /**
146
+ * Setup IPC communication
147
+ * 设置 IPC 通信
148
+ * @param options - Optional IPC configuration (可选的 IPC 配置)
149
+ */
150
+ setupIPC(options) {
151
+ let result;
152
+ if (options?.setupImpl) {
153
+ result = options.setupImpl({
154
+ config: this.config,
155
+ ipcRouter: this.ipcRouter,
156
+ currentIpcChannel: this.currentIpcChannel,
157
+ currentIpcSyncChannel: this.currentIpcSyncChannel,
158
+ options,
159
+ });
160
+ }
161
+ else if (this.config.ipcSetup) {
162
+ result = this.config.ipcSetup(this, options);
163
+ }
164
+ else {
165
+ result = IpcSetup.IpcSetup.setup({
166
+ config: this.config,
167
+ ipcRouter: this.ipcRouter,
168
+ currentIpcChannel: this.currentIpcChannel,
169
+ currentIpcSyncChannel: this.currentIpcSyncChannel,
170
+ options,
171
+ });
172
+ }
173
+ if (result) {
174
+ this.currentIpcChannel = result.channel;
175
+ this.currentIpcSyncChannel = result.syncChannel;
176
+ if (result.ipcTransport) {
177
+ this.ipcTransport = result.ipcTransport;
178
+ }
179
+ return;
180
+ }
181
+ if (!this.ipcRouter) {
182
+ throw new Error('IpcRouter instance is required for IPC setup. Please pass it to the WindowManager constructor.');
183
+ }
184
+ }
185
+ /**
186
+ * Create a new window
187
+ * 创建一个新窗口
188
+ * @param config - Configuration object (配置对象)
189
+ * @returns Window ID (窗口 ID)
190
+ */
191
+ async create(config = {}) {
192
+ const perf = PerformanceMonitor.PerformanceMonitor.getInstance();
193
+ const measureId = `window-create-${Date.now()}`;
194
+ perf.startMeasure(measureId, 'Window Creation', {
195
+ name: config.name,
196
+ width: config.width,
197
+ height: config.height,
198
+ });
199
+ try {
200
+ const windowId = await this.lifecycle.create(config);
201
+ perf.endMeasure(measureId, { status: 'success', windowId });
202
+ return windowId;
203
+ }
204
+ catch (error) {
205
+ perf.endMeasure(measureId, {
206
+ status: 'error',
207
+ error: error instanceof Error ? error.message : String(error),
208
+ });
209
+ throw error;
210
+ }
211
+ }
212
+ /**
213
+ * Remove window
214
+ * 移除窗口
215
+ * @param windowId - Window ID
216
+ */
217
+ async removeWindow(windowId) {
218
+ return this.lifecycle.removeWindow(windowId);
219
+ }
220
+ /**
221
+ * Get performance metrics
222
+ * 获取性能指标
223
+ * @returns Performance metrics object
224
+ */
225
+ getMetrics() {
226
+ return this.metricsManager.getMetrics(this.getWindowCount());
227
+ }
228
+ /**
229
+ * Dispose all resources
230
+ * 释放所有资源
231
+ */
232
+ dispose() {
233
+ this.logger.info('Disposing WindowManager...');
234
+ // 1. 清理所有窗口 (先关闭窗口,再清理 Store)
235
+ const windowIds = this.getAllWindowKeys();
236
+ windowIds.forEach((id) => {
237
+ try {
238
+ this.removeWindow(id);
239
+ }
240
+ catch (error) {
241
+ this.logger.error(`Failed to remove window ${id}: ${error}`);
242
+ }
243
+ });
244
+ // 2. Dispose WindowStore (stops cleanup timer & clears registry)
245
+ this.windowStore.dispose();
246
+ // 3. 清理 IPC
247
+ if (this.ipcTransport) {
248
+ this.ipcTransport.removeAllHandlers();
249
+ this.ipcTransport.removeAllListeners();
250
+ }
251
+ if (this.ipcRouter && typeof this.ipcRouter.dispose === 'function') {
252
+ this.ipcRouter.dispose();
253
+ }
254
+ // 4. 移除所有事件监听器
255
+ this.removeAllListeners();
256
+ this.logger.info('WindowManager disposed');
257
+ }
258
+ getMainWindowId() {
259
+ return this.windowStore.mainWindow
260
+ ? this.windowStore.getWindowId(this.windowStore.mainWindow)
261
+ : undefined;
262
+ }
263
+ createBrowserWindow(config) {
264
+ const defaultConfig = this.getDefaultWindowConfig();
265
+ return new electron.BrowserWindow({ ...defaultConfig, ...config });
266
+ }
267
+ getDefaultWindowConfig() {
268
+ return (this.config.defaultConfig || {
269
+ width: 800,
270
+ height: 600,
271
+ show: false,
272
+ webPreferences: {
273
+ nodeIntegration: false,
274
+ contextIsolation: true,
275
+ },
276
+ });
277
+ }
278
+ configureWindowBehavior(window, windowId) {
279
+ if (this.config.isDevelopment) {
280
+ this.windowStore.openDevTools(windowId);
281
+ }
282
+ if (this.config.preventExternalLinks !== false) {
283
+ window.webContents.setWindowOpenHandler((details) => {
284
+ electron.shell.openExternal(details.url);
285
+ return { action: 'deny' };
286
+ });
287
+ }
288
+ window.once('ready-to-show', () => this.windowStore.show(window, windowId));
289
+ window.on('closed', () => {
290
+ this.windowStore.removeFocus(windowId);
291
+ this.removeWindow(windowId);
292
+ });
293
+ // Handle render process crash
294
+ // 处理渲染进程崩溃
295
+ window.webContents.on('render-process-gone', (event, details) => {
296
+ this.logger.error(`Window ${windowId} crashed: ${details.reason} (Exit Code: ${details.exitCode})`);
297
+ const { reason } = details;
298
+ // Attempt to reload for non-fatal crashes
299
+ // 对于非致命崩溃尝试重新加载
300
+ if (reason === 'crashed' || reason === 'oom') {
301
+ this.logger.info(`Attempting to reload window ${windowId}...`);
302
+ // Give it a small delay before reload
303
+ setTimeout(() => {
304
+ if (!window.isDestroyed()) {
305
+ window.reload();
306
+ }
307
+ }, 1000);
308
+ }
309
+ });
310
+ // Handle unresponsive window
311
+ // 处理窗口无响应
312
+ window.on('unresponsive', () => {
313
+ this.logger.warn(`Window ${windowId} is unresponsive`);
314
+ });
315
+ // Track Focus
316
+ // 追踪焦点
317
+ window.on('focus', () => {
318
+ this.windowStore.pushFocus(windowId);
319
+ });
320
+ // Also push focus immediately on creation if window is shown
321
+ // 如果窗口显示,创建时也立即推入焦点
322
+ if (window.isVisible() && window.isFocused()) {
323
+ this.windowStore.pushFocus(windowId);
324
+ }
325
+ }
326
+ // ========================================================================================
327
+ // Group Management API
328
+ // 窗口组管理 API
329
+ // ========================================================================================
330
+ /**
331
+ * Join a window to a group
332
+ * 将窗口加入组
333
+ */
334
+ joinGroup(windowId, group) {
335
+ this.windowStore.joinGroup(windowId, group);
336
+ }
337
+ /**
338
+ * Leave a window from a group
339
+ * 将窗口移出组
340
+ */
341
+ leaveGroup(windowId, group) {
342
+ this.windowStore.leaveGroup(windowId, group);
343
+ }
344
+ /**
345
+ * Get all window IDs in a group
346
+ * 获取组内所有窗口 ID
347
+ */
348
+ getGroup(group) {
349
+ return this.windowStore.getGroup(group);
350
+ }
351
+ /**
352
+ * Close all windows in a group
353
+ * 关闭组内所有窗口
354
+ */
355
+ async closeGroup(group) {
356
+ await this.windowStore.closeGroup(group);
357
+ }
358
+ /**
359
+ * Hide all windows in a group
360
+ * 隐藏组内所有窗口
361
+ */
362
+ hideGroup(group) {
363
+ this.windowStore.hideGroup(group);
364
+ }
365
+ /**
366
+ * Show all windows in a group
367
+ * 显示组内所有窗口
368
+ */
369
+ showGroup(group) {
370
+ this.windowStore.showGroup(group);
371
+ }
372
+ /**
373
+ * Focus all windows in a group
374
+ * 聚焦组内所有窗口
375
+ */
376
+ focusGroup(group) {
377
+ this.windowStore.focusGroup(group);
378
+ }
379
+ /**
380
+ * Send message to all windows in a group via MessageBus
381
+ * 通过 MessageBus 向组内所有窗口发送消息
382
+ * @param group - Group name (组名)
383
+ * @param channel - Channel name (频道名称)
384
+ * @param data - Message data (消息数据)
385
+ * @returns Number of successful sends (成功发送的数量)
386
+ */
387
+ sendToGroup(group, channel, data) {
388
+ if (!this.messageBus) {
389
+ this.logger.warn('[WindowManager.sendToGroup] MessageBus not configured');
390
+ return 0;
391
+ }
392
+ const ids = this.windowStore.getGroup(group);
393
+ return this.messageBus.broadcastToWindows(ids, channel, data);
394
+ }
395
+ /**
396
+ * Focus previous window in history
397
+ * 聚焦历史记录中的上一个窗口
398
+ */
399
+ focusPrevious() {
400
+ const previousId = this.windowStore.getPreviousFocusedWindow();
401
+ if (previousId) {
402
+ this.windowStore.focus(previousId);
403
+ }
404
+ }
405
+ // ========================================================================================
406
+ // Validation Helpers
407
+ // 验证辅助函数
408
+ // ========================================================================================
409
+ validateWindowId(windowId, methodName) {
410
+ if (!windowId || typeof windowId !== 'string' || windowId.trim() === '') {
411
+ throw new Error(`[WindowManager.${methodName}] Invalid windowId: must be a non-empty string`);
412
+ }
413
+ return windowId;
414
+ }
415
+ // ========================================================================================
416
+ // Delegated Methods from WindowStore
417
+ // ========================================================================================
418
+ show(window, windowId) {
419
+ if (!window || window.isDestroyed()) {
420
+ this.logger.warn('[WindowManager.show] Window is null or destroyed');
421
+ return;
422
+ }
423
+ // If windowId is provided, validate it. If not, it's optional in signature but good to check.
424
+ if (windowId !== undefined) {
425
+ this.validateWindowId(windowId, 'show');
426
+ }
427
+ this.windowStore.show(window, windowId);
428
+ }
429
+ hide(windowId) {
430
+ this.windowStore.hide(this.validateWindowId(windowId, 'hide'));
431
+ }
432
+ isDestroyed(windowId) {
433
+ // isDestroyed should be safe to call even with invalid ID (returns false)
434
+ // but validateWindowId ensures we don't pass garbage
435
+ return this.windowStore.isDestroyed(this.validateWindowId(windowId, 'isDestroyed'));
436
+ }
437
+ isVisible(windowId) {
438
+ return this.windowStore.isVisible(this.validateWindowId(windowId, 'isVisible'));
439
+ }
440
+ isMinimized(windowId) {
441
+ return this.windowStore.isMinimized(this.validateWindowId(windowId, 'isMinimized'));
442
+ }
443
+ isMaximized(windowId) {
444
+ return this.windowStore.isMaximized(this.validateWindowId(windowId, 'isMaximized'));
445
+ }
446
+ fullScreenState(windowId) {
447
+ return this.windowStore.fullScreenState(this.validateWindowId(windowId, 'fullScreenState'));
448
+ }
449
+ minimize(windowId) {
450
+ if (windowId)
451
+ this.validateWindowId(windowId, 'minimize');
452
+ this.windowStore.minimize(windowId);
453
+ }
454
+ restore(windowId) {
455
+ this.windowStore.restore(this.validateWindowId(windowId, 'restore'));
456
+ }
457
+ maximize(windowId) {
458
+ this.windowStore.maximize(this.validateWindowId(windowId, 'maximize'));
459
+ }
460
+ unmaximize(windowId) {
461
+ this.windowStore.unmaximize(this.validateWindowId(windowId, 'unmaximize'));
462
+ }
463
+ fullScreen(windowId) {
464
+ this.windowStore.fullScreen(this.validateWindowId(windowId, 'fullScreen'));
465
+ }
466
+ focus(windowId) {
467
+ this.windowStore.focus(this.validateWindowId(windowId, 'focus'));
468
+ }
469
+ setMovable(window) {
470
+ if (!window || window.isDestroyed())
471
+ return;
472
+ this.windowStore.setMovable(window);
473
+ }
474
+ /**
475
+ * Close a window
476
+ * 关闭窗口
477
+ * @param windowId - Window ID (窗口 ID)
478
+ */
479
+ close(windowId) {
480
+ this.windowStore.winClose(this.validateWindowId(windowId, 'close'));
481
+ }
482
+ /**
483
+ * @deprecated Use close() instead
484
+ * @deprecated 使用 close() 代替
485
+ */
486
+ winClose(windowId) {
487
+ this.close(windowId);
488
+ }
489
+ openDevTools(windowId) {
490
+ this.windowStore.openDevTools(this.validateWindowId(windowId, 'openDevTools'));
491
+ }
492
+ isDevToolsOpened(windowId) {
493
+ return this.windowStore.isDevToolsOpened(this.validateWindowId(windowId, 'isDevToolsOpened'));
494
+ }
495
+ closeDevTools(windowId) {
496
+ this.windowStore.closeDevTools(this.validateWindowId(windowId, 'closeDevTools'));
497
+ }
498
+ quit() {
499
+ this.windowStore.quit();
500
+ }
501
+ getWindowSize() {
502
+ return this.windowStore.getWindowSize();
503
+ }
504
+ send(windowId, name, data = '') {
505
+ this.windowStore.send(windowId, name, data);
506
+ }
507
+ setSkipTaskbar(windowId, bool) {
508
+ this.windowStore.setSkipTaskbar(windowId, bool);
509
+ }
510
+ // Property Accessors (Delegated)
511
+ get mainWindow() {
512
+ return this.windowStore.mainWindow;
513
+ }
514
+ getWindowCount() {
515
+ return this.windowStore.getWindowCount();
516
+ }
517
+ getAllWindowKeys() {
518
+ return this.windowStore.getAllWindowKeys();
519
+ }
520
+ getAllWindows() {
521
+ return this.windowStore.getAllWindows();
522
+ }
523
+ getWindowNames() {
524
+ return this.windowStore.getWindowNames();
525
+ }
526
+ getNameByWindowId(windowId) {
527
+ return this.windowStore.getNameByWindowId(windowId);
528
+ }
529
+ getWindowByNameId(name) {
530
+ return this.windowStore.getWindowByNameId(name);
531
+ }
532
+ getWindowByName(name) {
533
+ return this.windowStore.getWindowByName(name);
534
+ }
535
+ hasByName(proposedName) {
536
+ return this.windowStore.hasByName(proposedName);
537
+ }
538
+ deleteByName(proposedName) {
539
+ return this.windowStore.deleteByName(proposedName);
540
+ }
541
+ getWindowById(windowId) {
542
+ return this.windowStore.getWindowById(windowId);
543
+ }
544
+ hasById(windowId) {
545
+ return this.windowStore.hasById(windowId);
546
+ }
547
+ deleteById(windowId) {
548
+ return this.windowStore.deleteById(windowId);
549
+ }
550
+ getWindowId(window) {
551
+ return this.windowStore.getWindowId(window);
552
+ }
553
+ updateWindowName(windowId, newName) {
554
+ this.windowStore.updateWindowName(windowId, newName);
555
+ }
556
+ // Helpers
557
+ getTargetWindow(windowId) {
558
+ return this.windowStore.getTargetWindow(windowId);
559
+ }
560
+ getValidWindow(windowId) {
561
+ return this.windowStore.getValidWindow(windowId);
562
+ }
563
+ getCurrentWindow() {
564
+ return this.windowStore.getCurrentWindow();
565
+ }
566
+ // Context Management
567
+ async saveWindowContext(windowId, context) {
568
+ await this.windowStore.saveWindowContext(windowId, context);
569
+ }
570
+ async loadWindowContext(windowId) {
571
+ return await this.windowStore.loadWindowContext(windowId);
572
+ }
573
+ async clearWindowContext(windowId) {
574
+ await this.windowStore.clearWindowContext(windowId);
575
+ }
576
+ // Cleanup
577
+ startCleanupProtection(intervalMs = 30000) {
578
+ this.windowStore.startCleanupProtection(intervalMs);
579
+ }
580
+ stopCleanupProtection() {
581
+ this.windowStore.stopCleanupProtection();
582
+ }
583
+ }module.exports=WindowManager;//# sourceMappingURL=WindowManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WindowManager.js","sources":["../../../src/core/window/WindowManager.ts"],"sourcesContent":["import { BrowserWindow, shell, BrowserWindowConstructorOptions } from 'electron';\nimport { TypedEmitter } from 'tiny-typed-emitter';\nimport { Logger, ILogger } from '@/infrastructure/logger';\nimport { validateWindowManagerConfig } from './window-manager.schema';\nimport WindowStore from './WindowStore';\nimport type {\n WindowManagerConfig,\n WindowManagerPlugin,\n WindowCreationOptions,\n WindowManagerEvents,\n} from './window-manager.type';\nimport type IpcRouter from '@/core/ipc/IpcRouter';\nimport type { IIpcTransport } from '@/core/ipc/transport/ipc.type';\nimport type { MessageBus } from '@/core/message-bus/MessageBus';\nimport { IpcSetup } from './IpcSetup';\nimport { MetricsManager } from './core/MetricsManager';\nimport { PluginExecutor } from './core/PluginExecutor';\nimport { WindowLifecycle } from './core/WindowLifecycle';\nimport { PerformanceMonitor } from '@/infrastructure/debug';\n\n/**\n * WindowManager - Core class for managing Electron windows\n * WindowManager - 管理 Electron 窗口的核心类\n *\n * Uses WindowStore via composition to handle window management\n * 使用组合方式通过 WindowStore 处理窗口管理\n */\nexport default class WindowManager extends TypedEmitter<WindowManagerEvents> {\n public config: WindowManagerConfig = {};\n public ipcRouter?: IpcRouter;\n public ipcTransport?: IIpcTransport;\n public messageBus?: MessageBus;\n protected currentIpcChannel: string | null = null;\n protected currentIpcSyncChannel: string | null = null;\n public logger: ILogger;\n\n // Composition: The internal WindowStore instance\n // 组合:内部 WindowStore 实例\n public readonly windowStore: WindowStore;\n\n // Core Managers\n protected metricsManager: MetricsManager;\n protected pluginExecutor: PluginExecutor;\n protected lifecycle: WindowLifecycle;\n\n private isInitialized = false;\n private initPromise: Promise<void>;\n private initError: Error | null = null;\n\n /**\n * Constructor\n * 构造函数\n * @param config - WindowManager configuration\n */\n constructor(config: WindowManagerConfig = {}) {\n super();\n // Validate config using Zod schema (Task 2)\n // 使用 Zod schema 验证配置 (任务 2)\n const validationResult = validateWindowManagerConfig(config);\n if (!validationResult.success) {\n throw new Error(`Invalid WindowManager configuration: ${validationResult.error}`);\n }\n this.config = validationResult.data as WindowManagerConfig;\n\n this.ipcRouter = this.config.ipcRouter;\n this.ipcTransport = this.config.ipcTransport;\n this.messageBus = this.config.messageBus;\n this.logger = this.config.logger || new Logger({ appName: 'WindowManager' });\n\n // Runtime validation for optional dependencies\n // 可选依赖的运行时验证\n if (config.logger) {\n const requiredMethods = ['info', 'warn', 'error', 'debug'];\n for (const method of requiredMethods) {\n if (typeof (config.logger as any)[method] !== 'function') {\n throw new Error(`config.logger must have ${requiredMethods.join('/')} methods`);\n }\n }\n }\n if (config.ipcRouter && typeof config.ipcRouter.handle !== 'function') {\n throw new Error('config.ipcRouter must have handle/addHandler methods');\n }\n\n // Initialize WindowStore with nested store configuration\n // 使用嵌套的 store 配置初始化 WindowStore\n this.windowStore = new WindowStore({\n logger: this.logger,\n ...(config.store || {}), // Spread nested store config\n });\n\n // Forward error events\n this.windowStore.on('error', (err) => this.emit('error', err));\n\n // Initialize Managers\n this.metricsManager = new MetricsManager();\n this.pluginExecutor = new PluginExecutor(this.logger, config.plugins, config.hooks);\n this.lifecycle = new WindowLifecycle(\n this,\n this.pluginExecutor,\n this.metricsManager,\n this.logger\n );\n\n // Initialize group resolver for MessageBus if available\n // 如果 MessageBus 可用,初始化分组解析器\n if (this.messageBus) {\n this.messageBus.setGroupResolver((group) => this.windowStore.getGroup(group));\n }\n\n // Initialize plugins (Async, properly handle errors)\n // 初始化插件(异步,正确处理错误)\n this.initPromise = this.init()\n .then(async () => {\n // Auto-initialize IPC after plugins are ready\n // 插件就绪后自动初始化 IPC\n if (this.ipcRouter && this.config.ipc?.autoInit !== false) {\n try {\n this.setupIPC();\n } catch (e) {\n this.logger.warn(`Auto IPC setup failed: ${e}`);\n throw e;\n }\n }\n })\n .catch((err) => {\n this.initError = err instanceof Error ? err : new Error(String(err));\n this.logger.error(`WindowManager initialization failed: ${this.initError.message}`);\n this.emit('error', this.initError);\n throw this.initError;\n });\n }\n\n /**\n * Returns a promise that resolves when initialization is complete\n * 返回一个 Promise,当初始化完成时 resolve\n * @throws {Error} If initialization failed\n */\n public async ready(): Promise<void> {\n if (this.initError) {\n throw this.initError;\n }\n return this.initPromise;\n }\n\n /**\n * Check if WindowManager is initialized\n * 检查 WindowManager 是否已初始化\n */\n public get initialized(): boolean {\n return this.isInitialized && !this.initError;\n }\n\n /**\n * Get initialization error if any\n * 获取初始化错误(如果有)\n */\n public get initializationError(): Error | null {\n return this.initError;\n }\n\n /**\n * Initialize plugins\n * 初始化插件\n */\n private async init(): Promise<void> {\n if (this.isInitialized) return;\n this.isInitialized = true;\n await this.pluginExecutor.initPlugins(this);\n }\n\n /**\n * Register a plugin\n * 注册插件\n * @param plugin - Plugin instance\n */\n public use(plugin: WindowManagerPlugin): this {\n this.pluginExecutor.addPlugin(plugin);\n\n // If already initialized, initialize the new plugin immediately\n if (this.isInitialized) {\n this.pluginExecutor.initPlugin(plugin, this);\n }\n\n return this;\n }\n\n /**\n * Setup IPC communication\n * 设置 IPC 通信\n * @param options - Optional IPC configuration (可选的 IPC 配置)\n */\n public setupIPC(options?: {\n channel?: string;\n syncChannel?: string;\n setupImpl?: typeof IpcSetup.setup;\n }): void {\n let result: { channel: string; syncChannel: string; ipcTransport?: IIpcTransport };\n\n if (options?.setupImpl) {\n result = options.setupImpl({\n config: this.config,\n ipcRouter: this.ipcRouter!,\n currentIpcChannel: this.currentIpcChannel,\n currentIpcSyncChannel: this.currentIpcSyncChannel,\n options,\n });\n } else if (this.config.ipcSetup) {\n result = this.config.ipcSetup(this, options);\n } else {\n result = IpcSetup.setup({\n config: this.config,\n ipcRouter: this.ipcRouter!,\n currentIpcChannel: this.currentIpcChannel,\n currentIpcSyncChannel: this.currentIpcSyncChannel,\n options,\n });\n }\n\n if (result) {\n this.currentIpcChannel = result.channel;\n this.currentIpcSyncChannel = result.syncChannel;\n if (result.ipcTransport) {\n this.ipcTransport = result.ipcTransport;\n }\n return;\n }\n\n if (!this.ipcRouter) {\n throw new Error(\n 'IpcRouter instance is required for IPC setup. Please pass it to the WindowManager constructor.'\n );\n }\n }\n\n /**\n * Create a new window\n * 创建一个新窗口\n * @param config - Configuration object (配置对象)\n * @returns Window ID (窗口 ID)\n */\n async create(config: WindowCreationOptions = {}): Promise<string> {\n const perf = PerformanceMonitor.getInstance();\n const measureId = `window-create-${Date.now()}`;\n\n perf.startMeasure(measureId, 'Window Creation', {\n name: config.name,\n width: config.width,\n height: config.height,\n });\n\n try {\n const windowId = await this.lifecycle.create(config);\n perf.endMeasure(measureId, { status: 'success', windowId });\n return windowId;\n } catch (error) {\n perf.endMeasure(measureId, {\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n\n /**\n * Remove window\n * 移除窗口\n * @param windowId - Window ID\n */\n public async removeWindow(windowId: string): Promise<void> {\n return this.lifecycle.removeWindow(windowId);\n }\n\n /**\n * Get performance metrics\n * 获取性能指标\n * @returns Performance metrics object\n */\n public getMetrics() {\n return this.metricsManager.getMetrics(this.getWindowCount());\n }\n\n /**\n * Dispose all resources\n * 释放所有资源\n */\n public dispose(): void {\n this.logger.info('Disposing WindowManager...');\n\n // 1. 清理所有窗口 (先关闭窗口,再清理 Store)\n const windowIds = this.getAllWindowKeys();\n windowIds.forEach((id) => {\n try {\n this.removeWindow(id);\n } catch (error) {\n this.logger.error(`Failed to remove window ${id}: ${error}`);\n }\n });\n\n // 2. Dispose WindowStore (stops cleanup timer & clears registry)\n this.windowStore.dispose();\n\n // 3. 清理 IPC\n if (this.ipcTransport) {\n this.ipcTransport.removeAllHandlers();\n this.ipcTransport.removeAllListeners();\n }\n\n if (this.ipcRouter && typeof (this.ipcRouter as any).dispose === 'function') {\n (this.ipcRouter as any).dispose();\n }\n\n // 4. 移除所有事件监听器\n this.removeAllListeners();\n\n this.logger.info('WindowManager disposed');\n }\n\n private getMainWindowId(): string | undefined {\n return this.windowStore.mainWindow\n ? this.windowStore.getWindowId(this.windowStore.mainWindow)\n : undefined;\n }\n\n public createBrowserWindow(config?: BrowserWindowConstructorOptions): BrowserWindow {\n const defaultConfig = this.getDefaultWindowConfig();\n return new BrowserWindow({ ...defaultConfig, ...config });\n }\n\n protected getDefaultWindowConfig(): BrowserWindowConstructorOptions {\n return (\n this.config.defaultConfig || {\n width: 800,\n height: 600,\n show: false,\n webPreferences: {\n nodeIntegration: false,\n contextIsolation: true,\n },\n }\n );\n }\n\n public configureWindowBehavior(window: BrowserWindow, windowId: string): void {\n if (this.config.isDevelopment) {\n this.windowStore.openDevTools(windowId);\n }\n\n if (this.config.preventExternalLinks !== false) {\n window.webContents.setWindowOpenHandler((details) => {\n shell.openExternal(details.url);\n return { action: 'deny' };\n });\n }\n\n window.once('ready-to-show', () => this.windowStore.show(window, windowId));\n\n window.on('closed', () => {\n this.windowStore.removeFocus(windowId);\n this.removeWindow(windowId);\n });\n\n // Handle render process crash\n // 处理渲染进程崩溃\n window.webContents.on('render-process-gone', (event, details) => {\n this.logger.error(\n `Window ${windowId} crashed: ${details.reason} (Exit Code: ${details.exitCode})`\n );\n\n const { reason } = details;\n\n // Attempt to reload for non-fatal crashes\n // 对于非致命崩溃尝试重新加载\n if (reason === 'crashed' || reason === 'oom') {\n this.logger.info(`Attempting to reload window ${windowId}...`);\n // Give it a small delay before reload\n setTimeout(() => {\n if (!window.isDestroyed()) {\n window.reload();\n }\n }, 1000);\n }\n });\n\n // Handle unresponsive window\n // 处理窗口无响应\n window.on('unresponsive', () => {\n this.logger.warn(`Window ${windowId} is unresponsive`);\n });\n\n // Track Focus\n // 追踪焦点\n window.on('focus', () => {\n this.windowStore.pushFocus(windowId);\n });\n\n // Also push focus immediately on creation if window is shown\n // 如果窗口显示,创建时也立即推入焦点\n if (window.isVisible() && window.isFocused()) {\n this.windowStore.pushFocus(windowId);\n }\n }\n\n // ========================================================================================\n // Group Management API\n // 窗口组管理 API\n // ========================================================================================\n\n /**\n * Join a window to a group\n * 将窗口加入组\n */\n joinGroup(windowId: string, group: string): void {\n this.windowStore.joinGroup(windowId, group);\n }\n\n /**\n * Leave a window from a group\n * 将窗口移出组\n */\n leaveGroup(windowId: string, group: string): void {\n this.windowStore.leaveGroup(windowId, group);\n }\n\n /**\n * Get all window IDs in a group\n * 获取组内所有窗口 ID\n */\n getGroup(group: string): string[] {\n return this.windowStore.getGroup(group);\n }\n\n /**\n * Close all windows in a group\n * 关闭组内所有窗口\n */\n async closeGroup(group: string): Promise<void> {\n await this.windowStore.closeGroup(group);\n }\n\n /**\n * Hide all windows in a group\n * 隐藏组内所有窗口\n */\n hideGroup(group: string): void {\n this.windowStore.hideGroup(group);\n }\n\n /**\n * Show all windows in a group\n * 显示组内所有窗口\n */\n showGroup(group: string): void {\n this.windowStore.showGroup(group);\n }\n\n /**\n * Focus all windows in a group\n * 聚焦组内所有窗口\n */\n focusGroup(group: string): void {\n this.windowStore.focusGroup(group);\n }\n\n /**\n * Send message to all windows in a group via MessageBus\n * 通过 MessageBus 向组内所有窗口发送消息\n * @param group - Group name (组名)\n * @param channel - Channel name (频道名称)\n * @param data - Message data (消息数据)\n * @returns Number of successful sends (成功发送的数量)\n */\n sendToGroup(group: string, channel: string, data: any): number {\n if (!this.messageBus) {\n this.logger.warn('[WindowManager.sendToGroup] MessageBus not configured');\n return 0;\n }\n const ids = this.windowStore.getGroup(group);\n return this.messageBus.broadcastToWindows(ids, channel, data);\n }\n\n /**\n * Focus previous window in history\n * 聚焦历史记录中的上一个窗口\n */\n focusPrevious(): void {\n const previousId = this.windowStore.getPreviousFocusedWindow();\n if (previousId) {\n this.windowStore.focus(previousId);\n }\n }\n\n // ========================================================================================\n // Validation Helpers\n // 验证辅助函数\n // ========================================================================================\n\n public validateWindowId(windowId: string | undefined | null, methodName: string): string {\n if (!windowId || typeof windowId !== 'string' || windowId.trim() === '') {\n throw new Error(`[WindowManager.${methodName}] Invalid windowId: must be a non-empty string`);\n }\n return windowId;\n }\n\n // ========================================================================================\n // Delegated Methods from WindowStore\n // ========================================================================================\n\n show(window: BrowserWindow, windowId?: string): void {\n if (!window || window.isDestroyed()) {\n this.logger.warn('[WindowManager.show] Window is null or destroyed');\n return;\n }\n // If windowId is provided, validate it. If not, it's optional in signature but good to check.\n if (windowId !== undefined) {\n this.validateWindowId(windowId, 'show');\n }\n this.windowStore.show(window, windowId);\n }\n\n hide(windowId: string): void {\n this.windowStore.hide(this.validateWindowId(windowId, 'hide'));\n }\n\n isDestroyed(windowId: string): boolean {\n // isDestroyed should be safe to call even with invalid ID (returns false)\n // but validateWindowId ensures we don't pass garbage\n return this.windowStore.isDestroyed(this.validateWindowId(windowId, 'isDestroyed'));\n }\n\n isVisible(windowId: string): boolean {\n return this.windowStore.isVisible(this.validateWindowId(windowId, 'isVisible'));\n }\n\n isMinimized(windowId: string): boolean {\n return this.windowStore.isMinimized(this.validateWindowId(windowId, 'isMinimized'));\n }\n\n isMaximized(windowId: string): boolean {\n return this.windowStore.isMaximized(this.validateWindowId(windowId, 'isMaximized'));\n }\n\n fullScreenState(windowId: string): boolean {\n return this.windowStore.fullScreenState(this.validateWindowId(windowId, 'fullScreenState'));\n }\n\n minimize(windowId?: string): void {\n if (windowId) this.validateWindowId(windowId, 'minimize');\n this.windowStore.minimize(windowId);\n }\n\n restore(windowId: string): void {\n this.windowStore.restore(this.validateWindowId(windowId, 'restore'));\n }\n\n maximize(windowId: string): void {\n this.windowStore.maximize(this.validateWindowId(windowId, 'maximize'));\n }\n\n unmaximize(windowId: string): void {\n this.windowStore.unmaximize(this.validateWindowId(windowId, 'unmaximize'));\n }\n\n fullScreen(windowId: string): void {\n this.windowStore.fullScreen(this.validateWindowId(windowId, 'fullScreen'));\n }\n\n focus(windowId: string): void {\n this.windowStore.focus(this.validateWindowId(windowId, 'focus'));\n }\n\n setMovable(window: BrowserWindow): void {\n if (!window || window.isDestroyed()) return;\n this.windowStore.setMovable(window);\n }\n\n /**\n * Close a window\n * 关闭窗口\n * @param windowId - Window ID (窗口 ID)\n */\n close(windowId: string): void {\n this.windowStore.winClose(this.validateWindowId(windowId, 'close'));\n }\n\n /**\n * @deprecated Use close() instead\n * @deprecated 使用 close() 代替\n */\n winClose(windowId: string): void {\n this.close(windowId);\n }\n\n openDevTools(windowId: string): void {\n this.windowStore.openDevTools(this.validateWindowId(windowId, 'openDevTools'));\n }\n\n isDevToolsOpened(windowId: string): boolean {\n return this.windowStore.isDevToolsOpened(this.validateWindowId(windowId, 'isDevToolsOpened'));\n }\n\n closeDevTools(windowId: string): void {\n this.windowStore.closeDevTools(this.validateWindowId(windowId, 'closeDevTools'));\n }\n\n quit(): void {\n this.windowStore.quit();\n }\n\n getWindowSize(): { width: number; height: number } {\n return this.windowStore.getWindowSize();\n }\n\n send(windowId: string, name: string, data: unknown = ''): void {\n this.windowStore.send(windowId, name, data);\n }\n\n setSkipTaskbar(windowId: string, bool: boolean): void {\n this.windowStore.setSkipTaskbar(windowId, bool);\n }\n\n // Property Accessors (Delegated)\n\n public get mainWindow(): BrowserWindow | null {\n return this.windowStore.mainWindow;\n }\n\n getWindowCount(): number {\n return this.windowStore.getWindowCount();\n }\n\n getAllWindowKeys(): string[] {\n return this.windowStore.getAllWindowKeys();\n }\n\n getAllWindows(): BrowserWindow[] {\n return this.windowStore.getAllWindows();\n }\n\n getWindowNames(): Map<string, string> {\n return this.windowStore.getWindowNames();\n }\n\n getNameByWindowId(windowId: string): string | undefined {\n return this.windowStore.getNameByWindowId(windowId);\n }\n\n getWindowByNameId(name: string): string | undefined {\n return this.windowStore.getWindowByNameId(name);\n }\n\n getWindowByName(name: string): BrowserWindow | undefined {\n return this.windowStore.getWindowByName(name);\n }\n\n hasByName(proposedName: string): boolean {\n return this.windowStore.hasByName(proposedName);\n }\n\n deleteByName(proposedName: string): boolean {\n return this.windowStore.deleteByName(proposedName);\n }\n\n getWindowById(windowId: string): BrowserWindow | undefined {\n return this.windowStore.getWindowById(windowId);\n }\n\n hasById(windowId: string): boolean {\n return this.windowStore.hasById(windowId);\n }\n\n deleteById(windowId: string): boolean {\n return this.windowStore.deleteById(windowId);\n }\n\n getWindowId(window: BrowserWindow): string | undefined {\n return this.windowStore.getWindowId(window);\n }\n\n updateWindowName(windowId: string, newName: string): void {\n this.windowStore.updateWindowName(windowId, newName);\n }\n\n // Helpers\n\n getTargetWindow(windowId?: string): BrowserWindow | undefined {\n return this.windowStore.getTargetWindow(windowId);\n }\n\n getValidWindow(windowId?: string): BrowserWindow | undefined {\n return this.windowStore.getValidWindow(windowId);\n }\n\n getCurrentWindow(): BrowserWindow | undefined {\n return this.windowStore.getCurrentWindow();\n }\n\n // Context Management\n\n async saveWindowContext(windowId: string, context: any): Promise<void> {\n await this.windowStore.saveWindowContext(windowId, context);\n }\n\n async loadWindowContext(windowId: string): Promise<any> {\n return await this.windowStore.loadWindowContext(windowId);\n }\n\n async clearWindowContext(windowId: string): Promise<void> {\n await this.windowStore.clearWindowContext(windowId);\n }\n\n // Cleanup\n\n public startCleanupProtection(intervalMs: number = 30000): void {\n this.windowStore.startCleanupProtection(intervalMs);\n }\n\n public stopCleanupProtection(): void {\n this.windowStore.stopCleanupProtection();\n }\n}\n"],"names":["TypedEmitter","validateWindowManagerConfig","Logger","MetricsManager","PluginExecutor","WindowLifecycle","IpcSetup","PerformanceMonitor","BrowserWindow","shell"],"mappings":"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"}