@binance/common 2.1.1 → 2.3.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/index.d.mts +56 -16
- package/dist/index.d.ts +56 -16
- package/dist/index.js +132 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +131 -55
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -344,16 +344,17 @@ const httpRequestFunction = async function(axiosArgs, configuration) {
|
|
|
344
344
|
else if (typeof responseData === "object") data = responseData;
|
|
345
345
|
}
|
|
346
346
|
const errorMsg = data.msg;
|
|
347
|
+
const errorCode = typeof data.code === "number" ? data.code : void 0;
|
|
347
348
|
switch (status) {
|
|
348
|
-
case 400: throw new BadRequestError(errorMsg);
|
|
349
|
-
case 401: throw new UnauthorizedError(errorMsg);
|
|
350
|
-
case 403: throw new ForbiddenError(errorMsg);
|
|
351
|
-
case 404: throw new NotFoundError(errorMsg);
|
|
352
|
-
case 418: throw new RateLimitBanError(errorMsg);
|
|
353
|
-
case 429: throw new TooManyRequestsError(errorMsg);
|
|
349
|
+
case 400: throw new BadRequestError(errorMsg, errorCode);
|
|
350
|
+
case 401: throw new UnauthorizedError(errorMsg, errorCode);
|
|
351
|
+
case 403: throw new ForbiddenError(errorMsg, errorCode);
|
|
352
|
+
case 404: throw new NotFoundError(errorMsg, errorCode);
|
|
353
|
+
case 418: throw new RateLimitBanError(errorMsg, errorCode);
|
|
354
|
+
case 429: throw new TooManyRequestsError(errorMsg, errorCode);
|
|
354
355
|
default:
|
|
355
356
|
if (status >= 500 && status < 600) throw new ServerError(`Server error: ${status}`, status);
|
|
356
|
-
throw new ConnectorClientError(errorMsg);
|
|
357
|
+
throw new ConnectorClientError(errorMsg, errorCode);
|
|
357
358
|
}
|
|
358
359
|
} else {
|
|
359
360
|
if (retries > 0 && attempt >= retries) lastError = /* @__PURE__ */ new Error(`Request failed after ${retries} retries`);
|
|
@@ -690,7 +691,9 @@ const DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL = "wss://testnet.binan
|
|
|
690
691
|
const DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL = "wss://fstream.binance.com";
|
|
691
692
|
const DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL = "wss://stream.binancefuture.com";
|
|
692
693
|
const DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL = "https://eapi.binance.com";
|
|
693
|
-
const
|
|
694
|
+
const DERIVATIVES_TRADING_OPTIONS_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
|
|
695
|
+
const DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL = "wss://fstream.binance.com";
|
|
696
|
+
const DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_TESTNET_URL = "wss://fstream.binancefuture.com";
|
|
694
697
|
const DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL = "https://papi.binance.com";
|
|
695
698
|
const DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
|
|
696
699
|
const DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL = "wss://fstream.binance.com/pm";
|
|
@@ -728,10 +731,11 @@ const WALLET_REST_API_PROD_URL = "https://api.binance.com";
|
|
|
728
731
|
* @param msg - An optional error message.
|
|
729
732
|
*/
|
|
730
733
|
var ConnectorClientError = class ConnectorClientError extends Error {
|
|
731
|
-
constructor(msg) {
|
|
734
|
+
constructor(msg, code) {
|
|
732
735
|
super(msg || "An unexpected error occurred.");
|
|
733
736
|
Object.setPrototypeOf(this, ConnectorClientError.prototype);
|
|
734
737
|
this.name = "ConnectorClientError";
|
|
738
|
+
this.code = code;
|
|
735
739
|
}
|
|
736
740
|
};
|
|
737
741
|
/**
|
|
@@ -752,10 +756,11 @@ var RequiredError = class RequiredError extends Error {
|
|
|
752
756
|
* @param msg - An optional error message.
|
|
753
757
|
*/
|
|
754
758
|
var UnauthorizedError = class UnauthorizedError extends Error {
|
|
755
|
-
constructor(msg) {
|
|
759
|
+
constructor(msg, code) {
|
|
756
760
|
super(msg || "Unauthorized access. Authentication required.");
|
|
757
761
|
Object.setPrototypeOf(this, UnauthorizedError.prototype);
|
|
758
762
|
this.name = "UnauthorizedError";
|
|
763
|
+
this.code = code;
|
|
759
764
|
}
|
|
760
765
|
};
|
|
761
766
|
/**
|
|
@@ -763,10 +768,11 @@ var UnauthorizedError = class UnauthorizedError extends Error {
|
|
|
763
768
|
* @param msg - An optional error message.
|
|
764
769
|
*/
|
|
765
770
|
var ForbiddenError = class ForbiddenError extends Error {
|
|
766
|
-
constructor(msg) {
|
|
771
|
+
constructor(msg, code) {
|
|
767
772
|
super(msg || "Access to the requested resource is forbidden.");
|
|
768
773
|
Object.setPrototypeOf(this, ForbiddenError.prototype);
|
|
769
774
|
this.name = "ForbiddenError";
|
|
775
|
+
this.code = code;
|
|
770
776
|
}
|
|
771
777
|
};
|
|
772
778
|
/**
|
|
@@ -774,10 +780,11 @@ var ForbiddenError = class ForbiddenError extends Error {
|
|
|
774
780
|
* @param msg - An optional error message.
|
|
775
781
|
*/
|
|
776
782
|
var TooManyRequestsError = class TooManyRequestsError extends Error {
|
|
777
|
-
constructor(msg) {
|
|
783
|
+
constructor(msg, code) {
|
|
778
784
|
super(msg || "Too many requests. You are being rate-limited.");
|
|
779
785
|
Object.setPrototypeOf(this, TooManyRequestsError.prototype);
|
|
780
786
|
this.name = "TooManyRequestsError";
|
|
787
|
+
this.code = code;
|
|
781
788
|
}
|
|
782
789
|
};
|
|
783
790
|
/**
|
|
@@ -785,10 +792,11 @@ var TooManyRequestsError = class TooManyRequestsError extends Error {
|
|
|
785
792
|
* @param msg - An optional error message.
|
|
786
793
|
*/
|
|
787
794
|
var RateLimitBanError = class RateLimitBanError extends Error {
|
|
788
|
-
constructor(msg) {
|
|
795
|
+
constructor(msg, code) {
|
|
789
796
|
super(msg || "The IP address has been banned for exceeding rate limits.");
|
|
790
797
|
Object.setPrototypeOf(this, RateLimitBanError.prototype);
|
|
791
798
|
this.name = "RateLimitBanError";
|
|
799
|
+
this.code = code;
|
|
792
800
|
}
|
|
793
801
|
};
|
|
794
802
|
/**
|
|
@@ -820,10 +828,11 @@ var NetworkError = class NetworkError extends Error {
|
|
|
820
828
|
* @param msg - An optional error message.
|
|
821
829
|
*/
|
|
822
830
|
var NotFoundError = class NotFoundError extends Error {
|
|
823
|
-
constructor(msg) {
|
|
831
|
+
constructor(msg, code) {
|
|
824
832
|
super(msg || "The requested resource was not found.");
|
|
825
833
|
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
826
834
|
this.name = "NotFoundError";
|
|
835
|
+
this.code = code;
|
|
827
836
|
}
|
|
828
837
|
};
|
|
829
838
|
/**
|
|
@@ -831,10 +840,11 @@ var NotFoundError = class NotFoundError extends Error {
|
|
|
831
840
|
* @param msg - An optional error message.
|
|
832
841
|
*/
|
|
833
842
|
var BadRequestError = class BadRequestError extends Error {
|
|
834
|
-
constructor(msg) {
|
|
843
|
+
constructor(msg, code) {
|
|
835
844
|
super(msg || "The request was invalid or cannot be otherwise served.");
|
|
836
845
|
Object.setPrototypeOf(this, BadRequestError.prototype);
|
|
837
846
|
this.name = "BadRequestError";
|
|
847
|
+
this.code = code;
|
|
838
848
|
}
|
|
839
849
|
};
|
|
840
850
|
|
|
@@ -952,10 +962,11 @@ var WebsocketCommon = class WebsocketCommon extends WebsocketEventEmitter {
|
|
|
952
962
|
* In 'single' mode, returns the first connection in the pool.
|
|
953
963
|
* In 'pool' mode, filters and returns connections that are ready for use.
|
|
954
964
|
* @param allowNonEstablishedWebsockets - Optional flag to include non-established WebSocket connections.
|
|
965
|
+
* @param urlPath - Optional URL path to filter connections.
|
|
955
966
|
* @returns An array of available WebSocket connections.
|
|
956
967
|
*/
|
|
957
|
-
getAvailableConnections(allowNonEstablishedWebsockets = false) {
|
|
958
|
-
if (this.mode === "single") return [this.connectionPool[0]];
|
|
968
|
+
getAvailableConnections(allowNonEstablishedWebsockets = false, urlPath) {
|
|
969
|
+
if (this.mode === "single" && !urlPath) return [this.connectionPool[0]];
|
|
959
970
|
return this.connectionPool.filter((connection) => this.isConnectionReady(connection, allowNonEstablishedWebsockets));
|
|
960
971
|
}
|
|
961
972
|
/**
|
|
@@ -964,10 +975,14 @@ var WebsocketCommon = class WebsocketCommon extends WebsocketEventEmitter {
|
|
|
964
975
|
* If the connection mode is 'pool', it returns an available connection from the pool,
|
|
965
976
|
* using a round-robin selection strategy. If no available connections are found, it throws an error.
|
|
966
977
|
* @param allowNonEstablishedWebsockets - A boolean indicating whether to allow connections that are not established.
|
|
978
|
+
* @param urlPath - An optional URL path to filter connections.
|
|
967
979
|
* @returns {WebsocketConnection} The selected WebSocket connection.
|
|
968
980
|
*/
|
|
969
|
-
getConnection(allowNonEstablishedWebsockets = false) {
|
|
970
|
-
const availableConnections = this.getAvailableConnections(allowNonEstablishedWebsockets)
|
|
981
|
+
getConnection(allowNonEstablishedWebsockets = false, urlPath) {
|
|
982
|
+
const availableConnections = this.getAvailableConnections(allowNonEstablishedWebsockets, urlPath).filter((connection) => {
|
|
983
|
+
if (urlPath) return connection.urlPath === urlPath;
|
|
984
|
+
return true;
|
|
985
|
+
});
|
|
971
986
|
if (availableConnections.length === 0) throw new Error("No available Websocket connections are ready.");
|
|
972
987
|
const selectedConnection = availableConnections[this.roundRobinIndex % availableConnections.length];
|
|
973
988
|
this.roundRobinIndex = (this.roundRobinIndex + 1) % availableConnections.length;
|
|
@@ -1165,14 +1180,15 @@ var WebsocketCommon = class WebsocketCommon extends WebsocketEventEmitter {
|
|
|
1165
1180
|
/**
|
|
1166
1181
|
* Connects all WebSocket connections in the pool
|
|
1167
1182
|
* @param url - The Websocket server URL.
|
|
1183
|
+
* @param connections - An optional array of WebSocket connections to connect. If not provided, all connections in the pool are connected.
|
|
1168
1184
|
* @returns A promise that resolves when all connections are established.
|
|
1169
1185
|
*/
|
|
1170
|
-
async connectPool(url) {
|
|
1171
|
-
const connectPromises = this.connectionPool.map((connection) => new Promise((resolve, reject) => {
|
|
1186
|
+
async connectPool(url, connections) {
|
|
1187
|
+
const connectPromises = (connections ?? this.connectionPool).map((connection) => new Promise((resolve, reject) => {
|
|
1172
1188
|
this.initConnect(url, false, connection);
|
|
1173
|
-
connection.ws?.
|
|
1174
|
-
connection.ws?.
|
|
1175
|
-
connection.ws?.
|
|
1189
|
+
connection.ws?.once("open", () => resolve());
|
|
1190
|
+
connection.ws?.once("error", (err) => reject(err));
|
|
1191
|
+
connection.ws?.once("close", () => reject(/* @__PURE__ */ new Error("Connection closed unexpectedly.")));
|
|
1176
1192
|
}));
|
|
1177
1193
|
await Promise.all(connectPromises);
|
|
1178
1194
|
}
|
|
@@ -1451,7 +1467,7 @@ var WebsocketAPIBase = class extends WebsocketCommon {
|
|
|
1451
1467
|
}
|
|
1452
1468
|
};
|
|
1453
1469
|
var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
1454
|
-
constructor(configuration, connectionPool = []) {
|
|
1470
|
+
constructor(configuration, connectionPool = [], urlPaths = []) {
|
|
1455
1471
|
super(configuration, connectionPool);
|
|
1456
1472
|
this.streamConnectionMap = /* @__PURE__ */ new Map();
|
|
1457
1473
|
this.streamIdIsStrictlyNumber = false;
|
|
@@ -1459,14 +1475,42 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1459
1475
|
this.logger = Logger.getInstance();
|
|
1460
1476
|
this.configuration = configuration;
|
|
1461
1477
|
this.wsURL = configuration.wsURL;
|
|
1478
|
+
this.urlPaths = urlPaths;
|
|
1479
|
+
this.ensurePoolSizeForUrlPaths();
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Ensures the connection pool has the required size based on the configured mode and number of URL paths.
|
|
1483
|
+
*
|
|
1484
|
+
* If no URL paths are configured, the method returns early without modifications.
|
|
1485
|
+
* In 'pool' mode, the pool size is multiplied by the number of URL paths.
|
|
1486
|
+
* In 'single' mode, only one connection per URL path is maintained.
|
|
1487
|
+
*
|
|
1488
|
+
* New connections are initialized with unique IDs and default state flags when the pool
|
|
1489
|
+
* size is less than the expected size.
|
|
1490
|
+
*
|
|
1491
|
+
* @private
|
|
1492
|
+
* @returns {void}
|
|
1493
|
+
*/
|
|
1494
|
+
ensurePoolSizeForUrlPaths() {
|
|
1495
|
+
if (this.urlPaths.length === 0) return;
|
|
1496
|
+
const expected = ((this.configuration?.mode ?? "single") === "pool" && this.configuration?.poolSize ? this.configuration.poolSize : 1) * this.urlPaths.length;
|
|
1497
|
+
while (this.connectionPool.length < expected) this.connectionPool.push({
|
|
1498
|
+
id: randomString(),
|
|
1499
|
+
closeInitiated: false,
|
|
1500
|
+
reconnectionPending: false,
|
|
1501
|
+
renewalPending: false,
|
|
1502
|
+
pendingRequests: /* @__PURE__ */ new Map(),
|
|
1503
|
+
pendingSubscriptions: []
|
|
1504
|
+
});
|
|
1462
1505
|
}
|
|
1463
1506
|
/**
|
|
1464
1507
|
* Formats the WebSocket URL for a given stream or streams.
|
|
1465
1508
|
* @param streams - Array of stream names to include in the URL.
|
|
1509
|
+
* @param urlPath - Optional URL path to include in the WebSocket URL.
|
|
1466
1510
|
* @returns The formatted WebSocket URL with the provided streams.
|
|
1467
1511
|
*/
|
|
1468
|
-
prepareURL(streams = []) {
|
|
1469
|
-
let url = `${this.wsURL}/stream?streams=${streams.join("/")}`;
|
|
1512
|
+
prepareURL(streams = [], urlPath) {
|
|
1513
|
+
let url = `${urlPath ? `${this.wsURL}/${urlPath}` : this.wsURL}/stream?streams=${streams.join("/")}`;
|
|
1470
1514
|
if (this.configuration?.timeUnit) try {
|
|
1471
1515
|
const _timeUnit = validateTimeUnit(this.configuration.timeUnit);
|
|
1472
1516
|
url = `${url}${url.includes("?") ? "&" : "?"}timeUnit=${_timeUnit}`;
|
|
@@ -1482,22 +1526,24 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1482
1526
|
* @returns The formatted WebSocket URL with streams and optional parameters.
|
|
1483
1527
|
*/
|
|
1484
1528
|
getReconnectURL(url, targetConnection) {
|
|
1485
|
-
const streams = Array.from(this.streamConnectionMap.keys()).filter((stream) => this.streamConnectionMap.get(stream) === targetConnection);
|
|
1486
|
-
return this.prepareURL(streams);
|
|
1529
|
+
const streams = Array.from(this.streamConnectionMap.keys()).filter((stream) => this.streamConnectionMap.get(stream) === targetConnection).map((key) => key.includes("::") ? key.split("::").slice(1).join("::") : key);
|
|
1530
|
+
return this.prepareURL(streams, targetConnection?.urlPath);
|
|
1487
1531
|
}
|
|
1488
1532
|
/**
|
|
1489
1533
|
* Handles subscription to streams and assigns them to specific connections
|
|
1490
1534
|
* @param streams Array of stream names to subscribe to
|
|
1535
|
+
* @param urlPath Optional URL path for the streams
|
|
1491
1536
|
* @returns Map of connections to streams
|
|
1492
1537
|
*/
|
|
1493
|
-
handleStreamAssignment(streams) {
|
|
1538
|
+
handleStreamAssignment(streams, urlPath) {
|
|
1494
1539
|
const connectionStreamMap = /* @__PURE__ */ new Map();
|
|
1495
1540
|
streams.forEach((stream) => {
|
|
1496
|
-
|
|
1497
|
-
|
|
1541
|
+
const key = this.streamKey(stream, urlPath);
|
|
1542
|
+
if (!this.streamCallbackMap.has(key)) this.streamCallbackMap.set(key, /* @__PURE__ */ new Set());
|
|
1543
|
+
let connection = this.streamConnectionMap.get(key);
|
|
1498
1544
|
if (!connection || connection.closeInitiated || connection.reconnectionPending) {
|
|
1499
|
-
connection = this.getConnection(true);
|
|
1500
|
-
this.streamConnectionMap.set(
|
|
1545
|
+
connection = this.getConnection(true, urlPath);
|
|
1546
|
+
this.streamConnectionMap.set(key, connection);
|
|
1501
1547
|
}
|
|
1502
1548
|
if (!connectionStreamMap.has(connection)) connectionStreamMap.set(connection, []);
|
|
1503
1549
|
connectionStreamMap.get(connection)?.push(stream);
|
|
@@ -1543,7 +1589,10 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1543
1589
|
try {
|
|
1544
1590
|
const parsedData = JSONParse(data);
|
|
1545
1591
|
const streamName = parsedData?.stream;
|
|
1546
|
-
if (streamName
|
|
1592
|
+
if (streamName) {
|
|
1593
|
+
const key = this.streamKey(streamName, connection?.urlPath);
|
|
1594
|
+
if (this.streamCallbackMap.has(key)) this.streamCallbackMap.get(key)?.forEach((callback) => callback(parsedData.data));
|
|
1595
|
+
}
|
|
1547
1596
|
} catch (error) {
|
|
1548
1597
|
this.logger.error("Failed to parse WebSocket message:", data, error);
|
|
1549
1598
|
}
|
|
@@ -1561,6 +1610,15 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1561
1610
|
super.onOpen(url, targetConnection, oldWSConnection);
|
|
1562
1611
|
}
|
|
1563
1612
|
/**
|
|
1613
|
+
* Generates a stream key by combining a stream name with an optional URL path.
|
|
1614
|
+
* @param stream - The stream name to use as the key or suffix.
|
|
1615
|
+
* @param urlPath - Optional URL path to prepend to the stream name.
|
|
1616
|
+
* @returns A stream key in the format `urlPath::stream` if urlPath is provided, otherwise just the stream name.
|
|
1617
|
+
*/
|
|
1618
|
+
streamKey(stream, urlPath) {
|
|
1619
|
+
return urlPath ? `${urlPath}::${stream}` : stream;
|
|
1620
|
+
}
|
|
1621
|
+
/**
|
|
1564
1622
|
* Connects to the WebSocket server and subscribes to the specified streams.
|
|
1565
1623
|
* This method returns a Promise that resolves when the connection is established,
|
|
1566
1624
|
* or rejects with an error if the connection fails to be established within 10 seconds.
|
|
@@ -1573,7 +1631,15 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1573
1631
|
const timeout = setTimeout(() => {
|
|
1574
1632
|
reject(/* @__PURE__ */ new Error("Websocket connection timed out"));
|
|
1575
1633
|
}, 1e4);
|
|
1576
|
-
|
|
1634
|
+
const basePoolSize = (this.configuration?.mode ?? "single") === "pool" && this.configuration?.poolSize ? this.configuration.poolSize : 1;
|
|
1635
|
+
const connections = this.urlPaths.length > 0 ? this.urlPaths.map((path, i) => {
|
|
1636
|
+
const start = i * basePoolSize;
|
|
1637
|
+
const end = start + basePoolSize;
|
|
1638
|
+
const subset = this.connectionPool.slice(start, end);
|
|
1639
|
+
subset.forEach((c) => c.urlPath = path);
|
|
1640
|
+
return this.connectPool(this.prepareURL(streams, path), subset);
|
|
1641
|
+
}) : [this.connectPool(this.prepareURL(streams))];
|
|
1642
|
+
Promise.all(connections).then(() => resolve()).catch((error) => reject(error)).finally(() => clearTimeout(timeout));
|
|
1577
1643
|
});
|
|
1578
1644
|
}
|
|
1579
1645
|
/**
|
|
@@ -1590,17 +1656,21 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1590
1656
|
* Handles both single and pool modes
|
|
1591
1657
|
* @param stream Single stream name or array of stream names to subscribe to
|
|
1592
1658
|
* @param id Optional subscription ID
|
|
1659
|
+
* @param urlPath Optional URL path for the streams
|
|
1593
1660
|
* @returns void
|
|
1594
1661
|
*/
|
|
1595
|
-
subscribe(stream, id) {
|
|
1596
|
-
const streams = (Array.isArray(stream) ? stream : [stream]).filter((stream$1) =>
|
|
1597
|
-
|
|
1662
|
+
subscribe(stream, id, urlPath) {
|
|
1663
|
+
const streams = (Array.isArray(stream) ? stream : [stream]).filter((stream$1) => {
|
|
1664
|
+
const key = this.streamKey(stream$1, urlPath);
|
|
1665
|
+
return !this.streamConnectionMap.has(key);
|
|
1666
|
+
});
|
|
1667
|
+
this.handleStreamAssignment(streams, urlPath).forEach((assignedStreams, connection) => {
|
|
1598
1668
|
if (!this.isConnected(connection)) {
|
|
1599
|
-
this.logger.info(`Connection ${connection.id} is not ready. Queuing subscription for streams: ${
|
|
1600
|
-
connection.pendingSubscriptions?.push(...
|
|
1669
|
+
this.logger.info(`Connection ${connection.id} is not ready. Queuing subscription for streams: ${assignedStreams}`);
|
|
1670
|
+
connection.pendingSubscriptions?.push(...assignedStreams);
|
|
1601
1671
|
return;
|
|
1602
1672
|
}
|
|
1603
|
-
this.sendSubscriptionPayload(connection,
|
|
1673
|
+
this.sendSubscriptionPayload(connection, assignedStreams, id);
|
|
1604
1674
|
});
|
|
1605
1675
|
}
|
|
1606
1676
|
/**
|
|
@@ -1608,16 +1678,18 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1608
1678
|
* Handles both single and pool modes
|
|
1609
1679
|
* @param stream Single stream name or array of stream names to unsubscribe from
|
|
1610
1680
|
* @param id Optional unsubscription ID
|
|
1681
|
+
* @param urlPath Optional URL path for the streams
|
|
1611
1682
|
* @returns void
|
|
1612
1683
|
*/
|
|
1613
|
-
unsubscribe(stream, id) {
|
|
1684
|
+
unsubscribe(stream, id, urlPath) {
|
|
1614
1685
|
(Array.isArray(stream) ? stream : [stream]).forEach((stream$1) => {
|
|
1615
|
-
const
|
|
1686
|
+
const key = this.streamKey(stream$1, urlPath);
|
|
1687
|
+
const connection = this.streamConnectionMap.get(key);
|
|
1616
1688
|
if (!connection || !connection.ws || !this.isConnected(connection)) {
|
|
1617
1689
|
this.logger.warn(`Stream ${stream$1} not associated with an active connection.`);
|
|
1618
1690
|
return;
|
|
1619
1691
|
}
|
|
1620
|
-
if (!this.streamCallbackMap.has(
|
|
1692
|
+
if (!this.streamCallbackMap.has(key) || this.streamCallbackMap.get(key)?.size === 0) {
|
|
1621
1693
|
const payload = {
|
|
1622
1694
|
method: "UNSUBSCRIBE",
|
|
1623
1695
|
params: [stream$1],
|
|
@@ -1625,8 +1697,8 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1625
1697
|
};
|
|
1626
1698
|
this.logger.debug("UNSUBSCRIBE", payload);
|
|
1627
1699
|
this.send(JSON.stringify(payload), void 0, false, 0, connection);
|
|
1628
|
-
this.streamConnectionMap.delete(
|
|
1629
|
-
this.streamCallbackMap.delete(
|
|
1700
|
+
this.streamConnectionMap.delete(key);
|
|
1701
|
+
this.streamCallbackMap.delete(key);
|
|
1630
1702
|
}
|
|
1631
1703
|
});
|
|
1632
1704
|
}
|
|
@@ -1636,7 +1708,9 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1636
1708
|
* @returns `true` if the stream is currently subscribed, `false` otherwise.
|
|
1637
1709
|
*/
|
|
1638
1710
|
isSubscribed(stream) {
|
|
1639
|
-
|
|
1711
|
+
if (this.streamConnectionMap.has(stream)) return true;
|
|
1712
|
+
for (const key of this.streamConnectionMap.keys()) if (key.endsWith(`::${stream}`)) return true;
|
|
1713
|
+
return false;
|
|
1640
1714
|
}
|
|
1641
1715
|
};
|
|
1642
1716
|
/**
|
|
@@ -1646,10 +1720,12 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1646
1720
|
* @param {WebsocketAPIBase | WebsocketStreamsBase} websocketBase The WebSocket base instance
|
|
1647
1721
|
* @param {string} streamOrId The stream identifier
|
|
1648
1722
|
* @param {string} [id] Optional additional identifier
|
|
1723
|
+
* @param {string} [urlPath] Optional URL path for the stream
|
|
1649
1724
|
* @returns {WebsocketStream<T>} A stream handler with methods to register callbacks and unsubscribe
|
|
1650
1725
|
*/
|
|
1651
|
-
function createStreamHandler(websocketBase, streamOrId, id) {
|
|
1652
|
-
|
|
1726
|
+
function createStreamHandler(websocketBase, streamOrId, id, urlPath) {
|
|
1727
|
+
const key = websocketBase instanceof WebsocketStreamsBase ? websocketBase.streamKey(streamOrId, urlPath) : streamOrId;
|
|
1728
|
+
if (websocketBase instanceof WebsocketStreamsBase) websocketBase.subscribe(streamOrId, id, urlPath);
|
|
1653
1729
|
let registeredCallback;
|
|
1654
1730
|
return {
|
|
1655
1731
|
on: (event, callback) => {
|
|
@@ -1659,18 +1735,18 @@ function createStreamHandler(websocketBase, streamOrId, id) {
|
|
|
1659
1735
|
websocketBase.logger.error(`Error in stream callback: ${err}`);
|
|
1660
1736
|
});
|
|
1661
1737
|
};
|
|
1662
|
-
const callbackSet = websocketBase.streamCallbackMap.get(
|
|
1738
|
+
const callbackSet = websocketBase.streamCallbackMap.get(key) ?? /* @__PURE__ */ new Set();
|
|
1663
1739
|
callbackSet.add(registeredCallback);
|
|
1664
|
-
websocketBase.streamCallbackMap.set(
|
|
1740
|
+
websocketBase.streamCallbackMap.set(key, callbackSet);
|
|
1665
1741
|
}
|
|
1666
1742
|
},
|
|
1667
1743
|
unsubscribe: () => {
|
|
1668
|
-
if (registeredCallback) websocketBase.streamCallbackMap.get(
|
|
1669
|
-
if (websocketBase instanceof WebsocketStreamsBase) websocketBase.unsubscribe(streamOrId, id);
|
|
1744
|
+
if (registeredCallback) websocketBase.streamCallbackMap.get(key)?.delete(registeredCallback);
|
|
1745
|
+
if (websocketBase instanceof WebsocketStreamsBase) websocketBase.unsubscribe(streamOrId, id, urlPath);
|
|
1670
1746
|
}
|
|
1671
1747
|
};
|
|
1672
1748
|
}
|
|
1673
1749
|
|
|
1674
1750
|
//#endregion
|
|
1675
|
-
export { ALGO_REST_API_PROD_URL, BadRequestError, C2C_REST_API_PROD_URL, CONVERT_REST_API_PROD_URL, COPY_TRADING_REST_API_PROD_URL, CRYPTO_LOAN_REST_API_PROD_URL, ConfigurationRestAPI, ConfigurationWebsocketAPI, ConfigurationWebsocketStreams, ConnectorClientError, DERIVATIVES_TRADING_COIN_FUTURES_REST_API_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_REST_API_TESTNET_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_API_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_API_TESTNET_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL, DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_REST_API_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_REST_API_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_REST_API_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_API_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL, DUAL_INVESTMENT_REST_API_PROD_URL, FIAT_REST_API_PROD_URL, ForbiddenError, GIFT_CARD_REST_API_PROD_URL, LogLevel, Logger, MARGIN_TRADING_REST_API_PROD_URL, MARGIN_TRADING_RISK_WS_STREAMS_PROD_URL, MARGIN_TRADING_WS_STREAMS_PROD_URL, MINING_REST_API_PROD_URL, NFT_REST_API_PROD_URL, NetworkError, NotFoundError, PAY_REST_API_PROD_URL, REBATE_REST_API_PROD_URL, RateLimitBanError, RequiredError, SIMPLE_EARN_REST_API_PROD_URL, SPOT_REST_API_MARKET_URL, SPOT_REST_API_PROD_URL, SPOT_REST_API_TESTNET_URL, SPOT_WS_API_PROD_URL, SPOT_WS_API_TESTNET_URL, SPOT_WS_STREAMS_MARKET_URL, SPOT_WS_STREAMS_PROD_URL, SPOT_WS_STREAMS_TESTNET_URL, STAKING_REST_API_PROD_URL, SUB_ACCOUNT_REST_API_PROD_URL, ServerError, TimeUnit, TooManyRequestsError, UnauthorizedError, VIP_LOAN_REST_API_PROD_URL, WALLET_REST_API_PROD_URL, WebsocketAPIBase, WebsocketCommon, WebsocketEventEmitter, WebsocketStreamsBase, assertParamExists, buildQueryString, buildUserAgent, buildWebsocketAPIMessage, clearSignerCache, createStreamHandler, delay, getSignature, getTimestamp, httpRequestFunction, normalizeScientificNumbers, normalizeStreamId, parseCustomHeaders, parseRateLimitHeaders, randomInteger, randomString, removeEmptyValue, replaceWebsocketStreamsPlaceholders, sanitizeHeaderValue, sendRequest, setSearchParams, shouldRetryRequest, sortObject, toPathString, validateTimeUnit };
|
|
1751
|
+
export { ALGO_REST_API_PROD_URL, BadRequestError, C2C_REST_API_PROD_URL, CONVERT_REST_API_PROD_URL, COPY_TRADING_REST_API_PROD_URL, CRYPTO_LOAN_REST_API_PROD_URL, ConfigurationRestAPI, ConfigurationWebsocketAPI, ConfigurationWebsocketStreams, ConnectorClientError, DERIVATIVES_TRADING_COIN_FUTURES_REST_API_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_REST_API_TESTNET_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_API_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_API_TESTNET_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_COIN_FUTURES_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL, DERIVATIVES_TRADING_OPTIONS_REST_API_TESTNET_URL, DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_REST_API_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_PRO_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_REST_API_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_REST_API_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_API_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL, DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL, DUAL_INVESTMENT_REST_API_PROD_URL, FIAT_REST_API_PROD_URL, ForbiddenError, GIFT_CARD_REST_API_PROD_URL, LogLevel, Logger, MARGIN_TRADING_REST_API_PROD_URL, MARGIN_TRADING_RISK_WS_STREAMS_PROD_URL, MARGIN_TRADING_WS_STREAMS_PROD_URL, MINING_REST_API_PROD_URL, NFT_REST_API_PROD_URL, NetworkError, NotFoundError, PAY_REST_API_PROD_URL, REBATE_REST_API_PROD_URL, RateLimitBanError, RequiredError, SIMPLE_EARN_REST_API_PROD_URL, SPOT_REST_API_MARKET_URL, SPOT_REST_API_PROD_URL, SPOT_REST_API_TESTNET_URL, SPOT_WS_API_PROD_URL, SPOT_WS_API_TESTNET_URL, SPOT_WS_STREAMS_MARKET_URL, SPOT_WS_STREAMS_PROD_URL, SPOT_WS_STREAMS_TESTNET_URL, STAKING_REST_API_PROD_URL, SUB_ACCOUNT_REST_API_PROD_URL, ServerError, TimeUnit, TooManyRequestsError, UnauthorizedError, VIP_LOAN_REST_API_PROD_URL, WALLET_REST_API_PROD_URL, WebsocketAPIBase, WebsocketCommon, WebsocketEventEmitter, WebsocketStreamsBase, assertParamExists, buildQueryString, buildUserAgent, buildWebsocketAPIMessage, clearSignerCache, createStreamHandler, delay, getSignature, getTimestamp, httpRequestFunction, normalizeScientificNumbers, normalizeStreamId, parseCustomHeaders, parseRateLimitHeaders, randomInteger, randomString, removeEmptyValue, replaceWebsocketStreamsPlaceholders, sanitizeHeaderValue, sendRequest, setSearchParams, shouldRetryRequest, sortObject, toPathString, validateTimeUnit };
|
|
1676
1752
|
//# sourceMappingURL=index.mjs.map
|