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.
- package/README.md +5 -5
- package/cjs/basic-v4.cjs +1205 -0
- package/cjs/basic-v4.cjs.map +1 -0
- package/cjs/basic-v5.cjs +1469 -0
- package/cjs/basic-v5.cjs.map +1 -0
- package/cjs/index.cjs +308 -267
- package/cjs/index.cjs.map +1 -1
- package/cjs/v4.cjs +303 -262
- package/cjs/v4.cjs.map +1 -1
- package/cjs/v5.cjs +305 -263
- package/cjs/v5.cjs.map +1 -1
- package/code/_cmdid_dispatch.jsy +1 -3
- package/code/base.jsy +64 -84
- package/code/basic-v4.js +18 -0
- package/code/basic-v5.js +26 -0
- package/code/index.js +2 -1
- package/code/{_router.jsy → router_path.jsy} +30 -12
- package/code/v4.js +3 -1
- package/code/v5.js +5 -2
- package/code/with_topic_router.jsy +41 -0
- package/esm/deno/basic-v4.js +1193 -0
- package/esm/deno/basic-v4.js.map +1 -0
- package/esm/deno/basic-v5.js +1455 -0
- package/esm/deno/basic-v5.js.map +1 -0
- package/esm/deno/index.js +306 -264
- package/esm/deno/index.js.map +1 -1
- package/esm/deno/v4.js +303 -262
- package/esm/deno/v4.js.map +1 -1
- package/esm/deno/v5.js +305 -263
- package/esm/deno/v5.js.map +1 -1
- package/esm/node/basic-v4.js +1196 -0
- package/esm/node/basic-v4.js.map +1 -0
- package/esm/node/basic-v4.mjs +1196 -0
- package/esm/node/basic-v4.mjs.map +1 -0
- package/esm/node/basic-v5.js +1458 -0
- package/esm/node/basic-v5.js.map +1 -0
- package/esm/node/basic-v5.mjs +1458 -0
- package/esm/node/basic-v5.mjs.map +1 -0
- package/esm/node/index.js +306 -264
- package/esm/node/index.js.map +1 -1
- package/esm/node/index.mjs +306 -264
- package/esm/node/index.mjs.map +1 -1
- package/esm/node/v4.js +303 -262
- package/esm/node/v4.js.map +1 -1
- package/esm/node/v4.mjs +303 -262
- package/esm/node/v4.mjs.map +1 -1
- package/esm/node/v5.js +305 -263
- package/esm/node/v5.js.map +1 -1
- package/esm/node/v5.mjs +305 -263
- package/esm/node/v5.mjs.map +1 -1
- package/esm/web/basic-v4.js +1193 -0
- package/esm/web/basic-v4.js.map +1 -0
- package/esm/web/basic-v4.min.js +1 -0
- package/esm/web/basic-v4.min.js.br +0 -0
- package/esm/web/basic-v4.min.js.gz +0 -0
- package/esm/web/basic-v5.js +1455 -0
- package/esm/web/basic-v5.js.map +1 -0
- package/esm/web/basic-v5.min.js +1 -0
- package/esm/web/basic-v5.min.js.br +0 -0
- package/esm/web/basic-v5.min.js.gz +0 -0
- package/esm/web/index.js +305 -263
- package/esm/web/index.js.map +1 -1
- package/esm/web/index.min.js +1 -1
- package/esm/web/index.min.js.br +0 -0
- package/esm/web/index.min.js.gz +0 -0
- package/esm/web/v4.js +303 -262
- package/esm/web/v4.js.map +1 -1
- package/esm/web/v4.min.js +1 -1
- package/esm/web/v4.min.js.br +0 -0
- package/esm/web/v4.min.js.gz +0 -0
- package/esm/web/v5.js +304 -262
- package/esm/web/v5.js.map +1 -1
- package/esm/web/v5.min.js +1 -1
- package/esm/web/v5.min.js.br +0 -0
- package/esm/web/v5.min.js.gz +0 -0
- package/package.json +5 -5
package/esm/node/v4.mjs
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
|
-
|
|
704
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
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
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
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
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
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.
|
|
1372
|
+
const version = '0.4.0';
|
|
1333
1373
|
|
|
1334
1374
|
const MQTTClient_v4 = /* #__PURE__ */
|
|
1335
|
-
|
|
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);
|