import { RequestError, RequestErrorCode } from "@lodestar/reqresp";
/**
 * Sink for `<response_chunk>*`, from
 * ```bnf
 * response ::= <response_chunk>*
 * ```
 * Expects exactly one response
 */
export async function collectExactOneTyped(source, typeFn) {
    for await (const chunk of source) {
        const type = typeFn(chunk.fork, chunk.protocolVersion);
        const response = sszDeserializeResponse(type, chunk.data);
        return response;
    }
    throw new RequestError({ code: RequestErrorCode.EMPTY_RESPONSE });
}
/**
 * Sink for `<response_chunk>*`, from
 * ```bnf
 * response ::= <response_chunk>*
 * ```
 * Collects a bounded list of responses up to `maxResponses`
 */
export async function collectMaxResponseTyped(source, maxResponses, typeFn, serializedCache) {
    // else: zero or more responses
    const responses = [];
    for await (const chunk of source) {
        const type = typeFn(chunk.fork, chunk.protocolVersion);
        const response = sszDeserializeResponse(type, chunk.data);
        // optionally cache the serialized response if the cache is available
        serializedCache?.set(response, chunk.data);
        responses.push(response);
        if (maxResponses !== undefined && responses.length >= maxResponses) {
            break;
        }
    }
    return responses;
}
/**
 * Sink for `<response_chunk>*`, from
 * ```bnf
 * response ::= <response_chunk>*
 * ```
 * Collects a bounded list of responses up to `maxResponses`
 */
export async function collectMaxResponseTypedWithBytes(source, maxResponses, typeFn, serializedCache) {
    // else: zero or more responses
    const responses = [];
    for await (const chunk of source) {
        const type = typeFn(chunk.fork, chunk.protocolVersion);
        const data = sszDeserializeResponse(type, chunk.data);
        responses.push(data);
        // optionally cache the serialized response if the cache is available
        serializedCache?.set(data, chunk.data);
        if (maxResponses !== undefined && responses.length >= maxResponses) {
            break;
        }
    }
    return responses;
}
/** Light wrapper on type to wrap deserialize errors */
export function sszDeserializeResponse(type, bytes) {
    try {
        return type.deserialize(bytes);
    }
    catch (e) {
        throw new RequestError({ code: RequestErrorCode.INVALID_RESPONSE_SSZ, errorMessage: e.message });
    }
}
//# sourceMappingURL=collect.js.map