From b70a64f64023457b8a2af0394fd09ba10e0b8586 Mon Sep 17 00:00:00 2001 From: Sandu Luca Date: Fri, 28 Jun 2024 16:14:07 +0300 Subject: [PATCH 1/5] feat: allow to pass custom timer for keepalive manager --- src/lib/KeepaliveManager.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib/KeepaliveManager.ts b/src/lib/KeepaliveManager.ts index 14daf1eb3..c68be773e 100644 --- a/src/lib/KeepaliveManager.ts +++ b/src/lib/KeepaliveManager.ts @@ -33,9 +33,14 @@ export default class KeepaliveManager { return this._keepalive } - constructor(client: MqttClient, variant: TimerVariant) { + constructor(client: MqttClient, variant: TimerVariant | Timer) { this.client = client - this.timer = getTimer(variant) + this.timer = + typeof variant === 'object' && + 'set' in variant && + 'clear' in variant + ? variant + : getTimer(variant) this.setKeepalive(client.options.keepalive) } From 1479d4f013602123b8b71723db3ea96307453024 Mon Sep 17 00:00:00 2001 From: Sandu Luca Date: Fri, 28 Jun 2024 17:05:16 +0300 Subject: [PATCH 2/5] docs(readme): update `timerVariant` description --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 74a43cffb..f13a9a98e 100644 --- a/README.md +++ b/README.md @@ -466,7 +466,14 @@ The arguments are: - `messageIdProvider`: custom messageId provider. when `new UniqueMessageIdProvider()` is set, then non conflict messageId is provided. - `log`: custom log function. Default uses [debug](https://www.npmjs.com/package/debug) package. - `manualConnect`: prevents the constructor to call `connect`. In this case after the `mqtt.connect` is called you should call `client.connect` manually. - - `timerVariant`: defaults to `auto`, which tries to determine which timer is most appropriate for you environment, if you're having detection issues, you can set it to `worker` or `native` + - `timerVariant`: defaults to `auto`, which tries to determine which timer is most appropriate for you environment, if you're having detection issues, you can set it to `worker` or `native`. If none suits you, you can pass a timer object with set and clear properties: + ```js + timerVariant: { + set: (func, timer) => setInterval(func, timer), + clear: (id) => clearInterval(id) + } + ``` + - `unixSocket`: if you want to connect to a unix socket, set this to true In case mqtts (mqtt over tls) is required, the `options` object is passed through to [`tls.connect()`](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback). If using a **self-signed certificate**, set `rejectUnauthorized: false`. However, be cautious as this exposes you to potential man in the middle attacks and isn't recommended for production. From 3d7c3c83587a78e4866e2f7b996953becb3349c1 Mon Sep 17 00:00:00 2001 From: Sandu Luca Date: Mon, 1 Jul 2024 11:53:14 +0300 Subject: [PATCH 3/5] feat: export `Timer` type --- src/mqtt.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mqtt.ts b/src/mqtt.ts index e3a79abeb..6785affc9 100644 --- a/src/mqtt.ts +++ b/src/mqtt.ts @@ -25,3 +25,4 @@ export { export * from './lib/client' export * from './lib/shared' export { ReasonCodes } from './lib/handlers/ack' +export type { Timer } from './lib/get-timer' From 5eec4ee7d9771f9144d34dea7a96891275c1b51e Mon Sep 17 00:00:00 2001 From: Sandu Luca Date: Mon, 1 Jul 2024 11:56:23 +0300 Subject: [PATCH 4/5] feat(test): add test for KeepaliveManager to use provided Timer object --- test/keepaliveManager.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/test/keepaliveManager.ts b/test/keepaliveManager.ts index 60084f139..91d5a24a4 100644 --- a/test/keepaliveManager.ts +++ b/test/keepaliveManager.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, it } from 'node:test' import KeepaliveManager from '../src/lib/KeepaliveManager' import { assert } from 'chai' -import { useFakeTimers, spy, mock } from 'sinon' +import { useFakeTimers, spy, stub } from 'sinon' import { MqttClient } from 'src' function mockedClient(keepalive: number) { @@ -105,4 +105,22 @@ describe('KeepaliveManager', () => { assert.equal(manager.keepalive, 10000) assert.equal(manager.intervalEvery, 5000) }) + + it('should use provided Timer object', () => { + const keepalive = 10 // seconds + const customTimer = { + set: stub().returns(123), + clear: stub(), + } + const manager = new KeepaliveManager( + mockedClient(keepalive), + customTimer, + ) + assert.equal(manager['timer'], customTimer) + assert.equal(customTimer.set.callCount, 1) + assert.equal(manager['timerId'], 123) + + manager.destroy() + assert.equal(customTimer.clear.called, true) + }) }) From 78cf08ce9e943d7b18a82fa9a5a7a2955860c4d1 Mon Sep 17 00:00:00 2001 From: Sandu Luca Date: Mon, 1 Jul 2024 13:43:48 +0300 Subject: [PATCH 5/5] fix(type): add Timer type to timerVariant on client options --- src/lib/client.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/client.ts b/src/lib/client.ts index 8ea645f61..20fdce334 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -41,6 +41,7 @@ import TopicAliasSend from './topic-alias-send' import { TypedEventEmitter } from './TypedEmitter' import KeepaliveManager from './KeepaliveManager' import isBrowser, { isWebWorker } from './is-browser' +import { Timer } from './get-timer' const setImmediate = globalThis.setImmediate || @@ -278,8 +279,9 @@ export interface IClientOptions extends ISecureClientOptions { properties?: IConnectPacket['properties'] /** * @description 'auto', set to 'native' or 'worker' if you're having issues with 'auto' detection + * or pass a custom timer object */ - timerVariant?: TimerVariant + timerVariant?: TimerVariant | Timer } export interface IClientPublishOptions {