electron-infra-kit 0.1.0 → 0.1.1
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.
- package/README.md +56 -2
- package/README.zh-CN.md +52 -2
- package/dist/core/lifecycle/LifecycleManager.js +11 -9
- package/dist/core/lifecycle/LifecycleManager.js.map +1 -1
- package/dist/core/lifecycle/LifecycleManager.mjs +6 -4
- package/dist/core/lifecycle/LifecycleManager.mjs.map +1 -1
- package/dist/core/window/WindowCreator.js +12 -12
- package/dist/core/window/WindowCreator.js.map +1 -1
- package/dist/core/window/WindowCreator.mjs +12 -12
- package/dist/core/window/WindowCreator.mjs.map +1 -1
- package/dist/core/window/window-manager.type.d.ts +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -4
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/infrastructure/logger/ElectronLogger.d.ts +4 -0
- package/dist/infrastructure/logger/ElectronLogger.js +3 -1
- package/dist/infrastructure/logger/ElectronLogger.js.map +1 -1
- package/dist/infrastructure/logger/ElectronLogger.mjs +3 -1
- package/dist/infrastructure/logger/ElectronLogger.mjs.map +1 -1
- package/dist/infrastructure/logger/index.d.ts +4 -0
- package/dist/infrastructure/logger/index.js +10 -0
- package/dist/infrastructure/logger/index.js.map +1 -0
- package/dist/infrastructure/logger/index.mjs +10 -0
- package/dist/infrastructure/logger/index.mjs.map +1 -0
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import WindowManager from './core/window/WindowManager';\nimport IpcRouter from './core/ipc/IpcRouter';\nimport { MessageBus } from './core/message-bus/MessageBus';\nimport { WindowManagerConfig } from './core/window/window-manager.type';\nimport { DebugHelper } from './infrastructure/debug';\n\n/**\n * Quick Start Helper\n * 快速开始助手\n * @param config - WindowManager configuration\n * @returns Object containing initialized instances\n */\nexport function createElectronToolkit(config: WindowManagerConfig = {}) {\n // Create IpcRouter\n const ipcRouter = new IpcRouter({ logger
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import WindowManager from './core/window/WindowManager';\nimport IpcRouter from './core/ipc/IpcRouter';\nimport { MessageBus } from './core/message-bus/MessageBus';\nimport { WindowManagerConfig } from './core/window/window-manager.type';\nimport { DebugHelper } from './infrastructure/debug';\nimport { getSharedLogger } from './infrastructure/logger';\n\n/**\n * Quick Start Helper\n * 快速开始助手\n * @param config - WindowManager configuration\n * @returns Object containing initialized instances\n */\nexport function createElectronToolkit(config: WindowManagerConfig = {}) {\n const logger = config.logger || getSharedLogger(config.loggerOptions);\n // Create IpcRouter\n const ipcRouter = new IpcRouter({ logger });\n\n // Create WindowManager with ipcRouter integrated\n const windowManager = new WindowManager({\n ...config,\n logger,\n ipcRouter,\n });\n\n // Create MessageBus\n const messageBus = new MessageBus({ logger });\n\n // Automatically integrate MessageBus with WindowManager\n // 自动集成 MessageBus 和 WindowManager\n messageBus.autoRegisterWindows(windowManager);\n\n // Setup Debug Mode\n // 设置调试模式\n if (config.isDevelopment || process.env.NODE_ENV === 'development') {\n DebugHelper.enableDebugMode();\n DebugHelper.register('windowManager', windowManager);\n DebugHelper.register('ipcRouter', ipcRouter);\n DebugHelper.register('messageBus', messageBus);\n }\n\n return {\n windowManager,\n ipcRouter,\n messageBus,\n };\n}\n\nexport * from './core/window';\nexport * from './core/ipc';\nexport * from './core/message-bus';\nexport * from './core/lifecycle/LifecycleManager';\n// IpcTransport is internal, do not export\n// export { default as IpcTransport } from './ipc-transport'\nexport {\n Logger,\n type LoggerOptions,\n getSharedLogger,\n setSharedLogger,\n} from './infrastructure/logger';\nexport * from './preload';\n// Internal utils should not be exported\n// export * from './internal/utils';\nexport * from './infrastructure/config';\nexport * as Types from './types';\nexport { DebugHelper, debugHelper, EnhancedDebugHelper } from './infrastructure/debug';\nexport * from './infrastructure/errors';\n"],"names":["getSharedLogger","MessageBus","DebugHelper"],"mappings":"mxCAOA;;;;;AAKG;AACG,SAAU,qBAAqB,CAAC,MAAA,GAA8B,EAAE,EAAA;AACpE,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAIA,qBAAe,CAAC,MAAM,CAAC,aAAa,CAAC;;IAErE,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;;AAG3C,IAAA,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC;AACtC,QAAA,GAAG,MAAM;QACT,MAAM;QACN,SAAS;AACV,KAAA,CAAC;;IAGF,MAAM,UAAU,GAAG,IAAIC,qBAAU,CAAC,EAAE,MAAM,EAAE,CAAC;;;AAI7C,IAAA,UAAU,CAAC,mBAAmB,CAAC,aAAa,CAAC;;;AAI7C,IAAA,IAAI,MAAM,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;QAClEC,mBAAW,CAAC,eAAe,EAAE;AAC7B,QAAAA,mBAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC;AACpD,QAAAA,mBAAW,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;AAC5C,QAAAA,mBAAW,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC;IAChD;IAEA,OAAO;QACL,aAAa;QACb,SAAS;QACT,UAAU;KACX;AACH"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import WindowManager from'./core/window/WindowManager.mjs';import IpcRouter from'./core/ipc/IpcRouter.mjs';import {MessageBus}from'./core/message-bus/MessageBus.mjs';import {DebugHelper}from'./infrastructure/debug/index.mjs';export{LifecycleManager}from'./core/lifecycle/LifecycleManager.mjs';export{IpcRendererBridge,ipcRendererBridge}from'./preload/index.mjs';import*as types from'./types.mjs';export{types as Types };export{ElectronToolkitError,IpcHandlerError,WindowNotFoundError}from'./infrastructure/errors/index.mjs';export{default as WindowStore}from'./core/window/WindowStore.mjs';export{default as WindowCreator}from'./core/window/WindowCreator.mjs';export{default as IpcHandler}from'./core/ipc/IpcHandler.mjs';export{ElectronLogger as Logger}from'./infrastructure/logger/ElectronLogger.mjs';export{EnhancedDebugHelper,debugHelper}from'./infrastructure/debug/EnhancedDebugHelper.mjs';export{validateWindowManagerConfig}from'./core/window/window-manager.schema.mjs';export{IpcSetup}from'./core/window/IpcSetup.mjs';export{WindowError,WindowErrorCode}from'./core/error/WindowError.mjs';export{MessageBusClient}from'./core/message-bus/MessageBusClient.mjs';export{setupMessageBus}from'./core/message-bus/preload.mjs';export{MessageProtocolType}from'./core/message-bus/message-bus.type.mjs';export{ConfigManager}from'./infrastructure/config/ConfigManager.mjs';export{ErrorCategory,IpcErrorCode,MessageBusErrorCode,WindowManagerErrorCode}from'./infrastructure/errors/ErrorCodes.mjs';export{NotFoundError,PermissionError,StandardError,ValidationError}from'./infrastructure/errors/StandardError.mjs';/**
|
|
1
|
+
import WindowManager from'./core/window/WindowManager.mjs';import IpcRouter from'./core/ipc/IpcRouter.mjs';import {MessageBus}from'./core/message-bus/MessageBus.mjs';import {DebugHelper}from'./infrastructure/debug/index.mjs';import {getSharedLogger}from'./infrastructure/logger/index.mjs';export{setSharedLogger}from'./infrastructure/logger/index.mjs';export{LifecycleManager}from'./core/lifecycle/LifecycleManager.mjs';export{IpcRendererBridge,ipcRendererBridge}from'./preload/index.mjs';import*as types from'./types.mjs';export{types as Types };export{ElectronToolkitError,IpcHandlerError,WindowNotFoundError}from'./infrastructure/errors/index.mjs';export{default as WindowStore}from'./core/window/WindowStore.mjs';export{default as WindowCreator}from'./core/window/WindowCreator.mjs';export{default as IpcHandler}from'./core/ipc/IpcHandler.mjs';export{ElectronLogger as Logger}from'./infrastructure/logger/ElectronLogger.mjs';export{EnhancedDebugHelper,debugHelper}from'./infrastructure/debug/EnhancedDebugHelper.mjs';export{validateWindowManagerConfig}from'./core/window/window-manager.schema.mjs';export{IpcSetup}from'./core/window/IpcSetup.mjs';export{WindowError,WindowErrorCode}from'./core/error/WindowError.mjs';export{MessageBusClient}from'./core/message-bus/MessageBusClient.mjs';export{setupMessageBus}from'./core/message-bus/preload.mjs';export{MessageProtocolType}from'./core/message-bus/message-bus.type.mjs';export{ConfigManager}from'./infrastructure/config/ConfigManager.mjs';export{ErrorCategory,IpcErrorCode,MessageBusErrorCode,WindowManagerErrorCode}from'./infrastructure/errors/ErrorCodes.mjs';export{NotFoundError,PermissionError,StandardError,ValidationError}from'./infrastructure/errors/StandardError.mjs';/**
|
|
2
2
|
* Quick Start Helper
|
|
3
3
|
* 快速开始助手
|
|
4
4
|
* @param config - WindowManager configuration
|
|
5
5
|
* @returns Object containing initialized instances
|
|
6
6
|
*/
|
|
7
7
|
function createElectronToolkit(config = {}) {
|
|
8
|
+
const logger = config.logger || getSharedLogger(config.loggerOptions);
|
|
8
9
|
// Create IpcRouter
|
|
9
|
-
const ipcRouter = new IpcRouter({ logger
|
|
10
|
+
const ipcRouter = new IpcRouter({ logger });
|
|
10
11
|
// Create WindowManager with ipcRouter integrated
|
|
11
12
|
const windowManager = new WindowManager({
|
|
12
13
|
...config,
|
|
14
|
+
logger,
|
|
13
15
|
ipcRouter,
|
|
14
16
|
});
|
|
15
17
|
// Create MessageBus
|
|
16
|
-
const messageBus = new MessageBus({ logger
|
|
18
|
+
const messageBus = new MessageBus({ logger });
|
|
17
19
|
// Automatically integrate MessageBus with WindowManager
|
|
18
20
|
// 自动集成 MessageBus 和 WindowManager
|
|
19
21
|
messageBus.autoRegisterWindows(windowManager);
|
|
@@ -30,4 +32,4 @@ function createElectronToolkit(config = {}) {
|
|
|
30
32
|
ipcRouter,
|
|
31
33
|
messageBus,
|
|
32
34
|
};
|
|
33
|
-
}export{DebugHelper,IpcRouter,MessageBus,WindowManager,createElectronToolkit};//# sourceMappingURL=index.mjs.map
|
|
35
|
+
}export{DebugHelper,IpcRouter,MessageBus,WindowManager,createElectronToolkit,getSharedLogger};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import WindowManager from './core/window/WindowManager';\nimport IpcRouter from './core/ipc/IpcRouter';\nimport { MessageBus } from './core/message-bus/MessageBus';\nimport { WindowManagerConfig } from './core/window/window-manager.type';\nimport { DebugHelper } from './infrastructure/debug';\n\n/**\n * Quick Start Helper\n * 快速开始助手\n * @param config - WindowManager configuration\n * @returns Object containing initialized instances\n */\nexport function createElectronToolkit(config: WindowManagerConfig = {}) {\n // Create IpcRouter\n const ipcRouter = new IpcRouter({ logger
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import WindowManager from './core/window/WindowManager';\nimport IpcRouter from './core/ipc/IpcRouter';\nimport { MessageBus } from './core/message-bus/MessageBus';\nimport { WindowManagerConfig } from './core/window/window-manager.type';\nimport { DebugHelper } from './infrastructure/debug';\nimport { getSharedLogger } from './infrastructure/logger';\n\n/**\n * Quick Start Helper\n * 快速开始助手\n * @param config - WindowManager configuration\n * @returns Object containing initialized instances\n */\nexport function createElectronToolkit(config: WindowManagerConfig = {}) {\n const logger = config.logger || getSharedLogger(config.loggerOptions);\n // Create IpcRouter\n const ipcRouter = new IpcRouter({ logger });\n\n // Create WindowManager with ipcRouter integrated\n const windowManager = new WindowManager({\n ...config,\n logger,\n ipcRouter,\n });\n\n // Create MessageBus\n const messageBus = new MessageBus({ logger });\n\n // Automatically integrate MessageBus with WindowManager\n // 自动集成 MessageBus 和 WindowManager\n messageBus.autoRegisterWindows(windowManager);\n\n // Setup Debug Mode\n // 设置调试模式\n if (config.isDevelopment || process.env.NODE_ENV === 'development') {\n DebugHelper.enableDebugMode();\n DebugHelper.register('windowManager', windowManager);\n DebugHelper.register('ipcRouter', ipcRouter);\n DebugHelper.register('messageBus', messageBus);\n }\n\n return {\n windowManager,\n ipcRouter,\n messageBus,\n };\n}\n\nexport * from './core/window';\nexport * from './core/ipc';\nexport * from './core/message-bus';\nexport * from './core/lifecycle/LifecycleManager';\n// IpcTransport is internal, do not export\n// export { default as IpcTransport } from './ipc-transport'\nexport {\n Logger,\n type LoggerOptions,\n getSharedLogger,\n setSharedLogger,\n} from './infrastructure/logger';\nexport * from './preload';\n// Internal utils should not be exported\n// export * from './internal/utils';\nexport * from './infrastructure/config';\nexport * as Types from './types';\nexport { DebugHelper, debugHelper, EnhancedDebugHelper } from './infrastructure/debug';\nexport * from './infrastructure/errors';\n"],"names":[],"mappings":"ksDAOA;;;;;AAKG;AACG,SAAU,qBAAqB,CAAC,MAAA,GAA8B,EAAE,EAAA;AACpE,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC,MAAM,CAAC,aAAa,CAAC;;IAErE,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;;AAG3C,IAAA,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC;AACtC,QAAA,GAAG,MAAM;QACT,MAAM;QACN,SAAS;AACV,KAAA,CAAC;;IAGF,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;;;AAI7C,IAAA,UAAU,CAAC,mBAAmB,CAAC,aAAa,CAAC;;;AAI7C,IAAA,IAAI,MAAM,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;QAClE,WAAW,CAAC,eAAe,EAAE;AAC7B,QAAA,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC;AACpD,QAAA,WAAW,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;AAC5C,QAAA,WAAW,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC;IAChD;IAEA,OAAO;QACL,aAAa;QACb,SAAS;QACT,UAAU;KACX;AACH"}
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("electron"),require("tiny-typed-emitter"),require("zod"),require("uuid"),require("events"),require("fs"),require("path"),require("crypto"),require("electron-log")):"function"==typeof define&&define.amd?define(["exports","electron","tiny-typed-emitter","zod","uuid","events","fs","path","crypto","electron-log"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ElectronInfraKit={},e.Electron,e.tinyTypedEmitter,e.zod,e.uuid,e.events,e.fs,e.path,e.crypto,e.electronLog)}(this,function(e,t,s,i,r,o,n,a,d,h){"use strict";function c(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(s){if("default"!==s){var i=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,i.get?i:{enumerable:!0,get:function(){return e[s]}})}}),t.default=e,Object.freeze(t)}var l=c(n),g=c(a),u=c(d);class w{logger;isDev;constructor(e={}){this.isDev="production"!==process.env.NODE_ENV;const{appName:t="main",maxSize:s=10485760,fileName:i,fileLevel:r,consoleLevel:o}=e;this.logger=h.create({logId:t}),this.logger.scope(t);const n=this.isDev?"debug":"info",a=!!this.isDev&&"debug";this.logger.transports.file.level=r??n,this.logger.transports.console.level=o??a,this.logger.transports.file.format="[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}",this.logger.transports.file.maxSize=s,this.logger.transports.file.fileName=i??(this.isDev?`${t}_dev.log`:`${t}.log`)}info(e,...t){this.logger.info(e,...t)}debug(e,...t){this.logger.debug(e,...t)}error(e,...t){this.logger.error(e,...t)}warn(e,...t){this.logger.warn(e,...t)}verbose(e,...t){this.logger.verbose(e,...t)}silly(e,...t){this.logger.silly(e,...t)}getLogger(){return this.logger}}const p=i.z.custom(e=>"object"==typeof e&&null!==e&&"info"in e&&"warn"in e&&"error"in e&&"debug"in e&&"function"==typeof e.info&&"function"==typeof e.warn&&"function"==typeof e.error&&"function"==typeof e.debug,"Logger must implement ILogger interface with info/warn/error/debug methods"),m=i.z.custom(e=>"object"==typeof e&&null!==e&&"handle"in e&&"addHandler"in e&&"function"==typeof e.handle&&"function"==typeof e.addHandler,"IpcRouter must implement handle/addHandler methods"),f=i.z.custom(e=>"object"==typeof e&&null!==e&&"registerWindow"in e&&"unregisterWindow"in e&&"function"==typeof e.registerWindow&&"function"==typeof e.unregisterWindow,"MessageBus must implement registerWindow/unregisterWindow methods"),y=i.z.object({logger:p.optional(),ipcRouter:m.optional(),messageBus:f.optional(),isDevelopment:i.z.boolean().default(!1),preventExternalLinks:i.z.boolean().default(!0),defaultConfig:i.z.record(i.z.string(),i.z.any()).default({}),plugins:i.z.array(i.z.any()).default([]),hooks:i.z.record(i.z.string(),i.z.any()).default({}),ipc:i.z.object({autoInit:i.z.boolean().default(!0)}).default({autoInit:!0}),store:i.z.record(i.z.string(),i.z.any()).default({}),ipcSetup:i.z.function().optional(),ipcTransport:i.z.any().optional()}).strict();function S(e){const t=y.safeParse(e);return t.success?{success:!0,data:t.data}:{success:!1,error:t.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join("; ")}}class I{logger;windows=new Map;windowNames=new Map;windowIds=new Map;windowInstanceIds=new Map;_mainWindow=null;groups=new Map;windowGroups=new Map;cleanupTimer=null;constructor(e){this.logger=e}register(e,t,s){this.windows.set(e,s),this.windowNames.set(t,e),this.windowIds.set(e,t),this.windowInstanceIds.set(s,e),this._mainWindow||(this._mainWindow=s)}unregister(e){const t=this.windowGroups.get(e);t&&(t.forEach(t=>{const s=this.groups.get(t);s&&(s.delete(e),0===s.size&&this.groups.delete(t))}),this.windowGroups.delete(e));const s=this.windowIds.get(e);s&&this.windowNames.delete(s);const i=this.windows.get(e);i&&(this.windowInstanceIds.delete(i),this._mainWindow===i&&(this._mainWindow=null)),this.windows.delete(e),this.windowIds.delete(e)}addToGroup(e,t){this.windows.has(e)?(this.groups.has(t)||this.groups.set(t,new Set),this.groups.get(t).add(e),this.windowGroups.has(e)||this.windowGroups.set(e,new Set),this.windowGroups.get(e).add(t)):this.logger.warn(`Cannot add non-existent window ${e} to group ${t}`)}removeFromGroup(e,t){const s=this.groups.get(t);s&&(s.delete(e),0===s.size&&this.groups.delete(t));const i=this.windowGroups.get(e);i&&(i.delete(t),0===i.size&&this.windowGroups.delete(e))}getGroupIds(e){const t=this.groups.get(e);return t?Array.from(t):[]}getWindowGroups(e){const t=this.windowGroups.get(e);return t?Array.from(t):[]}clear(){this.windows.clear(),this.windowNames.clear(),this.windowIds.clear(),this.windowInstanceIds.clear(),this.groups.clear(),this.windowGroups.clear(),this._mainWindow=null,this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}getById(e){return this.windows.get(e)}getIdByName(e){return this.windowNames.get(e)}getByName(e){const t=this.windowNames.get(e);return t?this.windows.get(t):void 0}getNameById(e){return this.windowIds.get(e)}getIdByWindow(e){return this.windowInstanceIds.get(e)}hasId(e){return this.windows.has(e)}hasName(e){return this.windowNames.has(e)}getAllIds(){return Array.from(this.windows.keys())}getAllWindows(){return Array.from(this.windows.values())}getNameMap(){return this.windowNames}getCount(){return this.windows.size}setMainWindow(e){this._mainWindow=e}getMainWindow(){return this._mainWindow}updateWindowName(e,t){const s=this.windowIds.get(e);s&&this.windowNames.delete(s),this.windowNames.set(t,e),this.windowIds.set(e,t)}startCleanupProtection(e=3e4){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=setInterval(()=>{this.cleanupDestroyedWindows()},e),this.cleanupTimer.unref()}stopCleanupProtection(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}cleanupDestroyedWindows(){if(this.windows.size<=50)return void this.performCleanup(Array.from(this.windows.entries()));const e=Array.from(this.windows.entries());this.processCleanupChunk(e,0,50)}processCleanupChunk(e,t,s){if(t>=e.length)return;const i=Math.min(t+s,e.length),r=e.slice(t,i);this.performCleanup(r),i<e.length&&setImmediate(()=>{this.processCleanupChunk(e,i,s)})}performCleanup(e){const t=[];e.forEach(([e,s])=>{s.isDestroyed()&&t.push(e)}),t.length>0&&(this.logger.warn(`Found ${t.length} destroyed windows in registry. Cleaning up...`),t.forEach(e=>this.unregister(e)))}}class v{logger;constructor(e){this.logger=e}isSafe(e){return!!e&&!e.isDestroyed()}show(e){this.isSafe(e)&&(e.show(),e.setSkipTaskbar(!1))}hide(e){this.isSafe(e)&&(e.hide(),e.setSkipTaskbar(!0))}minimize(e){this.isSafe(e)&&e.minimize()}restore(e){this.isSafe(e)&&e.restore()}maximize(e){this.isSafe(e)&&e.maximize()}unmaximize(e){this.isSafe(e)&&e.unmaximize()}toggleFullScreen(e){this.isSafe(e)&&e.setFullScreen(!e.isFullScreen())}focus(e){this.isSafe(e)&&e.focus()}close(e){this.isSafe(e)&&e.close()}destroy(e){this.isSafe(e)&&e.destroy()}openDevTools(e){this.isSafe(e)&&e.webContents.openDevTools()}closeDevTools(e){this.isSafe(e)&&e.webContents.closeDevTools()}isDevToolsOpened(e){return!!this.isSafe(e)&&e.webContents.isDevToolsOpened()}send(e,t,s){this.isSafe(e)&&e.webContents.send(t,s)}setSkipTaskbar(e,t){this.isSafe(e)&&e.setSkipTaskbar(t)}}class E{persistence;logger;constructor(e,t){this.persistence=e,this.logger=t}async save(e,t){if(this.persistence)try{await this.persistence.save(e,t)}catch(t){this.logger.error(`Failed to save context for window ${e}: ${t}`)}else this.logger.warn("Context persistence is not enabled")}async load(e){if(!this.persistence)return null;try{return await this.persistence.load(e)}catch(t){return this.logger.error(`Failed to load context for window ${e}: ${t}`),null}}async clear(e){if(this.persistence)try{await this.persistence.clear(e)}catch(t){this.logger.error(`Failed to clear context for window ${e}: ${t}`)}}}class M{stateFile;state={};logger;saveTimer=null;throttleLastSave=0;saveDelay;saveStrategy;static activeFiles=new Set;hasLock=!1;isWriting=!1;pendingWrite=!1;lastSavedHash="";constructor(e={}){this.logger=e.logger||new w({appName:"StateKeeper"}),this.saveDelay=e.saveDelay??500,this.saveStrategy=e.saveStrategy??"debounce";const s=t.app.getPath("userData");this.stateFile=e.stateFilePath||g.join(s,"window-state.json"),M.activeFiles.has(this.stateFile)?(this.logger.warn(`State file "${this.stateFile}" is already in use by another StateKeeper instance. This may lead to data conflicts.`),this.hasLock=!1):(M.activeFiles.add(this.stateFile),this.hasLock=!0),this.loadState(),t.app.on("before-quit",()=>{this.flushSync()})}loadState(){try{if(l.existsSync(this.stateFile)){const e=l.readFileSync(this.stateFile,"utf-8");this.state=JSON.parse(e),this.lastSavedHash=u.createHash("md5").update(e).digest("hex")}}catch(e){this.logger.error(`Failed to load window state: ${e}`),this.state={}}}saveState(e,t){(function(e,t){if(e===t)return!0;if(!e||!t)return!1;const s=e.groups||[],i=t.groups||[],r=s.length===i.length&&[...s].sort().every((e,t)=>e===[...i].sort()[t]);return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height&&e.isMaximized===t.isMaximized&&e.isFullScreen===t.isFullScreen&&r&&(!e.displayBounds&&!t.displayBounds||!!e.displayBounds&&!!t.displayBounds&&e.displayBounds.x===t.displayBounds.x&&e.displayBounds.y===t.displayBounds.y&&e.displayBounds.width===t.displayBounds.width&&e.displayBounds.height===t.displayBounds.height)})(this.state[e],t)||(this.state[e]=t,this.persist())}flushSync(){this.saveTimer&&(clearTimeout(this.saveTimer),this.saveTimer=null);try{l.writeFileSync(this.stateFile,JSON.stringify(this.state,null,2))}catch(e){this.logger.error(`Failed to flush window state: ${e}`)}}persist(){if("throttle"===this.saveStrategy){const e=Date.now(),t=e-this.throttleLastSave;t>=this.saveDelay?(this.performSave(),this.throttleLastSave=e):(this.saveTimer&&clearTimeout(this.saveTimer),this.saveTimer=setTimeout(()=>{this.performSave(),this.throttleLastSave=Date.now()},this.saveDelay-t))}else this.saveTimer&&clearTimeout(this.saveTimer),this.saveTimer=setTimeout(()=>{this.performSave()},this.saveDelay)}async performSave(){if(this.isWriting)return void(this.pendingWrite=!0);this.isWriting=!0;const e=`${this.stateFile}.tmp`;try{const t=JSON.stringify(this.state,null,2),s=u.createHash("md5").update(t).digest("hex");if(s===this.lastSavedHash)return void(this.isWriting=!1);await l.promises.writeFile(e,t),await l.promises.rename(e,this.stateFile),this.lastSavedHash=s}catch(t){this.logger.error(`Failed to save window state: ${t}`);try{await l.promises.unlink(e)}catch(e){}}finally{this.saveTimer=null,this.isWriting=!1,this.pendingWrite&&(this.pendingWrite=!1,setImmediate(()=>this.performSave()))}}getWindowState(e,t=800,s=600){const i=this.state[e];return i&&this.isValidState(i)?i:{width:t,height:s,isMaximized:!1,isFullScreen:!1}}isValidState(e){const s=t.screen.getAllDisplays();return!(!e.displayBounds||!s.find(t=>t.bounds.x===e.displayBounds?.x&&t.bounds.y===e.displayBounds?.y&&t.bounds.width===e.displayBounds?.width&&t.bounds.height===e.displayBounds?.height)||void 0===e.x||void 0===e.y)||s.some(t=>{const{x:s,y:i,width:r,height:o}=t.bounds,n=e.x||0,a=e.y||0,d=e.width,h=e.height;return n<s+r&&n+d>s&&a<i+o&&a+h>i})}removeState(e){this.state[e]&&(delete this.state[e],this.persist())}dispose(){this.saveTimer&&(clearTimeout(this.saveTimer),this.saveTimer=null),this.hasLock&&M.activeFiles.delete(this.stateFile)}}class T{logger;stateKeeper;handlers=new Map;constructor(e,t){this.logger=e,this.stateKeeper=t||new M({logger:this.logger})}manage(e,s,i){this.unmanage(s.id);const r=()=>{if(!s.isDestroyed())try{const r=s.getBounds(),o=s.isMaximized(),n=s.isFullScreen(),a=t.screen.getDisplayMatching(r),d=i?i():void 0;this.stateKeeper.saveState(e,{x:r.x,y:r.y,width:r.width,height:r.height,isMaximized:o,isFullScreen:n,displayBounds:a.bounds,groups:d})}catch(t){this.logger.warn(`Failed to save state for window ${e}: ${t}`)}};s.on("resize",r),s.on("move",r),s.on("close",r),s.on("maximize",r),s.on("unmaximize",r),s.on("enter-full-screen",r),s.on("leave-full-screen",r),this.handlers.set(s.id,()=>{s.isDestroyed()||(s.removeListener("resize",r),s.removeListener("move",r),s.removeListener("close",r),s.removeListener("maximize",r),s.removeListener("unmaximize",r),s.removeListener("enter-full-screen",r),s.removeListener("leave-full-screen",r))}),s.once("closed",()=>{this.handlers.delete(s.id)})}unmanage(e){const t=this.handlers.get(e);t&&(t(),this.handlers.delete(e))}dispose(){this.handlers.forEach(e=>e()),this.handlers.clear(),this.stateKeeper&&"function"==typeof this.stateKeeper.dispose&&this.stateKeeper.dispose()}getState(e,t,s){return this.stateKeeper.getWindowState(e,t,s)}}const W="renderer-to-main",b="renderer-to-main-sync",N="message-bus-port",D="window-state-changed";class C extends o.EventEmitter{MAX_WINDOWS;enablePersistence=!1;logger;get persistenceEnabled(){return this.enablePersistence}registry;operator;contextManager;stateManager;focusHistory=[];constructor(e){super(),this.logger=e?.logger||new w({appName:"WindowStore"}),this.MAX_WINDOWS=e?.maxWindows||50,this.enablePersistence=e?.enablePersistence??!1,this.registry=new I(this.logger),this.operator=new v(this.logger),this.contextManager=new E(e?.contextPersistence,this.logger),this.stateManager=new T(this.logger,e?.stateKeeper),!1!==e?.autoStartCleanup&&this.startCleanupProtection(e?.cleanupInterval)}pushFocus(e){this.focusHistory=this.focusHistory.filter(t=>t!==e),this.focusHistory.push(e)}removeFocus(e){this.focusHistory=this.focusHistory.filter(t=>t!==e)}getPreviousFocusedWindow(){if(!(this.focusHistory.length<2))return this.focusHistory[this.focusHistory.length-2]}popFocus(){return this.focusHistory.pop()}joinGroup(e,t){this.registry.addToGroup(e,t)}leaveGroup(e,t){this.registry.removeFromGroup(e,t)}getGroup(e){return this.registry.getGroupIds(e)}async closeGroup(e){const t=this.registry.getGroupIds(e);if(!t||0===t.length)return;const s=t.map(t=>new Promise(s=>{try{setImmediate(()=>{this.operator.destroy(this.getTargetWindow(t)),s()})}catch(i){this.logger.error(`Failed to close window ${t} in group ${e}: ${i}`),s()}}));await Promise.all(s)}hideGroup(e){this.registry.getGroupIds(e).forEach(e=>this.hide(e))}showGroup(e){this.registry.getGroupIds(e).forEach(e=>{const t=this.getTargetWindow(e);t&&this.show(t)})}focusGroup(e){this.registry.getGroupIds(e).forEach(e=>this.focus(e))}show(e,t){this.operator.show(e)}hide(e){const t=this.getTargetWindow(e);t&&this.operator.hide(t)}isDestroyed(e){const t=this.getTargetWindow(e);return!t||t.isDestroyed()}isVisible(e){const t=this.getValidWindow(e);return t?.isVisible()||!1}isMinimized(e){return this.getTargetWindow(e)?.isMinimized()||!1}isMaximized(e){return this.getTargetWindow(e)?.isMaximized()||!1}fullScreenState(e){return this.getTargetWindow(e)?.isFullScreen()||!1}minimize(e){const t=this.getTargetWindow(e);t&&this.operator.minimize(t)}restore(e){const t=this.getValidWindow(e);t&&this.operator.restore(t)}maximize(e){const t=this.getValidWindow(e);t&&this.operator.maximize(t)}unmaximize(e){const t=this.getValidWindow(e);t&&this.operator.unmaximize(t)}fullScreen(e){const t=this.getValidWindow(e);t&&this.operator.toggleFullScreen(t)}focus(e){const t=this.getValidWindow(e);t&&this.operator.focus(t)}setMovable(e){e.setMovable(!0)}winClose(e){this.removeWindow(e)}openDevTools(e){const t=this.getTargetWindow(e);t&&this.operator.openDevTools(t)}isDevToolsOpened(e){const t=this.getTargetWindow(e);return!!t&&this.operator.isDevToolsOpened(t)}closeDevTools(e){const t=this.getTargetWindow(e);t&&this.operator.closeDevTools(t)}quit(){t.app.quit()}getWindowSize(){const{width:e,height:s}=t.screen.getPrimaryDisplay().workAreaSize;return{width:e,height:s}}send(e,t,s=""){const i=this.getTargetWindow(e);i&&this.operator.send(i,t,s)}setSkipTaskbar(e,t){const s=this.getTargetWindow(e);s&&this.operator.setSkipTaskbar(s,t)}get mainWindow(){return this.registry.getMainWindow()}set mainWindow(e){this.registry.setMainWindow(e)}getWindowCount(){return this.registry.getCount()}getAllWindowKeys(){return this.registry.getAllIds()}getAllWindows(){return this.registry.getAllWindows()}getWindowNames(){return this.registry.getNameMap()}getNameByWindowId(e){return this.registry.getNameById(e)}getWindowByNameId(e){return this.registry.getIdByName(e)}getWindowByName(e){return this.registry.getByName(e)}hasByName(e){return this.registry.hasName(e)}deleteByName(e){const t=this.registry.getIdByName(e);return!!t&&(this.registry.unregister(t),!0)}getWindowById(e){return this.registry.getById(e)}hasById(e){return this.registry.hasId(e)}deleteById(e){return!!this.registry.hasId(e)&&(this.registry.unregister(e),!0)}getWindowId(e){return this.registry.getIdByWindow(e)}updateWindowName(e,t){this.registry.updateWindowName(e,t)}getTargetWindow(e){return e?this.registry.getById(e)||this.registry.getByName(e):this.getCurrentWindow()}getValidWindow(e){const t=this.getTargetWindow(e);if(t&&!t.isDestroyed())return t;this.logger.warn(`Window ${e||"current"} not found or destroyed`)}getCurrentWindow(){const e=t.BrowserWindow.getFocusedWindow();return e&&!e.isDestroyed()?e:this.mainWindow??void 0}createWindow(e,t){if(this.registry.getCount()>=this.MAX_WINDOWS){const e=new Error(`Maximum window limit (${this.MAX_WINDOWS}) reached`);throw this.logger.error(e.message),e}const s=t?.windowId||r.v4();let i=t?.name||`window-${s}`;try{i=this.validateWindowName(i)}catch{this.logger.warn(`Window name "${i}" already exists, generating unique name`),i=`${i}-${Date.now()}`}return this.registerWindow(s,i,e,{enablePersistence:t?.enablePersistence}),s}removeWindow(e){const t=this.registry.getById(e);if(t&&!t.isDestroyed())try{this.operator.close(t),t.isDestroyed()||this.operator.destroy(t)}catch(t){this.logger.error(`Failed to remove window ${e}: ${t}`),this.emit("error",t)}this.registry.unregister(e)}validateWindowName(e){if(this.registry.hasName(e))throw new Error(`Window name "${e}" already exists`);return e}registerWindow(e,t,s,i){this.registry.register(e,t,s),(i?.enablePersistence??this.enablePersistence)&&this.stateManager.manage(t,s)}manageState(e,t,s){this.stateManager.manage(e,t,s)}getWindowGroups(e){return this.registry.getWindowGroups(e)}getWindowState(e,t,s){return this.stateManager.getState(e,t,s)}async saveWindowContext(e,t){await this.contextManager.save(e,t)}async loadWindowContext(e){return await this.contextManager.load(e)}async clearWindowContext(e){await this.contextManager.clear(e)}startCleanupProtection(e=3e4){this.registry.startCleanupProtection(e)}stopCleanupProtection(){this.registry.stopCleanupProtection()}async dispose(){this.logger.info("Disposing WindowStore..."),this.stopCleanupProtection();const e=this.getAllWindows();for(const t of e)t.isDestroyed()||t.close();this.registry.clear(),this.logger.info("WindowStore disposed")}}const O=()=>{};let R=class{channels=new Map;handlers=new Set;logger;constructor(e){this.logger=e||new w({appName:"IpcTransport"})}setLogger(e){this.logger=e}on(e,s=O){const i=async(t,...i)=>{try{this.logEvent(e,"on",i),await s(t,...i)}catch(s){this.logError(e,"on",s),t.sender.isDestroyed()||t.sender.send(`${e}:error`,this.serializeError(s))}};this.channels.has(e)||this.channels.set(e,new Map),this.channels.get(e).set(s,i),t.ipcMain.on(e,i)}handle(e,s=O){this.handlers.has(e)&&t.ipcMain.removeHandler(e),this.handlers.add(e),t.ipcMain.handle(e,async(t,...i)=>{try{return this.logEvent(e,"handle",i),{code:0,message:"success",data:await s(t,...i)}}catch(t){this.logError(e,"handle",t);const s="development"===process.env.NODE_ENV;return t&&"object"==typeof t&&"code"in t&&"category"in t?{code:t.code,message:t.message,data:null,category:t.category,details:t.details,stack:s?t.stack:void 0}:{code:t.code||500,message:t instanceof Error?t.message:String(t),data:null,stack:s&&t instanceof Error?t.stack:void 0}}})}removeListener(e,s){const i=this.channels.get(e);if(i){if(s){const r=i.get(s);r&&(t.ipcMain.removeListener(e,r),i.delete(s))}else{for(const s of i.values())t.ipcMain.removeListener(e,s);i.clear()}0===i.size&&this.channels.delete(e)}}removeAllListeners(e){if(e)this.removeListener(e);else{for(const e of this.channels.keys())this.removeListener(e);this.channels.clear()}}removeHandler(e){this.handlers.has(e)&&(t.ipcMain.removeHandler(e),this.handlers.delete(e))}removeAllHandlers(){for(const e of this.handlers)t.ipcMain.removeHandler(e);this.handlers.clear()}error(e){this.logger.error(`[IPC System Error]: ${e}`)}log(e){this.logger.info(`[IPC System Log]: ${e}`)}logEvent(e,t,s){try{const i=s[0]?.name,r=i?`[Action: ${i}]`:`[Args: ${this.safeStringify(s)}]`;this.logger.info(`[${t.toUpperCase()}] ${e} ${r}`)}catch{this.logger.info(`[${t.toUpperCase()}] ${e} [Args parsing failed]`)}}logError(e,t,s){const i=s instanceof Error?s.message:String(s),r=s instanceof Error?s.stack:"";this.logger.error(`[${t.toUpperCase()} ERROR] ${e}: ${i}`,r)}serializeError(e){if(e instanceof Error){const t={name:e.name,message:e.message,stack:e.stack};for(const s of Object.getOwnPropertyNames(e))["name","message","stack"].includes(s)||(t[s]=e[s]);return t}return"object"==typeof e&&null!==e?e:{message:String(e),name:"UnknownError"}}safeStringify(e){try{return JSON.stringify(e)}catch{return"[Circular or Non-serializable]"}}};class _{static defaultSetup(e,t){return _.setup({config:e.config,ipcRouter:e.ipcRouter,currentIpcChannel:e.currentIpcChannel,currentIpcSyncChannel:e.currentIpcSyncChannel,options:t})}static setup(e){const{config:t,ipcRouter:s,currentIpcChannel:i,currentIpcSyncChannel:r,options:o}=e,n=e.ipcTransport||new R,a=o?.channel||t.ipc?.channel||W,d=o?.syncChannel||t.ipc?.syncChannel||b;return i&&n.removeHandler(i),r&&n.removeListener(r),n.handle(a,async(e,t)=>{try{const i=e.sender?.id;return{code:0,message:"success",data:await s.handle(t,i)}}catch(e){return{code:e.code||500,message:e instanceof Error?e.message:String(e),data:null}}}),d&&n.on(d,(e,t)=>{try{const i=s.handle(t);e.returnValue={code:0,message:"success",data:i}}catch(t){e.returnValue={code:t.code||500,message:t instanceof Error?t.message:String(t),data:null}}}),{channel:a,syncChannel:d,ipcTransport:n}}}class P{metrics={creationTimes:[],totalCreated:0,totalDestroyed:0};recordCreation(e){this.metrics.creationTimes.push(e),this.metrics.totalCreated++}recordDestruction(){this.metrics.totalDestroyed++}getMetrics(e){const t=this.metrics.creationTimes.length>0?this.metrics.creationTimes.reduce((e,t)=>e+t,0)/this.metrics.creationTimes.length:0;return{windowCount:e,totalCreated:this.metrics.totalCreated,totalDestroyed:this.metrics.totalDestroyed,averageCreationTime:Math.round(t),memoryUsage:process.memoryUsage(),uptime:process.uptime()}}}class ${plugins=[];hooks={};logger;constructor(e,t=[],s={}){this.logger=e,this.plugins=t,this.hooks=s}addPlugin(e){this.plugins.push(e)}getPlugins(){return this.plugins}async initPlugins(e){for(const t of this.plugins)try{await(t.onInit?.(e))}catch(e){this.logger.error(`Plugin "${t.name}" initialization failed: ${e}`)}}async initPlugin(e,t){try{await(e.onInit?.(t))}catch(t){this.logger.error(`Plugin "${e.name}" initialization failed: ${t}`)}}onWillCreate(e){let t={...e};for(const e of this.plugins)if(e.onWillCreate){const s=e.onWillCreate(t);if(!1===s)return!1;s&&"object"==typeof s&&(t=s)}if(this.hooks.onWillCreate){const e=this.hooks.onWillCreate(t);if(!1===e)return!1;e&&"object"==typeof e&&(t=e)}return t}async onDidCreate(e){for(const t of this.plugins)try{await(t.onDidCreate?.(e))}catch(e){this.logger.error(`Plugin ${t.name} onDidCreate failed: ${e}`)}if(this.hooks.onDidCreate)try{await this.hooks.onDidCreate(e)}catch(e){this.logger.error(`Hook onDidCreate failed: ${e}`)}}async onWillDestroy(e){for(const t of this.plugins)try{await(t.onWillDestroy?.(e))}catch(e){this.logger.error(`Plugin ${t.name} onWillDestroy failed: ${e}`)}if(this.hooks.onWillDestroy)try{await this.hooks.onWillDestroy(e)}catch(e){this.logger.error(`Hook onWillDestroy failed: ${e}`)}}async onDidDestroy(e){for(const t of this.plugins)try{await(t.onDidDestroy?.(e))}catch(e){this.logger.error(`Plugin ${t.name} onDidDestroy failed: ${e}`)}if(this.hooks.onDidDestroy)try{await this.hooks.onDidDestroy(e)}catch(e){this.logger.error(`Hook onDidDestroy failed: ${e}`)}}}class k{static instance;logger;registry=new Map;performanceMetrics=[];metricsEnabled=!1;constructor(){this.logger=new w({appName:"DebugHelper"})}static getInstance(){return k.instance||(k.instance=new k),k.instance}register(e,t){this.registry.set(e,t),this.logger.info(`Registered component: ${e}`)}get(e){return this.registry.get(e)}getAll(){const e={};return this.registry.forEach((t,s)=>{e[s]=t}),e}enablePerformanceMonitoring(){this.metricsEnabled=!0,this.logger.info("Performance monitoring enabled")}disablePerformanceMonitoring(){this.metricsEnabled=!1,this.logger.info("Performance monitoring disabled")}recordMetric(e){this.metricsEnabled&&(this.performanceMetrics.push(e),this.performanceMetrics.length>1e3&&this.performanceMetrics.shift(),this.logger.info(`Performance: ${e.name} took ${e.duration.toFixed(2)}ms`,e.metadata))}getMetrics(){return[...this.performanceMetrics]}clearMetrics(){this.performanceMetrics=[],this.logger.info("Performance metrics cleared")}getStatistics(){const e={};return this.performanceMetrics.forEach(t=>{e[t.name]||(e[t.name]={count:0,total:0,min:1/0,max:-1/0,avg:0});const s=e[t.name];s.count++,s.total+=t.duration,s.min=Math.min(s.min,t.duration),s.max=Math.max(s.max,t.duration),s.avg=s.total/s.count}),e}createTimer(e,t){const s=performance.now();return()=>{const i=performance.now()-s;this.recordMetric({name:e,duration:i,timestamp:Date.now(),metadata:t})}}getWindowManagerInfo(){const e=this.registry.get("windowManager");if(!e)return null;try{const t=e.getAllWindows();return{windowCount:t.length,windows:t.map(e=>({isDestroyed:e.isDestroyed(),isVisible:e.isVisible(),isMinimized:e.isMinimized(),isMaximized:e.isMaximized(),title:e.getTitle()}))}}catch(e){return this.logger.error("Failed to get WindowManager info:",e),{error:"Failed to retrieve info"}}}getIpcRouterInfo(){return this.registry.get("ipcRouter")?{registered:!0,type:"IpcRouter"}:null}getMessageBusInfo(){const e=this.registry.get("messageBus");return e?{registeredWindows:e.getRegisteredWindows(),data:e.getData()}:null}getDebugSnapshot(){return{timestamp:Date.now(),components:{windowManager:this.getWindowManagerInfo(),ipcRouter:this.getIpcRouterInfo(),messageBus:this.getMessageBusInfo()},performance:{metrics:this.getMetrics(),statistics:this.getStatistics()}}}logSnapshot(){const e=this.getDebugSnapshot();console.log("=== Debug Snapshot ==="),console.log(JSON.stringify(e,null,2))}}const B=k.getInstance();class A{static instance;metrics=new Map;logger;constructor(e){this.logger=e||new w({appName:"PerformanceMonitor"})}static getInstance(e){return A.instance||(A.instance=new A(e)),A.instance}startMeasure(e,t,s){this.metrics.set(e,{name:t,startTime:performance.now(),metadata:s})}endMeasure(e,t){const s=this.metrics.get(e);if(!s)return;const i=performance.now()-s.startTime;return this.logger.info(`[Performance] ${s.name}: ${i.toFixed(2)}ms`,{...s.metadata,...t,duration:i}),this.metrics.delete(e),i}recordMetric(e,t,s){this.logger.info(`[Metric] ${e}: ${t}`,s)}}class L{static isDebugEnabled=!1;static enableDebugMode(){this.isDebugEnabled||(process.env.ELECTRON_TOOLKIT_DEBUG="true",this.isDebugEnabled=!0,"browser"===process.type&&(global.__ELECTRON_TOOLKIT_DEBUG__={instances:{},listInstances:()=>Object.keys(global.__ELECTRON_TOOLKIT_DEBUG__.instances),getInstance:e=>global.__ELECTRON_TOOLKIT_DEBUG__.instances[e]},console.log("[ElectronToolkit] Debug mode enabled. Access global.__ELECTRON_TOOLKIT_DEBUG__ for details.")))}static register(e,t){"browser"===process.type&&global.__ELECTRON_TOOLKIT_DEBUG__&&(global.__ELECTRON_TOOLKIT_DEBUG__.instances[e]=t)}}class x{api;data;winId;creator;extraOptions;logger;constructor(e,t,s,i,r){this.api=e,this.data=t,this.winId=t?.data?.winId||"",this.creator=s,this.extraOptions=i,this.logger=r||new w({appName:"WindowCreator"})}async createWindow(){let e=!1;if(this.winId&&this.api.window.hasById(this.winId)){if(!this.api.window.isDestroyed(this.winId))return{winId:this.winId,isNew:!1};this.logger.warn(`Window ${this.winId} is found in store but destroyed. Cleaning up and recreating.`),await this.api.window.removeWindow(this.winId)}const t=this.winId?{windowId:this.winId,...this.extraOptions?.(this.data.data)||{}}:this.data.data;return this.winId=await this.creator(t),e=!0,{winId:this.winId,isNew:!0}}showWindow(e,t){const s=this.api.window.getTargetWindow(e);s&&!s.isDestroyed()?t?s.once("ready-to-show",()=>{this.api.window.show(s,e)}):this.api.window.show(s,e):this.logger.error(`Failed to show window ${e}: Window not found or destroyed`)}async loadContent(e,t){const s=this.api.window.getTargetWindow(e);if(s&&!s.isDestroyed())if(t.loadWindowContent)try{await t.loadWindowContent(s)}catch(t){this.logger.error(`Custom loadWindowContent failed for window ${e}: ${t}`)}else if(this.data.contentLoader)try{await this.data.contentLoader(s,t)}catch(t){this.logger.error(`Global contentLoader failed for window ${e}: ${t}`)}else t.loadUrl?s.loadURL(t.loadUrl).catch(s=>{this.logger.error(`Failed to load URL "${t.loadUrl}" for window ${e}: ${s}`)}):t.loadFile&&s.loadFile(t.loadFile).catch(s=>{this.logger.error(`Failed to load file "${t.loadFile}" for window ${e}: ${s}`)})}async createAndShow(){try{const{isNew:e}=await this.createWindow();if(e){const e=this.winId?{windowId:this.winId,...this.extraOptions?.(this.data.data)||{}}:this.data.data;await this.loadContent(this.winId,e)}return this.showWindow(this.winId,e),this.winId}catch(e){throw this.logger.error(`Failed to create and show window: ${e}`),e}}}const z=!t.app.isPackaged;class F{wm;pluginExecutor;metrics;logger;constructor(e,t,s,i){this.wm=e,this.pluginExecutor=t,this.metrics=s,this.logger=i}async create(e={}){const s=Date.now(),i=A.getInstance(),r=`create-window-${Date.now()}`;i.startMeasure(r,"Window Creation",{name:e.name});const o=this.pluginExecutor.onWillCreate(e);if(!1===o)return"";(e=o).defaultConfig&&(this.wm.config.defaultConfig=e.defaultConfig),this.wm.config.isDevelopment=e.isDevelopment??z,this.logger.info(`Current Environment / 当前环境: ${JSON.stringify({appIsPackaged:t.app.isPackaged,cachedIsDev:z,finalConfigIsDev:this.wm.config.isDevelopment},null,2)}`);const n={window:{hasById:e=>this.wm.windowStore.hasById(e),isDestroyed:e=>this.wm.windowStore.isDestroyed(e),deleteByName:e=>{const t=this.wm.windowStore.getWindowByNameId(e);return!!t&&(this.removeWindow(t),!0)},deleteById:e=>!!this.wm.windowStore.hasById(e)&&(this.removeWindow(e),!0),getTargetWindow:e=>this.wm.windowStore.getTargetWindow(e),removeWindow:e=>this.removeWindow(e),show:(e,t)=>this.wm.windowStore.show(e,t)}},a=e.windowId||(e.name?this.wm.windowStore.getWindowByNameId(e.name):void 0);e.windowId&&this.wm.validateWindowId(e.windowId,"create");let d={...e};const h=e.enablePersistence??this.wm.windowStore.persistenceEnabled;if(h&&e.name){const t=this.wm.windowStore.getWindowState(e.name,e.width,e.height);t&&(d={...d,x:t.x,y:t.y,width:t.width,height:t.height,fullscreen:t.isFullScreen||e.fullscreen})}const c=new x(n,{data:{...d,winId:a},contentLoader:this.wm.config.contentLoader},async t=>{const s=this.wm.createBrowserWindow(t);if(h&&e.name){const t=this.wm.windowStore.getWindowState(e.name);t?.isMaximized&&!s.isFullScreen()&&s.maximize()}const i=this.wm.windowStore.createWindow(s,t);if(this.wm.configureWindowBehavior(s,i),t.name){const e=this.wm.windowStore.getWindowState(t.name);e&&e.groups&&Array.isArray(e.groups)&&e.groups.forEach(e=>{this.wm.windowStore.joinGroup(i,e)}),this.registerStateManagement(t.name,s)}const r={window:s,id:i,name:t.data.name||""};return await this.pluginExecutor.onDidCreate(r),this.wm.emit("window-created",r),i},void 0,this.logger),l=await c.createAndShow(),g=Date.now()-s;return this.metrics.recordCreation(g),g>2e3&&this.logger.warn(`Slow window creation detected: ${l} took ${g}ms`),i.endMeasure(r,{windowId:l}),l}async removeWindow(e){const t=A.getInstance(),s=`destroy-window-${e}`;t.startMeasure(s,"Window Destruction",{windowId:e}),this.wm.validateWindowId(e,"removeWindow"),await this.pluginExecutor.onWillDestroy(e),this.wm.emit("window-will-be-destroyed",e),this.wm.windowStore.removeWindow(e),this.metrics.recordDestruction(),await this.pluginExecutor.onDidDestroy(e),this.wm.emit("window-destroyed",e),t.endMeasure(s,{windowId:e})}registerStateManagement(e,t){this.wm.windowStore.persistenceEnabled&&this.wm.windowStore.manageState(e,t,()=>this.wm.windowStore.getWindowGroups(t.id.toString()))}}class G extends s.TypedEmitter{config={};ipcRouter;ipcTransport;messageBus;currentIpcChannel=null;currentIpcSyncChannel=null;logger;windowStore;metricsManager;pluginExecutor;lifecycle;isInitialized=!1;initPromise;initError=null;constructor(e={}){super();const t=S(e);if(!t.success)throw new Error(`Invalid WindowManager configuration: ${t.error}`);if(this.config=t.data,this.ipcRouter=this.config.ipcRouter,this.ipcTransport=this.config.ipcTransport,this.messageBus=this.config.messageBus,this.logger=this.config.logger||new w({appName:"WindowManager"}),e.logger){const t=["info","warn","error","debug"];for(const s of t)if("function"!=typeof e.logger[s])throw new Error(`config.logger must have ${t.join("/")} methods`)}if(e.ipcRouter&&"function"!=typeof e.ipcRouter.handle)throw new Error("config.ipcRouter must have handle/addHandler methods");this.windowStore=new C({logger:this.logger,...e.store||{}}),this.windowStore.on("error",e=>this.emit("error",e)),this.metricsManager=new P,this.pluginExecutor=new $(this.logger,e.plugins,e.hooks),this.lifecycle=new F(this,this.pluginExecutor,this.metricsManager,this.logger),this.messageBus&&this.messageBus.setGroupResolver(e=>this.windowStore.getGroup(e)),this.initPromise=this.init().then(async()=>{if(this.ipcRouter&&!1!==this.config.ipc?.autoInit)try{this.setupIPC()}catch(e){throw this.logger.warn(`Auto IPC setup failed: ${e}`),e}}).catch(e=>{throw this.initError=e instanceof Error?e:new Error(String(e)),this.logger.error(`WindowManager initialization failed: ${this.initError.message}`),this.emit("error",this.initError),this.initError})}async ready(){if(this.initError)throw this.initError;return this.initPromise}get initialized(){return this.isInitialized&&!this.initError}get initializationError(){return this.initError}async init(){this.isInitialized||(this.isInitialized=!0,await this.pluginExecutor.initPlugins(this))}use(e){return this.pluginExecutor.addPlugin(e),this.isInitialized&&this.pluginExecutor.initPlugin(e,this),this}setupIPC(e){let t;if(t=e?.setupImpl?e.setupImpl({config:this.config,ipcRouter:this.ipcRouter,currentIpcChannel:this.currentIpcChannel,currentIpcSyncChannel:this.currentIpcSyncChannel,options:e}):this.config.ipcSetup?this.config.ipcSetup(this,e):_.setup({config:this.config,ipcRouter:this.ipcRouter,currentIpcChannel:this.currentIpcChannel,currentIpcSyncChannel:this.currentIpcSyncChannel,options:e}),t)return this.currentIpcChannel=t.channel,this.currentIpcSyncChannel=t.syncChannel,void(t.ipcTransport&&(this.ipcTransport=t.ipcTransport));if(!this.ipcRouter)throw new Error("IpcRouter instance is required for IPC setup. Please pass it to the WindowManager constructor.")}async create(e={}){const t=A.getInstance(),s=`window-create-${Date.now()}`;t.startMeasure(s,"Window Creation",{name:e.name,width:e.width,height:e.height});try{const i=await this.lifecycle.create(e);return t.endMeasure(s,{status:"success",windowId:i}),i}catch(e){throw t.endMeasure(s,{status:"error",error:e instanceof Error?e.message:String(e)}),e}}async removeWindow(e){return this.lifecycle.removeWindow(e)}getMetrics(){return this.metricsManager.getMetrics(this.getWindowCount())}dispose(){this.logger.info("Disposing WindowManager..."),this.getAllWindowKeys().forEach(e=>{try{this.removeWindow(e)}catch(t){this.logger.error(`Failed to remove window ${e}: ${t}`)}}),this.windowStore.dispose(),this.ipcTransport&&(this.ipcTransport.removeAllHandlers(),this.ipcTransport.removeAllListeners()),this.ipcRouter&&"function"==typeof this.ipcRouter.dispose&&this.ipcRouter.dispose(),this.removeAllListeners(),this.logger.info("WindowManager disposed")}getMainWindowId(){return this.windowStore.mainWindow?this.windowStore.getWindowId(this.windowStore.mainWindow):void 0}createBrowserWindow(e){const s=this.getDefaultWindowConfig();return new t.BrowserWindow({...s,...e})}getDefaultWindowConfig(){return this.config.defaultConfig||{width:800,height:600,show:!1,webPreferences:{nodeIntegration:!1,contextIsolation:!0}}}configureWindowBehavior(e,s){this.config.isDevelopment&&this.windowStore.openDevTools(s),!1!==this.config.preventExternalLinks&&e.webContents.setWindowOpenHandler(e=>(t.shell.openExternal(e.url),{action:"deny"})),e.once("ready-to-show",()=>this.windowStore.show(e,s)),e.on("closed",()=>{this.windowStore.removeFocus(s),this.removeWindow(s)}),e.webContents.on("render-process-gone",(t,i)=>{this.logger.error(`Window ${s} crashed: ${i.reason} (Exit Code: ${i.exitCode})`);const{reason:r}=i;"crashed"!==r&&"oom"!==r||(this.logger.info(`Attempting to reload window ${s}...`),setTimeout(()=>{e.isDestroyed()||e.reload()},1e3))}),e.on("unresponsive",()=>{this.logger.warn(`Window ${s} is unresponsive`)}),e.on("focus",()=>{this.windowStore.pushFocus(s)}),e.isVisible()&&e.isFocused()&&this.windowStore.pushFocus(s)}joinGroup(e,t){this.windowStore.joinGroup(e,t)}leaveGroup(e,t){this.windowStore.leaveGroup(e,t)}getGroup(e){return this.windowStore.getGroup(e)}async closeGroup(e){await this.windowStore.closeGroup(e)}hideGroup(e){this.windowStore.hideGroup(e)}showGroup(e){this.windowStore.showGroup(e)}focusGroup(e){this.windowStore.focusGroup(e)}sendToGroup(e,t,s){if(!this.messageBus)return this.logger.warn("[WindowManager.sendToGroup] MessageBus not configured"),0;const i=this.windowStore.getGroup(e);return this.messageBus.broadcastToWindows(i,t,s)}focusPrevious(){const e=this.windowStore.getPreviousFocusedWindow();e&&this.windowStore.focus(e)}validateWindowId(e,t){if(!e||"string"!=typeof e||""===e.trim())throw new Error(`[WindowManager.${t}] Invalid windowId: must be a non-empty string`);return e}show(e,t){e&&!e.isDestroyed()?(void 0!==t&&this.validateWindowId(t,"show"),this.windowStore.show(e,t)):this.logger.warn("[WindowManager.show] Window is null or destroyed")}hide(e){this.windowStore.hide(this.validateWindowId(e,"hide"))}isDestroyed(e){return this.windowStore.isDestroyed(this.validateWindowId(e,"isDestroyed"))}isVisible(e){return this.windowStore.isVisible(this.validateWindowId(e,"isVisible"))}isMinimized(e){return this.windowStore.isMinimized(this.validateWindowId(e,"isMinimized"))}isMaximized(e){return this.windowStore.isMaximized(this.validateWindowId(e,"isMaximized"))}fullScreenState(e){return this.windowStore.fullScreenState(this.validateWindowId(e,"fullScreenState"))}minimize(e){e&&this.validateWindowId(e,"minimize"),this.windowStore.minimize(e)}restore(e){this.windowStore.restore(this.validateWindowId(e,"restore"))}maximize(e){this.windowStore.maximize(this.validateWindowId(e,"maximize"))}unmaximize(e){this.windowStore.unmaximize(this.validateWindowId(e,"unmaximize"))}fullScreen(e){this.windowStore.fullScreen(this.validateWindowId(e,"fullScreen"))}focus(e){this.windowStore.focus(this.validateWindowId(e,"focus"))}setMovable(e){e&&!e.isDestroyed()&&this.windowStore.setMovable(e)}close(e){this.windowStore.winClose(this.validateWindowId(e,"close"))}winClose(e){this.close(e)}openDevTools(e){this.windowStore.openDevTools(this.validateWindowId(e,"openDevTools"))}isDevToolsOpened(e){return this.windowStore.isDevToolsOpened(this.validateWindowId(e,"isDevToolsOpened"))}closeDevTools(e){this.windowStore.closeDevTools(this.validateWindowId(e,"closeDevTools"))}quit(){this.windowStore.quit()}getWindowSize(){return this.windowStore.getWindowSize()}send(e,t,s=""){this.windowStore.send(e,t,s)}setSkipTaskbar(e,t){this.windowStore.setSkipTaskbar(e,t)}get mainWindow(){return this.windowStore.mainWindow}getWindowCount(){return this.windowStore.getWindowCount()}getAllWindowKeys(){return this.windowStore.getAllWindowKeys()}getAllWindows(){return this.windowStore.getAllWindows()}getWindowNames(){return this.windowStore.getWindowNames()}getNameByWindowId(e){return this.windowStore.getNameByWindowId(e)}getWindowByNameId(e){return this.windowStore.getWindowByNameId(e)}getWindowByName(e){return this.windowStore.getWindowByName(e)}hasByName(e){return this.windowStore.hasByName(e)}deleteByName(e){return this.windowStore.deleteByName(e)}getWindowById(e){return this.windowStore.getWindowById(e)}hasById(e){return this.windowStore.hasById(e)}deleteById(e){return this.windowStore.deleteById(e)}getWindowId(e){return this.windowStore.getWindowId(e)}updateWindowName(e,t){this.windowStore.updateWindowName(e,t)}getTargetWindow(e){return this.windowStore.getTargetWindow(e)}getValidWindow(e){return this.windowStore.getValidWindow(e)}getCurrentWindow(){return this.windowStore.getCurrentWindow()}async saveWindowContext(e,t){await this.windowStore.saveWindowContext(e,t)}async loadWindowContext(e){return await this.windowStore.loadWindowContext(e)}async clearWindowContext(e){await this.windowStore.clearWindowContext(e)}startCleanupProtection(e=3e4){this.windowStore.startCleanupProtection(e)}stopCleanupProtection(){this.windowStore.stopCleanupProtection()}}class H{handlers=new Map;logger;errorHandler;constructor(e,t,s){this.logger=t||new w({appName:e}),this.errorHandler=s}register(e,t,s){this.handlers.has(e)&&this.logger.warn(`Handler "${e}" is being overwritten / 处理器 "${e}" 被覆盖`),this.handlers.set(e,{callback:t,metadata:s})}unregister(e){return this.handlers.delete(e)}getMetadata(e){return this.handlers.get(e)?.metadata}dispatch(e,t,s){const i=this.handlers.get(e);if(i)try{return i.callback(t,s)}catch(t){if(this.logger.error(`Error in handler "${e}": ${t} / 处理器 "${e}" 执行错误: ${t}`),this.errorHandler)return this.errorHandler(t,e);throw t}else this.logger.warn(`No handler found for "${e}" / 未找到处理器 "${e}"`)}has(e){return this.handlers.has(e)}getHandlerNames(){return Array.from(this.handlers.keys())}clear(){this.handlers.clear()}}var U,V,j,q;e.IpcErrorCode=void 0,(U=e.IpcErrorCode||(e.IpcErrorCode={}))[U.SUCCESS=0]="SUCCESS",U[U.BAD_REQUEST=400]="BAD_REQUEST",U[U.FORBIDDEN=403]="FORBIDDEN",U[U.NOT_FOUND=404]="NOT_FOUND",U[U.VALIDATION_ERROR=422]="VALIDATION_ERROR",U[U.INTERNAL_ERROR=500]="INTERNAL_ERROR",U[U.HANDLER_ERROR=501]="HANDLER_ERROR",e.MessageBusErrorCode=void 0,(V=e.MessageBusErrorCode||(e.MessageBusErrorCode={}))[V.SUCCESS=0]="SUCCESS",V[V.PERMISSION_DENIED=403]="PERMISSION_DENIED",V[V.NOT_FOUND=404]="NOT_FOUND",V[V.INVALID_OPERATION=400]="INVALID_OPERATION",V[V.INTERNAL_ERROR=500]="INTERNAL_ERROR",e.WindowManagerErrorCode=void 0,(j=e.WindowManagerErrorCode||(e.WindowManagerErrorCode={}))[j.SUCCESS=0]="SUCCESS",j[j.WINDOW_NOT_FOUND=404]="WINDOW_NOT_FOUND",j[j.WINDOW_ALREADY_EXISTS=409]="WINDOW_ALREADY_EXISTS",j[j.INVALID_CONFIG=400]="INVALID_CONFIG",j[j.CREATION_FAILED=500]="CREATION_FAILED",j[j.OPERATION_FAILED=500]="OPERATION_FAILED",e.ErrorCategory=void 0,(q=e.ErrorCategory||(e.ErrorCategory={})).VALIDATION="VALIDATION",q.PERMISSION="PERMISSION",q.NOT_FOUND="NOT_FOUND",q.INTERNAL="INTERNAL",q.BUSINESS="BUSINESS";class J extends Error{code;category;details;timestamp;constructor(t,s,i=e.ErrorCategory.INTERNAL,r){super(s),this.name="StandardError",this.code=t,this.category=i,this.details=r,this.timestamp=Date.now(),Error.captureStackTrace&&Error.captureStackTrace(this,J)}toResponse(e=!1){return{code:this.code,message:this.message,category:this.category,details:this.details,stack:e?this.stack:void 0,timestamp:this.timestamp}}static from(t,s=500){return t instanceof J?t:t instanceof Error?new J(s,t.message,e.ErrorCategory.INTERNAL,{originalError:t.name,stack:t.stack}):new J(s,String(t),e.ErrorCategory.INTERNAL,{originalError:t})}}class K extends Error{code;details;constructor(e,t,s){super(e),this.code=t,this.details=s,this.name="ElectronToolkitError"}}class X extends K{constructor(e,t){super(`IPC handler "${e}" failed: ${t.message}`,"IPC_HANDLER_ERROR",{handlerName:e,originalError:t})}}class Y{limits=new Map;state=new Map;defaultLimit=null;logger;cleanupTimer=null;cleanupInterval;constructor(e={}){this.logger=e.logger,this.defaultLimit=e.defaultLimit||null,this.cleanupInterval=e.cleanupInterval||6e4,this.startCleanup()}startCleanup(){this.cleanupTimer||(this.cleanupTimer=setInterval(()=>{this.cleanup()},this.cleanupInterval),this.cleanupTimer.unref())}stopCleanup(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}setLimit(e,t){this.limits.set(e,t)}check(e,t){const s=this.limits.get(t)||this.defaultLimit;if(!s)return!0;const i=Date.now();let r=this.state.get(e);return(!r||i>r.resetTime)&&(r={count:0,resetTime:i+s.interval},this.state.set(e,r)),r.count>=s.limit?(this.logger&&this.logger.warn(`Rate limit exceeded for ${e} (Rule: ${t}, Limit: ${s.limit}/${s.interval}ms)`),!1):(r.count++,!0)}clear(){this.state.clear()}cleanup(){const e=Date.now();for(const[t,s]of this.state.entries())e>s.resetTime&&this.state.delete(t)}}const Q=i.z.object({name:i.z.string({message:"Handler name is required"}),payload:i.z.unknown().optional()});class Z{_api={};dispatcher;rateLimiter;constructor(e={}){this.dispatcher=new H("IpcRouter",e.logger),this.rateLimiter=new Y({logger:e.logger,defaultLimit:e.defaultRateLimit})}addHandler(e){this.dispatcher.register(e.name,e.callback,e.schema)}addHandlers(e){e.forEach(e=>this.addHandler(e))}setRateLimit(e,t){this.rateLimiter.setLimit(e,t)}removeHandler(e){this.dispatcher.unregister(e)}handle(e,t){const s=A.getInstance(),i=`ipc-${String(e.name)}-${Date.now()}`;return(async()=>{try{if(s.startMeasure(i,"IPC Call",{handler:String(e.name),senderId:t}),void 0!==t){const s=`${t}:${String(e.name)}`;if(!this.rateLimiter.check(s,String(e.name)))throw new X(String(e.name),new Error(`Rate limit exceeded for handler "${String(e.name)}"`))}const r=Q.safeParse(e);if(!r.success)throw console.warn("[IpcRouter] Invalid IPC request data:",r.error.format()),new X("validation",new Error(`Invalid IPC request: ${r.error.message}`));const o=this.dispatcher.getMetadata(e.name);if(o){const t=o.safeParse(e.payload);if(!t.success)throw console.warn(`[IpcRouter] Invalid payload for handler "${String(e.name)}":`,t.error.message),new X(String(e.name),new Error(`Invalid payload: ${t.error.message}`))}const n={...this._api},a=await Promise.resolve(this.dispatcher.dispatch(e.name,n,e.payload));return s.endMeasure(i,{status:"success"}),a}catch(t){if(s.endMeasure(i,{status:"error",error:t instanceof Error?t.message:String(t)}),t instanceof X)throw t;throw new X(String(e.name),t)}})()}addApi(e,t){this._api[e]=t}addApis(e){Object.entries(e).forEach(([e,t])=>{this.addApi(e,t)})}dispose(){this.rateLimiter.stopCleanup(),this.rateLimiter.clear(),this.dispatcher.clear(),this._api={}}}var ee;e.MessageProtocolType=void 0,(ee=e.MessageProtocolType||(e.MessageProtocolType={})).GET="get",ee.GET_RESPONSE="get-response",ee.SET="set",ee.DELETE="delete",ee.CLEAR="clear",ee.MESSAGE="message",ee.SUBSCRIBE="subscribe",ee.UNSUBSCRIBE="unsubscribe",ee.SET_PERMISSION="set-permission",ee.CONNECT="__message_bus_ready__",ee.TRANSACTION_START="transaction-start",ee.TRANSACTION_COMMIT="transaction-commit",ee.TRANSACTION_ROLLBACK="transaction-rollback",ee.UPDATE="update",ee.SEND_TO_WINDOW="send-to-window",ee.SEND_TO_GROUP="send-to-group";class te{buffers=new Map;logger;constructor(e){this.logger=e}start(e){this.buffers.has(e)?this.logger.warn(`Transaction already started for window ${e}`):this.buffers.set(e,new Map)}commit(e){const t=this.buffers.get(e);if(t)return this.buffers.delete(e),t;this.logger.warn(`No transaction to commit for window ${e}`)}rollback(e){this.buffers.has(e)?this.buffers.delete(e):this.logger.warn(`No transaction to rollback for window ${e}`)}add(e,t,s){return!!this.buffers.has(e)&&(this.buffers.get(e).set(t,s),!0)}hasTransaction(e){return this.buffers.has(e)}getBufferedValue(e,t){if(this.buffers.has(e)){const s=this.buffers.get(e);if(s.has(t)){const e=s.get(t);return"set"===e.type?{has:!0,value:e.value}:{has:!0,value:void 0}}}return{has:!1}}clear(){this.buffers.clear()}}class se{subscriptions=new Map;logger;MAX_SUBSCRIPTIONS_PER_KEY=100;constructor(e){this.logger=e}subscribe(e,t){t.forEach(t=>{this.subscriptions.has(t)||this.subscriptions.set(t,new Set);const s=this.subscriptions.get(t);s.add(e),this.logger&&s.size>this.MAX_SUBSCRIPTIONS_PER_KEY&&s.size===this.MAX_SUBSCRIPTIONS_PER_KEY+1&&this.logger.warn(`High number of subscriptions (${s.size}) for key: "${t}". Potential memory leak or design issue.`)})}unsubscribe(e,t){t.forEach(t=>{const s=this.subscriptions.get(t);s&&(s.delete(e),0===s.size&&this.subscriptions.delete(t))})}removeWindow(e){this.subscriptions.forEach((t,s)=>{t.has(e)&&(t.delete(e),0===t.size&&this.subscriptions.delete(s))})}getSubscribers(e){return this.subscriptions.get(e)}clear(){this.subscriptions.clear()}}class ie{dataStore=new Map;get(e){return this.dataStore.get(e)?.value}getItem(e){return this.dataStore.get(e)}getAll(){const e={};return this.dataStore.forEach((t,s)=>{e[s]=t.value}),e}set(e,t){const s=this.dataStore.get(e);this.dataStore.set(e,{value:t,permission:s?.permission})}delete(e){this.dataStore.delete(e)}checkPermission(e,t,s){const i=this.dataStore.get(e);if(i?.permission){const r="string"==typeof i.permission?{mode:i.permission}:i.permission;if(r.readonly)return{success:!1,error:`Field "${e}" is readonly`};if(r.allowedWindows&&t&&!r.allowedWindows.includes(t))return{success:!1,error:`Window "${t}" is not allowed to ${s} "${e}"`}}return{success:!0}}setPermission(e,t){const s=this.dataStore.get(e);s?s.permission=t:this.dataStore.set(e,{value:void 0,permission:t})}clear(){this.dataStore.clear()}}class re{port;_isClosed=!1;constructor(e){this.port=e}get isClosed(){return this._isClosed}postMessage(e){if(this._isClosed)return!1;try{return this.port.postMessage(e),!0}catch(e){throw this._isClosed=!0,e}}close(){if(!this._isClosed){this._isClosed=!0;try{this.port.close()}catch(e){}}}get rawPort(){return this.port}}class oe{ports=new Map;logger;constructor(e){this.logger=e}register(e,s,i){this.unregister(e);const{port1:r,port2:o}=new t.MessageChannelMain,n=new re(r);this.ports.set(e,n),r.on("message",t=>{let s;try{s="string"==typeof t.data?JSON.parse(t.data):t.data}catch(t){return void this.logger.error(`Failed to parse message from window ${e}: ${t}`)}i(s,n)}),r.start();const a=()=>{try{s.webContents.postMessage(N,null,[o])}catch(t){this.logger.error(`Failed to post message to window ${e}: ${t}`),n.close(),this.ports.delete(e)}};s.webContents.isLoading()?s.webContents.once("did-finish-load",a):a()}unregister(e){const t=this.ports.get(e);return!!t&&(t.close(),this.ports.delete(e),!0)}get(e){return this.ports.get(e)}broadcast(e,t){let s=0;return(t||Array.from(this.ports.keys())).forEach(t=>{const i=this.ports.get(t);if(i)try{i.postMessage(e)&&s++}catch(e){this.logger.error(`Failed to broadcast to window ${t}: ${e}`)}}),s}dispose(){this.ports.forEach(e=>e.close()),this.ports.clear()}getAllWindowIds(){return Array.from(this.ports.keys())}}class ne{name="messageport";portManager;onMessage;constructor(e){this.portManager=new oe(e)}init(e){this.onMessage=e}registerWindow(e,t){this.portManager.register(e,t,(t,s)=>{this.onMessage&&this.onMessage(t,e)})}unregisterWindow(e){this.portManager.unregister(e)}send(e,t){const s=this.portManager.get(e);if(s){const e="string"==typeof t?t:JSON.stringify(t);s.postMessage(e)}}broadcast(e,t){const s="string"==typeof e?e:JSON.stringify(e);return this.portManager.broadcast(s,t)}dispose(){}}const ae="message-bus-ipc";class de{name="ipc";logger;windows=new Map;onMessage;constructor(e){this.logger=e,this.setupIpcListener()}setupIpcListener(){t.ipcMain.on(ae,(e,t)=>{const s=this.findWindowId(e.sender.id);s&&this.onMessage&&this.onMessage(t,s)})}findWindowId(e){for(const[t,s]of this.windows.entries())if(s.webContents.id===e)return t}init(e){this.onMessage=e}registerWindow(e,t){this.windows.set(e,t)}unregisterWindow(e){this.windows.delete(e)}send(e,t){const s=this.windows.get(e);s&&!s.isDestroyed()&&s.webContents.send(ae,t)}broadcast(e,t){let s=0;const i=t||Array.from(this.windows.keys());for(const t of i)try{this.send(t,e),s++}catch(e){this.logger.error(`Failed to send IPC message to ${t}`,e)}return s}dispose(){this.windows.clear(),t.ipcMain.removeAllListeners(ae)}}class he extends o.EventEmitter{eventName=D;logger;subscriptionManager;transactionManager;dataStoreManager;transport;transportMode;windows=new Map;dispatcher;groupResolver;watchCallbacks=new Set;windowSubscriptions=new WeakMap;constructor(e={}){super(),this.eventName=e.eventName||D,this.logger=e.logger||new w({appName:"MessageBus"}),this.dispatcher=new H("MessageBus",this.logger),this.subscriptionManager=new se(this.logger),this.transactionManager=new te(this.logger),this.dataStoreManager=new ie;const t=e.transportMode||"auto";this.transportMode=this.selectTransportMode(t),this.transport=this.createTransport(this.transportMode);try{this.transport.init((e,t)=>this.handleTransportMessage(e,t)),this.logger.info(`MessageBus initialized with ${this.transportMode} transport`)}catch(e){this.logger.error(`Failed to initialize ${this.transportMode} transport: ${e}. Falling back to IPC.`),this.transportMode="ipc",this.transport=new de(this.logger),this.transport.init((e,t)=>this.handleTransportMessage(e,t))}this.registerDefaultHandlers()}selectTransportMode(e){return"ipc"===e?"ipc":"messageport"===e?"messageport":void 0===t.MessageChannelMain?(this.logger.warn("MessageChannelMain not available, falling back to IPC transport"),"ipc"):"messageport"}createTransport(e){return"ipc"===e?new de(this.logger):new ne(this.logger)}handleTransportMessage(t,s){try{if(t&&t.type){const i=this.dispatcher.dispatch(t.type,this,{...t,windowId:s});t.requestId&&Promise.resolve(i).then(i=>{this.transport.send(s,{type:e.MessageProtocolType.GET_RESPONSE,requestId:t.requestId,value:i})}).catch(e=>{this.logger.error(`Error handling message ${t.type}: ${e}`)})}}catch(e){this.logger.error(`Failed to handle message from window ${s}: ${e}`)}}registerWindow(e,t){this.unregisterWindow(e),this.windows.set(e,t),this.transport.registerWindow(e,t)}unregisterWindow(e){const t=this.windows.get(e);if(t&&this.windowSubscriptions.has(t)){const s=this.windowSubscriptions.get(t);s&&(this.logger.info(`Cleaning up ${s.size} subscriptions for window ${e}`),s.forEach(e=>{try{e()}catch(e){}}),this.windowSubscriptions.delete(t))}this.transport.unregisterWindow(e),this.windows.delete(e),this.subscriptionManager.removeWindow(e),this.transactionManager.hasTransaction(e)&&this.transactionManager.rollback(e)}autoRegisterWindows(e){e.on("window-created",({window:e,id:t})=>{this.registerWindow(t,e)}),e.on("window-will-be-destroyed",e=>{this.unregisterWindow(e)})}dispose(){this.logger.info("Disposing MessageBus..."),this.watchCallbacks.forEach(e=>{try{e()}catch(e){this.logger.warn(`Failed to unsubscribe watch callback: ${e}`)}}),this.watchCallbacks.clear(),this.dispatcher.clear(),this.transport.dispose(),this.dataStoreManager.clear(),this.subscriptionManager.clear(),this.transactionManager.clear(),this.windows.clear(),this.removeAllListeners(),this.logger.info("MessageBus disposed")}registerHandler(e){this.on(e.eventName,e.callback)}registerHandlers(e){e.forEach(e=>this.registerHandler(e))}unregisterHandler(e){this.removeListener(e.eventName,e.callback)}unregisterHandlers(e){e.forEach(e=>this.unregisterHandler(e))}getData(e){return e?this.dataStoreManager.get(e):this.dataStoreManager.getAll()}checkPermission(e,t,s){return this.dataStoreManager.checkPermission(e,t,s)}setData(t,s,i,r,o=!1){const n=this.checkPermission(t,i,"modify");if(!n.success)return n;if(!o&&i&&this.transactionManager.hasTransaction(i))return this.transactionManager.add(i,t,{type:"set",value:s}),{success:!0};const a=this.dataStoreManager.getItem(t),d=a?.value;this.dataStoreManager.set(t,s);const h={type:e.MessageProtocolType.SET,key:t,value:s,oldValue:d,windowId:i,timestamp:Date.now()};return this.broadcastChange(h),this.emit(r||this.eventName,h),{success:!0}}deleteData(t,s,i,r=!1){const o=this.checkPermission(t,s,"delete");if(!o.success)return o;if(!r&&s&&this.transactionManager.hasTransaction(s))return this.transactionManager.add(s,t,{type:"delete"}),{success:!0};const n=this.dataStoreManager.getItem(t),a=n?.value;this.dataStoreManager.delete(t);const d={type:e.MessageProtocolType.DELETE,key:t,oldValue:a,windowId:s,timestamp:Date.now()};return this.broadcastChange(d),this.emit(i||this.eventName,d),{success:!0}}startTransaction(e){this.transactionManager.start(e)}commitTransaction(e){const t=this.transactionManager.commit(e);t&&t.forEach((t,s)=>{"set"===t.type?this.setData(s,t.value,e,void 0,!0):"delete"===t.type&&this.deleteData(s,e,void 0,!0)})}rollbackTransaction(e){this.transactionManager.rollback(e)}watch(t,s,i){const r=i=>{"key"in i&&i.key===t&&(i.type===e.MessageProtocolType.SET?s(i.value,i.oldValue):i.type===e.MessageProtocolType.DELETE&&s(void 0,i.oldValue))};this.on(this.eventName,r);const o=()=>{if(this.off(this.eventName,r),this.watchCallbacks.delete(o),i){const e=this.windows.get(i);e&&this.windowSubscriptions.has(e)&&this.windowSubscriptions.get(e)?.delete(o)}};if(this.watchCallbacks.add(o),i){const e=this.windows.get(i);e?(this.windowSubscriptions.has(e)||this.windowSubscriptions.set(e,new Set),this.windowSubscriptions.get(e).add(o)):this.logger.warn(`Window ${i} not found, watch subscription will not be auto-cleaned up on window destroy`)}return o}updateData(e,t,s){let i=this.dataStoreManager.get(e);if(s){const t=this.transactionManager.getBufferedValue(s,e);t.has&&(i=t.value)}const r="function"==typeof t?t(i):t;return this.setData(e,r,s)}setFieldPermission(e,t){this.dataStoreManager.setPermission(e,t)}getRegisteredWindows(){return Array.from(this.windows.keys())}registerMessageHandler(e){this.dispatcher.register(e.name,e.callback)}registerDefaultHandlers(){this.registerMessageHandler({name:e.MessageProtocolType.GET,callback:(e,{key:t}={})=>e.getData(t)}),this.registerMessageHandler({name:e.MessageProtocolType.SET,callback:(e,{key:t,value:s,windowId:i,eventName:r})=>e.setData(t,s,i,r)}),this.registerMessageHandler({name:e.MessageProtocolType.DELETE,callback:(e,{key:t,windowId:s,eventName:i})=>e.deleteData(t,s,i)}),this.registerMessageHandler({name:e.MessageProtocolType.SET_PERMISSION,callback:(e,{key:t,permission:s})=>e.setFieldPermission(t,s)}),this.registerMessageHandler({name:e.MessageProtocolType.SUBSCRIBE,callback:(e,{windowId:t,keys:s})=>e.subscribe(t,s)}),this.registerMessageHandler({name:e.MessageProtocolType.UNSUBSCRIBE,callback:(e,{windowId:t,keys:s})=>e.unsubscribe(t,s)}),this.registerMessageHandler({name:e.MessageProtocolType.TRANSACTION_START,callback:(e,{windowId:t})=>e.startTransaction(t)}),this.registerMessageHandler({name:e.MessageProtocolType.TRANSACTION_COMMIT,callback:(e,{windowId:t})=>e.commitTransaction(t)}),this.registerMessageHandler({name:e.MessageProtocolType.TRANSACTION_ROLLBACK,callback:(e,{windowId:t})=>e.rollbackTransaction(t)}),this.registerMessageHandler({name:e.MessageProtocolType.SEND_TO_WINDOW,callback:(e,{targetWindowId:t,channel:s,data:i})=>e.sendToWindow(t,s,i)}),this.registerMessageHandler({name:e.MessageProtocolType.SEND_TO_GROUP,callback:(e,{group:t,channel:s,data:i})=>e.sendToGroup(t,s,i)}),this.registerMessageHandler({name:e.MessageProtocolType.UPDATE,callback:(e,{key:t,value:s,windowId:i})=>e.setData(t,s,i)})}handleMessage(e,t){return this.dispatcher.dispatch(e,this,t)}initializeListener(){t.ipcMain.handle("message-bus-invoke",(e,{name:t,data:s})=>this.handleMessage(t,s))}setGroupResolver(e){this.groupResolver=e}sendToWindow(t,s,i){const r=A.getInstance(),o=`message-bus-send-${Date.now()}`;if(r.startMeasure(o,"MessageBus Send",{windowId:t,channel:s}),!this.windows.has(t))return this.logger.warn(`Window ${t} not found or not registered`),r.endMeasure(o,{status:"failed",reason:"window_not_found"}),!1;try{const n={type:e.MessageProtocolType.MESSAGE,channel:s,value:i,timestamp:Date.now()};return this.transport.send(t,JSON.stringify(n)),r.endMeasure(o,{status:"success"}),!0}catch(e){return this.logger.error(`Failed to send message to window ${t}: ${e}`),this.emit("error",e),r.endMeasure(o,{status:"error",error:e instanceof Error?e.message:String(e)}),!1}}sendToGroup(e,t,s){const i=A.getInstance(),r=`message-bus-broadcast-${Date.now()}`;if(i.startMeasure(r,"MessageBus Broadcast",{group:e,channel:t}),!this.groupResolver)return this.logger.warn("Group resolver not set, cannot send to group"),i.endMeasure(r,{status:"failed",reason:"no_group_resolver"}),0;const o=this.groupResolver(e),n=this.broadcastToWindows(o,t,s);return i.endMeasure(r,{status:"success",windowCount:o.length,successCount:n}),n}broadcastToWindows(t,s,i){const r={type:e.MessageProtocolType.MESSAGE,channel:s,value:i,timestamp:Date.now()},o=JSON.stringify(r);return this.transport.broadcast(o,t)}subscribe(e,t){this.subscriptionManager.subscribe(e,t)}unsubscribe(e,t){this.subscriptionManager.unsubscribe(e,t)}broadcastChange(e){const t=JSON.stringify(e);if("key"in e&&e.key){const s=this.subscriptionManager.getSubscribers(e.key);if(s)return void this.transport.broadcast(t,Array.from(s))}this.transport.broadcast(t)}}var ce;e.WindowErrorCode=void 0,(ce=e.WindowErrorCode||(e.WindowErrorCode={}))[ce.CONFIG_INVALID=1001]="CONFIG_INVALID",ce[ce.CONFIG_MISSING=1002]="CONFIG_MISSING",ce[ce.WINDOW_NOT_FOUND=2001]="WINDOW_NOT_FOUND",ce[ce.WINDOW_CREATION_FAILED=2002]="WINDOW_CREATION_FAILED",ce[ce.WINDOW_ALREADY_EXISTS=2003]="WINDOW_ALREADY_EXISTS",ce[ce.WINDOW_LIMIT_REACHED=2004]="WINDOW_LIMIT_REACHED",ce[ce.WINDOW_DESTROYED=2005]="WINDOW_DESTROYED",ce[ce.IPC_CONNECTION_FAILED=3001]="IPC_CONNECTION_FAILED",ce[ce.IPC_TIMEOUT=3002]="IPC_TIMEOUT",ce[ce.IPC_HANDLER_ERROR=3003]="IPC_HANDLER_ERROR",ce[ce.INTERNAL_ERROR=5001]="INTERNAL_ERROR",ce[ce.DEPENDENCY_MISSING=5002]="DEPENDENCY_MISSING";class le extends Error{code;originalError;details;suggestion;constructor(e){super(e.message),this.name="WindowError",this.code=e.code,this.originalError=e.originalError,this.details=e.details,this.suggestion=e.suggestion,Object.setPrototypeOf(this,le.prototype)}getErrorCategory(){return this.code>=1e3&&this.code<2e3?"configuration":this.code>=2e3&&this.code<3e3?"window":this.code>=3e3&&this.code<4e3?"ipc":this.code>=5e3&&this.code<6e3?"system":"unknown"}toJSON(){return{name:this.name,message:this.message,code:this.code,category:this.getErrorCategory(),details:this.details,suggestion:this.suggestion}}}class ge{bindings;channel=W;syncChannel=b;constructor(){this.bindings={invoke:this.invoke.bind(this),sendSync:this.sendSync.bind(this)}}configure(e){e.channel&&(this.channel=e.channel),e.syncChannel&&(this.syncChannel=e.syncChannel)}invoke=async(e,s)=>{const i=await t.ipcRenderer.invoke(this.channel,{name:e,payload:s});if(i&&"object"==typeof i&&"code"in i){if(0===i.code)return i.data;throw new Error(i.message||`IPC Error: ${i.code}`)}return i};sendSync=(e,s)=>{const i=t.ipcRenderer.sendSync(this.syncChannel,{name:e,payload:s});if(i&&"object"==typeof i&&"code"in i){if(0===i.code)return i.data;throw new Error(i.message||`IPC Error: ${i.code}`)}return i};getBindings(){return this.bindings}exposeApi(e="ipcApi"){try{t.contextBridge.exposeInMainWorld(e,this.bindings)}catch(e){console.error("[IpcRendererBridge] Failed to expose API:",e)}}}const ue=new ge;class we extends s.TypedEmitter{config={};filePath;logger;autoSave;saveTimer=null;saveDelay;schema;constructor(e={}){super(),this.logger=e.logger||new w({appName:"ConfigManager"}),this.autoSave=e.autoSave??!0,this.saveDelay=e.saveDelay||100,this.schema=e.schema;const s=t.app.getPath("userData");this.filePath=g.join(s,e.filename||"config.json"),this.load()}get(e,t){const s=this.getDeep(this.config,e);return void 0===s?t:s}set(e,t){const s=this.get(e);if(JSON.stringify(s)!==JSON.stringify(t)){if(this.schema){const s=JSON.parse(JSON.stringify(this.config));this.setDeep(s,e,t);const i=this.schema.safeParse(s);if(!i.success)throw new Error(`Configuration validation failed: ${i.error.message}`)}this.setDeep(this.config,e,t),this.emit("change",e,t,s),this.autoSave&&this.triggerSave()}}delete(e){if(!this.has(e))return;const t=this.get(e);this.deleteDeep(this.config,e),this.emit("change",e,void 0,t),this.autoSave&&this.triggerSave()}has(e){return void 0!==this.getDeep(this.config,e)}clear(){this.config={},this.emit("change","",{},{}),this.autoSave&&this.triggerSave()}async save(){this.saveTimer&&(clearTimeout(this.saveTimer),this.saveTimer=null);try{const e=JSON.stringify(this.config,null,2);await l.promises.writeFile(this.filePath,e,"utf-8"),this.emit("saved")}catch(e){const t=e instanceof Error?e:new Error(String(e));this.logger.error(`Failed to save configuration: ${t.message}`),this.emit("error",t)}}load(){try{if(l.existsSync(this.filePath)){const e=l.readFileSync(this.filePath,"utf-8");let t=JSON.parse(e);if(this.schema){const e=this.schema.safeParse(t);e.success?t=e.data:(this.logger.error(`Configuration validation failed: ${e.error.message}`),this.emit("error",new Error(`Configuration validation failed: ${e.error.message}`)))}this.config=t,this.emit("loaded",this.config),this.logger.info(`Configuration loaded from ${this.filePath}`)}else this.logger.info("No configuration file found, starting with empty config")}catch(e){const t=e instanceof Error?e:new Error(String(e));this.logger.error(`Failed to load configuration: ${t.message}`),this.emit("error",t)}}getAll(){return JSON.parse(JSON.stringify(this.config))}triggerSave(){this.saveTimer&&clearTimeout(this.saveTimer),this.saveTimer=setTimeout(()=>{this.save()},this.saveDelay)}getDeep(e,t){if(!t)return;const s=t.split(".");let i=e;for(const e of s){if(null==i)return;i=i[e]}return i}setDeep(e,t,s){if(!t)return;const i=t.split("."),r=i.pop();let o=e;for(const e of i)void 0!==o[e]&&null!==o[e]&&"object"==typeof o[e]||(o[e]={}),o=o[e];o[r]=s}deleteDeep(e,t){if(!t)return;const s=t.split("."),i=s.pop();let r=e;for(const e of s){if(void 0===r[e]||null===r[e])return;r=r[e]}delete r[i]}}var pe=Object.freeze({__proto__:null,get MessageProtocolType(){return e.MessageProtocolType},createChannelName:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid channel name: must be a non-empty string");return e},createEventName:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid event name: must be a non-empty string");return e},createFieldKey:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid field key: must be a non-empty string");return e},createHandlerName:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid handler name: must be a non-empty string");return e},createWindowId:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid window ID: must be a non-empty string");return e}});e.ConfigManager=we,e.DebugHelper=L,e.ElectronToolkitError=K,e.EnhancedDebugHelper=k,e.IpcHandler=class{_name;_event;_callback;_schema;constructor(e,t,s,i){this._name=e,this._event=t,this._callback=s,this._schema=i}get name(){return this._name}get event(){return this._event}get callback(){return this._callback}get schema(){return this._schema}},e.IpcHandlerError=X,e.IpcRendererBridge=ge,e.IpcRouter=Z,e.IpcSetup=_,e.LifecycleManager=class{windowManager;ipcRouter;messageBus;logger;isStarted=!1;config;constructor(e={}){this.config=e,this.logger=e.logger||new w({appName:"LifecycleManager"}),e.autoStart&&this.startup().catch(e=>{this.logger.error(`Auto-startup failed: ${e}`)})}async startup(){if(this.isStarted)this.logger.warn("LifecycleManager already started");else try{this.logger.info("Starting up Electron Toolkit services..."),this.ipcRouter=this.config.ipcRouter||new Z({logger:this.config.logger}),this.logger.info("IpcRouter initialized"),this.messageBus=this.config.messageBus||new he({logger:this.config.logger}),this.windowManager=this.config.windowManager||new G({...this.config,ipcRouter:this.ipcRouter,messageBus:this.messageBus}),await this.windowManager.ready(),this.logger.info("WindowManager initialized"),this.messageBus.autoRegisterWindows(this.windowManager),this.logger.info("MessageBus initialized"),(this.config.isDevelopment||"development"===process.env.NODE_ENV)&&(L.enableDebugMode(),L.register("windowManager",this.windowManager),L.register("ipcRouter",this.ipcRouter),L.register("messageBus",this.messageBus),L.register("lifecycleManager",this),this.logger.info("Debug mode enabled")),this.isStarted=!0,this.logger.info("Startup completed successfully")}catch(e){throw this.logger.error(`Startup failed: ${e}`),await this.shutdown(),e}}async shutdown(){if(this.logger.info("Shutting down Electron Toolkit services..."),this.messageBus){try{this.messageBus.dispose(),this.logger.info("MessageBus disposed")}catch(e){this.logger.warn(`MessageBus dispose error: ${e}`)}this.messageBus=void 0}if(this.windowManager){try{"function"==typeof this.windowManager.dispose?(await this.windowManager.dispose(),this.logger.info("WindowManager disposed")):this.windowManager.stopCleanupProtection()}catch(e){this.logger.warn(`WindowManager dispose error: ${e}`)}this.windowManager=void 0}if(this.ipcRouter){try{this.ipcRouter.dispose(),this.logger.info("IpcRouter disposed")}catch(e){this.logger.warn(`IpcRouter dispose error: ${e}`)}this.ipcRouter=void 0}this.isStarted=!1,this.logger.info("Shutdown completed")}get started(){return this.isStarted}},e.Logger=w,e.MessageBus=he,e.MessageBusClient=class{port=null;ready=!1;pendingOperations=[];subscriptions=new Map;messageListeners=new Map;pendingRequests=new Map;logger;constructor(e={}){this.logger=e.logger||new w({appName:"MessageBusClient"}),this.initialize()}subscribe(t,s){return this.subscriptions.has(t)||(this.subscriptions.set(t,new Set),this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.SUBSCRIBE,keys:[t]}))})),this.subscriptions.get(t).add(s),()=>{this.subscriptions.get(t)?.delete(s),0===this.subscriptions.get(t)?.size&&(this.subscriptions.delete(t),this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.UNSUBSCRIBE,keys:[t]}))}))}}watch(e,t){return this.subscribe(e,t)}onMessage(e,t){return this.messageListeners.has(e)||this.messageListeners.set(e,new Set),this.messageListeners.get(e).add(t),()=>{this.messageListeners.get(e)?.delete(t),0===this.messageListeners.get(e)?.size&&this.messageListeners.delete(e)}}sendToWindow(t,s,i){this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.SEND_TO_WINDOW,targetWindowId:t,channel:s,data:i}))})}sendToGroup(t,s,i){this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.SEND_TO_GROUP,group:t,channel:s,data:i}))})}set(t,s){this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.SET,key:t,value:s}))})}async get(t){return new Promise(s=>{this.ensureReady(()=>{const i=r.v4(),o=setTimeout(()=>{this.pendingRequests.has(i)&&(this.pendingRequests.delete(i),this.logger.warn(`Get request for key "${t}" timed out`),s(void 0))},5e3);this.pendingRequests.set(i,{resolve:s,timeout:o}),this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.GET,key:t,requestId:i}))})})}delete(t){this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.DELETE,key:t}))})}initialize(){window.addEventListener("message",t=>{t.data?.type===e.MessageProtocolType.CONNECT&&(this.port=t.ports[0],this.port.onmessage=this.handleMessage.bind(this),this.port.start(),this.ready=!0,this.logger.debug("MessageBusClient connected"),this.pendingOperations.forEach(e=>e()),this.pendingOperations=[])})}handleMessage(t){try{const s=JSON.parse(t.data);if(s.type===e.MessageProtocolType.GET_RESPONSE&&s.requestId){const e=this.pendingRequests.get(s.requestId);return void(e&&(clearTimeout(e.timeout),this.pendingRequests.delete(s.requestId),e.resolve(s.value)))}if("message"===s.type&&s.channel){const e=this.messageListeners.get(s.channel);return void(e&&e.forEach(e=>{try{e(s.value)}catch(e){this.logger.error(`Error in message listener for channel "${s.channel}": ${e}`)}}))}if(s.key&&(s.type===e.MessageProtocolType.SET||s.type===e.MessageProtocolType.DELETE)){const e=this.subscriptions.get(s.key);e&&e.forEach(e=>{try{e(s.value)}catch(e){this.logger.error(`Error in subscription callback for key "${s.key}": ${e}`)}})}}catch(e){this.logger.error(`Failed to handle message: ${e}`)}}ensureReady(e){this.ready?e():this.pendingOperations.push(e)}dispose(){this.port&&(this.port.close(),this.port=null),this.subscriptions.clear(),this.pendingOperations=[],this.pendingRequests.forEach(e=>{clearTimeout(e.timeout),e.resolve(void 0)}),this.pendingRequests.clear(),this.ready=!1}},e.NotFoundError=class extends J{constructor(t,s){super(404,t,e.ErrorCategory.NOT_FOUND,s),this.name="NotFoundError"}},e.PermissionError=class extends J{constructor(t,s){super(403,t,e.ErrorCategory.PERMISSION,s),this.name="PermissionError"}},e.StandardError=J,e.Types=pe,e.ValidationError=class extends J{constructor(t,s){super(422,t,e.ErrorCategory.VALIDATION,s),this.name="ValidationError"}},e.WindowCreator=x,e.WindowError=le,e.WindowManager=G,e.WindowNotFoundError=class extends K{constructor(e){super(`Window "${e}" not found or destroyed`,"WINDOW_NOT_FOUND",{windowId:e})}},e.WindowStore=C,e.createElectronToolkit=function(e={}){const t=new Z({logger:e.logger}),s=new G({...e,ipcRouter:t}),i=new he({logger:e.logger});return i.autoRegisterWindows(s),(e.isDevelopment||"development"===process.env.NODE_ENV)&&(L.enableDebugMode(),L.register("windowManager",s),L.register("ipcRouter",t),L.register("messageBus",i)),{windowManager:s,ipcRouter:t,messageBus:i}},e.debugHelper=B,e.ipcRendererBridge=ue,e.setupMessageBus=function(){t.ipcRenderer.on(N,t=>{const[s]=t.ports;s?window.postMessage({type:e.MessageProtocolType.CONNECT,port:s},"*",[s]):console.error("[MessageBus] No port received in message-bus-port event")})},e.validateWindowManagerConfig=S});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("electron"),require("tiny-typed-emitter"),require("zod"),require("uuid"),require("events"),require("fs"),require("path"),require("crypto"),require("electron-log")):"function"==typeof define&&define.amd?define(["exports","electron","tiny-typed-emitter","zod","uuid","events","fs","path","crypto","electron-log"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ElectronInfraKit={},e.Electron,e.tinyTypedEmitter,e.zod,e.uuid,e.events,e.fs,e.path,e.crypto,e.electronLog)}(this,function(e,t,s,i,r,o,n,a,d,h){"use strict";function c(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(s){if("default"!==s){var i=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,i.get?i:{enumerable:!0,get:function(){return e[s]}})}}),t.default=e,Object.freeze(t)}var l=c(n),g=c(a),u=c(d);class w{logger;isDev;constructor(e={}){this.isDev="production"!==process.env.NODE_ENV;const{appName:t="main",maxSize:s=10485760,fileName:i,fileLevel:r,consoleLevel:o,ipcEnabled:n,ipcLevel:a}=e;this.logger=h.create({logId:t}),this.logger.scope(t);const d=this.isDev?"silly":"info";this.logger.transports.ipc.level=a??(!!n&&d);const c=this.isDev?"debug":"info",l=!!this.isDev&&"debug";this.logger.transports.file.level=r??c,this.logger.transports.console.level=o??l,this.logger.transports.file.format="[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}",this.logger.transports.file.maxSize=s,this.logger.transports.file.fileName=i??(this.isDev?`${t}_dev.log`:`${t}.log`)}info(e,...t){this.logger.info(e,...t)}debug(e,...t){this.logger.debug(e,...t)}error(e,...t){this.logger.error(e,...t)}warn(e,...t){this.logger.warn(e,...t)}verbose(e,...t){this.logger.verbose(e,...t)}silly(e,...t){this.logger.silly(e,...t)}getLogger(){return this.logger}}let p=null;function m(e){return p||(p=new w(e)),p}const f=i.z.custom(e=>"object"==typeof e&&null!==e&&"info"in e&&"warn"in e&&"error"in e&&"debug"in e&&"function"==typeof e.info&&"function"==typeof e.warn&&"function"==typeof e.error&&"function"==typeof e.debug,"Logger must implement ILogger interface with info/warn/error/debug methods"),y=i.z.custom(e=>"object"==typeof e&&null!==e&&"handle"in e&&"addHandler"in e&&"function"==typeof e.handle&&"function"==typeof e.addHandler,"IpcRouter must implement handle/addHandler methods"),S=i.z.custom(e=>"object"==typeof e&&null!==e&&"registerWindow"in e&&"unregisterWindow"in e&&"function"==typeof e.registerWindow&&"function"==typeof e.unregisterWindow,"MessageBus must implement registerWindow/unregisterWindow methods"),I=i.z.object({logger:f.optional(),ipcRouter:y.optional(),messageBus:S.optional(),isDevelopment:i.z.boolean().default(!1),preventExternalLinks:i.z.boolean().default(!0),defaultConfig:i.z.record(i.z.string(),i.z.any()).default({}),plugins:i.z.array(i.z.any()).default([]),hooks:i.z.record(i.z.string(),i.z.any()).default({}),ipc:i.z.object({autoInit:i.z.boolean().default(!0)}).default({autoInit:!0}),store:i.z.record(i.z.string(),i.z.any()).default({}),ipcSetup:i.z.function().optional(),ipcTransport:i.z.any().optional()}).strict();function v(e){const t=I.safeParse(e);return t.success?{success:!0,data:t.data}:{success:!1,error:t.error.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join("; ")}}class E{logger;windows=new Map;windowNames=new Map;windowIds=new Map;windowInstanceIds=new Map;_mainWindow=null;groups=new Map;windowGroups=new Map;cleanupTimer=null;constructor(e){this.logger=e}register(e,t,s){this.windows.set(e,s),this.windowNames.set(t,e),this.windowIds.set(e,t),this.windowInstanceIds.set(s,e),this._mainWindow||(this._mainWindow=s)}unregister(e){const t=this.windowGroups.get(e);t&&(t.forEach(t=>{const s=this.groups.get(t);s&&(s.delete(e),0===s.size&&this.groups.delete(t))}),this.windowGroups.delete(e));const s=this.windowIds.get(e);s&&this.windowNames.delete(s);const i=this.windows.get(e);i&&(this.windowInstanceIds.delete(i),this._mainWindow===i&&(this._mainWindow=null)),this.windows.delete(e),this.windowIds.delete(e)}addToGroup(e,t){this.windows.has(e)?(this.groups.has(t)||this.groups.set(t,new Set),this.groups.get(t).add(e),this.windowGroups.has(e)||this.windowGroups.set(e,new Set),this.windowGroups.get(e).add(t)):this.logger.warn(`Cannot add non-existent window ${e} to group ${t}`)}removeFromGroup(e,t){const s=this.groups.get(t);s&&(s.delete(e),0===s.size&&this.groups.delete(t));const i=this.windowGroups.get(e);i&&(i.delete(t),0===i.size&&this.windowGroups.delete(e))}getGroupIds(e){const t=this.groups.get(e);return t?Array.from(t):[]}getWindowGroups(e){const t=this.windowGroups.get(e);return t?Array.from(t):[]}clear(){this.windows.clear(),this.windowNames.clear(),this.windowIds.clear(),this.windowInstanceIds.clear(),this.groups.clear(),this.windowGroups.clear(),this._mainWindow=null,this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}getById(e){return this.windows.get(e)}getIdByName(e){return this.windowNames.get(e)}getByName(e){const t=this.windowNames.get(e);return t?this.windows.get(t):void 0}getNameById(e){return this.windowIds.get(e)}getIdByWindow(e){return this.windowInstanceIds.get(e)}hasId(e){return this.windows.has(e)}hasName(e){return this.windowNames.has(e)}getAllIds(){return Array.from(this.windows.keys())}getAllWindows(){return Array.from(this.windows.values())}getNameMap(){return this.windowNames}getCount(){return this.windows.size}setMainWindow(e){this._mainWindow=e}getMainWindow(){return this._mainWindow}updateWindowName(e,t){const s=this.windowIds.get(e);s&&this.windowNames.delete(s),this.windowNames.set(t,e),this.windowIds.set(e,t)}startCleanupProtection(e=3e4){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=setInterval(()=>{this.cleanupDestroyedWindows()},e),this.cleanupTimer.unref()}stopCleanupProtection(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}cleanupDestroyedWindows(){if(this.windows.size<=50)return void this.performCleanup(Array.from(this.windows.entries()));const e=Array.from(this.windows.entries());this.processCleanupChunk(e,0,50)}processCleanupChunk(e,t,s){if(t>=e.length)return;const i=Math.min(t+s,e.length),r=e.slice(t,i);this.performCleanup(r),i<e.length&&setImmediate(()=>{this.processCleanupChunk(e,i,s)})}performCleanup(e){const t=[];e.forEach(([e,s])=>{s.isDestroyed()&&t.push(e)}),t.length>0&&(this.logger.warn(`Found ${t.length} destroyed windows in registry. Cleaning up...`),t.forEach(e=>this.unregister(e)))}}class M{logger;constructor(e){this.logger=e}isSafe(e){return!!e&&!e.isDestroyed()}show(e){this.isSafe(e)&&(e.show(),e.setSkipTaskbar(!1))}hide(e){this.isSafe(e)&&(e.hide(),e.setSkipTaskbar(!0))}minimize(e){this.isSafe(e)&&e.minimize()}restore(e){this.isSafe(e)&&e.restore()}maximize(e){this.isSafe(e)&&e.maximize()}unmaximize(e){this.isSafe(e)&&e.unmaximize()}toggleFullScreen(e){this.isSafe(e)&&e.setFullScreen(!e.isFullScreen())}focus(e){this.isSafe(e)&&e.focus()}close(e){this.isSafe(e)&&e.close()}destroy(e){this.isSafe(e)&&e.destroy()}openDevTools(e){this.isSafe(e)&&e.webContents.openDevTools()}closeDevTools(e){this.isSafe(e)&&e.webContents.closeDevTools()}isDevToolsOpened(e){return!!this.isSafe(e)&&e.webContents.isDevToolsOpened()}send(e,t,s){this.isSafe(e)&&e.webContents.send(t,s)}setSkipTaskbar(e,t){this.isSafe(e)&&e.setSkipTaskbar(t)}}class T{persistence;logger;constructor(e,t){this.persistence=e,this.logger=t}async save(e,t){if(this.persistence)try{await this.persistence.save(e,t)}catch(t){this.logger.error(`Failed to save context for window ${e}: ${t}`)}else this.logger.warn("Context persistence is not enabled")}async load(e){if(!this.persistence)return null;try{return await this.persistence.load(e)}catch(t){return this.logger.error(`Failed to load context for window ${e}: ${t}`),null}}async clear(e){if(this.persistence)try{await this.persistence.clear(e)}catch(t){this.logger.error(`Failed to clear context for window ${e}: ${t}`)}}}class W{stateFile;state={};logger;saveTimer=null;throttleLastSave=0;saveDelay;saveStrategy;static activeFiles=new Set;hasLock=!1;isWriting=!1;pendingWrite=!1;lastSavedHash="";constructor(e={}){this.logger=e.logger||new w({appName:"StateKeeper"}),this.saveDelay=e.saveDelay??500,this.saveStrategy=e.saveStrategy??"debounce";const s=t.app.getPath("userData");this.stateFile=e.stateFilePath||g.join(s,"window-state.json"),W.activeFiles.has(this.stateFile)?(this.logger.warn(`State file "${this.stateFile}" is already in use by another StateKeeper instance. This may lead to data conflicts.`),this.hasLock=!1):(W.activeFiles.add(this.stateFile),this.hasLock=!0),this.loadState(),t.app.on("before-quit",()=>{this.flushSync()})}loadState(){try{if(l.existsSync(this.stateFile)){const e=l.readFileSync(this.stateFile,"utf-8");this.state=JSON.parse(e),this.lastSavedHash=u.createHash("md5").update(e).digest("hex")}}catch(e){this.logger.error(`Failed to load window state: ${e}`),this.state={}}}saveState(e,t){(function(e,t){if(e===t)return!0;if(!e||!t)return!1;const s=e.groups||[],i=t.groups||[],r=s.length===i.length&&[...s].sort().every((e,t)=>e===[...i].sort()[t]);return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height&&e.isMaximized===t.isMaximized&&e.isFullScreen===t.isFullScreen&&r&&(!e.displayBounds&&!t.displayBounds||!!e.displayBounds&&!!t.displayBounds&&e.displayBounds.x===t.displayBounds.x&&e.displayBounds.y===t.displayBounds.y&&e.displayBounds.width===t.displayBounds.width&&e.displayBounds.height===t.displayBounds.height)})(this.state[e],t)||(this.state[e]=t,this.persist())}flushSync(){this.saveTimer&&(clearTimeout(this.saveTimer),this.saveTimer=null);try{l.writeFileSync(this.stateFile,JSON.stringify(this.state,null,2))}catch(e){this.logger.error(`Failed to flush window state: ${e}`)}}persist(){if("throttle"===this.saveStrategy){const e=Date.now(),t=e-this.throttleLastSave;t>=this.saveDelay?(this.performSave(),this.throttleLastSave=e):(this.saveTimer&&clearTimeout(this.saveTimer),this.saveTimer=setTimeout(()=>{this.performSave(),this.throttleLastSave=Date.now()},this.saveDelay-t))}else this.saveTimer&&clearTimeout(this.saveTimer),this.saveTimer=setTimeout(()=>{this.performSave()},this.saveDelay)}async performSave(){if(this.isWriting)return void(this.pendingWrite=!0);this.isWriting=!0;const e=`${this.stateFile}.tmp`;try{const t=JSON.stringify(this.state,null,2),s=u.createHash("md5").update(t).digest("hex");if(s===this.lastSavedHash)return void(this.isWriting=!1);await l.promises.writeFile(e,t),await l.promises.rename(e,this.stateFile),this.lastSavedHash=s}catch(t){this.logger.error(`Failed to save window state: ${t}`);try{await l.promises.unlink(e)}catch(e){}}finally{this.saveTimer=null,this.isWriting=!1,this.pendingWrite&&(this.pendingWrite=!1,setImmediate(()=>this.performSave()))}}getWindowState(e,t=800,s=600){const i=this.state[e];return i&&this.isValidState(i)?i:{width:t,height:s,isMaximized:!1,isFullScreen:!1}}isValidState(e){const s=t.screen.getAllDisplays();return!(!e.displayBounds||!s.find(t=>t.bounds.x===e.displayBounds?.x&&t.bounds.y===e.displayBounds?.y&&t.bounds.width===e.displayBounds?.width&&t.bounds.height===e.displayBounds?.height)||void 0===e.x||void 0===e.y)||s.some(t=>{const{x:s,y:i,width:r,height:o}=t.bounds,n=e.x||0,a=e.y||0,d=e.width,h=e.height;return n<s+r&&n+d>s&&a<i+o&&a+h>i})}removeState(e){this.state[e]&&(delete this.state[e],this.persist())}dispose(){this.saveTimer&&(clearTimeout(this.saveTimer),this.saveTimer=null),this.hasLock&&W.activeFiles.delete(this.stateFile)}}class b{logger;stateKeeper;handlers=new Map;constructor(e,t){this.logger=e,this.stateKeeper=t||new W({logger:this.logger})}manage(e,s,i){this.unmanage(s.id);const r=()=>{if(!s.isDestroyed())try{const r=s.getBounds(),o=s.isMaximized(),n=s.isFullScreen(),a=t.screen.getDisplayMatching(r),d=i?i():void 0;this.stateKeeper.saveState(e,{x:r.x,y:r.y,width:r.width,height:r.height,isMaximized:o,isFullScreen:n,displayBounds:a.bounds,groups:d})}catch(t){this.logger.warn(`Failed to save state for window ${e}: ${t}`)}};s.on("resize",r),s.on("move",r),s.on("close",r),s.on("maximize",r),s.on("unmaximize",r),s.on("enter-full-screen",r),s.on("leave-full-screen",r),this.handlers.set(s.id,()=>{s.isDestroyed()||(s.removeListener("resize",r),s.removeListener("move",r),s.removeListener("close",r),s.removeListener("maximize",r),s.removeListener("unmaximize",r),s.removeListener("enter-full-screen",r),s.removeListener("leave-full-screen",r))}),s.once("closed",()=>{this.handlers.delete(s.id)})}unmanage(e){const t=this.handlers.get(e);t&&(t(),this.handlers.delete(e))}dispose(){this.handlers.forEach(e=>e()),this.handlers.clear(),this.stateKeeper&&"function"==typeof this.stateKeeper.dispose&&this.stateKeeper.dispose()}getState(e,t,s){return this.stateKeeper.getWindowState(e,t,s)}}const N="renderer-to-main",D="renderer-to-main-sync",C="message-bus-port",O="window-state-changed";class R extends o.EventEmitter{MAX_WINDOWS;enablePersistence=!1;logger;get persistenceEnabled(){return this.enablePersistence}registry;operator;contextManager;stateManager;focusHistory=[];constructor(e){super(),this.logger=e?.logger||new w({appName:"WindowStore"}),this.MAX_WINDOWS=e?.maxWindows||50,this.enablePersistence=e?.enablePersistence??!1,this.registry=new E(this.logger),this.operator=new M(this.logger),this.contextManager=new T(e?.contextPersistence,this.logger),this.stateManager=new b(this.logger,e?.stateKeeper),!1!==e?.autoStartCleanup&&this.startCleanupProtection(e?.cleanupInterval)}pushFocus(e){this.focusHistory=this.focusHistory.filter(t=>t!==e),this.focusHistory.push(e)}removeFocus(e){this.focusHistory=this.focusHistory.filter(t=>t!==e)}getPreviousFocusedWindow(){if(!(this.focusHistory.length<2))return this.focusHistory[this.focusHistory.length-2]}popFocus(){return this.focusHistory.pop()}joinGroup(e,t){this.registry.addToGroup(e,t)}leaveGroup(e,t){this.registry.removeFromGroup(e,t)}getGroup(e){return this.registry.getGroupIds(e)}async closeGroup(e){const t=this.registry.getGroupIds(e);if(!t||0===t.length)return;const s=t.map(t=>new Promise(s=>{try{setImmediate(()=>{this.operator.destroy(this.getTargetWindow(t)),s()})}catch(i){this.logger.error(`Failed to close window ${t} in group ${e}: ${i}`),s()}}));await Promise.all(s)}hideGroup(e){this.registry.getGroupIds(e).forEach(e=>this.hide(e))}showGroup(e){this.registry.getGroupIds(e).forEach(e=>{const t=this.getTargetWindow(e);t&&this.show(t)})}focusGroup(e){this.registry.getGroupIds(e).forEach(e=>this.focus(e))}show(e,t){this.operator.show(e)}hide(e){const t=this.getTargetWindow(e);t&&this.operator.hide(t)}isDestroyed(e){const t=this.getTargetWindow(e);return!t||t.isDestroyed()}isVisible(e){const t=this.getValidWindow(e);return t?.isVisible()||!1}isMinimized(e){return this.getTargetWindow(e)?.isMinimized()||!1}isMaximized(e){return this.getTargetWindow(e)?.isMaximized()||!1}fullScreenState(e){return this.getTargetWindow(e)?.isFullScreen()||!1}minimize(e){const t=this.getTargetWindow(e);t&&this.operator.minimize(t)}restore(e){const t=this.getValidWindow(e);t&&this.operator.restore(t)}maximize(e){const t=this.getValidWindow(e);t&&this.operator.maximize(t)}unmaximize(e){const t=this.getValidWindow(e);t&&this.operator.unmaximize(t)}fullScreen(e){const t=this.getValidWindow(e);t&&this.operator.toggleFullScreen(t)}focus(e){const t=this.getValidWindow(e);t&&this.operator.focus(t)}setMovable(e){e.setMovable(!0)}winClose(e){this.removeWindow(e)}openDevTools(e){const t=this.getTargetWindow(e);t&&this.operator.openDevTools(t)}isDevToolsOpened(e){const t=this.getTargetWindow(e);return!!t&&this.operator.isDevToolsOpened(t)}closeDevTools(e){const t=this.getTargetWindow(e);t&&this.operator.closeDevTools(t)}quit(){t.app.quit()}getWindowSize(){const{width:e,height:s}=t.screen.getPrimaryDisplay().workAreaSize;return{width:e,height:s}}send(e,t,s=""){const i=this.getTargetWindow(e);i&&this.operator.send(i,t,s)}setSkipTaskbar(e,t){const s=this.getTargetWindow(e);s&&this.operator.setSkipTaskbar(s,t)}get mainWindow(){return this.registry.getMainWindow()}set mainWindow(e){this.registry.setMainWindow(e)}getWindowCount(){return this.registry.getCount()}getAllWindowKeys(){return this.registry.getAllIds()}getAllWindows(){return this.registry.getAllWindows()}getWindowNames(){return this.registry.getNameMap()}getNameByWindowId(e){return this.registry.getNameById(e)}getWindowByNameId(e){return this.registry.getIdByName(e)}getWindowByName(e){return this.registry.getByName(e)}hasByName(e){return this.registry.hasName(e)}deleteByName(e){const t=this.registry.getIdByName(e);return!!t&&(this.registry.unregister(t),!0)}getWindowById(e){return this.registry.getById(e)}hasById(e){return this.registry.hasId(e)}deleteById(e){return!!this.registry.hasId(e)&&(this.registry.unregister(e),!0)}getWindowId(e){return this.registry.getIdByWindow(e)}updateWindowName(e,t){this.registry.updateWindowName(e,t)}getTargetWindow(e){return e?this.registry.getById(e)||this.registry.getByName(e):this.getCurrentWindow()}getValidWindow(e){const t=this.getTargetWindow(e);if(t&&!t.isDestroyed())return t;this.logger.warn(`Window ${e||"current"} not found or destroyed`)}getCurrentWindow(){const e=t.BrowserWindow.getFocusedWindow();return e&&!e.isDestroyed()?e:this.mainWindow??void 0}createWindow(e,t){if(this.registry.getCount()>=this.MAX_WINDOWS){const e=new Error(`Maximum window limit (${this.MAX_WINDOWS}) reached`);throw this.logger.error(e.message),e}const s=t?.windowId||r.v4();let i=t?.name||`window-${s}`;try{i=this.validateWindowName(i)}catch{this.logger.warn(`Window name "${i}" already exists, generating unique name`),i=`${i}-${Date.now()}`}return this.registerWindow(s,i,e,{enablePersistence:t?.enablePersistence}),s}removeWindow(e){const t=this.registry.getById(e);if(t&&!t.isDestroyed())try{this.operator.close(t),t.isDestroyed()||this.operator.destroy(t)}catch(t){this.logger.error(`Failed to remove window ${e}: ${t}`),this.emit("error",t)}this.registry.unregister(e)}validateWindowName(e){if(this.registry.hasName(e))throw new Error(`Window name "${e}" already exists`);return e}registerWindow(e,t,s,i){this.registry.register(e,t,s),(i?.enablePersistence??this.enablePersistence)&&this.stateManager.manage(t,s)}manageState(e,t,s){this.stateManager.manage(e,t,s)}getWindowGroups(e){return this.registry.getWindowGroups(e)}getWindowState(e,t,s){return this.stateManager.getState(e,t,s)}async saveWindowContext(e,t){await this.contextManager.save(e,t)}async loadWindowContext(e){return await this.contextManager.load(e)}async clearWindowContext(e){await this.contextManager.clear(e)}startCleanupProtection(e=3e4){this.registry.startCleanupProtection(e)}stopCleanupProtection(){this.registry.stopCleanupProtection()}async dispose(){this.logger.info("Disposing WindowStore..."),this.stopCleanupProtection();const e=this.getAllWindows();for(const t of e)t.isDestroyed()||t.close();this.registry.clear(),this.logger.info("WindowStore disposed")}}const _=()=>{};let P=class{channels=new Map;handlers=new Set;logger;constructor(e){this.logger=e||new w({appName:"IpcTransport"})}setLogger(e){this.logger=e}on(e,s=_){const i=async(t,...i)=>{try{this.logEvent(e,"on",i),await s(t,...i)}catch(s){this.logError(e,"on",s),t.sender.isDestroyed()||t.sender.send(`${e}:error`,this.serializeError(s))}};this.channels.has(e)||this.channels.set(e,new Map),this.channels.get(e).set(s,i),t.ipcMain.on(e,i)}handle(e,s=_){this.handlers.has(e)&&t.ipcMain.removeHandler(e),this.handlers.add(e),t.ipcMain.handle(e,async(t,...i)=>{try{return this.logEvent(e,"handle",i),{code:0,message:"success",data:await s(t,...i)}}catch(t){this.logError(e,"handle",t);const s="development"===process.env.NODE_ENV;return t&&"object"==typeof t&&"code"in t&&"category"in t?{code:t.code,message:t.message,data:null,category:t.category,details:t.details,stack:s?t.stack:void 0}:{code:t.code||500,message:t instanceof Error?t.message:String(t),data:null,stack:s&&t instanceof Error?t.stack:void 0}}})}removeListener(e,s){const i=this.channels.get(e);if(i){if(s){const r=i.get(s);r&&(t.ipcMain.removeListener(e,r),i.delete(s))}else{for(const s of i.values())t.ipcMain.removeListener(e,s);i.clear()}0===i.size&&this.channels.delete(e)}}removeAllListeners(e){if(e)this.removeListener(e);else{for(const e of this.channels.keys())this.removeListener(e);this.channels.clear()}}removeHandler(e){this.handlers.has(e)&&(t.ipcMain.removeHandler(e),this.handlers.delete(e))}removeAllHandlers(){for(const e of this.handlers)t.ipcMain.removeHandler(e);this.handlers.clear()}error(e){this.logger.error(`[IPC System Error]: ${e}`)}log(e){this.logger.info(`[IPC System Log]: ${e}`)}logEvent(e,t,s){try{const i=s[0]?.name,r=i?`[Action: ${i}]`:`[Args: ${this.safeStringify(s)}]`;this.logger.info(`[${t.toUpperCase()}] ${e} ${r}`)}catch{this.logger.info(`[${t.toUpperCase()}] ${e} [Args parsing failed]`)}}logError(e,t,s){const i=s instanceof Error?s.message:String(s),r=s instanceof Error?s.stack:"";this.logger.error(`[${t.toUpperCase()} ERROR] ${e}: ${i}`,r)}serializeError(e){if(e instanceof Error){const t={name:e.name,message:e.message,stack:e.stack};for(const s of Object.getOwnPropertyNames(e))["name","message","stack"].includes(s)||(t[s]=e[s]);return t}return"object"==typeof e&&null!==e?e:{message:String(e),name:"UnknownError"}}safeStringify(e){try{return JSON.stringify(e)}catch{return"[Circular or Non-serializable]"}}};class ${static defaultSetup(e,t){return $.setup({config:e.config,ipcRouter:e.ipcRouter,currentIpcChannel:e.currentIpcChannel,currentIpcSyncChannel:e.currentIpcSyncChannel,options:t})}static setup(e){const{config:t,ipcRouter:s,currentIpcChannel:i,currentIpcSyncChannel:r,options:o}=e,n=e.ipcTransport||new P,a=o?.channel||t.ipc?.channel||N,d=o?.syncChannel||t.ipc?.syncChannel||D;return i&&n.removeHandler(i),r&&n.removeListener(r),n.handle(a,async(e,t)=>{try{const i=e.sender?.id;return{code:0,message:"success",data:await s.handle(t,i)}}catch(e){return{code:e.code||500,message:e instanceof Error?e.message:String(e),data:null}}}),d&&n.on(d,(e,t)=>{try{const i=s.handle(t);e.returnValue={code:0,message:"success",data:i}}catch(t){e.returnValue={code:t.code||500,message:t instanceof Error?t.message:String(t),data:null}}}),{channel:a,syncChannel:d,ipcTransport:n}}}class k{metrics={creationTimes:[],totalCreated:0,totalDestroyed:0};recordCreation(e){this.metrics.creationTimes.push(e),this.metrics.totalCreated++}recordDestruction(){this.metrics.totalDestroyed++}getMetrics(e){const t=this.metrics.creationTimes.length>0?this.metrics.creationTimes.reduce((e,t)=>e+t,0)/this.metrics.creationTimes.length:0;return{windowCount:e,totalCreated:this.metrics.totalCreated,totalDestroyed:this.metrics.totalDestroyed,averageCreationTime:Math.round(t),memoryUsage:process.memoryUsage(),uptime:process.uptime()}}}class B{plugins=[];hooks={};logger;constructor(e,t=[],s={}){this.logger=e,this.plugins=t,this.hooks=s}addPlugin(e){this.plugins.push(e)}getPlugins(){return this.plugins}async initPlugins(e){for(const t of this.plugins)try{await(t.onInit?.(e))}catch(e){this.logger.error(`Plugin "${t.name}" initialization failed: ${e}`)}}async initPlugin(e,t){try{await(e.onInit?.(t))}catch(t){this.logger.error(`Plugin "${e.name}" initialization failed: ${t}`)}}onWillCreate(e){let t={...e};for(const e of this.plugins)if(e.onWillCreate){const s=e.onWillCreate(t);if(!1===s)return!1;s&&"object"==typeof s&&(t=s)}if(this.hooks.onWillCreate){const e=this.hooks.onWillCreate(t);if(!1===e)return!1;e&&"object"==typeof e&&(t=e)}return t}async onDidCreate(e){for(const t of this.plugins)try{await(t.onDidCreate?.(e))}catch(e){this.logger.error(`Plugin ${t.name} onDidCreate failed: ${e}`)}if(this.hooks.onDidCreate)try{await this.hooks.onDidCreate(e)}catch(e){this.logger.error(`Hook onDidCreate failed: ${e}`)}}async onWillDestroy(e){for(const t of this.plugins)try{await(t.onWillDestroy?.(e))}catch(e){this.logger.error(`Plugin ${t.name} onWillDestroy failed: ${e}`)}if(this.hooks.onWillDestroy)try{await this.hooks.onWillDestroy(e)}catch(e){this.logger.error(`Hook onWillDestroy failed: ${e}`)}}async onDidDestroy(e){for(const t of this.plugins)try{await(t.onDidDestroy?.(e))}catch(e){this.logger.error(`Plugin ${t.name} onDidDestroy failed: ${e}`)}if(this.hooks.onDidDestroy)try{await this.hooks.onDidDestroy(e)}catch(e){this.logger.error(`Hook onDidDestroy failed: ${e}`)}}}class A{static instance;logger;registry=new Map;performanceMetrics=[];metricsEnabled=!1;constructor(){this.logger=new w({appName:"DebugHelper"})}static getInstance(){return A.instance||(A.instance=new A),A.instance}register(e,t){this.registry.set(e,t),this.logger.info(`Registered component: ${e}`)}get(e){return this.registry.get(e)}getAll(){const e={};return this.registry.forEach((t,s)=>{e[s]=t}),e}enablePerformanceMonitoring(){this.metricsEnabled=!0,this.logger.info("Performance monitoring enabled")}disablePerformanceMonitoring(){this.metricsEnabled=!1,this.logger.info("Performance monitoring disabled")}recordMetric(e){this.metricsEnabled&&(this.performanceMetrics.push(e),this.performanceMetrics.length>1e3&&this.performanceMetrics.shift(),this.logger.info(`Performance: ${e.name} took ${e.duration.toFixed(2)}ms`,e.metadata))}getMetrics(){return[...this.performanceMetrics]}clearMetrics(){this.performanceMetrics=[],this.logger.info("Performance metrics cleared")}getStatistics(){const e={};return this.performanceMetrics.forEach(t=>{e[t.name]||(e[t.name]={count:0,total:0,min:1/0,max:-1/0,avg:0});const s=e[t.name];s.count++,s.total+=t.duration,s.min=Math.min(s.min,t.duration),s.max=Math.max(s.max,t.duration),s.avg=s.total/s.count}),e}createTimer(e,t){const s=performance.now();return()=>{const i=performance.now()-s;this.recordMetric({name:e,duration:i,timestamp:Date.now(),metadata:t})}}getWindowManagerInfo(){const e=this.registry.get("windowManager");if(!e)return null;try{const t=e.getAllWindows();return{windowCount:t.length,windows:t.map(e=>({isDestroyed:e.isDestroyed(),isVisible:e.isVisible(),isMinimized:e.isMinimized(),isMaximized:e.isMaximized(),title:e.getTitle()}))}}catch(e){return this.logger.error("Failed to get WindowManager info:",e),{error:"Failed to retrieve info"}}}getIpcRouterInfo(){return this.registry.get("ipcRouter")?{registered:!0,type:"IpcRouter"}:null}getMessageBusInfo(){const e=this.registry.get("messageBus");return e?{registeredWindows:e.getRegisteredWindows(),data:e.getData()}:null}getDebugSnapshot(){return{timestamp:Date.now(),components:{windowManager:this.getWindowManagerInfo(),ipcRouter:this.getIpcRouterInfo(),messageBus:this.getMessageBusInfo()},performance:{metrics:this.getMetrics(),statistics:this.getStatistics()}}}logSnapshot(){const e=this.getDebugSnapshot();console.log("=== Debug Snapshot ==="),console.log(JSON.stringify(e,null,2))}}const L=A.getInstance();class x{static instance;metrics=new Map;logger;constructor(e){this.logger=e||new w({appName:"PerformanceMonitor"})}static getInstance(e){return x.instance||(x.instance=new x(e)),x.instance}startMeasure(e,t,s){this.metrics.set(e,{name:t,startTime:performance.now(),metadata:s})}endMeasure(e,t){const s=this.metrics.get(e);if(!s)return;const i=performance.now()-s.startTime;return this.logger.info(`[Performance] ${s.name}: ${i.toFixed(2)}ms`,{...s.metadata,...t,duration:i}),this.metrics.delete(e),i}recordMetric(e,t,s){this.logger.info(`[Metric] ${e}: ${t}`,s)}}class z{static isDebugEnabled=!1;static enableDebugMode(){this.isDebugEnabled||(process.env.ELECTRON_TOOLKIT_DEBUG="true",this.isDebugEnabled=!0,"browser"===process.type&&(global.__ELECTRON_TOOLKIT_DEBUG__={instances:{},listInstances:()=>Object.keys(global.__ELECTRON_TOOLKIT_DEBUG__.instances),getInstance:e=>global.__ELECTRON_TOOLKIT_DEBUG__.instances[e]},console.log("[ElectronToolkit] Debug mode enabled. Access global.__ELECTRON_TOOLKIT_DEBUG__ for details.")))}static register(e,t){"browser"===process.type&&global.__ELECTRON_TOOLKIT_DEBUG__&&(global.__ELECTRON_TOOLKIT_DEBUG__.instances[e]=t)}}class F{api;data;winId;creator;extraOptions;logger;constructor(e,t,s,i,r){this.api=e,this.data=t,this.winId=t?.data?.winId||"",this.creator=s,this.extraOptions=i,this.logger=r||new w({appName:"WindowCreator"})}async createWindow(){let e=!1;if(this.winId&&this.api.window.hasById(this.winId)){if(!this.api.window.isDestroyed(this.winId))return{winId:this.winId,isNew:!1};this.logger.warn(`Window ${this.winId} is found in store but destroyed. Cleaning up and recreating.`),await this.api.window.removeWindow(this.winId)}const t=this.data.data||{},s={...t,...this.extraOptions?.(t)||{},...this.winId?{windowId:this.winId}:{}};return this.winId=await this.creator(s),e=!0,{winId:this.winId,isNew:!0}}showWindow(e,t){const s=this.api.window.getTargetWindow(e);s&&!s.isDestroyed()?t?s.once("ready-to-show",()=>{this.api.window.show(s,e)}):this.api.window.show(s,e):this.logger.error(`Failed to show window ${e}: Window not found or destroyed`)}async loadContent(e,t){const s=this.api.window.getTargetWindow(e);if(s&&!s.isDestroyed())if(t.loadWindowContent)try{await t.loadWindowContent(s)}catch(t){this.logger.error(`Custom loadWindowContent failed for window ${e}: ${t}`)}else if(this.data.contentLoader)try{await this.data.contentLoader(s,t)}catch(t){this.logger.error(`Global contentLoader failed for window ${e}: ${t}`)}else t.loadUrl?s.loadURL(t.loadUrl).catch(s=>{this.logger.error(`Failed to load URL "${t.loadUrl}" for window ${e}: ${s}`)}):t.loadFile&&s.loadFile(t.loadFile).catch(s=>{this.logger.error(`Failed to load file "${t.loadFile}" for window ${e}: ${s}`)})}async createAndShow(){try{const{isNew:e}=await this.createWindow();if(e){const e=this.data.data||{},t={...e,...this.extraOptions?.(e)||{},windowId:this.winId};await this.loadContent(this.winId,t)}return this.showWindow(this.winId,e),this.winId}catch(e){throw this.logger.error(`Failed to create and show window: ${e}`),e}}}const G=!t.app.isPackaged;class H{wm;pluginExecutor;metrics;logger;constructor(e,t,s,i){this.wm=e,this.pluginExecutor=t,this.metrics=s,this.logger=i}async create(e={}){const s=Date.now(),i=x.getInstance(),r=`create-window-${Date.now()}`;i.startMeasure(r,"Window Creation",{name:e.name});const o=this.pluginExecutor.onWillCreate(e);if(!1===o)return"";(e=o).defaultConfig&&(this.wm.config.defaultConfig=e.defaultConfig),this.wm.config.isDevelopment=e.isDevelopment??G,this.logger.info(`Current Environment / 当前环境: ${JSON.stringify({appIsPackaged:t.app.isPackaged,cachedIsDev:G,finalConfigIsDev:this.wm.config.isDevelopment},null,2)}`);const n={window:{hasById:e=>this.wm.windowStore.hasById(e),isDestroyed:e=>this.wm.windowStore.isDestroyed(e),deleteByName:e=>{const t=this.wm.windowStore.getWindowByNameId(e);return!!t&&(this.removeWindow(t),!0)},deleteById:e=>!!this.wm.windowStore.hasById(e)&&(this.removeWindow(e),!0),getTargetWindow:e=>this.wm.windowStore.getTargetWindow(e),removeWindow:e=>this.removeWindow(e),show:(e,t)=>this.wm.windowStore.show(e,t)}},a=e.windowId||(e.name?this.wm.windowStore.getWindowByNameId(e.name):void 0);e.windowId&&this.wm.validateWindowId(e.windowId,"create");let d={...e};const h=e.enablePersistence??this.wm.windowStore.persistenceEnabled;if(h&&e.name){const t=this.wm.windowStore.getWindowState(e.name,e.width,e.height);t&&(d={...d,x:t.x,y:t.y,width:t.width,height:t.height,fullscreen:t.isFullScreen||e.fullscreen})}const c=new F(n,{data:{...d,winId:a},contentLoader:this.wm.config.contentLoader},async t=>{const s=this.wm.createBrowserWindow(t);if(h&&e.name){const t=this.wm.windowStore.getWindowState(e.name);t?.isMaximized&&!s.isFullScreen()&&s.maximize()}const i=this.wm.windowStore.createWindow(s,t);if(this.wm.configureWindowBehavior(s,i),t.name){const e=this.wm.windowStore.getWindowState(t.name);e&&e.groups&&Array.isArray(e.groups)&&e.groups.forEach(e=>{this.wm.windowStore.joinGroup(i,e)}),this.registerStateManagement(t.name,s)}const r={window:s,id:i,name:t.data.name||""};return await this.pluginExecutor.onDidCreate(r),this.wm.emit("window-created",r),i},void 0,this.logger),l=await c.createAndShow(),g=Date.now()-s;return this.metrics.recordCreation(g),g>2e3&&this.logger.warn(`Slow window creation detected: ${l} took ${g}ms`),i.endMeasure(r,{windowId:l}),l}async removeWindow(e){const t=x.getInstance(),s=`destroy-window-${e}`;t.startMeasure(s,"Window Destruction",{windowId:e}),this.wm.validateWindowId(e,"removeWindow"),await this.pluginExecutor.onWillDestroy(e),this.wm.emit("window-will-be-destroyed",e),this.wm.windowStore.removeWindow(e),this.metrics.recordDestruction(),await this.pluginExecutor.onDidDestroy(e),this.wm.emit("window-destroyed",e),t.endMeasure(s,{windowId:e})}registerStateManagement(e,t){this.wm.windowStore.persistenceEnabled&&this.wm.windowStore.manageState(e,t,()=>this.wm.windowStore.getWindowGroups(t.id.toString()))}}class U extends s.TypedEmitter{config={};ipcRouter;ipcTransport;messageBus;currentIpcChannel=null;currentIpcSyncChannel=null;logger;windowStore;metricsManager;pluginExecutor;lifecycle;isInitialized=!1;initPromise;initError=null;constructor(e={}){super();const t=v(e);if(!t.success)throw new Error(`Invalid WindowManager configuration: ${t.error}`);if(this.config=t.data,this.ipcRouter=this.config.ipcRouter,this.ipcTransport=this.config.ipcTransport,this.messageBus=this.config.messageBus,this.logger=this.config.logger||new w({appName:"WindowManager"}),e.logger){const t=["info","warn","error","debug"];for(const s of t)if("function"!=typeof e.logger[s])throw new Error(`config.logger must have ${t.join("/")} methods`)}if(e.ipcRouter&&"function"!=typeof e.ipcRouter.handle)throw new Error("config.ipcRouter must have handle/addHandler methods");this.windowStore=new R({logger:this.logger,...e.store||{}}),this.windowStore.on("error",e=>this.emit("error",e)),this.metricsManager=new k,this.pluginExecutor=new B(this.logger,e.plugins,e.hooks),this.lifecycle=new H(this,this.pluginExecutor,this.metricsManager,this.logger),this.messageBus&&this.messageBus.setGroupResolver(e=>this.windowStore.getGroup(e)),this.initPromise=this.init().then(async()=>{if(this.ipcRouter&&!1!==this.config.ipc?.autoInit)try{this.setupIPC()}catch(e){throw this.logger.warn(`Auto IPC setup failed: ${e}`),e}}).catch(e=>{throw this.initError=e instanceof Error?e:new Error(String(e)),this.logger.error(`WindowManager initialization failed: ${this.initError.message}`),this.emit("error",this.initError),this.initError})}async ready(){if(this.initError)throw this.initError;return this.initPromise}get initialized(){return this.isInitialized&&!this.initError}get initializationError(){return this.initError}async init(){this.isInitialized||(this.isInitialized=!0,await this.pluginExecutor.initPlugins(this))}use(e){return this.pluginExecutor.addPlugin(e),this.isInitialized&&this.pluginExecutor.initPlugin(e,this),this}setupIPC(e){let t;if(t=e?.setupImpl?e.setupImpl({config:this.config,ipcRouter:this.ipcRouter,currentIpcChannel:this.currentIpcChannel,currentIpcSyncChannel:this.currentIpcSyncChannel,options:e}):this.config.ipcSetup?this.config.ipcSetup(this,e):$.setup({config:this.config,ipcRouter:this.ipcRouter,currentIpcChannel:this.currentIpcChannel,currentIpcSyncChannel:this.currentIpcSyncChannel,options:e}),t)return this.currentIpcChannel=t.channel,this.currentIpcSyncChannel=t.syncChannel,void(t.ipcTransport&&(this.ipcTransport=t.ipcTransport));if(!this.ipcRouter)throw new Error("IpcRouter instance is required for IPC setup. Please pass it to the WindowManager constructor.")}async create(e={}){const t=x.getInstance(),s=`window-create-${Date.now()}`;t.startMeasure(s,"Window Creation",{name:e.name,width:e.width,height:e.height});try{const i=await this.lifecycle.create(e);return t.endMeasure(s,{status:"success",windowId:i}),i}catch(e){throw t.endMeasure(s,{status:"error",error:e instanceof Error?e.message:String(e)}),e}}async removeWindow(e){return this.lifecycle.removeWindow(e)}getMetrics(){return this.metricsManager.getMetrics(this.getWindowCount())}dispose(){this.logger.info("Disposing WindowManager..."),this.getAllWindowKeys().forEach(e=>{try{this.removeWindow(e)}catch(t){this.logger.error(`Failed to remove window ${e}: ${t}`)}}),this.windowStore.dispose(),this.ipcTransport&&(this.ipcTransport.removeAllHandlers(),this.ipcTransport.removeAllListeners()),this.ipcRouter&&"function"==typeof this.ipcRouter.dispose&&this.ipcRouter.dispose(),this.removeAllListeners(),this.logger.info("WindowManager disposed")}getMainWindowId(){return this.windowStore.mainWindow?this.windowStore.getWindowId(this.windowStore.mainWindow):void 0}createBrowserWindow(e){const s=this.getDefaultWindowConfig();return new t.BrowserWindow({...s,...e})}getDefaultWindowConfig(){return this.config.defaultConfig||{width:800,height:600,show:!1,webPreferences:{nodeIntegration:!1,contextIsolation:!0}}}configureWindowBehavior(e,s){this.config.isDevelopment&&this.windowStore.openDevTools(s),!1!==this.config.preventExternalLinks&&e.webContents.setWindowOpenHandler(e=>(t.shell.openExternal(e.url),{action:"deny"})),e.once("ready-to-show",()=>this.windowStore.show(e,s)),e.on("closed",()=>{this.windowStore.removeFocus(s),this.removeWindow(s)}),e.webContents.on("render-process-gone",(t,i)=>{this.logger.error(`Window ${s} crashed: ${i.reason} (Exit Code: ${i.exitCode})`);const{reason:r}=i;"crashed"!==r&&"oom"!==r||(this.logger.info(`Attempting to reload window ${s}...`),setTimeout(()=>{e.isDestroyed()||e.reload()},1e3))}),e.on("unresponsive",()=>{this.logger.warn(`Window ${s} is unresponsive`)}),e.on("focus",()=>{this.windowStore.pushFocus(s)}),e.isVisible()&&e.isFocused()&&this.windowStore.pushFocus(s)}joinGroup(e,t){this.windowStore.joinGroup(e,t)}leaveGroup(e,t){this.windowStore.leaveGroup(e,t)}getGroup(e){return this.windowStore.getGroup(e)}async closeGroup(e){await this.windowStore.closeGroup(e)}hideGroup(e){this.windowStore.hideGroup(e)}showGroup(e){this.windowStore.showGroup(e)}focusGroup(e){this.windowStore.focusGroup(e)}sendToGroup(e,t,s){if(!this.messageBus)return this.logger.warn("[WindowManager.sendToGroup] MessageBus not configured"),0;const i=this.windowStore.getGroup(e);return this.messageBus.broadcastToWindows(i,t,s)}focusPrevious(){const e=this.windowStore.getPreviousFocusedWindow();e&&this.windowStore.focus(e)}validateWindowId(e,t){if(!e||"string"!=typeof e||""===e.trim())throw new Error(`[WindowManager.${t}] Invalid windowId: must be a non-empty string`);return e}show(e,t){e&&!e.isDestroyed()?(void 0!==t&&this.validateWindowId(t,"show"),this.windowStore.show(e,t)):this.logger.warn("[WindowManager.show] Window is null or destroyed")}hide(e){this.windowStore.hide(this.validateWindowId(e,"hide"))}isDestroyed(e){return this.windowStore.isDestroyed(this.validateWindowId(e,"isDestroyed"))}isVisible(e){return this.windowStore.isVisible(this.validateWindowId(e,"isVisible"))}isMinimized(e){return this.windowStore.isMinimized(this.validateWindowId(e,"isMinimized"))}isMaximized(e){return this.windowStore.isMaximized(this.validateWindowId(e,"isMaximized"))}fullScreenState(e){return this.windowStore.fullScreenState(this.validateWindowId(e,"fullScreenState"))}minimize(e){e&&this.validateWindowId(e,"minimize"),this.windowStore.minimize(e)}restore(e){this.windowStore.restore(this.validateWindowId(e,"restore"))}maximize(e){this.windowStore.maximize(this.validateWindowId(e,"maximize"))}unmaximize(e){this.windowStore.unmaximize(this.validateWindowId(e,"unmaximize"))}fullScreen(e){this.windowStore.fullScreen(this.validateWindowId(e,"fullScreen"))}focus(e){this.windowStore.focus(this.validateWindowId(e,"focus"))}setMovable(e){e&&!e.isDestroyed()&&this.windowStore.setMovable(e)}close(e){this.windowStore.winClose(this.validateWindowId(e,"close"))}winClose(e){this.close(e)}openDevTools(e){this.windowStore.openDevTools(this.validateWindowId(e,"openDevTools"))}isDevToolsOpened(e){return this.windowStore.isDevToolsOpened(this.validateWindowId(e,"isDevToolsOpened"))}closeDevTools(e){this.windowStore.closeDevTools(this.validateWindowId(e,"closeDevTools"))}quit(){this.windowStore.quit()}getWindowSize(){return this.windowStore.getWindowSize()}send(e,t,s=""){this.windowStore.send(e,t,s)}setSkipTaskbar(e,t){this.windowStore.setSkipTaskbar(e,t)}get mainWindow(){return this.windowStore.mainWindow}getWindowCount(){return this.windowStore.getWindowCount()}getAllWindowKeys(){return this.windowStore.getAllWindowKeys()}getAllWindows(){return this.windowStore.getAllWindows()}getWindowNames(){return this.windowStore.getWindowNames()}getNameByWindowId(e){return this.windowStore.getNameByWindowId(e)}getWindowByNameId(e){return this.windowStore.getWindowByNameId(e)}getWindowByName(e){return this.windowStore.getWindowByName(e)}hasByName(e){return this.windowStore.hasByName(e)}deleteByName(e){return this.windowStore.deleteByName(e)}getWindowById(e){return this.windowStore.getWindowById(e)}hasById(e){return this.windowStore.hasById(e)}deleteById(e){return this.windowStore.deleteById(e)}getWindowId(e){return this.windowStore.getWindowId(e)}updateWindowName(e,t){this.windowStore.updateWindowName(e,t)}getTargetWindow(e){return this.windowStore.getTargetWindow(e)}getValidWindow(e){return this.windowStore.getValidWindow(e)}getCurrentWindow(){return this.windowStore.getCurrentWindow()}async saveWindowContext(e,t){await this.windowStore.saveWindowContext(e,t)}async loadWindowContext(e){return await this.windowStore.loadWindowContext(e)}async clearWindowContext(e){await this.windowStore.clearWindowContext(e)}startCleanupProtection(e=3e4){this.windowStore.startCleanupProtection(e)}stopCleanupProtection(){this.windowStore.stopCleanupProtection()}}class V{handlers=new Map;logger;errorHandler;constructor(e,t,s){this.logger=t||new w({appName:e}),this.errorHandler=s}register(e,t,s){this.handlers.has(e)&&this.logger.warn(`Handler "${e}" is being overwritten / 处理器 "${e}" 被覆盖`),this.handlers.set(e,{callback:t,metadata:s})}unregister(e){return this.handlers.delete(e)}getMetadata(e){return this.handlers.get(e)?.metadata}dispatch(e,t,s){const i=this.handlers.get(e);if(i)try{return i.callback(t,s)}catch(t){if(this.logger.error(`Error in handler "${e}": ${t} / 处理器 "${e}" 执行错误: ${t}`),this.errorHandler)return this.errorHandler(t,e);throw t}else this.logger.warn(`No handler found for "${e}" / 未找到处理器 "${e}"`)}has(e){return this.handlers.has(e)}getHandlerNames(){return Array.from(this.handlers.keys())}clear(){this.handlers.clear()}}var j,q,J,K;e.IpcErrorCode=void 0,(j=e.IpcErrorCode||(e.IpcErrorCode={}))[j.SUCCESS=0]="SUCCESS",j[j.BAD_REQUEST=400]="BAD_REQUEST",j[j.FORBIDDEN=403]="FORBIDDEN",j[j.NOT_FOUND=404]="NOT_FOUND",j[j.VALIDATION_ERROR=422]="VALIDATION_ERROR",j[j.INTERNAL_ERROR=500]="INTERNAL_ERROR",j[j.HANDLER_ERROR=501]="HANDLER_ERROR",e.MessageBusErrorCode=void 0,(q=e.MessageBusErrorCode||(e.MessageBusErrorCode={}))[q.SUCCESS=0]="SUCCESS",q[q.PERMISSION_DENIED=403]="PERMISSION_DENIED",q[q.NOT_FOUND=404]="NOT_FOUND",q[q.INVALID_OPERATION=400]="INVALID_OPERATION",q[q.INTERNAL_ERROR=500]="INTERNAL_ERROR",e.WindowManagerErrorCode=void 0,(J=e.WindowManagerErrorCode||(e.WindowManagerErrorCode={}))[J.SUCCESS=0]="SUCCESS",J[J.WINDOW_NOT_FOUND=404]="WINDOW_NOT_FOUND",J[J.WINDOW_ALREADY_EXISTS=409]="WINDOW_ALREADY_EXISTS",J[J.INVALID_CONFIG=400]="INVALID_CONFIG",J[J.CREATION_FAILED=500]="CREATION_FAILED",J[J.OPERATION_FAILED=500]="OPERATION_FAILED",e.ErrorCategory=void 0,(K=e.ErrorCategory||(e.ErrorCategory={})).VALIDATION="VALIDATION",K.PERMISSION="PERMISSION",K.NOT_FOUND="NOT_FOUND",K.INTERNAL="INTERNAL",K.BUSINESS="BUSINESS";class X extends Error{code;category;details;timestamp;constructor(t,s,i=e.ErrorCategory.INTERNAL,r){super(s),this.name="StandardError",this.code=t,this.category=i,this.details=r,this.timestamp=Date.now(),Error.captureStackTrace&&Error.captureStackTrace(this,X)}toResponse(e=!1){return{code:this.code,message:this.message,category:this.category,details:this.details,stack:e?this.stack:void 0,timestamp:this.timestamp}}static from(t,s=500){return t instanceof X?t:t instanceof Error?new X(s,t.message,e.ErrorCategory.INTERNAL,{originalError:t.name,stack:t.stack}):new X(s,String(t),e.ErrorCategory.INTERNAL,{originalError:t})}}class Y extends Error{code;details;constructor(e,t,s){super(e),this.code=t,this.details=s,this.name="ElectronToolkitError"}}class Q extends Y{constructor(e,t){super(`IPC handler "${e}" failed: ${t.message}`,"IPC_HANDLER_ERROR",{handlerName:e,originalError:t})}}class Z{limits=new Map;state=new Map;defaultLimit=null;logger;cleanupTimer=null;cleanupInterval;constructor(e={}){this.logger=e.logger,this.defaultLimit=e.defaultLimit||null,this.cleanupInterval=e.cleanupInterval||6e4,this.startCleanup()}startCleanup(){this.cleanupTimer||(this.cleanupTimer=setInterval(()=>{this.cleanup()},this.cleanupInterval),this.cleanupTimer.unref())}stopCleanup(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}setLimit(e,t){this.limits.set(e,t)}check(e,t){const s=this.limits.get(t)||this.defaultLimit;if(!s)return!0;const i=Date.now();let r=this.state.get(e);return(!r||i>r.resetTime)&&(r={count:0,resetTime:i+s.interval},this.state.set(e,r)),r.count>=s.limit?(this.logger&&this.logger.warn(`Rate limit exceeded for ${e} (Rule: ${t}, Limit: ${s.limit}/${s.interval}ms)`),!1):(r.count++,!0)}clear(){this.state.clear()}cleanup(){const e=Date.now();for(const[t,s]of this.state.entries())e>s.resetTime&&this.state.delete(t)}}const ee=i.z.object({name:i.z.string({message:"Handler name is required"}),payload:i.z.unknown().optional()});class te{_api={};dispatcher;rateLimiter;constructor(e={}){this.dispatcher=new V("IpcRouter",e.logger),this.rateLimiter=new Z({logger:e.logger,defaultLimit:e.defaultRateLimit})}addHandler(e){this.dispatcher.register(e.name,e.callback,e.schema)}addHandlers(e){e.forEach(e=>this.addHandler(e))}setRateLimit(e,t){this.rateLimiter.setLimit(e,t)}removeHandler(e){this.dispatcher.unregister(e)}handle(e,t){const s=x.getInstance(),i=`ipc-${String(e.name)}-${Date.now()}`;return(async()=>{try{if(s.startMeasure(i,"IPC Call",{handler:String(e.name),senderId:t}),void 0!==t){const s=`${t}:${String(e.name)}`;if(!this.rateLimiter.check(s,String(e.name)))throw new Q(String(e.name),new Error(`Rate limit exceeded for handler "${String(e.name)}"`))}const r=ee.safeParse(e);if(!r.success)throw console.warn("[IpcRouter] Invalid IPC request data:",r.error.format()),new Q("validation",new Error(`Invalid IPC request: ${r.error.message}`));const o=this.dispatcher.getMetadata(e.name);if(o){const t=o.safeParse(e.payload);if(!t.success)throw console.warn(`[IpcRouter] Invalid payload for handler "${String(e.name)}":`,t.error.message),new Q(String(e.name),new Error(`Invalid payload: ${t.error.message}`))}const n={...this._api},a=await Promise.resolve(this.dispatcher.dispatch(e.name,n,e.payload));return s.endMeasure(i,{status:"success"}),a}catch(t){if(s.endMeasure(i,{status:"error",error:t instanceof Error?t.message:String(t)}),t instanceof Q)throw t;throw new Q(String(e.name),t)}})()}addApi(e,t){this._api[e]=t}addApis(e){Object.entries(e).forEach(([e,t])=>{this.addApi(e,t)})}dispose(){this.rateLimiter.stopCleanup(),this.rateLimiter.clear(),this.dispatcher.clear(),this._api={}}}var se;e.MessageProtocolType=void 0,(se=e.MessageProtocolType||(e.MessageProtocolType={})).GET="get",se.GET_RESPONSE="get-response",se.SET="set",se.DELETE="delete",se.CLEAR="clear",se.MESSAGE="message",se.SUBSCRIBE="subscribe",se.UNSUBSCRIBE="unsubscribe",se.SET_PERMISSION="set-permission",se.CONNECT="__message_bus_ready__",se.TRANSACTION_START="transaction-start",se.TRANSACTION_COMMIT="transaction-commit",se.TRANSACTION_ROLLBACK="transaction-rollback",se.UPDATE="update",se.SEND_TO_WINDOW="send-to-window",se.SEND_TO_GROUP="send-to-group";class ie{buffers=new Map;logger;constructor(e){this.logger=e}start(e){this.buffers.has(e)?this.logger.warn(`Transaction already started for window ${e}`):this.buffers.set(e,new Map)}commit(e){const t=this.buffers.get(e);if(t)return this.buffers.delete(e),t;this.logger.warn(`No transaction to commit for window ${e}`)}rollback(e){this.buffers.has(e)?this.buffers.delete(e):this.logger.warn(`No transaction to rollback for window ${e}`)}add(e,t,s){return!!this.buffers.has(e)&&(this.buffers.get(e).set(t,s),!0)}hasTransaction(e){return this.buffers.has(e)}getBufferedValue(e,t){if(this.buffers.has(e)){const s=this.buffers.get(e);if(s.has(t)){const e=s.get(t);return"set"===e.type?{has:!0,value:e.value}:{has:!0,value:void 0}}}return{has:!1}}clear(){this.buffers.clear()}}class re{subscriptions=new Map;logger;MAX_SUBSCRIPTIONS_PER_KEY=100;constructor(e){this.logger=e}subscribe(e,t){t.forEach(t=>{this.subscriptions.has(t)||this.subscriptions.set(t,new Set);const s=this.subscriptions.get(t);s.add(e),this.logger&&s.size>this.MAX_SUBSCRIPTIONS_PER_KEY&&s.size===this.MAX_SUBSCRIPTIONS_PER_KEY+1&&this.logger.warn(`High number of subscriptions (${s.size}) for key: "${t}". Potential memory leak or design issue.`)})}unsubscribe(e,t){t.forEach(t=>{const s=this.subscriptions.get(t);s&&(s.delete(e),0===s.size&&this.subscriptions.delete(t))})}removeWindow(e){this.subscriptions.forEach((t,s)=>{t.has(e)&&(t.delete(e),0===t.size&&this.subscriptions.delete(s))})}getSubscribers(e){return this.subscriptions.get(e)}clear(){this.subscriptions.clear()}}class oe{dataStore=new Map;get(e){return this.dataStore.get(e)?.value}getItem(e){return this.dataStore.get(e)}getAll(){const e={};return this.dataStore.forEach((t,s)=>{e[s]=t.value}),e}set(e,t){const s=this.dataStore.get(e);this.dataStore.set(e,{value:t,permission:s?.permission})}delete(e){this.dataStore.delete(e)}checkPermission(e,t,s){const i=this.dataStore.get(e);if(i?.permission){const r="string"==typeof i.permission?{mode:i.permission}:i.permission;if(r.readonly)return{success:!1,error:`Field "${e}" is readonly`};if(r.allowedWindows&&t&&!r.allowedWindows.includes(t))return{success:!1,error:`Window "${t}" is not allowed to ${s} "${e}"`}}return{success:!0}}setPermission(e,t){const s=this.dataStore.get(e);s?s.permission=t:this.dataStore.set(e,{value:void 0,permission:t})}clear(){this.dataStore.clear()}}class ne{port;_isClosed=!1;constructor(e){this.port=e}get isClosed(){return this._isClosed}postMessage(e){if(this._isClosed)return!1;try{return this.port.postMessage(e),!0}catch(e){throw this._isClosed=!0,e}}close(){if(!this._isClosed){this._isClosed=!0;try{this.port.close()}catch(e){}}}get rawPort(){return this.port}}class ae{ports=new Map;logger;constructor(e){this.logger=e}register(e,s,i){this.unregister(e);const{port1:r,port2:o}=new t.MessageChannelMain,n=new ne(r);this.ports.set(e,n),r.on("message",t=>{let s;try{s="string"==typeof t.data?JSON.parse(t.data):t.data}catch(t){return void this.logger.error(`Failed to parse message from window ${e}: ${t}`)}i(s,n)}),r.start();const a=()=>{try{s.webContents.postMessage(C,null,[o])}catch(t){this.logger.error(`Failed to post message to window ${e}: ${t}`),n.close(),this.ports.delete(e)}};s.webContents.isLoading()?s.webContents.once("did-finish-load",a):a()}unregister(e){const t=this.ports.get(e);return!!t&&(t.close(),this.ports.delete(e),!0)}get(e){return this.ports.get(e)}broadcast(e,t){let s=0;return(t||Array.from(this.ports.keys())).forEach(t=>{const i=this.ports.get(t);if(i)try{i.postMessage(e)&&s++}catch(e){this.logger.error(`Failed to broadcast to window ${t}: ${e}`)}}),s}dispose(){this.ports.forEach(e=>e.close()),this.ports.clear()}getAllWindowIds(){return Array.from(this.ports.keys())}}class de{name="messageport";portManager;onMessage;constructor(e){this.portManager=new ae(e)}init(e){this.onMessage=e}registerWindow(e,t){this.portManager.register(e,t,(t,s)=>{this.onMessage&&this.onMessage(t,e)})}unregisterWindow(e){this.portManager.unregister(e)}send(e,t){const s=this.portManager.get(e);if(s){const e="string"==typeof t?t:JSON.stringify(t);s.postMessage(e)}}broadcast(e,t){const s="string"==typeof e?e:JSON.stringify(e);return this.portManager.broadcast(s,t)}dispose(){}}const he="message-bus-ipc";class ce{name="ipc";logger;windows=new Map;onMessage;constructor(e){this.logger=e,this.setupIpcListener()}setupIpcListener(){t.ipcMain.on(he,(e,t)=>{const s=this.findWindowId(e.sender.id);s&&this.onMessage&&this.onMessage(t,s)})}findWindowId(e){for(const[t,s]of this.windows.entries())if(s.webContents.id===e)return t}init(e){this.onMessage=e}registerWindow(e,t){this.windows.set(e,t)}unregisterWindow(e){this.windows.delete(e)}send(e,t){const s=this.windows.get(e);s&&!s.isDestroyed()&&s.webContents.send(he,t)}broadcast(e,t){let s=0;const i=t||Array.from(this.windows.keys());for(const t of i)try{this.send(t,e),s++}catch(e){this.logger.error(`Failed to send IPC message to ${t}`,e)}return s}dispose(){this.windows.clear(),t.ipcMain.removeAllListeners(he)}}class le extends o.EventEmitter{eventName=O;logger;subscriptionManager;transactionManager;dataStoreManager;transport;transportMode;windows=new Map;dispatcher;groupResolver;watchCallbacks=new Set;windowSubscriptions=new WeakMap;constructor(e={}){super(),this.eventName=e.eventName||O,this.logger=e.logger||new w({appName:"MessageBus"}),this.dispatcher=new V("MessageBus",this.logger),this.subscriptionManager=new re(this.logger),this.transactionManager=new ie(this.logger),this.dataStoreManager=new oe;const t=e.transportMode||"auto";this.transportMode=this.selectTransportMode(t),this.transport=this.createTransport(this.transportMode);try{this.transport.init((e,t)=>this.handleTransportMessage(e,t)),this.logger.info(`MessageBus initialized with ${this.transportMode} transport`)}catch(e){this.logger.error(`Failed to initialize ${this.transportMode} transport: ${e}. Falling back to IPC.`),this.transportMode="ipc",this.transport=new ce(this.logger),this.transport.init((e,t)=>this.handleTransportMessage(e,t))}this.registerDefaultHandlers()}selectTransportMode(e){return"ipc"===e?"ipc":"messageport"===e?"messageport":void 0===t.MessageChannelMain?(this.logger.warn("MessageChannelMain not available, falling back to IPC transport"),"ipc"):"messageport"}createTransport(e){return"ipc"===e?new ce(this.logger):new de(this.logger)}handleTransportMessage(t,s){try{if(t&&t.type){const i=this.dispatcher.dispatch(t.type,this,{...t,windowId:s});t.requestId&&Promise.resolve(i).then(i=>{this.transport.send(s,{type:e.MessageProtocolType.GET_RESPONSE,requestId:t.requestId,value:i})}).catch(e=>{this.logger.error(`Error handling message ${t.type}: ${e}`)})}}catch(e){this.logger.error(`Failed to handle message from window ${s}: ${e}`)}}registerWindow(e,t){this.unregisterWindow(e),this.windows.set(e,t),this.transport.registerWindow(e,t)}unregisterWindow(e){const t=this.windows.get(e);if(t&&this.windowSubscriptions.has(t)){const s=this.windowSubscriptions.get(t);s&&(this.logger.info(`Cleaning up ${s.size} subscriptions for window ${e}`),s.forEach(e=>{try{e()}catch(e){}}),this.windowSubscriptions.delete(t))}this.transport.unregisterWindow(e),this.windows.delete(e),this.subscriptionManager.removeWindow(e),this.transactionManager.hasTransaction(e)&&this.transactionManager.rollback(e)}autoRegisterWindows(e){e.on("window-created",({window:e,id:t})=>{this.registerWindow(t,e)}),e.on("window-will-be-destroyed",e=>{this.unregisterWindow(e)})}dispose(){this.logger.info("Disposing MessageBus..."),this.watchCallbacks.forEach(e=>{try{e()}catch(e){this.logger.warn(`Failed to unsubscribe watch callback: ${e}`)}}),this.watchCallbacks.clear(),this.dispatcher.clear(),this.transport.dispose(),this.dataStoreManager.clear(),this.subscriptionManager.clear(),this.transactionManager.clear(),this.windows.clear(),this.removeAllListeners(),this.logger.info("MessageBus disposed")}registerHandler(e){this.on(e.eventName,e.callback)}registerHandlers(e){e.forEach(e=>this.registerHandler(e))}unregisterHandler(e){this.removeListener(e.eventName,e.callback)}unregisterHandlers(e){e.forEach(e=>this.unregisterHandler(e))}getData(e){return e?this.dataStoreManager.get(e):this.dataStoreManager.getAll()}checkPermission(e,t,s){return this.dataStoreManager.checkPermission(e,t,s)}setData(t,s,i,r,o=!1){const n=this.checkPermission(t,i,"modify");if(!n.success)return n;if(!o&&i&&this.transactionManager.hasTransaction(i))return this.transactionManager.add(i,t,{type:"set",value:s}),{success:!0};const a=this.dataStoreManager.getItem(t),d=a?.value;this.dataStoreManager.set(t,s);const h={type:e.MessageProtocolType.SET,key:t,value:s,oldValue:d,windowId:i,timestamp:Date.now()};return this.broadcastChange(h),this.emit(r||this.eventName,h),{success:!0}}deleteData(t,s,i,r=!1){const o=this.checkPermission(t,s,"delete");if(!o.success)return o;if(!r&&s&&this.transactionManager.hasTransaction(s))return this.transactionManager.add(s,t,{type:"delete"}),{success:!0};const n=this.dataStoreManager.getItem(t),a=n?.value;this.dataStoreManager.delete(t);const d={type:e.MessageProtocolType.DELETE,key:t,oldValue:a,windowId:s,timestamp:Date.now()};return this.broadcastChange(d),this.emit(i||this.eventName,d),{success:!0}}startTransaction(e){this.transactionManager.start(e)}commitTransaction(e){const t=this.transactionManager.commit(e);t&&t.forEach((t,s)=>{"set"===t.type?this.setData(s,t.value,e,void 0,!0):"delete"===t.type&&this.deleteData(s,e,void 0,!0)})}rollbackTransaction(e){this.transactionManager.rollback(e)}watch(t,s,i){const r=i=>{"key"in i&&i.key===t&&(i.type===e.MessageProtocolType.SET?s(i.value,i.oldValue):i.type===e.MessageProtocolType.DELETE&&s(void 0,i.oldValue))};this.on(this.eventName,r);const o=()=>{if(this.off(this.eventName,r),this.watchCallbacks.delete(o),i){const e=this.windows.get(i);e&&this.windowSubscriptions.has(e)&&this.windowSubscriptions.get(e)?.delete(o)}};if(this.watchCallbacks.add(o),i){const e=this.windows.get(i);e?(this.windowSubscriptions.has(e)||this.windowSubscriptions.set(e,new Set),this.windowSubscriptions.get(e).add(o)):this.logger.warn(`Window ${i} not found, watch subscription will not be auto-cleaned up on window destroy`)}return o}updateData(e,t,s){let i=this.dataStoreManager.get(e);if(s){const t=this.transactionManager.getBufferedValue(s,e);t.has&&(i=t.value)}const r="function"==typeof t?t(i):t;return this.setData(e,r,s)}setFieldPermission(e,t){this.dataStoreManager.setPermission(e,t)}getRegisteredWindows(){return Array.from(this.windows.keys())}registerMessageHandler(e){this.dispatcher.register(e.name,e.callback)}registerDefaultHandlers(){this.registerMessageHandler({name:e.MessageProtocolType.GET,callback:(e,{key:t}={})=>e.getData(t)}),this.registerMessageHandler({name:e.MessageProtocolType.SET,callback:(e,{key:t,value:s,windowId:i,eventName:r})=>e.setData(t,s,i,r)}),this.registerMessageHandler({name:e.MessageProtocolType.DELETE,callback:(e,{key:t,windowId:s,eventName:i})=>e.deleteData(t,s,i)}),this.registerMessageHandler({name:e.MessageProtocolType.SET_PERMISSION,callback:(e,{key:t,permission:s})=>e.setFieldPermission(t,s)}),this.registerMessageHandler({name:e.MessageProtocolType.SUBSCRIBE,callback:(e,{windowId:t,keys:s})=>e.subscribe(t,s)}),this.registerMessageHandler({name:e.MessageProtocolType.UNSUBSCRIBE,callback:(e,{windowId:t,keys:s})=>e.unsubscribe(t,s)}),this.registerMessageHandler({name:e.MessageProtocolType.TRANSACTION_START,callback:(e,{windowId:t})=>e.startTransaction(t)}),this.registerMessageHandler({name:e.MessageProtocolType.TRANSACTION_COMMIT,callback:(e,{windowId:t})=>e.commitTransaction(t)}),this.registerMessageHandler({name:e.MessageProtocolType.TRANSACTION_ROLLBACK,callback:(e,{windowId:t})=>e.rollbackTransaction(t)}),this.registerMessageHandler({name:e.MessageProtocolType.SEND_TO_WINDOW,callback:(e,{targetWindowId:t,channel:s,data:i})=>e.sendToWindow(t,s,i)}),this.registerMessageHandler({name:e.MessageProtocolType.SEND_TO_GROUP,callback:(e,{group:t,channel:s,data:i})=>e.sendToGroup(t,s,i)}),this.registerMessageHandler({name:e.MessageProtocolType.UPDATE,callback:(e,{key:t,value:s,windowId:i})=>e.setData(t,s,i)})}handleMessage(e,t){return this.dispatcher.dispatch(e,this,t)}initializeListener(){t.ipcMain.handle("message-bus-invoke",(e,{name:t,data:s})=>this.handleMessage(t,s))}setGroupResolver(e){this.groupResolver=e}sendToWindow(t,s,i){const r=x.getInstance(),o=`message-bus-send-${Date.now()}`;if(r.startMeasure(o,"MessageBus Send",{windowId:t,channel:s}),!this.windows.has(t))return this.logger.warn(`Window ${t} not found or not registered`),r.endMeasure(o,{status:"failed",reason:"window_not_found"}),!1;try{const n={type:e.MessageProtocolType.MESSAGE,channel:s,value:i,timestamp:Date.now()};return this.transport.send(t,JSON.stringify(n)),r.endMeasure(o,{status:"success"}),!0}catch(e){return this.logger.error(`Failed to send message to window ${t}: ${e}`),this.emit("error",e),r.endMeasure(o,{status:"error",error:e instanceof Error?e.message:String(e)}),!1}}sendToGroup(e,t,s){const i=x.getInstance(),r=`message-bus-broadcast-${Date.now()}`;if(i.startMeasure(r,"MessageBus Broadcast",{group:e,channel:t}),!this.groupResolver)return this.logger.warn("Group resolver not set, cannot send to group"),i.endMeasure(r,{status:"failed",reason:"no_group_resolver"}),0;const o=this.groupResolver(e),n=this.broadcastToWindows(o,t,s);return i.endMeasure(r,{status:"success",windowCount:o.length,successCount:n}),n}broadcastToWindows(t,s,i){const r={type:e.MessageProtocolType.MESSAGE,channel:s,value:i,timestamp:Date.now()},o=JSON.stringify(r);return this.transport.broadcast(o,t)}subscribe(e,t){this.subscriptionManager.subscribe(e,t)}unsubscribe(e,t){this.subscriptionManager.unsubscribe(e,t)}broadcastChange(e){const t=JSON.stringify(e);if("key"in e&&e.key){const s=this.subscriptionManager.getSubscribers(e.key);if(s)return void this.transport.broadcast(t,Array.from(s))}this.transport.broadcast(t)}}var ge;e.WindowErrorCode=void 0,(ge=e.WindowErrorCode||(e.WindowErrorCode={}))[ge.CONFIG_INVALID=1001]="CONFIG_INVALID",ge[ge.CONFIG_MISSING=1002]="CONFIG_MISSING",ge[ge.WINDOW_NOT_FOUND=2001]="WINDOW_NOT_FOUND",ge[ge.WINDOW_CREATION_FAILED=2002]="WINDOW_CREATION_FAILED",ge[ge.WINDOW_ALREADY_EXISTS=2003]="WINDOW_ALREADY_EXISTS",ge[ge.WINDOW_LIMIT_REACHED=2004]="WINDOW_LIMIT_REACHED",ge[ge.WINDOW_DESTROYED=2005]="WINDOW_DESTROYED",ge[ge.IPC_CONNECTION_FAILED=3001]="IPC_CONNECTION_FAILED",ge[ge.IPC_TIMEOUT=3002]="IPC_TIMEOUT",ge[ge.IPC_HANDLER_ERROR=3003]="IPC_HANDLER_ERROR",ge[ge.INTERNAL_ERROR=5001]="INTERNAL_ERROR",ge[ge.DEPENDENCY_MISSING=5002]="DEPENDENCY_MISSING";class ue extends Error{code;originalError;details;suggestion;constructor(e){super(e.message),this.name="WindowError",this.code=e.code,this.originalError=e.originalError,this.details=e.details,this.suggestion=e.suggestion,Object.setPrototypeOf(this,ue.prototype)}getErrorCategory(){return this.code>=1e3&&this.code<2e3?"configuration":this.code>=2e3&&this.code<3e3?"window":this.code>=3e3&&this.code<4e3?"ipc":this.code>=5e3&&this.code<6e3?"system":"unknown"}toJSON(){return{name:this.name,message:this.message,code:this.code,category:this.getErrorCategory(),details:this.details,suggestion:this.suggestion}}}class we{bindings;channel=N;syncChannel=D;constructor(){this.bindings={invoke:this.invoke.bind(this),sendSync:this.sendSync.bind(this)}}configure(e){e.channel&&(this.channel=e.channel),e.syncChannel&&(this.syncChannel=e.syncChannel)}invoke=async(e,s)=>{const i=await t.ipcRenderer.invoke(this.channel,{name:e,payload:s});if(i&&"object"==typeof i&&"code"in i){if(0===i.code)return i.data;throw new Error(i.message||`IPC Error: ${i.code}`)}return i};sendSync=(e,s)=>{const i=t.ipcRenderer.sendSync(this.syncChannel,{name:e,payload:s});if(i&&"object"==typeof i&&"code"in i){if(0===i.code)return i.data;throw new Error(i.message||`IPC Error: ${i.code}`)}return i};getBindings(){return this.bindings}exposeApi(e="ipcApi"){try{t.contextBridge.exposeInMainWorld(e,this.bindings)}catch(e){console.error("[IpcRendererBridge] Failed to expose API:",e)}}}const pe=new we;class me extends s.TypedEmitter{config={};filePath;logger;autoSave;saveTimer=null;saveDelay;schema;constructor(e={}){super(),this.logger=e.logger||new w({appName:"ConfigManager"}),this.autoSave=e.autoSave??!0,this.saveDelay=e.saveDelay||100,this.schema=e.schema;const s=t.app.getPath("userData");this.filePath=g.join(s,e.filename||"config.json"),this.load()}get(e,t){const s=this.getDeep(this.config,e);return void 0===s?t:s}set(e,t){const s=this.get(e);if(JSON.stringify(s)!==JSON.stringify(t)){if(this.schema){const s=JSON.parse(JSON.stringify(this.config));this.setDeep(s,e,t);const i=this.schema.safeParse(s);if(!i.success)throw new Error(`Configuration validation failed: ${i.error.message}`)}this.setDeep(this.config,e,t),this.emit("change",e,t,s),this.autoSave&&this.triggerSave()}}delete(e){if(!this.has(e))return;const t=this.get(e);this.deleteDeep(this.config,e),this.emit("change",e,void 0,t),this.autoSave&&this.triggerSave()}has(e){return void 0!==this.getDeep(this.config,e)}clear(){this.config={},this.emit("change","",{},{}),this.autoSave&&this.triggerSave()}async save(){this.saveTimer&&(clearTimeout(this.saveTimer),this.saveTimer=null);try{const e=JSON.stringify(this.config,null,2);await l.promises.writeFile(this.filePath,e,"utf-8"),this.emit("saved")}catch(e){const t=e instanceof Error?e:new Error(String(e));this.logger.error(`Failed to save configuration: ${t.message}`),this.emit("error",t)}}load(){try{if(l.existsSync(this.filePath)){const e=l.readFileSync(this.filePath,"utf-8");let t=JSON.parse(e);if(this.schema){const e=this.schema.safeParse(t);e.success?t=e.data:(this.logger.error(`Configuration validation failed: ${e.error.message}`),this.emit("error",new Error(`Configuration validation failed: ${e.error.message}`)))}this.config=t,this.emit("loaded",this.config),this.logger.info(`Configuration loaded from ${this.filePath}`)}else this.logger.info("No configuration file found, starting with empty config")}catch(e){const t=e instanceof Error?e:new Error(String(e));this.logger.error(`Failed to load configuration: ${t.message}`),this.emit("error",t)}}getAll(){return JSON.parse(JSON.stringify(this.config))}triggerSave(){this.saveTimer&&clearTimeout(this.saveTimer),this.saveTimer=setTimeout(()=>{this.save()},this.saveDelay)}getDeep(e,t){if(!t)return;const s=t.split(".");let i=e;for(const e of s){if(null==i)return;i=i[e]}return i}setDeep(e,t,s){if(!t)return;const i=t.split("."),r=i.pop();let o=e;for(const e of i)void 0!==o[e]&&null!==o[e]&&"object"==typeof o[e]||(o[e]={}),o=o[e];o[r]=s}deleteDeep(e,t){if(!t)return;const s=t.split("."),i=s.pop();let r=e;for(const e of s){if(void 0===r[e]||null===r[e])return;r=r[e]}delete r[i]}}var fe=Object.freeze({__proto__:null,get MessageProtocolType(){return e.MessageProtocolType},createChannelName:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid channel name: must be a non-empty string");return e},createEventName:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid event name: must be a non-empty string");return e},createFieldKey:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid field key: must be a non-empty string");return e},createHandlerName:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid handler name: must be a non-empty string");return e},createWindowId:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid window ID: must be a non-empty string");return e}});e.ConfigManager=me,e.DebugHelper=z,e.ElectronToolkitError=Y,e.EnhancedDebugHelper=A,e.IpcHandler=class{_name;_event;_callback;_schema;constructor(e,t,s,i){this._name=e,this._event=t,this._callback=s,this._schema=i}get name(){return this._name}get event(){return this._event}get callback(){return this._callback}get schema(){return this._schema}},e.IpcHandlerError=Q,e.IpcRendererBridge=we,e.IpcRouter=te,e.IpcSetup=$,e.LifecycleManager=class{windowManager;ipcRouter;messageBus;logger;isStarted=!1;config;constructor(e={}){this.config=e;const t=e.logger||m(e.loggerOptions);this.logger=t,e.autoStart&&this.startup().catch(e=>{this.logger.error(`Auto-startup failed: ${e}`)})}async startup(){if(this.isStarted)this.logger.warn("LifecycleManager already started");else try{this.logger.info("Starting up Electron Toolkit services..."),this.ipcRouter=this.config.ipcRouter||new te({logger:this.logger}),this.logger.info("IpcRouter initialized"),this.messageBus=this.config.messageBus||new le({logger:this.logger}),this.windowManager=this.config.windowManager||new U({...this.config,logger:this.logger,ipcRouter:this.ipcRouter,messageBus:this.messageBus}),await this.windowManager.ready(),this.logger.info("WindowManager initialized"),this.messageBus.autoRegisterWindows(this.windowManager),this.logger.info("MessageBus initialized"),(this.config.isDevelopment||"development"===process.env.NODE_ENV)&&(z.enableDebugMode(),z.register("windowManager",this.windowManager),z.register("ipcRouter",this.ipcRouter),z.register("messageBus",this.messageBus),z.register("lifecycleManager",this),this.logger.info("Debug mode enabled")),this.isStarted=!0,this.logger.info("Startup completed successfully")}catch(e){throw this.logger.error(`Startup failed: ${e}`),await this.shutdown(),e}}async shutdown(){if(this.logger.info("Shutting down Electron Toolkit services..."),this.messageBus){try{this.messageBus.dispose(),this.logger.info("MessageBus disposed")}catch(e){this.logger.warn(`MessageBus dispose error: ${e}`)}this.messageBus=void 0}if(this.windowManager){try{"function"==typeof this.windowManager.dispose?(await this.windowManager.dispose(),this.logger.info("WindowManager disposed")):this.windowManager.stopCleanupProtection()}catch(e){this.logger.warn(`WindowManager dispose error: ${e}`)}this.windowManager=void 0}if(this.ipcRouter){try{this.ipcRouter.dispose(),this.logger.info("IpcRouter disposed")}catch(e){this.logger.warn(`IpcRouter dispose error: ${e}`)}this.ipcRouter=void 0}this.isStarted=!1,this.logger.info("Shutdown completed")}get started(){return this.isStarted}},e.Logger=w,e.MessageBus=le,e.MessageBusClient=class{port=null;ready=!1;pendingOperations=[];subscriptions=new Map;messageListeners=new Map;pendingRequests=new Map;logger;constructor(e={}){this.logger=e.logger||new w({appName:"MessageBusClient"}),this.initialize()}subscribe(t,s){return this.subscriptions.has(t)||(this.subscriptions.set(t,new Set),this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.SUBSCRIBE,keys:[t]}))})),this.subscriptions.get(t).add(s),()=>{this.subscriptions.get(t)?.delete(s),0===this.subscriptions.get(t)?.size&&(this.subscriptions.delete(t),this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.UNSUBSCRIBE,keys:[t]}))}))}}watch(e,t){return this.subscribe(e,t)}onMessage(e,t){return this.messageListeners.has(e)||this.messageListeners.set(e,new Set),this.messageListeners.get(e).add(t),()=>{this.messageListeners.get(e)?.delete(t),0===this.messageListeners.get(e)?.size&&this.messageListeners.delete(e)}}sendToWindow(t,s,i){this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.SEND_TO_WINDOW,targetWindowId:t,channel:s,data:i}))})}sendToGroup(t,s,i){this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.SEND_TO_GROUP,group:t,channel:s,data:i}))})}set(t,s){this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.SET,key:t,value:s}))})}async get(t){return new Promise(s=>{this.ensureReady(()=>{const i=r.v4(),o=setTimeout(()=>{this.pendingRequests.has(i)&&(this.pendingRequests.delete(i),this.logger.warn(`Get request for key "${t}" timed out`),s(void 0))},5e3);this.pendingRequests.set(i,{resolve:s,timeout:o}),this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.GET,key:t,requestId:i}))})})}delete(t){this.ensureReady(()=>{this.port.postMessage(JSON.stringify({type:e.MessageProtocolType.DELETE,key:t}))})}initialize(){window.addEventListener("message",t=>{t.data?.type===e.MessageProtocolType.CONNECT&&(this.port=t.ports[0],this.port.onmessage=this.handleMessage.bind(this),this.port.start(),this.ready=!0,this.logger.debug("MessageBusClient connected"),this.pendingOperations.forEach(e=>e()),this.pendingOperations=[])})}handleMessage(t){try{const s=JSON.parse(t.data);if(s.type===e.MessageProtocolType.GET_RESPONSE&&s.requestId){const e=this.pendingRequests.get(s.requestId);return void(e&&(clearTimeout(e.timeout),this.pendingRequests.delete(s.requestId),e.resolve(s.value)))}if("message"===s.type&&s.channel){const e=this.messageListeners.get(s.channel);return void(e&&e.forEach(e=>{try{e(s.value)}catch(e){this.logger.error(`Error in message listener for channel "${s.channel}": ${e}`)}}))}if(s.key&&(s.type===e.MessageProtocolType.SET||s.type===e.MessageProtocolType.DELETE)){const e=this.subscriptions.get(s.key);e&&e.forEach(e=>{try{e(s.value)}catch(e){this.logger.error(`Error in subscription callback for key "${s.key}": ${e}`)}})}}catch(e){this.logger.error(`Failed to handle message: ${e}`)}}ensureReady(e){this.ready?e():this.pendingOperations.push(e)}dispose(){this.port&&(this.port.close(),this.port=null),this.subscriptions.clear(),this.pendingOperations=[],this.pendingRequests.forEach(e=>{clearTimeout(e.timeout),e.resolve(void 0)}),this.pendingRequests.clear(),this.ready=!1}},e.NotFoundError=class extends X{constructor(t,s){super(404,t,e.ErrorCategory.NOT_FOUND,s),this.name="NotFoundError"}},e.PermissionError=class extends X{constructor(t,s){super(403,t,e.ErrorCategory.PERMISSION,s),this.name="PermissionError"}},e.StandardError=X,e.Types=fe,e.ValidationError=class extends X{constructor(t,s){super(422,t,e.ErrorCategory.VALIDATION,s),this.name="ValidationError"}},e.WindowCreator=F,e.WindowError=ue,e.WindowManager=U,e.WindowNotFoundError=class extends Y{constructor(e){super(`Window "${e}" not found or destroyed`,"WINDOW_NOT_FOUND",{windowId:e})}},e.WindowStore=R,e.createElectronToolkit=function(e={}){const t=e.logger||m(e.loggerOptions),s=new te({logger:t}),i=new U({...e,logger:t,ipcRouter:s}),r=new le({logger:t});return r.autoRegisterWindows(i),(e.isDevelopment||"development"===process.env.NODE_ENV)&&(z.enableDebugMode(),z.register("windowManager",i),z.register("ipcRouter",s),z.register("messageBus",r)),{windowManager:i,ipcRouter:s,messageBus:r}},e.debugHelper=L,e.getSharedLogger=m,e.ipcRendererBridge=pe,e.setSharedLogger=function(e){p=e},e.setupMessageBus=function(){t.ipcRenderer.on(C,t=>{const[s]=t.ports;s?window.postMessage({type:e.MessageProtocolType.CONNECT,port:s},"*",[s]):console.error("[MessageBus] No port received in message-bus-port event")})},e.validateWindowManagerConfig=v});
|
|
@@ -15,6 +15,10 @@ export interface LoggerOptions {
|
|
|
15
15
|
fileLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;
|
|
16
16
|
/** Console log level / 控制台日志级别 */
|
|
17
17
|
consoleLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;
|
|
18
|
+
/** Enable IPC transport / 启用 IPC 传输 */
|
|
19
|
+
ipcEnabled?: boolean;
|
|
20
|
+
/** IPC transport level / IPC 传输级别 */
|
|
21
|
+
ipcLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;
|
|
18
22
|
}
|
|
19
23
|
/**
|
|
20
24
|
* Default logger implementation using electron-log
|
|
@@ -13,10 +13,12 @@ class ElectronLogger {
|
|
|
13
13
|
constructor(options = {}) {
|
|
14
14
|
this.isDev = process.env.NODE_ENV !== 'production';
|
|
15
15
|
const { appName = 'main', maxSize = 10 * 1024 * 1024, // Default 10MB
|
|
16
|
-
fileName, fileLevel, consoleLevel, } = options;
|
|
16
|
+
fileName, fileLevel, consoleLevel, ipcEnabled, ipcLevel, } = options;
|
|
17
17
|
// Create a logger instance for either 'main' or 'renderer'
|
|
18
18
|
this.logger = LoggerService.create({ logId: appName });
|
|
19
19
|
this.logger.scope(appName);
|
|
20
|
+
const defaultIpcLevel = this.isDev ? 'silly' : 'info';
|
|
21
|
+
this.logger.transports.ipc.level = ipcLevel ?? (ipcEnabled ? defaultIpcLevel : false);
|
|
20
22
|
// Set log levels with smart defaults based on environment
|
|
21
23
|
// 根据环境设置日志级别,使用智能默认值
|
|
22
24
|
const defaultFileLevel = this.isDev ? 'debug' : 'info';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronLogger.js","sources":["../../../src/infrastructure/logger/ElectronLogger.ts"],"sourcesContent":["import LoggerService from 'electron-log';\nimport { ILogger } from './logger.type';\n\n/**\n * Logger Configuration Options\n * 日志配置选项\n */\nexport interface LoggerOptions {\n /** Application name for log identification / 应用名称用于日志标识 */\n appName?: string;\n /** Maximum log file size in bytes / 最大日志文件大小(字节) */\n maxSize?: number;\n /** Custom log file name / 自定义日志文件名 */\n fileName?: string;\n /** File log level / 文件日志级别 */\n fileLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n /** Console log level / 控制台日志级别 */\n consoleLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n}\n\n/**\n * Default logger implementation using electron-log\n * 使用 electron-log 的默认日志实现\n */\nexport class ElectronLogger implements ILogger {\n private logger: typeof LoggerService;\n private isDev: boolean;\n\n /**\n * Constructor for Logger\n * 日志记录器构造函数\n * @param options - Logger configuration options\n */\n constructor(options: LoggerOptions = {}) {\n this.isDev = process.env.NODE_ENV !== 'production';\n\n const {\n appName = 'main',\n maxSize = 10 * 1024 * 1024, // Default 10MB\n fileName,\n fileLevel,\n consoleLevel,\n } = options;\n\n // Create a logger instance for either 'main' or 'renderer'\n this.logger = LoggerService.create({ logId: appName });\n this.logger.scope(appName);\n\n // Set log levels with smart defaults based on environment\n // 根据环境设置日志级别,使用智能默认值\n const defaultFileLevel = this.isDev ? 'debug' : 'info';\n const defaultConsoleLevel = this.isDev ? 'debug' : false;\n\n this.logger.transports.file.level = fileLevel ?? defaultFileLevel;\n this.logger.transports.console.level = consoleLevel ?? defaultConsoleLevel;\n\n // Optimize log format with date and log level\n // 优化日志格式,增加日期和日志级别\n this.logger.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}';\n\n // Set maximum file size (configurable)\n // 设置最大文件大小(可配置)\n this.logger.transports.file.maxSize = maxSize;\n\n // Set log file name (configurable or default based on environment)\n // 设置日志文件名(可配置或根据环境使用默认值)\n this.logger.transports.file.fileName =\n fileName ?? (this.isDev ? `${appName}_dev.log` : `${appName}.log`);\n }\n\n // Info log\n info(message: string, ...args: any[]): void {\n this.logger.info(message, ...args);\n }\n\n // Debug log\n debug(message: string, ...args: any[]): void {\n this.logger.debug(message, ...args);\n }\n\n // Error log\n error(message: string, ...args: any[]): void {\n this.logger.error(message, ...args);\n }\n\n // Warn log\n warn(message: string, ...args: any[]): void {\n this.logger.warn(message, ...args);\n }\n\n // Verbose log\n verbose(message: string, ...args: any[]): void {\n this.logger.verbose(message, ...args);\n }\n\n // Silly log\n silly(message: string, ...args: any[]): void {\n this.logger.silly(message, ...args);\n }\n\n // Get the logger instance (useful if you need more custom configurations)\n getLogger(): typeof LoggerService {\n return this.logger;\n }\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ElectronLogger.js","sources":["../../../src/infrastructure/logger/ElectronLogger.ts"],"sourcesContent":["import LoggerService from 'electron-log';\nimport { ILogger } from './logger.type';\n\n/**\n * Logger Configuration Options\n * 日志配置选项\n */\nexport interface LoggerOptions {\n /** Application name for log identification / 应用名称用于日志标识 */\n appName?: string;\n /** Maximum log file size in bytes / 最大日志文件大小(字节) */\n maxSize?: number;\n /** Custom log file name / 自定义日志文件名 */\n fileName?: string;\n /** File log level / 文件日志级别 */\n fileLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n /** Console log level / 控制台日志级别 */\n consoleLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n /** Enable IPC transport / 启用 IPC 传输 */\n ipcEnabled?: boolean;\n /** IPC transport level / IPC 传输级别 */\n ipcLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n}\n\n/**\n * Default logger implementation using electron-log\n * 使用 electron-log 的默认日志实现\n */\nexport class ElectronLogger implements ILogger {\n private logger: typeof LoggerService;\n private isDev: boolean;\n\n /**\n * Constructor for Logger\n * 日志记录器构造函数\n * @param options - Logger configuration options\n */\n constructor(options: LoggerOptions = {}) {\n this.isDev = process.env.NODE_ENV !== 'production';\n\n const {\n appName = 'main',\n maxSize = 10 * 1024 * 1024, // Default 10MB\n fileName,\n fileLevel,\n consoleLevel,\n ipcEnabled,\n ipcLevel,\n } = options;\n\n // Create a logger instance for either 'main' or 'renderer'\n this.logger = LoggerService.create({ logId: appName });\n this.logger.scope(appName);\n const defaultIpcLevel = this.isDev ? 'silly' : 'info';\n this.logger.transports.ipc.level = ipcLevel ?? (ipcEnabled ? defaultIpcLevel : false);\n\n // Set log levels with smart defaults based on environment\n // 根据环境设置日志级别,使用智能默认值\n const defaultFileLevel = this.isDev ? 'debug' : 'info';\n const defaultConsoleLevel = this.isDev ? 'debug' : false;\n\n this.logger.transports.file.level = fileLevel ?? defaultFileLevel;\n this.logger.transports.console.level = consoleLevel ?? defaultConsoleLevel;\n\n // Optimize log format with date and log level\n // 优化日志格式,增加日期和日志级别\n this.logger.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}';\n\n // Set maximum file size (configurable)\n // 设置最大文件大小(可配置)\n this.logger.transports.file.maxSize = maxSize;\n\n // Set log file name (configurable or default based on environment)\n // 设置日志文件名(可配置或根据环境使用默认值)\n this.logger.transports.file.fileName =\n fileName ?? (this.isDev ? `${appName}_dev.log` : `${appName}.log`);\n }\n\n // Info log\n info(message: string, ...args: any[]): void {\n this.logger.info(message, ...args);\n }\n\n // Debug log\n debug(message: string, ...args: any[]): void {\n this.logger.debug(message, ...args);\n }\n\n // Error log\n error(message: string, ...args: any[]): void {\n this.logger.error(message, ...args);\n }\n\n // Warn log\n warn(message: string, ...args: any[]): void {\n this.logger.warn(message, ...args);\n }\n\n // Verbose log\n verbose(message: string, ...args: any[]): void {\n this.logger.verbose(message, ...args);\n }\n\n // Silly log\n silly(message: string, ...args: any[]): void {\n this.logger.silly(message, ...args);\n }\n\n // Get the logger instance (useful if you need more custom configurations)\n getLogger(): typeof LoggerService {\n return this.logger;\n }\n}\n"],"names":[],"mappings":"uDAwBA;;;AAGG;MACU,cAAc,CAAA;AACjB,IAAA,MAAM;AACN,IAAA,KAAK;AAEb;;;;AAIG;AACH,IAAA,WAAA,CAAY,UAAyB,EAAE,EAAA;QACrC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;AAElD,QAAA,MAAM,EACJ,OAAO,GAAG,MAAM,EAChB,OAAO,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;QAC1B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,UAAU,EACV,QAAQ,GACT,GAAG,OAAO;;AAGX,QAAA,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACtD,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;AAC1B,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,MAAM;QACrD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,GAAG,QAAQ,KAAK,UAAU,GAAG,eAAe,GAAG,KAAK,CAAC;;;AAIrF,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,MAAM;AACtD,QAAA,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,KAAK;AAExD,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,IAAI,gBAAgB;AACjE,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,GAAG,YAAY,IAAI,mBAAmB;;;QAI1E,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,iDAAiD;;;QAItF,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO;;;AAI7C,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ;AAClC,YAAA,QAAQ,KAAK,IAAI,CAAC,KAAK,GAAG,CAAA,EAAG,OAAO,CAAA,QAAA,CAAU,GAAG,GAAG,OAAO,CAAA,IAAA,CAAM,CAAC;IACtE;;AAGA,IAAA,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACpC;;AAGA,IAAA,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACrC;;AAGA,IAAA,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACrC;;AAGA,IAAA,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACpC;;AAGA,IAAA,OAAO,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QACrC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACvC;;AAGA,IAAA,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACrC;;IAGA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AACD"}
|
|
@@ -13,10 +13,12 @@ class ElectronLogger {
|
|
|
13
13
|
constructor(options = {}) {
|
|
14
14
|
this.isDev = process.env.NODE_ENV !== 'production';
|
|
15
15
|
const { appName = 'main', maxSize = 10 * 1024 * 1024, // Default 10MB
|
|
16
|
-
fileName, fileLevel, consoleLevel, } = options;
|
|
16
|
+
fileName, fileLevel, consoleLevel, ipcEnabled, ipcLevel, } = options;
|
|
17
17
|
// Create a logger instance for either 'main' or 'renderer'
|
|
18
18
|
this.logger = LoggerService.create({ logId: appName });
|
|
19
19
|
this.logger.scope(appName);
|
|
20
|
+
const defaultIpcLevel = this.isDev ? 'silly' : 'info';
|
|
21
|
+
this.logger.transports.ipc.level = ipcLevel ?? (ipcEnabled ? defaultIpcLevel : false);
|
|
20
22
|
// Set log levels with smart defaults based on environment
|
|
21
23
|
// 根据环境设置日志级别,使用智能默认值
|
|
22
24
|
const defaultFileLevel = this.isDev ? 'debug' : 'info';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronLogger.mjs","sources":["../../../src/infrastructure/logger/ElectronLogger.ts"],"sourcesContent":["import LoggerService from 'electron-log';\nimport { ILogger } from './logger.type';\n\n/**\n * Logger Configuration Options\n * 日志配置选项\n */\nexport interface LoggerOptions {\n /** Application name for log identification / 应用名称用于日志标识 */\n appName?: string;\n /** Maximum log file size in bytes / 最大日志文件大小(字节) */\n maxSize?: number;\n /** Custom log file name / 自定义日志文件名 */\n fileName?: string;\n /** File log level / 文件日志级别 */\n fileLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n /** Console log level / 控制台日志级别 */\n consoleLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n}\n\n/**\n * Default logger implementation using electron-log\n * 使用 electron-log 的默认日志实现\n */\nexport class ElectronLogger implements ILogger {\n private logger: typeof LoggerService;\n private isDev: boolean;\n\n /**\n * Constructor for Logger\n * 日志记录器构造函数\n * @param options - Logger configuration options\n */\n constructor(options: LoggerOptions = {}) {\n this.isDev = process.env.NODE_ENV !== 'production';\n\n const {\n appName = 'main',\n maxSize = 10 * 1024 * 1024, // Default 10MB\n fileName,\n fileLevel,\n consoleLevel,\n } = options;\n\n // Create a logger instance for either 'main' or 'renderer'\n this.logger = LoggerService.create({ logId: appName });\n this.logger.scope(appName);\n\n // Set log levels with smart defaults based on environment\n // 根据环境设置日志级别,使用智能默认值\n const defaultFileLevel = this.isDev ? 'debug' : 'info';\n const defaultConsoleLevel = this.isDev ? 'debug' : false;\n\n this.logger.transports.file.level = fileLevel ?? defaultFileLevel;\n this.logger.transports.console.level = consoleLevel ?? defaultConsoleLevel;\n\n // Optimize log format with date and log level\n // 优化日志格式,增加日期和日志级别\n this.logger.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}';\n\n // Set maximum file size (configurable)\n // 设置最大文件大小(可配置)\n this.logger.transports.file.maxSize = maxSize;\n\n // Set log file name (configurable or default based on environment)\n // 设置日志文件名(可配置或根据环境使用默认值)\n this.logger.transports.file.fileName =\n fileName ?? (this.isDev ? `${appName}_dev.log` : `${appName}.log`);\n }\n\n // Info log\n info(message: string, ...args: any[]): void {\n this.logger.info(message, ...args);\n }\n\n // Debug log\n debug(message: string, ...args: any[]): void {\n this.logger.debug(message, ...args);\n }\n\n // Error log\n error(message: string, ...args: any[]): void {\n this.logger.error(message, ...args);\n }\n\n // Warn log\n warn(message: string, ...args: any[]): void {\n this.logger.warn(message, ...args);\n }\n\n // Verbose log\n verbose(message: string, ...args: any[]): void {\n this.logger.verbose(message, ...args);\n }\n\n // Silly log\n silly(message: string, ...args: any[]): void {\n this.logger.silly(message, ...args);\n }\n\n // Get the logger instance (useful if you need more custom configurations)\n getLogger(): typeof LoggerService {\n return this.logger;\n }\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ElectronLogger.mjs","sources":["../../../src/infrastructure/logger/ElectronLogger.ts"],"sourcesContent":["import LoggerService from 'electron-log';\nimport { ILogger } from './logger.type';\n\n/**\n * Logger Configuration Options\n * 日志配置选项\n */\nexport interface LoggerOptions {\n /** Application name for log identification / 应用名称用于日志标识 */\n appName?: string;\n /** Maximum log file size in bytes / 最大日志文件大小(字节) */\n maxSize?: number;\n /** Custom log file name / 自定义日志文件名 */\n fileName?: string;\n /** File log level / 文件日志级别 */\n fileLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n /** Console log level / 控制台日志级别 */\n consoleLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n /** Enable IPC transport / 启用 IPC 传输 */\n ipcEnabled?: boolean;\n /** IPC transport level / IPC 传输级别 */\n ipcLevel?: 'debug' | 'info' | 'warn' | 'error' | 'verbose' | 'silly' | false;\n}\n\n/**\n * Default logger implementation using electron-log\n * 使用 electron-log 的默认日志实现\n */\nexport class ElectronLogger implements ILogger {\n private logger: typeof LoggerService;\n private isDev: boolean;\n\n /**\n * Constructor for Logger\n * 日志记录器构造函数\n * @param options - Logger configuration options\n */\n constructor(options: LoggerOptions = {}) {\n this.isDev = process.env.NODE_ENV !== 'production';\n\n const {\n appName = 'main',\n maxSize = 10 * 1024 * 1024, // Default 10MB\n fileName,\n fileLevel,\n consoleLevel,\n ipcEnabled,\n ipcLevel,\n } = options;\n\n // Create a logger instance for either 'main' or 'renderer'\n this.logger = LoggerService.create({ logId: appName });\n this.logger.scope(appName);\n const defaultIpcLevel = this.isDev ? 'silly' : 'info';\n this.logger.transports.ipc.level = ipcLevel ?? (ipcEnabled ? defaultIpcLevel : false);\n\n // Set log levels with smart defaults based on environment\n // 根据环境设置日志级别,使用智能默认值\n const defaultFileLevel = this.isDev ? 'debug' : 'info';\n const defaultConsoleLevel = this.isDev ? 'debug' : false;\n\n this.logger.transports.file.level = fileLevel ?? defaultFileLevel;\n this.logger.transports.console.level = consoleLevel ?? defaultConsoleLevel;\n\n // Optimize log format with date and log level\n // 优化日志格式,增加日期和日志级别\n this.logger.transports.file.format = '[{y}-{m}-{d} {h}:{i}:{s}.{ms}] [{level}] {text}';\n\n // Set maximum file size (configurable)\n // 设置最大文件大小(可配置)\n this.logger.transports.file.maxSize = maxSize;\n\n // Set log file name (configurable or default based on environment)\n // 设置日志文件名(可配置或根据环境使用默认值)\n this.logger.transports.file.fileName =\n fileName ?? (this.isDev ? `${appName}_dev.log` : `${appName}.log`);\n }\n\n // Info log\n info(message: string, ...args: any[]): void {\n this.logger.info(message, ...args);\n }\n\n // Debug log\n debug(message: string, ...args: any[]): void {\n this.logger.debug(message, ...args);\n }\n\n // Error log\n error(message: string, ...args: any[]): void {\n this.logger.error(message, ...args);\n }\n\n // Warn log\n warn(message: string, ...args: any[]): void {\n this.logger.warn(message, ...args);\n }\n\n // Verbose log\n verbose(message: string, ...args: any[]): void {\n this.logger.verbose(message, ...args);\n }\n\n // Silly log\n silly(message: string, ...args: any[]): void {\n this.logger.silly(message, ...args);\n }\n\n // Get the logger instance (useful if you need more custom configurations)\n getLogger(): typeof LoggerService {\n return this.logger;\n }\n}\n"],"names":[],"mappings":"wCAwBA;;;AAGG;MACU,cAAc,CAAA;AACjB,IAAA,MAAM;AACN,IAAA,KAAK;AAEb;;;;AAIG;AACH,IAAA,WAAA,CAAY,UAAyB,EAAE,EAAA;QACrC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;AAElD,QAAA,MAAM,EACJ,OAAO,GAAG,MAAM,EAChB,OAAO,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;QAC1B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,UAAU,EACV,QAAQ,GACT,GAAG,OAAO;;AAGX,QAAA,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACtD,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;AAC1B,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,MAAM;QACrD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,GAAG,QAAQ,KAAK,UAAU,GAAG,eAAe,GAAG,KAAK,CAAC;;;AAIrF,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,MAAM;AACtD,QAAA,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,KAAK;AAExD,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,IAAI,gBAAgB;AACjE,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,GAAG,YAAY,IAAI,mBAAmB;;;QAI1E,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,iDAAiD;;;QAItF,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO;;;AAI7C,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ;AAClC,YAAA,QAAQ,KAAK,IAAI,CAAC,KAAK,GAAG,CAAA,EAAG,OAAO,CAAA,QAAA,CAAU,GAAG,GAAG,OAAO,CAAA,IAAA,CAAM,CAAC;IACtE;;AAGA,IAAA,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACpC;;AAGA,IAAA,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACrC;;AAGA,IAAA,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACrC;;AAGA,IAAA,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACpC;;AAGA,IAAA,OAAO,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QACrC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACvC;;AAGA,IAAA,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW,EAAA;QACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;IACrC;;IAGA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AACD"}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export { ElectronLogger as Logger, type LoggerOptions } from './ElectronLogger';
|
|
2
2
|
export type { ILogger } from './logger.type';
|
|
3
|
+
import type { ILogger } from './logger.type';
|
|
4
|
+
import type { LoggerOptions } from './ElectronLogger';
|
|
5
|
+
export declare function getSharedLogger(options?: LoggerOptions): ILogger;
|
|
6
|
+
export declare function setSharedLogger(logger: ILogger): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';var ElectronLogger=require('./ElectronLogger.js');let sharedLogger = null;
|
|
2
|
+
function getSharedLogger(options) {
|
|
3
|
+
if (!sharedLogger) {
|
|
4
|
+
sharedLogger = new ElectronLogger.ElectronLogger(options);
|
|
5
|
+
}
|
|
6
|
+
return sharedLogger;
|
|
7
|
+
}
|
|
8
|
+
function setSharedLogger(logger) {
|
|
9
|
+
sharedLogger = logger;
|
|
10
|
+
}exports.Logger=ElectronLogger.ElectronLogger;exports.getSharedLogger=getSharedLogger;exports.setSharedLogger=setSharedLogger;//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/infrastructure/logger/index.ts"],"sourcesContent":["export { ElectronLogger as Logger, type LoggerOptions } from './ElectronLogger';\nexport type { ILogger } from './logger.type';\nimport { ElectronLogger } from './ElectronLogger';\nimport type { ILogger } from './logger.type';\nimport type { LoggerOptions } from './ElectronLogger';\n\nlet sharedLogger: ILogger | null = null;\n\nexport function getSharedLogger(options?: LoggerOptions): ILogger {\n if (!sharedLogger) {\n sharedLogger = new ElectronLogger(options);\n }\n return sharedLogger;\n}\n\nexport function setSharedLogger(logger: ILogger): void {\n sharedLogger = logger;\n}\n"],"names":["ElectronLogger"],"mappings":"+DAMA,IAAI,YAAY,GAAmB,IAAI;AAEjC,SAAU,eAAe,CAAC,OAAuB,EAAA;IACrD,IAAI,CAAC,YAAY,EAAE;AACjB,QAAA,YAAY,GAAG,IAAIA,6BAAc,CAAC,OAAO,CAAC;IAC5C;AACA,IAAA,OAAO,YAAY;AACrB;AAEM,SAAU,eAAe,CAAC,MAAe,EAAA;IAC7C,YAAY,GAAG,MAAM;AACvB"}
|