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