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