kafka-ts 0.0.2-beta → 0.0.2

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 (195) hide show
  1. package/.prettierrc +3 -2
  2. package/README.md +109 -39
  3. package/dist/api/api-versions.d.ts +9 -0
  4. package/dist/api/api-versions.js +24 -0
  5. package/dist/api/create-topics.d.ts +38 -0
  6. package/dist/api/create-topics.js +53 -0
  7. package/dist/api/delete-topics.d.ts +18 -0
  8. package/dist/api/delete-topics.js +33 -0
  9. package/dist/api/fetch.d.ts +84 -0
  10. package/dist/api/fetch.js +142 -0
  11. package/dist/api/find-coordinator.d.ts +21 -0
  12. package/dist/api/find-coordinator.js +39 -0
  13. package/dist/api/heartbeat.d.ts +11 -0
  14. package/dist/api/heartbeat.js +27 -0
  15. package/dist/api/index.d.ts +578 -0
  16. package/dist/api/index.js +165 -0
  17. package/dist/api/init-producer-id.d.ts +13 -0
  18. package/dist/api/init-producer-id.js +29 -0
  19. package/dist/api/join-group.d.ts +34 -0
  20. package/dist/api/join-group.js +51 -0
  21. package/dist/api/leave-group.d.ts +19 -0
  22. package/dist/api/leave-group.js +39 -0
  23. package/dist/api/list-offsets.d.ts +29 -0
  24. package/dist/api/list-offsets.js +48 -0
  25. package/dist/api/metadata.d.ts +40 -0
  26. package/dist/api/metadata.js +58 -0
  27. package/dist/api/offset-commit.d.ts +28 -0
  28. package/dist/api/offset-commit.js +48 -0
  29. package/dist/api/offset-fetch.d.ts +33 -0
  30. package/dist/api/offset-fetch.js +57 -0
  31. package/dist/api/produce.d.ts +54 -0
  32. package/dist/api/produce.js +126 -0
  33. package/dist/api/sasl-authenticate.d.ts +11 -0
  34. package/dist/api/sasl-authenticate.js +23 -0
  35. package/dist/api/sasl-handshake.d.ts +6 -0
  36. package/dist/api/sasl-handshake.js +19 -0
  37. package/dist/api/sync-group.d.ts +24 -0
  38. package/dist/api/sync-group.js +36 -0
  39. package/dist/auth/index.d.ts +2 -0
  40. package/dist/auth/index.js +8 -0
  41. package/dist/auth/plain.d.ts +5 -0
  42. package/dist/auth/plain.js +12 -0
  43. package/dist/auth/scram.d.ts +9 -0
  44. package/dist/auth/scram.js +40 -0
  45. package/dist/broker.d.ts +30 -0
  46. package/dist/broker.js +55 -0
  47. package/dist/client.d.ts +23 -0
  48. package/dist/client.js +36 -0
  49. package/dist/cluster.d.ts +27 -0
  50. package/dist/cluster.js +70 -0
  51. package/dist/cluster.test.d.ts +1 -0
  52. package/dist/cluster.test.js +345 -0
  53. package/dist/codecs/gzip.d.ts +2 -0
  54. package/dist/codecs/gzip.js +8 -0
  55. package/dist/codecs/index.d.ts +2 -0
  56. package/dist/codecs/index.js +17 -0
  57. package/dist/codecs/none.d.ts +2 -0
  58. package/dist/codecs/none.js +7 -0
  59. package/dist/codecs/types.d.ts +5 -0
  60. package/dist/codecs/types.js +2 -0
  61. package/dist/connection.d.ts +26 -0
  62. package/dist/connection.js +175 -0
  63. package/dist/consumer/consumer-group.d.ts +41 -0
  64. package/dist/consumer/consumer-group.js +217 -0
  65. package/dist/consumer/consumer-metadata.d.ts +7 -0
  66. package/dist/consumer/consumer-metadata.js +14 -0
  67. package/dist/consumer/consumer.d.ts +44 -0
  68. package/dist/consumer/consumer.js +225 -0
  69. package/dist/consumer/fetch-manager.d.ts +33 -0
  70. package/dist/consumer/fetch-manager.js +140 -0
  71. package/dist/consumer/fetcher.d.ts +25 -0
  72. package/dist/consumer/fetcher.js +64 -0
  73. package/dist/consumer/offset-manager.d.ts +22 -0
  74. package/dist/consumer/offset-manager.js +66 -0
  75. package/dist/consumer/processor.d.ts +19 -0
  76. package/dist/consumer/processor.js +59 -0
  77. package/dist/distributors/assignments-to-replicas.d.ts +16 -0
  78. package/dist/distributors/assignments-to-replicas.js +59 -0
  79. package/dist/distributors/assignments-to-replicas.test.d.ts +1 -0
  80. package/dist/distributors/assignments-to-replicas.test.js +40 -0
  81. package/dist/distributors/messages-to-topic-partition-leaders.d.ts +17 -0
  82. package/dist/distributors/messages-to-topic-partition-leaders.js +15 -0
  83. package/dist/distributors/messages-to-topic-partition-leaders.test.d.ts +1 -0
  84. package/dist/distributors/messages-to-topic-partition-leaders.test.js +30 -0
  85. package/dist/distributors/partitioner.d.ts +7 -0
  86. package/dist/distributors/partitioner.js +23 -0
  87. package/dist/index.d.ts +9 -0
  88. package/dist/index.js +26 -0
  89. package/dist/metadata.d.ts +24 -0
  90. package/dist/metadata.js +106 -0
  91. package/dist/producer/producer.d.ts +24 -0
  92. package/dist/producer/producer.js +131 -0
  93. package/dist/types.d.ts +11 -0
  94. package/dist/types.js +2 -0
  95. package/dist/utils/api.d.ts +9 -0
  96. package/dist/utils/api.js +5 -0
  97. package/dist/utils/crypto.d.ts +8 -0
  98. package/dist/utils/crypto.js +18 -0
  99. package/dist/utils/decoder.d.ts +30 -0
  100. package/dist/utils/decoder.js +152 -0
  101. package/dist/utils/delay.d.ts +1 -0
  102. package/dist/utils/delay.js +5 -0
  103. package/dist/utils/encoder.d.ts +28 -0
  104. package/dist/utils/encoder.js +125 -0
  105. package/dist/utils/error.d.ts +11 -0
  106. package/dist/utils/error.js +27 -0
  107. package/dist/utils/logger.d.ts +9 -0
  108. package/dist/utils/logger.js +32 -0
  109. package/dist/utils/memo.d.ts +1 -0
  110. package/dist/utils/memo.js +16 -0
  111. package/dist/utils/murmur2.d.ts +3 -0
  112. package/dist/utils/murmur2.js +40 -0
  113. package/dist/utils/retrier.d.ts +10 -0
  114. package/dist/utils/retrier.js +22 -0
  115. package/dist/utils/tracer.d.ts +5 -0
  116. package/dist/utils/tracer.js +39 -0
  117. package/package.json +30 -19
  118. package/src/__snapshots__/{request-handler.test.ts.snap → cluster.test.ts.snap} +329 -26
  119. package/src/api/api-versions.ts +2 -2
  120. package/src/api/create-topics.ts +2 -2
  121. package/src/api/delete-topics.ts +2 -2
  122. package/src/api/fetch.ts +86 -31
  123. package/src/api/find-coordinator.ts +2 -2
  124. package/src/api/heartbeat.ts +2 -2
  125. package/src/api/index.ts +21 -19
  126. package/src/api/init-producer-id.ts +2 -2
  127. package/src/api/join-group.ts +3 -3
  128. package/src/api/leave-group.ts +2 -2
  129. package/src/api/list-offsets.ts +3 -3
  130. package/src/api/metadata.ts +3 -3
  131. package/src/api/offset-commit.ts +2 -2
  132. package/src/api/offset-fetch.ts +2 -2
  133. package/src/api/produce.ts +17 -20
  134. package/src/api/sasl-authenticate.ts +2 -2
  135. package/src/api/sasl-handshake.ts +2 -2
  136. package/src/api/sync-group.ts +2 -2
  137. package/src/auth/index.ts +2 -0
  138. package/src/auth/plain.ts +10 -0
  139. package/src/auth/scram.ts +52 -0
  140. package/src/broker.ts +12 -14
  141. package/src/client.ts +7 -7
  142. package/src/cluster.test.ts +78 -74
  143. package/src/cluster.ts +43 -45
  144. package/src/codecs/gzip.ts +9 -0
  145. package/src/codecs/index.ts +16 -0
  146. package/src/codecs/none.ts +6 -0
  147. package/src/codecs/types.ts +4 -0
  148. package/src/connection.ts +49 -33
  149. package/src/consumer/consumer-group.ts +57 -35
  150. package/src/consumer/consumer-metadata.ts +2 -2
  151. package/src/consumer/consumer.ts +115 -92
  152. package/src/consumer/fetch-manager.ts +169 -0
  153. package/src/consumer/fetcher.ts +64 -0
  154. package/src/consumer/offset-manager.ts +24 -13
  155. package/src/consumer/processor.ts +53 -0
  156. package/src/distributors/assignments-to-replicas.test.ts +7 -7
  157. package/src/distributors/assignments-to-replicas.ts +2 -4
  158. package/src/distributors/messages-to-topic-partition-leaders.test.ts +6 -6
  159. package/src/distributors/partitioner.ts +27 -0
  160. package/src/index.ts +9 -3
  161. package/src/metadata.ts +8 -4
  162. package/src/producer/producer.ts +30 -20
  163. package/src/types.ts +5 -3
  164. package/src/utils/api.ts +5 -5
  165. package/src/utils/crypto.ts +15 -0
  166. package/src/utils/decoder.ts +14 -8
  167. package/src/utils/encoder.ts +34 -27
  168. package/src/utils/error.ts +3 -3
  169. package/src/utils/logger.ts +37 -0
  170. package/src/utils/murmur2.ts +44 -0
  171. package/src/utils/retrier.ts +1 -1
  172. package/src/utils/tracer.ts +41 -20
  173. package/tsconfig.json +16 -16
  174. package/.github/workflows/release.yml +0 -17
  175. package/certs/ca.crt +0 -29
  176. package/certs/ca.key +0 -52
  177. package/certs/ca.srl +0 -1
  178. package/certs/kafka.crt +0 -29
  179. package/certs/kafka.csr +0 -26
  180. package/certs/kafka.key +0 -52
  181. package/certs/kafka.keystore.jks +0 -0
  182. package/certs/kafka.truststore.jks +0 -0
  183. package/docker-compose.yml +0 -104
  184. package/examples/package-lock.json +0 -31
  185. package/examples/package.json +0 -14
  186. package/examples/src/client.ts +0 -9
  187. package/examples/src/consumer.ts +0 -17
  188. package/examples/src/create-topic.ts +0 -37
  189. package/examples/src/producer.ts +0 -24
  190. package/examples/src/replicator.ts +0 -25
  191. package/examples/src/utils/json.ts +0 -1
  192. package/examples/tsconfig.json +0 -7
  193. package/log4j.properties +0 -95
  194. package/scripts/generate-certs.sh +0 -24
  195. package/src/utils/debug.ts +0 -9
@@ -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);
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ export type Message = {
3
+ topic: string;
4
+ partition?: number;
5
+ offset?: bigint;
6
+ timestamp?: bigint;
7
+ key?: Buffer | null;
8
+ value: Buffer | null;
9
+ headers?: Record<string, string>;
10
+ };
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 });
@@ -0,0 +1,9 @@
1
+ import { Decoder } from './decoder';
2
+ import { Encoder } from './encoder';
3
+ export type Api<Request, Response> = {
4
+ apiKey: number;
5
+ apiVersion: number;
6
+ request: (encoder: Encoder, body: Request) => Encoder;
7
+ response: (buffer: Decoder) => Promise<Response> | Response;
8
+ };
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
+ }
@@ -0,0 +1,152 @@
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() {
11
+ return this.offset;
12
+ }
13
+ getBufferLength() {
14
+ return this.buffer.length;
15
+ }
16
+ readInt8() {
17
+ const value = this.buffer.readInt8(this.offset);
18
+ this.offset += 1;
19
+ return value;
20
+ }
21
+ readInt16() {
22
+ const value = this.buffer.readInt16BE(this.offset);
23
+ this.offset += 2;
24
+ return value;
25
+ }
26
+ readInt32() {
27
+ const value = this.buffer.readInt32BE(this.offset);
28
+ this.offset += 4;
29
+ return value;
30
+ }
31
+ readUInt32() {
32
+ const value = this.buffer.readUInt32BE(this.offset);
33
+ this.offset += 4;
34
+ return value;
35
+ }
36
+ readInt64() {
37
+ const value = this.buffer.readBigInt64BE(this.offset);
38
+ this.offset += 8;
39
+ return value;
40
+ }
41
+ readUVarInt() {
42
+ let result = 0;
43
+ let shift = 0;
44
+ let currentByte;
45
+ do {
46
+ currentByte = this.buffer[this.offset++];
47
+ result |= (currentByte & 0x7f) << shift;
48
+ shift += 7;
49
+ } while ((currentByte & 0x80) !== 0);
50
+ return result;
51
+ }
52
+ readVarInt() {
53
+ const decodedValue = this.readUVarInt();
54
+ return (decodedValue >>> 1) ^ -(decodedValue & 1);
55
+ }
56
+ readUVarLong() {
57
+ let result = BigInt(0);
58
+ let shift = BigInt(0);
59
+ let currentByte;
60
+ do {
61
+ currentByte = BigInt(this.buffer[this.offset++]);
62
+ result |= (currentByte & BigInt(0x7f)) << shift;
63
+ shift += BigInt(7);
64
+ } while ((currentByte & BigInt(0x80)) !== BigInt(0));
65
+ return result;
66
+ }
67
+ readVarLong() {
68
+ const decodedValue = this.readUVarLong();
69
+ return (decodedValue >> BigInt(1)) ^ -(decodedValue & BigInt(1));
70
+ }
71
+ readString() {
72
+ const length = this.readInt16();
73
+ if (length < 0) {
74
+ return null;
75
+ }
76
+ const value = this.buffer.toString('utf-8', this.offset, this.offset + length);
77
+ this.offset += length;
78
+ return value;
79
+ }
80
+ readCompactString() {
81
+ const length = this.readUVarInt() - 1;
82
+ if (length < 0) {
83
+ return null;
84
+ }
85
+ const value = this.buffer.toString('utf-8', this.offset, this.offset + length);
86
+ this.offset += length;
87
+ return value;
88
+ }
89
+ readVarIntBuffer() {
90
+ const length = this.readVarInt();
91
+ if (length < 0) {
92
+ return null;
93
+ }
94
+ const value = this.buffer.subarray(this.offset, this.offset + length);
95
+ this.offset += length;
96
+ return value;
97
+ }
98
+ readUUID() {
99
+ const value = this.buffer.toString('hex', this.offset, this.offset + 16);
100
+ this.offset += 16;
101
+ return value;
102
+ }
103
+ readBoolean() {
104
+ const value = this.buffer.readInt8(this.offset) === 1;
105
+ this.offset += 1;
106
+ return value;
107
+ }
108
+ readArray(callback) {
109
+ const length = this.readInt32();
110
+ const results = Array.from({ length }).map(() => callback(this));
111
+ return results;
112
+ }
113
+ readCompactArray(callback) {
114
+ const length = this.readUVarInt() - 1;
115
+ const results = Array.from({ length }).map(() => callback(this));
116
+ return results;
117
+ }
118
+ readVarIntArray(callback) {
119
+ const length = this.readVarInt();
120
+ const results = Array.from({ length }).map(() => callback(this));
121
+ return results;
122
+ }
123
+ readRecords(callback) {
124
+ const length = this.readInt32();
125
+ return Array.from({ length }).map(() => {
126
+ const size = this.readVarInt();
127
+ const child = new Decoder(this.buffer.subarray(this.offset, this.offset + size));
128
+ this.offset += size;
129
+ return callback(child);
130
+ });
131
+ }
132
+ read(length) {
133
+ const value = this.buffer.subarray(this.offset, length !== undefined ? this.offset + length : undefined);
134
+ this.offset += Buffer.byteLength(value);
135
+ return value;
136
+ }
137
+ readBytes() {
138
+ const length = this.readInt32();
139
+ return this.read(length);
140
+ }
141
+ readCompactBytes() {
142
+ const length = this.readUVarInt() - 1;
143
+ if (length < 0) {
144
+ return null;
145
+ }
146
+ return this.read(length);
147
+ }
148
+ readTagBuffer() {
149
+ this.readUVarInt();
150
+ }
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
+ }