@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
@@ -2,92 +2,136 @@
2
2
  * @module persistence
3
3
  * @description Module for handling MQTT message persistence and client management
4
4
  */
5
- import type { ClientId, PublishPacket, QoS, Topic } from "./deps.ts";
6
- import type { IStore } from "./store.ts";
5
+ import type {
6
+ ClientId,
7
+ PacketId,
8
+ PublishPacketV5,
9
+ QoS,
10
+ TopicFilter,
11
+ TRetainHandling,
12
+ } from "./deps.ts";
7
13
 
8
14
  /**
9
- * Maximum packet ID value for MQTT messages (0xffff/65535)
10
- * @constant {number}
11
- */
12
- export const maxPacketId = 0xffff;
13
- /**
14
- * Handler function type for processing publish packets
15
- * @callback Handler
16
- * @param {PublishPacket} packet - The MQTT publish packet to handle
15
+ * extended publish packet also contains meta data
17
16
  */
18
- export type Handler = (packet: PublishPacket) => void;
17
+ export type ExtPublishPacket = PublishPacketV5 & {
18
+ expiresAtMs?: number;
19
+ };
19
20
 
20
21
  /**
21
- * Store type for retained messages mapped by topic
22
- * @typedef {Map<Topic, PublishPacket>} RetainStore
22
+ * The MQTT topic share to subscribe/unsubscribe to
23
23
  */
24
- export type RetainStore = Map<Topic, PublishPacket>;
24
+ export type ShareName = string;
25
+
26
+ export type ClientSubscription = {
27
+ topicFilter: TopicFilter;
28
+ shareName: ShareName;
29
+ qos: QoS;
30
+ noLocal?: boolean;
31
+ retainAsPublished?: boolean;
32
+ retainHandling?: TRetainHandling;
33
+ subscriptionIdentifier?: number;
34
+ };
25
35
 
26
36
  /**
27
- * Client type containing message store and packet handler
28
- * @typedef {Object} Client
29
- * @property {IStore} store - The client's message store
30
- * @property {Handler} handler - The client's packet handler function
37
+ * Maximum packet ID value for MQTT messages (0xffff/65535)
31
38
  */
32
- export type Client = { store: IStore; handler: Handler };
39
+ export const MAX_PACKET_ID = 0xffff;
40
+
41
+ // Handler function type for processing publish packets
42
+ export type Handler = (packet: ExtPublishPacket) => void | Promise<void>;
43
+
44
+ // The result returned by client registration
45
+ export type ClientRegistrationResult = {
46
+ existingSession: boolean;
47
+ };
33
48
 
34
49
  /**
35
50
  * Interface for persistence implementations to store messages and subscriptions
36
- * @interface IPersistence
37
51
  */
38
52
  export interface IPersistence {
39
- /**
40
- * Map of connected clients by client ID
41
- * @type {Map<ClientId, Client>}
42
- */
43
- clientList: Map<ClientId, Client>;
53
+ // initialize the persistence
54
+ // e.g. setting up the data store
55
+ initialize(): Promise<void>;
56
+
57
+ // client registration
58
+ registerClient(
59
+ clientId: ClientId,
60
+ handler: Handler,
61
+ ): Promise<ClientRegistrationResult>;
62
+ deregisterClient(clientId: ClientId): Promise<void>;
44
63
 
45
- /**
46
- * Map of retained messages by topic
47
- * @type {RetainStore}
48
- */
49
- retained: RetainStore;
64
+ disconnectClient(clientId: ClientId): Promise<void>;
50
65
 
51
- /**
52
- * Register a new client with the persistence layer
53
- * @param {ClientId} clientId - Unique identifier for the client
54
- * @param {Handler} handler - Packet handler function for the client
55
- * @param {boolean} clean - Whether to start with a clean session
56
- * @returns {IStore} The client's message store
57
- */
58
- registerClient(clientId: ClientId, handler: Handler, clean: boolean): IStore;
66
+ // subscription management
67
+ subscribe(
68
+ clientId: ClientId,
69
+ subscription: ClientSubscription,
70
+ ): Promise<void>;
71
+ unsubscribe(
72
+ clientId: ClientId,
73
+ topicFilter: TopicFilter,
74
+ shareName: ShareName,
75
+ ): Promise<void>;
76
+ listSubscriptions(
77
+ clientId: ClientId,
78
+ ): AsyncIterableIterator<ClientSubscription>;
59
79
 
60
- /**
61
- * Remove a client from the persistence layer
62
- * @param {ClientId} clientId - ID of client to deregister
63
- */
64
- deregisterClient(clientId: ClientId): void;
80
+ // Incoming Packet management
81
+ addPendingIncomingPacket(
82
+ clientId: ClientId,
83
+ packet: ExtPublishPacket,
84
+ ): Promise<void>;
85
+ getPendingIncomingPacket(
86
+ clientId: ClientId,
87
+ packetId: PacketId,
88
+ ): Promise<ExtPublishPacket | null>;
89
+ listPendingIncomingPackets(
90
+ clientId: ClientId,
91
+ ): AsyncIterableIterator<ExtPublishPacket>;
92
+ deletePendingIncomingPacket(
93
+ clientId: ClientId,
94
+ packetId: PacketId,
95
+ ): Promise<boolean>;
65
96
 
66
- /**
67
- * Publish a message to all subscribed clients
68
- * @param {Topic} topic - Topic to publish to
69
- * @param {PublishPacket} packet - Packet containing the message
70
- */
71
- publish(topic: Topic, packet: PublishPacket): void;
97
+ // Outgoing Packet management
98
+ addPendingOutgoingPacket(
99
+ clientId: ClientId,
100
+ packet: ExtPublishPacket,
101
+ ): Promise<void>;
102
+ getPendingOutgoingPacket(
103
+ clientId: ClientId,
104
+ packetId: PacketId,
105
+ ): Promise<ExtPublishPacket | null>;
106
+ updatePendingOutgoingPacket(
107
+ clientId: ClientId,
108
+ packetId: PacketId,
109
+ dup: boolean,
110
+ ): Promise<boolean>;
111
+ listPendingOutgoingPackets(
112
+ clientId: ClientId,
113
+ ): AsyncIterableIterator<ExtPublishPacket>;
114
+ deletePendingOutgoingPacket(
115
+ clientId: ClientId,
116
+ packetId: PacketId,
117
+ ): Promise<boolean>;
72
118
 
73
- /**
74
- * Subscribe a client to a topic
75
- * @param {IStore} store - Client's message store
76
- * @param {Topic} topic - Topic to subscribe to
77
- * @param {QoS} qos - Quality of Service level
78
- */
79
- subscribe(store: IStore, topic: Topic, qos: QoS): void;
119
+ // Acks
120
+ addPendingAck(clientId: ClientId, packetId: PacketId): Promise<void>;
121
+ hasPendingAck(clientId: ClientId, packetId: PacketId): Promise<boolean>;
122
+ deletePendingAck(clientId: ClientId, packetId: PacketId): Promise<boolean>;
123
+ listPendingAcks(clientId: ClientId): AsyncIterableIterator<PacketId>;
80
124
 
81
- /**
82
- * Unsubscribe a client from a topic
83
- * @param {IStore} store - Client's message store
84
- * @param {Topic} topic - Topic to unsubscribe from
85
- */
86
- unsubscribe(store: IStore, topic: Topic): void;
125
+ // Message Delivery & Retained
126
+ publish(
127
+ clientId: ClientId,
128
+ packet: ExtPublishPacket,
129
+ ): Promise<void>;
130
+ handleRetained(
131
+ clientId: ClientId,
132
+ subscriptions: ClientSubscription[],
133
+ ): Promise<void>;
87
134
 
88
- /**
89
- * Send retained messages to a client
90
- * @param {ClientId} clientId - ID of client to send retained messages to
91
- */
92
- handleRetained(clientId: ClientId): void;
135
+ // Packet ID Generation
136
+ nextPacketId(clientId: ClientId): Promise<PacketId>;
93
137
  }
@@ -0,0 +1,294 @@
1
+ import sqlite from "node:sqlite";
2
+ import type { ClientId } from "../../mqttPacket/types.ts";
3
+
4
+ /**
5
+ * Instantiates the physical relational structures and schemas required by the persistence engine.
6
+ * @param filename Filepath location or memory target specifier.
7
+ */
8
+ export function initializeDatabase(filename: string): sqlite.DatabaseSync {
9
+ const db = new sqlite.DatabaseSync(filename);
10
+ db.exec(`
11
+ PRAGMA journal_mode = WAL;
12
+ PRAGMA synchronous = NORMAL;
13
+
14
+ CREATE TABLE IF NOT EXISTS client_sessions (
15
+ client_id TEXT PRIMARY KEY,
16
+ session_data TEXT NOT NULL
17
+ );
18
+
19
+ CREATE TABLE IF NOT EXISTS subscriptions (
20
+ client_id TEXT NOT NULL,
21
+ topic TEXT NOT NULL,
22
+ share_name TEXT NOT NULL,
23
+ subscription_data TEXT NOT NULL,
24
+ PRIMARY KEY (client_id, topic, share_name)
25
+ );
26
+
27
+ CREATE TABLE IF NOT EXISTS pending_incoming (
28
+ seq_id INTEGER PRIMARY KEY AUTOINCREMENT, -- Guarantees absolute insertion order
29
+ client_id TEXT NOT NULL,
30
+ packet_id INTEGER NOT NULL,
31
+ packet TEXT NOT NULL,
32
+ payload BLOB,
33
+ created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
34
+ UNIQUE (client_id, packet_id)
35
+ );
36
+
37
+ CREATE TABLE IF NOT EXISTS pending_outgoing (
38
+ seq_id INTEGER PRIMARY KEY AUTOINCREMENT, -- Guarantees absolute insertion order
39
+ client_id TEXT NOT NULL,
40
+ packet_id INTEGER NOT NULL,
41
+ packet TEXT NOT NULL,
42
+ payload BLOB,
43
+ created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
44
+ UNIQUE (client_id, packet_id)
45
+ );
46
+
47
+ CREATE TABLE IF NOT EXISTS pending_ack_outgoing (
48
+ client_id TEXT NOT NULL,
49
+ packet_id INTEGER NOT NULL,
50
+ PRIMARY KEY (client_id, packet_id)
51
+ );
52
+
53
+ CREATE TABLE IF NOT EXISTS retained (
54
+ topic TEXT PRIMARY KEY,
55
+ packet TEXT NOT NULL,
56
+ payload BLOB
57
+ );
58
+ `);
59
+ return db;
60
+ }
61
+
62
+ export type AllStatements = {
63
+ // Sessions
64
+ saveSession: sqlite.StatementSync;
65
+ getSession: sqlite.StatementSync;
66
+ listAllSessions: sqlite.StatementSync;
67
+
68
+ // Subscriptions
69
+ saveSubscription: sqlite.StatementSync;
70
+ deleteSubscription: sqlite.StatementSync;
71
+ listSubscriptions: sqlite.StatementSync;
72
+ listAllSubscriptions: sqlite.StatementSync;
73
+
74
+ // Pending Incoming Packets
75
+ saveIncoming: sqlite.StatementSync;
76
+ getIncoming: sqlite.StatementSync;
77
+ updateIncomingDup: sqlite.StatementSync;
78
+ deleteIncoming: sqlite.StatementSync;
79
+ listIncoming: sqlite.StatementSync;
80
+
81
+ // Pending Outgoing Packets
82
+ saveOutgoing: sqlite.StatementSync;
83
+ getOutgoing: sqlite.StatementSync;
84
+ updateOutgoingDup: sqlite.StatementSync;
85
+ deleteOutgoing: sqlite.StatementSync;
86
+ listOutgoing: sqlite.StatementSync;
87
+
88
+ // ACKs
89
+ saveAck: sqlite.StatementSync;
90
+ hasAck: sqlite.StatementSync;
91
+ deleteAck: sqlite.StatementSync;
92
+ listAcks: sqlite.StatementSync;
93
+
94
+ // Retained
95
+ saveRetained: sqlite.StatementSync;
96
+ deleteRetained: sqlite.StatementSync;
97
+ getRetainedExact: sqlite.StatementSync;
98
+ listRetainedLike: sqlite.StatementSync;
99
+ };
100
+
101
+ /**
102
+ * Instantiates the physical relational structures and schemas required by the persistence engine.
103
+ * @param db the database for which to prepare the statements
104
+ */
105
+ export function prepareAllStatements(db: sqlite.DatabaseSync): AllStatements {
106
+ return {
107
+ // Sessions
108
+ saveSession: db.prepare(`
109
+ INSERT INTO client_sessions (client_id, session_data)
110
+ VALUES (?, ?)
111
+ ON CONFLICT(client_id) DO UPDATE SET
112
+ session_data = excluded.session_data
113
+ `),
114
+
115
+ getSession: db.prepare(`
116
+ SELECT session_data
117
+ FROM client_sessions
118
+ WHERE client_id = ?
119
+ `),
120
+
121
+ listAllSessions: db.prepare(`
122
+ SELECT client_id, session_data
123
+ FROM client_sessions
124
+ `),
125
+
126
+ // Subscriptions
127
+ saveSubscription: db.prepare(`
128
+ INSERT INTO subscriptions (client_id, topic, share_name, subscription_data)
129
+ VALUES (?, ?, ?, ?)
130
+ ON CONFLICT(client_id, topic, share_name) DO UPDATE SET
131
+ subscription_data = excluded.subscription_data
132
+ `),
133
+
134
+ deleteSubscription: db.prepare(`
135
+ DELETE FROM subscriptions
136
+ WHERE client_id = ? AND topic = ? AND share_name = ?
137
+ `),
138
+
139
+ listSubscriptions: db.prepare(`
140
+ SELECT topic, share_name, subscription_data
141
+ FROM subscriptions
142
+ WHERE client_id = ?
143
+ `),
144
+
145
+ listAllSubscriptions: db.prepare(`
146
+ SELECT client_id, topic, share_name, subscription_data
147
+ FROM subscriptions
148
+ `),
149
+
150
+ // Pending Incoming Packets
151
+ saveIncoming: db.prepare(`
152
+ INSERT INTO pending_incoming (client_id, packet_id, packet, payload)
153
+ VALUES (?, ?, ?, ?)
154
+ ON CONFLICT(client_id, packet_id) DO UPDATE SET
155
+ packet = excluded.packet,
156
+ payload = excluded.payload
157
+ `),
158
+
159
+ getIncoming: db.prepare(`
160
+ SELECT packet, payload
161
+ FROM pending_incoming
162
+ WHERE client_id = ? AND packet_id = ?
163
+ `),
164
+
165
+ updateIncomingDup: db.prepare(`
166
+ UPDATE pending_incoming
167
+ SET packet = json_set(packet, '$.dup', json(?))
168
+ WHERE client_id = ? AND packet_id = ?
169
+ `),
170
+
171
+ deleteIncoming: db.prepare(`
172
+ DELETE FROM pending_incoming
173
+ WHERE client_id = ? AND packet_id = ?
174
+ `),
175
+
176
+ listIncoming: db.prepare(`
177
+ SELECT packet, payload
178
+ FROM pending_incoming
179
+ WHERE client_id = ?
180
+ ORDER BY seq_id ASC
181
+ `),
182
+
183
+ // Pending Outgoing Packets
184
+ saveOutgoing: db.prepare(`
185
+ INSERT INTO pending_outgoing (client_id, packet_id, packet, payload)
186
+ VALUES (?, ?, ?, ?)
187
+ ON CONFLICT(client_id, packet_id) DO UPDATE SET
188
+ packet = excluded.packet,
189
+ payload = excluded.payload
190
+ `),
191
+
192
+ getOutgoing: db.prepare(`
193
+ SELECT packet, payload
194
+ FROM pending_outgoing
195
+ WHERE client_id = ? AND packet_id = ?
196
+ `),
197
+
198
+ updateOutgoingDup: db.prepare(`
199
+ UPDATE pending_outgoing
200
+ SET packet = json_set(packet, '$.dup', json(?))
201
+ WHERE client_id = ? AND packet_id = ?
202
+ `),
203
+
204
+ deleteOutgoing: db.prepare(`
205
+ DELETE FROM pending_outgoing
206
+ WHERE client_id = ? AND packet_id = ?
207
+ `),
208
+
209
+ listOutgoing: db.prepare(`
210
+ SELECT packet, payload
211
+ FROM pending_outgoing
212
+ WHERE client_id = ?
213
+ ORDER BY seq_id ASC
214
+ `),
215
+
216
+ // ACKs
217
+ saveAck: db.prepare(`
218
+ INSERT INTO pending_ack_outgoing (client_id, packet_id)
219
+ VALUES (?, ?)
220
+ ON CONFLICT(client_id, packet_id) DO NOTHING
221
+ `),
222
+
223
+ hasAck: db.prepare(`
224
+ SELECT 1
225
+ FROM pending_ack_outgoing
226
+ WHERE client_id = ? AND packet_id = ?
227
+ `),
228
+
229
+ deleteAck: db.prepare(`
230
+ DELETE FROM pending_ack_outgoing
231
+ WHERE client_id = ? AND packet_id = ?
232
+ `),
233
+
234
+ listAcks: db.prepare(`
235
+ SELECT packet_id
236
+ FROM pending_ack_outgoing
237
+ WHERE client_id = ?
238
+ `),
239
+
240
+ // Retained Messages
241
+ saveRetained: db.prepare(`
242
+ INSERT INTO retained (topic, packet, payload)
243
+ VALUES (?, ?, ?)
244
+ ON CONFLICT(topic) DO UPDATE SET
245
+ packet = excluded.packet,
246
+ payload = excluded.payload
247
+ `),
248
+
249
+ deleteRetained: db.prepare(`
250
+ DELETE FROM retained
251
+ WHERE topic = ?
252
+ `),
253
+
254
+ getRetainedExact: db.prepare(`
255
+ SELECT packet, payload
256
+ FROM retained
257
+ WHERE topic = ?
258
+ `),
259
+
260
+ listRetainedLike: db.prepare(`
261
+ SELECT topic, packet, payload
262
+ FROM retained
263
+ WHERE topic LIKE ?
264
+ `),
265
+ };
266
+ }
267
+
268
+ /**
269
+ * Truncates and drops relational state assignments under targeted clients inside atomic scopes.
270
+ * @param db Connection reference context.
271
+ * @param clientId Specific target client ID tracking token.
272
+ */
273
+ export function deleteClientState(
274
+ db: sqlite.DatabaseSync,
275
+ clientId: ClientId,
276
+ ): void {
277
+ db.exec("begin;");
278
+ db.prepare(
279
+ "delete from subscriptions where client_id = ?",
280
+ ).run(clientId);
281
+ db.prepare(
282
+ "delete from pending_incoming where client_id = ?",
283
+ ).run(clientId);
284
+ db.prepare(
285
+ "delete from pending_outgoing where client_id = ?",
286
+ ).run(clientId);
287
+ db.prepare(
288
+ "delete from pending_ack_outgoing where client_id = ?",
289
+ ).run(clientId);
290
+ db.prepare(
291
+ "delete from client_sessions where client_id = ?",
292
+ ).run(clientId);
293
+ db.exec("commit;");
294
+ }
@@ -0,0 +1,48 @@
1
+ import { test } from "node:test";
2
+ import { initializeDatabase } from "./sqliteDatabase.ts";
3
+ import { SqlitePersistence } from "./sqlitePersistence.ts";
4
+ import { SqliteStorage } from "./sqliteStorage.ts";
5
+ import { PacketDirection } from "../storage.ts";
6
+ import { PacketType } from "../deps.ts";
7
+ import assert from "node:assert/strict";
8
+
9
+ const utf8Encoder = new TextEncoder();
10
+
11
+ test("SqlitePersistence - Trie is correctly rebuilt (restored) from the database", async () => {
12
+ // Manually create an in-memory (:memory:) database and set up the tables
13
+ const sharedDb = initializeDatabase(":memory:");
14
+ // Simulate an existing state by directly injecting data into the sessions table
15
+ const storage = new SqliteStorage(sharedDb);
16
+ storage.saveSession("Client_A", { existingSession: true });
17
+ storage.saveSession("Client_B", { existingSession: true });
18
+ storage.saveSubscription("Client_A", {
19
+ topicFilter: "sensor/temperature",
20
+ shareName: "",
21
+ qos: 1,
22
+ });
23
+ storage.saveSubscription("Client_B", {
24
+ topicFilter: "sensor/#",
25
+ shareName: "",
26
+ qos: 2,
27
+ });
28
+ const persistence = await SqlitePersistence.start(sharedDb);
29
+ const topic = "sensor/temperature";
30
+ await persistence.publish("Client_C", {
31
+ type: PacketType.publish,
32
+ protocolLevel: 5,
33
+ topic,
34
+ payload: utf8Encoder.encode("25 degrees"),
35
+ qos: 2,
36
+ });
37
+ const packetsA = await Array.fromAsync(
38
+ storage.listPendingPackets("Client_A", PacketDirection.Outgoing),
39
+ );
40
+ assert.strictEqual(packetsA[0].topic, topic);
41
+ assert.strictEqual(packetsA[0].qos, 1);
42
+ const packetsB = await Array.fromAsync(
43
+ storage.listPendingPackets("Client_B", PacketDirection.Outgoing),
44
+ );
45
+ assert.strictEqual(packetsB[0].topic, topic);
46
+ assert.strictEqual(packetsB[0].qos, 2);
47
+ persistence.close();
48
+ });
@@ -0,0 +1,36 @@
1
+ import { MqttPersistence } from "../basicPersistence.ts";
2
+ import { SqliteStorage } from "./sqliteStorage.ts";
3
+ import type sqlite from "node:sqlite";
4
+
5
+ const SQLITE_DATABASE_URL = ":memory:";
6
+
7
+ export class SqlitePersistence extends MqttPersistence {
8
+ private storageInstance: SqliteStorage;
9
+
10
+ constructor(db: string | sqlite.DatabaseSync = SQLITE_DATABASE_URL) {
11
+ const storage = new SqliteStorage(db);
12
+ super(storage);
13
+ this.storageInstance = storage;
14
+ }
15
+
16
+ /**
17
+ * Convenient lifecycle method combining instance creation and initialization.
18
+ */
19
+ static async start(
20
+ db: string | sqlite.DatabaseSync = SQLITE_DATABASE_URL,
21
+ ): Promise<SqlitePersistence> {
22
+ const persistence = new SqlitePersistence(db);
23
+ await persistence.initialize();
24
+ return persistence;
25
+ }
26
+
27
+ /**
28
+ * Overrides close to make sure the underlying database file
29
+ * handle is cleaned up correctly when the persistence is halted.
30
+ */
31
+ async close(): Promise<void> {
32
+ if (this.storageInstance.close) {
33
+ await this.storageInstance.close();
34
+ }
35
+ }
36
+ }