@apibara/indexer 2.0.0-beta.9 → 2.1.0-beta.2
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 +271 -39
- package/dist/index.d.cts +1 -16
- package/dist/index.d.mts +1 -16
- package/dist/index.d.ts +1 -16
- package/dist/index.mjs +262 -25
- package/dist/internal/index.cjs +10 -0
- package/dist/internal/index.d.cts +3 -0
- package/dist/internal/index.d.mts +3 -0
- package/dist/internal/index.d.ts +3 -0
- package/dist/internal/index.mjs +8 -0
- package/dist/internal/plugins.cjs +38 -0
- package/dist/internal/plugins.d.cts +13 -0
- package/dist/internal/plugins.d.mts +13 -0
- package/dist/internal/plugins.d.ts +13 -0
- package/dist/internal/plugins.mjs +34 -0
- package/dist/internal/testing.cjs +118 -0
- package/dist/internal/testing.d.cts +42 -0
- package/dist/internal/testing.d.mts +42 -0
- package/dist/internal/testing.d.ts +42 -0
- package/dist/internal/testing.mjs +113 -0
- package/dist/plugins/index.cjs +39 -3
- package/dist/plugins/index.d.cts +16 -2
- package/dist/plugins/index.d.mts +16 -2
- package/dist/plugins/index.d.ts +16 -2
- package/dist/plugins/index.mjs +36 -3
- package/dist/shared/indexer.077335f3.cjs +15 -0
- package/dist/shared/indexer.2416906c.cjs +29 -0
- package/dist/shared/indexer.601ceab0.cjs +7 -0
- package/dist/shared/indexer.9b21ddd2.mjs +5 -0
- package/dist/shared/indexer.a55ad619.mjs +12 -0
- package/dist/shared/indexer.fedcd831.d.cts +100 -0
- package/dist/shared/indexer.fedcd831.d.mts +100 -0
- package/dist/shared/indexer.fedcd831.d.ts +100 -0
- package/dist/shared/indexer.ff25c953.mjs +26 -0
- package/dist/testing/index.cjs +52 -50
- package/dist/testing/index.d.cts +8 -36
- package/dist/testing/index.d.mts +8 -36
- package/dist/testing/index.d.ts +8 -36
- package/dist/testing/index.mjs +47 -47
- package/dist/vcr/index.cjs +84 -17
- package/dist/vcr/index.d.cts +16 -7
- package/dist/vcr/index.d.mts +16 -7
- package/dist/vcr/index.d.ts +16 -7
- package/dist/vcr/index.mjs +75 -11
- package/package.json +22 -42
- package/src/compose.test.ts +76 -0
- package/src/compose.ts +71 -0
- package/src/context.ts +14 -8
- package/src/index.ts +0 -5
- package/src/indexer.test.ts +125 -186
- package/src/indexer.ts +278 -151
- package/src/internal/index.ts +6 -0
- package/src/internal/plugins.ts +1 -0
- package/src/internal/testing.ts +148 -0
- package/src/plugins/config.ts +4 -4
- package/src/plugins/context.ts +40 -0
- package/src/plugins/index.ts +8 -1
- package/src/plugins/logger.ts +30 -0
- package/src/plugins/persistence.ts +24 -187
- package/src/testing/index.ts +58 -3
- package/src/vcr/record.ts +5 -3
- package/src/vcr/replay.ts +8 -18
- package/dist/plugins/kv.cjs +0 -131
- package/dist/plugins/kv.d.cts +0 -32
- package/dist/plugins/kv.d.mts +0 -32
- package/dist/plugins/kv.d.ts +0 -32
- package/dist/plugins/kv.mjs +0 -124
- package/dist/plugins/persistence.cjs +0 -182
- package/dist/plugins/persistence.d.cts +0 -50
- package/dist/plugins/persistence.d.mts +0 -50
- package/dist/plugins/persistence.d.ts +0 -50
- package/dist/plugins/persistence.mjs +0 -179
- package/dist/shared/indexer.2c23c9cd.mjs +0 -35
- package/dist/shared/indexer.318d3617.cjs +0 -47
- package/dist/shared/indexer.36530330.mjs +0 -249
- package/dist/shared/indexer.500fd281.d.cts +0 -23
- package/dist/shared/indexer.541d43eb.cjs +0 -266
- package/dist/shared/indexer.93d6b2eb.mjs +0 -17
- package/dist/shared/indexer.a8b7ab1f.cjs +0 -25
- package/dist/shared/indexer.b9c8f0d8.d.cts +0 -19
- package/dist/shared/indexer.b9c8f0d8.d.mts +0 -19
- package/dist/shared/indexer.b9c8f0d8.d.ts +0 -19
- package/dist/shared/indexer.c7ed6b83.d.cts +0 -82
- package/dist/shared/indexer.e1856641.d.mts +0 -23
- package/dist/shared/indexer.e4f2430f.d.ts +0 -23
- package/dist/shared/indexer.e8bd138d.d.mts +0 -82
- package/dist/shared/indexer.f761abcd.d.ts +0 -82
- package/dist/sinks/csv.cjs +0 -85
- package/dist/sinks/csv.d.cts +0 -66
- package/dist/sinks/csv.d.mts +0 -66
- package/dist/sinks/csv.d.ts +0 -66
- package/dist/sinks/csv.mjs +0 -78
- package/dist/sinks/drizzle/index.cjs +0 -212
- package/dist/sinks/drizzle/index.d.cts +0 -153
- package/dist/sinks/drizzle/index.d.mts +0 -153
- package/dist/sinks/drizzle/index.d.ts +0 -153
- package/dist/sinks/drizzle/index.mjs +0 -198
- package/dist/sinks/sqlite.cjs +0 -90
- package/dist/sinks/sqlite.d.cts +0 -71
- package/dist/sinks/sqlite.d.mts +0 -71
- package/dist/sinks/sqlite.d.ts +0 -71
- package/dist/sinks/sqlite.mjs +0 -87
- package/src/hooks/index.ts +0 -2
- package/src/hooks/useKVStore.ts +0 -12
- package/src/hooks/useSink.ts +0 -13
- package/src/plugins/kv.test.ts +0 -120
- package/src/plugins/kv.ts +0 -132
- package/src/plugins/persistence.test.ts +0 -151
- package/src/sink.ts +0 -36
- package/src/sinks/csv.test.ts +0 -65
- package/src/sinks/csv.ts +0 -159
- package/src/sinks/drizzle/Int8Range.ts +0 -52
- package/src/sinks/drizzle/delete.ts +0 -42
- package/src/sinks/drizzle/drizzle.test.ts +0 -239
- package/src/sinks/drizzle/drizzle.ts +0 -115
- package/src/sinks/drizzle/index.ts +0 -6
- package/src/sinks/drizzle/insert.ts +0 -42
- package/src/sinks/drizzle/select.ts +0 -44
- package/src/sinks/drizzle/transaction.ts +0 -49
- package/src/sinks/drizzle/update.ts +0 -47
- package/src/sinks/drizzle/utils.ts +0 -99
- package/src/sinks/sqlite.test.ts +0 -99
- package/src/sinks/sqlite.ts +0 -170
- package/src/testing/helper.ts +0 -13
- package/src/testing/indexer.ts +0 -35
- package/src/testing/setup.ts +0 -59
- package/src/testing/vcr.ts +0 -54
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { d as deserialize, s as serialize } from '../shared/indexer.2c23c9cd.mjs';
|
|
2
|
-
import 'node:fs/promises';
|
|
3
|
-
import 'node:path';
|
|
4
|
-
import 'klona/full';
|
|
5
|
-
import 'consola';
|
|
6
|
-
import 'hookable';
|
|
7
|
-
import 'node:assert';
|
|
8
|
-
import 'node:fs';
|
|
9
|
-
import '@apibara/protocol/testing';
|
|
10
|
-
import { defineIndexerPlugin } from './index.mjs';
|
|
11
|
-
import 'node:async_hooks';
|
|
12
|
-
import 'unctx';
|
|
13
|
-
import '@opentelemetry/api';
|
|
14
|
-
|
|
15
|
-
var __defProp = Object.defineProperty;
|
|
16
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
17
|
-
var __publicField = (obj, key, value) => {
|
|
18
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
19
|
-
return value;
|
|
20
|
-
};
|
|
21
|
-
function sqlitePersistence({
|
|
22
|
-
database
|
|
23
|
-
}) {
|
|
24
|
-
return defineIndexerPlugin((indexer) => {
|
|
25
|
-
let store;
|
|
26
|
-
indexer.hooks.hook("run:before", () => {
|
|
27
|
-
SqlitePersistence.initialize(database);
|
|
28
|
-
store = new SqlitePersistence(database);
|
|
29
|
-
});
|
|
30
|
-
indexer.hooks.hook("connect:before", ({ request }) => {
|
|
31
|
-
const { cursor, filter } = store.get();
|
|
32
|
-
if (cursor) {
|
|
33
|
-
request.startingCursor = cursor;
|
|
34
|
-
}
|
|
35
|
-
if (filter) {
|
|
36
|
-
request.filter[1] = filter;
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
indexer.hooks.hook("transaction:commit", ({ endCursor }) => {
|
|
40
|
-
if (endCursor) {
|
|
41
|
-
store.put({ cursor: endCursor });
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
indexer.hooks.hook("connect:factory", ({ request, endCursor }) => {
|
|
45
|
-
if (request.filter[1]) {
|
|
46
|
-
store.put({ cursor: endCursor, filter: request.filter[1] });
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
class SqlitePersistence {
|
|
52
|
-
constructor(_db) {
|
|
53
|
-
this._db = _db;
|
|
54
|
-
/** Sqlite Queries Prepare Statements */
|
|
55
|
-
__publicField(this, "_getCheckpointQuery");
|
|
56
|
-
__publicField(this, "_putCheckpointQuery");
|
|
57
|
-
__publicField(this, "_delCheckpointQuery");
|
|
58
|
-
__publicField(this, "_getFilterQuery");
|
|
59
|
-
__publicField(this, "_updateFilterToBlockQuery");
|
|
60
|
-
__publicField(this, "_insertFilterQuery");
|
|
61
|
-
__publicField(this, "_delFilterQuery");
|
|
62
|
-
this._getCheckpointQuery = this._db.prepare(statements.getCheckpoint);
|
|
63
|
-
this._putCheckpointQuery = this._db.prepare(statements.putCheckpoint);
|
|
64
|
-
this._delCheckpointQuery = this._db.prepare(statements.delCheckpoint);
|
|
65
|
-
this._getFilterQuery = this._db.prepare(statements.getFilter);
|
|
66
|
-
this._updateFilterToBlockQuery = this._db.prepare(
|
|
67
|
-
statements.updateFilterToBlock
|
|
68
|
-
);
|
|
69
|
-
this._insertFilterQuery = this._db.prepare(statements.insertFilter);
|
|
70
|
-
this._delFilterQuery = this._db.prepare(statements.delFilter);
|
|
71
|
-
}
|
|
72
|
-
static initialize(db) {
|
|
73
|
-
db.prepare(statements.createCheckpointsTable).run();
|
|
74
|
-
db.prepare(statements.createFiltersTable).run();
|
|
75
|
-
}
|
|
76
|
-
get() {
|
|
77
|
-
const cursor = this._getCheckpoint();
|
|
78
|
-
const filter = this._getFilter();
|
|
79
|
-
return { cursor, filter };
|
|
80
|
-
}
|
|
81
|
-
put({ cursor, filter }) {
|
|
82
|
-
if (cursor) {
|
|
83
|
-
this._putCheckpoint(cursor);
|
|
84
|
-
if (filter) {
|
|
85
|
-
this._putFilter(filter, cursor);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
del() {
|
|
90
|
-
this._delCheckpoint();
|
|
91
|
-
this._delFilter();
|
|
92
|
-
}
|
|
93
|
-
// --- CHECKPOINTS TABLE METHODS ---
|
|
94
|
-
_getCheckpoint() {
|
|
95
|
-
const row = this._getCheckpointQuery.get("default");
|
|
96
|
-
if (!row)
|
|
97
|
-
return void 0;
|
|
98
|
-
return { orderKey: BigInt(row.order_key), uniqueKey: row.unique_key };
|
|
99
|
-
}
|
|
100
|
-
_putCheckpoint(cursor) {
|
|
101
|
-
this._putCheckpointQuery.run(
|
|
102
|
-
"default",
|
|
103
|
-
Number(cursor.orderKey),
|
|
104
|
-
cursor.uniqueKey
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
_delCheckpoint() {
|
|
108
|
-
this._delCheckpointQuery.run("default");
|
|
109
|
-
}
|
|
110
|
-
// --- FILTERS TABLE METHODS ---
|
|
111
|
-
_getFilter() {
|
|
112
|
-
const row = this._getFilterQuery.get("default");
|
|
113
|
-
if (!row)
|
|
114
|
-
return void 0;
|
|
115
|
-
return deserialize(row.filter);
|
|
116
|
-
}
|
|
117
|
-
_putFilter(filter, endCursor) {
|
|
118
|
-
this._updateFilterToBlockQuery.run(Number(endCursor.orderKey), "default");
|
|
119
|
-
this._insertFilterQuery.run(
|
|
120
|
-
"default",
|
|
121
|
-
serialize(filter),
|
|
122
|
-
Number(endCursor.orderKey)
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
_delFilter() {
|
|
126
|
-
this._delFilterQuery.run("default");
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
const statements = {
|
|
130
|
-
beginTxn: "BEGIN TRANSACTION",
|
|
131
|
-
commitTxn: "COMMIT TRANSACTION",
|
|
132
|
-
rollbackTxn: "ROLLBACK TRANSACTION",
|
|
133
|
-
createCheckpointsTable: `
|
|
134
|
-
CREATE TABLE IF NOT EXISTS checkpoints (
|
|
135
|
-
id TEXT NOT NULL PRIMARY KEY,
|
|
136
|
-
order_key INTEGER NOT NULL,
|
|
137
|
-
unique_key TEXT
|
|
138
|
-
);`,
|
|
139
|
-
createFiltersTable: `
|
|
140
|
-
CREATE TABLE IF NOT EXISTS filters (
|
|
141
|
-
id TEXT NOT NULL,
|
|
142
|
-
filter BLOB NOT NULL,
|
|
143
|
-
from_block INTEGER NOT NULL,
|
|
144
|
-
to_block INTEGER,
|
|
145
|
-
PRIMARY KEY (id, from_block)
|
|
146
|
-
);`,
|
|
147
|
-
getCheckpoint: `
|
|
148
|
-
SELECT *
|
|
149
|
-
FROM checkpoints
|
|
150
|
-
WHERE id = ?`,
|
|
151
|
-
putCheckpoint: `
|
|
152
|
-
INSERT INTO checkpoints (id, order_key, unique_key)
|
|
153
|
-
VALUES (?, ?, ?)
|
|
154
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
155
|
-
order_key = excluded.order_key,
|
|
156
|
-
unique_key = excluded.unique_key`,
|
|
157
|
-
delCheckpoint: `
|
|
158
|
-
DELETE FROM checkpoints
|
|
159
|
-
WHERE id = ?`,
|
|
160
|
-
getFilter: `
|
|
161
|
-
SELECT *
|
|
162
|
-
FROM filters
|
|
163
|
-
WHERE id = ? AND to_block IS NULL`,
|
|
164
|
-
updateFilterToBlock: `
|
|
165
|
-
UPDATE filters
|
|
166
|
-
SET to_block = ?
|
|
167
|
-
WHERE id = ? AND to_block IS NULL`,
|
|
168
|
-
insertFilter: `
|
|
169
|
-
INSERT INTO filters (id, filter, from_block)
|
|
170
|
-
VALUES (?, ?, ?)
|
|
171
|
-
ON CONFLICT(id, from_block) DO UPDATE SET
|
|
172
|
-
filter = excluded.filter,
|
|
173
|
-
from_block = excluded.from_block`,
|
|
174
|
-
delFilter: `
|
|
175
|
-
DELETE FROM filters
|
|
176
|
-
WHERE id = ?`
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
export { SqlitePersistence, sqlitePersistence };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { getContext } from 'unctx';
|
|
3
|
-
import { trace } from '@opentelemetry/api';
|
|
4
|
-
import fs from 'node:fs';
|
|
5
|
-
import path from 'node:path';
|
|
6
|
-
|
|
7
|
-
const indexerAsyncContext = getContext("indexer", {
|
|
8
|
-
asyncContext: true,
|
|
9
|
-
AsyncLocalStorage
|
|
10
|
-
});
|
|
11
|
-
function useIndexerContext() {
|
|
12
|
-
return indexerAsyncContext.use();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const tracer = trace.getTracer("@apibara/indexer");
|
|
16
|
-
|
|
17
|
-
function deserialize(str) {
|
|
18
|
-
return JSON.parse(
|
|
19
|
-
str,
|
|
20
|
-
(_, value) => typeof value === "string" && value.match(/^\d+n$/) ? BigInt(value.slice(0, -1)) : value
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
function serialize(obj) {
|
|
24
|
-
return JSON.stringify(
|
|
25
|
-
obj,
|
|
26
|
-
(_, value) => typeof value === "bigint" ? `${value.toString()}n` : value,
|
|
27
|
-
" "
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
function isCassetteAvailable(vcrConfig, cassetteName) {
|
|
31
|
-
const filePath = path.join(vcrConfig.cassetteDir, `${cassetteName}.json`);
|
|
32
|
-
return fs.existsSync(filePath);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { indexerAsyncContext as a, deserialize as d, isCassetteAvailable as i, serialize as s, tracer as t, useIndexerContext as u };
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const node_async_hooks = require('node:async_hooks');
|
|
4
|
-
const unctx = require('unctx');
|
|
5
|
-
const api = require('@opentelemetry/api');
|
|
6
|
-
const fs = require('node:fs');
|
|
7
|
-
const path = require('node:path');
|
|
8
|
-
|
|
9
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
10
|
-
|
|
11
|
-
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
12
|
-
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
13
|
-
|
|
14
|
-
const indexerAsyncContext = unctx.getContext("indexer", {
|
|
15
|
-
asyncContext: true,
|
|
16
|
-
AsyncLocalStorage: node_async_hooks.AsyncLocalStorage
|
|
17
|
-
});
|
|
18
|
-
function useIndexerContext() {
|
|
19
|
-
return indexerAsyncContext.use();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const tracer = api.trace.getTracer("@apibara/indexer");
|
|
23
|
-
|
|
24
|
-
function deserialize(str) {
|
|
25
|
-
return JSON.parse(
|
|
26
|
-
str,
|
|
27
|
-
(_, value) => typeof value === "string" && value.match(/^\d+n$/) ? BigInt(value.slice(0, -1)) : value
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
function serialize(obj) {
|
|
31
|
-
return JSON.stringify(
|
|
32
|
-
obj,
|
|
33
|
-
(_, value) => typeof value === "bigint" ? `${value.toString()}n` : value,
|
|
34
|
-
" "
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
function isCassetteAvailable(vcrConfig, cassetteName) {
|
|
38
|
-
const filePath = path__default.join(vcrConfig.cassetteDir, `${cassetteName}.json`);
|
|
39
|
-
return fs__default.existsSync(filePath);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
exports.deserialize = deserialize;
|
|
43
|
-
exports.indexerAsyncContext = indexerAsyncContext;
|
|
44
|
-
exports.isCassetteAvailable = isCassetteAvailable;
|
|
45
|
-
exports.serialize = serialize;
|
|
46
|
-
exports.tracer = tracer;
|
|
47
|
-
exports.useIndexerContext = useIndexerContext;
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import { a as indexerAsyncContext, u as useIndexerContext, t as tracer, s as serialize, d as deserialize } from './indexer.2c23c9cd.mjs';
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { klona } from 'klona/full';
|
|
5
|
-
import consola from 'consola';
|
|
6
|
-
import { createHooks, createDebugger } from 'hookable';
|
|
7
|
-
import assert from 'node:assert';
|
|
8
|
-
import { d as defaultSink, S as Sink } from './indexer.93d6b2eb.mjs';
|
|
9
|
-
import fs$1 from 'node:fs';
|
|
10
|
-
import { MockClient } from '@apibara/protocol/testing';
|
|
11
|
-
|
|
12
|
-
function defineIndexer(streamConfig) {
|
|
13
|
-
return (config) => ({
|
|
14
|
-
streamConfig,
|
|
15
|
-
...config
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
function createIndexer({
|
|
19
|
-
streamConfig,
|
|
20
|
-
...options
|
|
21
|
-
}) {
|
|
22
|
-
const indexer = {
|
|
23
|
-
options,
|
|
24
|
-
streamConfig,
|
|
25
|
-
hooks: createHooks()
|
|
26
|
-
};
|
|
27
|
-
if (indexer.options.debug) {
|
|
28
|
-
createDebugger(indexer.hooks, { tag: "indexer" });
|
|
29
|
-
}
|
|
30
|
-
indexer.hooks.addHooks(indexer.options.hooks ?? {});
|
|
31
|
-
for (const plugin of indexer.options.plugins ?? []) {
|
|
32
|
-
plugin(indexer);
|
|
33
|
-
}
|
|
34
|
-
return indexer;
|
|
35
|
-
}
|
|
36
|
-
async function run(client, indexer) {
|
|
37
|
-
await indexerAsyncContext.callAsync({}, async () => {
|
|
38
|
-
const context = useIndexerContext();
|
|
39
|
-
const sink = indexer.options.sink ?? defaultSink();
|
|
40
|
-
context.sink = sink;
|
|
41
|
-
await indexer.hooks.callHook("run:before");
|
|
42
|
-
const isFactoryMode = indexer.options.factory !== void 0;
|
|
43
|
-
const request = indexer.streamConfig.Request.make({
|
|
44
|
-
filter: isFactoryMode ? [indexer.options.filter, {}] : [indexer.options.filter],
|
|
45
|
-
finality: indexer.options.finality,
|
|
46
|
-
startingCursor: indexer.options.startingCursor
|
|
47
|
-
});
|
|
48
|
-
const options = {};
|
|
49
|
-
await indexer.hooks.callHook("connect:before", { request, options });
|
|
50
|
-
let mainFilter;
|
|
51
|
-
if (isFactoryMode) {
|
|
52
|
-
mainFilter = request.filter[1];
|
|
53
|
-
}
|
|
54
|
-
let stream = client.streamData(request, options)[Symbol.asyncIterator]();
|
|
55
|
-
await indexer.hooks.callHook("connect:after");
|
|
56
|
-
while (true) {
|
|
57
|
-
const { value: message, done } = await stream.next();
|
|
58
|
-
if (done) {
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
await indexer.hooks.callHook("message", { message });
|
|
62
|
-
switch (message._tag) {
|
|
63
|
-
case "data": {
|
|
64
|
-
await tracer.startActiveSpan("message data", async (span) => {
|
|
65
|
-
const blocks = message.data.data;
|
|
66
|
-
const { cursor, endCursor, finality } = message.data;
|
|
67
|
-
await sink.transaction(
|
|
68
|
-
{ cursor, endCursor, finality },
|
|
69
|
-
async (txn) => {
|
|
70
|
-
context.sinkTransaction = txn;
|
|
71
|
-
let block;
|
|
72
|
-
if (isFactoryMode) {
|
|
73
|
-
assert(indexer.options.factory !== void 0);
|
|
74
|
-
const [factoryBlock, mainBlock] = blocks;
|
|
75
|
-
block = mainBlock;
|
|
76
|
-
if (factoryBlock !== null) {
|
|
77
|
-
const { filter } = await indexer.options.factory({
|
|
78
|
-
block: factoryBlock,
|
|
79
|
-
context
|
|
80
|
-
});
|
|
81
|
-
if (filter) {
|
|
82
|
-
mainFilter = indexer.streamConfig.mergeFilter(
|
|
83
|
-
mainFilter,
|
|
84
|
-
filter
|
|
85
|
-
);
|
|
86
|
-
const request2 = indexer.streamConfig.Request.make({
|
|
87
|
-
filter: [indexer.options.filter, mainFilter],
|
|
88
|
-
finality: indexer.options.finality,
|
|
89
|
-
startingCursor: cursor
|
|
90
|
-
});
|
|
91
|
-
await indexer.hooks.callHook("connect:factory", {
|
|
92
|
-
request: request2,
|
|
93
|
-
endCursor
|
|
94
|
-
});
|
|
95
|
-
stream = client.streamData(request2, options)[Symbol.asyncIterator]();
|
|
96
|
-
const { value: message2 } = await stream.next();
|
|
97
|
-
assert(message2._tag === "data");
|
|
98
|
-
const [_factoryBlock, _block] = message2.data.data;
|
|
99
|
-
block = _block;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
} else {
|
|
103
|
-
block = blocks[0];
|
|
104
|
-
}
|
|
105
|
-
if (block) {
|
|
106
|
-
await tracer.startActiveSpan("handler", async (span2) => {
|
|
107
|
-
await indexer.hooks.callHook("handler:before", {
|
|
108
|
-
block,
|
|
109
|
-
endCursor,
|
|
110
|
-
finality
|
|
111
|
-
});
|
|
112
|
-
try {
|
|
113
|
-
await indexer.options.transform({
|
|
114
|
-
block,
|
|
115
|
-
cursor,
|
|
116
|
-
endCursor,
|
|
117
|
-
finality,
|
|
118
|
-
context
|
|
119
|
-
});
|
|
120
|
-
await indexer.hooks.callHook("handler:after", {
|
|
121
|
-
block,
|
|
122
|
-
finality,
|
|
123
|
-
endCursor
|
|
124
|
-
});
|
|
125
|
-
} catch (error) {
|
|
126
|
-
assert(error instanceof Error);
|
|
127
|
-
await indexer.hooks.callHook("handler:exception", {
|
|
128
|
-
error
|
|
129
|
-
});
|
|
130
|
-
throw error;
|
|
131
|
-
}
|
|
132
|
-
span2.end();
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
);
|
|
137
|
-
await indexer.hooks.callHook("transaction:commit", {
|
|
138
|
-
finality,
|
|
139
|
-
endCursor
|
|
140
|
-
});
|
|
141
|
-
span.end();
|
|
142
|
-
});
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
case "invalidate": {
|
|
146
|
-
await tracer.startActiveSpan("message invalidate", async (span) => {
|
|
147
|
-
await sink.invalidate(message.invalidate.cursor);
|
|
148
|
-
});
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
default: {
|
|
152
|
-
consola.warn("unexpected message", message);
|
|
153
|
-
throw new Error("not implemented");
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
await indexer.hooks.callHook("run:after");
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
async function record(vcrConfig, client, indexerArg, cassetteOptions) {
|
|
162
|
-
const indexer = klona(indexerArg);
|
|
163
|
-
const messages = [];
|
|
164
|
-
indexer.hooks.addHooks({
|
|
165
|
-
"connect:before"({ options, request }) {
|
|
166
|
-
request.startingCursor = cassetteOptions.startingCursor;
|
|
167
|
-
options.endingCursor = cassetteOptions.endingCursor;
|
|
168
|
-
},
|
|
169
|
-
message({ message }) {
|
|
170
|
-
messages.push(message);
|
|
171
|
-
},
|
|
172
|
-
async "run:after"() {
|
|
173
|
-
const output = {
|
|
174
|
-
filter: indexer.options.filter,
|
|
175
|
-
messages
|
|
176
|
-
};
|
|
177
|
-
const filePath = path.join(
|
|
178
|
-
vcrConfig.cassetteDir,
|
|
179
|
-
`${cassetteOptions.name}.json`
|
|
180
|
-
);
|
|
181
|
-
await fs.writeFile(filePath, serialize(output), { flag: "w" });
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
await run(client, indexer);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
var __defProp = Object.defineProperty;
|
|
188
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
189
|
-
var __publicField = (obj, key, value) => {
|
|
190
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
191
|
-
return value;
|
|
192
|
-
};
|
|
193
|
-
const transactionHelper = (context) => {
|
|
194
|
-
return {
|
|
195
|
-
insert: (data) => {
|
|
196
|
-
context.buffer.push(...data);
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
};
|
|
200
|
-
class VcrSink extends Sink {
|
|
201
|
-
constructor() {
|
|
202
|
-
super(...arguments);
|
|
203
|
-
__publicField(this, "result", []);
|
|
204
|
-
}
|
|
205
|
-
write({ data, endCursor }) {
|
|
206
|
-
if (data.length === 0)
|
|
207
|
-
return;
|
|
208
|
-
this.result.push({ data, endCursor });
|
|
209
|
-
}
|
|
210
|
-
async transaction({ cursor, endCursor, finality }, cb) {
|
|
211
|
-
const context = {
|
|
212
|
-
buffer: []
|
|
213
|
-
};
|
|
214
|
-
const writer = transactionHelper(context);
|
|
215
|
-
await cb({ writer });
|
|
216
|
-
this.write({ data: context.buffer, endCursor });
|
|
217
|
-
}
|
|
218
|
-
async invalidate(cursor) {
|
|
219
|
-
throw new Error("Not implemented");
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
function vcr() {
|
|
223
|
-
return new VcrSink();
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
async function replay(vcrConfig, indexer, cassetteName) {
|
|
227
|
-
const client = loadCassette(vcrConfig, cassetteName);
|
|
228
|
-
const sink = vcr();
|
|
229
|
-
await run(client, indexer);
|
|
230
|
-
return {
|
|
231
|
-
outputs: sink.result
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
function loadCassette(vcrConfig, cassetteName) {
|
|
235
|
-
const filePath = path.join(vcrConfig.cassetteDir, `${cassetteName}.json`);
|
|
236
|
-
const data = fs$1.readFileSync(filePath, "utf8");
|
|
237
|
-
const cassetteData = deserialize(data);
|
|
238
|
-
const { filter, messages } = cassetteData;
|
|
239
|
-
return new MockClient((request, options) => {
|
|
240
|
-
assert.deepStrictEqual(
|
|
241
|
-
request.filter,
|
|
242
|
-
filter,
|
|
243
|
-
"Request and Cassette filter mismatch"
|
|
244
|
-
);
|
|
245
|
-
return messages;
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
export { VcrSink as V, record as a, replay as b, createIndexer as c, defineIndexer as d, loadCassette as l, run as r, vcr as v };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Cursor, Client } from '@apibara/protocol';
|
|
2
|
-
import { f as Indexer } from './indexer.c7ed6b83.cjs';
|
|
3
|
-
import { b as SinkData } from './indexer.b9c8f0d8.cjs';
|
|
4
|
-
|
|
5
|
-
type VcrConfig = {
|
|
6
|
-
cassetteDir: string;
|
|
7
|
-
};
|
|
8
|
-
type CassetteOptions = {
|
|
9
|
-
name: string;
|
|
10
|
-
startingCursor: Cursor;
|
|
11
|
-
endingCursor: Cursor;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
declare function replay<TFilter, TBlock, TTxnParams>(vcrConfig: VcrConfig, indexer: Indexer<TFilter, TBlock, TTxnParams>, cassetteName: string): Promise<VcrReplayResult>;
|
|
15
|
-
type VcrReplayResult = {
|
|
16
|
-
outputs: Array<{
|
|
17
|
-
endCursor?: Cursor;
|
|
18
|
-
data: SinkData[];
|
|
19
|
-
}>;
|
|
20
|
-
};
|
|
21
|
-
declare function loadCassette<TFilter, TBlock>(vcrConfig: VcrConfig, cassetteName: string): Client<TFilter, TBlock>;
|
|
22
|
-
|
|
23
|
-
export { type CassetteOptions as C, type VcrConfig as V, type VcrReplayResult as a, loadCassette as l, replay as r };
|