@private.me/xbind 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/README.md +55 -14
  2. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1920 -1
  3. package/dist-standalone/_deps/shared/cjs/errors.js +729 -1
  4. package/dist-standalone/_deps/shared/cjs/index.js +463 -1
  5. package/dist-standalone/_deps/shared/cjs/types.js +315 -1
  6. package/dist-standalone/_deps/shared/errors.js +244 -1
  7. package/dist-standalone/_deps/shared/index.js +72 -1
  8. package/dist-standalone/_deps/shared/types.js +86 -1
  9. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
  10. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
  11. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
  12. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
  13. package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
  14. package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
  15. package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
  16. package/dist-standalone/_deps/ux-helpers/index.js +1 -1
  17. package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
  18. package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
  19. package/dist-standalone/_deps/ux-helpers/search.js +1 -1
  20. package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
  21. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
  22. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
  23. package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
  24. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
  25. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
  26. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
  27. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
  28. package/dist-standalone/_deps/xchange/errors.js +1 -1
  29. package/dist-standalone/_deps/xchange/index.js +1 -1
  30. package/dist-standalone/_deps/xchange/invite-client.js +1 -1
  31. package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
  32. package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
  33. package/dist-standalone/_deps/xchange/xchange.js +1 -1
  34. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
  35. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
  36. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
  37. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
  38. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
  39. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
  40. package/dist-standalone/_deps/xregistry/discovery.js +1 -1
  41. package/dist-standalone/_deps/xregistry/errors.js +1 -1
  42. package/dist-standalone/_deps/xregistry/index.js +1 -1
  43. package/dist-standalone/_deps/xregistry/registry.js +1 -1
  44. package/dist-standalone/_deps/xregistry/schema.js +1 -1
  45. package/dist-standalone/_deps/xregistry/types.js +1 -1
  46. package/dist-standalone/agent-call.js +659 -1
  47. package/dist-standalone/agent-sdk.js +328 -1
  48. package/dist-standalone/agent.js +1800 -1
  49. package/dist-standalone/approval.js +193 -1
  50. package/dist-standalone/async-iterators.js +382 -1
  51. package/dist-standalone/auth.js +219 -1
  52. package/dist-standalone/auto-accept.js +229 -1
  53. package/dist-standalone/backup-config.js +201 -1
  54. package/dist-standalone/backup.js +326 -1
  55. package/dist-standalone/batch-operations.js +388 -1
  56. package/dist-standalone/cancellation.js +477 -1
  57. package/dist-standalone/checkpoint.js +186 -1
  58. package/dist-standalone/circuit-breaker.js +468 -1
  59. package/dist-standalone/cjs/agent-call.js +701 -1
  60. package/dist-standalone/cjs/agent-sdk.js +332 -1
  61. package/dist-standalone/cjs/agent.js +1837 -1
  62. package/dist-standalone/cjs/approval.js +199 -1
  63. package/dist-standalone/cjs/async-iterators.js +392 -1
  64. package/dist-standalone/cjs/auth.js +225 -1
  65. package/dist-standalone/cjs/auto-accept.js +233 -1
  66. package/dist-standalone/cjs/backup-config.js +207 -1
  67. package/dist-standalone/cjs/backup.js +330 -1
  68. package/dist-standalone/cjs/batch-operations.js +397 -1
  69. package/dist-standalone/cjs/cancellation.js +490 -1
  70. package/dist-standalone/cjs/checkpoint.js +193 -1
  71. package/dist-standalone/cjs/circuit-breaker.js +476 -1
  72. package/dist-standalone/cjs/cli/init.js +492 -1
  73. package/dist-standalone/cjs/config-validation.js +522 -1
  74. package/dist-standalone/cjs/connect.js +312 -1
  75. package/dist-standalone/cjs/connection-pool.js +506 -1
  76. package/dist-standalone/cjs/correlation-id.js +339 -1
  77. package/dist-standalone/cjs/crypto-utils.js +176 -1
  78. package/dist-standalone/cjs/debug-mode.js +534 -1
  79. package/dist-standalone/cjs/did-document.js +101 -1
  80. package/dist-standalone/cjs/did-privateme.js +130 -1
  81. package/dist-standalone/cjs/did-web.js +201 -1
  82. package/dist-standalone/cjs/discovery.js +462 -1
  83. package/dist-standalone/cjs/dual-mode.js +251 -1
  84. package/dist-standalone/cjs/email-templates.js +313 -1
  85. package/dist-standalone/cjs/email-transport.js +239 -1
  86. package/dist-standalone/cjs/envelope.js +538 -1
  87. package/dist-standalone/cjs/errors.js +913 -1
  88. package/dist-standalone/cjs/event-emitter.js +461 -1
  89. package/dist-standalone/cjs/gateway-state.js +55 -1
  90. package/dist-standalone/cjs/gateway-transport.js +120 -1
  91. package/dist-standalone/cjs/graceful-degradation.js +403 -1
  92. package/dist-standalone/cjs/guardrails.js +223 -1
  93. package/dist-standalone/cjs/health-check.js +336 -1
  94. package/dist-standalone/cjs/http-compat.js +272 -1
  95. package/dist-standalone/cjs/http-status-map.js +571 -1
  96. package/dist-standalone/cjs/identity.js +645 -1
  97. package/dist-standalone/cjs/index.js +406 -1
  98. package/dist-standalone/cjs/invitation.js +421 -1
  99. package/dist-standalone/cjs/invite.js +328 -1
  100. package/dist-standalone/cjs/key-agreement.js +335 -1
  101. package/dist-standalone/cjs/lazy-init.js +300 -1
  102. package/dist-standalone/cjs/logger.js +291 -1
  103. package/dist-standalone/cjs/mdns-discovery.js +202 -1
  104. package/dist-standalone/cjs/nonce-store.js +80 -1
  105. package/dist-standalone/cjs/pairing-manager.js +223 -1
  106. package/dist-standalone/cjs/plugin-system.js +264 -1
  107. package/dist-standalone/cjs/plugins/logging.js +168 -1
  108. package/dist-standalone/cjs/plugins/metrics.js +181 -1
  109. package/dist-standalone/cjs/plugins/validation.js +302 -1
  110. package/dist-standalone/cjs/policy.js +320 -1
  111. package/dist-standalone/cjs/progress-callbacks.js +583 -1
  112. package/dist-standalone/cjs/redis-nonce-store.js +76 -1
  113. package/dist-standalone/cjs/registry-middleware.js +50 -1
  114. package/dist-standalone/cjs/retry-strategies.js +544 -1
  115. package/dist-standalone/cjs/retry-transport.js +102 -1
  116. package/dist-standalone/cjs/runtime/browser.js +533 -1
  117. package/dist-standalone/cjs/runtime/edge.js +526 -1
  118. package/dist-standalone/cjs/runtime/react-native.js +394 -1
  119. package/dist-standalone/cjs/security-policy.js +245 -1
  120. package/dist-standalone/cjs/serialization.js +1040 -1
  121. package/dist-standalone/cjs/split-channel.js +225 -1
  122. package/dist-standalone/cjs/subscription-proof.js +230 -1
  123. package/dist-standalone/cjs/succession.js +148 -1
  124. package/dist-standalone/cjs/timeouts.js +412 -1
  125. package/dist-standalone/cjs/trace-context.js +424 -1
  126. package/dist-standalone/cjs/trace-spans.js +495 -1
  127. package/dist-standalone/cjs/transport.js +63 -1
  128. package/dist-standalone/cjs/trust-registry.js +991 -1
  129. package/dist-standalone/cjs/types/error-response.js +56 -1
  130. package/dist-standalone/cjs/vault-auth.js +178 -1
  131. package/dist-standalone/cjs/vault-store-loader.js +194 -1
  132. package/dist-standalone/cjs/verify.js +25 -1
  133. package/dist-standalone/cjs/version-info.js +543 -1
  134. package/dist-standalone/cjs/xfetch.js +340 -1
  135. package/dist-standalone/cli/init.js +455 -1
  136. package/dist-standalone/cli/setup.js +514 -1
  137. package/dist-standalone/cli/types.js +27 -1
  138. package/dist-standalone/cli/xbind.js +148 -1
  139. package/dist-standalone/config-validation.js +513 -1
  140. package/dist-standalone/connect.js +274 -1
  141. package/dist-standalone/connection-pool.js +500 -1
  142. package/dist-standalone/correlation-id.js +326 -1
  143. package/dist-standalone/crypto-utils.js +157 -1
  144. package/dist-standalone/debug-mode.js +510 -1
  145. package/dist-standalone/did-document.js +96 -1
  146. package/dist-standalone/did-privateme.js +121 -1
  147. package/dist-standalone/did-web.js +196 -1
  148. package/dist-standalone/discovery.js +458 -1
  149. package/dist-standalone/dual-mode.js +247 -1
  150. package/dist-standalone/email-templates.js +309 -1
  151. package/dist-standalone/email-transport.js +232 -1
  152. package/dist-standalone/envelope.js +525 -1
  153. package/dist-standalone/errors.js +896 -1
  154. package/dist-standalone/event-emitter.js +456 -1
  155. package/dist-standalone/gateway-state.js +51 -1
  156. package/dist-standalone/gateway-transport.js +116 -1
  157. package/dist-standalone/graceful-degradation.js +396 -1
  158. package/dist-standalone/guardrails.js +216 -1
  159. package/dist-standalone/health-check.js +332 -1
  160. package/dist-standalone/http-compat.js +267 -1
  161. package/dist-standalone/http-status-map.js +561 -1
  162. package/dist-standalone/identity.js +619 -1
  163. package/dist-standalone/index.js +78 -1
  164. package/dist-standalone/invitation.js +415 -1
  165. package/dist-standalone/invite.js +324 -1
  166. package/dist-standalone/key-agreement.js +325 -1
  167. package/dist-standalone/lazy-init.js +295 -1
  168. package/dist-standalone/logger.js +285 -1
  169. package/dist-standalone/mdns-discovery.js +195 -1
  170. package/dist-standalone/nonce-store.js +76 -1
  171. package/dist-standalone/pairing-manager.js +219 -1
  172. package/dist-standalone/plugin-system.js +257 -1
  173. package/dist-standalone/plugins/logging.js +163 -1
  174. package/dist-standalone/plugins/metrics.js +176 -1
  175. package/dist-standalone/plugins/validation.js +297 -1
  176. package/dist-standalone/policy.js +315 -1
  177. package/dist-standalone/progress-callbacks.js +576 -1
  178. package/dist-standalone/redis-nonce-store.js +72 -1
  179. package/dist-standalone/registry-middleware.js +47 -1
  180. package/dist-standalone/retry-strategies.js +534 -1
  181. package/dist-standalone/retry-transport.js +98 -1
  182. package/dist-standalone/runtime/browser.js +516 -1
  183. package/dist-standalone/runtime/edge.js +511 -1
  184. package/dist-standalone/runtime/react-native.js +383 -1
  185. package/dist-standalone/security-policy.js +239 -1
  186. package/dist-standalone/serialization.js +1031 -1
  187. package/dist-standalone/split-channel.js +219 -1
  188. package/dist-standalone/subscription-proof.js +224 -1
  189. package/dist-standalone/succession.js +142 -1
  190. package/dist-standalone/timeouts.js +398 -1
  191. package/dist-standalone/trace-context.js +414 -1
  192. package/dist-standalone/trace-spans.js +488 -1
  193. package/dist-standalone/transport.js +59 -1
  194. package/dist-standalone/trust-registry.js +950 -1
  195. package/dist-standalone/types/error-response.js +52 -1
  196. package/dist-standalone/vault-auth.js +174 -1
  197. package/dist-standalone/vault-store-loader.js +187 -1
  198. package/dist-standalone/verify.js +16 -1
  199. package/dist-standalone/version-info.js +530 -1
  200. package/dist-standalone/xfetch.js +335 -1
  201. package/package.json +4 -13
  202. package/share1.dat +0 -0
  203. package/dist-standalone/_deps/mldsa-wasm/LICENSE +0 -24
  204. package/dist-standalone/_deps/mldsa-wasm/package.json +0 -46
  205. package/dist-standalone/_deps/shared/cjs/package.json +0 -1
  206. package/dist-standalone/_deps/ux-helpers/cjs/package.json +0 -1
  207. package/dist-standalone/_deps/xchange/cjs/package.json +0 -1
  208. package/dist-standalone/_deps/xregistry/cjs/package.json +0 -1
  209. package/dist-standalone/cjs/package.json +0 -3
  210. package/dist-standalone/package.json +0 -10
@@ -1 +1,476 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CircuitBreakerManager=exports.CircuitBreaker=void 0,exports.createRegistryCircuitBreaker=createRegistryCircuitBreaker,exports.createGatewayCircuitBreaker=createGatewayCircuitBreaker,exports.createS3CircuitBreaker=createS3CircuitBreaker;const shared_1=require("../_deps/shared/index.js");class CircuitBreaker{state="CLOSED";consecutiveFailures=0;consecutiveSuccesses=0;successCount=0;failureCount=0;rejectedCount=0;lastOpenedAt;lastClosedAt;recoveryTimer;failureThreshold;recoveryTimeout;halfOpenMaxCalls;successThreshold;name;onStateChange;onOpen;onClose;onHalfOpen;constructor(e={}){this.failureThreshold=e.failureThreshold??5,this.recoveryTimeout=e.recoveryTimeout??6e4,this.halfOpenMaxCalls=e.halfOpenMaxCalls??3,this.successThreshold=e.successThreshold??2,this.name=e.name??"default",this.onStateChange=e.onStateChange,this.onOpen=e.onOpen,this.onClose=e.onClose,this.onHalfOpen=e.onHalfOpen}async execute(e){if("OPEN"===this.state)return this.rejectedCount++,(0,shared_1.err)("CIRCUIT_OPEN");if("HALF_OPEN"===this.state){if(this.consecutiveSuccesses+(this.consecutiveFailures>0?1:0)>=this.halfOpenMaxCalls)return this.rejectedCount++,(0,shared_1.err)("HALF_OPEN_LIMIT_EXCEEDED")}try{const t=await e();return this.onSuccess(),(0,shared_1.ok)(t)}catch(e){return this.onFailure(e),(0,shared_1.err)("EXECUTION_FAILED")}}getMetrics(){return{state:this.state,successCount:this.successCount,failureCount:this.failureCount,rejectedCount:this.rejectedCount,consecutiveFailures:this.consecutiveFailures,consecutiveSuccesses:this.consecutiveSuccesses,lastOpenedAt:this.lastOpenedAt,lastClosedAt:this.lastClosedAt,name:this.name}}getState(){return this.state}reset(){this.clearRecoveryTimer(),this.transitionTo("CLOSED","manual reset"),this.consecutiveFailures=0,this.consecutiveSuccesses=0}forceOpen(e="manual intervention"){this.transitionTo("OPEN",e),this.scheduleRecovery()}dispose(){this.clearRecoveryTimer()}onSuccess(){this.successCount++,this.consecutiveFailures=0,"HALF_OPEN"===this.state&&(this.consecutiveSuccesses++,this.consecutiveSuccesses>=this.successThreshold&&(this.transitionTo("CLOSED",`${this.consecutiveSuccesses} consecutive successes`),this.consecutiveSuccesses=0))}onFailure(e){if(this.failureCount++,this.consecutiveFailures++,this.consecutiveSuccesses=0,"CLOSED"===this.state&&this.consecutiveFailures>=this.failureThreshold){const e=`${this.consecutiveFailures} consecutive failures`;this.transitionTo("OPEN",e),this.scheduleRecovery()}"HALF_OPEN"===this.state&&(this.transitionTo("OPEN","failure in HALF_OPEN state"),this.scheduleRecovery())}transitionTo(e,t){const s=this.state;s!==e&&(this.state=e,"OPEN"===e?(this.lastOpenedAt=Date.now(),this.onOpen?.(t)):"CLOSED"===e?(this.lastClosedAt=Date.now(),this.onClose?.()):"HALF_OPEN"===e&&this.onHalfOpen?.(),this.onStateChange?.(s,e,t))}scheduleRecovery(){this.clearRecoveryTimer(),this.recoveryTimer=setTimeout(()=>{"OPEN"===this.state&&this.transitionTo("HALF_OPEN","recovery timeout elapsed")},this.recoveryTimeout),this.recoveryTimer.unref&&this.recoveryTimer.unref()}clearRecoveryTimer(){this.recoveryTimer&&(clearTimeout(this.recoveryTimer),this.recoveryTimer=void 0)}}function createRegistryCircuitBreaker(e={}){return new CircuitBreaker({name:"registry",failureThreshold:10,recoveryTimeout:12e4,halfOpenMaxCalls:5,successThreshold:3,...e})}function createGatewayCircuitBreaker(e={}){return new CircuitBreaker({name:"gateway",failureThreshold:5,recoveryTimeout:6e4,halfOpenMaxCalls:3,successThreshold:2,...e})}function createS3CircuitBreaker(e={}){return new CircuitBreaker({name:"s3",failureThreshold:3,recoveryTimeout:3e4,halfOpenMaxCalls:2,successThreshold:2,...e})}exports.CircuitBreaker=CircuitBreaker;class CircuitBreakerManager{breakers=new Map;constructor(){this.breakers.set("registry",createRegistryCircuitBreaker()),this.breakers.set("gateway",createGatewayCircuitBreaker()),this.breakers.set("s3",createS3CircuitBreaker())}async executeRegistry(e){const t=this.breakers.get("registry");return t?t.execute(e):(0,shared_1.err)("Circuit breaker not found: registry")}async executeGateway(e){const t=this.breakers.get("gateway");return t?t.execute(e):(0,shared_1.err)("Circuit breaker not found: gateway")}async executeS3(e){const t=this.breakers.get("s3");return t?t.execute(e):(0,shared_1.err)("Circuit breaker not found: s3")}getMetrics(e){return this.breakers.get(e)?.getMetrics()}getAllMetrics(){const e={};for(const[t,s]of this.breakers.entries())e[t]=s.getMetrics();return e}getOrCreate(e,t){let s=this.breakers.get(e);return s||(s=new CircuitBreaker({...t,name:e}),this.breakers.set(e,s)),s}resetAll(){for(const e of this.breakers.values())e.reset()}dispose(){for(const e of this.breakers.values())e.dispose();this.breakers.clear()}}exports.CircuitBreakerManager=CircuitBreakerManager;
1
+ "use strict";
2
+ /**
3
+ * @module circuit-breaker
4
+ * Circuit breaker pattern for enhanced fault tolerance
5
+ *
6
+ * Protects external service calls (registry, gateway, S3) from cascading failures
7
+ * by automatically opening circuits after repeated failures and closing them after
8
+ * recovery periods.
9
+ *
10
+ * Architecture:
11
+ * - CLOSED: Normal operation, all requests pass through
12
+ * - OPEN: Circuit tripped, fast-fail all requests without calling service
13
+ * - HALF_OPEN: Testing recovery, allow limited requests to probe service health
14
+ *
15
+ * Features:
16
+ * - Automatic state transitions based on failure thresholds
17
+ * - Exponential backoff for recovery attempts
18
+ * - Per-service circuit isolation
19
+ * - Metrics integration for monitoring
20
+ * - Type-safe error handling
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const breaker = new CircuitBreaker({
25
+ * failureThreshold: 5,
26
+ * recoveryTimeout: 60000,
27
+ * halfOpenMaxCalls: 3,
28
+ * });
29
+ *
30
+ * const result = await breaker.execute(async () => {
31
+ * return await registryClient.lookup(did);
32
+ * });
33
+ * ```
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CircuitBreakerManager = exports.CircuitBreaker = void 0;
37
+ exports.createRegistryCircuitBreaker = createRegistryCircuitBreaker;
38
+ exports.createGatewayCircuitBreaker = createGatewayCircuitBreaker;
39
+ exports.createS3CircuitBreaker = createS3CircuitBreaker;
40
+ const shared_1 = require("../_deps/shared/index.js");
41
+ /* ── Implementation ── */
42
+ /**
43
+ * Circuit breaker for protecting external service calls.
44
+ *
45
+ * Implements the circuit breaker pattern to prevent cascading failures
46
+ * when external services (registry, gateway, S3) become unavailable.
47
+ *
48
+ * State transitions:
49
+ * - CLOSED → OPEN: After failureThreshold consecutive failures
50
+ * - OPEN → HALF_OPEN: After recoveryTimeout milliseconds
51
+ * - HALF_OPEN → CLOSED: After successThreshold successful calls
52
+ * - HALF_OPEN → OPEN: On any failure
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * // Create circuit breaker for registry calls
57
+ * const registryBreaker = new CircuitBreaker({
58
+ * name: 'registry',
59
+ * failureThreshold: 5,
60
+ * recoveryTimeout: 60000,
61
+ * });
62
+ *
63
+ * // Execute protected call
64
+ * const result = await registryBreaker.execute(async () => {
65
+ * return await registry.lookup(did);
66
+ * });
67
+ *
68
+ * if (!result.ok) {
69
+ * console.error('Circuit breaker error:', result.error);
70
+ * }
71
+ * ```
72
+ */
73
+ class CircuitBreaker {
74
+ state = 'CLOSED';
75
+ consecutiveFailures = 0;
76
+ consecutiveSuccesses = 0;
77
+ successCount = 0;
78
+ failureCount = 0;
79
+ rejectedCount = 0;
80
+ lastOpenedAt;
81
+ lastClosedAt;
82
+ recoveryTimer;
83
+ failureThreshold;
84
+ recoveryTimeout;
85
+ halfOpenMaxCalls;
86
+ successThreshold;
87
+ name;
88
+ onStateChange;
89
+ onOpen;
90
+ onClose;
91
+ onHalfOpen;
92
+ /**
93
+ * Create a new circuit breaker.
94
+ *
95
+ * @param options - Circuit breaker configuration
96
+ */
97
+ constructor(options = {}) {
98
+ this.failureThreshold = options.failureThreshold ?? 5;
99
+ this.recoveryTimeout = options.recoveryTimeout ?? 60000;
100
+ this.halfOpenMaxCalls = options.halfOpenMaxCalls ?? 3;
101
+ this.successThreshold = options.successThreshold ?? 2;
102
+ this.name = options.name ?? 'default';
103
+ this.onStateChange = options.onStateChange;
104
+ this.onOpen = options.onOpen;
105
+ this.onClose = options.onClose;
106
+ this.onHalfOpen = options.onHalfOpen;
107
+ }
108
+ /**
109
+ * Execute a function with circuit breaker protection.
110
+ *
111
+ * If the circuit is OPEN, immediately returns an error without calling the function.
112
+ * If the circuit is HALF_OPEN, limits the number of concurrent calls.
113
+ * If the circuit is CLOSED, executes the function normally.
114
+ *
115
+ * @param fn - Async function to execute
116
+ * @returns Result of function execution or circuit breaker error
117
+ */
118
+ async execute(fn) {
119
+ // Check if circuit is open
120
+ if (this.state === 'OPEN') {
121
+ this.rejectedCount++;
122
+ return (0, shared_1.err)('CIRCUIT_OPEN');
123
+ }
124
+ // Check if we've exceeded half-open call limit
125
+ // Use total calls attempted (success + failure) not just counter
126
+ if (this.state === 'HALF_OPEN') {
127
+ const totalAttempts = this.consecutiveSuccesses + (this.consecutiveFailures > 0 ? 1 : 0);
128
+ if (totalAttempts >= this.halfOpenMaxCalls) {
129
+ this.rejectedCount++;
130
+ return (0, shared_1.err)('HALF_OPEN_LIMIT_EXCEEDED');
131
+ }
132
+ }
133
+ try {
134
+ const result = await fn();
135
+ this.onSuccess();
136
+ return (0, shared_1.ok)(result);
137
+ }
138
+ catch (error) {
139
+ this.onFailure(error);
140
+ return (0, shared_1.err)('EXECUTION_FAILED');
141
+ }
142
+ }
143
+ /**
144
+ * Get current circuit breaker metrics.
145
+ *
146
+ * @returns Current metrics snapshot
147
+ */
148
+ getMetrics() {
149
+ return {
150
+ state: this.state,
151
+ successCount: this.successCount,
152
+ failureCount: this.failureCount,
153
+ rejectedCount: this.rejectedCount,
154
+ consecutiveFailures: this.consecutiveFailures,
155
+ consecutiveSuccesses: this.consecutiveSuccesses,
156
+ lastOpenedAt: this.lastOpenedAt,
157
+ lastClosedAt: this.lastClosedAt,
158
+ name: this.name,
159
+ };
160
+ }
161
+ /**
162
+ * Get current circuit state.
163
+ *
164
+ * @returns Current state (CLOSED, OPEN, or HALF_OPEN)
165
+ */
166
+ getState() {
167
+ return this.state;
168
+ }
169
+ /**
170
+ * Manually reset the circuit breaker to CLOSED state.
171
+ *
172
+ * Useful for testing or manual recovery scenarios.
173
+ * Clears all counters and timers.
174
+ */
175
+ reset() {
176
+ this.clearRecoveryTimer();
177
+ this.transitionTo('CLOSED', 'manual reset');
178
+ this.consecutiveFailures = 0;
179
+ this.consecutiveSuccesses = 0;
180
+ }
181
+ /**
182
+ * Manually open the circuit breaker.
183
+ *
184
+ * Useful for maintenance windows or manual intervention.
185
+ *
186
+ * @param reason - Optional reason for opening circuit
187
+ */
188
+ forceOpen(reason = 'manual intervention') {
189
+ this.transitionTo('OPEN', reason);
190
+ this.scheduleRecovery();
191
+ }
192
+ /**
193
+ * Dispose of the circuit breaker and clean up resources.
194
+ *
195
+ * Clears any pending recovery timers.
196
+ */
197
+ dispose() {
198
+ this.clearRecoveryTimer();
199
+ }
200
+ /* ── Private Methods ── */
201
+ /**
202
+ * Handle successful execution.
203
+ */
204
+ onSuccess() {
205
+ this.successCount++;
206
+ this.consecutiveFailures = 0;
207
+ if (this.state === 'HALF_OPEN') {
208
+ this.consecutiveSuccesses++;
209
+ // Close circuit if we've reached success threshold
210
+ if (this.consecutiveSuccesses >= this.successThreshold) {
211
+ this.transitionTo('CLOSED', `${this.consecutiveSuccesses} consecutive successes`);
212
+ this.consecutiveSuccesses = 0;
213
+ }
214
+ }
215
+ }
216
+ /**
217
+ * Handle failed execution.
218
+ *
219
+ * @param _error - Error that occurred (unused but kept for potential future logging)
220
+ */
221
+ onFailure(_error) {
222
+ this.failureCount++;
223
+ this.consecutiveFailures++;
224
+ this.consecutiveSuccesses = 0;
225
+ // Open circuit if we've exceeded failure threshold in CLOSED state
226
+ if (this.state === 'CLOSED' && this.consecutiveFailures >= this.failureThreshold) {
227
+ const reason = `${this.consecutiveFailures} consecutive failures`;
228
+ this.transitionTo('OPEN', reason);
229
+ this.scheduleRecovery();
230
+ }
231
+ // Reopen circuit on any failure in HALF_OPEN state
232
+ if (this.state === 'HALF_OPEN') {
233
+ this.transitionTo('OPEN', 'failure in HALF_OPEN state');
234
+ this.scheduleRecovery();
235
+ }
236
+ }
237
+ /**
238
+ * Transition to a new state.
239
+ *
240
+ * @param newState - Target state
241
+ * @param reason - Reason for transition
242
+ */
243
+ transitionTo(newState, reason) {
244
+ const oldState = this.state;
245
+ if (oldState === newState) {
246
+ return;
247
+ }
248
+ this.state = newState;
249
+ // Update timestamps
250
+ if (newState === 'OPEN') {
251
+ this.lastOpenedAt = Date.now();
252
+ this.onOpen?.(reason);
253
+ }
254
+ else if (newState === 'CLOSED') {
255
+ this.lastClosedAt = Date.now();
256
+ this.onClose?.();
257
+ }
258
+ else if (newState === 'HALF_OPEN') {
259
+ this.onHalfOpen?.();
260
+ }
261
+ // Invoke state change callback
262
+ this.onStateChange?.(oldState, newState, reason);
263
+ }
264
+ /**
265
+ * Schedule automatic recovery from OPEN to HALF_OPEN state.
266
+ */
267
+ scheduleRecovery() {
268
+ this.clearRecoveryTimer();
269
+ this.recoveryTimer = setTimeout(() => {
270
+ if (this.state === 'OPEN') {
271
+ this.transitionTo('HALF_OPEN', 'recovery timeout elapsed');
272
+ }
273
+ }, this.recoveryTimeout);
274
+ // Don't prevent Node.js from exiting
275
+ if (this.recoveryTimer.unref) {
276
+ this.recoveryTimer.unref();
277
+ }
278
+ }
279
+ /**
280
+ * Clear any pending recovery timer.
281
+ */
282
+ clearRecoveryTimer() {
283
+ if (this.recoveryTimer) {
284
+ clearTimeout(this.recoveryTimer);
285
+ this.recoveryTimer = undefined;
286
+ }
287
+ }
288
+ }
289
+ exports.CircuitBreaker = CircuitBreaker;
290
+ /* ── Service-Specific Circuit Breakers ── */
291
+ /**
292
+ * Create a circuit breaker configured for registry operations.
293
+ *
294
+ * Registry operations have:
295
+ * - Higher failure threshold (10) - registry is critical, tolerate transient failures
296
+ * - Longer recovery timeout (2 minutes) - DNS/network issues take time
297
+ * - More half-open probes (5) - verify stability before full recovery
298
+ *
299
+ * @param options - Optional overrides
300
+ * @returns Configured circuit breaker for registry calls
301
+ */
302
+ function createRegistryCircuitBreaker(options = {}) {
303
+ return new CircuitBreaker({
304
+ name: 'registry',
305
+ failureThreshold: 10,
306
+ recoveryTimeout: 120000, // 2 minutes
307
+ halfOpenMaxCalls: 5,
308
+ successThreshold: 3,
309
+ ...options,
310
+ });
311
+ }
312
+ /**
313
+ * Create a circuit breaker configured for gateway operations.
314
+ *
315
+ * Gateway operations have:
316
+ * - Medium failure threshold (5) - gateway should be reliable
317
+ * - Standard recovery timeout (1 minute)
318
+ * - Standard half-open probes (3)
319
+ *
320
+ * @param options - Optional overrides
321
+ * @returns Configured circuit breaker for gateway calls
322
+ */
323
+ function createGatewayCircuitBreaker(options = {}) {
324
+ return new CircuitBreaker({
325
+ name: 'gateway',
326
+ failureThreshold: 5,
327
+ recoveryTimeout: 60000, // 1 minute
328
+ halfOpenMaxCalls: 3,
329
+ successThreshold: 2,
330
+ ...options,
331
+ });
332
+ }
333
+ /**
334
+ * Create a circuit breaker configured for S3 storage operations.
335
+ *
336
+ * S3 operations have:
337
+ * - Lower failure threshold (3) - storage failures are serious
338
+ * - Shorter recovery timeout (30 seconds) - AWS S3 recovers quickly
339
+ * - Fewer half-open probes (2) - S3 is usually reliable
340
+ *
341
+ * @param options - Optional overrides
342
+ * @returns Configured circuit breaker for S3 calls
343
+ */
344
+ function createS3CircuitBreaker(options = {}) {
345
+ return new CircuitBreaker({
346
+ name: 's3',
347
+ failureThreshold: 3,
348
+ recoveryTimeout: 30000, // 30 seconds
349
+ halfOpenMaxCalls: 2,
350
+ successThreshold: 2,
351
+ ...options,
352
+ });
353
+ }
354
+ /* ── Multi-Service Circuit Breaker Manager ── */
355
+ /**
356
+ * Manages multiple circuit breakers for different services.
357
+ *
358
+ * Provides centralized access to service-specific circuit breakers
359
+ * and aggregated metrics across all circuits.
360
+ *
361
+ * @example
362
+ * ```typescript
363
+ * const manager = new CircuitBreakerManager();
364
+ *
365
+ * // Execute registry call with protection
366
+ * const result = await manager.executeRegistry(async () => {
367
+ * return await registry.lookup(did);
368
+ * });
369
+ *
370
+ * // Get all metrics
371
+ * const metrics = manager.getAllMetrics();
372
+ * console.log('Registry state:', metrics.registry.state);
373
+ * ```
374
+ */
375
+ class CircuitBreakerManager {
376
+ breakers = new Map();
377
+ constructor() {
378
+ // Initialize default breakers
379
+ this.breakers.set('registry', createRegistryCircuitBreaker());
380
+ this.breakers.set('gateway', createGatewayCircuitBreaker());
381
+ this.breakers.set('s3', createS3CircuitBreaker());
382
+ }
383
+ /**
384
+ * Execute a function with registry circuit breaker protection.
385
+ *
386
+ * @param fn - Async function to execute
387
+ * @returns Result of function execution or circuit breaker error
388
+ */
389
+ async executeRegistry(fn) {
390
+ const breaker = this.breakers.get('registry');
391
+ if (!breaker) {
392
+ return (0, shared_1.err)('Circuit breaker not found: registry');
393
+ }
394
+ return breaker.execute(fn);
395
+ }
396
+ /**
397
+ * Execute a function with gateway circuit breaker protection.
398
+ *
399
+ * @param fn - Async function to execute
400
+ * @returns Result of function execution or circuit breaker error
401
+ */
402
+ async executeGateway(fn) {
403
+ const breaker = this.breakers.get('gateway');
404
+ if (!breaker) {
405
+ return (0, shared_1.err)('Circuit breaker not found: gateway');
406
+ }
407
+ return breaker.execute(fn);
408
+ }
409
+ /**
410
+ * Execute a function with S3 circuit breaker protection.
411
+ *
412
+ * @param fn - Async function to execute
413
+ * @returns Result of function execution or circuit breaker error
414
+ */
415
+ async executeS3(fn) {
416
+ const breaker = this.breakers.get('s3');
417
+ if (!breaker) {
418
+ return (0, shared_1.err)('Circuit breaker not found: s3');
419
+ }
420
+ return breaker.execute(fn);
421
+ }
422
+ /**
423
+ * Get metrics for a specific circuit breaker.
424
+ *
425
+ * @param name - Circuit breaker name
426
+ * @returns Metrics or undefined if breaker not found
427
+ */
428
+ getMetrics(name) {
429
+ return this.breakers.get(name)?.getMetrics();
430
+ }
431
+ /**
432
+ * Get metrics for all circuit breakers.
433
+ *
434
+ * @returns Map of circuit name to metrics
435
+ */
436
+ getAllMetrics() {
437
+ const metrics = {};
438
+ for (const [name, breaker] of this.breakers.entries()) {
439
+ metrics[name] = breaker.getMetrics();
440
+ }
441
+ return metrics;
442
+ }
443
+ /**
444
+ * Get or create a custom circuit breaker.
445
+ *
446
+ * @param name - Circuit breaker name
447
+ * @param options - Optional configuration (used only on first access)
448
+ * @returns Circuit breaker instance
449
+ */
450
+ getOrCreate(name, options) {
451
+ let breaker = this.breakers.get(name);
452
+ if (!breaker) {
453
+ breaker = new CircuitBreaker({ ...options, name });
454
+ this.breakers.set(name, breaker);
455
+ }
456
+ return breaker;
457
+ }
458
+ /**
459
+ * Reset all circuit breakers to CLOSED state.
460
+ */
461
+ resetAll() {
462
+ for (const breaker of this.breakers.values()) {
463
+ breaker.reset();
464
+ }
465
+ }
466
+ /**
467
+ * Dispose of all circuit breakers and clean up resources.
468
+ */
469
+ dispose() {
470
+ for (const breaker of this.breakers.values()) {
471
+ breaker.dispose();
472
+ }
473
+ this.breakers.clear();
474
+ }
475
+ }
476
+ exports.CircuitBreakerManager = CircuitBreakerManager;