import { C as CompressionConfig, f as CompressionMiddlewareResult, R as RequestCompressionConfig, g as RequestCompressionMiddlewareResult, e as DefaultHttpClientConfig, h as HttpTransport, D as DefaultHttpClient, i as AdaptiveLimiter, H as HttpRequest, d as HttpMiddleware, L as LifecycleClientConfig, j as LifecycleClient, b as HttpWireResponse, c as HttpError, k as LifecycleEvent, l as HttpClientStats, m as LifecycleEventType, n as LifecycleStats, P as PrewarmResult, o as PrewarmStatusSnapshot, p as PrewarmConfig, q as HttpClientFn, r as PrewarmOriginState, s as HttpMethod, t as HttpStreamTransport, u as HttpPoolConfig, v as AdaptiveLimiterConfig, a as HttpClient, w as HttpClientStream, x as DefaultHttpClientPreset, y as DedupConfig$1, B as BatchConfig, z as CacheConfig$1, E as PriorityConfig$1, F as RetryPolicy, G as PrewarmLifecycleConfig, I as AdaptiveLimiterPreset } from '../defaultClient-DLOa3gdw.js'; export { J as AdaptiveAcquireOptions, K as AdaptiveBaselineStrategy, M as AdaptiveHeadroomContext, N as AdaptiveHeadroomMode, O as AdaptiveHeadroomStrategy, Q as AdaptiveLease, S as AdaptiveLimiterDiagnostics, T as AdaptiveLimiterKeySnapshot, A as AdaptiveLimiterStats, U as AdaptiveQueueLoadShedding, V as AdaptiveQueueStrategy, W as AdaptiveReleaseInfo, X as BatchFunction, Y as CachePolicyResult, Z as CompressionStats, _ as DecompressResult, $ as Decompressor, a0 as DefaultGetJson, a1 as DefaultHttpClientFeatures, a2 as DefaultPostJson, a3 as Dx, a4 as HttpBody, a5 as HttpClientStreamFn, a6 as HttpConcurrencyPool, a7 as HttpErrorHandlers, a8 as HttpInit, a9 as HttpJsonInit, aa as HttpMeta, ab as HttpPolicyPreset, ac as HttpPolicyPresets, ad as HttpPoolKeyResolver, ae as HttpPoolKeyStats, af as HttpPoolLease, ag as HttpPoolStats, ah as HttpPostJsonBodyInit, ai as HttpPostJsonInit, aj as HttpPostJsonSchemaBodyInit, ak as HttpRequestPolicy, al as HttpRequestPolicyRef, am as HttpRequestRetryOverride, an as HttpResponse, ao as HttpResponseWithMeta, ap as HttpRetryScheduleInput, aq as HttpTransportContext, ar as HttpTransportTiming, as as HttpWireResponseStream, at as HttpWireWithMeta, au as JsonDecodeResult, av as KnownHttpError, aw as KnownHttpErrorTag, ax as LifecycleRequestOptions, ay as LimitChangeEvent, az as MakeHttpConfig, aA as PerRequestRetryOverride, aB as PrewarmEvent, aC as PrewarmEventType, aD as PrewarmOriginStatus, aE as PrewarmResultStatus, aF as PromiseHttpTransportBodyBuilder, aG as PromiseHttpTransportBodySelector, aH as PromiseHttpTransportConfig, aI as PromiseHttpTransportConfigWithSignal, aJ as PromiseHttpTransportFluentResponseBuilder, aK as PromiseHttpTransportRequestConfigBuilder, aL as PromiseHttpTransportRequestConfigContext, aM as PromiseHttpTransportRequestConfigMapper, aN as PromiseHttpTransportResponse, aO as PromiseHttpTransportResponseInfo, aP as PromiseHttpTransportResponseInfoMapper, aQ as PromiseHttpTransportStartBuilder, aR as RequestCompressionStats, aS as ResolveHttpRequestPolicyOptions, aT as ResolvedConfig, aU as RetryEvent, aV as RetryScheduleInput, aW as RetryableHttpErrorOptions, aX as SUPPORTED_ENCODINGS, aY as SupportedEncoding, aZ as ToHttpErrorOptions, a_ as ValidationError, a$ as abortErrorForSignal, b0 as adaptiveLimiterPresets, b1 as backoffDelayMs, b2 as decodeJsonBody, b3 as decodeJsonBodyEffect, b4 as decorate, b5 as decorateStream, b6 as defaultHttpClientPreset, b7 as defaultRetryOnError, b8 as defaultRetryOnStatus, b9 as defaultRetryableMethods, ba as defineHttpPolicyPresets, bb as encodeJsonBodyEffect, bc as fetchLabel, bd as formatHttpError, be as getHttpRequestPolicy, bf as headersOf, bg as httpClient, bh as httpClientStream, bi as httpClientWithMeta, bj as httpErrorStatus, bk as httpPolicy, bl as isAbortError, bm as isAbortHttpError, bn as isCircuitBreakerOpen, bo as isExternalAbortError, bp as isExternalTimeoutError, bq as isFetchHttpError, br as isHttpError, bs as isKnownHttpError, bt as isPromiseTransportDirect, bu as isRetryableHttpError, bv as isRetryableHttpStatus, bw as isTaggedHttpError, bx as isTimeoutHttpError, by as isValidationError, bz as linkAbortSignals, bA as makeAdaptiveLimiter, bB as makeAdaptiveLimiterConfig, bC as makeDefaultHttpClient, bD as makeFetchStreamTransport, bE as makeFetchTransport, bF as makeHttp, bG as makeHttpStats, bH as makeHttpStream, bI as makeJsonParseValidationError, bJ as makePool, bK as makePromiseHttpTransport, bL as matchHttpError, bM as noopSignal, bN as normalizeHeadersInit, bO as normalizeHttpError, bP as normalizeHttpHeaders, bQ as normalizeRequest, bR as normalizeRetryBudget, bS as promiseHttpTransport, bT as releaseFailure, bU as releaseSuccess, bV as requestPriority, bW as resolveConfig, bX as resolveHttpPoolKey, bY as resolveHttpRequestPolicyPresets, bZ as resolvePositiveTimeout, b_ as resolveRequestUrl, b$ as retryAfterMs, c0 as runDirectTransport, c1 as runPoolTransport, c2 as runTransportEffect, c3 as timeoutReason, c4 as toHttpError, c5 as validateConfig, c6 as validatedJson, c7 as validatedJsonResponse, c8 as withBatch, c9 as withHttpPolicyPresets, ca as withHttpRequestPolicy, cb as withMiddleware, cc as withRetry, cd as withRetryStream } from '../defaultClient-DLOa3gdw.js'; import { Agent, Server } from 'node:http'; import { Agent as Agent$1 } from 'node:https'; import { c as CircuitBreakerConfig, l as Schedule, a as LayerContext, S as ServiceTag, L as Layer } from '../layer-CsNGeVee.js'; import { T as Tracer, R as Resource } from '../tracing-DIAUf2x8.js'; import { A as Async, b as Runtime, a as RuntimeOptions } from '../effect-DbEMiMvv.js'; import { AddressInfo } from 'node:net'; import { O as Observability, q as HttpServerObservabilityOptions, $ as RuntimeHealthOptions } from '../server-BGXOabjo.js'; import { AnyJsonSchemaLike, InferJsonSchema } from '../schema/index.js'; export { AnySchema, ConfigValidationError, InferObject, InferSchema, JsonSchemaLike, JsonValidator, JsonValidatorResult, NumberSchemaOptions, ObjectSchemaOptions, Schema, SchemaIssue, SchemaPathPart, SchemaResult, SchemaShape, SchemaValidationException, StringSchemaOptions, formatConfigError, formatIssues, isConfigValidationError, isSchema, makeSchemaIssue, parseConfig, s, schema, validateValue } from '../schema/index.js'; import '../stream-B8c_UKZq.js'; import '../tracer-CS3yOXZx.js'; /** * A fixed-size circular buffer that stores latency samples and supports * efficient min and percentile computation using the nearest-rank method. * * The ring preserves eviction order while `sorted` keeps an exact sorted view. * Recording is O(windowSize) because it removes/inserts by binary search + * splice, but percentile reads are O(1) and avoid sorting on every call. */ declare class LatencyWindow { private readonly buffer; private readonly sorted; private readonly size; private head; private count; constructor(size: number); /** * Record a latency sample. Discards non-positive, NaN, and Infinity values. * Evicts the oldest sample when the buffer is full. */ record(latencyMs: number): void; /** * Returns the minimum latency in the current window, or undefined if empty. */ min(): number | undefined; /** * Computes the percentile using the nearest-rank method. * Returns undefined if fewer than 2 samples are present. * @param p - Percentile value in [0, 100] */ percentile(p: number): number | undefined; /** * Computes a percentile where newer samples receive exponentially higher * weight. A decay of 1 is identical to `percentile`; lower values adapt * faster to recent latency shifts. */ weightedPercentile(p: number, decay: number): number | undefined; /** Number of samples currently in the window. */ get length(): number; /** Maximum capacity of the window. */ get capacity(): number; /** Returns a copy of the current samples (oldest to newest). */ samples(): number[]; private insertSorted; private removeSorted; private lowerBound; } /** * Exponential Moving Average computer. * Smooths latency samples using the formula: ema = α * sample + (1 - α) * previous_ema */ declare class EmaComputer { private readonly alpha; private current; /** * @param alpha - Smoothing factor in (0, 1]. Higher values weight recent samples more. */ constructor(alpha: number); /** * Update the EMA with a new sample and return the new EMA value. * On the first sample, the EMA is initialized to that sample. */ update(sample: number): number; /** Returns the current EMA value, or undefined if no samples have been recorded. */ get value(): number | undefined; /** Resets the EMA state. */ reset(): void; } /** * Computes the gradient as the ratio of minimum latency to current (smoothed) latency. * A gradient < 1.0 indicates latency is increasing (saturation). * A gradient >= 1.0 indicates latency is stable or decreasing. */ declare function computeGradient(minLatency: number, currentLatency: number): number; /** * Computes the new concurrency limit based on the gradient. * * - If gradient < decreaseThreshold: decrease toward `currentLimit * gradient` * - If gradient >= increaseThreshold: newLimit = currentLimit + headroom * - Otherwise: hold the current limit * * Decreases are capped by `maxDecreaseRatio` so a single noisy latency sample * cannot collapse concurrency. * * The result is clamped to [minBound, maxBound]. */ declare function computeNewLimit(currentLimit: number, gradient: number, headroom: number, minBound: number, maxBound: number, options?: { readonly decreaseThreshold?: number; readonly increaseThreshold?: number; readonly maxDecreaseRatio?: number; }): number; /** * Creates the compression middleware with optional configuration. * * The middleware: * 1. Injects Accept-Encoding header on outgoing requests (if missing) * 2. Decompresses response bodies based on Content-Encoding header * 3. Tracks compression statistics */ declare function makeCompressionMiddleware(config?: CompressionConfig): CompressionMiddlewareResult; declare const makeResponseCompressionMiddleware: typeof makeCompressionMiddleware; declare function makeRequestCompressionMiddleware(config?: RequestCompressionConfig): RequestCompressionMiddlewareResult; type NodeHttpTransportConfig = { readonly keepAlive?: boolean; readonly maxSockets?: number; readonly maxFreeSockets?: number; readonly httpAgent?: Agent; readonly httpsAgent?: Agent$1; readonly socketTimeoutMs?: number; }; type NodeHttpTransport = HttpTransport & { readonly destroy: () => void; }; type NodeHttpProxyClientConfig = Omit & { /** * Defaults to the explicit hot proxy preset. Use `proxy` only when you need * the shorter compatibility name in stats/config snapshots. */ readonly preset?: "highThroughputProxy" | "proxy"; /** Existing Node transport to use. When omitted, Brass creates owned keep-alive agents. */ readonly transport?: NodeHttpTransport; /** Options for the owned Node transport when `transport` is omitted. */ readonly nodeTransport?: NodeHttpTransportConfig; }; declare function makeNodeHttpTransport(config?: NodeHttpTransportConfig): NodeHttpTransport; declare function makeNodeHttpProxyClient(config?: NodeHttpProxyClientConfig): DefaultHttpClient; type HttpCircuitBreakerConfig = CircuitBreakerConfig & { /** Key resolver for per-origin circuit breakers. Default: per-origin. */ perOrigin?: boolean; /** Optional limiter to notify when this breaker is already/opened. Defaults to `next.adaptiveLimiter` when available. */ adaptiveLimiter?: Pick; /** Optional resolver when the limiter key differs from the request URL origin/global fallback. */ adaptiveLimiterKey?: (req: HttpRequest) => string; }; /** * HTTP middleware that wraps requests in a circuit breaker. * When the circuit opens, requests fail fast with CircuitBreakerOpen error. */ declare function withCircuitBreaker(config?: HttpCircuitBreakerConfig): HttpMiddleware; /** * HTTP middleware that creates a span for each request. */ declare function withTracing(tracer: Tracer): HttpMiddleware; /** * Creates a lifecycle-aware HTTP client that composes deduplication, caching, * and priority scheduling layers on top of the Wire_Client. * * When no layers are configured, the client delegates directly to the underlying * Wire_Client with zero additional overhead (zero-cost when disabled). Each layer * is independently optional and can be set to `false` to explicitly disable. * * Layer composition order (outermost to innermost): * - User middleware (applied via `.with()`) * - Dedup layer (if enabled) * - Cache layer (if enabled) * - Priority layer (if enabled) * - Wire_Client (`makeHttp`) * * @param config - Lifecycle client configuration extending `MakeHttpConfig` with optional layer settings. * - `config.baseUrl` — Base URL prepended to relative request paths. * - `config.headers` — Default headers merged into every request. * - `config.timeoutMs` — Request budget in milliseconds covering pool wait + fetch + body read. * - `config.dedup` — Deduplication layer config or `false` to disable. * - `config.dedup.dedupKey` — Custom key function overriding default key computation. * - `config.cache` — Response cache layer config or `false` to disable. * - `config.cache.ttlSeconds` — Time-to-live in seconds; integer between 1 and 86400 (default: 60). * - `config.cache.maxEntries` — Maximum cached entries; integer >= 1 (default: 1024). * - `config.cache.staleWhileRevalidate` — Enable stale-while-revalidate (default: false). * - `config.cache.cachePolicy` — Custom cache policy function. * - `config.cache.cacheRelevantHeaders` — Additional headers included in Cache_Key computation. * - `config.priority` — Priority scheduler layer config or `false` to disable. * - `config.priority.concurrency` — Maximum concurrent dispatched requests; integer >= 1 (default: 32). * - `config.priority.queueTimeoutMs` — Queue timeout in milliseconds for priority-queued requests. * - `config.onEvent` — Optional observer callback invoked on each lifecycle event. * * @returns A {@link LifecycleClient} instance that is callable as an `HttpClientFn` and exposes * `.with()` for middleware composition, `.stats()` for observability, `.cancelAll()` for * bulk cancellation, and `.cache` for cache management. * * @example * ```typescript * import { makeLifecycleClient } from "./index"; * import type { LifecycleClientConfig } from "./index"; * * const config: LifecycleClientConfig = { * baseUrl: "https://api.example.com", * cache: { ttlSeconds: 120, maxEntries: 512 }, * priority: { concurrency: 8 }, * dedup: {}, * }; * * const client = makeLifecycleClient(config); * * // Execute a GET request through all lifecycle layers * const response = client({ method: "GET", url: "/users" }); * ``` */ declare function makeLifecycleClient(config?: LifecycleClientConfig): LifecycleClient; /** * Canonical production HTTP client factory. * * Alias of {@link makeLifecycleClient}; kept as the recommended public name * for callers that want the stable wire -> priority -> retry -> cache -> dedup * lifecycle pipeline without importing lower-level building blocks. * * @param config - Lifecycle client configuration with optional wire, retry, cache, dedup, and priority settings. * @returns A lifecycle-aware HTTP client with stats, cache controls, middleware composition, and `cancelAll`. */ declare function makeHttpClient(config?: LifecycleClientConfig): LifecycleClient; /** * Components of a parsed Cache_Key, representing the individual parts * that make up a deterministic cache key string. * * @property method - The HTTP method (uppercase), e.g. "GET", "POST" * @property resolvedUrl - The fully resolved URL including base URL resolution * @property headers - Cache-relevant headers as key-value pairs (lowercase keys) * @property body - The request body string, or empty string if no body was present */ type CacheKeyComponents = { method: string; resolvedUrl: string; headers: Record; body: string; }; /** * Null character (`\u0000`) used as a separator between Cache_Key components. * * This non-printable character is chosen because it cannot appear in valid HTTP * method names, URLs, or header values, ensuring unambiguous key parsing via * `parseCacheKey`. */ declare const SEPARATOR = "\0"; /** * Default set of HTTP headers included in Cache_Key computation. * * Value: `["accept", "authorization", "content-type"]` * * These headers are always factored into the cache key to ensure that requests * with different content negotiation, authentication, or body encoding are * cached separately. Additional headers can be included via the `extraHeaders` * parameter of `computeCacheKey` or the `cacheRelevantHeaders` option in `CacheConfig`. */ declare const DEFAULT_CACHE_RELEVANT_HEADERS: string[]; /** * Computes a deterministic Cache_Key string from an HTTP request. * * The key is composed of: method (uppercase), resolved URL, sorted filtered headers, * and body — concatenated with null character separators. The resulting string * uniquely identifies a cacheable request and can be round-tripped via `parseCacheKey`. * * @param req - The HTTP request to compute a Cache_Key for * @param baseUrl - Base URL for resolving relative request URLs * @param extraHeaders - Additional header names to include in the Cache_Key beyond * the defaults in `DEFAULT_CACHE_RELEVANT_HEADERS` * @returns A deterministic Cache_Key string suitable for use as a cache lookup key * * @example * ```typescript * import { computeCacheKey } from "./cacheKey"; * * const key = computeCacheKey( * { method: "GET", url: "/users", headers: { accept: "application/json" } }, * "https://api.example.com" * ); * // key is a deterministic string encoding method, URL, headers, and body * ``` */ declare function computeCacheKey(req: HttpRequest, baseUrl: string, extraHeaders?: string[]): string; /** * Parses a Cache_Key string back into its component parts. * * Splits on the null character separator and reconstructs the `CacheKeyComponents` object. * The body may contain separator characters, so all parts after the third separator * are joined back together as the body. This enables round-trip fidelity with * `computeCacheKey`. * * @param key - A Cache_Key string produced by `computeCacheKey` * @returns The parsed `CacheKeyComponents` with method, resolvedUrl, headers, and body * * @example * ```typescript * import { computeCacheKey, parseCacheKey } from "./cacheKey"; * * const key = computeCacheKey( * { method: "POST", url: "/data", headers: { "content-type": "application/json" }, body: '{"id":1}' }, * "https://api.example.com" * ); * const parts = parseCacheKey(key); * // parts.method === "POST" * // parts.resolvedUrl === "https://api.example.com/data" * // parts.headers === { "content-type": "application/json" } * // parts.body === '{"id":1}' * ``` */ declare function parseCacheKey(key: string): CacheKeyComponents; /** * Event object passed to the `withLogging` middleware's logger callback on each * request lifecycle phase (request, response, or error). * * @property phase - The lifecycle phase that triggered this event: `"request"` before * the request is sent, `"response"` on success, or `"error"` on failure. * @property req - The original HttpRequest being executed. * @property res - The HttpWireResponse received from the server. Present only when * `phase` is `"response"`. * @property error - The HttpError that occurred. Present only when `phase` is `"error"`. * @property durationMs - Elapsed time in milliseconds since the request was initiated. * Present only when `phase` is `"response"` or `"error"`. */ type LogEvent = { phase: "request" | "response" | "error"; req: HttpRequest; res?: HttpWireResponse; error?: HttpError; durationMs?: number; }; /** * Creates a middleware that injects a Bearer token into the Authorization header. * The token is obtained asynchronously via the provided `tokenProvider` Async_Effect. * If the token provider fails, the error propagates to the caller unchanged. * * @param tokenProvider - A function returning an Async_Effect that resolves to the * Bearer token string. Called on every request to support token rotation. * @returns An HttpMiddleware that prepends `Authorization: Bearer ` to outgoing requests. * * @example * ```typescript * import { makeLifecycleClient, withAuth } from "./index"; * import { asyncSucceed } from "../../core/types/asyncEffect"; * * const client = makeLifecycleClient({ baseUrl: "https://api.example.com" }) * .with(withAuth(() => asyncSucceed("my-secret-token"))); * * // All requests now include Authorization: Bearer my-secret-token * const result = client({ method: "GET", url: "/users" }); * ``` */ declare function withAuth(tokenProvider: () => Async): HttpMiddleware; /** * Creates a middleware that logs request, response, and error events through a * user-supplied logger callback. The logger is invoked synchronously at each phase; * if it throws, the error is swallowed to avoid disrupting the request pipeline. * * @param logger - A synchronous callback invoked with a {@link LogEvent} for each * lifecycle phase (`"request"`, `"response"`, `"error"`). Exceptions thrown by * the logger are silently caught. * @returns An HttpMiddleware that instruments requests with logging side-effects. * * @example * ```typescript * import { makeLifecycleClient, withLogging } from "./index"; * import type { LogEvent } from "./index"; * * const client = makeLifecycleClient({ baseUrl: "https://api.example.com" }) * .with(withLogging((event: LogEvent) => { * console.log(`[${event.phase}] ${event.req.method} ${event.req.url} ${event.durationMs ?? ""}ms`); * })); * * const result = client({ method: "GET", url: "/health" }); * ``` */ declare function withLogging(logger: (event: LogEvent) => void): HttpMiddleware; /** * Creates a middleware that transforms HTTP responses after retrieval. The * transformation is applied to both cached and network responses. Cached * responses are stored in their original (untransformed) form, so the transform * runs on every access. * * If the transform function throws, the error is propagated as a `FetchError`. * * @param fn - A synchronous function that receives the response and the original * request, and returns a modified HttpWireResponse. Must not return `undefined`. * @returns An HttpMiddleware that applies the transform to every successful response. * * @example * ```typescript * import { makeLifecycleClient, withResponseTransform } from "./index"; * * const client = makeLifecycleClient({ baseUrl: "https://api.example.com" }) * .with(withResponseTransform((res, req) => ({ * ...res, * headers: { ...res.headers, "x-request-url": req.url }, * }))); * * // Responses now include the x-request-url header * const result = client({ method: "GET", url: "/data" }); * ``` */ declare function withResponseTransform(fn: (res: HttpWireResponse, req: HttpRequest) => HttpWireResponse): HttpMiddleware; /** * Configuration for the LRU cache. * * @property maxEntries - Maximum number of entries the cache can hold. * Must be >= 1. Values less than 1 are clamped to 1. Fractional values are floored. * Default: 1024. * @property onEvict - Optional callback invoked when entries are evicted from the cache. * Receives the number of entries evicted in that operation (currently always 1). * * @example * ```typescript * import { LRUCache } from "./lruCache"; * * const cache = new LRUCache({ maxEntries: 100, onEvict: (n) => console.log(`Evicted ${n}`) }); * ``` */ type LRUCacheConfig = { /** Maximum number of entries. Must be >= 1. Default: 1024. */ maxEntries?: number; /** Optional callback invoked with the number of entries evicted on each eviction. */ onEvict?: (count: number) => void; }; /** * A generic LRU (Least Recently Used) cache with per-entry TTL support. * * Uses a doubly-linked list combined with a Map for O(1) get, set, and eviction * operations. The head of the list is the most recently used entry; the tail is * the least recently used. * * When the cache exceeds `maxEntries`, the least recently used entry is evicted. * Expired entries are lazily removed on access (get). * * @example * ```typescript * import { LRUCache } from "./lruCache"; * * const cache = new LRUCache({ maxEntries: 256 }); * cache.set("user:1", "Alice", 60_000); // TTL of 60 seconds * const value = cache.get("user:1"); // "Alice" (moves to head) * cache.delete("user:1"); // true * ``` */ declare class LRUCache { private readonly map; private head; private tail; private readonly maxEntries; private readonly onEvict; /** * Creates a new LRU cache instance. * * @param config - Cache configuration options. * @param config.maxEntries - Maximum number of entries. Must be >= 1. Default: 1024. * @param config.onEvict - Optional eviction callback. * * @example * ```typescript * import { LRUCache } from "./lruCache"; * * const cache = new LRUCache({ maxEntries: 50 }); * ``` */ constructor(config?: LRUCacheConfig); /** * Returns the number of entries currently in the cache. * * @returns The current entry count. * * @example * ```typescript * import { LRUCache } from "./lruCache"; * * const cache = new LRUCache(); * cache.set("a", "1", 10_000); * console.log(cache.size); // 1 * ``` */ get size(): number; /** * Retrieves a value by key. * * Returns `undefined` if the key is not found or the entry has expired. * On a hit (non-expired), the entry is moved to the head (most recently used). * Expired entries are lazily removed on access. * * @param key - The cache key to look up. * @returns The cached value, or `undefined` if not found or expired. * * @example * ```typescript * import { LRUCache } from "./lruCache"; * * const cache = new LRUCache(); * cache.set("greeting", "hello", 30_000); * const val = cache.get("greeting"); // "hello" * const miss = cache.get("unknown"); // undefined * ``` */ get(key: string): V | undefined; /** * Inserts or updates an entry in the cache. * * If the key already exists, the value and TTL are updated and the entry is * moved to the head. If inserting a new entry causes the cache to exceed * `maxEntries` (must be >= 1), the least recently used entry is evicted. * * @param key - The cache key. * @param value - The value to store. * @param ttlMs - Time-to-live in milliseconds. The entry expires after this duration. * * @example * ```typescript * import { LRUCache } from "./lruCache"; * * const cache = new LRUCache({ maxEntries: 2 }); * cache.set("a", "alpha", 60_000); * cache.set("b", "beta", 60_000); * cache.set("c", "gamma", 60_000); // evicts "a" (LRU) * ``` */ set(key: string, value: V, ttlMs: number): void; /** * Removes an entry by key. * * @param key - The cache key to remove. * @returns `true` if the entry was found and removed, `false` otherwise. * * @example * ```typescript * import { LRUCache } from "./lruCache"; * * const cache = new LRUCache(); * cache.set("x", "value", 10_000); * cache.delete("x"); // true * cache.delete("x"); // false (already removed) * ``` */ delete(key: string): boolean; /** * Removes all entries from the cache, resetting it to an empty state. * * @example * ```typescript * import { LRUCache } from "./lruCache"; * * const cache = new LRUCache(); * cache.set("a", "1", 10_000); * cache.clear(); * console.log(cache.size); // 0 * ``` */ clear(): void; /** Adds a node to the head of the list (most recently used position). */ private addToHead; /** Removes a node from its current position in the list. */ private removeNode; /** Moves an existing node to the head of the list. */ private moveToHead; /** Evicts the tail node (least recently used) and notifies via callback. */ private evictTail; } /** * Clamps a priority value to the valid range [0, 9]. * * - Truncates toward zero (removes fractional part) * - Clamps the result to the integer range 0 through 9 * - Returns a default of 5 for `undefined`, `NaN`, or non-finite values * * @param value - The priority value to clamp. Must be an integer from 0 to 9. * Values outside this range are clamped. Undefined or non-finite values default to 5. * @returns An integer in the range [0, 9] representing the clamped priority. * * @example * ```typescript * import { clampPriority } from "./priorityQueue"; * * clampPriority(3); // 3 * clampPriority(15); // 9 (clamped to max) * clampPriority(-2); // 0 (clamped to min) * clampPriority(undefined); // 5 (default) * clampPriority(2.7); // 2 (truncated) * ``` */ declare function clampPriority(value: number | undefined): number; /** * An entry stored in the priority queue. * * @property priority - Priority level from 0 to 9, where 0 is the highest priority. * Clamped on enqueue via `clampPriority`. * @property arrivalOrder - Monotonic counter used for FIFO tiebreak within the same * priority level. Lower values are dispatched first. * @property value - The stored value associated with this entry. * @property cancelled - When `true`, the entry is logically removed (lazy deletion). * Cancelled entries are skipped during dequeue and peek operations. */ type PriorityQueueEntry = { /** Priority level 0-9 (0 = highest priority). Clamped on enqueue. */ priority: number; /** Monotonic counter for FIFO tiebreak within the same priority level. */ arrivalOrder: number; /** The stored value. */ value: T; /** When true, the entry is logically removed (lazy deletion). */ cancelled: boolean; }; /** * A generic binary min-heap priority queue. * * Entries are ordered by priority ascending (lower value = higher priority), * with FIFO tiebreak via a monotonic arrivalOrder counter. Priority values * are integers from 0 to 9, where 0 is the highest priority. * * Supports lazy removal: entries can be marked as cancelled and are * skipped during dequeue and peek operations. * * @example * ```typescript * import { PriorityQueue } from "./priorityQueue"; * * const queue = new PriorityQueue(); * queue.enqueue("low", 9); * queue.enqueue("high", 0); * const entry = queue.dequeue(); // { value: "high", priority: 0, ... } * ``` */ declare class PriorityQueue { private heap; private counter; /** * Returns the number of entries in the queue (including cancelled entries). * * @returns The total number of entries in the internal heap. * * @example * ```typescript * import { PriorityQueue } from "./priorityQueue"; * * const queue = new PriorityQueue(); * queue.enqueue("task", 5); * console.log(queue.size); // 1 * ``` */ get size(): number; /** Returns the number of entries that have not been cancelled. */ get activeSize(): number; /** * Adds a value to the queue with the given priority. * * Priority is clamped to the valid range [0, 9] via `clampPriority`. * Returns the created entry, which can be used for later cancellation * by setting `entry.cancelled = true`. * * @param value - The value to enqueue. * @param priority - Priority level, integer from 0 (highest) to 9 (lowest). * Clamped to [0, 9]. Defaults to 5 if undefined. * @returns The created queue entry. * * @example * ```typescript * import { PriorityQueue } from "./priorityQueue"; * * const queue = new PriorityQueue(); * const entry = queue.enqueue("urgent-task", 0); * entry.cancelled = true; // cancel later if needed * ``` */ enqueue(value: T, priority?: number): PriorityQueueEntry; /** * Removes and returns the highest-priority non-cancelled entry. * * Skips (and discards) any cancelled entries at the top of the heap. * Returns `undefined` if the queue is empty or all entries are cancelled. * * @returns The highest-priority non-cancelled entry, or `undefined` if none available. * * @example * ```typescript * import { PriorityQueue } from "./priorityQueue"; * * const queue = new PriorityQueue(); * queue.enqueue("first", 1); * queue.enqueue("second", 2); * const entry = queue.dequeue(); // { value: "first", priority: 1, ... } * ``` */ dequeue(): PriorityQueueEntry | undefined; /** * Returns the highest-priority non-cancelled entry without removing it. * * Discards cancelled entries at the top of the heap as a side effect. * Returns `undefined` if the queue is empty or all entries are cancelled. * * @returns The highest-priority non-cancelled entry, or `undefined` if none available. * * @example * ```typescript * import { PriorityQueue } from "./priorityQueue"; * * const queue = new PriorityQueue(); * queue.enqueue("task", 3); * const top = queue.peek(); // { value: "task", priority: 3, ... } * console.log(queue.size); // 1 (not removed) * ``` */ peek(): PriorityQueueEntry | undefined; /** * Marks all entries matching the predicate as cancelled (lazy removal). * * Cancelled entries are skipped on subsequent dequeue/peek calls. * This does not immediately remove entries from the heap; they are * discarded lazily when encountered at the top during dequeue or peek. * * @param predicate - A function that returns `true` for entries to cancel. * @returns The number of entries marked as cancelled. * * @example * ```typescript * import { PriorityQueue } from "./priorityQueue"; * * const queue = new PriorityQueue(); * queue.enqueue("a", 1); * queue.enqueue("b", 2); * const removed = queue.remove((e) => e.value === "a"); // 1 * ``` */ remove(predicate: (entry: PriorityQueueEntry) => boolean): number; /** Removes the top element from the heap and restores heap property. */ private removeTop; /** Moves an element up the heap until the heap property is restored. */ private bubbleUp; /** Moves an element down the heap until the heap property is restored. */ private sinkDown; } /** * Tracks lifecycle statistics for the HTTP Lifecycle Client. * * All counters start at zero and increase monotonically. The tracker also * provides event emission for observability, wrapping the user-supplied * `onEvent` callback in a try-catch so that callback errors never disrupt * request processing. * * Use the `snapshot()` method to obtain a frozen point-in-time view of all * statistics, including wire-level stats from the underlying HTTP client. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ * onEvent: (event) => console.log(event.type), * wireStats: () => ({ requestCount: 0, errorCount: 0 }), * }); * tracker.cacheHit(); * const stats = tracker.snapshot(); * console.log(stats.cacheHits); // 1 * ``` */ declare class LifecycleStatsTracker { private _cacheHits; private _cacheMisses; private _cacheEvictions; private _dedupHits; private _dedupActive; private _queueDepth; private _requestsStarted; private _requestsCompleted; private _requestsFailed; private _retries; private _batchDispatches; private _batchedRequests; private readonly _onEvent; private readonly _wireStats; /** * Creates a new lifecycle stats tracker. * * @param opts - Configuration options for the tracker. * @param opts.onEvent - Optional callback invoked on each lifecycle event. * Errors thrown by this callback are silently discarded. * @param opts.wireStats - A function returning the current wire-level HTTP client stats. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ * wireStats: () => ({ requestCount: 0, errorCount: 0 }), * }); * ``` */ constructor(opts: { onEvent?: (event: LifecycleEvent) => void; wireStats: () => HttpClientStats; }); /** * Records a cache hit. Increments the cache hit counter by 1. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.cacheHit(); * ``` */ cacheHit(): void; /** * Records a cache miss. Increments the cache miss counter by 1. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.cacheMiss(); * ``` */ cacheMiss(): void; /** * Records a cache eviction. Increments the cache eviction counter by 1. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.cacheEviction(); * ``` */ cacheEviction(): void; /** * Records a dedup hit (a request that joined an in-flight duplicate). * Increments the dedup hit counter by 1. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.dedupHit(); * ``` */ dedupHit(): void; /** * Sets the current number of active dedup groups. * * @param n - The current count of active dedup groups. Must be >= 0. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.setDedupActive(3); * ``` */ setDedupActive(n: number): void; /** * Sets the current priority queue depth. * * @param n - The current number of entries in the priority queue. Must be >= 0. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.setQueueDepth(5); * ``` */ setQueueDepth(n: number): void; /** * Records that a request has started. Increments the requests started counter by 1. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.requestStarted(); * ``` */ requestStarted(): void; /** * Records that a request has completed successfully. * Increments the requests completed counter by 1. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.requestCompleted(); * ``` */ requestCompleted(): void; /** * Records that a request has failed. * Increments the requests failed counter by 1. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ wireStats: () => ({ requestCount: 0, errorCount: 0 }) }); * tracker.requestFailed(); * ``` */ requestFailed(): void; retry(): void; /** * Records a batch dispatch. Increments the batch dispatches counter by 1. */ batchDispatch(): void; /** * Records requests that were coalesced into a batch. * @param count - The number of individual requests in the batch. */ batchedRequests(count: number): void; /** * Emits a lifecycle event to the registered `onEvent` callback. * * The callback is wrapped in a try-catch so that any exception thrown by * the callback is silently discarded and request processing continues * unaffected. If no `onEvent` callback was provided, this is a no-op. * * @param type - The lifecycle event type to emit (e.g., `"cache-hit"`, `"request-start"`). * @param extra - Optional additional event data. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ * onEvent: (event) => console.log(event.type, event.timestamp), * wireStats: () => ({ requestCount: 0, errorCount: 0 }), * }); * tracker.emit("cache-hit", { cacheKey: "GET|/api/users" }); * ``` */ emit(type: LifecycleEventType, extra?: { cacheKey?: string; priority?: number; batchKey?: string; batchSize?: number; attempt?: number; delayMs?: number; status?: number; errorTag?: string; }): void; /** * Returns a frozen snapshot of all lifecycle statistics including wire stats. * * The returned object is frozen (immutable) and represents a point-in-time * view of all counters and gauges. * * @returns A frozen `LifecycleStats` object containing all current statistics. * * @example * ```typescript * import { LifecycleStatsTracker } from "./stats"; * * const tracker = new LifecycleStatsTracker({ * wireStats: () => ({ requestCount: 10, errorCount: 1 }), * }); * tracker.cacheHit(); * tracker.cacheHit(); * const stats = tracker.snapshot(); * console.log(stats.cacheHits); // 2 * ``` */ snapshot(): LifecycleStats; } /** * Configuration for the deduplication middleware. */ type DedupConfig = { /** Custom key function. When provided, overrides default key computation. */ dedupKey?: (req: HttpRequest) => string; /** Optional lifecycle observer for dedup hits/misses. */ onEvent?: (event: { type: "dedup-hit" | "dedup-miss" | "dedup-active"; cacheKey?: string; active?: number; }) => void; }; /** * Creates a deduplication middleware that collapses identical in-flight requests * into a single network call. * * For safe HTTP methods (GET, HEAD, OPTIONS), concurrent requests with the same * dedup key share a single underlying network call. All callers receive the same * response or error. * * Non-safe methods (POST, PUT, PATCH, DELETE) pass through without deduplication. * * Supports ref-counted cancellation: when a caller cancels, the refCount is decremented. * When refCount reaches 0, the underlying request is aborted via AbortController. * * @param config - Optional dedup configuration. Provide a `dedupKey` function to override * the default Cache_Key computation. Return an empty string from `dedupKey` to bypass * deduplication for a specific request. * @returns An HttpMiddleware that wraps the next Wire_Client with deduplication logic. * Concurrent safe-method requests sharing the same key resolve to a single network call. * * @example * ```typescript * import { withDedup } from "./dedup"; * * // Basic usage with default key computation * const dedupMiddleware = withDedup(); * * // With custom key function * const customDedup = withDedup({ * dedupKey: (req) => `${req.method}:${req.url}`, * }); * ``` */ declare function withDedup(config?: DedupConfig): HttpMiddleware; /** * Result of a custom cache policy function. */ type CachePolicyResult = { cacheable: boolean; ttlSeconds?: number; }; /** * Configuration for the response cache middleware. */ type CacheConfig = { /** Time-to-live in seconds. Default: 60. Range: [1, 86400]. */ ttlSeconds?: number; /** Maximum number of cached entries. Default: 1024. Minimum: 1. */ maxEntries?: number; /** Enable stale-while-revalidate. Default: false. */ staleWhileRevalidate?: boolean; /** Custom cache policy function. */ cachePolicy?: (req: HttpRequest, res: HttpWireResponse) => CachePolicyResult; /** Additional headers to include in cache key computation. */ cacheRelevantHeaders?: string[]; /** Base URL needed for cache key computation. */ baseUrl?: string; /** Optional event callback for structured cache failure events. */ onEvent?: (event: { type: string; cacheKey?: string; error?: any; }) => void; /** Optional internal lifecycle callback for hit/miss/eviction stats. */ onLifecycleEvent?: (event: { type: "cache-hit" | "cache-miss" | "cache-eviction"; cacheKey?: string; count?: number; }) => void; }; /** * Creates a response cache middleware that stores and serves previously fetched * responses based on configurable cache policies. * * Features: * - LRU eviction when maxEntries is exceeded * - Per-entry TTL with configurable default * - Stale-while-revalidate support * - Custom cache policy function for cacheability and TTL override * - Only caches safe methods (GET, HEAD, OPTIONS) by default * - Exposes `invalidate(key)` and `clear()` for manual cache control * * @param config - Optional cache configuration object. * - `ttlSeconds`: Time-to-live per entry in seconds, clamped to [1, 86400]. Default: 60. * - `maxEntries`: Maximum cached entries, minimum 1. Default: 1024. * - `staleWhileRevalidate`: When true, serves stale entries while refreshing in background. Default: false. * - `cachePolicy`: Custom function to determine cacheability and per-entry TTL override. * - `cacheRelevantHeaders`: Additional headers included in Cache_Key computation. * - `baseUrl`: Base URL for Cache_Key computation. * - `onEvent`: Callback for structured cache events (e.g., revalidation failures). * @returns An object containing: * - `middleware`: An HttpMiddleware that wraps the next Wire_Client with caching logic. * - `invalidate(key)`: Removes a specific entry from the cache by its Cache_Key. * - `clear()`: Removes all entries from the cache. * * @example * ```typescript * import { withCache } from "./responseCache"; * * // Basic usage with defaults (60s TTL, 1024 max entries) * const { middleware, invalidate, clear } = withCache(); * * // Custom TTL and max entries * const cache = withCache({ * ttlSeconds: 300, * maxEntries: 512, * staleWhileRevalidate: true, * }); * * // Manually invalidate a cached entry * cache.invalidate("GET|https://api.example.com/users"); * ``` */ declare function withCache(config?: CacheConfig): { middleware: HttpMiddleware; invalidate: (key: string) => void; clear: () => void; }; /** * Configuration for the priority scheduler middleware. */ type PriorityConfig = { /** Maximum concurrent requests dispatched to the wire client. Default: 32. */ concurrency?: number; /** Queue timeout in ms for priority-queued requests. Default: no timeout. */ queueTimeoutMs?: number; /** Optional lifecycle observer for queue events. */ onEvent?: (event: { type: "queue-enqueue" | "queue-dispatch"; priority: number; }) => void; }; /** * Creates a priority scheduler middleware that reorders queued requests * by priority before dispatching them to the downstream wire client. * * When the concurrency limit is not reached, requests are dispatched immediately. * When at capacity, requests are held in a priority queue (lower numeric priority = higher urgency) * and dispatched in priority order as slots become available. * * Supports: * - Priority extraction from request options (default 5, clamped to 0-9) * - Queue timeout via `queueTimeoutMs` config (produces PoolTimeout error) * - Cancellation: removes from queue on abort signal * - Stats tracking via `queueDepth` getter * * @param config - Optional priority scheduler configuration. * - `concurrency`: Maximum concurrent requests dispatched to the Wire_Client. * Must be a positive integer (>= 1). Default: 32. * - `queueTimeoutMs`: Maximum time in milliseconds a request may wait in the queue * before receiving a PoolTimeout error. Must be a positive integer (>= 1) or undefined * for no timeout. Default: undefined (no timeout). * @returns An HttpMiddleware (with an additional `queueDepth()` method) that wraps the * next Wire_Client with priority-based scheduling. Requests carry a priority level * (integer from 0 to 9, where 0 is highest urgency). Default priority is 5. * * @example * ```typescript * import { withPriority } from "./priorityScheduler"; * * // Basic usage with default concurrency (32) * const priorityMiddleware = withPriority(); * * // Limit concurrency and set queue timeout * const scheduler = withPriority({ * concurrency: 4, * queueTimeoutMs: 5000, * }); * * // Check current queue depth * const depth = scheduler.queueDepth(); * ``` */ declare function withPriority(config?: PriorityConfig): HttpMiddleware & { queueDepth: () => number; }; type RequestBatchingEvent = { type: "batch-enqueue"; key: string; size: number; request: HttpRequest; } | { type: "batch-flush"; key: string; size: number; reason: "size" | "timer" | "manual"; } | { type: "batch-cancel"; key: string; remaining: number; } | { type: "batch-error"; key: string; size: number; error: HttpError; }; type RequestBatchingConfig = { /** * Groups requests into independent batches. Return undefined/null/empty string * to bypass batching for a request. * * Default: `${method}:${url}`. */ key?: (req: HttpRequest) => string | undefined | null; /** Extra predicate for per-request opt-in/out. Default: batch all keyed requests. */ shouldBatch?: (req: HttpRequest) => boolean; /** Maximum requests per batch. Default: 16. */ maxBatchSize?: number; /** Maximum time to wait before flushing a non-full batch. Default: 5ms. */ maxWaitMs?: number; /** Builds the actual wire request sent to the batch endpoint. */ encode: (requests: readonly HttpRequest[]) => HttpRequest; /** * Splits the batch endpoint response back into one response per original * request. The returned array must have the same length and order. */ decode: (response: HttpWireResponse, requests: readonly HttpRequest[]) => readonly HttpWireResponse[]; /** Optional observability hook. Exceptions are swallowed. */ onEvent?: (event: RequestBatchingEvent) => void; }; declare function withRequestBatching(config: RequestBatchingConfig): HttpMiddleware; /** * The PrewarmManager interface for managing connection pre-warming. */ type PrewarmManager = { /** Warm a single origin. Skips if already warm. */ warm: (origin: string) => Promise; /** Warm all configured origins. Skips already-warm origins. */ warmAll: () => Promise; /** Check if an origin has an active warm connection. */ isWarm: (origin: string) => boolean; /** Cancel in-flight probe for a specific origin. */ cancel: (origin: string) => void; /** Cancel all in-flight and queued probes. */ cancelAll: () => void; /** Get a snapshot of all managed origins and their states. */ status: () => PrewarmStatusSnapshot; /** Dispose the manager: cancel all, stop timers, release resources. */ dispose: () => void; }; /** * Creates a PrewarmManager that proactively establishes TCP+TLS connections * to known origins using lightweight HEAD probe requests. * * @param config - Configuration for the prewarm manager. * @returns A PrewarmManager instance. * @throws Error if fetch/AbortController is unavailable or origins are invalid. */ declare function makePrewarmManager(config: PrewarmConfig): PrewarmManager; /** * Validates and normalizes an origin string. * * A valid origin is: scheme + host + optional port (e.g., "https://api.example.com" or "http://localhost:3000"). * Trailing slashes are stripped. Paths, query strings, and fragments are rejected. * * @param origin - The origin string to validate. * @returns The normalized origin string. * @throws Error if the origin is invalid. */ declare function validateOrigin(origin: string): string; /** * Detects the current runtime platform. * * @returns "browser" if running in a browser environment, "node" otherwise. */ declare function detectPlatform(): "browser" | "node"; /** * Validates that the global `fetch` API is available. * * @throws Error if `fetch` or `AbortController` is not available. */ declare function validateFetchAvailable(): void; /** * Outcome of a probe request. */ type ProbeOutcome = { /** Whether the probe succeeded (connection established). */ ok: boolean; /** Duration of the probe in milliseconds. */ durationMs: number; /** Error message if the probe failed. */ error?: string; }; /** * Options for executing a probe request. */ type ProbeOptions = { /** Probe timeout in milliseconds. */ timeoutMs: number; /** AbortSignal for external cancellation. */ signal: AbortSignal; /** Runtime platform. */ platform: "browser" | "node"; /** Optional Wire_Client to route through (when useClientPool is true). */ client?: HttpClientFn; }; /** * Executes a HEAD probe request to the root path of the given origin. * * The probe is a lightweight HEAD request to `${origin}/` designed to trigger * TCP+TLS connection establishment in the platform's connection pool. * * @param origin - The validated origin to probe (e.g., "https://api.example.com"). * @param options - Probe configuration options. * @returns A ProbeOutcome indicating success or failure. */ declare function executeProbe(origin: string, options: ProbeOptions): Promise; /** * Interface for the connection state map. */ type ConnectionStateMap = { /** Mark an origin as warm with the current timestamp. */ markWarm: (origin: string, now?: number) => void; /** Mark an origin as expired. */ markExpired: (origin: string) => void; /** Mark an origin as idle (reset state). */ markIdle: (origin: string) => void; /** Mark an origin as probing. */ markProbing: (origin: string) => void; /** Check if an origin is currently warm (not expired). */ isWarm: (origin: string, now?: number) => boolean; /** Get the current state of an origin. */ getState: (origin: string) => PrewarmOriginState | undefined; /** Get a snapshot of all managed origins. */ snapshot: () => PrewarmStatusSnapshot; }; /** * Creates a connection state map for tracking per-origin warm/expired/idle states. * * @param origins - Array of origin strings to manage. * @param keepAliveDurationMs - Duration in ms after which a warm connection expires. * @returns A ConnectionStateMap instance. */ declare function makeConnectionStateMap(origins: string[], keepAliveDurationMs: number): ConnectionStateMap; /** * A lightweight counting semaphore that limits concurrent in-flight operations. */ type BudgetSemaphore = { /** Acquire a slot. Resolves with a release handle when a slot is available. */ acquire: () => Promise<{ release: () => void; }>; /** Try to acquire a slot synchronously. Returns undefined if no slot is available. */ tryAcquire: () => { release: () => void; } | undefined; /** Number of currently available slots. */ available: () => number; /** Number of waiters currently queued. */ queued: () => number; }; /** * Creates a budget semaphore with the given capacity. * * @param capacity - Maximum number of concurrent slots. Must be >= 1. * @returns A BudgetSemaphore instance. */ declare function makeBudgetSemaphore(capacity: number): BudgetSemaphore; type ConnectionPrewarmAttempt = { url: string; origin: string; ok: boolean; status?: number; ms: number; error?: HttpError; }; type ConnectionPrewarmResult = { attempted: number; warmed: number; failed: number; skipped: number; attempts: readonly ConnectionPrewarmAttempt[]; }; type ConnectionPrewarmEvent = { type: "prewarm-start"; url: string; origin: string; } | { type: "prewarm-success"; url: string; origin: string; status: number; ms: number; } | { type: "prewarm-failure"; url: string; origin: string; error: HttpError; ms: number; }; type ConnectionPrewarmConfig = { baseUrl?: string; urls?: readonly string[]; origins?: readonly string[]; path?: string; method?: Extract; headers?: Record; timeoutMs?: number; failFast?: boolean; fetchImpl?: typeof fetch; onEvent?: (event: ConnectionPrewarmEvent) => void; }; type ConnectionPrewarmingMiddlewareConfig = ConnectionPrewarmConfig & { once?: boolean; shouldPrewarm?: (req: HttpRequest) => boolean; target?: (req: HttpRequest) => string | undefined | null; }; declare function prewarmConnections(config?: ConnectionPrewarmConfig): Async; declare const prewarmHttpConnections: typeof prewarmConnections; declare function withConnectionPrewarming(config?: ConnectionPrewarmingMiddlewareConfig): HttpMiddleware; /** * Event emitted by the bare-metal client. Intentionally minimal — only * construction-time warnings and lifecycle signals are emitted. */ type BareMetalHttpEvent = { readonly type: "warning"; readonly message: string; }; /** * Configuration for the bare-metal HTTP client factories. * * Contains only wire-level options — no lifecycle/middleware config. * All fields are optional; sensible defaults (fetch transport, no pool, * no timeout) are applied when omitted. */ interface BareMetalHttpConfig { /** Base URL prepended to relative request paths. */ readonly baseUrl?: string; /** Default headers merged under per-request headers. */ readonly headers?: Record; /** Request timeout in milliseconds (≥ 1). Disabled when omitted. */ readonly timeoutMs?: number; /** Effect-based transport. Defaults to fetch when omitted. */ readonly transport?: HttpTransport; /** Effect-based streaming transport. Defaults to fetch streaming when omitted. */ readonly streamTransport?: HttpStreamTransport; /** Connection pool config. Set `false` to explicitly disable. */ readonly pool?: false | HttpPoolConfig; /** Adaptive concurrency limiter config. Set `false` to explicitly disable. */ readonly adaptiveLimiter?: false | AdaptiveLimiterConfig; /** Optional event callback for construction-time warnings. */ readonly onEvent?: (event: BareMetalHttpEvent) => void; } /** * Validates a `BareMetalHttpConfig` object at construction time. * Throws `ConfigValidationError` with field-path issues on invalid input. */ declare function validateBareMetalConfig(config: BareMetalHttpConfig): void; /** * Creates a bare-metal HTTP client with zero middleware overhead. * * The returned client delegates directly to `runDirectTransport` or * `runPoolTransport` — no lifecycle stack (retry, dedup, cache, batch, * priority scheduling), no compression, no prewarm. * * Typed errors, cancellation, pool/adaptive-limiter, and stats are preserved. */ declare function makeBareMetalHttp(cfg?: BareMetalHttpConfig): HttpClient; /** * Creates a bare-metal streaming HTTP client with zero middleware overhead. * * Mirrors `makeBareMetalHttp` but uses `streamTransport` and returns an * `HttpClientStream` conforming to `HttpClientStreamFn`. * * Pool leases are acquired before the stream transport and released upon * receiving response headers — body stream consumption is independent of * pool capacity. * * No lifecycle stack (retry, dedup, cache, batch, priority scheduling), * no compression, no prewarm. */ declare function makeBareMetalHttpStream(cfg?: BareMetalHttpConfig): HttpClientStream; type HttpClientBuilder = { readonly config: () => DefaultHttpClientConfig; readonly baseUrl: (baseUrl: string) => HttpClientBuilder; readonly header: (name: string, value: string) => HttpClientBuilder; readonly headers: (headers: Record) => HttpClientBuilder; readonly timeoutMs: (timeoutMs: number) => HttpClientBuilder; readonly timeout: (timeoutMs: number) => HttpClientBuilder; readonly transport: (transport: HttpTransport) => HttpClientBuilder; readonly preset: (preset: DefaultHttpClientPreset) => HttpClientBuilder; readonly minimal: () => HttpClientBuilder; readonly proxy: () => HttpClientBuilder; readonly balanced: () => HttpClientBuilder; readonly defaultPreset: () => HttpClientBuilder; readonly production: () => HttpClientBuilder; readonly dedup: (config?: DedupConfig$1 | false) => HttpClientBuilder; readonly noDedup: () => HttpClientBuilder; readonly batch: (config: BatchConfig | false) => HttpClientBuilder; readonly noBatch: () => HttpClientBuilder; readonly cache: (config?: CacheConfig$1 | false) => HttpClientBuilder; readonly noCache: () => HttpClientBuilder; readonly priority: (config?: PriorityConfig$1 | false) => HttpClientBuilder; readonly noPriority: () => HttpClientBuilder; readonly retry: (config?: RetryPolicy | false) => HttpClientBuilder; readonly noRetry: () => HttpClientBuilder; readonly prewarm: (config?: PrewarmLifecycleConfig | false) => HttpClientBuilder; readonly noPrewarm: () => HttpClientBuilder; readonly adaptiveLimiter: (config?: AdaptiveLimiterConfig | false) => HttpClientBuilder; readonly adaptiveLimiterPreset: (preset: AdaptiveLimiterPreset, overrides?: AdaptiveLimiterConfig) => HttpClientBuilder; readonly conservativeLimiter: (overrides?: AdaptiveLimiterConfig) => HttpClientBuilder; readonly balancedLimiter: (overrides?: AdaptiveLimiterConfig) => HttpClientBuilder; readonly aggressiveLimiter: (overrides?: AdaptiveLimiterConfig) => HttpClientBuilder; readonly noAdaptiveLimiter: () => HttpClientBuilder; readonly pool: (config?: HttpPoolConfig | false) => HttpClientBuilder; readonly noPool: () => HttpClientBuilder; readonly compression: (config?: CompressionConfig | false) => HttpClientBuilder; readonly noCompression: () => HttpClientBuilder; readonly middleware: (mw: HttpMiddleware) => HttpClientBuilder; readonly use: (mw: HttpMiddleware) => HttpClientBuilder; readonly configure: (config: DefaultHttpClientConfig) => HttpClientBuilder; readonly build: () => DefaultHttpClient; readonly buildWire: () => LifecycleClient; }; declare function httpClientBuilder(config?: DefaultHttpClientConfig): HttpClientBuilder; declare const makeHttpClientBuilder: typeof httpClientBuilder; declare const httpBuilder: typeof httpClientBuilder; type HttpServerMethod = HttpMethod | "ALL"; type HttpServerHeaders = Record; type HttpServerQuery = Record; type HttpServerParams = Record; type HttpServerBody = string | Uint8Array | ArrayBuffer | unknown; type HttpServerRequest = { readonly method: string; readonly url: string; readonly path: string; readonly target: string; readonly headers: HttpServerHeaders; readonly query: HttpServerQuery; readonly params: HttpServerParams; readonly bodyText: string; readonly raw?: unknown; }; type HttpServerContext = Omit & { readonly route: string; readonly params: Params; readonly query: Query; readonly body: Body; }; type HttpServerResponse = { readonly status?: number; readonly headers?: HttpServerHeaders; readonly body?: Body; }; type HttpServerHandler = (ctx: HttpServerContext) => Async>; type HttpServerMiddleware = (next: HttpServerHandler) => HttpServerHandler; type HttpRouteSchemas = { readonly params?: ParamsSchema; readonly paramsSchemaName?: string; readonly query?: QuerySchema; readonly querySchemaName?: string; readonly body?: BodySchema; readonly bodySchemaName?: string; readonly response?: ResponseSchema; readonly responseSchemaName?: string; }; type HttpRouteOptions = HttpRouteSchemas & { readonly middleware?: readonly HttpServerMiddleware[]; }; type HttpRuntimeHealthRouteOptions = RuntimeHealthOptions & { readonly path?: string; }; type InferServerPart = Schema extends AnyJsonSchemaLike ? InferJsonSchema : Fallback; type RoutePathParamNames = Path extends `${string}:${infer Param}/${infer Rest}` ? StripRouteParamModifier | RoutePathParamNames<`/${Rest}`> : Path extends `${string}:${infer Param}` ? StripRouteParamModifier : never; type RoutePathParams = [ RoutePathParamNames ] extends [never] ? {} : { readonly [Key in RoutePathParamNames]: string; }; type StripRouteParamModifier = Param extends `${infer Name}?` ? Name : Param extends `${infer Name}+` ? Name : Param extends `${infer Name}*` ? Name : Param; type HttpServerRoute = { readonly method: HttpServerMethod; readonly path: Path; readonly options: HttpRouteOptions; readonly handler: HttpServerHandler>, InferServerPart, InferServerPart, InferServerPart>; readonly match: (path: string) => HttpServerParams | undefined; }; type HttpRouterOptions = { readonly middleware?: readonly HttpServerMiddleware[]; readonly includeErrorDetails?: boolean; }; type HttpRouteMatch = { readonly _tag: "Match"; readonly route: HttpServerRoute; readonly params: HttpServerParams; } | { readonly _tag: "MethodNotAllowed"; readonly route: HttpServerRoute; readonly allowed: readonly HttpServerMethod[]; } | { readonly _tag: "NotFound"; }; type HttpRouter = { readonly routes: readonly HttpServerRoute[]; readonly match: (method: string, path: string) => HttpRouteMatch; readonly handle: (request: HttpServerRequest, match?: HttpRouteMatch) => Async; readonly listen: (options?: Omit, "router">) => Resource; }; type NodeHttpServerError = { readonly _tag: "ListenError"; readonly error: unknown; readonly message: string; } | { readonly _tag: "ServerClosed"; readonly message: string; }; type NodeHttpServerHandle = { readonly server: Server; readonly router: HttpRouter; readonly address: () => AddressInfo | string | null; readonly url: () => string | undefined; readonly close: () => Promise; }; type NodeHttpServerOptions = { readonly router: HttpRouter | readonly HttpServerRoute[]; readonly host?: string; readonly port?: number; readonly env?: R; readonly runtime?: Runtime; readonly runtimeOptions?: Omit, "env" | "hooks">; readonly observability?: Observability; readonly observabilityOptions?: HttpServerObservabilityOptions; readonly maxBodyBytes?: number; readonly gracefulShutdownMs?: number; readonly shutdownPollSchedule?: Schedule; readonly onError?: (error: unknown) => void; }; type NodeHttpServerShutdownState = { readonly listening: boolean; readonly elapsedMs: number; }; declare function route(method: HttpServerMethod, path: Path, options: HttpRouteOptions, handler: HttpServerHandler>, InferServerPart, InferServerPart, InferServerPart>): HttpServerRoute; declare function route(method: HttpServerMethod, path: Path, handler: HttpServerHandler>): HttpServerRoute; declare const httpRoute: typeof route; declare function makeHttpRouter(routes: readonly HttpServerRoute[], options?: HttpRouterOptions): HttpRouter; declare function json(body: Body, init?: Omit, "body">): HttpServerResponse; declare function text(body: string, init?: Omit, "body">): HttpServerResponse; declare function empty(status?: number, headers?: HttpServerHeaders): HttpServerResponse; declare function makeRuntimeHealthRoute(options?: HttpRuntimeHealthRouteOptions): HttpServerRoute; declare function makeRuntimeReadinessRoute(options?: HttpRuntimeHealthRouteOptions): HttpServerRoute; declare const runtimeHealthRoute: typeof makeRuntimeHealthRoute; declare const runtimeReadinessRoute: typeof makeRuntimeReadinessRoute; declare function withResponseHeader(name: string, value: string): HttpServerMiddleware; declare function makeNodeHttpServer(options: NodeHttpServerOptions): Async; declare function nodeHttpServerResource(options: NodeHttpServerOptions): Resource; declare const makeNodeHttpServerResource: typeof nodeHttpServerResource; declare const makeHttpServerResource: typeof nodeHttpServerResource; declare const HttpServer: Readonly<{ route: typeof route; httpRoute: typeof route; router: typeof makeHttpRouter; listen: typeof makeNodeHttpServer; resource: typeof nodeHttpServerResource; json: typeof json; text: typeof text; empty: typeof empty; healthRoute: typeof makeRuntimeHealthRoute; readinessRoute: typeof makeRuntimeReadinessRoute; middleware: Readonly<{ header: typeof withResponseHeader; }>; }>; declare const HttpClientService: ServiceTag; type DefaultHttpClientLayerConfig = DefaultHttpClientConfig | ((context: LayerContext) => DefaultHttpClientConfig); type DefaultHttpClientLayerOptions = { readonly tag?: ServiceTag; }; declare function makeDefaultHttpClientLayer(config?: DefaultHttpClientLayerConfig, options?: DefaultHttpClientLayerOptions): Layer; export { AdaptiveLimiter, AdaptiveLimiterConfig, AdaptiveLimiterPreset, AnyJsonSchemaLike, type BareMetalHttpConfig, type BareMetalHttpEvent, BatchConfig, type BudgetSemaphore, CacheConfig$1 as CacheConfig, type CacheKeyComponents, CompressionConfig, CompressionMiddlewareResult, type ConnectionPrewarmAttempt, type ConnectionPrewarmConfig, type ConnectionPrewarmEvent, type ConnectionPrewarmResult, type ConnectionPrewarmingMiddlewareConfig, type ConnectionStateMap, DEFAULT_CACHE_RELEVANT_HEADERS, DedupConfig$1 as DedupConfig, DefaultHttpClient, DefaultHttpClientConfig, type DefaultHttpClientLayerConfig, type DefaultHttpClientLayerOptions, DefaultHttpClientPreset, EmaComputer, type HttpCircuitBreakerConfig, HttpClient, type HttpClientBuilder, HttpClientFn, HttpClientService, HttpClientStats, HttpClientStream, HttpError, HttpMethod, HttpMiddleware, HttpPoolConfig, HttpRequest, type HttpRouteMatch, type HttpRouteOptions, type HttpRouteSchemas, type HttpRouter, type HttpRouterOptions, type HttpRuntimeHealthRouteOptions, HttpServer, type HttpServerBody, type HttpServerContext, type HttpServerHandler, type HttpServerHeaders, type HttpServerMethod, type HttpServerMiddleware, type HttpServerParams, type HttpServerQuery, type HttpServerRequest, type HttpServerResponse, type HttpServerRoute, HttpStreamTransport, HttpTransport, HttpWireResponse, InferJsonSchema, type InferServerPart, LRUCache, type LRUCacheConfig, LatencyWindow, LifecycleClient, LifecycleClientConfig, LifecycleEvent, LifecycleEventType, LifecycleStats, LifecycleStatsTracker, type LogEvent, type NodeHttpProxyClientConfig, type NodeHttpServerError, type NodeHttpServerHandle, type NodeHttpServerOptions, type NodeHttpServerShutdownState, type NodeHttpTransport, type NodeHttpTransportConfig, PrewarmConfig, PrewarmLifecycleConfig, type PrewarmManager, PrewarmOriginState, PrewarmResult, PrewarmStatusSnapshot, PriorityConfig$1 as PriorityConfig, PriorityQueue, type PriorityQueueEntry, type ProbeOutcome, type RequestBatchingConfig, type RequestBatchingEvent, RequestCompressionConfig, RequestCompressionMiddlewareResult, RetryPolicy, type RoutePathParamNames, type RoutePathParams, SEPARATOR, clampPriority, computeCacheKey, computeGradient, computeNewLimit, detectPlatform, empty, executeProbe, httpBuilder, httpClientBuilder, httpRoute, json, makeBareMetalHttp, makeBareMetalHttpStream, makeBudgetSemaphore, makeCompressionMiddleware, makeConnectionStateMap, makeDefaultHttpClientLayer, makeHttpClient, makeHttpClientBuilder, makeHttpRouter, makeHttpServerResource, makeLifecycleClient, makeNodeHttpProxyClient, makeNodeHttpServer, makeNodeHttpServerResource, makeNodeHttpTransport, makePrewarmManager, makeRequestCompressionMiddleware, makeResponseCompressionMiddleware, makeRuntimeHealthRoute, makeRuntimeReadinessRoute, nodeHttpServerResource, parseCacheKey, prewarmConnections, prewarmHttpConnections, route, runtimeHealthRoute, runtimeReadinessRoute, text, validateBareMetalConfig, validateFetchAvailable, validateOrigin, withAuth, withCache, withCircuitBreaker, withConnectionPrewarming, withDedup, withLogging, withPriority, withRequestBatching, withResponseHeader, withResponseTransform, withTracing };