websocket-mqtt 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/base.d.ts CHANGED
@@ -3,13 +3,12 @@ import { type ConnackPacket, type PublishPacket, type QoSLevel } from "./packets
3
3
  import { type EventEmitter } from "./utils/events.js";
4
4
  export type MqttEvents = {
5
5
  connect: [packet: ConnackPacket];
6
+ offline: [];
7
+ reconnect: [attempt: number, delayMs: number];
8
+ close: [];
6
9
  message: [topic: string, payload: Uint8Array, packet: PublishPacket];
7
10
  error: [error: unknown];
8
- close: [];
9
11
  };
10
- export type MqttOptions = {
11
- url: string;
12
- } & ConnectionOptions;
13
12
  export type MqttClient = EventEmitter<MqttEvents> & {
14
13
  connection: Connection;
15
14
  isConnected: () => boolean;
@@ -18,6 +17,7 @@ export type MqttClient = EventEmitter<MqttEvents> & {
18
17
  retain?: boolean;
19
18
  }) => Promise<void>;
20
19
  subscribe: (topic: string, qos?: QoSLevel) => Promise<number[]>;
20
+ unsubscribe: (topic: string | string[]) => Promise<void>;
21
21
  connect: () => Promise<void>;
22
22
  close: () => void;
23
23
  };
@@ -27,7 +27,8 @@ export type MqttClientInternalRequest<K> = {
27
27
  };
28
28
  export type MqttClientInternalPending = {
29
29
  sub: Map<number, MqttClientInternalRequest<number[]>>;
30
+ unsub: Map<number, MqttClientInternalRequest<void>>;
30
31
  pub: Map<number, MqttClientInternalRequest<void>>;
31
32
  };
32
- export declare const createMqtt: (options: MqttOptions) => MqttClient;
33
+ export declare const createMqtt: (options: ConnectionOptions) => MqttClient;
33
34
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1E,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IACrE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACxB,KAAK,EAAE,EAAE,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,iBAAiB,CAAC;AAEtB,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG;IAClD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,OAAO,EAAE,CACP,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;KAAE,KAC5C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI;IACzC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC9B,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtD,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;CACnD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,WAAW,KAAG,UAiIjD,CAAC"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,aAAa,EAElB,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1E,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjC,OAAO,EAAE,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IACrE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG;IAClD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,OAAO,EAAE,CACP,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;KAAE,KAC5C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChE,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI;IACzC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;CACnD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,iBAAiB,KAAG,UAsLvD,CAAC"}
package/dist/base.js CHANGED
@@ -6,17 +6,28 @@ import { createLogger } from "./utils/logger.js";
6
6
  export const createMqtt = (options) => {
7
7
  const pending = {
8
8
  sub: new Map(),
9
+ unsub: new Map(),
9
10
  pub: new Map(),
10
11
  };
11
12
  const events = createEventEmitter();
12
13
  const log = createLogger(options);
13
14
  const connection = createConnection(options);
14
- connection.on("connect", (packet) => {
15
- events.emit("connect", packet);
16
- });
17
- connection.on("message", (topic, payload, packet) => {
18
- events.emit("message", topic, payload, packet);
19
- });
15
+ const rejectAllPending = () => {
16
+ for (const request of pending.sub.values()) {
17
+ request.reject(new Error("Connection closed"));
18
+ }
19
+ pending.sub.clear();
20
+ for (const request of pending.unsub.values()) {
21
+ request.reject(new Error("Connection closed"));
22
+ }
23
+ pending.unsub.clear();
24
+ for (const request of pending.pub.values()) {
25
+ request.reject(new Error("Connection closed"));
26
+ }
27
+ pending.pub.clear();
28
+ };
29
+ connection.on("connect", packet => events.emit("connect", packet));
30
+ connection.on("message", (topic, payload, packet) => events.emit("message", topic, payload, packet));
20
31
  connection.on("packet", (packet) => {
21
32
  switch (packet.type) {
22
33
  case PacketType.SUBACK: {
@@ -34,6 +45,15 @@ export const createMqtt = (options) => {
34
45
  }
35
46
  break;
36
47
  }
48
+ case PacketType.UNSUBACK: {
49
+ log("UNSUBACK", packet);
50
+ const request = pending.unsub.get(packet.messageId);
51
+ if (request) {
52
+ pending.unsub.delete(packet.messageId);
53
+ request.resolve();
54
+ }
55
+ break;
56
+ }
37
57
  case PacketType.PUBACK: {
38
58
  log("PUBACK", packet);
39
59
  const request = pending.pub.get(packet.messageId);
@@ -45,21 +65,19 @@ export const createMqtt = (options) => {
45
65
  }
46
66
  }
47
67
  });
48
- connection.on("error", (err) => {
49
- console.error("error", err);
50
- events.emit("error", err);
68
+ connection.on("error", err => events.emit("error", err));
69
+ connection.on("reconnect", (attempt, delayMs) => events.emit("reconnect", attempt, delayMs));
70
+ connection.on("offline", () => {
71
+ rejectAllPending();
72
+ events.emit("offline");
51
73
  });
52
74
  connection.on("close", () => {
53
- for (const request of pending.sub.values()) {
54
- request.reject(new Error("Connection closed"));
55
- }
56
- pending.sub.clear();
57
- for (const request of pending.pub.values()) {
58
- request.reject(new Error("Connection closed"));
59
- }
60
- pending.pub.clear();
75
+ rejectAllPending();
61
76
  events.emit("close");
62
77
  });
78
+ connection.on("reconnect", (attempt, delayMs) => {
79
+ events.emit("reconnect", attempt, delayMs);
80
+ });
63
81
  const publish = (topic, payload, options) => {
64
82
  const qos = options?.qos ?? QoS.AT_MOST_ONCE;
65
83
  const retain = options?.retain ?? false;
@@ -90,21 +108,44 @@ export const createMqtt = (options) => {
90
108
  subscriptions: [{ topic, qos }],
91
109
  });
92
110
  });
111
+ const unsubscribe = (topic) => new Promise((resolve, reject) => {
112
+ const topics = Array.isArray(topic) ? topic : [topic];
113
+ const messageId = connection.nextMessageId();
114
+ pending.unsub.set(messageId, { resolve, reject });
115
+ connection.send({
116
+ type: PacketType.UNSUBSCRIBE,
117
+ messageId,
118
+ topics,
119
+ });
120
+ });
93
121
  const connect = () => new Promise((resolve, reject) => {
122
+ // Resolves on the first successful connect (including after retries).
123
+ // Rejects only when the connection is permanently closed (retries exhausted
124
+ // or intentional close).
125
+ const onConnect = () => {
126
+ cleanup();
127
+ resolve();
128
+ };
129
+ const onClose = () => {
130
+ cleanup();
131
+ reject(new Error("Connection closed"));
132
+ };
133
+ const cleanup = () => {
134
+ connection.off("connect", onConnect);
135
+ connection.off("close", onClose);
136
+ };
137
+ connection.on("connect", onConnect);
138
+ connection.on("close", onClose);
94
139
  connection.open();
95
- connection.on("connect", () => resolve());
96
- connection.on("error", err => reject(err));
97
140
  });
98
141
  return {
99
142
  ...events,
100
143
  publish,
101
144
  subscribe,
145
+ unsubscribe,
102
146
  connection,
103
147
  isConnected: () => connection.isConnected(),
104
148
  connect,
105
- close: () => {
106
- log("closing from up above");
107
- connection.close();
108
- },
149
+ close: () => connection.close(),
109
150
  };
110
151
  };
@@ -1,5 +1,11 @@
1
1
  import { ConnackPacket, IncomingPacket, OutgoingPacket, PublishPacket, QoSLevel } from "./packets/index.js";
2
2
  import { type LogOptions } from "./utils/logger.js";
3
+ export type RetryOptions = {
4
+ retries?: number;
5
+ initialDelayMs?: number;
6
+ maxDelayMs?: number;
7
+ jitter?: boolean;
8
+ };
3
9
  export type ConnectionOptions = {
4
10
  url: string;
5
11
  clientId?: string;
@@ -14,6 +20,7 @@ export type ConnectionOptions = {
14
20
  retain?: boolean;
15
21
  };
16
22
  signal?: AbortSignal;
23
+ retry?: RetryOptions;
17
24
  } & LogOptions;
18
25
  export type HandlePacketFunction = (packet: IncomingPacket) => void;
19
26
  export type Connection = {
@@ -25,10 +32,12 @@ export type Connection = {
25
32
  };
26
33
  export type ConnectionEvents = {
27
34
  connect: [packet: ConnackPacket];
35
+ offline: [];
36
+ reconnect: [attempt: number, delayMs: number];
37
+ close: [];
28
38
  message: [topic: string, payload: Uint8Array, packet: PublishPacket];
29
39
  packet: [packet: IncomingPacket];
30
40
  error: [error: unknown];
31
- close: [];
32
41
  };
33
42
  export declare const DEFAULT_CLIENT_ID = "websocket_mqtt_";
34
43
  export declare const createConnection: (options: ConnectionOptions) => {
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,aAAa,EAGb,cAAc,EACd,cAAc,EAEd,aAAa,EAEb,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAElE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;QAC7B,GAAG,CAAC,EAAE,QAAQ,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,UAAU,CAAC;AAEf,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;AAEpE,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IACrE,MAAM,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACjC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACxB,KAAK,EAAE,EAAE,CAAC;CACX,CAAC;AAEF,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB;;;;;;mBA6FnC,cAAc,KAAG,IAAI;yBAlEjB,MAAM;;CAiKjC,CAAC"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,aAAa,EAGb,cAAc,EACd,cAAc,EAEd,aAAa,EAEb,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIlE,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;QAC7B,GAAG,CAAC,EAAE,QAAQ,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB,GAAG,UAAU,CAAC;AAEf,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;AAEpE,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjC,OAAO,EAAE,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9C,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IACrE,MAAM,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACjC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB;;;;;;mBAqEnC,cAAc,KAAG,IAAI;yBAVjB,MAAM;;CAwQjC,CAAC"}
@@ -3,16 +3,43 @@ import { decodeAll, DEFAULT_KEEPALIVE_SECONDS, PacketType, QoS, } from "./packet
3
3
  import { toUint8Array } from "./utils/buffer.js";
4
4
  import { createEventEmitter } from "./utils/events.js";
5
5
  import { createLogger } from "./utils/logger.js";
6
+ const FORCE_CLOSE_TIMEOUT_MS = 2000;
6
7
  export const DEFAULT_CLIENT_ID = "websocket_mqtt_";
7
8
  export const createConnection = (options) => {
8
9
  const events = createEventEmitter();
9
10
  const log = createLogger(options);
10
11
  let lastMessageId = 1;
11
12
  let connected = false;
12
- let pingInterval;
13
13
  let ws;
14
+ let activeAc;
15
+ const timers = {
16
+ pingInterval: undefined,
17
+ pingTimeout: undefined,
18
+ retry: undefined,
19
+ forceClose: undefined,
20
+ clearAll() {
21
+ if (this.pingInterval)
22
+ clearInterval(this.pingInterval);
23
+ if (this.pingTimeout)
24
+ clearTimeout(this.pingTimeout);
25
+ if (this.retry)
26
+ clearTimeout(this.retry);
27
+ if (this.forceClose)
28
+ clearTimeout(this.forceClose);
29
+ this.pingInterval = undefined;
30
+ this.pingTimeout = undefined;
31
+ this.retry = undefined;
32
+ this.forceClose = undefined;
33
+ },
34
+ };
14
35
  const { clientId = DEFAULT_CLIENT_ID + Math.random().toString(36)
15
- .slice(2, 15), username, password, keepalive = DEFAULT_KEEPALIVE_SECONDS, clean = true, url, signal, } = options;
36
+ .slice(2, 15), username, password, keepalive = DEFAULT_KEEPALIVE_SECONDS, clean = true, url, signal, retry, } = options;
37
+ const maxRetries = Math.max(0, retry?.retries ?? 0);
38
+ const initialDelayMs = retry?.initialDelayMs ?? 1000;
39
+ const maxDelayMs = retry?.maxDelayMs ?? 30000;
40
+ const jitter = retry?.jitter ?? true;
41
+ let intentionalClose = false;
42
+ let retryAttempt = 0;
16
43
  const will = options.will
17
44
  ? {
18
45
  topic: options.will.topic,
@@ -26,53 +53,7 @@ export const createConnection = (options) => {
26
53
  lastMessageId = (messageId % 65535) + 1;
27
54
  return lastMessageId;
28
55
  };
29
- const startPingInterval = () => {
30
- log("starting ping interval");
31
- if (keepalive > 0) {
32
- const pingIntervalMs = (keepalive * 1000) / 2;
33
- pingInterval = setInterval(() => {
34
- sendRaw(encodePingreq());
35
- }, pingIntervalMs);
36
- }
37
- };
38
56
  let receiveBuffer = new Uint8Array(0);
39
- const handlePacket2 = (packet) => {
40
- log("handlePacket2", packet);
41
- switch (packet.type) {
42
- case PacketType.CONNACK: {
43
- if (packet.returnCode === 0) {
44
- connected = true;
45
- startPingInterval();
46
- events.emit("connect", packet);
47
- log("connected");
48
- }
49
- else {
50
- const message = getConnackErrorMessage(packet.returnCode);
51
- console.error(message);
52
- events.emit("error", new Error(message));
53
- close();
54
- }
55
- break;
56
- }
57
- case PacketType.PUBLISH: {
58
- log("received a publish packet");
59
- if (packet.qos === 1 && packet.messageId !== undefined) {
60
- send({ type: PacketType.PUBACK, messageId: packet.messageId });
61
- }
62
- events.emit("message", packet.topic, packet.payload, packet);
63
- break;
64
- }
65
- case PacketType.PINGRESP: {
66
- log("PINGRESP");
67
- break;
68
- }
69
- default: {
70
- log("received a default packet");
71
- events.emit("packet", packet);
72
- break;
73
- }
74
- }
75
- };
76
57
  const send = (packet) => {
77
58
  log("sending packet", packet);
78
59
  sendRaw(encodePacket(packet));
@@ -86,23 +67,148 @@ export const createConnection = (options) => {
86
67
  log("not sending raw data", data);
87
68
  }
88
69
  };
70
+ const scheduleRetry = () => {
71
+ if (maxRetries === 0 || (maxRetries !== Infinity && retryAttempt >= maxRetries)) {
72
+ events.emit("close");
73
+ return;
74
+ }
75
+ retryAttempt++;
76
+ const exponentialDelay = Math.min(initialDelayMs * 2 ** (retryAttempt - 1), maxDelayMs);
77
+ const delay = jitter
78
+ ? exponentialDelay * (0.5 + Math.random() * 0.5)
79
+ : exponentialDelay;
80
+ log(`scheduling retry #${retryAttempt} in ${Math.round(delay)}ms`);
81
+ events.emit("reconnect", retryAttempt, Math.round(delay));
82
+ timers.retry = setTimeout(() => {
83
+ timers.retry = undefined;
84
+ open();
85
+ }, delay);
86
+ };
89
87
  const close = () => {
90
88
  log("closing connection");
89
+ intentionalClose = true;
90
+ timers.clearAll();
91
+ // Detach all WebSocket listeners before closing to prevent handleDisconnect
92
+ if (activeAc) {
93
+ activeAc.abort();
94
+ activeAc = undefined;
95
+ }
91
96
  if (connected && ws) {
92
97
  sendRaw(encodeDisconnect());
93
98
  }
94
99
  ws?.close();
100
+ ws = undefined;
95
101
  connected = false;
96
- if (pingInterval) {
97
- clearInterval(pingInterval);
98
- pingInterval = undefined;
99
- }
102
+ events.emit("close");
100
103
  };
101
104
  const open = () => {
102
- ws = new WebSocket(url, ["mqtt"]);
105
+ intentionalClose = false;
106
+ receiveBuffer = new Uint8Array(0);
107
+ // Abort previous WebSocket listeners and close socket if open() is called again
108
+ if (activeAc) {
109
+ activeAc.abort();
110
+ }
111
+ ws?.close();
112
+ const ac = new AbortController();
113
+ activeAc = ac;
114
+ const { signal: wsSignal } = ac;
115
+ let disconnected = false;
116
+ const handleDisconnect = () => {
117
+ if (disconnected)
118
+ return;
119
+ disconnected = true;
120
+ ac.abort();
121
+ activeAc = undefined;
122
+ log("ws:disconnect");
123
+ connected = false;
124
+ timers.clearAll();
125
+ if (!intentionalClose) {
126
+ events.emit("offline");
127
+ scheduleRetry();
128
+ }
129
+ };
130
+ const handleConnectionLost = () => {
131
+ connected = false;
132
+ timers.clearAll();
133
+ ws?.close();
134
+ timers.forceClose = setTimeout(() => {
135
+ log("force closing stale connection");
136
+ timers.forceClose = undefined;
137
+ ws = undefined;
138
+ handleDisconnect();
139
+ }, FORCE_CLOSE_TIMEOUT_MS);
140
+ };
141
+ const startPingInterval = () => {
142
+ if (keepalive <= 0)
143
+ return;
144
+ log("starting ping interval");
145
+ const pingIntervalMs = (keepalive * 1000) / 2;
146
+ const pingTimeoutMs = keepalive * 1000;
147
+ timers.pingInterval = setInterval(() => {
148
+ sendRaw(encodePingreq());
149
+ if (!timers.pingTimeout) {
150
+ timers.pingTimeout = setTimeout(() => {
151
+ log("ping timeout, connection lost");
152
+ handleConnectionLost();
153
+ }, pingTimeoutMs);
154
+ }
155
+ }, pingIntervalMs);
156
+ };
157
+ const handlePacket = (packet) => {
158
+ log("handlePacket", packet);
159
+ // Any incoming packet proves the connection is alive, so reset the
160
+ // ping timeout (not just PINGRESP — the spec only requires PINGRESP,
161
+ // but any data is a valid liveness signal).
162
+ if (timers.pingTimeout) {
163
+ clearTimeout(timers.pingTimeout);
164
+ timers.pingTimeout = undefined;
165
+ }
166
+ switch (packet.type) {
167
+ case PacketType.CONNACK: {
168
+ if (packet.returnCode === 0) {
169
+ connected = true;
170
+ retryAttempt = 0;
171
+ startPingInterval();
172
+ events.emit("connect", packet);
173
+ log("connected");
174
+ }
175
+ else {
176
+ const message = getConnackErrorMessage(packet.returnCode);
177
+ events.emit("error", new Error(message));
178
+ close();
179
+ }
180
+ break;
181
+ }
182
+ case PacketType.PUBLISH: {
183
+ log("received a publish packet");
184
+ if (packet.qos === 1 && packet.messageId !== undefined) {
185
+ send({ type: PacketType.PUBACK, messageId: packet.messageId });
186
+ }
187
+ events.emit("message", packet.topic, packet.payload, packet);
188
+ break;
189
+ }
190
+ case PacketType.PINGRESP: {
191
+ log("PINGRESP");
192
+ break;
193
+ }
194
+ default: {
195
+ log("received a default packet");
196
+ events.emit("packet", packet);
197
+ break;
198
+ }
199
+ }
200
+ };
201
+ try {
202
+ ws = new WebSocket(url, ["mqtt"]);
203
+ }
204
+ catch (error) {
205
+ log("WebSocket constructor threw", error);
206
+ events.emit("error", error);
207
+ scheduleRetry();
208
+ return;
209
+ }
103
210
  ws.binaryType = "arraybuffer";
104
211
  ws.addEventListener("open", () => {
105
- // sendConnect();
106
212
  const packet = encodeConnect({
107
213
  type: PacketType.CONNECT,
108
214
  clientId,
@@ -113,7 +219,7 @@ export const createConnection = (options) => {
113
219
  will,
114
220
  });
115
221
  sendRaw(packet);
116
- });
222
+ }, { signal: wsSignal });
117
223
  ws.addEventListener("message", (event) => {
118
224
  log("onmessage");
119
225
  const data = new Uint8Array(event.data);
@@ -125,17 +231,18 @@ export const createConnection = (options) => {
125
231
  receiveBuffer = remaining;
126
232
  log("packets to process", packets.length);
127
233
  for (const packet of packets) {
128
- log("packet", packet);
129
- handlePacket2(packet);
234
+ handlePacket(packet);
130
235
  }
131
- });
236
+ }, { signal: wsSignal });
132
237
  ws.addEventListener("error", (event) => {
133
238
  events.emit("error", event);
134
- });
135
- ws.addEventListener("close", () => {
136
- log("ws:onclose");
137
- close();
138
- });
239
+ // If we were never connected, the close event may not fire (e.g. Node.js
240
+ // WebSocket on a failed connection attempt), so treat it as a disconnect.
241
+ if (!connected) {
242
+ handleDisconnect();
243
+ }
244
+ }, { signal: wsSignal });
245
+ ws.addEventListener("close", handleDisconnect, { signal: wsSignal });
139
246
  };
140
247
  signal?.addEventListener("abort", () => {
141
248
  log("abort signal received");
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./base.js";
2
+ export type { ConnectionOptions, RetryOptions } from "./connection.js";
2
3
  export type { MqttPacket, QoSLevel } from "./packets/index.js";
3
4
  export { QoS } from "./packets/index.js";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/packets/decode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EAKf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,MAAM,GAAI,OAAO,UAAU,KAAG,YAAY,GAAG,IAiDzD,CAAC;AA0CF,eAAO,MAAM,SAAS,GAAI,OAAO,UAAU,KAAG;IAC5C,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,UAAU,CAAC;CAevB,CAAC"}
1
+ {"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/packets/decode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EAMf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,MAAM,GAAI,OAAO,UAAU,KAAG,YAAY,GAAG,IAqDzD,CAAC;AA6CF,eAAO,MAAM,SAAS,GAAI,OAAO,UAAU,KAAG;IAC5C,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,UAAU,CAAC;CAevB,CAAC"}
@@ -35,6 +35,10 @@ export const decode = (bytes) => {
35
35
  packet = decodePuback(payloadReader);
36
36
  break;
37
37
  }
38
+ case PacketType.UNSUBACK: {
39
+ packet = decodeUnsuback(payloadReader);
40
+ break;
41
+ }
38
42
  case PacketType.PINGRESP: {
39
43
  packet = { type: PacketType.PINGRESP };
40
44
  break;
@@ -76,6 +80,7 @@ const decodePublish = (reader, flags) => {
76
80
  };
77
81
  };
78
82
  const decodePuback = (reader) => ({ type: PacketType.PUBACK, messageId: reader.readUint16() });
83
+ const decodeUnsuback = (reader) => ({ type: PacketType.UNSUBACK, messageId: reader.readUint16() });
79
84
  export const decodeAll = (bytes) => {
80
85
  const packets = [];
81
86
  let offset = 0;
@@ -1,6 +1,7 @@
1
- import type { ConnectPacket, OutgoingPacket, PubackPacket, PublishPacket, SubscribePacket } from "./types.js";
1
+ import type { ConnectPacket, OutgoingPacket, PubackPacket, PublishPacket, SubscribePacket, UnsubscribePacket } from "./types.js";
2
2
  export declare const encodeConnect: (packet: ConnectPacket) => Uint8Array;
3
3
  export declare const encodeSubscribe: (packet: SubscribePacket) => Uint8Array;
4
+ export declare const encodeUnsubscribe: (packet: UnsubscribePacket) => Uint8Array;
4
5
  export declare const encodePublish: (packet: PublishPacket) => Uint8Array;
5
6
  export declare const encodePuback: (packet: PubackPacket) => Uint8Array;
6
7
  export declare const encodePingreq: () => Uint8Array;
@@ -1 +1 @@
1
- {"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/packets/encode.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAC;AAoBpB,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,KAAG,UAoClD,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,QAAQ,eAAe,KAAG,UAQtD,CAAC;AAEL,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,KAAG,UAkBrD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,QAAQ,YAAY,KAAG,UAGhD,CAAC;AAEL,eAAO,MAAM,aAAa,QAAO,UACa,CAAC;AAE/C,eAAO,MAAM,gBAAgB,QAAO,UACa,CAAC;AAElD,eAAO,MAAM,YAAY,GAAI,QAAQ,cAAc,KAAG,UAsBrD,CAAC"}
1
+ {"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/packets/encode.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,eAAe,EACf,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAoBpB,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,KAAG,UAoClD,CAAC;AAEL,eAAO,MAAM,eAAe,GAAI,QAAQ,eAAe,KAAG,UAQtD,CAAC;AAEL,eAAO,MAAM,iBAAiB,GAAI,QAAQ,iBAAiB,KAAG,UAO1D,CAAC;AAEL,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa,KAAG,UAkBrD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,QAAQ,YAAY,KAAG,UAGhD,CAAC;AAEL,eAAO,MAAM,aAAa,QAAO,UACa,CAAC;AAE/C,eAAO,MAAM,gBAAgB,QAAO,UACa,CAAC;AAElD,eAAO,MAAM,YAAY,GAAI,QAAQ,cAAc,KAAG,UAyBrD,CAAC"}
@@ -47,6 +47,12 @@ export const encodeSubscribe = (packet) => writePacket(PacketType.SUBSCRIBE, 0x0
47
47
  writer.writeByte(sub.qos);
48
48
  }
49
49
  });
50
+ export const encodeUnsubscribe = (packet) => writePacket(PacketType.UNSUBSCRIBE, 0x02, (writer) => {
51
+ writer.writeUint16(packet.messageId);
52
+ for (const topic of packet.topics) {
53
+ writer.writeString(topic);
54
+ }
55
+ });
50
56
  export const encodePublish = (packet) => {
51
57
  let flags = 0;
52
58
  if (packet.dup)
@@ -75,6 +81,9 @@ export const encodePacket = (packet) => {
75
81
  case PacketType.SUBSCRIBE: {
76
82
  return encodeSubscribe(packet);
77
83
  }
84
+ case PacketType.UNSUBSCRIBE: {
85
+ return encodeUnsubscribe(packet);
86
+ }
78
87
  case PacketType.PUBLISH: {
79
88
  return encodePublish(packet);
80
89
  }
@@ -47,6 +47,15 @@ export type SubackPacket = BasePacket & {
47
47
  messageId: number;
48
48
  granted: number[];
49
49
  };
50
+ export type UnsubscribePacket = BasePacket & {
51
+ type: 10;
52
+ messageId: number;
53
+ topics: string[];
54
+ };
55
+ export type UnsubackPacket = BasePacket & {
56
+ type: 11;
57
+ messageId: number;
58
+ };
50
59
  export type PingreqPacket = BasePacket & {
51
60
  type: 12;
52
61
  };
@@ -56,7 +65,7 @@ export type PingrespPacket = BasePacket & {
56
65
  export type DisconnectPacket = BasePacket & {
57
66
  type: 14;
58
67
  };
59
- export type MqttPacket = ConnectPacket | ConnackPacket | PublishPacket | PubackPacket | SubscribePacket | SubackPacket | PingreqPacket | PingrespPacket | DisconnectPacket;
60
- export type IncomingPacket = ConnackPacket | PublishPacket | PubackPacket | SubackPacket | PingrespPacket;
61
- export type OutgoingPacket = ConnectPacket | SubscribePacket | PublishPacket | PubackPacket | DisconnectPacket | PingreqPacket;
68
+ export type MqttPacket = ConnectPacket | ConnackPacket | PublishPacket | PubackPacket | SubscribePacket | SubackPacket | UnsubscribePacket | UnsubackPacket | PingreqPacket | PingrespPacket | DisconnectPacket;
69
+ export type IncomingPacket = ConnackPacket | PublishPacket | PubackPacket | SubackPacket | UnsubackPacket | PingrespPacket;
70
+ export type OutgoingPacket = ConnectPacket | SubscribePacket | UnsubscribePacket | PublishPacket | PubackPacket | DisconnectPacket | PingreqPacket;
62
71
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/packets/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,UAAU,CAAC;QACpB,GAAG,EAAE,QAAQ,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,GAAG,EAAE,QAAQ,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG;IACzC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,KAAK,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,QAAQ,CAAC;KACf,CAAC,CAAC;CACJ,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAC1C,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,aAAa,GACb,aAAa,GACb,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAErB,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,cAAc,CAAC;AAEnB,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,eAAe,GACf,aAAa,GACb,YAAY,GACZ,gBAAgB,GAChB,aAAa,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/packets/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,UAAU,CAAC;QACpB,GAAG,EAAE,QAAQ,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,GAAG,EAAE,QAAQ,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG;IACzC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,KAAK,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,QAAQ,CAAC;KACf,CAAC,CAAC;CACJ,CAAC;AAGF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IACtC,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG;IAC3C,IAAI,EAAE,EAAE,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC,IAAI,EAAE,EAAE,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAGF,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAC1C,IAAI,EAAE,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,aAAa,GACb,aAAa,GACb,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAErB,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,cAAc,CAAC;AAEnB,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,aAAa,GACb,YAAY,GACZ,gBAAgB,GAChB,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "websocket-mqtt",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "A lightweight MQTT WebSocket client library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",