@seriousme/opifex 1.11.3 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +2 -0
- package/client/client.ts +51 -41
- package/client/context.ts +75 -21
- package/client/deps.ts +4 -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 +1 -1
- 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 -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 +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 +13 -16
- 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 +1 -1
- 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 +23 -15
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +56 -35
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts.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 +4 -5
- 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 +6 -27
- 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/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 +4 -5
- 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 +5 -5
- 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 +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 +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 +76 -44
- 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 +175 -182
- package/mqttPacket/decoder.test.ts +0 -39
- package/mqttPacket/decoder.ts +8 -35
- package/mqttPacket/disconnect.ts +57 -68
- package/mqttPacket/encoder.ts +5 -40
- 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 +56 -70
- package/mqttPacket/publish.ts +67 -74
- 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 +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 +4 -9
- 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 -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 +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/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
package/trie/trie.test.ts
CHANGED
|
@@ -141,7 +141,15 @@ test("Removal of object values works", () => {
|
|
|
141
141
|
assert.ok(includesAll(root.match("foo/bar"), [c1, c2]), "two items found");
|
|
142
142
|
root.remove("foo/bar", c2);
|
|
143
143
|
assert.ok(includesAll(root.match("foo/bar"), [c1]), "one item found");
|
|
144
|
-
|
|
144
|
+
// partial filter
|
|
145
|
+
root.remove("foo/bar", { a: 1 });
|
|
145
146
|
assert.ok(includesAll(root.match("foo/bar"), []), "empty array");
|
|
146
147
|
assert.deepStrictEqual(root.match("foo/bar").length, 0, "matches left");
|
|
147
148
|
});
|
|
149
|
+
|
|
150
|
+
test("Overlapping topics with empty levels works", () => {
|
|
151
|
+
const root = new Trie<number>();
|
|
152
|
+
root.add("foo/bar", 2);
|
|
153
|
+
root.add("foo/bar/#", 3);
|
|
154
|
+
assert.ok(includesAll(root.match("foo/bar"), [2, 3]), "two items found");
|
|
155
|
+
});
|
package/trie/trie.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @description A Trie data structure implementation that supports wildcard matching
|
|
4
4
|
* @template T The type of values stored in the trie
|
|
5
5
|
*/
|
|
6
|
-
type Parts = string[];
|
|
6
|
+
export type Parts = string[];
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Trie class for storing and matching hierarchical key-value pairs with wildcard support
|
|
@@ -58,14 +58,11 @@ export class Trie<T> {
|
|
|
58
58
|
* @returns Array of matched values
|
|
59
59
|
*/
|
|
60
60
|
private _matchPrefix(parts: Parts): Array<T> {
|
|
61
|
-
if (parts.length === 0) {
|
|
62
|
-
return this.#value ? this.#value : [];
|
|
63
|
-
}
|
|
64
61
|
const [first, ...rest] = parts;
|
|
65
|
-
if (first
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return
|
|
62
|
+
if (first === undefined) return [];
|
|
63
|
+
|
|
64
|
+
// Direct lookup on the reserved topic node without evaluating top-level + or #
|
|
65
|
+
return this.matchChild(first, rest);
|
|
69
66
|
}
|
|
70
67
|
|
|
71
68
|
/**
|
|
@@ -74,18 +71,31 @@ export class Trie<T> {
|
|
|
74
71
|
* @returns Array of matched values
|
|
75
72
|
*/
|
|
76
73
|
private _match(parts: Parts): Array<T> {
|
|
74
|
+
let results: Array<T> = [];
|
|
75
|
+
|
|
76
|
+
// 1. Check if there is a multi-level wildcard ('#') at this level.
|
|
77
|
+
// In MQTT, 'a/#' matches 'a', 'a/b', 'a/b/c', etc.
|
|
78
|
+
const subtreeNode = this.#children.get(this.wildcardSubtree);
|
|
79
|
+
if (subtreeNode) {
|
|
80
|
+
results = results.concat(subtreeNode.#value);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 2. Base case: we reached the end of the topic parts.
|
|
77
84
|
if (parts.length === 0) {
|
|
78
|
-
return this.#value
|
|
85
|
+
return results.concat(this.#value);
|
|
79
86
|
}
|
|
87
|
+
|
|
80
88
|
const [first, ...rest] = parts;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
// deno-coverage-ignore
|
|
90
|
+
if (first === undefined) return [];
|
|
91
|
+
|
|
92
|
+
// 3. Exact matching child node
|
|
93
|
+
const exact = this.matchChild(first, rest);
|
|
94
|
+
|
|
95
|
+
// 4. Single-level wildcard ('+') matching child node
|
|
96
|
+
const single = this.matchChild(this.wildcardOne, rest);
|
|
97
|
+
|
|
98
|
+
return results.concat(exact, single);
|
|
89
99
|
}
|
|
90
100
|
|
|
91
101
|
/**
|
|
@@ -102,23 +112,22 @@ export class Trie<T> {
|
|
|
102
112
|
* @param parts Parts of the key to add at
|
|
103
113
|
* @param value The value to add
|
|
104
114
|
*/
|
|
105
|
-
private _add(parts: Parts, value: T) {
|
|
115
|
+
private _add(parts: Parts, value: T): void {
|
|
106
116
|
if (parts.length === 0) {
|
|
107
117
|
this.#value = this.#value.concat(value);
|
|
108
118
|
return;
|
|
109
119
|
}
|
|
110
120
|
const [first, ...rest] = parts;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
121
|
+
// deno-coverage-ignore
|
|
122
|
+
if (first === undefined) return;
|
|
123
|
+
const child = this.#children.get(first);
|
|
124
|
+
if (child instanceof Trie) {
|
|
125
|
+
child._add(rest, value);
|
|
126
|
+
} else {
|
|
127
|
+
const node = new Trie<T>(this.looseCompare);
|
|
128
|
+
this.#children.set(first, node);
|
|
129
|
+
node._add(rest, value);
|
|
120
130
|
}
|
|
121
|
-
return;
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
/**
|
|
@@ -126,7 +135,12 @@ export class Trie<T> {
|
|
|
126
135
|
* @param key The key to remove the value from
|
|
127
136
|
* @param value The value to remove
|
|
128
137
|
*/
|
|
129
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Removes a value from the trie at the specified key
|
|
140
|
+
* @param key The key to remove the value from
|
|
141
|
+
* @param value The value (or partial object) to remove
|
|
142
|
+
*/
|
|
143
|
+
remove(key: string, value: Partial<T> | T): void {
|
|
130
144
|
return this._remove(key.split(this.separator), value);
|
|
131
145
|
}
|
|
132
146
|
|
|
@@ -135,40 +149,51 @@ export class Trie<T> {
|
|
|
135
149
|
* @param parts Parts of the key to remove from
|
|
136
150
|
* @param value The value to remove
|
|
137
151
|
*/
|
|
138
|
-
private _remove(parts: Parts, value: T): void {
|
|
152
|
+
private _remove(parts: Parts, value: Partial<T> | T): void {
|
|
139
153
|
if (parts.length === 0) {
|
|
140
|
-
const arr = this.#value
|
|
154
|
+
const arr = this.#value;
|
|
141
155
|
this.#value = arr.filter(this.filter(value));
|
|
142
156
|
return;
|
|
143
157
|
}
|
|
144
158
|
const [first, ...rest] = parts;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
159
|
+
// deno-coverage-ignore
|
|
160
|
+
if (first === undefined) return;
|
|
161
|
+
const node = this.#children.get(first);
|
|
162
|
+
if (node) {
|
|
163
|
+
node._remove(rest, value);
|
|
164
|
+
if (node.#value.length === 0 && node.#children.size === 0) {
|
|
165
|
+
this.#children.delete(first);
|
|
152
166
|
}
|
|
153
167
|
}
|
|
154
168
|
}
|
|
155
169
|
|
|
156
170
|
/**
|
|
157
171
|
* Creates a filter function for removing values
|
|
158
|
-
*
|
|
159
|
-
* @
|
|
172
|
+
* Supports partial object matching when looseCompare is enabled or when matching objects.
|
|
173
|
+
* @param value The value (or partial value) to filter against
|
|
174
|
+
* @returns Filter function (returns true to KEEP the item, false to REMOVE it)
|
|
160
175
|
*/
|
|
161
|
-
private filter(value: T
|
|
162
|
-
if (
|
|
176
|
+
private filter(value: Partial<T> | T): (item: T) => boolean {
|
|
177
|
+
if (typeof value === "object" && value !== null) {
|
|
163
178
|
return (item) => {
|
|
179
|
+
if (typeof item !== "object" || item === null) {
|
|
180
|
+
return true; // Keep if the stored item isn't an object but we are filtering by one
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Check if every key-value pair in our filter object matches the stored item
|
|
164
184
|
for (const key in value) {
|
|
165
|
-
if (value
|
|
166
|
-
|
|
185
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
186
|
+
// If the stored item has a different value (or doesn't have the key), it's not a match
|
|
187
|
+
if (item[key] !== value[key]) {
|
|
188
|
+
return true; // Keep the item (no match)
|
|
189
|
+
}
|
|
167
190
|
}
|
|
168
191
|
}
|
|
169
|
-
return false;
|
|
192
|
+
return false; // Remove the item (it matches all criteria in the partial object)
|
|
170
193
|
};
|
|
171
194
|
}
|
|
195
|
+
|
|
196
|
+
// Fallback for primitives
|
|
172
197
|
return (item) => item !== value;
|
|
173
198
|
}
|
|
174
199
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import { BufferedAsyncIterable } from "./bufferedAsyncIterable.ts";
|
|
4
|
+
|
|
5
|
+
test("should initialize with correct default state", () => {
|
|
6
|
+
const iterable = new BufferedAsyncIterable<number>();
|
|
7
|
+
assert.strictEqual(iterable.isDone, false);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test("should handle immediate push and pull via next()", () => {
|
|
11
|
+
const iterable = new BufferedAsyncIterable<string>();
|
|
12
|
+
|
|
13
|
+
iterable.push("hello");
|
|
14
|
+
const result = iterable.next();
|
|
15
|
+
|
|
16
|
+
assert.strictEqual(result, "hello");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("should resolve a pending next() call when data is pushed later", async () => {
|
|
20
|
+
const iterable = new BufferedAsyncIterable<number>();
|
|
21
|
+
|
|
22
|
+
const pendingPromise = iterable.next() as Promise<number>;
|
|
23
|
+
|
|
24
|
+
// The promise should resolve once we push data
|
|
25
|
+
iterable.push(42);
|
|
26
|
+
|
|
27
|
+
const result = await pendingPromise;
|
|
28
|
+
assert.strictEqual(result, 42);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("should work correctly with for-await-of loop", async () => {
|
|
32
|
+
const iterable = new BufferedAsyncIterable<number>();
|
|
33
|
+
const items: number[] = [];
|
|
34
|
+
|
|
35
|
+
iterable.push(1);
|
|
36
|
+
iterable.push(2);
|
|
37
|
+
|
|
38
|
+
// Read items asynchronously
|
|
39
|
+
const consumer = async () => {
|
|
40
|
+
try {
|
|
41
|
+
for await (const item of iterable) {
|
|
42
|
+
items.push(item);
|
|
43
|
+
}
|
|
44
|
+
} catch (err) {
|
|
45
|
+
// Expecting a 'Closed' error to break the loop when close() is called
|
|
46
|
+
assert.match((err as Error).message, /closed/i);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const consumerPromise = consumer();
|
|
51
|
+
|
|
52
|
+
// Allow the event loop to process the items, then close the iterable
|
|
53
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
54
|
+
iterable.close();
|
|
55
|
+
|
|
56
|
+
await consumerPromise;
|
|
57
|
+
|
|
58
|
+
assert.deepStrictEqual(items, [1, 2]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("should reject pending promises and throw when closed", async () => {
|
|
62
|
+
const iterable = new BufferedAsyncIterable<number>();
|
|
63
|
+
|
|
64
|
+
const pendingPromise = iterable.next() as Promise<number>;
|
|
65
|
+
|
|
66
|
+
iterable.close("custom close reason");
|
|
67
|
+
|
|
68
|
+
// The outstanding promise should now reject
|
|
69
|
+
await assert.rejects(pendingPromise, /custom close reason/);
|
|
70
|
+
|
|
71
|
+
// Subsequent calls to next() should instantly throw
|
|
72
|
+
assert.throws(() => iterable.next(), /Closed/);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("should apply backpressure when buffer size is exceeded", async () => {
|
|
76
|
+
// Set a very small buffer size of 1 to easily trigger backpressure
|
|
77
|
+
const iterable = new BufferedAsyncIterable<number>(1);
|
|
78
|
+
|
|
79
|
+
// First item fills the queue size to 1 (equal to bufferSize, no backpressure yet)
|
|
80
|
+
iterable.push(1);
|
|
81
|
+
|
|
82
|
+
// Second item exceeds bufferSize (size becomes 2), returning a backpressure promise
|
|
83
|
+
const backpressurePromise = iterable.push(2);
|
|
84
|
+
|
|
85
|
+
assert.ok(
|
|
86
|
+
backpressurePromise instanceof Promise,
|
|
87
|
+
"Should return a promise due to backpressure",
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Wait for the backpressure timeout to resolve (proportional to buffer size, 2ms)
|
|
91
|
+
await backpressurePromise;
|
|
92
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import { Deferred } from "./deferred.ts"; // Note the .js extension if you are using ESM
|
|
4
|
+
|
|
5
|
+
test("should initialize with a pending promise", async () => {
|
|
6
|
+
const deferred = new Deferred<string>();
|
|
7
|
+
|
|
8
|
+
assert.ok(deferred.promise instanceof Promise);
|
|
9
|
+
|
|
10
|
+
// Verify it is indeed pending by racing it against a fast timeout
|
|
11
|
+
const timeout = new Promise((_, reject) =>
|
|
12
|
+
setTimeout(() => reject(new Error("Timeout")), 10)
|
|
13
|
+
);
|
|
14
|
+
await assert.rejects(Promise.race([deferred.promise, timeout]), /Timeout/);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("should resolve the promise when resolve() is called", async () => {
|
|
18
|
+
const deferred = new Deferred<number>();
|
|
19
|
+
|
|
20
|
+
deferred.resolve(123);
|
|
21
|
+
|
|
22
|
+
const result = await deferred.promise;
|
|
23
|
+
assert.strictEqual(result, 123);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("should reject the promise when reject() is called", async () => {
|
|
27
|
+
const deferred = new Deferred<void>();
|
|
28
|
+
const testError = new Error("Something went wrong");
|
|
29
|
+
|
|
30
|
+
deferred.reject(testError);
|
|
31
|
+
|
|
32
|
+
await assert.rejects(deferred.promise, (err: Error) => {
|
|
33
|
+
assert.strictEqual(err.message, "Something went wrong");
|
|
34
|
+
return true;
|
|
35
|
+
});
|
|
36
|
+
});
|
package/utils/deferred.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Node 26 has getOrInsert by default.
|
|
3
|
+
This is a polyfill for older versions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function getOrInsert<K, V>(map: Map<K, V>, key: K, defaultValue: V): V {
|
|
7
|
+
if (map.has(key)) {
|
|
8
|
+
return map.get(key)!;
|
|
9
|
+
}
|
|
10
|
+
map.set(key, defaultValue);
|
|
11
|
+
return defaultValue;
|
|
12
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { mock, test } from "node:test";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
import { Logger, logger, LogLevel } from "./logger.ts";
|
|
4
|
+
|
|
5
|
+
// Helper to check if a function is the 'noop' function
|
|
6
|
+
// deno-lint-ignore ban-types
|
|
7
|
+
const isNoop = (fn: Function) =>
|
|
8
|
+
fn.name === "noop" || fn.toString().includes("noop");
|
|
9
|
+
|
|
10
|
+
test("default initialization", () => {
|
|
11
|
+
const testLogger = new Logger();
|
|
12
|
+
|
|
13
|
+
// By default, error, warn, and info should be active, while verbose/debug should be noop
|
|
14
|
+
assert.strictEqual(typeof testLogger.error, "function");
|
|
15
|
+
assert.strictEqual(typeof testLogger.warn, "function");
|
|
16
|
+
assert.strictEqual(typeof testLogger.info, "function");
|
|
17
|
+
|
|
18
|
+
assert.strictEqual(
|
|
19
|
+
isNoop(testLogger.verbose),
|
|
20
|
+
true,
|
|
21
|
+
"Verbose should be noop by default",
|
|
22
|
+
);
|
|
23
|
+
assert.strictEqual(
|
|
24
|
+
isNoop(testLogger.debug),
|
|
25
|
+
true,
|
|
26
|
+
"Debug should be noop by default",
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("level(LogLevel.error) activates only error", () => {
|
|
31
|
+
const testLogger = new Logger();
|
|
32
|
+
testLogger.level(LogLevel.error);
|
|
33
|
+
|
|
34
|
+
assert.strictEqual(
|
|
35
|
+
isNoop(testLogger.warn),
|
|
36
|
+
true,
|
|
37
|
+
"Warn should be noop at error level",
|
|
38
|
+
);
|
|
39
|
+
assert.strictEqual(
|
|
40
|
+
isNoop(testLogger.info),
|
|
41
|
+
true,
|
|
42
|
+
"Info should be noop at error level",
|
|
43
|
+
);
|
|
44
|
+
assert.strictEqual(
|
|
45
|
+
isNoop(testLogger.verbose),
|
|
46
|
+
true,
|
|
47
|
+
"Verbose should be noop at error level",
|
|
48
|
+
);
|
|
49
|
+
assert.strictEqual(
|
|
50
|
+
isNoop(testLogger.debug),
|
|
51
|
+
true,
|
|
52
|
+
"Debug should be noop at error level",
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("level(LogLevel.info) activates warn and info", () => {
|
|
57
|
+
const testLogger = new Logger();
|
|
58
|
+
testLogger.level(LogLevel.info);
|
|
59
|
+
|
|
60
|
+
assert.strictEqual(
|
|
61
|
+
isNoop(testLogger.warn),
|
|
62
|
+
false,
|
|
63
|
+
"Warn should be active at info level",
|
|
64
|
+
);
|
|
65
|
+
assert.strictEqual(
|
|
66
|
+
isNoop(testLogger.info),
|
|
67
|
+
false,
|
|
68
|
+
"Info should be active at info level",
|
|
69
|
+
);
|
|
70
|
+
assert.strictEqual(
|
|
71
|
+
isNoop(testLogger.verbose),
|
|
72
|
+
true,
|
|
73
|
+
"Verbose should be noop at info level",
|
|
74
|
+
);
|
|
75
|
+
assert.strictEqual(
|
|
76
|
+
isNoop(testLogger.debug),
|
|
77
|
+
true,
|
|
78
|
+
"Debug should be noop at info level",
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("level(LogLevel.debug) activates all loggers", () => {
|
|
83
|
+
const testLogger = new Logger();
|
|
84
|
+
testLogger.level(LogLevel.debug);
|
|
85
|
+
|
|
86
|
+
assert.strictEqual(isNoop(testLogger.warn), false);
|
|
87
|
+
assert.strictEqual(isNoop(testLogger.info), false);
|
|
88
|
+
assert.strictEqual(isNoop(testLogger.verbose), false);
|
|
89
|
+
assert.strictEqual(isNoop(testLogger.debug), false);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("verify that log functions actually execute logging", () => {
|
|
93
|
+
const testLogger = new Logger();
|
|
94
|
+
|
|
95
|
+
// deno-lint-ignore no-explicit-any
|
|
96
|
+
const debugSpy = mock.method(testLogger as any, "defaultDebug");
|
|
97
|
+
// set the level, this will connect the spy
|
|
98
|
+
testLogger.level(LogLevel.debug);
|
|
99
|
+
|
|
100
|
+
testLogger.debug("Test debug message");
|
|
101
|
+
|
|
102
|
+
// check if the spy was called
|
|
103
|
+
assert.strictEqual(
|
|
104
|
+
debugSpy.mock.calls.length,
|
|
105
|
+
1,
|
|
106
|
+
"The log method should be called exactly once",
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// and if the parameters were passed correcty
|
|
110
|
+
assert.deepStrictEqual(debugSpy.mock.calls[0].arguments, [
|
|
111
|
+
"Test debug message",
|
|
112
|
+
]);
|
|
113
|
+
|
|
114
|
+
// cleaunup the mock and restore state to normal
|
|
115
|
+
mock.restoreAll();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("verify that the exported logger is an instance", () => {
|
|
119
|
+
assert.strictEqual(
|
|
120
|
+
logger instanceof Logger,
|
|
121
|
+
true,
|
|
122
|
+
"The exported logger must be a Logger instance",
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("should always return the exact same instance (Reference Check)", () => {
|
|
127
|
+
const firstImport = logger;
|
|
128
|
+
const secondImport = logger;
|
|
129
|
+
|
|
130
|
+
// Verify both references point to the exact same object in memory
|
|
131
|
+
assert.strictEqual(
|
|
132
|
+
firstImport,
|
|
133
|
+
secondImport,
|
|
134
|
+
"The exported logger must be a strict singleton reference",
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("should share state across the application (State Check)", () => {
|
|
139
|
+
// 1. Change the log level to Error
|
|
140
|
+
logger.level(LogLevel.error);
|
|
141
|
+
|
|
142
|
+
// 2. Verify the state change is reflected globally (debug should now be noop)
|
|
143
|
+
assert.strictEqual(
|
|
144
|
+
isNoop(logger.debug),
|
|
145
|
+
true,
|
|
146
|
+
"State changes should reflect globally",
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// 3. Change it back to Debug and verify again
|
|
150
|
+
logger.level(LogLevel.debug);
|
|
151
|
+
assert.strictEqual(
|
|
152
|
+
isNoop(logger.debug),
|
|
153
|
+
false,
|
|
154
|
+
"State changes should reflect globally",
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test("should not be the same as a newly instantiated Logger", () => {
|
|
159
|
+
const newInstance = new Logger();
|
|
160
|
+
|
|
161
|
+
// The singleton instance must be completely unique from manually created instances
|
|
162
|
+
assert.notStrictEqual(
|
|
163
|
+
logger,
|
|
164
|
+
newInstance,
|
|
165
|
+
"The singleton instance must be unique from new Logger() instances",
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("should perform lazy evaluation of log arguments", () => {
|
|
170
|
+
const testLogger = new Logger();
|
|
171
|
+
testLogger.level(LogLevel.debug);
|
|
172
|
+
|
|
173
|
+
let evaluationCount = 0;
|
|
174
|
+
|
|
175
|
+
const lazyArg = () => {
|
|
176
|
+
evaluationCount++;
|
|
177
|
+
return "Lazy evaluated message";
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Call debug with a lazy argument
|
|
181
|
+
testLogger.debug(lazyArg);
|
|
182
|
+
|
|
183
|
+
// The lazy argument should have been evaluated exactly once
|
|
184
|
+
assert.strictEqual(
|
|
185
|
+
evaluationCount,
|
|
186
|
+
1,
|
|
187
|
+
"The lazy argument should be evaluated exactly once",
|
|
188
|
+
);
|
|
189
|
+
});
|
package/utils/logger.ts
CHANGED
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
import { noop } from "./utils.ts";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* The available log levels
|
|
4
|
+
* The available log levels used to filter messages.
|
|
5
5
|
*/
|
|
6
6
|
export const LogLevel = {
|
|
7
|
+
/** Crucial application errors or failures. */
|
|
7
8
|
error: 0,
|
|
9
|
+
/** Non-fatal warnings that indicate unexpected behavior. */
|
|
8
10
|
warn: 1,
|
|
11
|
+
/** Informational statements highlighting general operational flow. */
|
|
9
12
|
info: 2,
|
|
13
|
+
/** Detailed tracing and comprehensive runtime statements. */
|
|
10
14
|
verbose: 3,
|
|
15
|
+
/** High-density internal troubleshooting logs. */
|
|
11
16
|
debug: 4,
|
|
12
17
|
} as const;
|
|
13
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Union type representing the permitted numeric log level indices.
|
|
21
|
+
*/
|
|
14
22
|
export type TLogLevel = typeof LogLevel[keyof typeof LogLevel];
|
|
15
23
|
|
|
24
|
+
type LogArgument = unknown | (() => unknown);
|
|
25
|
+
|
|
16
26
|
/**
|
|
17
|
-
* Simple logger class
|
|
27
|
+
* Simple logger class providing level-configurable output routing.
|
|
28
|
+
* @class Logger
|
|
29
|
+
*
|
|
18
30
|
* @example
|
|
19
31
|
* ```ts
|
|
20
32
|
* const logger = new Logger();
|
|
@@ -27,30 +39,73 @@ export type TLogLevel = typeof LogLevel[keyof typeof LogLevel];
|
|
|
27
39
|
* ```
|
|
28
40
|
*/
|
|
29
41
|
export class Logger {
|
|
42
|
+
/** Native console reference used to output critical errors. */
|
|
30
43
|
private defaultError = console.error;
|
|
44
|
+
/** Native console reference used to output warning flags. */
|
|
31
45
|
private defaultWarn = console.warn;
|
|
46
|
+
/** Native console reference used to output standard runtime indicators. */
|
|
32
47
|
private defaultInfo = console.info;
|
|
48
|
+
/** Native console reference used to track granular metrics and details. */
|
|
33
49
|
private defaultVerbose = console.log;
|
|
50
|
+
/** Native console reference used to step through highly specific operations. */
|
|
34
51
|
private defaultDebug = console.log;
|
|
35
52
|
|
|
53
|
+
/** Flag indicating if error messages should be logged. */
|
|
54
|
+
isError = true;
|
|
55
|
+
/** Flag indicating if warning messages should be logged. */
|
|
56
|
+
isWarn = true;
|
|
57
|
+
/** Flag indicating if informational messages should be logged. */
|
|
58
|
+
isInfo = true;
|
|
59
|
+
/** Flag indicating if verbose messages should be logged. */
|
|
60
|
+
isVerbose = false;
|
|
61
|
+
/** Flag indicating if debug messages should be logged. */
|
|
62
|
+
isDebug = false;
|
|
63
|
+
|
|
64
|
+
/** Log an error message to the standard error stream. */
|
|
36
65
|
error: typeof console.log = this.defaultError;
|
|
66
|
+
/** Log a warning message if the active log level permits. */
|
|
37
67
|
warn: typeof console.log = this.defaultWarn;
|
|
68
|
+
/** Log an informational status update if the active log level permits. */
|
|
38
69
|
info: typeof console.log = this.defaultInfo;
|
|
70
|
+
/** Log extended telemetry notes if the active log level permits. */
|
|
39
71
|
verbose: typeof console.log = noop;
|
|
72
|
+
/** Log debug parameters and objects if the active log level permits. */
|
|
40
73
|
debug: typeof console.log = noop;
|
|
41
74
|
|
|
75
|
+
/** Creates a wrapper function that evaluates lazy log arguments before invoking the target logging function. */
|
|
76
|
+
// deno-lint-ignore no-explicit-any
|
|
77
|
+
private createLogFn(targetFn: (...args: any[]) => void) {
|
|
78
|
+
return (...args: LogArgument[]) => {
|
|
79
|
+
const evaluated = args.map((
|
|
80
|
+
arg,
|
|
81
|
+
) => (typeof arg === "function" ? arg() : arg));
|
|
82
|
+
targetFn(...evaluated);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Create a new Logger instance. */
|
|
42
87
|
constructor() {}
|
|
43
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Adjusts the current verbosity threshold, enabling or masking specific log outputs.
|
|
91
|
+
* @param {TLogLevel} logLevel - The minimum numeric severity level threshold to output.
|
|
92
|
+
*/
|
|
44
93
|
level(logLevel: TLogLevel) {
|
|
45
|
-
this.
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
48
|
-
this.
|
|
94
|
+
this.isWarn = logLevel >= LogLevel.warn;
|
|
95
|
+
this.isInfo = logLevel >= LogLevel.info;
|
|
96
|
+
this.isVerbose = logLevel >= LogLevel.verbose;
|
|
97
|
+
this.isDebug = logLevel >= LogLevel.debug;
|
|
98
|
+
this.warn = this.isWarn ? this.createLogFn(this.defaultWarn) : noop;
|
|
99
|
+
this.info = this.isInfo ? this.createLogFn(this.defaultInfo) : noop;
|
|
100
|
+
this.verbose = this.isVerbose
|
|
101
|
+
? this.createLogFn(this.defaultVerbose)
|
|
102
|
+
: noop;
|
|
103
|
+
this.debug = this.isDebug ? this.createLogFn(this.defaultDebug) : noop;
|
|
49
104
|
}
|
|
50
105
|
}
|
|
51
106
|
|
|
52
107
|
/**
|
|
53
|
-
*
|
|
108
|
+
* Provides a single pre-configured global logger instance.
|
|
54
109
|
* @example
|
|
55
110
|
* ```ts
|
|
56
111
|
* import { logger } from "./utils/logger.ts";
|
package/utils/mod.ts
CHANGED
|
@@ -5,4 +5,18 @@
|
|
|
5
5
|
export { assert } from "./assert.ts";
|
|
6
6
|
export { Deferred } from "./deferred.ts";
|
|
7
7
|
export { Logger, logger, LogLevel } from "./logger.ts";
|
|
8
|
-
export { BufferedAsyncIterable } from "./
|
|
8
|
+
export { BufferedAsyncIterable } from "./bufferedAsyncIterable.ts";
|
|
9
|
+
export {
|
|
10
|
+
joinTopicFilter,
|
|
11
|
+
parseTopicFilter,
|
|
12
|
+
topicFilterToRegExp,
|
|
13
|
+
} from "./topicFilter.ts";
|
|
14
|
+
export { OutboundTopicAliasManager } from "./outboundTopicAliasManager.ts";
|
|
15
|
+
export type { OutboundTopicAlias } from "./outboundTopicAliasManager.ts";
|
|
16
|
+
export {
|
|
17
|
+
hasWildcards,
|
|
18
|
+
invalidmaxTopicLevels,
|
|
19
|
+
invalidTopic,
|
|
20
|
+
invalidTopicFilter,
|
|
21
|
+
} from "./validators.ts";
|
|
22
|
+
export { delay, noop } from "./utils.ts";
|