import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Schedule from "effect/Schedule";
import * as HttpClient from "effect/unstable/http/HttpClient";
import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest";
import type { HttpClientResponse } from "effect/unstable/http/HttpClientResponse";
import * as RpcClient from "effect/unstable/rpc/RpcClient";
import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization";
declare const WorkerNotReady_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
readonly _tag: "WorkerNotReady";
} & Readonly;
/**
* A freshly-deployed Cloudflare Worker is not instantly reachable over HTTP.
* Its `workers.dev` route, the script, and each binding (R2 / D1 / DO / Secrets
* Store) propagate to the edge independently and asynchronously, so the first
* requests to a new URL can transiently return:
*
* - `404` while the `workers.dev` subdomain / route is still propagating
* (Cloudflare serves its "There is nothing here yet" placeholder), or
* - `5xx` while the script is up but a binding it depends on isn't ready yet.
*
* This is ordinary eventual consistency that belongs at the call site, not in
* the resource provider — the provider returning before every edge PoP has
* converged is correct. Consumers ride out the window by retrying the request.
*/
export declare class WorkerNotReady extends WorkerNotReady_base<{
status: number;
}> {
}
export interface WhenReadyOptions {
/** Max retry attempts before surfacing {@link WorkerNotReady}. Default `20`. */
times?: number;
}
/**
* Execute an arbitrary {@link HttpClientRequest.HttpClientRequest}, retrying
* through the Cloudflare cold-start window ({@link isColdStartStatus}) until the
* Worker serves a non-transient response. The returned response can carry any
* non-cold-start status (e.g. `200`, `202`, `401`) for the caller to assert on.
*/
export declare const executeWhenReady: (request: HttpClientRequest.HttpClientRequest, options?: WhenReadyOptions) => Effect.Effect;
/**
* Convenience wrapper over {@link executeWhenReady} for a plain `GET`.
*/
export declare const getWhenReady: (url: string, options?: WhenReadyOptions) => Effect.Effect;
/**
* Options for the edge-transient response guard applied by
* {@link guardContentType} / {@link rpcClientLayer}. Pass per suite via
* `Test.make({ http: { ... } })` or per call site.
*/
export interface EdgeGuardOptions {
/**
* Retry schedule for edge-transient responses (and transport errors).
* Default: exponential from 500ms capped at 3s.
*/
schedule?: Schedule.Schedule;
/** Max transport-level retry attempts. Default `5`. */
times?: number;
}
/**
* Guard an `HttpClient` against edge-generated bodies on a freshly deployed
* Worker URL.
*
* Protocol clients like effect RPC's `layerProtocolHttp` never inspect the
* response status or content-type — they pipe the raw body straight into the
* serialization parser, so every edge-generated HTML page (the workers.dev
* placeholder, which serves with HTTP **200**; 1101/1102 error pages;
* 429/1015 rate limits) surfaces as an opaque decode defect (e.g.
* `RpcClientDefect: Error decoding HTTP response`).
*
* This transform rejects any response whose `content-type` doesn't match the
* expected one as a typed `HttpClientError` that records the status + a body
* snippet — so a failure names its cause — and retries the request through a
* bounded schedule so callers ride out the cold-start window
* ({@link WorkerNotReady} documents why this belongs at the call site).
*/
export declare const guardContentType: (contentType: string, options?: EdgeGuardOptions) => (client: HttpClient.HttpClient) => HttpClient.HttpClient;
/**
* A fetch-backed `HttpClient` layer wrapped with {@link guardContentType}.
*
* Deliberately a standalone layer rather than a transform of the ambient
* test `HttpClient`: the ambient client also serves the engine's own cloud
* API calls during `deploy`/`destroy` and distilled SDK calls in
* `test.provider` bodies, which must NOT be subjected to this guard.
*/
export declare const guardedFetchLayer: (contentType: string, options?: EdgeGuardOptions) => Layer.Layer;
/**
* Complete RPC-over-HTTP client transport for driving a deployed Worker:
* `RpcClient.layerProtocolHttp` + the given serialization (ndjson by
* default) + a {@link guardedFetchLayer} expecting that serialization's
* content-type.
*
* ```ts
* const client = yield* RpcClient.make(WorkerRpcs);
* // ...
* }).pipe(Effect.scoped, Effect.provide(Test.Http.rpcClientLayer(url)));
* ```
*/
export declare const rpcClientLayer: (url: string, options?: EdgeGuardOptions & {
/** RPC wire serialization. Default {@link RpcSerialization.ndjson}. */
serialization?: RpcSerialization.RpcSerialization["Service"];
/**
* Set `false` to skip the edge guard entirely and use a plain fetch
* transport — e.g. for a test that asserts on the raw edge behavior
* itself. Default `true`.
*/
guard?: boolean;
}) => Layer.Layer;
export {};
//# sourceMappingURL=Http.d.ts.map