@thru/replay 0.2.18 → 0.2.20
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.cjs +51 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +51 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -797,7 +797,7 @@ function createEventReplay(options) {
|
|
|
797
797
|
orderBy: PAGE_ORDER_ASC3,
|
|
798
798
|
pageToken: cursor
|
|
799
799
|
});
|
|
800
|
-
const baseFilter =
|
|
800
|
+
const baseFilter = eventBackfillFilter(startSlot, options.resumeAfter);
|
|
801
801
|
const mergedFilter = combineFilters(baseFilter, options.filter);
|
|
802
802
|
const response = await client.listEvents(
|
|
803
803
|
protobuf.create(proto.ListEventsRequestSchema, {
|
|
@@ -808,13 +808,19 @@ function createEventReplay(options) {
|
|
|
808
808
|
return backfillPage(response.events, response.page);
|
|
809
809
|
};
|
|
810
810
|
const createSubscribeLive = (client) => (startSlot) => {
|
|
811
|
-
const mergedFilter = combineFilters(
|
|
811
|
+
const mergedFilter = combineFilters(
|
|
812
|
+
slotLiteralFilter("event.slot", startSlot),
|
|
813
|
+
options.filter
|
|
814
|
+
);
|
|
812
815
|
const request = protobuf.create(proto.StreamEventsRequestSchema, {
|
|
813
816
|
filter: mergedFilter
|
|
814
817
|
});
|
|
815
818
|
return mapAsyncIterable(
|
|
816
819
|
client.streamEvents(request),
|
|
817
|
-
(resp) =>
|
|
820
|
+
(resp) => {
|
|
821
|
+
const event = streamResponseToEvent(resp);
|
|
822
|
+
return shouldEmitLiveEvent(event, startSlot, options.resumeAfter) ? event : null;
|
|
823
|
+
}
|
|
818
824
|
);
|
|
819
825
|
};
|
|
820
826
|
const onReconnect = options.clientFactory ? () => {
|
|
@@ -852,6 +858,48 @@ function eventKey(event) {
|
|
|
852
858
|
const slotPart = event.slot?.toString() ?? "0";
|
|
853
859
|
return `${slotPart}:${event.callIdx ?? 0}`;
|
|
854
860
|
}
|
|
861
|
+
function eventBackfillFilter(startSlot, resumeAfter) {
|
|
862
|
+
const boundary = parseEventId(resumeAfter);
|
|
863
|
+
if (!boundary || startSlot > boundary.slot) {
|
|
864
|
+
return slotLiteralFilter("event.slot", startSlot);
|
|
865
|
+
}
|
|
866
|
+
return protobuf.create(proto.FilterSchema, {
|
|
867
|
+
expression: `event.slot > uint(${boundary.slot.toString()}) || (event.slot == uint(${boundary.slot.toString()}) && (event.block_offset > uint(${boundary.blockOffset.toString()}) || (event.block_offset == uint(${boundary.blockOffset.toString()}) && event.call_idx > uint(${boundary.callIdx.toString()}))))`
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
function parseEventId(resumeAfter) {
|
|
871
|
+
if (!resumeAfter?.eventId) return null;
|
|
872
|
+
return parseCanonicalEventId(resumeAfter.eventId, resumeAfter.slot);
|
|
873
|
+
}
|
|
874
|
+
function parseCanonicalEventId(eventId, expectedSlot) {
|
|
875
|
+
if (!eventId) return null;
|
|
876
|
+
const match = /^ts(\d+)_(\d+)_(\d+)$/.exec(eventId);
|
|
877
|
+
if (!match) return null;
|
|
878
|
+
const [slotPart, blockOffsetPart, callIdxPart] = match.slice(1);
|
|
879
|
+
const slot = BigInt(slotPart);
|
|
880
|
+
if (slot !== expectedSlot) return null;
|
|
881
|
+
return {
|
|
882
|
+
slot,
|
|
883
|
+
blockOffset: BigInt(blockOffsetPart),
|
|
884
|
+
callIdx: BigInt(callIdxPart)
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
function isAfterBoundary(event, boundary) {
|
|
888
|
+
if (event.slot !== boundary.slot) return event.slot > boundary.slot;
|
|
889
|
+
if (event.blockOffset !== boundary.blockOffset) {
|
|
890
|
+
return event.blockOffset > boundary.blockOffset;
|
|
891
|
+
}
|
|
892
|
+
return event.callIdx > boundary.callIdx;
|
|
893
|
+
}
|
|
894
|
+
function shouldEmitLiveEvent(event, startSlot, resumeAfter) {
|
|
895
|
+
const boundary = parseEventId(resumeAfter);
|
|
896
|
+
if (!boundary || startSlot > boundary.slot) return true;
|
|
897
|
+
const eventSlot = event.slot ?? 0n;
|
|
898
|
+
if (eventSlot > boundary.slot) return true;
|
|
899
|
+
if (eventSlot < boundary.slot) return false;
|
|
900
|
+
const eventPosition = parseCanonicalEventId(event.eventId, boundary.slot);
|
|
901
|
+
return eventPosition ? isAfterBoundary(eventPosition, boundary) : false;
|
|
902
|
+
}
|
|
855
903
|
|
|
856
904
|
// src/page-assembler.ts
|
|
857
905
|
var PAGE_SIZE = 4096;
|