From 778008c4c092c327721732cf12499edb8654a806 Mon Sep 17 00:00:00 2001 From: getlarge Date: Fri, 5 Mar 2021 09:27:30 +0100 Subject: [PATCH] fix: add types definitions (#76) --- abstract.js | 4 +- package.json | 8 +- types/index.d.ts | 270 ++++++++++++++++++++++++++++++++++++++++++ types/index.test-d.ts | 168 ++++++++++++++++++++++++++ 4 files changed, 446 insertions(+), 4 deletions(-) create mode 100644 types/index.d.ts create mode 100644 types/index.test-d.ts diff --git a/abstract.js b/abstract.js index 0d0b028..2039b21 100644 --- a/abstract.js +++ b/abstract.js @@ -105,7 +105,7 @@ function abstractPersistence (opts) { function testPacket (t, packet, expected) { if (packet.messageId === null) packet.messageId = undefined t.equal(packet.messageId, undefined, 'should have an unassigned messageId in queue') - t.deepEqual(packet, expected, 'must return the packet') + t.deepLooseEqual(packet, expected, 'must return the packet') } test('store and look up retained messages', function (t) { @@ -1256,7 +1256,7 @@ function abstractPersistence (opts) { delete retrieved.brokerId delete packet.length - t.deepEqual(retrieved, packet, 'retrieved packet must be deeply equal') + t.deepLooseEqual(retrieved, packet, 'retrieved packet must be deeply equal') t.notEqual(retrieved, packet, 'retrieved packet must not be the same objet') instance.incomingDelPacket(client, retrieved, function (err) { diff --git a/package.json b/package.json index 7456be2..bfb8258 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,13 @@ "version": "8.1.2", "description": "The spec for an Aedes persistence, with abstract tests and a fast in-memory implementation.", "main": "persistence.js", + "types": "types/index.d.ts", "scripts": { "lint": "standard --verbose | snazzy", "lint-fix": "standard --fix", "unit": "tape test.js | faucet", - "test": "npm run lint && npm run unit", + "test:types": "tsd", + "test": "npm run lint && npm run unit && tsd", "coverage": "nyc --reporter=lcov tape test.js", "test:ci": "npm run lint && npm run coverage", "license-checker": "license-checker --production --onlyAllow='MIT;ISC;BSD-3-Clause;BSD-2-Clause'", @@ -58,6 +60,7 @@ "node": ">=10" }, "devDependencies": { + "aedes": "^0.45.0", "concat-stream": "^2.0.0", "faucet": "0.0.1", "license-checker": "^25.0.1", @@ -69,7 +72,8 @@ "snazzy": "^9.0.0", "standard": "^15.0.1", "tape": "^5.2.1", - "through2": "^4.0.2" + "through2": "^4.0.2", + "tsd": "^0.14.0" }, "dependencies": { "aedes-packet": "^2.3.1", diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..079c66c --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,270 @@ +import type { Brokers, Client, Subscription } from 'aedes'; +import type { AedesPacket } from 'aedes-packet'; +import type { QoS } from 'mqtt-packet'; +import type { Readable } from 'stream'; + +export type { AedesPacket as Packet } from 'aedes-packet'; + +export interface AedesPersistenceSubscription { + clientId: string; + topic: string; + qos?: QoS; +} + +export type CallbackError = Error | null | undefined; + +export type WillPacket = AedesPacket & { [key: string]: any }; + +interface Incoming { + [clientId: string]: { [messageId: string]: AedesPacket }; +} + +export interface AedesPersistence { + storeRetained: ( + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + createRetainedStream: (pattern: string) => Readable; + + createRetainedStreamCombi: (patterns: string[]) => Readable; + + addSubscriptions: ( + client: Client, + subs: Subscription[], + cb: (error: CallbackError, client: Client) => void + ) => void; + + removeSubscriptions: ( + client: Client, + subs: Subscription[], + cb: (error: CallbackError, client: Client) => void + ) => void; + + subscriptionsByClient: ( + client: Client, + cb: ( + error: CallbackError, + subs: { topic: string; qos: QoS }[], + client: Client + ) => void + ) => void; + + countOffline: ( + cb: ( + error: CallbackError, + subscriptionsCount: number, + clientsCount: number + ) => void + ) => void; + + subscriptionsByTopic: ( + pattern: string, + cb: (error: CallbackError, subs: AedesPersistenceSubscription[]) => void + ) => void; + + cleanSubscriptions: ( + client: Client, + cb: (error: CallbackError, client: Client) => void + ) => void; + + outgoingEnqueue: ( + sub: { clientId: string }, + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + outgoingEnqueueCombi: ( + subs: { clientId: string }[], + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + outgoingUpdate: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError, client: Client, packet: AedesPacket) => void + ) => void; + + outgoingClearMessageId: ( + client: Client, + packet: AedesPacket, + cb: (error?: CallbackError, packet?: AedesPacket) => void + ) => void; + + outgoingStream: (client: Client) => Readable; + + incomingStorePacket: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + incomingGetPacket: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError, packet: AedesPacket) => void + ) => void; + + incomingDelPacket: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + putWill: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError, client: Client) => void + ) => void; + + getWill: ( + client: Client, + cb: (error: CallbackError, will: WillPacket, client: Client) => void + ) => void; + + delWill: ( + client: Client, + cb: (error: CallbackError, will: WillPacket, client: Client) => void + ) => void; + + streamWill: (brokers: Brokers) => Readable; + + getClientList: (topic: string) => Readable; + + destroy: (cb?: (error: CallbackError) => void) => void; +} + +export class AedesMemoryPersistence implements AedesPersistence { + _retained: AedesPacket[]; + _subscriptions: Map< + AedesPersistenceSubscription['clientId'], + Map< + AedesPersistenceSubscription['topic'], + AedesPersistenceSubscription['qos'] + > + >; + _clientsCount: number; + _trie: any; + _outgoing: Record; + _incoming: Incoming; + _wills: Record; + + constructor(); + + storeRetained: ( + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + createRetainedStream: (pattern: string) => Readable; + + createRetainedStreamCombi: (patterns: string[]) => Readable; + + addSubscriptions: ( + client: Client, + subs: Subscription[], + cb: (error: CallbackError, client: Client) => void + ) => void; + + removeSubscriptions: ( + client: Client, + subs: Subscription[], + cb: (error: CallbackError, client: Client) => void + ) => void; + + subscriptionsByClient: ( + client: Client, + cb: ( + error: CallbackError, + subs: { topic: string; qos: QoS }[], + client: Client + ) => void + ) => void; + + countOffline: ( + cb: ( + error: CallbackError, + subscriptionsCount: number, + clientsCount: number + ) => void + ) => void; + + subscriptionsByTopic: ( + pattern: string, + cb: (error: CallbackError, subs: AedesPersistenceSubscription[]) => void + ) => void; + + cleanSubscriptions: ( + client: Client, + cb: (error: CallbackError, client: Client) => void + ) => void; + + outgoingEnqueue: ( + sub: { clientId: string }, + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + outgoingEnqueueCombi: ( + sub: { clientId: string }[], + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + outgoingUpdate: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError, client: Client, packet: AedesPacket) => void + ) => void; + + outgoingClearMessageId: ( + client: Client, + packet: AedesPacket, + cb: (error?: CallbackError, packet?: AedesPacket) => void + ) => void; + + outgoingStream: (client: Client) => Readable; + + incomingStorePacket: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + incomingGetPacket: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError, packet: AedesPacket) => void + ) => void; + + incomingDelPacket: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError) => void + ) => void; + + putWill: ( + client: Client, + packet: AedesPacket, + cb: (error: CallbackError, client: Client) => void + ) => void; + + getWill: ( + client: Client, + cb: (error: CallbackError, will: WillPacket, client: Client) => void + ) => void; + + delWill: ( + client: Client, + cb: (error: CallbackError, will: WillPacket, client: Client) => void + ) => void; + + streamWill: (brokers: Brokers) => Readable; + + getClientList: (topic: string) => Readable; + + destroy: (cb?: (error: CallbackError) => void) => void; +} + +export default function aedesMemoryPersistence(): AedesMemoryPersistence; diff --git a/types/index.test-d.ts b/types/index.test-d.ts new file mode 100644 index 0000000..2249263 --- /dev/null +++ b/types/index.test-d.ts @@ -0,0 +1,168 @@ +import type { Brokers, Client, Subscription } from 'aedes'; +import type { AedesPacket } from 'aedes-packet'; +import type { QoS } from 'mqtt-packet'; +import type { Readable } from 'stream'; +import { expectType } from 'tsd'; +import aedesMemoryPersistence, { + AedesMemoryPersistence, + AedesPersistenceSubscription, + CallbackError, + WillPacket, +} from '.'; + +expectType(aedesMemoryPersistence()); + +expectType( + aedesMemoryPersistence().storeRetained( + { + brokerId: '', + brokerCounter: 1, + cmd: 'publish', + qos: 0, + dup: false, + retain: false, + topic: 'test', + payload: 'test', + }, + (err: CallbackError) => {} + ) +); + +expectType( + aedesMemoryPersistence().addSubscriptions( + {} as Client, + [] as Subscription[], + (err: CallbackError) => {} + ) +); + +expectType( + aedesMemoryPersistence().removeSubscriptions( + {} as Client, + [] as Subscription[], + (err: CallbackError) => {} + ) +); + +expectType( + aedesMemoryPersistence().subscriptionsByClient( + {} as Client, + ( + error: CallbackError, + subs: { topic: string; qos: QoS }[], + client: Client + ) => {} + ) +); + +expectType( + aedesMemoryPersistence().countOffline( + ( + error: CallbackError, + subscriptionsCount: number, + clientsCount: number + ) => {} + ) +); + +expectType( + aedesMemoryPersistence().subscriptionsByTopic( + 'pattern', + (error: CallbackError, subs: AedesPersistenceSubscription[]) => {} + ) +); + +expectType( + aedesMemoryPersistence().cleanSubscriptions( + {} as Client, + (error: CallbackError, client: Client) => {} + ) +); + +expectType( + aedesMemoryPersistence().outgoingEnqueue( + { clientId: '' }, + {} as AedesPacket, + (error: CallbackError) => {} + ) +); + +expectType( + aedesMemoryPersistence().outgoingEnqueueCombi( + [{ clientId: '' }], + {} as AedesPacket, + (error: CallbackError) => {} + ) +); + +expectType( + aedesMemoryPersistence().outgoingUpdate( + {} as Client, + {} as AedesPacket, + (error: CallbackError, client: Client, packet: AedesPacket) => {} + ) +); + +expectType( + aedesMemoryPersistence().outgoingClearMessageId( + {} as Client, + {} as AedesPacket, + (error: CallbackError, packet?: AedesPacket) => {} + ) +); + +expectType(aedesMemoryPersistence().outgoingStream({} as Client)); + +expectType( + aedesMemoryPersistence().incomingStorePacket( + {} as Client, + {} as AedesPacket, + (error: CallbackError) => {} + ) +); + +expectType( + aedesMemoryPersistence().incomingGetPacket( + {} as Client, + {} as AedesPacket, + (error: CallbackError, packet: AedesPacket) => {} + ) +); + +expectType( + aedesMemoryPersistence().incomingDelPacket( + {} as Client, + {} as AedesPacket, + (error: CallbackError) => {} + ) +); + +expectType( + aedesMemoryPersistence().putWill( + {} as Client, + {} as AedesPacket, + (error: CallbackError, client: Client) => {} + ) +); + +expectType( + aedesMemoryPersistence().getWill( + {} as Client, + (error: CallbackError, will: WillPacket, client: Client) => {} + ) +); + +expectType( + aedesMemoryPersistence().delWill( + {} as Client, + (error: CallbackError, will: WillPacket, client: Client) => {} + ) +); + +expectType(aedesMemoryPersistence().streamWill({} as Brokers)); + +expectType(aedesMemoryPersistence().getClientList('topic')); + +expectType(aedesMemoryPersistence().destroy()); + +expectType(aedesMemoryPersistence().destroy(() => {}));