/** * @module persistence * @description Module for handling MQTT message persistence and client management */ import type { ClientId, PacketId, PublishPacketV5, QoS, RetainHandling, TopicFilter, } from "./deps.ts"; /** * extended publish packet also contains meta data */ export type ExtPublishPacket = PublishPacketV5 & { expiresAtMs?: number; }; /** * The MQTT topic share to subscribe/unsubscribe to */ export type ShareName = string; export type ClientSubscription = { topicFilter: TopicFilter; shareName: ShareName; qos: QoS; noLocal?: boolean; retainAsPublished?: boolean; retainHandling?: RetainHandling; subscriptionIdentifier?: number; }; /** * Maximum packet ID value for MQTT messages (0xffff/65535) */ export const MAX_PACKET_ID = 0xffff; // Handler function type for processing publish packets export type Handler = (packet: ExtPublishPacket) => void | Promise; // The result returned by client registration export type ClientRegistrationResult = { existingSession: boolean; }; /** * Interface for persistence implementations to store messages and subscriptions */ export interface Persistence { // initialize the persistence // e.g. setting up the data store initialize(): Promise; // client registration registerClient( clientId: ClientId, handler: Handler, ): Promise; deregisterClient(clientId: ClientId): Promise; disconnectClient(clientId: ClientId): Promise; // subscription management subscribe( clientId: ClientId, subscription: ClientSubscription, ): Promise; unsubscribe( clientId: ClientId, topicFilter: TopicFilter, shareName: ShareName, ): Promise; listSubscriptions( clientId: ClientId, ): AsyncIterableIterator; // Incoming Packet management addPendingIncomingPacket( clientId: ClientId, packet: ExtPublishPacket, ): Promise; getPendingIncomingPacket( clientId: ClientId, packetId: PacketId, ): Promise; listPendingIncomingPackets( clientId: ClientId, ): AsyncIterableIterator; deletePendingIncomingPacket( clientId: ClientId, packetId: PacketId, ): Promise; // Outgoing Packet management addPendingOutgoingPacket( clientId: ClientId, packet: ExtPublishPacket, ): Promise; getPendingOutgoingPacket( clientId: ClientId, packetId: PacketId, ): Promise; updatePendingOutgoingPacket( clientId: ClientId, packetId: PacketId, dup: boolean, ): Promise; listPendingOutgoingPackets( clientId: ClientId, ): AsyncIterableIterator; deletePendingOutgoingPacket( clientId: ClientId, packetId: PacketId, ): Promise; // Acks addPendingAck(clientId: ClientId, packetId: PacketId): Promise; hasPendingAck(clientId: ClientId, packetId: PacketId): Promise; deletePendingAck(clientId: ClientId, packetId: PacketId): Promise; listPendingAcks(clientId: ClientId): AsyncIterableIterator; // Message Delivery & Retained publish( clientId: ClientId, packet: ExtPublishPacket, ): Promise; handleRetained( clientId: ClientId, subscriptions: ClientSubscription[], ): Promise; // Packet ID Generation nextPacketId(clientId: ClientId): Promise; }