kafka-ts 0.0.3-beta → 0.0.4

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 (176) hide show
  1. package/README.md +72 -8
  2. package/dist/api/api-versions.d.ts +9 -0
  3. package/{src/api/api-versions.ts → dist/api/api-versions.js} +8 -5
  4. package/dist/api/create-topics.d.ts +38 -0
  5. package/dist/api/create-topics.js +53 -0
  6. package/dist/api/delete-topics.d.ts +18 -0
  7. package/dist/api/delete-topics.js +33 -0
  8. package/dist/api/fetch.d.ts +84 -0
  9. package/dist/api/fetch.js +142 -0
  10. package/dist/api/find-coordinator.d.ts +21 -0
  11. package/{src/api/find-coordinator.ts → dist/api/find-coordinator.js} +14 -14
  12. package/dist/api/heartbeat.d.ts +11 -0
  13. package/dist/api/heartbeat.js +27 -0
  14. package/dist/api/index.d.ts +576 -0
  15. package/{src/api/index.ts → dist/api/index.js} +42 -41
  16. package/dist/api/init-producer-id.d.ts +13 -0
  17. package/dist/api/init-producer-id.js +29 -0
  18. package/dist/api/join-group.d.ts +34 -0
  19. package/dist/api/join-group.js +51 -0
  20. package/dist/api/leave-group.d.ts +19 -0
  21. package/dist/api/leave-group.js +39 -0
  22. package/dist/api/list-offsets.d.ts +29 -0
  23. package/dist/api/list-offsets.js +48 -0
  24. package/dist/api/metadata.d.ts +40 -0
  25. package/{src/api/metadata.ts → dist/api/metadata.js} +18 -26
  26. package/dist/api/offset-commit.d.ts +28 -0
  27. package/dist/api/offset-commit.js +48 -0
  28. package/dist/api/offset-fetch.d.ts +31 -0
  29. package/dist/api/offset-fetch.js +55 -0
  30. package/dist/api/produce.d.ts +54 -0
  31. package/{src/api/produce.ts → dist/api/produce.js} +55 -102
  32. package/dist/api/sasl-authenticate.d.ts +11 -0
  33. package/dist/api/sasl-authenticate.js +23 -0
  34. package/dist/api/sasl-handshake.d.ts +6 -0
  35. package/dist/api/sasl-handshake.js +19 -0
  36. package/dist/api/sync-group.d.ts +24 -0
  37. package/dist/api/sync-group.js +36 -0
  38. package/dist/auth/index.d.ts +2 -0
  39. package/dist/auth/index.js +8 -0
  40. package/dist/auth/plain.d.ts +5 -0
  41. package/dist/auth/plain.js +12 -0
  42. package/dist/auth/scram.d.ts +9 -0
  43. package/dist/auth/scram.js +40 -0
  44. package/dist/broker.d.ts +30 -0
  45. package/dist/broker.js +55 -0
  46. package/dist/client.d.ts +22 -0
  47. package/dist/client.js +36 -0
  48. package/dist/cluster.d.ts +27 -0
  49. package/dist/cluster.js +70 -0
  50. package/dist/cluster.test.d.ts +1 -0
  51. package/{src/cluster.test.ts → dist/cluster.test.js} +87 -113
  52. package/dist/codecs/gzip.d.ts +2 -0
  53. package/dist/codecs/gzip.js +8 -0
  54. package/dist/codecs/index.d.ts +2 -0
  55. package/dist/codecs/index.js +17 -0
  56. package/dist/codecs/none.d.ts +2 -0
  57. package/dist/codecs/none.js +7 -0
  58. package/dist/codecs/types.d.ts +5 -0
  59. package/dist/codecs/types.js +2 -0
  60. package/dist/connection.d.ts +26 -0
  61. package/dist/connection.js +175 -0
  62. package/dist/consumer/consumer-group.d.ts +41 -0
  63. package/dist/consumer/consumer-group.js +215 -0
  64. package/dist/consumer/consumer-metadata.d.ts +7 -0
  65. package/dist/consumer/consumer-metadata.js +14 -0
  66. package/dist/consumer/consumer.d.ts +44 -0
  67. package/dist/consumer/consumer.js +225 -0
  68. package/dist/consumer/fetch-manager.d.ts +33 -0
  69. package/dist/consumer/fetch-manager.js +140 -0
  70. package/dist/consumer/fetcher.d.ts +25 -0
  71. package/dist/consumer/fetcher.js +64 -0
  72. package/dist/consumer/offset-manager.d.ts +22 -0
  73. package/dist/consumer/offset-manager.js +66 -0
  74. package/dist/consumer/processor.d.ts +19 -0
  75. package/dist/consumer/processor.js +59 -0
  76. package/dist/distributors/assignments-to-replicas.d.ts +16 -0
  77. package/{src/distributors/assignments-to-replicas.ts → dist/distributors/assignments-to-replicas.js} +15 -41
  78. package/dist/distributors/assignments-to-replicas.test.d.ts +1 -0
  79. package/dist/distributors/assignments-to-replicas.test.js +40 -0
  80. package/dist/distributors/messages-to-topic-partition-leaders.d.ts +17 -0
  81. package/dist/distributors/messages-to-topic-partition-leaders.js +15 -0
  82. package/dist/distributors/messages-to-topic-partition-leaders.test.d.ts +1 -0
  83. package/dist/distributors/messages-to-topic-partition-leaders.test.js +30 -0
  84. package/dist/distributors/partitioner.d.ts +7 -0
  85. package/dist/distributors/partitioner.js +23 -0
  86. package/dist/index.d.ts +9 -0
  87. package/dist/index.js +26 -0
  88. package/dist/metadata.d.ts +24 -0
  89. package/dist/metadata.js +106 -0
  90. package/dist/producer/producer.d.ts +24 -0
  91. package/dist/producer/producer.js +131 -0
  92. package/{src/types.ts → dist/types.d.ts} +4 -4
  93. package/dist/types.js +2 -0
  94. package/{src/utils/api.ts → dist/utils/api.d.ts} +2 -4
  95. package/dist/utils/api.js +5 -0
  96. package/dist/utils/crypto.d.ts +8 -0
  97. package/dist/utils/crypto.js +18 -0
  98. package/dist/utils/decoder.d.ts +30 -0
  99. package/{src/utils/decoder.ts → dist/utils/decoder.js} +41 -57
  100. package/dist/utils/delay.d.ts +1 -0
  101. package/dist/utils/delay.js +5 -0
  102. package/dist/utils/encoder.d.ts +28 -0
  103. package/{src/utils/encoder.ts → dist/utils/encoder.js} +50 -66
  104. package/dist/utils/error.d.ts +11 -0
  105. package/dist/utils/error.js +27 -0
  106. package/dist/utils/logger.d.ts +9 -0
  107. package/dist/utils/logger.js +32 -0
  108. package/dist/utils/memo.d.ts +1 -0
  109. package/{src/utils/memo.ts → dist/utils/memo.js} +7 -3
  110. package/dist/utils/murmur2.d.ts +3 -0
  111. package/dist/utils/murmur2.js +40 -0
  112. package/dist/utils/retrier.d.ts +10 -0
  113. package/dist/utils/retrier.js +22 -0
  114. package/dist/utils/tracer.d.ts +5 -0
  115. package/dist/utils/tracer.js +39 -0
  116. package/package.json +11 -2
  117. package/.github/workflows/release.yml +0 -17
  118. package/.prettierrc +0 -8
  119. package/certs/ca.crt +0 -29
  120. package/certs/ca.key +0 -52
  121. package/certs/ca.srl +0 -1
  122. package/certs/kafka.crt +0 -29
  123. package/certs/kafka.csr +0 -26
  124. package/certs/kafka.key +0 -52
  125. package/certs/kafka.keystore.jks +0 -0
  126. package/certs/kafka.truststore.jks +0 -0
  127. package/docker-compose.yml +0 -104
  128. package/examples/package-lock.json +0 -31
  129. package/examples/package.json +0 -14
  130. package/examples/src/client.ts +0 -9
  131. package/examples/src/consumer.ts +0 -18
  132. package/examples/src/create-topic.ts +0 -44
  133. package/examples/src/producer.ts +0 -24
  134. package/examples/src/replicator.ts +0 -25
  135. package/examples/src/utils/delay.ts +0 -1
  136. package/examples/src/utils/json.ts +0 -1
  137. package/examples/tsconfig.json +0 -7
  138. package/log4j.properties +0 -95
  139. package/scripts/generate-certs.sh +0 -24
  140. package/src/__snapshots__/request-handler.test.ts.snap +0 -978
  141. package/src/api/create-topics.ts +0 -78
  142. package/src/api/delete-topics.ts +0 -42
  143. package/src/api/fetch.ts +0 -143
  144. package/src/api/heartbeat.ts +0 -33
  145. package/src/api/init-producer-id.ts +0 -35
  146. package/src/api/join-group.ts +0 -67
  147. package/src/api/leave-group.ts +0 -48
  148. package/src/api/list-offsets.ts +0 -65
  149. package/src/api/offset-commit.ts +0 -67
  150. package/src/api/offset-fetch.ts +0 -74
  151. package/src/api/sasl-authenticate.ts +0 -21
  152. package/src/api/sasl-handshake.ts +0 -16
  153. package/src/api/sync-group.ts +0 -54
  154. package/src/broker.ts +0 -74
  155. package/src/client.ts +0 -47
  156. package/src/cluster.ts +0 -87
  157. package/src/connection.ts +0 -143
  158. package/src/consumer/consumer-group.ts +0 -209
  159. package/src/consumer/consumer-metadata.ts +0 -14
  160. package/src/consumer/consumer.ts +0 -231
  161. package/src/consumer/fetch-manager.ts +0 -179
  162. package/src/consumer/fetcher.ts +0 -57
  163. package/src/consumer/offset-manager.ts +0 -93
  164. package/src/consumer/processor.ts +0 -47
  165. package/src/distributors/assignments-to-replicas.test.ts +0 -43
  166. package/src/distributors/messages-to-topic-partition-leaders.test.ts +0 -32
  167. package/src/distributors/messages-to-topic-partition-leaders.ts +0 -19
  168. package/src/index.ts +0 -4
  169. package/src/metadata.ts +0 -122
  170. package/src/producer/producer.ts +0 -132
  171. package/src/utils/debug.ts +0 -9
  172. package/src/utils/delay.ts +0 -1
  173. package/src/utils/error.ts +0 -21
  174. package/src/utils/retrier.ts +0 -39
  175. package/src/utils/tracer.ts +0 -31
  176. package/tsconfig.json +0 -17
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.setTracer = void 0;
18
+ __exportStar(require("./api"), exports);
19
+ __exportStar(require("./auth"), exports);
20
+ __exportStar(require("./client"), exports);
21
+ __exportStar(require("./distributors/partitioner"), exports);
22
+ __exportStar(require("./types"), exports);
23
+ __exportStar(require("./utils/error"), exports);
24
+ __exportStar(require("./utils/logger"), exports);
25
+ var tracer_1 = require("./utils/tracer");
26
+ Object.defineProperty(exports, "setTracer", { enumerable: true, get: function () { return tracer_1.setTracer; } });
@@ -0,0 +1,24 @@
1
+ import { Cluster } from './cluster';
2
+ type MetadataOptions = {
3
+ cluster: Cluster;
4
+ };
5
+ export declare class Metadata {
6
+ private options;
7
+ private topicPartitions;
8
+ private topicNameById;
9
+ private topicIdByName;
10
+ private leaderIdByTopicPartition;
11
+ private isrNodesByTopicPartition;
12
+ constructor(options: MetadataOptions);
13
+ getTopicPartitionLeaderIds(): Record<string, Record<number, number>>;
14
+ getTopicPartitionReplicaIds(): Record<string, Record<number, number[]>>;
15
+ getTopicPartitions(): Record<string, number[]>;
16
+ getTopicIdByName(name: string): string;
17
+ getTopicNameById(id: string): string;
18
+ fetchMetadataIfNecessary({ topics, allowTopicAutoCreation, }: {
19
+ topics: string[];
20
+ allowTopicAutoCreation: boolean;
21
+ }): Promise<void>;
22
+ private fetchMetadata;
23
+ }
24
+ export {};
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Metadata = void 0;
13
+ const api_1 = require("./api");
14
+ const delay_1 = require("./utils/delay");
15
+ const error_1 = require("./utils/error");
16
+ const tracer_1 = require("./utils/tracer");
17
+ const trace = (0, tracer_1.createTracer)('Metadata');
18
+ class Metadata {
19
+ options;
20
+ topicPartitions = {};
21
+ topicNameById = {};
22
+ topicIdByName = {};
23
+ leaderIdByTopicPartition = {};
24
+ isrNodesByTopicPartition = {};
25
+ constructor(options) {
26
+ this.options = options;
27
+ }
28
+ getTopicPartitionLeaderIds() {
29
+ return this.leaderIdByTopicPartition;
30
+ }
31
+ getTopicPartitionReplicaIds() {
32
+ return this.isrNodesByTopicPartition;
33
+ }
34
+ getTopicPartitions() {
35
+ return this.topicPartitions;
36
+ }
37
+ getTopicIdByName(name) {
38
+ return this.topicIdByName[name];
39
+ }
40
+ getTopicNameById(id) {
41
+ return this.topicNameById[id];
42
+ }
43
+ async fetchMetadataIfNecessary({ topics, allowTopicAutoCreation, }) {
44
+ const missingTopics = topics.filter((topic) => !this.topicPartitions[topic]);
45
+ if (!missingTopics.length) {
46
+ return;
47
+ }
48
+ try {
49
+ return await this.fetchMetadata({ topics: missingTopics, allowTopicAutoCreation });
50
+ }
51
+ catch (error) {
52
+ if (error instanceof error_1.KafkaTSApiError &&
53
+ error.errorCode === api_1.API_ERROR.UNKNOWN_TOPIC_OR_PARTITION &&
54
+ allowTopicAutoCreation) {
55
+ // TODO: investigate if we can avoid the delay
56
+ await (0, delay_1.delay)(1000);
57
+ return await this.fetchMetadata({ topics: missingTopics, allowTopicAutoCreation });
58
+ }
59
+ throw error;
60
+ }
61
+ }
62
+ async fetchMetadata({ topics, allowTopicAutoCreation, }) {
63
+ const { cluster } = this.options;
64
+ const response = await cluster.sendRequest(api_1.API.METADATA, {
65
+ allowTopicAutoCreation,
66
+ includeTopicAuthorizedOperations: false,
67
+ topics: topics?.map((name) => ({ id: null, name })) ?? null,
68
+ });
69
+ this.topicPartitions = {
70
+ ...this.topicPartitions,
71
+ ...Object.fromEntries(response.topics.map((topic) => [
72
+ topic.name,
73
+ topic.partitions.map((partition) => partition.partitionIndex),
74
+ ])),
75
+ };
76
+ this.topicNameById = {
77
+ ...this.topicNameById,
78
+ ...Object.fromEntries(response.topics.map((topic) => [topic.topicId, topic.name])),
79
+ };
80
+ this.topicIdByName = {
81
+ ...this.topicIdByName,
82
+ ...Object.fromEntries(response.topics.map((topic) => [topic.name, topic.topicId])),
83
+ };
84
+ this.leaderIdByTopicPartition = {
85
+ ...this.leaderIdByTopicPartition,
86
+ ...Object.fromEntries(response.topics.map((topic) => [
87
+ topic.name,
88
+ Object.fromEntries(topic.partitions.map((partition) => [partition.partitionIndex, partition.leaderId])),
89
+ ])),
90
+ };
91
+ this.isrNodesByTopicPartition = {
92
+ ...this.isrNodesByTopicPartition,
93
+ ...Object.fromEntries(response.topics.map((topic) => [
94
+ topic.name,
95
+ Object.fromEntries(topic.partitions.map((partition) => [partition.partitionIndex, partition.isrNodes])),
96
+ ])),
97
+ };
98
+ }
99
+ }
100
+ exports.Metadata = Metadata;
101
+ __decorate([
102
+ trace(),
103
+ __metadata("design:type", Function),
104
+ __metadata("design:paramtypes", [Object]),
105
+ __metadata("design:returntype", Promise)
106
+ ], Metadata.prototype, "fetchMetadataIfNecessary", null);
@@ -0,0 +1,24 @@
1
+ import { Cluster } from '../cluster';
2
+ import { Partitioner } from '../distributors/partitioner';
3
+ import { Message } from '../types';
4
+ export type ProducerOptions = {
5
+ allowTopicAutoCreation?: boolean;
6
+ partitioner?: Partitioner;
7
+ };
8
+ export declare class Producer {
9
+ private cluster;
10
+ private options;
11
+ private metadata;
12
+ private producerId;
13
+ private producerEpoch;
14
+ private sequences;
15
+ private partition;
16
+ constructor(cluster: Cluster, options: ProducerOptions);
17
+ send(messages: Message[], { acks }?: {
18
+ acks?: -1 | 1;
19
+ }): Promise<void>;
20
+ close(): Promise<void>;
21
+ private ensureConnected;
22
+ private initProducerId;
23
+ private nextSequence;
24
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Producer = void 0;
13
+ const api_1 = require("../api");
14
+ const messages_to_topic_partition_leaders_1 = require("../distributors/messages-to-topic-partition-leaders");
15
+ const partitioner_1 = require("../distributors/partitioner");
16
+ const metadata_1 = require("../metadata");
17
+ const delay_1 = require("../utils/delay");
18
+ const memo_1 = require("../utils/memo");
19
+ const tracer_1 = require("../utils/tracer");
20
+ const trace = (0, tracer_1.createTracer)('Producer');
21
+ class Producer {
22
+ cluster;
23
+ options;
24
+ metadata;
25
+ producerId = 0n;
26
+ producerEpoch = 0;
27
+ sequences = {};
28
+ partition;
29
+ constructor(cluster, options) {
30
+ this.cluster = cluster;
31
+ this.options = {
32
+ ...options,
33
+ allowTopicAutoCreation: options.allowTopicAutoCreation ?? false,
34
+ partitioner: options.partitioner ?? partitioner_1.defaultPartitioner,
35
+ };
36
+ this.metadata = new metadata_1.Metadata({ cluster });
37
+ this.partition = this.options.partitioner({ metadata: this.metadata });
38
+ }
39
+ async send(messages, { acks = -1 } = {}) {
40
+ await this.ensureConnected();
41
+ const { allowTopicAutoCreation } = this.options;
42
+ const defaultTimestamp = BigInt(Date.now());
43
+ const topics = Array.from(new Set(messages.map((message) => message.topic)));
44
+ await this.metadata.fetchMetadataIfNecessary({ topics, allowTopicAutoCreation });
45
+ const nodeTopicPartitionMessages = (0, messages_to_topic_partition_leaders_1.distributeMessagesToTopicPartitionLeaders)(messages.map((message) => ({ ...message, partition: this.partition(message) })), this.metadata.getTopicPartitionLeaderIds());
46
+ await Promise.all(Object.entries(nodeTopicPartitionMessages).map(([nodeId, topicPartitionMessages]) => this.cluster.sendRequestToNode(parseInt(nodeId))(api_1.API.PRODUCE, {
47
+ transactionalId: null,
48
+ acks,
49
+ timeoutMs: 5000,
50
+ topicData: Object.entries(topicPartitionMessages).map(([topic, partitionMessages]) => ({
51
+ name: topic,
52
+ partitionData: Object.entries(partitionMessages).map(([partition, messages]) => {
53
+ const partitionIndex = parseInt(partition);
54
+ let baseTimestamp;
55
+ let maxTimestamp;
56
+ messages.forEach(({ timestamp = defaultTimestamp }) => {
57
+ if (!baseTimestamp || timestamp < baseTimestamp) {
58
+ baseTimestamp = timestamp;
59
+ }
60
+ if (!maxTimestamp || timestamp > maxTimestamp) {
61
+ maxTimestamp = timestamp;
62
+ }
63
+ });
64
+ const baseSequence = this.nextSequence(topic, partitionIndex, messages.length);
65
+ return {
66
+ index: partitionIndex,
67
+ baseOffset: 0n,
68
+ partitionLeaderEpoch: -1,
69
+ attributes: 0,
70
+ lastOffsetDelta: messages.length - 1,
71
+ baseTimestamp: baseTimestamp ?? 0n,
72
+ maxTimestamp: maxTimestamp ?? 0n,
73
+ producerId: this.producerId,
74
+ producerEpoch: 0,
75
+ baseSequence,
76
+ records: messages.map((message, index) => ({
77
+ attributes: 0,
78
+ timestampDelta: (message.timestamp ?? defaultTimestamp) - (baseTimestamp ?? 0n),
79
+ offsetDelta: index,
80
+ key: message.key ?? null,
81
+ value: message.value,
82
+ headers: Object.entries(message.headers ?? {}).map(([key, value]) => ({
83
+ key: Buffer.from(key),
84
+ value: Buffer.from(value),
85
+ })),
86
+ })),
87
+ };
88
+ }),
89
+ })),
90
+ })));
91
+ }
92
+ async close() {
93
+ await this.cluster.disconnect();
94
+ }
95
+ ensureConnected = (0, memo_1.memo)(async () => {
96
+ await this.cluster.connect();
97
+ await this.initProducerId();
98
+ });
99
+ async initProducerId() {
100
+ try {
101
+ const result = await this.cluster.sendRequest(api_1.API.INIT_PRODUCER_ID, {
102
+ transactionalId: null,
103
+ transactionTimeoutMs: 0,
104
+ producerId: this.producerId,
105
+ producerEpoch: this.producerEpoch,
106
+ });
107
+ this.producerId = result.producerId;
108
+ this.producerEpoch = result.producerEpoch;
109
+ this.sequences = {};
110
+ }
111
+ catch (error) {
112
+ if (error.errorCode === api_1.API_ERROR.COORDINATOR_LOAD_IN_PROGRESS) {
113
+ await (0, delay_1.delay)(100);
114
+ return this.initProducerId();
115
+ }
116
+ throw error;
117
+ }
118
+ }
119
+ nextSequence(topic, partition, messagesCount) {
120
+ this.sequences[topic] ??= {};
121
+ this.sequences[topic][partition] ??= 0;
122
+ return (this.sequences[topic][partition] += messagesCount || 1);
123
+ }
124
+ }
125
+ exports.Producer = Producer;
126
+ __decorate([
127
+ trace(() => ({ root: true })),
128
+ __metadata("design:type", Function),
129
+ __metadata("design:paramtypes", [Array, Object]),
130
+ __metadata("design:returntype", Promise)
131
+ ], Producer.prototype, "send", null);
@@ -1,11 +1,11 @@
1
+ /// <reference types="node" />
1
2
  export type Message = {
2
3
  topic: string;
3
- partition: number;
4
+ partition?: number;
4
5
  offset?: bigint;
5
6
  timestamp?: bigint;
6
- key: string | null;
7
- value: string | null;
7
+ key?: Buffer | null;
8
+ value: Buffer | null;
8
9
  headers?: Record<string, string>;
9
10
  };
10
-
11
11
  export type Batch = Required<Message>[];
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,11 +1,9 @@
1
1
  import { Decoder } from './decoder';
2
2
  import { Encoder } from './encoder';
3
-
4
3
  export type Api<Request, Response> = {
5
4
  apiKey: number;
6
5
  apiVersion: number;
7
6
  request: (encoder: Encoder, body: Request) => Encoder;
8
- response: (buffer: Decoder) => Response;
7
+ response: (buffer: Decoder) => Promise<Response> | Response;
9
8
  };
10
-
11
- export const createApi = <Request, Response>(api: Api<Request, Response>) => api;
9
+ export declare const createApi: <Request, Response>(api: Api<Request, Response>) => Api<Request, Response>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createApi = void 0;
4
+ const createApi = (api) => api;
5
+ exports.createApi = createApi;
@@ -0,0 +1,8 @@
1
+ /// <reference types="node" />
2
+ export declare const generateNonce: () => string;
3
+ export declare const saltPassword: (password: string, salt: string, iterations: number, keyLength: number, digest: string) => Promise<Buffer>;
4
+ export declare const base64Encode: (input: Buffer | string) => string;
5
+ export declare const base64Decode: (input: string) => string;
6
+ export declare const hash: (data: Buffer, digest: string) => Buffer;
7
+ export declare const hmac: (key: Buffer, data: Buffer | string, digest: string) => Buffer;
8
+ export declare const xor: (a: Buffer, b: Buffer) => Buffer;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.xor = exports.hmac = exports.hash = exports.base64Decode = exports.base64Encode = exports.saltPassword = exports.generateNonce = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const generateNonce = () => (0, crypto_1.randomBytes)(16).toString('base64').replace(/[\/=]/g, '');
6
+ exports.generateNonce = generateNonce;
7
+ const saltPassword = (password, salt, iterations, keyLength, digest) => new Promise((resolve, reject) => (0, crypto_1.pbkdf2)(password, salt, iterations, keyLength, digest, (err, key) => (err ? reject(err) : resolve(key))));
8
+ exports.saltPassword = saltPassword;
9
+ const base64Encode = (input) => Buffer.from(input).toString('base64');
10
+ exports.base64Encode = base64Encode;
11
+ const base64Decode = (input) => Buffer.from(input, 'base64').toString();
12
+ exports.base64Decode = base64Decode;
13
+ const hash = (data, digest) => (0, crypto_1.createHash)(digest).update(data).digest();
14
+ exports.hash = hash;
15
+ const hmac = (key, data, digest) => (0, crypto_1.createHmac)(digest, key).update(data).digest();
16
+ exports.hmac = hmac;
17
+ const xor = (a, b) => Buffer.from(a.map((byte, i) => byte ^ b[i]));
18
+ exports.xor = xor;
@@ -0,0 +1,30 @@
1
+ /// <reference types="node" />
2
+ export declare class Decoder {
3
+ private buffer;
4
+ private offset;
5
+ constructor(buffer: Buffer);
6
+ getOffset(): number;
7
+ getBufferLength(): number;
8
+ readInt8(): number;
9
+ readInt16(): number;
10
+ readInt32(): number;
11
+ readUInt32(): number;
12
+ readInt64(): bigint;
13
+ readUVarInt(): number;
14
+ readVarInt(): number;
15
+ readUVarLong(): bigint;
16
+ readVarLong(): bigint;
17
+ readString(): string | null;
18
+ readCompactString(): string | null;
19
+ readVarIntBuffer(): Buffer | null;
20
+ readUUID(): string;
21
+ readBoolean(): boolean;
22
+ readArray<T>(callback: (opts: Decoder) => T): T[];
23
+ readCompactArray<T>(callback: (opts: Decoder) => T): T[];
24
+ readVarIntArray<T>(callback: (opts: Decoder) => T): T[];
25
+ readRecords<T>(callback: (opts: Decoder) => T): T[];
26
+ read(length?: number): Buffer;
27
+ readBytes(): Buffer;
28
+ readCompactBytes(): Buffer | null;
29
+ readTagBuffer(): void;
30
+ }
@@ -1,47 +1,44 @@
1
- export class Decoder {
2
- private offset = 0;
3
-
4
- constructor(private buffer: Buffer) {}
5
-
6
- public getOffset() {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Decoder = void 0;
4
+ class Decoder {
5
+ buffer;
6
+ offset = 0;
7
+ constructor(buffer) {
8
+ this.buffer = buffer;
9
+ }
10
+ getOffset() {
7
11
  return this.offset;
8
12
  }
9
-
10
- public getBufferLength() {
13
+ getBufferLength() {
11
14
  return this.buffer.length;
12
15
  }
13
-
14
- public readInt8() {
16
+ readInt8() {
15
17
  const value = this.buffer.readInt8(this.offset);
16
18
  this.offset += 1;
17
19
  return value;
18
20
  }
19
-
20
- public readInt16() {
21
+ readInt16() {
21
22
  const value = this.buffer.readInt16BE(this.offset);
22
23
  this.offset += 2;
23
24
  return value;
24
25
  }
25
-
26
- public readInt32() {
26
+ readInt32() {
27
27
  const value = this.buffer.readInt32BE(this.offset);
28
28
  this.offset += 4;
29
29
  return value;
30
30
  }
31
-
32
- public readUInt32() {
31
+ readUInt32() {
33
32
  const value = this.buffer.readUInt32BE(this.offset);
34
33
  this.offset += 4;
35
34
  return value;
36
35
  }
37
-
38
- public readInt64() {
36
+ readInt64() {
39
37
  const value = this.buffer.readBigInt64BE(this.offset);
40
38
  this.offset += 8;
41
39
  return value;
42
40
  }
43
-
44
- public readUVarInt() {
41
+ readUVarInt() {
45
42
  let result = 0;
46
43
  let shift = 0;
47
44
  let currentByte;
@@ -52,13 +49,11 @@ export class Decoder {
52
49
  } while ((currentByte & 0x80) !== 0);
53
50
  return result;
54
51
  }
55
-
56
- public readVarInt() {
52
+ readVarInt() {
57
53
  const decodedValue = this.readUVarInt();
58
54
  return (decodedValue >>> 1) ^ -(decodedValue & 1);
59
55
  }
60
-
61
- public readUVarLong() {
56
+ readUVarLong() {
62
57
  let result = BigInt(0);
63
58
  let shift = BigInt(0);
64
59
  let currentByte;
@@ -69,72 +64,64 @@ export class Decoder {
69
64
  } while ((currentByte & BigInt(0x80)) !== BigInt(0));
70
65
  return result;
71
66
  }
72
-
73
- public readVarLong() {
67
+ readVarLong() {
74
68
  const decodedValue = this.readUVarLong();
75
69
  return (decodedValue >> BigInt(1)) ^ -(decodedValue & BigInt(1));
76
70
  }
77
-
78
- public readString() {
71
+ readString() {
79
72
  const length = this.readInt16();
80
73
  if (length < 0) {
81
74
  return null;
82
75
  }
83
-
84
76
  const value = this.buffer.toString('utf-8', this.offset, this.offset + length);
85
77
  this.offset += length;
86
78
  return value;
87
79
  }
88
-
89
- public readCompactString() {
80
+ readCompactString() {
90
81
  const length = this.readUVarInt() - 1;
91
82
  if (length < 0) {
92
83
  return null;
93
84
  }
94
-
95
85
  const value = this.buffer.toString('utf-8', this.offset, this.offset + length);
96
86
  this.offset += length;
97
87
  return value;
98
88
  }
99
-
100
- public readVarIntString() {
89
+ readVarIntBuffer() {
101
90
  const length = this.readVarInt();
102
91
  if (length < 0) {
103
92
  return null;
104
93
  }
105
-
106
- const value = this.buffer.toString('utf-8', this.offset, this.offset + length);
94
+ const value = this.buffer.subarray(this.offset, this.offset + length);
107
95
  this.offset += length;
108
96
  return value;
109
97
  }
110
-
111
- public readUUID() {
98
+ readUUID() {
112
99
  const value = this.buffer.toString('hex', this.offset, this.offset + 16);
113
100
  this.offset += 16;
114
101
  return value;
115
102
  }
116
-
117
- public readBoolean() {
103
+ readBoolean() {
118
104
  const value = this.buffer.readInt8(this.offset) === 1;
119
105
  this.offset += 1;
120
106
  return value;
121
107
  }
122
-
123
- public readArray<T>(callback: (opts: Decoder) => T): T[] {
108
+ readArray(callback) {
124
109
  const length = this.readInt32();
125
110
  const results = Array.from({ length }).map(() => callback(this));
126
111
  return results;
127
112
  }
128
-
129
- public readCompactArray<T>(callback: (opts: Decoder) => T): T[] {
113
+ readCompactArray(callback) {
130
114
  const length = this.readUVarInt() - 1;
131
115
  const results = Array.from({ length }).map(() => callback(this));
132
116
  return results;
133
117
  }
134
-
135
- public readRecords<T>(callback: (opts: Decoder) => T): T[] {
118
+ readVarIntArray(callback) {
119
+ const length = this.readVarInt();
120
+ const results = Array.from({ length }).map(() => callback(this));
121
+ return results;
122
+ }
123
+ readRecords(callback) {
136
124
  const length = this.readInt32();
137
-
138
125
  return Array.from({ length }).map(() => {
139
126
  const size = this.readVarInt();
140
127
  const child = new Decoder(this.buffer.subarray(this.offset, this.offset + size));
@@ -142,27 +129,24 @@ export class Decoder {
142
129
  return callback(child);
143
130
  });
144
131
  }
145
-
146
- public read(length: number) {
147
- const value = this.buffer.subarray(this.offset, this.offset + length);
148
- this.offset += length;
132
+ read(length) {
133
+ const value = this.buffer.subarray(this.offset, length !== undefined ? this.offset + length : undefined);
134
+ this.offset += Buffer.byteLength(value);
149
135
  return value;
150
136
  }
151
-
152
- public readBytes() {
137
+ readBytes() {
153
138
  const length = this.readInt32();
154
139
  return this.read(length);
155
140
  }
156
-
157
- public readCompactBytes() {
141
+ readCompactBytes() {
158
142
  const length = this.readUVarInt() - 1;
159
143
  if (length < 0) {
160
144
  return null;
161
145
  }
162
146
  return this.read(length);
163
147
  }
164
-
165
- public readTagBuffer() {
148
+ readTagBuffer() {
166
149
  this.readUVarInt();
167
150
  }
168
151
  }
152
+ exports.Decoder = Decoder;
@@ -0,0 +1 @@
1
+ export declare const delay: (delayMs: number) => Promise<void>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.delay = void 0;
4
+ const delay = (delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs));
5
+ exports.delay = delay;
@@ -0,0 +1,28 @@
1
+ /// <reference types="node" />
2
+ export declare class Encoder {
3
+ private chunks;
4
+ getChunks(): Buffer[];
5
+ getByteLength(): number;
6
+ write(...buffers: Buffer[]): this;
7
+ writeEncoder(encoder: Encoder): this;
8
+ writeInt8(value: number): this;
9
+ writeInt16(value: number): this;
10
+ writeInt32(value: number): this;
11
+ writeUInt32(value: number): this;
12
+ writeInt64(value: bigint): this;
13
+ writeUVarInt(value: number): this;
14
+ writeVarInt(value: number): this;
15
+ writeUVarLong(value: bigint): this;
16
+ writeVarLong(value: bigint): this;
17
+ writeString(value: string | null): this;
18
+ writeCompactString(value: string | null): this;
19
+ writeVarIntBuffer(buffer: Buffer | null): this;
20
+ writeUUID(value: string | null): this;
21
+ writeBoolean(value: boolean): this;
22
+ writeArray<T>(arr: T[], callback: (encoder: Encoder, item: T) => Encoder): this;
23
+ writeCompactArray<T>(arr: T[] | null, callback: (encoder: Encoder, item: T) => Encoder): this;
24
+ writeVarIntArray<T>(arr: T[], callback: (encoder: Encoder, item: T) => Encoder): this;
25
+ writeBytes(value: Buffer): this;
26
+ writeCompactBytes(value: Buffer): this;
27
+ value(): Buffer;
28
+ }