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