@apibara/protocol 0.4.1 → 0.4.3

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/client.d.ts CHANGED
@@ -55,6 +55,10 @@ export declare type StreamClientArgs = {
55
55
  * Grpc client options.
56
56
  */
57
57
  clientOptions?: ClientOptions;
58
+ /**
59
+ * Authorization bearer token, used to authenticate with the server.
60
+ */
61
+ token?: string;
58
62
  /**
59
63
  * Callback to control reconnection after receiving an error from the stream.
60
64
  *
@@ -90,7 +94,7 @@ export declare class StreamClient {
90
94
  * }
91
95
  * ```
92
96
  */
93
- constructor({ url, credentials, clientOptions, onReconnect }: StreamClientArgs);
97
+ constructor({ url, credentials, clientOptions, token, onReconnect }: StreamClientArgs);
94
98
  /**
95
99
  * Async iterator over messages in the stream.
96
100
  */
package/dist/client.js CHANGED
@@ -7,6 +7,8 @@ const request_1 = require("./request");
7
7
  var grpc_js_2 = require("@grpc/grpc-js");
8
8
  Object.defineProperty(exports, "ChannelCredentials", { enumerable: true, get: function () { return grpc_js_2.ChannelCredentials; } });
9
9
  const StreamService = proto_1.v1alpha2.protoDescriptor.apibara.node.v1alpha2.Stream;
10
+ // Server produces an heartbeat every 30 seconds, so we use 45 seconds as a timeout.
11
+ const MESSAGE_TIMEOUT_MS = 45000;
10
12
  /**
11
13
  * A client to configure and stream data.
12
14
  */
@@ -30,8 +32,10 @@ class StreamClient {
30
32
  * }
31
33
  * ```
32
34
  */
33
- constructor({ url, credentials, clientOptions, onReconnect }) {
34
- this.inner = new StreamService(url, credentials ?? grpc_js_1.ChannelCredentials.createSsl(), {
35
+ constructor({ url, credentials, clientOptions, token, onReconnect }) {
36
+ const baseCredentials = credentials ?? grpc_js_1.ChannelCredentials.createSsl();
37
+ const credentialsWithMetadata = baseCredentials.compose(grpc_js_1.CallCredentials.createFromMetadataGenerator(createMetadataGenerator(token)));
38
+ this.inner = new StreamService(url, credentialsWithMetadata, {
35
39
  'grpc.keepalive_timeout_ms': 3600000,
36
40
  ...clientOptions,
37
41
  });
@@ -53,13 +57,22 @@ class StreamClient {
53
57
  while (true) {
54
58
  let retryCount = 1;
55
59
  let cursor = null;
60
+ let clock;
56
61
  try {
57
62
  // this check is to make ts happy
58
63
  if (!this.stream) {
59
64
  throw new Error('Stream disconnected unexpectedly');
60
65
  }
61
- for await (const message of this.stream) {
62
- const messageTyped = message;
66
+ const streamIter = this.stream[Symbol.asyncIterator]();
67
+ while (true) {
68
+ const timeout = new Promise((_, reject) => {
69
+ clock = setTimeout(() => {
70
+ reject(new Error('Stream timed out'));
71
+ }, MESSAGE_TIMEOUT_MS);
72
+ });
73
+ const message = (await Promise.race([streamIter.next(), timeout]));
74
+ const messageTyped = message.value;
75
+ clearTimeout(clock);
63
76
  // only return messages if they are with the most recently configured stream
64
77
  if (messageTyped.streamId?.toString() == this.stream_id.toString()) {
65
78
  // reset retry count on new message
@@ -76,6 +89,7 @@ class StreamClient {
76
89
  }
77
90
  }
78
91
  catch (err) {
92
+ clearTimeout(clock);
79
93
  const isGrpcError = err.hasOwnProperty('code') &&
80
94
  err.hasOwnProperty('details') &&
81
95
  err.hasOwnProperty('metadata');
@@ -167,4 +181,16 @@ async function defaultOnReconnect(err, retryCount) {
167
181
  };
168
182
  }
169
183
  exports.defaultOnReconnect = defaultOnReconnect;
184
+ /*
185
+ * Returns a generator that adds the given `token` to request metadata.
186
+ */
187
+ function createMetadataGenerator(token) {
188
+ const metadata = new grpc_js_1.Metadata();
189
+ if (token) {
190
+ metadata.add('authorization', `bearer ${token}`);
191
+ }
192
+ return (_options, cb) => {
193
+ cb(null, metadata);
194
+ };
195
+ }
170
196
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apibara/protocol",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/client.ts CHANGED
@@ -1,4 +1,12 @@
1
- import { ChannelCredentials, ClientDuplexStream, ClientOptions, StatusObject } from '@grpc/grpc-js'
1
+ import {
2
+ CallCredentials,
3
+ ChannelCredentials,
4
+ ClientDuplexStream,
5
+ ClientOptions,
6
+ Metadata,
7
+ StatusObject,
8
+ } from '@grpc/grpc-js'
9
+ import { CallMetadataGenerator } from '@grpc/grpc-js/build/src/call-credentials'
2
10
  import { v1alpha2 } from './proto'
3
11
  import { StreamDataRequest } from './request'
4
12
 
@@ -6,6 +14,9 @@ export { ChannelCredentials, StatusObject } from '@grpc/grpc-js'
6
14
 
7
15
  const StreamService = v1alpha2.protoDescriptor.apibara.node.v1alpha2.Stream
8
16
 
17
+ // Server produces an heartbeat every 30 seconds, so we use 45 seconds as a timeout.
18
+ const MESSAGE_TIMEOUT_MS = 45_000
19
+
9
20
  export type DataStream = ClientDuplexStream<
10
21
  v1alpha2.IStreamDataRequest,
11
22
  v1alpha2.IStreamDataResponse
@@ -76,6 +87,11 @@ export type StreamClientArgs = {
76
87
  * Grpc client options.
77
88
  */
78
89
  clientOptions?: ClientOptions
90
+
91
+ /**
92
+ * Authorization bearer token, used to authenticate with the server.
93
+ */
94
+ token?: string
79
95
  /**
80
96
  * Callback to control reconnection after receiving an error from the stream.
81
97
  *
@@ -114,8 +130,12 @@ export class StreamClient {
114
130
  * }
115
131
  * ```
116
132
  */
117
- constructor({ url, credentials, clientOptions, onReconnect }: StreamClientArgs) {
118
- this.inner = new StreamService(url, credentials ?? ChannelCredentials.createSsl(), {
133
+ constructor({ url, credentials, clientOptions, token, onReconnect }: StreamClientArgs) {
134
+ const baseCredentials = credentials ?? ChannelCredentials.createSsl()
135
+ const credentialsWithMetadata = baseCredentials.compose(
136
+ CallCredentials.createFromMetadataGenerator(createMetadataGenerator(token))
137
+ )
138
+ this.inner = new StreamService(url, credentialsWithMetadata, {
119
139
  'grpc.keepalive_timeout_ms': 3_600_000,
120
140
  ...clientOptions,
121
141
  })
@@ -140,14 +160,27 @@ export class StreamClient {
140
160
  while (true) {
141
161
  let retryCount = 1
142
162
  let cursor = null
163
+ let clock
143
164
  try {
144
165
  // this check is to make ts happy
145
166
  if (!this.stream) {
146
167
  throw new Error('Stream disconnected unexpectedly')
147
168
  }
148
169
 
149
- for await (const message of this.stream) {
150
- const messageTyped = message as v1alpha2.IStreamDataResponse
170
+ const streamIter = this.stream[Symbol.asyncIterator]()
171
+ while (true) {
172
+ const timeout = new Promise((_, reject) => {
173
+ clock = setTimeout(() => {
174
+ reject(new Error('Stream timed out'))
175
+ }, MESSAGE_TIMEOUT_MS)
176
+ })
177
+
178
+ const message = <IteratorResult<v1alpha2.IStreamDataResponse>>(
179
+ await Promise.race([streamIter.next(), timeout])
180
+ )
181
+ const messageTyped = message.value as v1alpha2.IStreamDataResponse
182
+
183
+ clearTimeout(clock)
151
184
 
152
185
  // only return messages if they are with the most recently configured stream
153
186
  if (messageTyped.streamId?.toString() == this.stream_id.toString()) {
@@ -165,6 +198,8 @@ export class StreamClient {
165
198
  }
166
199
  }
167
200
  } catch (err: any) {
201
+ clearTimeout(clock)
202
+
168
203
  const isGrpcError =
169
204
  err.hasOwnProperty('code') &&
170
205
  err.hasOwnProperty('details') &&
@@ -269,3 +304,17 @@ export async function defaultOnReconnect(
269
304
  reconnect: retryCount < 5,
270
305
  }
271
306
  }
307
+
308
+ /*
309
+ * Returns a generator that adds the given `token` to request metadata.
310
+ */
311
+ function createMetadataGenerator(token?: string): CallMetadataGenerator {
312
+ const metadata = new Metadata()
313
+ if (token) {
314
+ metadata.add('authorization', `bearer ${token}`)
315
+ }
316
+
317
+ return (_options, cb) => {
318
+ cb(null, metadata)
319
+ }
320
+ }