@apibara/plugin-mongo 2.1.0-beta.55 → 2.1.0-beta.57
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/mongo.ts +3 -5
- package/src/persistence.ts +10 -10
- package/src/storage.ts +10 -10
package/dist/index.cjs
CHANGED
|
@@ -7,18 +7,17 @@ const plugins$1 = require('@apibara/indexer/internal/plugins');
|
|
|
7
7
|
const protocol = require('@apibara/protocol');
|
|
8
8
|
|
|
9
9
|
async function invalidate(db, session, cursor, collections) {
|
|
10
|
-
const orderKeyValue = Number(cursor.orderKey);
|
|
11
10
|
for (const collection of collections) {
|
|
12
11
|
await db.collection(collection).deleteMany(
|
|
13
12
|
{
|
|
14
13
|
"_cursor.from": {
|
|
15
|
-
$gt:
|
|
14
|
+
$gt: cursor.orderKey
|
|
16
15
|
}
|
|
17
16
|
},
|
|
18
17
|
{ session }
|
|
19
18
|
);
|
|
20
19
|
await db.collection(collection).updateMany(
|
|
21
|
-
{ "_cursor.to": { $gt:
|
|
20
|
+
{ "_cursor.to": { $gt: cursor.orderKey } },
|
|
22
21
|
{
|
|
23
22
|
$set: {
|
|
24
23
|
"_cursor.to": null
|
|
@@ -29,11 +28,10 @@ async function invalidate(db, session, cursor, collections) {
|
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
async function finalize(db, session, cursor, collections) {
|
|
32
|
-
const orderKeyValue = Number(cursor.orderKey);
|
|
33
31
|
for (const collection of collections) {
|
|
34
32
|
await db.collection(collection).deleteMany(
|
|
35
33
|
{
|
|
36
|
-
"_cursor.to": { $lte:
|
|
34
|
+
"_cursor.to": { $lte: cursor.orderKey }
|
|
37
35
|
},
|
|
38
36
|
{ session }
|
|
39
37
|
);
|
|
@@ -85,7 +83,7 @@ async function persistState(props) {
|
|
|
85
83
|
{ id: indexerId },
|
|
86
84
|
{
|
|
87
85
|
$set: {
|
|
88
|
-
orderKey:
|
|
86
|
+
orderKey: endCursor.orderKey,
|
|
89
87
|
uniqueKey: endCursor.uniqueKey ? endCursor.uniqueKey : null
|
|
90
88
|
}
|
|
91
89
|
},
|
|
@@ -94,18 +92,18 @@ async function persistState(props) {
|
|
|
94
92
|
if (filter) {
|
|
95
93
|
await db.collection(filterCollectionName).updateMany(
|
|
96
94
|
{ id: indexerId, toBlock: null },
|
|
97
|
-
{ $set: { toBlock:
|
|
95
|
+
{ $set: { toBlock: endCursor.orderKey } },
|
|
98
96
|
{ session }
|
|
99
97
|
);
|
|
100
98
|
await db.collection(filterCollectionName).updateOne(
|
|
101
99
|
{
|
|
102
100
|
id: indexerId,
|
|
103
|
-
fromBlock:
|
|
101
|
+
fromBlock: endCursor.orderKey
|
|
104
102
|
},
|
|
105
103
|
{
|
|
106
104
|
$set: {
|
|
107
105
|
filter,
|
|
108
|
-
fromBlock:
|
|
106
|
+
fromBlock: endCursor.orderKey,
|
|
109
107
|
toBlock: null
|
|
110
108
|
}
|
|
111
109
|
},
|
|
@@ -140,11 +138,11 @@ async function getState(props) {
|
|
|
140
138
|
async function invalidateState(props) {
|
|
141
139
|
const { db, session, cursor, indexerId } = props;
|
|
142
140
|
await db.collection(filterCollectionName).deleteMany(
|
|
143
|
-
{ id: indexerId, fromBlock: { $gt:
|
|
141
|
+
{ id: indexerId, fromBlock: { $gt: cursor.orderKey } },
|
|
144
142
|
{ session }
|
|
145
143
|
);
|
|
146
144
|
await db.collection(filterCollectionName).updateMany(
|
|
147
|
-
{ id: indexerId, toBlock: { $gt:
|
|
145
|
+
{ id: indexerId, toBlock: { $gt: cursor.orderKey } },
|
|
148
146
|
{ $set: { toBlock: null } },
|
|
149
147
|
{ session }
|
|
150
148
|
);
|
|
@@ -154,7 +152,7 @@ async function finalizeState(props) {
|
|
|
154
152
|
await db.collection(filterCollectionName).deleteMany(
|
|
155
153
|
{
|
|
156
154
|
id: indexerId,
|
|
157
|
-
toBlock: { $lte:
|
|
155
|
+
toBlock: { $lte: cursor.orderKey }
|
|
158
156
|
},
|
|
159
157
|
{ session }
|
|
160
158
|
);
|
|
@@ -197,7 +195,7 @@ class MongoCollection {
|
|
|
197
195
|
{
|
|
198
196
|
...doc,
|
|
199
197
|
_cursor: {
|
|
200
|
-
from:
|
|
198
|
+
from: this.endCursor?.orderKey ?? null,
|
|
201
199
|
to: null
|
|
202
200
|
}
|
|
203
201
|
},
|
|
@@ -209,7 +207,7 @@ class MongoCollection {
|
|
|
209
207
|
docs.map((doc) => ({
|
|
210
208
|
...doc,
|
|
211
209
|
_cursor: {
|
|
212
|
-
from:
|
|
210
|
+
from: this.endCursor?.orderKey ?? null,
|
|
213
211
|
to: null
|
|
214
212
|
}
|
|
215
213
|
})),
|
|
@@ -226,7 +224,7 @@ class MongoCollection {
|
|
|
226
224
|
...update,
|
|
227
225
|
$set: {
|
|
228
226
|
...update.$set,
|
|
229
|
-
"_cursor.from":
|
|
227
|
+
"_cursor.from": this.endCursor?.orderKey ?? null
|
|
230
228
|
}
|
|
231
229
|
},
|
|
232
230
|
{
|
|
@@ -242,7 +240,7 @@ class MongoCollection {
|
|
|
242
240
|
...doc,
|
|
243
241
|
_cursor: {
|
|
244
242
|
...oldDoc._cursor,
|
|
245
|
-
to:
|
|
243
|
+
to: this.endCursor?.orderKey ?? null
|
|
246
244
|
}
|
|
247
245
|
},
|
|
248
246
|
{ session: this.session }
|
|
@@ -273,7 +271,7 @@ class MongoCollection {
|
|
|
273
271
|
...update,
|
|
274
272
|
$set: {
|
|
275
273
|
...update.$set,
|
|
276
|
-
"_cursor.from":
|
|
274
|
+
"_cursor.from": this.endCursor?.orderKey ?? null
|
|
277
275
|
}
|
|
278
276
|
},
|
|
279
277
|
{ ...options, session: this.session }
|
|
@@ -282,7 +280,7 @@ class MongoCollection {
|
|
|
282
280
|
...doc,
|
|
283
281
|
_cursor: {
|
|
284
282
|
...doc._cursor,
|
|
285
|
-
to:
|
|
283
|
+
to: this.endCursor?.orderKey ?? null
|
|
286
284
|
}
|
|
287
285
|
}));
|
|
288
286
|
if (oldDocsWithUpdatedCursor.length > 0) {
|
|
@@ -301,7 +299,7 @@ class MongoCollection {
|
|
|
301
299
|
},
|
|
302
300
|
{
|
|
303
301
|
$set: {
|
|
304
|
-
"_cursor.to":
|
|
302
|
+
"_cursor.to": this.endCursor?.orderKey ?? null
|
|
305
303
|
}
|
|
306
304
|
},
|
|
307
305
|
{ ...options, session: this.session }
|
|
@@ -315,7 +313,7 @@ class MongoCollection {
|
|
|
315
313
|
},
|
|
316
314
|
{
|
|
317
315
|
$set: {
|
|
318
|
-
"_cursor.to":
|
|
316
|
+
"_cursor.to": this.endCursor?.orderKey ?? null
|
|
319
317
|
}
|
|
320
318
|
},
|
|
321
319
|
{ ...options, session: this.session }
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/mongo.ts","../src/utils.ts","../src/persistence.ts","../src/storage.ts","../src/index.ts"],"sourcesContent":["import type { Cursor } from \"@apibara/protocol\";\nimport type { ClientSession, Db } from \"mongodb\";\n\nexport async function invalidate(\n db: Db,\n session: ClientSession,\n cursor: Cursor,\n collections: string[],\n) {\n const orderKeyValue = Number(cursor.orderKey);\n for (const collection of collections) {\n // Delete documents where the lower bound of _cursor is greater than the invalidate cursor\n await db.collection(collection).deleteMany(\n {\n \"_cursor.from\": {\n $gt: orderKeyValue,\n },\n },\n { session },\n );\n\n // Update documents where the upper bound of _cursor is greater than the invalidate cursor\n await db.collection(collection).updateMany(\n { \"_cursor.to\": { $gt: orderKeyValue } },\n {\n $set: {\n \"_cursor.to\": null,\n },\n },\n { session },\n );\n }\n}\n\nexport async function finalize(\n db: Db,\n session: ClientSession,\n cursor: Cursor,\n collections: string[],\n) {\n const orderKeyValue = Number(cursor.orderKey);\n for (const collection of collections) {\n // Delete documents where the upper bound of _cursor is less than the finalize cursor\n await db.collection(collection).deleteMany(\n {\n \"_cursor.to\": { $lte: orderKeyValue },\n },\n { session },\n );\n }\n}\n\nexport async function cleanupStorage(\n db: Db,\n session: ClientSession,\n collections: string[],\n) {\n for (const collection of collections) {\n try {\n // Delete all documents in the collection\n await db.collection(collection).deleteMany({}, { session });\n } catch (error) {\n throw new Error(`Failed to clean up collection ${collection}`, {\n cause: error,\n });\n }\n }\n}\n","import type { ClientSession, MongoClient } from \"mongodb\";\n\nexport class MongoStorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"MongoStorageError\";\n }\n}\n\nexport async function withTransaction<T>(\n client: MongoClient,\n cb: (session: ClientSession) => Promise<T>,\n) {\n return await client.withSession(async (session) => {\n return await session.withTransaction(\n async (session) => {\n return await cb(session);\n },\n {\n retryWrites: false,\n },\n );\n });\n}\n","import { type Cursor, normalizeCursor } from \"@apibara/protocol\";\nimport type { ClientSession, Db } from \"mongodb\";\nimport { MongoStorageError } from \"./utils\";\n\nexport type CheckpointSchema = {\n id: string;\n orderKey: number;\n uniqueKey: string | null;\n};\n\nexport type FilterSchema = {\n id: string;\n filter: Record<string, unknown>;\n fromBlock: number;\n toBlock: number | null;\n};\n\nexport const checkpointCollectionName = \"checkpoints\";\nexport const filterCollectionName = \"filters\";\n\nexport async function initializePersistentState(\n db: Db,\n session: ClientSession,\n) {\n const checkpoint = db.collection<CheckpointSchema>(checkpointCollectionName);\n const filter = db.collection<FilterSchema>(filterCollectionName);\n\n await checkpoint.createIndex({ id: 1 }, { session });\n await filter.createIndex({ id: 1, fromBlock: 1 }, { session });\n}\n\nexport async function persistState<TFilter>(props: {\n db: Db;\n session: ClientSession;\n endCursor: Cursor;\n filter?: TFilter;\n indexerId: string;\n}) {\n const { db, session, endCursor, filter, indexerId } = props;\n\n if (endCursor) {\n await db.collection<CheckpointSchema>(checkpointCollectionName).updateOne(\n { id: indexerId },\n {\n $set: {\n orderKey: Number(endCursor.orderKey),\n uniqueKey: endCursor.uniqueKey ? endCursor.uniqueKey : null,\n },\n },\n { upsert: true, session },\n );\n\n if (filter) {\n // Update existing filter's to_block\n await db\n .collection<FilterSchema>(filterCollectionName)\n .updateMany(\n { id: indexerId, toBlock: null },\n { $set: { toBlock: Number(endCursor.orderKey) } },\n { session },\n );\n\n // Insert new filter\n await db.collection<FilterSchema>(filterCollectionName).updateOne(\n {\n id: indexerId,\n fromBlock: Number(endCursor.orderKey),\n },\n {\n $set: {\n filter: filter as Record<string, unknown>,\n fromBlock: Number(endCursor.orderKey),\n toBlock: null,\n },\n },\n { upsert: true, session },\n );\n }\n }\n}\n\nexport async function getState<TFilter>(props: {\n db: Db;\n session: ClientSession;\n indexerId: string;\n}): Promise<{ cursor?: Cursor; filter?: TFilter }> {\n const { db, session, indexerId } = props;\n\n let cursor: Cursor | undefined;\n let filter: TFilter | undefined;\n\n const checkpointRow = await db\n .collection<CheckpointSchema>(checkpointCollectionName)\n .findOne({ id: indexerId }, { session });\n\n if (checkpointRow) {\n cursor = normalizeCursor({\n orderKey: BigInt(checkpointRow.orderKey),\n uniqueKey: checkpointRow.uniqueKey,\n });\n }\n\n const filterRow = await db\n .collection<FilterSchema>(filterCollectionName)\n .findOne(\n {\n id: indexerId,\n toBlock: null,\n },\n { session },\n );\n\n if (filterRow) {\n filter = filterRow.filter as TFilter;\n }\n\n return { cursor, filter };\n}\n\nexport async function invalidateState(props: {\n db: Db;\n session: ClientSession;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { db, session, cursor, indexerId } = props;\n\n await db\n .collection<FilterSchema>(filterCollectionName)\n .deleteMany(\n { id: indexerId, fromBlock: { $gt: Number(cursor.orderKey) } },\n { session },\n );\n\n await db\n .collection<FilterSchema>(filterCollectionName)\n .updateMany(\n { id: indexerId, toBlock: { $gt: Number(cursor.orderKey) } },\n { $set: { toBlock: null } },\n { session },\n );\n}\n\nexport async function finalizeState(props: {\n db: Db;\n session: ClientSession;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { db, session, cursor, indexerId } = props;\n\n await db.collection<FilterSchema>(filterCollectionName).deleteMany(\n {\n id: indexerId,\n toBlock: { $lte: Number(cursor.orderKey) },\n },\n { session },\n );\n}\n\nexport async function resetPersistence(props: {\n db: Db;\n session: ClientSession;\n indexerId: string;\n}) {\n const { db, session, indexerId } = props;\n\n try {\n // Delete all checkpoints for this indexer\n await db\n .collection<CheckpointSchema>(checkpointCollectionName)\n .deleteMany({ id: indexerId }, { session });\n\n // Delete all filters for this indexer\n await db\n .collection<FilterSchema>(filterCollectionName)\n .deleteMany({ id: indexerId }, { session });\n } catch (error) {\n throw new MongoStorageError(\"Failed to reset persistence state\", {\n cause: error,\n });\n }\n}\n","import type { Cursor } from \"@apibara/protocol\";\nimport type {\n BulkWriteOptions,\n ClientSession,\n Collection,\n CollectionOptions,\n Db,\n DeleteOptions,\n Document,\n Filter,\n FindCursor,\n FindOneAndUpdateOptions,\n FindOptions,\n InsertManyResult,\n InsertOneOptions,\n InsertOneResult,\n MatchKeysAndValues,\n OptionalUnlessRequiredId,\n UpdateFilter,\n UpdateOptions,\n UpdateResult,\n WithId,\n} from \"mongodb\";\n\nexport class MongoStorage {\n constructor(\n private db: Db,\n private session: ClientSession,\n private endCursor?: Cursor,\n ) {}\n\n collection<TSchema extends Document = Document>(\n name: string,\n options?: CollectionOptions,\n ) {\n const collection = this.db.collection<TSchema>(name, options);\n\n return new MongoCollection<TSchema>(\n this.session,\n collection,\n this.endCursor,\n );\n }\n}\n\nexport type MongoCursor = {\n from: number | null;\n to: number | null;\n};\n\nexport type CursoredSchema<TSchema extends Document> = TSchema & {\n _cursor: MongoCursor;\n};\n\nexport class MongoCollection<TSchema extends Document> {\n constructor(\n private session: ClientSession,\n private collection: Collection<TSchema>,\n private endCursor?: Cursor,\n ) {}\n\n async insertOne(\n doc: OptionalUnlessRequiredId<TSchema>,\n options?: InsertOneOptions,\n ): Promise<InsertOneResult<TSchema>> {\n return await this.collection.insertOne(\n {\n ...doc,\n _cursor: {\n from: Number(this.endCursor?.orderKey),\n to: null,\n } as MongoCursor,\n },\n { ...options, session: this.session },\n );\n }\n\n async insertMany(\n docs: ReadonlyArray<OptionalUnlessRequiredId<TSchema>>,\n options?: BulkWriteOptions,\n ): Promise<InsertManyResult<TSchema>> {\n return await this.collection.insertMany(\n docs.map((doc) => ({\n ...doc,\n _cursor: {\n from: Number(this.endCursor?.orderKey),\n to: null,\n } as MongoCursor,\n })),\n { ...options, session: this.session },\n );\n }\n\n async updateOne(\n filter: Filter<TSchema>,\n update: UpdateFilter<TSchema>,\n options?: UpdateOptions,\n ): Promise<UpdateResult<TSchema>> {\n // 1. Find and update the document, getting the old version\n const oldDoc = await this.collection.findOneAndUpdate(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n ...update,\n $set: {\n ...update.$set,\n \"_cursor.from\": Number(this.endCursor?.orderKey),\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n {\n ...options,\n session: this.session,\n returnDocument: \"before\",\n } as FindOneAndUpdateOptions,\n );\n\n // 2. If we found and updated a document, insert its old version\n if (oldDoc) {\n const { _id, ...doc } = oldDoc;\n await this.collection.insertOne(\n {\n ...doc,\n _cursor: {\n ...oldDoc._cursor,\n to: Number(this.endCursor?.orderKey),\n },\n } as unknown as OptionalUnlessRequiredId<TSchema>,\n { session: this.session },\n );\n }\n\n // 3. Return an UpdateResult-compatible object\n return {\n acknowledged: true,\n modifiedCount: oldDoc ? 1 : 0,\n upsertedId: null,\n upsertedCount: 0,\n matchedCount: oldDoc ? 1 : 0,\n };\n }\n\n async updateMany(\n filter: Filter<TSchema>,\n update: UpdateFilter<TSchema>,\n options?: UpdateOptions,\n ): Promise<UpdateResult<TSchema>> {\n // 1. Find all documents matching the filter that are latest (to: null)\n const oldDocs = await this.collection\n .find(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { session: this.session },\n )\n .toArray();\n\n // 2. Update to the new values with updateMany\n // (setting _cursor.from to endCursor, leaving _cursor.to unchanged)\n const updateResult = await this.collection.updateMany(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n ...update,\n $set: {\n ...update.$set,\n \"_cursor.from\": Number(this.endCursor?.orderKey),\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n\n // 3. Adjust the cursor.to of the old values\n const oldDocsWithUpdatedCursor = oldDocs.map(({ _id, ...doc }) => ({\n ...doc,\n _cursor: {\n ...doc._cursor,\n to: Number(this.endCursor?.orderKey),\n },\n }));\n\n // 4. Insert the old values back into the db\n if (oldDocsWithUpdatedCursor.length > 0) {\n await this.collection.insertMany(\n oldDocsWithUpdatedCursor as unknown as OptionalUnlessRequiredId<TSchema>[],\n { session: this.session },\n );\n }\n\n return updateResult;\n }\n\n async deleteOne(\n filter: Filter<TSchema>,\n options?: DeleteOptions,\n ): Promise<UpdateResult<TSchema>> {\n return await this.collection.updateOne(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n $set: {\n \"_cursor.to\": Number(this.endCursor?.orderKey),\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n }\n\n async deleteMany(\n filter?: Filter<TSchema>,\n options?: DeleteOptions,\n ): Promise<UpdateResult<TSchema>> {\n return await this.collection.updateMany(\n {\n ...((filter ?? {}) as Filter<TSchema>),\n \"_cursor.to\": null,\n },\n {\n $set: {\n \"_cursor.to\": Number(this.endCursor?.orderKey),\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n }\n\n async findOne(\n filter: Filter<TSchema>,\n options?: Omit<FindOptions, \"timeoutMode\">,\n ): Promise<WithId<TSchema> | null> {\n return await this.collection.findOne(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { ...options, session: this.session },\n );\n }\n\n find(\n filter: Filter<TSchema>,\n options?: FindOptions,\n ): FindCursor<WithId<TSchema>> {\n return this.collection.find(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { ...options, session: this.session },\n );\n }\n}\n","import { useIndexerContext } from \"@apibara/indexer\";\nimport { defineIndexerPlugin, useLogger } from \"@apibara/indexer/plugins\";\nimport type { DbOptions, MongoClient } from \"mongodb\";\n\nimport { generateIndexerId } from \"@apibara/indexer/internal\";\nimport { useInternalContext } from \"@apibara/indexer/internal/plugins\";\nimport type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport { cleanupStorage, finalize, invalidate } from \"./mongo\";\nimport {\n finalizeState,\n getState,\n initializePersistentState,\n invalidateState,\n persistState,\n resetPersistence,\n} from \"./persistence\";\nimport { MongoStorage } from \"./storage\";\nimport { MongoStorageError, withTransaction } from \"./utils\";\n\nexport { MongoCollection, MongoStorage } from \"./storage\";\n\nconst MONGO_PROPERTY = \"_mongo\";\n\nexport function useMongoStorage(): MongoStorage {\n const context = useIndexerContext();\n\n if (!context[MONGO_PROPERTY]) {\n throw new MongoStorageError(\n \"mongo storage is not available. Did you register the plugin?\",\n );\n }\n\n return context[MONGO_PROPERTY] as MongoStorage;\n}\n\nexport interface MongoStorageOptions {\n client: MongoClient;\n dbName: string;\n dbOptions?: DbOptions;\n collections: string[];\n persistState?: boolean;\n indexerName?: string;\n}\n/**\n * Creates a plugin that uses MongoDB as the storage layer.\n *\n * Supports storing the indexer's state and provides a simple Key-Value store.\n * @param options.client - The MongoDB client instance.\n * @param options.dbName - The name of the database.\n * @param options.dbOptions - The database options.\n * @param options.collections - The collections to use.\n * @param options.persistState - Whether to persist the indexer's state. Defaults to true.\n * @param options.indexerName - The name of the indexer. Defaults value is 'default'.\n */\nexport function mongoStorage<TFilter, TBlock>({\n client,\n dbName,\n dbOptions,\n collections,\n persistState: enablePersistence = true,\n indexerName: identifier = \"default\",\n}: MongoStorageOptions) {\n return defineIndexerPlugin<TFilter, TBlock>((indexer) => {\n let indexerId = \"\";\n const alwaysReindex = process.env[\"APIBARA_ALWAYS_REINDEX\"] === \"true\";\n let prevFinality: DataFinality | undefined;\n\n indexer.hooks.hook(\"plugins:init\", async () => {\n const { indexerName } = useInternalContext();\n indexerId = generateIndexerId(indexerName, identifier);\n const logger = useLogger();\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n if (enablePersistence) {\n await initializePersistentState(db, session);\n }\n\n if (alwaysReindex) {\n logger.warn(\n `Reindexing: Deleting all data from collections - ${collections.join(\", \")}`,\n );\n\n await cleanupStorage(db, session, collections);\n\n if (enablePersistence) {\n await resetPersistence({ db, session, indexerId });\n }\n\n logger.success(\"All data has been cleaned up for reindexing\");\n }\n });\n });\n\n indexer.hooks.hook(\"connect:before\", async ({ request }) => {\n if (!enablePersistence) {\n return;\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n const { cursor, filter } = await getState<TFilter>({\n db,\n session,\n indexerId,\n });\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(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await invalidate(db, session, cursor, collections);\n\n if (enablePersistence) {\n await invalidateState({ db, session, cursor, indexerId });\n }\n });\n });\n\n indexer.hooks.hook(\"connect:factory\", async ({ request, endCursor }) => {\n if (!enablePersistence) {\n return;\n }\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n if (endCursor && request.filter[1]) {\n await persistState({\n db,\n endCursor,\n session,\n filter: request.filter[1],\n indexerId,\n });\n }\n });\n });\n\n indexer.hooks.hook(\"message:finalize\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new MongoStorageError(\"finalized cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await finalize(db, session, cursor, collections);\n\n if (enablePersistence) {\n await finalizeState({ db, session, 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 MongoStorageError(\"invalidate cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await invalidate(db, session, cursor, collections);\n\n if (enablePersistence) {\n await invalidateState({ db, session, cursor, indexerId });\n }\n });\n });\n\n indexer.hooks.hook(\"handler:middleware\", async ({ use }) => {\n use(async (context, next) => {\n const { endCursor, finality, cursor } = context as {\n cursor: Cursor;\n endCursor: Cursor;\n finality: DataFinality;\n };\n\n if (!endCursor) {\n throw new MongoStorageError(\"end cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n context[MONGO_PROPERTY] = new MongoStorage(db, session, endCursor);\n\n if (prevFinality === \"pending\") {\n // invalidate if previous block's finality was \"pending\"\n await invalidate(db, session, cursor, collections);\n }\n\n await next();\n\n delete context[MONGO_PROPERTY];\n\n if (enablePersistence && finality !== \"pending\") {\n await persistState({\n db,\n endCursor,\n session,\n indexerId,\n });\n }\n\n prevFinality = finality;\n });\n });\n });\n });\n}\n"],"names":["session","normalizeCursor","useIndexerContext","defineIndexerPlugin","useInternalContext","generateIndexerId","useLogger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/mongo.ts","../src/utils.ts","../src/persistence.ts","../src/storage.ts","../src/index.ts"],"sourcesContent":["import type { Cursor } from \"@apibara/protocol\";\nimport type { ClientSession, Db } from \"mongodb\";\n\nexport async function invalidate(\n db: Db,\n session: ClientSession,\n cursor: Cursor,\n collections: string[],\n) {\n for (const collection of collections) {\n // Delete documents where the lower bound of _cursor is greater than the invalidate cursor\n await db.collection(collection).deleteMany(\n {\n \"_cursor.from\": {\n $gt: cursor.orderKey,\n },\n },\n { session },\n );\n\n // Update documents where the upper bound of _cursor is greater than the invalidate cursor\n await db.collection(collection).updateMany(\n { \"_cursor.to\": { $gt: cursor.orderKey } },\n {\n $set: {\n \"_cursor.to\": null,\n },\n },\n { session },\n );\n }\n}\n\nexport async function finalize(\n db: Db,\n session: ClientSession,\n cursor: Cursor,\n collections: string[],\n) {\n for (const collection of collections) {\n // Delete documents where the upper bound of _cursor is less than the finalize cursor\n await db.collection(collection).deleteMany(\n {\n \"_cursor.to\": { $lte: cursor.orderKey },\n },\n { session },\n );\n }\n}\n\nexport async function cleanupStorage(\n db: Db,\n session: ClientSession,\n collections: string[],\n) {\n for (const collection of collections) {\n try {\n // Delete all documents in the collection\n await db.collection(collection).deleteMany({}, { session });\n } catch (error) {\n throw new Error(`Failed to clean up collection ${collection}`, {\n cause: error,\n });\n }\n }\n}\n","import type { ClientSession, MongoClient } from \"mongodb\";\n\nexport class MongoStorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"MongoStorageError\";\n }\n}\n\nexport async function withTransaction<T>(\n client: MongoClient,\n cb: (session: ClientSession) => Promise<T>,\n) {\n return await client.withSession(async (session) => {\n return await session.withTransaction(\n async (session) => {\n return await cb(session);\n },\n {\n retryWrites: false,\n },\n );\n });\n}\n","import { type Cursor, normalizeCursor } from \"@apibara/protocol\";\nimport type { ClientSession, Db } from \"mongodb\";\nimport { MongoStorageError } from \"./utils\";\n\nexport type CheckpointSchema = {\n id: string;\n orderKey: bigint;\n uniqueKey: string | null;\n};\n\nexport type FilterSchema = {\n id: string;\n filter: Record<string, unknown>;\n fromBlock: bigint;\n toBlock: bigint | null;\n};\n\nexport const checkpointCollectionName = \"checkpoints\";\nexport const filterCollectionName = \"filters\";\n\nexport async function initializePersistentState(\n db: Db,\n session: ClientSession,\n) {\n const checkpoint = db.collection<CheckpointSchema>(checkpointCollectionName);\n const filter = db.collection<FilterSchema>(filterCollectionName);\n\n await checkpoint.createIndex({ id: 1 }, { session });\n await filter.createIndex({ id: 1, fromBlock: 1 }, { session });\n}\n\nexport async function persistState<TFilter>(props: {\n db: Db;\n session: ClientSession;\n endCursor: Cursor;\n filter?: TFilter;\n indexerId: string;\n}) {\n const { db, session, endCursor, filter, indexerId } = props;\n\n if (endCursor) {\n await db.collection<CheckpointSchema>(checkpointCollectionName).updateOne(\n { id: indexerId },\n {\n $set: {\n orderKey: endCursor.orderKey,\n uniqueKey: endCursor.uniqueKey ? endCursor.uniqueKey : null,\n },\n },\n { upsert: true, session },\n );\n\n if (filter) {\n // Update existing filter's to_block\n await db\n .collection<FilterSchema>(filterCollectionName)\n .updateMany(\n { id: indexerId, toBlock: null },\n { $set: { toBlock: endCursor.orderKey } },\n { session },\n );\n\n // Insert new filter\n await db.collection<FilterSchema>(filterCollectionName).updateOne(\n {\n id: indexerId,\n fromBlock: endCursor.orderKey,\n },\n {\n $set: {\n filter: filter as Record<string, unknown>,\n fromBlock: endCursor.orderKey,\n toBlock: null,\n },\n },\n { upsert: true, session },\n );\n }\n }\n}\n\nexport async function getState<TFilter>(props: {\n db: Db;\n session: ClientSession;\n indexerId: string;\n}): Promise<{ cursor?: Cursor; filter?: TFilter }> {\n const { db, session, indexerId } = props;\n\n let cursor: Cursor | undefined;\n let filter: TFilter | undefined;\n\n const checkpointRow = await db\n .collection<CheckpointSchema>(checkpointCollectionName)\n .findOne({ id: indexerId }, { session });\n\n if (checkpointRow) {\n cursor = normalizeCursor({\n orderKey: BigInt(checkpointRow.orderKey),\n uniqueKey: checkpointRow.uniqueKey,\n });\n }\n\n const filterRow = await db\n .collection<FilterSchema>(filterCollectionName)\n .findOne(\n {\n id: indexerId,\n toBlock: null,\n },\n { session },\n );\n\n if (filterRow) {\n filter = filterRow.filter as TFilter;\n }\n\n return { cursor, filter };\n}\n\nexport async function invalidateState(props: {\n db: Db;\n session: ClientSession;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { db, session, cursor, indexerId } = props;\n\n await db\n .collection<FilterSchema>(filterCollectionName)\n .deleteMany(\n { id: indexerId, fromBlock: { $gt: cursor.orderKey } },\n { session },\n );\n\n await db\n .collection<FilterSchema>(filterCollectionName)\n .updateMany(\n { id: indexerId, toBlock: { $gt: cursor.orderKey } },\n { $set: { toBlock: null } },\n { session },\n );\n}\n\nexport async function finalizeState(props: {\n db: Db;\n session: ClientSession;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { db, session, cursor, indexerId } = props;\n\n await db.collection<FilterSchema>(filterCollectionName).deleteMany(\n {\n id: indexerId,\n toBlock: { $lte: cursor.orderKey },\n },\n { session },\n );\n}\n\nexport async function resetPersistence(props: {\n db: Db;\n session: ClientSession;\n indexerId: string;\n}) {\n const { db, session, indexerId } = props;\n\n try {\n // Delete all checkpoints for this indexer\n await db\n .collection<CheckpointSchema>(checkpointCollectionName)\n .deleteMany({ id: indexerId }, { session });\n\n // Delete all filters for this indexer\n await db\n .collection<FilterSchema>(filterCollectionName)\n .deleteMany({ id: indexerId }, { session });\n } catch (error) {\n throw new MongoStorageError(\"Failed to reset persistence state\", {\n cause: error,\n });\n }\n}\n","import type { Cursor } from \"@apibara/protocol\";\nimport type {\n BulkWriteOptions,\n ClientSession,\n Collection,\n CollectionOptions,\n Db,\n DeleteOptions,\n Document,\n Filter,\n FindCursor,\n FindOneAndUpdateOptions,\n FindOptions,\n InsertManyResult,\n InsertOneOptions,\n InsertOneResult,\n MatchKeysAndValues,\n OptionalUnlessRequiredId,\n UpdateFilter,\n UpdateOptions,\n UpdateResult,\n WithId,\n} from \"mongodb\";\n\nexport class MongoStorage {\n constructor(\n private db: Db,\n private session: ClientSession,\n private endCursor?: Cursor,\n ) {}\n\n collection<TSchema extends Document = Document>(\n name: string,\n options?: CollectionOptions,\n ) {\n const collection = this.db.collection<TSchema>(name, options);\n\n return new MongoCollection<TSchema>(\n this.session,\n collection,\n this.endCursor,\n );\n }\n}\n\nexport type MongoCursor = {\n from: bigint | null;\n to: bigint | null;\n};\n\nexport type CursoredSchema<TSchema extends Document> = TSchema & {\n _cursor: MongoCursor;\n};\n\nexport class MongoCollection<TSchema extends Document> {\n constructor(\n private session: ClientSession,\n private collection: Collection<TSchema>,\n private endCursor?: Cursor,\n ) {}\n\n async insertOne(\n doc: OptionalUnlessRequiredId<TSchema>,\n options?: InsertOneOptions,\n ): Promise<InsertOneResult<TSchema>> {\n return await this.collection.insertOne(\n {\n ...doc,\n _cursor: {\n from: this.endCursor?.orderKey ?? null,\n to: null,\n } as MongoCursor,\n },\n { ...options, session: this.session },\n );\n }\n\n async insertMany(\n docs: ReadonlyArray<OptionalUnlessRequiredId<TSchema>>,\n options?: BulkWriteOptions,\n ): Promise<InsertManyResult<TSchema>> {\n return await this.collection.insertMany(\n docs.map((doc) => ({\n ...doc,\n _cursor: {\n from: this.endCursor?.orderKey ?? null,\n to: null,\n } as MongoCursor,\n })),\n { ...options, session: this.session },\n );\n }\n\n async updateOne(\n filter: Filter<TSchema>,\n update: UpdateFilter<TSchema>,\n options?: UpdateOptions,\n ): Promise<UpdateResult<TSchema>> {\n // 1. Find and update the document, getting the old version\n const oldDoc = await this.collection.findOneAndUpdate(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n ...update,\n $set: {\n ...update.$set,\n \"_cursor.from\": this.endCursor?.orderKey ?? null,\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n {\n ...options,\n session: this.session,\n returnDocument: \"before\",\n } as FindOneAndUpdateOptions,\n );\n\n // 2. If we found and updated a document, insert its old version\n if (oldDoc) {\n const { _id, ...doc } = oldDoc;\n await this.collection.insertOne(\n {\n ...doc,\n _cursor: {\n ...oldDoc._cursor,\n to: this.endCursor?.orderKey ?? null,\n },\n } as unknown as OptionalUnlessRequiredId<TSchema>,\n { session: this.session },\n );\n }\n\n // 3. Return an UpdateResult-compatible object\n return {\n acknowledged: true,\n modifiedCount: oldDoc ? 1 : 0,\n upsertedId: null,\n upsertedCount: 0,\n matchedCount: oldDoc ? 1 : 0,\n };\n }\n\n async updateMany(\n filter: Filter<TSchema>,\n update: UpdateFilter<TSchema>,\n options?: UpdateOptions,\n ): Promise<UpdateResult<TSchema>> {\n // 1. Find all documents matching the filter that are latest (to: null)\n const oldDocs = await this.collection\n .find(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { session: this.session },\n )\n .toArray();\n\n // 2. Update to the new values with updateMany\n // (setting _cursor.from to endCursor, leaving _cursor.to unchanged)\n const updateResult = await this.collection.updateMany(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n ...update,\n $set: {\n ...update.$set,\n \"_cursor.from\": this.endCursor?.orderKey ?? null,\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n\n // 3. Adjust the cursor.to of the old values\n const oldDocsWithUpdatedCursor = oldDocs.map(({ _id, ...doc }) => ({\n ...doc,\n _cursor: {\n ...doc._cursor,\n to: this.endCursor?.orderKey ?? null,\n },\n }));\n\n // 4. Insert the old values back into the db\n if (oldDocsWithUpdatedCursor.length > 0) {\n await this.collection.insertMany(\n oldDocsWithUpdatedCursor as unknown as OptionalUnlessRequiredId<TSchema>[],\n { session: this.session },\n );\n }\n\n return updateResult;\n }\n\n async deleteOne(\n filter: Filter<TSchema>,\n options?: DeleteOptions,\n ): Promise<UpdateResult<TSchema>> {\n return await this.collection.updateOne(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n $set: {\n \"_cursor.to\": this.endCursor?.orderKey ?? null,\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n }\n\n async deleteMany(\n filter?: Filter<TSchema>,\n options?: DeleteOptions,\n ): Promise<UpdateResult<TSchema>> {\n return await this.collection.updateMany(\n {\n ...((filter ?? {}) as Filter<TSchema>),\n \"_cursor.to\": null,\n },\n {\n $set: {\n \"_cursor.to\": this.endCursor?.orderKey ?? null,\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n }\n\n async findOne(\n filter: Filter<TSchema>,\n options?: Omit<FindOptions, \"timeoutMode\">,\n ): Promise<WithId<TSchema> | null> {\n return await this.collection.findOne(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { ...options, session: this.session },\n );\n }\n\n find(\n filter: Filter<TSchema>,\n options?: FindOptions,\n ): FindCursor<WithId<TSchema>> {\n return this.collection.find(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { ...options, session: this.session },\n );\n }\n}\n","import { useIndexerContext } from \"@apibara/indexer\";\nimport { defineIndexerPlugin, useLogger } from \"@apibara/indexer/plugins\";\nimport type { DbOptions, MongoClient } from \"mongodb\";\n\nimport { generateIndexerId } from \"@apibara/indexer/internal\";\nimport { useInternalContext } from \"@apibara/indexer/internal/plugins\";\nimport type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport { cleanupStorage, finalize, invalidate } from \"./mongo\";\nimport {\n finalizeState,\n getState,\n initializePersistentState,\n invalidateState,\n persistState,\n resetPersistence,\n} from \"./persistence\";\nimport { MongoStorage } from \"./storage\";\nimport { MongoStorageError, withTransaction } from \"./utils\";\n\nexport { MongoCollection, MongoStorage } from \"./storage\";\n\nconst MONGO_PROPERTY = \"_mongo\";\n\nexport function useMongoStorage(): MongoStorage {\n const context = useIndexerContext();\n\n if (!context[MONGO_PROPERTY]) {\n throw new MongoStorageError(\n \"mongo storage is not available. Did you register the plugin?\",\n );\n }\n\n return context[MONGO_PROPERTY] as MongoStorage;\n}\n\nexport interface MongoStorageOptions {\n client: MongoClient;\n dbName: string;\n dbOptions?: DbOptions;\n collections: string[];\n persistState?: boolean;\n indexerName?: string;\n}\n/**\n * Creates a plugin that uses MongoDB as the storage layer.\n *\n * Supports storing the indexer's state and provides a simple Key-Value store.\n * @param options.client - The MongoDB client instance.\n * @param options.dbName - The name of the database.\n * @param options.dbOptions - The database options.\n * @param options.collections - The collections to use.\n * @param options.persistState - Whether to persist the indexer's state. Defaults to true.\n * @param options.indexerName - The name of the indexer. Defaults value is 'default'.\n */\nexport function mongoStorage<TFilter, TBlock>({\n client,\n dbName,\n dbOptions,\n collections,\n persistState: enablePersistence = true,\n indexerName: identifier = \"default\",\n}: MongoStorageOptions) {\n return defineIndexerPlugin<TFilter, TBlock>((indexer) => {\n let indexerId = \"\";\n const alwaysReindex = process.env[\"APIBARA_ALWAYS_REINDEX\"] === \"true\";\n let prevFinality: DataFinality | undefined;\n\n indexer.hooks.hook(\"plugins:init\", async () => {\n const { indexerName } = useInternalContext();\n indexerId = generateIndexerId(indexerName, identifier);\n const logger = useLogger();\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n if (enablePersistence) {\n await initializePersistentState(db, session);\n }\n\n if (alwaysReindex) {\n logger.warn(\n `Reindexing: Deleting all data from collections - ${collections.join(\", \")}`,\n );\n\n await cleanupStorage(db, session, collections);\n\n if (enablePersistence) {\n await resetPersistence({ db, session, indexerId });\n }\n\n logger.success(\"All data has been cleaned up for reindexing\");\n }\n });\n });\n\n indexer.hooks.hook(\"connect:before\", async ({ request }) => {\n if (!enablePersistence) {\n return;\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n const { cursor, filter } = await getState<TFilter>({\n db,\n session,\n indexerId,\n });\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(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await invalidate(db, session, cursor, collections);\n\n if (enablePersistence) {\n await invalidateState({ db, session, cursor, indexerId });\n }\n });\n });\n\n indexer.hooks.hook(\"connect:factory\", async ({ request, endCursor }) => {\n if (!enablePersistence) {\n return;\n }\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n if (endCursor && request.filter[1]) {\n await persistState({\n db,\n endCursor,\n session,\n filter: request.filter[1],\n indexerId,\n });\n }\n });\n });\n\n indexer.hooks.hook(\"message:finalize\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new MongoStorageError(\"finalized cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await finalize(db, session, cursor, collections);\n\n if (enablePersistence) {\n await finalizeState({ db, session, 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 MongoStorageError(\"invalidate cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await invalidate(db, session, cursor, collections);\n\n if (enablePersistence) {\n await invalidateState({ db, session, cursor, indexerId });\n }\n });\n });\n\n indexer.hooks.hook(\"handler:middleware\", async ({ use }) => {\n use(async (context, next) => {\n const { endCursor, finality, cursor } = context as {\n cursor: Cursor;\n endCursor: Cursor;\n finality: DataFinality;\n };\n\n if (!endCursor) {\n throw new MongoStorageError(\"end cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n context[MONGO_PROPERTY] = new MongoStorage(db, session, endCursor);\n\n if (prevFinality === \"pending\") {\n // invalidate if previous block's finality was \"pending\"\n await invalidate(db, session, cursor, collections);\n }\n\n await next();\n\n delete context[MONGO_PROPERTY];\n\n if (enablePersistence && finality !== \"pending\") {\n await persistState({\n db,\n endCursor,\n session,\n indexerId,\n });\n }\n\n prevFinality = finality;\n });\n });\n });\n });\n}\n"],"names":["session","normalizeCursor","useIndexerContext","defineIndexerPlugin","useInternalContext","generateIndexerId","useLogger"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -5,18 +5,17 @@ import { useInternalContext } from '@apibara/indexer/internal/plugins';
|
|
|
5
5
|
import { normalizeCursor } from '@apibara/protocol';
|
|
6
6
|
|
|
7
7
|
async function invalidate(db, session, cursor, collections) {
|
|
8
|
-
const orderKeyValue = Number(cursor.orderKey);
|
|
9
8
|
for (const collection of collections) {
|
|
10
9
|
await db.collection(collection).deleteMany(
|
|
11
10
|
{
|
|
12
11
|
"_cursor.from": {
|
|
13
|
-
$gt:
|
|
12
|
+
$gt: cursor.orderKey
|
|
14
13
|
}
|
|
15
14
|
},
|
|
16
15
|
{ session }
|
|
17
16
|
);
|
|
18
17
|
await db.collection(collection).updateMany(
|
|
19
|
-
{ "_cursor.to": { $gt:
|
|
18
|
+
{ "_cursor.to": { $gt: cursor.orderKey } },
|
|
20
19
|
{
|
|
21
20
|
$set: {
|
|
22
21
|
"_cursor.to": null
|
|
@@ -27,11 +26,10 @@ async function invalidate(db, session, cursor, collections) {
|
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
async function finalize(db, session, cursor, collections) {
|
|
30
|
-
const orderKeyValue = Number(cursor.orderKey);
|
|
31
29
|
for (const collection of collections) {
|
|
32
30
|
await db.collection(collection).deleteMany(
|
|
33
31
|
{
|
|
34
|
-
"_cursor.to": { $lte:
|
|
32
|
+
"_cursor.to": { $lte: cursor.orderKey }
|
|
35
33
|
},
|
|
36
34
|
{ session }
|
|
37
35
|
);
|
|
@@ -83,7 +81,7 @@ async function persistState(props) {
|
|
|
83
81
|
{ id: indexerId },
|
|
84
82
|
{
|
|
85
83
|
$set: {
|
|
86
|
-
orderKey:
|
|
84
|
+
orderKey: endCursor.orderKey,
|
|
87
85
|
uniqueKey: endCursor.uniqueKey ? endCursor.uniqueKey : null
|
|
88
86
|
}
|
|
89
87
|
},
|
|
@@ -92,18 +90,18 @@ async function persistState(props) {
|
|
|
92
90
|
if (filter) {
|
|
93
91
|
await db.collection(filterCollectionName).updateMany(
|
|
94
92
|
{ id: indexerId, toBlock: null },
|
|
95
|
-
{ $set: { toBlock:
|
|
93
|
+
{ $set: { toBlock: endCursor.orderKey } },
|
|
96
94
|
{ session }
|
|
97
95
|
);
|
|
98
96
|
await db.collection(filterCollectionName).updateOne(
|
|
99
97
|
{
|
|
100
98
|
id: indexerId,
|
|
101
|
-
fromBlock:
|
|
99
|
+
fromBlock: endCursor.orderKey
|
|
102
100
|
},
|
|
103
101
|
{
|
|
104
102
|
$set: {
|
|
105
103
|
filter,
|
|
106
|
-
fromBlock:
|
|
104
|
+
fromBlock: endCursor.orderKey,
|
|
107
105
|
toBlock: null
|
|
108
106
|
}
|
|
109
107
|
},
|
|
@@ -138,11 +136,11 @@ async function getState(props) {
|
|
|
138
136
|
async function invalidateState(props) {
|
|
139
137
|
const { db, session, cursor, indexerId } = props;
|
|
140
138
|
await db.collection(filterCollectionName).deleteMany(
|
|
141
|
-
{ id: indexerId, fromBlock: { $gt:
|
|
139
|
+
{ id: indexerId, fromBlock: { $gt: cursor.orderKey } },
|
|
142
140
|
{ session }
|
|
143
141
|
);
|
|
144
142
|
await db.collection(filterCollectionName).updateMany(
|
|
145
|
-
{ id: indexerId, toBlock: { $gt:
|
|
143
|
+
{ id: indexerId, toBlock: { $gt: cursor.orderKey } },
|
|
146
144
|
{ $set: { toBlock: null } },
|
|
147
145
|
{ session }
|
|
148
146
|
);
|
|
@@ -152,7 +150,7 @@ async function finalizeState(props) {
|
|
|
152
150
|
await db.collection(filterCollectionName).deleteMany(
|
|
153
151
|
{
|
|
154
152
|
id: indexerId,
|
|
155
|
-
toBlock: { $lte:
|
|
153
|
+
toBlock: { $lte: cursor.orderKey }
|
|
156
154
|
},
|
|
157
155
|
{ session }
|
|
158
156
|
);
|
|
@@ -195,7 +193,7 @@ class MongoCollection {
|
|
|
195
193
|
{
|
|
196
194
|
...doc,
|
|
197
195
|
_cursor: {
|
|
198
|
-
from:
|
|
196
|
+
from: this.endCursor?.orderKey ?? null,
|
|
199
197
|
to: null
|
|
200
198
|
}
|
|
201
199
|
},
|
|
@@ -207,7 +205,7 @@ class MongoCollection {
|
|
|
207
205
|
docs.map((doc) => ({
|
|
208
206
|
...doc,
|
|
209
207
|
_cursor: {
|
|
210
|
-
from:
|
|
208
|
+
from: this.endCursor?.orderKey ?? null,
|
|
211
209
|
to: null
|
|
212
210
|
}
|
|
213
211
|
})),
|
|
@@ -224,7 +222,7 @@ class MongoCollection {
|
|
|
224
222
|
...update,
|
|
225
223
|
$set: {
|
|
226
224
|
...update.$set,
|
|
227
|
-
"_cursor.from":
|
|
225
|
+
"_cursor.from": this.endCursor?.orderKey ?? null
|
|
228
226
|
}
|
|
229
227
|
},
|
|
230
228
|
{
|
|
@@ -240,7 +238,7 @@ class MongoCollection {
|
|
|
240
238
|
...doc,
|
|
241
239
|
_cursor: {
|
|
242
240
|
...oldDoc._cursor,
|
|
243
|
-
to:
|
|
241
|
+
to: this.endCursor?.orderKey ?? null
|
|
244
242
|
}
|
|
245
243
|
},
|
|
246
244
|
{ session: this.session }
|
|
@@ -271,7 +269,7 @@ class MongoCollection {
|
|
|
271
269
|
...update,
|
|
272
270
|
$set: {
|
|
273
271
|
...update.$set,
|
|
274
|
-
"_cursor.from":
|
|
272
|
+
"_cursor.from": this.endCursor?.orderKey ?? null
|
|
275
273
|
}
|
|
276
274
|
},
|
|
277
275
|
{ ...options, session: this.session }
|
|
@@ -280,7 +278,7 @@ class MongoCollection {
|
|
|
280
278
|
...doc,
|
|
281
279
|
_cursor: {
|
|
282
280
|
...doc._cursor,
|
|
283
|
-
to:
|
|
281
|
+
to: this.endCursor?.orderKey ?? null
|
|
284
282
|
}
|
|
285
283
|
}));
|
|
286
284
|
if (oldDocsWithUpdatedCursor.length > 0) {
|
|
@@ -299,7 +297,7 @@ class MongoCollection {
|
|
|
299
297
|
},
|
|
300
298
|
{
|
|
301
299
|
$set: {
|
|
302
|
-
"_cursor.to":
|
|
300
|
+
"_cursor.to": this.endCursor?.orderKey ?? null
|
|
303
301
|
}
|
|
304
302
|
},
|
|
305
303
|
{ ...options, session: this.session }
|
|
@@ -313,7 +311,7 @@ class MongoCollection {
|
|
|
313
311
|
},
|
|
314
312
|
{
|
|
315
313
|
$set: {
|
|
316
|
-
"_cursor.to":
|
|
314
|
+
"_cursor.to": this.endCursor?.orderKey ?? null
|
|
317
315
|
}
|
|
318
316
|
},
|
|
319
317
|
{ ...options, session: this.session }
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/mongo.ts","../src/utils.ts","../src/persistence.ts","../src/storage.ts","../src/index.ts"],"sourcesContent":["import type { Cursor } from \"@apibara/protocol\";\nimport type { ClientSession, Db } from \"mongodb\";\n\nexport async function invalidate(\n db: Db,\n session: ClientSession,\n cursor: Cursor,\n collections: string[],\n) {\n const orderKeyValue = Number(cursor.orderKey);\n for (const collection of collections) {\n // Delete documents where the lower bound of _cursor is greater than the invalidate cursor\n await db.collection(collection).deleteMany(\n {\n \"_cursor.from\": {\n $gt: orderKeyValue,\n },\n },\n { session },\n );\n\n // Update documents where the upper bound of _cursor is greater than the invalidate cursor\n await db.collection(collection).updateMany(\n { \"_cursor.to\": { $gt: orderKeyValue } },\n {\n $set: {\n \"_cursor.to\": null,\n },\n },\n { session },\n );\n }\n}\n\nexport async function finalize(\n db: Db,\n session: ClientSession,\n cursor: Cursor,\n collections: string[],\n) {\n const orderKeyValue = Number(cursor.orderKey);\n for (const collection of collections) {\n // Delete documents where the upper bound of _cursor is less than the finalize cursor\n await db.collection(collection).deleteMany(\n {\n \"_cursor.to\": { $lte: orderKeyValue },\n },\n { session },\n );\n }\n}\n\nexport async function cleanupStorage(\n db: Db,\n session: ClientSession,\n collections: string[],\n) {\n for (const collection of collections) {\n try {\n // Delete all documents in the collection\n await db.collection(collection).deleteMany({}, { session });\n } catch (error) {\n throw new Error(`Failed to clean up collection ${collection}`, {\n cause: error,\n });\n }\n }\n}\n","import type { ClientSession, MongoClient } from \"mongodb\";\n\nexport class MongoStorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"MongoStorageError\";\n }\n}\n\nexport async function withTransaction<T>(\n client: MongoClient,\n cb: (session: ClientSession) => Promise<T>,\n) {\n return await client.withSession(async (session) => {\n return await session.withTransaction(\n async (session) => {\n return await cb(session);\n },\n {\n retryWrites: false,\n },\n );\n });\n}\n","import { type Cursor, normalizeCursor } from \"@apibara/protocol\";\nimport type { ClientSession, Db } from \"mongodb\";\nimport { MongoStorageError } from \"./utils\";\n\nexport type CheckpointSchema = {\n id: string;\n orderKey: number;\n uniqueKey: string | null;\n};\n\nexport type FilterSchema = {\n id: string;\n filter: Record<string, unknown>;\n fromBlock: number;\n toBlock: number | null;\n};\n\nexport const checkpointCollectionName = \"checkpoints\";\nexport const filterCollectionName = \"filters\";\n\nexport async function initializePersistentState(\n db: Db,\n session: ClientSession,\n) {\n const checkpoint = db.collection<CheckpointSchema>(checkpointCollectionName);\n const filter = db.collection<FilterSchema>(filterCollectionName);\n\n await checkpoint.createIndex({ id: 1 }, { session });\n await filter.createIndex({ id: 1, fromBlock: 1 }, { session });\n}\n\nexport async function persistState<TFilter>(props: {\n db: Db;\n session: ClientSession;\n endCursor: Cursor;\n filter?: TFilter;\n indexerId: string;\n}) {\n const { db, session, endCursor, filter, indexerId } = props;\n\n if (endCursor) {\n await db.collection<CheckpointSchema>(checkpointCollectionName).updateOne(\n { id: indexerId },\n {\n $set: {\n orderKey: Number(endCursor.orderKey),\n uniqueKey: endCursor.uniqueKey ? endCursor.uniqueKey : null,\n },\n },\n { upsert: true, session },\n );\n\n if (filter) {\n // Update existing filter's to_block\n await db\n .collection<FilterSchema>(filterCollectionName)\n .updateMany(\n { id: indexerId, toBlock: null },\n { $set: { toBlock: Number(endCursor.orderKey) } },\n { session },\n );\n\n // Insert new filter\n await db.collection<FilterSchema>(filterCollectionName).updateOne(\n {\n id: indexerId,\n fromBlock: Number(endCursor.orderKey),\n },\n {\n $set: {\n filter: filter as Record<string, unknown>,\n fromBlock: Number(endCursor.orderKey),\n toBlock: null,\n },\n },\n { upsert: true, session },\n );\n }\n }\n}\n\nexport async function getState<TFilter>(props: {\n db: Db;\n session: ClientSession;\n indexerId: string;\n}): Promise<{ cursor?: Cursor; filter?: TFilter }> {\n const { db, session, indexerId } = props;\n\n let cursor: Cursor | undefined;\n let filter: TFilter | undefined;\n\n const checkpointRow = await db\n .collection<CheckpointSchema>(checkpointCollectionName)\n .findOne({ id: indexerId }, { session });\n\n if (checkpointRow) {\n cursor = normalizeCursor({\n orderKey: BigInt(checkpointRow.orderKey),\n uniqueKey: checkpointRow.uniqueKey,\n });\n }\n\n const filterRow = await db\n .collection<FilterSchema>(filterCollectionName)\n .findOne(\n {\n id: indexerId,\n toBlock: null,\n },\n { session },\n );\n\n if (filterRow) {\n filter = filterRow.filter as TFilter;\n }\n\n return { cursor, filter };\n}\n\nexport async function invalidateState(props: {\n db: Db;\n session: ClientSession;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { db, session, cursor, indexerId } = props;\n\n await db\n .collection<FilterSchema>(filterCollectionName)\n .deleteMany(\n { id: indexerId, fromBlock: { $gt: Number(cursor.orderKey) } },\n { session },\n );\n\n await db\n .collection<FilterSchema>(filterCollectionName)\n .updateMany(\n { id: indexerId, toBlock: { $gt: Number(cursor.orderKey) } },\n { $set: { toBlock: null } },\n { session },\n );\n}\n\nexport async function finalizeState(props: {\n db: Db;\n session: ClientSession;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { db, session, cursor, indexerId } = props;\n\n await db.collection<FilterSchema>(filterCollectionName).deleteMany(\n {\n id: indexerId,\n toBlock: { $lte: Number(cursor.orderKey) },\n },\n { session },\n );\n}\n\nexport async function resetPersistence(props: {\n db: Db;\n session: ClientSession;\n indexerId: string;\n}) {\n const { db, session, indexerId } = props;\n\n try {\n // Delete all checkpoints for this indexer\n await db\n .collection<CheckpointSchema>(checkpointCollectionName)\n .deleteMany({ id: indexerId }, { session });\n\n // Delete all filters for this indexer\n await db\n .collection<FilterSchema>(filterCollectionName)\n .deleteMany({ id: indexerId }, { session });\n } catch (error) {\n throw new MongoStorageError(\"Failed to reset persistence state\", {\n cause: error,\n });\n }\n}\n","import type { Cursor } from \"@apibara/protocol\";\nimport type {\n BulkWriteOptions,\n ClientSession,\n Collection,\n CollectionOptions,\n Db,\n DeleteOptions,\n Document,\n Filter,\n FindCursor,\n FindOneAndUpdateOptions,\n FindOptions,\n InsertManyResult,\n InsertOneOptions,\n InsertOneResult,\n MatchKeysAndValues,\n OptionalUnlessRequiredId,\n UpdateFilter,\n UpdateOptions,\n UpdateResult,\n WithId,\n} from \"mongodb\";\n\nexport class MongoStorage {\n constructor(\n private db: Db,\n private session: ClientSession,\n private endCursor?: Cursor,\n ) {}\n\n collection<TSchema extends Document = Document>(\n name: string,\n options?: CollectionOptions,\n ) {\n const collection = this.db.collection<TSchema>(name, options);\n\n return new MongoCollection<TSchema>(\n this.session,\n collection,\n this.endCursor,\n );\n }\n}\n\nexport type MongoCursor = {\n from: number | null;\n to: number | null;\n};\n\nexport type CursoredSchema<TSchema extends Document> = TSchema & {\n _cursor: MongoCursor;\n};\n\nexport class MongoCollection<TSchema extends Document> {\n constructor(\n private session: ClientSession,\n private collection: Collection<TSchema>,\n private endCursor?: Cursor,\n ) {}\n\n async insertOne(\n doc: OptionalUnlessRequiredId<TSchema>,\n options?: InsertOneOptions,\n ): Promise<InsertOneResult<TSchema>> {\n return await this.collection.insertOne(\n {\n ...doc,\n _cursor: {\n from: Number(this.endCursor?.orderKey),\n to: null,\n } as MongoCursor,\n },\n { ...options, session: this.session },\n );\n }\n\n async insertMany(\n docs: ReadonlyArray<OptionalUnlessRequiredId<TSchema>>,\n options?: BulkWriteOptions,\n ): Promise<InsertManyResult<TSchema>> {\n return await this.collection.insertMany(\n docs.map((doc) => ({\n ...doc,\n _cursor: {\n from: Number(this.endCursor?.orderKey),\n to: null,\n } as MongoCursor,\n })),\n { ...options, session: this.session },\n );\n }\n\n async updateOne(\n filter: Filter<TSchema>,\n update: UpdateFilter<TSchema>,\n options?: UpdateOptions,\n ): Promise<UpdateResult<TSchema>> {\n // 1. Find and update the document, getting the old version\n const oldDoc = await this.collection.findOneAndUpdate(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n ...update,\n $set: {\n ...update.$set,\n \"_cursor.from\": Number(this.endCursor?.orderKey),\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n {\n ...options,\n session: this.session,\n returnDocument: \"before\",\n } as FindOneAndUpdateOptions,\n );\n\n // 2. If we found and updated a document, insert its old version\n if (oldDoc) {\n const { _id, ...doc } = oldDoc;\n await this.collection.insertOne(\n {\n ...doc,\n _cursor: {\n ...oldDoc._cursor,\n to: Number(this.endCursor?.orderKey),\n },\n } as unknown as OptionalUnlessRequiredId<TSchema>,\n { session: this.session },\n );\n }\n\n // 3. Return an UpdateResult-compatible object\n return {\n acknowledged: true,\n modifiedCount: oldDoc ? 1 : 0,\n upsertedId: null,\n upsertedCount: 0,\n matchedCount: oldDoc ? 1 : 0,\n };\n }\n\n async updateMany(\n filter: Filter<TSchema>,\n update: UpdateFilter<TSchema>,\n options?: UpdateOptions,\n ): Promise<UpdateResult<TSchema>> {\n // 1. Find all documents matching the filter that are latest (to: null)\n const oldDocs = await this.collection\n .find(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { session: this.session },\n )\n .toArray();\n\n // 2. Update to the new values with updateMany\n // (setting _cursor.from to endCursor, leaving _cursor.to unchanged)\n const updateResult = await this.collection.updateMany(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n ...update,\n $set: {\n ...update.$set,\n \"_cursor.from\": Number(this.endCursor?.orderKey),\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n\n // 3. Adjust the cursor.to of the old values\n const oldDocsWithUpdatedCursor = oldDocs.map(({ _id, ...doc }) => ({\n ...doc,\n _cursor: {\n ...doc._cursor,\n to: Number(this.endCursor?.orderKey),\n },\n }));\n\n // 4. Insert the old values back into the db\n if (oldDocsWithUpdatedCursor.length > 0) {\n await this.collection.insertMany(\n oldDocsWithUpdatedCursor as unknown as OptionalUnlessRequiredId<TSchema>[],\n { session: this.session },\n );\n }\n\n return updateResult;\n }\n\n async deleteOne(\n filter: Filter<TSchema>,\n options?: DeleteOptions,\n ): Promise<UpdateResult<TSchema>> {\n return await this.collection.updateOne(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n $set: {\n \"_cursor.to\": Number(this.endCursor?.orderKey),\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n }\n\n async deleteMany(\n filter?: Filter<TSchema>,\n options?: DeleteOptions,\n ): Promise<UpdateResult<TSchema>> {\n return await this.collection.updateMany(\n {\n ...((filter ?? {}) as Filter<TSchema>),\n \"_cursor.to\": null,\n },\n {\n $set: {\n \"_cursor.to\": Number(this.endCursor?.orderKey),\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n }\n\n async findOne(\n filter: Filter<TSchema>,\n options?: Omit<FindOptions, \"timeoutMode\">,\n ): Promise<WithId<TSchema> | null> {\n return await this.collection.findOne(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { ...options, session: this.session },\n );\n }\n\n find(\n filter: Filter<TSchema>,\n options?: FindOptions,\n ): FindCursor<WithId<TSchema>> {\n return this.collection.find(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { ...options, session: this.session },\n );\n }\n}\n","import { useIndexerContext } from \"@apibara/indexer\";\nimport { defineIndexerPlugin, useLogger } from \"@apibara/indexer/plugins\";\nimport type { DbOptions, MongoClient } from \"mongodb\";\n\nimport { generateIndexerId } from \"@apibara/indexer/internal\";\nimport { useInternalContext } from \"@apibara/indexer/internal/plugins\";\nimport type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport { cleanupStorage, finalize, invalidate } from \"./mongo\";\nimport {\n finalizeState,\n getState,\n initializePersistentState,\n invalidateState,\n persistState,\n resetPersistence,\n} from \"./persistence\";\nimport { MongoStorage } from \"./storage\";\nimport { MongoStorageError, withTransaction } from \"./utils\";\n\nexport { MongoCollection, MongoStorage } from \"./storage\";\n\nconst MONGO_PROPERTY = \"_mongo\";\n\nexport function useMongoStorage(): MongoStorage {\n const context = useIndexerContext();\n\n if (!context[MONGO_PROPERTY]) {\n throw new MongoStorageError(\n \"mongo storage is not available. Did you register the plugin?\",\n );\n }\n\n return context[MONGO_PROPERTY] as MongoStorage;\n}\n\nexport interface MongoStorageOptions {\n client: MongoClient;\n dbName: string;\n dbOptions?: DbOptions;\n collections: string[];\n persistState?: boolean;\n indexerName?: string;\n}\n/**\n * Creates a plugin that uses MongoDB as the storage layer.\n *\n * Supports storing the indexer's state and provides a simple Key-Value store.\n * @param options.client - The MongoDB client instance.\n * @param options.dbName - The name of the database.\n * @param options.dbOptions - The database options.\n * @param options.collections - The collections to use.\n * @param options.persistState - Whether to persist the indexer's state. Defaults to true.\n * @param options.indexerName - The name of the indexer. Defaults value is 'default'.\n */\nexport function mongoStorage<TFilter, TBlock>({\n client,\n dbName,\n dbOptions,\n collections,\n persistState: enablePersistence = true,\n indexerName: identifier = \"default\",\n}: MongoStorageOptions) {\n return defineIndexerPlugin<TFilter, TBlock>((indexer) => {\n let indexerId = \"\";\n const alwaysReindex = process.env[\"APIBARA_ALWAYS_REINDEX\"] === \"true\";\n let prevFinality: DataFinality | undefined;\n\n indexer.hooks.hook(\"plugins:init\", async () => {\n const { indexerName } = useInternalContext();\n indexerId = generateIndexerId(indexerName, identifier);\n const logger = useLogger();\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n if (enablePersistence) {\n await initializePersistentState(db, session);\n }\n\n if (alwaysReindex) {\n logger.warn(\n `Reindexing: Deleting all data from collections - ${collections.join(\", \")}`,\n );\n\n await cleanupStorage(db, session, collections);\n\n if (enablePersistence) {\n await resetPersistence({ db, session, indexerId });\n }\n\n logger.success(\"All data has been cleaned up for reindexing\");\n }\n });\n });\n\n indexer.hooks.hook(\"connect:before\", async ({ request }) => {\n if (!enablePersistence) {\n return;\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n const { cursor, filter } = await getState<TFilter>({\n db,\n session,\n indexerId,\n });\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(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await invalidate(db, session, cursor, collections);\n\n if (enablePersistence) {\n await invalidateState({ db, session, cursor, indexerId });\n }\n });\n });\n\n indexer.hooks.hook(\"connect:factory\", async ({ request, endCursor }) => {\n if (!enablePersistence) {\n return;\n }\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n if (endCursor && request.filter[1]) {\n await persistState({\n db,\n endCursor,\n session,\n filter: request.filter[1],\n indexerId,\n });\n }\n });\n });\n\n indexer.hooks.hook(\"message:finalize\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new MongoStorageError(\"finalized cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await finalize(db, session, cursor, collections);\n\n if (enablePersistence) {\n await finalizeState({ db, session, 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 MongoStorageError(\"invalidate cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await invalidate(db, session, cursor, collections);\n\n if (enablePersistence) {\n await invalidateState({ db, session, cursor, indexerId });\n }\n });\n });\n\n indexer.hooks.hook(\"handler:middleware\", async ({ use }) => {\n use(async (context, next) => {\n const { endCursor, finality, cursor } = context as {\n cursor: Cursor;\n endCursor: Cursor;\n finality: DataFinality;\n };\n\n if (!endCursor) {\n throw new MongoStorageError(\"end cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n context[MONGO_PROPERTY] = new MongoStorage(db, session, endCursor);\n\n if (prevFinality === \"pending\") {\n // invalidate if previous block's finality was \"pending\"\n await invalidate(db, session, cursor, collections);\n }\n\n await next();\n\n delete context[MONGO_PROPERTY];\n\n if (enablePersistence && finality !== \"pending\") {\n await persistState({\n db,\n endCursor,\n session,\n indexerId,\n });\n }\n\n prevFinality = finality;\n });\n });\n });\n });\n}\n"],"names":["session"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/mongo.ts","../src/utils.ts","../src/persistence.ts","../src/storage.ts","../src/index.ts"],"sourcesContent":["import type { Cursor } from \"@apibara/protocol\";\nimport type { ClientSession, Db } from \"mongodb\";\n\nexport async function invalidate(\n db: Db,\n session: ClientSession,\n cursor: Cursor,\n collections: string[],\n) {\n for (const collection of collections) {\n // Delete documents where the lower bound of _cursor is greater than the invalidate cursor\n await db.collection(collection).deleteMany(\n {\n \"_cursor.from\": {\n $gt: cursor.orderKey,\n },\n },\n { session },\n );\n\n // Update documents where the upper bound of _cursor is greater than the invalidate cursor\n await db.collection(collection).updateMany(\n { \"_cursor.to\": { $gt: cursor.orderKey } },\n {\n $set: {\n \"_cursor.to\": null,\n },\n },\n { session },\n );\n }\n}\n\nexport async function finalize(\n db: Db,\n session: ClientSession,\n cursor: Cursor,\n collections: string[],\n) {\n for (const collection of collections) {\n // Delete documents where the upper bound of _cursor is less than the finalize cursor\n await db.collection(collection).deleteMany(\n {\n \"_cursor.to\": { $lte: cursor.orderKey },\n },\n { session },\n );\n }\n}\n\nexport async function cleanupStorage(\n db: Db,\n session: ClientSession,\n collections: string[],\n) {\n for (const collection of collections) {\n try {\n // Delete all documents in the collection\n await db.collection(collection).deleteMany({}, { session });\n } catch (error) {\n throw new Error(`Failed to clean up collection ${collection}`, {\n cause: error,\n });\n }\n }\n}\n","import type { ClientSession, MongoClient } from \"mongodb\";\n\nexport class MongoStorageError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"MongoStorageError\";\n }\n}\n\nexport async function withTransaction<T>(\n client: MongoClient,\n cb: (session: ClientSession) => Promise<T>,\n) {\n return await client.withSession(async (session) => {\n return await session.withTransaction(\n async (session) => {\n return await cb(session);\n },\n {\n retryWrites: false,\n },\n );\n });\n}\n","import { type Cursor, normalizeCursor } from \"@apibara/protocol\";\nimport type { ClientSession, Db } from \"mongodb\";\nimport { MongoStorageError } from \"./utils\";\n\nexport type CheckpointSchema = {\n id: string;\n orderKey: bigint;\n uniqueKey: string | null;\n};\n\nexport type FilterSchema = {\n id: string;\n filter: Record<string, unknown>;\n fromBlock: bigint;\n toBlock: bigint | null;\n};\n\nexport const checkpointCollectionName = \"checkpoints\";\nexport const filterCollectionName = \"filters\";\n\nexport async function initializePersistentState(\n db: Db,\n session: ClientSession,\n) {\n const checkpoint = db.collection<CheckpointSchema>(checkpointCollectionName);\n const filter = db.collection<FilterSchema>(filterCollectionName);\n\n await checkpoint.createIndex({ id: 1 }, { session });\n await filter.createIndex({ id: 1, fromBlock: 1 }, { session });\n}\n\nexport async function persistState<TFilter>(props: {\n db: Db;\n session: ClientSession;\n endCursor: Cursor;\n filter?: TFilter;\n indexerId: string;\n}) {\n const { db, session, endCursor, filter, indexerId } = props;\n\n if (endCursor) {\n await db.collection<CheckpointSchema>(checkpointCollectionName).updateOne(\n { id: indexerId },\n {\n $set: {\n orderKey: endCursor.orderKey,\n uniqueKey: endCursor.uniqueKey ? endCursor.uniqueKey : null,\n },\n },\n { upsert: true, session },\n );\n\n if (filter) {\n // Update existing filter's to_block\n await db\n .collection<FilterSchema>(filterCollectionName)\n .updateMany(\n { id: indexerId, toBlock: null },\n { $set: { toBlock: endCursor.orderKey } },\n { session },\n );\n\n // Insert new filter\n await db.collection<FilterSchema>(filterCollectionName).updateOne(\n {\n id: indexerId,\n fromBlock: endCursor.orderKey,\n },\n {\n $set: {\n filter: filter as Record<string, unknown>,\n fromBlock: endCursor.orderKey,\n toBlock: null,\n },\n },\n { upsert: true, session },\n );\n }\n }\n}\n\nexport async function getState<TFilter>(props: {\n db: Db;\n session: ClientSession;\n indexerId: string;\n}): Promise<{ cursor?: Cursor; filter?: TFilter }> {\n const { db, session, indexerId } = props;\n\n let cursor: Cursor | undefined;\n let filter: TFilter | undefined;\n\n const checkpointRow = await db\n .collection<CheckpointSchema>(checkpointCollectionName)\n .findOne({ id: indexerId }, { session });\n\n if (checkpointRow) {\n cursor = normalizeCursor({\n orderKey: BigInt(checkpointRow.orderKey),\n uniqueKey: checkpointRow.uniqueKey,\n });\n }\n\n const filterRow = await db\n .collection<FilterSchema>(filterCollectionName)\n .findOne(\n {\n id: indexerId,\n toBlock: null,\n },\n { session },\n );\n\n if (filterRow) {\n filter = filterRow.filter as TFilter;\n }\n\n return { cursor, filter };\n}\n\nexport async function invalidateState(props: {\n db: Db;\n session: ClientSession;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { db, session, cursor, indexerId } = props;\n\n await db\n .collection<FilterSchema>(filterCollectionName)\n .deleteMany(\n { id: indexerId, fromBlock: { $gt: cursor.orderKey } },\n { session },\n );\n\n await db\n .collection<FilterSchema>(filterCollectionName)\n .updateMany(\n { id: indexerId, toBlock: { $gt: cursor.orderKey } },\n { $set: { toBlock: null } },\n { session },\n );\n}\n\nexport async function finalizeState(props: {\n db: Db;\n session: ClientSession;\n cursor: Cursor;\n indexerId: string;\n}) {\n const { db, session, cursor, indexerId } = props;\n\n await db.collection<FilterSchema>(filterCollectionName).deleteMany(\n {\n id: indexerId,\n toBlock: { $lte: cursor.orderKey },\n },\n { session },\n );\n}\n\nexport async function resetPersistence(props: {\n db: Db;\n session: ClientSession;\n indexerId: string;\n}) {\n const { db, session, indexerId } = props;\n\n try {\n // Delete all checkpoints for this indexer\n await db\n .collection<CheckpointSchema>(checkpointCollectionName)\n .deleteMany({ id: indexerId }, { session });\n\n // Delete all filters for this indexer\n await db\n .collection<FilterSchema>(filterCollectionName)\n .deleteMany({ id: indexerId }, { session });\n } catch (error) {\n throw new MongoStorageError(\"Failed to reset persistence state\", {\n cause: error,\n });\n }\n}\n","import type { Cursor } from \"@apibara/protocol\";\nimport type {\n BulkWriteOptions,\n ClientSession,\n Collection,\n CollectionOptions,\n Db,\n DeleteOptions,\n Document,\n Filter,\n FindCursor,\n FindOneAndUpdateOptions,\n FindOptions,\n InsertManyResult,\n InsertOneOptions,\n InsertOneResult,\n MatchKeysAndValues,\n OptionalUnlessRequiredId,\n UpdateFilter,\n UpdateOptions,\n UpdateResult,\n WithId,\n} from \"mongodb\";\n\nexport class MongoStorage {\n constructor(\n private db: Db,\n private session: ClientSession,\n private endCursor?: Cursor,\n ) {}\n\n collection<TSchema extends Document = Document>(\n name: string,\n options?: CollectionOptions,\n ) {\n const collection = this.db.collection<TSchema>(name, options);\n\n return new MongoCollection<TSchema>(\n this.session,\n collection,\n this.endCursor,\n );\n }\n}\n\nexport type MongoCursor = {\n from: bigint | null;\n to: bigint | null;\n};\n\nexport type CursoredSchema<TSchema extends Document> = TSchema & {\n _cursor: MongoCursor;\n};\n\nexport class MongoCollection<TSchema extends Document> {\n constructor(\n private session: ClientSession,\n private collection: Collection<TSchema>,\n private endCursor?: Cursor,\n ) {}\n\n async insertOne(\n doc: OptionalUnlessRequiredId<TSchema>,\n options?: InsertOneOptions,\n ): Promise<InsertOneResult<TSchema>> {\n return await this.collection.insertOne(\n {\n ...doc,\n _cursor: {\n from: this.endCursor?.orderKey ?? null,\n to: null,\n } as MongoCursor,\n },\n { ...options, session: this.session },\n );\n }\n\n async insertMany(\n docs: ReadonlyArray<OptionalUnlessRequiredId<TSchema>>,\n options?: BulkWriteOptions,\n ): Promise<InsertManyResult<TSchema>> {\n return await this.collection.insertMany(\n docs.map((doc) => ({\n ...doc,\n _cursor: {\n from: this.endCursor?.orderKey ?? null,\n to: null,\n } as MongoCursor,\n })),\n { ...options, session: this.session },\n );\n }\n\n async updateOne(\n filter: Filter<TSchema>,\n update: UpdateFilter<TSchema>,\n options?: UpdateOptions,\n ): Promise<UpdateResult<TSchema>> {\n // 1. Find and update the document, getting the old version\n const oldDoc = await this.collection.findOneAndUpdate(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n ...update,\n $set: {\n ...update.$set,\n \"_cursor.from\": this.endCursor?.orderKey ?? null,\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n {\n ...options,\n session: this.session,\n returnDocument: \"before\",\n } as FindOneAndUpdateOptions,\n );\n\n // 2. If we found and updated a document, insert its old version\n if (oldDoc) {\n const { _id, ...doc } = oldDoc;\n await this.collection.insertOne(\n {\n ...doc,\n _cursor: {\n ...oldDoc._cursor,\n to: this.endCursor?.orderKey ?? null,\n },\n } as unknown as OptionalUnlessRequiredId<TSchema>,\n { session: this.session },\n );\n }\n\n // 3. Return an UpdateResult-compatible object\n return {\n acknowledged: true,\n modifiedCount: oldDoc ? 1 : 0,\n upsertedId: null,\n upsertedCount: 0,\n matchedCount: oldDoc ? 1 : 0,\n };\n }\n\n async updateMany(\n filter: Filter<TSchema>,\n update: UpdateFilter<TSchema>,\n options?: UpdateOptions,\n ): Promise<UpdateResult<TSchema>> {\n // 1. Find all documents matching the filter that are latest (to: null)\n const oldDocs = await this.collection\n .find(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { session: this.session },\n )\n .toArray();\n\n // 2. Update to the new values with updateMany\n // (setting _cursor.from to endCursor, leaving _cursor.to unchanged)\n const updateResult = await this.collection.updateMany(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n ...update,\n $set: {\n ...update.$set,\n \"_cursor.from\": this.endCursor?.orderKey ?? null,\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n\n // 3. Adjust the cursor.to of the old values\n const oldDocsWithUpdatedCursor = oldDocs.map(({ _id, ...doc }) => ({\n ...doc,\n _cursor: {\n ...doc._cursor,\n to: this.endCursor?.orderKey ?? null,\n },\n }));\n\n // 4. Insert the old values back into the db\n if (oldDocsWithUpdatedCursor.length > 0) {\n await this.collection.insertMany(\n oldDocsWithUpdatedCursor as unknown as OptionalUnlessRequiredId<TSchema>[],\n { session: this.session },\n );\n }\n\n return updateResult;\n }\n\n async deleteOne(\n filter: Filter<TSchema>,\n options?: DeleteOptions,\n ): Promise<UpdateResult<TSchema>> {\n return await this.collection.updateOne(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n {\n $set: {\n \"_cursor.to\": this.endCursor?.orderKey ?? null,\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n }\n\n async deleteMany(\n filter?: Filter<TSchema>,\n options?: DeleteOptions,\n ): Promise<UpdateResult<TSchema>> {\n return await this.collection.updateMany(\n {\n ...((filter ?? {}) as Filter<TSchema>),\n \"_cursor.to\": null,\n },\n {\n $set: {\n \"_cursor.to\": this.endCursor?.orderKey ?? null,\n } as unknown as MatchKeysAndValues<TSchema>,\n },\n { ...options, session: this.session },\n );\n }\n\n async findOne(\n filter: Filter<TSchema>,\n options?: Omit<FindOptions, \"timeoutMode\">,\n ): Promise<WithId<TSchema> | null> {\n return await this.collection.findOne(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { ...options, session: this.session },\n );\n }\n\n find(\n filter: Filter<TSchema>,\n options?: FindOptions,\n ): FindCursor<WithId<TSchema>> {\n return this.collection.find(\n {\n ...filter,\n \"_cursor.to\": null,\n },\n { ...options, session: this.session },\n );\n }\n}\n","import { useIndexerContext } from \"@apibara/indexer\";\nimport { defineIndexerPlugin, useLogger } from \"@apibara/indexer/plugins\";\nimport type { DbOptions, MongoClient } from \"mongodb\";\n\nimport { generateIndexerId } from \"@apibara/indexer/internal\";\nimport { useInternalContext } from \"@apibara/indexer/internal/plugins\";\nimport type { Cursor, DataFinality } from \"@apibara/protocol\";\nimport { cleanupStorage, finalize, invalidate } from \"./mongo\";\nimport {\n finalizeState,\n getState,\n initializePersistentState,\n invalidateState,\n persistState,\n resetPersistence,\n} from \"./persistence\";\nimport { MongoStorage } from \"./storage\";\nimport { MongoStorageError, withTransaction } from \"./utils\";\n\nexport { MongoCollection, MongoStorage } from \"./storage\";\n\nconst MONGO_PROPERTY = \"_mongo\";\n\nexport function useMongoStorage(): MongoStorage {\n const context = useIndexerContext();\n\n if (!context[MONGO_PROPERTY]) {\n throw new MongoStorageError(\n \"mongo storage is not available. Did you register the plugin?\",\n );\n }\n\n return context[MONGO_PROPERTY] as MongoStorage;\n}\n\nexport interface MongoStorageOptions {\n client: MongoClient;\n dbName: string;\n dbOptions?: DbOptions;\n collections: string[];\n persistState?: boolean;\n indexerName?: string;\n}\n/**\n * Creates a plugin that uses MongoDB as the storage layer.\n *\n * Supports storing the indexer's state and provides a simple Key-Value store.\n * @param options.client - The MongoDB client instance.\n * @param options.dbName - The name of the database.\n * @param options.dbOptions - The database options.\n * @param options.collections - The collections to use.\n * @param options.persistState - Whether to persist the indexer's state. Defaults to true.\n * @param options.indexerName - The name of the indexer. Defaults value is 'default'.\n */\nexport function mongoStorage<TFilter, TBlock>({\n client,\n dbName,\n dbOptions,\n collections,\n persistState: enablePersistence = true,\n indexerName: identifier = \"default\",\n}: MongoStorageOptions) {\n return defineIndexerPlugin<TFilter, TBlock>((indexer) => {\n let indexerId = \"\";\n const alwaysReindex = process.env[\"APIBARA_ALWAYS_REINDEX\"] === \"true\";\n let prevFinality: DataFinality | undefined;\n\n indexer.hooks.hook(\"plugins:init\", async () => {\n const { indexerName } = useInternalContext();\n indexerId = generateIndexerId(indexerName, identifier);\n const logger = useLogger();\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n if (enablePersistence) {\n await initializePersistentState(db, session);\n }\n\n if (alwaysReindex) {\n logger.warn(\n `Reindexing: Deleting all data from collections - ${collections.join(\", \")}`,\n );\n\n await cleanupStorage(db, session, collections);\n\n if (enablePersistence) {\n await resetPersistence({ db, session, indexerId });\n }\n\n logger.success(\"All data has been cleaned up for reindexing\");\n }\n });\n });\n\n indexer.hooks.hook(\"connect:before\", async ({ request }) => {\n if (!enablePersistence) {\n return;\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n const { cursor, filter } = await getState<TFilter>({\n db,\n session,\n indexerId,\n });\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(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await invalidate(db, session, cursor, collections);\n\n if (enablePersistence) {\n await invalidateState({ db, session, cursor, indexerId });\n }\n });\n });\n\n indexer.hooks.hook(\"connect:factory\", async ({ request, endCursor }) => {\n if (!enablePersistence) {\n return;\n }\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n if (endCursor && request.filter[1]) {\n await persistState({\n db,\n endCursor,\n session,\n filter: request.filter[1],\n indexerId,\n });\n }\n });\n });\n\n indexer.hooks.hook(\"message:finalize\", async ({ message }) => {\n const { cursor } = message;\n\n if (!cursor) {\n throw new MongoStorageError(\"finalized cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await finalize(db, session, cursor, collections);\n\n if (enablePersistence) {\n await finalizeState({ db, session, 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 MongoStorageError(\"invalidate cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n await invalidate(db, session, cursor, collections);\n\n if (enablePersistence) {\n await invalidateState({ db, session, cursor, indexerId });\n }\n });\n });\n\n indexer.hooks.hook(\"handler:middleware\", async ({ use }) => {\n use(async (context, next) => {\n const { endCursor, finality, cursor } = context as {\n cursor: Cursor;\n endCursor: Cursor;\n finality: DataFinality;\n };\n\n if (!endCursor) {\n throw new MongoStorageError(\"end cursor is undefined\");\n }\n\n await withTransaction(client, async (session) => {\n const db = client.db(dbName, dbOptions);\n context[MONGO_PROPERTY] = new MongoStorage(db, session, endCursor);\n\n if (prevFinality === \"pending\") {\n // invalidate if previous block's finality was \"pending\"\n await invalidate(db, session, cursor, collections);\n }\n\n await next();\n\n delete context[MONGO_PROPERTY];\n\n if (enablePersistence && finality !== \"pending\") {\n await persistState({\n db,\n endCursor,\n session,\n indexerId,\n });\n }\n\n prevFinality = finality;\n });\n });\n });\n });\n}\n"],"names":["session"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apibara/plugin-mongo",
|
|
3
|
-
"version": "2.1.0-beta.
|
|
3
|
+
"version": "2.1.0-beta.57",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"mongodb": "^6.12.0"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@apibara/indexer": "2.1.0-beta.
|
|
39
|
-
"@apibara/protocol": "2.1.0-beta.
|
|
38
|
+
"@apibara/indexer": "2.1.0-beta.58",
|
|
39
|
+
"@apibara/protocol": "2.1.0-beta.58"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/mongo.ts
CHANGED
|
@@ -7,13 +7,12 @@ export async function invalidate(
|
|
|
7
7
|
cursor: Cursor,
|
|
8
8
|
collections: string[],
|
|
9
9
|
) {
|
|
10
|
-
const orderKeyValue = Number(cursor.orderKey);
|
|
11
10
|
for (const collection of collections) {
|
|
12
11
|
// Delete documents where the lower bound of _cursor is greater than the invalidate cursor
|
|
13
12
|
await db.collection(collection).deleteMany(
|
|
14
13
|
{
|
|
15
14
|
"_cursor.from": {
|
|
16
|
-
$gt:
|
|
15
|
+
$gt: cursor.orderKey,
|
|
17
16
|
},
|
|
18
17
|
},
|
|
19
18
|
{ session },
|
|
@@ -21,7 +20,7 @@ export async function invalidate(
|
|
|
21
20
|
|
|
22
21
|
// Update documents where the upper bound of _cursor is greater than the invalidate cursor
|
|
23
22
|
await db.collection(collection).updateMany(
|
|
24
|
-
{ "_cursor.to": { $gt:
|
|
23
|
+
{ "_cursor.to": { $gt: cursor.orderKey } },
|
|
25
24
|
{
|
|
26
25
|
$set: {
|
|
27
26
|
"_cursor.to": null,
|
|
@@ -38,12 +37,11 @@ export async function finalize(
|
|
|
38
37
|
cursor: Cursor,
|
|
39
38
|
collections: string[],
|
|
40
39
|
) {
|
|
41
|
-
const orderKeyValue = Number(cursor.orderKey);
|
|
42
40
|
for (const collection of collections) {
|
|
43
41
|
// Delete documents where the upper bound of _cursor is less than the finalize cursor
|
|
44
42
|
await db.collection(collection).deleteMany(
|
|
45
43
|
{
|
|
46
|
-
"_cursor.to": { $lte:
|
|
44
|
+
"_cursor.to": { $lte: cursor.orderKey },
|
|
47
45
|
},
|
|
48
46
|
{ session },
|
|
49
47
|
);
|
package/src/persistence.ts
CHANGED
|
@@ -4,15 +4,15 @@ import { MongoStorageError } from "./utils";
|
|
|
4
4
|
|
|
5
5
|
export type CheckpointSchema = {
|
|
6
6
|
id: string;
|
|
7
|
-
orderKey:
|
|
7
|
+
orderKey: bigint;
|
|
8
8
|
uniqueKey: string | null;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export type FilterSchema = {
|
|
12
12
|
id: string;
|
|
13
13
|
filter: Record<string, unknown>;
|
|
14
|
-
fromBlock:
|
|
15
|
-
toBlock:
|
|
14
|
+
fromBlock: bigint;
|
|
15
|
+
toBlock: bigint | null;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export const checkpointCollectionName = "checkpoints";
|
|
@@ -43,7 +43,7 @@ export async function persistState<TFilter>(props: {
|
|
|
43
43
|
{ id: indexerId },
|
|
44
44
|
{
|
|
45
45
|
$set: {
|
|
46
|
-
orderKey:
|
|
46
|
+
orderKey: endCursor.orderKey,
|
|
47
47
|
uniqueKey: endCursor.uniqueKey ? endCursor.uniqueKey : null,
|
|
48
48
|
},
|
|
49
49
|
},
|
|
@@ -56,7 +56,7 @@ export async function persistState<TFilter>(props: {
|
|
|
56
56
|
.collection<FilterSchema>(filterCollectionName)
|
|
57
57
|
.updateMany(
|
|
58
58
|
{ id: indexerId, toBlock: null },
|
|
59
|
-
{ $set: { toBlock:
|
|
59
|
+
{ $set: { toBlock: endCursor.orderKey } },
|
|
60
60
|
{ session },
|
|
61
61
|
);
|
|
62
62
|
|
|
@@ -64,12 +64,12 @@ export async function persistState<TFilter>(props: {
|
|
|
64
64
|
await db.collection<FilterSchema>(filterCollectionName).updateOne(
|
|
65
65
|
{
|
|
66
66
|
id: indexerId,
|
|
67
|
-
fromBlock:
|
|
67
|
+
fromBlock: endCursor.orderKey,
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
$set: {
|
|
71
71
|
filter: filter as Record<string, unknown>,
|
|
72
|
-
fromBlock:
|
|
72
|
+
fromBlock: endCursor.orderKey,
|
|
73
73
|
toBlock: null,
|
|
74
74
|
},
|
|
75
75
|
},
|
|
@@ -128,14 +128,14 @@ export async function invalidateState(props: {
|
|
|
128
128
|
await db
|
|
129
129
|
.collection<FilterSchema>(filterCollectionName)
|
|
130
130
|
.deleteMany(
|
|
131
|
-
{ id: indexerId, fromBlock: { $gt:
|
|
131
|
+
{ id: indexerId, fromBlock: { $gt: cursor.orderKey } },
|
|
132
132
|
{ session },
|
|
133
133
|
);
|
|
134
134
|
|
|
135
135
|
await db
|
|
136
136
|
.collection<FilterSchema>(filterCollectionName)
|
|
137
137
|
.updateMany(
|
|
138
|
-
{ id: indexerId, toBlock: { $gt:
|
|
138
|
+
{ id: indexerId, toBlock: { $gt: cursor.orderKey } },
|
|
139
139
|
{ $set: { toBlock: null } },
|
|
140
140
|
{ session },
|
|
141
141
|
);
|
|
@@ -152,7 +152,7 @@ export async function finalizeState(props: {
|
|
|
152
152
|
await db.collection<FilterSchema>(filterCollectionName).deleteMany(
|
|
153
153
|
{
|
|
154
154
|
id: indexerId,
|
|
155
|
-
toBlock: { $lte:
|
|
155
|
+
toBlock: { $lte: cursor.orderKey },
|
|
156
156
|
},
|
|
157
157
|
{ session },
|
|
158
158
|
);
|
package/src/storage.ts
CHANGED
|
@@ -44,8 +44,8 @@ export class MongoStorage {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export type MongoCursor = {
|
|
47
|
-
from:
|
|
48
|
-
to:
|
|
47
|
+
from: bigint | null;
|
|
48
|
+
to: bigint | null;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
export type CursoredSchema<TSchema extends Document> = TSchema & {
|
|
@@ -67,7 +67,7 @@ export class MongoCollection<TSchema extends Document> {
|
|
|
67
67
|
{
|
|
68
68
|
...doc,
|
|
69
69
|
_cursor: {
|
|
70
|
-
from:
|
|
70
|
+
from: this.endCursor?.orderKey ?? null,
|
|
71
71
|
to: null,
|
|
72
72
|
} as MongoCursor,
|
|
73
73
|
},
|
|
@@ -83,7 +83,7 @@ export class MongoCollection<TSchema extends Document> {
|
|
|
83
83
|
docs.map((doc) => ({
|
|
84
84
|
...doc,
|
|
85
85
|
_cursor: {
|
|
86
|
-
from:
|
|
86
|
+
from: this.endCursor?.orderKey ?? null,
|
|
87
87
|
to: null,
|
|
88
88
|
} as MongoCursor,
|
|
89
89
|
})),
|
|
@@ -106,7 +106,7 @@ export class MongoCollection<TSchema extends Document> {
|
|
|
106
106
|
...update,
|
|
107
107
|
$set: {
|
|
108
108
|
...update.$set,
|
|
109
|
-
"_cursor.from":
|
|
109
|
+
"_cursor.from": this.endCursor?.orderKey ?? null,
|
|
110
110
|
} as unknown as MatchKeysAndValues<TSchema>,
|
|
111
111
|
},
|
|
112
112
|
{
|
|
@@ -124,7 +124,7 @@ export class MongoCollection<TSchema extends Document> {
|
|
|
124
124
|
...doc,
|
|
125
125
|
_cursor: {
|
|
126
126
|
...oldDoc._cursor,
|
|
127
|
-
to:
|
|
127
|
+
to: this.endCursor?.orderKey ?? null,
|
|
128
128
|
},
|
|
129
129
|
} as unknown as OptionalUnlessRequiredId<TSchema>,
|
|
130
130
|
{ session: this.session },
|
|
@@ -168,7 +168,7 @@ export class MongoCollection<TSchema extends Document> {
|
|
|
168
168
|
...update,
|
|
169
169
|
$set: {
|
|
170
170
|
...update.$set,
|
|
171
|
-
"_cursor.from":
|
|
171
|
+
"_cursor.from": this.endCursor?.orderKey ?? null,
|
|
172
172
|
} as unknown as MatchKeysAndValues<TSchema>,
|
|
173
173
|
},
|
|
174
174
|
{ ...options, session: this.session },
|
|
@@ -179,7 +179,7 @@ export class MongoCollection<TSchema extends Document> {
|
|
|
179
179
|
...doc,
|
|
180
180
|
_cursor: {
|
|
181
181
|
...doc._cursor,
|
|
182
|
-
to:
|
|
182
|
+
to: this.endCursor?.orderKey ?? null,
|
|
183
183
|
},
|
|
184
184
|
}));
|
|
185
185
|
|
|
@@ -205,7 +205,7 @@ export class MongoCollection<TSchema extends Document> {
|
|
|
205
205
|
},
|
|
206
206
|
{
|
|
207
207
|
$set: {
|
|
208
|
-
"_cursor.to":
|
|
208
|
+
"_cursor.to": this.endCursor?.orderKey ?? null,
|
|
209
209
|
} as unknown as MatchKeysAndValues<TSchema>,
|
|
210
210
|
},
|
|
211
211
|
{ ...options, session: this.session },
|
|
@@ -223,7 +223,7 @@ export class MongoCollection<TSchema extends Document> {
|
|
|
223
223
|
},
|
|
224
224
|
{
|
|
225
225
|
$set: {
|
|
226
|
-
"_cursor.to":
|
|
226
|
+
"_cursor.to": this.endCursor?.orderKey ?? null,
|
|
227
227
|
} as unknown as MatchKeysAndValues<TSchema>,
|
|
228
228
|
},
|
|
229
229
|
{ ...options, session: this.session },
|