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/deno/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
|
+
// ensure the interval allows the Deno event loop to exit
|
|
890
|
+
Deno.unrefTimer(tid);
|
|
699
891
|
|
|
700
|
-
|
|
701
|
-
|
|
892
|
+
|
|
893
|
+
|
|
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
|
+
|
|
1052
1080
|
|
|
1053
|
-
|
|
1081
|
+
this.new_client_id(parts)
|
|
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
|
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1062
1097
|
|
|
1063
1098
|
|
|
1099
|
+
// Internal API
|
|
1064
1100
|
|
|
1101
|
+
/* async _send(type, pkt) -- provided by _conn_ and transport */
|
|
1065
1102
|
|
|
1103
|
+
_init_dispatch(opt) {
|
|
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)}
|
|
1066
1109
|
|
|
1110
|
+
static _aliases() {
|
|
1111
|
+
return ' pub:publish sub:subscribe unsub:unsubscribe '}
|
|
1067
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;} } } }
|
|
1068
1121
|
|
|
1069
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
|
+
*/
|
|
1070
1138
|
|
|
1071
|
-
// Internal API
|
|
1072
|
-
|
|
1073
|
-
/* async _send(type, pkt) -- provided by _conn_ and transport */
|
|
1074
|
-
|
|
1075
|
-
_init_router(opt) {
|
|
1076
|
-
return this.router = _mqtt_topic_router()}
|
|
1077
|
-
|
|
1078
|
-
_init_dispatch(opt) {
|
|
1079
|
-
let tgt ={
|
|
1080
|
-
__proto__: opt.on_mqtt_type || {}
|
|
1081
|
-
, router: this._init_router(opt, this)};
|
|
1082
|
-
|
|
1083
|
-
tgt.mqtt_publish ||= tgt.router.invoke;
|
|
1084
|
-
return _mqtt_dispatch(this, tgt)} }
|
|
1085
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) );
|
|
1086
1145
|
|
|
1087
|
-
{
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
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
|
-
*/}
|
|
1146
|
+
function _as_topics(pkt, ex, topic_prefix) {
|
|
1147
|
+
if (ex?.trim) {// string
|
|
1148
|
+
topic_prefix = ex;
|
|
1149
|
+
ex = null;}
|
|
1114
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);
|
|
1115
1158
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
return ex ? {...pkt, ...ex} : pkt}
|
|
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
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
with_tls(...opt) {
|
|
1245
|
-
opt = this._conn_opt(opt);
|
|
1246
|
-
return this._use_conn (() =>
|
|
1247
|
-
this.with_deno_iter(
|
|
1248
|
-
Deno.connectTls(opt)) ) }
|
|
1249
|
-
|
|
1250
|
-
with_deno_iter(conn) {
|
|
1251
|
-
return this.with_async_iter(
|
|
1252
|
-
conn.then(Deno.iter),
|
|
1253
|
-
async u8_pkt =>
|
|
1254
|
-
(await conn).write(u8_pkt)) }
|
|
1255
|
-
|
|
1256
|
-
_conn_opt([a0, a1, a2]) {
|
|
1257
|
-
// (port, hostname, options) or (url, options)
|
|
1258
|
-
if (Number.isFinite(a0)) {
|
|
1259
|
-
return {...a2, port: a0, hostname: a1}}
|
|
1260
|
-
|
|
1261
|
-
a0 = new URL(a0);
|
|
1262
|
-
return {...a1, port: a0.port, hostname: a0.hostname}}
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1279
|
+
with_tcp(...opt) {
|
|
1280
|
+
opt = this._conn_opt(opt);
|
|
1281
|
+
opt.transport = 'tcp';
|
|
1282
|
+
return this._use_conn (() =>
|
|
1283
|
+
this.with_deno_iter(
|
|
1284
|
+
Deno.connect(opt)) ) }
|
|
1277
1285
|
|
|
1286
|
+
with_tls(...opt) {
|
|
1287
|
+
opt = this._conn_opt(opt);
|
|
1288
|
+
return this._use_conn (() =>
|
|
1289
|
+
this.with_deno_iter(
|
|
1290
|
+
Deno.connectTls(opt)) ) }
|
|
1278
1291
|
|
|
1292
|
+
with_deno_iter(conn) {
|
|
1293
|
+
return this.with_async_iter(
|
|
1294
|
+
conn.then(Deno.iter),
|
|
1295
|
+
async u8_pkt =>
|
|
1296
|
+
(await conn).write(u8_pkt)) }
|
|
1279
1297
|
|
|
1298
|
+
_conn_opt([a0, a1, a2]) {
|
|
1299
|
+
// (port, hostname, options) or (url, options)
|
|
1300
|
+
if (Number.isFinite(a0)) {
|
|
1301
|
+
return {...a2, port: a0, hostname: a1}}
|
|
1280
1302
|
|
|
1303
|
+
a0 = new URL(a0);
|
|
1304
|
+
return {...a1, port: a0.port, hostname: a0.hostname}}
|
|
1281
1305
|
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1282
1313
|
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1283
1319
|
|
|
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);
|