unetjs 5.0.1 → 6.0.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 v5.0.1 2025-09-10T10:45:09.129Z */
1
+ /* unet.js v6.0.0 2026-04-01T02:42:00.135Z */
2
2
 
3
3
  'use strict';
4
4
 
5
- /* fjage.js v2.2.2 */
5
+ /* fjage.js v2.3.0 */
6
6
 
7
7
  /**
8
8
  * An action represented by a message. The performative actions are a subset of the
@@ -1846,6 +1846,60 @@ const ParameterReq = MessageClass('org.arl.fjage.param.ParameterReq');
1846
1846
  */
1847
1847
  MessageClass('org.arl.fjage.param.ParameterRsp');
1848
1848
 
1849
+ /**
1850
+ * Request to write contents to a file, or delete a file.
1851
+ *
1852
+ * @typedef {Message} PutFileReq
1853
+ * @property {string} filename - name of the file to be written to or deleted
1854
+ * @property {number} [content] - content to be written to the file as a byte array. If not provided, the file will be deleted.
1855
+ * @property {number} [offset=0] - offset in the file to write the content to.
1856
+ * @exports PutFileReq
1857
+ */
1858
+ const PutFileReq = MessageClass('org.arl.fjage.shell.PutFileReq');
1859
+
1860
+
1861
+ /**
1862
+ * Request to read a file or a directory.
1863
+ *
1864
+ * If the filename specified represents a directory, then the contents of the
1865
+ * directory (list of files) are returned as a tab separated string with:
1866
+ * filename, file size, last modification time.
1867
+ *
1868
+ * The time is represented as epoch time (milliseconds since 1 Jan 1970).
1869
+ *
1870
+ * @typedef {Message} GetFileReq
1871
+ * @property {string} filename - name of the file or directory to be read
1872
+ * @property {number} [offset=0] - offset in the file to read from (ignored for directories)
1873
+ * @property {number} [length=0] - number of bytes to read from the file (ignored for directories). If 0,
1874
+ * the entire file will be read.
1875
+ * @exports GetFileReq
1876
+ */
1877
+ const GetFileReq = MessageClass('org.arl.fjage.shell.GetFileReq');
1878
+
1879
+ /**
1880
+ * Response to a {@link GetFileReq}, with the contents of the file or the directory.
1881
+ *
1882
+ * @typedef {Message} GetFileRsp
1883
+ * @property {string} filename - name of the file or directory that was read
1884
+ * @property {number} [content] - content of the file as a byte array. If the filename represents a directory,
1885
+ * the content consists of a list of files (one file per line). Each line starts with the filename
1886
+ * (with a trailing "/" if it is a directory), "\t", file size in bytes, "\t", and last modification date.
1887
+ * @property {number} [offset=0] - offset in the file that the content corresponds to (ignored for directories)
1888
+ * @property {boolean} [directory=false] - indicates if the filename represents a directory
1889
+ * @exports GetFileRsp
1890
+ */
1891
+ const GetFileRsp = MessageClass('org.arl.fjage.shell.GetFileRsp');
1892
+
1893
+ /**
1894
+ * Request to execute shell command/script.
1895
+ *
1896
+ * @typedef {Message} ShellExecReq
1897
+ * @property {string} command - shell command or script to be executed
1898
+ * @property {boolean} ans - indicates if the response to this request should include the output of the command/script execution
1899
+ * @exports ShellExecReq
1900
+ */
1901
+ const ShellExecReq = MessageClass('org.arl.fjage.shell.ShellExecReq');
1902
+
1849
1903
  /**
1850
1904
  * Services supported by fjage agents.
1851
1905
  */
@@ -1858,9 +1912,15 @@ init();
1858
1912
  const DatagramReq$1 = MessageClass('org.arl.unet.DatagramReq');
1859
1913
  const DatagramNtf$1 = MessageClass('org.arl.unet.DatagramNtf');
1860
1914
  const TxFrameReq = MessageClass('org.arl.unet.phy.TxFrameReq', DatagramReq$1);
1861
- const RxFrameNtf$1 = MessageClass('org.arl.unet.phy.RxFrameNtf', DatagramNtf$1);
1915
+ const RxFrameNtf = MessageClass('org.arl.unet.phy.RxFrameNtf', DatagramNtf$1);
1862
1916
  const BasebandSignal = MessageClass('org.arl.unet.bb.BasebandSignal');
1863
1917
 
1918
+ const UnetTopics = {
1919
+ 'PARAMCHANGE' : 'org.arl.unet.Topics.PARAMCHANGE', // Topic for parameter change notification.
1920
+ 'LIFECYCLE' : 'org.arl.unet.Topics.LIFECYCLE', // Topic for agent lifecycle notification.
1921
+ 'DATAGRAM' : 'org.arl.unet.Topics.DATAGRAM', // Topic for incoming datagram notification.
1922
+ };
1923
+
1864
1924
  let UnetServices = {
1865
1925
  'NODE_INFO': 'org.arl.unet.Services.NODE_INFO',
1866
1926
  'ADDRESS_RESOLUTION': 'org.arl.unet.Services.ADDRESS_RESOLUTION',
@@ -1905,6 +1965,13 @@ let Protocol = {
1905
1965
  * @typedef {Object.<string, MessageClass>} UnetMessages
1906
1966
  */
1907
1967
  let UnetMessages = {
1968
+
1969
+ // fjage
1970
+ 'PutFileReq' : PutFileReq,
1971
+ 'GetFileReq' : GetFileReq,
1972
+ 'GetFileRsp' : GetFileRsp,
1973
+ 'ShellExecReq' : ShellExecReq,
1974
+
1908
1975
  // unet
1909
1976
  'TestReportNtf' : MessageClass('org.arl.unet.TestReportNtf'),
1910
1977
  'AbnormalTerminationNtf' : MessageClass('org.arl.unet.AbnormalTerminationNtf'),
@@ -1917,6 +1984,7 @@ let UnetMessages = {
1917
1984
  'DatagramNtf' : MessageClass('org.arl.unet.DatagramNtf'),
1918
1985
  'DatagramProgressNtf' : MessageClass('org.arl.unet.DatagramProgressNtf'),
1919
1986
  'DatagramReq' : MessageClass('org.arl.unet.DatagramReq'),
1987
+ 'DatagramTransmissionNtf': MessageClass('org.arl.unet.DatagramTransmissionNtf'),
1920
1988
  'ParamChangeNtf' : MessageClass('org.arl.unet.ParamChangeNtf'),
1921
1989
  'RefuseRsp' : MessageClass('org.arl.unet.RefuseRsp'),
1922
1990
  'FailureNtf' : MessageClass('org.arl.unet.FailureNtf'),
@@ -1930,9 +1998,9 @@ let UnetMessages = {
1930
1998
 
1931
1999
  // phy
1932
2000
  'FecDecodeReq' : MessageClass('org.arl.unet.phy.FecDecodeReq'),
1933
- 'RxSWiG1FrameNtf' : MessageClass('org.arl.unet.phy.RxSWiG1FrameNtf', RxFrameNtf$1),
2001
+ 'RxSWiG1FrameNtf' : MessageClass('org.arl.unet.phy.RxSWiG1FrameNtf', RxFrameNtf),
1934
2002
  'TxSWiG1FrameReq' : MessageClass('org.arl.unet.phy.TxSWiG1FrameReq', TxFrameReq),
1935
- 'RxJanusFrameNtf' : MessageClass('org.arl.unet.phy.RxJanusFrameNtf', RxFrameNtf$1),
2003
+ 'RxJanusFrameNtf' : MessageClass('org.arl.unet.phy.RxJanusFrameNtf', RxFrameNtf),
1936
2004
  'TxJanusFrameReq' : MessageClass('org.arl.unet.phy.TxJanusFrameReq', TxFrameReq),
1937
2005
  'BadFrameNtf' : MessageClass('org.arl.unet.phy.BadFrameNtf'),
1938
2006
  'BadRangeNtf' : MessageClass('org.arl.unet.phy.BadRangeNtf'),
@@ -1986,6 +2054,7 @@ let UnetMessages = {
1986
2054
  'RemoteFileGetReq' : MessageClass('org.arl.unet.remote.RemoteFileGetReq'),
1987
2055
  'RemoteFileNtf' : MessageClass('org.arl.unet.remote.RemoteFileNtf'),
1988
2056
  'RemoteFilePutReq' : MessageClass('org.arl.unet.remote.RemoteFilePutReq'),
2057
+ 'RemoteDeliveryNtf' : MessageClass('org.arl.unet.remote.RemoteDeliveryNtf'),
1989
2058
  'RemoteSuccessNtf' : MessageClass('org.arl.unet.remote.RemoteSuccessNtf'),
1990
2059
  'RemoteTextNtf' : MessageClass('org.arl.unet.remote.RemoteTextNtf'),
1991
2060
  'RemoteTextReq' : MessageClass('org.arl.unet.remote.RemoteTextReq'),
@@ -2040,243 +2109,33 @@ function _initConv(lat){
2040
2109
  return [xScale, yScale];
2041
2110
  }
2042
2111
 
2043
- /**
2044
- * A message which requests the transmission of the datagram from the Unet
2045
- *
2046
- * @typedef {Message} DatagramReq
2047
- * @property {number[]} data - data as an Array of bytes
2048
- * @property {number} from - from/source node address
2049
- * @property {number} to - to/destination node address
2050
- * @property {number} protocol - protocol number to be used to send this Datagram
2051
- * @property {boolean} reliability - true if Datagram should be reliable, false if unreliable
2052
- * @property {number} ttl - time-to-live for the datagram. Time-to-live is advisory, and an agent may choose it ignore it
2053
- */
2054
-
2055
- /**
2056
- * Notification of received datagram message received by the Unet node.
2057
- *
2058
- * @typedef {Message} DatagramNtf
2059
- * @property {number[]} data - data as an Array of bytes
2060
- * @property {number} from - from/source node address
2061
- * @property {number} to - to/destination node address
2062
- * @property {number} protocol - protocol number to be used to send this Datagram
2063
- * @property {number} ttl - time-to-live for the datagram. Time-to-live is advisory, and an agent may choose it ignore it
2064
- */
2065
-
2066
- /**
2067
- * An identifier for an agent or a topic.
2068
- * @external AgentID
2069
- * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
2070
- */
2071
-
2072
- /**
2073
- * Services supported by fjage agents.
2074
- * @external Services
2075
- * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
2076
- */
2077
-
2078
- /**
2079
- * An action represented by a message.
2080
- * @external Performative
2081
- * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
2082
- */
2083
-
2084
- /**
2085
- * Function to creates a unqualified message class based on a fully qualified name.
2086
- * @external MessageClass
2087
- * @see {@link https://org-arl.github.io/fjage/jsdoc/|fjåge.js Documentation}
2088
- */
2089
-
2090
- /**
2091
- * A caching CachingAgentID which caches Agent parameters locally.
2092
- *
2093
- * @class
2094
- * @extends AgentID
2095
- * @param {string | AgentID} name - name of the agent or an AgentID to copy
2096
- * @param {boolean} topic - name of topic
2097
- * @param {Gateway} owner - Gateway owner for this AgentID
2098
- * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
2099
- *
2100
- */
2101
- class CachingAgentID extends AgentID {
2102
-
2103
- constructor(name, topic, owner, greedy=true) {
2104
- if (name instanceof AgentID) {
2105
- super(name.getName(), name.topic, name.owner);
2106
- } else {
2107
- super(name, topic, owner);
2108
- }
2109
- this.greedy = greedy;
2110
- this.cache = {};
2111
- this.specialParams = ['name', 'version'];
2112
- }
2113
-
2114
- /**
2115
- * Sets parameter(s) on the Agent referred to by this AgentID, and caches the parameter(s).
2116
- *
2117
- * @param {(string|string[])} params - parameters name(s) to be set
2118
- * @param {(Object|Object[])} values - parameters value(s) to be set
2119
- * @param {number} [index=-1] - index of parameter(s) to be set
2120
- * @param {number} [timeout=5000] - timeout for the response
2121
- * @returns {Promise<(Object|Object[])>} - a promise which returns the new value(s) of the parameters
2122
- */
2123
- async set(params, values, index=-1, timeout=5000) {
2124
- let s = await super.set(params, values, index, timeout);
2125
- this._updateCache(params, s, index);
2126
- return s;
2127
- }
2128
-
2129
- /**
2130
- * Gets parameter(s) on the Agent referred to by this AgentID, getting them from the cache if possible.
2131
- *
2132
- * @param {(string|string[])} params - parameters name(s) to be fetched
2133
- * @param {number} [index=-1] - index of parameter(s) to be fetched
2134
- * @param {number} [timeout=5000] - timeout for the response
2135
- * @param {number} [maxage=5000] - maximum age of the cached result to retreive
2136
- * @returns {Promise<(Object|Object[])>} - a promise which returns the value(s) of the parameters
2137
- */
2138
- async get(params, index=-1, timeout=5000, maxage=5000) {
2139
- if (this._isCached(params, index, maxage)) return this._getCache(params, index);
2140
- if (this.greedy &&
2141
- !(Array.isArray(params) && [...new Set([...params, ...this.specialParams])].length!=0) &&
2142
- !this.specialParams.includes(params)) {
2143
- let rsp = await super.get(null, index, timeout);
2144
- this._updateCache(null, rsp, index);
2145
- if (!rsp) return Array.isArray(params) ? new Array(params.length).fill(null) : null;
2146
- if (!params) return rsp;
2147
- else if (Array.isArray(params)) {
2148
- return params.map(p => {
2149
- let f = Object.keys(rsp).find(rv => this._toNamed(rv) === p);
2150
- return f ? rsp[f] : null;
2151
- });
2152
- } else {
2153
- let f = Object.keys(rsp).find(rv => this._toNamed(rv) === params);
2154
- return f ? rsp[f] : null;
2155
- }
2156
- } else {
2157
- let r = await super.get(params, index, timeout);
2158
- this._updateCache(params, r, index);
2159
- return r;
2160
- }
2161
- }
2162
-
2163
- _updateCache(params, vals, index) {
2164
- if (vals == null || Array.isArray(vals) && vals.every(v => v == null)) return;
2165
- if (params == null) {
2166
- params = Object.keys(vals);
2167
- vals = Object.values(vals);
2168
- } else if (!Array.isArray(params)) params = [params];
2169
- if (!Array.isArray(vals)) vals = [vals];
2170
- params = params.map(this._toNamed);
2171
- if (this.cache[index.toString()] === undefined) this.cache[index.toString()] = {};
2172
- let c = this.cache[index.toString()];
2173
- for (let i = 0; i < params.length; i++) {
2174
- if (c[params[i]] === undefined) c[params[i]] = {};
2175
- c[params[i]].value = vals[i];
2176
- c[params[i]].ctime = Date.now();
2177
- }
2178
- }
2179
-
2180
- _isCached(params, index, maxage) {
2181
- if (maxage <= 0) return false;
2182
- if (params == null) return false;
2183
- let c = this.cache[index.toString()];
2184
- if (!c) {
2185
- return false;
2186
- }
2187
- if (!Array.isArray(params)) params = [params];
2188
- const rv = params.every(p => {
2189
- p = this._toNamed(p);
2190
- return (p in c) && (Date.now() - c[p].ctime <= maxage);
2191
- });
2192
- return rv;
2193
- }
2194
-
2195
- _getCache(params, index) {
2196
- let c = this.cache[index.toString()];
2197
- if (!c) return null;
2198
- if (!Array.isArray(params)){
2199
- if (params in c) return c[params].value;
2200
- return null;
2201
- }else {
2202
- return params.map(p => p in c ? c[p].value : null);
2203
- }
2204
- }
2205
-
2206
- _toNamed(param) {
2207
- const idx = param.lastIndexOf('.');
2208
- if (idx < 0) return param;
2209
- else return param.slice(idx+1);
2210
- }
2211
-
2212
- }
2213
-
2214
-
2215
- class CachingGateway extends Gateway{
2216
-
2217
- /**
2218
- * Get an AgentID for a given agent name.
2219
- *
2220
- * @param {string} name - name of agent
2221
- * @param {Boolean} [caching=true] - if the AgentID should cache parameters
2222
- * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
2223
- * @returns {AgentID|CachingAgentID} - AgentID for the given name
2224
- */
2225
- agent(name, caching=true, greedy=true) {
2226
- const aid = super.agent(name);
2227
- return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
2228
- }
2229
-
2230
- /**
2231
- * Returns an object representing the named topic.
2232
- *
2233
- * @param {string|AgentID} topic - name of the topic or AgentID
2234
- * @param {string} topic2 - name of the topic if the topic param is an AgentID
2235
- * @param {Boolean} [caching=true] - if the AgentID should cache parameters
2236
- * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
2237
- * @returns {AgentID|CachingAgentID} - object representing the topic
2238
- */
2239
- topic(topic, topic2, caching=true, greedy=true) {
2240
- const aid = super.topic(topic, topic2);
2241
- return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
2242
- }
2243
-
2244
- /**
2245
- * Finds an agent that provides a named service. If multiple agents are registered
2246
- * to provide a given service, any of the agents' id may be returned.
2247
- *
2248
- * @param {string} service - the named service of interest
2249
- * @param {Boolean} [caching=true] - if the AgentID should cache parameters
2250
- * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
2251
- * @returns {Promise<?AgentID|CachingAgentID>} - a promise which returns an agent id for an agent that provides the service when resolved
2252
- */
2253
- async agentForService(service, caching=true, greedy=true) {
2254
- const aid = await super.agentForService(service);
2255
- if (!aid) return aid;
2256
- return caching ? new CachingAgentID(aid, null, null, greedy) : aid;
2257
- }
2258
-
2259
- /**
2260
- * Finds all agents that provides a named service.
2261
- *
2262
- * @param {string} service - the named service of interest
2263
- * @param {Boolean} [caching=true] - if the AgentID should cache parameters
2264
- * @param {Boolean} [greedy=true] - greedily fetches and caches all parameters if this Agent
2265
- * @returns {Promise<?AgentID|CachingAgentID[]>} - a promise which returns an array of all agent ids that provides the service when resolved
2266
- */
2267
- async agentsForService(service, caching=true, greedy=true) {
2268
- const aids = await super.agentsForService(service);
2269
- return caching ? aids.map(a => new CachingAgentID(a, null, null, greedy)) : aids;
2270
- }
2271
- }
2272
-
2112
+ const BROADCAST_ADDR = 0;
2273
2113
  const REQUEST_TIMEOUT = 1000;
2114
+ const NON_BLOCKING = 0;
2115
+ const SEMI_BLOCKING = 1;
2116
+ const BLOCKING = 2;
2274
2117
 
2275
2118
  const AddressResolutionReq = UnetMessages.AddressResolutionReq;
2119
+ const DatagramDeliveryNtf = UnetMessages.DatagramDeliveryNtf;
2120
+ const DatagramFailureNtf = UnetMessages.DatagramFailureNtf;
2276
2121
  const DatagramReq = UnetMessages.DatagramReq;
2277
2122
  const DatagramNtf = UnetMessages.DatagramNtf;
2278
- const RxFrameNtf = UnetMessages.RxFrameNtf;
2123
+ const DatagramTransmissionNtf = UnetMessages.DatagramTransmissionNtf;
2124
+ const RemoteDeliveryNtf = UnetMessages.RemoteDeliveryNtf;
2125
+ const RemoteFailureNtf = UnetMessages.RemoteFailureNtf;
2126
+ const RemoteSuccessNtf = UnetMessages.RemoteSuccessNtf;
2127
+
2128
+ function isReservedProtocol(protocol) {
2129
+ return protocol != Protocol.DATA && (protocol < Protocol.USER || protocol > Protocol.MAX);
2130
+ }
2131
+
2132
+ function hasValue(value) {
2133
+ return value !== undefined && value !== null;
2134
+ }
2279
2135
 
2136
+ function hasFiniteNumber(value) {
2137
+ return typeof value === 'number' && Number.isFinite(value);
2138
+ }
2280
2139
  /**
2281
2140
  * Creates a new UnetSocket to connect to a running Unet instance. This constructor returns a
2282
2141
  * {@link Promise} instead of the constructed UnetSocket object. Use `await` or `.then()` to get
@@ -2297,18 +2156,63 @@ class UnetSocket {
2297
2156
 
2298
2157
  constructor(hostname, port, path='') {
2299
2158
  return (async () => {
2300
- this.gw = new Gateway({
2159
+ this._gw = new Gateway({
2301
2160
  hostname : hostname,
2302
2161
  port : port,
2303
2162
  path : path
2304
2163
  });
2305
- this.localProtocol = -1;
2306
- this.remoteAddress = -1;
2307
- this.remoteProtocol = Protocol.DATA;
2308
- this.timeout = 0;
2309
- this.provider = null;
2310
- const alist = await this.gw.agentsForService(Services.DATAGRAM);
2311
- alist.forEach(a => {this.gw.subscribe(this.gw.topic(a));});
2164
+ this._localProtocol = -1;
2165
+ this._remoteAddress = -1;
2166
+ this._localAddress = -1;
2167
+ this._remoteProtocol = Protocol.DATA;
2168
+ this._timeout = 0;
2169
+ this._serviceProvider = null;
2170
+ this._ttl = NaN;
2171
+ this._priority = null;
2172
+ this._reliability = null;
2173
+ this._route = null;
2174
+ this._mimeType = null;
2175
+ this._remoteRecipient = null;
2176
+ this._mailbox = null;
2177
+ this._messageClass = null;
2178
+ this._sendMode = SEMI_BLOCKING;
2179
+ this._warnedDeprecatedSend = false;
2180
+ this._paramChangeCallbacks = {};
2181
+
2182
+ //for new UnetStack versions (5.2.0 and later)
2183
+ this._gw.subscribe(this._gw.topic(UnetTopics.DATAGRAM));
2184
+
2185
+ //for compatibility with older UnetStack versions (before 5.2.0)
2186
+ const alist = await this._gw.agentsForService(Services.DATAGRAM);
2187
+ alist.forEach(a => {this._gw.subscribe(this._gw.topic(a));});
2188
+
2189
+ // get local nodeinfo agent
2190
+ const nodeinfo = await this._gw.agentForService(Services.NODE_INFO);
2191
+
2192
+ // subscribe to paramchange notifications for onParamChange callbacks
2193
+ this._gw.subscribe(this._gw.topic(UnetTopics.PARAMCHANGE));
2194
+ if (nodeinfo != null) this._gw.subscribe(this._gw.topic(nodeinfo)); // nodeinfo publishes param changes for local node parameters
2195
+ this._gw.addMessageListener(msg => {
2196
+ if (msg instanceof UnetMessages.ParamChangeNtf) {
2197
+ const sender = (msg.sender instanceof AgentID) ? msg.sender.name : msg.sender;
2198
+ if (msg.paramValues != null){
2199
+ for (const p in msg.paramValues) {
2200
+ // if p has dots inside then take the substring after the last dot as the parameter name,
2201
+ // since many times fully qualified parameter names are used in the notifications
2202
+ const paramName = p.includes('.') ? p.substring(p.lastIndexOf('.') + 1) : p;
2203
+ const callback = this._paramChangeCallbacks[sender + '.' + paramName];
2204
+ if (callback != null) callback(msg.paramValues[p]);
2205
+ }
2206
+ }
2207
+ }
2208
+ });
2209
+
2210
+ // get local node address and subscribe to changes in the local node address
2211
+ if (nodeinfo != null) {
2212
+ this.onParamChange(nodeinfo.name, 'address', (addr) => { this._localAddress = addr; });
2213
+ this._localAddress = await nodeinfo.get('address');
2214
+ }
2215
+
2312
2216
  return this;
2313
2217
  })();
2314
2218
  }
@@ -2318,8 +2222,8 @@ class UnetSocket {
2318
2222
  * @returns {void}
2319
2223
  */
2320
2224
  close() {
2321
- this.gw.close();
2322
- this.gw = null;
2225
+ this._gw.close();
2226
+ this._gw = null;
2323
2227
  }
2324
2228
 
2325
2229
  /**
@@ -2327,7 +2231,7 @@ class UnetSocket {
2327
2231
  * @returns {boolean} - true if closed, false if open
2328
2232
  */
2329
2233
  isClosed() {
2330
- return this.gw == null;
2234
+ return this._gw == null;
2331
2235
  }
2332
2236
 
2333
2237
  /**
@@ -2339,7 +2243,7 @@ class UnetSocket {
2339
2243
  */
2340
2244
  bind(protocol) {
2341
2245
  if (protocol == Protocol.DATA || (protocol >= Protocol.USER && protocol <= Protocol.MAX)) {
2342
- this.localProtocol = protocol;
2246
+ this._localProtocol = protocol;
2343
2247
  return true;
2344
2248
  }
2345
2249
  return false;
@@ -2350,13 +2254,13 @@ class UnetSocket {
2350
2254
  * Protocol numbers between Protocol.DATA+1 to Protocol.USER-1 are considered reserved.
2351
2255
  * @returns {void}
2352
2256
  */
2353
- unbind() { this.localProtocol = -1;}
2257
+ unbind() { this._localProtocol = -1;}
2354
2258
 
2355
2259
  /**
2356
2260
  * Checks if a socket is bound.
2357
2261
  * @returns {boolean} - true if bound to a protocol, false if unbound
2358
2262
  */
2359
- isBound() { return this.localProtocol >= 0;}
2263
+ isBound() { return this._localProtocol >= 0;}
2360
2264
 
2361
2265
  /**
2362
2266
  * Sets the default destination address and destination protocol number for datagrams sent
@@ -2372,8 +2276,8 @@ class UnetSocket {
2372
2276
  */
2373
2277
  connect(to, protocol) {
2374
2278
  if (to >= 0 && (protocol == Protocol.DATA || (protocol >= Protocol.USER && protocol <= Protocol.MAX))) {
2375
- this.remoteAddress = to;
2376
- this.remoteProtocol = protocol;
2279
+ this._remoteAddress = to;
2280
+ this._remoteProtocol = protocol;
2377
2281
  return true;
2378
2282
  }
2379
2283
  return false;
@@ -2385,23 +2289,23 @@ class UnetSocket {
2385
2289
  * @returns {void}
2386
2290
  */
2387
2291
  disconnect() {
2388
- this.remoteAddress = -1;
2389
- this.remoteProtocol = 0;
2292
+ this._remoteAddress = -1;
2293
+ this._remoteProtocol = 0;
2390
2294
  }
2391
2295
 
2392
2296
  /**
2393
2297
  * Checks if a socket is connected, i.e., has a default destination address and protocol number.
2394
2298
  * @returns {boolean} - true if connected, false otherwise
2395
2299
  */
2396
- isConnected() { return this.remoteAddress >= 0; }
2300
+ isConnected() { return this._remoteAddress >= 0; }
2397
2301
 
2398
2302
  /**
2399
2303
  * Gets the local node address of the Unet node connected to.
2400
2304
  * @returns {Promise<int>} - local node address, or -1 on error
2401
2305
  */
2402
2306
  async getLocalAddress() {
2403
- if (this.gw == null) return -1;
2404
- const nodeinfo = await this.gw.agentForService(Services.NODE_INFO);
2307
+ if (this._gw == null) return -1;
2308
+ const nodeinfo = await this._gw.agentForService(Services.NODE_INFO);
2405
2309
  if (nodeinfo == null) return -1;
2406
2310
  const addr = await nodeinfo.get('address');
2407
2311
  return addr != null ? addr : -1;
@@ -2409,21 +2313,21 @@ class UnetSocket {
2409
2313
 
2410
2314
  /**
2411
2315
  * Gets the protocol number that the socket is bound to.
2412
- * @returns {number}} - protocol number if socket is bound, -1 otherwise
2316
+ * @returns {number} - protocol number if socket is bound, -1 otherwise
2413
2317
  */
2414
- getLocalProtocol() { return this.localProtocol; }
2318
+ getLocalProtocol() { return this._localProtocol; }
2415
2319
 
2416
2320
  /**
2417
2321
  * Gets the default destination node address for a connected socket.
2418
- * @returns {number}} - default destination node address if connected, -1 otherwise
2322
+ * @returns {number} - default destination node address if connected, -1 otherwise
2419
2323
  */
2420
- getRemoteAddress() { return this.remoteAddress; }
2324
+ getRemoteAddress() { return this._remoteAddress; }
2421
2325
 
2422
2326
  /**
2423
2327
  * Gets the default transmission protocol number.
2424
- * @returns {number}} - default protocol number used to transmit a datagram
2328
+ * @returns {number} - default protocol number used to transmit a datagram
2425
2329
  */
2426
- getRemoteProtocol() { return this.remoteProtocol; }
2330
+ getRemoteProtocol() { return this._remoteProtocol; }
2427
2331
 
2428
2332
  /**
2429
2333
  * Sets the timeout for datagram reception. A timeout of 0 means the
@@ -2435,14 +2339,275 @@ class UnetSocket {
2435
2339
  */
2436
2340
  setTimeout(ms) {
2437
2341
  if (ms < 0) ms = 0;
2438
- this.timeout = ms;
2342
+ this._timeout = ms;
2439
2343
  }
2440
2344
 
2441
2345
  /**
2442
2346
  * Gets the timeout for datagram reception.
2443
2347
  * @returns {number} - timeout in milliseconds
2444
2348
  */
2445
- getTimeout() { return this.timeout; }
2349
+ getTimeout() { return this._timeout; }
2350
+
2351
+ /**
2352
+ * Sets the default time-to-live for datagrams sent using this socket.
2353
+ * TTL is advisory; an agent may choose to ignore it.
2354
+ * @param {number} ttl - time-to-live in seconds
2355
+ * @returns {void}
2356
+ */
2357
+ setTTL(ttl) {
2358
+ this._ttl = ttl;
2359
+ }
2360
+
2361
+ /**
2362
+ * Gets the default time-to-live for datagrams sent using this socket.
2363
+ * @returns {number} - time-to-live in seconds, or NaN if not set
2364
+ */
2365
+ getTTL() {
2366
+ return this._ttl;
2367
+ }
2368
+
2369
+ /**
2370
+ * Sets the default priority for datagrams sent using this socket.
2371
+ * @param {*} priority - priority value; interpretation is provider-dependent
2372
+ * @returns {void}
2373
+ */
2374
+ setPriority(priority) {
2375
+ this._priority = priority;
2376
+ }
2377
+
2378
+ /**
2379
+ * Gets the default priority for datagrams sent using this socket.
2380
+ * @returns {*} - priority value, or null if not set
2381
+ */
2382
+ getPriority() {
2383
+ return this._priority;
2384
+ }
2385
+
2386
+ /**
2387
+ * Sets the default reliability for datagrams sent using this socket.
2388
+ * When set to true, the socket will request reliable delivery and, in
2389
+ * SEMI_BLOCKING mode, will wait for a delivery confirmation before returning.
2390
+ * @param {boolean} reliability - true for reliable delivery, false for unreliable
2391
+ * @returns {void}
2392
+ */
2393
+ setReliability(reliability) {
2394
+ this._reliability = reliability;
2395
+ }
2396
+
2397
+ /**
2398
+ * Gets the default reliability setting for datagrams sent using this socket.
2399
+ * @returns {boolean|null} - true if reliable, false if unreliable, null if not set
2400
+ */
2401
+ getReliability() {
2402
+ return this._reliability;
2403
+ }
2404
+
2405
+ /**
2406
+ * Sets the default route identifier for datagrams sent using this socket.
2407
+ * Route selection is provider-dependent; not all providers support explicit routing.
2408
+ * @param {*} route - route identifier
2409
+ * @returns {void}
2410
+ */
2411
+ setRoute(route) {
2412
+ this._route = route;
2413
+ }
2414
+
2415
+ /**
2416
+ * Gets the default route identifier for datagrams sent using this socket.
2417
+ * @returns {*} - route identifier, or null if not set
2418
+ */
2419
+ getRoute() {
2420
+ return this._route;
2421
+ }
2422
+
2423
+ /**
2424
+ * Sets the default MIME type describing the datagram payload.
2425
+ * This can be used by REMOTE service providers to apply content-aware compression.
2426
+ * @param {string} mimeType - MIME type string (e.g. 'application/json')
2427
+ * @returns {void}
2428
+ */
2429
+ setMimeType(mimeType) {
2430
+ this._mimeType = mimeType;
2431
+ }
2432
+
2433
+ /**
2434
+ * Gets the default MIME type for datagrams sent using this socket.
2435
+ * @returns {string|null} - MIME type string, or null if not set
2436
+ */
2437
+ getMimeType() {
2438
+ return this._mimeType;
2439
+ }
2440
+
2441
+ /**
2442
+ * Sets the default remote recipient for datagrams sent using this socket.
2443
+ * Used by REMOTE service providers to address a specific entity on the remote node.
2444
+ * @param {*} remoteRecipient - remote recipient identifier (e.g. an AgentID or name string)
2445
+ * @returns {void}
2446
+ */
2447
+ setRemoteRecipient(remoteRecipient) {
2448
+ this._remoteRecipient = remoteRecipient;
2449
+ }
2450
+
2451
+ /**
2452
+ * Gets the default remote recipient for datagrams sent using this socket.
2453
+ * @returns {*} - remote recipient identifier, or null if not set
2454
+ */
2455
+ getRemoteRecipient() {
2456
+ return this._remoteRecipient;
2457
+ }
2458
+
2459
+ /**
2460
+ * Sets the default mailbox name for datagrams sent using this socket.
2461
+ * Mailboxes are used by REMOTE service providers to deliver messages
2462
+ * to a named queue on the remote node.
2463
+ * @param {string} mailbox - mailbox name
2464
+ * @returns {void}
2465
+ */
2466
+ setMailbox(mailbox) {
2467
+ this._mailbox = mailbox;
2468
+ }
2469
+
2470
+ /**
2471
+ * Gets the default mailbox name for datagrams sent using this socket.
2472
+ * @returns {string|null} - mailbox name, or null if not set
2473
+ */
2474
+ getMailbox() {
2475
+ return this._mailbox;
2476
+ }
2477
+
2478
+ /**
2479
+ * Sets the default application message class for datagrams sent using this socket.
2480
+ * Used by REMOTE service providers to associate a fully-qualified class name with the payload.
2481
+ * @param {string} messageClass - fully-qualified message class name (e.g. 'org.example.Status')
2482
+ * @returns {void}
2483
+ */
2484
+ setMessageClass(messageClass) {
2485
+ this._messageClass = messageClass;
2486
+ }
2487
+
2488
+ /**
2489
+ * Gets the default application message class for datagrams sent using this socket.
2490
+ * @returns {string|null} - message class name, or null if not set
2491
+ */
2492
+ getMessageClass() {
2493
+ return this._messageClass;
2494
+ }
2495
+
2496
+ /**
2497
+ * Overrides the service provider used to transmit datagrams. When set, provider
2498
+ * auto-selection is bypassed and all sends go through the specified agent.
2499
+ * Pass null to re-enable auto-selection.
2500
+ * @param {AgentID|string|null} provider - agent id, agent name string, or null to clear the override
2501
+ * @returns {void}
2502
+ */
2503
+ setServiceProvider(provider) {
2504
+ if (typeof provider === 'string') provider = this.agent(provider);
2505
+ this._serviceProvider = provider instanceof AgentID || provider == null ? provider : null;
2506
+ }
2507
+
2508
+ /**
2509
+ * Gets the currently configured service provider override.
2510
+ * @returns {AgentID|null} - the override agent id, or null if auto-selection is active
2511
+ */
2512
+ getServiceProvider() {
2513
+ return this._serviceProvider;
2514
+ }
2515
+
2516
+ /**
2517
+ * Sets the send mode that controls how send() behaves after the provider accepts a request:
2518
+ * - `UnetSocket.NON_BLOCKING` (0): returns immediately after the provider agrees.
2519
+ * - `UnetSocket.SEMI_BLOCKING` (1): if reliability is not true, returns after AGREE; otherwise
2520
+ * waits for a delivery confirmation (RemoteDeliveryNtf / DatagramDeliveryNtf) or failure.
2521
+ * - `UnetSocket.BLOCKING` (2): waits for a transmission or delivery notification
2522
+ * (DatagramTransmissionNtf, DatagramDeliveryNtf) before returning.
2523
+ * The default is SEMI_BLOCKING.
2524
+ * @param {number} sendMode - one of UnetSocket.NON_BLOCKING, SEMI_BLOCKING, or BLOCKING
2525
+ * @returns {void}
2526
+ */
2527
+ setSendMode(sendMode) {
2528
+ if ([NON_BLOCKING, SEMI_BLOCKING, BLOCKING].includes(sendMode)) this._sendMode = sendMode;
2529
+ }
2530
+
2531
+ /**
2532
+ * Gets the current send mode.
2533
+ * @returns {number} - current send mode (NON_BLOCKING=0, SEMI_BLOCKING=1, BLOCKING=2)
2534
+ */
2535
+ getSendMode() {
2536
+ return this._sendMode;
2537
+ }
2538
+
2539
+ async _chooseAgentForService(service) {
2540
+ const agents = await this._gw.agentsForService(service);
2541
+ if (agents == null || agents.length === 0) return null;
2542
+ return agents[Math.floor(Math.random() * agents.length)];
2543
+ }
2544
+
2545
+ async _resolveProvider() {
2546
+ if (this._serviceProvider != null) return this._serviceProvider;
2547
+ const serviceOrder = [
2548
+ Services.REMOTE,
2549
+ Services.TRANSPORT,
2550
+ Services.ROUTING,
2551
+ Services.LINK,
2552
+ Services.PHYSICAL,
2553
+ Services.DATAGRAM,
2554
+ ];
2555
+ for (const service of serviceOrder) {
2556
+ const provider = await this._chooseAgentForService(service);
2557
+ if (provider != null) return provider;
2558
+ }
2559
+ return null;
2560
+ }
2561
+
2562
+ _applySocketSettings(req) {
2563
+ if (!hasValue(req.priority) && hasValue(this._priority)) req.priority = this._priority;
2564
+ if (!hasValue(req.reliability) && hasValue(this._reliability)) req.reliability = this._reliability;
2565
+ if ((!hasValue(req.ttl) || Number.isNaN(req.ttl)) && hasFiniteNumber(this._ttl)) req.ttl = this._ttl;
2566
+ if (!hasValue(req.route) && hasValue(this._route)) req.route = this._route;
2567
+ if (!hasValue(req.mimeType) && hasValue(this._mimeType)) req.mimeType = this._mimeType;
2568
+ if (!hasValue(req.remoteRecipient) && hasValue(this._remoteRecipient)) req.remoteRecipient = this._remoteRecipient;
2569
+ if (!hasValue(req.mailbox) && hasValue(this._mailbox)) req.mailbox = this._mailbox;
2570
+ if (!hasValue(req.messageClass) && hasValue(this._messageClass)) req.messageClass = this._messageClass;
2571
+ }
2572
+
2573
+ _effectiveReliability(req) {
2574
+ return hasValue(req.reliability) ? req.reliability : this._reliability;
2575
+ }
2576
+
2577
+ async _waitForNotification(req, types, timeout = REQUEST_TIMEOUT) {
2578
+ return await this._gw.receive(msg => {
2579
+ if (!types.some(type => msg instanceof type)) return false;
2580
+ if (hasValue(msg.inReplyTo) && msg.inReplyTo === req.msgID) return true;
2581
+ return false;
2582
+ }, timeout);
2583
+ }
2584
+
2585
+ async _waitForSemiBlockingOutcome(req) {
2586
+ const notification = await this._waitForNotification(req, [
2587
+ DatagramDeliveryNtf,
2588
+ DatagramFailureNtf,
2589
+ RemoteDeliveryNtf,
2590
+ RemoteSuccessNtf,
2591
+ RemoteFailureNtf,
2592
+ ]);
2593
+ if (notification == null) return false;
2594
+ if (notification instanceof DatagramFailureNtf || notification instanceof RemoteFailureNtf) return false;
2595
+ return true;
2596
+ }
2597
+
2598
+ async _waitForBlockingOutcome(req) {
2599
+ const notification = await this._waitForNotification(req, [
2600
+ DatagramTransmissionNtf,
2601
+ DatagramDeliveryNtf,
2602
+ DatagramFailureNtf,
2603
+ RemoteDeliveryNtf,
2604
+ RemoteSuccessNtf,
2605
+ RemoteFailureNtf,
2606
+ ]);
2607
+ if (notification == null) return false;
2608
+ if (notification instanceof DatagramFailureNtf || notification instanceof RemoteFailureNtf) return false;
2609
+ return true;
2610
+ }
2446
2611
 
2447
2612
  /**
2448
2613
  * Transmits a datagram to the specified node address using the specified protocol.
@@ -2453,32 +2618,43 @@ class UnetSocket {
2453
2618
  * @param {number} protocol - protocol number
2454
2619
  * @returns {Promise<boolean>} - true if the Unet node agreed to send out the Datagram, false otherwise
2455
2620
  */
2456
- async send(data, to=this.remoteAddress, protocol=this.remoteProtocol) {
2457
- if (to < 0 || this.gw == null) return false;
2458
- var req;
2459
- if (Array.isArray(data)){
2621
+ async send(data, to=this._remoteAddress, protocol=this._remoteProtocol) {
2622
+ if (this._gw == null) return false;
2623
+ let req;
2624
+ if (Array.isArray(data)) {
2460
2625
  req = new DatagramReq();
2461
2626
  req.data = data;
2462
2627
  req.to = to;
2463
2628
  req.protocol = protocol;
2464
- } else if (data instanceof DatagramReq){
2629
+ } else if (data instanceof DatagramReq) {
2465
2630
  req = data;
2631
+ if (!this._warnedDeprecatedSend && typeof console !== 'undefined' && typeof console.warn === 'function') {
2632
+ console.warn('UnetSocket.send(DatagramReq) is deprecated; prefer socket metadata setters with send(data, to, protocol).');
2633
+ this._warnedDeprecatedSend = true;
2634
+ }
2466
2635
  } else {
2467
2636
  return false;
2468
2637
  }
2469
- let p = req.protocol;
2470
- if (p != Protocol.DATA && (p < Protocol.USER || p > Protocol.MAX)) return false;
2638
+ if ((!hasValue(req.to) || req.to < 0) && to >= 0) req.to = to;
2639
+ if (!hasValue(req.protocol)) req.protocol = protocol;
2640
+ this._applySocketSettings(req);
2641
+
2642
+ if (!Array.isArray(req.data) || req.to < 0 || isReservedProtocol(req.protocol)) return false;
2471
2643
  if (req.recipient == null) {
2472
- if (this.provider == null) this.provider = await this.gw.agentForService(Services.TRANSPORT);
2473
- if (this.provider == null) this.provider = await this.gw.agentForService(Services.ROUTING);
2474
- if (this.provider == null) this.provider = await this.gw.agentForService(Services.LINK);
2475
- if (this.provider == null) this.provider = await this.gw.agentForService(Services.PHYSICAL);
2476
- if (this.provider == null) this.provider = await this.gw.agentForService(Services.DATAGRAM);
2477
- if (this.provider == null) return false;
2478
- req.recipient = this.provider;
2644
+ req.recipient = await this._resolveProvider();
2645
+ if (req.recipient == null) return false;
2479
2646
  }
2480
- const rsp = await this.gw.request(req, REQUEST_TIMEOUT);
2481
- return (rsp != null && rsp.perf == Performative.AGREE);
2647
+ const rsp = await this._gw.request(req, REQUEST_TIMEOUT);
2648
+ if (rsp == null || rsp.perf != Performative.AGREE) return false;
2649
+
2650
+ if (this._sendMode === NON_BLOCKING) return true;
2651
+
2652
+ if (this._sendMode === SEMI_BLOCKING) {
2653
+ if (this._effectiveReliability(req) !== true) return true;
2654
+ return await this._waitForSemiBlockingOutcome(req);
2655
+ }
2656
+
2657
+ return await this._waitForBlockingOutcome(req);
2482
2658
  }
2483
2659
 
2484
2660
  /**
@@ -2488,22 +2664,23 @@ class UnetSocket {
2488
2664
  * @returns {Promise<?DatagramNtf>} - datagram received by the socket
2489
2665
  */
2490
2666
  async receive() {
2491
- if (this.gw == null) return null;
2492
- return await this.gw.receive(msg => {
2493
- if (msg.__clazz__ != DatagramNtf.__clazz__ && msg.__clazz__ != RxFrameNtf.__clazz__ ) return false;
2667
+ if (this._gw == null) return null;
2668
+ return await this._gw.receive(msg => {
2669
+ if (!(msg instanceof DatagramNtf)) return false;
2494
2670
  let p = msg.protocol;
2671
+ if (msg.to != BROADCAST_ADDR && msg.to != this._localAddress) return false; // Datagram not addressed to this node
2495
2672
  if (p == Protocol.DATA || p >= Protocol.USER) {
2496
- return this.localProtocol < 0 || this.localProtocol == p;
2673
+ return this._localProtocol < 0 || this._localProtocol == p;
2497
2674
  }
2498
2675
  return false;
2499
- }, this.timeout);
2676
+ }, this._timeout);
2500
2677
  }
2501
2678
 
2502
2679
  /**
2503
2680
  * Gets a Gateway to provide low-level access to UnetStack.
2504
2681
  * @returns {Gateway} - underlying fjage Gateway supporting this socket
2505
2682
  */
2506
- getGateway() { return this.gw; }
2683
+ getGateway() { return this._gw; }
2507
2684
 
2508
2685
  /**
2509
2686
  * Gets an AgentID providing a specified service for low-level access to UnetStack
@@ -2511,8 +2688,8 @@ class UnetSocket {
2511
2688
  * @returns {Promise<?AgentID>} - a promise which returns an {@link AgentID} that provides the service when resolved
2512
2689
  */
2513
2690
  async agentForService(svc) {
2514
- if (this.gw == null) return null;
2515
- return await this.gw.agentForService(svc);
2691
+ if (this._gw == null) return null;
2692
+ return await this._gw.agentForService(svc);
2516
2693
  }
2517
2694
 
2518
2695
  /**
@@ -2521,8 +2698,8 @@ class UnetSocket {
2521
2698
  * @returns {Promise<AgentID[]>} - a promise which returns an array of {@link AgentID|AgentIDs} that provides the service when resolved
2522
2699
  */
2523
2700
  async agentsForService(svc) {
2524
- if (this.gw == null) return null;
2525
- return await this.gw.agentsForService(svc);
2701
+ if (this._gw == null) return null;
2702
+ return await this._gw.agentsForService(svc);
2526
2703
  }
2527
2704
 
2528
2705
  /**
@@ -2531,8 +2708,8 @@ class UnetSocket {
2531
2708
  * @returns {AgentID} - AgentID for the given name
2532
2709
  */
2533
2710
  agent(name) {
2534
- if (this.gw == null) return null;
2535
- return this.gw.agent(name);
2711
+ if (this._gw == null) return null;
2712
+ return this._gw.agent(name);
2536
2713
  }
2537
2714
 
2538
2715
  /**
@@ -2546,15 +2723,42 @@ class UnetSocket {
2546
2723
  const req = new AddressResolutionReq(nodeName);
2547
2724
  req.name = nodeName;
2548
2725
  req.recipient = arp;
2549
- const rsp = await this.gw.request(req, REQUEST_TIMEOUT);
2726
+ const rsp = await this._gw.request(req, REQUEST_TIMEOUT);
2550
2727
  if (rsp == null || ! Object.prototype.hasOwnProperty.call(rsp, 'address')) return null;
2551
2728
  return rsp.address;
2552
2729
  }
2730
+
2731
+ /**
2732
+ * Registers a callback function to be called when a parameter value changes for the local node. This
2733
+ * uses the ParamChangeNtf messages published by the Unet node to notify of parameter changes. The callback
2734
+ * function will be called with the new value of the parameter.
2735
+ *
2736
+ * @param {AgentID|string} agentId
2737
+ * @param {string} paramName
2738
+ * @param {function(object): void} callback
2739
+ */
2740
+ onParamChange(agentId, paramName, callback) {
2741
+ if (agentId instanceof AgentID) agentId = agentId.name;
2742
+ this._paramChangeCallbacks[agentId + '.' + paramName] = callback;
2743
+ }
2744
+
2745
+ /**
2746
+ * Removes a callback function registered to be called when a parameter value changes for the local node.
2747
+ *
2748
+ * @param {AgentID|string} agentId
2749
+ * @param {string} paramName
2750
+ */
2751
+ removeParamChange(agentId, paramName) {
2752
+ if (agentId instanceof AgentID) agentId = agentId.name;
2753
+ delete this._paramChangeCallbacks[agentId + '.' + paramName];
2754
+ }
2553
2755
  }
2554
2756
 
2757
+ UnetSocket.NON_BLOCKING = NON_BLOCKING;
2758
+ UnetSocket.SEMI_BLOCKING = SEMI_BLOCKING;
2759
+ UnetSocket.BLOCKING = BLOCKING;
2760
+
2555
2761
  exports.AgentID = AgentID;
2556
- exports.CachingAgentID = CachingAgentID;
2557
- exports.CachingGateway = CachingGateway;
2558
2762
  exports.Gateway = Gateway;
2559
2763
  exports.Message = Message;
2560
2764
  exports.MessageClass = MessageClass;
@@ -2563,5 +2767,6 @@ exports.Protocol = Protocol;
2563
2767
  exports.Services = Services;
2564
2768
  exports.UnetMessages = UnetMessages;
2565
2769
  exports.UnetSocket = UnetSocket;
2770
+ exports.UnetTopics = UnetTopics;
2566
2771
  exports.toGps = toGps;
2567
2772
  exports.toLocal = toLocal;