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
@@ -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
-
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
- }
17
+
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
-
42
- function init_mqtt_props() {
43
- let mqtt_props = new Map();
44
26
 
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};
200
-
201
- let lut = (proto._reasons_by[pkt_type] ||= new Map());
202
- for (let [u8, reason] of reason_entries)
203
- 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);
204
173
 
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)
206
177
  }
207
- };
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
+ }
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,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,65 +660,44 @@ 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,
779
666
  encode_fns: mqtt_encode_v5,
780
667
  mqtt_writer: mqtt_writer_v5, };
781
668
 
782
- /*
783
- export function decode_varint_loop(u8, i=0) {
784
- let i0 = i
785
- let shift = 0, n = (u8[i] & 0x7f)
786
- while ( 0x80 & u8[i++] )
787
- n |= (u8[i] & 0x7f) << (shift += 7)
669
+ function decode_varint(u8, i0=0, invalid) {
670
+ let shift=0, i=i0, b=u8[i++], n=(b & 0x7f);
671
+ for(; b & 0x80;)
672
+ n |= ((b=u8[i++]) & 0x7f) << (shift += 7);
788
673
 
789
- return [n, i, i0]
790
- }
791
- */
792
-
793
-
794
- function decode_varint(u8, i=0) {
795
- let i0 = i;
796
- // unrolled for a max of 4 chains
797
- let n = (u8[i] & 0x7f) << 0;
798
- if ( 0x80 & u8[i++] ) {
799
- n |= (u8[i] & 0x7f) << 7;
800
- if ( 0x80 & u8[i++] ) {
801
- n |= (u8[i] & 0x7f) << 14;
802
- if ( 0x80 & u8[i++] ) {
803
- n |= (u8[i] & 0x7f) << 21;
804
- }
805
- }
806
- }
807
- return [n, i, i0]
674
+ return (u8.length < i)
675
+ ? [invalid, i0, i0] // fail: insuffecient u8 bytes to decode
676
+ : [n, i, i0] // successful value
808
677
  }
809
678
 
810
679
  function mqtt_raw_dispatch(opt) {
811
- let u8 = new Uint8Array(0);
680
+ let u8 = new Uint8Array(0), len_tip=0;
812
681
  return u8_buf => {
813
682
  u8 = 0 === u8.byteLength
814
683
  ? u8_buf : _u8_join(u8, u8_buf);
815
684
 
816
685
  let res = [];
817
- while (1) {
818
- let [len_body, len_vh] = decode_varint(u8, 1);
819
- let len_pkt = len_body + len_vh;
820
686
 
821
- if ( u8.byteLength < len_pkt )
822
- return res
687
+ // wait for at least len_tip bytes for next (tip) message
688
+ while ( u8.byteLength >= len_tip ) {
689
+
690
+ // if varint is incomplete, return len_body=NaN
691
+ let [len_body, len_vh] = decode_varint(u8, 1, NaN);
692
+ let len_pkt = len_body + len_vh; // may be NaN
693
+
694
+ if (!( len_pkt <= u8.byteLength )) {
695
+ // incomplete packet cases:
696
+ // - len_pkt is less than available bytes
697
+ // - len_pkt is NaN from decode_varint() due to lack of data
698
+ len_tip = len_pkt || 0; // 0 when NaN
699
+ break
700
+ }
823
701
 
824
702
  let b0 = u8[0];
825
703
  let u8_body = 0 === len_body ? null
@@ -831,6 +709,8 @@ function mqtt_raw_dispatch(opt) {
831
709
  if (null != pkt)
832
710
  res.push( pkt );
833
711
  }
712
+
713
+ return res
834
714
  }
835
715
  }
836
716
 
@@ -841,16 +721,17 @@ function _u8_join(a, b) {
841
721
  return r
842
722
  }
843
723
 
844
- const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
724
+ const _pkt_types = ['~', 'connect', 'connack', 'publish', 'puback', 'pubrec', 'pubrel', 'pubcomp', 'subscribe', 'suback', 'unsubscribe', 'unsuback', 'pingreq', 'pingresp', 'disconnect', 'auth'];
725
+
726
+
727
+ function mqtt_pkt_ctx(mqtt_level, opts, pkt_api=opts.pkt_ctx) {
728
+ let _as_pkt_ctx = pkt_api => ({
729
+ __proto__: pkt_api,
730
+ get hdr() { return this.b0 & 0xf },
731
+ get id() { return this.b0 >>> 4 },
732
+ get type() { return _pkt_types[this.b0 >>> 4] },
733
+ mqtt_level });
845
734
 
846
- function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
847
- pkt_ctx = {
848
- __proto__: pkt_ctx || opts.pkt_ctx,
849
- mqtt_level,
850
- get hdr() { return this.b0 & 0xf },
851
- get id() { return this.b0 >>> 4 },
852
- get type() { return _pkt_types[this.b0 >>> 4] },
853
- };
854
735
 
855
736
  let op, _decode_by_id=[], _encode_by_type={};
856
737
  for (op of opts.encode_fns)
@@ -859,10 +740,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
859
740
  op(_decode_by_id, opts.mqtt_reader);
860
741
 
861
742
  return {
862
- pkt_ctx,
743
+ pkt_api, pkt_ctx: _as_pkt_ctx(pkt_api),
863
744
 
864
- encode_pkt(type, pkt) {
865
- return _encode_by_type[type]( mqtt_level, pkt ) },
745
+ encode_pkt: (type, pkt) =>
746
+ _encode_by_type[type]( mqtt_level, pkt ),
866
747
 
867
748
  decode_pkt(b0, u8_body) {
868
749
  if (b0.map) // Uint8Array in first arg
@@ -871,12 +752,10 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
871
752
  let fn_decode = _decode_by_id[b0>>>4] || _decode_by_id[0];
872
753
  return fn_decode?.({__proto__: this.pkt_ctx, b0}, u8_body) },
873
754
 
874
- mqtt_stream() {
875
- let self = { __proto__: this, pkt_ctx: { __proto__: pkt_ctx } };
876
- self.pkt_ctx._base_ = self.pkt_ctx;
755
+ mqtt_stream(pkt_api=this.pkt_api) {
756
+ let self = { __proto__: this, pkt_ctx: _as_pkt_ctx(pkt_api) };
877
757
  self.decode = mqtt_raw_dispatch(self);
878
- return self
879
- },
758
+ return self },
880
759
  }
881
760
  }
882
761
 
@@ -1417,7 +1296,7 @@ class MQTTCore extends MQTTBase {
1417
1296
 
1418
1297
  return this} }
1419
1298
 
1420
- const version = '0.6.1-deno';
1299
+ const version = '0.6.3-deno';
1421
1300
 
1422
1301
  const MQTTClient_v4 = /* #__PURE__ */
1423
1302
  MQTTCore.mqtt_ctx(4, mqtt_opts_v5);