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/deno/index.js CHANGED
@@ -1,39 +1,18 @@
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]
19
- }
20
- */
21
-
22
-
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]
13
+ return (u8.length < i)
14
+ ? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
15
+ : [n, i, i0] // successful value
37
16
  }
38
17
 
39
18
  function add_mqtt_props(mqtt_props, entries) {
@@ -80,19 +59,18 @@ const init_mqtt_props = () =>
80
59
  const mqtt_props = /* #__PURE__ */
81
60
  init_mqtt_props();
82
61
 
83
- class U8_Reason extends Number {
84
- static of(v, pkt_kind, by_kind) {
85
- let self = new this(v);
86
- self.reason = by_kind?.[pkt_kind]?.get(v) || pkt_kind;
87
- 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}`;
88
66
  }
89
67
  }
90
68
 
91
69
  class mqtt_reader_v4 {
92
- static of(buf) { return this.prototype.of(buf) }
93
- of(buf) {
70
+ static for(pkt, u8_body) { return new this().of(u8_body, {pkt}) }
71
+ of(buf, opt) {
94
72
  let step = (width, k) => (k=0|step.k, step.k=k+width, k);
95
- return {__proto__: this, buf, step}
73
+ return {__proto__: this, buf, step, ...opt}
96
74
  }
97
75
 
98
76
  has_more() {
@@ -135,7 +113,7 @@ class mqtt_reader_v4 {
135
113
  reason(pkt_kind) {
136
114
  let v = this.buf[this.step(1)];
137
115
  if (null != v)
138
- return U8_Reason.of(v, pkt_kind, this._reasons_by)
116
+ return new mqtt_reason(v, this._reason_for?.(v, pkt_kind))
139
117
  }
140
118
 
141
119
  flush() {
@@ -149,7 +127,7 @@ class mqtt_reader_v4 {
149
127
  let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
150
128
  props() {
151
129
  let {buf, step} = this;
152
- let [n, vi, vi0] = decode_varint$1(buf, step.k|0);
130
+ let [n, vi, vi0] = decode_varint$1(buf, step.k|0, 0);
153
131
  step(n + vi - vi0);
154
132
  if (0 === n) return null
155
133
 
@@ -158,7 +136,7 @@ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
158
136
  let v, pk = fork.u8(), pt = mqtt_props.get( pk );
159
137
  if (!pt) {
160
138
  res._unknown_ = pk;
161
- this.warn(`unknown property: ${pk}`);
139
+ this.warn?.(`unknown property: ${pk}`);
162
140
  break
163
141
  }
164
142
 
@@ -178,8 +156,6 @@ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
178
156
  return vec
179
157
  }
180
158
 
181
- warn(msg) { console.warn('[u8-mqtt-packet] '+msg); }
182
-
183
159
  /*
184
160
  vbuf() {
185
161
  let {buf, step} = this
@@ -191,28 +167,99 @@ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
191
167
  */
192
168
  };
193
169
 
194
- function mqtt_reader_info(mqtt_reader, ... info_fn_list) {
195
- mqtt_reader = class extends mqtt_reader {
196
- static reasons(pkt_type, ...reason_entries) {
197
- let proto = this.prototype;
198
- proto._reasons_by = {... proto._reasons_by};
199
-
200
- let lut = (proto._reasons_by[pkt_type] ||= new Map());
201
- for (let [u8, reason] of reason_entries)
202
- lut.set( u8, reason );
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);
203
173
 
204
- 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)
205
177
  }
206
- };
178
+ warn(msg) {
179
+ let pkt = this.pkt;
180
+ pkt.warn ? pkt.warn(msg, pkt)
181
+ : console.warn('[u8-mqtt-packet] '+msg);
182
+ }
183
+ }
184
+ }
207
185
 
208
- for (let fn_info of info_fn_list)
209
- fn_info(mqtt_reader);
210
186
 
211
- return mqtt_reader
212
- }
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);
213
260
 
214
261
  class mqtt_writer_v4 {
215
- static of() { return this.prototype.of() }
262
+ static for(pkt) { return new this().of() }
216
263
  of() { return {__proto__: this, $:[]} }
217
264
 
218
265
  static init() { return this }
@@ -326,245 +373,6 @@ class mqtt_writer_v5 extends mqtt_writer_v4 {
326
373
  }
327
374
  }
328
375
 
329
- function mqtt_decode_connack(ns, mqtt_reader) {
330
- class _connack_flags_ extends Number {
331
- get session_present() { return this & 0x01 !== 0 }
332
- }
333
-
334
- return ns[0x2] = (pkt, u8_body) => {
335
- let rdr = mqtt_reader.of(u8_body);
336
-
337
- pkt.flags =
338
- rdr.flags(_connack_flags_);
339
-
340
- pkt.reason = rdr.reason(pkt.type);
341
- if (5 <= pkt.mqtt_level)
342
- pkt.props = rdr.props();
343
- return pkt }
344
- }
345
-
346
-
347
- function _connack_v4(mqtt_reader) {
348
- mqtt_reader.reasons('connack',
349
- // MQTT 3.1.1
350
- [ 0x00, 'Success'],
351
- [ 0x01, 'Connection refused, unacceptable protocol version'],
352
- [ 0x02, 'Connection refused, identifier rejected'],
353
- [ 0x03, 'Connection refused, server unavailable'],
354
- [ 0x04, 'Connection refused, bad user name or password'],
355
- [ 0x05, 'Connection refused, not authorized'],
356
- );
357
- }
358
-
359
- function _connack_v5(mqtt_reader) {
360
- _connack_v4(mqtt_reader);
361
-
362
- mqtt_reader.reasons('connack',
363
- // MQTT 5.0
364
- [ 0x81, 'Malformed Packet'],
365
- [ 0x82, 'Protocol Error'],
366
- [ 0x83, 'Implementation specific error'],
367
- [ 0x84, 'Unsupported Protocol Version'],
368
- [ 0x85, 'Client Identifier not valid'],
369
- [ 0x86, 'Bad User Name or Password'],
370
- [ 0x87, 'Not authorized'],
371
- [ 0x88, 'Server unavailable'],
372
- [ 0x89, 'Server busy'],
373
- [ 0x8A, 'Banned'],
374
- [ 0x8C, 'Bad authentication method'],
375
- [ 0x90, 'Topic Name invalid'],
376
- [ 0x95, 'Packet too large'],
377
- [ 0x97, 'Quota exceeded'],
378
- [ 0x99, 'Payload format invalid'],
379
- [ 0x9A, 'Retain not supported'],
380
- [ 0x9B, 'QoS not supported'],
381
- [ 0x9C, 'Use another server'],
382
- [ 0x9D, 'Server moved'],
383
- [ 0x9F, 'Connection rate exceeded'],
384
- );
385
- }
386
-
387
- function mqtt_decode_publish(ns, mqtt_reader) {
388
- return ns[0x3] = (pkt, u8_body) => {
389
- let {hdr} = pkt;
390
- pkt.dup = Boolean(hdr & 0x8);
391
- pkt.retain = Boolean(hdr & 0x1);
392
- let qos = pkt.qos = (hdr>>1) & 0x3;
393
-
394
- let rdr = mqtt_reader.of(u8_body);
395
- pkt.topic = rdr.utf8();
396
- if (0 !== qos)
397
- pkt.pkt_id = rdr.u16();
398
-
399
- if (5 <= pkt.mqtt_level)
400
- pkt.props = rdr.props();
401
-
402
- pkt.payload = rdr.flush();
403
- return pkt }
404
- }
405
-
406
- function mqtt_decode_puback(ns, mqtt_reader) {
407
- return ns[0x4] = (pkt, u8_body) => {
408
- let rdr = mqtt_reader.of(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
-
419
-
420
- function _puback_v5(mqtt_reader) {
421
- mqtt_reader.reasons('puback',
422
- // MQTT 5.0
423
- [ 0x00, 'Success'],
424
- [ 0x10, 'No matching subscribers'],
425
- [ 0x80, 'Unspecified error'],
426
- [ 0x83, 'Implementation specific error'],
427
- [ 0x87, 'Not authorized'],
428
- [ 0x90, 'Topic Name invalid'],
429
- [ 0x91, 'Packet identifier in use'],
430
- [ 0x97, 'Quota exceeded'],
431
- [ 0x99, 'Payload format invalid'],
432
- );
433
- }
434
-
435
- function _mqtt_decode_suback(mqtt_reader) {
436
- return (pkt, u8_body) => {
437
- let rdr = mqtt_reader.of(u8_body);
438
-
439
- pkt.pkt_id = rdr.u16();
440
- if (5 <= pkt.mqtt_level)
441
- pkt.props = rdr.props();
442
-
443
- let answers = pkt.answers = [];
444
- while (rdr.has_more())
445
- answers.push(
446
- rdr.reason(pkt.type) );
447
-
448
- return pkt }
449
- }
450
-
451
- function mqtt_decode_suback(ns, mqtt_reader) {
452
- return ns[0x9] = _mqtt_decode_suback(mqtt_reader)
453
- }
454
-
455
- function _suback_v4(mqtt_reader) {
456
- mqtt_reader.reasons('suback',
457
- // MQTT 3.1.1
458
- [ 0x00, 'Granted QoS 0'],
459
- [ 0x01, 'Granted QoS 1'],
460
- [ 0x02, 'Granted QoS 2'],
461
- );
462
- }
463
-
464
- function _suback_v5(mqtt_reader) {
465
- _suback_v4(mqtt_reader);
466
-
467
- mqtt_reader.reasons('suback',
468
- // MQTT 5.0
469
- [ 0x80, 'Unspecified error'],
470
- [ 0x83, 'Implementation specific error'],
471
- [ 0x87, 'Not authorized'],
472
- [ 0x8F, 'Topic Filter invalid'],
473
- [ 0x91, 'Packet Identifier in use'],
474
- [ 0x97, 'Quota exceeded'],
475
- [ 0x9E, 'Shared Subscriptions not supported'],
476
- [ 0xA1, 'Subscription Identifiers not supported'],
477
- [ 0xA2, 'Wildcard Subscriptions not supported'],
478
- );
479
- }
480
-
481
- function mqtt_decode_unsuback(ns, mqtt_reader) {
482
- return ns[0xb] = _mqtt_decode_suback(mqtt_reader)
483
- }
484
-
485
- function _unsuback_v4(mqtt_reader) {
486
- mqtt_reader.reasons('unsuback',
487
- // MQTT 3.1.1
488
- [ 0x00, 'Success'],
489
- [ 0x11, 'No subscription existed'],
490
- [ 0x80, 'Unspecified error'],
491
- [ 0x83, 'Implementation specific error'],
492
- [ 0x87, 'Not authorized'],
493
- [ 0x8F, 'Topic Filter invalid'],
494
- [ 0x91, 'Packet Identifier in use'],
495
- );
496
- }
497
-
498
- function mqtt_decode_pingxxx(ns) {
499
- return ns[0xc] = ns[0xd] = pkt => pkt
500
- }
501
-
502
- function mqtt_decode_disconnect(ns, mqtt_reader) {
503
- return ns[0xe] = (pkt, u8_body) => {
504
- if (u8_body && 5 <= pkt.mqtt_level) {
505
- let rdr = mqtt_reader.of(u8_body);
506
- pkt.reason = rdr.reason(pkt.type);
507
- pkt.props = rdr.props();
508
- }
509
- return pkt }
510
- }
511
-
512
-
513
- function _disconnect_v5(mqtt_reader) {
514
- mqtt_reader.reasons('disconnect',
515
- // MQTT 5.0
516
- [ 0x00, 'Normal disconnection'],
517
- [ 0x04, 'Disconnect with Will Message'],
518
- [ 0x80, 'Unspecified error'],
519
- [ 0x81, 'Malformed Packet'],
520
- [ 0x82, 'Protocol Error'],
521
- [ 0x83, 'Implementation specific error'],
522
- [ 0x87, 'Not authorized'],
523
- [ 0x89, 'Server busy'],
524
- [ 0x8B, 'Server shutting down'],
525
- [ 0x8D, 'Keep Alive timeout'],
526
- [ 0x8E, 'Session taken over'],
527
- [ 0x8F, 'Topic Filter invalid'],
528
- [ 0x90, 'Topic Name invalid'],
529
- [ 0x93, 'Receive Maximum exceeded'],
530
- [ 0x94, 'Topic Alias invalid'],
531
- [ 0x95, 'Packet too large'],
532
- [ 0x96, 'Message rate too high'],
533
- [ 0x97, 'Quota exceeded'],
534
- [ 0x98, 'Administrative action'],
535
- [ 0x99, 'Payload format invalid'],
536
- [ 0x9A, 'Retain not supported'],
537
- [ 0x9B, 'QoS not supported'],
538
- [ 0x9C, 'Use another server'],
539
- [ 0x9D, 'Server moved'],
540
- [ 0x9E, 'Shared Subscriptions not supported'],
541
- [ 0x9F, 'Connection rate exceeded'],
542
- [ 0xA0, 'Maximum connect time'],
543
- [ 0xA1, 'Subscription Identifiers not supported'],
544
- [ 0xA2, 'Wildcard Subscriptions not supported'],
545
- );
546
- }
547
-
548
- function mqtt_decode_auth(ns, mqtt_reader) {
549
- return ns[0xf] = (pkt, u8_body) => {
550
- if ( 5 <= pkt.mqtt_level ) {
551
- let rdr = mqtt_reader.of(u8_body);
552
- pkt.reason = rdr.reason(pkt.type);
553
- pkt.props = rdr.props();
554
- }
555
- return pkt }
556
- }
557
-
558
-
559
- function _auth_v5(mqtt_reader) {
560
- mqtt_reader.reasons('auth',
561
- // MQTT 5.0
562
- [ 0x00, 'Success' ],
563
- [ 0x18, 'Continue authentication' ],
564
- [ 0x19, 'Re-authenticate' ],
565
- );
566
- }
567
-
568
376
  function mqtt_encode_connect(ns, mqtt_writer) {
569
377
  const _c_mqtt_proto = new Uint8Array([
570
378
  0, 4, 0x4d, 0x51, 0x54, 0x54 ]);
@@ -583,7 +391,7 @@ function mqtt_encode_connect(ns, mqtt_writer) {
583
391
  | ( will.retain ? 0x20 : 0 );
584
392
 
585
393
  return ns.connect = ( mqtt_level, pkt ) => {
586
- let wrt = mqtt_writer.of(pkt);
394
+ let wrt = mqtt_writer.for(pkt);
587
395
 
588
396
  wrt.push(_c_mqtt_proto);
589
397
  wrt.u8( mqtt_level );
@@ -621,10 +429,27 @@ function mqtt_encode_connect(ns, mqtt_writer) {
621
429
  }
622
430
  }
623
431
 
432
+ function mqtt_decode_connack(ns, mqtt_reader) {
433
+ class _connack_flags_ extends Number {
434
+ get session_present() { return this & 0x01 !== 0 }
435
+ }
436
+
437
+ return ns[0x2] = (pkt, u8_body) => {
438
+ let rdr = mqtt_reader.for(pkt, u8_body);
439
+
440
+ pkt.flags =
441
+ rdr.flags(_connack_flags_);
442
+
443
+ pkt.reason = rdr.reason(pkt.type);
444
+ if (5 <= pkt.mqtt_level)
445
+ pkt.props = rdr.props();
446
+ return pkt }
447
+ }
448
+
624
449
  function mqtt_encode_publish(ns, mqtt_writer) {
625
450
  return ns.publish = ( mqtt_level, pkt ) => {
626
451
  let qos = (pkt.qos & 0x3) << 1;
627
- let wrt = mqtt_writer.of(pkt);
452
+ let wrt = mqtt_writer.for(pkt);
628
453
 
629
454
  wrt.utf8(pkt.topic);
630
455
  if (0 !== qos)
@@ -642,9 +467,28 @@ function mqtt_encode_publish(ns, mqtt_writer) {
642
467
  }
643
468
  }
644
469
 
470
+ function mqtt_decode_publish(ns, mqtt_reader) {
471
+ return ns[0x3] = (pkt, u8_body) => {
472
+ let {hdr} = pkt;
473
+ pkt.dup = Boolean(hdr & 0x8);
474
+ pkt.retain = Boolean(hdr & 0x1);
475
+ let qos = pkt.qos = (hdr>>1) & 0x3;
476
+
477
+ let rdr = mqtt_reader.for(pkt, u8_body);
478
+ pkt.topic = rdr.utf8();
479
+ if (0 !== qos)
480
+ pkt.pkt_id = rdr.u16();
481
+
482
+ if (5 <= pkt.mqtt_level)
483
+ pkt.props = rdr.props();
484
+
485
+ pkt.payload = rdr.flush();
486
+ return pkt }
487
+ }
488
+
645
489
  function mqtt_encode_puback(ns, mqtt_writer) {
646
490
  return ns.puback = ( mqtt_level, pkt ) => {
647
- let wrt = mqtt_writer.of(pkt);
491
+ let wrt = mqtt_writer.for(pkt);
648
492
 
649
493
  wrt.u16(pkt.pkt_id);
650
494
  if (5 <= mqtt_level) {
@@ -656,6 +500,20 @@ function mqtt_encode_puback(ns, mqtt_writer) {
656
500
  }
657
501
  }
658
502
 
503
+
504
+ function mqtt_decode_puback(ns, mqtt_reader) {
505
+ return ns[0x4] = (pkt, u8_body) => {
506
+ let rdr = mqtt_reader.for(pkt, u8_body);
507
+
508
+ pkt.pkt_id = rdr.u16();
509
+ if (5 <= pkt.mqtt_level) {
510
+ pkt.reason = rdr.reason(pkt.type);
511
+ pkt.props = rdr.props();
512
+ }
513
+
514
+ return pkt }
515
+ }
516
+
659
517
  function mqtt_encode_subscribe(ns, mqtt_writer) {
660
518
  const _enc_subscribe_flags = opts => 0
661
519
  | ( opts.qos & 0x3 )
@@ -663,7 +521,7 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
663
521
  | ( (opts.retain_handling & 0x3) << 2 );
664
522
 
665
523
  return ns.subscribe = ( mqtt_level, pkt ) => {
666
- let wrt = mqtt_writer.of(pkt);
524
+ let wrt = mqtt_writer.for(pkt);
667
525
 
668
526
  wrt.u16(pkt.pkt_id);
669
527
  if (5 <= mqtt_level)
@@ -689,9 +547,25 @@ function mqtt_encode_subscribe(ns, mqtt_writer) {
689
547
  }
690
548
  }
691
549
 
550
+ function mqtt_decode_xxsuback(ns, mqtt_reader) {
551
+ return ns[0x9] = ns[0xb] = (pkt, u8_body) => {
552
+ let rdr = mqtt_reader.for(pkt, u8_body);
553
+
554
+ pkt.pkt_id = rdr.u16();
555
+ if (5 <= pkt.mqtt_level)
556
+ pkt.props = rdr.props();
557
+
558
+ let answers = pkt.answers = [];
559
+ while (rdr.has_more())
560
+ answers.push(
561
+ rdr.reason(pkt.type) );
562
+
563
+ return pkt }
564
+ }
565
+
692
566
  function mqtt_encode_unsubscribe(ns, mqtt_writer) {
693
567
  return ns.unsubscribe = ( mqtt_level, pkt ) => {
694
- let wrt = mqtt_writer.of(pkt);
568
+ let wrt = mqtt_writer.for(pkt);
695
569
 
696
570
  wrt.u16(pkt.pkt_id);
697
571
  if (5 <= mqtt_level)
@@ -709,9 +583,14 @@ function mqtt_encode_pingxxx(ns) {
709
583
  ns.pingresp = () => new Uint8Array([ 0xd0, 0 ]);
710
584
  }
711
585
 
586
+
587
+ function mqtt_decode_pingxxx(ns) {
588
+ return ns[0xc] = ns[0xd] = pkt => pkt
589
+ }
590
+
712
591
  function mqtt_encode_disconnect(ns, mqtt_writer) {
713
592
  return ns.disconnect = ( mqtt_level, pkt ) => {
714
- let wrt = mqtt_writer.of(pkt);
593
+ let wrt = mqtt_writer.for(pkt);
715
594
 
716
595
  if (pkt && 5 <= mqtt_level) {
717
596
  if (pkt.reason || pkt.props) {
@@ -724,6 +603,17 @@ function mqtt_encode_disconnect(ns, mqtt_writer) {
724
603
  }
725
604
  }
726
605
 
606
+
607
+ function mqtt_decode_disconnect(ns, mqtt_reader) {
608
+ return ns[0xe] = (pkt, u8_body) => {
609
+ if (u8_body && 5 <= pkt.mqtt_level) {
610
+ let rdr = mqtt_reader.for(pkt, u8_body);
611
+ pkt.reason = rdr.reason(pkt.type);
612
+ pkt.props = rdr.props();
613
+ }
614
+ return pkt }
615
+ }
616
+
727
617
  function mqtt_encode_auth(ns, mqtt_writer) {
728
618
  return ns.auth = ( mqtt_level, pkt ) => {
729
619
  if (5 > mqtt_level)
@@ -738,12 +628,21 @@ function mqtt_encode_auth(ns, mqtt_writer) {
738
628
  }
739
629
  }
740
630
 
631
+ function mqtt_decode_auth(ns, mqtt_reader) {
632
+ return ns[0xf] = (pkt, u8_body) => {
633
+ if ( 5 <= pkt.mqtt_level ) {
634
+ let rdr = mqtt_reader.of(u8_body);
635
+ pkt.reason = rdr.reason(pkt.type);
636
+ pkt.props = rdr.props();
637
+ }
638
+ return pkt }
639
+ }
640
+
741
641
  const mqtt_decode_v5 = [
742
642
  mqtt_decode_connack,
743
643
  mqtt_decode_publish,
744
644
  mqtt_decode_puback,
745
- mqtt_decode_suback,
746
- mqtt_decode_unsuback,
645
+ mqtt_decode_xxsuback,
747
646
  mqtt_decode_pingxxx,
748
647
  mqtt_decode_disconnect,
749
648
  mqtt_decode_auth,
@@ -761,18 +660,6 @@ const mqtt_encode_v5 = [
761
660
  mqtt_encode_auth,
762
661
  ];
763
662
 
764
- const mqtt_reader_v5 = /* #__PURE__ */
765
- mqtt_reader_info(
766
- mqtt_reader_v5$1,
767
- _connack_v5,
768
- _puback_v5,
769
- _suback_v5,
770
- _unsuback_v4,
771
- _disconnect_v5,
772
- _auth_v5,
773
- );
774
-
775
-
776
663
  const mqtt_opts_v5 =
777
664
  { decode_fns: mqtt_decode_v5,
778
665
  mqtt_reader: mqtt_reader_v5,
@@ -864,7 +751,10 @@ const with_topic_router = mqtt_topic_router =>
864
751
  // alias: unsub_topic
865
752
  unsubscribe_topic(topic_route, ...args) {
866
753
  let router = this.router;
867
- router.remove(topic_route, true);
754
+
755
+ let fn = args.at(-1)?.call ? args.pop() : null;
756
+ router.remove(topic_route, true, fn);
757
+
868
758
  let topic = router.mqtt_topic(topic_route);
869
759
  return this.unsubscribe(topic, ...args ) }// topic_prefix
870
760
 
@@ -917,34 +807,38 @@ function mqtt_topic_path_router() {
917
807
  if (fn) {throw new TypeError()}
918
808
  fn = _ignore;}
919
809
 
920
- let rte = parse(as_topic_path(topic_route));
921
-
922
- rte.key = topic_route;
923
- rte.tgt = fn;
924
- pri_lsts[priority ? 0 : 1].push(rte);
810
+ let route = parse(as_topic_path(topic_route));
811
+ route.topic = topic_route;
812
+ route.tgt = fn;
813
+ pri_lsts[priority ? 0 : 1].push(route);
925
814
  return this}
926
815
 
927
- , remove(topic_route, priority) {
928
- let lst = pri_lsts[priority ? 0 : 1];
929
- return _route_remove([lst], topic_route)}
816
+ , remove(query, ...args) {
817
+ let lst = pri_lsts;
818
+ if ('boolean' === typeof args[0]) {
819
+ lst = [pri_lsts[args.shift() ? 0 : 1]];}
820
+
821
+ if ('string' === typeof query) {
822
+ query ={topic: query, tgt: args.pop()}; }
823
+ return _route_remove(lst, query)}
930
824
 
931
825
  , clear(priority) {
932
- pri_lsts[priority ? 0 : 1] = [];
933
826
  if (null == priority) {
934
- pri_lsts[1] = []; } }// null clears both lists
827
+ pri_lsts = [[],[]]; }// null clears both lists
828
+ else {
829
+ pri_lsts[priority ? 0 : 1] = [];} }
935
830
 
936
831
  , async invoke(pkt, ctx) {
937
832
  ctx.idx = 0;
938
833
  ctx.rm = rm;
939
834
 
940
- for (let [fn, params] of find(pkt.topic)) {
835
+ for (let [fn, params, route] of find(pkt.topic)) {
941
836
  let res = await fn(pkt, params, ctx);
942
837
 
943
838
  if (rm === res) {
944
- _route_remove(pri_lsts, fn);}
839
+ _route_remove(pri_lsts, route);}
945
840
 
946
- if (ctx.done) {
947
- break}
841
+ if (ctx.done) {break}
948
842
  else ctx.idx++;}
949
843
 
950
844
  if (1 === pkt.qos) {
@@ -954,70 +848,68 @@ function mqtt_topic_path_router() {
954
848
  function * _routes_iter(all_route_lists, topic) {
955
849
  topic = topic.replace(/^[\/]*/, '/'); // ensure '/' prefix for regexparam library
956
850
  for (let route_list of all_route_lists) {
957
- for (let {keys, pattern, tgt} of route_list) {
958
- let match = pattern.exec(topic);
851
+ for (let route of route_list) {
852
+ let match = route.pattern.exec(topic);
959
853
  if (match) {
960
- let params = keys
961
- ? keys.reduce(
854
+ let params = route.keys
855
+ ? route.keys.reduce(
962
856
  (o, k, i) => (o[k] = match[1+i], o)
963
857
  , {})
964
858
  : match.groups ?? match;
965
- yield [tgt, params];} } } }
859
+ yield [route.tgt, params, route];} } } }
966
860
 
967
861
 
968
862
  function _route_remove(all_route_lists, query) {
969
- let fn_match = route =>(
970
- route===query
971
- || route.tgt===query
972
- || route.key===query);
863
+ let ans = false;
973
864
  for (let lst of all_route_lists) {
974
- let i = lst.findIndex(fn_match);
975
- if (0 <= i) {
976
- lst.splice(i,1);
977
- return true} }
978
- return false}
979
-
980
- /*
981
- export function decode_varint_loop(u8, i=0) {
982
- let i0 = i
983
- let shift = 0, n = (u8[i] & 0x7f)
984
- while ( 0x80 & u8[i++] )
985
- n |= (u8[i] & 0x7f) << (shift += 7)
986
-
987
- return [n, i, i0]
988
- }
989
- */
990
-
991
-
992
- function decode_varint(u8, i=0) {
993
- let i0 = i;
994
- // unrolled for a max of 4 chains
995
- let n = (u8[i] & 0x7f) << 0;
996
- if ( 0x80 & u8[i++] ) {
997
- n |= (u8[i] & 0x7f) << 7;
998
- if ( 0x80 & u8[i++] ) {
999
- n |= (u8[i] & 0x7f) << 14;
1000
- if ( 0x80 & u8[i++] ) {
1001
- n |= (u8[i] & 0x7f) << 21;
1002
- }
1003
- }
1004
- }
1005
- return [n, i, i0]
865
+ let idx_tip = 0;
866
+ for (let route of lst) {
867
+ // skip matching routes to remove from compacted list
868
+ if (route === query) continue
869
+ if (route.topic === query.topic) {
870
+ if (null == query.tgt) continue
871
+ if (route.tgt === query.tgt) continue}
872
+
873
+ lst[idx_tip++] = route;}
874
+
875
+ // truncate remaining list
876
+ if (lst.splice(idx_tip).length)
877
+ ans = true;}
878
+
879
+ return ans}
880
+
881
+ function decode_varint(u8, i0=0, invalid) {
882
+ let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
883
+ for(; b & 0x80;)
884
+ n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
885
+
886
+ return (u8.length < i)
887
+ ? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
888
+ : [n, i, i0] // successful value
1006
889
  }
1007
890
 
1008
891
  function mqtt_raw_dispatch(opt) {
1009
- let u8 = new Uint8Array(0);
892
+ let u8 = new Uint8Array(0), len_tip=0;
1010
893
  return u8_buf => {
1011
894
  u8 = 0 === u8.byteLength
1012
895
  ? u8_buf : _u8_join(u8, u8_buf);
1013
896
 
1014
897
  let res = [];
1015
- while (1) {
1016
- let [len_body, len_vh] = decode_varint(u8, 1);
1017
- let len_pkt = len_body + len_vh;
1018
898
 
1019
- if ( u8.byteLength < len_pkt )
1020
- return res
899
+ // wait for at least len_tip bytes for next (tip) message
900
+ while ( u8.byteLength >= len_tip ) {
901
+
902
+ // if varint is incomplete, return len_body=NaN
903
+ let [len_body, len_vh] = decode_varint(u8, 1, NaN);
904
+ let len_pkt = len_body + len_vh; // may be NaN
905
+
906
+ if (!( len_pkt <= u8.byteLength )) {
907
+ // incomplete packet cases:
908
+ // - len_pkt is less than available bytes
909
+ // - len_pkt is NaN from decode_varint() due to lack of data
910
+ len_tip = len_pkt || 0; // 0 when NaN
911
+ break
912
+ }
1021
913
 
1022
914
  let b0 = u8[0];
1023
915
  let u8_body = 0 === len_body ? null
@@ -1029,6 +921,8 @@ function mqtt_raw_dispatch(opt) {
1029
921
  if (null != pkt)
1030
922
  res.push( pkt );
1031
923
  }
924
+
925
+ return res
1032
926
  }
1033
927
  }
1034
928
 
@@ -1039,16 +933,17 @@ function _u8_join(a, b) {
1039
933
  return r
1040
934
  }
1041
935
 
1042
- const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
936
+ const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
937
+
938
+
939
+ function mqtt_pkt_ctx(mqtt_level, opts, pkt_api=opts.pkt_ctx) {
940
+ let _as_pkt_ctx = pkt_api => ({
941
+ __proto__: pkt_api,
942
+ get hdr() { return this.b0 & 0xf },
943
+ get id() { return this.b0 >>> 4 },
944
+ get type() { return _pkt_types[this.b0 >>> 4] },
945
+ mqtt_level });
1043
946
 
1044
- function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
1045
- pkt_ctx = {
1046
- __proto__: pkt_ctx || opts.pkt_ctx,
1047
- mqtt_level,
1048
- get hdr() { return this.b0 & 0xf },
1049
- get id() { return this.b0 >>> 4 },
1050
- get type() { return _pkt_types[this.b0 >>> 4] },
1051
- };
1052
947
 
1053
948
  let op, _decode_by_id=[], _encode_by_type={};
1054
949
  for (op of opts.encode_fns)
@@ -1057,10 +952,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
1057
952
  op(_decode_by_id, opts.mqtt_reader);
1058
953
 
1059
954
  return {
1060
- pkt_ctx,
955
+ pkt_api, pkt_ctx: _as_pkt_ctx(pkt_api),
1061
956
 
1062
- encode_pkt(type, pkt) {
1063
- return _encode_by_type[type]( mqtt_level, pkt ) },
957
+ encode_pkt: (type, pkt) =>
958
+ _encode_by_type[type]( mqtt_level, pkt ),
1064
959
 
1065
960
  decode_pkt(b0, u8_body) {
1066
961
  if (b0.map) // Uint8Array in first arg
@@ -1069,12 +964,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
1069
964
  let fn_decode = _decode_by_id[b0>>>4] || _decode_by_id[0];
1070
965
  return fn_decode?.({__proto__: this.pkt_ctx, b0}, u8_body) },
1071
966
 
1072
- mqtt_stream() {
1073
- let self = { __proto__: this, pkt_ctx: { __proto__: pkt_ctx } };
1074
- self.pkt_ctx._base_ = self.pkt_ctx;
967
+ mqtt_stream(pkt_api=this.pkt_api) {
968
+ let self = { __proto__: this, pkt_ctx: _as_pkt_ctx(pkt_api) };
1075
969
  self.decode = mqtt_raw_dispatch(self);
1076
- return self
1077
- },
970
+ return self },
1078
971
  }
1079
972
  }
1080
973
 
@@ -1598,7 +1491,7 @@ class MQTTCore extends MQTTBase {
1598
1491
 
1599
1492
  return this} }
1600
1493
 
1601
- const version = '0.6.2-deno';
1494
+ const version = '0.6.4-deno';
1602
1495
 
1603
1496
  const MQTTClient_v4 = /* #__PURE__ */
1604
1497
  with_topic_path_router(