@seriousme/opifex 1.10.1 → 1.11.0

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.
Files changed (83) hide show
  1. package/bin/mqtt.ts +1 -1
  2. package/client/client.ts +27 -7
  3. package/client/context.ts +30 -9
  4. package/deno/tcpClient.ts +1 -1
  5. package/dist/bin/mqtt.js +1 -1
  6. package/dist/bin/mqtt.js.map +1 -1
  7. package/dist/client/client.d.ts +9 -1
  8. package/dist/client/client.d.ts.map +1 -1
  9. package/dist/client/client.js +20 -7
  10. package/dist/client/client.js.map +1 -1
  11. package/dist/client/context.d.ts +5 -2
  12. package/dist/client/context.d.ts.map +1 -1
  13. package/dist/client/context.js +24 -8
  14. package/dist/client/context.js.map +1 -1
  15. package/dist/mqttPacket/auth.d.ts +6 -6
  16. package/dist/mqttPacket/auth.d.ts.map +1 -1
  17. package/dist/mqttPacket/auth.js.map +1 -1
  18. package/dist/mqttPacket/connack.d.ts +4 -4
  19. package/dist/mqttPacket/connack.d.ts.map +1 -1
  20. package/dist/mqttPacket/connect.d.ts +3 -3
  21. package/dist/mqttPacket/connect.d.ts.map +1 -1
  22. package/dist/mqttPacket/disconnect.d.ts +4 -4
  23. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  24. package/dist/mqttPacket/mod.d.ts +1 -0
  25. package/dist/mqttPacket/mod.d.ts.map +1 -1
  26. package/dist/mqttPacket/mod.js +1 -0
  27. package/dist/mqttPacket/mod.js.map +1 -1
  28. package/dist/mqttPacket/protocolLevels.d.ts +5 -4
  29. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
  30. package/dist/mqttPacket/protocolLevels.js +1 -1
  31. package/dist/mqttPacket/protocolLevels.js.map +1 -1
  32. package/dist/mqttPacket/pubblishAcks.d.ts +15 -8
  33. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
  34. package/dist/mqttPacket/pubblishAcks.js.map +1 -1
  35. package/dist/mqttPacket/suback.d.ts +4 -4
  36. package/dist/mqttPacket/suback.d.ts.map +1 -1
  37. package/dist/mqttPacket/subscribe.d.ts +3 -3
  38. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  39. package/dist/mqttPacket/types.d.ts +3 -0
  40. package/dist/mqttPacket/types.d.ts.map +1 -1
  41. package/dist/mqttPacket/unsuback.d.ts +4 -4
  42. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  43. package/dist/mqttPacket/unsubscribe.d.ts +3 -3
  44. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  45. package/dist/mqttPacket/validators.d.ts +15 -0
  46. package/dist/mqttPacket/validators.d.ts.map +1 -1
  47. package/dist/mqttPacket/validators.js +15 -0
  48. package/dist/mqttPacket/validators.js.map +1 -1
  49. package/dist/node/tcpClient.js +1 -1
  50. package/dist/node/tcpClient.js.map +1 -1
  51. package/dist/persistence/memory/memoryPersistence.js +1 -1
  52. package/dist/persistence/memory/memoryPersistence.js.map +1 -1
  53. package/dist/utils/asyncQueue.d.ts +1 -3
  54. package/dist/utils/asyncQueue.d.ts.map +1 -1
  55. package/dist/utils/asyncQueue.js +16 -21
  56. package/dist/utils/asyncQueue.js.map +1 -1
  57. package/dist/utils/logger.d.ts +5 -15
  58. package/dist/utils/logger.d.ts.map +1 -1
  59. package/dist/utils/logger.js +7 -8
  60. package/dist/utils/logger.js.map +1 -1
  61. package/dist/utils/utils.d.ts +2 -0
  62. package/dist/utils/utils.d.ts.map +1 -0
  63. package/dist/utils/utils.js +6 -0
  64. package/dist/utils/utils.js.map +1 -0
  65. package/mqttPacket/auth.ts +6 -7
  66. package/mqttPacket/connack.ts +4 -4
  67. package/mqttPacket/connect.ts +3 -3
  68. package/mqttPacket/disconnect.ts +4 -4
  69. package/mqttPacket/mod.ts +1 -0
  70. package/mqttPacket/protocolLevels.ts +2 -2
  71. package/mqttPacket/pubblishAcks.ts +15 -9
  72. package/mqttPacket/suback.ts +4 -4
  73. package/mqttPacket/subscribe.ts +3 -3
  74. package/mqttPacket/types.ts +3 -0
  75. package/mqttPacket/unsuback.ts +4 -4
  76. package/mqttPacket/unsubscribe.ts +3 -3
  77. package/mqttPacket/validators.ts +15 -0
  78. package/node/tcpClient.ts +1 -1
  79. package/package.json +1 -1
  80. package/persistence/memory/memoryPersistence.ts +1 -1
  81. package/utils/asyncQueue.ts +17 -21
  82. package/utils/logger.ts +12 -11
  83. package/utils/utils.ts +6 -0
@@ -0,0 +1,2 @@
1
+ export declare const noop: () => void;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../utils/utils.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,IAAI,YAAW,CAAC"}
@@ -0,0 +1,6 @@
1
+ /*
2
+ * This file contains utilities used throughout the project too small to
3
+ * deserve their own dedicated files.
4
+ */
5
+ export const noop = () => { };
6
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../utils/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC"}
@@ -5,13 +5,6 @@ import { Decoder, DecoderError, hasEmptyFlags } from "./decoder.ts";
5
5
  import type { TReasonCode } from "./ReasonCode.ts";
6
6
  import type { AuthProperties } from "./Properties.ts";
7
7
 
8
- /**
9
- * An AUTH packet is sent from Client to Server or Server to Client as part of an extended
10
- * authentication exchange, such as challenge / response authentication.
11
- * It is a Protocol Error for the Client or Server to send an AUTH packet
12
- * if the CONNECT packet did not contain the same Authentication Method.
13
- */
14
-
15
8
  // AuthPacket does not exist on protocol levels < 5
16
9
  export type AuthPacketV5 = {
17
10
  type: TPacketType;
@@ -20,6 +13,12 @@ export type AuthPacketV5 = {
20
13
  properties?: AuthProperties;
21
14
  };
22
15
 
16
+ /**
17
+ * An AUTH packet is sent from Client to Server or Server to Client as part of an extended
18
+ * authentication exchange, such as challenge / response authentication.
19
+ * It is a Protocol Error for the Client or Server to send an AUTH packet
20
+ * if the CONNECT packet did not contain the same Authentication Method.
21
+ */
23
22
  export type AuthPacket = AuthPacketV5;
24
23
 
25
24
  export const auth: {
@@ -17,10 +17,6 @@ import { AuthenticationResultByNumber } from "./AuthenticationResult.ts";
17
17
  import type { TReasonCode } from "./ReasonCode.ts";
18
18
  import type { ConnackProperties } from "./Properties.ts";
19
19
 
20
- /**
21
- * ConnackPacket is sent from the server to the client in response to a connect packet.
22
- * It indicates that the connect is accepted.
23
- */
24
20
  export type ConnackPacketV4 = {
25
21
  type: TPacketType;
26
22
  protocolLevel: ProtocolLevelNoV5;
@@ -36,6 +32,10 @@ export type ConnackPacketV5 = {
36
32
  properties?: ConnackProperties;
37
33
  };
38
34
 
35
+ /**
36
+ * ConnackPacket is sent from the server to the client in response to a connect packet.
37
+ * It indicates that the connect is accepted.
38
+ */
39
39
  export type ConnackPacket = ConnackPacketV4 | ConnackPacketV5;
40
40
 
41
41
  export const connack: {
@@ -20,9 +20,6 @@ import {
20
20
  hasEmptyFlags,
21
21
  } from "./decoder.ts";
22
22
 
23
- /**
24
- * ConnectPacket is sent from the client to the server to initiate a connection.
25
- */
26
23
  export type ConnectPacketV4 = {
27
24
  type: TPacketType;
28
25
  protocolName?: string;
@@ -61,6 +58,9 @@ export type ConnectPacketV5 = {
61
58
  properties?: ConnectProperties;
62
59
  };
63
60
 
61
+ /**
62
+ * ConnectPacket is sent from the client to the server to initiate a connection.
63
+ */
64
64
  export type ConnectPacket = ConnectPacketV4 | ConnectPacketV5;
65
65
 
66
66
  function invalidProtocolName(version: number, name: string): boolean {
@@ -10,10 +10,6 @@ import type { DisconnectProperties } from "./Properties.ts";
10
10
  import { Encoder } from "./encoder.ts";
11
11
  import { ReasonCode } from "./ReasonCode.ts";
12
12
 
13
- /**
14
- * DisconnectPacket is the final control packet sent from the client to the server.
15
- * It indicates that the client is disconnecting cleanly.
16
- */
17
13
  export type DisconnectPacketv4 = {
18
14
  type: TPacketType;
19
15
  protocolLevel: ProtocolLevelNoV5;
@@ -26,6 +22,10 @@ export type DisconnectPacketv5 = {
26
22
  properties?: DisconnectProperties;
27
23
  };
28
24
 
25
+ /**
26
+ * DisconnectPacket is the final control packet sent from the client to the server.
27
+ * It indicates that the client is disconnecting cleanly.
28
+ */
29
29
  export type DisconnectPacket = DisconnectPacketv4 | DisconnectPacketv5;
30
30
 
31
31
  const DISCONNECT_PACKET = new Uint8Array([PacketType.disconnect << 4, 0]);
package/mqttPacket/mod.ts CHANGED
@@ -209,6 +209,7 @@ export function decodePayload(
209
209
  /**
210
210
  * @function decode
211
211
  * @description Decodes a complete MQTT packet from binary format into a packet object
212
+ *
212
213
  * @param {Uint8Array} buffer - The binary buffer containing the complete MQTT packet
213
214
  * @param {CodecOpts} codecOpts - the options for the decoder
214
215
  * @returns {AnyPacket} The decoded MQTT packet object
@@ -4,10 +4,10 @@
4
4
 
5
5
  import type { ProtocolLevel } from "./types.ts";
6
6
 
7
- // MQTT Protocol levels
7
+ /** available MQTT Protocol levels */
8
8
  export const MQTTLevel = {
9
9
  unknown: undefined as ProtocolLevel,
10
10
  v3: 3 as ProtocolLevel,
11
11
  v4: 4 as ProtocolLevel,
12
12
  v5: 5 as ProtocolLevel,
13
- };
13
+ } as const;
@@ -10,14 +10,6 @@ import { PacketType } from "./PacketType.ts";
10
10
  import { Decoder, DecoderError } from "./decoder.ts";
11
11
  import { Encoder } from "./encoder.ts";
12
12
 
13
- /**
14
- * PubackPacket is sent to indicate publish complete (QoS 1)
15
- * Pubrec is sent to indicate publish received (QoS 2)
16
- * Pubrel is sent to indicate publish release (QoS 2)
17
- * Pubcomp is sent to indicate publish complete (QoS 2)
18
- *
19
- * all 4 packets are identical except for packet type
20
- */
21
13
  export type AckPacketV4<T> = {
22
14
  type: TPacketType;
23
15
  protocolLevel: ProtocolLevelNoV5;
@@ -31,11 +23,25 @@ export type AckPacketV5<T> = {
31
23
  reasonCode?: TReasonCode;
32
24
  properties?: PubackProperties;
33
25
  };
34
-
26
+ /**
27
+ * all 4 ack packets are identical except for packet type and flags of Pubrel
28
+ */
35
29
  export type AckPacket<T> = AckPacketV4<T> | AckPacketV5<T>;
30
+ /**
31
+ * PubackPacket is sent to indicate publish complete (QoS 1)
32
+ */
36
33
  export type PubackPacket = AckPacket<typeof PacketType.puback>;
34
+ /**
35
+ * Pubrec is sent to indicate publish received (QoS 2)
36
+ */
37
37
  export type PubrecPacket = AckPacket<typeof PacketType.pubrec>;
38
+ /**
39
+ * Pubrel is sent to indicate publish release (QoS 2)
40
+ */
38
41
  export type PubrelPacket = AckPacket<typeof PacketType.pubrel>;
42
+ /**
43
+ * Pubcomp is sent to indicate publish complete (QoS 2)
44
+ */
39
45
  export type PubcompPacket = AckPacket<typeof PacketType.pubcomp>;
40
46
 
41
47
  export type AnyAckPacket =
@@ -12,10 +12,6 @@ import { Encoder } from "./encoder.ts";
12
12
  import { Decoder, DecoderError } from "./decoder.ts";
13
13
  const validReturnCodes = [0x00, 0x01, 0x02, 0x80];
14
14
 
15
- /**
16
- * SubackPacket is sent by the server to the client to confirm receipt and
17
- * processing of a SubscribePacket.
18
- */
19
15
  export type SubackPacketV4 = {
20
16
  type: TPacketType;
21
17
  protocolLevel: ProtocolLevelNoV5;
@@ -31,6 +27,10 @@ export type SubackPacketV5 = {
31
27
  reasonCodes: Array<TReasonCode>;
32
28
  };
33
29
 
30
+ /**
31
+ * SubackPacket is sent by the server to the client to confirm receipt and
32
+ * processing of a SubscribePacket.
33
+ */
34
34
  export type SubackPacket = SubackPacketV4 | SubackPacketV5;
35
35
 
36
36
  export const suback: {
@@ -13,9 +13,6 @@ import { BitMask } from "./BitMask.ts";
13
13
  import { Encoder } from "./encoder.ts";
14
14
  import { booleanFlag, Decoder, DecoderError } from "./decoder.ts";
15
15
 
16
- /**
17
- * SubscribePacket is sent from client to server to subscribe to topics
18
- */
19
16
  export type SubscribePacketV4 = {
20
17
  type: TPacketType;
21
18
  protocolLevel: ProtocolLevelNoV5;
@@ -31,6 +28,9 @@ export type SubscribePacketV5 = {
31
28
  subscriptions: Array<SubscriptionV5>;
32
29
  };
33
30
 
31
+ /**
32
+ * SubscribePacket is sent from client to server to subscribe to topics
33
+ */
34
34
  export type SubscribePacket = SubscribePacketV4 | SubscribePacketV5;
35
35
  /**
36
36
  * The topic to subscribe to and the associated QoS
@@ -73,6 +73,9 @@ export type ReturnCodes = number[];
73
73
  */
74
74
  export type ClientId = string;
75
75
 
76
+ /**
77
+ * helper type to limit retain handling values
78
+ */
76
79
  export type TRetainHandling =
77
80
  typeof RetainHandling[keyof typeof RetainHandling];
78
81
 
@@ -10,10 +10,6 @@ import { PacketType } from "./PacketType.ts";
10
10
  import { Decoder, hasEmptyFlags } from "./decoder.ts";
11
11
  import { Encoder } from "./encoder.ts";
12
12
 
13
- /**
14
- * UnsubackPacket is sent by the server to the client to confirm receipt
15
- * of an UnsubscribePacket.
16
- */
17
13
  export type UnsubackPacketV4 = {
18
14
  type: TPacketType;
19
15
  protocolLevel: ProtocolLevelNoV5;
@@ -28,6 +24,10 @@ export type UnsubackPacketV5 = {
28
24
  reasonCodes: Array<TReasonCode>;
29
25
  };
30
26
 
27
+ /**
28
+ * UnsubackPacket is sent by the server to the client to confirm receipt
29
+ * of an UnsubscribePacket.
30
+ */
31
31
  export type UnsubackPacket = UnsubackPacketV4 | UnsubackPacketV5;
32
32
 
33
33
  export const unsuback: {
@@ -11,9 +11,6 @@ import { PacketType } from "./PacketType.ts";
11
11
  import { Encoder } from "./encoder.ts";
12
12
  import { Decoder, DecoderError } from "./decoder.ts";
13
13
 
14
- /**
15
- * UnsubscribePacket is sent from client to server to unsubscribe from topics
16
- */
17
14
  export type UnsubscribePacketV4 = {
18
15
  type: TPacketType;
19
16
  protocolLevel: ProtocolLevelNoV5;
@@ -29,6 +26,9 @@ export type UnsubscribePacketV5 = {
29
26
  topicFilters: TopicFilter[];
30
27
  };
31
28
 
29
+ /**
30
+ * UnsubscribePacket is sent from client to server to unsubscribe from topics
31
+ */
32
32
  export type UnsubscribePacket = UnsubscribePacketV4 | UnsubscribePacketV5;
33
33
 
34
34
  export const unsubscribe: {
@@ -7,14 +7,29 @@ const invalidTopicRegEx = new RegExp(/^$|\+|#|\x00|\uFFFD/);
7
7
  // deno-lint-ignore no-control-regex
8
8
  const invalidTopicFilterRegEx = new RegExp(/^$|#.|[^\/]\+|\+[^\/]|\x00|\uFFFD/);
9
9
 
10
+ /**
11
+ * check for invalid UTF-8 characters
12
+ * @param value string to test
13
+ * @returns true if the string contains invalid UTF-8 characters
14
+ */
10
15
  export function invalidUTF8(value: string): boolean {
11
16
  return invalidUTF8regEx.test(value);
12
17
  }
13
18
 
19
+ /**
20
+ * check for invalid topic characters
21
+ * @param value
22
+ * @returns true if the topic is invalid
23
+ */
14
24
  export function invalidTopic(value: Topic): boolean {
15
25
  return invalidTopicRegEx.test(value);
16
26
  }
17
27
 
28
+ /**
29
+ * check for invalid topic filter characters
30
+ * @param value topic filter to test
31
+ * @returns true if the topic filter is invalid
32
+ */
18
33
  export function invalidTopicFilter(value: TopicFilter): boolean {
19
34
  return invalidTopicFilterRegEx.test(value);
20
35
  }
package/node/tcpClient.ts CHANGED
@@ -96,6 +96,6 @@ export class TcpClient extends Client {
96
96
  if (protocol === "mqtt:") {
97
97
  return this.connectMQTT(hostname, port);
98
98
  }
99
- throw `Unsupported protocol: ${protocol}`;
99
+ throw new Error(`Unsupported protocol: ${protocol}`);
100
100
  }
101
101
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seriousme/opifex",
3
- "version": "1.10.1",
3
+ "version": "1.11.0",
4
4
  "description": "MQTT client & server for Deno & NodeJS",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -134,7 +134,7 @@ export class MemoryPersistence implements IPersistence {
134
134
  newPacket.qos = qos;
135
135
  // logger.debug(`publish ${topic} to client ${clientId}`);
136
136
  const client = this.clientList.get(clientId);
137
- client?.handler(packet);
137
+ client?.handler(newPacket);
138
138
  }
139
139
  }
140
140
 
@@ -1,3 +1,4 @@
1
+ import { Deferred } from "./deferred.ts";
1
2
  import { nextTick } from "./nextTick.ts";
2
3
  /**
3
4
  * An Async Queue is a queue that can be used to push items to it and then wait
@@ -12,13 +13,14 @@ import { nextTick } from "./nextTick.ts";
12
13
  * }
13
14
  * ```
14
15
  */
16
+
15
17
  export class AsyncQueue<T> {
16
18
  private queue: T[] = [];
17
19
  private maxQueueLength = Infinity;
18
- private nextResolve = (_value: T) => {};
19
- private nextReject = (_reason?: string) => {};
20
+
20
21
  private done = false;
21
- private hasNext = false;
22
+
23
+ #next?: Deferred<T>;
22
24
 
23
25
  constructor(maxQueueLength?: number) {
24
26
  if (maxQueueLength) {
@@ -28,39 +30,33 @@ export class AsyncQueue<T> {
28
30
 
29
31
  async next(): Promise<T> {
30
32
  await nextTick();
31
- if (this.done && this.queue.length === 0) {
33
+ if (this.queue.length) {
34
+ return Promise.resolve(this.queue.shift()!);
35
+ } else if (this.done) {
32
36
  return Promise.reject("Closed");
37
+ } else if (!this.#next) {
38
+ this.#next = new Deferred<T>();
33
39
  }
34
- return new Promise((resolve, reject) => {
35
- if (this.queue.length > 0) {
36
- const item = this.queue.shift();
37
- if (item) {
38
- return resolve(item);
39
- }
40
- }
41
- this.nextResolve = resolve;
42
- this.nextReject = reject;
43
- this.hasNext = true;
44
- });
40
+ return this.#next.promise;
45
41
  }
46
42
 
47
43
  close(reason = "closed"): void {
48
44
  this.done = true;
49
- if (this.hasNext) {
50
- this.nextReject(reason);
45
+ if (this.#next) {
46
+ this.#next.reject(new Error(reason));
51
47
  }
52
48
  }
53
49
 
54
50
  async *[Symbol.asyncIterator](): AsyncGenerator<Awaited<T>, void, unknown> {
55
51
  while (true) {
56
- yield this.next();
52
+ yield await this.next();
57
53
  }
58
54
  }
59
55
 
60
56
  push(item: T) {
61
- if (this.hasNext) {
62
- this.nextResolve(item);
63
- this.hasNext = false;
57
+ if (this.#next) {
58
+ this.#next.resolve(item);
59
+ this.#next = undefined;
64
60
  return;
65
61
  }
66
62
  if (this.queue.length > this.maxQueueLength) {
package/utils/logger.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { noop } from "./utils.ts";
2
+
1
3
  /**
2
4
  * The available log levels
3
5
  */
@@ -30,21 +32,20 @@ export class Logger {
30
32
  private defaultInfo = console.info;
31
33
  private defaultVerbose = console.log;
32
34
  private defaultDebug = console.log;
33
- // deno-lint-ignore no-explicit-any
34
- private noop = (..._data: any[]) => {};
35
- error = this.defaultError;
36
- warn = this.defaultWarn;
37
- info = this.defaultInfo;
38
- verbose = this.noop;
39
- debug = this.noop;
35
+
36
+ error: typeof console.log = this.defaultError;
37
+ warn: typeof console.log = this.defaultWarn;
38
+ info: typeof console.log = this.defaultInfo;
39
+ verbose: typeof console.log = noop;
40
+ debug: typeof console.log = noop;
40
41
 
41
42
  constructor() {}
42
43
 
43
44
  level(logLevel: TLogLevel) {
44
- this.warn = logLevel > 0 ? this.defaultWarn : this.noop;
45
- this.info = logLevel > 1 ? this.defaultInfo : this.noop;
46
- this.verbose = logLevel > 2 ? this.defaultVerbose : this.noop;
47
- this.debug = logLevel > 3 ? this.defaultDebug : this.noop;
45
+ this.warn = logLevel > 0 ? this.defaultWarn : noop;
46
+ this.info = logLevel > 1 ? this.defaultInfo : noop;
47
+ this.verbose = logLevel > 2 ? this.defaultVerbose : noop;
48
+ this.debug = logLevel > 3 ? this.defaultDebug : noop;
48
49
  }
49
50
  }
50
51
 
package/utils/utils.ts ADDED
@@ -0,0 +1,6 @@
1
+ /*
2
+ * This file contains utilities used throughout the project too small to
3
+ * deserve their own dedicated files.
4
+ */
5
+
6
+ export const noop = () => {};