@binance/common 2.1.0 → 2.2.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 +70 -9
- package/dist/index.d.ts +70 -9
- package/dist/index.js +151 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +148 -43
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -112,6 +112,42 @@ function randomString() {
|
|
|
112
112
|
return crypto.randomBytes(16).toString("hex");
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
115
|
+
* Generates a cryptographically secure random 32-bit unsigned integer.
|
|
116
|
+
*
|
|
117
|
+
* Uses the Web Crypto API to generate a random value between 0 and 4,294,967,295 (2^32 - 1).
|
|
118
|
+
*
|
|
119
|
+
* @returns A random 32-bit unsigned integer.
|
|
120
|
+
*/
|
|
121
|
+
function randomInteger() {
|
|
122
|
+
const array = new Uint32Array(1);
|
|
123
|
+
crypto.getRandomValues(array);
|
|
124
|
+
return array[0];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Normalizes a stream ID to ensure it is valid, generating a random ID if needed.
|
|
128
|
+
*
|
|
129
|
+
* For string inputs:
|
|
130
|
+
* - Returns the input if it's a valid 32-character hexadecimal string (case-insensitive)
|
|
131
|
+
* - Otherwise, generates a new random hexadecimal string using `randomString()`
|
|
132
|
+
*
|
|
133
|
+
* For number inputs:
|
|
134
|
+
* - Returns the input if it's a finite, non-negative integer within the safe integer range
|
|
135
|
+
* - Otherwise, generates a new random integer using `randomInteger()`
|
|
136
|
+
*
|
|
137
|
+
* For null or undefined inputs:
|
|
138
|
+
* - Generates a new random hexadecimal string using `randomString()`
|
|
139
|
+
*
|
|
140
|
+
* @param id - The stream ID to normalize (string, number, null, or undefined).
|
|
141
|
+
* @param streamIdIsStrictlyNumber - Boolean forcing an id to be a number or not.
|
|
142
|
+
* @returns A valid stream ID as either a 32-character hexadecimal string or a safe integer.
|
|
143
|
+
*/
|
|
144
|
+
function normalizeStreamId(id, streamIdIsStrictlyNumber) {
|
|
145
|
+
const isValidNumber = typeof id === "number" && Number.isFinite(id) && Number.isInteger(id) && id >= 0 && id <= Number.MAX_SAFE_INTEGER;
|
|
146
|
+
if (streamIdIsStrictlyNumber || typeof id === "number") return isValidNumber ? id : randomInteger();
|
|
147
|
+
if (typeof id === "string") return id && /^[0-9a-f]{32}$/i.test(id) ? id : randomString();
|
|
148
|
+
return randomString();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
115
151
|
* Validates the provided time unit string and returns it if it is either 'MILLISECOND' or 'MICROSECOND'.
|
|
116
152
|
*
|
|
117
153
|
* @param timeUnit - The time unit string to be validated.
|
|
@@ -654,7 +690,9 @@ const DERIVATIVES_TRADING_USDS_FUTURES_WS_API_TESTNET_URL = "wss://testnet.binan
|
|
|
654
690
|
const DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_PROD_URL = "wss://fstream.binance.com";
|
|
655
691
|
const DERIVATIVES_TRADING_USDS_FUTURES_WS_STREAMS_TESTNET_URL = "wss://stream.binancefuture.com";
|
|
656
692
|
const DERIVATIVES_TRADING_OPTIONS_REST_API_PROD_URL = "https://eapi.binance.com";
|
|
657
|
-
const
|
|
693
|
+
const DERIVATIVES_TRADING_OPTIONS_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
|
|
694
|
+
const DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_PROD_URL = "wss://fstream.binance.com";
|
|
695
|
+
const DERIVATIVES_TRADING_OPTIONS_WS_STREAMS_TESTNET_URL = "wss://fstream.binancefuture.com";
|
|
658
696
|
const DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_PROD_URL = "https://papi.binance.com";
|
|
659
697
|
const DERIVATIVES_TRADING_PORTFOLIO_MARGIN_REST_API_TESTNET_URL = "https://testnet.binancefuture.com";
|
|
660
698
|
const DERIVATIVES_TRADING_PORTFOLIO_MARGIN_WS_STREAMS_PROD_URL = "wss://fstream.binance.com/pm";
|
|
@@ -916,10 +954,11 @@ var WebsocketCommon = class WebsocketCommon extends WebsocketEventEmitter {
|
|
|
916
954
|
* In 'single' mode, returns the first connection in the pool.
|
|
917
955
|
* In 'pool' mode, filters and returns connections that are ready for use.
|
|
918
956
|
* @param allowNonEstablishedWebsockets - Optional flag to include non-established WebSocket connections.
|
|
957
|
+
* @param urlPath - Optional URL path to filter connections.
|
|
919
958
|
* @returns An array of available WebSocket connections.
|
|
920
959
|
*/
|
|
921
|
-
getAvailableConnections(allowNonEstablishedWebsockets = false) {
|
|
922
|
-
if (this.mode === "single") return [this.connectionPool[0]];
|
|
960
|
+
getAvailableConnections(allowNonEstablishedWebsockets = false, urlPath) {
|
|
961
|
+
if (this.mode === "single" && !urlPath) return [this.connectionPool[0]];
|
|
923
962
|
return this.connectionPool.filter((connection) => this.isConnectionReady(connection, allowNonEstablishedWebsockets));
|
|
924
963
|
}
|
|
925
964
|
/**
|
|
@@ -928,10 +967,14 @@ var WebsocketCommon = class WebsocketCommon extends WebsocketEventEmitter {
|
|
|
928
967
|
* If the connection mode is 'pool', it returns an available connection from the pool,
|
|
929
968
|
* using a round-robin selection strategy. If no available connections are found, it throws an error.
|
|
930
969
|
* @param allowNonEstablishedWebsockets - A boolean indicating whether to allow connections that are not established.
|
|
970
|
+
* @param urlPath - An optional URL path to filter connections.
|
|
931
971
|
* @returns {WebsocketConnection} The selected WebSocket connection.
|
|
932
972
|
*/
|
|
933
|
-
getConnection(allowNonEstablishedWebsockets = false) {
|
|
934
|
-
const availableConnections = this.getAvailableConnections(allowNonEstablishedWebsockets)
|
|
973
|
+
getConnection(allowNonEstablishedWebsockets = false, urlPath) {
|
|
974
|
+
const availableConnections = this.getAvailableConnections(allowNonEstablishedWebsockets, urlPath).filter((connection) => {
|
|
975
|
+
if (urlPath) return connection.urlPath === urlPath;
|
|
976
|
+
return true;
|
|
977
|
+
});
|
|
935
978
|
if (availableConnections.length === 0) throw new Error("No available Websocket connections are ready.");
|
|
936
979
|
const selectedConnection = availableConnections[this.roundRobinIndex % availableConnections.length];
|
|
937
980
|
this.roundRobinIndex = (this.roundRobinIndex + 1) % availableConnections.length;
|
|
@@ -1129,14 +1172,15 @@ var WebsocketCommon = class WebsocketCommon extends WebsocketEventEmitter {
|
|
|
1129
1172
|
/**
|
|
1130
1173
|
* Connects all WebSocket connections in the pool
|
|
1131
1174
|
* @param url - The Websocket server URL.
|
|
1175
|
+
* @param connections - An optional array of WebSocket connections to connect. If not provided, all connections in the pool are connected.
|
|
1132
1176
|
* @returns A promise that resolves when all connections are established.
|
|
1133
1177
|
*/
|
|
1134
|
-
async connectPool(url) {
|
|
1135
|
-
const connectPromises = this.connectionPool.map((connection) => new Promise((resolve, reject) => {
|
|
1178
|
+
async connectPool(url, connections) {
|
|
1179
|
+
const connectPromises = (connections ?? this.connectionPool).map((connection) => new Promise((resolve, reject) => {
|
|
1136
1180
|
this.initConnect(url, false, connection);
|
|
1137
|
-
connection.ws?.
|
|
1138
|
-
connection.ws?.
|
|
1139
|
-
connection.ws?.
|
|
1181
|
+
connection.ws?.once("open", () => resolve());
|
|
1182
|
+
connection.ws?.once("error", (err) => reject(err));
|
|
1183
|
+
connection.ws?.once("close", () => reject(/* @__PURE__ */ new Error("Connection closed unexpectedly.")));
|
|
1140
1184
|
}));
|
|
1141
1185
|
await Promise.all(connectPromises);
|
|
1142
1186
|
}
|
|
@@ -1415,21 +1459,50 @@ var WebsocketAPIBase = class extends WebsocketCommon {
|
|
|
1415
1459
|
}
|
|
1416
1460
|
};
|
|
1417
1461
|
var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
1418
|
-
constructor(configuration, connectionPool = []) {
|
|
1462
|
+
constructor(configuration, connectionPool = [], urlPaths = []) {
|
|
1419
1463
|
super(configuration, connectionPool);
|
|
1420
1464
|
this.streamConnectionMap = /* @__PURE__ */ new Map();
|
|
1465
|
+
this.streamIdIsStrictlyNumber = false;
|
|
1421
1466
|
this.streamCallbackMap = /* @__PURE__ */ new Map();
|
|
1422
1467
|
this.logger = Logger.getInstance();
|
|
1423
1468
|
this.configuration = configuration;
|
|
1424
1469
|
this.wsURL = configuration.wsURL;
|
|
1470
|
+
this.urlPaths = urlPaths;
|
|
1471
|
+
this.ensurePoolSizeForUrlPaths();
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* Ensures the connection pool has the required size based on the configured mode and number of URL paths.
|
|
1475
|
+
*
|
|
1476
|
+
* If no URL paths are configured, the method returns early without modifications.
|
|
1477
|
+
* In 'pool' mode, the pool size is multiplied by the number of URL paths.
|
|
1478
|
+
* In 'single' mode, only one connection per URL path is maintained.
|
|
1479
|
+
*
|
|
1480
|
+
* New connections are initialized with unique IDs and default state flags when the pool
|
|
1481
|
+
* size is less than the expected size.
|
|
1482
|
+
*
|
|
1483
|
+
* @private
|
|
1484
|
+
* @returns {void}
|
|
1485
|
+
*/
|
|
1486
|
+
ensurePoolSizeForUrlPaths() {
|
|
1487
|
+
if (this.urlPaths.length === 0) return;
|
|
1488
|
+
const expected = ((this.configuration?.mode ?? "single") === "pool" && this.configuration?.poolSize ? this.configuration.poolSize : 1) * this.urlPaths.length;
|
|
1489
|
+
while (this.connectionPool.length < expected) this.connectionPool.push({
|
|
1490
|
+
id: randomString(),
|
|
1491
|
+
closeInitiated: false,
|
|
1492
|
+
reconnectionPending: false,
|
|
1493
|
+
renewalPending: false,
|
|
1494
|
+
pendingRequests: /* @__PURE__ */ new Map(),
|
|
1495
|
+
pendingSubscriptions: []
|
|
1496
|
+
});
|
|
1425
1497
|
}
|
|
1426
1498
|
/**
|
|
1427
1499
|
* Formats the WebSocket URL for a given stream or streams.
|
|
1428
1500
|
* @param streams - Array of stream names to include in the URL.
|
|
1501
|
+
* @param urlPath - Optional URL path to include in the WebSocket URL.
|
|
1429
1502
|
* @returns The formatted WebSocket URL with the provided streams.
|
|
1430
1503
|
*/
|
|
1431
|
-
prepareURL(streams = []) {
|
|
1432
|
-
let url = `${this.wsURL}/stream?streams=${streams.join("/")}`;
|
|
1504
|
+
prepareURL(streams = [], urlPath) {
|
|
1505
|
+
let url = `${urlPath ? `${this.wsURL}/${urlPath}` : this.wsURL}/stream?streams=${streams.join("/")}`;
|
|
1433
1506
|
if (this.configuration?.timeUnit) try {
|
|
1434
1507
|
const _timeUnit = validateTimeUnit(this.configuration.timeUnit);
|
|
1435
1508
|
url = `${url}${url.includes("?") ? "&" : "?"}timeUnit=${_timeUnit}`;
|
|
@@ -1445,22 +1518,24 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1445
1518
|
* @returns The formatted WebSocket URL with streams and optional parameters.
|
|
1446
1519
|
*/
|
|
1447
1520
|
getReconnectURL(url, targetConnection) {
|
|
1448
|
-
const streams = Array.from(this.streamConnectionMap.keys()).filter((stream) => this.streamConnectionMap.get(stream) === targetConnection);
|
|
1449
|
-
return this.prepareURL(streams);
|
|
1521
|
+
const streams = Array.from(this.streamConnectionMap.keys()).filter((stream) => this.streamConnectionMap.get(stream) === targetConnection).map((key) => key.includes("::") ? key.split("::").slice(1).join("::") : key);
|
|
1522
|
+
return this.prepareURL(streams, targetConnection?.urlPath);
|
|
1450
1523
|
}
|
|
1451
1524
|
/**
|
|
1452
1525
|
* Handles subscription to streams and assigns them to specific connections
|
|
1453
1526
|
* @param streams Array of stream names to subscribe to
|
|
1527
|
+
* @param urlPath Optional URL path for the streams
|
|
1454
1528
|
* @returns Map of connections to streams
|
|
1455
1529
|
*/
|
|
1456
|
-
handleStreamAssignment(streams) {
|
|
1530
|
+
handleStreamAssignment(streams, urlPath) {
|
|
1457
1531
|
const connectionStreamMap = /* @__PURE__ */ new Map();
|
|
1458
1532
|
streams.forEach((stream) => {
|
|
1459
|
-
|
|
1460
|
-
|
|
1533
|
+
const key = this.streamKey(stream, urlPath);
|
|
1534
|
+
if (!this.streamCallbackMap.has(key)) this.streamCallbackMap.set(key, /* @__PURE__ */ new Set());
|
|
1535
|
+
let connection = this.streamConnectionMap.get(key);
|
|
1461
1536
|
if (!connection || connection.closeInitiated || connection.reconnectionPending) {
|
|
1462
|
-
connection = this.getConnection(true);
|
|
1463
|
-
this.streamConnectionMap.set(
|
|
1537
|
+
connection = this.getConnection(true, urlPath);
|
|
1538
|
+
this.streamConnectionMap.set(key, connection);
|
|
1464
1539
|
}
|
|
1465
1540
|
if (!connectionStreamMap.has(connection)) connectionStreamMap.set(connection, []);
|
|
1466
1541
|
connectionStreamMap.get(connection)?.push(stream);
|
|
@@ -1477,7 +1552,7 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1477
1552
|
const payload = {
|
|
1478
1553
|
method: "SUBSCRIBE",
|
|
1479
1554
|
params: streams,
|
|
1480
|
-
id:
|
|
1555
|
+
id: normalizeStreamId(id, this.streamIdIsStrictlyNumber)
|
|
1481
1556
|
};
|
|
1482
1557
|
this.logger.debug("SUBSCRIBE", payload);
|
|
1483
1558
|
this.send(JSON.stringify(payload), void 0, false, 0, connection);
|
|
@@ -1506,7 +1581,10 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1506
1581
|
try {
|
|
1507
1582
|
const parsedData = JSONParse(data);
|
|
1508
1583
|
const streamName = parsedData?.stream;
|
|
1509
|
-
if (streamName
|
|
1584
|
+
if (streamName) {
|
|
1585
|
+
const key = this.streamKey(streamName, connection?.urlPath);
|
|
1586
|
+
if (this.streamCallbackMap.has(key)) this.streamCallbackMap.get(key)?.forEach((callback) => callback(parsedData.data));
|
|
1587
|
+
}
|
|
1510
1588
|
} catch (error) {
|
|
1511
1589
|
this.logger.error("Failed to parse WebSocket message:", data, error);
|
|
1512
1590
|
}
|
|
@@ -1524,6 +1602,15 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1524
1602
|
super.onOpen(url, targetConnection, oldWSConnection);
|
|
1525
1603
|
}
|
|
1526
1604
|
/**
|
|
1605
|
+
* Generates a stream key by combining a stream name with an optional URL path.
|
|
1606
|
+
* @param stream - The stream name to use as the key or suffix.
|
|
1607
|
+
* @param urlPath - Optional URL path to prepend to the stream name.
|
|
1608
|
+
* @returns A stream key in the format `urlPath::stream` if urlPath is provided, otherwise just the stream name.
|
|
1609
|
+
*/
|
|
1610
|
+
streamKey(stream, urlPath) {
|
|
1611
|
+
return urlPath ? `${urlPath}::${stream}` : stream;
|
|
1612
|
+
}
|
|
1613
|
+
/**
|
|
1527
1614
|
* Connects to the WebSocket server and subscribes to the specified streams.
|
|
1528
1615
|
* This method returns a Promise that resolves when the connection is established,
|
|
1529
1616
|
* or rejects with an error if the connection fails to be established within 10 seconds.
|
|
@@ -1536,7 +1623,15 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1536
1623
|
const timeout = setTimeout(() => {
|
|
1537
1624
|
reject(/* @__PURE__ */ new Error("Websocket connection timed out"));
|
|
1538
1625
|
}, 1e4);
|
|
1539
|
-
|
|
1626
|
+
const basePoolSize = (this.configuration?.mode ?? "single") === "pool" && this.configuration?.poolSize ? this.configuration.poolSize : 1;
|
|
1627
|
+
const connections = this.urlPaths.length > 0 ? this.urlPaths.map((path, i) => {
|
|
1628
|
+
const start = i * basePoolSize;
|
|
1629
|
+
const end = start + basePoolSize;
|
|
1630
|
+
const subset = this.connectionPool.slice(start, end);
|
|
1631
|
+
subset.forEach((c) => c.urlPath = path);
|
|
1632
|
+
return this.connectPool(this.prepareURL(streams, path), subset);
|
|
1633
|
+
}) : [this.connectPool(this.prepareURL(streams))];
|
|
1634
|
+
Promise.all(connections).then(() => resolve()).catch((error) => reject(error)).finally(() => clearTimeout(timeout));
|
|
1540
1635
|
});
|
|
1541
1636
|
}
|
|
1542
1637
|
/**
|
|
@@ -1553,17 +1648,21 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1553
1648
|
* Handles both single and pool modes
|
|
1554
1649
|
* @param stream Single stream name or array of stream names to subscribe to
|
|
1555
1650
|
* @param id Optional subscription ID
|
|
1651
|
+
* @param urlPath Optional URL path for the streams
|
|
1556
1652
|
* @returns void
|
|
1557
1653
|
*/
|
|
1558
|
-
subscribe(stream, id) {
|
|
1559
|
-
const streams = (Array.isArray(stream) ? stream : [stream]).filter((stream$1) =>
|
|
1560
|
-
|
|
1654
|
+
subscribe(stream, id, urlPath) {
|
|
1655
|
+
const streams = (Array.isArray(stream) ? stream : [stream]).filter((stream$1) => {
|
|
1656
|
+
const key = this.streamKey(stream$1, urlPath);
|
|
1657
|
+
return !this.streamConnectionMap.has(key);
|
|
1658
|
+
});
|
|
1659
|
+
this.handleStreamAssignment(streams, urlPath).forEach((assignedStreams, connection) => {
|
|
1561
1660
|
if (!this.isConnected(connection)) {
|
|
1562
|
-
this.logger.info(`Connection ${connection.id} is not ready. Queuing subscription for streams: ${
|
|
1563
|
-
connection.pendingSubscriptions?.push(...
|
|
1661
|
+
this.logger.info(`Connection ${connection.id} is not ready. Queuing subscription for streams: ${assignedStreams}`);
|
|
1662
|
+
connection.pendingSubscriptions?.push(...assignedStreams);
|
|
1564
1663
|
return;
|
|
1565
1664
|
}
|
|
1566
|
-
this.sendSubscriptionPayload(connection,
|
|
1665
|
+
this.sendSubscriptionPayload(connection, assignedStreams, id);
|
|
1567
1666
|
});
|
|
1568
1667
|
}
|
|
1569
1668
|
/**
|
|
@@ -1571,25 +1670,27 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1571
1670
|
* Handles both single and pool modes
|
|
1572
1671
|
* @param stream Single stream name or array of stream names to unsubscribe from
|
|
1573
1672
|
* @param id Optional unsubscription ID
|
|
1673
|
+
* @param urlPath Optional URL path for the streams
|
|
1574
1674
|
* @returns void
|
|
1575
1675
|
*/
|
|
1576
|
-
unsubscribe(stream, id) {
|
|
1676
|
+
unsubscribe(stream, id, urlPath) {
|
|
1577
1677
|
(Array.isArray(stream) ? stream : [stream]).forEach((stream$1) => {
|
|
1578
|
-
const
|
|
1678
|
+
const key = this.streamKey(stream$1, urlPath);
|
|
1679
|
+
const connection = this.streamConnectionMap.get(key);
|
|
1579
1680
|
if (!connection || !connection.ws || !this.isConnected(connection)) {
|
|
1580
1681
|
this.logger.warn(`Stream ${stream$1} not associated with an active connection.`);
|
|
1581
1682
|
return;
|
|
1582
1683
|
}
|
|
1583
|
-
if (!this.streamCallbackMap.has(
|
|
1684
|
+
if (!this.streamCallbackMap.has(key) || this.streamCallbackMap.get(key)?.size === 0) {
|
|
1584
1685
|
const payload = {
|
|
1585
1686
|
method: "UNSUBSCRIBE",
|
|
1586
1687
|
params: [stream$1],
|
|
1587
|
-
id:
|
|
1688
|
+
id: normalizeStreamId(id, this.streamIdIsStrictlyNumber)
|
|
1588
1689
|
};
|
|
1589
1690
|
this.logger.debug("UNSUBSCRIBE", payload);
|
|
1590
1691
|
this.send(JSON.stringify(payload), void 0, false, 0, connection);
|
|
1591
|
-
this.streamConnectionMap.delete(
|
|
1592
|
-
this.streamCallbackMap.delete(
|
|
1692
|
+
this.streamConnectionMap.delete(key);
|
|
1693
|
+
this.streamCallbackMap.delete(key);
|
|
1593
1694
|
}
|
|
1594
1695
|
});
|
|
1595
1696
|
}
|
|
@@ -1599,7 +1700,9 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1599
1700
|
* @returns `true` if the stream is currently subscribed, `false` otherwise.
|
|
1600
1701
|
*/
|
|
1601
1702
|
isSubscribed(stream) {
|
|
1602
|
-
|
|
1703
|
+
if (this.streamConnectionMap.has(stream)) return true;
|
|
1704
|
+
for (const key of this.streamConnectionMap.keys()) if (key.endsWith(`::${stream}`)) return true;
|
|
1705
|
+
return false;
|
|
1603
1706
|
}
|
|
1604
1707
|
};
|
|
1605
1708
|
/**
|
|
@@ -1609,10 +1712,12 @@ var WebsocketStreamsBase = class extends WebsocketCommon {
|
|
|
1609
1712
|
* @param {WebsocketAPIBase | WebsocketStreamsBase} websocketBase The WebSocket base instance
|
|
1610
1713
|
* @param {string} streamOrId The stream identifier
|
|
1611
1714
|
* @param {string} [id] Optional additional identifier
|
|
1715
|
+
* @param {string} [urlPath] Optional URL path for the stream
|
|
1612
1716
|
* @returns {WebsocketStream<T>} A stream handler with methods to register callbacks and unsubscribe
|
|
1613
1717
|
*/
|
|
1614
|
-
function createStreamHandler(websocketBase, streamOrId, id) {
|
|
1615
|
-
|
|
1718
|
+
function createStreamHandler(websocketBase, streamOrId, id, urlPath) {
|
|
1719
|
+
const key = websocketBase instanceof WebsocketStreamsBase ? websocketBase.streamKey(streamOrId, urlPath) : streamOrId;
|
|
1720
|
+
if (websocketBase instanceof WebsocketStreamsBase) websocketBase.subscribe(streamOrId, id, urlPath);
|
|
1616
1721
|
let registeredCallback;
|
|
1617
1722
|
return {
|
|
1618
1723
|
on: (event, callback) => {
|
|
@@ -1622,18 +1727,18 @@ function createStreamHandler(websocketBase, streamOrId, id) {
|
|
|
1622
1727
|
websocketBase.logger.error(`Error in stream callback: ${err}`);
|
|
1623
1728
|
});
|
|
1624
1729
|
};
|
|
1625
|
-
const callbackSet = websocketBase.streamCallbackMap.get(
|
|
1730
|
+
const callbackSet = websocketBase.streamCallbackMap.get(key) ?? /* @__PURE__ */ new Set();
|
|
1626
1731
|
callbackSet.add(registeredCallback);
|
|
1627
|
-
websocketBase.streamCallbackMap.set(
|
|
1732
|
+
websocketBase.streamCallbackMap.set(key, callbackSet);
|
|
1628
1733
|
}
|
|
1629
1734
|
},
|
|
1630
1735
|
unsubscribe: () => {
|
|
1631
|
-
if (registeredCallback) websocketBase.streamCallbackMap.get(
|
|
1632
|
-
if (websocketBase instanceof WebsocketStreamsBase) websocketBase.unsubscribe(streamOrId, id);
|
|
1736
|
+
if (registeredCallback) websocketBase.streamCallbackMap.get(key)?.delete(registeredCallback);
|
|
1737
|
+
if (websocketBase instanceof WebsocketStreamsBase) websocketBase.unsubscribe(streamOrId, id, urlPath);
|
|
1633
1738
|
}
|
|
1634
1739
|
};
|
|
1635
1740
|
}
|
|
1636
1741
|
|
|
1637
1742
|
//#endregion
|
|
1638
|
-
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, parseCustomHeaders, parseRateLimitHeaders, randomString, removeEmptyValue, replaceWebsocketStreamsPlaceholders, sanitizeHeaderValue, sendRequest, setSearchParams, shouldRetryRequest, sortObject, toPathString, validateTimeUnit };
|
|
1743
|
+
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 };
|
|
1639
1744
|
//# sourceMappingURL=index.mjs.map
|