@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 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 + 1n : defaultStartSlot;
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
- lastEvent.id
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: eventsToCommit }, { db });
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
- stats.accountsUpdated++;
673
- if (stats.accountsUpdated <= 3) {
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 (slot > lastProcessedSlot) {
697
- lastProcessedSlot = slot;
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) {