@apibara/plugin-sqlite 2.1.0-beta.2 → 2.1.0-beta.20
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 +15 -7
- package/dist/index.mjs +15 -7
- package/package.json +4 -3
- package/src/index.ts +23 -7
- package/src/kv.ts +1 -1
- package/src/persistence.ts +13 -0
package/dist/index.cjs
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const indexer = require('@apibara/indexer');
|
|
4
4
|
const plugins = require('@apibara/indexer/plugins');
|
|
5
|
-
const protocol = require('@apibara/protocol');
|
|
6
5
|
const internal = require('@apibara/indexer/internal');
|
|
7
6
|
const plugins$1 = require('@apibara/indexer/internal/plugins');
|
|
7
|
+
const protocol = require('@apibara/protocol');
|
|
8
8
|
|
|
9
9
|
class SqliteStorageError extends Error {
|
|
10
10
|
constructor(message, options) {
|
|
@@ -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) {
|
|
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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useIndexerContext } from '@apibara/indexer';
|
|
2
2
|
import { defineIndexerPlugin } from '@apibara/indexer/plugins';
|
|
3
|
-
import { normalizeCursor, isCursor } from '@apibara/protocol';
|
|
4
3
|
import { generateIndexerId } from '@apibara/indexer/internal';
|
|
5
4
|
import { useInternalContext } from '@apibara/indexer/internal/plugins';
|
|
5
|
+
import { normalizeCursor } from '@apibara/protocol';
|
|
6
6
|
|
|
7
7
|
class SqliteStorageError extends Error {
|
|
8
8
|
constructor(message, options) {
|
|
@@ -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) {
|
|
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.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/better-sqlite3": "^7.6.11",
|
|
30
30
|
"@types/node": "^20.14.0",
|
|
31
|
+
"better-sqlite3": "^9.0.0",
|
|
31
32
|
"unbuild": "^2.0.0",
|
|
32
33
|
"vitest": "^1.6.0"
|
|
33
34
|
},
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
"better-sqlite3": "^9.0.0"
|
|
36
37
|
},
|
|
37
38
|
"dependencies": {
|
|
38
|
-
"@apibara/indexer": "2.1.0-beta.
|
|
39
|
-
"@apibara/protocol": "2.1.0-beta.
|
|
39
|
+
"@apibara/indexer": "2.1.0-beta.20",
|
|
40
|
+
"@apibara/protocol": "2.1.0-beta.20"
|
|
40
41
|
}
|
|
41
42
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useIndexerContext } from "@apibara/indexer";
|
|
2
2
|
import { defineIndexerPlugin } from "@apibara/indexer/plugins";
|
|
3
|
-
import {
|
|
3
|
+
import type { Cursor, DataFinality } from "@apibara/protocol";
|
|
4
4
|
import type { Database as SqliteDatabase } from "better-sqlite3";
|
|
5
5
|
|
|
6
6
|
import { generateIndexerId } from "@apibara/indexer/internal";
|
|
@@ -76,6 +76,7 @@ export function sqliteStorage<TFilter, TBlock>({
|
|
|
76
76
|
}: SqliteStorageOptions) {
|
|
77
77
|
return defineIndexerPlugin<TFilter, TBlock>((indexer) => {
|
|
78
78
|
let indexerId = "";
|
|
79
|
+
let prevFinality: DataFinality | undefined;
|
|
79
80
|
|
|
80
81
|
indexer.hooks.hook("run:before", async () => {
|
|
81
82
|
const { indexerName: indexerFileName, availableIndexers } =
|
|
@@ -206,22 +207,35 @@ export function sqliteStorage<TFilter, TBlock>({
|
|
|
206
207
|
|
|
207
208
|
indexer.hooks.hook("handler:middleware", ({ use }) => {
|
|
208
209
|
use(async (ctx, next) => {
|
|
209
|
-
|
|
210
|
+
const { endCursor, finality, cursor } = ctx as {
|
|
211
|
+
cursor: Cursor;
|
|
212
|
+
endCursor: Cursor;
|
|
213
|
+
finality: DataFinality;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
if (!finality) {
|
|
210
217
|
throw new SqliteStorageError("finality is undefined");
|
|
211
218
|
}
|
|
212
219
|
|
|
213
|
-
if (!
|
|
220
|
+
if (!endCursor) {
|
|
214
221
|
throw new SqliteStorageError(
|
|
215
222
|
"endCursor is undefined or not a cursor",
|
|
216
223
|
);
|
|
217
224
|
}
|
|
218
225
|
|
|
219
226
|
await withTransaction(database, async (db) => {
|
|
227
|
+
if (prevFinality === "pending") {
|
|
228
|
+
// invalidate if previous block's finality was "pending"
|
|
229
|
+
if (enableKeyValueStore) {
|
|
230
|
+
invalidateKV(db, cursor);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
220
234
|
if (enableKeyValueStore) {
|
|
221
235
|
ctx[KV_PROPERTY] = new KeyValueStore(
|
|
222
236
|
db,
|
|
223
|
-
|
|
224
|
-
|
|
237
|
+
endCursor,
|
|
238
|
+
finality,
|
|
225
239
|
serializeFn,
|
|
226
240
|
deserializeFn,
|
|
227
241
|
);
|
|
@@ -229,13 +243,15 @@ export function sqliteStorage<TFilter, TBlock>({
|
|
|
229
243
|
|
|
230
244
|
await next();
|
|
231
245
|
|
|
232
|
-
if (enablePersistState) {
|
|
233
|
-
persistState({ db, endCursor
|
|
246
|
+
if (enablePersistState && finality !== "pending") {
|
|
247
|
+
persistState({ db, endCursor, indexerId });
|
|
234
248
|
}
|
|
235
249
|
|
|
236
250
|
if (enableKeyValueStore) {
|
|
237
251
|
delete ctx[KV_PROPERTY];
|
|
238
252
|
}
|
|
253
|
+
|
|
254
|
+
prevFinality = finality;
|
|
239
255
|
});
|
|
240
256
|
});
|
|
241
257
|
});
|
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 (
|