@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.
- package/LICENSE.txt +1 -1
- package/README.md +102 -43
- package/bin/conformanceServer.ts +45 -13
- package/bin/demoServer.ts +38 -13
- package/bin/mqtt.ts +52 -30
- package/client/ConnectionState.ts +2 -0
- package/client/client.ts +57 -47
- package/client/context.ts +75 -21
- package/client/deps.ts +5 -0
- 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 +16 -6
- 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 +2 -2
- package/client/store/memoryStore.ts +2 -2
- package/client/store/store.ts +3 -1
- package/deno/README.md +1 -2
- package/deno/tcpClient.test.ts +75 -0
- package/deno/tcpClient.ts +16 -11
- package/deno/tcpServer.test.ts +22 -21
- package/deno/tcpServer.ts +5 -0
- package/deno/tlsServer.test.ts +97 -0
- package/deno/tlsServer.ts +42 -0
- package/deno/wsServer.test.ts +93 -0
- package/deno/wsServer.ts +73 -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 -2
- 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 +19 -16
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/ConnectionState.d.ts +2 -0
- 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 +19 -22
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +34 -20
- package/dist/client/client.js.map +1 -1
- package/dist/client/context.d.ts +11 -3
- 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 +3 -2
- 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 +2 -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.map +1 -1
- package/dist/client/store/memoryStore.js +2 -2
- package/dist/client/store/memoryStore.js.map +1 -1
- package/dist/client/store/store.d.ts +2 -1
- 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 +25 -16
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +69 -40
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts +12 -11
- package/dist/mqttPacket/BitMask.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.js +10 -18
- package/dist/mqttPacket/BitMask.js.map +1 -1
- package/dist/mqttPacket/PacketType.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.d.ts +2 -2
- package/dist/mqttPacket/Properties.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.js.map +1 -1
- package/dist/mqttPacket/ReasonCode.d.ts +1 -0
- 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.map +1 -1
- package/dist/mqttPacket/auth.d.ts +3 -5
- 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 +4 -5
- 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 +26 -27
- 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 +1 -13
- 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 +4 -5
- 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 +1 -15
- package/dist/mqttPacket/encoder.d.ts.map +1 -1
- package/dist/mqttPacket/encoder.js +4 -27
- package/dist/mqttPacket/encoder.js.map +1 -1
- package/dist/mqttPacket/length.js +1 -1
- package/dist/mqttPacket/length.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 +4 -5
- 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 +4 -5
- 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 +14 -14
- 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 +4 -5
- 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 +36 -7
- 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 +1 -8
- package/dist/mqttPacket/types.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.d.ts +4 -5
- 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 +23 -6
- 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 +1 -1
- package/dist/node/tcpClient.d.ts.map +1 -1
- package/dist/node/tcpClient.js +12 -7
- package/dist/node/tcpClient.js.map +1 -1
- package/dist/node/tcpServer.d.ts.map +1 -1
- package/dist/node/tcpServer.js +4 -0
- package/dist/node/tcpServer.js.map +1 -1
- package/dist/node/tlsServer.d.ts +19 -0
- package/dist/node/tlsServer.d.ts.map +1 -0
- package/dist/node/tlsServer.js +58 -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 +44 -69
- 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 +198 -24
- 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 +8 -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 +29 -6
- 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 +11 -9
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +67 -15
- 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 +47 -17
- 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 +40 -3
- 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 +7 -0
- package/dist/web/wsClient.d.ts.map +1 -0
- package/dist/web/wsClient.js +22 -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 +91 -49
- package/mqttPacket/BitMask.ts +11 -19
- package/mqttPacket/Properties.ts +6 -3
- package/mqttPacket/ReasonCode.ts +2 -1
- package/mqttPacket/auth.test.ts +1 -1
- package/mqttPacket/auth.ts +41 -48
- package/mqttPacket/codec.ts +146 -0
- package/mqttPacket/connack.ts +57 -68
- package/mqttPacket/connect.test.ts +2 -2
- package/mqttPacket/connect.ts +197 -204
- package/mqttPacket/decoder.test.ts +0 -39
- package/mqttPacket/decoder.ts +9 -36
- package/mqttPacket/disconnect.ts +57 -68
- package/mqttPacket/encoder.ts +5 -40
- package/mqttPacket/length.ts +1 -1
- package/mqttPacket/mod.ts +48 -200
- package/mqttPacket/pingreq.ts +21 -27
- package/mqttPacket/pingres.ts +21 -27
- package/mqttPacket/protocolLevels.ts +12 -7
- package/mqttPacket/pubblishAcks.ts +68 -77
- package/mqttPacket/publish.ts +76 -83
- package/mqttPacket/suback.ts +48 -58
- package/mqttPacket/subscribe.ts +141 -117
- package/mqttPacket/types.ts +1 -9
- package/mqttPacket/unsuback.ts +46 -58
- package/mqttPacket/unsubscribe.ts +74 -63
- 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 +13 -12
- package/node/tcpServer.test.ts +24 -20
- package/node/tcpServer.ts +6 -0
- package/node/tlsServer.test.ts +94 -0
- package/node/tlsServer.ts +81 -0
- package/node/wrapNodeSocket.ts +7 -30
- package/package.json +73 -45
- package/persistence/basicPersistence.ts +495 -0
- package/persistence/deps.ts +11 -1
- package/persistence/memory/memoryPersistence.ts +12 -152
- package/persistence/memory/memoryStorage.ts +232 -0
- package/persistence/mod.ts +4 -4
- package/persistence/persistence.test.ts +24 -0
- package/persistence/persistence.testing.ts +1324 -0
- package/persistence/persistence.ts +111 -67
- 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 +658 -74
- package/server/deps.ts +25 -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 +189 -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 +158 -39
- package/server/handlers/handleUnsubscribe.test.ts +79 -0
- package/server/handlers/handleUnsubscribe.ts +29 -5
- 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 +4 -3
- package/server/preconnect.test.ts +151 -0
- package/server/server.ts +115 -17
- package/socket/socket.test.ts +91 -0
- package/socket/socket.ts +81 -31
- 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 +57 -22
- package/utils/bufferedAsyncIterable.test.ts +92 -0
- package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +1 -1
- 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 +62 -7
- 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 +25 -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/dist/persistence/store.d.ts +0 -13
- 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 -15
- package/server/test/handleConnect.test.ts +0 -130
- package/server/test/test-handlers.ts +0 -53
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { TcpClient } from "@seriousme/opifex/tcpClient";
|
|
4
|
+
import { TcpServer } from "@seriousme/opifex/tcpServer";
|
|
5
|
+
import { delay, logger, LogLevel } from "@seriousme/opifex/utils";
|
|
6
|
+
import type { PublishPacket, QoS } from "@seriousme/opifex/mqttPacket";
|
|
7
|
+
|
|
8
|
+
logger.level(LogLevel.info);
|
|
9
|
+
|
|
10
|
+
test("Test pubSub using TCP client and server using memoryPersistence", async function () {
|
|
11
|
+
const server = new TcpServer({ port: 0 }, {
|
|
12
|
+
// just an example on how to configure the server
|
|
13
|
+
configuration: { context: { maximumConnectPacketSize: 3000 } },
|
|
14
|
+
});
|
|
15
|
+
server.start();
|
|
16
|
+
|
|
17
|
+
assert.deepStrictEqual(
|
|
18
|
+
server.port !== undefined,
|
|
19
|
+
true,
|
|
20
|
+
"server runs a a random port",
|
|
21
|
+
);
|
|
22
|
+
logger.info(
|
|
23
|
+
`TCP server running on port: ${server.port}, address: ${server.address}`,
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const params = {
|
|
27
|
+
url: new URL(`mqtt://${server.address}:${server.port}`),
|
|
28
|
+
numberOfRetries: 0,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const client = new TcpClient();
|
|
32
|
+
await client.connect(params);
|
|
33
|
+
logger.info("Client connected to server at", client.url);
|
|
34
|
+
|
|
35
|
+
const publishSet: { topic: string; qos: QoS }[] = [
|
|
36
|
+
{ topic: "t0@q0", qos: 0 },
|
|
37
|
+
{ topic: "t1@q0", qos: 0 },
|
|
38
|
+
{ topic: "t2@q0", qos: 0 },
|
|
39
|
+
{ topic: "t0@q1", qos: 1 },
|
|
40
|
+
{ topic: "t1@q1", qos: 1 },
|
|
41
|
+
{ topic: "t2@q1", qos: 1 },
|
|
42
|
+
{ topic: "t0@q2", qos: 2 },
|
|
43
|
+
{ topic: "t1@q2", qos: 2 },
|
|
44
|
+
{ topic: "t2@q2", qos: 2 },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const subscriptions = publishSet.map((item) => ({
|
|
48
|
+
topicFilter: item.topic,
|
|
49
|
+
qos: item.qos,
|
|
50
|
+
}));
|
|
51
|
+
await client.subscribe({
|
|
52
|
+
subscriptions,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// the IIFE ensures message reception runs in parallel
|
|
56
|
+
logger.info("Start receiving");
|
|
57
|
+
const received: PublishPacket[] = [];
|
|
58
|
+
(async function () {
|
|
59
|
+
for await (const item of client.messages()) {
|
|
60
|
+
logger.verbose("Receiving:", item.topic, "--", item.qos);
|
|
61
|
+
received.push(item);
|
|
62
|
+
}
|
|
63
|
+
})();
|
|
64
|
+
// end of IIFE
|
|
65
|
+
for (const item of publishSet) {
|
|
66
|
+
logger.verbose("Publishing:", item.topic, "--", item.qos);
|
|
67
|
+
await client.publish({
|
|
68
|
+
topic: item.topic,
|
|
69
|
+
qos: item.qos,
|
|
70
|
+
payload: new Uint8Array([0x01]),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
await delay(100);
|
|
75
|
+
logger.info("Disconnect client");
|
|
76
|
+
await client.disconnect();
|
|
77
|
+
|
|
78
|
+
logger.info("Check completeness");
|
|
79
|
+
for (const item of publishSet) {
|
|
80
|
+
const found = received.find((f) =>
|
|
81
|
+
f.topic == item.topic && f.qos === item.qos
|
|
82
|
+
);
|
|
83
|
+
logger.verbose("Found:", item.topic, "--", item.qos);
|
|
84
|
+
assert(found, `${item.topic} -- ${item.qos}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
logger.info("Stop server");
|
|
88
|
+
server.stop();
|
|
89
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { TcpClient } from "@seriousme/opifex/tcpClient";
|
|
4
|
+
import { TlsServer } from "@seriousme/opifex/tlsServer";
|
|
5
|
+
import { SqlitePersistence } from "@seriousme/opifex/persistence";
|
|
6
|
+
import { delay, logger, LogLevel } from "@seriousme/opifex/utils";
|
|
7
|
+
import type { PublishPacket, QoS } from "@seriousme/opifex/mqttPacket";
|
|
8
|
+
import { generateLocalhostCerts } from "../dev_utils/generateCert.ts";
|
|
9
|
+
|
|
10
|
+
logger.level(LogLevel.info);
|
|
11
|
+
|
|
12
|
+
test("Test pubSub using TLS client and server and sqlitePersistence", async function () {
|
|
13
|
+
// the localhost certs generate here are great for testing but lack securiity
|
|
14
|
+
// use something like LetsEncrypt for any serious server
|
|
15
|
+
// generateLocalhostCerts is a dev tool and relies on node-forge as a (dev)dependency
|
|
16
|
+
const { key, cert, caCert } = generateLocalhostCerts();
|
|
17
|
+
const dbFile = ":memory:";
|
|
18
|
+
// .start() combines instance creation and async initialization
|
|
19
|
+
const persistence = await SqlitePersistence.start(dbFile);
|
|
20
|
+
const server = new TlsServer({ port: 0, key, cert }, { persistence });
|
|
21
|
+
server.start();
|
|
22
|
+
|
|
23
|
+
assert.deepStrictEqual(
|
|
24
|
+
server.port !== undefined,
|
|
25
|
+
true,
|
|
26
|
+
"TLS server runs on a random port",
|
|
27
|
+
);
|
|
28
|
+
logger.info(
|
|
29
|
+
`TLS server running on port: ${server.port}, address: ${server.address}`,
|
|
30
|
+
);
|
|
31
|
+
// pick the correct hostname
|
|
32
|
+
const hostname = server.address === "0.0.0.0" ? "127.0.0.1" : server.address;
|
|
33
|
+
|
|
34
|
+
const params = {
|
|
35
|
+
url: new URL(`mqtts://${hostname}:${server.port}`),
|
|
36
|
+
numberOfRetries: 0,
|
|
37
|
+
// since we signed our server cert ourselves we need to add the caCert
|
|
38
|
+
// this is not required if you use a public Certificate Authority
|
|
39
|
+
caCerts: [caCert],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const client = new TcpClient();
|
|
43
|
+
await client.connect(params);
|
|
44
|
+
logger.info("Client connected to server at", client.url);
|
|
45
|
+
|
|
46
|
+
const publishSet: { topic: string; qos: QoS }[] = [
|
|
47
|
+
{ topic: "t0@q0", qos: 0 },
|
|
48
|
+
{ topic: "t1@q0", qos: 0 },
|
|
49
|
+
{ topic: "t2@q0", qos: 0 },
|
|
50
|
+
{ topic: "t0@q1", qos: 1 },
|
|
51
|
+
{ topic: "t1@q1", qos: 1 },
|
|
52
|
+
{ topic: "t2@q1", qos: 1 },
|
|
53
|
+
{ topic: "t0@q2", qos: 2 },
|
|
54
|
+
{ topic: "t1@q2", qos: 2 },
|
|
55
|
+
{ topic: "t2@q2", qos: 2 },
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
const subscriptions = publishSet.map((item) => ({
|
|
59
|
+
topicFilter: item.topic,
|
|
60
|
+
qos: item.qos,
|
|
61
|
+
}));
|
|
62
|
+
await client.subscribe({
|
|
63
|
+
subscriptions,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// the IIFE ensures message reception runs in parallel
|
|
67
|
+
logger.info("Start receiving");
|
|
68
|
+
const received: PublishPacket[] = [];
|
|
69
|
+
(async function () {
|
|
70
|
+
for await (const item of client.messages()) {
|
|
71
|
+
logger.verbose("Receiving:", item.topic, "--", item.qos);
|
|
72
|
+
received.push(item);
|
|
73
|
+
}
|
|
74
|
+
})();
|
|
75
|
+
// end of IIFE
|
|
76
|
+
for (const item of publishSet) {
|
|
77
|
+
logger.verbose("Publishing:", item.topic, "--", item.qos);
|
|
78
|
+
await client.publish({
|
|
79
|
+
topic: item.topic,
|
|
80
|
+
qos: item.qos,
|
|
81
|
+
payload: new Uint8Array([0x01]),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
await delay(100);
|
|
86
|
+
logger.info("Disconnect client");
|
|
87
|
+
await client.disconnect();
|
|
88
|
+
|
|
89
|
+
logger.info("Check completeness");
|
|
90
|
+
for (const item of publishSet) {
|
|
91
|
+
const found = received.find((f) =>
|
|
92
|
+
f.topic == item.topic && f.qos === item.qos
|
|
93
|
+
);
|
|
94
|
+
logger.verbose("Found:", item.topic, "--", item.qos);
|
|
95
|
+
assert(found, `${item.topic} -- ${item.qos}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
logger.info("Stop server");
|
|
99
|
+
server.stop();
|
|
100
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { delay, logger, LogLevel } from "@seriousme/opifex/utils";
|
|
4
|
+
|
|
5
|
+
import type { PublishPacket, QoS } from "@seriousme/opifex/mqttPacket";
|
|
6
|
+
|
|
7
|
+
logger.level(LogLevel.info);
|
|
8
|
+
|
|
9
|
+
test("Deno: Test pubSub using WebSocket client and server and memoryPersistence", async function () {
|
|
10
|
+
// Nodejs does not natively support WebSockets so we only import Websocket client and server here
|
|
11
|
+
if (typeof Deno !== "undefined") {
|
|
12
|
+
const { WsClient } = await import("@seriousme/opifex/wsClient");
|
|
13
|
+
const { WsServer } = await import("@seriousme/opifex/wsServer");
|
|
14
|
+
const server = new WsServer({ port: 0 }, {});
|
|
15
|
+
server.start();
|
|
16
|
+
|
|
17
|
+
assert.deepStrictEqual(
|
|
18
|
+
server.port !== undefined,
|
|
19
|
+
true,
|
|
20
|
+
"WebSocket server runs on a random port",
|
|
21
|
+
);
|
|
22
|
+
logger.info(
|
|
23
|
+
`WebSocket server running on port: ${server.port}, address: ${server.address}`,
|
|
24
|
+
);
|
|
25
|
+
// pick the correct hostname
|
|
26
|
+
const hostname = server.address === "0.0.0.0"
|
|
27
|
+
? "127.0.0.1"
|
|
28
|
+
: server.address;
|
|
29
|
+
|
|
30
|
+
const params = {
|
|
31
|
+
url: new URL(`ws://${hostname}:${server.port}`),
|
|
32
|
+
numberOfRetries: 0,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const client = new WsClient();
|
|
36
|
+
await client.connect(params);
|
|
37
|
+
logger.info("Client connected to server at", client.url);
|
|
38
|
+
|
|
39
|
+
const publishSet: { topic: string; qos: QoS }[] = [
|
|
40
|
+
{ topic: "t0@q0", qos: 0 },
|
|
41
|
+
{ topic: "t1@q0", qos: 0 },
|
|
42
|
+
{ topic: "t2@q0", qos: 0 },
|
|
43
|
+
{ topic: "t0@q1", qos: 1 },
|
|
44
|
+
{ topic: "t1@q1", qos: 1 },
|
|
45
|
+
{ topic: "t2@q1", qos: 1 },
|
|
46
|
+
{ topic: "t0@q2", qos: 2 },
|
|
47
|
+
{ topic: "t1@q2", qos: 2 },
|
|
48
|
+
{ topic: "t2@q2", qos: 2 },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const subscriptions = publishSet.map((item) => ({
|
|
52
|
+
topicFilter: item.topic,
|
|
53
|
+
qos: item.qos,
|
|
54
|
+
}));
|
|
55
|
+
await client.subscribe({
|
|
56
|
+
subscriptions,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// the IIFE ensures message reception runs in parallel
|
|
60
|
+
logger.info("Start receiving");
|
|
61
|
+
const received: PublishPacket[] = [];
|
|
62
|
+
(async function () {
|
|
63
|
+
for await (const item of client.messages()) {
|
|
64
|
+
logger.verbose("Receiving:", item.topic, "--", item.qos);
|
|
65
|
+
received.push(item);
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
// end of IIFE
|
|
69
|
+
for (const item of publishSet) {
|
|
70
|
+
logger.verbose("Publishing:", item.topic, "--", item.qos);
|
|
71
|
+
await client.publish({
|
|
72
|
+
topic: item.topic,
|
|
73
|
+
qos: item.qos,
|
|
74
|
+
payload: new Uint8Array([0x01]),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await delay(100);
|
|
79
|
+
logger.info("Disconnect client");
|
|
80
|
+
await client.disconnect();
|
|
81
|
+
|
|
82
|
+
logger.info("Check completeness");
|
|
83
|
+
for (const item of publishSet) {
|
|
84
|
+
const found = received.find((f) =>
|
|
85
|
+
f.topic == item.topic && f.qos === item.qos
|
|
86
|
+
);
|
|
87
|
+
logger.verbose("Found:", item.topic, "--", item.qos);
|
|
88
|
+
assert(found, `${item.topic} -- ${item.qos}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
logger.info("Stop server");
|
|
92
|
+
server.stop();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { test } from "node:test";
|
|
3
|
-
import {
|
|
3
|
+
import { createMockSockConn } from "../dev_utils/mod.ts";
|
|
4
4
|
import { encode, MQTTLevel, PacketType } from "../mqttPacket/mod.ts";
|
|
5
5
|
import { MqttConn, MqttConnError } from "./mqttConn.ts";
|
|
6
6
|
import type { AnyPacket, CodecOpts } from "../mqttPacket/mod.ts";
|
|
@@ -50,7 +50,7 @@ test("MqttConn should act as asyncIterator", async () => {
|
|
|
50
50
|
const publish = encode(publishPacket, codecOptsV4);
|
|
51
51
|
const disconnect = encode(disconnectPacket, codecOptsV4);
|
|
52
52
|
|
|
53
|
-
const conn =
|
|
53
|
+
const conn = createMockSockConn(
|
|
54
54
|
[connect, publish, disconnect],
|
|
55
55
|
new Uint8Array(),
|
|
56
56
|
);
|
|
@@ -62,13 +62,13 @@ test("MqttConn should act as asyncIterator", async () => {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
assert.deepStrictEqual(packets.length, 3);
|
|
65
|
-
assert.deepStrictEqual(packets[0], connectPacket);
|
|
66
|
-
assert.deepStrictEqual(packets[1], publishPacket);
|
|
67
|
-
assert.deepStrictEqual(packets[2], disconnectPacket);
|
|
65
|
+
assert.deepStrictEqual(packets[0], connectPacket, "has connect packet");
|
|
66
|
+
assert.deepStrictEqual(packets[1], publishPacket, "has publish packet");
|
|
67
|
+
assert.deepStrictEqual(packets[2], disconnectPacket, "has disconnect packet");
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
test("MqttConn should close on malformed length", async () => {
|
|
71
|
-
const conn =
|
|
71
|
+
const conn = createMockSockConn([new Uint8Array([1, 175])], new Uint8Array());
|
|
72
72
|
const mqttConn = new MqttConn({ conn });
|
|
73
73
|
|
|
74
74
|
const packets: AnyPacket[] = [];
|
|
@@ -86,7 +86,7 @@ test("MqttConn should close on failed packets", async () => {
|
|
|
86
86
|
const publish = encode(publishPacket, codecOptsV4);
|
|
87
87
|
const brokenPublish = publish.slice(0, 7);
|
|
88
88
|
|
|
89
|
-
const conn =
|
|
89
|
+
const conn = createMockSockConn([connect, brokenPublish], new Uint8Array());
|
|
90
90
|
const mqttConn = new MqttConn({ conn });
|
|
91
91
|
|
|
92
92
|
const packets: AnyPacket[] = [];
|
|
@@ -103,7 +103,7 @@ test("MqttConn should close on failed packets", async () => {
|
|
|
103
103
|
test("MqttConn should close on packets too large", async () => {
|
|
104
104
|
const connect = encode(connectPacket, codecOptsV4);
|
|
105
105
|
|
|
106
|
-
const conn =
|
|
106
|
+
const conn = createMockSockConn([connect], new Uint8Array());
|
|
107
107
|
const mqttConn = new MqttConn({ conn, maxIncomingPacketSize: 20 });
|
|
108
108
|
|
|
109
109
|
const packets: AnyPacket[] = [];
|
|
@@ -119,7 +119,7 @@ test("MqttConn should close on packets too large", async () => {
|
|
|
119
119
|
test("MqttConn should be writable", async () => {
|
|
120
120
|
const connect = encode(connectPacket, codecOptsV4);
|
|
121
121
|
const writer = new Uint8Array(24);
|
|
122
|
-
const conn =
|
|
122
|
+
const conn = createMockSockConn([connect], writer);
|
|
123
123
|
const mqttConn = new MqttConn({ conn });
|
|
124
124
|
await mqttConn.send(connectPacket);
|
|
125
125
|
assert.deepStrictEqual(writer, connect);
|
package/mqttConn/mqttConn.ts
CHANGED
|
@@ -6,7 +6,6 @@ import type {
|
|
|
6
6
|
AnyPacket,
|
|
7
7
|
CodecOpts,
|
|
8
8
|
LengthDecoderResult,
|
|
9
|
-
ProtocolLevel,
|
|
10
9
|
} from "../mqttPacket/mod.ts";
|
|
11
10
|
|
|
12
11
|
import {
|
|
@@ -26,10 +25,19 @@ import { Conn } from "../socket/socket.ts";
|
|
|
26
25
|
export const MqttConnError = {
|
|
27
26
|
invalidPacket: "Invalid Packet",
|
|
28
27
|
packetTooLarge: "Packet too large",
|
|
28
|
+
connectPacketTooLarge: "Connect Packet too large",
|
|
29
29
|
UnexpectedEof: "Unexpected EOF",
|
|
30
30
|
} as const;
|
|
31
31
|
|
|
32
|
-
const DEFAULT_MAX_PACKETSIZE =
|
|
32
|
+
const DEFAULT_MAX_PACKETSIZE = 4 * 1024; // 4Kb
|
|
33
|
+
|
|
34
|
+
export type SendResult =
|
|
35
|
+
| { sent: true }
|
|
36
|
+
| {
|
|
37
|
+
sent: false;
|
|
38
|
+
reason: "packetTooLarge" | "connectionClosed";
|
|
39
|
+
size?: number;
|
|
40
|
+
};
|
|
33
41
|
|
|
34
42
|
/**
|
|
35
43
|
* Interface for MQTT connection handling
|
|
@@ -42,7 +50,7 @@ export interface IMqttConn extends AsyncIterable<AnyPacket> {
|
|
|
42
50
|
/** Reason for connection closure if any */
|
|
43
51
|
readonly reason: string | undefined;
|
|
44
52
|
/** Send an MQTT packet */
|
|
45
|
-
send(data: AnyPacket): Promise<
|
|
53
|
+
send(data: AnyPacket): Promise<SendResult>;
|
|
46
54
|
/** Close the connection */
|
|
47
55
|
close(): void;
|
|
48
56
|
}
|
|
@@ -54,11 +62,11 @@ export interface IMqttConn extends AsyncIterable<AnyPacket> {
|
|
|
54
62
|
* @throws Error if EOF reached unexpectedly
|
|
55
63
|
*/
|
|
56
64
|
async function readByte(conn: Conn): Promise<number> {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
assert(
|
|
60
|
-
assert(
|
|
61
|
-
return
|
|
65
|
+
const buff = await conn.read(1);
|
|
66
|
+
assert(buff !== null, MqttConnError.UnexpectedEof);
|
|
67
|
+
assert(buff !== undefined, MqttConnError.UnexpectedEof);
|
|
68
|
+
assert(buff.byteLength !== 0, MqttConnError.UnexpectedEof);
|
|
69
|
+
return buff[0] || 0;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
/**
|
|
@@ -67,31 +75,30 @@ async function readByte(conn: Conn): Promise<number> {
|
|
|
67
75
|
* @param buf Buffer to read into
|
|
68
76
|
* @throws Error if EOF reached unexpectedly
|
|
69
77
|
*/
|
|
70
|
-
async function readFull(conn: Conn,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
assert(read !== 0, MqttConnError.UnexpectedEof);
|
|
76
|
-
bytesRead += read;
|
|
77
|
-
}
|
|
78
|
+
async function readFull(conn: Conn, length: number): Promise<Uint8Array> {
|
|
79
|
+
const buff = await conn.read(length);
|
|
80
|
+
assert(buff !== null, MqttConnError.UnexpectedEof);
|
|
81
|
+
assert(buff.byteLength === length, MqttConnError.UnexpectedEof);
|
|
82
|
+
return buff;
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
/**
|
|
81
86
|
* Read a complete MQTT packet from the connection
|
|
82
87
|
* @param conn Connection to read from
|
|
83
|
-
* @param
|
|
88
|
+
* @param codecOpts the CodecOpts
|
|
84
89
|
* @returns Decoded MQTT packet
|
|
85
90
|
* @throws Error if packet is invalid or too large
|
|
86
91
|
*/
|
|
87
92
|
export async function readPacket(
|
|
88
93
|
conn: Conn,
|
|
89
94
|
codecOpts: CodecOpts,
|
|
95
|
+
maxConnectPacketSize: number,
|
|
90
96
|
): Promise<AnyPacket> {
|
|
91
97
|
// fixed header is 1 byte of type + flags
|
|
92
98
|
// + a maximum of 4 bytes to encode the remaining length
|
|
93
99
|
const decodeLength = getLengthDecoder();
|
|
94
100
|
const firstByte = await readByte(conn);
|
|
101
|
+
const isConnect = (firstByte >> 4) === 1;
|
|
95
102
|
let result: LengthDecoderResult;
|
|
96
103
|
do {
|
|
97
104
|
const byte = await readByte(conn);
|
|
@@ -99,14 +106,19 @@ export async function readPacket(
|
|
|
99
106
|
} while (!result.done);
|
|
100
107
|
|
|
101
108
|
const remainingLength = result.length;
|
|
109
|
+
if (isConnect) {
|
|
110
|
+
assert(
|
|
111
|
+
remainingLength < maxConnectPacketSize - 1,
|
|
112
|
+
MqttConnError.connectPacketTooLarge,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
102
115
|
const maxIncomingPacketSize = codecOpts.maxIncomingPacketSize;
|
|
103
116
|
assert(
|
|
104
117
|
remainingLength < maxIncomingPacketSize - 1,
|
|
105
118
|
MqttConnError.packetTooLarge,
|
|
106
119
|
);
|
|
107
|
-
const packetBuf = new Uint8Array(remainingLength);
|
|
108
120
|
// read the rest of the packet
|
|
109
|
-
await readFull(conn,
|
|
121
|
+
const packetBuf = await readFull(conn, remainingLength);
|
|
110
122
|
const packet = decodePayload(firstByte, packetBuf, codecOpts);
|
|
111
123
|
assert(packet !== null, MqttConnError.UnexpectedEof);
|
|
112
124
|
return packet;
|
|
@@ -118,6 +130,8 @@ export async function readPacket(
|
|
|
118
130
|
export class MqttConn implements IMqttConn {
|
|
119
131
|
/** Underlying connection */
|
|
120
132
|
readonly conn: Conn;
|
|
133
|
+
/** Maximum Connect packet size */
|
|
134
|
+
readonly maxConnectPacketSize: number;
|
|
121
135
|
/** codecOpts */
|
|
122
136
|
codecOpts: CodecOpts;
|
|
123
137
|
/** Reason for connection closure if any */
|
|
@@ -129,24 +143,25 @@ export class MqttConn implements IMqttConn {
|
|
|
129
143
|
* Create new MQTT connection
|
|
130
144
|
* @param options Connection options
|
|
131
145
|
* @param options.conn Underlying socket connection
|
|
132
|
-
* @param options.
|
|
133
|
-
* @param options.
|
|
146
|
+
* @param options.maxConnectPacketSize Maximum allowed connect packet size
|
|
147
|
+
* @param options.maxIncomingPacketSize Maximum allowed incoming packet size
|
|
148
|
+
* @param options.maxOutGoingPacketSize Maximum allowed outgoing packet size
|
|
134
149
|
* @param options.protocolLevel Supported protocolLevel
|
|
135
150
|
*/
|
|
136
|
-
constructor(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
conn
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}) {
|
|
145
|
-
this.conn = new Conn(conn);
|
|
151
|
+
constructor(
|
|
152
|
+
options:
|
|
153
|
+
& { conn: SockConn; maxConnectPacketSize?: number }
|
|
154
|
+
& Partial<CodecOpts>,
|
|
155
|
+
) {
|
|
156
|
+
this.conn = new Conn(options.conn);
|
|
157
|
+
this.maxConnectPacketSize = options.maxConnectPacketSize ??
|
|
158
|
+
DEFAULT_MAX_PACKETSIZE;
|
|
146
159
|
this.codecOpts = {
|
|
147
|
-
maxIncomingPacketSize
|
|
148
|
-
|
|
149
|
-
|
|
160
|
+
maxIncomingPacketSize: options.maxIncomingPacketSize ??
|
|
161
|
+
DEFAULT_MAX_PACKETSIZE,
|
|
162
|
+
maxOutgoingPacketSize: options.maxOutgoingPacketSize ??
|
|
163
|
+
DEFAULT_MAX_PACKETSIZE,
|
|
164
|
+
protocolLevel: options.protocolLevel ?? MQTTLevel.unknown,
|
|
150
165
|
};
|
|
151
166
|
}
|
|
152
167
|
|
|
@@ -170,9 +185,15 @@ export class MqttConn implements IMqttConn {
|
|
|
170
185
|
* @returns a Promise that resolves to AnyPacket if the connection is open
|
|
171
186
|
* and working nominally, undefined otherwise.
|
|
172
187
|
*/
|
|
173
|
-
#receive(): Promise<AnyPacket | undefined> {
|
|
188
|
+
async #receive(): Promise<AnyPacket | undefined> {
|
|
174
189
|
if (!this._isClosed) {
|
|
175
|
-
|
|
190
|
+
try {
|
|
191
|
+
return await readPacket(
|
|
192
|
+
this.conn,
|
|
193
|
+
this.codecOpts,
|
|
194
|
+
this.maxConnectPacketSize,
|
|
195
|
+
);
|
|
196
|
+
} catch (err) {
|
|
176
197
|
if (err instanceof Error) {
|
|
177
198
|
if (err.name === "PartialReadError") {
|
|
178
199
|
err.message = MqttConnError.UnexpectedEof;
|
|
@@ -182,31 +203,52 @@ export class MqttConn implements IMqttConn {
|
|
|
182
203
|
// packet too large, malformed packet or connection closed.
|
|
183
204
|
this.close();
|
|
184
205
|
return undefined;
|
|
185
|
-
}
|
|
206
|
+
}
|
|
186
207
|
}
|
|
187
208
|
return Promise.resolve(undefined);
|
|
188
209
|
}
|
|
189
210
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
211
|
+
/** Return next packet. */
|
|
212
|
+
async next(): Promise<IteratorResult<AnyPacket>> {
|
|
213
|
+
const packet = await this.#receive();
|
|
214
|
+
|
|
215
|
+
if (packet !== undefined) {
|
|
216
|
+
return { value: packet, done: false };
|
|
194
217
|
}
|
|
218
|
+
|
|
219
|
+
return { value: undefined, done: true };
|
|
195
220
|
}
|
|
196
221
|
|
|
197
|
-
/**
|
|
222
|
+
/** Async iterator. */
|
|
223
|
+
[Symbol.asyncIterator](): this {
|
|
224
|
+
return this;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/*
|
|
198
228
|
* Send an MQTT packet
|
|
199
229
|
* @param data Packet to send
|
|
200
230
|
*/
|
|
201
|
-
async send(data: AnyPacket): Promise<
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
231
|
+
async send(data: AnyPacket): Promise<SendResult> {
|
|
232
|
+
if (!this._isClosed) {
|
|
233
|
+
try {
|
|
234
|
+
const encoded = encode(data, this.codecOpts);
|
|
235
|
+
if (encoded.byteLength > this.codecOpts.maxOutgoingPacketSize) {
|
|
236
|
+
return {
|
|
237
|
+
sent: false,
|
|
238
|
+
reason: "packetTooLarge",
|
|
239
|
+
size: encoded.byteLength,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
await this.conn.write(encoded);
|
|
243
|
+
return { sent: true };
|
|
244
|
+
} catch (err) {
|
|
245
|
+
if (err instanceof Error) {
|
|
246
|
+
this._reason = err.message;
|
|
247
|
+
}
|
|
248
|
+
this.close();
|
|
207
249
|
}
|
|
208
|
-
this.close();
|
|
209
250
|
}
|
|
251
|
+
return { sent: false, reason: "connectionClosed" };
|
|
210
252
|
}
|
|
211
253
|
|
|
212
254
|
/** Whether connection is closed */
|
package/mqttPacket/BitMask.ts
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Object containing bit mask values from 2^0 to 2^7
|
|
3
|
-
* @
|
|
4
|
-
* @
|
|
5
|
-
* @property {number} bit0 - Represents 2^0 = 1
|
|
6
|
-
* @property {number} bit1 - Represents 2^1 = 2
|
|
7
|
-
* @property {number} bit2 - Represents 2^2 = 4
|
|
8
|
-
* @property {number} bit3 - Represents 2^3 = 8
|
|
9
|
-
* @property {number} bit4 - Represents 2^4 = 16
|
|
10
|
-
* @property {number} bit5 - Represents 2^5 = 32
|
|
11
|
-
* @property {number} bit6 - Represents 2^6 = 64
|
|
12
|
-
* @property {number} bit7 - Represents 2^7 = 128
|
|
3
|
+
* @readonly
|
|
4
|
+
* @enum {number}
|
|
13
5
|
*/
|
|
14
|
-
export const BitMask
|
|
15
|
-
bit0: 2 ** 0,
|
|
16
|
-
bit1: 2 ** 1,
|
|
17
|
-
bit2: 2 ** 2,
|
|
18
|
-
bit3: 2 ** 3,
|
|
19
|
-
bit4: 2 ** 4,
|
|
20
|
-
bit5: 2 ** 5,
|
|
21
|
-
bit6: 2 ** 6,
|
|
22
|
-
bit7: 2 ** 7,
|
|
6
|
+
export const BitMask = {
|
|
7
|
+
bit0: 2 ** 0, // 1
|
|
8
|
+
bit1: 2 ** 1, // 2
|
|
9
|
+
bit2: 2 ** 2, // 4
|
|
10
|
+
bit3: 2 ** 3, // 8
|
|
11
|
+
bit4: 2 ** 4, // 16
|
|
12
|
+
bit5: 2 ** 5, // 32
|
|
13
|
+
bit6: 2 ** 6, // 64
|
|
14
|
+
bit7: 2 ** 7, // 128
|
|
23
15
|
} as const;
|
package/mqttPacket/Properties.ts
CHANGED
|
@@ -117,11 +117,14 @@ export type ValidPropertyNumber =
|
|
|
117
117
|
(typeof propertyToId)[keyof typeof propertyToId];
|
|
118
118
|
// Then, create a mapped type that iterates over the property names
|
|
119
119
|
// and uses propertyToKind to look up the correct TypeScript type.
|
|
120
|
+
// properties are optional, but can also hold "undefined"
|
|
120
121
|
|
|
121
122
|
type AllMqttv5Properties = {
|
|
122
|
-
[K in PropertyNames]?:
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
[K in PropertyNames]?:
|
|
124
|
+
| Mqttv5PropertyType<
|
|
125
|
+
typeof propertyToKind[typeof propertyToId[K]]
|
|
126
|
+
>
|
|
127
|
+
| undefined;
|
|
125
128
|
};
|
|
126
129
|
|
|
127
130
|
type PropertyByNumberType = InvertRecord<typeof propertyToId>;
|
package/mqttPacket/ReasonCode.ts
CHANGED
|
@@ -58,7 +58,8 @@ export const ReasonCode = {
|
|
|
58
58
|
*/
|
|
59
59
|
|
|
60
60
|
export type ReasonCodeByNumberType = InvertRecord<typeof ReasonCode>;
|
|
61
|
-
|
|
61
|
+
/** Map of numeric reason codes to names. */
|
|
62
|
+
export const ReasonCodeByNumber: ReasonCodeByNumberType = Object
|
|
62
63
|
.fromEntries(
|
|
63
64
|
Object.entries(ReasonCode).map(([k, v]) => [v, k]),
|
|
64
65
|
) as ReasonCodeByNumberType;
|
package/mqttPacket/auth.test.ts
CHANGED
|
@@ -75,7 +75,7 @@ test("encode/decode minimal auth V5", () => {
|
|
|
75
75
|
|
|
76
76
|
test("encode/decode auth V5", () => {
|
|
77
77
|
const packet: AuthPacket = {
|
|
78
|
-
protocolLevel:
|
|
78
|
+
protocolLevel: MQTTLevel.v5,
|
|
79
79
|
type: PacketType.auth,
|
|
80
80
|
reasonCode: ReasonCode.continueAuthentication,
|
|
81
81
|
properties: {
|