u8-mqtt 0.6.2 → 0.6.4

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 (108) 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 +342 -384
  6. package/cjs/full-v4.cjs.map +1 -1
  7. package/cjs/full-v5.cjs +395 -507
  8. package/cjs/full-v5.cjs.map +1 -1
  9. package/cjs/index.cjs +292 -399
  10. package/cjs/index.cjs.map +1 -1
  11. package/cjs/v4.cjs +239 -274
  12. package/cjs/v4.cjs.map +1 -1
  13. package/cjs/v5.cjs +292 -399
  14. package/cjs/v5.cjs.map +1 -1
  15. package/code/router_path.jsy +39 -28
  16. package/code/with_topic_router.jsy +4 -1
  17. package/esm/basic-v4.js +194 -243
  18. package/esm/basic-v4.js.map +1 -1
  19. package/esm/basic-v5.js +247 -368
  20. package/esm/basic-v5.js.map +1 -1
  21. package/esm/deno/basic-v4.js +194 -243
  22. package/esm/deno/basic-v4.js.map +1 -1
  23. package/esm/deno/basic-v5.js +247 -368
  24. package/esm/deno/basic-v5.js.map +1 -1
  25. package/esm/deno/full-v4.js +342 -384
  26. package/esm/deno/full-v4.js.map +1 -1
  27. package/esm/deno/full-v5.js +395 -507
  28. package/esm/deno/full-v5.js.map +1 -1
  29. package/esm/deno/index.js +292 -399
  30. package/esm/deno/index.js.map +1 -1
  31. package/esm/deno/v4.js +239 -274
  32. package/esm/deno/v4.js.map +1 -1
  33. package/esm/deno/v5.js +292 -399
  34. package/esm/deno/v5.js.map +1 -1
  35. package/esm/full-v4.js +342 -384
  36. package/esm/full-v4.js.map +1 -1
  37. package/esm/full-v5.js +395 -507
  38. package/esm/full-v5.js.map +1 -1
  39. package/esm/index.js +292 -399
  40. package/esm/index.js.map +1 -1
  41. package/esm/node/basic-v4.js +194 -243
  42. package/esm/node/basic-v4.js.map +1 -1
  43. package/esm/node/basic-v4.mjs +194 -243
  44. package/esm/node/basic-v4.mjs.map +1 -1
  45. package/esm/node/basic-v5.js +247 -368
  46. package/esm/node/basic-v5.js.map +1 -1
  47. package/esm/node/basic-v5.mjs +247 -368
  48. package/esm/node/basic-v5.mjs.map +1 -1
  49. package/esm/node/full-v4.js +342 -384
  50. package/esm/node/full-v4.js.map +1 -1
  51. package/esm/node/full-v4.mjs +342 -384
  52. package/esm/node/full-v4.mjs.map +1 -1
  53. package/esm/node/full-v5.js +395 -507
  54. package/esm/node/full-v5.js.map +1 -1
  55. package/esm/node/full-v5.mjs +395 -507
  56. package/esm/node/full-v5.mjs.map +1 -1
  57. package/esm/node/index.js +292 -399
  58. package/esm/node/index.js.map +1 -1
  59. package/esm/node/index.mjs +292 -399
  60. package/esm/node/index.mjs.map +1 -1
  61. package/esm/node/v4.js +239 -274
  62. package/esm/node/v4.js.map +1 -1
  63. package/esm/node/v4.mjs +239 -274
  64. package/esm/node/v4.mjs.map +1 -1
  65. package/esm/node/v5.js +292 -399
  66. package/esm/node/v5.js.map +1 -1
  67. package/esm/node/v5.mjs +292 -399
  68. package/esm/node/v5.mjs.map +1 -1
  69. package/esm/v4.js +239 -274
  70. package/esm/v4.js.map +1 -1
  71. package/esm/v5.js +292 -399
  72. package/esm/v5.js.map +1 -1
  73. package/esm/web/basic-v4.js +194 -243
  74. package/esm/web/basic-v4.js.map +1 -1
  75. package/esm/web/basic-v4.min.js +1 -1
  76. package/esm/web/basic-v4.min.js.br +0 -0
  77. package/esm/web/basic-v4.min.js.gz +0 -0
  78. package/esm/web/basic-v5.js +247 -368
  79. package/esm/web/basic-v5.js.map +1 -1
  80. package/esm/web/basic-v5.min.js +1 -1
  81. package/esm/web/basic-v5.min.js.br +0 -0
  82. package/esm/web/basic-v5.min.js.gz +0 -0
  83. package/esm/web/full-v4.js +342 -384
  84. package/esm/web/full-v4.js.map +1 -1
  85. package/esm/web/full-v4.min.js +1 -1
  86. package/esm/web/full-v4.min.js.br +0 -0
  87. package/esm/web/full-v4.min.js.gz +0 -0
  88. package/esm/web/full-v5.js +395 -507
  89. package/esm/web/full-v5.js.map +1 -1
  90. package/esm/web/full-v5.min.js +1 -1
  91. package/esm/web/full-v5.min.js.br +0 -0
  92. package/esm/web/full-v5.min.js.gz +0 -0
  93. package/esm/web/index.js +292 -399
  94. package/esm/web/index.js.map +1 -1
  95. package/esm/web/index.min.js +1 -1
  96. package/esm/web/index.min.js.br +0 -0
  97. package/esm/web/index.min.js.gz +0 -0
  98. package/esm/web/v4.js +239 -274
  99. package/esm/web/v4.js.map +1 -1
  100. package/esm/web/v4.min.js +1 -1
  101. package/esm/web/v4.min.js.br +0 -0
  102. package/esm/web/v4.min.js.gz +0 -0
  103. package/esm/web/v5.js +292 -399
  104. package/esm/web/v5.js.map +1 -1
  105. package/esm/web/v5.min.js +1 -1
  106. package/esm/web/v5.min.js.br +0 -0
  107. package/esm/web/v5.min.js.gz +0 -0
  108. package/package.json +5 -5
package/esm/v4.js CHANGED
@@ -1,54 +1,32 @@
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
- }
35
- }
36
- return [n, i, i0]
37
- }
38
-
39
- class U8_Reason extends Number {
40
- static of(v, pkt_kind, by_kind) {
41
- let self = new this(v);
42
- self.reason = by_kind?.[pkt_kind]?.get(v) || pkt_kind;
43
- return self
18
+ class mqtt_reason extends Number {
19
+ constructor(v, reason) {
20
+ super(v);
21
+ this.reason = `:${(this.ok = v<0x80) ? 'ok' : 'fail'}:${reason}`;
44
22
  }
45
23
  }
46
24
 
47
25
  let mqtt_reader_v4$1 = class mqtt_reader_v4 {
48
- static of(buf) { return this.prototype.of(buf) }
49
- of(buf) {
26
+ static for(pkt, u8_body) { return new this().of(u8_body, {pkt}) }
27
+ of(buf, opt) {
50
28
  let step = (width, k) => (k=0|step.k, step.k=k+width, k);
51
- return {__proto__: this, buf, step}
29
+ return {__proto__: this, buf, step, ...opt}
52
30
  }
53
31
 
54
32
  has_more() {
@@ -91,7 +69,7 @@ let mqtt_reader_v4$1 = class mqtt_reader_v4 {
91
69
  reason(pkt_kind) {
92
70
  let v = this.buf[this.step(1)];
93
71
  if (null != v)
94
- return U8_Reason.of(v, pkt_kind, this._reasons_by)
72
+ return new mqtt_reason(v, this._reason_for?.(v, pkt_kind))
95
73
  }
96
74
 
97
75
  flush() {
@@ -102,28 +80,57 @@ let mqtt_reader_v4$1 = class mqtt_reader_v4 {
102
80
 
103
81
  };
104
82
 
105
- function mqtt_reader_info(mqtt_reader, ... info_fn_list) {
106
- mqtt_reader = class extends mqtt_reader {
107
- static reasons(pkt_type, ...reason_entries) {
108
- let proto = this.prototype;
109
- proto._reasons_by = {... proto._reasons_by};
110
-
111
- let lut = (proto._reasons_by[pkt_type] ||= new Map());
112
- for (let [u8, reason] of reason_entries)
113
- lut.set( u8, reason );
83
+ function with_reasons(mqtt_reader, by_kind) {
84
+ for (let [k,lut] of Object.entries(by_kind))
85
+ by_kind[k] = new Map(lut);
114
86
 
115
- return this
87
+ return class extends mqtt_reader {
88
+ _reason_for(v, pkt_kind) {
89
+ return by_kind[pkt_kind]?.get(v) || by_kind.all.get(v)
116
90
  }
117
- };
91
+ warn(msg) {
92
+ let pkt = this.pkt;
93
+ pkt.warn ? pkt.warn(msg, pkt)
94
+ : console.warn('[u8-mqtt-packet] '+msg);
95
+ }
96
+ }
97
+ }
118
98
 
119
- for (let fn_info of info_fn_list)
120
- fn_info(mqtt_reader);
121
99
 
122
- return mqtt_reader
123
- }
100
+ const reasons_v4 = {
101
+ connack: [
102
+ [ 0x01, 'conn refused: unacceptable protocol version'],
103
+ [ 0x02, 'conn refused: identifier rejected'],
104
+ [ 0x03, 'conn refused: server unavailable'],
105
+ [ 0x04, 'conn refused: bad user name or password'],
106
+ [ 0x05, 'conn refused: not authorized'],
107
+ ],
108
+ suback: [
109
+ [ 0x00, 'qos=0'],
110
+ [ 0x01, 'qos=1'],
111
+ [ 0x02, 'qos=2'],
112
+ ],
113
+ unsuback: [
114
+ [ 0x11, 'no subscription existed'],
115
+ ],
116
+ puback: [
117
+ [ 0x10, 'no matching subscribers'],
118
+ ],
119
+ all: [
120
+ [ 0, ''], // Success
121
+ [ 0x80, 'unspecified error'], // disconnect puback suback unsuback
122
+ [ 0x83, 'implementation specific error'], // connack disconnect puback suback unsuback
123
+ [ 0x87, 'not authorized'], // connack disconnect puback suback unsuback
124
+ [ 0x8F, 'topic filter invalid'], // disconnect suback unsuback
125
+ [ 0x91, 'packet identifier in use'], // puback suback unsuback
126
+ [ 0x92, 'packet identifier not found' ], // pubxxx
127
+ ]};
128
+
129
+ const mqtt_reader_v4 = /* #__PURE__ */
130
+ with_reasons(mqtt_reader_v4$1, reasons_v4);
124
131
 
125
132
  class mqtt_writer_v4 {
126
- static of() { return this.prototype.of() }
133
+ static for(pkt) { return new this().of() }
127
134
  of() { return {__proto__: this, $:[]} }
128
135
 
129
136
  static init() { return this }
@@ -194,128 +201,6 @@ class mqtt_writer_v4 {
194
201
  }
195
202
  }
196
203
 
197
- function mqtt_decode_connack(ns, mqtt_reader) {
198
- class _connack_flags_ extends Number {
199
- get session_present() { return this & 0x01 !== 0 }
200
- }
201
-
202
- return ns[0x2] = (pkt, u8_body) => {
203
- let rdr = mqtt_reader.of(u8_body);
204
-
205
- pkt.flags =
206
- rdr.flags(_connack_flags_);
207
-
208
- pkt.reason = rdr.reason(pkt.type);
209
- if (5 <= pkt.mqtt_level)
210
- pkt.props = rdr.props();
211
- return pkt }
212
- }
213
-
214
-
215
- function _connack_v4(mqtt_reader) {
216
- mqtt_reader.reasons('connack',
217
- // MQTT 3.1.1
218
- [ 0x00, 'Success'],
219
- [ 0x01, 'Connection refused, unacceptable protocol version'],
220
- [ 0x02, 'Connection refused, identifier rejected'],
221
- [ 0x03, 'Connection refused, server unavailable'],
222
- [ 0x04, 'Connection refused, bad user name or password'],
223
- [ 0x05, 'Connection refused, not authorized'],
224
- );
225
- }
226
-
227
- function mqtt_decode_publish(ns, mqtt_reader) {
228
- return ns[0x3] = (pkt, u8_body) => {
229
- let {hdr} = pkt;
230
- pkt.dup = Boolean(hdr & 0x8);
231
- pkt.retain = Boolean(hdr & 0x1);
232
- let qos = pkt.qos = (hdr>>1) & 0x3;
233
-
234
- let rdr = mqtt_reader.of(u8_body);
235
- pkt.topic = rdr.utf8();
236
- if (0 !== qos)
237
- pkt.pkt_id = rdr.u16();
238
-
239
- if (5 <= pkt.mqtt_level)
240
- pkt.props = rdr.props();
241
-
242
- pkt.payload = rdr.flush();
243
- return pkt }
244
- }
245
-
246
- function mqtt_decode_puback(ns, mqtt_reader) {
247
- return ns[0x4] = (pkt, u8_body) => {
248
- let rdr = mqtt_reader.of(u8_body);
249
-
250
- pkt.pkt_id = rdr.u16();
251
- if (5 <= pkt.mqtt_level) {
252
- pkt.reason = rdr.reason(pkt.type);
253
- pkt.props = rdr.props();
254
- }
255
-
256
- return pkt }
257
- }
258
-
259
- function _mqtt_decode_suback(mqtt_reader) {
260
- return (pkt, u8_body) => {
261
- let rdr = mqtt_reader.of(u8_body);
262
-
263
- pkt.pkt_id = rdr.u16();
264
- if (5 <= pkt.mqtt_level)
265
- pkt.props = rdr.props();
266
-
267
- let answers = pkt.answers = [];
268
- while (rdr.has_more())
269
- answers.push(
270
- rdr.reason(pkt.type) );
271
-
272
- return pkt }
273
- }
274
-
275
- function mqtt_decode_suback(ns, mqtt_reader) {
276
- return ns[0x9] = _mqtt_decode_suback(mqtt_reader)
277
- }
278
-
279
- function _suback_v4(mqtt_reader) {
280
- mqtt_reader.reasons('suback',
281
- // MQTT 3.1.1
282
- [ 0x00, 'Granted QoS 0'],
283
- [ 0x01, 'Granted QoS 1'],
284
- [ 0x02, 'Granted QoS 2'],
285
- );
286
- }
287
-
288
- function mqtt_decode_unsuback(ns, mqtt_reader) {
289
- return ns[0xb] = _mqtt_decode_suback(mqtt_reader)
290
- }
291
-
292
- function _unsuback_v4(mqtt_reader) {
293
- mqtt_reader.reasons('unsuback',
294
- // MQTT 3.1.1
295
- [ 0x00, 'Success'],
296
- [ 0x11, 'No subscription existed'],
297
- [ 0x80, 'Unspecified error'],
298
- [ 0x83, 'Implementation specific error'],
299
- [ 0x87, 'Not authorized'],
300
- [ 0x8F, 'Topic Filter invalid'],
301
- [ 0x91, 'Packet Identifier in use'],
302
- );
303
- }
304
-
305
- function mqtt_decode_pingxxx(ns) {
306
- return ns[0xc] = ns[0xd] = pkt => pkt
307
- }
308
-
309
- function mqtt_decode_disconnect(ns, mqtt_reader) {
310
- return ns[0xe] = (pkt, u8_body) => {
311
- if (u8_body && 5 <= pkt.mqtt_level) {
312
- let rdr = mqtt_reader.of(u8_body);
313
- pkt.reason = rdr.reason(pkt.type);
314
- pkt.props = rdr.props();
315
- }
316
- return pkt }
317
- }
318
-
319
204
  function mqtt_encode_connect(ns, mqtt_writer) {
320
205
  const _c_mqtt_proto = new Uint8Array([
321
206
  0, 4, 0x4d, 0x51, 0x54, 0x54 ]);
@@ -334,7 +219,7 @@ function mqtt_encode_connect(ns, mqtt_writer) {
334
219
  | ( will.retain ? 0x20 : 0 );
335
220
 
336
221
  return ns.connect = ( mqtt_level, pkt ) => {
337
- let wrt = mqtt_writer.of(pkt);
222
+ let wrt = mqtt_writer.for(pkt);
338
223
 
339
224
  wrt.push(_c_mqtt_proto);
340
225
  wrt.u8( mqtt_level );
@@ -372,10 +257,27 @@ function mqtt_encode_connect(ns, mqtt_writer) {
372
257
  }
373
258
  }
374
259
 
260
+ function mqtt_decode_connack(ns, mqtt_reader) {
261
+ class _connack_flags_ extends Number {
262
+ get session_present() { return this & 0x01 !== 0 }
263
+ }
264
+
265
+ return ns[0x2] = (pkt, u8_body) => {
266
+ let rdr = mqtt_reader.for(pkt, u8_body);
267
+
268
+ pkt.flags =
269
+ rdr.flags(_connack_flags_);
270
+
271
+ pkt.reason = rdr.reason(pkt.type);
272
+ if (5 <= pkt.mqtt_level)
273
+ pkt.props = rdr.props();
274
+ return pkt }
275
+ }
276
+
375
277
  function mqtt_encode_publish(ns, mqtt_writer) {
376
278
  return ns.publish = ( mqtt_level, pkt ) => {
377
279
  let qos = (pkt.qos & 0x3) << 1;
378
- let wrt = mqtt_writer.of(pkt);
280
+ let wrt = mqtt_writer.for(pkt);
379
281
 
380
282
  wrt.utf8(pkt.topic);
381
283
  if (0 !== qos)
@@ -393,9 +295,28 @@ function mqtt_encode_publish(ns, mqtt_writer) {
393
295
  }
394
296
  }
395
297
 
298
+ function mqtt_decode_publish(ns, mqtt_reader) {
299
+ return ns[0x3] = (pkt, u8_body) => {
300
+ let {hdr} = pkt;
301
+ pkt.dup = Boolean(hdr & 0x8);
302
+ pkt.retain = Boolean(hdr & 0x1);
303
+ let qos = pkt.qos = (hdr>>1) & 0x3;
304
+
305
+ let rdr = mqtt_reader.for(pkt, u8_body);
306
+ pkt.topic = rdr.utf8();
307
+ if (0 !== qos)
308
+ pkt.pkt_id = rdr.u16();
309
+
310
+ if (5 <= pkt.mqtt_level)
311
+ pkt.props = rdr.props();
312
+
313
+ pkt.payload = rdr.flush();
314
+ return pkt }
315
+ }
316
+
396
317
  function mqtt_encode_puback(ns, mqtt_writer) {
397
318
  return ns.puback = ( mqtt_level, pkt ) => {
398
- let wrt = mqtt_writer.of(pkt);
319
+ let wrt = mqtt_writer.for(pkt);
399
320
 
400
321
  wrt.u16(pkt.pkt_id);
401
322
  if (5 <= mqtt_level) {
@@ -407,6 +328,20 @@ function mqtt_encode_puback(ns, mqtt_writer) {
407
328
  }
408
329
  }
409
330
 
331
+
332
+ function mqtt_decode_puback(ns, mqtt_reader) {
333
+ return ns[0x4] = (pkt, u8_body) => {
334
+ let rdr = mqtt_reader.for(pkt, u8_body);
335
+
336
+ pkt.pkt_id = rdr.u16();
337
+ if (5 <= pkt.mqtt_level) {
338
+ pkt.reason = rdr.reason(pkt.type);
339
+ pkt.props = rdr.props();
340
+ }
341
+
342
+ return pkt }
343
+ }
344
+
410
345
  function mqtt_encode_subscribe(ns, mqtt_writer) {
411
346
  const _enc_subscribe_flags = opts => 0
412
347
  | ( opts.qos & 0x3 )
@@ -414,7 +349,7 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
414
349
  | ( (opts.retain_handling & 0x3) << 2 );
415
350
 
416
351
  return ns.subscribe = ( mqtt_level, pkt ) => {
417
- let wrt = mqtt_writer.of(pkt);
352
+ let wrt = mqtt_writer.for(pkt);
418
353
 
419
354
  wrt.u16(pkt.pkt_id);
420
355
  if (5 <= mqtt_level)
@@ -440,9 +375,25 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
440
375
  }
441
376
  }
442
377
 
378
+ function mqtt_decode_xxsuback(ns, mqtt_reader) {
379
+ return ns[0x9] = ns[0xb] = (pkt, u8_body) => {
380
+ let rdr = mqtt_reader.for(pkt, u8_body);
381
+
382
+ pkt.pkt_id = rdr.u16();
383
+ if (5 <= pkt.mqtt_level)
384
+ pkt.props = rdr.props();
385
+
386
+ let answers = pkt.answers = [];
387
+ while (rdr.has_more())
388
+ answers.push(
389
+ rdr.reason(pkt.type) );
390
+
391
+ return pkt }
392
+ }
393
+
443
394
  function mqtt_encode_unsubscribe(ns, mqtt_writer) {
444
395
  return ns.unsubscribe = ( mqtt_level, pkt ) => {
445
- let wrt = mqtt_writer.of(pkt);
396
+ let wrt = mqtt_writer.for(pkt);
446
397
 
447
398
  wrt.u16(pkt.pkt_id);
448
399
  if (5 <= mqtt_level)
@@ -460,9 +411,14 @@ function mqtt_encode_pingxxx(ns) {
460
411
  ns.pingresp = () => new Uint8Array([ 0xd0, 0 ]);
461
412
  }
462
413
 
414
+
415
+ function mqtt_decode_pingxxx(ns) {
416
+ return ns[0xc] = ns[0xd] = pkt => pkt
417
+ }
418
+
463
419
  function mqtt_encode_disconnect(ns, mqtt_writer) {
464
420
  return ns.disconnect = ( mqtt_level, pkt ) => {
465
- let wrt = mqtt_writer.of(pkt);
421
+ let wrt = mqtt_writer.for(pkt);
466
422
 
467
423
  if (pkt && 5 <= mqtt_level) {
468
424
  if (pkt.reason || pkt.props) {
@@ -475,15 +431,25 @@ function mqtt_encode_disconnect(ns, mqtt_writer) {
475
431
  }
476
432
  }
477
433
 
478
- // not a v4 packet: import { mqtt_encode_auth } from './encode/auth.js'
434
+
435
+ function mqtt_decode_disconnect(ns, mqtt_reader) {
436
+ return ns[0xe] = (pkt, u8_body) => {
437
+ if (u8_body && 5 <= pkt.mqtt_level) {
438
+ let rdr = mqtt_reader.for(pkt, u8_body);
439
+ pkt.reason = rdr.reason(pkt.type);
440
+ pkt.props = rdr.props();
441
+ }
442
+ return pkt }
443
+ }
444
+
445
+ // not a v4 packet: import { mqtt_encode_auth, mqtt_decode_auth } from './pkt/auth.js'
479
446
 
480
447
 
481
448
  const mqtt_decode_v4 = [
482
449
  mqtt_decode_connack,
483
450
  mqtt_decode_publish,
484
451
  mqtt_decode_puback,
485
- mqtt_decode_suback,
486
- mqtt_decode_unsuback,
452
+ mqtt_decode_xxsuback,
487
453
  mqtt_decode_pingxxx,
488
454
  mqtt_decode_disconnect,
489
455
  ];
@@ -499,13 +465,6 @@ const mqtt_encode_v4 = [
499
465
  mqtt_encode_disconnect,
500
466
  ];
501
467
 
502
- const mqtt_reader_v4 = /* #__PURE__ */
503
- mqtt_reader_info(
504
- mqtt_reader_v4$1,
505
- _connack_v4,
506
- _suback_v4,
507
- _unsuback_v4,
508
- );
509
468
 
510
469
  const mqtt_opts_v4 =
511
470
  { decode_fns: mqtt_decode_v4,
@@ -598,7 +557,10 @@ const with_topic_router = mqtt_topic_router =>
598
557
  // alias: unsub_topic
599
558
  unsubscribe_topic(topic_route, ...args) {
600
559
  let router = this.router;
601
- router.remove(topic_route, true);
560
+
561
+ let fn = args.at(-1)?.call ? args.pop() : null;
562
+ router.remove(topic_route, true, fn);
563
+
602
564
  let topic = router.mqtt_topic(topic_route);
603
565
  return this.unsubscribe(topic, ...args ) }// topic_prefix
604
566
 
@@ -651,34 +613,38 @@ function mqtt_topic_path_router() {
651
613
  if (fn) {throw new TypeError()}
652
614
  fn = _ignore;}
653
615
 
654
- let rte = parse(as_topic_path(topic_route));
655
-
656
- rte.key = topic_route;
657
- rte.tgt = fn;
658
- pri_lsts[priority ? 0 : 1].push(rte);
616
+ let route = parse(as_topic_path(topic_route));
617
+ route.topic = topic_route;
618
+ route.tgt = fn;
619
+ pri_lsts[priority ? 0 : 1].push(route);
659
620
  return this}
660
621
 
661
- , remove(topic_route, priority) {
662
- let lst = pri_lsts[priority ? 0 : 1];
663
- return _route_remove([lst], topic_route)}
622
+ , remove(query, ...args) {
623
+ let lst = pri_lsts;
624
+ if ('boolean' === typeof args[0]) {
625
+ lst = [pri_lsts[args.shift() ? 0 : 1]];}
626
+
627
+ if ('string' === typeof query) {
628
+ query ={topic: query, tgt: args.pop()}; }
629
+ return _route_remove(lst, query)}
664
630
 
665
631
  , clear(priority) {
666
- pri_lsts[priority ? 0 : 1] = [];
667
632
  if (null == priority) {
668
- pri_lsts[1] = []; } }// null clears both lists
633
+ pri_lsts = [[],[]]; }// null clears both lists
634
+ else {
635
+ pri_lsts[priority ? 0 : 1] = [];} }
669
636
 
670
637
  , async invoke(pkt, ctx) {
671
638
  ctx.idx = 0;
672
639
  ctx.rm = rm;
673
640
 
674
- for (let [fn, params] of find(pkt.topic)) {
641
+ for (let [fn, params, route] of find(pkt.topic)) {
675
642
  let res = await fn(pkt, params, ctx);
676
643
 
677
644
  if (rm === res) {
678
- _route_remove(pri_lsts, fn);}
645
+ _route_remove(pri_lsts, route);}
679
646
 
680
- if (ctx.done) {
681
- break}
647
+ if (ctx.done) {break}
682
648
  else ctx.idx++;}
683
649
 
684
650
  if (1 === pkt.qos) {
@@ -688,70 +654,68 @@ function mqtt_topic_path_router() {
688
654
  function * _routes_iter(all_route_lists, topic) {
689
655
  topic = topic.replace(/^[\/]*/, '/'); // ensure '/' prefix for regexparam library
690
656
  for (let route_list of all_route_lists) {
691
- for (let {keys, pattern, tgt} of route_list) {
692
- let match = pattern.exec(topic);
657
+ for (let route of route_list) {
658
+ let match = route.pattern.exec(topic);
693
659
  if (match) {
694
- let params = keys
695
- ? keys.reduce(
660
+ let params = route.keys
661
+ ? route.keys.reduce(
696
662
  (o, k, i) => (o[k] = match[1+i], o)
697
663
  , {})
698
664
  : match.groups ?? match;
699
- yield [tgt, params];} } } }
665
+ yield [route.tgt, params, route];} } } }
700
666
 
701
667
 
702
668
  function _route_remove(all_route_lists, query) {
703
- let fn_match = route =>(
704
- route===query
705
- || route.tgt===query
706
- || route.key===query);
669
+ let ans = false;
707
670
  for (let lst of all_route_lists) {
708
- let i = lst.findIndex(fn_match);
709
- if (0 <= i) {
710
- lst.splice(i,1);
711
- return true} }
712
- return false}
713
-
714
- /*
715
- export function decode_varint_loop(u8, i=0) {
716
- let i0 = i
717
- let shift = 0, n = (u8[i] & 0x7f)
718
- while ( 0x80 & u8[i++] )
719
- n |= (u8[i] & 0x7f) << (shift += 7)
720
-
721
- return [n, i, i0]
722
- }
723
- */
724
-
725
-
726
- function decode_varint(u8, i=0) {
727
- let i0 = i;
728
- // unrolled for a max of 4 chains
729
- let n = (u8[i] & 0x7f) << 0;
730
- if ( 0x80 & u8[i++] ) {
731
- n |= (u8[i] & 0x7f) << 7;
732
- if ( 0x80 & u8[i++] ) {
733
- n |= (u8[i] & 0x7f) << 14;
734
- if ( 0x80 & u8[i++] ) {
735
- n |= (u8[i] & 0x7f) << 21;
736
- }
737
- }
738
- }
739
- return [n, i, i0]
671
+ let idx_tip = 0;
672
+ for (let route of lst) {
673
+ // skip matching routes to remove from compacted list
674
+ if (route === query) continue
675
+ if (route.topic === query.topic) {
676
+ if (null == query.tgt) continue
677
+ if (route.tgt === query.tgt) continue}
678
+
679
+ lst[idx_tip++] = route;}
680
+
681
+ // truncate remaining list
682
+ if (lst.splice(idx_tip).length)
683
+ ans = true;}
684
+
685
+ return ans}
686
+
687
+ function decode_varint(u8, i0=0, invalid) {
688
+ let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
689
+ for(; b & 0x80;)
690
+ n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
691
+
692
+ return (u8.length < i)
693
+ ? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
694
+ : [n, i, i0] // successful value
740
695
  }
741
696
 
742
697
  function mqtt_raw_dispatch(opt) {
743
- let u8 = new Uint8Array(0);
698
+ let u8 = new Uint8Array(0), len_tip=0;
744
699
  return u8_buf => {
745
700
  u8 = 0 === u8.byteLength
746
701
  ? u8_buf : _u8_join(u8, u8_buf);
747
702
 
748
703
  let res = [];
749
- while (1) {
750
- let [len_body, len_vh] = decode_varint(u8, 1);
751
- let len_pkt = len_body + len_vh;
752
704
 
753
- if ( u8.byteLength < len_pkt )
754
- return res
705
+ // wait for at least len_tip bytes for next (tip) message
706
+ while ( u8.byteLength >= len_tip ) {
707
+
708
+ // if varint is incomplete, return len_body=NaN
709
+ let [len_body, len_vh] = decode_varint(u8, 1, NaN);
710
+ let len_pkt = len_body + len_vh; // may be NaN
711
+
712
+ if (!( len_pkt <= u8.byteLength )) {
713
+ // incomplete packet cases:
714
+ // - len_pkt is less than available bytes
715
+ // - len_pkt is NaN from decode_varint() due to lack of data
716
+ len_tip = len_pkt || 0; // 0 when NaN
717
+ break
718
+ }
755
719
 
756
720
  let b0 = u8[0];
757
721
  let u8_body = 0 === len_body ? null
@@ -763,6 +727,8 @@ function mqtt_raw_dispatch(opt) {
763
727
  if (null != pkt)
764
728
  res.push( pkt );
765
729
  }
730
+
731
+ return res
766
732
  }
767
733
  }
768
734
 
@@ -773,16 +739,17 @@ function _u8_join(a, b) {
773
739
  return r
774
740
  }
775
741
 
776
- const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
742
+ const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
743
+
744
+
745
+ function mqtt_pkt_ctx(mqtt_level, opts, pkt_api=opts.pkt_ctx) {
746
+ let _as_pkt_ctx = pkt_api => ({
747
+ __proto__: pkt_api,
748
+ get hdr() { return this.b0 & 0xf },
749
+ get id() { return this.b0 >>> 4 },
750
+ get type() { return _pkt_types[this.b0 >>> 4] },
751
+ mqtt_level });
777
752
 
778
- function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
779
- pkt_ctx = {
780
- __proto__: pkt_ctx || opts.pkt_ctx,
781
- mqtt_level,
782
- get hdr() { return this.b0 & 0xf },
783
- get id() { return this.b0 >>> 4 },
784
- get type() { return _pkt_types[this.b0 >>> 4] },
785
- };
786
753
 
787
754
  let op, _decode_by_id=[], _encode_by_type={};
788
755
  for (op of opts.encode_fns)
@@ -791,10 +758,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
791
758
  op(_decode_by_id, opts.mqtt_reader);
792
759
 
793
760
  return {
794
- pkt_ctx,
761
+ pkt_api, pkt_ctx: _as_pkt_ctx(pkt_api),
795
762
 
796
- encode_pkt(type, pkt) {
797
- return _encode_by_type[type]( mqtt_level, pkt ) },
763
+ encode_pkt: (type, pkt) =>
764
+ _encode_by_type[type]( mqtt_level, pkt ),
798
765
 
799
766
  decode_pkt(b0, u8_body) {
800
767
  if (b0.map) // Uint8Array in first arg
@@ -803,12 +770,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
803
770
  let fn_decode = _decode_by_id[b0>>>4] || _decode_by_id[0];
804
771
  return fn_decode?.({__proto__: this.pkt_ctx, b0}, u8_body) },
805
772
 
806
- mqtt_stream() {
807
- let self = { __proto__: this, pkt_ctx: { __proto__: pkt_ctx } };
808
- self.pkt_ctx._base_ = self.pkt_ctx;
773
+ mqtt_stream(pkt_api=this.pkt_api) {
774
+ let self = { __proto__: this, pkt_ctx: _as_pkt_ctx(pkt_api) };
809
775
  self.decode = mqtt_raw_dispatch(self);
810
- return self
811
- },
776
+ return self },
812
777
  }
813
778
  }
814
779
 
@@ -1332,7 +1297,7 @@ class MQTTCore extends MQTTBase {
1332
1297
 
1333
1298
  return this} }
1334
1299
 
1335
- const version = '0.6.2';
1300
+ const version = '0.6.4';
1336
1301
 
1337
1302
  const MQTTClient_v4 = /* #__PURE__ */
1338
1303
  with_topic_path_router(