| 1 | import { upgradeWebSocket } from "@neon/functions"; |
| 2 | import * as Effect from "effect/Effect"; |
| 3 | import * as HttpServerResponse from "effect/http/HttpServerResponse"; |
| 4 | import type { RuntimeContext } from "../RuntimeContext.ts"; |
| 5 | import { FunctionRequest } from "./FunctionEnvironment.ts"; |
| 6 | import { 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 | */ |
| 13 | export 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 | }); |