@vlian/framework 1.2.25 → 1.2.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/dist/analytics.umd.js +208 -2395
  2. package/dist/analytics.umd.js.map +1 -1
  3. package/dist/core/error/ErrorHandler.cjs.map +1 -1
  4. package/dist/core/error/ErrorHandler.d.ts +1 -1
  5. package/dist/core/error/ErrorHandler.js.map +1 -1
  6. package/dist/core/router/monitoring/RouterMonitoring.cjs +1 -1
  7. package/dist/core/router/monitoring/RouterMonitoring.cjs.map +1 -1
  8. package/dist/core/router/monitoring/RouterMonitoring.js +1 -1
  9. package/dist/core/router/monitoring/RouterMonitoring.js.map +1 -1
  10. package/dist/core/router/utils/adapters/react-router/transform.cjs +4 -0
  11. package/dist/core/router/utils/adapters/react-router/transform.cjs.map +1 -1
  12. package/dist/core/router/utils/adapters/react-router/transform.js +4 -0
  13. package/dist/core/router/utils/adapters/react-router/transform.js.map +1 -1
  14. package/dist/core/startup/initializeServices.cjs +1 -1
  15. package/dist/core/startup/initializeServices.cjs.map +1 -1
  16. package/dist/core/startup/initializeServices.d.ts +1 -1
  17. package/dist/core/startup/initializeServices.js +1 -1
  18. package/dist/core/startup/initializeServices.js.map +1 -1
  19. package/dist/core/startup/performanceTracker.cjs.map +1 -1
  20. package/dist/core/startup/performanceTracker.d.ts +1 -1
  21. package/dist/core/startup/performanceTracker.js.map +1 -1
  22. package/dist/core/startup/renderApp.cjs +1 -1
  23. package/dist/core/startup/renderApp.cjs.map +1 -1
  24. package/dist/core/startup/renderApp.d.ts +1 -1
  25. package/dist/core/startup/renderApp.js +1 -1
  26. package/dist/core/startup/renderApp.js.map +1 -1
  27. package/dist/core/startup/startApp.cjs +2 -2
  28. package/dist/core/startup/startApp.cjs.map +1 -1
  29. package/dist/core/startup/startApp.js +3 -3
  30. package/dist/core/startup/startApp.js.map +1 -1
  31. package/dist/core/types.d.ts +1 -1
  32. package/dist/core/types.js.map +1 -1
  33. package/dist/index.cjs +15 -2
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.ts +6 -4
  36. package/dist/index.js +5 -4
  37. package/dist/index.js.map +1 -1
  38. package/dist/index.umd.js +11648 -32616
  39. package/dist/index.umd.js.map +1 -1
  40. package/dist/kernel/constants.cjs +67 -0
  41. package/dist/kernel/constants.cjs.map +1 -0
  42. package/dist/kernel/constants.d.ts +5 -0
  43. package/dist/kernel/constants.js +43 -0
  44. package/dist/kernel/constants.js.map +1 -0
  45. package/dist/kernel/index.cjs +40 -0
  46. package/dist/kernel/index.cjs.map +1 -0
  47. package/dist/kernel/index.d.ts +3 -0
  48. package/dist/kernel/index.js +4 -0
  49. package/dist/kernel/index.js.map +1 -0
  50. package/dist/kernel/kernel.cjs +296 -0
  51. package/dist/kernel/kernel.cjs.map +1 -0
  52. package/dist/kernel/kernel.d.ts +40 -0
  53. package/dist/kernel/kernel.js +272 -0
  54. package/dist/kernel/kernel.js.map +1 -0
  55. package/dist/kernel/manager/cacheManager.cjs +46 -0
  56. package/dist/kernel/manager/cacheManager.cjs.map +1 -0
  57. package/dist/kernel/manager/cacheManager.d.ts +6 -0
  58. package/dist/kernel/manager/cacheManager.js +36 -0
  59. package/dist/kernel/manager/cacheManager.js.map +1 -0
  60. package/dist/kernel/manager/i18nManager.cjs +68 -0
  61. package/dist/kernel/manager/i18nManager.cjs.map +1 -0
  62. package/dist/kernel/manager/i18nManager.d.ts +8 -0
  63. package/dist/kernel/manager/i18nManager.js +58 -0
  64. package/dist/kernel/manager/i18nManager.js.map +1 -0
  65. package/dist/kernel/manager/index.cjs +30 -0
  66. package/dist/kernel/manager/index.cjs.map +1 -0
  67. package/dist/kernel/manager/index.d.ts +4 -0
  68. package/dist/kernel/manager/index.js +6 -0
  69. package/dist/kernel/manager/index.js.map +1 -0
  70. package/dist/kernel/manager/loggerManager.cjs +70 -0
  71. package/dist/kernel/manager/loggerManager.cjs.map +1 -0
  72. package/dist/kernel/manager/loggerManager.d.ts +14 -0
  73. package/dist/kernel/manager/loggerManager.js +60 -0
  74. package/dist/kernel/manager/loggerManager.js.map +1 -0
  75. package/dist/kernel/manager/persistence.cjs +93 -0
  76. package/dist/kernel/manager/persistence.cjs.map +1 -0
  77. package/dist/kernel/manager/persistence.d.ts +3 -0
  78. package/dist/kernel/manager/persistence.js +75 -0
  79. package/dist/kernel/manager/persistence.js.map +1 -0
  80. package/dist/kernel/manager/themeManager.cjs +85 -0
  81. package/dist/kernel/manager/themeManager.cjs.map +1 -0
  82. package/dist/kernel/manager/themeManager.d.ts +9 -0
  83. package/dist/kernel/manager/themeManager.js +75 -0
  84. package/dist/kernel/manager/themeManager.js.map +1 -0
  85. package/dist/kernel/types.cjs +6 -0
  86. package/dist/kernel/types.cjs.map +1 -0
  87. package/dist/kernel/types.d.ts +72 -0
  88. package/dist/kernel/types.js +3 -0
  89. package/dist/kernel/types.js.map +1 -0
  90. package/dist/request/adapter.d.ts +1 -0
  91. package/dist/request/core.d.ts +1 -0
  92. package/dist/request/index.d.ts +1 -42
  93. package/dist/request/plugin/csrfPlugin.d.ts +2 -2
  94. package/dist/request/plugin/queue.d.ts +2 -2
  95. package/dist/request/plugin.d.ts +1 -0
  96. package/dist/request/runtime.d.ts +1 -0
  97. package/dist/request/types.d.ts +1 -394
  98. package/dist/request/utils.d.ts +1 -0
  99. package/dist/state.umd.js +1 -1
  100. package/dist/utils/csrf.cjs +13 -152
  101. package/dist/utils/csrf.cjs.map +1 -1
  102. package/dist/utils/csrf.d.ts +1 -72
  103. package/dist/utils/csrf.js +1 -142
  104. package/dist/utils/csrf.js.map +1 -1
  105. package/dist/utils/errors/ErrorCodes.cjs +6 -76
  106. package/dist/utils/errors/ErrorCodes.cjs.map +1 -1
  107. package/dist/utils/errors/ErrorCodes.d.ts +1 -45
  108. package/dist/utils/errors/ErrorCodes.js +1 -84
  109. package/dist/utils/errors/ErrorCodes.js.map +1 -1
  110. package/dist/utils/errors.cjs +15 -344
  111. package/dist/utils/errors.cjs.map +1 -1
  112. package/dist/utils/errors.d.ts +1 -183
  113. package/dist/utils/errors.js +1 -352
  114. package/dist/utils/errors.js.map +1 -1
  115. package/dist/utils/logger.cjs +5 -374
  116. package/dist/utils/logger.cjs.map +1 -1
  117. package/dist/utils/logger.d.ts +2 -189
  118. package/dist/utils/logger.js +1 -379
  119. package/dist/utils/logger.js.map +1 -1
  120. package/dist/utils/logger.types.cjs +3 -12
  121. package/dist/utils/logger.types.cjs.map +1 -1
  122. package/dist/utils/logger.types.d.ts +2 -57
  123. package/dist/utils/logger.types.js +1 -10
  124. package/dist/utils/logger.types.js.map +1 -1
  125. package/dist/utils/monitoring.cjs +11 -302
  126. package/dist/utils/monitoring.cjs.map +1 -1
  127. package/dist/utils/monitoring.d.ts +1 -163
  128. package/dist/utils/monitoring.js +1 -294
  129. package/dist/utils/monitoring.js.map +1 -1
  130. package/dist/utils/performance.cjs +5 -352
  131. package/dist/utils/performance.cjs.map +1 -1
  132. package/dist/utils/performance.d.ts +2 -246
  133. package/dist/utils/performance.js +1 -354
  134. package/dist/utils/performance.js.map +1 -1
  135. package/dist/utils/resourceLoader.cjs +5 -303
  136. package/dist/utils/resourceLoader.cjs.map +1 -1
  137. package/dist/utils/resourceLoader.d.ts +2 -130
  138. package/dist/utils/resourceLoader.js +1 -305
  139. package/dist/utils/resourceLoader.js.map +1 -1
  140. package/dist/utils/runtimeSecurity.cjs +2 -140
  141. package/dist/utils/runtimeSecurity.cjs.map +1 -1
  142. package/dist/utils/runtimeSecurity.d.ts +2 -104
  143. package/dist/utils/runtimeSecurity.js +1 -141
  144. package/dist/utils/runtimeSecurity.js.map +1 -1
  145. package/dist/utils/security.cjs +3 -314
  146. package/dist/utils/security.cjs.map +1 -1
  147. package/dist/utils/security.d.ts +2 -80
  148. package/dist/utils/security.js +1 -311
  149. package/dist/utils/security.js.map +1 -1
  150. package/dist/utils/traceId.cjs +10 -111
  151. package/dist/utils/traceId.cjs.map +1 -1
  152. package/dist/utils/traceId.d.ts +1 -63
  153. package/dist/utils/traceId.js +1 -116
  154. package/dist/utils/traceId.js.map +1 -1
  155. package/dist/utils/validation.cjs +3 -173
  156. package/dist/utils/validation.cjs.map +1 -1
  157. package/dist/utils/validation.d.ts +2 -110
  158. package/dist/utils/validation.js +1 -175
  159. package/dist/utils/validation.js.map +1 -1
  160. package/package.json +15 -24
  161. package/dist/lazy/index.cjs +0 -104
  162. package/dist/lazy/index.cjs.map +0 -1
  163. package/dist/lazy/index.d.ts +0 -19
  164. package/dist/lazy/index.js +0 -24
  165. package/dist/lazy/index.js.map +0 -1
  166. package/dist/request/adapter/RequestAdapter.cjs +0 -78
  167. package/dist/request/adapter/RequestAdapter.cjs.map +0 -1
  168. package/dist/request/adapter/axiosAdapter.cjs +0 -164
  169. package/dist/request/adapter/axiosAdapter.cjs.map +0 -1
  170. package/dist/request/adapter/fetchAdapter.cjs +0 -134
  171. package/dist/request/adapter/fetchAdapter.cjs.map +0 -1
  172. package/dist/request/adapter/index.cjs +0 -80
  173. package/dist/request/adapter/index.cjs.map +0 -1
  174. package/dist/request/adapter/kyAdapter.cjs +0 -191
  175. package/dist/request/adapter/kyAdapter.cjs.map +0 -1
  176. package/dist/request/adapter/undiciAdapter.cjs +0 -213
  177. package/dist/request/adapter/undiciAdapter.cjs.map +0 -1
  178. package/dist/request/core/RequestClient.cjs +0 -558
  179. package/dist/request/core/RequestClient.cjs.map +0 -1
  180. package/dist/request/core/index.cjs +0 -15
  181. package/dist/request/core/index.cjs.map +0 -1
  182. package/dist/request/index.cjs +0 -149
  183. package/dist/request/index.cjs.map +0 -1
  184. package/dist/request/plugin/RequestPlugin.cjs +0 -218
  185. package/dist/request/plugin/RequestPlugin.cjs.map +0 -1
  186. package/dist/request/plugin/cache.cjs +0 -269
  187. package/dist/request/plugin/cache.cjs.map +0 -1
  188. package/dist/request/plugin/csrfPlugin.cjs +0 -40
  189. package/dist/request/plugin/csrfPlugin.cjs.map +0 -1
  190. package/dist/request/plugin/index.cjs +0 -53
  191. package/dist/request/plugin/index.cjs.map +0 -1
  192. package/dist/request/plugin/monitoring.cjs +0 -216
  193. package/dist/request/plugin/monitoring.cjs.map +0 -1
  194. package/dist/request/plugin/queue.cjs +0 -140
  195. package/dist/request/plugin/queue.cjs.map +0 -1
  196. package/dist/request/plugin/retry.cjs +0 -98
  197. package/dist/request/plugin/retry.cjs.map +0 -1
  198. package/dist/request/plugin/validation.cjs +0 -121
  199. package/dist/request/plugin/validation.cjs.map +0 -1
  200. package/dist/request/runtime/RequestContext.cjs +0 -77
  201. package/dist/request/runtime/RequestContext.cjs.map +0 -1
  202. package/dist/request/runtime/index.cjs +0 -32
  203. package/dist/request/runtime/index.cjs.map +0 -1
  204. package/dist/request/types.cjs +0 -112
  205. package/dist/request/types.cjs.map +0 -1
  206. package/dist/request/utils/RequestQueueManager.cjs +0 -168
  207. package/dist/request/utils/RequestQueueManager.cjs.map +0 -1
  208. package/dist/request/utils/dependencyCheck.cjs +0 -237
  209. package/dist/request/utils/dependencyCheck.cjs.map +0 -1
  210. package/dist/request/utils/index.cjs +0 -30
  211. package/dist/request/utils/index.cjs.map +0 -1
  212. package/dist/request.umd.js +0 -5392
  213. package/dist/request.umd.js.map +0 -1
@@ -1,296 +1,3 @@
1
- function _define_property(obj, key, value) {
2
- if (key in obj) {
3
- Object.defineProperty(obj, key, {
4
- value: value,
5
- enumerable: true,
6
- configurable: true,
7
- writable: true
8
- });
9
- } else {
10
- obj[key] = value;
11
- }
12
- return obj;
13
- }
14
- import { logger } from "./logger";
15
- import { errorUtils } from "./errors";
16
- import { convertMetricsToWithUnits } from "./performance";
17
- /**
18
- * 监控服务类
19
- */ export class MonitoringService {
20
- /**
21
- * 初始化错误捕获
22
- */ initErrorCapture() {
23
- // 捕获未处理的 Promise 错误
24
- this.unhandledRejectionHandler = (event)=>{
25
- const error = errorUtils.normalizeError(event.reason);
26
- this.captureError(error, {
27
- type: 'unhandledrejection',
28
- reason: event.reason
29
- });
30
- };
31
- window.addEventListener('unhandledrejection', this.unhandledRejectionHandler);
32
- // 捕获全局错误
33
- this.errorHandler = (event)=>{
34
- const error = errorUtils.normalizeError(event.error || new Error(event.message));
35
- this.captureError(error, {
36
- type: 'global',
37
- filename: event.filename,
38
- lineno: event.lineno,
39
- colno: event.colno
40
- });
41
- };
42
- window.addEventListener('error', this.errorHandler);
43
- }
44
- /**
45
- * 清理资源
46
- */ destroy() {
47
- // 移除事件监听器
48
- if (typeof window !== 'undefined') {
49
- if (this.unhandledRejectionHandler) {
50
- window.removeEventListener('unhandledrejection', this.unhandledRejectionHandler);
51
- }
52
- if (this.errorHandler) {
53
- window.removeEventListener('error', this.errorHandler);
54
- }
55
- }
56
- // 停止聚合定时器
57
- if (this.aggregationTimer) {
58
- clearInterval(this.aggregationTimer);
59
- this.aggregationTimer = undefined;
60
- }
61
- // 清空错误处理器
62
- this.errorHandlers = [];
63
- this.errorRecords = [];
64
- this.errorAggregations.clear();
65
- }
66
- /**
67
- * 启动错误聚合定时器
68
- */ startAggregationTimer() {
69
- this.aggregationTimer = setInterval(()=>{
70
- this.aggregateErrors();
71
- }, this.errorConfig.aggregationWindow);
72
- }
73
- /**
74
- * 聚合错误
75
- */ aggregateErrors() {
76
- const now = Date.now();
77
- const windowStart = now - this.errorConfig.aggregationWindow;
78
- // 过滤窗口内的错误
79
- const windowErrors = this.errorRecords.filter((record)=>record.timestamp >= windowStart);
80
- // 按错误代码聚合
81
- const aggregations = new Map();
82
- for (const record of windowErrors){
83
- const error = record.error;
84
- const key = `${error.code}_${error.type}`;
85
- if (!aggregations.has(key)) {
86
- aggregations.set(key, {
87
- code: error.code,
88
- message: error.message,
89
- type: error.type,
90
- count: 0,
91
- firstOccurrence: record.timestamp,
92
- lastOccurrence: record.timestamp,
93
- stack: error.originalError?.stack,
94
- context: error.context
95
- });
96
- }
97
- const agg = aggregations.get(key);
98
- agg.count++;
99
- agg.lastOccurrence = Math.max(agg.lastOccurrence, record.timestamp);
100
- }
101
- // 更新聚合结果
102
- this.errorAggregations = aggregations;
103
- }
104
- /**
105
- * 捕获错误
106
- */ captureError(error, context) {
107
- // 采样检查
108
- if (Math.random() > this.errorConfig.sampleRate) {
109
- return;
110
- }
111
- const normalizedError = errorUtils.normalizeError(error);
112
- // 创建带上下文的错误对象(使用 Object.assign 来更新只读属性)
113
- const errorWithContext = Object.assign(normalizedError, {
114
- context: {
115
- ...normalizedError.context,
116
- ...context,
117
- timestamp: new Date().toISOString(),
118
- userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,
119
- url: typeof window !== 'undefined' ? window.location.href : undefined
120
- }
121
- });
122
- // 记录错误
123
- const timestamp = Date.now();
124
- this.errorRecords.push({
125
- error: errorWithContext,
126
- timestamp
127
- });
128
- // 限制错误记录数量
129
- if (this.errorRecords.length > this.errorConfig.maxErrorRecords) {
130
- this.errorRecords.shift();
131
- }
132
- // 记录日志
133
- if (this.errorConfig.showInConsole) {
134
- logger.error('监控服务捕获到错误:', errorWithContext.toJSON());
135
- }
136
- // 调用错误回调
137
- this.errorConfig.onError(errorWithContext, context);
138
- // 调用注册的错误处理器
139
- this.errorHandlers.forEach((handler)=>{
140
- try {
141
- handler(errorWithContext);
142
- } catch (e) {
143
- // 忽略处理器错误
144
- }
145
- });
146
- }
147
- /**
148
- * 获取错误聚合信息
149
- *
150
- * @param code - 错误代码(可选,如果提供则只返回该错误的聚合信息)
151
- * @returns 错误聚合信息
152
- */ getErrorAggregations(code) {
153
- if (code) {
154
- const aggregation = this.errorAggregations.get(code);
155
- return aggregation ? [
156
- aggregation
157
- ] : [];
158
- }
159
- return Array.from(this.errorAggregations.values());
160
- }
161
- /**
162
- * 获取错误记录
163
- *
164
- * @param limit - 限制返回的记录数
165
- * @param since - 只返回此时间之后的错误
166
- * @returns 错误记录
167
- */ getErrorRecords(limit, since) {
168
- let records = this.errorRecords;
169
- if (since) {
170
- records = records.filter((record)=>record.timestamp >= since);
171
- }
172
- if (limit) {
173
- records = records.slice(-limit);
174
- }
175
- return [
176
- ...records
177
- ];
178
- }
179
- /**
180
- * 清空错误记录
181
- */ clearErrorRecords() {
182
- this.errorRecords = [];
183
- this.errorAggregations.clear();
184
- }
185
- /**
186
- * 注册错误处理器
187
- */ onError(handler) {
188
- this.errorHandlers.push(handler);
189
- return ()=>{
190
- const index = this.errorHandlers.indexOf(handler);
191
- if (index > -1) {
192
- this.errorHandlers.splice(index, 1);
193
- }
194
- };
195
- }
196
- /**
197
- * 上报性能指标
198
- */ reportPerformance(metrics, context) {
199
- // 将传入的指标转换为带单位的格式
200
- const metricsWithUnits = convertMetricsToWithUnits(metrics);
201
- // 合并到现有指标中
202
- this.performanceMetrics = {
203
- ...this.performanceMetrics,
204
- ...metricsWithUnits
205
- };
206
- // 记录性能指标(带上下文)
207
- if (context) {
208
- logger.debug('性能指标更新:', {
209
- metrics: metricsWithUnits,
210
- context
211
- });
212
- } else {
213
- logger.debug('性能指标更新:', metricsWithUnits);
214
- }
215
- }
216
- /**
217
- * 批量上报性能指标
218
- */ reportPerformanceBatch(metricsArray) {
219
- for (const { metrics, context } of metricsArray){
220
- this.reportPerformance(metrics, context);
221
- }
222
- }
223
- /**
224
- * 获取性能指标(带单位)
225
- */ getPerformanceMetrics() {
226
- return {
227
- ...this.performanceMetrics
228
- };
229
- }
230
- /**
231
- * 获取性能指标(原始数值格式,向后兼容)
232
- */ getPerformanceMetricsRaw() {
233
- const result = {};
234
- for (const [key, metricValue] of Object.entries(this.performanceMetrics)){
235
- if (metricValue && typeof metricValue === 'object' && 'value' in metricValue) {
236
- result[key] = metricValue.value;
237
- }
238
- }
239
- return result;
240
- }
241
- /**
242
- * 记录用户行为(匿名)
243
- */ trackEvent(eventName, properties) {
244
- logger.debug('用户事件:', {
245
- eventName,
246
- properties
247
- });
248
- }
249
- constructor(errorConfig = {}){
250
- _define_property(this, "errorConfig", void 0);
251
- _define_property(this, "errorHandlers", []);
252
- _define_property(this, "performanceMetrics", {});
253
- _define_property(this, "unhandledRejectionHandler", void 0);
254
- _define_property(this, "errorHandler", void 0);
255
- _define_property(this, "errorRecords", []);
256
- _define_property(this, "errorAggregations", new Map());
257
- _define_property(this, "aggregationTimer", void 0);
258
- this.errorConfig = {
259
- autoCapture: errorConfig.autoCapture ?? true,
260
- onError: errorConfig.onError ?? (()=>{}),
261
- sampleRate: errorConfig.sampleRate ?? 1.0,
262
- showInConsole: errorConfig.showInConsole ?? true,
263
- enableAggregation: errorConfig.enableAggregation ?? true,
264
- aggregationWindow: errorConfig.aggregationWindow ?? 60000,
265
- maxErrorRecords: errorConfig.maxErrorRecords ?? 1000
266
- };
267
- if (this.errorConfig.autoCapture && typeof window !== 'undefined') {
268
- this.initErrorCapture();
269
- }
270
- // 启动错误聚合定时器
271
- if (this.errorConfig.enableAggregation) {
272
- this.startAggregationTimer();
273
- }
274
- }
275
- }
276
- /**
277
- * 默认监控服务实例
278
- */ let defaultMonitoringService = null;
279
- /**
280
- * 初始化默认监控服务
281
- */ export function initMonitoring(config) {
282
- if (!defaultMonitoringService) {
283
- defaultMonitoringService = new MonitoringService(config);
284
- }
285
- return defaultMonitoringService;
286
- }
287
- /**
288
- * 获取默认监控服务
289
- */ export function getMonitoring() {
290
- if (!defaultMonitoringService) {
291
- return initMonitoring();
292
- }
293
- return defaultMonitoringService;
294
- }
1
+ export * from "@vlian/monitoring";
295
2
 
296
3
  //# sourceMappingURL=monitoring.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/monitoring.ts"],"sourcesContent":["import { logger } from './logger';\nimport { errorUtils, type FrameworkError } from './errors';\nimport type { PerformanceMetrics, PerformanceMetricsWithUnits, PerformanceMetricValue } from './performance';\nimport { convertMetricsToWithUnits } from './performance';\n\n/**\n * 错误监控配置\n */\nexport interface ErrorMonitorConfig {\n /**\n * 是否自动捕获未处理的错误\n */\n autoCapture?: boolean;\n /**\n * 错误上报回调\n */\n onError?: (error: FrameworkError, context?: Record<string, unknown>) => void;\n /**\n * 采样率 (0-1)\n */\n sampleRate?: number;\n /**\n * 是否在控制台显示错误\n */\n showInConsole?: boolean;\n /**\n * 是否启用错误聚合\n */\n enableAggregation?: boolean;\n /**\n * 错误聚合窗口大小(毫秒)\n */\n aggregationWindow?: number;\n /**\n * 最大错误记录数\n */\n maxErrorRecords?: number;\n}\n\n/**\n * 错误聚合信息\n */\nexport interface ErrorAggregation {\n /**\n * 错误代码\n */\n code: string;\n /**\n * 错误消息\n */\n message: string;\n /**\n * 错误类型\n */\n type: string;\n /**\n * 错误数量\n */\n count: number;\n /**\n * 首次出现时间\n */\n firstOccurrence: number;\n /**\n * 最后出现时间\n */\n lastOccurrence: number;\n /**\n * 错误堆栈(示例)\n */\n stack?: string;\n /**\n * 错误上下文(示例)\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * 监控服务类\n */\nexport class MonitoringService {\n private errorConfig: Required<ErrorMonitorConfig>;\n private errorHandlers: Array<(error: FrameworkError) => void> = [];\n private performanceMetrics: PerformanceMetricsWithUnits = {};\n private unhandledRejectionHandler?: (event: PromiseRejectionEvent) => void;\n private errorHandler?: (event: ErrorEvent) => void;\n private errorRecords: Array<{ error: FrameworkError; timestamp: number }> = [];\n private errorAggregations: Map<string, ErrorAggregation> = new Map();\n private aggregationTimer?: ReturnType<typeof setInterval>;\n\n constructor(errorConfig: ErrorMonitorConfig = {}) {\n this.errorConfig = {\n autoCapture: errorConfig.autoCapture ?? true,\n onError: errorConfig.onError ?? (() => {}),\n sampleRate: errorConfig.sampleRate ?? 1.0,\n showInConsole: errorConfig.showInConsole ?? true,\n enableAggregation: errorConfig.enableAggregation ?? true,\n aggregationWindow: errorConfig.aggregationWindow ?? 60000, // 1分钟\n maxErrorRecords: errorConfig.maxErrorRecords ?? 1000,\n };\n\n if (this.errorConfig.autoCapture && typeof window !== 'undefined') {\n this.initErrorCapture();\n }\n\n // 启动错误聚合定时器\n if (this.errorConfig.enableAggregation) {\n this.startAggregationTimer();\n }\n }\n\n /**\n * 初始化错误捕获\n */\n private initErrorCapture(): void {\n // 捕获未处理的 Promise 错误\n this.unhandledRejectionHandler = (event: PromiseRejectionEvent) => {\n const error = errorUtils.normalizeError(event.reason);\n this.captureError(error, {\n type: 'unhandledrejection',\n reason: event.reason,\n });\n };\n window.addEventListener('unhandledrejection', this.unhandledRejectionHandler);\n\n // 捕获全局错误\n this.errorHandler = (event: ErrorEvent) => {\n const error = errorUtils.normalizeError(event.error || new Error(event.message));\n this.captureError(error, {\n type: 'global',\n filename: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n });\n };\n window.addEventListener('error', this.errorHandler);\n }\n\n /**\n * 清理资源\n */\n destroy(): void {\n // 移除事件监听器\n if (typeof window !== 'undefined') {\n if (this.unhandledRejectionHandler) {\n window.removeEventListener('unhandledrejection', this.unhandledRejectionHandler);\n }\n if (this.errorHandler) {\n window.removeEventListener('error', this.errorHandler);\n }\n }\n\n // 停止聚合定时器\n if (this.aggregationTimer) {\n clearInterval(this.aggregationTimer);\n this.aggregationTimer = undefined;\n }\n\n // 清空错误处理器\n this.errorHandlers = [];\n this.errorRecords = [];\n this.errorAggregations.clear();\n }\n\n /**\n * 启动错误聚合定时器\n */\n private startAggregationTimer(): void {\n this.aggregationTimer = setInterval(() => {\n this.aggregateErrors();\n }, this.errorConfig.aggregationWindow!);\n }\n\n /**\n * 聚合错误\n */\n private aggregateErrors(): void {\n const now = Date.now();\n const windowStart = now - this.errorConfig.aggregationWindow!;\n\n // 过滤窗口内的错误\n const windowErrors = this.errorRecords.filter(\n (record) => record.timestamp >= windowStart\n );\n\n // 按错误代码聚合\n const aggregations = new Map<string, ErrorAggregation>();\n\n for (const record of windowErrors) {\n const error = record.error;\n const key = `${error.code}_${error.type}`;\n\n if (!aggregations.has(key)) {\n aggregations.set(key, {\n code: error.code,\n message: error.message,\n type: error.type,\n count: 0,\n firstOccurrence: record.timestamp,\n lastOccurrence: record.timestamp,\n stack: error.originalError?.stack,\n context: error.context,\n });\n }\n\n const agg = aggregations.get(key)!;\n agg.count++;\n agg.lastOccurrence = Math.max(agg.lastOccurrence, record.timestamp);\n }\n\n // 更新聚合结果\n this.errorAggregations = aggregations;\n }\n\n /**\n * 捕获错误\n */\n captureError(error: unknown, context?: Record<string, unknown>): void {\n // 采样检查\n if (Math.random() > this.errorConfig.sampleRate) {\n return;\n }\n\n const normalizedError = errorUtils.normalizeError(error);\n // 创建带上下文的错误对象(使用 Object.assign 来更新只读属性)\n const errorWithContext = Object.assign(normalizedError, {\n context: {\n ...normalizedError.context,\n ...context,\n timestamp: new Date().toISOString(),\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,\n url: typeof window !== 'undefined' ? window.location.href : undefined,\n },\n });\n\n // 记录错误\n const timestamp = Date.now();\n this.errorRecords.push({\n error: errorWithContext,\n timestamp,\n });\n\n // 限制错误记录数量\n if (this.errorRecords.length > this.errorConfig.maxErrorRecords!) {\n this.errorRecords.shift();\n }\n\n // 记录日志\n if (this.errorConfig.showInConsole) {\n logger.error('监控服务捕获到错误:', errorWithContext.toJSON());\n }\n\n // 调用错误回调\n this.errorConfig.onError(errorWithContext, context);\n\n // 调用注册的错误处理器\n this.errorHandlers.forEach((handler) => {\n try {\n handler(errorWithContext);\n } catch (e) {\n // 忽略处理器错误\n }\n });\n }\n\n /**\n * 获取错误聚合信息\n * \n * @param code - 错误代码(可选,如果提供则只返回该错误的聚合信息)\n * @returns 错误聚合信息\n */\n getErrorAggregations(code?: string): ErrorAggregation[] {\n if (code) {\n const aggregation = this.errorAggregations.get(code);\n return aggregation ? [aggregation] : [];\n }\n return Array.from(this.errorAggregations.values());\n }\n\n /**\n * 获取错误记录\n * \n * @param limit - 限制返回的记录数\n * @param since - 只返回此时间之后的错误\n * @returns 错误记录\n */\n getErrorRecords(limit?: number, since?: number): Array<{ error: FrameworkError; timestamp: number }> {\n let records = this.errorRecords;\n\n if (since) {\n records = records.filter((record) => record.timestamp >= since);\n }\n\n if (limit) {\n records = records.slice(-limit);\n }\n\n return [...records];\n }\n\n /**\n * 清空错误记录\n */\n clearErrorRecords(): void {\n this.errorRecords = [];\n this.errorAggregations.clear();\n }\n\n /**\n * 注册错误处理器\n */\n onError(handler: (error: FrameworkError) => void): () => void {\n this.errorHandlers.push(handler);\n return () => {\n const index = this.errorHandlers.indexOf(handler);\n if (index > -1) {\n this.errorHandlers.splice(index, 1);\n }\n };\n }\n\n /**\n * 上报性能指标\n */\n reportPerformance(metrics: PerformanceMetrics, context?: Record<string, unknown>): void {\n // 将传入的指标转换为带单位的格式\n const metricsWithUnits = convertMetricsToWithUnits(metrics);\n \n // 合并到现有指标中\n this.performanceMetrics = { ...this.performanceMetrics, ...metricsWithUnits };\n \n // 记录性能指标(带上下文)\n if (context) {\n logger.debug('性能指标更新:', { metrics: metricsWithUnits, context });\n } else {\n logger.debug('性能指标更新:', metricsWithUnits);\n }\n }\n\n /**\n * 批量上报性能指标\n */\n reportPerformanceBatch(metricsArray: Array<{ metrics: PerformanceMetrics; context?: Record<string, unknown> }>): void {\n for (const { metrics, context } of metricsArray) {\n this.reportPerformance(metrics, context);\n }\n }\n\n /**\n * 获取性能指标(带单位)\n */\n getPerformanceMetrics(): PerformanceMetricsWithUnits {\n return { ...this.performanceMetrics };\n }\n\n /**\n * 获取性能指标(原始数值格式,向后兼容)\n */\n getPerformanceMetricsRaw(): PerformanceMetrics {\n const result: PerformanceMetrics = {};\n \n for (const [key, metricValue] of Object.entries(this.performanceMetrics)) {\n if (metricValue && typeof metricValue === 'object' && 'value' in metricValue) {\n (result as Record<string, number>)[key] = (metricValue as PerformanceMetricValue).value;\n }\n }\n \n return result;\n }\n\n /**\n * 记录用户行为(匿名)\n */\n trackEvent(eventName: string, properties?: Record<string, unknown>): void {\n logger.debug('用户事件:', { eventName, properties });\n }\n}\n\n/**\n * 默认监控服务实例\n */\nlet defaultMonitoringService: MonitoringService | null = null;\n\n/**\n * 初始化默认监控服务\n */\nexport function initMonitoring(config?: ErrorMonitorConfig): MonitoringService {\n if (!defaultMonitoringService) {\n defaultMonitoringService = new MonitoringService(config);\n }\n return defaultMonitoringService;\n}\n\n/**\n * 获取默认监控服务\n */\nexport function getMonitoring(): MonitoringService {\n if (!defaultMonitoringService) {\n return initMonitoring();\n }\n return defaultMonitoringService;\n}\n"],"names":["logger","errorUtils","convertMetricsToWithUnits","MonitoringService","initErrorCapture","unhandledRejectionHandler","event","error","normalizeError","reason","captureError","type","window","addEventListener","errorHandler","Error","message","filename","lineno","colno","destroy","removeEventListener","aggregationTimer","clearInterval","undefined","errorHandlers","errorRecords","errorAggregations","clear","startAggregationTimer","setInterval","aggregateErrors","errorConfig","aggregationWindow","now","Date","windowStart","windowErrors","filter","record","timestamp","aggregations","Map","key","code","has","set","count","firstOccurrence","lastOccurrence","stack","originalError","context","agg","get","Math","max","random","sampleRate","normalizedError","errorWithContext","Object","assign","toISOString","userAgent","navigator","url","location","href","push","length","maxErrorRecords","shift","showInConsole","toJSON","onError","forEach","handler","e","getErrorAggregations","aggregation","Array","from","values","getErrorRecords","limit","since","records","slice","clearErrorRecords","index","indexOf","splice","reportPerformance","metrics","metricsWithUnits","performanceMetrics","debug","reportPerformanceBatch","metricsArray","getPerformanceMetrics","getPerformanceMetricsRaw","result","metricValue","entries","value","trackEvent","eventName","properties","autoCapture","enableAggregation","defaultMonitoringService","initMonitoring","config","getMonitoring"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/monitoring.ts"],"sourcesContent":["export * from '@vlian/monitoring';\n"],"names":[],"mappings":"AAAA,cAAc,oBAAoB"}