@platformatic/kafka 0.1.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 (223) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +270 -0
  3. package/dist/apis/admin/alter-client-quotas.d.ts +33 -0
  4. package/dist/apis/admin/alter-client-quotas.js +64 -0
  5. package/dist/apis/admin/alter-configs.d.ts +26 -0
  6. package/dist/apis/admin/alter-configs.js +57 -0
  7. package/dist/apis/admin/alter-partition-reassignments.d.ts +30 -0
  8. package/dist/apis/admin/alter-partition-reassignments.js +68 -0
  9. package/dist/apis/admin/alter-partition.d.ts +39 -0
  10. package/dist/apis/admin/alter-partition.js +87 -0
  11. package/dist/apis/admin/alter-replica-log-dirs.d.ts +26 -0
  12. package/dist/apis/admin/alter-replica-log-dirs.js +55 -0
  13. package/dist/apis/admin/alter-user-scram-credentials.d.ts +27 -0
  14. package/dist/apis/admin/alter-user-scram-credentials.js +60 -0
  15. package/dist/apis/admin/consumer-group-describe.d.ts +41 -0
  16. package/dist/apis/admin/consumer-group-describe.js +103 -0
  17. package/dist/apis/admin/create-acls.d.ts +24 -0
  18. package/dist/apis/admin/create-acls.js +55 -0
  19. package/dist/apis/admin/create-delegation-token.d.ts +24 -0
  20. package/dist/apis/admin/create-delegation-token.js +54 -0
  21. package/dist/apis/admin/create-partitions.d.ts +24 -0
  22. package/dist/apis/admin/create-partitions.js +54 -0
  23. package/dist/apis/admin/create-topics.d.ts +42 -0
  24. package/dist/apis/admin/create-topics.js +86 -0
  25. package/dist/apis/admin/delete-acls.d.ts +36 -0
  26. package/dist/apis/admin/delete-acls.js +82 -0
  27. package/dist/apis/admin/delete-groups.d.ts +14 -0
  28. package/dist/apis/admin/delete-groups.js +40 -0
  29. package/dist/apis/admin/delete-records.d.ts +27 -0
  30. package/dist/apis/admin/delete-records.js +59 -0
  31. package/dist/apis/admin/delete-topics.d.ts +21 -0
  32. package/dist/apis/admin/delete-topics.js +50 -0
  33. package/dist/apis/admin/describe-acls.d.ts +25 -0
  34. package/dist/apis/admin/describe-acls.js +66 -0
  35. package/dist/apis/admin/describe-client-quotas.d.ts +30 -0
  36. package/dist/apis/admin/describe-client-quotas.js +57 -0
  37. package/dist/apis/admin/describe-cluster.d.ts +23 -0
  38. package/dist/apis/admin/describe-cluster.js +50 -0
  39. package/dist/apis/admin/describe-configs.d.ts +38 -0
  40. package/dist/apis/admin/describe-configs.js +85 -0
  41. package/dist/apis/admin/describe-delegation-token.d.ts +31 -0
  42. package/dist/apis/admin/describe-delegation-token.js +62 -0
  43. package/dist/apis/admin/describe-groups.d.ts +28 -0
  44. package/dist/apis/admin/describe-groups.js +67 -0
  45. package/dist/apis/admin/describe-log-dirs.d.ts +32 -0
  46. package/dist/apis/admin/describe-log-dirs.js +75 -0
  47. package/dist/apis/admin/describe-producers.d.ts +33 -0
  48. package/dist/apis/admin/describe-producers.js +70 -0
  49. package/dist/apis/admin/describe-quorum.d.ts +50 -0
  50. package/dist/apis/admin/describe-quorum.js +116 -0
  51. package/dist/apis/admin/describe-topic-partitions.d.ts +42 -0
  52. package/dist/apis/admin/describe-topic-partitions.js +94 -0
  53. package/dist/apis/admin/describe-transactions.d.ts +24 -0
  54. package/dist/apis/admin/describe-transactions.js +59 -0
  55. package/dist/apis/admin/describe-user-scram-credentials.d.ts +26 -0
  56. package/dist/apis/admin/describe-user-scram-credentials.js +62 -0
  57. package/dist/apis/admin/envelope.d.ts +10 -0
  58. package/dist/apis/admin/envelope.js +32 -0
  59. package/dist/apis/admin/expire-delegation-token.d.ts +11 -0
  60. package/dist/apis/admin/expire-delegation-token.js +29 -0
  61. package/dist/apis/admin/incremental-alter-configs.d.ts +27 -0
  62. package/dist/apis/admin/incremental-alter-configs.js +58 -0
  63. package/dist/apis/admin/index.d.ts +37 -0
  64. package/dist/apis/admin/index.js +37 -0
  65. package/dist/apis/admin/list-groups.d.ts +18 -0
  66. package/dist/apis/admin/list-groups.js +43 -0
  67. package/dist/apis/admin/list-partition-reassignments.d.ts +27 -0
  68. package/dist/apis/admin/list-partition-reassignments.js +56 -0
  69. package/dist/apis/admin/list-transactions.d.ts +18 -0
  70. package/dist/apis/admin/list-transactions.js +45 -0
  71. package/dist/apis/admin/offset-delete.d.ts +26 -0
  72. package/dist/apis/admin/offset-delete.js +59 -0
  73. package/dist/apis/admin/renew-delegation-token.d.ts +11 -0
  74. package/dist/apis/admin/renew-delegation-token.js +29 -0
  75. package/dist/apis/admin/unregister-broker.d.ts +12 -0
  76. package/dist/apis/admin/unregister-broker.js +28 -0
  77. package/dist/apis/admin/update-features.d.ts +23 -0
  78. package/dist/apis/admin/update-features.js +60 -0
  79. package/dist/apis/consumer/consumer-group-heartbeat.d.ts +27 -0
  80. package/dist/apis/consumer/consumer-group-heartbeat.js +70 -0
  81. package/dist/apis/consumer/fetch.d.ts +46 -0
  82. package/dist/apis/consumer/fetch.js +121 -0
  83. package/dist/apis/consumer/heartbeat.d.ts +11 -0
  84. package/dist/apis/consumer/heartbeat.js +34 -0
  85. package/dist/apis/consumer/index.d.ts +9 -0
  86. package/dist/apis/consumer/index.js +9 -0
  87. package/dist/apis/consumer/join-group.d.ts +27 -0
  88. package/dist/apis/consumer/join-group.js +71 -0
  89. package/dist/apis/consumer/leave-group.d.ts +22 -0
  90. package/dist/apis/consumer/leave-group.js +57 -0
  91. package/dist/apis/consumer/list-offsets.d.ts +30 -0
  92. package/dist/apis/consumer/list-offsets.js +68 -0
  93. package/dist/apis/consumer/offset-commit.d.ts +29 -0
  94. package/dist/apis/consumer/offset-commit.js +68 -0
  95. package/dist/apis/consumer/offset-fetch.d.ts +37 -0
  96. package/dist/apis/consumer/offset-fetch.js +81 -0
  97. package/dist/apis/consumer/sync-group.d.ts +18 -0
  98. package/dist/apis/consumer/sync-group.js +49 -0
  99. package/dist/apis/definitions.d.ts +16 -0
  100. package/dist/apis/definitions.js +12 -0
  101. package/dist/apis/enumerations.d.ts +114 -0
  102. package/dist/apis/enumerations.js +78 -0
  103. package/dist/apis/index.d.ts +8 -0
  104. package/dist/apis/index.js +10 -0
  105. package/dist/apis/metadata/api-versions.d.ts +17 -0
  106. package/dist/apis/metadata/api-versions.js +41 -0
  107. package/dist/apis/metadata/find-coordinator.d.ts +19 -0
  108. package/dist/apis/metadata/find-coordinator.js +50 -0
  109. package/dist/apis/metadata/index.d.ts +3 -0
  110. package/dist/apis/metadata/index.js +3 -0
  111. package/dist/apis/metadata/metadata.d.ts +37 -0
  112. package/dist/apis/metadata/metadata.js +92 -0
  113. package/dist/apis/producer/add-offsets-to-txn.d.ts +10 -0
  114. package/dist/apis/producer/add-offsets-to-txn.js +34 -0
  115. package/dist/apis/producer/add-partitions-to-txn.d.ts +34 -0
  116. package/dist/apis/producer/add-partitions-to-txn.js +79 -0
  117. package/dist/apis/producer/end-txn.d.ts +10 -0
  118. package/dist/apis/producer/end-txn.js +34 -0
  119. package/dist/apis/producer/index.d.ts +6 -0
  120. package/dist/apis/producer/index.js +6 -0
  121. package/dist/apis/producer/init-producer-id.d.ts +21 -0
  122. package/dist/apis/producer/init-producer-id.js +38 -0
  123. package/dist/apis/producer/produce.d.ts +29 -0
  124. package/dist/apis/producer/produce.js +104 -0
  125. package/dist/apis/producer/txn-offset-commit.d.ts +29 -0
  126. package/dist/apis/producer/txn-offset-commit.js +77 -0
  127. package/dist/apis/security/index.d.ts +2 -0
  128. package/dist/apis/security/index.js +2 -0
  129. package/dist/apis/security/sasl-authenticate.d.ts +15 -0
  130. package/dist/apis/security/sasl-authenticate.js +30 -0
  131. package/dist/apis/security/sasl-handshake.d.ts +10 -0
  132. package/dist/apis/security/sasl-handshake.js +28 -0
  133. package/dist/apis/telemetry/get-telemetry-subscriptions.d.ts +18 -0
  134. package/dist/apis/telemetry/get-telemetry-subscriptions.js +46 -0
  135. package/dist/apis/telemetry/index.d.ts +3 -0
  136. package/dist/apis/telemetry/index.js +3 -0
  137. package/dist/apis/telemetry/list-client-metrics-resources.d.ts +14 -0
  138. package/dist/apis/telemetry/list-client-metrics-resources.js +32 -0
  139. package/dist/apis/telemetry/push-telemetry.d.ts +10 -0
  140. package/dist/apis/telemetry/push-telemetry.js +36 -0
  141. package/dist/clients/admin/admin.d.ts +18 -0
  142. package/dist/clients/admin/admin.js +322 -0
  143. package/dist/clients/admin/index.d.ts +3 -0
  144. package/dist/clients/admin/index.js +3 -0
  145. package/dist/clients/admin/options.d.ts +135 -0
  146. package/dist/clients/admin/options.js +81 -0
  147. package/dist/clients/admin/types.d.ts +56 -0
  148. package/dist/clients/admin/types.js +1 -0
  149. package/dist/clients/base/base.d.ts +48 -0
  150. package/dist/clients/base/base.js +242 -0
  151. package/dist/clients/base/index.d.ts +3 -0
  152. package/dist/clients/base/index.js +3 -0
  153. package/dist/clients/base/options.d.ts +115 -0
  154. package/dist/clients/base/options.js +59 -0
  155. package/dist/clients/base/types.d.ts +38 -0
  156. package/dist/clients/base/types.js +1 -0
  157. package/dist/clients/callbacks.d.ts +8 -0
  158. package/dist/clients/callbacks.js +42 -0
  159. package/dist/clients/consumer/consumer.d.ts +33 -0
  160. package/dist/clients/consumer/consumer.js +767 -0
  161. package/dist/clients/consumer/index.d.ts +5 -0
  162. package/dist/clients/consumer/index.js +5 -0
  163. package/dist/clients/consumer/messages-stream.d.ts +56 -0
  164. package/dist/clients/consumer/messages-stream.js +404 -0
  165. package/dist/clients/consumer/options.d.ts +521 -0
  166. package/dist/clients/consumer/options.js +177 -0
  167. package/dist/clients/consumer/topics-map.d.ts +8 -0
  168. package/dist/clients/consumer/topics-map.js +48 -0
  169. package/dist/clients/consumer/types.d.ts +74 -0
  170. package/dist/clients/consumer/types.js +11 -0
  171. package/dist/clients/index.d.ts +6 -0
  172. package/dist/clients/index.js +6 -0
  173. package/dist/clients/producer/index.d.ts +3 -0
  174. package/dist/clients/producer/index.js +3 -0
  175. package/dist/clients/producer/options.d.ts +122 -0
  176. package/dist/clients/producer/options.js +47 -0
  177. package/dist/clients/producer/producer.d.ts +13 -0
  178. package/dist/clients/producer/producer.js +272 -0
  179. package/dist/clients/producer/types.d.ts +29 -0
  180. package/dist/clients/producer/types.js +1 -0
  181. package/dist/clients/serde.d.ts +40 -0
  182. package/dist/clients/serde.js +49 -0
  183. package/dist/errors.d.ts +67 -0
  184. package/dist/errors.js +160 -0
  185. package/dist/index.d.ts +6 -0
  186. package/dist/index.js +10 -0
  187. package/dist/network/connection-pool.d.ts +11 -0
  188. package/dist/network/connection-pool.js +101 -0
  189. package/dist/network/connection.d.ts +49 -0
  190. package/dist/network/connection.js +319 -0
  191. package/dist/network/index.d.ts +2 -0
  192. package/dist/network/index.js +2 -0
  193. package/dist/protocol/apis.d.ts +2 -0
  194. package/dist/protocol/apis.js +191 -0
  195. package/dist/protocol/compression.d.ts +70 -0
  196. package/dist/protocol/compression.js +114 -0
  197. package/dist/protocol/crc32c.d.ts +2 -0
  198. package/dist/protocol/crc32c.js +83 -0
  199. package/dist/protocol/definitions.d.ts +12 -0
  200. package/dist/protocol/definitions.js +11 -0
  201. package/dist/protocol/dynamic-buffer.d.ts +65 -0
  202. package/dist/protocol/dynamic-buffer.js +557 -0
  203. package/dist/protocol/errors.d.ts +8 -0
  204. package/dist/protocol/errors.js +908 -0
  205. package/dist/protocol/index.d.ts +14 -0
  206. package/dist/protocol/index.js +14 -0
  207. package/dist/protocol/murmur2.d.ts +1 -0
  208. package/dist/protocol/murmur2.js +55 -0
  209. package/dist/protocol/reader.d.ts +58 -0
  210. package/dist/protocol/reader.js +296 -0
  211. package/dist/protocol/records.d.ts +110 -0
  212. package/dist/protocol/records.js +149 -0
  213. package/dist/protocol/sasl/plain.d.ts +3 -0
  214. package/dist/protocol/sasl/plain.js +3 -0
  215. package/dist/protocol/sasl/scram-sha.d.ts +28 -0
  216. package/dist/protocol/sasl/scram-sha.js +104 -0
  217. package/dist/protocol/varint.d.ts +12 -0
  218. package/dist/protocol/varint.js +36 -0
  219. package/dist/protocol/writer.d.ts +48 -0
  220. package/dist/protocol/writer.js +223 -0
  221. package/dist/utils.d.ts +20 -0
  222. package/dist/utils.js +127 -0
  223. package/package.json +75 -0
@@ -0,0 +1,319 @@
1
+ import fastq from 'fastq';
2
+ import EventEmitter from 'node:events';
3
+ import { createConnection } from 'node:net';
4
+ import { connect as createTLSConnection } from 'node:tls';
5
+ import { createPromisifiedCallback, kCallbackPromise } from "../clients/callbacks.js";
6
+ import { NetworkError, TimeoutError, UnexpectedCorrelationIdError } from "../errors.js";
7
+ import { protocolAPIsById } from "../protocol/apis.js";
8
+ import { EMPTY_OR_SINGLE_COMPACT_LENGTH_SIZE, INT32_SIZE } from "../protocol/definitions.js";
9
+ import { DynamicBuffer } from "../protocol/dynamic-buffer.js";
10
+ import { Reader } from "../protocol/reader.js";
11
+ import { Writer } from "../protocol/writer.js";
12
+ import { loggers } from "../utils.js";
13
+ export const ConnectionStatuses = {
14
+ NONE: 'none',
15
+ CONNECTING: 'connecting',
16
+ CONNECTED: 'connected',
17
+ CLOSED: 'closed',
18
+ CLOSING: 'closing',
19
+ ERROR: 'error'
20
+ };
21
+ export const defaultOptions = {
22
+ connectTimeout: 5000,
23
+ maxInflights: 5
24
+ };
25
+ const kNoResponse = Symbol('plt.kafka.noResponse');
26
+ /* c8 ignore next */
27
+ export function noResponseCallback(..._) { }
28
+ noResponseCallback[kNoResponse] = true;
29
+ export class Connection extends EventEmitter {
30
+ #options;
31
+ #status;
32
+ #clientId;
33
+ // @ts-ignore This is used just for debugging
34
+ #ownerId;
35
+ #correlationId;
36
+ #nextMessage;
37
+ #afterDrainRequests;
38
+ #requestsQueue;
39
+ #inflightRequests;
40
+ #responseBuffer;
41
+ #responseReader;
42
+ #socket;
43
+ #socketMustBeDrained;
44
+ constructor(clientId, options = {}) {
45
+ super();
46
+ this.setMaxListeners(0);
47
+ this.#options = Object.assign({}, defaultOptions, options);
48
+ this.#status = ConnectionStatuses.NONE;
49
+ this.#clientId = clientId;
50
+ this.#ownerId = options.ownerId;
51
+ this.#correlationId = 0;
52
+ this.#nextMessage = 0;
53
+ this.#afterDrainRequests = [];
54
+ this.#requestsQueue = fastq((op, cb) => op(cb), this.#options.maxInflights);
55
+ this.#inflightRequests = new Map();
56
+ this.#responseBuffer = new DynamicBuffer();
57
+ this.#responseReader = new Reader(this.#responseBuffer);
58
+ this.#socketMustBeDrained = false;
59
+ }
60
+ get status() {
61
+ return this.#status;
62
+ }
63
+ get socket() {
64
+ return this.#socket;
65
+ }
66
+ connect(host, port, callback) {
67
+ if (!callback) {
68
+ callback = createPromisifiedCallback();
69
+ }
70
+ if (this.#status === ConnectionStatuses.CONNECTED) {
71
+ callback(null);
72
+ return callback[kCallbackPromise];
73
+ }
74
+ this.ready(callback);
75
+ if (this.#status === ConnectionStatuses.CONNECTING) {
76
+ return callback[kCallbackPromise];
77
+ }
78
+ this.#status = ConnectionStatuses.CONNECTING;
79
+ const connectionOptions = {
80
+ timeout: this.#options.connectTimeout
81
+ };
82
+ const connectionTimeoutHandler = () => {
83
+ const error = new TimeoutError(`Connection to ${host}:${port} timed out.`);
84
+ this.#socket.destroy();
85
+ this.#status = ConnectionStatuses.ERROR;
86
+ this.emit('timeout', error);
87
+ this.emit('error', error);
88
+ };
89
+ const connectionErrorHandler = (e) => {
90
+ const error = new NetworkError(`Connection to ${host}:${port} failed.`, { cause: e });
91
+ this.#status = ConnectionStatuses.ERROR;
92
+ this.emit('error', error);
93
+ };
94
+ this.emit('connecting');
95
+ /* c8 ignore next 3 */
96
+ this.#socket = this.#options.tls
97
+ ? createTLSConnection(port, host, { ...this.#options.tls, ...connectionOptions })
98
+ : createConnection({ ...connectionOptions, port, host });
99
+ this.#socket.setNoDelay(true);
100
+ this.#socket.once('connect', () => {
101
+ this.#socket.removeListener('timeout', connectionTimeoutHandler);
102
+ this.#socket.removeListener('error', connectionErrorHandler);
103
+ this.#socket.on('error', this.#onError.bind(this));
104
+ this.#socket.on('data', this.#onData.bind(this));
105
+ this.#socket.on('drain', this.#onDrain.bind(this));
106
+ this.#socket.on('close', this.#onClose.bind(this));
107
+ this.#socket.setTimeout(0);
108
+ this.#status = ConnectionStatuses.CONNECTED;
109
+ this.emit('connect');
110
+ });
111
+ this.#socket.once('timeout', connectionTimeoutHandler);
112
+ this.#socket.once('error', connectionErrorHandler);
113
+ return callback[kCallbackPromise];
114
+ }
115
+ ready(callback) {
116
+ if (!callback) {
117
+ callback = createPromisifiedCallback();
118
+ }
119
+ const onConnect = () => {
120
+ this.removeListener('error', onError);
121
+ callback(null);
122
+ };
123
+ const onError = (error) => {
124
+ this.removeListener('connect', onConnect);
125
+ callback(error);
126
+ };
127
+ this.once('connect', onConnect);
128
+ this.once('error', onError);
129
+ this.emit('ready');
130
+ return callback[kCallbackPromise];
131
+ }
132
+ close(callback) {
133
+ if (!callback) {
134
+ callback = createPromisifiedCallback();
135
+ }
136
+ if (this.#status === ConnectionStatuses.CLOSED ||
137
+ this.#status === ConnectionStatuses.ERROR ||
138
+ this.#status === ConnectionStatuses.NONE) {
139
+ callback(null);
140
+ return callback[kCallbackPromise];
141
+ }
142
+ else if (this.#status === ConnectionStatuses.CLOSING) {
143
+ this.once('close', () => {
144
+ callback(null);
145
+ });
146
+ return callback[kCallbackPromise];
147
+ }
148
+ // Ignore all disconnection errors
149
+ this.#socket.removeAllListeners('error');
150
+ this.#socket.once('error', () => { });
151
+ this.#socket.once('close', () => {
152
+ this.#status = ConnectionStatuses.CLOSED;
153
+ this.emit('close');
154
+ callback(null);
155
+ });
156
+ this.#status = ConnectionStatuses.CLOSING;
157
+ this.emit('closing');
158
+ this.#socket.end();
159
+ return callback[kCallbackPromise];
160
+ }
161
+ send(apiKey, apiVersion, payload, responseParser, hasRequestHeaderTaggedFields, hasResponseHeaderTaggedFields, callback) {
162
+ this.#requestsQueue.push(fastQueueCallback => {
163
+ const correlationId = ++this.#correlationId;
164
+ const request = {
165
+ correlationId,
166
+ apiKey,
167
+ apiVersion,
168
+ hasRequestHeaderTaggedFields,
169
+ hasResponseHeaderTaggedFields,
170
+ parser: responseParser,
171
+ payload,
172
+ callback: fastQueueCallback
173
+ };
174
+ if (this.#socketMustBeDrained) {
175
+ this.#afterDrainRequests.push(request);
176
+ return false;
177
+ }
178
+ return this.#sendRequest(request);
179
+ }, callback);
180
+ }
181
+ /*
182
+ Request => Size [Request Header v2] [payload]
183
+ Request Header v2 => request_api_key request_api_version correlation_id client_id TAG_BUFFER
184
+ request_api_key => INT16
185
+ request_api_version => INT16
186
+ correlation_id => INT32
187
+ client_id => NULLABLE_STRING
188
+ */
189
+ #sendRequest(request) {
190
+ if (this.#status !== ConnectionStatuses.CONNECTED) {
191
+ request.callback(new NetworkError('Connection closed'), undefined);
192
+ return false;
193
+ }
194
+ let canWrite = true;
195
+ const { correlationId, apiKey, apiVersion, payload: payloadFn, hasRequestHeaderTaggedFields } = request;
196
+ const writer = Writer.create()
197
+ .appendInt16(apiKey)
198
+ .appendInt16(apiVersion)
199
+ .appendInt32(correlationId)
200
+ .appendString(this.#clientId, false);
201
+ if (hasRequestHeaderTaggedFields) {
202
+ writer.appendTaggedFields();
203
+ }
204
+ const payload = payloadFn();
205
+ writer.appendFrom(payload);
206
+ writer.prependLength();
207
+ // Write the header
208
+ this.#socket.cork();
209
+ if (!payload.context.noResponse) {
210
+ this.#inflightRequests.set(correlationId, request);
211
+ }
212
+ /* c8 ignore next */
213
+ loggers.protocol({ apiKey: protocolAPIsById[apiKey], correlationId, request }, 'Sending request.');
214
+ for (const buf of writer.buffers) {
215
+ if (!this.#socket.write(buf)) {
216
+ canWrite = false;
217
+ }
218
+ }
219
+ if (!canWrite) {
220
+ this.#socketMustBeDrained = true;
221
+ }
222
+ this.#socket.uncork();
223
+ if (payload.context.noResponse) {
224
+ request.callback(null, canWrite);
225
+ }
226
+ // debugDump(Date.now() % 100000, 'send', { owner: this.#ownerId, apiKey: protocolAPIsById[apiKey], correlationId })
227
+ return canWrite;
228
+ }
229
+ /*
230
+ Response Header v1 => correlation_id TAG_BUFFER
231
+ correlation_id => INT32
232
+ */
233
+ #onData(chunk) {
234
+ this.#responseBuffer.append(chunk);
235
+ // There is at least one message size to add
236
+ // Note that here the initial position is always 0
237
+ while (this.#responseBuffer.length > INT32_SIZE) {
238
+ if (this.#nextMessage < 1) {
239
+ this.#nextMessage = this.#responseReader.readInt32();
240
+ }
241
+ // Less data than the message size, wait for more data
242
+ if (this.#nextMessage > this.#responseBuffer.length - INT32_SIZE) {
243
+ break;
244
+ }
245
+ // Read the correlationId and get the handler
246
+ const correlationId = this.#responseReader.readInt32();
247
+ const request = this.#inflightRequests.get(correlationId);
248
+ if (!request) {
249
+ this.emit('error', new UnexpectedCorrelationIdError(`Received unexpected response with correlation_id=${correlationId}`, {
250
+ raw: this.#responseReader.buffer.slice(0, this.#nextMessage + INT32_SIZE)
251
+ }));
252
+ return;
253
+ }
254
+ this.#inflightRequests.delete(correlationId);
255
+ const { apiKey, apiVersion, hasResponseHeaderTaggedFields, parser, callback } = request;
256
+ let deserialized;
257
+ let responseError = null;
258
+ try {
259
+ // Due to inconsistency in the wire protocol, the tag buffer in the header might have to be handled by the APIs
260
+ // For example: https://github.com/apache/kafka/blob/84caaa6e9da06435411510a81fa321d4f99c351f/clients/src/main/resources/common/message/ApiVersionsResponse.json#L24
261
+ if (hasResponseHeaderTaggedFields) {
262
+ this.#responseReader.skip(EMPTY_OR_SINGLE_COMPACT_LENGTH_SIZE);
263
+ }
264
+ deserialized = parser(correlationId, apiKey, apiVersion, new Reader(this.#responseReader.buffer.subarray(this.#responseReader.position, this.#nextMessage + INT32_SIZE)));
265
+ }
266
+ catch (error) {
267
+ responseError = error;
268
+ // debugDump(Date.now() % 100000, 'received error', {
269
+ // owner: this.#ownerId,
270
+ // apiKey: protocolAPIsById[apiKey],
271
+ // error
272
+ // })
273
+ }
274
+ finally {
275
+ this.#responseBuffer.consume(this.#nextMessage + INT32_SIZE);
276
+ this.#responseReader.position = 0;
277
+ this.#nextMessage = -1;
278
+ }
279
+ // debugDump(Date.now() % 100000, 'receive', {
280
+ // owner: this.#ownerId,
281
+ // apiKey: protocolAPIsById[apiKey],
282
+ // correlationId
283
+ // })
284
+ /* c8 ignore next */
285
+ loggers.protocol({ apiKey: protocolAPIsById[apiKey], correlationId, request }, 'Received response.');
286
+ callback(responseError, deserialized);
287
+ }
288
+ }
289
+ #onDrain() {
290
+ // First of all, send all the requests that were waiting for the socket to drain
291
+ while (this.#afterDrainRequests.length) {
292
+ const request = this.#afterDrainRequests.shift();
293
+ // If no more request or after sending the request the socket is blocked again, abort
294
+ if (!request || !this.#sendRequest(request)) {
295
+ return;
296
+ }
297
+ }
298
+ // Start getting requests again
299
+ this.#socketMustBeDrained = false;
300
+ this.emit('drain');
301
+ }
302
+ #onClose() {
303
+ this.#status = ConnectionStatuses.CLOSED;
304
+ this.emit('close');
305
+ const error = new NetworkError('Connection closed');
306
+ for (const request of this.#afterDrainRequests) {
307
+ const payload = request.payload();
308
+ if (!payload.context.noResponse) {
309
+ request.callback(error, undefined);
310
+ }
311
+ }
312
+ for (const inflight of this.#inflightRequests.values()) {
313
+ inflight.callback(error, undefined);
314
+ }
315
+ }
316
+ #onError(error) {
317
+ this.emit('error', new NetworkError('Connection error', { cause: error }));
318
+ }
319
+ }
@@ -0,0 +1,2 @@
1
+ export * from './connection-pool.ts';
2
+ export * from './connection.ts';
@@ -0,0 +1,2 @@
1
+ export * from "./connection-pool.js";
2
+ export * from "./connection.js";
@@ -0,0 +1,2 @@
1
+ export declare const protocolAPIsByName: Record<string, number>;
2
+ export declare const protocolAPIsById: Record<number, string>;
@@ -0,0 +1,191 @@
1
+ // This is autogenerated from the generate:apis script, do not edit manually.
2
+ export const protocolAPIsByName = Object.freeze({
3
+ AddOffsetsToTxn: 25,
4
+ AddPartitionsToTxn: 24,
5
+ AddRaftVoter: 80,
6
+ AllocateProducerIds: 67,
7
+ AlterClientQuotas: 49,
8
+ AlterConfigs: 33,
9
+ AlterPartitionReassignments: 45,
10
+ AlterPartition: 56,
11
+ AlterReplicaLogDirs: 34,
12
+ AlterShareGroupOffsets: 91,
13
+ AlterUserScramCredentials: 51,
14
+ ApiVersions: 18,
15
+ AssignReplicasToDirs: 73,
16
+ BeginQuorumEpoch: 53,
17
+ BrokerHeartbeat: 63,
18
+ BrokerRegistration: 62,
19
+ ConsumerGroupDescribe: 69,
20
+ ConsumerGroupHeartbeat: 68,
21
+ ControlledShutdown: 7,
22
+ ControllerRegistration: 70,
23
+ CreateAcls: 30,
24
+ CreateDelegationToken: 38,
25
+ CreatePartitions: 37,
26
+ CreateTopics: 19,
27
+ DeleteAcls: 31,
28
+ DeleteGroups: 42,
29
+ DeleteRecords: 21,
30
+ DeleteShareGroupOffsets: 92,
31
+ DeleteShareGroupState: 86,
32
+ DeleteTopics: 20,
33
+ DescribeAcls: 29,
34
+ DescribeClientQuotas: 48,
35
+ DescribeCluster: 60,
36
+ DescribeConfigs: 32,
37
+ DescribeDelegationToken: 41,
38
+ DescribeGroups: 15,
39
+ DescribeLogDirs: 35,
40
+ DescribeProducers: 61,
41
+ DescribeQuorum: 55,
42
+ DescribeShareGroupOffsets: 90,
43
+ DescribeTopicPartitions: 75,
44
+ DescribeTransactions: 65,
45
+ DescribeUserScramCredentials: 50,
46
+ ElectLeaders: 43,
47
+ EndQuorumEpoch: 54,
48
+ EndTxn: 26,
49
+ Envelope: 58,
50
+ ExpireDelegationToken: 40,
51
+ Fetch: 1,
52
+ FetchSnapshot: 59,
53
+ FindCoordinator: 10,
54
+ GetTelemetrySubscriptions: 71,
55
+ Heartbeat: 12,
56
+ IncrementalAlterConfigs: 44,
57
+ InitProducerId: 22,
58
+ InitializeShareGroupState: 83,
59
+ JoinGroup: 11,
60
+ LeaderAndIsr: 4,
61
+ LeaveGroup: 13,
62
+ ListClientMetricsResources: 74,
63
+ ListGroups: 16,
64
+ ListOffsets: 2,
65
+ ListPartitionReassignments: 46,
66
+ ListTransactions: 66,
67
+ Metadata: 3,
68
+ OffsetCommit: 8,
69
+ OffsetDelete: 47,
70
+ OffsetFetch: 9,
71
+ OffsetForLeaderEpoch: 23,
72
+ Produce: 0,
73
+ PushTelemetry: 72,
74
+ ReadShareGroupState: 84,
75
+ ReadShareGroupStateSummary: 87,
76
+ RemoveRaftVoter: 81,
77
+ RenewDelegationToken: 39,
78
+ SaslAuthenticate: 36,
79
+ SaslHandshake: 17,
80
+ ShareAcknowledge: 79,
81
+ ShareFetch: 78,
82
+ ShareGroupDescribe: 77,
83
+ ShareGroupHeartbeat: 76,
84
+ StopReplica: 5,
85
+ StreamsGroupDescribe: 89,
86
+ StreamsGroupHeartbeat: 88,
87
+ SyncGroup: 14,
88
+ TxnOffsetCommit: 28,
89
+ UnregisterBroker: 64,
90
+ UpdateFeatures: 57,
91
+ UpdateMetadata: 6,
92
+ UpdateRaftVoter: 82,
93
+ Vote: 52,
94
+ WriteShareGroupState: 85,
95
+ WriteTxnMarkers: 27
96
+ });
97
+ export const protocolAPIsById = Object.freeze({
98
+ 0: 'Produce',
99
+ 1: 'Fetch',
100
+ 2: 'ListOffsets',
101
+ 3: 'Metadata',
102
+ 4: 'LeaderAndIsr',
103
+ 5: 'StopReplica',
104
+ 6: 'UpdateMetadata',
105
+ 7: 'ControlledShutdown',
106
+ 8: 'OffsetCommit',
107
+ 9: 'OffsetFetch',
108
+ 10: 'FindCoordinator',
109
+ 11: 'JoinGroup',
110
+ 12: 'Heartbeat',
111
+ 13: 'LeaveGroup',
112
+ 14: 'SyncGroup',
113
+ 15: 'DescribeGroups',
114
+ 16: 'ListGroups',
115
+ 17: 'SaslHandshake',
116
+ 18: 'ApiVersions',
117
+ 19: 'CreateTopics',
118
+ 20: 'DeleteTopics',
119
+ 21: 'DeleteRecords',
120
+ 22: 'InitProducerId',
121
+ 23: 'OffsetForLeaderEpoch',
122
+ 24: 'AddPartitionsToTxn',
123
+ 25: 'AddOffsetsToTxn',
124
+ 26: 'EndTxn',
125
+ 27: 'WriteTxnMarkers',
126
+ 28: 'TxnOffsetCommit',
127
+ 29: 'DescribeAcls',
128
+ 30: 'CreateAcls',
129
+ 31: 'DeleteAcls',
130
+ 32: 'DescribeConfigs',
131
+ 33: 'AlterConfigs',
132
+ 34: 'AlterReplicaLogDirs',
133
+ 35: 'DescribeLogDirs',
134
+ 36: 'SaslAuthenticate',
135
+ 37: 'CreatePartitions',
136
+ 38: 'CreateDelegationToken',
137
+ 39: 'RenewDelegationToken',
138
+ 40: 'ExpireDelegationToken',
139
+ 41: 'DescribeDelegationToken',
140
+ 42: 'DeleteGroups',
141
+ 43: 'ElectLeaders',
142
+ 44: 'IncrementalAlterConfigs',
143
+ 45: 'AlterPartitionReassignments',
144
+ 46: 'ListPartitionReassignments',
145
+ 47: 'OffsetDelete',
146
+ 48: 'DescribeClientQuotas',
147
+ 49: 'AlterClientQuotas',
148
+ 50: 'DescribeUserScramCredentials',
149
+ 51: 'AlterUserScramCredentials',
150
+ 52: 'Vote',
151
+ 53: 'BeginQuorumEpoch',
152
+ 54: 'EndQuorumEpoch',
153
+ 55: 'DescribeQuorum',
154
+ 56: 'AlterPartition',
155
+ 57: 'UpdateFeatures',
156
+ 58: 'Envelope',
157
+ 59: 'FetchSnapshot',
158
+ 60: 'DescribeCluster',
159
+ 61: 'DescribeProducers',
160
+ 62: 'BrokerRegistration',
161
+ 63: 'BrokerHeartbeat',
162
+ 64: 'UnregisterBroker',
163
+ 65: 'DescribeTransactions',
164
+ 66: 'ListTransactions',
165
+ 67: 'AllocateProducerIds',
166
+ 68: 'ConsumerGroupHeartbeat',
167
+ 69: 'ConsumerGroupDescribe',
168
+ 70: 'ControllerRegistration',
169
+ 71: 'GetTelemetrySubscriptions',
170
+ 72: 'PushTelemetry',
171
+ 73: 'AssignReplicasToDirs',
172
+ 74: 'ListClientMetricsResources',
173
+ 75: 'DescribeTopicPartitions',
174
+ 76: 'ShareGroupHeartbeat',
175
+ 77: 'ShareGroupDescribe',
176
+ 78: 'ShareFetch',
177
+ 79: 'ShareAcknowledge',
178
+ 80: 'AddRaftVoter',
179
+ 81: 'RemoveRaftVoter',
180
+ 82: 'UpdateRaftVoter',
181
+ 83: 'InitializeShareGroupState',
182
+ 84: 'ReadShareGroupState',
183
+ 85: 'WriteShareGroupState',
184
+ 86: 'DeleteShareGroupState',
185
+ 87: 'ReadShareGroupStateSummary',
186
+ 88: 'StreamsGroupHeartbeat',
187
+ 89: 'StreamsGroupDescribe',
188
+ 90: 'DescribeShareGroupOffsets',
189
+ 91: 'AlterShareGroupOffsets',
190
+ 92: 'DeleteShareGroupOffsets'
191
+ });
@@ -0,0 +1,70 @@
1
+ import { DynamicBuffer } from './dynamic-buffer.ts';
2
+ export type SyncCompressionPhase = (data: Buffer | DynamicBuffer) => Buffer;
3
+ export type CompressionOperation = (data: Buffer) => Buffer;
4
+ export interface CompressionAlgorithm {
5
+ compressSync: SyncCompressionPhase;
6
+ decompressSync: SyncCompressionPhase;
7
+ bitmask: number;
8
+ available?: boolean;
9
+ }
10
+ export declare const compressionsAlgorithms: {
11
+ readonly none: {
12
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
13
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
14
+ readonly bitmask: 0;
15
+ readonly available: true;
16
+ };
17
+ readonly gzip: {
18
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
19
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
20
+ readonly bitmask: 1;
21
+ readonly available: true;
22
+ };
23
+ readonly snappy: {
24
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
25
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
26
+ readonly bitmask: 2;
27
+ readonly available: true;
28
+ };
29
+ readonly lz4: {
30
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
31
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
32
+ readonly bitmask: 3;
33
+ readonly available: true;
34
+ };
35
+ readonly zstd: {
36
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
37
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
38
+ readonly bitmask: 4;
39
+ readonly available: boolean;
40
+ };
41
+ };
42
+ export declare const compressionsAlgorithmsByBitmask: {
43
+ [k: string]: {
44
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
45
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
46
+ readonly bitmask: 0;
47
+ readonly available: true;
48
+ } | {
49
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
50
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
51
+ readonly bitmask: 1;
52
+ readonly available: true;
53
+ } | {
54
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
55
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
56
+ readonly bitmask: 2;
57
+ readonly available: true;
58
+ } | {
59
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
60
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
61
+ readonly bitmask: 3;
62
+ readonly available: true;
63
+ } | {
64
+ readonly compressSync: (data: Buffer | DynamicBuffer) => Buffer;
65
+ readonly decompressSync: (data: Buffer | DynamicBuffer) => Buffer;
66
+ readonly bitmask: 4;
67
+ readonly available: boolean;
68
+ };
69
+ };
70
+ export type CompressionAlgorithms = keyof typeof compressionsAlgorithms;