websocket-mqtt 0.0.6 → 0.0.8
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.map +1 -1
- package/dist/base.js +14 -18
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +51 -46
- package/dist/packets/decode.d.ts +2 -2
- package/dist/packets/decode.d.ts.map +1 -1
- package/dist/packets/decode.js +27 -20
- package/dist/packets/encode.d.ts +6 -6
- package/dist/packets/encode.d.ts.map +1 -1
- package/dist/packets/encode.js +58 -63
- 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.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,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IACrE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACxB,KAAK,EAAE,EAAE,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,iBAAiB,CAAC;AAEtB,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,
|
|
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,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IACrE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACxB,KAAK,EAAE,EAAE,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,iBAAiB,CAAC;AAEtB,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,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;AACF,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtD,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;CACnD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,WAAW,KAAG,UAiIjD,CAAC"}
|
package/dist/base.js
CHANGED
|
@@ -24,7 +24,7 @@ export const createMqtt = (options) => {
|
|
|
24
24
|
const request = pending.sub.get(packet.messageId);
|
|
25
25
|
if (request) {
|
|
26
26
|
pending.sub.delete(packet.messageId);
|
|
27
|
-
const hasFailure = packet.granted.
|
|
27
|
+
const hasFailure = packet.granted.includes(0x80);
|
|
28
28
|
if (hasFailure) {
|
|
29
29
|
request.reject(new Error("Subscription failed"));
|
|
30
30
|
}
|
|
@@ -81,24 +81,20 @@ export const createMqtt = (options) => {
|
|
|
81
81
|
pending.pub.set(messageId, { resolve, reject });
|
|
82
82
|
});
|
|
83
83
|
};
|
|
84
|
-
const subscribe = (topic, qos = QoS.AT_MOST_ONCE) => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
subscriptions: [{ topic, qos }],
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
};
|
|
95
|
-
const connect = () => {
|
|
96
|
-
return new Promise((resolve, reject) => {
|
|
97
|
-
connection.open();
|
|
98
|
-
connection.on("connect", () => resolve());
|
|
99
|
-
connection.on("error", (err) => reject(err));
|
|
84
|
+
const subscribe = (topic, qos = QoS.AT_MOST_ONCE) => new Promise((resolve, reject) => {
|
|
85
|
+
const messageId = connection.nextMessageId();
|
|
86
|
+
pending.sub.set(messageId, { resolve, reject });
|
|
87
|
+
connection.send({
|
|
88
|
+
type: PacketType.SUBSCRIBE,
|
|
89
|
+
messageId,
|
|
90
|
+
subscriptions: [{ topic, qos }],
|
|
100
91
|
});
|
|
101
|
-
};
|
|
92
|
+
});
|
|
93
|
+
const connect = () => new Promise((resolve, reject) => {
|
|
94
|
+
connection.open();
|
|
95
|
+
connection.on("connect", () => resolve());
|
|
96
|
+
connection.on("error", err => reject(err));
|
|
97
|
+
});
|
|
102
98
|
return {
|
|
103
99
|
...events,
|
|
104
100
|
publish,
|
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;AAElE,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;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,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;IACxB,KAAK,EAAE,EAAE,CAAC;CACX,CAAC;AAEF,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB;;;;;;
|
|
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;AAElE,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;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,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;IACxB,KAAK,EAAE,EAAE,CAAC;CACX,CAAC;AAEF,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB;;;;;;mBA6FnC,cAAc,KAAG,IAAI;yBAlEjB,MAAM;;CAiKjC,CAAC"}
|
package/dist/connection.js
CHANGED
|
@@ -9,9 +9,10 @@ export const createConnection = (options) => {
|
|
|
9
9
|
const log = createLogger(options);
|
|
10
10
|
let lastMessageId = 1;
|
|
11
11
|
let connected = false;
|
|
12
|
-
let pingInterval
|
|
13
|
-
let ws
|
|
14
|
-
const { clientId = DEFAULT_CLIENT_ID + Math.random().toString(36)
|
|
12
|
+
let pingInterval;
|
|
13
|
+
let ws;
|
|
14
|
+
const { clientId = DEFAULT_CLIENT_ID + Math.random().toString(36)
|
|
15
|
+
.slice(2, 15), username, password, keepalive = DEFAULT_KEEPALIVE_SECONDS, clean = true, url, signal, } = options;
|
|
15
16
|
const will = options.will
|
|
16
17
|
? {
|
|
17
18
|
topic: options.will.topic,
|
|
@@ -34,6 +35,44 @@ export const createConnection = (options) => {
|
|
|
34
35
|
}, pingIntervalMs);
|
|
35
36
|
}
|
|
36
37
|
};
|
|
38
|
+
let receiveBuffer = new Uint8Array(0);
|
|
39
|
+
const handlePacket2 = (packet) => {
|
|
40
|
+
log("handlePacket2", packet);
|
|
41
|
+
switch (packet.type) {
|
|
42
|
+
case PacketType.CONNACK: {
|
|
43
|
+
if (packet.returnCode === 0) {
|
|
44
|
+
connected = true;
|
|
45
|
+
startPingInterval();
|
|
46
|
+
events.emit("connect", packet);
|
|
47
|
+
log("connected");
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const message = getConnackErrorMessage(packet.returnCode);
|
|
51
|
+
console.error(message);
|
|
52
|
+
events.emit("error", new Error(message));
|
|
53
|
+
close();
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case PacketType.PUBLISH: {
|
|
58
|
+
log("received a publish packet");
|
|
59
|
+
if (packet.qos === 1 && packet.messageId !== undefined) {
|
|
60
|
+
send({ type: PacketType.PUBACK, messageId: packet.messageId });
|
|
61
|
+
}
|
|
62
|
+
events.emit("message", packet.topic, packet.payload, packet);
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case PacketType.PINGRESP: {
|
|
66
|
+
log("PINGRESP");
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
default: {
|
|
70
|
+
log("received a default packet");
|
|
71
|
+
events.emit("packet", packet);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
37
76
|
const send = (packet) => {
|
|
38
77
|
log("sending packet", packet);
|
|
39
78
|
sendRaw(encodePacket(packet));
|
|
@@ -56,13 +95,13 @@ export const createConnection = (options) => {
|
|
|
56
95
|
connected = false;
|
|
57
96
|
if (pingInterval) {
|
|
58
97
|
clearInterval(pingInterval);
|
|
59
|
-
pingInterval =
|
|
98
|
+
pingInterval = undefined;
|
|
60
99
|
}
|
|
61
100
|
};
|
|
62
101
|
const open = () => {
|
|
63
102
|
ws = new WebSocket(url, ["mqtt"]);
|
|
64
103
|
ws.binaryType = "arraybuffer";
|
|
65
|
-
ws.
|
|
104
|
+
ws.addEventListener("open", () => {
|
|
66
105
|
// sendConnect();
|
|
67
106
|
const packet = encodeConnect({
|
|
68
107
|
type: PacketType.CONNECT,
|
|
@@ -74,42 +113,8 @@ export const createConnection = (options) => {
|
|
|
74
113
|
will,
|
|
75
114
|
});
|
|
76
115
|
sendRaw(packet);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const handlePacket2 = (packet) => {
|
|
80
|
-
log("handlePacket2", packet);
|
|
81
|
-
switch (packet.type) {
|
|
82
|
-
case PacketType.CONNACK:
|
|
83
|
-
if (packet.returnCode === 0) {
|
|
84
|
-
connected = true;
|
|
85
|
-
startPingInterval();
|
|
86
|
-
events.emit("connect", packet);
|
|
87
|
-
log("connected");
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
const message = getConnackErrorMessage(packet.returnCode);
|
|
91
|
-
console.error(message);
|
|
92
|
-
events.emit("error", new Error(message));
|
|
93
|
-
close();
|
|
94
|
-
}
|
|
95
|
-
break;
|
|
96
|
-
case PacketType.PUBLISH:
|
|
97
|
-
log("received a publish packet");
|
|
98
|
-
if (packet.qos === 1 && packet.messageId !== undefined) {
|
|
99
|
-
send({ type: PacketType.PUBACK, messageId: packet.messageId });
|
|
100
|
-
}
|
|
101
|
-
events.emit("message", packet.topic, packet.payload, packet);
|
|
102
|
-
break;
|
|
103
|
-
case PacketType.PINGRESP:
|
|
104
|
-
log("PINGRESP");
|
|
105
|
-
break;
|
|
106
|
-
default:
|
|
107
|
-
log("received a default packet");
|
|
108
|
-
events.emit("packet", packet);
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
ws.onmessage = (event) => {
|
|
116
|
+
});
|
|
117
|
+
ws.addEventListener("message", (event) => {
|
|
113
118
|
log("onmessage");
|
|
114
119
|
const data = new Uint8Array(event.data);
|
|
115
120
|
const combined = new Uint8Array(receiveBuffer.length + data.length);
|
|
@@ -123,14 +128,14 @@ export const createConnection = (options) => {
|
|
|
123
128
|
log("packet", packet);
|
|
124
129
|
handlePacket2(packet);
|
|
125
130
|
}
|
|
126
|
-
};
|
|
127
|
-
ws.
|
|
131
|
+
});
|
|
132
|
+
ws.addEventListener("error", (event) => {
|
|
128
133
|
events.emit("error", event);
|
|
129
|
-
};
|
|
130
|
-
ws.
|
|
134
|
+
});
|
|
135
|
+
ws.addEventListener("close", () => {
|
|
131
136
|
log("ws:onclose");
|
|
132
137
|
close();
|
|
133
|
-
};
|
|
138
|
+
});
|
|
134
139
|
};
|
|
135
140
|
signal?.addEventListener("abort", () => {
|
|
136
141
|
log("abort signal received");
|
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,EAKf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,
|
|
1
|
+
{"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/packets/decode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EAKf,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,IAiDzD,CAAC;AA0CF,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,67 @@
|
|
|
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.PINGRESP: {
|
|
32
39
|
packet = { type: PacketType.PINGRESP };
|
|
33
40
|
break;
|
|
34
|
-
|
|
41
|
+
}
|
|
42
|
+
default: {
|
|
35
43
|
throw new Error(`Unknown MQTT packet type: ${packetType}`);
|
|
44
|
+
}
|
|
36
45
|
}
|
|
37
46
|
return { packet, bytesConsumed: totalLength };
|
|
38
|
-
}
|
|
39
|
-
|
|
47
|
+
};
|
|
48
|
+
const decodeConnack = (reader) => {
|
|
40
49
|
const flags = reader.readByte();
|
|
41
50
|
return {
|
|
42
51
|
type: PacketType.CONNACK,
|
|
43
52
|
sessionPresent: (flags & 0x01) === 1,
|
|
44
53
|
returnCode: reader.readByte(),
|
|
45
54
|
};
|
|
46
|
-
}
|
|
47
|
-
|
|
55
|
+
};
|
|
56
|
+
const decodeSuback = (reader) => {
|
|
48
57
|
const messageId = reader.readUint16();
|
|
49
58
|
const granted = [];
|
|
50
59
|
while (reader.remaining > 0) {
|
|
51
60
|
granted.push(reader.readByte());
|
|
52
61
|
}
|
|
53
62
|
return { type: PacketType.SUBACK, messageId, granted };
|
|
54
|
-
}
|
|
55
|
-
|
|
63
|
+
};
|
|
64
|
+
const decodePublish = (reader, flags) => {
|
|
56
65
|
const topic = reader.readString();
|
|
57
66
|
const qos = ((flags >> 1) & 0x03);
|
|
58
67
|
const messageId = qos > 0 ? reader.readUint16() : undefined;
|
|
@@ -65,11 +74,9 @@ function decodePublish(reader, flags) {
|
|
|
65
74
|
dup: (flags & 0x08) !== 0,
|
|
66
75
|
messageId,
|
|
67
76
|
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
export function decodeAll(bytes) {
|
|
77
|
+
};
|
|
78
|
+
const decodePuback = (reader) => ({ type: PacketType.PUBACK, messageId: reader.readUint16() });
|
|
79
|
+
export const decodeAll = (bytes) => {
|
|
73
80
|
const packets = [];
|
|
74
81
|
let offset = 0;
|
|
75
82
|
while (offset < bytes.length) {
|
|
@@ -80,4 +87,4 @@ export function decodeAll(bytes) {
|
|
|
80
87
|
offset += result.bytesConsumed;
|
|
81
88
|
}
|
|
82
89
|
return { packets, remaining: bytes.subarray(offset) };
|
|
83
|
-
}
|
|
90
|
+
};
|
package/dist/packets/encode.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
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
|
|
2
|
+
export declare const encodeConnect: (packet: ConnectPacket) => Uint8Array;
|
|
3
|
+
export declare const encodeSubscribe: (packet: SubscribePacket) => Uint8Array;
|
|
4
|
+
export declare const encodePublish: (packet: PublishPacket) => Uint8Array;
|
|
5
|
+
export declare const encodePuback: (packet: PubackPacket) => Uint8Array;
|
|
6
|
+
export declare const encodePingreq: () => Uint8Array;
|
|
7
|
+
export declare const encodeDisconnect: () => Uint8Array;
|
|
8
8
|
export declare const encodePacket: (packet: OutgoingPacket) => Uint8Array;
|
|
9
9
|
//# 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,EAChB,MAAM,YAAY,CAAC;AAoBpB,
|
|
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,EAChB,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,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,UAsBrD,CAAC"}
|
package/dist/packets/encode.js
CHANGED
|
@@ -1,57 +1,53 @@
|
|
|
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
|
-
export function encodePublish(packet) {
|
|
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 encodePublish = (packet) => {
|
|
55
51
|
let flags = 0;
|
|
56
52
|
if (packet.dup)
|
|
57
53
|
flags |= 0x08;
|
|
@@ -65,33 +61,32 @@ export function encodePublish(packet) {
|
|
|
65
61
|
}
|
|
66
62
|
writer.writeBytes(toUint8Array(packet.payload));
|
|
67
63
|
});
|
|
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
|
-
}
|
|
64
|
+
};
|
|
65
|
+
export const encodePuback = (packet) => writePacket(PacketType.PUBACK, 0, (writer) => {
|
|
66
|
+
writer.writeUint16(packet.messageId);
|
|
67
|
+
});
|
|
68
|
+
export const encodePingreq = () => new Uint8Array([PacketType.PINGREQ << 4, 0]);
|
|
69
|
+
export const encodeDisconnect = () => new Uint8Array([PacketType.DISCONNECT << 4, 0]);
|
|
80
70
|
export const encodePacket = (packet) => {
|
|
81
71
|
switch (packet.type) {
|
|
82
|
-
case PacketType.CONNECT:
|
|
72
|
+
case PacketType.CONNECT: {
|
|
83
73
|
return encodeConnect(packet);
|
|
84
|
-
|
|
74
|
+
}
|
|
75
|
+
case PacketType.SUBSCRIBE: {
|
|
85
76
|
return encodeSubscribe(packet);
|
|
86
|
-
|
|
77
|
+
}
|
|
78
|
+
case PacketType.PUBLISH: {
|
|
87
79
|
return encodePublish(packet);
|
|
88
|
-
|
|
80
|
+
}
|
|
81
|
+
case PacketType.PUBACK: {
|
|
89
82
|
return encodePuback(packet);
|
|
83
|
+
}
|
|
90
84
|
// case PacketType.DISCONNECT:
|
|
91
85
|
// return encodeDisconnect();
|
|
92
86
|
// case PacketType.PINGREQ:
|
|
93
87
|
// return encodePingreq();
|
|
94
|
-
default:
|
|
88
|
+
default: {
|
|
95
89
|
throw new Error(`Unknown packet type: ${packet["type"]}`);
|
|
90
|
+
}
|
|
96
91
|
}
|
|
97
92
|
};
|
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.8",
|
|
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
|
}
|