@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.
@@ -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.4",
3
+ "version": "2.0.0-beta.41",
4
4
  "type": "module",
5
- "source": "./src/index.ts",
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
- defaultCallOptions?: DefaultCallOptions<
52
- NormalizedServiceDefinition<proto.stream.DnaStreamDefinition>
53
- >,
74
+ options: CreateClientOptions = {},
54
75
  ) {
55
- const channel = createChannel(streamUrl);
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
- const { done, value } = await inner.next();
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
- if (done || value.message === undefined) {
111
- return { done: true, value: undefined };
112
- }
146
+ try {
147
+ const { done, value } = await Promise.race([inner.next(), t]);
113
148
 
114
- const decodedMessage = decoder(value.message);
149
+ clearTimeout(clock);
115
150
 
116
- if (endingCursor) {
117
- assert(value.message.$case === "data");
118
- assert(decodedMessage._tag === "data");
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
- const { orderKey, uniqueKey } = endingCursor;
121
- const endCursor = decodedMessage.data.endCursor;
161
+ const { orderKey, uniqueKey } = endingCursor;
162
+ const endCursor = decodedMessage.data.endCursor;
122
163
 
123
- // Check if the orderKey matches
124
- if (orderKey === endCursor?.orderKey) {
125
- // If a uniqueKey is specified, it must also match
126
- if (!uniqueKey || uniqueKey === endCursor.uniqueKey) {
127
- shouldStop = true;
128
- return { done: false, value: decodedMessage };
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
- return {
134
- done: false,
135
- value: decodedMessage,
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
+ }
@@ -6,7 +6,7 @@
6
6
 
7
7
  /* eslint-disable */
8
8
  import Long from "long";
9
- import _m0 from "protobufjs/minimal";
9
+ import _m0 from "protobufjs/minimal.js";
10
10
 
11
11
  export const protobufPackage = "google.protobuf";
12
12