@thru/indexer 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 +39 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +39 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -369,7 +369,7 @@ async function runEventStreamProcessor(stream, options, abortSignal) {
|
|
|
369
369
|
};
|
|
370
370
|
log("info", `Starting stream processor: ${stream.description}`);
|
|
371
371
|
const checkpoint = await getCheckpoint(db, stream.name);
|
|
372
|
-
const startSlot = checkpoint ? checkpoint.slot
|
|
372
|
+
const startSlot = checkpoint ? checkpoint.slot : defaultStartSlot;
|
|
373
373
|
log(
|
|
374
374
|
"info",
|
|
375
375
|
`Starting from slot ${startSlot}${checkpoint ? " (resuming)" : " (fresh start)"}`
|
|
@@ -384,6 +384,7 @@ async function runEventStreamProcessor(stream, options, abortSignal) {
|
|
|
384
384
|
const replay = createEventReplay({
|
|
385
385
|
clientFactory,
|
|
386
386
|
startSlot,
|
|
387
|
+
resumeAfter: checkpoint?.eventId ? { slot: checkpoint.slot, eventId: checkpoint.eventId } : void 0,
|
|
387
388
|
safetyMargin: BigInt(safetyMargin),
|
|
388
389
|
pageSize,
|
|
389
390
|
filter: stream.getFilter(),
|
|
@@ -399,6 +400,8 @@ async function runEventStreamProcessor(stream, options, abortSignal) {
|
|
|
399
400
|
let lastLogTime = Date.now();
|
|
400
401
|
let eventsReceivedSinceLastLog = 0;
|
|
401
402
|
const commitBatch = async (batch) => {
|
|
403
|
+
const lastSeenEvent = batch.events[batch.events.length - 1];
|
|
404
|
+
const lastSeenEventId = lastSeenEvent?.id ?? null;
|
|
402
405
|
let eventsToCommit = batch.events;
|
|
403
406
|
if (stream.filterBatch) {
|
|
404
407
|
try {
|
|
@@ -411,6 +414,8 @@ async function runEventStreamProcessor(stream, options, abortSignal) {
|
|
|
411
414
|
"debug",
|
|
412
415
|
`All ${batch.events.length} events filtered out at slot ${batch.slot}`
|
|
413
416
|
);
|
|
417
|
+
await updateCheckpoint(db, stream.name, batch.slot, lastSeenEventId);
|
|
418
|
+
stats.lastSlot = batch.slot;
|
|
414
419
|
return;
|
|
415
420
|
}
|
|
416
421
|
if (eventsToCommit.length < batch.events.length) {
|
|
@@ -427,21 +432,23 @@ async function runEventStreamProcessor(stream, options, abortSignal) {
|
|
|
427
432
|
return;
|
|
428
433
|
}
|
|
429
434
|
}
|
|
435
|
+
const lastEventToCommit = eventsToCommit[eventsToCommit.length - 1];
|
|
436
|
+
const lastEventToCommitId = lastEventToCommit?.id ?? null;
|
|
437
|
+
let committedEvents = eventsToCommit;
|
|
430
438
|
await db.transaction(async (tx) => {
|
|
431
|
-
await tx.insert(stream.table).values(eventsToCommit).onConflictDoNothing();
|
|
432
|
-
const lastEvent = eventsToCommit[eventsToCommit.length - 1];
|
|
439
|
+
committedEvents = await tx.insert(stream.table).values(eventsToCommit).onConflictDoNothing().returning();
|
|
433
440
|
await updateCheckpoint(
|
|
434
441
|
tx,
|
|
435
442
|
stream.name,
|
|
436
443
|
batch.slot,
|
|
437
|
-
|
|
444
|
+
lastEventToCommitId
|
|
438
445
|
);
|
|
439
446
|
});
|
|
440
447
|
stats.batchesCommitted++;
|
|
441
448
|
stats.lastSlot = batch.slot;
|
|
442
|
-
if (stream.onCommit) {
|
|
449
|
+
if (stream.onCommit && committedEvents.length > 0) {
|
|
443
450
|
try {
|
|
444
|
-
await stream.onCommit({ ...batch, events:
|
|
451
|
+
await stream.onCommit({ ...batch, events: committedEvents }, { db });
|
|
445
452
|
} catch (hookErr) {
|
|
446
453
|
log(
|
|
447
454
|
"error",
|
|
@@ -615,7 +622,6 @@ async function runAccountStreamProcessor(stream, options, abortSignal) {
|
|
|
615
622
|
"info",
|
|
616
623
|
`Backfill complete. Highest slot: ${highestSlot}, accounts processed: ${stats.accountsProcessed}`
|
|
617
624
|
);
|
|
618
|
-
lastProcessedSlot = highestSlot;
|
|
619
625
|
}
|
|
620
626
|
});
|
|
621
627
|
for await (const event of replay) {
|
|
@@ -641,6 +647,9 @@ async function runAccountStreamProcessor(stream, options, abortSignal) {
|
|
|
641
647
|
await db.delete(stream.table).where(eq(table[idField], idValue));
|
|
642
648
|
stats.accountsDeleted++;
|
|
643
649
|
log("info", `Deleted row for account ${account.addressHex}`);
|
|
650
|
+
if (account.slot > lastProcessedSlot) {
|
|
651
|
+
lastProcessedSlot = account.slot;
|
|
652
|
+
}
|
|
644
653
|
} catch (err) {
|
|
645
654
|
log("error", `Failed to delete account ${account.addressHex}: ${err}`);
|
|
646
655
|
}
|
|
@@ -652,6 +661,9 @@ async function runAccountStreamProcessor(stream, options, abortSignal) {
|
|
|
652
661
|
"debug",
|
|
653
662
|
`Skipped account ${account.addressHex} - parser returned null (dataLen=${account.data.length})`
|
|
654
663
|
);
|
|
664
|
+
if (account.slot > lastProcessedSlot) {
|
|
665
|
+
lastProcessedSlot = account.slot;
|
|
666
|
+
}
|
|
655
667
|
continue;
|
|
656
668
|
}
|
|
657
669
|
if (validateParse) {
|
|
@@ -661,14 +673,18 @@ async function runAccountStreamProcessor(stream, options, abortSignal) {
|
|
|
661
673
|
continue;
|
|
662
674
|
}
|
|
663
675
|
}
|
|
676
|
+
let upserted = false;
|
|
664
677
|
try {
|
|
665
|
-
await db.insert(stream.table).values(parsed).onConflictDoUpdate({
|
|
678
|
+
const upsertedRows = await db.insert(stream.table).values(parsed).onConflictDoUpdate({
|
|
666
679
|
target: table[idField],
|
|
667
680
|
set: parsed,
|
|
668
681
|
where: sql`${table.slot} <= ${parsed.slot}`
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
if (
|
|
682
|
+
}).returning();
|
|
683
|
+
upserted = upsertedRows.length > 0;
|
|
684
|
+
if (upserted) {
|
|
685
|
+
stats.accountsUpdated++;
|
|
686
|
+
}
|
|
687
|
+
if (upserted && stats.accountsUpdated <= 3) {
|
|
672
688
|
log(
|
|
673
689
|
"info",
|
|
674
690
|
`Successfully inserted account ${stats.accountsUpdated}`
|
|
@@ -680,7 +696,7 @@ async function runAccountStreamProcessor(stream, options, abortSignal) {
|
|
|
680
696
|
`Failed to upsert account ${account.addressHex}: ${err}`
|
|
681
697
|
);
|
|
682
698
|
}
|
|
683
|
-
if (account.slot > lastProcessedSlot) {
|
|
699
|
+
if (upserted && account.slot > lastProcessedSlot) {
|
|
684
700
|
lastProcessedSlot = account.slot;
|
|
685
701
|
}
|
|
686
702
|
if (stats.accountsProcessed % 100 === 0) {
|
|
@@ -691,11 +707,18 @@ async function runAccountStreamProcessor(stream, options, abortSignal) {
|
|
|
691
707
|
}
|
|
692
708
|
} else if (event.type === "blockFinished") {
|
|
693
709
|
const slot = event.block.slot;
|
|
694
|
-
if (
|
|
695
|
-
lastProcessedSlot
|
|
710
|
+
if (lastProcessedSlot > 0n) {
|
|
711
|
+
await updateCheckpoint(db, checkpointName, lastProcessedSlot, null);
|
|
712
|
+
log(
|
|
713
|
+
"debug",
|
|
714
|
+
`Block finished: slot ${slot}, checkpoint saved at account slot ${lastProcessedSlot}`
|
|
715
|
+
);
|
|
716
|
+
} else {
|
|
717
|
+
log(
|
|
718
|
+
"debug",
|
|
719
|
+
`Block finished: slot ${slot}, no checkpoint yet (no accounts handled)`
|
|
720
|
+
);
|
|
696
721
|
}
|
|
697
|
-
await updateCheckpoint(db, checkpointName, lastProcessedSlot, null);
|
|
698
|
-
log("debug", `Block finished: slot ${slot}, checkpoint saved`);
|
|
699
722
|
}
|
|
700
723
|
}
|
|
701
724
|
if (lastProcessedSlot > 0n) {
|