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