@chainflip/rpc 1.6.8 → 1.6.10

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/Client.cjs CHANGED
@@ -1,33 +1,43 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/Client.ts
2
- var _commoncjs = require('./common.cjs');
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); var _class;// src/Client.ts
3
2
  var _assertion = require('@chainflip/utils/assertion');
4
- var Client = class {
5
- constructor(url) {
3
+ var _commoncjs = require('./common.cjs');
4
+ var Client = (_class = class {
5
+ constructor(url) {;_class.prototype.__init.call(this);
6
6
  this.url = url;
7
7
  }
8
+ __init() {this.lastRequestId = 0}
8
9
  getRequestId() {
9
- return "1";
10
+ return String(++this.lastRequestId);
10
11
  }
11
12
  formatRequest(method, params) {
12
13
  return { jsonrpc: "2.0", id: this.getRequestId(), method, params };
13
14
  }
14
- async sendRequest(method, ...params) {
15
- const response = await this.send(this.formatRequest(method, params));
16
- if (!response.success)
15
+ parseSingleResponse(response) {
16
+ if (!response.success) {
17
17
  throw response.error;
18
+ }
18
19
  const parseResult = _commoncjs.rpcResponse.safeParse(response.result);
19
- _assertion.assert.call(void 0, parseResult.success, "Malformed RPC response received");
20
+ if (!parseResult.success) {
21
+ throw new Error("Malformed RPC response received");
22
+ }
20
23
  if ("error" in parseResult.data) {
21
24
  throw new Error(
22
25
  `RPC error [${parseResult.data.error.code}]: ${parseResult.data.error.message}`
23
26
  );
24
27
  }
25
- return _commoncjs.rpcResult[method].parse(parseResult.data.result);
28
+ _assertion.assert.call(void 0, "result" in parseResult.data);
29
+ return parseResult.data;
30
+ }
31
+ async sendRequest(method, ...params) {
32
+ const [response] = await this.send([this.formatRequest(method, params)]);
33
+ if (!response.success) throw response.error;
34
+ const parseResult = this.parseSingleResponse(response);
35
+ return _commoncjs.rpcResult[method].parse(parseResult.result);
26
36
  }
27
37
  methods() {
28
38
  return Object.keys(_commoncjs.rpcResult).sort();
29
39
  }
30
- };
40
+ }, _class);
31
41
 
32
42
 
33
43
  exports.default = Client;
package/dist/Client.d.cts CHANGED
@@ -3,20 +3,29 @@ import '@chainflip/utils/types';
3
3
  import 'zod';
4
4
  import './parsers.cjs';
5
5
 
6
+ type Response = {
7
+ success: true;
8
+ id: string;
9
+ result: unknown;
10
+ } | {
11
+ success: false;
12
+ id: string;
13
+ error: Error;
14
+ };
6
15
  declare abstract class Client {
7
16
  protected readonly url: string;
17
+ private lastRequestId;
8
18
  constructor(url: string);
9
- protected abstract send<const T extends RpcMethod>(data: JsonRpcRequest<T>): Promise<{
10
- success: true;
11
- result: unknown;
12
- } | {
13
- success: false;
14
- error: Error;
15
- }>;
19
+ protected abstract send<const T extends RpcMethod>(data: JsonRpcRequest<T>[]): Promise<Response[]>;
16
20
  protected getRequestId(): string;
17
- private formatRequest;
21
+ protected formatRequest<T extends RpcMethod>(method: T, params: RpcRequest[T]): JsonRpcRequest<T>;
22
+ protected parseSingleResponse(response: Response): {
23
+ id: string | number;
24
+ jsonrpc: "2.0";
25
+ result?: any;
26
+ };
18
27
  sendRequest<const T extends RpcMethod>(method: T, ...params: RpcRequest[T]): Promise<RpcResult<T>>;
19
28
  methods(): RpcMethod[];
20
29
  }
21
30
 
22
- export { Client as default };
31
+ export { type Response, Client as default };
package/dist/Client.d.ts CHANGED
@@ -3,20 +3,29 @@ import '@chainflip/utils/types';
3
3
  import 'zod';
4
4
  import './parsers.js';
5
5
 
6
+ type Response = {
7
+ success: true;
8
+ id: string;
9
+ result: unknown;
10
+ } | {
11
+ success: false;
12
+ id: string;
13
+ error: Error;
14
+ };
6
15
  declare abstract class Client {
7
16
  protected readonly url: string;
17
+ private lastRequestId;
8
18
  constructor(url: string);
9
- protected abstract send<const T extends RpcMethod>(data: JsonRpcRequest<T>): Promise<{
10
- success: true;
11
- result: unknown;
12
- } | {
13
- success: false;
14
- error: Error;
15
- }>;
19
+ protected abstract send<const T extends RpcMethod>(data: JsonRpcRequest<T>[]): Promise<Response[]>;
16
20
  protected getRequestId(): string;
17
- private formatRequest;
21
+ protected formatRequest<T extends RpcMethod>(method: T, params: RpcRequest[T]): JsonRpcRequest<T>;
22
+ protected parseSingleResponse(response: Response): {
23
+ id: string | number;
24
+ jsonrpc: "2.0";
25
+ result?: any;
26
+ };
18
27
  sendRequest<const T extends RpcMethod>(method: T, ...params: RpcRequest[T]): Promise<RpcResult<T>>;
19
28
  methods(): RpcMethod[];
20
29
  }
21
30
 
22
- export { Client as default };
31
+ export { type Response, Client as default };
package/dist/Client.mjs CHANGED
@@ -1,28 +1,38 @@
1
1
  // src/Client.ts
2
- import { rpcResult, rpcResponse } from "./common.mjs";
3
2
  import { assert } from "@chainflip/utils/assertion";
3
+ import { rpcResult, rpcResponse } from "./common.mjs";
4
4
  var Client = class {
5
5
  constructor(url) {
6
6
  this.url = url;
7
7
  }
8
+ lastRequestId = 0;
8
9
  getRequestId() {
9
- return "1";
10
+ return String(++this.lastRequestId);
10
11
  }
11
12
  formatRequest(method, params) {
12
13
  return { jsonrpc: "2.0", id: this.getRequestId(), method, params };
13
14
  }
14
- async sendRequest(method, ...params) {
15
- const response = await this.send(this.formatRequest(method, params));
16
- if (!response.success)
15
+ parseSingleResponse(response) {
16
+ if (!response.success) {
17
17
  throw response.error;
18
+ }
18
19
  const parseResult = rpcResponse.safeParse(response.result);
19
- assert(parseResult.success, "Malformed RPC response received");
20
+ if (!parseResult.success) {
21
+ throw new Error("Malformed RPC response received");
22
+ }
20
23
  if ("error" in parseResult.data) {
21
24
  throw new Error(
22
25
  `RPC error [${parseResult.data.error.code}]: ${parseResult.data.error.message}`
23
26
  );
24
27
  }
25
- return rpcResult[method].parse(parseResult.data.result);
28
+ assert("result" in parseResult.data);
29
+ return parseResult.data;
30
+ }
31
+ async sendRequest(method, ...params) {
32
+ const [response] = await this.send([this.formatRequest(method, params)]);
33
+ if (!response.success) throw response.error;
34
+ const parseResult = this.parseSingleResponse(response);
35
+ return rpcResult[method].parse(parseResult.result);
26
36
  }
27
37
  methods() {
28
38
  return Object.keys(rpcResult).sort();
@@ -1,6 +1,13 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/HttpClient.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _class;// src/HttpClient.ts
2
+ var _async = require('@chainflip/utils/async');
2
3
  var _Clientcjs = require('./Client.cjs'); var _Clientcjs2 = _interopRequireDefault(_Clientcjs);
3
- var HttpClient = class extends _Clientcjs2.default {
4
+
5
+
6
+ var _commoncjs = require('./common.cjs');
7
+ var HttpClient = (_class = class extends _Clientcjs2.default {constructor(...args) { super(...args); _class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this); }
8
+ __init() {this.timer = null}
9
+ __init2() {this.batchDuration = 100}
10
+ __init3() {this.requestMap = /* @__PURE__ */ new Map()}
4
11
  async send(request) {
5
12
  const res = await fetch(this.url, {
6
13
  body: JSON.stringify(request),
@@ -10,16 +17,59 @@ var HttpClient = class extends _Clientcjs2.default {
10
17
  }
11
18
  });
12
19
  if (!res.ok) {
13
- return { success: false, error: new Error(`HTTP error: ${res.status}`) };
20
+ return request.map((r) => ({
21
+ id: r.id,
22
+ success: false,
23
+ error: new Error(`HTTP error: ${res.status}`)
24
+ }));
14
25
  }
15
26
  try {
16
- const result = await res.json();
17
- return { success: true, result };
27
+ const jsonRpcResponse = await res.json();
28
+ return jsonRpcResponse.map((r) => ({ id: r.id, success: true, result: r }));
18
29
  } catch (cause) {
19
- return { success: false, error: new Error("Invalid JSON response", { cause }) };
30
+ return request.map((r) => ({
31
+ id: r.id,
32
+ success: false,
33
+ error: new Error("Invalid JSON response", { cause })
34
+ }));
20
35
  }
21
36
  }
22
- };
37
+ sendRequest(method, ...params) {
38
+ const deferred = _async.deferredPromise.call(void 0, );
39
+ const body = this.formatRequest(method, params);
40
+ this.requestMap.set(body.id, { deferred, body, method });
41
+ if (this.timer) clearTimeout(this.timer);
42
+ this.timer = setTimeout(() => this.sendBatch(), this.batchDuration);
43
+ return deferred.promise;
44
+ }
45
+ async sendBatch() {
46
+ const clonedMap = new Map(this.requestMap);
47
+ this.requestMap.clear();
48
+ const requests = [...clonedMap.values()].map((item) => item.body);
49
+ const responses = await this.send(requests);
50
+ for (const response of responses) {
51
+ const clonedItem = clonedMap.get(response.id);
52
+ if (!clonedItem) {
53
+ continue;
54
+ }
55
+ if (!response.success) {
56
+ clonedItem.deferred.reject(response.error);
57
+ continue;
58
+ }
59
+ try {
60
+ const parseResult = this.parseSingleResponse(response);
61
+ clonedItem.deferred.resolve(_commoncjs.rpcResult[clonedItem.method].parse(parseResult.result));
62
+ } catch (e) {
63
+ clonedItem.deferred.reject(e);
64
+ } finally {
65
+ clonedMap.delete(response.id);
66
+ }
67
+ }
68
+ clonedMap.forEach((item) => {
69
+ item.deferred.reject(new Error("Could not find the result for the request"));
70
+ });
71
+ }
72
+ }, _class);
23
73
 
24
74
 
25
75
  exports.default = HttpClient;
@@ -1,17 +1,16 @@
1
- import Client from './Client.cjs';
2
- import { RpcMethod, JsonRpcRequest } from './common.cjs';
1
+ import Client, { Response } from './Client.cjs';
2
+ import { RpcMethod, JsonRpcRequest, RpcRequest, RpcResult } from './common.cjs';
3
3
  import '@chainflip/utils/types';
4
4
  import 'zod';
5
5
  import './parsers.cjs';
6
6
 
7
7
  declare class HttpClient extends Client {
8
- protected send<const T extends RpcMethod>(request: JsonRpcRequest<T>): Promise<{
9
- success: true;
10
- result: unknown;
11
- } | {
12
- success: false;
13
- error: Error;
14
- }>;
8
+ private timer;
9
+ private batchDuration;
10
+ private requestMap;
11
+ protected send<const T extends RpcMethod>(request: JsonRpcRequest<T>[]): Promise<Response[]>;
12
+ sendRequest<const T extends RpcMethod>(method: T, ...params: RpcRequest[T]): Promise<RpcResult<T>>;
13
+ private sendBatch;
15
14
  }
16
15
 
17
16
  export { HttpClient as default };
@@ -1,17 +1,16 @@
1
- import Client from './Client.js';
2
- import { RpcMethod, JsonRpcRequest } from './common.js';
1
+ import Client, { Response } from './Client.js';
2
+ import { RpcMethod, JsonRpcRequest, RpcRequest, RpcResult } from './common.js';
3
3
  import '@chainflip/utils/types';
4
4
  import 'zod';
5
5
  import './parsers.js';
6
6
 
7
7
  declare class HttpClient extends Client {
8
- protected send<const T extends RpcMethod>(request: JsonRpcRequest<T>): Promise<{
9
- success: true;
10
- result: unknown;
11
- } | {
12
- success: false;
13
- error: Error;
14
- }>;
8
+ private timer;
9
+ private batchDuration;
10
+ private requestMap;
11
+ protected send<const T extends RpcMethod>(request: JsonRpcRequest<T>[]): Promise<Response[]>;
12
+ sendRequest<const T extends RpcMethod>(method: T, ...params: RpcRequest[T]): Promise<RpcResult<T>>;
13
+ private sendBatch;
15
14
  }
16
15
 
17
16
  export { HttpClient as default };
@@ -1,6 +1,13 @@
1
1
  // src/HttpClient.ts
2
+ import { deferredPromise } from "@chainflip/utils/async";
2
3
  import Client from "./Client.mjs";
4
+ import {
5
+ rpcResult
6
+ } from "./common.mjs";
3
7
  var HttpClient = class extends Client {
8
+ timer = null;
9
+ batchDuration = 100;
10
+ requestMap = /* @__PURE__ */ new Map();
4
11
  async send(request) {
5
12
  const res = await fetch(this.url, {
6
13
  body: JSON.stringify(request),
@@ -10,15 +17,58 @@ var HttpClient = class extends Client {
10
17
  }
11
18
  });
12
19
  if (!res.ok) {
13
- return { success: false, error: new Error(`HTTP error: ${res.status}`) };
20
+ return request.map((r) => ({
21
+ id: r.id,
22
+ success: false,
23
+ error: new Error(`HTTP error: ${res.status}`)
24
+ }));
14
25
  }
15
26
  try {
16
- const result = await res.json();
17
- return { success: true, result };
27
+ const jsonRpcResponse = await res.json();
28
+ return jsonRpcResponse.map((r) => ({ id: r.id, success: true, result: r }));
18
29
  } catch (cause) {
19
- return { success: false, error: new Error("Invalid JSON response", { cause }) };
30
+ return request.map((r) => ({
31
+ id: r.id,
32
+ success: false,
33
+ error: new Error("Invalid JSON response", { cause })
34
+ }));
20
35
  }
21
36
  }
37
+ sendRequest(method, ...params) {
38
+ const deferred = deferredPromise();
39
+ const body = this.formatRequest(method, params);
40
+ this.requestMap.set(body.id, { deferred, body, method });
41
+ if (this.timer) clearTimeout(this.timer);
42
+ this.timer = setTimeout(() => this.sendBatch(), this.batchDuration);
43
+ return deferred.promise;
44
+ }
45
+ async sendBatch() {
46
+ const clonedMap = new Map(this.requestMap);
47
+ this.requestMap.clear();
48
+ const requests = [...clonedMap.values()].map((item) => item.body);
49
+ const responses = await this.send(requests);
50
+ for (const response of responses) {
51
+ const clonedItem = clonedMap.get(response.id);
52
+ if (!clonedItem) {
53
+ continue;
54
+ }
55
+ if (!response.success) {
56
+ clonedItem.deferred.reject(response.error);
57
+ continue;
58
+ }
59
+ try {
60
+ const parseResult = this.parseSingleResponse(response);
61
+ clonedItem.deferred.resolve(rpcResult[clonedItem.method].parse(parseResult.result));
62
+ } catch (e) {
63
+ clonedItem.deferred.reject(e);
64
+ } finally {
65
+ clonedMap.delete(response.id);
66
+ }
67
+ }
68
+ clonedMap.forEach((item) => {
69
+ item.deferred.reject(new Error("Could not find the result for the request"));
70
+ });
71
+ }
22
72
  };
23
73
  export {
24
74
  HttpClient as default
package/dist/WsClient.cjs CHANGED
@@ -1,6 +1,5 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/WsClient.ts
2
2
  var _async = require('@chainflip/utils/async');
3
- var _crypto = require('crypto');
4
3
  var _Clientcjs = require('./Client.cjs'); var _Clientcjs2 = _interopRequireDefault(_Clientcjs);
5
4
  var _commoncjs = require('./common.cjs');
6
5
  var READY = "READY";
@@ -14,15 +13,11 @@ var WsClient = (_class = class extends _Clientcjs2.default {
14
13
  __init() {this.reconnectAttempts = 0}
15
14
  __init2() {this.emitter = new EventTarget()}
16
15
  __init3() {this.requestMap = /* @__PURE__ */ new Map()}
17
- getRequestId() {
18
- return _crypto.randomUUID.call(void 0, );
19
- }
20
16
  async close() {
21
17
  await this.handleClose();
22
18
  }
23
19
  async handleClose() {
24
- if (!this.ws)
25
- return;
20
+ if (!this.ws) return;
26
21
  this.ws.removeEventListener("close", this.handleDisconnect);
27
22
  this.ws.close();
28
23
  if (this.ws.readyState !== this.WebSocket.CLOSED) {
@@ -53,8 +48,7 @@ var WsClient = (_class = class extends _Clientcjs2.default {
53
48
  __init5() {this.handleMessage = (data) => {
54
49
  const parsedData = JSON.parse(data.data);
55
50
  const response = _commoncjs.rpcResponse.safeParse(parsedData);
56
- if (!response.success)
57
- return;
51
+ if (!response.success) return;
58
52
  const { id } = response.data;
59
53
  _optionalChain([this, 'access', _6 => _6.requestMap, 'access', _7 => _7.get, 'call', _8 => _8(id), 'optionalAccess', _9 => _9.resolve, 'call', _10 => _10(response.data)]);
60
54
  }}
@@ -71,36 +65,47 @@ var WsClient = (_class = class extends _Clientcjs2.default {
71
65
  this.reconnectAttempts = 0;
72
66
  return socket;
73
67
  }
74
- async send(data) {
75
- let requestId = data.id;
76
- for (let i = 0; i < 5; i += 1) {
77
- let socket;
78
- try {
79
- socket = await this.connectionReady();
80
- } catch (e) {
81
- continue;
68
+ async send(requests) {
69
+ const responses = [];
70
+ for (const data of requests) {
71
+ const MAX_RETRIES = 5;
72
+ for (let i = 0; i < MAX_RETRIES; i += 1) {
73
+ let socket;
74
+ try {
75
+ socket = await this.connectionReady();
76
+ } catch (e) {
77
+ continue;
78
+ }
79
+ socket.send(JSON.stringify(data));
80
+ const request = _async.deferredPromise.call(void 0, );
81
+ this.requestMap.set(data.id, request);
82
+ const controller = new AbortController();
83
+ const result = await Promise.race([
84
+ _async.sleep.call(void 0, 3e4, { signal: controller.signal }).then(
85
+ () => ({ success: false, retry: false, error: new Error("timeout") })
86
+ ),
87
+ request.promise.then(
88
+ (result2) => ({ success: true, result: result2 }),
89
+ (error) => ({ success: false, error, retry: true })
90
+ )
91
+ ]).finally(() => {
92
+ this.requestMap.delete(data.id);
93
+ controller.abort();
94
+ });
95
+ if (result.success || !result.retry) {
96
+ responses.push({ ...result, id: data.id });
97
+ break;
98
+ }
99
+ if (i === MAX_RETRIES - 1) {
100
+ responses.push({
101
+ success: false,
102
+ error: new Error("max retries exceeded"),
103
+ id: data.id
104
+ });
105
+ }
82
106
  }
83
- socket.send(JSON.stringify({ ...data, id: requestId }));
84
- const request = _async.deferredPromise.call(void 0, );
85
- this.requestMap.set(requestId, request);
86
- const controller = new AbortController();
87
- const result = await Promise.race([
88
- _async.sleep.call(void 0, 3e4, { signal: controller.signal }).then(
89
- () => ({ success: false, retry: false, error: new Error("timeout") })
90
- ),
91
- request.promise.then(
92
- (result2) => ({ success: true, result: result2 }),
93
- (error) => ({ success: false, error, retry: true })
94
- )
95
- ]).finally(() => {
96
- this.requestMap.delete(requestId);
97
- controller.abort();
98
- });
99
- if (result.success || !result.retry)
100
- return result;
101
- requestId = this.getRequestId();
102
107
  }
103
- return { success: false, error: new Error("max retries exceeded") };
108
+ return responses;
104
109
  }
105
110
  }, _class);
106
111
 
@@ -1,4 +1,4 @@
1
- import Client from './Client.cjs';
1
+ import Client, { Response } from './Client.cjs';
2
2
  import { RpcMethod, JsonRpcRequest } from './common.cjs';
3
3
  import '@chainflip/utils/types';
4
4
  import 'zod';
@@ -11,20 +11,13 @@ declare class WsClient extends Client {
11
11
  private emitter;
12
12
  private requestMap;
13
13
  constructor(url: string, WebSocket?: typeof globalThis.WebSocket);
14
- protected getRequestId(): `${string}-${string}-${string}-${string}-${string}`;
15
14
  close(): Promise<void>;
16
15
  private handleClose;
17
16
  private connectionReady;
18
17
  private handleDisconnect;
19
18
  private handleMessage;
20
19
  private connect;
21
- protected send<const T extends RpcMethod>(data: JsonRpcRequest<T>): Promise<{
22
- success: true;
23
- result: unknown;
24
- } | {
25
- success: false;
26
- error: Error;
27
- }>;
20
+ protected send<const T extends RpcMethod>(requests: JsonRpcRequest<T>[]): Promise<Response[]>;
28
21
  }
29
22
 
30
23
  export { WsClient as default };
@@ -1,4 +1,4 @@
1
- import Client from './Client.js';
1
+ import Client, { Response } from './Client.js';
2
2
  import { RpcMethod, JsonRpcRequest } from './common.js';
3
3
  import '@chainflip/utils/types';
4
4
  import 'zod';
@@ -11,20 +11,13 @@ declare class WsClient extends Client {
11
11
  private emitter;
12
12
  private requestMap;
13
13
  constructor(url: string, WebSocket?: typeof globalThis.WebSocket);
14
- protected getRequestId(): `${string}-${string}-${string}-${string}-${string}`;
15
14
  close(): Promise<void>;
16
15
  private handleClose;
17
16
  private connectionReady;
18
17
  private handleDisconnect;
19
18
  private handleMessage;
20
19
  private connect;
21
- protected send<const T extends RpcMethod>(data: JsonRpcRequest<T>): Promise<{
22
- success: true;
23
- result: unknown;
24
- } | {
25
- success: false;
26
- error: Error;
27
- }>;
20
+ protected send<const T extends RpcMethod>(requests: JsonRpcRequest<T>[]): Promise<Response[]>;
28
21
  }
29
22
 
30
23
  export { WsClient as default };
package/dist/WsClient.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  // src/WsClient.ts
2
2
  import { deferredPromise, once, sleep } from "@chainflip/utils/async";
3
- import { randomUUID } from "crypto";
4
3
  import Client from "./Client.mjs";
5
4
  import { rpcResponse } from "./common.mjs";
6
5
  var READY = "READY";
@@ -14,15 +13,11 @@ var WsClient = class extends Client {
14
13
  reconnectAttempts = 0;
15
14
  emitter = new EventTarget();
16
15
  requestMap = /* @__PURE__ */ new Map();
17
- getRequestId() {
18
- return randomUUID();
19
- }
20
16
  async close() {
21
17
  await this.handleClose();
22
18
  }
23
19
  async handleClose() {
24
- if (!this.ws)
25
- return;
20
+ if (!this.ws) return;
26
21
  this.ws.removeEventListener("close", this.handleDisconnect);
27
22
  this.ws.close();
28
23
  if (this.ws.readyState !== this.WebSocket.CLOSED) {
@@ -53,8 +48,7 @@ var WsClient = class extends Client {
53
48
  handleMessage = (data) => {
54
49
  const parsedData = JSON.parse(data.data);
55
50
  const response = rpcResponse.safeParse(parsedData);
56
- if (!response.success)
57
- return;
51
+ if (!response.success) return;
58
52
  const { id } = response.data;
59
53
  this.requestMap.get(id)?.resolve(response.data);
60
54
  };
@@ -71,36 +65,47 @@ var WsClient = class extends Client {
71
65
  this.reconnectAttempts = 0;
72
66
  return socket;
73
67
  }
74
- async send(data) {
75
- let requestId = data.id;
76
- for (let i = 0; i < 5; i += 1) {
77
- let socket;
78
- try {
79
- socket = await this.connectionReady();
80
- } catch {
81
- continue;
68
+ async send(requests) {
69
+ const responses = [];
70
+ for (const data of requests) {
71
+ const MAX_RETRIES = 5;
72
+ for (let i = 0; i < MAX_RETRIES; i += 1) {
73
+ let socket;
74
+ try {
75
+ socket = await this.connectionReady();
76
+ } catch {
77
+ continue;
78
+ }
79
+ socket.send(JSON.stringify(data));
80
+ const request = deferredPromise();
81
+ this.requestMap.set(data.id, request);
82
+ const controller = new AbortController();
83
+ const result = await Promise.race([
84
+ sleep(3e4, { signal: controller.signal }).then(
85
+ () => ({ success: false, retry: false, error: new Error("timeout") })
86
+ ),
87
+ request.promise.then(
88
+ (result2) => ({ success: true, result: result2 }),
89
+ (error) => ({ success: false, error, retry: true })
90
+ )
91
+ ]).finally(() => {
92
+ this.requestMap.delete(data.id);
93
+ controller.abort();
94
+ });
95
+ if (result.success || !result.retry) {
96
+ responses.push({ ...result, id: data.id });
97
+ break;
98
+ }
99
+ if (i === MAX_RETRIES - 1) {
100
+ responses.push({
101
+ success: false,
102
+ error: new Error("max retries exceeded"),
103
+ id: data.id
104
+ });
105
+ }
82
106
  }
83
- socket.send(JSON.stringify({ ...data, id: requestId }));
84
- const request = deferredPromise();
85
- this.requestMap.set(requestId, request);
86
- const controller = new AbortController();
87
- const result = await Promise.race([
88
- sleep(3e4, { signal: controller.signal }).then(
89
- () => ({ success: false, retry: false, error: new Error("timeout") })
90
- ),
91
- request.promise.then(
92
- (result2) => ({ success: true, result: result2 }),
93
- (error) => ({ success: false, error, retry: true })
94
- )
95
- ]).finally(() => {
96
- this.requestMap.delete(requestId);
97
- controller.abort();
98
- });
99
- if (result.success || !result.retry)
100
- return result;
101
- requestId = this.getRequestId();
102
107
  }
103
- return { success: false, error: new Error("max retries exceeded") };
108
+ return responses;
104
109
  }
105
110
  };
106
111
  export {