u8-mqtt 0.6.2 → 0.6.3

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 (106) hide show
  1. package/cjs/basic-v4.cjs +194 -243
  2. package/cjs/basic-v4.cjs.map +1 -1
  3. package/cjs/basic-v5.cjs +247 -368
  4. package/cjs/basic-v5.cjs.map +1 -1
  5. package/cjs/full-v4.cjs +297 -353
  6. package/cjs/full-v4.cjs.map +1 -1
  7. package/cjs/full-v5.cjs +350 -476
  8. package/cjs/full-v5.cjs.map +1 -1
  9. package/cjs/index.cjs +247 -368
  10. package/cjs/index.cjs.map +1 -1
  11. package/cjs/v4.cjs +194 -243
  12. package/cjs/v4.cjs.map +1 -1
  13. package/cjs/v5.cjs +247 -368
  14. package/cjs/v5.cjs.map +1 -1
  15. package/esm/basic-v4.js +194 -243
  16. package/esm/basic-v4.js.map +1 -1
  17. package/esm/basic-v5.js +247 -368
  18. package/esm/basic-v5.js.map +1 -1
  19. package/esm/deno/basic-v4.js +194 -243
  20. package/esm/deno/basic-v4.js.map +1 -1
  21. package/esm/deno/basic-v5.js +247 -368
  22. package/esm/deno/basic-v5.js.map +1 -1
  23. package/esm/deno/full-v4.js +297 -353
  24. package/esm/deno/full-v4.js.map +1 -1
  25. package/esm/deno/full-v5.js +350 -476
  26. package/esm/deno/full-v5.js.map +1 -1
  27. package/esm/deno/index.js +247 -368
  28. package/esm/deno/index.js.map +1 -1
  29. package/esm/deno/v4.js +194 -243
  30. package/esm/deno/v4.js.map +1 -1
  31. package/esm/deno/v5.js +247 -368
  32. package/esm/deno/v5.js.map +1 -1
  33. package/esm/full-v4.js +297 -353
  34. package/esm/full-v4.js.map +1 -1
  35. package/esm/full-v5.js +350 -476
  36. package/esm/full-v5.js.map +1 -1
  37. package/esm/index.js +247 -368
  38. package/esm/index.js.map +1 -1
  39. package/esm/node/basic-v4.js +194 -243
  40. package/esm/node/basic-v4.js.map +1 -1
  41. package/esm/node/basic-v4.mjs +194 -243
  42. package/esm/node/basic-v4.mjs.map +1 -1
  43. package/esm/node/basic-v5.js +247 -368
  44. package/esm/node/basic-v5.js.map +1 -1
  45. package/esm/node/basic-v5.mjs +247 -368
  46. package/esm/node/basic-v5.mjs.map +1 -1
  47. package/esm/node/full-v4.js +297 -353
  48. package/esm/node/full-v4.js.map +1 -1
  49. package/esm/node/full-v4.mjs +297 -353
  50. package/esm/node/full-v4.mjs.map +1 -1
  51. package/esm/node/full-v5.js +350 -476
  52. package/esm/node/full-v5.js.map +1 -1
  53. package/esm/node/full-v5.mjs +350 -476
  54. package/esm/node/full-v5.mjs.map +1 -1
  55. package/esm/node/index.js +247 -368
  56. package/esm/node/index.js.map +1 -1
  57. package/esm/node/index.mjs +247 -368
  58. package/esm/node/index.mjs.map +1 -1
  59. package/esm/node/v4.js +194 -243
  60. package/esm/node/v4.js.map +1 -1
  61. package/esm/node/v4.mjs +194 -243
  62. package/esm/node/v4.mjs.map +1 -1
  63. package/esm/node/v5.js +247 -368
  64. package/esm/node/v5.js.map +1 -1
  65. package/esm/node/v5.mjs +247 -368
  66. package/esm/node/v5.mjs.map +1 -1
  67. package/esm/v4.js +194 -243
  68. package/esm/v4.js.map +1 -1
  69. package/esm/v5.js +247 -368
  70. package/esm/v5.js.map +1 -1
  71. package/esm/web/basic-v4.js +194 -243
  72. package/esm/web/basic-v4.js.map +1 -1
  73. package/esm/web/basic-v4.min.js +1 -1
  74. package/esm/web/basic-v4.min.js.br +0 -0
  75. package/esm/web/basic-v4.min.js.gz +0 -0
  76. package/esm/web/basic-v5.js +247 -368
  77. package/esm/web/basic-v5.js.map +1 -1
  78. package/esm/web/basic-v5.min.js +1 -1
  79. package/esm/web/basic-v5.min.js.br +0 -0
  80. package/esm/web/basic-v5.min.js.gz +0 -0
  81. package/esm/web/full-v4.js +297 -353
  82. package/esm/web/full-v4.js.map +1 -1
  83. package/esm/web/full-v4.min.js +1 -1
  84. package/esm/web/full-v4.min.js.br +0 -0
  85. package/esm/web/full-v4.min.js.gz +0 -0
  86. package/esm/web/full-v5.js +350 -476
  87. package/esm/web/full-v5.js.map +1 -1
  88. package/esm/web/full-v5.min.js +1 -1
  89. package/esm/web/full-v5.min.js.br +0 -0
  90. package/esm/web/full-v5.min.js.gz +0 -0
  91. package/esm/web/index.js +247 -368
  92. package/esm/web/index.js.map +1 -1
  93. package/esm/web/index.min.js +1 -1
  94. package/esm/web/index.min.js.br +0 -0
  95. package/esm/web/index.min.js.gz +0 -0
  96. package/esm/web/v4.js +194 -243
  97. package/esm/web/v4.js.map +1 -1
  98. package/esm/web/v4.min.js +1 -1
  99. package/esm/web/v4.min.js.br +0 -0
  100. package/esm/web/v4.min.js.gz +0 -0
  101. package/esm/web/v5.js +247 -368
  102. package/esm/web/v5.js.map +1 -1
  103. package/esm/web/v5.min.js +1 -1
  104. package/esm/web/v5.min.js.br +0 -0
  105. package/esm/web/v5.min.js.gz +0 -0
  106. package/package.json +2 -2
package/cjs/full-v4.cjs CHANGED
@@ -6,56 +6,34 @@ var node_net = require('node:net');
6
6
  var node_tls = require('node:tls');
7
7
 
8
8
  function encode_varint(n, a=[]) {
9
- do {
10
- const ni = n & 0x7f;
11
- n >>>= 7;
12
- a.push( ni | (0===n ? 0 : 0x80) );
13
- } while (n > 0)
9
+ a.push((n<0x80 ? 0 : 0x80) | (n & 0x7f));
10
+ for(; ( n>>>=7 ) > 0 ;)
11
+ a.push((n<0x80 ? 0 : 0x80) | (n & 0x7f));
14
12
  return a
15
13
  }
16
14
 
15
+ function decode_varint$1(u8, i0=0, invalid) {
16
+ let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
17
+ for(; b & 0x80;)
18
+ n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
17
19
 
18
- /*
19
- export function decode_varint_loop(u8, i=0) {
20
- let i0 = i
21
- let shift = 0, n = (u8[i] & 0x7f)
22
- while ( 0x80 & u8[i++] )
23
- n |= (u8[i] & 0x7f) << (shift += 7)
24
-
25
- return [n, i, i0]
26
- }
27
- */
28
-
29
-
30
- function decode_varint$1(u8, i=0) {
31
- let i0 = i;
32
- // unrolled for a max of 4 chains
33
- let n = (u8[i] & 0x7f) << 0;
34
- if ( 0x80 & u8[i++] ) {
35
- n |= (u8[i] & 0x7f) << 7;
36
- if ( 0x80 & u8[i++] ) {
37
- n |= (u8[i] & 0x7f) << 14;
38
- if ( 0x80 & u8[i++] ) {
39
- n |= (u8[i] & 0x7f) << 21;
40
- }
41
- }
42
- }
43
- return [n, i, i0]
20
+ return (u8.length < i)
21
+ ? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
22
+ : [n, i, i0] // successful value
44
23
  }
45
24
 
46
- class U8_Reason extends Number {
47
- static of(v, pkt_kind, by_kind) {
48
- let self = new this(v);
49
- self.reason = by_kind?.[pkt_kind]?.get(v) || pkt_kind;
50
- return self
25
+ class mqtt_reason extends Number {
26
+ constructor(v, reason) {
27
+ super(v);
28
+ this.reason = `:${(this.ok = v<0x80) ? 'ok' : 'fail'}:${reason}`;
51
29
  }
52
30
  }
53
31
 
54
32
  let mqtt_reader_v4$1 = class mqtt_reader_v4 {
55
- static of(buf) { return this.prototype.of(buf) }
56
- of(buf) {
33
+ static for(pkt, u8_body) { return new this().of(u8_body, {pkt}) }
34
+ of(buf, opt) {
57
35
  let step = (width, k) => (k=0|step.k, step.k=k+width, k);
58
- return {__proto__: this, buf, step}
36
+ return {__proto__: this, buf, step, ...opt}
59
37
  }
60
38
 
61
39
  has_more() {
@@ -98,7 +76,7 @@ let mqtt_reader_v4$1 = class mqtt_reader_v4 {
98
76
  reason(pkt_kind) {
99
77
  let v = this.buf[this.step(1)];
100
78
  if (null != v)
101
- return U8_Reason.of(v, pkt_kind, this._reasons_by)
79
+ return new mqtt_reason(v, this._reason_for?.(v, pkt_kind))
102
80
  }
103
81
 
104
82
  flush() {
@@ -109,28 +87,57 @@ let mqtt_reader_v4$1 = class mqtt_reader_v4 {
109
87
 
110
88
  };
111
89
 
112
- function mqtt_reader_info(mqtt_reader, ... info_fn_list) {
113
- mqtt_reader = class extends mqtt_reader {
114
- static reasons(pkt_type, ...reason_entries) {
115
- let proto = this.prototype;
116
- proto._reasons_by = {... proto._reasons_by};
90
+ function with_reasons(mqtt_reader, by_kind) {
91
+ for (let [k,lut] of Object.entries(by_kind))
92
+ by_kind[k] = new Map(lut);
117
93
 
118
- let lut = (proto._reasons_by[pkt_type] ||= new Map());
119
- for (let [u8, reason] of reason_entries)
120
- lut.set( u8, reason );
121
-
122
- return this
94
+ return class extends mqtt_reader {
95
+ _reason_for(v, pkt_kind) {
96
+ return by_kind[pkt_kind]?.get(v) || by_kind.all.get(v)
97
+ }
98
+ warn(msg) {
99
+ let pkt = this.pkt;
100
+ pkt.warn ? pkt.warn(msg, pkt)
101
+ : console.warn('[u8-mqtt-packet] '+msg);
123
102
  }
124
- };
103
+ }
104
+ }
125
105
 
126
- for (let fn_info of info_fn_list)
127
- fn_info(mqtt_reader);
128
106
 
129
- return mqtt_reader
130
- }
107
+ const reasons_v4 = {
108
+ connack: [
109
+ [ 0x01, 'conn refused: unacceptable protocol version'],
110
+ [ 0x02, 'conn refused: identifier rejected'],
111
+ [ 0x03, 'conn refused: server unavailable'],
112
+ [ 0x04, 'conn refused: bad user name or password'],
113
+ [ 0x05, 'conn refused: not authorized'],
114
+ ],
115
+ suback: [
116
+ [ 0x00, 'qos=0'],
117
+ [ 0x01, 'qos=1'],
118
+ [ 0x02, 'qos=2'],
119
+ ],
120
+ unsuback: [
121
+ [ 0x11, 'no subscription existed'],
122
+ ],
123
+ puback: [
124
+ [ 0x10, 'no matching subscribers'],
125
+ ],
126
+ all: [
127
+ [ 0, ''], // Success
128
+ [ 0x80, 'unspecified error'], // disconnect puback suback unsuback
129
+ [ 0x83, 'implementation specific error'], // connack disconnect puback suback unsuback
130
+ [ 0x87, 'not authorized'], // connack disconnect puback suback unsuback
131
+ [ 0x8F, 'topic filter invalid'], // disconnect suback unsuback
132
+ [ 0x91, 'packet identifier in use'], // puback suback unsuback
133
+ [ 0x92, 'packet identifier not found' ], // pubxxx
134
+ ]};
135
+
136
+ const mqtt_reader_v4 = /* #__PURE__ */
137
+ with_reasons(mqtt_reader_v4$1, reasons_v4);
131
138
 
132
139
  class mqtt_writer_v4 {
133
- static of() { return this.prototype.of() }
140
+ static for(pkt) { return new this().of() }
134
141
  of() { return {__proto__: this, $:[]} }
135
142
 
136
143
  static init() { return this }
@@ -201,234 +208,6 @@ class mqtt_writer_v4 {
201
208
  }
202
209
  }
203
210
 
204
- function mqtt_decode_connect(ns, mqtt_reader) {
205
- class _connect_flags_ extends Number {
206
- get reserved() { return this & 0x01 !== 0 }
207
- get clean_start() { return this & 0x02 !== 0 }
208
- get will_flag() { return this & 0x04 !== 0 }
209
- get will_qos() { return (this >>> 3) & 0x3 }
210
- get will_retain() { return this & 0x20 !== 0 }
211
- get password() { return this & 0x40 !== 0 }
212
- get username() { return this & 0x80 !== 0 }
213
- }
214
-
215
- return ns[0x1] = (pkt, u8_body) => {
216
- let rdr = mqtt_reader.of(u8_body);
217
- if ('MQTT' !== rdr.utf8())
218
- throw new Error('Invalid mqtt_connect packet')
219
-
220
- pkt._base_.mqtt_level = pkt.mqtt_level = rdr.u8();
221
-
222
- let flags = pkt.flags =
223
- rdr.flags(_connect_flags_);
224
-
225
- pkt.keep_alive = rdr.u16();
226
-
227
- if (5 <= pkt.mqtt_level)
228
- pkt.props = rdr.props();
229
-
230
-
231
-
232
- pkt.client_id = rdr.utf8();
233
- if (flags.will_flag) {
234
- let will = pkt.will = {};
235
- if (5 <= pkt.mqtt_level)
236
- will.props = rdr.props();
237
-
238
- will.topic = rdr.utf8();
239
- will.payload = rdr.bin();
240
- will.qos = flags.will_qos;
241
- will.retain = flags.will_retain;
242
- }
243
-
244
- if (flags.username)
245
- pkt.username = rdr.utf8();
246
-
247
- if (flags.password)
248
- pkt.password = rdr.bin();
249
- return pkt }
250
- }
251
-
252
- function mqtt_decode_connack(ns, mqtt_reader) {
253
- class _connack_flags_ extends Number {
254
- get session_present() { return this & 0x01 !== 0 }
255
- }
256
-
257
- return ns[0x2] = (pkt, u8_body) => {
258
- let rdr = mqtt_reader.of(u8_body);
259
-
260
- pkt.flags =
261
- rdr.flags(_connack_flags_);
262
-
263
- pkt.reason = rdr.reason(pkt.type);
264
- if (5 <= pkt.mqtt_level)
265
- pkt.props = rdr.props();
266
- return pkt }
267
- }
268
-
269
-
270
- function _connack_v4(mqtt_reader) {
271
- mqtt_reader.reasons('connack',
272
- // MQTT 3.1.1
273
- [ 0x00, 'Success'],
274
- [ 0x01, 'Connection refused, unacceptable protocol version'],
275
- [ 0x02, 'Connection refused, identifier rejected'],
276
- [ 0x03, 'Connection refused, server unavailable'],
277
- [ 0x04, 'Connection refused, bad user name or password'],
278
- [ 0x05, 'Connection refused, not authorized'],
279
- );
280
- }
281
-
282
- function mqtt_decode_publish(ns, mqtt_reader) {
283
- return ns[0x3] = (pkt, u8_body) => {
284
- let {hdr} = pkt;
285
- pkt.dup = Boolean(hdr & 0x8);
286
- pkt.retain = Boolean(hdr & 0x1);
287
- let qos = pkt.qos = (hdr>>1) & 0x3;
288
-
289
- let rdr = mqtt_reader.of(u8_body);
290
- pkt.topic = rdr.utf8();
291
- if (0 !== qos)
292
- pkt.pkt_id = rdr.u16();
293
-
294
- if (5 <= pkt.mqtt_level)
295
- pkt.props = rdr.props();
296
-
297
- pkt.payload = rdr.flush();
298
- return pkt }
299
- }
300
-
301
- function mqtt_decode_puback(ns, mqtt_reader) {
302
- return ns[0x4] = (pkt, u8_body) => {
303
- let rdr = mqtt_reader.of(u8_body);
304
-
305
- pkt.pkt_id = rdr.u16();
306
- if (5 <= pkt.mqtt_level) {
307
- pkt.reason = rdr.reason(pkt.type);
308
- pkt.props = rdr.props();
309
- }
310
-
311
- return pkt }
312
- }
313
-
314
- function mqtt_decode_pubxxx(ns, mqtt_reader) {
315
- return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
316
- let rdr = mqtt_reader.of(u8_body);
317
-
318
- pkt.pkt_id = rdr.u16();
319
- pkt.reason = rdr.reason('pubxxx', mqtt_reader);
320
- if (5 <= pkt.mqtt_level)
321
- pkt.props = rdr.props();
322
- return pkt }
323
- }
324
-
325
- function _pubxxx_v4(mqtt_reader) {
326
- mqtt_reader.reasons('pubxxx',
327
- // MQTT 3.1.1
328
- [ 0x00, 'Success' ],
329
- [ 0x92, 'Packet Identifier not found' ],
330
- );
331
- }
332
-
333
- function mqtt_decode_subscribe(ns, mqtt_reader) {
334
- class _subscription_options_ extends Number {
335
- get qos() { return this & 0x3 }
336
- get retain() { return this & 0x4 !== 0 }
337
- get retain_handling() { return (this >> 2) & 0x3 }
338
- }
339
-
340
- return ns[0x8] = (pkt, u8_body) => {
341
- let rdr = mqtt_reader.of(u8_body);
342
-
343
- pkt.pkt_id = rdr.u16();
344
- if (5 <= pkt.mqtt_level)
345
- pkt.props = rdr.props();
346
-
347
- let topic, opts, topic_list = pkt.topics = [];
348
- while (rdr.has_more()) {
349
- topic = rdr.utf8();
350
- opts = rdr.flags(_subscription_options_);
351
- topic_list.push({topic, opts});
352
- }
353
-
354
- return pkt }
355
- }
356
-
357
- function _mqtt_decode_suback(mqtt_reader) {
358
- return (pkt, u8_body) => {
359
- let rdr = mqtt_reader.of(u8_body);
360
-
361
- pkt.pkt_id = rdr.u16();
362
- if (5 <= pkt.mqtt_level)
363
- pkt.props = rdr.props();
364
-
365
- let answers = pkt.answers = [];
366
- while (rdr.has_more())
367
- answers.push(
368
- rdr.reason(pkt.type) );
369
-
370
- return pkt }
371
- }
372
-
373
- function mqtt_decode_suback(ns, mqtt_reader) {
374
- return ns[0x9] = _mqtt_decode_suback(mqtt_reader)
375
- }
376
-
377
- function _suback_v4(mqtt_reader) {
378
- mqtt_reader.reasons('suback',
379
- // MQTT 3.1.1
380
- [ 0x00, 'Granted QoS 0'],
381
- [ 0x01, 'Granted QoS 1'],
382
- [ 0x02, 'Granted QoS 2'],
383
- );
384
- }
385
-
386
- function mqtt_decode_unsubscribe(ns, mqtt_reader) {
387
- return ns[0xa] = (pkt, u8_body) => {
388
- let rdr = mqtt_reader.of(u8_body);
389
-
390
- pkt.pkt_id = rdr.u16();
391
- if (5 <= pkt.mqtt_level)
392
- pkt.props = rdr.props();
393
-
394
- let topic_list = pkt.topics = [];
395
- while (rdr.has_more())
396
- topic_list.push(rdr.utf8());
397
-
398
- return pkt }
399
- }
400
-
401
- function mqtt_decode_unsuback(ns, mqtt_reader) {
402
- return ns[0xb] = _mqtt_decode_suback(mqtt_reader)
403
- }
404
-
405
- function _unsuback_v4(mqtt_reader) {
406
- mqtt_reader.reasons('unsuback',
407
- // MQTT 3.1.1
408
- [ 0x00, 'Success'],
409
- [ 0x11, 'No subscription existed'],
410
- [ 0x80, 'Unspecified error'],
411
- [ 0x83, 'Implementation specific error'],
412
- [ 0x87, 'Not authorized'],
413
- [ 0x8F, 'Topic Filter invalid'],
414
- [ 0x91, 'Packet Identifier in use'],
415
- );
416
- }
417
-
418
- function mqtt_decode_pingxxx(ns) {
419
- return ns[0xc] = ns[0xd] = pkt => pkt
420
- }
421
-
422
- function mqtt_decode_disconnect(ns, mqtt_reader) {
423
- return ns[0xe] = (pkt, u8_body) => {
424
- if (u8_body && 5 <= pkt.mqtt_level) {
425
- let rdr = mqtt_reader.of(u8_body);
426
- pkt.reason = rdr.reason(pkt.type);
427
- pkt.props = rdr.props();
428
- }
429
- return pkt }
430
- }
431
-
432
211
  function mqtt_encode_connect(ns, mqtt_writer) {
433
212
  const _c_mqtt_proto = new Uint8Array([
434
213
  0, 4, 0x4d, 0x51, 0x54, 0x54 ]);
@@ -447,7 +226,7 @@ function mqtt_encode_connect(ns, mqtt_writer) {
447
226
  | ( will.retain ? 0x20 : 0 );
448
227
 
449
228
  return ns.connect = ( mqtt_level, pkt ) => {
450
- let wrt = mqtt_writer.of(pkt);
229
+ let wrt = mqtt_writer.for(pkt);
451
230
 
452
231
  wrt.push(_c_mqtt_proto);
453
232
  wrt.u8( mqtt_level );
@@ -485,12 +264,61 @@ function mqtt_encode_connect(ns, mqtt_writer) {
485
264
  }
486
265
  }
487
266
 
267
+ function mqtt_decode_connect(ns, mqtt_reader) {
268
+ class _connect_flags_ extends Number {
269
+ get reserved() { return this & 0x01 !== 0 }
270
+ get clean_start() { return this & 0x02 !== 0 }
271
+ get will_flag() { return this & 0x04 !== 0 }
272
+ get will_qos() { return (this >>> 3) & 0x3 }
273
+ get will_retain() { return this & 0x20 !== 0 }
274
+ get password() { return this & 0x40 !== 0 }
275
+ get username() { return this & 0x80 !== 0 }
276
+ }
277
+
278
+ return ns[0x1] = (pkt, u8_body) => {
279
+ let rdr = mqtt_reader.for(pkt, u8_body);
280
+ if ('MQTT' !== rdr.utf8())
281
+ throw new Error('Invalid mqtt_connect packet')
282
+
283
+ pkt.__proto__.mqtt_level =
284
+ pkt.mqtt_level = rdr.u8();
285
+
286
+ let flags = pkt.flags =
287
+ rdr.flags(_connect_flags_);
288
+
289
+ pkt.keep_alive = rdr.u16();
290
+
291
+ if (5 <= pkt.mqtt_level)
292
+ pkt.props = rdr.props();
293
+
294
+
295
+
296
+ pkt.client_id = rdr.utf8();
297
+ if (flags.will_flag) {
298
+ let will = pkt.will = {};
299
+ if (5 <= pkt.mqtt_level)
300
+ will.props = rdr.props();
301
+
302
+ will.topic = rdr.utf8();
303
+ will.payload = rdr.bin();
304
+ will.qos = flags.will_qos;
305
+ will.retain = flags.will_retain;
306
+ }
307
+
308
+ if (flags.username)
309
+ pkt.username = rdr.utf8();
310
+
311
+ if (flags.password)
312
+ pkt.password = rdr.bin();
313
+ return pkt }
314
+ }
315
+
488
316
  function mqtt_encode_connack(ns, mqtt_writer) {
489
317
  const _enc_flags_connack = flags =>
490
318
  flags.session_present ? 1 : 0;
491
319
 
492
320
  return ns.connack = (mqtt_level, pkt) => {
493
- let wrt = mqtt_writer.of(pkt);
321
+ let wrt = mqtt_writer.for(pkt);
494
322
 
495
323
  wrt.flags( pkt.flags, _enc_flags_connack );
496
324
 
@@ -506,10 +334,28 @@ function mqtt_encode_connack(ns, mqtt_writer) {
506
334
  }
507
335
  }
508
336
 
337
+
338
+ function mqtt_decode_connack(ns, mqtt_reader) {
339
+ class _connack_flags_ extends Number {
340
+ get session_present() { return this & 0x01 !== 0 }
341
+ }
342
+
343
+ return ns[0x2] = (pkt, u8_body) => {
344
+ let rdr = mqtt_reader.for(pkt, u8_body);
345
+
346
+ pkt.flags =
347
+ rdr.flags(_connack_flags_);
348
+
349
+ pkt.reason = rdr.reason(pkt.type);
350
+ if (5 <= pkt.mqtt_level)
351
+ pkt.props = rdr.props();
352
+ return pkt }
353
+ }
354
+
509
355
  function mqtt_encode_publish(ns, mqtt_writer) {
510
356
  return ns.publish = ( mqtt_level, pkt ) => {
511
357
  let qos = (pkt.qos & 0x3) << 1;
512
- let wrt = mqtt_writer.of(pkt);
358
+ let wrt = mqtt_writer.for(pkt);
513
359
 
514
360
  wrt.utf8(pkt.topic);
515
361
  if (0 !== qos)
@@ -527,9 +373,28 @@ function mqtt_encode_publish(ns, mqtt_writer) {
527
373
  }
528
374
  }
529
375
 
376
+ function mqtt_decode_publish(ns, mqtt_reader) {
377
+ return ns[0x3] = (pkt, u8_body) => {
378
+ let {hdr} = pkt;
379
+ pkt.dup = Boolean(hdr & 0x8);
380
+ pkt.retain = Boolean(hdr & 0x1);
381
+ let qos = pkt.qos = (hdr>>1) & 0x3;
382
+
383
+ let rdr = mqtt_reader.for(pkt, u8_body);
384
+ pkt.topic = rdr.utf8();
385
+ if (0 !== qos)
386
+ pkt.pkt_id = rdr.u16();
387
+
388
+ if (5 <= pkt.mqtt_level)
389
+ pkt.props = rdr.props();
390
+
391
+ pkt.payload = rdr.flush();
392
+ return pkt }
393
+ }
394
+
530
395
  function mqtt_encode_puback(ns, mqtt_writer) {
531
396
  return ns.puback = ( mqtt_level, pkt ) => {
532
- let wrt = mqtt_writer.of(pkt);
397
+ let wrt = mqtt_writer.for(pkt);
533
398
 
534
399
  wrt.u16(pkt.pkt_id);
535
400
  if (5 <= mqtt_level) {
@@ -541,6 +406,20 @@ function mqtt_encode_puback(ns, mqtt_writer) {
541
406
  }
542
407
  }
543
408
 
409
+
410
+ function mqtt_decode_puback(ns, mqtt_reader) {
411
+ return ns[0x4] = (pkt, u8_body) => {
412
+ let rdr = mqtt_reader.for(pkt, u8_body);
413
+
414
+ pkt.pkt_id = rdr.u16();
415
+ if (5 <= pkt.mqtt_level) {
416
+ pkt.reason = rdr.reason(pkt.type);
417
+ pkt.props = rdr.props();
418
+ }
419
+
420
+ return pkt }
421
+ }
422
+
544
423
  function mqtt_encode_pubxxx(ns, mqtt_writer) {
545
424
  ns.pubrec = _enc_pubxxx(0x50);
546
425
  ns.pubrel = _enc_pubxxx(0x62);
@@ -549,7 +428,7 @@ function mqtt_encode_pubxxx(ns, mqtt_writer) {
549
428
 
550
429
  function _enc_pubxxx(hdr) {
551
430
  return ( mqtt_level, pkt ) => {
552
- let wrt = mqtt_writer.of(pkt);
431
+ let wrt = mqtt_writer.for(pkt);
553
432
 
554
433
  wrt.u16(pkt.pkt_id);
555
434
  if (5 <= mqtt_level) {
@@ -565,6 +444,17 @@ function mqtt_encode_pubxxx(ns, mqtt_writer) {
565
444
  }
566
445
  }
567
446
 
447
+ function mqtt_decode_pubxxx(ns, mqtt_reader) {
448
+ return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
449
+ let rdr = mqtt_reader.for(pkt, u8_body);
450
+
451
+ pkt.pkt_id = rdr.u16();
452
+ pkt.reason = rdr.reason('pubxxx', mqtt_reader);
453
+ if (5 <= pkt.mqtt_level)
454
+ pkt.props = rdr.props();
455
+ return pkt }
456
+ }
457
+
568
458
  function mqtt_encode_subscribe(ns, mqtt_writer) {
569
459
  const _enc_subscribe_flags = opts => 0
570
460
  | ( opts.qos & 0x3 )
@@ -572,7 +462,7 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
572
462
  | ( (opts.retain_handling & 0x3) << 2 );
573
463
 
574
464
  return ns.subscribe = ( mqtt_level, pkt ) => {
575
- let wrt = mqtt_writer.of(pkt);
465
+ let wrt = mqtt_writer.for(pkt);
576
466
 
577
467
  wrt.u16(pkt.pkt_id);
578
468
  if (5 <= mqtt_level)
@@ -598,6 +488,30 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
598
488
  }
599
489
  }
600
490
 
491
+ function mqtt_decode_subscribe(ns, mqtt_reader) {
492
+ class _subscription_options_ extends Number {
493
+ get qos() { return this & 0x3 }
494
+ get retain() { return this & 0x4 !== 0 }
495
+ get retain_handling() { return (this >> 2) & 0x3 }
496
+ }
497
+
498
+ return ns[0x8] = (pkt, u8_body) => {
499
+ let rdr = mqtt_reader.for(pkt, u8_body);
500
+
501
+ pkt.pkt_id = rdr.u16();
502
+ if (5 <= pkt.mqtt_level)
503
+ pkt.props = rdr.props();
504
+
505
+ let topic, opts, topic_list = pkt.topics = [];
506
+ while (rdr.has_more()) {
507
+ topic = rdr.utf8();
508
+ opts = rdr.flags(_subscription_options_);
509
+ topic_list.push({topic, opts});
510
+ }
511
+
512
+ return pkt }
513
+ }
514
+
601
515
  function mqtt_encode_xxsuback(ns, mqtt_writer) {
602
516
  ns.suback = _enc_xxsuback(0x90);
603
517
  ns.unsuback = _enc_xxsuback(0xb0);
@@ -605,7 +519,7 @@ function mqtt_encode_xxsuback(ns, mqtt_writer) {
605
519
 
606
520
  function _enc_xxsuback(hdr) {
607
521
  return ( mqtt_level, pkt ) => {
608
- let wrt = mqtt_writer.of(pkt);
522
+ let wrt = mqtt_writer.for(pkt);
609
523
 
610
524
  wrt.u16(pkt.pkt_id);
611
525
  if (5 <= mqtt_level)
@@ -619,9 +533,26 @@ function mqtt_encode_xxsuback(ns, mqtt_writer) {
619
533
  }
620
534
  }
621
535
 
536
+
537
+ function mqtt_decode_xxsuback(ns, mqtt_reader) {
538
+ return ns[0x9] = ns[0xb] = (pkt, u8_body) => {
539
+ let rdr = mqtt_reader.for(pkt, u8_body);
540
+
541
+ pkt.pkt_id = rdr.u16();
542
+ if (5 <= pkt.mqtt_level)
543
+ pkt.props = rdr.props();
544
+
545
+ let answers = pkt.answers = [];
546
+ while (rdr.has_more())
547
+ answers.push(
548
+ rdr.reason(pkt.type) );
549
+
550
+ return pkt }
551
+ }
552
+
622
553
  function mqtt_encode_unsubscribe(ns, mqtt_writer) {
623
554
  return ns.unsubscribe = ( mqtt_level, pkt ) => {
624
- let wrt = mqtt_writer.of(pkt);
555
+ let wrt = mqtt_writer.for(pkt);
625
556
 
626
557
  wrt.u16(pkt.pkt_id);
627
558
  if (5 <= mqtt_level)
@@ -634,14 +565,34 @@ function mqtt_encode_unsubscribe(ns, mqtt_writer) {
634
565
  }
635
566
  }
636
567
 
568
+ function mqtt_decode_unsubscribe(ns, mqtt_reader) {
569
+ return ns[0xa] = (pkt, u8_body) => {
570
+ let rdr = mqtt_reader.for(pkt, u8_body);
571
+
572
+ pkt.pkt_id = rdr.u16();
573
+ if (5 <= pkt.mqtt_level)
574
+ pkt.props = rdr.props();
575
+
576
+ let topic_list = pkt.topics = [];
577
+ while (rdr.has_more())
578
+ topic_list.push(rdr.utf8());
579
+
580
+ return pkt }
581
+ }
582
+
637
583
  function mqtt_encode_pingxxx(ns) {
638
584
  ns.pingreq = () => new Uint8Array([ 0xc0, 0 ]);
639
585
  ns.pingresp = () => new Uint8Array([ 0xd0, 0 ]);
640
586
  }
641
587
 
588
+
589
+ function mqtt_decode_pingxxx(ns) {
590
+ return ns[0xc] = ns[0xd] = pkt => pkt
591
+ }
592
+
642
593
  function mqtt_encode_disconnect(ns, mqtt_writer) {
643
594
  return ns.disconnect = ( mqtt_level, pkt ) => {
644
- let wrt = mqtt_writer.of(pkt);
595
+ let wrt = mqtt_writer.for(pkt);
645
596
 
646
597
  if (pkt && 5 <= mqtt_level) {
647
598
  if (pkt.reason || pkt.props) {
@@ -654,17 +605,19 @@ function mqtt_encode_disconnect(ns, mqtt_writer) {
654
605
  }
655
606
  }
656
607
 
657
- // not a v4 packet: import { mqtt_encode_auth } from './encode/auth.js'
658
608
 
609
+ function mqtt_decode_disconnect(ns, mqtt_reader) {
610
+ return ns[0xe] = (pkt, u8_body) => {
611
+ if (u8_body && 5 <= pkt.mqtt_level) {
612
+ let rdr = mqtt_reader.for(pkt, u8_body);
613
+ pkt.reason = rdr.reason(pkt.type);
614
+ pkt.props = rdr.props();
615
+ }
616
+ return pkt }
617
+ }
618
+
619
+ // not a v4 packet: import { mqtt_encode_auth, mqtt_decode_auth } from './pkt/auth.js'
659
620
 
660
- const mqtt_reader_v4 = /* #__PURE__ */
661
- mqtt_reader_info(
662
- mqtt_reader_v4$1,
663
- _connack_v4,
664
- _pubxxx_v4,
665
- _suback_v4,
666
- _unsuback_v4,
667
- );
668
621
 
669
622
  const mqtt_decode_v4 = [
670
623
  mqtt_decode_connect,
@@ -673,9 +626,8 @@ const mqtt_decode_v4 = [
673
626
  mqtt_decode_puback,
674
627
  mqtt_decode_pubxxx,
675
628
  mqtt_decode_subscribe,
676
- mqtt_decode_suback,
629
+ mqtt_decode_xxsuback,
677
630
  mqtt_decode_unsubscribe,
678
- mqtt_decode_unsuback,
679
631
  mqtt_decode_pingxxx,
680
632
  mqtt_decode_disconnect,
681
633
  ];
@@ -899,47 +851,38 @@ function _route_remove(all_route_lists, query) {
899
851
  return true} }
900
852
  return false}
901
853
 
902
- /*
903
- export function decode_varint_loop(u8, i=0) {
904
- let i0 = i
905
- let shift = 0, n = (u8[i] & 0x7f)
906
- while ( 0x80 & u8[i++] )
907
- n |= (u8[i] & 0x7f) << (shift += 7)
854
+ function decode_varint(u8, i0=0, invalid) {
855
+ let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
856
+ for(; b & 0x80;)
857
+ n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
908
858
 
909
- return [n, i, i0]
910
- }
911
- */
912
-
913
-
914
- function decode_varint(u8, i=0) {
915
- let i0 = i;
916
- // unrolled for a max of 4 chains
917
- let n = (u8[i] & 0x7f) << 0;
918
- if ( 0x80 & u8[i++] ) {
919
- n |= (u8[i] & 0x7f) << 7;
920
- if ( 0x80 & u8[i++] ) {
921
- n |= (u8[i] & 0x7f) << 14;
922
- if ( 0x80 & u8[i++] ) {
923
- n |= (u8[i] & 0x7f) << 21;
924
- }
925
- }
926
- }
927
- return [n, i, i0]
859
+ return (u8.length < i)
860
+ ? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
861
+ : [n, i, i0] // successful value
928
862
  }
929
863
 
930
864
  function mqtt_raw_dispatch(opt) {
931
- let u8 = new Uint8Array(0);
865
+ let u8 = new Uint8Array(0), len_tip=0;
932
866
  return u8_buf => {
933
867
  u8 = 0 === u8.byteLength
934
868
  ? u8_buf : _u8_join(u8, u8_buf);
935
869
 
936
870
  let res = [];
937
- while (1) {
938
- let [len_body, len_vh] = decode_varint(u8, 1);
939
- let len_pkt = len_body + len_vh;
940
871
 
941
- if ( u8.byteLength < len_pkt )
942
- return res
872
+ // wait for at least len_tip bytes for next (tip) message
873
+ while ( u8.byteLength >= len_tip ) {
874
+
875
+ // if varint is incomplete, return len_body=NaN
876
+ let [len_body, len_vh] = decode_varint(u8, 1, NaN);
877
+ let len_pkt = len_body + len_vh; // may be NaN
878
+
879
+ if (!( len_pkt <= u8.byteLength )) {
880
+ // incomplete packet cases:
881
+ // - len_pkt is less than available bytes
882
+ // - len_pkt is NaN from decode_varint() due to lack of data
883
+ len_tip = len_pkt || 0; // 0 when NaN
884
+ break
885
+ }
943
886
 
944
887
  let b0 = u8[0];
945
888
  let u8_body = 0 === len_body ? null
@@ -951,6 +894,8 @@ function mqtt_raw_dispatch(opt) {
951
894
  if (null != pkt)
952
895
  res.push( pkt );
953
896
  }
897
+
898
+ return res
954
899
  }
955
900
  }
956
901
 
@@ -961,16 +906,17 @@ function _u8_join(a, b) {
961
906
  return r
962
907
  }
963
908
 
964
- const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
909
+ const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
910
+
911
+
912
+ function mqtt_pkt_ctx(mqtt_level, opts, pkt_api=opts.pkt_ctx) {
913
+ let _as_pkt_ctx = pkt_api => ({
914
+ __proto__: pkt_api,
915
+ get hdr() { return this.b0 & 0xf },
916
+ get id() { return this.b0 >>> 4 },
917
+ get type() { return _pkt_types[this.b0 >>> 4] },
918
+ mqtt_level });
965
919
 
966
- function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
967
- pkt_ctx = {
968
- __proto__: pkt_ctx || opts.pkt_ctx,
969
- mqtt_level,
970
- get hdr() { return this.b0 & 0xf },
971
- get id() { return this.b0 >>> 4 },
972
- get type() { return _pkt_types[this.b0 >>> 4] },
973
- };
974
920
 
975
921
  let op, _decode_by_id=[], _encode_by_type={};
976
922
  for (op of opts.encode_fns)
@@ -979,10 +925,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
979
925
  op(_decode_by_id, opts.mqtt_reader);
980
926
 
981
927
  return {
982
- pkt_ctx,
928
+ pkt_api, pkt_ctx: _as_pkt_ctx(pkt_api),
983
929
 
984
- encode_pkt(type, pkt) {
985
- return _encode_by_type[type]( mqtt_level, pkt ) },
930
+ encode_pkt: (type, pkt) =>
931
+ _encode_by_type[type]( mqtt_level, pkt ),
986
932
 
987
933
  decode_pkt(b0, u8_body) {
988
934
  if (b0.map) // Uint8Array in first arg
@@ -991,12 +937,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
991
937
  let fn_decode = _decode_by_id[b0>>>4] || _decode_by_id[0];
992
938
  return fn_decode?.({__proto__: this.pkt_ctx, b0}, u8_body) },
993
939
 
994
- mqtt_stream() {
995
- let self = { __proto__: this, pkt_ctx: { __proto__: pkt_ctx } };
996
- self.pkt_ctx._base_ = self.pkt_ctx;
940
+ mqtt_stream(pkt_api=this.pkt_api) {
941
+ let self = { __proto__: this, pkt_ctx: _as_pkt_ctx(pkt_api) };
997
942
  self.decode = mqtt_raw_dispatch(self);
998
- return self
999
- },
943
+ return self },
1000
944
  }
1001
945
  }
1002
946
 
@@ -1520,7 +1464,7 @@ class MQTTCore extends MQTTBase {
1520
1464
 
1521
1465
  return this} }
1522
1466
 
1523
- const version = '0.6.2-node';
1467
+ const version = '0.6.3-node';
1524
1468
 
1525
1469
  const MQTTClient_v4 = /* #__PURE__ */
1526
1470
  with_topic_path_router(