What are checkpoints?

Checkpoints track your position in a message stream so you can resume without reprocessing. They store the oldest and newest message IDs you've seen, along with the channel name to prevent accidental reuse across channels.

JsonCheckpointStore

Built-in file-based checkpoint storage using versioned JSON.

TypeScript
import { JsonCheckpointStore, CheckpointState } from 'teleglance';

const store = new JsonCheckpointStore('state.json');

// Load checkpoint (returns null if not found)
let state = await store.load('stream:telegram');

// Start from checkpoint or beginning
const afterId = state?.newestId;

for await (const message of client.iterNewMessages('telegram', { after: afterId })) {
  // Process message
  console.log(message.id);

  // Update checkpoint
  if (!state) {
    state = new CheckpointState('telegram', message.id, message.id);
  } else {
    state = state.record(message);
  }

  // Save periodically
  await store.save('stream:telegram', state);
}

Resume history iteration

Use checkpoints to resume backward pagination through history.

TypeScript
const store = new JsonCheckpointStore('history.json');
let state = await store.load('history:telegram');

// Resume from where we left off
const beforeId = state?.oldestId;

for await (const message of client.iterMessages('telegram', {
  limit: 1000,
  before: beforeId
})) {
  process(message);

  // Update checkpoint with oldest seen ID
  if (!state) {
    state = new CheckpointState('telegram', message.id, message.id);
  } else {
    state = state.record(message);
  }

  // Save every 50 messages
  if (message.id % 50 === 0) {
    await store.save('history:telegram', state);
  }
}

Custom checkpoint backends

Implement the CheckpointStore interface for databases or other storage:

TypeScript
import type { CheckpointStore, CheckpointState } from 'teleglance';

class RedisCheckpointStore implements CheckpointStore {
  constructor(private redis: RedisClient) {}

  async load(key: string): Promise<CheckpointState | null> {
    const data = await this.redis.get(`checkpoint:${key}`);
    if (data) {
      return CheckpointState.fromJson(JSON.parse(data));
    }
    return null;
  }

  async save(key: string, state: CheckpointState): Promise<void> {
    await this.redis.set(`checkpoint:${key}`, JSON.stringify(state.toJson()));
  }
}

const store = new RedisCheckpointStore(redisClient);
const state = await store.load('stream:telegram');