@apibara/plugin-sqlite 2.1.0-beta.39 → 2.1.0-beta.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -296,7 +296,7 @@ function sqliteStorage({
296
296
  let indexerId = "";
297
297
  let prevFinality;
298
298
  const alwaysReindex = process.env["APIBARA_ALWAYS_REINDEX"] === "true";
299
- indexer.hooks.hook("run:before", async () => {
299
+ indexer.hooks.hook("plugins:init", async () => {
300
300
  const { indexerName: indexerFileName, availableIndexers } = plugins$1.useInternalContext();
301
301
  const logger = plugins.useLogger();
302
302
  indexerId = internal.generateIndexerId(indexerFileName, identifier);
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/utils.ts","../src/kv.ts","../src/persistence.ts","../src/index.ts"],"sourcesContent":["import type { Database } from \"better-sqlite3\";\n\nexport type SerializeFn = <T>(value: T) => string;\nexport type DeserializeFn = <T>(value: string) => T;\n\nexport class SqliteStorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"SqliteStorageError\";\n }\n}\n\nexport async function withTransaction(\n db: Database,\n cb: (db: Database) => Promise<void>,\n) {\n db.prepare(\"BEGIN TRANSACTION\").run();\n try {\n await cb(db);\n } catch (error) {\n db.prepare(\"ROLLBACK TRANSACTION\").run();\n throw error;\n }\n db.prepare(\"COMMIT TRANSACTION\").run();\n}\n\nexport function assertInTransaction(db: Database) {\n if (!db.inTransaction) {\n throw new SqliteStorageError(\"Database is not in transaction\");\n }\n}\n\nexport function deserialize<T>(str: string): T {\n return JSON.parse(str, (_, value) =>\n typeof value === \"string\" && value.match(/^\\d+n$/)\n ? BigInt(value.slice(0, -1))\n : value,\n ) as T;\n}\n\nexport function serialize<T>(obj: T): string {\n return JSON.stringify(\n obj,\n (_, value) => (typeof value === \"bigint\" ? `${value.toString()}n` : value),\n \"\\t\",\n );\n}\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport type { Database } from \"better-sqlite3\";\n\nimport {\n type DeserializeFn,\n type SerializeFn,\n assertInTransaction,\n} from \"./utils\";\n\nexport function initializeKeyValueStore(db: Database) {\n assertInTransaction(db);\n db.exec(statements.createTable);\n}\n\nexport class KeyValueStore {\n constructor(\n private readonly db: Database,\n private readonly endCursor: Cursor,\n private readonly finality: DataFinality,\n private readonly serialize: SerializeFn,\n private readonly deserialize: DeserializeFn,\n private readonly indexerId: string,\n ) {\n assertInTransaction(db);\n }\n\n get<T>(key: string): T | undefined {\n const row = this.db\n .prepare<[string, string], KeyValueRow>(statements.get)\n .get(key, this.indexerId);\n\n return row ? this.deserialize(row.v) : undefined;\n }\n\n put<T>(key: string, value: T) {\n this.db\n .prepare<[number, string, string], KeyValueRow>(statements.updateToBlock)\n .run(Number(this.endCursor.orderKey), key, this.indexerId);\n\n this.db\n .prepare<[number, string, string, string], KeyValueRow>(\n statements.insertIntoKvs,\n )\n .run(\n Number(this.endCursor.orderKey),\n key,\n this.serialize(value as Record<string, unknown>),\n this.indexerId,\n );\n }\n\n del(key: string) {\n this.db\n .prepare<[number, string, string], KeyValueRow>(statements.del)\n .run(Number(this.endCursor.orderKey), key, this.indexerId);\n }\n}\n\nexport function finalizeKV(db: Database, cursor: Cursor, indexerId: string) {\n assertInTransaction(db);\n\n db.prepare<[number, string], KeyValueRow>(statements.finalize).run(\n Number(cursor.orderKey),\n indexerId,\n );\n}\n\nexport function invalidateKV(db: Database, cursor: Cursor, indexerId: string) {\n assertInTransaction(db);\n\n // Delete entries that started after the invalidation cursor\n db.prepare<[number, string], KeyValueRow>(statements.invalidateDelete).run(\n Number(cursor.orderKey),\n indexerId,\n );\n\n // Update entries that were supposed to end after the invalidation cursor\n db.prepare<[number, string], KeyValueRow>(statements.invalidateUpdate).run(\n Number(cursor.orderKey),\n indexerId,\n );\n}\n\nexport function cleanupKV(db: Database, indexerId: string) {\n assertInTransaction(db);\n\n db.prepare<[string], KeyValueRow>(statements.cleanup).run(indexerId);\n}\n\nexport type KeyValueRow = {\n from_block: number;\n to_block: number;\n k: string;\n v: string;\n id: string;\n};\n\nconst statements = {\n createTable: `\n CREATE TABLE IF NOT EXISTS kvs (\n from_block INTEGER NOT NULL,\n to_block INTEGER,\n k TEXT NOT NULL,\n v BLOB NOT NULL,\n id TEXT NOT NULL,\n PRIMARY KEY (from_block, k, id)\n );`,\n get: `\n SELECT v\n FROM kvs\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n updateToBlock: `\n UPDATE kvs\n SET to_block = ?\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n insertIntoKvs: `\n INSERT INTO kvs (from_block, to_block, k, v, id)\n VALUES (?, NULL, ?, ?, ?)`,\n del: `\n UPDATE kvs\n SET to_block = ?\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n finalize: `\n DELETE FROM kvs\n WHERE to_block <= ? AND id = ?`,\n invalidateDelete: `\n DELETE FROM kvs\n WHERE from_block > ? AND id = ?`,\n invalidateUpdate: `\n UPDATE kvs\n SET to_block = NULL\n WHERE to_block > ? AND id = ?`,\n cleanup: `\n DELETE FROM kvs\n WHERE id = ?`,\n} as const;\n","import { type Cursor, normalizeCursor } from \"@apibara/protocol\";\nimport type { Database } from \"better-sqlite3\";\n\nimport { assertInTransaction, deserialize, serialize } from \"./utils\";\n\nexport function initializePersistentState(db: Database) {\n assertInTransaction(db);\n db.exec(statements.createCheckpointsTable);\n db.exec(statements.createFiltersTable);\n}\n\nexport function persistState<TFilter>(props: {\n db: Database;\n endCursor: Cursor;\n filter?: TFilter;\n indexerId: string;\n}) {\n const { db, endCursor, filter, indexerId } = props;\n\n assertInTransaction(db);\n\n db.prepare(statements.putCheckpoint).run(\n indexerId,\n Number(endCursor.orderKey),\n endCursor.uniqueKey,\n );\n\n if (filter) {\n db.prepare(statements.updateFilterToBlock).run(\n Number(endCursor.orderKey),\n indexerId,\n );\n db.prepare(statements.insertFilter).run(\n indexerId,\n serialize(filter as Record<string, unknown>),\n Number(endCursor.orderKey),\n );\n }\n}\n\nexport function getState<TFilter>(props: {\n db: Database;\n indexerId: string;\n}) {\n const { db, indexerId } = props;\n assertInTransaction(db);\n const storedCursor = db\n .prepare<string, { order_key?: number; unique_key?: string }>(\n statements.getCheckpoint,\n )\n .get(indexerId);\n const storedFilter = db\n .prepare<string, { filter: string }>(statements.getFilter)\n .get(indexerId);\n\n let cursor: Cursor | undefined;\n let filter: TFilter | undefined;\n\n if (storedCursor?.order_key) {\n cursor = normalizeCursor({\n orderKey: BigInt(storedCursor.order_key),\n uniqueKey: storedCursor.unique_key ? storedCursor.unique_key : null,\n });\n }\n\n if (storedFilter) {\n filter = deserialize(storedFilter.filter) as TFilter;\n }\n\n return { cursor, filter };\n}\n\nexport function finalizeState(props: {\n db: Database;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { cursor, db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string, number]>(statements.finalizeFilter).run(\n indexerId,\n Number(cursor.orderKey),\n );\n}\n\nexport function invalidateState(props: {\n db: Database;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { cursor, db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string, number]>(statements.invalidateFilterDelete).run(\n indexerId,\n Number(cursor.orderKey),\n );\n db.prepare<[string, number]>(statements.invalidateFilterUpdate).run(\n indexerId,\n Number(cursor.orderKey),\n );\n}\n\nexport function resetPersistence(props: {\n db: Database;\n indexerId: string;\n}) {\n const { db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string]>(statements.resetCheckpoint).run(indexerId);\n db.prepare<[string]>(statements.resetFilter).run(indexerId);\n}\n\nexport type CheckpointRow = {\n id: string;\n order_key: number;\n unique_key: string | null;\n};\n\nexport type FilterRow = {\n id: string;\n filter: string;\n from_block: number;\n to_block: number | null;\n};\n\nconst statements = {\n createCheckpointsTable: `\n CREATE TABLE IF NOT EXISTS checkpoints (\n id TEXT NOT NULL PRIMARY KEY,\n order_key INTEGER,\n unique_key TEXT\n );`,\n createFiltersTable: `\n CREATE TABLE IF NOT EXISTS filters (\n id TEXT NOT NULL,\n filter BLOB NOT NULL,\n from_block INTEGER NOT NULL,\n to_block INTEGER,\n PRIMARY KEY (id, from_block)\n );`,\n getCheckpoint: `\n SELECT *\n FROM checkpoints\n WHERE id = ?`,\n putCheckpoint: `\n INSERT INTO checkpoints (id, order_key, unique_key)\n VALUES (?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n order_key = excluded.order_key,\n unique_key = excluded.unique_key`,\n delCheckpoint: `\n DELETE FROM checkpoints\n WHERE id = ?`,\n getFilter: `\n SELECT *\n FROM filters\n WHERE id = ? AND to_block IS NULL`,\n updateFilterToBlock: `\n UPDATE filters\n SET to_block = ?\n WHERE id = ? AND to_block IS NULL`,\n insertFilter: `\n INSERT INTO filters (id, filter, from_block)\n VALUES (?, ?, ?)\n ON CONFLICT(id, from_block) DO UPDATE SET\n filter = excluded.filter,\n from_block = excluded.from_block`,\n delFilter: `\n DELETE FROM filters\n WHERE id = ?`,\n finalizeFilter: `\n DELETE FROM filters\n WHERE id = ? AND to_block <= ?`,\n invalidateFilterDelete: `\n DELETE FROM filters\n WHERE id = ? AND from_block > ?`,\n invalidateFilterUpdate: `\n UPDATE filters\n SET to_block = NULL\n WHERE id = ? AND to_block > ?`,\n resetCheckpoint: `\n DELETE FROM checkpoints\n WHERE id = ?`,\n resetFilter: `\n DELETE FROM filters\n WHERE id = ?`,\n};\n","import { useIndexerContext } from \"@apibara/indexer\";\nimport { defineIndexerPlugin, useLogger } from \"@apibara/indexer/plugins\";\nimport type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport type { Database as SqliteDatabase } from \"better-sqlite3\";\n\nimport { generateIndexerId } from \"@apibara/indexer/internal\";\nimport { useInternalContext } from \"@apibara/indexer/internal/plugins\";\nimport {\n KeyValueStore,\n cleanupKV,\n finalizeKV,\n initializeKeyValueStore,\n invalidateKV,\n} from \"./kv\";\nimport {\n finalizeState,\n getState,\n initializePersistentState,\n invalidateState,\n persistState,\n resetPersistence,\n} from \"./persistence\";\nimport {\n type DeserializeFn,\n type SerializeFn,\n SqliteStorageError,\n assertInTransaction,\n deserialize,\n serialize,\n sleep,\n withTransaction,\n} from \"./utils\";\n\nconst KV_PROPERTY = \"_kv_sqlite\" as const;\nconst MAX_RETRIES = 5;\n\nexport { KeyValueStore } from \"./kv\";\n\nexport function useSqliteKeyValueStore(): KeyValueStore {\n const kv = useIndexerContext()[KV_PROPERTY] as KeyValueStore | undefined;\n if (!kv) {\n throw new SqliteStorageError(\n \"SQLite key-value store is not available. Did you forget to enable it?\",\n );\n }\n\n return kv;\n}\n\nexport type SqliteStorageOptions = {\n database: SqliteDatabase;\n keyValueStore?: boolean;\n persistState?: boolean;\n indexerName?: string;\n\n serialize?: SerializeFn;\n deserialize?: DeserializeFn;\n};\n\n/**\n * Creates a plugin that uses SQLite as the storage layer.\n *\n * Supports storing the indexer's state and provides a simple Key-Value store.\n * @param options.database - The SQLite database instance.\n * @param options.persistState - Whether to persist the indexer's state. Defaults to true.\n * @param options.keyValueStore - Whether to enable the Key-Value store. Defaults to true.\n * @param options.serialize - A function to serialize the value to the KV.\n * @param options.deserialize - A function to deserialize the value from the KV.\n * @param options.indexerName - The name of the indexer. Defaults value is 'default'.\n */\nexport function sqliteStorage<TFilter, TBlock>({\n database,\n persistState: enablePersistState = true,\n keyValueStore: enableKeyValueStore = true,\n serialize: serializeFn = serialize,\n deserialize: deserializeFn = deserialize,\n indexerName: identifier = \"default\",\n}: SqliteStorageOptions) {\n return defineIndexerPlugin<TFilter, TBlock>((indexer) => {\n let indexerId = \"\";\n let prevFinality: DataFinality | undefined;\n const alwaysReindex = process.env[\"APIBARA_ALWAYS_REINDEX\"] === \"true\";\n\n indexer.hooks.hook(\"run:before\", async () => {\n const { indexerName: indexerFileName, availableIndexers } =\n useInternalContext();\n\n const logger = useLogger();\n\n indexerId = generateIndexerId(indexerFileName, identifier);\n\n let retries = 0;\n\n let cleanupApplied = false;\n\n while (retries <= MAX_RETRIES) {\n try {\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n initializePersistentState(db);\n }\n\n if (enableKeyValueStore) {\n initializeKeyValueStore(db);\n }\n\n if (alwaysReindex && !cleanupApplied) {\n if (enableKeyValueStore) {\n logger.warn(\"Reindexing: Cleaning up key-value store\");\n cleanupKV(db, indexerId);\n }\n\n if (enablePersistState) {\n logger.warn(\"Reindexing: Resetting persistence state\");\n resetPersistence({ db, indexerId });\n }\n\n cleanupApplied = true;\n\n logger.success(\"All data has been cleaned up for reindexing\");\n }\n });\n break;\n } catch (error) {\n if (retries === MAX_RETRIES) {\n throw new SqliteStorageError(\n \"Initialization failed after 5 retries\",\n {\n cause: error,\n },\n );\n }\n await sleep(retries * 1000);\n retries++;\n }\n }\n });\n\n indexer.hooks.hook(\"connect:before\", async ({ request }) => {\n if (!enablePersistState) {\n return;\n }\n\n return await withTransaction(database, async (db) => {\n const { cursor, filter } = getState<TFilter>({ db, indexerId });\n\n if (cursor) {\n request.startingCursor = cursor;\n }\n\n if (filter) {\n request.filter[1] = filter;\n }\n });\n });\n\n indexer.hooks.hook(\"connect:after\", async ({ request }) => {\n // On restart, we need to invalidate data for blocks that were processed but not persisted.\n const cursor = request.startingCursor;\n\n if (!cursor) {\n return;\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n invalidateState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"connect:factory\", ({ request, endCursor }) => {\n if (!enablePersistState) {\n return;\n }\n\n // The connect factory hook is called while indexing a block, so the database should be in a transaction\n // created by the middleware.\n assertInTransaction(database);\n\n if (endCursor && request.filter[1]) {\n persistState({\n db: database,\n endCursor,\n indexerId,\n filter: request.filter[1],\n });\n }\n });\n\n indexer.hooks.hook(\"message:finalize\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new SqliteStorageError(\"finalized cursor is undefined\");\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n finalizeState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n finalizeKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"message:invalidate\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new SqliteStorageError(\"invalidate cursor is undefined\");\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n invalidateState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"handler:middleware\", ({ use }) => {\n use(async (ctx, next) => {\n const { endCursor, finality, cursor } = ctx as {\n cursor: Cursor;\n endCursor: Cursor;\n finality: DataFinality;\n };\n\n if (!finality) {\n throw new SqliteStorageError(\"finality is undefined\");\n }\n\n if (!endCursor) {\n throw new SqliteStorageError(\n \"endCursor is undefined or not a cursor\",\n );\n }\n\n await withTransaction(database, async (db) => {\n if (prevFinality === \"pending\") {\n // invalidate if previous block's finality was \"pending\"\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n }\n\n if (enableKeyValueStore) {\n ctx[KV_PROPERTY] = new KeyValueStore(\n db,\n endCursor,\n finality,\n serializeFn,\n deserializeFn,\n indexerId,\n );\n }\n\n await next();\n\n if (enablePersistState && finality !== \"pending\") {\n persistState({ db, endCursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n delete ctx[KV_PROPERTY];\n }\n\n prevFinality = finality;\n });\n });\n });\n });\n}\n"],"names":["statements","normalizeCursor","useIndexerContext","defineIndexerPlugin","useInternalContext","useLogger","generateIndexerId"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/utils.ts","../src/kv.ts","../src/persistence.ts","../src/index.ts"],"sourcesContent":["import type { Database } from \"better-sqlite3\";\n\nexport type SerializeFn = <T>(value: T) => string;\nexport type DeserializeFn = <T>(value: string) => T;\n\nexport class SqliteStorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"SqliteStorageError\";\n }\n}\n\nexport async function withTransaction(\n db: Database,\n cb: (db: Database) => Promise<void>,\n) {\n db.prepare(\"BEGIN TRANSACTION\").run();\n try {\n await cb(db);\n } catch (error) {\n db.prepare(\"ROLLBACK TRANSACTION\").run();\n throw error;\n }\n db.prepare(\"COMMIT TRANSACTION\").run();\n}\n\nexport function assertInTransaction(db: Database) {\n if (!db.inTransaction) {\n throw new SqliteStorageError(\"Database is not in transaction\");\n }\n}\n\nexport function deserialize<T>(str: string): T {\n return JSON.parse(str, (_, value) =>\n typeof value === \"string\" && value.match(/^\\d+n$/)\n ? BigInt(value.slice(0, -1))\n : value,\n ) as T;\n}\n\nexport function serialize<T>(obj: T): string {\n return JSON.stringify(\n obj,\n (_, value) => (typeof value === \"bigint\" ? `${value.toString()}n` : value),\n \"\\t\",\n );\n}\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport type { Database } from \"better-sqlite3\";\n\nimport {\n type DeserializeFn,\n type SerializeFn,\n assertInTransaction,\n} from \"./utils\";\n\nexport function initializeKeyValueStore(db: Database) {\n assertInTransaction(db);\n db.exec(statements.createTable);\n}\n\nexport class KeyValueStore {\n constructor(\n private readonly db: Database,\n private readonly endCursor: Cursor,\n private readonly finality: DataFinality,\n private readonly serialize: SerializeFn,\n private readonly deserialize: DeserializeFn,\n private readonly indexerId: string,\n ) {\n assertInTransaction(db);\n }\n\n get<T>(key: string): T | undefined {\n const row = this.db\n .prepare<[string, string], KeyValueRow>(statements.get)\n .get(key, this.indexerId);\n\n return row ? this.deserialize(row.v) : undefined;\n }\n\n put<T>(key: string, value: T) {\n this.db\n .prepare<[number, string, string], KeyValueRow>(statements.updateToBlock)\n .run(Number(this.endCursor.orderKey), key, this.indexerId);\n\n this.db\n .prepare<[number, string, string, string], KeyValueRow>(\n statements.insertIntoKvs,\n )\n .run(\n Number(this.endCursor.orderKey),\n key,\n this.serialize(value as Record<string, unknown>),\n this.indexerId,\n );\n }\n\n del(key: string) {\n this.db\n .prepare<[number, string, string], KeyValueRow>(statements.del)\n .run(Number(this.endCursor.orderKey), key, this.indexerId);\n }\n}\n\nexport function finalizeKV(db: Database, cursor: Cursor, indexerId: string) {\n assertInTransaction(db);\n\n db.prepare<[number, string], KeyValueRow>(statements.finalize).run(\n Number(cursor.orderKey),\n indexerId,\n );\n}\n\nexport function invalidateKV(db: Database, cursor: Cursor, indexerId: string) {\n assertInTransaction(db);\n\n // Delete entries that started after the invalidation cursor\n db.prepare<[number, string], KeyValueRow>(statements.invalidateDelete).run(\n Number(cursor.orderKey),\n indexerId,\n );\n\n // Update entries that were supposed to end after the invalidation cursor\n db.prepare<[number, string], KeyValueRow>(statements.invalidateUpdate).run(\n Number(cursor.orderKey),\n indexerId,\n );\n}\n\nexport function cleanupKV(db: Database, indexerId: string) {\n assertInTransaction(db);\n\n db.prepare<[string], KeyValueRow>(statements.cleanup).run(indexerId);\n}\n\nexport type KeyValueRow = {\n from_block: number;\n to_block: number;\n k: string;\n v: string;\n id: string;\n};\n\nconst statements = {\n createTable: `\n CREATE TABLE IF NOT EXISTS kvs (\n from_block INTEGER NOT NULL,\n to_block INTEGER,\n k TEXT NOT NULL,\n v BLOB NOT NULL,\n id TEXT NOT NULL,\n PRIMARY KEY (from_block, k, id)\n );`,\n get: `\n SELECT v\n FROM kvs\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n updateToBlock: `\n UPDATE kvs\n SET to_block = ?\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n insertIntoKvs: `\n INSERT INTO kvs (from_block, to_block, k, v, id)\n VALUES (?, NULL, ?, ?, ?)`,\n del: `\n UPDATE kvs\n SET to_block = ?\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n finalize: `\n DELETE FROM kvs\n WHERE to_block <= ? AND id = ?`,\n invalidateDelete: `\n DELETE FROM kvs\n WHERE from_block > ? AND id = ?`,\n invalidateUpdate: `\n UPDATE kvs\n SET to_block = NULL\n WHERE to_block > ? AND id = ?`,\n cleanup: `\n DELETE FROM kvs\n WHERE id = ?`,\n} as const;\n","import { type Cursor, normalizeCursor } from \"@apibara/protocol\";\nimport type { Database } from \"better-sqlite3\";\n\nimport { assertInTransaction, deserialize, serialize } from \"./utils\";\n\nexport function initializePersistentState(db: Database) {\n assertInTransaction(db);\n db.exec(statements.createCheckpointsTable);\n db.exec(statements.createFiltersTable);\n}\n\nexport function persistState<TFilter>(props: {\n db: Database;\n endCursor: Cursor;\n filter?: TFilter;\n indexerId: string;\n}) {\n const { db, endCursor, filter, indexerId } = props;\n\n assertInTransaction(db);\n\n db.prepare(statements.putCheckpoint).run(\n indexerId,\n Number(endCursor.orderKey),\n endCursor.uniqueKey,\n );\n\n if (filter) {\n db.prepare(statements.updateFilterToBlock).run(\n Number(endCursor.orderKey),\n indexerId,\n );\n db.prepare(statements.insertFilter).run(\n indexerId,\n serialize(filter as Record<string, unknown>),\n Number(endCursor.orderKey),\n );\n }\n}\n\nexport function getState<TFilter>(props: {\n db: Database;\n indexerId: string;\n}) {\n const { db, indexerId } = props;\n assertInTransaction(db);\n const storedCursor = db\n .prepare<string, { order_key?: number; unique_key?: string }>(\n statements.getCheckpoint,\n )\n .get(indexerId);\n const storedFilter = db\n .prepare<string, { filter: string }>(statements.getFilter)\n .get(indexerId);\n\n let cursor: Cursor | undefined;\n let filter: TFilter | undefined;\n\n if (storedCursor?.order_key) {\n cursor = normalizeCursor({\n orderKey: BigInt(storedCursor.order_key),\n uniqueKey: storedCursor.unique_key ? storedCursor.unique_key : null,\n });\n }\n\n if (storedFilter) {\n filter = deserialize(storedFilter.filter) as TFilter;\n }\n\n return { cursor, filter };\n}\n\nexport function finalizeState(props: {\n db: Database;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { cursor, db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string, number]>(statements.finalizeFilter).run(\n indexerId,\n Number(cursor.orderKey),\n );\n}\n\nexport function invalidateState(props: {\n db: Database;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { cursor, db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string, number]>(statements.invalidateFilterDelete).run(\n indexerId,\n Number(cursor.orderKey),\n );\n db.prepare<[string, number]>(statements.invalidateFilterUpdate).run(\n indexerId,\n Number(cursor.orderKey),\n );\n}\n\nexport function resetPersistence(props: {\n db: Database;\n indexerId: string;\n}) {\n const { db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string]>(statements.resetCheckpoint).run(indexerId);\n db.prepare<[string]>(statements.resetFilter).run(indexerId);\n}\n\nexport type CheckpointRow = {\n id: string;\n order_key: number;\n unique_key: string | null;\n};\n\nexport type FilterRow = {\n id: string;\n filter: string;\n from_block: number;\n to_block: number | null;\n};\n\nconst statements = {\n createCheckpointsTable: `\n CREATE TABLE IF NOT EXISTS checkpoints (\n id TEXT NOT NULL PRIMARY KEY,\n order_key INTEGER,\n unique_key TEXT\n );`,\n createFiltersTable: `\n CREATE TABLE IF NOT EXISTS filters (\n id TEXT NOT NULL,\n filter BLOB NOT NULL,\n from_block INTEGER NOT NULL,\n to_block INTEGER,\n PRIMARY KEY (id, from_block)\n );`,\n getCheckpoint: `\n SELECT *\n FROM checkpoints\n WHERE id = ?`,\n putCheckpoint: `\n INSERT INTO checkpoints (id, order_key, unique_key)\n VALUES (?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n order_key = excluded.order_key,\n unique_key = excluded.unique_key`,\n delCheckpoint: `\n DELETE FROM checkpoints\n WHERE id = ?`,\n getFilter: `\n SELECT *\n FROM filters\n WHERE id = ? AND to_block IS NULL`,\n updateFilterToBlock: `\n UPDATE filters\n SET to_block = ?\n WHERE id = ? AND to_block IS NULL`,\n insertFilter: `\n INSERT INTO filters (id, filter, from_block)\n VALUES (?, ?, ?)\n ON CONFLICT(id, from_block) DO UPDATE SET\n filter = excluded.filter,\n from_block = excluded.from_block`,\n delFilter: `\n DELETE FROM filters\n WHERE id = ?`,\n finalizeFilter: `\n DELETE FROM filters\n WHERE id = ? AND to_block <= ?`,\n invalidateFilterDelete: `\n DELETE FROM filters\n WHERE id = ? AND from_block > ?`,\n invalidateFilterUpdate: `\n UPDATE filters\n SET to_block = NULL\n WHERE id = ? AND to_block > ?`,\n resetCheckpoint: `\n DELETE FROM checkpoints\n WHERE id = ?`,\n resetFilter: `\n DELETE FROM filters\n WHERE id = ?`,\n};\n","import { useIndexerContext } from \"@apibara/indexer\";\nimport { defineIndexerPlugin, useLogger } from \"@apibara/indexer/plugins\";\nimport type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport type { Database as SqliteDatabase } from \"better-sqlite3\";\n\nimport { generateIndexerId } from \"@apibara/indexer/internal\";\nimport { useInternalContext } from \"@apibara/indexer/internal/plugins\";\nimport {\n KeyValueStore,\n cleanupKV,\n finalizeKV,\n initializeKeyValueStore,\n invalidateKV,\n} from \"./kv\";\nimport {\n finalizeState,\n getState,\n initializePersistentState,\n invalidateState,\n persistState,\n resetPersistence,\n} from \"./persistence\";\nimport {\n type DeserializeFn,\n type SerializeFn,\n SqliteStorageError,\n assertInTransaction,\n deserialize,\n serialize,\n sleep,\n withTransaction,\n} from \"./utils\";\n\nconst KV_PROPERTY = \"_kv_sqlite\" as const;\nconst MAX_RETRIES = 5;\n\nexport { KeyValueStore } from \"./kv\";\n\nexport function useSqliteKeyValueStore(): KeyValueStore {\n const kv = useIndexerContext()[KV_PROPERTY] as KeyValueStore | undefined;\n if (!kv) {\n throw new SqliteStorageError(\n \"SQLite key-value store is not available. Did you forget to enable it?\",\n );\n }\n\n return kv;\n}\n\nexport type SqliteStorageOptions = {\n database: SqliteDatabase;\n keyValueStore?: boolean;\n persistState?: boolean;\n indexerName?: string;\n\n serialize?: SerializeFn;\n deserialize?: DeserializeFn;\n};\n\n/**\n * Creates a plugin that uses SQLite as the storage layer.\n *\n * Supports storing the indexer's state and provides a simple Key-Value store.\n * @param options.database - The SQLite database instance.\n * @param options.persistState - Whether to persist the indexer's state. Defaults to true.\n * @param options.keyValueStore - Whether to enable the Key-Value store. Defaults to true.\n * @param options.serialize - A function to serialize the value to the KV.\n * @param options.deserialize - A function to deserialize the value from the KV.\n * @param options.indexerName - The name of the indexer. Defaults value is 'default'.\n */\nexport function sqliteStorage<TFilter, TBlock>({\n database,\n persistState: enablePersistState = true,\n keyValueStore: enableKeyValueStore = true,\n serialize: serializeFn = serialize,\n deserialize: deserializeFn = deserialize,\n indexerName: identifier = \"default\",\n}: SqliteStorageOptions) {\n return defineIndexerPlugin<TFilter, TBlock>((indexer) => {\n let indexerId = \"\";\n let prevFinality: DataFinality | undefined;\n const alwaysReindex = process.env[\"APIBARA_ALWAYS_REINDEX\"] === \"true\";\n\n indexer.hooks.hook(\"plugins:init\", async () => {\n const { indexerName: indexerFileName, availableIndexers } =\n useInternalContext();\n\n const logger = useLogger();\n\n indexerId = generateIndexerId(indexerFileName, identifier);\n\n let retries = 0;\n\n let cleanupApplied = false;\n\n while (retries <= MAX_RETRIES) {\n try {\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n initializePersistentState(db);\n }\n\n if (enableKeyValueStore) {\n initializeKeyValueStore(db);\n }\n\n if (alwaysReindex && !cleanupApplied) {\n if (enableKeyValueStore) {\n logger.warn(\"Reindexing: Cleaning up key-value store\");\n cleanupKV(db, indexerId);\n }\n\n if (enablePersistState) {\n logger.warn(\"Reindexing: Resetting persistence state\");\n resetPersistence({ db, indexerId });\n }\n\n cleanupApplied = true;\n\n logger.success(\"All data has been cleaned up for reindexing\");\n }\n });\n break;\n } catch (error) {\n if (retries === MAX_RETRIES) {\n throw new SqliteStorageError(\n \"Initialization failed after 5 retries\",\n {\n cause: error,\n },\n );\n }\n await sleep(retries * 1000);\n retries++;\n }\n }\n });\n\n indexer.hooks.hook(\"connect:before\", async ({ request }) => {\n if (!enablePersistState) {\n return;\n }\n\n return await withTransaction(database, async (db) => {\n const { cursor, filter } = getState<TFilter>({ db, indexerId });\n\n if (cursor) {\n request.startingCursor = cursor;\n }\n\n if (filter) {\n request.filter[1] = filter;\n }\n });\n });\n\n indexer.hooks.hook(\"connect:after\", async ({ request }) => {\n // On restart, we need to invalidate data for blocks that were processed but not persisted.\n const cursor = request.startingCursor;\n\n if (!cursor) {\n return;\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n invalidateState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"connect:factory\", ({ request, endCursor }) => {\n if (!enablePersistState) {\n return;\n }\n\n // The connect factory hook is called while indexing a block, so the database should be in a transaction\n // created by the middleware.\n assertInTransaction(database);\n\n if (endCursor && request.filter[1]) {\n persistState({\n db: database,\n endCursor,\n indexerId,\n filter: request.filter[1],\n });\n }\n });\n\n indexer.hooks.hook(\"message:finalize\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new SqliteStorageError(\"finalized cursor is undefined\");\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n finalizeState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n finalizeKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"message:invalidate\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new SqliteStorageError(\"invalidate cursor is undefined\");\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n invalidateState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"handler:middleware\", ({ use }) => {\n use(async (ctx, next) => {\n const { endCursor, finality, cursor } = ctx as {\n cursor: Cursor;\n endCursor: Cursor;\n finality: DataFinality;\n };\n\n if (!finality) {\n throw new SqliteStorageError(\"finality is undefined\");\n }\n\n if (!endCursor) {\n throw new SqliteStorageError(\n \"endCursor is undefined or not a cursor\",\n );\n }\n\n await withTransaction(database, async (db) => {\n if (prevFinality === \"pending\") {\n // invalidate if previous block's finality was \"pending\"\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n }\n\n if (enableKeyValueStore) {\n ctx[KV_PROPERTY] = new KeyValueStore(\n db,\n endCursor,\n finality,\n serializeFn,\n deserializeFn,\n indexerId,\n );\n }\n\n await next();\n\n if (enablePersistState && finality !== \"pending\") {\n persistState({ db, endCursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n delete ctx[KV_PROPERTY];\n }\n\n prevFinality = finality;\n });\n });\n });\n });\n}\n"],"names":["statements","normalizeCursor","useIndexerContext","defineIndexerPlugin","useInternalContext","useLogger","generateIndexerId"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -294,7 +294,7 @@ function sqliteStorage({
294
294
  let indexerId = "";
295
295
  let prevFinality;
296
296
  const alwaysReindex = process.env["APIBARA_ALWAYS_REINDEX"] === "true";
297
- indexer.hooks.hook("run:before", async () => {
297
+ indexer.hooks.hook("plugins:init", async () => {
298
298
  const { indexerName: indexerFileName, availableIndexers } = useInternalContext();
299
299
  const logger = useLogger();
300
300
  indexerId = generateIndexerId(indexerFileName, identifier);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/utils.ts","../src/kv.ts","../src/persistence.ts","../src/index.ts"],"sourcesContent":["import type { Database } from \"better-sqlite3\";\n\nexport type SerializeFn = <T>(value: T) => string;\nexport type DeserializeFn = <T>(value: string) => T;\n\nexport class SqliteStorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"SqliteStorageError\";\n }\n}\n\nexport async function withTransaction(\n db: Database,\n cb: (db: Database) => Promise<void>,\n) {\n db.prepare(\"BEGIN TRANSACTION\").run();\n try {\n await cb(db);\n } catch (error) {\n db.prepare(\"ROLLBACK TRANSACTION\").run();\n throw error;\n }\n db.prepare(\"COMMIT TRANSACTION\").run();\n}\n\nexport function assertInTransaction(db: Database) {\n if (!db.inTransaction) {\n throw new SqliteStorageError(\"Database is not in transaction\");\n }\n}\n\nexport function deserialize<T>(str: string): T {\n return JSON.parse(str, (_, value) =>\n typeof value === \"string\" && value.match(/^\\d+n$/)\n ? BigInt(value.slice(0, -1))\n : value,\n ) as T;\n}\n\nexport function serialize<T>(obj: T): string {\n return JSON.stringify(\n obj,\n (_, value) => (typeof value === \"bigint\" ? `${value.toString()}n` : value),\n \"\\t\",\n );\n}\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport type { Database } from \"better-sqlite3\";\n\nimport {\n type DeserializeFn,\n type SerializeFn,\n assertInTransaction,\n} from \"./utils\";\n\nexport function initializeKeyValueStore(db: Database) {\n assertInTransaction(db);\n db.exec(statements.createTable);\n}\n\nexport class KeyValueStore {\n constructor(\n private readonly db: Database,\n private readonly endCursor: Cursor,\n private readonly finality: DataFinality,\n private readonly serialize: SerializeFn,\n private readonly deserialize: DeserializeFn,\n private readonly indexerId: string,\n ) {\n assertInTransaction(db);\n }\n\n get<T>(key: string): T | undefined {\n const row = this.db\n .prepare<[string, string], KeyValueRow>(statements.get)\n .get(key, this.indexerId);\n\n return row ? this.deserialize(row.v) : undefined;\n }\n\n put<T>(key: string, value: T) {\n this.db\n .prepare<[number, string, string], KeyValueRow>(statements.updateToBlock)\n .run(Number(this.endCursor.orderKey), key, this.indexerId);\n\n this.db\n .prepare<[number, string, string, string], KeyValueRow>(\n statements.insertIntoKvs,\n )\n .run(\n Number(this.endCursor.orderKey),\n key,\n this.serialize(value as Record<string, unknown>),\n this.indexerId,\n );\n }\n\n del(key: string) {\n this.db\n .prepare<[number, string, string], KeyValueRow>(statements.del)\n .run(Number(this.endCursor.orderKey), key, this.indexerId);\n }\n}\n\nexport function finalizeKV(db: Database, cursor: Cursor, indexerId: string) {\n assertInTransaction(db);\n\n db.prepare<[number, string], KeyValueRow>(statements.finalize).run(\n Number(cursor.orderKey),\n indexerId,\n );\n}\n\nexport function invalidateKV(db: Database, cursor: Cursor, indexerId: string) {\n assertInTransaction(db);\n\n // Delete entries that started after the invalidation cursor\n db.prepare<[number, string], KeyValueRow>(statements.invalidateDelete).run(\n Number(cursor.orderKey),\n indexerId,\n );\n\n // Update entries that were supposed to end after the invalidation cursor\n db.prepare<[number, string], KeyValueRow>(statements.invalidateUpdate).run(\n Number(cursor.orderKey),\n indexerId,\n );\n}\n\nexport function cleanupKV(db: Database, indexerId: string) {\n assertInTransaction(db);\n\n db.prepare<[string], KeyValueRow>(statements.cleanup).run(indexerId);\n}\n\nexport type KeyValueRow = {\n from_block: number;\n to_block: number;\n k: string;\n v: string;\n id: string;\n};\n\nconst statements = {\n createTable: `\n CREATE TABLE IF NOT EXISTS kvs (\n from_block INTEGER NOT NULL,\n to_block INTEGER,\n k TEXT NOT NULL,\n v BLOB NOT NULL,\n id TEXT NOT NULL,\n PRIMARY KEY (from_block, k, id)\n );`,\n get: `\n SELECT v\n FROM kvs\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n updateToBlock: `\n UPDATE kvs\n SET to_block = ?\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n insertIntoKvs: `\n INSERT INTO kvs (from_block, to_block, k, v, id)\n VALUES (?, NULL, ?, ?, ?)`,\n del: `\n UPDATE kvs\n SET to_block = ?\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n finalize: `\n DELETE FROM kvs\n WHERE to_block <= ? AND id = ?`,\n invalidateDelete: `\n DELETE FROM kvs\n WHERE from_block > ? AND id = ?`,\n invalidateUpdate: `\n UPDATE kvs\n SET to_block = NULL\n WHERE to_block > ? AND id = ?`,\n cleanup: `\n DELETE FROM kvs\n WHERE id = ?`,\n} as const;\n","import { type Cursor, normalizeCursor } from \"@apibara/protocol\";\nimport type { Database } from \"better-sqlite3\";\n\nimport { assertInTransaction, deserialize, serialize } from \"./utils\";\n\nexport function initializePersistentState(db: Database) {\n assertInTransaction(db);\n db.exec(statements.createCheckpointsTable);\n db.exec(statements.createFiltersTable);\n}\n\nexport function persistState<TFilter>(props: {\n db: Database;\n endCursor: Cursor;\n filter?: TFilter;\n indexerId: string;\n}) {\n const { db, endCursor, filter, indexerId } = props;\n\n assertInTransaction(db);\n\n db.prepare(statements.putCheckpoint).run(\n indexerId,\n Number(endCursor.orderKey),\n endCursor.uniqueKey,\n );\n\n if (filter) {\n db.prepare(statements.updateFilterToBlock).run(\n Number(endCursor.orderKey),\n indexerId,\n );\n db.prepare(statements.insertFilter).run(\n indexerId,\n serialize(filter as Record<string, unknown>),\n Number(endCursor.orderKey),\n );\n }\n}\n\nexport function getState<TFilter>(props: {\n db: Database;\n indexerId: string;\n}) {\n const { db, indexerId } = props;\n assertInTransaction(db);\n const storedCursor = db\n .prepare<string, { order_key?: number; unique_key?: string }>(\n statements.getCheckpoint,\n )\n .get(indexerId);\n const storedFilter = db\n .prepare<string, { filter: string }>(statements.getFilter)\n .get(indexerId);\n\n let cursor: Cursor | undefined;\n let filter: TFilter | undefined;\n\n if (storedCursor?.order_key) {\n cursor = normalizeCursor({\n orderKey: BigInt(storedCursor.order_key),\n uniqueKey: storedCursor.unique_key ? storedCursor.unique_key : null,\n });\n }\n\n if (storedFilter) {\n filter = deserialize(storedFilter.filter) as TFilter;\n }\n\n return { cursor, filter };\n}\n\nexport function finalizeState(props: {\n db: Database;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { cursor, db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string, number]>(statements.finalizeFilter).run(\n indexerId,\n Number(cursor.orderKey),\n );\n}\n\nexport function invalidateState(props: {\n db: Database;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { cursor, db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string, number]>(statements.invalidateFilterDelete).run(\n indexerId,\n Number(cursor.orderKey),\n );\n db.prepare<[string, number]>(statements.invalidateFilterUpdate).run(\n indexerId,\n Number(cursor.orderKey),\n );\n}\n\nexport function resetPersistence(props: {\n db: Database;\n indexerId: string;\n}) {\n const { db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string]>(statements.resetCheckpoint).run(indexerId);\n db.prepare<[string]>(statements.resetFilter).run(indexerId);\n}\n\nexport type CheckpointRow = {\n id: string;\n order_key: number;\n unique_key: string | null;\n};\n\nexport type FilterRow = {\n id: string;\n filter: string;\n from_block: number;\n to_block: number | null;\n};\n\nconst statements = {\n createCheckpointsTable: `\n CREATE TABLE IF NOT EXISTS checkpoints (\n id TEXT NOT NULL PRIMARY KEY,\n order_key INTEGER,\n unique_key TEXT\n );`,\n createFiltersTable: `\n CREATE TABLE IF NOT EXISTS filters (\n id TEXT NOT NULL,\n filter BLOB NOT NULL,\n from_block INTEGER NOT NULL,\n to_block INTEGER,\n PRIMARY KEY (id, from_block)\n );`,\n getCheckpoint: `\n SELECT *\n FROM checkpoints\n WHERE id = ?`,\n putCheckpoint: `\n INSERT INTO checkpoints (id, order_key, unique_key)\n VALUES (?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n order_key = excluded.order_key,\n unique_key = excluded.unique_key`,\n delCheckpoint: `\n DELETE FROM checkpoints\n WHERE id = ?`,\n getFilter: `\n SELECT *\n FROM filters\n WHERE id = ? AND to_block IS NULL`,\n updateFilterToBlock: `\n UPDATE filters\n SET to_block = ?\n WHERE id = ? AND to_block IS NULL`,\n insertFilter: `\n INSERT INTO filters (id, filter, from_block)\n VALUES (?, ?, ?)\n ON CONFLICT(id, from_block) DO UPDATE SET\n filter = excluded.filter,\n from_block = excluded.from_block`,\n delFilter: `\n DELETE FROM filters\n WHERE id = ?`,\n finalizeFilter: `\n DELETE FROM filters\n WHERE id = ? AND to_block <= ?`,\n invalidateFilterDelete: `\n DELETE FROM filters\n WHERE id = ? AND from_block > ?`,\n invalidateFilterUpdate: `\n UPDATE filters\n SET to_block = NULL\n WHERE id = ? AND to_block > ?`,\n resetCheckpoint: `\n DELETE FROM checkpoints\n WHERE id = ?`,\n resetFilter: `\n DELETE FROM filters\n WHERE id = ?`,\n};\n","import { useIndexerContext } from \"@apibara/indexer\";\nimport { defineIndexerPlugin, useLogger } from \"@apibara/indexer/plugins\";\nimport type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport type { Database as SqliteDatabase } from \"better-sqlite3\";\n\nimport { generateIndexerId } from \"@apibara/indexer/internal\";\nimport { useInternalContext } from \"@apibara/indexer/internal/plugins\";\nimport {\n KeyValueStore,\n cleanupKV,\n finalizeKV,\n initializeKeyValueStore,\n invalidateKV,\n} from \"./kv\";\nimport {\n finalizeState,\n getState,\n initializePersistentState,\n invalidateState,\n persistState,\n resetPersistence,\n} from \"./persistence\";\nimport {\n type DeserializeFn,\n type SerializeFn,\n SqliteStorageError,\n assertInTransaction,\n deserialize,\n serialize,\n sleep,\n withTransaction,\n} from \"./utils\";\n\nconst KV_PROPERTY = \"_kv_sqlite\" as const;\nconst MAX_RETRIES = 5;\n\nexport { KeyValueStore } from \"./kv\";\n\nexport function useSqliteKeyValueStore(): KeyValueStore {\n const kv = useIndexerContext()[KV_PROPERTY] as KeyValueStore | undefined;\n if (!kv) {\n throw new SqliteStorageError(\n \"SQLite key-value store is not available. Did you forget to enable it?\",\n );\n }\n\n return kv;\n}\n\nexport type SqliteStorageOptions = {\n database: SqliteDatabase;\n keyValueStore?: boolean;\n persistState?: boolean;\n indexerName?: string;\n\n serialize?: SerializeFn;\n deserialize?: DeserializeFn;\n};\n\n/**\n * Creates a plugin that uses SQLite as the storage layer.\n *\n * Supports storing the indexer's state and provides a simple Key-Value store.\n * @param options.database - The SQLite database instance.\n * @param options.persistState - Whether to persist the indexer's state. Defaults to true.\n * @param options.keyValueStore - Whether to enable the Key-Value store. Defaults to true.\n * @param options.serialize - A function to serialize the value to the KV.\n * @param options.deserialize - A function to deserialize the value from the KV.\n * @param options.indexerName - The name of the indexer. Defaults value is 'default'.\n */\nexport function sqliteStorage<TFilter, TBlock>({\n database,\n persistState: enablePersistState = true,\n keyValueStore: enableKeyValueStore = true,\n serialize: serializeFn = serialize,\n deserialize: deserializeFn = deserialize,\n indexerName: identifier = \"default\",\n}: SqliteStorageOptions) {\n return defineIndexerPlugin<TFilter, TBlock>((indexer) => {\n let indexerId = \"\";\n let prevFinality: DataFinality | undefined;\n const alwaysReindex = process.env[\"APIBARA_ALWAYS_REINDEX\"] === \"true\";\n\n indexer.hooks.hook(\"run:before\", async () => {\n const { indexerName: indexerFileName, availableIndexers } =\n useInternalContext();\n\n const logger = useLogger();\n\n indexerId = generateIndexerId(indexerFileName, identifier);\n\n let retries = 0;\n\n let cleanupApplied = false;\n\n while (retries <= MAX_RETRIES) {\n try {\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n initializePersistentState(db);\n }\n\n if (enableKeyValueStore) {\n initializeKeyValueStore(db);\n }\n\n if (alwaysReindex && !cleanupApplied) {\n if (enableKeyValueStore) {\n logger.warn(\"Reindexing: Cleaning up key-value store\");\n cleanupKV(db, indexerId);\n }\n\n if (enablePersistState) {\n logger.warn(\"Reindexing: Resetting persistence state\");\n resetPersistence({ db, indexerId });\n }\n\n cleanupApplied = true;\n\n logger.success(\"All data has been cleaned up for reindexing\");\n }\n });\n break;\n } catch (error) {\n if (retries === MAX_RETRIES) {\n throw new SqliteStorageError(\n \"Initialization failed after 5 retries\",\n {\n cause: error,\n },\n );\n }\n await sleep(retries * 1000);\n retries++;\n }\n }\n });\n\n indexer.hooks.hook(\"connect:before\", async ({ request }) => {\n if (!enablePersistState) {\n return;\n }\n\n return await withTransaction(database, async (db) => {\n const { cursor, filter } = getState<TFilter>({ db, indexerId });\n\n if (cursor) {\n request.startingCursor = cursor;\n }\n\n if (filter) {\n request.filter[1] = filter;\n }\n });\n });\n\n indexer.hooks.hook(\"connect:after\", async ({ request }) => {\n // On restart, we need to invalidate data for blocks that were processed but not persisted.\n const cursor = request.startingCursor;\n\n if (!cursor) {\n return;\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n invalidateState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"connect:factory\", ({ request, endCursor }) => {\n if (!enablePersistState) {\n return;\n }\n\n // The connect factory hook is called while indexing a block, so the database should be in a transaction\n // created by the middleware.\n assertInTransaction(database);\n\n if (endCursor && request.filter[1]) {\n persistState({\n db: database,\n endCursor,\n indexerId,\n filter: request.filter[1],\n });\n }\n });\n\n indexer.hooks.hook(\"message:finalize\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new SqliteStorageError(\"finalized cursor is undefined\");\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n finalizeState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n finalizeKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"message:invalidate\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new SqliteStorageError(\"invalidate cursor is undefined\");\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n invalidateState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"handler:middleware\", ({ use }) => {\n use(async (ctx, next) => {\n const { endCursor, finality, cursor } = ctx as {\n cursor: Cursor;\n endCursor: Cursor;\n finality: DataFinality;\n };\n\n if (!finality) {\n throw new SqliteStorageError(\"finality is undefined\");\n }\n\n if (!endCursor) {\n throw new SqliteStorageError(\n \"endCursor is undefined or not a cursor\",\n );\n }\n\n await withTransaction(database, async (db) => {\n if (prevFinality === \"pending\") {\n // invalidate if previous block's finality was \"pending\"\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n }\n\n if (enableKeyValueStore) {\n ctx[KV_PROPERTY] = new KeyValueStore(\n db,\n endCursor,\n finality,\n serializeFn,\n deserializeFn,\n indexerId,\n );\n }\n\n await next();\n\n if (enablePersistState && finality !== \"pending\") {\n persistState({ db, endCursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n delete ctx[KV_PROPERTY];\n }\n\n prevFinality = finality;\n });\n });\n });\n });\n}\n"],"names":["statements"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/utils.ts","../src/kv.ts","../src/persistence.ts","../src/index.ts"],"sourcesContent":["import type { Database } from \"better-sqlite3\";\n\nexport type SerializeFn = <T>(value: T) => string;\nexport type DeserializeFn = <T>(value: string) => T;\n\nexport class SqliteStorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"SqliteStorageError\";\n }\n}\n\nexport async function withTransaction(\n db: Database,\n cb: (db: Database) => Promise<void>,\n) {\n db.prepare(\"BEGIN TRANSACTION\").run();\n try {\n await cb(db);\n } catch (error) {\n db.prepare(\"ROLLBACK TRANSACTION\").run();\n throw error;\n }\n db.prepare(\"COMMIT TRANSACTION\").run();\n}\n\nexport function assertInTransaction(db: Database) {\n if (!db.inTransaction) {\n throw new SqliteStorageError(\"Database is not in transaction\");\n }\n}\n\nexport function deserialize<T>(str: string): T {\n return JSON.parse(str, (_, value) =>\n typeof value === \"string\" && value.match(/^\\d+n$/)\n ? BigInt(value.slice(0, -1))\n : value,\n ) as T;\n}\n\nexport function serialize<T>(obj: T): string {\n return JSON.stringify(\n obj,\n (_, value) => (typeof value === \"bigint\" ? `${value.toString()}n` : value),\n \"\\t\",\n );\n}\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport type { Database } from \"better-sqlite3\";\n\nimport {\n type DeserializeFn,\n type SerializeFn,\n assertInTransaction,\n} from \"./utils\";\n\nexport function initializeKeyValueStore(db: Database) {\n assertInTransaction(db);\n db.exec(statements.createTable);\n}\n\nexport class KeyValueStore {\n constructor(\n private readonly db: Database,\n private readonly endCursor: Cursor,\n private readonly finality: DataFinality,\n private readonly serialize: SerializeFn,\n private readonly deserialize: DeserializeFn,\n private readonly indexerId: string,\n ) {\n assertInTransaction(db);\n }\n\n get<T>(key: string): T | undefined {\n const row = this.db\n .prepare<[string, string], KeyValueRow>(statements.get)\n .get(key, this.indexerId);\n\n return row ? this.deserialize(row.v) : undefined;\n }\n\n put<T>(key: string, value: T) {\n this.db\n .prepare<[number, string, string], KeyValueRow>(statements.updateToBlock)\n .run(Number(this.endCursor.orderKey), key, this.indexerId);\n\n this.db\n .prepare<[number, string, string, string], KeyValueRow>(\n statements.insertIntoKvs,\n )\n .run(\n Number(this.endCursor.orderKey),\n key,\n this.serialize(value as Record<string, unknown>),\n this.indexerId,\n );\n }\n\n del(key: string) {\n this.db\n .prepare<[number, string, string], KeyValueRow>(statements.del)\n .run(Number(this.endCursor.orderKey), key, this.indexerId);\n }\n}\n\nexport function finalizeKV(db: Database, cursor: Cursor, indexerId: string) {\n assertInTransaction(db);\n\n db.prepare<[number, string], KeyValueRow>(statements.finalize).run(\n Number(cursor.orderKey),\n indexerId,\n );\n}\n\nexport function invalidateKV(db: Database, cursor: Cursor, indexerId: string) {\n assertInTransaction(db);\n\n // Delete entries that started after the invalidation cursor\n db.prepare<[number, string], KeyValueRow>(statements.invalidateDelete).run(\n Number(cursor.orderKey),\n indexerId,\n );\n\n // Update entries that were supposed to end after the invalidation cursor\n db.prepare<[number, string], KeyValueRow>(statements.invalidateUpdate).run(\n Number(cursor.orderKey),\n indexerId,\n );\n}\n\nexport function cleanupKV(db: Database, indexerId: string) {\n assertInTransaction(db);\n\n db.prepare<[string], KeyValueRow>(statements.cleanup).run(indexerId);\n}\n\nexport type KeyValueRow = {\n from_block: number;\n to_block: number;\n k: string;\n v: string;\n id: string;\n};\n\nconst statements = {\n createTable: `\n CREATE TABLE IF NOT EXISTS kvs (\n from_block INTEGER NOT NULL,\n to_block INTEGER,\n k TEXT NOT NULL,\n v BLOB NOT NULL,\n id TEXT NOT NULL,\n PRIMARY KEY (from_block, k, id)\n );`,\n get: `\n SELECT v\n FROM kvs\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n updateToBlock: `\n UPDATE kvs\n SET to_block = ?\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n insertIntoKvs: `\n INSERT INTO kvs (from_block, to_block, k, v, id)\n VALUES (?, NULL, ?, ?, ?)`,\n del: `\n UPDATE kvs\n SET to_block = ?\n WHERE k = ? AND id = ? AND to_block IS NULL`,\n finalize: `\n DELETE FROM kvs\n WHERE to_block <= ? AND id = ?`,\n invalidateDelete: `\n DELETE FROM kvs\n WHERE from_block > ? AND id = ?`,\n invalidateUpdate: `\n UPDATE kvs\n SET to_block = NULL\n WHERE to_block > ? AND id = ?`,\n cleanup: `\n DELETE FROM kvs\n WHERE id = ?`,\n} as const;\n","import { type Cursor, normalizeCursor } from \"@apibara/protocol\";\nimport type { Database } from \"better-sqlite3\";\n\nimport { assertInTransaction, deserialize, serialize } from \"./utils\";\n\nexport function initializePersistentState(db: Database) {\n assertInTransaction(db);\n db.exec(statements.createCheckpointsTable);\n db.exec(statements.createFiltersTable);\n}\n\nexport function persistState<TFilter>(props: {\n db: Database;\n endCursor: Cursor;\n filter?: TFilter;\n indexerId: string;\n}) {\n const { db, endCursor, filter, indexerId } = props;\n\n assertInTransaction(db);\n\n db.prepare(statements.putCheckpoint).run(\n indexerId,\n Number(endCursor.orderKey),\n endCursor.uniqueKey,\n );\n\n if (filter) {\n db.prepare(statements.updateFilterToBlock).run(\n Number(endCursor.orderKey),\n indexerId,\n );\n db.prepare(statements.insertFilter).run(\n indexerId,\n serialize(filter as Record<string, unknown>),\n Number(endCursor.orderKey),\n );\n }\n}\n\nexport function getState<TFilter>(props: {\n db: Database;\n indexerId: string;\n}) {\n const { db, indexerId } = props;\n assertInTransaction(db);\n const storedCursor = db\n .prepare<string, { order_key?: number; unique_key?: string }>(\n statements.getCheckpoint,\n )\n .get(indexerId);\n const storedFilter = db\n .prepare<string, { filter: string }>(statements.getFilter)\n .get(indexerId);\n\n let cursor: Cursor | undefined;\n let filter: TFilter | undefined;\n\n if (storedCursor?.order_key) {\n cursor = normalizeCursor({\n orderKey: BigInt(storedCursor.order_key),\n uniqueKey: storedCursor.unique_key ? storedCursor.unique_key : null,\n });\n }\n\n if (storedFilter) {\n filter = deserialize(storedFilter.filter) as TFilter;\n }\n\n return { cursor, filter };\n}\n\nexport function finalizeState(props: {\n db: Database;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { cursor, db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string, number]>(statements.finalizeFilter).run(\n indexerId,\n Number(cursor.orderKey),\n );\n}\n\nexport function invalidateState(props: {\n db: Database;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { cursor, db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string, number]>(statements.invalidateFilterDelete).run(\n indexerId,\n Number(cursor.orderKey),\n );\n db.prepare<[string, number]>(statements.invalidateFilterUpdate).run(\n indexerId,\n Number(cursor.orderKey),\n );\n}\n\nexport function resetPersistence(props: {\n db: Database;\n indexerId: string;\n}) {\n const { db, indexerId } = props;\n assertInTransaction(db);\n db.prepare<[string]>(statements.resetCheckpoint).run(indexerId);\n db.prepare<[string]>(statements.resetFilter).run(indexerId);\n}\n\nexport type CheckpointRow = {\n id: string;\n order_key: number;\n unique_key: string | null;\n};\n\nexport type FilterRow = {\n id: string;\n filter: string;\n from_block: number;\n to_block: number | null;\n};\n\nconst statements = {\n createCheckpointsTable: `\n CREATE TABLE IF NOT EXISTS checkpoints (\n id TEXT NOT NULL PRIMARY KEY,\n order_key INTEGER,\n unique_key TEXT\n );`,\n createFiltersTable: `\n CREATE TABLE IF NOT EXISTS filters (\n id TEXT NOT NULL,\n filter BLOB NOT NULL,\n from_block INTEGER NOT NULL,\n to_block INTEGER,\n PRIMARY KEY (id, from_block)\n );`,\n getCheckpoint: `\n SELECT *\n FROM checkpoints\n WHERE id = ?`,\n putCheckpoint: `\n INSERT INTO checkpoints (id, order_key, unique_key)\n VALUES (?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n order_key = excluded.order_key,\n unique_key = excluded.unique_key`,\n delCheckpoint: `\n DELETE FROM checkpoints\n WHERE id = ?`,\n getFilter: `\n SELECT *\n FROM filters\n WHERE id = ? AND to_block IS NULL`,\n updateFilterToBlock: `\n UPDATE filters\n SET to_block = ?\n WHERE id = ? AND to_block IS NULL`,\n insertFilter: `\n INSERT INTO filters (id, filter, from_block)\n VALUES (?, ?, ?)\n ON CONFLICT(id, from_block) DO UPDATE SET\n filter = excluded.filter,\n from_block = excluded.from_block`,\n delFilter: `\n DELETE FROM filters\n WHERE id = ?`,\n finalizeFilter: `\n DELETE FROM filters\n WHERE id = ? AND to_block <= ?`,\n invalidateFilterDelete: `\n DELETE FROM filters\n WHERE id = ? AND from_block > ?`,\n invalidateFilterUpdate: `\n UPDATE filters\n SET to_block = NULL\n WHERE id = ? AND to_block > ?`,\n resetCheckpoint: `\n DELETE FROM checkpoints\n WHERE id = ?`,\n resetFilter: `\n DELETE FROM filters\n WHERE id = ?`,\n};\n","import { useIndexerContext } from \"@apibara/indexer\";\nimport { defineIndexerPlugin, useLogger } from \"@apibara/indexer/plugins\";\nimport type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport type { Database as SqliteDatabase } from \"better-sqlite3\";\n\nimport { generateIndexerId } from \"@apibara/indexer/internal\";\nimport { useInternalContext } from \"@apibara/indexer/internal/plugins\";\nimport {\n KeyValueStore,\n cleanupKV,\n finalizeKV,\n initializeKeyValueStore,\n invalidateKV,\n} from \"./kv\";\nimport {\n finalizeState,\n getState,\n initializePersistentState,\n invalidateState,\n persistState,\n resetPersistence,\n} from \"./persistence\";\nimport {\n type DeserializeFn,\n type SerializeFn,\n SqliteStorageError,\n assertInTransaction,\n deserialize,\n serialize,\n sleep,\n withTransaction,\n} from \"./utils\";\n\nconst KV_PROPERTY = \"_kv_sqlite\" as const;\nconst MAX_RETRIES = 5;\n\nexport { KeyValueStore } from \"./kv\";\n\nexport function useSqliteKeyValueStore(): KeyValueStore {\n const kv = useIndexerContext()[KV_PROPERTY] as KeyValueStore | undefined;\n if (!kv) {\n throw new SqliteStorageError(\n \"SQLite key-value store is not available. Did you forget to enable it?\",\n );\n }\n\n return kv;\n}\n\nexport type SqliteStorageOptions = {\n database: SqliteDatabase;\n keyValueStore?: boolean;\n persistState?: boolean;\n indexerName?: string;\n\n serialize?: SerializeFn;\n deserialize?: DeserializeFn;\n};\n\n/**\n * Creates a plugin that uses SQLite as the storage layer.\n *\n * Supports storing the indexer's state and provides a simple Key-Value store.\n * @param options.database - The SQLite database instance.\n * @param options.persistState - Whether to persist the indexer's state. Defaults to true.\n * @param options.keyValueStore - Whether to enable the Key-Value store. Defaults to true.\n * @param options.serialize - A function to serialize the value to the KV.\n * @param options.deserialize - A function to deserialize the value from the KV.\n * @param options.indexerName - The name of the indexer. Defaults value is 'default'.\n */\nexport function sqliteStorage<TFilter, TBlock>({\n database,\n persistState: enablePersistState = true,\n keyValueStore: enableKeyValueStore = true,\n serialize: serializeFn = serialize,\n deserialize: deserializeFn = deserialize,\n indexerName: identifier = \"default\",\n}: SqliteStorageOptions) {\n return defineIndexerPlugin<TFilter, TBlock>((indexer) => {\n let indexerId = \"\";\n let prevFinality: DataFinality | undefined;\n const alwaysReindex = process.env[\"APIBARA_ALWAYS_REINDEX\"] === \"true\";\n\n indexer.hooks.hook(\"plugins:init\", async () => {\n const { indexerName: indexerFileName, availableIndexers } =\n useInternalContext();\n\n const logger = useLogger();\n\n indexerId = generateIndexerId(indexerFileName, identifier);\n\n let retries = 0;\n\n let cleanupApplied = false;\n\n while (retries <= MAX_RETRIES) {\n try {\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n initializePersistentState(db);\n }\n\n if (enableKeyValueStore) {\n initializeKeyValueStore(db);\n }\n\n if (alwaysReindex && !cleanupApplied) {\n if (enableKeyValueStore) {\n logger.warn(\"Reindexing: Cleaning up key-value store\");\n cleanupKV(db, indexerId);\n }\n\n if (enablePersistState) {\n logger.warn(\"Reindexing: Resetting persistence state\");\n resetPersistence({ db, indexerId });\n }\n\n cleanupApplied = true;\n\n logger.success(\"All data has been cleaned up for reindexing\");\n }\n });\n break;\n } catch (error) {\n if (retries === MAX_RETRIES) {\n throw new SqliteStorageError(\n \"Initialization failed after 5 retries\",\n {\n cause: error,\n },\n );\n }\n await sleep(retries * 1000);\n retries++;\n }\n }\n });\n\n indexer.hooks.hook(\"connect:before\", async ({ request }) => {\n if (!enablePersistState) {\n return;\n }\n\n return await withTransaction(database, async (db) => {\n const { cursor, filter } = getState<TFilter>({ db, indexerId });\n\n if (cursor) {\n request.startingCursor = cursor;\n }\n\n if (filter) {\n request.filter[1] = filter;\n }\n });\n });\n\n indexer.hooks.hook(\"connect:after\", async ({ request }) => {\n // On restart, we need to invalidate data for blocks that were processed but not persisted.\n const cursor = request.startingCursor;\n\n if (!cursor) {\n return;\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n invalidateState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"connect:factory\", ({ request, endCursor }) => {\n if (!enablePersistState) {\n return;\n }\n\n // The connect factory hook is called while indexing a block, so the database should be in a transaction\n // created by the middleware.\n assertInTransaction(database);\n\n if (endCursor && request.filter[1]) {\n persistState({\n db: database,\n endCursor,\n indexerId,\n filter: request.filter[1],\n });\n }\n });\n\n indexer.hooks.hook(\"message:finalize\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new SqliteStorageError(\"finalized cursor is undefined\");\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n finalizeState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n finalizeKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"message:invalidate\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new SqliteStorageError(\"invalidate cursor is undefined\");\n }\n\n await withTransaction(database, async (db) => {\n if (enablePersistState) {\n invalidateState({ db, cursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n });\n });\n\n indexer.hooks.hook(\"handler:middleware\", ({ use }) => {\n use(async (ctx, next) => {\n const { endCursor, finality, cursor } = ctx as {\n cursor: Cursor;\n endCursor: Cursor;\n finality: DataFinality;\n };\n\n if (!finality) {\n throw new SqliteStorageError(\"finality is undefined\");\n }\n\n if (!endCursor) {\n throw new SqliteStorageError(\n \"endCursor is undefined or not a cursor\",\n );\n }\n\n await withTransaction(database, async (db) => {\n if (prevFinality === \"pending\") {\n // invalidate if previous block's finality was \"pending\"\n if (enableKeyValueStore) {\n invalidateKV(db, cursor, indexerId);\n }\n }\n\n if (enableKeyValueStore) {\n ctx[KV_PROPERTY] = new KeyValueStore(\n db,\n endCursor,\n finality,\n serializeFn,\n deserializeFn,\n indexerId,\n );\n }\n\n await next();\n\n if (enablePersistState && finality !== \"pending\") {\n persistState({ db, endCursor, indexerId });\n }\n\n if (enableKeyValueStore) {\n delete ctx[KV_PROPERTY];\n }\n\n prevFinality = finality;\n });\n });\n });\n });\n}\n"],"names":["statements"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apibara/plugin-sqlite",
3
- "version": "2.1.0-beta.39",
3
+ "version": "2.1.0-beta.40",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -36,7 +36,7 @@
36
36
  "better-sqlite3": "^9.0.0"
37
37
  },
38
38
  "dependencies": {
39
- "@apibara/indexer": "2.1.0-beta.39",
40
- "@apibara/protocol": "2.1.0-beta.39"
39
+ "@apibara/indexer": "2.1.0-beta.40",
40
+ "@apibara/protocol": "2.1.0-beta.40"
41
41
  }
42
42
  }
package/src/index.ts CHANGED
@@ -81,7 +81,7 @@ export function sqliteStorage<TFilter, TBlock>({
81
81
  let prevFinality: DataFinality | undefined;
82
82
  const alwaysReindex = process.env["APIBARA_ALWAYS_REINDEX"] === "true";
83
83
 
84
- indexer.hooks.hook("run:before", async () => {
84
+ indexer.hooks.hook("plugins:init", async () => {
85
85
  const { indexerName: indexerFileName, availableIndexers } =
86
86
  useInternalContext();
87
87