websocket-mqtt 0.0.7 → 0.0.9
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/dist/base.d.ts +6 -5
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +75 -38
- package/dist/connection.d.ts +10 -1
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +160 -48
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/packets/decode.d.ts +2 -2
- package/dist/packets/decode.d.ts.map +1 -1
- package/dist/packets/decode.js +32 -20
- package/dist/packets/encode.d.ts +8 -7
- package/dist/packets/encode.d.ts.map +1 -1
- package/dist/packets/encode.js +67 -63
- package/dist/packets/types.d.ts +12 -3
- package/dist/packets/types.d.ts.map +1 -1
- package/dist/utils/buffer.d.ts +3 -3
- package/dist/utils/buffer.d.ts.map +1 -1
- package/dist/utils/buffer.js +10 -12
- package/dist/utils/events.js +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/package.json +5 -15
package/dist/base.d.ts
CHANGED
|
@@ -3,13 +3,12 @@ import { type ConnackPacket, type PublishPacket, type QoSLevel } from "./packets
|
|
|
3
3
|
import { type EventEmitter } from "./utils/events.js";
|
|
4
4
|
export type MqttEvents = {
|
|
5
5
|
connect: [packet: ConnackPacket];
|
|
6
|
+
offline: [];
|
|
7
|
+
reconnect: [attempt: number, delayMs: number];
|
|
8
|
+
close: [];
|
|
6
9
|
message: [topic: string, payload: Uint8Array, packet: PublishPacket];
|
|
7
10
|
error: [error: unknown];
|
|
8
|
-
close: [];
|
|
9
11
|
};
|
|
10
|
-
export type MqttOptions = {
|
|
11
|
-
url: string;
|
|
12
|
-
} & ConnectionOptions;
|
|
13
12
|
export type MqttClient = EventEmitter<MqttEvents> & {
|
|
14
13
|
connection: Connection;
|
|
15
14
|
isConnected: () => boolean;
|
|
@@ -18,6 +17,7 @@ export type MqttClient = EventEmitter<MqttEvents> & {
|
|
|
18
17
|
retain?: boolean;
|
|
19
18
|
}) => Promise<void>;
|
|
20
19
|
subscribe: (topic: string, qos?: QoSLevel) => Promise<number[]>;
|
|
20
|
+
unsubscribe: (topic: string | string[]) => Promise<void>;
|
|
21
21
|
connect: () => Promise<void>;
|
|
22
22
|
close: () => void;
|
|
23
23
|
};
|
|
@@ -27,7 +27,8 @@ export type MqttClientInternalRequest<K> = {
|
|
|
27
27
|
};
|
|
28
28
|
export type MqttClientInternalPending = {
|
|
29
29
|
sub: Map<number, MqttClientInternalRequest<number[]>>;
|
|
30
|
+
unsub: Map<number, MqttClientInternalRequest<void>>;
|
|
30
31
|
pub: Map<number, MqttClientInternalRequest<void>>;
|
|
31
32
|
};
|
|
32
|
-
export declare const createMqtt: (options:
|
|
33
|
+
export declare const createMqtt: (options: ConnectionOptions) => MqttClient;
|
|
33
34
|
//# sourceMappingURL=base.d.ts.map
|
package/dist/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1E,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjC,OAAO,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1E,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjC,OAAO,EAAE,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IACrE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG;IAClD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,OAAO,EAAE,CACP,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;KAAE,KAC5C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChE,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI;IACzC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;CACnD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,iBAAiB,KAAG,UAsLvD,CAAC"}
|
package/dist/base.js
CHANGED
|
@@ -6,17 +6,28 @@ import { createLogger } from "./utils/logger.js";
|
|
|
6
6
|
export const createMqtt = (options) => {
|
|
7
7
|
const pending = {
|
|
8
8
|
sub: new Map(),
|
|
9
|
+
unsub: new Map(),
|
|
9
10
|
pub: new Map(),
|
|
10
11
|
};
|
|
11
12
|
const events = createEventEmitter();
|
|
12
13
|
const log = createLogger(options);
|
|
13
14
|
const connection = createConnection(options);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
const rejectAllPending = () => {
|
|
16
|
+
for (const request of pending.sub.values()) {
|
|
17
|
+
request.reject(new Error("Connection closed"));
|
|
18
|
+
}
|
|
19
|
+
pending.sub.clear();
|
|
20
|
+
for (const request of pending.unsub.values()) {
|
|
21
|
+
request.reject(new Error("Connection closed"));
|
|
22
|
+
}
|
|
23
|
+
pending.unsub.clear();
|
|
24
|
+
for (const request of pending.pub.values()) {
|
|
25
|
+
request.reject(new Error("Connection closed"));
|
|
26
|
+
}
|
|
27
|
+
pending.pub.clear();
|
|
28
|
+
};
|
|
29
|
+
connection.on("connect", packet => events.emit("connect", packet));
|
|
30
|
+
connection.on("message", (topic, payload, packet) => events.emit("message", topic, payload, packet));
|
|
20
31
|
connection.on("packet", (packet) => {
|
|
21
32
|
switch (packet.type) {
|
|
22
33
|
case PacketType.SUBACK: {
|
|
@@ -24,7 +35,7 @@ export const createMqtt = (options) => {
|
|
|
24
35
|
const request = pending.sub.get(packet.messageId);
|
|
25
36
|
if (request) {
|
|
26
37
|
pending.sub.delete(packet.messageId);
|
|
27
|
-
const hasFailure = packet.granted.
|
|
38
|
+
const hasFailure = packet.granted.includes(0x80);
|
|
28
39
|
if (hasFailure) {
|
|
29
40
|
request.reject(new Error("Subscription failed"));
|
|
30
41
|
}
|
|
@@ -34,6 +45,15 @@ export const createMqtt = (options) => {
|
|
|
34
45
|
}
|
|
35
46
|
break;
|
|
36
47
|
}
|
|
48
|
+
case PacketType.UNSUBACK: {
|
|
49
|
+
log("UNSUBACK", packet);
|
|
50
|
+
const request = pending.unsub.get(packet.messageId);
|
|
51
|
+
if (request) {
|
|
52
|
+
pending.unsub.delete(packet.messageId);
|
|
53
|
+
request.resolve();
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
37
57
|
case PacketType.PUBACK: {
|
|
38
58
|
log("PUBACK", packet);
|
|
39
59
|
const request = pending.pub.get(packet.messageId);
|
|
@@ -45,21 +65,19 @@ export const createMqtt = (options) => {
|
|
|
45
65
|
}
|
|
46
66
|
}
|
|
47
67
|
});
|
|
48
|
-
connection.on("error",
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
connection.on("error", err => events.emit("error", err));
|
|
69
|
+
connection.on("reconnect", (attempt, delayMs) => events.emit("reconnect", attempt, delayMs));
|
|
70
|
+
connection.on("offline", () => {
|
|
71
|
+
rejectAllPending();
|
|
72
|
+
events.emit("offline");
|
|
51
73
|
});
|
|
52
74
|
connection.on("close", () => {
|
|
53
|
-
|
|
54
|
-
request.reject(new Error("Connection closed"));
|
|
55
|
-
}
|
|
56
|
-
pending.sub.clear();
|
|
57
|
-
for (const request of pending.pub.values()) {
|
|
58
|
-
request.reject(new Error("Connection closed"));
|
|
59
|
-
}
|
|
60
|
-
pending.pub.clear();
|
|
75
|
+
rejectAllPending();
|
|
61
76
|
events.emit("close");
|
|
62
77
|
});
|
|
78
|
+
connection.on("reconnect", (attempt, delayMs) => {
|
|
79
|
+
events.emit("reconnect", attempt, delayMs);
|
|
80
|
+
});
|
|
63
81
|
const publish = (topic, payload, options) => {
|
|
64
82
|
const qos = options?.qos ?? QoS.AT_MOST_ONCE;
|
|
65
83
|
const retain = options?.retain ?? false;
|
|
@@ -81,34 +99,53 @@ export const createMqtt = (options) => {
|
|
|
81
99
|
pending.pub.set(messageId, { resolve, reject });
|
|
82
100
|
});
|
|
83
101
|
};
|
|
84
|
-
const subscribe = (topic, qos = QoS.AT_MOST_ONCE) => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
subscriptions: [{ topic, qos }],
|
|
92
|
-
});
|
|
102
|
+
const subscribe = (topic, qos = QoS.AT_MOST_ONCE) => new Promise((resolve, reject) => {
|
|
103
|
+
const messageId = connection.nextMessageId();
|
|
104
|
+
pending.sub.set(messageId, { resolve, reject });
|
|
105
|
+
connection.send({
|
|
106
|
+
type: PacketType.SUBSCRIBE,
|
|
107
|
+
messageId,
|
|
108
|
+
subscriptions: [{ topic, qos }],
|
|
93
109
|
});
|
|
94
|
-
};
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
});
|
|
111
|
+
const unsubscribe = (topic) => new Promise((resolve, reject) => {
|
|
112
|
+
const topics = Array.isArray(topic) ? topic : [topic];
|
|
113
|
+
const messageId = connection.nextMessageId();
|
|
114
|
+
pending.unsub.set(messageId, { resolve, reject });
|
|
115
|
+
connection.send({
|
|
116
|
+
type: PacketType.UNSUBSCRIBE,
|
|
117
|
+
messageId,
|
|
118
|
+
topics,
|
|
100
119
|
});
|
|
101
|
-
};
|
|
120
|
+
});
|
|
121
|
+
const connect = () => new Promise((resolve, reject) => {
|
|
122
|
+
// Resolves on the first successful connect (including after retries).
|
|
123
|
+
// Rejects only when the connection is permanently closed (retries exhausted
|
|
124
|
+
// or intentional close).
|
|
125
|
+
const onConnect = () => {
|
|
126
|
+
cleanup();
|
|
127
|
+
resolve();
|
|
128
|
+
};
|
|
129
|
+
const onClose = () => {
|
|
130
|
+
cleanup();
|
|
131
|
+
reject(new Error("Connection closed"));
|
|
132
|
+
};
|
|
133
|
+
const cleanup = () => {
|
|
134
|
+
connection.off("connect", onConnect);
|
|
135
|
+
connection.off("close", onClose);
|
|
136
|
+
};
|
|
137
|
+
connection.on("connect", onConnect);
|
|
138
|
+
connection.on("close", onClose);
|
|
139
|
+
connection.open();
|
|
140
|
+
});
|
|
102
141
|
return {
|
|
103
142
|
...events,
|
|
104
143
|
publish,
|
|
105
144
|
subscribe,
|
|
145
|
+
unsubscribe,
|
|
106
146
|
connection,
|
|
107
147
|
isConnected: () => connection.isConnected(),
|
|
108
148
|
connect,
|
|
109
|
-
close: () =>
|
|
110
|
-
log("closing from up above");
|
|
111
|
-
connection.close();
|
|
112
|
-
},
|
|
149
|
+
close: () => connection.close(),
|
|
113
150
|
};
|
|
114
151
|
};
|
package/dist/connection.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { ConnackPacket, IncomingPacket, OutgoingPacket, PublishPacket, QoSLevel } from "./packets/index.js";
|
|
2
2
|
import { type LogOptions } from "./utils/logger.js";
|
|
3
|
+
export type RetryOptions = {
|
|
4
|
+
retries?: number;
|
|
5
|
+
initialDelayMs?: number;
|
|
6
|
+
maxDelayMs?: number;
|
|
7
|
+
jitter?: boolean;
|
|
8
|
+
};
|
|
3
9
|
export type ConnectionOptions = {
|
|
4
10
|
url: string;
|
|
5
11
|
clientId?: string;
|
|
@@ -14,6 +20,7 @@ export type ConnectionOptions = {
|
|
|
14
20
|
retain?: boolean;
|
|
15
21
|
};
|
|
16
22
|
signal?: AbortSignal;
|
|
23
|
+
retry?: RetryOptions;
|
|
17
24
|
} & LogOptions;
|
|
18
25
|
export type HandlePacketFunction = (packet: IncomingPacket) => void;
|
|
19
26
|
export type Connection = {
|
|
@@ -25,10 +32,12 @@ export type Connection = {
|
|
|
25
32
|
};
|
|
26
33
|
export type ConnectionEvents = {
|
|
27
34
|
connect: [packet: ConnackPacket];
|
|
35
|
+
offline: [];
|
|
36
|
+
reconnect: [attempt: number, delayMs: number];
|
|
37
|
+
close: [];
|
|
28
38
|
message: [topic: string, payload: Uint8Array, packet: PublishPacket];
|
|
29
39
|
packet: [packet: IncomingPacket];
|
|
30
40
|
error: [error: unknown];
|
|
31
|
-
close: [];
|
|
32
41
|
};
|
|
33
42
|
export declare const DEFAULT_CLIENT_ID = "websocket_mqtt_";
|
|
34
43
|
export declare const createConnection: (options: ConnectionOptions) => {
|
package/dist/connection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,aAAa,EAGb,cAAc,EACd,cAAc,EAEd,aAAa,EAEb,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,aAAa,EAGb,cAAc,EACd,cAAc,EAEd,aAAa,EAEb,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIlE,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;QAC7B,GAAG,CAAC,EAAE,QAAQ,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB,GAAG,UAAU,CAAC;AAEf,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;AAEpE,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjC,OAAO,EAAE,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IACrE,MAAM,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACjC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB;;;;;;mBAqEnC,cAAc,KAAG,IAAI;yBAVjB,MAAM;;CAwQjC,CAAC"}
|
package/dist/connection.js
CHANGED
|
@@ -3,15 +3,43 @@ import { decodeAll, DEFAULT_KEEPALIVE_SECONDS, PacketType, QoS, } from "./packet
|
|
|
3
3
|
import { toUint8Array } from "./utils/buffer.js";
|
|
4
4
|
import { createEventEmitter } from "./utils/events.js";
|
|
5
5
|
import { createLogger } from "./utils/logger.js";
|
|
6
|
+
const FORCE_CLOSE_TIMEOUT_MS = 2000;
|
|
6
7
|
export const DEFAULT_CLIENT_ID = "websocket_mqtt_";
|
|
7
8
|
export const createConnection = (options) => {
|
|
8
9
|
const events = createEventEmitter();
|
|
9
10
|
const log = createLogger(options);
|
|
10
11
|
let lastMessageId = 1;
|
|
11
12
|
let connected = false;
|
|
12
|
-
let
|
|
13
|
-
let
|
|
14
|
-
const
|
|
13
|
+
let ws;
|
|
14
|
+
let activeAc;
|
|
15
|
+
const timers = {
|
|
16
|
+
pingInterval: undefined,
|
|
17
|
+
pingTimeout: undefined,
|
|
18
|
+
retry: undefined,
|
|
19
|
+
forceClose: undefined,
|
|
20
|
+
clearAll() {
|
|
21
|
+
if (this.pingInterval)
|
|
22
|
+
clearInterval(this.pingInterval);
|
|
23
|
+
if (this.pingTimeout)
|
|
24
|
+
clearTimeout(this.pingTimeout);
|
|
25
|
+
if (this.retry)
|
|
26
|
+
clearTimeout(this.retry);
|
|
27
|
+
if (this.forceClose)
|
|
28
|
+
clearTimeout(this.forceClose);
|
|
29
|
+
this.pingInterval = undefined;
|
|
30
|
+
this.pingTimeout = undefined;
|
|
31
|
+
this.retry = undefined;
|
|
32
|
+
this.forceClose = undefined;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
const { clientId = DEFAULT_CLIENT_ID + Math.random().toString(36)
|
|
36
|
+
.slice(2, 15), username, password, keepalive = DEFAULT_KEEPALIVE_SECONDS, clean = true, url, signal, retry, } = options;
|
|
37
|
+
const maxRetries = Math.max(0, retry?.retries ?? 0);
|
|
38
|
+
const initialDelayMs = retry?.initialDelayMs ?? 1000;
|
|
39
|
+
const maxDelayMs = retry?.maxDelayMs ?? 30000;
|
|
40
|
+
const jitter = retry?.jitter ?? true;
|
|
41
|
+
let intentionalClose = false;
|
|
42
|
+
let retryAttempt = 0;
|
|
15
43
|
const will = options.will
|
|
16
44
|
? {
|
|
17
45
|
topic: options.will.topic,
|
|
@@ -25,15 +53,7 @@ export const createConnection = (options) => {
|
|
|
25
53
|
lastMessageId = (messageId % 65535) + 1;
|
|
26
54
|
return lastMessageId;
|
|
27
55
|
};
|
|
28
|
-
|
|
29
|
-
log("starting ping interval");
|
|
30
|
-
if (keepalive > 0) {
|
|
31
|
-
const pingIntervalMs = (keepalive * 1000) / 2;
|
|
32
|
-
pingInterval = setInterval(() => {
|
|
33
|
-
sendRaw(encodePingreq());
|
|
34
|
-
}, pingIntervalMs);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
56
|
+
let receiveBuffer = new Uint8Array(0);
|
|
37
57
|
const send = (packet) => {
|
|
38
58
|
log("sending packet", packet);
|
|
39
59
|
sendRaw(encodePacket(packet));
|
|
@@ -47,69 +67,160 @@ export const createConnection = (options) => {
|
|
|
47
67
|
log("not sending raw data", data);
|
|
48
68
|
}
|
|
49
69
|
};
|
|
70
|
+
const scheduleRetry = () => {
|
|
71
|
+
if (maxRetries === 0 || (maxRetries !== Infinity && retryAttempt >= maxRetries)) {
|
|
72
|
+
events.emit("close");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
retryAttempt++;
|
|
76
|
+
const exponentialDelay = Math.min(initialDelayMs * 2 ** (retryAttempt - 1), maxDelayMs);
|
|
77
|
+
const delay = jitter
|
|
78
|
+
? exponentialDelay * (0.5 + Math.random() * 0.5)
|
|
79
|
+
: exponentialDelay;
|
|
80
|
+
log(`scheduling retry #${retryAttempt} in ${Math.round(delay)}ms`);
|
|
81
|
+
events.emit("reconnect", retryAttempt, Math.round(delay));
|
|
82
|
+
timers.retry = setTimeout(() => {
|
|
83
|
+
timers.retry = undefined;
|
|
84
|
+
open();
|
|
85
|
+
}, delay);
|
|
86
|
+
};
|
|
50
87
|
const close = () => {
|
|
51
88
|
log("closing connection");
|
|
89
|
+
intentionalClose = true;
|
|
90
|
+
timers.clearAll();
|
|
91
|
+
// Detach all WebSocket listeners before closing to prevent handleDisconnect
|
|
92
|
+
if (activeAc) {
|
|
93
|
+
activeAc.abort();
|
|
94
|
+
activeAc = undefined;
|
|
95
|
+
}
|
|
52
96
|
if (connected && ws) {
|
|
53
97
|
sendRaw(encodeDisconnect());
|
|
54
98
|
}
|
|
55
99
|
ws?.close();
|
|
100
|
+
ws = undefined;
|
|
56
101
|
connected = false;
|
|
57
|
-
|
|
58
|
-
clearInterval(pingInterval);
|
|
59
|
-
pingInterval = null;
|
|
60
|
-
}
|
|
102
|
+
events.emit("close");
|
|
61
103
|
};
|
|
62
104
|
const open = () => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
105
|
+
intentionalClose = false;
|
|
106
|
+
receiveBuffer = new Uint8Array(0);
|
|
107
|
+
// Abort previous WebSocket listeners and close socket if open() is called again
|
|
108
|
+
if (activeAc) {
|
|
109
|
+
activeAc.abort();
|
|
110
|
+
}
|
|
111
|
+
ws?.close();
|
|
112
|
+
const ac = new AbortController();
|
|
113
|
+
activeAc = ac;
|
|
114
|
+
const { signal: wsSignal } = ac;
|
|
115
|
+
let disconnected = false;
|
|
116
|
+
const handleDisconnect = () => {
|
|
117
|
+
if (disconnected)
|
|
118
|
+
return;
|
|
119
|
+
disconnected = true;
|
|
120
|
+
ac.abort();
|
|
121
|
+
activeAc = undefined;
|
|
122
|
+
log("ws:disconnect");
|
|
123
|
+
connected = false;
|
|
124
|
+
timers.clearAll();
|
|
125
|
+
if (!intentionalClose) {
|
|
126
|
+
events.emit("offline");
|
|
127
|
+
scheduleRetry();
|
|
128
|
+
}
|
|
77
129
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
130
|
+
const handleConnectionLost = () => {
|
|
131
|
+
connected = false;
|
|
132
|
+
timers.clearAll();
|
|
133
|
+
ws?.close();
|
|
134
|
+
timers.forceClose = setTimeout(() => {
|
|
135
|
+
log("force closing stale connection");
|
|
136
|
+
timers.forceClose = undefined;
|
|
137
|
+
ws = undefined;
|
|
138
|
+
handleDisconnect();
|
|
139
|
+
}, FORCE_CLOSE_TIMEOUT_MS);
|
|
140
|
+
};
|
|
141
|
+
const startPingInterval = () => {
|
|
142
|
+
if (keepalive <= 0)
|
|
143
|
+
return;
|
|
144
|
+
log("starting ping interval");
|
|
145
|
+
const pingIntervalMs = (keepalive * 1000) / 2;
|
|
146
|
+
const pingTimeoutMs = keepalive * 1000;
|
|
147
|
+
timers.pingInterval = setInterval(() => {
|
|
148
|
+
sendRaw(encodePingreq());
|
|
149
|
+
if (!timers.pingTimeout) {
|
|
150
|
+
timers.pingTimeout = setTimeout(() => {
|
|
151
|
+
log("ping timeout, connection lost");
|
|
152
|
+
handleConnectionLost();
|
|
153
|
+
}, pingTimeoutMs);
|
|
154
|
+
}
|
|
155
|
+
}, pingIntervalMs);
|
|
156
|
+
};
|
|
157
|
+
const handlePacket = (packet) => {
|
|
158
|
+
log("handlePacket", packet);
|
|
159
|
+
// Any incoming packet proves the connection is alive, so reset the
|
|
160
|
+
// ping timeout (not just PINGRESP — the spec only requires PINGRESP,
|
|
161
|
+
// but any data is a valid liveness signal).
|
|
162
|
+
if (timers.pingTimeout) {
|
|
163
|
+
clearTimeout(timers.pingTimeout);
|
|
164
|
+
timers.pingTimeout = undefined;
|
|
165
|
+
}
|
|
81
166
|
switch (packet.type) {
|
|
82
|
-
case PacketType.CONNACK:
|
|
167
|
+
case PacketType.CONNACK: {
|
|
83
168
|
if (packet.returnCode === 0) {
|
|
84
169
|
connected = true;
|
|
170
|
+
retryAttempt = 0;
|
|
85
171
|
startPingInterval();
|
|
86
172
|
events.emit("connect", packet);
|
|
87
173
|
log("connected");
|
|
88
174
|
}
|
|
89
175
|
else {
|
|
90
176
|
const message = getConnackErrorMessage(packet.returnCode);
|
|
91
|
-
console.error(message);
|
|
92
177
|
events.emit("error", new Error(message));
|
|
93
178
|
close();
|
|
94
179
|
}
|
|
95
180
|
break;
|
|
96
|
-
|
|
181
|
+
}
|
|
182
|
+
case PacketType.PUBLISH: {
|
|
97
183
|
log("received a publish packet");
|
|
98
184
|
if (packet.qos === 1 && packet.messageId !== undefined) {
|
|
99
185
|
send({ type: PacketType.PUBACK, messageId: packet.messageId });
|
|
100
186
|
}
|
|
101
187
|
events.emit("message", packet.topic, packet.payload, packet);
|
|
102
188
|
break;
|
|
103
|
-
|
|
189
|
+
}
|
|
190
|
+
case PacketType.PINGRESP: {
|
|
104
191
|
log("PINGRESP");
|
|
105
192
|
break;
|
|
106
|
-
|
|
193
|
+
}
|
|
194
|
+
default: {
|
|
107
195
|
log("received a default packet");
|
|
108
196
|
events.emit("packet", packet);
|
|
109
197
|
break;
|
|
198
|
+
}
|
|
110
199
|
}
|
|
111
200
|
};
|
|
112
|
-
|
|
201
|
+
try {
|
|
202
|
+
ws = new WebSocket(url, ["mqtt"]);
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
log("WebSocket constructor threw", error);
|
|
206
|
+
events.emit("error", error);
|
|
207
|
+
scheduleRetry();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
ws.binaryType = "arraybuffer";
|
|
211
|
+
ws.addEventListener("open", () => {
|
|
212
|
+
const packet = encodeConnect({
|
|
213
|
+
type: PacketType.CONNECT,
|
|
214
|
+
clientId,
|
|
215
|
+
username,
|
|
216
|
+
password,
|
|
217
|
+
keepalive,
|
|
218
|
+
clean,
|
|
219
|
+
will,
|
|
220
|
+
});
|
|
221
|
+
sendRaw(packet);
|
|
222
|
+
}, { signal: wsSignal });
|
|
223
|
+
ws.addEventListener("message", (event) => {
|
|
113
224
|
log("onmessage");
|
|
114
225
|
const data = new Uint8Array(event.data);
|
|
115
226
|
const combined = new Uint8Array(receiveBuffer.length + data.length);
|
|
@@ -120,17 +231,18 @@ export const createConnection = (options) => {
|
|
|
120
231
|
receiveBuffer = remaining;
|
|
121
232
|
log("packets to process", packets.length);
|
|
122
233
|
for (const packet of packets) {
|
|
123
|
-
|
|
124
|
-
handlePacket2(packet);
|
|
234
|
+
handlePacket(packet);
|
|
125
235
|
}
|
|
126
|
-
};
|
|
127
|
-
ws.
|
|
236
|
+
}, { signal: wsSignal });
|
|
237
|
+
ws.addEventListener("error", (event) => {
|
|
128
238
|
events.emit("error", event);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
239
|
+
// If we were never connected, the close event may not fire (e.g. Node.js
|
|
240
|
+
// WebSocket on a failed connection attempt), so treat it as a disconnect.
|
|
241
|
+
if (!connected) {
|
|
242
|
+
handleDisconnect();
|
|
243
|
+
}
|
|
244
|
+
}, { signal: wsSignal });
|
|
245
|
+
ws.addEventListener("close", handleDisconnect, { signal: wsSignal });
|
|
134
246
|
};
|
|
135
247
|
signal?.addEventListener("abort", () => {
|
|
136
248
|
log("abort signal received");
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/packets/decode.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ export interface DecodeResult {
|
|
|
3
3
|
packet: IncomingPacket;
|
|
4
4
|
bytesConsumed: number;
|
|
5
5
|
}
|
|
6
|
-
export declare
|
|
7
|
-
export declare
|
|
6
|
+
export declare const decode: (bytes: Uint8Array) => DecodeResult | null;
|
|
7
|
+
export declare const decodeAll: (bytes: Uint8Array) => {
|
|
8
8
|
packets: IncomingPacket[];
|
|
9
9
|
remaining: Uint8Array;
|
|
10
10
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/packets/decode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,
|
|
1
|
+
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/packets/decode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EAMf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,MAAM,GAAI,OAAO,UAAU,KAAG,YAAY,GAAG,IAqDzD,CAAC;AA6CF,eAAO,MAAM,SAAS,GAAI,OAAO,UAAU,KAAG;IAC5C,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,UAAU,CAAC;CAevB,CAAC"}
|
package/dist/packets/decode.js
CHANGED
|
@@ -1,58 +1,71 @@
|
|
|
1
1
|
import { createPacketReader } from "../utils/buffer.js";
|
|
2
2
|
import { PacketType } from "./constants.js";
|
|
3
|
-
export
|
|
3
|
+
export const decode = (bytes) => {
|
|
4
|
+
// Preserve public API semantics: incomplete packets decode to null.
|
|
5
|
+
// eslint-disable-next-line unicorn/no-null
|
|
4
6
|
if (bytes.length < 2)
|
|
5
7
|
return null;
|
|
6
8
|
const reader = createPacketReader(bytes);
|
|
7
9
|
const firstByte = reader.readByte();
|
|
8
10
|
const packetType = firstByte >> 4;
|
|
9
|
-
const flags = firstByte &
|
|
11
|
+
const flags = firstByte & 0x0F;
|
|
10
12
|
const remainingLength = reader.readVariableInt();
|
|
11
13
|
const headerLength = reader.position;
|
|
12
14
|
const totalLength = headerLength + remainingLength;
|
|
15
|
+
// eslint-disable-next-line unicorn/no-null
|
|
13
16
|
if (bytes.length < totalLength)
|
|
14
17
|
return null;
|
|
15
18
|
const payload = reader.readBytes(remainingLength);
|
|
16
19
|
const payloadReader = createPacketReader(payload);
|
|
17
20
|
let packet;
|
|
18
21
|
switch (packetType) {
|
|
19
|
-
case PacketType.CONNACK:
|
|
22
|
+
case PacketType.CONNACK: {
|
|
20
23
|
packet = decodeConnack(payloadReader);
|
|
21
24
|
break;
|
|
22
|
-
|
|
25
|
+
}
|
|
26
|
+
case PacketType.SUBACK: {
|
|
23
27
|
packet = decodeSuback(payloadReader);
|
|
24
28
|
break;
|
|
25
|
-
|
|
29
|
+
}
|
|
30
|
+
case PacketType.PUBLISH: {
|
|
26
31
|
packet = decodePublish(payloadReader, flags);
|
|
27
32
|
break;
|
|
28
|
-
|
|
33
|
+
}
|
|
34
|
+
case PacketType.PUBACK: {
|
|
29
35
|
packet = decodePuback(payloadReader);
|
|
30
36
|
break;
|
|
31
|
-
|
|
37
|
+
}
|
|
38
|
+
case PacketType.UNSUBACK: {
|
|
39
|
+
packet = decodeUnsuback(payloadReader);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case PacketType.PINGRESP: {
|
|
32
43
|
packet = { type: PacketType.PINGRESP };
|
|
33
44
|
break;
|
|
34
|
-
|
|
45
|
+
}
|
|
46
|
+
default: {
|
|
35
47
|
throw new Error(`Unknown MQTT packet type: ${packetType}`);
|
|
48
|
+
}
|
|
36
49
|
}
|
|
37
50
|
return { packet, bytesConsumed: totalLength };
|
|
38
|
-
}
|
|
39
|
-
|
|
51
|
+
};
|
|
52
|
+
const decodeConnack = (reader) => {
|
|
40
53
|
const flags = reader.readByte();
|
|
41
54
|
return {
|
|
42
55
|
type: PacketType.CONNACK,
|
|
43
56
|
sessionPresent: (flags & 0x01) === 1,
|
|
44
57
|
returnCode: reader.readByte(),
|
|
45
58
|
};
|
|
46
|
-
}
|
|
47
|
-
|
|
59
|
+
};
|
|
60
|
+
const decodeSuback = (reader) => {
|
|
48
61
|
const messageId = reader.readUint16();
|
|
49
62
|
const granted = [];
|
|
50
63
|
while (reader.remaining > 0) {
|
|
51
64
|
granted.push(reader.readByte());
|
|
52
65
|
}
|
|
53
66
|
return { type: PacketType.SUBACK, messageId, granted };
|
|
54
|
-
}
|
|
55
|
-
|
|
67
|
+
};
|
|
68
|
+
const decodePublish = (reader, flags) => {
|
|
56
69
|
const topic = reader.readString();
|
|
57
70
|
const qos = ((flags >> 1) & 0x03);
|
|
58
71
|
const messageId = qos > 0 ? reader.readUint16() : undefined;
|
|
@@ -65,11 +78,10 @@ function decodePublish(reader, flags) {
|
|
|
65
78
|
dup: (flags & 0x08) !== 0,
|
|
66
79
|
messageId,
|
|
67
80
|
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
export function decodeAll(bytes) {
|
|
81
|
+
};
|
|
82
|
+
const decodePuback = (reader) => ({ type: PacketType.PUBACK, messageId: reader.readUint16() });
|
|
83
|
+
const decodeUnsuback = (reader) => ({ type: PacketType.UNSUBACK, messageId: reader.readUint16() });
|
|
84
|
+
export const decodeAll = (bytes) => {
|
|
73
85
|
const packets = [];
|
|
74
86
|
let offset = 0;
|
|
75
87
|
while (offset < bytes.length) {
|
|
@@ -80,4 +92,4 @@ export function decodeAll(bytes) {
|
|
|
80
92
|
offset += result.bytesConsumed;
|
|
81
93
|
}
|
|
82
94
|
return { packets, remaining: bytes.subarray(offset) };
|
|
83
|
-
}
|
|
95
|
+
};
|
package/dist/packets/encode.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { ConnectPacket, OutgoingPacket, PubackPacket, PublishPacket, SubscribePacket } from "./types.js";
|
|
2
|
-
export declare
|
|
3
|
-
export declare
|
|
4
|
-
export declare
|
|
5
|
-
export declare
|
|
6
|
-
export declare
|
|
7
|
-
export declare
|
|
1
|
+
import type { ConnectPacket, OutgoingPacket, PubackPacket, PublishPacket, SubscribePacket, UnsubscribePacket } from "./types.js";
|
|
2
|
+
export declare const encodeConnect: (packet: ConnectPacket) => Uint8Array;
|
|
3
|
+
export declare const encodeSubscribe: (packet: SubscribePacket) => Uint8Array;
|
|
4
|
+
export declare const encodeUnsubscribe: (packet: UnsubscribePacket) => Uint8Array;
|
|
5
|
+
export declare const encodePublish: (packet: PublishPacket) => Uint8Array;
|
|
6
|
+
export declare const encodePuback: (packet: PubackPacket) => Uint8Array;
|
|
7
|
+
export declare const encodePingreq: () => Uint8Array;
|
|
8
|
+
export declare const encodeDisconnect: () => Uint8Array;
|
|
8
9
|
export declare const encodePacket: (packet: OutgoingPacket) => Uint8Array;
|
|
9
10
|
//# sourceMappingURL=encode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/packets/encode.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,
|
|
1
|
+
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/packets/encode.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,EACf,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAoBpB,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,KAAG,UAoClD,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,QAAQ,eAAe,KAAG,UAQtD,CAAC;AAEL,eAAO,MAAM,iBAAiB,GAAI,QAAQ,iBAAiB,KAAG,UAO1D,CAAC;AAEL,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,KAAG,UAkBrD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,QAAQ,YAAY,KAAG,UAGhD,CAAC;AAEL,eAAO,MAAM,aAAa,QAAO,UACa,CAAC;AAE/C,eAAO,MAAM,gBAAgB,QAAO,UACa,CAAC;AAElD,eAAO,MAAM,YAAY,GAAI,QAAQ,cAAc,KAAG,UAyBrD,CAAC"}
|
package/dist/packets/encode.js
CHANGED
|
@@ -1,57 +1,59 @@
|
|
|
1
1
|
import { createPacketWriter, toUint8Array, } from "../utils/buffer.js";
|
|
2
2
|
import { ConnectFlags, DEFAULT_KEEPALIVE_SECONDS, PacketType, PROTOCOL_NAME, PROTOCOL_VERSION, } from "./constants.js";
|
|
3
|
-
|
|
3
|
+
const writePacket = (type, flags, writeBody) => {
|
|
4
4
|
const body = createPacketWriter();
|
|
5
5
|
writeBody(body);
|
|
6
6
|
const packet = createPacketWriter();
|
|
7
|
-
packet.writeByte((type << 4) | (flags &
|
|
7
|
+
packet.writeByte((type << 4) | (flags & 0x0F));
|
|
8
8
|
packet.writeVariableInt(body.length);
|
|
9
9
|
packet.writeBytes(body.toUint8Array());
|
|
10
10
|
return packet.toUint8Array();
|
|
11
|
-
}
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
writer.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
11
|
+
};
|
|
12
|
+
export const encodeConnect = (packet) => writePacket(PacketType.CONNECT, 0, (writer) => {
|
|
13
|
+
// Variable header
|
|
14
|
+
writer.writeString(PROTOCOL_NAME);
|
|
15
|
+
writer.writeByte(PROTOCOL_VERSION);
|
|
16
|
+
// Connect flags
|
|
17
|
+
let flags = 0;
|
|
18
|
+
if (packet.clean)
|
|
19
|
+
flags |= ConnectFlags.CLEAN_SESSION;
|
|
20
|
+
if (packet.will) {
|
|
21
|
+
flags |= ConnectFlags.WILL_FLAG;
|
|
22
|
+
flags |= packet.will.qos << 3;
|
|
23
|
+
if (packet.will.retain)
|
|
24
|
+
flags |= ConnectFlags.WILL_RETAIN;
|
|
25
|
+
}
|
|
26
|
+
if (packet.password !== undefined)
|
|
27
|
+
flags |= ConnectFlags.PASSWORD;
|
|
28
|
+
if (packet.username !== undefined)
|
|
29
|
+
flags |= ConnectFlags.USERNAME;
|
|
30
|
+
writer.writeByte(flags);
|
|
31
|
+
writer.writeUint16(packet.keepalive ?? DEFAULT_KEEPALIVE_SECONDS);
|
|
32
|
+
// Payload
|
|
33
|
+
writer.writeString(packet.clientId);
|
|
34
|
+
if (packet.will) {
|
|
35
|
+
writer.writeString(packet.will.topic);
|
|
36
|
+
writer.writeBinary(packet.will.payload);
|
|
37
|
+
}
|
|
38
|
+
if (packet.username !== undefined)
|
|
39
|
+
writer.writeString(packet.username);
|
|
40
|
+
if (packet.password !== undefined)
|
|
41
|
+
writer.writeString(packet.password);
|
|
42
|
+
});
|
|
43
|
+
export const encodeSubscribe = (packet) => writePacket(PacketType.SUBSCRIBE, 0x02, (writer) => {
|
|
44
|
+
writer.writeUint16(packet.messageId);
|
|
45
|
+
for (const sub of packet.subscriptions) {
|
|
46
|
+
writer.writeString(sub.topic);
|
|
47
|
+
writer.writeByte(sub.qos);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
export const encodeUnsubscribe = (packet) => writePacket(PacketType.UNSUBSCRIBE, 0x02, (writer) => {
|
|
51
|
+
writer.writeUint16(packet.messageId);
|
|
52
|
+
for (const topic of packet.topics) {
|
|
53
|
+
writer.writeString(topic);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
export const encodePublish = (packet) => {
|
|
55
57
|
let flags = 0;
|
|
56
58
|
if (packet.dup)
|
|
57
59
|
flags |= 0x08;
|
|
@@ -65,33 +67,35 @@ export function encodePublish(packet) {
|
|
|
65
67
|
}
|
|
66
68
|
writer.writeBytes(toUint8Array(packet.payload));
|
|
67
69
|
});
|
|
68
|
-
}
|
|
69
|
-
export
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
export function encodePingreq() {
|
|
75
|
-
return new Uint8Array([PacketType.PINGREQ << 4, 0]);
|
|
76
|
-
}
|
|
77
|
-
export function encodeDisconnect() {
|
|
78
|
-
return new Uint8Array([PacketType.DISCONNECT << 4, 0]);
|
|
79
|
-
}
|
|
70
|
+
};
|
|
71
|
+
export const encodePuback = (packet) => writePacket(PacketType.PUBACK, 0, (writer) => {
|
|
72
|
+
writer.writeUint16(packet.messageId);
|
|
73
|
+
});
|
|
74
|
+
export const encodePingreq = () => new Uint8Array([PacketType.PINGREQ << 4, 0]);
|
|
75
|
+
export const encodeDisconnect = () => new Uint8Array([PacketType.DISCONNECT << 4, 0]);
|
|
80
76
|
export const encodePacket = (packet) => {
|
|
81
77
|
switch (packet.type) {
|
|
82
|
-
case PacketType.CONNECT:
|
|
78
|
+
case PacketType.CONNECT: {
|
|
83
79
|
return encodeConnect(packet);
|
|
84
|
-
|
|
80
|
+
}
|
|
81
|
+
case PacketType.SUBSCRIBE: {
|
|
85
82
|
return encodeSubscribe(packet);
|
|
86
|
-
|
|
83
|
+
}
|
|
84
|
+
case PacketType.UNSUBSCRIBE: {
|
|
85
|
+
return encodeUnsubscribe(packet);
|
|
86
|
+
}
|
|
87
|
+
case PacketType.PUBLISH: {
|
|
87
88
|
return encodePublish(packet);
|
|
88
|
-
|
|
89
|
+
}
|
|
90
|
+
case PacketType.PUBACK: {
|
|
89
91
|
return encodePuback(packet);
|
|
92
|
+
}
|
|
90
93
|
// case PacketType.DISCONNECT:
|
|
91
94
|
// return encodeDisconnect();
|
|
92
95
|
// case PacketType.PINGREQ:
|
|
93
96
|
// return encodePingreq();
|
|
94
|
-
default:
|
|
97
|
+
default: {
|
|
95
98
|
throw new Error(`Unknown packet type: ${packet["type"]}`);
|
|
99
|
+
}
|
|
96
100
|
}
|
|
97
101
|
};
|
package/dist/packets/types.d.ts
CHANGED
|
@@ -47,6 +47,15 @@ export type SubackPacket = BasePacket & {
|
|
|
47
47
|
messageId: number;
|
|
48
48
|
granted: number[];
|
|
49
49
|
};
|
|
50
|
+
export type UnsubscribePacket = BasePacket & {
|
|
51
|
+
type: 10;
|
|
52
|
+
messageId: number;
|
|
53
|
+
topics: string[];
|
|
54
|
+
};
|
|
55
|
+
export type UnsubackPacket = BasePacket & {
|
|
56
|
+
type: 11;
|
|
57
|
+
messageId: number;
|
|
58
|
+
};
|
|
50
59
|
export type PingreqPacket = BasePacket & {
|
|
51
60
|
type: 12;
|
|
52
61
|
};
|
|
@@ -56,7 +65,7 @@ export type PingrespPacket = BasePacket & {
|
|
|
56
65
|
export type DisconnectPacket = BasePacket & {
|
|
57
66
|
type: 14;
|
|
58
67
|
};
|
|
59
|
-
export type MqttPacket = ConnectPacket | ConnackPacket | PublishPacket | PubackPacket | SubscribePacket | SubackPacket | PingreqPacket | PingrespPacket | DisconnectPacket;
|
|
60
|
-
export type IncomingPacket = ConnackPacket | PublishPacket | PubackPacket | SubackPacket | PingrespPacket;
|
|
61
|
-
export type OutgoingPacket = ConnectPacket | SubscribePacket | PublishPacket | PubackPacket | DisconnectPacket | PingreqPacket;
|
|
68
|
+
export type MqttPacket = ConnectPacket | ConnackPacket | PublishPacket | PubackPacket | SubscribePacket | SubackPacket | UnsubscribePacket | UnsubackPacket | PingreqPacket | PingrespPacket | DisconnectPacket;
|
|
69
|
+
export type IncomingPacket = ConnackPacket | PublishPacket | PubackPacket | SubackPacket | UnsubackPacket | PingrespPacket;
|
|
70
|
+
export type OutgoingPacket = ConnectPacket | SubscribePacket | UnsubscribePacket | PublishPacket | PubackPacket | DisconnectPacket | PingreqPacket;
|
|
62
71
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/packets/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,UAAU,CAAC;QACpB,GAAG,EAAE,QAAQ,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,GAAG,EAAE,QAAQ,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG;IACzC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,KAAK,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,QAAQ,CAAC;KACf,CAAC,CAAC;CACJ,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAC1C,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,aAAa,GACb,aAAa,GACb,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAErB,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,cAAc,CAAC;AAEnB,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,eAAe,GACf,aAAa,GACb,YAAY,GACZ,gBAAgB,GAChB,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/packets/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,UAAU,CAAC;QACpB,GAAG,EAAE,QAAQ,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,GAAG,EAAE,QAAQ,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG;IACzC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,KAAK,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,QAAQ,CAAC;KACf,CAAC,CAAC;CACJ,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG;IAC3C,IAAI,EAAE,EAAE,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC,IAAI,EAAE,EAAE,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAC1C,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,aAAa,GACb,aAAa,GACb,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAErB,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,cAAc,CAAC;AAEnB,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,aAAa,GACb,YAAY,GACZ,gBAAgB,GAChB,aAAa,CAAC"}
|
package/dist/utils/buffer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
export declare
|
|
1
|
+
export declare const toUint8Array: (data: string | Uint8Array) => Uint8Array;
|
|
2
|
+
export declare const createPacketWriter: (initialSize?: number) => {
|
|
3
3
|
writeByte(value: number): /*elided*/ any;
|
|
4
4
|
writeUint16(value: number): /*elided*/ any;
|
|
5
5
|
writeBytes(data: Uint8Array): /*elided*/ any;
|
|
@@ -9,7 +9,7 @@ export declare function createPacketWriter(initialSize?: number): {
|
|
|
9
9
|
toUint8Array(): Uint8Array;
|
|
10
10
|
readonly length: number;
|
|
11
11
|
};
|
|
12
|
-
export declare
|
|
12
|
+
export declare const createPacketReader: (buffer: Uint8Array) => {
|
|
13
13
|
readonly remaining: number;
|
|
14
14
|
readonly position: number;
|
|
15
15
|
readByte(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../src/utils/buffer.ts"],"names":[],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../src/utils/buffer.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,GAAG,UAAU,KAAG,UACK,CAAC;AAE/D,eAAO,MAAM,kBAAkB,GAAI,oBAAiB;qBAoB/B,MAAM;uBAOJ,MAAM;qBAQR,UAAU;uBAQR,MAAM;sBASP,UAAU;4BAOJ,MAAM;oBAcd,UAAU;qBAIZ,MAAM;CAMvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,UAAU;wBAIhC,MAAM;uBAIP,MAAM;gBAIV,MAAM;kBAIJ,MAAM;sBAQF,MAAM,GAAG,UAAU;kBAQvB,MAAM;uBAWD,MAAM;gBAcb,UAAU;CAQzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
package/dist/utils/buffer.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
const textEncoder = new TextEncoder();
|
|
2
2
|
const textDecoder = new TextDecoder();
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
export function createPacketWriter(initialSize = 256) {
|
|
3
|
+
export const toUint8Array = (data) => (typeof data === "string" ? textEncoder.encode(data) : data);
|
|
4
|
+
export const createPacketWriter = (initialSize = 256) => {
|
|
7
5
|
let buffer = new Uint8Array(initialSize);
|
|
8
6
|
let position = 0;
|
|
9
7
|
/**
|
|
@@ -11,14 +9,14 @@ export function createPacketWriter(initialSize = 256) {
|
|
|
11
9
|
* If the buffer is too small, it doubles in size or expands to fit the needed bytes,
|
|
12
10
|
* whichever is larger, and copies existing data to the new buffer.
|
|
13
11
|
*/
|
|
14
|
-
|
|
12
|
+
const ensureCapacity = (bytesNeeded) => {
|
|
15
13
|
if (position + bytesNeeded > buffer.length) {
|
|
16
14
|
const newSize = Math.max(buffer.length * 2, position + bytesNeeded);
|
|
17
15
|
const newBuffer = new Uint8Array(newSize);
|
|
18
16
|
newBuffer.set(buffer);
|
|
19
17
|
buffer = newBuffer;
|
|
20
18
|
}
|
|
21
|
-
}
|
|
19
|
+
};
|
|
22
20
|
const writer = {
|
|
23
21
|
writeByte(value) {
|
|
24
22
|
ensureCapacity(1);
|
|
@@ -27,8 +25,8 @@ export function createPacketWriter(initialSize = 256) {
|
|
|
27
25
|
},
|
|
28
26
|
writeUint16(value) {
|
|
29
27
|
ensureCapacity(2);
|
|
30
|
-
buffer[position++] = (value >> 8) &
|
|
31
|
-
buffer[position++] = value &
|
|
28
|
+
buffer[position++] = (value >> 8) & 0xFF;
|
|
29
|
+
buffer[position++] = value & 0xFF;
|
|
32
30
|
return writer;
|
|
33
31
|
},
|
|
34
32
|
writeBytes(data) {
|
|
@@ -66,8 +64,8 @@ export function createPacketWriter(initialSize = 256) {
|
|
|
66
64
|
},
|
|
67
65
|
};
|
|
68
66
|
return writer;
|
|
69
|
-
}
|
|
70
|
-
export
|
|
67
|
+
};
|
|
68
|
+
export const createPacketReader = (buffer) => {
|
|
71
69
|
let position = 0;
|
|
72
70
|
return {
|
|
73
71
|
get remaining() {
|
|
@@ -102,7 +100,7 @@ export function createPacketReader(buffer) {
|
|
|
102
100
|
let byte;
|
|
103
101
|
do {
|
|
104
102
|
byte = buffer[position++];
|
|
105
|
-
value += (byte &
|
|
103
|
+
value += (byte & 0x7F) * multiplier;
|
|
106
104
|
multiplier *= 128;
|
|
107
105
|
} while (byte & 0x80);
|
|
108
106
|
return value;
|
|
@@ -113,4 +111,4 @@ export function createPacketReader(buffer) {
|
|
|
113
111
|
return data;
|
|
114
112
|
},
|
|
115
113
|
};
|
|
116
|
-
}
|
|
114
|
+
};
|
package/dist/utils/events.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAElD,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAElD,eAAO,MAAM,YAAY,GACpB,UAAU,UAAU,KAAG,MAKvB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "websocket-mqtt",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "A lightweight MQTT WebSocket client library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,26 +23,16 @@
|
|
|
23
23
|
"author": "",
|
|
24
24
|
"license": "LGPL-3.0",
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"eslint": "^9.20.0",
|
|
29
|
-
"eslint-config-prettier": "^10.1.8",
|
|
30
|
-
"eslint-plugin-import": "^2.32.0",
|
|
31
|
-
"eslint-plugin-prettier": "^5.5.5",
|
|
32
|
-
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
33
|
-
"eslint-plugin-sonarjs": "^3.0.5",
|
|
34
|
-
"eslint-plugin-unicorn": "^62.0.0",
|
|
35
|
-
"eslint-plugin-unused-imports": "^4.3.0",
|
|
26
|
+
"eslint": "^9",
|
|
27
|
+
"eslint-plugin-v3xlabs": "1.7.11",
|
|
36
28
|
"mqtt": "^5.14.1",
|
|
37
|
-
"prettier": "^3.8.1",
|
|
38
29
|
"typescript": "^5.9.3",
|
|
39
|
-
"typescript-eslint": "^8.20.0",
|
|
40
30
|
"vitest": "^4.0.18"
|
|
41
31
|
},
|
|
42
32
|
"scripts": {
|
|
43
33
|
"test": "vitest",
|
|
44
34
|
"build": "tsc",
|
|
45
|
-
"lint": "eslint
|
|
46
|
-
"lint:fix": "eslint
|
|
35
|
+
"lint": "eslint",
|
|
36
|
+
"lint:fix": "eslint --fix"
|
|
47
37
|
}
|
|
48
38
|
}
|