@river-build/sdk
Version:
For more details, visit the following resources:
91 lines • 3.82 kB
JavaScript
import { createClient } from '@connectrpc/connect';
import { StreamService } from '@river-build/proto';
import { dlog } from '@river-build/dlog';
import { getEnvVar, randomUrlSelector } from './utils';
import { DEFAULT_RETRY_PARAMS, getRetryDelayMs, loggingInterceptor, retryInterceptor, } from './rpcInterceptors';
import { unpackMiniblock } from './sign';
import { createHttp2ConnectTransport } from './rpcCommon';
import { streamIdAsBytes } from './id';
const logInfo = dlog('csb:rpc:info');
let nextRpcClientNum = 0;
export function makeStreamRpcClient(dest, refreshNodeUrl, opts) {
const transportId = nextRpcClientNum++;
const retryParams = opts?.retryParams ?? DEFAULT_RETRY_PARAMS;
logInfo('makeStreamRpcClient, transportId =', transportId);
const url = randomUrlSelector(dest);
logInfo('makeStreamRpcClient: Connecting to url=', url, ' allUrls=', dest);
const options = {
baseUrl: url,
interceptors: [
...(opts?.interceptors ?? []),
loggingInterceptor(transportId),
retryInterceptor({ ...retryParams, refreshNodeUrl }),
],
defaultTimeoutMs: undefined, // default timeout is undefined, we add a timeout in the retryInterceptor
};
if (getEnvVar('RIVER_DEBUG_TRANSPORT') !== 'true') {
options.useBinaryFormat = true;
}
else {
logInfo('makeStreamRpcClient: running in debug mode, using JSON format');
options.useBinaryFormat = false;
options.jsonOptions = {
alwaysEmitImplicit: true,
useProtoFieldName: true,
};
}
const transport = createHttp2ConnectTransport(options);
const client = createClient(StreamService, transport);
client.url = url;
client.opts = { retryParams };
return client;
}
export function getMaxTimeoutMs(opts) {
let maxTimeoutMs = 0;
for (let i = 1; i <= opts.retryParams.maxAttempts; i++) {
maxTimeoutMs +=
opts.retryParams.defaultTimeoutMs ?? 0 + getRetryDelayMs(i, opts.retryParams);
}
return maxTimeoutMs;
}
export async function getMiniblocks(client, streamId, fromInclusive, toExclusive, unpackEnvelopeOpts) {
const allMiniblocks = [];
let currentFromInclusive = fromInclusive;
let reachedTerminus = false;
while (currentFromInclusive < toExclusive) {
const { miniblocks, terminus, nextFromInclusive } = await fetchMiniblocksFromRpc(client, streamId, currentFromInclusive, toExclusive, unpackEnvelopeOpts);
allMiniblocks.push(...miniblocks);
// Set the terminus to true if we got at least one response with reached terminus
// The behaviour around this flag is not implemented yet
if (terminus && !reachedTerminus) {
reachedTerminus = true;
}
if (currentFromInclusive === nextFromInclusive) {
break;
}
currentFromInclusive = nextFromInclusive;
}
return {
miniblocks: allMiniblocks,
terminus: reachedTerminus,
};
}
async function fetchMiniblocksFromRpc(client, streamId, fromInclusive, toExclusive, unpackEnvelopeOpts) {
const response = await client.getMiniblocks({
streamId: streamIdAsBytes(streamId),
fromInclusive,
toExclusive,
});
const miniblocks = [];
for (const miniblock of response.miniblocks) {
const unpackedMiniblock = await unpackMiniblock(miniblock, unpackEnvelopeOpts);
miniblocks.push(unpackedMiniblock);
}
const respondedFromInclusive = miniblocks.length > 0 ? miniblocks[0].header.miniblockNum : fromInclusive;
return {
miniblocks: miniblocks,
terminus: response.terminus,
nextFromInclusive: respondedFromInclusive + BigInt(response.miniblocks.length),
};
}
//# sourceMappingURL=makeStreamRpcClient.js.map