@apibara/plugin-sqlite 2.1.0-beta.11 → 2.1.0-beta.12
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 +14 -6
- package/dist/index.mjs +14 -6
- package/package.json +3 -3
- package/src/index.ts +23 -6
- package/src/kv.ts +1 -1
- package/src/persistence.ts +13 -0
package/dist/index.cjs
CHANGED
|
@@ -267,6 +267,7 @@ function sqliteStorage({
|
|
|
267
267
|
}) {
|
|
268
268
|
return plugins.defineIndexerPlugin((indexer) => {
|
|
269
269
|
let indexerId = "";
|
|
270
|
+
let prevFinality;
|
|
270
271
|
indexer.hooks.hook("run:before", async () => {
|
|
271
272
|
const { indexerName: indexerFileName, availableIndexers } = plugins$1.useInternalContext();
|
|
272
273
|
indexerId = internal.generateIndexerId(indexerFileName, identifier);
|
|
@@ -368,31 +369,38 @@ function sqliteStorage({
|
|
|
368
369
|
});
|
|
369
370
|
indexer.hooks.hook("handler:middleware", ({ use }) => {
|
|
370
371
|
use(async (ctx, next) => {
|
|
371
|
-
|
|
372
|
+
const { endCursor, finality, cursor } = ctx;
|
|
373
|
+
if (!finality) {
|
|
372
374
|
throw new SqliteStorageError("finality is undefined");
|
|
373
375
|
}
|
|
374
|
-
if (!
|
|
376
|
+
if (!endCursor || !protocol.isCursor(endCursor)) {
|
|
375
377
|
throw new SqliteStorageError(
|
|
376
378
|
"endCursor is undefined or not a cursor"
|
|
377
379
|
);
|
|
378
380
|
}
|
|
379
381
|
await withTransaction(database, async (db) => {
|
|
382
|
+
if (prevFinality === "pending") {
|
|
383
|
+
if (enableKeyValueStore) {
|
|
384
|
+
invalidateKV(db, cursor);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
380
387
|
if (enableKeyValueStore) {
|
|
381
388
|
ctx[KV_PROPERTY] = new KeyValueStore(
|
|
382
389
|
db,
|
|
383
|
-
|
|
384
|
-
|
|
390
|
+
endCursor,
|
|
391
|
+
finality,
|
|
385
392
|
serializeFn,
|
|
386
393
|
deserializeFn
|
|
387
394
|
);
|
|
388
395
|
}
|
|
389
396
|
await next();
|
|
390
|
-
if (enablePersistState) {
|
|
391
|
-
persistState({ db, endCursor
|
|
397
|
+
if (enablePersistState && finality !== "pending") {
|
|
398
|
+
persistState({ db, endCursor, indexerId });
|
|
392
399
|
}
|
|
393
400
|
if (enableKeyValueStore) {
|
|
394
401
|
delete ctx[KV_PROPERTY];
|
|
395
402
|
}
|
|
403
|
+
prevFinality = finality;
|
|
396
404
|
});
|
|
397
405
|
});
|
|
398
406
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -265,6 +265,7 @@ function sqliteStorage({
|
|
|
265
265
|
}) {
|
|
266
266
|
return defineIndexerPlugin((indexer) => {
|
|
267
267
|
let indexerId = "";
|
|
268
|
+
let prevFinality;
|
|
268
269
|
indexer.hooks.hook("run:before", async () => {
|
|
269
270
|
const { indexerName: indexerFileName, availableIndexers } = useInternalContext();
|
|
270
271
|
indexerId = generateIndexerId(indexerFileName, identifier);
|
|
@@ -366,31 +367,38 @@ function sqliteStorage({
|
|
|
366
367
|
});
|
|
367
368
|
indexer.hooks.hook("handler:middleware", ({ use }) => {
|
|
368
369
|
use(async (ctx, next) => {
|
|
369
|
-
|
|
370
|
+
const { endCursor, finality, cursor } = ctx;
|
|
371
|
+
if (!finality) {
|
|
370
372
|
throw new SqliteStorageError("finality is undefined");
|
|
371
373
|
}
|
|
372
|
-
if (!
|
|
374
|
+
if (!endCursor || !isCursor(endCursor)) {
|
|
373
375
|
throw new SqliteStorageError(
|
|
374
376
|
"endCursor is undefined or not a cursor"
|
|
375
377
|
);
|
|
376
378
|
}
|
|
377
379
|
await withTransaction(database, async (db) => {
|
|
380
|
+
if (prevFinality === "pending") {
|
|
381
|
+
if (enableKeyValueStore) {
|
|
382
|
+
invalidateKV(db, cursor);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
378
385
|
if (enableKeyValueStore) {
|
|
379
386
|
ctx[KV_PROPERTY] = new KeyValueStore(
|
|
380
387
|
db,
|
|
381
|
-
|
|
382
|
-
|
|
388
|
+
endCursor,
|
|
389
|
+
finality,
|
|
383
390
|
serializeFn,
|
|
384
391
|
deserializeFn
|
|
385
392
|
);
|
|
386
393
|
}
|
|
387
394
|
await next();
|
|
388
|
-
if (enablePersistState) {
|
|
389
|
-
persistState({ db, endCursor
|
|
395
|
+
if (enablePersistState && finality !== "pending") {
|
|
396
|
+
persistState({ db, endCursor, indexerId });
|
|
390
397
|
}
|
|
391
398
|
if (enableKeyValueStore) {
|
|
392
399
|
delete ctx[KV_PROPERTY];
|
|
393
400
|
}
|
|
401
|
+
prevFinality = finality;
|
|
394
402
|
});
|
|
395
403
|
});
|
|
396
404
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apibara/plugin-sqlite",
|
|
3
|
-
"version": "2.1.0-beta.
|
|
3
|
+
"version": "2.1.0-beta.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"better-sqlite3": "^9.0.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@apibara/indexer": "2.1.0-beta.
|
|
40
|
-
"@apibara/protocol": "2.1.0-beta.
|
|
39
|
+
"@apibara/indexer": "2.1.0-beta.12",
|
|
40
|
+
"@apibara/protocol": "2.1.0-beta.12"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useIndexerContext } from "@apibara/indexer";
|
|
2
2
|
import { defineIndexerPlugin } from "@apibara/indexer/plugins";
|
|
3
3
|
import { isCursor } from "@apibara/protocol";
|
|
4
|
+
import type { Cursor, DataFinality } from "@apibara/protocol";
|
|
4
5
|
import type { Database as SqliteDatabase } from "better-sqlite3";
|
|
5
6
|
|
|
6
7
|
import { generateIndexerId } from "@apibara/indexer/internal";
|
|
@@ -76,6 +77,7 @@ export function sqliteStorage<TFilter, TBlock>({
|
|
|
76
77
|
}: SqliteStorageOptions) {
|
|
77
78
|
return defineIndexerPlugin<TFilter, TBlock>((indexer) => {
|
|
78
79
|
let indexerId = "";
|
|
80
|
+
let prevFinality: DataFinality | undefined;
|
|
79
81
|
|
|
80
82
|
indexer.hooks.hook("run:before", async () => {
|
|
81
83
|
const { indexerName: indexerFileName, availableIndexers } =
|
|
@@ -206,22 +208,35 @@ export function sqliteStorage<TFilter, TBlock>({
|
|
|
206
208
|
|
|
207
209
|
indexer.hooks.hook("handler:middleware", ({ use }) => {
|
|
208
210
|
use(async (ctx, next) => {
|
|
209
|
-
|
|
211
|
+
const { endCursor, finality, cursor } = ctx as {
|
|
212
|
+
cursor: Cursor;
|
|
213
|
+
endCursor: Cursor;
|
|
214
|
+
finality: DataFinality;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
if (!finality) {
|
|
210
218
|
throw new SqliteStorageError("finality is undefined");
|
|
211
219
|
}
|
|
212
220
|
|
|
213
|
-
if (!
|
|
221
|
+
if (!endCursor || !isCursor(endCursor)) {
|
|
214
222
|
throw new SqliteStorageError(
|
|
215
223
|
"endCursor is undefined or not a cursor",
|
|
216
224
|
);
|
|
217
225
|
}
|
|
218
226
|
|
|
219
227
|
await withTransaction(database, async (db) => {
|
|
228
|
+
if (prevFinality === "pending") {
|
|
229
|
+
// invalidate if previous block's finality was "pending"
|
|
230
|
+
if (enableKeyValueStore) {
|
|
231
|
+
invalidateKV(db, cursor);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
220
235
|
if (enableKeyValueStore) {
|
|
221
236
|
ctx[KV_PROPERTY] = new KeyValueStore(
|
|
222
237
|
db,
|
|
223
|
-
|
|
224
|
-
|
|
238
|
+
endCursor,
|
|
239
|
+
finality,
|
|
225
240
|
serializeFn,
|
|
226
241
|
deserializeFn,
|
|
227
242
|
);
|
|
@@ -229,13 +244,15 @@ export function sqliteStorage<TFilter, TBlock>({
|
|
|
229
244
|
|
|
230
245
|
await next();
|
|
231
246
|
|
|
232
|
-
if (enablePersistState) {
|
|
233
|
-
persistState({ db, endCursor
|
|
247
|
+
if (enablePersistState && finality !== "pending") {
|
|
248
|
+
persistState({ db, endCursor, indexerId });
|
|
234
249
|
}
|
|
235
250
|
|
|
236
251
|
if (enableKeyValueStore) {
|
|
237
252
|
delete ctx[KV_PROPERTY];
|
|
238
253
|
}
|
|
254
|
+
|
|
255
|
+
prevFinality = finality;
|
|
239
256
|
});
|
|
240
257
|
});
|
|
241
258
|
});
|
package/src/kv.ts
CHANGED
package/src/persistence.ts
CHANGED
|
@@ -100,6 +100,19 @@ export function invalidateState(props: {
|
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
export type CheckpointRow = {
|
|
104
|
+
id: string;
|
|
105
|
+
order_key: number;
|
|
106
|
+
unique_key: string | null;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export type FilterRow = {
|
|
110
|
+
id: string;
|
|
111
|
+
filter: string;
|
|
112
|
+
from_block: number;
|
|
113
|
+
to_block: number | null;
|
|
114
|
+
};
|
|
115
|
+
|
|
103
116
|
const statements = {
|
|
104
117
|
createCheckpointsTable: `
|
|
105
118
|
CREATE TABLE IF NOT EXISTS checkpoints (
|