u8-mqtt 0.4.0 → 0.5.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.
Files changed (82) hide show
  1. package/README.md +3 -3
  2. package/cjs/basic-v4.cjs +107 -146
  3. package/cjs/basic-v4.cjs.map +1 -1
  4. package/cjs/basic-v5.cjs +106 -145
  5. package/cjs/basic-v5.cjs.map +1 -1
  6. package/cjs/index.cjs +163 -206
  7. package/cjs/index.cjs.map +1 -1
  8. package/cjs/v4.cjs +164 -207
  9. package/cjs/v4.cjs.map +1 -1
  10. package/cjs/v5.cjs +163 -206
  11. package/cjs/v5.cjs.map +1 -1
  12. package/code/_dispatch.jsy +16 -0
  13. package/code/base.jsy +72 -133
  14. package/code/core.jsy +15 -9
  15. package/code/router_path.jsy +38 -51
  16. package/code/with_topic_router.jsy +20 -11
  17. package/esm/basic-v4.js +1154 -0
  18. package/esm/basic-v4.js.map +1 -0
  19. package/esm/basic-v5.js +1416 -0
  20. package/esm/basic-v5.js.map +1 -0
  21. package/esm/deno/basic-v4.js +107 -146
  22. package/esm/deno/basic-v4.js.map +1 -1
  23. package/esm/deno/basic-v5.js +106 -145
  24. package/esm/deno/basic-v5.js.map +1 -1
  25. package/esm/deno/index.js +163 -206
  26. package/esm/deno/index.js.map +1 -1
  27. package/esm/deno/v4.js +164 -207
  28. package/esm/deno/v4.js.map +1 -1
  29. package/esm/deno/v5.js +163 -206
  30. package/esm/deno/v5.js.map +1 -1
  31. package/esm/index.js +1599 -0
  32. package/esm/index.js.map +1 -0
  33. package/esm/node/basic-v4.js +107 -146
  34. package/esm/node/basic-v4.js.map +1 -1
  35. package/esm/node/basic-v4.mjs +107 -146
  36. package/esm/node/basic-v4.mjs.map +1 -1
  37. package/esm/node/basic-v5.js +106 -145
  38. package/esm/node/basic-v5.js.map +1 -1
  39. package/esm/node/basic-v5.mjs +106 -145
  40. package/esm/node/basic-v5.mjs.map +1 -1
  41. package/esm/node/index.js +163 -206
  42. package/esm/node/index.js.map +1 -1
  43. package/esm/node/index.mjs +163 -206
  44. package/esm/node/index.mjs.map +1 -1
  45. package/esm/node/v4.js +164 -207
  46. package/esm/node/v4.js.map +1 -1
  47. package/esm/node/v4.mjs +164 -207
  48. package/esm/node/v4.mjs.map +1 -1
  49. package/esm/node/v5.js +163 -206
  50. package/esm/node/v5.js.map +1 -1
  51. package/esm/node/v5.mjs +163 -206
  52. package/esm/node/v5.mjs.map +1 -1
  53. package/esm/v4.js +1336 -0
  54. package/esm/v4.js.map +1 -0
  55. package/esm/v5.js +1599 -0
  56. package/esm/v5.js.map +1 -0
  57. package/esm/web/basic-v4.js +107 -146
  58. package/esm/web/basic-v4.js.map +1 -1
  59. package/esm/web/basic-v4.min.js +1 -1
  60. package/esm/web/basic-v4.min.js.br +0 -0
  61. package/esm/web/basic-v4.min.js.gz +0 -0
  62. package/esm/web/basic-v5.js +106 -145
  63. package/esm/web/basic-v5.js.map +1 -1
  64. package/esm/web/basic-v5.min.js +1 -1
  65. package/esm/web/basic-v5.min.js.br +0 -0
  66. package/esm/web/basic-v5.min.js.gz +0 -0
  67. package/esm/web/index.js +163 -206
  68. package/esm/web/index.js.map +1 -1
  69. package/esm/web/index.min.js +1 -1
  70. package/esm/web/index.min.js.br +0 -0
  71. package/esm/web/index.min.js.gz +0 -0
  72. package/esm/web/v4.js +164 -207
  73. package/esm/web/v4.js.map +1 -1
  74. package/esm/web/v4.min.js +1 -1
  75. package/esm/web/v4.min.js.br +0 -0
  76. package/esm/web/v4.min.js.gz +0 -0
  77. package/esm/web/v5.js +163 -206
  78. package/esm/web/v5.js.map +1 -1
  79. package/esm/web/v5.min.js +1 -1
  80. package/esm/web/v5.min.js.br +0 -0
  81. package/esm/web/v5.min.js.gz +0 -0
  82. package/package.json +7 -8
package/esm/node/v5.js CHANGED
@@ -150,7 +150,7 @@ class mqtt_reader_v4 {
150
150
 
151
151
  }
152
152
 
153
- class mqtt_reader_v5$1 extends mqtt_reader_v4 {
153
+ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
154
154
  props() {
155
155
  let {buf, step} = this;
156
156
  let [n, vi, vi0] = decode_varint$1(buf, step.k|0);
@@ -185,7 +185,7 @@ class mqtt_reader_v5$1 extends mqtt_reader_v4 {
185
185
  : buf.subarray(vi, step.k|0)
186
186
  }
187
187
  */
188
- }
188
+ };
189
189
 
190
190
  function mqtt_reader_info(mqtt_reader, ... info_fn_list) {
191
191
  mqtt_reader = class extends mqtt_reader {
@@ -815,30 +815,39 @@ const with_topic_router = mqtt_topic_router =>
815
815
  return super._aliases() +
816
816
  ' sub_topic:subscribe_topic unsub_topic:unsubscribe_topic'}
817
817
 
818
- _init_router(opt) {
819
- return mqtt_topic_router(opt, this)}
820
-
821
- get on_topic() {return this.router.add}
818
+ _init_router(opt, self, target) {
819
+ this._subs = [];
820
+ let router = this.router = target.router =
821
+ mqtt_topic_router(opt, this, target);
822
+ return router?.invoke}
822
823
 
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
824
+ on_sub(suback, pkt) {
825
+ suback.pkt = pkt;
826
+ this._subs.push(suback);
827
+ return suback}
828
+ subs_settled() {
829
+ return Promise.allSettled(
830
+ this._subs.splice(0,Infinity)) }
828
831
 
829
832
  // alias: sub_topic
830
833
  subscribe_topic(topic_route, ...args) {
831
834
  let router = this.router;
832
835
  router.add(topic_route, true, args.pop() );// handler
833
836
  let topic = router.mqtt_topic(topic_route);
834
- return this._sub_chain(topic, ...args ) }// ex, topic_prefix
837
+ this.subscribe(topic, ...args );// ex, topic_prefix
838
+ return this }// fluent api -- return this and track side effects
835
839
 
836
840
  // alias: unsub_topic
837
841
  unsubscribe_topic(topic_route, ...args) {
838
842
  let router = this.router;
839
843
  router.remove(topic_route, true);
840
844
  let topic = router.mqtt_topic(topic_route);
841
- return this.unsubscribe([[ topic ]], ...args ) } };// topic_prefix
845
+ return this.unsubscribe(topic, ...args ) }// topic_prefix
846
+
847
+ // add topic handlers without corresponding subscribe packet
848
+ on_topic(...args) {
849
+ this.router.add(...args);
850
+ return this} };
842
851
 
843
852
  // Use [regexparam][] for url-like topic parsing
844
853
  // [regexparam]: https://github.com/lukeed/regexparam
@@ -851,16 +860,22 @@ const with_topic_path_router = /* #__PURE__ */
851
860
  const mqtt_topic = topic_route =>
852
861
  topic_route
853
862
  .replace(/[*].*$/, '#')
854
- .replace(/:\w+\??/g, '+');
863
+ .replace(/:\w[^\/]*/g, '+');
855
864
 
856
- const as_topic_path = topic_route =>(
865
+ /* From the [MQTT v5 Spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Topic_Names_and)
866
+ 4.7.1.2 Multi-level wildcard -- (‘#’ U+0023)
867
+ ... MUST be specified either on its own or following a topic level separator.
868
+ In either case it MUST be the last character specified in the Topic Filter
869
+
870
+ 4.7.1.3 Single-level wildcard -- (‘+’ U+002B)
871
+ ...it MUST occupy an entire level of the filter.
872
+ */
873
+
874
+ const as_topic_path = (topic_route, id) =>(
875
+ id=1,
857
876
  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
877
+ .replace(/#$/, '*' )// replace MQTT '#' multi-level wildcard at end
878
+ .replace(/\+/g, () => `:$${id++}` ) );// replace MQTT '+' single-level wildcards
864
879
 
865
880
  function _ignore(pkt, params, ctx) {ctx.done = true;}
866
881
 
@@ -875,9 +890,8 @@ function mqtt_topic_path_router() {
875
890
  let priority = args.pop();
876
891
 
877
892
  if ('function' !== typeof fn) {
878
- if (false === fn) {
879
- fn = _ignore;}
880
- else throw new TypeError()}
893
+ if (fn) {throw new TypeError()}
894
+ fn = _ignore;}
881
895
 
882
896
  let rte = parse(as_topic_path(topic_route));
883
897
 
@@ -893,7 +907,7 @@ function mqtt_topic_path_router() {
893
907
  , clear(priority) {
894
908
  pri_lsts[priority ? 0 : 1] = [];
895
909
  if (null == priority) {
896
- pri_lsts[1] = [];} }
910
+ pri_lsts[1] = []; } }// null clears both lists
897
911
 
898
912
  , async invoke(pkt, ctx) {
899
913
  ctx.idx = 0;
@@ -909,52 +923,34 @@ function mqtt_topic_path_router() {
909
923
  break}
910
924
  else ctx.idx++;}
911
925
 
912
- let {pkt_id, qos} = pkt;
913
- if (1 === qos) {
914
- await ctx.mqtt._send('puback', {pkt_id});} } } }
926
+ if (1 === pkt.qos) {
927
+ await ctx.mqtt.puback(pkt);} } } }
915
928
 
916
929
 
917
930
  function * _routes_iter(all_route_lists, topic) {
931
+ topic = topic.replace(/^[\/]*/, '/'); // ensure '/' prefix for regexparam library
918
932
  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]}
933
+ for (let {keys, pattern, tgt} of route_list) {
934
+ let match = pattern.exec(topic);
935
+ if (match) {
936
+ let params = keys
937
+ ? keys.reduce(
938
+ (o, k, i) => (o[k] = match[1+i], o)
939
+ , {})
940
+ : match.groups ?? match;
941
+ yield [tgt, params];} } } }
951
942
 
952
943
 
953
944
  function _route_remove(all_route_lists, query) {
954
- let match = route => route===query || route.tgt===query || route.key===query;
945
+ let fn_match = route =>(
946
+ route===query
947
+ || route.tgt===query
948
+ || route.key===query);
955
949
  for (let lst of all_route_lists) {
956
- let i = lst.findIndex(match);
957
- if (0 <= i) {return !! lst.splice(i,1)} }
950
+ let i = lst.findIndex(fn_match);
951
+ if (0 <= i) {
952
+ lst.splice(i,1);
953
+ return true} }
958
954
  return false}
959
955
 
960
956
  /*
@@ -1215,6 +1211,22 @@ const _mqtt_cmdid_dispatch ={
1215
1211
 
1216
1212
  await fn?.call(target, pkt, ctx);} })()) };
1217
1213
 
1214
+ /*
1215
+ on_mqtt_type = {
1216
+ mqtt_auth(pkt, ctx) ::
1217
+ mqtt_connect(pkt, ctx) ::
1218
+ mqtt_connack(pkt, ctx) ::
1219
+ mqtt_disconnect(pkt, ctx) ::
1220
+
1221
+ mqtt_publish(pkt, ctx)
1222
+ mqtt_subscribe(pkt, ctx) ::
1223
+ mqtt_unsubscribe(pkt, ctx) ::
1224
+
1225
+ mqtt_pingreq(pkt, ctx) ::
1226
+ mqtt_pingresp(pkt, ctx) ::
1227
+ }
1228
+ */
1229
+
1218
1230
  function _mqtt_dispatch(opt, target) {
1219
1231
  let _disp_ = _mqtt_cmdid_dispatch.create(target);
1220
1232
  let { cmdids } = _disp_;
@@ -1244,28 +1256,34 @@ class MQTTError extends Error {
1244
1256
 
1245
1257
  class MQTTBase {
1246
1258
  constructor(opt={}) {
1259
+ this.with(opt);
1247
1260
  this._conn_ = _mqtt_conn(this,
1248
1261
  this._init_dispatch(opt, this)); }
1249
1262
 
1263
+ with(fns_ns) {
1264
+ for (let [k,v] of Object.entries(fns_ns)) {
1265
+ if ('function' === typeof v) {this[k] = v;} }
1266
+ return this}
1267
+
1250
1268
  async conn_emit(evt, arg, err_arg) {
1251
1269
  this.log_conn?.(evt, arg, err_arg);
1252
1270
  try {
1253
- let fn_evt = this[await evt]; // microtask break
1271
+ let fn_evt = this[await evt]; // microtask break using `await evt`
1254
1272
  if (fn_evt) {
1255
1273
  await fn_evt.call(this, this, arg, err_arg);}
1256
- else if (err_arg) {
1257
- await this.on_error(err_arg, evt);} }
1274
+ else if (err_arg) {throw err_arg} }
1258
1275
  catch (err) {
1259
1276
  this.on_error(err, evt);} }
1260
1277
 
1261
- on_error(err, err_path) {
1262
- console.warn('[[u8-mqtt error: %s]]', err_path, err); }
1278
+ on_error(err, evt) {
1279
+ console.warn('[[u8-mqtt error: %s]]', evt, err); }
1263
1280
 
1264
1281
  // Handshaking Packets
1265
1282
 
1266
1283
  async connect(pkt={}) {
1267
- let cid = pkt.client_id || ['u8-mqtt--', ''];
1268
- if (Array.isArray(cid)) {
1284
+ let cid = pkt.client_id || this.client_id;
1285
+ if ('string' !== typeof cid) {
1286
+ // see init_client_id implementation in core.jsy
1269
1287
  pkt.client_id = cid = this.init_client_id(cid);}
1270
1288
  this.client_id = cid;
1271
1289
 
@@ -1291,12 +1309,13 @@ class MQTTBase {
1291
1309
  return this._send('auth', pkt, 'auth')}
1292
1310
 
1293
1311
  ping() {return this._send('pingreq', null, 'pingresp')}
1294
-
1312
+ puback({pkt_id}) {return this._send('puback', {pkt_id})}
1295
1313
 
1296
1314
  // alias: sub
1297
1315
  subscribe(pkt, ex, topic_prefix) {
1298
1316
  pkt = _as_topics(pkt, ex, topic_prefix);
1299
- return this._send('subscribe', pkt, pkt)}
1317
+ let suback = this._send('subscribe', pkt, pkt);
1318
+ return this.on_sub?.(suback, pkt) ?? suback}
1300
1319
 
1301
1320
  // alias: unsub
1302
1321
  unsubscribe(pkt, ex, topic_prefix) {
@@ -1304,48 +1323,52 @@ class MQTTBase {
1304
1323
  return this._send('unsubscribe', pkt, pkt)}
1305
1324
 
1306
1325
 
1307
- // alias: pub
1308
- publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
1309
- post(topic, payload, pub_opt) {return _pub.m(this, topic, payload, pub_opt)}
1310
- send(topic, payload, pub_opt) {return _pub.mq(this, topic, payload, pub_opt)}
1311
- store(topic, payload, pub_opt) {return _pub.mqr(this, topic, payload, pub_opt)}
1312
-
1313
- json_post(topic, msg, pub_opt) {return _pub.o(this, topic, msg, pub_opt)}
1314
- json_send(topic, msg, pub_opt) {return _pub.oq(this, topic, msg, pub_opt)}
1315
- json_store(topic, msg, pub_opt) {return _pub.oqr(this, topic, msg, pub_opt)}
1316
-
1317
- obj_post(topic, msg, pub_opt) {return _pub.o(this, topic, msg, pub_opt)}
1318
- obj_send(topic, msg, pub_opt) {return _pub.oq(this, topic, msg, pub_opt)}
1319
- obj_store(topic, msg, pub_opt) {return _pub.oqr(this, topic, msg, pub_opt)}
1320
-
1321
-
1322
-
1323
- // Utility Methods
1324
-
1325
- init_client_id(parts) {
1326
- let cid = this.client_id;
1327
-
1328
- if (undefined === cid) {
1329
- this.client_id = cid = (
1330
-
1331
-
1332
-
1333
- this.new_client_id(parts)
1334
- );}
1335
-
1336
- return cid}
1337
-
1338
- new_client_id(parts) {
1339
- return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
1340
-
1341
-
1342
-
1343
-
1344
-
1345
-
1346
-
1347
-
1348
-
1326
+ post(topic, payload, pub_opt) {// qos:0
1327
+ return this.pub({topic, payload, qos:0}, pub_opt)}
1328
+ send(topic, payload, pub_opt) {// qos:1
1329
+ return this.pub({topic, payload, qos:1}, pub_opt)}
1330
+ store(topic, payload, pub_opt) {// qos:1, retain: 1
1331
+ return this.pub({topic, payload, qos:1, retain: 1}, pub_opt)}
1332
+
1333
+ // alias: json_post
1334
+ obj_post(topic, msg, pub_opt) {// qos:0
1335
+ return this.pub({topic, msg, arg: 'msg', qos:0}, pub_opt)}
1336
+ // alias: json_send
1337
+ obj_send(topic, msg, pub_opt) {// qos:1
1338
+ return this.pub({topic, msg, arg: 'msg', qos:1}, pub_opt)}
1339
+ // alias: json_store
1340
+ obj_store(topic, msg, pub_opt) {// qos:1, retain: 1
1341
+ return this.pub({topic, msg, arg: 'msg', qos:1, retain: 1}, pub_opt)}
1342
+
1343
+ // alias: publish -- because 'pub' is shorter for semantic aliases above
1344
+ async pub(pkt, pub_opt) {
1345
+ if (undefined === pkt.payload) {
1346
+ if ('function' === typeof pub_opt) {
1347
+ pub_opt = {fn_encode: pub_opt};}
1348
+
1349
+ let {msg} = pkt;
1350
+ switch (typeof msg) {
1351
+ case 'function':
1352
+ pub_opt = {...pub_opt, fn_encode: msg};
1353
+ // flow into 'undefined' case
1354
+ case 'undefined':
1355
+ // return a single-value closure to publish packets
1356
+ return v => this.pub({...pkt, [pkt.arg || 'payload']: v}, pub_opt)}
1357
+
1358
+ // Encode payload from msg; fn_encode allows alternative to JSON.stringify
1359
+ let {fn_encode} = pub_opt || {};
1360
+ pkt.payload = fn_encode
1361
+ ? await fn_encode(msg)
1362
+ : JSON.stringify(msg);}
1363
+
1364
+ if (pub_opt) {
1365
+ if (pub_opt.props) {
1366
+ pkt.props = pub_opt.props;}
1367
+ if (pub_opt.xform) {
1368
+ pkt = pub_opt.xform(pkt) || pkt;} }
1369
+
1370
+ return this._send('publish', pkt,
1371
+ pkt.qos ? pkt : void 0 ) }// key
1349
1372
 
1350
1373
 
1351
1374
  // Internal API
@@ -1354,52 +1377,24 @@ class MQTTBase {
1354
1377
 
1355
1378
  _init_dispatch(opt) {
1356
1379
  this.constructor?._once_();
1357
- let router = this.router =
1358
- this._init_router?.(opt, this);
1359
-
1360
- let tgt ={
1361
- __proto__: opt.on_mqtt_type || {}
1362
- , router};
1363
-
1364
- tgt.mqtt_publish ||= router?.invoke;
1365
- return _mqtt_dispatch(this, tgt)}
1380
+ let target ={__proto__: opt.on_mqtt_type};
1381
+ target.mqtt_publish ||=
1382
+ this._init_router?.(opt, this, target);
1383
+ return _mqtt_dispatch(this, target)}
1366
1384
 
1367
1385
  static _aliases() {
1368
- return ' pub:publish sub:subscribe unsub:unsubscribe '}
1386
+ return ' publish:pub sub:subscribe unsub:unsubscribe json_post:obj_post json_send:obj_send json_store:obj_store'}
1369
1387
 
1370
1388
  static _once_(self=this) {
1371
1389
  self._once_ = _=>0;
1372
- self.MQTTError = MQTTError;
1373
1390
  let p = self.prototype;
1391
+ p.MQTTError = MQTTError;
1374
1392
  for (let alias of self._aliases().split(/\s+/)) {
1375
1393
  alias = alias.split(':');
1376
1394
  let fn = alias[1] && p[alias[1]];
1377
1395
  if (fn) {p[alias[0]] = fn;} } } }
1378
1396
 
1379
1397
 
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
- */
1395
-
1396
-
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
1398
  function _as_topics(pkt, ex, topic_prefix) {
1404
1399
  if (ex?.trim) {// string
1405
1400
  topic_prefix = ex;
@@ -1416,55 +1411,11 @@ function _as_topics(pkt, ex, topic_prefix) {
1416
1411
  if (topic_prefix) {
1417
1412
  // particularly useful with shared queues, e.g.
1418
1413
  // topic_prefix = '$share/some-queue-name/'
1419
- pkt.topics = _prefix_topics(topic_prefix, pkt.topics);}
1420
- return pkt}
1421
-
1414
+ let _prefix_topics = v =>
1415
+ v.trim ? topic_prefix+v : v.map(_prefix_topics);
1422
1416
 
1423
- async function _pub(self, pkt, pub_opt) {
1424
- if (undefined === pkt.payload) {
1425
- if ('function' === typeof pub_opt) {
1426
- pub_opt = {fn_encode: pub_opt};}
1427
-
1428
- let {msg} = pkt;
1429
- switch (typeof msg) {
1430
- case 'function':
1431
- pub_opt = {...pub_opt, fn_encode: msg};
1432
- // flow into 'undefined' case
1433
- case 'undefined':
1434
- // return a single-value closure to publish packets
1435
- return v => _pub(self, {...pkt, [pkt.arg || 'payload']: v}, pub_opt)
1436
-
1437
- default:
1438
- // Encode payload from msg; fn_encode allows alternative to JSON.stringify
1439
- let {fn_encode} = pub_opt || {};
1440
- pkt.payload = fn_encode
1441
- ? await fn_encode(msg)
1442
- : JSON.stringify(msg);} }
1443
-
1444
- if (pub_opt) {
1445
- if (pub_opt.props) {
1446
- pkt.props = pub_opt.props;}
1447
- if (pub_opt.xform) {
1448
- pkt = pub_opt.xform(pkt) || pkt;} }
1449
-
1450
- return self._send('publish', pkt,
1451
- pkt.qos ? pkt : void 0 ) }// key
1452
-
1453
- {
1454
- Object.assign(_pub,{
1455
- m: (self, topic, payload, pub_opt) =>
1456
- _pub(self, {topic, payload, qos:0}, pub_opt)
1457
- , mq: (self, topic, payload, pub_opt) =>
1458
- _pub(self, {topic, payload, qos:1}, pub_opt)
1459
- , mqr: (self, topic, payload, pub_opt) =>
1460
- _pub(self, {topic, payload, qos:1, retain: 1}, pub_opt)
1461
-
1462
- , o: (self, topic, msg, pub_opt) =>
1463
- _pub(self, {topic, msg, arg: 'msg', qos:0}, pub_opt)
1464
- , oq: (self, topic, msg, pub_opt) =>
1465
- _pub(self, {topic, msg, arg: 'msg', qos:1}, pub_opt)
1466
- , oqr: (self, topic, msg, pub_opt) =>
1467
- _pub(self, {topic, msg, arg: 'msg', qos:1, retain: 1}, pub_opt)} ); }
1417
+ pkt.topics = pkt.topics.map(_prefix_topics);}
1418
+ return pkt}
1468
1419
 
1469
1420
  const pkt_api = {
1470
1421
  utf8(u8) { return new TextDecoder('utf-8').decode(u8 || this.payload ) },
@@ -1473,20 +1424,27 @@ const pkt_api = {
1473
1424
  };
1474
1425
 
1475
1426
  class MQTTCore extends MQTTBase {
1476
- constructor(opt={}) {
1477
- super(opt);
1478
- this.with(opt);}
1479
-
1480
1427
  static mqtt_ctx(mqtt_level, mqtt_opts, pkt_ctx=pkt_api) {
1481
1428
  let self = class extends this {};
1482
1429
  self.prototype.mqtt_ctx =
1483
1430
  mqtt_pkt_ctx(mqtt_level, mqtt_opts, pkt_ctx);
1484
1431
  return self}
1485
1432
 
1486
- with(fns_ns) {
1487
- for (let [k,v] of Object.entries(fns_ns)) {
1488
- if ('function' === typeof v) {this[k] = v;} }
1489
- return this}
1433
+
1434
+ // automatic Client Id for connect()
1435
+ init_client_id(parts=['u8-mqtt--','']) {
1436
+ let sess_stg=this.sess_stg;
1437
+ let key, cid = sess_stg?.getItem(key=parts.join(' '));
1438
+ if (! cid) {
1439
+ cid = parts.join(Math.random().toString(36).slice(2));
1440
+ sess_stg?.setItem(key, cid);}
1441
+ return cid}
1442
+
1443
+ get sess_stg() {return globalThis.sessionStorage}
1444
+
1445
+
1446
+ //on_error(err, evt) ::
1447
+ // console.warn @ '[[u8-mqtt error: %s]]', evt, err
1490
1448
 
1491
1449
  //log_conn(evt, arg, err_arg) ::
1492
1450
  // console.info @ '[[u8-mqtt log: %s]]', evt, arg, err_arg
@@ -1563,7 +1521,6 @@ class MQTTCore extends MQTTBase {
1563
1521
 
1564
1522
  with_tcp(...opt) {
1565
1523
  opt = this._conn_opt(opt);
1566
- console.log({opt});
1567
1524
  return this._use_conn (() =>
1568
1525
  this.with_stream(
1569
1526
  connect(opt)) ) }
@@ -1625,7 +1582,7 @@ class MQTTCore extends MQTTBase {
1625
1582
 
1626
1583
  return this} }
1627
1584
 
1628
- const version = '0.4.0';
1585
+ const version = '0.5.0';
1629
1586
 
1630
1587
  const MQTTClient_v4 = /* #__PURE__ */
1631
1588
  with_topic_path_router(