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 @@
1
+ {"version":3,"file":"ConfigManager.js","sources":["../../../src/infrastructure/config/ConfigManager.ts"],"sourcesContent":["import { app } from 'electron';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { TypedEmitter } from 'tiny-typed-emitter';\nimport { ILogger, Logger } from '@/infrastructure/logger';\nimport { z } from 'zod';\n\n/**\n * Config Manager Events\n * 配置管理器事件\n */\nexport interface ConfigManagerEvents {\n /**\n * Emitted when a configuration value changes\n * 当配置值发生变化时触发\n */\n change: (key: string, newValue: any, oldValue: any) => void;\n /**\n * Emitted when configuration is loaded from disk\n * 当配置从磁盘加载时触发\n */\n loaded: (config: Record<string, any>) => void;\n /**\n * Emitted when configuration is saved to disk\n * 当配置保存到磁盘时触发\n */\n saved: () => void;\n /**\n * Emitted when an error occurs\n * 当发生错误时触发\n */\n error: (error: Error) => void;\n}\n\n/**\n * Config Manager Options\n * 配置管理器选项\n */\nexport interface ConfigManagerOptions {\n /**\n * Configuration filename (default: 'config.json')\n * 配置文件名 (默认: 'config.json')\n */\n filename?: string;\n /**\n * Logger instance\n * 日志实例\n */\n logger?: ILogger;\n /**\n * Whether to automatically save on changes (default: true)\n * 是否在更改时自动保存 (默认: true)\n */\n autoSave?: boolean;\n /**\n * Save delay in milliseconds (debounce) (default: 100)\n * 保存延迟(毫秒,防抖) (默认: 100)\n */\n saveDelay?: number;\n /**\n * Zod schema for validation\n * 用于校验的 Zod schema\n */\n schema?: z.ZodType<any>;\n}\n\n/**\n * Config Manager\n * 配置管理器\n *\n * Manages application configuration with persistence and type safety support.\n * 管理具有持久化和类型安全支持的应用程序配置。\n */\nexport class ConfigManager extends TypedEmitter<ConfigManagerEvents> {\n private config: Record<string, any> = {};\n private filePath: string;\n private logger: ILogger;\n private autoSave: boolean;\n private saveTimer: NodeJS.Timeout | null = null;\n private saveDelay: number;\n private schema?: z.ZodType<any>;\n\n /**\n * Create ConfigManager instance\n * 创建 ConfigManager 实例\n */\n constructor(options: ConfigManagerOptions = {}) {\n super();\n this.logger = options.logger || new Logger({ appName: 'ConfigManager' });\n this.autoSave = options.autoSave ?? true;\n this.saveDelay = options.saveDelay || 100;\n this.schema = options.schema;\n\n const userDataPath = app.getPath('userData');\n this.filePath = path.join(userDataPath, options.filename || 'config.json');\n\n this.load();\n }\n\n /**\n * Get configuration value\n * 获取配置值\n *\n * @param key Dot-notation key (e.g., 'ui.theme') / 点符号键 (如 'ui.theme')\n * @param defaultValue Default value if key not found / 如果键未找到的默认值\n */\n public get<T>(key: string, defaultValue?: T): T {\n const value = this.getDeep(this.config, key);\n return value === undefined ? (defaultValue as T) : value;\n }\n\n /**\n * Set configuration value\n * 设置配置值\n *\n * @param key Dot-notation key (e.g., 'ui.theme') / 点符号键 (如 'ui.theme')\n * @param value Value to set / 要设置的值\n */\n public set(key: string, value: any): void {\n const oldValue = this.get(key);\n\n // Simple equality check to avoid unnecessary writes/events\n // 简单的相等性检查以避免不必要的写入/事件\n if (JSON.stringify(oldValue) === JSON.stringify(value)) {\n return;\n }\n\n // Validation\n if (this.schema) {\n const tempConfig = JSON.parse(JSON.stringify(this.config));\n this.setDeep(tempConfig, key, value);\n const result = this.schema.safeParse(tempConfig);\n if (!result.success) {\n throw new Error(`Configuration validation failed: ${result.error.message}`);\n }\n }\n\n this.setDeep(this.config, key, value);\n this.emit('change', key, value, oldValue);\n\n if (this.autoSave) {\n this.triggerSave();\n }\n }\n\n /**\n * Delete configuration value\n * 删除配置值\n *\n * @param key Dot-notation key / 点符号键\n */\n public delete(key: string): void {\n if (!this.has(key)) return;\n\n const oldValue = this.get(key);\n this.deleteDeep(this.config, key);\n this.emit('change', key, undefined, oldValue);\n\n if (this.autoSave) {\n this.triggerSave();\n }\n }\n\n /**\n * Check if key exists\n * 检查键是否存在\n */\n public has(key: string): boolean {\n return this.getDeep(this.config, key) !== undefined;\n }\n\n /**\n * Clear all configuration\n * 清除所有配置\n */\n public clear(): void {\n this.config = {};\n this.emit('change', '', {}, {}); // Root change\n if (this.autoSave) {\n this.triggerSave();\n }\n }\n\n /**\n * Force save configuration to disk\n * 强制保存配置到磁盘\n */\n public async save(): Promise<void> {\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n\n try {\n const data = JSON.stringify(this.config, null, 2);\n await fs.promises.writeFile(this.filePath, data, 'utf-8');\n this.emit('saved');\n // this.logger.debug('Configuration saved');\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.error(`Failed to save configuration: ${err.message}`);\n this.emit('error', err);\n }\n }\n\n /**\n * Load configuration from disk\n * 从磁盘加载配置\n */\n public load(): void {\n try {\n if (fs.existsSync(this.filePath)) {\n const data = fs.readFileSync(this.filePath, 'utf-8');\n let parsedConfig = JSON.parse(data);\n\n // Validation\n if (this.schema) {\n const result = this.schema.safeParse(parsedConfig);\n if (!result.success) {\n this.logger.error(`Configuration validation failed: ${result.error.message}`);\n this.emit(\n 'error',\n new Error(`Configuration validation failed: ${result.error.message}`)\n );\n // We still load it, but maybe we should rely on the user to handle the error\n // Or maybe we should use the partial valid data?\n // For now, let's proceed with what we have, but logging the error is crucial.\n } else {\n parsedConfig = result.data;\n }\n }\n\n this.config = parsedConfig;\n this.emit('loaded', this.config);\n this.logger.info(`Configuration loaded from ${this.filePath}`);\n } else {\n this.logger.info('No configuration file found, starting with empty config');\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.error(`Failed to load configuration: ${err.message}`);\n // Don't throw, just start with empty or partial config\n this.emit('error', err);\n }\n }\n\n /**\n * Get the full configuration object\n * 获取完整的配置对象\n */\n public getAll(): Record<string, any> {\n return JSON.parse(JSON.stringify(this.config));\n }\n\n // --- Private Helpers ---\n\n private triggerSave(): void {\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n }\n\n this.saveTimer = setTimeout(() => {\n this.save();\n }, this.saveDelay);\n }\n\n private getDeep(obj: any, path: string): any {\n if (!path) return undefined;\n const keys = path.split('.');\n let current = obj;\n\n for (const key of keys) {\n if (current === undefined || current === null) return undefined;\n current = current[key];\n }\n\n return current;\n }\n\n private setDeep(obj: any, path: string, value: any): void {\n if (!path) return;\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n let current = obj;\n\n for (const key of keys) {\n if (current[key] === undefined || current[key] === null || typeof current[key] !== 'object') {\n current[key] = {};\n }\n current = current[key];\n }\n\n current[lastKey] = value;\n }\n\n private deleteDeep(obj: any, path: string): void {\n if (!path) return;\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n let current = obj;\n\n for (const key of keys) {\n if (current[key] === undefined || current[key] === null) return;\n current = current[key];\n }\n\n delete current[lastKey];\n }\n}\n"],"names":["TypedEmitter","Logger","app","path","fs"],"mappings":"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"}
@@ -0,0 +1,218 @@
1
+ import {app}from'electron';import*as fs from'fs';import*as path from'path';import {TypedEmitter}from'tiny-typed-emitter';import {ElectronLogger}from'../logger/ElectronLogger.mjs';/**
2
+ * Config Manager
3
+ * 配置管理器
4
+ *
5
+ * Manages application configuration with persistence and type safety support.
6
+ * 管理具有持久化和类型安全支持的应用程序配置。
7
+ */
8
+ class ConfigManager extends TypedEmitter {
9
+ config = {};
10
+ filePath;
11
+ logger;
12
+ autoSave;
13
+ saveTimer = null;
14
+ saveDelay;
15
+ schema;
16
+ /**
17
+ * Create ConfigManager instance
18
+ * 创建 ConfigManager 实例
19
+ */
20
+ constructor(options = {}) {
21
+ super();
22
+ this.logger = options.logger || new ElectronLogger({ appName: 'ConfigManager' });
23
+ this.autoSave = options.autoSave ?? true;
24
+ this.saveDelay = options.saveDelay || 100;
25
+ this.schema = options.schema;
26
+ const userDataPath = app.getPath('userData');
27
+ this.filePath = path.join(userDataPath, options.filename || 'config.json');
28
+ this.load();
29
+ }
30
+ /**
31
+ * Get configuration value
32
+ * 获取配置值
33
+ *
34
+ * @param key Dot-notation key (e.g., 'ui.theme') / 点符号键 (如 'ui.theme')
35
+ * @param defaultValue Default value if key not found / 如果键未找到的默认值
36
+ */
37
+ get(key, defaultValue) {
38
+ const value = this.getDeep(this.config, key);
39
+ return value === undefined ? defaultValue : value;
40
+ }
41
+ /**
42
+ * Set configuration value
43
+ * 设置配置值
44
+ *
45
+ * @param key Dot-notation key (e.g., 'ui.theme') / 点符号键 (如 'ui.theme')
46
+ * @param value Value to set / 要设置的值
47
+ */
48
+ set(key, value) {
49
+ const oldValue = this.get(key);
50
+ // Simple equality check to avoid unnecessary writes/events
51
+ // 简单的相等性检查以避免不必要的写入/事件
52
+ if (JSON.stringify(oldValue) === JSON.stringify(value)) {
53
+ return;
54
+ }
55
+ // Validation
56
+ if (this.schema) {
57
+ const tempConfig = JSON.parse(JSON.stringify(this.config));
58
+ this.setDeep(tempConfig, key, value);
59
+ const result = this.schema.safeParse(tempConfig);
60
+ if (!result.success) {
61
+ throw new Error(`Configuration validation failed: ${result.error.message}`);
62
+ }
63
+ }
64
+ this.setDeep(this.config, key, value);
65
+ this.emit('change', key, value, oldValue);
66
+ if (this.autoSave) {
67
+ this.triggerSave();
68
+ }
69
+ }
70
+ /**
71
+ * Delete configuration value
72
+ * 删除配置值
73
+ *
74
+ * @param key Dot-notation key / 点符号键
75
+ */
76
+ delete(key) {
77
+ if (!this.has(key))
78
+ return;
79
+ const oldValue = this.get(key);
80
+ this.deleteDeep(this.config, key);
81
+ this.emit('change', key, undefined, oldValue);
82
+ if (this.autoSave) {
83
+ this.triggerSave();
84
+ }
85
+ }
86
+ /**
87
+ * Check if key exists
88
+ * 检查键是否存在
89
+ */
90
+ has(key) {
91
+ return this.getDeep(this.config, key) !== undefined;
92
+ }
93
+ /**
94
+ * Clear all configuration
95
+ * 清除所有配置
96
+ */
97
+ clear() {
98
+ this.config = {};
99
+ this.emit('change', '', {}, {}); // Root change
100
+ if (this.autoSave) {
101
+ this.triggerSave();
102
+ }
103
+ }
104
+ /**
105
+ * Force save configuration to disk
106
+ * 强制保存配置到磁盘
107
+ */
108
+ async save() {
109
+ if (this.saveTimer) {
110
+ clearTimeout(this.saveTimer);
111
+ this.saveTimer = null;
112
+ }
113
+ try {
114
+ const data = JSON.stringify(this.config, null, 2);
115
+ await fs.promises.writeFile(this.filePath, data, 'utf-8');
116
+ this.emit('saved');
117
+ // this.logger.debug('Configuration saved');
118
+ }
119
+ catch (error) {
120
+ const err = error instanceof Error ? error : new Error(String(error));
121
+ this.logger.error(`Failed to save configuration: ${err.message}`);
122
+ this.emit('error', err);
123
+ }
124
+ }
125
+ /**
126
+ * Load configuration from disk
127
+ * 从磁盘加载配置
128
+ */
129
+ load() {
130
+ try {
131
+ if (fs.existsSync(this.filePath)) {
132
+ const data = fs.readFileSync(this.filePath, 'utf-8');
133
+ let parsedConfig = JSON.parse(data);
134
+ // Validation
135
+ if (this.schema) {
136
+ const result = this.schema.safeParse(parsedConfig);
137
+ if (!result.success) {
138
+ this.logger.error(`Configuration validation failed: ${result.error.message}`);
139
+ this.emit('error', new Error(`Configuration validation failed: ${result.error.message}`));
140
+ // We still load it, but maybe we should rely on the user to handle the error
141
+ // Or maybe we should use the partial valid data?
142
+ // For now, let's proceed with what we have, but logging the error is crucial.
143
+ }
144
+ else {
145
+ parsedConfig = result.data;
146
+ }
147
+ }
148
+ this.config = parsedConfig;
149
+ this.emit('loaded', this.config);
150
+ this.logger.info(`Configuration loaded from ${this.filePath}`);
151
+ }
152
+ else {
153
+ this.logger.info('No configuration file found, starting with empty config');
154
+ }
155
+ }
156
+ catch (error) {
157
+ const err = error instanceof Error ? error : new Error(String(error));
158
+ this.logger.error(`Failed to load configuration: ${err.message}`);
159
+ // Don't throw, just start with empty or partial config
160
+ this.emit('error', err);
161
+ }
162
+ }
163
+ /**
164
+ * Get the full configuration object
165
+ * 获取完整的配置对象
166
+ */
167
+ getAll() {
168
+ return JSON.parse(JSON.stringify(this.config));
169
+ }
170
+ // --- Private Helpers ---
171
+ triggerSave() {
172
+ if (this.saveTimer) {
173
+ clearTimeout(this.saveTimer);
174
+ }
175
+ this.saveTimer = setTimeout(() => {
176
+ this.save();
177
+ }, this.saveDelay);
178
+ }
179
+ getDeep(obj, path) {
180
+ if (!path)
181
+ return undefined;
182
+ const keys = path.split('.');
183
+ let current = obj;
184
+ for (const key of keys) {
185
+ if (current === undefined || current === null)
186
+ return undefined;
187
+ current = current[key];
188
+ }
189
+ return current;
190
+ }
191
+ setDeep(obj, path, value) {
192
+ if (!path)
193
+ return;
194
+ const keys = path.split('.');
195
+ const lastKey = keys.pop();
196
+ let current = obj;
197
+ for (const key of keys) {
198
+ if (current[key] === undefined || current[key] === null || typeof current[key] !== 'object') {
199
+ current[key] = {};
200
+ }
201
+ current = current[key];
202
+ }
203
+ current[lastKey] = value;
204
+ }
205
+ deleteDeep(obj, path) {
206
+ if (!path)
207
+ return;
208
+ const keys = path.split('.');
209
+ const lastKey = keys.pop();
210
+ let current = obj;
211
+ for (const key of keys) {
212
+ if (current[key] === undefined || current[key] === null)
213
+ return;
214
+ current = current[key];
215
+ }
216
+ delete current[lastKey];
217
+ }
218
+ }export{ConfigManager};//# sourceMappingURL=ConfigManager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigManager.mjs","sources":["../../../src/infrastructure/config/ConfigManager.ts"],"sourcesContent":["import { app } from 'electron';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { TypedEmitter } from 'tiny-typed-emitter';\nimport { ILogger, Logger } from '@/infrastructure/logger';\nimport { z } from 'zod';\n\n/**\n * Config Manager Events\n * 配置管理器事件\n */\nexport interface ConfigManagerEvents {\n /**\n * Emitted when a configuration value changes\n * 当配置值发生变化时触发\n */\n change: (key: string, newValue: any, oldValue: any) => void;\n /**\n * Emitted when configuration is loaded from disk\n * 当配置从磁盘加载时触发\n */\n loaded: (config: Record<string, any>) => void;\n /**\n * Emitted when configuration is saved to disk\n * 当配置保存到磁盘时触发\n */\n saved: () => void;\n /**\n * Emitted when an error occurs\n * 当发生错误时触发\n */\n error: (error: Error) => void;\n}\n\n/**\n * Config Manager Options\n * 配置管理器选项\n */\nexport interface ConfigManagerOptions {\n /**\n * Configuration filename (default: 'config.json')\n * 配置文件名 (默认: 'config.json')\n */\n filename?: string;\n /**\n * Logger instance\n * 日志实例\n */\n logger?: ILogger;\n /**\n * Whether to automatically save on changes (default: true)\n * 是否在更改时自动保存 (默认: true)\n */\n autoSave?: boolean;\n /**\n * Save delay in milliseconds (debounce) (default: 100)\n * 保存延迟(毫秒,防抖) (默认: 100)\n */\n saveDelay?: number;\n /**\n * Zod schema for validation\n * 用于校验的 Zod schema\n */\n schema?: z.ZodType<any>;\n}\n\n/**\n * Config Manager\n * 配置管理器\n *\n * Manages application configuration with persistence and type safety support.\n * 管理具有持久化和类型安全支持的应用程序配置。\n */\nexport class ConfigManager extends TypedEmitter<ConfigManagerEvents> {\n private config: Record<string, any> = {};\n private filePath: string;\n private logger: ILogger;\n private autoSave: boolean;\n private saveTimer: NodeJS.Timeout | null = null;\n private saveDelay: number;\n private schema?: z.ZodType<any>;\n\n /**\n * Create ConfigManager instance\n * 创建 ConfigManager 实例\n */\n constructor(options: ConfigManagerOptions = {}) {\n super();\n this.logger = options.logger || new Logger({ appName: 'ConfigManager' });\n this.autoSave = options.autoSave ?? true;\n this.saveDelay = options.saveDelay || 100;\n this.schema = options.schema;\n\n const userDataPath = app.getPath('userData');\n this.filePath = path.join(userDataPath, options.filename || 'config.json');\n\n this.load();\n }\n\n /**\n * Get configuration value\n * 获取配置值\n *\n * @param key Dot-notation key (e.g., 'ui.theme') / 点符号键 (如 'ui.theme')\n * @param defaultValue Default value if key not found / 如果键未找到的默认值\n */\n public get<T>(key: string, defaultValue?: T): T {\n const value = this.getDeep(this.config, key);\n return value === undefined ? (defaultValue as T) : value;\n }\n\n /**\n * Set configuration value\n * 设置配置值\n *\n * @param key Dot-notation key (e.g., 'ui.theme') / 点符号键 (如 'ui.theme')\n * @param value Value to set / 要设置的值\n */\n public set(key: string, value: any): void {\n const oldValue = this.get(key);\n\n // Simple equality check to avoid unnecessary writes/events\n // 简单的相等性检查以避免不必要的写入/事件\n if (JSON.stringify(oldValue) === JSON.stringify(value)) {\n return;\n }\n\n // Validation\n if (this.schema) {\n const tempConfig = JSON.parse(JSON.stringify(this.config));\n this.setDeep(tempConfig, key, value);\n const result = this.schema.safeParse(tempConfig);\n if (!result.success) {\n throw new Error(`Configuration validation failed: ${result.error.message}`);\n }\n }\n\n this.setDeep(this.config, key, value);\n this.emit('change', key, value, oldValue);\n\n if (this.autoSave) {\n this.triggerSave();\n }\n }\n\n /**\n * Delete configuration value\n * 删除配置值\n *\n * @param key Dot-notation key / 点符号键\n */\n public delete(key: string): void {\n if (!this.has(key)) return;\n\n const oldValue = this.get(key);\n this.deleteDeep(this.config, key);\n this.emit('change', key, undefined, oldValue);\n\n if (this.autoSave) {\n this.triggerSave();\n }\n }\n\n /**\n * Check if key exists\n * 检查键是否存在\n */\n public has(key: string): boolean {\n return this.getDeep(this.config, key) !== undefined;\n }\n\n /**\n * Clear all configuration\n * 清除所有配置\n */\n public clear(): void {\n this.config = {};\n this.emit('change', '', {}, {}); // Root change\n if (this.autoSave) {\n this.triggerSave();\n }\n }\n\n /**\n * Force save configuration to disk\n * 强制保存配置到磁盘\n */\n public async save(): Promise<void> {\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n\n try {\n const data = JSON.stringify(this.config, null, 2);\n await fs.promises.writeFile(this.filePath, data, 'utf-8');\n this.emit('saved');\n // this.logger.debug('Configuration saved');\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.error(`Failed to save configuration: ${err.message}`);\n this.emit('error', err);\n }\n }\n\n /**\n * Load configuration from disk\n * 从磁盘加载配置\n */\n public load(): void {\n try {\n if (fs.existsSync(this.filePath)) {\n const data = fs.readFileSync(this.filePath, 'utf-8');\n let parsedConfig = JSON.parse(data);\n\n // Validation\n if (this.schema) {\n const result = this.schema.safeParse(parsedConfig);\n if (!result.success) {\n this.logger.error(`Configuration validation failed: ${result.error.message}`);\n this.emit(\n 'error',\n new Error(`Configuration validation failed: ${result.error.message}`)\n );\n // We still load it, but maybe we should rely on the user to handle the error\n // Or maybe we should use the partial valid data?\n // For now, let's proceed with what we have, but logging the error is crucial.\n } else {\n parsedConfig = result.data;\n }\n }\n\n this.config = parsedConfig;\n this.emit('loaded', this.config);\n this.logger.info(`Configuration loaded from ${this.filePath}`);\n } else {\n this.logger.info('No configuration file found, starting with empty config');\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.error(`Failed to load configuration: ${err.message}`);\n // Don't throw, just start with empty or partial config\n this.emit('error', err);\n }\n }\n\n /**\n * Get the full configuration object\n * 获取完整的配置对象\n */\n public getAll(): Record<string, any> {\n return JSON.parse(JSON.stringify(this.config));\n }\n\n // --- Private Helpers ---\n\n private triggerSave(): void {\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n }\n\n this.saveTimer = setTimeout(() => {\n this.save();\n }, this.saveDelay);\n }\n\n private getDeep(obj: any, path: string): any {\n if (!path) return undefined;\n const keys = path.split('.');\n let current = obj;\n\n for (const key of keys) {\n if (current === undefined || current === null) return undefined;\n current = current[key];\n }\n\n return current;\n }\n\n private setDeep(obj: any, path: string, value: any): void {\n if (!path) return;\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n let current = obj;\n\n for (const key of keys) {\n if (current[key] === undefined || current[key] === null || typeof current[key] !== 'object') {\n current[key] = {};\n }\n current = current[key];\n }\n\n current[lastKey] = value;\n }\n\n private deleteDeep(obj: any, path: string): void {\n if (!path) return;\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n let current = obj;\n\n for (const key of keys) {\n if (current[key] === undefined || current[key] === null) return;\n current = current[key];\n }\n\n delete current[lastKey];\n }\n}\n"],"names":["Logger"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from './ConfigManager';
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Debug Helper - Enhanced debugging tools for development
3
+ * 调试助手 - 增强的开发调试工具
4
+ */
5
+ import { PerformanceMetric } from '@/internal/types/PerformanceOptions';
6
+ /**
7
+ * Debug Panel Configuration
8
+ * 调试面板配置
9
+ */
10
+ export interface DebugPanelConfig {
11
+ /** Enable debug panel */
12
+ enabled?: boolean;
13
+ /** Port for debug server */
14
+ port?: number;
15
+ /** Auto-open in browser */
16
+ autoOpen?: boolean;
17
+ }
18
+ /**
19
+ * Enhanced Debug Helper
20
+ * 增强的调试助手
21
+ */
22
+ export declare class EnhancedDebugHelper {
23
+ private static instance;
24
+ private logger;
25
+ private registry;
26
+ private performanceMetrics;
27
+ private metricsEnabled;
28
+ private constructor();
29
+ static getInstance(): EnhancedDebugHelper;
30
+ /**
31
+ * Register a component for debugging
32
+ * 注册组件用于调试
33
+ */
34
+ register(name: string, component: any): void;
35
+ /**
36
+ * Get registered component
37
+ * 获取已注册的组件
38
+ */
39
+ get(name: string): any;
40
+ /**
41
+ * Get all registered components
42
+ * 获取所有已注册的组件
43
+ */
44
+ getAll(): Record<string, any>;
45
+ /**
46
+ * Enable performance monitoring
47
+ * 启用性能监控
48
+ */
49
+ enablePerformanceMonitoring(): void;
50
+ /**
51
+ * Disable performance monitoring
52
+ * 禁用性能监控
53
+ */
54
+ disablePerformanceMonitoring(): void;
55
+ /**
56
+ * Record a performance metric
57
+ * 记录性能指标
58
+ */
59
+ recordMetric(metric: PerformanceMetric): void;
60
+ /**
61
+ * Get performance metrics
62
+ * 获取性能指标
63
+ */
64
+ getMetrics(): PerformanceMetric[];
65
+ /**
66
+ * Clear performance metrics
67
+ * 清除性能指标
68
+ */
69
+ clearMetrics(): void;
70
+ /**
71
+ * Get performance statistics
72
+ * 获取性能统计
73
+ */
74
+ getStatistics(): Record<string, any>;
75
+ /**
76
+ * Create a performance timer
77
+ * 创建性能计时器
78
+ */
79
+ createTimer(name: string, metadata?: Record<string, unknown>): () => void;
80
+ /**
81
+ * Get debug information about WindowManager
82
+ * 获取 WindowManager 的调试信息
83
+ */
84
+ getWindowManagerInfo(): any;
85
+ /**
86
+ * Get debug information about IpcRouter
87
+ * 获取 IpcRouter 的调试信息
88
+ */
89
+ getIpcRouterInfo(): any;
90
+ /**
91
+ * Get debug information about MessageBus
92
+ * 获取 MessageBus 的调试信息
93
+ */
94
+ getMessageBusInfo(): any;
95
+ /**
96
+ * Get comprehensive debug snapshot
97
+ * 获取综合调试快照
98
+ */
99
+ getDebugSnapshot(): any;
100
+ /**
101
+ * Log debug snapshot to console
102
+ * 将调试快照输出到控制台
103
+ */
104
+ logSnapshot(): void;
105
+ }
106
+ export declare const debugHelper: EnhancedDebugHelper;
@@ -0,0 +1,218 @@
1
+ 'use strict';var ElectronLogger=require('../logger/ElectronLogger.js');/**
2
+ * Debug Helper - Enhanced debugging tools for development
3
+ * 调试助手 - 增强的开发调试工具
4
+ */
5
+ /**
6
+ * Enhanced Debug Helper
7
+ * 增强的调试助手
8
+ */
9
+ class EnhancedDebugHelper {
10
+ static instance;
11
+ logger;
12
+ registry = new Map();
13
+ performanceMetrics = [];
14
+ metricsEnabled = false;
15
+ constructor() {
16
+ this.logger = new ElectronLogger.ElectronLogger({ appName: 'DebugHelper' });
17
+ }
18
+ static getInstance() {
19
+ if (!EnhancedDebugHelper.instance) {
20
+ EnhancedDebugHelper.instance = new EnhancedDebugHelper();
21
+ }
22
+ return EnhancedDebugHelper.instance;
23
+ }
24
+ /**
25
+ * Register a component for debugging
26
+ * 注册组件用于调试
27
+ */
28
+ register(name, component) {
29
+ this.registry.set(name, component);
30
+ this.logger.info(`Registered component: ${name}`);
31
+ }
32
+ /**
33
+ * Get registered component
34
+ * 获取已注册的组件
35
+ */
36
+ get(name) {
37
+ return this.registry.get(name);
38
+ }
39
+ /**
40
+ * Get all registered components
41
+ * 获取所有已注册的组件
42
+ */
43
+ getAll() {
44
+ const result = {};
45
+ this.registry.forEach((value, key) => {
46
+ result[key] = value;
47
+ });
48
+ return result;
49
+ }
50
+ /**
51
+ * Enable performance monitoring
52
+ * 启用性能监控
53
+ */
54
+ enablePerformanceMonitoring() {
55
+ this.metricsEnabled = true;
56
+ this.logger.info('Performance monitoring enabled');
57
+ }
58
+ /**
59
+ * Disable performance monitoring
60
+ * 禁用性能监控
61
+ */
62
+ disablePerformanceMonitoring() {
63
+ this.metricsEnabled = false;
64
+ this.logger.info('Performance monitoring disabled');
65
+ }
66
+ /**
67
+ * Record a performance metric
68
+ * 记录性能指标
69
+ */
70
+ recordMetric(metric) {
71
+ if (!this.metricsEnabled)
72
+ return;
73
+ this.performanceMetrics.push(metric);
74
+ // Keep only last 1000 metrics
75
+ if (this.performanceMetrics.length > 1000) {
76
+ this.performanceMetrics.shift();
77
+ }
78
+ this.logger.info(`Performance: ${metric.name} took ${metric.duration.toFixed(2)}ms`, metric.metadata);
79
+ }
80
+ /**
81
+ * Get performance metrics
82
+ * 获取性能指标
83
+ */
84
+ getMetrics() {
85
+ return [...this.performanceMetrics];
86
+ }
87
+ /**
88
+ * Clear performance metrics
89
+ * 清除性能指标
90
+ */
91
+ clearMetrics() {
92
+ this.performanceMetrics = [];
93
+ this.logger.info('Performance metrics cleared');
94
+ }
95
+ /**
96
+ * Get performance statistics
97
+ * 获取性能统计
98
+ */
99
+ getStatistics() {
100
+ const stats = {};
101
+ this.performanceMetrics.forEach((metric) => {
102
+ if (!stats[metric.name]) {
103
+ stats[metric.name] = {
104
+ count: 0,
105
+ total: 0,
106
+ min: Infinity,
107
+ max: -Infinity,
108
+ avg: 0,
109
+ };
110
+ }
111
+ const stat = stats[metric.name];
112
+ stat.count++;
113
+ stat.total += metric.duration;
114
+ stat.min = Math.min(stat.min, metric.duration);
115
+ stat.max = Math.max(stat.max, metric.duration);
116
+ stat.avg = stat.total / stat.count;
117
+ });
118
+ return stats;
119
+ }
120
+ /**
121
+ * Create a performance timer
122
+ * 创建性能计时器
123
+ */
124
+ createTimer(name, metadata) {
125
+ const start = performance.now();
126
+ return () => {
127
+ const duration = performance.now() - start;
128
+ this.recordMetric({
129
+ name,
130
+ duration,
131
+ timestamp: Date.now(),
132
+ metadata,
133
+ });
134
+ };
135
+ }
136
+ /**
137
+ * Get debug information about WindowManager
138
+ * 获取 WindowManager 的调试信息
139
+ */
140
+ getWindowManagerInfo() {
141
+ const wm = this.registry.get('windowManager');
142
+ if (!wm)
143
+ return null;
144
+ try {
145
+ const windows = wm.getAllWindows();
146
+ return {
147
+ windowCount: windows.length,
148
+ windows: windows.map((window) => ({
149
+ isDestroyed: window.isDestroyed(),
150
+ isVisible: window.isVisible(),
151
+ isMinimized: window.isMinimized(),
152
+ isMaximized: window.isMaximized(),
153
+ title: window.getTitle(),
154
+ })),
155
+ };
156
+ }
157
+ catch (error) {
158
+ this.logger.error('Failed to get WindowManager info:', error);
159
+ return { error: 'Failed to retrieve info' };
160
+ }
161
+ }
162
+ /**
163
+ * Get debug information about IpcRouter
164
+ * 获取 IpcRouter 的调试信息
165
+ */
166
+ getIpcRouterInfo() {
167
+ const router = this.registry.get('ipcRouter');
168
+ if (!router)
169
+ return null;
170
+ // IpcRouter doesn't expose handler names by default, so we return basic info
171
+ return {
172
+ registered: true,
173
+ type: 'IpcRouter',
174
+ };
175
+ }
176
+ /**
177
+ * Get debug information about MessageBus
178
+ * 获取 MessageBus 的调试信息
179
+ */
180
+ getMessageBusInfo() {
181
+ const bus = this.registry.get('messageBus');
182
+ if (!bus)
183
+ return null;
184
+ return {
185
+ registeredWindows: bus.getRegisteredWindows(),
186
+ data: bus.getData(),
187
+ };
188
+ }
189
+ /**
190
+ * Get comprehensive debug snapshot
191
+ * 获取综合调试快照
192
+ */
193
+ getDebugSnapshot() {
194
+ return {
195
+ timestamp: Date.now(),
196
+ components: {
197
+ windowManager: this.getWindowManagerInfo(),
198
+ ipcRouter: this.getIpcRouterInfo(),
199
+ messageBus: this.getMessageBusInfo(),
200
+ },
201
+ performance: {
202
+ metrics: this.getMetrics(),
203
+ statistics: this.getStatistics(),
204
+ },
205
+ };
206
+ }
207
+ /**
208
+ * Log debug snapshot to console
209
+ * 将调试快照输出到控制台
210
+ */
211
+ logSnapshot() {
212
+ const snapshot = this.getDebugSnapshot();
213
+ console.log('=== Debug Snapshot ===');
214
+ console.log(JSON.stringify(snapshot, null, 2));
215
+ }
216
+ }
217
+ // Export singleton instance
218
+ const debugHelper = EnhancedDebugHelper.getInstance();exports.EnhancedDebugHelper=EnhancedDebugHelper;exports.debugHelper=debugHelper;//# sourceMappingURL=EnhancedDebugHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnhancedDebugHelper.js","sources":["../../../src/infrastructure/debug/EnhancedDebugHelper.ts"],"sourcesContent":["/**\n * Debug Helper - Enhanced debugging tools for development\n * 调试助手 - 增强的开发调试工具\n */\n\nimport { ILogger, Logger } from '@/infrastructure/logger';\nimport type WindowManager from '@/core/window/WindowManager';\nimport type IpcRouter from '@/core/ipc/IpcRouter';\nimport type { MessageBus } from '@/core/message-bus/MessageBus';\nimport { PerformanceMetric } from '@/internal/types/PerformanceOptions';\n\n/**\n * Debug Panel Configuration\n * 调试面板配置\n */\nexport interface DebugPanelConfig {\n /** Enable debug panel */\n enabled?: boolean;\n /** Port for debug server */\n port?: number;\n /** Auto-open in browser */\n autoOpen?: boolean;\n}\n\n/**\n * Enhanced Debug Helper\n * 增强的调试助手\n */\nexport class EnhancedDebugHelper {\n private static instance: EnhancedDebugHelper;\n private logger: ILogger;\n private registry: Map<string, any> = new Map();\n private performanceMetrics: PerformanceMetric[] = [];\n private metricsEnabled: boolean = false;\n\n private constructor() {\n this.logger = new Logger({ appName: 'DebugHelper' });\n }\n\n static getInstance(): EnhancedDebugHelper {\n if (!EnhancedDebugHelper.instance) {\n EnhancedDebugHelper.instance = new EnhancedDebugHelper();\n }\n return EnhancedDebugHelper.instance;\n }\n\n /**\n * Register a component for debugging\n * 注册组件用于调试\n */\n register(name: string, component: any): void {\n this.registry.set(name, component);\n this.logger.info(`Registered component: ${name}`);\n }\n\n /**\n * Get registered component\n * 获取已注册的组件\n */\n get(name: string): any {\n return this.registry.get(name);\n }\n\n /**\n * Get all registered components\n * 获取所有已注册的组件\n */\n getAll(): Record<string, any> {\n const result: Record<string, any> = {};\n this.registry.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n }\n\n /**\n * Enable performance monitoring\n * 启用性能监控\n */\n enablePerformanceMonitoring(): void {\n this.metricsEnabled = true;\n this.logger.info('Performance monitoring enabled');\n }\n\n /**\n * Disable performance monitoring\n * 禁用性能监控\n */\n disablePerformanceMonitoring(): void {\n this.metricsEnabled = false;\n this.logger.info('Performance monitoring disabled');\n }\n\n /**\n * Record a performance metric\n * 记录性能指标\n */\n recordMetric(metric: PerformanceMetric): void {\n if (!this.metricsEnabled) return;\n\n this.performanceMetrics.push(metric);\n\n // Keep only last 1000 metrics\n if (this.performanceMetrics.length > 1000) {\n this.performanceMetrics.shift();\n }\n\n this.logger.info(\n `Performance: ${metric.name} took ${metric.duration.toFixed(2)}ms`,\n metric.metadata\n );\n }\n\n /**\n * Get performance metrics\n * 获取性能指标\n */\n getMetrics(): PerformanceMetric[] {\n return [...this.performanceMetrics];\n }\n\n /**\n * Clear performance metrics\n * 清除性能指标\n */\n clearMetrics(): void {\n this.performanceMetrics = [];\n this.logger.info('Performance metrics cleared');\n }\n\n /**\n * Get performance statistics\n * 获取性能统计\n */\n getStatistics(): Record<string, any> {\n const stats: Record<string, any> = {};\n\n this.performanceMetrics.forEach((metric) => {\n if (!stats[metric.name]) {\n stats[metric.name] = {\n count: 0,\n total: 0,\n min: Infinity,\n max: -Infinity,\n avg: 0,\n };\n }\n\n const stat = stats[metric.name];\n stat.count++;\n stat.total += metric.duration;\n stat.min = Math.min(stat.min, metric.duration);\n stat.max = Math.max(stat.max, metric.duration);\n stat.avg = stat.total / stat.count;\n });\n\n return stats;\n }\n\n /**\n * Create a performance timer\n * 创建性能计时器\n */\n createTimer(name: string, metadata?: Record<string, unknown>): () => void {\n const start = performance.now();\n\n return () => {\n const duration = performance.now() - start;\n this.recordMetric({\n name,\n duration,\n timestamp: Date.now(),\n metadata,\n });\n };\n }\n\n /**\n * Get debug information about WindowManager\n * 获取 WindowManager 的调试信息\n */\n getWindowManagerInfo(): any {\n const wm = this.registry.get('windowManager') as WindowManager | undefined;\n if (!wm) return null;\n\n try {\n const windows = wm.getAllWindows();\n return {\n windowCount: windows.length,\n windows: windows.map((window) => ({\n isDestroyed: window.isDestroyed(),\n isVisible: window.isVisible(),\n isMinimized: window.isMinimized(),\n isMaximized: window.isMaximized(),\n title: window.getTitle(),\n })),\n };\n } catch (error) {\n this.logger.error('Failed to get WindowManager info:', error);\n return { error: 'Failed to retrieve info' };\n }\n }\n\n /**\n * Get debug information about IpcRouter\n * 获取 IpcRouter 的调试信息\n */\n getIpcRouterInfo(): any {\n const router = this.registry.get('ipcRouter') as IpcRouter | undefined;\n if (!router) return null;\n\n // IpcRouter doesn't expose handler names by default, so we return basic info\n return {\n registered: true,\n type: 'IpcRouter',\n };\n }\n\n /**\n * Get debug information about MessageBus\n * 获取 MessageBus 的调试信息\n */\n getMessageBusInfo(): any {\n const bus = this.registry.get('messageBus') as MessageBus | undefined;\n if (!bus) return null;\n\n return {\n registeredWindows: bus.getRegisteredWindows(),\n data: bus.getData(),\n };\n }\n\n /**\n * Get comprehensive debug snapshot\n * 获取综合调试快照\n */\n getDebugSnapshot(): any {\n return {\n timestamp: Date.now(),\n components: {\n windowManager: this.getWindowManagerInfo(),\n ipcRouter: this.getIpcRouterInfo(),\n messageBus: this.getMessageBusInfo(),\n },\n performance: {\n metrics: this.getMetrics(),\n statistics: this.getStatistics(),\n },\n };\n }\n\n /**\n * Log debug snapshot to console\n * 将调试快照输出到控制台\n */\n logSnapshot(): void {\n const snapshot = this.getDebugSnapshot();\n console.log('=== Debug Snapshot ===');\n console.log(JSON.stringify(snapshot, null, 2));\n }\n}\n\n// Export singleton instance\nexport const debugHelper = EnhancedDebugHelper.getInstance();\n"],"names":["Logger"],"mappings":"uEAAA;;;AAGG;AAqBH;;;AAGG;MACU,mBAAmB,CAAA;IACtB,OAAO,QAAQ;AACf,IAAA,MAAM;AACN,IAAA,QAAQ,GAAqB,IAAI,GAAG,EAAE;IACtC,kBAAkB,GAAwB,EAAE;IAC5C,cAAc,GAAY,KAAK;AAEvC,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,MAAM,GAAG,IAAIA,6BAAM,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IACtD;AAEA,IAAA,OAAO,WAAW,GAAA;AAChB,QAAA,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE;AACjC,YAAA,mBAAmB,CAAC,QAAQ,GAAG,IAAI,mBAAmB,EAAE;QAC1D;QACA,OAAO,mBAAmB,CAAC,QAAQ;IACrC;AAEA;;;AAGG;IACH,QAAQ,CAAC,IAAY,EAAE,SAAc,EAAA;QACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAE,CAAC;IACnD;AAEA;;;AAGG;AACH,IAAA,GAAG,CAAC,IAAY,EAAA;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;IAChC;AAEA;;;AAGG;IACH,MAAM,GAAA;QACJ,MAAM,MAAM,GAAwB,EAAE;QACtC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,KAAI;AACnC,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK;AACrB,QAAA,CAAC,CAAC;AACF,QAAA,OAAO,MAAM;IACf;AAEA;;;AAGG;IACH,2BAA2B,GAAA;AACzB,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;AAC1B,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC;IACpD;AAEA;;;AAGG;IACH,4BAA4B,GAAA;AAC1B,QAAA,IAAI,CAAC,cAAc,GAAG,KAAK;AAC3B,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC;IACrD;AAEA;;;AAGG;AACH,IAAA,YAAY,CAAC,MAAyB,EAAA;QACpC,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE;AAE1B,QAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;;QAGpC,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,IAAI,EAAE;AACzC,YAAA,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE;QACjC;QAEA,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,gBAAgB,MAAM,CAAC,IAAI,CAAA,MAAA,EAAS,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA,EAAA,CAAI,EAClE,MAAM,CAAC,QAAQ,CAChB;IACH;AAEA;;;AAGG;IACH,UAAU,GAAA;AACR,QAAA,OAAO,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC;IACrC;AAEA;;;AAGG;IACH,YAAY,GAAA;AACV,QAAA,IAAI,CAAC,kBAAkB,GAAG,EAAE;AAC5B,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC;IACjD;AAEA;;;AAGG;IACH,aAAa,GAAA;QACX,MAAM,KAAK,GAAwB,EAAE;QAErC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,MAAM,KAAI;YACzC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AACvB,gBAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;AACnB,oBAAA,KAAK,EAAE,CAAC;AACR,oBAAA,KAAK,EAAE,CAAC;AACR,oBAAA,GAAG,EAAE,QAAQ;oBACb,GAAG,EAAE,CAAC,QAAQ;AACd,oBAAA,GAAG,EAAE,CAAC;iBACP;YACH;YAEA,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;YAC/B,IAAI,CAAC,KAAK,EAAE;AACZ,YAAA,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ;AAC7B,YAAA,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC;AAC9C,YAAA,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC;YAC9C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;AACpC,QAAA,CAAC,CAAC;AAEF,QAAA,OAAO,KAAK;IACd;AAEA;;;AAGG;IACH,WAAW,CAAC,IAAY,EAAE,QAAkC,EAAA;AAC1D,QAAA,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;AAE/B,QAAA,OAAO,MAAK;YACV,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK;YAC1C,IAAI,CAAC,YAAY,CAAC;gBAChB,IAAI;gBACJ,QAAQ;AACR,gBAAA,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,QAAQ;AACT,aAAA,CAAC;AACJ,QAAA,CAAC;IACH;AAEA;;;AAGG;IACH,oBAAoB,GAAA;QAClB,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAA8B;AAC1E,QAAA,IAAI,CAAC,EAAE;AAAE,YAAA,OAAO,IAAI;AAEpB,QAAA,IAAI;AACF,YAAA,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,EAAE;YAClC,OAAO;gBACL,WAAW,EAAE,OAAO,CAAC,MAAM;gBAC3B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM;AAChC,oBAAA,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE;AACjC,oBAAA,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE;AAC7B,oBAAA,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE;AACjC,oBAAA,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE;AACjC,oBAAA,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE;AACzB,iBAAA,CAAC,CAAC;aACJ;QACH;QAAE,OAAO,KAAK,EAAE;YACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC;AAC7D,YAAA,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE;QAC7C;IACF;AAEA;;;AAGG;IACH,gBAAgB,GAAA;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAA0B;AACtE,QAAA,IAAI,CAAC,MAAM;AAAE,YAAA,OAAO,IAAI;;QAGxB,OAAO;AACL,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,IAAI,EAAE,WAAW;SAClB;IACH;AAEA;;;AAGG;IACH,iBAAiB,GAAA;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAA2B;AACrE,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,IAAI;QAErB,OAAO;AACL,YAAA,iBAAiB,EAAE,GAAG,CAAC,oBAAoB,EAAE;AAC7C,YAAA,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE;SACpB;IACH;AAEA;;;AAGG;IACH,gBAAgB,GAAA;QACd,OAAO;AACL,YAAA,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;AACrB,YAAA,UAAU,EAAE;AACV,gBAAA,aAAa,EAAE,IAAI,CAAC,oBAAoB,EAAE;AAC1C,gBAAA,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;AAClC,gBAAA,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE;AACrC,aAAA;AACD,YAAA,WAAW,EAAE;AACX,gBAAA,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE;AAC1B,gBAAA,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE;AACjC,aAAA;SACF;IACH;AAEA;;;AAGG;IACH,WAAW,GAAA;AACT,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACxC,QAAA,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;AACrC,QAAA,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAChD;AACD;AAED;MACa,WAAW,GAAG,mBAAmB,CAAC,WAAW"}