@seriousme/opifex 1.11.3 → 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 (531) hide show
  1. package/README.md +99 -40
  2. package/bin/conformanceServer.ts +45 -13
  3. package/bin/demoServer.ts +38 -13
  4. package/bin/mqtt.ts +2 -2
  5. package/client/ConnectionState.ts +2 -0
  6. package/client/client.ts +51 -41
  7. package/client/context.ts +75 -21
  8. package/client/deps.ts +4 -0
  9. package/client/handlers/handleAuth.test.ts +193 -0
  10. package/client/handlers/handleAuth.ts +89 -0
  11. package/client/handlers/handleConnack.test.ts +173 -0
  12. package/client/handlers/handleConnack.ts +16 -6
  13. package/client/handlers/handleDisconnect.test.ts +22 -0
  14. package/client/handlers/handleDisconnect.ts +17 -0
  15. package/client/handlers/handlePacket.test.ts +242 -0
  16. package/client/handlers/handlePacket.ts +19 -5
  17. package/client/handlers/handlePuback.test.ts +99 -0
  18. package/client/handlers/handlePuback.ts +6 -0
  19. package/client/handlers/handlePubcomp.test.ts +112 -0
  20. package/client/handlers/handlePubcomp.ts +5 -0
  21. package/client/handlers/handlePublish.test.ts +188 -0
  22. package/client/handlers/handlePubrec.test.ts +119 -0
  23. package/client/handlers/handlePubrec.ts +5 -1
  24. package/client/handlers/handlePubrel.test.ts +136 -0
  25. package/client/handlers/handleSuback.test.ts +122 -0
  26. package/client/handlers/handleSuback.ts +3 -0
  27. package/client/handlers/handleUnsuback.test.ts +101 -0
  28. package/client/mod.ts +1 -1
  29. package/client/store/memoryStore.ts +2 -2
  30. package/client/store/store.ts +3 -1
  31. package/deno/README.md +1 -2
  32. package/deno/tcpClient.test.ts +75 -0
  33. package/deno/tcpClient.ts +16 -11
  34. package/deno/tcpServer.test.ts +22 -21
  35. package/deno/tcpServer.ts +5 -0
  36. package/deno/tlsServer.test.ts +97 -0
  37. package/deno/tlsServer.ts +42 -0
  38. package/deno/wsServer.test.ts +93 -0
  39. package/deno/wsServer.ts +73 -0
  40. package/dev_utils/generateCert.ts +95 -0
  41. package/dev_utils/mockConn.ts +36 -0
  42. package/dev_utils/mockServer.ts +28 -0
  43. package/dev_utils/mod.ts +30 -3
  44. package/dev_utils/packetHelpers.ts +404 -0
  45. package/dev_utils/test-handlers.ts +98 -0
  46. package/dev_utils/timers.ts +14 -0
  47. package/dev_utils/webStreamPair.test.ts +171 -0
  48. package/dev_utils/webStreamPair.ts +143 -0
  49. package/dist/bin/conformanceServer.js +17 -12
  50. package/dist/bin/conformanceServer.js.map +1 -1
  51. package/dist/bin/demoServer.js +16 -12
  52. package/dist/bin/demoServer.js.map +1 -1
  53. package/dist/bin/mqtt.js +2 -2
  54. package/dist/bin/mqtt.js.map +1 -1
  55. package/dist/client/ConnectionState.d.ts +2 -0
  56. package/dist/client/ConnectionState.d.ts.map +1 -1
  57. package/dist/client/ConnectionState.js +2 -0
  58. package/dist/client/ConnectionState.js.map +1 -1
  59. package/dist/client/client.d.ts +13 -16
  60. package/dist/client/client.d.ts.map +1 -1
  61. package/dist/client/client.js +34 -20
  62. package/dist/client/client.js.map +1 -1
  63. package/dist/client/context.d.ts +11 -3
  64. package/dist/client/context.d.ts.map +1 -1
  65. package/dist/client/context.js +44 -12
  66. package/dist/client/context.js.map +1 -1
  67. package/dist/client/deps.d.ts +3 -2
  68. package/dist/client/deps.d.ts.map +1 -1
  69. package/dist/client/deps.js +1 -1
  70. package/dist/client/deps.js.map +1 -1
  71. package/dist/client/handlers/handleAuth.d.ts +9 -0
  72. package/dist/client/handlers/handleAuth.d.ts.map +1 -0
  73. package/dist/client/handlers/handleAuth.js +66 -0
  74. package/dist/client/handlers/handleAuth.js.map +1 -0
  75. package/dist/client/handlers/handleConnack.d.ts +2 -2
  76. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  77. package/dist/client/handlers/handleConnack.js +16 -6
  78. package/dist/client/handlers/handleConnack.js.map +1 -1
  79. package/dist/client/handlers/handleDisconnect.d.ts +11 -0
  80. package/dist/client/handlers/handleDisconnect.d.ts.map +1 -0
  81. package/dist/client/handlers/handleDisconnect.js +15 -0
  82. package/dist/client/handlers/handleDisconnect.js.map +1 -0
  83. package/dist/client/handlers/handlePacket.d.ts.map +1 -1
  84. package/dist/client/handlers/handlePacket.js +14 -3
  85. package/dist/client/handlers/handlePacket.js.map +1 -1
  86. package/dist/client/handlers/handlePuback.d.ts.map +1 -1
  87. package/dist/client/handlers/handlePuback.js +5 -0
  88. package/dist/client/handlers/handlePuback.js.map +1 -1
  89. package/dist/client/handlers/handlePubcomp.d.ts.map +1 -1
  90. package/dist/client/handlers/handlePubcomp.js +5 -0
  91. package/dist/client/handlers/handlePubcomp.js.map +1 -1
  92. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  93. package/dist/client/handlers/handlePubrec.js +5 -1
  94. package/dist/client/handlers/handlePubrec.js.map +1 -1
  95. package/dist/client/handlers/handleSuback.d.ts +1 -0
  96. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  97. package/dist/client/handlers/handleSuback.js +3 -0
  98. package/dist/client/handlers/handleSuback.js.map +1 -1
  99. package/dist/client/mod.d.ts +1 -1
  100. package/dist/client/mod.d.ts.map +1 -1
  101. package/dist/client/mod.js +1 -1
  102. package/dist/client/mod.js.map +1 -1
  103. package/dist/client/store/memoryStore.d.ts.map +1 -1
  104. package/dist/client/store/memoryStore.js +2 -2
  105. package/dist/client/store/memoryStore.js.map +1 -1
  106. package/dist/client/store/store.d.ts +2 -1
  107. package/dist/client/store/store.d.ts.map +1 -1
  108. package/dist/client/store/store.js +1 -1
  109. package/dist/client/store/store.js.map +1 -1
  110. package/dist/dev_utils/generateCert.d.ts +11 -0
  111. package/dist/dev_utils/generateCert.d.ts.map +1 -0
  112. package/dist/dev_utils/generateCert.js +76 -0
  113. package/dist/dev_utils/generateCert.js.map +1 -0
  114. package/dist/examples/authHandler.test.d.ts +2 -0
  115. package/dist/examples/authHandler.test.d.ts.map +1 -0
  116. package/dist/examples/authHandler.test.js +123 -0
  117. package/dist/examples/authHandler.test.js.map +1 -0
  118. package/dist/examples/mqtt.test.d.ts +2 -0
  119. package/dist/examples/mqtt.test.d.ts.map +1 -0
  120. package/dist/examples/mqtt.test.js +70 -0
  121. package/dist/examples/mqtt.test.js.map +1 -0
  122. package/dist/examples/mqtts.test.d.ts +2 -0
  123. package/dist/examples/mqtts.test.d.ts.map +1 -0
  124. package/dist/examples/mqtts.test.js +81 -0
  125. package/dist/examples/mqtts.test.js.map +1 -0
  126. package/dist/mqttConn/mqttConn.d.ts +23 -15
  127. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  128. package/dist/mqttConn/mqttConn.js +56 -35
  129. package/dist/mqttConn/mqttConn.js.map +1 -1
  130. package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
  131. package/dist/mqttPacket/BitMask.d.ts.map +1 -1
  132. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  133. package/dist/mqttPacket/Properties.d.ts +2 -2
  134. package/dist/mqttPacket/Properties.d.ts.map +1 -1
  135. package/dist/mqttPacket/Properties.js.map +1 -1
  136. package/dist/mqttPacket/ReasonCode.d.ts +1 -0
  137. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -1
  138. package/dist/mqttPacket/ReasonCode.js +1 -0
  139. package/dist/mqttPacket/ReasonCode.js.map +1 -1
  140. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
  141. package/dist/mqttPacket/auth.d.ts +3 -5
  142. package/dist/mqttPacket/auth.d.ts.map +1 -1
  143. package/dist/mqttPacket/auth.js +31 -30
  144. package/dist/mqttPacket/auth.js.map +1 -1
  145. package/dist/mqttPacket/codec.d.ts +48 -0
  146. package/dist/mqttPacket/codec.d.ts.map +1 -0
  147. package/dist/mqttPacket/codec.js +93 -0
  148. package/dist/mqttPacket/codec.js.map +1 -0
  149. package/dist/mqttPacket/connack.d.ts +4 -5
  150. package/dist/mqttPacket/connack.d.ts.map +1 -1
  151. package/dist/mqttPacket/connack.js +43 -45
  152. package/dist/mqttPacket/connack.js.map +1 -1
  153. package/dist/mqttPacket/connect.d.ts +4 -5
  154. package/dist/mqttPacket/connect.d.ts.map +1 -1
  155. package/dist/mqttPacket/connect.js +156 -157
  156. package/dist/mqttPacket/connect.js.map +1 -1
  157. package/dist/mqttPacket/decoder.d.ts +1 -13
  158. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  159. package/dist/mqttPacket/decoder.js +6 -27
  160. package/dist/mqttPacket/decoder.js.map +1 -1
  161. package/dist/mqttPacket/disconnect.d.ts +4 -5
  162. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  163. package/dist/mqttPacket/disconnect.js +41 -43
  164. package/dist/mqttPacket/disconnect.js.map +1 -1
  165. package/dist/mqttPacket/encoder.d.ts +1 -15
  166. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  167. package/dist/mqttPacket/encoder.js +4 -27
  168. package/dist/mqttPacket/encoder.js.map +1 -1
  169. package/dist/mqttPacket/mod.d.ts +21 -103
  170. package/dist/mqttPacket/mod.d.ts.map +1 -1
  171. package/dist/mqttPacket/mod.js +5 -94
  172. package/dist/mqttPacket/mod.js.map +1 -1
  173. package/dist/mqttPacket/pingreq.d.ts +4 -5
  174. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  175. package/dist/mqttPacket/pingreq.js +11 -13
  176. package/dist/mqttPacket/pingreq.js.map +1 -1
  177. package/dist/mqttPacket/pingres.d.ts +4 -5
  178. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  179. package/dist/mqttPacket/pingres.js +11 -13
  180. package/dist/mqttPacket/pingres.js.map +1 -1
  181. package/dist/mqttPacket/protocolLevels.d.ts +11 -6
  182. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
  183. package/dist/mqttPacket/protocolLevels.js +5 -1
  184. package/dist/mqttPacket/protocolLevels.js.map +1 -1
  185. package/dist/mqttPacket/pubblishAcks.d.ts +4 -5
  186. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
  187. package/dist/mqttPacket/pubblishAcks.js +43 -45
  188. package/dist/mqttPacket/pubblishAcks.js.map +1 -1
  189. package/dist/mqttPacket/publish.d.ts +5 -5
  190. package/dist/mqttPacket/publish.d.ts.map +1 -1
  191. package/dist/mqttPacket/publish.js +53 -55
  192. package/dist/mqttPacket/publish.js.map +1 -1
  193. package/dist/mqttPacket/suback.d.ts +4 -5
  194. package/dist/mqttPacket/suback.d.ts.map +1 -1
  195. package/dist/mqttPacket/suback.js +38 -40
  196. package/dist/mqttPacket/suback.js.map +1 -1
  197. package/dist/mqttPacket/subscribe.d.ts +36 -7
  198. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  199. package/dist/mqttPacket/subscribe.js +90 -89
  200. package/dist/mqttPacket/subscribe.js.map +1 -1
  201. package/dist/mqttPacket/types.d.ts +1 -8
  202. package/dist/mqttPacket/types.d.ts.map +1 -1
  203. package/dist/mqttPacket/unsuback.d.ts +4 -5
  204. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  205. package/dist/mqttPacket/unsuback.js +32 -34
  206. package/dist/mqttPacket/unsuback.js.map +1 -1
  207. package/dist/mqttPacket/unsubscribe.d.ts +23 -6
  208. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  209. package/dist/mqttPacket/unsubscribe.js +45 -44
  210. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  211. package/dist/mqttPacket/validators.d.ts +4 -16
  212. package/dist/mqttPacket/validators.d.ts.map +1 -1
  213. package/dist/mqttPacket/validators.js +5 -26
  214. package/dist/mqttPacket/validators.js.map +1 -1
  215. package/dist/node/tcpClient.d.ts +1 -1
  216. package/dist/node/tcpClient.d.ts.map +1 -1
  217. package/dist/node/tcpClient.js +12 -7
  218. package/dist/node/tcpClient.js.map +1 -1
  219. package/dist/node/tcpServer.d.ts.map +1 -1
  220. package/dist/node/tcpServer.js +4 -0
  221. package/dist/node/tcpServer.js.map +1 -1
  222. package/dist/node/tlsServer.d.ts +19 -0
  223. package/dist/node/tlsServer.d.ts.map +1 -0
  224. package/dist/node/tlsServer.js +58 -0
  225. package/dist/node/tlsServer.js.map +1 -0
  226. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  227. package/dist/node/wrapNodeSocket.js +6 -28
  228. package/dist/node/wrapNodeSocket.js.map +1 -1
  229. package/dist/persistence/basicPersistence.d.ts +36 -0
  230. package/dist/persistence/basicPersistence.d.ts.map +1 -0
  231. package/dist/persistence/basicPersistence.js +306 -0
  232. package/dist/persistence/basicPersistence.js.map +1 -0
  233. package/dist/persistence/deps.d.ts +3 -2
  234. package/dist/persistence/deps.d.ts.map +1 -1
  235. package/dist/persistence/deps.js +2 -1
  236. package/dist/persistence/deps.js.map +1 -1
  237. package/dist/persistence/memory/memoryPersistence.d.ts +6 -23
  238. package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
  239. package/dist/persistence/memory/memoryPersistence.js +12 -115
  240. package/dist/persistence/memory/memoryPersistence.js.map +1 -1
  241. package/dist/persistence/memory/memoryStorage.d.ts +45 -0
  242. package/dist/persistence/memory/memoryStorage.d.ts.map +1 -0
  243. package/dist/persistence/memory/memoryStorage.js +143 -0
  244. package/dist/persistence/memory/memoryStorage.js.map +1 -0
  245. package/dist/persistence/mod.d.ts +3 -3
  246. package/dist/persistence/mod.d.ts.map +1 -1
  247. package/dist/persistence/mod.js +6 -1
  248. package/dist/persistence/mod.js.map +1 -1
  249. package/dist/persistence/persistence.d.ts +44 -69
  250. package/dist/persistence/persistence.d.ts.map +1 -1
  251. package/dist/persistence/persistence.js +1 -2
  252. package/dist/persistence/persistence.js.map +1 -1
  253. package/dist/persistence/sqlite/sqliteDatabase.d.ts +46 -0
  254. package/dist/persistence/sqlite/sqliteDatabase.d.ts.map +1 -0
  255. package/dist/persistence/sqlite/sqliteDatabase.js +215 -0
  256. package/dist/persistence/sqlite/sqliteDatabase.js.map +1 -0
  257. package/dist/persistence/sqlite/sqlitePersistence.d.ts +16 -0
  258. package/dist/persistence/sqlite/sqlitePersistence.d.ts.map +1 -0
  259. package/dist/persistence/sqlite/sqlitePersistence.js +29 -0
  260. package/dist/persistence/sqlite/sqlitePersistence.js.map +1 -0
  261. package/dist/persistence/sqlite/sqliteStorage.d.ts +36 -0
  262. package/dist/persistence/sqlite/sqliteStorage.d.ts.map +1 -0
  263. package/dist/persistence/sqlite/sqliteStorage.js +194 -0
  264. package/dist/persistence/sqlite/sqliteStorage.js.map +1 -0
  265. package/dist/persistence/storage.d.ts +38 -0
  266. package/dist/persistence/storage.d.ts.map +1 -0
  267. package/dist/persistence/storage.js +5 -0
  268. package/dist/persistence/storage.js.map +1 -0
  269. package/dist/server/config.d.ts +47 -0
  270. package/dist/server/config.d.ts.map +1 -0
  271. package/dist/server/config.js +41 -0
  272. package/dist/server/config.js.map +1 -0
  273. package/dist/server/context.d.ts +198 -24
  274. package/dist/server/context.d.ts.map +1 -1
  275. package/dist/server/context.js +432 -53
  276. package/dist/server/context.js.map +1 -1
  277. package/dist/server/deps.d.ts +5 -6
  278. package/dist/server/deps.d.ts.map +1 -1
  279. package/dist/server/deps.js +2 -2
  280. package/dist/server/deps.js.map +1 -1
  281. package/dist/server/handlers/completeConnect.d.ts +8 -0
  282. package/dist/server/handlers/completeConnect.d.ts.map +1 -0
  283. package/dist/server/handlers/completeConnect.js +74 -0
  284. package/dist/server/handlers/completeConnect.js.map +1 -0
  285. package/dist/server/handlers/handleAuth.d.ts +9 -0
  286. package/dist/server/handlers/handleAuth.d.ts.map +1 -0
  287. package/dist/server/handlers/handleAuth.js +69 -0
  288. package/dist/server/handlers/handleAuth.js.map +1 -0
  289. package/dist/server/handlers/handleConnect.d.ts +2 -4
  290. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  291. package/dist/server/handlers/handleConnect.js +140 -67
  292. package/dist/server/handlers/handleConnect.js.map +1 -1
  293. package/dist/server/handlers/handleDisconnect.d.ts +1 -1
  294. package/dist/server/handlers/handleDisconnect.d.ts.map +1 -1
  295. package/dist/server/handlers/handleDisconnect.js +3 -3
  296. package/dist/server/handlers/handleDisconnect.js.map +1 -1
  297. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  298. package/dist/server/handlers/handlePacket.js +19 -6
  299. package/dist/server/handlers/handlePacket.js.map +1 -1
  300. package/dist/server/handlers/handlePuback.d.ts +1 -3
  301. package/dist/server/handlers/handlePuback.d.ts.map +1 -1
  302. package/dist/server/handlers/handlePuback.js +2 -8
  303. package/dist/server/handlers/handlePuback.js.map +1 -1
  304. package/dist/server/handlers/handlePubcomp.d.ts +1 -1
  305. package/dist/server/handlers/handlePubcomp.d.ts.map +1 -1
  306. package/dist/server/handlers/handlePubcomp.js +2 -4
  307. package/dist/server/handlers/handlePubcomp.js.map +1 -1
  308. package/dist/server/handlers/handlePublish.d.ts +1 -1
  309. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  310. package/dist/server/handlers/handlePublish.js +149 -45
  311. package/dist/server/handlers/handlePublish.js.map +1 -1
  312. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  313. package/dist/server/handlers/handlePubrec.js +2 -3
  314. package/dist/server/handlers/handlePubrec.js.map +1 -1
  315. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  316. package/dist/server/handlers/handlePubrel.js +6 -2
  317. package/dist/server/handlers/handlePubrel.js.map +1 -1
  318. package/dist/server/handlers/handleSubscribe.d.ts +1 -6
  319. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  320. package/dist/server/handlers/handleSubscribe.js +99 -38
  321. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  322. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  323. package/dist/server/handlers/handleUnsubscribe.js +19 -4
  324. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  325. package/dist/server/mod.d.ts +3 -3
  326. package/dist/server/mod.d.ts.map +1 -1
  327. package/dist/server/mod.js +1 -1
  328. package/dist/server/mod.js.map +1 -1
  329. package/dist/server/server.d.ts +29 -6
  330. package/dist/server/server.d.ts.map +1 -1
  331. package/dist/server/server.js +84 -15
  332. package/dist/server/server.js.map +1 -1
  333. package/dist/socket/socket.d.ts +11 -9
  334. package/dist/socket/socket.d.ts.map +1 -1
  335. package/dist/socket/socket.js +66 -18
  336. package/dist/socket/socket.js.map +1 -1
  337. package/dist/timer/timer.d.ts +32 -0
  338. package/dist/timer/timer.d.ts.map +1 -1
  339. package/dist/timer/timer.js +32 -0
  340. package/dist/timer/timer.js.map +1 -1
  341. package/dist/trie/trie.d.ts +10 -5
  342. package/dist/trie/trie.d.ts.map +1 -1
  343. package/dist/trie/trie.js +61 -41
  344. package/dist/trie/trie.js.map +1 -1
  345. package/dist/utils/assert.d.ts.map +1 -1
  346. package/dist/utils/{BufferedAsyncIterable.d.ts → bufferedAsyncIterable.d.ts} +1 -1
  347. package/dist/utils/bufferedAsyncIterable.d.ts.map +1 -0
  348. package/dist/utils/{BufferedAsyncIterable.js → bufferedAsyncIterable.js} +1 -1
  349. package/dist/utils/bufferedAsyncIterable.js.map +1 -0
  350. package/dist/utils/deferred.d.ts.map +1 -1
  351. package/dist/utils/deferred.js.map +1 -1
  352. package/dist/utils/getOrInsertPolyFill.d.ts +2 -0
  353. package/dist/utils/getOrInsertPolyFill.d.ts.map +1 -0
  354. package/dist/utils/getOrInsertPolyFill.js +12 -0
  355. package/dist/utils/getOrInsertPolyFill.js.map +1 -0
  356. package/dist/utils/logger.d.ts +40 -3
  357. package/dist/utils/logger.d.ts.map +1 -1
  358. package/dist/utils/logger.js +53 -7
  359. package/dist/utils/logger.js.map +1 -1
  360. package/dist/utils/mod.d.ts +6 -1
  361. package/dist/utils/mod.d.ts.map +1 -1
  362. package/dist/utils/mod.js +5 -1
  363. package/dist/utils/mod.js.map +1 -1
  364. package/dist/utils/outboundTopicAliasManager.d.ts +52 -0
  365. package/dist/utils/outboundTopicAliasManager.d.ts.map +1 -0
  366. package/dist/utils/outboundTopicAliasManager.js +74 -0
  367. package/dist/utils/outboundTopicAliasManager.js.map +1 -0
  368. package/dist/utils/queue.d.ts.map +1 -1
  369. package/dist/utils/topicFilter.d.ts +32 -0
  370. package/dist/utils/topicFilter.d.ts.map +1 -0
  371. package/dist/utils/topicFilter.js +52 -0
  372. package/dist/utils/topicFilter.js.map +1 -0
  373. package/dist/utils/utils.d.ts +2 -0
  374. package/dist/utils/utils.d.ts.map +1 -1
  375. package/dist/utils/utils.js +2 -0
  376. package/dist/utils/utils.js.map +1 -1
  377. package/dist/utils/validators.d.ts +34 -0
  378. package/dist/utils/validators.d.ts.map +1 -0
  379. package/dist/utils/validators.js +61 -0
  380. package/dist/utils/validators.js.map +1 -0
  381. package/dist/web/webSocketStream.d.ts +29 -0
  382. package/dist/web/webSocketStream.d.ts.map +1 -0
  383. package/dist/web/webSocketStream.js +69 -0
  384. package/dist/web/webSocketStream.js.map +1 -0
  385. package/dist/web/wrapWebSocket.d.ts +12 -0
  386. package/dist/web/wrapWebSocket.d.ts.map +1 -0
  387. package/dist/web/wrapWebSocket.js +41 -0
  388. package/dist/web/wrapWebSocket.js.map +1 -0
  389. package/dist/web/wsClient.d.ts +7 -0
  390. package/dist/web/wsClient.d.ts.map +1 -0
  391. package/dist/web/wsClient.js +22 -0
  392. package/dist/web/wsClient.js.map +1 -0
  393. package/dist/web/wsClient.test.d.ts +2 -0
  394. package/dist/web/wsClient.test.d.ts.map +1 -0
  395. package/dist/web/wsClient.test.js +20 -0
  396. package/dist/web/wsClient.test.js.map +1 -0
  397. package/examples/authHandler.test.ts +164 -0
  398. package/examples/mqtt.test.ts +89 -0
  399. package/examples/mqtts.test.ts +100 -0
  400. package/examples/webSocket.test.ts +94 -0
  401. package/mqttConn/mqttConn.test.ts +9 -9
  402. package/mqttConn/mqttConn.ts +76 -44
  403. package/mqttPacket/Properties.ts +6 -3
  404. package/mqttPacket/ReasonCode.ts +2 -1
  405. package/mqttPacket/auth.test.ts +1 -1
  406. package/mqttPacket/auth.ts +41 -48
  407. package/mqttPacket/codec.ts +146 -0
  408. package/mqttPacket/connack.ts +57 -68
  409. package/mqttPacket/connect.test.ts +2 -2
  410. package/mqttPacket/connect.ts +175 -182
  411. package/mqttPacket/decoder.test.ts +0 -39
  412. package/mqttPacket/decoder.ts +8 -35
  413. package/mqttPacket/disconnect.ts +57 -68
  414. package/mqttPacket/encoder.ts +5 -40
  415. package/mqttPacket/mod.ts +48 -200
  416. package/mqttPacket/pingreq.ts +21 -27
  417. package/mqttPacket/pingres.ts +21 -27
  418. package/mqttPacket/protocolLevels.ts +12 -7
  419. package/mqttPacket/pubblishAcks.ts +56 -70
  420. package/mqttPacket/publish.ts +67 -74
  421. package/mqttPacket/suback.ts +48 -58
  422. package/mqttPacket/subscribe.ts +141 -117
  423. package/mqttPacket/types.ts +1 -9
  424. package/mqttPacket/unsuback.ts +46 -58
  425. package/mqttPacket/unsubscribe.ts +74 -63
  426. package/mqttPacket/validators.ts +5 -31
  427. package/node/socket-node-stream.test.ts +322 -0
  428. package/node/socket-node-stream.ts +174 -0
  429. package/node/tcpClient.test.ts +70 -0
  430. package/node/tcpClient.ts +13 -12
  431. package/node/tcpServer.test.ts +24 -20
  432. package/node/tcpServer.ts +6 -0
  433. package/node/tlsServer.test.ts +94 -0
  434. package/node/tlsServer.ts +81 -0
  435. package/node/wrapNodeSocket.ts +7 -30
  436. package/package.json +72 -44
  437. package/persistence/basicPersistence.ts +495 -0
  438. package/persistence/deps.ts +11 -1
  439. package/persistence/memory/memoryPersistence.ts +12 -153
  440. package/persistence/memory/memoryStorage.ts +232 -0
  441. package/persistence/mod.ts +4 -9
  442. package/persistence/persistence.test.ts +24 -0
  443. package/persistence/persistence.testing.ts +1324 -0
  444. package/persistence/persistence.ts +111 -67
  445. package/persistence/sqlite/sqliteDatabase.ts +294 -0
  446. package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
  447. package/persistence/sqlite/sqlitePersistence.ts +36 -0
  448. package/persistence/sqlite/sqliteStorage.ts +324 -0
  449. package/persistence/storage.ts +84 -0
  450. package/server/config.ts +65 -0
  451. package/server/context.ts +658 -74
  452. package/server/deps.ts +25 -5
  453. package/server/handlers/completeConnect.ts +93 -0
  454. package/server/handlers/duplicate.test.ts +196 -0
  455. package/server/handlers/handleAuth.test.ts +225 -0
  456. package/server/handlers/handleAuth.ts +88 -0
  457. package/server/handlers/handleConnect.test.ts +589 -0
  458. package/server/handlers/handleConnect.ts +201 -86
  459. package/server/handlers/handleConnect.version.test.ts +108 -0
  460. package/server/handlers/handleDisconnect.test.ts +56 -0
  461. package/server/handlers/handleDisconnect.ts +3 -3
  462. package/server/handlers/handlePacket.test.ts +24 -0
  463. package/server/handlers/handlePacket.ts +30 -8
  464. package/server/handlers/handlePingreq.test.ts +29 -0
  465. package/server/handlers/handlePuback.test.ts +28 -0
  466. package/server/handlers/handlePuback.ts +5 -8
  467. package/server/handlers/handlePubcomp.test.ts +28 -0
  468. package/server/handlers/handlePubcomp.ts +5 -4
  469. package/server/handlers/handlePublish.test.ts +471 -0
  470. package/server/handlers/handlePublish.ts +189 -35
  471. package/server/handlers/handlePubrec.test.ts +28 -0
  472. package/server/handlers/handlePubrec.ts +2 -3
  473. package/server/handlers/handlePubrel.test.ts +74 -0
  474. package/server/handlers/handlePubrel.ts +12 -2
  475. package/server/handlers/handleSubscribe.test.ts +971 -0
  476. package/server/handlers/handleSubscribe.ts +158 -39
  477. package/server/handlers/handleUnsubscribe.test.ts +79 -0
  478. package/server/handlers/handleUnsubscribe.ts +29 -5
  479. package/server/handlers/keepalive.test.ts +132 -0
  480. package/server/handlers/session.persistence.test.ts +194 -0
  481. package/server/handlers/will.delivery.test.ts +221 -0
  482. package/server/mod.ts +4 -3
  483. package/server/preconnect.test.ts +151 -0
  484. package/server/server.ts +115 -17
  485. package/socket/socket.test.ts +91 -0
  486. package/socket/socket.ts +81 -34
  487. package/timer/timer.test.ts +4 -7
  488. package/timer/timer.ts +36 -0
  489. package/tools/benchmarks/receiver.ts +51 -0
  490. package/tools/benchmarks/sender.ts +48 -0
  491. package/tools/benchmarks/utils.ts +31 -0
  492. package/tools/mqtt-compat/README.md +130 -0
  493. package/tools/mqtt-compat/broker.ts +52 -0
  494. package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
  495. package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
  496. package/trie/trie.test.ts +9 -1
  497. package/trie/trie.ts +70 -45
  498. package/utils/bufferedAsyncIterable.test.ts +92 -0
  499. package/utils/deferred.test.ts +36 -0
  500. package/utils/deferred.ts +0 -1
  501. package/utils/getOrInsertPolyFill.ts +12 -0
  502. package/utils/logger.test.ts +189 -0
  503. package/utils/logger.ts +62 -7
  504. package/utils/mod.ts +15 -1
  505. package/utils/outboundTopicAliasManager.ts +100 -0
  506. package/utils/queue.test.ts +61 -0
  507. package/utils/topicFilter.test.ts +63 -0
  508. package/utils/topicFilter.ts +61 -0
  509. package/utils/utils.ts +3 -0
  510. package/utils/validators.ts +67 -0
  511. package/web/webSocketStream.ts +97 -0
  512. package/web/wrapWebSocket.ts +52 -0
  513. package/web/wsClient.test.ts +26 -0
  514. package/web/wsClient.ts +25 -0
  515. package/benchmarks/receiver.ts +0 -35
  516. package/benchmarks/sender.ts +0 -32
  517. package/benchmarks/utils.ts +0 -9
  518. package/dev_utils/dummyConn.ts +0 -110
  519. package/dev_utils/socketPair.ts +0 -85
  520. package/dist/persistence/store.d.ts +0 -14
  521. package/dist/persistence/store.d.ts.map +0 -1
  522. package/dist/persistence/store.js +0 -2
  523. package/dist/persistence/store.js.map +0 -1
  524. package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
  525. package/dist/utils/BufferedAsyncIterable.js.map +0 -1
  526. package/examples/tcpServer.test.ts +0 -148
  527. package/persistence/memory/memoryPersistence.test.ts +0 -156
  528. package/persistence/store.ts +0 -16
  529. package/server/test/handleConnect.test.ts +0 -122
  530. package/server/test/test-handlers.ts +0 -53
  531. /package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +0 -0
@@ -0,0 +1,174 @@
1
+ import type { Duplex } from "node:stream";
2
+
3
+ export type SockAddr = NetAddr | UnixAddr | VsockAddr;
4
+ export interface NetAddr {
5
+ transport: "tcp" | "udp";
6
+ hostname: string;
7
+ port: number;
8
+ }
9
+ export interface UnixAddr {
10
+ transport: "unix" | "unixpacket";
11
+ path: string;
12
+ }
13
+ export interface VsockAddr {
14
+ transport: "vsock";
15
+ cid: number;
16
+ port: number;
17
+ }
18
+
19
+ export type SockConn = {
20
+ stream: Duplex;
21
+ close: () => void;
22
+ localAddr?: SockAddr;
23
+ remoteAddr?: SockAddr;
24
+ };
25
+
26
+ export class Conn {
27
+ private stream: Duplex;
28
+ private closed: boolean;
29
+ private closer: () => void;
30
+ public remoteAddr: SockAddr | undefined;
31
+ private leftover: Uint8Array = new Uint8Array(0);
32
+
33
+ // Store bound event listeners so we can cleanly remove them later
34
+ private onStreamClose = () => {
35
+ this.closed = true;
36
+ };
37
+ private onStreamError = () => {
38
+ this.closed = true;
39
+ };
40
+
41
+ constructor(sockConn: SockConn) {
42
+ this.stream = sockConn.stream;
43
+ this.closed = false;
44
+ this.closer = sockConn.close;
45
+ this.remoteAddr = sockConn.remoteAddr;
46
+
47
+ // Attach listeners to update internal state on stream termination
48
+ this.stream.on("close", this.onStreamClose);
49
+ this.stream.on("error", this.onStreamError);
50
+ }
51
+
52
+ async read(length: number): Promise<Uint8Array | null> {
53
+ if (this.closed || length < 0) {
54
+ return null;
55
+ }
56
+
57
+ if (length === 0) {
58
+ return new Uint8Array(0);
59
+ }
60
+
61
+ const result = new Uint8Array(length);
62
+ let bytesAccumulated = 0;
63
+
64
+ // 1. Process leftover data from the previous read operation
65
+ if (this.leftover.byteLength > 0) {
66
+ const take = Math.min(this.leftover.byteLength, length);
67
+ result.set(this.leftover.subarray(0, take), bytesAccumulated);
68
+ bytesAccumulated += take;
69
+ this.leftover = this.leftover.subarray(take);
70
+ }
71
+
72
+ // 2. Loop until the requested number of bytes is accumulated
73
+ while (bytesAccumulated < length) {
74
+ if (this.closed || !this.stream.readable) {
75
+ break;
76
+ }
77
+
78
+ const chunk = this.stream.read();
79
+ if (chunk === null) {
80
+ await new Promise<void>((resolve) => {
81
+ const cleanup = () => {
82
+ this.stream.off("readable", onEvent);
83
+ this.stream.off("end", onEvent);
84
+ this.stream.off("error", onEvent);
85
+ this.stream.off("close", onEvent);
86
+ };
87
+ const onEvent = () => {
88
+ cleanup();
89
+ resolve();
90
+ };
91
+
92
+ this.stream.on("readable", onEvent);
93
+ this.stream.on("end", onEvent);
94
+ this.stream.on("error", onEvent);
95
+ this.stream.on("close", onEvent);
96
+ });
97
+
98
+ continue;
99
+ }
100
+
101
+ // 3. Process the retrieved chunk
102
+ const chunkLength = chunk.byteLength;
103
+ const needed = length - bytesAccumulated;
104
+
105
+ if (chunkLength <= needed) {
106
+ result.set(chunk, bytesAccumulated);
107
+ bytesAccumulated += chunkLength;
108
+ } else {
109
+ result.set(chunk.subarray(0, needed), bytesAccumulated);
110
+ bytesAccumulated += needed;
111
+ this.leftover = chunk.subarray(needed);
112
+ }
113
+ }
114
+
115
+ if (bytesAccumulated < length) {
116
+ return null;
117
+ }
118
+
119
+ return result;
120
+ }
121
+
122
+ write(data: Uint8Array): Promise<number> {
123
+ if (this.closed || !this.stream.writable) {
124
+ return Promise.reject(new Error("Stream is closed or not writable"));
125
+ }
126
+
127
+ return new Promise((resolve, reject) => {
128
+ // 1. Fire the write command and catch any immediate/async errors via the callback
129
+ const canWriteMore = this.stream.write(data, (err) => {
130
+ if (err) {
131
+ reject(err);
132
+ }
133
+ });
134
+
135
+ // 2. Determine when to resolve based on the return value of write()
136
+ if (canWriteMore) {
137
+ // If the buffer is not full, we can resolve immediately
138
+ resolve(data.length);
139
+ } else {
140
+ // If backpressure is triggered, we must wait for the 'drain' event
141
+ this.stream.once("drain", () => {
142
+ resolve(data.length);
143
+ });
144
+ }
145
+ });
146
+ }
147
+
148
+ close() {
149
+ if (!this.closed) {
150
+ this.closed = true;
151
+
152
+ // Clean up permanent event listeners to prevent memory leaks
153
+ this.stream.off("close", this.onStreamClose);
154
+ this.stream.off("error", this.onStreamError);
155
+
156
+ // Safely destroy the stream first, then trigger the closer callback
157
+ try {
158
+ this.stream.destroy();
159
+ // deno-coverage-ignore
160
+ } catch (_) {
161
+ // Suppress stream destruction errors
162
+ // deno-coverage-ignore
163
+ }
164
+
165
+ try {
166
+ this.closer();
167
+ // deno-coverage-ignore
168
+ } catch (_) {
169
+ // Prevent closer failures from crashing the thread
170
+ // deno-coverage-ignore
171
+ }
172
+ }
173
+ }
174
+ }
@@ -0,0 +1,70 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+ import { getFileData, TcpClient } from "./tcpClient.ts";
7
+
8
+ // most client testing is already done in tcpServer.test.ts
9
+
10
+ test("Test getFileData - valid file, empty file and undefined", async () => {
11
+ // Create a unique temporary directory using native NodeJS path/fs utilities
12
+ const tempDir = await mkdtemp(join(tmpdir(), "mqtt-client-test-"));
13
+
14
+ const validFilePath = join(tempDir, "valid.txt");
15
+ const emptyFilePath = join(tempDir, "empty.txt");
16
+ const testContent = "Hello MQTT World!";
17
+
18
+ try {
19
+ // 1. Test with a valid file containing data
20
+ await writeFile(validFilePath, testContent, "utf-8");
21
+ const result = await getFileData(validFilePath);
22
+ assert.strictEqual(
23
+ result,
24
+ testContent,
25
+ "Should return the correct content of the file",
26
+ );
27
+
28
+ // 2. Test with an empty file
29
+ await writeFile(emptyFilePath, "", "utf-8");
30
+ const emptyResult = await getFileData(emptyFilePath);
31
+ assert.strictEqual(
32
+ emptyResult,
33
+ undefined,
34
+ "Should return undefined if the file is empty",
35
+ );
36
+ } finally {
37
+ // Clean up the temporary directory and all its contents
38
+ await rm(tempDir, { recursive: true, force: true });
39
+ }
40
+
41
+ // 3. Test with undefined filename
42
+ const undefinedResult = await getFileData(undefined);
43
+ assert.strictEqual(
44
+ undefinedResult,
45
+ undefined,
46
+ "Should return undefined immediately if filename is undefined",
47
+ );
48
+ });
49
+
50
+ test("Test createConn - unsupported protocol", async () => {
51
+ const client = new TcpClient();
52
+
53
+ // Use an unsupported protocol like 'ftp://' to trigger the throw in createConn
54
+ const invalidParams = {
55
+ url: new URL("ftp://localhost:1883"),
56
+ numberOfRetries: 0,
57
+ };
58
+
59
+ // Assert that connect rejects with the specific "Unsupported protocol" error
60
+ await assert.rejects(
61
+ async () => {
62
+ await client.connect(invalidParams);
63
+ },
64
+ {
65
+ name: "Error",
66
+ message: "Unsupported protocol: ftp:",
67
+ },
68
+ "Should throw an error when an unsupported protocol is provided",
69
+ );
70
+ });
package/node/tcpClient.ts CHANGED
@@ -65,9 +65,10 @@ export class TcpClient extends Client {
65
65
  const opts = {
66
66
  host: hostname,
67
67
  port,
68
- secureContext: (ca || key || cert)
69
- ? tls.createSecureContext({ ca, cert, key })
70
- : undefined,
68
+ ca,
69
+ key,
70
+ cert,
71
+ minVersion: "TLSv1.3" as const,
71
72
  };
72
73
  logger.debug({ hostname, port, ca, cert });
73
74
  return new Promise((resolve, reject) => {
@@ -82,16 +83,16 @@ export class TcpClient extends Client {
82
83
  });
83
84
  }
84
85
 
85
- protected override createConn(
86
- protocol: string,
87
- hostname: string,
88
- port?: number,
89
- caCerts?: string[],
90
- ): Promise<SockConn> {
91
- // if you need to support alternative connection types just
92
- // overload this method in your subclass
86
+ // overload createConn from the base client class
87
+ protected override createConn(): Promise<SockConn> {
88
+ const { protocol, hostname, port: portStr } = this.connectUrl;
89
+ const port = Number(portStr);
90
+ const caCerts = this.caCerts;
91
+ const cert = this.cert;
92
+ const key = this.key;
93
+
93
94
  if (protocol === "mqtts:") {
94
- return this.connectMQTTS(hostname, port, caCerts);
95
+ return this.connectMQTTS(hostname, port, caCerts, cert, key);
95
96
  }
96
97
  if (protocol === "mqtt:") {
97
98
  return this.connectMQTT(hostname, port);
@@ -3,14 +3,12 @@ import assert from "node:assert/strict";
3
3
  import { TcpClient } from "./tcpClient.ts";
4
4
  import { TcpServer } from "./tcpServer.ts";
5
5
  import { logger, LogLevel } from "../utils/mod.ts";
6
- import type { PublishPacket, QoS } from "../mqttPacket/mod.ts";
6
+ import { delay } from "../dev_utils/mod.ts";
7
+ import type { ProtocolLevel, PublishPacket, QoS } from "../mqttPacket/mod.ts";
7
8
 
8
9
  logger.level(LogLevel.info);
9
- export function sleep(ms: number): Promise<unknown> {
10
- return new Promise((r) => setTimeout(r, ms));
11
- }
12
10
 
13
- test("Test pubSub using client and server", async function () {
11
+ test("Test pubSub using client and server", async () => {
14
12
  const server = new TcpServer({ port: 0 }, {});
15
13
  server.start();
16
14
 
@@ -52,17 +50,17 @@ test("Test pubSub using client and server", async function () {
52
50
  });
53
51
 
54
52
  // the IIFE ensures message reception runs in parallel
55
- logger.verbose(`Start receiving`);
53
+ logger.verbose("Start receiving");
56
54
  const received: PublishPacket[] = [];
57
- (async function () {
55
+ (async () => {
58
56
  for await (const item of client.messages()) {
59
- logger.verbose(`Receiving: ${item.topic} -- ${item.qos}`);
57
+ logger.verbose("Receiving:", item.topic, "--", item.qos);
60
58
  received.push(item);
61
59
  }
62
60
  })();
63
61
  // end of IIFE
64
62
  for (const item of publishSet) {
65
- logger.verbose(`Publishing: ${item.topic} -- ${item.qos}`);
63
+ logger.verbose("Publishing:", item.topic, "--", item.qos);
66
64
  await client.publish({
67
65
  topic: item.topic,
68
66
  qos: item.qos,
@@ -70,24 +68,24 @@ test("Test pubSub using client and server", async function () {
70
68
  });
71
69
  }
72
70
 
73
- await sleep(100);
74
- logger.verbose(`Disconnect client`);
71
+ await delay(100);
72
+ logger.verbose("Disconnect client");
75
73
  await client.disconnect();
76
74
 
77
- logger.verbose(`Check completeness`);
75
+ logger.verbose("Check completeness");
78
76
  for (const item of publishSet) {
79
77
  const found = received.find((f) =>
80
78
  f.topic == item.topic && f.qos === item.qos
81
79
  );
82
- logger.verbose(`Found: ${item.topic} -- ${item.qos}`);
80
+ logger.verbose("Found:", item.topic, "--", item.qos);
83
81
  assert(found, `${item.topic} -- ${item.qos}`);
84
82
  }
85
83
 
86
- logger.verbose(`Stop server`);
84
+ logger.verbose("Stop server");
87
85
  server.stop();
88
86
  });
89
87
 
90
- test("Test subscription persistence after reconnect", async function () {
88
+ test("Test subscription persistence after reconnect", async () => {
91
89
  // Start server
92
90
  const server = new TcpServer({ port: 0 }, {});
93
91
  server.start();
@@ -95,8 +93,14 @@ test("Test subscription persistence after reconnect", async function () {
95
93
  const params = {
96
94
  url: new URL(`mqtt://${server.address}:${server.port}`),
97
95
  numberOfRetries: 0,
96
+ options: {
97
+ protocolLevel: 4 as ProtocolLevel,
98
+ clean: false,
99
+ },
98
100
  };
99
101
 
102
+ logger.verbose("client parameters: ", params);
103
+
100
104
  const client = new TcpClient();
101
105
  const testTopic = "test/topic";
102
106
  const received: PublishPacket[] = [];
@@ -111,7 +115,7 @@ test("Test subscription persistence after reconnect", async function () {
111
115
  });
112
116
 
113
117
  // Start receiving messages
114
- (async function () {
118
+ (async () => {
115
119
  for await (const item of client.messages()) {
116
120
  received.push(item);
117
121
  }
@@ -119,11 +123,11 @@ test("Test subscription persistence after reconnect", async function () {
119
123
 
120
124
  // Disconnect client
121
125
  await client.disconnect();
122
- await sleep(100);
126
+ await delay(100);
123
127
 
124
128
  // Reconnect client
125
129
  await client.connect(params);
126
- await sleep(100);
130
+ await delay(100);
127
131
 
128
132
  // Publish test message
129
133
  await client.publish({
@@ -132,8 +136,8 @@ test("Test subscription persistence after reconnect", async function () {
132
136
  payload: new Uint8Array([0x01]),
133
137
  });
134
138
 
135
- await sleep(100);
136
- logger.verbose(`Disconnect client`);
139
+ await delay(100);
140
+ logger.verbose("Disconnect client");
137
141
  await client.disconnect();
138
142
 
139
143
  // Verify message was received
package/node/tcpServer.ts CHANGED
@@ -40,21 +40,26 @@ export class TcpServer {
40
40
  return;
41
41
  }
42
42
  stop() {
43
+ this.mqttServer.close();
43
44
  this.server?.close();
44
45
  }
45
46
 
46
47
  get port() {
47
48
  const address = this.server?.address();
49
+ // deno-coverage-ignore-start
48
50
  if (typeof address === "object" && address !== null) {
49
51
  return address?.port;
50
52
  }
51
53
  return this.serverOptions?.port;
54
+ // deno-coverage-ignore-stop
52
55
  }
53
56
 
54
57
  get address() {
55
58
  const addressResult = this.server?.address();
59
+ // deno-coverage-ignore-start
56
60
  if (typeof addressResult === "object") {
57
61
  const address = addressResult?.address;
62
+
58
63
  if (address === "::") {
59
64
  return "localhost";
60
65
  }
@@ -65,4 +70,5 @@ export class TcpServer {
65
70
  }
66
71
  return addressResult;
67
72
  }
73
+ // deno-coverage-ignore-stop
68
74
  }
@@ -0,0 +1,94 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { TcpClient } from "./tcpClient.ts";
4
+ import { TlsServer } from "./tlsServer.ts";
5
+ import { logger, LogLevel } from "../utils/mod.ts";
6
+ import type { PublishPacket, QoS } from "../mqttPacket/mod.ts";
7
+ import { delay, generateLocalhostCerts } from "../dev_utils/mod.ts";
8
+
9
+ logger.level(LogLevel.info);
10
+
11
+ const { key, cert, caCert } = generateLocalhostCerts();
12
+
13
+ test("Test pubSub using client and server", async () => {
14
+ const server = new TlsServer({ port: 0, key, cert }, {});
15
+ server.start();
16
+
17
+ assert.deepStrictEqual(
18
+ server.port !== undefined,
19
+ true,
20
+ "server runs a a random port",
21
+ );
22
+ logger.verbose("server running on: ", {
23
+ port: server.port,
24
+ address: server.address,
25
+ });
26
+
27
+ const params = {
28
+ url: new URL(`mqtts://${server.address}:${server.port}`),
29
+ numberOfRetries: 0,
30
+ caCerts: [caCert],
31
+ };
32
+
33
+ logger.verbose("client parameters: ", params);
34
+
35
+ const client = new TcpClient();
36
+
37
+ await client.connect(params);
38
+ assert(true, "Client connected to server");
39
+
40
+ const publishSet: { topic: string; qos: QoS }[] = [
41
+ { topic: "t0@q0", qos: 0 },
42
+ { topic: "t1@q0", qos: 0 },
43
+ { topic: "t2@q0", qos: 0 },
44
+ { topic: "t0@q1", qos: 1 },
45
+ { topic: "t1@q1", qos: 1 },
46
+ { topic: "t2@q1", qos: 1 },
47
+ { topic: "t0@q2", qos: 2 },
48
+ { topic: "t1@q2", qos: 2 },
49
+ { topic: "t2@q2", qos: 2 },
50
+ ];
51
+
52
+ const subscriptions = publishSet.map((item) => ({
53
+ topicFilter: item.topic,
54
+ qos: item.qos,
55
+ }));
56
+ await client.subscribe({
57
+ subscriptions,
58
+ });
59
+
60
+ // the IIFE ensures message reception runs in parallel
61
+ logger.verbose("Start receiving");
62
+ const received: PublishPacket[] = [];
63
+ (async () => {
64
+ for await (const item of client.messages()) {
65
+ logger.verbose("Receiving:", item.topic, "--", item.qos);
66
+ received.push(item);
67
+ }
68
+ })();
69
+ // end of IIFE
70
+ for (const item of publishSet) {
71
+ logger.verbose("Publishing:", item.topic, "--", item.qos);
72
+ await client.publish({
73
+ topic: item.topic,
74
+ qos: item.qos,
75
+ payload: new Uint8Array([0x01]),
76
+ });
77
+ }
78
+
79
+ await delay(100);
80
+ logger.verbose("Disconnect client");
81
+ await client.disconnect();
82
+
83
+ logger.verbose("Check completeness");
84
+ for (const item of publishSet) {
85
+ const found = received.find((f) =>
86
+ f.topic == item.topic && f.qos === item.qos
87
+ );
88
+ logger.verbose("Found:", item.topic, "--", item.qos);
89
+ assert(found, `${item.topic} -- ${item.qos}`);
90
+ }
91
+
92
+ logger.verbose("Stop server");
93
+ server.stop();
94
+ });
@@ -0,0 +1,81 @@
1
+ /*
2
+ * This module provides a NodeJS specific implementation of a tls socket listener
3
+ * it uses the platform agnostic MqttServer class
4
+ * @module
5
+ */
6
+ import type { Server } from "node:net";
7
+ import { createServer } from "node:tls";
8
+ import type { MqttServerOptions } from "../server/mod.ts";
9
+ import { MqttServer } from "../server/mod.ts";
10
+ import { wrapNodeSocket } from "./wrapNodeSocket.ts";
11
+
12
+ type ServerOptions = {
13
+ hostname?: string;
14
+ port?: number;
15
+ key: string;
16
+ cert: string;
17
+ };
18
+
19
+ /*
20
+ * TCP server that wraps a MqttServer, see demoServer.ts in the /bin folder
21
+ */
22
+ export class TlsServer {
23
+ private mqttServer: MqttServer;
24
+ private server?: Server;
25
+ private serverOptions;
26
+
27
+ constructor(serverOptions: ServerOptions, mqttOptions: MqttServerOptions) {
28
+ this.mqttServer = new MqttServer(mqttOptions);
29
+ this.serverOptions = serverOptions;
30
+ }
31
+
32
+ async start() {
33
+ const tlsOptions = {
34
+ minVersion: "TLSv1.3" as const,
35
+ key: this.serverOptions.key,
36
+ cert: this.serverOptions.cert,
37
+ };
38
+
39
+ this.server = createServer(
40
+ tlsOptions,
41
+ (sock) => this.mqttServer.serve(wrapNodeSocket(sock)),
42
+ );
43
+ const isListening = new Promise((resolve) => {
44
+ this.server?.on("listening", () => {
45
+ resolve(true);
46
+ });
47
+ });
48
+ this.server.listen(this.serverOptions.port, this.serverOptions.hostname);
49
+ await isListening;
50
+ return;
51
+ }
52
+ stop() {
53
+ this.mqttServer.close();
54
+ this.server?.close();
55
+ }
56
+
57
+ get port() {
58
+ const address = this.server?.address();
59
+ if (typeof address === "object" && address !== null) {
60
+ return address?.port;
61
+ }
62
+ return this.serverOptions?.port;
63
+ }
64
+
65
+ get address() {
66
+ const addressResult = this.server?.address();
67
+ // deno-coverage-ignore-start
68
+ if (typeof addressResult === "object") {
69
+ const address = addressResult?.address;
70
+ if (address === "::") {
71
+ return "localhost";
72
+ }
73
+ if (address?.includes(":")) {
74
+ return `[${address}]`;
75
+ }
76
+ return address;
77
+ }
78
+ return addressResult;
79
+ }
80
+ // deno-coverage-ignore-stop
81
+ }
@@ -2,7 +2,7 @@
2
2
  * Utility functions for wrapping Node.js sockets into standard web streams.
3
3
  */
4
4
  import type { Socket } from "node:net";
5
- import { Writable } from "node:stream";
5
+ import { Readable, Writable } from "node:stream";
6
6
  import type { NetAddr, SockConn } from "../socket/socket.ts";
7
7
 
8
8
  /**
@@ -10,9 +10,11 @@ import type { NetAddr, SockConn } from "../socket/socket.ts";
10
10
  * @param sock - The Node.js socket to close
11
11
  */
12
12
  function closer(sock: Socket): void {
13
+ // deno-coverage-ignore-start
13
14
  if (!sock.closed) {
14
15
  sock.end();
15
16
  }
17
+ // deno-coverage-ignore-stop
16
18
  }
17
19
 
18
20
  /**
@@ -21,41 +23,16 @@ function closer(sock: Socket): void {
21
23
  * @returns A socket connection object with readable/writable streams and close method
22
24
  */
23
25
  export function wrapNodeSocket(socket: Socket): SockConn {
24
- const readable = new ReadableStream(
25
- {
26
- type: "bytes",
27
- start(controller) {
28
- socket.on("data", (data: Uint8Array<ArrayBuffer>) => {
29
- controller.enqueue(data);
30
- const desiredSize = controller.desiredSize ?? 0;
31
- if (desiredSize <= 0) {
32
- // The internal queue is full, so propagate
33
- // the backpressure signal to the underlying source.
34
- socket.pause();
35
- }
36
- });
37
- socket.on("error", (err: unknown) => controller.error(err));
38
- socket.on("end", () => {
39
- // close the controller
40
- controller.close();
41
- // and unlock the last BYOB read request
42
- controller.byobRequest?.respond(0);
43
- });
44
- },
45
- pull: () => {
46
- socket.resume();
47
- },
48
- cancel: () => {
49
- socket.end();
50
- },
51
- },
52
- );
26
+ const readable = Readable.toWeb(socket);
53
27
  const writable = Writable.toWeb(socket);
28
+
29
+ // deno-coverage-ignore-start
54
30
  const remoteAddr: NetAddr = {
55
31
  hostname: socket.remoteAddress || "",
56
32
  port: socket.remotePort || 0,
57
33
  transport: "tcp",
58
34
  };
35
+ // deno-coverage-ignore-stop
59
36
 
60
37
  const conn: SockConn = {
61
38
  readable: readable as ReadableStream<Uint8Array>,