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