@vlian/framework 1.2.37 → 1.2.38
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/dist/analytics.umd.js +1 -1
- package/dist/core/Test.cjs +2 -2
- package/dist/core/Test.cjs.map +1 -1
- package/dist/core/Test.js +1 -1
- package/dist/core/Test.js.map +1 -1
- package/dist/core/config/ConfigLoader.cjs +7 -7
- package/dist/core/config/ConfigLoader.cjs.map +1 -1
- package/dist/core/config/ConfigLoader.js +1 -1
- package/dist/core/config/ConfigLoader.js.map +1 -1
- package/dist/core/error/ErrorBoundary.cjs +6 -6
- package/dist/core/error/ErrorBoundary.cjs.map +1 -1
- package/dist/core/error/ErrorBoundary.d.ts +1 -1
- package/dist/core/error/ErrorBoundary.js +2 -2
- package/dist/core/error/ErrorBoundary.js.map +1 -1
- package/dist/core/error/ErrorHandler.cjs +19 -19
- package/dist/core/error/ErrorHandler.cjs.map +1 -1
- package/dist/core/error/ErrorHandler.d.ts +1 -1
- package/dist/core/error/ErrorHandler.js +2 -2
- package/dist/core/error/ErrorHandler.js.map +1 -1
- package/dist/core/event/AppEventBus.cjs +5 -5
- package/dist/core/event/AppEventBus.cjs.map +1 -1
- package/dist/core/event/AppEventBus.js +1 -1
- package/dist/core/event/AppEventBus.js.map +1 -1
- package/dist/core/initialization/InitializationErrorThrower.cjs.map +1 -1
- package/dist/core/initialization/InitializationErrorThrower.js.map +1 -1
- package/dist/core/initialization/initialization.cjs +3 -3
- package/dist/core/initialization/initialization.cjs.map +1 -1
- package/dist/core/initialization/initialization.d.ts +1 -1
- package/dist/core/initialization/initialization.js +1 -1
- package/dist/core/initialization/initialization.js.map +1 -1
- package/dist/core/initialization/initializationErrorState.cjs +2 -2
- package/dist/core/initialization/initializationErrorState.cjs.map +1 -1
- package/dist/core/initialization/initializationErrorState.d.ts +1 -1
- package/dist/core/initialization/initializationErrorState.js +1 -1
- package/dist/core/initialization/initializationErrorState.js.map +1 -1
- package/dist/core/kernel/defaultAdapters.cjs +14 -13
- package/dist/core/kernel/defaultAdapters.cjs.map +1 -1
- package/dist/core/kernel/defaultAdapters.js +2 -1
- package/dist/core/kernel/defaultAdapters.js.map +1 -1
- package/dist/core/kernel/types.d.ts +1 -1
- package/dist/core/kernel/types.js.map +1 -1
- package/dist/core/router/RouterManager.cjs +9 -9
- package/dist/core/router/RouterManager.cjs.map +1 -1
- package/dist/core/router/RouterManager.js +1 -1
- package/dist/core/router/RouterManager.js.map +1 -1
- package/dist/core/router/adapter/AdapterManager.cjs +10 -10
- package/dist/core/router/adapter/AdapterManager.cjs.map +1 -1
- package/dist/core/router/adapter/AdapterManager.js +1 -1
- package/dist/core/router/adapter/AdapterManager.js.map +1 -1
- package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs +4 -4
- package/dist/core/router/adapter/react-router/ReactRouterAdapter.cjs.map +1 -1
- package/dist/core/router/adapter/react-router/ReactRouterAdapter.js +1 -1
- package/dist/core/router/adapter/react-router/ReactRouterAdapter.js.map +1 -1
- package/dist/core/router/dynamic/DynamicRouteManager.cjs +8 -8
- package/dist/core/router/dynamic/DynamicRouteManager.cjs.map +1 -1
- package/dist/core/router/dynamic/DynamicRouteManager.js +1 -1
- package/dist/core/router/dynamic/DynamicRouteManager.js.map +1 -1
- package/dist/core/router/errors/RouterError.cjs +4 -4
- package/dist/core/router/errors/RouterError.cjs.map +1 -1
- package/dist/core/router/errors/RouterError.d.ts +1 -1
- package/dist/core/router/errors/RouterError.js +1 -1
- package/dist/core/router/errors/RouterError.js.map +1 -1
- package/dist/core/router/lifecycle/RouterLifecycleManager.cjs +8 -8
- package/dist/core/router/lifecycle/RouterLifecycleManager.cjs.map +1 -1
- package/dist/core/router/lifecycle/RouterLifecycleManager.js +1 -1
- package/dist/core/router/lifecycle/RouterLifecycleManager.js.map +1 -1
- package/dist/core/router/middleware/RouterMiddlewareManager.cjs +11 -11
- package/dist/core/router/middleware/RouterMiddlewareManager.cjs.map +1 -1
- package/dist/core/router/middleware/RouterMiddlewareManager.js +1 -1
- package/dist/core/router/middleware/RouterMiddlewareManager.js.map +1 -1
- package/dist/core/router/middleware/auth.cjs +4 -4
- package/dist/core/router/middleware/auth.cjs.map +1 -1
- package/dist/core/router/middleware/auth.js +1 -1
- package/dist/core/router/middleware/auth.js.map +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.cjs +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.cjs.map +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.js +1 -1
- package/dist/core/router/monitoring/RouterMonitoring.js.map +1 -1
- package/dist/core/router/navigation/RouterNavigation.cjs +7 -7
- package/dist/core/router/navigation/RouterNavigation.cjs.map +1 -1
- package/dist/core/router/navigation/RouterNavigation.js +1 -1
- package/dist/core/router/navigation/RouterNavigation.js.map +1 -1
- package/dist/core/router/performance/RouteCache.cjs +7 -7
- package/dist/core/router/performance/RouteCache.cjs.map +1 -1
- package/dist/core/router/performance/RouteCache.js +1 -1
- package/dist/core/router/performance/RouteCache.js.map +1 -1
- package/dist/core/router/performance/RoutePreloader.cjs +6 -6
- package/dist/core/router/performance/RoutePreloader.cjs.map +1 -1
- package/dist/core/router/performance/RoutePreloader.js +1 -1
- package/dist/core/router/performance/RoutePreloader.js.map +1 -1
- package/dist/core/router/plugin/RouterPluginManager.cjs +8 -8
- package/dist/core/router/plugin/RouterPluginManager.cjs.map +1 -1
- package/dist/core/router/plugin/RouterPluginManager.js +1 -1
- package/dist/core/router/plugin/RouterPluginManager.js.map +1 -1
- package/dist/core/router/utils/adapters/react-router/transform.cjs +2 -2
- package/dist/core/router/utils/adapters/react-router/transform.cjs.map +1 -1
- package/dist/core/router/utils/adapters/react-router/transform.js +1 -1
- package/dist/core/router/utils/adapters/react-router/transform.js.map +1 -1
- package/dist/core/router/utils/transform.cjs +13 -12
- package/dist/core/router/utils/transform.cjs.map +1 -1
- package/dist/core/router/utils/transform.js +2 -1
- package/dist/core/router/utils/transform.js.map +1 -1
- package/dist/core/router/validation/RouterConfigValidator.cjs +2 -2
- package/dist/core/router/validation/RouterConfigValidator.cjs.map +1 -1
- package/dist/core/router/validation/RouterConfigValidator.js +1 -1
- package/dist/core/router/validation/RouterConfigValidator.js.map +1 -1
- package/dist/core/router/version/RouteVersionManager.cjs +6 -6
- package/dist/core/router/version/RouteVersionManager.cjs.map +1 -1
- package/dist/core/router/version/RouteVersionManager.js +1 -1
- package/dist/core/router/version/RouteVersionManager.js.map +1 -1
- package/dist/core/splash/SplashScreen.cjs +4 -4
- package/dist/core/splash/SplashScreen.cjs.map +1 -1
- package/dist/core/splash/SplashScreen.js +1 -1
- package/dist/core/splash/SplashScreen.js.map +1 -1
- package/dist/core/startup/initializeServices.cjs +14 -14
- package/dist/core/startup/initializeServices.cjs.map +1 -1
- package/dist/core/startup/initializeServices.d.ts +1 -1
- package/dist/core/startup/initializeServices.js +2 -2
- package/dist/core/startup/initializeServices.js.map +1 -1
- package/dist/core/startup/renderApp.cjs +2 -2
- package/dist/core/startup/renderApp.cjs.map +1 -1
- package/dist/core/startup/renderApp.js +1 -1
- package/dist/core/startup/renderApp.js.map +1 -1
- package/dist/core/startup/startApp.cjs +22 -22
- package/dist/core/startup/startApp.cjs.map +1 -1
- package/dist/core/startup/startApp.js +2 -2
- package/dist/core/startup/startApp.js.map +1 -1
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js.map +1 -1
- package/dist/index.umd.js +1394 -1401
- package/dist/index.umd.js.map +1 -1
- package/dist/kernel/constants.cjs +2 -2
- package/dist/kernel/constants.cjs.map +1 -1
- package/dist/kernel/constants.js +1 -1
- package/dist/kernel/constants.js.map +1 -1
- package/dist/kernel/manager/loggerManager.cjs +10 -10
- package/dist/kernel/manager/loggerManager.cjs.map +1 -1
- package/dist/kernel/manager/loggerManager.d.ts +1 -1
- package/dist/kernel/manager/loggerManager.js +1 -1
- package/dist/kernel/manager/loggerManager.js.map +1 -1
- package/dist/kernel/types.d.ts +1 -1
- package/dist/kernel/types.js.map +1 -1
- package/dist/library/storage/encryption.cjs +12 -13
- package/dist/library/storage/encryption.cjs.map +1 -1
- package/dist/library/storage/encryption.js +1 -2
- package/dist/library/storage/encryption.js.map +1 -1
- package/dist/state.umd.js +1 -1
- package/dist/utils/errors.cjs +71 -15
- package/dist/utils/errors.cjs.map +1 -1
- package/dist/utils/errors.d.ts +30 -1
- package/dist/utils/errors.js +16 -1
- package/dist/utils/errors.js.map +1 -1
- package/package.json +1 -1
|
@@ -29,8 +29,8 @@ _export(exports, {
|
|
|
29
29
|
return setDefaultErrorHandler;
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
|
-
const
|
|
33
|
-
const
|
|
32
|
+
const _logger = require("@vlian/logger");
|
|
33
|
+
const _utils = require("@vlian/utils");
|
|
34
34
|
function _define_property(obj, key, value) {
|
|
35
35
|
if (key in obj) {
|
|
36
36
|
Object.defineProperty(obj, key, {
|
|
@@ -76,9 +76,9 @@ let ErrorHandler = class ErrorHandler {
|
|
|
76
76
|
* @returns 错误处理结果
|
|
77
77
|
*/ async handleError(error, context) {
|
|
78
78
|
// 标准化错误对象
|
|
79
|
-
const normalizedError =
|
|
79
|
+
const normalizedError = _utils.errorUtils.normalizeError(error);
|
|
80
80
|
// 创建包含上下文信息的错误对象(由于 context 是只读的,需要创建新对象)
|
|
81
|
-
const errorWithContext = context ? new
|
|
81
|
+
const errorWithContext = context ? new _utils.FrameworkError(normalizedError.message, normalizedError.type, normalizedError.severity, {
|
|
82
82
|
code: normalizedError.code,
|
|
83
83
|
originalError: normalizedError.originalError,
|
|
84
84
|
context: {
|
|
@@ -150,7 +150,7 @@ let ErrorHandler = class ErrorHandler {
|
|
|
150
150
|
break;
|
|
151
151
|
}
|
|
152
152
|
} catch (strategyError) {
|
|
153
|
-
|
|
153
|
+
_logger.logger.warn(`错误处理策略 ${strategy} 执行失败:`, strategyError);
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
return handled;
|
|
@@ -158,23 +158,23 @@ let ErrorHandler = class ErrorHandler {
|
|
|
158
158
|
/**
|
|
159
159
|
* 记录错误
|
|
160
160
|
*/ logError(error) {
|
|
161
|
-
const errorInfo =
|
|
161
|
+
const errorInfo = _utils.errorUtils.extractErrorInfo(error);
|
|
162
162
|
// 根据错误严重程度选择日志级别
|
|
163
163
|
switch(error.severity){
|
|
164
|
-
case
|
|
165
|
-
case
|
|
166
|
-
|
|
164
|
+
case _utils.ErrorSeverity.CRITICAL:
|
|
165
|
+
case _utils.ErrorSeverity.HIGH:
|
|
166
|
+
_logger.logger.error('错误:', errorInfo);
|
|
167
167
|
break;
|
|
168
|
-
case
|
|
169
|
-
|
|
168
|
+
case _utils.ErrorSeverity.MEDIUM:
|
|
169
|
+
_logger.logger.warn('警告:', errorInfo);
|
|
170
170
|
break;
|
|
171
|
-
case
|
|
172
|
-
|
|
171
|
+
case _utils.ErrorSeverity.LOW:
|
|
172
|
+
_logger.logger.info('信息:', errorInfo);
|
|
173
173
|
break;
|
|
174
174
|
}
|
|
175
175
|
// 开发环境显示详细错误信息
|
|
176
176
|
if (this.config.showDetailedErrorsInDev && process.env.NODE_ENV === 'development') {
|
|
177
|
-
const detailedError =
|
|
177
|
+
const detailedError = _utils.errorUtils.formatErrorForDev(error);
|
|
178
178
|
console.error(detailedError);
|
|
179
179
|
}
|
|
180
180
|
}
|
|
@@ -182,7 +182,7 @@ let ErrorHandler = class ErrorHandler {
|
|
|
182
182
|
* 上报错误
|
|
183
183
|
*/ async reportError(error) {
|
|
184
184
|
if (!this.monitoring) {
|
|
185
|
-
|
|
185
|
+
_logger.logger.debug('监控服务未配置,跳过错误上报');
|
|
186
186
|
return;
|
|
187
187
|
}
|
|
188
188
|
try {
|
|
@@ -193,7 +193,7 @@ let ErrorHandler = class ErrorHandler {
|
|
|
193
193
|
context: error.context
|
|
194
194
|
});
|
|
195
195
|
} catch (reportError) {
|
|
196
|
-
|
|
196
|
+
_logger.logger.warn('错误上报失败:', reportError);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
/**
|
|
@@ -213,13 +213,13 @@ let ErrorHandler = class ErrorHandler {
|
|
|
213
213
|
if (options.fallback) {
|
|
214
214
|
try {
|
|
215
215
|
const fallbackValue = await Promise.resolve(options.fallback());
|
|
216
|
-
|
|
216
|
+
_logger.logger.info('错误已通过降级方案恢复');
|
|
217
217
|
return {
|
|
218
218
|
recoverable: true,
|
|
219
219
|
value: fallbackValue
|
|
220
220
|
};
|
|
221
221
|
} catch (fallbackError) {
|
|
222
|
-
|
|
222
|
+
_logger.logger.warn('降级方案执行失败:', fallbackError);
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
// 尝试重试(如果错误可恢复且满足重试条件)
|
|
@@ -229,7 +229,7 @@ let ErrorHandler = class ErrorHandler {
|
|
|
229
229
|
break;
|
|
230
230
|
}
|
|
231
231
|
const delay = exponentialBackoff ? retryDelay * Math.pow(2, attempt) : retryDelay;
|
|
232
|
-
|
|
232
|
+
_logger.logger.debug(`错误恢复重试 ${attempt + 1}/${maxRetries},${delay}ms 后重试...`);
|
|
233
233
|
await new Promise((resolve)=>setTimeout(resolve, delay));
|
|
234
234
|
// 这里应该调用原始操作的重试逻辑
|
|
235
235
|
// 由于错误处理器不知道原始操作,这里只返回可恢复状态
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/error/ErrorHandler.ts"],"sourcesContent":["/**\n * 统一错误处理器\n * \n * 优化:\n * 1. 统一错误处理策略:记录、上报、恢复、降级\n * 2. 错误分类:致命、可恢复、警告\n * 3. 错误恢复机制:自动重试、降级方案\n */\n\nimport { logger } from '../../utils';\nimport { errorUtils, ErrorSeverity, ErrorType, FrameworkError } from '../../utils/errors';\nimport type { MonitoringService } from '@vlian/monitoring';\n\n/**\n * 错误处理策略\n */\nexport enum ErrorHandlingStrategy {\n /**\n * 记录错误(日志)\n */\n LOG = 'LOG',\n /**\n * 上报错误(监控服务)\n */\n REPORT = 'REPORT',\n /**\n * 尝试恢复错误\n */\n RECOVER = 'RECOVER',\n /**\n * 降级处理\n */\n FALLBACK = 'FALLBACK',\n /**\n * 忽略错误\n */\n IGNORE = 'IGNORE',\n}\n\n/**\n * 错误恢复选项\n */\nexport interface ErrorRecoveryOptions {\n /**\n * 最大重试次数\n * @default 3\n */\n maxRetries?: number;\n /**\n * 重试延迟(毫秒)\n * @default 1000\n */\n retryDelay?: number;\n /**\n * 是否启用指数退避\n * @default true\n */\n exponentialBackoff?: boolean;\n /**\n * 重试条件函数\n */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n /**\n * 降级方案函数\n */\n fallback?: () => Promise<unknown> | unknown;\n}\n\n/**\n * 错误处理配置\n */\nexport interface ErrorHandlerConfig {\n /**\n * 监控服务实例(可选)\n */\n monitoring?: MonitoringService;\n /**\n * 默认错误处理策略\n * @default [ErrorHandlingStrategy.LOG, ErrorHandlingStrategy.REPORT]\n */\n defaultStrategies?: ErrorHandlingStrategy[];\n /**\n * 错误严重程度对应的处理策略\n */\n severityStrategies?: Partial<Record<ErrorSeverity, ErrorHandlingStrategy[]>>;\n /**\n * 错误类型对应的处理策略\n */\n typeStrategies?: Partial<Record<ErrorType, ErrorHandlingStrategy[]>>;\n /**\n * 错误恢复选项\n */\n recoveryOptions?: ErrorRecoveryOptions;\n /**\n * 是否在开发环境显示详细错误信息\n * @default true\n */\n showDetailedErrorsInDev?: boolean;\n}\n\n/**\n * 错误处理结果\n */\nexport interface ErrorHandleResult {\n /**\n * 是否已处理\n */\n handled: boolean;\n /**\n * 是否可恢复\n */\n recoverable: boolean;\n /**\n * 恢复后的结果(如果已恢复)\n */\n recoveredValue?: unknown;\n /**\n * 使用的处理策略\n */\n strategies: ErrorHandlingStrategy[];\n /**\n * 错误信息\n */\n error: FrameworkError;\n}\n\n/**\n * 统一错误处理器\n */\nexport class ErrorHandler {\n private config: Omit<Required<ErrorHandlerConfig>, 'monitoring'>;\n private monitoring?: MonitoringService;\n\n constructor(config: ErrorHandlerConfig = {}) {\n this.monitoring = config.monitoring;\n this.config = {\n defaultStrategies: config.defaultStrategies ?? [\n ErrorHandlingStrategy.LOG,\n ErrorHandlingStrategy.REPORT,\n ],\n severityStrategies: config.severityStrategies ?? {},\n typeStrategies: config.typeStrategies ?? {},\n recoveryOptions: config.recoveryOptions ?? {},\n showDetailedErrorsInDev: config.showDetailedErrorsInDev ?? true,\n };\n }\n\n /**\n * 设置监控服务\n */\n setMonitoring(monitoring: MonitoringService): void {\n this.monitoring = monitoring;\n }\n\n /**\n * 处理错误\n * \n * @param error - 错误对象\n * @param context - 错误上下文\n * @returns 错误处理结果\n */\n async handleError(\n error: unknown,\n context?: Record<string, unknown>\n ): Promise<ErrorHandleResult> {\n // 标准化错误对象\n const normalizedError = errorUtils.normalizeError(error);\n \n // 创建包含上下文信息的错误对象(由于 context 是只读的,需要创建新对象)\n const errorWithContext: FrameworkError = context\n ? new FrameworkError(\n normalizedError.message,\n normalizedError.type,\n normalizedError.severity,\n {\n code: normalizedError.code,\n originalError: normalizedError.originalError,\n context: {\n ...normalizedError.context,\n ...context,\n },\n recoverable: normalizedError.recoverable,\n }\n )\n : normalizedError;\n\n // 确定处理策略\n const strategies = this.determineStrategies(errorWithContext);\n \n // 执行处理策略\n const handled = await this.executeStrategies(errorWithContext, strategies);\n\n // 尝试恢复错误\n let recoveredValue: unknown | undefined;\n let recoverable = false;\n if (handled && errorWithContext.recoverable && this.config.recoveryOptions) {\n const recoveryResult = await this.attemptRecovery(errorWithContext);\n recoverable = recoveryResult.recoverable;\n recoveredValue = recoveryResult.value;\n }\n\n return {\n handled,\n recoverable,\n recoveredValue,\n strategies,\n error: errorWithContext,\n };\n }\n\n /**\n * 确定错误处理策略\n */\n private determineStrategies(error: FrameworkError): ErrorHandlingStrategy[] {\n // 1. 检查错误类型对应的策略\n if (this.config.typeStrategies[error.type]) {\n return this.config.typeStrategies[error.type]!;\n }\n\n // 2. 检查错误严重程度对应的策略\n if (this.config.severityStrategies[error.severity]) {\n return this.config.severityStrategies[error.severity]!;\n }\n\n // 3. 使用默认策略\n return this.config.defaultStrategies;\n }\n\n /**\n * 执行处理策略\n */\n private async executeStrategies(\n error: FrameworkError,\n strategies: ErrorHandlingStrategy[]\n ): Promise<boolean> {\n let handled = false;\n\n for (const strategy of strategies) {\n try {\n switch (strategy) {\n case ErrorHandlingStrategy.LOG:\n this.logError(error);\n handled = true;\n break;\n\n case ErrorHandlingStrategy.REPORT:\n await this.reportError(error);\n handled = true;\n break;\n\n case ErrorHandlingStrategy.RECOVER:\n // 恢复策略在 handleError 中统一处理\n handled = true;\n break;\n\n case ErrorHandlingStrategy.FALLBACK:\n // 降级策略在 attemptRecovery 中处理\n handled = true;\n break;\n\n case ErrorHandlingStrategy.IGNORE:\n // 忽略错误,不做任何处理\n handled = true;\n break;\n }\n } catch (strategyError) {\n logger.warn(`错误处理策略 ${strategy} 执行失败:`, strategyError);\n }\n }\n\n return handled;\n }\n\n /**\n * 记录错误\n */\n private logError(error: FrameworkError): void {\n const errorInfo = errorUtils.extractErrorInfo(error);\n \n // 根据错误严重程度选择日志级别\n switch (error.severity) {\n case ErrorSeverity.CRITICAL:\n case ErrorSeverity.HIGH:\n logger.error('错误:', errorInfo);\n break;\n case ErrorSeverity.MEDIUM:\n logger.warn('警告:', errorInfo);\n break;\n case ErrorSeverity.LOW:\n logger.info('信息:', errorInfo);\n break;\n }\n\n // 开发环境显示详细错误信息\n if (this.config.showDetailedErrorsInDev && process.env.NODE_ENV === 'development') {\n const detailedError = errorUtils.formatErrorForDev(error);\n console.error(detailedError);\n }\n }\n\n /**\n * 上报错误\n */\n private async reportError(error: FrameworkError): Promise<void> {\n if (!this.monitoring) {\n logger.debug('监控服务未配置,跳过错误上报');\n return;\n }\n\n try {\n this.monitoring.captureError(error, {\n severity: error.severity,\n type: error.type,\n code: error.code,\n context: error.context,\n });\n } catch (reportError) {\n logger.warn('错误上报失败:', reportError);\n }\n }\n\n /**\n * 尝试恢复错误\n */\n private async attemptRecovery(\n error: FrameworkError\n ): Promise<{ recoverable: boolean; value?: unknown }> {\n const options = this.config.recoveryOptions;\n if (!options) {\n return { recoverable: false };\n }\n\n const maxRetries = options.maxRetries ?? 3;\n const retryDelay = options.retryDelay ?? 1000;\n const exponentialBackoff = options.exponentialBackoff ?? true;\n const shouldRetry = options.shouldRetry ?? (() => true);\n\n // 如果有降级方案,先尝试降级\n if (options.fallback) {\n try {\n const fallbackValue = await Promise.resolve(options.fallback());\n logger.info('错误已通过降级方案恢复');\n return { recoverable: true, value: fallbackValue };\n } catch (fallbackError) {\n logger.warn('降级方案执行失败:', fallbackError);\n }\n }\n\n // 尝试重试(如果错误可恢复且满足重试条件)\n if (error.recoverable && shouldRetry(error, 0)) {\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n if (!shouldRetry(error, attempt)) {\n break;\n }\n\n const delay = exponentialBackoff\n ? retryDelay * Math.pow(2, attempt)\n : retryDelay;\n\n logger.debug(`错误恢复重试 ${attempt + 1}/${maxRetries},${delay}ms 后重试...`);\n\n await new Promise(resolve => setTimeout(resolve, delay));\n\n // 这里应该调用原始操作的重试逻辑\n // 由于错误处理器不知道原始操作,这里只返回可恢复状态\n // 实际的重试应该在调用方实现\n }\n }\n\n return { recoverable: error.recoverable };\n }\n\n /**\n * 创建错误处理器的便捷方法\n */\n static create(config?: ErrorHandlerConfig): ErrorHandler {\n return new ErrorHandler(config);\n }\n}\n\n/**\n * 默认错误处理器实例(单例)\n */\nlet defaultErrorHandler: ErrorHandler | null = null;\n\n/**\n * 获取默认错误处理器\n */\nexport function getDefaultErrorHandler(): ErrorHandler {\n if (!defaultErrorHandler) {\n defaultErrorHandler = new ErrorHandler();\n }\n return defaultErrorHandler;\n}\n\n/**\n * 设置默认错误处理器\n */\nexport function setDefaultErrorHandler(handler: ErrorHandler): void {\n defaultErrorHandler = handler;\n}\n"],"names":["ErrorHandler","ErrorHandlingStrategy","getDefaultErrorHandler","setDefaultErrorHandler","setMonitoring","monitoring","handleError","error","context","normalizedError","errorUtils","normalizeError","errorWithContext","FrameworkError","message","type","severity","code","originalError","recoverable","strategies","determineStrategies","handled","executeStrategies","recoveredValue","config","recoveryOptions","recoveryResult","attemptRecovery","value","typeStrategies","severityStrategies","defaultStrategies","strategy","logError","reportError","strategyError","logger","warn","errorInfo","extractErrorInfo","ErrorSeverity","CRITICAL","HIGH","MEDIUM","LOW","info","showDetailedErrorsInDev","process","env","NODE_ENV","detailedError","formatErrorForDev","console","debug","captureError","options","maxRetries","retryDelay","exponentialBackoff","shouldRetry","fallback","fallbackValue","Promise","resolve","fallbackError","attempt","delay","Math","pow","setTimeout","create","defaultErrorHandler","handler"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/error/ErrorHandler.ts"],"sourcesContent":["/**\n * 统一错误处理器\n * \n * 优化:\n * 1. 统一错误处理策略:记录、上报、恢复、降级\n * 2. 错误分类:致命、可恢复、警告\n * 3. 错误恢复机制:自动重试、降级方案\n */\n\nimport { logger } from '@vlian/logger';\nimport { errorUtils, ErrorSeverity, ErrorType, FrameworkError } from '@vlian/utils';\nimport type { MonitoringService } from '@vlian/monitoring';\n\n/**\n * 错误处理策略\n */\nexport enum ErrorHandlingStrategy {\n /**\n * 记录错误(日志)\n */\n LOG = 'LOG',\n /**\n * 上报错误(监控服务)\n */\n REPORT = 'REPORT',\n /**\n * 尝试恢复错误\n */\n RECOVER = 'RECOVER',\n /**\n * 降级处理\n */\n FALLBACK = 'FALLBACK',\n /**\n * 忽略错误\n */\n IGNORE = 'IGNORE',\n}\n\n/**\n * 错误恢复选项\n */\nexport interface ErrorRecoveryOptions {\n /**\n * 最大重试次数\n * @default 3\n */\n maxRetries?: number;\n /**\n * 重试延迟(毫秒)\n * @default 1000\n */\n retryDelay?: number;\n /**\n * 是否启用指数退避\n * @default true\n */\n exponentialBackoff?: boolean;\n /**\n * 重试条件函数\n */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n /**\n * 降级方案函数\n */\n fallback?: () => Promise<unknown> | unknown;\n}\n\n/**\n * 错误处理配置\n */\nexport interface ErrorHandlerConfig {\n /**\n * 监控服务实例(可选)\n */\n monitoring?: MonitoringService;\n /**\n * 默认错误处理策略\n * @default [ErrorHandlingStrategy.LOG, ErrorHandlingStrategy.REPORT]\n */\n defaultStrategies?: ErrorHandlingStrategy[];\n /**\n * 错误严重程度对应的处理策略\n */\n severityStrategies?: Partial<Record<ErrorSeverity, ErrorHandlingStrategy[]>>;\n /**\n * 错误类型对应的处理策略\n */\n typeStrategies?: Partial<Record<ErrorType, ErrorHandlingStrategy[]>>;\n /**\n * 错误恢复选项\n */\n recoveryOptions?: ErrorRecoveryOptions;\n /**\n * 是否在开发环境显示详细错误信息\n * @default true\n */\n showDetailedErrorsInDev?: boolean;\n}\n\n/**\n * 错误处理结果\n */\nexport interface ErrorHandleResult {\n /**\n * 是否已处理\n */\n handled: boolean;\n /**\n * 是否可恢复\n */\n recoverable: boolean;\n /**\n * 恢复后的结果(如果已恢复)\n */\n recoveredValue?: unknown;\n /**\n * 使用的处理策略\n */\n strategies: ErrorHandlingStrategy[];\n /**\n * 错误信息\n */\n error: FrameworkError;\n}\n\n/**\n * 统一错误处理器\n */\nexport class ErrorHandler {\n private config: Omit<Required<ErrorHandlerConfig>, 'monitoring'>;\n private monitoring?: MonitoringService;\n\n constructor(config: ErrorHandlerConfig = {}) {\n this.monitoring = config.monitoring;\n this.config = {\n defaultStrategies: config.defaultStrategies ?? [\n ErrorHandlingStrategy.LOG,\n ErrorHandlingStrategy.REPORT,\n ],\n severityStrategies: config.severityStrategies ?? {},\n typeStrategies: config.typeStrategies ?? {},\n recoveryOptions: config.recoveryOptions ?? {},\n showDetailedErrorsInDev: config.showDetailedErrorsInDev ?? true,\n };\n }\n\n /**\n * 设置监控服务\n */\n setMonitoring(monitoring: MonitoringService): void {\n this.monitoring = monitoring;\n }\n\n /**\n * 处理错误\n * \n * @param error - 错误对象\n * @param context - 错误上下文\n * @returns 错误处理结果\n */\n async handleError(\n error: unknown,\n context?: Record<string, unknown>\n ): Promise<ErrorHandleResult> {\n // 标准化错误对象\n const normalizedError = errorUtils.normalizeError(error);\n \n // 创建包含上下文信息的错误对象(由于 context 是只读的,需要创建新对象)\n const errorWithContext: FrameworkError = context\n ? new FrameworkError(\n normalizedError.message,\n normalizedError.type,\n normalizedError.severity,\n {\n code: normalizedError.code,\n originalError: normalizedError.originalError,\n context: {\n ...normalizedError.context,\n ...context,\n },\n recoverable: normalizedError.recoverable,\n }\n )\n : normalizedError;\n\n // 确定处理策略\n const strategies = this.determineStrategies(errorWithContext);\n \n // 执行处理策略\n const handled = await this.executeStrategies(errorWithContext, strategies);\n\n // 尝试恢复错误\n let recoveredValue: unknown | undefined;\n let recoverable = false;\n if (handled && errorWithContext.recoverable && this.config.recoveryOptions) {\n const recoveryResult = await this.attemptRecovery(errorWithContext);\n recoverable = recoveryResult.recoverable;\n recoveredValue = recoveryResult.value;\n }\n\n return {\n handled,\n recoverable,\n recoveredValue,\n strategies,\n error: errorWithContext,\n };\n }\n\n /**\n * 确定错误处理策略\n */\n private determineStrategies(error: FrameworkError): ErrorHandlingStrategy[] {\n // 1. 检查错误类型对应的策略\n if (this.config.typeStrategies[error.type]) {\n return this.config.typeStrategies[error.type]!;\n }\n\n // 2. 检查错误严重程度对应的策略\n if (this.config.severityStrategies[error.severity]) {\n return this.config.severityStrategies[error.severity]!;\n }\n\n // 3. 使用默认策略\n return this.config.defaultStrategies;\n }\n\n /**\n * 执行处理策略\n */\n private async executeStrategies(\n error: FrameworkError,\n strategies: ErrorHandlingStrategy[]\n ): Promise<boolean> {\n let handled = false;\n\n for (const strategy of strategies) {\n try {\n switch (strategy) {\n case ErrorHandlingStrategy.LOG:\n this.logError(error);\n handled = true;\n break;\n\n case ErrorHandlingStrategy.REPORT:\n await this.reportError(error);\n handled = true;\n break;\n\n case ErrorHandlingStrategy.RECOVER:\n // 恢复策略在 handleError 中统一处理\n handled = true;\n break;\n\n case ErrorHandlingStrategy.FALLBACK:\n // 降级策略在 attemptRecovery 中处理\n handled = true;\n break;\n\n case ErrorHandlingStrategy.IGNORE:\n // 忽略错误,不做任何处理\n handled = true;\n break;\n }\n } catch (strategyError) {\n logger.warn(`错误处理策略 ${strategy} 执行失败:`, strategyError);\n }\n }\n\n return handled;\n }\n\n /**\n * 记录错误\n */\n private logError(error: FrameworkError): void {\n const errorInfo = errorUtils.extractErrorInfo(error);\n \n // 根据错误严重程度选择日志级别\n switch (error.severity) {\n case ErrorSeverity.CRITICAL:\n case ErrorSeverity.HIGH:\n logger.error('错误:', errorInfo);\n break;\n case ErrorSeverity.MEDIUM:\n logger.warn('警告:', errorInfo);\n break;\n case ErrorSeverity.LOW:\n logger.info('信息:', errorInfo);\n break;\n }\n\n // 开发环境显示详细错误信息\n if (this.config.showDetailedErrorsInDev && process.env.NODE_ENV === 'development') {\n const detailedError = errorUtils.formatErrorForDev(error);\n console.error(detailedError);\n }\n }\n\n /**\n * 上报错误\n */\n private async reportError(error: FrameworkError): Promise<void> {\n if (!this.monitoring) {\n logger.debug('监控服务未配置,跳过错误上报');\n return;\n }\n\n try {\n this.monitoring.captureError(error, {\n severity: error.severity,\n type: error.type,\n code: error.code,\n context: error.context,\n });\n } catch (reportError) {\n logger.warn('错误上报失败:', reportError);\n }\n }\n\n /**\n * 尝试恢复错误\n */\n private async attemptRecovery(\n error: FrameworkError\n ): Promise<{ recoverable: boolean; value?: unknown }> {\n const options = this.config.recoveryOptions;\n if (!options) {\n return { recoverable: false };\n }\n\n const maxRetries = options.maxRetries ?? 3;\n const retryDelay = options.retryDelay ?? 1000;\n const exponentialBackoff = options.exponentialBackoff ?? true;\n const shouldRetry = options.shouldRetry ?? (() => true);\n\n // 如果有降级方案,先尝试降级\n if (options.fallback) {\n try {\n const fallbackValue = await Promise.resolve(options.fallback());\n logger.info('错误已通过降级方案恢复');\n return { recoverable: true, value: fallbackValue };\n } catch (fallbackError) {\n logger.warn('降级方案执行失败:', fallbackError);\n }\n }\n\n // 尝试重试(如果错误可恢复且满足重试条件)\n if (error.recoverable && shouldRetry(error, 0)) {\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n if (!shouldRetry(error, attempt)) {\n break;\n }\n\n const delay = exponentialBackoff\n ? retryDelay * Math.pow(2, attempt)\n : retryDelay;\n\n logger.debug(`错误恢复重试 ${attempt + 1}/${maxRetries},${delay}ms 后重试...`);\n\n await new Promise(resolve => setTimeout(resolve, delay));\n\n // 这里应该调用原始操作的重试逻辑\n // 由于错误处理器不知道原始操作,这里只返回可恢复状态\n // 实际的重试应该在调用方实现\n }\n }\n\n return { recoverable: error.recoverable };\n }\n\n /**\n * 创建错误处理器的便捷方法\n */\n static create(config?: ErrorHandlerConfig): ErrorHandler {\n return new ErrorHandler(config);\n }\n}\n\n/**\n * 默认错误处理器实例(单例)\n */\nlet defaultErrorHandler: ErrorHandler | null = null;\n\n/**\n * 获取默认错误处理器\n */\nexport function getDefaultErrorHandler(): ErrorHandler {\n if (!defaultErrorHandler) {\n defaultErrorHandler = new ErrorHandler();\n }\n return defaultErrorHandler;\n}\n\n/**\n * 设置默认错误处理器\n */\nexport function setDefaultErrorHandler(handler: ErrorHandler): void {\n defaultErrorHandler = handler;\n}\n"],"names":["ErrorHandler","ErrorHandlingStrategy","getDefaultErrorHandler","setDefaultErrorHandler","setMonitoring","monitoring","handleError","error","context","normalizedError","errorUtils","normalizeError","errorWithContext","FrameworkError","message","type","severity","code","originalError","recoverable","strategies","determineStrategies","handled","executeStrategies","recoveredValue","config","recoveryOptions","recoveryResult","attemptRecovery","value","typeStrategies","severityStrategies","defaultStrategies","strategy","logError","reportError","strategyError","logger","warn","errorInfo","extractErrorInfo","ErrorSeverity","CRITICAL","HIGH","MEDIUM","LOW","info","showDetailedErrorsInDev","process","env","NODE_ENV","detailedError","formatErrorForDev","console","debug","captureError","options","maxRetries","retryDelay","exponentialBackoff","shouldRetry","fallback","fallbackValue","Promise","resolve","fallbackError","attempt","delay","Math","pow","setTimeout","create","defaultErrorHandler","handler"],"mappings":"AAAA;;;;;;;CAOC;;;;;;;;;;;QA0HYA;eAAAA;;QAjHDC;eAAAA;;QAoXIC;eAAAA;;QAUAC;eAAAA;;;wBArYO;uBAC8C;;;;;;;;;;;;;;AAM9D,IAAA,AAAKF,+CAAAA;IACV;;GAEC;IAED;;GAEC;IAED;;GAEC;IAED;;GAEC;IAED;;GAEC;WAnBSA;;AAiHL,IAAA,AAAMD,eAAN,MAAMA;IAkBX;;GAEC,GACDI,cAAcC,UAA6B,EAAQ;QACjD,IAAI,CAACA,UAAU,GAAGA;IACpB;IAEA;;;;;;GAMC,GACD,MAAMC,YACJC,KAAc,EACdC,OAAiC,EACL;QAC5B,UAAU;QACV,MAAMC,kBAAkBC,iBAAU,CAACC,cAAc,CAACJ;QAElD,0CAA0C;QAC1C,MAAMK,mBAAmCJ,UACrC,IAAIK,qBAAc,CAChBJ,gBAAgBK,OAAO,EACvBL,gBAAgBM,IAAI,EACpBN,gBAAgBO,QAAQ,EACxB;YACEC,MAAMR,gBAAgBQ,IAAI;YAC1BC,eAAeT,gBAAgBS,aAAa;YAC5CV,SAAS;gBACP,GAAGC,gBAAgBD,OAAO;gBAC1B,GAAGA,OAAO;YACZ;YACAW,aAAaV,gBAAgBU,WAAW;QAC1C,KAEFV;QAEJ,SAAS;QACT,MAAMW,aAAa,IAAI,CAACC,mBAAmB,CAACT;QAE5C,SAAS;QACT,MAAMU,UAAU,MAAM,IAAI,CAACC,iBAAiB,CAACX,kBAAkBQ;QAE/D,SAAS;QACT,IAAII;QACJ,IAAIL,cAAc;QAClB,IAAIG,WAAWV,iBAAiBO,WAAW,IAAI,IAAI,CAACM,MAAM,CAACC,eAAe,EAAE;YAC1E,MAAMC,iBAAiB,MAAM,IAAI,CAACC,eAAe,CAAChB;YAClDO,cAAcQ,eAAeR,WAAW;YACxCK,iBAAiBG,eAAeE,KAAK;QACvC;QAEA,OAAO;YACLP;YACAH;YACAK;YACAJ;YACAb,OAAOK;QACT;IACF;IAEA;;GAEC,GACD,AAAQS,oBAAoBd,KAAqB,EAA2B;QAC1E,iBAAiB;QACjB,IAAI,IAAI,CAACkB,MAAM,CAACK,cAAc,CAACvB,MAAMQ,IAAI,CAAC,EAAE;YAC1C,OAAO,IAAI,CAACU,MAAM,CAACK,cAAc,CAACvB,MAAMQ,IAAI,CAAC;QAC/C;QAEA,mBAAmB;QACnB,IAAI,IAAI,CAACU,MAAM,CAACM,kBAAkB,CAACxB,MAAMS,QAAQ,CAAC,EAAE;YAClD,OAAO,IAAI,CAACS,MAAM,CAACM,kBAAkB,CAACxB,MAAMS,QAAQ,CAAC;QACvD;QAEA,YAAY;QACZ,OAAO,IAAI,CAACS,MAAM,CAACO,iBAAiB;IACtC;IAEA;;GAEC,GACD,MAAcT,kBACZhB,KAAqB,EACrBa,UAAmC,EACjB;QAClB,IAAIE,UAAU;QAEd,KAAK,MAAMW,YAAYb,WAAY;YACjC,IAAI;gBACF,OAAQa;oBACN;wBACE,IAAI,CAACC,QAAQ,CAAC3B;wBACde,UAAU;wBACV;oBAEF;wBACE,MAAM,IAAI,CAACa,WAAW,CAAC5B;wBACvBe,UAAU;wBACV;oBAEF;wBACE,0BAA0B;wBAC1BA,UAAU;wBACV;oBAEF;wBACE,4BAA4B;wBAC5BA,UAAU;wBACV;oBAEF;wBACE,cAAc;wBACdA,UAAU;wBACV;gBACJ;YACF,EAAE,OAAOc,eAAe;gBACtBC,cAAM,CAACC,IAAI,CAAC,CAAC,OAAO,EAAEL,SAAS,MAAM,CAAC,EAAEG;YAC1C;QACF;QAEA,OAAOd;IACT;IAEA;;GAEC,GACD,AAAQY,SAAS3B,KAAqB,EAAQ;QAC5C,MAAMgC,YAAY7B,iBAAU,CAAC8B,gBAAgB,CAACjC;QAE9C,iBAAiB;QACjB,OAAQA,MAAMS,QAAQ;YACpB,KAAKyB,oBAAa,CAACC,QAAQ;YAC3B,KAAKD,oBAAa,CAACE,IAAI;gBACrBN,cAAM,CAAC9B,KAAK,CAAC,OAAOgC;gBACpB;YACF,KAAKE,oBAAa,CAACG,MAAM;gBACvBP,cAAM,CAACC,IAAI,CAAC,OAAOC;gBACnB;YACF,KAAKE,oBAAa,CAACI,GAAG;gBACpBR,cAAM,CAACS,IAAI,CAAC,OAAOP;gBACnB;QACJ;QAEA,eAAe;QACf,IAAI,IAAI,CAACd,MAAM,CAACsB,uBAAuB,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;YACjF,MAAMC,gBAAgBzC,iBAAU,CAAC0C,iBAAiB,CAAC7C;YACnD8C,QAAQ9C,KAAK,CAAC4C;QAChB;IACF;IAEA;;GAEC,GACD,MAAchB,YAAY5B,KAAqB,EAAiB;QAC9D,IAAI,CAAC,IAAI,CAACF,UAAU,EAAE;YACpBgC,cAAM,CAACiB,KAAK,CAAC;YACb;QACF;QAEA,IAAI;YACF,IAAI,CAACjD,UAAU,CAACkD,YAAY,CAAChD,OAAO;gBAClCS,UAAUT,MAAMS,QAAQ;gBACxBD,MAAMR,MAAMQ,IAAI;gBAChBE,MAAMV,MAAMU,IAAI;gBAChBT,SAASD,MAAMC,OAAO;YACxB;QACF,EAAE,OAAO2B,aAAa;YACpBE,cAAM,CAACC,IAAI,CAAC,WAAWH;QACzB;IACF;IAEA;;GAEC,GACD,MAAcP,gBACZrB,KAAqB,EAC+B;QACpD,MAAMiD,UAAU,IAAI,CAAC/B,MAAM,CAACC,eAAe;QAC3C,IAAI,CAAC8B,SAAS;YACZ,OAAO;gBAAErC,aAAa;YAAM;QAC9B;QAEA,MAAMsC,aAAaD,QAAQC,UAAU,IAAI;QACzC,MAAMC,aAAaF,QAAQE,UAAU,IAAI;QACzC,MAAMC,qBAAqBH,QAAQG,kBAAkB,IAAI;QACzD,MAAMC,cAAcJ,QAAQI,WAAW,IAAK,CAAA,IAAM,IAAG;QAErD,gBAAgB;QAChB,IAAIJ,QAAQK,QAAQ,EAAE;YACpB,IAAI;gBACF,MAAMC,gBAAgB,MAAMC,QAAQC,OAAO,CAACR,QAAQK,QAAQ;gBAC5DxB,cAAM,CAACS,IAAI,CAAC;gBACZ,OAAO;oBAAE3B,aAAa;oBAAMU,OAAOiC;gBAAc;YACnD,EAAE,OAAOG,eAAe;gBACtB5B,cAAM,CAACC,IAAI,CAAC,aAAa2B;YAC3B;QACF;QAEA,uBAAuB;QACvB,IAAI1D,MAAMY,WAAW,IAAIyC,YAAYrD,OAAO,IAAI;YAC9C,IAAK,IAAI2D,UAAU,GAAGA,UAAUT,YAAYS,UAAW;gBACrD,IAAI,CAACN,YAAYrD,OAAO2D,UAAU;oBAChC;gBACF;gBAEA,MAAMC,QAAQR,qBACVD,aAAaU,KAAKC,GAAG,CAAC,GAAGH,WACzBR;gBAEJrB,cAAM,CAACiB,KAAK,CAAC,CAAC,OAAO,EAAEY,UAAU,EAAE,CAAC,EAAET,WAAW,CAAC,EAAEU,MAAM,SAAS,CAAC;gBAEpE,MAAM,IAAIJ,QAAQC,CAAAA,UAAWM,WAAWN,SAASG;YAEjD,kBAAkB;YAClB,4BAA4B;YAC5B,gBAAgB;YAClB;QACF;QAEA,OAAO;YAAEhD,aAAaZ,MAAMY,WAAW;QAAC;IAC1C;IAEA;;GAEC,GACD,OAAOoD,OAAO9C,MAA2B,EAAgB;QACvD,OAAO,IAAIzB,aAAayB;IAC1B;IApPA,YAAYA,SAA6B,CAAC,CAAC,CAAE;QAH7C,uBAAQA,UAAR,KAAA;QACA,uBAAQpB,cAAR,KAAA;QAGE,IAAI,CAACA,UAAU,GAAGoB,OAAOpB,UAAU;QACnC,IAAI,CAACoB,MAAM,GAAG;YACZO,mBAAmBP,OAAOO,iBAAiB,IAAI;;;aAG9C;YACDD,oBAAoBN,OAAOM,kBAAkB,IAAI,CAAC;YAClDD,gBAAgBL,OAAOK,cAAc,IAAI,CAAC;YAC1CJ,iBAAiBD,OAAOC,eAAe,IAAI,CAAC;YAC5CqB,yBAAyBtB,OAAOsB,uBAAuB,IAAI;QAC7D;IACF;AAyOF;AAEA;;CAEC,GACD,IAAIyB,sBAA2C;AAKxC,SAAStE;IACd,IAAI,CAACsE,qBAAqB;QACxBA,sBAAsB,IAAIxE;IAC5B;IACA,OAAOwE;AACT;AAKO,SAASrE,uBAAuBsE,OAAqB;IAC1DD,sBAAsBC;AACxB"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* 2. 错误分类:致命、可恢复、警告
|
|
7
7
|
* 3. 错误恢复机制:自动重试、降级方案
|
|
8
8
|
*/
|
|
9
|
-
import { ErrorSeverity, ErrorType, FrameworkError } from '
|
|
9
|
+
import { ErrorSeverity, ErrorType, FrameworkError } from '@vlian/utils';
|
|
10
10
|
import type { MonitoringService } from '@vlian/monitoring';
|
|
11
11
|
/**
|
|
12
12
|
* 错误处理策略
|
|
@@ -18,8 +18,8 @@ function _define_property(obj, key, value) {
|
|
|
18
18
|
* 1. 统一错误处理策略:记录、上报、恢复、降级
|
|
19
19
|
* 2. 错误分类:致命、可恢复、警告
|
|
20
20
|
* 3. 错误恢复机制:自动重试、降级方案
|
|
21
|
-
*/ import { logger } from "
|
|
22
|
-
import { errorUtils, ErrorSeverity, FrameworkError } from "
|
|
21
|
+
*/ import { logger } from "@vlian/logger";
|
|
22
|
+
import { errorUtils, ErrorSeverity, FrameworkError } from "@vlian/utils";
|
|
23
23
|
/**
|
|
24
24
|
* 错误处理策略
|
|
25
25
|
*/ export var ErrorHandlingStrategy = /*#__PURE__*/ function(ErrorHandlingStrategy) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/error/ErrorHandler.ts"],"sourcesContent":["/**\n * 统一错误处理器\n * \n * 优化:\n * 1. 统一错误处理策略:记录、上报、恢复、降级\n * 2. 错误分类:致命、可恢复、警告\n * 3. 错误恢复机制:自动重试、降级方案\n */\n\nimport { logger } from '../../utils';\nimport { errorUtils, ErrorSeverity, ErrorType, FrameworkError } from '../../utils/errors';\nimport type { MonitoringService } from '@vlian/monitoring';\n\n/**\n * 错误处理策略\n */\nexport enum ErrorHandlingStrategy {\n /**\n * 记录错误(日志)\n */\n LOG = 'LOG',\n /**\n * 上报错误(监控服务)\n */\n REPORT = 'REPORT',\n /**\n * 尝试恢复错误\n */\n RECOVER = 'RECOVER',\n /**\n * 降级处理\n */\n FALLBACK = 'FALLBACK',\n /**\n * 忽略错误\n */\n IGNORE = 'IGNORE',\n}\n\n/**\n * 错误恢复选项\n */\nexport interface ErrorRecoveryOptions {\n /**\n * 最大重试次数\n * @default 3\n */\n maxRetries?: number;\n /**\n * 重试延迟(毫秒)\n * @default 1000\n */\n retryDelay?: number;\n /**\n * 是否启用指数退避\n * @default true\n */\n exponentialBackoff?: boolean;\n /**\n * 重试条件函数\n */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n /**\n * 降级方案函数\n */\n fallback?: () => Promise<unknown> | unknown;\n}\n\n/**\n * 错误处理配置\n */\nexport interface ErrorHandlerConfig {\n /**\n * 监控服务实例(可选)\n */\n monitoring?: MonitoringService;\n /**\n * 默认错误处理策略\n * @default [ErrorHandlingStrategy.LOG, ErrorHandlingStrategy.REPORT]\n */\n defaultStrategies?: ErrorHandlingStrategy[];\n /**\n * 错误严重程度对应的处理策略\n */\n severityStrategies?: Partial<Record<ErrorSeverity, ErrorHandlingStrategy[]>>;\n /**\n * 错误类型对应的处理策略\n */\n typeStrategies?: Partial<Record<ErrorType, ErrorHandlingStrategy[]>>;\n /**\n * 错误恢复选项\n */\n recoveryOptions?: ErrorRecoveryOptions;\n /**\n * 是否在开发环境显示详细错误信息\n * @default true\n */\n showDetailedErrorsInDev?: boolean;\n}\n\n/**\n * 错误处理结果\n */\nexport interface ErrorHandleResult {\n /**\n * 是否已处理\n */\n handled: boolean;\n /**\n * 是否可恢复\n */\n recoverable: boolean;\n /**\n * 恢复后的结果(如果已恢复)\n */\n recoveredValue?: unknown;\n /**\n * 使用的处理策略\n */\n strategies: ErrorHandlingStrategy[];\n /**\n * 错误信息\n */\n error: FrameworkError;\n}\n\n/**\n * 统一错误处理器\n */\nexport class ErrorHandler {\n private config: Omit<Required<ErrorHandlerConfig>, 'monitoring'>;\n private monitoring?: MonitoringService;\n\n constructor(config: ErrorHandlerConfig = {}) {\n this.monitoring = config.monitoring;\n this.config = {\n defaultStrategies: config.defaultStrategies ?? [\n ErrorHandlingStrategy.LOG,\n ErrorHandlingStrategy.REPORT,\n ],\n severityStrategies: config.severityStrategies ?? {},\n typeStrategies: config.typeStrategies ?? {},\n recoveryOptions: config.recoveryOptions ?? {},\n showDetailedErrorsInDev: config.showDetailedErrorsInDev ?? true,\n };\n }\n\n /**\n * 设置监控服务\n */\n setMonitoring(monitoring: MonitoringService): void {\n this.monitoring = monitoring;\n }\n\n /**\n * 处理错误\n * \n * @param error - 错误对象\n * @param context - 错误上下文\n * @returns 错误处理结果\n */\n async handleError(\n error: unknown,\n context?: Record<string, unknown>\n ): Promise<ErrorHandleResult> {\n // 标准化错误对象\n const normalizedError = errorUtils.normalizeError(error);\n \n // 创建包含上下文信息的错误对象(由于 context 是只读的,需要创建新对象)\n const errorWithContext: FrameworkError = context\n ? new FrameworkError(\n normalizedError.message,\n normalizedError.type,\n normalizedError.severity,\n {\n code: normalizedError.code,\n originalError: normalizedError.originalError,\n context: {\n ...normalizedError.context,\n ...context,\n },\n recoverable: normalizedError.recoverable,\n }\n )\n : normalizedError;\n\n // 确定处理策略\n const strategies = this.determineStrategies(errorWithContext);\n \n // 执行处理策略\n const handled = await this.executeStrategies(errorWithContext, strategies);\n\n // 尝试恢复错误\n let recoveredValue: unknown | undefined;\n let recoverable = false;\n if (handled && errorWithContext.recoverable && this.config.recoveryOptions) {\n const recoveryResult = await this.attemptRecovery(errorWithContext);\n recoverable = recoveryResult.recoverable;\n recoveredValue = recoveryResult.value;\n }\n\n return {\n handled,\n recoverable,\n recoveredValue,\n strategies,\n error: errorWithContext,\n };\n }\n\n /**\n * 确定错误处理策略\n */\n private determineStrategies(error: FrameworkError): ErrorHandlingStrategy[] {\n // 1. 检查错误类型对应的策略\n if (this.config.typeStrategies[error.type]) {\n return this.config.typeStrategies[error.type]!;\n }\n\n // 2. 检查错误严重程度对应的策略\n if (this.config.severityStrategies[error.severity]) {\n return this.config.severityStrategies[error.severity]!;\n }\n\n // 3. 使用默认策略\n return this.config.defaultStrategies;\n }\n\n /**\n * 执行处理策略\n */\n private async executeStrategies(\n error: FrameworkError,\n strategies: ErrorHandlingStrategy[]\n ): Promise<boolean> {\n let handled = false;\n\n for (const strategy of strategies) {\n try {\n switch (strategy) {\n case ErrorHandlingStrategy.LOG:\n this.logError(error);\n handled = true;\n break;\n\n case ErrorHandlingStrategy.REPORT:\n await this.reportError(error);\n handled = true;\n break;\n\n case ErrorHandlingStrategy.RECOVER:\n // 恢复策略在 handleError 中统一处理\n handled = true;\n break;\n\n case ErrorHandlingStrategy.FALLBACK:\n // 降级策略在 attemptRecovery 中处理\n handled = true;\n break;\n\n case ErrorHandlingStrategy.IGNORE:\n // 忽略错误,不做任何处理\n handled = true;\n break;\n }\n } catch (strategyError) {\n logger.warn(`错误处理策略 ${strategy} 执行失败:`, strategyError);\n }\n }\n\n return handled;\n }\n\n /**\n * 记录错误\n */\n private logError(error: FrameworkError): void {\n const errorInfo = errorUtils.extractErrorInfo(error);\n \n // 根据错误严重程度选择日志级别\n switch (error.severity) {\n case ErrorSeverity.CRITICAL:\n case ErrorSeverity.HIGH:\n logger.error('错误:', errorInfo);\n break;\n case ErrorSeverity.MEDIUM:\n logger.warn('警告:', errorInfo);\n break;\n case ErrorSeverity.LOW:\n logger.info('信息:', errorInfo);\n break;\n }\n\n // 开发环境显示详细错误信息\n if (this.config.showDetailedErrorsInDev && process.env.NODE_ENV === 'development') {\n const detailedError = errorUtils.formatErrorForDev(error);\n console.error(detailedError);\n }\n }\n\n /**\n * 上报错误\n */\n private async reportError(error: FrameworkError): Promise<void> {\n if (!this.monitoring) {\n logger.debug('监控服务未配置,跳过错误上报');\n return;\n }\n\n try {\n this.monitoring.captureError(error, {\n severity: error.severity,\n type: error.type,\n code: error.code,\n context: error.context,\n });\n } catch (reportError) {\n logger.warn('错误上报失败:', reportError);\n }\n }\n\n /**\n * 尝试恢复错误\n */\n private async attemptRecovery(\n error: FrameworkError\n ): Promise<{ recoverable: boolean; value?: unknown }> {\n const options = this.config.recoveryOptions;\n if (!options) {\n return { recoverable: false };\n }\n\n const maxRetries = options.maxRetries ?? 3;\n const retryDelay = options.retryDelay ?? 1000;\n const exponentialBackoff = options.exponentialBackoff ?? true;\n const shouldRetry = options.shouldRetry ?? (() => true);\n\n // 如果有降级方案,先尝试降级\n if (options.fallback) {\n try {\n const fallbackValue = await Promise.resolve(options.fallback());\n logger.info('错误已通过降级方案恢复');\n return { recoverable: true, value: fallbackValue };\n } catch (fallbackError) {\n logger.warn('降级方案执行失败:', fallbackError);\n }\n }\n\n // 尝试重试(如果错误可恢复且满足重试条件)\n if (error.recoverable && shouldRetry(error, 0)) {\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n if (!shouldRetry(error, attempt)) {\n break;\n }\n\n const delay = exponentialBackoff\n ? retryDelay * Math.pow(2, attempt)\n : retryDelay;\n\n logger.debug(`错误恢复重试 ${attempt + 1}/${maxRetries},${delay}ms 后重试...`);\n\n await new Promise(resolve => setTimeout(resolve, delay));\n\n // 这里应该调用原始操作的重试逻辑\n // 由于错误处理器不知道原始操作,这里只返回可恢复状态\n // 实际的重试应该在调用方实现\n }\n }\n\n return { recoverable: error.recoverable };\n }\n\n /**\n * 创建错误处理器的便捷方法\n */\n static create(config?: ErrorHandlerConfig): ErrorHandler {\n return new ErrorHandler(config);\n }\n}\n\n/**\n * 默认错误处理器实例(单例)\n */\nlet defaultErrorHandler: ErrorHandler | null = null;\n\n/**\n * 获取默认错误处理器\n */\nexport function getDefaultErrorHandler(): ErrorHandler {\n if (!defaultErrorHandler) {\n defaultErrorHandler = new ErrorHandler();\n }\n return defaultErrorHandler;\n}\n\n/**\n * 设置默认错误处理器\n */\nexport function setDefaultErrorHandler(handler: ErrorHandler): void {\n defaultErrorHandler = handler;\n}\n"],"names":["logger","errorUtils","ErrorSeverity","FrameworkError","ErrorHandlingStrategy","ErrorHandler","setMonitoring","monitoring","handleError","error","context","normalizedError","normalizeError","errorWithContext","message","type","severity","code","originalError","recoverable","strategies","determineStrategies","handled","executeStrategies","recoveredValue","config","recoveryOptions","recoveryResult","attemptRecovery","value","typeStrategies","severityStrategies","defaultStrategies","strategy","logError","reportError","strategyError","warn","errorInfo","extractErrorInfo","CRITICAL","HIGH","MEDIUM","LOW","info","showDetailedErrorsInDev","process","env","NODE_ENV","detailedError","formatErrorForDev","console","debug","captureError","options","maxRetries","retryDelay","exponentialBackoff","shouldRetry","fallback","fallbackValue","Promise","resolve","fallbackError","attempt","delay","Math","pow","setTimeout","create","defaultErrorHandler","getDefaultErrorHandler","setDefaultErrorHandler","handler"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/error/ErrorHandler.ts"],"sourcesContent":["/**\n * 统一错误处理器\n * \n * 优化:\n * 1. 统一错误处理策略:记录、上报、恢复、降级\n * 2. 错误分类:致命、可恢复、警告\n * 3. 错误恢复机制:自动重试、降级方案\n */\n\nimport { logger } from '@vlian/logger';\nimport { errorUtils, ErrorSeverity, ErrorType, FrameworkError } from '@vlian/utils';\nimport type { MonitoringService } from '@vlian/monitoring';\n\n/**\n * 错误处理策略\n */\nexport enum ErrorHandlingStrategy {\n /**\n * 记录错误(日志)\n */\n LOG = 'LOG',\n /**\n * 上报错误(监控服务)\n */\n REPORT = 'REPORT',\n /**\n * 尝试恢复错误\n */\n RECOVER = 'RECOVER',\n /**\n * 降级处理\n */\n FALLBACK = 'FALLBACK',\n /**\n * 忽略错误\n */\n IGNORE = 'IGNORE',\n}\n\n/**\n * 错误恢复选项\n */\nexport interface ErrorRecoveryOptions {\n /**\n * 最大重试次数\n * @default 3\n */\n maxRetries?: number;\n /**\n * 重试延迟(毫秒)\n * @default 1000\n */\n retryDelay?: number;\n /**\n * 是否启用指数退避\n * @default true\n */\n exponentialBackoff?: boolean;\n /**\n * 重试条件函数\n */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n /**\n * 降级方案函数\n */\n fallback?: () => Promise<unknown> | unknown;\n}\n\n/**\n * 错误处理配置\n */\nexport interface ErrorHandlerConfig {\n /**\n * 监控服务实例(可选)\n */\n monitoring?: MonitoringService;\n /**\n * 默认错误处理策略\n * @default [ErrorHandlingStrategy.LOG, ErrorHandlingStrategy.REPORT]\n */\n defaultStrategies?: ErrorHandlingStrategy[];\n /**\n * 错误严重程度对应的处理策略\n */\n severityStrategies?: Partial<Record<ErrorSeverity, ErrorHandlingStrategy[]>>;\n /**\n * 错误类型对应的处理策略\n */\n typeStrategies?: Partial<Record<ErrorType, ErrorHandlingStrategy[]>>;\n /**\n * 错误恢复选项\n */\n recoveryOptions?: ErrorRecoveryOptions;\n /**\n * 是否在开发环境显示详细错误信息\n * @default true\n */\n showDetailedErrorsInDev?: boolean;\n}\n\n/**\n * 错误处理结果\n */\nexport interface ErrorHandleResult {\n /**\n * 是否已处理\n */\n handled: boolean;\n /**\n * 是否可恢复\n */\n recoverable: boolean;\n /**\n * 恢复后的结果(如果已恢复)\n */\n recoveredValue?: unknown;\n /**\n * 使用的处理策略\n */\n strategies: ErrorHandlingStrategy[];\n /**\n * 错误信息\n */\n error: FrameworkError;\n}\n\n/**\n * 统一错误处理器\n */\nexport class ErrorHandler {\n private config: Omit<Required<ErrorHandlerConfig>, 'monitoring'>;\n private monitoring?: MonitoringService;\n\n constructor(config: ErrorHandlerConfig = {}) {\n this.monitoring = config.monitoring;\n this.config = {\n defaultStrategies: config.defaultStrategies ?? [\n ErrorHandlingStrategy.LOG,\n ErrorHandlingStrategy.REPORT,\n ],\n severityStrategies: config.severityStrategies ?? {},\n typeStrategies: config.typeStrategies ?? {},\n recoveryOptions: config.recoveryOptions ?? {},\n showDetailedErrorsInDev: config.showDetailedErrorsInDev ?? true,\n };\n }\n\n /**\n * 设置监控服务\n */\n setMonitoring(monitoring: MonitoringService): void {\n this.monitoring = monitoring;\n }\n\n /**\n * 处理错误\n * \n * @param error - 错误对象\n * @param context - 错误上下文\n * @returns 错误处理结果\n */\n async handleError(\n error: unknown,\n context?: Record<string, unknown>\n ): Promise<ErrorHandleResult> {\n // 标准化错误对象\n const normalizedError = errorUtils.normalizeError(error);\n \n // 创建包含上下文信息的错误对象(由于 context 是只读的,需要创建新对象)\n const errorWithContext: FrameworkError = context\n ? new FrameworkError(\n normalizedError.message,\n normalizedError.type,\n normalizedError.severity,\n {\n code: normalizedError.code,\n originalError: normalizedError.originalError,\n context: {\n ...normalizedError.context,\n ...context,\n },\n recoverable: normalizedError.recoverable,\n }\n )\n : normalizedError;\n\n // 确定处理策略\n const strategies = this.determineStrategies(errorWithContext);\n \n // 执行处理策略\n const handled = await this.executeStrategies(errorWithContext, strategies);\n\n // 尝试恢复错误\n let recoveredValue: unknown | undefined;\n let recoverable = false;\n if (handled && errorWithContext.recoverable && this.config.recoveryOptions) {\n const recoveryResult = await this.attemptRecovery(errorWithContext);\n recoverable = recoveryResult.recoverable;\n recoveredValue = recoveryResult.value;\n }\n\n return {\n handled,\n recoverable,\n recoveredValue,\n strategies,\n error: errorWithContext,\n };\n }\n\n /**\n * 确定错误处理策略\n */\n private determineStrategies(error: FrameworkError): ErrorHandlingStrategy[] {\n // 1. 检查错误类型对应的策略\n if (this.config.typeStrategies[error.type]) {\n return this.config.typeStrategies[error.type]!;\n }\n\n // 2. 检查错误严重程度对应的策略\n if (this.config.severityStrategies[error.severity]) {\n return this.config.severityStrategies[error.severity]!;\n }\n\n // 3. 使用默认策略\n return this.config.defaultStrategies;\n }\n\n /**\n * 执行处理策略\n */\n private async executeStrategies(\n error: FrameworkError,\n strategies: ErrorHandlingStrategy[]\n ): Promise<boolean> {\n let handled = false;\n\n for (const strategy of strategies) {\n try {\n switch (strategy) {\n case ErrorHandlingStrategy.LOG:\n this.logError(error);\n handled = true;\n break;\n\n case ErrorHandlingStrategy.REPORT:\n await this.reportError(error);\n handled = true;\n break;\n\n case ErrorHandlingStrategy.RECOVER:\n // 恢复策略在 handleError 中统一处理\n handled = true;\n break;\n\n case ErrorHandlingStrategy.FALLBACK:\n // 降级策略在 attemptRecovery 中处理\n handled = true;\n break;\n\n case ErrorHandlingStrategy.IGNORE:\n // 忽略错误,不做任何处理\n handled = true;\n break;\n }\n } catch (strategyError) {\n logger.warn(`错误处理策略 ${strategy} 执行失败:`, strategyError);\n }\n }\n\n return handled;\n }\n\n /**\n * 记录错误\n */\n private logError(error: FrameworkError): void {\n const errorInfo = errorUtils.extractErrorInfo(error);\n \n // 根据错误严重程度选择日志级别\n switch (error.severity) {\n case ErrorSeverity.CRITICAL:\n case ErrorSeverity.HIGH:\n logger.error('错误:', errorInfo);\n break;\n case ErrorSeverity.MEDIUM:\n logger.warn('警告:', errorInfo);\n break;\n case ErrorSeverity.LOW:\n logger.info('信息:', errorInfo);\n break;\n }\n\n // 开发环境显示详细错误信息\n if (this.config.showDetailedErrorsInDev && process.env.NODE_ENV === 'development') {\n const detailedError = errorUtils.formatErrorForDev(error);\n console.error(detailedError);\n }\n }\n\n /**\n * 上报错误\n */\n private async reportError(error: FrameworkError): Promise<void> {\n if (!this.monitoring) {\n logger.debug('监控服务未配置,跳过错误上报');\n return;\n }\n\n try {\n this.monitoring.captureError(error, {\n severity: error.severity,\n type: error.type,\n code: error.code,\n context: error.context,\n });\n } catch (reportError) {\n logger.warn('错误上报失败:', reportError);\n }\n }\n\n /**\n * 尝试恢复错误\n */\n private async attemptRecovery(\n error: FrameworkError\n ): Promise<{ recoverable: boolean; value?: unknown }> {\n const options = this.config.recoveryOptions;\n if (!options) {\n return { recoverable: false };\n }\n\n const maxRetries = options.maxRetries ?? 3;\n const retryDelay = options.retryDelay ?? 1000;\n const exponentialBackoff = options.exponentialBackoff ?? true;\n const shouldRetry = options.shouldRetry ?? (() => true);\n\n // 如果有降级方案,先尝试降级\n if (options.fallback) {\n try {\n const fallbackValue = await Promise.resolve(options.fallback());\n logger.info('错误已通过降级方案恢复');\n return { recoverable: true, value: fallbackValue };\n } catch (fallbackError) {\n logger.warn('降级方案执行失败:', fallbackError);\n }\n }\n\n // 尝试重试(如果错误可恢复且满足重试条件)\n if (error.recoverable && shouldRetry(error, 0)) {\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n if (!shouldRetry(error, attempt)) {\n break;\n }\n\n const delay = exponentialBackoff\n ? retryDelay * Math.pow(2, attempt)\n : retryDelay;\n\n logger.debug(`错误恢复重试 ${attempt + 1}/${maxRetries},${delay}ms 后重试...`);\n\n await new Promise(resolve => setTimeout(resolve, delay));\n\n // 这里应该调用原始操作的重试逻辑\n // 由于错误处理器不知道原始操作,这里只返回可恢复状态\n // 实际的重试应该在调用方实现\n }\n }\n\n return { recoverable: error.recoverable };\n }\n\n /**\n * 创建错误处理器的便捷方法\n */\n static create(config?: ErrorHandlerConfig): ErrorHandler {\n return new ErrorHandler(config);\n }\n}\n\n/**\n * 默认错误处理器实例(单例)\n */\nlet defaultErrorHandler: ErrorHandler | null = null;\n\n/**\n * 获取默认错误处理器\n */\nexport function getDefaultErrorHandler(): ErrorHandler {\n if (!defaultErrorHandler) {\n defaultErrorHandler = new ErrorHandler();\n }\n return defaultErrorHandler;\n}\n\n/**\n * 设置默认错误处理器\n */\nexport function setDefaultErrorHandler(handler: ErrorHandler): void {\n defaultErrorHandler = handler;\n}\n"],"names":["logger","errorUtils","ErrorSeverity","FrameworkError","ErrorHandlingStrategy","ErrorHandler","setMonitoring","monitoring","handleError","error","context","normalizedError","normalizeError","errorWithContext","message","type","severity","code","originalError","recoverable","strategies","determineStrategies","handled","executeStrategies","recoveredValue","config","recoveryOptions","recoveryResult","attemptRecovery","value","typeStrategies","severityStrategies","defaultStrategies","strategy","logError","reportError","strategyError","warn","errorInfo","extractErrorInfo","CRITICAL","HIGH","MEDIUM","LOW","info","showDetailedErrorsInDev","process","env","NODE_ENV","detailedError","formatErrorForDev","console","debug","captureError","options","maxRetries","retryDelay","exponentialBackoff","shouldRetry","fallback","fallbackValue","Promise","resolve","fallbackError","attempt","delay","Math","pow","setTimeout","create","defaultErrorHandler","getDefaultErrorHandler","setDefaultErrorHandler","handler"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ Object.defineProperty(exports, "AppEventBus", {
|
|
|
11
11
|
return AppEventBus;
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
|
-
const
|
|
14
|
+
const _logger = require("@vlian/logger");
|
|
15
15
|
function _define_property(obj, key, value) {
|
|
16
16
|
if (key in obj) {
|
|
17
17
|
Object.defineProperty(obj, key, {
|
|
@@ -133,13 +133,13 @@ let AppEventBus = class AppEventBus {
|
|
|
133
133
|
const startTime = this.config.enablePerformanceMonitoring ? performance.now() : 0;
|
|
134
134
|
// 事件验证
|
|
135
135
|
if (this.config.enableValidation && !this.config.validator(fullEventName, data)) {
|
|
136
|
-
|
|
136
|
+
_logger.logger.warn(`事件 ${fullEventName} 验证失败,已忽略`);
|
|
137
137
|
return;
|
|
138
138
|
}
|
|
139
139
|
// 安全检查
|
|
140
140
|
if (this.config.enableSecurityMode && metadata?.source) {
|
|
141
141
|
if (!this.config.allowedSources.includes(metadata.source)) {
|
|
142
|
-
|
|
142
|
+
_logger.logger.warn(`事件 ${fullEventName} 的来源 ${metadata.source} 不在白名单中,已忽略`);
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -214,7 +214,7 @@ let AppEventBus = class AppEventBus {
|
|
|
214
214
|
listenersToRemove.push(listenerWithOptions);
|
|
215
215
|
}
|
|
216
216
|
} catch (error) {
|
|
217
|
-
|
|
217
|
+
_logger.logger.error(`事件 ${fullEventName} 的监听器执行失败:`, error);
|
|
218
218
|
}
|
|
219
219
|
};
|
|
220
220
|
executionPromises.push(executeListener());
|
|
@@ -241,7 +241,7 @@ let AppEventBus = class AppEventBus {
|
|
|
241
241
|
*/ emitSync(event, data, metadata) {
|
|
242
242
|
// 同步执行 emit,但不等待 Promise 完成
|
|
243
243
|
this.emit(event, data, metadata).catch((error)=>{
|
|
244
|
-
|
|
244
|
+
_logger.logger.error(`同步发布事件 ${event} 失败:`, error);
|
|
245
245
|
});
|
|
246
246
|
}
|
|
247
247
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/event/AppEventBus.ts"],"sourcesContent":["/**\n * 应用级事件总线\n * 提供高性能、类型安全、可观测的事件通信能力\n */\n\nimport { logger } from '../../utils';\nimport type {\n EventListener,\n EventMetadata,\n EventWrapper,\n EventMiddleware,\n EventListenerOptions,\n AppEventBusConfig,\n EventStats,\n} from './types';\n\n/**\n * 带选项的监听器\n */\ninterface ListenerWithOptions {\n listener: EventListener;\n options: Required<EventListenerOptions>;\n id: symbol;\n}\n\n/**\n * 事件历史记录\n */\ninterface EventHistoryRecord {\n event: string;\n data: unknown;\n metadata: EventMetadata;\n executionTime?: number;\n}\n\n/**\n * 应用事件总线\n */\nexport class AppEventBus {\n /**\n * 事件监听器映射表\n * 使用 Map + Set 结构提高性能\n */\n private listeners: Map<string, Set<ListenerWithOptions>> = new Map();\n \n /**\n * 事件历史记录\n */\n private eventHistory: EventHistoryRecord[] = [];\n \n /**\n * 事件中间件列表\n */\n private middlewares: EventMiddleware[] = [];\n \n /**\n * 事件统计信息\n */\n private stats: Map<string, EventStats> = new Map();\n \n /**\n * 配置\n */\n private config: Required<AppEventBusConfig>;\n \n /**\n * 事件计数器(用于生成唯一事件ID)\n */\n private eventCounter: number = 0;\n \n /**\n * 监听器ID计数器\n */\n private listenerIdCounter: number = 0;\n\n constructor(config: AppEventBusConfig = {}) {\n this.config = {\n enableTracking: config.enableTracking ?? (process.env.NODE_ENV === 'development'),\n maxHistorySize: config.maxHistorySize ?? 100,\n enableValidation: config.enableValidation ?? false,\n validator: config.validator ?? (() => true),\n enablePerformanceMonitoring: config.enablePerformanceMonitoring ?? (process.env.NODE_ENV === 'development'),\n namespacePrefix: config.namespacePrefix ?? '',\n instanceId: config.instanceId,\n enableSecurityMode: config.enableSecurityMode ?? false,\n allowedSources: config.allowedSources ?? [],\n } as Required<AppEventBusConfig>;\n }\n\n /**\n * 订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器\n * @param options - 监听器选项\n * @returns 取消订阅函数\n * \n * @example\n * ```typescript\n * const unsubscribe = eventBus.on('user:login', (data, metadata) => {\n * console.log('用户登录:', data);\n * });\n * \n * // 取消订阅\n * unsubscribe();\n * ```\n */\n on<T = unknown>(\n event: string,\n listener: EventListener<T>,\n options: EventListenerOptions = {}\n ): () => void {\n const fullEventName = this.getFullEventName(event);\n const listenerId = Symbol(`listener_${++this.listenerIdCounter}`);\n \n const listenerWithOptions: ListenerWithOptions = {\n listener: listener as EventListener,\n options: {\n priority: options.priority ?? 100,\n once: options.once ?? false,\n namespace: options.namespace ?? this.config.namespacePrefix,\n async: options.async ?? true,\n },\n id: listenerId,\n };\n\n if (!this.listeners.has(fullEventName)) {\n this.listeners.set(fullEventName, new Set());\n }\n\n const listeners = this.listeners.get(fullEventName)!;\n listeners.add(listenerWithOptions);\n\n // 按优先级排序(数字越小优先级越高)\n const sortedListeners = Array.from(listeners).sort(\n (a, b) => a.options.priority - b.options.priority\n );\n this.listeners.set(fullEventName, new Set(sortedListeners));\n\n // 返回取消订阅函数\n return () => {\n const currentListeners = this.listeners.get(fullEventName);\n if (currentListeners) {\n currentListeners.delete(listenerWithOptions);\n if (currentListeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n }\n };\n }\n\n /**\n * 取消订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器(可选,不提供则取消该事件的所有监听器)\n */\n off<T = unknown>(event: string, listener?: EventListener<T>): void {\n const fullEventName = this.getFullEventName(event);\n const listeners = this.listeners.get(fullEventName);\n \n if (!listeners) {\n return;\n }\n\n if (listener) {\n // 移除指定的监听器\n for (const item of listeners) {\n if (item.listener === listener) {\n listeners.delete(item);\n break;\n }\n }\n } else {\n // 移除所有监听器\n listeners.clear();\n }\n\n if (listeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n }\n\n /**\n * 一次性订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器\n * @param options - 监听器选项\n */\n once<T = unknown>(\n event: string,\n listener: EventListener<T>,\n options?: Omit<EventListenerOptions, 'once'>\n ): () => void {\n return this.on(event, listener, { ...options, once: true });\n }\n\n /**\n * 发布事件\n * \n * @param event - 事件名称\n * @param data - 事件数据\n * @param metadata - 事件元数据(可选)\n * \n * @example\n * ```typescript\n * await eventBus.emit('user:login', {\n * userId: '123',\n * username: 'john',\n * });\n * ```\n */\n async emit<T = unknown>(\n event: string,\n data?: T,\n metadata?: Partial<EventMetadata>\n ): Promise<void> {\n const fullEventName = this.getFullEventName(event);\n const startTime = this.config.enablePerformanceMonitoring ? performance.now() : 0;\n\n // 事件验证\n if (this.config.enableValidation && !this.config.validator(fullEventName, data)) {\n logger.warn(`事件 ${fullEventName} 验证失败,已忽略`);\n return;\n }\n\n // 安全检查\n if (this.config.enableSecurityMode && metadata?.source) {\n if (!this.config.allowedSources.includes(metadata.source)) {\n logger.warn(`事件 ${fullEventName} 的来源 ${metadata.source} 不在白名单中,已忽略`);\n return;\n }\n }\n\n // 构建事件元数据\n const eventMetadata: EventMetadata = {\n source: metadata?.source,\n timestamp: metadata?.timestamp ?? Date.now(),\n eventId: metadata?.eventId ?? `event_${++this.eventCounter}`,\n priority: metadata?.priority ?? 0,\n instanceId: metadata?.instanceId ?? this.config.instanceId,\n namespace: metadata?.namespace ?? this.config.namespacePrefix,\n ...metadata,\n };\n\n // 创建事件包装器\n const eventWrapper: EventWrapper<T> = {\n data: data as T,\n metadata: eventMetadata,\n };\n\n // 执行中间件(中间件可以阻止事件传播)\n if (this.middlewares.length > 0) {\n let middlewareIndex = 0;\n let nextCalled = false;\n \n const executeMiddleware = async (): Promise<void> => {\n if (middlewareIndex < this.middlewares.length) {\n nextCalled = false;\n const currentIndex = middlewareIndex;\n const middleware = this.middlewares[middlewareIndex++];\n \n const next = async () => {\n nextCalled = true;\n if (currentIndex < this.middlewares.length - 1) {\n await executeMiddleware();\n }\n };\n \n await Promise.resolve(middleware(fullEventName, data, eventMetadata, next));\n \n // 如果中间件没有调用 next(),阻止事件传播\n if (!nextCalled) {\n return;\n }\n }\n };\n \n await executeMiddleware();\n \n // 如果最后一个中间件没有调用 next(),阻止事件传播\n if (!nextCalled && this.middlewares.length > 0) {\n return;\n }\n }\n\n // 获取监听器\n const listeners = this.listeners.get(fullEventName);\n \n // 记录事件历史(无论是否有监听器)\n if (this.config.enableTracking) {\n const executionTime = this.config.enablePerformanceMonitoring\n ? performance.now() - startTime\n : undefined;\n this.recordEventHistory(fullEventName, data, eventMetadata, executionTime);\n }\n \n if (!listeners || listeners.size === 0) {\n // 更新统计(即使没有监听器也记录)\n this.updateStats(fullEventName, 0);\n return;\n }\n\n // 执行监听器\n const executionPromises: Promise<void>[] = [];\n const listenersToRemove: ListenerWithOptions[] = [];\n\n for (const listenerWithOptions of listeners) {\n const executeListener = async () => {\n try {\n if (listenerWithOptions.options.async) {\n await Promise.resolve(\n listenerWithOptions.listener(eventWrapper.data, eventWrapper.metadata)\n );\n } else {\n listenerWithOptions.listener(eventWrapper.data, eventWrapper.metadata);\n }\n\n // 如果是一次性监听器,标记为待移除\n if (listenerWithOptions.options.once) {\n listenersToRemove.push(listenerWithOptions);\n }\n } catch (error) {\n logger.error(`事件 ${fullEventName} 的监听器执行失败:`, error);\n }\n };\n\n executionPromises.push(executeListener());\n }\n\n // 等待所有监听器执行完成\n await Promise.allSettled(executionPromises);\n\n // 移除一次性监听器\n for (const listenerToRemove of listenersToRemove) {\n listeners.delete(listenerToRemove);\n }\n\n if (listeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n\n // 更新统计信息\n const executionTime = this.config.enablePerformanceMonitoring\n ? performance.now() - startTime\n : 0;\n this.updateStats(fullEventName, executionTime, listeners.size);\n }\n\n /**\n * 同步发布事件(不等待异步监听器完成)\n * \n * @param event - 事件名称\n * @param data - 事件数据\n * @param metadata - 事件元数据(可选)\n */\n emitSync<T = unknown>(\n event: string,\n data?: T,\n metadata?: Partial<EventMetadata>\n ): void {\n // 同步执行 emit,但不等待 Promise 完成\n this.emit(event, data, metadata).catch((error) => {\n logger.error(`同步发布事件 ${event} 失败:`, error);\n });\n }\n\n /**\n * 注册事件中间件\n * \n * @param middleware - 中间件函数\n * @returns 取消注册函数\n * \n * @example\n * ```typescript\n * const unsubscribe = eventBus.use((event, data, metadata, next) => {\n * console.log('事件触发:', event);\n * return next();\n * });\n * ```\n */\n use(middleware: EventMiddleware): () => void {\n this.middlewares.push(middleware);\n \n return () => {\n const index = this.middlewares.indexOf(middleware);\n if (index > -1) {\n this.middlewares.splice(index, 1);\n }\n };\n }\n\n /**\n * 清空所有事件监听器\n */\n clear(): void {\n this.listeners.clear();\n }\n\n /**\n * 清空事件历史记录\n */\n clearHistory(): void {\n this.eventHistory = [];\n }\n\n /**\n * 获取事件监听器数量\n * \n * @param event - 事件名称(可选,不提供则返回所有事件的监听器总数)\n */\n listenerCount(event?: string): number {\n if (event) {\n const fullEventName = this.getFullEventName(event);\n return this.listeners.get(fullEventName)?.size || 0;\n }\n\n let count = 0;\n for (const listeners of this.listeners.values()) {\n count += listeners.size;\n }\n return count;\n }\n\n /**\n * 获取所有事件名称\n */\n eventNames(): string[] {\n return Array.from(this.listeners.keys());\n }\n\n /**\n * 获取事件历史记录\n * \n * @param event - 事件名称(可选,如果提供则只返回该事件的历史)\n * @param limit - 限制返回的记录数\n */\n getEventHistory(event?: string, limit?: number): EventHistoryRecord[] {\n if (!this.config.enableTracking) {\n return [];\n }\n\n let history = this.eventHistory;\n if (event) {\n const fullEventName = this.getFullEventName(event);\n history = history.filter((h) => h.event === fullEventName);\n }\n\n if (limit) {\n history = history.slice(-limit);\n }\n\n return [...history];\n }\n\n /**\n * 获取事件统计信息\n * \n * @param event - 事件名称(可选,不提供则返回所有事件的统计)\n */\n getStats(event?: string): EventStats | Map<string, EventStats> {\n if (event) {\n const fullEventName = this.getFullEventName(event);\n return this.stats.get(fullEventName) || {\n event: fullEventName,\n count: 0,\n avgExecutionTime: 0,\n listenerCount: 0,\n lastTriggered: 0,\n };\n }\n\n return new Map(this.stats);\n }\n\n /**\n * 获取配置\n */\n getConfig(): AppEventBusConfig {\n return { ...this.config };\n }\n\n /**\n * 更新配置\n */\n updateConfig(config: Partial<AppEventBusConfig>): void {\n this.config = {\n ...this.config,\n ...config,\n };\n }\n\n /**\n * 销毁事件总线(清理所有资源)\n */\n destroy(): void {\n this.clear();\n this.clearHistory();\n this.middlewares = [];\n this.stats.clear();\n }\n\n /**\n * 获取完整事件名称(包含命名空间前缀)\n */\n private getFullEventName(event: string): string {\n if (this.config.namespacePrefix) {\n return `${this.config.namespacePrefix}${event}`;\n }\n return event;\n }\n\n /**\n * 记录事件历史\n */\n private recordEventHistory(\n event: string,\n data: unknown,\n metadata: EventMetadata,\n executionTime?: number\n ): void {\n this.eventHistory.push({\n event,\n data,\n metadata,\n executionTime,\n });\n\n // 限制历史记录大小\n if (this.eventHistory.length > this.config.maxHistorySize) {\n this.eventHistory.shift();\n }\n }\n\n /**\n * 更新统计信息\n */\n private updateStats(\n event: string,\n executionTime: number,\n listenerCount: number = 0\n ): void {\n if (!this.config.enablePerformanceMonitoring) {\n return;\n }\n\n const existingStats = this.stats.get(event);\n if (existingStats) {\n const totalTime = existingStats.avgExecutionTime * existingStats.count + executionTime;\n const newCount = existingStats.count + 1;\n \n this.stats.set(event, {\n ...existingStats,\n count: newCount,\n avgExecutionTime: totalTime / newCount,\n listenerCount,\n lastTriggered: Date.now(),\n });\n } else {\n this.stats.set(event, {\n event,\n count: 1,\n avgExecutionTime: executionTime,\n listenerCount,\n lastTriggered: Date.now(),\n });\n }\n }\n}\n"],"names":["AppEventBus","on","event","listener","options","fullEventName","getFullEventName","listenerId","Symbol","listenerIdCounter","listenerWithOptions","priority","once","namespace","config","namespacePrefix","async","id","listeners","has","set","Set","get","add","sortedListeners","Array","from","sort","a","b","currentListeners","delete","size","off","item","clear","emit","data","metadata","startTime","enablePerformanceMonitoring","performance","now","enableValidation","validator","logger","warn","enableSecurityMode","source","allowedSources","includes","eventMetadata","timestamp","Date","eventId","eventCounter","instanceId","eventWrapper","middlewares","length","middlewareIndex","nextCalled","executeMiddleware","currentIndex","middleware","next","Promise","resolve","enableTracking","executionTime","undefined","recordEventHistory","updateStats","executionPromises","listenersToRemove","executeListener","push","error","allSettled","listenerToRemove","emitSync","catch","use","index","indexOf","splice","clearHistory","eventHistory","listenerCount","count","values","eventNames","keys","getEventHistory","limit","history","filter","h","slice","getStats","stats","avgExecutionTime","lastTriggered","Map","getConfig","updateConfig","destroy","maxHistorySize","shift","existingStats","totalTime","newCount","process","env","NODE_ENV"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/event/AppEventBus.ts"],"sourcesContent":["/**\n * 应用级事件总线\n * 提供高性能、类型安全、可观测的事件通信能力\n */\n\nimport { logger } from '@vlian/logger';\nimport type {\n EventListener,\n EventMetadata,\n EventWrapper,\n EventMiddleware,\n EventListenerOptions,\n AppEventBusConfig,\n EventStats,\n} from './types';\n\n/**\n * 带选项的监听器\n */\ninterface ListenerWithOptions {\n listener: EventListener;\n options: Required<EventListenerOptions>;\n id: symbol;\n}\n\n/**\n * 事件历史记录\n */\ninterface EventHistoryRecord {\n event: string;\n data: unknown;\n metadata: EventMetadata;\n executionTime?: number;\n}\n\n/**\n * 应用事件总线\n */\nexport class AppEventBus {\n /**\n * 事件监听器映射表\n * 使用 Map + Set 结构提高性能\n */\n private listeners: Map<string, Set<ListenerWithOptions>> = new Map();\n \n /**\n * 事件历史记录\n */\n private eventHistory: EventHistoryRecord[] = [];\n \n /**\n * 事件中间件列表\n */\n private middlewares: EventMiddleware[] = [];\n \n /**\n * 事件统计信息\n */\n private stats: Map<string, EventStats> = new Map();\n \n /**\n * 配置\n */\n private config: Required<AppEventBusConfig>;\n \n /**\n * 事件计数器(用于生成唯一事件ID)\n */\n private eventCounter: number = 0;\n \n /**\n * 监听器ID计数器\n */\n private listenerIdCounter: number = 0;\n\n constructor(config: AppEventBusConfig = {}) {\n this.config = {\n enableTracking: config.enableTracking ?? (process.env.NODE_ENV === 'development'),\n maxHistorySize: config.maxHistorySize ?? 100,\n enableValidation: config.enableValidation ?? false,\n validator: config.validator ?? (() => true),\n enablePerformanceMonitoring: config.enablePerformanceMonitoring ?? (process.env.NODE_ENV === 'development'),\n namespacePrefix: config.namespacePrefix ?? '',\n instanceId: config.instanceId,\n enableSecurityMode: config.enableSecurityMode ?? false,\n allowedSources: config.allowedSources ?? [],\n } as Required<AppEventBusConfig>;\n }\n\n /**\n * 订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器\n * @param options - 监听器选项\n * @returns 取消订阅函数\n * \n * @example\n * ```typescript\n * const unsubscribe = eventBus.on('user:login', (data, metadata) => {\n * console.log('用户登录:', data);\n * });\n * \n * // 取消订阅\n * unsubscribe();\n * ```\n */\n on<T = unknown>(\n event: string,\n listener: EventListener<T>,\n options: EventListenerOptions = {}\n ): () => void {\n const fullEventName = this.getFullEventName(event);\n const listenerId = Symbol(`listener_${++this.listenerIdCounter}`);\n \n const listenerWithOptions: ListenerWithOptions = {\n listener: listener as EventListener,\n options: {\n priority: options.priority ?? 100,\n once: options.once ?? false,\n namespace: options.namespace ?? this.config.namespacePrefix,\n async: options.async ?? true,\n },\n id: listenerId,\n };\n\n if (!this.listeners.has(fullEventName)) {\n this.listeners.set(fullEventName, new Set());\n }\n\n const listeners = this.listeners.get(fullEventName)!;\n listeners.add(listenerWithOptions);\n\n // 按优先级排序(数字越小优先级越高)\n const sortedListeners = Array.from(listeners).sort(\n (a, b) => a.options.priority - b.options.priority\n );\n this.listeners.set(fullEventName, new Set(sortedListeners));\n\n // 返回取消订阅函数\n return () => {\n const currentListeners = this.listeners.get(fullEventName);\n if (currentListeners) {\n currentListeners.delete(listenerWithOptions);\n if (currentListeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n }\n };\n }\n\n /**\n * 取消订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器(可选,不提供则取消该事件的所有监听器)\n */\n off<T = unknown>(event: string, listener?: EventListener<T>): void {\n const fullEventName = this.getFullEventName(event);\n const listeners = this.listeners.get(fullEventName);\n \n if (!listeners) {\n return;\n }\n\n if (listener) {\n // 移除指定的监听器\n for (const item of listeners) {\n if (item.listener === listener) {\n listeners.delete(item);\n break;\n }\n }\n } else {\n // 移除所有监听器\n listeners.clear();\n }\n\n if (listeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n }\n\n /**\n * 一次性订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器\n * @param options - 监听器选项\n */\n once<T = unknown>(\n event: string,\n listener: EventListener<T>,\n options?: Omit<EventListenerOptions, 'once'>\n ): () => void {\n return this.on(event, listener, { ...options, once: true });\n }\n\n /**\n * 发布事件\n * \n * @param event - 事件名称\n * @param data - 事件数据\n * @param metadata - 事件元数据(可选)\n * \n * @example\n * ```typescript\n * await eventBus.emit('user:login', {\n * userId: '123',\n * username: 'john',\n * });\n * ```\n */\n async emit<T = unknown>(\n event: string,\n data?: T,\n metadata?: Partial<EventMetadata>\n ): Promise<void> {\n const fullEventName = this.getFullEventName(event);\n const startTime = this.config.enablePerformanceMonitoring ? performance.now() : 0;\n\n // 事件验证\n if (this.config.enableValidation && !this.config.validator(fullEventName, data)) {\n logger.warn(`事件 ${fullEventName} 验证失败,已忽略`);\n return;\n }\n\n // 安全检查\n if (this.config.enableSecurityMode && metadata?.source) {\n if (!this.config.allowedSources.includes(metadata.source)) {\n logger.warn(`事件 ${fullEventName} 的来源 ${metadata.source} 不在白名单中,已忽略`);\n return;\n }\n }\n\n // 构建事件元数据\n const eventMetadata: EventMetadata = {\n source: metadata?.source,\n timestamp: metadata?.timestamp ?? Date.now(),\n eventId: metadata?.eventId ?? `event_${++this.eventCounter}`,\n priority: metadata?.priority ?? 0,\n instanceId: metadata?.instanceId ?? this.config.instanceId,\n namespace: metadata?.namespace ?? this.config.namespacePrefix,\n ...metadata,\n };\n\n // 创建事件包装器\n const eventWrapper: EventWrapper<T> = {\n data: data as T,\n metadata: eventMetadata,\n };\n\n // 执行中间件(中间件可以阻止事件传播)\n if (this.middlewares.length > 0) {\n let middlewareIndex = 0;\n let nextCalled = false;\n \n const executeMiddleware = async (): Promise<void> => {\n if (middlewareIndex < this.middlewares.length) {\n nextCalled = false;\n const currentIndex = middlewareIndex;\n const middleware = this.middlewares[middlewareIndex++];\n \n const next = async () => {\n nextCalled = true;\n if (currentIndex < this.middlewares.length - 1) {\n await executeMiddleware();\n }\n };\n \n await Promise.resolve(middleware(fullEventName, data, eventMetadata, next));\n \n // 如果中间件没有调用 next(),阻止事件传播\n if (!nextCalled) {\n return;\n }\n }\n };\n \n await executeMiddleware();\n \n // 如果最后一个中间件没有调用 next(),阻止事件传播\n if (!nextCalled && this.middlewares.length > 0) {\n return;\n }\n }\n\n // 获取监听器\n const listeners = this.listeners.get(fullEventName);\n \n // 记录事件历史(无论是否有监听器)\n if (this.config.enableTracking) {\n const executionTime = this.config.enablePerformanceMonitoring\n ? performance.now() - startTime\n : undefined;\n this.recordEventHistory(fullEventName, data, eventMetadata, executionTime);\n }\n \n if (!listeners || listeners.size === 0) {\n // 更新统计(即使没有监听器也记录)\n this.updateStats(fullEventName, 0);\n return;\n }\n\n // 执行监听器\n const executionPromises: Promise<void>[] = [];\n const listenersToRemove: ListenerWithOptions[] = [];\n\n for (const listenerWithOptions of listeners) {\n const executeListener = async () => {\n try {\n if (listenerWithOptions.options.async) {\n await Promise.resolve(\n listenerWithOptions.listener(eventWrapper.data, eventWrapper.metadata)\n );\n } else {\n listenerWithOptions.listener(eventWrapper.data, eventWrapper.metadata);\n }\n\n // 如果是一次性监听器,标记为待移除\n if (listenerWithOptions.options.once) {\n listenersToRemove.push(listenerWithOptions);\n }\n } catch (error) {\n logger.error(`事件 ${fullEventName} 的监听器执行失败:`, error);\n }\n };\n\n executionPromises.push(executeListener());\n }\n\n // 等待所有监听器执行完成\n await Promise.allSettled(executionPromises);\n\n // 移除一次性监听器\n for (const listenerToRemove of listenersToRemove) {\n listeners.delete(listenerToRemove);\n }\n\n if (listeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n\n // 更新统计信息\n const executionTime = this.config.enablePerformanceMonitoring\n ? performance.now() - startTime\n : 0;\n this.updateStats(fullEventName, executionTime, listeners.size);\n }\n\n /**\n * 同步发布事件(不等待异步监听器完成)\n * \n * @param event - 事件名称\n * @param data - 事件数据\n * @param metadata - 事件元数据(可选)\n */\n emitSync<T = unknown>(\n event: string,\n data?: T,\n metadata?: Partial<EventMetadata>\n ): void {\n // 同步执行 emit,但不等待 Promise 完成\n this.emit(event, data, metadata).catch((error) => {\n logger.error(`同步发布事件 ${event} 失败:`, error);\n });\n }\n\n /**\n * 注册事件中间件\n * \n * @param middleware - 中间件函数\n * @returns 取消注册函数\n * \n * @example\n * ```typescript\n * const unsubscribe = eventBus.use((event, data, metadata, next) => {\n * console.log('事件触发:', event);\n * return next();\n * });\n * ```\n */\n use(middleware: EventMiddleware): () => void {\n this.middlewares.push(middleware);\n \n return () => {\n const index = this.middlewares.indexOf(middleware);\n if (index > -1) {\n this.middlewares.splice(index, 1);\n }\n };\n }\n\n /**\n * 清空所有事件监听器\n */\n clear(): void {\n this.listeners.clear();\n }\n\n /**\n * 清空事件历史记录\n */\n clearHistory(): void {\n this.eventHistory = [];\n }\n\n /**\n * 获取事件监听器数量\n * \n * @param event - 事件名称(可选,不提供则返回所有事件的监听器总数)\n */\n listenerCount(event?: string): number {\n if (event) {\n const fullEventName = this.getFullEventName(event);\n return this.listeners.get(fullEventName)?.size || 0;\n }\n\n let count = 0;\n for (const listeners of this.listeners.values()) {\n count += listeners.size;\n }\n return count;\n }\n\n /**\n * 获取所有事件名称\n */\n eventNames(): string[] {\n return Array.from(this.listeners.keys());\n }\n\n /**\n * 获取事件历史记录\n * \n * @param event - 事件名称(可选,如果提供则只返回该事件的历史)\n * @param limit - 限制返回的记录数\n */\n getEventHistory(event?: string, limit?: number): EventHistoryRecord[] {\n if (!this.config.enableTracking) {\n return [];\n }\n\n let history = this.eventHistory;\n if (event) {\n const fullEventName = this.getFullEventName(event);\n history = history.filter((h) => h.event === fullEventName);\n }\n\n if (limit) {\n history = history.slice(-limit);\n }\n\n return [...history];\n }\n\n /**\n * 获取事件统计信息\n * \n * @param event - 事件名称(可选,不提供则返回所有事件的统计)\n */\n getStats(event?: string): EventStats | Map<string, EventStats> {\n if (event) {\n const fullEventName = this.getFullEventName(event);\n return this.stats.get(fullEventName) || {\n event: fullEventName,\n count: 0,\n avgExecutionTime: 0,\n listenerCount: 0,\n lastTriggered: 0,\n };\n }\n\n return new Map(this.stats);\n }\n\n /**\n * 获取配置\n */\n getConfig(): AppEventBusConfig {\n return { ...this.config };\n }\n\n /**\n * 更新配置\n */\n updateConfig(config: Partial<AppEventBusConfig>): void {\n this.config = {\n ...this.config,\n ...config,\n };\n }\n\n /**\n * 销毁事件总线(清理所有资源)\n */\n destroy(): void {\n this.clear();\n this.clearHistory();\n this.middlewares = [];\n this.stats.clear();\n }\n\n /**\n * 获取完整事件名称(包含命名空间前缀)\n */\n private getFullEventName(event: string): string {\n if (this.config.namespacePrefix) {\n return `${this.config.namespacePrefix}${event}`;\n }\n return event;\n }\n\n /**\n * 记录事件历史\n */\n private recordEventHistory(\n event: string,\n data: unknown,\n metadata: EventMetadata,\n executionTime?: number\n ): void {\n this.eventHistory.push({\n event,\n data,\n metadata,\n executionTime,\n });\n\n // 限制历史记录大小\n if (this.eventHistory.length > this.config.maxHistorySize) {\n this.eventHistory.shift();\n }\n }\n\n /**\n * 更新统计信息\n */\n private updateStats(\n event: string,\n executionTime: number,\n listenerCount: number = 0\n ): void {\n if (!this.config.enablePerformanceMonitoring) {\n return;\n }\n\n const existingStats = this.stats.get(event);\n if (existingStats) {\n const totalTime = existingStats.avgExecutionTime * existingStats.count + executionTime;\n const newCount = existingStats.count + 1;\n \n this.stats.set(event, {\n ...existingStats,\n count: newCount,\n avgExecutionTime: totalTime / newCount,\n listenerCount,\n lastTriggered: Date.now(),\n });\n } else {\n this.stats.set(event, {\n event,\n count: 1,\n avgExecutionTime: executionTime,\n listenerCount,\n lastTriggered: Date.now(),\n });\n }\n }\n}\n"],"names":["AppEventBus","on","event","listener","options","fullEventName","getFullEventName","listenerId","Symbol","listenerIdCounter","listenerWithOptions","priority","once","namespace","config","namespacePrefix","async","id","listeners","has","set","Set","get","add","sortedListeners","Array","from","sort","a","b","currentListeners","delete","size","off","item","clear","emit","data","metadata","startTime","enablePerformanceMonitoring","performance","now","enableValidation","validator","logger","warn","enableSecurityMode","source","allowedSources","includes","eventMetadata","timestamp","Date","eventId","eventCounter","instanceId","eventWrapper","middlewares","length","middlewareIndex","nextCalled","executeMiddleware","currentIndex","middleware","next","Promise","resolve","enableTracking","executionTime","undefined","recordEventHistory","updateStats","executionPromises","listenersToRemove","executeListener","push","error","allSettled","listenerToRemove","emitSync","catch","use","index","indexOf","splice","clearHistory","eventHistory","listenerCount","count","values","eventNames","keys","getEventHistory","limit","history","filter","h","slice","getStats","stats","avgExecutionTime","lastTriggered","Map","getConfig","updateConfig","destroy","maxHistorySize","shift","existingStats","totalTime","newCount","process","env","NODE_ENV"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/event/AppEventBus.ts"],"sourcesContent":["/**\n * 应用级事件总线\n * 提供高性能、类型安全、可观测的事件通信能力\n */\n\nimport { logger } from '../../utils';\nimport type {\n EventListener,\n EventMetadata,\n EventWrapper,\n EventMiddleware,\n EventListenerOptions,\n AppEventBusConfig,\n EventStats,\n} from './types';\n\n/**\n * 带选项的监听器\n */\ninterface ListenerWithOptions {\n listener: EventListener;\n options: Required<EventListenerOptions>;\n id: symbol;\n}\n\n/**\n * 事件历史记录\n */\ninterface EventHistoryRecord {\n event: string;\n data: unknown;\n metadata: EventMetadata;\n executionTime?: number;\n}\n\n/**\n * 应用事件总线\n */\nexport class AppEventBus {\n /**\n * 事件监听器映射表\n * 使用 Map + Set 结构提高性能\n */\n private listeners: Map<string, Set<ListenerWithOptions>> = new Map();\n \n /**\n * 事件历史记录\n */\n private eventHistory: EventHistoryRecord[] = [];\n \n /**\n * 事件中间件列表\n */\n private middlewares: EventMiddleware[] = [];\n \n /**\n * 事件统计信息\n */\n private stats: Map<string, EventStats> = new Map();\n \n /**\n * 配置\n */\n private config: Required<AppEventBusConfig>;\n \n /**\n * 事件计数器(用于生成唯一事件ID)\n */\n private eventCounter: number = 0;\n \n /**\n * 监听器ID计数器\n */\n private listenerIdCounter: number = 0;\n\n constructor(config: AppEventBusConfig = {}) {\n this.config = {\n enableTracking: config.enableTracking ?? (process.env.NODE_ENV === 'development'),\n maxHistorySize: config.maxHistorySize ?? 100,\n enableValidation: config.enableValidation ?? false,\n validator: config.validator ?? (() => true),\n enablePerformanceMonitoring: config.enablePerformanceMonitoring ?? (process.env.NODE_ENV === 'development'),\n namespacePrefix: config.namespacePrefix ?? '',\n instanceId: config.instanceId,\n enableSecurityMode: config.enableSecurityMode ?? false,\n allowedSources: config.allowedSources ?? [],\n } as Required<AppEventBusConfig>;\n }\n\n /**\n * 订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器\n * @param options - 监听器选项\n * @returns 取消订阅函数\n * \n * @example\n * ```typescript\n * const unsubscribe = eventBus.on('user:login', (data, metadata) => {\n * console.log('用户登录:', data);\n * });\n * \n * // 取消订阅\n * unsubscribe();\n * ```\n */\n on<T = unknown>(\n event: string,\n listener: EventListener<T>,\n options: EventListenerOptions = {}\n ): () => void {\n const fullEventName = this.getFullEventName(event);\n const listenerId = Symbol(`listener_${++this.listenerIdCounter}`);\n \n const listenerWithOptions: ListenerWithOptions = {\n listener: listener as EventListener,\n options: {\n priority: options.priority ?? 100,\n once: options.once ?? false,\n namespace: options.namespace ?? this.config.namespacePrefix,\n async: options.async ?? true,\n },\n id: listenerId,\n };\n\n if (!this.listeners.has(fullEventName)) {\n this.listeners.set(fullEventName, new Set());\n }\n\n const listeners = this.listeners.get(fullEventName)!;\n listeners.add(listenerWithOptions);\n\n // 按优先级排序(数字越小优先级越高)\n const sortedListeners = Array.from(listeners).sort(\n (a, b) => a.options.priority - b.options.priority\n );\n this.listeners.set(fullEventName, new Set(sortedListeners));\n\n // 返回取消订阅函数\n return () => {\n const currentListeners = this.listeners.get(fullEventName);\n if (currentListeners) {\n currentListeners.delete(listenerWithOptions);\n if (currentListeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n }\n };\n }\n\n /**\n * 取消订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器(可选,不提供则取消该事件的所有监听器)\n */\n off<T = unknown>(event: string, listener?: EventListener<T>): void {\n const fullEventName = this.getFullEventName(event);\n const listeners = this.listeners.get(fullEventName);\n \n if (!listeners) {\n return;\n }\n\n if (listener) {\n // 移除指定的监听器\n for (const item of listeners) {\n if (item.listener === listener) {\n listeners.delete(item);\n break;\n }\n }\n } else {\n // 移除所有监听器\n listeners.clear();\n }\n\n if (listeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n }\n\n /**\n * 一次性订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器\n * @param options - 监听器选项\n */\n once<T = unknown>(\n event: string,\n listener: EventListener<T>,\n options?: Omit<EventListenerOptions, 'once'>\n ): () => void {\n return this.on(event, listener, { ...options, once: true });\n }\n\n /**\n * 发布事件\n * \n * @param event - 事件名称\n * @param data - 事件数据\n * @param metadata - 事件元数据(可选)\n * \n * @example\n * ```typescript\n * await eventBus.emit('user:login', {\n * userId: '123',\n * username: 'john',\n * });\n * ```\n */\n async emit<T = unknown>(\n event: string,\n data?: T,\n metadata?: Partial<EventMetadata>\n ): Promise<void> {\n const fullEventName = this.getFullEventName(event);\n const startTime = this.config.enablePerformanceMonitoring ? performance.now() : 0;\n\n // 事件验证\n if (this.config.enableValidation && !this.config.validator(fullEventName, data)) {\n logger.warn(`事件 ${fullEventName} 验证失败,已忽略`);\n return;\n }\n\n // 安全检查\n if (this.config.enableSecurityMode && metadata?.source) {\n if (!this.config.allowedSources.includes(metadata.source)) {\n logger.warn(`事件 ${fullEventName} 的来源 ${metadata.source} 不在白名单中,已忽略`);\n return;\n }\n }\n\n // 构建事件元数据\n const eventMetadata: EventMetadata = {\n source: metadata?.source,\n timestamp: metadata?.timestamp ?? Date.now(),\n eventId: metadata?.eventId ?? `event_${++this.eventCounter}`,\n priority: metadata?.priority ?? 0,\n instanceId: metadata?.instanceId ?? this.config.instanceId,\n namespace: metadata?.namespace ?? this.config.namespacePrefix,\n ...metadata,\n };\n\n // 创建事件包装器\n const eventWrapper: EventWrapper<T> = {\n data: data as T,\n metadata: eventMetadata,\n };\n\n // 执行中间件(中间件可以阻止事件传播)\n if (this.middlewares.length > 0) {\n let middlewareIndex = 0;\n let nextCalled = false;\n \n const executeMiddleware = async (): Promise<void> => {\n if (middlewareIndex < this.middlewares.length) {\n nextCalled = false;\n const currentIndex = middlewareIndex;\n const middleware = this.middlewares[middlewareIndex++];\n \n const next = async () => {\n nextCalled = true;\n if (currentIndex < this.middlewares.length - 1) {\n await executeMiddleware();\n }\n };\n \n await Promise.resolve(middleware(fullEventName, data, eventMetadata, next));\n \n // 如果中间件没有调用 next(),阻止事件传播\n if (!nextCalled) {\n return;\n }\n }\n };\n \n await executeMiddleware();\n \n // 如果最后一个中间件没有调用 next(),阻止事件传播\n if (!nextCalled && this.middlewares.length > 0) {\n return;\n }\n }\n\n // 获取监听器\n const listeners = this.listeners.get(fullEventName);\n \n // 记录事件历史(无论是否有监听器)\n if (this.config.enableTracking) {\n const executionTime = this.config.enablePerformanceMonitoring\n ? performance.now() - startTime\n : undefined;\n this.recordEventHistory(fullEventName, data, eventMetadata, executionTime);\n }\n \n if (!listeners || listeners.size === 0) {\n // 更新统计(即使没有监听器也记录)\n this.updateStats(fullEventName, 0);\n return;\n }\n\n // 执行监听器\n const executionPromises: Promise<void>[] = [];\n const listenersToRemove: ListenerWithOptions[] = [];\n\n for (const listenerWithOptions of listeners) {\n const executeListener = async () => {\n try {\n if (listenerWithOptions.options.async) {\n await Promise.resolve(\n listenerWithOptions.listener(eventWrapper.data, eventWrapper.metadata)\n );\n } else {\n listenerWithOptions.listener(eventWrapper.data, eventWrapper.metadata);\n }\n\n // 如果是一次性监听器,标记为待移除\n if (listenerWithOptions.options.once) {\n listenersToRemove.push(listenerWithOptions);\n }\n } catch (error) {\n logger.error(`事件 ${fullEventName} 的监听器执行失败:`, error);\n }\n };\n\n executionPromises.push(executeListener());\n }\n\n // 等待所有监听器执行完成\n await Promise.allSettled(executionPromises);\n\n // 移除一次性监听器\n for (const listenerToRemove of listenersToRemove) {\n listeners.delete(listenerToRemove);\n }\n\n if (listeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n\n // 更新统计信息\n const executionTime = this.config.enablePerformanceMonitoring\n ? performance.now() - startTime\n : 0;\n this.updateStats(fullEventName, executionTime, listeners.size);\n }\n\n /**\n * 同步发布事件(不等待异步监听器完成)\n * \n * @param event - 事件名称\n * @param data - 事件数据\n * @param metadata - 事件元数据(可选)\n */\n emitSync<T = unknown>(\n event: string,\n data?: T,\n metadata?: Partial<EventMetadata>\n ): void {\n // 同步执行 emit,但不等待 Promise 完成\n this.emit(event, data, metadata).catch((error) => {\n logger.error(`同步发布事件 ${event} 失败:`, error);\n });\n }\n\n /**\n * 注册事件中间件\n * \n * @param middleware - 中间件函数\n * @returns 取消注册函数\n * \n * @example\n * ```typescript\n * const unsubscribe = eventBus.use((event, data, metadata, next) => {\n * console.log('事件触发:', event);\n * return next();\n * });\n * ```\n */\n use(middleware: EventMiddleware): () => void {\n this.middlewares.push(middleware);\n \n return () => {\n const index = this.middlewares.indexOf(middleware);\n if (index > -1) {\n this.middlewares.splice(index, 1);\n }\n };\n }\n\n /**\n * 清空所有事件监听器\n */\n clear(): void {\n this.listeners.clear();\n }\n\n /**\n * 清空事件历史记录\n */\n clearHistory(): void {\n this.eventHistory = [];\n }\n\n /**\n * 获取事件监听器数量\n * \n * @param event - 事件名称(可选,不提供则返回所有事件的监听器总数)\n */\n listenerCount(event?: string): number {\n if (event) {\n const fullEventName = this.getFullEventName(event);\n return this.listeners.get(fullEventName)?.size || 0;\n }\n\n let count = 0;\n for (const listeners of this.listeners.values()) {\n count += listeners.size;\n }\n return count;\n }\n\n /**\n * 获取所有事件名称\n */\n eventNames(): string[] {\n return Array.from(this.listeners.keys());\n }\n\n /**\n * 获取事件历史记录\n * \n * @param event - 事件名称(可选,如果提供则只返回该事件的历史)\n * @param limit - 限制返回的记录数\n */\n getEventHistory(event?: string, limit?: number): EventHistoryRecord[] {\n if (!this.config.enableTracking) {\n return [];\n }\n\n let history = this.eventHistory;\n if (event) {\n const fullEventName = this.getFullEventName(event);\n history = history.filter((h) => h.event === fullEventName);\n }\n\n if (limit) {\n history = history.slice(-limit);\n }\n\n return [...history];\n }\n\n /**\n * 获取事件统计信息\n * \n * @param event - 事件名称(可选,不提供则返回所有事件的统计)\n */\n getStats(event?: string): EventStats | Map<string, EventStats> {\n if (event) {\n const fullEventName = this.getFullEventName(event);\n return this.stats.get(fullEventName) || {\n event: fullEventName,\n count: 0,\n avgExecutionTime: 0,\n listenerCount: 0,\n lastTriggered: 0,\n };\n }\n\n return new Map(this.stats);\n }\n\n /**\n * 获取配置\n */\n getConfig(): AppEventBusConfig {\n return { ...this.config };\n }\n\n /**\n * 更新配置\n */\n updateConfig(config: Partial<AppEventBusConfig>): void {\n this.config = {\n ...this.config,\n ...config,\n };\n }\n\n /**\n * 销毁事件总线(清理所有资源)\n */\n destroy(): void {\n this.clear();\n this.clearHistory();\n this.middlewares = [];\n this.stats.clear();\n }\n\n /**\n * 获取完整事件名称(包含命名空间前缀)\n */\n private getFullEventName(event: string): string {\n if (this.config.namespacePrefix) {\n return `${this.config.namespacePrefix}${event}`;\n }\n return event;\n }\n\n /**\n * 记录事件历史\n */\n private recordEventHistory(\n event: string,\n data: unknown,\n metadata: EventMetadata,\n executionTime?: number\n ): void {\n this.eventHistory.push({\n event,\n data,\n metadata,\n executionTime,\n });\n\n // 限制历史记录大小\n if (this.eventHistory.length > this.config.maxHistorySize) {\n this.eventHistory.shift();\n }\n }\n\n /**\n * 更新统计信息\n */\n private updateStats(\n event: string,\n executionTime: number,\n listenerCount: number = 0\n ): void {\n if (!this.config.enablePerformanceMonitoring) {\n return;\n }\n\n const existingStats = this.stats.get(event);\n if (existingStats) {\n const totalTime = existingStats.avgExecutionTime * existingStats.count + executionTime;\n const newCount = existingStats.count + 1;\n \n this.stats.set(event, {\n ...existingStats,\n count: newCount,\n avgExecutionTime: totalTime / newCount,\n listenerCount,\n lastTriggered: Date.now(),\n });\n } else {\n this.stats.set(event, {\n event,\n count: 1,\n avgExecutionTime: executionTime,\n listenerCount,\n lastTriggered: Date.now(),\n });\n }\n }\n}\n"],"names":["logger","AppEventBus","on","event","listener","options","fullEventName","getFullEventName","listenerId","Symbol","listenerIdCounter","listenerWithOptions","priority","once","namespace","config","namespacePrefix","async","id","listeners","has","set","Set","get","add","sortedListeners","Array","from","sort","a","b","currentListeners","delete","size","off","item","clear","emit","data","metadata","startTime","enablePerformanceMonitoring","performance","now","enableValidation","validator","warn","enableSecurityMode","source","allowedSources","includes","eventMetadata","timestamp","Date","eventId","eventCounter","instanceId","eventWrapper","middlewares","length","middlewareIndex","nextCalled","executeMiddleware","currentIndex","middleware","next","Promise","resolve","enableTracking","executionTime","undefined","recordEventHistory","updateStats","executionPromises","listenersToRemove","executeListener","push","error","allSettled","listenerToRemove","emitSync","catch","use","index","indexOf","splice","clearHistory","eventHistory","listenerCount","count","values","eventNames","keys","getEventHistory","limit","history","filter","h","slice","getStats","stats","avgExecutionTime","lastTriggered","Map","getConfig","updateConfig","destroy","maxHistorySize","shift","existingStats","totalTime","newCount","process","env","NODE_ENV"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/event/AppEventBus.ts"],"sourcesContent":["/**\n * 应用级事件总线\n * 提供高性能、类型安全、可观测的事件通信能力\n */\n\nimport { logger } from '@vlian/logger';\nimport type {\n EventListener,\n EventMetadata,\n EventWrapper,\n EventMiddleware,\n EventListenerOptions,\n AppEventBusConfig,\n EventStats,\n} from './types';\n\n/**\n * 带选项的监听器\n */\ninterface ListenerWithOptions {\n listener: EventListener;\n options: Required<EventListenerOptions>;\n id: symbol;\n}\n\n/**\n * 事件历史记录\n */\ninterface EventHistoryRecord {\n event: string;\n data: unknown;\n metadata: EventMetadata;\n executionTime?: number;\n}\n\n/**\n * 应用事件总线\n */\nexport class AppEventBus {\n /**\n * 事件监听器映射表\n * 使用 Map + Set 结构提高性能\n */\n private listeners: Map<string, Set<ListenerWithOptions>> = new Map();\n \n /**\n * 事件历史记录\n */\n private eventHistory: EventHistoryRecord[] = [];\n \n /**\n * 事件中间件列表\n */\n private middlewares: EventMiddleware[] = [];\n \n /**\n * 事件统计信息\n */\n private stats: Map<string, EventStats> = new Map();\n \n /**\n * 配置\n */\n private config: Required<AppEventBusConfig>;\n \n /**\n * 事件计数器(用于生成唯一事件ID)\n */\n private eventCounter: number = 0;\n \n /**\n * 监听器ID计数器\n */\n private listenerIdCounter: number = 0;\n\n constructor(config: AppEventBusConfig = {}) {\n this.config = {\n enableTracking: config.enableTracking ?? (process.env.NODE_ENV === 'development'),\n maxHistorySize: config.maxHistorySize ?? 100,\n enableValidation: config.enableValidation ?? false,\n validator: config.validator ?? (() => true),\n enablePerformanceMonitoring: config.enablePerformanceMonitoring ?? (process.env.NODE_ENV === 'development'),\n namespacePrefix: config.namespacePrefix ?? '',\n instanceId: config.instanceId,\n enableSecurityMode: config.enableSecurityMode ?? false,\n allowedSources: config.allowedSources ?? [],\n } as Required<AppEventBusConfig>;\n }\n\n /**\n * 订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器\n * @param options - 监听器选项\n * @returns 取消订阅函数\n * \n * @example\n * ```typescript\n * const unsubscribe = eventBus.on('user:login', (data, metadata) => {\n * console.log('用户登录:', data);\n * });\n * \n * // 取消订阅\n * unsubscribe();\n * ```\n */\n on<T = unknown>(\n event: string,\n listener: EventListener<T>,\n options: EventListenerOptions = {}\n ): () => void {\n const fullEventName = this.getFullEventName(event);\n const listenerId = Symbol(`listener_${++this.listenerIdCounter}`);\n \n const listenerWithOptions: ListenerWithOptions = {\n listener: listener as EventListener,\n options: {\n priority: options.priority ?? 100,\n once: options.once ?? false,\n namespace: options.namespace ?? this.config.namespacePrefix,\n async: options.async ?? true,\n },\n id: listenerId,\n };\n\n if (!this.listeners.has(fullEventName)) {\n this.listeners.set(fullEventName, new Set());\n }\n\n const listeners = this.listeners.get(fullEventName)!;\n listeners.add(listenerWithOptions);\n\n // 按优先级排序(数字越小优先级越高)\n const sortedListeners = Array.from(listeners).sort(\n (a, b) => a.options.priority - b.options.priority\n );\n this.listeners.set(fullEventName, new Set(sortedListeners));\n\n // 返回取消订阅函数\n return () => {\n const currentListeners = this.listeners.get(fullEventName);\n if (currentListeners) {\n currentListeners.delete(listenerWithOptions);\n if (currentListeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n }\n };\n }\n\n /**\n * 取消订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器(可选,不提供则取消该事件的所有监听器)\n */\n off<T = unknown>(event: string, listener?: EventListener<T>): void {\n const fullEventName = this.getFullEventName(event);\n const listeners = this.listeners.get(fullEventName);\n \n if (!listeners) {\n return;\n }\n\n if (listener) {\n // 移除指定的监听器\n for (const item of listeners) {\n if (item.listener === listener) {\n listeners.delete(item);\n break;\n }\n }\n } else {\n // 移除所有监听器\n listeners.clear();\n }\n\n if (listeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n }\n\n /**\n * 一次性订阅事件\n * \n * @param event - 事件名称\n * @param listener - 事件监听器\n * @param options - 监听器选项\n */\n once<T = unknown>(\n event: string,\n listener: EventListener<T>,\n options?: Omit<EventListenerOptions, 'once'>\n ): () => void {\n return this.on(event, listener, { ...options, once: true });\n }\n\n /**\n * 发布事件\n * \n * @param event - 事件名称\n * @param data - 事件数据\n * @param metadata - 事件元数据(可选)\n * \n * @example\n * ```typescript\n * await eventBus.emit('user:login', {\n * userId: '123',\n * username: 'john',\n * });\n * ```\n */\n async emit<T = unknown>(\n event: string,\n data?: T,\n metadata?: Partial<EventMetadata>\n ): Promise<void> {\n const fullEventName = this.getFullEventName(event);\n const startTime = this.config.enablePerformanceMonitoring ? performance.now() : 0;\n\n // 事件验证\n if (this.config.enableValidation && !this.config.validator(fullEventName, data)) {\n logger.warn(`事件 ${fullEventName} 验证失败,已忽略`);\n return;\n }\n\n // 安全检查\n if (this.config.enableSecurityMode && metadata?.source) {\n if (!this.config.allowedSources.includes(metadata.source)) {\n logger.warn(`事件 ${fullEventName} 的来源 ${metadata.source} 不在白名单中,已忽略`);\n return;\n }\n }\n\n // 构建事件元数据\n const eventMetadata: EventMetadata = {\n source: metadata?.source,\n timestamp: metadata?.timestamp ?? Date.now(),\n eventId: metadata?.eventId ?? `event_${++this.eventCounter}`,\n priority: metadata?.priority ?? 0,\n instanceId: metadata?.instanceId ?? this.config.instanceId,\n namespace: metadata?.namespace ?? this.config.namespacePrefix,\n ...metadata,\n };\n\n // 创建事件包装器\n const eventWrapper: EventWrapper<T> = {\n data: data as T,\n metadata: eventMetadata,\n };\n\n // 执行中间件(中间件可以阻止事件传播)\n if (this.middlewares.length > 0) {\n let middlewareIndex = 0;\n let nextCalled = false;\n \n const executeMiddleware = async (): Promise<void> => {\n if (middlewareIndex < this.middlewares.length) {\n nextCalled = false;\n const currentIndex = middlewareIndex;\n const middleware = this.middlewares[middlewareIndex++];\n \n const next = async () => {\n nextCalled = true;\n if (currentIndex < this.middlewares.length - 1) {\n await executeMiddleware();\n }\n };\n \n await Promise.resolve(middleware(fullEventName, data, eventMetadata, next));\n \n // 如果中间件没有调用 next(),阻止事件传播\n if (!nextCalled) {\n return;\n }\n }\n };\n \n await executeMiddleware();\n \n // 如果最后一个中间件没有调用 next(),阻止事件传播\n if (!nextCalled && this.middlewares.length > 0) {\n return;\n }\n }\n\n // 获取监听器\n const listeners = this.listeners.get(fullEventName);\n \n // 记录事件历史(无论是否有监听器)\n if (this.config.enableTracking) {\n const executionTime = this.config.enablePerformanceMonitoring\n ? performance.now() - startTime\n : undefined;\n this.recordEventHistory(fullEventName, data, eventMetadata, executionTime);\n }\n \n if (!listeners || listeners.size === 0) {\n // 更新统计(即使没有监听器也记录)\n this.updateStats(fullEventName, 0);\n return;\n }\n\n // 执行监听器\n const executionPromises: Promise<void>[] = [];\n const listenersToRemove: ListenerWithOptions[] = [];\n\n for (const listenerWithOptions of listeners) {\n const executeListener = async () => {\n try {\n if (listenerWithOptions.options.async) {\n await Promise.resolve(\n listenerWithOptions.listener(eventWrapper.data, eventWrapper.metadata)\n );\n } else {\n listenerWithOptions.listener(eventWrapper.data, eventWrapper.metadata);\n }\n\n // 如果是一次性监听器,标记为待移除\n if (listenerWithOptions.options.once) {\n listenersToRemove.push(listenerWithOptions);\n }\n } catch (error) {\n logger.error(`事件 ${fullEventName} 的监听器执行失败:`, error);\n }\n };\n\n executionPromises.push(executeListener());\n }\n\n // 等待所有监听器执行完成\n await Promise.allSettled(executionPromises);\n\n // 移除一次性监听器\n for (const listenerToRemove of listenersToRemove) {\n listeners.delete(listenerToRemove);\n }\n\n if (listeners.size === 0) {\n this.listeners.delete(fullEventName);\n }\n\n // 更新统计信息\n const executionTime = this.config.enablePerformanceMonitoring\n ? performance.now() - startTime\n : 0;\n this.updateStats(fullEventName, executionTime, listeners.size);\n }\n\n /**\n * 同步发布事件(不等待异步监听器完成)\n * \n * @param event - 事件名称\n * @param data - 事件数据\n * @param metadata - 事件元数据(可选)\n */\n emitSync<T = unknown>(\n event: string,\n data?: T,\n metadata?: Partial<EventMetadata>\n ): void {\n // 同步执行 emit,但不等待 Promise 完成\n this.emit(event, data, metadata).catch((error) => {\n logger.error(`同步发布事件 ${event} 失败:`, error);\n });\n }\n\n /**\n * 注册事件中间件\n * \n * @param middleware - 中间件函数\n * @returns 取消注册函数\n * \n * @example\n * ```typescript\n * const unsubscribe = eventBus.use((event, data, metadata, next) => {\n * console.log('事件触发:', event);\n * return next();\n * });\n * ```\n */\n use(middleware: EventMiddleware): () => void {\n this.middlewares.push(middleware);\n \n return () => {\n const index = this.middlewares.indexOf(middleware);\n if (index > -1) {\n this.middlewares.splice(index, 1);\n }\n };\n }\n\n /**\n * 清空所有事件监听器\n */\n clear(): void {\n this.listeners.clear();\n }\n\n /**\n * 清空事件历史记录\n */\n clearHistory(): void {\n this.eventHistory = [];\n }\n\n /**\n * 获取事件监听器数量\n * \n * @param event - 事件名称(可选,不提供则返回所有事件的监听器总数)\n */\n listenerCount(event?: string): number {\n if (event) {\n const fullEventName = this.getFullEventName(event);\n return this.listeners.get(fullEventName)?.size || 0;\n }\n\n let count = 0;\n for (const listeners of this.listeners.values()) {\n count += listeners.size;\n }\n return count;\n }\n\n /**\n * 获取所有事件名称\n */\n eventNames(): string[] {\n return Array.from(this.listeners.keys());\n }\n\n /**\n * 获取事件历史记录\n * \n * @param event - 事件名称(可选,如果提供则只返回该事件的历史)\n * @param limit - 限制返回的记录数\n */\n getEventHistory(event?: string, limit?: number): EventHistoryRecord[] {\n if (!this.config.enableTracking) {\n return [];\n }\n\n let history = this.eventHistory;\n if (event) {\n const fullEventName = this.getFullEventName(event);\n history = history.filter((h) => h.event === fullEventName);\n }\n\n if (limit) {\n history = history.slice(-limit);\n }\n\n return [...history];\n }\n\n /**\n * 获取事件统计信息\n * \n * @param event - 事件名称(可选,不提供则返回所有事件的统计)\n */\n getStats(event?: string): EventStats | Map<string, EventStats> {\n if (event) {\n const fullEventName = this.getFullEventName(event);\n return this.stats.get(fullEventName) || {\n event: fullEventName,\n count: 0,\n avgExecutionTime: 0,\n listenerCount: 0,\n lastTriggered: 0,\n };\n }\n\n return new Map(this.stats);\n }\n\n /**\n * 获取配置\n */\n getConfig(): AppEventBusConfig {\n return { ...this.config };\n }\n\n /**\n * 更新配置\n */\n updateConfig(config: Partial<AppEventBusConfig>): void {\n this.config = {\n ...this.config,\n ...config,\n };\n }\n\n /**\n * 销毁事件总线(清理所有资源)\n */\n destroy(): void {\n this.clear();\n this.clearHistory();\n this.middlewares = [];\n this.stats.clear();\n }\n\n /**\n * 获取完整事件名称(包含命名空间前缀)\n */\n private getFullEventName(event: string): string {\n if (this.config.namespacePrefix) {\n return `${this.config.namespacePrefix}${event}`;\n }\n return event;\n }\n\n /**\n * 记录事件历史\n */\n private recordEventHistory(\n event: string,\n data: unknown,\n metadata: EventMetadata,\n executionTime?: number\n ): void {\n this.eventHistory.push({\n event,\n data,\n metadata,\n executionTime,\n });\n\n // 限制历史记录大小\n if (this.eventHistory.length > this.config.maxHistorySize) {\n this.eventHistory.shift();\n }\n }\n\n /**\n * 更新统计信息\n */\n private updateStats(\n event: string,\n executionTime: number,\n listenerCount: number = 0\n ): void {\n if (!this.config.enablePerformanceMonitoring) {\n return;\n }\n\n const existingStats = this.stats.get(event);\n if (existingStats) {\n const totalTime = existingStats.avgExecutionTime * existingStats.count + executionTime;\n const newCount = existingStats.count + 1;\n \n this.stats.set(event, {\n ...existingStats,\n count: newCount,\n avgExecutionTime: totalTime / newCount,\n listenerCount,\n lastTriggered: Date.now(),\n });\n } else {\n this.stats.set(event, {\n event,\n count: 1,\n avgExecutionTime: executionTime,\n listenerCount,\n lastTriggered: Date.now(),\n });\n }\n }\n}\n"],"names":["logger","AppEventBus","on","event","listener","options","fullEventName","getFullEventName","listenerId","Symbol","listenerIdCounter","listenerWithOptions","priority","once","namespace","config","namespacePrefix","async","id","listeners","has","set","Set","get","add","sortedListeners","Array","from","sort","a","b","currentListeners","delete","size","off","item","clear","emit","data","metadata","startTime","enablePerformanceMonitoring","performance","now","enableValidation","validator","warn","enableSecurityMode","source","allowedSources","includes","eventMetadata","timestamp","Date","eventId","eventCounter","instanceId","eventWrapper","middlewares","length","middlewareIndex","nextCalled","executeMiddleware","currentIndex","middleware","next","Promise","resolve","enableTracking","executionTime","undefined","recordEventHistory","updateStats","executionPromises","listenersToRemove","executeListener","push","error","allSettled","listenerToRemove","emitSync","catch","use","index","indexOf","splice","clearHistory","eventHistory","listenerCount","count","values","eventNames","keys","getEventHistory","limit","history","filter","h","slice","getStats","stats","avgExecutionTime","lastTriggered","Map","getConfig","updateConfig","destroy","maxHistorySize","shift","existingStats","totalTime","newCount","process","env","NODE_ENV"],"mappings":"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"}
|