@seriousme/opifex 1.8.1 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/mqttPacket/BitMask.d.ts +14 -10
- package/dist/mqttPacket/BitMask.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.js +13 -0
- package/dist/mqttPacket/BitMask.js.map +1 -1
- package/dist/mqttPacket/PacketType.d.ts +6 -0
- package/dist/mqttPacket/PacketType.d.ts.map +1 -1
- package/dist/mqttPacket/PacketType.js +6 -0
- package/dist/mqttPacket/PacketType.js.map +1 -1
- package/dist/mqttPacket/decoder.d.ts +71 -0
- package/dist/mqttPacket/decoder.d.ts.map +1 -1
- package/dist/mqttPacket/decoder.js +71 -0
- package/dist/mqttPacket/decoder.js.map +1 -1
- package/dist/mqttPacket/encoder.d.ts +52 -0
- package/dist/mqttPacket/encoder.d.ts.map +1 -1
- package/dist/mqttPacket/encoder.js +52 -0
- package/dist/mqttPacket/encoder.js.map +1 -1
- package/dist/mqttPacket/length.d.ts +21 -0
- package/dist/mqttPacket/length.d.ts.map +1 -1
- package/dist/mqttPacket/length.js +18 -0
- package/dist/mqttPacket/length.js.map +1 -1
- package/dist/mqttPacket/mod.d.ts +30 -3
- package/dist/mqttPacket/mod.d.ts.map +1 -1
- package/dist/mqttPacket/mod.js +30 -3
- package/dist/mqttPacket/mod.js.map +1 -1
- package/mqttPacket/BitMask.ts +14 -1
- package/mqttPacket/PacketType.ts +6 -0
- package/mqttPacket/decoder.ts +73 -1
- package/mqttPacket/encoder.ts +52 -0
- package/mqttPacket/length.ts +21 -0
- package/mqttPacket/mod.ts +31 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -90,16 +90,16 @@ Bun (as of version 1.2) is capable of running the NodeJS version.
|
|
|
90
90
|
|
|
91
91
|
## Exports
|
|
92
92
|
|
|
93
|
-
| Export
|
|
94
|
-
|
|
|
95
|
-
| @seriousme/opifex/tcpClient
|
|
96
|
-
| @seriousme/opifex/tcpServer
|
|
97
|
-
| @seriousme/opifex/server
|
|
98
|
-
| @seriousme/opifex/client
|
|
99
|
-
| @seriousme/opifex/
|
|
100
|
-
| @seriousme/opifex/mqttConn
|
|
101
|
-
| @seriousme/opifex/mqttPacket
|
|
102
|
-
| @seriousme/opifex/utils
|
|
93
|
+
| Export | Description |
|
|
94
|
+
| ----------------------------- | ------------------------------------------------------- |
|
|
95
|
+
| @seriousme/opifex/tcpClient | Exports a MQTT over TCP client |
|
|
96
|
+
| @seriousme/opifex/tcpServer | Exports a MQTT over TCP server |
|
|
97
|
+
| @seriousme/opifex/server | Exports a transport agnostic MQTT server |
|
|
98
|
+
| @seriousme/opifex/client | Exports a transport agnostic MQTT client |
|
|
99
|
+
| @seriousme/opifex/persistence | Exports an Typescript interface for storage persistence |
|
|
100
|
+
| @seriousme/opifex/mqttConn | Exports MQTT connection handling |
|
|
101
|
+
| @seriousme/opifex/mqttPacket | Exports MQTT packet handling |
|
|
102
|
+
| @seriousme/opifex/utils | Exports various utilities |
|
|
103
103
|
|
|
104
104
|
## Naming
|
|
105
105
|
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Object containing bit mask values from 2^0 to 2^7
|
|
3
|
+
* @constant
|
|
4
|
+
* @type {Record<string,number>}
|
|
5
|
+
* @property {number} bit0 - Represents 2^0 = 1
|
|
6
|
+
* @property {number} bit1 - Represents 2^1 = 2
|
|
7
|
+
* @property {number} bit2 - Represents 2^2 = 4
|
|
8
|
+
* @property {number} bit3 - Represents 2^3 = 8
|
|
9
|
+
* @property {number} bit4 - Represents 2^4 = 16
|
|
10
|
+
* @property {number} bit5 - Represents 2^5 = 32
|
|
11
|
+
* @property {number} bit6 - Represents 2^6 = 64
|
|
12
|
+
* @property {number} bit7 - Represents 2^7 = 128
|
|
13
|
+
*/
|
|
14
|
+
export declare const BitMask: Record<string, number>;
|
|
11
15
|
//# sourceMappingURL=BitMask.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitMask.d.ts","sourceRoot":"","sources":["../../mqttPacket/BitMask.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"BitMask.d.ts","sourceRoot":"","sources":["../../mqttPacket/BitMask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CASjC,CAAC"}
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object containing bit mask values from 2^0 to 2^7
|
|
3
|
+
* @constant
|
|
4
|
+
* @type {Record<string,number>}
|
|
5
|
+
* @property {number} bit0 - Represents 2^0 = 1
|
|
6
|
+
* @property {number} bit1 - Represents 2^1 = 2
|
|
7
|
+
* @property {number} bit2 - Represents 2^2 = 4
|
|
8
|
+
* @property {number} bit3 - Represents 2^3 = 8
|
|
9
|
+
* @property {number} bit4 - Represents 2^4 = 16
|
|
10
|
+
* @property {number} bit5 - Represents 2^5 = 32
|
|
11
|
+
* @property {number} bit6 - Represents 2^6 = 64
|
|
12
|
+
* @property {number} bit7 - Represents 2^7 = 128
|
|
13
|
+
*/
|
|
1
14
|
export const BitMask = {
|
|
2
15
|
bit0: 2 ** 0,
|
|
3
16
|
bit1: 2 ** 1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitMask.js","sourceRoot":"","sources":["../../mqttPacket/BitMask.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"BitMask.js","sourceRoot":"","sources":["../../mqttPacket/BitMask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,OAAO,GAA2B;IAC7C,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,IAAI,EAAE,CAAC,IAAI,CAAC;IACZ,IAAI,EAAE,CAAC,IAAI,CAAC;CACJ,CAAC"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Possible MQTT packet types
|
|
3
|
+
*/
|
|
1
4
|
export declare const PacketType: {
|
|
2
5
|
readonly reserved: 0;
|
|
3
6
|
readonly connect: 1;
|
|
@@ -15,5 +18,8 @@ export declare const PacketType: {
|
|
|
15
18
|
readonly pingres: 13;
|
|
16
19
|
readonly disconnect: 14;
|
|
17
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Reverse lookup for packet types
|
|
23
|
+
*/
|
|
18
24
|
export declare const PacketNameByType: Record<number, string>;
|
|
19
25
|
//# sourceMappingURL=PacketType.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PacketType.d.ts","sourceRoot":"","sources":["../../mqttPacket/PacketType.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;CAgBb,CAAC;AAEX,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAEnD,CAAC"}
|
|
1
|
+
{"version":3,"file":"PacketType.d.ts","sourceRoot":"","sources":["../../mqttPacket/PacketType.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;CAgBb,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAEnD,CAAC"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Possible MQTT packet types
|
|
3
|
+
*/
|
|
1
4
|
export const PacketType = {
|
|
2
5
|
reserved: 0,
|
|
3
6
|
connect: 1,
|
|
@@ -15,5 +18,8 @@ export const PacketType = {
|
|
|
15
18
|
pingres: 13,
|
|
16
19
|
disconnect: 14,
|
|
17
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Reverse lookup for packet types
|
|
23
|
+
*/
|
|
18
24
|
export const PacketNameByType = Object.fromEntries(Object.entries(PacketType).map(([k, v]) => [v, k]));
|
|
19
25
|
//# sourceMappingURL=PacketType.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PacketType.js","sourceRoot":"","sources":["../../mqttPacket/PacketType.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,EAAE;IACf,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,EAAE;CACN,CAAC;AAEX,MAAM,CAAC,MAAM,gBAAgB,GAA2B,MAAM,CAAC,WAAW,CACxE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACnD,CAAC"}
|
|
1
|
+
{"version":3,"file":"PacketType.js","sourceRoot":"","sources":["../../mqttPacket/PacketType.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,EAAE;IACf,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,EAAE;CACN,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA2B,MAAM,CAAC,WAAW,CACxE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACnD,CAAC"}
|
|
@@ -1,24 +1,95 @@
|
|
|
1
1
|
import type { TBitMask, Topic, TopicFilter } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a specific bit flag is set in a byte using a bitmask
|
|
4
|
+
* @param byte - The byte to check
|
|
5
|
+
* @param mask - The bitmask to apply
|
|
6
|
+
* @returns True if the flag is set, false otherwise
|
|
7
|
+
*/
|
|
2
8
|
export declare function booleanFlag(byte: number, mask: TBitMask): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Checks if a buffer is empty, throws error if not empty
|
|
11
|
+
* @param buf - The buffer to check
|
|
12
|
+
* @throws {DecoderError} If buffer is not empty
|
|
13
|
+
*/
|
|
3
14
|
export declare function isEmptyBuf(buf: Uint8Array): void;
|
|
15
|
+
/**
|
|
16
|
+
* Checks if flags are empty (zero), throws error if not
|
|
17
|
+
* @param flags - The flags value to check
|
|
18
|
+
* @throws {DecoderError} If flags are not zero
|
|
19
|
+
*/
|
|
4
20
|
export declare function hasEmptyFlags(flags: number): void;
|
|
21
|
+
/**
|
|
22
|
+
* Custom error class for decoder errors
|
|
23
|
+
*/
|
|
5
24
|
export declare class DecoderError extends Error {
|
|
6
25
|
constructor(message: string);
|
|
7
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Decoder class for parsing MQTT packets
|
|
29
|
+
*/
|
|
8
30
|
export declare class Decoder {
|
|
9
31
|
private buf;
|
|
10
32
|
private pos;
|
|
11
33
|
private len;
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new Decoder instance
|
|
36
|
+
* @param buf - The buffer to decode
|
|
37
|
+
* @param pos - Starting position in the buffer (default: 0)
|
|
38
|
+
*/
|
|
12
39
|
constructor(buf: Uint8Array, pos?: number);
|
|
40
|
+
/**
|
|
41
|
+
* Checks if the current position is valid
|
|
42
|
+
* @param pos - Position to check
|
|
43
|
+
* @throws {DecoderError} If position exceeds buffer length
|
|
44
|
+
*/
|
|
13
45
|
checkpos(pos: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* Gets a single byte from the buffer
|
|
48
|
+
* @returns The byte value
|
|
49
|
+
*/
|
|
14
50
|
getByte(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Gets a 16-bit integer from the buffer
|
|
53
|
+
* @returns The 16-bit integer value
|
|
54
|
+
*/
|
|
15
55
|
getInt16(): number;
|
|
56
|
+
/**
|
|
57
|
+
* Gets a byte array from the buffer
|
|
58
|
+
* @returns A subarray of the buffer
|
|
59
|
+
*/
|
|
16
60
|
getByteArray(): Uint8Array;
|
|
61
|
+
/**
|
|
62
|
+
* Gets a UTF-8 string from the buffer
|
|
63
|
+
* @returns The decoded UTF-8 string
|
|
64
|
+
*/
|
|
17
65
|
getUtf8String(): string;
|
|
66
|
+
/**
|
|
67
|
+
* Gets a topic from the buffer
|
|
68
|
+
* @returns The decoded topic
|
|
69
|
+
* @throws {DecoderError} If topic is invalid
|
|
70
|
+
*/
|
|
18
71
|
getTopic(): Topic;
|
|
72
|
+
/**
|
|
73
|
+
* Gets a topic filter from the buffer
|
|
74
|
+
* @returns The decoded topic filter
|
|
75
|
+
* @throws {DecoderError} If topic filter is invalid
|
|
76
|
+
*/
|
|
19
77
|
getTopicFilter(): TopicFilter;
|
|
78
|
+
/**
|
|
79
|
+
* Gets the remaining bytes from the current position to the end
|
|
80
|
+
* @returns The remaining bytes as a subarray
|
|
81
|
+
*/
|
|
20
82
|
getRemainder(): Uint8Array<ArrayBufferLike>;
|
|
83
|
+
/**
|
|
84
|
+
* Checks if decoder has reached the end of the buffer
|
|
85
|
+
* @returns True if at end, false otherwise
|
|
86
|
+
*/
|
|
21
87
|
atEnd(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Checks if decoding is complete
|
|
90
|
+
* @returns True if complete
|
|
91
|
+
* @throws {DecoderError} If packet is too long
|
|
92
|
+
*/
|
|
22
93
|
done(): boolean;
|
|
23
94
|
}
|
|
24
95
|
//# sourceMappingURL=decoder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../mqttPacket/decoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../mqttPacket/decoder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI/D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAIhD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIjD;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,GAAG,CAAS;IAEpB;;;;OAIG;gBACS,GAAG,EAAE,UAAU,EAAE,GAAG,GAAE,MAAU;IAM5C;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM3B;;;OAGG;IACH,OAAO,IAAI,MAAM;IAKjB;;;OAGG;IACH,QAAQ,IAAI,MAAM;IAMlB;;;OAGG;IACH,YAAY,IAAI,UAAU;IAS1B;;;OAGG;IACH,aAAa,IAAI,MAAM;IAKvB;;;;OAIG;IACH,QAAQ,IAAI,KAAK;IAUjB;;;;OAIG;IACH,cAAc,IAAI,WAAW;IAU7B;;;OAGG;IACH,YAAY;IAOZ;;;OAGG;IACH,KAAK,IAAI,OAAO;IAOhB;;;;OAIG;IACH,IAAI,IAAI,OAAO;CAMhB"}
|
|
@@ -1,47 +1,91 @@
|
|
|
1
1
|
import { invalidTopic, invalidTopicFilter } from "./validators.js";
|
|
2
2
|
const utf8Decoder = new TextDecoder("utf-8");
|
|
3
|
+
/**
|
|
4
|
+
* Checks if a specific bit flag is set in a byte using a bitmask
|
|
5
|
+
* @param byte - The byte to check
|
|
6
|
+
* @param mask - The bitmask to apply
|
|
7
|
+
* @returns True if the flag is set, false otherwise
|
|
8
|
+
*/
|
|
3
9
|
export function booleanFlag(byte, mask) {
|
|
4
10
|
return !!(byte & mask);
|
|
5
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Checks if a buffer is empty, throws error if not empty
|
|
14
|
+
* @param buf - The buffer to check
|
|
15
|
+
* @throws {DecoderError} If buffer is not empty
|
|
16
|
+
*/
|
|
6
17
|
export function isEmptyBuf(buf) {
|
|
7
18
|
if (buf.length > 0) {
|
|
8
19
|
throw new DecoderError("Packet too long");
|
|
9
20
|
}
|
|
10
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Checks if flags are empty (zero), throws error if not
|
|
24
|
+
* @param flags - The flags value to check
|
|
25
|
+
* @throws {DecoderError} If flags are not zero
|
|
26
|
+
*/
|
|
11
27
|
export function hasEmptyFlags(flags) {
|
|
12
28
|
if (flags !== 0) {
|
|
13
29
|
throw new DecoderError("Invalid fixed header flags");
|
|
14
30
|
}
|
|
15
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Custom error class for decoder errors
|
|
34
|
+
*/
|
|
16
35
|
export class DecoderError extends Error {
|
|
17
36
|
constructor(message) {
|
|
18
37
|
super(message);
|
|
19
38
|
this.name = "DecoderError";
|
|
20
39
|
}
|
|
21
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Decoder class for parsing MQTT packets
|
|
43
|
+
*/
|
|
22
44
|
export class Decoder {
|
|
23
45
|
buf;
|
|
24
46
|
pos;
|
|
25
47
|
len;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a new Decoder instance
|
|
50
|
+
* @param buf - The buffer to decode
|
|
51
|
+
* @param pos - Starting position in the buffer (default: 0)
|
|
52
|
+
*/
|
|
26
53
|
constructor(buf, pos = 0) {
|
|
27
54
|
this.buf = buf;
|
|
28
55
|
this.pos = pos;
|
|
29
56
|
this.len = buf.length;
|
|
30
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Checks if the current position is valid
|
|
60
|
+
* @param pos - Position to check
|
|
61
|
+
* @throws {DecoderError} If position exceeds buffer length
|
|
62
|
+
*/
|
|
31
63
|
checkpos(pos) {
|
|
32
64
|
if (pos > this.len) {
|
|
33
65
|
throw new DecoderError("Packet too short");
|
|
34
66
|
}
|
|
35
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Gets a single byte from the buffer
|
|
70
|
+
* @returns The byte value
|
|
71
|
+
*/
|
|
36
72
|
getByte() {
|
|
37
73
|
this.checkpos(this.pos);
|
|
38
74
|
return this.buf[this.pos++];
|
|
39
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Gets a 16-bit integer from the buffer
|
|
78
|
+
* @returns The 16-bit integer value
|
|
79
|
+
*/
|
|
40
80
|
getInt16() {
|
|
41
81
|
const msb = this.getByte();
|
|
42
82
|
const lsb = this.getByte();
|
|
43
83
|
return (msb << 8) | lsb;
|
|
44
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Gets a byte array from the buffer
|
|
87
|
+
* @returns A subarray of the buffer
|
|
88
|
+
*/
|
|
45
89
|
getByteArray() {
|
|
46
90
|
const len = this.getInt16();
|
|
47
91
|
const start = this.pos;
|
|
@@ -50,10 +94,19 @@ export class Decoder {
|
|
|
50
94
|
this.checkpos(end);
|
|
51
95
|
return this.buf.subarray(start, end);
|
|
52
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Gets a UTF-8 string from the buffer
|
|
99
|
+
* @returns The decoded UTF-8 string
|
|
100
|
+
*/
|
|
53
101
|
getUtf8String() {
|
|
54
102
|
const str = utf8Decoder.decode(this.getByteArray());
|
|
55
103
|
return str;
|
|
56
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Gets a topic from the buffer
|
|
107
|
+
* @returns The decoded topic
|
|
108
|
+
* @throws {DecoderError} If topic is invalid
|
|
109
|
+
*/
|
|
57
110
|
getTopic() {
|
|
58
111
|
const topic = this.getUtf8String();
|
|
59
112
|
if (invalidTopic(topic)) {
|
|
@@ -61,6 +114,11 @@ export class Decoder {
|
|
|
61
114
|
}
|
|
62
115
|
return topic;
|
|
63
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Gets a topic filter from the buffer
|
|
119
|
+
* @returns The decoded topic filter
|
|
120
|
+
* @throws {DecoderError} If topic filter is invalid
|
|
121
|
+
*/
|
|
64
122
|
getTopicFilter() {
|
|
65
123
|
const topicFilter = this.getUtf8String();
|
|
66
124
|
if (invalidTopicFilter(topicFilter)) {
|
|
@@ -68,18 +126,31 @@ export class Decoder {
|
|
|
68
126
|
}
|
|
69
127
|
return topicFilter;
|
|
70
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Gets the remaining bytes from the current position to the end
|
|
131
|
+
* @returns The remaining bytes as a subarray
|
|
132
|
+
*/
|
|
71
133
|
getRemainder() {
|
|
72
134
|
const start = this.pos;
|
|
73
135
|
const end = this.len;
|
|
74
136
|
this.pos = end;
|
|
75
137
|
return this.buf.subarray(start, end);
|
|
76
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Checks if decoder has reached the end of the buffer
|
|
141
|
+
* @returns True if at end, false otherwise
|
|
142
|
+
*/
|
|
77
143
|
atEnd() {
|
|
78
144
|
if (this.len === this.pos) {
|
|
79
145
|
return true;
|
|
80
146
|
}
|
|
81
147
|
return false;
|
|
82
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Checks if decoding is complete
|
|
151
|
+
* @returns True if complete
|
|
152
|
+
* @throws {DecoderError} If packet is too long
|
|
153
|
+
*/
|
|
83
154
|
done() {
|
|
84
155
|
if (this.atEnd()) {
|
|
85
156
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decoder.js","sourceRoot":"","sources":["../../mqttPacket/decoder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"decoder.js","sourceRoot":"","sources":["../../mqttPacket/decoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,69 @@
|
|
|
1
1
|
import type { Topic, TopicFilter } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Custom error class for encoding operations
|
|
4
|
+
*/
|
|
2
5
|
export declare class EncoderError extends Error {
|
|
3
6
|
constructor(message: string);
|
|
4
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Encoder class for MQTT packet encoding
|
|
10
|
+
*/
|
|
5
11
|
export declare class Encoder {
|
|
12
|
+
/** Internal buffer to store encoded bytes */
|
|
6
13
|
private buffer;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new Encoder instance
|
|
16
|
+
*/
|
|
7
17
|
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Adds a single byte to the buffer
|
|
20
|
+
* @param value - Byte value to add (0-255)
|
|
21
|
+
* @returns The encoder instance for chaining
|
|
22
|
+
*/
|
|
8
23
|
setByte(value: number): this;
|
|
24
|
+
/**
|
|
25
|
+
* Adds a 16-bit integer to the buffer in big-endian format
|
|
26
|
+
* @param value - 16-bit integer value to add
|
|
27
|
+
* @returns The encoder instance for chaining
|
|
28
|
+
*/
|
|
9
29
|
setInt16(value: number): this;
|
|
30
|
+
/**
|
|
31
|
+
* Adds a byte array to the buffer with length prefix
|
|
32
|
+
* @param value - Byte array to add
|
|
33
|
+
* @throws {EncoderError} If array length exceeds 0xffff bytes
|
|
34
|
+
* @returns The encoder instance for chaining
|
|
35
|
+
*/
|
|
10
36
|
setByteArray(value: Uint8Array): this;
|
|
37
|
+
/**
|
|
38
|
+
* Adds a UTF-8 encoded string to the buffer with length prefix
|
|
39
|
+
* @param value - String to encode and add
|
|
40
|
+
* @returns The encoder instance for chaining
|
|
41
|
+
*/
|
|
11
42
|
setUtf8String(value: string): this;
|
|
43
|
+
/**
|
|
44
|
+
* Adds an MQTT topic string to the buffer
|
|
45
|
+
* @param value - Topic string to add
|
|
46
|
+
* @throws {EncoderError} If topic is invalid
|
|
47
|
+
* @returns The encoder instance for chaining
|
|
48
|
+
*/
|
|
12
49
|
setTopic(value: Topic): this;
|
|
50
|
+
/**
|
|
51
|
+
* Adds an MQTT topic filter string to the buffer
|
|
52
|
+
* @param value - Topic filter string to add
|
|
53
|
+
* @throws {EncoderError} If topic filter is invalid
|
|
54
|
+
* @returns The encoder instance for chaining
|
|
55
|
+
*/
|
|
13
56
|
setTopicFilter(value: TopicFilter): this;
|
|
57
|
+
/**
|
|
58
|
+
* Adds remaining bytes to the buffer without modification
|
|
59
|
+
* @param value - Array of bytes to add
|
|
60
|
+
* @returns The encoder instance for chaining
|
|
61
|
+
*/
|
|
14
62
|
setRemainder(value: Uint8Array | number[]): this;
|
|
63
|
+
/**
|
|
64
|
+
* Returns the final encoded buffer
|
|
65
|
+
* @returns Array containing all encoded bytes
|
|
66
|
+
*/
|
|
15
67
|
done(): number[];
|
|
16
68
|
}
|
|
17
69
|
//# sourceMappingURL=encoder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../mqttPacket/encoder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGrD,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAW;;
|
|
1
|
+
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../mqttPacket/encoder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGrD;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,OAAO;IAClB,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAW;IAEzB;;OAEG;;IAKH;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM7B;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IASrC;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAU5B;;;;;OAKG;IACH,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAUxC;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,GAAG,IAAI;IAKhD;;;OAGG;IACH,IAAI,IAAI,MAAM,EAAE;CAGjB"}
|
|
@@ -1,25 +1,51 @@
|
|
|
1
1
|
const utf8Encoder = new TextEncoder();
|
|
2
2
|
import { invalidTopic, invalidTopicFilter } from "./validators.js";
|
|
3
|
+
/**
|
|
4
|
+
* Custom error class for encoding operations
|
|
5
|
+
*/
|
|
3
6
|
export class EncoderError extends Error {
|
|
4
7
|
constructor(message) {
|
|
5
8
|
super(message);
|
|
6
9
|
this.name = "EncoderError";
|
|
7
10
|
}
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Encoder class for MQTT packet encoding
|
|
14
|
+
*/
|
|
9
15
|
export class Encoder {
|
|
16
|
+
/** Internal buffer to store encoded bytes */
|
|
10
17
|
buffer;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new Encoder instance
|
|
20
|
+
*/
|
|
11
21
|
constructor() {
|
|
12
22
|
this.buffer = [];
|
|
13
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Adds a single byte to the buffer
|
|
26
|
+
* @param value - Byte value to add (0-255)
|
|
27
|
+
* @returns The encoder instance for chaining
|
|
28
|
+
*/
|
|
14
29
|
setByte(value) {
|
|
15
30
|
this.buffer.push(value);
|
|
16
31
|
return this;
|
|
17
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Adds a 16-bit integer to the buffer in big-endian format
|
|
35
|
+
* @param value - 16-bit integer value to add
|
|
36
|
+
* @returns The encoder instance for chaining
|
|
37
|
+
*/
|
|
18
38
|
setInt16(value) {
|
|
19
39
|
this.setByte(value >> 8);
|
|
20
40
|
this.setByte(value & 0xff);
|
|
21
41
|
return this;
|
|
22
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Adds a byte array to the buffer with length prefix
|
|
45
|
+
* @param value - Byte array to add
|
|
46
|
+
* @throws {EncoderError} If array length exceeds 0xffff bytes
|
|
47
|
+
* @returns The encoder instance for chaining
|
|
48
|
+
*/
|
|
23
49
|
setByteArray(value) {
|
|
24
50
|
if (value.length > 0xffff) {
|
|
25
51
|
throw new EncoderError("More than 0xffff bytes of data");
|
|
@@ -28,10 +54,21 @@ export class Encoder {
|
|
|
28
54
|
this.buffer.push(...value);
|
|
29
55
|
return this;
|
|
30
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Adds a UTF-8 encoded string to the buffer with length prefix
|
|
59
|
+
* @param value - String to encode and add
|
|
60
|
+
* @returns The encoder instance for chaining
|
|
61
|
+
*/
|
|
31
62
|
setUtf8String(value) {
|
|
32
63
|
this.setByteArray(utf8Encoder.encode(value));
|
|
33
64
|
return this;
|
|
34
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Adds an MQTT topic string to the buffer
|
|
68
|
+
* @param value - Topic string to add
|
|
69
|
+
* @throws {EncoderError} If topic is invalid
|
|
70
|
+
* @returns The encoder instance for chaining
|
|
71
|
+
*/
|
|
35
72
|
setTopic(value) {
|
|
36
73
|
if (invalidTopic(value)) {
|
|
37
74
|
throw new EncoderError("Topic must contain valid UTF-8 and contain more than 1 byte and no wildcards");
|
|
@@ -39,6 +76,12 @@ export class Encoder {
|
|
|
39
76
|
this.setUtf8String(value);
|
|
40
77
|
return this;
|
|
41
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Adds an MQTT topic filter string to the buffer
|
|
81
|
+
* @param value - Topic filter string to add
|
|
82
|
+
* @throws {EncoderError} If topic filter is invalid
|
|
83
|
+
* @returns The encoder instance for chaining
|
|
84
|
+
*/
|
|
42
85
|
setTopicFilter(value) {
|
|
43
86
|
if (invalidTopicFilter(value)) {
|
|
44
87
|
throw new EncoderError("Topicfilter must contain valid UTF-8 and contain more than 1 byte and valid wildcards");
|
|
@@ -46,10 +89,19 @@ export class Encoder {
|
|
|
46
89
|
this.setUtf8String(value);
|
|
47
90
|
return this;
|
|
48
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Adds remaining bytes to the buffer without modification
|
|
94
|
+
* @param value - Array of bytes to add
|
|
95
|
+
* @returns The encoder instance for chaining
|
|
96
|
+
*/
|
|
49
97
|
setRemainder(value) {
|
|
50
98
|
this.buffer.push(...value);
|
|
51
99
|
return this;
|
|
52
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns the final encoded buffer
|
|
103
|
+
* @returns Array containing all encoded bytes
|
|
104
|
+
*/
|
|
53
105
|
done() {
|
|
54
106
|
return this.buffer;
|
|
55
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../mqttPacket/encoder.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,OAAO;
|
|
1
|
+
{"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../mqttPacket/encoder.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEnE;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,OAAO;IAClB,6CAA6C;IACrC,MAAM,CAAW;IAEzB;;OAEG;IACH;QACE,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAa;QACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,KAAa;QACpB,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,KAAiB;QAC5B,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,YAAY,CAAC,gCAAgC,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,aAAa,CAAC,KAAa;QACzB,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAY;QACnB,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,YAAY,CACpB,8EAA8E,CAC/E,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,KAAkB;QAC/B,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,YAAY,CACpB,uFAAuF,CACxF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,YAAY,CAAC,KAA4B;QACvC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -1,12 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encodes a number into a variable-length byte array using a modified base-128 encoding
|
|
3
|
+
* @param n The number to encode
|
|
4
|
+
* @returns Array of bytes representing the encoded number
|
|
5
|
+
* @throws Error if the encoded length is greater than 4 bytes
|
|
6
|
+
*/
|
|
1
7
|
export declare function encodeLength(n: number): number[];
|
|
8
|
+
/**
|
|
9
|
+
* Decodes a variable-length encoded number from a byte array
|
|
10
|
+
* @param buf The byte array containing the encoded number
|
|
11
|
+
* @param start The starting position in the buffer to begin decoding
|
|
12
|
+
* @returns Object containing the decoded length and number of bytes used for encoding
|
|
13
|
+
* @throws Error if decoding fails
|
|
14
|
+
*/
|
|
2
15
|
export declare function decodeLength(buf: Uint8Array, start: number): {
|
|
3
16
|
length: number;
|
|
4
17
|
numLengthBytes: number;
|
|
5
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Interface for the result returned by the length decoder
|
|
21
|
+
*/
|
|
6
22
|
export type LengthDecoderResult = {
|
|
7
23
|
done: boolean;
|
|
8
24
|
length: number;
|
|
9
25
|
numLengthBytes: number;
|
|
10
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Creates a stateful decoder function for processing variable-length encoded numbers
|
|
29
|
+
* @returns Function that processes one byte at a time and returns decoding status
|
|
30
|
+
* @throws Error if the encoded length is greater than 4 bytes
|
|
31
|
+
*/
|
|
11
32
|
export declare function getLengthDecoder(): (encodedByte: number) => LengthDecoderResult;
|
|
12
33
|
//# sourceMappingURL=length.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"length.d.ts","sourceRoot":"","sources":["../../mqttPacket/length.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAehD;AAED,wBAAgB,YAAY,CAC1B,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAU5C;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,gBAAgB,IAAI,CAClC,WAAW,EAAE,MAAM,KAChB,mBAAmB,CAgBvB"}
|
|
1
|
+
{"version":3,"file":"length.d.ts","sourceRoot":"","sources":["../../mqttPacket/length.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAehD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAU5C;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,CAClC,WAAW,EAAE,MAAM,KAChB,mBAAmB,CAgBvB"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encodes a number into a variable-length byte array using a modified base-128 encoding
|
|
3
|
+
* @param n The number to encode
|
|
4
|
+
* @returns Array of bytes representing the encoded number
|
|
5
|
+
* @throws Error if the encoded length is greater than 4 bytes
|
|
6
|
+
*/
|
|
1
7
|
export function encodeLength(n) {
|
|
2
8
|
const output = [];
|
|
3
9
|
let x = n;
|
|
@@ -14,6 +20,13 @@ export function encodeLength(n) {
|
|
|
14
20
|
}
|
|
15
21
|
return output;
|
|
16
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Decodes a variable-length encoded number from a byte array
|
|
25
|
+
* @param buf The byte array containing the encoded number
|
|
26
|
+
* @param start The starting position in the buffer to begin decoding
|
|
27
|
+
* @returns Object containing the decoded length and number of bytes used for encoding
|
|
28
|
+
* @throws Error if decoding fails
|
|
29
|
+
*/
|
|
17
30
|
export function decodeLength(buf, start) {
|
|
18
31
|
const decode = getLengthDecoder();
|
|
19
32
|
const lenBuf = buf.subarray(start);
|
|
@@ -25,6 +38,11 @@ export function decodeLength(buf, start) {
|
|
|
25
38
|
}
|
|
26
39
|
throw Error("length decoding failed");
|
|
27
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates a stateful decoder function for processing variable-length encoded numbers
|
|
43
|
+
* @returns Function that processes one byte at a time and returns decoding status
|
|
44
|
+
* @throws Error if the encoded length is greater than 4 bytes
|
|
45
|
+
*/
|
|
28
46
|
export function getLengthDecoder() {
|
|
29
47
|
let numLengthBytes = 1;
|
|
30
48
|
let length = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"length.js","sourceRoot":"","sources":["../../mqttPacket/length.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC;QACF,IAAI,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC;QAC3B,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,WAAW,GAAG,WAAW,GAAG,IAAI,CAAC;QACnC,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;IAChB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,GAAe,EACf,KAAa;IAEb,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;IACD,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAC;AACxC,CAAC;
|
|
1
|
+
{"version":3,"file":"length.js","sourceRoot":"","sources":["../../mqttPacket/length.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,GAAG,CAAC;QACF,IAAI,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC;QAC3B,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,WAAW,GAAG,WAAW,GAAG,IAAI,CAAC;QACnC,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;IAChB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAe,EACf,KAAa;IAEb,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;IACD,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAC;AACxC,CAAC;AAWD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAG9B,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,OAAO,SAAS,aAAa,CAAC,WAAmB;QAC/C,MAAM,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,UAAU,CAAC;QAC5C,UAAU,IAAI,IAAI,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAChD,CAAC;QACD,IAAI,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/mqttPacket/mod.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* @module MQTT Packet Encoding/Decoding
|
|
3
|
+
* @description This module provides comprehensive encoding and decoding functionality for MQTT packets
|
|
4
|
+
* used in both server and client implementations. It handles all MQTT packet types and their
|
|
5
|
+
* transformations between binary and object representations.
|
|
5
6
|
*/
|
|
6
7
|
import type { ClientId, Dup, PacketId, Payload, QoS, ReturnCodes, TAuthenticationResult, Topic, TopicFilter, TPacketType } from "./types.ts";
|
|
7
8
|
import { PacketNameByType, PacketType } from "./PacketType.ts";
|
|
@@ -29,6 +30,10 @@ export type AnyPacket = ConnectPacket | ConnackPacket | PublishPacket | PubackPa
|
|
|
29
30
|
export type { ClientId, ConnackPacket, ConnectPacket, DisconnectPacket, Dup, PacketId, Payload, PingreqPacket, PingresPacket, PubackPacket, PubcompPacket, PublishPacket, PubrecPacket, PubrelPacket, QoS, ReturnCodes, SubackPacket, SubscribePacket, TAuthenticationResult, Topic, TopicFilter, TPacketType, UnsubackPacket, UnsubscribePacket, };
|
|
30
31
|
export type { Subscription } from "./subscribe.ts";
|
|
31
32
|
export { AuthenticationResult, AuthenticationResultByNumber, decodeLength, encodeLength, invalidTopic, invalidTopicFilter, invalidUTF8, PacketNameByType, PacketType, };
|
|
33
|
+
/**
|
|
34
|
+
* Array mapping MQTT packet types to their corresponding encode/decode handlers
|
|
35
|
+
* Index corresponds to packet type number.
|
|
36
|
+
*/
|
|
32
37
|
export declare const packetsByType: readonly [null, {
|
|
33
38
|
encode(packet: ConnectPacket): {
|
|
34
39
|
flags: number;
|
|
@@ -114,8 +119,30 @@ export declare const packetsByType: readonly [null, {
|
|
|
114
119
|
};
|
|
115
120
|
decode(buffer: Uint8Array, _flags: number): DisconnectPacket;
|
|
116
121
|
}];
|
|
122
|
+
/**
|
|
123
|
+
* @function encode
|
|
124
|
+
* @description Encodes an MQTT packet object into a binary Uint8Array format
|
|
125
|
+
* @param {AnyPacket} packet - The MQTT packet object to encode
|
|
126
|
+
* @returns {Uint8Array} The encoded packet as a binary buffer
|
|
127
|
+
* @throws {Error} If packet encoding fails
|
|
128
|
+
*/
|
|
117
129
|
export declare function encode(packet: AnyPacket): Uint8Array;
|
|
130
|
+
/**
|
|
131
|
+
* @function decodePayload
|
|
132
|
+
* @description Decodes a packet payload from binary format into an MQTT packet object
|
|
133
|
+
* @param {number} firstByte - The first byte of the MQTT packet containing type and flags
|
|
134
|
+
* @param {Uint8Array} buffer - The binary buffer containing the packet payload
|
|
135
|
+
* @returns {AnyPacket} The decoded MQTT packet object
|
|
136
|
+
* @throws {Error} If packet decoding fails
|
|
137
|
+
*/
|
|
118
138
|
export declare function decodePayload(firstByte: number, buffer: Uint8Array): AnyPacket;
|
|
139
|
+
/**
|
|
140
|
+
* @function decode
|
|
141
|
+
* @description Decodes a complete MQTT packet from binary format into a packet object
|
|
142
|
+
* @param {Uint8Array} buffer - The binary buffer containing the complete MQTT packet
|
|
143
|
+
* @returns {AnyPacket} The decoded MQTT packet object
|
|
144
|
+
* @throws {DecoderError} If packet decoding fails due to invalid format or insufficient data
|
|
145
|
+
*/
|
|
119
146
|
export declare function decode(buffer: Uint8Array): AnyPacket;
|
|
120
147
|
export { getLengthDecoder } from "../mqttPacket/length.ts";
|
|
121
148
|
export type { LengthDecoderResult } from "../mqttPacket/length.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../mqttPacket/mod.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../mqttPacket/mod.ts"],"names":[],"mappings":"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"}
|
package/dist/mqttPacket/mod.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* @module MQTT Packet Encoding/Decoding
|
|
3
|
+
* @description This module provides comprehensive encoding and decoding functionality for MQTT packets
|
|
4
|
+
* used in both server and client implementations. It handles all MQTT packet types and their
|
|
5
|
+
* transformations between binary and object representations.
|
|
5
6
|
*/
|
|
6
7
|
import { PacketNameByType, PacketType } from "./PacketType.js";
|
|
7
8
|
import { invalidTopic, invalidTopicFilter, invalidUTF8 } from "./validators.js";
|
|
@@ -23,6 +24,10 @@ import { pingres } from "./pingres.js";
|
|
|
23
24
|
import { disconnect } from "./disconnect.js";
|
|
24
25
|
import { DecoderError } from "./decoder.js";
|
|
25
26
|
export { AuthenticationResult, AuthenticationResultByNumber, decodeLength, encodeLength, invalidTopic, invalidTopicFilter, invalidUTF8, PacketNameByType, PacketType, };
|
|
27
|
+
/**
|
|
28
|
+
* Array mapping MQTT packet types to their corresponding encode/decode handlers
|
|
29
|
+
* Index corresponds to packet type number.
|
|
30
|
+
*/
|
|
26
31
|
export const packetsByType = [
|
|
27
32
|
null,
|
|
28
33
|
connect, // 1
|
|
@@ -40,6 +45,13 @@ export const packetsByType = [
|
|
|
40
45
|
pingres, // 13
|
|
41
46
|
disconnect, // 14
|
|
42
47
|
];
|
|
48
|
+
/**
|
|
49
|
+
* @function encode
|
|
50
|
+
* @description Encodes an MQTT packet object into a binary Uint8Array format
|
|
51
|
+
* @param {AnyPacket} packet - The MQTT packet object to encode
|
|
52
|
+
* @returns {Uint8Array} The encoded packet as a binary buffer
|
|
53
|
+
* @throws {Error} If packet encoding fails
|
|
54
|
+
*/
|
|
43
55
|
export function encode(packet) {
|
|
44
56
|
const packetType = packet.type;
|
|
45
57
|
// deno-lint-ignore no-explicit-any
|
|
@@ -55,6 +67,14 @@ export function encode(packet) {
|
|
|
55
67
|
...bytes,
|
|
56
68
|
]);
|
|
57
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* @function decodePayload
|
|
72
|
+
* @description Decodes a packet payload from binary format into an MQTT packet object
|
|
73
|
+
* @param {number} firstByte - The first byte of the MQTT packet containing type and flags
|
|
74
|
+
* @param {Uint8Array} buffer - The binary buffer containing the packet payload
|
|
75
|
+
* @returns {AnyPacket} The decoded MQTT packet object
|
|
76
|
+
* @throws {Error} If packet decoding fails
|
|
77
|
+
*/
|
|
58
78
|
export function decodePayload(firstByte, buffer) {
|
|
59
79
|
const packetType = firstByte >> 4;
|
|
60
80
|
const flags = firstByte & 0x0f;
|
|
@@ -64,6 +84,13 @@ export function decodePayload(firstByte, buffer) {
|
|
|
64
84
|
}
|
|
65
85
|
throw new Error("packet decoding failed");
|
|
66
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* @function decode
|
|
89
|
+
* @description Decodes a complete MQTT packet from binary format into a packet object
|
|
90
|
+
* @param {Uint8Array} buffer - The binary buffer containing the complete MQTT packet
|
|
91
|
+
* @returns {AnyPacket} The decoded MQTT packet object
|
|
92
|
+
* @throws {DecoderError} If packet decoding fails due to invalid format or insufficient data
|
|
93
|
+
*/
|
|
67
94
|
export function decode(buffer) {
|
|
68
95
|
if (buffer.length < 2) {
|
|
69
96
|
throw new DecoderError("Packet decoding failed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../mqttPacket/mod.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../mqttPacket/mod.ts"],"names":[],"mappings":"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"}
|
package/mqttPacket/BitMask.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Object containing bit mask values from 2^0 to 2^7
|
|
3
|
+
* @constant
|
|
4
|
+
* @type {Record<string,number>}
|
|
5
|
+
* @property {number} bit0 - Represents 2^0 = 1
|
|
6
|
+
* @property {number} bit1 - Represents 2^1 = 2
|
|
7
|
+
* @property {number} bit2 - Represents 2^2 = 4
|
|
8
|
+
* @property {number} bit3 - Represents 2^3 = 8
|
|
9
|
+
* @property {number} bit4 - Represents 2^4 = 16
|
|
10
|
+
* @property {number} bit5 - Represents 2^5 = 32
|
|
11
|
+
* @property {number} bit6 - Represents 2^6 = 64
|
|
12
|
+
* @property {number} bit7 - Represents 2^7 = 128
|
|
13
|
+
*/
|
|
14
|
+
export const BitMask: Record<string, number> = {
|
|
2
15
|
bit0: 2 ** 0,
|
|
3
16
|
bit1: 2 ** 1,
|
|
4
17
|
bit2: 2 ** 2,
|
package/mqttPacket/PacketType.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Possible MQTT packet types
|
|
3
|
+
*/
|
|
1
4
|
export const PacketType = {
|
|
2
5
|
reserved: 0,
|
|
3
6
|
connect: 1,
|
|
@@ -16,6 +19,9 @@ export const PacketType = {
|
|
|
16
19
|
disconnect: 14,
|
|
17
20
|
} as const;
|
|
18
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Reverse lookup for packet types
|
|
24
|
+
*/
|
|
19
25
|
export const PacketNameByType: Record<number, string> = Object.fromEntries(
|
|
20
26
|
Object.entries(PacketType).map(([k, v]) => [v, k]),
|
|
21
27
|
);
|
package/mqttPacket/decoder.ts
CHANGED
|
@@ -2,23 +2,41 @@ import type { TBitMask, Topic, TopicFilter } from "./types.ts";
|
|
|
2
2
|
import { invalidTopic, invalidTopicFilter } from "./validators.ts";
|
|
3
3
|
|
|
4
4
|
const utf8Decoder = new TextDecoder("utf-8");
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Checks if a specific bit flag is set in a byte using a bitmask
|
|
7
|
+
* @param byte - The byte to check
|
|
8
|
+
* @param mask - The bitmask to apply
|
|
9
|
+
* @returns True if the flag is set, false otherwise
|
|
10
|
+
*/
|
|
6
11
|
export function booleanFlag(byte: number, mask: TBitMask): boolean {
|
|
7
12
|
return !!(byte & mask);
|
|
8
13
|
}
|
|
9
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Checks if a buffer is empty, throws error if not empty
|
|
17
|
+
* @param buf - The buffer to check
|
|
18
|
+
* @throws {DecoderError} If buffer is not empty
|
|
19
|
+
*/
|
|
10
20
|
export function isEmptyBuf(buf: Uint8Array): void {
|
|
11
21
|
if (buf.length > 0) {
|
|
12
22
|
throw new DecoderError("Packet too long");
|
|
13
23
|
}
|
|
14
24
|
}
|
|
15
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Checks if flags are empty (zero), throws error if not
|
|
28
|
+
* @param flags - The flags value to check
|
|
29
|
+
* @throws {DecoderError} If flags are not zero
|
|
30
|
+
*/
|
|
16
31
|
export function hasEmptyFlags(flags: number): void {
|
|
17
32
|
if (flags !== 0) {
|
|
18
33
|
throw new DecoderError("Invalid fixed header flags");
|
|
19
34
|
}
|
|
20
35
|
}
|
|
21
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Custom error class for decoder errors
|
|
39
|
+
*/
|
|
22
40
|
export class DecoderError extends Error {
|
|
23
41
|
constructor(message: string) {
|
|
24
42
|
super(message);
|
|
@@ -26,33 +44,59 @@ export class DecoderError extends Error {
|
|
|
26
44
|
}
|
|
27
45
|
}
|
|
28
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Decoder class for parsing MQTT packets
|
|
49
|
+
*/
|
|
29
50
|
export class Decoder {
|
|
30
51
|
private buf: Uint8Array;
|
|
31
52
|
private pos: number;
|
|
32
53
|
private len: number;
|
|
33
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Creates a new Decoder instance
|
|
57
|
+
* @param buf - The buffer to decode
|
|
58
|
+
* @param pos - Starting position in the buffer (default: 0)
|
|
59
|
+
*/
|
|
34
60
|
constructor(buf: Uint8Array, pos: number = 0) {
|
|
35
61
|
this.buf = buf;
|
|
36
62
|
this.pos = pos;
|
|
37
63
|
this.len = buf.length;
|
|
38
64
|
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Checks if the current position is valid
|
|
68
|
+
* @param pos - Position to check
|
|
69
|
+
* @throws {DecoderError} If position exceeds buffer length
|
|
70
|
+
*/
|
|
39
71
|
checkpos(pos: number): void {
|
|
40
72
|
if (pos > this.len) {
|
|
41
73
|
throw new DecoderError("Packet too short");
|
|
42
74
|
}
|
|
43
75
|
}
|
|
44
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Gets a single byte from the buffer
|
|
79
|
+
* @returns The byte value
|
|
80
|
+
*/
|
|
45
81
|
getByte(): number {
|
|
46
82
|
this.checkpos(this.pos);
|
|
47
83
|
return this.buf[this.pos++];
|
|
48
84
|
}
|
|
49
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Gets a 16-bit integer from the buffer
|
|
88
|
+
* @returns The 16-bit integer value
|
|
89
|
+
*/
|
|
50
90
|
getInt16(): number {
|
|
51
91
|
const msb = this.getByte();
|
|
52
92
|
const lsb = this.getByte();
|
|
53
93
|
return (msb << 8) | lsb;
|
|
54
94
|
}
|
|
55
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Gets a byte array from the buffer
|
|
98
|
+
* @returns A subarray of the buffer
|
|
99
|
+
*/
|
|
56
100
|
getByteArray(): Uint8Array {
|
|
57
101
|
const len = this.getInt16();
|
|
58
102
|
const start = this.pos;
|
|
@@ -62,11 +106,20 @@ export class Decoder {
|
|
|
62
106
|
return this.buf.subarray(start, end);
|
|
63
107
|
}
|
|
64
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Gets a UTF-8 string from the buffer
|
|
111
|
+
* @returns The decoded UTF-8 string
|
|
112
|
+
*/
|
|
65
113
|
getUtf8String(): string {
|
|
66
114
|
const str = utf8Decoder.decode(this.getByteArray());
|
|
67
115
|
return str;
|
|
68
116
|
}
|
|
69
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Gets a topic from the buffer
|
|
120
|
+
* @returns The decoded topic
|
|
121
|
+
* @throws {DecoderError} If topic is invalid
|
|
122
|
+
*/
|
|
70
123
|
getTopic(): Topic {
|
|
71
124
|
const topic = this.getUtf8String();
|
|
72
125
|
if (invalidTopic(topic)) {
|
|
@@ -77,6 +130,11 @@ export class Decoder {
|
|
|
77
130
|
return topic;
|
|
78
131
|
}
|
|
79
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Gets a topic filter from the buffer
|
|
135
|
+
* @returns The decoded topic filter
|
|
136
|
+
* @throws {DecoderError} If topic filter is invalid
|
|
137
|
+
*/
|
|
80
138
|
getTopicFilter(): TopicFilter {
|
|
81
139
|
const topicFilter = this.getUtf8String();
|
|
82
140
|
if (invalidTopicFilter(topicFilter)) {
|
|
@@ -87,6 +145,10 @@ export class Decoder {
|
|
|
87
145
|
return topicFilter;
|
|
88
146
|
}
|
|
89
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Gets the remaining bytes from the current position to the end
|
|
150
|
+
* @returns The remaining bytes as a subarray
|
|
151
|
+
*/
|
|
90
152
|
getRemainder() {
|
|
91
153
|
const start = this.pos;
|
|
92
154
|
const end = this.len;
|
|
@@ -94,12 +156,22 @@ export class Decoder {
|
|
|
94
156
|
return this.buf.subarray(start, end);
|
|
95
157
|
}
|
|
96
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Checks if decoder has reached the end of the buffer
|
|
161
|
+
* @returns True if at end, false otherwise
|
|
162
|
+
*/
|
|
97
163
|
atEnd(): boolean {
|
|
98
164
|
if (this.len === this.pos) {
|
|
99
165
|
return true;
|
|
100
166
|
}
|
|
101
167
|
return false;
|
|
102
168
|
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Checks if decoding is complete
|
|
172
|
+
* @returns True if complete
|
|
173
|
+
* @throws {DecoderError} If packet is too long
|
|
174
|
+
*/
|
|
103
175
|
done(): boolean {
|
|
104
176
|
if (this.atEnd()) {
|
|
105
177
|
return true;
|
package/mqttPacket/encoder.ts
CHANGED
|
@@ -2,6 +2,9 @@ const utf8Encoder = new TextEncoder();
|
|
|
2
2
|
import type { Topic, TopicFilter } from "./types.ts";
|
|
3
3
|
import { invalidTopic, invalidTopicFilter } from "./validators.ts";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Custom error class for encoding operations
|
|
7
|
+
*/
|
|
5
8
|
export class EncoderError extends Error {
|
|
6
9
|
constructor(message: string) {
|
|
7
10
|
super(message);
|
|
@@ -9,24 +12,47 @@ export class EncoderError extends Error {
|
|
|
9
12
|
}
|
|
10
13
|
}
|
|
11
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Encoder class for MQTT packet encoding
|
|
17
|
+
*/
|
|
12
18
|
export class Encoder {
|
|
19
|
+
/** Internal buffer to store encoded bytes */
|
|
13
20
|
private buffer: number[];
|
|
14
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Creates a new Encoder instance
|
|
24
|
+
*/
|
|
15
25
|
constructor() {
|
|
16
26
|
this.buffer = [];
|
|
17
27
|
}
|
|
18
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Adds a single byte to the buffer
|
|
31
|
+
* @param value - Byte value to add (0-255)
|
|
32
|
+
* @returns The encoder instance for chaining
|
|
33
|
+
*/
|
|
19
34
|
setByte(value: number): this {
|
|
20
35
|
this.buffer.push(value);
|
|
21
36
|
return this;
|
|
22
37
|
}
|
|
23
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Adds a 16-bit integer to the buffer in big-endian format
|
|
41
|
+
* @param value - 16-bit integer value to add
|
|
42
|
+
* @returns The encoder instance for chaining
|
|
43
|
+
*/
|
|
24
44
|
setInt16(value: number): this {
|
|
25
45
|
this.setByte(value >> 8);
|
|
26
46
|
this.setByte(value & 0xff);
|
|
27
47
|
return this;
|
|
28
48
|
}
|
|
29
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Adds a byte array to the buffer with length prefix
|
|
52
|
+
* @param value - Byte array to add
|
|
53
|
+
* @throws {EncoderError} If array length exceeds 0xffff bytes
|
|
54
|
+
* @returns The encoder instance for chaining
|
|
55
|
+
*/
|
|
30
56
|
setByteArray(value: Uint8Array): this {
|
|
31
57
|
if (value.length > 0xffff) {
|
|
32
58
|
throw new EncoderError("More than 0xffff bytes of data");
|
|
@@ -36,11 +62,22 @@ export class Encoder {
|
|
|
36
62
|
return this;
|
|
37
63
|
}
|
|
38
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Adds a UTF-8 encoded string to the buffer with length prefix
|
|
67
|
+
* @param value - String to encode and add
|
|
68
|
+
* @returns The encoder instance for chaining
|
|
69
|
+
*/
|
|
39
70
|
setUtf8String(value: string): this {
|
|
40
71
|
this.setByteArray(utf8Encoder.encode(value));
|
|
41
72
|
return this;
|
|
42
73
|
}
|
|
43
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Adds an MQTT topic string to the buffer
|
|
77
|
+
* @param value - Topic string to add
|
|
78
|
+
* @throws {EncoderError} If topic is invalid
|
|
79
|
+
* @returns The encoder instance for chaining
|
|
80
|
+
*/
|
|
44
81
|
setTopic(value: Topic): this {
|
|
45
82
|
if (invalidTopic(value)) {
|
|
46
83
|
throw new EncoderError(
|
|
@@ -51,6 +88,12 @@ export class Encoder {
|
|
|
51
88
|
return this;
|
|
52
89
|
}
|
|
53
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Adds an MQTT topic filter string to the buffer
|
|
93
|
+
* @param value - Topic filter string to add
|
|
94
|
+
* @throws {EncoderError} If topic filter is invalid
|
|
95
|
+
* @returns The encoder instance for chaining
|
|
96
|
+
*/
|
|
54
97
|
setTopicFilter(value: TopicFilter): this {
|
|
55
98
|
if (invalidTopicFilter(value)) {
|
|
56
99
|
throw new EncoderError(
|
|
@@ -61,11 +104,20 @@ export class Encoder {
|
|
|
61
104
|
return this;
|
|
62
105
|
}
|
|
63
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Adds remaining bytes to the buffer without modification
|
|
109
|
+
* @param value - Array of bytes to add
|
|
110
|
+
* @returns The encoder instance for chaining
|
|
111
|
+
*/
|
|
64
112
|
setRemainder(value: Uint8Array | number[]): this {
|
|
65
113
|
this.buffer.push(...value);
|
|
66
114
|
return this;
|
|
67
115
|
}
|
|
68
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Returns the final encoded buffer
|
|
119
|
+
* @returns Array containing all encoded bytes
|
|
120
|
+
*/
|
|
69
121
|
done(): number[] {
|
|
70
122
|
return this.buffer;
|
|
71
123
|
}
|
package/mqttPacket/length.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encodes a number into a variable-length byte array using a modified base-128 encoding
|
|
3
|
+
* @param n The number to encode
|
|
4
|
+
* @returns Array of bytes representing the encoded number
|
|
5
|
+
* @throws Error if the encoded length is greater than 4 bytes
|
|
6
|
+
*/
|
|
1
7
|
export function encodeLength(n: number): number[] {
|
|
2
8
|
const output = [];
|
|
3
9
|
let x = n;
|
|
@@ -15,6 +21,13 @@ export function encodeLength(n: number): number[] {
|
|
|
15
21
|
return output;
|
|
16
22
|
}
|
|
17
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Decodes a variable-length encoded number from a byte array
|
|
26
|
+
* @param buf The byte array containing the encoded number
|
|
27
|
+
* @param start The starting position in the buffer to begin decoding
|
|
28
|
+
* @returns Object containing the decoded length and number of bytes used for encoding
|
|
29
|
+
* @throws Error if decoding fails
|
|
30
|
+
*/
|
|
18
31
|
export function decodeLength(
|
|
19
32
|
buf: Uint8Array,
|
|
20
33
|
start: number,
|
|
@@ -30,12 +43,20 @@ export function decodeLength(
|
|
|
30
43
|
throw Error("length decoding failed");
|
|
31
44
|
}
|
|
32
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Interface for the result returned by the length decoder
|
|
48
|
+
*/
|
|
33
49
|
export type LengthDecoderResult = {
|
|
34
50
|
done: boolean;
|
|
35
51
|
length: number;
|
|
36
52
|
numLengthBytes: number;
|
|
37
53
|
};
|
|
38
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Creates a stateful decoder function for processing variable-length encoded numbers
|
|
57
|
+
* @returns Function that processes one byte at a time and returns decoding status
|
|
58
|
+
* @throws Error if the encoded length is greater than 4 bytes
|
|
59
|
+
*/
|
|
39
60
|
export function getLengthDecoder(): (
|
|
40
61
|
encodedByte: number,
|
|
41
62
|
) => LengthDecoderResult {
|
package/mqttPacket/mod.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* @module MQTT Packet Encoding/Decoding
|
|
3
|
+
* @description This module provides comprehensive encoding and decoding functionality for MQTT packets
|
|
4
|
+
* used in both server and client implementations. It handles all MQTT packet types and their
|
|
5
|
+
* transformations between binary and object representations.
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
import type {
|
|
@@ -99,6 +100,10 @@ export {
|
|
|
99
100
|
PacketType,
|
|
100
101
|
};
|
|
101
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Array mapping MQTT packet types to their corresponding encode/decode handlers
|
|
105
|
+
* Index corresponds to packet type number.
|
|
106
|
+
*/
|
|
102
107
|
export const packetsByType = [
|
|
103
108
|
null,
|
|
104
109
|
connect, // 1
|
|
@@ -117,6 +122,13 @@ export const packetsByType = [
|
|
|
117
122
|
disconnect, // 14
|
|
118
123
|
] as const;
|
|
119
124
|
|
|
125
|
+
/**
|
|
126
|
+
* @function encode
|
|
127
|
+
* @description Encodes an MQTT packet object into a binary Uint8Array format
|
|
128
|
+
* @param {AnyPacket} packet - The MQTT packet object to encode
|
|
129
|
+
* @returns {Uint8Array} The encoded packet as a binary buffer
|
|
130
|
+
* @throws {Error} If packet encoding fails
|
|
131
|
+
*/
|
|
120
132
|
export function encode(packet: AnyPacket): Uint8Array {
|
|
121
133
|
const packetType: number = packet.type;
|
|
122
134
|
// deno-lint-ignore no-explicit-any
|
|
@@ -133,6 +145,15 @@ export function encode(packet: AnyPacket): Uint8Array {
|
|
|
133
145
|
]);
|
|
134
146
|
}
|
|
135
147
|
|
|
148
|
+
/**
|
|
149
|
+
* @function decodePayload
|
|
150
|
+
* @description Decodes a packet payload from binary format into an MQTT packet object
|
|
151
|
+
* @param {number} firstByte - The first byte of the MQTT packet containing type and flags
|
|
152
|
+
* @param {Uint8Array} buffer - The binary buffer containing the packet payload
|
|
153
|
+
* @returns {AnyPacket} The decoded MQTT packet object
|
|
154
|
+
* @throws {Error} If packet decoding fails
|
|
155
|
+
*/
|
|
156
|
+
|
|
136
157
|
export function decodePayload(
|
|
137
158
|
firstByte: number,
|
|
138
159
|
buffer: Uint8Array,
|
|
@@ -146,6 +167,13 @@ export function decodePayload(
|
|
|
146
167
|
throw new Error("packet decoding failed");
|
|
147
168
|
}
|
|
148
169
|
|
|
170
|
+
/**
|
|
171
|
+
* @function decode
|
|
172
|
+
* @description Decodes a complete MQTT packet from binary format into a packet object
|
|
173
|
+
* @param {Uint8Array} buffer - The binary buffer containing the complete MQTT packet
|
|
174
|
+
* @returns {AnyPacket} The decoded MQTT packet object
|
|
175
|
+
* @throws {DecoderError} If packet decoding fails due to invalid format or insufficient data
|
|
176
|
+
*/
|
|
149
177
|
export function decode(buffer: Uint8Array): AnyPacket {
|
|
150
178
|
if (buffer.length < 2) {
|
|
151
179
|
throw new DecoderError("Packet decoding failed");
|