@tdengine/websocket 3.2.3 → 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 (224) hide show
  1. package/lib/package.json +1 -1
  2. package/lib/src/client/wsClient.d.ts +23 -7
  3. package/lib/src/client/wsClient.d.ts.map +1 -1
  4. package/lib/src/client/wsClient.js +154 -139
  5. package/lib/src/client/wsConnector.d.ts +55 -9
  6. package/lib/src/client/wsConnector.d.ts.map +1 -1
  7. package/lib/src/client/wsConnector.js +519 -100
  8. package/lib/src/client/wsConnectorPool.d.ts +5 -1
  9. package/lib/src/client/wsConnectorPool.d.ts.map +1 -1
  10. package/lib/src/client/wsConnectorPool.js +61 -43
  11. package/lib/src/client/wsEventCallback.d.ts +3 -0
  12. package/lib/src/client/wsEventCallback.d.ts.map +1 -1
  13. package/lib/src/client/wsEventCallback.js +67 -8
  14. package/lib/src/common/addressConnectionTracker.d.ts +11 -0
  15. package/lib/src/common/addressConnectionTracker.d.ts.map +1 -0
  16. package/lib/src/common/addressConnectionTracker.js +53 -0
  17. package/lib/src/common/dsn.d.ts +14 -2
  18. package/lib/src/common/dsn.d.ts.map +1 -1
  19. package/lib/src/common/dsn.js +91 -22
  20. package/lib/src/common/taosResult.d.ts.map +1 -1
  21. package/lib/src/common/taosResult.js +0 -5
  22. package/lib/src/common/urlParser.d.ts +32 -0
  23. package/lib/src/common/urlParser.d.ts.map +1 -0
  24. package/lib/src/common/urlParser.js +201 -0
  25. package/lib/src/common/utils.d.ts +2 -1
  26. package/lib/src/common/utils.d.ts.map +1 -1
  27. package/lib/src/common/utils.js +35 -34
  28. package/lib/src/sql/wsSql.js +2 -2
  29. package/lib/src/stmt/FieldBindParams.d.ts.map +1 -1
  30. package/lib/src/stmt/wsColumnInfo.d.ts.map +1 -1
  31. package/lib/src/stmt/wsParams1.d.ts.map +1 -1
  32. package/lib/src/stmt/wsParams1.js +26 -26
  33. package/lib/src/stmt/wsParams2.d.ts.map +1 -1
  34. package/lib/src/stmt/wsParams2.js +0 -3
  35. package/lib/src/stmt/wsParamsBase.d.ts.map +1 -1
  36. package/lib/src/stmt/wsProto.d.ts.map +1 -1
  37. package/lib/src/stmt/wsProto.js +16 -16
  38. package/lib/src/stmt/wsStmt1.d.ts.map +1 -1
  39. package/lib/src/stmt/wsStmt2.d.ts +12 -4
  40. package/lib/src/stmt/wsStmt2.d.ts.map +1 -1
  41. package/lib/src/stmt/wsStmt2.js +182 -64
  42. package/lib/src/stmt/wsTableInfo.d.ts.map +1 -1
  43. package/lib/src/tmq/config.d.ts +3 -2
  44. package/lib/src/tmq/config.d.ts.map +1 -1
  45. package/lib/src/tmq/config.js +15 -15
  46. package/lib/src/tmq/wsTmq.d.ts +4 -1
  47. package/lib/src/tmq/wsTmq.d.ts.map +1 -1
  48. package/lib/src/tmq/wsTmq.js +50 -27
  49. package/lib/test/bulkPulling/a.test.d.ts +2 -0
  50. package/lib/test/bulkPulling/a.test.d.ts.map +1 -0
  51. package/lib/test/bulkPulling/a.test.js +166 -0
  52. package/lib/test/bulkPulling/dsn.test.js +19 -0
  53. package/lib/test/bulkPulling/retryConfig.test.js +11 -11
  54. package/lib/test/bulkPulling/sql.failover.test.d.ts +2 -0
  55. package/lib/test/bulkPulling/sql.failover.test.d.ts.map +1 -0
  56. package/lib/test/bulkPulling/sql.failover.test.js +338 -0
  57. package/lib/test/bulkPulling/stmt2.failover.test.d.ts +2 -0
  58. package/lib/test/bulkPulling/stmt2.failover.test.d.ts.map +1 -0
  59. package/lib/test/bulkPulling/stmt2.failover.test.js +313 -0
  60. package/lib/test/bulkPulling/stmt2.init.failover.test.d.ts +2 -0
  61. package/lib/test/bulkPulling/stmt2.init.failover.test.d.ts.map +1 -0
  62. package/lib/test/bulkPulling/stmt2.init.failover.test.js +50 -0
  63. package/lib/test/bulkPulling/tmq.failover.test.d.ts +2 -0
  64. package/lib/test/bulkPulling/tmq.failover.test.d.ts.map +1 -0
  65. package/lib/test/bulkPulling/tmq.failover.test.js +404 -0
  66. package/lib/test/bulkPulling/urlParser.test.d.ts +2 -0
  67. package/lib/test/bulkPulling/urlParser.test.d.ts.map +1 -0
  68. package/lib/test/bulkPulling/urlParser.test.js +452 -0
  69. package/lib/test/bulkPulling/wsClient.reconnect.integration.test.js +2 -2
  70. package/lib/test/bulkPulling/wsClient.recovery.test.d.ts +2 -0
  71. package/lib/test/bulkPulling/wsClient.recovery.test.d.ts.map +1 -0
  72. package/lib/test/bulkPulling/wsClient.recovery.test.js +104 -0
  73. package/lib/test/bulkPulling/wsConfig.dsn.test.js +2 -0
  74. package/lib/test/bulkPulling/wsConnector.failover.test.js +396 -27
  75. package/lib/test/bulkPulling/wsConnectorPool.key.test.js +12 -10
  76. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.d.ts +2 -0
  77. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.d.ts.map +1 -0
  78. package/lib/test/bulkPulling/wsConnectorPool.keyAuth.test.js +28 -0
  79. package/lib/test/bulkPulling/wsProxy.failover.integration.test.d.ts +2 -0
  80. package/lib/test/bulkPulling/wsProxy.failover.integration.test.d.ts.map +1 -0
  81. package/lib/test/bulkPulling/wsProxy.failover.integration.test.js +120 -0
  82. package/lib/test/bulkPulling/wsProxy.failover.test.d.ts +2 -0
  83. package/lib/test/bulkPulling/wsProxy.failover.test.d.ts.map +1 -0
  84. package/lib/test/bulkPulling/wsProxy.failover.test.js +465 -0
  85. package/lib/test/client/wsClient.recovery.test.d.ts +2 -0
  86. package/lib/test/client/wsClient.recovery.test.d.ts.map +1 -0
  87. package/lib/test/client/wsClient.recovery.test.js +122 -0
  88. package/lib/test/client/wsConnectPool.test.d.ts +2 -0
  89. package/lib/test/client/wsConnectPool.test.d.ts.map +1 -0
  90. package/lib/test/client/wsConnectPool.test.js +147 -0
  91. package/lib/test/client/wsConnector.failover.test.d.ts +2 -0
  92. package/lib/test/client/wsConnector.failover.test.d.ts.map +1 -0
  93. package/lib/test/client/wsConnector.failover.test.js +681 -0
  94. package/lib/test/client/wsConnector.leastConnections.test.d.ts +2 -0
  95. package/lib/test/client/wsConnector.leastConnections.test.d.ts.map +1 -0
  96. package/lib/test/client/wsConnector.leastConnections.test.js +71 -0
  97. package/lib/test/client/wsConnectorPool.key.test.d.ts +2 -0
  98. package/lib/test/client/wsConnectorPool.key.test.d.ts.map +1 -0
  99. package/lib/test/client/wsConnectorPool.key.test.js +127 -0
  100. package/lib/test/client/wsEventCallback.test.d.ts +2 -0
  101. package/lib/test/client/wsEventCallback.test.d.ts.map +1 -0
  102. package/lib/test/client/wsEventCallback.test.js +98 -0
  103. package/lib/test/common/addressConnectionTracker.test.d.ts +2 -0
  104. package/lib/test/common/addressConnectionTracker.test.d.ts.map +1 -0
  105. package/lib/test/common/addressConnectionTracker.test.js +74 -0
  106. package/lib/test/common/dsn.test.d.ts +2 -0
  107. package/lib/test/common/dsn.test.d.ts.map +1 -0
  108. package/lib/test/common/dsn.test.js +406 -0
  109. package/lib/test/common/log.test.d.ts +2 -0
  110. package/lib/test/common/log.test.d.ts.map +1 -0
  111. package/lib/test/common/log.test.js +54 -0
  112. package/lib/test/common/utils.test.d.ts +2 -0
  113. package/lib/test/common/utils.test.d.ts.map +1 -0
  114. package/lib/test/common/utils.test.js +13 -0
  115. package/lib/test/common/wsConfig.dsn.test.d.ts +2 -0
  116. package/lib/test/common/wsConfig.dsn.test.d.ts.map +1 -0
  117. package/lib/test/common/wsConfig.dsn.test.js +39 -0
  118. package/lib/test/helpers/utils.d.ts +27 -0
  119. package/lib/test/helpers/utils.d.ts.map +1 -0
  120. package/lib/test/helpers/utils.js +341 -0
  121. package/lib/test/helpers/wsFailoverProxy.d.ts +109 -0
  122. package/lib/test/helpers/wsFailoverProxy.d.ts.map +1 -0
  123. package/lib/test/helpers/wsFailoverProxy.js +420 -0
  124. package/lib/test/helpers/wsProxy.d.ts +110 -0
  125. package/lib/test/helpers/wsProxy.d.ts.map +1 -0
  126. package/lib/test/helpers/wsProxy.js +429 -0
  127. package/lib/test/sql/core/decimal.test.d.ts +2 -0
  128. package/lib/test/sql/core/decimal.test.d.ts.map +1 -0
  129. package/lib/test/sql/core/decimal.test.js +153 -0
  130. package/lib/test/sql/core/queryTables.test.d.ts +2 -0
  131. package/lib/test/sql/core/queryTables.test.d.ts.map +1 -0
  132. package/lib/test/sql/core/queryTables.test.js +506 -0
  133. package/lib/test/sql/core/schemaless.test.d.ts +2 -0
  134. package/lib/test/sql/core/schemaless.test.d.ts.map +1 -0
  135. package/lib/test/sql/core/schemaless.test.js +102 -0
  136. package/lib/test/sql/core/sql.test.d.ts +2 -0
  137. package/lib/test/sql/core/sql.test.d.ts.map +1 -0
  138. package/lib/test/sql/core/sql.test.js +324 -0
  139. package/lib/test/sql/decimal.test.d.ts +2 -0
  140. package/lib/test/sql/decimal.test.d.ts.map +1 -0
  141. package/lib/test/sql/decimal.test.js +153 -0
  142. package/lib/test/sql/failover/sql.failover.test.d.ts +2 -0
  143. package/lib/test/sql/failover/sql.failover.test.d.ts.map +1 -0
  144. package/lib/test/sql/failover/sql.failover.test.js +341 -0
  145. package/lib/test/sql/queryTables.test.d.ts +2 -0
  146. package/lib/test/sql/queryTables.test.d.ts.map +1 -0
  147. package/lib/test/sql/queryTables.test.js +506 -0
  148. package/lib/test/sql/schemaless.test.d.ts +2 -0
  149. package/lib/test/sql/schemaless.test.d.ts.map +1 -0
  150. package/lib/test/sql/schemaless.test.js +102 -0
  151. package/lib/test/sql/sql.failover.test.d.ts +2 -0
  152. package/lib/test/sql/sql.failover.test.d.ts.map +1 -0
  153. package/lib/test/sql/sql.failover.test.js +341 -0
  154. package/lib/test/sql/sql.test.d.ts +2 -0
  155. package/lib/test/sql/sql.test.d.ts.map +1 -0
  156. package/lib/test/sql/sql.test.js +324 -0
  157. package/lib/test/stmt/failover/stmt2.failover.mock.test.d.ts +2 -0
  158. package/lib/test/stmt/failover/stmt2.failover.mock.test.d.ts.map +1 -0
  159. package/lib/test/stmt/failover/stmt2.failover.mock.test.js +341 -0
  160. package/lib/test/stmt/failover/stmt2.failover.test.d.ts +2 -0
  161. package/lib/test/stmt/failover/stmt2.failover.test.d.ts.map +1 -0
  162. package/lib/test/stmt/failover/stmt2.failover.test.js +384 -0
  163. package/lib/test/stmt/stmt1.func.test.d.ts +2 -0
  164. package/lib/test/stmt/stmt1.func.test.d.ts.map +1 -0
  165. package/lib/test/stmt/stmt1.func.test.js +418 -0
  166. package/lib/test/stmt/stmt1.type.test.d.ts +2 -0
  167. package/lib/test/stmt/stmt1.type.test.d.ts.map +1 -0
  168. package/lib/test/stmt/stmt1.type.test.js +399 -0
  169. package/lib/test/stmt/stmt2.failover.mock.test.d.ts +2 -0
  170. package/lib/test/stmt/stmt2.failover.mock.test.d.ts.map +1 -0
  171. package/lib/test/stmt/stmt2.failover.mock.test.js +341 -0
  172. package/lib/test/stmt/stmt2.failover.test.d.ts +2 -0
  173. package/lib/test/stmt/stmt2.failover.test.d.ts.map +1 -0
  174. package/lib/test/stmt/stmt2.failover.test.js +384 -0
  175. package/lib/test/stmt/stmt2.func.test.d.ts +2 -0
  176. package/lib/test/stmt/stmt2.func.test.d.ts.map +1 -0
  177. package/lib/test/stmt/stmt2.func.test.js +537 -0
  178. package/lib/test/stmt/stmt2.type.test.d.ts +2 -0
  179. package/lib/test/stmt/stmt2.type.test.d.ts.map +1 -0
  180. package/lib/test/stmt/stmt2.type.test.js +401 -0
  181. package/lib/test/stmt/v1/stmt1.func.test.d.ts +2 -0
  182. package/lib/test/stmt/v1/stmt1.func.test.d.ts.map +1 -0
  183. package/lib/test/stmt/v1/stmt1.func.test.js +418 -0
  184. package/lib/test/stmt/v1/stmt1.type.test.d.ts +2 -0
  185. package/lib/test/stmt/v1/stmt1.type.test.d.ts.map +1 -0
  186. package/lib/test/stmt/v1/stmt1.type.test.js +399 -0
  187. package/lib/test/stmt/v2/stmt2.func.test.d.ts +2 -0
  188. package/lib/test/stmt/v2/stmt2.func.test.d.ts.map +1 -0
  189. package/lib/test/stmt/v2/stmt2.func.test.js +537 -0
  190. package/lib/test/stmt/v2/stmt2.type.test.d.ts +2 -0
  191. package/lib/test/stmt/v2/stmt2.type.test.d.ts.map +1 -0
  192. package/lib/test/stmt/v2/stmt2.type.test.js +401 -0
  193. package/lib/test/tmq/cloud/cloud.tmq.test.d.ts +2 -0
  194. package/lib/test/tmq/cloud/cloud.tmq.test.d.ts.map +1 -0
  195. package/lib/test/tmq/cloud/cloud.tmq.test.js +84 -0
  196. package/lib/test/tmq/cloud/tmq.cloud.test.d.ts +2 -0
  197. package/lib/test/tmq/cloud/tmq.cloud.test.d.ts.map +1 -0
  198. package/lib/test/tmq/cloud/tmq.cloud.test.js +82 -0
  199. package/lib/test/tmq/core/tmq.config.test.d.ts +2 -0
  200. package/lib/test/tmq/core/tmq.config.test.d.ts.map +1 -0
  201. package/lib/test/tmq/core/tmq.config.test.js +83 -0
  202. package/lib/test/tmq/core/tmq.test.d.ts +2 -0
  203. package/lib/test/tmq/core/tmq.test.d.ts.map +1 -0
  204. package/lib/test/tmq/core/tmq.test.js +513 -0
  205. package/lib/test/tmq/failover/tmq.failover.test.d.ts +2 -0
  206. package/lib/test/tmq/failover/tmq.failover.test.d.ts.map +1 -0
  207. package/lib/test/tmq/failover/tmq.failover.test.js +404 -0
  208. package/lib/test/tmq/tmq.cloud.test.d.ts +2 -0
  209. package/lib/test/tmq/tmq.cloud.test.d.ts.map +1 -0
  210. package/lib/test/tmq/tmq.cloud.test.js +82 -0
  211. package/lib/test/tmq/tmq.config.test.d.ts +2 -0
  212. package/lib/test/tmq/tmq.config.test.d.ts.map +1 -0
  213. package/lib/test/tmq/tmq.config.test.js +94 -0
  214. package/lib/test/tmq/tmq.failover.test.d.ts +2 -0
  215. package/lib/test/tmq/tmq.failover.test.d.ts.map +1 -0
  216. package/lib/test/tmq/tmq.failover.test.js +404 -0
  217. package/lib/test/tmq/tmq.test.d.ts +2 -0
  218. package/lib/test/tmq/tmq.test.d.ts.map +1 -0
  219. package/lib/test/tmq/tmq.test.js +513 -0
  220. package/lib/test/unit/connectionManager.test.d.ts +2 -0
  221. package/lib/test/unit/connectionManager.test.d.ts.map +1 -0
  222. package/lib/test/unit/connectionManager.test.js +91 -0
  223. package/package.json +1 -1
  224. package/readme.md +2 -2
@@ -0,0 +1,429 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.WsProxy = void 0;
37
+ const http = __importStar(require("http"));
38
+ const websocket_1 = require("websocket");
39
+ const DEFAULT_UPSTREAM_BASE_URL = "ws://localhost:6041";
40
+ class WsProxy {
41
+ constructor(options) {
42
+ this._lockedPort = null;
43
+ this._httpServer = null;
44
+ this._wsServer = null;
45
+ this._running = false;
46
+ this._nextConnectionId = 1;
47
+ this._lifecycleChain = Promise.resolve();
48
+ this._tunnels = new Map();
49
+ this._eventLog = [];
50
+ if (!options.host || options.host.trim().length === 0) {
51
+ throw new Error("listen host must not be empty");
52
+ }
53
+ if (!Number.isInteger(options.port) ||
54
+ options.port < 0 ||
55
+ options.port > 65535) {
56
+ throw new Error(`invalid listen port: ${options.port}, expected 0-65535`);
57
+ }
58
+ this._listenHost = options.host;
59
+ this._requestedPort = options.port;
60
+ this._onEvent = options.onEvent;
61
+ this._control = {
62
+ restart: async (opts) => {
63
+ await this.restart(opts);
64
+ },
65
+ stop: async (reason) => {
66
+ await this.stop(reason);
67
+ },
68
+ isRunning: () => this.isRunning(),
69
+ };
70
+ }
71
+ static async create(options) {
72
+ const proxy = new WsProxy(options);
73
+ await proxy.start("initial start");
74
+ return proxy;
75
+ }
76
+ async start(reason) {
77
+ await this.enqueueLifecycle(async () => {
78
+ await this.startInternal(reason);
79
+ });
80
+ }
81
+ async stop(reason) {
82
+ await this.enqueueLifecycle(async () => {
83
+ await this.stopInternal(reason);
84
+ });
85
+ }
86
+ async restart(opts) {
87
+ await this.enqueueLifecycle(async () => {
88
+ const reason = opts?.reason || "restart";
89
+ const downtimeMs = Math.max(0, opts?.downtimeMs || 0);
90
+ await this.stopInternal(reason);
91
+ if (downtimeMs > 0) {
92
+ await sleep(downtimeMs);
93
+ }
94
+ await this.startInternal(reason);
95
+ });
96
+ }
97
+ isRunning() {
98
+ return this._running;
99
+ }
100
+ getPort() {
101
+ if (this._lockedPort === null) {
102
+ throw new Error("proxy has not started yet");
103
+ }
104
+ return this._lockedPort;
105
+ }
106
+ getHost() {
107
+ return this._listenHost;
108
+ }
109
+ getUrl() {
110
+ return `ws://${this._listenHost}:${this.getPort()}`;
111
+ }
112
+ getEventLog() {
113
+ return [...this._eventLog];
114
+ }
115
+ async enqueueLifecycle(task) {
116
+ this._lifecycleChain = this._lifecycleChain.then(task, task);
117
+ await this._lifecycleChain;
118
+ }
119
+ async startInternal(reason) {
120
+ if (this._running) {
121
+ return;
122
+ }
123
+ const listenPort = this._lockedPort === null
124
+ ? this._requestedPort
125
+ : this._lockedPort;
126
+ const httpServer = http.createServer((_req, res) => {
127
+ res.statusCode = 404;
128
+ res.end();
129
+ });
130
+ await new Promise((resolve, reject) => {
131
+ const onError = (err) => {
132
+ httpServer.removeListener("listening", onListening);
133
+ reject(err);
134
+ };
135
+ const onListening = () => {
136
+ httpServer.removeListener("error", onError);
137
+ resolve();
138
+ };
139
+ httpServer.once("error", onError);
140
+ httpServer.once("listening", onListening);
141
+ httpServer.listen(listenPort, this._listenHost);
142
+ });
143
+ const address = httpServer.address();
144
+ if (!address || typeof address === "string") {
145
+ httpServer.close();
146
+ throw new Error("failed to get proxy listen address");
147
+ }
148
+ if (this._lockedPort === null) {
149
+ this._lockedPort = address.port;
150
+ }
151
+ const wsServer = new websocket_1.server({
152
+ httpServer,
153
+ autoAcceptConnections: false,
154
+ });
155
+ wsServer.on("request", (request) => {
156
+ this.handleClientRequest(request);
157
+ });
158
+ this._httpServer = httpServer;
159
+ this._wsServer = wsServer;
160
+ this._running = true;
161
+ this.emitEvent({
162
+ type: "proxy_started",
163
+ timestamp: Date.now(),
164
+ host: this._listenHost,
165
+ port: this.getPort(),
166
+ url: this.getUrl(),
167
+ reason,
168
+ });
169
+ }
170
+ async stopInternal(reason) {
171
+ if (!this._running && !this._httpServer && !this._wsServer) {
172
+ return;
173
+ }
174
+ this._running = false;
175
+ for (const tunnel of Array.from(this._tunnels.values())) {
176
+ this.closeTunnel(tunnel.id, `proxy stopping${reason ? `: ${reason}` : ""}`, "proxy");
177
+ }
178
+ if (this._wsServer) {
179
+ try {
180
+ this._wsServer.removeAllListeners("request");
181
+ this._wsServer.closeAllConnections();
182
+ this._wsServer.unmount();
183
+ }
184
+ catch (_err) {
185
+ // Ignore shutdown errors and continue releasing resources.
186
+ }
187
+ }
188
+ if (this._httpServer) {
189
+ await new Promise((resolve) => {
190
+ if (!this._httpServer || !this._httpServer.listening) {
191
+ resolve();
192
+ return;
193
+ }
194
+ this._httpServer.close(() => resolve());
195
+ });
196
+ }
197
+ this._wsServer = null;
198
+ this._httpServer = null;
199
+ this.emitEvent({
200
+ type: "proxy_stopped",
201
+ timestamp: Date.now(),
202
+ reason,
203
+ });
204
+ }
205
+ handleClientRequest(request) {
206
+ if (!this._running) {
207
+ request.reject(503, "proxy is not running");
208
+ return;
209
+ }
210
+ const path = request.resourceURL?.pathname || request.resource;
211
+ const clientConn = request.accept(undefined, request.origin);
212
+ const connectionId = this._nextConnectionId;
213
+ this._nextConnectionId += 1;
214
+ const tunnel = {
215
+ id: connectionId,
216
+ path,
217
+ closed: false,
218
+ messageSeq: 0,
219
+ clientConn,
220
+ pendingFrames: [],
221
+ };
222
+ this._tunnels.set(connectionId, tunnel);
223
+ this.emitEvent({
224
+ type: "client_connected",
225
+ timestamp: Date.now(),
226
+ connectionId,
227
+ path,
228
+ remoteAddress: request.remoteAddress,
229
+ });
230
+ clientConn.on("message", (message) => {
231
+ this.handleClientMessage(tunnel, message);
232
+ });
233
+ clientConn.on("close", (code, desc) => {
234
+ this.closeTunnel(connectionId, `client closed: ${code} ${desc}`, "client");
235
+ });
236
+ clientConn.on("error", (error) => {
237
+ this.emitError("client_error", error, connectionId);
238
+ this.closeTunnel(connectionId, `client error: ${error.message}`, "client");
239
+ });
240
+ this.connectUpstream(tunnel);
241
+ }
242
+ connectUpstream(tunnel) {
243
+ const upstreamClient = new websocket_1.client();
244
+ tunnel.upstreamClient = upstreamClient;
245
+ const upstreamUrl = this.buildUpstreamUrl(tunnel.path);
246
+ upstreamClient.on("connect", (upstreamConn) => {
247
+ if (tunnel.closed) {
248
+ upstreamConn.close();
249
+ return;
250
+ }
251
+ tunnel.upstreamConn = upstreamConn;
252
+ this.emitEvent({
253
+ type: "upstream_connected",
254
+ timestamp: Date.now(),
255
+ connectionId: tunnel.id,
256
+ upstreamUrl,
257
+ });
258
+ upstreamConn.on("message", (message) => {
259
+ this.handleUpstreamMessage(tunnel, message);
260
+ });
261
+ upstreamConn.on("close", (code, desc) => {
262
+ this.closeTunnel(tunnel.id, `upstream closed: ${code} ${desc}`, "upstream");
263
+ });
264
+ upstreamConn.on("error", (error) => {
265
+ this.emitError("upstream_error", error, tunnel.id);
266
+ this.closeTunnel(tunnel.id, `upstream error: ${error.message}`, "upstream");
267
+ });
268
+ this.flushPendingFrames(tunnel);
269
+ });
270
+ upstreamClient.on("connectFailed", (error) => {
271
+ this.emitError("upstream_connect_failed", error, tunnel.id);
272
+ this.closeTunnel(tunnel.id, `upstream connect failed: ${error.message}`, "upstream");
273
+ });
274
+ upstreamClient.connect(upstreamUrl);
275
+ }
276
+ buildUpstreamUrl(path) {
277
+ const upstream = new URL(DEFAULT_UPSTREAM_BASE_URL);
278
+ upstream.pathname = ensureLeadingSlash(path);
279
+ return upstream.toString();
280
+ }
281
+ handleClientMessage(tunnel, message) {
282
+ if (tunnel.closed) {
283
+ return;
284
+ }
285
+ if (message.type === "utf8") {
286
+ const rawData = message.utf8Data;
287
+ this.emitMessageEvent(tunnel, "client_to_upstream", false, rawData);
288
+ if (this.isConnected(tunnel.upstreamConn)) {
289
+ tunnel.upstreamConn.sendUTF(rawData);
290
+ return;
291
+ }
292
+ tunnel.pendingFrames.push({
293
+ isBinary: false,
294
+ data: rawData,
295
+ });
296
+ return;
297
+ }
298
+ const rawData = Buffer.from(message.binaryData);
299
+ this.emitMessageEvent(tunnel, "client_to_upstream", true, rawData);
300
+ if (this.isConnected(tunnel.upstreamConn)) {
301
+ tunnel.upstreamConn.sendBytes(rawData);
302
+ return;
303
+ }
304
+ tunnel.pendingFrames.push({
305
+ isBinary: true,
306
+ data: rawData,
307
+ });
308
+ }
309
+ handleUpstreamMessage(tunnel, message) {
310
+ if (tunnel.closed || !this.isConnected(tunnel.clientConn)) {
311
+ this.closeTunnel(tunnel.id, "client connection unavailable while forwarding upstream message", "client");
312
+ return;
313
+ }
314
+ if (message.type === "utf8") {
315
+ const rawData = message.utf8Data;
316
+ this.emitMessageEvent(tunnel, "upstream_to_client", false, rawData);
317
+ tunnel.clientConn.sendUTF(rawData);
318
+ return;
319
+ }
320
+ const rawData = Buffer.from(message.binaryData);
321
+ this.emitMessageEvent(tunnel, "upstream_to_client", true, rawData);
322
+ tunnel.clientConn.sendBytes(rawData);
323
+ }
324
+ flushPendingFrames(tunnel) {
325
+ if (!this.isConnected(tunnel.upstreamConn) || tunnel.closed) {
326
+ return;
327
+ }
328
+ while (tunnel.pendingFrames.length > 0) {
329
+ const frame = tunnel.pendingFrames.shift();
330
+ if (!frame) {
331
+ break;
332
+ }
333
+ if (frame.isBinary) {
334
+ tunnel.upstreamConn.sendBytes(frame.data);
335
+ }
336
+ else {
337
+ tunnel.upstreamConn.sendUTF(frame.data);
338
+ }
339
+ }
340
+ }
341
+ closeTunnel(connectionId, reason, source) {
342
+ const tunnel = this._tunnels.get(connectionId);
343
+ if (!tunnel || tunnel.closed) {
344
+ return;
345
+ }
346
+ tunnel.closed = true;
347
+ this._tunnels.delete(connectionId);
348
+ const isProxyInjectedFailure = source === "proxy";
349
+ this.safeCloseConnection(tunnel.clientConn, isProxyInjectedFailure);
350
+ this.safeCloseConnection(tunnel.upstreamConn, isProxyInjectedFailure);
351
+ this.emitEvent({
352
+ type: "tunnel_closed",
353
+ timestamp: Date.now(),
354
+ connectionId,
355
+ reason,
356
+ source,
357
+ });
358
+ }
359
+ isConnected(conn) {
360
+ return !!conn && conn.connected;
361
+ }
362
+ emitMessageEvent(tunnel, direction, isBinary, rawData) {
363
+ tunnel.messageSeq += 1;
364
+ this.emitEvent({
365
+ type: "message",
366
+ timestamp: Date.now(),
367
+ connectionId: tunnel.id,
368
+ direction,
369
+ isBinary,
370
+ byteLength: typeof rawData === "string"
371
+ ? Buffer.byteLength(rawData)
372
+ : rawData.byteLength,
373
+ rawData,
374
+ messageSeq: tunnel.messageSeq,
375
+ });
376
+ }
377
+ emitError(stage, error, connectionId, sourceEventType, details, notifyCallback = true) {
378
+ this.emitEvent({
379
+ type: "error",
380
+ timestamp: Date.now(),
381
+ connectionId,
382
+ error: normalizeError(error),
383
+ stage,
384
+ sourceEventType,
385
+ details,
386
+ }, notifyCallback);
387
+ }
388
+ emitEvent(event, notifyCallback = true) {
389
+ this._eventLog.push(event);
390
+ if (!notifyCallback || !this._onEvent) {
391
+ return;
392
+ }
393
+ void Promise.resolve(this._onEvent(event, this._control)).catch((err) => {
394
+ this.emitError("event_handler", err, event.connectionId, event.type, "event callback threw an error", false);
395
+ });
396
+ }
397
+ safeCloseConnection(conn, abnormal) {
398
+ try {
399
+ if (!this.isConnected(conn)) {
400
+ return;
401
+ }
402
+ if (abnormal) {
403
+ conn.close(1012, "proxy restart");
404
+ return;
405
+ }
406
+ conn.close();
407
+ }
408
+ catch (_err) {
409
+ // Ignore close failures.
410
+ }
411
+ }
412
+ }
413
+ exports.WsProxy = WsProxy;
414
+ function normalizeError(error) {
415
+ if (error instanceof Error) {
416
+ return error;
417
+ }
418
+ return new Error(String(error));
419
+ }
420
+ function ensureLeadingSlash(path) {
421
+ if (!path || path.trim().length === 0) {
422
+ throw new Error("proxy supported path must not be empty");
423
+ }
424
+ const trimmed = path.trim();
425
+ return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
426
+ }
427
+ function sleep(ms) {
428
+ return new Promise((resolve) => setTimeout(resolve, ms));
429
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=decimal.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decimal.test.d.ts","sourceRoot":"","sources":["../../../../test/sql/core/decimal.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,153 @@
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("@test-helpers/utils");
7
+ const log_1 = require("@src/common/log");
8
+ const constant_1 = require("@src/tmq/constant");
9
+ const wsTmq_1 = require("@src/tmq/wsTmq");
10
+ let dns = "ws://localhost:6041";
11
+ let createTopic = `create topic if not exists topic_decimal_test as select * from power.decimal_test`;
12
+ let dropTopic = `DROP TOPIC IF EXISTS topic_decimal_test;`;
13
+ (0, log_1.setLevel)("debug");
14
+ beforeAll(async () => {
15
+ let conf = new config_1.WSConfig(dns);
16
+ conf.setUser((0, utils_1.testUsername)());
17
+ conf.setPwd((0, utils_1.testPassword)());
18
+ let wsSql = await wsSql_1.WsSql.open(conf);
19
+ await wsSql.exec(dropTopic);
20
+ await wsSql.exec("drop database if exists power");
21
+ await wsSql.exec("create database if not exists power KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;");
22
+ await (0, utils_1.Sleep)(100);
23
+ await wsSql.exec("use power");
24
+ await wsSql.exec("CREATE STABLE if not exists decimal_test (ts timestamp, dec64 decimal(10,6), dec128 decimal(24,10), int1 int) TAGS (location binary(64), groupId int);");
25
+ await wsSql.exec(createTopic);
26
+ await wsSql.close();
27
+ });
28
+ const expectedResultsMap = new Map([
29
+ [
30
+ "-1234.654321",
31
+ {
32
+ dec128: "-123456789012.0987654321",
33
+ int1: 3,
34
+ location: "California",
35
+ groupId: 3,
36
+ },
37
+ ],
38
+ [
39
+ "-0.000654",
40
+ {
41
+ dec128: "-0.0009876543",
42
+ int1: 2,
43
+ location: "California",
44
+ groupId: 3,
45
+ },
46
+ ],
47
+ [
48
+ "9876.123456",
49
+ {
50
+ dec128: "1234567890.0987654321",
51
+ int1: 1,
52
+ location: "California",
53
+ groupId: 3,
54
+ },
55
+ ],
56
+ ]);
57
+ describe("TDWebSocket.WsSql()", () => {
58
+ jest.setTimeout(20 * 1000);
59
+ test("insert recoder", async () => {
60
+ let conf = new config_1.WSConfig(dns);
61
+ conf.setUser((0, utils_1.testUsername)());
62
+ conf.setPwd((0, utils_1.testPassword)());
63
+ let wsSql = await wsSql_1.WsSql.open(conf);
64
+ let taosResult = await wsSql.exec("use power");
65
+ console.log(taosResult);
66
+ expect(taosResult).toBeTruthy();
67
+ taosResult = await wsSql.exec("describe decimal_test");
68
+ console.log(taosResult);
69
+ taosResult = await wsSql.exec('INSERT INTO d1001 USING decimal_test (location, groupid) TAGS ("California", 3) VALUES (NOW, "9876.123456", "1234567890.0987654321", 1) (NOW + 1a, "-0.000654", "-0.0009876543", 2) (NOW + 2a, "-1234.654321", "-123456789012.0987654321", 3)');
70
+ console.log(taosResult);
71
+ expect(taosResult.getAffectRows()).toBeGreaterThanOrEqual(3);
72
+ let wsRows = await wsSql.query("select * from decimal_test");
73
+ expect(wsRows).toBeTruthy();
74
+ let meta = wsRows.getMeta();
75
+ expect(meta).toBeTruthy();
76
+ console.log("wsRow:meta:=>", meta);
77
+ let count = 0;
78
+ while (await wsRows.next()) {
79
+ let result = wsRows.getData();
80
+ if (result != null && result.length > 0) {
81
+ if (expectedResultsMap.has(result[1])) {
82
+ console.log("result:=>", result);
83
+ const expected = expectedResultsMap.get(result[1]);
84
+ expect(result[2]).toBe(expected?.dec128);
85
+ expect(result[3]).toBe(expected?.int1);
86
+ expect(result[4]).toBe(expected?.location);
87
+ expect(result[5]).toBe(expected?.groupId);
88
+ count++;
89
+ }
90
+ }
91
+ }
92
+ await wsSql.close();
93
+ expect(count).toBe(3);
94
+ });
95
+ });
96
+ test("normal Subscribe", async () => {
97
+ let configMap = new Map([
98
+ [constant_1.TMQConstants.GROUP_ID, "gId"],
99
+ [constant_1.TMQConstants.CONNECT_USER, (0, utils_1.testUsername)()],
100
+ [constant_1.TMQConstants.CONNECT_PASS, (0, utils_1.testPassword)()],
101
+ [constant_1.TMQConstants.AUTO_OFFSET_RESET, "earliest"],
102
+ [constant_1.TMQConstants.CLIENT_ID, "test_tmq_client"],
103
+ [constant_1.TMQConstants.WS_URL, dns],
104
+ [constant_1.TMQConstants.ENABLE_AUTO_COMMIT, "true"],
105
+ [constant_1.TMQConstants.AUTO_COMMIT_INTERVAL_MS, "1000"],
106
+ ["session.timeout.ms", "10000"],
107
+ ["max.poll.interval.ms", "30000"],
108
+ ["msg.with.table.name", "true"],
109
+ ]);
110
+ let consumer = await wsTmq_1.WsConsumer.newConsumer(configMap);
111
+ await consumer.subscribe(["topic_decimal_test"]);
112
+ let assignment = await consumer.assignment();
113
+ console.log(assignment);
114
+ let useTime = [];
115
+ let count = 0;
116
+ for (let i = 0; i < 5; i++) {
117
+ let startTime = new Date().getTime();
118
+ let res = await consumer.poll(500);
119
+ let currTime = new Date().getTime();
120
+ useTime.push(Math.abs(currTime - startTime));
121
+ for (let [key, value] of res) {
122
+ console.log(key, value.getMeta());
123
+ let data = value.getData();
124
+ if (data == null || data.length == 0) {
125
+ break;
126
+ }
127
+ for (let record of data) {
128
+ console.log("record:=----------->", record);
129
+ if (expectedResultsMap.has(record[1])) {
130
+ const expected = expectedResultsMap.get(record[1]);
131
+ expect(record[2]).toBe(expected?.dec128);
132
+ expect(record[3]).toBe(expected?.int1);
133
+ expect(record[4]).toBe(expected?.location);
134
+ expect(record[5]).toBe(expected?.groupId);
135
+ count++;
136
+ }
137
+ }
138
+ }
139
+ }
140
+ await consumer.unsubscribe();
141
+ await consumer.close();
142
+ expect(count).toBe(3);
143
+ });
144
+ afterAll(async () => {
145
+ let conf = new config_1.WSConfig(dns);
146
+ conf.setUser((0, utils_1.testUsername)());
147
+ conf.setPwd((0, utils_1.testPassword)());
148
+ let wsSql = await wsSql_1.WsSql.open(conf);
149
+ await wsSql.exec(dropTopic);
150
+ await wsSql.exec("drop database power");
151
+ await wsSql.close();
152
+ wsConnectorPool_1.WebSocketConnectionPool.instance().destroyed();
153
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=queryTables.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryTables.test.d.ts","sourceRoot":"","sources":["../../../../test/sql/core/queryTables.test.ts"],"names":[],"mappings":""}