@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 @@
1
+ {"version":3,"file":"topicFilter.d.ts","sourceRoot":"","sources":["../../utils/topicFilter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAS/D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAWA;AAED,sCAAsC;AACtC,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,MAAM,CAKR"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Converts an MQTT topic filter into a regular expression according to the MQTT specification.
3
+ *
4
+ * This utility escapes standard regex characters to prevent injection or unexpected behavior,
5
+ * and then converts the native MQTT wildcards into their regex equivalents:
6
+ * - `+` (single-level wildcard) becomes `[^/]+` (matches one or more characters except a forward slash)
7
+ * - `#` (multi-level wildcard) becomes an optional matching group `(?:/.*)?` to correctly handle parent levels.
8
+ *
9
+ * @param topicFilter - The MQTT topic filter string to convert (e.g., "home/+/temperature" or "clients/#").
10
+ * @returns A `RegExp` object configured to match topics corresponding to the filter.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const regex = topicFilterToRegExp("home/+/temperature");
15
+ * regex.test("home/livingroom/temperature"); // true
16
+ * regex.test("home/kitchen/lights"); // false
17
+ * ```
18
+ */
19
+ export function topicFilterToRegExp(topicFilter) {
20
+ // RegExp.escape (ES2024+) safely escapes special characters, forcing punctuation into hex formats (\xHH)
21
+ const escaped = RegExp.escape(topicFilter);
22
+ const regexStr = escaped
23
+ .replace(/\\\+/g, "[^/]+") // Replace '+' wildcard globally
24
+ .replace(/(?:\\\/)?\\x23/g, "(?:/.*)?"); // Replace '#' and its optional preceding slash (\/) globally
25
+ return new RegExp(`^${regexStr}$`);
26
+ }
27
+ /**
28
+ * Parses a Topic filter for a "shared subscription" into the share name and the regular Topic Filter
29
+ *
30
+ * @param topicFilter - The MQTT topic filter string to parse (e.g. "$share/sharename/rest/of/topic/filter")).
31
+ * @returns an object that contains the regular topicFilter and he share name (if present)
32
+ */
33
+ export function parseTopicFilter(topicFilter) {
34
+ if (topicFilter.startsWith("$share/")) {
35
+ const nextSlashIndex = topicFilter.indexOf("/", 7);
36
+ if (nextSlashIndex !== -1) {
37
+ return {
38
+ topicFilter: topicFilter.slice(nextSlashIndex + 1),
39
+ shareName: topicFilter.slice(7, nextSlashIndex),
40
+ };
41
+ }
42
+ }
43
+ return { topicFilter, shareName: "" };
44
+ }
45
+ /** the inverse of parseTopicFilter */
46
+ export function joinTopicFilter(topicFilter, shareName) {
47
+ if (shareName !== "") {
48
+ return `$share/${shareName}/${topicFilter}`;
49
+ }
50
+ return topicFilter;
51
+ }
52
+ //# sourceMappingURL=topicFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topicFilter.js","sourceRoot":"","sources":["../../utils/topicFilter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACrD,yGAAyG;IACzG,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,gCAAgC;SAC1D,OAAO,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC,6DAA6D;IAExG,OAAO,IAAI,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAIlD,IAAI,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACnD,IAAI,cAAc,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1B,OAAO;gBACL,WAAW,EAAE,WAAW,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;gBAClD,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC;aAChD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;AACxC,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,eAAe,CAC7B,WAAmB,EACnB,SAAiB;IAEjB,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;QACrB,OAAO,UAAU,SAAS,IAAI,WAAW,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -1,2 +1,4 @@
1
+ import { setTimeout as delay } from "node:timers/promises";
2
+ export { delay };
1
3
  export declare const noop: () => void;
2
4
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../utils/utils.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,IAAI,YAAW,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../utils/utils.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,CAAC;AAEjB,eAAO,MAAM,IAAI,YAAW,CAAC"}
@@ -2,5 +2,7 @@
2
2
  * This file contains utilities used throughout the project too small to
3
3
  * deserve their own dedicated files.
4
4
  */
5
+ import { setTimeout as delay } from "node:timers/promises";
6
+ export { delay };
5
7
  export const noop = () => { };
6
8
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../utils/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../utils/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,CAAC;AAEjB,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Checks for too many topic levels to reduce the risk of Denial of Service
3
+ *
4
+ * @param value - The string to validate.
5
+ * @returns `true` if the string contains more / signs than allowed`.
6
+ */
7
+ export declare function invalidmaxTopicLevels(value: string, maxTopicLevels: number): boolean;
8
+ /**
9
+ * Checks for invalid characters in an MQTT topic name.
10
+ * It cannot contain wildcards (+, #)
11
+ *
12
+ * @param value - The topic name to validate.
13
+ * @returns `true` if the topic is invalid, otherwise `false`.
14
+ */
15
+ export declare function invalidTopic(value: string): boolean;
16
+ /**
17
+ * Checks for MQTT wildcards in a string.
18
+ *
19
+ * @param value - The topic name to validate.
20
+ * @returns `true` if the topic is invalid, otherwise `false`.
21
+ */
22
+ export declare function hasWildcards(value: string): boolean;
23
+ /**
24
+ * Checks for invalid characters and malformed wildcards in an MQTT topic filter.
25
+ *
26
+ * Wildcard rules according to the MQTT specification:
27
+ * - '+' must occupy an entire level (e.g., 'a/+/b' is valid, 'a+/b' is invalid)
28
+ * - '#' must only appear at the very end of the string (e.g., 'a/#' is valid, 'a/#/b' is invalid)
29
+ *
30
+ * @param value - The topic filter to validate.
31
+ * @returns `true` if the topic filter is invalid, otherwise `false`.
32
+ */
33
+ export declare function invalidTopicFilter(value: string): boolean;
34
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../utils/validators.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,GACrB,OAAO,CAST;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAczD"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Checks for too many topic levels to reduce the risk of Denial of Service
3
+ *
4
+ * @param value - The string to validate.
5
+ * @returns `true` if the string contains more / signs than allowed`.
6
+ */
7
+ export function invalidmaxTopicLevels(value, maxTopicLevels) {
8
+ let slashCount = 0;
9
+ for (const char of value) {
10
+ if (char === "/") {
11
+ slashCount++;
12
+ if (slashCount >= maxTopicLevels)
13
+ return true;
14
+ }
15
+ }
16
+ return false;
17
+ }
18
+ /**
19
+ * Checks for invalid characters in an MQTT topic name.
20
+ * It cannot contain wildcards (+, #)
21
+ *
22
+ * @param value - The topic name to validate.
23
+ * @returns `true` if the topic is invalid, otherwise `false`.
24
+ */
25
+ export function invalidTopic(value) {
26
+ return hasWildcards(value);
27
+ }
28
+ /**
29
+ * Checks for MQTT wildcards in a string.
30
+ *
31
+ * @param value - The topic name to validate.
32
+ * @returns `true` if the topic is invalid, otherwise `false`.
33
+ */
34
+ export function hasWildcards(value) {
35
+ // Native .includes() is significantly faster than regular expressions for basic character checks
36
+ return value.includes("+") || value.includes("#");
37
+ }
38
+ /**
39
+ * Checks for invalid characters and malformed wildcards in an MQTT topic filter.
40
+ *
41
+ * Wildcard rules according to the MQTT specification:
42
+ * - '+' must occupy an entire level (e.g., 'a/+/b' is valid, 'a+/b' is invalid)
43
+ * - '#' must only appear at the very end of the string (e.g., 'a/#' is valid, 'a/#/b' is invalid)
44
+ *
45
+ * @param value - The topic filter to validate.
46
+ * @returns `true` if the topic filter is invalid, otherwise `false`.
47
+ */
48
+ export function invalidTopicFilter(value) {
49
+ // Rule 1: A '#' wildcard must NEVER be followed by any other character
50
+ if (/#./.test(value)) {
51
+ return true;
52
+ }
53
+ // Rule 2: A '+' wildcard must be isolated by slashes (or string boundaries).
54
+ // Modern lookbehind (?<=) and lookahead (?=) make this highly readable.
55
+ const malformedPlus = /(?<=[^\/])\+|\+(?=[^\/])/.test(value);
56
+ if (malformedPlus) {
57
+ return true;
58
+ }
59
+ return false;
60
+ }
61
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../utils/validators.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAa,EACb,cAAsB;IAEtB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjB,UAAU,EAAE,CAAC;YACb,IAAI,UAAU,IAAI,cAAc;gBAAE,OAAO,IAAI,CAAC;QAChD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,iGAAiG;IACjG,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,uEAAuE;IACvE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6EAA6E;IAC7E,wEAAwE;IACxE,MAAM,aAAa,GAAG,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Utility functions for wrapping standard WebSockets into standard web streams.
3
+ */
4
+ export interface WebSocketConnection<T extends Uint8Array | string = Uint8Array | string> {
5
+ readable: ReadableStream<T>;
6
+ writable: WritableStream<T>;
7
+ protocol: string;
8
+ extensions: string;
9
+ }
10
+ export interface WebSocketCloseInfo {
11
+ closeCode?: number;
12
+ reason?: string;
13
+ }
14
+ export interface WebSocketStreamOptions {
15
+ protocols?: string[];
16
+ signal?: AbortSignal;
17
+ }
18
+ /**
19
+ * [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) with [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)
20
+ *
21
+ * @see https://web.dev/websocketstream/
22
+ */
23
+ export declare class WebSocketStream<T extends Uint8Array | string = Uint8Array | string> {
24
+ readonly opened: Promise<WebSocketConnection<T>>;
25
+ readonly closed: Promise<WebSocketCloseInfo>;
26
+ readonly close: (closeInfo?: WebSocketCloseInfo) => void;
27
+ constructor(ws: WebSocket, options?: WebSocketStreamOptions);
28
+ }
29
+ //# sourceMappingURL=webSocketStream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webSocketStream.d.ts","sourceRoot":"","sources":["../../web/webSocketStream.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,mBAAmB,CAClC,CAAC,SAAS,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM;IAEnD,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAC5B,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,eAAe,CAC1B,CAAC,SAAS,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM;IAEnD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE7C,QAAQ,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAEzD,YAAY,EAAE,EAAE,SAAS,EAAE,OAAO,GAAE,sBAA2B,EA0D9D;CACF"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Utility functions for wrapping standard WebSockets into standard web streams.
3
+ */
4
+ /**
5
+ * [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) with [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)
6
+ *
7
+ * @see https://web.dev/websocketstream/
8
+ */
9
+ export class WebSocketStream {
10
+ opened;
11
+ closed;
12
+ close;
13
+ constructor(ws, options = {}) {
14
+ if (options.signal?.aborted) {
15
+ throw new DOMException("This operation was aborted", "AbortError");
16
+ }
17
+ const closeWithInfo = ({ closeCode: code, reason } = {}) => ws.close(code, reason);
18
+ this.opened = new Promise((resolve, reject) => {
19
+ ws.onopen = () => {
20
+ resolve({
21
+ readable: new ReadableStream({
22
+ start(controller) {
23
+ ws.onmessage = ({ data }) => {
24
+ if (data instanceof ArrayBuffer) {
25
+ controller.enqueue(new Uint8Array(data));
26
+ }
27
+ else {
28
+ controller.enqueue(data);
29
+ }
30
+ };
31
+ ws.onerror = (e) => controller.error(e);
32
+ },
33
+ cancel: closeWithInfo,
34
+ }),
35
+ writable: new WritableStream({
36
+ write(chunk) {
37
+ if (chunk instanceof Uint8Array) {
38
+ ws.send(chunk.buffer);
39
+ }
40
+ else {
41
+ ws.send(chunk);
42
+ }
43
+ },
44
+ abort() {
45
+ ws.close();
46
+ },
47
+ close: closeWithInfo,
48
+ }),
49
+ protocol: ws.protocol,
50
+ extensions: ws.extensions,
51
+ });
52
+ ws.removeEventListener("error", reject);
53
+ };
54
+ ws.addEventListener("error", reject);
55
+ });
56
+ this.closed = new Promise((resolve, reject) => {
57
+ ws.onclose = ({ code, reason }) => {
58
+ resolve({ closeCode: code, reason });
59
+ ws.removeEventListener("error", reject);
60
+ };
61
+ ws.addEventListener("error", reject);
62
+ });
63
+ if (options.signal) {
64
+ options.signal.onabort = () => ws.close();
65
+ }
66
+ this.close = closeWithInfo;
67
+ }
68
+ }
69
+ //# sourceMappingURL=webSocketStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webSocketStream.js","sourceRoot":"","sources":["../../web/webSocketStream.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqBH;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAGjB,MAAM,CAAkC;IAExC,MAAM,CAA8B;IAEpC,KAAK,CAA2C;IAEzD,YAAY,EAAa,EAAE,OAAO,GAA2B,EAAE;QAC7D,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,YAAY,CAAC,4BAA4B,EAAE,YAAY,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,aAAa,GAAG,CACpB,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAuB,EAAE,EACpD,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAE5B,IAAI,CAAC,MAAM,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5C,EAAE,CAAC,MAAM,GAAG,GAAG,EAAE;gBACf,OAAO,CAAC;oBACN,QAAQ,EAAE,IAAI,cAAc,CAAI;wBAC9B,KAAK,CAAC,UAAU;4BACd,EAAE,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;gCAC1B,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;oCAChC,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,IAAI,CAAM,CAAC,CAAC;gCAChD,CAAC;qCAAM,CAAC;oCACN,UAAU,CAAC,OAAO,CAAC,IAAS,CAAC,CAAC;gCAChC,CAAC;4BACH,CAAC,CAAC;4BACF,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBAC1C,CAAC;wBACD,MAAM,EAAE,aAAa;qBACtB,CAAC;oBACF,QAAQ,EAAE,IAAI,cAAc,CAAI;wBAC9B,KAAK,CAAC,KAAK;4BACT,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;gCAChC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAqB,CAAC,CAAC;4BACvC,CAAC;iCAAM,CAAC;gCACN,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;4BACjB,CAAC;wBACH,CAAC;wBACD,KAAK;4BACH,EAAE,CAAC,KAAK,EAAE,CAAC;wBACb,CAAC;wBACD,KAAK,EAAE,aAAa;qBACrB,CAAC;oBACF,QAAQ,EAAE,EAAE,CAAC,QAAQ;oBACrB,UAAU,EAAE,EAAE,CAAC,UAAU;iBAC1B,CAAC,CAAC;gBACH,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1C,CAAC,CAAC;YACF,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,GAAG,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAChE,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;gBAChC,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACrC,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1C,CAAC,CAAC;YACF,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { SockConn } from "../socket/socket.ts";
2
+ export type HostnamePort = {
3
+ hostname?: string;
4
+ port?: string | number;
5
+ };
6
+ /**
7
+ * Wraps a WebSocketStream socket into a standard web streams-based socket connection
8
+ * @param ws - The WebSocket to wrap
9
+ * @returns A SockConn object
10
+ */
11
+ export declare function wrapWebSocket(ws: WebSocket, remoteAddr?: HostnamePort): Promise<SockConn>;
12
+ //# sourceMappingURL=wrapWebSocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapWebSocket.d.ts","sourceRoot":"","sources":["../../web/wrapWebSocket.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,CAAC;AAYF;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,SAAS,EACb,UAAU,CAAC,EAAE,YAAY,GACxB,OAAO,CAAC,QAAQ,CAAC,CAqBnB"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Utility functions for wrapping WebSocketStream sockets into standard web streams.
3
+ */
4
+ import { WebSocketStream } from "./webSocketStream.js";
5
+ import { logger } from "../utils/logger.js";
6
+ /**
7
+ * Closes a WebSocketStream socket if it is not already closed
8
+ * @param sock - The WebSocketStream socket to close
9
+ */
10
+ async function closer(stream) {
11
+ if (!await stream.closed) {
12
+ stream.close();
13
+ }
14
+ }
15
+ /**
16
+ * Wraps a WebSocketStream socket into a standard web streams-based socket connection
17
+ * @param ws - The WebSocket to wrap
18
+ * @returns A SockConn object
19
+ */
20
+ export async function wrapWebSocket(ws, remoteAddr) {
21
+ ws.binaryType = "arraybuffer";
22
+ const wsstream = new WebSocketStream(ws);
23
+ logger.debug("created wsstream");
24
+ const stream = await wsstream.opened;
25
+ logger.debug("wsstream is opened");
26
+ const readable = stream.readable;
27
+ const writable = stream.writable;
28
+ const { hostname = "localhost", port = 0 } = remoteAddr || {};
29
+ const conn = {
30
+ readable: readable,
31
+ writable: writable,
32
+ close: () => closer(wsstream),
33
+ remoteAddr: {
34
+ hostname,
35
+ port: Number(port),
36
+ transport: "tcp",
37
+ },
38
+ };
39
+ return conn;
40
+ }
41
+ //# sourceMappingURL=wrapWebSocket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapWebSocket.js","sourceRoot":"","sources":["../../web/wrapWebSocket.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAO5C;;;GAGG;AACH,KAAK,UAAU,MAAM,CAAC,MAAuB;IAC3C,IAAI,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAa,EACb,UAAyB;IAEzB,EAAE,CAAC,UAAU,GAAG,aAAa,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAa,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,MAAM,EAAE,QAAQ,GAAG,WAAW,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,UAAU,IAAI,EAAE,CAAC;IAE9D,MAAM,IAAI,GAAa;QACrB,QAAQ,EAAE,QAAsC;QAChD,QAAQ,EAAE,QAAsC;QAChD,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC7B,UAAU,EAAE;YACV,QAAQ;YACR,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;YAClB,SAAS,EAAE,KAAK;SACjB;KACF,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Client } from "../client/client.ts";
2
+ import type { SockConn } from "../client/deps.ts";
3
+ export declare class WsClient extends Client {
4
+ private establishSocket;
5
+ protected createConn(): Promise<SockConn>;
6
+ }
7
+ //# sourceMappingURL=wsClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsClient.d.ts","sourceRoot":"","sources":["../../web/wsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGlD,qBAAa,QAAS,SAAQ,MAAM;YACpB,eAAe;IAO7B,UAAmB,UAAU,IAAI,OAAO,CAAC,QAAQ,CAAC,CAUjD;CACF"}
@@ -0,0 +1,22 @@
1
+ import { Client } from "../client/client.js";
2
+ import { logger } from "../client/deps.js";
3
+ import { wrapWebSocket } from "./wrapWebSocket.js";
4
+ export class WsClient extends Client {
5
+ async establishSocket(url) {
6
+ const ws = new WebSocket(url);
7
+ const conn = await wrapWebSocket(ws);
8
+ return conn;
9
+ }
10
+ // overload createConn from the base client class
11
+ createConn() {
12
+ const { protocol, hostname, port: portStr, pathname } = this.connectUrl;
13
+ const port = portStr ? Number(portStr) : (protocol === "wss:" ? 443 : 80);
14
+ const path = pathname || "/mqtt";
15
+ logger.debug({ hostname, port, path });
16
+ if (protocol === "ws:" || protocol === "wss:") {
17
+ return this.establishSocket(`${protocol}//${hostname}:${port}${path}`);
18
+ }
19
+ throw new Error(`Unsupported protocol: ${protocol}`);
20
+ }
21
+ }
22
+ //# sourceMappingURL=wsClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsClient.js","sourceRoot":"","sources":["../../web/wsClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,OAAO,QAAS,SAAQ,MAAM;IAC1B,KAAK,CAAC,eAAe,CAAC,GAAW;QACvC,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iDAAiD;IAC9B,UAAU;QAC3B,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;QACxE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1E,MAAM,IAAI,GAAG,QAAQ,IAAI,OAAO,CAAC;QAEjC,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,IAAI,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,QAAQ,KAAK,QAAQ,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACvD,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=wsClient.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsClient.test.d.ts","sourceRoot":"","sources":["../../web/wsClient.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { WsClient } from "./wsClient.js";
4
+ // most client testing is already done in wsServer.test.ts
5
+ test("Web: Test createConn - unsupported protocol", async () => {
6
+ const client = new WsClient();
7
+ // Use an unsupported protocol like 'ftp://' to trigger the throw in createConn
8
+ const invalidParams = {
9
+ url: new URL("ftp://localhost:1883"),
10
+ numberOfRetries: 0,
11
+ };
12
+ // Assert that connect rejects with the specific "Unsupported protocol" error
13
+ await assert.rejects(async () => {
14
+ await client.connect(invalidParams);
15
+ }, {
16
+ name: "Error",
17
+ message: "Unsupported protocol: ftp:",
18
+ }, "Should throw an error when an unsupported protocol is provided");
19
+ });
20
+ //# sourceMappingURL=wsClient.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsClient.test.js","sourceRoot":"","sources":["../../web/wsClient.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,0DAA0D;AAC1D,IAAI,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;IAC7D,MAAM,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAE9B,+EAA+E;IAC/E,MAAM,aAAa,GAAG;QACpB,GAAG,EAAE,IAAI,GAAG,CAAC,sBAAsB,CAAC;QACpC,eAAe,EAAE,CAAC;KACnB,CAAC;IAEF,6EAA6E;IAC7E,MAAM,MAAM,CAAC,OAAO,CAClB,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACtC,CAAC,EACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,4BAA4B;KACtC,EACD,gEAAgE,CACjE,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,164 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { TcpClient } from "@seriousme/opifex/tcpClient";
4
+ import { TcpServer } from "@seriousme/opifex/tcpServer";
5
+ import { delay, logger, LogLevel } from "@seriousme/opifex/utils";
6
+ import type { PublishPacket, QoS } from "@seriousme/opifex/mqttPacket";
7
+ import { ReasonCode } from "@seriousme/opifex/server";
8
+ // just for demo purposes: ReasonCode is identical in server and client
9
+ import {
10
+ MQTTLevel,
11
+ ReasonCode as ClientReasonCode,
12
+ } from "@seriousme/opifex/client";
13
+
14
+ import type { Context } from "@seriousme/opifex/server";
15
+
16
+ const txtEncoder = new TextEncoder();
17
+ const txtDecoder = new TextDecoder();
18
+
19
+ logger.level(LogLevel.info);
20
+ const firstClientMessage = "first client message";
21
+ const secondClientMessage = "second client message";
22
+ const firstServerMessage = "first server message";
23
+ const secondServerMessage = "second server message";
24
+
25
+ const authMethodForTest = "opifex-for-test-only";
26
+
27
+ function serverProcessAuth(
28
+ _ctx: Context,
29
+ _clientId: string,
30
+ authMethod: string,
31
+ authData: Uint8Array,
32
+ ) {
33
+ logger.debug("serverProcessAuth", authMethod, txtDecoder.decode(authData));
34
+ if (authMethod !== authMethodForTest) {
35
+ return {
36
+ reasonCode: ReasonCode.badAuthenticationMethod,
37
+ };
38
+ }
39
+ const authDataString = txtDecoder.decode(authData);
40
+ if (authDataString === firstClientMessage) {
41
+ return {
42
+ reasonCode: ReasonCode.continueAuthentication,
43
+ authData: txtEncoder.encode(firstServerMessage),
44
+ };
45
+ }
46
+
47
+ if (authDataString === secondClientMessage) {
48
+ return {
49
+ reasonCode: ReasonCode.success,
50
+ authData: txtEncoder.encode(secondServerMessage),
51
+ };
52
+ }
53
+ return {
54
+ reasonCode: ReasonCode.notAuthorized,
55
+ };
56
+ }
57
+
58
+ function clientProcessAuth(
59
+ authMethod: string,
60
+ authData: Uint8Array,
61
+ ) {
62
+ const authDataString = txtDecoder.decode(authData);
63
+ logger.debug("clientProcessAuth", authMethod, authDataString);
64
+ if (
65
+ authMethod !== authMethodForTest ||
66
+ (
67
+ authDataString !== firstServerMessage &&
68
+ authDataString !== secondServerMessage
69
+ )
70
+ ) {
71
+ return {
72
+ reasonCode: ClientReasonCode.badAuthenticationMethod,
73
+ reasonString: "Unknown method or bad data",
74
+ };
75
+ }
76
+ return {
77
+ reasonCode: ClientReasonCode.continueAuthentication,
78
+ authData: txtEncoder.encode(secondClientMessage),
79
+ reasonString: "Continue",
80
+ };
81
+ }
82
+
83
+ test("Test MQTTv5 Auth using TCP client and server", async function () {
84
+ const server = new TcpServer({ port: 0 }, {
85
+ handlers: {
86
+ processAuth: serverProcessAuth,
87
+ },
88
+ });
89
+ server.start();
90
+
91
+ assert.deepStrictEqual(
92
+ server.port !== undefined,
93
+ true,
94
+ "server runs a a random port",
95
+ );
96
+ logger.info(
97
+ `TCP server running on port: ${server.port}, address: ${server.address}`,
98
+ );
99
+
100
+ const params = {
101
+ url: new URL(`mqtt://${server.address}:${server.port}`),
102
+ numberOfRetries: 0,
103
+ options: {
104
+ protocolLevel: MQTTLevel.v5,
105
+ properties: {
106
+ authenticationMethod: authMethodForTest,
107
+ authenticationData: txtEncoder.encode(firstClientMessage),
108
+ },
109
+ },
110
+ };
111
+
112
+ const client = new TcpClient();
113
+ client.onAuth = clientProcessAuth;
114
+ await client.connect(params);
115
+ logger.info("Client connected to server at", client.url);
116
+
117
+ const publishSet: { topic: string; qos: QoS }[] = [
118
+ { topic: "t0@q0", qos: 0 },
119
+ { topic: "t1@q0", qos: 0 },
120
+ ];
121
+
122
+ const subscriptions = publishSet.map((item) => ({
123
+ topicFilter: item.topic,
124
+ qos: item.qos,
125
+ }));
126
+ await client.subscribe({
127
+ subscriptions,
128
+ });
129
+
130
+ // the IIFE ensures message reception runs in parallel
131
+ logger.info("Start receiving");
132
+ const received: PublishPacket[] = [];
133
+ (async function () {
134
+ for await (const item of client.messages()) {
135
+ logger.verbose("Receiving:", item.topic, "--", item.qos);
136
+ received.push(item);
137
+ }
138
+ })();
139
+ // end of IIFE
140
+ for (const item of publishSet) {
141
+ logger.verbose("Publishing:", item.topic, "--", item.qos);
142
+ await client.publish({
143
+ topic: item.topic,
144
+ qos: item.qos,
145
+ payload: new Uint8Array([0x01]),
146
+ });
147
+ }
148
+
149
+ await delay(100);
150
+ logger.info("Disconnect client");
151
+ await client.disconnect();
152
+
153
+ logger.info("Check completeness");
154
+ for (const item of publishSet) {
155
+ const found = received.find((f) =>
156
+ f.topic == item.topic && f.qos === item.qos
157
+ );
158
+ logger.verbose("Found:", item.topic, "--", item.qos);
159
+ assert(found, `${item.topic} -- ${item.qos}`);
160
+ }
161
+
162
+ logger.info("Stop server");
163
+ server.stop();
164
+ });