@seriousme/opifex 1.9.3 → 1.10.1

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.
Files changed (304) hide show
  1. package/README.md +37 -26
  2. package/bin/conformanceServer.ts +3 -2
  3. package/bin/demoServer.ts +3 -2
  4. package/bin/mqtt.ts +126 -117
  5. package/client/client.ts +35 -15
  6. package/client/context.ts +42 -22
  7. package/client/deps.ts +5 -0
  8. package/client/handlers/handleConnack.ts +17 -5
  9. package/client/handlers/handlePublish.ts +4 -1
  10. package/client/handlers/handlePubrec.ts +3 -1
  11. package/client/handlers/handlePubrel.ts +3 -1
  12. package/client/handlers/handleSuback.ts +3 -1
  13. package/client/mod.ts +8 -1
  14. package/client/store/memoryStore.ts +2 -1
  15. package/dev_utils/dummyConn.ts +17 -2
  16. package/dist/bin/conformanceServer.js +3 -2
  17. package/dist/bin/conformanceServer.js.map +1 -1
  18. package/dist/bin/demoServer.js +3 -2
  19. package/dist/bin/demoServer.js.map +1 -1
  20. package/dist/bin/mqtt.d.ts +29 -0
  21. package/dist/bin/mqtt.d.ts.map +1 -1
  22. package/dist/bin/mqtt.js +101 -96
  23. package/dist/bin/mqtt.js.map +1 -1
  24. package/dist/client/client.d.ts +7 -4
  25. package/dist/client/client.d.ts.map +1 -1
  26. package/dist/client/client.js +17 -9
  27. package/dist/client/client.js.map +1 -1
  28. package/dist/client/context.d.ts +3 -1
  29. package/dist/client/context.d.ts.map +1 -1
  30. package/dist/client/context.js +27 -13
  31. package/dist/client/context.js.map +1 -1
  32. package/dist/client/deps.d.ts +3 -2
  33. package/dist/client/deps.d.ts.map +1 -1
  34. package/dist/client/deps.js +2 -1
  35. package/dist/client/deps.js.map +1 -1
  36. package/dist/client/handlers/handleConnack.d.ts +1 -1
  37. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  38. package/dist/client/handlers/handleConnack.js +14 -5
  39. package/dist/client/handlers/handleConnack.js.map +1 -1
  40. package/dist/client/handlers/handlePublish.d.ts +1 -1
  41. package/dist/client/handlers/handlePublish.d.ts.map +1 -1
  42. package/dist/client/handlers/handlePublish.js +2 -0
  43. package/dist/client/handlers/handlePublish.js.map +1 -1
  44. package/dist/client/handlers/handlePubrec.d.ts +1 -1
  45. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  46. package/dist/client/handlers/handlePubrec.js +1 -0
  47. package/dist/client/handlers/handlePubrec.js.map +1 -1
  48. package/dist/client/handlers/handlePubrel.d.ts +1 -1
  49. package/dist/client/handlers/handlePubrel.d.ts.map +1 -1
  50. package/dist/client/handlers/handlePubrel.js +1 -0
  51. package/dist/client/handlers/handlePubrel.js.map +1 -1
  52. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  53. package/dist/client/handlers/handleSuback.js +3 -1
  54. package/dist/client/handlers/handleSuback.js.map +1 -1
  55. package/dist/client/mod.d.ts +3 -1
  56. package/dist/client/mod.d.ts.map +1 -1
  57. package/dist/client/mod.js +2 -1
  58. package/dist/client/mod.js.map +1 -1
  59. package/dist/client/store/memoryStore.d.ts +1 -1
  60. package/dist/client/store/memoryStore.d.ts.map +1 -1
  61. package/dist/client/store/memoryStore.js.map +1 -1
  62. package/dist/mqttConn/mqttConn.d.ts +13 -8
  63. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  64. package/dist/mqttConn/mqttConn.js +27 -12
  65. package/dist/mqttConn/mqttConn.js.map +1 -1
  66. package/dist/mqttPacket/PacketType.d.ts +1 -0
  67. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  68. package/dist/mqttPacket/PacketType.js +1 -0
  69. package/dist/mqttPacket/PacketType.js.map +1 -1
  70. package/dist/mqttPacket/Properties.d.ts +157 -0
  71. package/dist/mqttPacket/Properties.d.ts.map +1 -0
  72. package/dist/mqttPacket/Properties.js +177 -0
  73. package/dist/mqttPacket/Properties.js.map +1 -0
  74. package/dist/mqttPacket/ReasonCode.d.ts +74 -0
  75. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -0
  76. package/dist/mqttPacket/ReasonCode.js +230 -0
  77. package/dist/mqttPacket/ReasonCode.js.map +1 -0
  78. package/dist/mqttPacket/RetainHandling.d.ts +12 -0
  79. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -0
  80. package/dist/mqttPacket/RetainHandling.js +12 -0
  81. package/dist/mqttPacket/RetainHandling.js.map +1 -0
  82. package/dist/mqttPacket/auth.d.ts +21 -0
  83. package/dist/mqttPacket/auth.d.ts.map +1 -0
  84. package/dist/mqttPacket/auth.js +34 -0
  85. package/dist/mqttPacket/auth.js.map +1 -0
  86. package/dist/mqttPacket/connack.d.ts +15 -7
  87. package/dist/mqttPacket/connack.d.ts.map +1 -1
  88. package/dist/mqttPacket/connack.js +43 -15
  89. package/dist/mqttPacket/connack.js.map +1 -1
  90. package/dist/mqttPacket/connect.d.ts +27 -8
  91. package/dist/mqttPacket/connect.d.ts.map +1 -1
  92. package/dist/mqttPacket/connect.js +106 -30
  93. package/dist/mqttPacket/connect.js.map +1 -1
  94. package/dist/mqttPacket/decoder.d.ts +42 -3
  95. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  96. package/dist/mqttPacket/decoder.js +135 -4
  97. package/dist/mqttPacket/decoder.js.map +1 -1
  98. package/dist/mqttPacket/disconnect.d.ts +13 -7
  99. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  100. package/dist/mqttPacket/disconnect.js +45 -6
  101. package/dist/mqttPacket/disconnect.js.map +1 -1
  102. package/dist/mqttPacket/encoder.d.ts +57 -8
  103. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  104. package/dist/mqttPacket/encoder.js +185 -13
  105. package/dist/mqttPacket/encoder.js.map +1 -1
  106. package/dist/mqttPacket/length.d.ts.map +1 -1
  107. package/dist/mqttPacket/length.js +3 -2
  108. package/dist/mqttPacket/length.js.map +1 -1
  109. package/dist/mqttPacket/mod.d.ts +56 -91
  110. package/dist/mqttPacket/mod.d.ts.map +1 -1
  111. package/dist/mqttPacket/mod.js +22 -22
  112. package/dist/mqttPacket/mod.js.map +1 -1
  113. package/dist/mqttPacket/pingreq.d.ts +4 -6
  114. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  115. package/dist/mqttPacket/pingreq.js +5 -4
  116. package/dist/mqttPacket/pingreq.js.map +1 -1
  117. package/dist/mqttPacket/pingres.d.ts +4 -6
  118. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  119. package/dist/mqttPacket/pingres.js +7 -5
  120. package/dist/mqttPacket/pingres.js.map +1 -1
  121. package/dist/mqttPacket/protocolLevels.d.ts +11 -0
  122. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -0
  123. package/dist/mqttPacket/protocolLevels.js +11 -0
  124. package/dist/mqttPacket/protocolLevels.js.map +1 -0
  125. package/dist/mqttPacket/pubblishAcks.d.ts +35 -0
  126. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -0
  127. package/dist/mqttPacket/pubblishAcks.js +56 -0
  128. package/dist/mqttPacket/pubblishAcks.js.map +1 -0
  129. package/dist/mqttPacket/publish.d.ts +19 -8
  130. package/dist/mqttPacket/publish.d.ts.map +1 -1
  131. package/dist/mqttPacket/publish.js +26 -7
  132. package/dist/mqttPacket/publish.js.map +1 -1
  133. package/dist/mqttPacket/suback.d.ts +14 -7
  134. package/dist/mqttPacket/suback.d.ts.map +1 -1
  135. package/dist/mqttPacket/suback.js +41 -20
  136. package/dist/mqttPacket/suback.js.map +1 -1
  137. package/dist/mqttPacket/subscribe.d.ts +24 -9
  138. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  139. package/dist/mqttPacket/subscribe.js +71 -15
  140. package/dist/mqttPacket/subscribe.js.map +1 -1
  141. package/dist/mqttPacket/types.d.ts +33 -0
  142. package/dist/mqttPacket/types.d.ts.map +1 -1
  143. package/dist/mqttPacket/unsuback.d.ts +14 -7
  144. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  145. package/dist/mqttPacket/unsuback.js +29 -6
  146. package/dist/mqttPacket/unsuback.js.map +1 -1
  147. package/dist/mqttPacket/unsubscribe.d.ts +14 -7
  148. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  149. package/dist/mqttPacket/unsubscribe.js +24 -8
  150. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  151. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  152. package/dist/node/wrapNodeSocket.js.map +1 -1
  153. package/dist/persistence/deps.d.ts +1 -1
  154. package/dist/persistence/deps.d.ts.map +1 -1
  155. package/dist/persistence/deps.js +1 -1
  156. package/dist/persistence/deps.js.map +1 -1
  157. package/dist/server/context.d.ts +3 -1
  158. package/dist/server/context.d.ts.map +1 -1
  159. package/dist/server/context.js +8 -2
  160. package/dist/server/context.js.map +1 -1
  161. package/dist/server/deps.d.ts +2 -2
  162. package/dist/server/deps.d.ts.map +1 -1
  163. package/dist/server/deps.js +1 -1
  164. package/dist/server/deps.js.map +1 -1
  165. package/dist/server/handlers/handleConnect.d.ts +1 -1
  166. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  167. package/dist/server/handlers/handleConnect.js +9 -1
  168. package/dist/server/handlers/handleConnect.js.map +1 -1
  169. package/dist/server/handlers/handlePacket.d.ts +1 -1
  170. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  171. package/dist/server/handlers/handlePacket.js +1 -1
  172. package/dist/server/handlers/handlePacket.js.map +1 -1
  173. package/dist/server/handlers/handlePingreq.d.ts.map +1 -1
  174. package/dist/server/handlers/handlePingreq.js +1 -0
  175. package/dist/server/handlers/handlePingreq.js.map +1 -1
  176. package/dist/server/handlers/handlePublish.d.ts +2 -2
  177. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  178. package/dist/server/handlers/handlePublish.js +2 -0
  179. package/dist/server/handlers/handlePublish.js.map +1 -1
  180. package/dist/server/handlers/handlePubrec.d.ts +1 -1
  181. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  182. package/dist/server/handlers/handlePubrec.js +1 -0
  183. package/dist/server/handlers/handlePubrec.js.map +1 -1
  184. package/dist/server/handlers/handlePubrel.d.ts +1 -1
  185. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  186. package/dist/server/handlers/handlePubrel.js +1 -0
  187. package/dist/server/handlers/handlePubrel.js.map +1 -1
  188. package/dist/server/handlers/handleSubscribe.d.ts +1 -1
  189. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  190. package/dist/server/handlers/handleSubscribe.js +2 -1
  191. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  192. package/dist/server/handlers/handleUnsubscribe.d.ts +1 -1
  193. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  194. package/dist/server/handlers/handleUnsubscribe.js +1 -0
  195. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  196. package/dist/server/server.d.ts +2 -2
  197. package/dist/server/server.d.ts.map +1 -1
  198. package/dist/server/server.js +5 -3
  199. package/dist/server/server.js.map +1 -1
  200. package/dist/socket/socket.d.ts.map +1 -1
  201. package/dist/socket/socket.js +6 -1
  202. package/dist/socket/socket.js.map +1 -1
  203. package/dist/utils/assert.d.ts +0 -3
  204. package/dist/utils/assert.d.ts.map +1 -1
  205. package/dist/utils/assert.js +0 -7
  206. package/dist/utils/assert.js.map +1 -1
  207. package/dist/utils/mod.d.ts +0 -3
  208. package/dist/utils/mod.d.ts.map +1 -1
  209. package/dist/utils/mod.js +0 -2
  210. package/dist/utils/mod.js.map +1 -1
  211. package/mqttConn/mqttConn.test.ts +27 -12
  212. package/mqttConn/mqttConn.ts +45 -14
  213. package/mqttPacket/PacketType.ts +1 -0
  214. package/mqttPacket/Properties.ts +276 -0
  215. package/mqttPacket/ReasonCode.test.ts +22 -0
  216. package/mqttPacket/ReasonCode.ts +256 -0
  217. package/mqttPacket/RetainHandling.ts +11 -0
  218. package/mqttPacket/auth.test.ts +112 -0
  219. package/mqttPacket/auth.ts +72 -0
  220. package/mqttPacket/connack.test.ts +84 -64
  221. package/mqttPacket/connack.ts +84 -20
  222. package/mqttPacket/connect.test.ts +497 -18
  223. package/mqttPacket/connect.ts +167 -36
  224. package/mqttPacket/decoder.test.ts +33 -16
  225. package/mqttPacket/decoder.ts +173 -5
  226. package/mqttPacket/disconnect.test.ts +97 -18
  227. package/mqttPacket/disconnect.ts +82 -10
  228. package/mqttPacket/encoder.test.ts +32 -8
  229. package/mqttPacket/encoder.ts +236 -11
  230. package/mqttPacket/length.ts +3 -2
  231. package/mqttPacket/mod.ts +75 -32
  232. package/mqttPacket/pingreq.test.ts +52 -4
  233. package/mqttPacket/pingreq.ts +20 -7
  234. package/mqttPacket/pingres.test.ts +52 -4
  235. package/mqttPacket/pingres.ts +22 -8
  236. package/mqttPacket/properties.test.ts +193 -0
  237. package/mqttPacket/protocolLevels.ts +13 -0
  238. package/mqttPacket/pubblishAcks.ts +117 -0
  239. package/mqttPacket/publish.test.ts +212 -133
  240. package/mqttPacket/publish.ts +69 -14
  241. package/mqttPacket/publishAcks.test.ts +128 -0
  242. package/mqttPacket/suback.test.ts +71 -27
  243. package/mqttPacket/suback.ts +78 -26
  244. package/mqttPacket/subscribe.test.ts +132 -43
  245. package/mqttPacket/subscribe.ts +125 -22
  246. package/mqttPacket/types.ts +40 -0
  247. package/mqttPacket/unsuback.test.ts +80 -30
  248. package/mqttPacket/unsuback.ts +65 -10
  249. package/mqttPacket/unsubscribe.test.ts +59 -34
  250. package/mqttPacket/unsubscribe.ts +61 -14
  251. package/node/wrapNodeSocket.ts +2 -1
  252. package/package.json +2 -2
  253. package/persistence/deps.ts +1 -1
  254. package/persistence/memory/memoryPersistence.test.ts +5 -1
  255. package/server/context.ts +23 -10
  256. package/server/deps.ts +2 -0
  257. package/server/handlers/handleConnect.ts +12 -9
  258. package/server/handlers/handlePacket.ts +10 -11
  259. package/server/handlers/handlePingreq.ts +1 -0
  260. package/server/handlers/handlePublish.ts +6 -2
  261. package/server/handlers/handlePubrec.ts +3 -1
  262. package/server/handlers/handlePubrel.ts +3 -1
  263. package/server/handlers/handleSubscribe.ts +3 -6
  264. package/server/handlers/handleUnsubscribe.ts +3 -1
  265. package/server/server.ts +8 -12
  266. package/server/test/handleConnect.test.ts +2 -1
  267. package/server/test/test-handlers.ts +2 -1
  268. package/socket/socket.ts +5 -1
  269. package/utils/assert.ts +0 -18
  270. package/utils/mod.ts +0 -3
  271. package/dist/mqttPacket/puback.d.ts +0 -16
  272. package/dist/mqttPacket/puback.d.ts.map +0 -1
  273. package/dist/mqttPacket/puback.js +0 -21
  274. package/dist/mqttPacket/puback.js.map +0 -1
  275. package/dist/mqttPacket/pubcomp.d.ts +0 -17
  276. package/dist/mqttPacket/pubcomp.d.ts.map +0 -1
  277. package/dist/mqttPacket/pubcomp.js +0 -21
  278. package/dist/mqttPacket/pubcomp.js.map +0 -1
  279. package/dist/mqttPacket/pubrec.d.ts +0 -17
  280. package/dist/mqttPacket/pubrec.d.ts.map +0 -1
  281. package/dist/mqttPacket/pubrec.js +0 -21
  282. package/dist/mqttPacket/pubrec.js.map +0 -1
  283. package/dist/mqttPacket/pubrel.d.ts +0 -17
  284. package/dist/mqttPacket/pubrel.d.ts.map +0 -1
  285. package/dist/mqttPacket/pubrel.js +0 -21
  286. package/dist/mqttPacket/pubrel.js.map +0 -1
  287. package/dist/utils/args.d.ts +0 -28
  288. package/dist/utils/args.d.ts.map +0 -1
  289. package/dist/utils/args.js +0 -76
  290. package/dist/utils/args.js.map +0 -1
  291. package/dist/utils/platform.d.ts +0 -5
  292. package/dist/utils/platform.d.ts.map +0 -1
  293. package/dist/utils/platform.js +0 -8
  294. package/dist/utils/platform.js.map +0 -1
  295. package/mqttPacket/puback.test.ts +0 -55
  296. package/mqttPacket/puback.ts +0 -34
  297. package/mqttPacket/pubcomp.test.ts +0 -55
  298. package/mqttPacket/pubcomp.ts +0 -35
  299. package/mqttPacket/pubrec.test.ts +0 -55
  300. package/mqttPacket/pubrec.ts +0 -35
  301. package/mqttPacket/pubrel.test.ts +0 -55
  302. package/mqttPacket/pubrel.ts +0 -35
  303. package/utils/args.ts +0 -103
  304. package/utils/platform.ts +0 -8
@@ -1,53 +1,100 @@
1
- import type { PacketId, Topic, TopicFilter, TPacketType } from "./types.ts";
1
+ import type {
2
+ CodecOpts,
3
+ PacketId,
4
+ ProtocolLevelNoV5,
5
+ Topic,
6
+ TopicFilter,
7
+ TPacketType,
8
+ } from "./types.ts";
9
+ import type { UnsubscribeProperties } from "./Properties.ts";
2
10
  import { PacketType } from "./PacketType.ts";
3
- import { BitMask } from "./BitMask.ts";
4
11
  import { Encoder } from "./encoder.ts";
5
- import { booleanFlag, Decoder, DecoderError } from "./decoder.ts";
12
+ import { Decoder, DecoderError } from "./decoder.ts";
6
13
 
7
14
  /**
8
15
  * UnsubscribePacket is sent from client to server to unsubscribe from topics
9
16
  */
10
- export type UnsubscribePacket = {
17
+ export type UnsubscribePacketV4 = {
11
18
  type: TPacketType;
19
+ protocolLevel: ProtocolLevelNoV5;
12
20
  id: PacketId;
13
21
  topicFilters: TopicFilter[];
14
22
  };
15
23
 
24
+ export type UnsubscribePacketV5 = {
25
+ type: TPacketType;
26
+ protocolLevel: 5;
27
+ id: PacketId;
28
+ properties?: UnsubscribeProperties;
29
+ topicFilters: TopicFilter[];
30
+ };
31
+
32
+ export type UnsubscribePacket = UnsubscribePacketV4 | UnsubscribePacketV5;
33
+
16
34
  export const unsubscribe: {
17
- encode(packet: UnsubscribePacket): { flags: number; bytes: number[] };
18
- decode(buffer: Uint8Array, flags: number): UnsubscribePacket;
35
+ encode(packet: UnsubscribePacket, codecOpts: CodecOpts): Uint8Array;
36
+ decode(
37
+ buffer: Uint8Array,
38
+ flags: number,
39
+ codecOpts: CodecOpts,
40
+ packetType: TPacketType,
41
+ ): UnsubscribePacket;
19
42
  } = {
20
- encode(packet: UnsubscribePacket): { flags: number; bytes: number[] } {
43
+ encode(packet: UnsubscribePacket, codecOpts: CodecOpts): Uint8Array {
21
44
  // Bits 3,2,1 and 0 of the fixed header of the UNSUBSCRIBE Control Packet are reserved and
22
45
  // MUST be set to 0,0,1 and 0 respectively. The Server MUST treat any other value as
23
46
  // malformed and close the Network Connection [MQTT-3.10.1-1].
24
47
  const flags = 0b0010;
25
48
 
26
- const encoder = new Encoder();
49
+ const encoder = new Encoder(packet.type);
27
50
  encoder.setInt16(packet.id);
51
+ if (packet.protocolLevel === 5) {
52
+ encoder.setProperties(
53
+ packet.properties || {},
54
+ PacketType.unsubscribe,
55
+ codecOpts.maxOutgoingPacketSize,
56
+ );
57
+ }
28
58
  for (const topicFilter of packet.topicFilters) {
29
59
  encoder.setTopicFilter(topicFilter);
30
60
  }
31
- return { flags, bytes: encoder.done() };
61
+ return encoder.done(flags);
32
62
  },
33
63
 
34
- decode(buffer: Uint8Array, flags: number): UnsubscribePacket {
35
- if (!booleanFlag(flags, BitMask.bit1)) {
64
+ decode(
65
+ buffer: Uint8Array,
66
+ flags: number,
67
+ codecOpts: CodecOpts,
68
+ packetType: TPacketType,
69
+ ): UnsubscribePacket {
70
+ if (flags !== 0b0010) {
36
71
  throw new DecoderError("Invalid header");
37
72
  }
38
- const decoder = new Decoder(buffer);
73
+ const decoder = new Decoder(packetType, buffer);
39
74
  const id = decoder.getInt16();
40
-
75
+ let properties = {};
76
+ if (codecOpts.protocolLevel === 5) {
77
+ properties = decoder.getProperties(PacketType.unsubscribe);
78
+ }
41
79
  const topicFilters: Topic[] = [];
42
80
  do {
43
81
  const topicFilter = decoder.getTopicFilter();
44
82
  topicFilters.push(topicFilter);
45
83
  } while (!decoder.atEnd());
46
84
  decoder.done();
47
-
85
+ if (codecOpts.protocolLevel !== 5) {
86
+ return {
87
+ type: PacketType.unsubscribe,
88
+ protocolLevel: codecOpts.protocolLevel,
89
+ id,
90
+ topicFilters,
91
+ };
92
+ }
48
93
  return {
49
94
  type: PacketType.unsubscribe,
95
+ protocolLevel: 5,
50
96
  id,
97
+ properties,
51
98
  topicFilters,
52
99
  };
53
100
  },
@@ -4,6 +4,7 @@
4
4
  import type { Socket } from "node:net";
5
5
  import { Writable } from "node:stream";
6
6
  import type { NetAddr, SockConn } from "../socket/socket.ts";
7
+
7
8
  /**
8
9
  * Closes a Node.js socket if it is not already closed
9
10
  * @param sock - The Node.js socket to close
@@ -24,7 +25,7 @@ export function wrapNodeSocket(socket: Socket): SockConn {
24
25
  {
25
26
  type: "bytes",
26
27
  start(controller) {
27
- socket.on("data", (data: ArrayBufferView) => {
28
+ socket.on("data", (data: Uint8Array<ArrayBuffer>) => {
28
29
  controller.enqueue(data);
29
30
  const desiredSize = controller.desiredSize ?? 0;
30
31
  if (desiredSize <= 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seriousme/opifex",
3
- "version": "1.9.3",
3
+ "version": "1.10.1",
4
4
  "description": "MQTT client & server for Deno & NodeJS",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -68,6 +68,6 @@
68
68
  },
69
69
  "homepage": "https://github.com/seriousme/opifex#readme",
70
70
  "devDependencies": {
71
- "@types/node": "^22.13.1"
71
+ "@types/node": "^24.6.2"
72
72
  }
73
73
  }
@@ -7,6 +7,6 @@ export type {
7
7
  Topic,
8
8
  TopicFilter,
9
9
  } from "../mqttPacket/mod.ts";
10
- export { PacketType } from "../mqttPacket/mod.ts";
10
+ export { MQTTLevel, PacketType } from "../mqttPacket/mod.ts";
11
11
  export { Trie } from "../trie/trie.ts";
12
12
  export { logger } from "../utils/mod.ts";
@@ -5,7 +5,8 @@ import {
5
5
 
6
6
  import assert from "node:assert/strict";
7
7
  import { test } from "node:test";
8
- import { PacketType, type PublishPacket } from "../deps.ts";
8
+ import { MQTTLevel, PacketType } from "../deps.ts";
9
+ import type { PublishPacket } from "../deps.ts";
9
10
 
10
11
  const payloadAny = new TextEncoder().encode("any");
11
12
  const qos = 1;
@@ -39,6 +40,7 @@ test("pub/sub should work", async () => {
39
40
  const topic = "/myTopic";
40
41
  const publishPacket: PublishPacket = {
41
42
  type: PacketType.publish,
43
+ protocolLevel: MQTTLevel.v4,
42
44
  id: 1,
43
45
  topic,
44
46
  payload: payloadAny,
@@ -77,6 +79,7 @@ test("many packets should work", async () => {
77
79
  const numMessages = 1000;
78
80
  const publishPacket: PublishPacket = {
79
81
  type: PacketType.publish,
82
+ protocolLevel: MQTTLevel.v4,
80
83
  id: 1,
81
84
  topic,
82
85
  payload: payloadAny,
@@ -123,6 +126,7 @@ test("unsubscribe should work", () => {
123
126
  const topic = "/myTopic";
124
127
  const publishPacket: PublishPacket = {
125
128
  type: PacketType.publish,
129
+ protocolLevel: MQTTLevel.v4,
126
130
  id: 1,
127
131
  topic,
128
132
  payload: payloadAny,
package/server/context.ts CHANGED
@@ -1,16 +1,20 @@
1
1
  import {
2
- type AnyPacket,
3
- type IPersistence,
4
- type IStore,
5
2
  logger,
6
3
  MqttConn,
4
+ MQTTLevel,
7
5
  PacketNameByType,
8
6
  PacketType,
9
- type PublishPacket,
10
- type SockConn,
11
- type TAuthenticationResult,
12
- type Timer,
13
- type Topic,
7
+ } from "./deps.ts";
8
+ import type {
9
+ AnyPacket,
10
+ IPersistence,
11
+ IStore,
12
+ ProtocolLevel,
13
+ PublishPacket,
14
+ SockConn,
15
+ TAuthenticationResult,
16
+ Timer,
17
+ Topic,
14
18
  } from "./deps.ts";
15
19
 
16
20
  export type ClientId = string;
@@ -49,6 +53,7 @@ export type Handlers = {
49
53
 
50
54
  export class Context {
51
55
  connected: boolean;
56
+ protocolLevel: ProtocolLevel;
52
57
  conn: SockConn;
53
58
  mqttConn: MqttConn;
54
59
  persistence: IPersistence;
@@ -64,6 +69,7 @@ export class Context {
64
69
  this.conn = conn;
65
70
  this.mqttConn = new MqttConn({ conn });
66
71
  this.handlers = handlers;
72
+ this.protocolLevel = MQTTLevel.unknown;
67
73
  }
68
74
 
69
75
  async send(packet: AnyPacket): Promise<void> {
@@ -109,10 +115,10 @@ export class Context {
109
115
 
110
116
  close(executewill = true): void {
111
117
  if (this.connected) {
112
- logger.debug(
118
+ logger.info(
113
119
  `Closing ${this.store?.clientId} while mqttConn is ${
114
120
  this.mqttConn.isClosed ? "" : "not "
115
- }closed`,
121
+ }closed because of "${this.mqttConn.reason || "normal disconnect"}"`,
116
122
  );
117
123
  this.connected = false;
118
124
  if (typeof this.timer === "object") {
@@ -124,6 +130,12 @@ export class Context {
124
130
  if (executewill) {
125
131
  this.handleWill();
126
132
  }
133
+ } else {
134
+ logger.info(
135
+ `closing connection from ${this.mqttConn.remoteAddress} because of "${
136
+ this.mqttConn.reason || "normal disconnect"
137
+ }"`,
138
+ );
127
139
  }
128
140
  if (!this.mqttConn.isClosed) {
129
141
  this.mqttConn.close();
@@ -145,6 +157,7 @@ export class Context {
145
157
  broadcast(topic: Topic, payload: string, retain = false): void {
146
158
  const packet: PublishPacket = {
147
159
  type: PacketType.publish,
160
+ protocolLevel: this.protocolLevel,
148
161
  topic,
149
162
  retain,
150
163
  payload: utf8Encoder.encode(payload),
package/server/deps.ts CHANGED
@@ -12,6 +12,7 @@ export type {
12
12
  PacketId,
13
13
  PingreqPacket,
14
14
  PingresPacket,
15
+ ProtocolLevel,
15
16
  PubackPacket,
16
17
  PubcompPacket,
17
18
  PublishPacket,
@@ -30,6 +31,7 @@ export type {
30
31
 
31
32
  export {
32
33
  AuthenticationResult,
34
+ MQTTLevel,
33
35
  PacketNameByType,
34
36
  PacketType,
35
37
  } from "../mqttPacket/mod.ts";
@@ -1,12 +1,7 @@
1
1
  import type { Context } from "../context.ts";
2
- import {
3
- AuthenticationResult,
4
- type ConnectPacket,
5
- logger,
6
- PacketType,
7
- type TAuthenticationResult,
8
- Timer,
9
- } from "../deps.ts";
2
+ import { AuthenticationResult, logger, PacketType, Timer } from "../deps.ts";
3
+
4
+ import type { ConnectPacket, TAuthenticationResult } from "../deps.ts";
10
5
 
11
6
  /**
12
7
  * Checks if the client is authenticated based on the provided credentials
@@ -42,6 +37,7 @@ function validateConnect(
42
37
  if (packet.protocolLevel !== 4) {
43
38
  return AuthenticationResult.unacceptableProtocol;
44
39
  }
40
+
45
41
  return isAuthenticated(ctx, packet);
46
42
  }
47
43
 
@@ -61,6 +57,7 @@ function processValidatedConnect(
61
57
  if (packet.will) {
62
58
  ctx.will = {
63
59
  type: PacketType.publish,
60
+ protocolLevel: ctx.protocolLevel,
64
61
  qos: packet.will.qos,
65
62
  retain: packet.will.retain,
66
63
  topic: packet.will.topic,
@@ -69,6 +66,11 @@ function processValidatedConnect(
69
66
  }
70
67
 
71
68
  ctx.connect(clientId, packet.clean || false);
69
+ ctx.protocolLevel = packet.protocolLevel;
70
+ if (ctx.mqttConn) {
71
+ logger.debug(`Setting protocolLevel to ${ctx.protocolLevel}`);
72
+ ctx.mqttConn.codecOpts.protocolLevel = ctx.protocolLevel;
73
+ }
72
74
 
73
75
  const keepAlive = packet.keepAlive || 0;
74
76
  if (keepAlive > 0) {
@@ -106,10 +108,11 @@ export function handleConnect(ctx: Context, packet: ConnectPacket): void {
106
108
  );
107
109
  ctx.send({
108
110
  type: PacketType.connack,
111
+ protocolLevel: ctx.protocolLevel,
109
112
  sessionPresent,
110
113
  returnCode,
111
114
  });
112
-
115
+ logger.debug("connect returnCode", returnCode);
113
116
  if (returnCode !== AuthenticationResult.ok) {
114
117
  ctx.close();
115
118
  }
@@ -1,15 +1,14 @@
1
1
  import type { Context } from "../context.ts";
2
- import {
3
- type AnyPacket,
4
- PacketNameByType,
5
- PacketType,
6
- type PubackPacket,
7
- type PubcompPacket,
8
- type PublishPacket,
9
- type PubrecPacket,
10
- type PubrelPacket,
11
- type SubscribePacket,
12
- type UnsubscribePacket,
2
+ import { PacketNameByType, PacketType } from "../deps.ts";
3
+ import type {
4
+ AnyPacket,
5
+ PubackPacket,
6
+ PubcompPacket,
7
+ PublishPacket,
8
+ PubrecPacket,
9
+ PubrelPacket,
10
+ SubscribePacket,
11
+ UnsubscribePacket,
13
12
  } from "../deps.ts";
14
13
  import { handleConnect } from "./handleConnect.ts";
15
14
  import { handlePingreq } from "./handlePingreq.ts";
@@ -10,5 +10,6 @@ import { PacketType } from "../deps.ts";
10
10
  export async function handlePingreq(ctx: Context): Promise<void> {
11
11
  await ctx.send({
12
12
  type: PacketType.pingres,
13
+ protocolLevel: ctx.protocolLevel,
13
14
  });
14
15
  }
@@ -1,5 +1,7 @@
1
- import { type Context, SysPrefix } from "../context.ts";
2
- import { PacketType, type PublishPacket, type Topic } from "../deps.ts";
1
+ import { SysPrefix } from "../context.ts";
2
+ import { PacketType } from "../deps.ts";
3
+ import type { Context } from "../context.ts";
4
+ import type { PublishPacket, Topic } from "../deps.ts";
3
5
 
4
6
  /**
5
7
  * Checks if a client is authorized to publish to a given topic
@@ -45,6 +47,7 @@ export async function handlePublish(
45
47
  ctx.persistence.publish(packet.topic, packet);
46
48
  await ctx.send({
47
49
  type: PacketType.puback,
50
+ protocolLevel: ctx.protocolLevel,
48
51
  id,
49
52
  });
50
53
  return;
@@ -54,6 +57,7 @@ export async function handlePublish(
54
57
  ctx.store.pendingIncoming.set(packet.id, packet);
55
58
  await ctx.send({
56
59
  type: PacketType.pubrec,
60
+ protocolLevel: ctx.protocolLevel,
57
61
  id: packet.id,
58
62
  });
59
63
  }
@@ -1,5 +1,6 @@
1
+ import { PacketType } from "../deps.ts";
2
+ import type { PubrecPacket } from "../deps.ts";
1
3
  import type { Context } from "../context.ts";
2
- import { PacketType, type PubrecPacket } from "../deps.ts";
3
4
 
4
5
  /**
5
6
  * Handles PUBREC (QoS 2 Publish Received) packets
@@ -22,6 +23,7 @@ export async function handlePubrec(
22
23
  ctx.store.pendingAckOutgoing.add(id);
23
24
  await ctx.send({
24
25
  type: PacketType.pubrel,
26
+ protocolLevel: ctx.protocolLevel,
25
27
  id,
26
28
  });
27
29
  }
@@ -1,5 +1,6 @@
1
+ import { PacketType } from "../deps.ts";
1
2
  import type { Context } from "../context.ts";
2
- import { PacketType, type PubrelPacket } from "../deps.ts";
3
+ import type { PubrelPacket } from "../deps.ts";
3
4
 
4
5
  /**
5
6
  * Handles PUBREL (QoS 2 publish release) packets
@@ -25,6 +26,7 @@ export async function handlePubrel(
25
26
  ctx.store.pendingIncoming.delete(id);
26
27
  await ctx.send({
27
28
  type: PacketType.pubcomp,
29
+ protocolLevel: ctx.protocolLevel,
28
30
  id,
29
31
  });
30
32
  }
@@ -1,10 +1,6 @@
1
1
  import type { Context } from "../context.ts";
2
- import {
3
- PacketType,
4
- type SubscribePacket,
5
- type Subscription,
6
- type Topic,
7
- } from "../deps.ts";
2
+ import { PacketType } from "../deps.ts";
3
+ import type { SubscribePacket, Subscription, Topic } from "../deps.ts";
8
4
 
9
5
  /**
10
6
  * @constant {number} SubscriptionFailure
@@ -57,6 +53,7 @@ export async function handleSubscribe(
57
53
 
58
54
  await ctx.send({
59
55
  type: PacketType.suback,
56
+ protocolLevel: ctx.protocolLevel,
60
57
  id: packet.id,
61
58
  returnCodes: returnCodes,
62
59
  });
@@ -1,5 +1,6 @@
1
+ import { PacketType } from "../deps.ts";
2
+ import type { UnsubscribePacket } from "../deps.ts";
1
3
  import type { Context } from "../context.ts";
2
- import { PacketType, type UnsubscribePacket } from "../deps.ts";
3
4
 
4
5
  /**
5
6
  * Handles MQTT unsubscribe packets by removing subscriptions and sending acknowledgement
@@ -19,5 +20,6 @@ export async function handleUnsubscribe(
19
20
  await ctx.send({
20
21
  type: PacketType.unsuback,
21
22
  id: packet.id,
23
+ protocolLevel: ctx.protocolLevel,
22
24
  });
23
25
  }
package/server/server.ts CHANGED
@@ -1,13 +1,7 @@
1
- import { Context, type Handlers } from "./context.ts";
2
- import {
3
- AuthenticationResult,
4
- type IPersistence,
5
- logger,
6
- MemoryPersistence,
7
- type SockConn,
8
- type Topic,
9
- } from "./deps.ts";
10
-
1
+ import { AuthenticationResult, logger, MemoryPersistence } from "./deps.ts";
2
+ import { Context } from "./context.ts";
3
+ import type { Handlers } from "./context.ts";
4
+ import type { IPersistence, SockConn, Topic } from "./deps.ts";
11
5
  import { handlePacket } from "./handlers/handlePacket.ts";
12
6
 
13
7
  const defaultIsAuthenticated = (
@@ -63,12 +57,14 @@ export class MqttServer {
63
57
  }
64
58
  try {
65
59
  for await (const packet of ctx.mqttConn) {
66
- handlePacket(ctx, packet);
60
+ await handlePacket(ctx, packet);
67
61
  }
68
62
  } catch (err) {
69
63
  logger.debug(`Error while serving:${err}`);
70
64
  } finally {
71
- ctx.close();
65
+ if (!ctx.mqttConn.isClosed) {
66
+ ctx.close();
67
+ }
72
68
  }
73
69
  }
74
70
  }
@@ -7,7 +7,7 @@ import {
7
7
  PacketType,
8
8
  } from "../../mqttPacket/mod.ts";
9
9
  import { AsyncQueue, nextTick } from "../../utils/mod.ts";
10
- import { MqttConn } from "../deps.ts";
10
+ import { MqttConn, MQTTLevel } from "../deps.ts";
11
11
  import { MqttServer } from "../mod.ts";
12
12
  import { handlers } from "./test-handlers.ts";
13
13
 
@@ -28,6 +28,7 @@ const connectPacket: AnyPacket = {
28
28
 
29
29
  const disconnectPacket: AnyPacket = {
30
30
  type: PacketType.disconnect,
31
+ protocolLevel: MQTTLevel.v4,
31
32
  };
32
33
 
33
34
  const mqttServer = new MqttServer({ handlers });
@@ -1,6 +1,7 @@
1
- import { AuthenticationResult, type Context, type Topic } from "../mod.ts";
1
+ import { AuthenticationResult } from "../mod.ts";
2
2
  import { logger } from "../../utils/mod.ts";
3
3
  import type { TAuthenticationResult } from "../deps.ts";
4
+ import type { Context, Topic } from "../mod.ts";
4
5
 
5
6
  const utf8Decoder = new TextDecoder();
6
7
  const userTable = new Map();
package/socket/socket.ts CHANGED
@@ -60,7 +60,11 @@ export class Conn {
60
60
  close() {
61
61
  if (!this.closed) {
62
62
  this.closed = true;
63
- this.closer();
63
+ try {
64
+ this.closer();
65
+ } catch (_err) {
66
+ // swallow any errors on close
67
+ }
64
68
  }
65
69
  }
66
70
  }
package/utils/assert.ts CHANGED
@@ -12,21 +12,3 @@ export function assert(expr: unknown, msg = ""): asserts expr {
12
12
  throw new AssertionError(msg);
13
13
  }
14
14
  }
15
-
16
- /** An array-like object (`Array`, `Uint8Array`, `NodeList`, etc.) that is not a string */
17
- export type ArrayLikeArg<T> = ArrayLike<T> & object;
18
-
19
- export function assertArrayIncludes<T>(
20
- actual: ArrayLikeArg<T>,
21
- expected: ArrayLikeArg<T>,
22
- msg?: string,
23
- ) {
24
- const actualArr = Array.from(actual);
25
- const expectedArr = Array.from(expected);
26
- for (const item of expectedArr) {
27
- assert(
28
- actualArr.includes(item),
29
- msg + `\nExpected: ${expectedArr}\nActual: ${actualArr}`,
30
- );
31
- }
32
- }
package/utils/mod.ts CHANGED
@@ -7,6 +7,3 @@ export { Deferred } from "./deferred.ts";
7
7
  export { Logger, logger, LogLevel } from "./logger.ts";
8
8
  export { AsyncQueue } from "./asyncQueue.ts";
9
9
  export { nextTick } from "./nextTick.ts";
10
- export { parseArgs } from "./args.ts";
11
- export type { Args } from "./args.ts";
12
- export { getArgs } from "./platform.ts";
@@ -1,16 +0,0 @@
1
- import type { PacketId, TPacketType } from "./types.ts";
2
- /**
3
- * PubackPacket is sent to indicate publish complete (QoS 1)
4
- */
5
- export type PubackPacket = {
6
- type: TPacketType;
7
- id: PacketId;
8
- };
9
- export declare const puback: {
10
- encode(packet: PubackPacket): {
11
- flags: number;
12
- bytes: number[];
13
- };
14
- decode(buffer: Uint8Array): PubackPacket;
15
- };
16
- //# sourceMappingURL=puback.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"puback.d.ts","sourceRoot":"","sources":["../../mqttPacket/puback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKxD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,QAAQ,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE;IACnB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACjE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAAC;CAkB1C,CAAC"}
@@ -1,21 +0,0 @@
1
- import { PacketType } from "./PacketType.js";
2
- import { Decoder } from "./decoder.js";
3
- import { Encoder } from "./encoder.js";
4
- export const puback = {
5
- encode(packet) {
6
- const flags = 0;
7
- const encoder = new Encoder();
8
- encoder.setInt16(packet.id);
9
- return { flags, bytes: encoder.done() };
10
- },
11
- decode(buffer) {
12
- const decoder = new Decoder(buffer);
13
- const id = decoder.getInt16();
14
- decoder.done();
15
- return {
16
- type: PacketType.puback,
17
- id,
18
- };
19
- },
20
- };
21
- //# sourceMappingURL=puback.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"puback.js","sourceRoot":"","sources":["../../mqttPacket/puback.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAUvC,MAAM,CAAC,MAAM,MAAM,GAGf;IACF,MAAM,CAAC,MAAoB;QACzB,MAAM,KAAK,GAAG,CAAC,CAAC;QAChB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;IAC1C,CAAC;IAED,MAAM,CAAC,MAAkB;QACvB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,UAAU,CAAC,MAAM;YACvB,EAAE;SACH,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -1,17 +0,0 @@
1
- import type { PacketId, TPacketType } from "./types.ts";
2
- /**
3
- * PubcompPacket is sent to indicate publish complete
4
- * It is the fourth packet of the QoS 2 protocol exchange.
5
- */
6
- export type PubcompPacket = {
7
- type: TPacketType;
8
- id: PacketId;
9
- };
10
- export declare const pubcomp: {
11
- encode(packet: PubcompPacket): {
12
- flags: number;
13
- bytes: number[];
14
- };
15
- decode(buffer: Uint8Array): PubcompPacket;
16
- };
17
- //# sourceMappingURL=pubcomp.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pubcomp.d.ts","sourceRoot":"","sources":["../../mqttPacket/pubcomp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKxD;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,QAAQ,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE;IACpB,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAClE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAAC;CAkB3C,CAAC"}
@@ -1,21 +0,0 @@
1
- import { PacketType } from "./PacketType.js";
2
- import { Decoder } from "./decoder.js";
3
- import { Encoder } from "./encoder.js";
4
- export const pubcomp = {
5
- encode(packet) {
6
- const flags = 0;
7
- const encoder = new Encoder();
8
- encoder.setInt16(packet.id);
9
- return { flags, bytes: encoder.done() };
10
- },
11
- decode(buffer) {
12
- const decoder = new Decoder(buffer);
13
- const id = decoder.getInt16();
14
- decoder.done();
15
- return {
16
- type: PacketType.pubcomp,
17
- id,
18
- };
19
- },
20
- };
21
- //# sourceMappingURL=pubcomp.js.map