@transitive-sdk/utils-web 0.15.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/utils-web.js +49 -31
  2. package/package.json +1 -1
package/dist/utils-web.js CHANGED
@@ -406,8 +406,10 @@ var require_common = __commonJS({
406
406
  callback && callback(count);
407
407
  }, delay);
408
408
  };
409
- var storageRequestToSelector = (topic) => pathToTopic2(topicToPath2(topic).map((value) => value == "$store" ? "+" : value).map((value) => value == "$storeTail" ? "#" : value));
410
- var selectorToStorageRequest = (topic) => pathToTopic2(topicToPath2(topic).map((value) => value[0] == "+" ? "$store" : value).map((value) => value[0] == "#" ? "$storeTail" : value));
409
+ var metaPathToSelectorPath = (path) => path.map((value) => value[0] == "$" ? decodeURIComponent(value.slice(1)) : value);
410
+ var metaTopicToSelector = (topic) => pathToTopic2(metaPathToSelectorPath(topicToPath2(topic)));
411
+ var selectorPathToMetaPath = (path) => path.map((value) => ["+", "#"].includes(value[0]) ? `$${encodeURIComponent(value)}` : value);
412
+ var selectorToMetaTopic = (topic) => pathToTopic2(selectorPathToMetaPath(topicToPath2(topic)));
411
413
  var getRandomId = (bytes = 6) => {
412
414
  const buffer = new Uint8Array(bytes);
413
415
  crypto.getRandomValues(buffer);
@@ -497,8 +499,11 @@ var require_common = __commonJS({
497
499
  tryJSONParse,
498
500
  decodeJWT: decodeJWT3,
499
501
  visitAncestor,
500
- storageRequestToSelector,
501
- selectorToStorageRequest
502
+ // storageRequestToSelector, selectorToStorageRequest
503
+ metaPathToSelectorPath,
504
+ selectorPathToMetaPath,
505
+ metaTopicToSelector,
506
+ selectorToMetaTopic
502
507
  };
503
508
  }
504
509
  });
@@ -718,7 +723,7 @@ var require_MqttSync = __commonJS({
718
723
  encodeTopicElement,
719
724
  visitAncestor,
720
725
  getRandomId,
721
- selectorToStorageRequest
726
+ selectorPathToMetaPath
722
727
  } = require_common();
723
728
  var { DataCache } = require_DataCache();
724
729
  var log2 = getLogger2("MqttSync");
@@ -805,9 +810,10 @@ var require_MqttSync = __commonJS({
805
810
  if (!inclMeta && path.some((field) => field[0] == "$")) {
806
811
  return;
807
812
  }
808
- if (this.rpcHandlers[topic]) {
813
+ const rpcHandler = this.getRPCHandler(topic);
814
+ if (rpcHandler) {
809
815
  const json = mqttParsePayload(payload);
810
- this.handleRPCRequest(topic, json);
816
+ this.handleRPCRequest(path, rpcHandler, json);
811
817
  } else if (this.rpcCallbacks[topic]) {
812
818
  const json = mqttParsePayload(payload);
813
819
  this.handleRPCResponse(topic, json);
@@ -1183,12 +1189,17 @@ var require_MqttSync = __commonJS({
1183
1189
  /* --------------------------------------------------------------------------
1184
1190
  * Remote Procedure Calls (RPC)
1185
1191
  */
1192
+ /** Given a (ground) topic find the matching RPC handler, if any. This is
1193
+ * needed because RPC topics can include wildcards. */
1194
+ getRPCHandler(topic) {
1195
+ return _3.find(this.rpcHandlers, (_handler, topicSelector) => topicMatch(topicSelector, topic));
1196
+ }
1186
1197
  /* Handle RPC requests */
1187
- async handleRPCRequest(topic, json) {
1188
- log2.debug("handling RPC request for", topic, json);
1189
- const handler = this.rpcHandlers[topic];
1190
- const result = handler(json.args);
1191
- const responseTopic = `${topic.replace("/request", "/response")}/${json.id}`;
1198
+ async handleRPCRequest(path, handler, json) {
1199
+ log2.debug("handling RPC request for", path, json);
1200
+ const commandTopic = pathToTopic2(path.slice(0, -1));
1201
+ const result = handler(json.args, commandTopic);
1202
+ const responseTopic = `${commandTopic}/response/${json.id}`;
1192
1203
  if (result instanceof Promise) {
1193
1204
  result.then((resultValue) => this.mqtt.publish(
1194
1205
  responseTopic,
@@ -1211,24 +1222,29 @@ var require_MqttSync = __commonJS({
1211
1222
  this.mqtt.unsubscribe(topic);
1212
1223
  }
1213
1224
  /** Register an RPC request handler. Example:
1214
- * ```js
1215
- * mqttSync.register('/mySquare', arg => {
1216
- * log.debug('running /mySquare with args', arg);
1217
- * return arg * arg;
1218
- * });
1219
- * ```
1220
- * Note that the command topic needs to be in the capabilities namespace like
1221
- * any other topic. In robot capabilities, as usual, these can start in `/`
1222
- * because the local mqtt bridge operated by the robot agent will place all
1223
- * topics in their respective namespace. In the cloud and on the web you will
1224
- * need to use the respective namespace, i.e.,
1225
- * `/orgId/deviceId/@scope/capName/capVersion/`.
1226
- *
1227
- * #### Async/Await
1228
- * Yes, you can make the handler `async` and use `await` inside of it. This
1229
- * will be handled correctly, i.e., MqttSync will await the result of the
1230
- * handler before responding to the RPC request client.
1231
- */
1225
+ * ```js
1226
+ * mqttSync.register('/mySquare', (arg, commandTopic) => {
1227
+ * log.debug('we got request on topic', commandTopic);
1228
+ * log.debug('running /mySquare with args', arg);
1229
+ * return arg * arg;
1230
+ * });
1231
+ * ```
1232
+ * Note that the command topic needs to be in the capabilities namespace like
1233
+ * any other topic. In robot capabilities, as usual, these can start in `/`
1234
+ * because the local mqtt bridge operated by the robot agent will place all
1235
+ * topics in their respective namespace. In the cloud and on the web you will
1236
+ * need to use the respective namespace, i.e.,
1237
+ * `/orgId/deviceId/@scope/capName/capVersion/`.
1238
+ *
1239
+ * You can use wildcards in the registered topic. The handler will receive the
1240
+ * actual, ground topic the request was made on as the second argument. This
1241
+ * allows you to make the RPCs behavior depend on the topic.
1242
+ *
1243
+ * #### Async/Await
1244
+ * Yes, you can make the handler `async` and use `await` inside of it. This
1245
+ * will be handled correctly, i.e., MqttSync will await the result of the
1246
+ * handler before responding to the RPC request client.
1247
+ */
1232
1248
  register(command, handler) {
1233
1249
  log2.debug("registering RPC handler for", command);
1234
1250
  const requestTopic = `${command}/request`;
@@ -1296,7 +1312,9 @@ var require_MqttSync = __commonJS({
1296
1312
  * service is running -- as it usually is inside the
1297
1313
  * transitiverobotics/clickhouse docker image). */
1298
1314
  requestHistoryStorage(topic, ttl = 1) {
1299
- const storageRequest = selectorToStorageRequest(topic);
1315
+ const path = selectorPathToMetaPath(topicToPath2(topic));
1316
+ path.splice(5, 0, "$store");
1317
+ const storageRequest = pathToTopic2(path);
1300
1318
  this.mqtt.publish(storageRequest, String(ttl), { retain: true });
1301
1319
  }
1302
1320
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transitive-sdk/utils-web",
3
- "version": "0.15.0",
3
+ "version": "0.16.1",
4
4
  "description": "Web utils for the Transitive framework",
5
5
  "homepage": "https://transitiverobotics.com",
6
6
  "repository": {