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/deno/v5.js
CHANGED
|
@@ -769,6 +769,191 @@ const mqtt_opts_v5 =
|
|
|
769
769
|
encode_fns: mqtt_encode_v5,
|
|
770
770
|
mqtt_writer: mqtt_writer_v5, };
|
|
771
771
|
|
|
772
|
+
function parse(str, loose) {
|
|
773
|
+
if (str instanceof RegExp) return { keys:false, pattern:str };
|
|
774
|
+
var c, o, tmp, ext, keys=[], pattern='', arr = str.split('/');
|
|
775
|
+
arr[0] || arr.shift();
|
|
776
|
+
|
|
777
|
+
while (tmp = arr.shift()) {
|
|
778
|
+
c = tmp[0];
|
|
779
|
+
if (c === '*') {
|
|
780
|
+
keys.push('wild');
|
|
781
|
+
pattern += '/(.*)';
|
|
782
|
+
} else if (c === ':') {
|
|
783
|
+
o = tmp.indexOf('?', 1);
|
|
784
|
+
ext = tmp.indexOf('.', 1);
|
|
785
|
+
keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) );
|
|
786
|
+
pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)';
|
|
787
|
+
if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext);
|
|
788
|
+
} else {
|
|
789
|
+
pattern += '/' + tmp;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
return {
|
|
794
|
+
keys: keys,
|
|
795
|
+
pattern: new RegExp('^' + pattern + (loose ? '(?=$|\/)' : '\/?$'), 'i')
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/*
|
|
800
|
+
class AbstractTopicRouter ::
|
|
801
|
+
async invoke(pkt, ctx) ::
|
|
802
|
+
add(topic_route, ...args) ::
|
|
803
|
+
remove(topic_route, priority) ::
|
|
804
|
+
clear(priority) ::
|
|
805
|
+
find(topic) :: // optional
|
|
806
|
+
mqtt_topic(topic_route)
|
|
807
|
+
*/
|
|
808
|
+
|
|
809
|
+
const with_topic_router = mqtt_topic_router =>
|
|
810
|
+
MQTTKlass => class extends MQTTKlass {
|
|
811
|
+
static _aliases() {
|
|
812
|
+
return super._aliases() +
|
|
813
|
+
' sub_topic:subscribe_topic unsub_topic:unsubscribe_topic'}
|
|
814
|
+
|
|
815
|
+
_init_router(opt) {
|
|
816
|
+
return mqtt_topic_router(opt, this)}
|
|
817
|
+
|
|
818
|
+
get on_topic() {return this.router.add}
|
|
819
|
+
|
|
820
|
+
_sub_chain(topic, ex, topic_prefix) {
|
|
821
|
+
let res = this.subscribe([[ topic ]], ex, topic_prefix);
|
|
822
|
+
let subs = this.subs ||(this.subs = new Map());
|
|
823
|
+
subs.set((res.topic = topic), (subs.last = res));
|
|
824
|
+
return this }// fluent api -- return this and track side effects
|
|
825
|
+
|
|
826
|
+
// alias: sub_topic
|
|
827
|
+
subscribe_topic(topic_route, ...args) {
|
|
828
|
+
let router = this.router;
|
|
829
|
+
router.add(topic_route, true, args.pop() );// handler
|
|
830
|
+
let topic = router.mqtt_topic(topic_route);
|
|
831
|
+
return this._sub_chain(topic, ...args ) }// ex, topic_prefix
|
|
832
|
+
|
|
833
|
+
// alias: unsub_topic
|
|
834
|
+
unsubscribe_topic(topic_route, ...args) {
|
|
835
|
+
let router = this.router;
|
|
836
|
+
router.remove(topic_route, true);
|
|
837
|
+
let topic = router.mqtt_topic(topic_route);
|
|
838
|
+
return this.unsubscribe([[ topic ]], ...args ) } };// topic_prefix
|
|
839
|
+
|
|
840
|
+
// Use [regexparam][] for url-like topic parsing
|
|
841
|
+
// [regexparam]: https://github.com/lukeed/regexparam
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
const with_topic_path_router = /* #__PURE__ */
|
|
845
|
+
with_topic_router(mqtt_topic_path_router);
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
const mqtt_topic = topic_route =>
|
|
849
|
+
topic_route
|
|
850
|
+
.replace(/[*].*$/, '#')
|
|
851
|
+
.replace(/:\w+\??/g, '+');
|
|
852
|
+
|
|
853
|
+
const as_topic_path = topic_route =>(
|
|
854
|
+
topic_route
|
|
855
|
+
.replace(/#$/, '*') // replace MQTT # wildcard at end
|
|
856
|
+
.split(/([^\/]*[+][^\/]*)/) // split on MQTT + match tokens
|
|
857
|
+
.reduce (( sz, v, idx ) => sz +(
|
|
858
|
+
idx & 1 // even entires are body, odd are MQTT + tokens
|
|
859
|
+
? `:$${1 + idx>>1}` // replace with `:$#` sequential ids, using ? for partial entries
|
|
860
|
+
: v ) ) );// pass through body
|
|
861
|
+
|
|
862
|
+
function _ignore(pkt, params, ctx) {ctx.done = true;}
|
|
863
|
+
|
|
864
|
+
function mqtt_topic_path_router() {
|
|
865
|
+
let pri_lsts = [[],[]], rm = Symbol();
|
|
866
|
+
let find = topic => _routes_iter(pri_lsts, topic);
|
|
867
|
+
|
|
868
|
+
// return duck-type compatible with AbstractTopicRouter in ./with_topic_router
|
|
869
|
+
return {find, mqtt_topic,
|
|
870
|
+
add(topic_route, ...args) {
|
|
871
|
+
let fn = args.pop();
|
|
872
|
+
let priority = args.pop();
|
|
873
|
+
|
|
874
|
+
if ('function' !== typeof fn) {
|
|
875
|
+
if (false === fn) {
|
|
876
|
+
fn = _ignore;}
|
|
877
|
+
else throw new TypeError()}
|
|
878
|
+
|
|
879
|
+
let rte = parse(as_topic_path(topic_route));
|
|
880
|
+
|
|
881
|
+
rte.key = topic_route;
|
|
882
|
+
rte.tgt = fn;
|
|
883
|
+
pri_lsts[priority ? 0 : 1].push(rte);
|
|
884
|
+
return this}
|
|
885
|
+
|
|
886
|
+
, remove(topic_route, priority) {
|
|
887
|
+
let lst = pri_lsts[priority ? 0 : 1];
|
|
888
|
+
return _route_remove([lst], topic_route)}
|
|
889
|
+
|
|
890
|
+
, clear(priority) {
|
|
891
|
+
pri_lsts[priority ? 0 : 1] = [];
|
|
892
|
+
if (null == priority) {
|
|
893
|
+
pri_lsts[1] = [];} }
|
|
894
|
+
|
|
895
|
+
, async invoke(pkt, ctx) {
|
|
896
|
+
ctx.idx = 0;
|
|
897
|
+
ctx.rm = rm;
|
|
898
|
+
|
|
899
|
+
for (let [fn, params] of find(pkt.topic)) {
|
|
900
|
+
let res = await fn(pkt, params, ctx);
|
|
901
|
+
|
|
902
|
+
if (rm === res) {
|
|
903
|
+
_route_remove(pri_lsts, fn);}
|
|
904
|
+
|
|
905
|
+
if (ctx.done) {
|
|
906
|
+
break}
|
|
907
|
+
else ctx.idx++;}
|
|
908
|
+
|
|
909
|
+
let {pkt_id, qos} = pkt;
|
|
910
|
+
if (1 === qos) {
|
|
911
|
+
await ctx.mqtt._send('puback', {pkt_id});} } } }
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
function * _routes_iter(all_route_lists, topic) {
|
|
915
|
+
for (let route_list of all_route_lists) {
|
|
916
|
+
for (let route of route_list) {
|
|
917
|
+
let res = _route_match_one(topic, route);
|
|
918
|
+
if (undefined !== res) {
|
|
919
|
+
yield res;} } } }
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
function _route_match_one(topic, {keys, pattern, tgt}) {
|
|
923
|
+
let match = '/' !== topic[0]
|
|
924
|
+
? pattern.exec('/'+topic)
|
|
925
|
+
: pattern.exec(topic);
|
|
926
|
+
|
|
927
|
+
if (null === match) {
|
|
928
|
+
return}
|
|
929
|
+
|
|
930
|
+
if (false === keys) {
|
|
931
|
+
let {groups} = match;
|
|
932
|
+
if (! groups) {
|
|
933
|
+
return [tgt]}
|
|
934
|
+
|
|
935
|
+
let params = {};
|
|
936
|
+
for (let k in groups) {
|
|
937
|
+
params[k] = groups[k];}
|
|
938
|
+
|
|
939
|
+
return [tgt, params]}
|
|
940
|
+
|
|
941
|
+
if (0 === keys.length) {
|
|
942
|
+
return [tgt]}
|
|
943
|
+
|
|
944
|
+
let params = {};
|
|
945
|
+
for (let i=0; i<keys.length; i++) {
|
|
946
|
+
params[ keys[i] ] = match[1+i];}
|
|
947
|
+
return [tgt, params]}
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
function _route_remove(all_route_lists, query) {
|
|
951
|
+
let match = route => route===query || route.tgt===query || route.key===query;
|
|
952
|
+
for (let lst of all_route_lists) {
|
|
953
|
+
let i = lst.findIndex(match);
|
|
954
|
+
if (0 <= i) {return !! lst.splice(i,1)} }
|
|
955
|
+
return false}
|
|
956
|
+
|
|
772
957
|
/*
|
|
773
958
|
export function decode_varint_loop(u8, i=0) {
|
|
774
959
|
let i0 = i
|
|
@@ -950,138 +1135,13 @@ function _ping_interval(send_ping) {
|
|
|
950
1135
|
if (td) {
|
|
951
1136
|
tid = setInterval(send_ping, 1000 * td);
|
|
952
1137
|
|
|
953
|
-
|
|
954
|
-
|
|
1138
|
+
// ensure the interval allows the Deno event loop to exit
|
|
1139
|
+
Deno.unrefTimer(tid);
|
|
955
1140
|
|
|
956
|
-
|
|
957
|
-
|
|
1141
|
+
|
|
1142
|
+
|
|
958
1143
|
return true} }) }
|
|
959
1144
|
|
|
960
|
-
function parse(str, loose) {
|
|
961
|
-
if (str instanceof RegExp) return { keys:false, pattern:str };
|
|
962
|
-
var c, o, tmp, ext, keys=[], pattern='', arr = str.split('/');
|
|
963
|
-
arr[0] || arr.shift();
|
|
964
|
-
|
|
965
|
-
while (tmp = arr.shift()) {
|
|
966
|
-
c = tmp[0];
|
|
967
|
-
if (c === '*') {
|
|
968
|
-
keys.push('wild');
|
|
969
|
-
pattern += '/(.*)';
|
|
970
|
-
} else if (c === ':') {
|
|
971
|
-
o = tmp.indexOf('?', 1);
|
|
972
|
-
ext = tmp.indexOf('.', 1);
|
|
973
|
-
keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) );
|
|
974
|
-
pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)';
|
|
975
|
-
if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext);
|
|
976
|
-
} else {
|
|
977
|
-
pattern += '/' + tmp;
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
return {
|
|
982
|
-
keys: keys,
|
|
983
|
-
pattern: new RegExp('^' + pattern + (loose ? '(?=$|\/)' : '\/?$'), 'i')
|
|
984
|
-
};
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// Use [regexparam][] for url-like topic parsing
|
|
988
|
-
|
|
989
|
-
function _ignore(pkt, params, ctx) {ctx.done = true;}
|
|
990
|
-
|
|
991
|
-
function _mqtt_topic_router() {
|
|
992
|
-
let pri_lsts = [[],[]], rm = Symbol();
|
|
993
|
-
let find = topic => _mqtt_routes_iter(pri_lsts, topic);
|
|
994
|
-
|
|
995
|
-
return {find,
|
|
996
|
-
|
|
997
|
-
add(topic_route, ...args) {
|
|
998
|
-
let fn = args.pop();
|
|
999
|
-
let priority = args.pop();
|
|
1000
|
-
|
|
1001
|
-
if ('function' !== typeof fn) {
|
|
1002
|
-
if (false === fn) {
|
|
1003
|
-
fn = _ignore;}
|
|
1004
|
-
else throw new TypeError()}
|
|
1005
|
-
|
|
1006
|
-
let rte = parse(
|
|
1007
|
-
topic_route.replace(/[+#]$/, '*'));
|
|
1008
|
-
|
|
1009
|
-
rte.key = topic_route;
|
|
1010
|
-
rte.tgt = fn;
|
|
1011
|
-
pri_lsts[priority ? 0 : 1].push(rte);
|
|
1012
|
-
return this}
|
|
1013
|
-
|
|
1014
|
-
, remove(topic_route, priority) {
|
|
1015
|
-
let lst = pri_lsts[priority ? 0 : 1];
|
|
1016
|
-
return _mqtt_route_remove([lst], topic_route)}
|
|
1017
|
-
|
|
1018
|
-
, clear(priority) {
|
|
1019
|
-
pri_lsts[priority ? 0 : 1] = [];
|
|
1020
|
-
if (null == priority) {
|
|
1021
|
-
pri_lsts[1] = [];} }
|
|
1022
|
-
|
|
1023
|
-
, async invoke(pkt, ctx) {
|
|
1024
|
-
ctx.idx = 0;
|
|
1025
|
-
ctx.rm = rm;
|
|
1026
|
-
|
|
1027
|
-
for (let [fn, params] of find(pkt.topic)) {
|
|
1028
|
-
let res = await fn(pkt, params, ctx);
|
|
1029
|
-
|
|
1030
|
-
if (rm === res) {
|
|
1031
|
-
_mqtt_route_remove(pri_lsts, fn);}
|
|
1032
|
-
|
|
1033
|
-
if (ctx.done) {
|
|
1034
|
-
break}
|
|
1035
|
-
else ctx.idx++;}
|
|
1036
|
-
|
|
1037
|
-
let {pkt_id, qos} = pkt;
|
|
1038
|
-
if (1 === qos) {
|
|
1039
|
-
await ctx.mqtt._send('puback', {pkt_id});} } } }
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
function * _mqtt_routes_iter(all_route_lists, topic) {
|
|
1043
|
-
for (let route_list of all_route_lists) {
|
|
1044
|
-
for (let route of route_list) {
|
|
1045
|
-
let res = _mqtt_route_match_one(topic, route);
|
|
1046
|
-
if (undefined !== res) {
|
|
1047
|
-
yield res;} } } }
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
function _mqtt_route_match_one(topic, {keys, pattern, tgt}) {
|
|
1051
|
-
let match = '/' !== topic[0]
|
|
1052
|
-
? pattern.exec('/'+topic)
|
|
1053
|
-
: pattern.exec(topic);
|
|
1054
|
-
|
|
1055
|
-
if (null === match) {
|
|
1056
|
-
return}
|
|
1057
|
-
|
|
1058
|
-
if (false === keys) {
|
|
1059
|
-
let {groups} = match;
|
|
1060
|
-
if (! groups) {
|
|
1061
|
-
return [tgt]}
|
|
1062
|
-
|
|
1063
|
-
let params = {};
|
|
1064
|
-
for (let k in groups) {
|
|
1065
|
-
params[k] = groups[k];}
|
|
1066
|
-
|
|
1067
|
-
return [tgt, params]}
|
|
1068
|
-
|
|
1069
|
-
if (0 === keys.length) {
|
|
1070
|
-
return [tgt]}
|
|
1071
|
-
|
|
1072
|
-
let params = {};
|
|
1073
|
-
for (let i=0; i<keys.length; i++) {
|
|
1074
|
-
params[ keys[i] ] = match[1+i];}
|
|
1075
|
-
return [tgt, params]}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
function _mqtt_route_remove(all_route_lists, query) {
|
|
1079
|
-
let match = route => route===query || route.tgt===query || route.key===query;
|
|
1080
|
-
for (let lst of all_route_lists) {
|
|
1081
|
-
let i = lst.findIndex(match);
|
|
1082
|
-
if (0 <= i) {return !! lst.splice(i,1)} }
|
|
1083
|
-
return false}
|
|
1084
|
-
|
|
1085
1145
|
const _mqtt_cmdid_dispatch ={
|
|
1086
1146
|
create(target) {
|
|
1087
1147
|
return {__proto__: this, target, hashbelt: [new Map()]} }
|
|
@@ -1150,8 +1210,7 @@ const _mqtt_cmdid_dispatch ={
|
|
|
1150
1210
|
let fn = target[`mqtt_${pkt.type}`]
|
|
1151
1211
|
|| target.mqtt_pkt;
|
|
1152
1212
|
|
|
1153
|
-
|
|
1154
|
-
await fn.call(target, pkt, ctx);} } })()) };
|
|
1213
|
+
await fn?.call(target, pkt, ctx);} })()) };
|
|
1155
1214
|
|
|
1156
1215
|
function _mqtt_dispatch(opt, target) {
|
|
1157
1216
|
let _disp_ = _mqtt_cmdid_dispatch.create(target);
|
|
@@ -1232,53 +1291,15 @@ class MQTTBase {
|
|
|
1232
1291
|
|
|
1233
1292
|
|
|
1234
1293
|
// alias: sub
|
|
1235
|
-
subscribe(pkt, ex) {
|
|
1236
|
-
pkt = _as_topics(pkt, ex);
|
|
1294
|
+
subscribe(pkt, ex, topic_prefix) {
|
|
1295
|
+
pkt = _as_topics(pkt, ex, topic_prefix);
|
|
1237
1296
|
return this._send('subscribe', pkt, pkt)}
|
|
1238
|
-
_sub_chain(topic, ex) {
|
|
1239
|
-
let res = this.subscribe([[ topic ]], ex);
|
|
1240
|
-
let subs = this.subs ||(this.subs = new Map());
|
|
1241
|
-
subs.set((res.topic = topic), (subs.last = res));
|
|
1242
|
-
return this }// fluent api -- return this and track side effects
|
|
1243
1297
|
|
|
1244
1298
|
// alias: unsub
|
|
1245
|
-
unsubscribe(pkt, ex) {
|
|
1246
|
-
pkt = _as_topics(pkt, ex);
|
|
1299
|
+
unsubscribe(pkt, ex, topic_prefix) {
|
|
1300
|
+
pkt = _as_topics(pkt, ex, topic_prefix);
|
|
1247
1301
|
return this._send('unsubscribe', pkt, pkt)}
|
|
1248
1302
|
|
|
1249
|
-
get on_topic() {return this.router.add}
|
|
1250
|
-
|
|
1251
|
-
// alias: sub_topic
|
|
1252
|
-
subscribe_topic(topic_route, ...args) {
|
|
1253
|
-
this.router.add(topic_route, true, args.pop() );// handler
|
|
1254
|
-
let topic = this.topic_for(topic_route);
|
|
1255
|
-
return this._sub_chain(topic, args.pop() ) }// ex
|
|
1256
|
-
|
|
1257
|
-
// alias: unsub_topic
|
|
1258
|
-
unsubscribe_topic(topic_route) {
|
|
1259
|
-
this.router.remove(topic_route, true);
|
|
1260
|
-
let topic = this.topic_for(topic_route);
|
|
1261
|
-
return this.unsubscribe([[ topic ]]) }
|
|
1262
|
-
|
|
1263
|
-
// alias: shared_sub
|
|
1264
|
-
shared_subscribe(group, topic_route, ...args) {
|
|
1265
|
-
this.router.add(topic_route, true, args.pop() );// handler
|
|
1266
|
-
let topic = this.topic_for(topic_route);
|
|
1267
|
-
if (null != group) {
|
|
1268
|
-
topic = `$share/${group}/${topic}`;}
|
|
1269
|
-
return this._sub_chain(topic, args.pop() ) }// ex
|
|
1270
|
-
|
|
1271
|
-
// alias: shared_unsub
|
|
1272
|
-
shared_unsubscribe(group, topic_route) {
|
|
1273
|
-
this.router.remove(topic_route, true);
|
|
1274
|
-
let topic = this.topic_for(topic_route);
|
|
1275
|
-
if (null != group) {
|
|
1276
|
-
topic = `$share/${group}/${topic}`;}
|
|
1277
|
-
return this.unsubscribe([[ topic ]]) }
|
|
1278
|
-
|
|
1279
|
-
topic_for(topic_route) {
|
|
1280
|
-
return topic_route.replace(/[:*].*$/, '#')}
|
|
1281
|
-
|
|
1282
1303
|
|
|
1283
1304
|
// alias: pub
|
|
1284
1305
|
publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
|
|
@@ -1304,9 +1325,9 @@ class MQTTBase {
|
|
|
1304
1325
|
if (undefined === cid) {
|
|
1305
1326
|
this.client_id = cid = (
|
|
1306
1327
|
|
|
1307
|
-
|
|
1328
|
+
|
|
1308
1329
|
|
|
1309
|
-
|
|
1330
|
+
this.new_client_id(parts)
|
|
1310
1331
|
);}
|
|
1311
1332
|
|
|
1312
1333
|
return cid}
|
|
@@ -1315,66 +1336,85 @@ class MQTTBase {
|
|
|
1315
1336
|
return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
|
|
1316
1337
|
|
|
1317
1338
|
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
|
|
1325
1346
|
|
|
1326
1347
|
|
|
1327
1348
|
// Internal API
|
|
1328
1349
|
|
|
1329
1350
|
/* async _send(type, pkt) -- provided by _conn_ and transport */
|
|
1330
1351
|
|
|
1331
|
-
_init_router(opt) {
|
|
1332
|
-
return this.router = _mqtt_topic_router()}
|
|
1333
|
-
|
|
1334
1352
|
_init_dispatch(opt) {
|
|
1353
|
+
this.constructor?._once_();
|
|
1354
|
+
let router = this.router =
|
|
1355
|
+
this._init_router?.(opt, this);
|
|
1356
|
+
|
|
1335
1357
|
let tgt ={
|
|
1336
1358
|
__proto__: opt.on_mqtt_type || {}
|
|
1337
|
-
, router
|
|
1359
|
+
, router};
|
|
1338
1360
|
|
|
1339
|
-
tgt.mqtt_publish ||=
|
|
1340
|
-
return _mqtt_dispatch(this, tgt)}
|
|
1361
|
+
tgt.mqtt_publish ||= router?.invoke;
|
|
1362
|
+
return _mqtt_dispatch(this, tgt)}
|
|
1341
1363
|
|
|
1364
|
+
static _aliases() {
|
|
1365
|
+
return ' pub:publish sub:subscribe unsub:unsubscribe '}
|
|
1342
1366
|
|
|
1343
|
-
{
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
, unsub_topic: p.unsubscribe_topic
|
|
1352
|
-
, shared_sub: p.shared_subscribe
|
|
1353
|
-
, shared_unsub: p.shared_unsubscribe} );
|
|
1367
|
+
static _once_(self=this) {
|
|
1368
|
+
self._once_ = _=>0;
|
|
1369
|
+
self.MQTTError = MQTTError;
|
|
1370
|
+
let p = self.prototype;
|
|
1371
|
+
for (let alias of self._aliases().split(/\s+/)) {
|
|
1372
|
+
alias = alias.split(':');
|
|
1373
|
+
let fn = alias[1] && p[alias[1]];
|
|
1374
|
+
if (fn) {p[alias[0]] = fn;} } } }
|
|
1354
1375
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1376
|
+
|
|
1377
|
+
/*
|
|
1378
|
+
on_mqtt_type = {
|
|
1379
|
+
mqtt_auth(pkt, ctx) ::
|
|
1380
|
+
mqtt_connect(pkt, ctx) ::
|
|
1381
|
+
mqtt_connack(pkt, ctx) ::
|
|
1382
|
+
mqtt_disconnect(pkt, ctx) ::
|
|
1383
|
+
|
|
1384
|
+
mqtt_publish(pkt, ctx)
|
|
1385
|
+
mqtt_subscribe(pkt, ctx) ::
|
|
1386
|
+
mqtt_unsubscribe(pkt, ctx) ::
|
|
1387
|
+
|
|
1388
|
+
mqtt_pingreq(pkt, ctx) ::
|
|
1389
|
+
mqtt_pingresp(pkt, ctx) ::
|
|
1390
|
+
}
|
|
1391
|
+
*/
|
|
1370
1392
|
|
|
1371
1393
|
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1394
|
+
const _prefix_topics = (topic_prefix, iterable) =>
|
|
1395
|
+
Array.from(iterable, value =>(
|
|
1396
|
+
value.trim // string
|
|
1397
|
+
? _prefix_topics(topic_prefix, value)
|
|
1398
|
+
: topic_prefix + value) );
|
|
1399
|
+
|
|
1400
|
+
function _as_topics(pkt, ex, topic_prefix) {
|
|
1401
|
+
if (ex?.trim) {// string
|
|
1402
|
+
topic_prefix = ex;
|
|
1403
|
+
ex = null;}
|
|
1404
|
+
|
|
1405
|
+
pkt =(
|
|
1406
|
+
pkt.trim // string
|
|
1407
|
+
? {topics:[pkt], ... ex}
|
|
1408
|
+
: pkt[Symbol.iterator]
|
|
1409
|
+
? {topics:[... pkt], ... ex}
|
|
1410
|
+
: ex ? {...pkt, ...ex}
|
|
1411
|
+
: pkt);
|
|
1412
|
+
|
|
1413
|
+
if (topic_prefix) {
|
|
1414
|
+
// particularly useful with shared queues, e.g.
|
|
1415
|
+
// topic_prefix = '$share/some-queue-name/'
|
|
1416
|
+
pkt.topics = _prefix_topics(topic_prefix, pkt.topics);}
|
|
1417
|
+
return pkt}
|
|
1378
1418
|
|
|
1379
1419
|
|
|
1380
1420
|
async function _pub(self, pkt, pub_opt) {
|
|
@@ -1490,53 +1530,53 @@ class MQTTCore extends MQTTBase {
|
|
|
1490
1530
|
|
|
1491
1531
|
|
|
1492
1532
|
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
with_tls(...opt) {
|
|
1501
|
-
opt = this._conn_opt(opt);
|
|
1502
|
-
return this._use_conn (() =>
|
|
1503
|
-
this.with_deno_iter(
|
|
1504
|
-
Deno.connectTls(opt)) ) }
|
|
1505
|
-
|
|
1506
|
-
with_deno_iter(conn) {
|
|
1507
|
-
return this.with_async_iter(
|
|
1508
|
-
conn.then(Deno.iter),
|
|
1509
|
-
async u8_pkt =>
|
|
1510
|
-
(await conn).write(u8_pkt)) }
|
|
1511
|
-
|
|
1512
|
-
_conn_opt([a0, a1, a2]) {
|
|
1513
|
-
// (port, hostname, options) or (url, options)
|
|
1514
|
-
if (Number.isFinite(a0)) {
|
|
1515
|
-
return {...a2, port: a0, hostname: a1}}
|
|
1516
|
-
|
|
1517
|
-
a0 = new URL(a0);
|
|
1518
|
-
return {...a1, port: a0.port, hostname: a0.hostname}}
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
+
with_tcp(...opt) {
|
|
1534
|
+
opt = this._conn_opt(opt);
|
|
1535
|
+
opt.transport = 'tcp';
|
|
1536
|
+
return this._use_conn (() =>
|
|
1537
|
+
this.with_deno_iter(
|
|
1538
|
+
Deno.connect(opt)) ) }
|
|
1533
1539
|
|
|
1540
|
+
with_tls(...opt) {
|
|
1541
|
+
opt = this._conn_opt(opt);
|
|
1542
|
+
return this._use_conn (() =>
|
|
1543
|
+
this.with_deno_iter(
|
|
1544
|
+
Deno.connectTls(opt)) ) }
|
|
1534
1545
|
|
|
1546
|
+
with_deno_iter(conn) {
|
|
1547
|
+
return this.with_async_iter(
|
|
1548
|
+
conn.then(Deno.iter),
|
|
1549
|
+
async u8_pkt =>
|
|
1550
|
+
(await conn).write(u8_pkt)) }
|
|
1535
1551
|
|
|
1552
|
+
_conn_opt([a0, a1, a2]) {
|
|
1553
|
+
// (port, hostname, options) or (url, options)
|
|
1554
|
+
if (Number.isFinite(a0)) {
|
|
1555
|
+
return {...a2, port: a0, hostname: a1}}
|
|
1536
1556
|
|
|
1557
|
+
a0 = new URL(a0);
|
|
1558
|
+
return {...a1, port: a0.port, hostname: a0.hostname}}
|
|
1537
1559
|
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
|
|
1563
|
+
|
|
1564
|
+
|
|
1565
|
+
|
|
1566
|
+
|
|
1538
1567
|
|
|
1568
|
+
|
|
1569
|
+
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
|
|
1539
1573
|
|
|
1574
|
+
|
|
1575
|
+
|
|
1576
|
+
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
|
|
1540
1580
|
|
|
1541
1581
|
|
|
1542
1582
|
with_stream(read_stream, write_stream) {
|
|
@@ -1582,13 +1622,15 @@ class MQTTCore extends MQTTBase {
|
|
|
1582
1622
|
|
|
1583
1623
|
return this} }
|
|
1584
1624
|
|
|
1585
|
-
const version = '0.
|
|
1625
|
+
const version = '0.4.0';
|
|
1586
1626
|
|
|
1587
1627
|
const MQTTClient_v4 = /* #__PURE__ */
|
|
1588
|
-
|
|
1628
|
+
with_topic_path_router(
|
|
1629
|
+
MQTTCore.mqtt_ctx(4, mqtt_opts_v5) );
|
|
1589
1630
|
|
|
1590
1631
|
const MQTTClient_v5 = /* #__PURE__ */
|
|
1591
|
-
|
|
1632
|
+
with_topic_path_router(
|
|
1633
|
+
MQTTCore.mqtt_ctx(5, mqtt_opts_v5) );
|
|
1592
1634
|
|
|
1593
1635
|
const mqtt_v4 = opt =>
|
|
1594
1636
|
new MQTTClient_v4(opt);
|