@solana/web3.js 1.92.2 → 1.93.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/lib/index.browser.cjs.js +3 -6
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +3 -4
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +3 -6
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.esm.js +3 -4
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +349 -414
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +1 -1
- package/lib/index.iife.min.js.map +1 -1
- package/lib/index.native.js +3 -6
- package/lib/index.native.js.map +1 -1
- package/package.json +3 -3
- package/src/rpc-websocket.ts +9 -13
- package/src/__forks__/browser/rpc-websocket-factory.ts +0 -1
- package/src/__forks__/react-native/rpc-websocket-factory.ts +0 -1
- package/src/rpc-websocket-factory.ts +0 -4
package/lib/index.iife.js
CHANGED
|
@@ -16193,8 +16193,6 @@ var solanaWeb3 = (function (exports) {
|
|
|
16193
16193
|
|
|
16194
16194
|
var fetchImpl = globalThis.fetch;
|
|
16195
16195
|
|
|
16196
|
-
var client = {};
|
|
16197
|
-
|
|
16198
16196
|
var eventemitter3 = {exports: {}};
|
|
16199
16197
|
|
|
16200
16198
|
(function (module) {
|
|
@@ -16537,429 +16535,366 @@ var solanaWeb3 = (function (exports) {
|
|
|
16537
16535
|
|
|
16538
16536
|
var eventemitter3Exports = eventemitter3.exports;
|
|
16539
16537
|
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
}
|
|
16559
|
-
decode(value) {
|
|
16560
|
-
return JSON.parse(value);
|
|
16561
|
-
}
|
|
16562
|
-
}
|
|
16563
|
-
utils.DefaultDataPack = DefaultDataPack;
|
|
16564
|
-
/**
|
|
16565
|
-
* Creates a JSON-RPC 2.0-compliant error.
|
|
16566
|
-
* @param {Number} code - error code
|
|
16567
|
-
* @param {String} details - error details
|
|
16568
|
-
* @return {Object}
|
|
16569
|
-
*/
|
|
16570
|
-
function createError(code, details) {
|
|
16571
|
-
const error = {
|
|
16572
|
-
code: code,
|
|
16573
|
-
message: errors.get(code) || "Internal Server Error"
|
|
16538
|
+
// node_modules/esbuild-plugin-polyfill-node/polyfills/buffer.js
|
|
16539
|
+
var WebSocketBrowserImpl = class extends eventemitter3Exports.EventEmitter {
|
|
16540
|
+
socket;
|
|
16541
|
+
/** Instantiate a WebSocket class
|
|
16542
|
+
* @constructor
|
|
16543
|
+
* @param {String} address - url to a websocket server
|
|
16544
|
+
* @param {(Object)} options - websocket options
|
|
16545
|
+
* @param {(String|Array)} protocols - a list of protocols
|
|
16546
|
+
* @return {WebSocketBrowserImpl} - returns a WebSocket instance
|
|
16547
|
+
*/
|
|
16548
|
+
constructor(address, options, protocols) {
|
|
16549
|
+
super();
|
|
16550
|
+
this.socket = new window.WebSocket(address, protocols);
|
|
16551
|
+
this.socket.onopen = () => this.emit("open");
|
|
16552
|
+
this.socket.onmessage = (event) => this.emit("message", event.data);
|
|
16553
|
+
this.socket.onerror = (error) => this.emit("error", error);
|
|
16554
|
+
this.socket.onclose = (event) => {
|
|
16555
|
+
this.emit("close", event.code, event.reason);
|
|
16574
16556
|
};
|
|
16575
|
-
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
|
|
16581
|
-
|
|
16582
|
-
|
|
16583
|
-
|
|
16584
|
-
|
|
16585
|
-
|
|
16586
|
-
|
|
16587
|
-
|
|
16588
|
-
|
|
16589
|
-
|
|
16590
|
-
|
|
16591
|
-
address;
|
|
16592
|
-
rpc_id;
|
|
16593
|
-
queue;
|
|
16594
|
-
options;
|
|
16595
|
-
autoconnect;
|
|
16596
|
-
ready;
|
|
16597
|
-
reconnect;
|
|
16598
|
-
reconnect_timer_id;
|
|
16599
|
-
reconnect_interval;
|
|
16600
|
-
max_reconnects;
|
|
16601
|
-
rest_options;
|
|
16602
|
-
current_reconnects;
|
|
16603
|
-
generate_request_id;
|
|
16604
|
-
socket;
|
|
16605
|
-
webSocketFactory;
|
|
16606
|
-
dataPack;
|
|
16607
|
-
/**
|
|
16608
|
-
* Instantiate a Client class.
|
|
16609
|
-
* @constructor
|
|
16610
|
-
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
|
|
16611
|
-
* @param {String} address - url to a websocket server
|
|
16612
|
-
* @param {Object} options - ws options object with reconnect parameters
|
|
16613
|
-
* @param {Function} generate_request_id - custom generation request Id
|
|
16614
|
-
* @param {DataPack} dataPack - data pack contains encoder and decoder
|
|
16615
|
-
* @return {CommonClient}
|
|
16616
|
-
*/
|
|
16617
|
-
constructor(webSocketFactory, address = "ws://localhost:8080", { autoconnect = true, reconnect = true, reconnect_interval = 1000, max_reconnects = 5, ...rest_options } = {}, generate_request_id, dataPack) {
|
|
16618
|
-
super();
|
|
16619
|
-
this.webSocketFactory = webSocketFactory;
|
|
16620
|
-
this.queue = {};
|
|
16621
|
-
this.rpc_id = 0;
|
|
16622
|
-
this.address = address;
|
|
16623
|
-
this.autoconnect = autoconnect;
|
|
16624
|
-
this.ready = false;
|
|
16625
|
-
this.reconnect = reconnect;
|
|
16626
|
-
this.reconnect_timer_id = undefined;
|
|
16627
|
-
this.reconnect_interval = reconnect_interval;
|
|
16628
|
-
this.max_reconnects = max_reconnects;
|
|
16629
|
-
this.rest_options = rest_options;
|
|
16630
|
-
this.current_reconnects = 0;
|
|
16631
|
-
this.generate_request_id = generate_request_id || (() => ++this.rpc_id);
|
|
16632
|
-
if (!dataPack)
|
|
16633
|
-
this.dataPack = new utils_cjs_1.DefaultDataPack();
|
|
16634
|
-
else
|
|
16635
|
-
this.dataPack = dataPack;
|
|
16636
|
-
if (this.autoconnect)
|
|
16637
|
-
this._connect(this.address, {
|
|
16638
|
-
autoconnect: this.autoconnect,
|
|
16639
|
-
reconnect: this.reconnect,
|
|
16640
|
-
reconnect_interval: this.reconnect_interval,
|
|
16641
|
-
max_reconnects: this.max_reconnects,
|
|
16642
|
-
...this.rest_options
|
|
16643
|
-
});
|
|
16644
|
-
}
|
|
16645
|
-
/**
|
|
16646
|
-
* Connects to a defined server if not connected already.
|
|
16647
|
-
* @method
|
|
16648
|
-
* @return {Undefined}
|
|
16649
|
-
*/
|
|
16650
|
-
connect() {
|
|
16651
|
-
if (this.socket)
|
|
16652
|
-
return;
|
|
16653
|
-
this._connect(this.address, {
|
|
16654
|
-
autoconnect: this.autoconnect,
|
|
16655
|
-
reconnect: this.reconnect,
|
|
16656
|
-
reconnect_interval: this.reconnect_interval,
|
|
16657
|
-
max_reconnects: this.max_reconnects,
|
|
16658
|
-
...this.rest_options
|
|
16659
|
-
});
|
|
16660
|
-
}
|
|
16661
|
-
/**
|
|
16662
|
-
* Calls a registered RPC method on server.
|
|
16663
|
-
* @method
|
|
16664
|
-
* @param {String} method - RPC method name
|
|
16665
|
-
* @param {Object|Array} params - optional method parameters
|
|
16666
|
-
* @param {Number} timeout - RPC reply timeout value
|
|
16667
|
-
* @param {Object} ws_opts - options passed to ws
|
|
16668
|
-
* @return {Promise}
|
|
16669
|
-
*/
|
|
16670
|
-
call(method, params, timeout, ws_opts) {
|
|
16671
|
-
if (!ws_opts && "object" === typeof timeout) {
|
|
16672
|
-
ws_opts = timeout;
|
|
16673
|
-
timeout = null;
|
|
16674
|
-
}
|
|
16675
|
-
return new Promise((resolve, reject) => {
|
|
16676
|
-
if (!this.ready)
|
|
16677
|
-
return reject(new Error("socket not ready"));
|
|
16678
|
-
const rpc_id = this.generate_request_id(method, params);
|
|
16679
|
-
const message = {
|
|
16680
|
-
jsonrpc: "2.0",
|
|
16681
|
-
method: method,
|
|
16682
|
-
params: params || undefined,
|
|
16683
|
-
id: rpc_id
|
|
16684
|
-
};
|
|
16685
|
-
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => {
|
|
16686
|
-
if (error)
|
|
16687
|
-
return reject(error);
|
|
16688
|
-
this.queue[rpc_id] = { promise: [resolve, reject] };
|
|
16689
|
-
if (timeout) {
|
|
16690
|
-
this.queue[rpc_id].timeout = setTimeout(() => {
|
|
16691
|
-
delete this.queue[rpc_id];
|
|
16692
|
-
reject(new Error("reply timeout"));
|
|
16693
|
-
}, timeout);
|
|
16694
|
-
}
|
|
16695
|
-
});
|
|
16696
|
-
});
|
|
16697
|
-
}
|
|
16698
|
-
/**
|
|
16699
|
-
* Logins with the other side of the connection.
|
|
16700
|
-
* @method
|
|
16701
|
-
* @param {Object} params - Login credentials object
|
|
16702
|
-
* @return {Promise}
|
|
16703
|
-
*/
|
|
16704
|
-
async login(params) {
|
|
16705
|
-
const resp = await this.call("rpc.login", params);
|
|
16706
|
-
if (!resp)
|
|
16707
|
-
throw new Error("authentication failed");
|
|
16708
|
-
return resp;
|
|
16709
|
-
}
|
|
16710
|
-
/**
|
|
16711
|
-
* Fetches a list of client's methods registered on server.
|
|
16712
|
-
* @method
|
|
16713
|
-
* @return {Array}
|
|
16714
|
-
*/
|
|
16715
|
-
async listMethods() {
|
|
16716
|
-
return await this.call("__listMethods");
|
|
16717
|
-
}
|
|
16718
|
-
/**
|
|
16719
|
-
* Sends a JSON-RPC 2.0 notification to server.
|
|
16720
|
-
* @method
|
|
16721
|
-
* @param {String} method - RPC method name
|
|
16722
|
-
* @param {Object} params - optional method parameters
|
|
16723
|
-
* @return {Promise}
|
|
16724
|
-
*/
|
|
16725
|
-
notify(method, params) {
|
|
16726
|
-
return new Promise((resolve, reject) => {
|
|
16727
|
-
if (!this.ready)
|
|
16728
|
-
return reject(new Error("socket not ready"));
|
|
16729
|
-
const message = {
|
|
16730
|
-
jsonrpc: "2.0",
|
|
16731
|
-
method: method,
|
|
16732
|
-
params
|
|
16733
|
-
};
|
|
16734
|
-
this.socket.send(this.dataPack.encode(message), (error) => {
|
|
16735
|
-
if (error)
|
|
16736
|
-
return reject(error);
|
|
16737
|
-
resolve();
|
|
16738
|
-
});
|
|
16739
|
-
});
|
|
16740
|
-
}
|
|
16741
|
-
/**
|
|
16742
|
-
* Subscribes for a defined event.
|
|
16743
|
-
* @method
|
|
16744
|
-
* @param {String|Array} event - event name
|
|
16745
|
-
* @return {Undefined}
|
|
16746
|
-
* @throws {Error}
|
|
16747
|
-
*/
|
|
16748
|
-
async subscribe(event) {
|
|
16749
|
-
if (typeof event === "string")
|
|
16750
|
-
event = [event];
|
|
16751
|
-
const result = await this.call("rpc.on", event);
|
|
16752
|
-
if (typeof event === "string" && result[event] !== "ok")
|
|
16753
|
-
throw new Error("Failed subscribing to an event '" + event + "' with: " + result[event]);
|
|
16754
|
-
return result;
|
|
16755
|
-
}
|
|
16756
|
-
/**
|
|
16757
|
-
* Unsubscribes from a defined event.
|
|
16758
|
-
* @method
|
|
16759
|
-
* @param {String|Array} event - event name
|
|
16760
|
-
* @return {Undefined}
|
|
16761
|
-
* @throws {Error}
|
|
16762
|
-
*/
|
|
16763
|
-
async unsubscribe(event) {
|
|
16764
|
-
if (typeof event === "string")
|
|
16765
|
-
event = [event];
|
|
16766
|
-
const result = await this.call("rpc.off", event);
|
|
16767
|
-
if (typeof event === "string" && result[event] !== "ok")
|
|
16768
|
-
throw new Error("Failed unsubscribing from an event with: " + result);
|
|
16769
|
-
return result;
|
|
16770
|
-
}
|
|
16771
|
-
/**
|
|
16772
|
-
* Closes a WebSocket connection gracefully.
|
|
16773
|
-
* @method
|
|
16774
|
-
* @param {Number} code - socket close code
|
|
16775
|
-
* @param {String} data - optional data to be sent before closing
|
|
16776
|
-
* @return {Undefined}
|
|
16777
|
-
*/
|
|
16778
|
-
close(code, data) {
|
|
16779
|
-
this.socket.close(code || 1000, data);
|
|
16780
|
-
}
|
|
16781
|
-
/**
|
|
16782
|
-
* Enable / disable automatic reconnection.
|
|
16783
|
-
* @method
|
|
16784
|
-
* @param {Boolean} reconnect - enable / disable reconnection
|
|
16785
|
-
* @return {Undefined}
|
|
16786
|
-
*/
|
|
16787
|
-
setAutoReconnect(reconnect) {
|
|
16788
|
-
this.reconnect = reconnect;
|
|
16789
|
-
}
|
|
16790
|
-
/**
|
|
16791
|
-
* Set the interval between reconnection attempts.
|
|
16792
|
-
* @method
|
|
16793
|
-
* @param {Number} interval - reconnection interval in milliseconds
|
|
16794
|
-
* @return {Undefined}
|
|
16795
|
-
*/
|
|
16796
|
-
setReconnectInterval(interval) {
|
|
16797
|
-
this.reconnect_interval = interval;
|
|
16798
|
-
}
|
|
16799
|
-
/**
|
|
16800
|
-
* Set the maximum number of reconnection attempts.
|
|
16801
|
-
* @method
|
|
16802
|
-
* @param {Number} max_reconnects - maximum reconnection attempts
|
|
16803
|
-
* @return {Undefined}
|
|
16804
|
-
*/
|
|
16805
|
-
setMaxReconnects(max_reconnects) {
|
|
16806
|
-
this.max_reconnects = max_reconnects;
|
|
16807
|
-
}
|
|
16808
|
-
/**
|
|
16809
|
-
* Connection/Message handler.
|
|
16810
|
-
* @method
|
|
16811
|
-
* @private
|
|
16812
|
-
* @param {String} address - WebSocket API address
|
|
16813
|
-
* @param {Object} options - ws options object
|
|
16814
|
-
* @return {Undefined}
|
|
16815
|
-
*/
|
|
16816
|
-
_connect(address, options) {
|
|
16817
|
-
clearTimeout(this.reconnect_timer_id);
|
|
16818
|
-
this.socket = this.webSocketFactory(address, options);
|
|
16819
|
-
this.socket.addEventListener("open", () => {
|
|
16820
|
-
this.ready = true;
|
|
16821
|
-
this.emit("open");
|
|
16822
|
-
this.current_reconnects = 0;
|
|
16823
|
-
});
|
|
16824
|
-
this.socket.addEventListener("message", ({ data: message }) => {
|
|
16825
|
-
if (message instanceof ArrayBuffer)
|
|
16826
|
-
message = Buffer.from(message).toString();
|
|
16827
|
-
try {
|
|
16828
|
-
message = this.dataPack.decode(message);
|
|
16829
|
-
}
|
|
16830
|
-
catch (error) {
|
|
16831
|
-
return;
|
|
16832
|
-
}
|
|
16833
|
-
// check if any listeners are attached and forward event
|
|
16834
|
-
if (message.notification && this.listeners(message.notification).length) {
|
|
16835
|
-
if (!Object.keys(message.params).length)
|
|
16836
|
-
return this.emit(message.notification);
|
|
16837
|
-
const args = [message.notification];
|
|
16838
|
-
if (message.params.constructor === Object)
|
|
16839
|
-
args.push(message.params);
|
|
16840
|
-
else
|
|
16841
|
-
// using for-loop instead of unshift/spread because performance is better
|
|
16842
|
-
for (let i = 0; i < message.params.length; i++)
|
|
16843
|
-
args.push(message.params[i]);
|
|
16844
|
-
// run as microtask so that pending queue messages are resolved first
|
|
16845
|
-
// eslint-disable-next-line prefer-spread
|
|
16846
|
-
return Promise.resolve().then(() => { this.emit.apply(this, args); });
|
|
16847
|
-
}
|
|
16848
|
-
if (!this.queue[message.id]) {
|
|
16849
|
-
// general JSON RPC 2.0 events
|
|
16850
|
-
if (message.method) {
|
|
16851
|
-
// run as microtask so that pending queue messages are resolved first
|
|
16852
|
-
return Promise.resolve().then(() => {
|
|
16853
|
-
this.emit(message.method, message?.params);
|
|
16854
|
-
});
|
|
16855
|
-
}
|
|
16856
|
-
return;
|
|
16857
|
-
}
|
|
16858
|
-
// reject early since server's response is invalid
|
|
16859
|
-
if ("error" in message === "result" in message)
|
|
16860
|
-
this.queue[message.id].promise[1](new Error("Server response malformed. Response must include either \"result\"" +
|
|
16861
|
-
" or \"error\", but not both."));
|
|
16862
|
-
if (this.queue[message.id].timeout)
|
|
16863
|
-
clearTimeout(this.queue[message.id].timeout);
|
|
16864
|
-
if (message.error)
|
|
16865
|
-
this.queue[message.id].promise[1](message.error);
|
|
16866
|
-
else
|
|
16867
|
-
this.queue[message.id].promise[0](message.result);
|
|
16868
|
-
delete this.queue[message.id];
|
|
16869
|
-
});
|
|
16870
|
-
this.socket.addEventListener("error", (error) => this.emit("error", error));
|
|
16871
|
-
this.socket.addEventListener("close", ({ code, reason }) => {
|
|
16872
|
-
if (this.ready) // Delay close event until internal state is updated
|
|
16873
|
-
setTimeout(() => this.emit("close", code, reason), 0);
|
|
16874
|
-
this.ready = false;
|
|
16875
|
-
this.socket = undefined;
|
|
16876
|
-
if (code === 1000)
|
|
16877
|
-
return;
|
|
16878
|
-
this.current_reconnects++;
|
|
16879
|
-
if (this.reconnect && ((this.max_reconnects > this.current_reconnects) ||
|
|
16880
|
-
this.max_reconnects === 0))
|
|
16881
|
-
this.reconnect_timer_id = setTimeout(() => this._connect(address, options), this.reconnect_interval);
|
|
16882
|
-
});
|
|
16557
|
+
}
|
|
16558
|
+
/**
|
|
16559
|
+
* Sends data through a websocket connection
|
|
16560
|
+
* @method
|
|
16561
|
+
* @param {(String|Object)} data - data to be sent via websocket
|
|
16562
|
+
* @param {Object} optionsOrCallback - ws options
|
|
16563
|
+
* @param {Function} callback - a callback called once the data is sent
|
|
16564
|
+
* @return {Undefined}
|
|
16565
|
+
*/
|
|
16566
|
+
send(data, optionsOrCallback, callback) {
|
|
16567
|
+
const cb = callback || optionsOrCallback;
|
|
16568
|
+
try {
|
|
16569
|
+
this.socket.send(data);
|
|
16570
|
+
cb();
|
|
16571
|
+
} catch (error) {
|
|
16572
|
+
cb(error);
|
|
16883
16573
|
}
|
|
16574
|
+
}
|
|
16575
|
+
/**
|
|
16576
|
+
* Closes an underlying socket
|
|
16577
|
+
* @method
|
|
16578
|
+
* @param {Number} code - status code explaining why the connection is being closed
|
|
16579
|
+
* @param {String} reason - a description why the connection is closing
|
|
16580
|
+
* @return {Undefined}
|
|
16581
|
+
* @throws {Error}
|
|
16582
|
+
*/
|
|
16583
|
+
close(code, reason) {
|
|
16584
|
+
this.socket.close(code, reason);
|
|
16585
|
+
}
|
|
16586
|
+
addEventListener(type, listener, options) {
|
|
16587
|
+
this.socket.addEventListener(type, listener, options);
|
|
16588
|
+
}
|
|
16589
|
+
};
|
|
16590
|
+
function WebSocket(address, options) {
|
|
16591
|
+
return new WebSocketBrowserImpl(address, options);
|
|
16884
16592
|
}
|
|
16885
|
-
var _default$1 = client.default = CommonClient;
|
|
16886
16593
|
|
|
16887
|
-
|
|
16594
|
+
// src/lib/utils.ts
|
|
16595
|
+
var DefaultDataPack = class {
|
|
16596
|
+
encode(value) {
|
|
16597
|
+
return JSON.stringify(value);
|
|
16598
|
+
}
|
|
16599
|
+
decode(value) {
|
|
16600
|
+
return JSON.parse(value);
|
|
16601
|
+
}
|
|
16602
|
+
};
|
|
16888
16603
|
|
|
16889
|
-
|
|
16890
|
-
|
|
16891
|
-
|
|
16892
|
-
|
|
16893
|
-
|
|
16894
|
-
|
|
16895
|
-
|
|
16896
|
-
|
|
16897
|
-
|
|
16898
|
-
|
|
16899
|
-
|
|
16900
|
-
|
|
16901
|
-
|
|
16902
|
-
|
|
16903
|
-
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16604
|
+
// src/lib/client.ts
|
|
16605
|
+
var CommonClient = class extends eventemitter3Exports.EventEmitter {
|
|
16606
|
+
address;
|
|
16607
|
+
rpc_id;
|
|
16608
|
+
queue;
|
|
16609
|
+
options;
|
|
16610
|
+
autoconnect;
|
|
16611
|
+
ready;
|
|
16612
|
+
reconnect;
|
|
16613
|
+
reconnect_timer_id;
|
|
16614
|
+
reconnect_interval;
|
|
16615
|
+
max_reconnects;
|
|
16616
|
+
rest_options;
|
|
16617
|
+
current_reconnects;
|
|
16618
|
+
generate_request_id;
|
|
16619
|
+
socket;
|
|
16620
|
+
webSocketFactory;
|
|
16621
|
+
dataPack;
|
|
16622
|
+
/**
|
|
16623
|
+
* Instantiate a Client class.
|
|
16624
|
+
* @constructor
|
|
16625
|
+
* @param {webSocketFactory} webSocketFactory - factory method for WebSocket
|
|
16626
|
+
* @param {String} address - url to a websocket server
|
|
16627
|
+
* @param {Object} options - ws options object with reconnect parameters
|
|
16628
|
+
* @param {Function} generate_request_id - custom generation request Id
|
|
16629
|
+
* @param {DataPack} dataPack - data pack contains encoder and decoder
|
|
16630
|
+
* @return {CommonClient}
|
|
16631
|
+
*/
|
|
16632
|
+
constructor(webSocketFactory, address = "ws://localhost:8080", {
|
|
16633
|
+
autoconnect = true,
|
|
16634
|
+
reconnect = true,
|
|
16635
|
+
reconnect_interval = 1e3,
|
|
16636
|
+
max_reconnects = 5,
|
|
16637
|
+
...rest_options
|
|
16638
|
+
} = {}, generate_request_id, dataPack) {
|
|
16639
|
+
super();
|
|
16640
|
+
this.webSocketFactory = webSocketFactory;
|
|
16641
|
+
this.queue = {};
|
|
16642
|
+
this.rpc_id = 0;
|
|
16643
|
+
this.address = address;
|
|
16644
|
+
this.autoconnect = autoconnect;
|
|
16645
|
+
this.ready = false;
|
|
16646
|
+
this.reconnect = reconnect;
|
|
16647
|
+
this.reconnect_timer_id = void 0;
|
|
16648
|
+
this.reconnect_interval = reconnect_interval;
|
|
16649
|
+
this.max_reconnects = max_reconnects;
|
|
16650
|
+
this.rest_options = rest_options;
|
|
16651
|
+
this.current_reconnects = 0;
|
|
16652
|
+
this.generate_request_id = generate_request_id || (() => ++this.rpc_id);
|
|
16653
|
+
if (!dataPack) this.dataPack = new DefaultDataPack();
|
|
16654
|
+
else this.dataPack = dataPack;
|
|
16655
|
+
if (this.autoconnect)
|
|
16656
|
+
this._connect(this.address, {
|
|
16657
|
+
autoconnect: this.autoconnect,
|
|
16658
|
+
reconnect: this.reconnect,
|
|
16659
|
+
reconnect_interval: this.reconnect_interval,
|
|
16660
|
+
max_reconnects: this.max_reconnects,
|
|
16661
|
+
...this.rest_options
|
|
16662
|
+
});
|
|
16663
|
+
}
|
|
16664
|
+
/**
|
|
16665
|
+
* Connects to a defined server if not connected already.
|
|
16666
|
+
* @method
|
|
16667
|
+
* @return {Undefined}
|
|
16668
|
+
*/
|
|
16669
|
+
connect() {
|
|
16670
|
+
if (this.socket) return;
|
|
16671
|
+
this._connect(this.address, {
|
|
16672
|
+
autoconnect: this.autoconnect,
|
|
16673
|
+
reconnect: this.reconnect,
|
|
16674
|
+
reconnect_interval: this.reconnect_interval,
|
|
16675
|
+
max_reconnects: this.max_reconnects,
|
|
16676
|
+
...this.rest_options
|
|
16677
|
+
});
|
|
16678
|
+
}
|
|
16679
|
+
/**
|
|
16680
|
+
* Calls a registered RPC method on server.
|
|
16681
|
+
* @method
|
|
16682
|
+
* @param {String} method - RPC method name
|
|
16683
|
+
* @param {Object|Array} params - optional method parameters
|
|
16684
|
+
* @param {Number} timeout - RPC reply timeout value
|
|
16685
|
+
* @param {Object} ws_opts - options passed to ws
|
|
16686
|
+
* @return {Promise}
|
|
16687
|
+
*/
|
|
16688
|
+
call(method, params, timeout, ws_opts) {
|
|
16689
|
+
if (!ws_opts && "object" === typeof timeout) {
|
|
16690
|
+
ws_opts = timeout;
|
|
16691
|
+
timeout = null;
|
|
16913
16692
|
}
|
|
16914
|
-
|
|
16915
|
-
|
|
16916
|
-
|
|
16917
|
-
|
|
16918
|
-
|
|
16919
|
-
|
|
16920
|
-
|
|
16921
|
-
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
|
|
16926
|
-
|
|
16693
|
+
return new Promise((resolve, reject) => {
|
|
16694
|
+
if (!this.ready) return reject(new Error("socket not ready"));
|
|
16695
|
+
const rpc_id = this.generate_request_id(method, params);
|
|
16696
|
+
const message = {
|
|
16697
|
+
jsonrpc: "2.0",
|
|
16698
|
+
method,
|
|
16699
|
+
params: params || void 0,
|
|
16700
|
+
id: rpc_id
|
|
16701
|
+
};
|
|
16702
|
+
this.socket.send(this.dataPack.encode(message), ws_opts, (error) => {
|
|
16703
|
+
if (error) return reject(error);
|
|
16704
|
+
this.queue[rpc_id] = { promise: [resolve, reject] };
|
|
16705
|
+
if (timeout) {
|
|
16706
|
+
this.queue[rpc_id].timeout = setTimeout(() => {
|
|
16707
|
+
delete this.queue[rpc_id];
|
|
16708
|
+
reject(new Error("reply timeout"));
|
|
16709
|
+
}, timeout);
|
|
16927
16710
|
}
|
|
16928
|
-
|
|
16929
|
-
|
|
16711
|
+
});
|
|
16712
|
+
});
|
|
16713
|
+
}
|
|
16714
|
+
/**
|
|
16715
|
+
* Logins with the other side of the connection.
|
|
16716
|
+
* @method
|
|
16717
|
+
* @param {Object} params - Login credentials object
|
|
16718
|
+
* @return {Promise}
|
|
16719
|
+
*/
|
|
16720
|
+
async login(params) {
|
|
16721
|
+
const resp = await this.call("rpc.login", params);
|
|
16722
|
+
if (!resp) throw new Error("authentication failed");
|
|
16723
|
+
return resp;
|
|
16724
|
+
}
|
|
16725
|
+
/**
|
|
16726
|
+
* Fetches a list of client's methods registered on server.
|
|
16727
|
+
* @method
|
|
16728
|
+
* @return {Array}
|
|
16729
|
+
*/
|
|
16730
|
+
async listMethods() {
|
|
16731
|
+
return await this.call("__listMethods");
|
|
16732
|
+
}
|
|
16733
|
+
/**
|
|
16734
|
+
* Sends a JSON-RPC 2.0 notification to server.
|
|
16735
|
+
* @method
|
|
16736
|
+
* @param {String} method - RPC method name
|
|
16737
|
+
* @param {Object} params - optional method parameters
|
|
16738
|
+
* @return {Promise}
|
|
16739
|
+
*/
|
|
16740
|
+
notify(method, params) {
|
|
16741
|
+
return new Promise((resolve, reject) => {
|
|
16742
|
+
if (!this.ready) return reject(new Error("socket not ready"));
|
|
16743
|
+
const message = {
|
|
16744
|
+
jsonrpc: "2.0",
|
|
16745
|
+
method,
|
|
16746
|
+
params
|
|
16747
|
+
};
|
|
16748
|
+
this.socket.send(this.dataPack.encode(message), (error) => {
|
|
16749
|
+
if (error) return reject(error);
|
|
16750
|
+
resolve();
|
|
16751
|
+
});
|
|
16752
|
+
});
|
|
16753
|
+
}
|
|
16754
|
+
/**
|
|
16755
|
+
* Subscribes for a defined event.
|
|
16756
|
+
* @method
|
|
16757
|
+
* @param {String|Array} event - event name
|
|
16758
|
+
* @return {Undefined}
|
|
16759
|
+
* @throws {Error}
|
|
16760
|
+
*/
|
|
16761
|
+
async subscribe(event) {
|
|
16762
|
+
if (typeof event === "string") event = [event];
|
|
16763
|
+
const result = await this.call("rpc.on", event);
|
|
16764
|
+
if (typeof event === "string" && result[event] !== "ok")
|
|
16765
|
+
throw new Error(
|
|
16766
|
+
"Failed subscribing to an event '" + event + "' with: " + result[event]
|
|
16767
|
+
);
|
|
16768
|
+
return result;
|
|
16769
|
+
}
|
|
16770
|
+
/**
|
|
16771
|
+
* Unsubscribes from a defined event.
|
|
16772
|
+
* @method
|
|
16773
|
+
* @param {String|Array} event - event name
|
|
16774
|
+
* @return {Undefined}
|
|
16775
|
+
* @throws {Error}
|
|
16776
|
+
*/
|
|
16777
|
+
async unsubscribe(event) {
|
|
16778
|
+
if (typeof event === "string") event = [event];
|
|
16779
|
+
const result = await this.call("rpc.off", event);
|
|
16780
|
+
if (typeof event === "string" && result[event] !== "ok")
|
|
16781
|
+
throw new Error("Failed unsubscribing from an event with: " + result);
|
|
16782
|
+
return result;
|
|
16783
|
+
}
|
|
16784
|
+
/**
|
|
16785
|
+
* Closes a WebSocket connection gracefully.
|
|
16786
|
+
* @method
|
|
16787
|
+
* @param {Number} code - socket close code
|
|
16788
|
+
* @param {String} data - optional data to be sent before closing
|
|
16789
|
+
* @return {Undefined}
|
|
16790
|
+
*/
|
|
16791
|
+
close(code, data) {
|
|
16792
|
+
this.socket.close(code || 1e3, data);
|
|
16793
|
+
}
|
|
16794
|
+
/**
|
|
16795
|
+
* Enable / disable automatic reconnection.
|
|
16796
|
+
* @method
|
|
16797
|
+
* @param {Boolean} reconnect - enable / disable reconnection
|
|
16798
|
+
* @return {Undefined}
|
|
16799
|
+
*/
|
|
16800
|
+
setAutoReconnect(reconnect) {
|
|
16801
|
+
this.reconnect = reconnect;
|
|
16802
|
+
}
|
|
16803
|
+
/**
|
|
16804
|
+
* Set the interval between reconnection attempts.
|
|
16805
|
+
* @method
|
|
16806
|
+
* @param {Number} interval - reconnection interval in milliseconds
|
|
16807
|
+
* @return {Undefined}
|
|
16808
|
+
*/
|
|
16809
|
+
setReconnectInterval(interval) {
|
|
16810
|
+
this.reconnect_interval = interval;
|
|
16811
|
+
}
|
|
16812
|
+
/**
|
|
16813
|
+
* Set the maximum number of reconnection attempts.
|
|
16814
|
+
* @method
|
|
16815
|
+
* @param {Number} max_reconnects - maximum reconnection attempts
|
|
16816
|
+
* @return {Undefined}
|
|
16817
|
+
*/
|
|
16818
|
+
setMaxReconnects(max_reconnects) {
|
|
16819
|
+
this.max_reconnects = max_reconnects;
|
|
16820
|
+
}
|
|
16821
|
+
/**
|
|
16822
|
+
* Connection/Message handler.
|
|
16823
|
+
* @method
|
|
16824
|
+
* @private
|
|
16825
|
+
* @param {String} address - WebSocket API address
|
|
16826
|
+
* @param {Object} options - ws options object
|
|
16827
|
+
* @return {Undefined}
|
|
16828
|
+
*/
|
|
16829
|
+
_connect(address, options) {
|
|
16830
|
+
clearTimeout(this.reconnect_timer_id);
|
|
16831
|
+
this.socket = this.webSocketFactory(address, options);
|
|
16832
|
+
this.socket.addEventListener("open", () => {
|
|
16833
|
+
this.ready = true;
|
|
16834
|
+
this.emit("open");
|
|
16835
|
+
this.current_reconnects = 0;
|
|
16836
|
+
});
|
|
16837
|
+
this.socket.addEventListener("message", ({ data: message }) => {
|
|
16838
|
+
if (message instanceof ArrayBuffer)
|
|
16839
|
+
message = buffer.Buffer.from(message).toString();
|
|
16840
|
+
try {
|
|
16841
|
+
message = this.dataPack.decode(message);
|
|
16842
|
+
} catch (error) {
|
|
16843
|
+
return;
|
|
16844
|
+
}
|
|
16845
|
+
if (message.notification && this.listeners(message.notification).length) {
|
|
16846
|
+
if (!Object.keys(message.params).length)
|
|
16847
|
+
return this.emit(message.notification);
|
|
16848
|
+
const args = [message.notification];
|
|
16849
|
+
if (message.params.constructor === Object) args.push(message.params);
|
|
16850
|
+
else
|
|
16851
|
+
for (let i = 0; i < message.params.length; i++)
|
|
16852
|
+
args.push(message.params[i]);
|
|
16853
|
+
return Promise.resolve().then(() => {
|
|
16854
|
+
this.emit.apply(this, args);
|
|
16855
|
+
});
|
|
16856
|
+
}
|
|
16857
|
+
if (!this.queue[message.id]) {
|
|
16858
|
+
if (message.method) {
|
|
16859
|
+
return Promise.resolve().then(() => {
|
|
16860
|
+
this.emit(message.method, message?.params);
|
|
16861
|
+
});
|
|
16930
16862
|
}
|
|
16931
|
-
|
|
16932
|
-
|
|
16933
|
-
|
|
16934
|
-
|
|
16935
|
-
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
|
|
16940
|
-
|
|
16941
|
-
|
|
16942
|
-
|
|
16943
|
-
|
|
16944
|
-
|
|
16945
|
-
|
|
16946
|
-
|
|
16947
|
-
|
|
16948
|
-
|
|
16949
|
-
|
|
16950
|
-
|
|
16951
|
-
|
|
16952
|
-
|
|
16953
|
-
|
|
16954
|
-
|
|
16955
|
-
|
|
16956
|
-
|
|
16957
|
-
|
|
16863
|
+
return;
|
|
16864
|
+
}
|
|
16865
|
+
if ("error" in message === "result" in message)
|
|
16866
|
+
this.queue[message.id].promise[1](
|
|
16867
|
+
new Error(
|
|
16868
|
+
'Server response malformed. Response must include either "result" or "error", but not both.'
|
|
16869
|
+
)
|
|
16870
|
+
);
|
|
16871
|
+
if (this.queue[message.id].timeout)
|
|
16872
|
+
clearTimeout(this.queue[message.id].timeout);
|
|
16873
|
+
if (message.error) this.queue[message.id].promise[1](message.error);
|
|
16874
|
+
else this.queue[message.id].promise[0](message.result);
|
|
16875
|
+
delete this.queue[message.id];
|
|
16876
|
+
});
|
|
16877
|
+
this.socket.addEventListener("error", (error) => this.emit("error", error));
|
|
16878
|
+
this.socket.addEventListener("close", ({ code, reason }) => {
|
|
16879
|
+
if (this.ready)
|
|
16880
|
+
setTimeout(() => this.emit("close", code, reason), 0);
|
|
16881
|
+
this.ready = false;
|
|
16882
|
+
this.socket = void 0;
|
|
16883
|
+
if (code === 1e3) return;
|
|
16884
|
+
this.current_reconnects++;
|
|
16885
|
+
if (this.reconnect && (this.max_reconnects > this.current_reconnects || this.max_reconnects === 0))
|
|
16886
|
+
this.reconnect_timer_id = setTimeout(
|
|
16887
|
+
() => this._connect(address, options),
|
|
16888
|
+
this.reconnect_interval
|
|
16889
|
+
);
|
|
16890
|
+
});
|
|
16891
|
+
}
|
|
16892
|
+
};
|
|
16958
16893
|
|
|
16959
|
-
class RpcWebSocketClient extends
|
|
16894
|
+
class RpcWebSocketClient extends CommonClient {
|
|
16960
16895
|
constructor(address, options, generate_request_id) {
|
|
16961
16896
|
const webSocketFactory = url => {
|
|
16962
|
-
const rpc =
|
|
16897
|
+
const rpc = WebSocket(url, {
|
|
16963
16898
|
autoconnect: true,
|
|
16964
16899
|
max_reconnects: 5,
|
|
16965
16900
|
reconnect: true,
|