@apibara/indexer 2.0.0-beta.16 → 2.0.0-beta.17
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 +198 -36
- package/dist/index.d.cts +2 -16
- package/dist/index.d.mts +2 -16
- package/dist/index.d.ts +2 -16
- package/dist/index.mjs +190 -25
- package/dist/plugins/index.d.cts +2 -2
- package/dist/plugins/index.d.mts +2 -2
- package/dist/plugins/index.d.ts +2 -2
- package/dist/plugins/kv.cjs +12 -4
- package/dist/plugins/kv.d.cts +5 -3
- package/dist/plugins/kv.d.mts +5 -3
- package/dist/plugins/kv.d.ts +5 -3
- package/dist/plugins/kv.mjs +9 -2
- package/dist/plugins/persistence.cjs +2 -1
- package/dist/plugins/persistence.d.cts +2 -2
- package/dist/plugins/persistence.d.mts +2 -2
- package/dist/plugins/persistence.d.ts +2 -2
- package/dist/plugins/persistence.mjs +2 -1
- package/dist/shared/{indexer.2c23c9cd.mjs → indexer.0c0510df.mjs} +1 -14
- package/dist/shared/{indexer.1b97aab9.d.ts → indexer.0d847427.d.ts} +2 -8
- package/dist/shared/{indexer.93cfc7a5.d.cts → indexer.1082134b.d.cts} +2 -8
- package/dist/shared/{indexer.f2fc7e82.d.mts → indexer.108e1a0b.d.mts} +2 -8
- package/dist/shared/indexer.136b6ca6.mjs +15 -0
- package/dist/shared/{indexer.a7ecc7b3.d.ts → indexer.1895909f.d.cts} +12 -1
- package/dist/shared/{indexer.a7ecc7b3.d.mts → indexer.1895909f.d.mts} +12 -1
- package/dist/shared/{indexer.a7ecc7b3.d.cts → indexer.1895909f.d.ts} +12 -1
- package/dist/shared/{indexer.318d3617.cjs → indexer.219f58e0.cjs} +0 -16
- package/dist/shared/{indexer.1a975098.mjs → indexer.7ac83e6b.mjs} +9 -1
- package/dist/shared/indexer.f055283f.cjs +19 -0
- package/dist/shared/{indexer.d4b01878.cjs → indexer.fd803d5b.cjs} +9 -0
- package/dist/sinks/csv.cjs +1 -1
- package/dist/sinks/csv.d.cts +1 -1
- package/dist/sinks/csv.d.mts +1 -1
- package/dist/sinks/csv.d.ts +1 -1
- package/dist/sinks/csv.mjs +1 -1
- package/dist/sinks/drizzle/index.cjs +1 -1
- package/dist/sinks/drizzle/index.d.cts +1 -1
- package/dist/sinks/drizzle/index.d.mts +1 -1
- package/dist/sinks/drizzle/index.d.ts +1 -1
- package/dist/sinks/drizzle/index.mjs +1 -1
- package/dist/sinks/sqlite.cjs +1 -1
- package/dist/sinks/sqlite.d.cts +1 -1
- package/dist/sinks/sqlite.d.mts +1 -1
- package/dist/sinks/sqlite.d.ts +1 -1
- package/dist/sinks/sqlite.mjs +1 -1
- package/dist/testing/index.cjs +40 -46
- package/dist/testing/index.d.cts +9 -37
- package/dist/testing/index.d.mts +9 -37
- package/dist/testing/index.d.ts +9 -37
- package/dist/testing/index.mjs +36 -44
- package/dist/vcr/index.cjs +66 -14
- package/dist/vcr/index.d.cts +16 -6
- package/dist/vcr/index.d.mts +16 -6
- package/dist/vcr/index.d.ts +16 -6
- package/dist/vcr/index.mjs +61 -11
- package/package.json +3 -2
- package/src/index.ts +0 -4
- package/src/indexer.test.ts +10 -7
- package/src/internal/testing.ts +107 -0
- package/src/plugins/kv.ts +10 -0
- package/src/plugins/persistence.test.ts +1 -2
- package/src/sink.ts +15 -0
- package/src/sinks/csv.test.ts +2 -4
- package/src/sinks/drizzle/drizzle.test.ts +2 -3
- package/src/sinks/sqlite.test.ts +2 -4
- package/src/testing/index.ts +47 -3
- package/src/vcr/record.ts +4 -0
- package/src/vcr/replay.ts +7 -17
- package/dist/shared/indexer.01aa4f30.mjs +0 -291
- package/dist/shared/indexer.4233a929.cjs +0 -308
- package/dist/shared/indexer.82aac5b5.d.mts +0 -23
- package/dist/shared/indexer.cb7e11cb.d.ts +0 -23
- package/dist/shared/indexer.e157d75a.d.cts +0 -23
- package/src/hooks/index.ts +0 -2
- package/src/hooks/useKVStore.ts +0 -12
- package/src/hooks/useSink.ts +0 -13
- 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 -59
package/dist/index.cjs
CHANGED
|
@@ -1,50 +1,212 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
require('
|
|
8
|
-
require('node:path');
|
|
9
|
-
require('klona/full');
|
|
10
|
-
require('consola');
|
|
11
|
-
require('hookable');
|
|
12
|
-
require('node:assert');
|
|
13
|
-
require('node:fs');
|
|
14
|
-
require('@apibara/protocol/testing');
|
|
3
|
+
const consola = require('consola');
|
|
4
|
+
const hookable = require('hookable');
|
|
5
|
+
const assert = require('node:assert');
|
|
6
|
+
const otel = require('./shared/indexer.f055283f.cjs');
|
|
7
|
+
const sink = require('./shared/indexer.fd803d5b.cjs');
|
|
15
8
|
require('node:async_hooks');
|
|
16
9
|
require('unctx');
|
|
17
10
|
require('@opentelemetry/api');
|
|
18
11
|
|
|
19
|
-
function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return ctx.kv;
|
|
24
|
-
}
|
|
12
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
13
|
+
|
|
14
|
+
const consola__default = /*#__PURE__*/_interopDefaultCompat(consola);
|
|
15
|
+
const assert__default = /*#__PURE__*/_interopDefaultCompat(assert);
|
|
25
16
|
|
|
26
|
-
function
|
|
27
|
-
|
|
17
|
+
function defineIndexer(streamConfig) {
|
|
18
|
+
return (config) => ({
|
|
19
|
+
streamConfig,
|
|
20
|
+
...config
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function createIndexer({
|
|
24
|
+
streamConfig,
|
|
25
|
+
...options
|
|
28
26
|
}) {
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
const indexer = {
|
|
28
|
+
options,
|
|
29
|
+
streamConfig,
|
|
30
|
+
hooks: hookable.createHooks()
|
|
31
|
+
};
|
|
32
|
+
if (indexer.options.debug) {
|
|
33
|
+
hookable.createDebugger(indexer.hooks, { tag: "indexer" });
|
|
31
34
|
}
|
|
32
|
-
|
|
35
|
+
indexer.hooks.addHooks(indexer.options.hooks ?? {});
|
|
36
|
+
for (const plugin of indexer.options.plugins ?? []) {
|
|
37
|
+
plugin(indexer);
|
|
38
|
+
}
|
|
39
|
+
return indexer;
|
|
40
|
+
}
|
|
41
|
+
async function run(client, indexer) {
|
|
42
|
+
await otel.indexerAsyncContext.callAsync({}, async () => {
|
|
43
|
+
const context = otel.useIndexerContext();
|
|
44
|
+
const sink$1 = indexer.options.sink ?? sink.defaultSink();
|
|
45
|
+
context.sink = sink$1;
|
|
46
|
+
await indexer.hooks.callHook("run:before");
|
|
47
|
+
const isFactoryMode = indexer.options.factory !== void 0;
|
|
48
|
+
const request = indexer.streamConfig.Request.make({
|
|
49
|
+
filter: isFactoryMode ? [indexer.options.filter, {}] : [indexer.options.filter],
|
|
50
|
+
finality: indexer.options.finality,
|
|
51
|
+
startingCursor: indexer.options.startingCursor
|
|
52
|
+
});
|
|
53
|
+
const options = {};
|
|
54
|
+
await indexer.hooks.callHook("connect:before", { request, options });
|
|
55
|
+
let mainFilter;
|
|
56
|
+
if (isFactoryMode) {
|
|
57
|
+
mainFilter = request.filter[1];
|
|
58
|
+
}
|
|
59
|
+
let stream = client.streamData(request, options)[Symbol.asyncIterator]();
|
|
60
|
+
await indexer.hooks.callHook("connect:after");
|
|
61
|
+
while (true) {
|
|
62
|
+
const { value: message, done } = await stream.next();
|
|
63
|
+
if (done) {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
await indexer.hooks.callHook("message", { message });
|
|
67
|
+
switch (message._tag) {
|
|
68
|
+
case "data": {
|
|
69
|
+
await otel.tracer.startActiveSpan("message data", async (span) => {
|
|
70
|
+
const blocks = message.data.data;
|
|
71
|
+
const { cursor, endCursor, finality } = message.data;
|
|
72
|
+
await sink$1.transaction(
|
|
73
|
+
{ cursor, endCursor, finality },
|
|
74
|
+
async (txn) => {
|
|
75
|
+
context.sinkTransaction = txn;
|
|
76
|
+
let block;
|
|
77
|
+
if (isFactoryMode) {
|
|
78
|
+
assert__default(indexer.options.factory !== void 0);
|
|
79
|
+
const [factoryBlock, mainBlock] = blocks;
|
|
80
|
+
block = mainBlock;
|
|
81
|
+
if (factoryBlock !== null) {
|
|
82
|
+
const { filter } = await indexer.options.factory({
|
|
83
|
+
block: factoryBlock,
|
|
84
|
+
context
|
|
85
|
+
});
|
|
86
|
+
if (filter) {
|
|
87
|
+
mainFilter = indexer.streamConfig.mergeFilter(
|
|
88
|
+
mainFilter,
|
|
89
|
+
filter
|
|
90
|
+
);
|
|
91
|
+
const request2 = indexer.streamConfig.Request.make({
|
|
92
|
+
filter: [indexer.options.filter, mainFilter],
|
|
93
|
+
finality: indexer.options.finality,
|
|
94
|
+
startingCursor: cursor
|
|
95
|
+
});
|
|
96
|
+
await indexer.hooks.callHook("connect:factory", {
|
|
97
|
+
request: request2,
|
|
98
|
+
endCursor
|
|
99
|
+
});
|
|
100
|
+
stream = client.streamData(request2, options)[Symbol.asyncIterator]();
|
|
101
|
+
const { value: message2 } = await stream.next();
|
|
102
|
+
assert__default(message2._tag === "data");
|
|
103
|
+
const [_factoryBlock, _block] = message2.data.data;
|
|
104
|
+
block = _block;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
block = blocks[0];
|
|
109
|
+
}
|
|
110
|
+
if (block) {
|
|
111
|
+
await otel.tracer.startActiveSpan("handler", async (span2) => {
|
|
112
|
+
await indexer.hooks.callHook("handler:before", {
|
|
113
|
+
block,
|
|
114
|
+
endCursor,
|
|
115
|
+
finality
|
|
116
|
+
});
|
|
117
|
+
try {
|
|
118
|
+
await indexer.options.transform({
|
|
119
|
+
block,
|
|
120
|
+
cursor,
|
|
121
|
+
endCursor,
|
|
122
|
+
finality,
|
|
123
|
+
context
|
|
124
|
+
});
|
|
125
|
+
await indexer.hooks.callHook("handler:after", {
|
|
126
|
+
block,
|
|
127
|
+
finality,
|
|
128
|
+
endCursor
|
|
129
|
+
});
|
|
130
|
+
} catch (error) {
|
|
131
|
+
assert__default(error instanceof Error);
|
|
132
|
+
await indexer.hooks.callHook("handler:exception", {
|
|
133
|
+
error
|
|
134
|
+
});
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
span2.end();
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
await indexer.hooks.callHook("transaction:commit", {
|
|
143
|
+
finality,
|
|
144
|
+
endCursor
|
|
145
|
+
});
|
|
146
|
+
span.end();
|
|
147
|
+
});
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
case "invalidate": {
|
|
151
|
+
await otel.tracer.startActiveSpan("message invalidate", async (span) => {
|
|
152
|
+
await sink$1.invalidate(message.invalidate.cursor);
|
|
153
|
+
await indexer.hooks.callHook("message:invalidate", { message });
|
|
154
|
+
span.end();
|
|
155
|
+
});
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case "finalize": {
|
|
159
|
+
await otel.tracer.startActiveSpan("message finalize", async (span) => {
|
|
160
|
+
await sink$1.finalize(message.finalize.cursor);
|
|
161
|
+
await indexer.hooks.callHook("message:finalize", { message });
|
|
162
|
+
span.end();
|
|
163
|
+
});
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case "heartbeat": {
|
|
167
|
+
await otel.tracer.startActiveSpan("message heartbeat", async (span) => {
|
|
168
|
+
await indexer.hooks.callHook("message:heartbeat", { message });
|
|
169
|
+
span.end();
|
|
170
|
+
});
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case "systemMessage": {
|
|
174
|
+
await otel.tracer.startActiveSpan(
|
|
175
|
+
"message systemMessage",
|
|
176
|
+
async (span) => {
|
|
177
|
+
switch (message.systemMessage.output?._tag) {
|
|
178
|
+
case "stderr": {
|
|
179
|
+
consola__default.warn(message.systemMessage.output.stderr);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
case "stdout": {
|
|
183
|
+
consola__default.info(message.systemMessage.output.stdout);
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
await indexer.hooks.callHook("message:systemMessage", {
|
|
188
|
+
message
|
|
189
|
+
});
|
|
190
|
+
span.end();
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
default: {
|
|
196
|
+
consola__default.warn("unexpected message", message);
|
|
197
|
+
throw new Error("not implemented");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
await indexer.hooks.callHook("run:after");
|
|
201
|
+
}
|
|
202
|
+
});
|
|
33
203
|
}
|
|
34
204
|
|
|
35
|
-
exports.
|
|
36
|
-
exports.defineIndexer = vcr_index.defineIndexer;
|
|
37
|
-
exports.loadCassette = vcr_index.loadCassette;
|
|
38
|
-
exports.record = vcr_index.record;
|
|
39
|
-
exports.replay = vcr_index.replay;
|
|
40
|
-
exports.run = vcr_index.run;
|
|
205
|
+
exports.useIndexerContext = otel.useIndexerContext;
|
|
41
206
|
exports.DefaultSink = sink.DefaultSink;
|
|
42
207
|
exports.Sink = sink.Sink;
|
|
43
208
|
exports.defaultSink = sink.defaultSink;
|
|
44
|
-
exports.
|
|
45
|
-
exports.
|
|
46
|
-
exports.
|
|
47
|
-
exports.
|
|
48
|
-
exports.defineIndexerPlugin = plugins_index.defineIndexerPlugin;
|
|
49
|
-
exports.useKVStore = useKVStore;
|
|
50
|
-
exports.useSink = useSink;
|
|
209
|
+
exports.useSink = sink.useSink;
|
|
210
|
+
exports.createIndexer = createIndexer;
|
|
211
|
+
exports.defineIndexer = defineIndexer;
|
|
212
|
+
exports.run = run;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export { D as DefaultSink, S as Sink, a as SinkCursorParams, b as SinkData, d as defaultSink } from './shared/indexer.a7ecc7b3.cjs';
|
|
4
|
-
export { C as CassetteOptions, V as VcrConfig, a as VcrReplayResult, l as loadCassette, r as replay } from './shared/indexer.e157d75a.cjs';
|
|
5
|
-
export { CassetteDataType, deserialize, isCassetteAvailable, record, serialize } from './vcr/index.cjs';
|
|
6
|
-
import { KVStore } from './plugins/kv.cjs';
|
|
1
|
+
export { b as Indexer, e as IndexerConfig, c as IndexerHooks, I as IndexerWithStreamConfig, g as createIndexer, f as defineIndexer, r as run } from './shared/indexer.1082134b.cjs';
|
|
2
|
+
export { D as DefaultSink, S as Sink, a as SinkCursorParams, b as SinkData, d as defaultSink, u as useIndexerContext, c as useSink } from './shared/indexer.1895909f.cjs';
|
|
7
3
|
import '@apibara/protocol';
|
|
8
4
|
import 'hookable';
|
|
9
|
-
import 'better-sqlite3';
|
|
10
|
-
|
|
11
|
-
type UseKVStoreResult = InstanceType<typeof KVStore>;
|
|
12
|
-
declare function useKVStore(): UseKVStoreResult;
|
|
13
|
-
|
|
14
|
-
declare function useSink<TTxnParams>({ context, }: {
|
|
15
|
-
context: IndexerContext<TTxnParams>;
|
|
16
|
-
}): NonNullable<TTxnParams>;
|
|
17
|
-
|
|
18
|
-
export { type UseKVStoreResult, useKVStore, useSink };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export { D as DefaultSink, S as Sink, a as SinkCursorParams, b as SinkData, d as defaultSink } from './shared/indexer.a7ecc7b3.mjs';
|
|
4
|
-
export { C as CassetteOptions, V as VcrConfig, a as VcrReplayResult, l as loadCassette, r as replay } from './shared/indexer.82aac5b5.mjs';
|
|
5
|
-
export { CassetteDataType, deserialize, isCassetteAvailable, record, serialize } from './vcr/index.mjs';
|
|
6
|
-
import { KVStore } from './plugins/kv.mjs';
|
|
1
|
+
export { b as Indexer, e as IndexerConfig, c as IndexerHooks, I as IndexerWithStreamConfig, g as createIndexer, f as defineIndexer, r as run } from './shared/indexer.108e1a0b.mjs';
|
|
2
|
+
export { D as DefaultSink, S as Sink, a as SinkCursorParams, b as SinkData, d as defaultSink, u as useIndexerContext, c as useSink } from './shared/indexer.1895909f.mjs';
|
|
7
3
|
import '@apibara/protocol';
|
|
8
4
|
import 'hookable';
|
|
9
|
-
import 'better-sqlite3';
|
|
10
|
-
|
|
11
|
-
type UseKVStoreResult = InstanceType<typeof KVStore>;
|
|
12
|
-
declare function useKVStore(): UseKVStoreResult;
|
|
13
|
-
|
|
14
|
-
declare function useSink<TTxnParams>({ context, }: {
|
|
15
|
-
context: IndexerContext<TTxnParams>;
|
|
16
|
-
}): NonNullable<TTxnParams>;
|
|
17
|
-
|
|
18
|
-
export { type UseKVStoreResult, useKVStore, useSink };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export { D as DefaultSink, S as Sink, a as SinkCursorParams, b as SinkData, d as defaultSink } from './shared/indexer.a7ecc7b3.js';
|
|
4
|
-
export { C as CassetteOptions, V as VcrConfig, a as VcrReplayResult, l as loadCassette, r as replay } from './shared/indexer.cb7e11cb.js';
|
|
5
|
-
export { CassetteDataType, deserialize, isCassetteAvailable, record, serialize } from './vcr/index.js';
|
|
6
|
-
import { KVStore } from './plugins/kv.js';
|
|
1
|
+
export { b as Indexer, e as IndexerConfig, c as IndexerHooks, I as IndexerWithStreamConfig, g as createIndexer, f as defineIndexer, r as run } from './shared/indexer.0d847427.js';
|
|
2
|
+
export { D as DefaultSink, S as Sink, a as SinkCursorParams, b as SinkData, d as defaultSink, u as useIndexerContext, c as useSink } from './shared/indexer.1895909f.js';
|
|
7
3
|
import '@apibara/protocol';
|
|
8
4
|
import 'hookable';
|
|
9
|
-
import 'better-sqlite3';
|
|
10
|
-
|
|
11
|
-
type UseKVStoreResult = InstanceType<typeof KVStore>;
|
|
12
|
-
declare function useKVStore(): UseKVStoreResult;
|
|
13
|
-
|
|
14
|
-
declare function useSink<TTxnParams>({ context, }: {
|
|
15
|
-
context: IndexerContext<TTxnParams>;
|
|
16
|
-
}): NonNullable<TTxnParams>;
|
|
17
|
-
|
|
18
|
-
export { type UseKVStoreResult, useKVStore, useSink };
|
package/dist/index.mjs
CHANGED
|
@@ -1,34 +1,199 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import 'node:path';
|
|
8
|
-
import 'klona/full';
|
|
9
|
-
import 'consola';
|
|
10
|
-
import 'hookable';
|
|
11
|
-
import 'node:assert';
|
|
12
|
-
import 'node:fs';
|
|
13
|
-
import '@apibara/protocol/testing';
|
|
1
|
+
import consola from 'consola';
|
|
2
|
+
import { createHooks, createDebugger } from 'hookable';
|
|
3
|
+
import assert from 'node:assert';
|
|
4
|
+
import { i as indexerAsyncContext, u as useIndexerContext, t as tracer } from './shared/indexer.136b6ca6.mjs';
|
|
5
|
+
import { d as defaultSink } from './shared/indexer.7ac83e6b.mjs';
|
|
6
|
+
export { D as DefaultSink, S as Sink, u as useSink } from './shared/indexer.7ac83e6b.mjs';
|
|
14
7
|
import 'node:async_hooks';
|
|
15
8
|
import 'unctx';
|
|
16
9
|
import '@opentelemetry/api';
|
|
17
10
|
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
function defineIndexer(streamConfig) {
|
|
12
|
+
return (config) => ({
|
|
13
|
+
streamConfig,
|
|
14
|
+
...config
|
|
15
|
+
});
|
|
23
16
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
function createIndexer({
|
|
18
|
+
streamConfig,
|
|
19
|
+
...options
|
|
27
20
|
}) {
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
const indexer = {
|
|
22
|
+
options,
|
|
23
|
+
streamConfig,
|
|
24
|
+
hooks: createHooks()
|
|
25
|
+
};
|
|
26
|
+
if (indexer.options.debug) {
|
|
27
|
+
createDebugger(indexer.hooks, { tag: "indexer" });
|
|
28
|
+
}
|
|
29
|
+
indexer.hooks.addHooks(indexer.options.hooks ?? {});
|
|
30
|
+
for (const plugin of indexer.options.plugins ?? []) {
|
|
31
|
+
plugin(indexer);
|
|
30
32
|
}
|
|
31
|
-
return
|
|
33
|
+
return indexer;
|
|
34
|
+
}
|
|
35
|
+
async function run(client, indexer) {
|
|
36
|
+
await indexerAsyncContext.callAsync({}, async () => {
|
|
37
|
+
const context = useIndexerContext();
|
|
38
|
+
const sink = indexer.options.sink ?? defaultSink();
|
|
39
|
+
context.sink = sink;
|
|
40
|
+
await indexer.hooks.callHook("run:before");
|
|
41
|
+
const isFactoryMode = indexer.options.factory !== void 0;
|
|
42
|
+
const request = indexer.streamConfig.Request.make({
|
|
43
|
+
filter: isFactoryMode ? [indexer.options.filter, {}] : [indexer.options.filter],
|
|
44
|
+
finality: indexer.options.finality,
|
|
45
|
+
startingCursor: indexer.options.startingCursor
|
|
46
|
+
});
|
|
47
|
+
const options = {};
|
|
48
|
+
await indexer.hooks.callHook("connect:before", { request, options });
|
|
49
|
+
let mainFilter;
|
|
50
|
+
if (isFactoryMode) {
|
|
51
|
+
mainFilter = request.filter[1];
|
|
52
|
+
}
|
|
53
|
+
let stream = client.streamData(request, options)[Symbol.asyncIterator]();
|
|
54
|
+
await indexer.hooks.callHook("connect:after");
|
|
55
|
+
while (true) {
|
|
56
|
+
const { value: message, done } = await stream.next();
|
|
57
|
+
if (done) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
await indexer.hooks.callHook("message", { message });
|
|
61
|
+
switch (message._tag) {
|
|
62
|
+
case "data": {
|
|
63
|
+
await tracer.startActiveSpan("message data", async (span) => {
|
|
64
|
+
const blocks = message.data.data;
|
|
65
|
+
const { cursor, endCursor, finality } = message.data;
|
|
66
|
+
await sink.transaction(
|
|
67
|
+
{ cursor, endCursor, finality },
|
|
68
|
+
async (txn) => {
|
|
69
|
+
context.sinkTransaction = txn;
|
|
70
|
+
let block;
|
|
71
|
+
if (isFactoryMode) {
|
|
72
|
+
assert(indexer.options.factory !== void 0);
|
|
73
|
+
const [factoryBlock, mainBlock] = blocks;
|
|
74
|
+
block = mainBlock;
|
|
75
|
+
if (factoryBlock !== null) {
|
|
76
|
+
const { filter } = await indexer.options.factory({
|
|
77
|
+
block: factoryBlock,
|
|
78
|
+
context
|
|
79
|
+
});
|
|
80
|
+
if (filter) {
|
|
81
|
+
mainFilter = indexer.streamConfig.mergeFilter(
|
|
82
|
+
mainFilter,
|
|
83
|
+
filter
|
|
84
|
+
);
|
|
85
|
+
const request2 = indexer.streamConfig.Request.make({
|
|
86
|
+
filter: [indexer.options.filter, mainFilter],
|
|
87
|
+
finality: indexer.options.finality,
|
|
88
|
+
startingCursor: cursor
|
|
89
|
+
});
|
|
90
|
+
await indexer.hooks.callHook("connect:factory", {
|
|
91
|
+
request: request2,
|
|
92
|
+
endCursor
|
|
93
|
+
});
|
|
94
|
+
stream = client.streamData(request2, options)[Symbol.asyncIterator]();
|
|
95
|
+
const { value: message2 } = await stream.next();
|
|
96
|
+
assert(message2._tag === "data");
|
|
97
|
+
const [_factoryBlock, _block] = message2.data.data;
|
|
98
|
+
block = _block;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
block = blocks[0];
|
|
103
|
+
}
|
|
104
|
+
if (block) {
|
|
105
|
+
await tracer.startActiveSpan("handler", async (span2) => {
|
|
106
|
+
await indexer.hooks.callHook("handler:before", {
|
|
107
|
+
block,
|
|
108
|
+
endCursor,
|
|
109
|
+
finality
|
|
110
|
+
});
|
|
111
|
+
try {
|
|
112
|
+
await indexer.options.transform({
|
|
113
|
+
block,
|
|
114
|
+
cursor,
|
|
115
|
+
endCursor,
|
|
116
|
+
finality,
|
|
117
|
+
context
|
|
118
|
+
});
|
|
119
|
+
await indexer.hooks.callHook("handler:after", {
|
|
120
|
+
block,
|
|
121
|
+
finality,
|
|
122
|
+
endCursor
|
|
123
|
+
});
|
|
124
|
+
} catch (error) {
|
|
125
|
+
assert(error instanceof Error);
|
|
126
|
+
await indexer.hooks.callHook("handler:exception", {
|
|
127
|
+
error
|
|
128
|
+
});
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
span2.end();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
await indexer.hooks.callHook("transaction:commit", {
|
|
137
|
+
finality,
|
|
138
|
+
endCursor
|
|
139
|
+
});
|
|
140
|
+
span.end();
|
|
141
|
+
});
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case "invalidate": {
|
|
145
|
+
await tracer.startActiveSpan("message invalidate", async (span) => {
|
|
146
|
+
await sink.invalidate(message.invalidate.cursor);
|
|
147
|
+
await indexer.hooks.callHook("message:invalidate", { message });
|
|
148
|
+
span.end();
|
|
149
|
+
});
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "finalize": {
|
|
153
|
+
await tracer.startActiveSpan("message finalize", async (span) => {
|
|
154
|
+
await sink.finalize(message.finalize.cursor);
|
|
155
|
+
await indexer.hooks.callHook("message:finalize", { message });
|
|
156
|
+
span.end();
|
|
157
|
+
});
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case "heartbeat": {
|
|
161
|
+
await tracer.startActiveSpan("message heartbeat", async (span) => {
|
|
162
|
+
await indexer.hooks.callHook("message:heartbeat", { message });
|
|
163
|
+
span.end();
|
|
164
|
+
});
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case "systemMessage": {
|
|
168
|
+
await tracer.startActiveSpan(
|
|
169
|
+
"message systemMessage",
|
|
170
|
+
async (span) => {
|
|
171
|
+
switch (message.systemMessage.output?._tag) {
|
|
172
|
+
case "stderr": {
|
|
173
|
+
consola.warn(message.systemMessage.output.stderr);
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
case "stdout": {
|
|
177
|
+
consola.info(message.systemMessage.output.stdout);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
await indexer.hooks.callHook("message:systemMessage", {
|
|
182
|
+
message
|
|
183
|
+
});
|
|
184
|
+
span.end();
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
default: {
|
|
190
|
+
consola.warn("unexpected message", message);
|
|
191
|
+
throw new Error("not implemented");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
await indexer.hooks.callHook("run:after");
|
|
195
|
+
}
|
|
196
|
+
});
|
|
32
197
|
}
|
|
33
198
|
|
|
34
|
-
export {
|
|
199
|
+
export { createIndexer, defaultSink, defineIndexer, run, useIndexerContext };
|
package/dist/plugins/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { a as IndexerPlugin, d as defineIndexerPlugin } from '../shared/indexer.1082134b.cjs';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
|
4
|
-
import '../shared/indexer.
|
|
4
|
+
import '../shared/indexer.1895909f.cjs';
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { a as IndexerPlugin, d as defineIndexerPlugin } from '../shared/indexer.108e1a0b.mjs';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
|
4
|
-
import '../shared/indexer.
|
|
4
|
+
import '../shared/indexer.1895909f.mjs';
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { a as IndexerPlugin, d as defineIndexerPlugin } from '../shared/indexer.0d847427.js';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
|
4
|
-
import '../shared/indexer.
|
|
4
|
+
import '../shared/indexer.1895909f.js';
|
package/dist/plugins/kv.cjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const assert = require('node:assert');
|
|
4
|
-
const
|
|
4
|
+
const otel = require('../shared/indexer.f055283f.cjs');
|
|
5
|
+
const helper = require('../shared/indexer.219f58e0.cjs');
|
|
5
6
|
require('node:fs/promises');
|
|
6
7
|
require('node:path');
|
|
7
8
|
require('klona/full');
|
|
@@ -32,18 +33,18 @@ function kv({
|
|
|
32
33
|
KVStore.initialize(database);
|
|
33
34
|
});
|
|
34
35
|
indexer.hooks.hook("handler:before", ({ finality, endCursor }) => {
|
|
35
|
-
const ctx =
|
|
36
|
+
const ctx = otel.useIndexerContext();
|
|
36
37
|
assert__default(endCursor, new Error("endCursor cannot be undefined"));
|
|
37
38
|
ctx.kv = new KVStore(database, finality, endCursor);
|
|
38
39
|
ctx.kv.beginTransaction();
|
|
39
40
|
});
|
|
40
41
|
indexer.hooks.hook("handler:after", () => {
|
|
41
|
-
const ctx =
|
|
42
|
+
const ctx = otel.useIndexerContext();
|
|
42
43
|
ctx.kv.commitTransaction();
|
|
43
44
|
ctx.kv = null;
|
|
44
45
|
});
|
|
45
46
|
indexer.hooks.hook("handler:exception", () => {
|
|
46
|
-
const ctx =
|
|
47
|
+
const ctx = otel.useIndexerContext();
|
|
47
48
|
ctx.kv.rollbackTransaction();
|
|
48
49
|
ctx.kv = null;
|
|
49
50
|
});
|
|
@@ -98,6 +99,12 @@ class KVStore {
|
|
|
98
99
|
this._delQuery.run(Number(this._endCursor.orderKey), key);
|
|
99
100
|
}
|
|
100
101
|
}
|
|
102
|
+
function useKVStore() {
|
|
103
|
+
const ctx = otel.useIndexerContext();
|
|
104
|
+
if (!ctx?.kv)
|
|
105
|
+
throw new Error("KV Plugin is not available in context!");
|
|
106
|
+
return ctx.kv;
|
|
107
|
+
}
|
|
101
108
|
const statements = {
|
|
102
109
|
beginTxn: "BEGIN TRANSACTION",
|
|
103
110
|
commitTxn: "COMMIT TRANSACTION",
|
|
@@ -129,3 +136,4 @@ const statements = {
|
|
|
129
136
|
|
|
130
137
|
exports.KVStore = KVStore;
|
|
131
138
|
exports.kv = kv;
|
|
139
|
+
exports.useKVStore = useKVStore;
|
package/dist/plugins/kv.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as IndexerPlugin } from '../shared/indexer.1082134b.cjs';
|
|
2
2
|
import { DataFinality, Cursor } from '@apibara/protocol';
|
|
3
3
|
import { Database } from 'better-sqlite3';
|
|
4
4
|
import 'hookable';
|
|
5
|
-
import '../shared/indexer.
|
|
5
|
+
import '../shared/indexer.1895909f.cjs';
|
|
6
6
|
|
|
7
7
|
declare function kv<TFilter, TBlock, TTxnParams>({ database, }: {
|
|
8
8
|
database: Database;
|
|
@@ -28,5 +28,7 @@ declare class KVStore {
|
|
|
28
28
|
put<T>(key: string, value: T): void;
|
|
29
29
|
del(key: string): void;
|
|
30
30
|
}
|
|
31
|
+
type UseKVStoreResult = InstanceType<typeof KVStore>;
|
|
32
|
+
declare function useKVStore(): UseKVStoreResult;
|
|
31
33
|
|
|
32
|
-
export { KVStore, kv };
|
|
34
|
+
export { KVStore, type UseKVStoreResult, kv, useKVStore };
|
package/dist/plugins/kv.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as IndexerPlugin } from '../shared/indexer.108e1a0b.mjs';
|
|
2
2
|
import { DataFinality, Cursor } from '@apibara/protocol';
|
|
3
3
|
import { Database } from 'better-sqlite3';
|
|
4
4
|
import 'hookable';
|
|
5
|
-
import '../shared/indexer.
|
|
5
|
+
import '../shared/indexer.1895909f.mjs';
|
|
6
6
|
|
|
7
7
|
declare function kv<TFilter, TBlock, TTxnParams>({ database, }: {
|
|
8
8
|
database: Database;
|
|
@@ -28,5 +28,7 @@ declare class KVStore {
|
|
|
28
28
|
put<T>(key: string, value: T): void;
|
|
29
29
|
del(key: string): void;
|
|
30
30
|
}
|
|
31
|
+
type UseKVStoreResult = InstanceType<typeof KVStore>;
|
|
32
|
+
declare function useKVStore(): UseKVStoreResult;
|
|
31
33
|
|
|
32
|
-
export { KVStore, kv };
|
|
34
|
+
export { KVStore, type UseKVStoreResult, kv, useKVStore };
|