@xapy/orderbook 0.1.28 → 0.1.29

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 (42) hide show
  1. package/README.md +1 -0
  2. package/dist/exchanges/aster/index.cjs +610 -0
  3. package/dist/exchanges/aster/index.cjs.map +1 -0
  4. package/dist/exchanges/aster/index.d.cts +65 -0
  5. package/dist/exchanges/aster/index.d.ts +65 -0
  6. package/dist/exchanges/aster/index.js +602 -0
  7. package/dist/exchanges/aster/index.js.map +1 -0
  8. package/dist/exchanges/binance/index.d.cts +1 -1
  9. package/dist/exchanges/binance/index.d.ts +1 -1
  10. package/dist/exchanges/bingx/index.d.cts +1 -1
  11. package/dist/exchanges/bingx/index.d.ts +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/okx/index.d.cts +1 -1
  31. package/dist/exchanges/okx/index.d.ts +1 -1
  32. package/dist/exchanges/whitebit/index.d.cts +1 -1
  33. package/dist/exchanges/whitebit/index.d.ts +1 -1
  34. package/dist/index.cjs +219 -0
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +3 -2
  37. package/dist/index.d.ts +3 -2
  38. package/dist/index.js +219 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/{stream-D8ErAue9.d.cts → stream-D5-FyNGW.d.cts} +1 -1
  41. package/dist/{stream-D8ErAue9.d.ts → stream-D5-FyNGW.d.ts} +1 -1
  42. 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-D8ErAue9.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-D8ErAue9.cjs';
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';
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';
@@ -13,6 +13,7 @@ export { DeribitClient } from './exchanges/deribit/index.cjs';
13
13
  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
+ export { AsterClient } from './exchanges/aster/index.cjs';
16
17
 
17
18
  declare class ExchangeError extends Error {
18
19
  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-D8ErAue9.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-D8ErAue9.js';
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';
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';
@@ -13,6 +13,7 @@ export { DeribitClient } from './exchanges/deribit/index.js';
13
13
  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
+ export { AsterClient } from './exchanges/aster/index.js';
16
17
 
17
18
  declare class ExchangeError extends Error {
18
19
  readonly exchange: string;
package/dist/index.js CHANGED
@@ -3435,6 +3435,224 @@ var WhitebitClient = class {
3435
3435
  }
3436
3436
  };
3437
3437
 
3438
- export { Backoff, BinanceClient, BingxClient, BitgetClient, BookMerger, BybitClient, CoinexClient, DeribitClient, EdgexClient, ExchangeError, GateClient, HyperliquidClient, KucoinClient, LighterClient, OkxClient, OrderbookStream, RateLimitError, SequenceGapError, WhitebitClient, parseSymbol };
3438
+ // src/exchanges/aster/symbols.ts
3439
+ var QUOTES5 = ["USDT", "USD1", "FORM", "USDC", "BTC", "ETH", "U"];
3440
+ function toAsterSymbol(symbol) {
3441
+ const [base, quote] = symbol.split("/");
3442
+ if (!base || !quote) {
3443
+ throw new Error(`invalid symbol "${symbol}" \u2014 expected "BASE/QUOTE"`);
3444
+ }
3445
+ return `${base}${quote}`.toUpperCase();
3446
+ }
3447
+ function fromAsterSymbol(s) {
3448
+ const upper = s.toUpperCase();
3449
+ for (const q of QUOTES5) {
3450
+ if (upper.endsWith(q) && upper.length > q.length) {
3451
+ return `${upper.slice(0, -q.length)}/${q}`;
3452
+ }
3453
+ }
3454
+ return upper;
3455
+ }
3456
+
3457
+ // src/exchanges/aster/rest.ts
3458
+ var ASTER_SPOT_REST = "https://sapi.asterdex.com";
3459
+ var ASTER_FUTURES_REST = "https://fapi.asterdex.com";
3460
+ async function fetchAsterOrderbook(opts) {
3461
+ const symbol = toAsterSymbol(opts.symbol);
3462
+ const limit = opts.depth ?? 1e3;
3463
+ const url = opts.market === "spot" ? `${ASTER_SPOT_REST}/api/v3/depth?symbol=${symbol}&limit=${limit}` : `${ASTER_FUTURES_REST}/fapi/v1/depth?symbol=${symbol}&limit=${limit}`;
3464
+ const data = await httpJson({
3465
+ url,
3466
+ timeoutMs: opts.timeoutMs,
3467
+ transformUrl: opts.transformUrl
3468
+ });
3469
+ return {
3470
+ exchange: "aster",
3471
+ symbol: fromAsterSymbol(data.symbol ?? symbol),
3472
+ market: opts.market,
3473
+ bids: data.bids.map(([p, s]) => ({ price: Number(p), size: Number(s) })),
3474
+ asks: data.asks.map(([p, s]) => ({ price: Number(p), size: Number(s) })),
3475
+ timestamp: data.E ?? data.T ?? Date.now(),
3476
+ sequence: data.lastUpdateId
3477
+ };
3478
+ }
3479
+
3480
+ // src/exchanges/aster/ws.ts
3481
+ var WS_SPOT6 = "wss://sstream.asterdex.com/ws";
3482
+ var WS_FUTURES4 = "wss://fstream.asterdex.com/ws";
3483
+ function streamAsterOrderbook(opts) {
3484
+ const symbol = toAsterSymbol(opts.symbol);
3485
+ const isSpot = opts.market === "spot";
3486
+ const wsBase = isSpot ? WS_SPOT6 : WS_FUTURES4;
3487
+ const wsUrl = `${wsBase}/${symbol.toLowerCase()}@depth@${opts.interval ?? "100ms"}`;
3488
+ const merger = new BookMerger();
3489
+ let snapshotId = -1;
3490
+ let lastU = -1;
3491
+ let snapshotInFlight = false;
3492
+ let snapshotDone = false;
3493
+ let buffered = [];
3494
+ let recovering = false;
3495
+ let ws = null;
3496
+ const stream = new OrderbookStream(() => ws?.close());
3497
+ const emit = (r) => {
3498
+ const book = {
3499
+ exchange: "aster",
3500
+ symbol: fromAsterSymbol(symbol),
3501
+ market: opts.market,
3502
+ bids: r.bids,
3503
+ asks: r.asks,
3504
+ timestamp: r.timestamp,
3505
+ sequence: r.sequence
3506
+ };
3507
+ stream.emit("update", book);
3508
+ };
3509
+ const triggerSnapshot = () => {
3510
+ if (snapshotInFlight) return;
3511
+ snapshotInFlight = true;
3512
+ fetchAsterOrderbook({
3513
+ symbol: opts.symbol,
3514
+ market: opts.market,
3515
+ depth: opts.depth ?? 1e3,
3516
+ timeoutMs: opts.timeoutMs,
3517
+ transformUrl: opts.transformUrl
3518
+ }).then((snap) => {
3519
+ snapshotId = snap.sequence;
3520
+ const r = merger.apply({
3521
+ kind: "snapshot",
3522
+ bids: snap.bids,
3523
+ asks: snap.asks,
3524
+ sequence: snap.sequence,
3525
+ timestamp: snap.timestamp
3526
+ });
3527
+ if (r.ok) emit(r);
3528
+ snapshotDone = true;
3529
+ lastU = -1;
3530
+ const pending2 = buffered;
3531
+ buffered = [];
3532
+ for (const ev of pending2) processDelta(ev);
3533
+ }).catch((err) => stream.emit("error", err)).finally(() => {
3534
+ snapshotInFlight = false;
3535
+ });
3536
+ };
3537
+ const resync = () => {
3538
+ if (recovering) return;
3539
+ recovering = true;
3540
+ merger.reset();
3541
+ snapshotId = -1;
3542
+ snapshotDone = false;
3543
+ lastU = -1;
3544
+ buffered = [];
3545
+ setTimeout(() => {
3546
+ recovering = false;
3547
+ triggerSnapshot();
3548
+ }, 100);
3549
+ };
3550
+ const processDelta = (ev) => {
3551
+ if (ev.u < snapshotId) return;
3552
+ const bids = ev.b.map(([p, s]) => ({
3553
+ price: Number(p),
3554
+ size: Number(s)
3555
+ }));
3556
+ const asks = ev.a.map(([p, s]) => ({
3557
+ price: Number(p),
3558
+ size: Number(s)
3559
+ }));
3560
+ let prevSequence;
3561
+ if (lastU < 0) {
3562
+ if (ev.U > snapshotId) {
3563
+ resync();
3564
+ return;
3565
+ }
3566
+ prevSequence = snapshotId;
3567
+ } else {
3568
+ if (ev.pu === void 0) {
3569
+ resync();
3570
+ return;
3571
+ }
3572
+ prevSequence = ev.pu;
3573
+ }
3574
+ const r = merger.apply({
3575
+ kind: "delta",
3576
+ bids,
3577
+ asks,
3578
+ sequence: ev.u,
3579
+ prevSequence,
3580
+ timestamp: ev.E
3581
+ });
3582
+ if (r.ok) {
3583
+ lastU = ev.u;
3584
+ emit(r);
3585
+ } else if (r.reason === "gap" || r.reason === "no-snapshot") {
3586
+ resync();
3587
+ }
3588
+ };
3589
+ const onMessage = (raw) => {
3590
+ if (typeof raw !== "string") return;
3591
+ let msg;
3592
+ try {
3593
+ msg = JSON.parse(raw);
3594
+ } catch {
3595
+ return;
3596
+ }
3597
+ if (msg.e !== "depthUpdate") return;
3598
+ if (!snapshotDone) {
3599
+ buffered.push(msg);
3600
+ if (!snapshotInFlight) triggerSnapshot();
3601
+ return;
3602
+ }
3603
+ processDelta(msg);
3604
+ };
3605
+ ws = new WSClient({
3606
+ url: wsUrl,
3607
+ onOpen: () => {
3608
+ merger.reset();
3609
+ snapshotId = -1;
3610
+ snapshotDone = false;
3611
+ lastU = -1;
3612
+ buffered = [];
3613
+ },
3614
+ onMessage
3615
+ // Server-initiated WS-level ping; auto-handled by the WS impl.
3616
+ });
3617
+ ws.on("open", () => stream.emit("connected"));
3618
+ ws.on("close", (r) => stream.emit("disconnected", r));
3619
+ ws.on("reconnecting", (a, w) => stream.emit("reconnecting", a, w));
3620
+ ws.on("error", (e) => stream.emit("error", e));
3621
+ ws.connect().catch((e) => stream.emit("error", e));
3622
+ return stream;
3623
+ }
3624
+
3625
+ // src/exchanges/aster/index.ts
3626
+ var AsterClient = class {
3627
+ exchange = "aster";
3628
+ transformUrl;
3629
+ timeoutMs;
3630
+ constructor(opts = {}) {
3631
+ this.transformUrl = opts.transformUrl;
3632
+ this.timeoutMs = opts.timeoutMs;
3633
+ }
3634
+ fetchOrderbook(symbol, opts = {}) {
3635
+ const { pair, market } = parseSymbol(symbol);
3636
+ return fetchAsterOrderbook({
3637
+ symbol: pair,
3638
+ market,
3639
+ depth: opts.depth,
3640
+ timeoutMs: this.timeoutMs,
3641
+ transformUrl: this.transformUrl
3642
+ });
3643
+ }
3644
+ streamOrderbook(symbol, opts = {}) {
3645
+ const { pair, market } = parseSymbol(symbol);
3646
+ return streamAsterOrderbook({
3647
+ symbol: pair,
3648
+ market,
3649
+ depth: opts.depth,
3650
+ transformUrl: this.transformUrl,
3651
+ timeoutMs: this.timeoutMs
3652
+ });
3653
+ }
3654
+ };
3655
+
3656
+ export { AsterClient, Backoff, BinanceClient, BingxClient, BitgetClient, BookMerger, BybitClient, CoinexClient, DeribitClient, EdgexClient, ExchangeError, GateClient, HyperliquidClient, KucoinClient, LighterClient, OkxClient, OrderbookStream, RateLimitError, SequenceGapError, WhitebitClient, parseSymbol };
3439
3657
  //# sourceMappingURL=index.js.map
3440
3658
  //# sourceMappingURL=index.js.map