1/**
2 * Browser WebSocket layers for Effect sockets.
3 *
4 * `layerWebSocket` creates a `Socket.Socket` connected to a WebSocket URL using
5 * the browser `WebSocket` constructor. `layerWebSocketConstructor` provides
6 * only the browser-backed constructor service for lower-level socket code.
7 *
8 * @since 4.0.0
9 */
10import type * as Duration from "effect/Duration"
11import * as Layer from "effect/Layer"
12import * as Socket from "effect/socket/Socket"
13
14/**
15 * Creates a `Socket` layer connected to the given URL using the browser `WebSocket` constructor.
16 *
17 * **When to use**
18 *
19 * Use when you need browser code to satisfy the platform socket service from a
20 * URL without wiring the browser constructor service separately.
21 *
22 * **Details**
23 *
24 * Delegates socket construction to `Socket.makeWebSocket` and provides the
25 * browser-backed `WebSocketConstructor` service.
26 *
27 * **Gotchas**
28 *
29 * Browser WebSocket rules still control URL schemes, mixed-content blocking,
30 * cookies, authentication, origin checks, subprotocols, and extensions. Every
31 * close, whatever the code, fails the socket's reader with a `SocketError`.
32 *
33 * @see {@link layerWebSocketConstructor} for providing only the browser constructor service
34 *
35 * @category layers
36 * @since 4.0.0
37 */
38export const layerWebSocket = (url: string, options?: {
39 readonly openTimeout?: Duration.Input | undefined
40 readonly protocols?: string | Array<string> | undefined
41 readonly highWaterMark?: number | undefined
42}): Layer.Layer<Socket.Socket> =>
43 Layer.effect(Socket.Socket, Socket.makeWebSocket(url, options)).pipe(
44 Layer.provide(layerWebSocketConstructor)
45 )
46
47/**
48 * Layer that provides a `WebSocketConstructor` service backed by `globalThis.WebSocket`.
49 *
50 * @category layers
51 * @since 4.0.0
52 */
53export const layerWebSocketConstructor: Layer.Layer<Socket.WebSocketConstructor> =
54 Socket.layerWebSocketConstructorGlobal