@xapy/orderbook 0.1.29 → 0.1.31

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.
Files changed (48) hide show
  1. package/README.md +3 -0
  2. package/dist/exchanges/aster/index.d.cts +1 -1
  3. package/dist/exchanges/aster/index.d.ts +1 -1
  4. package/dist/exchanges/binance/index.d.cts +1 -1
  5. package/dist/exchanges/binance/index.d.ts +1 -1
  6. package/dist/exchanges/bingx/index.cjs +8 -85
  7. package/dist/exchanges/bingx/index.cjs.map +1 -1
  8. package/dist/exchanges/bingx/index.d.cts +12 -7
  9. package/dist/exchanges/bingx/index.d.ts +12 -7
  10. package/dist/exchanges/bingx/index.js +8 -85
  11. package/dist/exchanges/bingx/index.js.map +1 -1
  12. package/dist/exchanges/bitget/index.d.cts +1 -1
  13. package/dist/exchanges/bitget/index.d.ts +1 -1
  14. package/dist/exchanges/bybit/index.d.cts +1 -1
  15. package/dist/exchanges/bybit/index.d.ts +1 -1
  16. package/dist/exchanges/coinex/index.d.cts +1 -1
  17. package/dist/exchanges/coinex/index.d.ts +1 -1
  18. package/dist/exchanges/deribit/index.d.cts +1 -1
  19. package/dist/exchanges/deribit/index.d.ts +1 -1
  20. package/dist/exchanges/edgex/index.d.cts +1 -1
  21. package/dist/exchanges/edgex/index.d.ts +1 -1
  22. package/dist/exchanges/gate/index.d.cts +1 -1
  23. package/dist/exchanges/gate/index.d.ts +1 -1
  24. package/dist/exchanges/hyperliquid/index.d.cts +1 -1
  25. package/dist/exchanges/hyperliquid/index.d.ts +1 -1
  26. package/dist/exchanges/kucoin/index.d.cts +1 -1
  27. package/dist/exchanges/kucoin/index.d.ts +1 -1
  28. package/dist/exchanges/lighter/index.d.cts +1 -1
  29. package/dist/exchanges/lighter/index.d.ts +1 -1
  30. package/dist/exchanges/mexc/index.cjs +729 -0
  31. package/dist/exchanges/mexc/index.cjs.map +1 -0
  32. package/dist/exchanges/mexc/index.d.cts +57 -0
  33. package/dist/exchanges/mexc/index.d.ts +57 -0
  34. package/dist/exchanges/mexc/index.js +721 -0
  35. package/dist/exchanges/mexc/index.js.map +1 -0
  36. package/dist/exchanges/okx/index.d.cts +1 -1
  37. package/dist/exchanges/okx/index.d.ts +1 -1
  38. package/dist/exchanges/whitebit/index.d.cts +1 -1
  39. package/dist/exchanges/whitebit/index.d.ts +1 -1
  40. package/dist/index.cjs +337 -89
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.cts +3 -2
  43. package/dist/index.d.ts +3 -2
  44. package/dist/index.js +337 -90
  45. package/dist/index.js.map +1 -1
  46. package/dist/{stream-D5-FyNGW.d.cts → stream-Dyq24thx.d.cts} +1 -1
  47. package/dist/{stream-D5-FyNGW.d.ts → stream-Dyq24thx.d.ts} +1 -1
  48. package/package.json +12 -1
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BookEvent, O as OrderbookLevel, M as Market } from './stream-D5-FyNGW.cjs';
2
- export { C as ClientOptions, E as ExchangeName, a as Orderbook, b as OrderbookOptions, c as OrderbookStream, S as Side, d as StreamEvents } from './stream-D5-FyNGW.cjs';
1
+ import { B as BookEvent, O as OrderbookLevel, M as Market } from './stream-Dyq24thx.cjs';
2
+ export { C as ClientOptions, E as ExchangeName, a as Orderbook, b as OrderbookOptions, c as OrderbookStream, S as Side, d as StreamEvents } from './stream-Dyq24thx.cjs';
3
3
  export { BybitClient } from './exchanges/bybit/index.cjs';
4
4
  export { BitgetClient } from './exchanges/bitget/index.cjs';
5
5
  export { GateClient } from './exchanges/gate/index.cjs';
@@ -14,6 +14,7 @@ export { LighterClient } from './exchanges/lighter/index.cjs';
14
14
  export { EdgexClient } from './exchanges/edgex/index.cjs';
15
15
  export { WhitebitClient } from './exchanges/whitebit/index.cjs';
16
16
  export { AsterClient } from './exchanges/aster/index.cjs';
17
+ export { MexcClient } from './exchanges/mexc/index.cjs';
17
18
 
18
19
  declare class ExchangeError extends Error {
19
20
  readonly exchange: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BookEvent, O as OrderbookLevel, M as Market } from './stream-D5-FyNGW.js';
2
- export { C as ClientOptions, E as ExchangeName, a as Orderbook, b as OrderbookOptions, c as OrderbookStream, S as Side, d as StreamEvents } from './stream-D5-FyNGW.js';
1
+ import { B as BookEvent, O as OrderbookLevel, M as Market } from './stream-Dyq24thx.js';
2
+ export { C as ClientOptions, E as ExchangeName, a as Orderbook, b as OrderbookOptions, c as OrderbookStream, S as Side, d as StreamEvents } from './stream-Dyq24thx.js';
3
3
  export { BybitClient } from './exchanges/bybit/index.js';
4
4
  export { BitgetClient } from './exchanges/bitget/index.js';
5
5
  export { GateClient } from './exchanges/gate/index.js';
@@ -14,6 +14,7 @@ export { LighterClient } from './exchanges/lighter/index.js';
14
14
  export { EdgexClient } from './exchanges/edgex/index.js';
15
15
  export { WhitebitClient } from './exchanges/whitebit/index.js';
16
16
  export { AsterClient } from './exchanges/aster/index.js';
17
+ export { MexcClient } from './exchanges/mexc/index.js';
17
18
 
18
19
  declare class ExchangeError extends Error {
19
20
  readonly exchange: string;
package/dist/index.js CHANGED
@@ -1248,48 +1248,14 @@ function streamBingxOrderbook(opts) {
1248
1248
  const level = opts.depth ?? 20;
1249
1249
  const interval = opts.interval ?? "500ms";
1250
1250
  const depthDataType = isSpot ? `${wsSymbol}@depth${level}` : `${wsSymbol}@depth${level}@${interval}`;
1251
- const tickerDataType = `${wsSymbol}@bookTicker`;
1252
1251
  const merger = new BookMerger();
1253
1252
  let ws = null;
1254
1253
  const stream = new OrderbookStream(() => ws?.close());
1255
- const subId = Date.now();
1256
1254
  const subscribeDepth = JSON.stringify({
1257
- id: `sub-depth-${subId}`,
1255
+ id: `sub-depth-${Date.now()}`,
1258
1256
  reqType: "sub",
1259
1257
  dataType: depthDataType
1260
1258
  });
1261
- const subscribeTicker = JSON.stringify({
1262
- id: `sub-ticker-${subId}`,
1263
- reqType: "sub",
1264
- dataType: tickerDataType
1265
- });
1266
- let lastMerged = null;
1267
- let lastTicker = null;
1268
- const emitOverlayed = () => {
1269
- if (!lastMerged) return;
1270
- let bids = lastMerged.bids;
1271
- let asks = lastMerged.asks;
1272
- let timestamp = lastMerged.timestamp;
1273
- let sequence = lastMerged.sequence;
1274
- if (lastTicker) {
1275
- bids = overlayBid(bids, lastTicker.bid);
1276
- asks = overlayAsk(asks, lastTicker.ask);
1277
- if (lastTicker.ts > timestamp) {
1278
- timestamp = lastTicker.ts;
1279
- sequence = Math.max(sequence, lastTicker.ts);
1280
- }
1281
- }
1282
- const book = {
1283
- exchange: "bingx",
1284
- symbol: opts.symbol,
1285
- market: opts.market,
1286
- bids,
1287
- asks,
1288
- timestamp,
1289
- sequence
1290
- };
1291
- stream.emit("update", book);
1292
- };
1293
1259
  const handleDepth = (d, frameTs) => {
1294
1260
  const ts = d.T ?? d.ts ?? frameTs ?? Date.now();
1295
1261
  const event = {
@@ -1301,26 +1267,16 @@ function streamBingxOrderbook(opts) {
1301
1267
  };
1302
1268
  const r = merger.apply(event);
1303
1269
  if (!r.ok) return;
1304
- lastMerged = {
1270
+ const book = {
1271
+ exchange: "bingx",
1272
+ symbol: opts.symbol,
1273
+ market: opts.market,
1305
1274
  bids: r.bids,
1306
1275
  asks: r.asks,
1307
1276
  timestamp: r.timestamp,
1308
1277
  sequence: r.sequence
1309
1278
  };
1310
- emitOverlayed();
1311
- };
1312
- const handleTicker = (t) => {
1313
- const bidPrice = Number(t.b);
1314
- const askPrice = Number(t.a);
1315
- const bidSize = Number(t.B);
1316
- const askSize = Number(t.A);
1317
- if (!Number.isFinite(bidPrice) || !Number.isFinite(askPrice)) return;
1318
- lastTicker = {
1319
- bid: { price: bidPrice, size: bidSize },
1320
- ask: { price: askPrice, size: askSize },
1321
- ts: t.T ?? t.E ?? Date.now()
1322
- };
1323
- emitOverlayed();
1279
+ stream.emit("update", book);
1324
1280
  };
1325
1281
  const handlePayload = (text) => {
1326
1282
  if (text === "Ping" || text === "ping") {
@@ -1346,12 +1302,8 @@ function streamBingxOrderbook(opts) {
1346
1302
  return;
1347
1303
  }
1348
1304
  if (!msg.dataType || !msg.data) return;
1349
- const frameTs = msg.ts ?? msg.timestamp;
1350
- if (msg.dataType === depthDataType) {
1351
- handleDepth(msg.data, frameTs);
1352
- } else if (msg.dataType === tickerDataType) {
1353
- handleTicker(msg.data);
1354
- }
1305
+ if (msg.dataType !== depthDataType) return;
1306
+ handleDepth(msg.data, msg.ts ?? msg.timestamp);
1355
1307
  };
1356
1308
  const onMessage = async (raw) => {
1357
1309
  if (typeof raw === "string") {
@@ -1365,10 +1317,7 @@ function streamBingxOrderbook(opts) {
1365
1317
  url: isSpot ? WS_SPOT3 : WS_SWAP,
1366
1318
  onOpen: (sock) => {
1367
1319
  merger.reset();
1368
- lastMerged = null;
1369
- lastTicker = null;
1370
1320
  sock.send(subscribeDepth);
1371
- sock.send(subscribeTicker);
1372
1321
  },
1373
1322
  onMessage
1374
1323
  // bingx server is the one that sends Ping frames; we don't need client pings.
@@ -1380,32 +1329,6 @@ function streamBingxOrderbook(opts) {
1380
1329
  ws.connect().catch((e) => stream.emit("error", e));
1381
1330
  return stream;
1382
1331
  }
1383
- function overlayAsk(asks, top) {
1384
- if (!(top.size > 0)) return asks;
1385
- let i = 0;
1386
- for (; i < asks.length; i++) {
1387
- const level = asks[i];
1388
- if (!level || level.price >= top.price) break;
1389
- }
1390
- const at = asks[i];
1391
- if (at && at.price === top.price) {
1392
- return [{ price: top.price, size: top.size }, ...asks.slice(i + 1)];
1393
- }
1394
- return [{ price: top.price, size: top.size }, ...asks.slice(i)];
1395
- }
1396
- function overlayBid(bids, top) {
1397
- if (!(top.size > 0)) return bids;
1398
- let i = 0;
1399
- for (; i < bids.length; i++) {
1400
- const level = bids[i];
1401
- if (!level || level.price <= top.price) break;
1402
- }
1403
- const at = bids[i];
1404
- if (at && at.price === top.price) {
1405
- return [{ price: top.price, size: top.size }, ...bids.slice(i + 1)];
1406
- }
1407
- return [{ price: top.price, size: top.size }, ...bids.slice(i)];
1408
- }
1409
1332
 
1410
1333
  // src/exchanges/bingx/index.ts
1411
1334
  var BingxClient = class {
@@ -1515,8 +1438,8 @@ function streamCoinexOrderbook(opts) {
1515
1438
  let timestamp = lastMerged.timestamp;
1516
1439
  let sequence = lastMerged.sequence;
1517
1440
  if (lastTicker) {
1518
- bids = overlayBid2(bids, lastTicker.bid);
1519
- asks = overlayAsk2(asks, lastTicker.ask);
1441
+ bids = overlayBid(bids, lastTicker.bid);
1442
+ asks = overlayAsk(asks, lastTicker.ask);
1520
1443
  if (lastTicker.ts > timestamp) {
1521
1444
  timestamp = lastTicker.ts;
1522
1445
  sequence = Math.max(sequence, lastTicker.ts);
@@ -1614,7 +1537,7 @@ function streamCoinexOrderbook(opts) {
1614
1537
  ws.connect().catch((e) => stream.emit("error", e));
1615
1538
  return stream;
1616
1539
  }
1617
- function overlayAsk2(asks, top) {
1540
+ function overlayAsk(asks, top) {
1618
1541
  if (!(top.size > 0)) return asks;
1619
1542
  let i = 0;
1620
1543
  for (; i < asks.length; i++) {
@@ -1627,7 +1550,7 @@ function overlayAsk2(asks, top) {
1627
1550
  }
1628
1551
  return [{ price: top.price, size: top.size }, ...asks.slice(i)];
1629
1552
  }
1630
- function overlayBid2(bids, top) {
1553
+ function overlayBid(bids, top) {
1631
1554
  if (!(top.size > 0)) return bids;
1632
1555
  let i = 0;
1633
1556
  for (; i < bids.length; i++) {
@@ -3653,6 +3576,330 @@ var AsterClient = class {
3653
3576
  }
3654
3577
  };
3655
3578
 
3656
- export { AsterClient, Backoff, BinanceClient, BingxClient, BitgetClient, BookMerger, BybitClient, CoinexClient, DeribitClient, EdgexClient, ExchangeError, GateClient, HyperliquidClient, KucoinClient, LighterClient, OkxClient, OrderbookStream, RateLimitError, SequenceGapError, WhitebitClient, parseSymbol };
3579
+ // src/exchanges/mexc/contracts.ts
3580
+ var MEXC_SPOT_REST = "https://api.mexc.com";
3581
+ var MEXC_FUTURES_REST = "https://contract.mexc.com";
3582
+ var cache2 = null;
3583
+ var inflight2 = null;
3584
+ async function fetchContracts2(opts) {
3585
+ const res = await httpJson({
3586
+ url: `${MEXC_FUTURES_REST}/api/v1/contract/detail`,
3587
+ timeoutMs: opts.timeoutMs,
3588
+ transformUrl: opts.transformUrl
3589
+ });
3590
+ const rows = res.data ?? [];
3591
+ if (rows.length === 0) {
3592
+ throw new ExchangeError(
3593
+ "mexc",
3594
+ res.message ? `${res.code}: ${res.message}` : "empty contract/detail response"
3595
+ );
3596
+ }
3597
+ const map = /* @__PURE__ */ new Map();
3598
+ for (const row of rows) map.set(row.symbol.toUpperCase(), row);
3599
+ return map;
3600
+ }
3601
+ function loadContracts2(opts) {
3602
+ inflight2 ??= fetchContracts2(opts).then(
3603
+ (m) => {
3604
+ cache2 = m;
3605
+ inflight2 = null;
3606
+ return m;
3607
+ },
3608
+ (err) => {
3609
+ inflight2 = null;
3610
+ throw err;
3611
+ }
3612
+ );
3613
+ return inflight2;
3614
+ }
3615
+ async function resolveContractSize(symbol, opts) {
3616
+ const k = symbol.toUpperCase();
3617
+ const hit = cache2?.get(k);
3618
+ const contract = hit ?? (await loadContracts2(opts)).get(k);
3619
+ if (!contract) {
3620
+ throw new ExchangeError(
3621
+ "mexc",
3622
+ `unknown futures contract "${symbol}" \u2014 not listed on mexc`
3623
+ );
3624
+ }
3625
+ const size = Number(contract.contractSize);
3626
+ if (!Number.isFinite(size) || size <= 0) {
3627
+ throw new ExchangeError(
3628
+ "mexc",
3629
+ `contract "${symbol}" has no usable contractSize (${contract.contractSize})`
3630
+ );
3631
+ }
3632
+ return size;
3633
+ }
3634
+
3635
+ // src/exchanges/mexc/symbols.ts
3636
+ var QUOTES6 = ["USDT", "USDC", "TUSD", "USD", "BTC", "ETH"];
3637
+ function toMexcSymbol(symbol, market) {
3638
+ const [base, quote] = symbol.split("/");
3639
+ if (!base || !quote) {
3640
+ throw new Error(`invalid symbol "${symbol}" \u2014 expected "BASE/QUOTE"`);
3641
+ }
3642
+ return market === "perpetual" ? `${base.toUpperCase()}_${quote.toUpperCase()}` : `${base}${quote}`.toUpperCase();
3643
+ }
3644
+ function fromMexcSymbol(s, market) {
3645
+ const upper = s.toUpperCase();
3646
+ if (market === "perpetual") {
3647
+ const [base, quote] = upper.split("_");
3648
+ return base && quote ? `${base}/${quote}` : upper;
3649
+ }
3650
+ for (const q of QUOTES6) {
3651
+ if (upper.endsWith(q) && upper.length > q.length) {
3652
+ return `${upper.slice(0, -q.length)}/${q}`;
3653
+ }
3654
+ }
3655
+ return upper;
3656
+ }
3657
+
3658
+ // src/exchanges/mexc/rest.ts
3659
+ var toSpotLevels = (rows) => (rows ?? []).map(([p, s]) => ({ price: Number(p), size: Number(s) }));
3660
+ var toFuturesLevels = (rows, contractSize) => (rows ?? []).map(([price, vol]) => ({
3661
+ price: Number(price),
3662
+ size: Number(vol) * contractSize
3663
+ }));
3664
+ async function fetchMexcOrderbook(opts) {
3665
+ const symbol = toMexcSymbol(opts.symbol, opts.market);
3666
+ const depth = opts.depth ?? 50;
3667
+ if (opts.market === "spot") {
3668
+ const data = await httpJson({
3669
+ url: `${MEXC_SPOT_REST}/api/v3/depth?symbol=${symbol}&limit=${depth}`,
3670
+ timeoutMs: opts.timeoutMs,
3671
+ transformUrl: opts.transformUrl
3672
+ });
3673
+ return {
3674
+ exchange: "mexc",
3675
+ symbol: fromMexcSymbol(symbol, opts.market),
3676
+ market: opts.market,
3677
+ bids: toSpotLevels(data.bids),
3678
+ asks: toSpotLevels(data.asks),
3679
+ // The spot depth endpoint returns no timestamp of its own.
3680
+ timestamp: Date.now(),
3681
+ sequence: data.lastUpdateId
3682
+ };
3683
+ }
3684
+ const contractSize = await resolveContractSize(symbol, opts);
3685
+ const res = await httpJson({
3686
+ url: `${MEXC_FUTURES_REST}/api/v1/contract/depth/${symbol}?limit=${depth}`,
3687
+ timeoutMs: opts.timeoutMs,
3688
+ transformUrl: opts.transformUrl
3689
+ });
3690
+ if (!res.data) {
3691
+ throw new ExchangeError(
3692
+ "mexc",
3693
+ res.message ? `${res.code}: ${res.message}` : "empty orderbook response"
3694
+ );
3695
+ }
3696
+ return {
3697
+ exchange: "mexc",
3698
+ symbol: fromMexcSymbol(symbol, opts.market),
3699
+ market: opts.market,
3700
+ bids: toFuturesLevels(res.data.bids, contractSize),
3701
+ asks: toFuturesLevels(res.data.asks, contractSize),
3702
+ timestamp: res.data.timestamp ?? Date.now(),
3703
+ sequence: Number(res.data.version ?? 0)
3704
+ };
3705
+ }
3706
+
3707
+ // src/exchanges/mexc/ws.ts
3708
+ var WS_FUTURES5 = "wss://contract.mexc.com/edge";
3709
+ var PING_INTERVAL_MS3 = 2e4;
3710
+ function streamMexcOrderbook(opts) {
3711
+ if (opts.market !== "perpetual") {
3712
+ throw new Error(
3713
+ `mexc spot streaming requires the protobuf WS feed, which this adapter does not decode \u2014 use fetchOrderbook("${opts.symbol}") for a REST snapshot, or stream the perpetual ("${opts.symbol}:${opts.symbol.split("/")[1]}")`
3714
+ );
3715
+ }
3716
+ const symbol = toMexcSymbol(opts.symbol, opts.market);
3717
+ const unified = fromMexcSymbol(symbol, opts.market);
3718
+ const contractSize = resolveContractSize(symbol, opts);
3719
+ contractSize.catch(() => {
3720
+ });
3721
+ const merger = new BookMerger();
3722
+ let seedVersion = -1;
3723
+ let lastVersion = -1;
3724
+ let snapshotInFlight = false;
3725
+ let snapshotDone = false;
3726
+ let buffered = [];
3727
+ let recovering = false;
3728
+ let scale = 0;
3729
+ let ws = null;
3730
+ const stream = new OrderbookStream(() => ws?.close());
3731
+ const emit = (r) => {
3732
+ const book = {
3733
+ exchange: "mexc",
3734
+ symbol: unified,
3735
+ market: opts.market,
3736
+ bids: r.bids,
3737
+ asks: r.asks,
3738
+ timestamp: r.timestamp,
3739
+ sequence: r.sequence
3740
+ };
3741
+ stream.emit("update", book);
3742
+ };
3743
+ const triggerSnapshot = () => {
3744
+ if (snapshotInFlight) return;
3745
+ snapshotInFlight = true;
3746
+ contractSize.then(async (size) => {
3747
+ scale = size;
3748
+ return fetchMexcOrderbook({
3749
+ symbol: opts.symbol,
3750
+ market: opts.market,
3751
+ depth: opts.depth ?? 200,
3752
+ timeoutMs: opts.timeoutMs,
3753
+ transformUrl: opts.transformUrl
3754
+ });
3755
+ }).then((snap) => {
3756
+ seedVersion = snap.sequence;
3757
+ const r = merger.apply({
3758
+ kind: "snapshot",
3759
+ bids: snap.bids,
3760
+ asks: snap.asks,
3761
+ sequence: snap.sequence,
3762
+ timestamp: snap.timestamp
3763
+ });
3764
+ if (r.ok) emit(r);
3765
+ snapshotDone = true;
3766
+ lastVersion = -1;
3767
+ const pending2 = buffered;
3768
+ buffered = [];
3769
+ for (const d of pending2) processDelta(d);
3770
+ }).catch((err) => stream.emit("error", err)).finally(() => {
3771
+ snapshotInFlight = false;
3772
+ });
3773
+ };
3774
+ const resync = () => {
3775
+ if (recovering) return;
3776
+ recovering = true;
3777
+ merger.reset();
3778
+ seedVersion = -1;
3779
+ snapshotDone = false;
3780
+ lastVersion = -1;
3781
+ buffered = [];
3782
+ setTimeout(() => {
3783
+ recovering = false;
3784
+ triggerSnapshot();
3785
+ }, 100);
3786
+ };
3787
+ const processDelta = (d) => {
3788
+ const end = Number(d.end ?? d.version ?? 0);
3789
+ const begin = Number(d.begin ?? end);
3790
+ if (end <= seedVersion) return;
3791
+ let prevSequence;
3792
+ if (lastVersion < 0) {
3793
+ if (begin - 1 > seedVersion) {
3794
+ resync();
3795
+ return;
3796
+ }
3797
+ prevSequence = seedVersion;
3798
+ } else {
3799
+ prevSequence = begin - 1;
3800
+ }
3801
+ const r = merger.apply({
3802
+ kind: "delta",
3803
+ bids: toFuturesLevels(d.bids, scale),
3804
+ asks: toFuturesLevels(d.asks, scale),
3805
+ sequence: end,
3806
+ prevSequence,
3807
+ timestamp: d.timestamp ?? d.cts ?? Date.now()
3808
+ });
3809
+ if (r.ok) {
3810
+ lastVersion = end;
3811
+ emit(r);
3812
+ } else if (r.reason === "gap" || r.reason === "no-snapshot") {
3813
+ resync();
3814
+ }
3815
+ };
3816
+ const onMessage = (raw) => {
3817
+ if (typeof raw !== "string") return;
3818
+ let msg;
3819
+ try {
3820
+ msg = JSON.parse(raw);
3821
+ } catch {
3822
+ return;
3823
+ }
3824
+ if (msg.channel === "push.depth") {
3825
+ if (msg.symbol && msg.symbol !== symbol) return;
3826
+ const d = msg.data;
3827
+ if (!d) return;
3828
+ if (!snapshotDone) {
3829
+ buffered.push(d);
3830
+ if (!snapshotInFlight) triggerSnapshot();
3831
+ return;
3832
+ }
3833
+ processDelta(d);
3834
+ return;
3835
+ }
3836
+ if (msg.channel === "rs.error" || msg.channel?.startsWith("rs.error")) {
3837
+ stream.emit("error", new ExchangeError("mexc", String(msg.data)));
3838
+ return;
3839
+ }
3840
+ if (msg.channel === "rs.sub.depth" && msg.data !== "success") {
3841
+ stream.emit(
3842
+ "error",
3843
+ new ExchangeError("mexc", `subscribe rejected: ${String(msg.data)}`)
3844
+ );
3845
+ }
3846
+ };
3847
+ ws = new WSClient({
3848
+ url: WS_FUTURES5,
3849
+ onOpen: (handle) => {
3850
+ merger.reset();
3851
+ seedVersion = -1;
3852
+ snapshotDone = false;
3853
+ lastVersion = -1;
3854
+ buffered = [];
3855
+ handle.send(
3856
+ JSON.stringify({ method: "sub.depth", param: { symbol } })
3857
+ );
3858
+ },
3859
+ onMessage,
3860
+ pingIntervalMs: PING_INTERVAL_MS3,
3861
+ pingPayload: () => JSON.stringify({ method: "ping" })
3862
+ });
3863
+ ws.on("open", () => stream.emit("connected"));
3864
+ ws.on("close", (r) => stream.emit("disconnected", r));
3865
+ ws.on("reconnecting", (a, w) => stream.emit("reconnecting", a, w));
3866
+ ws.on("error", (e) => stream.emit("error", e));
3867
+ ws.connect().catch((e) => stream.emit("error", e));
3868
+ return stream;
3869
+ }
3870
+
3871
+ // src/exchanges/mexc/index.ts
3872
+ var MexcClient = class {
3873
+ exchange = "mexc";
3874
+ transformUrl;
3875
+ timeoutMs;
3876
+ constructor(opts = {}) {
3877
+ this.transformUrl = opts.transformUrl;
3878
+ this.timeoutMs = opts.timeoutMs;
3879
+ }
3880
+ fetchOrderbook(symbol, opts = {}) {
3881
+ const { pair, market } = parseSymbol(symbol);
3882
+ return fetchMexcOrderbook({
3883
+ symbol: pair,
3884
+ market,
3885
+ depth: opts.depth,
3886
+ timeoutMs: this.timeoutMs,
3887
+ transformUrl: this.transformUrl
3888
+ });
3889
+ }
3890
+ /** Perpetuals only — see the class note on spot. */
3891
+ streamOrderbook(symbol, opts = {}) {
3892
+ const { pair, market } = parseSymbol(symbol);
3893
+ return streamMexcOrderbook({
3894
+ symbol: pair,
3895
+ market,
3896
+ depth: opts.depth,
3897
+ transformUrl: this.transformUrl,
3898
+ timeoutMs: this.timeoutMs
3899
+ });
3900
+ }
3901
+ };
3902
+
3903
+ export { AsterClient, Backoff, BinanceClient, BingxClient, BitgetClient, BookMerger, BybitClient, CoinexClient, DeribitClient, EdgexClient, ExchangeError, GateClient, HyperliquidClient, KucoinClient, LighterClient, MexcClient, OkxClient, OrderbookStream, RateLimitError, SequenceGapError, WhitebitClient, parseSymbol };
3657
3904
  //# sourceMappingURL=index.js.map
3658
3905
  //# sourceMappingURL=index.js.map