kafka-ts 0.0.1-beta

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 (196) hide show
  1. package/.prettierrc +7 -0
  2. package/LICENSE +24 -0
  3. package/README.md +88 -0
  4. package/certs/ca.crt +29 -0
  5. package/certs/ca.key +52 -0
  6. package/certs/ca.srl +1 -0
  7. package/certs/kafka.crt +29 -0
  8. package/certs/kafka.csr +26 -0
  9. package/certs/kafka.key +52 -0
  10. package/certs/kafka.keystore.jks +0 -0
  11. package/certs/kafka.truststore.jks +0 -0
  12. package/dist/api/api-versions.d.ts +9 -0
  13. package/dist/api/api-versions.js +24 -0
  14. package/dist/api/create-topics.d.ts +38 -0
  15. package/dist/api/create-topics.js +53 -0
  16. package/dist/api/delete-topics.d.ts +18 -0
  17. package/dist/api/delete-topics.js +33 -0
  18. package/dist/api/fetch.d.ts +77 -0
  19. package/dist/api/fetch.js +106 -0
  20. package/dist/api/find-coordinator.d.ts +21 -0
  21. package/dist/api/find-coordinator.js +39 -0
  22. package/dist/api/heartbeat.d.ts +11 -0
  23. package/dist/api/heartbeat.js +27 -0
  24. package/dist/api/index.d.ts +573 -0
  25. package/dist/api/index.js +164 -0
  26. package/dist/api/init-producer-id.d.ts +13 -0
  27. package/dist/api/init-producer-id.js +29 -0
  28. package/dist/api/join-group.d.ts +34 -0
  29. package/dist/api/join-group.js +51 -0
  30. package/dist/api/leave-group.d.ts +19 -0
  31. package/dist/api/leave-group.js +39 -0
  32. package/dist/api/list-offsets.d.ts +29 -0
  33. package/dist/api/list-offsets.js +48 -0
  34. package/dist/api/metadata.d.ts +40 -0
  35. package/dist/api/metadata.js +58 -0
  36. package/dist/api/offset-commit.d.ts +28 -0
  37. package/dist/api/offset-commit.js +48 -0
  38. package/dist/api/offset-fetch.d.ts +33 -0
  39. package/dist/api/offset-fetch.js +57 -0
  40. package/dist/api/produce.d.ts +53 -0
  41. package/dist/api/produce.js +129 -0
  42. package/dist/api/sasl-authenticate.d.ts +11 -0
  43. package/dist/api/sasl-authenticate.js +23 -0
  44. package/dist/api/sasl-handshake.d.ts +6 -0
  45. package/dist/api/sasl-handshake.js +19 -0
  46. package/dist/api/sync-group.d.ts +24 -0
  47. package/dist/api/sync-group.js +36 -0
  48. package/dist/broker.d.ts +29 -0
  49. package/dist/broker.js +60 -0
  50. package/dist/client.d.ts +23 -0
  51. package/dist/client.js +36 -0
  52. package/dist/cluster.d.ts +24 -0
  53. package/dist/cluster.js +72 -0
  54. package/dist/connection.d.ts +25 -0
  55. package/dist/connection.js +155 -0
  56. package/dist/consumer/consumer-group.d.ts +36 -0
  57. package/dist/consumer/consumer-group.js +182 -0
  58. package/dist/consumer/consumer-metadata.d.ts +7 -0
  59. package/dist/consumer/consumer-metadata.js +14 -0
  60. package/dist/consumer/consumer.d.ts +37 -0
  61. package/dist/consumer/consumer.js +178 -0
  62. package/dist/consumer/metadata.d.ts +24 -0
  63. package/dist/consumer/metadata.js +64 -0
  64. package/dist/consumer/offset-manager.d.ts +22 -0
  65. package/dist/consumer/offset-manager.js +56 -0
  66. package/dist/distributors/assignments-to-replicas.d.ts +17 -0
  67. package/dist/distributors/assignments-to-replicas.js +60 -0
  68. package/dist/distributors/assignments-to-replicas.test.d.ts +1 -0
  69. package/dist/distributors/assignments-to-replicas.test.js +40 -0
  70. package/dist/distributors/messages-to-topic-partition-leaders.d.ts +17 -0
  71. package/dist/distributors/messages-to-topic-partition-leaders.js +15 -0
  72. package/dist/distributors/messages-to-topic-partition-leaders.test.d.ts +1 -0
  73. package/dist/distributors/messages-to-topic-partition-leaders.test.js +30 -0
  74. package/dist/examples/src/replicator.js +34 -0
  75. package/dist/examples/src/utils/json.js +5 -0
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.js +19 -0
  78. package/dist/metadata.d.ts +24 -0
  79. package/dist/metadata.js +89 -0
  80. package/dist/producer/producer.d.ts +19 -0
  81. package/dist/producer/producer.js +111 -0
  82. package/dist/request-handler.d.ts +16 -0
  83. package/dist/request-handler.js +67 -0
  84. package/dist/request-handler.test.d.ts +1 -0
  85. package/dist/request-handler.test.js +340 -0
  86. package/dist/src/api/api-versions.js +18 -0
  87. package/dist/src/api/create-topics.js +46 -0
  88. package/dist/src/api/delete-topics.js +26 -0
  89. package/dist/src/api/fetch.js +95 -0
  90. package/dist/src/api/find-coordinator.js +34 -0
  91. package/dist/src/api/heartbeat.js +22 -0
  92. package/dist/src/api/index.js +38 -0
  93. package/dist/src/api/init-producer-id.js +24 -0
  94. package/dist/src/api/join-group.js +48 -0
  95. package/dist/src/api/leave-group.js +30 -0
  96. package/dist/src/api/list-offsets.js +39 -0
  97. package/dist/src/api/metadata.js +47 -0
  98. package/dist/src/api/offset-commit.js +39 -0
  99. package/dist/src/api/offset-fetch.js +44 -0
  100. package/dist/src/api/produce.js +119 -0
  101. package/dist/src/api/sync-group.js +31 -0
  102. package/dist/src/broker.js +35 -0
  103. package/dist/src/connection.js +21 -0
  104. package/dist/src/consumer/consumer-group.js +131 -0
  105. package/dist/src/consumer/consumer.js +103 -0
  106. package/dist/src/consumer/metadata.js +52 -0
  107. package/dist/src/consumer/offset-manager.js +23 -0
  108. package/dist/src/index.js +19 -0
  109. package/dist/src/producer/producer.js +84 -0
  110. package/dist/src/request-handler.js +57 -0
  111. package/dist/src/request-handler.test.js +321 -0
  112. package/dist/src/types.js +2 -0
  113. package/dist/src/utils/api.js +5 -0
  114. package/dist/src/utils/decoder.js +161 -0
  115. package/dist/src/utils/encoder.js +137 -0
  116. package/dist/src/utils/error.js +10 -0
  117. package/dist/types.d.ts +9 -0
  118. package/dist/types.js +2 -0
  119. package/dist/utils/api.d.ts +9 -0
  120. package/dist/utils/api.js +5 -0
  121. package/dist/utils/debug.d.ts +2 -0
  122. package/dist/utils/debug.js +11 -0
  123. package/dist/utils/decoder.d.ts +29 -0
  124. package/dist/utils/decoder.js +147 -0
  125. package/dist/utils/delay.d.ts +1 -0
  126. package/dist/utils/delay.js +5 -0
  127. package/dist/utils/encoder.d.ts +28 -0
  128. package/dist/utils/encoder.js +122 -0
  129. package/dist/utils/error.d.ts +11 -0
  130. package/dist/utils/error.js +27 -0
  131. package/dist/utils/memo.d.ts +1 -0
  132. package/dist/utils/memo.js +16 -0
  133. package/dist/utils/retrier.d.ts +10 -0
  134. package/dist/utils/retrier.js +22 -0
  135. package/dist/utils/tracer.d.ts +1 -0
  136. package/dist/utils/tracer.js +26 -0
  137. package/docker-compose.yml +104 -0
  138. package/examples/node_modules/.package-lock.json +22 -0
  139. package/examples/package-lock.json +30 -0
  140. package/examples/package.json +14 -0
  141. package/examples/src/client.ts +9 -0
  142. package/examples/src/consumer.ts +17 -0
  143. package/examples/src/create-topic.ts +37 -0
  144. package/examples/src/producer.ts +24 -0
  145. package/examples/src/replicator.ts +25 -0
  146. package/examples/src/utils/json.ts +1 -0
  147. package/examples/tsconfig.json +7 -0
  148. package/log4j.properties +95 -0
  149. package/package.json +17 -0
  150. package/scripts/generate-certs.sh +24 -0
  151. package/src/__snapshots__/request-handler.test.ts.snap +1687 -0
  152. package/src/api/api-versions.ts +21 -0
  153. package/src/api/create-topics.ts +78 -0
  154. package/src/api/delete-topics.ts +42 -0
  155. package/src/api/fetch.ts +143 -0
  156. package/src/api/find-coordinator.ts +39 -0
  157. package/src/api/heartbeat.ts +33 -0
  158. package/src/api/index.ts +164 -0
  159. package/src/api/init-producer-id.ts +35 -0
  160. package/src/api/join-group.ts +67 -0
  161. package/src/api/leave-group.ts +48 -0
  162. package/src/api/list-offsets.ts +65 -0
  163. package/src/api/metadata.ts +66 -0
  164. package/src/api/offset-commit.ts +67 -0
  165. package/src/api/offset-fetch.ts +74 -0
  166. package/src/api/produce.ts +173 -0
  167. package/src/api/sasl-authenticate.ts +21 -0
  168. package/src/api/sasl-handshake.ts +16 -0
  169. package/src/api/sync-group.ts +54 -0
  170. package/src/broker.ts +74 -0
  171. package/src/client.ts +47 -0
  172. package/src/cluster.ts +87 -0
  173. package/src/connection.ts +141 -0
  174. package/src/consumer/consumer-group.ts +209 -0
  175. package/src/consumer/consumer-metadata.ts +14 -0
  176. package/src/consumer/consumer.ts +229 -0
  177. package/src/consumer/offset-manager.ts +93 -0
  178. package/src/distributors/assignments-to-replicas.test.ts +43 -0
  179. package/src/distributors/assignments-to-replicas.ts +85 -0
  180. package/src/distributors/messages-to-topic-partition-leaders.test.ts +32 -0
  181. package/src/distributors/messages-to-topic-partition-leaders.ts +19 -0
  182. package/src/index.ts +3 -0
  183. package/src/metadata.ts +122 -0
  184. package/src/producer/producer.ts +132 -0
  185. package/src/request-handler.test.ts +366 -0
  186. package/src/types.ts +9 -0
  187. package/src/utils/api.ts +11 -0
  188. package/src/utils/debug.ts +9 -0
  189. package/src/utils/decoder.ts +168 -0
  190. package/src/utils/delay.ts +1 -0
  191. package/src/utils/encoder.ts +141 -0
  192. package/src/utils/error.ts +21 -0
  193. package/src/utils/memo.ts +12 -0
  194. package/src/utils/retrier.ts +39 -0
  195. package/src/utils/tracer.ts +28 -0
  196. package/tsconfig.json +17 -0
@@ -0,0 +1,141 @@
1
+ export class Encoder {
2
+ private buffer: Buffer;
3
+
4
+ constructor({ buffer = Buffer.alloc(0) }: { buffer?: Buffer } = {}) {
5
+ this.buffer = buffer;
6
+ }
7
+
8
+ public write(rightBuffer: Buffer) {
9
+ this.buffer = Buffer.concat([this.buffer, rightBuffer]);
10
+ return this;
11
+ }
12
+
13
+ public writeInt8(value: number) {
14
+ const buffer = Buffer.alloc(1);
15
+ buffer.writeInt8(value);
16
+ return this.write(buffer);
17
+ }
18
+
19
+ public writeInt16(value: number) {
20
+ const buffer = Buffer.alloc(2);
21
+ buffer.writeInt16BE(value);
22
+ return this.write(buffer);
23
+ }
24
+
25
+ public writeInt32(value: number) {
26
+ const buffer = Buffer.alloc(4);
27
+ buffer.writeInt32BE(value);
28
+ return this.write(buffer);
29
+ }
30
+
31
+ public writeUInt32(value: number) {
32
+ const buffer = Buffer.alloc(4);
33
+ buffer.writeUInt32BE(value);
34
+ return this.write(buffer);
35
+ }
36
+
37
+ public writeInt64(value: bigint) {
38
+ const buffer = Buffer.alloc(8);
39
+ buffer.writeBigInt64BE(value);
40
+ return this.write(buffer);
41
+ }
42
+
43
+ public writeUVarInt(value: number) {
44
+ const byteArray = [];
45
+ while ((value & 0xffffffff) !== 0) {
46
+ byteArray.push((value & 0x7f) | 0x80);
47
+ value >>>= 7;
48
+ }
49
+ byteArray.push(value & 0x7f);
50
+ return this.write(Buffer.from(byteArray));
51
+ }
52
+
53
+ public writeVarInt(value: number) {
54
+ const encodedValue = (value << 1) ^ (value >> 31);
55
+ return this.writeUVarInt(encodedValue);
56
+ }
57
+
58
+ public writeUVarLong(value: bigint) {
59
+ const byteArray = [];
60
+ while ((value & BigInt(0xffffffffffffffff)) !== BigInt(0)) {
61
+ byteArray.push(Number((value & BigInt(0x7f)) | BigInt(0x80)));
62
+ value = value >> BigInt(7);
63
+ }
64
+ byteArray.push(Number(value));
65
+ return this.write(Buffer.from(byteArray));
66
+ }
67
+
68
+ public writeVarLong(value: bigint) {
69
+ const encodedValue = (value << BigInt(1)) ^ (value >> BigInt(63));
70
+ return this.writeUVarLong(encodedValue);
71
+ }
72
+
73
+ public writeString(value: string | null) {
74
+ if (value === null) {
75
+ return this.writeInt16(-1);
76
+ }
77
+ const byteLength = Buffer.byteLength(value, "utf-8");
78
+ const buffer = Buffer.alloc(byteLength);
79
+ buffer.write(value, 0, byteLength, "utf-8");
80
+ return this.writeInt16(byteLength).write(buffer);
81
+ }
82
+
83
+ public writeCompactString(value: string | null) {
84
+ if (value === null) {
85
+ return this.writeUVarInt(0);
86
+ }
87
+
88
+ const byteLength = Buffer.byteLength(value, "utf-8");
89
+ const buffer = Buffer.alloc(byteLength);
90
+ buffer.write(value, 0, byteLength, "utf-8");
91
+ return this.writeUVarInt(byteLength + 1).write(buffer);
92
+ }
93
+
94
+ public writeVarIntString(value: string | null) {
95
+ if (value === null) {
96
+ return this.writeVarInt(-1);
97
+ }
98
+ return this.writeVarInt(Buffer.byteLength(value, "utf-8")).write(Buffer.from(value, "utf-8"));
99
+ }
100
+
101
+ public writeUUID(value: string | null) {
102
+ if (value === null) {
103
+ return this.write(Buffer.alloc(16));
104
+ }
105
+ return this.write(Buffer.from(value, "hex"));
106
+ }
107
+
108
+ public writeBoolean(value: boolean) {
109
+ return this.writeInt8(value ? 1 : 0);
110
+ }
111
+
112
+ public writeArray<T>(arr: T[], callback: (encoder: Encoder, item: T) => Encoder) {
113
+ const buffers = arr.map((item) => callback(new Encoder(), item).value());
114
+ return this.writeInt32(arr.length).write(Buffer.concat(buffers));
115
+ }
116
+
117
+ public writeCompactArray<T>(arr: T[] | null, callback: (encoder: Encoder, item: T) => Encoder) {
118
+ if (arr === null) {
119
+ return this.writeUVarInt(0);
120
+ }
121
+ const buffers = arr.map((item) => callback(new Encoder(), item).value());
122
+ return this.writeUVarInt(buffers.length + 1).write(Buffer.concat(buffers));
123
+ }
124
+
125
+ public writeVarIntArray<T>(arr: T[], callback: (encoder: Encoder, item: T) => Encoder) {
126
+ const buffers = arr.map((item) => callback(new Encoder(), item).value());
127
+ return this.writeVarInt(buffers.length).write(Buffer.concat(buffers));
128
+ }
129
+
130
+ public writeBytes(value: Buffer) {
131
+ return this.writeInt32(value.length).write(value);
132
+ }
133
+
134
+ public writeCompactBytes(value: Buffer) {
135
+ return this.writeUVarInt(value.length + 1).write(value);
136
+ }
137
+
138
+ public value() {
139
+ return this.buffer;
140
+ }
141
+ }
@@ -0,0 +1,21 @@
1
+ import { API_ERROR } from "../api";
2
+
3
+ export class KafkaTSError extends Error {
4
+ constructor(message: string) {
5
+ super(message);
6
+ this.name = this.constructor.name;
7
+ }
8
+ }
9
+
10
+ export class KafkaTSApiError<T = any> extends KafkaTSError {
11
+ constructor(
12
+ public errorCode: number,
13
+ public errorMessage: string | null,
14
+ public response: T,
15
+ ) {
16
+ const [errorName] = Object.entries(API_ERROR).find(([, value]) => value === errorCode) ?? ["UNKNOWN"];
17
+ super(`${errorName}${errorMessage ? `: ${errorMessage}` : ""}`);
18
+ }
19
+ }
20
+
21
+ export class ConnectionError extends KafkaTSError {}
@@ -0,0 +1,12 @@
1
+ export const memo = <T extends (...args: any[]) => any>(fn: T) => {
2
+ const cache: Record<string, ReturnType<T>> = {};
3
+ return (...args: Parameters<T>): ReturnType<T> => {
4
+ const key = JSON.stringify(args);
5
+ if (cache[key]) {
6
+ return cache[key];
7
+ }
8
+ const result = fn(...args);
9
+ cache[key] = result;
10
+ return result;
11
+ };
12
+ };
@@ -0,0 +1,39 @@
1
+ import { delay } from "./delay";
2
+
3
+ export type Retrier = (func: () => unknown) => Promise<void>;
4
+
5
+ export const createExponentialBackoffRetrier =
6
+ (options: {
7
+ onFailure?: (error: unknown) => Promise<void>;
8
+ maxRetries?: number;
9
+ initialDelayMs?: number;
10
+ maxDelayMs?: number;
11
+ multiplier?: number;
12
+ retry?: number;
13
+ }): Retrier =>
14
+ async (func) => {
15
+ try {
16
+ await func();
17
+ } catch (error) {
18
+ const {
19
+ retry = 0,
20
+ maxRetries = 3,
21
+ onFailure = (error) => {
22
+ throw error;
23
+ },
24
+ initialDelayMs = 100,
25
+ maxDelayMs = 3000,
26
+ multiplier = 2,
27
+ } = options;
28
+
29
+ const isMaxRetriesExceeded = retry > maxRetries;
30
+ if (isMaxRetriesExceeded) return onFailure(error);
31
+
32
+ const delayMs = Math.min(maxDelayMs, initialDelayMs * multiplier ** retry);
33
+ await delay(delayMs);
34
+
35
+ return createExponentialBackoffRetrier({ ...options, retry: retry + 1 })(func);
36
+ }
37
+ };
38
+
39
+ export const defaultRetrier = createExponentialBackoffRetrier({});
@@ -0,0 +1,28 @@
1
+ import { serializer } from "./debug";
2
+
3
+ export const trace =
4
+ (fn?: (...args: any[]) => Record<string, unknown> | undefined) =>
5
+ (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
6
+ if (!process.env.DEBUG?.includes("kafkats")) return;
7
+
8
+ const original = descriptor.value;
9
+ descriptor.value = function (...args: any[]) {
10
+ const startTime = Date.now();
11
+ const metadata = fn?.(...args);
12
+
13
+ const onEnd = <T>(result: T): T => {
14
+ console.log(
15
+ `[${propertyKey}] +${Date.now() - startTime}ms ${JSON.stringify({ ...metadata, result }, serializer)}`,
16
+ );
17
+ return result;
18
+ };
19
+
20
+ const result = original.apply(this, args);
21
+ if (result instanceof Promise) {
22
+ return result.then(onEnd);
23
+ } else {
24
+ onEnd(result);
25
+ return result;
26
+ }
27
+ };
28
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["es2023"],
4
+ "target": "es2022",
5
+ "module": "node16",
6
+ "strict": true,
7
+ "forceConsistentCasingInFileNames": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "moduleResolution": "node16",
11
+ "outDir": "dist",
12
+ "declaration": true,
13
+ "emitDecoratorMetadata": true,
14
+ "experimentalDecorators": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ }