u8-mqtt 0.4.1 → 0.5.1

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 (81) hide show
  1. package/cjs/basic-v4.cjs +103 -137
  2. package/cjs/basic-v4.cjs.map +1 -1
  3. package/cjs/basic-v5.cjs +102 -136
  4. package/cjs/basic-v5.cjs.map +1 -1
  5. package/cjs/index.cjs +144 -189
  6. package/cjs/index.cjs.map +1 -1
  7. package/cjs/v4.cjs +145 -190
  8. package/cjs/v4.cjs.map +1 -1
  9. package/cjs/v5.cjs +144 -189
  10. package/cjs/v5.cjs.map +1 -1
  11. package/code/_dispatch.jsy +16 -0
  12. package/code/base.jsy +68 -124
  13. package/code/core.jsy +15 -9
  14. package/code/router_path.jsy +24 -43
  15. package/code/with_topic_router.jsy +18 -10
  16. package/esm/basic-v4.js +1154 -0
  17. package/esm/basic-v4.js.map +1 -0
  18. package/esm/basic-v5.js +1416 -0
  19. package/esm/basic-v5.js.map +1 -0
  20. package/esm/deno/basic-v4.js +103 -137
  21. package/esm/deno/basic-v4.js.map +1 -1
  22. package/esm/deno/basic-v5.js +102 -136
  23. package/esm/deno/basic-v5.js.map +1 -1
  24. package/esm/deno/index.js +144 -189
  25. package/esm/deno/index.js.map +1 -1
  26. package/esm/deno/v4.js +145 -190
  27. package/esm/deno/v4.js.map +1 -1
  28. package/esm/deno/v5.js +144 -189
  29. package/esm/deno/v5.js.map +1 -1
  30. package/esm/index.js +1599 -0
  31. package/esm/index.js.map +1 -0
  32. package/esm/node/basic-v4.js +103 -137
  33. package/esm/node/basic-v4.js.map +1 -1
  34. package/esm/node/basic-v4.mjs +103 -137
  35. package/esm/node/basic-v4.mjs.map +1 -1
  36. package/esm/node/basic-v5.js +102 -136
  37. package/esm/node/basic-v5.js.map +1 -1
  38. package/esm/node/basic-v5.mjs +102 -136
  39. package/esm/node/basic-v5.mjs.map +1 -1
  40. package/esm/node/index.js +144 -189
  41. package/esm/node/index.js.map +1 -1
  42. package/esm/node/index.mjs +144 -189
  43. package/esm/node/index.mjs.map +1 -1
  44. package/esm/node/v4.js +145 -190
  45. package/esm/node/v4.js.map +1 -1
  46. package/esm/node/v4.mjs +145 -190
  47. package/esm/node/v4.mjs.map +1 -1
  48. package/esm/node/v5.js +144 -189
  49. package/esm/node/v5.js.map +1 -1
  50. package/esm/node/v5.mjs +144 -189
  51. package/esm/node/v5.mjs.map +1 -1
  52. package/esm/v4.js +1336 -0
  53. package/esm/v4.js.map +1 -0
  54. package/esm/v5.js +1599 -0
  55. package/esm/v5.js.map +1 -0
  56. package/esm/web/basic-v4.js +103 -137
  57. package/esm/web/basic-v4.js.map +1 -1
  58. package/esm/web/basic-v4.min.js +1 -1
  59. package/esm/web/basic-v4.min.js.br +0 -0
  60. package/esm/web/basic-v4.min.js.gz +0 -0
  61. package/esm/web/basic-v5.js +102 -136
  62. package/esm/web/basic-v5.js.map +1 -1
  63. package/esm/web/basic-v5.min.js +1 -1
  64. package/esm/web/basic-v5.min.js.br +0 -0
  65. package/esm/web/basic-v5.min.js.gz +0 -0
  66. package/esm/web/index.js +144 -189
  67. package/esm/web/index.js.map +1 -1
  68. package/esm/web/index.min.js +1 -1
  69. package/esm/web/index.min.js.br +0 -0
  70. package/esm/web/index.min.js.gz +0 -0
  71. package/esm/web/v4.js +145 -190
  72. package/esm/web/v4.js.map +1 -1
  73. package/esm/web/v4.min.js +1 -1
  74. package/esm/web/v4.min.js.br +0 -0
  75. package/esm/web/v4.min.js.gz +0 -0
  76. package/esm/web/v5.js +144 -189
  77. package/esm/web/v5.js.map +1 -1
  78. package/esm/web/v5.min.js +1 -1
  79. package/esm/web/v5.min.js.br +0 -0
  80. package/esm/web/v5.min.js.gz +0 -0
  81. package/package.json +14 -9
package/esm/deno/v4.js CHANGED
@@ -44,7 +44,7 @@ class U8_Reason extends Number {
44
44
  }
45
45
  }
46
46
 
47
- class mqtt_reader_v4$1 {
47
+ let mqtt_reader_v4$1 = class mqtt_reader_v4 {
48
48
  static of(buf) { return this.prototype.of(buf) }
49
49
  of(buf) {
50
50
  let step = (width, k) => (k=0|step.k, step.k=k+width, k);
@@ -100,7 +100,7 @@ class mqtt_reader_v4$1 {
100
100
  return buf.subarray(step.k|0)
101
101
  }
102
102
 
103
- }
103
+ };
104
104
 
105
105
  function mqtt_reader_info(mqtt_reader, ... info_fn_list) {
106
106
  mqtt_reader = class extends mqtt_reader {
@@ -475,7 +475,7 @@ function mqtt_encode_disconnect(ns, mqtt_writer) {
475
475
  }
476
476
  }
477
477
 
478
- // not a v4 packet: import { mqtt_encode_auth } from './encode/auth.mjs'
478
+ // not a v4 packet: import { mqtt_encode_auth } from './encode/auth.js'
479
479
 
480
480
 
481
481
  const mqtt_decode_v4 = [
@@ -556,31 +556,39 @@ const with_topic_router = mqtt_topic_router =>
556
556
  return super._aliases() +
557
557
  ' sub_topic:subscribe_topic unsub_topic:unsubscribe_topic'}
558
558
 
559
- _init_router(opt, client, target) {
559
+ _init_router(opt, self, target) {
560
+ this._subs = [];
560
561
  let router = this.router = target.router =
561
- mqtt_topic_router(opt, this);
562
+ mqtt_topic_router(opt, this, target);
562
563
  return router?.invoke}
563
- get on_topic() {return this.router.add}
564
564
 
565
- _sub_chain(topic, ex, topic_prefix) {
566
- let res = this.subscribe([[ topic ]], ex, topic_prefix);
567
- let subs = this.subs ||(this.subs = new Map());
568
- subs.set((res.topic = topic), (subs.last = res));
569
- return this }// fluent api -- return this and track side effects
565
+ on_sub(suback, pkt) {
566
+ suback.pkt = pkt;
567
+ this._subs.push(suback);
568
+ return suback}
569
+ subs_settled() {
570
+ return Promise.allSettled(
571
+ this._subs.splice(0,Infinity)) }
570
572
 
571
573
  // alias: sub_topic
572
574
  subscribe_topic(topic_route, ...args) {
573
575
  let router = this.router;
574
576
  router.add(topic_route, true, args.pop() );// handler
575
577
  let topic = router.mqtt_topic(topic_route);
576
- return this._sub_chain(topic, ...args ) }// ex, topic_prefix
578
+ this.subscribe(topic, ...args );// ex, topic_prefix
579
+ return this }// fluent api -- return this and track side effects
577
580
 
578
581
  // alias: unsub_topic
579
582
  unsubscribe_topic(topic_route, ...args) {
580
583
  let router = this.router;
581
584
  router.remove(topic_route, true);
582
585
  let topic = router.mqtt_topic(topic_route);
583
- return this.unsubscribe([[ topic ]], ...args ) } };// topic_prefix
586
+ return this.unsubscribe(topic, ...args ) }// topic_prefix
587
+
588
+ // add topic handlers without corresponding subscribe packet
589
+ on_topic(...args) {
590
+ this.router.add(...args);
591
+ return this} };
584
592
 
585
593
  // Use [regexparam][] for url-like topic parsing
586
594
  // [regexparam]: https://github.com/lukeed/regexparam
@@ -593,7 +601,7 @@ const with_topic_path_router = /* #__PURE__ */
593
601
  const mqtt_topic = topic_route =>
594
602
  topic_route
595
603
  .replace(/[*].*$/, '#')
596
- .replace(/:\w+\??/g, '+');
604
+ .replace(/:\w[^\/]*/g, '+');
597
605
 
598
606
  /* From the [MQTT v5 Spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Topic_Names_and)
599
607
  4.7.1.2 Multi-level wildcard -- (‘#’ U+0023)
@@ -623,9 +631,8 @@ function mqtt_topic_path_router() {
623
631
  let priority = args.pop();
624
632
 
625
633
  if ('function' !== typeof fn) {
626
- if (false === fn) {
627
- fn = _ignore;}
628
- else throw new TypeError()}
634
+ if (fn) {throw new TypeError()}
635
+ fn = _ignore;}
629
636
 
630
637
  let rte = parse(as_topic_path(topic_route));
631
638
 
@@ -641,7 +648,7 @@ function mqtt_topic_path_router() {
641
648
  , clear(priority) {
642
649
  pri_lsts[priority ? 0 : 1] = [];
643
650
  if (null == priority) {
644
- pri_lsts[1] = [];} }
651
+ pri_lsts[1] = []; } }// null clears both lists
645
652
 
646
653
  , async invoke(pkt, ctx) {
647
654
  ctx.idx = 0;
@@ -657,52 +664,34 @@ function mqtt_topic_path_router() {
657
664
  break}
658
665
  else ctx.idx++;}
659
666
 
660
- let {pkt_id, qos} = pkt;
661
- if (1 === qos) {
662
- await ctx.mqtt._send('puback', {pkt_id});} } } }
667
+ if (1 === pkt.qos) {
668
+ await ctx.mqtt.puback(pkt);} } } }
663
669
 
664
670
 
665
671
  function * _routes_iter(all_route_lists, topic) {
672
+ topic = topic.replace(/^[\/]*/, '/'); // ensure '/' prefix for regexparam library
666
673
  for (let route_list of all_route_lists) {
667
- for (let route of route_list) {
668
- let res = _route_match_one(topic, route);
669
- if (undefined !== res) {
670
- yield res;} } } }
671
-
672
-
673
- function _route_match_one(topic, {keys, pattern, tgt}) {
674
- let match = '/' !== topic[0]
675
- ? pattern.exec('/'+topic)
676
- : pattern.exec(topic);
677
-
678
- if (null === match) {
679
- return}
680
-
681
- if (false === keys) {
682
- let {groups} = match;
683
- if (! groups) {
684
- return [tgt]}
685
-
686
- let params = {};
687
- for (let k in groups) {
688
- params[k] = groups[k];}
689
-
690
- return [tgt, params]}
691
-
692
- if (0 === keys.length) {
693
- return [tgt]}
694
-
695
- let params = {};
696
- for (let i=0; i<keys.length; i++) {
697
- params[ keys[i] ] = match[1+i];}
698
- return [tgt, params]}
674
+ for (let {keys, pattern, tgt} of route_list) {
675
+ let match = pattern.exec(topic);
676
+ if (match) {
677
+ let params = keys
678
+ ? keys.reduce(
679
+ (o, k, i) => (o[k] = match[1+i], o)
680
+ , {})
681
+ : match.groups ?? match;
682
+ yield [tgt, params];} } } }
699
683
 
700
684
 
701
685
  function _route_remove(all_route_lists, query) {
702
- let match = route => route===query || route.tgt===query || route.key===query;
686
+ let fn_match = route =>(
687
+ route===query
688
+ || route.tgt===query
689
+ || route.key===query);
703
690
  for (let lst of all_route_lists) {
704
- let i = lst.findIndex(match);
705
- if (0 <= i) {return !! lst.splice(i,1)} }
691
+ let i = lst.findIndex(fn_match);
692
+ if (0 <= i) {
693
+ lst.splice(i,1);
694
+ return true} }
706
695
  return false}
707
696
 
708
697
  /*
@@ -963,6 +952,22 @@ const _mqtt_cmdid_dispatch ={
963
952
 
964
953
  await fn?.call(target, pkt, ctx);} })()) };
965
954
 
955
+ /*
956
+ on_mqtt_type = {
957
+ mqtt_auth(pkt, ctx) ::
958
+ mqtt_connect(pkt, ctx) ::
959
+ mqtt_connack(pkt, ctx) ::
960
+ mqtt_disconnect(pkt, ctx) ::
961
+
962
+ mqtt_publish(pkt, ctx)
963
+ mqtt_subscribe(pkt, ctx) ::
964
+ mqtt_unsubscribe(pkt, ctx) ::
965
+
966
+ mqtt_pingreq(pkt, ctx) ::
967
+ mqtt_pingresp(pkt, ctx) ::
968
+ }
969
+ */
970
+
966
971
  function _mqtt_dispatch(opt, target) {
967
972
  let _disp_ = _mqtt_cmdid_dispatch.create(target);
968
973
  let { cmdids } = _disp_;
@@ -992,28 +997,34 @@ class MQTTError extends Error {
992
997
 
993
998
  class MQTTBase {
994
999
  constructor(opt={}) {
1000
+ this.with(opt);
995
1001
  this._conn_ = _mqtt_conn(this,
996
1002
  this._init_dispatch(opt, this)); }
997
1003
 
1004
+ with(fns_ns) {
1005
+ for (let [k,v] of Object.entries(fns_ns)) {
1006
+ if ('function' === typeof v) {this[k] = v;} }
1007
+ return this}
1008
+
998
1009
  async conn_emit(evt, arg, err_arg) {
999
1010
  this.log_conn?.(evt, arg, err_arg);
1000
1011
  try {
1001
- let fn_evt = this[await evt]; // microtask break
1012
+ let fn_evt = this[await evt]; // microtask break using `await evt`
1002
1013
  if (fn_evt) {
1003
1014
  await fn_evt.call(this, this, arg, err_arg);}
1004
- else if (err_arg) {
1005
- await this.on_error(err_arg, evt);} }
1015
+ else if (err_arg) {throw err_arg} }
1006
1016
  catch (err) {
1007
1017
  this.on_error(err, evt);} }
1008
1018
 
1009
- on_error(err, err_path) {
1010
- console.warn('[[u8-mqtt error: %s]]', err_path, err); }
1019
+ on_error(err, evt) {
1020
+ console.warn('[[u8-mqtt error: %s]]', evt, err); }
1011
1021
 
1012
1022
  // Handshaking Packets
1013
1023
 
1014
1024
  async connect(pkt={}) {
1015
- let cid = pkt.client_id || ['u8-mqtt--', ''];
1016
- if (Array.isArray(cid)) {
1025
+ let cid = pkt.client_id || this.client_id;
1026
+ if ('string' !== typeof cid) {
1027
+ // see init_client_id implementation in core.jsy
1017
1028
  pkt.client_id = cid = this.init_client_id(cid);}
1018
1029
  this.client_id = cid;
1019
1030
 
@@ -1039,12 +1050,13 @@ class MQTTBase {
1039
1050
  return this._send('auth', pkt, 'auth')}
1040
1051
 
1041
1052
  ping() {return this._send('pingreq', null, 'pingresp')}
1042
-
1053
+ puback({pkt_id}) {return this._send('puback', {pkt_id})}
1043
1054
 
1044
1055
  // alias: sub
1045
1056
  subscribe(pkt, ex, topic_prefix) {
1046
1057
  pkt = _as_topics(pkt, ex, topic_prefix);
1047
- return this._send('subscribe', pkt, pkt)}
1058
+ let suback = this._send('subscribe', pkt, pkt);
1059
+ return this.on_sub?.(suback, pkt) ?? suback}
1048
1060
 
1049
1061
  // alias: unsub
1050
1062
  unsubscribe(pkt, ex, topic_prefix) {
@@ -1052,48 +1064,52 @@ class MQTTBase {
1052
1064
  return this._send('unsubscribe', pkt, pkt)}
1053
1065
 
1054
1066
 
1055
- // alias: pub
1056
- publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
1057
- post(topic, payload, pub_opt) {return _pub.m(this, topic, payload, pub_opt)}
1058
- send(topic, payload, pub_opt) {return _pub.mq(this, topic, payload, pub_opt)}
1059
- store(topic, payload, pub_opt) {return _pub.mqr(this, topic, payload, pub_opt)}
1060
-
1061
- json_post(topic, msg, pub_opt) {return _pub.o(this, topic, msg, pub_opt)}
1062
- json_send(topic, msg, pub_opt) {return _pub.oq(this, topic, msg, pub_opt)}
1063
- json_store(topic, msg, pub_opt) {return _pub.oqr(this, topic, msg, pub_opt)}
1064
-
1065
- obj_post(topic, msg, pub_opt) {return _pub.o(this, topic, msg, pub_opt)}
1066
- obj_send(topic, msg, pub_opt) {return _pub.oq(this, topic, msg, pub_opt)}
1067
- obj_store(topic, msg, pub_opt) {return _pub.oqr(this, topic, msg, pub_opt)}
1068
-
1069
-
1070
-
1071
- // Utility Methods
1072
-
1073
- init_client_id(parts) {
1074
- let cid = this.client_id;
1075
-
1076
- if (undefined === cid) {
1077
- this.client_id = cid = (
1078
-
1079
-
1080
-
1081
- this.new_client_id(parts)
1082
- );}
1083
-
1084
- return cid}
1085
-
1086
- new_client_id(parts) {
1087
- return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
1088
-
1089
-
1090
-
1091
-
1092
-
1093
-
1094
-
1095
-
1096
-
1067
+ post(topic, payload, pub_opt) {// qos:0
1068
+ return this.pub({topic, payload, qos:0}, pub_opt)}
1069
+ send(topic, payload, pub_opt) {// qos:1
1070
+ return this.pub({topic, payload, qos:1}, pub_opt)}
1071
+ store(topic, payload, pub_opt) {// qos:1, retain: 1
1072
+ return this.pub({topic, payload, qos:1, retain: 1}, pub_opt)}
1073
+
1074
+ // alias: json_post
1075
+ obj_post(topic, msg, pub_opt) {// qos:0
1076
+ return this.pub({topic, msg, arg: 'msg', qos:0}, pub_opt)}
1077
+ // alias: json_send
1078
+ obj_send(topic, msg, pub_opt) {// qos:1
1079
+ return this.pub({topic, msg, arg: 'msg', qos:1}, pub_opt)}
1080
+ // alias: json_store
1081
+ obj_store(topic, msg, pub_opt) {// qos:1, retain: 1
1082
+ return this.pub({topic, msg, arg: 'msg', qos:1, retain: 1}, pub_opt)}
1083
+
1084
+ // alias: publish -- because 'pub' is shorter for semantic aliases above
1085
+ async pub(pkt, pub_opt) {
1086
+ if (undefined === pkt.payload) {
1087
+ if ('function' === typeof pub_opt) {
1088
+ pub_opt = {fn_encode: pub_opt};}
1089
+
1090
+ let {msg} = pkt;
1091
+ switch (typeof msg) {
1092
+ case 'function':
1093
+ pub_opt = {...pub_opt, fn_encode: msg};
1094
+ // flow into 'undefined' case
1095
+ case 'undefined':
1096
+ // return a single-value closure to publish packets
1097
+ return v => this.pub({...pkt, [pkt.arg || 'payload']: v}, pub_opt)}
1098
+
1099
+ // Encode payload from msg; fn_encode allows alternative to JSON.stringify
1100
+ let {fn_encode} = pub_opt || {};
1101
+ pkt.payload = fn_encode
1102
+ ? await fn_encode(msg)
1103
+ : JSON.stringify(msg);}
1104
+
1105
+ if (pub_opt) {
1106
+ if (pub_opt.props) {
1107
+ pkt.props = pub_opt.props;}
1108
+ if (pub_opt.xform) {
1109
+ pkt = pub_opt.xform(pkt) || pkt;} }
1110
+
1111
+ return this._send('publish', pkt,
1112
+ pkt.qos ? pkt : void 0 ) }// key
1097
1113
 
1098
1114
 
1099
1115
  // Internal API
@@ -1108,41 +1124,18 @@ class MQTTBase {
1108
1124
  return _mqtt_dispatch(this, target)}
1109
1125
 
1110
1126
  static _aliases() {
1111
- return ' pub:publish sub:subscribe unsub:unsubscribe '}
1127
+ return ' publish:pub sub:subscribe unsub:unsubscribe json_post:obj_post json_send:obj_send json_store:obj_store'}
1112
1128
 
1113
1129
  static _once_(self=this) {
1114
1130
  self._once_ = _=>0;
1115
- self.MQTTError = MQTTError;
1116
1131
  let p = self.prototype;
1132
+ p.MQTTError = MQTTError;
1117
1133
  for (let alias of self._aliases().split(/\s+/)) {
1118
1134
  alias = alias.split(':');
1119
1135
  let fn = alias[1] && p[alias[1]];
1120
1136
  if (fn) {p[alias[0]] = fn;} } } }
1121
1137
 
1122
1138
 
1123
- /*
1124
- on_mqtt_type = {
1125
- mqtt_auth(pkt, ctx) ::
1126
- mqtt_connect(pkt, ctx) ::
1127
- mqtt_connack(pkt, ctx) ::
1128
- mqtt_disconnect(pkt, ctx) ::
1129
-
1130
- mqtt_publish(pkt, ctx)
1131
- mqtt_subscribe(pkt, ctx) ::
1132
- mqtt_unsubscribe(pkt, ctx) ::
1133
-
1134
- mqtt_pingreq(pkt, ctx) ::
1135
- mqtt_pingresp(pkt, ctx) ::
1136
- }
1137
- */
1138
-
1139
-
1140
- const _prefix_topics = (topic_prefix, iterable) =>
1141
- Array.from(iterable, value =>(
1142
- value.trim // string
1143
- ? _prefix_topics(topic_prefix, value)
1144
- : topic_prefix + value) );
1145
-
1146
1139
  function _as_topics(pkt, ex, topic_prefix) {
1147
1140
  if (ex?.trim) {// string
1148
1141
  topic_prefix = ex;
@@ -1159,55 +1152,11 @@ function _as_topics(pkt, ex, topic_prefix) {
1159
1152
  if (topic_prefix) {
1160
1153
  // particularly useful with shared queues, e.g.
1161
1154
  // topic_prefix = '$share/some-queue-name/'
1162
- pkt.topics = _prefix_topics(topic_prefix, pkt.topics);}
1163
- return pkt}
1164
-
1155
+ let _prefix_topics = v =>
1156
+ v.trim ? topic_prefix+v : v.map(_prefix_topics);
1165
1157
 
1166
- async function _pub(self, pkt, pub_opt) {
1167
- if (undefined === pkt.payload) {
1168
- if ('function' === typeof pub_opt) {
1169
- pub_opt = {fn_encode: pub_opt};}
1170
-
1171
- let {msg} = pkt;
1172
- switch (typeof msg) {
1173
- case 'function':
1174
- pub_opt = {...pub_opt, fn_encode: msg};
1175
- // flow into 'undefined' case
1176
- case 'undefined':
1177
- // return a single-value closure to publish packets
1178
- return v => _pub(self, {...pkt, [pkt.arg || 'payload']: v}, pub_opt)
1179
-
1180
- default:
1181
- // Encode payload from msg; fn_encode allows alternative to JSON.stringify
1182
- let {fn_encode} = pub_opt || {};
1183
- pkt.payload = fn_encode
1184
- ? await fn_encode(msg)
1185
- : JSON.stringify(msg);} }
1186
-
1187
- if (pub_opt) {
1188
- if (pub_opt.props) {
1189
- pkt.props = pub_opt.props;}
1190
- if (pub_opt.xform) {
1191
- pkt = pub_opt.xform(pkt) || pkt;} }
1192
-
1193
- return self._send('publish', pkt,
1194
- pkt.qos ? pkt : void 0 ) }// key
1195
-
1196
- {
1197
- Object.assign(_pub,{
1198
- m: (self, topic, payload, pub_opt) =>
1199
- _pub(self, {topic, payload, qos:0}, pub_opt)
1200
- , mq: (self, topic, payload, pub_opt) =>
1201
- _pub(self, {topic, payload, qos:1}, pub_opt)
1202
- , mqr: (self, topic, payload, pub_opt) =>
1203
- _pub(self, {topic, payload, qos:1, retain: 1}, pub_opt)
1204
-
1205
- , o: (self, topic, msg, pub_opt) =>
1206
- _pub(self, {topic, msg, arg: 'msg', qos:0}, pub_opt)
1207
- , oq: (self, topic, msg, pub_opt) =>
1208
- _pub(self, {topic, msg, arg: 'msg', qos:1}, pub_opt)
1209
- , oqr: (self, topic, msg, pub_opt) =>
1210
- _pub(self, {topic, msg, arg: 'msg', qos:1, retain: 1}, pub_opt)} ); }
1158
+ pkt.topics = pkt.topics.map(_prefix_topics);}
1159
+ return pkt}
1211
1160
 
1212
1161
  const pkt_api = {
1213
1162
  utf8(u8) { return new TextDecoder('utf-8').decode(u8 || this.payload ) },
@@ -1216,20 +1165,27 @@ const pkt_api = {
1216
1165
  };
1217
1166
 
1218
1167
  class MQTTCore extends MQTTBase {
1219
- constructor(opt={}) {
1220
- super(opt);
1221
- this.with(opt);}
1222
-
1223
1168
  static mqtt_ctx(mqtt_level, mqtt_opts, pkt_ctx=pkt_api) {
1224
1169
  let self = class extends this {};
1225
1170
  self.prototype.mqtt_ctx =
1226
1171
  mqtt_pkt_ctx(mqtt_level, mqtt_opts, pkt_ctx);
1227
1172
  return self}
1228
1173
 
1229
- with(fns_ns) {
1230
- for (let [k,v] of Object.entries(fns_ns)) {
1231
- if ('function' === typeof v) {this[k] = v;} }
1232
- return this}
1174
+
1175
+ // automatic Client Id for connect()
1176
+ init_client_id(parts=['u8-mqtt--','']) {
1177
+ let sess_stg=this.sess_stg;
1178
+ let key, cid = sess_stg?.getItem(key=parts.join(' '));
1179
+ if (! cid) {
1180
+ cid = parts.join(Math.random().toString(36).slice(2));
1181
+ sess_stg?.setItem(key, cid);}
1182
+ return cid}
1183
+
1184
+ get sess_stg() {return globalThis.sessionStorage}
1185
+
1186
+
1187
+ //on_error(err, evt) ::
1188
+ // console.warn @ '[[u8-mqtt error: %s]]', evt, err
1233
1189
 
1234
1190
  //log_conn(evt, arg, err_arg) ::
1235
1191
  // console.info @ '[[u8-mqtt log: %s]]', evt, arg, err_arg
@@ -1307,7 +1263,6 @@ class MQTTCore extends MQTTBase {
1307
1263
 
1308
1264
 
1309
1265
 
1310
-
1311
1266
 
1312
1267
 
1313
1268
 
@@ -1368,7 +1323,7 @@ class MQTTCore extends MQTTBase {
1368
1323
 
1369
1324
  return this} }
1370
1325
 
1371
- const version = '0.4.1';
1326
+ const version = '0.5.1-deno';
1372
1327
 
1373
1328
  const MQTTClient_v4 = /* #__PURE__ */
1374
1329
  with_topic_path_router(