Comparing version 1.4.0-beta.1 to 1.4.0-beta.2
import { RegisterClientOptions, Resolvable } from './mqtt.types'; | ||
import EventEmitter = require('eventemitter3'); | ||
import { PacketReadResultMap } from './packets/packet-reader'; | ||
import { PacketWriteOptionsMap } from './packets/packet-writer'; | ||
import { PacketWriteOptionsMap, PacketReadResultMap } from './packets'; | ||
import { MqttMessage } from './mqtt.message'; | ||
import { EventMapping, PacketType } from './mqtt.constants'; | ||
import EventEmitter = require('eventemitter3'); | ||
export declare enum StateId { | ||
@@ -18,3 +17,6 @@ Fatal = -1, | ||
connect: (packet: ReadMap[PacketType.ConnAck]) => void; | ||
disconnect: (reason?: string) => void; | ||
disconnect: (event?: { | ||
reason?: string | Error; | ||
reconnect: boolean; | ||
}) => void; | ||
message: (message: MqttMessage) => void; | ||
@@ -25,2 +27,3 @@ } & { | ||
private sate; | ||
constructor(sate?: StateId); | ||
get current(): StateId; | ||
@@ -32,24 +35,26 @@ get created(): boolean; | ||
get disconnected(): boolean; | ||
private _connectResolver?; | ||
set connectResolver(resolver: Resolvable<RegisterClientOptions> | undefined); | ||
private _connectOptions?; | ||
get connectOptions(): RegisterClientOptions | undefined; | ||
set connectOptions(options: RegisterClientOptions | undefined); | ||
expectReady(): void; | ||
expectCreated(): void; | ||
expectConnecting(): void; | ||
hasConnectOptions(): boolean; | ||
resolveConnectOptions(): Promise<RegisterClientOptions>; | ||
protected emitWarning: (e: Error) => boolean; | ||
protected emitError: (e: Error) => boolean; | ||
protected emitDisconnect: (reason?: string | undefined) => boolean; | ||
protected emitDisconnect: (event: { | ||
reason?: string | Error; | ||
reconnect: boolean; | ||
}) => boolean; | ||
protected emitConnect: (packet: ReadMap[PacketType.ConnAck]) => boolean; | ||
protected emitMessage: (message: MqttMessage) => boolean; | ||
constructor(sate?: StateId); | ||
private next; | ||
expectReady(): void; | ||
expectCreated(): void; | ||
expectConnecting(): void; | ||
protected reset(): void; | ||
protected setConnecting(): void; | ||
protected setReady(): void; | ||
protected setDisconnected(): void; | ||
protected _setDisconnected(): void; | ||
protected setFatal(): void; | ||
private _connectResolver?; | ||
private _connectOptions?; | ||
set connectOptions(options: RegisterClientOptions | undefined); | ||
get connectOptions(): RegisterClientOptions | undefined; | ||
set connectResolver(resolver: Resolvable<RegisterClientOptions> | undefined); | ||
hasConnectOptions(): boolean; | ||
resolveConnectOptions(): Promise<RegisterClientOptions>; | ||
private next; | ||
} |
@@ -21,3 +21,3 @@ "use strict"; | ||
this.emitError = (e) => this.emit('error', e); | ||
this.emitDisconnect = (reason) => this.emit('disconnect', reason); | ||
this.emitDisconnect = (event) => this.emit('disconnect', event); | ||
this.emitConnect = (packet) => this.emit('connect', packet); | ||
@@ -38,6 +38,6 @@ this.emitMessage = (message) => this.emit('message', message); | ||
} | ||
// although it might seem weird, this is intended | ||
get connecting() { | ||
return this.current === StateId.Connecting; | ||
} | ||
// although it might seem weird, this is intended | ||
// if the client is just created, it's not connected | ||
@@ -47,11 +47,13 @@ get disconnected() { | ||
} | ||
next(newState) { | ||
if (newState > this.current || | ||
(this.current === StateId.Fatal && newState === StateId.Disconnected) /* reconnect */) { | ||
this.sate = newState; | ||
} | ||
else { | ||
throw new Error(`Invalid state requested (current: ${this.current}, requested: ${newState})`); | ||
} | ||
set connectResolver(resolver) { | ||
var _a; | ||
this._connectResolver = (_a = this._connectResolver) !== null && _a !== void 0 ? _a : resolver; | ||
} | ||
get connectOptions() { | ||
return this._connectOptions; | ||
} | ||
set connectOptions(options) { | ||
var _a; | ||
this._connectOptions = (_a = this._connectOptions) !== null && _a !== void 0 ? _a : options; | ||
} | ||
expectReady() { | ||
@@ -72,2 +74,12 @@ if (!this.ready) { | ||
} | ||
hasConnectOptions() { | ||
return !!this._connectOptions; | ||
} | ||
async resolveConnectOptions() { | ||
this._connectOptions = { | ||
...this._connectOptions, | ||
...(this._connectResolver ? await mqtt_utilities_1.resolve(this._connectResolver) : {}), | ||
}; | ||
return this._connectOptions; | ||
} | ||
reset() { | ||
@@ -87,3 +99,3 @@ if (this.sate === StateId.Created || this.sate === StateId.Disconnected) { | ||
} | ||
setDisconnected() { | ||
_setDisconnected() { | ||
this.next(StateId.Disconnected); | ||
@@ -94,25 +106,13 @@ } | ||
} | ||
set connectOptions(options) { | ||
var _a; | ||
this._connectOptions = (_a = this._connectOptions) !== null && _a !== void 0 ? _a : options; | ||
next(newState) { | ||
if (newState > this.current || | ||
(this.current === StateId.Fatal && newState === StateId.Disconnected) /* reconnect */) { | ||
this.sate = newState; | ||
} | ||
else { | ||
throw new Error(`Invalid state requested (current: ${this.current}, requested: ${newState})`); | ||
} | ||
} | ||
get connectOptions() { | ||
return this._connectOptions; | ||
} | ||
set connectResolver(resolver) { | ||
var _a; | ||
this._connectResolver = (_a = this._connectResolver) !== null && _a !== void 0 ? _a : resolver; | ||
} | ||
hasConnectOptions() { | ||
return !!this._connectOptions; | ||
} | ||
async resolveConnectOptions() { | ||
this._connectOptions = { | ||
...this._connectOptions, | ||
...(this._connectResolver ? await mqtt_utilities_1.resolve(this._connectResolver) : {}), | ||
}; | ||
return this._connectOptions; | ||
} | ||
} | ||
exports.MqttBaseClient = MqttBaseClient; | ||
//# sourceMappingURL=mqtt.base-client.js.map |
/// <reference types="node" /> | ||
import { ExecuteDelayed, ExecuteNextTick, ExecutePeriodically, IncomingListenMessage, ListenOptions, ListenSubscribeOptions, MqttAutoReconnectOptions, MqttClientConstructorOptions, MqttSubscription, RegisterClientOptions, Resolvable, StopExecuting, TimerRef } from './mqtt.types'; | ||
import { ExecuteDelayed, ExecutePeriodically, IncomingListenMessage, ListenOptions, ListenSubscribeOptions, MqttAutoReconnectOptions, MqttClientConstructorOptions, MqttSubscription, RegisterClientOptions, Resolvable, StopExecuting, TimerRef } from './mqtt.types'; | ||
import { PacketFlowData, PacketFlowFunc } from './flow'; | ||
@@ -16,3 +16,2 @@ import { MqttParseResult, MqttTransformer } from './mqtt.parser'; | ||
private pingDebug; | ||
protected executeNextTick: ExecuteNextTick; | ||
protected executePeriodically: ExecutePeriodically; | ||
@@ -39,3 +38,4 @@ protected stopExecuting: StopExecuting; | ||
constructor(options: MqttClientConstructorOptions<ReadMap, WriteMap>); | ||
connect(options?: Resolvable<RegisterClientOptions>): Promise<any>; | ||
private _connect; | ||
connect(options?: Resolvable<RegisterClientOptions>): Promise<void>; | ||
protected createPipeline(): void; | ||
@@ -56,4 +56,4 @@ publish(message: MqttMessageOutgoing): Promise<MqttMessageOutgoing>; | ||
* Run the accept and next function of all active flows | ||
* @param {MqttPacket} packet | ||
* @returns {boolean} true if a flow has been found | ||
* @param packet | ||
* @returns true if a flow has been found | ||
*/ | ||
@@ -79,3 +79,3 @@ protected continueFlows(packet: MqttParseResult<ReadMap, typeof PacketType[keyof typeof PacketType]>): boolean; | ||
protected reconnect(): Promise<void>; | ||
protected setDisconnected(reason?: string): Promise<void>; | ||
protected setDisconnected(reason?: string | Error): Promise<void>; | ||
} |
@@ -24,3 +24,2 @@ "use strict"; | ||
// wrapper functions | ||
this.executeNextTick = process.nextTick; | ||
this.executePeriodically = (ms, cb) => setInterval(cb, ms); | ||
@@ -30,3 +29,3 @@ this.stopExecuting = clearInterval; | ||
this.flowCounter = mqtt_utilities_1.createFlowCounter(); | ||
this.reconnectAttempt = 0; | ||
this.reconnectAttempt = 1; | ||
this.activeFlows = []; | ||
@@ -71,11 +70,33 @@ this.messageListener = new mqtt_listener_1.MqttListener(); | ||
} | ||
async connect(options) { | ||
async _connect(options) { | ||
this.expectCreated(); | ||
this.mqttDebug('Connecting...'); | ||
this.mqttDebug(`Connecting using transport "${this.transport.constructor.name}"`); | ||
this.connectResolver = options; | ||
this.setConnecting(); | ||
await this.transport.connect(); | ||
try { | ||
await this.transport.connect(); | ||
} | ||
catch (e) { | ||
this.mqttDebug(`Transport connect error ("${this.transport.constructor.name}")`, e.message); | ||
const shouldReconnect = this.shouldReconnect(); | ||
await this.setDisconnected(e); | ||
if (shouldReconnect) { | ||
return; | ||
} | ||
else { | ||
throw e; | ||
} | ||
} | ||
this.createPipeline(); | ||
return this.registerClient(await this.resolveConnectOptions()); | ||
} | ||
async connect(options) { | ||
try { | ||
await this._connect(options); | ||
} | ||
catch (e) { | ||
this.mqttDebug(`Connection error`, e); | ||
this.emitError(e); | ||
} | ||
} | ||
createPipeline() { | ||
@@ -95,4 +116,5 @@ if (!this.transport.duplex) | ||
this.emitError(err); | ||
if (!this.disconnected) | ||
this.setDisconnected('Pipeline finished').catch(e => this.emitWarning(e)); | ||
if (!this.disconnected) { | ||
(err ? this.setDisconnected(err) : this.setDisconnected('Pipeline finished')).catch(e => this.emitWarning(e)); | ||
} | ||
}); | ||
@@ -112,3 +134,5 @@ } | ||
if (!force) { | ||
return this.startFlow(flow_1.outgoingDisconnectFlow()).then(async () => await this.setDisconnected()); | ||
return this.startFlow(flow_1.outgoingDisconnectFlow()).then(async () => { | ||
await this.setDisconnected(); | ||
}); | ||
} | ||
@@ -174,4 +198,4 @@ else { | ||
* Run the accept and next function of all active flows | ||
* @param {MqttPacket} packet | ||
* @returns {boolean} true if a flow has been found | ||
* @param packet | ||
* @returns true if a flow has been found | ||
*/ | ||
@@ -222,3 +246,4 @@ continueFlows(packet) { | ||
}); | ||
connectPromiseFlow.finally(() => this.stopExecuting(timerId)) | ||
connectPromiseFlow | ||
.finally(() => this.stopExecuting(timerId)) | ||
// not sure why this is necessary, but it's there so no unhandledRejection is thrown | ||
@@ -289,3 +314,3 @@ .catch(() => undefined); | ||
if (typeof this.autoReconnect === 'object' && this.autoReconnect.resetOnConnect) | ||
this.reconnectAttempt = 0; | ||
this.reconnectAttempt = 1; | ||
} | ||
@@ -335,6 +360,6 @@ else { | ||
return false; | ||
if (typeof this.autoReconnect === 'boolean') | ||
return !this.disconnected && this.ready && !this.connecting; | ||
const base = this.autoReconnect.reconnectUnready || (!this.disconnected && this.ready && !this.connecting); | ||
return base && this.reconnectAttempt <= ((_a = this.autoReconnect.maxReconnectAttempts) !== null && _a !== void 0 ? _a : 1); | ||
if (typeof this.autoReconnect === 'boolean') { | ||
return this.autoReconnect; | ||
} | ||
return this.reconnectAttempt <= ((_a = this.autoReconnect.maxReconnectAttempts) !== null && _a !== void 0 ? _a : 1); | ||
} | ||
@@ -346,10 +371,11 @@ async reconnect() { | ||
this.transformer.options.debug = (_a = this.transformer.options.debug) !== null && _a !== void 0 ? _a : this.mqttDebug.extend('transformer'); | ||
await this.connect().catch(e => this.emitError(e)); | ||
await this.connect(); | ||
} | ||
async setDisconnected(reason) { | ||
const willReconnect = this.shouldReconnect(); | ||
this.mqttDebug(`Disconnected. Will reconnect: ${willReconnect}. Reconnect attempt #${this.reconnectAttempt}`); | ||
this.reconnectAttempt++; // this should range from 1 to maxAttempts + 1 when shouldReconnect() is called | ||
const willReconnect = this.autoReconnect && this.shouldReconnect(); | ||
this.stopExecutingFlows(new errors_1.AbortError('Client disconnected.')); | ||
super.setDisconnected(); | ||
this.emitDisconnect(`reason: ${reason} willReconnect: ${willReconnect}`); | ||
this._setDisconnected(); | ||
this.emitDisconnect({ reason, reconnect: willReconnect }); | ||
if (this.transport.active) { | ||
@@ -356,0 +382,0 @@ await new Promise(resolve => { var _a, _b; return (_b = (_a = this.transport.duplex) === null || _a === void 0 ? void 0 : _a.end(resolve)) !== null && _b !== void 0 ? _b : resolve(); }); |
@@ -24,3 +24,2 @@ import { ConnectRequestOptions } from './packets'; | ||
maxReconnectAttempts?: number; | ||
reconnectUnready?: boolean; | ||
resetOnConnect?: boolean; | ||
@@ -34,3 +33,2 @@ } | ||
export declare type TimerRef = any; | ||
export declare type ExecuteNextTick = (action: () => void) => void; | ||
export declare type ExecutePeriodically = (timeInMs: number, action: () => void) => TimerRef; | ||
@@ -37,0 +35,0 @@ export declare type ExecuteDelayed = (timeInMs: number, action: () => void) => TimerRef; |
@@ -26,9 +26,10 @@ "use strict"; | ||
const socket = this.socket; | ||
const duplex = this.duplex; | ||
return new Promise((resolve, reject) => { | ||
socket.once('open', () => { | ||
resolve(); | ||
socket.removeAllListeners('error'); | ||
duplex.removeAllListeners('error'); | ||
}); | ||
socket.once('error', () => { | ||
reject(); | ||
duplex.once('error', e => { | ||
reject(e); | ||
socket.removeAllListeners('open'); | ||
@@ -35,0 +36,0 @@ }); |
139
package.json
{ | ||
"name": "mqtts", | ||
"version": "1.4.0-beta.1", | ||
"description": "MQTT client in Typescript", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist" | ||
], | ||
"engines": { | ||
"node": ">=14.0.0" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/Nerixyz/mqtts" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/Nerixyz/mqtts/issues" | ||
}, | ||
"scripts": { | ||
"test": "jest", | ||
"build": "rimraf dist && tsc -p tsconfig.build.json", | ||
"prepare": "npm run build", | ||
"lint": "eslint --fix --ext .js,.ts src/**", | ||
"format": "prettier --write \"src/**/*.ts\" --loglevel warn", | ||
"typecheck": "tsc -p tsconfig.build.json --noEmit", | ||
"precommit": "npm run typecheck && npm run lint && npm run format" | ||
}, | ||
"dependencies": { | ||
"@types/ws": "^7.2.5", | ||
"debug": "^4.1.1", | ||
"eventemitter3": "^4.0.4", | ||
"socks": "^2.5.0", | ||
"ts-custom-error": "^3.1.1", | ||
"ts-xor": "^1.0.8", | ||
"ws": "^7.3.0" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "^4.2.11", | ||
"@types/chai-as-promised": "^7.1.2", | ||
"@types/debug": "^4.1.5", | ||
"@types/duplexify": "^3.6.0", | ||
"@types/jest": "^26.0.0", | ||
"@types/node": "^14.14.35", | ||
"@types/sinon": "^9.0.4", | ||
"@typescript-eslint/eslint-plugin": "4.18.0", | ||
"@typescript-eslint/parser": "^4.18.0", | ||
"chai": "^4.2.0", | ||
"chai-as-promised": "^7.1.1", | ||
"duplexify": "^4.1.1", | ||
"eslint": "^7.22.0", | ||
"eslint-config-prettier": "^8.1.0", | ||
"jest": "^26.0.1", | ||
"prettier": "^2.0.5", | ||
"rimraf": "^3.0.2", | ||
"sinon": "^9.0.2", | ||
"ts-jest": "^26.5.4", | ||
"typescript": "^4.2.3" | ||
}, | ||
"keywords": [ | ||
"MQTT", | ||
"subscribe", | ||
"iot", | ||
"tls" | ||
], | ||
"author": "nerixyz", | ||
"license": "MIT" | ||
"name": "mqtts", | ||
"version": "1.4.0-beta.2", | ||
"description": "MQTT client in Typescript", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist" | ||
], | ||
"engines": { | ||
"node": ">=14.0.0" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/Nerixyz/mqtts" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/Nerixyz/mqtts/issues" | ||
}, | ||
"scripts": { | ||
"test": "jest", | ||
"build": "rimraf dist && tsc -p tsconfig.build.json", | ||
"prepare": "npm run build", | ||
"lint": "eslint --fix --ext .js,.ts src/**", | ||
"format": "prettier --write \"src/**/*.ts\" --loglevel warn", | ||
"typecheck": "tsc -p tsconfig.build.json --noEmit", | ||
"precommit": "npm run typecheck && npm run lint && npm run format" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "pretty-quick --staged" | ||
} | ||
}, | ||
"dependencies": { | ||
"@types/ws": "^7.2.5", | ||
"debug": "^4.1.1", | ||
"eventemitter3": "^4.0.4", | ||
"socks": "^2.5.0", | ||
"ts-custom-error": "^3.1.1", | ||
"ts-xor": "^1.0.8", | ||
"ws": "^7.3.0" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "^4.2.11", | ||
"@types/chai-as-promised": "^7.1.2", | ||
"@types/debug": "^4.1.5", | ||
"@types/duplexify": "^3.6.0", | ||
"@types/jest": "^26.0.0", | ||
"@types/node": "^14.14.35", | ||
"@types/sinon": "^9.0.4", | ||
"@typescript-eslint/eslint-plugin": "4.18.0", | ||
"@typescript-eslint/parser": "^4.18.0", | ||
"chai": "^4.2.0", | ||
"chai-as-promised": "^7.1.1", | ||
"duplexify": "^4.1.1", | ||
"eslint": "^7.22.0", | ||
"eslint-config-prettier": "^8.1.0", | ||
"husky": "^5.2.0", | ||
"jest": "^26.0.1", | ||
"prettier": "^2.0.5", | ||
"pretty-quick": "^3.1.0", | ||
"rimraf": "^3.0.2", | ||
"sinon": "^9.0.2", | ||
"ts-jest": "^26.5.4", | ||
"typescript": "^4.2.3" | ||
}, | ||
"keywords": [ | ||
"MQTT", | ||
"subscribe", | ||
"iot", | ||
"tls" | ||
], | ||
"author": "nerixyz", | ||
"license": "MIT" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
169739
2542
22