@mip-client/ts 1.0.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.
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # MIP-client-ts
2
+
3
+ TypeScript client for the MIP (MSIP) protocol - handles connections, events, errors, and auto-reconnection.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install mip-client-ts
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic Connection
14
+
15
+ ```typescript
16
+ import { MIPClient } from "mip-client-ts";
17
+
18
+ const client = new MIPClient({
19
+ host: "127.0.0.1",
20
+ port: 9000,
21
+ });
22
+
23
+ // Events
24
+ client.on("connect", () => {
25
+ console.log("Connected to server");
26
+ });
27
+
28
+ client.on("disconnect", () => {
29
+ console.log("Disconnected");
30
+ });
31
+
32
+ client.on("error", (err) => {
33
+ console.error("Error:", err.message);
34
+ });
35
+
36
+ client.on("message", (msg) => {
37
+ console.log(`[${msg.topic}] ${msg.message}`);
38
+ });
39
+
40
+ // Connect
41
+ await client.connect();
42
+ ```
43
+
44
+ ### Subscribe / Publish
45
+
46
+ ```typescript
47
+ // Subscribe to a topic
48
+ client.subscribe("my-topic");
49
+
50
+ // Listen for messages
51
+ client.on("message", (msg) => {
52
+ console.log(`Topic: ${msg.topic}`);
53
+ console.log(`Message: ${msg.message}`);
54
+ });
55
+
56
+ // Publish a message
57
+ client.publish("my-topic", "Hello World!");
58
+ ```
59
+
60
+ ### Advanced Options
61
+
62
+ ```typescript
63
+ import { MIPClient, Flags } from "mip-client-ts";
64
+
65
+ const client = new MIPClient({
66
+ host: "127.0.0.1",
67
+ port: 9000,
68
+ autoReconnect: true, // Auto-reconnect (default: true)
69
+ reconnectDelay: 3000, // Delay between reconnections (default: 3000ms)
70
+ maxReconnectAttempts: 10, // Max attempts (0 = infinite)
71
+ pingInterval: 5000, // Automatic ping (0 = disabled)
72
+ });
73
+
74
+ // Publish with flags
75
+ client.publish("urgent-topic", "Important!", Flags.URGENT | Flags.ACK_REQUIRED);
76
+
77
+ // Listen for ACKs
78
+ client.on("ack", (msgId) => {
79
+ console.log("ACK received for:", msgId.toString());
80
+ });
81
+
82
+ // Manual ping
83
+ client.ping();
84
+ client.on("pong", () => {
85
+ console.log("Pong received!");
86
+ });
87
+ ```
88
+
89
+ ### Auto-Reconnection
90
+
91
+ ```typescript
92
+ client.on("reconnecting", (attempt) => {
93
+ console.log(`Reconnection attempt #${attempt}...`);
94
+ });
95
+
96
+ client.on("connect", () => {
97
+ // Re-subscribe after reconnection
98
+ client.subscribe("my-topic");
99
+ });
100
+ ```
101
+
102
+ ### Factory Function
103
+
104
+ ```typescript
105
+ import { createClient } from "mip-client-ts";
106
+
107
+ const client = createClient("127.0.0.1", 9000, {
108
+ autoReconnect: true,
109
+ pingInterval: 10000,
110
+ });
111
+ ```
112
+
113
+ ## API
114
+
115
+ ### `MIPClient`
116
+
117
+ #### Constructor Options
118
+
119
+ | Option | Type | Default | Description |
120
+ | ---------------------- | --------- | ------- | -------------------------------------- |
121
+ | `host` | `string` | - | Server address |
122
+ | `port` | `number` | - | Server port |
123
+ | `autoReconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
124
+ | `reconnectDelay` | `number` | `3000` | Delay between reconnections (ms) |
125
+ | `maxReconnectAttempts` | `number` | `10` |Max reconnection attempts (0 = infinite)|
126
+ | `pingInterval` | `number` | `0` | Ping interval (0 = disabled) |
127
+
128
+ #### Methods
129
+
130
+ - `connect(): Promise<void>` - Connect to server
131
+ - `disconnect(): void` - Disconnect from server
132
+ - `subscribe(topic: string, requireAck?: boolean): bigint` - Subscribe to a topic
133
+ - `unsubscribe(topic: string, requireAck?: boolean): bigint` - Unsubscribe from a topic
134
+ - `publish(topic: string, message: string | Buffer, flags?: number): bigint` - Publish a message
135
+ - `ping(): bigint` - Send a ping
136
+
137
+ #### Events
138
+
139
+ - `connect` - Connection established
140
+ - `disconnect` - Disconnected
141
+ - `reconnecting(attempt)` - Reconnection attempt
142
+ - `message(msg)` - Message received (PUBLISH or EVENT)
143
+ - `event(msg)` - Event received (EVENT only)
144
+ - `ack(msgId)` - ACK received
145
+ - `pong` - Pong received
146
+ - `error(error)` - Error occurred
147
+ - `frame(header, payload)` - Raw frame (advanced usage)
148
+
149
+ ### Constants
150
+
151
+ ```typescript
152
+ import { FrameType, Flags } from "mip-client-ts";
153
+
154
+ // Frame types
155
+ FrameType.HELLO // 0x0001
156
+ FrameType.SUBSCRIBE // 0x0002
157
+ FrameType.UNSUBSCRIBE // 0x0003
158
+ FrameType.PUBLISH // 0x0004
159
+ FrameType.EVENT // 0x0005
160
+ FrameType.ACK // 0x0006
161
+ FrameType.ERROR // 0x0007
162
+ FrameType.PING // 0x0008
163
+ FrameType.PONG // 0x0009
164
+ FrameType.CLOSE // 0x000A
165
+
166
+ // Flags
167
+ Flags.NONE // 0b00000000
168
+ Flags.ACK_REQUIRED // 0b00000001
169
+ Flags.COMPRESSED // 0b00000010
170
+ Flags.URGENT // 0b00000100
171
+ ```
172
+
173
+ ## License
174
+
175
+ MIT License
@@ -0,0 +1,122 @@
1
+ import { EventEmitter } from "events";
2
+ /** Frame types for the MIP protocol */
3
+ export declare const FrameType: {
4
+ readonly HELLO: 1;
5
+ readonly SUBSCRIBE: 2;
6
+ readonly UNSUBSCRIBE: 3;
7
+ readonly PUBLISH: 4;
8
+ readonly EVENT: 5;
9
+ readonly ACK: 6;
10
+ readonly ERROR: 7;
11
+ readonly PING: 8;
12
+ readonly PONG: 9;
13
+ readonly CLOSE: 10;
14
+ };
15
+ export type FrameTypeValue = (typeof FrameType)[keyof typeof FrameType];
16
+ /** Flags for frame options */
17
+ export declare const Flags: {
18
+ readonly NONE: 0;
19
+ readonly ACK_REQUIRED: 1;
20
+ readonly COMPRESSED: 2;
21
+ readonly URGENT: 4;
22
+ };
23
+ export type FlagsValue = (typeof Flags)[keyof typeof Flags];
24
+ /** Configuration options for the MIP client */
25
+ export interface MIPClientOptions {
26
+ /** Server host address */
27
+ host: string;
28
+ /** Server port number */
29
+ port: number;
30
+ /** Auto-reconnect on disconnect (default: true) */
31
+ autoReconnect?: boolean;
32
+ /** Reconnect delay in milliseconds (default: 3000) */
33
+ reconnectDelay?: number;
34
+ /** Maximum reconnection attempts (default: 10, 0 = infinite) */
35
+ maxReconnectAttempts?: number;
36
+ /** Enable ping interval in milliseconds (default: 0 = disabled) */
37
+ pingInterval?: number;
38
+ }
39
+ /** Parsed frame header */
40
+ export interface FrameHeader {
41
+ magic: number;
42
+ version: number;
43
+ flags: number;
44
+ frameType: FrameTypeValue;
45
+ msgKind: number;
46
+ payloadLength: number;
47
+ msgId: bigint;
48
+ }
49
+ /** Received message event */
50
+ export interface MIPMessage {
51
+ header: FrameHeader;
52
+ topic: string;
53
+ message: string;
54
+ }
55
+ /** Error details */
56
+ export interface MIPError {
57
+ code?: number;
58
+ message: string;
59
+ raw?: Buffer;
60
+ }
61
+ /** Events emitted by the MIP client */
62
+ export interface MIPClientEvents {
63
+ connect: () => void;
64
+ disconnect: () => void;
65
+ reconnecting: (attempt: number) => void;
66
+ message: (msg: MIPMessage) => void;
67
+ event: (msg: MIPMessage) => void;
68
+ ack: (msgId: bigint) => void;
69
+ pong: () => void;
70
+ error: (error: MIPError) => void;
71
+ frame: (header: FrameHeader, payload: Buffer) => void;
72
+ }
73
+ export declare class MIPClient extends EventEmitter {
74
+ private socket;
75
+ private buffer;
76
+ private options;
77
+ private connected;
78
+ private reconnectAttempts;
79
+ private reconnectTimer;
80
+ private pingTimer;
81
+ private msgIdCounter;
82
+ constructor(options: MIPClientOptions);
83
+ /** Check if the client is connected */
84
+ get isConnected(): boolean;
85
+ /** Connect to the MIP server */
86
+ connect(): Promise<void>;
87
+ /** Disconnect from the server */
88
+ disconnect(): void;
89
+ /** Subscribe to a topic */
90
+ subscribe(topic: string, requireAck?: boolean): bigint;
91
+ /** Unsubscribe from a topic */
92
+ unsubscribe(topic: string, requireAck?: boolean): bigint;
93
+ /** Publish a message to a topic */
94
+ publish(topic: string, message: string | Buffer, flags?: number): bigint;
95
+ /** Send a ping to the server */
96
+ ping(): bigint;
97
+ /** Send raw frame (advanced usage) */
98
+ sendRawFrame(frameType: FrameTypeValue, payload: Buffer, flags?: number): bigint;
99
+ on<K extends keyof MIPClientEvents>(event: K, listener: MIPClientEvents[K]): this;
100
+ once<K extends keyof MIPClientEvents>(event: K, listener: MIPClientEvents[K]): this;
101
+ emit<K extends keyof MIPClientEvents>(event: K, ...args: Parameters<MIPClientEvents[K]>): boolean;
102
+ off<K extends keyof MIPClientEvents>(event: K, listener: MIPClientEvents[K]): this;
103
+ private generateMsgId;
104
+ private buildHeader;
105
+ private sendFrame;
106
+ private sendClose;
107
+ private handleData;
108
+ private parseHeader;
109
+ private processFrame;
110
+ private parseMessage;
111
+ private handleClose;
112
+ private scheduleReconnect;
113
+ private setupPingInterval;
114
+ private cleanup;
115
+ private emitError;
116
+ }
117
+ /** Get the name of a frame type */
118
+ export declare function getFrameTypeName(type: FrameTypeValue): string;
119
+ /** Create a client with default options */
120
+ export declare function createClient(host?: string, port?: number, options?: Partial<MIPClientOptions>): MIPClient;
121
+ export default MIPClient;
122
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,346 @@
1
+ import * as net from "net";
2
+ import { EventEmitter } from "events";
3
+ // ============================================================================
4
+ // Constants
5
+ // ============================================================================
6
+ const MAGIC = 0x4d534950; // "MSIP"
7
+ const VERSION = 1;
8
+ const HEADER_SIZE = 24;
9
+ /** Frame types for the MIP protocol */
10
+ export const FrameType = {
11
+ HELLO: 0x0001,
12
+ SUBSCRIBE: 0x0002,
13
+ UNSUBSCRIBE: 0x0003,
14
+ PUBLISH: 0x0004,
15
+ EVENT: 0x0005,
16
+ ACK: 0x0006,
17
+ ERROR: 0x0007,
18
+ PING: 0x0008,
19
+ PONG: 0x0009,
20
+ CLOSE: 0x000a,
21
+ };
22
+ /** Flags for frame options */
23
+ export const Flags = {
24
+ NONE: 0b0000_0000,
25
+ ACK_REQUIRED: 0b0000_0001,
26
+ COMPRESSED: 0b0000_0010,
27
+ URGENT: 0b0000_0100,
28
+ };
29
+ const MSG_KIND_EVENT = 0x0001;
30
+ // ============================================================================
31
+ // MIP Client Class
32
+ // ============================================================================
33
+ export class MIPClient extends EventEmitter {
34
+ socket = null;
35
+ buffer = Buffer.alloc(0);
36
+ options;
37
+ connected = false;
38
+ reconnectAttempts = 0;
39
+ reconnectTimer = null;
40
+ pingTimer = null;
41
+ msgIdCounter = 0n;
42
+ constructor(options) {
43
+ super();
44
+ this.options = {
45
+ host: options.host,
46
+ port: options.port,
47
+ autoReconnect: options.autoReconnect ?? true,
48
+ reconnectDelay: options.reconnectDelay ?? 3000,
49
+ maxReconnectAttempts: options.maxReconnectAttempts ?? 10,
50
+ pingInterval: options.pingInterval ?? 0,
51
+ };
52
+ }
53
+ // --------------------------------------------------------------------------
54
+ // Public API
55
+ // --------------------------------------------------------------------------
56
+ /** Check if the client is connected */
57
+ get isConnected() {
58
+ return this.connected;
59
+ }
60
+ /** Connect to the MIP server */
61
+ connect() {
62
+ return new Promise((resolve, reject) => {
63
+ if (this.connected) {
64
+ resolve();
65
+ return;
66
+ }
67
+ this.socket = new net.Socket();
68
+ this.buffer = Buffer.alloc(0);
69
+ const onConnect = () => {
70
+ this.connected = true;
71
+ this.reconnectAttempts = 0;
72
+ this.setupPingInterval();
73
+ this.emit("connect");
74
+ resolve();
75
+ };
76
+ const onError = (err) => {
77
+ if (!this.connected) {
78
+ reject(err);
79
+ }
80
+ this.emitError({ message: err.message });
81
+ };
82
+ this.socket.once("connect", onConnect);
83
+ this.socket.once("error", onError);
84
+ this.socket.on("data", this.handleData.bind(this));
85
+ this.socket.on("close", this.handleClose.bind(this));
86
+ this.socket.on("error", (err) => {
87
+ if (this.connected) {
88
+ this.emitError({ message: err.message });
89
+ }
90
+ });
91
+ this.socket.connect(this.options.port, this.options.host);
92
+ });
93
+ }
94
+ /** Disconnect from the server */
95
+ disconnect() {
96
+ this.options.autoReconnect = false;
97
+ this.cleanup();
98
+ if (this.socket) {
99
+ this.sendClose();
100
+ this.socket.destroy();
101
+ this.socket = null;
102
+ }
103
+ this.connected = false;
104
+ }
105
+ /** Subscribe to a topic */
106
+ subscribe(topic, requireAck = true) {
107
+ const topicBuffer = Buffer.from(topic, "utf-8");
108
+ const flags = requireAck ? Flags.ACK_REQUIRED : Flags.NONE;
109
+ const msgId = this.sendFrame(FrameType.SUBSCRIBE, topicBuffer, flags);
110
+ return msgId;
111
+ }
112
+ /** Unsubscribe from a topic */
113
+ unsubscribe(topic, requireAck = true) {
114
+ const topicBuffer = Buffer.from(topic, "utf-8");
115
+ const flags = requireAck ? Flags.ACK_REQUIRED : Flags.NONE;
116
+ const msgId = this.sendFrame(FrameType.UNSUBSCRIBE, topicBuffer, flags);
117
+ return msgId;
118
+ }
119
+ /** Publish a message to a topic */
120
+ publish(topic, message, flags = Flags.NONE) {
121
+ const topicBuffer = Buffer.from(topic, "utf-8");
122
+ const messageBuffer = Buffer.isBuffer(message)
123
+ ? message
124
+ : Buffer.from(message, "utf-8");
125
+ const payload = Buffer.alloc(2 + topicBuffer.length + messageBuffer.length);
126
+ payload.writeUInt16BE(topicBuffer.length, 0);
127
+ topicBuffer.copy(payload, 2);
128
+ messageBuffer.copy(payload, 2 + topicBuffer.length);
129
+ const msgId = this.sendFrame(FrameType.PUBLISH, payload, flags);
130
+ return msgId;
131
+ }
132
+ /** Send a ping to the server */
133
+ ping() {
134
+ return this.sendFrame(FrameType.PING, Buffer.alloc(0));
135
+ }
136
+ /** Send raw frame (advanced usage) */
137
+ sendRawFrame(frameType, payload, flags = 0) {
138
+ return this.sendFrame(frameType, payload, flags);
139
+ }
140
+ // --------------------------------------------------------------------------
141
+ // Event Emitter Override for Type Safety
142
+ // --------------------------------------------------------------------------
143
+ on(event, listener) {
144
+ return super.on(event, listener);
145
+ }
146
+ once(event, listener) {
147
+ return super.once(event, listener);
148
+ }
149
+ emit(event, ...args) {
150
+ return super.emit(event, ...args);
151
+ }
152
+ off(event, listener) {
153
+ return super.off(event, listener);
154
+ }
155
+ // --------------------------------------------------------------------------
156
+ // Private Methods
157
+ // --------------------------------------------------------------------------
158
+ generateMsgId() {
159
+ this.msgIdCounter++;
160
+ return BigInt(Date.now()) * 1000000n + this.msgIdCounter;
161
+ }
162
+ buildHeader(frameType, payloadLength, flags = 0, msgId) {
163
+ const header = Buffer.alloc(HEADER_SIZE);
164
+ let offset = 0;
165
+ const id = msgId ?? this.generateMsgId();
166
+ header.writeUInt32BE(MAGIC, offset);
167
+ offset += 4;
168
+ header.writeUInt8(VERSION, offset);
169
+ offset += 1;
170
+ header.writeUInt8(flags, offset);
171
+ offset += 1;
172
+ header.writeUInt16BE(frameType, offset);
173
+ offset += 2;
174
+ header.writeUInt16BE(MSG_KIND_EVENT, offset);
175
+ offset += 2;
176
+ header.writeUInt16BE(0, offset);
177
+ offset += 2; // reserved
178
+ header.writeUInt32BE(payloadLength, offset);
179
+ offset += 4;
180
+ header.writeBigUInt64BE(id, offset);
181
+ return header;
182
+ }
183
+ sendFrame(frameType, payload, flags = 0) {
184
+ if (!this.socket || !this.connected) {
185
+ throw new Error("Client is not connected");
186
+ }
187
+ const msgId = this.generateMsgId();
188
+ const header = this.buildHeader(frameType, payload.length, flags, msgId);
189
+ this.socket.write(Buffer.concat([header, payload]));
190
+ return msgId;
191
+ }
192
+ sendClose() {
193
+ if (this.socket && this.connected) {
194
+ try {
195
+ const header = this.buildHeader(FrameType.CLOSE, 0);
196
+ this.socket.write(header);
197
+ }
198
+ catch {
199
+ // Ignore errors during close
200
+ }
201
+ }
202
+ }
203
+ handleData(data) {
204
+ this.buffer = Buffer.concat([this.buffer, data]);
205
+ while (this.buffer.length >= HEADER_SIZE) {
206
+ const magic = this.buffer.readUInt32BE(0);
207
+ if (magic !== MAGIC) {
208
+ this.emitError({ message: "Invalid magic number", code: magic });
209
+ this.socket?.destroy();
210
+ return;
211
+ }
212
+ const payloadLength = this.buffer.readUInt32BE(12);
213
+ if (this.buffer.length < HEADER_SIZE + payloadLength) {
214
+ return; // Wait for more data
215
+ }
216
+ const header = this.parseHeader(this.buffer.subarray(0, HEADER_SIZE));
217
+ const payload = this.buffer.subarray(HEADER_SIZE, HEADER_SIZE + payloadLength);
218
+ this.processFrame(header, payload);
219
+ this.buffer = this.buffer.subarray(HEADER_SIZE + payloadLength);
220
+ }
221
+ }
222
+ parseHeader(buffer) {
223
+ return {
224
+ magic: buffer.readUInt32BE(0),
225
+ version: buffer.readUInt8(4),
226
+ flags: buffer.readUInt8(5),
227
+ frameType: buffer.readUInt16BE(6),
228
+ msgKind: buffer.readUInt16BE(8),
229
+ payloadLength: buffer.readUInt32BE(12),
230
+ msgId: buffer.readBigUInt64BE(16),
231
+ };
232
+ }
233
+ processFrame(header, payload) {
234
+ // Emit raw frame event for advanced usage
235
+ this.emit("frame", header, payload);
236
+ switch (header.frameType) {
237
+ case FrameType.EVENT:
238
+ case FrameType.PUBLISH: {
239
+ const msg = this.parseMessage(header, payload);
240
+ if (msg) {
241
+ if (header.frameType === FrameType.EVENT) {
242
+ this.emit("event", msg);
243
+ }
244
+ this.emit("message", msg);
245
+ }
246
+ break;
247
+ }
248
+ case FrameType.ACK:
249
+ this.emit("ack", header.msgId);
250
+ break;
251
+ case FrameType.PONG:
252
+ this.emit("pong");
253
+ break;
254
+ case FrameType.ERROR: {
255
+ const errorMsg = payload.toString("utf-8");
256
+ this.emitError({ message: errorMsg, raw: payload });
257
+ break;
258
+ }
259
+ case FrameType.CLOSE:
260
+ this.handleClose();
261
+ break;
262
+ }
263
+ }
264
+ parseMessage(header, payload) {
265
+ if (payload.length < 2) {
266
+ return null;
267
+ }
268
+ const topicLength = payload.readUInt16BE(0);
269
+ if (payload.length < 2 + topicLength) {
270
+ return null;
271
+ }
272
+ const topic = payload.subarray(2, 2 + topicLength).toString("utf-8");
273
+ const message = payload.subarray(2 + topicLength).toString("utf-8");
274
+ return { topic, message, header };
275
+ }
276
+ handleClose() {
277
+ const wasConnected = this.connected;
278
+ this.connected = false;
279
+ this.cleanup();
280
+ if (wasConnected) {
281
+ this.emit("disconnect");
282
+ }
283
+ if (this.options.autoReconnect) {
284
+ this.scheduleReconnect();
285
+ }
286
+ }
287
+ scheduleReconnect() {
288
+ if (this.reconnectTimer) {
289
+ return;
290
+ }
291
+ const maxAttempts = this.options.maxReconnectAttempts;
292
+ if (maxAttempts > 0 && this.reconnectAttempts >= maxAttempts) {
293
+ this.emitError({
294
+ message: `Max reconnection attempts (${maxAttempts}) reached`,
295
+ });
296
+ return;
297
+ }
298
+ this.reconnectAttempts++;
299
+ this.emit("reconnecting", this.reconnectAttempts);
300
+ this.reconnectTimer = setTimeout(() => {
301
+ this.reconnectTimer = null;
302
+ this.connect().catch(() => {
303
+ // Error already emitted, will retry if autoReconnect is still true
304
+ if (this.options.autoReconnect) {
305
+ this.scheduleReconnect();
306
+ }
307
+ });
308
+ }, this.options.reconnectDelay);
309
+ }
310
+ setupPingInterval() {
311
+ if (this.options.pingInterval > 0) {
312
+ this.pingTimer = setInterval(() => {
313
+ if (this.connected) {
314
+ this.ping();
315
+ }
316
+ }, this.options.pingInterval);
317
+ }
318
+ }
319
+ cleanup() {
320
+ if (this.pingTimer) {
321
+ clearInterval(this.pingTimer);
322
+ this.pingTimer = null;
323
+ }
324
+ if (this.reconnectTimer) {
325
+ clearTimeout(this.reconnectTimer);
326
+ this.reconnectTimer = null;
327
+ }
328
+ }
329
+ emitError(error) {
330
+ this.emit("error", error);
331
+ }
332
+ }
333
+ // ============================================================================
334
+ // Utility Functions
335
+ // ============================================================================
336
+ /** Get the name of a frame type */
337
+ export function getFrameTypeName(type) {
338
+ const entry = Object.entries(FrameType).find(([, value]) => value === type);
339
+ return entry ? entry[0] : "UNKNOWN";
340
+ }
341
+ /** Create a client with default options */
342
+ export function createClient(host = "127.0.0.1", port = 9000, options = {}) {
343
+ return new MIPClient({ host, port, ...options });
344
+ }
345
+ export default MIPClient;
346
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,393 @@
1
+ import { describe, it, expect, beforeEach, afterEach, jest, } from "@jest/globals";
2
+ import { EventEmitter } from "events";
3
+ // ============================================================================
4
+ // Mock Socket Class
5
+ // ============================================================================
6
+ let shouldFailConnection = false;
7
+ class MockSocket extends EventEmitter {
8
+ writtenData = [];
9
+ destroyed = false;
10
+ connect(_port, _host, callback) {
11
+ setImmediate(() => {
12
+ if (shouldFailConnection) {
13
+ this.emit("error", new Error("Connection refused"));
14
+ shouldFailConnection = false; // Reset for next test
15
+ }
16
+ else {
17
+ this.emit("connect");
18
+ callback?.();
19
+ }
20
+ });
21
+ return this;
22
+ }
23
+ write(data) {
24
+ this.writtenData.push(Buffer.from(data));
25
+ return true;
26
+ }
27
+ destroy() {
28
+ this.destroyed = true;
29
+ setImmediate(() => this.emit("close"));
30
+ }
31
+ }
32
+ let mockSocketInstance;
33
+ // Mock the net module BEFORE importing MIPClient
34
+ jest.unstable_mockModule("net", () => ({
35
+ Socket: jest.fn(() => {
36
+ mockSocketInstance = new MockSocket();
37
+ return mockSocketInstance;
38
+ }),
39
+ }));
40
+ // Import after mocking
41
+ const { MIPClient, FrameType, Flags, getFrameTypeName, createClient, } = await import("./index.js");
42
+ // ============================================================================
43
+ // Test Helpers
44
+ // ============================================================================
45
+ const MAGIC = 0x4d534950;
46
+ const VERSION = 1;
47
+ function buildMockFrame(frameType, payload = Buffer.alloc(0), flags = 0, msgId = 12345n) {
48
+ const header = Buffer.alloc(24);
49
+ let offset = 0;
50
+ header.writeUInt32BE(MAGIC, offset);
51
+ offset += 4;
52
+ header.writeUInt8(VERSION, offset);
53
+ offset += 1;
54
+ header.writeUInt8(flags, offset);
55
+ offset += 1;
56
+ header.writeUInt16BE(frameType, offset);
57
+ offset += 2;
58
+ header.writeUInt16BE(0x0001, offset);
59
+ offset += 2;
60
+ header.writeUInt16BE(0, offset);
61
+ offset += 2;
62
+ header.writeUInt32BE(payload.length, offset);
63
+ offset += 4;
64
+ header.writeBigUInt64BE(msgId, offset);
65
+ return Buffer.concat([header, payload]);
66
+ }
67
+ function buildMessagePayload(topic, message) {
68
+ const topicBuffer = Buffer.from(topic, "utf-8");
69
+ const messageBuffer = Buffer.from(message, "utf-8");
70
+ const payload = Buffer.alloc(2 + topicBuffer.length + messageBuffer.length);
71
+ payload.writeUInt16BE(topicBuffer.length, 0);
72
+ topicBuffer.copy(payload, 2);
73
+ messageBuffer.copy(payload, 2 + topicBuffer.length);
74
+ return payload;
75
+ }
76
+ // ============================================================================
77
+ // Tests
78
+ // ============================================================================
79
+ describe("MIPClient", () => {
80
+ let client;
81
+ beforeEach(() => {
82
+ shouldFailConnection = false; // Reset flag for each test
83
+ client = new MIPClient({
84
+ host: "127.0.0.1",
85
+ port: 9000,
86
+ autoReconnect: false,
87
+ });
88
+ });
89
+ afterEach(() => {
90
+ shouldFailConnection = false; // Ensure flag is reset
91
+ client.disconnect();
92
+ jest.clearAllMocks();
93
+ });
94
+ describe("Connection", () => {
95
+ it("should connect successfully", async () => {
96
+ await client.connect();
97
+ expect(client.isConnected).toBe(true);
98
+ });
99
+ it("should emit connect event", async () => {
100
+ const connectHandler = jest.fn();
101
+ client.on("connect", connectHandler);
102
+ await client.connect();
103
+ expect(connectHandler).toHaveBeenCalledTimes(1);
104
+ });
105
+ it("should emit disconnect event when closed", async () => {
106
+ const disconnectHandler = jest.fn();
107
+ client.on("disconnect", disconnectHandler);
108
+ await client.connect();
109
+ mockSocketInstance.emit("close");
110
+ expect(disconnectHandler).toHaveBeenCalledTimes(1);
111
+ });
112
+ it("should handle connection errors", async () => {
113
+ // Set flag to make next connection fail
114
+ shouldFailConnection = true;
115
+ const errorClient = new MIPClient({
116
+ host: "127.0.0.1",
117
+ port: 9000,
118
+ autoReconnect: false,
119
+ });
120
+ // Add error handler to prevent unhandled error
121
+ errorClient.on("error", () => { });
122
+ await expect(errorClient.connect()).rejects.toThrow("Connection refused");
123
+ });
124
+ });
125
+ describe("Subscribe", () => {
126
+ it("should send SUBSCRIBE frame", async () => {
127
+ await client.connect();
128
+ mockSocketInstance.writtenData = [];
129
+ client.subscribe("test-topic");
130
+ expect(mockSocketInstance.writtenData.length).toBe(1);
131
+ const frame = mockSocketInstance.writtenData[0];
132
+ const frameType = frame.readUInt16BE(6);
133
+ expect(frameType).toBe(FrameType.SUBSCRIBE);
134
+ });
135
+ it("should include topic in payload", async () => {
136
+ await client.connect();
137
+ mockSocketInstance.writtenData = [];
138
+ client.subscribe("my-topic");
139
+ const frame = mockSocketInstance.writtenData[0];
140
+ const payload = frame.subarray(24).toString("utf-8");
141
+ expect(payload).toBe("my-topic");
142
+ });
143
+ it("should set ACK_REQUIRED flag by default", async () => {
144
+ await client.connect();
145
+ mockSocketInstance.writtenData = [];
146
+ client.subscribe("topic");
147
+ const frame = mockSocketInstance.writtenData[0];
148
+ const flags = frame.readUInt8(5);
149
+ expect(flags & Flags.ACK_REQUIRED).toBeTruthy();
150
+ });
151
+ it("should allow disabling ACK_REQUIRED", async () => {
152
+ await client.connect();
153
+ mockSocketInstance.writtenData = [];
154
+ client.subscribe("topic", false);
155
+ const frame = mockSocketInstance.writtenData[0];
156
+ const flags = frame.readUInt8(5);
157
+ expect(flags & Flags.ACK_REQUIRED).toBeFalsy();
158
+ });
159
+ });
160
+ describe("Unsubscribe", () => {
161
+ it("should send UNSUBSCRIBE frame", async () => {
162
+ await client.connect();
163
+ mockSocketInstance.writtenData = [];
164
+ client.unsubscribe("test-topic");
165
+ const frame = mockSocketInstance.writtenData[0];
166
+ const frameType = frame.readUInt16BE(6);
167
+ expect(frameType).toBe(FrameType.UNSUBSCRIBE);
168
+ });
169
+ });
170
+ describe("Publish", () => {
171
+ it("should send PUBLISH frame", async () => {
172
+ await client.connect();
173
+ mockSocketInstance.writtenData = [];
174
+ client.publish("topic", "message");
175
+ const frame = mockSocketInstance.writtenData[0];
176
+ const frameType = frame.readUInt16BE(6);
177
+ expect(frameType).toBe(FrameType.PUBLISH);
178
+ });
179
+ it("should encode topic and message correctly", async () => {
180
+ await client.connect();
181
+ mockSocketInstance.writtenData = [];
182
+ client.publish("hello", "world");
183
+ const frame = mockSocketInstance.writtenData[0];
184
+ const payload = frame.subarray(24);
185
+ const topicLen = payload.readUInt16BE(0);
186
+ const topic = payload.subarray(2, 2 + topicLen).toString("utf-8");
187
+ const message = payload.subarray(2 + topicLen).toString("utf-8");
188
+ expect(topic).toBe("hello");
189
+ expect(message).toBe("world");
190
+ });
191
+ it("should accept Buffer as message", async () => {
192
+ await client.connect();
193
+ mockSocketInstance.writtenData = [];
194
+ const binaryData = Buffer.from([0x01, 0x02, 0x03]);
195
+ client.publish("topic", binaryData);
196
+ const frame = mockSocketInstance.writtenData[0];
197
+ const payload = frame.subarray(24);
198
+ const topicLen = payload.readUInt16BE(0);
199
+ const messageBytes = payload.subarray(2 + topicLen);
200
+ expect(messageBytes).toEqual(binaryData);
201
+ });
202
+ it("should apply custom flags", async () => {
203
+ await client.connect();
204
+ mockSocketInstance.writtenData = [];
205
+ client.publish("topic", "msg", Flags.URGENT | Flags.COMPRESSED);
206
+ const frame = mockSocketInstance.writtenData[0];
207
+ const flags = frame.readUInt8(5);
208
+ expect(flags & Flags.URGENT).toBeTruthy();
209
+ expect(flags & Flags.COMPRESSED).toBeTruthy();
210
+ });
211
+ });
212
+ describe("Ping", () => {
213
+ it("should send PING frame", async () => {
214
+ await client.connect();
215
+ mockSocketInstance.writtenData = [];
216
+ client.ping();
217
+ const frame = mockSocketInstance.writtenData[0];
218
+ const frameType = frame.readUInt16BE(6);
219
+ expect(frameType).toBe(FrameType.PING);
220
+ });
221
+ it("should have empty payload", async () => {
222
+ await client.connect();
223
+ mockSocketInstance.writtenData = [];
224
+ client.ping();
225
+ const frame = mockSocketInstance.writtenData[0];
226
+ const payloadLen = frame.readUInt32BE(12);
227
+ expect(payloadLen).toBe(0);
228
+ });
229
+ });
230
+ describe("Incoming Frames", () => {
231
+ it("should emit message event on EVENT frame", async () => {
232
+ const messageHandler = jest.fn();
233
+ client.on("message", messageHandler);
234
+ await client.connect();
235
+ const payload = buildMessagePayload("test-topic", "test-message");
236
+ const frame = buildMockFrame(FrameType.EVENT, payload);
237
+ mockSocketInstance.emit("data", frame);
238
+ expect(messageHandler).toHaveBeenCalledTimes(1);
239
+ expect(messageHandler).toHaveBeenCalledWith(expect.objectContaining({
240
+ topic: "test-topic",
241
+ message: "test-message",
242
+ }));
243
+ });
244
+ it("should emit event and message on EVENT frame", async () => {
245
+ const eventHandler = jest.fn();
246
+ const messageHandler = jest.fn();
247
+ client.on("event", eventHandler);
248
+ client.on("message", messageHandler);
249
+ await client.connect();
250
+ const payload = buildMessagePayload("topic", "msg");
251
+ const frame = buildMockFrame(FrameType.EVENT, payload);
252
+ mockSocketInstance.emit("data", frame);
253
+ expect(eventHandler).toHaveBeenCalledTimes(1);
254
+ expect(messageHandler).toHaveBeenCalledTimes(1);
255
+ });
256
+ it("should emit ack event on ACK frame", async () => {
257
+ const ackHandler = jest.fn();
258
+ client.on("ack", ackHandler);
259
+ await client.connect();
260
+ const frame = buildMockFrame(FrameType.ACK, Buffer.alloc(0), 0, 99999n);
261
+ mockSocketInstance.emit("data", frame);
262
+ expect(ackHandler).toHaveBeenCalledWith(99999n);
263
+ });
264
+ it("should emit pong event on PONG frame", async () => {
265
+ const pongHandler = jest.fn();
266
+ client.on("pong", pongHandler);
267
+ await client.connect();
268
+ const frame = buildMockFrame(FrameType.PONG);
269
+ mockSocketInstance.emit("data", frame);
270
+ expect(pongHandler).toHaveBeenCalledTimes(1);
271
+ });
272
+ it("should emit error event on ERROR frame", async () => {
273
+ const errorHandler = jest.fn();
274
+ client.on("error", errorHandler);
275
+ await client.connect();
276
+ const errorPayload = Buffer.from("Something went wrong", "utf-8");
277
+ const frame = buildMockFrame(FrameType.ERROR, errorPayload);
278
+ mockSocketInstance.emit("data", frame);
279
+ expect(errorHandler).toHaveBeenCalledWith(expect.objectContaining({
280
+ message: "Something went wrong",
281
+ }));
282
+ });
283
+ it("should handle fragmented data", async () => {
284
+ const messageHandler = jest.fn();
285
+ client.on("message", messageHandler);
286
+ await client.connect();
287
+ const payload = buildMessagePayload("topic", "message");
288
+ const frame = buildMockFrame(FrameType.EVENT, payload);
289
+ // Send in two parts
290
+ mockSocketInstance.emit("data", frame.subarray(0, 10));
291
+ mockSocketInstance.emit("data", frame.subarray(10));
292
+ expect(messageHandler).toHaveBeenCalledTimes(1);
293
+ });
294
+ it("should handle multiple frames in one data event", async () => {
295
+ const ackHandler = jest.fn();
296
+ client.on("ack", ackHandler);
297
+ await client.connect();
298
+ const frame1 = buildMockFrame(FrameType.ACK, Buffer.alloc(0), 0, 1n);
299
+ const frame2 = buildMockFrame(FrameType.ACK, Buffer.alloc(0), 0, 2n);
300
+ mockSocketInstance.emit("data", Buffer.concat([frame1, frame2]));
301
+ expect(ackHandler).toHaveBeenCalledTimes(2);
302
+ expect(ackHandler).toHaveBeenNthCalledWith(1, 1n);
303
+ expect(ackHandler).toHaveBeenNthCalledWith(2, 2n);
304
+ });
305
+ it("should reject invalid magic number", async () => {
306
+ const errorHandler = jest.fn();
307
+ client.on("error", errorHandler);
308
+ await client.connect();
309
+ const invalidFrame = Buffer.alloc(24);
310
+ invalidFrame.writeUInt32BE(0xdeadbeef, 0);
311
+ mockSocketInstance.emit("data", invalidFrame);
312
+ expect(errorHandler).toHaveBeenCalledWith(expect.objectContaining({
313
+ message: "Invalid magic number",
314
+ }));
315
+ expect(mockSocketInstance.destroyed).toBe(true);
316
+ });
317
+ });
318
+ describe("Reconnection", () => {
319
+ it("should emit reconnecting event", async () => {
320
+ const reconnectClient = new MIPClient({
321
+ host: "127.0.0.1",
322
+ port: 9000,
323
+ autoReconnect: true,
324
+ reconnectDelay: 50,
325
+ maxReconnectAttempts: 2,
326
+ });
327
+ const reconnectingHandler = jest.fn();
328
+ reconnectClient.on("reconnecting", reconnectingHandler);
329
+ await reconnectClient.connect();
330
+ mockSocketInstance.emit("close");
331
+ // Wait for reconnect attempt
332
+ await new Promise((r) => setTimeout(r, 100));
333
+ expect(reconnectingHandler).toHaveBeenCalledWith(1);
334
+ // Clean up
335
+ reconnectClient.disconnect();
336
+ });
337
+ });
338
+ describe("Error handling", () => {
339
+ it("should throw when publishing without connection", () => {
340
+ expect(() => client.publish("topic", "msg")).toThrow("Client is not connected");
341
+ });
342
+ it("should throw when subscribing without connection", () => {
343
+ expect(() => client.subscribe("topic")).toThrow("Client is not connected");
344
+ });
345
+ it("should throw when pinging without connection", () => {
346
+ expect(() => client.ping()).toThrow("Client is not connected");
347
+ });
348
+ });
349
+ });
350
+ describe("Utility Functions", () => {
351
+ describe("getFrameTypeName", () => {
352
+ it("should return frame type name", () => {
353
+ expect(getFrameTypeName(FrameType.HELLO)).toBe("HELLO");
354
+ expect(getFrameTypeName(FrameType.SUBSCRIBE)).toBe("SUBSCRIBE");
355
+ expect(getFrameTypeName(FrameType.PUBLISH)).toBe("PUBLISH");
356
+ expect(getFrameTypeName(FrameType.ACK)).toBe("ACK");
357
+ });
358
+ it("should return UNKNOWN for invalid type", () => {
359
+ expect(getFrameTypeName(0xffff)).toBe("UNKNOWN");
360
+ });
361
+ });
362
+ describe("createClient", () => {
363
+ it("should create client with defaults", () => {
364
+ const c = createClient();
365
+ expect(c).toBeInstanceOf(MIPClient);
366
+ });
367
+ it("should accept custom options", () => {
368
+ const c = createClient("192.168.1.1", 8080, { autoReconnect: false });
369
+ expect(c).toBeInstanceOf(MIPClient);
370
+ });
371
+ });
372
+ });
373
+ describe("Constants", () => {
374
+ it("should export FrameType constants", () => {
375
+ expect(FrameType.HELLO).toBe(0x0001);
376
+ expect(FrameType.SUBSCRIBE).toBe(0x0002);
377
+ expect(FrameType.UNSUBSCRIBE).toBe(0x0003);
378
+ expect(FrameType.PUBLISH).toBe(0x0004);
379
+ expect(FrameType.EVENT).toBe(0x0005);
380
+ expect(FrameType.ACK).toBe(0x0006);
381
+ expect(FrameType.ERROR).toBe(0x0007);
382
+ expect(FrameType.PING).toBe(0x0008);
383
+ expect(FrameType.PONG).toBe(0x0009);
384
+ expect(FrameType.CLOSE).toBe(0x000a);
385
+ });
386
+ it("should export Flags constants", () => {
387
+ expect(Flags.NONE).toBe(0b0000_0000);
388
+ expect(Flags.ACK_REQUIRED).toBe(0b0000_0001);
389
+ expect(Flags.COMPRESSED).toBe(0b0000_0010);
390
+ expect(Flags.URGENT).toBe(0b0000_0100);
391
+ });
392
+ });
393
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../index.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@mip-client/ts",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript client for the MIP (MSIP) protocol - handles connections, events, errors, and auto-reconnection",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "type": "module",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsc",
25
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
26
+ "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
27
+ "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
28
+ "lint": "eslint . --ext .ts",
29
+ "format": "prettier --write ."
30
+ },
31
+ "keywords": [
32
+ "mip",
33
+ "msip",
34
+ "protocol",
35
+ "client",
36
+ "tcp",
37
+ "pubsub",
38
+ "events"
39
+ ],
40
+ "author": "",
41
+ "license": "ISC",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/DoctorPok42/MIP-Clients/tree/main/mip-client-ts"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/jest": "^30.0.0",
51
+ "@types/node": "^25.3.3",
52
+ "eslint": "^10.0.2",
53
+ "jest": "^30.2.0",
54
+ "prettier": "^3.8.1",
55
+ "ts-jest": "^29.4.6",
56
+ "ts-node": "^10.9.2",
57
+ "typescript": "^5.9.3"
58
+ }
59
+ }