@secondlayer/sdk 6.23.1 → 6.24.1

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.ts CHANGED
@@ -488,6 +488,12 @@ type StreamsReorg = {
488
488
  from: string
489
489
  to: string
490
490
  }
491
+ /**
492
+ * First position of the new canonical chain at the fork, `fork:0`
493
+ * (INCLUSIVE). Not an exclusive resume token — resuming directly from it
494
+ * skips `fork:0`. The consumer rewinds to the foot of `fork_point_height`
495
+ * (`Cursor.atHeight`) to re-read the new run from `fork:0` inclusive.
496
+ */
491
497
  new_canonical_tip: string
492
498
  };
493
499
  type StreamsEventsEnvelope = {
@@ -649,6 +655,13 @@ type StreamsEventsReplayParams = {
649
655
  onDumpFile: (file: StreamsDumpFile) => Promise<void> | void
650
656
  /** Called per live page after the dump phase, like `consume`. */
651
657
  onBatch: (events: StreamsEvent[], envelope: StreamsEventsEnvelope) => Promise<string | null | undefined> | string | null | undefined
658
+ /**
659
+ * Called when the live-tail phase (after the dump backfill) crosses a reorg,
660
+ * before the cursor rewinds and re-reads the now-canonical events — same
661
+ * contract as `consume`. The dump-backfill phase is finalized and never
662
+ * reorgs; omit this to leave stale rows from an orphaned fork in place.
663
+ */
664
+ onReorg?: (reorg: StreamsReorg, ctx: StreamsReorgContext) => Promise<void> | void
652
665
  mode?: "tail" | "bounded"
653
666
  batchSize?: number
654
667
  emptyBackoffMs?: number
@@ -863,9 +876,12 @@ type IndexTip = {
863
876
  /**
864
877
  * A chain reorg overlapping a returned page's height range. Height-keyed feeds
865
878
  * (`/transactions`, `/contract-calls`, `/stacking`) populate this so a consumer
866
- * can reconcile: roll back the rows whose `block_height:tx_index` cursor falls in
867
- * `orphaned_range`, then re-fetch from `new_canonical_tip`. Empty when the page
868
- * spans no reorg.
879
+ * can reconcile: roll back every row at `block_height >= fork_point_height`
880
+ * (the whole fork block is replaced, so the rollback is inclusive of the fork
881
+ * height), then re-read the canonical run from the foot of `fork_point_height`.
882
+ * The SDK consumers do exactly this — they rewind to `Cursor.atHeight(
883
+ * fork_point_height)`, an exclusive cursor that re-reads from `fork:0`
884
+ * inclusive. Empty when the page spans no reorg.
869
885
  */
870
886
  type IndexReorg = {
871
887
  id: string
@@ -878,7 +894,12 @@ type IndexReorg = {
878
894
  from: string
879
895
  to: string
880
896
  }
881
- /** New canonical tip cursor to resume from. */
897
+ /**
898
+ * First position of the new canonical chain at the fork, `fork:0`
899
+ * (INCLUSIVE). Not an exclusive resume token — resuming a `(bh,ei) > cursor`
900
+ * read directly from it would skip `fork:0`. To re-read the new run, rewind
901
+ * to the foot of `fork_point_height` (`Cursor.atHeight`), not to this value.
902
+ */
882
903
  new_canonical_tip: string
883
904
  };
884
905
  type IndexUsage = {
@@ -2018,9 +2039,20 @@ type DecodedEventColumns = {
2018
2039
  */
2019
2040
  declare const Cursor: {
2020
2041
  /**
2021
- * Cursor at the foot of `height`. Resuming from it re-reads every event
2022
- * strictly above block `height` (cursors are exclusive), so this is the
2023
- * position to rewind to after a reorg whose fork point is `height`.
2042
+ * Cursor at the foot of `height` a position that sorts strictly below the
2043
+ * first event of block `height` (`height:0`) and strictly above every event
2044
+ * of block `height - 1`. Cursors are exclusive (`(bh,ei) > after`), so
2045
+ * resuming from it re-reads the entire canonical run starting at `height:0`
2046
+ * inclusive. This is the position to rewind to after a reorg whose fork point
2047
+ * is `height`: the new canonical block at `height` carries a fresh first
2048
+ * event at `(height, 0)` that the consumer MUST re-read.
2049
+ *
2050
+ * Encoded as `${height-1}:${SENTINEL}` rather than the seemingly-natural
2051
+ * `${height}:0` — that earlier form was an off-by-one: being exclusive, it
2052
+ * skipped `(height, 0)`, silently dropping the fork block's first row on
2053
+ * every reorg. The sentinel is int4 max (the `event_index`/`tx_index` column
2054
+ * type), larger than any real index, so nothing at `height - 1` survives the
2055
+ * keyset and the next returned row is exactly `(height, 0)`.
2024
2056
  */
2025
2057
  atHeight(height: number): string
2026
2058
  /** Parse a `<block>:<index>` cursor. Throws `ValidationError` if malformed. */
package/dist/index.js CHANGED
@@ -491,9 +491,12 @@ class StreamsSignatureError extends Error {
491
491
  }
492
492
 
493
493
  // src/streams/cursor.ts
494
+ var REWIND_FOOT_INDEX_SENTINEL = 2147483647;
494
495
  var Cursor = {
495
496
  atHeight(height) {
496
- return `${height}:0`;
497
+ if (height <= 0)
498
+ return "0:0";
499
+ return `${height - 1}:${REWIND_FOOT_INDEX_SENTINEL}`;
497
500
  },
498
501
  parse(cursor) {
499
502
  const parts = cursor.split(":");
@@ -1637,6 +1640,7 @@ function createStreamsClient(options) {
1637
1640
  batchSize: params.batchSize ?? 100,
1638
1641
  fetchEvents,
1639
1642
  onBatch: params.onBatch,
1643
+ onReorg: params.onReorg,
1640
1644
  emptyBackoffMs: params.emptyBackoffMs,
1641
1645
  maxPages: params.maxPages,
1642
1646
  maxEmptyPolls: params.maxEmptyPolls,
@@ -2501,5 +2505,5 @@ export {
2501
2505
  ApiError
2502
2506
  };
2503
2507
 
2504
- //# debugId=949AD5368987433264756E2164756E21
2508
+ //# debugId=83F19CEB4B72C83564756E2164756E21
2505
2509
  //# sourceMappingURL=index.js.map