u8-mqtt 0.3.2-0 → 0.4.0

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 (76) hide show
  1. package/README.md +5 -5
  2. package/cjs/basic-v4.cjs +1205 -0
  3. package/cjs/basic-v4.cjs.map +1 -0
  4. package/cjs/basic-v5.cjs +1469 -0
  5. package/cjs/basic-v5.cjs.map +1 -0
  6. package/cjs/index.cjs +308 -267
  7. package/cjs/index.cjs.map +1 -1
  8. package/cjs/v4.cjs +303 -262
  9. package/cjs/v4.cjs.map +1 -1
  10. package/cjs/v5.cjs +305 -263
  11. package/cjs/v5.cjs.map +1 -1
  12. package/code/_cmdid_dispatch.jsy +1 -3
  13. package/code/base.jsy +64 -84
  14. package/code/basic-v4.js +18 -0
  15. package/code/basic-v5.js +26 -0
  16. package/code/index.js +2 -1
  17. package/code/{_router.jsy → router_path.jsy} +30 -12
  18. package/code/v4.js +3 -1
  19. package/code/v5.js +5 -2
  20. package/code/with_topic_router.jsy +41 -0
  21. package/esm/deno/basic-v4.js +1193 -0
  22. package/esm/deno/basic-v4.js.map +1 -0
  23. package/esm/deno/basic-v5.js +1455 -0
  24. package/esm/deno/basic-v5.js.map +1 -0
  25. package/esm/deno/index.js +306 -264
  26. package/esm/deno/index.js.map +1 -1
  27. package/esm/deno/v4.js +303 -262
  28. package/esm/deno/v4.js.map +1 -1
  29. package/esm/deno/v5.js +305 -263
  30. package/esm/deno/v5.js.map +1 -1
  31. package/esm/node/basic-v4.js +1196 -0
  32. package/esm/node/basic-v4.js.map +1 -0
  33. package/esm/node/basic-v4.mjs +1196 -0
  34. package/esm/node/basic-v4.mjs.map +1 -0
  35. package/esm/node/basic-v5.js +1458 -0
  36. package/esm/node/basic-v5.js.map +1 -0
  37. package/esm/node/basic-v5.mjs +1458 -0
  38. package/esm/node/basic-v5.mjs.map +1 -0
  39. package/esm/node/index.js +306 -264
  40. package/esm/node/index.js.map +1 -1
  41. package/esm/node/index.mjs +306 -264
  42. package/esm/node/index.mjs.map +1 -1
  43. package/esm/node/v4.js +303 -262
  44. package/esm/node/v4.js.map +1 -1
  45. package/esm/node/v4.mjs +303 -262
  46. package/esm/node/v4.mjs.map +1 -1
  47. package/esm/node/v5.js +305 -263
  48. package/esm/node/v5.js.map +1 -1
  49. package/esm/node/v5.mjs +305 -263
  50. package/esm/node/v5.mjs.map +1 -1
  51. package/esm/web/basic-v4.js +1193 -0
  52. package/esm/web/basic-v4.js.map +1 -0
  53. package/esm/web/basic-v4.min.js +1 -0
  54. package/esm/web/basic-v4.min.js.br +0 -0
  55. package/esm/web/basic-v4.min.js.gz +0 -0
  56. package/esm/web/basic-v5.js +1455 -0
  57. package/esm/web/basic-v5.js.map +1 -0
  58. package/esm/web/basic-v5.min.js +1 -0
  59. package/esm/web/basic-v5.min.js.br +0 -0
  60. package/esm/web/basic-v5.min.js.gz +0 -0
  61. package/esm/web/index.js +305 -263
  62. package/esm/web/index.js.map +1 -1
  63. package/esm/web/index.min.js +1 -1
  64. package/esm/web/index.min.js.br +0 -0
  65. package/esm/web/index.min.js.gz +0 -0
  66. package/esm/web/v4.js +303 -262
  67. package/esm/web/v4.js.map +1 -1
  68. package/esm/web/v4.min.js +1 -1
  69. package/esm/web/v4.min.js.br +0 -0
  70. package/esm/web/v4.min.js.gz +0 -0
  71. package/esm/web/v5.js +304 -262
  72. package/esm/web/v5.js.map +1 -1
  73. package/esm/web/v5.min.js +1 -1
  74. package/esm/web/v5.min.js.br +0 -0
  75. package/esm/web/v5.min.js.gz +0 -0
  76. package/package.json +5 -5
package/esm/node/v4.js CHANGED
@@ -516,6 +516,191 @@ const mqtt_opts_v4 =
516
516
  encode_fns: mqtt_encode_v4,
517
517
  mqtt_writer: mqtt_writer_v4, };
518
518
 
519
+ function parse(str, loose) {
520
+ if (str instanceof RegExp) return { keys:false, pattern:str };
521
+ var c, o, tmp, ext, keys=[], pattern='', arr = str.split('/');
522
+ arr[0] || arr.shift();
523
+
524
+ while (tmp = arr.shift()) {
525
+ c = tmp[0];
526
+ if (c === '*') {
527
+ keys.push('wild');
528
+ pattern += '/(.*)';
529
+ } else if (c === ':') {
530
+ o = tmp.indexOf('?', 1);
531
+ ext = tmp.indexOf('.', 1);
532
+ keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) );
533
+ pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)';
534
+ if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext);
535
+ } else {
536
+ pattern += '/' + tmp;
537
+ }
538
+ }
539
+
540
+ return {
541
+ keys: keys,
542
+ pattern: new RegExp('^' + pattern + (loose ? '(?=$|\/)' : '\/?$'), 'i')
543
+ };
544
+ }
545
+
546
+ /*
547
+ class AbstractTopicRouter ::
548
+ async invoke(pkt, ctx) ::
549
+ add(topic_route, ...args) ::
550
+ remove(topic_route, priority) ::
551
+ clear(priority) ::
552
+ find(topic) :: // optional
553
+ mqtt_topic(topic_route)
554
+ */
555
+
556
+ const with_topic_router = mqtt_topic_router =>
557
+ MQTTKlass => class extends MQTTKlass {
558
+ static _aliases() {
559
+ return super._aliases() +
560
+ ' sub_topic:subscribe_topic unsub_topic:unsubscribe_topic'}
561
+
562
+ _init_router(opt) {
563
+ return mqtt_topic_router(opt, this)}
564
+
565
+ get on_topic() {return this.router.add}
566
+
567
+ _sub_chain(topic, ex, topic_prefix) {
568
+ let res = this.subscribe([[ topic ]], ex, topic_prefix);
569
+ let subs = this.subs ||(this.subs = new Map());
570
+ subs.set((res.topic = topic), (subs.last = res));
571
+ return this }// fluent api -- return this and track side effects
572
+
573
+ // alias: sub_topic
574
+ subscribe_topic(topic_route, ...args) {
575
+ let router = this.router;
576
+ router.add(topic_route, true, args.pop() );// handler
577
+ let topic = router.mqtt_topic(topic_route);
578
+ return this._sub_chain(topic, ...args ) }// ex, topic_prefix
579
+
580
+ // alias: unsub_topic
581
+ unsubscribe_topic(topic_route, ...args) {
582
+ let router = this.router;
583
+ router.remove(topic_route, true);
584
+ let topic = router.mqtt_topic(topic_route);
585
+ return this.unsubscribe([[ topic ]], ...args ) } };// topic_prefix
586
+
587
+ // Use [regexparam][] for url-like topic parsing
588
+ // [regexparam]: https://github.com/lukeed/regexparam
589
+
590
+
591
+ const with_topic_path_router = /* #__PURE__ */
592
+ with_topic_router(mqtt_topic_path_router);
593
+
594
+
595
+ const mqtt_topic = topic_route =>
596
+ topic_route
597
+ .replace(/[*].*$/, '#')
598
+ .replace(/:\w+\??/g, '+');
599
+
600
+ const as_topic_path = topic_route =>(
601
+ topic_route
602
+ .replace(/#$/, '*') // replace MQTT # wildcard at end
603
+ .split(/([^\/]*[+][^\/]*)/) // split on MQTT + match tokens
604
+ .reduce (( sz, v, idx ) => sz +(
605
+ idx & 1 // even entires are body, odd are MQTT + tokens
606
+ ? `:$${1 + idx>>1}` // replace with `:$#` sequential ids, using ? for partial entries
607
+ : v ) ) );// pass through body
608
+
609
+ function _ignore(pkt, params, ctx) {ctx.done = true;}
610
+
611
+ function mqtt_topic_path_router() {
612
+ let pri_lsts = [[],[]], rm = Symbol();
613
+ let find = topic => _routes_iter(pri_lsts, topic);
614
+
615
+ // return duck-type compatible with AbstractTopicRouter in ./with_topic_router
616
+ return {find, mqtt_topic,
617
+ add(topic_route, ...args) {
618
+ let fn = args.pop();
619
+ let priority = args.pop();
620
+
621
+ if ('function' !== typeof fn) {
622
+ if (false === fn) {
623
+ fn = _ignore;}
624
+ else throw new TypeError()}
625
+
626
+ let rte = parse(as_topic_path(topic_route));
627
+
628
+ rte.key = topic_route;
629
+ rte.tgt = fn;
630
+ pri_lsts[priority ? 0 : 1].push(rte);
631
+ return this}
632
+
633
+ , remove(topic_route, priority) {
634
+ let lst = pri_lsts[priority ? 0 : 1];
635
+ return _route_remove([lst], topic_route)}
636
+
637
+ , clear(priority) {
638
+ pri_lsts[priority ? 0 : 1] = [];
639
+ if (null == priority) {
640
+ pri_lsts[1] = [];} }
641
+
642
+ , async invoke(pkt, ctx) {
643
+ ctx.idx = 0;
644
+ ctx.rm = rm;
645
+
646
+ for (let [fn, params] of find(pkt.topic)) {
647
+ let res = await fn(pkt, params, ctx);
648
+
649
+ if (rm === res) {
650
+ _route_remove(pri_lsts, fn);}
651
+
652
+ if (ctx.done) {
653
+ break}
654
+ else ctx.idx++;}
655
+
656
+ let {pkt_id, qos} = pkt;
657
+ if (1 === qos) {
658
+ await ctx.mqtt._send('puback', {pkt_id});} } } }
659
+
660
+
661
+ function * _routes_iter(all_route_lists, topic) {
662
+ for (let route_list of all_route_lists) {
663
+ for (let route of route_list) {
664
+ let res = _route_match_one(topic, route);
665
+ if (undefined !== res) {
666
+ yield res;} } } }
667
+
668
+
669
+ function _route_match_one(topic, {keys, pattern, tgt}) {
670
+ let match = '/' !== topic[0]
671
+ ? pattern.exec('/'+topic)
672
+ : pattern.exec(topic);
673
+
674
+ if (null === match) {
675
+ return}
676
+
677
+ if (false === keys) {
678
+ let {groups} = match;
679
+ if (! groups) {
680
+ return [tgt]}
681
+
682
+ let params = {};
683
+ for (let k in groups) {
684
+ params[k] = groups[k];}
685
+
686
+ return [tgt, params]}
687
+
688
+ if (0 === keys.length) {
689
+ return [tgt]}
690
+
691
+ let params = {};
692
+ for (let i=0; i<keys.length; i++) {
693
+ params[ keys[i] ] = match[1+i];}
694
+ return [tgt, params]}
695
+
696
+
697
+ function _route_remove(all_route_lists, query) {
698
+ let match = route => route===query || route.tgt===query || route.key===query;
699
+ for (let lst of all_route_lists) {
700
+ let i = lst.findIndex(match);
701
+ if (0 <= i) {return !! lst.splice(i,1)} }
702
+ return false}
703
+
519
704
  /*
520
705
  export function decode_varint_loop(u8, i=0) {
521
706
  let i0 = i
@@ -697,138 +882,13 @@ function _ping_interval(send_ping) {
697
882
  if (td) {
698
883
  tid = setInterval(send_ping, 1000 * td);
699
884
 
700
-
701
-
885
+
886
+
702
887
 
703
- // ensure the interval allows the NodeJS event loop to exit
704
- tid.unref?.();
888
+ // ensure the interval allows the NodeJS event loop to exit
889
+ tid.unref?.();
705
890
  return true} }) }
706
891
 
707
- function parse(str, loose) {
708
- if (str instanceof RegExp) return { keys:false, pattern:str };
709
- var c, o, tmp, ext, keys=[], pattern='', arr = str.split('/');
710
- arr[0] || arr.shift();
711
-
712
- while (tmp = arr.shift()) {
713
- c = tmp[0];
714
- if (c === '*') {
715
- keys.push('wild');
716
- pattern += '/(.*)';
717
- } else if (c === ':') {
718
- o = tmp.indexOf('?', 1);
719
- ext = tmp.indexOf('.', 1);
720
- keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) );
721
- pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)';
722
- if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext);
723
- } else {
724
- pattern += '/' + tmp;
725
- }
726
- }
727
-
728
- return {
729
- keys: keys,
730
- pattern: new RegExp('^' + pattern + (loose ? '(?=$|\/)' : '\/?$'), 'i')
731
- };
732
- }
733
-
734
- // Use [regexparam][] for url-like topic parsing
735
-
736
- function _ignore(pkt, params, ctx) {ctx.done = true;}
737
-
738
- function _mqtt_topic_router() {
739
- let pri_lsts = [[],[]], rm = Symbol();
740
- let find = topic => _mqtt_routes_iter(pri_lsts, topic);
741
-
742
- return {find,
743
-
744
- add(topic_route, ...args) {
745
- let fn = args.pop();
746
- let priority = args.pop();
747
-
748
- if ('function' !== typeof fn) {
749
- if (false === fn) {
750
- fn = _ignore;}
751
- else throw new TypeError()}
752
-
753
- let rte = parse(
754
- topic_route.replace(/[+#]$/, '*'));
755
-
756
- rte.key = topic_route;
757
- rte.tgt = fn;
758
- pri_lsts[priority ? 0 : 1].push(rte);
759
- return this}
760
-
761
- , remove(topic_route, priority) {
762
- let lst = pri_lsts[priority ? 0 : 1];
763
- return _mqtt_route_remove([lst], topic_route)}
764
-
765
- , clear(priority) {
766
- pri_lsts[priority ? 0 : 1] = [];
767
- if (null == priority) {
768
- pri_lsts[1] = [];} }
769
-
770
- , async invoke(pkt, ctx) {
771
- ctx.idx = 0;
772
- ctx.rm = rm;
773
-
774
- for (let [fn, params] of find(pkt.topic)) {
775
- let res = await fn(pkt, params, ctx);
776
-
777
- if (rm === res) {
778
- _mqtt_route_remove(pri_lsts, fn);}
779
-
780
- if (ctx.done) {
781
- break}
782
- else ctx.idx++;}
783
-
784
- let {pkt_id, qos} = pkt;
785
- if (1 === qos) {
786
- await ctx.mqtt._send('puback', {pkt_id});} } } }
787
-
788
-
789
- function * _mqtt_routes_iter(all_route_lists, topic) {
790
- for (let route_list of all_route_lists) {
791
- for (let route of route_list) {
792
- let res = _mqtt_route_match_one(topic, route);
793
- if (undefined !== res) {
794
- yield res;} } } }
795
-
796
-
797
- function _mqtt_route_match_one(topic, {keys, pattern, tgt}) {
798
- let match = '/' !== topic[0]
799
- ? pattern.exec('/'+topic)
800
- : pattern.exec(topic);
801
-
802
- if (null === match) {
803
- return}
804
-
805
- if (false === keys) {
806
- let {groups} = match;
807
- if (! groups) {
808
- return [tgt]}
809
-
810
- let params = {};
811
- for (let k in groups) {
812
- params[k] = groups[k];}
813
-
814
- return [tgt, params]}
815
-
816
- if (0 === keys.length) {
817
- return [tgt]}
818
-
819
- let params = {};
820
- for (let i=0; i<keys.length; i++) {
821
- params[ keys[i] ] = match[1+i];}
822
- return [tgt, params]}
823
-
824
-
825
- function _mqtt_route_remove(all_route_lists, query) {
826
- let match = route => route===query || route.tgt===query || route.key===query;
827
- for (let lst of all_route_lists) {
828
- let i = lst.findIndex(match);
829
- if (0 <= i) {return !! lst.splice(i,1)} }
830
- return false}
831
-
832
892
  const _mqtt_cmdid_dispatch ={
833
893
  create(target) {
834
894
  return {__proto__: this, target, hashbelt: [new Map()]} }
@@ -897,8 +957,7 @@ const _mqtt_cmdid_dispatch ={
897
957
  let fn = target[`mqtt_${pkt.type}`]
898
958
  || target.mqtt_pkt;
899
959
 
900
- if (undefined !== fn) {
901
- await fn.call(target, pkt, ctx);} } })()) };
960
+ await fn?.call(target, pkt, ctx);} })()) };
902
961
 
903
962
  function _mqtt_dispatch(opt, target) {
904
963
  let _disp_ = _mqtt_cmdid_dispatch.create(target);
@@ -979,53 +1038,15 @@ class MQTTBase {
979
1038
 
980
1039
 
981
1040
  // alias: sub
982
- subscribe(pkt, ex) {
983
- pkt = _as_topics(pkt, ex);
1041
+ subscribe(pkt, ex, topic_prefix) {
1042
+ pkt = _as_topics(pkt, ex, topic_prefix);
984
1043
  return this._send('subscribe', pkt, pkt)}
985
- _sub_chain(topic, ex) {
986
- let res = this.subscribe([[ topic ]], ex);
987
- let subs = this.subs ||(this.subs = new Map());
988
- subs.set((res.topic = topic), (subs.last = res));
989
- return this }// fluent api -- return this and track side effects
990
1044
 
991
1045
  // alias: unsub
992
- unsubscribe(pkt, ex) {
993
- pkt = _as_topics(pkt, ex);
1046
+ unsubscribe(pkt, ex, topic_prefix) {
1047
+ pkt = _as_topics(pkt, ex, topic_prefix);
994
1048
  return this._send('unsubscribe', pkt, pkt)}
995
1049
 
996
- get on_topic() {return this.router.add}
997
-
998
- // alias: sub_topic
999
- subscribe_topic(topic_route, ...args) {
1000
- this.router.add(topic_route, true, args.pop() );// handler
1001
- let topic = this.topic_for(topic_route);
1002
- return this._sub_chain(topic, args.pop() ) }// ex
1003
-
1004
- // alias: unsub_topic
1005
- unsubscribe_topic(topic_route) {
1006
- this.router.remove(topic_route, true);
1007
- let topic = this.topic_for(topic_route);
1008
- return this.unsubscribe([[ topic ]]) }
1009
-
1010
- // alias: shared_sub
1011
- shared_subscribe(group, topic_route, ...args) {
1012
- this.router.add(topic_route, true, args.pop() );// handler
1013
- let topic = this.topic_for(topic_route);
1014
- if (null != group) {
1015
- topic = `$share/${group}/${topic}`;}
1016
- return this._sub_chain(topic, args.pop() ) }// ex
1017
-
1018
- // alias: shared_unsub
1019
- shared_unsubscribe(group, topic_route) {
1020
- this.router.remove(topic_route, true);
1021
- let topic = this.topic_for(topic_route);
1022
- if (null != group) {
1023
- topic = `$share/${group}/${topic}`;}
1024
- return this.unsubscribe([[ topic ]]) }
1025
-
1026
- topic_for(topic_route) {
1027
- return topic_route.replace(/[:*].*$/, '#')}
1028
-
1029
1050
 
1030
1051
  // alias: pub
1031
1052
  publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
@@ -1051,9 +1072,9 @@ class MQTTBase {
1051
1072
  if (undefined === cid) {
1052
1073
  this.client_id = cid = (
1053
1074
 
1054
-
1075
+
1055
1076
 
1056
- this.new_client_id(parts)
1077
+ this.new_client_id(parts)
1057
1078
  );}
1058
1079
 
1059
1080
  return cid}
@@ -1062,66 +1083,85 @@ class MQTTBase {
1062
1083
  return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
1063
1084
 
1064
1085
 
1086
+
1087
+
1088
+
1089
+
1090
+
1091
+
1092
+
1065
1093
 
1066
1094
 
1095
+ // Internal API
1067
1096
 
1097
+ /* async _send(type, pkt) -- provided by _conn_ and transport */
1068
1098
 
1099
+ _init_dispatch(opt) {
1100
+ this.constructor?._once_();
1101
+ let router = this.router =
1102
+ this._init_router?.(opt, this);
1069
1103
 
1104
+ let tgt ={
1105
+ __proto__: opt.on_mqtt_type || {}
1106
+ , router};
1070
1107
 
1108
+ tgt.mqtt_publish ||= router?.invoke;
1109
+ return _mqtt_dispatch(this, tgt)}
1071
1110
 
1111
+ static _aliases() {
1112
+ return ' pub:publish sub:subscribe unsub:unsubscribe '}
1072
1113
 
1114
+ static _once_(self=this) {
1115
+ self._once_ = _=>0;
1116
+ self.MQTTError = MQTTError;
1117
+ let p = self.prototype;
1118
+ for (let alias of self._aliases().split(/\s+/)) {
1119
+ alias = alias.split(':');
1120
+ let fn = alias[1] && p[alias[1]];
1121
+ if (fn) {p[alias[0]] = fn;} } } }
1073
1122
 
1074
- // Internal API
1075
-
1076
- /* async _send(type, pkt) -- provided by _conn_ and transport */
1077
-
1078
- _init_router(opt) {
1079
- return this.router = _mqtt_topic_router()}
1080
1123
 
1081
- _init_dispatch(opt) {
1082
- let tgt ={
1083
- __proto__: opt.on_mqtt_type || {}
1084
- , router: this._init_router(opt, this)};
1124
+ /*
1125
+ on_mqtt_type = {
1126
+ mqtt_auth(pkt, ctx) ::
1127
+ mqtt_connect(pkt, ctx) ::
1128
+ mqtt_connack(pkt, ctx) ::
1129
+ mqtt_disconnect(pkt, ctx) ::
1130
+
1131
+ mqtt_publish(pkt, ctx)
1132
+ mqtt_subscribe(pkt, ctx) ::
1133
+ mqtt_unsubscribe(pkt, ctx) ::
1134
+
1135
+ mqtt_pingreq(pkt, ctx) ::
1136
+ mqtt_pingresp(pkt, ctx) ::
1137
+ }
1138
+ */
1085
1139
 
1086
- tgt.mqtt_publish ||= tgt.router.invoke;
1087
- return _mqtt_dispatch(this, tgt)} }
1088
1140
 
1141
+ const _prefix_topics = (topic_prefix, iterable) =>
1142
+ Array.from(iterable, value =>(
1143
+ value.trim // string
1144
+ ? _prefix_topics(topic_prefix, value)
1145
+ : topic_prefix + value) );
1089
1146
 
1090
- {
1091
- let p = MQTTBase.prototype;
1092
- Object.assign(p,{
1093
- MQTTError
1094
- , pub: p.publish
1095
- , sub: p.subscribe
1096
- , unsub: p.unsubscribe
1097
- , sub_topic: p.subscribe_topic
1098
- , unsub_topic: p.unsubscribe_topic
1099
- , shared_sub: p.shared_subscribe
1100
- , shared_unsub: p.shared_unsubscribe} );
1101
-
1102
- /*
1103
- p.on_mqtt_type = {
1104
- mqtt_auth(pkt, ctx) ::
1105
- mqtt_connect(pkt, ctx) ::
1106
- mqtt_connack(pkt, ctx) ::
1107
- mqtt_disconnect(pkt, ctx) ::
1108
-
1109
- mqtt_publish(pkt, ctx)
1110
- mqtt_subscribe(pkt, ctx) ::
1111
- mqtt_unsubscribe(pkt, ctx) ::
1112
-
1113
- mqtt_pingreq(pkt, ctx) ::
1114
- mqtt_pingresp(pkt, ctx) ::
1115
- }
1116
- */}
1147
+ function _as_topics(pkt, ex, topic_prefix) {
1148
+ if (ex?.trim) {// string
1149
+ topic_prefix = ex;
1150
+ ex = null;}
1117
1151
 
1152
+ pkt =(
1153
+ pkt.trim // string
1154
+ ? {topics:[pkt], ... ex}
1155
+ : pkt[Symbol.iterator]
1156
+ ? {topics:[... pkt], ... ex}
1157
+ : ex ? {...pkt, ...ex}
1158
+ : pkt);
1118
1159
 
1119
- function _as_topics(pkt, ex) {
1120
- if ('string' === typeof pkt) {
1121
- return {topics:[pkt], ... ex}}
1122
- if (pkt[Symbol.iterator]) {
1123
- return {topics:[... pkt], ... ex}}
1124
- return ex ? {...pkt, ...ex} : pkt}
1160
+ if (topic_prefix) {
1161
+ // particularly useful with shared queues, e.g.
1162
+ // topic_prefix = '$share/some-queue-name/'
1163
+ pkt.topics = _prefix_topics(topic_prefix, pkt.topics);}
1164
+ return pkt}
1125
1165
 
1126
1166
 
1127
1167
  async function _pub(self, pkt, pub_opt) {
@@ -1237,53 +1277,53 @@ class MQTTCore extends MQTTBase {
1237
1277
 
1238
1278
 
1239
1279
 
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1240
1286
 
1287
+
1288
+
1289
+
1290
+
1291
+
1241
1292
 
1293
+
1294
+
1295
+
1296
+
1297
+
1242
1298
 
1299
+
1300
+
1301
+
1302
+
1243
1303
 
1304
+
1305
+
1244
1306
 
1307
+
1308
+ with_tcp(...opt) {
1309
+ opt = this._conn_opt(opt);
1310
+ console.log({opt});
1311
+ return this._use_conn (() =>
1312
+ this.with_stream(
1313
+ connect(opt)) ) }
1245
1314
 
1315
+ with_tls(...opt) {
1316
+ opt = this._conn_opt(opt);
1317
+ return this._use_conn (() =>
1318
+ this.with_stream(
1319
+ connect$1(opt)) ) }
1246
1320
 
1247
-
1248
-
1249
-
1250
-
1251
-
1252
-
1253
-
1254
-
1255
-
1256
-
1257
-
1258
-
1259
-
1260
-
1261
-
1262
-
1263
-
1264
-
1265
-
1266
-
1267
-
1268
- with_tcp(...opt) {
1269
- opt = this._conn_opt(opt);
1270
- console.log({opt});
1271
- return this._use_conn (() =>
1272
- this.with_stream(
1273
- connect(opt)) ) }
1274
-
1275
- with_tls(...opt) {
1276
- opt = this._conn_opt(opt);
1277
- return this._use_conn (() =>
1278
- this.with_stream(
1279
- connect$1(opt)) ) }
1280
-
1281
- _conn_opt([a0, a1, a2]) {
1282
- // (port, hostname, options) or (url, options)
1283
- if (Number.isFinite(a0)) {
1284
- return {...a2, port: a0, host: a1}}
1285
- a0 = new URL(a0);
1286
- return {...a1, port: a0.port, host: a0.hostname}}
1321
+ _conn_opt([a0, a1, a2]) {
1322
+ // (port, hostname, options) or (url, options)
1323
+ if (Number.isFinite(a0)) {
1324
+ return {...a2, port: a0, host: a1}}
1325
+ a0 = new URL(a0);
1326
+ return {...a1, port: a0.port, host: a0.hostname}}
1287
1327
 
1288
1328
 
1289
1329
  with_stream(read_stream, write_stream) {
@@ -1329,10 +1369,11 @@ class MQTTCore extends MQTTBase {
1329
1369
 
1330
1370
  return this} }
1331
1371
 
1332
- const version = '0.3.2-0';
1372
+ const version = '0.4.0';
1333
1373
 
1334
1374
  const MQTTClient_v4 = /* #__PURE__ */
1335
- MQTTCore.mqtt_ctx(4, mqtt_opts_v4);
1375
+ with_topic_path_router(
1376
+ MQTTCore.mqtt_ctx(4, mqtt_opts_v4) );
1336
1377
 
1337
1378
  const mqtt_v4 = opt =>
1338
1379
  new MQTTClient_v4(opt);