@apibara/plugin-sqlite 2.1.0-beta.55 → 2.1.0-beta.56
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 +18 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +18 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/kv.ts +15 -14
- package/src/persistence.ts +23 -21
package/dist/index.cjs
CHANGED
|
@@ -59,39 +59,39 @@ class KeyValueStore {
|
|
|
59
59
|
assertInTransaction(db);
|
|
60
60
|
}
|
|
61
61
|
get(key) {
|
|
62
|
-
const row = this.db.prepare(statements$1.get).get(key, this.indexerId);
|
|
62
|
+
const row = this.db.prepare(statements$1.get).safeIntegers().get(key, this.indexerId);
|
|
63
63
|
return row ? this.deserialize(row.v) : void 0;
|
|
64
64
|
}
|
|
65
65
|
put(key, value) {
|
|
66
|
-
this.db.prepare(statements$1.updateToBlock).run(
|
|
66
|
+
this.db.prepare(statements$1.updateToBlock).run(this.endCursor.orderKey, key, this.indexerId);
|
|
67
67
|
this.db.prepare(
|
|
68
68
|
statements$1.insertIntoKvs
|
|
69
69
|
).run(
|
|
70
|
-
|
|
70
|
+
this.endCursor.orderKey,
|
|
71
71
|
key,
|
|
72
72
|
this.serialize(value),
|
|
73
73
|
this.indexerId
|
|
74
74
|
);
|
|
75
75
|
}
|
|
76
76
|
del(key) {
|
|
77
|
-
this.db.prepare(statements$1.del).run(
|
|
77
|
+
this.db.prepare(statements$1.del).run(this.endCursor.orderKey, key, this.indexerId);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
function finalizeKV(db, cursor, indexerId) {
|
|
81
81
|
assertInTransaction(db);
|
|
82
82
|
db.prepare(statements$1.finalize).run(
|
|
83
|
-
|
|
83
|
+
cursor.orderKey,
|
|
84
84
|
indexerId
|
|
85
85
|
);
|
|
86
86
|
}
|
|
87
87
|
function invalidateKV(db, cursor, indexerId) {
|
|
88
88
|
assertInTransaction(db);
|
|
89
89
|
db.prepare(statements$1.invalidateDelete).run(
|
|
90
|
-
|
|
90
|
+
cursor.orderKey,
|
|
91
91
|
indexerId
|
|
92
92
|
);
|
|
93
93
|
db.prepare(statements$1.invalidateUpdate).run(
|
|
94
|
-
|
|
94
|
+
cursor.orderKey,
|
|
95
95
|
indexerId
|
|
96
96
|
);
|
|
97
97
|
}
|
|
@@ -147,20 +147,18 @@ function initializePersistentState(db) {
|
|
|
147
147
|
function persistState(props) {
|
|
148
148
|
const { db, endCursor, filter, indexerId } = props;
|
|
149
149
|
assertInTransaction(db);
|
|
150
|
-
db.prepare(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
endCursor.uniqueKey
|
|
154
|
-
);
|
|
150
|
+
db.prepare(
|
|
151
|
+
statements.putCheckpoint
|
|
152
|
+
).run(indexerId, endCursor.orderKey, endCursor.uniqueKey);
|
|
155
153
|
if (filter) {
|
|
156
154
|
db.prepare(statements.updateFilterToBlock).run(
|
|
157
|
-
|
|
155
|
+
endCursor.orderKey,
|
|
158
156
|
indexerId
|
|
159
157
|
);
|
|
160
158
|
db.prepare(statements.insertFilter).run(
|
|
161
159
|
indexerId,
|
|
162
160
|
serialize(filter),
|
|
163
|
-
|
|
161
|
+
endCursor.orderKey
|
|
164
162
|
);
|
|
165
163
|
}
|
|
166
164
|
}
|
|
@@ -169,13 +167,13 @@ function getState(props) {
|
|
|
169
167
|
assertInTransaction(db);
|
|
170
168
|
const storedCursor = db.prepare(
|
|
171
169
|
statements.getCheckpoint
|
|
172
|
-
).get(indexerId);
|
|
170
|
+
).safeIntegers().get(indexerId);
|
|
173
171
|
const storedFilter = db.prepare(statements.getFilter).get(indexerId);
|
|
174
172
|
let cursor;
|
|
175
173
|
let filter;
|
|
176
|
-
if (storedCursor
|
|
174
|
+
if (storedCursor && (storedCursor.order_key != null || storedCursor.order_key !== void 0)) {
|
|
177
175
|
cursor = protocol.normalizeCursor({
|
|
178
|
-
orderKey:
|
|
176
|
+
orderKey: storedCursor.order_key,
|
|
179
177
|
uniqueKey: storedCursor.unique_key ? storedCursor.unique_key : null
|
|
180
178
|
});
|
|
181
179
|
}
|
|
@@ -189,7 +187,7 @@ function finalizeState(props) {
|
|
|
189
187
|
assertInTransaction(db);
|
|
190
188
|
db.prepare(statements.finalizeFilter).run(
|
|
191
189
|
indexerId,
|
|
192
|
-
|
|
190
|
+
cursor.orderKey
|
|
193
191
|
);
|
|
194
192
|
}
|
|
195
193
|
function invalidateState(props) {
|
|
@@ -197,11 +195,11 @@ function invalidateState(props) {
|
|
|
197
195
|
assertInTransaction(db);
|
|
198
196
|
db.prepare(statements.invalidateFilterDelete).run(
|
|
199
197
|
indexerId,
|
|
200
|
-
|
|
198
|
+
cursor.orderKey
|
|
201
199
|
);
|
|
202
200
|
db.prepare(statements.invalidateFilterUpdate).run(
|
|
203
201
|
indexerId,
|
|
204
|
-
|
|
202
|
+
cursor.orderKey
|
|
205
203
|
);
|
|
206
204
|
}
|
|
207
205
|
function resetPersistence(props) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -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(\"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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"}
|
|
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 .safeIntegers()\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<[bigint, string, string], KeyValueRow>(statements.updateToBlock)\n .run(this.endCursor.orderKey, key, this.indexerId);\n\n this.db\n .prepare<[bigint, string, string, string], KeyValueRow>(\n statements.insertIntoKvs,\n )\n .run(\n 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<[bigint, string, string], KeyValueRow>(statements.del)\n .run(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<[bigint, string], KeyValueRow>(statements.finalize).run(\n 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<[bigint, string], KeyValueRow>(statements.invalidateDelete).run(\n cursor.orderKey,\n indexerId,\n );\n\n // Update entries that were supposed to end after the invalidation cursor\n db.prepare<[bigint, string], KeyValueRow>(statements.invalidateUpdate).run(\n 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: bigint;\n to_block: bigint;\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<[string, bigint, string | undefined]>(\n statements.putCheckpoint,\n ).run(indexerId, endCursor.orderKey, endCursor.uniqueKey);\n\n if (filter) {\n db.prepare<[bigint, string]>(statements.updateFilterToBlock).run(\n endCursor.orderKey,\n indexerId,\n );\n db.prepare<[string, string, bigint]>(statements.insertFilter).run(\n indexerId,\n serialize(filter as Record<string, unknown>),\n 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?: bigint; unique_key?: string }>(\n statements.getCheckpoint,\n )\n .safeIntegers()\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 (\n storedCursor &&\n (storedCursor.order_key != null || storedCursor.order_key !== undefined)\n ) {\n cursor = normalizeCursor({\n orderKey: 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, bigint]>(statements.finalizeFilter).run(\n indexerId,\n 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, bigint]>(statements.invalidateFilterDelete).run(\n indexerId,\n cursor.orderKey,\n );\n db.prepare<[string, bigint]>(statements.invalidateFilterUpdate).run(\n indexerId,\n 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: bigint;\n unique_key: string | null;\n};\n\nexport type FilterRow = {\n id: string;\n filter: string;\n from_block: bigint;\n to_block: bigint | 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
|
@@ -57,39 +57,39 @@ class KeyValueStore {
|
|
|
57
57
|
assertInTransaction(db);
|
|
58
58
|
}
|
|
59
59
|
get(key) {
|
|
60
|
-
const row = this.db.prepare(statements$1.get).get(key, this.indexerId);
|
|
60
|
+
const row = this.db.prepare(statements$1.get).safeIntegers().get(key, this.indexerId);
|
|
61
61
|
return row ? this.deserialize(row.v) : void 0;
|
|
62
62
|
}
|
|
63
63
|
put(key, value) {
|
|
64
|
-
this.db.prepare(statements$1.updateToBlock).run(
|
|
64
|
+
this.db.prepare(statements$1.updateToBlock).run(this.endCursor.orderKey, key, this.indexerId);
|
|
65
65
|
this.db.prepare(
|
|
66
66
|
statements$1.insertIntoKvs
|
|
67
67
|
).run(
|
|
68
|
-
|
|
68
|
+
this.endCursor.orderKey,
|
|
69
69
|
key,
|
|
70
70
|
this.serialize(value),
|
|
71
71
|
this.indexerId
|
|
72
72
|
);
|
|
73
73
|
}
|
|
74
74
|
del(key) {
|
|
75
|
-
this.db.prepare(statements$1.del).run(
|
|
75
|
+
this.db.prepare(statements$1.del).run(this.endCursor.orderKey, key, this.indexerId);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
function finalizeKV(db, cursor, indexerId) {
|
|
79
79
|
assertInTransaction(db);
|
|
80
80
|
db.prepare(statements$1.finalize).run(
|
|
81
|
-
|
|
81
|
+
cursor.orderKey,
|
|
82
82
|
indexerId
|
|
83
83
|
);
|
|
84
84
|
}
|
|
85
85
|
function invalidateKV(db, cursor, indexerId) {
|
|
86
86
|
assertInTransaction(db);
|
|
87
87
|
db.prepare(statements$1.invalidateDelete).run(
|
|
88
|
-
|
|
88
|
+
cursor.orderKey,
|
|
89
89
|
indexerId
|
|
90
90
|
);
|
|
91
91
|
db.prepare(statements$1.invalidateUpdate).run(
|
|
92
|
-
|
|
92
|
+
cursor.orderKey,
|
|
93
93
|
indexerId
|
|
94
94
|
);
|
|
95
95
|
}
|
|
@@ -145,20 +145,18 @@ function initializePersistentState(db) {
|
|
|
145
145
|
function persistState(props) {
|
|
146
146
|
const { db, endCursor, filter, indexerId } = props;
|
|
147
147
|
assertInTransaction(db);
|
|
148
|
-
db.prepare(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
endCursor.uniqueKey
|
|
152
|
-
);
|
|
148
|
+
db.prepare(
|
|
149
|
+
statements.putCheckpoint
|
|
150
|
+
).run(indexerId, endCursor.orderKey, endCursor.uniqueKey);
|
|
153
151
|
if (filter) {
|
|
154
152
|
db.prepare(statements.updateFilterToBlock).run(
|
|
155
|
-
|
|
153
|
+
endCursor.orderKey,
|
|
156
154
|
indexerId
|
|
157
155
|
);
|
|
158
156
|
db.prepare(statements.insertFilter).run(
|
|
159
157
|
indexerId,
|
|
160
158
|
serialize(filter),
|
|
161
|
-
|
|
159
|
+
endCursor.orderKey
|
|
162
160
|
);
|
|
163
161
|
}
|
|
164
162
|
}
|
|
@@ -167,13 +165,13 @@ function getState(props) {
|
|
|
167
165
|
assertInTransaction(db);
|
|
168
166
|
const storedCursor = db.prepare(
|
|
169
167
|
statements.getCheckpoint
|
|
170
|
-
).get(indexerId);
|
|
168
|
+
).safeIntegers().get(indexerId);
|
|
171
169
|
const storedFilter = db.prepare(statements.getFilter).get(indexerId);
|
|
172
170
|
let cursor;
|
|
173
171
|
let filter;
|
|
174
|
-
if (storedCursor
|
|
172
|
+
if (storedCursor && (storedCursor.order_key != null || storedCursor.order_key !== void 0)) {
|
|
175
173
|
cursor = normalizeCursor({
|
|
176
|
-
orderKey:
|
|
174
|
+
orderKey: storedCursor.order_key,
|
|
177
175
|
uniqueKey: storedCursor.unique_key ? storedCursor.unique_key : null
|
|
178
176
|
});
|
|
179
177
|
}
|
|
@@ -187,7 +185,7 @@ function finalizeState(props) {
|
|
|
187
185
|
assertInTransaction(db);
|
|
188
186
|
db.prepare(statements.finalizeFilter).run(
|
|
189
187
|
indexerId,
|
|
190
|
-
|
|
188
|
+
cursor.orderKey
|
|
191
189
|
);
|
|
192
190
|
}
|
|
193
191
|
function invalidateState(props) {
|
|
@@ -195,11 +193,11 @@ function invalidateState(props) {
|
|
|
195
193
|
assertInTransaction(db);
|
|
196
194
|
db.prepare(statements.invalidateFilterDelete).run(
|
|
197
195
|
indexerId,
|
|
198
|
-
|
|
196
|
+
cursor.orderKey
|
|
199
197
|
);
|
|
200
198
|
db.prepare(statements.invalidateFilterUpdate).run(
|
|
201
199
|
indexerId,
|
|
202
|
-
|
|
200
|
+
cursor.orderKey
|
|
203
201
|
);
|
|
204
202
|
}
|
|
205
203
|
function resetPersistence(props) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -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(\"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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"}
|
|
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 .safeIntegers()\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<[bigint, string, string], KeyValueRow>(statements.updateToBlock)\n .run(this.endCursor.orderKey, key, this.indexerId);\n\n this.db\n .prepare<[bigint, string, string, string], KeyValueRow>(\n statements.insertIntoKvs,\n )\n .run(\n 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<[bigint, string, string], KeyValueRow>(statements.del)\n .run(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<[bigint, string], KeyValueRow>(statements.finalize).run(\n 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<[bigint, string], KeyValueRow>(statements.invalidateDelete).run(\n cursor.orderKey,\n indexerId,\n );\n\n // Update entries that were supposed to end after the invalidation cursor\n db.prepare<[bigint, string], KeyValueRow>(statements.invalidateUpdate).run(\n 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: bigint;\n to_block: bigint;\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<[string, bigint, string | undefined]>(\n statements.putCheckpoint,\n ).run(indexerId, endCursor.orderKey, endCursor.uniqueKey);\n\n if (filter) {\n db.prepare<[bigint, string]>(statements.updateFilterToBlock).run(\n endCursor.orderKey,\n indexerId,\n );\n db.prepare<[string, string, bigint]>(statements.insertFilter).run(\n indexerId,\n serialize(filter as Record<string, unknown>),\n 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?: bigint; unique_key?: string }>(\n statements.getCheckpoint,\n )\n .safeIntegers()\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 (\n storedCursor &&\n (storedCursor.order_key != null || storedCursor.order_key !== undefined)\n ) {\n cursor = normalizeCursor({\n orderKey: 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, bigint]>(statements.finalizeFilter).run(\n indexerId,\n 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, bigint]>(statements.invalidateFilterDelete).run(\n indexerId,\n cursor.orderKey,\n );\n db.prepare<[string, bigint]>(statements.invalidateFilterUpdate).run(\n indexerId,\n 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: bigint;\n unique_key: string | null;\n};\n\nexport type FilterRow = {\n id: string;\n filter: string;\n from_block: bigint;\n to_block: bigint | 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.
|
|
3
|
+
"version": "2.1.0-beta.56",
|
|
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.
|
|
40
|
-
"@apibara/protocol": "2.1.0-beta.
|
|
39
|
+
"@apibara/indexer": "2.1.0-beta.57",
|
|
40
|
+
"@apibara/protocol": "2.1.0-beta.57"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/kv.ts
CHANGED
|
@@ -27,6 +27,7 @@ export class KeyValueStore {
|
|
|
27
27
|
get<T>(key: string): T | undefined {
|
|
28
28
|
const row = this.db
|
|
29
29
|
.prepare<[string, string], KeyValueRow>(statements.get)
|
|
30
|
+
.safeIntegers()
|
|
30
31
|
.get(key, this.indexerId);
|
|
31
32
|
|
|
32
33
|
return row ? this.deserialize(row.v) : undefined;
|
|
@@ -34,15 +35,15 @@ export class KeyValueStore {
|
|
|
34
35
|
|
|
35
36
|
put<T>(key: string, value: T) {
|
|
36
37
|
this.db
|
|
37
|
-
.prepare<[
|
|
38
|
-
.run(
|
|
38
|
+
.prepare<[bigint, string, string], KeyValueRow>(statements.updateToBlock)
|
|
39
|
+
.run(this.endCursor.orderKey, key, this.indexerId);
|
|
39
40
|
|
|
40
41
|
this.db
|
|
41
|
-
.prepare<[
|
|
42
|
+
.prepare<[bigint, string, string, string], KeyValueRow>(
|
|
42
43
|
statements.insertIntoKvs,
|
|
43
44
|
)
|
|
44
45
|
.run(
|
|
45
|
-
|
|
46
|
+
this.endCursor.orderKey,
|
|
46
47
|
key,
|
|
47
48
|
this.serialize(value as Record<string, unknown>),
|
|
48
49
|
this.indexerId,
|
|
@@ -51,16 +52,16 @@ export class KeyValueStore {
|
|
|
51
52
|
|
|
52
53
|
del(key: string) {
|
|
53
54
|
this.db
|
|
54
|
-
.prepare<[
|
|
55
|
-
.run(
|
|
55
|
+
.prepare<[bigint, string, string], KeyValueRow>(statements.del)
|
|
56
|
+
.run(this.endCursor.orderKey, key, this.indexerId);
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
export function finalizeKV(db: Database, cursor: Cursor, indexerId: string) {
|
|
60
61
|
assertInTransaction(db);
|
|
61
62
|
|
|
62
|
-
db.prepare<[
|
|
63
|
-
|
|
63
|
+
db.prepare<[bigint, string], KeyValueRow>(statements.finalize).run(
|
|
64
|
+
cursor.orderKey,
|
|
64
65
|
indexerId,
|
|
65
66
|
);
|
|
66
67
|
}
|
|
@@ -69,14 +70,14 @@ export function invalidateKV(db: Database, cursor: Cursor, indexerId: string) {
|
|
|
69
70
|
assertInTransaction(db);
|
|
70
71
|
|
|
71
72
|
// Delete entries that started after the invalidation cursor
|
|
72
|
-
db.prepare<[
|
|
73
|
-
|
|
73
|
+
db.prepare<[bigint, string], KeyValueRow>(statements.invalidateDelete).run(
|
|
74
|
+
cursor.orderKey,
|
|
74
75
|
indexerId,
|
|
75
76
|
);
|
|
76
77
|
|
|
77
78
|
// Update entries that were supposed to end after the invalidation cursor
|
|
78
|
-
db.prepare<[
|
|
79
|
-
|
|
79
|
+
db.prepare<[bigint, string], KeyValueRow>(statements.invalidateUpdate).run(
|
|
80
|
+
cursor.orderKey,
|
|
80
81
|
indexerId,
|
|
81
82
|
);
|
|
82
83
|
}
|
|
@@ -88,8 +89,8 @@ export function cleanupKV(db: Database, indexerId: string) {
|
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
export type KeyValueRow = {
|
|
91
|
-
from_block:
|
|
92
|
-
to_block:
|
|
92
|
+
from_block: bigint;
|
|
93
|
+
to_block: bigint;
|
|
93
94
|
k: string;
|
|
94
95
|
v: string;
|
|
95
96
|
id: string;
|
package/src/persistence.ts
CHANGED
|
@@ -19,21 +19,19 @@ export function persistState<TFilter>(props: {
|
|
|
19
19
|
|
|
20
20
|
assertInTransaction(db);
|
|
21
21
|
|
|
22
|
-
db.prepare(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
endCursor.uniqueKey,
|
|
26
|
-
);
|
|
22
|
+
db.prepare<[string, bigint, string | undefined]>(
|
|
23
|
+
statements.putCheckpoint,
|
|
24
|
+
).run(indexerId, endCursor.orderKey, endCursor.uniqueKey);
|
|
27
25
|
|
|
28
26
|
if (filter) {
|
|
29
|
-
db.prepare(statements.updateFilterToBlock).run(
|
|
30
|
-
|
|
27
|
+
db.prepare<[bigint, string]>(statements.updateFilterToBlock).run(
|
|
28
|
+
endCursor.orderKey,
|
|
31
29
|
indexerId,
|
|
32
30
|
);
|
|
33
|
-
db.prepare(statements.insertFilter).run(
|
|
31
|
+
db.prepare<[string, string, bigint]>(statements.insertFilter).run(
|
|
34
32
|
indexerId,
|
|
35
33
|
serialize(filter as Record<string, unknown>),
|
|
36
|
-
|
|
34
|
+
endCursor.orderKey,
|
|
37
35
|
);
|
|
38
36
|
}
|
|
39
37
|
}
|
|
@@ -45,9 +43,10 @@ export function getState<TFilter>(props: {
|
|
|
45
43
|
const { db, indexerId } = props;
|
|
46
44
|
assertInTransaction(db);
|
|
47
45
|
const storedCursor = db
|
|
48
|
-
.prepare<string, { order_key?:
|
|
46
|
+
.prepare<string, { order_key?: bigint; unique_key?: string }>(
|
|
49
47
|
statements.getCheckpoint,
|
|
50
48
|
)
|
|
49
|
+
.safeIntegers()
|
|
51
50
|
.get(indexerId);
|
|
52
51
|
const storedFilter = db
|
|
53
52
|
.prepare<string, { filter: string }>(statements.getFilter)
|
|
@@ -56,9 +55,12 @@ export function getState<TFilter>(props: {
|
|
|
56
55
|
let cursor: Cursor | undefined;
|
|
57
56
|
let filter: TFilter | undefined;
|
|
58
57
|
|
|
59
|
-
if (
|
|
58
|
+
if (
|
|
59
|
+
storedCursor &&
|
|
60
|
+
(storedCursor.order_key != null || storedCursor.order_key !== undefined)
|
|
61
|
+
) {
|
|
60
62
|
cursor = normalizeCursor({
|
|
61
|
-
orderKey:
|
|
63
|
+
orderKey: storedCursor.order_key,
|
|
62
64
|
uniqueKey: storedCursor.unique_key ? storedCursor.unique_key : null,
|
|
63
65
|
});
|
|
64
66
|
}
|
|
@@ -77,9 +79,9 @@ export function finalizeState(props: {
|
|
|
77
79
|
}) {
|
|
78
80
|
const { cursor, db, indexerId } = props;
|
|
79
81
|
assertInTransaction(db);
|
|
80
|
-
db.prepare<[string,
|
|
82
|
+
db.prepare<[string, bigint]>(statements.finalizeFilter).run(
|
|
81
83
|
indexerId,
|
|
82
|
-
|
|
84
|
+
cursor.orderKey,
|
|
83
85
|
);
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -90,13 +92,13 @@ export function invalidateState(props: {
|
|
|
90
92
|
}) {
|
|
91
93
|
const { cursor, db, indexerId } = props;
|
|
92
94
|
assertInTransaction(db);
|
|
93
|
-
db.prepare<[string,
|
|
95
|
+
db.prepare<[string, bigint]>(statements.invalidateFilterDelete).run(
|
|
94
96
|
indexerId,
|
|
95
|
-
|
|
97
|
+
cursor.orderKey,
|
|
96
98
|
);
|
|
97
|
-
db.prepare<[string,
|
|
99
|
+
db.prepare<[string, bigint]>(statements.invalidateFilterUpdate).run(
|
|
98
100
|
indexerId,
|
|
99
|
-
|
|
101
|
+
cursor.orderKey,
|
|
100
102
|
);
|
|
101
103
|
}
|
|
102
104
|
|
|
@@ -112,15 +114,15 @@ export function resetPersistence(props: {
|
|
|
112
114
|
|
|
113
115
|
export type CheckpointRow = {
|
|
114
116
|
id: string;
|
|
115
|
-
order_key:
|
|
117
|
+
order_key: bigint;
|
|
116
118
|
unique_key: string | null;
|
|
117
119
|
};
|
|
118
120
|
|
|
119
121
|
export type FilterRow = {
|
|
120
122
|
id: string;
|
|
121
123
|
filter: string;
|
|
122
|
-
from_block:
|
|
123
|
-
to_block:
|
|
124
|
+
from_block: bigint;
|
|
125
|
+
to_block: bigint | null;
|
|
124
126
|
};
|
|
125
127
|
|
|
126
128
|
const statements = {
|