electron-infra-kit 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +302 -0
- package/README.zh-CN.md +308 -0
- package/dist/core/error/WindowError.d.ts +56 -0
- package/dist/core/error/WindowError.js +71 -0
- package/dist/core/error/WindowError.js.map +1 -0
- package/dist/core/error/WindowError.mjs +71 -0
- package/dist/core/error/WindowError.mjs.map +1 -0
- package/dist/core/ipc/IpcHandler.d.ts +48 -0
- package/dist/core/ipc/IpcHandler.js +59 -0
- package/dist/core/ipc/IpcHandler.js.map +1 -0
- package/dist/core/ipc/IpcHandler.mjs +59 -0
- package/dist/core/ipc/IpcHandler.mjs.map +1 -0
- package/dist/core/ipc/IpcRouter.d.ts +70 -0
- package/dist/core/ipc/IpcRouter.js +143 -0
- package/dist/core/ipc/IpcRouter.js.map +1 -0
- package/dist/core/ipc/IpcRouter.mjs +143 -0
- package/dist/core/ipc/IpcRouter.mjs.map +1 -0
- package/dist/core/ipc/index.d.ts +3 -0
- package/dist/core/ipc/index.js +1 -0
- package/dist/core/ipc/index.js.map +1 -0
- package/dist/core/ipc/index.mjs +1 -0
- package/dist/core/ipc/index.mjs.map +1 -0
- package/dist/core/ipc/ipc-router.type.d.ts +73 -0
- package/dist/core/ipc/transport/index.d.ts +65 -0
- package/dist/core/ipc/transport/index.js +229 -0
- package/dist/core/ipc/transport/index.js.map +1 -0
- package/dist/core/ipc/transport/index.mjs +229 -0
- package/dist/core/ipc/transport/index.mjs.map +1 -0
- package/dist/core/ipc/transport/ipc.type.d.ts +36 -0
- package/dist/core/lifecycle/LifecycleManager.d.ts +66 -0
- package/dist/core/lifecycle/LifecycleManager.js +140 -0
- package/dist/core/lifecycle/LifecycleManager.js.map +1 -0
- package/dist/core/lifecycle/LifecycleManager.mjs +140 -0
- package/dist/core/lifecycle/LifecycleManager.mjs.map +1 -0
- package/dist/core/message-bus/MessageBus.d.ts +282 -0
- package/dist/core/message-bus/MessageBus.js +677 -0
- package/dist/core/message-bus/MessageBus.js.map +1 -0
- package/dist/core/message-bus/MessageBus.mjs +677 -0
- package/dist/core/message-bus/MessageBus.mjs.map +1 -0
- package/dist/core/message-bus/MessageBusClient.d.ts +100 -0
- package/dist/core/message-bus/MessageBusClient.js +280 -0
- package/dist/core/message-bus/MessageBusClient.js.map +1 -0
- package/dist/core/message-bus/MessageBusClient.mjs +280 -0
- package/dist/core/message-bus/MessageBusClient.mjs.map +1 -0
- package/dist/core/message-bus/core/DataStoreManager.d.ts +51 -0
- package/dist/core/message-bus/core/DataStoreManager.js +94 -0
- package/dist/core/message-bus/core/DataStoreManager.js.map +1 -0
- package/dist/core/message-bus/core/DataStoreManager.mjs +94 -0
- package/dist/core/message-bus/core/DataStoreManager.mjs.map +1 -0
- package/dist/core/message-bus/core/ManagedPort.d.ts +26 -0
- package/dist/core/message-bus/core/ManagedPort.js +55 -0
- package/dist/core/message-bus/core/ManagedPort.js.map +1 -0
- package/dist/core/message-bus/core/ManagedPort.mjs +55 -0
- package/dist/core/message-bus/core/ManagedPort.mjs.map +1 -0
- package/dist/core/message-bus/core/PortManager.d.ts +47 -0
- package/dist/core/message-bus/core/PortManager.js +114 -0
- package/dist/core/message-bus/core/PortManager.js.map +1 -0
- package/dist/core/message-bus/core/PortManager.mjs +114 -0
- package/dist/core/message-bus/core/PortManager.mjs.map +1 -0
- package/dist/core/message-bus/core/SubscriptionManager.d.ts +36 -0
- package/dist/core/message-bus/core/SubscriptionManager.js +78 -0
- package/dist/core/message-bus/core/SubscriptionManager.js.map +1 -0
- package/dist/core/message-bus/core/SubscriptionManager.mjs +78 -0
- package/dist/core/message-bus/core/SubscriptionManager.mjs.map +1 -0
- package/dist/core/message-bus/core/TransactionManager.d.ts +54 -0
- package/dist/core/message-bus/core/TransactionManager.js +95 -0
- package/dist/core/message-bus/core/TransactionManager.js.map +1 -0
- package/dist/core/message-bus/core/TransactionManager.mjs +95 -0
- package/dist/core/message-bus/core/TransactionManager.mjs.map +1 -0
- package/dist/core/message-bus/core/index.d.ts +5 -0
- package/dist/core/message-bus/index.d.ts +4 -0
- package/dist/core/message-bus/index.js +1 -0
- package/dist/core/message-bus/index.js.map +1 -0
- package/dist/core/message-bus/index.mjs +1 -0
- package/dist/core/message-bus/index.mjs.map +1 -0
- package/dist/core/message-bus/message-bus.type.d.ts +143 -0
- package/dist/core/message-bus/message-bus.type.js +26 -0
- package/dist/core/message-bus/message-bus.type.js.map +1 -0
- package/dist/core/message-bus/message-bus.type.mjs +26 -0
- package/dist/core/message-bus/message-bus.type.mjs.map +1 -0
- package/dist/core/message-bus/preload.d.ts +16 -0
- package/dist/core/message-bus/preload.js +27 -0
- package/dist/core/message-bus/preload.js.map +1 -0
- package/dist/core/message-bus/preload.mjs +27 -0
- package/dist/core/message-bus/preload.mjs.map +1 -0
- package/dist/core/message-bus/transport/ITransport.d.ts +40 -0
- package/dist/core/message-bus/transport/IpcTransport.d.ts +18 -0
- package/dist/core/message-bus/transport/IpcTransport.js +60 -0
- package/dist/core/message-bus/transport/IpcTransport.js.map +1 -0
- package/dist/core/message-bus/transport/IpcTransport.mjs +60 -0
- package/dist/core/message-bus/transport/IpcTransport.mjs.map +1 -0
- package/dist/core/message-bus/transport/MessagePortTransport.d.ts +15 -0
- package/dist/core/message-bus/transport/MessagePortTransport.js +35 -0
- package/dist/core/message-bus/transport/MessagePortTransport.js.map +1 -0
- package/dist/core/message-bus/transport/MessagePortTransport.mjs +35 -0
- package/dist/core/message-bus/transport/MessagePortTransport.mjs.map +1 -0
- package/dist/core/message-bus/transport/index.d.ts +3 -0
- package/dist/core/window/IpcSetup.d.ts +50 -0
- package/dist/core/window/IpcSetup.js +96 -0
- package/dist/core/window/IpcSetup.js.map +1 -0
- package/dist/core/window/IpcSetup.mjs +96 -0
- package/dist/core/window/IpcSetup.mjs.map +1 -0
- package/dist/core/window/WindowCreator.d.ts +66 -0
- package/dist/core/window/WindowCreator.js +168 -0
- package/dist/core/window/WindowCreator.js.map +1 -0
- package/dist/core/window/WindowCreator.mjs +168 -0
- package/dist/core/window/WindowCreator.mjs.map +1 -0
- package/dist/core/window/WindowManager.d.ts +214 -0
- package/dist/core/window/WindowManager.js +583 -0
- package/dist/core/window/WindowManager.js.map +1 -0
- package/dist/core/window/WindowManager.mjs +583 -0
- package/dist/core/window/WindowManager.mjs.map +1 -0
- package/dist/core/window/WindowStore.d.ts +136 -0
- package/dist/core/window/WindowStore.js +436 -0
- package/dist/core/window/WindowStore.js.map +1 -0
- package/dist/core/window/WindowStore.mjs +436 -0
- package/dist/core/window/WindowStore.mjs.map +1 -0
- package/dist/core/window/constants.d.ts +17 -0
- package/dist/core/window/constants.js +15 -0
- package/dist/core/window/constants.js.map +1 -0
- package/dist/core/window/constants.mjs +15 -0
- package/dist/core/window/constants.mjs.map +1 -0
- package/dist/core/window/core/MetricsManager.d.ts +14 -0
- package/dist/core/window/core/MetricsManager.js +27 -0
- package/dist/core/window/core/MetricsManager.js.map +1 -0
- package/dist/core/window/core/MetricsManager.mjs +27 -0
- package/dist/core/window/core/MetricsManager.mjs.map +1 -0
- package/dist/core/window/core/PluginExecutor.d.ts +22 -0
- package/dist/core/window/core/PluginExecutor.js +110 -0
- package/dist/core/window/core/PluginExecutor.js.map +1 -0
- package/dist/core/window/core/PluginExecutor.mjs +110 -0
- package/dist/core/window/core/PluginExecutor.mjs.map +1 -0
- package/dist/core/window/core/WindowContextManager.d.ts +26 -0
- package/dist/core/window/core/WindowContextManager.js +59 -0
- package/dist/core/window/core/WindowContextManager.js.map +1 -0
- package/dist/core/window/core/WindowContextManager.mjs +59 -0
- package/dist/core/window/core/WindowContextManager.mjs.map +1 -0
- package/dist/core/window/core/WindowLifecycle.d.ts +15 -0
- package/dist/core/window/core/WindowLifecycle.js +150 -0
- package/dist/core/window/core/WindowLifecycle.js.map +1 -0
- package/dist/core/window/core/WindowLifecycle.mjs +150 -0
- package/dist/core/window/core/WindowLifecycle.mjs.map +1 -0
- package/dist/core/window/core/WindowOperator.d.ts +90 -0
- package/dist/core/window/core/WindowOperator.js +154 -0
- package/dist/core/window/core/WindowOperator.js.map +1 -0
- package/dist/core/window/core/WindowOperator.mjs +154 -0
- package/dist/core/window/core/WindowOperator.mjs.map +1 -0
- package/dist/core/window/core/WindowRegistry.d.ts +168 -0
- package/dist/core/window/core/WindowRegistry.js +331 -0
- package/dist/core/window/core/WindowRegistry.js.map +1 -0
- package/dist/core/window/core/WindowRegistry.mjs +331 -0
- package/dist/core/window/core/WindowRegistry.mjs.map +1 -0
- package/dist/core/window/core/WindowStateManager.d.ts +40 -0
- package/dist/core/window/core/WindowStateManager.js +110 -0
- package/dist/core/window/core/WindowStateManager.js.map +1 -0
- package/dist/core/window/core/WindowStateManager.mjs +110 -0
- package/dist/core/window/core/WindowStateManager.mjs.map +1 -0
- package/dist/core/window/index.d.ts +7 -0
- package/dist/core/window/index.js +1 -0
- package/dist/core/window/index.js.map +1 -0
- package/dist/core/window/index.mjs +1 -0
- package/dist/core/window/index.mjs.map +1 -0
- package/dist/core/window/window-manager.schema.d.ts +50 -0
- package/dist/core/window/window-manager.schema.js +87 -0
- package/dist/core/window/window-manager.schema.js.map +1 -0
- package/dist/core/window/window-manager.schema.mjs +87 -0
- package/dist/core/window/window-manager.schema.mjs.map +1 -0
- package/dist/core/window/window-manager.type.d.ts +365 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +33 -0
- package/dist/index.mjs.map +1 -0
- package/dist/index.umd.js +1 -0
- package/dist/infrastructure/config/ConfigManager.d.ts +133 -0
- package/dist/infrastructure/config/ConfigManager.js +218 -0
- package/dist/infrastructure/config/ConfigManager.js.map +1 -0
- package/dist/infrastructure/config/ConfigManager.mjs +218 -0
- package/dist/infrastructure/config/ConfigManager.mjs.map +1 -0
- package/dist/infrastructure/config/index.d.ts +1 -0
- package/dist/infrastructure/debug/EnhancedDebugHelper.d.ts +106 -0
- package/dist/infrastructure/debug/EnhancedDebugHelper.js +218 -0
- package/dist/infrastructure/debug/EnhancedDebugHelper.js.map +1 -0
- package/dist/infrastructure/debug/EnhancedDebugHelper.mjs +218 -0
- package/dist/infrastructure/debug/EnhancedDebugHelper.mjs.map +1 -0
- package/dist/infrastructure/debug/PerformanceMonitor.d.ts +45 -0
- package/dist/infrastructure/debug/PerformanceMonitor.js +67 -0
- package/dist/infrastructure/debug/PerformanceMonitor.js.map +1 -0
- package/dist/infrastructure/debug/PerformanceMonitor.mjs +67 -0
- package/dist/infrastructure/debug/PerformanceMonitor.mjs.map +1 -0
- package/dist/infrastructure/debug/index.d.ts +22 -0
- package/dist/infrastructure/debug/index.js +47 -0
- package/dist/infrastructure/debug/index.js.map +1 -0
- package/dist/infrastructure/debug/index.mjs +47 -0
- package/dist/infrastructure/debug/index.mjs.map +1 -0
- package/dist/infrastructure/errors/ErrorCodes.d.ts +74 -0
- package/dist/infrastructure/errors/ErrorCodes.js +78 -0
- package/dist/infrastructure/errors/ErrorCodes.js.map +1 -0
- package/dist/infrastructure/errors/ErrorCodes.mjs +78 -0
- package/dist/infrastructure/errors/ErrorCodes.mjs.map +1 -0
- package/dist/infrastructure/errors/StandardError.d.ts +61 -0
- package/dist/infrastructure/errors/StandardError.js +84 -0
- package/dist/infrastructure/errors/StandardError.js.map +1 -0
- package/dist/infrastructure/errors/StandardError.mjs +84 -0
- package/dist/infrastructure/errors/StandardError.mjs.map +1 -0
- package/dist/infrastructure/errors/index.d.ts +13 -0
- package/dist/infrastructure/errors/index.js +24 -0
- package/dist/infrastructure/errors/index.js.map +1 -0
- package/dist/infrastructure/errors/index.mjs +24 -0
- package/dist/infrastructure/errors/index.mjs.map +1 -0
- package/dist/infrastructure/logger/ElectronLogger.d.ts +39 -0
- package/dist/infrastructure/logger/ElectronLogger.js +65 -0
- package/dist/infrastructure/logger/ElectronLogger.js.map +1 -0
- package/dist/infrastructure/logger/ElectronLogger.mjs +65 -0
- package/dist/infrastructure/logger/ElectronLogger.mjs.map +1 -0
- package/dist/infrastructure/logger/index.d.ts +2 -0
- package/dist/infrastructure/logger/logger.type.d.ts +8 -0
- package/dist/internal/types/BrandedTypes.d.ts +64 -0
- package/dist/internal/types/BrandedTypes.js +54 -0
- package/dist/internal/types/BrandedTypes.js.map +1 -0
- package/dist/internal/types/BrandedTypes.mjs +54 -0
- package/dist/internal/types/BrandedTypes.mjs.map +1 -0
- package/dist/internal/types/PerformanceOptions.d.ts +87 -0
- package/dist/internal/types/branded.d.ts +42 -0
- package/dist/internal/utils/MessageDispatcher.d.ts +67 -0
- package/dist/internal/utils/MessageDispatcher.js +96 -0
- package/dist/internal/utils/MessageDispatcher.js.map +1 -0
- package/dist/internal/utils/MessageDispatcher.mjs +96 -0
- package/dist/internal/utils/MessageDispatcher.mjs.map +1 -0
- package/dist/internal/utils/RateLimiter.d.ts +41 -0
- package/dist/internal/utils/RateLimiter.js +83 -0
- package/dist/internal/utils/RateLimiter.js.map +1 -0
- package/dist/internal/utils/RateLimiter.mjs +83 -0
- package/dist/internal/utils/RateLimiter.mjs.map +1 -0
- package/dist/internal/utils/StateKeeper.d.ts +125 -0
- package/dist/internal/utils/StateKeeper.js +334 -0
- package/dist/internal/utils/StateKeeper.js.map +1 -0
- package/dist/internal/utils/StateKeeper.mjs +334 -0
- package/dist/internal/utils/StateKeeper.mjs.map +1 -0
- package/dist/internal/utils/branded-helpers.d.ts +33 -0
- package/dist/internal/utils/index.d.ts +5 -0
- package/dist/preload/index.d.ts +45 -0
- package/dist/preload/index.js +91 -0
- package/dist/preload/index.js.map +1 -0
- package/dist/preload/index.mjs +91 -0
- package/dist/preload/index.mjs.map +1 -0
- package/dist/preload/preload.type.d.ts +15 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +1 -0
- package/dist/types.mjs.map +1 -0
- package/package.json +143 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { BrowserWindow } from 'electron';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { ILogger } from '@/infrastructure/logger';
|
|
4
|
+
import { WindowStoreOptions } from './window-manager.type';
|
|
5
|
+
/**
|
|
6
|
+
* WindowStore - Window state management class (Refactored & Optimized)
|
|
7
|
+
* WindowStore - 窗口状态管理类(已重构与优化)
|
|
8
|
+
*
|
|
9
|
+
* Facade that coordinates:
|
|
10
|
+
* - WindowRegistry (Storage & Cleanup)
|
|
11
|
+
* - WindowOperator (Actions)
|
|
12
|
+
* - WindowContextManager (Persistence)
|
|
13
|
+
* - WindowStateManager (State Persistence)
|
|
14
|
+
*
|
|
15
|
+
* @class
|
|
16
|
+
*/
|
|
17
|
+
export default class WindowStore extends EventEmitter {
|
|
18
|
+
private readonly MAX_WINDOWS;
|
|
19
|
+
protected enablePersistence: boolean;
|
|
20
|
+
protected logger: ILogger;
|
|
21
|
+
get persistenceEnabled(): boolean;
|
|
22
|
+
private registry;
|
|
23
|
+
private operator;
|
|
24
|
+
private contextManager;
|
|
25
|
+
private stateManager;
|
|
26
|
+
private focusHistory;
|
|
27
|
+
/**
|
|
28
|
+
* Creates an instance of WindowStore
|
|
29
|
+
* 创建 WindowStore 实例
|
|
30
|
+
*/
|
|
31
|
+
constructor(options?: WindowStoreOptions);
|
|
32
|
+
/**
|
|
33
|
+
* Push window ID to focus history
|
|
34
|
+
* 将窗口 ID 推入焦点历史
|
|
35
|
+
*/
|
|
36
|
+
pushFocus(windowId: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Remove window ID from focus history
|
|
39
|
+
* 从焦点历史中移除窗口 ID
|
|
40
|
+
*/
|
|
41
|
+
removeFocus(windowId: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Get the previously focused window ID (excluding current top if needed)
|
|
44
|
+
* 获取上一个聚焦的窗口 ID
|
|
45
|
+
*/
|
|
46
|
+
getPreviousFocusedWindow(): string | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Pop the top window from history
|
|
49
|
+
* 弹出栈顶窗口
|
|
50
|
+
*/
|
|
51
|
+
popFocus(): string | undefined;
|
|
52
|
+
joinGroup(windowId: string, group: string): void;
|
|
53
|
+
leaveGroup(windowId: string, group: string): void;
|
|
54
|
+
getGroup(group: string): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Close all windows in a group
|
|
57
|
+
* 关闭组内所有窗口
|
|
58
|
+
*/
|
|
59
|
+
closeGroup(group: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Hide all windows in a group
|
|
62
|
+
* 隐藏组内所有窗口
|
|
63
|
+
*/
|
|
64
|
+
hideGroup(group: string): void;
|
|
65
|
+
/**
|
|
66
|
+
* Show all windows in a group
|
|
67
|
+
* 显示组内所有窗口
|
|
68
|
+
*/
|
|
69
|
+
showGroup(group: string): void;
|
|
70
|
+
/**
|
|
71
|
+
* Focus all windows in a group
|
|
72
|
+
* 聚焦组内所有窗口
|
|
73
|
+
*/
|
|
74
|
+
focusGroup(group: string): void;
|
|
75
|
+
show(window: BrowserWindow, _windowId?: string): void;
|
|
76
|
+
hide(windowId: string): void;
|
|
77
|
+
isDestroyed(windowId: string): boolean;
|
|
78
|
+
isVisible(windowId: string): boolean;
|
|
79
|
+
isMinimized(windowId: string): boolean;
|
|
80
|
+
isMaximized(windowId: string): boolean;
|
|
81
|
+
fullScreenState(windowId: string): boolean;
|
|
82
|
+
minimize(windowId?: string): void;
|
|
83
|
+
restore(windowId: string): void;
|
|
84
|
+
maximize(windowId: string): void;
|
|
85
|
+
unmaximize(windowId: string): void;
|
|
86
|
+
fullScreen(windowId: string): void;
|
|
87
|
+
focus(windowId: string): void;
|
|
88
|
+
setMovable(window: BrowserWindow): void;
|
|
89
|
+
winClose(windowId: string): void;
|
|
90
|
+
openDevTools(windowId: string): void;
|
|
91
|
+
isDevToolsOpened(windowId: string): boolean;
|
|
92
|
+
closeDevTools(windowId: string): void;
|
|
93
|
+
quit(): void;
|
|
94
|
+
getWindowSize(): {
|
|
95
|
+
width: number;
|
|
96
|
+
height: number;
|
|
97
|
+
};
|
|
98
|
+
send(windowId: string, name: string, data?: unknown): void;
|
|
99
|
+
setSkipTaskbar(windowId: string, bool: boolean): void;
|
|
100
|
+
get mainWindow(): BrowserWindow | null;
|
|
101
|
+
protected set mainWindow(window: BrowserWindow | null);
|
|
102
|
+
getWindowCount(): number;
|
|
103
|
+
getAllWindowKeys(): string[];
|
|
104
|
+
getAllWindows(): BrowserWindow[];
|
|
105
|
+
getWindowNames(): Map<string, string>;
|
|
106
|
+
getNameByWindowId(windowId: string): string | undefined;
|
|
107
|
+
getWindowByNameId(name: string): string | undefined;
|
|
108
|
+
getWindowByName(name: string): BrowserWindow | undefined;
|
|
109
|
+
hasByName(proposedName: string): boolean;
|
|
110
|
+
deleteByName(proposedName: string): boolean;
|
|
111
|
+
getWindowById(windowId: string): BrowserWindow | undefined;
|
|
112
|
+
hasById(windowId: string): boolean;
|
|
113
|
+
deleteById(windowId: string): boolean;
|
|
114
|
+
getWindowId(window: BrowserWindow): string | undefined;
|
|
115
|
+
updateWindowName(windowId: string, newName: string): void;
|
|
116
|
+
getTargetWindow(windowId?: string): BrowserWindow | undefined;
|
|
117
|
+
getValidWindow(windowId?: string): BrowserWindow | undefined;
|
|
118
|
+
getCurrentWindow(): BrowserWindow | undefined;
|
|
119
|
+
createWindow(window: BrowserWindow, config?: {
|
|
120
|
+
name?: string;
|
|
121
|
+
windowId?: string;
|
|
122
|
+
enablePersistence?: boolean;
|
|
123
|
+
}): string;
|
|
124
|
+
removeWindow(windowId: string): void;
|
|
125
|
+
private validateWindowName;
|
|
126
|
+
private registerWindow;
|
|
127
|
+
manageState(name: string, window: BrowserWindow, getGroups?: () => string[]): void;
|
|
128
|
+
getWindowGroups(windowId: string): string[];
|
|
129
|
+
getWindowState(name: string, defaultWidth?: number, defaultHeight?: number): import("../../internal/utils/StateKeeper").WindowState;
|
|
130
|
+
saveWindowContext(windowId: string, context: any): Promise<void>;
|
|
131
|
+
loadWindowContext(windowId: string): Promise<any>;
|
|
132
|
+
clearWindowContext(windowId: string): Promise<void>;
|
|
133
|
+
startCleanupProtection(intervalMs?: number): void;
|
|
134
|
+
stopCleanupProtection(): void;
|
|
135
|
+
dispose(): Promise<void>;
|
|
136
|
+
}
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
'use strict';var electron=require('electron'),uuid=require('uuid'),events=require('events'),WindowRegistry=require('./core/WindowRegistry.js'),WindowOperator=require('./core/WindowOperator.js'),WindowContextManager=require('./core/WindowContextManager.js'),WindowStateManager=require('./core/WindowStateManager.js'),constants=require('./constants.js'),ElectronLogger=require('../../infrastructure/logger/ElectronLogger.js');/**
|
|
2
|
+
* WindowStore - Window state management class (Refactored & Optimized)
|
|
3
|
+
* WindowStore - 窗口状态管理类(已重构与优化)
|
|
4
|
+
*
|
|
5
|
+
* Facade that coordinates:
|
|
6
|
+
* - WindowRegistry (Storage & Cleanup)
|
|
7
|
+
* - WindowOperator (Actions)
|
|
8
|
+
* - WindowContextManager (Persistence)
|
|
9
|
+
* - WindowStateManager (State Persistence)
|
|
10
|
+
*
|
|
11
|
+
* @class
|
|
12
|
+
*/
|
|
13
|
+
class WindowStore extends events.EventEmitter {
|
|
14
|
+
MAX_WINDOWS;
|
|
15
|
+
enablePersistence = false;
|
|
16
|
+
logger;
|
|
17
|
+
get persistenceEnabled() {
|
|
18
|
+
return this.enablePersistence;
|
|
19
|
+
}
|
|
20
|
+
// Core components
|
|
21
|
+
registry;
|
|
22
|
+
operator;
|
|
23
|
+
contextManager;
|
|
24
|
+
stateManager;
|
|
25
|
+
// Focus History Stack
|
|
26
|
+
// 焦点历史栈
|
|
27
|
+
focusHistory = [];
|
|
28
|
+
/**
|
|
29
|
+
* Creates an instance of WindowStore
|
|
30
|
+
* 创建 WindowStore 实例
|
|
31
|
+
*/
|
|
32
|
+
constructor(options) {
|
|
33
|
+
super();
|
|
34
|
+
this.logger = options?.logger || new ElectronLogger.ElectronLogger({ appName: 'WindowStore' });
|
|
35
|
+
this.MAX_WINDOWS = options?.maxWindows || constants.DEFAULTS.MAX_WINDOWS;
|
|
36
|
+
this.enablePersistence = options?.enablePersistence ?? false;
|
|
37
|
+
// Initialize core components
|
|
38
|
+
this.registry = new WindowRegistry.WindowRegistry(this.logger);
|
|
39
|
+
this.operator = new WindowOperator.WindowOperator(this.logger);
|
|
40
|
+
this.contextManager = new WindowContextManager.WindowContextManager(options?.contextPersistence, this.logger);
|
|
41
|
+
this.stateManager = new WindowStateManager.WindowStateManager(this.logger, options?.stateKeeper);
|
|
42
|
+
// Default enable cleanup protection
|
|
43
|
+
// 默认启用清理保护
|
|
44
|
+
if (options?.autoStartCleanup !== false) {
|
|
45
|
+
this.startCleanupProtection(options?.cleanupInterval);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// ========================================================================================
|
|
49
|
+
// Focus Management
|
|
50
|
+
// 焦点管理
|
|
51
|
+
// ========================================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Push window ID to focus history
|
|
54
|
+
* 将窗口 ID 推入焦点历史
|
|
55
|
+
*/
|
|
56
|
+
pushFocus(windowId) {
|
|
57
|
+
// Remove if exists (move to top)
|
|
58
|
+
// 如果存在则移除(移动到顶部)
|
|
59
|
+
this.focusHistory = this.focusHistory.filter((id) => id !== windowId);
|
|
60
|
+
this.focusHistory.push(windowId);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Remove window ID from focus history
|
|
64
|
+
* 从焦点历史中移除窗口 ID
|
|
65
|
+
*/
|
|
66
|
+
removeFocus(windowId) {
|
|
67
|
+
this.focusHistory = this.focusHistory.filter((id) => id !== windowId);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the previously focused window ID (excluding current top if needed)
|
|
71
|
+
* 获取上一个聚焦的窗口 ID
|
|
72
|
+
*/
|
|
73
|
+
getPreviousFocusedWindow() {
|
|
74
|
+
// Current top is the active one. We want the one before it.
|
|
75
|
+
// 当前栈顶是活动窗口。我们需要它之前的一个。
|
|
76
|
+
if (this.focusHistory.length < 2) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
return this.focusHistory[this.focusHistory.length - 2];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Pop the top window from history
|
|
83
|
+
* 弹出栈顶窗口
|
|
84
|
+
*/
|
|
85
|
+
popFocus() {
|
|
86
|
+
return this.focusHistory.pop();
|
|
87
|
+
}
|
|
88
|
+
// ========================================================================================
|
|
89
|
+
// Group Management Actions
|
|
90
|
+
// 窗口组管理操作
|
|
91
|
+
// ========================================================================================
|
|
92
|
+
joinGroup(windowId, group) {
|
|
93
|
+
this.registry.addToGroup(windowId, group);
|
|
94
|
+
}
|
|
95
|
+
leaveGroup(windowId, group) {
|
|
96
|
+
this.registry.removeFromGroup(windowId, group);
|
|
97
|
+
}
|
|
98
|
+
getGroup(group) {
|
|
99
|
+
return this.registry.getGroupIds(group);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Close all windows in a group
|
|
103
|
+
* 关闭组内所有窗口
|
|
104
|
+
*/
|
|
105
|
+
async closeGroup(group) {
|
|
106
|
+
const ids = this.registry.getGroupIds(group);
|
|
107
|
+
if (!ids || ids.length === 0)
|
|
108
|
+
return;
|
|
109
|
+
const tasks = ids.map((id) => {
|
|
110
|
+
return new Promise((resolve) => {
|
|
111
|
+
try {
|
|
112
|
+
// Use setTimeout to allow UI updates between closes if many windows
|
|
113
|
+
// 使用 setTimeout 允许 UI 更新,如果有许多窗口
|
|
114
|
+
setImmediate(() => {
|
|
115
|
+
this.operator.destroy(this.getTargetWindow(id));
|
|
116
|
+
resolve();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
this.logger.error(`Failed to close window ${id} in group ${group}: ${error}`);
|
|
121
|
+
resolve();
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
await Promise.all(tasks);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Hide all windows in a group
|
|
129
|
+
* 隐藏组内所有窗口
|
|
130
|
+
*/
|
|
131
|
+
hideGroup(group) {
|
|
132
|
+
const ids = this.registry.getGroupIds(group);
|
|
133
|
+
ids.forEach((id) => this.hide(id));
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Show all windows in a group
|
|
137
|
+
* 显示组内所有窗口
|
|
138
|
+
*/
|
|
139
|
+
showGroup(group) {
|
|
140
|
+
const ids = this.registry.getGroupIds(group);
|
|
141
|
+
ids.forEach((id) => {
|
|
142
|
+
const win = this.getTargetWindow(id);
|
|
143
|
+
if (win)
|
|
144
|
+
this.show(win);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Focus all windows in a group
|
|
149
|
+
* 聚焦组内所有窗口
|
|
150
|
+
*/
|
|
151
|
+
focusGroup(group) {
|
|
152
|
+
const ids = this.registry.getGroupIds(group);
|
|
153
|
+
ids.forEach((id) => this.focus(id));
|
|
154
|
+
}
|
|
155
|
+
show(window, _windowId) {
|
|
156
|
+
this.operator.show(window);
|
|
157
|
+
}
|
|
158
|
+
hide(windowId) {
|
|
159
|
+
const window = this.getTargetWindow(windowId);
|
|
160
|
+
if (window)
|
|
161
|
+
this.operator.hide(window);
|
|
162
|
+
}
|
|
163
|
+
isDestroyed(windowId) {
|
|
164
|
+
const window = this.getTargetWindow(windowId);
|
|
165
|
+
return !window || window.isDestroyed();
|
|
166
|
+
}
|
|
167
|
+
isVisible(windowId) {
|
|
168
|
+
const window = this.getValidWindow(windowId);
|
|
169
|
+
return window?.isVisible() || false;
|
|
170
|
+
}
|
|
171
|
+
isMinimized(windowId) {
|
|
172
|
+
return this.getTargetWindow(windowId)?.isMinimized() || false;
|
|
173
|
+
}
|
|
174
|
+
isMaximized(windowId) {
|
|
175
|
+
return this.getTargetWindow(windowId)?.isMaximized() || false;
|
|
176
|
+
}
|
|
177
|
+
fullScreenState(windowId) {
|
|
178
|
+
return this.getTargetWindow(windowId)?.isFullScreen() || false;
|
|
179
|
+
}
|
|
180
|
+
minimize(windowId) {
|
|
181
|
+
const window = this.getTargetWindow(windowId);
|
|
182
|
+
if (window)
|
|
183
|
+
this.operator.minimize(window);
|
|
184
|
+
}
|
|
185
|
+
restore(windowId) {
|
|
186
|
+
const window = this.getValidWindow(windowId);
|
|
187
|
+
if (window)
|
|
188
|
+
this.operator.restore(window);
|
|
189
|
+
}
|
|
190
|
+
maximize(windowId) {
|
|
191
|
+
const window = this.getValidWindow(windowId);
|
|
192
|
+
if (window)
|
|
193
|
+
this.operator.maximize(window);
|
|
194
|
+
}
|
|
195
|
+
unmaximize(windowId) {
|
|
196
|
+
const window = this.getValidWindow(windowId);
|
|
197
|
+
if (window)
|
|
198
|
+
this.operator.unmaximize(window);
|
|
199
|
+
}
|
|
200
|
+
fullScreen(windowId) {
|
|
201
|
+
const window = this.getValidWindow(windowId);
|
|
202
|
+
if (window)
|
|
203
|
+
this.operator.toggleFullScreen(window);
|
|
204
|
+
}
|
|
205
|
+
focus(windowId) {
|
|
206
|
+
const window = this.getValidWindow(windowId);
|
|
207
|
+
if (window)
|
|
208
|
+
this.operator.focus(window);
|
|
209
|
+
}
|
|
210
|
+
setMovable(window) {
|
|
211
|
+
window.setMovable(true);
|
|
212
|
+
}
|
|
213
|
+
winClose(windowId) {
|
|
214
|
+
this.removeWindow(windowId);
|
|
215
|
+
}
|
|
216
|
+
openDevTools(windowId) {
|
|
217
|
+
const window = this.getTargetWindow(windowId);
|
|
218
|
+
if (window)
|
|
219
|
+
this.operator.openDevTools(window);
|
|
220
|
+
}
|
|
221
|
+
isDevToolsOpened(windowId) {
|
|
222
|
+
const window = this.getTargetWindow(windowId);
|
|
223
|
+
return window ? this.operator.isDevToolsOpened(window) : false;
|
|
224
|
+
}
|
|
225
|
+
closeDevTools(windowId) {
|
|
226
|
+
const window = this.getTargetWindow(windowId);
|
|
227
|
+
if (window)
|
|
228
|
+
this.operator.closeDevTools(window);
|
|
229
|
+
}
|
|
230
|
+
quit() {
|
|
231
|
+
electron.app.quit();
|
|
232
|
+
}
|
|
233
|
+
getWindowSize() {
|
|
234
|
+
const { width, height } = electron.screen.getPrimaryDisplay().workAreaSize;
|
|
235
|
+
return { width, height };
|
|
236
|
+
}
|
|
237
|
+
send(windowId, name, data = '') {
|
|
238
|
+
const window = this.getTargetWindow(windowId);
|
|
239
|
+
if (window)
|
|
240
|
+
this.operator.send(window, name, data);
|
|
241
|
+
}
|
|
242
|
+
setSkipTaskbar(windowId, bool) {
|
|
243
|
+
const window = this.getTargetWindow(windowId);
|
|
244
|
+
if (window)
|
|
245
|
+
this.operator.setSkipTaskbar(window, bool);
|
|
246
|
+
}
|
|
247
|
+
// ========================================================================================
|
|
248
|
+
// Property Accessors (Delegated to WindowRegistry)
|
|
249
|
+
// 属性访问器(委托给 WindowRegistry)
|
|
250
|
+
// ========================================================================================
|
|
251
|
+
get mainWindow() {
|
|
252
|
+
return this.registry.getMainWindow();
|
|
253
|
+
}
|
|
254
|
+
set mainWindow(window) {
|
|
255
|
+
this.registry.setMainWindow(window);
|
|
256
|
+
}
|
|
257
|
+
getWindowCount() {
|
|
258
|
+
return this.registry.getCount();
|
|
259
|
+
}
|
|
260
|
+
getAllWindowKeys() {
|
|
261
|
+
return this.registry.getAllIds();
|
|
262
|
+
}
|
|
263
|
+
getAllWindows() {
|
|
264
|
+
return this.registry.getAllWindows();
|
|
265
|
+
}
|
|
266
|
+
getWindowNames() {
|
|
267
|
+
return this.registry.getNameMap();
|
|
268
|
+
}
|
|
269
|
+
getNameByWindowId(windowId) {
|
|
270
|
+
return this.registry.getNameById(windowId);
|
|
271
|
+
}
|
|
272
|
+
getWindowByNameId(name) {
|
|
273
|
+
return this.registry.getIdByName(name);
|
|
274
|
+
}
|
|
275
|
+
getWindowByName(name) {
|
|
276
|
+
return this.registry.getByName(name);
|
|
277
|
+
}
|
|
278
|
+
hasByName(proposedName) {
|
|
279
|
+
return this.registry.hasName(proposedName);
|
|
280
|
+
}
|
|
281
|
+
deleteByName(proposedName) {
|
|
282
|
+
const id = this.registry.getIdByName(proposedName);
|
|
283
|
+
if (id) {
|
|
284
|
+
this.registry.unregister(id);
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
getWindowById(windowId) {
|
|
290
|
+
return this.registry.getById(windowId);
|
|
291
|
+
}
|
|
292
|
+
hasById(windowId) {
|
|
293
|
+
return this.registry.hasId(windowId);
|
|
294
|
+
}
|
|
295
|
+
deleteById(windowId) {
|
|
296
|
+
if (this.registry.hasId(windowId)) {
|
|
297
|
+
this.registry.unregister(windowId);
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
getWindowId(window) {
|
|
303
|
+
return this.registry.getIdByWindow(window);
|
|
304
|
+
}
|
|
305
|
+
updateWindowName(windowId, newName) {
|
|
306
|
+
this.registry.updateWindowName(windowId, newName);
|
|
307
|
+
}
|
|
308
|
+
// ========================================================================================
|
|
309
|
+
// Helper Methods
|
|
310
|
+
// 辅助方法
|
|
311
|
+
// ========================================================================================
|
|
312
|
+
getTargetWindow(windowId) {
|
|
313
|
+
if (!windowId) {
|
|
314
|
+
return this.getCurrentWindow();
|
|
315
|
+
}
|
|
316
|
+
return this.registry.getById(windowId) || this.registry.getByName(windowId);
|
|
317
|
+
}
|
|
318
|
+
getValidWindow(windowId) {
|
|
319
|
+
const window = this.getTargetWindow(windowId);
|
|
320
|
+
if (!window || window.isDestroyed()) {
|
|
321
|
+
this.logger.warn(`Window ${windowId || 'current'} not found or destroyed`);
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
return window;
|
|
325
|
+
}
|
|
326
|
+
getCurrentWindow() {
|
|
327
|
+
const focusedWindow = electron.BrowserWindow.getFocusedWindow();
|
|
328
|
+
if (focusedWindow && !focusedWindow.isDestroyed())
|
|
329
|
+
return focusedWindow;
|
|
330
|
+
return this.mainWindow ?? undefined;
|
|
331
|
+
}
|
|
332
|
+
// ========================================================================================
|
|
333
|
+
// Core Logic (Creation & Removal)
|
|
334
|
+
// 核心逻辑(创建与移除)
|
|
335
|
+
// ========================================================================================
|
|
336
|
+
createWindow(window, config) {
|
|
337
|
+
if (this.registry.getCount() >= this.MAX_WINDOWS) {
|
|
338
|
+
const error = new Error(`Maximum window limit (${this.MAX_WINDOWS}) reached`);
|
|
339
|
+
this.logger.error(error.message);
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
342
|
+
const windowId = config?.windowId || uuid.v4();
|
|
343
|
+
let windowName = config?.name || `window-${windowId}`;
|
|
344
|
+
try {
|
|
345
|
+
windowName = this.validateWindowName(windowName);
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
this.logger.warn(`Window name "${windowName}" already exists, generating unique name`);
|
|
349
|
+
windowName = `${windowName}-${Date.now()}`;
|
|
350
|
+
}
|
|
351
|
+
this.registerWindow(windowId, windowName, window, {
|
|
352
|
+
enablePersistence: config?.enablePersistence,
|
|
353
|
+
});
|
|
354
|
+
return windowId;
|
|
355
|
+
}
|
|
356
|
+
removeWindow(windowId) {
|
|
357
|
+
const window = this.registry.getById(windowId);
|
|
358
|
+
if (window && !window.isDestroyed()) {
|
|
359
|
+
try {
|
|
360
|
+
// Operator handles safe closing
|
|
361
|
+
// Operator 处理安全关闭
|
|
362
|
+
this.operator.close(window);
|
|
363
|
+
// Ensure destruction
|
|
364
|
+
// 确保销毁
|
|
365
|
+
if (!window.isDestroyed()) {
|
|
366
|
+
this.operator.destroy(window);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
this.logger.error(`Failed to remove window ${windowId}: ${error}`);
|
|
371
|
+
this.emit('error', error);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// Always unregister from registry
|
|
375
|
+
// 始终从注册表中注销
|
|
376
|
+
this.registry.unregister(windowId);
|
|
377
|
+
}
|
|
378
|
+
validateWindowName(proposedName) {
|
|
379
|
+
if (this.registry.hasName(proposedName)) {
|
|
380
|
+
throw new Error(`Window name "${proposedName}" already exists`);
|
|
381
|
+
}
|
|
382
|
+
return proposedName;
|
|
383
|
+
}
|
|
384
|
+
registerWindow(id, name, window, options) {
|
|
385
|
+
this.registry.register(id, name, window);
|
|
386
|
+
if (options?.enablePersistence ?? this.enablePersistence) {
|
|
387
|
+
this.stateManager.manage(name, window);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
manageState(name, window, getGroups) {
|
|
391
|
+
this.stateManager.manage(name, window, getGroups);
|
|
392
|
+
}
|
|
393
|
+
getWindowGroups(windowId) {
|
|
394
|
+
return this.registry.getWindowGroups(windowId);
|
|
395
|
+
}
|
|
396
|
+
getWindowState(name, defaultWidth, defaultHeight) {
|
|
397
|
+
return this.stateManager.getState(name, defaultWidth, defaultHeight);
|
|
398
|
+
}
|
|
399
|
+
// ========================================================================================
|
|
400
|
+
// Context Management (Delegated to WindowContextManager)
|
|
401
|
+
// 上下文管理(委托给 WindowContextManager)
|
|
402
|
+
// ========================================================================================
|
|
403
|
+
async saveWindowContext(windowId, context) {
|
|
404
|
+
await this.contextManager.save(windowId, context);
|
|
405
|
+
}
|
|
406
|
+
async loadWindowContext(windowId) {
|
|
407
|
+
return await this.contextManager.load(windowId);
|
|
408
|
+
}
|
|
409
|
+
async clearWindowContext(windowId) {
|
|
410
|
+
await this.contextManager.clear(windowId);
|
|
411
|
+
}
|
|
412
|
+
// ========================================================================================
|
|
413
|
+
// Cleanup Protection (Delegated to WindowRegistry)
|
|
414
|
+
// 清理防护(委托给 WindowRegistry)
|
|
415
|
+
// ========================================================================================
|
|
416
|
+
startCleanupProtection(intervalMs = constants.DEFAULTS.CLEANUP_INTERVAL) {
|
|
417
|
+
this.registry.startCleanupProtection(intervalMs);
|
|
418
|
+
}
|
|
419
|
+
stopCleanupProtection() {
|
|
420
|
+
this.registry.stopCleanupProtection();
|
|
421
|
+
}
|
|
422
|
+
async dispose() {
|
|
423
|
+
this.logger.info('Disposing WindowStore...');
|
|
424
|
+
this.stopCleanupProtection();
|
|
425
|
+
// Close all windows
|
|
426
|
+
const windows = this.getAllWindows();
|
|
427
|
+
for (const win of windows) {
|
|
428
|
+
if (!win.isDestroyed()) {
|
|
429
|
+
win.close();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
// Clear registry
|
|
433
|
+
this.registry.clear();
|
|
434
|
+
this.logger.info('WindowStore disposed');
|
|
435
|
+
}
|
|
436
|
+
}module.exports=WindowStore;//# sourceMappingURL=WindowStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WindowStore.js","sources":["../../../src/core/window/WindowStore.ts"],"sourcesContent":["import { BrowserWindow, screen, app } from 'electron';\nimport { v4 as uuidv4 } from 'uuid';\nimport { EventEmitter } from 'events';\nimport { Logger, ILogger } from '@/infrastructure/logger';\nimport { WindowStoreOptions } from './window-manager.type';\nimport { WindowRegistry } from './core/WindowRegistry';\nimport { WindowOperator } from './core/WindowOperator';\nimport { WindowContextManager } from './core/WindowContextManager';\nimport { WindowStateManager } from './core/WindowStateManager';\nimport { DEFAULTS } from './constants';\n\n/**\n * WindowStore - Window state management class (Refactored & Optimized)\n * WindowStore - 窗口状态管理类(已重构与优化)\n *\n * Facade that coordinates:\n * - WindowRegistry (Storage & Cleanup)\n * - WindowOperator (Actions)\n * - WindowContextManager (Persistence)\n * - WindowStateManager (State Persistence)\n *\n * @class\n */\nexport default class WindowStore extends EventEmitter {\n private readonly MAX_WINDOWS: number;\n protected enablePersistence: boolean = false;\n protected logger: ILogger;\n\n public get persistenceEnabled(): boolean {\n return this.enablePersistence;\n }\n\n // Core components\n private registry: WindowRegistry;\n private operator: WindowOperator;\n private contextManager: WindowContextManager;\n private stateManager: WindowStateManager;\n\n // Focus History Stack\n // 焦点历史栈\n private focusHistory: string[] = [];\n\n /**\n * Creates an instance of WindowStore\n * 创建 WindowStore 实例\n */\n constructor(options?: WindowStoreOptions) {\n super();\n this.logger = options?.logger || new Logger({ appName: 'WindowStore' });\n this.MAX_WINDOWS = options?.maxWindows || DEFAULTS.MAX_WINDOWS;\n this.enablePersistence = options?.enablePersistence ?? false;\n\n // Initialize core components\n this.registry = new WindowRegistry(this.logger);\n this.operator = new WindowOperator(this.logger);\n this.contextManager = new WindowContextManager(options?.contextPersistence, this.logger);\n this.stateManager = new WindowStateManager(this.logger, options?.stateKeeper);\n\n // Default enable cleanup protection\n // 默认启用清理保护\n if (options?.autoStartCleanup !== false) {\n this.startCleanupProtection(options?.cleanupInterval);\n }\n }\n\n // ========================================================================================\n // Focus Management\n // 焦点管理\n // ========================================================================================\n\n /**\n * Push window ID to focus history\n * 将窗口 ID 推入焦点历史\n */\n pushFocus(windowId: string): void {\n // Remove if exists (move to top)\n // 如果存在则移除(移动到顶部)\n this.focusHistory = this.focusHistory.filter((id) => id !== windowId);\n this.focusHistory.push(windowId);\n }\n\n /**\n * Remove window ID from focus history\n * 从焦点历史中移除窗口 ID\n */\n removeFocus(windowId: string): void {\n this.focusHistory = this.focusHistory.filter((id) => id !== windowId);\n }\n\n /**\n * Get the previously focused window ID (excluding current top if needed)\n * 获取上一个聚焦的窗口 ID\n */\n getPreviousFocusedWindow(): string | undefined {\n // Current top is the active one. We want the one before it.\n // 当前栈顶是活动窗口。我们需要它之前的一个。\n if (this.focusHistory.length < 2) {\n return undefined;\n }\n return this.focusHistory[this.focusHistory.length - 2];\n }\n\n /**\n * Pop the top window from history\n * 弹出栈顶窗口\n */\n popFocus(): string | undefined {\n return this.focusHistory.pop();\n }\n\n // ========================================================================================\n // Group Management Actions\n // 窗口组管理操作\n // ========================================================================================\n\n joinGroup(windowId: string, group: string): void {\n this.registry.addToGroup(windowId, group);\n }\n\n leaveGroup(windowId: string, group: string): void {\n this.registry.removeFromGroup(windowId, group);\n }\n\n getGroup(group: string): string[] {\n return this.registry.getGroupIds(group);\n }\n\n /**\n * Close all windows in a group\n * 关闭组内所有窗口\n */\n async closeGroup(group: string): Promise<void> {\n const ids = this.registry.getGroupIds(group);\n if (!ids || ids.length === 0) return;\n\n const tasks = ids.map((id) => {\n return new Promise<void>((resolve) => {\n try {\n // Use setTimeout to allow UI updates between closes if many windows\n // 使用 setTimeout 允许 UI 更新,如果有许多窗口\n setImmediate(() => {\n this.operator.destroy(this.getTargetWindow(id));\n resolve();\n });\n } catch (error) {\n this.logger.error(`Failed to close window ${id} in group ${group}: ${error}`);\n resolve();\n }\n });\n });\n\n await Promise.all(tasks);\n }\n\n /**\n * Hide all windows in a group\n * 隐藏组内所有窗口\n */\n hideGroup(group: string): void {\n const ids = this.registry.getGroupIds(group);\n ids.forEach((id) => this.hide(id));\n }\n\n /**\n * Show all windows in a group\n * 显示组内所有窗口\n */\n showGroup(group: string): void {\n const ids = this.registry.getGroupIds(group);\n ids.forEach((id) => {\n const win = this.getTargetWindow(id);\n if (win) this.show(win);\n });\n }\n\n /**\n * Focus all windows in a group\n * 聚焦组内所有窗口\n */\n focusGroup(group: string): void {\n const ids = this.registry.getGroupIds(group);\n ids.forEach((id) => this.focus(id));\n }\n\n show(window: BrowserWindow, _windowId?: string): void {\n this.operator.show(window);\n }\n\n hide(windowId: string): void {\n const window = this.getTargetWindow(windowId);\n if (window) this.operator.hide(window);\n }\n\n isDestroyed(windowId: string): boolean {\n const window = this.getTargetWindow(windowId);\n return !window || window.isDestroyed();\n }\n\n isVisible(windowId: string): boolean {\n const window = this.getValidWindow(windowId);\n return window?.isVisible() || false;\n }\n\n isMinimized(windowId: string): boolean {\n return this.getTargetWindow(windowId)?.isMinimized() || false;\n }\n\n isMaximized(windowId: string): boolean {\n return this.getTargetWindow(windowId)?.isMaximized() || false;\n }\n\n fullScreenState(windowId: string): boolean {\n return this.getTargetWindow(windowId)?.isFullScreen() || false;\n }\n\n minimize(windowId?: string): void {\n const window = this.getTargetWindow(windowId);\n if (window) this.operator.minimize(window);\n }\n\n restore(windowId: string): void {\n const window = this.getValidWindow(windowId);\n if (window) this.operator.restore(window);\n }\n\n maximize(windowId: string): void {\n const window = this.getValidWindow(windowId);\n if (window) this.operator.maximize(window);\n }\n\n unmaximize(windowId: string): void {\n const window = this.getValidWindow(windowId);\n if (window) this.operator.unmaximize(window);\n }\n\n fullScreen(windowId: string): void {\n const window = this.getValidWindow(windowId);\n if (window) this.operator.toggleFullScreen(window);\n }\n\n focus(windowId: string): void {\n const window = this.getValidWindow(windowId);\n if (window) this.operator.focus(window);\n }\n\n setMovable(window: BrowserWindow): void {\n window.setMovable(true);\n }\n\n winClose(windowId: string): void {\n this.removeWindow(windowId);\n }\n\n openDevTools(windowId: string): void {\n const window = this.getTargetWindow(windowId);\n if (window) this.operator.openDevTools(window);\n }\n\n isDevToolsOpened(windowId: string): boolean {\n const window = this.getTargetWindow(windowId);\n return window ? this.operator.isDevToolsOpened(window) : false;\n }\n\n closeDevTools(windowId: string): void {\n const window = this.getTargetWindow(windowId);\n if (window) this.operator.closeDevTools(window);\n }\n\n quit(): void {\n app.quit();\n }\n\n getWindowSize(): { width: number; height: number } {\n const { width, height } = screen.getPrimaryDisplay().workAreaSize;\n return { width, height };\n }\n\n send(windowId: string, name: string, data: unknown = ''): void {\n const window = this.getTargetWindow(windowId);\n if (window) this.operator.send(window, name, data);\n }\n\n setSkipTaskbar(windowId: string, bool: boolean): void {\n const window = this.getTargetWindow(windowId);\n if (window) this.operator.setSkipTaskbar(window, bool);\n }\n\n // ========================================================================================\n // Property Accessors (Delegated to WindowRegistry)\n // 属性访问器(委托给 WindowRegistry)\n // ========================================================================================\n\n public get mainWindow(): BrowserWindow | null {\n return this.registry.getMainWindow();\n }\n\n protected set mainWindow(window: BrowserWindow | null) {\n this.registry.setMainWindow(window);\n }\n\n getWindowCount(): number {\n return this.registry.getCount();\n }\n\n getAllWindowKeys(): string[] {\n return this.registry.getAllIds();\n }\n\n getAllWindows(): BrowserWindow[] {\n return this.registry.getAllWindows();\n }\n\n getWindowNames(): Map<string, string> {\n return this.registry.getNameMap();\n }\n\n getNameByWindowId(windowId: string): string | undefined {\n return this.registry.getNameById(windowId);\n }\n\n getWindowByNameId(name: string): string | undefined {\n return this.registry.getIdByName(name);\n }\n\n getWindowByName(name: string): BrowserWindow | undefined {\n return this.registry.getByName(name);\n }\n\n hasByName(proposedName: string): boolean {\n return this.registry.hasName(proposedName);\n }\n\n deleteByName(proposedName: string): boolean {\n const id = this.registry.getIdByName(proposedName);\n if (id) {\n this.registry.unregister(id);\n return true;\n }\n return false;\n }\n\n getWindowById(windowId: string): BrowserWindow | undefined {\n return this.registry.getById(windowId);\n }\n\n hasById(windowId: string): boolean {\n return this.registry.hasId(windowId);\n }\n\n deleteById(windowId: string): boolean {\n if (this.registry.hasId(windowId)) {\n this.registry.unregister(windowId);\n return true;\n }\n return false;\n }\n\n getWindowId(window: BrowserWindow): string | undefined {\n return this.registry.getIdByWindow(window);\n }\n\n updateWindowName(windowId: string, newName: string): void {\n this.registry.updateWindowName(windowId, newName);\n }\n\n // ========================================================================================\n // Helper Methods\n // 辅助方法\n // ========================================================================================\n\n getTargetWindow(windowId?: string): BrowserWindow | undefined {\n if (!windowId) {\n return this.getCurrentWindow();\n }\n return this.registry.getById(windowId) || this.registry.getByName(windowId);\n }\n\n getValidWindow(windowId?: string): BrowserWindow | undefined {\n const window = this.getTargetWindow(windowId);\n if (!window || window.isDestroyed()) {\n this.logger.warn(`Window ${windowId || 'current'} not found or destroyed`);\n return undefined;\n }\n return window;\n }\n\n getCurrentWindow(): BrowserWindow | undefined {\n const focusedWindow = BrowserWindow.getFocusedWindow();\n if (focusedWindow && !focusedWindow.isDestroyed()) return focusedWindow;\n return this.mainWindow ?? undefined;\n }\n\n // ========================================================================================\n // Core Logic (Creation & Removal)\n // 核心逻辑(创建与移除)\n // ========================================================================================\n\n createWindow(\n window: BrowserWindow,\n config?: { name?: string; windowId?: string; enablePersistence?: boolean }\n ): string {\n if (this.registry.getCount() >= this.MAX_WINDOWS) {\n const error = new Error(`Maximum window limit (${this.MAX_WINDOWS}) reached`);\n this.logger.error(error.message);\n throw error;\n }\n\n const windowId = config?.windowId || uuidv4();\n let windowName = config?.name || `window-${windowId}`;\n\n try {\n windowName = this.validateWindowName(windowName);\n } catch {\n this.logger.warn(`Window name \"${windowName}\" already exists, generating unique name`);\n windowName = `${windowName}-${Date.now()}`;\n }\n\n this.registerWindow(windowId, windowName, window, {\n enablePersistence: config?.enablePersistence,\n });\n return windowId;\n }\n\n removeWindow(windowId: string): void {\n const window = this.registry.getById(windowId);\n\n if (window && !window.isDestroyed()) {\n try {\n // Operator handles safe closing\n // Operator 处理安全关闭\n this.operator.close(window);\n\n // Ensure destruction\n // 确保销毁\n if (!window.isDestroyed()) {\n this.operator.destroy(window);\n }\n } catch (error) {\n this.logger.error(`Failed to remove window ${windowId}: ${error}`);\n this.emit('error', error);\n }\n }\n\n // Always unregister from registry\n // 始终从注册表中注销\n this.registry.unregister(windowId);\n }\n\n private validateWindowName(proposedName: string): string {\n if (this.registry.hasName(proposedName)) {\n throw new Error(`Window name \"${proposedName}\" already exists`);\n }\n return proposedName;\n }\n\n private registerWindow(\n id: string,\n name: string,\n window: BrowserWindow,\n options?: { enablePersistence?: boolean }\n ): void {\n this.registry.register(id, name, window);\n\n if (options?.enablePersistence ?? this.enablePersistence) {\n this.stateManager.manage(name, window);\n }\n }\n\n manageState(name: string, window: BrowserWindow, getGroups?: () => string[]): void {\n this.stateManager.manage(name, window, getGroups);\n }\n\n getWindowGroups(windowId: string): string[] {\n return this.registry.getWindowGroups(windowId);\n }\n\n getWindowState(name: string, defaultWidth?: number, defaultHeight?: number) {\n return this.stateManager.getState(name, defaultWidth, defaultHeight);\n }\n\n // ========================================================================================\n // Context Management (Delegated to WindowContextManager)\n // 上下文管理(委托给 WindowContextManager)\n // ========================================================================================\n\n async saveWindowContext(windowId: string, context: any): Promise<void> {\n await this.contextManager.save(windowId, context);\n }\n\n async loadWindowContext(windowId: string): Promise<any> {\n return await this.contextManager.load(windowId);\n }\n\n async clearWindowContext(windowId: string): Promise<void> {\n await this.contextManager.clear(windowId);\n }\n\n // ========================================================================================\n // Cleanup Protection (Delegated to WindowRegistry)\n // 清理防护(委托给 WindowRegistry)\n // ========================================================================================\n\n public startCleanupProtection(intervalMs: number = DEFAULTS.CLEANUP_INTERVAL): void {\n this.registry.startCleanupProtection(intervalMs);\n }\n\n public stopCleanupProtection(): void {\n this.registry.stopCleanupProtection();\n }\n\n public async dispose(): Promise<void> {\n this.logger.info('Disposing WindowStore...');\n this.stopCleanupProtection();\n\n // Close all windows\n const windows = this.getAllWindows();\n for (const win of windows) {\n if (!win.isDestroyed()) {\n win.close();\n }\n }\n\n // Clear registry\n this.registry.clear();\n this.logger.info('WindowStore disposed');\n }\n}\n"],"names":["EventEmitter","Logger","DEFAULTS","WindowRegistry","WindowOperator","WindowContextManager","WindowStateManager","app","screen","BrowserWindow","uuidv4"],"mappings":"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"}
|