unetjs 3.0.0 → 3.1.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.
package/dist/cjs/unet.cjs CHANGED
@@ -1,8 +1,8 @@
1
- /* unet.js v3.0.0 2023-12-11T11:03:52.183Z */
1
+ /* unet.js v3.1.0 2024-01-26T11:16:07.040Z */
2
2
 
3
3
  'use strict';
4
4
 
5
- /* fjage.js v1.11.2 */
5
+ /* fjage.js v1.12.0 */
6
6
 
7
7
  const isBrowser =
8
8
  typeof window !== "undefined" && typeof window.document !== "undefined";
@@ -502,14 +502,17 @@ class AgentID {
502
502
  msg.index = Number.isInteger(index) ? index : -1;
503
503
  const rsp = await this.owner.request(msg, timeout);
504
504
  var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
505
- if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) return ret;
505
+ if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
506
+ if (this.owner._returnNullOnFailedResponse) return ret;
507
+ else throw new Error(`Unable to set ${this.name}.${params} to ${values}`);
508
+ }
506
509
  if (Array.isArray(params)) {
507
510
  if (!rsp.values) rsp.values = {};
508
511
  if (rsp.param) rsp.values[rsp.param] = rsp.value;
509
512
  const rvals = Object.keys(rsp.values);
510
513
  return params.map( p => {
511
514
  let f = rvals.find(rv => rv.endsWith(p));
512
- return f ? rsp.values[f] : null;
515
+ return f ? rsp.values[f] : undefined;
513
516
  });
514
517
  } else {
515
518
  return rsp.value;
@@ -540,7 +543,10 @@ class AgentID {
540
543
  msg.index = Number.isInteger(index) ? index : -1;
541
544
  const rsp = await this.owner.request(msg, timeout);
542
545
  var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
543
- if (!rsp || rsp.perf != Performative.INFORM || (params && (!rsp.param))) return ret;
546
+ if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
547
+ if (this.owner._returnNullOnFailedResponse) return ret;
548
+ else throw new Error(`Unable to get ${this.name}.${params}`);
549
+ }
544
550
  // Request for listing of all parameters.
545
551
  if (!params) {
546
552
  if (!rsp.values) rsp.values = {};
@@ -552,7 +558,7 @@ class AgentID {
552
558
  const rvals = Object.keys(rsp.values);
553
559
  return params.map(p => {
554
560
  let f = rvals.find(rv => rv.endsWith(p));
555
- return f ? rsp.values[f] : null;
561
+ return f ? rsp.values[f] : undefined;
556
562
  });
557
563
  } else {
558
564
  return rsp.value;
@@ -636,12 +642,17 @@ class Message {
636
642
  return null;
637
643
  }
638
644
  }
639
- let qclazz = obj.clazz;
640
- let clazz = qclazz.replace(/^.*\./, '');
641
- let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
642
- rv.__clazz__ = qclazz;
643
- rv._inflate(obj.data);
644
- return rv;
645
+ try {
646
+ let qclazz = obj.clazz;
647
+ let clazz = qclazz.replace(/^.*\./, '');
648
+ let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
649
+ rv.__clazz__ = qclazz;
650
+ rv._inflate(obj.data);
651
+ return rv;
652
+ } catch (err) {
653
+ console.warn('Error trying to deserialize JSON object : ', obj, err);
654
+ return null;
655
+ }
645
656
  }
646
657
  }
647
658
 
@@ -658,6 +669,7 @@ class Message {
658
669
  * @param {string} [opts.keepAlive=true] - try to reconnect if the connection is lost
659
670
  * @param {number} [opts.queueSize=128] - size of the queue of received messages that haven't been consumed yet
660
671
  * @param {number} [opts.timeout=1000] - timeout for fjage level messages in ms
672
+ * @param {boolean} [opts.returnNullOnFailedResponse=true] - return null instead of throwing an error when a parameter is not found
661
673
  * @param {string} [hostname="localhost"] - <strike>Deprecated : hostname/ip address of the master container to connect to</strike>
662
674
  * @param {number} [port=] - <strike>Deprecated : port number of the master container to connect to</strike>
663
675
  * @param {string} [pathname=="/ws/"] - <strike>Deprecated : path of the master container to connect to (for WebSockets)</strike>
@@ -686,6 +698,7 @@ class Gateway {
686
698
  this._timeout = opts.timeout; // timeout for fjage level messages (agentForService etc)
687
699
  this._keepAlive = opts.keepAlive; // reconnect if connection gets closed/errored
688
700
  this._queueSize = opts.queueSize; // size of queue
701
+ this._returnNullOnFailedResponse = opts.returnNullOnFailedResponse; // null or error
689
702
  this.pending = {}; // msgid to callback mapping for pending requests to server
690
703
  this.subscriptions = {}; // hashset for all topics that are subscribed
691
704
  this.listener = {}; // set of callbacks that want to listen to incoming messages
@@ -1036,6 +1049,30 @@ class Gateway {
1036
1049
  this._update_watch();
1037
1050
  }
1038
1051
 
1052
+ /**
1053
+ * Gets a list of all agents in the container.
1054
+ * @returns {Promise<AgentID[]>} - a promise which returns an array of all agent ids when resolved
1055
+ */
1056
+ async agents() {
1057
+ let rq = { action: 'agents' };
1058
+ let rsp = await this._msgTxRx(rq);
1059
+ if (!rsp || !Array.isArray(rsp.agentIDs)) throw new Error('Unable to get agents');
1060
+ return rsp.agentIDs.map(aid => new AgentID(aid, false, this));
1061
+ }
1062
+
1063
+ /**
1064
+ * Check if an agent with a given name exists in the container.
1065
+ *
1066
+ * @param {AgentID|String} agentID - the agent id to check
1067
+ * @returns {Promise<boolean>} - a promise which returns true if the agent exists when resolved
1068
+ */
1069
+ async containsAgent(agentID) {
1070
+ let rq = { action: 'containsAgent', agentID: agentID instanceof AgentID ? agentID.getName() : agentID };
1071
+ let rsp = await this._msgTxRx(rq);
1072
+ if (!rsp) throw new Error('Unable to check if agent exists');
1073
+ return !!rsp.answer;
1074
+ }
1075
+
1039
1076
  /**
1040
1077
  * Finds an agent that provides a named service. If multiple agents are registered
1041
1078
  * to provide a given service, any of the agents' id may be returned.
@@ -1046,7 +1083,11 @@ class Gateway {
1046
1083
  async agentForService(service) {
1047
1084
  let rq = { action: 'agentForService', service: service };
1048
1085
  let rsp = await this._msgTxRx(rq);
1049
- if (!rsp || !rsp.agentID) return;
1086
+ if (!rsp) {
1087
+ if (this._returnNullOnFailedResponse) return null;
1088
+ else throw new Error('Unable to get agent for service');
1089
+ }
1090
+ if (!rsp.agentID) return null;
1050
1091
  return new AgentID(rsp.agentID, false, this);
1051
1092
  }
1052
1093
 
@@ -1060,7 +1101,11 @@ class Gateway {
1060
1101
  let rq = { action: 'agentsForService', service: service };
1061
1102
  let rsp = await this._msgTxRx(rq);
1062
1103
  let aids = [];
1063
- if (!rsp || !Array.isArray(rsp.agentIDs)) return aids;
1104
+ if (!rsp) {
1105
+ if (this._returnNullOnFailedResponse) return aids;
1106
+ else throw new Error('Unable to get agents for service');
1107
+ }
1108
+ if (!Array.isArray(rsp.agentIDs)) return aids;
1064
1109
  for (var i = 0; i < rsp.agentIDs.length; i++)
1065
1110
  aids.push(new AgentID(rsp.agentIDs[i], false, this));
1066
1111
  return aids;
@@ -1279,7 +1324,8 @@ if (isBrowser || isWebWorker){
1279
1324
  'pathname' : '/ws/',
1280
1325
  'timeout': 1000,
1281
1326
  'keepAlive' : true,
1282
- 'queueSize': DEFAULT_QUEUE_SIZE
1327
+ 'queueSize': DEFAULT_QUEUE_SIZE,
1328
+ 'returnNullOnFailedResponse': true
1283
1329
  });
1284
1330
  DEFAULT_URL = new URL('ws://localhost');
1285
1331
  // Enable caching of Gateways
@@ -1293,7 +1339,8 @@ if (isBrowser || isWebWorker){
1293
1339
  'pathname': '',
1294
1340
  'timeout': 1000,
1295
1341
  'keepAlive' : true,
1296
- 'queueSize': DEFAULT_QUEUE_SIZE
1342
+ 'queueSize': DEFAULT_QUEUE_SIZE,
1343
+ 'returnNullOnFailedResponse': true
1297
1344
  });
1298
1345
  DEFAULT_URL = new URL('tcp://localhost');
1299
1346
  gObj.atob = a => Buffer.from(a, 'base64').toString('binary');
package/dist/esm/unet.js CHANGED
@@ -1,6 +1,6 @@
1
- /* unet.js v3.0.0 2023-12-11T11:03:52.183Z */
1
+ /* unet.js v3.1.0 2024-01-26T11:16:07.039Z */
2
2
 
3
- /* fjage.js v1.11.2 */
3
+ /* fjage.js v1.12.0 */
4
4
 
5
5
  const isBrowser =
6
6
  typeof window !== "undefined" && typeof window.document !== "undefined";
@@ -500,14 +500,17 @@ class AgentID {
500
500
  msg.index = Number.isInteger(index) ? index : -1;
501
501
  const rsp = await this.owner.request(msg, timeout);
502
502
  var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
503
- if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) return ret;
503
+ if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
504
+ if (this.owner._returnNullOnFailedResponse) return ret;
505
+ else throw new Error(`Unable to set ${this.name}.${params} to ${values}`);
506
+ }
504
507
  if (Array.isArray(params)) {
505
508
  if (!rsp.values) rsp.values = {};
506
509
  if (rsp.param) rsp.values[rsp.param] = rsp.value;
507
510
  const rvals = Object.keys(rsp.values);
508
511
  return params.map( p => {
509
512
  let f = rvals.find(rv => rv.endsWith(p));
510
- return f ? rsp.values[f] : null;
513
+ return f ? rsp.values[f] : undefined;
511
514
  });
512
515
  } else {
513
516
  return rsp.value;
@@ -538,7 +541,10 @@ class AgentID {
538
541
  msg.index = Number.isInteger(index) ? index : -1;
539
542
  const rsp = await this.owner.request(msg, timeout);
540
543
  var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
541
- if (!rsp || rsp.perf != Performative.INFORM || (params && (!rsp.param))) return ret;
544
+ if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
545
+ if (this.owner._returnNullOnFailedResponse) return ret;
546
+ else throw new Error(`Unable to get ${this.name}.${params}`);
547
+ }
542
548
  // Request for listing of all parameters.
543
549
  if (!params) {
544
550
  if (!rsp.values) rsp.values = {};
@@ -550,7 +556,7 @@ class AgentID {
550
556
  const rvals = Object.keys(rsp.values);
551
557
  return params.map(p => {
552
558
  let f = rvals.find(rv => rv.endsWith(p));
553
- return f ? rsp.values[f] : null;
559
+ return f ? rsp.values[f] : undefined;
554
560
  });
555
561
  } else {
556
562
  return rsp.value;
@@ -634,12 +640,17 @@ class Message {
634
640
  return null;
635
641
  }
636
642
  }
637
- let qclazz = obj.clazz;
638
- let clazz = qclazz.replace(/^.*\./, '');
639
- let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
640
- rv.__clazz__ = qclazz;
641
- rv._inflate(obj.data);
642
- return rv;
643
+ try {
644
+ let qclazz = obj.clazz;
645
+ let clazz = qclazz.replace(/^.*\./, '');
646
+ let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
647
+ rv.__clazz__ = qclazz;
648
+ rv._inflate(obj.data);
649
+ return rv;
650
+ } catch (err) {
651
+ console.warn('Error trying to deserialize JSON object : ', obj, err);
652
+ return null;
653
+ }
643
654
  }
644
655
  }
645
656
 
@@ -656,6 +667,7 @@ class Message {
656
667
  * @param {string} [opts.keepAlive=true] - try to reconnect if the connection is lost
657
668
  * @param {number} [opts.queueSize=128] - size of the queue of received messages that haven't been consumed yet
658
669
  * @param {number} [opts.timeout=1000] - timeout for fjage level messages in ms
670
+ * @param {boolean} [opts.returnNullOnFailedResponse=true] - return null instead of throwing an error when a parameter is not found
659
671
  * @param {string} [hostname="localhost"] - <strike>Deprecated : hostname/ip address of the master container to connect to</strike>
660
672
  * @param {number} [port=] - <strike>Deprecated : port number of the master container to connect to</strike>
661
673
  * @param {string} [pathname=="/ws/"] - <strike>Deprecated : path of the master container to connect to (for WebSockets)</strike>
@@ -684,6 +696,7 @@ class Gateway {
684
696
  this._timeout = opts.timeout; // timeout for fjage level messages (agentForService etc)
685
697
  this._keepAlive = opts.keepAlive; // reconnect if connection gets closed/errored
686
698
  this._queueSize = opts.queueSize; // size of queue
699
+ this._returnNullOnFailedResponse = opts.returnNullOnFailedResponse; // null or error
687
700
  this.pending = {}; // msgid to callback mapping for pending requests to server
688
701
  this.subscriptions = {}; // hashset for all topics that are subscribed
689
702
  this.listener = {}; // set of callbacks that want to listen to incoming messages
@@ -1034,6 +1047,30 @@ class Gateway {
1034
1047
  this._update_watch();
1035
1048
  }
1036
1049
 
1050
+ /**
1051
+ * Gets a list of all agents in the container.
1052
+ * @returns {Promise<AgentID[]>} - a promise which returns an array of all agent ids when resolved
1053
+ */
1054
+ async agents() {
1055
+ let rq = { action: 'agents' };
1056
+ let rsp = await this._msgTxRx(rq);
1057
+ if (!rsp || !Array.isArray(rsp.agentIDs)) throw new Error('Unable to get agents');
1058
+ return rsp.agentIDs.map(aid => new AgentID(aid, false, this));
1059
+ }
1060
+
1061
+ /**
1062
+ * Check if an agent with a given name exists in the container.
1063
+ *
1064
+ * @param {AgentID|String} agentID - the agent id to check
1065
+ * @returns {Promise<boolean>} - a promise which returns true if the agent exists when resolved
1066
+ */
1067
+ async containsAgent(agentID) {
1068
+ let rq = { action: 'containsAgent', agentID: agentID instanceof AgentID ? agentID.getName() : agentID };
1069
+ let rsp = await this._msgTxRx(rq);
1070
+ if (!rsp) throw new Error('Unable to check if agent exists');
1071
+ return !!rsp.answer;
1072
+ }
1073
+
1037
1074
  /**
1038
1075
  * Finds an agent that provides a named service. If multiple agents are registered
1039
1076
  * to provide a given service, any of the agents' id may be returned.
@@ -1044,7 +1081,11 @@ class Gateway {
1044
1081
  async agentForService(service) {
1045
1082
  let rq = { action: 'agentForService', service: service };
1046
1083
  let rsp = await this._msgTxRx(rq);
1047
- if (!rsp || !rsp.agentID) return;
1084
+ if (!rsp) {
1085
+ if (this._returnNullOnFailedResponse) return null;
1086
+ else throw new Error('Unable to get agent for service');
1087
+ }
1088
+ if (!rsp.agentID) return null;
1048
1089
  return new AgentID(rsp.agentID, false, this);
1049
1090
  }
1050
1091
 
@@ -1058,7 +1099,11 @@ class Gateway {
1058
1099
  let rq = { action: 'agentsForService', service: service };
1059
1100
  let rsp = await this._msgTxRx(rq);
1060
1101
  let aids = [];
1061
- if (!rsp || !Array.isArray(rsp.agentIDs)) return aids;
1102
+ if (!rsp) {
1103
+ if (this._returnNullOnFailedResponse) return aids;
1104
+ else throw new Error('Unable to get agents for service');
1105
+ }
1106
+ if (!Array.isArray(rsp.agentIDs)) return aids;
1062
1107
  for (var i = 0; i < rsp.agentIDs.length; i++)
1063
1108
  aids.push(new AgentID(rsp.agentIDs[i], false, this));
1064
1109
  return aids;
@@ -1277,7 +1322,8 @@ if (isBrowser || isWebWorker){
1277
1322
  'pathname' : '/ws/',
1278
1323
  'timeout': 1000,
1279
1324
  'keepAlive' : true,
1280
- 'queueSize': DEFAULT_QUEUE_SIZE
1325
+ 'queueSize': DEFAULT_QUEUE_SIZE,
1326
+ 'returnNullOnFailedResponse': true
1281
1327
  });
1282
1328
  DEFAULT_URL = new URL('ws://localhost');
1283
1329
  // Enable caching of Gateways
@@ -1291,7 +1337,8 @@ if (isBrowser || isWebWorker){
1291
1337
  'pathname': '',
1292
1338
  'timeout': 1000,
1293
1339
  'keepAlive' : true,
1294
- 'queueSize': DEFAULT_QUEUE_SIZE
1340
+ 'queueSize': DEFAULT_QUEUE_SIZE,
1341
+ 'returnNullOnFailedResponse': true
1295
1342
  });
1296
1343
  DEFAULT_URL = new URL('tcp://localhost');
1297
1344
  gObj.atob = a => Buffer.from(a, 'base64').toString('binary');
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.0 */
8
8
 
9
9
  const isBrowser =
10
10
  typeof window !== "undefined" && typeof window.document !== "undefined";
@@ -504,14 +504,17 @@
504
504
  msg.index = Number.isInteger(index) ? index : -1;
505
505
  const rsp = await this.owner.request(msg, timeout);
506
506
  var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
507
- if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) return ret;
507
+ if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
508
+ if (this.owner._returnNullOnFailedResponse) return ret;
509
+ else throw new Error(`Unable to set ${this.name}.${params} to ${values}`);
510
+ }
508
511
  if (Array.isArray(params)) {
509
512
  if (!rsp.values) rsp.values = {};
510
513
  if (rsp.param) rsp.values[rsp.param] = rsp.value;
511
514
  const rvals = Object.keys(rsp.values);
512
515
  return params.map( p => {
513
516
  let f = rvals.find(rv => rv.endsWith(p));
514
- return f ? rsp.values[f] : null;
517
+ return f ? rsp.values[f] : undefined;
515
518
  });
516
519
  } else {
517
520
  return rsp.value;
@@ -542,7 +545,10 @@
542
545
  msg.index = Number.isInteger(index) ? index : -1;
543
546
  const rsp = await this.owner.request(msg, timeout);
544
547
  var ret = Array.isArray(params) ? new Array(params.length).fill(null) : null;
545
- if (!rsp || rsp.perf != Performative.INFORM || (params && (!rsp.param))) return ret;
548
+ if (!rsp || rsp.perf != Performative.INFORM || !rsp.param) {
549
+ if (this.owner._returnNullOnFailedResponse) return ret;
550
+ else throw new Error(`Unable to get ${this.name}.${params}`);
551
+ }
546
552
  // Request for listing of all parameters.
547
553
  if (!params) {
548
554
  if (!rsp.values) rsp.values = {};
@@ -554,7 +560,7 @@
554
560
  const rvals = Object.keys(rsp.values);
555
561
  return params.map(p => {
556
562
  let f = rvals.find(rv => rv.endsWith(p));
557
- return f ? rsp.values[f] : null;
563
+ return f ? rsp.values[f] : undefined;
558
564
  });
559
565
  } else {
560
566
  return rsp.value;
@@ -638,12 +644,17 @@
638
644
  return null;
639
645
  }
640
646
  }
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;
647
+ try {
648
+ let qclazz = obj.clazz;
649
+ let clazz = qclazz.replace(/^.*\./, '');
650
+ let rv = MessageClass[clazz] ? new MessageClass[clazz] : new Message();
651
+ rv.__clazz__ = qclazz;
652
+ rv._inflate(obj.data);
653
+ return rv;
654
+ } catch (err) {
655
+ console.warn('Error trying to deserialize JSON object : ', obj, err);
656
+ return null;
657
+ }
647
658
  }
648
659
  }
649
660
 
@@ -660,6 +671,7 @@
660
671
  * @param {string} [opts.keepAlive=true] - try to reconnect if the connection is lost
661
672
  * @param {number} [opts.queueSize=128] - size of the queue of received messages that haven't been consumed yet
662
673
  * @param {number} [opts.timeout=1000] - timeout for fjage level messages in ms
674
+ * @param {boolean} [opts.returnNullOnFailedResponse=true] - return null instead of throwing an error when a parameter is not found
663
675
  * @param {string} [hostname="localhost"] - <strike>Deprecated : hostname/ip address of the master container to connect to</strike>
664
676
  * @param {number} [port=] - <strike>Deprecated : port number of the master container to connect to</strike>
665
677
  * @param {string} [pathname=="/ws/"] - <strike>Deprecated : path of the master container to connect to (for WebSockets)</strike>
@@ -688,6 +700,7 @@
688
700
  this._timeout = opts.timeout; // timeout for fjage level messages (agentForService etc)
689
701
  this._keepAlive = opts.keepAlive; // reconnect if connection gets closed/errored
690
702
  this._queueSize = opts.queueSize; // size of queue
703
+ this._returnNullOnFailedResponse = opts.returnNullOnFailedResponse; // null or error
691
704
  this.pending = {}; // msgid to callback mapping for pending requests to server
692
705
  this.subscriptions = {}; // hashset for all topics that are subscribed
693
706
  this.listener = {}; // set of callbacks that want to listen to incoming messages
@@ -1038,6 +1051,30 @@
1038
1051
  this._update_watch();
1039
1052
  }
1040
1053
 
1054
+ /**
1055
+ * Gets a list of all agents in the container.
1056
+ * @returns {Promise<AgentID[]>} - a promise which returns an array of all agent ids when resolved
1057
+ */
1058
+ async agents() {
1059
+ let rq = { action: 'agents' };
1060
+ let rsp = await this._msgTxRx(rq);
1061
+ if (!rsp || !Array.isArray(rsp.agentIDs)) throw new Error('Unable to get agents');
1062
+ return rsp.agentIDs.map(aid => new AgentID(aid, false, this));
1063
+ }
1064
+
1065
+ /**
1066
+ * Check if an agent with a given name exists in the container.
1067
+ *
1068
+ * @param {AgentID|String} agentID - the agent id to check
1069
+ * @returns {Promise<boolean>} - a promise which returns true if the agent exists when resolved
1070
+ */
1071
+ async containsAgent(agentID) {
1072
+ let rq = { action: 'containsAgent', agentID: agentID instanceof AgentID ? agentID.getName() : agentID };
1073
+ let rsp = await this._msgTxRx(rq);
1074
+ if (!rsp) throw new Error('Unable to check if agent exists');
1075
+ return !!rsp.answer;
1076
+ }
1077
+
1041
1078
  /**
1042
1079
  * Finds an agent that provides a named service. If multiple agents are registered
1043
1080
  * to provide a given service, any of the agents' id may be returned.
@@ -1048,7 +1085,11 @@
1048
1085
  async agentForService(service) {
1049
1086
  let rq = { action: 'agentForService', service: service };
1050
1087
  let rsp = await this._msgTxRx(rq);
1051
- if (!rsp || !rsp.agentID) return;
1088
+ if (!rsp) {
1089
+ if (this._returnNullOnFailedResponse) return null;
1090
+ else throw new Error('Unable to get agent for service');
1091
+ }
1092
+ if (!rsp.agentID) return null;
1052
1093
  return new AgentID(rsp.agentID, false, this);
1053
1094
  }
1054
1095
 
@@ -1062,7 +1103,11 @@
1062
1103
  let rq = { action: 'agentsForService', service: service };
1063
1104
  let rsp = await this._msgTxRx(rq);
1064
1105
  let aids = [];
1065
- if (!rsp || !Array.isArray(rsp.agentIDs)) return aids;
1106
+ if (!rsp) {
1107
+ if (this._returnNullOnFailedResponse) return aids;
1108
+ else throw new Error('Unable to get agents for service');
1109
+ }
1110
+ if (!Array.isArray(rsp.agentIDs)) return aids;
1066
1111
  for (var i = 0; i < rsp.agentIDs.length; i++)
1067
1112
  aids.push(new AgentID(rsp.agentIDs[i], false, this));
1068
1113
  return aids;
@@ -1281,7 +1326,8 @@
1281
1326
  'pathname' : '/ws/',
1282
1327
  'timeout': 1000,
1283
1328
  'keepAlive' : true,
1284
- 'queueSize': DEFAULT_QUEUE_SIZE
1329
+ 'queueSize': DEFAULT_QUEUE_SIZE,
1330
+ 'returnNullOnFailedResponse': true
1285
1331
  });
1286
1332
  DEFAULT_URL = new URL('ws://localhost');
1287
1333
  // Enable caching of Gateways
@@ -1295,7 +1341,8 @@
1295
1341
  'pathname': '',
1296
1342
  'timeout': 1000,
1297
1343
  'keepAlive' : true,
1298
- 'queueSize': DEFAULT_QUEUE_SIZE
1344
+ 'queueSize': DEFAULT_QUEUE_SIZE,
1345
+ 'returnNullOnFailedResponse': true
1299
1346
  });
1300
1347
  DEFAULT_URL = new URL('tcp://localhost');
1301
1348
  gObj.atob = a => Buffer.from(a, 'base64').toString('binary');