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