@seriousme/opifex 1.11.3 → 2.1.0
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.
- package/README.md +99 -40
- package/bin/conformanceServer.ts +45 -13
- package/bin/demoServer.ts +38 -13
- package/bin/mqtt.ts +2 -2
- package/client/ConnectionState.ts +3 -1
- package/client/client.ts +88 -47
- package/client/context.ts +79 -27
- package/client/deps.ts +10 -3
- package/client/handlers/handleAuth.test.ts +193 -0
- package/client/handlers/handleAuth.ts +89 -0
- package/client/handlers/handleConnack.test.ts +173 -0
- package/client/handlers/handleConnack.ts +18 -8
- package/client/handlers/handleDisconnect.test.ts +22 -0
- package/client/handlers/handleDisconnect.ts +17 -0
- package/client/handlers/handlePacket.test.ts +242 -0
- package/client/handlers/handlePacket.ts +19 -5
- package/client/handlers/handlePuback.test.ts +99 -0
- package/client/handlers/handlePuback.ts +6 -0
- package/client/handlers/handlePubcomp.test.ts +112 -0
- package/client/handlers/handlePubcomp.ts +5 -0
- package/client/handlers/handlePublish.test.ts +188 -0
- package/client/handlers/handlePubrec.test.ts +119 -0
- package/client/handlers/handlePubrec.ts +5 -1
- package/client/handlers/handlePubrel.test.ts +136 -0
- package/client/handlers/handleSuback.test.ts +122 -0
- package/client/handlers/handleSuback.ts +3 -0
- package/client/handlers/handleUnsuback.test.ts +101 -0
- package/client/mod.ts +13 -2
- package/client/store/memoryStore.ts +12 -11
- package/client/store/store.ts +4 -2
- package/deno/README.md +1 -2
- package/deno/tcpClient.test.ts +75 -0
- package/deno/tcpClient.ts +36 -18
- package/deno/tcpServer.test.ts +22 -21
- package/deno/tcpServer.ts +26 -4
- package/deno/tlsServer.test.ts +97 -0
- package/deno/tlsServer.ts +58 -0
- package/deno/wsServer.test.ts +93 -0
- package/deno/wsServer.ts +96 -0
- package/dev_utils/generateCert.ts +95 -0
- package/dev_utils/mockConn.ts +36 -0
- package/dev_utils/mockServer.ts +28 -0
- package/dev_utils/mod.ts +30 -3
- package/dev_utils/packetHelpers.ts +404 -0
- package/dev_utils/test-handlers.ts +98 -0
- package/dev_utils/timers.ts +14 -0
- package/dev_utils/webStreamPair.test.ts +171 -0
- package/dev_utils/webStreamPair.ts +143 -0
- package/dist/bin/conformanceServer.js +17 -12
- package/dist/bin/conformanceServer.js.map +1 -1
- package/dist/bin/demoServer.js +16 -12
- package/dist/bin/demoServer.js.map +1 -1
- package/dist/bin/mqtt.js +2 -2
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/ConnectionState.d.ts +3 -1
- package/dist/client/ConnectionState.d.ts.map +1 -1
- package/dist/client/ConnectionState.js +2 -0
- package/dist/client/ConnectionState.js.map +1 -1
- package/dist/client/client.d.ts +47 -21
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +57 -20
- package/dist/client/client.js.map +1 -1
- package/dist/client/context.d.ts +15 -7
- package/dist/client/context.d.ts.map +1 -1
- package/dist/client/context.js +44 -12
- package/dist/client/context.js.map +1 -1
- package/dist/client/deps.d.ts +4 -3
- package/dist/client/deps.d.ts.map +1 -1
- package/dist/client/deps.js +1 -1
- package/dist/client/deps.js.map +1 -1
- package/dist/client/handlers/handleAuth.d.ts +9 -0
- package/dist/client/handlers/handleAuth.d.ts.map +1 -0
- package/dist/client/handlers/handleAuth.js +66 -0
- package/dist/client/handlers/handleAuth.js.map +1 -0
- package/dist/client/handlers/handleConnack.d.ts +2 -2
- package/dist/client/handlers/handleConnack.d.ts.map +1 -1
- package/dist/client/handlers/handleConnack.js +16 -6
- package/dist/client/handlers/handleConnack.js.map +1 -1
- package/dist/client/handlers/handleDisconnect.d.ts +11 -0
- package/dist/client/handlers/handleDisconnect.d.ts.map +1 -0
- package/dist/client/handlers/handleDisconnect.js +15 -0
- package/dist/client/handlers/handleDisconnect.js.map +1 -0
- package/dist/client/handlers/handlePacket.d.ts.map +1 -1
- package/dist/client/handlers/handlePacket.js +14 -3
- package/dist/client/handlers/handlePacket.js.map +1 -1
- package/dist/client/handlers/handlePuback.d.ts.map +1 -1
- package/dist/client/handlers/handlePuback.js +5 -0
- package/dist/client/handlers/handlePuback.js.map +1 -1
- package/dist/client/handlers/handlePubcomp.d.ts.map +1 -1
- package/dist/client/handlers/handlePubcomp.js +5 -0
- package/dist/client/handlers/handlePubcomp.js.map +1 -1
- package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/client/handlers/handlePubrec.js +5 -1
- package/dist/client/handlers/handlePubrec.js.map +1 -1
- package/dist/client/handlers/handleSuback.d.ts +1 -0
- package/dist/client/handlers/handleSuback.d.ts.map +1 -1
- package/dist/client/handlers/handleSuback.js +3 -0
- package/dist/client/handlers/handleSuback.js.map +1 -1
- package/dist/client/mod.d.ts +3 -2
- package/dist/client/mod.d.ts.map +1 -1
- package/dist/client/mod.js +1 -1
- package/dist/client/mod.js.map +1 -1
- package/dist/client/store/memoryStore.d.ts +3 -3
- package/dist/client/store/memoryStore.d.ts.map +1 -1
- package/dist/client/store/memoryStore.js +3 -3
- package/dist/client/store/memoryStore.js.map +1 -1
- package/dist/client/store/store.d.ts +3 -2
- package/dist/client/store/store.d.ts.map +1 -1
- package/dist/client/store/store.js +1 -1
- package/dist/client/store/store.js.map +1 -1
- package/dist/dev_utils/generateCert.d.ts +11 -0
- package/dist/dev_utils/generateCert.d.ts.map +1 -0
- package/dist/dev_utils/generateCert.js +76 -0
- package/dist/dev_utils/generateCert.js.map +1 -0
- package/dist/examples/authHandler.test.d.ts +2 -0
- package/dist/examples/authHandler.test.d.ts.map +1 -0
- package/dist/examples/authHandler.test.js +123 -0
- package/dist/examples/authHandler.test.js.map +1 -0
- package/dist/examples/mqtt.test.d.ts +2 -0
- package/dist/examples/mqtt.test.d.ts.map +1 -0
- package/dist/examples/mqtt.test.js +70 -0
- package/dist/examples/mqtt.test.js.map +1 -0
- package/dist/examples/mqtts.test.d.ts +2 -0
- package/dist/examples/mqtts.test.d.ts.map +1 -0
- package/dist/examples/mqtts.test.js +81 -0
- package/dist/examples/mqtts.test.js.map +1 -0
- package/dist/mqttConn/mqttConn.d.ts +24 -31
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +57 -36
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.d.ts +4 -0
- package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.js.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts.map +1 -1
- package/dist/mqttPacket/PacketType.d.ts +4 -0
- package/dist/mqttPacket/PacketType.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.d.ts +4 -4
- package/dist/mqttPacket/Properties.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.js.map +1 -1
- package/dist/mqttPacket/ReasonCode.d.ts +4 -5
- package/dist/mqttPacket/ReasonCode.d.ts.map +1 -1
- package/dist/mqttPacket/ReasonCode.js +1 -0
- package/dist/mqttPacket/ReasonCode.js.map +1 -1
- package/dist/mqttPacket/RetainHandling.d.ts +4 -0
- package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
- package/dist/mqttPacket/auth.d.ts +7 -8
- package/dist/mqttPacket/auth.d.ts.map +1 -1
- package/dist/mqttPacket/auth.js +31 -30
- package/dist/mqttPacket/auth.js.map +1 -1
- package/dist/mqttPacket/codec.d.ts +48 -0
- package/dist/mqttPacket/codec.d.ts.map +1 -0
- package/dist/mqttPacket/codec.js +93 -0
- package/dist/mqttPacket/codec.js.map +1 -0
- package/dist/mqttPacket/connack.d.ts +11 -10
- package/dist/mqttPacket/connack.d.ts.map +1 -1
- package/dist/mqttPacket/connack.js +43 -45
- package/dist/mqttPacket/connack.js.map +1 -1
- package/dist/mqttPacket/connect.d.ts +7 -7
- package/dist/mqttPacket/connect.d.ts.map +1 -1
- package/dist/mqttPacket/connect.js +156 -157
- package/dist/mqttPacket/connect.js.map +1 -1
- package/dist/mqttPacket/decoder.d.ts +6 -16
- package/dist/mqttPacket/decoder.d.ts.map +1 -1
- package/dist/mqttPacket/decoder.js +7 -28
- package/dist/mqttPacket/decoder.js.map +1 -1
- package/dist/mqttPacket/disconnect.d.ts +9 -8
- package/dist/mqttPacket/disconnect.d.ts.map +1 -1
- package/dist/mqttPacket/disconnect.js +41 -43
- package/dist/mqttPacket/disconnect.js.map +1 -1
- package/dist/mqttPacket/encoder.d.ts +7 -19
- package/dist/mqttPacket/encoder.d.ts.map +1 -1
- package/dist/mqttPacket/encoder.js +5 -28
- package/dist/mqttPacket/encoder.js.map +1 -1
- package/dist/mqttPacket/mod.d.ts +21 -103
- package/dist/mqttPacket/mod.d.ts.map +1 -1
- package/dist/mqttPacket/mod.js +5 -94
- package/dist/mqttPacket/mod.js.map +1 -1
- package/dist/mqttPacket/pingreq.d.ts +6 -6
- package/dist/mqttPacket/pingreq.d.ts.map +1 -1
- package/dist/mqttPacket/pingreq.js +11 -13
- package/dist/mqttPacket/pingreq.js.map +1 -1
- package/dist/mqttPacket/pingres.d.ts +6 -6
- package/dist/mqttPacket/pingres.d.ts.map +1 -1
- package/dist/mqttPacket/pingres.js +11 -13
- package/dist/mqttPacket/pingres.js.map +1 -1
- package/dist/mqttPacket/protocolLevels.d.ts +11 -6
- package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
- package/dist/mqttPacket/protocolLevels.js +5 -1
- package/dist/mqttPacket/protocolLevels.js.map +1 -1
- package/dist/mqttPacket/pubblishAcks.d.ts +9 -10
- package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
- package/dist/mqttPacket/pubblishAcks.js +43 -45
- package/dist/mqttPacket/pubblishAcks.js.map +1 -1
- package/dist/mqttPacket/publish.d.ts +8 -7
- package/dist/mqttPacket/publish.d.ts.map +1 -1
- package/dist/mqttPacket/publish.js +53 -55
- package/dist/mqttPacket/publish.js.map +1 -1
- package/dist/mqttPacket/suback.d.ts +9 -8
- package/dist/mqttPacket/suback.d.ts.map +1 -1
- package/dist/mqttPacket/suback.js +38 -40
- package/dist/mqttPacket/suback.js.map +1 -1
- package/dist/mqttPacket/subscribe.d.ts +41 -10
- package/dist/mqttPacket/subscribe.d.ts.map +1 -1
- package/dist/mqttPacket/subscribe.js +90 -89
- package/dist/mqttPacket/subscribe.js.map +1 -1
- package/dist/mqttPacket/types.d.ts +2 -29
- package/dist/mqttPacket/types.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.d.ts +9 -8
- package/dist/mqttPacket/unsuback.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.js +32 -34
- package/dist/mqttPacket/unsuback.js.map +1 -1
- package/dist/mqttPacket/unsubscribe.d.ts +26 -8
- package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
- package/dist/mqttPacket/unsubscribe.js +45 -44
- package/dist/mqttPacket/unsubscribe.js.map +1 -1
- package/dist/mqttPacket/validators.d.ts +4 -16
- package/dist/mqttPacket/validators.d.ts.map +1 -1
- package/dist/mqttPacket/validators.js +5 -26
- package/dist/mqttPacket/validators.js.map +1 -1
- package/dist/node/tcpClient.d.ts +22 -2
- package/dist/node/tcpClient.d.ts.map +1 -1
- package/dist/node/tcpClient.js +29 -10
- package/dist/node/tcpClient.js.map +1 -1
- package/dist/node/tcpServer.d.ts +18 -0
- package/dist/node/tcpServer.d.ts.map +1 -1
- package/dist/node/tcpServer.js +21 -2
- package/dist/node/tcpServer.js.map +1 -1
- package/dist/node/tlsServer.d.ts +37 -0
- package/dist/node/tlsServer.d.ts.map +1 -0
- package/dist/node/tlsServer.js +73 -0
- package/dist/node/tlsServer.js.map +1 -0
- package/dist/node/wrapNodeSocket.d.ts.map +1 -1
- package/dist/node/wrapNodeSocket.js +6 -28
- package/dist/node/wrapNodeSocket.js.map +1 -1
- package/dist/persistence/basicPersistence.d.ts +36 -0
- package/dist/persistence/basicPersistence.d.ts.map +1 -0
- package/dist/persistence/basicPersistence.js +306 -0
- package/dist/persistence/basicPersistence.js.map +1 -0
- package/dist/persistence/deps.d.ts +3 -2
- package/dist/persistence/deps.d.ts.map +1 -1
- package/dist/persistence/deps.js +2 -1
- package/dist/persistence/deps.js.map +1 -1
- package/dist/persistence/memory/memoryPersistence.d.ts +6 -23
- package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
- package/dist/persistence/memory/memoryPersistence.js +12 -115
- package/dist/persistence/memory/memoryPersistence.js.map +1 -1
- package/dist/persistence/memory/memoryStorage.d.ts +45 -0
- package/dist/persistence/memory/memoryStorage.d.ts.map +1 -0
- package/dist/persistence/memory/memoryStorage.js +143 -0
- package/dist/persistence/memory/memoryStorage.js.map +1 -0
- package/dist/persistence/mod.d.ts +3 -3
- package/dist/persistence/mod.d.ts.map +1 -1
- package/dist/persistence/mod.js +6 -1
- package/dist/persistence/mod.js.map +1 -1
- package/dist/persistence/persistence.d.ts +45 -70
- package/dist/persistence/persistence.d.ts.map +1 -1
- package/dist/persistence/persistence.js +1 -2
- package/dist/persistence/persistence.js.map +1 -1
- package/dist/persistence/sqlite/sqliteDatabase.d.ts +46 -0
- package/dist/persistence/sqlite/sqliteDatabase.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqliteDatabase.js +215 -0
- package/dist/persistence/sqlite/sqliteDatabase.js.map +1 -0
- package/dist/persistence/sqlite/sqlitePersistence.d.ts +16 -0
- package/dist/persistence/sqlite/sqlitePersistence.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqlitePersistence.js +29 -0
- package/dist/persistence/sqlite/sqlitePersistence.js.map +1 -0
- package/dist/persistence/sqlite/sqliteStorage.d.ts +36 -0
- package/dist/persistence/sqlite/sqliteStorage.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqliteStorage.js +194 -0
- package/dist/persistence/sqlite/sqliteStorage.js.map +1 -0
- package/dist/persistence/storage.d.ts +38 -0
- package/dist/persistence/storage.d.ts.map +1 -0
- package/dist/persistence/storage.js +5 -0
- package/dist/persistence/storage.js.map +1 -0
- package/dist/server/config.d.ts +47 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +41 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/context.d.ts +199 -25
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +432 -53
- package/dist/server/context.js.map +1 -1
- package/dist/server/deps.d.ts +5 -6
- package/dist/server/deps.d.ts.map +1 -1
- package/dist/server/deps.js +2 -2
- package/dist/server/deps.js.map +1 -1
- package/dist/server/handlers/completeConnect.d.ts +9 -0
- package/dist/server/handlers/completeConnect.d.ts.map +1 -0
- package/dist/server/handlers/completeConnect.js +74 -0
- package/dist/server/handlers/completeConnect.js.map +1 -0
- package/dist/server/handlers/handleAuth.d.ts +9 -0
- package/dist/server/handlers/handleAuth.d.ts.map +1 -0
- package/dist/server/handlers/handleAuth.js +69 -0
- package/dist/server/handlers/handleAuth.js.map +1 -0
- package/dist/server/handlers/handleConnect.d.ts +2 -4
- package/dist/server/handlers/handleConnect.d.ts.map +1 -1
- package/dist/server/handlers/handleConnect.js +140 -67
- package/dist/server/handlers/handleConnect.js.map +1 -1
- package/dist/server/handlers/handleDisconnect.d.ts +1 -1
- package/dist/server/handlers/handleDisconnect.d.ts.map +1 -1
- package/dist/server/handlers/handleDisconnect.js +3 -3
- package/dist/server/handlers/handleDisconnect.js.map +1 -1
- package/dist/server/handlers/handlePacket.d.ts.map +1 -1
- package/dist/server/handlers/handlePacket.js +19 -6
- package/dist/server/handlers/handlePacket.js.map +1 -1
- package/dist/server/handlers/handlePuback.d.ts +1 -3
- package/dist/server/handlers/handlePuback.d.ts.map +1 -1
- package/dist/server/handlers/handlePuback.js +2 -8
- package/dist/server/handlers/handlePuback.js.map +1 -1
- package/dist/server/handlers/handlePubcomp.d.ts +1 -1
- package/dist/server/handlers/handlePubcomp.d.ts.map +1 -1
- package/dist/server/handlers/handlePubcomp.js +2 -4
- package/dist/server/handlers/handlePubcomp.js.map +1 -1
- package/dist/server/handlers/handlePublish.d.ts +1 -1
- package/dist/server/handlers/handlePublish.d.ts.map +1 -1
- package/dist/server/handlers/handlePublish.js +149 -45
- package/dist/server/handlers/handlePublish.js.map +1 -1
- package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrec.js +2 -3
- package/dist/server/handlers/handlePubrec.js.map +1 -1
- package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrel.js +6 -2
- package/dist/server/handlers/handlePubrel.js.map +1 -1
- package/dist/server/handlers/handleSubscribe.d.ts +1 -6
- package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleSubscribe.js +99 -38
- package/dist/server/handlers/handleSubscribe.js.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.js +19 -4
- package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
- package/dist/server/mod.d.ts +3 -3
- package/dist/server/mod.d.ts.map +1 -1
- package/dist/server/mod.js +1 -1
- package/dist/server/mod.js.map +1 -1
- package/dist/server/server.d.ts +32 -9
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +84 -15
- package/dist/server/server.js.map +1 -1
- package/dist/socket/socket.d.ts +15 -9
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +66 -18
- package/dist/socket/socket.js.map +1 -1
- package/dist/timer/timer.d.ts +32 -0
- package/dist/timer/timer.d.ts.map +1 -1
- package/dist/timer/timer.js +32 -0
- package/dist/timer/timer.js.map +1 -1
- package/dist/trie/trie.d.ts +10 -5
- package/dist/trie/trie.d.ts.map +1 -1
- package/dist/trie/trie.js +61 -41
- package/dist/trie/trie.js.map +1 -1
- package/dist/utils/assert.d.ts.map +1 -1
- package/dist/utils/{BufferedAsyncIterable.d.ts → bufferedAsyncIterable.d.ts} +1 -1
- package/dist/utils/bufferedAsyncIterable.d.ts.map +1 -0
- package/dist/utils/{BufferedAsyncIterable.js → bufferedAsyncIterable.js} +1 -1
- package/dist/utils/bufferedAsyncIterable.js.map +1 -0
- package/dist/utils/deferred.d.ts.map +1 -1
- package/dist/utils/deferred.js.map +1 -1
- package/dist/utils/getOrInsertPolyFill.d.ts +2 -0
- package/dist/utils/getOrInsertPolyFill.d.ts.map +1 -0
- package/dist/utils/getOrInsertPolyFill.js +12 -0
- package/dist/utils/getOrInsertPolyFill.js.map +1 -0
- package/dist/utils/logger.d.ts +42 -5
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +53 -7
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/mod.d.ts +6 -1
- package/dist/utils/mod.d.ts.map +1 -1
- package/dist/utils/mod.js +5 -1
- package/dist/utils/mod.js.map +1 -1
- package/dist/utils/outboundTopicAliasManager.d.ts +52 -0
- package/dist/utils/outboundTopicAliasManager.d.ts.map +1 -0
- package/dist/utils/outboundTopicAliasManager.js +74 -0
- package/dist/utils/outboundTopicAliasManager.js.map +1 -0
- package/dist/utils/queue.d.ts.map +1 -1
- package/dist/utils/topicFilter.d.ts +32 -0
- package/dist/utils/topicFilter.d.ts.map +1 -0
- package/dist/utils/topicFilter.js +52 -0
- package/dist/utils/topicFilter.js.map +1 -0
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +2 -0
- package/dist/utils/utils.js.map +1 -1
- package/dist/utils/validators.d.ts +34 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +61 -0
- package/dist/utils/validators.js.map +1 -0
- package/dist/web/webSocketStream.d.ts +29 -0
- package/dist/web/webSocketStream.d.ts.map +1 -0
- package/dist/web/webSocketStream.js +69 -0
- package/dist/web/webSocketStream.js.map +1 -0
- package/dist/web/wrapWebSocket.d.ts +12 -0
- package/dist/web/wrapWebSocket.d.ts.map +1 -0
- package/dist/web/wrapWebSocket.js +41 -0
- package/dist/web/wrapWebSocket.js.map +1 -0
- package/dist/web/wsClient.d.ts +14 -0
- package/dist/web/wsClient.d.ts.map +1 -0
- package/dist/web/wsClient.js +33 -0
- package/dist/web/wsClient.js.map +1 -0
- package/dist/web/wsClient.test.d.ts +2 -0
- package/dist/web/wsClient.test.d.ts.map +1 -0
- package/dist/web/wsClient.test.js +20 -0
- package/dist/web/wsClient.test.js.map +1 -0
- package/examples/authHandler.test.ts +164 -0
- package/examples/mqtt.test.ts +89 -0
- package/examples/mqtts.test.ts +100 -0
- package/examples/webSocket.test.ts +94 -0
- package/mqttConn/mqttConn.test.ts +9 -9
- package/mqttConn/mqttConn.ts +76 -60
- package/mqttPacket/AuthenticationResult.ts +6 -0
- package/mqttPacket/PacketType.ts +5 -0
- package/mqttPacket/Properties.ts +8 -5
- package/mqttPacket/ReasonCode.ts +8 -9
- package/mqttPacket/RetainHandling.ts +5 -0
- package/mqttPacket/auth.test.ts +1 -1
- package/mqttPacket/auth.ts +44 -51
- package/mqttPacket/codec.ts +147 -0
- package/mqttPacket/connack.ts +63 -73
- package/mqttPacket/connect.test.ts +2 -2
- package/mqttPacket/connect.ts +178 -192
- package/mqttPacket/decoder.test.ts +0 -39
- package/mqttPacket/decoder.ts +17 -46
- package/mqttPacket/disconnect.ts +60 -71
- package/mqttPacket/encoder.test.ts +2 -2
- package/mqttPacket/encoder.ts +13 -46
- package/mqttPacket/mod.ts +48 -204
- package/mqttPacket/pingreq.ts +22 -28
- package/mqttPacket/pingres.ts +22 -28
- package/mqttPacket/protocolLevels.ts +12 -7
- package/mqttPacket/pubblishAcks.ts +61 -75
- package/mqttPacket/publish.ts +70 -84
- package/mqttPacket/publishAcks.test.ts +3 -3
- package/mqttPacket/suback.ts +53 -68
- package/mqttPacket/subscribe.ts +146 -128
- package/mqttPacket/types.ts +2 -35
- package/mqttPacket/unsuback.ts +50 -61
- package/mqttPacket/unsubscribe.ts +77 -72
- package/mqttPacket/validators.ts +5 -31
- package/node/socket-node-stream.test.ts +322 -0
- package/node/socket-node-stream.ts +174 -0
- package/node/tcpClient.test.ts +70 -0
- package/node/tcpClient.ts +33 -17
- package/node/tcpServer.test.ts +24 -20
- package/node/tcpServer.ts +29 -6
- package/node/tlsServer.test.ts +94 -0
- package/node/tlsServer.ts +97 -0
- package/node/wrapNodeSocket.ts +7 -30
- package/package.json +72 -44
- package/persistence/basicPersistence.ts +495 -0
- package/persistence/deps.ts +11 -1
- package/persistence/memory/memoryPersistence.ts +12 -153
- package/persistence/memory/memoryStorage.ts +232 -0
- package/persistence/mod.ts +5 -10
- package/persistence/persistence.test.ts +24 -0
- package/persistence/persistence.testing.ts +1324 -0
- package/persistence/persistence.ts +112 -68
- package/persistence/sqlite/sqliteDatabase.ts +294 -0
- package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
- package/persistence/sqlite/sqlitePersistence.ts +36 -0
- package/persistence/sqlite/sqliteStorage.ts +324 -0
- package/persistence/storage.ts +84 -0
- package/server/config.ts +65 -0
- package/server/context.ts +660 -76
- package/server/deps.ts +24 -5
- package/server/handlers/completeConnect.ts +93 -0
- package/server/handlers/duplicate.test.ts +196 -0
- package/server/handlers/handleAuth.test.ts +225 -0
- package/server/handlers/handleAuth.ts +88 -0
- package/server/handlers/handleConnect.test.ts +589 -0
- package/server/handlers/handleConnect.ts +201 -86
- package/server/handlers/handleConnect.version.test.ts +108 -0
- package/server/handlers/handleDisconnect.test.ts +56 -0
- package/server/handlers/handleDisconnect.ts +3 -3
- package/server/handlers/handlePacket.test.ts +24 -0
- package/server/handlers/handlePacket.ts +30 -8
- package/server/handlers/handlePingreq.test.ts +29 -0
- package/server/handlers/handlePuback.test.ts +28 -0
- package/server/handlers/handlePuback.ts +5 -8
- package/server/handlers/handlePubcomp.test.ts +28 -0
- package/server/handlers/handlePubcomp.ts +5 -4
- package/server/handlers/handlePublish.test.ts +471 -0
- package/server/handlers/handlePublish.ts +188 -35
- package/server/handlers/handlePubrec.test.ts +28 -0
- package/server/handlers/handlePubrec.ts +2 -3
- package/server/handlers/handlePubrel.test.ts +74 -0
- package/server/handlers/handlePubrel.ts +12 -2
- package/server/handlers/handleSubscribe.test.ts +971 -0
- package/server/handlers/handleSubscribe.ts +157 -39
- package/server/handlers/handleUnsubscribe.test.ts +79 -0
- package/server/handlers/handleUnsubscribe.ts +28 -4
- package/server/handlers/keepalive.test.ts +132 -0
- package/server/handlers/session.persistence.test.ts +194 -0
- package/server/handlers/will.delivery.test.ts +221 -0
- package/server/mod.ts +5 -4
- package/server/preconnect.test.ts +151 -0
- package/server/server.ts +117 -19
- package/socket/socket.test.ts +91 -0
- package/socket/socket.ts +85 -34
- package/timer/timer.test.ts +4 -7
- package/timer/timer.ts +36 -0
- package/tools/benchmarks/receiver.ts +51 -0
- package/tools/benchmarks/sender.ts +48 -0
- package/tools/benchmarks/utils.ts +31 -0
- package/tools/mqtt-compat/README.md +130 -0
- package/tools/mqtt-compat/broker.ts +52 -0
- package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
- package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
- package/trie/trie.test.ts +9 -1
- package/trie/trie.ts +70 -45
- package/utils/bufferedAsyncIterable.test.ts +92 -0
- package/utils/deferred.test.ts +36 -0
- package/utils/deferred.ts +0 -1
- package/utils/getOrInsertPolyFill.ts +12 -0
- package/utils/logger.test.ts +189 -0
- package/utils/logger.ts +64 -9
- package/utils/mod.ts +15 -1
- package/utils/outboundTopicAliasManager.ts +100 -0
- package/utils/queue.test.ts +61 -0
- package/utils/topicFilter.test.ts +63 -0
- package/utils/topicFilter.ts +61 -0
- package/utils/utils.ts +3 -0
- package/utils/validators.ts +67 -0
- package/web/webSocketStream.ts +97 -0
- package/web/wrapWebSocket.ts +52 -0
- package/web/wsClient.test.ts +26 -0
- package/web/wsClient.ts +37 -0
- package/benchmarks/receiver.ts +0 -35
- package/benchmarks/sender.ts +0 -32
- package/benchmarks/utils.ts +0 -9
- package/dev_utils/dummyConn.ts +0 -110
- package/dev_utils/socketPair.ts +0 -85
- package/dist/persistence/store.d.ts +0 -14
- package/dist/persistence/store.d.ts.map +0 -1
- package/dist/persistence/store.js +0 -2
- package/dist/persistence/store.js.map +0 -1
- package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
- package/dist/utils/BufferedAsyncIterable.js.map +0 -1
- package/examples/tcpServer.test.ts +0 -148
- package/persistence/memory/memoryPersistence.test.ts +0 -156
- package/persistence/store.ts +0 -16
- package/server/test/handleConnect.test.ts +0 -122
- package/server/test/test-handlers.ts +0 -53
- /package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +0 -0
|
@@ -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 {
|
|
6
|
-
|
|
5
|
+
import type {
|
|
6
|
+
ClientId,
|
|
7
|
+
PacketId,
|
|
8
|
+
PublishPacketV5,
|
|
9
|
+
QoS,
|
|
10
|
+
RetainHandling,
|
|
11
|
+
TopicFilter,
|
|
12
|
+
} from "./deps.ts";
|
|
7
13
|
|
|
8
14
|
/**
|
|
9
|
-
*
|
|
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
|
|
17
|
+
export type ExtPublishPacket = PublishPacketV5 & {
|
|
18
|
+
expiresAtMs?: number;
|
|
19
|
+
};
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
|
-
*
|
|
22
|
-
* @typedef {Map<Topic, PublishPacket>} RetainStore
|
|
22
|
+
* The MQTT topic share to subscribe/unsubscribe to
|
|
23
23
|
*/
|
|
24
|
-
export type
|
|
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?: RetainHandling;
|
|
33
|
+
subscriptionIdentifier?: number;
|
|
34
|
+
};
|
|
25
35
|
|
|
26
36
|
/**
|
|
27
|
-
*
|
|
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
|
|
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
|
-
export interface
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
export interface Persistence {
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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
|
+
}
|