@0xarchive/sdk 0.6.0 → 0.6.2

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/README.md CHANGED
@@ -519,6 +519,31 @@ ws.stream('orderbook', 'BTC', {
519
519
  ws.streamStop();
520
520
  ```
521
521
 
522
+ ### Gap Detection
523
+
524
+ During historical replay and bulk streaming, the server automatically detects gaps in the data and notifies the client. This helps identify periods where data may be missing.
525
+
526
+ ```typescript
527
+ // Handle gap notifications during replay/stream
528
+ ws.onGap((channel, coin, gapStart, gapEnd, durationMinutes) => {
529
+ console.log(`Gap detected in ${channel}/${coin}:`);
530
+ console.log(` From: ${new Date(gapStart).toISOString()}`);
531
+ console.log(` To: ${new Date(gapEnd).toISOString()}`);
532
+ console.log(` Duration: ${durationMinutes} minutes`);
533
+ });
534
+
535
+ // Start replay - gaps will be reported via onGap callback
536
+ ws.replay('orderbook', 'BTC', {
537
+ start: Date.now() - 86400000,
538
+ end: Date.now(),
539
+ speed: 10
540
+ });
541
+ ```
542
+
543
+ Gap thresholds vary by channel:
544
+ - **orderbook**, **candles**, **liquidations**: 2 minutes
545
+ - **trades**: 60 minutes (trades can naturally have longer gaps during low activity periods)
546
+
522
547
  ### WebSocket Configuration
523
548
 
524
549
  ```typescript
@@ -539,6 +564,7 @@ const ws = new OxArchiveWs({
539
564
  | `orderbook` | L2 order book updates | Yes | Yes |
540
565
  | `trades` | Trade/fill updates | Yes | Yes |
541
566
  | `candles` | OHLCV candle data | Yes | Yes (replay/stream only) |
567
+ | `liquidations` | Liquidation events (May 2025+) | Yes | Yes (replay/stream only) |
542
568
  | `ticker` | Price and 24h volume | Yes | Real-time only |
543
569
  | `all_tickers` | All market tickers | No | Real-time only |
544
570
 
package/dist/index.d.mts CHANGED
@@ -536,8 +536,24 @@ interface WsStreamStopped {
536
536
  type: 'stream_stopped';
537
537
  snapshots_sent: number;
538
538
  }
539
+ /**
540
+ * Gap detected in historical data stream.
541
+ * Sent when there's a gap exceeding the threshold between consecutive data points.
542
+ * Thresholds: 2 minutes for orderbook/candles/liquidations, 60 minutes for trades.
543
+ */
544
+ interface WsGapDetected {
545
+ type: 'gap_detected';
546
+ channel: WsChannel;
547
+ coin: string;
548
+ /** Start of the gap (last data point timestamp in ms) */
549
+ gap_start: number;
550
+ /** End of the gap (next data point timestamp in ms) */
551
+ gap_end: number;
552
+ /** Gap duration in minutes */
553
+ duration_minutes: number;
554
+ }
539
555
  /** Server message union type */
540
- type WsServerMessage = WsSubscribed | WsUnsubscribed | WsPong | WsError | WsData | WsReplayStarted | WsReplayPaused | WsReplayResumed | WsReplayCompleted | WsReplayStopped | WsHistoricalData | WsHistoricalTickData | WsStreamStarted | WsStreamProgress | WsHistoricalBatch | WsStreamCompleted | WsStreamStopped;
556
+ type WsServerMessage = WsSubscribed | WsUnsubscribed | WsPong | WsError | WsData | WsReplayStarted | WsReplayPaused | WsReplayResumed | WsReplayCompleted | WsReplayStopped | WsHistoricalData | WsHistoricalTickData | WsStreamStarted | WsStreamProgress | WsHistoricalBatch | WsStreamCompleted | WsStreamStopped | WsGapDetected;
541
557
  /**
542
558
  * WebSocket connection options.
543
559
  *
@@ -1679,6 +1695,7 @@ declare class OxArchiveWs {
1679
1695
  private streamCompleteHandlers;
1680
1696
  private orderbookHandlers;
1681
1697
  private tradesHandlers;
1698
+ private gapHandlers;
1682
1699
  constructor(options: WsOptions);
1683
1700
  /**
1684
1701
  * Connect to the WebSocket server
@@ -1840,6 +1857,23 @@ declare class OxArchiveWs {
1840
1857
  * Handle stream completed event
1841
1858
  */
1842
1859
  onStreamComplete(handler: (channel: WsChannel, coin: string, snapshotsSent: number) => void): void;
1860
+ /**
1861
+ * Handle gap detected events during replay or streaming.
1862
+ * Called when there's a gap in the historical data exceeding the threshold.
1863
+ * Thresholds: 2 minutes for orderbook/candles/liquidations, 60 minutes for trades.
1864
+ *
1865
+ * @param handler - Callback receiving channel, coin, gap start/end timestamps (ms), and duration (minutes)
1866
+ *
1867
+ * @example
1868
+ * ```typescript
1869
+ * ws.onGap((channel, coin, gapStart, gapEnd, durationMinutes) => {
1870
+ * console.warn(`Gap detected in ${channel} ${coin}: ${durationMinutes} minutes`);
1871
+ * console.warn(` From: ${new Date(gapStart).toISOString()}`);
1872
+ * console.warn(` To: ${new Date(gapEnd).toISOString()}`);
1873
+ * });
1874
+ * ```
1875
+ */
1876
+ onGap(handler: (channel: WsChannel, coin: string, gapStart: number, gapEnd: number, durationMinutes: number) => void): void;
1843
1877
  /**
1844
1878
  * Get current connection state
1845
1879
  */
package/dist/index.d.ts CHANGED
@@ -536,8 +536,24 @@ interface WsStreamStopped {
536
536
  type: 'stream_stopped';
537
537
  snapshots_sent: number;
538
538
  }
539
+ /**
540
+ * Gap detected in historical data stream.
541
+ * Sent when there's a gap exceeding the threshold between consecutive data points.
542
+ * Thresholds: 2 minutes for orderbook/candles/liquidations, 60 minutes for trades.
543
+ */
544
+ interface WsGapDetected {
545
+ type: 'gap_detected';
546
+ channel: WsChannel;
547
+ coin: string;
548
+ /** Start of the gap (last data point timestamp in ms) */
549
+ gap_start: number;
550
+ /** End of the gap (next data point timestamp in ms) */
551
+ gap_end: number;
552
+ /** Gap duration in minutes */
553
+ duration_minutes: number;
554
+ }
539
555
  /** Server message union type */
540
- type WsServerMessage = WsSubscribed | WsUnsubscribed | WsPong | WsError | WsData | WsReplayStarted | WsReplayPaused | WsReplayResumed | WsReplayCompleted | WsReplayStopped | WsHistoricalData | WsHistoricalTickData | WsStreamStarted | WsStreamProgress | WsHistoricalBatch | WsStreamCompleted | WsStreamStopped;
556
+ type WsServerMessage = WsSubscribed | WsUnsubscribed | WsPong | WsError | WsData | WsReplayStarted | WsReplayPaused | WsReplayResumed | WsReplayCompleted | WsReplayStopped | WsHistoricalData | WsHistoricalTickData | WsStreamStarted | WsStreamProgress | WsHistoricalBatch | WsStreamCompleted | WsStreamStopped | WsGapDetected;
541
557
  /**
542
558
  * WebSocket connection options.
543
559
  *
@@ -1679,6 +1695,7 @@ declare class OxArchiveWs {
1679
1695
  private streamCompleteHandlers;
1680
1696
  private orderbookHandlers;
1681
1697
  private tradesHandlers;
1698
+ private gapHandlers;
1682
1699
  constructor(options: WsOptions);
1683
1700
  /**
1684
1701
  * Connect to the WebSocket server
@@ -1840,6 +1857,23 @@ declare class OxArchiveWs {
1840
1857
  * Handle stream completed event
1841
1858
  */
1842
1859
  onStreamComplete(handler: (channel: WsChannel, coin: string, snapshotsSent: number) => void): void;
1860
+ /**
1861
+ * Handle gap detected events during replay or streaming.
1862
+ * Called when there's a gap in the historical data exceeding the threshold.
1863
+ * Thresholds: 2 minutes for orderbook/candles/liquidations, 60 minutes for trades.
1864
+ *
1865
+ * @param handler - Callback receiving channel, coin, gap start/end timestamps (ms), and duration (minutes)
1866
+ *
1867
+ * @example
1868
+ * ```typescript
1869
+ * ws.onGap((channel, coin, gapStart, gapEnd, durationMinutes) => {
1870
+ * console.warn(`Gap detected in ${channel} ${coin}: ${durationMinutes} minutes`);
1871
+ * console.warn(` From: ${new Date(gapStart).toISOString()}`);
1872
+ * console.warn(` To: ${new Date(gapEnd).toISOString()}`);
1873
+ * });
1874
+ * ```
1875
+ */
1876
+ onGap(handler: (channel: WsChannel, coin: string, gapStart: number, gapEnd: number, durationMinutes: number) => void): void;
1843
1877
  /**
1844
1878
  * Get current connection state
1845
1879
  */
package/dist/index.js CHANGED
@@ -533,7 +533,7 @@ var TradesResource = class {
533
533
  */
534
534
  async recent(coin, limit) {
535
535
  const response = await this.http.get(
536
- `/v1/trades/${coin.toUpperCase()}/recent`,
536
+ `${this.basePath}/trades/${coin.toUpperCase()}/recent`,
537
537
  { limit },
538
538
  this.http.validationEnabled ? TradeArrayResponseSchema : void 0
539
539
  );
@@ -1175,6 +1175,7 @@ var OxArchiveWs = class {
1175
1175
  streamCompleteHandlers = [];
1176
1176
  orderbookHandlers = [];
1177
1177
  tradesHandlers = [];
1178
+ gapHandlers = [];
1178
1179
  constructor(options) {
1179
1180
  this.options = {
1180
1181
  apiKey: options.apiKey,
@@ -1464,6 +1465,25 @@ var OxArchiveWs = class {
1464
1465
  onStreamComplete(handler) {
1465
1466
  this.streamCompleteHandlers.push(handler);
1466
1467
  }
1468
+ /**
1469
+ * Handle gap detected events during replay or streaming.
1470
+ * Called when there's a gap in the historical data exceeding the threshold.
1471
+ * Thresholds: 2 minutes for orderbook/candles/liquidations, 60 minutes for trades.
1472
+ *
1473
+ * @param handler - Callback receiving channel, coin, gap start/end timestamps (ms), and duration (minutes)
1474
+ *
1475
+ * @example
1476
+ * ```typescript
1477
+ * ws.onGap((channel, coin, gapStart, gapEnd, durationMinutes) => {
1478
+ * console.warn(`Gap detected in ${channel} ${coin}: ${durationMinutes} minutes`);
1479
+ * console.warn(` From: ${new Date(gapStart).toISOString()}`);
1480
+ * console.warn(` To: ${new Date(gapEnd).toISOString()}`);
1481
+ * });
1482
+ * ```
1483
+ */
1484
+ onGap(handler) {
1485
+ this.gapHandlers.push(handler);
1486
+ }
1467
1487
  /**
1468
1488
  * Get current connection state
1469
1489
  */
@@ -1606,6 +1626,13 @@ var OxArchiveWs = class {
1606
1626
  }
1607
1627
  break;
1608
1628
  }
1629
+ case "gap_detected": {
1630
+ const msg = message;
1631
+ for (const handler of this.gapHandlers) {
1632
+ handler(msg.channel, msg.coin, msg.gap_start, msg.gap_end, msg.duration_minutes);
1633
+ }
1634
+ break;
1635
+ }
1609
1636
  case "data": {
1610
1637
  if (message.channel === "orderbook") {
1611
1638
  const orderbook = transformOrderbook(message.coin, message.data);