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/cjs/v5.cjs CHANGED
@@ -154,7 +154,7 @@ class mqtt_reader_v4 {
154
154
 
155
155
  }
156
156
 
157
- class mqtt_reader_v5$1 extends mqtt_reader_v4 {
157
+ let mqtt_reader_v5$1 = class mqtt_reader_v5 extends mqtt_reader_v4 {
158
158
  props() {
159
159
  let {buf, step} = this;
160
160
  let [n, vi, vi0] = decode_varint$1(buf, step.k|0);
@@ -189,7 +189,7 @@ class mqtt_reader_v5$1 extends mqtt_reader_v4 {
189
189
  : buf.subarray(vi, step.k|0)
190
190
  }
191
191
  */
192
- }
192
+ };
193
193
 
194
194
  function mqtt_reader_info(mqtt_reader, ... info_fn_list) {
195
195
  mqtt_reader = class extends mqtt_reader {
@@ -819,30 +819,39 @@ const with_topic_router = mqtt_topic_router =>
819
819
  return super._aliases() +
820
820
  ' sub_topic:subscribe_topic unsub_topic:unsubscribe_topic'}
821
821
 
822
- _init_router(opt) {
823
- return mqtt_topic_router(opt, this)}
824
-
825
- get on_topic() {return this.router.add}
822
+ _init_router(opt, self, target) {
823
+ this._subs = [];
824
+ let router = this.router = target.router =
825
+ mqtt_topic_router(opt, this, target);
826
+ return router?.invoke}
826
827
 
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
828
+ on_sub(suback, pkt) {
829
+ suback.pkt = pkt;
830
+ this._subs.push(suback);
831
+ return suback}
832
+ subs_settled() {
833
+ return Promise.allSettled(
834
+ this._subs.splice(0,Infinity)) }
832
835
 
833
836
  // alias: sub_topic
834
837
  subscribe_topic(topic_route, ...args) {
835
838
  let router = this.router;
836
839
  router.add(topic_route, true, args.pop() );// handler
837
840
  let topic = router.mqtt_topic(topic_route);
838
- return this._sub_chain(topic, ...args ) }// ex, topic_prefix
841
+ this.subscribe(topic, ...args );// ex, topic_prefix
842
+ return this }// fluent api -- return this and track side effects
839
843
 
840
844
  // alias: unsub_topic
841
845
  unsubscribe_topic(topic_route, ...args) {
842
846
  let router = this.router;
843
847
  router.remove(topic_route, true);
844
848
  let topic = router.mqtt_topic(topic_route);
845
- return this.unsubscribe([[ topic ]], ...args ) } };// topic_prefix
849
+ return this.unsubscribe(topic, ...args ) }// topic_prefix
850
+
851
+ // add topic handlers without corresponding subscribe packet
852
+ on_topic(...args) {
853
+ this.router.add(...args);
854
+ return this} };
846
855
 
847
856
  // Use [regexparam][] for url-like topic parsing
848
857
  // [regexparam]: https://github.com/lukeed/regexparam
@@ -855,16 +864,22 @@ const with_topic_path_router = /* #__PURE__ */
855
864
  const mqtt_topic = topic_route =>
856
865
  topic_route
857
866
  .replace(/[*].*$/, '#')
858
- .replace(/:\w+\??/g, '+');
867
+ .replace(/:\w[^\/]*/g, '+');
859
868
 
860
- const as_topic_path = topic_route =>(
869
+ /* From the [MQTT v5 Spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Topic_Names_and)
870
+ 4.7.1.2 Multi-level wildcard -- (‘#’ U+0023)
871
+ ... MUST be specified either on its own or following a topic level separator.
872
+ In either case it MUST be the last character specified in the Topic Filter
873
+
874
+ 4.7.1.3 Single-level wildcard -- (‘+’ U+002B)
875
+ ...it MUST occupy an entire level of the filter.
876
+ */
877
+
878
+ const as_topic_path = (topic_route, id) =>(
879
+ id=1,
861
880
  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
881
+ .replace(/#$/, '*' )// replace MQTT '#' multi-level wildcard at end
882
+ .replace(/\+/g, () => `:$${id++}` ) );// replace MQTT '+' single-level wildcards
868
883
 
869
884
  function _ignore(pkt, params, ctx) {ctx.done = true;}
870
885
 
@@ -879,9 +894,8 @@ function mqtt_topic_path_router() {
879
894
  let priority = args.pop();
880
895
 
881
896
  if ('function' !== typeof fn) {
882
- if (false === fn) {
883
- fn = _ignore;}
884
- else throw new TypeError()}
897
+ if (fn) {throw new TypeError()}
898
+ fn = _ignore;}
885
899
 
886
900
  let rte = parse(as_topic_path(topic_route));
887
901
 
@@ -897,7 +911,7 @@ function mqtt_topic_path_router() {
897
911
  , clear(priority) {
898
912
  pri_lsts[priority ? 0 : 1] = [];
899
913
  if (null == priority) {
900
- pri_lsts[1] = [];} }
914
+ pri_lsts[1] = []; } }// null clears both lists
901
915
 
902
916
  , async invoke(pkt, ctx) {
903
917
  ctx.idx = 0;
@@ -913,52 +927,34 @@ function mqtt_topic_path_router() {
913
927
  break}
914
928
  else ctx.idx++;}
915
929
 
916
- let {pkt_id, qos} = pkt;
917
- if (1 === qos) {
918
- await ctx.mqtt._send('puback', {pkt_id});} } } }
930
+ if (1 === pkt.qos) {
931
+ await ctx.mqtt.puback(pkt);} } } }
919
932
 
920
933
 
921
934
  function * _routes_iter(all_route_lists, topic) {
935
+ topic = topic.replace(/^[\/]*/, '/'); // ensure '/' prefix for regexparam library
922
936
  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]}
937
+ for (let {keys, pattern, tgt} of route_list) {
938
+ let match = pattern.exec(topic);
939
+ if (match) {
940
+ let params = keys
941
+ ? keys.reduce(
942
+ (o, k, i) => (o[k] = match[1+i], o)
943
+ , {})
944
+ : match.groups ?? match;
945
+ yield [tgt, params];} } } }
955
946
 
956
947
 
957
948
  function _route_remove(all_route_lists, query) {
958
- let match = route => route===query || route.tgt===query || route.key===query;
949
+ let fn_match = route =>(
950
+ route===query
951
+ || route.tgt===query
952
+ || route.key===query);
959
953
  for (let lst of all_route_lists) {
960
- let i = lst.findIndex(match);
961
- if (0 <= i) {return !! lst.splice(i,1)} }
954
+ let i = lst.findIndex(fn_match);
955
+ if (0 <= i) {
956
+ lst.splice(i,1);
957
+ return true} }
962
958
  return false}
963
959
 
964
960
  /*
@@ -1219,6 +1215,22 @@ const _mqtt_cmdid_dispatch ={
1219
1215
 
1220
1216
  await fn?.call(target, pkt, ctx);} })()) };
1221
1217
 
1218
+ /*
1219
+ on_mqtt_type = {
1220
+ mqtt_auth(pkt, ctx) ::
1221
+ mqtt_connect(pkt, ctx) ::
1222
+ mqtt_connack(pkt, ctx) ::
1223
+ mqtt_disconnect(pkt, ctx) ::
1224
+
1225
+ mqtt_publish(pkt, ctx)
1226
+ mqtt_subscribe(pkt, ctx) ::
1227
+ mqtt_unsubscribe(pkt, ctx) ::
1228
+
1229
+ mqtt_pingreq(pkt, ctx) ::
1230
+ mqtt_pingresp(pkt, ctx) ::
1231
+ }
1232
+ */
1233
+
1222
1234
  function _mqtt_dispatch(opt, target) {
1223
1235
  let _disp_ = _mqtt_cmdid_dispatch.create(target);
1224
1236
  let { cmdids } = _disp_;
@@ -1248,28 +1260,34 @@ class MQTTError extends Error {
1248
1260
 
1249
1261
  class MQTTBase {
1250
1262
  constructor(opt={}) {
1263
+ this.with(opt);
1251
1264
  this._conn_ = _mqtt_conn(this,
1252
1265
  this._init_dispatch(opt, this)); }
1253
1266
 
1267
+ with(fns_ns) {
1268
+ for (let [k,v] of Object.entries(fns_ns)) {
1269
+ if ('function' === typeof v) {this[k] = v;} }
1270
+ return this}
1271
+
1254
1272
  async conn_emit(evt, arg, err_arg) {
1255
1273
  this.log_conn?.(evt, arg, err_arg);
1256
1274
  try {
1257
- let fn_evt = this[await evt]; // microtask break
1275
+ let fn_evt = this[await evt]; // microtask break using `await evt`
1258
1276
  if (fn_evt) {
1259
1277
  await fn_evt.call(this, this, arg, err_arg);}
1260
- else if (err_arg) {
1261
- await this.on_error(err_arg, evt);} }
1278
+ else if (err_arg) {throw err_arg} }
1262
1279
  catch (err) {
1263
1280
  this.on_error(err, evt);} }
1264
1281
 
1265
- on_error(err, err_path) {
1266
- console.warn('[[u8-mqtt error: %s]]', err_path, err); }
1282
+ on_error(err, evt) {
1283
+ console.warn('[[u8-mqtt error: %s]]', evt, err); }
1267
1284
 
1268
1285
  // Handshaking Packets
1269
1286
 
1270
1287
  async connect(pkt={}) {
1271
- let cid = pkt.client_id || ['u8-mqtt--', ''];
1272
- if (Array.isArray(cid)) {
1288
+ let cid = pkt.client_id || this.client_id;
1289
+ if ('string' !== typeof cid) {
1290
+ // see init_client_id implementation in core.jsy
1273
1291
  pkt.client_id = cid = this.init_client_id(cid);}
1274
1292
  this.client_id = cid;
1275
1293
 
@@ -1295,12 +1313,13 @@ class MQTTBase {
1295
1313
  return this._send('auth', pkt, 'auth')}
1296
1314
 
1297
1315
  ping() {return this._send('pingreq', null, 'pingresp')}
1298
-
1316
+ puback({pkt_id}) {return this._send('puback', {pkt_id})}
1299
1317
 
1300
1318
  // alias: sub
1301
1319
  subscribe(pkt, ex, topic_prefix) {
1302
1320
  pkt = _as_topics(pkt, ex, topic_prefix);
1303
- return this._send('subscribe', pkt, pkt)}
1321
+ let suback = this._send('subscribe', pkt, pkt);
1322
+ return this.on_sub?.(suback, pkt) ?? suback}
1304
1323
 
1305
1324
  // alias: unsub
1306
1325
  unsubscribe(pkt, ex, topic_prefix) {
@@ -1308,48 +1327,52 @@ class MQTTBase {
1308
1327
  return this._send('unsubscribe', pkt, pkt)}
1309
1328
 
1310
1329
 
1311
- // alias: pub
1312
- publish(pkt, pub_opt) {return _pub(this, pkt, pub_opt)}
1313
- post(topic, payload, pub_opt) {return _pub.m(this, topic, payload, pub_opt)}
1314
- send(topic, payload, pub_opt) {return _pub.mq(this, topic, payload, pub_opt)}
1315
- store(topic, payload, pub_opt) {return _pub.mqr(this, topic, payload, pub_opt)}
1316
-
1317
- json_post(topic, msg, pub_opt) {return _pub.o(this, topic, msg, pub_opt)}
1318
- json_send(topic, msg, pub_opt) {return _pub.oq(this, topic, msg, pub_opt)}
1319
- json_store(topic, msg, pub_opt) {return _pub.oqr(this, topic, msg, pub_opt)}
1320
-
1321
- obj_post(topic, msg, pub_opt) {return _pub.o(this, topic, msg, pub_opt)}
1322
- obj_send(topic, msg, pub_opt) {return _pub.oq(this, topic, msg, pub_opt)}
1323
- obj_store(topic, msg, pub_opt) {return _pub.oqr(this, topic, msg, pub_opt)}
1324
-
1325
-
1326
-
1327
- // Utility Methods
1328
-
1329
- init_client_id(parts) {
1330
- let cid = this.client_id;
1331
-
1332
- if (undefined === cid) {
1333
- this.client_id = cid = (
1334
-
1335
-
1336
-
1337
- this.new_client_id(parts)
1338
- );}
1339
-
1340
- return cid}
1341
-
1342
- new_client_id(parts) {
1343
- return [parts[0], Math.random().toString(36).slice(2), parts[1]].join('')}
1344
-
1345
-
1346
-
1347
-
1348
-
1349
-
1350
-
1351
-
1352
-
1330
+ post(topic, payload, pub_opt) {// qos:0
1331
+ return this.pub({topic, payload, qos:0}, pub_opt)}
1332
+ send(topic, payload, pub_opt) {// qos:1
1333
+ return this.pub({topic, payload, qos:1}, pub_opt)}
1334
+ store(topic, payload, pub_opt) {// qos:1, retain: 1
1335
+ return this.pub({topic, payload, qos:1, retain: 1}, pub_opt)}
1336
+
1337
+ // alias: json_post
1338
+ obj_post(topic, msg, pub_opt) {// qos:0
1339
+ return this.pub({topic, msg, arg: 'msg', qos:0}, pub_opt)}
1340
+ // alias: json_send
1341
+ obj_send(topic, msg, pub_opt) {// qos:1
1342
+ return this.pub({topic, msg, arg: 'msg', qos:1}, pub_opt)}
1343
+ // alias: json_store
1344
+ obj_store(topic, msg, pub_opt) {// qos:1, retain: 1
1345
+ return this.pub({topic, msg, arg: 'msg', qos:1, retain: 1}, pub_opt)}
1346
+
1347
+ // alias: publish -- because 'pub' is shorter for semantic aliases above
1348
+ async pub(pkt, pub_opt) {
1349
+ if (undefined === pkt.payload) {
1350
+ if ('function' === typeof pub_opt) {
1351
+ pub_opt = {fn_encode: pub_opt};}
1352
+
1353
+ let {msg} = pkt;
1354
+ switch (typeof msg) {
1355
+ case 'function':
1356
+ pub_opt = {...pub_opt, fn_encode: msg};
1357
+ // flow into 'undefined' case
1358
+ case 'undefined':
1359
+ // return a single-value closure to publish packets
1360
+ return v => this.pub({...pkt, [pkt.arg || 'payload']: v}, pub_opt)}
1361
+
1362
+ // Encode payload from msg; fn_encode allows alternative to JSON.stringify
1363
+ let {fn_encode} = pub_opt || {};
1364
+ pkt.payload = fn_encode
1365
+ ? await fn_encode(msg)
1366
+ : JSON.stringify(msg);}
1367
+
1368
+ if (pub_opt) {
1369
+ if (pub_opt.props) {
1370
+ pkt.props = pub_opt.props;}
1371
+ if (pub_opt.xform) {
1372
+ pkt = pub_opt.xform(pkt) || pkt;} }
1373
+
1374
+ return this._send('publish', pkt,
1375
+ pkt.qos ? pkt : void 0 ) }// key
1353
1376
 
1354
1377
 
1355
1378
  // Internal API
@@ -1358,52 +1381,24 @@ class MQTTBase {
1358
1381
 
1359
1382
  _init_dispatch(opt) {
1360
1383
  this.constructor?._once_();
1361
- let router = this.router =
1362
- this._init_router?.(opt, this);
1363
-
1364
- let tgt ={
1365
- __proto__: opt.on_mqtt_type || {}
1366
- , router};
1367
-
1368
- tgt.mqtt_publish ||= router?.invoke;
1369
- return _mqtt_dispatch(this, tgt)}
1384
+ let target ={__proto__: opt.on_mqtt_type};
1385
+ target.mqtt_publish ||=
1386
+ this._init_router?.(opt, this, target);
1387
+ return _mqtt_dispatch(this, target)}
1370
1388
 
1371
1389
  static _aliases() {
1372
- return ' pub:publish sub:subscribe unsub:unsubscribe '}
1390
+ return ' publish:pub sub:subscribe unsub:unsubscribe json_post:obj_post json_send:obj_send json_store:obj_store'}
1373
1391
 
1374
1392
  static _once_(self=this) {
1375
1393
  self._once_ = _=>0;
1376
- self.MQTTError = MQTTError;
1377
1394
  let p = self.prototype;
1395
+ p.MQTTError = MQTTError;
1378
1396
  for (let alias of self._aliases().split(/\s+/)) {
1379
1397
  alias = alias.split(':');
1380
1398
  let fn = alias[1] && p[alias[1]];
1381
1399
  if (fn) {p[alias[0]] = fn;} } } }
1382
1400
 
1383
1401
 
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
- */
1399
-
1400
-
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
1402
  function _as_topics(pkt, ex, topic_prefix) {
1408
1403
  if (ex?.trim) {// string
1409
1404
  topic_prefix = ex;
@@ -1420,55 +1415,11 @@ function _as_topics(pkt, ex, topic_prefix) {
1420
1415
  if (topic_prefix) {
1421
1416
  // particularly useful with shared queues, e.g.
1422
1417
  // topic_prefix = '$share/some-queue-name/'
1423
- pkt.topics = _prefix_topics(topic_prefix, pkt.topics);}
1424
- return pkt}
1425
-
1418
+ let _prefix_topics = v =>
1419
+ v.trim ? topic_prefix+v : v.map(_prefix_topics);
1426
1420
 
1427
- async function _pub(self, pkt, pub_opt) {
1428
- if (undefined === pkt.payload) {
1429
- if ('function' === typeof pub_opt) {
1430
- pub_opt = {fn_encode: pub_opt};}
1431
-
1432
- let {msg} = pkt;
1433
- switch (typeof msg) {
1434
- case 'function':
1435
- pub_opt = {...pub_opt, fn_encode: msg};
1436
- // flow into 'undefined' case
1437
- case 'undefined':
1438
- // return a single-value closure to publish packets
1439
- return v => _pub(self, {...pkt, [pkt.arg || 'payload']: v}, pub_opt)
1440
-
1441
- default:
1442
- // Encode payload from msg; fn_encode allows alternative to JSON.stringify
1443
- let {fn_encode} = pub_opt || {};
1444
- pkt.payload = fn_encode
1445
- ? await fn_encode(msg)
1446
- : JSON.stringify(msg);} }
1447
-
1448
- if (pub_opt) {
1449
- if (pub_opt.props) {
1450
- pkt.props = pub_opt.props;}
1451
- if (pub_opt.xform) {
1452
- pkt = pub_opt.xform(pkt) || pkt;} }
1453
-
1454
- return self._send('publish', pkt,
1455
- pkt.qos ? pkt : void 0 ) }// key
1456
-
1457
- {
1458
- Object.assign(_pub,{
1459
- m: (self, topic, payload, pub_opt) =>
1460
- _pub(self, {topic, payload, qos:0}, pub_opt)
1461
- , mq: (self, topic, payload, pub_opt) =>
1462
- _pub(self, {topic, payload, qos:1}, pub_opt)
1463
- , mqr: (self, topic, payload, pub_opt) =>
1464
- _pub(self, {topic, payload, qos:1, retain: 1}, pub_opt)
1465
-
1466
- , o: (self, topic, msg, pub_opt) =>
1467
- _pub(self, {topic, msg, arg: 'msg', qos:0}, pub_opt)
1468
- , oq: (self, topic, msg, pub_opt) =>
1469
- _pub(self, {topic, msg, arg: 'msg', qos:1}, pub_opt)
1470
- , oqr: (self, topic, msg, pub_opt) =>
1471
- _pub(self, {topic, msg, arg: 'msg', qos:1, retain: 1}, pub_opt)} ); }
1421
+ pkt.topics = pkt.topics.map(_prefix_topics);}
1422
+ return pkt}
1472
1423
 
1473
1424
  const pkt_api = {
1474
1425
  utf8(u8) { return new TextDecoder('utf-8').decode(u8 || this.payload ) },
@@ -1477,20 +1428,27 @@ const pkt_api = {
1477
1428
  };
1478
1429
 
1479
1430
  class MQTTCore extends MQTTBase {
1480
- constructor(opt={}) {
1481
- super(opt);
1482
- this.with(opt);}
1483
-
1484
1431
  static mqtt_ctx(mqtt_level, mqtt_opts, pkt_ctx=pkt_api) {
1485
1432
  let self = class extends this {};
1486
1433
  self.prototype.mqtt_ctx =
1487
1434
  mqtt_pkt_ctx(mqtt_level, mqtt_opts, pkt_ctx);
1488
1435
  return self}
1489
1436
 
1490
- with(fns_ns) {
1491
- for (let [k,v] of Object.entries(fns_ns)) {
1492
- if ('function' === typeof v) {this[k] = v;} }
1493
- return this}
1437
+
1438
+ // automatic Client Id for connect()
1439
+ init_client_id(parts=['u8-mqtt--','']) {
1440
+ let sess_stg=this.sess_stg;
1441
+ let key, cid = sess_stg?.getItem(key=parts.join(' '));
1442
+ if (! cid) {
1443
+ cid = parts.join(Math.random().toString(36).slice(2));
1444
+ sess_stg?.setItem(key, cid);}
1445
+ return cid}
1446
+
1447
+ get sess_stg() {return globalThis.sessionStorage}
1448
+
1449
+
1450
+ //on_error(err, evt) ::
1451
+ // console.warn @ '[[u8-mqtt error: %s]]', evt, err
1494
1452
 
1495
1453
  //log_conn(evt, arg, err_arg) ::
1496
1454
  // console.info @ '[[u8-mqtt log: %s]]', evt, arg, err_arg
@@ -1567,7 +1525,6 @@ class MQTTCore extends MQTTBase {
1567
1525
 
1568
1526
  with_tcp(...opt) {
1569
1527
  opt = this._conn_opt(opt);
1570
- console.log({opt});
1571
1528
  return this._use_conn (() =>
1572
1529
  this.with_stream(
1573
1530
  node_net.connect(opt)) ) }
@@ -1629,7 +1586,7 @@ class MQTTCore extends MQTTBase {
1629
1586
 
1630
1587
  return this} }
1631
1588
 
1632
- const version = '0.4.0';
1589
+ const version = '0.5.0';
1633
1590
 
1634
1591
  const MQTTClient_v4 = /* #__PURE__ */
1635
1592
  with_topic_path_router(