unetjs 1.1.0 → 2.0.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/esm/unet.js CHANGED
@@ -1,4 +1,4 @@
1
- /* unet.js v1.1.0 2022-02-19T07:01:46.580Z */
1
+ /* unet.js v2.0.2 2022-06-10T03:18:03.319Z */
2
2
 
3
3
  /* fjage.js v1.9.1-rc6 */
4
4
 
@@ -1395,6 +1395,268 @@ let UnetMessages = {
1395
1395
  'SaveStateReq' : MessageClass('org.arl.unet.state.SaveStateReq')
1396
1396
  };
1397
1397
 
1398
+ /**
1399
+ * Convert coordinates from a local coordinates to GPS coordinate
1400
+ * @param {Array} origin - Local coordinate system's origin as `[latitude, longitude]`
1401
+ * @param {Number} x - X coordinate of the local coordinate to be converted
1402
+ * @param {Number} y - Y coordinate of the local coordinate to be converted
1403
+ * @returns {Array} - GPS coordinates (in decimal degrees) as `[latitude, longitude]`
1404
+ */
1405
+
1406
+ function toGps(origin, x, y) {
1407
+ let coords = [] ;
1408
+ let [xScale,yScale] = _initConv(origin[0]);
1409
+ coords[1] = x/xScale + origin[1];
1410
+ coords[0] = y/yScale + origin[0];
1411
+ return coords;
1412
+ }
1413
+
1414
+ /**
1415
+ * Convert coordinates from a GPS coordinates to local coordinate
1416
+ * @param {Array} origin - Local coordinate system's origin as `[latitude, longitude]`
1417
+ * @param {Number} lat - Latitude of the GPS coordinate to be converted
1418
+ * @param {Number} lon - Longitude of the GPS coordinate to be converted
1419
+ * @returns {Array} - GPS coordinates (in decimal degrees) as `[latitude, longitude]`
1420
+ */
1421
+ function toLocal(origin, lat, lon) {
1422
+ let pos = [];
1423
+ let [xScale,yScale] = _initConv(origin[0]);
1424
+ pos[0] = (lon-origin[1]) * xScale;
1425
+ pos[1] = (lat-origin[0]) * yScale;
1426
+ return pos;
1427
+ }
1428
+
1429
+ function _initConv(lat){
1430
+ let rlat = lat * Math.PI/180;
1431
+ let yScale = 111132.92 - 559.82*Math.cos(2*rlat) + 1.175*Math.cos(4*rlat) - 0.0023*Math.cos(6*rlat);
1432
+ let xScale = 111412.84*Math.cos(rlat) - 93.5*Math.cos(3*rlat) + 0.118*Math.cos(5*rlat);
1433
+ return [xScale, yScale];
1434
+ }
1435
+
1436
+ /**
1437
+ * A message which requests the transmission of the datagram from the Unet
1438
+ *
1439
+ * @typedef {Message} DatagramReq
1440
+ * @property {number[]} data - data as an Array of bytes
1441
+ * @property {number} from - from/source node address
1442
+ * @property {number} to - to/destination node address
1443
+ * @property {number} protocol - protocol number to be used to send this Datagram
1444
+ * @property {boolean} reliability - true if Datagram should be reliable, false if unreliable
1445
+ * @property {number} ttl - time-to-live for the datagram. Time-to-live is advisory, and an agent may choose it ignore it
1446
+ */
1447
+
1448
+ /**
1449
+ * Notification of received datagram message received by the Unet node.
1450
+ *
1451
+ * @typedef {Message} DatagramNtf
1452
+ * @property {number[]} data - data as an Array of bytes
1453
+ * @property {number} from - from/source node address
1454
+ * @property {number} to - to/destination node address
1455
+ * @property {number} protocol - protocol number to be used to send this Datagram
1456
+ * @property {number} ttl - time-to-live for the datagram. Time-to-live is advisory, and an agent may choose it ignore it
1457
+ */
1458
+
1459
+ /**
1460
+ * An identifier for an agent or a topic.
1461
+ * @external AgentID
1462
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1463
+ */
1464
+
1465
+ /**
1466
+ * Services supported by fjage agents.
1467
+ * @external Services
1468
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1469
+ */
1470
+
1471
+ /**
1472
+ * An action represented by a message.
1473
+ * @external Performative
1474
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1475
+ */
1476
+
1477
+ /**
1478
+ * Function to creates a unqualified message class based on a fully qualified name.
1479
+ * @external MessageClass
1480
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1481
+ */
1482
+
1483
+ /**
1484
+ * A caching CachingAgentID which caches Agent parameters locally.
1485
+ *
1486
+ * @class
1487
+ * @extends AgentID
1488
+ * @param {string | AgentID} name - name of the agent or an AgentID to copy
1489
+ * @param {boolean} topic - name of topic
1490
+ * @param {Gateway} owner - Gateway owner for this AgentID
1491
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1492
+ *
1493
+ */
1494
+ class CachingAgentID extends AgentID {
1495
+
1496
+ constructor(name, topic, owner, greedy=true) {
1497
+ if (name instanceof AgentID) {
1498
+ super(name.getName(), name.topic, name.owner);
1499
+ } else {
1500
+ super(name, topic, owner);
1501
+ }
1502
+ this.greedy = greedy;
1503
+ this.cache = {};
1504
+ }
1505
+
1506
+ /**
1507
+ * Sets parameter(s) on the Agent referred to by this AgentID, and caches the parameter(s).
1508
+ *
1509
+ * @param {(string|string[])} params - parameters name(s) to be set
1510
+ * @param {(Object|Object[])} values - parameters value(s) to be set
1511
+ * @param {number} [index=-1] - index of parameter(s) to be set
1512
+ * @param {number} [timeout=5000] - timeout for the response
1513
+ * @returns {Promise<(Object|Object[])>} - a promise which returns the new value(s) of the parameters
1514
+ */
1515
+ async set(params, values, index=-1, timeout=5000) {
1516
+ let s = await super.set(params, values, index, timeout);
1517
+ this._updateCache(params, s, index);
1518
+ }
1519
+
1520
+ /**
1521
+ * Gets parameter(s) on the Agent referred to by this AgentID, getting them from the cache if possible.
1522
+ *
1523
+ * @param {(string|string[])} params - parameters name(s) to be fetched
1524
+ * @param {number} [index=-1] - index of parameter(s) to be fetched
1525
+ * @param {number} [timeout=5000] - timeout for the response
1526
+ * @param {number} [maxage=5000] - maximum age of the cached result to retreive
1527
+ * @returns {Promise<(Object|Object[])>} - a promise which returns the value(s) of the parameters
1528
+ */
1529
+ async get(params, index=-1, timeout=5000, maxage=5000) {
1530
+ if (this._isCached(params, index, maxage)) return this._getCache(params, index);
1531
+ if (this.greedy && !(Array.isArray(params) && params.includes('name')) && params != 'name') {
1532
+ let rsp = await super.get(null, index, timeout);
1533
+ this._updateCache(null, rsp, index);
1534
+ if (Array.isArray(params)) {
1535
+ return params.map(p => {
1536
+ let f = Object.keys(rsp).find(rv => this._toNamed(rv) === p);
1537
+ return f ? rsp[f] : null;
1538
+ });
1539
+ } else {
1540
+ let f = Object.keys(rsp).find(rv => this._toNamed(rv) === params);
1541
+ return f ? rsp[f] : null;
1542
+ }
1543
+ } else {
1544
+ let r = await super.get(params, index, timeout);
1545
+ this._updateCache(params, r, index);
1546
+ return r;
1547
+ }
1548
+ }
1549
+
1550
+ _updateCache(params, vals, index) {
1551
+ if (vals == null || Array.isArray(vals) && vals.every(v => v == null)) return;
1552
+ if (params == null) {
1553
+ params = Object.keys(vals);
1554
+ vals = Object.values(vals);
1555
+ } else if (!Array.isArray(params)) params = [params];
1556
+ if (!Array.isArray(vals)) vals = [vals];
1557
+ params = params.map(this._toNamed);
1558
+ if (this.cache[index.toString()] === undefined) this.cache[index.toString()] = {};
1559
+ let c = this.cache[index.toString()];
1560
+ for (let i = 0; i < params.length; i++) {
1561
+ if (c[params[i]] === undefined) c[params[i]] = {};
1562
+ c[params[i]].value = vals[i];
1563
+ c[params[i]].ctime = Date.now();
1564
+ }
1565
+ }
1566
+
1567
+ _isCached(params, index, maxage) {
1568
+ if (maxage <= 0) return false;
1569
+ if (params == null) return false;
1570
+ let c = this.cache[index.toString()];
1571
+ if (!c) {
1572
+ return false;
1573
+ }
1574
+ if (!Array.isArray(params)) params = [params];
1575
+ const rv = params.every(p => {
1576
+ p = this._toNamed(p);
1577
+ return (p in c) && (Date.now() - c[p].ctime <= maxage);
1578
+ });
1579
+ return rv;
1580
+ }
1581
+
1582
+ _getCache(params, index) {
1583
+ let c = this.cache[index.toString()];
1584
+ if (!c) return null;
1585
+ if (!Array.isArray(params)){
1586
+ if (params in c) return c[params].value;
1587
+ return null;
1588
+ }else {
1589
+ return params.map(p => p in c ? c[p].value : null);
1590
+ }
1591
+ }
1592
+
1593
+ _toNamed(param) {
1594
+ const idx = param.lastIndexOf('.');
1595
+ if (idx < 0) return param;
1596
+ else return param.slice(idx+1);
1597
+ }
1598
+
1599
+ }
1600
+
1601
+
1602
+ class CachingGateway extends Gateway{
1603
+
1604
+ /**
1605
+ * Get an AgentID for a given agent name.
1606
+ *
1607
+ * @param {string} name - name of agent
1608
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1609
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1610
+ * @returns {AgentID|CachingAgentID} - AgentID for the given name
1611
+ */
1612
+ agent(name, caching=true, greedy=true) {
1613
+ const aid = super.agent(name);
1614
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1615
+ }
1616
+
1617
+ /**
1618
+ * Returns an object representing the named topic.
1619
+ *
1620
+ * @param {string|AgentID} topic - name of the topic or AgentID
1621
+ * @param {string} topic2 - name of the topic if the topic param is an AgentID
1622
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1623
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1624
+ * @returns {AgentID|CachingAgentID} - object representing the topic
1625
+ */
1626
+ topic(topic, topic2, caching=true, greedy=true) {
1627
+ const aid = super.topic(topic, topic2);
1628
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1629
+ }
1630
+
1631
+ /**
1632
+ * Finds an agent that provides a named service. If multiple agents are registered
1633
+ * to provide a given service, any of the agents' id may be returned.
1634
+ *
1635
+ * @param {string} service - the named service of interest
1636
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1637
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1638
+ * @returns {Promise<?AgentID|CachingAgentID>} - a promise which returns an agent id for an agent that provides the service when resolved
1639
+ */
1640
+ async agentForService(service, caching=true, greedy=true) {
1641
+ const aid = await super.agentForService(service);
1642
+ if (!aid) return aid;
1643
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1644
+ }
1645
+
1646
+ /**
1647
+ * Finds all agents that provides a named service.
1648
+ *
1649
+ * @param {string} service - the named service of interest
1650
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1651
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1652
+ * @returns {Promise<?AgentID|CachingAgentID[]>} - a promise which returns an array of all agent ids that provides the service when resolved
1653
+ */
1654
+ async agentsForService(service, caching=true, greedy=true) {
1655
+ const aids = await super.agentsForService(service);
1656
+ return caching ? aids.map(a => new CachingAgentID(a, null, null, greedy)) : aids;
1657
+ }
1658
+ }
1659
+
1398
1660
  const REQUEST_TIMEOUT = 1000;
1399
1661
 
1400
1662
  const AddressResolutionReq = UnetMessages.AddressResolutionReq;
@@ -1422,7 +1684,7 @@ class UnetSocket {
1422
1684
 
1423
1685
  constructor(hostname, port, path='') {
1424
1686
  return (async () => {
1425
- this.gw = new Gateway({
1687
+ this.gw = new CachingGateway({
1426
1688
  hostname : hostname,
1427
1689
  port : port,
1428
1690
  path : path
@@ -1633,31 +1895,34 @@ class UnetSocket {
1633
1895
  /**
1634
1896
  * Gets an AgentID providing a specified service for low-level access to UnetStack
1635
1897
  * @param {string} svc - the named service of interest
1898
+ * @param {Boolean} caching - if the AgentID should cache parameters
1636
1899
  * @returns {Promise<?AgentID>} - a promise which returns an {@link AgentID} that provides the service when resolved
1637
1900
  */
1638
- async agentForService(svc) {
1901
+ async agentForService(svc, caching=true) {
1639
1902
  if (this.gw == null) return null;
1640
- return await this.gw.agentForService(svc);
1903
+ return await this.gw.agentForService(svc, caching);
1641
1904
  }
1642
1905
 
1643
1906
  /**
1644
1907
  *
1645
1908
  * @param {string} svc - the named service of interest
1909
+ * @param {Boolean} caching - if the AgentID should cache parameters
1646
1910
  * @returns {Promise<AgentID[]>} - a promise which returns an array of {@link AgentID|AgentIDs} that provides the service when resolved
1647
1911
  */
1648
- async agentsForService(svc) {
1912
+ async agentsForService(svc, caching=true) {
1649
1913
  if (this.gw == null) return null;
1650
- return await this.gw.agentsForService(svc);
1914
+ return await this.gw.agentsForService(svc, caching``);
1651
1915
  }
1652
1916
 
1653
1917
  /**
1654
1918
  * Gets a named AgentID for low-level access to UnetStack.
1655
1919
  * @param {string} name - name of agent
1920
+ * @param {Boolean} caching - if the AgentID should cache parameters
1656
1921
  * @returns {AgentID} - AgentID for the given name
1657
1922
  */
1658
- agent(name) {
1923
+ agent(name, caching=true) {
1659
1924
  if (this.gw == null) return null;
1660
- return this.gw.agent(name);
1925
+ return this.gw.agent(name, caching);
1661
1926
  }
1662
1927
 
1663
1928
  /**
@@ -1677,4 +1942,4 @@ class UnetSocket {
1677
1942
  }
1678
1943
  }
1679
1944
 
1680
- export { AgentID, Gateway, Message, MessageClass, Performative, Protocol, Services, UnetMessages, UnetSocket };
1945
+ export { AgentID, CachingAgentID, CachingGateway as Gateway, Message, MessageClass, Performative, Protocol, Services, UnetMessages, UnetSocket, toGps, toLocal };
package/dist/unetjs.js CHANGED
@@ -1399,6 +1399,268 @@
1399
1399
  'SaveStateReq' : MessageClass('org.arl.unet.state.SaveStateReq')
1400
1400
  };
1401
1401
 
1402
+ /**
1403
+ * Convert coordinates from a local coordinates to GPS coordinate
1404
+ * @param {Array} origin - Local coordinate system's origin as `[latitude, longitude]`
1405
+ * @param {Number} x - X coordinate of the local coordinate to be converted
1406
+ * @param {Number} y - Y coordinate of the local coordinate to be converted
1407
+ * @returns {Array} - GPS coordinates (in decimal degrees) as `[latitude, longitude]`
1408
+ */
1409
+
1410
+ function toGps(origin, x, y) {
1411
+ let coords = [] ;
1412
+ let [xScale,yScale] = _initConv(origin[0]);
1413
+ coords[1] = x/xScale + origin[1];
1414
+ coords[0] = y/yScale + origin[0];
1415
+ return coords;
1416
+ }
1417
+
1418
+ /**
1419
+ * Convert coordinates from a GPS coordinates to local coordinate
1420
+ * @param {Array} origin - Local coordinate system's origin as `[latitude, longitude]`
1421
+ * @param {Number} lat - Latitude of the GPS coordinate to be converted
1422
+ * @param {Number} lon - Longitude of the GPS coordinate to be converted
1423
+ * @returns {Array} - GPS coordinates (in decimal degrees) as `[latitude, longitude]`
1424
+ */
1425
+ function toLocal(origin, lat, lon) {
1426
+ let pos = [];
1427
+ let [xScale,yScale] = _initConv(origin[0]);
1428
+ pos[0] = (lon-origin[1]) * xScale;
1429
+ pos[1] = (lat-origin[0]) * yScale;
1430
+ return pos;
1431
+ }
1432
+
1433
+ function _initConv(lat){
1434
+ let rlat = lat * Math.PI/180;
1435
+ let yScale = 111132.92 - 559.82*Math.cos(2*rlat) + 1.175*Math.cos(4*rlat) - 0.0023*Math.cos(6*rlat);
1436
+ let xScale = 111412.84*Math.cos(rlat) - 93.5*Math.cos(3*rlat) + 0.118*Math.cos(5*rlat);
1437
+ return [xScale, yScale];
1438
+ }
1439
+
1440
+ /**
1441
+ * A message which requests the transmission of the datagram from the Unet
1442
+ *
1443
+ * @typedef {Message} DatagramReq
1444
+ * @property {number[]} data - data as an Array of bytes
1445
+ * @property {number} from - from/source node address
1446
+ * @property {number} to - to/destination node address
1447
+ * @property {number} protocol - protocol number to be used to send this Datagram
1448
+ * @property {boolean} reliability - true if Datagram should be reliable, false if unreliable
1449
+ * @property {number} ttl - time-to-live for the datagram. Time-to-live is advisory, and an agent may choose it ignore it
1450
+ */
1451
+
1452
+ /**
1453
+ * Notification of received datagram message received by the Unet node.
1454
+ *
1455
+ * @typedef {Message} DatagramNtf
1456
+ * @property {number[]} data - data as an Array of bytes
1457
+ * @property {number} from - from/source node address
1458
+ * @property {number} to - to/destination node address
1459
+ * @property {number} protocol - protocol number to be used to send this Datagram
1460
+ * @property {number} ttl - time-to-live for the datagram. Time-to-live is advisory, and an agent may choose it ignore it
1461
+ */
1462
+
1463
+ /**
1464
+ * An identifier for an agent or a topic.
1465
+ * @external AgentID
1466
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1467
+ */
1468
+
1469
+ /**
1470
+ * Services supported by fjage agents.
1471
+ * @external Services
1472
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1473
+ */
1474
+
1475
+ /**
1476
+ * An action represented by a message.
1477
+ * @external Performative
1478
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1479
+ */
1480
+
1481
+ /**
1482
+ * Function to creates a unqualified message class based on a fully qualified name.
1483
+ * @external MessageClass
1484
+ * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
1485
+ */
1486
+
1487
+ /**
1488
+ * A caching CachingAgentID which caches Agent parameters locally.
1489
+ *
1490
+ * @class
1491
+ * @extends AgentID
1492
+ * @param {string | AgentID} name - name of the agent or an AgentID to copy
1493
+ * @param {boolean} topic - name of topic
1494
+ * @param {Gateway} owner - Gateway owner for this AgentID
1495
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1496
+ *
1497
+ */
1498
+ class CachingAgentID extends AgentID {
1499
+
1500
+ constructor(name, topic, owner, greedy=true) {
1501
+ if (name instanceof AgentID) {
1502
+ super(name.getName(), name.topic, name.owner);
1503
+ } else {
1504
+ super(name, topic, owner);
1505
+ }
1506
+ this.greedy = greedy;
1507
+ this.cache = {};
1508
+ }
1509
+
1510
+ /**
1511
+ * Sets parameter(s) on the Agent referred to by this AgentID, and caches the parameter(s).
1512
+ *
1513
+ * @param {(string|string[])} params - parameters name(s) to be set
1514
+ * @param {(Object|Object[])} values - parameters value(s) to be set
1515
+ * @param {number} [index=-1] - index of parameter(s) to be set
1516
+ * @param {number} [timeout=5000] - timeout for the response
1517
+ * @returns {Promise<(Object|Object[])>} - a promise which returns the new value(s) of the parameters
1518
+ */
1519
+ async set(params, values, index=-1, timeout=5000) {
1520
+ let s = await super.set(params, values, index, timeout);
1521
+ this._updateCache(params, s, index);
1522
+ }
1523
+
1524
+ /**
1525
+ * Gets parameter(s) on the Agent referred to by this AgentID, getting them from the cache if possible.
1526
+ *
1527
+ * @param {(string|string[])} params - parameters name(s) to be fetched
1528
+ * @param {number} [index=-1] - index of parameter(s) to be fetched
1529
+ * @param {number} [timeout=5000] - timeout for the response
1530
+ * @param {number} [maxage=5000] - maximum age of the cached result to retreive
1531
+ * @returns {Promise<(Object|Object[])>} - a promise which returns the value(s) of the parameters
1532
+ */
1533
+ async get(params, index=-1, timeout=5000, maxage=5000) {
1534
+ if (this._isCached(params, index, maxage)) return this._getCache(params, index);
1535
+ if (this.greedy && !(Array.isArray(params) && params.includes('name')) && params != 'name') {
1536
+ let rsp = await super.get(null, index, timeout);
1537
+ this._updateCache(null, rsp, index);
1538
+ if (Array.isArray(params)) {
1539
+ return params.map(p => {
1540
+ let f = Object.keys(rsp).find(rv => this._toNamed(rv) === p);
1541
+ return f ? rsp[f] : null;
1542
+ });
1543
+ } else {
1544
+ let f = Object.keys(rsp).find(rv => this._toNamed(rv) === params);
1545
+ return f ? rsp[f] : null;
1546
+ }
1547
+ } else {
1548
+ let r = await super.get(params, index, timeout);
1549
+ this._updateCache(params, r, index);
1550
+ return r;
1551
+ }
1552
+ }
1553
+
1554
+ _updateCache(params, vals, index) {
1555
+ if (vals == null || Array.isArray(vals) && vals.every(v => v == null)) return;
1556
+ if (params == null) {
1557
+ params = Object.keys(vals);
1558
+ vals = Object.values(vals);
1559
+ } else if (!Array.isArray(params)) params = [params];
1560
+ if (!Array.isArray(vals)) vals = [vals];
1561
+ params = params.map(this._toNamed);
1562
+ if (this.cache[index.toString()] === undefined) this.cache[index.toString()] = {};
1563
+ let c = this.cache[index.toString()];
1564
+ for (let i = 0; i < params.length; i++) {
1565
+ if (c[params[i]] === undefined) c[params[i]] = {};
1566
+ c[params[i]].value = vals[i];
1567
+ c[params[i]].ctime = Date.now();
1568
+ }
1569
+ }
1570
+
1571
+ _isCached(params, index, maxage) {
1572
+ if (maxage <= 0) return false;
1573
+ if (params == null) return false;
1574
+ let c = this.cache[index.toString()];
1575
+ if (!c) {
1576
+ return false;
1577
+ }
1578
+ if (!Array.isArray(params)) params = [params];
1579
+ const rv = params.every(p => {
1580
+ p = this._toNamed(p);
1581
+ return (p in c) && (Date.now() - c[p].ctime <= maxage);
1582
+ });
1583
+ return rv;
1584
+ }
1585
+
1586
+ _getCache(params, index) {
1587
+ let c = this.cache[index.toString()];
1588
+ if (!c) return null;
1589
+ if (!Array.isArray(params)){
1590
+ if (params in c) return c[params].value;
1591
+ return null;
1592
+ }else {
1593
+ return params.map(p => p in c ? c[p].value : null);
1594
+ }
1595
+ }
1596
+
1597
+ _toNamed(param) {
1598
+ const idx = param.lastIndexOf('.');
1599
+ if (idx < 0) return param;
1600
+ else return param.slice(idx+1);
1601
+ }
1602
+
1603
+ }
1604
+
1605
+
1606
+ class CachingGateway extends Gateway{
1607
+
1608
+ /**
1609
+ * Get an AgentID for a given agent name.
1610
+ *
1611
+ * @param {string} name - name of agent
1612
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1613
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1614
+ * @returns {AgentID|CachingAgentID} - AgentID for the given name
1615
+ */
1616
+ agent(name, caching=true, greedy=true) {
1617
+ const aid = super.agent(name);
1618
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1619
+ }
1620
+
1621
+ /**
1622
+ * Returns an object representing the named topic.
1623
+ *
1624
+ * @param {string|AgentID} topic - name of the topic or AgentID
1625
+ * @param {string} topic2 - name of the topic if the topic param is an AgentID
1626
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1627
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1628
+ * @returns {AgentID|CachingAgentID} - object representing the topic
1629
+ */
1630
+ topic(topic, topic2, caching=true, greedy=true) {
1631
+ const aid = super.topic(topic, topic2);
1632
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1633
+ }
1634
+
1635
+ /**
1636
+ * Finds an agent that provides a named service. If multiple agents are registered
1637
+ * to provide a given service, any of the agents' id may be returned.
1638
+ *
1639
+ * @param {string} service - the named service of interest
1640
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1641
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1642
+ * @returns {Promise<?AgentID|CachingAgentID>} - a promise which returns an agent id for an agent that provides the service when resolved
1643
+ */
1644
+ async agentForService(service, caching=true, greedy=true) {
1645
+ const aid = await super.agentForService(service);
1646
+ if (!aid) return aid;
1647
+ return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
1648
+ }
1649
+
1650
+ /**
1651
+ * Finds all agents that provides a named service.
1652
+ *
1653
+ * @param {string} service - the named service of interest
1654
+ * @param {Boolean} [caching=true] - if the AgentID should cache parameters
1655
+ * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
1656
+ * @returns {Promise<?AgentID|CachingAgentID[]>} - a promise which returns an array of all agent ids that provides the service when resolved
1657
+ */
1658
+ async agentsForService(service, caching=true, greedy=true) {
1659
+ const aids = await super.agentsForService(service);
1660
+ return caching ? aids.map(a => new CachingAgentID(a, null, null, greedy)) : aids;
1661
+ }
1662
+ }
1663
+
1402
1664
  const REQUEST_TIMEOUT = 1000;
1403
1665
 
1404
1666
  const AddressResolutionReq = UnetMessages.AddressResolutionReq;
@@ -1426,7 +1688,7 @@
1426
1688
 
1427
1689
  constructor(hostname, port, path='') {
1428
1690
  return (async () => {
1429
- this.gw = new Gateway({
1691
+ this.gw = new CachingGateway({
1430
1692
  hostname : hostname,
1431
1693
  port : port,
1432
1694
  path : path
@@ -1637,31 +1899,34 @@
1637
1899
  /**
1638
1900
  * Gets an AgentID providing a specified service for low-level access to UnetStack
1639
1901
  * @param {string} svc - the named service of interest
1902
+ * @param {Boolean} caching - if the AgentID should cache parameters
1640
1903
  * @returns {Promise<?AgentID>} - a promise which returns an {@link AgentID} that provides the service when resolved
1641
1904
  */
1642
- async agentForService(svc) {
1905
+ async agentForService(svc, caching=true) {
1643
1906
  if (this.gw == null) return null;
1644
- return await this.gw.agentForService(svc);
1907
+ return await this.gw.agentForService(svc, caching);
1645
1908
  }
1646
1909
 
1647
1910
  /**
1648
1911
  *
1649
1912
  * @param {string} svc - the named service of interest
1913
+ * @param {Boolean} caching - if the AgentID should cache parameters
1650
1914
  * @returns {Promise<AgentID[]>} - a promise which returns an array of {@link AgentID|AgentIDs} that provides the service when resolved
1651
1915
  */
1652
- async agentsForService(svc) {
1916
+ async agentsForService(svc, caching=true) {
1653
1917
  if (this.gw == null) return null;
1654
- return await this.gw.agentsForService(svc);
1918
+ return await this.gw.agentsForService(svc, caching``);
1655
1919
  }
1656
1920
 
1657
1921
  /**
1658
1922
  * Gets a named AgentID for low-level access to UnetStack.
1659
1923
  * @param {string} name - name of agent
1924
+ * @param {Boolean} caching - if the AgentID should cache parameters
1660
1925
  * @returns {AgentID} - AgentID for the given name
1661
1926
  */
1662
- agent(name) {
1927
+ agent(name, caching=true) {
1663
1928
  if (this.gw == null) return null;
1664
- return this.gw.agent(name);
1929
+ return this.gw.agent(name, caching);
1665
1930
  }
1666
1931
 
1667
1932
  /**
@@ -1682,7 +1947,8 @@
1682
1947
  }
1683
1948
 
1684
1949
  exports.AgentID = AgentID;
1685
- exports.Gateway = Gateway;
1950
+ exports.CachingAgentID = CachingAgentID;
1951
+ exports.Gateway = CachingGateway;
1686
1952
  exports.Message = Message;
1687
1953
  exports.MessageClass = MessageClass;
1688
1954
  exports.Performative = Performative;
@@ -1690,6 +1956,8 @@
1690
1956
  exports.Services = Services;
1691
1957
  exports.UnetMessages = UnetMessages;
1692
1958
  exports.UnetSocket = UnetSocket;
1959
+ exports.toGps = toGps;
1960
+ exports.toLocal = toLocal;
1693
1961
 
1694
1962
  }));
1695
1963
  //# sourceMappingURL=unetjs.js.map