/** * The client half of the `http` generator — see * docs/specs/2026-07-23-http-service-generator.md §4. * * A pure async function: given an endpoint, a count, and the input values for * one batch, it POSTs the §4 request and returns exactly `count` values in * order. It knows the wire contract and the error model, and nothing about * sequences or the engine — the caller wraps a thrown error with the sequence * name and a TDC code. * * Batch, never per-row: one call carries a whole chunk, which is what keeps a * billion rows to a thousand requests rather than a billion. */ /** Why a service call failed. The caller turns this into a TDC diagnostic. */ export type HttpFailureKind = 'status' | 'rate-limited' | 'timeout' | 'network' | 'count-mismatch' | 'too-large'; /** * The most of a reply this client will hold. The contract is one value per * line for `count` rows — a bounded, known-small answer — so a body that * outgrows this is a misbehaving service, and reading it to the end would * trade an error message for an OOM. The same limit lives in the other four * implementations. */ export declare const MAX_RESPONSE_BYTES: number; export declare class HttpServiceError extends Error { readonly kind: HttpFailureKind; readonly url: string; readonly status?: number | undefined; constructor(message: string, kind: HttpFailureKind, url: string, status?: number | undefined); } export type OnError = 'fail' | 'empty'; export interface HttpFetchOptions { readonly src: string; /** How many values are wanted — travels as `X-TDC-Count` and bounds the reply. */ readonly count: number; /** One line per input value, in row order. Omit/empty for a pure source. */ readonly inputs?: readonly string[] | undefined; /** * Travels as `X-TDC-Seed`. Derived per SEQUENCE, not the raw `` seed: * two http sequences pointed at one service must not receive the same seed, * or a service that generates from it would hand back two identical columns. */ readonly seed?: string | undefined; readonly onError: OnError; readonly timeoutMs: number; /** * The already-resolved `secret=`, if the config carries one. * * Present means the request is SIGNED: `X-TDC-Timestamp` and * `X-TDC-Signature` travel with it and the service can tell the generator from * anyone else who can reach the port. The secret itself never goes on the * wire. Resolution is the caller's job — see `resolveHttpSecret`. */ readonly secret?: string | undefined; /** * Wall-clock milliseconds stamped into the signature. * * The REAL clock, not the run's pinned `now`: it exists so a service can * refuse a request replayed tomorrow, and a config pinned to last year would * be refused by every service that checks. Injectable so a test can pin it. */ readonly nowMs?: number | undefined; } /** * The headers that say what this request IS, beyond its body. * * `X-TDC-Input` is the one that closes a real ambiguity: `in=` naming a column * of one empty value produced an empty body, which is exactly what a pure * source sends, and the service could not tell "process this empty value" from * "invent one". It carries the number of input lines, so zero-versus-absent is * the whole answer, and a service that ignores it behaves as it always did. */ export declare function contractHeaders(opts: HttpFetchOptions, body: string): Record; /** * `hex(HMAC-SHA256(secret, timestamp \n seed \n count \n body))`. * * Everything that decides what comes back is inside: change the body, the count, * the seed or the minute, and the signature no longer matches. The secret is the * key, so it is never sent — which is what makes this safe over plain http on a * trusted network, and what makes a captured request useless tomorrow once the * service checks the timestamp. */ export declare function signRequest(secret: string, timestamp: string, seed: string, count: number, body: string): string; /** * The value sent as `X-TDC-Seed`: eight hex digits derived from the env seed and * the sequence name, using the same hash the engine uses for its own per-stream * keys. Stable across runs, so a service can reproduce its own answers, and * different for every sequence, so two of them never receive the same stream. * * Beside the signature rather than inside the renderer because it is part of the * same wire contract, and because a service author reading either one wants both. * The four ports have always kept it here. */ export declare function httpSeedFor(envSeed: string, sequenceName: string): string; /** * Run one batch against the service. Resolves with exactly `count` strings. * * `on_error="fail"` throws an {@link HttpServiceError}; `"empty"` returns * `count` blanks instead — EXCEPT for 429, which is fatal under both, because * "slow down" and "stream the whole column" cannot be reconciled and pretending * otherwise yields quietly truncated data. */ export declare function fetchHttpValues(opts: HttpFetchOptions): Promise; //# sourceMappingURL=http.d.ts.map