import * as Cause from "effect/Cause"; import * as Effect from "effect/Effect"; import * as Stream from "effect/Stream"; import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"; import type * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"; import * as Socket from "effect/unstable/socket/Socket"; import type { HttpEffect } from "./Http.ts"; export type Rpc = { "~alchemy/rpc": Shape; }; /** * Recover the user's RPC `Shape` from any of the forms a caller might pass * to {@link toRpcAsync}: * * - the Worker class value's type, e.g. `typeof Backend`, which extends * `Effect.Effect, …>` * - the unwrapped `Worker & Rpc` type * - a bare `Shape` (when the caller types it explicitly) */ export declare namespace Rpc { type Shape = W extends Effect.Effect ? R extends Rpc ? Shape : R : W extends Rpc ? Shape : W; } export declare const StreamTag = "~alchemy/rpc/stream"; export declare const ErrorTag = "~alchemy/rpc/error"; export declare const StreamErrorTag = "~alchemy/rpc/stream-error"; export type StreamEncoding = "bytes" | "jsonl"; export type RpcStreamEnvelope = { _tag: typeof StreamTag; encoding: StreamEncoding; body: ReadableStream; }; export type RpcErrorEnvelope = { _tag: typeof ErrorTag; error: unknown; }; export type RpcStreamErrorMarker = { _tag: typeof StreamErrorTag; error: unknown; }; declare const RpcDecodeError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & { readonly _tag: "RpcDecodeError"; } & Readonly; export declare class RpcDecodeError extends RpcDecodeError_base<{ readonly cause: unknown; }> { get message(): string; } declare const RpcCallError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & { readonly _tag: "RpcCallError"; } & Readonly; export declare class RpcCallError extends RpcCallError_base<{ readonly method: string; readonly cause: unknown; }> { get message(): string; } declare const RpcRemoteStreamError_base: new = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & { readonly _tag: "RpcRemoteStreamError"; } & Readonly; export declare class RpcRemoteStreamError extends RpcRemoteStreamError_base<{ readonly error: unknown; }> { } export declare const isRpcStreamErrorMarker: (value: unknown) => value is RpcStreamErrorMarker; export declare const isRpcErrorEnvelope: (value: unknown) => value is RpcErrorEnvelope; export declare const isRpcStreamEnvelope: (value: unknown) => value is RpcStreamEnvelope; /** * Normalize an error value into a plain, structured-clone-safe object. * Tagged errors keep `_tag` and all own enumerable fields. * Plain `Error` instances keep `name`, `message`, and `stack`. */ export declare const encodeRpcError: (error: unknown) => unknown; /** * Decode a wire byte stream into the original values. `bytes` streams pass * through untouched; `jsonl` streams are split per-line, JSON-parsed, and any * embedded {@link RpcStreamErrorMarker} is lifted into the error channel. */ export declare const decodeRpcByteStream: (bytes: Stream.Stream, encoding: StreamEncoding) => Stream.Stream; export declare const fromRpcReadableStream: (body: ReadableStream, encoding: StreamEncoding) => Stream.Stream; export declare const fromRpcStreamEnvelope: (envelope: RpcStreamEnvelope) => Stream.Stream; export declare const decodeRpcValue: (value: unknown) => unknown; /** * Decode an RPC return value, lifting error envelopes into the Effect * error channel so that remote `Effect.fail(...)` values are recoverable. */ export declare const decodeRpcResult: (value: unknown) => Effect.Effect; export declare const toRpcStream: (stream: Stream.Stream) => Effect.Effect<{ _tag: "~alchemy/rpc/stream"; encoding: "bytes"; body: ReadableStream; } | { _tag: "~alchemy/rpc/stream"; encoding: "jsonl"; body: ReadableStream>; } | { _tag: "~alchemy/rpc/stream"; encoding: "jsonl"; body: ReadableStream>; }, never, any>; /** * Encode a `Stream` as a lazy NDJSON byte stream for an HTTP response body. * No peeking, so nothing is held open across the handler→body-streaming * boundary. `Uint8Array` elements are tagged + base64-encoded; a source * failure is appended as a trailing {@link RpcStreamErrorMarker}. */ export declare const encodeRpcResponseStream: (stream: Stream.Stream) => Stream.Stream; /** * Decode an NDJSON byte stream produced by {@link encodeRpcResponseStream}: * tagged byte chunks become `Uint8Array`, a {@link RpcStreamErrorMarker} is * lifted into the error channel, everything else is the decoded JSON value. */ export declare const decodeRpcResponseStream: (bytes: Stream.Stream) => Stream.Stream; export declare const asEffectOrStream: (call: Effect.Effect) => Effect.Effect; /** Path prefix under which RPC methods are dispatched. */ export declare const RPC_PATH_PREFIX = "/__rpc__/"; /** Response header flag marking an NDJSON streamed body (vs a JSON value). */ export declare const RPC_STREAM_HEADER = "x-alchemy-rpc-stream"; /** * Build a typed RPC stub over a plain `fetch` transport. Any property that * isn't an own property of `base` is treated as a remote method: calling it * `POST`s `{baseUrl}{RPC_PATH_PREFIX}{name}` with the JSON-encoded arguments * and decodes the response into an {@link asEffectOrStream} value (so value * methods `yield*` as `Effect`s and streaming methods pipe as `Stream`s). */ export declare const makeFetchRpcStub: (options: { readonly fetch: (request: HttpClientRequest.HttpClientRequest) => Effect.Effect; readonly baseUrl?: string; /** Own properties that take precedence over remote-method dispatch. */ readonly base?: Record; }) => Shape; /** * Serve the RPC methods on `shape` over the {@link RPC_PATH_PREFIX} route, * delegating every other request to `fallback`. The mirror of {@link * makeFetchRpcStub}: method arguments are read from the JSON request body, the * method is invoked, and the result is encoded as a JSON value, a JSON error * envelope, or a streamed body (flagged via {@link RPC_STREAM_HEADER}). */ export declare const serveRpc: (shape: Record, fallback: HttpEffect) => HttpEffect; export {}; //# sourceMappingURL=Rpc.d.ts.map