@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,720 @@
1
+ "use strict";
2
+ /**
3
+ * Configuration schemas for Teneo Protocol SDK using Zod
4
+ * Provides runtime validation and TypeScript type inference
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SDKConfigBuilder = exports.DEFAULT_CONFIG = exports.WebhookPayloadSchema = exports.WebhookConfigSchema = exports.AuthenticationStateSchema = exports.ConnectionStateSchema = exports.PartialSDKConfigSchema = exports.SDKConfigSchema = exports.WebhookEventTypeSchema = exports.ResponseFormatSchema = exports.LogLevelSchema = exports.LoggerSchema = void 0;
8
+ exports.validateConfig = validateConfig;
9
+ exports.safeParseConfig = safeParseConfig;
10
+ const zod_1 = require("zod");
11
+ const messages_1 = require("./messages");
12
+ const retry_policy_1 = require("../utils/retry-policy");
13
+ // Logger schema - using loose function validation
14
+ exports.LoggerSchema = zod_1.z.object({
15
+ debug: zod_1.z.function(),
16
+ info: zod_1.z.function(),
17
+ warn: zod_1.z.function(),
18
+ error: zod_1.z.function()
19
+ });
20
+ // Log level schema
21
+ exports.LogLevelSchema = zod_1.z.enum(["debug", "info", "warn", "error", "silent"]);
22
+ // Response format schema
23
+ exports.ResponseFormatSchema = zod_1.z.enum(["raw", "humanized", "both"]);
24
+ // Webhook event type schema
25
+ exports.WebhookEventTypeSchema = zod_1.z.enum([
26
+ "message",
27
+ "task",
28
+ "task_response",
29
+ "agent_selected",
30
+ "error",
31
+ "connection_state",
32
+ "auth_state"
33
+ ]);
34
+ // Custom Zod schema for SecurePrivateKey or string
35
+ const PrivateKeySchema = zod_1.z.union([
36
+ zod_1.z.string(),
37
+ zod_1.z.custom((val) => {
38
+ // Check if it's a SecurePrivateKey instance
39
+ return val && typeof val === 'object' && 'use' in val && 'destroy' in val && 'isDestroyed' in val;
40
+ }, { message: "Must be a string or SecurePrivateKey instance" })
41
+ ]);
42
+ // SDK Configuration schema
43
+ exports.SDKConfigSchema = zod_1.z.object({
44
+ // WebSocket configuration
45
+ wsUrl: zod_1.z
46
+ .string()
47
+ .url()
48
+ .refine((url) => url.startsWith("ws://") || url.startsWith("wss://"), {
49
+ message: "WebSocket URL must start with ws:// or wss://"
50
+ }),
51
+ // Authentication
52
+ privateKey: PrivateKeySchema.optional(),
53
+ walletAddress: zod_1.z.string().optional(),
54
+ // Client identification
55
+ clientType: messages_1.ClientTypeSchema.optional(),
56
+ clientName: zod_1.z.string().optional(),
57
+ // Room configuration
58
+ autoJoinRooms: zod_1.z.array(zod_1.z.string()).optional(),
59
+ // Webhook configuration
60
+ webhookUrl: zod_1.z.string().url().optional(),
61
+ webhookHeaders: zod_1.z.record(zod_1.z.string()).optional(),
62
+ webhookRetries: zod_1.z.number().min(0).max(10).optional(),
63
+ webhookTimeout: zod_1.z.number().min(1000).max(60000).optional(),
64
+ webhookRetryStrategy: retry_policy_1.RetryStrategySchema.optional(), // REL-3: Configurable retry strategy
65
+ // Connection settings
66
+ reconnect: zod_1.z.boolean().optional(),
67
+ reconnectDelay: zod_1.z.number().min(100).max(60000).optional(),
68
+ maxReconnectAttempts: zod_1.z.number().min(0).max(100).optional(),
69
+ connectionTimeout: zod_1.z.number().min(1000).max(120000).optional(),
70
+ reconnectStrategy: retry_policy_1.RetryStrategySchema.optional(), // REL-3: Configurable retry strategy
71
+ // Message settings
72
+ messageTimeout: zod_1.z.number().min(1000).max(300000).optional(),
73
+ maxMessageSize: zod_1.z.number().min(1024).max(10485760).optional(), // 1KB to 10MB
74
+ maxMessagesPerSecond: zod_1.z.number().min(1).max(1000).optional(), // Rate limiting
75
+ // Response formatting
76
+ responseFormat: exports.ResponseFormatSchema.optional(),
77
+ includeMetadata: zod_1.z.boolean().optional(),
78
+ // Logging
79
+ logLevel: exports.LogLevelSchema.optional(),
80
+ logger: exports.LoggerSchema.optional(),
81
+ // Performance
82
+ enableCache: zod_1.z.boolean().optional(),
83
+ cacheTimeout: zod_1.z.number().min(1000).max(3600000).optional(),
84
+ maxCacheSize: zod_1.z.number().min(1).max(10000).optional(),
85
+ // Security
86
+ validateSignatures: zod_1.z.boolean().optional(),
87
+ trustedAgentAddresses: zod_1.z.array(zod_1.z.string()).optional(),
88
+ requireSignaturesFor: zod_1.z.array(messages_1.MessageTypeSchema).optional(),
89
+ strictSignatureValidation: zod_1.z.boolean().optional(),
90
+ allowInsecureWebhooks: zod_1.z.boolean().optional(),
91
+ // Message deduplication (CB-4)
92
+ enableMessageDeduplication: zod_1.z.boolean().optional(),
93
+ messageDedupeTtl: zod_1.z.number().min(1000).max(3600000).optional(), // 1s to 1 hour
94
+ messageDedupMaxSize: zod_1.z.number().min(1).max(100000).optional()
95
+ });
96
+ // Partial config for constructor
97
+ exports.PartialSDKConfigSchema = exports.SDKConfigSchema.partial().refine((config) => config.wsUrl !== undefined, { message: "WebSocket URL is required" });
98
+ // Connection state schema
99
+ exports.ConnectionStateSchema = zod_1.z.object({
100
+ connected: zod_1.z.boolean(),
101
+ authenticated: zod_1.z.boolean(),
102
+ reconnecting: zod_1.z.boolean(),
103
+ reconnectAttempts: zod_1.z.number(),
104
+ lastError: zod_1.z.instanceof(Error).optional(),
105
+ lastConnectedAt: zod_1.z.date().optional(),
106
+ lastDisconnectedAt: zod_1.z.date().optional()
107
+ });
108
+ // Authentication state schema
109
+ exports.AuthenticationStateSchema = zod_1.z.object({
110
+ authenticated: zod_1.z.boolean(),
111
+ clientId: zod_1.z.string().optional(),
112
+ walletAddress: zod_1.z.string().optional(),
113
+ isWhitelisted: zod_1.z.boolean().optional(),
114
+ isAdmin: zod_1.z.boolean().optional(),
115
+ nftVerified: zod_1.z.boolean().optional(),
116
+ rooms: zod_1.z.array(zod_1.z.string()).optional(), // Room IDs for backward compatibility
117
+ roomObjects: zod_1.z.array(messages_1.RoomSchema).optional(), // Full room objects from auth
118
+ privateRoomId: zod_1.z.string().optional(),
119
+ challenge: zod_1.z.string().optional(),
120
+ challengeTimestamp: zod_1.z.number().optional()
121
+ });
122
+ // Webhook config schema
123
+ exports.WebhookConfigSchema = zod_1.z.object({
124
+ url: zod_1.z.string().url(),
125
+ headers: zod_1.z.record(zod_1.z.string()).optional(),
126
+ retries: zod_1.z.number().min(0).max(10).optional(),
127
+ timeout: zod_1.z.number().min(1000).max(60000).optional(),
128
+ events: zod_1.z.array(exports.WebhookEventTypeSchema).optional()
129
+ });
130
+ // Webhook payload schema
131
+ exports.WebhookPayloadSchema = zod_1.z.object({
132
+ event: exports.WebhookEventTypeSchema,
133
+ timestamp: zod_1.z.string(),
134
+ data: zod_1.z.any(),
135
+ metadata: zod_1.z
136
+ .object({
137
+ clientId: zod_1.z.string().optional(),
138
+ roomId: zod_1.z.string().optional(),
139
+ agentId: zod_1.z.string().optional(),
140
+ taskId: zod_1.z.string().optional()
141
+ })
142
+ .optional()
143
+ });
144
+ // Default configuration with validation
145
+ exports.DEFAULT_CONFIG = exports.SDKConfigSchema.partial().parse({
146
+ wsUrl: "ws://localhost:8080/ws",
147
+ clientType: "user",
148
+ reconnect: true,
149
+ reconnectDelay: 5000,
150
+ maxReconnectAttempts: 10,
151
+ connectionTimeout: 30000,
152
+ messageTimeout: 30000,
153
+ maxMessageSize: 2 * 1024 * 1024, // 2MB
154
+ maxMessagesPerSecond: 10, // Rate limit: 10 messages per second
155
+ responseFormat: "humanized",
156
+ includeMetadata: false,
157
+ logLevel: "info",
158
+ enableCache: true,
159
+ cacheTimeout: 300000, // 5 minutes
160
+ maxCacheSize: 100,
161
+ validateSignatures: false,
162
+ trustedAgentAddresses: [],
163
+ requireSignaturesFor: ["task_response", "agent_selected"],
164
+ strictSignatureValidation: false,
165
+ allowInsecureWebhooks: false,
166
+ webhookRetries: 3,
167
+ webhookTimeout: 10000,
168
+ enableMessageDeduplication: true, // Enable by default to prevent duplicates
169
+ messageDedupeTtl: 60000, // 60 seconds (1 minute)
170
+ messageDedupMaxSize: 10000 // 10k messages
171
+ });
172
+ // Configuration validation with custom refinements
173
+ function validateConfig(config) {
174
+ // First validate basic structure
175
+ const parsed = exports.SDKConfigSchema.parse(config);
176
+ // Additional custom validations
177
+ if (parsed.webhookUrl && !parsed.allowInsecureWebhooks) {
178
+ const url = new URL(parsed.webhookUrl);
179
+ if (url.protocol === "http:" && !["localhost", "127.0.0.1", "::1"].includes(url.hostname)) {
180
+ throw new Error("Webhook URL must use HTTPS for non-localhost endpoints");
181
+ }
182
+ }
183
+ return parsed;
184
+ }
185
+ // Safe parse configuration
186
+ function safeParseConfig(config) {
187
+ try {
188
+ const data = validateConfig(config);
189
+ return { success: true, data };
190
+ }
191
+ catch (error) {
192
+ if (error instanceof zod_1.z.ZodError) {
193
+ return { success: false, error };
194
+ }
195
+ return { success: false, error: error };
196
+ }
197
+ }
198
+ /**
199
+ * Fluent API builder for creating Teneo SDK configurations with validation.
200
+ * Provides a chainable interface for configuring the SDK with runtime validation
201
+ * at each step. Call `.build()` to create the final validated configuration.
202
+ *
203
+ * This is the recommended way to configure the SDK for complex setups, as it provides
204
+ * better IDE intellisense, method chaining, and validates each configuration option
205
+ * as you set it.
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * // Basic configuration
210
+ * const config = new SDKConfigBuilder()
211
+ * .withWebSocketUrl('wss://teneo.example.com')
212
+ * .withAuthentication('0x...')
213
+ * .build();
214
+ *
215
+ * const sdk = new TeneoSDK(config);
216
+ *
217
+ * // Full configuration with all options
218
+ * const config = new SDKConfigBuilder()
219
+ * .withWebSocketUrl('wss://teneo.example.com')
220
+ * .withAuthentication('0x...', '0xYourWalletAddress')
221
+ * .withAutoJoinRooms(['general', 'announcements'])
222
+ * .withWebhook('https://api.example.com/webhooks', {
223
+ * 'Authorization': 'Bearer token'
224
+ * })
225
+ * .withReconnection(true, 5000, 10)
226
+ * .withResponseFormat({ format: 'both', includeMetadata: true })
227
+ * .withLogging('debug')
228
+ * .withCache(true, 300000, 100)
229
+ * .build();
230
+ *
231
+ * const sdk = new TeneoSDK(config);
232
+ *
233
+ * // Using via TeneoSDK.builder() (recommended)
234
+ * const sdk = TeneoSDK.builder()
235
+ * .withWebSocketUrl('wss://teneo.example.com')
236
+ * .withAuthentication('0x...')
237
+ * .withAutoJoinRooms(['general'])
238
+ * .build();
239
+ * ```
240
+ *
241
+ * @see {@link TeneoSDK} for the main SDK class
242
+ * @see {@link TeneoSDK.builder} for creating a builder instance
243
+ */
244
+ class SDKConfigBuilder {
245
+ constructor() {
246
+ this.config = { ...exports.DEFAULT_CONFIG };
247
+ }
248
+ /**
249
+ * Sets the WebSocket URL for connecting to the Teneo network.
250
+ * URL must start with 'ws://' or 'wss://'. HTTPS (wss://) is recommended for production.
251
+ *
252
+ * @param url - WebSocket URL (e.g., 'wss://teneo.example.com')
253
+ * @returns this builder for method chaining
254
+ * @throws {z.ZodError} If URL is invalid or doesn't start with ws:// or wss://
255
+ *
256
+ * @example
257
+ * ```typescript
258
+ * builder.withWebSocketUrl('wss://teneo.example.com')
259
+ * ```
260
+ */
261
+ withWebSocketUrl(url) {
262
+ const parsed = zod_1.z
263
+ .string()
264
+ .url()
265
+ .refine((u) => u.startsWith("ws://") || u.startsWith("wss://"), {
266
+ message: "WebSocket URL must start with ws:// or wss://"
267
+ })
268
+ .parse(url);
269
+ this.config.wsUrl = parsed;
270
+ return this;
271
+ }
272
+ /**
273
+ * Configures Ethereum wallet-based authentication credentials.
274
+ * Private key is used to sign authentication challenges from the server.
275
+ * Wallet address is optional and will be derived from the private key if not provided.
276
+ *
277
+ * For enhanced security (SEC-3), you can pass a SecurePrivateKey instance to keep
278
+ * the private key encrypted in memory from the start.
279
+ *
280
+ * @param privateKey - Ethereum private key (hex string starting with 0x) or SecurePrivateKey instance
281
+ * @param walletAddress - Optional wallet address (will be derived if not provided)
282
+ * @returns this builder for method chaining
283
+ * @throws {z.ZodError} If privateKey or walletAddress is invalid
284
+ *
285
+ * @example
286
+ * ```typescript
287
+ * // With private key string only (address derived automatically)
288
+ * builder.withAuthentication('0x...')
289
+ *
290
+ * // With explicit wallet address
291
+ * builder.withAuthentication('0x...privatekey', '0x...address')
292
+ *
293
+ * // With SecurePrivateKey for enhanced security (SEC-3)
294
+ * const secureKey = new SecurePrivateKey('0x...');
295
+ * builder.withAuthentication(secureKey, '0x...address')
296
+ * ```
297
+ */
298
+ withAuthentication(privateKey, walletAddress) {
299
+ this.config.privateKey = PrivateKeySchema.parse(privateKey);
300
+ if (walletAddress) {
301
+ this.config.walletAddress = zod_1.z.string().parse(walletAddress);
302
+ }
303
+ return this;
304
+ }
305
+ /**
306
+ * Configures webhook URL and optional HTTP headers for receiving real-time event notifications.
307
+ * Webhook URL must use HTTPS for non-localhost endpoints (security requirement).
308
+ * Events are sent via HTTP POST requests with JSON payloads.
309
+ *
310
+ * @param url - Webhook endpoint URL (must be HTTPS unless localhost)
311
+ * @param headers - Optional HTTP headers to include with webhook requests (e.g., Authorization)
312
+ * @returns this builder for method chaining
313
+ * @throws {z.ZodError} If URL is invalid
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * // Basic webhook
318
+ * builder.withWebhook('https://api.example.com/webhooks/teneo')
319
+ *
320
+ * // With authentication headers
321
+ * builder.withWebhook('https://api.example.com/webhooks', {
322
+ * 'Authorization': 'Bearer your-token',
323
+ * 'X-Custom-Header': 'value'
324
+ * })
325
+ * ```
326
+ */
327
+ withWebhook(url, headers) {
328
+ this.config.webhookUrl = zod_1.z.string().url().parse(url);
329
+ if (headers) {
330
+ this.config.webhookHeaders = zod_1.z.record(zod_1.z.string()).parse(headers);
331
+ }
332
+ return this;
333
+ }
334
+ /**
335
+ * Configures rooms to automatically subscribe to after authentication.
336
+ * These rooms will be subscribed to automatically when connection is established.
337
+ *
338
+ * @param rooms - Array of room IDs to auto-subscribe to on connection
339
+ * @returns this builder for method chaining
340
+ * @throws {z.ZodError} If room IDs are invalid
341
+ *
342
+ * @example
343
+ * ```typescript
344
+ * builder.withAutoJoinRooms(['general', 'announcements', 'support'])
345
+ * ```
346
+ */
347
+ withAutoJoinRooms(rooms) {
348
+ this.config.autoJoinRooms = zod_1.z.array(zod_1.z.string()).parse(rooms);
349
+ return this;
350
+ }
351
+ /**
352
+ * Configures automatic reconnection behavior for WebSocket connections.
353
+ * When enabled, SDK will automatically attempt to reconnect on disconnection.
354
+ * Uses exponential backoff strategy for reconnection attempts.
355
+ *
356
+ * @param optionsOrEnabled - Reconnection configuration options object, or boolean for backwards compatibility
357
+ * @param delay - (Deprecated positional arg) Delay between reconnection attempts in ms
358
+ * @param maxAttempts - (Deprecated positional arg) Maximum reconnection attempts
359
+ * @returns this builder for method chaining
360
+ * @throws {z.ZodError} If options are out of valid range
361
+ *
362
+ * @example
363
+ * ```typescript
364
+ * // New API with object (recommended)
365
+ * builder.withReconnection({ enabled: true })
366
+ * builder.withReconnection({
367
+ * enabled: true,
368
+ * delay: 3000,
369
+ * maxAttempts: 5
370
+ * })
371
+ *
372
+ * // Old API with positional args (backwards compatible)
373
+ * builder.withReconnection(true, 3000, 5)
374
+ * ```
375
+ */
376
+ withReconnection(optionsOrEnabled, delay, maxAttempts) {
377
+ // Handle backwards compatible positional arguments
378
+ if (typeof optionsOrEnabled === "boolean") {
379
+ this.config.reconnect = zod_1.z.boolean().parse(optionsOrEnabled);
380
+ if (delay !== undefined) {
381
+ this.config.reconnectDelay = zod_1.z.number().min(100).max(60000).parse(delay);
382
+ }
383
+ if (maxAttempts !== undefined) {
384
+ this.config.maxReconnectAttempts = zod_1.z.number().min(0).max(100).parse(maxAttempts);
385
+ }
386
+ }
387
+ else {
388
+ // New object API
389
+ const options = optionsOrEnabled;
390
+ if (options.enabled !== undefined) {
391
+ this.config.reconnect = zod_1.z.boolean().parse(options.enabled);
392
+ }
393
+ if (options.delay !== undefined) {
394
+ this.config.reconnectDelay = zod_1.z.number().min(100).max(60000).parse(options.delay);
395
+ }
396
+ if (options.maxAttempts !== undefined) {
397
+ this.config.maxReconnectAttempts = zod_1.z.number().min(0).max(100).parse(options.maxAttempts);
398
+ }
399
+ }
400
+ return this;
401
+ }
402
+ /**
403
+ * Configures how agent responses are formatted when received.
404
+ * Choose between raw JSON, human-readable text, or both formats.
405
+ * Metadata includes timestamps, agent info, and other contextual data.
406
+ *
407
+ * @param optionsOrFormat - Response format configuration object, or format string for backwards compatibility
408
+ * @param includeMetadata - (Deprecated positional arg) Include metadata in responses
409
+ * @returns this builder for method chaining
410
+ * @throws {z.ZodError} If format is invalid
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * // New API with object (recommended)
415
+ * builder.withResponseFormat({ format: 'humanized' })
416
+ * builder.withResponseFormat({
417
+ * format: 'both',
418
+ * includeMetadata: true
419
+ * })
420
+ *
421
+ * // Old API with positional args (backwards compatible)
422
+ * builder.withResponseFormat('humanized', true)
423
+ * ```
424
+ */
425
+ withResponseFormat(optionsOrFormat, includeMetadata) {
426
+ // Handle backwards compatible positional arguments
427
+ if (typeof optionsOrFormat === "string") {
428
+ this.config.responseFormat = exports.ResponseFormatSchema.parse(optionsOrFormat);
429
+ if (includeMetadata !== undefined) {
430
+ this.config.includeMetadata = zod_1.z.boolean().parse(includeMetadata);
431
+ }
432
+ }
433
+ else {
434
+ // New object API
435
+ const options = optionsOrFormat;
436
+ if (options.format !== undefined) {
437
+ this.config.responseFormat = exports.ResponseFormatSchema.parse(options.format);
438
+ }
439
+ if (options.includeMetadata !== undefined) {
440
+ this.config.includeMetadata = zod_1.z.boolean().parse(options.includeMetadata);
441
+ }
442
+ }
443
+ return this;
444
+ }
445
+ /**
446
+ * Configures logging level and optionally provides a custom logger implementation.
447
+ * Default logger uses pino with pretty printing in development and JSON in production.
448
+ * Custom logger must implement the Logger interface (debug, info, warn, error methods).
449
+ *
450
+ * @param level - Log level: 'debug', 'info', 'warn', 'error', or 'silent' (default: 'info')
451
+ * @param logger - Optional custom logger implementation
452
+ * @returns this builder for method chaining
453
+ * @throws {z.ZodError} If level is invalid or logger doesn't implement required interface
454
+ *
455
+ * @example
456
+ * ```typescript
457
+ * // Set log level only (uses default pino logger)
458
+ * builder.withLogging('debug')
459
+ *
460
+ * // With custom logger
461
+ * const customLogger = {
462
+ * debug: (msg, data) => console.debug(msg, data),
463
+ * info: (msg, data) => console.info(msg, data),
464
+ * warn: (msg, data) => console.warn(msg, data),
465
+ * error: (msg, data) => console.error(msg, data)
466
+ * };
467
+ * builder.withLogging('info', customLogger)
468
+ *
469
+ * // Silent mode (no logs)
470
+ * builder.withLogging('silent')
471
+ * ```
472
+ */
473
+ withLogging(level, logger) {
474
+ this.config.logLevel = exports.LogLevelSchema.parse(level);
475
+ if (logger) {
476
+ this.config.logger = exports.LoggerSchema.parse(logger);
477
+ }
478
+ return this;
479
+ }
480
+ /**
481
+ * Configures agent caching for improved performance.
482
+ * Cache stores agent information to reduce lookup overhead.
483
+ * Automatically invalidates stale entries based on timeout.
484
+ *
485
+ * @param enabled - Enable/disable agent caching (default: true)
486
+ * @param timeout - Cache entry timeout in ms (default: 300000 / 5 minutes, range: 1000-3600000)
487
+ * @param maxSize - Maximum cache size (default: 100, range: 1-10000)
488
+ * @returns this builder for method chaining
489
+ * @throws {z.ZodError} If timeout or maxSize are out of valid range
490
+ *
491
+ * @example
492
+ * ```typescript
493
+ * // Enable with defaults
494
+ * builder.withCache(true)
495
+ *
496
+ * // Custom cache settings
497
+ * builder.withCache(true, 600000, 500) // 10 minutes, 500 entries
498
+ *
499
+ * // Disable caching
500
+ * builder.withCache(false)
501
+ * ```
502
+ */
503
+ withCache(enabled, timeout, maxSize) {
504
+ this.config.enableCache = zod_1.z.boolean().parse(enabled);
505
+ if (timeout !== undefined) {
506
+ this.config.cacheTimeout = zod_1.z.number().min(1000).max(3600000).parse(timeout);
507
+ }
508
+ if (maxSize !== undefined) {
509
+ this.config.maxCacheSize = zod_1.z.number().min(1).max(10000).parse(maxSize);
510
+ }
511
+ return this;
512
+ }
513
+ /**
514
+ * Configures message signature verification for security (SEC-2).
515
+ * Verifies Ethereum ECDSA signatures on incoming messages to prevent spoofing attacks.
516
+ * Disabled by default for backwards compatibility.
517
+ *
518
+ * @param options - Signature verification configuration
519
+ * @param options.enabled - Enable/disable signature verification (default: false)
520
+ * @param options.trustedAddresses - Whitelist of trusted agent addresses (empty = allow all)
521
+ * @param options.requireFor - Message types that require signatures (default: ['task_response', 'agent_selected'])
522
+ * @param options.strictMode - Reject all unsigned messages vs just critical ones (default: false)
523
+ * @returns this builder for method chaining
524
+ * @throws {z.ZodError} If options are invalid
525
+ *
526
+ * @example
527
+ * ```typescript
528
+ * // Enable with defaults (verify but allow unsigned non-critical messages)
529
+ * builder.withSignatureVerification({ enabled: true })
530
+ *
531
+ * // Enable with trusted address whitelist
532
+ * builder.withSignatureVerification({
533
+ * enabled: true,
534
+ * trustedAddresses: ['0xAgent1...', '0xAgent2...']
535
+ * })
536
+ *
537
+ * // Strict mode (reject all unsigned messages)
538
+ * builder.withSignatureVerification({
539
+ * enabled: true,
540
+ * strictMode: true,
541
+ * requireFor: ['task_response', 'agent_selected', 'message']
542
+ * })
543
+ * ```
544
+ */
545
+ withSignatureVerification(options) {
546
+ const { enabled, trustedAddresses, requireFor, strictMode } = options;
547
+ if (enabled !== undefined) {
548
+ this.config.validateSignatures = zod_1.z.boolean().parse(enabled);
549
+ }
550
+ if (trustedAddresses !== undefined) {
551
+ this.config.trustedAgentAddresses = zod_1.z.array(zod_1.z.string()).parse(trustedAddresses);
552
+ }
553
+ if (requireFor !== undefined) {
554
+ this.config.requireSignaturesFor = zod_1.z.array(messages_1.MessageTypeSchema).parse(requireFor);
555
+ }
556
+ if (strictMode !== undefined) {
557
+ this.config.strictSignatureValidation = zod_1.z.boolean().parse(strictMode);
558
+ }
559
+ return this;
560
+ }
561
+ /**
562
+ * Configures WebSocket reconnection retry strategy (REL-3).
563
+ * Allows full control over retry behavior: exponential, linear, or constant backoff.
564
+ * If not specified, uses exponential backoff with default parameters for backward compatibility.
565
+ *
566
+ * @param strategy - Partial retry strategy configuration (unspecified fields use defaults)
567
+ * @returns this builder for method chaining
568
+ * @throws {z.ZodError} If strategy parameters are invalid
569
+ *
570
+ * @example
571
+ * ```typescript
572
+ * // Exponential backoff with aggressive multiplier
573
+ * builder.withReconnectionStrategy({
574
+ * type: 'exponential',
575
+ * baseDelay: 3000,
576
+ * maxDelay: 120000,
577
+ * maxAttempts: 20,
578
+ * jitter: true,
579
+ * backoffMultiplier: 3
580
+ * })
581
+ *
582
+ * // Linear backoff for predictable delays
583
+ * builder.withReconnectionStrategy({
584
+ * type: 'linear',
585
+ * baseDelay: 5000,
586
+ * maxDelay: 60000,
587
+ * maxAttempts: 10,
588
+ * jitter: false
589
+ * })
590
+ *
591
+ * // Constant delay (useful for testing)
592
+ * builder.withReconnectionStrategy({
593
+ * type: 'constant',
594
+ * baseDelay: 10000,
595
+ * maxDelay: 10000,
596
+ * maxAttempts: 5,
597
+ * jitter: false
598
+ * })
599
+ * ```
600
+ */
601
+ withReconnectionStrategy(strategy) {
602
+ // Merge with defaults to allow partial strategy specification
603
+ const fullStrategy = {
604
+ type: strategy.type || "exponential",
605
+ baseDelay: strategy.baseDelay !== undefined ? strategy.baseDelay : 5000,
606
+ maxDelay: strategy.maxDelay !== undefined ? strategy.maxDelay : 60000,
607
+ maxAttempts: strategy.maxAttempts !== undefined ? strategy.maxAttempts : 10,
608
+ jitter: strategy.jitter !== undefined ? strategy.jitter : true,
609
+ backoffMultiplier: strategy.backoffMultiplier
610
+ };
611
+ // Validate with schema
612
+ this.config.reconnectStrategy = retry_policy_1.RetryStrategySchema.parse(fullStrategy);
613
+ return this;
614
+ }
615
+ /**
616
+ * Configures webhook delivery retry strategy (REL-3).
617
+ * Allows full control over retry behavior: exponential, linear, or constant backoff.
618
+ * If not specified, uses exponential backoff with default parameters for backward compatibility.
619
+ *
620
+ * @param strategy - Partial retry strategy configuration (unspecified fields use defaults)
621
+ * @returns this builder for method chaining
622
+ * @throws {z.ZodError} If strategy parameters are invalid
623
+ *
624
+ * @example
625
+ * ```typescript
626
+ * // Exponential backoff without jitter
627
+ * builder.withWebhookRetryStrategy({
628
+ * type: 'exponential',
629
+ * baseDelay: 1000,
630
+ * maxDelay: 30000,
631
+ * maxAttempts: 5,
632
+ * jitter: false,
633
+ * backoffMultiplier: 2
634
+ * })
635
+ *
636
+ * // Linear backoff with jitter to spread load
637
+ * builder.withWebhookRetryStrategy({
638
+ * type: 'linear',
639
+ * baseDelay: 2000,
640
+ * maxDelay: 20000,
641
+ * maxAttempts: 3,
642
+ * jitter: true
643
+ * })
644
+ * ```
645
+ */
646
+ withWebhookRetryStrategy(strategy) {
647
+ // Merge with defaults to allow partial strategy specification
648
+ const fullStrategy = {
649
+ type: strategy.type || "exponential",
650
+ baseDelay: strategy.baseDelay !== undefined ? strategy.baseDelay : 1000,
651
+ maxDelay: strategy.maxDelay !== undefined ? strategy.maxDelay : 30000,
652
+ maxAttempts: strategy.maxAttempts !== undefined ? strategy.maxAttempts : 3,
653
+ jitter: strategy.jitter !== undefined ? strategy.jitter : false,
654
+ backoffMultiplier: strategy.backoffMultiplier
655
+ };
656
+ // Validate with schema
657
+ this.config.webhookRetryStrategy = retry_policy_1.RetryStrategySchema.parse(fullStrategy);
658
+ return this;
659
+ }
660
+ /**
661
+ * Configures message deduplication to prevent duplicate processing (CB-4).
662
+ * Uses TTL-based cache to track recently processed message IDs.
663
+ * Automatically expires entries to prevent unbounded memory growth.
664
+ * Enabled by default with sensible limits for most use cases.
665
+ *
666
+ * @param enabled - Enable/disable message deduplication (default: true)
667
+ * @param ttl - How long to remember message IDs in milliseconds (default: 60000 / 1 minute, range: 1000-3600000)
668
+ * @param maxSize - Maximum cache size (default: 10000, range: 1-100000)
669
+ * @returns this builder for method chaining
670
+ * @throws {z.ZodError} If ttl or maxSize are out of valid range
671
+ *
672
+ * @example
673
+ * ```typescript
674
+ * // Enable with defaults (60s TTL, 10k cache)
675
+ * builder.withMessageDeduplication(true)
676
+ *
677
+ * // Custom settings for high-volume scenarios
678
+ * builder.withMessageDeduplication(true, 120000, 50000) // 2 minutes, 50k entries
679
+ *
680
+ * // Disable deduplication (not recommended for production)
681
+ * builder.withMessageDeduplication(false)
682
+ * ```
683
+ */
684
+ withMessageDeduplication(enabled, ttl, maxSize) {
685
+ this.config.enableMessageDeduplication = zod_1.z.boolean().parse(enabled);
686
+ if (ttl !== undefined) {
687
+ this.config.messageDedupeTtl = zod_1.z.number().min(1000).max(3600000).parse(ttl);
688
+ }
689
+ if (maxSize !== undefined) {
690
+ this.config.messageDedupMaxSize = zod_1.z.number().min(1).max(100000).parse(maxSize);
691
+ }
692
+ return this;
693
+ }
694
+ /**
695
+ * Builds and validates the final SDK configuration.
696
+ * Performs comprehensive validation including custom refinements (e.g., webhook security).
697
+ * Must be called after setting all desired configuration options.
698
+ *
699
+ * @returns Validated SDK configuration ready to pass to TeneoSDK constructor
700
+ * @throws {Error} If configuration is invalid or fails validation
701
+ * @throws {z.ZodError} If required fields are missing or values are out of range
702
+ *
703
+ * @example
704
+ * ```typescript
705
+ * const config = new SDKConfigBuilder()
706
+ * .withWebSocketUrl('wss://teneo.example.com')
707
+ * .withAuthentication('0x...')
708
+ * .withAutoJoinRooms(['general'])
709
+ * .build(); // Validates and returns final config
710
+ *
711
+ * const sdk = new TeneoSDK(config);
712
+ * ```
713
+ */
714
+ build() {
715
+ // Validate and return complete config
716
+ return validateConfig(this.config);
717
+ }
718
+ }
719
+ exports.SDKConfigBuilder = SDKConfigBuilder;
720
+ //# sourceMappingURL=config.js.map