1/**
2 * Service contract for servers that accept socket connections.
3 *
4 * `SocketServer` exposes the bound server `address` and a long-running `run`
5 * loop that hands each accepted connection to a handler as a `Socket.Socket`.
6 * Bound addresses use the shared `NetAddress.SocketAddress` model. This module also
7 * defines server-level errors reported while opening or running a server.
8 * Platform layers provide concrete implementations of this service.
9 *
10 * @stability unstable
11 * @since 4.0.0
12 */
13import * as Context from "../Context.ts"
14import * as Data from "../Data.ts"
15import type * as Effect from "../Effect.ts"
16import type * as NetAddress from "../net/NetAddress.ts"
17import type * as Socket from "./Socket.ts"
18
19/**
20 * Context service for a socket server, exposing its bound address and a run
21 * loop that handles each accepted `Socket`.
22 *
23 * @stability unstable
24 * @category services
25 * @since 4.0.0
26 */
27export class SocketServer extends Context.Service<SocketServer, {
28 readonly address: NetAddress.SocketAddress
29 readonly run: <R, E, _>(
30 handler: (socket: Socket.Socket) => Effect.Effect<_, E, R>
31 ) => Effect.Effect<never, SocketServerError, R>
32}>()("@effect/platform/SocketServer") {}
33
34/**
35 * Runtime type identifier attached to `SocketServerError` values.
36 *
37 * @stability unstable
38 * @category type IDs
39 * @since 4.0.0
40 */
41export const ErrorTypeId: ErrorTypeId = "@effect/platform/SocketServer/SocketServerError"
42
43/**
44 * Type-level identifier used to mark `SocketServerError` values.
45 *
46 * @stability unstable
47 * @category type IDs
48 * @since 4.0.0
49 */
50export type ErrorTypeId = "@effect/platform/SocketServer/SocketServerError"
51
52/**
53 * Error reason for failures that occur while opening a socket server.
54 *
55 * @stability unstable
56 * @category errors
57 * @since 4.0.0
58 */
59export class SocketServerOpenError extends Data.TaggedError("SocketServerOpenError")<{
60 readonly cause: unknown
61}> {
62 override get message(): string {
63 return "Open"
64 }
65}
66
67/**
68 * Error reason for uncategorized socket server failures.
69 *
70 * @stability unstable
71 * @category errors
72 * @since 4.0.0
73 */
74export class SocketServerUnknownError extends Data.TaggedError("SocketServerUnknownError")<{
75 readonly cause: unknown
76}> {
77 override get message(): string {
78 return "Unknown"
79 }
80}
81
82/**
83 * Union of socket server error reasons.
84 *
85 * @stability unstable
86 * @category errors
87 * @since 4.0.0
88 */
89export type SocketServerErrorReason = SocketServerOpenError | SocketServerUnknownError
90
91/**
92 * Tagged socket server error that wraps a server error reason and exposes its
93 * cause.
94 *
95 * @stability unstable
96 * @category errors
97 * @since 4.0.0
98 */
99export class SocketServerError extends Data.TaggedError("SocketServerError")<{
100 readonly reason: SocketServerErrorReason
101}> {
102 constructor(props: {
103 readonly reason: SocketServerErrorReason
104 }) {
105 super({
106 ...props,
107 cause: props.reason.cause
108 } as any)
109 }
110 /**
111 * Marks this value as a socket server error for runtime guards.
112 *
113 * @stability unstable
114 * @since 4.0.0
115 */
116 readonly [ErrorTypeId]: ErrorTypeId = ErrorTypeId
117
118 /**
119 * Delegates the public message to the underlying socket server error reason.
120 *
121 * @stability unstable
122 * @since 4.0.0
123 */
124 override get message(): string {
125 return this.reason.message
126 }
127}