1import type * as mgmt from "@distilled.cloud/aws/apigatewaymanagementapi";
2import type * as Effect from "effect/Effect";
3import * as Binding from "../../Binding.ts";
4import type { ApiGatewayV2Stage } from "./Stage.ts";
5
6export interface PostToConnectionRequest extends mgmt.PostToConnectionRequest {}
7export interface GetConnectionRequest extends mgmt.GetConnectionRequest {}
8export interface DeleteConnectionRequest extends mgmt.DeleteConnectionRequest {}
9
10/**
11 * The runtime client returned by binding {@link ManageConnections} to a
12 * WebSocket API stage.
13 */
14export interface ManageConnectionsClient {
15 /**
16 * Send data to a connected WebSocket client. Fails with a typed
17 * `GoneException` when the connection has already disconnected (410).
18 */
19 readonly postToConnection: (
20 request: PostToConnectionRequest,
21 ) => Effect.Effect<mgmt.PostToConnectionResponse, mgmt.PostToConnectionError>;
22 /**
23 * Get metadata (connect time, last active time, source identity) about a
24 * connection.
25 */
26 readonly getConnection: (
27 request: GetConnectionRequest,
28 ) => Effect.Effect<mgmt.GetConnectionResponse, mgmt.GetConnectionError>;
29 /**
30 * Forcibly disconnect a WebSocket client.
31 */
32 readonly deleteConnection: (
33 request: DeleteConnectionRequest,
34 ) => Effect.Effect<mgmt.DeleteConnectionResponse, mgmt.DeleteConnectionError>;
35}
36
37/**
38 * Runtime binding for the WebSocket `@connections` management API
39 * (`execute-api:ManageConnections`).
40 *
41 * Bind this to a WebSocket API {@link Stage} inside a function runtime to
42 * push messages to connected clients — the flagship server-push primitive
43 * for WebSocket APIs. The binding grants `execute-api:ManageConnections`
44 * scoped to the stage's `@connections` ARN and targets the stage's
45 * callback endpoint (`https://{apiId}.execute-api.{region}.amazonaws.com/{stage}`).
46 *
47 * Provide `ApiGatewayV2.ManageConnectionsHttp` on the hosting function's
48 * Effect (`Effect.provide(ApiGatewayV2.ManageConnectionsHttp)`) to satisfy
49 * the binding.
50 * ### Pushing to clients
51 * **Example:** Echo a message back to the sender
52 * ```typescript
53 * const connections = yield* ApiGatewayV2.ManageConnections(stage);
54 *
55 * yield* ApiGatewayV2.onWebSocketRoute(api, { routeKey: "$default" }, (event) =>
56 * connections
57 * .postToConnection({
58 * ConnectionId: event.requestContext.connectionId,
59 * Data: `echo:${event.body ?? ""}`,
60 * })
61 * .pipe(
62 * Effect.asVoid,
63 * // The peer may have disconnected between send and receive.
64 * Effect.catchTag("GoneException", () => Effect.void),
65 * Effect.orDie,
66 * ),
67 * );
68 * ```
69 *
70 * ### Managing connections
71 * **Example:** Disconnect a client
72 * ```typescript
73 * yield* connections.deleteConnection({ ConnectionId: staleConnectionId });
74 * ```
75 *
76 * @binding
77 */
78export interface ManageConnections extends Binding.Service<
79 ManageConnections,
80 "AWS.ApiGatewayV2.ManageConnections",
81 <S extends ApiGatewayV2Stage>(
82 stage: S,
83 ) => Effect.Effect<ManageConnectionsClient>
84> {}
85export const ManageConnections = Binding.Service<ManageConnections>(
86 "AWS.ApiGatewayV2.ManageConnections",
87);