@apibara/indexer 2.1.0-beta.23 → 2.1.0-beta.25
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 +12 -8
- 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 +12 -8
- 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/testing.d.cts +3 -3
- package/dist/internal/testing.d.mts +3 -3
- package/dist/internal/testing.d.ts +3 -3
- 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/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/testing/index.d.cts +1 -1
- package/dist/testing/index.d.mts +1 -1
- package/dist/testing/index.d.ts +1 -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/package.json +2 -2
- package/src/indexer.ts +13 -10
- package/src/internal/testing.ts +4 -4
- package/src/compose.test.ts +0 -76
- package/src/indexer.test.ts +0 -430
package/dist/index.cjs
CHANGED
|
@@ -148,11 +148,11 @@ async function run(client, indexer, runOptions = {}) {
|
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
|
-
const request =
|
|
151
|
+
const request = {
|
|
152
152
|
filter: isFactoryMode ? [indexer.options.filter, {}] : [indexer.options.filter],
|
|
153
153
|
finality: indexer.options.finality,
|
|
154
154
|
startingCursor
|
|
155
|
-
}
|
|
155
|
+
};
|
|
156
156
|
const options = {};
|
|
157
157
|
await indexer.hooks.callHook("connect:before", { request, options });
|
|
158
158
|
let mainFilter;
|
|
@@ -204,11 +204,11 @@ async function run(client, indexer, runOptions = {}) {
|
|
|
204
204
|
mainFilter,
|
|
205
205
|
filter
|
|
206
206
|
);
|
|
207
|
-
const request2 =
|
|
207
|
+
const request2 = {
|
|
208
208
|
filter: [indexer.options.filter, mainFilter],
|
|
209
209
|
finality: indexer.options.finality,
|
|
210
210
|
startingCursor: cursor
|
|
211
|
-
}
|
|
211
|
+
};
|
|
212
212
|
await indexer.hooks.callHook("connect:factory", {
|
|
213
213
|
request: request2,
|
|
214
214
|
endCursor
|
|
@@ -251,21 +251,25 @@ async function run(client, indexer, runOptions = {}) {
|
|
|
251
251
|
indexerMetrics.reorgCounter.add(1, {
|
|
252
252
|
indexer_id: indexerId
|
|
253
253
|
});
|
|
254
|
-
await indexer.hooks.callHook("message:invalidate", {
|
|
254
|
+
await indexer.hooks.callHook("message:invalidate", {
|
|
255
|
+
message: message.invalidate
|
|
256
|
+
});
|
|
255
257
|
span.end();
|
|
256
258
|
});
|
|
257
259
|
break;
|
|
258
260
|
}
|
|
259
261
|
case "finalize": {
|
|
260
262
|
await tracer.startActiveSpan("message finalize", async (span) => {
|
|
261
|
-
await indexer.hooks.callHook("message:finalize", {
|
|
263
|
+
await indexer.hooks.callHook("message:finalize", {
|
|
264
|
+
message: message.finalize
|
|
265
|
+
});
|
|
262
266
|
span.end();
|
|
263
267
|
});
|
|
264
268
|
break;
|
|
265
269
|
}
|
|
266
270
|
case "heartbeat": {
|
|
267
271
|
await tracer.startActiveSpan("message heartbeat", async (span) => {
|
|
268
|
-
await indexer.hooks.callHook("message:heartbeat"
|
|
272
|
+
await indexer.hooks.callHook("message:heartbeat");
|
|
269
273
|
span.end();
|
|
270
274
|
});
|
|
271
275
|
break;
|
|
@@ -285,7 +289,7 @@ async function run(client, indexer, runOptions = {}) {
|
|
|
285
289
|
}
|
|
286
290
|
}
|
|
287
291
|
await indexer.hooks.callHook("message:systemMessage", {
|
|
288
|
-
message
|
|
292
|
+
message: message.systemMessage
|
|
289
293
|
});
|
|
290
294
|
span.end();
|
|
291
295
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a as Indexer, c as IndexerConfig, e as IndexerHooks, f as IndexerStartingCursor, I as IndexerWithStreamConfig, R as ReconnectOptions, i as RunOptions, U as UseMiddlewareFunction, h as createIndexer, g as defineIndexer, j as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.
|
|
1
|
+
export { a as Indexer, c as IndexerConfig, e as IndexerHooks, f as IndexerStartingCursor, I as IndexerWithStreamConfig, R as ReconnectOptions, i as RunOptions, U as UseMiddlewareFunction, h as createIndexer, g as defineIndexer, j as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.7668fe34.cjs';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a as Indexer, c as IndexerConfig, e as IndexerHooks, f as IndexerStartingCursor, I as IndexerWithStreamConfig, R as ReconnectOptions, i as RunOptions, U as UseMiddlewareFunction, h as createIndexer, g as defineIndexer, j as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.
|
|
1
|
+
export { a as Indexer, c as IndexerConfig, e as IndexerHooks, f as IndexerStartingCursor, I as IndexerWithStreamConfig, R as ReconnectOptions, i as RunOptions, U as UseMiddlewareFunction, h as createIndexer, g as defineIndexer, j as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.7668fe34.mjs';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a as Indexer, c as IndexerConfig, e as IndexerHooks, f as IndexerStartingCursor, I as IndexerWithStreamConfig, R as ReconnectOptions, i as RunOptions, U as UseMiddlewareFunction, h as createIndexer, g as defineIndexer, j as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.
|
|
1
|
+
export { a as Indexer, c as IndexerConfig, e as IndexerHooks, f as IndexerStartingCursor, I as IndexerWithStreamConfig, R as ReconnectOptions, i as RunOptions, U as UseMiddlewareFunction, h as createIndexer, g as defineIndexer, j as run, r as runWithReconnect, u as useIndexerContext } from './shared/indexer.7668fe34.js';
|
|
2
2
|
import '@apibara/protocol';
|
|
3
3
|
import 'hookable';
|
package/dist/index.mjs
CHANGED
|
@@ -141,11 +141,11 @@ async function run(client, indexer, runOptions = {}) {
|
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
const request =
|
|
144
|
+
const request = {
|
|
145
145
|
filter: isFactoryMode ? [indexer.options.filter, {}] : [indexer.options.filter],
|
|
146
146
|
finality: indexer.options.finality,
|
|
147
147
|
startingCursor
|
|
148
|
-
}
|
|
148
|
+
};
|
|
149
149
|
const options = {};
|
|
150
150
|
await indexer.hooks.callHook("connect:before", { request, options });
|
|
151
151
|
let mainFilter;
|
|
@@ -197,11 +197,11 @@ async function run(client, indexer, runOptions = {}) {
|
|
|
197
197
|
mainFilter,
|
|
198
198
|
filter
|
|
199
199
|
);
|
|
200
|
-
const request2 =
|
|
200
|
+
const request2 = {
|
|
201
201
|
filter: [indexer.options.filter, mainFilter],
|
|
202
202
|
finality: indexer.options.finality,
|
|
203
203
|
startingCursor: cursor
|
|
204
|
-
}
|
|
204
|
+
};
|
|
205
205
|
await indexer.hooks.callHook("connect:factory", {
|
|
206
206
|
request: request2,
|
|
207
207
|
endCursor
|
|
@@ -244,21 +244,25 @@ async function run(client, indexer, runOptions = {}) {
|
|
|
244
244
|
indexerMetrics.reorgCounter.add(1, {
|
|
245
245
|
indexer_id: indexerId
|
|
246
246
|
});
|
|
247
|
-
await indexer.hooks.callHook("message:invalidate", {
|
|
247
|
+
await indexer.hooks.callHook("message:invalidate", {
|
|
248
|
+
message: message.invalidate
|
|
249
|
+
});
|
|
248
250
|
span.end();
|
|
249
251
|
});
|
|
250
252
|
break;
|
|
251
253
|
}
|
|
252
254
|
case "finalize": {
|
|
253
255
|
await tracer.startActiveSpan("message finalize", async (span) => {
|
|
254
|
-
await indexer.hooks.callHook("message:finalize", {
|
|
256
|
+
await indexer.hooks.callHook("message:finalize", {
|
|
257
|
+
message: message.finalize
|
|
258
|
+
});
|
|
255
259
|
span.end();
|
|
256
260
|
});
|
|
257
261
|
break;
|
|
258
262
|
}
|
|
259
263
|
case "heartbeat": {
|
|
260
264
|
await tracer.startActiveSpan("message heartbeat", async (span) => {
|
|
261
|
-
await indexer.hooks.callHook("message:heartbeat"
|
|
265
|
+
await indexer.hooks.callHook("message:heartbeat");
|
|
262
266
|
span.end();
|
|
263
267
|
});
|
|
264
268
|
break;
|
|
@@ -278,7 +282,7 @@ async function run(client, indexer, runOptions = {}) {
|
|
|
278
282
|
}
|
|
279
283
|
}
|
|
280
284
|
await indexer.hooks.callHook("message:systemMessage", {
|
|
281
|
-
message
|
|
285
|
+
message: message.systemMessage
|
|
282
286
|
});
|
|
283
287
|
span.end();
|
|
284
288
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Indexer, b as IndexerPlugin, c as IndexerConfig } from '../shared/indexer.
|
|
1
|
+
import { a as Indexer, b as IndexerPlugin, c as IndexerConfig } from '../shared/indexer.7668fe34.cjs';
|
|
2
2
|
import { MockStreamResponse, MockFilter, MockBlock } from '@apibara/protocol/testing';
|
|
3
3
|
import { InternalContext } from './plugins.cjs';
|
|
4
4
|
import '@apibara/protocol';
|
|
@@ -22,9 +22,9 @@ type MockIndexerParams = {
|
|
|
22
22
|
override?: Partial<IndexerConfig<MockFilter, MockBlock>>;
|
|
23
23
|
};
|
|
24
24
|
declare function getMockIndexer(params?: MockIndexerParams): Indexer<{
|
|
25
|
-
|
|
25
|
+
filter?: string | undefined;
|
|
26
26
|
}, {
|
|
27
|
-
|
|
27
|
+
data?: string | undefined;
|
|
28
28
|
}>;
|
|
29
29
|
type MockRet = {
|
|
30
30
|
data: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Indexer, b as IndexerPlugin, c as IndexerConfig } from '../shared/indexer.
|
|
1
|
+
import { a as Indexer, b as IndexerPlugin, c as IndexerConfig } from '../shared/indexer.7668fe34.mjs';
|
|
2
2
|
import { MockStreamResponse, MockFilter, MockBlock } from '@apibara/protocol/testing';
|
|
3
3
|
import { InternalContext } from './plugins.mjs';
|
|
4
4
|
import '@apibara/protocol';
|
|
@@ -22,9 +22,9 @@ type MockIndexerParams = {
|
|
|
22
22
|
override?: Partial<IndexerConfig<MockFilter, MockBlock>>;
|
|
23
23
|
};
|
|
24
24
|
declare function getMockIndexer(params?: MockIndexerParams): Indexer<{
|
|
25
|
-
|
|
25
|
+
filter?: string | undefined;
|
|
26
26
|
}, {
|
|
27
|
-
|
|
27
|
+
data?: string | undefined;
|
|
28
28
|
}>;
|
|
29
29
|
type MockRet = {
|
|
30
30
|
data: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Indexer, b as IndexerPlugin, c as IndexerConfig } from '../shared/indexer.
|
|
1
|
+
import { a as Indexer, b as IndexerPlugin, c as IndexerConfig } from '../shared/indexer.7668fe34.js';
|
|
2
2
|
import { MockStreamResponse, MockFilter, MockBlock } from '@apibara/protocol/testing';
|
|
3
3
|
import { InternalContext } from './plugins.js';
|
|
4
4
|
import '@apibara/protocol';
|
|
@@ -22,9 +22,9 @@ type MockIndexerParams = {
|
|
|
22
22
|
override?: Partial<IndexerConfig<MockFilter, MockBlock>>;
|
|
23
23
|
};
|
|
24
24
|
declare function getMockIndexer(params?: MockIndexerParams): Indexer<{
|
|
25
|
-
|
|
25
|
+
filter?: string | undefined;
|
|
26
26
|
}, {
|
|
27
|
-
|
|
27
|
+
data?: string | undefined;
|
|
28
28
|
}>;
|
|
29
29
|
type MockRet = {
|
|
30
30
|
data: string;
|
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';
|
|
@@ -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;
|
package/dist/testing/index.d.cts
CHANGED
package/dist/testing/index.d.mts
CHANGED
package/dist/testing/index.d.ts
CHANGED
package/dist/vcr/index.d.cts
CHANGED
package/dist/vcr/index.d.mts
CHANGED
package/dist/vcr/index.d.ts
CHANGED
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.25",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -70,7 +70,7 @@
|
|
|
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.25",
|
|
74
74
|
"@opentelemetry/api": "^1.9.0",
|
|
75
75
|
"ci-info": "^4.1.0",
|
|
76
76
|
"consola": "^3.4.2",
|
package/src/indexer.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
type Cursor,
|
|
5
5
|
type DataFinality,
|
|
6
6
|
type Finalize,
|
|
7
|
-
type Heartbeat,
|
|
8
7
|
type Invalidate,
|
|
9
8
|
Status,
|
|
10
9
|
type StreamConfig,
|
|
@@ -60,7 +59,7 @@ export interface IndexerHooks<TFilter, TBlock> {
|
|
|
60
59
|
message: ({ message }: { message: StreamDataResponse<TBlock> }) => void;
|
|
61
60
|
"message:invalidate": ({ message }: { message: Invalidate }) => void;
|
|
62
61
|
"message:finalize": ({ message }: { message: Finalize }) => void;
|
|
63
|
-
"message:heartbeat": (
|
|
62
|
+
"message:heartbeat": () => void;
|
|
64
63
|
"message:systemMessage": ({ message }: { message: SystemMessage }) => void;
|
|
65
64
|
}
|
|
66
65
|
|
|
@@ -241,13 +240,13 @@ export async function run<TFilter, TBlock>(
|
|
|
241
240
|
}
|
|
242
241
|
|
|
243
242
|
// if factory mode we add a empty filter at the end of the filter array.
|
|
244
|
-
const request =
|
|
243
|
+
const request = {
|
|
245
244
|
filter: isFactoryMode
|
|
246
245
|
? [indexer.options.filter, {} as TFilter]
|
|
247
246
|
: [indexer.options.filter],
|
|
248
247
|
finality: indexer.options.finality,
|
|
249
248
|
startingCursor,
|
|
250
|
-
}
|
|
249
|
+
} as StreamDataRequest<TFilter>;
|
|
251
250
|
|
|
252
251
|
const options: StreamDataOptions = {};
|
|
253
252
|
|
|
@@ -329,11 +328,11 @@ export async function run<TFilter, TBlock>(
|
|
|
329
328
|
);
|
|
330
329
|
|
|
331
330
|
// create request with new filters
|
|
332
|
-
const request =
|
|
331
|
+
const request = {
|
|
333
332
|
filter: [indexer.options.filter, mainFilter],
|
|
334
333
|
finality: indexer.options.finality,
|
|
335
334
|
startingCursor: cursor,
|
|
336
|
-
}
|
|
335
|
+
} as StreamDataRequest<TFilter>;
|
|
337
336
|
|
|
338
337
|
await indexer.hooks.callHook("connect:factory", {
|
|
339
338
|
request,
|
|
@@ -395,21 +394,25 @@ export async function run<TFilter, TBlock>(
|
|
|
395
394
|
indexerMetrics.reorgCounter.add(1, {
|
|
396
395
|
indexer_id: indexerId,
|
|
397
396
|
});
|
|
398
|
-
await indexer.hooks.callHook("message:invalidate", {
|
|
397
|
+
await indexer.hooks.callHook("message:invalidate", {
|
|
398
|
+
message: message.invalidate,
|
|
399
|
+
});
|
|
399
400
|
span.end();
|
|
400
401
|
});
|
|
401
402
|
break;
|
|
402
403
|
}
|
|
403
404
|
case "finalize": {
|
|
404
405
|
await tracer.startActiveSpan("message finalize", async (span) => {
|
|
405
|
-
await indexer.hooks.callHook("message:finalize", {
|
|
406
|
+
await indexer.hooks.callHook("message:finalize", {
|
|
407
|
+
message: message.finalize,
|
|
408
|
+
});
|
|
406
409
|
span.end();
|
|
407
410
|
});
|
|
408
411
|
break;
|
|
409
412
|
}
|
|
410
413
|
case "heartbeat": {
|
|
411
414
|
await tracer.startActiveSpan("message heartbeat", async (span) => {
|
|
412
|
-
await indexer.hooks.callHook("message:heartbeat"
|
|
415
|
+
await indexer.hooks.callHook("message:heartbeat");
|
|
413
416
|
span.end();
|
|
414
417
|
});
|
|
415
418
|
break;
|
|
@@ -432,7 +435,7 @@ export async function run<TFilter, TBlock>(
|
|
|
432
435
|
}
|
|
433
436
|
|
|
434
437
|
await indexer.hooks.callHook("message:systemMessage", {
|
|
435
|
-
message,
|
|
438
|
+
message: message.systemMessage,
|
|
436
439
|
});
|
|
437
440
|
span.end();
|
|
438
441
|
},
|
package/src/internal/testing.ts
CHANGED
|
@@ -48,8 +48,8 @@ export function generateMockMessages(
|
|
|
48
48
|
? uniqueKeyFromOrderKey(invalidateToBlock)
|
|
49
49
|
: undefined,
|
|
50
50
|
},
|
|
51
|
-
},
|
|
52
|
-
}
|
|
51
|
+
} as Invalidate,
|
|
52
|
+
});
|
|
53
53
|
} else if (finalizeAt && i === finalizeAt.finalizeTriggerIndex) {
|
|
54
54
|
const fianlizedToBlock =
|
|
55
55
|
baseBlockNumber + BigInt(finalizeAt.finalizeToIndex);
|
|
@@ -62,8 +62,8 @@ export function generateMockMessages(
|
|
|
62
62
|
? uniqueKeyFromOrderKey(fianlizedToBlock)
|
|
63
63
|
: undefined,
|
|
64
64
|
},
|
|
65
|
-
},
|
|
66
|
-
}
|
|
65
|
+
} as Finalize,
|
|
66
|
+
});
|
|
67
67
|
} else {
|
|
68
68
|
messages.push({
|
|
69
69
|
_tag: "data",
|
package/src/compose.test.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { type MiddlewareFunction, type NextFunction, compose } from "./compose";
|
|
3
|
-
|
|
4
|
-
type C = {
|
|
5
|
-
bag: Record<string, unknown>;
|
|
6
|
-
finalized: boolean;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
type MiddlewareTuple = MiddlewareFunction<C>;
|
|
10
|
-
|
|
11
|
-
describe("compose", () => {
|
|
12
|
-
async function a(context: C, next: NextFunction) {
|
|
13
|
-
context.bag.log = "log";
|
|
14
|
-
await next();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function b(context: C, next: NextFunction) {
|
|
18
|
-
await next();
|
|
19
|
-
context.bag.headers = "custom-header";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async function c(context: C, next: NextFunction) {
|
|
23
|
-
context.bag.xxx = "yyy";
|
|
24
|
-
await next();
|
|
25
|
-
context.bag.zzz = context.bag.xxx;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function handler(context: C, next: NextFunction) {
|
|
29
|
-
context.bag.log = `${context.bag.log} message`;
|
|
30
|
-
await next();
|
|
31
|
-
context.bag.message = "new response";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const middleware: MiddlewareTuple[] = [];
|
|
35
|
-
|
|
36
|
-
middleware.push(a);
|
|
37
|
-
middleware.push(b);
|
|
38
|
-
middleware.push(c);
|
|
39
|
-
middleware.push(handler);
|
|
40
|
-
|
|
41
|
-
it("composes", async () => {
|
|
42
|
-
const context: C = {
|
|
43
|
-
bag: {},
|
|
44
|
-
finalized: false,
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const composed = compose<C>(middleware);
|
|
48
|
-
await composed(context);
|
|
49
|
-
|
|
50
|
-
expect(context.bag.log).toBeDefined();
|
|
51
|
-
expect(context.bag.log).toBe("log message");
|
|
52
|
-
expect(context.bag.headers).toBe("custom-header");
|
|
53
|
-
expect(context.bag.xxx).toBe("yyy");
|
|
54
|
-
expect(context.bag.zzz).toBe("yyy");
|
|
55
|
-
expect(context.finalized).toBe(false);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("accepts a next function", async () => {
|
|
59
|
-
const context: C = {
|
|
60
|
-
bag: {},
|
|
61
|
-
finalized: false,
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const composed = compose<C>(middleware);
|
|
65
|
-
await composed(context, async () => {
|
|
66
|
-
context.finalized = true;
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
expect(context.bag.log).toBeDefined();
|
|
70
|
-
expect(context.bag.log).toBe("log message");
|
|
71
|
-
expect(context.bag.headers).toBe("custom-header");
|
|
72
|
-
expect(context.bag.xxx).toBe("yyy");
|
|
73
|
-
expect(context.bag.zzz).toBe("yyy");
|
|
74
|
-
expect(context.finalized).toBe(true);
|
|
75
|
-
});
|
|
76
|
-
});
|
package/src/indexer.test.ts
DELETED
|
@@ -1,430 +0,0 @@
|
|
|
1
|
-
import type { Cursor, DataFinality } from "@apibara/protocol";
|
|
2
|
-
import {
|
|
3
|
-
type MockBlock,
|
|
4
|
-
MockClient,
|
|
5
|
-
type MockFilter,
|
|
6
|
-
} from "@apibara/protocol/testing";
|
|
7
|
-
import { describe, expect, it } from "vitest";
|
|
8
|
-
import { type IndexerContext, useMessageMetadataContext } from "./context";
|
|
9
|
-
import { run } from "./indexer";
|
|
10
|
-
import {
|
|
11
|
-
generateMockMessages,
|
|
12
|
-
getMockIndexer,
|
|
13
|
-
mockSink,
|
|
14
|
-
useMockSink,
|
|
15
|
-
} from "./internal/testing";
|
|
16
|
-
|
|
17
|
-
async function transform<TData>({
|
|
18
|
-
block: { data },
|
|
19
|
-
}: {
|
|
20
|
-
block: { data?: TData };
|
|
21
|
-
cursor?: Cursor;
|
|
22
|
-
endCursor?: Cursor;
|
|
23
|
-
finality?: DataFinality;
|
|
24
|
-
context: IndexerContext;
|
|
25
|
-
}) {
|
|
26
|
-
const { cursor, endCursor, finality } = useMessageMetadataContext();
|
|
27
|
-
const { output } = useMockSink();
|
|
28
|
-
output.push({
|
|
29
|
-
data,
|
|
30
|
-
cursor: cursor?.orderKey,
|
|
31
|
-
endCursor: endCursor?.orderKey,
|
|
32
|
-
finality,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
describe("Run Test", () => {
|
|
37
|
-
it("should stream messages", async () => {
|
|
38
|
-
const client = new MockClient<MockFilter, MockBlock>((request, options) => {
|
|
39
|
-
return generateMockMessages();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const output: unknown[] = [];
|
|
43
|
-
|
|
44
|
-
const indexer = getMockIndexer({
|
|
45
|
-
override: {
|
|
46
|
-
plugins: [mockSink({ output })],
|
|
47
|
-
transform,
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
await run(client, indexer);
|
|
52
|
-
|
|
53
|
-
expect(output).toMatchInlineSnapshot(`
|
|
54
|
-
[
|
|
55
|
-
{
|
|
56
|
-
"cursor": 4999999n,
|
|
57
|
-
"data": "5000000",
|
|
58
|
-
"endCursor": 5000000n,
|
|
59
|
-
"finality": "accepted",
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"cursor": 5000000n,
|
|
63
|
-
"data": "5000001",
|
|
64
|
-
"endCursor": 5000001n,
|
|
65
|
-
"finality": "accepted",
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"cursor": 5000001n,
|
|
69
|
-
"data": "5000002",
|
|
70
|
-
"endCursor": 5000002n,
|
|
71
|
-
"finality": "accepted",
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
"cursor": 5000002n,
|
|
75
|
-
"data": "5000003",
|
|
76
|
-
"endCursor": 5000003n,
|
|
77
|
-
"finality": "accepted",
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
"cursor": 5000003n,
|
|
81
|
-
"data": "5000004",
|
|
82
|
-
"endCursor": 5000004n,
|
|
83
|
-
"finality": "accepted",
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
"cursor": 5000004n,
|
|
87
|
-
"data": "5000005",
|
|
88
|
-
"endCursor": 5000005n,
|
|
89
|
-
"finality": "accepted",
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
"cursor": 5000005n,
|
|
93
|
-
"data": "5000006",
|
|
94
|
-
"endCursor": 5000006n,
|
|
95
|
-
"finality": "accepted",
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
"cursor": 5000006n,
|
|
99
|
-
"data": "5000007",
|
|
100
|
-
"endCursor": 5000007n,
|
|
101
|
-
"finality": "accepted",
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"cursor": 5000007n,
|
|
105
|
-
"data": "5000008",
|
|
106
|
-
"endCursor": 5000008n,
|
|
107
|
-
"finality": "accepted",
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"cursor": 5000008n,
|
|
111
|
-
"data": "5000009",
|
|
112
|
-
"endCursor": 5000009n,
|
|
113
|
-
"finality": "accepted",
|
|
114
|
-
},
|
|
115
|
-
]
|
|
116
|
-
`);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("factory mode: indexer should merge filters and restart when needed", async () => {
|
|
120
|
-
const client = new MockClient<MockFilter, MockBlock>((request, options) => {
|
|
121
|
-
const [_factoryFilter, mainFilter] = request.filter;
|
|
122
|
-
|
|
123
|
-
if (Object.keys(mainFilter).length === 0) {
|
|
124
|
-
expect(request.startingCursor?.orderKey).toEqual(100n);
|
|
125
|
-
|
|
126
|
-
return [
|
|
127
|
-
{
|
|
128
|
-
_tag: "data",
|
|
129
|
-
data: {
|
|
130
|
-
finality: "accepted",
|
|
131
|
-
cursor: { orderKey: 100n },
|
|
132
|
-
endCursor: { orderKey: 101n },
|
|
133
|
-
data: [null, null],
|
|
134
|
-
production: "backfill",
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
_tag: "data",
|
|
139
|
-
data: {
|
|
140
|
-
finality: "accepted",
|
|
141
|
-
cursor: { orderKey: 101n },
|
|
142
|
-
endCursor: { orderKey: 102n },
|
|
143
|
-
data: [null, null],
|
|
144
|
-
production: "backfill",
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
_tag: "data",
|
|
149
|
-
data: {
|
|
150
|
-
finality: "accepted",
|
|
151
|
-
cursor: { orderKey: 102n },
|
|
152
|
-
endCursor: { orderKey: 103n },
|
|
153
|
-
data: [{ data: "B" }, null],
|
|
154
|
-
production: "backfill",
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
];
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (mainFilter.filter === "B") {
|
|
161
|
-
expect(request.startingCursor?.orderKey).toEqual(102n);
|
|
162
|
-
|
|
163
|
-
return [
|
|
164
|
-
{
|
|
165
|
-
_tag: "data",
|
|
166
|
-
data: {
|
|
167
|
-
finality: "accepted",
|
|
168
|
-
cursor: { orderKey: 102n },
|
|
169
|
-
endCursor: { orderKey: 103n },
|
|
170
|
-
data: [{ data: "B" }, { data: "103B" }],
|
|
171
|
-
production: "backfill",
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
_tag: "data",
|
|
176
|
-
data: {
|
|
177
|
-
finality: "accepted",
|
|
178
|
-
cursor: { orderKey: 103n },
|
|
179
|
-
endCursor: { orderKey: 104n },
|
|
180
|
-
data: [null, { data: "104B" }],
|
|
181
|
-
production: "backfill",
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
_tag: "data",
|
|
186
|
-
data: {
|
|
187
|
-
finality: "accepted",
|
|
188
|
-
cursor: { orderKey: 104n },
|
|
189
|
-
endCursor: { orderKey: 105n },
|
|
190
|
-
data: [null, { data: "105B" }],
|
|
191
|
-
production: "backfill",
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
_tag: "data",
|
|
196
|
-
data: {
|
|
197
|
-
finality: "accepted",
|
|
198
|
-
cursor: { orderKey: 105n },
|
|
199
|
-
endCursor: { orderKey: 106n },
|
|
200
|
-
data: [{ data: "C" }, { data: "106B" }],
|
|
201
|
-
production: "backfill",
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
];
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (mainFilter.filter === "BC") {
|
|
208
|
-
expect(request.startingCursor?.orderKey).toEqual(105n);
|
|
209
|
-
|
|
210
|
-
return [
|
|
211
|
-
{
|
|
212
|
-
_tag: "data",
|
|
213
|
-
data: {
|
|
214
|
-
finality: "accepted",
|
|
215
|
-
cursor: { orderKey: 105n },
|
|
216
|
-
endCursor: { orderKey: 106n },
|
|
217
|
-
data: [{ data: "C" }, { data: "106BC" }],
|
|
218
|
-
production: "backfill",
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
_tag: "data",
|
|
223
|
-
data: {
|
|
224
|
-
finality: "accepted",
|
|
225
|
-
cursor: { orderKey: 106n },
|
|
226
|
-
endCursor: { orderKey: 107n },
|
|
227
|
-
data: [null, { data: "107BC" }],
|
|
228
|
-
production: "backfill",
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
_tag: "data",
|
|
233
|
-
data: {
|
|
234
|
-
finality: "accepted",
|
|
235
|
-
cursor: { orderKey: 107n },
|
|
236
|
-
endCursor: { orderKey: 108n },
|
|
237
|
-
data: [null, { data: "108BC" }],
|
|
238
|
-
production: "backfill",
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
];
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return [];
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
const output: unknown[] = [];
|
|
248
|
-
const metadata: Record<string, unknown> = {};
|
|
249
|
-
|
|
250
|
-
const indexer = getMockIndexer({
|
|
251
|
-
override: {
|
|
252
|
-
plugins: [mockSink({ output, metadata })],
|
|
253
|
-
startingCursor: { orderKey: 100n },
|
|
254
|
-
factory: async ({ block }) => {
|
|
255
|
-
if (block.data === "B") {
|
|
256
|
-
return { filter: { filter: "B" } };
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (block.data === "C") {
|
|
260
|
-
return { filter: { filter: "C" } };
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return {};
|
|
264
|
-
},
|
|
265
|
-
transform,
|
|
266
|
-
},
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
await run(client, indexer);
|
|
270
|
-
|
|
271
|
-
expect((metadata.lastCursor as Cursor).orderKey).toEqual(108n);
|
|
272
|
-
expect((metadata.lastFilter as { filter: unknown }).filter).toEqual("BC");
|
|
273
|
-
|
|
274
|
-
expect(output).toMatchInlineSnapshot(`
|
|
275
|
-
[
|
|
276
|
-
{
|
|
277
|
-
"cursor": 102n,
|
|
278
|
-
"data": "103B",
|
|
279
|
-
"endCursor": 103n,
|
|
280
|
-
"finality": "accepted",
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
"cursor": 103n,
|
|
284
|
-
"data": "104B",
|
|
285
|
-
"endCursor": 104n,
|
|
286
|
-
"finality": "accepted",
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
"cursor": 104n,
|
|
290
|
-
"data": "105B",
|
|
291
|
-
"endCursor": 105n,
|
|
292
|
-
"finality": "accepted",
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
"cursor": 105n,
|
|
296
|
-
"data": "106BC",
|
|
297
|
-
"endCursor": 106n,
|
|
298
|
-
"finality": "accepted",
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
"cursor": 106n,
|
|
302
|
-
"data": "107BC",
|
|
303
|
-
"endCursor": 107n,
|
|
304
|
-
"finality": "accepted",
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
"cursor": 107n,
|
|
308
|
-
"data": "108BC",
|
|
309
|
-
"endCursor": 108n,
|
|
310
|
-
"finality": "accepted",
|
|
311
|
-
},
|
|
312
|
-
]
|
|
313
|
-
`);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
it("factory mode: last cursor should persist when error is thrown in indexer", async () => {
|
|
317
|
-
const client = new MockClient<MockFilter, MockBlock>((request, options) => {
|
|
318
|
-
const [_factoryFilter, mainFilter] = request.filter;
|
|
319
|
-
|
|
320
|
-
if (Object.keys(mainFilter).length === 0) {
|
|
321
|
-
expect(request.startingCursor?.orderKey).toEqual(100n);
|
|
322
|
-
|
|
323
|
-
return [
|
|
324
|
-
{
|
|
325
|
-
_tag: "data",
|
|
326
|
-
data: {
|
|
327
|
-
finality: "accepted",
|
|
328
|
-
cursor: { orderKey: 100n },
|
|
329
|
-
endCursor: { orderKey: 101n },
|
|
330
|
-
data: [null, null],
|
|
331
|
-
production: "backfill",
|
|
332
|
-
},
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
_tag: "data",
|
|
336
|
-
data: {
|
|
337
|
-
finality: "accepted",
|
|
338
|
-
cursor: { orderKey: 101n },
|
|
339
|
-
endCursor: { orderKey: 102n },
|
|
340
|
-
data: [null, null],
|
|
341
|
-
production: "backfill",
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
_tag: "data",
|
|
346
|
-
data: {
|
|
347
|
-
finality: "accepted",
|
|
348
|
-
cursor: { orderKey: 102n },
|
|
349
|
-
endCursor: { orderKey: 103n },
|
|
350
|
-
data: [{ data: "B" }, null],
|
|
351
|
-
production: "backfill",
|
|
352
|
-
},
|
|
353
|
-
},
|
|
354
|
-
Error("this error should not occurr!"),
|
|
355
|
-
];
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if (mainFilter.filter === "B") {
|
|
359
|
-
expect(request.startingCursor?.orderKey).toEqual(102n);
|
|
360
|
-
|
|
361
|
-
return [
|
|
362
|
-
Error("this error should occurr!"),
|
|
363
|
-
{
|
|
364
|
-
_tag: "data",
|
|
365
|
-
data: {
|
|
366
|
-
finality: "accepted",
|
|
367
|
-
cursor: { orderKey: 103n },
|
|
368
|
-
endCursor: { orderKey: 104n },
|
|
369
|
-
data: [null, { data: "104B" }],
|
|
370
|
-
production: "backfill",
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
|
-
{
|
|
374
|
-
_tag: "data",
|
|
375
|
-
data: {
|
|
376
|
-
finality: "accepted",
|
|
377
|
-
cursor: { orderKey: 104n },
|
|
378
|
-
endCursor: { orderKey: 105n },
|
|
379
|
-
data: [null, { data: "105B" }],
|
|
380
|
-
production: "backfill",
|
|
381
|
-
},
|
|
382
|
-
},
|
|
383
|
-
{
|
|
384
|
-
_tag: "data",
|
|
385
|
-
data: {
|
|
386
|
-
finality: "accepted",
|
|
387
|
-
cursor: { orderKey: 105n },
|
|
388
|
-
endCursor: { orderKey: 106n },
|
|
389
|
-
data: [{ data: "C" }, { data: "106B" }],
|
|
390
|
-
production: "backfill",
|
|
391
|
-
},
|
|
392
|
-
},
|
|
393
|
-
];
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
return [];
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
const output: unknown[] = [];
|
|
400
|
-
const metadata: Record<string, unknown> = {};
|
|
401
|
-
|
|
402
|
-
const indexer = getMockIndexer({
|
|
403
|
-
override: {
|
|
404
|
-
plugins: [mockSink({ output, metadata })],
|
|
405
|
-
startingCursor: { orderKey: 100n },
|
|
406
|
-
factory: async ({ block }) => {
|
|
407
|
-
if (block.data === "B") {
|
|
408
|
-
return { filter: { filter: "B" } };
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
if (block.data === "C") {
|
|
412
|
-
return { filter: { filter: "C" } };
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
return {};
|
|
416
|
-
},
|
|
417
|
-
transform,
|
|
418
|
-
},
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
await expect(() => run(client, indexer)).rejects.toThrowError(
|
|
422
|
-
"this error should occurr!",
|
|
423
|
-
);
|
|
424
|
-
|
|
425
|
-
expect((metadata.lastCursor as Cursor).orderKey).toEqual(103n);
|
|
426
|
-
expect((metadata.lastFilter as { filter: unknown }).filter).toEqual("B");
|
|
427
|
-
|
|
428
|
-
expect(output).toMatchInlineSnapshot("[]");
|
|
429
|
-
});
|
|
430
|
-
});
|