@thru/indexer 0.2.35 → 0.2.37

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema/builder.ts","../src/schema/table.ts","../src/schema/validation.ts","../src/streams/define.ts","../src/checkpoint/table.ts","../src/checkpoint/repository.ts","../src/checkpoint/index.ts","../src/runtime/logger.ts","../src/streams/processor.ts","../src/accounts/define.ts","../src/accounts/processor.ts","../src/runtime/status.ts","../src/runtime/indexer.ts"],"names":["text","bigint","integer","boolean","timestamp","index","pgTable","z","eq","replay","createEventReplay","pascalCase","createAccountsByOwnerReplay","AccountView","encodeAddress","sql"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Fluent column builder API for defining schemas.\n * Exports a global `t` object for concise schema definitions.\n *\n * @example\n * ```ts\n * import { t } from \"@thru/indexer\";\n *\n * const schema = {\n * id: t.text().primaryKey(),\n * slot: t.bigint().notNull().index(),\n * amount: t.bigint().notNull(),\n * timestamp: t.timestamp(),\n * };\n * ```\n */\n\nimport type { PgTableWithColumns } from \"drizzle-orm/pg-core\";\nimport type { ColumnDef, ColumnType } from \"./types\";\n\n// ============================================================\n// Column Definition Implementation\n// ============================================================\n\ninterface ColumnState<T> {\n _type: T;\n _columnType: ColumnType;\n _nullable: boolean;\n _indexed: boolean;\n _unique: boolean;\n _primary: boolean;\n _default?: T;\n _defaultNow?: boolean;\n _references?: { table: PgTableWithColumns<any>; column: string };\n}\n\n/**\n * Create a builder object from state with the given nullability type parameter.\n */\nfunction createBuilder<T, TNull extends boolean>(\n state: ColumnState<T>\n): ColumnDef<T, TNull> {\n const builder: ColumnDef<T, TNull> = {\n get _type() { return state._type; },\n get _columnType() { return state._columnType; },\n get _nullable() { return state._nullable as TNull; },\n get _indexed() { return state._indexed; },\n get _unique() { return state._unique; },\n get _primary() { return state._primary; },\n get _default() { return state._default; },\n get _defaultNow() { return state._defaultNow; },\n get _references() { return state._references; },\n\n notNull(): ColumnDef<T, false> {\n state._nullable = false;\n return createBuilder<T, false>(state);\n },\n\n index(): ColumnDef<T, TNull> {\n state._indexed = true;\n return builder;\n },\n\n unique(): ColumnDef<T, TNull> {\n state._unique = true;\n return builder;\n },\n\n primaryKey(): ColumnDef<T, false> {\n state._primary = true;\n state._nullable = false;\n return createBuilder<T, false>(state);\n },\n\n default(value: T): ColumnDef<T, TNull> {\n state._default = value;\n return builder;\n },\n\n defaultNow(): ColumnDef<T, TNull> {\n state._defaultNow = true;\n return builder;\n },\n\n references<TTable extends PgTableWithColumns<any>>(\n table: TTable | (() => TTable),\n column: keyof TTable[\"_\"][\"columns\"]\n ): ColumnDef<T, TNull> {\n const resolvedTable = typeof table === \"function\" ? table() : table;\n state._references = { table: resolvedTable, column: column as string };\n return builder;\n },\n };\n\n return builder;\n}\n\n/**\n * Creates a column definition with proper type tracking.\n */\nfunction createColumnDef<T>(type: ColumnType): ColumnDef<T, true> {\n const state: ColumnState<T> = {\n _type: undefined as T,\n _columnType: type,\n _nullable: true,\n _indexed: false,\n _unique: false,\n _primary: false,\n _default: undefined,\n _defaultNow: false,\n _references: undefined,\n };\n\n return createBuilder<T, true>(state);\n}\n\n// ============================================================\n// Column Builder Interface\n// ============================================================\n\n/**\n * Interface for the column builder.\n * Each method creates a new column definition of the appropriate type.\n */\nexport interface ColumnBuilder {\n /** Text column (varchar) */\n text(): ColumnDef<string, true>;\n /** BigInt column (64-bit integer) - use for slots, amounts */\n bigint(): ColumnDef<bigint, true>;\n /** Integer column (32-bit) */\n integer(): ColumnDef<number, true>;\n /** Boolean column */\n boolean(): ColumnDef<boolean, true>;\n /** Timestamp column with timezone */\n timestamp(): ColumnDef<Date, true>;\n}\n\n// ============================================================\n// Global Column Builder\n// ============================================================\n\n/**\n * Global column builder for defining schemas.\n *\n * @example\n * ```ts\n * const schema = {\n * id: t.text().primaryKey(),\n * slot: t.bigint().notNull().index(),\n * name: t.text(),\n * active: t.boolean().notNull().default(true),\n * createdAt: t.timestamp().notNull().defaultNow(),\n * };\n * ```\n */\nexport const t: ColumnBuilder = {\n text: () => createColumnDef<string>(\"text\"),\n bigint: () => createColumnDef<bigint>(\"bigint\"),\n integer: () => createColumnDef<number>(\"integer\"),\n boolean: () => createColumnDef<boolean>(\"boolean\"),\n timestamp: () => createColumnDef<Date>(\"timestamp\"),\n};\n\n/**\n * Alternative export for the column builder.\n * Same as `t` but with a more descriptive name.\n */\nexport const columnBuilder = t;\n","/**\n * Build Drizzle tables from schema definitions.\n */\n\nimport {\n pgTable,\n text,\n bigint,\n integer,\n boolean,\n timestamp,\n index,\n type PgTableWithColumns,\n type PgColumnBuilderBase,\n} from \"drizzle-orm/pg-core\";\nimport type { AnyColumnDef, ColumnType, SchemaDefinition } from \"./types\";\n\n// ============================================================\n// Internal Types\n// ============================================================\n\ninterface ColumnDefInternal {\n _type: unknown;\n _columnType: ColumnType;\n _nullable: boolean;\n _indexed: boolean;\n _unique: boolean;\n _primary: boolean;\n _default?: unknown;\n _defaultNow?: boolean;\n _references?: { table: PgTableWithColumns<any>; column: string };\n}\n\n// ============================================================\n// Utilities\n// ============================================================\n\n/**\n * Convert camelCase to snake_case for database column names.\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n// ============================================================\n// Table Builder\n// ============================================================\n\n/**\n * Build a Drizzle pgTable from a schema definition object.\n *\n * @param tableName - The database table name\n * @param schema - Schema definition object with column definitions\n * @returns A Drizzle table with proper types\n *\n * @example\n * ```ts\n * const schema = {\n * id: t.text().primaryKey(),\n * slot: t.bigint().notNull().index(),\n * };\n *\n * const table = buildDrizzleTable(\"my_events\", schema);\n * ```\n */\nexport function buildDrizzleTable<TSchema extends SchemaDefinition>(\n tableName: string,\n schema: TSchema\n): PgTableWithColumns<any> {\n // Build column definitions\n const columns: Record<string, PgColumnBuilderBase> = {};\n const indices: Array<(table: any) => any> = [];\n\n for (const [name, def] of Object.entries(schema)) {\n const internal = def as ColumnDefInternal;\n const snakeName = camelToSnake(name);\n\n // Create the base column\n let col: PgColumnBuilderBase;\n switch (internal._columnType) {\n case \"text\":\n col = text(snakeName);\n break;\n case \"bigint\":\n col = bigint(snakeName, { mode: \"bigint\" });\n break;\n case \"integer\":\n col = integer(snakeName);\n break;\n case \"boolean\":\n col = boolean(snakeName);\n break;\n case \"timestamp\":\n col = timestamp(snakeName, { withTimezone: true });\n break;\n default:\n throw new Error(`Unknown column type: ${internal._columnType}`);\n }\n\n // Apply modifiers\n if (internal._primary) {\n col = (col as any).primaryKey();\n }\n if (internal._unique) {\n col = (col as any).unique();\n }\n if (!internal._nullable) {\n col = (col as any).notNull();\n }\n if (internal._defaultNow && internal._columnType === \"timestamp\") {\n col = (col as any).defaultNow();\n } else if (internal._default !== undefined) {\n col = (col as any).default(internal._default);\n }\n if (internal._references) {\n const refTable = internal._references.table;\n const refColumn = internal._references.column;\n col = (col as any).references(() => refTable[refColumn]);\n }\n\n columns[name] = col;\n\n // Track indices\n if (internal._indexed) {\n indices.push((table: any) =>\n index(`${tableName}_${snakeName}_idx`).on(table[name])\n );\n }\n }\n\n // Create the table\n if (indices.length > 0) {\n return pgTable(tableName, columns, (table) =>\n indices.map((fn) => fn(table))\n );\n }\n return pgTable(tableName, columns);\n}\n","/**\n * Runtime validation for parsed data.\n * Generates Zod schemas from column definitions for validation.\n */\n\nimport { z } from \"zod\";\nimport type { SchemaDefinition, AnyColumnDef } from \"./types\";\n\n/**\n * Generate a Zod schema from column definitions.\n * Used for runtime validation of parse output.\n */\nexport function generateZodSchema<TSchema extends SchemaDefinition>(\n schema: TSchema\n): z.ZodObject<any> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, col] of Object.entries(schema)) {\n const colDef = col as AnyColumnDef;\n let zodType: z.ZodTypeAny;\n\n // Map column type to Zod type\n switch (colDef._columnType) {\n case \"text\":\n zodType = z.string();\n break;\n case \"bigint\":\n zodType = z.bigint();\n break;\n case \"integer\":\n zodType = z.number().int();\n break;\n case \"boolean\":\n zodType = z.boolean();\n break;\n case \"timestamp\":\n zodType = z.date();\n break;\n default:\n zodType = z.unknown();\n }\n\n // Handle nullability\n if (colDef._nullable) {\n zodType = zodType.nullable();\n }\n\n shape[key] = zodType;\n }\n\n return z.object(shape);\n}\n\n/**\n * Validate parsed data against schema.\n * Returns validation result with detailed errors.\n */\nexport function validateParsedData<TSchema extends SchemaDefinition>(\n schema: TSchema,\n data: unknown,\n streamName: string\n): { success: true; data: unknown } | { success: false; error: string } {\n const zodSchema = generateZodSchema(schema);\n const result = zodSchema.safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data };\n }\n\n const errorMessages = result.error.issues\n .map((e) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\");\n\n return {\n success: false,\n error: `Stream \"${streamName}\" parse returned invalid data:\\n${errorMessages}`,\n };\n}\n","/**\n * Define an event stream for indexing blockchain events.\n *\n * Event streams index historical, immutable event data from the chain.\n * Each event is stored once and never updated.\n *\n * @example\n * ```ts\n * import { defineEventStream, t } from \"@thru/indexer\";\n * import { create } from \"@bufbuild/protobuf\";\n * import { FilterSchema, type Event } from \"@thru/replay\";\n *\n * export const transfers = defineEventStream({\n * name: \"transfers\",\n *\n * schema: {\n * id: t.text().primaryKey(),\n * slot: t.bigint().notNull().index(),\n * source: t.text().notNull().index(),\n * dest: t.text().notNull().index(),\n * amount: t.bigint().notNull(),\n * },\n *\n * filter: create(FilterSchema, {\n * expression: \"event.program.value == params.address\",\n * params: { address: ... },\n * }),\n *\n * parse: (event: Event) => {\n * if (!event.payload) return null;\n * return {\n * id: event.eventId,\n * slot: event.slot!,\n * source: decodeAddress(event.payload, 0),\n * dest: decodeAddress(event.payload, 32),\n * amount: decodeBigint(event.payload, 64),\n * };\n * },\n *\n * api: { filters: [\"source\", \"dest\"] },\n * });\n *\n * // Export the table for Drizzle migrations\n * export const transfersTable = transfers.table;\n * ```\n */\n\nimport type { Filter } from \"@thru/replay\";\nimport type { SchemaDefinition } from \"../schema/types\";\nimport { buildDrizzleTable } from \"../schema/table\";\nimport type { EventStreamDefinition, EventStream } from \"./types\";\n\n// ============================================================\n// Utilities\n// ============================================================\n\nfunction pascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\n// ============================================================\n// Main Export\n// ============================================================\n\n/**\n * Define an event stream for indexing blockchain events.\n *\n * @param definition - Stream definition with schema, filter, and parse function\n * @returns A compiled event stream ready for use with the indexer\n */\nexport function defineEventStream<TSchema extends SchemaDefinition>(\n definition: EventStreamDefinition<TSchema>\n): EventStream<TSchema> {\n // Validate that either filter or filterFactory is provided\n if (!definition.filter && !definition.filterFactory) {\n throw new Error(`Stream \"${definition.name}\" must provide either filter or filterFactory`);\n }\n\n // Build table name (e.g., \"transfers\" -> \"transfer_events\")\n const tableName = `${definition.name.replace(/s$/, \"\")}_events`;\n\n // Build Drizzle table from schema\n const table = buildDrizzleTable(tableName, definition.schema);\n\n // Lazy filter resolution (cached after first call)\n let cachedFilter: Filter | null = definition.filter ?? null;\n const getFilter = (): Filter => {\n if (!cachedFilter) {\n if (definition.filterFactory) {\n cachedFilter = definition.filterFactory();\n } else {\n throw new Error(`Stream \"${definition.name}\" has no filter configured`);\n }\n }\n return cachedFilter;\n };\n\n return {\n name: definition.name,\n description: definition.description ?? `${pascalCase(definition.name)} events`,\n schema: definition.schema,\n table,\n // Column accessors for Drizzle operators\n c: table as any,\n getFilter,\n parse: definition.parse,\n api: definition.api,\n filterBatch: definition.filterBatch,\n onCommit: definition.onCommit,\n };\n}\n","/**\n * Checkpoint table schema.\n *\n * Users should export this from their Drizzle schema for migrations.\n *\n * @example\n * ```ts\n * // db/schema.ts\n * import { checkpointTable } from \"@thru/indexer\";\n * export { checkpointTable };\n * ```\n */\n\nimport {\n pgTable,\n text,\n bigint,\n timestamp,\n} from \"drizzle-orm/pg-core\";\n\n/**\n * Per-stream checkpoint table.\n * Each stream has its own checkpoint keyed by stream name.\n *\n * This table should be included in your Drizzle migrations.\n */\nexport const checkpointTable = pgTable(\"indexer_checkpoints\", {\n /** Stream name (primary key) */\n streamName: text(\"stream_name\").primaryKey(),\n /** Last indexed slot number */\n lastIndexedSlot: bigint(\"last_indexed_slot\", { mode: \"bigint\" }).notNull(),\n /** Last event ID (for cursor-based resume) */\n lastEventId: text(\"last_event_id\"),\n /** When the checkpoint was last updated */\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .defaultNow()\n .notNull(),\n});\n\n/**\n * Checkpoint data structure.\n */\nexport interface Checkpoint {\n /** Last indexed slot number */\n slot: bigint;\n /** Last event ID (for cursor-based resume) */\n eventId: string | null;\n}\n","/**\n * Checkpoint repository for reading and updating stream checkpoints.\n */\n\nimport { eq } from \"drizzle-orm\";\nimport type { DatabaseClient } from \"../schema/types\";\nimport { checkpointTable, type Checkpoint } from \"./table\";\n\n/**\n * Get the checkpoint for a specific stream.\n * Returns null if no checkpoint exists yet.\n *\n * @param db - Database client\n * @param streamName - Name of the stream\n * @returns Checkpoint or null if not found\n */\nexport async function getCheckpoint(\n db: DatabaseClient,\n streamName: string\n): Promise<Checkpoint | null> {\n const [row] = await db\n .select()\n .from(checkpointTable)\n .where(eq(checkpointTable.streamName, streamName))\n .limit(1);\n\n if (!row) {\n return null;\n }\n\n return {\n slot: row.lastIndexedSlot,\n eventId: row.lastEventId,\n };\n}\n\n/**\n * Update the checkpoint for a specific stream.\n * Uses upsert to handle both insert and update cases.\n *\n * @param db - Database client (can be a transaction)\n * @param streamName - Name of the stream\n * @param slot - Last indexed slot number\n * @param eventId - Last event ID (optional)\n */\nexport async function updateCheckpoint(\n db: DatabaseClient,\n streamName: string,\n slot: bigint,\n eventId: string | null = null\n): Promise<void> {\n await db\n .insert(checkpointTable)\n .values({\n streamName,\n lastIndexedSlot: slot,\n lastEventId: eventId,\n updatedAt: new Date(),\n })\n .onConflictDoUpdate({\n target: checkpointTable.streamName,\n set: {\n lastIndexedSlot: slot,\n lastEventId: eventId,\n updatedAt: new Date(),\n },\n });\n}\n\n/**\n * Delete the checkpoint for a specific stream.\n * Use with caution - this will cause the stream to re-index from the start.\n *\n * @param db - Database client\n * @param streamName - Name of the stream\n */\nexport async function deleteCheckpoint(\n db: DatabaseClient,\n streamName: string\n): Promise<void> {\n await db\n .delete(checkpointTable)\n .where(eq(checkpointTable.streamName, streamName));\n}\n\n/**\n * Get all checkpoints.\n * Useful for monitoring and debugging.\n *\n * @param db - Database client\n * @returns Array of checkpoints with stream names\n */\nexport async function getAllCheckpoints(\n db: DatabaseClient\n): Promise<Array<{ streamName: string; checkpoint: Checkpoint }>> {\n const rows = await db.select().from(checkpointTable);\n\n return rows.map((row) => ({\n streamName: row.streamName,\n checkpoint: {\n slot: row.lastIndexedSlot,\n eventId: row.lastEventId,\n },\n }));\n}\n","/**\n * Checkpoint module exports.\n */\n\nexport { checkpointTable, type Checkpoint } from \"./table\";\nexport {\n getCheckpoint,\n updateCheckpoint,\n deleteCheckpoint,\n getAllCheckpoints,\n} from \"./repository\";\n\nimport { checkpointTable } from \"./table\";\nimport type { EventStream } from \"../streams/types\";\nimport type { AccountStream } from \"../accounts/types\";\nimport type { PgTableWithColumns } from \"drizzle-orm/pg-core\";\n\n/**\n * Get all tables that need to be exported for Drizzle migrations.\n *\n * This helper collects the checkpoint table and all stream tables\n * into a single object for easy export in your schema file.\n *\n * @example\n * ```ts\n * // db/schema.ts\n * import { getSchemaExports } from \"@thru/indexer\";\n * import transfers from \"../streams/transfers\";\n * import tokenAccounts from \"../account-streams/token-accounts\";\n *\n * export const {\n * checkpointTable,\n * transfersTable,\n * tokenAccountsTable,\n * } = getSchemaExports({\n * eventStreams: [transfers],\n * accountStreams: [tokenAccounts],\n * tableNames: {\n * transfers: \"transfersTable\",\n * \"token-accounts\": \"tokenAccountsTable\",\n * },\n * });\n * ```\n */\nexport function getSchemaExports(config: {\n eventStreams?: EventStream<any>[];\n accountStreams?: AccountStream<any>[];\n tableNames?: Record<string, string>;\n}): Record<string, PgTableWithColumns<any>> {\n const { eventStreams = [], accountStreams = [], tableNames = {} } = config;\n\n const exports: Record<string, PgTableWithColumns<any>> = {\n checkpointTable,\n };\n\n for (const stream of eventStreams) {\n const exportName = tableNames[stream.name] ?? `${stream.name}Table`;\n exports[exportName] = stream.table as PgTableWithColumns<any>;\n }\n\n for (const stream of accountStreams) {\n const exportName = tableNames[stream.name] ?? `${stream.name.replace(/-/g, \"\")}Table`;\n exports[exportName] = stream.table as PgTableWithColumns<any>;\n }\n\n return exports;\n}\n","import type { ReplayLogger } from \"@thru/replay\";\n\nexport type IndexerLogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: IndexerLogLevel[] = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction shouldLog(level: IndexerLogLevel, minimum: IndexerLogLevel): boolean {\n return LEVELS.indexOf(level) >= LEVELS.indexOf(minimum);\n}\n\nfunction writeConsole(\n prefix: string,\n level: IndexerLogLevel,\n message: string,\n meta?: Record<string, unknown>\n): void {\n const text = `[${prefix}] ${message}`;\n if (meta && Object.keys(meta).length > 0) {\n if (level === \"error\") {\n console.error(text, meta);\n } else if (level === \"warn\") {\n console.warn(text, meta);\n } else {\n console.log(text, meta);\n }\n return;\n }\n\n if (level === \"error\") {\n console.error(text);\n } else if (level === \"warn\") {\n console.warn(text);\n } else {\n console.log(text);\n }\n}\n\nexport function createScopedLogger(options: {\n logger?: ReplayLogger;\n level?: IndexerLogLevel;\n prefix: string;\n bindings?: Record<string, unknown>;\n}): ReplayLogger {\n const minimum = options.level ?? \"info\";\n const bindings = options.bindings ?? {};\n\n const log = (\n level: IndexerLogLevel,\n message: string,\n meta?: Record<string, unknown>\n ) => {\n if (!shouldLog(level, minimum)) {\n return;\n }\n\n const hasMeta = meta !== undefined && Object.keys(meta).length > 0;\n const fields = { ...bindings, ...(meta ?? {}) };\n if (options.logger) {\n options.logger[level](message, fields);\n } else {\n writeConsole(options.prefix, level, message, hasMeta ? fields : undefined);\n }\n };\n\n return {\n debug: (message, meta) => log(\"debug\", message, meta),\n info: (message, meta) => log(\"info\", message, meta),\n warn: (message, meta) => log(\"warn\", message, meta),\n error: (message, meta) => log(\"error\", message, meta),\n };\n}\n","/**\n * Event stream processor.\n *\n * Processes events from @thru/replay and commits them to the database\n * with batching and checkpointing.\n */\n\nimport type { ChainClientFactory, ReplayLogger } from \"@thru/replay\";\nimport { createEventReplay } from \"@thru/replay\";\nimport type { PgTable } from \"drizzle-orm/pg-core\";\nimport type { DatabaseClient } from \"../schema/types\";\nimport { validateParsedData } from \"../schema/validation\";\nimport { getCheckpoint, updateCheckpoint } from \"../checkpoint\";\nimport type { EventStream } from \"./types\";\nimport type { StreamBatch } from \"../types\";\nimport type { ProcessorStatusObserver } from \"../runtime/status\";\nimport { createScopedLogger } from \"../runtime/logger\";\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface ProcessorOptions {\n /** Factory to create fresh chain clients for reconnection */\n clientFactory: ChainClientFactory;\n /** Database client */\n db: DatabaseClient;\n /** Start slot if no checkpoint exists */\n defaultStartSlot: bigint;\n /** Safety margin for finality (in slots) */\n safetyMargin?: number;\n /** Page size for fetching events */\n pageSize?: number;\n /** Log level */\n logLevel?: \"debug\" | \"info\" | \"warn\" | \"error\";\n /** Structured logger for processor and replay lifecycle logs */\n logger?: ReplayLogger;\n /** Validate parse output with Zod (useful for development) */\n validateParse?: boolean;\n /** Runtime status observer */\n observer?: ProcessorStatusObserver;\n}\n\nexport interface ProcessorStats {\n /** Total events processed */\n eventsProcessed: number;\n /** Total batches committed */\n batchesCommitted: number;\n /** Last slot processed */\n lastSlot: bigint | null;\n}\n\n// ============================================================\n// Batcher\n// ============================================================\n\n/**\n * Generic batcher that collects events by slot and flushes on slot change\n * or when thresholds are reached.\n */\nclass StreamBatcher {\n private currentSlot: bigint | null = null;\n private pendingEvents: unknown[] = [];\n private lastFlushTime = Date.now();\n private maxPendingCount = 100;\n private maxPendingMs = 5000;\n\n addEvent(event: unknown, slot: bigint): StreamBatch | null {\n // If slot changed or thresholds reached, flush pending\n if (this.shouldFlush(slot)) {\n const batch = this.flush();\n this.currentSlot = slot;\n this.pendingEvents = [event];\n return batch;\n }\n\n this.currentSlot = slot;\n this.pendingEvents.push(event);\n return null;\n }\n\n private shouldFlush(newSlot: bigint): boolean {\n if (this.pendingEvents.length === 0) return false;\n if (this.currentSlot !== null && newSlot !== this.currentSlot) return true;\n if (this.pendingEvents.length >= this.maxPendingCount) return true;\n if (Date.now() - this.lastFlushTime >= this.maxPendingMs) return true;\n return false;\n }\n\n flush(): StreamBatch | null {\n if (this.pendingEvents.length === 0 || this.currentSlot === null) {\n return null;\n }\n const batch = {\n slot: this.currentSlot,\n events: this.pendingEvents,\n };\n this.pendingEvents = [];\n this.lastFlushTime = Date.now();\n return batch;\n }\n\n getPendingCount(): number {\n return this.pendingEvents.length;\n }\n\n /**\n * Flush if the timeout has elapsed since last flush.\n * Called by background timer to ensure events don't sit in buffer indefinitely.\n */\n flushIfStale(): StreamBatch | null {\n if (\n this.pendingEvents.length > 0 &&\n Date.now() - this.lastFlushTime >= this.maxPendingMs\n ) {\n return this.flush();\n }\n return null;\n }\n}\n\n// ============================================================\n// Processor\n// ============================================================\n\n/**\n * Run an event stream processor.\n *\n * Fetches events from the chain using @thru/replay, parses them,\n * batches by slot, and commits to the database with checkpointing.\n *\n * @param stream - The event stream to process\n * @param options - Processor configuration\n * @param abortSignal - Optional signal to stop processing\n * @returns Processor statistics\n */\nexport async function runEventStreamProcessor(\n stream: EventStream,\n options: ProcessorOptions,\n abortSignal?: AbortSignal\n): Promise<ProcessorStats> {\n const {\n clientFactory,\n db,\n defaultStartSlot,\n safetyMargin = 64,\n pageSize = 512,\n logLevel = \"info\",\n logger: baseLogger,\n validateParse = false,\n observer,\n } = options;\n\n const logger = createScopedLogger({\n logger: baseLogger,\n level: logLevel,\n prefix: stream.name,\n bindings: {\n component: \"indexer-stream\",\n stream: stream.name,\n kind: \"event\",\n },\n });\n const log = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n msg: string,\n meta?: Record<string, unknown>\n ) => logger[level](msg, meta);\n\n log(\"info\", `Starting stream processor: ${stream.description}`);\n\n // Get checkpoint for this stream\n const checkpoint = await getCheckpoint(db, stream.name);\n // Resume from the checkpoint slot rather than slot + 1. Checkpoints store\n // lastEventId, but this processor only filters by slot; replaying the\n // checkpoint slot and relying on idempotent inserts avoids skipping\n // unprocessed events from the same slot after partial commits.\n const startSlot = checkpoint ? checkpoint.slot : defaultStartSlot;\n observer?.onStart?.({\n startSlot,\n checkpointSlot: checkpoint?.slot ?? null,\n });\n\n log(\n \"info\",\n `Starting from slot ${startSlot}${checkpoint ? \" (resuming)\" : \" (fresh start)\"}`\n );\n\n // Create replay stream with factory for robust reconnection\n const replay = createEventReplay({\n clientFactory,\n startSlot,\n resumeAfter: checkpoint?.eventId\n ? { slot: checkpoint.slot, eventId: checkpoint.eventId }\n : undefined,\n safetyMargin: BigInt(safetyMargin),\n pageSize,\n filter: stream.getFilter(),\n logger,\n resubscribeOnEnd: true,\n signal: abortSignal,\n });\n\n const batcher = new StreamBatcher();\n const stats: ProcessorStats = {\n eventsProcessed: 0,\n batchesCommitted: 0,\n lastSlot: null,\n };\n\n let lastLogTime = Date.now();\n let eventsReceivedSinceLastLog = 0;\n\n // Commit a batch to the database\n const commitBatch = async (batch: StreamBatch): Promise<void> => {\n const lastSeenEvent = (batch.events as Record<string, unknown>[])[\n batch.events.length - 1\n ] as { id?: string } | undefined;\n const lastSeenEventId = lastSeenEvent?.id ?? null;\n let eventsToCommit = batch.events as Record<string, unknown>[];\n\n // Apply filterBatch hook if defined\n if (stream.filterBatch) {\n try {\n eventsToCommit = (await stream.filterBatch(\n eventsToCommit as any,\n { db }\n )) as any;\n if (eventsToCommit.length === 0) {\n log(\n \"debug\",\n `All ${batch.events.length} events filtered out at slot ${batch.slot}`\n );\n await updateCheckpoint(db, stream.name, batch.slot, lastSeenEventId);\n stats.lastSlot = batch.slot;\n return;\n }\n if (eventsToCommit.length < batch.events.length) {\n log(\n \"debug\",\n `Filtered ${batch.events.length - eventsToCommit.length} of ${batch.events.length} events at slot ${batch.slot}`\n );\n }\n } catch (filterErr) {\n observer?.onError?.(\"filterBatch\", filterErr);\n log(\n \"error\",\n `filterBatch hook failed: ${filterErr instanceof Error ? filterErr.message : String(filterErr)}`\n );\n throw filterErr;\n }\n }\n\n const lastEventToCommit = eventsToCommit[eventsToCommit.length - 1] as\n | { id?: string }\n | undefined;\n const lastEventToCommitId = lastEventToCommit?.id ?? null;\n let committedEvents = eventsToCommit;\n try {\n await db.transaction(async (tx) => {\n // Insert events (skip duplicates)\n committedEvents = (await tx\n .insert(stream.table as PgTable)\n .values(eventsToCommit)\n .onConflictDoNothing()\n .returning()) as Record<string, unknown>[];\n\n // Update checkpoint\n await updateCheckpoint(\n tx as unknown as DatabaseClient,\n stream.name,\n batch.slot,\n lastEventToCommitId\n );\n });\n } catch (commitErr) {\n observer?.onError?.(\"commit\", commitErr);\n throw commitErr;\n }\n\n stats.batchesCommitted++;\n stats.lastSlot = batch.slot;\n observer?.onBatchCommitted?.({\n slot: batch.slot,\n count: eventsToCommit.length,\n });\n observer?.onCheckpoint?.({ slot: batch.slot });\n\n // Call onCommit hook if defined\n if (stream.onCommit && committedEvents.length > 0) {\n try {\n await stream.onCommit({ ...batch, events: committedEvents }, { db });\n } catch (hookErr) {\n observer?.onError?.(\"onCommit\", hookErr);\n log(\n \"error\",\n `onCommit hook failed: ${hookErr instanceof Error ? hookErr.message : String(hookErr)}`\n );\n // Don't rethrow - hooks should not block indexing\n }\n }\n };\n\n let rejectFlushFailure: (error: unknown) => void = () => {};\n const flushFailure = new Promise<never>((_, reject) => {\n rejectFlushFailure = reject;\n });\n\n // Background timer to flush pending events that exceed the timeout.\n // Failures here must reject the processor so the supervisor can restart\n // from the last durable checkpoint instead of silently dropping the batch.\n const flushInterval = setInterval(async () => {\n const batch = batcher.flushIfStale();\n if (batch) {\n try {\n await commitBatch(batch);\n log(\n \"debug\",\n `Timeout flush: ${batch.events.length} event(s) at slot ${batch.slot}`\n );\n } catch (err) {\n log(\n \"error\",\n `Timeout flush failed: ${err instanceof Error ? err.message : String(err)}`\n );\n clearInterval(flushInterval);\n rejectFlushFailure(err);\n }\n }\n }, 1000);\n\n const processReplay = async () => {\n for await (const event of replay) {\n if (abortSignal?.aborted) {\n log(\"info\", \"Abort signal received, stopping...\");\n break;\n }\n\n eventsReceivedSinceLastLog++;\n observer?.onRecord?.({\n slot: event.slot ?? null,\n id: event.eventId ?? null,\n });\n\n // Parse the event\n let parsed: Record<string, unknown> | null;\n try {\n parsed = stream.parse(event) as Record<string, unknown> | null;\n } catch (parseErr) {\n observer?.onParserError?.(parseErr);\n observer?.onError?.(\"parse\", parseErr);\n throw parseErr;\n }\n if (!parsed) {\n observer?.onParserNull?.();\n continue;\n }\n\n // Validate parse output if enabled\n if (validateParse) {\n const validation = validateParsedData(stream.schema, parsed, stream.name);\n if (!validation.success) {\n observer?.onParseValidationError?.(validation.error);\n log(\"error\", validation.error);\n continue; // Skip invalid events\n }\n }\n\n stats.eventsProcessed++;\n\n // Add to batcher\n const batch = batcher.addEvent(parsed, event.slot!);\n if (batch) {\n await commitBatch(batch);\n log(\n \"info\",\n `Committed ${batch.events.length} event(s) at slot ${batch.slot} (total: ${stats.eventsProcessed})`\n );\n }\n\n // Heartbeat logging\n const now = Date.now();\n if (now - lastLogTime >= 30000) {\n log(\n \"info\",\n `Heartbeat: ${eventsReceivedSinceLastLog} events received, ${batcher.getPendingCount()} pending`\n );\n eventsReceivedSinceLastLog = 0;\n lastLogTime = now;\n }\n }\n\n // Flush any remaining events\n const finalBatch = batcher.flush();\n if (finalBatch) {\n await commitBatch(finalBatch);\n log(\n \"info\",\n `Final flush: ${finalBatch.events.length} event(s) at slot ${finalBatch.slot}`\n );\n }\n };\n\n try {\n await Promise.race([processReplay(), flushFailure]);\n } catch (err) {\n log(\n \"error\",\n `Stream error: ${err instanceof Error ? err.message : String(err)}`\n );\n throw err;\n } finally {\n clearInterval(flushInterval);\n rejectFlushFailure = () => {};\n }\n\n log(\n \"info\",\n `Stream stopped. Processed ${stats.eventsProcessed} events in ${stats.batchesCommitted} batches.`\n );\n return stats;\n}\n","/**\n * Define an account stream for indexing on-chain account state.\n *\n * Account streams track current state of on-chain accounts.\n * Unlike event streams (historical log), account streams are mutable -\n * rows are updated when account state changes.\n *\n * @example\n * ```ts\n * import { defineAccountStream, t } from \"@thru/indexer\";\n * import { decodeAddress } from \"@thru/sdk/helpers\";\n * import type { AccountState } from \"@thru/replay\";\n *\n * export const tokenAccounts = defineAccountStream({\n * name: \"token-accounts\",\n *\n * ownerProgram: decodeAddress(TOKEN_PROGRAM_PUBKEY),\n * expectedSize: 73, // TokenAccount size in bytes\n *\n * schema: {\n * address: t.text().primaryKey(),\n * mint: t.text().notNull().index(),\n * owner: t.text().notNull().index(),\n * amount: t.bigint().notNull(),\n * isFrozen: t.boolean().notNull(),\n * slot: t.bigint().notNull(),\n * seq: t.bigint().notNull(),\n * updatedAt: t.timestamp().notNull().defaultNow(),\n * },\n *\n * parse: (account: AccountState) => {\n * if (account.data.length !== 73) return null;\n * return {\n * address: encodeAddress(account.address),\n * mint: parseAddress(account.data, 0),\n * owner: parseAddress(account.data, 32),\n * amount: parseBigint(account.data, 64),\n * isFrozen: account.data[72] !== 0,\n * slot: account.slot,\n * seq: account.seq,\n * updatedAt: new Date(),\n * };\n * },\n *\n * api: { filters: [\"mint\", \"owner\"], idField: \"address\" },\n * });\n *\n * // Export the table for Drizzle migrations\n * export const tokenAccountsTable = tokenAccounts.table;\n * ```\n */\n\nimport type { SchemaDefinition } from \"../schema/types\";\nimport { buildDrizzleTable } from \"../schema/table\";\nimport type { AccountStreamDefinition, AccountStream } from \"./types\";\n\n// ============================================================\n// Utilities\n// ============================================================\n\nfunction pascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\n// ============================================================\n// Main Export\n// ============================================================\n\n/**\n * Define an account stream for indexing on-chain account state.\n *\n * @param definition - Stream definition with schema, ownerProgram, and parse function\n * @returns A compiled account stream ready for use with the indexer\n */\nexport function defineAccountStream<TSchema extends SchemaDefinition>(\n definition: AccountStreamDefinition<TSchema>\n): AccountStream<TSchema> {\n // Validate that either ownerProgram or ownerProgramFactory is provided\n if (!definition.ownerProgram && !definition.ownerProgramFactory) {\n throw new Error(`Stream \"${definition.name}\" must provide either ownerProgram or ownerProgramFactory`);\n }\n\n // Build table name (e.g., \"token-accounts\" -> \"token_accounts\")\n const tableName = definition.name.replace(/-/g, \"_\");\n\n // Build Drizzle table from schema\n const table = buildDrizzleTable(tableName, definition.schema);\n\n // Lazy ownerProgram resolution (cached after first call)\n let cachedOwnerProgram: Uint8Array | null = definition.ownerProgram ?? null;\n const getOwnerProgram = (): Uint8Array => {\n if (!cachedOwnerProgram) {\n if (definition.ownerProgramFactory) {\n cachedOwnerProgram = definition.ownerProgramFactory();\n } else {\n throw new Error(`Stream \"${definition.name}\" has no ownerProgram configured`);\n }\n }\n return cachedOwnerProgram;\n };\n\n return {\n name: definition.name,\n description: definition.description ?? `${pascalCase(definition.name)} accounts`,\n schema: definition.schema,\n getOwnerProgram,\n expectedSize: definition.expectedSize,\n dataSizes: definition.dataSizes,\n table,\n // Column accessors for Drizzle operators\n c: table as any,\n parse: definition.parse,\n api: definition.api,\n };\n}\n","/**\n * Account stream processor.\n *\n * Processes account state from @thru/replay and commits to the database\n * with slot-aware upserts and checkpointing.\n */\n\nimport { eq, sql } from \"drizzle-orm\";\nimport type { ChainClientFactory, ReplayLogger } from \"@thru/replay\";\nimport { createAccountsByOwnerReplay, AccountView } from \"@thru/replay\";\nimport { encodeAddress } from \"@thru/sdk/helpers\";\nimport type { DatabaseClient } from \"../schema/types\";\nimport { validateParsedData } from \"../schema/validation\";\nimport { getCheckpoint, updateCheckpoint } from \"../checkpoint\";\nimport type { AccountStream } from \"./types\";\nimport type { ProcessorStatusObserver } from \"../runtime/status\";\nimport { createScopedLogger } from \"../runtime/logger\";\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface AccountProcessorOptions {\n /** Factory to create fresh chain clients for reconnection */\n clientFactory: ChainClientFactory;\n /** Database client */\n db: DatabaseClient;\n /** Log level */\n logLevel?: \"debug\" | \"info\" | \"warn\" | \"error\";\n /** Structured logger for processor and replay lifecycle logs */\n logger?: ReplayLogger;\n /** Validate parse output with Zod (useful for development) */\n validateParse?: boolean;\n /** Runtime status observer */\n observer?: ProcessorStatusObserver;\n}\n\nexport interface AccountProcessorStats {\n /** Total accounts processed */\n accountsProcessed: number;\n /** Total accounts inserted/updated */\n accountsUpdated: number;\n /** Total accounts deleted */\n accountsDeleted: number;\n}\n\n// ============================================================\n// Processor\n// ============================================================\n\n/**\n * Run an account stream processor.\n *\n * Backfills all accounts via ListAccounts, then streams live updates.\n * Supports resumable indexing via checkpoint persistence.\n *\n * @param stream - The account stream to process\n * @param options - Processor configuration\n * @param abortSignal - Optional signal to stop processing\n * @returns Processor statistics\n */\nexport async function runAccountStreamProcessor(\n stream: AccountStream,\n options: AccountProcessorOptions,\n abortSignal?: AbortSignal\n): Promise<AccountProcessorStats> {\n const { clientFactory, db, logLevel = \"info\", logger: baseLogger, validateParse = false, observer } = options;\n const checkpointName = `account:${stream.name}`;\n\n const logger = createScopedLogger({\n logger: baseLogger,\n level: logLevel,\n prefix: `account-stream:${stream.name}`,\n bindings: {\n component: \"indexer-stream\",\n stream: stream.name,\n kind: \"account\",\n checkpoint_name: checkpointName,\n },\n });\n const log = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n msg: string,\n meta?: Record<string, unknown>\n ) => logger[level](msg, meta);\n\n const stats: AccountProcessorStats = {\n accountsProcessed: 0,\n accountsUpdated: 0,\n accountsDeleted: 0,\n };\n\n // Load checkpoint for resumable backfill\n const checkpoint = await getCheckpoint(db, checkpointName);\n const minUpdatedSlot = checkpoint?.slot;\n observer?.onStart?.({\n startSlot: minUpdatedSlot,\n checkpointSlot: checkpoint?.slot ?? null,\n });\n if (minUpdatedSlot) {\n log(\"info\", `Resuming from checkpoint: slot ${minUpdatedSlot}`);\n }\n\n log(\"info\", `Starting account stream: ${stream.description}`);\n if (stream.expectedSize) {\n log(\"info\", `Expected data size: ${stream.expectedSize} bytes`);\n }\n\n // Track highest slot seen for checkpoint persistence\n let lastProcessedSlot = minUpdatedSlot ?? 0n;\n\n try {\n // Use createAccountsByOwnerReplay for hybrid backfill + streaming\n const replay = createAccountsByOwnerReplay({\n clientFactory,\n owner: stream.getOwnerProgram(),\n view: AccountView.FULL,\n dataSizes: stream.dataSizes ?? (stream.expectedSize ? [stream.expectedSize] : undefined),\n minUpdatedSlot,\n logger,\n signal: abortSignal,\n onBackfillComplete: (highestSlot) => {\n log(\n \"info\",\n `Backfill complete. Highest slot: ${highestSlot}, accounts processed: ${stats.accountsProcessed}`\n );\n },\n });\n\n for await (const event of replay) {\n if (abortSignal?.aborted) {\n log(\"info\", \"Abort signal received, stopping\");\n break;\n }\n\n if (event.type === \"account\") {\n const account = event.account;\n stats.accountsProcessed++;\n observer?.onRecord?.({\n slot: account.slot,\n id: account.addressHex,\n });\n\n // Log first few accounts for debugging\n if (stats.accountsProcessed <= 3) {\n log(\n \"info\",\n `Account ${stats.accountsProcessed}: ${account.addressHex}, slot=${account.slot}, dataLen=${account.data.length}`\n );\n }\n\n const table = stream.table as any;\n const idField = stream.api?.idField ?? \"address\";\n\n // Handle account deletions before parsing — deleted accounts have\n // zeroed data so parse() would return null and the delete would be\n // silently skipped.\n if (account.isDelete) {\n log(\"debug\", `Account deleted: ${account.addressHex}`);\n const idValue = encodeAddress(account.address);\n try {\n await db.delete(stream.table).where(eq(table[idField], idValue));\n stats.accountsDeleted++;\n observer?.onCheckpoint?.({ slot: account.slot });\n log(\"info\", `Deleted row for account ${account.addressHex}`);\n if (account.slot > lastProcessedSlot) {\n lastProcessedSlot = account.slot;\n }\n } catch (err) {\n observer?.onError?.(\"commit\", err);\n log(\"error\", `Failed to delete account ${account.addressHex}: ${err}`);\n throw err;\n }\n continue;\n }\n\n // Parse using stream's parser\n let parsed;\n try {\n parsed = stream.parse(account);\n } catch (parseErr) {\n observer?.onParserError?.(parseErr);\n observer?.onError?.(\"parse\", parseErr);\n throw parseErr;\n }\n if (!parsed) {\n observer?.onParserNull?.();\n log(\n \"debug\",\n `Skipped account ${account.addressHex} - parser returned null (dataLen=${account.data.length})`\n );\n if (account.slot > lastProcessedSlot) {\n lastProcessedSlot = account.slot;\n }\n continue;\n }\n\n // Validate parse output if enabled\n if (validateParse) {\n const validation = validateParsedData(stream.schema, parsed, stream.name);\n if (!validation.success) {\n observer?.onParseValidationError?.(validation.error);\n log(\"error\", validation.error);\n continue; // Skip invalid accounts\n }\n }\n\n // Slot-aware upsert: only update if incoming slot >= existing slot\n\n let upserted = false;\n try {\n const upsertedRows = await db\n .insert(stream.table)\n .values(parsed)\n .onConflictDoUpdate({\n target: table[idField],\n set: parsed,\n where: sql`${table.slot} <= ${(parsed as any).slot}`,\n })\n .returning();\n\n upserted = upsertedRows.length > 0;\n if (upserted) {\n stats.accountsUpdated++;\n }\n\n if (upserted && stats.accountsUpdated <= 3) {\n log(\n \"info\",\n `Successfully inserted account ${stats.accountsUpdated}`\n );\n }\n } catch (err) {\n observer?.onError?.(\"commit\", err);\n log(\n \"error\",\n `Failed to upsert account ${account.addressHex}: ${err}`\n );\n throw err;\n }\n\n // Track highest slot for checkpoint\n if (upserted && account.slot > lastProcessedSlot) {\n lastProcessedSlot = account.slot;\n }\n\n // Progress logging\n if (stats.accountsProcessed % 100 === 0) {\n log(\n \"info\",\n `Processed ${stats.accountsProcessed} accounts, updated ${stats.accountsUpdated}`\n );\n }\n } else if (event.type === \"blockFinished\") {\n // Persist at block boundaries, but do not advance the checkpoint to\n // the block slot unless an account update was actually handled.\n const slot = event.block.slot;\n if (lastProcessedSlot > 0n) {\n await updateCheckpoint(db, checkpointName, lastProcessedSlot, null);\n observer?.onCheckpoint?.({ slot: lastProcessedSlot });\n log(\n \"debug\",\n `Block finished: slot ${slot}, checkpoint saved at account slot ${lastProcessedSlot}`\n );\n } else {\n log(\n \"debug\",\n `Block finished: slot ${slot}, no checkpoint yet (no accounts handled)`\n );\n }\n }\n }\n\n // Final checkpoint save\n if (lastProcessedSlot > 0n) {\n await updateCheckpoint(db, checkpointName, lastProcessedSlot, null);\n observer?.onCheckpoint?.({ slot: lastProcessedSlot });\n log(\"info\", `Final checkpoint saved: slot ${lastProcessedSlot}`);\n }\n } catch (err) {\n if (abortSignal?.aborted) {\n log(\"info\", \"Stream aborted\");\n } else {\n log(\n \"error\",\n `Stream error: ${err instanceof Error ? err.message : String(err)}`\n );\n throw err;\n }\n }\n\n log(\n \"info\",\n `Finished. Processed: ${stats.accountsProcessed}, Updated: ${stats.accountsUpdated}, Deleted: ${stats.accountsDeleted}`\n );\n\n return stats;\n}\n","/**\n * Runtime status and health types for the indexer supervisor.\n */\n\nexport type IndexerStreamKind = \"event\" | \"account\";\n\nexport type IndexerStreamState =\n | \"idle\"\n | \"starting\"\n | \"running\"\n | \"retrying\"\n | \"stopped\";\n\nexport type IndexerErrorPhase =\n | \"starting\"\n | \"backfill\"\n | \"live\"\n | \"parse\"\n | \"commit\"\n | \"filterBatch\"\n | \"onCommit\"\n | \"supervisor\";\n\nexport interface NormalizedIndexerError {\n name: string;\n message: string;\n code?: string | number;\n phase: IndexerErrorPhase;\n retryable: boolean;\n streamName: string;\n streamKind: IndexerStreamKind;\n startSlot?: string;\n checkpointSlot?: string;\n endpointLabel?: string;\n}\n\nexport interface IndexerStreamCounters {\n eventsReceived: number;\n parserNulls: number;\n parserErrors: number;\n parseValidationErrors: number;\n commitErrors: number;\n filterBatchErrors: number;\n onCommitErrors: number;\n recordsProcessed: number;\n batchesCommitted: number;\n}\n\nexport interface IndexerStreamStatus {\n name: string;\n kind: IndexerStreamKind;\n state: IndexerStreamState;\n checkpointSlot: string | null;\n lastProcessedSlot: string | null;\n lastEventAt: string | null;\n stale: boolean;\n restartCount: number;\n lastStartedAt: string | null;\n lastErrorAt: string | null;\n lastError: NormalizedIndexerError | null;\n counters: IndexerStreamCounters;\n}\n\nexport interface IndexerStatus {\n running: boolean;\n shutdownRequested: boolean;\n startedAt: string | null;\n uptimeMs: number;\n healthy: boolean;\n streams: IndexerStreamStatus[];\n}\n\nexport interface ProcessorStatusObserver {\n onStart?(info: {\n startSlot?: bigint;\n checkpointSlot?: bigint | null;\n }): void;\n onRecord?(info: {\n slot?: bigint | null;\n id?: string | null;\n }): void;\n onParserNull?(): void;\n onParserError?(error: unknown): void;\n onParseValidationError?(error: string): void;\n onBatchCommitted?(info: {\n slot: bigint;\n count: number;\n }): void;\n onCheckpoint?(info: {\n slot: bigint;\n }): void;\n onError?(phase: IndexerErrorPhase, error: unknown): void;\n}\n\nexport function emptyStreamCounters(): IndexerStreamCounters {\n return {\n eventsReceived: 0,\n parserNulls: 0,\n parserErrors: 0,\n parseValidationErrors: 0,\n commitErrors: 0,\n filterBatchErrors: 0,\n onCommitErrors: 0,\n recordsProcessed: 0,\n batchesCommitted: 0,\n };\n}\n\nexport function cloneStreamStatus(status: IndexerStreamStatus): IndexerStreamStatus {\n return {\n ...status,\n lastError: status.lastError ? { ...status.lastError } : null,\n counters: { ...status.counters },\n };\n}\n\nexport function normalizeIndexerError(input: {\n error: unknown;\n phase: IndexerErrorPhase;\n streamName: string;\n streamKind: IndexerStreamKind;\n startSlot?: bigint | null;\n checkpointSlot?: bigint | null;\n endpointLabel?: string;\n}): NormalizedIndexerError {\n const err = input.error;\n const maybeRecord = err && typeof err === \"object\" ? err as Record<string, unknown> : {};\n const name = err instanceof Error ? err.name : typeof maybeRecord.name === \"string\" ? maybeRecord.name : \"Error\";\n const message = err instanceof Error ? err.message : String(err);\n const code = typeof maybeRecord.code === \"string\" || typeof maybeRecord.code === \"number\"\n ? maybeRecord.code\n : undefined;\n const retryable = isRetryablePhase(input.phase);\n\n return {\n name,\n message,\n code,\n phase: input.phase,\n retryable,\n streamName: input.streamName,\n streamKind: input.streamKind,\n startSlot: input.startSlot === undefined || input.startSlot === null ? undefined : input.startSlot.toString(),\n checkpointSlot: input.checkpointSlot === undefined || input.checkpointSlot === null ? undefined : input.checkpointSlot.toString(),\n endpointLabel: input.endpointLabel,\n };\n}\n\nfunction isRetryablePhase(phase: IndexerErrorPhase): boolean {\n switch (phase) {\n case \"starting\":\n case \"backfill\":\n case \"live\":\n case \"commit\":\n case \"supervisor\":\n return true;\n case \"parse\":\n case \"filterBatch\":\n case \"onCommit\":\n return false;\n }\n}\n","/**\n * Indexer runtime class.\n *\n * Orchestrates running multiple event and account streams concurrently\n * with graceful shutdown support.\n *\n * @example\n * ```ts\n * import { Indexer } from \"@thru/indexer\";\n * import { ChainClient } from \"@thru/replay\";\n * import { transfers } from \"./streams/transfers\";\n * import { tokenAccounts } from \"./account-streams/token-accounts\";\n *\n * const indexer = new Indexer({\n * db,\n * clientFactory: () => new ChainClient({ baseUrl: RPC_URL }),\n * eventStreams: [transfers],\n * accountStreams: [tokenAccounts],\n * defaultStartSlot: 0n,\n * safetyMargin: 64,\n * });\n *\n * // Handle graceful shutdown\n * process.on(\"SIGINT\", () => indexer.stop());\n * process.on(\"SIGTERM\", () => indexer.stop());\n *\n * // Start indexing\n * await indexer.start();\n * ```\n */\n\nimport { sql } from \"drizzle-orm\";\nimport type { IndexerConfig } from \"./config\";\nimport { runEventStreamProcessor, type ProcessorStats } from \"../streams/processor\";\nimport { runAccountStreamProcessor, type AccountProcessorStats } from \"../accounts/processor\";\nimport {\n cloneStreamStatus,\n emptyStreamCounters,\n normalizeIndexerError,\n type IndexerStatus,\n type IndexerStreamKind,\n type IndexerStreamStatus,\n type ProcessorStatusObserver,\n} from \"./status\";\nimport { createScopedLogger } from \"./logger\";\nimport type { EventStream } from \"../streams/types\";\nimport type { AccountStream } from \"../accounts/types\";\nimport type { ReplayLogger } from \"@thru/replay\";\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface IndexerResult {\n /** Results from event stream processors */\n eventStreams: Array<{\n name: string;\n status: \"fulfilled\" | \"rejected\";\n result?: ProcessorStats;\n error?: Error;\n }>;\n /** Results from account stream processors */\n accountStreams: Array<{\n name: string;\n status: \"fulfilled\" | \"rejected\";\n result?: AccountProcessorStats;\n error?: Error;\n }>;\n}\n\n// ============================================================\n// Indexer Class\n// ============================================================\n\n/**\n * Indexer runtime that orchestrates event and account streams.\n */\nexport class Indexer {\n private config: IndexerConfig;\n private logger: ReplayLogger;\n private abortController: AbortController | null = null;\n private running = false;\n private shutdownRequested = false;\n private startedAtMs: number | null = null;\n private streamStatuses = new Map<string, IndexerStreamStatus>();\n private streamHealthStates = new Map<string, {\n unhealthy: boolean;\n unhealthySinceMs: number | null;\n }>();\n\n constructor(config: IndexerConfig) {\n this.config = {\n defaultStartSlot: 0n,\n safetyMargin: 64,\n pageSize: 512,\n logLevel: \"info\",\n supervisorInitialBackoffMs: 1000,\n supervisorMaxBackoffMs: 30000,\n streamStaleMs: 300000,\n ...config,\n };\n this.logger = createScopedLogger({\n logger: this.config.logger,\n level: this.config.logLevel,\n prefix: \"indexer\",\n bindings: { component: \"indexer-runtime\" },\n });\n\n this.initializeStreamStatuses();\n }\n\n /**\n * Check if the checkpoint table exists in the database.\n * Logs a warning if it doesn't exist (user may have forgotten to export it in schema).\n */\n private async checkCheckpointTable(): Promise<void> {\n try {\n // Try to query the checkpoint table\n await this.config.db.execute(\n sql`SELECT 1 FROM indexer_checkpoints LIMIT 1`\n );\n } catch (err) {\n // drizzle-orm >= 0.44 wraps driver errors in DrizzleQueryError;\n // the original DB message lives in .cause\n const message = err instanceof Error\n ? (err.cause instanceof Error ? err.cause.message : err.message)\n : String(err);\n // Check if error is about missing table\n if (message.includes(\"does not exist\") || message.includes(\"relation\")) {\n this.logger.warn(\n `Checkpoint table \"indexer_checkpoints\" not found.\nMake sure to export checkpointTable from your Drizzle schema:\n\n // db/schema.ts\n export { checkpointTable } from \"@thru/indexer\";\n\nThen run: pnpm drizzle-kit push (or generate + migrate)\n`\n );\n }\n // Re-throw so startup fails\n throw err;\n }\n }\n\n /**\n * Start the indexer.\n *\n * Runs all configured event and account streams concurrently.\n * Returns when all streams complete or when stop() is called.\n *\n * @returns Results from all stream processors\n */\n async start(): Promise<IndexerResult> {\n if (this.running) {\n throw new Error(\"Indexer is already running\");\n }\n\n // Check that checkpoint table exists before starting\n await this.checkCheckpointTable();\n\n this.running = true;\n this.shutdownRequested = false;\n this.startedAtMs = Date.now();\n this.abortController = new AbortController();\n this.initializeStreamStatuses();\n\n const {\n db,\n clientFactory,\n eventStreams = [],\n accountStreams = [],\n defaultStartSlot,\n safetyMargin,\n pageSize,\n logLevel,\n validateParse,\n endpointLabel,\n supervisorInitialBackoffMs = 1000,\n supervisorMaxBackoffMs = 30000,\n logger,\n } = this.config;\n\n this.logger.info(\"Starting indexer\", {\n event: \"indexer.started\",\n event_streams: eventStreams.map((stream) => stream.name),\n account_streams: accountStreams.map((stream) => stream.name),\n });\n\n try {\n const supervisorOptions = {\n endpointLabel,\n initialBackoffMs: supervisorInitialBackoffMs,\n maxBackoffMs: supervisorMaxBackoffMs,\n };\n\n const eventSupervisors = eventStreams.map((stream) =>\n this.runEventStreamSupervisor(stream, {\n clientFactory,\n db,\n defaultStartSlot: defaultStartSlot!,\n safetyMargin,\n pageSize,\n logLevel,\n logger,\n validateParse,\n }, supervisorOptions)\n );\n\n const accountSupervisors = accountStreams.map((stream) =>\n this.runAccountStreamSupervisor(stream, {\n clientFactory,\n db,\n logLevel,\n logger,\n validateParse,\n }, supervisorOptions)\n );\n\n await Promise.all([...eventSupervisors, ...accountSupervisors]);\n\n const result: IndexerResult = {\n eventStreams: eventStreams.map((stream) => this.resultForStream(stream.name)),\n accountStreams: accountStreams.map((stream) => this.resultForStream(stream.name)),\n };\n\n this.logger.info(\"All indexer streams stopped\", {\n event: \"indexer.stopped\",\n });\n return result;\n } finally {\n this.running = false;\n this.abortController = null;\n this.startedAtMs = null;\n }\n }\n\n /**\n * Stop the indexer gracefully.\n *\n * Signals all streams to finish their current batch and stop.\n * The start() promise will resolve once all streams have stopped.\n */\n stop(): void {\n if (!this.running || !this.abortController) {\n this.logger.info(\"Indexer is not running\", {\n event: \"indexer.stop.noop\",\n });\n return;\n }\n\n if (this.shutdownRequested) {\n this.logger.warn(\"Force shutting down indexer\", {\n event: \"indexer.force_shutdown\",\n });\n process.exit(1);\n }\n\n this.logger.info(\"Indexer shutdown requested\", {\n event: \"indexer.shutdown_requested\",\n });\n this.shutdownRequested = true;\n this.abortController.abort();\n }\n\n /**\n * Check if the indexer is currently running.\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Get the current in-memory runtime status for every configured stream.\n */\n getStatus(): IndexerStatus {\n const now = Date.now();\n const streams = Array.from(this.streamStatuses.values()).map((status) => {\n const stream = cloneStreamStatus(status);\n stream.stale = this.isStreamStale(stream, now);\n return stream;\n });\n const healthy =\n this.running &&\n !this.shutdownRequested &&\n streams.length > 0 &&\n streams.every((stream) => stream.state === \"running\" && !stream.stale);\n this.emitHealthTransitions(streams, now);\n\n return {\n running: this.running,\n shutdownRequested: this.shutdownRequested,\n startedAt: this.startedAtMs === null ? null : new Date(this.startedAtMs).toISOString(),\n uptimeMs: this.startedAtMs === null ? 0 : now - this.startedAtMs,\n healthy,\n streams,\n };\n }\n\n private initializeStreamStatuses(): void {\n this.streamStatuses = new Map();\n this.streamHealthStates = new Map();\n for (const stream of this.config.eventStreams ?? []) {\n this.streamStatuses.set(this.statusKey(\"event\", stream.name), this.createInitialStreamStatus(\"event\", stream.name));\n }\n for (const stream of this.config.accountStreams ?? []) {\n this.streamStatuses.set(this.statusKey(\"account\", stream.name), this.createInitialStreamStatus(\"account\", stream.name));\n }\n }\n\n private createInitialStreamStatus(kind: IndexerStreamKind, name: string): IndexerStreamStatus {\n return {\n name,\n kind,\n state: \"idle\",\n checkpointSlot: null,\n lastProcessedSlot: null,\n lastEventAt: null,\n stale: false,\n restartCount: 0,\n lastStartedAt: null,\n lastErrorAt: null,\n lastError: null,\n counters: emptyStreamCounters(),\n };\n }\n\n private statusKey(kind: IndexerStreamKind, name: string): string {\n return `${kind}:${name}`;\n }\n\n private statusFor(kind: IndexerStreamKind, name: string): IndexerStreamStatus {\n const key = this.statusKey(kind, name);\n let status = this.streamStatuses.get(key);\n if (!status) {\n status = this.createInitialStreamStatus(kind, name);\n this.streamStatuses.set(key, status);\n }\n return status;\n }\n\n private resultForStream(name: string): {\n name: string;\n status: \"fulfilled\" | \"rejected\";\n error?: Error;\n } {\n return {\n name,\n status: \"fulfilled\",\n };\n }\n\n private setStreamState(\n status: IndexerStreamStatus,\n nextState: IndexerStreamStatus[\"state\"],\n meta: Record<string, unknown> = {}\n ): void {\n const previousState = status.state;\n status.state = nextState;\n if (previousState === nextState) {\n return;\n }\n\n this.logger.info(\"Indexer stream state changed\", {\n event: \"indexer.stream.state_changed\",\n stream: status.name,\n kind: status.kind,\n previous_state: previousState,\n next_state: nextState,\n restart_count: status.restartCount,\n ...meta,\n });\n }\n\n private streamLogFields(stream: IndexerStreamStatus): Record<string, unknown> {\n return {\n stream: stream.name,\n kind: stream.kind,\n state: stream.state,\n stale: stream.stale,\n checkpoint_slot: stream.checkpointSlot,\n last_processed_slot: stream.lastProcessedSlot,\n last_event_at: stream.lastEventAt,\n restart_count: stream.restartCount,\n last_error_at: stream.lastErrorAt,\n last_error: stream.lastError,\n };\n }\n\n private emitHealthTransitions(streams: IndexerStreamStatus[], nowMs: number): void {\n if (!this.running || this.shutdownRequested) {\n return;\n }\n\n for (const stream of streams) {\n const key = this.statusKey(stream.kind, stream.name);\n const unhealthy = stream.state !== \"running\" || stream.stale;\n const previous = this.streamHealthStates.get(key);\n const initialStarting =\n !previous &&\n stream.state === \"starting\" &&\n stream.restartCount === 0 &&\n !stream.lastError;\n\n if (initialStarting) {\n this.streamHealthStates.set(key, {\n unhealthy: false,\n unhealthySinceMs: null,\n });\n continue;\n }\n\n if (unhealthy && previous?.unhealthy !== true) {\n this.streamHealthStates.set(key, {\n unhealthy: true,\n unhealthySinceMs: nowMs,\n });\n this.logger.warn(\"Indexer stream unhealthy\", {\n event: \"indexer.stream.unhealthy\",\n reason: stream.stale ? \"stale\" : \"state\",\n ...this.streamLogFields(stream),\n });\n continue;\n }\n\n if (!unhealthy && previous?.unhealthy === true) {\n this.streamHealthStates.set(key, {\n unhealthy: false,\n unhealthySinceMs: null,\n });\n this.logger.info(\"Indexer stream recovered\", {\n event: \"indexer.stream.recovered\",\n unhealthy_duration_ms: previous.unhealthySinceMs === null\n ? null\n : nowMs - previous.unhealthySinceMs,\n ...this.streamLogFields(stream),\n });\n continue;\n }\n\n if (!previous) {\n this.streamHealthStates.set(key, {\n unhealthy,\n unhealthySinceMs: unhealthy ? nowMs : null,\n });\n }\n }\n }\n\n private createObserver(kind: IndexerStreamKind, name: string, endpointLabel?: string): ProcessorStatusObserver {\n const status = this.statusFor(kind, name);\n let startSlot: bigint | null = null;\n let checkpointSlot: bigint | null = null;\n\n return {\n onStart: (info) => {\n startSlot = info.startSlot ?? null;\n checkpointSlot = info.checkpointSlot ?? null;\n this.setStreamState(status, \"running\", {\n start_slot: startSlot?.toString(),\n checkpoint_slot: checkpointSlot?.toString() ?? null,\n });\n status.checkpointSlot = checkpointSlot === null ? null : checkpointSlot.toString();\n status.lastStartedAt = new Date().toISOString();\n },\n onRecord: (info) => {\n status.counters.eventsReceived++;\n status.lastEventAt = new Date().toISOString();\n if (info.slot !== undefined && info.slot !== null) {\n status.lastProcessedSlot = info.slot.toString();\n }\n },\n onParserNull: () => {\n status.counters.parserNulls++;\n },\n onParserError: () => {\n status.counters.parserErrors++;\n },\n onParseValidationError: () => {\n status.counters.parseValidationErrors++;\n },\n onBatchCommitted: (info) => {\n status.counters.batchesCommitted++;\n status.counters.recordsProcessed += info.count;\n status.lastProcessedSlot = info.slot.toString();\n status.lastEventAt = new Date().toISOString();\n },\n onCheckpoint: (info) => {\n status.checkpointSlot = info.slot.toString();\n status.lastProcessedSlot = info.slot.toString();\n },\n onError: (phase, error) => {\n if (phase === \"commit\") status.counters.commitErrors++;\n if (phase === \"filterBatch\") status.counters.filterBatchErrors++;\n if (phase === \"onCommit\") status.counters.onCommitErrors++;\n status.lastErrorAt = new Date().toISOString();\n status.lastError = normalizeIndexerError({\n error,\n phase,\n streamName: name,\n streamKind: kind,\n startSlot,\n checkpointSlot,\n endpointLabel,\n });\n },\n };\n }\n\n private async runEventStreamSupervisor(\n stream: EventStream,\n processorOptions: Omit<Parameters<typeof runEventStreamProcessor>[1], \"observer\">,\n supervisorOptions: { endpointLabel?: string; initialBackoffMs: number; maxBackoffMs: number }\n ): Promise<void> {\n await this.runStreamSupervisor(\"event\", stream.name, supervisorOptions, async (observer) => {\n const result = await runEventStreamProcessor(\n stream,\n { ...processorOptions, observer },\n this.abortController!.signal\n );\n return `processed ${result.eventsProcessed} event(s) in ${result.batchesCommitted} batch(es)`;\n });\n }\n\n private async runAccountStreamSupervisor(\n stream: AccountStream,\n processorOptions: Omit<Parameters<typeof runAccountStreamProcessor>[1], \"observer\">,\n supervisorOptions: { endpointLabel?: string; initialBackoffMs: number; maxBackoffMs: number }\n ): Promise<void> {\n await this.runStreamSupervisor(\"account\", stream.name, supervisorOptions, async (observer) => {\n const result = await runAccountStreamProcessor(\n stream,\n { ...processorOptions, observer },\n this.abortController!.signal\n );\n return `processed ${result.accountsProcessed} account event(s), updated ${result.accountsUpdated}, deleted ${result.accountsDeleted}`;\n });\n }\n\n private async runStreamSupervisor(\n kind: IndexerStreamKind,\n name: string,\n options: { endpointLabel?: string; initialBackoffMs: number; maxBackoffMs: number },\n runOnce: (observer: ProcessorStatusObserver) => Promise<string>\n ): Promise<void> {\n let attempt = 0;\n const status = this.statusFor(kind, name);\n\n while (!this.abortController?.signal.aborted) {\n const observer = this.createObserver(kind, name, options.endpointLabel);\n const runStartedAtMs = Date.now();\n this.setStreamState(status, attempt === 0 ? \"starting\" : \"retrying\", {\n attempt,\n });\n status.lastStartedAt = new Date(runStartedAtMs).toISOString();\n\n try {\n const summary = await runOnce(observer);\n if (this.abortController?.signal.aborted) {\n this.setStreamState(status, \"stopped\", { summary });\n return;\n }\n\n throw new Error(`${kind} stream \"${name}\" completed unexpectedly: ${summary}`);\n } catch (error) {\n if (this.abortController?.signal.aborted) {\n this.setStreamState(status, \"stopped\");\n return;\n }\n\n status.restartCount++;\n this.setStreamState(status, \"retrying\", {\n restart_count: status.restartCount,\n });\n status.lastErrorAt = new Date().toISOString();\n if (!status.lastError || status.lastError.phase === \"supervisor\") {\n status.lastError = normalizeIndexerError({\n error,\n phase: \"supervisor\",\n streamName: name,\n streamKind: kind,\n endpointLabel: options.endpointLabel,\n });\n }\n\n if (Date.now() - runStartedAtMs >= options.maxBackoffMs) {\n attempt = 0;\n }\n\n const backoffMs = this.supervisorBackoffMs(attempt, options.initialBackoffMs, options.maxBackoffMs);\n this.logger.warn(\"Indexer stream supervisor restarting\", {\n event: \"indexer.stream.supervisor_restart\",\n stream: name,\n kind,\n backoff_ms: backoffMs,\n attempt: attempt + 1,\n restart_count: status.restartCount,\n error,\n last_error: status.lastError,\n });\n attempt++;\n await this.delay(backoffMs, this.abortController!.signal);\n }\n }\n\n this.setStreamState(status, \"stopped\");\n }\n\n private supervisorBackoffMs(attempt: number, initialMs: number, maxMs: number): number {\n const base = Math.min(maxMs, initialMs * Math.pow(2, attempt));\n const jitter = Math.floor(base * 0.2 * Math.random());\n return base + jitter;\n }\n\n private isStreamStale(stream: IndexerStreamStatus, nowMs: number): boolean {\n const staleMs = this.config.streamStaleMs ?? 300000;\n if (staleMs <= 0 || stream.state !== \"running\") {\n return false;\n }\n\n const activityAt = stream.lastEventAt ?? stream.lastStartedAt;\n if (!activityAt) {\n return true;\n }\n\n const activityMs = Date.parse(activityAt);\n return !Number.isFinite(activityMs) || nowMs - activityMs > staleMs;\n }\n\n private delay(ms: number, signal: AbortSignal): Promise<void> {\n if (ms <= 0 || signal.aborted) return Promise.resolve();\n return new Promise((resolve) => {\n const onAbort = () => {\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n timer.unref?.();\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/schema/builder.ts","../src/schema/table.ts","../src/schema/validation.ts","../src/streams/define.ts","../src/checkpoint/table.ts","../src/checkpoint/repository.ts","../src/checkpoint/index.ts","../src/runtime/logger.ts","../src/streams/processor.ts","../src/accounts/define.ts","../src/accounts/processor.ts","../src/runtime/status.ts","../src/runtime/indexer.ts"],"names":["text","bigint","integer","boolean","timestamp","index","pgTable","z","eq","replay","createEventReplay","pascalCase","createAccountsByOwnerReplay","AccountView","encodeAddress","sql"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Fluent column builder API for defining schemas.\n * Exports a global `t` object for concise schema definitions.\n *\n * @example\n * ```ts\n * import { t } from \"@thru/indexer\";\n *\n * const schema = {\n * id: t.text().primaryKey(),\n * slot: t.bigint().notNull().index(),\n * amount: t.bigint().notNull(),\n * timestamp: t.timestamp(),\n * };\n * ```\n */\n\nimport type { PgTableWithColumns } from \"drizzle-orm/pg-core\";\nimport type { ColumnDef, ColumnType } from \"./types\";\n\n// ============================================================\n// Column Definition Implementation\n// ============================================================\n\ninterface ColumnState<T> {\n _type: T;\n _columnType: ColumnType;\n _nullable: boolean;\n _indexed: boolean;\n _unique: boolean;\n _primary: boolean;\n _default?: T;\n _defaultNow?: boolean;\n _references?: { table: PgTableWithColumns<any>; column: string };\n}\n\n/**\n * Create a builder object from state with the given nullability type parameter.\n */\nfunction createBuilder<T, TNull extends boolean>(\n state: ColumnState<T>\n): ColumnDef<T, TNull> {\n const builder: ColumnDef<T, TNull> = {\n get _type() { return state._type; },\n get _columnType() { return state._columnType; },\n get _nullable() { return state._nullable as TNull; },\n get _indexed() { return state._indexed; },\n get _unique() { return state._unique; },\n get _primary() { return state._primary; },\n get _default() { return state._default; },\n get _defaultNow() { return state._defaultNow; },\n get _references() { return state._references; },\n\n notNull(): ColumnDef<T, false> {\n state._nullable = false;\n return createBuilder<T, false>(state);\n },\n\n index(): ColumnDef<T, TNull> {\n state._indexed = true;\n return builder;\n },\n\n unique(): ColumnDef<T, TNull> {\n state._unique = true;\n return builder;\n },\n\n primaryKey(): ColumnDef<T, false> {\n state._primary = true;\n state._nullable = false;\n return createBuilder<T, false>(state);\n },\n\n default(value: T): ColumnDef<T, TNull> {\n state._default = value;\n return builder;\n },\n\n defaultNow(): ColumnDef<T, TNull> {\n state._defaultNow = true;\n return builder;\n },\n\n references<TTable extends PgTableWithColumns<any>>(\n table: TTable | (() => TTable),\n column: keyof TTable[\"_\"][\"columns\"]\n ): ColumnDef<T, TNull> {\n const resolvedTable = typeof table === \"function\" ? table() : table;\n state._references = { table: resolvedTable, column: column as string };\n return builder;\n },\n };\n\n return builder;\n}\n\n/**\n * Creates a column definition with proper type tracking.\n */\nfunction createColumnDef<T>(type: ColumnType): ColumnDef<T, true> {\n const state: ColumnState<T> = {\n _type: undefined as T,\n _columnType: type,\n _nullable: true,\n _indexed: false,\n _unique: false,\n _primary: false,\n _default: undefined,\n _defaultNow: false,\n _references: undefined,\n };\n\n return createBuilder<T, true>(state);\n}\n\n// ============================================================\n// Column Builder Interface\n// ============================================================\n\n/**\n * Interface for the column builder.\n * Each method creates a new column definition of the appropriate type.\n */\nexport interface ColumnBuilder {\n /** Text column (varchar) */\n text(): ColumnDef<string, true>;\n /** BigInt column (64-bit integer) - use for slots, amounts */\n bigint(): ColumnDef<bigint, true>;\n /** Integer column (32-bit) */\n integer(): ColumnDef<number, true>;\n /** Boolean column */\n boolean(): ColumnDef<boolean, true>;\n /** Timestamp column with timezone */\n timestamp(): ColumnDef<Date, true>;\n}\n\n// ============================================================\n// Global Column Builder\n// ============================================================\n\n/**\n * Global column builder for defining schemas.\n *\n * @example\n * ```ts\n * const schema = {\n * id: t.text().primaryKey(),\n * slot: t.bigint().notNull().index(),\n * name: t.text(),\n * active: t.boolean().notNull().default(true),\n * createdAt: t.timestamp().notNull().defaultNow(),\n * };\n * ```\n */\nexport const t: ColumnBuilder = {\n text: () => createColumnDef<string>(\"text\"),\n bigint: () => createColumnDef<bigint>(\"bigint\"),\n integer: () => createColumnDef<number>(\"integer\"),\n boolean: () => createColumnDef<boolean>(\"boolean\"),\n timestamp: () => createColumnDef<Date>(\"timestamp\"),\n};\n\n/**\n * Alternative export for the column builder.\n * Same as `t` but with a more descriptive name.\n */\nexport const columnBuilder = t;\n","/**\n * Build Drizzle tables from schema definitions.\n */\n\nimport {\n pgTable,\n text,\n bigint,\n integer,\n boolean,\n timestamp,\n index,\n type PgTableWithColumns,\n type PgColumnBuilderBase,\n} from \"drizzle-orm/pg-core\";\nimport type { AnyColumnDef, ColumnType, SchemaDefinition } from \"./types\";\n\n// ============================================================\n// Internal Types\n// ============================================================\n\ninterface ColumnDefInternal {\n _type: unknown;\n _columnType: ColumnType;\n _nullable: boolean;\n _indexed: boolean;\n _unique: boolean;\n _primary: boolean;\n _default?: unknown;\n _defaultNow?: boolean;\n _references?: { table: PgTableWithColumns<any>; column: string };\n}\n\n// ============================================================\n// Utilities\n// ============================================================\n\n/**\n * Convert camelCase to snake_case for database column names.\n */\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n// ============================================================\n// Table Builder\n// ============================================================\n\n/**\n * Build a Drizzle pgTable from a schema definition object.\n *\n * @param tableName - The database table name\n * @param schema - Schema definition object with column definitions\n * @returns A Drizzle table with proper types\n *\n * @example\n * ```ts\n * const schema = {\n * id: t.text().primaryKey(),\n * slot: t.bigint().notNull().index(),\n * };\n *\n * const table = buildDrizzleTable(\"my_events\", schema);\n * ```\n */\nexport function buildDrizzleTable<TSchema extends SchemaDefinition>(\n tableName: string,\n schema: TSchema\n): PgTableWithColumns<any> {\n // Build column definitions\n const columns: Record<string, PgColumnBuilderBase> = {};\n const indices: Array<(table: any) => any> = [];\n\n for (const [name, def] of Object.entries(schema)) {\n const internal = def as ColumnDefInternal;\n const snakeName = camelToSnake(name);\n\n // Create the base column\n let col: PgColumnBuilderBase;\n switch (internal._columnType) {\n case \"text\":\n col = text(snakeName);\n break;\n case \"bigint\":\n col = bigint(snakeName, { mode: \"bigint\" });\n break;\n case \"integer\":\n col = integer(snakeName);\n break;\n case \"boolean\":\n col = boolean(snakeName);\n break;\n case \"timestamp\":\n col = timestamp(snakeName, { withTimezone: true });\n break;\n default:\n throw new Error(`Unknown column type: ${internal._columnType}`);\n }\n\n // Apply modifiers\n if (internal._primary) {\n col = (col as any).primaryKey();\n }\n if (internal._unique) {\n col = (col as any).unique();\n }\n if (!internal._nullable) {\n col = (col as any).notNull();\n }\n if (internal._defaultNow && internal._columnType === \"timestamp\") {\n col = (col as any).defaultNow();\n } else if (internal._default !== undefined) {\n col = (col as any).default(internal._default);\n }\n if (internal._references) {\n const refTable = internal._references.table;\n const refColumn = internal._references.column;\n col = (col as any).references(() => refTable[refColumn]);\n }\n\n columns[name] = col;\n\n // Track indices\n if (internal._indexed) {\n indices.push((table: any) =>\n index(`${tableName}_${snakeName}_idx`).on(table[name])\n );\n }\n }\n\n // Create the table\n if (indices.length > 0) {\n return pgTable(tableName, columns, (table) =>\n indices.map((fn) => fn(table))\n );\n }\n return pgTable(tableName, columns);\n}\n","/**\n * Runtime validation for parsed data.\n * Generates Zod schemas from column definitions for validation.\n */\n\nimport { z } from \"zod\";\nimport type { SchemaDefinition, AnyColumnDef } from \"./types\";\n\n/**\n * Generate a Zod schema from column definitions.\n * Used for runtime validation of parse output.\n */\nexport function generateZodSchema<TSchema extends SchemaDefinition>(\n schema: TSchema\n): z.ZodObject<any> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, col] of Object.entries(schema)) {\n const colDef = col as AnyColumnDef;\n let zodType: z.ZodTypeAny;\n\n // Map column type to Zod type\n switch (colDef._columnType) {\n case \"text\":\n zodType = z.string();\n break;\n case \"bigint\":\n zodType = z.bigint();\n break;\n case \"integer\":\n zodType = z.number().int();\n break;\n case \"boolean\":\n zodType = z.boolean();\n break;\n case \"timestamp\":\n zodType = z.date();\n break;\n default:\n zodType = z.unknown();\n }\n\n // Handle nullability\n if (colDef._nullable) {\n zodType = zodType.nullable();\n }\n\n shape[key] = zodType;\n }\n\n return z.object(shape);\n}\n\n/**\n * Validate parsed data against schema.\n * Returns validation result with detailed errors.\n */\nexport function validateParsedData<TSchema extends SchemaDefinition>(\n schema: TSchema,\n data: unknown,\n streamName: string\n): { success: true; data: unknown } | { success: false; error: string } {\n const zodSchema = generateZodSchema(schema);\n const result = zodSchema.safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data };\n }\n\n const errorMessages = result.error.issues\n .map((e) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\");\n\n return {\n success: false,\n error: `Stream \"${streamName}\" parse returned invalid data:\\n${errorMessages}`,\n };\n}\n","/**\n * Define an event stream for indexing blockchain events.\n *\n * Event streams index historical, immutable event data from the chain.\n * Each event is stored once and never updated.\n *\n * @example\n * ```ts\n * import { defineEventStream, t } from \"@thru/indexer\";\n * import { create } from \"@bufbuild/protobuf\";\n * import { FilterSchema, type Event } from \"@thru/replay\";\n *\n * export const transfers = defineEventStream({\n * name: \"transfers\",\n *\n * schema: {\n * id: t.text().primaryKey(),\n * slot: t.bigint().notNull().index(),\n * source: t.text().notNull().index(),\n * dest: t.text().notNull().index(),\n * amount: t.bigint().notNull(),\n * },\n *\n * filter: create(FilterSchema, {\n * expression: \"event.program.value == params.address\",\n * params: { address: ... },\n * }),\n *\n * parse: (event: Event) => {\n * if (!event.payload) return null;\n * return {\n * id: event.eventId,\n * slot: event.slot!,\n * source: decodeAddress(event.payload, 0),\n * dest: decodeAddress(event.payload, 32),\n * amount: decodeBigint(event.payload, 64),\n * };\n * },\n *\n * api: { filters: [\"source\", \"dest\"] },\n * });\n *\n * // Export the table for Drizzle migrations\n * export const transfersTable = transfers.table;\n * ```\n */\n\nimport type { Filter } from \"@thru/replay\";\nimport type { SchemaDefinition } from \"../schema/types\";\nimport { buildDrizzleTable } from \"../schema/table\";\nimport type { EventStreamDefinition, EventStream } from \"./types\";\n\n// ============================================================\n// Utilities\n// ============================================================\n\nfunction pascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\n// ============================================================\n// Main Export\n// ============================================================\n\n/**\n * Define an event stream for indexing blockchain events.\n *\n * @param definition - Stream definition with schema, filter, and parse function\n * @returns A compiled event stream ready for use with the indexer\n */\nexport function defineEventStream<TSchema extends SchemaDefinition>(\n definition: EventStreamDefinition<TSchema>\n): EventStream<TSchema> {\n // Validate that either filter or filterFactory is provided\n if (!definition.filter && !definition.filterFactory) {\n throw new Error(`Stream \"${definition.name}\" must provide either filter or filterFactory`);\n }\n\n // Build table name (e.g., \"transfers\" -> \"transfer_events\")\n const tableName = `${definition.name.replace(/s$/, \"\")}_events`;\n\n // Build Drizzle table from schema\n const table = buildDrizzleTable(tableName, definition.schema);\n\n // Lazy filter resolution (cached after first call)\n let cachedFilter: Filter | null = definition.filter ?? null;\n const getFilter = (): Filter => {\n if (!cachedFilter) {\n if (definition.filterFactory) {\n cachedFilter = definition.filterFactory();\n } else {\n throw new Error(`Stream \"${definition.name}\" has no filter configured`);\n }\n }\n return cachedFilter;\n };\n\n return {\n name: definition.name,\n description: definition.description ?? `${pascalCase(definition.name)} events`,\n schema: definition.schema,\n table,\n // Column accessors for Drizzle operators\n c: table as any,\n getFilter,\n parse: definition.parse,\n api: definition.api,\n filterBatch: definition.filterBatch,\n onCommit: definition.onCommit,\n };\n}\n","/**\n * Checkpoint table schema.\n *\n * Users should export this from their Drizzle schema for migrations.\n *\n * @example\n * ```ts\n * // db/schema.ts\n * import { checkpointTable } from \"@thru/indexer\";\n * export { checkpointTable };\n * ```\n */\n\nimport {\n pgTable,\n text,\n bigint,\n timestamp,\n} from \"drizzle-orm/pg-core\";\n\n/**\n * Per-stream checkpoint table.\n * Each stream has its own checkpoint keyed by stream name.\n *\n * This table should be included in your Drizzle migrations.\n */\nexport const checkpointTable = pgTable(\"indexer_checkpoints\", {\n /** Stream name (primary key) */\n streamName: text(\"stream_name\").primaryKey(),\n /** Last indexed slot number */\n lastIndexedSlot: bigint(\"last_indexed_slot\", { mode: \"bigint\" }).notNull(),\n /** Last event ID (for cursor-based resume) */\n lastEventId: text(\"last_event_id\"),\n /** When the checkpoint was last updated */\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .defaultNow()\n .notNull(),\n});\n\n/**\n * Checkpoint data structure.\n */\nexport interface Checkpoint {\n /** Last indexed slot number */\n slot: bigint;\n /** Last event ID (for cursor-based resume) */\n eventId: string | null;\n}\n","/**\n * Checkpoint repository for reading and updating stream checkpoints.\n */\n\nimport { eq } from \"drizzle-orm\";\nimport type { DatabaseClient } from \"../schema/types\";\nimport { checkpointTable, type Checkpoint } from \"./table\";\n\n/**\n * Get the checkpoint for a specific stream.\n * Returns null if no checkpoint exists yet.\n *\n * @param db - Database client\n * @param streamName - Name of the stream\n * @returns Checkpoint or null if not found\n */\nexport async function getCheckpoint(\n db: DatabaseClient,\n streamName: string\n): Promise<Checkpoint | null> {\n const [row] = await db\n .select()\n .from(checkpointTable)\n .where(eq(checkpointTable.streamName, streamName))\n .limit(1);\n\n if (!row) {\n return null;\n }\n\n return {\n slot: row.lastIndexedSlot,\n eventId: row.lastEventId,\n };\n}\n\n/**\n * Update the checkpoint for a specific stream.\n * Uses upsert to handle both insert and update cases.\n *\n * @param db - Database client (can be a transaction)\n * @param streamName - Name of the stream\n * @param slot - Last indexed slot number\n * @param eventId - Last event ID (optional)\n */\nexport async function updateCheckpoint(\n db: DatabaseClient,\n streamName: string,\n slot: bigint,\n eventId: string | null = null\n): Promise<void> {\n await db\n .insert(checkpointTable)\n .values({\n streamName,\n lastIndexedSlot: slot,\n lastEventId: eventId,\n updatedAt: new Date(),\n })\n .onConflictDoUpdate({\n target: checkpointTable.streamName,\n set: {\n lastIndexedSlot: slot,\n lastEventId: eventId,\n updatedAt: new Date(),\n },\n });\n}\n\n/**\n * Delete the checkpoint for a specific stream.\n * Use with caution - this will cause the stream to re-index from the start.\n *\n * @param db - Database client\n * @param streamName - Name of the stream\n */\nexport async function deleteCheckpoint(\n db: DatabaseClient,\n streamName: string\n): Promise<void> {\n await db\n .delete(checkpointTable)\n .where(eq(checkpointTable.streamName, streamName));\n}\n\n/**\n * Get all checkpoints.\n * Useful for monitoring and debugging.\n *\n * @param db - Database client\n * @returns Array of checkpoints with stream names\n */\nexport async function getAllCheckpoints(\n db: DatabaseClient\n): Promise<Array<{ streamName: string; checkpoint: Checkpoint }>> {\n const rows = await db.select().from(checkpointTable);\n\n return rows.map((row) => ({\n streamName: row.streamName,\n checkpoint: {\n slot: row.lastIndexedSlot,\n eventId: row.lastEventId,\n },\n }));\n}\n","/**\n * Checkpoint module exports.\n */\n\nexport { checkpointTable, type Checkpoint } from \"./table\";\nexport {\n getCheckpoint,\n updateCheckpoint,\n deleteCheckpoint,\n getAllCheckpoints,\n} from \"./repository\";\n\nimport { checkpointTable } from \"./table\";\nimport type { EventStream } from \"../streams/types\";\nimport type { AccountStream } from \"../accounts/types\";\nimport type { PgTableWithColumns } from \"drizzle-orm/pg-core\";\n\n/**\n * Get all tables that need to be exported for Drizzle migrations.\n *\n * This helper collects the checkpoint table and all stream tables\n * into a single object for easy export in your schema file.\n *\n * @example\n * ```ts\n * // db/schema.ts\n * import { getSchemaExports } from \"@thru/indexer\";\n * import transfers from \"../streams/transfers\";\n * import tokenAccounts from \"../account-streams/token-accounts\";\n *\n * export const {\n * checkpointTable,\n * transfersTable,\n * tokenAccountsTable,\n * } = getSchemaExports({\n * eventStreams: [transfers],\n * accountStreams: [tokenAccounts],\n * tableNames: {\n * transfers: \"transfersTable\",\n * \"token-accounts\": \"tokenAccountsTable\",\n * },\n * });\n * ```\n */\nexport function getSchemaExports(config: {\n eventStreams?: EventStream<any>[];\n accountStreams?: AccountStream<any>[];\n tableNames?: Record<string, string>;\n}): Record<string, PgTableWithColumns<any>> {\n const { eventStreams = [], accountStreams = [], tableNames = {} } = config;\n\n const exports: Record<string, PgTableWithColumns<any>> = {\n checkpointTable,\n };\n\n for (const stream of eventStreams) {\n const exportName = tableNames[stream.name] ?? `${stream.name}Table`;\n exports[exportName] = stream.table as PgTableWithColumns<any>;\n }\n\n for (const stream of accountStreams) {\n const exportName = tableNames[stream.name] ?? `${stream.name.replace(/-/g, \"\")}Table`;\n exports[exportName] = stream.table as PgTableWithColumns<any>;\n }\n\n return exports;\n}\n","import type { ReplayLogger } from \"@thru/replay\";\n\nexport type IndexerLogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: IndexerLogLevel[] = [\"debug\", \"info\", \"warn\", \"error\"];\n\nfunction shouldLog(level: IndexerLogLevel, minimum: IndexerLogLevel): boolean {\n return LEVELS.indexOf(level) >= LEVELS.indexOf(minimum);\n}\n\nfunction writeConsole(\n prefix: string,\n level: IndexerLogLevel,\n message: string,\n meta?: Record<string, unknown>\n): void {\n const text = `[${prefix}] ${message}`;\n if (meta && Object.keys(meta).length > 0) {\n if (level === \"error\") {\n console.error(text, meta);\n } else if (level === \"warn\") {\n console.warn(text, meta);\n } else {\n console.log(text, meta);\n }\n return;\n }\n\n if (level === \"error\") {\n console.error(text);\n } else if (level === \"warn\") {\n console.warn(text);\n } else {\n console.log(text);\n }\n}\n\nexport function createScopedLogger(options: {\n logger?: ReplayLogger;\n level?: IndexerLogLevel;\n prefix: string;\n bindings?: Record<string, unknown>;\n}): ReplayLogger {\n const minimum = options.level ?? \"info\";\n const bindings = options.bindings ?? {};\n\n const log = (\n level: IndexerLogLevel,\n message: string,\n meta?: Record<string, unknown>\n ) => {\n if (!shouldLog(level, minimum)) {\n return;\n }\n\n const hasMeta = meta !== undefined && Object.keys(meta).length > 0;\n const fields = { ...bindings, ...(meta ?? {}) };\n if (options.logger) {\n options.logger[level](message, fields);\n } else {\n writeConsole(options.prefix, level, message, hasMeta ? fields : undefined);\n }\n };\n\n return {\n debug: (message, meta) => log(\"debug\", message, meta),\n info: (message, meta) => log(\"info\", message, meta),\n warn: (message, meta) => log(\"warn\", message, meta),\n error: (message, meta) => log(\"error\", message, meta),\n };\n}\n","/**\n * Event stream processor.\n *\n * Processes events from @thru/replay and commits them to the database\n * with batching and checkpointing.\n */\n\nimport type { ChainClientFactory, ReplayLogger } from \"@thru/replay\";\nimport { createEventReplay } from \"@thru/replay\";\nimport type { PgTable } from \"drizzle-orm/pg-core\";\nimport type { DatabaseClient } from \"../schema/types\";\nimport { validateParsedData } from \"../schema/validation\";\nimport { getCheckpoint, updateCheckpoint } from \"../checkpoint\";\nimport type { EventStream } from \"./types\";\nimport type { StreamBatch } from \"../types\";\nimport type { ProcessorStatusObserver } from \"../runtime/status\";\nimport { createScopedLogger } from \"../runtime/logger\";\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface ProcessorOptions {\n /** Factory to create fresh chain clients for reconnection */\n clientFactory: ChainClientFactory;\n /** Database client */\n db: DatabaseClient;\n /** Start slot if no checkpoint exists */\n defaultStartSlot: bigint;\n /** Safety margin for finality (in slots) */\n safetyMargin?: number;\n /** Page size for fetching events */\n pageSize?: number;\n /** Log level */\n logLevel?: \"debug\" | \"info\" | \"warn\" | \"error\";\n /** Structured logger for processor and replay lifecycle logs */\n logger?: ReplayLogger;\n /** Validate parse output with Zod (useful for development) */\n validateParse?: boolean;\n /** Runtime status observer */\n observer?: ProcessorStatusObserver;\n}\n\nexport interface ProcessorStats {\n /** Total events processed */\n eventsProcessed: number;\n /** Total batches committed */\n batchesCommitted: number;\n /** Last slot processed */\n lastSlot: bigint | null;\n}\n\n// ============================================================\n// Batcher\n// ============================================================\n\n/**\n * Generic batcher that collects events by slot and flushes on slot change\n * or when thresholds are reached.\n */\nclass StreamBatcher {\n private currentSlot: bigint | null = null;\n private pendingEvents: unknown[] = [];\n private lastFlushTime = Date.now();\n private maxPendingCount = 100;\n private maxPendingMs = 5000;\n\n addEvent(event: unknown, slot: bigint): StreamBatch | null {\n // If slot changed or thresholds reached, flush pending\n if (this.shouldFlush(slot)) {\n const batch = this.flush();\n this.currentSlot = slot;\n this.pendingEvents = [event];\n return batch;\n }\n\n this.currentSlot = slot;\n this.pendingEvents.push(event);\n return null;\n }\n\n private shouldFlush(newSlot: bigint): boolean {\n if (this.pendingEvents.length === 0) return false;\n if (this.currentSlot !== null && newSlot !== this.currentSlot) return true;\n if (this.pendingEvents.length >= this.maxPendingCount) return true;\n if (Date.now() - this.lastFlushTime >= this.maxPendingMs) return true;\n return false;\n }\n\n flush(): StreamBatch | null {\n if (this.pendingEvents.length === 0 || this.currentSlot === null) {\n return null;\n }\n const batch = {\n slot: this.currentSlot,\n events: this.pendingEvents,\n };\n this.pendingEvents = [];\n this.lastFlushTime = Date.now();\n return batch;\n }\n\n getPendingCount(): number {\n return this.pendingEvents.length;\n }\n\n /**\n * Flush if the timeout has elapsed since last flush.\n * Called by background timer to ensure events don't sit in buffer indefinitely.\n */\n flushIfStale(): StreamBatch | null {\n if (\n this.pendingEvents.length > 0 &&\n Date.now() - this.lastFlushTime >= this.maxPendingMs\n ) {\n return this.flush();\n }\n return null;\n }\n}\n\n// ============================================================\n// Processor\n// ============================================================\n\n/**\n * Run an event stream processor.\n *\n * Fetches events from the chain using @thru/replay, parses them,\n * batches by slot, and commits to the database with checkpointing.\n *\n * @param stream - The event stream to process\n * @param options - Processor configuration\n * @param abortSignal - Optional signal to stop processing\n * @returns Processor statistics\n */\nexport async function runEventStreamProcessor(\n stream: EventStream,\n options: ProcessorOptions,\n abortSignal?: AbortSignal\n): Promise<ProcessorStats> {\n const {\n clientFactory,\n db,\n defaultStartSlot,\n safetyMargin = 64,\n pageSize = 512,\n logLevel = \"info\",\n logger: baseLogger,\n validateParse = false,\n observer,\n } = options;\n\n const logger = createScopedLogger({\n logger: baseLogger,\n level: logLevel,\n prefix: stream.name,\n bindings: {\n component: \"indexer-stream\",\n stream: stream.name,\n kind: \"event\",\n },\n });\n const log = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n msg: string,\n meta?: Record<string, unknown>\n ) => logger[level](msg, meta);\n\n log(\"info\", `Starting stream processor: ${stream.description}`);\n\n // Get checkpoint for this stream\n const checkpoint = await getCheckpoint(db, stream.name);\n // Resume from the checkpoint slot rather than slot + 1. Checkpoints store\n // lastEventId, but this processor only filters by slot; replaying the\n // checkpoint slot and relying on idempotent inserts avoids skipping\n // unprocessed events from the same slot after partial commits.\n const startSlot = checkpoint ? checkpoint.slot : defaultStartSlot;\n observer?.onStart?.({\n startSlot,\n checkpointSlot: checkpoint?.slot ?? null,\n });\n\n log(\n \"info\",\n `Starting from slot ${startSlot}${checkpoint ? \" (resuming)\" : \" (fresh start)\"}`\n );\n\n // Create replay stream with factory for robust reconnection\n const replay = createEventReplay({\n clientFactory,\n startSlot,\n resumeAfter: checkpoint?.eventId\n ? { slot: checkpoint.slot, eventId: checkpoint.eventId }\n : undefined,\n safetyMargin: BigInt(safetyMargin),\n pageSize,\n filter: stream.getFilter(),\n logger,\n resubscribeOnEnd: true,\n signal: abortSignal,\n });\n\n const batcher = new StreamBatcher();\n const stats: ProcessorStats = {\n eventsProcessed: 0,\n batchesCommitted: 0,\n lastSlot: null,\n };\n\n let lastLogTime = Date.now();\n let eventsReceivedSinceLastLog = 0;\n\n // Commit a batch to the database\n const commitBatch = async (batch: StreamBatch): Promise<void> => {\n const lastSeenEvent = (batch.events as Record<string, unknown>[])[\n batch.events.length - 1\n ] as { id?: string } | undefined;\n const lastSeenEventId = lastSeenEvent?.id ?? null;\n let eventsToCommit = batch.events as Record<string, unknown>[];\n\n // Apply filterBatch hook if defined\n if (stream.filterBatch) {\n try {\n eventsToCommit = (await stream.filterBatch(\n eventsToCommit as any,\n { db }\n )) as any;\n if (eventsToCommit.length === 0) {\n log(\n \"debug\",\n `All ${batch.events.length} events filtered out at slot ${batch.slot}`\n );\n await updateCheckpoint(db, stream.name, batch.slot, lastSeenEventId);\n stats.lastSlot = batch.slot;\n return;\n }\n if (eventsToCommit.length < batch.events.length) {\n log(\n \"debug\",\n `Filtered ${batch.events.length - eventsToCommit.length} of ${batch.events.length} events at slot ${batch.slot}`\n );\n }\n } catch (filterErr) {\n observer?.onError?.(\"filterBatch\", filterErr);\n log(\n \"error\",\n `filterBatch hook failed: ${filterErr instanceof Error ? filterErr.message : String(filterErr)}`\n );\n throw filterErr;\n }\n }\n\n const lastEventToCommit = eventsToCommit[eventsToCommit.length - 1] as\n | { id?: string }\n | undefined;\n const lastEventToCommitId = lastEventToCommit?.id ?? null;\n let committedEvents = eventsToCommit;\n try {\n await db.transaction(async (tx) => {\n // Insert events (skip duplicates)\n committedEvents = (await tx\n .insert(stream.table as PgTable)\n .values(eventsToCommit)\n .onConflictDoNothing()\n .returning()) as Record<string, unknown>[];\n\n // Update checkpoint\n await updateCheckpoint(\n tx as unknown as DatabaseClient,\n stream.name,\n batch.slot,\n lastEventToCommitId\n );\n });\n } catch (commitErr) {\n observer?.onError?.(\"commit\", commitErr);\n throw commitErr;\n }\n\n stats.batchesCommitted++;\n stats.lastSlot = batch.slot;\n observer?.onBatchCommitted?.({\n slot: batch.slot,\n count: eventsToCommit.length,\n });\n observer?.onCheckpoint?.({ slot: batch.slot });\n\n // Call onCommit hook if defined\n if (stream.onCommit && committedEvents.length > 0) {\n try {\n await stream.onCommit({ ...batch, events: committedEvents }, { db });\n } catch (hookErr) {\n observer?.onError?.(\"onCommit\", hookErr);\n log(\n \"error\",\n `onCommit hook failed: ${hookErr instanceof Error ? hookErr.message : String(hookErr)}`\n );\n // Don't rethrow - hooks should not block indexing\n }\n }\n };\n\n let rejectFlushFailure: (error: unknown) => void = () => {};\n const flushFailure = new Promise<never>((_, reject) => {\n rejectFlushFailure = reject;\n });\n\n // Background timer to flush pending events that exceed the timeout.\n // Failures here must reject the processor so the supervisor can restart\n // from the last durable checkpoint instead of silently dropping the batch.\n const flushInterval = setInterval(async () => {\n const batch = batcher.flushIfStale();\n if (batch) {\n try {\n await commitBatch(batch);\n log(\n \"debug\",\n `Timeout flush: ${batch.events.length} event(s) at slot ${batch.slot}`\n );\n } catch (err) {\n log(\n \"error\",\n `Timeout flush failed: ${err instanceof Error ? err.message : String(err)}`\n );\n clearInterval(flushInterval);\n rejectFlushFailure(err);\n }\n }\n }, 1000);\n\n const processReplay = async () => {\n for await (const event of replay) {\n if (abortSignal?.aborted) {\n log(\"info\", \"Abort signal received, stopping...\");\n break;\n }\n\n eventsReceivedSinceLastLog++;\n observer?.onRecord?.({\n slot: event.slot ?? null,\n id: event.eventId ?? null,\n });\n\n // Parse the event\n let parsed: Record<string, unknown> | null;\n try {\n parsed = stream.parse(event) as Record<string, unknown> | null;\n } catch (parseErr) {\n observer?.onParserError?.(parseErr);\n observer?.onError?.(\"parse\", parseErr);\n throw parseErr;\n }\n if (!parsed) {\n observer?.onParserNull?.();\n continue;\n }\n\n // Validate parse output if enabled\n if (validateParse) {\n const validation = validateParsedData(stream.schema, parsed, stream.name);\n if (!validation.success) {\n observer?.onParseValidationError?.(validation.error);\n log(\"error\", validation.error);\n continue; // Skip invalid events\n }\n }\n\n stats.eventsProcessed++;\n\n // Add to batcher\n const batch = batcher.addEvent(parsed, event.slot!);\n if (batch) {\n await commitBatch(batch);\n log(\n \"info\",\n `Committed ${batch.events.length} event(s) at slot ${batch.slot} (total: ${stats.eventsProcessed})`\n );\n }\n\n // Heartbeat logging\n const now = Date.now();\n if (now - lastLogTime >= 30000) {\n log(\n \"info\",\n `Heartbeat: ${eventsReceivedSinceLastLog} events received, ${batcher.getPendingCount()} pending`\n );\n eventsReceivedSinceLastLog = 0;\n lastLogTime = now;\n }\n }\n\n // Flush any remaining events\n const finalBatch = batcher.flush();\n if (finalBatch) {\n await commitBatch(finalBatch);\n log(\n \"info\",\n `Final flush: ${finalBatch.events.length} event(s) at slot ${finalBatch.slot}`\n );\n }\n };\n\n try {\n await Promise.race([processReplay(), flushFailure]);\n } catch (err) {\n log(\n \"error\",\n `Stream error: ${err instanceof Error ? err.message : String(err)}`\n );\n throw err;\n } finally {\n clearInterval(flushInterval);\n rejectFlushFailure = () => {};\n }\n\n log(\n \"info\",\n `Stream stopped. Processed ${stats.eventsProcessed} events in ${stats.batchesCommitted} batches.`\n );\n return stats;\n}\n","/**\n * Define an account stream for indexing on-chain account state.\n *\n * Account streams track current state of on-chain accounts.\n * Unlike event streams (historical log), account streams are mutable -\n * rows are updated when account state changes.\n *\n * @example\n * ```ts\n * import { defineAccountStream, t } from \"@thru/indexer\";\n * import { decodeAddress } from \"@thru/sdk/helpers\";\n * import type { AccountState } from \"@thru/replay\";\n *\n * export const tokenAccounts = defineAccountStream({\n * name: \"token-accounts\",\n *\n * ownerProgram: decodeAddress(TOKEN_PROGRAM_PUBKEY),\n * expectedSize: 73, // TokenAccount size in bytes\n *\n * schema: {\n * address: t.text().primaryKey(),\n * mint: t.text().notNull().index(),\n * owner: t.text().notNull().index(),\n * amount: t.bigint().notNull(),\n * isFrozen: t.boolean().notNull(),\n * slot: t.bigint().notNull(),\n * seq: t.bigint().notNull(),\n * updatedAt: t.timestamp().notNull().defaultNow(),\n * },\n *\n * parse: (account: AccountState) => {\n * if (account.data.length !== 73) return null;\n * return {\n * address: encodeAddress(account.address),\n * mint: parseAddress(account.data, 0),\n * owner: parseAddress(account.data, 32),\n * amount: parseBigint(account.data, 64),\n * isFrozen: account.data[72] !== 0,\n * slot: account.slot,\n * seq: account.seq,\n * updatedAt: new Date(),\n * };\n * },\n *\n * api: { filters: [\"mint\", \"owner\"], idField: \"address\" },\n * });\n *\n * // Export the table for Drizzle migrations\n * export const tokenAccountsTable = tokenAccounts.table;\n * ```\n */\n\nimport type { SchemaDefinition } from \"../schema/types\";\nimport { buildDrizzleTable } from \"../schema/table\";\nimport type { AccountStreamDefinition, AccountStream } from \"./types\";\n\n// ============================================================\n// Utilities\n// ============================================================\n\nfunction pascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\"\");\n}\n\n// ============================================================\n// Main Export\n// ============================================================\n\n/**\n * Define an account stream for indexing on-chain account state.\n *\n * @param definition - Stream definition with schema, ownerProgram, and parse function\n * @returns A compiled account stream ready for use with the indexer\n */\nexport function defineAccountStream<TSchema extends SchemaDefinition>(\n definition: AccountStreamDefinition<TSchema>\n): AccountStream<TSchema> {\n // Validate that either ownerProgram or ownerProgramFactory is provided\n if (!definition.ownerProgram && !definition.ownerProgramFactory) {\n throw new Error(`Stream \"${definition.name}\" must provide either ownerProgram or ownerProgramFactory`);\n }\n\n // Build table name (e.g., \"token-accounts\" -> \"token_accounts\")\n const tableName = definition.name.replace(/-/g, \"_\");\n\n // Build Drizzle table from schema\n const table = buildDrizzleTable(tableName, definition.schema);\n\n // Lazy ownerProgram resolution (cached after first call)\n let cachedOwnerProgram: Uint8Array | null = definition.ownerProgram ?? null;\n const getOwnerProgram = (): Uint8Array => {\n if (!cachedOwnerProgram) {\n if (definition.ownerProgramFactory) {\n cachedOwnerProgram = definition.ownerProgramFactory();\n } else {\n throw new Error(`Stream \"${definition.name}\" has no ownerProgram configured`);\n }\n }\n return cachedOwnerProgram;\n };\n\n return {\n name: definition.name,\n description: definition.description ?? `${pascalCase(definition.name)} accounts`,\n schema: definition.schema,\n getOwnerProgram,\n expectedSize: definition.expectedSize,\n dataSizes: definition.dataSizes,\n table,\n // Column accessors for Drizzle operators\n c: table as any,\n parse: definition.parse,\n api: definition.api,\n };\n}\n","/**\n * Account stream processor.\n *\n * Processes account state from @thru/replay and commits to the database\n * with slot-aware upserts and checkpointing.\n */\n\nimport { eq, sql } from \"drizzle-orm\";\nimport type { ChainClientFactory, ReplayLogger } from \"@thru/replay\";\nimport { createAccountsByOwnerReplay, AccountView } from \"@thru/replay\";\nimport { encodeAddress } from \"@thru/sdk/helpers\";\nimport type { DatabaseClient } from \"../schema/types\";\nimport { validateParsedData } from \"../schema/validation\";\nimport { getCheckpoint, updateCheckpoint } from \"../checkpoint\";\nimport type { AccountStream } from \"./types\";\nimport type { ProcessorStatusObserver } from \"../runtime/status\";\nimport { createScopedLogger } from \"../runtime/logger\";\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface AccountProcessorOptions {\n /** Factory to create fresh chain clients for reconnection */\n clientFactory: ChainClientFactory;\n /** Database client */\n db: DatabaseClient;\n /** Log level */\n logLevel?: \"debug\" | \"info\" | \"warn\" | \"error\";\n /** Structured logger for processor and replay lifecycle logs */\n logger?: ReplayLogger;\n /** Validate parse output with Zod (useful for development) */\n validateParse?: boolean;\n /** Runtime status observer */\n observer?: ProcessorStatusObserver;\n}\n\nexport interface AccountProcessorStats {\n /** Total accounts processed */\n accountsProcessed: number;\n /** Total accounts inserted/updated */\n accountsUpdated: number;\n /** Total accounts deleted */\n accountsDeleted: number;\n}\n\n// ============================================================\n// Processor\n// ============================================================\n\n/**\n * Run an account stream processor.\n *\n * Backfills all accounts via ListAccounts, then streams live updates.\n * Supports resumable indexing via checkpoint persistence.\n *\n * @param stream - The account stream to process\n * @param options - Processor configuration\n * @param abortSignal - Optional signal to stop processing\n * @returns Processor statistics\n */\nexport async function runAccountStreamProcessor(\n stream: AccountStream,\n options: AccountProcessorOptions,\n abortSignal?: AbortSignal\n): Promise<AccountProcessorStats> {\n const { clientFactory, db, logLevel = \"info\", logger: baseLogger, validateParse = false, observer } = options;\n const checkpointName = `account:${stream.name}`;\n\n const logger = createScopedLogger({\n logger: baseLogger,\n level: logLevel,\n prefix: `account-stream:${stream.name}`,\n bindings: {\n component: \"indexer-stream\",\n stream: stream.name,\n kind: \"account\",\n checkpoint_name: checkpointName,\n },\n });\n const log = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n msg: string,\n meta?: Record<string, unknown>\n ) => logger[level](msg, meta);\n\n const stats: AccountProcessorStats = {\n accountsProcessed: 0,\n accountsUpdated: 0,\n accountsDeleted: 0,\n };\n\n // Load checkpoint for resumable backfill\n const checkpoint = await getCheckpoint(db, checkpointName);\n const minUpdatedSlot = checkpoint?.slot;\n observer?.onStart?.({\n startSlot: minUpdatedSlot,\n checkpointSlot: checkpoint?.slot ?? null,\n });\n if (minUpdatedSlot) {\n log(\"info\", `Resuming from checkpoint: slot ${minUpdatedSlot}`);\n }\n\n log(\"info\", `Starting account stream: ${stream.description}`);\n if (stream.expectedSize) {\n log(\"info\", `Expected data size: ${stream.expectedSize} bytes`);\n }\n\n // Track highest slot seen for checkpoint persistence\n let lastProcessedSlot = minUpdatedSlot ?? 0n;\n\n try {\n // Use createAccountsByOwnerReplay for hybrid backfill + streaming\n const replay = createAccountsByOwnerReplay({\n clientFactory,\n owner: stream.getOwnerProgram(),\n view: AccountView.FULL,\n dataSizes: stream.dataSizes ?? (stream.expectedSize ? [stream.expectedSize] : undefined),\n minUpdatedSlot,\n logger,\n signal: abortSignal,\n onBackfillComplete: (highestSlot) => {\n log(\n \"info\",\n `Backfill complete. Highest slot: ${highestSlot}, accounts processed: ${stats.accountsProcessed}`\n );\n },\n });\n\n for await (const event of replay) {\n if (abortSignal?.aborted) {\n log(\"info\", \"Abort signal received, stopping\");\n break;\n }\n\n if (event.type === \"account\") {\n const account = event.account;\n stats.accountsProcessed++;\n observer?.onRecord?.({\n slot: account.slot,\n id: account.addressHex,\n });\n\n // Log first few accounts for debugging\n if (stats.accountsProcessed <= 3) {\n log(\n \"info\",\n `Account ${stats.accountsProcessed}: ${account.addressHex}, slot=${account.slot}, dataLen=${account.data.length}`\n );\n }\n\n const table = stream.table as any;\n const idField = stream.api?.idField ?? \"address\";\n\n // Handle account deletions before parsing — deleted accounts have\n // zeroed data so parse() would return null and the delete would be\n // silently skipped.\n if (account.isDelete) {\n log(\"debug\", `Account deleted: ${account.addressHex}`);\n const idValue = encodeAddress(account.address);\n try {\n await db.delete(stream.table).where(eq(table[idField], idValue));\n stats.accountsDeleted++;\n observer?.onCheckpoint?.({ slot: account.slot });\n log(\"info\", `Deleted row for account ${account.addressHex}`);\n if (account.slot > lastProcessedSlot) {\n lastProcessedSlot = account.slot;\n }\n } catch (err) {\n observer?.onError?.(\"commit\", err);\n log(\"error\", `Failed to delete account ${account.addressHex}: ${err}`);\n throw err;\n }\n continue;\n }\n\n // Parse using stream's parser\n let parsed;\n try {\n parsed = stream.parse(account);\n } catch (parseErr) {\n observer?.onParserError?.(parseErr);\n observer?.onError?.(\"parse\", parseErr);\n throw parseErr;\n }\n if (!parsed) {\n observer?.onParserNull?.();\n log(\n \"debug\",\n `Skipped account ${account.addressHex} - parser returned null (dataLen=${account.data.length})`\n );\n if (account.slot > lastProcessedSlot) {\n lastProcessedSlot = account.slot;\n }\n continue;\n }\n\n // Validate parse output if enabled\n if (validateParse) {\n const validation = validateParsedData(stream.schema, parsed, stream.name);\n if (!validation.success) {\n observer?.onParseValidationError?.(validation.error);\n log(\"error\", validation.error);\n continue; // Skip invalid accounts\n }\n }\n\n // Slot-aware upsert: only update if incoming slot >= existing slot\n\n let upserted = false;\n try {\n const upsertedRows = await db\n .insert(stream.table)\n .values(parsed)\n .onConflictDoUpdate({\n target: table[idField],\n set: parsed,\n where: sql`${table.slot} <= ${(parsed as any).slot}`,\n })\n .returning();\n\n upserted = upsertedRows.length > 0;\n if (upserted) {\n stats.accountsUpdated++;\n }\n\n if (upserted && stats.accountsUpdated <= 3) {\n log(\n \"info\",\n `Successfully inserted account ${stats.accountsUpdated}`\n );\n }\n } catch (err) {\n observer?.onError?.(\"commit\", err);\n log(\n \"error\",\n `Failed to upsert account ${account.addressHex}: ${err}`\n );\n throw err;\n }\n\n // Track highest slot for checkpoint\n if (upserted && account.slot > lastProcessedSlot) {\n lastProcessedSlot = account.slot;\n }\n\n // Progress logging\n if (stats.accountsProcessed % 100 === 0) {\n log(\n \"info\",\n `Processed ${stats.accountsProcessed} accounts, updated ${stats.accountsUpdated}`\n );\n }\n } else if (event.type === \"blockFinished\") {\n // Persist at block boundaries, but do not advance the checkpoint to\n // the block slot unless an account update was actually handled.\n const slot = event.block.slot;\n if (lastProcessedSlot > 0n) {\n await updateCheckpoint(db, checkpointName, lastProcessedSlot, null);\n observer?.onCheckpoint?.({ slot: lastProcessedSlot });\n log(\n \"debug\",\n `Block finished: slot ${slot}, checkpoint saved at account slot ${lastProcessedSlot}`\n );\n } else {\n log(\n \"debug\",\n `Block finished: slot ${slot}, no checkpoint yet (no accounts handled)`\n );\n }\n }\n }\n\n // Final checkpoint save\n if (lastProcessedSlot > 0n) {\n await updateCheckpoint(db, checkpointName, lastProcessedSlot, null);\n observer?.onCheckpoint?.({ slot: lastProcessedSlot });\n log(\"info\", `Final checkpoint saved: slot ${lastProcessedSlot}`);\n }\n } catch (err) {\n if (abortSignal?.aborted) {\n log(\"info\", \"Stream aborted\");\n } else {\n log(\n \"error\",\n `Stream error: ${err instanceof Error ? err.message : String(err)}`\n );\n throw err;\n }\n }\n\n log(\n \"info\",\n `Finished. Processed: ${stats.accountsProcessed}, Updated: ${stats.accountsUpdated}, Deleted: ${stats.accountsDeleted}`\n );\n\n return stats;\n}\n","/**\n * Runtime status and health types for the indexer supervisor.\n */\n\nexport type IndexerStreamKind = \"event\" | \"account\";\n\nexport type IndexerStreamState =\n | \"idle\"\n | \"starting\"\n | \"running\"\n | \"retrying\"\n | \"stopped\";\n\nexport type IndexerErrorPhase =\n | \"starting\"\n | \"backfill\"\n | \"live\"\n | \"parse\"\n | \"commit\"\n | \"filterBatch\"\n | \"onCommit\"\n | \"supervisor\";\n\nexport interface NormalizedIndexerError {\n name: string;\n message: string;\n code?: string | number;\n phase: IndexerErrorPhase;\n retryable: boolean;\n streamName: string;\n streamKind: IndexerStreamKind;\n startSlot?: string;\n checkpointSlot?: string;\n endpointLabel?: string;\n}\n\nexport interface IndexerStreamCounters {\n eventsReceived: number;\n parserNulls: number;\n parserErrors: number;\n parseValidationErrors: number;\n commitErrors: number;\n filterBatchErrors: number;\n onCommitErrors: number;\n recordsProcessed: number;\n batchesCommitted: number;\n}\n\nexport interface IndexerStreamStatus {\n name: string;\n kind: IndexerStreamKind;\n state: IndexerStreamState;\n checkpointSlot: string | null;\n lastProcessedSlot: string | null;\n lastEventAt: string | null;\n stale: boolean;\n restartCount: number;\n lastStartedAt: string | null;\n lastErrorAt: string | null;\n lastError: NormalizedIndexerError | null;\n counters: IndexerStreamCounters;\n}\n\nexport interface IndexerStatus {\n running: boolean;\n shutdownRequested: boolean;\n startedAt: string | null;\n uptimeMs: number;\n healthy: boolean;\n streams: IndexerStreamStatus[];\n}\n\nexport interface ProcessorStatusObserver {\n onStart?(info: {\n startSlot?: bigint;\n checkpointSlot?: bigint | null;\n }): void;\n onRecord?(info: {\n slot?: bigint | null;\n id?: string | null;\n }): void;\n onParserNull?(): void;\n onParserError?(error: unknown): void;\n onParseValidationError?(error: string): void;\n onBatchCommitted?(info: {\n slot: bigint;\n count: number;\n }): void;\n onCheckpoint?(info: {\n slot: bigint;\n }): void;\n onError?(phase: IndexerErrorPhase, error: unknown): void;\n}\n\nexport function emptyStreamCounters(): IndexerStreamCounters {\n return {\n eventsReceived: 0,\n parserNulls: 0,\n parserErrors: 0,\n parseValidationErrors: 0,\n commitErrors: 0,\n filterBatchErrors: 0,\n onCommitErrors: 0,\n recordsProcessed: 0,\n batchesCommitted: 0,\n };\n}\n\nexport function cloneStreamStatus(status: IndexerStreamStatus): IndexerStreamStatus {\n return {\n ...status,\n lastError: status.lastError ? { ...status.lastError } : null,\n counters: { ...status.counters },\n };\n}\n\nexport function normalizeIndexerError(input: {\n error: unknown;\n phase: IndexerErrorPhase;\n streamName: string;\n streamKind: IndexerStreamKind;\n startSlot?: bigint | null;\n checkpointSlot?: bigint | null;\n endpointLabel?: string;\n}): NormalizedIndexerError {\n const err = input.error;\n const maybeRecord = err && typeof err === \"object\" ? err as Record<string, unknown> : {};\n const name = err instanceof Error ? err.name : typeof maybeRecord.name === \"string\" ? maybeRecord.name : \"Error\";\n const message = err instanceof Error ? err.message : String(err);\n const code = typeof maybeRecord.code === \"string\" || typeof maybeRecord.code === \"number\"\n ? maybeRecord.code\n : undefined;\n const retryable = isRetryablePhase(input.phase);\n\n return {\n name,\n message,\n code,\n phase: input.phase,\n retryable,\n streamName: input.streamName,\n streamKind: input.streamKind,\n startSlot: input.startSlot === undefined || input.startSlot === null ? undefined : input.startSlot.toString(),\n checkpointSlot: input.checkpointSlot === undefined || input.checkpointSlot === null ? undefined : input.checkpointSlot.toString(),\n endpointLabel: input.endpointLabel,\n };\n}\n\nfunction isRetryablePhase(phase: IndexerErrorPhase): boolean {\n switch (phase) {\n case \"starting\":\n case \"backfill\":\n case \"live\":\n case \"commit\":\n case \"supervisor\":\n return true;\n case \"parse\":\n case \"filterBatch\":\n case \"onCommit\":\n return false;\n }\n}\n","/**\n * Indexer runtime class.\n *\n * Orchestrates running multiple event and account streams concurrently\n * with graceful shutdown support.\n *\n * @example\n * ```ts\n * import { Indexer } from \"@thru/indexer\";\n * import { ChainClient } from \"@thru/replay\";\n * import { transfers } from \"./streams/transfers\";\n * import { tokenAccounts } from \"./account-streams/token-accounts\";\n *\n * const indexer = new Indexer({\n * db,\n * clientFactory: () => new ChainClient({ baseUrl: RPC_URL }),\n * eventStreams: [transfers],\n * accountStreams: [tokenAccounts],\n * defaultStartSlot: 0n,\n * safetyMargin: 64,\n * });\n *\n * // Handle graceful shutdown\n * process.on(\"SIGINT\", () => indexer.stop());\n * process.on(\"SIGTERM\", () => indexer.stop());\n *\n * // Start indexing\n * await indexer.start();\n * ```\n */\n\nimport { sql } from \"drizzle-orm\";\nimport type { IndexerConfig } from \"./config\";\nimport { runEventStreamProcessor, type ProcessorStats } from \"../streams/processor\";\nimport { runAccountStreamProcessor, type AccountProcessorStats } from \"../accounts/processor\";\nimport {\n cloneStreamStatus,\n emptyStreamCounters,\n normalizeIndexerError,\n type IndexerStatus,\n type IndexerStreamKind,\n type IndexerStreamStatus,\n type ProcessorStatusObserver,\n} from \"./status\";\nimport { createScopedLogger } from \"./logger\";\nimport type { EventStream } from \"../streams/types\";\nimport type { AccountStream } from \"../accounts/types\";\nimport type { ReplayLogger } from \"@thru/replay\";\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface IndexerResult {\n /** Results from event stream processors */\n eventStreams: Array<{\n name: string;\n status: \"fulfilled\" | \"rejected\";\n result?: ProcessorStats;\n error?: Error;\n }>;\n /** Results from account stream processors */\n accountStreams: Array<{\n name: string;\n status: \"fulfilled\" | \"rejected\";\n result?: AccountProcessorStats;\n error?: Error;\n }>;\n}\n\n// ============================================================\n// Indexer Class\n// ============================================================\n\n/**\n * Indexer runtime that orchestrates event and account streams.\n */\nexport class Indexer {\n private config: IndexerConfig;\n private logger: ReplayLogger;\n private abortController: AbortController | null = null;\n private running = false;\n private shutdownRequested = false;\n private startedAtMs: number | null = null;\n private streamStatuses = new Map<string, IndexerStreamStatus>();\n private streamHealthStates = new Map<string, {\n unhealthy: boolean;\n unhealthySinceMs: number | null;\n }>();\n\n constructor(config: IndexerConfig) {\n this.config = {\n defaultStartSlot: 0n,\n safetyMargin: 64,\n pageSize: 512,\n logLevel: \"info\",\n supervisorInitialBackoffMs: 1000,\n supervisorMaxBackoffMs: 30000,\n ...config,\n };\n this.logger = createScopedLogger({\n logger: this.config.logger,\n level: this.config.logLevel,\n prefix: \"indexer\",\n bindings: { component: \"indexer-runtime\" },\n });\n\n this.initializeStreamStatuses();\n }\n\n /**\n * Check if the checkpoint table exists in the database.\n * Logs a warning if it doesn't exist (user may have forgotten to export it in schema).\n */\n private async checkCheckpointTable(): Promise<void> {\n try {\n // Try to query the checkpoint table\n await this.config.db.execute(\n sql`SELECT 1 FROM indexer_checkpoints LIMIT 1`\n );\n } catch (err) {\n // drizzle-orm >= 0.44 wraps driver errors in DrizzleQueryError;\n // the original DB message lives in .cause\n const message = err instanceof Error\n ? (err.cause instanceof Error ? err.cause.message : err.message)\n : String(err);\n // Check if error is about missing table\n if (message.includes(\"does not exist\") || message.includes(\"relation\")) {\n this.logger.warn(\n `Checkpoint table \"indexer_checkpoints\" not found.\nMake sure to export checkpointTable from your Drizzle schema:\n\n // db/schema.ts\n export { checkpointTable } from \"@thru/indexer\";\n\nThen run: pnpm drizzle-kit push (or generate + migrate)\n`\n );\n }\n // Re-throw so startup fails\n throw err;\n }\n }\n\n /**\n * Start the indexer.\n *\n * Runs all configured event and account streams concurrently.\n * Returns when all streams complete or when stop() is called.\n *\n * @returns Results from all stream processors\n */\n async start(): Promise<IndexerResult> {\n if (this.running) {\n throw new Error(\"Indexer is already running\");\n }\n\n // Check that checkpoint table exists before starting\n await this.checkCheckpointTable();\n\n this.running = true;\n this.shutdownRequested = false;\n this.startedAtMs = Date.now();\n this.abortController = new AbortController();\n this.initializeStreamStatuses();\n\n const {\n db,\n clientFactory,\n eventStreams = [],\n accountStreams = [],\n defaultStartSlot,\n safetyMargin,\n pageSize,\n logLevel,\n validateParse,\n endpointLabel,\n supervisorInitialBackoffMs = 1000,\n supervisorMaxBackoffMs = 30000,\n logger,\n } = this.config;\n\n this.logger.info(\"Starting indexer\", {\n event: \"indexer.started\",\n event_streams: eventStreams.map((stream) => stream.name),\n account_streams: accountStreams.map((stream) => stream.name),\n });\n\n try {\n const supervisorOptions = {\n endpointLabel,\n initialBackoffMs: supervisorInitialBackoffMs,\n maxBackoffMs: supervisorMaxBackoffMs,\n };\n\n const eventSupervisors = eventStreams.map((stream) =>\n this.runEventStreamSupervisor(stream, {\n clientFactory,\n db,\n defaultStartSlot: defaultStartSlot!,\n safetyMargin,\n pageSize,\n logLevel,\n logger,\n validateParse,\n }, supervisorOptions)\n );\n\n const accountSupervisors = accountStreams.map((stream) =>\n this.runAccountStreamSupervisor(stream, {\n clientFactory,\n db,\n logLevel,\n logger,\n validateParse,\n }, supervisorOptions)\n );\n\n await Promise.all([...eventSupervisors, ...accountSupervisors]);\n\n const result: IndexerResult = {\n eventStreams: eventStreams.map((stream) => this.resultForStream(stream.name)),\n accountStreams: accountStreams.map((stream) => this.resultForStream(stream.name)),\n };\n\n this.logger.info(\"All indexer streams stopped\", {\n event: \"indexer.stopped\",\n });\n return result;\n } finally {\n this.running = false;\n this.abortController = null;\n this.startedAtMs = null;\n }\n }\n\n /**\n * Stop the indexer gracefully.\n *\n * Signals all streams to finish their current batch and stop.\n * The start() promise will resolve once all streams have stopped.\n */\n stop(): void {\n if (!this.running || !this.abortController) {\n this.logger.info(\"Indexer is not running\", {\n event: \"indexer.stop.noop\",\n });\n return;\n }\n\n if (this.shutdownRequested) {\n this.logger.warn(\"Force shutting down indexer\", {\n event: \"indexer.force_shutdown\",\n });\n process.exit(1);\n }\n\n this.logger.info(\"Indexer shutdown requested\", {\n event: \"indexer.shutdown_requested\",\n });\n this.shutdownRequested = true;\n this.abortController.abort();\n }\n\n /**\n * Check if the indexer is currently running.\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Get the current in-memory runtime status for every configured stream.\n */\n getStatus(): IndexerStatus {\n const now = Date.now();\n const streams = Array.from(this.streamStatuses.values()).map((status) => {\n const stream = cloneStreamStatus(status);\n stream.stale = this.isStreamStale(stream, now);\n return stream;\n });\n const healthy =\n this.running &&\n !this.shutdownRequested &&\n streams.length > 0 &&\n streams.every((stream) => stream.state === \"running\");\n this.emitHealthTransitions(streams, now);\n\n return {\n running: this.running,\n shutdownRequested: this.shutdownRequested,\n startedAt: this.startedAtMs === null ? null : new Date(this.startedAtMs).toISOString(),\n uptimeMs: this.startedAtMs === null ? 0 : now - this.startedAtMs,\n healthy,\n streams,\n };\n }\n\n private initializeStreamStatuses(): void {\n this.streamStatuses = new Map();\n this.streamHealthStates = new Map();\n for (const stream of this.config.eventStreams ?? []) {\n this.streamStatuses.set(this.statusKey(\"event\", stream.name), this.createInitialStreamStatus(\"event\", stream.name));\n }\n for (const stream of this.config.accountStreams ?? []) {\n this.streamStatuses.set(this.statusKey(\"account\", stream.name), this.createInitialStreamStatus(\"account\", stream.name));\n }\n }\n\n private createInitialStreamStatus(kind: IndexerStreamKind, name: string): IndexerStreamStatus {\n return {\n name,\n kind,\n state: \"idle\",\n checkpointSlot: null,\n lastProcessedSlot: null,\n lastEventAt: null,\n stale: false,\n restartCount: 0,\n lastStartedAt: null,\n lastErrorAt: null,\n lastError: null,\n counters: emptyStreamCounters(),\n };\n }\n\n private statusKey(kind: IndexerStreamKind, name: string): string {\n return `${kind}:${name}`;\n }\n\n private statusFor(kind: IndexerStreamKind, name: string): IndexerStreamStatus {\n const key = this.statusKey(kind, name);\n let status = this.streamStatuses.get(key);\n if (!status) {\n status = this.createInitialStreamStatus(kind, name);\n this.streamStatuses.set(key, status);\n }\n return status;\n }\n\n private resultForStream(name: string): {\n name: string;\n status: \"fulfilled\" | \"rejected\";\n error?: Error;\n } {\n return {\n name,\n status: \"fulfilled\",\n };\n }\n\n private setStreamState(\n status: IndexerStreamStatus,\n nextState: IndexerStreamStatus[\"state\"],\n meta: Record<string, unknown> = {}\n ): void {\n const previousState = status.state;\n status.state = nextState;\n if (previousState === nextState) {\n return;\n }\n\n this.logger.info(\"Indexer stream state changed\", {\n event: \"indexer.stream.state_changed\",\n stream: status.name,\n kind: status.kind,\n previous_state: previousState,\n next_state: nextState,\n restart_count: status.restartCount,\n ...meta,\n });\n }\n\n private streamLogFields(stream: IndexerStreamStatus): Record<string, unknown> {\n return {\n stream: stream.name,\n kind: stream.kind,\n state: stream.state,\n stale: stream.stale,\n checkpoint_slot: stream.checkpointSlot,\n last_processed_slot: stream.lastProcessedSlot,\n last_event_at: stream.lastEventAt,\n restart_count: stream.restartCount,\n last_error_at: stream.lastErrorAt,\n last_error: stream.lastError,\n };\n }\n\n private emitHealthTransitions(streams: IndexerStreamStatus[], nowMs: number): void {\n if (!this.running || this.shutdownRequested) {\n return;\n }\n\n for (const stream of streams) {\n const key = this.statusKey(stream.kind, stream.name);\n const unhealthy = stream.state !== \"running\";\n const previous = this.streamHealthStates.get(key);\n const initialStarting =\n !previous &&\n stream.state === \"starting\" &&\n stream.restartCount === 0 &&\n !stream.lastError;\n\n if (initialStarting) {\n this.streamHealthStates.set(key, {\n unhealthy: false,\n unhealthySinceMs: null,\n });\n continue;\n }\n\n if (unhealthy && previous?.unhealthy !== true) {\n this.streamHealthStates.set(key, {\n unhealthy: true,\n unhealthySinceMs: nowMs,\n });\n this.logger.warn(\"Indexer stream unhealthy\", {\n event: \"indexer.stream.unhealthy\",\n reason: stream.stale ? \"state_while_stale\" : \"state\",\n ...this.streamLogFields(stream),\n });\n continue;\n }\n\n if (!unhealthy && previous?.unhealthy === true) {\n this.streamHealthStates.set(key, {\n unhealthy: false,\n unhealthySinceMs: null,\n });\n this.logger.info(\"Indexer stream recovered\", {\n event: \"indexer.stream.recovered\",\n unhealthy_duration_ms: previous.unhealthySinceMs === null\n ? null\n : nowMs - previous.unhealthySinceMs,\n ...this.streamLogFields(stream),\n });\n continue;\n }\n\n if (!previous) {\n this.streamHealthStates.set(key, {\n unhealthy,\n unhealthySinceMs: unhealthy ? nowMs : null,\n });\n }\n }\n }\n\n private createObserver(kind: IndexerStreamKind, name: string, endpointLabel?: string): ProcessorStatusObserver {\n const status = this.statusFor(kind, name);\n let startSlot: bigint | null = null;\n let checkpointSlot: bigint | null = null;\n\n return {\n onStart: (info) => {\n startSlot = info.startSlot ?? null;\n checkpointSlot = info.checkpointSlot ?? null;\n this.setStreamState(status, \"running\", {\n start_slot: startSlot?.toString(),\n checkpoint_slot: checkpointSlot?.toString() ?? null,\n });\n status.checkpointSlot = checkpointSlot === null ? null : checkpointSlot.toString();\n status.lastStartedAt = new Date().toISOString();\n },\n onRecord: (info) => {\n status.counters.eventsReceived++;\n status.lastEventAt = new Date().toISOString();\n if (info.slot !== undefined && info.slot !== null) {\n status.lastProcessedSlot = info.slot.toString();\n }\n },\n onParserNull: () => {\n status.counters.parserNulls++;\n },\n onParserError: () => {\n status.counters.parserErrors++;\n },\n onParseValidationError: () => {\n status.counters.parseValidationErrors++;\n },\n onBatchCommitted: (info) => {\n status.counters.batchesCommitted++;\n status.counters.recordsProcessed += info.count;\n status.lastProcessedSlot = info.slot.toString();\n status.lastEventAt = new Date().toISOString();\n },\n onCheckpoint: (info) => {\n status.checkpointSlot = info.slot.toString();\n status.lastProcessedSlot = info.slot.toString();\n },\n onError: (phase, error) => {\n if (phase === \"commit\") status.counters.commitErrors++;\n if (phase === \"filterBatch\") status.counters.filterBatchErrors++;\n if (phase === \"onCommit\") status.counters.onCommitErrors++;\n status.lastErrorAt = new Date().toISOString();\n status.lastError = normalizeIndexerError({\n error,\n phase,\n streamName: name,\n streamKind: kind,\n startSlot,\n checkpointSlot,\n endpointLabel,\n });\n },\n };\n }\n\n private async runEventStreamSupervisor(\n stream: EventStream,\n processorOptions: Omit<Parameters<typeof runEventStreamProcessor>[1], \"observer\">,\n supervisorOptions: { endpointLabel?: string; initialBackoffMs: number; maxBackoffMs: number }\n ): Promise<void> {\n await this.runStreamSupervisor(\"event\", stream.name, supervisorOptions, async (observer) => {\n const result = await runEventStreamProcessor(\n stream,\n { ...processorOptions, observer },\n this.abortController!.signal\n );\n return `processed ${result.eventsProcessed} event(s) in ${result.batchesCommitted} batch(es)`;\n });\n }\n\n private async runAccountStreamSupervisor(\n stream: AccountStream,\n processorOptions: Omit<Parameters<typeof runAccountStreamProcessor>[1], \"observer\">,\n supervisorOptions: { endpointLabel?: string; initialBackoffMs: number; maxBackoffMs: number }\n ): Promise<void> {\n await this.runStreamSupervisor(\"account\", stream.name, supervisorOptions, async (observer) => {\n const result = await runAccountStreamProcessor(\n stream,\n { ...processorOptions, observer },\n this.abortController!.signal\n );\n return `processed ${result.accountsProcessed} account event(s), updated ${result.accountsUpdated}, deleted ${result.accountsDeleted}`;\n });\n }\n\n private async runStreamSupervisor(\n kind: IndexerStreamKind,\n name: string,\n options: { endpointLabel?: string; initialBackoffMs: number; maxBackoffMs: number },\n runOnce: (observer: ProcessorStatusObserver) => Promise<string>\n ): Promise<void> {\n let attempt = 0;\n const status = this.statusFor(kind, name);\n\n while (!this.abortController?.signal.aborted) {\n const observer = this.createObserver(kind, name, options.endpointLabel);\n const runStartedAtMs = Date.now();\n this.setStreamState(status, attempt === 0 ? \"starting\" : \"retrying\", {\n attempt,\n });\n status.lastStartedAt = new Date(runStartedAtMs).toISOString();\n\n try {\n const summary = await runOnce(observer);\n if (this.abortController?.signal.aborted) {\n this.setStreamState(status, \"stopped\", { summary });\n return;\n }\n\n throw new Error(`${kind} stream \"${name}\" completed unexpectedly: ${summary}`);\n } catch (error) {\n if (this.abortController?.signal.aborted) {\n this.setStreamState(status, \"stopped\");\n return;\n }\n\n status.restartCount++;\n this.setStreamState(status, \"retrying\", {\n restart_count: status.restartCount,\n });\n status.lastErrorAt = new Date().toISOString();\n if (!status.lastError || status.lastError.phase === \"supervisor\") {\n status.lastError = normalizeIndexerError({\n error,\n phase: \"supervisor\",\n streamName: name,\n streamKind: kind,\n endpointLabel: options.endpointLabel,\n });\n }\n\n if (Date.now() - runStartedAtMs >= options.maxBackoffMs) {\n attempt = 0;\n }\n\n const backoffMs = this.supervisorBackoffMs(attempt, options.initialBackoffMs, options.maxBackoffMs);\n this.logger.warn(\"Indexer stream supervisor restarting\", {\n event: \"indexer.stream.supervisor_restart\",\n stream: name,\n kind,\n backoff_ms: backoffMs,\n attempt: attempt + 1,\n restart_count: status.restartCount,\n error,\n last_error: status.lastError,\n });\n attempt++;\n await this.delay(backoffMs, this.abortController!.signal);\n }\n }\n\n this.setStreamState(status, \"stopped\");\n }\n\n private supervisorBackoffMs(attempt: number, initialMs: number, maxMs: number): number {\n const base = Math.min(maxMs, initialMs * Math.pow(2, attempt));\n const jitter = Math.floor(base * 0.2 * Math.random());\n return base + jitter;\n }\n\n private isStreamStale(stream: IndexerStreamStatus, nowMs: number): boolean {\n const staleMs = this.config.streamStaleMs;\n if (staleMs === undefined || staleMs <= 0 || stream.state !== \"running\") {\n return false;\n }\n\n const activityAt = stream.lastEventAt ?? stream.lastStartedAt;\n if (!activityAt) {\n return true;\n }\n\n const activityMs = Date.parse(activityAt);\n return !Number.isFinite(activityMs) || nowMs - activityMs > staleMs;\n }\n\n private delay(ms: number, signal: AbortSignal): Promise<void> {\n if (ms <= 0 || signal.aborted) return Promise.resolve();\n return new Promise((resolve) => {\n const onAbort = () => {\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n timer.unref?.();\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -825,7 +825,7 @@ interface IndexerConfig {
825
825
  supervisorInitialBackoffMs?: number;
826
826
  /** Maximum supervisor restart backoff in milliseconds (default: 30000) */
827
827
  supervisorMaxBackoffMs?: number;
828
- /** Mark running streams unhealthy when no activity is seen for this long (default: 300000, disabled with 0) */
828
+ /** Mark running streams stale when no activity is seen for this long (disabled by default, also disabled with 0) */
829
829
  streamStaleMs?: number;
830
830
  /**
831
831
  * Validate parse output at runtime using Zod schemas.