u8-mqtt 0.4.1 → 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 (81) hide show
  1. package/cjs/basic-v4.cjs +103 -137
  2. package/cjs/basic-v4.cjs.map +1 -1
  3. package/cjs/basic-v5.cjs +102 -136
  4. package/cjs/basic-v5.cjs.map +1 -1
  5. package/cjs/index.cjs +144 -189
  6. package/cjs/index.cjs.map +1 -1
  7. package/cjs/v4.cjs +145 -190
  8. package/cjs/v4.cjs.map +1 -1
  9. package/cjs/v5.cjs +144 -189
  10. package/cjs/v5.cjs.map +1 -1
  11. package/code/_dispatch.jsy +16 -0
  12. package/code/base.jsy +68 -124
  13. package/code/core.jsy +15 -9
  14. package/code/router_path.jsy +24 -43
  15. package/code/with_topic_router.jsy +18 -10
  16. package/esm/basic-v4.js +1154 -0
  17. package/esm/basic-v4.js.map +1 -0
  18. package/esm/basic-v5.js +1416 -0
  19. package/esm/basic-v5.js.map +1 -0
  20. package/esm/deno/basic-v4.js +103 -137
  21. package/esm/deno/basic-v4.js.map +1 -1
  22. package/esm/deno/basic-v5.js +102 -136
  23. package/esm/deno/basic-v5.js.map +1 -1
  24. package/esm/deno/index.js +144 -189
  25. package/esm/deno/index.js.map +1 -1
  26. package/esm/deno/v4.js +145 -190
  27. package/esm/deno/v4.js.map +1 -1
  28. package/esm/deno/v5.js +144 -189
  29. package/esm/deno/v5.js.map +1 -1
  30. package/esm/index.js +1599 -0
  31. package/esm/index.js.map +1 -0
  32. package/esm/node/basic-v4.js +103 -137
  33. package/esm/node/basic-v4.js.map +1 -1
  34. package/esm/node/basic-v4.mjs +103 -137
  35. package/esm/node/basic-v4.mjs.map +1 -1
  36. package/esm/node/basic-v5.js +102 -136
  37. package/esm/node/basic-v5.js.map +1 -1
  38. package/esm/node/basic-v5.mjs +102 -136
  39. package/esm/node/basic-v5.mjs.map +1 -1
  40. package/esm/node/index.js +144 -189
  41. package/esm/node/index.js.map +1 -1
  42. package/esm/node/index.mjs +144 -189
  43. package/esm/node/index.mjs.map +1 -1
  44. package/esm/node/v4.js +145 -190
  45. package/esm/node/v4.js.map +1 -1
  46. package/esm/node/v4.mjs +145 -190
  47. package/esm/node/v4.mjs.map +1 -1
  48. package/esm/node/v5.js +144 -189
  49. package/esm/node/v5.js.map +1 -1
  50. package/esm/node/v5.mjs +144 -189
  51. package/esm/node/v5.mjs.map +1 -1
  52. package/esm/v4.js +1336 -0
  53. package/esm/v4.js.map +1 -0
  54. package/esm/v5.js +1599 -0
  55. package/esm/v5.js.map +1 -0
  56. package/esm/web/basic-v4.js +103 -137
  57. package/esm/web/basic-v4.js.map +1 -1
  58. package/esm/web/basic-v4.min.js +1 -1
  59. package/esm/web/basic-v4.min.js.br +0 -0
  60. package/esm/web/basic-v4.min.js.gz +0 -0
  61. package/esm/web/basic-v5.js +102 -136
  62. package/esm/web/basic-v5.js.map +1 -1
  63. package/esm/web/basic-v5.min.js +1 -1
  64. package/esm/web/basic-v5.min.js.br +0 -0
  65. package/esm/web/basic-v5.min.js.gz +0 -0
  66. package/esm/web/index.js +144 -189
  67. package/esm/web/index.js.map +1 -1
  68. package/esm/web/index.min.js +1 -1
  69. package/esm/web/index.min.js.br +0 -0
  70. package/esm/web/index.min.js.gz +0 -0
  71. package/esm/web/v4.js +145 -190
  72. package/esm/web/v4.js.map +1 -1
  73. package/esm/web/v4.min.js +1 -1
  74. package/esm/web/v4.min.js.br +0 -0
  75. package/esm/web/v4.min.js.gz +0 -0
  76. package/esm/web/v5.js +144 -189
  77. package/esm/web/v5.js.map +1 -1
  78. package/esm/web/v5.min.js +1 -1
  79. package/esm/web/v5.min.js.br +0 -0
  80. package/esm/web/v5.min.js.gz +0 -0
  81. 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,31 +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, client, target) {
818
+ _init_router(opt, self, target) {
819
+ this._subs = [];
819
820
  let router = this.router = target.router =
820
- mqtt_topic_router(opt, this);
821
+ mqtt_topic_router(opt, this, target);
821
822
  return router?.invoke}
822
- get on_topic() {return this.router.add}
823
823
 
824
- _sub_chain(topic, ex, topic_prefix) {
825
- let res = this.subscribe([[ topic ]], ex, topic_prefix);
826
- let subs = this.subs ||(this.subs = new Map());
827
- subs.set((res.topic = topic), (subs.last = res));
828
- 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)) }
829
831
 
830
832
  // alias: sub_topic
831
833
  subscribe_topic(topic_route, ...args) {
832
834
  let router = this.router;
833
835
  router.add(topic_route, true, args.pop() );// handler
834
836
  let topic = router.mqtt_topic(topic_route);
835
- 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
836
839
 
837
840
  // alias: unsub_topic
838
841
  unsubscribe_topic(topic_route, ...args) {
839
842
  let router = this.router;
840
843
  router.remove(topic_route, true);
841
844
  let topic = router.mqtt_topic(topic_route);
842
- 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} };
843
851
 
844
852
  // Use [regexparam][] for url-like topic parsing
845
853
  // [regexparam]: https://github.com/lukeed/regexparam
@@ -852,7 +860,7 @@ const with_topic_path_router = /* #__PURE__ */
852
860
  const mqtt_topic = topic_route =>
853
861
  topic_route
854
862
  .replace(/[*].*$/, '#')
855
- .replace(/:\w+\??/g, '+');
863
+ .replace(/:\w[^\/]*/g, '+');
856
864
 
857
865
  /* From the [MQTT v5 Spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Topic_Names_and)
858
866
  4.7.1.2 Multi-level wildcard -- (‘#’ U+0023)
@@ -882,9 +890,8 @@ function mqtt_topic_path_router() {
882
890
  let priority = args.pop();
883
891
 
884
892
  if ('function' !== typeof fn) {
885
- if (false === fn) {
886
- fn = _ignore;}
887
- else throw new TypeError()}
893
+ if (fn) {throw new TypeError()}
894
+ fn = _ignore;}
888
895
 
889
896
  let rte = parse(as_topic_path(topic_route));
890
897
 
@@ -900,7 +907,7 @@ function mqtt_topic_path_router() {
900
907
  , clear(priority) {
901
908
  pri_lsts[priority ? 0 : 1] = [];
902
909
  if (null == priority) {
903
- pri_lsts[1] = [];} }
910
+ pri_lsts[1] = []; } }// null clears both lists
904
911
 
905
912
  , async invoke(pkt, ctx) {
906
913
  ctx.idx = 0;
@@ -916,52 +923,34 @@ function mqtt_topic_path_router() {
916
923
  break}
917
924
  else ctx.idx++;}
918
925
 
919
- let {pkt_id, qos} = pkt;
920
- if (1 === qos) {
921
- await ctx.mqtt._send('puback', {pkt_id});} } } }
926
+ if (1 === pkt.qos) {
927
+ await ctx.mqtt.puback(pkt);} } } }
922
928
 
923
929
 
924
930
  function * _routes_iter(all_route_lists, topic) {
931
+ topic = topic.replace(/^[\/]*/, '/'); // ensure '/' prefix for regexparam library
925
932
  for (let route_list of all_route_lists) {
926
- for (let route of route_list) {
927
- let res = _route_match_one(topic, route);
928
- if (undefined !== res) {
929
- yield res;} } } }
930
-
931
-
932
- function _route_match_one(topic, {keys, pattern, tgt}) {
933
- let match = '/' !== topic[0]
934
- ? pattern.exec('/'+topic)
935
- : pattern.exec(topic);
936
-
937
- if (null === match) {
938
- return}
939
-
940
- if (false === keys) {
941
- let {groups} = match;
942
- if (! groups) {
943
- return [tgt]}
944
-
945
- let params = {};
946
- for (let k in groups) {
947
- params[k] = groups[k];}
948
-
949
- return [tgt, params]}
950
-
951
- if (0 === keys.length) {
952
- return [tgt]}
953
-
954
- let params = {};
955
- for (let i=0; i<keys.length; i++) {
956
- params[ keys[i] ] = match[1+i];}
957
- 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];} } } }
958
942
 
959
943
 
960
944
  function _route_remove(all_route_lists, query) {
961
- 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);
962
949
  for (let lst of all_route_lists) {
963
- let i = lst.findIndex(match);
964
- 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} }
965
954
  return false}
966
955
 
967
956
  /*
@@ -1222,6 +1211,22 @@ const _mqtt_cmdid_dispatch ={
1222
1211
 
1223
1212
  await fn?.call(target, pkt, ctx);} })()) };
1224
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
+
1225
1230
  function _mqtt_dispatch(opt, target) {
1226
1231
  let _disp_ = _mqtt_cmdid_dispatch.create(target);
1227
1232
  let { cmdids } = _disp_;
@@ -1251,28 +1256,34 @@ class MQTTError extends Error {
1251
1256
 
1252
1257
  class MQTTBase {
1253
1258
  constructor(opt={}) {
1259
+ this.with(opt);
1254
1260
  this._conn_ = _mqtt_conn(this,
1255
1261
  this._init_dispatch(opt, this)); }
1256
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
+
1257
1268
  async conn_emit(evt, arg, err_arg) {
1258
1269
  this.log_conn?.(evt, arg, err_arg);
1259
1270
  try {
1260
- let fn_evt = this[await evt]; // microtask break
1271
+ let fn_evt = this[await evt]; // microtask break using `await evt`
1261
1272
  if (fn_evt) {
1262
1273
  await fn_evt.call(this, this, arg, err_arg);}
1263
- else if (err_arg) {
1264
- await this.on_error(err_arg, evt);} }
1274
+ else if (err_arg) {throw err_arg} }
1265
1275
  catch (err) {
1266
1276
  this.on_error(err, evt);} }
1267
1277
 
1268
- on_error(err, err_path) {
1269
- console.warn('[[u8-mqtt error: %s]]', err_path, err); }
1278
+ on_error(err, evt) {
1279
+ console.warn('[[u8-mqtt error: %s]]', evt, err); }
1270
1280
 
1271
1281
  // Handshaking Packets
1272
1282
 
1273
1283
  async connect(pkt={}) {
1274
- let cid = pkt.client_id || ['u8-mqtt--', ''];
1275
- 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
1276
1287
  pkt.client_id = cid = this.init_client_id(cid);}
1277
1288
  this.client_id = cid;
1278
1289
 
@@ -1298,12 +1309,13 @@ class MQTTBase {
1298
1309
  return this._send('auth', pkt, 'auth')}
1299
1310
 
1300
1311
  ping() {return this._send('pingreq', null, 'pingresp')}
1301
-
1312
+ puback({pkt_id}) {return this._send('puback', {pkt_id})}
1302
1313
 
1303
1314
  // alias: sub
1304
1315
  subscribe(pkt, ex, topic_prefix) {
1305
1316
  pkt = _as_topics(pkt, ex, topic_prefix);
1306
- return this._send('subscribe', pkt, pkt)}
1317
+ let suback = this._send('subscribe', pkt, pkt);
1318
+ return this.on_sub?.(suback, pkt) ?? suback}
1307
1319
 
1308
1320
  // alias: unsub
1309
1321
  unsubscribe(pkt, ex, topic_prefix) {
@@ -1311,48 +1323,52 @@ class MQTTBase {
1311
1323
  return this._send('unsubscribe', pkt, pkt)}
1312
1324
 
1313
1325
 
1314
- // alias: pub
1315
- publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
1316
- post(topic, payload, pub_opt) {return _pub.m(this, topic, payload, pub_opt)}
1317
- send(topic, payload, pub_opt) {return _pub.mq(this, topic, payload, pub_opt)}
1318
- store(topic, payload, pub_opt) {return _pub.mqr(this, topic, payload, pub_opt)}
1319
-
1320
- json_post(topic, msg, pub_opt) {return _pub.o(this, topic, msg, pub_opt)}
1321
- json_send(topic, msg, pub_opt) {return _pub.oq(this, topic, msg, pub_opt)}
1322
- json_store(topic, msg, pub_opt) {return _pub.oqr(this, topic, msg, pub_opt)}
1323
-
1324
- obj_post(topic, msg, pub_opt) {return _pub.o(this, topic, msg, pub_opt)}
1325
- obj_send(topic, msg, pub_opt) {return _pub.oq(this, topic, msg, pub_opt)}
1326
- obj_store(topic, msg, pub_opt) {return _pub.oqr(this, topic, msg, pub_opt)}
1327
-
1328
-
1329
-
1330
- // Utility Methods
1331
-
1332
- init_client_id(parts) {
1333
- let cid = this.client_id;
1334
-
1335
- if (undefined === cid) {
1336
- this.client_id = cid = (
1337
-
1338
-
1339
-
1340
- this.new_client_id(parts)
1341
- );}
1342
-
1343
- return cid}
1344
-
1345
- new_client_id(parts) {
1346
- return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
1347
-
1348
-
1349
-
1350
-
1351
-
1352
-
1353
-
1354
-
1355
-
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
1356
1372
 
1357
1373
 
1358
1374
  // Internal API
@@ -1367,41 +1383,18 @@ class MQTTBase {
1367
1383
  return _mqtt_dispatch(this, target)}
1368
1384
 
1369
1385
  static _aliases() {
1370
- 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'}
1371
1387
 
1372
1388
  static _once_(self=this) {
1373
1389
  self._once_ = _=>0;
1374
- self.MQTTError = MQTTError;
1375
1390
  let p = self.prototype;
1391
+ p.MQTTError = MQTTError;
1376
1392
  for (let alias of self._aliases().split(/\s+/)) {
1377
1393
  alias = alias.split(':');
1378
1394
  let fn = alias[1] && p[alias[1]];
1379
1395
  if (fn) {p[alias[0]] = fn;} } } }
1380
1396
 
1381
1397
 
1382
- /*
1383
- on_mqtt_type = {
1384
- mqtt_auth(pkt, ctx) ::
1385
- mqtt_connect(pkt, ctx) ::
1386
- mqtt_connack(pkt, ctx) ::
1387
- mqtt_disconnect(pkt, ctx) ::
1388
-
1389
- mqtt_publish(pkt, ctx)
1390
- mqtt_subscribe(pkt, ctx) ::
1391
- mqtt_unsubscribe(pkt, ctx) ::
1392
-
1393
- mqtt_pingreq(pkt, ctx) ::
1394
- mqtt_pingresp(pkt, ctx) ::
1395
- }
1396
- */
1397
-
1398
-
1399
- const _prefix_topics = (topic_prefix, iterable) =>
1400
- Array.from(iterable, value =>(
1401
- value.trim // string
1402
- ? _prefix_topics(topic_prefix, value)
1403
- : topic_prefix + value) );
1404
-
1405
1398
  function _as_topics(pkt, ex, topic_prefix) {
1406
1399
  if (ex?.trim) {// string
1407
1400
  topic_prefix = ex;
@@ -1418,55 +1411,11 @@ function _as_topics(pkt, ex, topic_prefix) {
1418
1411
  if (topic_prefix) {
1419
1412
  // particularly useful with shared queues, e.g.
1420
1413
  // topic_prefix = '$share/some-queue-name/'
1421
- pkt.topics = _prefix_topics(topic_prefix, pkt.topics);}
1422
- return pkt}
1414
+ let _prefix_topics = v =>
1415
+ v.trim ? topic_prefix+v : v.map(_prefix_topics);
1423
1416
 
1424
-
1425
- async function _pub(self, pkt, pub_opt) {
1426
- if (undefined === pkt.payload) {
1427
- if ('function' === typeof pub_opt) {
1428
- pub_opt = {fn_encode: pub_opt};}
1429
-
1430
- let {msg} = pkt;
1431
- switch (typeof msg) {
1432
- case 'function':
1433
- pub_opt = {...pub_opt, fn_encode: msg};
1434
- // flow into 'undefined' case
1435
- case 'undefined':
1436
- // return a single-value closure to publish packets
1437
- return v => _pub(self, {...pkt, [pkt.arg || 'payload']: v}, pub_opt)
1438
-
1439
- default:
1440
- // Encode payload from msg; fn_encode allows alternative to JSON.stringify
1441
- let {fn_encode} = pub_opt || {};
1442
- pkt.payload = fn_encode
1443
- ? await fn_encode(msg)
1444
- : JSON.stringify(msg);} }
1445
-
1446
- if (pub_opt) {
1447
- if (pub_opt.props) {
1448
- pkt.props = pub_opt.props;}
1449
- if (pub_opt.xform) {
1450
- pkt = pub_opt.xform(pkt) || pkt;} }
1451
-
1452
- return self._send('publish', pkt,
1453
- pkt.qos ? pkt : void 0 ) }// key
1454
-
1455
- {
1456
- Object.assign(_pub,{
1457
- m: (self, topic, payload, pub_opt) =>
1458
- _pub(self, {topic, payload, qos:0}, pub_opt)
1459
- , mq: (self, topic, payload, pub_opt) =>
1460
- _pub(self, {topic, payload, qos:1}, pub_opt)
1461
- , mqr: (self, topic, payload, pub_opt) =>
1462
- _pub(self, {topic, payload, qos:1, retain: 1}, pub_opt)
1463
-
1464
- , o: (self, topic, msg, pub_opt) =>
1465
- _pub(self, {topic, msg, arg: 'msg', qos:0}, pub_opt)
1466
- , oq: (self, topic, msg, pub_opt) =>
1467
- _pub(self, {topic, msg, arg: 'msg', qos:1}, pub_opt)
1468
- , oqr: (self, topic, msg, pub_opt) =>
1469
- _pub(self, {topic, msg, arg: 'msg', qos:1, retain: 1}, pub_opt)} ); }
1417
+ pkt.topics = pkt.topics.map(_prefix_topics);}
1418
+ return pkt}
1470
1419
 
1471
1420
  const pkt_api = {
1472
1421
  utf8(u8) { return new TextDecoder('utf-8').decode(u8 || this.payload ) },
@@ -1475,20 +1424,27 @@ const pkt_api = {
1475
1424
  };
1476
1425
 
1477
1426
  class MQTTCore extends MQTTBase {
1478
- constructor(opt={}) {
1479
- super(opt);
1480
- this.with(opt);}
1481
-
1482
1427
  static mqtt_ctx(mqtt_level, mqtt_opts, pkt_ctx=pkt_api) {
1483
1428
  let self = class extends this {};
1484
1429
  self.prototype.mqtt_ctx =
1485
1430
  mqtt_pkt_ctx(mqtt_level, mqtt_opts, pkt_ctx);
1486
1431
  return self}
1487
1432
 
1488
- with(fns_ns) {
1489
- for (let [k,v] of Object.entries(fns_ns)) {
1490
- if ('function' === typeof v) {this[k] = v;} }
1491
- 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
1492
1448
 
1493
1449
  //log_conn(evt, arg, err_arg) ::
1494
1450
  // console.info @ '[[u8-mqtt log: %s]]', evt, arg, err_arg
@@ -1565,7 +1521,6 @@ class MQTTCore extends MQTTBase {
1565
1521
 
1566
1522
  with_tcp(...opt) {
1567
1523
  opt = this._conn_opt(opt);
1568
- console.log({opt});
1569
1524
  return this._use_conn (() =>
1570
1525
  this.with_stream(
1571
1526
  connect(opt)) ) }
@@ -1627,7 +1582,7 @@ class MQTTCore extends MQTTBase {
1627
1582
 
1628
1583
  return this} }
1629
1584
 
1630
- const version = '0.4.1';
1585
+ const version = '0.5.0';
1631
1586
 
1632
1587
  const MQTTClient_v4 = /* #__PURE__ */
1633
1588
  with_topic_path_router(