@apibara/protocol 2.1.0-beta.4 → 2.1.0-beta.40
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/codec.cjs +242 -0
- package/dist/codec.cjs.map +1 -0
- package/dist/codec.d.cts +81 -0
- package/dist/codec.d.mts +81 -0
- package/dist/codec.d.ts +81 -0
- package/dist/codec.mjs +224 -0
- package/dist/codec.mjs.map +1 -0
- package/dist/index.cjs +43 -30
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -5
- package/dist/index.d.mts +4 -5
- package/dist/index.d.ts +4 -5
- package/dist/index.mjs +40 -22
- package/dist/index.mjs.map +1 -0
- package/dist/shared/{protocol.4b1cfe2c.d.cts → protocol.0e734e33.d.cts} +400 -247
- package/dist/shared/{protocol.4b1cfe2c.d.mts → protocol.21e66b9e.d.mts} +400 -247
- package/dist/shared/{protocol.e39e40d6.cjs → protocol.53f81a1e.cjs} +177 -177
- package/dist/shared/protocol.53f81a1e.cjs.map +1 -0
- package/dist/shared/{protocol.991ff9ad.mjs → protocol.68fdd897.mjs} +176 -171
- package/dist/shared/protocol.68fdd897.mjs.map +1 -0
- package/dist/shared/{protocol.4b1cfe2c.d.ts → protocol.8fb09325.d.ts} +400 -247
- package/dist/testing/index.cjs +26 -38
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +107 -54
- package/dist/testing/index.d.mts +107 -54
- package/dist/testing/index.d.ts +107 -54
- package/dist/testing/index.mjs +26 -38
- package/dist/testing/index.mjs.map +1 -0
- package/package.json +8 -3
- package/src/client.ts +39 -14
- package/src/codec.ts +662 -0
- package/src/common.ts +70 -53
- package/src/config.ts +4 -4
- package/src/proto/google/protobuf/duration.ts +8 -6
- package/src/proto/stream.ts +38 -24
- package/src/status.ts +9 -16
- package/src/stream.ts +145 -144
- package/src/testing/mock.ts +36 -38
- package/src/common.test.ts +0 -67
- package/src/status.test.ts +0 -51
- package/src/stream.test-d.ts +0 -33
- package/src/stream.test.ts +0 -254
- package/src/testing/client.test.ts +0 -97
- package/src/testing/mock.test.ts +0 -35
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { s as stream, t as testing, C as Cursor, D as DnaStreamDefinition, S as StreamDataResponse } from './shared/protocol.
|
|
2
|
-
export { B as
|
|
3
|
-
import {
|
|
4
|
-
import { createChannel, createClient as createClient$1 } from 'nice-grpc';
|
|
5
|
-
export { ClientError, Status } from 'nice-grpc';
|
|
6
|
-
import 'protobufjs/minimal.js';
|
|
1
|
+
import { s as stream, t as testing, C as Cursor, D as DnaStreamDefinition, S as StreamDataResponse } from './shared/protocol.68fdd897.mjs';
|
|
2
|
+
export { B as BytesFromUint8Array, a as CursorFromBytes, k as Data, b as DataFinality, d as DataProduction, e as DurationCodec, F as Finalize, H as Heartbeat, I as Invalidate, R as ResponseWithoutData, h as StdErr, g as StdOut, l as StreamConfig, f as StreamDataRequest, j as SystemMessage, c as createCursor, i as isCursor, n as normalizeCursor } from './shared/protocol.68fdd897.mjs';
|
|
3
|
+
import { MessageCodec, OptionalCodec } from './codec.mjs';
|
|
7
4
|
import assert from 'node:assert';
|
|
8
|
-
import '
|
|
5
|
+
import consola from 'consola';
|
|
6
|
+
import { createChannel, createClient as createClient$1, Metadata } from 'nice-grpc';
|
|
7
|
+
export { ClientError, Metadata, ServerError, Status } from 'nice-grpc';
|
|
8
|
+
import 'protobufjs/minimal.js';
|
|
9
9
|
import 'viem';
|
|
10
10
|
import 'long';
|
|
11
11
|
|
|
@@ -15,17 +15,13 @@ const index = {
|
|
|
15
15
|
testing: testing
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
const StatusRequest =
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
finalized: Schema.optional(Cursor),
|
|
25
|
-
starting: Schema.optional(Cursor)
|
|
18
|
+
const StatusRequest = MessageCodec({});
|
|
19
|
+
const StatusResponse = MessageCodec({
|
|
20
|
+
currentHead: OptionalCodec(Cursor),
|
|
21
|
+
lastIngested: OptionalCodec(Cursor),
|
|
22
|
+
finalized: OptionalCodec(Cursor),
|
|
23
|
+
starting: OptionalCodec(Cursor)
|
|
26
24
|
});
|
|
27
|
-
const statusResponseToProto = Schema.encodeSync(StatusResponse);
|
|
28
|
-
const statusResponseFromProto = Schema.decodeSync(StatusResponse);
|
|
29
25
|
|
|
30
26
|
var __defProp$1 = Object.defineProperty;
|
|
31
27
|
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -53,19 +49,40 @@ function createClient(config, streamUrl, options = {}) {
|
|
|
53
49
|
);
|
|
54
50
|
return new GrpcClient(config, client);
|
|
55
51
|
}
|
|
52
|
+
function createAuthenticatedClient(config, streamUrl, options) {
|
|
53
|
+
const dnaToken = process.env.DNA_TOKEN;
|
|
54
|
+
if (!dnaToken) {
|
|
55
|
+
consola.warn(
|
|
56
|
+
"DNA_TOKEN environment variable is not set. Trying to connect without authentication."
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return createClient(config, streamUrl, {
|
|
60
|
+
...options,
|
|
61
|
+
defaultCallOptions: {
|
|
62
|
+
...options?.defaultCallOptions ?? {},
|
|
63
|
+
"*": {
|
|
64
|
+
metadata: Metadata({
|
|
65
|
+
Authorization: `Bearer ${dnaToken}`
|
|
66
|
+
}),
|
|
67
|
+
// metadata cant be overrided with spread as its a class so we override it fully if user provided it.
|
|
68
|
+
...options?.defaultCallOptions?.["*"] ?? {}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
56
73
|
class GrpcClient {
|
|
57
74
|
constructor(config, client) {
|
|
58
75
|
this.config = config;
|
|
59
76
|
this.client = client;
|
|
60
77
|
__publicField$1(this, "encodeRequest");
|
|
61
|
-
this.encodeRequest =
|
|
78
|
+
this.encodeRequest = config.Request.encode;
|
|
62
79
|
}
|
|
63
80
|
async status(request, options) {
|
|
64
81
|
const response = await this.client.status(
|
|
65
|
-
|
|
82
|
+
StatusRequest.encode(request ?? {}),
|
|
66
83
|
options
|
|
67
84
|
);
|
|
68
|
-
return
|
|
85
|
+
return StatusResponse.decode(response);
|
|
69
86
|
}
|
|
70
87
|
streamData(request, options) {
|
|
71
88
|
const it = this.client.streamData(this.encodeRequest(request), options);
|
|
@@ -81,7 +98,7 @@ class StreamDataIterable {
|
|
|
81
98
|
[Symbol.asyncIterator]() {
|
|
82
99
|
const inner = this.it[Symbol.asyncIterator]();
|
|
83
100
|
const schema = StreamDataResponse(this.schema);
|
|
84
|
-
const decoder =
|
|
101
|
+
const decoder = schema.decode;
|
|
85
102
|
const { endingCursor, timeout = DEFAULT_TIMEOUT_MS } = this.options ?? {};
|
|
86
103
|
let shouldStop = false;
|
|
87
104
|
let clock;
|
|
@@ -176,4 +193,5 @@ class RateGauge {
|
|
|
176
193
|
}
|
|
177
194
|
}
|
|
178
195
|
|
|
179
|
-
export { Cursor, DnaStreamDefinition, GrpcClient, RateGauge, StatusRequest, StatusResponse, StreamDataIterable, StreamDataResponse, TimeoutError, createClient, index as proto
|
|
196
|
+
export { Cursor, DnaStreamDefinition, GrpcClient, RateGauge, StatusRequest, StatusResponse, StreamDataIterable, StreamDataResponse, TimeoutError, createAuthenticatedClient, createClient, index as proto };
|
|
197
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/status.ts","../src/client.ts","../src/rate.ts"],"sourcesContent":["import { type CodecType, MessageCodec, OptionalCodec } from \"./codec\";\nimport { Cursor } from \"./common\";\n\n/** The request to the `status` endpoint. */\nexport const StatusRequest = MessageCodec({});\n\nexport type StatusRequest = CodecType<typeof StatusRequest>;\n\n/** The response from the `status` endpoint. */\nexport const StatusResponse = MessageCodec({\n currentHead: OptionalCodec(Cursor),\n lastIngested: OptionalCodec(Cursor),\n finalized: OptionalCodec(Cursor),\n starting: OptionalCodec(Cursor),\n});\n\nexport type StatusResponse = CodecType<typeof StatusResponse>;\n","import assert from \"node:assert\";\n\nimport consola from \"consola\";\nimport {\n type ChannelCredentials,\n type ChannelOptions,\n type DefaultCallOptions,\n Metadata,\n type NormalizedServiceDefinition,\n createChannel,\n createClient as grpcCreateClient,\n} from \"nice-grpc\";\n\nimport * as proto from \"./proto\";\n\nimport type { Codec } from \"./codec\";\nimport type { Cursor } from \"./common\";\nimport type { StreamConfig } from \"./config\";\nimport { StatusRequest, StatusResponse } from \"./status\";\nimport { type StreamDataRequest, StreamDataResponse } from \"./stream\";\n\nexport { ClientError, ServerError, Status, Metadata } from \"nice-grpc\";\n\nconst DEFAULT_TIMEOUT_MS = 45_000;\n\nexport class TimeoutError extends Error {\n constructor(timeout: number) {\n super(`No message received in ${timeout}ms`);\n this.name = \"TimeoutError\";\n }\n}\n\n/** Client call options. */\nexport interface ClientCallOptions {\n signal?: AbortSignal;\n}\n\nexport interface StreamDataOptions extends ClientCallOptions {\n /** Stop at the specified cursor (inclusive). */\n endingCursor?: Cursor;\n /** Timeout between messages, in milliseconds. */\n timeout?: number;\n}\n\n/** DNA client. */\nexport interface Client<TFilter, TBlock> {\n /** Fetch the DNA stream status. */\n status(\n request?: StatusRequest,\n options?: ClientCallOptions,\n ): Promise<StatusResponse>;\n\n /** Start streaming data from the DNA server. */\n streamData(\n request: StreamDataRequest<TFilter>,\n options?: StreamDataOptions,\n ): AsyncIterable<StreamDataResponse<TBlock>>;\n}\n\nexport type CreateClientOptions = {\n defaultCallOptions?: DefaultCallOptions<\n NormalizedServiceDefinition<proto.stream.DnaStreamDefinition>\n >;\n credentials?: ChannelCredentials;\n channelOptions?: ChannelOptions;\n};\n\n/** Create a client connecting to the DNA grpc service. */\nexport function createClient<TFilter, TBlock>(\n config: StreamConfig<TFilter, TBlock>,\n streamUrl: string,\n options: CreateClientOptions = {},\n) {\n const channel = createChannel(\n streamUrl,\n options?.credentials,\n options?.channelOptions,\n );\n\n const client: proto.stream.DnaStreamClient = grpcCreateClient(\n proto.stream.DnaStreamDefinition,\n channel,\n options?.defaultCallOptions,\n );\n\n return new GrpcClient(config, client);\n}\n\nexport function createAuthenticatedClient<TFilter, TBlock>(\n config: StreamConfig<TFilter, TBlock>,\n streamUrl: string,\n options?: CreateClientOptions,\n) {\n const dnaToken = process.env.DNA_TOKEN;\n if (!dnaToken) {\n consola.warn(\n \"DNA_TOKEN environment variable is not set. Trying to connect without authentication.\",\n );\n }\n\n return createClient(config, streamUrl, {\n ...options,\n defaultCallOptions: {\n ...(options?.defaultCallOptions ?? {}),\n \"*\": {\n metadata: Metadata({\n Authorization: `Bearer ${dnaToken}`,\n }),\n // metadata cant be overrided with spread as its a class so we override it fully if user provided it.\n ...(options?.defaultCallOptions?.[\"*\"] ?? {}),\n },\n },\n });\n}\n\nexport class GrpcClient<TFilter, TBlock> implements Client<TFilter, TBlock> {\n private encodeRequest;\n\n constructor(\n private config: StreamConfig<TFilter, TBlock>,\n private client: proto.stream.DnaStreamClient,\n ) {\n this.encodeRequest = config.Request.encode;\n }\n\n async status(request?: StatusRequest, options?: ClientCallOptions) {\n const response = await this.client.status(\n StatusRequest.encode(request ?? {}),\n options,\n );\n return StatusResponse.decode(response);\n }\n\n streamData(request: StreamDataRequest<TFilter>, options?: StreamDataOptions) {\n const it = this.client.streamData(this.encodeRequest(request), options);\n return new StreamDataIterable(it, this.config.Block, options);\n }\n}\n\nexport class StreamDataIterable<TBlock> {\n constructor(\n private it: AsyncIterable<proto.stream.StreamDataResponse>,\n private schema: Codec<TBlock, Uint8Array>,\n private options?: StreamDataOptions,\n ) {}\n\n [Symbol.asyncIterator](): AsyncIterator<StreamDataResponse<TBlock>> {\n const inner = this.it[Symbol.asyncIterator]();\n const schema = StreamDataResponse(this.schema);\n const decoder = schema.decode;\n const { endingCursor, timeout = DEFAULT_TIMEOUT_MS } = this.options ?? {};\n let shouldStop = false;\n\n let clock: string | number | NodeJS.Timeout | undefined;\n\n return {\n async next() {\n if (shouldStop) {\n return { done: true, value: undefined };\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: any is ok\n const t: Promise<{ done: boolean; value: any }> = new Promise(\n (_, reject) => {\n clock = setTimeout(() => {\n reject(new TimeoutError(timeout));\n }, timeout);\n },\n );\n\n try {\n const { done, value } = await Promise.race([inner.next(), t]);\n\n clearTimeout(clock);\n\n if (done || value.message === undefined) {\n return { done: true, value: undefined };\n }\n\n const decodedMessage = decoder(value.message);\n\n if (endingCursor) {\n assert(value.message.$case === \"data\");\n assert(decodedMessage._tag === \"data\");\n\n const { orderKey, uniqueKey } = endingCursor;\n const endCursor = decodedMessage.data.endCursor;\n\n // Check if the orderKey matches\n if (orderKey === endCursor?.orderKey) {\n // If a uniqueKey is specified, it must also match\n if (!uniqueKey || uniqueKey === endCursor.uniqueKey) {\n shouldStop = true;\n return { done: false, value: decodedMessage };\n }\n }\n }\n\n return {\n done: false,\n value: decodedMessage,\n };\n } finally {\n clearTimeout(clock);\n }\n },\n };\n }\n}\n","/** Track data rate using high precision timers. */\nexport class RateGauge {\n private interval: number;\n private prev?: bigint;\n private rateMs?: number;\n private var: number;\n\n constructor(intervalSeconds: number) {\n // Convert seconds to milliseconds.\n this.interval = intervalSeconds * 1_000;\n this.var = 0;\n }\n\n public record(items: number) {\n // Compute the exponential moving average of the rate.\n const prev = this.prev;\n const now = process.hrtime.bigint();\n this.prev = now;\n\n if (!prev) {\n return;\n }\n\n const deltaMs = Number(now - prev) / 1_000_000;\n // rate in items/ms.\n const rateMs = items / deltaMs;\n\n if (this.rateMs === undefined) {\n this.rateMs = rateMs;\n this.var = 0;\n return;\n }\n\n const alpha = 1 - Math.exp(-deltaMs / this.interval);\n this.rateMs = alpha * rateMs + (1 - alpha) * this.rateMs;\n\n const diff = rateMs - this.rateMs;\n const incr = alpha * diff;\n this.var = (1 - alpha) * (this.var + incr * diff);\n }\n\n /** Returns the average rate per second. */\n public average() {\n if (this.rateMs === undefined) {\n return undefined;\n }\n return this.rateMs * 1_000;\n }\n\n /** Returns the variance. */\n public variance() {\n return this.var;\n }\n}\n"],"names":["grpcCreateClient","proto.stream.DnaStreamDefinition","__publicField"],"mappings":"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"}
|