@teneo-protocol/sdk 1.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 (281) hide show
  1. package/.dockerignore +14 -0
  2. package/.env.test.example +14 -0
  3. package/.eslintrc.json +26 -0
  4. package/.github/workflows/claude-code-review.yml +78 -0
  5. package/.github/workflows/claude-reviewer.yml +64 -0
  6. package/.github/workflows/publish-npm.yml +38 -0
  7. package/.github/workflows/push-to-main.yml +23 -0
  8. package/.node-version +1 -0
  9. package/.prettierrc +11 -0
  10. package/Dockerfile +25 -0
  11. package/LICENCE +661 -0
  12. package/README.md +709 -0
  13. package/dist/constants.d.ts +42 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +45 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/core/websocket-client.d.ts +261 -0
  18. package/dist/core/websocket-client.d.ts.map +1 -0
  19. package/dist/core/websocket-client.js +875 -0
  20. package/dist/core/websocket-client.js.map +1 -0
  21. package/dist/formatters/response-formatter.d.ts +354 -0
  22. package/dist/formatters/response-formatter.d.ts.map +1 -0
  23. package/dist/formatters/response-formatter.js +575 -0
  24. package/dist/formatters/response-formatter.js.map +1 -0
  25. package/dist/handlers/message-handler-registry.d.ts +155 -0
  26. package/dist/handlers/message-handler-registry.d.ts.map +1 -0
  27. package/dist/handlers/message-handler-registry.js +216 -0
  28. package/dist/handlers/message-handler-registry.js.map +1 -0
  29. package/dist/handlers/message-handlers/agent-selected-handler.d.ts +112 -0
  30. package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -0
  31. package/dist/handlers/message-handlers/agent-selected-handler.js +40 -0
  32. package/dist/handlers/message-handlers/agent-selected-handler.js.map +1 -0
  33. package/dist/handlers/message-handlers/agents-list-handler.d.ts +14 -0
  34. package/dist/handlers/message-handlers/agents-list-handler.d.ts.map +1 -0
  35. package/dist/handlers/message-handlers/agents-list-handler.js +25 -0
  36. package/dist/handlers/message-handlers/agents-list-handler.js.map +1 -0
  37. package/dist/handlers/message-handlers/auth-error-handler.d.ts +71 -0
  38. package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -0
  39. package/dist/handlers/message-handlers/auth-error-handler.js +30 -0
  40. package/dist/handlers/message-handlers/auth-error-handler.js.map +1 -0
  41. package/dist/handlers/message-handlers/auth-message-handler.d.ts +18 -0
  42. package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -0
  43. package/dist/handlers/message-handlers/auth-message-handler.js +60 -0
  44. package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -0
  45. package/dist/handlers/message-handlers/auth-required-handler.d.ts +76 -0
  46. package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -0
  47. package/dist/handlers/message-handlers/auth-required-handler.js +23 -0
  48. package/dist/handlers/message-handlers/auth-required-handler.js.map +1 -0
  49. package/dist/handlers/message-handlers/auth-success-handler.d.ts +18 -0
  50. package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -0
  51. package/dist/handlers/message-handlers/auth-success-handler.js +51 -0
  52. package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -0
  53. package/dist/handlers/message-handlers/base-handler.d.ts +55 -0
  54. package/dist/handlers/message-handlers/base-handler.d.ts.map +1 -0
  55. package/dist/handlers/message-handlers/base-handler.js +83 -0
  56. package/dist/handlers/message-handlers/base-handler.js.map +1 -0
  57. package/dist/handlers/message-handlers/challenge-handler.d.ts +73 -0
  58. package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -0
  59. package/dist/handlers/message-handlers/challenge-handler.js +47 -0
  60. package/dist/handlers/message-handlers/challenge-handler.js.map +1 -0
  61. package/dist/handlers/message-handlers/error-message-handler.d.ts +76 -0
  62. package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -0
  63. package/dist/handlers/message-handlers/error-message-handler.js +29 -0
  64. package/dist/handlers/message-handlers/error-message-handler.js.map +1 -0
  65. package/dist/handlers/message-handlers/index.d.ts +28 -0
  66. package/dist/handlers/message-handlers/index.d.ts.map +1 -0
  67. package/dist/handlers/message-handlers/index.js +100 -0
  68. package/dist/handlers/message-handlers/index.js.map +1 -0
  69. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +122 -0
  70. package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -0
  71. package/dist/handlers/message-handlers/list-rooms-response-handler.js +30 -0
  72. package/dist/handlers/message-handlers/list-rooms-response-handler.js.map +1 -0
  73. package/dist/handlers/message-handlers/ping-pong-handler.d.ts +104 -0
  74. package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -0
  75. package/dist/handlers/message-handlers/ping-pong-handler.js +36 -0
  76. package/dist/handlers/message-handlers/ping-pong-handler.js.map +1 -0
  77. package/dist/handlers/message-handlers/regular-message-handler.d.ts +56 -0
  78. package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -0
  79. package/dist/handlers/message-handlers/regular-message-handler.js +59 -0
  80. package/dist/handlers/message-handlers/regular-message-handler.js.map +1 -0
  81. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +81 -0
  82. package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -0
  83. package/dist/handlers/message-handlers/subscribe-response-handler.js +48 -0
  84. package/dist/handlers/message-handlers/subscribe-response-handler.js.map +1 -0
  85. package/dist/handlers/message-handlers/task-response-handler.d.ts +14 -0
  86. package/dist/handlers/message-handlers/task-response-handler.d.ts.map +1 -0
  87. package/dist/handlers/message-handlers/task-response-handler.js +44 -0
  88. package/dist/handlers/message-handlers/task-response-handler.js.map +1 -0
  89. package/dist/handlers/message-handlers/types.d.ts +51 -0
  90. package/dist/handlers/message-handlers/types.d.ts.map +1 -0
  91. package/dist/handlers/message-handlers/types.js +7 -0
  92. package/dist/handlers/message-handlers/types.js.map +1 -0
  93. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +81 -0
  94. package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -0
  95. package/dist/handlers/message-handlers/unsubscribe-response-handler.js +48 -0
  96. package/dist/handlers/message-handlers/unsubscribe-response-handler.js.map +1 -0
  97. package/dist/handlers/webhook-handler.d.ts +202 -0
  98. package/dist/handlers/webhook-handler.d.ts.map +1 -0
  99. package/dist/handlers/webhook-handler.js +511 -0
  100. package/dist/handlers/webhook-handler.js.map +1 -0
  101. package/dist/index.d.ts +71 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +217 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/managers/agent-registry.d.ts +173 -0
  106. package/dist/managers/agent-registry.d.ts.map +1 -0
  107. package/dist/managers/agent-registry.js +310 -0
  108. package/dist/managers/agent-registry.js.map +1 -0
  109. package/dist/managers/connection-manager.d.ts +134 -0
  110. package/dist/managers/connection-manager.d.ts.map +1 -0
  111. package/dist/managers/connection-manager.js +176 -0
  112. package/dist/managers/connection-manager.js.map +1 -0
  113. package/dist/managers/index.d.ts +9 -0
  114. package/dist/managers/index.d.ts.map +1 -0
  115. package/dist/managers/index.js +16 -0
  116. package/dist/managers/index.js.map +1 -0
  117. package/dist/managers/message-router.d.ts +112 -0
  118. package/dist/managers/message-router.d.ts.map +1 -0
  119. package/dist/managers/message-router.js +260 -0
  120. package/dist/managers/message-router.js.map +1 -0
  121. package/dist/managers/room-manager.d.ts +165 -0
  122. package/dist/managers/room-manager.d.ts.map +1 -0
  123. package/dist/managers/room-manager.js +227 -0
  124. package/dist/managers/room-manager.js.map +1 -0
  125. package/dist/teneo-sdk.d.ts +703 -0
  126. package/dist/teneo-sdk.d.ts.map +1 -0
  127. package/dist/teneo-sdk.js +907 -0
  128. package/dist/teneo-sdk.js.map +1 -0
  129. package/dist/types/config.d.ts +1047 -0
  130. package/dist/types/config.d.ts.map +1 -0
  131. package/dist/types/config.js +720 -0
  132. package/dist/types/config.js.map +1 -0
  133. package/dist/types/error-codes.d.ts +29 -0
  134. package/dist/types/error-codes.d.ts.map +1 -0
  135. package/dist/types/error-codes.js +41 -0
  136. package/dist/types/error-codes.js.map +1 -0
  137. package/dist/types/events.d.ts +616 -0
  138. package/dist/types/events.d.ts.map +1 -0
  139. package/dist/types/events.js +261 -0
  140. package/dist/types/events.js.map +1 -0
  141. package/dist/types/health.d.ts +40 -0
  142. package/dist/types/health.d.ts.map +1 -0
  143. package/dist/types/health.js +6 -0
  144. package/dist/types/health.js.map +1 -0
  145. package/dist/types/index.d.ts +10 -0
  146. package/dist/types/index.d.ts.map +1 -0
  147. package/dist/types/index.js +123 -0
  148. package/dist/types/index.js.map +1 -0
  149. package/dist/types/messages.d.ts +3734 -0
  150. package/dist/types/messages.d.ts.map +1 -0
  151. package/dist/types/messages.js +482 -0
  152. package/dist/types/messages.js.map +1 -0
  153. package/dist/types/validation.d.ts +81 -0
  154. package/dist/types/validation.d.ts.map +1 -0
  155. package/dist/types/validation.js +115 -0
  156. package/dist/types/validation.js.map +1 -0
  157. package/dist/utils/bounded-queue.d.ts +127 -0
  158. package/dist/utils/bounded-queue.d.ts.map +1 -0
  159. package/dist/utils/bounded-queue.js +181 -0
  160. package/dist/utils/bounded-queue.js.map +1 -0
  161. package/dist/utils/circuit-breaker.d.ts +141 -0
  162. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  163. package/dist/utils/circuit-breaker.js +215 -0
  164. package/dist/utils/circuit-breaker.js.map +1 -0
  165. package/dist/utils/deduplication-cache.d.ts +110 -0
  166. package/dist/utils/deduplication-cache.d.ts.map +1 -0
  167. package/dist/utils/deduplication-cache.js +177 -0
  168. package/dist/utils/deduplication-cache.js.map +1 -0
  169. package/dist/utils/event-waiter.d.ts +101 -0
  170. package/dist/utils/event-waiter.d.ts.map +1 -0
  171. package/dist/utils/event-waiter.js +118 -0
  172. package/dist/utils/event-waiter.js.map +1 -0
  173. package/dist/utils/index.d.ts +51 -0
  174. package/dist/utils/index.d.ts.map +1 -0
  175. package/dist/utils/index.js +72 -0
  176. package/dist/utils/index.js.map +1 -0
  177. package/dist/utils/logger.d.ts +22 -0
  178. package/dist/utils/logger.d.ts.map +1 -0
  179. package/dist/utils/logger.js +91 -0
  180. package/dist/utils/logger.js.map +1 -0
  181. package/dist/utils/rate-limiter.d.ts +122 -0
  182. package/dist/utils/rate-limiter.d.ts.map +1 -0
  183. package/dist/utils/rate-limiter.js +190 -0
  184. package/dist/utils/rate-limiter.js.map +1 -0
  185. package/dist/utils/retry-policy.d.ts +191 -0
  186. package/dist/utils/retry-policy.d.ts.map +1 -0
  187. package/dist/utils/retry-policy.js +225 -0
  188. package/dist/utils/retry-policy.js.map +1 -0
  189. package/dist/utils/secure-private-key.d.ts +113 -0
  190. package/dist/utils/secure-private-key.d.ts.map +1 -0
  191. package/dist/utils/secure-private-key.js +188 -0
  192. package/dist/utils/secure-private-key.js.map +1 -0
  193. package/dist/utils/signature-verifier.d.ts +143 -0
  194. package/dist/utils/signature-verifier.d.ts.map +1 -0
  195. package/dist/utils/signature-verifier.js +238 -0
  196. package/dist/utils/signature-verifier.js.map +1 -0
  197. package/dist/utils/ssrf-validator.d.ts +36 -0
  198. package/dist/utils/ssrf-validator.d.ts.map +1 -0
  199. package/dist/utils/ssrf-validator.js +195 -0
  200. package/dist/utils/ssrf-validator.js.map +1 -0
  201. package/examples/.env.example +17 -0
  202. package/examples/basic-usage.ts +211 -0
  203. package/examples/production-dashboard/.env.example +153 -0
  204. package/examples/production-dashboard/package.json +39 -0
  205. package/examples/production-dashboard/public/dashboard.html +642 -0
  206. package/examples/production-dashboard/server.ts +753 -0
  207. package/examples/webhook-integration.ts +239 -0
  208. package/examples/x-influencer-battle-redesign.html +1065 -0
  209. package/examples/x-influencer-battle-server.ts +217 -0
  210. package/examples/x-influencer-battle.html +787 -0
  211. package/package.json +65 -0
  212. package/src/constants.ts +43 -0
  213. package/src/core/websocket-client.test.ts +512 -0
  214. package/src/core/websocket-client.ts +1056 -0
  215. package/src/formatters/response-formatter.test.ts +571 -0
  216. package/src/formatters/response-formatter.ts +677 -0
  217. package/src/handlers/message-handler-registry.ts +239 -0
  218. package/src/handlers/message-handlers/agent-selected-handler.ts +40 -0
  219. package/src/handlers/message-handlers/agents-list-handler.ts +26 -0
  220. package/src/handlers/message-handlers/auth-error-handler.ts +31 -0
  221. package/src/handlers/message-handlers/auth-message-handler.ts +66 -0
  222. package/src/handlers/message-handlers/auth-required-handler.ts +23 -0
  223. package/src/handlers/message-handlers/auth-success-handler.ts +57 -0
  224. package/src/handlers/message-handlers/base-handler.ts +101 -0
  225. package/src/handlers/message-handlers/challenge-handler.ts +57 -0
  226. package/src/handlers/message-handlers/error-message-handler.ts +27 -0
  227. package/src/handlers/message-handlers/index.ts +77 -0
  228. package/src/handlers/message-handlers/list-rooms-response-handler.ts +28 -0
  229. package/src/handlers/message-handlers/ping-pong-handler.ts +30 -0
  230. package/src/handlers/message-handlers/regular-message-handler.ts +65 -0
  231. package/src/handlers/message-handlers/subscribe-response-handler.ts +47 -0
  232. package/src/handlers/message-handlers/task-response-handler.ts +45 -0
  233. package/src/handlers/message-handlers/types.ts +77 -0
  234. package/src/handlers/message-handlers/unsubscribe-response-handler.ts +47 -0
  235. package/src/handlers/webhook-handler.test.ts +789 -0
  236. package/src/handlers/webhook-handler.ts +576 -0
  237. package/src/index.ts +269 -0
  238. package/src/managers/agent-registry.test.ts +466 -0
  239. package/src/managers/agent-registry.ts +347 -0
  240. package/src/managers/connection-manager.ts +195 -0
  241. package/src/managers/index.ts +9 -0
  242. package/src/managers/message-router.ts +349 -0
  243. package/src/managers/room-manager.ts +248 -0
  244. package/src/teneo-sdk.ts +1022 -0
  245. package/src/types/config.test.ts +325 -0
  246. package/src/types/config.ts +799 -0
  247. package/src/types/error-codes.ts +44 -0
  248. package/src/types/events.test.ts +302 -0
  249. package/src/types/events.ts +382 -0
  250. package/src/types/health.ts +46 -0
  251. package/src/types/index.ts +199 -0
  252. package/src/types/messages.test.ts +660 -0
  253. package/src/types/messages.ts +570 -0
  254. package/src/types/validation.ts +123 -0
  255. package/src/utils/bounded-queue.test.ts +356 -0
  256. package/src/utils/bounded-queue.ts +205 -0
  257. package/src/utils/circuit-breaker.test.ts +394 -0
  258. package/src/utils/circuit-breaker.ts +262 -0
  259. package/src/utils/deduplication-cache.test.ts +380 -0
  260. package/src/utils/deduplication-cache.ts +198 -0
  261. package/src/utils/event-waiter.test.ts +381 -0
  262. package/src/utils/event-waiter.ts +172 -0
  263. package/src/utils/index.ts +74 -0
  264. package/src/utils/logger.ts +87 -0
  265. package/src/utils/rate-limiter.test.ts +341 -0
  266. package/src/utils/rate-limiter.ts +211 -0
  267. package/src/utils/retry-policy.test.ts +558 -0
  268. package/src/utils/retry-policy.ts +272 -0
  269. package/src/utils/secure-private-key.test.ts +356 -0
  270. package/src/utils/secure-private-key.ts +205 -0
  271. package/src/utils/signature-verifier.test.ts +464 -0
  272. package/src/utils/signature-verifier.ts +298 -0
  273. package/src/utils/ssrf-validator.test.ts +372 -0
  274. package/src/utils/ssrf-validator.ts +224 -0
  275. package/tests/integration/real-server.test.ts +740 -0
  276. package/tests/integration/websocket.test.ts +381 -0
  277. package/tests/integration-setup.ts +16 -0
  278. package/tests/setup.ts +34 -0
  279. package/tsconfig.json +32 -0
  280. package/vitest.config.ts +42 -0
  281. package/vitest.integration.config.ts +23 -0
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ /**
3
+ * Circuit Breaker Pattern Implementation
4
+ * Provides fault tolerance by preventing cascading failures
5
+ *
6
+ * States:
7
+ * - CLOSED: Normal operation, requests pass through
8
+ * - OPEN: Failure threshold exceeded, requests fail fast
9
+ * - HALF_OPEN: Testing if service recovered, limited requests allowed
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CircuitBreaker = exports.CircuitBreakerError = void 0;
13
+ /**
14
+ * Error thrown when circuit is open
15
+ */
16
+ class CircuitBreakerError extends Error {
17
+ constructor(message, state) {
18
+ super(message);
19
+ this.state = state;
20
+ this.name = "CircuitBreakerError";
21
+ if (Error.captureStackTrace) {
22
+ Error.captureStackTrace(this, CircuitBreakerError);
23
+ }
24
+ }
25
+ }
26
+ exports.CircuitBreakerError = CircuitBreakerError;
27
+ /**
28
+ * Circuit breaker for fault tolerance
29
+ * Prevents cascading failures by failing fast when errors are detected
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const breaker = new CircuitBreaker({
34
+ * failureThreshold: 5,
35
+ * timeout: 60000
36
+ * });
37
+ *
38
+ * try {
39
+ * await breaker.execute(async () => {
40
+ * return await fetch('https://api.example.com/data');
41
+ * });
42
+ * } catch (error) {
43
+ * if (error instanceof CircuitBreakerError) {
44
+ * console.log('Circuit is open, failing fast');
45
+ * }
46
+ * }
47
+ * ```
48
+ */
49
+ class CircuitBreaker {
50
+ /**
51
+ * Creates a new circuit breaker
52
+ *
53
+ * @param options - Configuration options
54
+ * @throws {Error} If thresholds are less than 1
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const breaker = new CircuitBreaker({
59
+ * failureThreshold: 5, // Open after 5 failures
60
+ * successThreshold: 2, // Close after 2 successes
61
+ * timeout: 60000, // Wait 60s before trying again
62
+ * windowSize: 60000 // Track failures in 60s window
63
+ * });
64
+ * ```
65
+ */
66
+ constructor(options = {}) {
67
+ this.state = "CLOSED";
68
+ this.failureCount = 0;
69
+ this.successCount = 0;
70
+ this.failures = []; // Timestamps of failures
71
+ this.failureThreshold = options.failureThreshold ?? 5;
72
+ this.successThreshold = options.successThreshold ?? 2;
73
+ this.timeout = options.timeout ?? 60000;
74
+ this.windowSize = options.windowSize ?? 60000;
75
+ if (this.failureThreshold < 1) {
76
+ throw new Error("CircuitBreaker failureThreshold must be at least 1");
77
+ }
78
+ if (this.successThreshold < 1) {
79
+ throw new Error("CircuitBreaker successThreshold must be at least 1");
80
+ }
81
+ }
82
+ /**
83
+ * Execute an operation through the circuit breaker
84
+ *
85
+ * @template T - Return type of the operation
86
+ * @param operation - Async operation to execute
87
+ * @returns Promise resolving to operation result
88
+ * @throws {CircuitBreakerError} If circuit is open
89
+ * @throws Operation error if operation fails
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const result = await breaker.execute(async () => {
94
+ * const response = await fetch(url);
95
+ * return await response.json();
96
+ * });
97
+ * ```
98
+ */
99
+ async execute(operation) {
100
+ // Check if we should try to close the circuit
101
+ this.tryTransitionToHalfOpen();
102
+ // If circuit is open, fail fast
103
+ if (this.state === "OPEN") {
104
+ throw new CircuitBreakerError("Circuit breaker is OPEN", this.state);
105
+ }
106
+ try {
107
+ const result = await operation();
108
+ this.onSuccess();
109
+ return result;
110
+ }
111
+ catch (error) {
112
+ this.onFailure();
113
+ throw error;
114
+ }
115
+ }
116
+ /**
117
+ * Get current circuit breaker state and metrics
118
+ *
119
+ * @returns State object with status and counters
120
+ */
121
+ getState() {
122
+ return {
123
+ state: this.state,
124
+ failureCount: this.failureCount,
125
+ successCount: this.successCount,
126
+ lastFailureTime: this.lastFailureTime,
127
+ nextAttemptTime: this.nextAttemptTime
128
+ };
129
+ }
130
+ /**
131
+ * Get circuit breaker configuration
132
+ */
133
+ getConfig() {
134
+ return {
135
+ failureThreshold: this.failureThreshold,
136
+ successThreshold: this.successThreshold,
137
+ timeout: this.timeout,
138
+ windowSize: this.windowSize
139
+ };
140
+ }
141
+ /**
142
+ * Manually reset the circuit breaker to CLOSED state
143
+ * Useful for recovery scenarios or testing
144
+ */
145
+ reset() {
146
+ this.state = "CLOSED";
147
+ this.failureCount = 0;
148
+ this.successCount = 0;
149
+ this.lastFailureTime = undefined;
150
+ this.nextAttemptTime = undefined;
151
+ this.failures.length = 0;
152
+ }
153
+ /**
154
+ * Try to transition from OPEN to HALF_OPEN if timeout has passed
155
+ */
156
+ tryTransitionToHalfOpen() {
157
+ if (this.state === "OPEN" && this.nextAttemptTime) {
158
+ if (Date.now() >= this.nextAttemptTime) {
159
+ this.state = "HALF_OPEN";
160
+ this.successCount = 0;
161
+ }
162
+ }
163
+ }
164
+ /**
165
+ * Handle successful operation
166
+ */
167
+ onSuccess() {
168
+ if (this.state === "HALF_OPEN") {
169
+ this.successCount++;
170
+ if (this.successCount >= this.successThreshold) {
171
+ // Close the circuit - service has recovered
172
+ this.state = "CLOSED";
173
+ this.failureCount = 0;
174
+ this.successCount = 0;
175
+ this.failures.length = 0;
176
+ this.lastFailureTime = undefined;
177
+ this.nextAttemptTime = undefined;
178
+ }
179
+ }
180
+ else if (this.state === "CLOSED") {
181
+ // Reset failure count on success in CLOSED state
182
+ this.failureCount = Math.max(0, this.failureCount - 1);
183
+ }
184
+ }
185
+ /**
186
+ * Handle failed operation
187
+ */
188
+ onFailure() {
189
+ const now = Date.now();
190
+ this.lastFailureTime = now;
191
+ if (this.state === "HALF_OPEN") {
192
+ // Failed while testing - reopen circuit
193
+ this.state = "OPEN";
194
+ this.nextAttemptTime = now + this.timeout;
195
+ this.successCount = 0;
196
+ return;
197
+ }
198
+ // Track failure with timestamp
199
+ this.failures.push(now);
200
+ // Remove failures outside the window
201
+ const windowStart = now - this.windowSize;
202
+ while (this.failures.length > 0 && this.failures[0] < windowStart) {
203
+ this.failures.shift();
204
+ }
205
+ // Count failures in current window
206
+ this.failureCount = this.failures.length;
207
+ // Open circuit if threshold exceeded
208
+ if (this.failureCount >= this.failureThreshold) {
209
+ this.state = "OPEN";
210
+ this.nextAttemptTime = now + this.timeout;
211
+ }
212
+ }
213
+ }
214
+ exports.CircuitBreaker = CircuitBreaker;
215
+ //# sourceMappingURL=circuit-breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/utils/circuit-breaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Deduplication Cache with TTL
3
+ * Prevents duplicate processing of messages/events
4
+ *
5
+ * Uses time-to-live (TTL) for automatic cleanup of old entries
6
+ * without requiring external cleanup timers.
7
+ */
8
+ /**
9
+ * TTL-based cache for detecting duplicates
10
+ * Automatically expires entries after configured TTL
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const cache = new DeduplicationCache(60000); // 60 second TTL
15
+ *
16
+ * // Check and add in one operation
17
+ * if (!cache.has('message-123')) {
18
+ * cache.add('message-123');
19
+ * // Process message
20
+ * } else {
21
+ * // Duplicate - skip processing
22
+ * }
23
+ * ```
24
+ */
25
+ export declare class DeduplicationCache {
26
+ private readonly ttl;
27
+ private readonly maxSize;
28
+ private cache;
29
+ /**
30
+ * Creates a new deduplication cache
31
+ *
32
+ * @param ttl - Time-to-live in milliseconds (default: 300000 / 5 minutes)
33
+ * @param maxSize - Maximum cache size before cleanup (default: 10000)
34
+ * @throws {Error} If TTL is less than 1000ms or maxSize is less than 1
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * // 5 minute TTL, max 10k entries
39
+ * const cache = new DeduplicationCache(300000, 10000);
40
+ * ```
41
+ */
42
+ constructor(ttl?: number, maxSize?: number);
43
+ /**
44
+ * Check if a key exists and hasn't expired
45
+ *
46
+ * @param key - Key to check
47
+ * @returns true if key exists and is not expired, false otherwise
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * if (cache.has('message-id')) {
52
+ * console.log('Duplicate message detected');
53
+ * }
54
+ * ```
55
+ */
56
+ has(key: string): boolean;
57
+ /**
58
+ * Add a key to the cache with current timestamp
59
+ *
60
+ * @param key - Key to add
61
+ * @returns true if added, false if already exists
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * if (cache.add('message-id')) {
66
+ * // Process message
67
+ * } else {
68
+ * // Already processed
69
+ * }
70
+ * ```
71
+ */
72
+ add(key: string): boolean;
73
+ /**
74
+ * Remove a specific key from the cache
75
+ *
76
+ * @param key - Key to remove
77
+ * @returns true if key was removed, false if didn't exist
78
+ */
79
+ delete(key: string): boolean;
80
+ /**
81
+ * Clear all entries from the cache
82
+ */
83
+ clear(): void;
84
+ /**
85
+ * Get current cache size
86
+ *
87
+ * @returns Number of entries in cache
88
+ */
89
+ size(): number;
90
+ /**
91
+ * Get cache configuration
92
+ */
93
+ getConfig(): {
94
+ ttl: number;
95
+ maxSize: number;
96
+ };
97
+ /**
98
+ * Clean up expired entries if cache is getting large
99
+ * Called automatically by has() and add()
100
+ */
101
+ private cleanupIfNeeded;
102
+ /**
103
+ * Force cleanup of all expired entries
104
+ * Usually not needed as cleanup is automatic
105
+ *
106
+ * @returns Number of entries removed
107
+ */
108
+ cleanup(): number;
109
+ }
110
+ //# sourceMappingURL=deduplication-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deduplication-cache.d.ts","sourceRoot":"","sources":["../../src/utils/deduplication-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,kBAAkB;IAiB3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAjB1B,OAAO,CAAC,KAAK,CAAiC;IAE9C;;;;;;;;;;;;OAYG;gBAEgB,GAAG,GAAE,MAAe,EACpB,OAAO,GAAE,MAAc;IAU1C;;;;;;;;;;;;OAYG;IACI,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAiBhC;;;;;;;;;;;;;;OAcG;IACI,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAahC;;;;;OAKG;IACI,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACI,KAAK,IAAI,IAAI;IAIpB;;;;OAIG;IACI,IAAI,IAAI,MAAM;IAIrB;;OAEG;IACI,SAAS,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAOpD;;;OAGG;IACH,OAAO,CAAC,eAAe;IAoBvB;;;;;OAKG;IACI,OAAO,IAAI,MAAM;CAgBzB"}
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ /**
3
+ * Deduplication Cache with TTL
4
+ * Prevents duplicate processing of messages/events
5
+ *
6
+ * Uses time-to-live (TTL) for automatic cleanup of old entries
7
+ * without requiring external cleanup timers.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.DeduplicationCache = void 0;
11
+ /**
12
+ * TTL-based cache for detecting duplicates
13
+ * Automatically expires entries after configured TTL
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const cache = new DeduplicationCache(60000); // 60 second TTL
18
+ *
19
+ * // Check and add in one operation
20
+ * if (!cache.has('message-123')) {
21
+ * cache.add('message-123');
22
+ * // Process message
23
+ * } else {
24
+ * // Duplicate - skip processing
25
+ * }
26
+ * ```
27
+ */
28
+ class DeduplicationCache {
29
+ /**
30
+ * Creates a new deduplication cache
31
+ *
32
+ * @param ttl - Time-to-live in milliseconds (default: 300000 / 5 minutes)
33
+ * @param maxSize - Maximum cache size before cleanup (default: 10000)
34
+ * @throws {Error} If TTL is less than 1000ms or maxSize is less than 1
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * // 5 minute TTL, max 10k entries
39
+ * const cache = new DeduplicationCache(300000, 10000);
40
+ * ```
41
+ */
42
+ constructor(ttl = 300000, maxSize = 10000) {
43
+ this.ttl = ttl;
44
+ this.maxSize = maxSize;
45
+ this.cache = new Map();
46
+ if (ttl < 1000) {
47
+ throw new Error("DeduplicationCache TTL must be at least 1000ms");
48
+ }
49
+ if (maxSize < 1) {
50
+ throw new Error("DeduplicationCache maxSize must be at least 1");
51
+ }
52
+ }
53
+ /**
54
+ * Check if a key exists and hasn't expired
55
+ *
56
+ * @param key - Key to check
57
+ * @returns true if key exists and is not expired, false otherwise
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * if (cache.has('message-id')) {
62
+ * console.log('Duplicate message detected');
63
+ * }
64
+ * ```
65
+ */
66
+ has(key) {
67
+ this.cleanupIfNeeded();
68
+ const entry = this.cache.get(key);
69
+ if (!entry) {
70
+ return false;
71
+ }
72
+ // Check if expired
73
+ if (Date.now() - entry.timestamp > this.ttl) {
74
+ this.cache.delete(key);
75
+ return false;
76
+ }
77
+ return true;
78
+ }
79
+ /**
80
+ * Add a key to the cache with current timestamp
81
+ *
82
+ * @param key - Key to add
83
+ * @returns true if added, false if already exists
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * if (cache.add('message-id')) {
88
+ * // Process message
89
+ * } else {
90
+ * // Already processed
91
+ * }
92
+ * ```
93
+ */
94
+ add(key) {
95
+ if (this.has(key)) {
96
+ return false;
97
+ }
98
+ this.cache.set(key, {
99
+ timestamp: Date.now()
100
+ });
101
+ this.cleanupIfNeeded();
102
+ return true;
103
+ }
104
+ /**
105
+ * Remove a specific key from the cache
106
+ *
107
+ * @param key - Key to remove
108
+ * @returns true if key was removed, false if didn't exist
109
+ */
110
+ delete(key) {
111
+ return this.cache.delete(key);
112
+ }
113
+ /**
114
+ * Clear all entries from the cache
115
+ */
116
+ clear() {
117
+ this.cache.clear();
118
+ }
119
+ /**
120
+ * Get current cache size
121
+ *
122
+ * @returns Number of entries in cache
123
+ */
124
+ size() {
125
+ return this.cache.size;
126
+ }
127
+ /**
128
+ * Get cache configuration
129
+ */
130
+ getConfig() {
131
+ return {
132
+ ttl: this.ttl,
133
+ maxSize: this.maxSize
134
+ };
135
+ }
136
+ /**
137
+ * Clean up expired entries if cache is getting large
138
+ * Called automatically by has() and add()
139
+ */
140
+ cleanupIfNeeded() {
141
+ // Only cleanup if approaching max size
142
+ if (this.cache.size < this.maxSize * 0.9) {
143
+ return;
144
+ }
145
+ const now = Date.now();
146
+ const keysToDelete = [];
147
+ for (const [key, entry] of this.cache.entries()) {
148
+ if (now - entry.timestamp > this.ttl) {
149
+ keysToDelete.push(key);
150
+ }
151
+ }
152
+ for (const key of keysToDelete) {
153
+ this.cache.delete(key);
154
+ }
155
+ }
156
+ /**
157
+ * Force cleanup of all expired entries
158
+ * Usually not needed as cleanup is automatic
159
+ *
160
+ * @returns Number of entries removed
161
+ */
162
+ cleanup() {
163
+ const now = Date.now();
164
+ const keysToDelete = [];
165
+ for (const [key, entry] of this.cache.entries()) {
166
+ if (now - entry.timestamp > this.ttl) {
167
+ keysToDelete.push(key);
168
+ }
169
+ }
170
+ for (const key of keysToDelete) {
171
+ this.cache.delete(key);
172
+ }
173
+ return keysToDelete.length;
174
+ }
175
+ }
176
+ exports.DeduplicationCache = DeduplicationCache;
177
+ //# sourceMappingURL=deduplication-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deduplication-cache.js","sourceRoot":"","sources":["../../src/utils/deduplication-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Event Waiter Utility
3
+ * Provides a clean Promise-based API for waiting for events with timeout and filtering
4
+ * Eliminates callback hell and ensures proper cleanup of listeners and timers
5
+ */
6
+ import { EventEmitter } from "eventemitter3";
7
+ /**
8
+ * Options for waiting for an event
9
+ */
10
+ export interface WaitForEventOptions<T> {
11
+ /**
12
+ * Timeout in milliseconds
13
+ */
14
+ timeout: number;
15
+ /**
16
+ * Optional filter function to match specific events
17
+ * If provided, only events that pass the filter will resolve the promise
18
+ *
19
+ * @param data - The event data
20
+ * @returns true if this is the event we're waiting for, false to keep waiting
21
+ */
22
+ filter?: (data: T) => boolean;
23
+ /**
24
+ * Optional custom timeout error message
25
+ * If not provided, a default message will be used
26
+ */
27
+ timeoutMessage?: string;
28
+ }
29
+ /**
30
+ * Wait for an event to be emitted with automatic timeout and cleanup
31
+ *
32
+ * This utility encapsulates the complex pattern of:
33
+ * - Setting up event listeners
34
+ * - Managing timeouts
35
+ * - Cleaning up listeners and timers in all code paths
36
+ * - Filtering events
37
+ *
38
+ * All cleanup is guaranteed to happen, preventing memory leaks.
39
+ *
40
+ * @param emitter - The EventEmitter to listen to
41
+ * @param eventName - The name of the event to wait for
42
+ * @param options - Configuration options
43
+ * @returns Promise that resolves with the event data or rejects on timeout
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * // Simple usage: wait for any 'data' event
48
+ * const data = await waitForEvent(emitter, 'data', { timeout: 5000 });
49
+ *
50
+ * // With filter: wait for specific event
51
+ * const response = await waitForEvent(wsClient, 'agent:response', {
52
+ * timeout: 30000,
53
+ * filter: (r) => r.taskId === myTaskId,
54
+ * timeoutMessage: 'Agent did not respond in time'
55
+ * });
56
+ * ```
57
+ */
58
+ export declare function waitForEvent<T = any>(emitter: EventEmitter, eventName: string, options: WaitForEventOptions<T>): Promise<T>;
59
+ /**
60
+ * Wait for multiple events simultaneously (race condition)
61
+ * Resolves with the first event that fires and matches its filter
62
+ *
63
+ * @param waiters - Array of event waiter configurations
64
+ * @returns Promise that resolves with the first matching event
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * // Wait for either success or error
69
+ * const result = await waitForAnyEvent([
70
+ * { emitter: client, eventName: 'auth:success', options: { timeout: 5000 } },
71
+ * { emitter: client, eventName: 'auth:error', options: { timeout: 5000 } }
72
+ * ]);
73
+ * ```
74
+ */
75
+ export declare function waitForAnyEvent<T = any>(waiters: Array<{
76
+ emitter: EventEmitter;
77
+ eventName: string;
78
+ options: WaitForEventOptions<T>;
79
+ }>): Promise<T>;
80
+ /**
81
+ * Wait for all events to fire (all must complete)
82
+ * Useful when you need multiple events to occur before proceeding
83
+ *
84
+ * @param waiters - Array of event waiter configurations
85
+ * @returns Promise that resolves with array of all event data
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * // Wait for both auth and connection
90
+ * const [authState, connState] = await waitForAllEvents([
91
+ * { emitter: client, eventName: 'auth:success', options: { timeout: 5000 } },
92
+ * { emitter: client, eventName: 'connection:open', options: { timeout: 5000 } }
93
+ * ]);
94
+ * ```
95
+ */
96
+ export declare function waitForAllEvents<T = any>(waiters: Array<{
97
+ emitter: EventEmitter;
98
+ eventName: string;
99
+ options: WaitForEventOptions<T>;
100
+ }>): Promise<T[]>;
101
+ //# sourceMappingURL=event-waiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-waiter.d.ts","sourceRoot":"","sources":["../../src/utils/event-waiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IAE9B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,YAAY,CAAC,CAAC,GAAG,GAAG,EACxC,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,CAAC,CAAC,CA6CZ;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,CAAC,GAAG,GAAG,EAC3C,OAAO,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC;CACjC,CAAC,GACD,OAAO,CAAC,CAAC,CAAC,CAMZ;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EAC5C,OAAO,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC;CACjC,CAAC,GACD,OAAO,CAAC,CAAC,EAAE,CAAC,CAMd"}