unetjs 3.0.0 → 3.1.2

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/dist/unetjs.js CHANGED
@@ -4,7 +4,7 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.unet = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- /* fjage.js v1.11.2 */
7
+ /* fjage.js v1.12.1 */
8
8
 
9
9
  const isBrowser =
10
10
  typeof window !== "undefined" && typeof window.document !== "undefined";
@@ -48,21 +48,20 @@
48
48
  /**
49
49
  * Create an TCPConnector to connect to a fjage master over TCP
50
50
  * @param {Object} opts
51
- * @param {string} [opts.hostname='localhost'] - hostname/ip address of the master container to connect to
52
- * @param {number} opts.port - port number of the master container to connect to
53
- * @param {string} opts.pathname - path of the master container to connect to
51
+ * @param {string} opts.hostname - hostname/ip address of the master container to connect to
52
+ * @param {string} opts.port - port number of the master container to connect to
54
53
  * @param {boolean} opts.keepAlive - try to reconnect if the connection is lost
55
54
  * @param {number} [opts.reconnectTime=5000] - time before reconnection is attempted after an error
56
55
  */
57
56
  constructor(opts = {}) {
57
+ let host = opts.hostname;
58
+ let port = opts.port;
59
+ this._keepAlive = opts.keepAlive;
60
+ this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME$1;
58
61
  this.url = new URL('tcp://localhost');
59
- let host = opts.hostname || 'localhost';
60
- let port = opts.port || -1;
61
62
  this.url.hostname = host;
62
63
  this.url.port = port;
63
64
  this._buf = '';
64
- this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME$1;
65
- this._keepAlive = opts.keepAlive || true;
66
65
  this._firstConn = true; // if the Gateway has managed to connect to a server before
67
66
  this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
68
67
  this.pendingOnOpen = []; // list of callbacks make as soon as gateway is open
@@ -234,7 +233,7 @@
234
233
  * Create an WSConnector to connect to a fjage master over WebSockets
235
234
  * @param {Object} opts
236
235
  * @param {string} opts.hostname - hostname/ip address of the master container to connect to
237
- * @param {number} opts.port - port number of the master container to connect to
236
+ * @param {string} opts.port - port number of the master container to connect to
238
237
  * @param {string} opts.pathname - path of the master container to connect to
239
238
  * @param {boolean} opts.keepAlive - try to reconnect if the connection is lost
240
239
  * @param {number} [opts.reconnectTime=5000] - time before reconnection is attempted after an error
@@ -244,8 +243,8 @@
244
243
  this.url.hostname = opts.hostname;
245
244
  this.url.port = opts.port;
246
245
  this.url.pathname = opts.pathname;
246
+ this._keepAlive = opts.keepAlive;
247
247
  this._reconnectTime = opts.reconnectTime || DEFAULT_RECONNECT_TIME;
248
- this._keepAlive = opts.keepAlive || true;
249
248
  this.debug = opts.debug || false; // debug info to be logged to console?
250
249
  this._firstConn = true; // if the Gateway has managed to connect to a server before
251
250
  this._firstReConn = true; // if the Gateway has attempted to reconnect to a server before
@@ -504,14 +503,17 @@
504
503
  msg.index = Number.isInteger(index) ? index : -1;
505
504
  const rsp = await this.owner.request(msg, timeout);
506
505
  var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
507
- if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) return ret;
506
+ if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
507
+ if (this.owner._returnNullOnFailedResponse) return ret;
508
+ else throw new Error(`Unable to set ${this.name}.${params} to ${values}`);
509
+ }
508
510
  if (Array.isArray(params)) {
509
511
  if (!rsp.values) rsp.values = {};
510
512
  if (rsp.param) rsp.values[rsp.param] = rsp.value;
511
513
  const rvals = Object.keys(rsp.values);
512
514
  return params.map( p => {
513
515
  let f = rvals.find(rv => rv.endsWith(p));
514
- return f ? rsp.values[f] : null;
516
+ return f ? rsp.values[f] : undefined;
515
517
  });
516
518
  } else {
517
519
  return rsp.value;
@@ -542,7 +544,10 @@
542
544
  msg.index = Number.isInteger(index) ? index : -1;
543
545
  const rsp = await this.owner.request(msg, timeout);
544
546
  var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
545
- if (!rsp || rsp.perf != Performative.INFORM || (params && (!rsp.param))) return ret;
547
+ if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
548
+ if (this.owner._returnNullOnFailedResponse) return ret;
549
+ else throw new Error(`Unable to get ${this.name}.${params}`);
550
+ }
546
551
  // Request for listing of all parameters.
547
552
  if (!params) {
548
553
  if (!rsp.values) rsp.values = {};
@@ -554,7 +559,7 @@
554
559
  const rvals = Object.keys(rsp.values);
555
560
  return params.map(p => {
556
561
  let f = rvals.find(rv => rv.endsWith(p));
557
- return f ? rsp.values[f] : null;
562
+ return f ? rsp.values[f] : undefined;
558
563
  });
559
564
  } else {
560
565
  return rsp.value;
@@ -638,12 +643,17 @@
638
643
  return null;
639
644
  }
640
645
  }
641
- let qclazz = obj.clazz;
642
- let clazz = qclazz.replace(/^.*\./, '');
643
- let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
644
- rv.__clazz__ = qclazz;
645
- rv._inflate(obj.data);
646
- return rv;
646
+ try {
647
+ let qclazz = obj.clazz;
648
+ let clazz = qclazz.replace(/^.*\./, '');
649
+ let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
650
+ rv.__clazz__ = qclazz;
651
+ rv._inflate(obj.data);
652
+ return rv;
653
+ } catch (err) {
654
+ console.warn('Error trying to deserialize JSON object : ', obj, err);
655
+ return null;
656
+ }
647
657
  }
648
658
  }
649
659
 
@@ -654,16 +664,17 @@
654
664
  *
655
665
  * @class
656
666
  * @param {Object} opts
657
- * @param {string} [opts.hostname="localhost"] - hostname/ip address of the master container to connect to
658
- * @param {number} [opts.port=1100] - port number of the master container to connect to
659
- * @param {string} [opts.pathname=""] - path of the master container to connect to (for WebSockets)
660
- * @param {string} [opts.keepAlive=true] - try to reconnect if the connection is lost
661
- * @param {number} [opts.queueSize=128] - size of the queue of received messages that haven't been consumed yet
662
- * @param {number} [opts.timeout=1000] - timeout for fjage level messages in ms
663
- * @param {string} [hostname="localhost"] - <strike>Deprecated : hostname/ip address of the master container to connect to</strike>
664
- * @param {number} [port=] - <strike>Deprecated : port number of the master container to connect to</strike>
665
- * @param {string} [pathname=="/ws/"] - <strike>Deprecated : path of the master container to connect to (for WebSockets)</strike>
666
- * @param {number} [timeout=1000] - <strike>Deprecated : timeout for fjage level messages in ms</strike>
667
+ * @param {string} [opts.hostname="localhost"] - hostname/ip address of the master container to connect to
668
+ * @param {string} [opts.port='1100'] - port number of the master container to connect to
669
+ * @param {string} [opts.pathname=""] - path of the master container to connect to (for WebSockets)
670
+ * @param {boolean} [opts.keepAlive=true] - try to reconnect if the connection is lost
671
+ * @param {number} [opts.queueSize=128] - size of the queue of received messages that haven't been consumed yet
672
+ * @param {number} [opts.timeout=1000] - timeout for fjage level messages in ms
673
+ * @param {boolean} [opts.returnNullOnFailedResponse=true] - return null instead of throwing an error when a parameter is not found
674
+ * @param {string} [hostname="localhost"] - <strike>Deprecated : hostname/ip address of the master container to connect to</strike>
675
+ * @param {number} [port=] - <strike>Deprecated : port number of the master container to connect to</strike>
676
+ * @param {string} [pathname=="/ws/"] - <strike>Deprecated : path of the master container to connect to (for WebSockets)</strike>
677
+ * @param {number} [timeout=1000] - <strike>Deprecated : timeout for fjage level messages in ms</strike>
667
678
  */
668
679
  class Gateway {
669
680
 
@@ -672,13 +683,17 @@
672
683
  if (typeof opts === 'string' || opts instanceof String){
673
684
  opts = {
674
685
  'hostname': opts,
675
- 'port' : port || gObj.location.port,
686
+ 'port' : port,
676
687
  'pathname' : pathname,
677
688
  'timeout' : timeout
678
689
  };
679
690
  console.warn('Deprecated use of Gateway constructor');
680
691
  }
681
- opts = Object.assign({}, GATEWAY_DEFAULTS, opts);
692
+
693
+ // Set defaults
694
+ for (var key in GATEWAY_DEFAULTS){
695
+ if (opts[key] == undefined || opts[key] === '') opts[key] = GATEWAY_DEFAULTS[key];
696
+ }
682
697
  var url = DEFAULT_URL;
683
698
  url.hostname = opts.hostname;
684
699
  url.port = opts.port;
@@ -687,7 +702,8 @@
687
702
  if (existing) return existing;
688
703
  this._timeout = opts.timeout; // timeout for fjage level messages (agentForService etc)
689
704
  this._keepAlive = opts.keepAlive; // reconnect if connection gets closed/errored
690
- this._queueSize = opts.queueSize; // size of queue
705
+ this._queueSize = opts.queueSize; // size of queue
706
+ this._returnNullOnFailedResponse = opts.returnNullOnFailedResponse; // null or error
691
707
  this.pending = {}; // msgid to callback mapping for pending requests to server
692
708
  this.subscriptions = {}; // hashset for all topics that are subscribed
693
709
  this.listener = {}; // set of callbacks that want to listen to incoming messages
@@ -1038,6 +1054,30 @@
1038
1054
  this._update_watch();
1039
1055
  }
1040
1056
 
1057
+ /**
1058
+ * Gets a list of all agents in the container.
1059
+ * @returns {Promise<AgentID[]>} - a promise which returns an array of all agent ids when resolved
1060
+ */
1061
+ async agents() {
1062
+ let rq = { action: 'agents' };
1063
+ let rsp = await this._msgTxRx(rq);
1064
+ if (!rsp || !Array.isArray(rsp.agentIDs)) throw new Error('Unable to get agents');
1065
+ return rsp.agentIDs.map(aid => new AgentID(aid, false, this));
1066
+ }
1067
+
1068
+ /**
1069
+ * Check if an agent with a given name exists in the container.
1070
+ *
1071
+ * @param {AgentID|String} agentID - the agent id to check
1072
+ * @returns {Promise<boolean>} - a promise which returns true if the agent exists when resolved
1073
+ */
1074
+ async containsAgent(agentID) {
1075
+ let rq = { action: 'containsAgent', agentID: agentID instanceof AgentID ? agentID.getName() : agentID };
1076
+ let rsp = await this._msgTxRx(rq);
1077
+ if (!rsp) throw new Error('Unable to check if agent exists');
1078
+ return !!rsp.answer;
1079
+ }
1080
+
1041
1081
  /**
1042
1082
  * Finds an agent that provides a named service. If multiple agents are registered
1043
1083
  * to provide a given service, any of the agents' id may be returned.
@@ -1048,7 +1088,11 @@
1048
1088
  async agentForService(service) {
1049
1089
  let rq = { action: 'agentForService', service: service };
1050
1090
  let rsp = await this._msgTxRx(rq);
1051
- if (!rsp || !rsp.agentID) return;
1091
+ if (!rsp) {
1092
+ if (this._returnNullOnFailedResponse) return null;
1093
+ else throw new Error('Unable to get agent for service');
1094
+ }
1095
+ if (!rsp.agentID) return null;
1052
1096
  return new AgentID(rsp.agentID, false, this);
1053
1097
  }
1054
1098
 
@@ -1062,7 +1106,11 @@
1062
1106
  let rq = { action: 'agentsForService', service: service };
1063
1107
  let rsp = await this._msgTxRx(rq);
1064
1108
  let aids = [];
1065
- if (!rsp || !Array.isArray(rsp.agentIDs)) return aids;
1109
+ if (!rsp) {
1110
+ if (this._returnNullOnFailedResponse) return aids;
1111
+ else throw new Error('Unable to get agents for service');
1112
+ }
1113
+ if (!Array.isArray(rsp.agentIDs)) return aids;
1066
1114
  for (var i = 0; i < rsp.agentIDs.length; i++)
1067
1115
  aids.push(new AgentID(rsp.agentIDs[i], false, this));
1068
1116
  return aids;
@@ -1281,7 +1329,8 @@
1281
1329
  'pathname' : '/ws/',
1282
1330
  'timeout': 1000,
1283
1331
  'keepAlive' : true,
1284
- 'queueSize': DEFAULT_QUEUE_SIZE
1332
+ 'queueSize': DEFAULT_QUEUE_SIZE,
1333
+ 'returnNullOnFailedResponse': true
1285
1334
  });
1286
1335
  DEFAULT_URL = new URL('ws://localhost');
1287
1336
  // Enable caching of Gateways
@@ -1295,7 +1344,8 @@
1295
1344
  'pathname': '',
1296
1345
  'timeout': 1000,
1297
1346
  'keepAlive' : true,
1298
- 'queueSize': DEFAULT_QUEUE_SIZE
1347
+ 'queueSize': DEFAULT_QUEUE_SIZE,
1348
+ 'returnNullOnFailedResponse': true
1299
1349
  });
1300
1350
  DEFAULT_URL = new URL('tcp://localhost');
1301
1351
  gObj.atob = a => Buffer.from(a, 'base64').toString('binary');
@@ -1730,7 +1780,7 @@
1730
1780
  *
1731
1781
  * @class UnetSocket
1732
1782
  * @param {string} [hostname] - hostname/ip address of the master container to connect to
1733
- * @param {number} [port] - port number of the master container to connect to
1783
+ * @param {string} [port] - port number of the master container to connect to
1734
1784
  * @param {string} [path=''] - path of the master container to connect to (for WebSockets)
1735
1785
  * @returns {Promise<UnetSocket>} - Promise which resolves to the UnetSocket object being constructed
1736
1786
  *