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