@private.me/xbind 1.3.5 → 3.0.0

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 (306) hide show
  1. package/LICENSES.md +212 -0
  2. package/README.md +388 -6
  3. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1 -1920
  4. package/dist-standalone/_deps/shared/cjs/errors.js +1 -639
  5. package/dist-standalone/_deps/shared/cjs/index.js +1 -496
  6. package/dist-standalone/_deps/shared/cjs/types.js +1 -317
  7. package/dist-standalone/_deps/shared/errors.js +1 -255
  8. package/dist-standalone/_deps/shared/index.js +1 -74
  9. package/dist-standalone/_deps/shared/types.js +1 -90
  10. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
  11. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
  12. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
  13. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
  14. package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
  15. package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
  16. package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
  17. package/dist-standalone/_deps/ux-helpers/index.js +1 -1
  18. package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
  19. package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
  20. package/dist-standalone/_deps/ux-helpers/search.js +1 -1
  21. package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
  22. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
  23. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
  24. package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
  25. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
  26. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
  27. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
  28. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
  29. package/dist-standalone/_deps/xchange/errors.js +1 -1
  30. package/dist-standalone/_deps/xchange/index.js +1 -1
  31. package/dist-standalone/_deps/xchange/invite-client.js +1 -1
  32. package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
  33. package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
  34. package/dist-standalone/_deps/xchange/xchange.js +1 -1
  35. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
  36. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
  37. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
  38. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
  39. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
  40. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
  41. package/dist-standalone/_deps/xregistry/discovery.js +1 -1
  42. package/dist-standalone/_deps/xregistry/errors.js +1 -1
  43. package/dist-standalone/_deps/xregistry/index.js +1 -1
  44. package/dist-standalone/_deps/xregistry/registry.js +1 -1
  45. package/dist-standalone/_deps/xregistry/schema.js +1 -1
  46. package/dist-standalone/_deps/xregistry/types.js +1 -1
  47. package/dist-standalone/agent-call.js +1 -642
  48. package/dist-standalone/agent-sdk.js +1 -328
  49. package/dist-standalone/agent.d.ts +95 -5
  50. package/dist-standalone/agent.js +1 -1545
  51. package/dist-standalone/approval.js +1 -193
  52. package/dist-standalone/async-iterators.d.ts +275 -0
  53. package/dist-standalone/async-iterators.js +1 -0
  54. package/dist-standalone/auth.js +1 -219
  55. package/dist-standalone/auto-accept.js +1 -229
  56. package/dist-standalone/backup-config.js +1 -201
  57. package/dist-standalone/backup.d.ts +114 -0
  58. package/dist-standalone/backup.js +1 -0
  59. package/dist-standalone/batch-operations.d.ts +297 -0
  60. package/dist-standalone/batch-operations.js +1 -0
  61. package/dist-standalone/cancellation.d.ts +301 -0
  62. package/dist-standalone/cancellation.js +1 -0
  63. package/dist-standalone/checkpoint.js +1 -186
  64. package/dist-standalone/circuit-breaker.d.ts +351 -0
  65. package/dist-standalone/circuit-breaker.js +1 -0
  66. package/dist-standalone/cjs/agent-call.js +1 -651
  67. package/dist-standalone/cjs/agent-sdk.js +1 -332
  68. package/dist-standalone/cjs/agent.js +1 -1582
  69. package/dist-standalone/cjs/approval.js +1 -199
  70. package/dist-standalone/cjs/async-iterators.js +1 -0
  71. package/dist-standalone/cjs/auth.js +1 -225
  72. package/dist-standalone/cjs/auto-accept.js +1 -233
  73. package/dist-standalone/cjs/backup-config.js +1 -207
  74. package/dist-standalone/cjs/backup.js +1 -0
  75. package/dist-standalone/cjs/batch-operations.js +1 -0
  76. package/dist-standalone/cjs/cancellation.js +1 -0
  77. package/dist-standalone/cjs/checkpoint.js +1 -193
  78. package/dist-standalone/cjs/circuit-breaker.js +1 -0
  79. package/dist-standalone/cjs/cli/init.js +1 -486
  80. package/dist-standalone/cjs/config-validation.js +1 -0
  81. package/dist-standalone/cjs/connect.js +1 -312
  82. package/dist-standalone/cjs/connection-pool.js +1 -0
  83. package/dist-standalone/cjs/correlation-id.js +1 -339
  84. package/dist-standalone/cjs/crypto-utils.js +1 -0
  85. package/dist-standalone/cjs/debug-mode.js +1 -0
  86. package/dist-standalone/cjs/did-document.js +1 -101
  87. package/dist-standalone/cjs/did-privateme.js +1 -130
  88. package/dist-standalone/cjs/did-web.js +1 -201
  89. package/dist-standalone/cjs/discovery.js +1 -462
  90. package/dist-standalone/cjs/dual-mode.js +1 -251
  91. package/dist-standalone/cjs/email-templates.js +1 -313
  92. package/dist-standalone/cjs/email-transport.js +1 -239
  93. package/dist-standalone/cjs/envelope.js +1 -510
  94. package/dist-standalone/cjs/errors.js +1 -826
  95. package/dist-standalone/cjs/event-emitter.js +1 -0
  96. package/dist-standalone/cjs/gateway-state.js +1 -55
  97. package/dist-standalone/cjs/gateway-transport.js +1 -120
  98. package/dist-standalone/cjs/graceful-degradation.js +1 -0
  99. package/dist-standalone/cjs/guardrails.js +1 -223
  100. package/dist-standalone/cjs/health-check.js +1 -0
  101. package/dist-standalone/cjs/http-compat.js +1 -272
  102. package/dist-standalone/cjs/http-status-map.js +1 -571
  103. package/dist-standalone/cjs/identity.js +1 -540
  104. package/dist-standalone/cjs/index.js +1 -237
  105. package/dist-standalone/cjs/invitation.js +1 -421
  106. package/dist-standalone/cjs/invite.js +1 -328
  107. package/dist-standalone/cjs/key-agreement.js +1 -246
  108. package/dist-standalone/cjs/lazy-init.js +1 -300
  109. package/dist-standalone/cjs/logger.js +1 -0
  110. package/dist-standalone/cjs/mdns-discovery.js +1 -202
  111. package/dist-standalone/cjs/nonce-store.js +1 -66
  112. package/dist-standalone/cjs/pairing-manager.js +1 -223
  113. package/dist-standalone/cjs/plugin-system.js +1 -0
  114. package/dist-standalone/cjs/plugins/logging.js +1 -0
  115. package/dist-standalone/cjs/plugins/metrics.js +1 -0
  116. package/dist-standalone/cjs/plugins/validation.js +1 -0
  117. package/dist-standalone/cjs/policy.js +1 -320
  118. package/dist-standalone/cjs/progress-callbacks.js +1 -0
  119. package/dist-standalone/cjs/redis-nonce-store.js +1 -76
  120. package/dist-standalone/cjs/registry-middleware.js +1 -50
  121. package/dist-standalone/cjs/retry-strategies.js +1 -0
  122. package/dist-standalone/cjs/retry-transport.js +1 -102
  123. package/dist-standalone/cjs/runtime/browser.js +1 -0
  124. package/dist-standalone/cjs/runtime/edge.js +1 -0
  125. package/dist-standalone/cjs/runtime/react-native.js +1 -0
  126. package/dist-standalone/cjs/security-policy.js +1 -245
  127. package/dist-standalone/cjs/serialization.js +1 -0
  128. package/dist-standalone/cjs/split-channel.js +1 -177
  129. package/dist-standalone/cjs/subscription-proof.js +1 -230
  130. package/dist-standalone/cjs/succession.js +1 -148
  131. package/dist-standalone/cjs/timeouts.js +1 -0
  132. package/dist-standalone/cjs/trace-context.js +1 -0
  133. package/dist-standalone/cjs/trace-spans.js +1 -0
  134. package/dist-standalone/cjs/transport.js +1 -63
  135. package/dist-standalone/cjs/trust-registry.js +1 -742
  136. package/dist-standalone/cjs/types/error-response.js +1 -56
  137. package/dist-standalone/cjs/vault-auth.js +1 -0
  138. package/dist-standalone/cjs/vault-store-loader.js +1 -0
  139. package/dist-standalone/cjs/verify.js +1 -25
  140. package/dist-standalone/cjs/version-info.js +1 -0
  141. package/dist-standalone/cjs/xfetch.js +1 -252
  142. package/dist-standalone/cli/init.js +1 -449
  143. package/dist-standalone/cli/setup.js +1 -514
  144. package/dist-standalone/cli/types.js +1 -27
  145. package/dist-standalone/cli/xbind.js +1 -148
  146. package/dist-standalone/config-validation.d.ts +185 -0
  147. package/dist-standalone/config-validation.js +1 -0
  148. package/dist-standalone/connect.js +1 -274
  149. package/dist-standalone/connection-pool.d.ts +251 -0
  150. package/dist-standalone/connection-pool.js +1 -0
  151. package/dist-standalone/correlation-id.js +1 -326
  152. package/dist-standalone/crypto-utils.d.ts +60 -0
  153. package/dist-standalone/crypto-utils.js +1 -0
  154. package/dist-standalone/debug-mode.d.ts +286 -0
  155. package/dist-standalone/debug-mode.js +1 -0
  156. package/dist-standalone/did-document.js +1 -96
  157. package/dist-standalone/did-privateme.js +1 -121
  158. package/dist-standalone/did-web.js +1 -196
  159. package/dist-standalone/discovery.js +1 -458
  160. package/dist-standalone/dual-mode.js +1 -247
  161. package/dist-standalone/email-templates.js +1 -309
  162. package/dist-standalone/email-transport.js +1 -232
  163. package/dist-standalone/envelope.d.ts +29 -1
  164. package/dist-standalone/envelope.js +1 -497
  165. package/dist-standalone/errors.d.ts +10 -0
  166. package/dist-standalone/errors.js +1 -811
  167. package/dist-standalone/event-emitter.d.ts +395 -0
  168. package/dist-standalone/event-emitter.js +1 -0
  169. package/dist-standalone/gateway-state.js +1 -51
  170. package/dist-standalone/gateway-transport.js +1 -116
  171. package/dist-standalone/graceful-degradation.d.ts +246 -0
  172. package/dist-standalone/graceful-degradation.js +1 -0
  173. package/dist-standalone/guardrails.js +1 -216
  174. package/dist-standalone/health-check.d.ts +150 -0
  175. package/dist-standalone/health-check.js +1 -0
  176. package/dist-standalone/http-compat.js +1 -267
  177. package/dist-standalone/http-status-map.js +1 -561
  178. package/dist-standalone/identity.d.ts +64 -1
  179. package/dist-standalone/identity.js +1 -515
  180. package/dist-standalone/index.d.ts +45 -3
  181. package/dist-standalone/index.js +1 -52
  182. package/dist-standalone/invitation.js +1 -415
  183. package/dist-standalone/invite.js +1 -324
  184. package/dist-standalone/key-agreement.d.ts +61 -13
  185. package/dist-standalone/key-agreement.js +1 -236
  186. package/dist-standalone/lazy-init.js +1 -295
  187. package/dist-standalone/logger.d.ts +77 -0
  188. package/dist-standalone/logger.js +1 -0
  189. package/dist-standalone/mdns-discovery.js +1 -195
  190. package/dist-standalone/nonce-store.d.ts +16 -3
  191. package/dist-standalone/nonce-store.js +1 -62
  192. package/dist-standalone/package.json +0 -1
  193. package/dist-standalone/pairing-manager.js +1 -219
  194. package/dist-standalone/plugin-system.d.ts +145 -0
  195. package/dist-standalone/plugin-system.js +1 -0
  196. package/dist-standalone/policy.js +1 -315
  197. package/dist-standalone/progress-callbacks.d.ts +394 -0
  198. package/dist-standalone/progress-callbacks.js +1 -0
  199. package/dist-standalone/redis-nonce-store.js +1 -72
  200. package/dist-standalone/registry-middleware.js +1 -47
  201. package/dist-standalone/retry-strategies.d.ts +382 -0
  202. package/dist-standalone/retry-strategies.js +1 -0
  203. package/dist-standalone/retry-transport.js +1 -98
  204. package/dist-standalone/security-policy.js +1 -239
  205. package/dist-standalone/serialization.d.ts +244 -0
  206. package/dist-standalone/serialization.js +1 -0
  207. package/dist-standalone/split-channel.d.ts +49 -1
  208. package/dist-standalone/split-channel.js +1 -171
  209. package/dist-standalone/subscription-proof.js +1 -224
  210. package/dist-standalone/succession.js +1 -142
  211. package/dist-standalone/timeouts.d.ts +275 -0
  212. package/dist-standalone/timeouts.js +1 -0
  213. package/dist-standalone/trace-context.d.ts +252 -0
  214. package/dist-standalone/trace-context.js +1 -0
  215. package/dist-standalone/trace-spans.d.ts +360 -0
  216. package/dist-standalone/trace-spans.js +1 -0
  217. package/dist-standalone/transport.js +1 -59
  218. package/dist-standalone/trust-registry.d.ts +106 -5
  219. package/dist-standalone/trust-registry.js +1 -702
  220. package/dist-standalone/vault-auth.d.ts +91 -0
  221. package/dist-standalone/vault-auth.js +1 -0
  222. package/dist-standalone/vault-store-loader.d.ts +110 -0
  223. package/dist-standalone/vault-store-loader.js +1 -0
  224. package/dist-standalone/verify.js +1 -16
  225. package/dist-standalone/version-info.d.ts +259 -0
  226. package/dist-standalone/version-info.js +1 -0
  227. package/dist-standalone/xfetch.js +1 -247
  228. package/llms.txt +1 -0
  229. package/package.json +65 -5
  230. package/share1.dat +0 -0
  231. package/dist-standalone/_deps/crypto/base64.d.ts +0 -29
  232. package/dist-standalone/_deps/crypto/base64.js +0 -222
  233. package/dist-standalone/_deps/crypto/cjs/base64.js +0 -665
  234. package/dist-standalone/_deps/crypto/cjs/errors.js +0 -675
  235. package/dist-standalone/_deps/crypto/cjs/hmac.js +0 -473
  236. package/dist-standalone/_deps/crypto/cjs/index.js +0 -852
  237. package/dist-standalone/_deps/crypto/cjs/package.json +0 -1
  238. package/dist-standalone/_deps/crypto/cjs/padding.js +0 -511
  239. package/dist-standalone/_deps/crypto/cjs/share-header.js +0 -372
  240. package/dist-standalone/_deps/crypto/cjs/shares.js +0 -874
  241. package/dist-standalone/_deps/crypto/cjs/tlv.js +0 -1021
  242. package/dist-standalone/_deps/crypto/cjs/uuid.js +0 -443
  243. package/dist-standalone/_deps/crypto/cjs/verify.js +0 -414
  244. package/dist-standalone/_deps/crypto/cjs/xorida.js +0 -923
  245. package/dist-standalone/_deps/crypto/errors.d.ts +0 -51
  246. package/dist-standalone/_deps/crypto/errors.js +0 -199
  247. package/dist-standalone/_deps/crypto/hmac.d.ts +0 -39
  248. package/dist-standalone/_deps/crypto/hmac.js +0 -134
  249. package/dist-standalone/_deps/crypto/index.d.ts +0 -20
  250. package/dist-standalone/_deps/crypto/index.js +0 -145
  251. package/dist-standalone/_deps/crypto/padding.d.ts +0 -19
  252. package/dist-standalone/_deps/crypto/padding.js +0 -159
  253. package/dist-standalone/_deps/crypto/share-header.d.ts +0 -44
  254. package/dist-standalone/_deps/crypto/share-header.js +0 -92
  255. package/dist-standalone/_deps/crypto/shares.d.ts +0 -27
  256. package/dist-standalone/_deps/crypto/shares.js +0 -295
  257. package/dist-standalone/_deps/crypto/tlv.d.ts +0 -26
  258. package/dist-standalone/_deps/crypto/tlv.js +0 -364
  259. package/dist-standalone/_deps/crypto/uuid.d.ts +0 -22
  260. package/dist-standalone/_deps/crypto/uuid.js +0 -136
  261. package/dist-standalone/_deps/crypto/verify.d.ts +0 -15
  262. package/dist-standalone/_deps/crypto/verify.js +0 -71
  263. package/dist-standalone/_deps/crypto/xorida.d.ts +0 -44
  264. package/dist-standalone/_deps/crypto/xorida.js +0 -366
  265. package/dist-standalone/_deps/shared/errors.d.ts.map +0 -1
  266. package/dist-standalone/_deps/shared/errors.js.map +0 -1
  267. package/dist-standalone/_deps/shared/index.d.ts.map +0 -1
  268. package/dist-standalone/_deps/shared/index.js.map +0 -1
  269. package/dist-standalone/_deps/shared/types.d.ts.map +0 -1
  270. package/dist-standalone/_deps/shared/types.js.map +0 -1
  271. package/dist-standalone/_deps/ux-helpers/cjs/errors.d.ts.map +0 -1
  272. package/dist-standalone/_deps/ux-helpers/cjs/errors.js.map +0 -1
  273. package/dist-standalone/_deps/ux-helpers/cjs/index.d.ts.map +0 -1
  274. package/dist-standalone/_deps/ux-helpers/cjs/index.js.map +0 -1
  275. package/dist-standalone/_deps/ux-helpers/cjs/pagination.d.ts.map +0 -1
  276. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js.map +0 -1
  277. package/dist-standalone/_deps/ux-helpers/cjs/progress.d.ts.map +0 -1
  278. package/dist-standalone/_deps/ux-helpers/cjs/progress.js.map +0 -1
  279. package/dist-standalone/_deps/ux-helpers/cjs/search.d.ts.map +0 -1
  280. package/dist-standalone/_deps/ux-helpers/cjs/search.js.map +0 -1
  281. package/dist-standalone/_deps/ux-helpers/cjs/types.d.ts.map +0 -1
  282. package/dist-standalone/_deps/ux-helpers/cjs/types.js.map +0 -1
  283. package/dist-standalone/_deps/ux-helpers/errors.d.ts.map +0 -1
  284. package/dist-standalone/_deps/ux-helpers/errors.js.map +0 -1
  285. package/dist-standalone/_deps/ux-helpers/index.d.ts.map +0 -1
  286. package/dist-standalone/_deps/ux-helpers/index.js.map +0 -1
  287. package/dist-standalone/_deps/ux-helpers/pagination.d.ts.map +0 -1
  288. package/dist-standalone/_deps/ux-helpers/pagination.js.map +0 -1
  289. package/dist-standalone/_deps/ux-helpers/progress.d.ts.map +0 -1
  290. package/dist-standalone/_deps/ux-helpers/progress.js.map +0 -1
  291. package/dist-standalone/_deps/ux-helpers/search.d.ts.map +0 -1
  292. package/dist-standalone/_deps/ux-helpers/search.js.map +0 -1
  293. package/dist-standalone/_deps/ux-helpers/types.d.ts.map +0 -1
  294. package/dist-standalone/_deps/ux-helpers/types.js.map +0 -1
  295. package/dist-standalone/_deps/xregistry/discovery.d.ts.map +0 -1
  296. package/dist-standalone/_deps/xregistry/discovery.js.map +0 -1
  297. package/dist-standalone/_deps/xregistry/errors.d.ts.map +0 -1
  298. package/dist-standalone/_deps/xregistry/errors.js.map +0 -1
  299. package/dist-standalone/_deps/xregistry/index.d.ts.map +0 -1
  300. package/dist-standalone/_deps/xregistry/index.js.map +0 -1
  301. package/dist-standalone/_deps/xregistry/registry.d.ts.map +0 -1
  302. package/dist-standalone/_deps/xregistry/registry.js.map +0 -1
  303. package/dist-standalone/_deps/xregistry/schema.d.ts.map +0 -1
  304. package/dist-standalone/_deps/xregistry/schema.js.map +0 -1
  305. package/dist-standalone/_deps/xregistry/types.d.ts.map +0 -1
  306. package/dist-standalone/_deps/xregistry/types.js.map +0 -1
@@ -0,0 +1,382 @@
1
+ /**
2
+ * @module retry-strategies
3
+ * Configurable retry strategies for enhanced reliability.
4
+ *
5
+ * Provides flexible retry policies with exponential backoff, jitter, circuit breakers,
6
+ * and error-specific retry logic. Designed for production-grade fault tolerance.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { RetryStrategy, CircuitBreaker } from '@private.me/xbind/retry-strategies';
11
+ *
12
+ * // Exponential backoff with circuit breaker
13
+ * const strategy = RetryStrategy.exponentialBackoff({
14
+ * maxAttempts: 5,
15
+ * initialDelayMs: 1000,
16
+ * maxDelayMs: 30000,
17
+ * multiplier: 2,
18
+ * jitter: true
19
+ * });
20
+ *
21
+ * const circuitBreaker = new CircuitBreaker({
22
+ * failureThreshold: 5,
23
+ * resetTimeoutMs: 60000
24
+ * });
25
+ * ```
26
+ */
27
+ import type { Result } from '@private.me/shared';
28
+ import type { TransportError } from './transport.js';
29
+ /**
30
+ * Retry context provides information about the current retry attempt.
31
+ */
32
+ export interface RetryContext {
33
+ /** Current attempt number (0-indexed) */
34
+ readonly attempt: number;
35
+ /** Error from the previous attempt */
36
+ readonly error: TransportError;
37
+ /** Timestamp of the first attempt */
38
+ readonly startTime: number;
39
+ /** Total elapsed time since first attempt (ms) */
40
+ readonly elapsedMs: number;
41
+ /** Additional metadata */
42
+ readonly metadata?: Record<string, unknown>;
43
+ }
44
+ /**
45
+ * Result of a retry decision.
46
+ */
47
+ export interface RetryDecision {
48
+ /** Whether to retry the operation */
49
+ readonly shouldRetry: boolean;
50
+ /** Delay before next retry (ms), if shouldRetry is true */
51
+ readonly delayMs?: number;
52
+ /** Reason for the decision (for logging/debugging) */
53
+ readonly reason?: string;
54
+ }
55
+ /**
56
+ * Configuration for exponential backoff retry strategy.
57
+ */
58
+ export interface ExponentialBackoffConfig {
59
+ /** Maximum number of retry attempts (default: 3) */
60
+ maxAttempts?: number;
61
+ /** Initial delay in milliseconds (default: 1000) */
62
+ initialDelayMs?: number;
63
+ /** Maximum delay cap in milliseconds (default: 30000) */
64
+ maxDelayMs?: number;
65
+ /** Backoff multiplier (default: 2) */
66
+ multiplier?: number;
67
+ /** Enable jitter randomization (default: true) */
68
+ jitter?: boolean;
69
+ /** Maximum jitter percentage (0-1, default: 0.2 = ±20%) */
70
+ jitterFactor?: number;
71
+ /** Only retry on specific errors (default: all errors) */
72
+ retryableErrors?: ReadonlyArray<TransportError>;
73
+ }
74
+ /**
75
+ * Configuration for linear backoff retry strategy.
76
+ */
77
+ export interface LinearBackoffConfig {
78
+ /** Maximum number of retry attempts (default: 3) */
79
+ maxAttempts?: number;
80
+ /** Fixed delay increment in milliseconds (default: 1000) */
81
+ delayIncrementMs?: number;
82
+ /** Initial delay in milliseconds (default: 1000) */
83
+ initialDelayMs?: number;
84
+ /** Maximum delay cap in milliseconds (default: 30000) */
85
+ maxDelayMs?: number;
86
+ /** Enable jitter randomization (default: true) */
87
+ jitter?: boolean;
88
+ /** Maximum jitter percentage (0-1, default: 0.1 = ±10%) */
89
+ jitterFactor?: number;
90
+ /** Only retry on specific errors (default: all errors) */
91
+ retryableErrors?: ReadonlyArray<TransportError>;
92
+ }
93
+ /**
94
+ * Configuration for fixed delay retry strategy.
95
+ */
96
+ export interface FixedDelayConfig {
97
+ /** Maximum number of retry attempts (default: 3) */
98
+ maxAttempts?: number;
99
+ /** Fixed delay in milliseconds (default: 1000) */
100
+ delayMs?: number;
101
+ /** Enable jitter randomization (default: false) */
102
+ jitter?: boolean;
103
+ /** Maximum jitter percentage (0-1, default: 0.1 = ±10%) */
104
+ jitterFactor?: number;
105
+ /** Only retry on specific errors (default: all errors) */
106
+ retryableErrors?: ReadonlyArray<TransportError>;
107
+ }
108
+ /**
109
+ * Configuration for circuit breaker.
110
+ */
111
+ export interface CircuitBreakerConfig {
112
+ /** Number of consecutive failures before opening circuit (default: 5) */
113
+ failureThreshold?: number;
114
+ /** Time to wait before attempting to close circuit (ms, default: 60000) */
115
+ resetTimeoutMs?: number;
116
+ /** Number of successful requests needed to close circuit (default: 2) */
117
+ successThreshold?: number;
118
+ /** Time window for counting failures (ms, default: 60000) */
119
+ windowMs?: number;
120
+ }
121
+ /**
122
+ * Circuit breaker states.
123
+ */
124
+ export type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
125
+ /**
126
+ * Statistics for circuit breaker monitoring.
127
+ */
128
+ export interface CircuitBreakerStats {
129
+ /** Current circuit state */
130
+ readonly state: CircuitState;
131
+ /** Number of consecutive failures */
132
+ readonly consecutiveFailures: number;
133
+ /** Number of consecutive successes in HALF_OPEN state */
134
+ readonly consecutiveSuccesses: number;
135
+ /** Timestamp when circuit was opened (if open) */
136
+ readonly openedAt?: number;
137
+ /** Total requests attempted */
138
+ readonly totalRequests: number;
139
+ /** Total failures */
140
+ readonly totalFailures: number;
141
+ /** Total successes */
142
+ readonly totalSuccesses: number;
143
+ }
144
+ /**
145
+ * Core retry strategy interface.
146
+ *
147
+ * Implementations determine retry behavior based on context.
148
+ */
149
+ export interface IRetryStrategy {
150
+ /**
151
+ * Decide whether to retry the operation.
152
+ *
153
+ * @param context - Current retry context
154
+ * @returns Retry decision with delay
155
+ */
156
+ shouldRetry(context: RetryContext): RetryDecision;
157
+ /**
158
+ * Get strategy name for logging.
159
+ */
160
+ readonly name: string;
161
+ }
162
+ /**
163
+ * Exponential backoff retry strategy.
164
+ *
165
+ * Delay formula: min(initialDelay * multiplier^attempt, maxDelay) ± jitter
166
+ *
167
+ * Best for: Network requests, API calls, database operations.
168
+ * Avoids overwhelming failing services with exponentially increasing delays.
169
+ */
170
+ export declare class ExponentialBackoffStrategy implements IRetryStrategy {
171
+ readonly name = "ExponentialBackoff";
172
+ private readonly maxAttempts;
173
+ private readonly initialDelayMs;
174
+ private readonly maxDelayMs;
175
+ private readonly multiplier;
176
+ private readonly jitter;
177
+ private readonly jitterFactor;
178
+ private readonly retryableErrors;
179
+ constructor(config?: ExponentialBackoffConfig);
180
+ shouldRetry(context: RetryContext): RetryDecision;
181
+ private applyJitter;
182
+ }
183
+ /**
184
+ * Linear backoff retry strategy.
185
+ *
186
+ * Delay formula: min(initialDelay + attempt * increment, maxDelay) ± jitter
187
+ *
188
+ * Best for: Rate-limited APIs, gradual load recovery.
189
+ * More predictable than exponential, suitable when service recovery is linear.
190
+ */
191
+ export declare class LinearBackoffStrategy implements IRetryStrategy {
192
+ readonly name = "LinearBackoff";
193
+ private readonly maxAttempts;
194
+ private readonly delayIncrementMs;
195
+ private readonly initialDelayMs;
196
+ private readonly maxDelayMs;
197
+ private readonly jitter;
198
+ private readonly jitterFactor;
199
+ private readonly retryableErrors;
200
+ constructor(config?: LinearBackoffConfig);
201
+ shouldRetry(context: RetryContext): RetryDecision;
202
+ private applyJitter;
203
+ }
204
+ /**
205
+ * Fixed delay retry strategy.
206
+ *
207
+ * Delay formula: delayMs ± jitter (constant for all attempts)
208
+ *
209
+ * Best for: Simple retry scenarios, testing.
210
+ * Predictable timing, no backoff complexity.
211
+ */
212
+ export declare class FixedDelayStrategy implements IRetryStrategy {
213
+ readonly name = "FixedDelay";
214
+ private readonly maxAttempts;
215
+ private readonly delayMs;
216
+ private readonly jitter;
217
+ private readonly jitterFactor;
218
+ private readonly retryableErrors;
219
+ constructor(config?: FixedDelayConfig);
220
+ shouldRetry(context: RetryContext): RetryDecision;
221
+ private applyJitter;
222
+ }
223
+ /**
224
+ * No retry strategy (fail immediately).
225
+ *
226
+ * Best for: Operations that must succeed on first try, testing.
227
+ */
228
+ export declare class NoRetryStrategy implements IRetryStrategy {
229
+ readonly name = "NoRetry";
230
+ shouldRetry(_context: RetryContext): RetryDecision;
231
+ }
232
+ /**
233
+ * Circuit breaker for preventing cascading failures.
234
+ *
235
+ * States:
236
+ * - CLOSED: Normal operation, requests pass through
237
+ * - OPEN: Circuit tripped, requests fail immediately
238
+ * - HALF_OPEN: Testing recovery, limited requests allowed
239
+ *
240
+ * Best practices:
241
+ * - Use with retry strategies for comprehensive fault tolerance
242
+ * - Monitor circuit state changes for alerting
243
+ * - Tune thresholds based on service characteristics
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * const breaker = new CircuitBreaker({
248
+ * failureThreshold: 5,
249
+ * resetTimeoutMs: 60000,
250
+ * successThreshold: 2
251
+ * });
252
+ *
253
+ * // Check before operation
254
+ * if (breaker.allowRequest()) {
255
+ * const result = await operation();
256
+ * if (result.ok) {
257
+ * breaker.recordSuccess();
258
+ * } else {
259
+ * breaker.recordFailure();
260
+ * }
261
+ * }
262
+ * ```
263
+ */
264
+ export declare class CircuitBreaker {
265
+ private state;
266
+ private consecutiveFailures;
267
+ private consecutiveSuccesses;
268
+ private openedAt?;
269
+ private totalRequests;
270
+ private totalFailures;
271
+ private totalSuccesses;
272
+ private failureTimestamps;
273
+ private readonly failureThreshold;
274
+ private readonly resetTimeoutMs;
275
+ private readonly successThreshold;
276
+ private readonly windowMs;
277
+ constructor(config?: CircuitBreakerConfig);
278
+ /**
279
+ * Check if request should be allowed through circuit.
280
+ *
281
+ * @returns True if request should proceed, false if circuit is open
282
+ */
283
+ allowRequest(): boolean;
284
+ /**
285
+ * Record a successful operation.
286
+ */
287
+ recordSuccess(): void;
288
+ /**
289
+ * Record a failed operation.
290
+ */
291
+ recordFailure(): void;
292
+ /**
293
+ * Get current circuit breaker statistics.
294
+ */
295
+ getStats(): CircuitBreakerStats;
296
+ /**
297
+ * Reset circuit breaker to initial state.
298
+ */
299
+ reset(): void;
300
+ /**
301
+ * Force circuit to open (for testing or manual intervention).
302
+ */
303
+ forceOpen(): void;
304
+ /**
305
+ * Force circuit to close (for testing or manual recovery).
306
+ */
307
+ forceClose(): void;
308
+ }
309
+ /**
310
+ * Factory for creating retry strategies with common configurations.
311
+ */
312
+ export declare class RetryStrategy {
313
+ /**
314
+ * Create exponential backoff strategy.
315
+ *
316
+ * @param config - Configuration options
317
+ * @returns Exponential backoff strategy
318
+ */
319
+ static exponentialBackoff(config?: ExponentialBackoffConfig): IRetryStrategy;
320
+ /**
321
+ * Create linear backoff strategy.
322
+ *
323
+ * @param config - Configuration options
324
+ * @returns Linear backoff strategy
325
+ */
326
+ static linearBackoff(config?: LinearBackoffConfig): IRetryStrategy;
327
+ /**
328
+ * Create fixed delay strategy.
329
+ *
330
+ * @param config - Configuration options
331
+ * @returns Fixed delay strategy
332
+ */
333
+ static fixedDelay(config?: FixedDelayConfig): IRetryStrategy;
334
+ /**
335
+ * Create no retry strategy (fail immediately).
336
+ *
337
+ * @returns No retry strategy
338
+ */
339
+ static noRetry(): IRetryStrategy;
340
+ /**
341
+ * Create aggressive retry strategy for critical operations.
342
+ *
343
+ * Config: 5 attempts, 500ms initial, max 10s, exponential backoff.
344
+ *
345
+ * @returns Aggressive retry strategy
346
+ */
347
+ static aggressive(): IRetryStrategy;
348
+ /**
349
+ * Create conservative retry strategy for non-critical operations.
350
+ *
351
+ * Config: 2 attempts, 2s initial, max 5s, linear backoff.
352
+ *
353
+ * @returns Conservative retry strategy
354
+ */
355
+ static conservative(): IRetryStrategy;
356
+ /**
357
+ * Create default retry strategy (balanced).
358
+ *
359
+ * Config: 3 attempts, 1s initial, max 30s, exponential backoff.
360
+ *
361
+ * @returns Default retry strategy
362
+ */
363
+ static default(): IRetryStrategy;
364
+ }
365
+ /**
366
+ * Execute an operation with retry strategy and optional circuit breaker.
367
+ *
368
+ * @param operation - Async operation to execute
369
+ * @param strategy - Retry strategy to use
370
+ * @param circuitBreaker - Optional circuit breaker
371
+ * @returns Result of the operation
372
+ *
373
+ * @example
374
+ * ```typescript
375
+ * const result = await executeWithRetry(
376
+ * async () => transport.send(envelope, did),
377
+ * RetryStrategy.exponentialBackoff(),
378
+ * circuitBreaker
379
+ * );
380
+ * ```
381
+ */
382
+ export declare function executeWithRetry<T>(operation: () => Promise<Result<T, TransportError>>, strategy: IRetryStrategy, circuitBreaker?: CircuitBreaker): Promise<Result<T, TransportError>>;
@@ -0,0 +1 @@
1
+ import{err}from"./_deps/shared/index.js";export class ExponentialBackoffStrategy{name="ExponentialBackoff";maxAttempts;initialDelayMs;maxDelayMs;multiplier;jitter;jitterFactor;retryableErrors;constructor(t={}){this.maxAttempts=t.maxAttempts??3,this.initialDelayMs=t.initialDelayMs??1e3,this.maxDelayMs=t.maxDelayMs??3e4,this.multiplier=t.multiplier??2,this.jitter=t.jitter??!0,this.jitterFactor=t.jitterFactor??.2,this.retryableErrors=t.retryableErrors?new Set(t.retryableErrors):new Set(["SEND_FAILED","NETWORK_ERROR","RECIPIENT_UNREACHABLE","TIMEOUT"])}shouldRetry(t){if(t.attempt>=this.maxAttempts)return{shouldRetry:!1,reason:`Maximum attempts (${this.maxAttempts}) exceeded`};if(!this.retryableErrors.has(t.error))return{shouldRetry:!1,reason:`Error type '${t.error}' is not retryable`};const e=this.initialDelayMs*Math.pow(this.multiplier,t.attempt),s=Math.min(e,this.maxDelayMs),r=this.jitter?this.applyJitter(s):s;return{shouldRetry:!0,delayMs:Math.round(r),reason:`Attempt ${t.attempt+1}/${this.maxAttempts}`}}applyJitter(t){const e=new Uint32Array(1);crypto.getRandomValues(e);return t+(2*(e[0]/4294967295)-1)*(t*this.jitterFactor)}}export class LinearBackoffStrategy{name="LinearBackoff";maxAttempts;delayIncrementMs;initialDelayMs;maxDelayMs;jitter;jitterFactor;retryableErrors;constructor(t={}){this.maxAttempts=t.maxAttempts??3,this.delayIncrementMs=t.delayIncrementMs??1e3,this.initialDelayMs=t.initialDelayMs??1e3,this.maxDelayMs=t.maxDelayMs??3e4,this.jitter=t.jitter??!0,this.jitterFactor=t.jitterFactor??.1,this.retryableErrors=t.retryableErrors?new Set(t.retryableErrors):new Set(["SEND_FAILED","NETWORK_ERROR","RECIPIENT_UNREACHABLE","TIMEOUT"])}shouldRetry(t){if(t.attempt>=this.maxAttempts)return{shouldRetry:!1,reason:`Maximum attempts (${this.maxAttempts}) exceeded`};if(!this.retryableErrors.has(t.error))return{shouldRetry:!1,reason:`Error type '${t.error}' is not retryable`};const e=this.initialDelayMs+t.attempt*this.delayIncrementMs,s=Math.min(e,this.maxDelayMs),r=this.jitter?this.applyJitter(s):s;return{shouldRetry:!0,delayMs:Math.round(r),reason:`Attempt ${t.attempt+1}/${this.maxAttempts}`}}applyJitter(t){const e=new Uint32Array(1);crypto.getRandomValues(e);return t+(2*(e[0]/4294967295)-1)*(t*this.jitterFactor)}}export class FixedDelayStrategy{name="FixedDelay";maxAttempts;delayMs;jitter;jitterFactor;retryableErrors;constructor(t={}){this.maxAttempts=t.maxAttempts??3,this.delayMs=t.delayMs??1e3,this.jitter=t.jitter??!1,this.jitterFactor=t.jitterFactor??.1,this.retryableErrors=t.retryableErrors?new Set(t.retryableErrors):new Set(["SEND_FAILED","NETWORK_ERROR","RECIPIENT_UNREACHABLE","TIMEOUT"])}shouldRetry(t){if(t.attempt>=this.maxAttempts)return{shouldRetry:!1,reason:`Maximum attempts (${this.maxAttempts}) exceeded`};if(!this.retryableErrors.has(t.error))return{shouldRetry:!1,reason:`Error type '${t.error}' is not retryable`};const e=this.jitter?this.applyJitter(this.delayMs):this.delayMs;return{shouldRetry:!0,delayMs:Math.round(e),reason:`Attempt ${t.attempt+1}/${this.maxAttempts}`}}applyJitter(t){const e=new Uint32Array(1);crypto.getRandomValues(e);return t+(2*(e[0]/4294967295)-1)*(t*this.jitterFactor)}}export class NoRetryStrategy{name="NoRetry";shouldRetry(t){return{shouldRetry:!1,reason:"No retry policy - fail immediately"}}}export class CircuitBreaker{state="CLOSED";consecutiveFailures=0;consecutiveSuccesses=0;openedAt;totalRequests=0;totalFailures=0;totalSuccesses=0;failureTimestamps=[];failureThreshold;resetTimeoutMs;successThreshold;windowMs;constructor(t={}){this.failureThreshold=t.failureThreshold??5,this.resetTimeoutMs=t.resetTimeoutMs??6e4,this.successThreshold=t.successThreshold??2,this.windowMs=t.windowMs??6e4}allowRequest(){const t=Date.now();return this.failureTimestamps=this.failureTimestamps.filter(e=>t-e<this.windowMs),"CLOSED"===this.state||("OPEN"!==this.state||!!(this.openedAt&&t-this.openedAt>=this.resetTimeoutMs)&&(this.state="HALF_OPEN",this.consecutiveSuccesses=0,!0))}recordSuccess(){this.totalRequests++,this.totalSuccesses++,this.consecutiveFailures=0,"HALF_OPEN"===this.state&&(this.consecutiveSuccesses++,this.consecutiveSuccesses>=this.successThreshold&&(this.state="CLOSED",this.consecutiveSuccesses=0,this.openedAt=void 0))}recordFailure(){this.totalRequests++,this.totalFailures++,this.consecutiveFailures++,this.consecutiveSuccesses=0;const t=Date.now();if(this.failureTimestamps.push(t),"CLOSED"===this.state||"HALF_OPEN"===this.state){this.failureTimestamps.filter(e=>t-e<this.windowMs).length>=this.failureThreshold&&(this.state="OPEN",this.openedAt=t)}}getStats(){return{state:this.state,consecutiveFailures:this.consecutiveFailures,consecutiveSuccesses:this.consecutiveSuccesses,openedAt:this.openedAt,totalRequests:this.totalRequests,totalFailures:this.totalFailures,totalSuccesses:this.totalSuccesses}}reset(){this.state="CLOSED",this.consecutiveFailures=0,this.consecutiveSuccesses=0,this.openedAt=void 0,this.totalRequests=0,this.totalFailures=0,this.totalSuccesses=0,this.failureTimestamps=[]}forceOpen(){this.state="OPEN",this.openedAt=Date.now()}forceClose(){this.state="CLOSED",this.consecutiveFailures=0,this.consecutiveSuccesses=0,this.openedAt=void 0}}export class RetryStrategy{static exponentialBackoff(t){return new ExponentialBackoffStrategy(t)}static linearBackoff(t){return new LinearBackoffStrategy(t)}static fixedDelay(t){return new FixedDelayStrategy(t)}static noRetry(){return new NoRetryStrategy}static aggressive(){return new ExponentialBackoffStrategy({maxAttempts:5,initialDelayMs:500,maxDelayMs:1e4,multiplier:2,jitter:!0})}static conservative(){return new LinearBackoffStrategy({maxAttempts:2,initialDelayMs:2e3,delayIncrementMs:1e3,maxDelayMs:5e3,jitter:!0})}static default(){return new ExponentialBackoffStrategy({maxAttempts:3,initialDelayMs:1e3,maxDelayMs:3e4,multiplier:2,jitter:!0})}}export async function executeWithRetry(t,e,s){const r=Date.now();let i=0,a="NETWORK_ERROR";for(;;){if(s&&!s.allowRequest())return err("SEND_FAILED");const o=await t();if(o.ok)return s?.recordSuccess(),o;a=o.error,s?.recordFailure();const l={attempt:i,error:a,startTime:r,elapsedMs:Date.now()-r},n=e.shouldRetry(l);if(!n.shouldRetry)return err(a);n.delayMs&&n.delayMs>0&&await sleep(n.delayMs),i++}}function sleep(t){return new Promise(e=>setTimeout(e,t))}
@@ -1,98 +1 @@
1
- /* ── Implementation ── */
2
- /**
3
- * Decorator that adds exponential backoff retry logic to any transport adapter.
4
- *
5
- * Retry delays follow exponential backoff with jitter:
6
- * - Formula: 2^attempt * baseDelay + jitter
7
- * - Jitter: Math.random() * maxJitter * 2 - maxJitter
8
- * - Default delays: 1s, 2s, 4s (with ±200ms jitter)
9
- *
10
- * Use case: Push notification delivery failures requiring automatic retry.
11
- *
12
- * @example
13
- * ```typescript
14
- * const transport = new RetryTransportAdapter(baseTransport, {
15
- * maxRetries: 3,
16
- * baseDelayMs: 1000,
17
- * maxJitterMs: 200
18
- * });
19
- * ```
20
- */
21
- export class RetryTransportAdapter {
22
- inner;
23
- maxRetries;
24
- baseDelayMs;
25
- maxJitterMs;
26
- /**
27
- * Create a new RetryTransportAdapter wrapping an existing transport.
28
- *
29
- * @param inner - The transport adapter to wrap with retry logic
30
- * @param options - Retry configuration options
31
- */
32
- constructor(inner, options = {}) {
33
- this.inner = inner;
34
- this.maxRetries = options.maxRetries ?? 3;
35
- this.baseDelayMs = options.baseDelayMs ?? 1000;
36
- this.maxJitterMs = options.maxJitterMs ?? 200;
37
- }
38
- /**
39
- * Send an envelope with exponential backoff retry logic.
40
- *
41
- * Retries on all error types (SEND_FAILED, NETWORK_ERROR, RECIPIENT_UNREACHABLE, TIMEOUT).
42
- * Throws error after all retries are exhausted.
43
- *
44
- * @param envelope - The envelope to send
45
- * @param recipientDid - The recipient's DID
46
- * @returns Result with void on success, or TransportError on failure
47
- * @throws Error if all retry attempts are exhausted
48
- */
49
- async send(envelope, recipientDid) {
50
- let lastError;
51
- for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
52
- const result = await this.inner.send(envelope, recipientDid);
53
- // Success - return immediately
54
- if (result.ok) {
55
- return result;
56
- }
57
- // Store error for final throw
58
- lastError = result.error;
59
- // Don't delay after final attempt
60
- if (attempt < this.maxRetries) {
61
- // Exponential backoff: 2^attempt * baseDelay + jitter
62
- const delay = Math.pow(2, attempt) * this.baseDelayMs;
63
- // SAFETY: Using crypto.getRandomValues for OWASP-compliant secure random jitter
64
- const jitterArray = new Uint32Array(1);
65
- crypto.getRandomValues(jitterArray);
66
- const jitter = (jitterArray[0] / 0xffffffff) * this.maxJitterMs * 2 -
67
- this.maxJitterMs;
68
- await this.sleep(delay + jitter);
69
- }
70
- }
71
- // All retries exhausted - throw error with clear message
72
- throw new Error(`Failed after ${this.maxRetries} retries: ${lastError ?? 'unknown error'}`);
73
- }
74
- /**
75
- * Register a handler for incoming envelopes.
76
- * Delegates directly to the inner transport.
77
- *
78
- * @param handler - The envelope handler function
79
- */
80
- onReceive(handler) {
81
- this.inner.onReceive(handler);
82
- }
83
- /**
84
- * Shut down the transport.
85
- * Delegates directly to the inner transport.
86
- */
87
- dispose() {
88
- this.inner.dispose();
89
- }
90
- /**
91
- * Sleep for a specified duration.
92
- *
93
- * @param ms - Duration in milliseconds
94
- */
95
- sleep(ms) {
96
- return new Promise((resolve) => setTimeout(resolve, ms));
97
- }
98
- }
1
+ export class RetryTransportAdapter{inner;maxRetries;baseDelayMs;maxJitterMs;constructor(e,t={}){this.inner=e,this.maxRetries=t.maxRetries??3,this.baseDelayMs=t.baseDelayMs??1e3,this.maxJitterMs=t.maxJitterMs??200}async send(e,t){let s;for(let r=0;r<=this.maxRetries;r++){const i=await this.inner.send(e,t);if(i.ok)return i;if(s=i.error,r<this.maxRetries){const e=Math.pow(2,r)*this.baseDelayMs,t=new Uint32Array(1);crypto.getRandomValues(t);const s=t[0]/4294967295*this.maxJitterMs*2-this.maxJitterMs;await this.sleep(e+s)}}throw new Error(`Failed after ${this.maxRetries} retries: ${s??"unknown error"}`)}onReceive(e){this.inner.onReceive(e)}dispose(){this.inner.dispose()}sleep(e){return new Promise(t=>setTimeout(t,e))}}