@seriousme/opifex 1.11.2 → 1.11.3
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/LICENSE.txt +1 -1
- package/README.md +8 -8
- package/bin/mqtt.ts +52 -30
- package/client/client.ts +9 -9
- package/client/deps.ts +1 -0
- package/client/mod.ts +1 -1
- package/dev_utils/mod.ts +1 -0
- package/dev_utils/socketPair.ts +85 -0
- package/dist/bin/mqtt.js +19 -16
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/client.d.ts +6 -6
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js.map +1 -1
- package/dist/client/deps.d.ts +1 -1
- package/dist/client/deps.d.ts.map +1 -1
- package/dist/client/deps.js.map +1 -1
- package/dist/client/mod.d.ts +1 -1
- package/dist/client/mod.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.d.ts +2 -1
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +16 -8
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts +12 -11
- package/dist/mqttPacket/BitMask.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.js +10 -18
- package/dist/mqttPacket/BitMask.js.map +1 -1
- package/dist/mqttPacket/connect.d.ts +22 -22
- package/dist/mqttPacket/connect.d.ts.map +1 -1
- package/dist/mqttPacket/decoder.js +1 -1
- package/dist/mqttPacket/decoder.js.map +1 -1
- package/dist/mqttPacket/length.js +1 -1
- package/dist/mqttPacket/length.js.map +1 -1
- package/dist/mqttPacket/mod.js +1 -1
- package/dist/mqttPacket/mod.js.map +1 -1
- package/dist/mqttPacket/pubblishAcks.d.ts +5 -5
- package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
- package/dist/mqttPacket/pubblishAcks.js.map +1 -1
- package/dist/mqttPacket/publish.d.ts +9 -9
- package/dist/mqttPacket/publish.d.ts.map +1 -1
- package/dist/persistence/memory/memoryPersistence.d.ts +3 -3
- package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
- package/dist/persistence/memory/memoryPersistence.js +1 -1
- package/dist/persistence/memory/memoryPersistence.js.map +1 -1
- package/dist/persistence/mod.d.ts +1 -1
- package/dist/persistence/mod.d.ts.map +1 -1
- package/dist/persistence/mod.js.map +1 -1
- package/dist/persistence/store.d.ts +3 -2
- package/dist/persistence/store.d.ts.map +1 -1
- package/dist/server/context.d.ts +1 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js.map +1 -1
- package/dist/server/handlers/handlePublish.js +1 -1
- package/dist/server/handlers/handlePublish.js.map +1 -1
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +4 -0
- package/dist/socket/socket.js.map +1 -1
- package/dist/trie/trie.d.ts.map +1 -1
- package/dist/trie/trie.js +30 -20
- package/dist/trie/trie.js.map +1 -1
- package/dist/utils/BufferedAsyncIterable.js.map +1 -1
- package/mqttConn/mqttConn.ts +18 -8
- package/mqttPacket/BitMask.ts +11 -19
- package/mqttPacket/connect.ts +22 -22
- package/mqttPacket/decoder.ts +1 -1
- package/mqttPacket/length.ts +1 -1
- package/mqttPacket/mod.ts +1 -1
- package/mqttPacket/pubblishAcks.ts +16 -11
- package/mqttPacket/publish.ts +9 -9
- package/package.json +3 -3
- package/persistence/memory/memoryPersistence.ts +4 -3
- package/persistence/mod.ts +6 -1
- package/persistence/store.ts +3 -2
- package/server/context.ts +1 -1
- package/server/handlers/handlePublish.ts +1 -1
- package/server/test/handleConnect.test.ts +13 -21
- package/socket/socket.ts +3 -0
- package/trie/trie.ts +29 -19
- package/utils/BufferedAsyncIterable.ts +1 -1
package/dist/trie/trie.js
CHANGED
|
@@ -36,7 +36,7 @@ export class Trie {
|
|
|
36
36
|
*/
|
|
37
37
|
match(key) {
|
|
38
38
|
const parts = key.split(this.separator);
|
|
39
|
-
if (parts.length > 0 && parts[0]
|
|
39
|
+
if (parts.length > 0 && parts[0]?.charAt(0) === this.reservedPrefix) {
|
|
40
40
|
return this._matchPrefix(parts);
|
|
41
41
|
}
|
|
42
42
|
return this._match(parts);
|
|
@@ -51,7 +51,10 @@ export class Trie {
|
|
|
51
51
|
return this.#value ? this.#value : [];
|
|
52
52
|
}
|
|
53
53
|
const [first, ...rest] = parts;
|
|
54
|
-
|
|
54
|
+
if (first !== undefined) {
|
|
55
|
+
return this.matchChild(first, rest);
|
|
56
|
+
}
|
|
57
|
+
return [];
|
|
55
58
|
}
|
|
56
59
|
/**
|
|
57
60
|
* Internal method to match keys with wildcard support
|
|
@@ -63,11 +66,14 @@ export class Trie {
|
|
|
63
66
|
return this.#value ? this.#value : [];
|
|
64
67
|
}
|
|
65
68
|
const [first, ...rest] = parts;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
if (first !== undefined) {
|
|
70
|
+
const exact = this.matchChild(first, rest);
|
|
71
|
+
const single = this.matchChild(this.wildcardOne, rest);
|
|
72
|
+
const subtree = this.matchChild(this.wildcardSubtree, []);
|
|
73
|
+
const results = exact.concat(single, subtree);
|
|
74
|
+
return results;
|
|
75
|
+
}
|
|
76
|
+
return [];
|
|
71
77
|
}
|
|
72
78
|
/**
|
|
73
79
|
* Adds a value to the trie at the specified key
|
|
@@ -88,14 +94,16 @@ export class Trie {
|
|
|
88
94
|
return;
|
|
89
95
|
}
|
|
90
96
|
const [first, ...rest] = parts;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
child
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
if (first !== undefined) {
|
|
98
|
+
const child = this.#children.get(first);
|
|
99
|
+
if (child instanceof Trie) {
|
|
100
|
+
child._add(rest, value);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const node = new Trie(this.looseCompare);
|
|
104
|
+
this.#children.set(first, node);
|
|
105
|
+
node._add(rest, value);
|
|
106
|
+
}
|
|
99
107
|
}
|
|
100
108
|
return;
|
|
101
109
|
}
|
|
@@ -119,11 +127,13 @@ export class Trie {
|
|
|
119
127
|
return;
|
|
120
128
|
}
|
|
121
129
|
const [first, ...rest] = parts;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
node
|
|
125
|
-
|
|
126
|
-
this.#children.
|
|
130
|
+
if (first !== undefined) {
|
|
131
|
+
const node = this.#children.get(first);
|
|
132
|
+
if (node) {
|
|
133
|
+
node._remove(rest, value);
|
|
134
|
+
if (node.#value.length === 0 && this.#children.size === 0) {
|
|
135
|
+
this.#children.delete(first);
|
|
136
|
+
}
|
|
127
137
|
}
|
|
128
138
|
}
|
|
129
139
|
}
|
package/dist/trie/trie.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trie.js","sourceRoot":"","sources":["../../trie/trie.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,OAAO,IAAI;IACf,MAAM,CAAW;IACjB,SAAS,CAAuB;IACxB,SAAS,GAAG,GAAG,CAAC;IAChB,WAAW,GAAG,GAAG,CAAC;IAClB,eAAe,GAAG,GAAG,CAAC;IACtB,cAAc,GAAG,GAAG,CAAC;IACrB,YAAY,CAAU;IAE9B;;;OAGG;IACH,YAAY,YAAY,GAAG,KAAK;QAC9B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,KAAa,EAAE,KAAY;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC5C,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,GAAW;QACf,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"trie.js","sourceRoot":"","sources":["../../trie/trie.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,OAAO,IAAI;IACf,MAAM,CAAW;IACjB,SAAS,CAAuB;IACxB,SAAS,GAAG,GAAG,CAAC;IAChB,WAAW,GAAG,GAAG,CAAC;IAClB,eAAe,GAAG,GAAG,CAAC;IACtB,cAAc,GAAG,GAAG,CAAC;IACrB,YAAY,CAAU;IAE9B;;;OAGG;IACH,YAAY,YAAY,GAAG,KAAK;QAC9B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,KAAa,EAAE,KAAY;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC5C,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,GAAW;QACf,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC;YACpE,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACK,YAAY,CAAC,KAAY;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,KAAY;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YACvD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,GAAW,EAAE,KAAQ;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACK,IAAI,CAAC,KAAY,EAAE,KAAQ;QACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACxC,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,IAAI,IAAI,CAAI,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC5C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAChC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QACD,OAAO;IACT,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,GAAW,EAAE,KAAQ;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IAED;;;;OAIG;IACK,OAAO,CAAC,KAAY,EAAE,KAAQ;QACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;oBAC1D,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,KAAQ;QACrB,IAAI,IAAI,CAAC,YAAY,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnD,OAAO,CAAC,IAAI,EAAE,EAAE;gBACd,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;oBACxB,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC7B,OAAO,IAAI,CAAC;oBACd,CAAC;gBACH,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BufferedAsyncIterable.js","sourceRoot":"","sources":["../../utils/BufferedAsyncIterable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,qBAAqB;IACxB,MAAM,CAAgB;IACtB,UAAU,CAAS;IAEnB,IAAI,GAAG,KAAK,CAAC;IAErB,KAAK,
|
|
1
|
+
{"version":3,"file":"BufferedAsyncIterable.js","sourceRoot":"","sources":["../../utils/BufferedAsyncIterable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,qBAAqB;IACxB,MAAM,CAAgB;IACtB,UAAU,CAAS;IAEnB,IAAI,GAAG,KAAK,CAAC;IAErB,KAAK,CAA2B;IAEhC,YAAY,aAAqB,IAAI;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,IAAI;QACF,oBAAoB;QACpB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAG,CAAC;QAChC,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,EAAK,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,MAAM,GAAG,QAAQ;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEQ,IAAI,GAAG,CAAC,IAAO,EAAwB,EAAE;QAChD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YACvB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACzC,8EAA8E;YAC9E,6EAA6E;YAC7E,6EAA6E;YAC7E,2EAA2E;YAC3E,+EAA+E;YAC/E,oCAAoC;YACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/mqttConn/mqttConn.ts
CHANGED
|
@@ -57,8 +57,9 @@ async function readByte(conn: Conn): Promise<number> {
|
|
|
57
57
|
const buf = new Uint8Array(1);
|
|
58
58
|
const bytesRead = await conn.read(buf);
|
|
59
59
|
assert(bytesRead !== null, MqttConnError.UnexpectedEof);
|
|
60
|
+
assert(bytesRead !== undefined, MqttConnError.UnexpectedEof);
|
|
60
61
|
assert(bytesRead !== 0, MqttConnError.UnexpectedEof);
|
|
61
|
-
return buf[0];
|
|
62
|
+
return buf[0] || 0;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
/**
|
|
@@ -170,9 +171,11 @@ export class MqttConn implements IMqttConn {
|
|
|
170
171
|
* @returns a Promise that resolves to AnyPacket if the connection is open
|
|
171
172
|
* and working nominally, undefined otherwise.
|
|
172
173
|
*/
|
|
173
|
-
#receive(): Promise<AnyPacket | undefined> {
|
|
174
|
+
async #receive(): Promise<AnyPacket | undefined> {
|
|
174
175
|
if (!this._isClosed) {
|
|
175
|
-
|
|
176
|
+
try {
|
|
177
|
+
return await readPacket(this.conn, this.codecOpts);
|
|
178
|
+
} catch (err) {
|
|
176
179
|
if (err instanceof Error) {
|
|
177
180
|
if (err.name === "PartialReadError") {
|
|
178
181
|
err.message = MqttConnError.UnexpectedEof;
|
|
@@ -182,16 +185,23 @@ export class MqttConn implements IMqttConn {
|
|
|
182
185
|
// packet too large, malformed packet or connection closed.
|
|
183
186
|
this.close();
|
|
184
187
|
return undefined;
|
|
185
|
-
}
|
|
188
|
+
}
|
|
186
189
|
}
|
|
187
190
|
return Promise.resolve(undefined);
|
|
188
191
|
}
|
|
189
192
|
|
|
190
|
-
async
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
193
|
+
async next(): Promise<IteratorResult<AnyPacket>> {
|
|
194
|
+
const packet = await this.#receive();
|
|
195
|
+
|
|
196
|
+
if (packet !== undefined) {
|
|
197
|
+
return { value: packet, done: false };
|
|
194
198
|
}
|
|
199
|
+
|
|
200
|
+
return { value: undefined, done: true };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
[Symbol.asyncIterator](): this {
|
|
204
|
+
return this;
|
|
195
205
|
}
|
|
196
206
|
|
|
197
207
|
/**
|
package/mqttPacket/BitMask.ts
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Object containing bit mask values from 2^0 to 2^7
|
|
3
|
-
* @
|
|
4
|
-
* @
|
|
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
|
|
3
|
+
* @readonly
|
|
4
|
+
* @enum {number}
|
|
13
5
|
*/
|
|
14
|
-
export const BitMask
|
|
15
|
-
bit0: 2 ** 0,
|
|
16
|
-
bit1: 2 ** 1,
|
|
17
|
-
bit2: 2 ** 2,
|
|
18
|
-
bit3: 2 ** 3,
|
|
19
|
-
bit4: 2 ** 4,
|
|
20
|
-
bit5: 2 ** 5,
|
|
21
|
-
bit6: 2 ** 6,
|
|
22
|
-
bit7: 2 ** 7,
|
|
6
|
+
export const BitMask = {
|
|
7
|
+
bit0: 2 ** 0, // 1
|
|
8
|
+
bit1: 2 ** 1, // 2
|
|
9
|
+
bit2: 2 ** 2, // 4
|
|
10
|
+
bit3: 2 ** 3, // 8
|
|
11
|
+
bit4: 2 ** 4, // 16
|
|
12
|
+
bit5: 2 ** 5, // 32
|
|
13
|
+
bit6: 2 ** 6, // 64
|
|
14
|
+
bit7: 2 ** 7, // 128
|
|
23
15
|
} as const;
|
package/mqttPacket/connect.ts
CHANGED
|
@@ -22,40 +22,40 @@ import {
|
|
|
22
22
|
|
|
23
23
|
export type ConnectPacketV4 = {
|
|
24
24
|
type: TPacketType;
|
|
25
|
-
protocolName?: string;
|
|
25
|
+
protocolName?: string | undefined;
|
|
26
26
|
protocolLevel: ProtocolLevelNoV5;
|
|
27
|
-
clientId?: ClientId;
|
|
28
|
-
username?: string;
|
|
29
|
-
password?: Uint8Array;
|
|
27
|
+
clientId?: ClientId | undefined;
|
|
28
|
+
username?: string | undefined;
|
|
29
|
+
password?: Uint8Array | undefined;
|
|
30
30
|
will?: {
|
|
31
31
|
topic: Topic;
|
|
32
32
|
payload: Payload;
|
|
33
|
-
retain?: boolean;
|
|
34
|
-
qos?: QoS;
|
|
35
|
-
};
|
|
36
|
-
clean?: boolean;
|
|
37
|
-
keepAlive?: number;
|
|
38
|
-
bridgeMode?: boolean;
|
|
33
|
+
retain?: boolean | undefined;
|
|
34
|
+
qos?: QoS | undefined;
|
|
35
|
+
} | undefined;
|
|
36
|
+
clean?: boolean | undefined;
|
|
37
|
+
keepAlive?: number | undefined;
|
|
38
|
+
bridgeMode?: boolean | undefined;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export type ConnectPacketV5 = {
|
|
42
42
|
type: TPacketType;
|
|
43
|
-
protocolName?: string;
|
|
43
|
+
protocolName?: string | undefined;
|
|
44
44
|
protocolLevel: 5;
|
|
45
|
-
clientId?: ClientId;
|
|
46
|
-
username?: string;
|
|
47
|
-
password?: Uint8Array;
|
|
45
|
+
clientId?: ClientId | undefined;
|
|
46
|
+
username?: string | undefined;
|
|
47
|
+
password?: Uint8Array | undefined;
|
|
48
48
|
will?: {
|
|
49
49
|
topic: Topic;
|
|
50
50
|
payload: Payload;
|
|
51
|
-
retain?: boolean;
|
|
52
|
-
qos?: QoS;
|
|
53
|
-
properties?: WillProperties;
|
|
54
|
-
};
|
|
55
|
-
clean?: boolean;
|
|
56
|
-
keepAlive?: number;
|
|
57
|
-
bridgeMode?: boolean;
|
|
58
|
-
properties?: ConnectProperties;
|
|
51
|
+
retain?: boolean | undefined;
|
|
52
|
+
qos?: QoS | undefined;
|
|
53
|
+
properties?: WillProperties | undefined;
|
|
54
|
+
} | undefined;
|
|
55
|
+
clean?: boolean | undefined;
|
|
56
|
+
keepAlive?: number | undefined;
|
|
57
|
+
bridgeMode?: boolean | undefined;
|
|
58
|
+
properties?: ConnectProperties | undefined;
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
/**
|
package/mqttPacket/decoder.ts
CHANGED
package/mqttPacket/length.ts
CHANGED
|
@@ -35,7 +35,7 @@ export function decodeLength(
|
|
|
35
35
|
const decode = getLengthDecoder();
|
|
36
36
|
const size = buf.length;
|
|
37
37
|
for (let i = start; i < size; i++) {
|
|
38
|
-
const byte = buf[i];
|
|
38
|
+
const byte = buf[i] || 0;
|
|
39
39
|
const { done, length, numLengthBytes } = decode(byte);
|
|
40
40
|
if (done) {
|
|
41
41
|
return { length, numLengthBytes };
|
package/mqttPacket/mod.ts
CHANGED
|
@@ -225,7 +225,7 @@ export function decode(
|
|
|
225
225
|
const { length, numLengthBytes } = decodeLength(buffer, 1);
|
|
226
226
|
const start = numLengthBytes + 1;
|
|
227
227
|
const end = start + length;
|
|
228
|
-
return decodePayload(buffer[0], buffer.subarray(start, end), codecOpts);
|
|
228
|
+
return decodePayload(buffer[0] || 0, buffer.subarray(start, end), codecOpts);
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
export { getLengthDecoder } from "../mqttPacket/length.ts";
|
|
@@ -10,35 +10,40 @@ import { PacketType } from "./PacketType.ts";
|
|
|
10
10
|
import { Decoder, DecoderError } from "./decoder.ts";
|
|
11
11
|
import { Encoder } from "./encoder.ts";
|
|
12
12
|
|
|
13
|
-
export type AckPacketV4<T> = {
|
|
14
|
-
type:
|
|
13
|
+
export type AckPacketV4<T extends TPacketType> = {
|
|
14
|
+
type: T;
|
|
15
15
|
protocolLevel: ProtocolLevelNoV5;
|
|
16
16
|
id: PacketId;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export type AckPacketV5<T> = {
|
|
20
|
-
type:
|
|
19
|
+
export type AckPacketV5<T extends TPacketType> = {
|
|
20
|
+
type: T;
|
|
21
21
|
protocolLevel: 5;
|
|
22
22
|
id: PacketId;
|
|
23
23
|
reasonCode?: TReasonCode;
|
|
24
24
|
properties?: PubackProperties;
|
|
25
25
|
};
|
|
26
|
+
|
|
26
27
|
/**
|
|
27
28
|
* all 4 ack packets are identical except for packet type and flags of Pubrel
|
|
28
29
|
*/
|
|
29
|
-
export type AckPacket<T> = AckPacketV4<T> | AckPacketV5<T>;
|
|
30
|
+
export type AckPacket<T extends TPacketType> = AckPacketV4<T> | AckPacketV5<T>;
|
|
31
|
+
|
|
30
32
|
/**
|
|
31
33
|
* PubackPacket is sent to indicate publish complete (QoS 1)
|
|
32
34
|
*/
|
|
33
35
|
export type PubackPacket = AckPacket<typeof PacketType.puback>;
|
|
36
|
+
|
|
34
37
|
/**
|
|
35
38
|
* Pubrec is sent to indicate publish received (QoS 2)
|
|
36
39
|
*/
|
|
37
40
|
export type PubrecPacket = AckPacket<typeof PacketType.pubrec>;
|
|
41
|
+
|
|
38
42
|
/**
|
|
39
43
|
* Pubrel is sent to indicate publish release (QoS 2)
|
|
40
44
|
*/
|
|
41
45
|
export type PubrelPacket = AckPacket<typeof PacketType.pubrel>;
|
|
46
|
+
|
|
42
47
|
/**
|
|
43
48
|
* Pubcomp is sent to indicate publish complete (QoS 2)
|
|
44
49
|
*/
|
|
@@ -97,27 +102,27 @@ export const anyAck: {
|
|
|
97
102
|
if (codecOpts.protocolLevel !== 5) {
|
|
98
103
|
decoder.done();
|
|
99
104
|
return {
|
|
100
|
-
type: packetType,
|
|
105
|
+
type: packetType as AnyAckPacket["type"],
|
|
101
106
|
protocolLevel: codecOpts.protocolLevel,
|
|
102
107
|
id,
|
|
103
|
-
};
|
|
108
|
+
} as AnyAckPacket;
|
|
104
109
|
}
|
|
105
110
|
if (decoder.atEnd()) {
|
|
106
111
|
return {
|
|
107
|
-
type: packetType,
|
|
112
|
+
type: packetType as AnyAckPacket["type"],
|
|
108
113
|
protocolLevel: 5,
|
|
109
114
|
id,
|
|
110
115
|
reasonCode: 0,
|
|
111
|
-
};
|
|
116
|
+
} as AnyAckPacket;
|
|
112
117
|
}
|
|
113
118
|
const reasonCode = decoder.getReasonCode();
|
|
114
119
|
const properties = decoder.getProperties(packetType);
|
|
115
120
|
return {
|
|
116
|
-
type: packetType,
|
|
121
|
+
type: packetType as AnyAckPacket["type"],
|
|
117
122
|
protocolLevel: 5,
|
|
118
123
|
id,
|
|
119
124
|
reasonCode,
|
|
120
125
|
properties,
|
|
121
|
-
};
|
|
126
|
+
} as AnyAckPacket;
|
|
122
127
|
},
|
|
123
128
|
};
|
package/mqttPacket/publish.ts
CHANGED
|
@@ -22,21 +22,21 @@ export type PublishPacketV4 = {
|
|
|
22
22
|
protocolLevel: ProtocolLevelNoV5;
|
|
23
23
|
topic: Topic;
|
|
24
24
|
payload: Payload;
|
|
25
|
-
dup?: Dup;
|
|
26
|
-
retain?: boolean;
|
|
27
|
-
qos?: QoS;
|
|
28
|
-
id?: number;
|
|
25
|
+
dup?: Dup | undefined;
|
|
26
|
+
retain?: boolean | undefined;
|
|
27
|
+
qos?: QoS | undefined;
|
|
28
|
+
id?: number | undefined;
|
|
29
29
|
};
|
|
30
30
|
export type PublishPacketV5 = {
|
|
31
31
|
type: TPacketType;
|
|
32
32
|
protocolLevel: 5;
|
|
33
33
|
topic: Topic;
|
|
34
34
|
payload: Payload;
|
|
35
|
-
dup?: Dup;
|
|
36
|
-
retain?: boolean;
|
|
37
|
-
qos?: QoS;
|
|
38
|
-
id?: number;
|
|
39
|
-
properties?: PublishProperties;
|
|
35
|
+
dup?: Dup | undefined;
|
|
36
|
+
retain?: boolean | undefined;
|
|
37
|
+
qos?: QoS | undefined;
|
|
38
|
+
id?: number | undefined;
|
|
39
|
+
properties?: PublishProperties | undefined;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
export type PublishPacket = PublishPacketV4 | PublishPacketV5;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seriousme/opifex",
|
|
3
|
-
"version": "1.11.
|
|
4
|
-
"description": "MQTT client & server for Deno & NodeJS",
|
|
3
|
+
"version": "1.11.3",
|
|
4
|
+
"description": "MQTT client & server for Deno & NodeJS and Bun",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "node --experimental-strip-types --test --test-skip-pattern='/^Deno/'",
|
|
@@ -68,6 +68,6 @@
|
|
|
68
68
|
},
|
|
69
69
|
"homepage": "https://github.com/seriousme/opifex#readme",
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@types/node": "^24.
|
|
71
|
+
"@types/node": "^24.12.4"
|
|
72
72
|
}
|
|
73
73
|
}
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
IPersistence,
|
|
6
6
|
IStore,
|
|
7
7
|
PacketId,
|
|
8
|
+
PacketIdStore,
|
|
8
9
|
PacketStore,
|
|
9
10
|
PublishPacket,
|
|
10
11
|
QoS,
|
|
@@ -28,14 +29,14 @@ export class MemoryStore implements IStore {
|
|
|
28
29
|
existingSession: boolean = false;
|
|
29
30
|
clientId: ClientId;
|
|
30
31
|
private packetId: PacketId;
|
|
31
|
-
pendingIncoming:
|
|
32
|
+
pendingIncoming: PacketIdStore;
|
|
32
33
|
pendingOutgoing: PacketStore;
|
|
33
|
-
pendingAckOutgoing:
|
|
34
|
+
pendingAckOutgoing: PacketIdStore;
|
|
34
35
|
subscriptions: SubscriptionStore;
|
|
35
36
|
|
|
36
37
|
constructor(clientId: ClientId) {
|
|
37
38
|
this.packetId = 0;
|
|
38
|
-
this.pendingIncoming = new
|
|
39
|
+
this.pendingIncoming = new Set();
|
|
39
40
|
this.pendingOutgoing = new Map();
|
|
40
41
|
this.pendingAckOutgoing = new Set();
|
|
41
42
|
this.subscriptions = new Map();
|
package/persistence/mod.ts
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* @module persistence
|
|
3
3
|
* @description Module for handling MQTT message persistence and client management
|
|
4
4
|
*/
|
|
5
|
-
export type {
|
|
5
|
+
export type {
|
|
6
|
+
IStore,
|
|
7
|
+
PacketIdStore,
|
|
8
|
+
PacketStore,
|
|
9
|
+
SubscriptionStore,
|
|
10
|
+
} from "./store.ts";
|
|
6
11
|
export type {
|
|
7
12
|
ClientId,
|
|
8
13
|
PacketId,
|
package/persistence/store.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { ClientId, PacketId, PublishPacket, QoS, Topic } from "./deps.ts";
|
|
2
2
|
|
|
3
3
|
export type PacketStore = Map<PacketId, PublishPacket>;
|
|
4
|
+
export type PacketIdStore = Set<PacketId>;
|
|
4
5
|
|
|
5
6
|
export type SubscriptionStore = Map<Topic, QoS>;
|
|
6
7
|
|
|
7
8
|
export interface IStore {
|
|
8
9
|
existingSession: boolean;
|
|
9
10
|
clientId: ClientId;
|
|
10
|
-
pendingIncoming:
|
|
11
|
+
pendingIncoming: PacketIdStore;
|
|
11
12
|
pendingOutgoing: PacketStore;
|
|
12
|
-
pendingAckOutgoing:
|
|
13
|
+
pendingAckOutgoing: PacketIdStore;
|
|
13
14
|
subscriptions: SubscriptionStore;
|
|
14
15
|
nextId(): PacketId;
|
|
15
16
|
}
|
package/server/context.ts
CHANGED
|
@@ -60,7 +60,7 @@ export class Context {
|
|
|
60
60
|
handlers: Handlers;
|
|
61
61
|
static clientList: Map<ClientId, Context> = new Map();
|
|
62
62
|
store?: IStore;
|
|
63
|
-
will?: PublishPacket;
|
|
63
|
+
will?: PublishPacket | undefined;
|
|
64
64
|
timer?: Timer;
|
|
65
65
|
|
|
66
66
|
constructor(persistence: IPersistence, conn: SockConn, handlers: Handlers) {
|
|
@@ -68,8 +68,8 @@ Identifier as being a new publication.
|
|
|
68
68
|
*/
|
|
69
69
|
if (ctx.store) {
|
|
70
70
|
if (!ctx.store.pendingIncoming.has(packet.id)) {
|
|
71
|
-
ctx.store.pendingIncoming.set(packet.id, packet);
|
|
72
71
|
ctx.persistence.publish(packet.topic, packet);
|
|
72
|
+
ctx.store.pendingIncoming.add(packet.id);
|
|
73
73
|
}
|
|
74
74
|
await ctx.send({
|
|
75
75
|
type: PacketType.pubrec,
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { test } from "node:test";
|
|
3
|
-
import {
|
|
4
|
-
makeDummyQueueSockConn,
|
|
5
|
-
resolveNextTick,
|
|
6
|
-
} from "../../dev_utils/mod.ts";
|
|
3
|
+
import { createWebSocketPair, resolveNextTick } from "../../dev_utils/mod.ts";
|
|
7
4
|
import {
|
|
8
5
|
type AnyPacket,
|
|
9
6
|
AuthenticationResult,
|
|
10
7
|
PacketType,
|
|
11
8
|
} from "../../mqttPacket/mod.ts";
|
|
12
|
-
import { BufferedAsyncIterable } from "../../utils/mod.ts";
|
|
13
9
|
import { MqttConn, MQTTLevel } from "../deps.ts";
|
|
14
10
|
import { MqttServer } from "../mod.ts";
|
|
15
11
|
import { handlers } from "./test-handlers.ts";
|
|
@@ -37,25 +33,21 @@ const disconnectPacket: AnyPacket = {
|
|
|
37
33
|
const mqttServer = new MqttServer({ handlers });
|
|
38
34
|
|
|
39
35
|
function startServer(): {
|
|
40
|
-
reader: AsyncIterator<AnyPacket>;
|
|
41
36
|
mqttConn: MqttConn;
|
|
42
37
|
} {
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const outputConn = makeDummyQueueSockConn(writer, reader);
|
|
47
|
-
const mqttConn = new MqttConn({ conn: outputConn });
|
|
48
|
-
const inputConn = makeDummyQueueSockConn(reader, writer, () => {
|
|
38
|
+
const { input, output } = createWebSocketPair();
|
|
39
|
+
const mqttConn = new MqttConn({ conn: output });
|
|
40
|
+
input.close = () => {
|
|
49
41
|
mqttConn.close();
|
|
50
|
-
}
|
|
51
|
-
mqttServer.serve(
|
|
52
|
-
return {
|
|
42
|
+
};
|
|
43
|
+
mqttServer.serve(input);
|
|
44
|
+
return { mqttConn };
|
|
53
45
|
}
|
|
54
46
|
|
|
55
47
|
test("Authentication with valid username and password works", async () => {
|
|
56
|
-
const {
|
|
48
|
+
const { mqttConn } = startServer();
|
|
57
49
|
mqttConn.send(connectPacket);
|
|
58
|
-
const { value: connack } = await
|
|
50
|
+
const { value: connack } = await mqttConn.next();
|
|
59
51
|
assert.deepStrictEqual(
|
|
60
52
|
connack.type,
|
|
61
53
|
PacketType.connack,
|
|
@@ -80,9 +72,9 @@ test("Authentication with valid username and password works", async () => {
|
|
|
80
72
|
test("Authentication with invalid username fails", async () => {
|
|
81
73
|
const newPacket = Object.assign({}, connectPacket);
|
|
82
74
|
newPacket.username = "wrong";
|
|
83
|
-
const {
|
|
75
|
+
const { mqttConn } = startServer();
|
|
84
76
|
mqttConn.send(newPacket);
|
|
85
|
-
const { value: connack } = await
|
|
77
|
+
const { value: connack } = await mqttConn.next();
|
|
86
78
|
assert.deepStrictEqual(
|
|
87
79
|
connack.type,
|
|
88
80
|
PacketType.connack,
|
|
@@ -106,9 +98,9 @@ test("Authentication with invalid username fails", async () => {
|
|
|
106
98
|
test("Authentication with invalid password fails", async () => {
|
|
107
99
|
const newPacket = Object.assign({}, connectPacket);
|
|
108
100
|
newPacket.password = undefined;
|
|
109
|
-
const {
|
|
101
|
+
const { mqttConn } = startServer();
|
|
110
102
|
mqttConn.send(newPacket);
|
|
111
|
-
const { value: connack } = await
|
|
103
|
+
const { value: connack } = await mqttConn.next();
|
|
112
104
|
assert.deepStrictEqual(
|
|
113
105
|
connack.type,
|
|
114
106
|
PacketType.connack,
|