Socket
Models bidirectional socket connections in Effect.
A Socket exposes a pull-based reader and a scoped writer. Acquiring
the reader dials the connection and returns an Effect that yields batches
of incoming frames with end-to-end backpressure: nothing is read from the
transport until the consumer pulls. Every termination, including clean
closes, surfaces as a SocketError, so reconnecting is a plain
Effect.retry around the scoped consume loop.
Combinators
readerBytes
Acquires the socket's binary pull, encoding any string frames as UTF-8
bytes.
Details
When a pulled batch contains no string frames it is returned as-is, so transports that only emit bytes (TCP) pay no per-chunk cost.
Signature
declare function readerBytes(self: Socket): Effect<Effect<readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>], SocketError, never>, SocketError, Scope>readerString
Acquires the socket's string pull, decoding binary frames with the optional
text encoding.
Details
The TextDecoder is created once per acquisition.
Signature
declare function readerString(self: Socket, encoding?: string): Effect<Effect<readonly [string, string], SocketError, never>, SocketError, Scope>Converts a Socket into a bidirectional binary Channel, encoding
incoming string frames as UTF-8 bytes and writing outgoing frame batches to
the socket.
Details
The read side is the socket's pull, so the channel is backpressured end-to-end.
Signature
declare function toChannel<IE = never>(self: Socket): Channel<readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>], SocketError | IE, void, readonly [string | Uint8Array<ArrayBufferLike> | CloseEvent, string | Uint8Array<ArrayBufferLike> | CloseEvent], IE>toChannelString
Converts a Socket into a bidirectional string Channel, decoding binary
frames with the optional text encoding.
Signature
declare const toChannelString: { (encoding?: string): <IE>(self: Socket) => Channel<readonly [string, string], SocketError | IE, void, readonly [string | Uint8Array<ArrayBufferLike> | CloseEvent, string | Uint8Array<ArrayBufferLike> | CloseEvent], IE>; <IE>(self: Socket, encoding?: string): Channel<readonly [string, string], SocketError | IE, void, readonly [string | Uint8Array<ArrayBufferLike> | CloseEvent, string | Uint8Array<ArrayBufferLike> | CloseEvent], IE>;}toChannelWith
Creates a Socket to binary Channel adapter with a fixed upstream error
type.
Signature
declare function toChannelWith<IE = never>(): (self: Socket) => Channel<readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>], SocketError | IE, void, readonly [string | Uint8Array<ArrayBufferLike> | CloseEvent, string | Uint8Array<ArrayBufferLike> | CloseEvent], IE>Converts a Socket into a read-only binary Stream backed by the socket's
pull, so consumption is backpressured end-to-end.
Signature
declare function toStream(self: Socket): Stream<Uint8Array<ArrayBufferLike>, SocketError>Constructors
fromTransformStream
Builds a Socket from a scoped InputTransformStream, pulling incoming
chunks from the readable side and writing outgoing chunks to the writable
stream, encoding strings as UTF-8.
Signature
declare function fromTransformStream<R>(acquire: Effect<InputTransformStream, SocketError, R>): Effect<Socket, never, Exclude<R, Scope>>fromWebSocket
Builds a Socket from a scoped WebSocket acquisition effect.
Details
Reader acquisition runs acquire, attaches event listeners, then waits for
the socket to open. Implementations exposing pause/resume (the ws
package) remain flowing until buffered frames reach the configured
highWaterMark (64 KiB by default). Draining the buffer resumes the
transport. Incoming frames that arrive in the same tick are coalesced into
one batch. Implementations without pause (browsers) buffer incoming frames,
optionally failing the socket with a SocketReadError when highWaterMark
bytes are exceeded (default unbounded). Message boundaries survive: each
pulled batch contains one element per frame.
Signature
declare function fromWebSocket<RO, WS extends WebSocketLike>(acquire: Effect<WS, SocketError, RO>, options?: { readonly highWaterMark?: number; readonly openTimeout?: Input;}): Effect<Socket, never, Exclude<RO, Scope>>Constructs a Socket from a reader acquisition and a scoped writer.
Details
The reader must fail a suspended pull when its acquisition scope closes; see
Socket for why. A reader that leaves a pull blocked forever will hang any
consumer that shuts the socket down by closing that scope.
Signature
declare function make(options: { readonly reader: Effect<Reader<string | Uint8Array<ArrayBufferLike>>, SocketError, Scope>; readonly writer: Effect<Writer, never, Scope>;}): SocketmakeChannel
Creates a binary socket Channel from the Socket service in the
environment.
Signature
declare function makeChannel<IE = never>(): Channel<readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>], SocketError | IE, void, readonly [string | Uint8Array<ArrayBufferLike> | CloseEvent, string | Uint8Array<ArrayBufferLike> | CloseEvent], IE, unknown, Socket>makeWebSocket
Creates a Socket backed by a WebSocketConstructor, dialing the
WebSocket for each reader acquisition.
Signature
declare function makeWebSocket(url: string | Effect<string, never, never>, options?: { readonly highWaterMark?: number; readonly openTimeout?: Input; readonly protocols?: string | Array<string>;}): Effect<Socket, never, WebSocketConstructor>makeWebSocketChannel
Creates a binary Channel backed by a WebSocket URL, requiring a
WebSocketConstructor service.
Signature
declare function makeWebSocketChannel<IE = never>(url: string, options?: { readonly highWaterMark?: number; readonly openTimeout?: Input; readonly protocols?: string | Array<string>;}): Channel<readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>], SocketError | IE, void, readonly [string | Uint8Array<ArrayBufferLike> | CloseEvent, string | Uint8Array<ArrayBufferLike> | CloseEvent], IE, unknown, WebSocketConstructor>Errors
SocketCloseError
Typed error for a socket close, carrying the close code and optional close reason.
Details
Sockets never classify closes: any close, whatever the code, fails the
reader with a SocketError wrapping this reason. Consumers that treat a
close as normal catch it.
Signature
declare class SocketCloseError extends { readonly _tag: "SocketCloseError"; readonly closeReason?: string; readonly code: number;} & YieldableError<this> { constructor(...args: [props: { readonly _tag?: "SocketCloseError"; readonly closeReason?: string; readonly code: number; }, options?: MakeOptions]); message: string;}SocketError
Tagged error that wraps socket read, write, open, upgrade, and close failures while preserving the underlying reason.
Signature
declare class SocketError extends { readonly _tag: "SocketError"; readonly reason: SocketReadError | SocketWriteError | SocketOpenError | SocketUpgradeError | SocketCloseError;} & YieldableError<this> { constructor(props: { readonly reason: SocketReadError | SocketWriteError | SocketOpenError | SocketUpgradeError | SocketCloseError; }); readonly "~effect/socket/Socket/SocketError": "~effect/socket/Socket/SocketError"; readonly message: string; static is(u: unknown): u is SocketError;}SocketErrorReason
Schema for all socket-specific error reasons.
Signature
declare const SocketErrorReason: Union<readonly [typeof SocketReadError, typeof SocketWriteError, typeof SocketOpenError, typeof SocketUpgradeError, typeof SocketCloseError]>SocketErrorReason type
Union of socket-specific read, write, open, upgrade, and close error reasons.
Signature
type SocketErrorReason = SocketReadError | SocketWriteError | SocketOpenError | SocketUpgradeError | SocketCloseErrorSocketOpenError
Typed error for failures that occur while opening a socket, including unknown open failures and open timeouts.
Signature
declare class SocketOpenError extends { readonly _tag: "SocketOpenError"; readonly cause: unknown; readonly kind: "Unknown" | "Timeout";} & YieldableError<this> { constructor(...args: [props: { readonly _tag?: "SocketOpenError"; readonly cause: unknown; readonly kind: "Unknown" | "Timeout"; }, options?: MakeOptions]); message: "timeout waiting for \"open\"" | "An error occurred during Open";}SocketReadError
Typed error for failures that occur while reading from a socket.
Signature
declare class SocketReadError extends { readonly _tag: "SocketReadError"; readonly cause: unknown;} & YieldableError<this> { constructor(...args: [props: { readonly _tag?: "SocketReadError"; readonly cause: unknown; }, options?: MakeOptions]); readonly message: "An error occurred during Read";}SocketUpgradeError
Typed error for an unsupported or failed in-place TLS upgrade.
Signature
declare class SocketUpgradeError extends { readonly _tag: "SocketUpgradeError"; readonly cause?: unknown;} & YieldableError<this> { constructor(...args: [props?: { readonly _tag?: "SocketUpgradeError"; readonly cause?: unknown; }, options?: MakeOptions]); static readonly unsupported: (options?: TlsUpgradeOptions) => Effect<void, SocketError>; message: "Socket does not support TLS upgrade" | "An error occurred during TLS upgrade";}SocketWriteError
Typed error for failures that occur while writing to a socket.
Signature
declare class SocketWriteError extends { readonly _tag: "SocketWriteError"; readonly cause: unknown;} & YieldableError<this> { constructor(...args: [props: { readonly _tag?: "SocketWriteError"; readonly cause: unknown; }, options?: MakeOptions]); readonly message: "An error occurred during Write";}Guards
isCloseEvent
Returns true when a value is a CloseEvent.
Signature
declare function isCloseEvent(u: unknown): u is CloseEventReturns true when a value is a Socket.
Signature
declare function isSocket(u: unknown): u is SocketisSocketError
Returns true when a value is a SocketError.
Signature
declare function isSocketError(u: unknown): u is SocketErrorLayers
layerWebSocket
Layer that provides a Socket service backed by a WebSocket URL or URL
effect.
Signature
declare const layerWebSocket: (url: string | Effect.Effect<string>, options?: { readonly highWaterMark?: number; readonly openTimeout?: Duration.Input; readonly protocols?: string | Array<string>;}) => Layer.Layer<Socket, never, WebSocketConstructor>layerWebSocketConstructorGlobal
Layer that provides WebSocketConstructor using globalThis.WebSocket.
Signature
declare const layerWebSocketConstructorGlobal: Layer.Layer<WebSocketConstructor>Models
CloseEvent
Represents a socket close event value carrying a close code and optional reason.
Signature
declare class CloseEvent { constructor(code: number, reason?: string); readonly "~effect/socket/Socket/CloseEvent": "~effect/socket/Socket/CloseEvent"; readonly code: number; readonly reason?: string; toString(): string;}InputTransformStream interface
Readable and writable stream pair used to adapt transform-style streams into
a Socket.
Signature
interface InputTransformStream { readonly readable: ReadableStream<Uint8Array<ArrayBufferLike>> | ReadableStream<string> | ReadableStream<string | Uint8Array<ArrayBufferLike>>; readonly writable: WritableStream<Uint8Array<ArrayBufferLike>>;}The read side of a live Socket connection.
Details
pull reads the next non-empty batch. upgrade wraps this connection with
TLS when the transport supports it. Unsupported readers fail with a
SocketUpgradeError. The upgrade also fails with SocketUpgradeError when
the selected TLS role requires an identity but key and cert are not both
provided. Calling upgrade() without an options object uses the adapter's
client defaults.
Signature
interface Reader<A extends Uint8Array | string = Uint8Array | string> { readonly pull: Effect<readonly [A, A], SocketError>; readonly upgrade: (options?: TlsUpgradeOptions) => Effect<void, SocketError>;}Effect-based socket abstraction exposing a pull-based read side and a scoped writer.
Details
Acquiring reader establishes the connection; the scope of the acquisition
owns the connection lifecycle. Its pull yields non-empty batches of incoming
frames and never completes via Cause.Done: every termination, clean close
included, fails with a SocketError wrapping the close reason. Code placed
between the acquisition and the first pull runs exactly once per
(re)connection, which makes handshakes plain code placement.
Closing the acquisition scope must fail a pull that is currently suspended,
rather than leaving it blocked. Consumers such as toChannel rely on this
to shut a connection down without racing every pull against a separate
failure signal.
The writer is detached from any single connection: acquiring it cannot fail, and writes made while disconnected suspend until the next connection is established. Releasing the writer scope half-closes the write side where the transport supports it.
Signature
interface Socket { readonly "~effect/socket/Socket": "~effect/socket/Socket"; readonly reader: Effect<Reader<string | Uint8Array<ArrayBufferLike>>, SocketError, Scope>; readonly writer: Effect<Writer, never, Scope>;}Example
(Consuming with automatic reconnect)
Effect.gen(function*() { const { pull } = yield* socket.reader while (true) { yield* handle(yield* pull) }}).pipe( Effect.scoped, Effect.retry({ schedule: Schedule.exponential(200) }))TlsUpgradeOptions interface
TLS credentials and handshake settings used to upgrade a live socket.
Details
key and cert are optional for client upgrades that do not present a
client certificate. Server upgrades require both, and providing only one is
invalid. Missing or incomplete credentials fail the upgrade with a
SocketUpgradeError when the adapter needs an identity.
Signature
interface TlsUpgradeOptions { readonly alpnProtocols?: readonly Array<string>; readonly ca?: string | Uint8Array<ArrayBufferLike> | readonly Array<string | Uint8Array<ArrayBufferLike>>; readonly cert?: string | Uint8Array<ArrayBufferLike> | readonly Array<string | Uint8Array<ArrayBufferLike>>; readonly key?: Redacted<string | Uint8Array<ArrayBufferLike>> | readonly Array<Redacted<string | Uint8Array<ArrayBufferLike>>>; readonly passphrase?: Redacted<string>; readonly rejectUnauthorized?: boolean; readonly requestCert?: boolean;}WebSocketClientOptions interface
Common options understood by a WebSocket client implementation.
Signature
interface WebSocketClientOptions { readonly headers?: Readonly<Record<string, string>>;}WebSocketConstructorOptions type
Options accepted by a WebSocketConstructor.
Details
Browser-compatible constructors accept a protocol string or list. Node and
Bun constructors additionally accept WebSocketClientOptions.
Signature
type WebSocketConstructorOptions = string | Array<string> | WebSocketClientOptionsWebSocketEvent interface
Event payload exposed by a WebSocket implementation.
Details
The socket adapter only reads data, code, and reason; implementations
may expose additional fields.
Signature
interface WebSocketEvent { readonly code?: number; readonly data?: unknown; readonly reason?: string; readonly type?: string;}WebSocketLike interface
The subset of the WebSocket API required by Socket.
Details
This structural interface is intentionally independent of the DOM
WebSocket type. Node implementations such as ws expose the same
event-target methods, but are not assignable to globalThis.WebSocket
because their event payload types are runtime-specific.
Signature
interface WebSocketLike { readonly readyState: number; addEventListener(type: "message" | "error" | "open" | "close", listener: (event: WebSocketEvent) => void, options?: { readonly once?: boolean; }): void; close(code?: number, reason?: string): void; removeEventListener(type: "message" | "error" | "open" | "close", listener: (event: WebSocketEvent) => void): void; send(data: string | Uint8Array<ArrayBuffer>): void;}The write side of a Socket.
Details
write sends a single frame or a CloseEvent; writeAll sends a batch of
frames, allowing transports to coalesce them into a single flush. Both
apply the transport's native backpressure before succeeding.
Signature
interface Writer { readonly write: (chunk: string | Uint8Array<ArrayBufferLike> | CloseEvent) => Effect<void, SocketError>; readonly writeAll: (chunks: readonly [string | Uint8Array<ArrayBufferLike>, string | Uint8Array<ArrayBufferLike>]) => Effect<void, SocketError>;}Services
Service tag for bidirectional socket transports.
When to use
Use to access or provide the socket implementation used by programs that read and write frames through the Effect environment.
Signature
declare const Socket: Context.Service<Socket, Socket>Context service for the active WebSocket instance.
Signature
declare class WebSocket extends Shape<"~effect/socket/Socket/WebSocket", WebSocketLike, this> { constructor(_: never);}WebSocketConstructor
Context service for constructing WebSocket instances from a URL and
optional protocols or platform-specific options.
Signature
declare class WebSocketConstructor extends Shape<"@effect/platform/Socket/WebSocketConstructor", (url: string, options?: WebSocketConstructorOptions) => WebSocketLike, this> { constructor(_: never);}Type IDs
SocketErrorTypeId
Runtime type identifier attached to SocketError values.
Signature
declare const SocketErrorTypeId: "~effect/socket/Socket/SocketError"SocketErrorTypeId type
Type-level identifier used to mark SocketError values.
Signature
type SocketErrorTypeId = "~effect/socket/Socket/SocketError"Runtime type identifier attached to Socket services.
Signature
declare const TypeId: "~effect/socket/Socket"