u8-mqtt 0.6.1 → 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 +264 -385
  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 +366 -492
  8. package/cjs/full-v5.cjs.map +1 -1
  9. package/cjs/index.cjs +263 -384
  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 +263 -384
  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 +264 -385
  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 +264 -385
  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 +366 -492
  26. package/esm/deno/full-v5.js.map +1 -1
  27. package/esm/deno/index.js +263 -384
  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 +263 -384
  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 +366 -492
  36. package/esm/full-v5.js.map +1 -1
  37. package/esm/index.js +263 -384
  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 +264 -385
  44. package/esm/node/basic-v5.js.map +1 -1
  45. package/esm/node/basic-v5.mjs +264 -385
  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 +366 -492
  52. package/esm/node/full-v5.js.map +1 -1
  53. package/esm/node/full-v5.mjs +366 -492
  54. package/esm/node/full-v5.mjs.map +1 -1
  55. package/esm/node/index.js +263 -384
  56. package/esm/node/index.js.map +1 -1
  57. package/esm/node/index.mjs +263 -384
  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 +263 -384
  64. package/esm/node/v5.js.map +1 -1
  65. package/esm/node/v5.mjs +263 -384
  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 +263 -384
  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 +264 -385
  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 +366 -492
  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 +263 -384
  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 +263 -384
  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/esm/full-v5.js CHANGED
@@ -1,48 +1,31 @@
1
1
  function encode_varint(n, a=[]) {
2
- do {
3
- const ni = n & 0x7f;
4
- n >>>= 7;
5
- a.push( ni | (0===n ? 0 : 0x80) );
6
- } while (n > 0)
2
+ a.push((n<0x80 ? 0 : 0x80) | (n & 0x7f));
3
+ for(; ( n>>>=7 ) > 0 ;)
4
+ a.push((n<0x80 ? 0 : 0x80) | (n & 0x7f));
7
5
  return a
8
6
  }
9
7
 
8
+ function decode_varint$1(u8, i0=0, invalid) {
9
+ let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
10
+ for(; b & 0x80;)
11
+ n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
10
12
 
11
- /*
12
- export function decode_varint_loop(u8, i=0) {
13
- let i0 = i
14
- let shift = 0, n = (u8[i] & 0x7f)
15
- while ( 0x80 & u8[i++] )
16
- n |= (u8[i] & 0x7f) << (shift += 7)
17
-
18
- return [n, i, i0]
13
+ return (u8.length < i)
14
+ ? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
15
+ : [n, i, i0] // successful value
19
16
  }
20
- */
21
-
22
17
 
23
- function decode_varint$1(u8, i=0) {
24
- let i0 = i;
25
- // unrolled for a max of 4 chains
26
- let n = (u8[i] & 0x7f) << 0;
27
- if ( 0x80 & u8[i++] ) {
28
- n |= (u8[i] & 0x7f) << 7;
29
- if ( 0x80 & u8[i++] ) {
30
- n |= (u8[i] & 0x7f) << 14;
31
- if ( 0x80 & u8[i++] ) {
32
- n |= (u8[i] & 0x7f) << 21;
33
- }
34
- }
18
+ function add_mqtt_props(mqtt_props, entries) {
19
+ for (let [id, type, name, obj] of entries) {
20
+ obj = {id, type, name, ...obj};
21
+ mqtt_props.set(id, obj).set(name, obj);
35
22
  }
36
- return [n, i, i0]
23
+ return mqtt_props
37
24
  }
38
25
 
39
- const mqtt_props = /* #__PURE__ */
40
- init_mqtt_props();
41
26
 
42
- function init_mqtt_props() {
43
- let mqtt_props = new Map();
44
-
45
- let entries = [
27
+ const init_mqtt_props = () =>
28
+ add_mqtt_props(new Map(), [
46
29
  [ 0x01, 'u8', 'payload_format_indicator'],
47
30
  [ 0x02, 'u32', 'message_expiry_interval'],
48
31
  [ 0x03, 'utf8', 'content_type'],
@@ -70,30 +53,24 @@ function init_mqtt_props() {
70
53
  [ 0x28, 'u8', 'wildcard_subscription_available'],
71
54
  [ 0x29, 'u8', 'subscription_identifiers_available', {op: 'u8_vec'}],
72
55
  [ 0x2A, 'u8', 'shared_subscription_available'],
73
- ];
56
+ ]);
74
57
 
75
- for (let [id, type, name, extra] of entries) {
76
- let prop_obj = {id, type, name, ...extra};
77
- mqtt_props.set(prop_obj.id, prop_obj);
78
- mqtt_props.set(prop_obj.name, prop_obj);
79
- }
80
58
 
81
- return mqtt_props
82
- }
59
+ const mqtt_props = /* #__PURE__ */
60
+ init_mqtt_props();
83
61
 
84
- class U8_Reason extends Number {
85
- static of(v, pkt_kind, by_kind) {
86
- let self = new this(v);
87
- self.reason = by_kind?.[pkt_kind]?.get(v) || pkt_kind;
88
- return self
62
+ class mqtt_reason extends Number {
63
+ constructor(v, reason) {
64
+ super(v);
65
+ this.reason = `:${(this.ok = v<0x80) ? 'ok' : 'fail'}:${reason}`;
89
66
  }
90
67
  }
91
68
 
92
69
  class mqtt_reader_v4 {
93
- static of(buf) { return this.prototype.of(buf) }
94
- of(buf) {
70
+ static for(pkt, u8_body) { return new this().of(u8_body, {pkt}) }
71
+ of(buf, opt) {
95
72
  let step = (width, k) => (k=0|step.k, step.k=k+width, k);
96
- return {__proto__: this, buf, step}
73
+ return {__proto__: this, buf, step, ...opt}
97
74
  }
98
75
 
99
76
  has_more() {
@@ -136,7 +113,7 @@ class mqtt_reader_v4 {
136
113
  reason(pkt_kind) {
137
114
  let v = this.buf[this.step(1)];
138
115
  if (null != v)
139
- return U8_Reason.of(v, pkt_kind, this._reasons_by)
116
+ return new mqtt_reason(v, this._reason_for?.(v, pkt_kind))
140
117
  }
141
118
 
142
119
  flush() {
@@ -150,24 +127,22 @@ class mqtt_reader_v4 {
150
127
  let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
151
128
  props() {
152
129
  let {buf, step} = this;
153
- let [n, vi, vi0] = decode_varint$1(buf, step.k|0);
130
+ let [n, vi, vi0] = decode_varint$1(buf, step.k|0, 0);
154
131
  step(n + vi - vi0);
155
132
  if (0 === n) return null
156
133
 
157
134
  let res={}, fork = this.of(buf.subarray(vi, step.k|0));
158
135
  while (fork.has_more()) {
159
136
  let v, pk = fork.u8(), pt = mqtt_props.get( pk );
160
-
161
137
  if (!pt) {
162
- res.error = `Unknown mqtt_prop enum ${pk}`;
163
- return res
138
+ res._unknown_ = pk;
139
+ this.warn?.(`unknown property: ${pk}`);
140
+ break
164
141
  }
165
142
 
166
143
  v = fork[pt.type]();
167
- if (pt.op) // accumulate operation
168
- v = fork[pt.op](res[pt.name], v);
169
-
170
- res[pt.name] = v;
144
+ res[pt.name] = !pt.op ? v
145
+ : fork[pt.op](res[pt.name], v); // accumulate operation
171
146
  }
172
147
  return res
173
148
  }
@@ -192,28 +167,99 @@ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
192
167
  */
193
168
  };
194
169
 
195
- function mqtt_reader_info(mqtt_reader, ... info_fn_list) {
196
- mqtt_reader = class extends mqtt_reader {
197
- static reasons(pkt_type, ...reason_entries) {
198
- let proto = this.prototype;
199
- proto._reasons_by = {... proto._reasons_by};
170
+ function with_reasons(mqtt_reader, by_kind) {
171
+ for (let [k,lut] of Object.entries(by_kind))
172
+ by_kind[k] = new Map(lut);
200
173
 
201
- let lut = (proto._reasons_by[pkt_type] ||= new Map());
202
- for (let [u8, reason] of reason_entries)
203
- lut.set( u8, reason );
204
-
205
- return this
174
+ return class extends mqtt_reader {
175
+ _reason_for(v, pkt_kind) {
176
+ return by_kind[pkt_kind]?.get(v) || by_kind.all.get(v)
177
+ }
178
+ warn(msg) {
179
+ let pkt = this.pkt;
180
+ pkt.warn ? pkt.warn(msg, pkt)
181
+ : console.warn('[u8-mqtt-packet] '+msg);
206
182
  }
207
- };
183
+ }
184
+ }
208
185
 
209
- for (let fn_info of info_fn_list)
210
- fn_info(mqtt_reader);
211
186
 
212
- return mqtt_reader
213
- }
187
+ const reasons_v4 = {
188
+ connack: [
189
+ [ 0x01, 'conn refused: unacceptable protocol version'],
190
+ [ 0x02, 'conn refused: identifier rejected'],
191
+ [ 0x03, 'conn refused: server unavailable'],
192
+ [ 0x04, 'conn refused: bad user name or password'],
193
+ [ 0x05, 'conn refused: not authorized'],
194
+ ],
195
+ suback: [
196
+ [ 0x00, 'qos=0'],
197
+ [ 0x01, 'qos=1'],
198
+ [ 0x02, 'qos=2'],
199
+ ],
200
+ unsuback: [
201
+ [ 0x11, 'no subscription existed'],
202
+ ],
203
+ puback: [
204
+ [ 0x10, 'no matching subscribers'],
205
+ ],
206
+ all: [
207
+ [ 0, ''], // Success
208
+ [ 0x80, 'unspecified error'], // disconnect puback suback unsuback
209
+ [ 0x83, 'implementation specific error'], // connack disconnect puback suback unsuback
210
+ [ 0x87, 'not authorized'], // connack disconnect puback suback unsuback
211
+ [ 0x8F, 'topic filter invalid'], // disconnect suback unsuback
212
+ [ 0x91, 'packet identifier in use'], // puback suback unsuback
213
+ [ 0x92, 'packet identifier not found' ], // pubxxx
214
+ ]};
215
+
216
+ const reasons_v5 = {
217
+ ... reasons_v4,
218
+ auth: [
219
+ [ 0x18, 'continue authentication' ],
220
+ [ 0x19, 're-authenticate' ],
221
+ ],
222
+ disconnect: [
223
+ [ 0x04, 'disconnect with will message'],
224
+ ],
225
+ all: [
226
+ ... reasons_v4.all,
227
+ [ 0x81, 'malformed packet'], // connack disconnect
228
+ [ 0x82, 'protocol error'], // connack disconnect
229
+ [ 0x84, 'unsupported protocol version'], // connack
230
+ [ 0x85, 'client identifier not valid'], // connack
231
+ [ 0x86, 'bad user name or password'], // connack
232
+ [ 0x88, 'server unavailable'], // connack
233
+ [ 0x89, 'server busy'], // connack disconnect
234
+ [ 0x8A, 'banned'], // connack
235
+ [ 0x8B, 'server shutting down'], // disconnect
236
+ [ 0x8C, 'bad authentication method'], // connack
237
+ [ 0x8D, 'keep alive timeout'], // disconnect
238
+ [ 0x8E, 'session taken over'], // disconnect
239
+ [ 0x90, 'topic name invalid'], // connack disconnect puback
240
+ [ 0x93, 'receive maximum exceeded'], // disconnect
241
+ [ 0x94, 'topic alias invalid'], // disconnect
242
+ [ 0x95, 'packet too large'], // connack disconnect
243
+ [ 0x96, 'message rate too high'], // disconnect
244
+ [ 0x97, 'quota exceeded'], // connack disconnect puback suback
245
+ [ 0x98, 'administrative action'], // disconnect
246
+ [ 0x99, 'payload format invalid'], // connack disconnect puback
247
+ [ 0x9A, 'retain not supported'], // connack disconnect
248
+ [ 0x9B, 'qoS not supported'], // connack disconnect
249
+ [ 0x9C, 'use another server'], // connack disconnect
250
+ [ 0x9D, 'server moved'], // connack disconnect
251
+ [ 0x9E, 'shared subscriptions not supported'], // disconnect suback
252
+ [ 0x9F, 'connection rate exceeded'], // connack disconnect
253
+ [ 0xA0, 'maximum connect time'], // disconnect
254
+ [ 0xA1, 'subscription identifiers not supported'], // disconnect suback
255
+ [ 0xA2, 'wildcard subscriptions not supported'], // disconnect suback
256
+ ]};
257
+
258
+ const mqtt_reader_v5 = /* #__PURE__ */
259
+ with_reasons(mqtt_reader_v5$1, reasons_v5);
214
260
 
215
261
  class mqtt_writer_v4 {
216
- static of() { return this.prototype.of() }
262
+ static for(pkt) { return new this().of() }
217
263
  of() { return {__proto__: this, $:[]} }
218
264
 
219
265
  static init() { return this }
@@ -302,7 +348,8 @@ class mqtt_writer_v5 extends mqtt_writer_v4 {
302
348
  for (let [name, value] of props) {
303
349
  let pt = mqtt_props.get(name);
304
350
  if (!pt)
305
- throw new Error(`Unknown mqtt_prop "${name}"`)
351
+ throw new Error(`MQTT unknown property "${name}"`)
352
+
306
353
  fork[pt.op || 'one'](value, pt);
307
354
  }
308
355
  this.push(fork.pack());
@@ -326,351 +373,6 @@ class mqtt_writer_v5 extends mqtt_writer_v4 {
326
373
  }
327
374
  }
328
375
 
329
- function mqtt_decode_connect(ns, mqtt_reader) {
330
- class _connect_flags_ extends Number {
331
- get reserved() { return this & 0x01 !== 0 }
332
- get clean_start() { return this & 0x02 !== 0 }
333
- get will_flag() { return this & 0x04 !== 0 }
334
- get will_qos() { return (this >>> 3) & 0x3 }
335
- get will_retain() { return this & 0x20 !== 0 }
336
- get password() { return this & 0x40 !== 0 }
337
- get username() { return this & 0x80 !== 0 }
338
- }
339
-
340
- return ns[0x1] = (pkt, u8_body) => {
341
- let rdr = mqtt_reader.of(u8_body);
342
- if ('MQTT' !== rdr.utf8())
343
- throw new Error('Invalid mqtt_connect packet')
344
-
345
- pkt._base_.mqtt_level = pkt.mqtt_level = rdr.u8();
346
-
347
- let flags = pkt.flags =
348
- rdr.flags(_connect_flags_);
349
-
350
- pkt.keep_alive = rdr.u16();
351
-
352
- if (5 <= pkt.mqtt_level)
353
- pkt.props = rdr.props();
354
-
355
-
356
-
357
- pkt.client_id = rdr.utf8();
358
- if (flags.will_flag) {
359
- let will = pkt.will = {};
360
- if (5 <= pkt.mqtt_level)
361
- will.props = rdr.props();
362
-
363
- will.topic = rdr.utf8();
364
- will.payload = rdr.bin();
365
- will.qos = flags.will_qos;
366
- will.retain = flags.will_retain;
367
- }
368
-
369
- if (flags.username)
370
- pkt.username = rdr.utf8();
371
-
372
- if (flags.password)
373
- pkt.password = rdr.bin();
374
- return pkt }
375
- }
376
-
377
- function mqtt_decode_connack(ns, mqtt_reader) {
378
- class _connack_flags_ extends Number {
379
- get session_present() { return this & 0x01 !== 0 }
380
- }
381
-
382
- return ns[0x2] = (pkt, u8_body) => {
383
- let rdr = mqtt_reader.of(u8_body);
384
-
385
- pkt.flags =
386
- rdr.flags(_connack_flags_);
387
-
388
- pkt.reason = rdr.reason(pkt.type);
389
- if (5 <= pkt.mqtt_level)
390
- pkt.props = rdr.props();
391
- return pkt }
392
- }
393
-
394
-
395
- function _connack_v4(mqtt_reader) {
396
- mqtt_reader.reasons('connack',
397
- // MQTT 3.1.1
398
- [ 0x00, 'Success'],
399
- [ 0x01, 'Connection refused, unacceptable protocol version'],
400
- [ 0x02, 'Connection refused, identifier rejected'],
401
- [ 0x03, 'Connection refused, server unavailable'],
402
- [ 0x04, 'Connection refused, bad user name or password'],
403
- [ 0x05, 'Connection refused, not authorized'],
404
- );
405
- }
406
-
407
- function _connack_v5(mqtt_reader) {
408
- _connack_v4(mqtt_reader);
409
-
410
- mqtt_reader.reasons('connack',
411
- // MQTT 5.0
412
- [ 0x81, 'Malformed Packet'],
413
- [ 0x82, 'Protocol Error'],
414
- [ 0x83, 'Implementation specific error'],
415
- [ 0x84, 'Unsupported Protocol Version'],
416
- [ 0x85, 'Client Identifier not valid'],
417
- [ 0x86, 'Bad User Name or Password'],
418
- [ 0x87, 'Not authorized'],
419
- [ 0x88, 'Server unavailable'],
420
- [ 0x89, 'Server busy'],
421
- [ 0x8A, 'Banned'],
422
- [ 0x8C, 'Bad authentication method'],
423
- [ 0x90, 'Topic Name invalid'],
424
- [ 0x95, 'Packet too large'],
425
- [ 0x97, 'Quota exceeded'],
426
- [ 0x99, 'Payload format invalid'],
427
- [ 0x9A, 'Retain not supported'],
428
- [ 0x9B, 'QoS not supported'],
429
- [ 0x9C, 'Use another server'],
430
- [ 0x9D, 'Server moved'],
431
- [ 0x9F, 'Connection rate exceeded'],
432
- );
433
- }
434
-
435
- function mqtt_decode_publish(ns, mqtt_reader) {
436
- return ns[0x3] = (pkt, u8_body) => {
437
- let {hdr} = pkt;
438
- pkt.dup = Boolean(hdr & 0x8);
439
- pkt.retain = Boolean(hdr & 0x1);
440
- let qos = pkt.qos = (hdr>>1) & 0x3;
441
-
442
- let rdr = mqtt_reader.of(u8_body);
443
- pkt.topic = rdr.utf8();
444
- if (0 !== qos)
445
- pkt.pkt_id = rdr.u16();
446
-
447
- if (5 <= pkt.mqtt_level)
448
- pkt.props = rdr.props();
449
-
450
- pkt.payload = rdr.flush();
451
- return pkt }
452
- }
453
-
454
- function mqtt_decode_puback(ns, mqtt_reader) {
455
- return ns[0x4] = (pkt, u8_body) => {
456
- let rdr = mqtt_reader.of(u8_body);
457
-
458
- pkt.pkt_id = rdr.u16();
459
- if (5 <= pkt.mqtt_level) {
460
- pkt.reason = rdr.reason(pkt.type);
461
- pkt.props = rdr.props();
462
- }
463
-
464
- return pkt }
465
- }
466
-
467
-
468
- function _puback_v5(mqtt_reader) {
469
- mqtt_reader.reasons('puback',
470
- // MQTT 5.0
471
- [ 0x00, 'Success'],
472
- [ 0x10, 'No matching subscribers'],
473
- [ 0x80, 'Unspecified error'],
474
- [ 0x83, 'Implementation specific error'],
475
- [ 0x87, 'Not authorized'],
476
- [ 0x90, 'Topic Name invalid'],
477
- [ 0x91, 'Packet identifier in use'],
478
- [ 0x97, 'Quota exceeded'],
479
- [ 0x99, 'Payload format invalid'],
480
- );
481
- }
482
-
483
- function mqtt_decode_pubxxx(ns, mqtt_reader) {
484
- return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
485
- let rdr = mqtt_reader.of(u8_body);
486
-
487
- pkt.pkt_id = rdr.u16();
488
- pkt.reason = rdr.reason('pubxxx', mqtt_reader);
489
- if (5 <= pkt.mqtt_level)
490
- pkt.props = rdr.props();
491
- return pkt }
492
- }
493
-
494
- function _pubxxx_v4(mqtt_reader) {
495
- mqtt_reader.reasons('pubxxx',
496
- // MQTT 3.1.1
497
- [ 0x00, 'Success' ],
498
- [ 0x92, 'Packet Identifier not found' ],
499
- );
500
- }
501
-
502
- function mqtt_decode_subscribe(ns, mqtt_reader) {
503
- class _subscription_options_ extends Number {
504
- get qos() { return this & 0x3 }
505
- get retain() { return this & 0x4 !== 0 }
506
- get retain_handling() { return (this >> 2) & 0x3 }
507
- }
508
-
509
- return ns[0x8] = (pkt, u8_body) => {
510
- let rdr = mqtt_reader.of(u8_body);
511
-
512
- pkt.pkt_id = rdr.u16();
513
- if (5 <= pkt.mqtt_level)
514
- pkt.props = rdr.props();
515
-
516
- let topic, opts, topic_list = pkt.topics = [];
517
- while (rdr.has_more()) {
518
- topic = rdr.utf8();
519
- opts = rdr.flags(_subscription_options_);
520
- topic_list.push({topic, opts});
521
- }
522
-
523
- return pkt }
524
- }
525
-
526
- function _mqtt_decode_suback(mqtt_reader) {
527
- return (pkt, u8_body) => {
528
- let rdr = mqtt_reader.of(u8_body);
529
-
530
- pkt.pkt_id = rdr.u16();
531
- if (5 <= pkt.mqtt_level)
532
- pkt.props = rdr.props();
533
-
534
- let answers = pkt.answers = [];
535
- while (rdr.has_more())
536
- answers.push(
537
- rdr.reason(pkt.type) );
538
-
539
- return pkt }
540
- }
541
-
542
- function mqtt_decode_suback(ns, mqtt_reader) {
543
- return ns[0x9] = _mqtt_decode_suback(mqtt_reader)
544
- }
545
-
546
- function _suback_v4(mqtt_reader) {
547
- mqtt_reader.reasons('suback',
548
- // MQTT 3.1.1
549
- [ 0x00, 'Granted QoS 0'],
550
- [ 0x01, 'Granted QoS 1'],
551
- [ 0x02, 'Granted QoS 2'],
552
- );
553
- }
554
-
555
- function _suback_v5(mqtt_reader) {
556
- _suback_v4(mqtt_reader);
557
-
558
- mqtt_reader.reasons('suback',
559
- // MQTT 5.0
560
- [ 0x80, 'Unspecified error'],
561
- [ 0x83, 'Implementation specific error'],
562
- [ 0x87, 'Not authorized'],
563
- [ 0x8F, 'Topic Filter invalid'],
564
- [ 0x91, 'Packet Identifier in use'],
565
- [ 0x97, 'Quota exceeded'],
566
- [ 0x9E, 'Shared Subscriptions not supported'],
567
- [ 0xA1, 'Subscription Identifiers not supported'],
568
- [ 0xA2, 'Wildcard Subscriptions not supported'],
569
- );
570
- }
571
-
572
- function mqtt_decode_unsubscribe(ns, mqtt_reader) {
573
- return ns[0xa] = (pkt, u8_body) => {
574
- let rdr = mqtt_reader.of(u8_body);
575
-
576
- pkt.pkt_id = rdr.u16();
577
- if (5 <= pkt.mqtt_level)
578
- pkt.props = rdr.props();
579
-
580
- let topic_list = pkt.topics = [];
581
- while (rdr.has_more())
582
- topic_list.push(rdr.utf8());
583
-
584
- return pkt }
585
- }
586
-
587
- function mqtt_decode_unsuback(ns, mqtt_reader) {
588
- return ns[0xb] = _mqtt_decode_suback(mqtt_reader)
589
- }
590
-
591
- function _unsuback_v4(mqtt_reader) {
592
- mqtt_reader.reasons('unsuback',
593
- // MQTT 3.1.1
594
- [ 0x00, 'Success'],
595
- [ 0x11, 'No subscription existed'],
596
- [ 0x80, 'Unspecified error'],
597
- [ 0x83, 'Implementation specific error'],
598
- [ 0x87, 'Not authorized'],
599
- [ 0x8F, 'Topic Filter invalid'],
600
- [ 0x91, 'Packet Identifier in use'],
601
- );
602
- }
603
-
604
- function mqtt_decode_pingxxx(ns) {
605
- return ns[0xc] = ns[0xd] = pkt => pkt
606
- }
607
-
608
- function mqtt_decode_disconnect(ns, mqtt_reader) {
609
- return ns[0xe] = (pkt, u8_body) => {
610
- if (u8_body && 5 <= pkt.mqtt_level) {
611
- let rdr = mqtt_reader.of(u8_body);
612
- pkt.reason = rdr.reason(pkt.type);
613
- pkt.props = rdr.props();
614
- }
615
- return pkt }
616
- }
617
-
618
-
619
- function _disconnect_v5(mqtt_reader) {
620
- mqtt_reader.reasons('disconnect',
621
- // MQTT 5.0
622
- [ 0x00, 'Normal disconnection'],
623
- [ 0x04, 'Disconnect with Will Message'],
624
- [ 0x80, 'Unspecified error'],
625
- [ 0x81, 'Malformed Packet'],
626
- [ 0x82, 'Protocol Error'],
627
- [ 0x83, 'Implementation specific error'],
628
- [ 0x87, 'Not authorized'],
629
- [ 0x89, 'Server busy'],
630
- [ 0x8B, 'Server shutting down'],
631
- [ 0x8D, 'Keep Alive timeout'],
632
- [ 0x8E, 'Session taken over'],
633
- [ 0x8F, 'Topic Filter invalid'],
634
- [ 0x90, 'Topic Name invalid'],
635
- [ 0x93, 'Receive Maximum exceeded'],
636
- [ 0x94, 'Topic Alias invalid'],
637
- [ 0x95, 'Packet too large'],
638
- [ 0x96, 'Message rate too high'],
639
- [ 0x97, 'Quota exceeded'],
640
- [ 0x98, 'Administrative action'],
641
- [ 0x99, 'Payload format invalid'],
642
- [ 0x9A, 'Retain not supported'],
643
- [ 0x9B, 'QoS not supported'],
644
- [ 0x9C, 'Use another server'],
645
- [ 0x9D, 'Server moved'],
646
- [ 0x9E, 'Shared Subscriptions not supported'],
647
- [ 0x9F, 'Connection rate exceeded'],
648
- [ 0xA0, 'Maximum connect time'],
649
- [ 0xA1, 'Subscription Identifiers not supported'],
650
- [ 0xA2, 'Wildcard Subscriptions not supported'],
651
- );
652
- }
653
-
654
- function mqtt_decode_auth(ns, mqtt_reader) {
655
- return ns[0xf] = (pkt, u8_body) => {
656
- if ( 5 <= pkt.mqtt_level ) {
657
- let rdr = mqtt_reader.of(u8_body);
658
- pkt.reason = rdr.reason(pkt.type);
659
- pkt.props = rdr.props();
660
- }
661
- return pkt }
662
- }
663
-
664
-
665
- function _auth_v5(mqtt_reader) {
666
- mqtt_reader.reasons('auth',
667
- // MQTT 5.0
668
- [ 0x00, 'Success' ],
669
- [ 0x18, 'Continue authentication' ],
670
- [ 0x19, 'Re-authenticate' ],
671
- );
672
- }
673
-
674
376
  function mqtt_encode_connect(ns, mqtt_writer) {
675
377
  const _c_mqtt_proto = new Uint8Array([
676
378
  0, 4, 0x4d, 0x51, 0x54, 0x54 ]);
@@ -689,7 +391,7 @@ function mqtt_encode_connect(ns, mqtt_writer) {
689
391
  | ( will.retain ? 0x20 : 0 );
690
392
 
691
393
  return ns.connect = ( mqtt_level, pkt ) => {
692
- let wrt = mqtt_writer.of(pkt);
394
+ let wrt = mqtt_writer.for(pkt);
693
395
 
694
396
  wrt.push(_c_mqtt_proto);
695
397
  wrt.u8( mqtt_level );
@@ -727,12 +429,61 @@ function mqtt_encode_connect(ns, mqtt_writer) {
727
429
  }
728
430
  }
729
431
 
432
+ function mqtt_decode_connect(ns, mqtt_reader) {
433
+ class _connect_flags_ extends Number {
434
+ get reserved() { return this & 0x01 !== 0 }
435
+ get clean_start() { return this & 0x02 !== 0 }
436
+ get will_flag() { return this & 0x04 !== 0 }
437
+ get will_qos() { return (this >>> 3) & 0x3 }
438
+ get will_retain() { return this & 0x20 !== 0 }
439
+ get password() { return this & 0x40 !== 0 }
440
+ get username() { return this & 0x80 !== 0 }
441
+ }
442
+
443
+ return ns[0x1] = (pkt, u8_body) => {
444
+ let rdr = mqtt_reader.for(pkt, u8_body);
445
+ if ('MQTT' !== rdr.utf8())
446
+ throw new Error('Invalid mqtt_connect packet')
447
+
448
+ pkt.__proto__.mqtt_level =
449
+ pkt.mqtt_level = rdr.u8();
450
+
451
+ let flags = pkt.flags =
452
+ rdr.flags(_connect_flags_);
453
+
454
+ pkt.keep_alive = rdr.u16();
455
+
456
+ if (5 <= pkt.mqtt_level)
457
+ pkt.props = rdr.props();
458
+
459
+
460
+
461
+ pkt.client_id = rdr.utf8();
462
+ if (flags.will_flag) {
463
+ let will = pkt.will = {};
464
+ if (5 <= pkt.mqtt_level)
465
+ will.props = rdr.props();
466
+
467
+ will.topic = rdr.utf8();
468
+ will.payload = rdr.bin();
469
+ will.qos = flags.will_qos;
470
+ will.retain = flags.will_retain;
471
+ }
472
+
473
+ if (flags.username)
474
+ pkt.username = rdr.utf8();
475
+
476
+ if (flags.password)
477
+ pkt.password = rdr.bin();
478
+ return pkt }
479
+ }
480
+
730
481
  function mqtt_encode_connack(ns, mqtt_writer) {
731
482
  const _enc_flags_connack = flags =>
732
483
  flags.session_present ? 1 : 0;
733
484
 
734
485
  return ns.connack = (mqtt_level, pkt) => {
735
- let wrt = mqtt_writer.of(pkt);
486
+ let wrt = mqtt_writer.for(pkt);
736
487
 
737
488
  wrt.flags( pkt.flags, _enc_flags_connack );
738
489
 
@@ -748,10 +499,28 @@ function mqtt_encode_connack(ns, mqtt_writer) {
748
499
  }
749
500
  }
750
501
 
502
+
503
+ function mqtt_decode_connack(ns, mqtt_reader) {
504
+ class _connack_flags_ extends Number {
505
+ get session_present() { return this & 0x01 !== 0 }
506
+ }
507
+
508
+ return ns[0x2] = (pkt, u8_body) => {
509
+ let rdr = mqtt_reader.for(pkt, u8_body);
510
+
511
+ pkt.flags =
512
+ rdr.flags(_connack_flags_);
513
+
514
+ pkt.reason = rdr.reason(pkt.type);
515
+ if (5 <= pkt.mqtt_level)
516
+ pkt.props = rdr.props();
517
+ return pkt }
518
+ }
519
+
751
520
  function mqtt_encode_publish(ns, mqtt_writer) {
752
521
  return ns.publish = ( mqtt_level, pkt ) => {
753
522
  let qos = (pkt.qos & 0x3) << 1;
754
- let wrt = mqtt_writer.of(pkt);
523
+ let wrt = mqtt_writer.for(pkt);
755
524
 
756
525
  wrt.utf8(pkt.topic);
757
526
  if (0 !== qos)
@@ -769,9 +538,28 @@ function mqtt_encode_publish(ns, mqtt_writer) {
769
538
  }
770
539
  }
771
540
 
541
+ function mqtt_decode_publish(ns, mqtt_reader) {
542
+ return ns[0x3] = (pkt, u8_body) => {
543
+ let {hdr} = pkt;
544
+ pkt.dup = Boolean(hdr & 0x8);
545
+ pkt.retain = Boolean(hdr & 0x1);
546
+ let qos = pkt.qos = (hdr>>1) & 0x3;
547
+
548
+ let rdr = mqtt_reader.for(pkt, u8_body);
549
+ pkt.topic = rdr.utf8();
550
+ if (0 !== qos)
551
+ pkt.pkt_id = rdr.u16();
552
+
553
+ if (5 <= pkt.mqtt_level)
554
+ pkt.props = rdr.props();
555
+
556
+ pkt.payload = rdr.flush();
557
+ return pkt }
558
+ }
559
+
772
560
  function mqtt_encode_puback(ns, mqtt_writer) {
773
561
  return ns.puback = ( mqtt_level, pkt ) => {
774
- let wrt = mqtt_writer.of(pkt);
562
+ let wrt = mqtt_writer.for(pkt);
775
563
 
776
564
  wrt.u16(pkt.pkt_id);
777
565
  if (5 <= mqtt_level) {
@@ -783,6 +571,20 @@ function mqtt_encode_puback(ns, mqtt_writer) {
783
571
  }
784
572
  }
785
573
 
574
+
575
+ function mqtt_decode_puback(ns, mqtt_reader) {
576
+ return ns[0x4] = (pkt, u8_body) => {
577
+ let rdr = mqtt_reader.for(pkt, u8_body);
578
+
579
+ pkt.pkt_id = rdr.u16();
580
+ if (5 <= pkt.mqtt_level) {
581
+ pkt.reason = rdr.reason(pkt.type);
582
+ pkt.props = rdr.props();
583
+ }
584
+
585
+ return pkt }
586
+ }
587
+
786
588
  function mqtt_encode_pubxxx(ns, mqtt_writer) {
787
589
  ns.pubrec = _enc_pubxxx(0x50);
788
590
  ns.pubrel = _enc_pubxxx(0x62);
@@ -791,7 +593,7 @@ function mqtt_encode_pubxxx(ns, mqtt_writer) {
791
593
 
792
594
  function _enc_pubxxx(hdr) {
793
595
  return ( mqtt_level, pkt ) => {
794
- let wrt = mqtt_writer.of(pkt);
596
+ let wrt = mqtt_writer.for(pkt);
795
597
 
796
598
  wrt.u16(pkt.pkt_id);
797
599
  if (5 <= mqtt_level) {
@@ -807,6 +609,17 @@ function mqtt_encode_pubxxx(ns, mqtt_writer) {
807
609
  }
808
610
  }
809
611
 
612
+ function mqtt_decode_pubxxx(ns, mqtt_reader) {
613
+ return ns[0x5] = ns[0x6] = ns[0x7] = (pkt, u8_body) => {
614
+ let rdr = mqtt_reader.for(pkt, u8_body);
615
+
616
+ pkt.pkt_id = rdr.u16();
617
+ pkt.reason = rdr.reason('pubxxx', mqtt_reader);
618
+ if (5 <= pkt.mqtt_level)
619
+ pkt.props = rdr.props();
620
+ return pkt }
621
+ }
622
+
810
623
  function mqtt_encode_subscribe(ns, mqtt_writer) {
811
624
  const _enc_subscribe_flags = opts => 0
812
625
  | ( opts.qos & 0x3 )
@@ -814,7 +627,7 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
814
627
  | ( (opts.retain_handling & 0x3) << 2 );
815
628
 
816
629
  return ns.subscribe = ( mqtt_level, pkt ) => {
817
- let wrt = mqtt_writer.of(pkt);
630
+ let wrt = mqtt_writer.for(pkt);
818
631
 
819
632
  wrt.u16(pkt.pkt_id);
820
633
  if (5 <= mqtt_level)
@@ -840,6 +653,30 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
840
653
  }
841
654
  }
842
655
 
656
+ function mqtt_decode_subscribe(ns, mqtt_reader) {
657
+ class _subscription_options_ extends Number {
658
+ get qos() { return this & 0x3 }
659
+ get retain() { return this & 0x4 !== 0 }
660
+ get retain_handling() { return (this >> 2) & 0x3 }
661
+ }
662
+
663
+ return ns[0x8] = (pkt, u8_body) => {
664
+ let rdr = mqtt_reader.for(pkt, u8_body);
665
+
666
+ pkt.pkt_id = rdr.u16();
667
+ if (5 <= pkt.mqtt_level)
668
+ pkt.props = rdr.props();
669
+
670
+ let topic, opts, topic_list = pkt.topics = [];
671
+ while (rdr.has_more()) {
672
+ topic = rdr.utf8();
673
+ opts = rdr.flags(_subscription_options_);
674
+ topic_list.push({topic, opts});
675
+ }
676
+
677
+ return pkt }
678
+ }
679
+
843
680
  function mqtt_encode_xxsuback(ns, mqtt_writer) {
844
681
  ns.suback = _enc_xxsuback(0x90);
845
682
  ns.unsuback = _enc_xxsuback(0xb0);
@@ -847,7 +684,7 @@ function mqtt_encode_xxsuback(ns, mqtt_writer) {
847
684
 
848
685
  function _enc_xxsuback(hdr) {
849
686
  return ( mqtt_level, pkt ) => {
850
- let wrt = mqtt_writer.of(pkt);
687
+ let wrt = mqtt_writer.for(pkt);
851
688
 
852
689
  wrt.u16(pkt.pkt_id);
853
690
  if (5 <= mqtt_level)
@@ -861,9 +698,26 @@ function mqtt_encode_xxsuback(ns, mqtt_writer) {
861
698
  }
862
699
  }
863
700
 
701
+
702
+ function mqtt_decode_xxsuback(ns, mqtt_reader) {
703
+ return ns[0x9] = ns[0xb] = (pkt, u8_body) => {
704
+ let rdr = mqtt_reader.for(pkt, u8_body);
705
+
706
+ pkt.pkt_id = rdr.u16();
707
+ if (5 <= pkt.mqtt_level)
708
+ pkt.props = rdr.props();
709
+
710
+ let answers = pkt.answers = [];
711
+ while (rdr.has_more())
712
+ answers.push(
713
+ rdr.reason(pkt.type) );
714
+
715
+ return pkt }
716
+ }
717
+
864
718
  function mqtt_encode_unsubscribe(ns, mqtt_writer) {
865
719
  return ns.unsubscribe = ( mqtt_level, pkt ) => {
866
- let wrt = mqtt_writer.of(pkt);
720
+ let wrt = mqtt_writer.for(pkt);
867
721
 
868
722
  wrt.u16(pkt.pkt_id);
869
723
  if (5 <= mqtt_level)
@@ -876,14 +730,34 @@ function mqtt_encode_unsubscribe(ns, mqtt_writer) {
876
730
  }
877
731
  }
878
732
 
733
+ function mqtt_decode_unsubscribe(ns, mqtt_reader) {
734
+ return ns[0xa] = (pkt, u8_body) => {
735
+ let rdr = mqtt_reader.for(pkt, u8_body);
736
+
737
+ pkt.pkt_id = rdr.u16();
738
+ if (5 <= pkt.mqtt_level)
739
+ pkt.props = rdr.props();
740
+
741
+ let topic_list = pkt.topics = [];
742
+ while (rdr.has_more())
743
+ topic_list.push(rdr.utf8());
744
+
745
+ return pkt }
746
+ }
747
+
879
748
  function mqtt_encode_pingxxx(ns) {
880
749
  ns.pingreq = () => new Uint8Array([ 0xc0, 0 ]);
881
750
  ns.pingresp = () => new Uint8Array([ 0xd0, 0 ]);
882
751
  }
883
752
 
753
+
754
+ function mqtt_decode_pingxxx(ns) {
755
+ return ns[0xc] = ns[0xd] = pkt => pkt
756
+ }
757
+
884
758
  function mqtt_encode_disconnect(ns, mqtt_writer) {
885
759
  return ns.disconnect = ( mqtt_level, pkt ) => {
886
- let wrt = mqtt_writer.of(pkt);
760
+ let wrt = mqtt_writer.for(pkt);
887
761
 
888
762
  if (pkt && 5 <= mqtt_level) {
889
763
  if (pkt.reason || pkt.props) {
@@ -896,6 +770,17 @@ function mqtt_encode_disconnect(ns, mqtt_writer) {
896
770
  }
897
771
  }
898
772
 
773
+
774
+ function mqtt_decode_disconnect(ns, mqtt_reader) {
775
+ return ns[0xe] = (pkt, u8_body) => {
776
+ if (u8_body && 5 <= pkt.mqtt_level) {
777
+ let rdr = mqtt_reader.for(pkt, u8_body);
778
+ pkt.reason = rdr.reason(pkt.type);
779
+ pkt.props = rdr.props();
780
+ }
781
+ return pkt }
782
+ }
783
+
899
784
  function mqtt_encode_auth(ns, mqtt_writer) {
900
785
  return ns.auth = ( mqtt_level, pkt ) => {
901
786
  if (5 > mqtt_level)
@@ -910,17 +795,15 @@ function mqtt_encode_auth(ns, mqtt_writer) {
910
795
  }
911
796
  }
912
797
 
913
- const mqtt_reader_v5 = /* #__PURE__ */
914
- mqtt_reader_info(
915
- mqtt_reader_v5$1,
916
- _connack_v5,
917
- _puback_v5,
918
- _pubxxx_v4,
919
- _suback_v5,
920
- _unsuback_v4,
921
- _disconnect_v5,
922
- _auth_v5,
923
- );
798
+ function mqtt_decode_auth(ns, mqtt_reader) {
799
+ return ns[0xf] = (pkt, u8_body) => {
800
+ if ( 5 <= pkt.mqtt_level ) {
801
+ let rdr = mqtt_reader.of(u8_body);
802
+ pkt.reason = rdr.reason(pkt.type);
803
+ pkt.props = rdr.props();
804
+ }
805
+ return pkt }
806
+ }
924
807
 
925
808
  const mqtt_decode_v5 = [
926
809
  mqtt_decode_connect,
@@ -929,9 +812,8 @@ const mqtt_decode_v5 = [
929
812
  mqtt_decode_puback,
930
813
  mqtt_decode_pubxxx,
931
814
  mqtt_decode_subscribe,
932
- mqtt_decode_suback,
815
+ mqtt_decode_xxsuback,
933
816
  mqtt_decode_unsubscribe,
934
- mqtt_decode_unsuback,
935
817
  mqtt_decode_pingxxx,
936
818
  mqtt_decode_disconnect,
937
819
  mqtt_decode_auth,
@@ -1157,47 +1039,38 @@ function _route_remove(all_route_lists, query) {
1157
1039
  return true} }
1158
1040
  return false}
1159
1041
 
1160
- /*
1161
- export function decode_varint_loop(u8, i=0) {
1162
- let i0 = i
1163
- let shift = 0, n = (u8[i] & 0x7f)
1164
- while ( 0x80 & u8[i++] )
1165
- n |= (u8[i] & 0x7f) << (shift += 7)
1166
-
1167
- return [n, i, i0]
1168
- }
1169
- */
1042
+ function decode_varint(u8, i0=0, invalid) {
1043
+ let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
1044
+ for(; b & 0x80;)
1045
+ n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
1170
1046
 
1171
-
1172
- function decode_varint(u8, i=0) {
1173
- let i0 = i;
1174
- // unrolled for a max of 4 chains
1175
- let n = (u8[i] & 0x7f) << 0;
1176
- if ( 0x80 & u8[i++] ) {
1177
- n |= (u8[i] & 0x7f) << 7;
1178
- if ( 0x80 & u8[i++] ) {
1179
- n |= (u8[i] & 0x7f) << 14;
1180
- if ( 0x80 & u8[i++] ) {
1181
- n |= (u8[i] & 0x7f) << 21;
1182
- }
1183
- }
1184
- }
1185
- return [n, i, i0]
1047
+ return (u8.length < i)
1048
+ ? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
1049
+ : [n, i, i0] // successful value
1186
1050
  }
1187
1051
 
1188
1052
  function mqtt_raw_dispatch(opt) {
1189
- let u8 = new Uint8Array(0);
1053
+ let u8 = new Uint8Array(0), len_tip=0;
1190
1054
  return u8_buf => {
1191
1055
  u8 = 0 === u8.byteLength
1192
1056
  ? u8_buf : _u8_join(u8, u8_buf);
1193
1057
 
1194
1058
  let res = [];
1195
- while (1) {
1196
- let [len_body, len_vh] = decode_varint(u8, 1);
1197
- let len_pkt = len_body + len_vh;
1198
1059
 
1199
- if ( u8.byteLength < len_pkt )
1200
- return res
1060
+ // wait for at least len_tip bytes for next (tip) message
1061
+ while ( u8.byteLength >= len_tip ) {
1062
+
1063
+ // if varint is incomplete, return len_body=NaN
1064
+ let [len_body, len_vh] = decode_varint(u8, 1, NaN);
1065
+ let len_pkt = len_body + len_vh; // may be NaN
1066
+
1067
+ if (!( len_pkt <= u8.byteLength )) {
1068
+ // incomplete packet cases:
1069
+ // - len_pkt is less than available bytes
1070
+ // - len_pkt is NaN from decode_varint() due to lack of data
1071
+ len_tip = len_pkt || 0; // 0 when NaN
1072
+ break
1073
+ }
1201
1074
 
1202
1075
  let b0 = u8[0];
1203
1076
  let u8_body = 0 === len_body ? null
@@ -1209,6 +1082,8 @@ function mqtt_raw_dispatch(opt) {
1209
1082
  if (null != pkt)
1210
1083
  res.push( pkt );
1211
1084
  }
1085
+
1086
+ return res
1212
1087
  }
1213
1088
  }
1214
1089
 
@@ -1219,16 +1094,17 @@ function _u8_join(a, b) {
1219
1094
  return r
1220
1095
  }
1221
1096
 
1222
- const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
1097
+ const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
1098
+
1099
+
1100
+ function mqtt_pkt_ctx(mqtt_level, opts, pkt_api=opts.pkt_ctx) {
1101
+ let _as_pkt_ctx = pkt_api => ({
1102
+ __proto__: pkt_api,
1103
+ get hdr() { return this.b0 & 0xf },
1104
+ get id() { return this.b0 >>> 4 },
1105
+ get type() { return _pkt_types[this.b0 >>> 4] },
1106
+ mqtt_level });
1223
1107
 
1224
- function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
1225
- pkt_ctx = {
1226
- __proto__: pkt_ctx || opts.pkt_ctx,
1227
- mqtt_level,
1228
- get hdr() { return this.b0 & 0xf },
1229
- get id() { return this.b0 >>> 4 },
1230
- get type() { return _pkt_types[this.b0 >>> 4] },
1231
- };
1232
1108
 
1233
1109
  let op, _decode_by_id=[], _encode_by_type={};
1234
1110
  for (op of opts.encode_fns)
@@ -1237,10 +1113,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
1237
1113
  op(_decode_by_id, opts.mqtt_reader);
1238
1114
 
1239
1115
  return {
1240
- pkt_ctx,
1116
+ pkt_api, pkt_ctx: _as_pkt_ctx(pkt_api),
1241
1117
 
1242
- encode_pkt(type, pkt) {
1243
- return _encode_by_type[type]( mqtt_level, pkt ) },
1118
+ encode_pkt: (type, pkt) =>
1119
+ _encode_by_type[type]( mqtt_level, pkt ),
1244
1120
 
1245
1121
  decode_pkt(b0, u8_body) {
1246
1122
  if (b0.map) // Uint8Array in first arg
@@ -1249,12 +1125,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
1249
1125
  let fn_decode = _decode_by_id[b0>>>4] || _decode_by_id[0];
1250
1126
  return fn_decode?.({__proto__: this.pkt_ctx, b0}, u8_body) },
1251
1127
 
1252
- mqtt_stream() {
1253
- let self = { __proto__: this, pkt_ctx: { __proto__: pkt_ctx } };
1254
- self.pkt_ctx._base_ = self.pkt_ctx;
1128
+ mqtt_stream(pkt_api=this.pkt_api) {
1129
+ let self = { __proto__: this, pkt_ctx: _as_pkt_ctx(pkt_api) };
1255
1130
  self.decode = mqtt_raw_dispatch(self);
1256
- return self
1257
- },
1131
+ return self },
1258
1132
  }
1259
1133
  }
1260
1134
 
@@ -1778,7 +1652,7 @@ class MQTTCore extends MQTTBase {
1778
1652
 
1779
1653
  return this} }
1780
1654
 
1781
- const version = '0.6.1';
1655
+ const version = '0.6.3';
1782
1656
 
1783
1657
  const MQTTClient_v4 = /* #__PURE__ */
1784
1658
  with_topic_path_router(