u8-mqtt 0.3.1 → 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 +312 -247
- package/cjs/index.cjs.map +1 -1
- package/cjs/v4.cjs +307 -242
- package/cjs/v4.cjs.map +1 -1
- package/cjs/v5.cjs +309 -243
- package/cjs/v5.cjs.map +1 -1
- package/code/_cmdid_dispatch.jsy +1 -3
- package/code/base.jsy +64 -84
- package/code/{v4.mjs → basic-v4.js} +1 -1
- package/code/{v5.mjs → basic-v5.js} +1 -1
- package/code/core.jsy +41 -15
- package/code/{index.mjs → index.js} +3 -2
- package/code/{_router.jsy → router_path.jsy} +30 -12
- package/code/v4.js +20 -0
- package/code/v5.js +29 -0
- package/code/version.js +1 -0
- 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 +307 -242
- package/esm/deno/index.js.map +1 -1
- package/esm/deno/v4.js +304 -240
- package/esm/deno/v4.js.map +1 -1
- package/esm/deno/v5.js +306 -241
- 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 +309 -243
- package/esm/node/index.js.map +1 -1
- package/esm/node/index.mjs +309 -243
- package/esm/node/index.mjs.map +1 -1
- package/esm/node/v4.js +306 -241
- package/esm/node/v4.js.map +1 -1
- package/esm/node/v4.mjs +306 -241
- package/esm/node/v4.mjs.map +1 -1
- package/esm/node/v5.js +308 -242
- package/esm/node/v5.js.map +1 -1
- package/esm/node/v5.mjs +308 -242
- 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 +307 -242
- 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 +305 -241
- 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 +306 -241
- 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 +7 -7
package/cjs/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var node_net = require('node:net');
|
|
6
|
+
var node_tls = require('node:tls');
|
|
6
7
|
|
|
7
8
|
function encode_varint(n, a=[]) {
|
|
8
9
|
do {
|
|
@@ -775,6 +776,191 @@ const mqtt_opts_v5 =
|
|
|
775
776
|
encode_fns: mqtt_encode_v5,
|
|
776
777
|
mqtt_writer: mqtt_writer_v5, };
|
|
777
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
|
+
|
|
778
964
|
/*
|
|
779
965
|
export function decode_varint_loop(u8, i=0) {
|
|
780
966
|
let i0 = i
|
|
@@ -873,8 +1059,6 @@ function mqtt_pkt_ctx(mqtt_level, opts, pkt_ctx) {
|
|
|
873
1059
|
}
|
|
874
1060
|
}
|
|
875
1061
|
|
|
876
|
-
Object.freeze({ao_done: true});
|
|
877
|
-
|
|
878
1062
|
function ao_defer_ctx(as_res = (...args) => args) {
|
|
879
1063
|
let y,n,_pset = (a,b) => { y=a, n=b; };
|
|
880
1064
|
return p =>(
|
|
@@ -958,138 +1142,13 @@ function _ping_interval(send_ping) {
|
|
|
958
1142
|
if (td) {
|
|
959
1143
|
tid = setInterval(send_ping, 1000 * td);
|
|
960
1144
|
|
|
961
|
-
|
|
962
|
-
|
|
1145
|
+
|
|
1146
|
+
|
|
963
1147
|
|
|
964
|
-
|
|
965
|
-
|
|
1148
|
+
// ensure the interval allows the NodeJS event loop to exit
|
|
1149
|
+
tid.unref?.();
|
|
966
1150
|
return true} }) }
|
|
967
1151
|
|
|
968
|
-
function parse(str, loose) {
|
|
969
|
-
if (str instanceof RegExp) return { keys:false, pattern:str };
|
|
970
|
-
var c, o, tmp, ext, keys=[], pattern='', arr = str.split('/');
|
|
971
|
-
arr[0] || arr.shift();
|
|
972
|
-
|
|
973
|
-
while (tmp = arr.shift()) {
|
|
974
|
-
c = tmp[0];
|
|
975
|
-
if (c === '*') {
|
|
976
|
-
keys.push('wild');
|
|
977
|
-
pattern += '/(.*)';
|
|
978
|
-
} else if (c === ':') {
|
|
979
|
-
o = tmp.indexOf('?', 1);
|
|
980
|
-
ext = tmp.indexOf('.', 1);
|
|
981
|
-
keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) );
|
|
982
|
-
pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)';
|
|
983
|
-
if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext);
|
|
984
|
-
} else {
|
|
985
|
-
pattern += '/' + tmp;
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
return {
|
|
990
|
-
keys: keys,
|
|
991
|
-
pattern: new RegExp('^' + pattern + (loose ? '(?=$|\/)' : '\/?$'), 'i')
|
|
992
|
-
};
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
// Use [regexparam][] for url-like topic parsing
|
|
996
|
-
|
|
997
|
-
function _ignore(pkt, params, ctx) {ctx.done = true;}
|
|
998
|
-
|
|
999
|
-
function _mqtt_topic_router() {
|
|
1000
|
-
let pri_lsts = [[],[]], rm = Symbol();
|
|
1001
|
-
let find = topic => _mqtt_routes_iter(pri_lsts, topic);
|
|
1002
|
-
|
|
1003
|
-
return {find,
|
|
1004
|
-
|
|
1005
|
-
add(topic_route, ...args) {
|
|
1006
|
-
let fn = args.pop();
|
|
1007
|
-
let priority = args.pop();
|
|
1008
|
-
|
|
1009
|
-
if ('function' !== typeof fn) {
|
|
1010
|
-
if (false === fn) {
|
|
1011
|
-
fn = _ignore;}
|
|
1012
|
-
else throw new TypeError()}
|
|
1013
|
-
|
|
1014
|
-
let rte = parse(
|
|
1015
|
-
topic_route.replace(/[+#]$/, '*'));
|
|
1016
|
-
|
|
1017
|
-
rte.key = topic_route;
|
|
1018
|
-
rte.tgt = fn;
|
|
1019
|
-
pri_lsts[priority ? 0 : 1].push(rte);
|
|
1020
|
-
return this}
|
|
1021
|
-
|
|
1022
|
-
, remove(topic_route, priority) {
|
|
1023
|
-
let lst = pri_lsts[priority ? 0 : 1];
|
|
1024
|
-
return _mqtt_route_remove([lst], topic_route)}
|
|
1025
|
-
|
|
1026
|
-
, clear(priority) {
|
|
1027
|
-
pri_lsts[priority ? 0 : 1] = [];
|
|
1028
|
-
if (null == priority) {
|
|
1029
|
-
pri_lsts[1] = [];} }
|
|
1030
|
-
|
|
1031
|
-
, async invoke(pkt, ctx) {
|
|
1032
|
-
ctx.idx = 0;
|
|
1033
|
-
ctx.rm = rm;
|
|
1034
|
-
|
|
1035
|
-
for (let [fn, params] of find(pkt.topic)) {
|
|
1036
|
-
let res = await fn(pkt, params, ctx);
|
|
1037
|
-
|
|
1038
|
-
if (rm === res) {
|
|
1039
|
-
_mqtt_route_remove(pri_lsts, fn);}
|
|
1040
|
-
|
|
1041
|
-
if (ctx.done) {
|
|
1042
|
-
break}
|
|
1043
|
-
else ctx.idx++;}
|
|
1044
|
-
|
|
1045
|
-
let {pkt_id, qos} = pkt;
|
|
1046
|
-
if (1 === qos) {
|
|
1047
|
-
await ctx.mqtt._send('puback', {pkt_id});} } } }
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
function * _mqtt_routes_iter(all_route_lists, topic) {
|
|
1051
|
-
for (let route_list of all_route_lists) {
|
|
1052
|
-
for (let route of route_list) {
|
|
1053
|
-
let res = _mqtt_route_match_one(topic, route);
|
|
1054
|
-
if (undefined !== res) {
|
|
1055
|
-
yield res;} } } }
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
function _mqtt_route_match_one(topic, {keys, pattern, tgt}) {
|
|
1059
|
-
let match = '/' !== topic[0]
|
|
1060
|
-
? pattern.exec('/'+topic)
|
|
1061
|
-
: pattern.exec(topic);
|
|
1062
|
-
|
|
1063
|
-
if (null === match) {
|
|
1064
|
-
return}
|
|
1065
|
-
|
|
1066
|
-
if (false === keys) {
|
|
1067
|
-
let {groups} = match;
|
|
1068
|
-
if (! groups) {
|
|
1069
|
-
return [tgt]}
|
|
1070
|
-
|
|
1071
|
-
let params = {};
|
|
1072
|
-
for (let k in groups) {
|
|
1073
|
-
params[k] = groups[k];}
|
|
1074
|
-
|
|
1075
|
-
return [tgt, params]}
|
|
1076
|
-
|
|
1077
|
-
if (0 === keys.length) {
|
|
1078
|
-
return [tgt]}
|
|
1079
|
-
|
|
1080
|
-
let params = {};
|
|
1081
|
-
for (let i=0; i<keys.length; i++) {
|
|
1082
|
-
params[ keys[i] ] = match[1+i];}
|
|
1083
|
-
return [tgt, params]}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
function _mqtt_route_remove(all_route_lists, query) {
|
|
1087
|
-
let match = route => route===query || route.tgt===query || route.key===query;
|
|
1088
|
-
for (let lst of all_route_lists) {
|
|
1089
|
-
let i = lst.findIndex(match);
|
|
1090
|
-
if (0 <= i) {return !! lst.splice(i,1)} }
|
|
1091
|
-
return false}
|
|
1092
|
-
|
|
1093
1152
|
const _mqtt_cmdid_dispatch ={
|
|
1094
1153
|
create(target) {
|
|
1095
1154
|
return {__proto__: this, target, hashbelt: [new Map()]} }
|
|
@@ -1158,8 +1217,7 @@ const _mqtt_cmdid_dispatch ={
|
|
|
1158
1217
|
let fn = target[`mqtt_${pkt.type}`]
|
|
1159
1218
|
|| target.mqtt_pkt;
|
|
1160
1219
|
|
|
1161
|
-
|
|
1162
|
-
await fn.call(target, pkt, ctx);} } })()) };
|
|
1220
|
+
await fn?.call(target, pkt, ctx);} })()) };
|
|
1163
1221
|
|
|
1164
1222
|
function _mqtt_dispatch(opt, target) {
|
|
1165
1223
|
let _disp_ = _mqtt_cmdid_dispatch.create(target);
|
|
@@ -1240,53 +1298,15 @@ class MQTTBase {
|
|
|
1240
1298
|
|
|
1241
1299
|
|
|
1242
1300
|
// alias: sub
|
|
1243
|
-
subscribe(pkt, ex) {
|
|
1244
|
-
pkt = _as_topics(pkt, ex);
|
|
1301
|
+
subscribe(pkt, ex, topic_prefix) {
|
|
1302
|
+
pkt = _as_topics(pkt, ex, topic_prefix);
|
|
1245
1303
|
return this._send('subscribe', pkt, pkt)}
|
|
1246
|
-
_sub_chain(topic, ex) {
|
|
1247
|
-
let res = this.subscribe([[ topic ]], ex);
|
|
1248
|
-
let subs = this.subs ||(this.subs = new Map());
|
|
1249
|
-
subs.set((res.topic = topic), (subs.last = res));
|
|
1250
|
-
return this }// fluent api -- return this and track side effects
|
|
1251
1304
|
|
|
1252
1305
|
// alias: unsub
|
|
1253
|
-
unsubscribe(pkt, ex) {
|
|
1254
|
-
pkt = _as_topics(pkt, ex);
|
|
1306
|
+
unsubscribe(pkt, ex, topic_prefix) {
|
|
1307
|
+
pkt = _as_topics(pkt, ex, topic_prefix);
|
|
1255
1308
|
return this._send('unsubscribe', pkt, pkt)}
|
|
1256
1309
|
|
|
1257
|
-
get on_topic() {return this.router.add}
|
|
1258
|
-
|
|
1259
|
-
// alias: sub_topic
|
|
1260
|
-
subscribe_topic(topic_route, ...args) {
|
|
1261
|
-
this.router.add(topic_route, true, args.pop() );// handler
|
|
1262
|
-
let topic = this.topic_for(topic_route);
|
|
1263
|
-
return this._sub_chain(topic, args.pop() ) }// ex
|
|
1264
|
-
|
|
1265
|
-
// alias: unsub_topic
|
|
1266
|
-
unsubscribe_topic(topic_route) {
|
|
1267
|
-
this.router.remove(topic_route, true);
|
|
1268
|
-
let topic = this.topic_for(topic_route);
|
|
1269
|
-
return this.unsubscribe([[ topic ]]) }
|
|
1270
|
-
|
|
1271
|
-
// alias: shared_sub
|
|
1272
|
-
shared_subscribe(group, topic_route, ...args) {
|
|
1273
|
-
this.router.add(topic_route, true, args.pop() );// handler
|
|
1274
|
-
let topic = this.topic_for(topic_route);
|
|
1275
|
-
if (null != group) {
|
|
1276
|
-
topic = `$share/${group}/${topic}`;}
|
|
1277
|
-
return this._sub_chain(topic, args.pop() ) }// ex
|
|
1278
|
-
|
|
1279
|
-
// alias: shared_unsub
|
|
1280
|
-
shared_unsubscribe(group, topic_route) {
|
|
1281
|
-
this.router.remove(topic_route, true);
|
|
1282
|
-
let topic = this.topic_for(topic_route);
|
|
1283
|
-
if (null != group) {
|
|
1284
|
-
topic = `$share/${group}/${topic}`;}
|
|
1285
|
-
return this.unsubscribe([[ topic ]]) }
|
|
1286
|
-
|
|
1287
|
-
topic_for(topic_route) {
|
|
1288
|
-
return topic_route.replace(/[:*].*$/, '#')}
|
|
1289
|
-
|
|
1290
1310
|
|
|
1291
1311
|
// alias: pub
|
|
1292
1312
|
publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
|
|
@@ -1312,9 +1332,9 @@ class MQTTBase {
|
|
|
1312
1332
|
if (undefined === cid) {
|
|
1313
1333
|
this.client_id = cid = (
|
|
1314
1334
|
|
|
1315
|
-
|
|
1335
|
+
|
|
1316
1336
|
|
|
1317
|
-
|
|
1337
|
+
this.new_client_id(parts)
|
|
1318
1338
|
);}
|
|
1319
1339
|
|
|
1320
1340
|
return cid}
|
|
@@ -1323,66 +1343,85 @@ class MQTTBase {
|
|
|
1323
1343
|
return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
|
|
1324
1344
|
|
|
1325
1345
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1346
|
+
|
|
1347
|
+
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
|
|
1333
1353
|
|
|
1334
1354
|
|
|
1335
1355
|
// Internal API
|
|
1336
1356
|
|
|
1337
1357
|
/* async _send(type, pkt) -- provided by _conn_ and transport */
|
|
1338
1358
|
|
|
1339
|
-
_init_router(opt) {
|
|
1340
|
-
return this.router = _mqtt_topic_router()}
|
|
1341
|
-
|
|
1342
1359
|
_init_dispatch(opt) {
|
|
1360
|
+
this.constructor?._once_();
|
|
1361
|
+
let router = this.router =
|
|
1362
|
+
this._init_router?.(opt, this);
|
|
1363
|
+
|
|
1343
1364
|
let tgt ={
|
|
1344
1365
|
__proto__: opt.on_mqtt_type || {}
|
|
1345
|
-
, router
|
|
1366
|
+
, router};
|
|
1346
1367
|
|
|
1347
|
-
tgt.mqtt_publish ||=
|
|
1348
|
-
return _mqtt_dispatch(this, tgt)}
|
|
1368
|
+
tgt.mqtt_publish ||= router?.invoke;
|
|
1369
|
+
return _mqtt_dispatch(this, tgt)}
|
|
1349
1370
|
|
|
1371
|
+
static _aliases() {
|
|
1372
|
+
return ' pub:publish sub:subscribe unsub:unsubscribe '}
|
|
1350
1373
|
|
|
1351
|
-
{
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
, unsub_topic: p.unsubscribe_topic
|
|
1360
|
-
, shared_sub: p.shared_subscribe
|
|
1361
|
-
, 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;} } } }
|
|
1362
1382
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
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
|
+
*/
|
|
1378
1399
|
|
|
1379
1400
|
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
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}
|
|
1386
1425
|
|
|
1387
1426
|
|
|
1388
1427
|
async function _pub(self, pkt, pub_opt) {
|
|
@@ -1454,7 +1493,7 @@ class MQTTCore extends MQTTBase {
|
|
|
1454
1493
|
return this}
|
|
1455
1494
|
|
|
1456
1495
|
//log_conn(evt, arg, err_arg) ::
|
|
1457
|
-
//console.info @ '[[u8-mqtt log: %s]]', evt, arg, err_arg
|
|
1496
|
+
// console.info @ '[[u8-mqtt log: %s]]', evt, arg, err_arg
|
|
1458
1497
|
|
|
1459
1498
|
on_live(client, is_reconnect) {
|
|
1460
1499
|
if (is_reconnect) {
|
|
@@ -1496,30 +1535,55 @@ class MQTTCore extends MQTTBase {
|
|
|
1496
1535
|
return this}
|
|
1497
1536
|
|
|
1498
1537
|
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
1538
|
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1510
1546
|
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1511
1552
|
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
|
|
1512
1558
|
|
|
1559
|
+
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
|
|
1513
1563
|
|
|
1564
|
+
|
|
1565
|
+
|
|
1514
1566
|
|
|
1515
1567
|
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
({
|
|
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)) ) }
|
|
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)) ) }
|
|
1519
1580
|
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
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}}
|
|
1523
1587
|
|
|
1524
1588
|
|
|
1525
1589
|
with_stream(read_stream, write_stream) {
|
|
@@ -1565,13 +1629,15 @@ class MQTTCore extends MQTTBase {
|
|
|
1565
1629
|
|
|
1566
1630
|
return this} }
|
|
1567
1631
|
|
|
1568
|
-
|
|
1632
|
+
const version = '0.4.0';
|
|
1569
1633
|
|
|
1570
1634
|
const MQTTClient_v4 = /* #__PURE__ */
|
|
1571
|
-
|
|
1635
|
+
with_topic_path_router(
|
|
1636
|
+
MQTTCore.mqtt_ctx(4, mqtt_opts_v5) );
|
|
1572
1637
|
|
|
1573
1638
|
const MQTTClient_v5 = /* #__PURE__ */
|
|
1574
|
-
|
|
1639
|
+
with_topic_path_router(
|
|
1640
|
+
MQTTCore.mqtt_ctx(5, mqtt_opts_v5) );
|
|
1575
1641
|
|
|
1576
1642
|
const mqtt_v4 = opt =>
|
|
1577
1643
|
new MQTTClient_v4(opt);
|
|
@@ -1587,13 +1653,12 @@ exports.MQTTError = MQTTError;
|
|
|
1587
1653
|
exports._mqtt_cmdid_dispatch = _mqtt_cmdid_dispatch;
|
|
1588
1654
|
exports._mqtt_conn = _mqtt_conn;
|
|
1589
1655
|
exports._mqtt_dispatch = _mqtt_dispatch;
|
|
1590
|
-
exports._mqtt_route_match_one = _mqtt_route_match_one;
|
|
1591
|
-
exports._mqtt_route_remove = _mqtt_route_remove;
|
|
1592
|
-
exports._mqtt_routes_iter = _mqtt_routes_iter;
|
|
1593
|
-
exports._mqtt_topic_router = _mqtt_topic_router;
|
|
1594
1656
|
exports.ao_defer_v = ao_defer_v;
|
|
1595
|
-
exports
|
|
1657
|
+
exports.as_topic_path = as_topic_path;
|
|
1658
|
+
exports.default = mqtt_v4;
|
|
1596
1659
|
exports.mqtt_v4 = mqtt_v4;
|
|
1597
1660
|
exports.mqtt_v5 = mqtt_v5;
|
|
1598
1661
|
exports.version = version;
|
|
1662
|
+
exports.with_topic_path_router = with_topic_path_router;
|
|
1663
|
+
exports.with_topic_router = with_topic_router;
|
|
1599
1664
|
//# sourceMappingURL=index.cjs.map
|