@nest-omni/core 4.1.3-19 → 4.1.3-20

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 (45) hide show
  1. package/cache/cache.module.d.ts +0 -6
  2. package/cache/cache.module.js +7 -7
  3. package/cache/cache.service.js +12 -0
  4. package/cache/dependencies/db.dependency.d.ts +0 -13
  5. package/cache/dependencies/db.dependency.js +0 -16
  6. package/cache/dependencies/tag.dependency.d.ts +39 -4
  7. package/cache/dependencies/tag.dependency.js +109 -11
  8. package/cache/interfaces/cache-options.interface.d.ts +8 -0
  9. package/cache/providers/memory-cache.provider.d.ts +20 -0
  10. package/cache/providers/memory-cache.provider.js +40 -0
  11. package/http-client/config/http-client.config.d.ts +5 -0
  12. package/http-client/config/http-client.config.js +24 -13
  13. package/http-client/decorators/http-client.decorators.d.ts +1 -25
  14. package/http-client/decorators/http-client.decorators.js +97 -90
  15. package/http-client/entities/http-log.entity.d.ts +0 -20
  16. package/http-client/entities/http-log.entity.js +0 -12
  17. package/http-client/examples/advanced-usage.example.d.ts +4 -5
  18. package/http-client/examples/advanced-usage.example.js +4 -56
  19. package/http-client/http-client.module.d.ts +35 -2
  20. package/http-client/http-client.module.js +80 -75
  21. package/http-client/index.d.ts +1 -1
  22. package/http-client/interfaces/api-client-config.interface.d.ts +1 -91
  23. package/http-client/interfaces/http-client-config.interface.d.ts +53 -62
  24. package/http-client/services/api-client-registry.service.d.ts +5 -23
  25. package/http-client/services/api-client-registry.service.js +41 -284
  26. package/http-client/services/circuit-breaker.service.d.ts +69 -2
  27. package/http-client/services/circuit-breaker.service.js +185 -7
  28. package/http-client/services/http-client.service.d.ts +58 -23
  29. package/http-client/services/http-client.service.js +294 -150
  30. package/http-client/services/http-log-query.service.js +0 -13
  31. package/http-client/services/index.d.ts +0 -1
  32. package/http-client/services/index.js +0 -1
  33. package/http-client/services/logging.service.d.ts +79 -10
  34. package/http-client/services/logging.service.js +246 -51
  35. package/http-client/utils/call-stack-extractor.util.d.ts +26 -0
  36. package/http-client/utils/call-stack-extractor.util.js +35 -0
  37. package/http-client/utils/security-validator.util.d.ts +118 -0
  38. package/http-client/utils/security-validator.util.js +352 -0
  39. package/package.json +1 -1
  40. package/redis-lock/lock-heartbeat.service.d.ts +2 -0
  41. package/redis-lock/lock-heartbeat.service.js +12 -2
  42. package/redis-lock/redis-lock.service.d.ts +4 -0
  43. package/redis-lock/redis-lock.service.js +61 -8
  44. package/http-client/services/cache.service.d.ts +0 -76
  45. package/http-client/services/cache.service.js +0 -333
@@ -21,25 +21,19 @@ var ApiClientRegistryService_1;
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
22
  exports.ApiClientRegistryService = exports.AuthType = void 0;
23
23
  const common_1 = require("@nestjs/common");
24
- const axios_1 = require("axios");
25
- const axios_retry_1 = require("axios-retry");
26
24
  const api_client_config_interface_1 = require("../interfaces/api-client-config.interface");
27
25
  Object.defineProperty(exports, "AuthType", { enumerable: true, get: function () { return api_client_config_interface_1.AuthType; } });
28
26
  const http_client_service_1 = require("./http-client.service");
29
27
  const circuit_breaker_service_1 = require("./circuit-breaker.service");
30
28
  const logging_service_1 = require("./logging.service");
31
- const cache_service_1 = require("./cache.service");
32
- const context_extractor_util_1 = require("../utils/context-extractor.util");
33
- const utils_1 = require("../../common/utils");
34
29
  /**
35
30
  * API客户端注册服务
31
+ * 负责管理多个 HttpClientService 实例
36
32
  */
37
33
  let ApiClientRegistryService = ApiClientRegistryService_1 = class ApiClientRegistryService {
38
- constructor(httpClientService, circuitBreakerService, loggingService, cacheService, globalConfig = {}) {
39
- this.httpClientService = httpClientService;
34
+ constructor(circuitBreakerService, loggingService, globalConfig = {}) {
40
35
  this.circuitBreakerService = circuitBreakerService;
41
36
  this.loggingService = loggingService;
42
- this.cacheService = cacheService;
43
37
  this.logger = new common_1.Logger(ApiClientRegistryService_1.name);
44
38
  this.clients = new Map();
45
39
  this.clientConfigs = new Map();
@@ -65,8 +59,10 @@ let ApiClientRegistryService = ApiClientRegistryService_1 = class ApiClientRegis
65
59
  }
66
60
  /**
67
61
  * 创建API客户端实例
62
+ * 使用 HttpClientService.createApiClient 静态方法创建
68
63
  */
69
64
  createClient(config) {
65
+ var _a, _b, _c, _d, _e, _f, _g;
70
66
  const clientName = config.name;
71
67
  const existingClient = this.clients.get(clientName);
72
68
  if (existingClient && !config.override) {
@@ -75,15 +71,44 @@ let ApiClientRegistryService = ApiClientRegistryService_1 = class ApiClientRegis
75
71
  }
76
72
  // 合并环境特定配置
77
73
  const finalConfig = this.mergeEnvironmentConfig(config);
78
- // 创建Axios实例
79
- const axiosInstance = this.createAxiosInstance(finalConfig);
80
- // 创建API客户端
81
- const client = new ApiClientInstance(clientName, finalConfig, axiosInstance, this.httpClientService, this.loggingService, this.cacheService);
74
+ // 使用静态工厂方法创建 HttpClientService 实例
75
+ const httpClient = http_client_service_1.HttpClientService.createApiClient({
76
+ circuitBreakerService: this.circuitBreakerService,
77
+ loggingService: this.loggingService,
78
+ }, {
79
+ name: clientName,
80
+ baseURL: finalConfig.baseURL,
81
+ timeout: ((_a = finalConfig.httpConfig) === null || _a === void 0 ? void 0 : _a.timeout) || 30000,
82
+ httpConfig: Object.assign({ retry: {
83
+ enabled: ((_b = finalConfig.retry) === null || _b === void 0 ? void 0 : _b.enabled) !== false &&
84
+ this.globalDefaults.enableGlobalRetry,
85
+ retries: ((_c = finalConfig.retry) === null || _c === void 0 ? void 0 : _c.retries) ||
86
+ ((_e = (_d = this.globalDefaults.globalDefaults) === null || _d === void 0 ? void 0 : _d.retry) === null || _e === void 0 ? void 0 : _e.retries) ||
87
+ 3,
88
+ retryDelay: (retryCount) => Math.pow(2, retryCount) * 1000,
89
+ retryCondition: ((_f = finalConfig.retry) === null || _f === void 0 ? void 0 : _f.retryCondition) ||
90
+ ((error) => {
91
+ if (!error.response)
92
+ return true;
93
+ const status = error.response.status;
94
+ return status >= 500 || status === 429;
95
+ }),
96
+ shouldResetTimeout: true,
97
+ }, logging: Object.assign({ enabled: true, logRequests: true, logResponses: true, logErrors: true, logHeaders: true, logBody: true, maxBodyLength: 10000, sanitizeHeaders: ['authorization', 'api-key'], logLevel: 'info' }, (_g = this.globalDefaults.globalDefaults) === null || _g === void 0 ? void 0 : _g.logging), circuitBreaker: {
98
+ enabled: this.globalDefaults.enableCircuitBreaker,
99
+ failureThreshold: 5,
100
+ recoveryTimeoutMs: 60000,
101
+ monitoringPeriodMs: 10000,
102
+ minimumThroughputThreshold: 10,
103
+ countHalfOpenCalls: true,
104
+ } }, finalConfig.httpConfig),
105
+ auth: finalConfig.auth,
106
+ });
82
107
  // 存储客户端和配置
83
- this.clients.set(clientName, client);
108
+ this.clients.set(clientName, httpClient);
84
109
  this.clientConfigs.set(clientName, finalConfig);
85
110
  this.logger.log(`Created API client: ${clientName}`);
86
- return client;
111
+ return httpClient;
87
112
  }
88
113
  /**
89
114
  * 获取已注册的客户端
@@ -209,182 +234,6 @@ let ApiClientRegistryService = ApiClientRegistryService_1 = class ApiClientRegis
209
234
  };
210
235
  });
211
236
  }
212
- /**
213
- * 创建Axios实例
214
- */
215
- createAxiosInstance(config) {
216
- var _a, _b, _c, _d, _e, _f;
217
- const axiosConfig = {
218
- baseURL: config.baseURL,
219
- timeout: ((_a = config.httpConfig) === null || _a === void 0 ? void 0 : _a.timeout) || 30000,
220
- headers: Object.assign({ 'Content-Type': 'application/json', 'User-Agent': `${config.name}/1.0.0` }, config.defaultHeaders),
221
- params: config.defaultParams,
222
- };
223
- const instance = axios_1.default.create(axiosConfig);
224
- const clientName = config.name; // Capture client name for use in closures
225
- // 配置请求拦截器
226
- instance.interceptors.request.use((config) => {
227
- // 添加鉴权信息 - for now, skip async authentication to avoid type issues
228
- const authenticatedConfig = config;
229
- // Add simple auth headers for basic cases
230
- if (config.auth) {
231
- switch (config.auth.type) {
232
- case api_client_config_interface_1.AuthType.BEARER_TOKEN:
233
- const bearerConfig = config.auth.config;
234
- authenticatedConfig.headers = authenticatedConfig.headers || {};
235
- authenticatedConfig.headers['Authorization'] =
236
- `Bearer ${bearerConfig.token}`;
237
- break;
238
- case api_client_config_interface_1.AuthType.API_KEY:
239
- const apiKeyConfig = config.auth.config;
240
- if (apiKeyConfig.location === 'header') {
241
- const headerName = apiKeyConfig.name || 'X-API-Key';
242
- const value = apiKeyConfig.prefix
243
- ? `${apiKeyConfig.prefix} ${apiKeyConfig.key}`
244
- : apiKeyConfig.key;
245
- authenticatedConfig.headers = authenticatedConfig.headers || {};
246
- authenticatedConfig.headers[headerName] = value;
247
- }
248
- break;
249
- }
250
- }
251
- // 添加请求ID和上下文信息
252
- const context = context_extractor_util_1.ContextExtractor.getHttpContext();
253
- const requestId = context.requestId || (0, utils_1.generateRequestId)();
254
- authenticatedConfig.headers = authenticatedConfig.headers || {};
255
- authenticatedConfig.headers['X-Request-ID'] = requestId;
256
- if (context.userId) {
257
- authenticatedConfig.headers['X-User-ID'] = context.userId;
258
- }
259
- // 添加API标识
260
- authenticatedConfig.headers['X-API-Client'] = clientName;
261
- return authenticatedConfig;
262
- }, (error) => {
263
- this.logger.error(`[${clientName}] Request interceptor error`, error);
264
- return Promise.reject(error);
265
- });
266
- // 配置响应拦截器
267
- instance.interceptors.response.use((response) => {
268
- // 应用响应转换器
269
- return this.applyResponseTransformer(response, config.responseTransformer);
270
- }, (error) => {
271
- var _a;
272
- // 应用错误转换器
273
- if ((_a = config.responseTransformer) === null || _a === void 0 ? void 0 : _a.error) {
274
- return config.responseTransformer.error(error);
275
- }
276
- return Promise.reject(error);
277
- });
278
- // 配置axios-retry
279
- if (((_b = config.retry) === null || _b === void 0 ? void 0 : _b.enabled) !== false &&
280
- this.globalDefaults.enableGlobalRetry) {
281
- (0, axios_retry_1.default)(instance, {
282
- retries: ((_c = config.retry) === null || _c === void 0 ? void 0 : _c.retries) ||
283
- ((_e = (_d = this.globalDefaults.globalDefaults) === null || _d === void 0 ? void 0 : _d.retry) === null || _e === void 0 ? void 0 : _e.retries) ||
284
- 3,
285
- retryDelay: (retryCount) => Math.pow(2, retryCount) * 1000,
286
- retryCondition: ((_f = config.retry) === null || _f === void 0 ? void 0 : _f.retryCondition) ||
287
- ((error) => {
288
- if (!error.response)
289
- return true;
290
- const status = error.response.status;
291
- return status >= 500 || status === 429;
292
- }),
293
- shouldResetTimeout: true,
294
- onRetry: (retryCount, error, requestConfig) => {
295
- var _a;
296
- this.logger.warn(`[${config.name}] Retrying request (attempt ${retryCount}): ${(_a = requestConfig.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()} ${requestConfig.url}`);
297
- },
298
- });
299
- }
300
- return instance;
301
- }
302
- /**
303
- * 应用鉴权配置
304
- */
305
- applyAuthentication(config, auth) {
306
- return __awaiter(this, void 0, void 0, function* () {
307
- if (!auth) {
308
- return config;
309
- }
310
- const authenticatedConfig = Object.assign({}, config);
311
- switch (auth.type) {
312
- case api_client_config_interface_1.AuthType.NONE:
313
- break;
314
- case api_client_config_interface_1.AuthType.API_KEY:
315
- const apiKeyConfig = auth.config;
316
- if (apiKeyConfig.location === 'header') {
317
- const headerName = apiKeyConfig.name || 'X-API-Key';
318
- const value = apiKeyConfig.prefix
319
- ? `${apiKeyConfig.prefix} ${apiKeyConfig.key}`
320
- : apiKeyConfig.key;
321
- authenticatedConfig.headers = Object.assign(Object.assign({}, authenticatedConfig.headers), { [headerName]: value });
322
- }
323
- else if (apiKeyConfig.location === 'query') {
324
- const paramName = apiKeyConfig.name || 'api_key';
325
- authenticatedConfig.params = Object.assign(Object.assign({}, authenticatedConfig.params), { [paramName]: apiKeyConfig.key });
326
- }
327
- break;
328
- case api_client_config_interface_1.AuthType.BEARER_TOKEN:
329
- const bearerConfig = auth.config;
330
- const scheme = bearerConfig.scheme || 'Bearer';
331
- authenticatedConfig.headers = Object.assign(Object.assign({}, authenticatedConfig.headers), { Authorization: `${scheme} ${bearerConfig.token}` });
332
- break;
333
- case api_client_config_interface_1.AuthType.BASIC_AUTH:
334
- const basicConfig = auth.config;
335
- const credentials = Buffer.from(`${basicConfig.username}:${basicConfig.password}`).toString('base64');
336
- authenticatedConfig.headers = Object.assign(Object.assign({}, authenticatedConfig.headers), { Authorization: `Basic ${credentials}` });
337
- break;
338
- case api_client_config_interface_1.AuthType.OAUTH2:
339
- const oauthConfig = auth.config;
340
- // OAuth2实现需要异步获取token
341
- // 这里简化处理,实际项目中可能需要更复杂的逻辑
342
- authenticatedConfig.headers = Object.assign(Object.assign({}, authenticatedConfig.headers), { Authorization: `Bearer ${oauthConfig.clientSecret}` });
343
- break;
344
- case api_client_config_interface_1.AuthType.CUSTOM:
345
- const customConfig = auth.config;
346
- return yield customConfig.authenticator(authenticatedConfig);
347
- }
348
- return authenticatedConfig;
349
- });
350
- }
351
- /**
352
- * 应用响应转换器
353
- */
354
- applyResponseTransformer(response, transformer) {
355
- if (!transformer) {
356
- return response;
357
- }
358
- // 应用成功响应转换器
359
- if (transformer.success) {
360
- response.data = transformer.success(response);
361
- }
362
- // 应用数据路径提取
363
- if (transformer.dataPath) {
364
- response.data = this.extractDataByPath(response.data, transformer.dataPath);
365
- }
366
- // 应用响应验证
367
- if (transformer.validateResponse && transformer.validator) {
368
- if (!transformer.validator(response.data)) {
369
- throw new Error(`Response validation failed for ${transformer.dataPath}`);
370
- }
371
- }
372
- return response;
373
- }
374
- /**
375
- * 根据路径提取数据
376
- */
377
- extractDataByPath(data, path) {
378
- const keys = path.split('.');
379
- let current = data;
380
- for (const key of keys) {
381
- if (current === null || current === undefined) {
382
- return undefined;
383
- }
384
- current = current[key];
385
- }
386
- return current;
387
- }
388
237
  /**
389
238
  * 合并环境特定配置
390
239
  */
@@ -398,98 +247,6 @@ let ApiClientRegistryService = ApiClientRegistryService_1 = class ApiClientRegis
398
247
  exports.ApiClientRegistryService = ApiClientRegistryService;
399
248
  exports.ApiClientRegistryService = ApiClientRegistryService = ApiClientRegistryService_1 = __decorate([
400
249
  (0, common_1.Injectable)(),
401
- __metadata("design:paramtypes", [http_client_service_1.HttpClientService,
402
- circuit_breaker_service_1.HttpCircuitBreakerService,
403
- logging_service_1.HttpLoggingService,
404
- cache_service_1.HttpCacheService, Object])
250
+ __metadata("design:paramtypes", [circuit_breaker_service_1.HttpCircuitBreakerService,
251
+ logging_service_1.HttpLoggingService, Object])
405
252
  ], ApiClientRegistryService);
406
- /**
407
- * API客户端实例实现
408
- */
409
- class ApiClientInstance {
410
- constructor(name, config, axiosInstance, httpClientService, loggingService, cacheService) {
411
- this.name = name;
412
- this.config = config;
413
- this.axiosInstance = axiosInstance;
414
- this.httpClientService = httpClientService;
415
- this.loggingService = loggingService;
416
- this.cacheService = cacheService;
417
- this.stats = {
418
- totalRequests: 0,
419
- successfulRequests: 0,
420
- failedRequests: 0,
421
- totalResponseTime: 0,
422
- averageResponseTime: 0,
423
- };
424
- }
425
- get(url, config) {
426
- return __awaiter(this, void 0, void 0, function* () {
427
- return this.request(Object.assign(Object.assign({}, config), { method: 'GET', url }));
428
- });
429
- }
430
- post(url, data, config) {
431
- return __awaiter(this, void 0, void 0, function* () {
432
- return this.request(Object.assign(Object.assign({}, config), { method: 'POST', url, data }));
433
- });
434
- }
435
- put(url, data, config) {
436
- return __awaiter(this, void 0, void 0, function* () {
437
- return this.request(Object.assign(Object.assign({}, config), { method: 'PUT', url, data }));
438
- });
439
- }
440
- patch(url, data, config) {
441
- return __awaiter(this, void 0, void 0, function* () {
442
- return this.request(Object.assign(Object.assign({}, config), { method: 'PATCH', url, data }));
443
- });
444
- }
445
- delete(url, config) {
446
- return __awaiter(this, void 0, void 0, function* () {
447
- return this.request(Object.assign(Object.assign({}, config), { method: 'DELETE', url }));
448
- });
449
- }
450
- request(config) {
451
- return __awaiter(this, void 0, void 0, function* () {
452
- const startTime = Date.now();
453
- this.stats.totalRequests++;
454
- try {
455
- const response = yield this.axiosInstance.request(config);
456
- // 更新统计信息
457
- const responseTime = Date.now() - startTime;
458
- this.updateStats(true, responseTime);
459
- return response.data;
460
- }
461
- catch (error) {
462
- // 更新统计信息
463
- const responseTime = Date.now() - startTime;
464
- this.updateStats(false, responseTime);
465
- throw error;
466
- }
467
- });
468
- }
469
- getStats() {
470
- return Object.assign({}, this.stats);
471
- }
472
- resetStats() {
473
- this.stats.totalRequests = 0;
474
- this.stats.successfulRequests = 0;
475
- this.stats.failedRequests = 0;
476
- this.stats.totalResponseTime = 0;
477
- this.stats.averageResponseTime = 0;
478
- }
479
- updateStats(success, responseTime) {
480
- if (success) {
481
- this.stats.successfulRequests++;
482
- }
483
- else {
484
- this.stats.failedRequests++;
485
- }
486
- this.stats.totalResponseTime += responseTime;
487
- this.stats.averageResponseTime =
488
- this.stats.totalResponseTime / this.stats.totalRequests;
489
- // 响应时间警告
490
- if (this.config.responseTimeWarningThreshold &&
491
- responseTime > this.config.responseTimeWarningThreshold) {
492
- console.warn(`[API Client ${this.name}] Slow response detected: ${responseTime}ms for ${this.axiosInstance.defaults.baseURL}`);
493
- }
494
- }
495
- }
@@ -1,5 +1,16 @@
1
1
  import { Logger } from '@nestjs/common';
2
2
  import { CircuitBreakerConfig } from '../interfaces/http-client-config.interface';
3
+ /**
4
+ * Circuit Breaker 清理配置
5
+ */
6
+ interface CircuitBreakerCleanupConfig {
7
+ /** 最大空闲时间(毫秒),超过此时间未使用的circuit breaker将被清理 */
8
+ maxIdleTimeMs: number;
9
+ /** 清理间隔(毫秒),定期清理的时间间隔 */
10
+ cleanupIntervalMs: number;
11
+ /** 最大circuit breaker数量,超过此数量时触发LRU清理 */
12
+ maxSize: number;
13
+ }
3
14
  /**
4
15
  * 熔断器服务
5
16
  * 基于Spring Cloud CircuitBreaker的设计理念
@@ -7,6 +18,11 @@ import { CircuitBreakerConfig } from '../interfaces/http-client-config.interface
7
18
  export declare class HttpCircuitBreakerService {
8
19
  private readonly logger;
9
20
  private readonly circuitBreakers;
21
+ private cleanupTimer?;
22
+ /** 默认清理配置 */
23
+ private readonly cleanupConfig;
24
+ constructor();
25
+ onModuleDestroy(): void;
10
26
  /**
11
27
  * 获取或创建熔断器
12
28
  */
@@ -14,7 +30,11 @@ export declare class HttpCircuitBreakerService {
14
30
  /**
15
31
  * 执行带熔断保护的请求
16
32
  */
17
- executeWithCircuitBreaker<T>(key: string, requestFn: () => Promise<T>, config: CircuitBreakerConfig): Promise<T>;
33
+ executeWithCircuitBreaker<T>(key: string, requestFn: () => Promise<T>, config: CircuitBreakerConfig, onStateChange?: (state: string) => void): Promise<T>;
34
+ /**
35
+ * 获取熔断器当前状态
36
+ */
37
+ getCircuitBreakerState(key: string): string | undefined;
18
38
  /**
19
39
  * 重置所有熔断器
20
40
  */
@@ -23,6 +43,39 @@ export declare class HttpCircuitBreakerService {
23
43
  * 获取所有熔断器状态
24
44
  */
25
45
  getAllStates(): Record<string, any>;
46
+ /**
47
+ * 获取Circuit Breaker统计信息
48
+ */
49
+ getStats(): {
50
+ total: number;
51
+ byState: Record<string, number>;
52
+ };
53
+ /**
54
+ * 清理空闲的Circuit Breaker
55
+ * 清理超过最大空闲时间的Circuit Breaker
56
+ */
57
+ cleanupIdle(): number;
58
+ /**
59
+ * 基于LRU策略清理Circuit Breaker
60
+ * 删除最久未访问的Circuit Breaker直到数量降到maxSize以下
61
+ */
62
+ private cleanupLRU;
63
+ /**
64
+ * 启动定期清理任务
65
+ */
66
+ private startCleanupTask;
67
+ /**
68
+ * 手动触发清理(用于测试)
69
+ */
70
+ manualCleanup(): number;
71
+ /**
72
+ * 设置清理配置
73
+ */
74
+ setCleanupConfig(config: Partial<CircuitBreakerCleanupConfig>): void;
75
+ /**
76
+ * 获取清理配置
77
+ */
78
+ getCleanupConfig(): CircuitBreakerCleanupConfig;
26
79
  }
27
80
  /**
28
81
  * 熔断器类
@@ -38,11 +91,21 @@ declare class CircuitBreaker {
38
91
  private nextAttemptTime;
39
92
  private requestCount;
40
93
  private windowStartTime;
94
+ private onStateChange?;
95
+ private lastAccessTime;
41
96
  constructor(key: string, config: CircuitBreakerConfig, logger: Logger);
97
+ /**
98
+ * 更新最后访问时间
99
+ */
100
+ updateLastAccessTime(): void;
101
+ /**
102
+ * 获取最后访问时间
103
+ */
104
+ getLastAccessTime(): number;
42
105
  /**
43
106
  * 执行请求
44
107
  */
45
- execute<T>(requestFn: () => Promise<T>): Promise<T>;
108
+ execute<T>(requestFn: () => Promise<T>, onStateChange?: (state: string) => void): Promise<T>;
46
109
  /**
47
110
  * 重置熔断器
48
111
  */
@@ -71,6 +134,10 @@ declare class CircuitBreaker {
71
134
  * 转换到半开状态
72
135
  */
73
136
  private transitionToHalfOpen;
137
+ /**
138
+ * 通知状态变化
139
+ */
140
+ private notifyStateChange;
74
141
  /**
75
142
  * 重置监控窗口
76
143
  */