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