@seriousme/opifex 1.11.2 → 2.0.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.
Files changed (538) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +102 -43
  3. package/bin/conformanceServer.ts +45 -13
  4. package/bin/demoServer.ts +38 -13
  5. package/bin/mqtt.ts +52 -30
  6. package/client/ConnectionState.ts +2 -0
  7. package/client/client.ts +57 -47
  8. package/client/context.ts +75 -21
  9. package/client/deps.ts +5 -0
  10. package/client/handlers/handleAuth.test.ts +193 -0
  11. package/client/handlers/handleAuth.ts +89 -0
  12. package/client/handlers/handleConnack.test.ts +173 -0
  13. package/client/handlers/handleConnack.ts +16 -6
  14. package/client/handlers/handleDisconnect.test.ts +22 -0
  15. package/client/handlers/handleDisconnect.ts +17 -0
  16. package/client/handlers/handlePacket.test.ts +242 -0
  17. package/client/handlers/handlePacket.ts +19 -5
  18. package/client/handlers/handlePuback.test.ts +99 -0
  19. package/client/handlers/handlePuback.ts +6 -0
  20. package/client/handlers/handlePubcomp.test.ts +112 -0
  21. package/client/handlers/handlePubcomp.ts +5 -0
  22. package/client/handlers/handlePublish.test.ts +188 -0
  23. package/client/handlers/handlePubrec.test.ts +119 -0
  24. package/client/handlers/handlePubrec.ts +5 -1
  25. package/client/handlers/handlePubrel.test.ts +136 -0
  26. package/client/handlers/handleSuback.test.ts +122 -0
  27. package/client/handlers/handleSuback.ts +3 -0
  28. package/client/handlers/handleUnsuback.test.ts +101 -0
  29. package/client/mod.ts +2 -2
  30. package/client/store/memoryStore.ts +2 -2
  31. package/client/store/store.ts +3 -1
  32. package/deno/README.md +1 -2
  33. package/deno/tcpClient.test.ts +75 -0
  34. package/deno/tcpClient.ts +16 -11
  35. package/deno/tcpServer.test.ts +22 -21
  36. package/deno/tcpServer.ts +5 -0
  37. package/deno/tlsServer.test.ts +97 -0
  38. package/deno/tlsServer.ts +42 -0
  39. package/deno/wsServer.test.ts +93 -0
  40. package/deno/wsServer.ts +73 -0
  41. package/dev_utils/generateCert.ts +95 -0
  42. package/dev_utils/mockConn.ts +36 -0
  43. package/dev_utils/mockServer.ts +28 -0
  44. package/dev_utils/mod.ts +30 -2
  45. package/dev_utils/packetHelpers.ts +404 -0
  46. package/dev_utils/test-handlers.ts +98 -0
  47. package/dev_utils/timers.ts +14 -0
  48. package/dev_utils/webStreamPair.test.ts +171 -0
  49. package/dev_utils/webStreamPair.ts +143 -0
  50. package/dist/bin/conformanceServer.js +17 -12
  51. package/dist/bin/conformanceServer.js.map +1 -1
  52. package/dist/bin/demoServer.js +16 -12
  53. package/dist/bin/demoServer.js.map +1 -1
  54. package/dist/bin/mqtt.js +19 -16
  55. package/dist/bin/mqtt.js.map +1 -1
  56. package/dist/client/ConnectionState.d.ts +2 -0
  57. package/dist/client/ConnectionState.d.ts.map +1 -1
  58. package/dist/client/ConnectionState.js +2 -0
  59. package/dist/client/ConnectionState.js.map +1 -1
  60. package/dist/client/client.d.ts +19 -22
  61. package/dist/client/client.d.ts.map +1 -1
  62. package/dist/client/client.js +34 -20
  63. package/dist/client/client.js.map +1 -1
  64. package/dist/client/context.d.ts +11 -3
  65. package/dist/client/context.d.ts.map +1 -1
  66. package/dist/client/context.js +44 -12
  67. package/dist/client/context.js.map +1 -1
  68. package/dist/client/deps.d.ts +3 -2
  69. package/dist/client/deps.d.ts.map +1 -1
  70. package/dist/client/deps.js +1 -1
  71. package/dist/client/deps.js.map +1 -1
  72. package/dist/client/handlers/handleAuth.d.ts +9 -0
  73. package/dist/client/handlers/handleAuth.d.ts.map +1 -0
  74. package/dist/client/handlers/handleAuth.js +66 -0
  75. package/dist/client/handlers/handleAuth.js.map +1 -0
  76. package/dist/client/handlers/handleConnack.d.ts +2 -2
  77. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  78. package/dist/client/handlers/handleConnack.js +16 -6
  79. package/dist/client/handlers/handleConnack.js.map +1 -1
  80. package/dist/client/handlers/handleDisconnect.d.ts +11 -0
  81. package/dist/client/handlers/handleDisconnect.d.ts.map +1 -0
  82. package/dist/client/handlers/handleDisconnect.js +15 -0
  83. package/dist/client/handlers/handleDisconnect.js.map +1 -0
  84. package/dist/client/handlers/handlePacket.d.ts.map +1 -1
  85. package/dist/client/handlers/handlePacket.js +14 -3
  86. package/dist/client/handlers/handlePacket.js.map +1 -1
  87. package/dist/client/handlers/handlePuback.d.ts.map +1 -1
  88. package/dist/client/handlers/handlePuback.js +5 -0
  89. package/dist/client/handlers/handlePuback.js.map +1 -1
  90. package/dist/client/handlers/handlePubcomp.d.ts.map +1 -1
  91. package/dist/client/handlers/handlePubcomp.js +5 -0
  92. package/dist/client/handlers/handlePubcomp.js.map +1 -1
  93. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  94. package/dist/client/handlers/handlePubrec.js +5 -1
  95. package/dist/client/handlers/handlePubrec.js.map +1 -1
  96. package/dist/client/handlers/handleSuback.d.ts +1 -0
  97. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  98. package/dist/client/handlers/handleSuback.js +3 -0
  99. package/dist/client/handlers/handleSuback.js.map +1 -1
  100. package/dist/client/mod.d.ts +2 -2
  101. package/dist/client/mod.d.ts.map +1 -1
  102. package/dist/client/mod.js +1 -1
  103. package/dist/client/mod.js.map +1 -1
  104. package/dist/client/store/memoryStore.d.ts.map +1 -1
  105. package/dist/client/store/memoryStore.js +2 -2
  106. package/dist/client/store/memoryStore.js.map +1 -1
  107. package/dist/client/store/store.d.ts +2 -1
  108. package/dist/client/store/store.d.ts.map +1 -1
  109. package/dist/client/store/store.js +1 -1
  110. package/dist/client/store/store.js.map +1 -1
  111. package/dist/dev_utils/generateCert.d.ts +11 -0
  112. package/dist/dev_utils/generateCert.d.ts.map +1 -0
  113. package/dist/dev_utils/generateCert.js +76 -0
  114. package/dist/dev_utils/generateCert.js.map +1 -0
  115. package/dist/examples/authHandler.test.d.ts +2 -0
  116. package/dist/examples/authHandler.test.d.ts.map +1 -0
  117. package/dist/examples/authHandler.test.js +123 -0
  118. package/dist/examples/authHandler.test.js.map +1 -0
  119. package/dist/examples/mqtt.test.d.ts +2 -0
  120. package/dist/examples/mqtt.test.d.ts.map +1 -0
  121. package/dist/examples/mqtt.test.js +70 -0
  122. package/dist/examples/mqtt.test.js.map +1 -0
  123. package/dist/examples/mqtts.test.d.ts +2 -0
  124. package/dist/examples/mqtts.test.d.ts.map +1 -0
  125. package/dist/examples/mqtts.test.js +81 -0
  126. package/dist/examples/mqtts.test.js.map +1 -0
  127. package/dist/mqttConn/mqttConn.d.ts +25 -16
  128. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  129. package/dist/mqttConn/mqttConn.js +69 -40
  130. package/dist/mqttConn/mqttConn.js.map +1 -1
  131. package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
  132. package/dist/mqttPacket/BitMask.d.ts +12 -11
  133. package/dist/mqttPacket/BitMask.d.ts.map +1 -1
  134. package/dist/mqttPacket/BitMask.js +10 -18
  135. package/dist/mqttPacket/BitMask.js.map +1 -1
  136. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  137. package/dist/mqttPacket/Properties.d.ts +2 -2
  138. package/dist/mqttPacket/Properties.d.ts.map +1 -1
  139. package/dist/mqttPacket/Properties.js.map +1 -1
  140. package/dist/mqttPacket/ReasonCode.d.ts +1 -0
  141. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -1
  142. package/dist/mqttPacket/ReasonCode.js +1 -0
  143. package/dist/mqttPacket/ReasonCode.js.map +1 -1
  144. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
  145. package/dist/mqttPacket/auth.d.ts +3 -5
  146. package/dist/mqttPacket/auth.d.ts.map +1 -1
  147. package/dist/mqttPacket/auth.js +31 -30
  148. package/dist/mqttPacket/auth.js.map +1 -1
  149. package/dist/mqttPacket/codec.d.ts +48 -0
  150. package/dist/mqttPacket/codec.d.ts.map +1 -0
  151. package/dist/mqttPacket/codec.js +93 -0
  152. package/dist/mqttPacket/codec.js.map +1 -0
  153. package/dist/mqttPacket/connack.d.ts +4 -5
  154. package/dist/mqttPacket/connack.d.ts.map +1 -1
  155. package/dist/mqttPacket/connack.js +43 -45
  156. package/dist/mqttPacket/connack.js.map +1 -1
  157. package/dist/mqttPacket/connect.d.ts +26 -27
  158. package/dist/mqttPacket/connect.d.ts.map +1 -1
  159. package/dist/mqttPacket/connect.js +156 -157
  160. package/dist/mqttPacket/connect.js.map +1 -1
  161. package/dist/mqttPacket/decoder.d.ts +1 -13
  162. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  163. package/dist/mqttPacket/decoder.js +7 -28
  164. package/dist/mqttPacket/decoder.js.map +1 -1
  165. package/dist/mqttPacket/disconnect.d.ts +4 -5
  166. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  167. package/dist/mqttPacket/disconnect.js +41 -43
  168. package/dist/mqttPacket/disconnect.js.map +1 -1
  169. package/dist/mqttPacket/encoder.d.ts +1 -15
  170. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  171. package/dist/mqttPacket/encoder.js +4 -27
  172. package/dist/mqttPacket/encoder.js.map +1 -1
  173. package/dist/mqttPacket/length.js +1 -1
  174. package/dist/mqttPacket/length.js.map +1 -1
  175. package/dist/mqttPacket/mod.d.ts +21 -103
  176. package/dist/mqttPacket/mod.d.ts.map +1 -1
  177. package/dist/mqttPacket/mod.js +5 -94
  178. package/dist/mqttPacket/mod.js.map +1 -1
  179. package/dist/mqttPacket/pingreq.d.ts +4 -5
  180. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  181. package/dist/mqttPacket/pingreq.js +11 -13
  182. package/dist/mqttPacket/pingreq.js.map +1 -1
  183. package/dist/mqttPacket/pingres.d.ts +4 -5
  184. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  185. package/dist/mqttPacket/pingres.js +11 -13
  186. package/dist/mqttPacket/pingres.js.map +1 -1
  187. package/dist/mqttPacket/protocolLevels.d.ts +11 -6
  188. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
  189. package/dist/mqttPacket/protocolLevels.js +5 -1
  190. package/dist/mqttPacket/protocolLevels.js.map +1 -1
  191. package/dist/mqttPacket/pubblishAcks.d.ts +9 -10
  192. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
  193. package/dist/mqttPacket/pubblishAcks.js +43 -45
  194. package/dist/mqttPacket/pubblishAcks.js.map +1 -1
  195. package/dist/mqttPacket/publish.d.ts +14 -14
  196. package/dist/mqttPacket/publish.d.ts.map +1 -1
  197. package/dist/mqttPacket/publish.js +53 -55
  198. package/dist/mqttPacket/publish.js.map +1 -1
  199. package/dist/mqttPacket/suback.d.ts +4 -5
  200. package/dist/mqttPacket/suback.d.ts.map +1 -1
  201. package/dist/mqttPacket/suback.js +38 -40
  202. package/dist/mqttPacket/suback.js.map +1 -1
  203. package/dist/mqttPacket/subscribe.d.ts +36 -7
  204. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  205. package/dist/mqttPacket/subscribe.js +90 -89
  206. package/dist/mqttPacket/subscribe.js.map +1 -1
  207. package/dist/mqttPacket/types.d.ts +1 -8
  208. package/dist/mqttPacket/types.d.ts.map +1 -1
  209. package/dist/mqttPacket/unsuback.d.ts +4 -5
  210. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  211. package/dist/mqttPacket/unsuback.js +32 -34
  212. package/dist/mqttPacket/unsuback.js.map +1 -1
  213. package/dist/mqttPacket/unsubscribe.d.ts +23 -6
  214. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  215. package/dist/mqttPacket/unsubscribe.js +45 -44
  216. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  217. package/dist/mqttPacket/validators.d.ts +4 -16
  218. package/dist/mqttPacket/validators.d.ts.map +1 -1
  219. package/dist/mqttPacket/validators.js +5 -26
  220. package/dist/mqttPacket/validators.js.map +1 -1
  221. package/dist/node/tcpClient.d.ts +1 -1
  222. package/dist/node/tcpClient.d.ts.map +1 -1
  223. package/dist/node/tcpClient.js +12 -7
  224. package/dist/node/tcpClient.js.map +1 -1
  225. package/dist/node/tcpServer.d.ts.map +1 -1
  226. package/dist/node/tcpServer.js +4 -0
  227. package/dist/node/tcpServer.js.map +1 -1
  228. package/dist/node/tlsServer.d.ts +19 -0
  229. package/dist/node/tlsServer.d.ts.map +1 -0
  230. package/dist/node/tlsServer.js +58 -0
  231. package/dist/node/tlsServer.js.map +1 -0
  232. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  233. package/dist/node/wrapNodeSocket.js +6 -28
  234. package/dist/node/wrapNodeSocket.js.map +1 -1
  235. package/dist/persistence/basicPersistence.d.ts +36 -0
  236. package/dist/persistence/basicPersistence.d.ts.map +1 -0
  237. package/dist/persistence/basicPersistence.js +306 -0
  238. package/dist/persistence/basicPersistence.js.map +1 -0
  239. package/dist/persistence/deps.d.ts +3 -2
  240. package/dist/persistence/deps.d.ts.map +1 -1
  241. package/dist/persistence/deps.js +2 -1
  242. package/dist/persistence/deps.js.map +1 -1
  243. package/dist/persistence/memory/memoryPersistence.d.ts +6 -23
  244. package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
  245. package/dist/persistence/memory/memoryPersistence.js +12 -115
  246. package/dist/persistence/memory/memoryPersistence.js.map +1 -1
  247. package/dist/persistence/memory/memoryStorage.d.ts +45 -0
  248. package/dist/persistence/memory/memoryStorage.d.ts.map +1 -0
  249. package/dist/persistence/memory/memoryStorage.js +143 -0
  250. package/dist/persistence/memory/memoryStorage.js.map +1 -0
  251. package/dist/persistence/mod.d.ts +3 -3
  252. package/dist/persistence/mod.d.ts.map +1 -1
  253. package/dist/persistence/mod.js +6 -1
  254. package/dist/persistence/mod.js.map +1 -1
  255. package/dist/persistence/persistence.d.ts +44 -69
  256. package/dist/persistence/persistence.d.ts.map +1 -1
  257. package/dist/persistence/persistence.js +1 -2
  258. package/dist/persistence/persistence.js.map +1 -1
  259. package/dist/persistence/sqlite/sqliteDatabase.d.ts +46 -0
  260. package/dist/persistence/sqlite/sqliteDatabase.d.ts.map +1 -0
  261. package/dist/persistence/sqlite/sqliteDatabase.js +215 -0
  262. package/dist/persistence/sqlite/sqliteDatabase.js.map +1 -0
  263. package/dist/persistence/sqlite/sqlitePersistence.d.ts +16 -0
  264. package/dist/persistence/sqlite/sqlitePersistence.d.ts.map +1 -0
  265. package/dist/persistence/sqlite/sqlitePersistence.js +29 -0
  266. package/dist/persistence/sqlite/sqlitePersistence.js.map +1 -0
  267. package/dist/persistence/sqlite/sqliteStorage.d.ts +36 -0
  268. package/dist/persistence/sqlite/sqliteStorage.d.ts.map +1 -0
  269. package/dist/persistence/sqlite/sqliteStorage.js +194 -0
  270. package/dist/persistence/sqlite/sqliteStorage.js.map +1 -0
  271. package/dist/persistence/storage.d.ts +38 -0
  272. package/dist/persistence/storage.d.ts.map +1 -0
  273. package/dist/persistence/storage.js +5 -0
  274. package/dist/persistence/storage.js.map +1 -0
  275. package/dist/server/config.d.ts +47 -0
  276. package/dist/server/config.d.ts.map +1 -0
  277. package/dist/server/config.js +41 -0
  278. package/dist/server/config.js.map +1 -0
  279. package/dist/server/context.d.ts +198 -24
  280. package/dist/server/context.d.ts.map +1 -1
  281. package/dist/server/context.js +432 -53
  282. package/dist/server/context.js.map +1 -1
  283. package/dist/server/deps.d.ts +5 -6
  284. package/dist/server/deps.d.ts.map +1 -1
  285. package/dist/server/deps.js +2 -2
  286. package/dist/server/deps.js.map +1 -1
  287. package/dist/server/handlers/completeConnect.d.ts +8 -0
  288. package/dist/server/handlers/completeConnect.d.ts.map +1 -0
  289. package/dist/server/handlers/completeConnect.js +74 -0
  290. package/dist/server/handlers/completeConnect.js.map +1 -0
  291. package/dist/server/handlers/handleAuth.d.ts +9 -0
  292. package/dist/server/handlers/handleAuth.d.ts.map +1 -0
  293. package/dist/server/handlers/handleAuth.js +69 -0
  294. package/dist/server/handlers/handleAuth.js.map +1 -0
  295. package/dist/server/handlers/handleConnect.d.ts +2 -4
  296. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  297. package/dist/server/handlers/handleConnect.js +140 -67
  298. package/dist/server/handlers/handleConnect.js.map +1 -1
  299. package/dist/server/handlers/handleDisconnect.d.ts +1 -1
  300. package/dist/server/handlers/handleDisconnect.d.ts.map +1 -1
  301. package/dist/server/handlers/handleDisconnect.js +3 -3
  302. package/dist/server/handlers/handleDisconnect.js.map +1 -1
  303. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  304. package/dist/server/handlers/handlePacket.js +19 -6
  305. package/dist/server/handlers/handlePacket.js.map +1 -1
  306. package/dist/server/handlers/handlePuback.d.ts +1 -3
  307. package/dist/server/handlers/handlePuback.d.ts.map +1 -1
  308. package/dist/server/handlers/handlePuback.js +2 -8
  309. package/dist/server/handlers/handlePuback.js.map +1 -1
  310. package/dist/server/handlers/handlePubcomp.d.ts +1 -1
  311. package/dist/server/handlers/handlePubcomp.d.ts.map +1 -1
  312. package/dist/server/handlers/handlePubcomp.js +2 -4
  313. package/dist/server/handlers/handlePubcomp.js.map +1 -1
  314. package/dist/server/handlers/handlePublish.d.ts +1 -1
  315. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  316. package/dist/server/handlers/handlePublish.js +149 -45
  317. package/dist/server/handlers/handlePublish.js.map +1 -1
  318. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  319. package/dist/server/handlers/handlePubrec.js +2 -3
  320. package/dist/server/handlers/handlePubrec.js.map +1 -1
  321. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  322. package/dist/server/handlers/handlePubrel.js +6 -2
  323. package/dist/server/handlers/handlePubrel.js.map +1 -1
  324. package/dist/server/handlers/handleSubscribe.d.ts +1 -6
  325. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  326. package/dist/server/handlers/handleSubscribe.js +99 -38
  327. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  328. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  329. package/dist/server/handlers/handleUnsubscribe.js +19 -4
  330. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  331. package/dist/server/mod.d.ts +3 -3
  332. package/dist/server/mod.d.ts.map +1 -1
  333. package/dist/server/mod.js +1 -1
  334. package/dist/server/mod.js.map +1 -1
  335. package/dist/server/server.d.ts +29 -6
  336. package/dist/server/server.d.ts.map +1 -1
  337. package/dist/server/server.js +84 -15
  338. package/dist/server/server.js.map +1 -1
  339. package/dist/socket/socket.d.ts +11 -9
  340. package/dist/socket/socket.d.ts.map +1 -1
  341. package/dist/socket/socket.js +67 -15
  342. package/dist/socket/socket.js.map +1 -1
  343. package/dist/timer/timer.d.ts +32 -0
  344. package/dist/timer/timer.d.ts.map +1 -1
  345. package/dist/timer/timer.js +32 -0
  346. package/dist/timer/timer.js.map +1 -1
  347. package/dist/trie/trie.d.ts +10 -5
  348. package/dist/trie/trie.d.ts.map +1 -1
  349. package/dist/trie/trie.js +47 -17
  350. package/dist/trie/trie.js.map +1 -1
  351. package/dist/utils/assert.d.ts.map +1 -1
  352. package/dist/utils/{BufferedAsyncIterable.d.ts → bufferedAsyncIterable.d.ts} +1 -1
  353. package/dist/utils/bufferedAsyncIterable.d.ts.map +1 -0
  354. package/dist/utils/{BufferedAsyncIterable.js → bufferedAsyncIterable.js} +1 -1
  355. package/dist/utils/bufferedAsyncIterable.js.map +1 -0
  356. package/dist/utils/deferred.d.ts.map +1 -1
  357. package/dist/utils/deferred.js.map +1 -1
  358. package/dist/utils/getOrInsertPolyFill.d.ts +2 -0
  359. package/dist/utils/getOrInsertPolyFill.d.ts.map +1 -0
  360. package/dist/utils/getOrInsertPolyFill.js +12 -0
  361. package/dist/utils/getOrInsertPolyFill.js.map +1 -0
  362. package/dist/utils/logger.d.ts +40 -3
  363. package/dist/utils/logger.d.ts.map +1 -1
  364. package/dist/utils/logger.js +53 -7
  365. package/dist/utils/logger.js.map +1 -1
  366. package/dist/utils/mod.d.ts +6 -1
  367. package/dist/utils/mod.d.ts.map +1 -1
  368. package/dist/utils/mod.js +5 -1
  369. package/dist/utils/mod.js.map +1 -1
  370. package/dist/utils/outboundTopicAliasManager.d.ts +52 -0
  371. package/dist/utils/outboundTopicAliasManager.d.ts.map +1 -0
  372. package/dist/utils/outboundTopicAliasManager.js +74 -0
  373. package/dist/utils/outboundTopicAliasManager.js.map +1 -0
  374. package/dist/utils/queue.d.ts.map +1 -1
  375. package/dist/utils/topicFilter.d.ts +32 -0
  376. package/dist/utils/topicFilter.d.ts.map +1 -0
  377. package/dist/utils/topicFilter.js +52 -0
  378. package/dist/utils/topicFilter.js.map +1 -0
  379. package/dist/utils/utils.d.ts +2 -0
  380. package/dist/utils/utils.d.ts.map +1 -1
  381. package/dist/utils/utils.js +2 -0
  382. package/dist/utils/utils.js.map +1 -1
  383. package/dist/utils/validators.d.ts +34 -0
  384. package/dist/utils/validators.d.ts.map +1 -0
  385. package/dist/utils/validators.js +61 -0
  386. package/dist/utils/validators.js.map +1 -0
  387. package/dist/web/webSocketStream.d.ts +29 -0
  388. package/dist/web/webSocketStream.d.ts.map +1 -0
  389. package/dist/web/webSocketStream.js +69 -0
  390. package/dist/web/webSocketStream.js.map +1 -0
  391. package/dist/web/wrapWebSocket.d.ts +12 -0
  392. package/dist/web/wrapWebSocket.d.ts.map +1 -0
  393. package/dist/web/wrapWebSocket.js +41 -0
  394. package/dist/web/wrapWebSocket.js.map +1 -0
  395. package/dist/web/wsClient.d.ts +7 -0
  396. package/dist/web/wsClient.d.ts.map +1 -0
  397. package/dist/web/wsClient.js +22 -0
  398. package/dist/web/wsClient.js.map +1 -0
  399. package/dist/web/wsClient.test.d.ts +2 -0
  400. package/dist/web/wsClient.test.d.ts.map +1 -0
  401. package/dist/web/wsClient.test.js +20 -0
  402. package/dist/web/wsClient.test.js.map +1 -0
  403. package/examples/authHandler.test.ts +164 -0
  404. package/examples/mqtt.test.ts +89 -0
  405. package/examples/mqtts.test.ts +100 -0
  406. package/examples/webSocket.test.ts +94 -0
  407. package/mqttConn/mqttConn.test.ts +9 -9
  408. package/mqttConn/mqttConn.ts +91 -49
  409. package/mqttPacket/BitMask.ts +11 -19
  410. package/mqttPacket/Properties.ts +6 -3
  411. package/mqttPacket/ReasonCode.ts +2 -1
  412. package/mqttPacket/auth.test.ts +1 -1
  413. package/mqttPacket/auth.ts +41 -48
  414. package/mqttPacket/codec.ts +146 -0
  415. package/mqttPacket/connack.ts +57 -68
  416. package/mqttPacket/connect.test.ts +2 -2
  417. package/mqttPacket/connect.ts +197 -204
  418. package/mqttPacket/decoder.test.ts +0 -39
  419. package/mqttPacket/decoder.ts +9 -36
  420. package/mqttPacket/disconnect.ts +57 -68
  421. package/mqttPacket/encoder.ts +5 -40
  422. package/mqttPacket/length.ts +1 -1
  423. package/mqttPacket/mod.ts +48 -200
  424. package/mqttPacket/pingreq.ts +21 -27
  425. package/mqttPacket/pingres.ts +21 -27
  426. package/mqttPacket/protocolLevels.ts +12 -7
  427. package/mqttPacket/pubblishAcks.ts +68 -77
  428. package/mqttPacket/publish.ts +76 -83
  429. package/mqttPacket/suback.ts +48 -58
  430. package/mqttPacket/subscribe.ts +141 -117
  431. package/mqttPacket/types.ts +1 -9
  432. package/mqttPacket/unsuback.ts +46 -58
  433. package/mqttPacket/unsubscribe.ts +74 -63
  434. package/mqttPacket/validators.ts +5 -31
  435. package/node/socket-node-stream.test.ts +322 -0
  436. package/node/socket-node-stream.ts +174 -0
  437. package/node/tcpClient.test.ts +70 -0
  438. package/node/tcpClient.ts +13 -12
  439. package/node/tcpServer.test.ts +24 -20
  440. package/node/tcpServer.ts +6 -0
  441. package/node/tlsServer.test.ts +94 -0
  442. package/node/tlsServer.ts +81 -0
  443. package/node/wrapNodeSocket.ts +7 -30
  444. package/package.json +73 -45
  445. package/persistence/basicPersistence.ts +495 -0
  446. package/persistence/deps.ts +11 -1
  447. package/persistence/memory/memoryPersistence.ts +12 -152
  448. package/persistence/memory/memoryStorage.ts +232 -0
  449. package/persistence/mod.ts +4 -4
  450. package/persistence/persistence.test.ts +24 -0
  451. package/persistence/persistence.testing.ts +1324 -0
  452. package/persistence/persistence.ts +111 -67
  453. package/persistence/sqlite/sqliteDatabase.ts +294 -0
  454. package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
  455. package/persistence/sqlite/sqlitePersistence.ts +36 -0
  456. package/persistence/sqlite/sqliteStorage.ts +324 -0
  457. package/persistence/storage.ts +84 -0
  458. package/server/config.ts +65 -0
  459. package/server/context.ts +658 -74
  460. package/server/deps.ts +25 -5
  461. package/server/handlers/completeConnect.ts +93 -0
  462. package/server/handlers/duplicate.test.ts +196 -0
  463. package/server/handlers/handleAuth.test.ts +225 -0
  464. package/server/handlers/handleAuth.ts +88 -0
  465. package/server/handlers/handleConnect.test.ts +589 -0
  466. package/server/handlers/handleConnect.ts +201 -86
  467. package/server/handlers/handleConnect.version.test.ts +108 -0
  468. package/server/handlers/handleDisconnect.test.ts +56 -0
  469. package/server/handlers/handleDisconnect.ts +3 -3
  470. package/server/handlers/handlePacket.test.ts +24 -0
  471. package/server/handlers/handlePacket.ts +30 -8
  472. package/server/handlers/handlePingreq.test.ts +29 -0
  473. package/server/handlers/handlePuback.test.ts +28 -0
  474. package/server/handlers/handlePuback.ts +5 -8
  475. package/server/handlers/handlePubcomp.test.ts +28 -0
  476. package/server/handlers/handlePubcomp.ts +5 -4
  477. package/server/handlers/handlePublish.test.ts +471 -0
  478. package/server/handlers/handlePublish.ts +189 -35
  479. package/server/handlers/handlePubrec.test.ts +28 -0
  480. package/server/handlers/handlePubrec.ts +2 -3
  481. package/server/handlers/handlePubrel.test.ts +74 -0
  482. package/server/handlers/handlePubrel.ts +12 -2
  483. package/server/handlers/handleSubscribe.test.ts +971 -0
  484. package/server/handlers/handleSubscribe.ts +158 -39
  485. package/server/handlers/handleUnsubscribe.test.ts +79 -0
  486. package/server/handlers/handleUnsubscribe.ts +29 -5
  487. package/server/handlers/keepalive.test.ts +132 -0
  488. package/server/handlers/session.persistence.test.ts +194 -0
  489. package/server/handlers/will.delivery.test.ts +221 -0
  490. package/server/mod.ts +4 -3
  491. package/server/preconnect.test.ts +151 -0
  492. package/server/server.ts +115 -17
  493. package/socket/socket.test.ts +91 -0
  494. package/socket/socket.ts +81 -31
  495. package/timer/timer.test.ts +4 -7
  496. package/timer/timer.ts +36 -0
  497. package/tools/benchmarks/receiver.ts +51 -0
  498. package/tools/benchmarks/sender.ts +48 -0
  499. package/tools/benchmarks/utils.ts +31 -0
  500. package/tools/mqtt-compat/README.md +130 -0
  501. package/tools/mqtt-compat/broker.ts +52 -0
  502. package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
  503. package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
  504. package/trie/trie.test.ts +9 -1
  505. package/trie/trie.ts +57 -22
  506. package/utils/bufferedAsyncIterable.test.ts +92 -0
  507. package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +1 -1
  508. package/utils/deferred.test.ts +36 -0
  509. package/utils/deferred.ts +0 -1
  510. package/utils/getOrInsertPolyFill.ts +12 -0
  511. package/utils/logger.test.ts +189 -0
  512. package/utils/logger.ts +62 -7
  513. package/utils/mod.ts +15 -1
  514. package/utils/outboundTopicAliasManager.ts +100 -0
  515. package/utils/queue.test.ts +61 -0
  516. package/utils/topicFilter.test.ts +63 -0
  517. package/utils/topicFilter.ts +61 -0
  518. package/utils/utils.ts +3 -0
  519. package/utils/validators.ts +67 -0
  520. package/web/webSocketStream.ts +97 -0
  521. package/web/wrapWebSocket.ts +52 -0
  522. package/web/wsClient.test.ts +26 -0
  523. package/web/wsClient.ts +25 -0
  524. package/benchmarks/receiver.ts +0 -35
  525. package/benchmarks/sender.ts +0 -32
  526. package/benchmarks/utils.ts +0 -9
  527. package/dev_utils/dummyConn.ts +0 -110
  528. package/dist/persistence/store.d.ts +0 -13
  529. package/dist/persistence/store.d.ts.map +0 -1
  530. package/dist/persistence/store.js +0 -2
  531. package/dist/persistence/store.js.map +0 -1
  532. package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
  533. package/dist/utils/BufferedAsyncIterable.js.map +0 -1
  534. package/examples/tcpServer.test.ts +0 -148
  535. package/persistence/memory/memoryPersistence.test.ts +0 -156
  536. package/persistence/store.ts +0 -15
  537. package/server/test/handleConnect.test.ts +0 -130
  538. package/server/test/test-handlers.ts +0 -53
@@ -0,0 +1,173 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { handleConnack } from "./handleConnack.ts";
4
+ import { ConnectionState } from "../ConnectionState.ts";
5
+ import { AuthenticationResult, MQTTLevel } from "../deps.ts";
6
+ import type { ConnackPacket } from "../deps.ts";
7
+ import { Deferred } from "../../utils/mod.ts";
8
+
9
+ function createMockContext() {
10
+ const sentPackets: unknown[] = [];
11
+ return {
12
+ connectionState: ConnectionState.connecting as string,
13
+ protocolLevel: 4 as const,
14
+ mqttConn: { codecOpts: { protocolLevel: MQTTLevel.unknown } },
15
+ pingTimer: { reset: () => {}, clear: () => {} },
16
+ unresolvedConnect: new Deferred<number>(),
17
+ store: {
18
+ pendingOutgoing: new Map(),
19
+ pendingIncoming: new Map(),
20
+ pendingAckOutgoing: new Map(),
21
+ async *pendingOutgoingPackets() {},
22
+ },
23
+ send: (packet: unknown) => {
24
+ sentPackets.push(packet);
25
+ },
26
+ sentPackets,
27
+ };
28
+ }
29
+
30
+ test("handleConnack sets connected state on success", async () => {
31
+ const ctx = createMockContext();
32
+ const packet = {
33
+ type: 2,
34
+ protocolLevel: 4 as const,
35
+ sessionPresent: false,
36
+ returnCode: AuthenticationResult.ok,
37
+ } as ConnackPacket;
38
+
39
+ await handleConnack(ctx as never, packet);
40
+
41
+ assert.deepStrictEqual(
42
+ ctx.connectionState,
43
+ ConnectionState.connected,
44
+ "Should be connected after successful CONNACK",
45
+ );
46
+ });
47
+
48
+ test("handleConnack resolves connect promise on success", async () => {
49
+ const ctx = createMockContext();
50
+ const packet = {
51
+ type: 2,
52
+ protocolLevel: 4 as const,
53
+ sessionPresent: false,
54
+ returnCode: AuthenticationResult.ok,
55
+ } as ConnackPacket;
56
+
57
+ await handleConnack(ctx as never, packet);
58
+
59
+ const result = await ctx.unresolvedConnect.promise;
60
+ assert.deepStrictEqual(result, 0, "Should resolve with success code 0");
61
+ });
62
+
63
+ test("handleConnack rejects on bad username/password", async () => {
64
+ const ctx = createMockContext();
65
+ const packet = {
66
+ type: 2,
67
+ protocolLevel: 4 as const,
68
+ sessionPresent: false,
69
+ returnCode: AuthenticationResult.badUsernameOrPassword,
70
+ } as ConnackPacket;
71
+
72
+ await handleConnack(ctx as never, packet);
73
+
74
+ assert.deepStrictEqual(
75
+ ctx.connectionState,
76
+ ConnectionState.disconnecting,
77
+ "Should be disconnecting on auth failure",
78
+ );
79
+
80
+ await assert.rejects(
81
+ ctx.unresolvedConnect.promise,
82
+ /Connect failed/,
83
+ "Should reject with connect failed error",
84
+ );
85
+ });
86
+
87
+ test("handleConnack rejects on not authorized", async () => {
88
+ const ctx = createMockContext();
89
+ const packet = {
90
+ type: 2,
91
+ protocolLevel: 4 as const,
92
+ sessionPresent: false,
93
+ returnCode: AuthenticationResult.notAuthorized,
94
+ } as ConnackPacket;
95
+
96
+ await handleConnack(ctx as never, packet);
97
+
98
+ assert.deepStrictEqual(
99
+ ctx.connectionState,
100
+ ConnectionState.disconnecting,
101
+ );
102
+
103
+ await assert.rejects(
104
+ ctx.unresolvedConnect.promise,
105
+ /Connect failed/,
106
+ );
107
+ });
108
+
109
+ test("handleConnack handles MQTT v5 reason codes", async () => {
110
+ const ctx = createMockContext();
111
+ (ctx as { protocolLevel: number }).protocolLevel = 5;
112
+ const packet = {
113
+ type: 2,
114
+ protocolLevel: 5 as const,
115
+ sessionPresent: false,
116
+ reasonCode: 0,
117
+ } as ConnackPacket;
118
+
119
+ await handleConnack(ctx as never, packet);
120
+
121
+ assert.deepStrictEqual(
122
+ ctx.connectionState,
123
+ ConnectionState.connected,
124
+ "Should be connected with v5 success reason code",
125
+ );
126
+ });
127
+
128
+ test("handleConnack resets ping timer on success", async () => {
129
+ let timerReset = false;
130
+ const ctx = createMockContext();
131
+ ctx.pingTimer = {
132
+ reset: () => {
133
+ timerReset = true;
134
+ },
135
+ clear: () => {},
136
+ };
137
+
138
+ const packet = {
139
+ type: 2,
140
+ protocolLevel: 4 as const,
141
+ sessionPresent: false,
142
+ returnCode: AuthenticationResult.ok,
143
+ } as ConnackPacket;
144
+
145
+ await handleConnack(ctx as never, packet);
146
+
147
+ assert.deepStrictEqual(timerReset, true, "Ping timer should be reset");
148
+ });
149
+
150
+ test("handleConnack clears ping timer on failure", async () => {
151
+ let timerCleared = false;
152
+ const ctx = createMockContext();
153
+ ctx.pingTimer = {
154
+ reset: () => {},
155
+ clear: () => {
156
+ timerCleared = true;
157
+ },
158
+ };
159
+
160
+ const packet = {
161
+ type: 2,
162
+ protocolLevel: 4 as const,
163
+ sessionPresent: false,
164
+ returnCode: AuthenticationResult.badUsernameOrPassword,
165
+ } as ConnackPacket;
166
+
167
+ await handleConnack(ctx as never, packet);
168
+ assert.deepStrictEqual(timerCleared, true, "Ping timer should be cleared");
169
+ await assert.rejects(
170
+ ctx.unresolvedConnect.promise,
171
+ /Connect failed/,
172
+ );
173
+ });
@@ -5,20 +5,30 @@ import type { ConnackPacket, TReasonCode } from "../deps.ts";
5
5
 
6
6
  /**
7
7
  * Handles the CONNACK packet received from the MQTT broker
8
- * @param packet - The CONNACK packet containing the connection acknowledgment
9
8
  * @param ctx - The connection context
9
+ * @param packet - The CONNACK packet containing the connection acknowledgment
10
10
  * @returns Promise that resolves when handling is complete
11
11
  */
12
- export async function handleConnack(packet: ConnackPacket, ctx: Context) {
13
- const result = packet.protocolLevel === 5
14
- ? packet.reasonCode
15
- : packet.returnCode;
12
+ export async function handleConnack(ctx: Context, packet: ConnackPacket) {
13
+ const isVersion5 = packet.protocolLevel === 5;
14
+ const result = isVersion5 ? packet.reasonCode : packet.returnCode;
16
15
  if (result === 0) {
17
16
  ctx.connectionState = ConnectionState.connected;
18
17
  if (ctx.mqttConn) {
19
18
  ctx.mqttConn.codecOpts.protocolLevel = ctx.protocolLevel;
20
19
  }
21
- ctx.pingTimer?.reset();
20
+
21
+ const serverKeepAlive = isVersion5
22
+ ? packet.properties?.serverKeepAlive
23
+ : undefined;
24
+
25
+ if (serverKeepAlive === 0) {
26
+ ctx.pingTimer?.clear(); // Server disabled keepalive
27
+ } else if (serverKeepAlive !== undefined) {
28
+ ctx.setPingTimer(serverKeepAlive); // Server set a new interval
29
+ } else {
30
+ ctx.pingTimer?.reset(); // Default fallback for V4 or V5 without override
31
+ }
22
32
  ctx.unresolvedConnect?.resolve(result);
23
33
  // start transmitting packets that were queued before
24
34
  for await (const packet of ctx.store.pendingOutgoingPackets()) {
@@ -0,0 +1,22 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { handleDisconnect } from "./handleDisconnect.ts";
4
+ import { PacketType, ReasonCode, ReasonCodeByNumber } from "../deps.ts";
5
+ import type { DisconnectPacket } from "../deps.ts";
6
+
7
+ function createMockContext() {
8
+ return {
9
+ close: () => {},
10
+ };
11
+ }
12
+
13
+ test("handleDisconnect processes V5 rejection", () => {
14
+ const ctx = createMockContext();
15
+ const reasonCode = ReasonCode.notAuthorized;
16
+ assert.throws(() =>
17
+ handleDisconnect(ctx as never, {
18
+ type: PacketType.disconnect,
19
+ protocolLevel: 5,
20
+ reasonCode,
21
+ } as DisconnectPacket), Error(ReasonCodeByNumber[reasonCode]));
22
+ });
@@ -0,0 +1,17 @@
1
+ import type { Context } from "../context.ts";
2
+ import type { DisconnectPacket } from "../deps.ts";
3
+ import { ReasonCodeByNumber } from "../deps.ts";
4
+
5
+ /**
6
+ * Handles Disconnect Packet sent by the broker (V5 only)
7
+ * @param ctx - The MQTT client context
8
+ * @param packet - The PUBACK packet received from the broker
9
+ * @description
10
+ * - throw error
11
+ */
12
+ export function handleDisconnect(ctx: Context, packet: DisconnectPacket): void {
13
+ if (packet.protocolLevel === 5 && ((packet.reasonCode ?? 0) !== 0)) {
14
+ throw new Error(ReasonCodeByNumber[packet.reasonCode!]);
15
+ }
16
+ ctx.close();
17
+ }
@@ -0,0 +1,242 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { handlePacket } from "./handlePacket.ts";
4
+ import { ConnectionState } from "../ConnectionState.ts";
5
+ import { AuthenticationResult, MQTTLevel, PacketType } from "../deps.ts";
6
+ import type { AnyPacket, PublishPacket } from "../deps.ts";
7
+ import { Deferred } from "../../utils/mod.ts";
8
+
9
+ function createMockContext() {
10
+ const sentPackets: unknown[] = [];
11
+ const receivedPublishes: PublishPacket[] = [];
12
+ const receivedIds: {
13
+ puback: number[];
14
+ pubcomp: number[];
15
+ suback: number[];
16
+ unsuback: number[];
17
+ } = {
18
+ puback: [],
19
+ pubcomp: [],
20
+ suback: [],
21
+ unsuback: [],
22
+ };
23
+ return {
24
+ connectionState: ConnectionState.connecting as string,
25
+ protocolLevel: 4 as const,
26
+ mqttConn: { codecOpts: { protocolLevel: MQTTLevel.unknown } },
27
+ pingTimer: { reset: () => {}, clear: () => {} },
28
+ unresolvedConnect: new Deferred<number>(),
29
+ store: {
30
+ pendingOutgoing: new Map<number, unknown>(),
31
+ pendingIncoming: new Map<number, PublishPacket>(),
32
+ pendingAckOutgoing: new Map<number, unknown>(),
33
+ async *pendingOutgoingPackets() {},
34
+ },
35
+ send: (packet: unknown) => {
36
+ sentPackets.push(packet);
37
+ },
38
+ receivePublish: (packet: PublishPacket) => {
39
+ receivedPublishes.push(packet);
40
+ },
41
+ receivePuback: (id: number) => {
42
+ receivedIds.puback.push(id);
43
+ return true;
44
+ },
45
+ receivePubcomp: (id: number) => {
46
+ receivedIds.pubcomp.push(id);
47
+ return true;
48
+ },
49
+ receiveSuback: (id: number, _codes: number[]) => {
50
+ receivedIds.suback.push(id);
51
+ return true;
52
+ },
53
+ receiveUnsuback: (id: number) => {
54
+ receivedIds.unsuback.push(id);
55
+ return true;
56
+ },
57
+ sentPackets,
58
+ receivedPublishes,
59
+ receivedIds,
60
+ };
61
+ }
62
+
63
+ test("handlePacket dispatches CONNACK before connected", async () => {
64
+ const ctx = createMockContext();
65
+
66
+ const packet = {
67
+ type: PacketType.connack,
68
+ protocolLevel: 4 as const,
69
+ sessionPresent: false,
70
+ returnCode: AuthenticationResult.ok,
71
+ } as AnyPacket;
72
+
73
+ await handlePacket(ctx as never, packet);
74
+
75
+ assert.deepStrictEqual(
76
+ ctx.connectionState,
77
+ ConnectionState.connected,
78
+ "Should handle CONNACK and set connected state",
79
+ );
80
+ });
81
+
82
+ test("handlePacket rejects non-CONNACK before connected", async () => {
83
+ const ctx = createMockContext();
84
+
85
+ const packet = {
86
+ type: PacketType.pingreq,
87
+ protocolLevel: 4,
88
+ } as AnyPacket;
89
+
90
+ await assert.rejects(
91
+ handlePacket(ctx as never, packet),
92
+ /while connecting/,
93
+ "Should reject packets before CONNACK",
94
+ );
95
+ });
96
+
97
+ test("handlePacket dispatches PUBLISH after connected", async () => {
98
+ const ctx = createMockContext();
99
+ ctx.connectionState = ConnectionState.connected;
100
+
101
+ const packet = {
102
+ type: PacketType.publish,
103
+ protocolLevel: 4 as const,
104
+ topic: "test/topic",
105
+ payload: new Uint8Array([1, 2, 3]),
106
+ qos: 0 as const,
107
+ retain: false,
108
+ dup: false,
109
+ } as AnyPacket;
110
+
111
+ await handlePacket(ctx as never, packet);
112
+
113
+ assert.deepStrictEqual(
114
+ ctx.receivedPublishes.length,
115
+ 1,
116
+ "Should dispatch PUBLISH to handler",
117
+ );
118
+ });
119
+
120
+ test("handlePacket dispatches PUBACK after connected", async () => {
121
+ const ctx = createMockContext();
122
+ ctx.connectionState = ConnectionState.connected;
123
+
124
+ const packet = {
125
+ type: PacketType.puback,
126
+ protocolLevel: 4 as const,
127
+ id: 1,
128
+ } as AnyPacket;
129
+
130
+ await handlePacket(ctx as never, packet);
131
+
132
+ assert.deepStrictEqual(
133
+ ctx.receivedIds.puback,
134
+ [1],
135
+ "Should dispatch PUBACK to handler",
136
+ );
137
+ });
138
+
139
+ test("handlePacket dispatches PINGRES silently", async () => {
140
+ const ctx = createMockContext();
141
+ ctx.connectionState = ConnectionState.connected;
142
+
143
+ const packet = {
144
+ type: PacketType.pingres,
145
+ protocolLevel: 4,
146
+ } as AnyPacket;
147
+
148
+ // Should not throw
149
+ await handlePacket(ctx as never, packet);
150
+
151
+ // PINGRES is silently handled (no specific action)
152
+ assert.deepStrictEqual(ctx.sentPackets.length, 0);
153
+ });
154
+
155
+ test("handlePacket dispatches SUBACK after connected", async () => {
156
+ const ctx = createMockContext();
157
+ ctx.connectionState = ConnectionState.connected;
158
+ ctx.store.pendingOutgoing.set(1, { type: PacketType.subscribe });
159
+
160
+ const packet = {
161
+ type: PacketType.suback,
162
+ protocolLevel: 4 as const,
163
+ id: 1,
164
+ returnCodes: [0],
165
+ } as AnyPacket;
166
+
167
+ await handlePacket(ctx as never, packet);
168
+
169
+ assert.deepStrictEqual(
170
+ ctx.receivedIds.suback,
171
+ [1],
172
+ "Should dispatch SUBACK to handler",
173
+ );
174
+ });
175
+
176
+ test("handlePacket dispatches UNSUBACK after connected", async () => {
177
+ const ctx = createMockContext();
178
+ ctx.connectionState = ConnectionState.connected;
179
+ ctx.store.pendingOutgoing.set(2, { type: PacketType.unsubscribe });
180
+
181
+ const packet = {
182
+ type: PacketType.unsuback,
183
+ protocolLevel: 4 as const,
184
+ id: 2,
185
+ } as AnyPacket;
186
+
187
+ await handlePacket(ctx as never, packet);
188
+
189
+ assert.deepStrictEqual(
190
+ ctx.receivedIds.unsuback,
191
+ [2],
192
+ "Should dispatch UNSUBACK to handler",
193
+ );
194
+ });
195
+
196
+ test("handlePacket rejects unexpected packet types", async () => {
197
+ const ctx = createMockContext();
198
+ ctx.connectionState = ConnectionState.connected;
199
+
200
+ // CONNECT shouldn't be received by client after connection
201
+ const packet = {
202
+ type: PacketType.connect,
203
+ protocolName: "MQTT",
204
+ protocolLevel: 4 as const,
205
+ clientId: "test",
206
+ clean: true,
207
+ keepAlive: 0,
208
+ } as AnyPacket;
209
+
210
+ await assert.rejects(
211
+ handlePacket(ctx as never, packet),
212
+ /unexpected/i,
213
+ "Should reject unexpected packet types",
214
+ );
215
+ });
216
+
217
+ test("handlePacket handles QoS 2 flow packets", async () => {
218
+ const ctx = createMockContext();
219
+ ctx.connectionState = ConnectionState.connected;
220
+
221
+ // Test PUBREC
222
+ ctx.store.pendingOutgoing.set(10, { type: PacketType.publish, id: 10 });
223
+ await handlePacket(ctx as never, {
224
+ type: PacketType.pubrec,
225
+ protocolLevel: 4,
226
+ id: 10,
227
+ } as AnyPacket);
228
+ assert.deepStrictEqual(ctx.sentPackets.length, 1);
229
+ assert.deepStrictEqual(
230
+ (ctx.sentPackets[0] as { type: number }).type,
231
+ PacketType.pubrel,
232
+ );
233
+
234
+ // Test PUBCOMP
235
+ ctx.store.pendingAckOutgoing.set(10, { type: PacketType.pubrel, id: 10 });
236
+ await handlePacket(ctx as never, {
237
+ type: PacketType.pubcomp,
238
+ protocolLevel: 4,
239
+ id: 10,
240
+ } as AnyPacket);
241
+ assert.deepStrictEqual(ctx.receivedIds.pubcomp, [10]);
242
+ });
@@ -1,5 +1,6 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import { ConnectionState } from "../ConnectionState.ts";
3
+ import { handleAuth } from "./handleAuth.ts";
3
4
  import { handleConnack } from "./handleConnack.ts";
4
5
  import { handlePublish } from "./handlePublish.ts";
5
6
  import { handlePuback } from "./handlePuback.ts";
@@ -8,10 +9,13 @@ import { handlePubrel } from "./handlePubrel.ts";
8
9
  import { handlePubcomp } from "./handlePubcomp.ts";
9
10
  import { handleSuback } from "./handleSuback.ts";
10
11
  import { handleUnsuback } from "./handleUnsuback.ts";
12
+ import { handleDisconnect } from "./handleDisconnect.ts";
11
13
  import { logger, PacketNameByType, PacketType } from "../deps.ts";
12
14
  import type {
13
15
  AnyPacket,
16
+ AuthPacket,
14
17
  ConnackPacket,
18
+ DisconnectPacket,
15
19
  PubackPacket,
16
20
  PubcompPacket,
17
21
  PublishPacket,
@@ -35,14 +39,21 @@ export async function handlePacket(
35
39
  logger.debug({ received: PacketNameByType[packet.type], packet });
36
40
  if (ctx.connectionState !== ConnectionState.connected) {
37
41
  if (packet.type === PacketType.connack) {
38
- handleConnack(packet as ConnackPacket, ctx);
39
- } else {
40
- throw new Error(
41
- `Received ${PacketNameByType[packet.type]} packet before connect`,
42
- );
42
+ handleConnack(ctx, packet as ConnackPacket);
43
+ return;
43
44
  }
45
+ if (packet.type === PacketType.auth) {
46
+ await handleAuth(ctx, packet as AuthPacket);
47
+ return;
48
+ }
49
+ throw new Error(
50
+ `Received ${PacketNameByType[packet.type]} packet while connecting`,
51
+ );
44
52
  } else {
45
53
  switch (packet.type) {
54
+ case PacketType.auth:
55
+ await handleAuth(ctx, packet as AuthPacket);
56
+ break;
46
57
  case PacketType.pingres:
47
58
  break;
48
59
  case PacketType.publish:
@@ -66,6 +77,9 @@ export async function handlePacket(
66
77
  case PacketType.unsuback:
67
78
  handleUnsuback(ctx, packet as UnsubackPacket);
68
79
  break;
80
+ case PacketType.disconnect:
81
+ handleDisconnect(ctx, packet as DisconnectPacket);
82
+ break;
69
83
 
70
84
  default:
71
85
  throw new Error(
@@ -0,0 +1,99 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { handlePuback } from "./handlePuback.ts";
4
+ import { PacketType, ReasonCode, ReasonCodeByNumber } from "../deps.ts";
5
+ import type { PubackPacket } from "../deps.ts";
6
+
7
+ function createMockContext() {
8
+ const receivedIds: number[] = [];
9
+ return {
10
+ protocolLevel: 4 as const,
11
+ store: {
12
+ pendingOutgoing: new Map<number, unknown>(),
13
+ pendingIncoming: new Map(),
14
+ pendingAckOutgoing: new Map(),
15
+ },
16
+ receivePuback: (id: number) => {
17
+ receivedIds.push(id);
18
+ return true;
19
+ },
20
+ receivedIds,
21
+ };
22
+ }
23
+
24
+ test("handlePuback removes packet from pending and notifies context", () => {
25
+ const ctx = createMockContext();
26
+ ctx.store.pendingOutgoing.set(1, { type: PacketType.publish });
27
+
28
+ const packet = {
29
+ type: PacketType.puback,
30
+ protocolLevel: 4 as const,
31
+ id: 1,
32
+ } as PubackPacket;
33
+
34
+ handlePuback(ctx as never, packet);
35
+
36
+ assert.deepStrictEqual(
37
+ ctx.store.pendingOutgoing.has(1),
38
+ false,
39
+ "Should remove from pending",
40
+ );
41
+ assert.deepStrictEqual(
42
+ ctx.receivedIds,
43
+ [1],
44
+ "Should notify context of puback",
45
+ );
46
+ });
47
+
48
+ test("handlePuback handles non-existent packet ID gracefully", () => {
49
+ const ctx = createMockContext();
50
+
51
+ const packet = {
52
+ type: PacketType.puback,
53
+ protocolLevel: 4 as const,
54
+ id: 999,
55
+ } as PubackPacket;
56
+
57
+ // Should not throw
58
+ handlePuback(ctx as never, packet);
59
+
60
+ assert.deepStrictEqual(
61
+ ctx.receivedIds,
62
+ [999],
63
+ "Should still notify context",
64
+ );
65
+ });
66
+
67
+ test("handlePuback processes multiple PUBACKs correctly", () => {
68
+ const ctx = createMockContext();
69
+ ctx.store.pendingOutgoing.set(1, { type: PacketType.publish });
70
+ ctx.store.pendingOutgoing.set(2, { type: PacketType.publish });
71
+ ctx.store.pendingOutgoing.set(3, { type: PacketType.publish });
72
+
73
+ handlePuback(ctx as never, {
74
+ type: PacketType.puback,
75
+ protocolLevel: 4,
76
+ id: 2,
77
+ } as PubackPacket);
78
+
79
+ assert.deepStrictEqual(ctx.store.pendingOutgoing.has(1), true);
80
+ assert.deepStrictEqual(ctx.store.pendingOutgoing.has(2), false);
81
+ assert.deepStrictEqual(ctx.store.pendingOutgoing.has(3), true);
82
+ assert.deepStrictEqual(ctx.receivedIds, [2]);
83
+ });
84
+
85
+ test("handlePuback processes V5 publish rejection", () => {
86
+ const ctx = createMockContext();
87
+ const reasonCode = ReasonCode.notAuthorized;
88
+ ctx.store.pendingOutgoing.set(2, {
89
+ type: PacketType.publish,
90
+ topic: "Test Puback",
91
+ });
92
+ assert.throws(() =>
93
+ handlePuback(ctx as never, {
94
+ type: PacketType.puback,
95
+ protocolLevel: 5,
96
+ id: 2,
97
+ reasonCode,
98
+ } as PubackPacket), Error(ReasonCodeByNumber[reasonCode]));
99
+ });
@@ -1,5 +1,6 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import type { PubackPacket } from "../deps.ts";
3
+ import { ReasonCodeByNumber } from "../deps.ts";
3
4
 
4
5
  /**
5
6
  * Handles PUBACK packet processing for QoS level 1 PUBLISH responses
@@ -12,5 +13,10 @@ import type { PubackPacket } from "../deps.ts";
12
13
  export function handlePuback(ctx: Context, packet: PubackPacket): void {
13
14
  const id = packet.id;
14
15
  ctx.store.pendingOutgoing.delete(id);
16
+
17
+ if (packet.protocolLevel === 5 && ((packet.reasonCode ?? 0) !== 0)) {
18
+ ctx.store.pendingOutgoing.delete(id);
19
+ throw new Error(ReasonCodeByNumber[packet.reasonCode!]);
20
+ }
15
21
  ctx.receivePuback(id);
16
22
  }