@tdengine/websocket 3.2.2 → 3.3.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 (275) hide show
  1. package/lib/package.json +64 -0
  2. package/lib/src/client/retryConfig.d.ts +10 -0
  3. package/lib/src/client/retryConfig.d.ts.map +1 -0
  4. package/lib/src/client/retryConfig.js +46 -0
  5. package/lib/src/client/wsClient.d.ts +24 -7
  6. package/lib/src/client/wsClient.d.ts.map +1 -1
  7. package/lib/src/client/wsClient.js +164 -137
  8. package/lib/src/client/wsConnector.d.ts +55 -9
  9. package/lib/src/client/wsConnector.d.ts.map +1 -1
  10. package/lib/src/client/wsConnector.js +522 -102
  11. package/lib/src/client/wsConnectorPool.d.ts +5 -1
  12. package/lib/src/client/wsConnectorPool.d.ts.map +1 -1
  13. package/lib/src/client/wsConnectorPool.js +67 -52
  14. package/lib/src/client/wsEventCallback.d.ts +3 -0
  15. package/lib/src/client/wsEventCallback.d.ts.map +1 -1
  16. package/lib/src/client/wsEventCallback.js +67 -8
  17. package/lib/src/client/wsResponse.d.ts +0 -3
  18. package/lib/src/client/wsResponse.d.ts.map +1 -1
  19. package/lib/src/client/wsResponse.js +0 -3
  20. package/lib/src/common/addressConnectionTracker.d.ts +11 -0
  21. package/lib/src/common/addressConnectionTracker.d.ts.map +1 -0
  22. package/lib/src/common/addressConnectionTracker.js +53 -0
  23. package/lib/src/common/config.d.ts +3 -0
  24. package/lib/src/common/config.d.ts.map +1 -1
  25. package/lib/src/common/config.js +6 -0
  26. package/lib/src/common/constant.d.ts +1 -0
  27. package/lib/src/common/constant.d.ts.map +1 -1
  28. package/lib/src/common/constant.js +6 -1
  29. package/lib/src/common/dsn.d.ts +30 -0
  30. package/lib/src/common/dsn.d.ts.map +1 -0
  31. package/lib/src/common/dsn.js +221 -0
  32. package/lib/src/common/taosResult.d.ts.map +1 -1
  33. package/lib/src/common/taosResult.js +0 -5
  34. package/lib/src/common/urlParser.d.ts +32 -0
  35. package/lib/src/common/urlParser.d.ts.map +1 -0
  36. package/lib/src/common/urlParser.js +201 -0
  37. package/lib/src/common/utils.d.ts +6 -1
  38. package/lib/src/common/utils.d.ts.map +1 -1
  39. package/lib/src/common/utils.js +74 -22
  40. package/lib/src/index.d.ts.map +1 -1
  41. package/lib/src/sql/wsSql.d.ts.map +1 -1
  42. package/lib/src/sql/wsSql.js +2 -2
  43. package/lib/src/stmt/FieldBindParams.d.ts.map +1 -1
  44. package/lib/src/stmt/wsColumnInfo.d.ts.map +1 -1
  45. package/lib/src/stmt/wsParams1.d.ts.map +1 -1
  46. package/lib/src/stmt/wsParams1.js +26 -26
  47. package/lib/src/stmt/wsParams2.d.ts.map +1 -1
  48. package/lib/src/stmt/wsParams2.js +0 -3
  49. package/lib/src/stmt/wsParamsBase.d.ts.map +1 -1
  50. package/lib/src/stmt/wsProto.d.ts.map +1 -1
  51. package/lib/src/stmt/wsProto.js +16 -16
  52. package/lib/src/stmt/wsStmt1.d.ts.map +1 -1
  53. package/lib/src/stmt/wsStmt2.d.ts +12 -4
  54. package/lib/src/stmt/wsStmt2.d.ts.map +1 -1
  55. package/lib/src/stmt/wsStmt2.js +182 -64
  56. package/lib/src/stmt/wsTableInfo.d.ts.map +1 -1
  57. package/lib/src/tmq/config.d.ts +4 -2
  58. package/lib/src/tmq/config.d.ts.map +1 -1
  59. package/lib/src/tmq/config.js +30 -13
  60. package/lib/src/tmq/constant.d.ts +4 -0
  61. package/lib/src/tmq/constant.d.ts.map +1 -1
  62. package/lib/src/tmq/constant.js +4 -0
  63. package/lib/src/tmq/tmqResponse.d.ts.map +1 -1
  64. package/lib/src/tmq/tmqResponse.js +1 -4
  65. package/lib/src/tmq/wsTmq.d.ts +4 -1
  66. package/lib/src/tmq/wsTmq.d.ts.map +1 -1
  67. package/lib/src/tmq/wsTmq.js +55 -27
  68. package/lib/test/bulkPulling/a.test.d.ts +2 -0
  69. package/lib/test/bulkPulling/a.test.d.ts.map +1 -0
  70. package/lib/test/bulkPulling/a.test.js +166 -0
  71. package/lib/test/bulkPulling/cloud.tmq.test.js +3 -2
  72. package/lib/test/bulkPulling/decimal.test.js +8 -8
  73. package/lib/test/bulkPulling/dsn.test.d.ts +2 -0
  74. package/lib/test/bulkPulling/dsn.test.d.ts.map +1 -0
  75. package/lib/test/bulkPulling/dsn.test.js +397 -0
  76. package/lib/test/bulkPulling/queryTables.test.js +1 -1
  77. package/lib/test/bulkPulling/retryConfig.test.d.ts +2 -0
  78. package/lib/test/bulkPulling/retryConfig.test.d.ts.map +1 -0
  79. package/lib/test/bulkPulling/retryConfig.test.js +34 -0
  80. package/lib/test/bulkPulling/schemaless.test.js +15 -14
  81. package/lib/test/bulkPulling/sql.failover.test.d.ts +2 -0
  82. package/lib/test/bulkPulling/sql.failover.test.d.ts.map +1 -0
  83. package/lib/test/bulkPulling/sql.failover.test.js +338 -0
  84. package/lib/test/bulkPulling/sql.test.js +116 -44
  85. package/lib/test/bulkPulling/stmt1.func.test.js +31 -30
  86. package/lib/test/bulkPulling/stmt1.type.test.js +1 -1
  87. package/lib/test/bulkPulling/stmt2.failover.test.d.ts +2 -0
  88. package/lib/test/bulkPulling/stmt2.failover.test.d.ts.map +1 -0
  89. package/lib/test/bulkPulling/stmt2.failover.test.js +313 -0
  90. package/lib/test/bulkPulling/stmt2.func.test.js +37 -36
  91. package/lib/test/bulkPulling/stmt2.init.failover.test.d.ts +2 -0
  92. package/lib/test/bulkPulling/stmt2.init.failover.test.d.ts.map +1 -0
  93. package/lib/test/bulkPulling/stmt2.init.failover.test.js +50 -0
  94. package/lib/test/bulkPulling/stmt2.type.test.js +1 -1
  95. package/lib/test/bulkPulling/tmq.config.test.d.ts +2 -0
  96. package/lib/test/bulkPulling/tmq.config.test.d.ts.map +1 -0
  97. package/lib/test/bulkPulling/tmq.config.test.js +77 -0
  98. package/lib/test/bulkPulling/tmq.failover.test.d.ts +2 -0
  99. package/lib/test/bulkPulling/tmq.failover.test.d.ts.map +1 -0
  100. package/lib/test/bulkPulling/tmq.failover.test.js +404 -0
  101. package/lib/test/bulkPulling/tmq.test.js +135 -14
  102. package/lib/test/bulkPulling/urlParser.test.d.ts +2 -0
  103. package/lib/test/bulkPulling/urlParser.test.d.ts.map +1 -0
  104. package/lib/test/bulkPulling/urlParser.test.js +452 -0
  105. package/lib/test/bulkPulling/wsClient.reconnect.integration.test.d.ts +2 -0
  106. package/lib/test/bulkPulling/wsClient.reconnect.integration.test.d.ts.map +1 -0
  107. package/lib/test/bulkPulling/wsClient.reconnect.integration.test.js +184 -0
  108. package/lib/test/bulkPulling/wsClient.recovery.test.d.ts +2 -0
  109. package/lib/test/bulkPulling/wsClient.recovery.test.d.ts.map +1 -0
  110. package/lib/test/bulkPulling/wsClient.recovery.test.js +104 -0
  111. package/lib/test/bulkPulling/wsConfig.dsn.test.d.ts +2 -0
  112. package/lib/test/bulkPulling/wsConfig.dsn.test.d.ts.map +1 -0
  113. package/lib/test/bulkPulling/wsConfig.dsn.test.js +39 -0
  114. package/lib/test/bulkPulling/wsConnectPool.test.js +7 -7
  115. package/lib/test/bulkPulling/wsConnector.failover.test.d.ts +2 -0
  116. package/lib/test/bulkPulling/wsConnector.failover.test.d.ts.map +1 -0
  117. package/lib/test/bulkPulling/wsConnector.failover.test.js +497 -0
  118. package/lib/test/bulkPulling/wsConnectorPool.key.test.d.ts +2 -0
  119. package/lib/test/bulkPulling/wsConnectorPool.key.test.d.ts.map +1 -0
  120. package/lib/test/bulkPulling/wsConnectorPool.key.test.js +52 -0
  121. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.d.ts +2 -0
  122. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.d.ts.map +1 -0
  123. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.js +28 -0
  124. package/lib/test/bulkPulling/wsEventCallback.test.d.ts +2 -0
  125. package/lib/test/bulkPulling/wsEventCallback.test.d.ts.map +1 -0
  126. package/lib/test/bulkPulling/wsEventCallback.test.js +54 -0
  127. package/lib/test/bulkPulling/wsProxy.failover.integration.test.d.ts +2 -0
  128. package/lib/test/bulkPulling/wsProxy.failover.integration.test.d.ts.map +1 -0
  129. package/lib/test/bulkPulling/wsProxy.failover.integration.test.js +120 -0
  130. package/lib/test/bulkPulling/wsProxy.failover.test.d.ts +2 -0
  131. package/lib/test/bulkPulling/wsProxy.failover.test.d.ts.map +1 -0
  132. package/lib/test/bulkPulling/wsProxy.failover.test.js +465 -0
  133. package/lib/test/client/wsClient.recovery.test.d.ts +2 -0
  134. package/lib/test/client/wsClient.recovery.test.d.ts.map +1 -0
  135. package/lib/test/client/wsClient.recovery.test.js +122 -0
  136. package/lib/test/client/wsConnectPool.test.d.ts +2 -0
  137. package/lib/test/client/wsConnectPool.test.d.ts.map +1 -0
  138. package/lib/test/client/wsConnectPool.test.js +147 -0
  139. package/lib/test/client/wsConnector.failover.test.d.ts +2 -0
  140. package/lib/test/client/wsConnector.failover.test.d.ts.map +1 -0
  141. package/lib/test/client/wsConnector.failover.test.js +681 -0
  142. package/lib/test/client/wsConnector.leastConnections.test.d.ts +2 -0
  143. package/lib/test/client/wsConnector.leastConnections.test.d.ts.map +1 -0
  144. package/lib/test/client/wsConnector.leastConnections.test.js +71 -0
  145. package/lib/test/client/wsConnectorPool.key.test.d.ts +2 -0
  146. package/lib/test/client/wsConnectorPool.key.test.d.ts.map +1 -0
  147. package/lib/test/client/wsConnectorPool.key.test.js +127 -0
  148. package/lib/test/client/wsEventCallback.test.d.ts +2 -0
  149. package/lib/test/client/wsEventCallback.test.d.ts.map +1 -0
  150. package/lib/test/client/wsEventCallback.test.js +98 -0
  151. package/lib/test/common/addressConnectionTracker.test.d.ts +2 -0
  152. package/lib/test/common/addressConnectionTracker.test.d.ts.map +1 -0
  153. package/lib/test/common/addressConnectionTracker.test.js +74 -0
  154. package/lib/test/common/dsn.test.d.ts +2 -0
  155. package/lib/test/common/dsn.test.d.ts.map +1 -0
  156. package/lib/test/common/dsn.test.js +406 -0
  157. package/lib/test/common/log.test.d.ts +2 -0
  158. package/lib/test/common/log.test.d.ts.map +1 -0
  159. package/lib/test/common/log.test.js +54 -0
  160. package/lib/test/common/utils.test.d.ts +2 -0
  161. package/lib/test/common/utils.test.d.ts.map +1 -0
  162. package/lib/test/common/utils.test.js +13 -0
  163. package/lib/test/common/wsConfig.dsn.test.d.ts +2 -0
  164. package/lib/test/common/wsConfig.dsn.test.d.ts.map +1 -0
  165. package/lib/test/common/wsConfig.dsn.test.js +39 -0
  166. package/lib/test/helpers/utils.d.ts +27 -0
  167. package/lib/test/helpers/utils.d.ts.map +1 -0
  168. package/lib/test/helpers/utils.js +341 -0
  169. package/lib/test/helpers/wsFailoverProxy.d.ts +109 -0
  170. package/lib/test/helpers/wsFailoverProxy.d.ts.map +1 -0
  171. package/lib/test/helpers/wsFailoverProxy.js +420 -0
  172. package/lib/test/helpers/wsProxy.d.ts +110 -0
  173. package/lib/test/helpers/wsProxy.d.ts.map +1 -0
  174. package/lib/test/helpers/wsProxy.js +429 -0
  175. package/lib/test/sql/core/decimal.test.d.ts +2 -0
  176. package/lib/test/sql/core/decimal.test.d.ts.map +1 -0
  177. package/lib/test/sql/core/decimal.test.js +153 -0
  178. package/lib/test/sql/core/queryTables.test.d.ts +2 -0
  179. package/lib/test/sql/core/queryTables.test.d.ts.map +1 -0
  180. package/lib/test/sql/core/queryTables.test.js +506 -0
  181. package/lib/test/sql/core/schemaless.test.d.ts +2 -0
  182. package/lib/test/sql/core/schemaless.test.d.ts.map +1 -0
  183. package/lib/test/sql/core/schemaless.test.js +102 -0
  184. package/lib/test/sql/core/sql.test.d.ts +2 -0
  185. package/lib/test/sql/core/sql.test.d.ts.map +1 -0
  186. package/lib/test/sql/core/sql.test.js +324 -0
  187. package/lib/test/sql/decimal.test.d.ts +2 -0
  188. package/lib/test/sql/decimal.test.d.ts.map +1 -0
  189. package/lib/test/sql/decimal.test.js +153 -0
  190. package/lib/test/sql/failover/sql.failover.test.d.ts +2 -0
  191. package/lib/test/sql/failover/sql.failover.test.d.ts.map +1 -0
  192. package/lib/test/sql/failover/sql.failover.test.js +341 -0
  193. package/lib/test/sql/queryTables.test.d.ts +2 -0
  194. package/lib/test/sql/queryTables.test.d.ts.map +1 -0
  195. package/lib/test/sql/queryTables.test.js +506 -0
  196. package/lib/test/sql/schemaless.test.d.ts +2 -0
  197. package/lib/test/sql/schemaless.test.d.ts.map +1 -0
  198. package/lib/test/sql/schemaless.test.js +102 -0
  199. package/lib/test/sql/sql.failover.test.d.ts +2 -0
  200. package/lib/test/sql/sql.failover.test.d.ts.map +1 -0
  201. package/lib/test/sql/sql.failover.test.js +341 -0
  202. package/lib/test/sql/sql.test.d.ts +2 -0
  203. package/lib/test/sql/sql.test.d.ts.map +1 -0
  204. package/lib/test/sql/sql.test.js +324 -0
  205. package/lib/test/stmt/failover/stmt2.failover.mock.test.d.ts +2 -0
  206. package/lib/test/stmt/failover/stmt2.failover.mock.test.d.ts.map +1 -0
  207. package/lib/test/stmt/failover/stmt2.failover.mock.test.js +341 -0
  208. package/lib/test/stmt/failover/stmt2.failover.test.d.ts +2 -0
  209. package/lib/test/stmt/failover/stmt2.failover.test.d.ts.map +1 -0
  210. package/lib/test/stmt/failover/stmt2.failover.test.js +384 -0
  211. package/lib/test/stmt/stmt1.func.test.d.ts +2 -0
  212. package/lib/test/stmt/stmt1.func.test.d.ts.map +1 -0
  213. package/lib/test/stmt/stmt1.func.test.js +418 -0
  214. package/lib/test/stmt/stmt1.type.test.d.ts +2 -0
  215. package/lib/test/stmt/stmt1.type.test.d.ts.map +1 -0
  216. package/lib/test/stmt/stmt1.type.test.js +399 -0
  217. package/lib/test/stmt/stmt2.failover.mock.test.d.ts +2 -0
  218. package/lib/test/stmt/stmt2.failover.mock.test.d.ts.map +1 -0
  219. package/lib/test/stmt/stmt2.failover.mock.test.js +341 -0
  220. package/lib/test/stmt/stmt2.failover.test.d.ts +2 -0
  221. package/lib/test/stmt/stmt2.failover.test.d.ts.map +1 -0
  222. package/lib/test/stmt/stmt2.failover.test.js +384 -0
  223. package/lib/test/stmt/stmt2.func.test.d.ts +2 -0
  224. package/lib/test/stmt/stmt2.func.test.d.ts.map +1 -0
  225. package/lib/test/stmt/stmt2.func.test.js +537 -0
  226. package/lib/test/stmt/stmt2.type.test.d.ts +2 -0
  227. package/lib/test/stmt/stmt2.type.test.d.ts.map +1 -0
  228. package/lib/test/stmt/stmt2.type.test.js +401 -0
  229. package/lib/test/stmt/v1/stmt1.func.test.d.ts +2 -0
  230. package/lib/test/stmt/v1/stmt1.func.test.d.ts.map +1 -0
  231. package/lib/test/stmt/v1/stmt1.func.test.js +418 -0
  232. package/lib/test/stmt/v1/stmt1.type.test.d.ts +2 -0
  233. package/lib/test/stmt/v1/stmt1.type.test.d.ts.map +1 -0
  234. package/lib/test/stmt/v1/stmt1.type.test.js +399 -0
  235. package/lib/test/stmt/v2/stmt2.func.test.d.ts +2 -0
  236. package/lib/test/stmt/v2/stmt2.func.test.d.ts.map +1 -0
  237. package/lib/test/stmt/v2/stmt2.func.test.js +537 -0
  238. package/lib/test/stmt/v2/stmt2.type.test.d.ts +2 -0
  239. package/lib/test/stmt/v2/stmt2.type.test.d.ts.map +1 -0
  240. package/lib/test/stmt/v2/stmt2.type.test.js +401 -0
  241. package/lib/test/tmq/cloud/cloud.tmq.test.d.ts +2 -0
  242. package/lib/test/tmq/cloud/cloud.tmq.test.d.ts.map +1 -0
  243. package/lib/test/tmq/cloud/cloud.tmq.test.js +84 -0
  244. package/lib/test/tmq/cloud/tmq.cloud.test.d.ts +2 -0
  245. package/lib/test/tmq/cloud/tmq.cloud.test.d.ts.map +1 -0
  246. package/lib/test/tmq/cloud/tmq.cloud.test.js +82 -0
  247. package/lib/test/tmq/core/tmq.config.test.d.ts +2 -0
  248. package/lib/test/tmq/core/tmq.config.test.d.ts.map +1 -0
  249. package/lib/test/tmq/core/tmq.config.test.js +83 -0
  250. package/lib/test/tmq/core/tmq.test.d.ts +2 -0
  251. package/lib/test/tmq/core/tmq.test.d.ts.map +1 -0
  252. package/lib/test/tmq/core/tmq.test.js +513 -0
  253. package/lib/test/tmq/failover/tmq.failover.test.d.ts +2 -0
  254. package/lib/test/tmq/failover/tmq.failover.test.d.ts.map +1 -0
  255. package/lib/test/tmq/failover/tmq.failover.test.js +404 -0
  256. package/lib/test/tmq/tmq.cloud.test.d.ts +2 -0
  257. package/lib/test/tmq/tmq.cloud.test.d.ts.map +1 -0
  258. package/lib/test/tmq/tmq.cloud.test.js +82 -0
  259. package/lib/test/tmq/tmq.config.test.d.ts +2 -0
  260. package/lib/test/tmq/tmq.config.test.d.ts.map +1 -0
  261. package/lib/test/tmq/tmq.config.test.js +94 -0
  262. package/lib/test/tmq/tmq.failover.test.d.ts +2 -0
  263. package/lib/test/tmq/tmq.failover.test.d.ts.map +1 -0
  264. package/lib/test/tmq/tmq.failover.test.js +404 -0
  265. package/lib/test/tmq/tmq.test.d.ts +2 -0
  266. package/lib/test/tmq/tmq.test.d.ts.map +1 -0
  267. package/lib/test/tmq/tmq.test.js +513 -0
  268. package/lib/test/unit/connectionManager.test.d.ts +2 -0
  269. package/lib/test/unit/connectionManager.test.d.ts.map +1 -0
  270. package/lib/test/unit/connectionManager.test.js +91 -0
  271. package/lib/test/utils.d.ts +4 -0
  272. package/lib/test/utils.d.ts.map +1 -1
  273. package/lib/test/utils.js +11 -17
  274. package/package.json +1 -1
  275. package/readme.md +2 -2
@@ -0,0 +1,497 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const wsConnector_1 = require("../../src/client/wsConnector");
4
+ const wsEventCallback_1 = require("../../src/client/wsEventCallback");
5
+ const dsn_1 = require("../../src/common/dsn");
6
+ function createInflightStore() {
7
+ let nextMsgId = 1n;
8
+ const reqIdToMsgId = new Map();
9
+ const msgIdToRequest = new Map();
10
+ return {
11
+ insert(req) {
12
+ const msgId = nextMsgId;
13
+ nextMsgId += 1n;
14
+ reqIdToMsgId.set(req.reqId, msgId);
15
+ msgIdToRequest.set(msgId, req);
16
+ },
17
+ remove(reqId) {
18
+ const msgId = reqIdToMsgId.get(reqId);
19
+ if (msgId === undefined) {
20
+ return;
21
+ }
22
+ reqIdToMsgId.delete(reqId);
23
+ msgIdToRequest.delete(msgId);
24
+ },
25
+ getRequests() {
26
+ return Array.from(msgIdToRequest.entries())
27
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
28
+ .map(([, req]) => req);
29
+ },
30
+ clear() {
31
+ nextMsgId = 1n;
32
+ reqIdToMsgId.clear();
33
+ msgIdToRequest.clear();
34
+ },
35
+ };
36
+ }
37
+ function createBareConnector() {
38
+ const connector = Object.create(wsConnector_1.WebSocketConnector.prototype);
39
+ connector._timeout = 5000;
40
+ connector._dsn = (0, dsn_1.parse)("ws://root:taosdata@host1:6041,host2:6042");
41
+ connector._currentAddressIndex = 0;
42
+ connector._retryConfig = new wsConnector_1.RetryConfig(1, 1, 8);
43
+ connector._reconnectLock = null;
44
+ connector._isReconnecting = false;
45
+ connector._allowReconnect = true;
46
+ connector._connectionReady = Promise.resolve();
47
+ connector._suppressedSockets = new WeakSet();
48
+ connector._sessionRecoveryHook = null;
49
+ connector._inflightStore = createInflightStore();
50
+ connector._conn = {
51
+ readyState: 1,
52
+ send: jest.fn(),
53
+ close: jest.fn(),
54
+ };
55
+ return connector;
56
+ }
57
+ function buildBinaryMessage(action) {
58
+ const buffer = new ArrayBuffer(26);
59
+ const view = new DataView(buffer);
60
+ view.setBigInt64(16, action, true);
61
+ return buffer;
62
+ }
63
+ function delay(ms) {
64
+ return new Promise((resolve) => setTimeout(resolve, ms));
65
+ }
66
+ function hasInflightRequest(connector, reqId) {
67
+ return connector
68
+ ._inflightStore
69
+ .getRequests()
70
+ .some((req) => req.reqId === reqId);
71
+ }
72
+ function listInflightReqIds(connector) {
73
+ return connector
74
+ ._inflightStore
75
+ .getRequests()
76
+ .map((req) => req.reqId);
77
+ }
78
+ describe("WebSocketConnector failover and retry", () => {
79
+ afterEach(() => {
80
+ jest.restoreAllMocks();
81
+ });
82
+ test("deduplicates concurrent reconnect triggers with reconnect lock", async () => {
83
+ const connector = createBareConnector();
84
+ const reconnectImpl = jest.fn(async () => {
85
+ await delay(20);
86
+ });
87
+ connector._doReconnect = reconnectImpl;
88
+ await Promise.all([
89
+ connector.triggerReconnect(),
90
+ connector.triggerReconnect(),
91
+ connector.triggerReconnect(),
92
+ ]);
93
+ expect(reconnectImpl).toHaveBeenCalledTimes(1);
94
+ });
95
+ test("switches to next address after retries are exhausted", async () => {
96
+ const connector = createBareConnector();
97
+ const attempts = [];
98
+ connector.sleep = jest.fn(async () => { });
99
+ connector.reconnect = jest.fn(async () => {
100
+ const current = connector._dsn.addresses[connector._currentAddressIndex];
101
+ const addr = `${current.host}:${current.port}`;
102
+ attempts.push(addr);
103
+ if (addr === "host1:6041") {
104
+ throw new Error("host1 down");
105
+ }
106
+ });
107
+ await connector.attemptReconnect();
108
+ expect(attempts).toEqual([
109
+ "host1:6041",
110
+ "host2:6042",
111
+ ]);
112
+ expect(connector._currentAddressIndex).toBe(1);
113
+ });
114
+ test("attemptReconnect throws after all addresses and retries are exhausted", async () => {
115
+ const connector = createBareConnector();
116
+ connector.sleep = jest.fn(async () => { });
117
+ connector.reconnect = jest.fn(async () => {
118
+ throw new Error("all down");
119
+ });
120
+ await expect(connector.attemptReconnect()).rejects.toThrow("Failed to reconnect to any available address");
121
+ expect(connector.reconnect).toHaveBeenCalledTimes(2);
122
+ expect(connector._currentAddressIndex).toBe(1);
123
+ });
124
+ test("handleDisconnect skips reconnect when reconnect is disabled", async () => {
125
+ const connector = createBareConnector();
126
+ connector._allowReconnect = false;
127
+ connector.triggerReconnect = jest.fn();
128
+ await connector.handleDisconnect(connector._conn);
129
+ expect(connector.triggerReconnect).not.toHaveBeenCalled();
130
+ });
131
+ test("handleDisconnect skips reconnect on normal close", async () => {
132
+ const connector = createBareConnector();
133
+ connector.triggerReconnect = jest.fn();
134
+ await connector.handleDisconnect(connector._conn, { code: 1000, reason: "normal close" });
135
+ expect(connector.triggerReconnect).not.toHaveBeenCalled();
136
+ });
137
+ test("handleDisconnect swallows reconnect failure", async () => {
138
+ const connector = createBareConnector();
139
+ connector.triggerReconnect = jest.fn(async () => {
140
+ throw new Error("reconnect failed");
141
+ });
142
+ await expect(connector.handleDisconnect(connector._conn, { code: 1006, reason: "abnormal close" })).resolves.toBeUndefined();
143
+ expect(connector.triggerReconnect).toHaveBeenCalledTimes(1);
144
+ });
145
+ test("_doReconnect fails all inflight requests when reconnect fails", async () => {
146
+ const connector = createBareConnector();
147
+ const rejectSpy = jest.fn();
148
+ connector.attemptReconnect = jest.fn(async () => {
149
+ throw new Error("reconnect failed");
150
+ });
151
+ connector._inflightStore.insert({
152
+ reqId: 901n,
153
+ action: "insert",
154
+ message: JSON.stringify({
155
+ action: "insert",
156
+ args: { req_id: 901 },
157
+ }),
158
+ resolve: jest.fn(),
159
+ reject: rejectSpy,
160
+ });
161
+ await expect(connector._doReconnect()).rejects.toThrow("reconnect failed");
162
+ expect(rejectSpy).toHaveBeenCalledTimes(1);
163
+ expect(hasInflightRequest(connector, 901n)).toBe(false);
164
+ });
165
+ test("close disables reconnect and closes current socket", () => {
166
+ const connector = createBareConnector();
167
+ connector.close();
168
+ expect(connector._allowReconnect).toBe(false);
169
+ expect(connector._conn.close).toHaveBeenCalledTimes(1);
170
+ expect(connector._suppressedSockets.has(connector._conn)).toBe(true);
171
+ });
172
+ test("triggers reconnect and keeps retriable string request inflight when send throws", async () => {
173
+ const connector = createBareConnector();
174
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
175
+ connector._conn.send = jest.fn(() => {
176
+ throw new Error("cannot call send() while not connected");
177
+ });
178
+ const pending = connector.sendMsg(JSON.stringify({
179
+ action: "insert",
180
+ args: {
181
+ req_id: 101,
182
+ },
183
+ }));
184
+ void pending.catch(() => { });
185
+ const state = await Promise.race([
186
+ pending.then(() => "resolved").catch(() => "rejected"),
187
+ delay(20).then(() => "pending"),
188
+ ]);
189
+ expect(state).toBe("pending");
190
+ expect(connector.triggerReconnect).toHaveBeenCalledTimes(1);
191
+ expect(hasInflightRequest(connector, 101n)).toBe(true);
192
+ connector.failAllInflightRequests(new Error("cleanup"));
193
+ });
194
+ test("triggers reconnect and keeps retriable poll request inflight when send throws", async () => {
195
+ const connector = createBareConnector();
196
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
197
+ connector._conn.send = jest.fn(() => {
198
+ throw new Error("cannot call send() while not connected");
199
+ });
200
+ const pending = connector.sendMsg(JSON.stringify({
201
+ action: "poll",
202
+ args: {
203
+ req_id: 109,
204
+ blocking_time: 500,
205
+ message_id: 0,
206
+ },
207
+ }));
208
+ void pending.catch(() => { });
209
+ const state = await Promise.race([
210
+ pending.then(() => "resolved").catch(() => "rejected"),
211
+ delay(20).then(() => "pending"),
212
+ ]);
213
+ expect(state).toBe("pending");
214
+ expect(connector.triggerReconnect).toHaveBeenCalledTimes(1);
215
+ expect(hasInflightRequest(connector, 109n)).toBe(true);
216
+ connector.failAllInflightRequests(new Error("cleanup"));
217
+ });
218
+ test("triggers reconnect and keeps retriable subscribe request inflight when send throws", async () => {
219
+ const connector = createBareConnector();
220
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
221
+ connector._conn.send = jest.fn(() => {
222
+ throw new Error("cannot call send() while not connected");
223
+ });
224
+ const pending = connector.sendMsg(JSON.stringify({
225
+ action: "subscribe",
226
+ args: {
227
+ req_id: 110,
228
+ topics: ["topic_a"],
229
+ },
230
+ }));
231
+ void pending.catch(() => { });
232
+ const state = await Promise.race([
233
+ pending.then(() => "resolved").catch(() => "rejected"),
234
+ delay(20).then(() => "pending"),
235
+ ]);
236
+ expect(state).toBe("pending");
237
+ expect(connector.triggerReconnect).toHaveBeenCalledTimes(1);
238
+ expect(hasInflightRequest(connector, 110n)).toBe(true);
239
+ connector.failAllInflightRequests(new Error("cleanup"));
240
+ });
241
+ test("rejects non-retriable string request immediately when send throws", async () => {
242
+ const connector = createBareConnector();
243
+ connector._conn.send = jest.fn(() => {
244
+ throw new Error("send failed");
245
+ });
246
+ await expect(connector.sendMsg(JSON.stringify({
247
+ action: "query",
248
+ args: {
249
+ req_id: 102,
250
+ },
251
+ }))).rejects.toThrow("send failed");
252
+ expect(hasInflightRequest(connector, 102n)).toBe(false);
253
+ });
254
+ test("rejects retriable string request immediately when send throws with non-network error", async () => {
255
+ const connector = createBareConnector();
256
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
257
+ connector._conn.send = jest.fn(() => {
258
+ throw new Error("serialize failed");
259
+ });
260
+ const pending = connector.sendMsg(JSON.stringify({
261
+ action: "insert",
262
+ args: {
263
+ req_id: 111,
264
+ },
265
+ }));
266
+ void pending.catch(() => { });
267
+ const state = await Promise.race([
268
+ pending.then(() => "resolved").catch(() => "rejected"),
269
+ delay(20).then(() => "pending"),
270
+ ]);
271
+ expect(state).toBe("rejected");
272
+ expect(connector.triggerReconnect).not.toHaveBeenCalled();
273
+ expect(hasInflightRequest(connector, 111n)).toBe(false);
274
+ });
275
+ test("rejects retriable subscribe request immediately when send throws with non-network error", async () => {
276
+ const connector = createBareConnector();
277
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
278
+ connector._conn.send = jest.fn(() => {
279
+ throw new Error("serialize failed");
280
+ });
281
+ const pending = connector.sendMsg(JSON.stringify({
282
+ action: "subscribe",
283
+ args: {
284
+ req_id: 113,
285
+ topics: ["topic_a"],
286
+ },
287
+ }));
288
+ void pending.catch(() => { });
289
+ const state = await Promise.race([
290
+ pending.then(() => "resolved").catch(() => "rejected"),
291
+ delay(20).then(() => "pending"),
292
+ ]);
293
+ expect(state).toBe("rejected");
294
+ expect(connector.triggerReconnect).not.toHaveBeenCalled();
295
+ expect(hasInflightRequest(connector, 113n)).toBe(false);
296
+ });
297
+ test("triggers reconnect and rejects non-retriable string request on network send error", async () => {
298
+ const connector = createBareConnector();
299
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
300
+ connector._conn.send = jest.fn(() => {
301
+ throw new Error("cannot call send() while not connected");
302
+ });
303
+ await expect(connector.sendMsg(JSON.stringify({
304
+ action: "query",
305
+ args: {
306
+ req_id: 112,
307
+ },
308
+ }))).rejects.toThrow("cannot call send() while not connected");
309
+ expect(connector.triggerReconnect).toHaveBeenCalledTimes(1);
310
+ expect(hasInflightRequest(connector, 112n)).toBe(false);
311
+ });
312
+ test("triggers reconnect and keeps retriable binary request inflight when send throws", async () => {
313
+ const connector = createBareConnector();
314
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
315
+ connector._conn.send = jest.fn(() => {
316
+ throw new Error("cannot call send() while not connected");
317
+ });
318
+ const message = buildBinaryMessage(6n);
319
+ const pending = connector.sendBinaryMsg(201n, "binary_query", message);
320
+ void pending.catch(() => { });
321
+ const state = await Promise.race([
322
+ pending.then(() => "resolved").catch(() => "rejected"),
323
+ delay(20).then(() => "pending"),
324
+ ]);
325
+ expect(state).toBe("pending");
326
+ expect(connector.triggerReconnect).toHaveBeenCalledTimes(1);
327
+ expect(hasInflightRequest(connector, 201n)).toBe(true);
328
+ connector.failAllInflightRequests(new Error("cleanup"));
329
+ });
330
+ test("rejects non-retriable binary request immediately when send throws", async () => {
331
+ const connector = createBareConnector();
332
+ connector._conn.send = jest.fn(() => {
333
+ throw new Error("send failed");
334
+ });
335
+ const message = buildBinaryMessage(7n);
336
+ await expect(connector.sendBinaryMsg(202n, "fetch", message)).rejects.toThrow("send failed");
337
+ expect(hasInflightRequest(connector, 202n)).toBe(false);
338
+ });
339
+ test("sendMsgDirect unregisters callback on network send error without reconnect", async () => {
340
+ const connector = createBareConnector();
341
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
342
+ connector._conn.send = jest.fn(() => {
343
+ throw new Error("cannot call send() while not connected");
344
+ });
345
+ const registerSpy = jest
346
+ .spyOn(wsEventCallback_1.WsEventCallback.instance(), "registerCallback")
347
+ .mockResolvedValue();
348
+ const unregisterSpy = jest
349
+ .spyOn(wsEventCallback_1.WsEventCallback.instance(), "unregisterCallback")
350
+ .mockResolvedValue();
351
+ await expect(connector.sendMsgDirect(JSON.stringify({
352
+ action: "conn",
353
+ args: {
354
+ req_id: 3001,
355
+ },
356
+ }))).rejects.toThrow("cannot call send() while not connected");
357
+ expect(registerSpy).toHaveBeenCalledTimes(1);
358
+ expect(unregisterSpy).toHaveBeenCalledWith(3001n);
359
+ expect(connector.triggerReconnect).not.toHaveBeenCalled();
360
+ });
361
+ test("sendMsgNoResp rejects on network send error and triggers reconnect", async () => {
362
+ const connector = createBareConnector();
363
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
364
+ connector._conn.send = jest.fn(() => {
365
+ throw new Error("cannot call send() while not connected");
366
+ });
367
+ await expect(connector.sendMsgNoResp(JSON.stringify({
368
+ action: "query",
369
+ args: {
370
+ req_id: 3002,
371
+ },
372
+ }))).rejects.toThrow("cannot call send() while not connected");
373
+ expect(connector.triggerReconnect).toHaveBeenCalledTimes(1);
374
+ });
375
+ test("keeps inflight store consistent when retriable requests are enqueued concurrently", async () => {
376
+ const connector = createBareConnector();
377
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
378
+ connector._conn.send = jest.fn(() => {
379
+ throw new Error("cannot call send() while not connected");
380
+ });
381
+ const reqIds = [301, 302, 303, 304];
382
+ await Promise.all(reqIds.map(async (reqId) => {
383
+ const pending = connector.sendMsg(JSON.stringify({
384
+ action: "insert",
385
+ args: {
386
+ req_id: reqId,
387
+ data: `insert into t values(now, ${reqId})`,
388
+ },
389
+ }));
390
+ void pending.catch(() => { });
391
+ }));
392
+ await delay(20);
393
+ expect(listInflightReqIds(connector)).toEqual([301n, 302n, 303n, 304n]);
394
+ for (const reqId of reqIds) {
395
+ expect(hasInflightRequest(connector, BigInt(reqId))).toBe(true);
396
+ }
397
+ connector.failAllInflightRequests(new Error("cleanup"));
398
+ });
399
+ test("replays inflight requests in the same put order", async () => {
400
+ const connector = createBareConnector();
401
+ connector.triggerReconnect = jest.fn(() => new Promise(() => { }));
402
+ connector._conn.send = jest.fn(() => {
403
+ throw new Error("cannot call send() while not connected");
404
+ });
405
+ const reqIds = [101, 102, 103, 104];
406
+ for (const reqId of reqIds) {
407
+ const pending = connector.sendMsg(JSON.stringify({
408
+ action: "insert",
409
+ args: {
410
+ req_id: reqId,
411
+ data: `insert into t values(now, ${reqId})`,
412
+ },
413
+ }));
414
+ void pending.catch(() => { });
415
+ }
416
+ await delay(20);
417
+ const replaySend = jest.fn();
418
+ connector._conn.send = replaySend;
419
+ await connector.replayRequests();
420
+ const replayedReqIds = replaySend.mock.calls.map(([payload]) => {
421
+ const parsed = JSON.parse(payload);
422
+ return parsed.args.req_id;
423
+ });
424
+ expect(replayedReqIds).toEqual([101, 102, 103, 104]);
425
+ connector.failAllInflightRequests(new Error("cleanup"));
426
+ });
427
+ test("replayRequests stops current round and keeps inflight when network send error happens", async () => {
428
+ const connector = createBareConnector();
429
+ const reject1 = jest.fn();
430
+ const reject2 = jest.fn();
431
+ connector._inflightStore.insert({
432
+ reqId: 501n,
433
+ action: "insert",
434
+ registerCallback: false,
435
+ message: JSON.stringify({
436
+ action: "insert",
437
+ args: {
438
+ req_id: 501,
439
+ },
440
+ }),
441
+ resolve: jest.fn(),
442
+ reject: reject1,
443
+ });
444
+ connector._inflightStore.insert({
445
+ reqId: 502n,
446
+ action: "insert",
447
+ registerCallback: false,
448
+ message: JSON.stringify({
449
+ action: "insert",
450
+ args: {
451
+ req_id: 502,
452
+ },
453
+ }),
454
+ resolve: jest.fn(),
455
+ reject: reject2,
456
+ });
457
+ connector._conn.readyState = 3;
458
+ connector._conn.send = jest.fn(() => {
459
+ throw new Error("cannot call send() while not connected");
460
+ });
461
+ await expect(connector.replayRequests()).rejects.toThrow("cannot call send() while not connected");
462
+ expect(hasInflightRequest(connector, 501n)).toBe(true);
463
+ expect(hasInflightRequest(connector, 502n)).toBe(true);
464
+ expect(reject1).not.toHaveBeenCalled();
465
+ expect(reject2).not.toHaveBeenCalled();
466
+ });
467
+ });
468
+ describe("RetryConfig", () => {
469
+ test("uses defaults when retry params are not provided", () => {
470
+ const dsn = (0, dsn_1.parse)("ws://root:taosdata@localhost:6041");
471
+ const config = wsConnector_1.RetryConfig.fromDsn(dsn);
472
+ expect(config.retries).toBe(5);
473
+ expect(config.retryBackoffMs).toBe(200);
474
+ expect(config.retryBackoffMaxMs).toBe(2000);
475
+ });
476
+ test("reads retry params from dsn", () => {
477
+ const dsn = (0, dsn_1.parse)("ws://root:taosdata@localhost:6041?retries=7&retry_backoff_ms=150&retry_backoff_max_ms=3200");
478
+ const config = wsConnector_1.RetryConfig.fromDsn(dsn);
479
+ expect(config.retries).toBe(7);
480
+ expect(config.retryBackoffMs).toBe(150);
481
+ expect(config.retryBackoffMaxMs).toBe(3200);
482
+ });
483
+ test("normalizes invalid params to safe defaults", () => {
484
+ const dsn = (0, dsn_1.parse)("ws://root:taosdata@localhost:6041?retries=-1&retry_backoff_ms=abc&retry_backoff_max_ms=0");
485
+ const config = wsConnector_1.RetryConfig.fromDsn(dsn);
486
+ expect(config.retries).toBe(5);
487
+ expect(config.retryBackoffMs).toBe(200);
488
+ expect(config.retryBackoffMaxMs).toBe(2000);
489
+ });
490
+ test("computes exponential backoff and caps at max", () => {
491
+ const config = new wsConnector_1.RetryConfig(3, 100, 350);
492
+ expect(config.getBackoffDelay(0)).toBe(100);
493
+ expect(config.getBackoffDelay(1)).toBe(200);
494
+ expect(config.getBackoffDelay(2)).toBe(350);
495
+ expect(config.getBackoffDelay(10)).toBe(350);
496
+ });
497
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=wsConnectorPool.key.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsConnectorPool.key.test.d.ts","sourceRoot":"","sources":["../../../test/bulkPulling/wsConnectorPool.key.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const wsConnectorPool_1 = require("../../src/client/wsConnectorPool");
4
+ const dsn_1 = require("../../src/common/dsn");
5
+ function resetPoolSingleton() {
6
+ const PoolClass = wsConnectorPool_1.WebSocketConnectionPool;
7
+ if (PoolClass._instance) {
8
+ PoolClass._instance.destroyed();
9
+ PoolClass._instance = undefined;
10
+ }
11
+ }
12
+ describe("WebSocketConnectionPool key generation", () => {
13
+ beforeEach(() => {
14
+ resetPoolSingleton();
15
+ });
16
+ afterEach(() => {
17
+ resetPoolSingleton();
18
+ });
19
+ test("normalizes address order when generating pool key", () => {
20
+ const pool = wsConnectorPool_1.WebSocketConnectionPool.instance();
21
+ const dsnA = (0, dsn_1.parse)("ws://root:taosdata@host2:6042,host1:6041/mydb?timezone=UTC&token=abc");
22
+ const dsnB = (0, dsn_1.parse)("ws://root:taosdata@host1:6041,host2:6042/mydb?token=abc&timezone=UTC");
23
+ const keyA = pool.getPoolKey(dsnA);
24
+ const keyB = pool.getPoolKey(dsnB);
25
+ expect(keyA).toBe(keyB);
26
+ });
27
+ test("isolates connections for different auth identities", () => {
28
+ const pool = wsConnectorPool_1.WebSocketConnectionPool.instance();
29
+ const dsnUserA = (0, dsn_1.parse)("ws://root:taosdata@host1:6041/mydb");
30
+ const dsnUserB = (0, dsn_1.parse)("ws://admin:taosdata@host1:6041/mydb");
31
+ const keyA = pool.getPoolKey(dsnUserA);
32
+ const keyB = pool.getPoolKey(dsnUserB);
33
+ expect(keyA).not.toBe(keyB);
34
+ });
35
+ test("isolates connections for different token values", () => {
36
+ const pool = wsConnectorPool_1.WebSocketConnectionPool.instance();
37
+ const dsnA = (0, dsn_1.parse)("ws://host1:6041/mydb?token=token-a");
38
+ const dsnB = (0, dsn_1.parse)("ws://host1:6041/mydb?token=token-b");
39
+ const keyA = pool.getPoolKey(dsnA);
40
+ const keyB = pool.getPoolKey(dsnB);
41
+ expect(keyA).not.toBe(keyB);
42
+ });
43
+ test("includes endpoint-derived websocket path in the pool key scope", () => {
44
+ const pool = wsConnectorPool_1.WebSocketConnectionPool.instance();
45
+ const sqlDsn = (0, dsn_1.parse)("ws://root:taosdata@host1:6041/mydb");
46
+ const tmqDsn = (0, dsn_1.parse)("ws://root:taosdata@host1:6041/mydb");
47
+ tmqDsn.endpoint = dsn_1.WS_TMQ_ENDPOINT;
48
+ const sqlKey = pool.getPoolKey(sqlDsn);
49
+ const tmqKey = pool.getPoolKey(tmqDsn);
50
+ expect(sqlKey).not.toBe(tmqKey);
51
+ });
52
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=wsConnectorPool.keyAuth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsConnectorPool.keyAuth.test.d.ts","sourceRoot":"","sources":["../../../test/bulkPulling/wsConnectorPool.keyAuth.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const wsConnectorPool_1 = require("../../src/client/wsConnectorPool");
4
+ const config_1 = require("../../src/common/config");
5
+ const wsSql_1 = require("../../src/sql/wsSql");
6
+ const utils_1 = require("../helpers/utils");
7
+ afterAll(() => {
8
+ wsConnectorPool_1.WebSocketConnectionPool.instance().destroyed();
9
+ });
10
+ describe("Security: pool key must include auth identity", () => {
11
+ test("username/password: different credentials must not share a pool entry", async () => {
12
+ const validDsn = `ws://${(0, utils_1.testUsername)()}:${(0, utils_1.testPassword)()}@localhost:6041`;
13
+ const wrongPasswordDsn = `ws://${(0, utils_1.testUsername)()}:WRONG_PASSWORD_SENTINEL@localhost:6041`;
14
+ const validConn = await wsSql_1.WsSql.open(new config_1.WSConfig(validDsn));
15
+ expect(validConn.state()).toBeGreaterThan(0);
16
+ await validConn.close();
17
+ await expect(wsSql_1.WsSql.open(new config_1.WSConfig(wrongPasswordDsn))).rejects.toThrow();
18
+ });
19
+ test("same credentials should share a pool entry (sanity check)", async () => {
20
+ const dsn = `ws://${(0, utils_1.testUsername)()}:${(0, utils_1.testPassword)()}@localhost:6041`;
21
+ const conn1 = await wsSql_1.WsSql.open(new config_1.WSConfig(dsn));
22
+ expect(conn1.state()).toBeGreaterThan(0);
23
+ await conn1.close();
24
+ const conn2 = await wsSql_1.WsSql.open(new config_1.WSConfig(dsn));
25
+ expect(conn2.state()).toBeGreaterThan(0);
26
+ await conn2.close();
27
+ });
28
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=wsEventCallback.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsEventCallback.test.d.ts","sourceRoot":"","sources":["../../../test/bulkPulling/wsEventCallback.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const wsEventCallback_1 = require("../../src/client/wsEventCallback");
4
+ function resetCallbackRegistry() {
5
+ const CallbackClass = wsEventCallback_1.WsEventCallback;
6
+ CallbackClass._msgActionRegister = new Map();
7
+ }
8
+ describe("WsEventCallback lifecycle", () => {
9
+ beforeEach(() => {
10
+ resetCallbackRegistry();
11
+ });
12
+ afterEach(() => {
13
+ resetCallbackRegistry();
14
+ jest.restoreAllMocks();
15
+ });
16
+ test("clears timeout when callback is matched", async () => {
17
+ const callback = wsEventCallback_1.WsEventCallback.instance();
18
+ const resolve = jest.fn();
19
+ const reject = jest.fn();
20
+ const clearSpy = jest.spyOn(global, "clearTimeout");
21
+ await callback.registerCallback({
22
+ action: "insert",
23
+ req_id: 11n,
24
+ timeout: 2000,
25
+ }, resolve, reject);
26
+ await callback.handleEventCallback({
27
+ action: "insert",
28
+ req_id: 11n,
29
+ }, wsEventCallback_1.OnMessageType.MESSAGE_TYPE_STRING, {
30
+ action: "insert",
31
+ req_id: 11n,
32
+ code: 0,
33
+ });
34
+ expect(resolve).toHaveBeenCalledTimes(1);
35
+ expect(reject).not.toHaveBeenCalled();
36
+ expect(clearSpy).toHaveBeenCalled();
37
+ expect(wsEventCallback_1.WsEventCallback._msgActionRegister.size).toBe(0);
38
+ });
39
+ test("unregisterCallback removes entry and clears its timeout", async () => {
40
+ const callback = wsEventCallback_1.WsEventCallback.instance();
41
+ const resolve = jest.fn();
42
+ const reject = jest.fn();
43
+ const clearSpy = jest.spyOn(global, "clearTimeout");
44
+ await callback.registerCallback({
45
+ action: "options_connection",
46
+ req_id: 22n,
47
+ timeout: 2000,
48
+ id: 22n,
49
+ }, resolve, reject);
50
+ await callback.unregisterCallback(22n);
51
+ expect(clearSpy).toHaveBeenCalled();
52
+ expect(wsEventCallback_1.WsEventCallback._msgActionRegister.size).toBe(0);
53
+ });
54
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=wsProxy.failover.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsProxy.failover.integration.test.d.ts","sourceRoot":"","sources":["../../../test/bulkPulling/wsProxy.failover.integration.test.ts"],"names":[],"mappings":""}