@apibara/protocol 2.0.0-beta.4 → 2.0.0-beta.41
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 +222 -0
- package/dist/index.d.cts +71 -0
- package/dist/index.d.mts +71 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.mjs +179 -0
- package/dist/shared/protocol.4b1cfe2c.d.cts +756 -0
- package/dist/shared/protocol.4b1cfe2c.d.mts +756 -0
- package/dist/shared/protocol.4b1cfe2c.d.ts +756 -0
- package/dist/shared/protocol.991ff9ad.mjs +1308 -0
- package/dist/shared/protocol.e39e40d6.cjs +1344 -0
- package/dist/testing/index.cjs +105 -0
- package/dist/testing/index.d.cts +76 -0
- package/dist/testing/index.d.mts +76 -0
- package/dist/testing/index.d.ts +76 -0
- package/dist/testing/index.mjs +97 -0
- package/package.json +8 -10
- package/src/client.ts +72 -28
- package/src/common.ts +28 -0
- package/src/proto/google/protobuf/duration.ts +1 -1
- package/src/proto/stream.ts +62 -3
- package/src/proto/testing.ts +1 -1
- package/src/stream.test.ts +16 -0
- package/src/stream.ts +34 -3
- package/src/testing/client.test.ts +28 -2
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const schema = require('@effect/schema');
|
|
4
|
+
const config = require('../shared/protocol.e39e40d6.cjs');
|
|
5
|
+
require('protobufjs/minimal.js');
|
|
6
|
+
require('effect');
|
|
7
|
+
require('viem');
|
|
8
|
+
require('long');
|
|
9
|
+
|
|
10
|
+
class MockClient {
|
|
11
|
+
constructor(messageFactory) {
|
|
12
|
+
this.messageFactory = messageFactory;
|
|
13
|
+
}
|
|
14
|
+
async status(request, options) {
|
|
15
|
+
throw new Error("Client.status is not implemented for VcrClient");
|
|
16
|
+
}
|
|
17
|
+
streamData(request, options) {
|
|
18
|
+
const messages = this.messageFactory(request, options);
|
|
19
|
+
return new StreamDataIterable(messages);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
class StreamDataIterable {
|
|
23
|
+
constructor(messages) {
|
|
24
|
+
this.messages = messages;
|
|
25
|
+
}
|
|
26
|
+
[Symbol.asyncIterator]() {
|
|
27
|
+
let index = 0;
|
|
28
|
+
const messages = this.messages;
|
|
29
|
+
return {
|
|
30
|
+
async next() {
|
|
31
|
+
if (index >= messages.length) {
|
|
32
|
+
return { done: true, value: void 0 };
|
|
33
|
+
}
|
|
34
|
+
const message = messages[index++];
|
|
35
|
+
if (message instanceof Error) {
|
|
36
|
+
throw message;
|
|
37
|
+
}
|
|
38
|
+
return { done: false, value: message };
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const MockFilter = schema.Schema.Struct({
|
|
45
|
+
filter: schema.Schema.optional(schema.Schema.String)
|
|
46
|
+
});
|
|
47
|
+
const MockFilterFromBytes = schema.Schema.transform(
|
|
48
|
+
schema.Schema.Uint8ArrayFromSelf,
|
|
49
|
+
MockFilter,
|
|
50
|
+
{
|
|
51
|
+
strict: false,
|
|
52
|
+
decode(value) {
|
|
53
|
+
return config.MockFilter.decode(value);
|
|
54
|
+
},
|
|
55
|
+
encode(value) {
|
|
56
|
+
return config.MockFilter.encode(value).finish();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
const MockBlock = schema.Schema.Struct({
|
|
61
|
+
data: schema.Schema.optional(schema.Schema.String)
|
|
62
|
+
});
|
|
63
|
+
const MockBlockFromBytes = schema.Schema.transform(
|
|
64
|
+
schema.Schema.Uint8ArrayFromSelf,
|
|
65
|
+
schema.Schema.NullOr(MockBlock),
|
|
66
|
+
{
|
|
67
|
+
strict: false,
|
|
68
|
+
decode(value) {
|
|
69
|
+
if (value.length === 0) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return config.MockBlock.decode(value);
|
|
73
|
+
},
|
|
74
|
+
encode(value) {
|
|
75
|
+
if (value === null) {
|
|
76
|
+
return new Uint8Array();
|
|
77
|
+
}
|
|
78
|
+
return config.MockBlock.encode(value).finish();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
function mergeMockFilter(a, b) {
|
|
83
|
+
let filter = "";
|
|
84
|
+
if (a.filter) {
|
|
85
|
+
filter += a.filter;
|
|
86
|
+
}
|
|
87
|
+
if (b.filter) {
|
|
88
|
+
filter += b.filter;
|
|
89
|
+
}
|
|
90
|
+
return { filter };
|
|
91
|
+
}
|
|
92
|
+
const MockStream = new config.StreamConfig(
|
|
93
|
+
MockFilterFromBytes,
|
|
94
|
+
MockBlockFromBytes,
|
|
95
|
+
mergeMockFilter
|
|
96
|
+
);
|
|
97
|
+
const MockStreamResponse = config.StreamDataResponse(MockBlockFromBytes);
|
|
98
|
+
|
|
99
|
+
exports.MockBlockFromBytes = MockBlockFromBytes;
|
|
100
|
+
exports.MockClient = MockClient;
|
|
101
|
+
exports.MockFilter = MockFilter;
|
|
102
|
+
exports.MockFilterFromBytes = MockFilterFromBytes;
|
|
103
|
+
exports.MockStream = MockStream;
|
|
104
|
+
exports.MockStreamResponse = MockStreamResponse;
|
|
105
|
+
exports.StreamDataIterable = StreamDataIterable;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { J as Client, u as StreamDataRequest, G as StreamDataOptions, z as StreamDataResponse, S as StatusRequest, E as ClientCallOptions, m as StatusResponse, A as StreamConfig, c as Cursor, C as CursorProto, O as DataFinality, P as DataProduction } from '../shared/protocol.4b1cfe2c.cjs';
|
|
2
|
+
import { Schema } from '@effect/schema';
|
|
3
|
+
import 'nice-grpc';
|
|
4
|
+
import 'nice-grpc-common';
|
|
5
|
+
import 'protobufjs/minimal.js';
|
|
6
|
+
import '@effect/schema/AST';
|
|
7
|
+
|
|
8
|
+
declare class MockClient<TFilter, TBlock> implements Client<TFilter, TBlock> {
|
|
9
|
+
private messageFactory;
|
|
10
|
+
constructor(messageFactory: (request: StreamDataRequest<TFilter>, options?: StreamDataOptions) => (StreamDataResponse<TBlock> | Error)[]);
|
|
11
|
+
status(request?: StatusRequest, options?: ClientCallOptions): Promise<StatusResponse>;
|
|
12
|
+
streamData(request: StreamDataRequest<TFilter>, options?: StreamDataOptions): StreamDataIterable<TBlock>;
|
|
13
|
+
}
|
|
14
|
+
declare class StreamDataIterable<TBlock> {
|
|
15
|
+
private messages;
|
|
16
|
+
constructor(messages: (StreamDataResponse<TBlock> | Error)[]);
|
|
17
|
+
[Symbol.asyncIterator](): AsyncIterator<StreamDataResponse<TBlock>>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare const MockFilter: Schema.Struct<{
|
|
21
|
+
filter: Schema.optional<typeof Schema.String>;
|
|
22
|
+
}>;
|
|
23
|
+
type MockFilter = typeof MockFilter.Type;
|
|
24
|
+
declare const MockFilterFromBytes: Schema.transform<Schema.Schema<Uint8Array, Uint8Array, never>, Schema.Struct<{
|
|
25
|
+
filter: Schema.optional<typeof Schema.String>;
|
|
26
|
+
}>>;
|
|
27
|
+
declare const MockBlock: Schema.Struct<{
|
|
28
|
+
data: Schema.optional<typeof Schema.String>;
|
|
29
|
+
}>;
|
|
30
|
+
type MockBlock = typeof MockBlock.Type;
|
|
31
|
+
declare const MockBlockFromBytes: Schema.transform<Schema.Schema<Uint8Array, Uint8Array, never>, Schema.NullOr<Schema.Struct<{
|
|
32
|
+
data: Schema.optional<typeof Schema.String>;
|
|
33
|
+
}>>>;
|
|
34
|
+
declare const MockStream: StreamConfig<{
|
|
35
|
+
readonly filter?: string | undefined;
|
|
36
|
+
}, {
|
|
37
|
+
readonly data?: string | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
declare const MockStreamResponse: Schema.Union<[Schema.Struct<{
|
|
40
|
+
_tag: Schema.PropertySignature<":", "data", "$case", ":", "data", false, never>;
|
|
41
|
+
data: Schema.Struct<{
|
|
42
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
43
|
+
endCursor: Schema.Schema<Cursor, CursorProto, never>;
|
|
44
|
+
finality: Schema.transform<Schema.Enums<typeof DataFinality>, Schema.Literal<["finalized", "accepted", "pending", "unknown"]>>;
|
|
45
|
+
production: Schema.transform<Schema.Enums<typeof DataProduction>, Schema.Literal<["backfill", "live", "unknown"]>>;
|
|
46
|
+
data: Schema.Array$<Schema.Schema<{
|
|
47
|
+
readonly data?: string | undefined;
|
|
48
|
+
} | null, Uint8Array, never>>;
|
|
49
|
+
}>;
|
|
50
|
+
}>, Schema.Struct<{
|
|
51
|
+
_tag: Schema.PropertySignature<":", "invalidate", "$case", ":", "invalidate", false, never>;
|
|
52
|
+
invalidate: Schema.Struct<{
|
|
53
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
54
|
+
}>;
|
|
55
|
+
}>, Schema.Struct<{
|
|
56
|
+
_tag: Schema.PropertySignature<":", "finalize", "$case", ":", "finalize", false, never>;
|
|
57
|
+
finalize: Schema.Struct<{
|
|
58
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
59
|
+
}>;
|
|
60
|
+
}>, Schema.Struct<{
|
|
61
|
+
_tag: Schema.PropertySignature<":", "heartbeat", "$case", ":", "heartbeat", false, never>;
|
|
62
|
+
}>, Schema.Struct<{
|
|
63
|
+
_tag: Schema.PropertySignature<":", "systemMessage", "$case", ":", "systemMessage", false, never>;
|
|
64
|
+
systemMessage: Schema.Struct<{
|
|
65
|
+
output: Schema.Union<[Schema.Struct<{
|
|
66
|
+
_tag: Schema.PropertySignature<":", "stdout", "$case", ":", "stdout", false, never>;
|
|
67
|
+
stdout: typeof Schema.String;
|
|
68
|
+
}>, Schema.Struct<{
|
|
69
|
+
_tag: Schema.PropertySignature<":", "stderr", "$case", ":", "stderr", false, never>;
|
|
70
|
+
stderr: typeof Schema.String;
|
|
71
|
+
}>]>;
|
|
72
|
+
}>;
|
|
73
|
+
}>]>;
|
|
74
|
+
type MockStreamResponse = typeof MockStreamResponse.Type;
|
|
75
|
+
|
|
76
|
+
export { MockBlock, MockBlockFromBytes, MockClient, MockFilter, MockFilterFromBytes, MockStream, MockStreamResponse, StreamDataIterable };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { J as Client, u as StreamDataRequest, G as StreamDataOptions, z as StreamDataResponse, S as StatusRequest, E as ClientCallOptions, m as StatusResponse, A as StreamConfig, c as Cursor, C as CursorProto, O as DataFinality, P as DataProduction } from '../shared/protocol.4b1cfe2c.mjs';
|
|
2
|
+
import { Schema } from '@effect/schema';
|
|
3
|
+
import 'nice-grpc';
|
|
4
|
+
import 'nice-grpc-common';
|
|
5
|
+
import 'protobufjs/minimal.js';
|
|
6
|
+
import '@effect/schema/AST';
|
|
7
|
+
|
|
8
|
+
declare class MockClient<TFilter, TBlock> implements Client<TFilter, TBlock> {
|
|
9
|
+
private messageFactory;
|
|
10
|
+
constructor(messageFactory: (request: StreamDataRequest<TFilter>, options?: StreamDataOptions) => (StreamDataResponse<TBlock> | Error)[]);
|
|
11
|
+
status(request?: StatusRequest, options?: ClientCallOptions): Promise<StatusResponse>;
|
|
12
|
+
streamData(request: StreamDataRequest<TFilter>, options?: StreamDataOptions): StreamDataIterable<TBlock>;
|
|
13
|
+
}
|
|
14
|
+
declare class StreamDataIterable<TBlock> {
|
|
15
|
+
private messages;
|
|
16
|
+
constructor(messages: (StreamDataResponse<TBlock> | Error)[]);
|
|
17
|
+
[Symbol.asyncIterator](): AsyncIterator<StreamDataResponse<TBlock>>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare const MockFilter: Schema.Struct<{
|
|
21
|
+
filter: Schema.optional<typeof Schema.String>;
|
|
22
|
+
}>;
|
|
23
|
+
type MockFilter = typeof MockFilter.Type;
|
|
24
|
+
declare const MockFilterFromBytes: Schema.transform<Schema.Schema<Uint8Array, Uint8Array, never>, Schema.Struct<{
|
|
25
|
+
filter: Schema.optional<typeof Schema.String>;
|
|
26
|
+
}>>;
|
|
27
|
+
declare const MockBlock: Schema.Struct<{
|
|
28
|
+
data: Schema.optional<typeof Schema.String>;
|
|
29
|
+
}>;
|
|
30
|
+
type MockBlock = typeof MockBlock.Type;
|
|
31
|
+
declare const MockBlockFromBytes: Schema.transform<Schema.Schema<Uint8Array, Uint8Array, never>, Schema.NullOr<Schema.Struct<{
|
|
32
|
+
data: Schema.optional<typeof Schema.String>;
|
|
33
|
+
}>>>;
|
|
34
|
+
declare const MockStream: StreamConfig<{
|
|
35
|
+
readonly filter?: string | undefined;
|
|
36
|
+
}, {
|
|
37
|
+
readonly data?: string | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
declare const MockStreamResponse: Schema.Union<[Schema.Struct<{
|
|
40
|
+
_tag: Schema.PropertySignature<":", "data", "$case", ":", "data", false, never>;
|
|
41
|
+
data: Schema.Struct<{
|
|
42
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
43
|
+
endCursor: Schema.Schema<Cursor, CursorProto, never>;
|
|
44
|
+
finality: Schema.transform<Schema.Enums<typeof DataFinality>, Schema.Literal<["finalized", "accepted", "pending", "unknown"]>>;
|
|
45
|
+
production: Schema.transform<Schema.Enums<typeof DataProduction>, Schema.Literal<["backfill", "live", "unknown"]>>;
|
|
46
|
+
data: Schema.Array$<Schema.Schema<{
|
|
47
|
+
readonly data?: string | undefined;
|
|
48
|
+
} | null, Uint8Array, never>>;
|
|
49
|
+
}>;
|
|
50
|
+
}>, Schema.Struct<{
|
|
51
|
+
_tag: Schema.PropertySignature<":", "invalidate", "$case", ":", "invalidate", false, never>;
|
|
52
|
+
invalidate: Schema.Struct<{
|
|
53
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
54
|
+
}>;
|
|
55
|
+
}>, Schema.Struct<{
|
|
56
|
+
_tag: Schema.PropertySignature<":", "finalize", "$case", ":", "finalize", false, never>;
|
|
57
|
+
finalize: Schema.Struct<{
|
|
58
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
59
|
+
}>;
|
|
60
|
+
}>, Schema.Struct<{
|
|
61
|
+
_tag: Schema.PropertySignature<":", "heartbeat", "$case", ":", "heartbeat", false, never>;
|
|
62
|
+
}>, Schema.Struct<{
|
|
63
|
+
_tag: Schema.PropertySignature<":", "systemMessage", "$case", ":", "systemMessage", false, never>;
|
|
64
|
+
systemMessage: Schema.Struct<{
|
|
65
|
+
output: Schema.Union<[Schema.Struct<{
|
|
66
|
+
_tag: Schema.PropertySignature<":", "stdout", "$case", ":", "stdout", false, never>;
|
|
67
|
+
stdout: typeof Schema.String;
|
|
68
|
+
}>, Schema.Struct<{
|
|
69
|
+
_tag: Schema.PropertySignature<":", "stderr", "$case", ":", "stderr", false, never>;
|
|
70
|
+
stderr: typeof Schema.String;
|
|
71
|
+
}>]>;
|
|
72
|
+
}>;
|
|
73
|
+
}>]>;
|
|
74
|
+
type MockStreamResponse = typeof MockStreamResponse.Type;
|
|
75
|
+
|
|
76
|
+
export { MockBlock, MockBlockFromBytes, MockClient, MockFilter, MockFilterFromBytes, MockStream, MockStreamResponse, StreamDataIterable };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { J as Client, u as StreamDataRequest, G as StreamDataOptions, z as StreamDataResponse, S as StatusRequest, E as ClientCallOptions, m as StatusResponse, A as StreamConfig, c as Cursor, C as CursorProto, O as DataFinality, P as DataProduction } from '../shared/protocol.4b1cfe2c.js';
|
|
2
|
+
import { Schema } from '@effect/schema';
|
|
3
|
+
import 'nice-grpc';
|
|
4
|
+
import 'nice-grpc-common';
|
|
5
|
+
import 'protobufjs/minimal.js';
|
|
6
|
+
import '@effect/schema/AST';
|
|
7
|
+
|
|
8
|
+
declare class MockClient<TFilter, TBlock> implements Client<TFilter, TBlock> {
|
|
9
|
+
private messageFactory;
|
|
10
|
+
constructor(messageFactory: (request: StreamDataRequest<TFilter>, options?: StreamDataOptions) => (StreamDataResponse<TBlock> | Error)[]);
|
|
11
|
+
status(request?: StatusRequest, options?: ClientCallOptions): Promise<StatusResponse>;
|
|
12
|
+
streamData(request: StreamDataRequest<TFilter>, options?: StreamDataOptions): StreamDataIterable<TBlock>;
|
|
13
|
+
}
|
|
14
|
+
declare class StreamDataIterable<TBlock> {
|
|
15
|
+
private messages;
|
|
16
|
+
constructor(messages: (StreamDataResponse<TBlock> | Error)[]);
|
|
17
|
+
[Symbol.asyncIterator](): AsyncIterator<StreamDataResponse<TBlock>>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare const MockFilter: Schema.Struct<{
|
|
21
|
+
filter: Schema.optional<typeof Schema.String>;
|
|
22
|
+
}>;
|
|
23
|
+
type MockFilter = typeof MockFilter.Type;
|
|
24
|
+
declare const MockFilterFromBytes: Schema.transform<Schema.Schema<Uint8Array, Uint8Array, never>, Schema.Struct<{
|
|
25
|
+
filter: Schema.optional<typeof Schema.String>;
|
|
26
|
+
}>>;
|
|
27
|
+
declare const MockBlock: Schema.Struct<{
|
|
28
|
+
data: Schema.optional<typeof Schema.String>;
|
|
29
|
+
}>;
|
|
30
|
+
type MockBlock = typeof MockBlock.Type;
|
|
31
|
+
declare const MockBlockFromBytes: Schema.transform<Schema.Schema<Uint8Array, Uint8Array, never>, Schema.NullOr<Schema.Struct<{
|
|
32
|
+
data: Schema.optional<typeof Schema.String>;
|
|
33
|
+
}>>>;
|
|
34
|
+
declare const MockStream: StreamConfig<{
|
|
35
|
+
readonly filter?: string | undefined;
|
|
36
|
+
}, {
|
|
37
|
+
readonly data?: string | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
declare const MockStreamResponse: Schema.Union<[Schema.Struct<{
|
|
40
|
+
_tag: Schema.PropertySignature<":", "data", "$case", ":", "data", false, never>;
|
|
41
|
+
data: Schema.Struct<{
|
|
42
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
43
|
+
endCursor: Schema.Schema<Cursor, CursorProto, never>;
|
|
44
|
+
finality: Schema.transform<Schema.Enums<typeof DataFinality>, Schema.Literal<["finalized", "accepted", "pending", "unknown"]>>;
|
|
45
|
+
production: Schema.transform<Schema.Enums<typeof DataProduction>, Schema.Literal<["backfill", "live", "unknown"]>>;
|
|
46
|
+
data: Schema.Array$<Schema.Schema<{
|
|
47
|
+
readonly data?: string | undefined;
|
|
48
|
+
} | null, Uint8Array, never>>;
|
|
49
|
+
}>;
|
|
50
|
+
}>, Schema.Struct<{
|
|
51
|
+
_tag: Schema.PropertySignature<":", "invalidate", "$case", ":", "invalidate", false, never>;
|
|
52
|
+
invalidate: Schema.Struct<{
|
|
53
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
54
|
+
}>;
|
|
55
|
+
}>, Schema.Struct<{
|
|
56
|
+
_tag: Schema.PropertySignature<":", "finalize", "$case", ":", "finalize", false, never>;
|
|
57
|
+
finalize: Schema.Struct<{
|
|
58
|
+
cursor: Schema.optional<Schema.Schema<Cursor, CursorProto, never>>;
|
|
59
|
+
}>;
|
|
60
|
+
}>, Schema.Struct<{
|
|
61
|
+
_tag: Schema.PropertySignature<":", "heartbeat", "$case", ":", "heartbeat", false, never>;
|
|
62
|
+
}>, Schema.Struct<{
|
|
63
|
+
_tag: Schema.PropertySignature<":", "systemMessage", "$case", ":", "systemMessage", false, never>;
|
|
64
|
+
systemMessage: Schema.Struct<{
|
|
65
|
+
output: Schema.Union<[Schema.Struct<{
|
|
66
|
+
_tag: Schema.PropertySignature<":", "stdout", "$case", ":", "stdout", false, never>;
|
|
67
|
+
stdout: typeof Schema.String;
|
|
68
|
+
}>, Schema.Struct<{
|
|
69
|
+
_tag: Schema.PropertySignature<":", "stderr", "$case", ":", "stderr", false, never>;
|
|
70
|
+
stderr: typeof Schema.String;
|
|
71
|
+
}>]>;
|
|
72
|
+
}>;
|
|
73
|
+
}>]>;
|
|
74
|
+
type MockStreamResponse = typeof MockStreamResponse.Type;
|
|
75
|
+
|
|
76
|
+
export { MockBlock, MockBlockFromBytes, MockClient, MockFilter, MockFilterFromBytes, MockStream, MockStreamResponse, StreamDataIterable };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Schema } from '@effect/schema';
|
|
2
|
+
import { M as MockFilter$1, u as MockBlock$1, r as StreamConfig, S as StreamDataResponse } from '../shared/protocol.991ff9ad.mjs';
|
|
3
|
+
import 'protobufjs/minimal.js';
|
|
4
|
+
import 'effect';
|
|
5
|
+
import 'viem';
|
|
6
|
+
import 'long';
|
|
7
|
+
|
|
8
|
+
class MockClient {
|
|
9
|
+
constructor(messageFactory) {
|
|
10
|
+
this.messageFactory = messageFactory;
|
|
11
|
+
}
|
|
12
|
+
async status(request, options) {
|
|
13
|
+
throw new Error("Client.status is not implemented for VcrClient");
|
|
14
|
+
}
|
|
15
|
+
streamData(request, options) {
|
|
16
|
+
const messages = this.messageFactory(request, options);
|
|
17
|
+
return new StreamDataIterable(messages);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
class StreamDataIterable {
|
|
21
|
+
constructor(messages) {
|
|
22
|
+
this.messages = messages;
|
|
23
|
+
}
|
|
24
|
+
[Symbol.asyncIterator]() {
|
|
25
|
+
let index = 0;
|
|
26
|
+
const messages = this.messages;
|
|
27
|
+
return {
|
|
28
|
+
async next() {
|
|
29
|
+
if (index >= messages.length) {
|
|
30
|
+
return { done: true, value: void 0 };
|
|
31
|
+
}
|
|
32
|
+
const message = messages[index++];
|
|
33
|
+
if (message instanceof Error) {
|
|
34
|
+
throw message;
|
|
35
|
+
}
|
|
36
|
+
return { done: false, value: message };
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const MockFilter = Schema.Struct({
|
|
43
|
+
filter: Schema.optional(Schema.String)
|
|
44
|
+
});
|
|
45
|
+
const MockFilterFromBytes = Schema.transform(
|
|
46
|
+
Schema.Uint8ArrayFromSelf,
|
|
47
|
+
MockFilter,
|
|
48
|
+
{
|
|
49
|
+
strict: false,
|
|
50
|
+
decode(value) {
|
|
51
|
+
return MockFilter$1.decode(value);
|
|
52
|
+
},
|
|
53
|
+
encode(value) {
|
|
54
|
+
return MockFilter$1.encode(value).finish();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
const MockBlock = Schema.Struct({
|
|
59
|
+
data: Schema.optional(Schema.String)
|
|
60
|
+
});
|
|
61
|
+
const MockBlockFromBytes = Schema.transform(
|
|
62
|
+
Schema.Uint8ArrayFromSelf,
|
|
63
|
+
Schema.NullOr(MockBlock),
|
|
64
|
+
{
|
|
65
|
+
strict: false,
|
|
66
|
+
decode(value) {
|
|
67
|
+
if (value.length === 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
return MockBlock$1.decode(value);
|
|
71
|
+
},
|
|
72
|
+
encode(value) {
|
|
73
|
+
if (value === null) {
|
|
74
|
+
return new Uint8Array();
|
|
75
|
+
}
|
|
76
|
+
return MockBlock$1.encode(value).finish();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
function mergeMockFilter(a, b) {
|
|
81
|
+
let filter = "";
|
|
82
|
+
if (a.filter) {
|
|
83
|
+
filter += a.filter;
|
|
84
|
+
}
|
|
85
|
+
if (b.filter) {
|
|
86
|
+
filter += b.filter;
|
|
87
|
+
}
|
|
88
|
+
return { filter };
|
|
89
|
+
}
|
|
90
|
+
const MockStream = new StreamConfig(
|
|
91
|
+
MockFilterFromBytes,
|
|
92
|
+
MockBlockFromBytes,
|
|
93
|
+
mergeMockFilter
|
|
94
|
+
);
|
|
95
|
+
const MockStreamResponse = StreamDataResponse(MockBlockFromBytes);
|
|
96
|
+
|
|
97
|
+
export { MockBlockFromBytes, MockClient, MockFilter, MockFilterFromBytes, MockStream, MockStreamResponse, StreamDataIterable };
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apibara/protocol",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.41",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"
|
|
5
|
+
"files": [
|
|
6
|
+
"dist",
|
|
7
|
+
"src",
|
|
8
|
+
"README.md"
|
|
9
|
+
],
|
|
6
10
|
"main": "./dist/index.mjs",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
7
12
|
"exports": {
|
|
8
13
|
".": {
|
|
9
14
|
"types": "./dist/index.d.ts",
|
|
@@ -18,7 +23,6 @@
|
|
|
18
23
|
"default": "./dist/testing/index.mjs"
|
|
19
24
|
}
|
|
20
25
|
},
|
|
21
|
-
"publishConfig": {},
|
|
22
26
|
"scripts": {
|
|
23
27
|
"build": "pnpm build:proto && unbuild",
|
|
24
28
|
"build:proto": "buf generate proto",
|
|
@@ -44,11 +48,5 @@
|
|
|
44
48
|
"nice-grpc-common": "^2.0.2",
|
|
45
49
|
"protobufjs": "^7.3.0",
|
|
46
50
|
"viem": "^2.13.2"
|
|
47
|
-
}
|
|
48
|
-
"files": [
|
|
49
|
-
"dist",
|
|
50
|
-
"src",
|
|
51
|
-
"README.md"
|
|
52
|
-
],
|
|
53
|
-
"types": "./dist/index.d.ts"
|
|
51
|
+
}
|
|
54
52
|
}
|
package/src/client.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Schema } from "@effect/schema";
|
|
2
2
|
import {
|
|
3
|
+
type ChannelCredentials,
|
|
4
|
+
type ChannelOptions,
|
|
3
5
|
type DefaultCallOptions,
|
|
4
6
|
type NormalizedServiceDefinition,
|
|
5
7
|
createChannel,
|
|
@@ -19,14 +21,27 @@ import {
|
|
|
19
21
|
} from "./status";
|
|
20
22
|
import { type StreamDataRequest, StreamDataResponse } from "./stream";
|
|
21
23
|
|
|
24
|
+
export { ClientError, Status } from "nice-grpc";
|
|
25
|
+
|
|
26
|
+
const DEFAULT_TIMEOUT_MS = 45_000;
|
|
27
|
+
|
|
28
|
+
export class TimeoutError extends Error {
|
|
29
|
+
constructor(timeout: number) {
|
|
30
|
+
super(`No message received in ${timeout}ms`);
|
|
31
|
+
this.name = "TimeoutError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
22
35
|
/** Client call options. */
|
|
23
36
|
export interface ClientCallOptions {
|
|
24
37
|
signal?: AbortSignal;
|
|
25
38
|
}
|
|
26
39
|
|
|
27
40
|
export interface StreamDataOptions extends ClientCallOptions {
|
|
28
|
-
/** Stop at the specified cursor (inclusive) */
|
|
41
|
+
/** Stop at the specified cursor (inclusive). */
|
|
29
42
|
endingCursor?: Cursor;
|
|
43
|
+
/** Timeout between messages, in milliseconds. */
|
|
44
|
+
timeout?: number;
|
|
30
45
|
}
|
|
31
46
|
|
|
32
47
|
/** DNA client. */
|
|
@@ -44,20 +59,32 @@ export interface Client<TFilter, TBlock> {
|
|
|
44
59
|
): AsyncIterable<StreamDataResponse<TBlock>>;
|
|
45
60
|
}
|
|
46
61
|
|
|
62
|
+
export type CreateClientOptions = {
|
|
63
|
+
defaultCallOptions?: DefaultCallOptions<
|
|
64
|
+
NormalizedServiceDefinition<proto.stream.DnaStreamDefinition>
|
|
65
|
+
>;
|
|
66
|
+
credentials?: ChannelCredentials;
|
|
67
|
+
channelOptions?: ChannelOptions;
|
|
68
|
+
};
|
|
69
|
+
|
|
47
70
|
/** Create a client connecting to the DNA grpc service. */
|
|
48
71
|
export function createClient<TFilter, TBlock>(
|
|
49
72
|
config: StreamConfig<TFilter, TBlock>,
|
|
50
73
|
streamUrl: string,
|
|
51
|
-
|
|
52
|
-
NormalizedServiceDefinition<proto.stream.DnaStreamDefinition>
|
|
53
|
-
>,
|
|
74
|
+
options: CreateClientOptions = {},
|
|
54
75
|
) {
|
|
55
|
-
const channel = createChannel(
|
|
76
|
+
const channel = createChannel(
|
|
77
|
+
streamUrl,
|
|
78
|
+
options?.credentials,
|
|
79
|
+
options?.channelOptions,
|
|
80
|
+
);
|
|
81
|
+
|
|
56
82
|
const client: proto.stream.DnaStreamClient = grpcCreateClient(
|
|
57
83
|
proto.stream.DnaStreamDefinition,
|
|
58
84
|
channel,
|
|
59
|
-
defaultCallOptions,
|
|
85
|
+
options?.defaultCallOptions,
|
|
60
86
|
);
|
|
87
|
+
|
|
61
88
|
return new GrpcClient(config, client);
|
|
62
89
|
}
|
|
63
90
|
|
|
@@ -96,44 +123,61 @@ export class StreamDataIterable<TBlock> {
|
|
|
96
123
|
const inner = this.it[Symbol.asyncIterator]();
|
|
97
124
|
const schema = StreamDataResponse(this.schema);
|
|
98
125
|
const decoder = Schema.decodeSync(schema);
|
|
99
|
-
const { endingCursor } = this.options ?? {};
|
|
126
|
+
const { endingCursor, timeout = DEFAULT_TIMEOUT_MS } = this.options ?? {};
|
|
100
127
|
let shouldStop = false;
|
|
101
128
|
|
|
129
|
+
let clock: string | number | NodeJS.Timeout | undefined;
|
|
130
|
+
|
|
102
131
|
return {
|
|
103
132
|
async next() {
|
|
104
133
|
if (shouldStop) {
|
|
105
134
|
return { done: true, value: undefined };
|
|
106
135
|
}
|
|
107
136
|
|
|
108
|
-
|
|
137
|
+
// biome-ignore lint/suspicious/noExplicitAny: any is ok
|
|
138
|
+
const t: Promise<{ done: boolean; value: any }> = new Promise(
|
|
139
|
+
(_, reject) => {
|
|
140
|
+
clock = setTimeout(() => {
|
|
141
|
+
reject(new TimeoutError(timeout));
|
|
142
|
+
}, timeout);
|
|
143
|
+
},
|
|
144
|
+
);
|
|
109
145
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
146
|
+
try {
|
|
147
|
+
const { done, value } = await Promise.race([inner.next(), t]);
|
|
113
148
|
|
|
114
|
-
|
|
149
|
+
clearTimeout(clock);
|
|
115
150
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
151
|
+
if (done || value.message === undefined) {
|
|
152
|
+
return { done: true, value: undefined };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const decodedMessage = decoder(value.message);
|
|
156
|
+
|
|
157
|
+
if (endingCursor) {
|
|
158
|
+
assert(value.message.$case === "data");
|
|
159
|
+
assert(decodedMessage._tag === "data");
|
|
119
160
|
|
|
120
|
-
|
|
121
|
-
|
|
161
|
+
const { orderKey, uniqueKey } = endingCursor;
|
|
162
|
+
const endCursor = decodedMessage.data.endCursor;
|
|
122
163
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
164
|
+
// Check if the orderKey matches
|
|
165
|
+
if (orderKey === endCursor?.orderKey) {
|
|
166
|
+
// If a uniqueKey is specified, it must also match
|
|
167
|
+
if (!uniqueKey || uniqueKey === endCursor.uniqueKey) {
|
|
168
|
+
shouldStop = true;
|
|
169
|
+
return { done: false, value: decodedMessage };
|
|
170
|
+
}
|
|
129
171
|
}
|
|
130
172
|
}
|
|
131
|
-
}
|
|
132
173
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
174
|
+
return {
|
|
175
|
+
done: false,
|
|
176
|
+
value: decodedMessage,
|
|
177
|
+
};
|
|
178
|
+
} finally {
|
|
179
|
+
clearTimeout(clock);
|
|
180
|
+
}
|
|
137
181
|
},
|
|
138
182
|
};
|
|
139
183
|
}
|
package/src/common.ts
CHANGED
|
@@ -63,3 +63,31 @@ export const CursorFromBytes = Schema.transform(
|
|
|
63
63
|
|
|
64
64
|
export const cursorToBytes = Schema.encodeSync(CursorFromBytes);
|
|
65
65
|
export const cursorFromBytes = Schema.decodeSync(CursorFromBytes);
|
|
66
|
+
|
|
67
|
+
export function isCursor(value: unknown): value is Cursor {
|
|
68
|
+
return Schema.is(Cursor)(value);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Normalize a cursor.
|
|
72
|
+
*
|
|
73
|
+
* The challenge is that the `Cursor` validator expects `uniqueKey` to be either a `0x${string}`
|
|
74
|
+
* or not present at all. Setting the field to `undefined` will result in a validation error.
|
|
75
|
+
*
|
|
76
|
+
* @param cursor The cursor to normalize
|
|
77
|
+
*/
|
|
78
|
+
export function normalizeCursor(cursor: {
|
|
79
|
+
orderKey: bigint;
|
|
80
|
+
uniqueKey: string | null;
|
|
81
|
+
}): Cursor {
|
|
82
|
+
if (cursor.uniqueKey !== null && cursor.uniqueKey.length > 0) {
|
|
83
|
+
const uniqueKey = cursor.uniqueKey as `0x${string}`;
|
|
84
|
+
return {
|
|
85
|
+
orderKey: BigInt(cursor.orderKey),
|
|
86
|
+
uniqueKey,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
orderKey: BigInt(cursor.orderKey),
|
|
92
|
+
};
|
|
93
|
+
}
|