@talex-touch/utils 1.0.40 → 1.0.44
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/.eslintcache +1 -0
- package/__tests__/cloud-sync-sdk.test.ts +442 -0
- package/__tests__/icons/icons.test.ts +84 -0
- package/__tests__/plugin-sdk-lifecycle.test.ts +130 -0
- package/__tests__/power-sdk.test.ts +143 -0
- package/__tests__/preset-export-types.test.ts +108 -0
- package/__tests__/search/fuzzy-match.test.ts +137 -0
- package/__tests__/transport/port-policy.test.ts +44 -0
- package/__tests__/transport-domain-sdks.test.ts +152 -0
- package/__tests__/types/update.test.ts +67 -0
- package/account/account-sdk.ts +915 -0
- package/account/index.ts +2 -0
- package/account/types.ts +321 -0
- package/analytics/client.ts +136 -0
- package/analytics/index.ts +2 -0
- package/analytics/types.ts +156 -0
- package/animation/auto-resize.ts +322 -0
- package/animation/window-node.ts +26 -19
- package/auth/clerk-types.ts +12 -30
- package/auth/index.ts +0 -2
- package/auth/useAuthState.ts +6 -14
- package/base/index.ts +2 -0
- package/base/log-level.ts +105 -0
- package/channel/index.ts +170 -69
- package/cloud-sync/cloud-sync-sdk.ts +450 -0
- package/cloud-sync/index.ts +1 -0
- package/common/file-scan-utils.ts +17 -9
- package/common/index.ts +4 -0
- package/common/logger/index.ts +46 -0
- package/common/logger/logger-manager.ts +303 -0
- package/common/logger/module-logger.ts +270 -0
- package/common/logger/transport-logger.ts +234 -0
- package/common/logger/types.ts +93 -0
- package/common/search/gather.ts +48 -6
- package/common/search/index.ts +8 -0
- package/common/storage/constants.ts +13 -0
- package/common/storage/entity/app-settings.ts +245 -0
- package/common/storage/entity/index.ts +3 -0
- package/common/storage/entity/layout-atom-types.ts +147 -0
- package/common/storage/entity/openers.ts +1 -0
- package/common/storage/entity/preset-cloud-api.ts +132 -0
- package/common/storage/entity/preset-export-types.ts +256 -0
- package/common/storage/entity/shortcut-settings.ts +1 -0
- package/common/storage/shortcut-storage.ts +11 -0
- package/common/utils/clone-diagnostics.ts +105 -0
- package/common/utils/file.ts +16 -8
- package/common/utils/index.ts +6 -2
- package/common/utils/payload-preview.ts +173 -0
- package/common/utils/polling.ts +167 -13
- package/common/utils/safe-path.ts +103 -0
- package/common/utils/safe-shell.ts +115 -0
- package/common/utils/task-queue.ts +4 -1
- package/core-box/builder/tuff-builder.ts +0 -1
- package/core-box/index.ts +1 -1
- package/core-box/recommendation.ts +38 -1
- package/core-box/tuff/tuff-dsl.ts +97 -0
- package/electron/download-manager.ts +10 -7
- package/electron/env-tool.ts +42 -40
- package/electron/index.ts +0 -1
- package/env/index.ts +156 -0
- package/eslint.config.js +55 -0
- package/i18n/index.ts +62 -0
- package/i18n/locales/en.json +226 -0
- package/i18n/locales/zh.json +226 -0
- package/i18n/message-keys.ts +236 -0
- package/i18n/resolver.ts +181 -0
- package/icons/index.ts +257 -0
- package/icons/svg.ts +69 -0
- package/index.ts +9 -1
- package/intelligence/client.ts +72 -42
- package/market/constants.ts +21 -3
- package/market/index.ts +1 -1
- package/market/types.ts +20 -5
- package/package.json +15 -5
- package/permission/index.ts +143 -46
- package/permission/legacy.ts +26 -0
- package/permission/registry.ts +304 -0
- package/permission/types.ts +164 -0
- package/plugin/channel.ts +68 -39
- package/plugin/index.ts +82 -8
- package/plugin/install.ts +3 -0
- package/plugin/log/types.ts +22 -5
- package/plugin/node/logger-manager.ts +11 -3
- package/plugin/node/logger.ts +24 -17
- package/plugin/preload.ts +25 -2
- package/plugin/providers/index.ts +4 -0
- package/plugin/providers/market-client.ts +218 -0
- package/plugin/providers/npm-provider.ts +228 -0
- package/plugin/providers/tpex-provider.ts +297 -0
- package/plugin/providers/tpex-types.ts +34 -0
- package/plugin/sdk/box-items.ts +14 -0
- package/plugin/sdk/box-sdk.ts +64 -0
- package/plugin/sdk/channel.ts +119 -4
- package/plugin/sdk/clipboard.ts +26 -12
- package/plugin/sdk/cloud-sync.ts +113 -0
- package/plugin/sdk/common.ts +19 -11
- package/plugin/sdk/core-box.ts +6 -15
- package/plugin/sdk/division-box.ts +160 -65
- package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
- package/plugin/sdk/feature-sdk.ts +111 -76
- package/plugin/sdk/flow.ts +146 -45
- package/plugin/sdk/hooks/bridge.ts +113 -49
- package/plugin/sdk/hooks/life-cycle.ts +35 -16
- package/plugin/sdk/index.ts +14 -3
- package/plugin/sdk/intelligence.ts +87 -0
- package/plugin/sdk/meta/README.md +179 -0
- package/plugin/sdk/meta-sdk.ts +244 -0
- package/plugin/sdk/notification.ts +9 -0
- package/plugin/sdk/performance.ts +1 -16
- package/plugin/sdk/plugin-info.ts +64 -0
- package/plugin/sdk/power.ts +155 -0
- package/plugin/sdk/recommend.ts +21 -0
- package/plugin/sdk/service/index.ts +12 -8
- package/plugin/sdk/sqlite.ts +141 -0
- package/plugin/sdk/storage.ts +2 -6
- package/plugin/sdk/system.ts +2 -9
- package/plugin/sdk/temp-files.ts +41 -0
- package/plugin/sdk/touch-sdk.ts +18 -0
- package/plugin/sdk/types.ts +44 -4
- package/plugin/sdk/window/index.ts +12 -9
- package/plugin/sdk-version.ts +231 -0
- package/preload/renderer.ts +3 -2
- package/renderer/hooks/arg-mapper.ts +34 -6
- package/renderer/hooks/index.ts +13 -0
- package/renderer/hooks/initialize.ts +2 -1
- package/renderer/hooks/use-agent-market-sdk.ts +7 -0
- package/renderer/hooks/use-agent-market.ts +106 -0
- package/renderer/hooks/use-agents-sdk.ts +7 -0
- package/renderer/hooks/use-app-sdk.ts +7 -0
- package/renderer/hooks/use-channel.ts +33 -4
- package/renderer/hooks/use-download-sdk.ts +21 -0
- package/renderer/hooks/use-intelligence-sdk.ts +7 -0
- package/renderer/hooks/use-intelligence-stats.ts +290 -0
- package/renderer/hooks/use-intelligence.ts +202 -104
- package/renderer/hooks/use-market-sdk.ts +16 -0
- package/renderer/hooks/use-notification-sdk.ts +7 -0
- package/renderer/hooks/use-permission-sdk.ts +7 -0
- package/renderer/hooks/use-permission.ts +325 -0
- package/renderer/hooks/use-platform-sdk.ts +7 -0
- package/renderer/hooks/use-plugin-sdk.ts +16 -0
- package/renderer/hooks/use-settings-sdk.ts +7 -0
- package/renderer/hooks/use-update-sdk.ts +21 -0
- package/renderer/index.ts +1 -0
- package/renderer/ref.ts +19 -10
- package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
- package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
- package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
- package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
- package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
- package/renderer/shared/components/index.ts +5 -0
- package/renderer/shared/components/shims-vue.d.ts +5 -0
- package/renderer/shared/index.ts +2 -0
- package/renderer/shared/plugin-detail.ts +62 -0
- package/renderer/storage/app-settings.ts +3 -1
- package/renderer/storage/base-storage.ts +508 -82
- package/renderer/storage/intelligence-storage.ts +37 -46
- package/renderer/storage/openers.ts +3 -1
- package/renderer/storage/storage-subscription.ts +126 -42
- package/renderer/touch-sdk/env.ts +10 -10
- package/renderer/touch-sdk/index.ts +114 -18
- package/renderer/touch-sdk/terminal.ts +24 -13
- package/search/feature-matcher.ts +279 -0
- package/search/fuzzy-match.ts +64 -34
- package/search/index.ts +10 -0
- package/search/levenshtein-utils.ts +17 -11
- package/transport/errors.ts +310 -0
- package/transport/event/builder.ts +378 -0
- package/transport/event/index.ts +7 -0
- package/transport/event/types.ts +292 -0
- package/transport/events/index.ts +2670 -0
- package/transport/events/meta-overlay.ts +79 -0
- package/transport/events/types/agents.ts +177 -0
- package/transport/events/types/app-index.ts +9 -0
- package/transport/events/types/app.ts +475 -0
- package/transport/events/types/box-item.ts +222 -0
- package/transport/events/types/clipboard.ts +80 -0
- package/transport/events/types/core-box.ts +534 -0
- package/transport/events/types/device-idle.ts +7 -0
- package/transport/events/types/division-box.ts +99 -0
- package/transport/events/types/download.ts +115 -0
- package/transport/events/types/file-index.ts +73 -0
- package/transport/events/types/flow.ts +149 -0
- package/transport/events/types/index.ts +70 -0
- package/transport/events/types/market.ts +39 -0
- package/transport/events/types/meta-overlay.ts +184 -0
- package/transport/events/types/notification.ts +140 -0
- package/transport/events/types/permission.ts +90 -0
- package/transport/events/types/platform.ts +8 -0
- package/transport/events/types/plugin.ts +620 -0
- package/transport/events/types/sentry.ts +20 -0
- package/transport/events/types/storage.ts +208 -0
- package/transport/events/types/transport.ts +60 -0
- package/transport/events/types/tray.ts +16 -0
- package/transport/events/types/update.ts +78 -0
- package/transport/index.ts +139 -0
- package/transport/main.ts +2 -0
- package/transport/sdk/constants.ts +29 -0
- package/transport/sdk/domains/agents-market.ts +47 -0
- package/transport/sdk/domains/agents.ts +62 -0
- package/transport/sdk/domains/app.ts +48 -0
- package/transport/sdk/domains/disposable.ts +35 -0
- package/transport/sdk/domains/download.ts +139 -0
- package/transport/sdk/domains/index.ts +13 -0
- package/transport/sdk/domains/intelligence.ts +616 -0
- package/transport/sdk/domains/market.ts +35 -0
- package/transport/sdk/domains/notification.ts +62 -0
- package/transport/sdk/domains/permission.ts +85 -0
- package/transport/sdk/domains/platform.ts +19 -0
- package/transport/sdk/domains/plugin.ts +144 -0
- package/transport/sdk/domains/settings.ts +92 -0
- package/transport/sdk/domains/update.ts +64 -0
- package/transport/sdk/index.ts +60 -0
- package/transport/sdk/main-transport.ts +710 -0
- package/transport/sdk/main.ts +9 -0
- package/transport/sdk/plugin-transport.ts +654 -0
- package/transport/sdk/port-policy.ts +38 -0
- package/transport/sdk/renderer-transport.ts +1165 -0
- package/transport/types.ts +605 -0
- package/types/agent.ts +399 -0
- package/types/cloud-sync.ts +157 -0
- package/types/division-box.ts +47 -27
- package/types/download.ts +1 -0
- package/types/flow.ts +63 -12
- package/types/icon.ts +2 -1
- package/types/index.ts +5 -0
- package/types/intelligence.ts +1492 -81
- package/types/modules/base.ts +2 -0
- package/types/path-browserify.d.ts +5 -0
- package/types/platform.ts +12 -0
- package/types/startup-info.ts +32 -0
- package/types/touch-app-core.ts +8 -8
- package/types/update.ts +94 -1
- package/vitest.config.ts +25 -0
- package/auth/useClerkConfig.ts +0 -40
- package/auth/useClerkProvider.ts +0 -52
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LoggerManager
|
|
3
|
+
*
|
|
4
|
+
* Singleton manager for all module loggers.
|
|
5
|
+
* Handles configuration, global controls, and logger lifecycle.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { LoggerInfo, LoggingConfig, ModuleLoggerOptions } from './types'
|
|
9
|
+
import { ModuleLogger } from './module-logger'
|
|
10
|
+
import {
|
|
11
|
+
|
|
12
|
+
LogLevel,
|
|
13
|
+
logLevelToString,
|
|
14
|
+
|
|
15
|
+
stringToLogLevel,
|
|
16
|
+
} from './types'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Default logging configuration
|
|
20
|
+
*/
|
|
21
|
+
const DEFAULT_CONFIG: LoggingConfig = {
|
|
22
|
+
enabled: true,
|
|
23
|
+
globalLevel: 'debug',
|
|
24
|
+
modules: {},
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Predefined module defaults
|
|
29
|
+
*/
|
|
30
|
+
const MODULE_DEFAULTS: Record<string, { enabled: boolean, level: LogLevel, color: string }> = {
|
|
31
|
+
'search-engine': { enabled: true, level: LogLevel.DEBUG, color: 'cyan' },
|
|
32
|
+
'file-provider': { enabled: false, level: LogLevel.DEBUG, color: 'green' },
|
|
33
|
+
'app-provider': { enabled: false, level: LogLevel.DEBUG, color: 'blue' },
|
|
34
|
+
'plugin-system': { enabled: true, level: LogLevel.INFO, color: 'magenta' },
|
|
35
|
+
'database': { enabled: false, level: LogLevel.WARN, color: 'yellow' },
|
|
36
|
+
'storage': { enabled: false, level: LogLevel.WARN, color: 'yellow' },
|
|
37
|
+
'clipboard': { enabled: false, level: LogLevel.INFO, color: 'cyan' },
|
|
38
|
+
'flow-bus': { enabled: true, level: LogLevel.INFO, color: 'green' },
|
|
39
|
+
'division-box': { enabled: true, level: LogLevel.INFO, color: 'blue' },
|
|
40
|
+
'channel-core': { enabled: true, level: LogLevel.INFO, color: 'cyan' },
|
|
41
|
+
'core-box': { enabled: true, level: LogLevel.INFO, color: 'cyan' },
|
|
42
|
+
'tray': { enabled: false, level: LogLevel.INFO, color: 'gray' },
|
|
43
|
+
'download': { enabled: true, level: LogLevel.INFO, color: 'green' },
|
|
44
|
+
'intelligence': { enabled: true, level: LogLevel.INFO, color: 'magenta' },
|
|
45
|
+
'terminal': { enabled: false, level: LogLevel.DEBUG, color: 'gray' },
|
|
46
|
+
'update': { enabled: true, level: LogLevel.INFO, color: 'blue' },
|
|
47
|
+
'widget': { enabled: true, level: LogLevel.DEBUG, color: 'cyan' },
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* LoggerManager singleton
|
|
52
|
+
*
|
|
53
|
+
* Manages all module loggers with:
|
|
54
|
+
* - Centralized configuration
|
|
55
|
+
* - Global enable/disable
|
|
56
|
+
* - Per-module level control
|
|
57
|
+
* - Configuration persistence
|
|
58
|
+
*/
|
|
59
|
+
export class LoggerManager {
|
|
60
|
+
private static instance: LoggerManager | null = null
|
|
61
|
+
private loggers: Map<string, ModuleLogger> = new Map()
|
|
62
|
+
private config: LoggingConfig = { ...DEFAULT_CONFIG }
|
|
63
|
+
private configLoader: (() => Promise<LoggingConfig | null>) | null = null
|
|
64
|
+
private configSaver: ((config: LoggingConfig) => Promise<void>) | null = null
|
|
65
|
+
|
|
66
|
+
private constructor() {}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get singleton instance
|
|
70
|
+
*/
|
|
71
|
+
static getInstance(): LoggerManager {
|
|
72
|
+
if (!LoggerManager.instance) {
|
|
73
|
+
LoggerManager.instance = new LoggerManager()
|
|
74
|
+
}
|
|
75
|
+
return LoggerManager.instance
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get or create a logger for a module
|
|
80
|
+
*/
|
|
81
|
+
getLogger(module: string, options?: Partial<ModuleLoggerOptions>): ModuleLogger {
|
|
82
|
+
let logger = this.loggers.get(module)
|
|
83
|
+
|
|
84
|
+
if (!logger) {
|
|
85
|
+
// Get module defaults
|
|
86
|
+
const defaults = MODULE_DEFAULTS[module]
|
|
87
|
+
const moduleConfig = this.config.modules[module]
|
|
88
|
+
|
|
89
|
+
// Determine enabled state
|
|
90
|
+
let enabled = this.config.enabled
|
|
91
|
+
if (moduleConfig?.enabled !== undefined) {
|
|
92
|
+
enabled = enabled && moduleConfig.enabled
|
|
93
|
+
}
|
|
94
|
+
else if (defaults?.enabled !== undefined) {
|
|
95
|
+
enabled = enabled && defaults.enabled
|
|
96
|
+
}
|
|
97
|
+
if (options?.enabled !== undefined) {
|
|
98
|
+
enabled = enabled && options.enabled
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Determine log level
|
|
102
|
+
let level = stringToLogLevel(this.config.globalLevel)
|
|
103
|
+
if (moduleConfig?.level) {
|
|
104
|
+
level = Math.max(level, stringToLogLevel(moduleConfig.level))
|
|
105
|
+
}
|
|
106
|
+
else if (defaults?.level !== undefined) {
|
|
107
|
+
level = Math.max(level, defaults.level)
|
|
108
|
+
}
|
|
109
|
+
if (options?.level !== undefined) {
|
|
110
|
+
level = options.level
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Determine color
|
|
114
|
+
const color = options?.color ?? defaults?.color ?? 'cyan'
|
|
115
|
+
|
|
116
|
+
logger = new ModuleLogger({
|
|
117
|
+
module,
|
|
118
|
+
color,
|
|
119
|
+
enabled,
|
|
120
|
+
level,
|
|
121
|
+
prefix: options?.prefix,
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
this.loggers.set(module, logger)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return logger
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Enable all loggers
|
|
132
|
+
*/
|
|
133
|
+
enableAll(): void {
|
|
134
|
+
this.config.enabled = true
|
|
135
|
+
for (const logger of this.loggers.values()) {
|
|
136
|
+
logger.setEnabled(true)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Disable all loggers
|
|
142
|
+
*/
|
|
143
|
+
disableAll(): void {
|
|
144
|
+
this.config.enabled = false
|
|
145
|
+
for (const logger of this.loggers.values()) {
|
|
146
|
+
logger.setEnabled(false)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Set global log level
|
|
152
|
+
*/
|
|
153
|
+
setGlobalLevel(level: LogLevel): void {
|
|
154
|
+
this.config.globalLevel = logLevelToString(level)
|
|
155
|
+
for (const logger of this.loggers.values()) {
|
|
156
|
+
if (logger.getLevel() < level) {
|
|
157
|
+
logger.setLevel(level)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Set module-specific configuration
|
|
164
|
+
*/
|
|
165
|
+
setModuleConfig(module: string, enabled: boolean, level: LogLevel): void {
|
|
166
|
+
this.config.modules[module] = {
|
|
167
|
+
enabled,
|
|
168
|
+
level: logLevelToString(level),
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const logger = this.loggers.get(module)
|
|
172
|
+
if (logger) {
|
|
173
|
+
logger.setEnabled(this.config.enabled && enabled)
|
|
174
|
+
logger.setLevel(level)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* List all registered loggers
|
|
180
|
+
*/
|
|
181
|
+
listLoggers(): LoggerInfo[] {
|
|
182
|
+
return Array.from(this.loggers.entries()).map(([module, logger]) => ({
|
|
183
|
+
module,
|
|
184
|
+
enabled: logger.isEnabled(),
|
|
185
|
+
level: logger.getLevel(),
|
|
186
|
+
color: logger.getColor(),
|
|
187
|
+
}))
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get current configuration
|
|
192
|
+
*/
|
|
193
|
+
getConfig(): LoggingConfig {
|
|
194
|
+
return { ...this.config }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Set configuration
|
|
199
|
+
*/
|
|
200
|
+
setConfig(config: Partial<LoggingConfig>): void {
|
|
201
|
+
this.config = { ...this.config, ...config }
|
|
202
|
+
this.applyConfig()
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Set config loader function
|
|
207
|
+
*/
|
|
208
|
+
setConfigLoader(loader: () => Promise<LoggingConfig | null>): void {
|
|
209
|
+
this.configLoader = loader
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Set config saver function
|
|
214
|
+
*/
|
|
215
|
+
setConfigSaver(saver: (config: LoggingConfig) => Promise<void>): void {
|
|
216
|
+
this.configSaver = saver
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Load configuration from storage
|
|
221
|
+
*/
|
|
222
|
+
async loadConfig(): Promise<void> {
|
|
223
|
+
if (!this.configLoader)
|
|
224
|
+
return
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
const loaded = await this.configLoader()
|
|
228
|
+
if (loaded) {
|
|
229
|
+
this.config = { ...DEFAULT_CONFIG, ...loaded }
|
|
230
|
+
this.applyConfig()
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
console.error('[LoggerManager] Failed to load config:', error)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Save configuration to storage
|
|
240
|
+
*/
|
|
241
|
+
async saveConfig(): Promise<void> {
|
|
242
|
+
if (!this.configSaver)
|
|
243
|
+
return
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
await this.configSaver(this.config)
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
console.error('[LoggerManager] Failed to save config:', error)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Apply current configuration to all loggers
|
|
255
|
+
*/
|
|
256
|
+
private applyConfig(): void {
|
|
257
|
+
for (const [module, logger] of this.loggers) {
|
|
258
|
+
const moduleConfig = this.config.modules[module]
|
|
259
|
+
const defaults = MODULE_DEFAULTS[module]
|
|
260
|
+
|
|
261
|
+
// Determine enabled state
|
|
262
|
+
let enabled = this.config.enabled
|
|
263
|
+
if (moduleConfig?.enabled !== undefined) {
|
|
264
|
+
enabled = enabled && moduleConfig.enabled
|
|
265
|
+
}
|
|
266
|
+
else if (defaults?.enabled !== undefined) {
|
|
267
|
+
enabled = enabled && defaults.enabled
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Determine log level
|
|
271
|
+
let level = stringToLogLevel(this.config.globalLevel)
|
|
272
|
+
if (moduleConfig?.level) {
|
|
273
|
+
level = Math.max(level, stringToLogLevel(moduleConfig.level))
|
|
274
|
+
}
|
|
275
|
+
else if (defaults?.level !== undefined) {
|
|
276
|
+
level = Math.max(level, defaults.level)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
logger.setEnabled(enabled)
|
|
280
|
+
logger.setLevel(level)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Reset to default configuration
|
|
286
|
+
*/
|
|
287
|
+
reset(): void {
|
|
288
|
+
this.config = { ...DEFAULT_CONFIG }
|
|
289
|
+
this.applyConfig()
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Singleton instance
|
|
295
|
+
*/
|
|
296
|
+
export const loggerManager = LoggerManager.getInstance()
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Shorthand for getting a logger
|
|
300
|
+
*/
|
|
301
|
+
export function getLogger(module: string, options?: Partial<ModuleLoggerOptions>): ModuleLogger {
|
|
302
|
+
return loggerManager.getLogger(module, options)
|
|
303
|
+
}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModuleLogger
|
|
3
|
+
*
|
|
4
|
+
* Provides structured, configurable logging for individual modules.
|
|
5
|
+
* Supports log levels, timing, grouping, and zero-overhead when disabled.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ModuleLoggerOptions } from './types'
|
|
9
|
+
import { LogLevel } from './types'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* ANSI color codes for terminal output
|
|
13
|
+
*/
|
|
14
|
+
const COLORS: Record<string, string> = {
|
|
15
|
+
reset: '\x1B[0m',
|
|
16
|
+
gray: '\x1B[90m',
|
|
17
|
+
red: '\x1B[31m',
|
|
18
|
+
green: '\x1B[32m',
|
|
19
|
+
yellow: '\x1B[33m',
|
|
20
|
+
blue: '\x1B[34m',
|
|
21
|
+
magenta: '\x1B[35m',
|
|
22
|
+
cyan: '\x1B[36m',
|
|
23
|
+
white: '\x1B[37m',
|
|
24
|
+
bgRed: '\x1B[41m',
|
|
25
|
+
bgGreen: '\x1B[42m',
|
|
26
|
+
bgYellow: '\x1B[43m',
|
|
27
|
+
bgBlue: '\x1B[44m',
|
|
28
|
+
bgMagenta: '\x1B[45m',
|
|
29
|
+
bgCyan: '\x1B[46m',
|
|
30
|
+
bold: '\x1B[1m',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Level color mapping
|
|
35
|
+
*/
|
|
36
|
+
const LEVEL_COLORS: Record<LogLevel, string> = {
|
|
37
|
+
[LogLevel.DEBUG]: 'gray',
|
|
38
|
+
[LogLevel.INFO]: 'blue',
|
|
39
|
+
[LogLevel.WARN]: 'yellow',
|
|
40
|
+
[LogLevel.ERROR]: 'red',
|
|
41
|
+
[LogLevel.NONE]: 'white',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Level labels
|
|
46
|
+
*/
|
|
47
|
+
const LEVEL_LABELS: Record<LogLevel, string> = {
|
|
48
|
+
[LogLevel.DEBUG]: 'DEBUG',
|
|
49
|
+
[LogLevel.INFO]: 'INFO ',
|
|
50
|
+
[LogLevel.WARN]: 'WARN ',
|
|
51
|
+
[LogLevel.ERROR]: 'ERROR',
|
|
52
|
+
[LogLevel.NONE]: 'NONE ',
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* ModuleLogger class
|
|
57
|
+
*
|
|
58
|
+
* Provides logging capabilities with:
|
|
59
|
+
* - Log levels (debug, info, warn, error)
|
|
60
|
+
* - Enable/disable per module
|
|
61
|
+
* - Timing functions
|
|
62
|
+
* - Grouping support
|
|
63
|
+
* - Zero overhead when disabled
|
|
64
|
+
*/
|
|
65
|
+
export class ModuleLogger {
|
|
66
|
+
private readonly module: string
|
|
67
|
+
private readonly color: string
|
|
68
|
+
private readonly prefix: string
|
|
69
|
+
private enabled: boolean
|
|
70
|
+
private level: LogLevel
|
|
71
|
+
private timers: Map<string, number> = new Map()
|
|
72
|
+
private groupDepth = 0
|
|
73
|
+
|
|
74
|
+
constructor(options: ModuleLoggerOptions) {
|
|
75
|
+
this.module = options.module
|
|
76
|
+
this.color = options.color ?? 'cyan'
|
|
77
|
+
this.prefix = options.prefix ?? ''
|
|
78
|
+
this.enabled = options.enabled ?? true
|
|
79
|
+
this.level = options.level ?? LogLevel.DEBUG
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Check if logger is enabled
|
|
84
|
+
*/
|
|
85
|
+
isEnabled(): boolean {
|
|
86
|
+
return this.enabled
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get current log level
|
|
91
|
+
*/
|
|
92
|
+
getLevel(): LogLevel {
|
|
93
|
+
return this.level
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get module name
|
|
98
|
+
*/
|
|
99
|
+
getModule(): string {
|
|
100
|
+
return this.module
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Get color
|
|
105
|
+
*/
|
|
106
|
+
getColor(): string {
|
|
107
|
+
return this.color
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Set enabled state
|
|
112
|
+
*/
|
|
113
|
+
setEnabled(enabled: boolean): void {
|
|
114
|
+
this.enabled = enabled
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Set log level
|
|
119
|
+
*/
|
|
120
|
+
setLevel(level: LogLevel): void {
|
|
121
|
+
this.level = level
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Log debug message
|
|
126
|
+
*/
|
|
127
|
+
debug(message: string, ...args: unknown[]): void {
|
|
128
|
+
this.log(LogLevel.DEBUG, message, ...args)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Log info message
|
|
133
|
+
*/
|
|
134
|
+
info(message: string, ...args: unknown[]): void {
|
|
135
|
+
this.log(LogLevel.INFO, message, ...args)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Log warning message
|
|
140
|
+
*/
|
|
141
|
+
warn(message: string, ...args: unknown[]): void {
|
|
142
|
+
this.log(LogLevel.WARN, message, ...args)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Log error message
|
|
147
|
+
*/
|
|
148
|
+
error(message: string, ...args: unknown[]): void {
|
|
149
|
+
this.log(LogLevel.ERROR, message, ...args)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Start a timer
|
|
154
|
+
*/
|
|
155
|
+
time(label: string): void {
|
|
156
|
+
if (!this.shouldLog(LogLevel.DEBUG))
|
|
157
|
+
return
|
|
158
|
+
this.timers.set(label, performance.now())
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* End a timer and log duration
|
|
163
|
+
*/
|
|
164
|
+
timeEnd(label: string): number {
|
|
165
|
+
if (!this.shouldLog(LogLevel.DEBUG))
|
|
166
|
+
return 0
|
|
167
|
+
const start = this.timers.get(label)
|
|
168
|
+
if (start === undefined) {
|
|
169
|
+
this.warn(`Timer "${label}" does not exist`)
|
|
170
|
+
return 0
|
|
171
|
+
}
|
|
172
|
+
this.timers.delete(label)
|
|
173
|
+
const duration = performance.now() - start
|
|
174
|
+
this.debug(`${label}: ${duration.toFixed(2)}ms`)
|
|
175
|
+
return duration
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Start a log group
|
|
180
|
+
*/
|
|
181
|
+
group(label: string): void {
|
|
182
|
+
if (!this.shouldLog(LogLevel.DEBUG))
|
|
183
|
+
return
|
|
184
|
+
this.info(label)
|
|
185
|
+
this.groupDepth++
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* End a log group
|
|
190
|
+
*/
|
|
191
|
+
groupEnd(): void {
|
|
192
|
+
if (this.groupDepth > 0) {
|
|
193
|
+
this.groupDepth--
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Create a child logger with a sub-module prefix
|
|
199
|
+
*/
|
|
200
|
+
child(subModule: string): ModuleLogger {
|
|
201
|
+
return new ModuleLogger({
|
|
202
|
+
module: `${this.module}:${subModule}`,
|
|
203
|
+
color: this.color,
|
|
204
|
+
enabled: this.enabled,
|
|
205
|
+
level: this.level,
|
|
206
|
+
prefix: this.prefix,
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Check if a level should be logged
|
|
212
|
+
*/
|
|
213
|
+
private shouldLog(level: LogLevel): boolean {
|
|
214
|
+
return this.enabled && level >= this.level
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Core logging method
|
|
219
|
+
*/
|
|
220
|
+
private log(level: LogLevel, message: string, ...args: unknown[]): void {
|
|
221
|
+
if (!this.shouldLog(level))
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
const timestamp = this.formatTimestamp()
|
|
225
|
+
const levelLabel = LEVEL_LABELS[level]
|
|
226
|
+
const levelColor = COLORS[LEVEL_COLORS[level]] ?? ''
|
|
227
|
+
const moduleColor = COLORS[this.color] ?? ''
|
|
228
|
+
const reset = COLORS.reset
|
|
229
|
+
|
|
230
|
+
// Build indent for groups
|
|
231
|
+
const indent = ' '.repeat(this.groupDepth)
|
|
232
|
+
|
|
233
|
+
// Format: [HH:MM:SS.mmm] [module] LEVEL message
|
|
234
|
+
const formattedModule = `${moduleColor}[${this.module}]${reset}`
|
|
235
|
+
const formattedLevel = `${levelColor}${levelLabel}${reset}`
|
|
236
|
+
const formattedMessage = `${indent}${message}`
|
|
237
|
+
|
|
238
|
+
const output = `${COLORS.gray}[${timestamp}]${reset} ${formattedModule} ${formattedLevel} ${formattedMessage}`
|
|
239
|
+
|
|
240
|
+
// Use appropriate console method
|
|
241
|
+
switch (level) {
|
|
242
|
+
case LogLevel.DEBUG:
|
|
243
|
+
console.debug(output, ...args)
|
|
244
|
+
break
|
|
245
|
+
case LogLevel.INFO:
|
|
246
|
+
console.info(output, ...args)
|
|
247
|
+
break
|
|
248
|
+
case LogLevel.WARN:
|
|
249
|
+
console.warn(output, ...args)
|
|
250
|
+
break
|
|
251
|
+
case LogLevel.ERROR:
|
|
252
|
+
console.error(output, ...args)
|
|
253
|
+
break
|
|
254
|
+
default:
|
|
255
|
+
console.log(output, ...args)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Format timestamp as HH:MM:SS.mmm
|
|
261
|
+
*/
|
|
262
|
+
private formatTimestamp(): string {
|
|
263
|
+
const now = new Date()
|
|
264
|
+
const hours = now.getHours().toString().padStart(2, '0')
|
|
265
|
+
const minutes = now.getMinutes().toString().padStart(2, '0')
|
|
266
|
+
const seconds = now.getSeconds().toString().padStart(2, '0')
|
|
267
|
+
const ms = now.getMilliseconds().toString().padStart(3, '0')
|
|
268
|
+
return `${hours}:${minutes}:${seconds}.${ms}`
|
|
269
|
+
}
|
|
270
|
+
}
|