1import { upgradeWebSocket } from "@neon/functions";
2import * as Effect from "effect/Effect";
3import * as HttpServerResponse from "effect/http/HttpServerResponse";
4import type { RuntimeContext } from "../RuntimeContext.ts";
5import { FunctionRequest } from "./FunctionEnvironment.ts";
6import { FunctionUpgradeSockets } from "./FunctionUpgrade.ts";
7
8/**
9 * Upgrade the current request using Neon's native WebSocket implementation.
10 * Return `response` unchanged; rebuilding it discards the native upgrade metadata.
11 * Authenticate the caller before accepting a public Function connection.
12 */
13export const upgrade = (options?: {
14 protocol?: string;
15}): Effect.Effect<
16 {
17 socket: WebSocket;
18 response: HttpServerResponse.HttpServerResponse;
19 },
20 never,
21 RuntimeContext | FunctionRequest
22> =>
23 Effect.gen(function* () {
24 const request = yield* FunctionRequest;
25 const { socket, response } = yield* Effect.sync(() =>
26 upgradeWebSocket(request, options),
27 );
28 yield* Effect.sync(() => FunctionUpgradeSockets.set(response, socket));
29 return { socket, response: HttpServerResponse.raw(response) };
30 });