@apibara/indexer 2.1.0-beta.3 → 2.1.0-beta.30
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 +70 -26
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +60 -16
- package/dist/internal/plugins.cjs +3 -4
- package/dist/internal/plugins.d.cts +1 -1
- package/dist/internal/plugins.d.mts +1 -1
- package/dist/internal/plugins.d.ts +1 -1
- package/dist/internal/plugins.mjs +1 -2
- package/dist/internal/testing.cjs +24 -10
- package/dist/internal/testing.d.cts +5 -3
- package/dist/internal/testing.d.mts +5 -3
- package/dist/internal/testing.d.ts +5 -3
- package/dist/internal/testing.mjs +22 -8
- package/dist/plugins/index.cjs +3 -4
- 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/index.mjs +3 -4
- package/dist/shared/{indexer.077335f3.cjs → indexer.479ae593.cjs} +5 -0
- package/dist/shared/{indexer.a55ad619.mjs → indexer.75773ef1.mjs} +5 -1
- package/dist/shared/{indexer.fedcd831.d.cts → indexer.7668fe34.d.cts} +2 -4
- package/dist/shared/{indexer.fedcd831.d.mts → indexer.7668fe34.d.mts} +2 -4
- package/dist/shared/{indexer.fedcd831.d.ts → indexer.7668fe34.d.ts} +2 -4
- package/dist/shared/{indexer.ff25c953.mjs → indexer.98a921a7.mjs} +1 -2
- package/dist/shared/{indexer.2416906c.cjs → indexer.a09fa402.cjs} +3 -4
- package/dist/testing/index.cjs +9 -5
- package/dist/testing/index.d.cts +4 -3
- package/dist/testing/index.d.mts +4 -3
- package/dist/testing/index.d.ts +4 -3
- package/dist/testing/index.mjs +9 -5
- package/dist/vcr/index.cjs +2 -1
- package/dist/vcr/index.d.cts +1 -1
- package/dist/vcr/index.d.mts +1 -1
- package/dist/vcr/index.d.ts +1 -1
- package/dist/vcr/index.mjs +2 -1
- package/package.json +3 -3
- package/src/indexer.ts +47 -15
- package/src/internal/testing.ts +34 -11
- package/src/otel.ts +29 -2
- package/src/testing/index.ts +11 -0
- package/dist/shared/indexer.601ceab0.cjs +0 -7
- package/dist/shared/indexer.9b21ddd2.mjs +0 -5
- package/src/compose.test.ts +0 -76
- package/src/indexer.test.ts +0 -430
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { isCursor } from '@apibara/protocol';
|
|
2
2
|
import { MockStream } from '@apibara/protocol/testing';
|
|
3
|
-
import { u as useIndexerContext } from '../shared/indexer.
|
|
3
|
+
import { d as defineIndexerPlugin, u as useIndexerContext } from '../shared/indexer.75773ef1.mjs';
|
|
4
4
|
import { createIndexer, defineIndexer } from '../index.mjs';
|
|
5
|
-
import {
|
|
6
|
-
import 'consola';
|
|
5
|
+
import { l as logger } from '../shared/indexer.98a921a7.mjs';
|
|
7
6
|
import { internalContext } from './plugins.mjs';
|
|
8
7
|
import 'node:async_hooks';
|
|
9
8
|
import 'unctx';
|
|
9
|
+
import 'consola';
|
|
10
10
|
import 'hookable';
|
|
11
11
|
import 'node:assert';
|
|
12
12
|
import '@opentelemetry/api';
|
|
@@ -15,22 +15,29 @@ function generateMockMessages(count = 10, options) {
|
|
|
15
15
|
const invalidateAt = options?.invalidate;
|
|
16
16
|
const finalizeAt = options?.finalize;
|
|
17
17
|
const messages = [];
|
|
18
|
+
const baseBlockNumber = options?.baseBlockNumber ?? BigInt(5e6);
|
|
18
19
|
for (let i = 0; i < count; i++) {
|
|
20
|
+
const currentBlockNumber = baseBlockNumber + BigInt(i);
|
|
21
|
+
const uniqueKey = uniqueKeyFromOrderKey(currentBlockNumber);
|
|
19
22
|
if (invalidateAt && i === invalidateAt.invalidateTriggerIndex) {
|
|
23
|
+
const invalidateToBlock = baseBlockNumber + BigInt(invalidateAt.invalidateFromIndex);
|
|
20
24
|
messages.push({
|
|
21
25
|
_tag: "invalidate",
|
|
22
26
|
invalidate: {
|
|
23
27
|
cursor: {
|
|
24
|
-
orderKey:
|
|
28
|
+
orderKey: invalidateToBlock,
|
|
29
|
+
uniqueKey: options?.uniqueKey ? uniqueKeyFromOrderKey(invalidateToBlock) : void 0
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
});
|
|
28
33
|
} else if (finalizeAt && i === finalizeAt.finalizeTriggerIndex) {
|
|
34
|
+
const fianlizedToBlock = baseBlockNumber + BigInt(finalizeAt.finalizeToIndex);
|
|
29
35
|
messages.push({
|
|
30
36
|
_tag: "finalize",
|
|
31
37
|
finalize: {
|
|
32
38
|
cursor: {
|
|
33
|
-
orderKey:
|
|
39
|
+
orderKey: fianlizedToBlock,
|
|
40
|
+
uniqueKey: options?.uniqueKey ? uniqueKeyFromOrderKey(fianlizedToBlock) : void 0
|
|
34
41
|
}
|
|
35
42
|
}
|
|
36
43
|
});
|
|
@@ -38,10 +45,13 @@ function generateMockMessages(count = 10, options) {
|
|
|
38
45
|
messages.push({
|
|
39
46
|
_tag: "data",
|
|
40
47
|
data: {
|
|
41
|
-
cursor: { orderKey:
|
|
48
|
+
cursor: { orderKey: currentBlockNumber - 1n },
|
|
42
49
|
finality: "accepted",
|
|
43
|
-
data: [{ data: `${
|
|
44
|
-
endCursor: {
|
|
50
|
+
data: [{ data: `${baseBlockNumber + BigInt(i)}` }],
|
|
51
|
+
endCursor: {
|
|
52
|
+
orderKey: currentBlockNumber,
|
|
53
|
+
uniqueKey: options?.uniqueKey ? uniqueKey : void 0
|
|
54
|
+
},
|
|
45
55
|
production: "backfill"
|
|
46
56
|
}
|
|
47
57
|
});
|
|
@@ -49,6 +59,9 @@ function generateMockMessages(count = 10, options) {
|
|
|
49
59
|
}
|
|
50
60
|
return messages;
|
|
51
61
|
}
|
|
62
|
+
function uniqueKeyFromOrderKey(orderKey) {
|
|
63
|
+
return `0xff00${orderKey.toString()}`;
|
|
64
|
+
}
|
|
52
65
|
function getMockIndexer(params) {
|
|
53
66
|
const { internalContext: contextParams, override } = params ?? {};
|
|
54
67
|
const { plugins, ...rest } = override ?? {};
|
|
@@ -60,6 +73,7 @@ function getMockIndexer(params) {
|
|
|
60
73
|
async transform() {
|
|
61
74
|
},
|
|
62
75
|
plugins: [
|
|
76
|
+
logger(),
|
|
63
77
|
internalContext(
|
|
64
78
|
contextParams ?? {
|
|
65
79
|
availableIndexers: ["testing"],
|
package/dist/plugins/index.cjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const config = require('../shared/indexer.
|
|
4
|
-
const logger = require('../shared/indexer.
|
|
3
|
+
const config = require('../shared/indexer.479ae593.cjs');
|
|
4
|
+
const logger = require('../shared/indexer.a09fa402.cjs');
|
|
5
5
|
const protocol = require('@apibara/protocol');
|
|
6
|
-
require('consola');
|
|
7
|
-
require('../shared/indexer.077335f3.cjs');
|
|
8
6
|
require('node:async_hooks');
|
|
9
7
|
require('unctx');
|
|
8
|
+
require('consola');
|
|
10
9
|
|
|
11
10
|
function inMemoryPersistence() {
|
|
12
11
|
return config.defineIndexerPlugin((indexer) => {
|
package/dist/plugins/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as IndexerPlugin } from '../shared/indexer.
|
|
2
|
-
export { d as defineIndexerPlugin } from '../shared/indexer.
|
|
1
|
+
import { b as IndexerPlugin } from '../shared/indexer.7668fe34.cjs';
|
|
2
|
+
export { d as defineIndexerPlugin } from '../shared/indexer.7668fe34.cjs';
|
|
3
3
|
import { ConsolaReporter, ConsolaInstance } from 'consola';
|
|
4
4
|
export { ConsolaInstance, ConsolaReporter } from 'consola';
|
|
5
5
|
import '@apibara/protocol';
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as IndexerPlugin } from '../shared/indexer.
|
|
2
|
-
export { d as defineIndexerPlugin } from '../shared/indexer.
|
|
1
|
+
import { b as IndexerPlugin } from '../shared/indexer.7668fe34.mjs';
|
|
2
|
+
export { d as defineIndexerPlugin } from '../shared/indexer.7668fe34.mjs';
|
|
3
3
|
import { ConsolaReporter, ConsolaInstance } from 'consola';
|
|
4
4
|
export { ConsolaInstance, ConsolaReporter } from 'consola';
|
|
5
5
|
import '@apibara/protocol';
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as IndexerPlugin } from '../shared/indexer.
|
|
2
|
-
export { d as defineIndexerPlugin } from '../shared/indexer.
|
|
1
|
+
import { b as IndexerPlugin } from '../shared/indexer.7668fe34.js';
|
|
2
|
+
export { d as defineIndexerPlugin } from '../shared/indexer.7668fe34.js';
|
|
3
3
|
import { ConsolaReporter, ConsolaInstance } from 'consola';
|
|
4
4
|
export { ConsolaInstance, ConsolaReporter } from 'consola';
|
|
5
5
|
import '@apibara/protocol';
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { d as defineIndexerPlugin } from '../shared/indexer.
|
|
2
|
-
export { l as logger, u as useLogger } from '../shared/indexer.
|
|
1
|
+
import { d as defineIndexerPlugin } from '../shared/indexer.75773ef1.mjs';
|
|
2
|
+
export { l as logger, u as useLogger } from '../shared/indexer.98a921a7.mjs';
|
|
3
3
|
import { isCursor } from '@apibara/protocol';
|
|
4
|
-
import 'consola';
|
|
5
|
-
import '../shared/indexer.a55ad619.mjs';
|
|
6
4
|
import 'node:async_hooks';
|
|
7
5
|
import 'unctx';
|
|
6
|
+
import 'consola';
|
|
8
7
|
|
|
9
8
|
function inMemoryPersistence() {
|
|
10
9
|
return defineIndexerPlugin((indexer) => {
|
|
@@ -11,5 +11,10 @@ function useIndexerContext() {
|
|
|
11
11
|
return indexerAsyncContext.use();
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
function defineIndexerPlugin(def) {
|
|
15
|
+
return def;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.defineIndexerPlugin = defineIndexerPlugin;
|
|
14
19
|
exports.indexerAsyncContext = indexerAsyncContext;
|
|
15
20
|
exports.useIndexerContext = useIndexerContext;
|
|
@@ -9,4 +9,8 @@ function useIndexerContext() {
|
|
|
9
9
|
return indexerAsyncContext.use();
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
function defineIndexerPlugin(def) {
|
|
13
|
+
return def;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { defineIndexerPlugin as d, indexerAsyncContext as i, useIndexerContext as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StreamDataRequest, StreamDataOptions, Cursor, StreamDataResponse, Invalidate, Finalize,
|
|
1
|
+
import { StreamDataRequest, StreamDataOptions, Cursor, StreamDataResponse, Invalidate, Finalize, SystemMessage, DataFinality, StreamConfig, Client } from '@apibara/protocol';
|
|
2
2
|
import { NestedHooks, Hookable } from 'hookable';
|
|
3
3
|
|
|
4
4
|
interface IndexerContext extends Record<string, any> {
|
|
@@ -38,9 +38,7 @@ interface IndexerHooks<TFilter, TBlock> {
|
|
|
38
38
|
"message:finalize": ({ message }: {
|
|
39
39
|
message: Finalize;
|
|
40
40
|
}) => void;
|
|
41
|
-
"message:heartbeat": (
|
|
42
|
-
message: Heartbeat;
|
|
43
|
-
}) => void;
|
|
41
|
+
"message:heartbeat": () => void;
|
|
44
42
|
"message:systemMessage": ({ message }: {
|
|
45
43
|
message: SystemMessage;
|
|
46
44
|
}) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StreamDataRequest, StreamDataOptions, Cursor, StreamDataResponse, Invalidate, Finalize,
|
|
1
|
+
import { StreamDataRequest, StreamDataOptions, Cursor, StreamDataResponse, Invalidate, Finalize, SystemMessage, DataFinality, StreamConfig, Client } from '@apibara/protocol';
|
|
2
2
|
import { NestedHooks, Hookable } from 'hookable';
|
|
3
3
|
|
|
4
4
|
interface IndexerContext extends Record<string, any> {
|
|
@@ -38,9 +38,7 @@ interface IndexerHooks<TFilter, TBlock> {
|
|
|
38
38
|
"message:finalize": ({ message }: {
|
|
39
39
|
message: Finalize;
|
|
40
40
|
}) => void;
|
|
41
|
-
"message:heartbeat": (
|
|
42
|
-
message: Heartbeat;
|
|
43
|
-
}) => void;
|
|
41
|
+
"message:heartbeat": () => void;
|
|
44
42
|
"message:systemMessage": ({ message }: {
|
|
45
43
|
message: SystemMessage;
|
|
46
44
|
}) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StreamDataRequest, StreamDataOptions, Cursor, StreamDataResponse, Invalidate, Finalize,
|
|
1
|
+
import { StreamDataRequest, StreamDataOptions, Cursor, StreamDataResponse, Invalidate, Finalize, SystemMessage, DataFinality, StreamConfig, Client } from '@apibara/protocol';
|
|
2
2
|
import { NestedHooks, Hookable } from 'hookable';
|
|
3
3
|
|
|
4
4
|
interface IndexerContext extends Record<string, any> {
|
|
@@ -38,9 +38,7 @@ interface IndexerHooks<TFilter, TBlock> {
|
|
|
38
38
|
"message:finalize": ({ message }: {
|
|
39
39
|
message: Finalize;
|
|
40
40
|
}) => void;
|
|
41
|
-
"message:heartbeat": (
|
|
42
|
-
message: Heartbeat;
|
|
43
|
-
}) => void;
|
|
41
|
+
"message:heartbeat": () => void;
|
|
44
42
|
"message:systemMessage": ({ message }: {
|
|
45
43
|
message: SystemMessage;
|
|
46
44
|
}) => void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { consola } from 'consola';
|
|
2
|
-
import { u as useIndexerContext } from './indexer.
|
|
3
|
-
import { d as defineIndexerPlugin } from './indexer.9b21ddd2.mjs';
|
|
2
|
+
import { d as defineIndexerPlugin, u as useIndexerContext } from './indexer.75773ef1.mjs';
|
|
4
3
|
|
|
5
4
|
function logger({
|
|
6
5
|
logger: logger2
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const consola = require('consola');
|
|
4
|
-
const
|
|
5
|
-
const config = require('./indexer.601ceab0.cjs');
|
|
4
|
+
const config = require('./indexer.479ae593.cjs');
|
|
6
5
|
|
|
7
6
|
function logger({
|
|
8
7
|
logger: logger2
|
|
9
8
|
} = {}) {
|
|
10
9
|
return config.defineIndexerPlugin((indexer) => {
|
|
11
10
|
indexer.hooks.hook("run:before", () => {
|
|
12
|
-
const ctx =
|
|
11
|
+
const ctx = config.useIndexerContext();
|
|
13
12
|
if (logger2) {
|
|
14
13
|
ctx.logger = consola.consola.create({ reporters: [logger2] });
|
|
15
14
|
} else {
|
|
@@ -19,7 +18,7 @@ function logger({
|
|
|
19
18
|
});
|
|
20
19
|
}
|
|
21
20
|
function useLogger() {
|
|
22
|
-
const ctx =
|
|
21
|
+
const ctx = config.useIndexerContext();
|
|
23
22
|
if (!ctx?.logger)
|
|
24
23
|
throw new Error("Logger plugin is not available in context");
|
|
25
24
|
return ctx.logger;
|
package/dist/testing/index.cjs
CHANGED
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
const protocol = require('@apibara/protocol');
|
|
4
4
|
const ci = require('ci-info');
|
|
5
|
+
const config = require('../shared/indexer.479ae593.cjs');
|
|
5
6
|
const index = require('../index.cjs');
|
|
6
7
|
const internal_plugins = require('../internal/plugins.cjs');
|
|
7
|
-
const logger = require('../shared/indexer.
|
|
8
|
+
const logger = require('../shared/indexer.a09fa402.cjs');
|
|
8
9
|
const vcr_index = require('../vcr/index.cjs');
|
|
10
|
+
require('node:async_hooks');
|
|
11
|
+
require('unctx');
|
|
9
12
|
require('consola');
|
|
10
13
|
require('hookable');
|
|
11
14
|
require('node:assert');
|
|
12
|
-
require('../shared/indexer.077335f3.cjs');
|
|
13
|
-
require('node:async_hooks');
|
|
14
|
-
require('unctx');
|
|
15
15
|
require('@opentelemetry/api');
|
|
16
|
-
require('../shared/indexer.601ceab0.cjs');
|
|
17
16
|
require('node:fs/promises');
|
|
18
17
|
require('node:path');
|
|
19
18
|
require('node:fs');
|
|
@@ -24,6 +23,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
|
|
|
24
23
|
const ci__default = /*#__PURE__*/_interopDefaultCompat(ci);
|
|
25
24
|
|
|
26
25
|
function createVcr() {
|
|
26
|
+
let result;
|
|
27
27
|
return {
|
|
28
28
|
async run(cassetteName, indexerConfig, range) {
|
|
29
29
|
const vcrConfig = {
|
|
@@ -47,6 +47,9 @@ function createVcr() {
|
|
|
47
47
|
...indexerConfig.plugins ?? []
|
|
48
48
|
];
|
|
49
49
|
const indexer = index.createIndexer(indexerConfig);
|
|
50
|
+
indexer.hooks.hook("run:after", () => {
|
|
51
|
+
result = config.useIndexerContext();
|
|
52
|
+
});
|
|
50
53
|
if (!vcr_index.isCassetteAvailable(vcrConfig, cassetteName)) {
|
|
51
54
|
if (ci__default.isCI) {
|
|
52
55
|
throw new Error("Cannot record cassette in CI");
|
|
@@ -59,6 +62,7 @@ function createVcr() {
|
|
|
59
62
|
} else {
|
|
60
63
|
await vcr_index.replay(vcrConfig, indexer, cassetteName);
|
|
61
64
|
}
|
|
65
|
+
return result;
|
|
62
66
|
}
|
|
63
67
|
};
|
|
64
68
|
}
|
package/dist/testing/index.d.cts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { I as IndexerWithStreamConfig } from '../shared/indexer.
|
|
1
|
+
import { I as IndexerWithStreamConfig } from '../shared/indexer.7668fe34.cjs';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
|
4
4
|
|
|
5
|
+
type VcrResult = Record<string, unknown>;
|
|
5
6
|
declare function createVcr(): {
|
|
6
7
|
run<TFilter, TBlock>(cassetteName: string, indexerConfig: IndexerWithStreamConfig<TFilter, TBlock>, range: {
|
|
7
8
|
fromBlock: bigint;
|
|
8
9
|
toBlock: bigint;
|
|
9
|
-
}): Promise<
|
|
10
|
+
}): Promise<VcrResult>;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
export { createVcr };
|
|
13
|
+
export { type VcrResult, createVcr };
|
package/dist/testing/index.d.mts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { I as IndexerWithStreamConfig } from '../shared/indexer.
|
|
1
|
+
import { I as IndexerWithStreamConfig } from '../shared/indexer.7668fe34.mjs';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
|
4
4
|
|
|
5
|
+
type VcrResult = Record<string, unknown>;
|
|
5
6
|
declare function createVcr(): {
|
|
6
7
|
run<TFilter, TBlock>(cassetteName: string, indexerConfig: IndexerWithStreamConfig<TFilter, TBlock>, range: {
|
|
7
8
|
fromBlock: bigint;
|
|
8
9
|
toBlock: bigint;
|
|
9
|
-
}): Promise<
|
|
10
|
+
}): Promise<VcrResult>;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
export { createVcr };
|
|
13
|
+
export { type VcrResult, createVcr };
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { I as IndexerWithStreamConfig } from '../shared/indexer.
|
|
1
|
+
import { I as IndexerWithStreamConfig } from '../shared/indexer.7668fe34.js';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
|
4
4
|
|
|
5
|
+
type VcrResult = Record<string, unknown>;
|
|
5
6
|
declare function createVcr(): {
|
|
6
7
|
run<TFilter, TBlock>(cassetteName: string, indexerConfig: IndexerWithStreamConfig<TFilter, TBlock>, range: {
|
|
7
8
|
fromBlock: bigint;
|
|
8
9
|
toBlock: bigint;
|
|
9
|
-
}): Promise<
|
|
10
|
+
}): Promise<VcrResult>;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
export { createVcr };
|
|
13
|
+
export { type VcrResult, createVcr };
|
package/dist/testing/index.mjs
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { createClient } from '@apibara/protocol';
|
|
2
2
|
import ci from 'ci-info';
|
|
3
|
+
import { u as useIndexerContext } from '../shared/indexer.75773ef1.mjs';
|
|
3
4
|
import { createIndexer } from '../index.mjs';
|
|
4
5
|
import { internalContext } from '../internal/plugins.mjs';
|
|
5
|
-
import { l as logger } from '../shared/indexer.
|
|
6
|
+
import { l as logger } from '../shared/indexer.98a921a7.mjs';
|
|
6
7
|
import { isCassetteAvailable, record, replay } from '../vcr/index.mjs';
|
|
8
|
+
import 'node:async_hooks';
|
|
9
|
+
import 'unctx';
|
|
7
10
|
import 'consola';
|
|
8
11
|
import 'hookable';
|
|
9
12
|
import 'node:assert';
|
|
10
|
-
import '../shared/indexer.a55ad619.mjs';
|
|
11
|
-
import 'node:async_hooks';
|
|
12
|
-
import 'unctx';
|
|
13
13
|
import '@opentelemetry/api';
|
|
14
|
-
import '../shared/indexer.9b21ddd2.mjs';
|
|
15
14
|
import 'node:fs/promises';
|
|
16
15
|
import 'node:path';
|
|
17
16
|
import 'node:fs';
|
|
18
17
|
import '@apibara/protocol/testing';
|
|
19
18
|
|
|
20
19
|
function createVcr() {
|
|
20
|
+
let result;
|
|
21
21
|
return {
|
|
22
22
|
async run(cassetteName, indexerConfig, range) {
|
|
23
23
|
const vcrConfig = {
|
|
@@ -41,6 +41,9 @@ function createVcr() {
|
|
|
41
41
|
...indexerConfig.plugins ?? []
|
|
42
42
|
];
|
|
43
43
|
const indexer = createIndexer(indexerConfig);
|
|
44
|
+
indexer.hooks.hook("run:after", () => {
|
|
45
|
+
result = useIndexerContext();
|
|
46
|
+
});
|
|
44
47
|
if (!isCassetteAvailable(vcrConfig, cassetteName)) {
|
|
45
48
|
if (ci.isCI) {
|
|
46
49
|
throw new Error("Cannot record cassette in CI");
|
|
@@ -53,6 +56,7 @@ function createVcr() {
|
|
|
53
56
|
} else {
|
|
54
57
|
await replay(vcrConfig, indexer, cassetteName);
|
|
55
58
|
}
|
|
59
|
+
return result;
|
|
56
60
|
}
|
|
57
61
|
};
|
|
58
62
|
}
|
package/dist/vcr/index.cjs
CHANGED
|
@@ -9,10 +9,11 @@ const testing = require('@apibara/protocol/testing');
|
|
|
9
9
|
require('@apibara/protocol');
|
|
10
10
|
require('consola');
|
|
11
11
|
require('hookable');
|
|
12
|
-
require('../shared/indexer.
|
|
12
|
+
require('../shared/indexer.479ae593.cjs');
|
|
13
13
|
require('node:async_hooks');
|
|
14
14
|
require('unctx');
|
|
15
15
|
require('@opentelemetry/api');
|
|
16
|
+
require('../internal/plugins.cjs');
|
|
16
17
|
|
|
17
18
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
18
19
|
|
package/dist/vcr/index.d.cts
CHANGED
package/dist/vcr/index.d.mts
CHANGED
package/dist/vcr/index.d.ts
CHANGED
package/dist/vcr/index.mjs
CHANGED
|
@@ -7,10 +7,11 @@ import { MockClient } from '@apibara/protocol/testing';
|
|
|
7
7
|
import '@apibara/protocol';
|
|
8
8
|
import 'consola';
|
|
9
9
|
import 'hookable';
|
|
10
|
-
import '../shared/indexer.
|
|
10
|
+
import '../shared/indexer.75773ef1.mjs';
|
|
11
11
|
import 'node:async_hooks';
|
|
12
12
|
import 'unctx';
|
|
13
13
|
import '@opentelemetry/api';
|
|
14
|
+
import '../internal/plugins.mjs';
|
|
14
15
|
|
|
15
16
|
function deserialize(str) {
|
|
16
17
|
return JSON.parse(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apibara/indexer",
|
|
3
|
-
"version": "2.1.0-beta.
|
|
3
|
+
"version": "2.1.0-beta.30",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -70,10 +70,10 @@
|
|
|
70
70
|
"vitest": "^1.6.0"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@apibara/protocol": "2.1.0-beta.
|
|
73
|
+
"@apibara/protocol": "2.1.0-beta.30",
|
|
74
74
|
"@opentelemetry/api": "^1.9.0",
|
|
75
75
|
"ci-info": "^4.1.0",
|
|
76
|
-
"consola": "^3.2
|
|
76
|
+
"consola": "^3.4.2",
|
|
77
77
|
"hookable": "^5.5.3",
|
|
78
78
|
"klona": "^2.0.6",
|
|
79
79
|
"nice-grpc": "^2.1.8",
|
package/src/indexer.ts
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
type Cursor,
|
|
5
5
|
type DataFinality,
|
|
6
6
|
type Finalize,
|
|
7
|
-
type Heartbeat,
|
|
8
7
|
type Invalidate,
|
|
8
|
+
ServerError,
|
|
9
9
|
Status,
|
|
10
10
|
type StreamConfig,
|
|
11
11
|
type StreamDataOptions,
|
|
@@ -28,8 +28,9 @@ import {
|
|
|
28
28
|
indexerAsyncContext,
|
|
29
29
|
useIndexerContext,
|
|
30
30
|
} from "./context";
|
|
31
|
-
import {
|
|
31
|
+
import { createIndexerMetrics, createTracer } from "./otel";
|
|
32
32
|
import type { IndexerPlugin } from "./plugins";
|
|
33
|
+
import { useInternalContext } from "./plugins/context";
|
|
33
34
|
|
|
34
35
|
export type UseMiddlewareFunction = (
|
|
35
36
|
fn: MiddlewareFunction<IndexerContext>,
|
|
@@ -59,7 +60,7 @@ export interface IndexerHooks<TFilter, TBlock> {
|
|
|
59
60
|
message: ({ message }: { message: StreamDataResponse<TBlock> }) => void;
|
|
60
61
|
"message:invalidate": ({ message }: { message: Invalidate }) => void;
|
|
61
62
|
"message:finalize": ({ message }: { message: Finalize }) => void;
|
|
62
|
-
"message:heartbeat": (
|
|
63
|
+
"message:heartbeat": () => void;
|
|
63
64
|
"message:systemMessage": ({ message }: { message: SystemMessage }) => void;
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -179,13 +180,18 @@ export async function runWithReconnect<TFilter, TBlock>(
|
|
|
179
180
|
|
|
180
181
|
retryCount++;
|
|
181
182
|
|
|
182
|
-
if (error instanceof ClientError) {
|
|
183
|
+
if (error instanceof ClientError || error instanceof ServerError) {
|
|
184
|
+
const isServerError = error instanceof ServerError;
|
|
185
|
+
|
|
183
186
|
if (error.code === Status.INTERNAL) {
|
|
184
187
|
if (retryCount < maxRetries) {
|
|
185
188
|
consola.error(
|
|
186
|
-
|
|
187
|
-
|
|
189
|
+
`Internal ${isServerError ? "server" : "client"} error: ${
|
|
190
|
+
error.message
|
|
191
|
+
}`,
|
|
188
192
|
);
|
|
193
|
+
consola.start("Reconnecting...");
|
|
194
|
+
console.log();
|
|
189
195
|
|
|
190
196
|
// Add jitter to the retry delay to avoid all clients retrying at the same time.
|
|
191
197
|
const delay = Math.random() * (retryDelay * 0.2) + retryDelay;
|
|
@@ -216,8 +222,13 @@ export async function run<TFilter, TBlock>(
|
|
|
216
222
|
const context = useIndexerContext();
|
|
217
223
|
const middleware = await registerMiddleware(indexer);
|
|
218
224
|
|
|
225
|
+
const indexerMetrics = createIndexerMetrics();
|
|
226
|
+
const tracer = createTracer();
|
|
227
|
+
|
|
219
228
|
await indexer.hooks.callHook("run:before");
|
|
220
229
|
|
|
230
|
+
const { indexerName: indexerId } = useInternalContext();
|
|
231
|
+
|
|
221
232
|
const isFactoryMode = indexer.options.factory !== undefined;
|
|
222
233
|
|
|
223
234
|
// Give priority to startingCursor over startingBlock.
|
|
@@ -235,13 +246,13 @@ export async function run<TFilter, TBlock>(
|
|
|
235
246
|
}
|
|
236
247
|
|
|
237
248
|
// if factory mode we add a empty filter at the end of the filter array.
|
|
238
|
-
const request =
|
|
249
|
+
const request = {
|
|
239
250
|
filter: isFactoryMode
|
|
240
251
|
? [indexer.options.filter, {} as TFilter]
|
|
241
252
|
: [indexer.options.filter],
|
|
242
253
|
finality: indexer.options.finality,
|
|
243
254
|
startingCursor,
|
|
244
|
-
}
|
|
255
|
+
} as StreamDataRequest<TFilter>;
|
|
245
256
|
|
|
246
257
|
const options: StreamDataOptions = {};
|
|
247
258
|
|
|
@@ -288,11 +299,19 @@ export async function run<TFilter, TBlock>(
|
|
|
288
299
|
context.endCursor = endCursor;
|
|
289
300
|
context.finality = finality;
|
|
290
301
|
|
|
302
|
+
// Record current block number being processed
|
|
303
|
+
indexerMetrics.currentBlockGauge.record(
|
|
304
|
+
Number(endCursor?.orderKey),
|
|
305
|
+
{
|
|
306
|
+
indexer_id: indexerId,
|
|
307
|
+
},
|
|
308
|
+
);
|
|
309
|
+
|
|
291
310
|
await middleware(context, async () => {
|
|
292
311
|
let block: TBlock | null;
|
|
293
312
|
|
|
294
313
|
// when factory mode
|
|
295
|
-
if (isFactoryMode) {
|
|
314
|
+
if (isFactoryMode && finality !== "pending") {
|
|
296
315
|
assert(indexer.options.factory !== undefined);
|
|
297
316
|
|
|
298
317
|
const [factoryBlock, mainBlock] = blocks;
|
|
@@ -315,11 +334,11 @@ export async function run<TFilter, TBlock>(
|
|
|
315
334
|
);
|
|
316
335
|
|
|
317
336
|
// create request with new filters
|
|
318
|
-
const request =
|
|
337
|
+
const request = {
|
|
319
338
|
filter: [indexer.options.filter, mainFilter],
|
|
320
339
|
finality: indexer.options.finality,
|
|
321
340
|
startingCursor: cursor,
|
|
322
|
-
}
|
|
341
|
+
} as StreamDataRequest<TFilter>;
|
|
323
342
|
|
|
324
343
|
await indexer.hooks.callHook("connect:factory", {
|
|
325
344
|
request,
|
|
@@ -364,6 +383,11 @@ export async function run<TFilter, TBlock>(
|
|
|
364
383
|
span.end();
|
|
365
384
|
});
|
|
366
385
|
|
|
386
|
+
// Record processed block metric
|
|
387
|
+
indexerMetrics.processedBlockCounter.add(1, {
|
|
388
|
+
indexer_id: indexerId,
|
|
389
|
+
});
|
|
390
|
+
|
|
367
391
|
context.cursor = undefined;
|
|
368
392
|
context.endCursor = undefined;
|
|
369
393
|
context.finality = undefined;
|
|
@@ -372,21 +396,29 @@ export async function run<TFilter, TBlock>(
|
|
|
372
396
|
}
|
|
373
397
|
case "invalidate": {
|
|
374
398
|
await tracer.startActiveSpan("message invalidate", async (span) => {
|
|
375
|
-
|
|
399
|
+
// Record reorg metric
|
|
400
|
+
indexerMetrics.reorgCounter.add(1, {
|
|
401
|
+
indexer_id: indexerId,
|
|
402
|
+
});
|
|
403
|
+
await indexer.hooks.callHook("message:invalidate", {
|
|
404
|
+
message: message.invalidate,
|
|
405
|
+
});
|
|
376
406
|
span.end();
|
|
377
407
|
});
|
|
378
408
|
break;
|
|
379
409
|
}
|
|
380
410
|
case "finalize": {
|
|
381
411
|
await tracer.startActiveSpan("message finalize", async (span) => {
|
|
382
|
-
await indexer.hooks.callHook("message:finalize", {
|
|
412
|
+
await indexer.hooks.callHook("message:finalize", {
|
|
413
|
+
message: message.finalize,
|
|
414
|
+
});
|
|
383
415
|
span.end();
|
|
384
416
|
});
|
|
385
417
|
break;
|
|
386
418
|
}
|
|
387
419
|
case "heartbeat": {
|
|
388
420
|
await tracer.startActiveSpan("message heartbeat", async (span) => {
|
|
389
|
-
await indexer.hooks.callHook("message:heartbeat"
|
|
421
|
+
await indexer.hooks.callHook("message:heartbeat");
|
|
390
422
|
span.end();
|
|
391
423
|
});
|
|
392
424
|
break;
|
|
@@ -409,7 +441,7 @@ export async function run<TFilter, TBlock>(
|
|
|
409
441
|
}
|
|
410
442
|
|
|
411
443
|
await indexer.hooks.callHook("message:systemMessage", {
|
|
412
|
-
message,
|
|
444
|
+
message: message.systemMessage,
|
|
413
445
|
});
|
|
414
446
|
span.end();
|
|
415
447
|
},
|