diff --git a/types/paho-mqtt/index.d.ts b/types/paho-mqtt/index.d.ts new file mode 100644 index 0000000000..7df5863532 --- /dev/null +++ b/types/paho-mqtt/index.d.ts @@ -0,0 +1,445 @@ +// Type definitions for paho-mqtt 1.0 +// Project: https://github.com/eclipse/paho.mqtt.javascript#readme +// Definitions by: Alex Mikhalev +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare namespace Paho { + /** + * Send and receive messages using web browsers. + *

+ * This programming interface lets a JavaScript client application use the MQTT V3.1 or + * V3.1.1 protocol to connect to an MQTT-supporting messaging server. + * + * The function supported includes: + *

    + *
  1. Connecting to and disconnecting from a server. The server is identified by its host name and port number. + *
  2. Specifying options that relate to the communications link with the server, + * for example the frequency of keep-alive heartbeats, and whether SSL/TLS is required. + *
  3. Subscribing to and receiving messages from MQTT Topics. + *
  4. Publishing messages to MQTT Topics. + *
+ *

+ * The API consists of two main objects: + *

+ *
{@link Paho.MQTT.Client}
+ *
This contains methods that provide the functionality of the API, + * including provision of callbacks that notify the application when a message + * arrives from or is delivered to the messaging server, + * or when the status of its connection to the messaging server changes.
+ *
{@link Paho.MQTT.Message}
+ *
This encapsulates the payload of the message along with various attributes + * associated with its delivery, in particular the destination to which it has + * been (or is about to be) sent.
+ *
+ *

+ * The programming interface validates parameters passed to it, and will throw + * an Error containing an error message intended for developer use, if it detects + * an error with any parameter. + *

+ * + * @namespace Paho.MQTT + */ + namespace MQTT { + /** + * The Quality of Service used to deliver a message. + *

+ *
0 Best effort (default).
+ *
1 At least once.
+ *
2 Exactly once.
+ *
+ */ + type Qos = 0 | 1 | 2; + + interface MQTTError { + /** A number indicating the nature of the error. */ + errorCode: number; + + /** Text describing the error */ + errorMessage: string; + } + interface WithInvocationContext { + /** + * invocationContext as passed in with the corresponding field in the connectOptions or + * subscribeOptions. + */ + invocationContext: any; + } + interface ErrorWithInvocationContext extends MQTTError, WithInvocationContext { + } + interface OnSubscribeSuccessParams extends WithInvocationContext { + grantedQos: Qos; + } + + /** + * Called when the connect acknowledgement has been received from the server. + * @param o + * A single response object parameter is passed to the onSuccess callback containing the following fields: + *
  • invocationContext as passed in with the corresponding field in the connectOptions. + */ + type OnSuccessCallback = (o: WithInvocationContext) => void; + + /** + * Called when the subscribe acknowledgement has been received from the server. + * @param o + * A single response object parameter is passed to the onSuccess callback containing the following fields: + *
  • invocationContext as passed in with the corresponding field in the connectOptions. + */ + type OnSubscribeSuccessCallback = (o: OnSubscribeSuccessParams) => void; + + /** + * Called when the connect request has failed or timed out. + * @param e + * A single response object parameter is passed to the onFailure callback containing the following fields: + *
  • invocationContext as passed in with the corresponding field in the connectOptions. + *
  • errorCode a number indicating the nature of the error. + *
  • errorMessage text describing the error. + */ + type OnFailureCallback = (e: ErrorWithInvocationContext) => void; + + /** + * Called when a connection has been lost. + * @param error A single response object parameter is passed to the onConnectionLost callback containing the + * following fields: + *
  • errorCode + *
  • errorMessage + */ + type OnConnectionLostHandler = (error: MQTTError) => void; + + /** + * Called when a message was delivered or has arrived. + * @param message The {@link Paho.MQTT.Message} that was delivered or has arrived. + */ + type OnMessageHandler = (message: Message) => void; + + /** + * Attributes used with a connection. + */ + interface ConnectionOptions { + /** + * If the connect has not succeeded within this number of seconds, it is deemed to have failed. + * @default The default is 30 seconds. + */ + timeout?: number; + /** Authentication username for this connection. */ + userName?: string; + /** Authentication password for this connection. */ + password?: string; + /** Sent by the server when the client disconnects abnormally. */ + willMessage?: Message; + /** + * The server disconnects this client if there is no activity for this number of seconds. + * @default The default value of 60 seconds is assumed if not set. + */ + keepAliveInterval?: number; + /** + * If true(default) the client and server persistent state is deleted on successful connect. + * @default true + */ + cleanSession?: boolean; + /** If present and true, use an SSL Websocket connection. */ + useSSL?: boolean; + /** Passed to the onSuccess callback or onFailure callback. */ + invocationContext?: any; + /** + * Called when the connect acknowledgement has been received from the server. + */ + onSuccess?: OnSuccessCallback; + /** + * Specifies the mqtt version to use when connecting + *
    + *
    3 - MQTT 3.1
    + *
    4 - MQTT 3.1.1 (default)
    + *
    + * @default 4 + */ + mqttVersion?: 3 | 4; + /** + * Called when the connect request has failed or timed out. + */ + onFailure?: OnFailureCallback; + /** + * If present this contains either a set of hostnames or fully qualified + * WebSocket URIs (ws://example.com:1883/mqtt), that are tried in order in place of the host and port + * paramater on the construtor. The hosts are tried one at at time in order until one of then succeeds. + */ + hosts?: string[]; + /** + * If present the set of ports matching the hosts. If hosts contains URIs, this property is not used. + */ + ports?: number[]; + } + + /** + * Used to control a subscription + */ + interface SubscribeOptions { + /** the maximum qos of any publications sent as a result of making this subscription. */ + qos?: Qos; + /** passed to the onSuccess callback or onFailure callback. */ + invocationContext?: any; + /** called when the subscribe acknowledgement has been received from the server. */ + onSuccess?: OnSubscribeSuccessCallback; + /** called when the subscribe request has failed or timed out. */ + onFailure?: OnFailureCallback; + /** + * timeout which, if present, determines the number of seconds after which the onFailure calback is called. + * The presence of a timeout does not prevent the onSuccess callback from being called when the subscribe + * completes. + */ + timeout?: number; + } + + interface UnsubscribeOptions { + /** passed to the onSuccess callback or onFailure callback. */ + invocationContext?: any; + /** called when the unsubscribe acknowledgement has been received from the server. */ + onSuccess?: OnSuccessCallback; + /** called when the unsubscribe request has failed or timed out. */ + onFailure?: OnFailureCallback; + /** + * timeout which, if present, determines the number of seconds after which the onFailure calback is called. + * The presence of a timeout does not prevent the onSuccess callback from being called when the unsubscribe + * completes. + */ + timeout?: number; + } + + interface TraceElement { + severity: "Debug"; + message: string; + } + + type TraceFunction = (element: TraceElement) => void; + + /** + * The JavaScript application communicates to the server using a {@link Paho.MQTT.Client} object. + * + * Most applications will create just one Client object and then call its connect() method, + * however applications can create more than one Client object if they wish. + * In this case the combination of host, port and clientId attributes must be different for each Client object. + * + * The send, subscribe and unsubscribe methods are implemented as asynchronous JavaScript methods + * (even though the underlying protocol exchange might be synchronous in nature). + * This means they signal their completion by calling back to the application, + * via Success or Failure callback functions provided by the application on the method in question. + * Such callbacks are called at most once per method invocation and do not persist beyond the lifetime + * of the script that made the invocation. + * + * In contrast there are some callback functions, most notably {@link onMessageArrived}, + * that are defined on the {@link Paho.MQTT.Client} object. + * These may get called multiple times, and aren't directly related to specific method invocations made by the + * client. + * + */ + class Client { + /** read only used when connecting to the server. */ + readonly clientId: string; + + /** read only the server's DNS hostname or dotted decimal IP address. */ + readonly host: string; + + /** read only the server's path. */ + readonly path: string; + + /** read only the server's port. */ + readonly port: number; + + /** function called with trace information, if set */ + trace?: TraceFunction; + + /** + * called when a connection has been lost. after a connect() method has succeeded. + * Establish the call back used when a connection has been lost. The connection may be + * lost because the client initiates a disconnect or because the server or network + * cause the client to be disconnected. The disconnect call back may be called without + * the connectionComplete call back being invoked if, for example the client fails to + * connect. + * A single response object parameter is passed to the onConnectionLost callback containing the following + * fields: + *
  • errorCode + *
  • errorMessage + */ + onConnectionLost: OnConnectionLostHandler; + + /** + * called when a message has been delivered. + * All processing that this Client will ever do has been completed. So, for example, + * in the case of a Qos=2 message sent by this client, the PubComp flow has been received from the server + * and the message has been removed from persistent storage before this callback is invoked. + * Parameters passed to the onMessageDelivered callback are: + *
  • {@link Paho.MQTT.Message} that was delivered. + */ + onMessageDelivered: OnMessageHandler; + + /** + * called when a message has arrived in this Paho.MQTT.client. + * Parameters passed to the onMessageArrived callback are: + *
  • {@link Paho.MQTT.Message} that has arrived. + */ + onMessageArrived: OnMessageHandler; + + /* tslint:disable:unified-signatures */ + /* these cannot actually be neatly unified */ + + /** + * @param host - the address of the messaging server as a DNS name or dotted decimal IP address. + * @param port - the port number to connect to + * @param path - the path on the host to connect to - only used if host is not a URI. Default: '/mqtt'. + * @param clientId - the Messaging client identifier, between 1 and 23 characters in length. + */ + constructor(host: string, port: number, path: string, clientId: string); + + /** + * @param host - the address of the messaging server as a DNS name or dotted decimal IP address. + * @param port - the port number to connect to + * @param clientId - the Messaging client identifier, between 1 and 23 characters in length. + */ + constructor(host: string, port: number, clientId: string); + + /** + * @param hostUri - the address of the messaging server as a fully qualified WebSocket URI + * @param clientId - the Messaging client identifier, between 1 and 23 characters in length. + */ + constructor(hostUri: string, clientId: string); + + /* tslint:enable:unified-signatures */ + + /** + * Connect this Messaging client to its server. + * @throws {InvalidState} if the client is not in disconnected state. The client must have received + * connectionLost or disconnected before calling connect for a second or subsequent time. + */ + connect(connectionOptions?: ConnectionOptions): void; + + /** + * Normal disconnect of this Messaging client from its server. + * + * @throws {InvalidState} if the client is already disconnected. + */ + disconnect(): void; + + /** + * @returns True if the client is currently connected + */ + isConnected(): boolean; + + /** + * Get the contents of the trace log. + * + * @return {Object[]} tracebuffer containing the time ordered trace records. + */ + getTraceLog(): any[]; + + /** + * Start tracing. + */ + startTrace(): void; + + /** + * Stop tracing. + */ + stopTrace(): void; + + /** + * Send a message to the consumers of the destination in the Message. + * + * @param {Paho.MQTT.Message} message - mandatory The {@link Paho.MQTT.Message} object to be sent. + * @throws {InvalidState} if the client is not connected. + */ + send(message: Message): void; + + /** + * Send a message to the consumers of the destination in the Message. + * + * @param {string} topic - mandatory The name of the destination to which the message is to be sent. + * @param {string|ArrayBuffer} payload - The message data to be sent. + * @param {number} qos The Quality of Service used to deliver the message. + *
    + *
    0 Best effort (default). + *
    1 At least once. + *
    2 Exactly once. + *
    + * @param {Boolean} retained If true, the message is to be retained by the server and delivered to both + * current and future subscriptions. If false the server only delivers the message to current subscribers, + * this is the default for new Messages. A received message has the retained boolean set to true if the + * message was published with the retained boolean set to true and the subscrption was made after the + * message has been published. + * @throws {InvalidState} if the client is not connected. + */ + send(topic: string, payload: string | ArrayBuffer, qos?: Qos, retained?: boolean): void; + + /** + * Subscribe for messages, request receipt of a copy of messages sent to the destinations described by the + * filter. + * + * @param filter A filter describing the destinations to receive messages from. + * @param subcribeOptions Used to control the subscription + * @throws {InvalidState} if the client is not in connected state. + */ + subscribe(filter: string, subcribeOptions?: SubscribeOptions): void; + + /** + * Unsubscribe for messages, stop receiving messages sent to destinations described by the filter. + * + * @param filter - describing the destinations to receive messages from. + * @param unsubscribeOptions - used to control the subscription + * @throws {InvalidState} if the client is not in connected state. + */ + unsubscribe(filter: string, unsubcribeOptions?: UnsubscribeOptions): void; + } + + /** + * An application message, sent or received. + */ + class Message { + /** + * mandatory The name of the destination to which the message is to be sent + * (for messages about to be sent) or the name of the destination from which the message has been received. + * (for messages received by the onMessage function). + */ + destinationName?: string; + + /** + * read only If true, this message might be a duplicate of one which has already been received. + * This is only set on messages received from the server. + */ + readonly duplicate: boolean; + + /** read only The payload as an ArrayBuffer. */ + readonly payloadBytes: ArrayBuffer; + + /** + * read only The payload as a string if the payload consists of valid UTF-8 characters. + * @throw {Error} if the payload is not valid UTF-8 + */ + readonly payloadString: string; + + /** + * The Quality of Service used to deliver the message. + *
    + *
    0 Best effort (default). + *
    1 At least once. + *
    2 Exactly once. + *
    + * + * @default 0 + */ + qos: number; + + /** + * If true, the message is to be retained by the server and delivered to both current and future + * subscriptions. If false the server only delivers the message to current subscribers, this is the default + * for new Messages. A received message has the retained boolean set to true if the message was published + * with the retained boolean set to true and the subscription was made after the message has been published. + * + * @default false + */ + retained: boolean; + + /** + * @param {String|ArrayBuffer} payload The message data to be sent. + */ + constructor(payload: string | ArrayBuffer); + } + } +} diff --git a/types/paho-mqtt/paho-mqtt-tests.ts b/types/paho-mqtt/paho-mqtt-tests.ts new file mode 100644 index 0000000000..b06c36cd0e --- /dev/null +++ b/types/paho-mqtt/paho-mqtt-tests.ts @@ -0,0 +1,87 @@ +let client = new Paho.MQTT.Client("ws://localhost/mqtt", "client-1"); +client = new Paho.MQTT.Client("localhost", 80, "client-2"); +client = new Paho.MQTT.Client("localhost", 80, "/mqtt", "client-3"); + +const willMsg = new Paho.MQTT.Message(""); + +declare var console: any; + +client.connect({ + timeout: 10, + userName: "username", + password: "pa$$word", + willMessage: willMsg, + keepAliveInterval: 10, + cleanSession: true, + useSSL: true, + invocationContext: { + asdf: true + }, + onSuccess: (o) => { + console.log("connected: ", o.invocationContext.asdf); + }, + mqttVersion: 3, + onFailure: (e) => { + console.error("could not connect: ", e.errorMessage); + }, + hosts: ["localhost", "8.8.8.8"], + ports: [80, 443], +}); + +console.log(`created new client on "${client.host}:${client.port}/${client.path}" with id "${client.clientId}"`); + +console.log(`connected?: ${client.isConnected()}`); + +client.trace = (msg) => { + console.log(`mqtt trace msg: ${msg}`); +}; + +client.startTrace(); +console.log(`trace log: ${client.getTraceLog()}`); +client.stopTrace(); + +client.onMessageArrived = (msg) => { + console.log(`arrived: ${msg.destinationName}: ${msg.payloadString}`); + console.log(`len: ${msg.payloadBytes.byteLength}, retained: ${msg.retained}, dup: ${msg.duplicate}, qos: ${msg.qos}`); +}; + +client.onConnectionLost = (err) => { + console.log(`connection lost (code ${err.errorCode}): ${err.errorMessage}`); +}; + +client.onMessageDelivered = (msg) => { + console.log(`delivered: ${msg.destinationName}: ${msg.payloadString}`); + console.log(`len: ${msg.payloadBytes.byteLength}, retained: ${msg.retained}, dup: ${msg.duplicate}, qos: ${msg.qos}`); +}; + +client.subscribe("test/topic", { + qos: 2, + invocationContext: { asdf: true }, + onSuccess: (o) => { + console.log(`subscribed: ${o.invocationContext.asdf}`); + }, + onFailure: (e) => { + console.error("error subscribing: ", e.errorMessage); + }, + timeout: 10, +}); + +client.unsubscribe("test/topic", { + invocationContext: { asdf: true }, + onSuccess: (o) => { + console.log(`subscribed: ${o.invocationContext.asdf}`); + }, + onFailure: (e) => { + console.error("error subscribing: ", e.errorMessage); + }, + timeout: 10, +}); + +client.send("test/topic2", "hello world!", 0, true); +client.send("test/topic3", "hello world 2!", 1); +client.send("test/topic4", new ArrayBuffer(3)); +const msg = new Paho.MQTT.Message(new ArrayBuffer(4)); +msg.destinationName = "test/topic5"; +msg.qos = 2; + +client.disconnect(); diff --git a/types/paho-mqtt/tsconfig.json b/types/paho-mqtt/tsconfig.json new file mode 100644 index 0000000000..e4666b9ef5 --- /dev/null +++ b/types/paho-mqtt/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "paho-mqtt-tests.ts" + ] +} diff --git a/types/paho-mqtt/tslint.json b/types/paho-mqtt/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/paho-mqtt/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }