u8-mqtt 0.3.2-0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/cjs/basic-v4.cjs +1200 -0
- package/cjs/basic-v4.cjs.map +1 -0
- package/cjs/basic-v5.cjs +1464 -0
- package/cjs/basic-v5.cjs.map +1 -0
- package/cjs/index.cjs +312 -269
- package/cjs/index.cjs.map +1 -1
- package/cjs/v4.cjs +307 -264
- package/cjs/v4.cjs.map +1 -1
- package/cjs/v5.cjs +309 -265
- package/cjs/v5.cjs.map +1 -1
- package/code/_cmdid_dispatch.jsy +1 -3
- package/code/base.jsy +64 -89
- 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} +36 -12
- package/code/v4.js +3 -1
- package/code/v5.js +5 -2
- package/code/with_topic_router.jsy +42 -0
- package/esm/deno/basic-v4.js +1188 -0
- package/esm/deno/basic-v4.js.map +1 -0
- package/esm/deno/basic-v5.js +1450 -0
- package/esm/deno/basic-v5.js.map +1 -0
- package/esm/deno/index.js +310 -266
- package/esm/deno/index.js.map +1 -1
- package/esm/deno/v4.js +307 -264
- package/esm/deno/v4.js.map +1 -1
- package/esm/deno/v5.js +309 -265
- package/esm/deno/v5.js.map +1 -1
- package/esm/node/basic-v4.js +1191 -0
- package/esm/node/basic-v4.js.map +1 -0
- package/esm/node/basic-v4.mjs +1191 -0
- package/esm/node/basic-v4.mjs.map +1 -0
- package/esm/node/basic-v5.js +1453 -0
- package/esm/node/basic-v5.js.map +1 -0
- package/esm/node/basic-v5.mjs +1453 -0
- package/esm/node/basic-v5.mjs.map +1 -0
- package/esm/node/index.js +310 -266
- package/esm/node/index.js.map +1 -1
- package/esm/node/index.mjs +310 -266
- package/esm/node/index.mjs.map +1 -1
- package/esm/node/v4.js +307 -264
- package/esm/node/v4.js.map +1 -1
- package/esm/node/v4.mjs +307 -264
- package/esm/node/v4.mjs.map +1 -1
- package/esm/node/v5.js +309 -265
- package/esm/node/v5.js.map +1 -1
- package/esm/node/v5.mjs +309 -265
- package/esm/node/v5.mjs.map +1 -1
- package/esm/web/basic-v4.js +1188 -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 +1450 -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 +309 -265
- 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 +307 -264
- 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 +308 -264
- 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,198 @@ 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, client, target) {
|
|
560
|
+
let router = this.router = target.router =
|
|
561
|
+
mqtt_topic_router(opt, this);
|
|
562
|
+
return router?.invoke}
|
|
563
|
+
get on_topic() {return this.router.add}
|
|
564
|
+
|
|
565
|
+
_sub_chain(topic, ex, topic_prefix) {
|
|
566
|
+
let res = this.subscribe([[ topic ]], ex, topic_prefix);
|
|
567
|
+
let subs = this.subs ||(this.subs = new Map());
|
|
568
|
+
subs.set((res.topic = topic), (subs.last = res));
|
|
569
|
+
return this }// fluent api -- return this and track side effects
|
|
570
|
+
|
|
571
|
+
// alias: sub_topic
|
|
572
|
+
subscribe_topic(topic_route, ...args) {
|
|
573
|
+
let router = this.router;
|
|
574
|
+
router.add(topic_route, true, args.pop() );// handler
|
|
575
|
+
let topic = router.mqtt_topic(topic_route);
|
|
576
|
+
return this._sub_chain(topic, ...args ) }// ex, topic_prefix
|
|
577
|
+
|
|
578
|
+
// alias: unsub_topic
|
|
579
|
+
unsubscribe_topic(topic_route, ...args) {
|
|
580
|
+
let router = this.router;
|
|
581
|
+
router.remove(topic_route, true);
|
|
582
|
+
let topic = router.mqtt_topic(topic_route);
|
|
583
|
+
return this.unsubscribe([[ topic ]], ...args ) } };// topic_prefix
|
|
584
|
+
|
|
585
|
+
// Use [regexparam][] for url-like topic parsing
|
|
586
|
+
// [regexparam]: https://github.com/lukeed/regexparam
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
const with_topic_path_router = /* #__PURE__ */
|
|
590
|
+
with_topic_router(mqtt_topic_path_router);
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
const mqtt_topic = topic_route =>
|
|
594
|
+
topic_route
|
|
595
|
+
.replace(/[*].*$/, '#')
|
|
596
|
+
.replace(/:\w+\??/g, '+');
|
|
597
|
+
|
|
598
|
+
/* From the [MQTT v5 Spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Topic_Names_and)
|
|
599
|
+
4.7.1.2 Multi-level wildcard -- (‘#’ U+0023)
|
|
600
|
+
... MUST be specified either on its own or following a topic level separator.
|
|
601
|
+
In either case it MUST be the last character specified in the Topic Filter
|
|
602
|
+
|
|
603
|
+
4.7.1.3 Single-level wildcard -- (‘+’ U+002B)
|
|
604
|
+
...it MUST occupy an entire level of the filter.
|
|
605
|
+
*/
|
|
606
|
+
|
|
607
|
+
const as_topic_path = (topic_route, id) =>(
|
|
608
|
+
id=1,
|
|
609
|
+
topic_route
|
|
610
|
+
.replace(/#$/, '*' )// replace MQTT '#' multi-level wildcard at end
|
|
611
|
+
.replace(/\+/g, () => `:$${id++}` ) );// replace MQTT '+' single-level wildcards
|
|
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
|
+
|
|
516
708
|
/*
|
|
517
709
|
export function decode_varint_loop(u8, i=0) {
|
|
518
710
|
let i0 = i
|
|
@@ -694,138 +886,13 @@ function _ping_interval(send_ping) {
|
|
|
694
886
|
if (td) {
|
|
695
887
|
tid = setInterval(send_ping, 1000 * td);
|
|
696
888
|
|
|
697
|
-
|
|
698
|
-
|
|
889
|
+
|
|
890
|
+
|
|
699
891
|
|
|
700
|
-
|
|
701
|
-
|
|
892
|
+
// ensure the interval allows the NodeJS event loop to exit
|
|
893
|
+
tid.unref?.();
|
|
702
894
|
return true} }) }
|
|
703
895
|
|
|
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
896
|
const _mqtt_cmdid_dispatch ={
|
|
830
897
|
create(target) {
|
|
831
898
|
return {__proto__: this, target, hashbelt: [new Map()]} }
|
|
@@ -894,8 +961,7 @@ const _mqtt_cmdid_dispatch ={
|
|
|
894
961
|
let fn = target[`mqtt_${pkt.type}`]
|
|
895
962
|
|| target.mqtt_pkt;
|
|
896
963
|
|
|
897
|
-
|
|
898
|
-
await fn.call(target, pkt, ctx);} } })()) };
|
|
964
|
+
await fn?.call(target, pkt, ctx);} })()) };
|
|
899
965
|
|
|
900
966
|
function _mqtt_dispatch(opt, target) {
|
|
901
967
|
let _disp_ = _mqtt_cmdid_dispatch.create(target);
|
|
@@ -976,53 +1042,15 @@ class MQTTBase {
|
|
|
976
1042
|
|
|
977
1043
|
|
|
978
1044
|
// alias: sub
|
|
979
|
-
subscribe(pkt, ex) {
|
|
980
|
-
pkt = _as_topics(pkt, ex);
|
|
1045
|
+
subscribe(pkt, ex, topic_prefix) {
|
|
1046
|
+
pkt = _as_topics(pkt, ex, topic_prefix);
|
|
981
1047
|
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
1048
|
|
|
988
1049
|
// alias: unsub
|
|
989
|
-
unsubscribe(pkt, ex) {
|
|
990
|
-
pkt = _as_topics(pkt, ex);
|
|
1050
|
+
unsubscribe(pkt, ex, topic_prefix) {
|
|
1051
|
+
pkt = _as_topics(pkt, ex, topic_prefix);
|
|
991
1052
|
return this._send('unsubscribe', pkt, pkt)}
|
|
992
1053
|
|
|
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
1054
|
|
|
1027
1055
|
// alias: pub
|
|
1028
1056
|
publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
|
|
@@ -1048,9 +1076,9 @@ class MQTTBase {
|
|
|
1048
1076
|
if (undefined === cid) {
|
|
1049
1077
|
this.client_id = cid = (
|
|
1050
1078
|
|
|
1051
|
-
|
|
1079
|
+
this.sess_client_id(parts)
|
|
1052
1080
|
|
|
1053
|
-
|
|
1081
|
+
|
|
1054
1082
|
);}
|
|
1055
1083
|
|
|
1056
1084
|
return cid}
|
|
@@ -1059,66 +1087,80 @@ class MQTTBase {
|
|
|
1059
1087
|
return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
|
|
1060
1088
|
|
|
1061
1089
|
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1090
|
+
sess_client_id(parts) {
|
|
1091
|
+
let key = parts.join('\x20');
|
|
1092
|
+
let cid = sessionStorage.getItem(key);
|
|
1093
|
+
if (null == cid) {
|
|
1094
|
+
cid = this.new_client_id(parts);
|
|
1095
|
+
sessionStorage.setItem(key, cid);}
|
|
1096
|
+
return cid}
|
|
1069
1097
|
|
|
1070
1098
|
|
|
1071
1099
|
// Internal API
|
|
1072
1100
|
|
|
1073
1101
|
/* async _send(type, pkt) -- provided by _conn_ and transport */
|
|
1074
1102
|
|
|
1075
|
-
_init_router(opt) {
|
|
1076
|
-
return this.router = _mqtt_topic_router()}
|
|
1077
|
-
|
|
1078
1103
|
_init_dispatch(opt) {
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1104
|
+
this.constructor?._once_();
|
|
1105
|
+
let target ={__proto__: opt.on_mqtt_type};
|
|
1106
|
+
target.mqtt_publish ||=
|
|
1107
|
+
this._init_router?.(opt, this, target);
|
|
1108
|
+
return _mqtt_dispatch(this, target)}
|
|
1082
1109
|
|
|
1083
|
-
|
|
1084
|
-
return
|
|
1110
|
+
static _aliases() {
|
|
1111
|
+
return ' pub:publish sub:subscribe unsub:unsubscribe '}
|
|
1085
1112
|
|
|
1113
|
+
static _once_(self=this) {
|
|
1114
|
+
self._once_ = _=>0;
|
|
1115
|
+
self.MQTTError = MQTTError;
|
|
1116
|
+
let p = self.prototype;
|
|
1117
|
+
for (let alias of self._aliases().split(/\s+/)) {
|
|
1118
|
+
alias = alias.split(':');
|
|
1119
|
+
let fn = alias[1] && p[alias[1]];
|
|
1120
|
+
if (fn) {p[alias[0]] = fn;} } } }
|
|
1086
1121
|
|
|
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
1122
|
|
|
1123
|
+
/*
|
|
1124
|
+
on_mqtt_type = {
|
|
1125
|
+
mqtt_auth(pkt, ctx) ::
|
|
1126
|
+
mqtt_connect(pkt, ctx) ::
|
|
1127
|
+
mqtt_connack(pkt, ctx) ::
|
|
1128
|
+
mqtt_disconnect(pkt, ctx) ::
|
|
1129
|
+
|
|
1130
|
+
mqtt_publish(pkt, ctx)
|
|
1131
|
+
mqtt_subscribe(pkt, ctx) ::
|
|
1132
|
+
mqtt_unsubscribe(pkt, ctx) ::
|
|
1133
|
+
|
|
1134
|
+
mqtt_pingreq(pkt, ctx) ::
|
|
1135
|
+
mqtt_pingresp(pkt, ctx) ::
|
|
1136
|
+
}
|
|
1137
|
+
*/
|
|
1115
1138
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1139
|
+
|
|
1140
|
+
const _prefix_topics = (topic_prefix, iterable) =>
|
|
1141
|
+
Array.from(iterable, value =>(
|
|
1142
|
+
value.trim // string
|
|
1143
|
+
? _prefix_topics(topic_prefix, value)
|
|
1144
|
+
: topic_prefix + value) );
|
|
1145
|
+
|
|
1146
|
+
function _as_topics(pkt, ex, topic_prefix) {
|
|
1147
|
+
if (ex?.trim) {// string
|
|
1148
|
+
topic_prefix = ex;
|
|
1149
|
+
ex = null;}
|
|
1150
|
+
|
|
1151
|
+
pkt =(
|
|
1152
|
+
pkt.trim // string
|
|
1153
|
+
? {topics:[pkt], ... ex}
|
|
1154
|
+
: pkt[Symbol.iterator]
|
|
1155
|
+
? {topics:[... pkt], ... ex}
|
|
1156
|
+
: ex ? {...pkt, ...ex}
|
|
1157
|
+
: pkt);
|
|
1158
|
+
|
|
1159
|
+
if (topic_prefix) {
|
|
1160
|
+
// particularly useful with shared queues, e.g.
|
|
1161
|
+
// topic_prefix = '$share/some-queue-name/'
|
|
1162
|
+
pkt.topics = _prefix_topics(topic_prefix, pkt.topics);}
|
|
1163
|
+
return pkt}
|
|
1122
1164
|
|
|
1123
1165
|
|
|
1124
1166
|
async function _pub(self, pkt, pub_opt) {
|
|
@@ -1234,53 +1276,53 @@ class MQTTCore extends MQTTBase {
|
|
|
1234
1276
|
|
|
1235
1277
|
|
|
1236
1278
|
|
|
1279
|
+
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
|
|
1283
|
+
|
|
1284
|
+
|
|
1237
1285
|
|
|
1286
|
+
|
|
1287
|
+
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
|
|
1238
1291
|
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
|
|
1239
1297
|
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
|
|
1240
1302
|
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1303
|
+
|
|
1304
|
+
|
|
1263
1305
|
|
|
1264
1306
|
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1265
1313
|
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1266
1319
|
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1284
1326
|
|
|
1285
1327
|
|
|
1286
1328
|
with_stream(read_stream, write_stream) {
|
|
@@ -1326,10 +1368,11 @@ class MQTTCore extends MQTTBase {
|
|
|
1326
1368
|
|
|
1327
1369
|
return this} }
|
|
1328
1370
|
|
|
1329
|
-
const version = '0.
|
|
1371
|
+
const version = '0.4.1';
|
|
1330
1372
|
|
|
1331
1373
|
const MQTTClient_v4 = /* #__PURE__ */
|
|
1332
|
-
|
|
1374
|
+
with_topic_path_router(
|
|
1375
|
+
MQTTCore.mqtt_ctx(4, mqtt_opts_v4) );
|
|
1333
1376
|
|
|
1334
1377
|
const mqtt_v4 = opt =>
|
|
1335
1378
|
new MQTTClient_v4(opt);
|