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/cjs/index.cjs
CHANGED
|
@@ -776,6 +776,198 @@ 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, client, target) {
|
|
823
|
+
let router = this.router = target.router =
|
|
824
|
+
mqtt_topic_router(opt, this);
|
|
825
|
+
return router?.invoke}
|
|
826
|
+
get on_topic() {return this.router.add}
|
|
827
|
+
|
|
828
|
+
_sub_chain(topic, ex, topic_prefix) {
|
|
829
|
+
let res = this.subscribe([[ topic ]], ex, topic_prefix);
|
|
830
|
+
let subs = this.subs ||(this.subs = new Map());
|
|
831
|
+
subs.set((res.topic = topic), (subs.last = res));
|
|
832
|
+
return this }// fluent api -- return this and track side effects
|
|
833
|
+
|
|
834
|
+
// alias: sub_topic
|
|
835
|
+
subscribe_topic(topic_route, ...args) {
|
|
836
|
+
let router = this.router;
|
|
837
|
+
router.add(topic_route, true, args.pop() );// handler
|
|
838
|
+
let topic = router.mqtt_topic(topic_route);
|
|
839
|
+
return this._sub_chain(topic, ...args ) }// ex, topic_prefix
|
|
840
|
+
|
|
841
|
+
// alias: unsub_topic
|
|
842
|
+
unsubscribe_topic(topic_route, ...args) {
|
|
843
|
+
let router = this.router;
|
|
844
|
+
router.remove(topic_route, true);
|
|
845
|
+
let topic = router.mqtt_topic(topic_route);
|
|
846
|
+
return this.unsubscribe([[ topic ]], ...args ) } };// topic_prefix
|
|
847
|
+
|
|
848
|
+
// Use [regexparam][] for url-like topic parsing
|
|
849
|
+
// [regexparam]: https://github.com/lukeed/regexparam
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
const with_topic_path_router = /* #__PURE__ */
|
|
853
|
+
with_topic_router(mqtt_topic_path_router);
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
const mqtt_topic = topic_route =>
|
|
857
|
+
topic_route
|
|
858
|
+
.replace(/[*].*$/, '#')
|
|
859
|
+
.replace(/:\w+\??/g, '+');
|
|
860
|
+
|
|
861
|
+
/* From the [MQTT v5 Spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Topic_Names_and)
|
|
862
|
+
4.7.1.2 Multi-level wildcard -- (‘#’ U+0023)
|
|
863
|
+
... MUST be specified either on its own or following a topic level separator.
|
|
864
|
+
In either case it MUST be the last character specified in the Topic Filter
|
|
865
|
+
|
|
866
|
+
4.7.1.3 Single-level wildcard -- (‘+’ U+002B)
|
|
867
|
+
...it MUST occupy an entire level of the filter.
|
|
868
|
+
*/
|
|
869
|
+
|
|
870
|
+
const as_topic_path = (topic_route, id) =>(
|
|
871
|
+
id=1,
|
|
872
|
+
topic_route
|
|
873
|
+
.replace(/#$/, '*' )// replace MQTT '#' multi-level wildcard at end
|
|
874
|
+
.replace(/\+/g, () => `:$${id++}` ) );// replace MQTT '+' single-level wildcards
|
|
875
|
+
|
|
876
|
+
function _ignore(pkt, params, ctx) {ctx.done = true;}
|
|
877
|
+
|
|
878
|
+
function mqtt_topic_path_router() {
|
|
879
|
+
let pri_lsts = [[],[]], rm = Symbol();
|
|
880
|
+
let find = topic => _routes_iter(pri_lsts, topic);
|
|
881
|
+
|
|
882
|
+
// return duck-type compatible with AbstractTopicRouter in ./with_topic_router
|
|
883
|
+
return {find, mqtt_topic,
|
|
884
|
+
add(topic_route, ...args) {
|
|
885
|
+
let fn = args.pop();
|
|
886
|
+
let priority = args.pop();
|
|
887
|
+
|
|
888
|
+
if ('function' !== typeof fn) {
|
|
889
|
+
if (false === fn) {
|
|
890
|
+
fn = _ignore;}
|
|
891
|
+
else throw new TypeError()}
|
|
892
|
+
|
|
893
|
+
let rte = parse(as_topic_path(topic_route));
|
|
894
|
+
|
|
895
|
+
rte.key = topic_route;
|
|
896
|
+
rte.tgt = fn;
|
|
897
|
+
pri_lsts[priority ? 0 : 1].push(rte);
|
|
898
|
+
return this}
|
|
899
|
+
|
|
900
|
+
, remove(topic_route, priority) {
|
|
901
|
+
let lst = pri_lsts[priority ? 0 : 1];
|
|
902
|
+
return _route_remove([lst], topic_route)}
|
|
903
|
+
|
|
904
|
+
, clear(priority) {
|
|
905
|
+
pri_lsts[priority ? 0 : 1] = [];
|
|
906
|
+
if (null == priority) {
|
|
907
|
+
pri_lsts[1] = [];} }
|
|
908
|
+
|
|
909
|
+
, async invoke(pkt, ctx) {
|
|
910
|
+
ctx.idx = 0;
|
|
911
|
+
ctx.rm = rm;
|
|
912
|
+
|
|
913
|
+
for (let [fn, params] of find(pkt.topic)) {
|
|
914
|
+
let res = await fn(pkt, params, ctx);
|
|
915
|
+
|
|
916
|
+
if (rm === res) {
|
|
917
|
+
_route_remove(pri_lsts, fn);}
|
|
918
|
+
|
|
919
|
+
if (ctx.done) {
|
|
920
|
+
break}
|
|
921
|
+
else ctx.idx++;}
|
|
922
|
+
|
|
923
|
+
let {pkt_id, qos} = pkt;
|
|
924
|
+
if (1 === qos) {
|
|
925
|
+
await ctx.mqtt._send('puback', {pkt_id});} } } }
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
function * _routes_iter(all_route_lists, topic) {
|
|
929
|
+
for (let route_list of all_route_lists) {
|
|
930
|
+
for (let route of route_list) {
|
|
931
|
+
let res = _route_match_one(topic, route);
|
|
932
|
+
if (undefined !== res) {
|
|
933
|
+
yield res;} } } }
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
function _route_match_one(topic, {keys, pattern, tgt}) {
|
|
937
|
+
let match = '/' !== topic[0]
|
|
938
|
+
? pattern.exec('/'+topic)
|
|
939
|
+
: pattern.exec(topic);
|
|
940
|
+
|
|
941
|
+
if (null === match) {
|
|
942
|
+
return}
|
|
943
|
+
|
|
944
|
+
if (false === keys) {
|
|
945
|
+
let {groups} = match;
|
|
946
|
+
if (! groups) {
|
|
947
|
+
return [tgt]}
|
|
948
|
+
|
|
949
|
+
let params = {};
|
|
950
|
+
for (let k in groups) {
|
|
951
|
+
params[k] = groups[k];}
|
|
952
|
+
|
|
953
|
+
return [tgt, params]}
|
|
954
|
+
|
|
955
|
+
if (0 === keys.length) {
|
|
956
|
+
return [tgt]}
|
|
957
|
+
|
|
958
|
+
let params = {};
|
|
959
|
+
for (let i=0; i<keys.length; i++) {
|
|
960
|
+
params[ keys[i] ] = match[1+i];}
|
|
961
|
+
return [tgt, params]}
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
function _route_remove(all_route_lists, query) {
|
|
965
|
+
let match = route => route===query || route.tgt===query || route.key===query;
|
|
966
|
+
for (let lst of all_route_lists) {
|
|
967
|
+
let i = lst.findIndex(match);
|
|
968
|
+
if (0 <= i) {return !! lst.splice(i,1)} }
|
|
969
|
+
return false}
|
|
970
|
+
|
|
779
971
|
/*
|
|
780
972
|
export function decode_varint_loop(u8, i=0) {
|
|
781
973
|
let i0 = i
|
|
@@ -957,138 +1149,13 @@ function _ping_interval(send_ping) {
|
|
|
957
1149
|
if (td) {
|
|
958
1150
|
tid = setInterval(send_ping, 1000 * td);
|
|
959
1151
|
|
|
960
|
-
|
|
961
|
-
|
|
1152
|
+
|
|
1153
|
+
|
|
962
1154
|
|
|
963
|
-
|
|
964
|
-
|
|
1155
|
+
// ensure the interval allows the NodeJS event loop to exit
|
|
1156
|
+
tid.unref?.();
|
|
965
1157
|
return true} }) }
|
|
966
1158
|
|
|
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
1159
|
const _mqtt_cmdid_dispatch ={
|
|
1093
1160
|
create(target) {
|
|
1094
1161
|
return {__proto__: this, target, hashbelt: [new Map()]} }
|
|
@@ -1157,8 +1224,7 @@ const _mqtt_cmdid_dispatch ={
|
|
|
1157
1224
|
let fn = target[`mqtt_${pkt.type}`]
|
|
1158
1225
|
|| target.mqtt_pkt;
|
|
1159
1226
|
|
|
1160
|
-
|
|
1161
|
-
await fn.call(target, pkt, ctx);} } })()) };
|
|
1227
|
+
await fn?.call(target, pkt, ctx);} })()) };
|
|
1162
1228
|
|
|
1163
1229
|
function _mqtt_dispatch(opt, target) {
|
|
1164
1230
|
let _disp_ = _mqtt_cmdid_dispatch.create(target);
|
|
@@ -1239,53 +1305,15 @@ class MQTTBase {
|
|
|
1239
1305
|
|
|
1240
1306
|
|
|
1241
1307
|
// alias: sub
|
|
1242
|
-
subscribe(pkt, ex) {
|
|
1243
|
-
pkt = _as_topics(pkt, ex);
|
|
1308
|
+
subscribe(pkt, ex, topic_prefix) {
|
|
1309
|
+
pkt = _as_topics(pkt, ex, topic_prefix);
|
|
1244
1310
|
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
1311
|
|
|
1251
1312
|
// alias: unsub
|
|
1252
|
-
unsubscribe(pkt, ex) {
|
|
1253
|
-
pkt = _as_topics(pkt, ex);
|
|
1313
|
+
unsubscribe(pkt, ex, topic_prefix) {
|
|
1314
|
+
pkt = _as_topics(pkt, ex, topic_prefix);
|
|
1254
1315
|
return this._send('unsubscribe', pkt, pkt)}
|
|
1255
1316
|
|
|
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
1317
|
|
|
1290
1318
|
// alias: pub
|
|
1291
1319
|
publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
|
|
@@ -1311,9 +1339,9 @@ class MQTTBase {
|
|
|
1311
1339
|
if (undefined === cid) {
|
|
1312
1340
|
this.client_id = cid = (
|
|
1313
1341
|
|
|
1314
|
-
|
|
1342
|
+
|
|
1315
1343
|
|
|
1316
|
-
|
|
1344
|
+
this.new_client_id(parts)
|
|
1317
1345
|
);}
|
|
1318
1346
|
|
|
1319
1347
|
return cid}
|
|
@@ -1322,66 +1350,80 @@ class MQTTBase {
|
|
|
1322
1350
|
return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
|
|
1323
1351
|
|
|
1324
1352
|
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1353
|
+
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
|
|
1332
1360
|
|
|
1333
1361
|
|
|
1334
1362
|
// Internal API
|
|
1335
1363
|
|
|
1336
1364
|
/* async _send(type, pkt) -- provided by _conn_ and transport */
|
|
1337
1365
|
|
|
1338
|
-
_init_router(opt) {
|
|
1339
|
-
return this.router = _mqtt_topic_router()}
|
|
1340
|
-
|
|
1341
1366
|
_init_dispatch(opt) {
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1367
|
+
this.constructor?._once_();
|
|
1368
|
+
let target ={__proto__: opt.on_mqtt_type};
|
|
1369
|
+
target.mqtt_publish ||=
|
|
1370
|
+
this._init_router?.(opt, this, target);
|
|
1371
|
+
return _mqtt_dispatch(this, target)}
|
|
1345
1372
|
|
|
1346
|
-
|
|
1347
|
-
return
|
|
1373
|
+
static _aliases() {
|
|
1374
|
+
return ' pub:publish sub:subscribe unsub:unsubscribe '}
|
|
1348
1375
|
|
|
1376
|
+
static _once_(self=this) {
|
|
1377
|
+
self._once_ = _=>0;
|
|
1378
|
+
self.MQTTError = MQTTError;
|
|
1379
|
+
let p = self.prototype;
|
|
1380
|
+
for (let alias of self._aliases().split(/\s+/)) {
|
|
1381
|
+
alias = alias.split(':');
|
|
1382
|
+
let fn = alias[1] && p[alias[1]];
|
|
1383
|
+
if (fn) {p[alias[0]] = fn;} } } }
|
|
1349
1384
|
|
|
1350
|
-
{
|
|
1351
|
-
let p = MQTTBase.prototype;
|
|
1352
|
-
Object.assign(p,{
|
|
1353
|
-
MQTTError
|
|
1354
|
-
, pub: p.publish
|
|
1355
|
-
, sub: p.subscribe
|
|
1356
|
-
, unsub: p.unsubscribe
|
|
1357
|
-
, sub_topic: p.subscribe_topic
|
|
1358
|
-
, unsub_topic: p.unsubscribe_topic
|
|
1359
|
-
, shared_sub: p.shared_subscribe
|
|
1360
|
-
, shared_unsub: p.shared_unsubscribe} );
|
|
1361
1385
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1386
|
+
/*
|
|
1387
|
+
on_mqtt_type = {
|
|
1388
|
+
mqtt_auth(pkt, ctx) ::
|
|
1389
|
+
mqtt_connect(pkt, ctx) ::
|
|
1390
|
+
mqtt_connack(pkt, ctx) ::
|
|
1391
|
+
mqtt_disconnect(pkt, ctx) ::
|
|
1392
|
+
|
|
1393
|
+
mqtt_publish(pkt, ctx)
|
|
1394
|
+
mqtt_subscribe(pkt, ctx) ::
|
|
1395
|
+
mqtt_unsubscribe(pkt, ctx) ::
|
|
1396
|
+
|
|
1397
|
+
mqtt_pingreq(pkt, ctx) ::
|
|
1398
|
+
mqtt_pingresp(pkt, ctx) ::
|
|
1399
|
+
}
|
|
1400
|
+
*/
|
|
1401
|
+
|
|
1402
|
+
|
|
1403
|
+
const _prefix_topics = (topic_prefix, iterable) =>
|
|
1404
|
+
Array.from(iterable, value =>(
|
|
1405
|
+
value.trim // string
|
|
1406
|
+
? _prefix_topics(topic_prefix, value)
|
|
1407
|
+
: topic_prefix + value) );
|
|
1408
|
+
|
|
1409
|
+
function _as_topics(pkt, ex, topic_prefix) {
|
|
1410
|
+
if (ex?.trim) {// string
|
|
1411
|
+
topic_prefix = ex;
|
|
1412
|
+
ex = null;}
|
|
1377
1413
|
|
|
1414
|
+
pkt =(
|
|
1415
|
+
pkt.trim // string
|
|
1416
|
+
? {topics:[pkt], ... ex}
|
|
1417
|
+
: pkt[Symbol.iterator]
|
|
1418
|
+
? {topics:[... pkt], ... ex}
|
|
1419
|
+
: ex ? {...pkt, ...ex}
|
|
1420
|
+
: pkt);
|
|
1378
1421
|
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
return ex ? {...pkt, ...ex} : pkt}
|
|
1422
|
+
if (topic_prefix) {
|
|
1423
|
+
// particularly useful with shared queues, e.g.
|
|
1424
|
+
// topic_prefix = '$share/some-queue-name/'
|
|
1425
|
+
pkt.topics = _prefix_topics(topic_prefix, pkt.topics);}
|
|
1426
|
+
return pkt}
|
|
1385
1427
|
|
|
1386
1428
|
|
|
1387
1429
|
async function _pub(self, pkt, pub_opt) {
|
|
@@ -1497,53 +1539,53 @@ class MQTTCore extends MQTTBase {
|
|
|
1497
1539
|
|
|
1498
1540
|
|
|
1499
1541
|
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1500
1548
|
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
|
|
1501
1554
|
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
|
|
1502
1560
|
|
|
1561
|
+
|
|
1562
|
+
|
|
1563
|
+
|
|
1564
|
+
|
|
1503
1565
|
|
|
1566
|
+
|
|
1567
|
+
|
|
1504
1568
|
|
|
1569
|
+
|
|
1570
|
+
with_tcp(...opt) {
|
|
1571
|
+
opt = this._conn_opt(opt);
|
|
1572
|
+
console.log({opt});
|
|
1573
|
+
return this._use_conn (() =>
|
|
1574
|
+
this.with_stream(
|
|
1575
|
+
node_net.connect(opt)) ) }
|
|
1505
1576
|
|
|
1577
|
+
with_tls(...opt) {
|
|
1578
|
+
opt = this._conn_opt(opt);
|
|
1579
|
+
return this._use_conn (() =>
|
|
1580
|
+
this.with_stream(
|
|
1581
|
+
node_tls.connect(opt)) ) }
|
|
1506
1582
|
|
|
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}}
|
|
1583
|
+
_conn_opt([a0, a1, a2]) {
|
|
1584
|
+
// (port, hostname, options) or (url, options)
|
|
1585
|
+
if (Number.isFinite(a0)) {
|
|
1586
|
+
return {...a2, port: a0, host: a1}}
|
|
1587
|
+
a0 = new URL(a0);
|
|
1588
|
+
return {...a1, port: a0.port, host: a0.hostname}}
|
|
1547
1589
|
|
|
1548
1590
|
|
|
1549
1591
|
with_stream(read_stream, write_stream) {
|
|
@@ -1589,13 +1631,15 @@ class MQTTCore extends MQTTBase {
|
|
|
1589
1631
|
|
|
1590
1632
|
return this} }
|
|
1591
1633
|
|
|
1592
|
-
const version = '0.
|
|
1634
|
+
const version = '0.4.1';
|
|
1593
1635
|
|
|
1594
1636
|
const MQTTClient_v4 = /* #__PURE__ */
|
|
1595
|
-
|
|
1637
|
+
with_topic_path_router(
|
|
1638
|
+
MQTTCore.mqtt_ctx(4, mqtt_opts_v5) );
|
|
1596
1639
|
|
|
1597
1640
|
const MQTTClient_v5 = /* #__PURE__ */
|
|
1598
|
-
|
|
1641
|
+
with_topic_path_router(
|
|
1642
|
+
MQTTCore.mqtt_ctx(5, mqtt_opts_v5) );
|
|
1599
1643
|
|
|
1600
1644
|
const mqtt_v4 = opt =>
|
|
1601
1645
|
new MQTTClient_v4(opt);
|
|
@@ -1611,13 +1655,12 @@ exports.MQTTError = MQTTError;
|
|
|
1611
1655
|
exports._mqtt_cmdid_dispatch = _mqtt_cmdid_dispatch;
|
|
1612
1656
|
exports._mqtt_conn = _mqtt_conn;
|
|
1613
1657
|
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
1658
|
exports.ao_defer_v = ao_defer_v;
|
|
1659
|
+
exports.as_topic_path = as_topic_path;
|
|
1619
1660
|
exports.default = mqtt_v4;
|
|
1620
1661
|
exports.mqtt_v4 = mqtt_v4;
|
|
1621
1662
|
exports.mqtt_v5 = mqtt_v5;
|
|
1622
1663
|
exports.version = version;
|
|
1664
|
+
exports.with_topic_path_router = with_topic_path_router;
|
|
1665
|
+
exports.with_topic_router = with_topic_router;
|
|
1623
1666
|
//# sourceMappingURL=index.cjs.map
|