Skip to content

Commit

Permalink
ensure /platform HttpApp.toWebHandler runs Stream's with the current …
Browse files Browse the repository at this point in the history
…runtime (#3278)
  • Loading branch information
tim-smart authored Jul 17, 2024
1 parent 51e9c5c commit fcecff7
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 7 deletions.
7 changes: 7 additions & 0 deletions .changeset/nervous-comics-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@effect/platform": patch
---

ensure /platform HttpApp.toWebHandler runs Stream's with the current runtime

Also add runtime options to HttpServerResponse.toWeb
4 changes: 2 additions & 2 deletions packages/platform/src/HttpApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,12 @@ export const withPreResponseHandler = dual<
*/
export const toWebHandlerRuntime = <R>(runtime: Runtime.Runtime<R>) => {
const run = Runtime.runFork(runtime)
return <E>(self: Default<E, R | Scope.Scope>, middleware: HttpMiddleware | undefined) =>
return <E>(self: Default<E, R | Scope.Scope>, middleware?: HttpMiddleware | undefined) =>
(request: Request): Promise<Response> =>
new Promise((resolve) => {
const fiber = run(Effect.provideService(
toHandled(self, (request, response) => {
resolve(ServerResponse.toWeb(response, request.method === "HEAD"))
resolve(ServerResponse.toWeb(response, { withoutBody: request.method === "HEAD", runtime }))
return Effect.void
}, middleware),
ServerRequest.HttpServerRequest,
Expand Down
9 changes: 8 additions & 1 deletion packages/platform/src/HttpServerResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { ParseOptions } from "@effect/schema/AST"
import type * as Schema from "@effect/schema/Schema"
import type * as Effect from "effect/Effect"
import type { Inspectable } from "effect/Inspectable"
import type * as Runtime from "effect/Runtime"
import type * as Stream from "effect/Stream"
import type { Cookie, Cookies, CookiesError } from "./Cookies.js"
import type * as PlatformError from "./Error.js"
Expand Down Expand Up @@ -353,4 +354,10 @@ export const setStatus: {
* @since 1.0.0
* @category conversions
*/
export const toWeb: (response: HttpServerResponse, withoutBody?: boolean | undefined) => Response = internal.toWeb
export const toWeb: (
response: HttpServerResponse,
options?: {
readonly withoutBody?: boolean | undefined
readonly runtime?: Runtime.Runtime<never> | undefined
}
) => Response = internal.toWeb
10 changes: 7 additions & 3 deletions packages/platform/src/internal/httpServerResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as Effect from "effect/Effect"
import * as Effectable from "effect/Effectable"
import { dual } from "effect/Function"
import * as Inspectable from "effect/Inspectable"
import * as Runtime from "effect/Runtime"
import * as Stream from "effect/Stream"
import * as Cookies from "../Cookies.js"
import type * as PlatformError from "../Error.js"
Expand Down Expand Up @@ -504,15 +505,18 @@ export const setBody = dual<
})

/** @internal */
export const toWeb = (response: ServerResponse.HttpServerResponse, withoutBody = false): Response => {
export const toWeb = (response: ServerResponse.HttpServerResponse, options?: {
readonly withoutBody?: boolean | undefined
readonly runtime?: Runtime.Runtime<never> | undefined
}): Response => {
const headers = new globalThis.Headers(response.headers)
if (!Cookies.isEmpty(response.cookies)) {
const toAdd = Cookies.toSetCookieHeaders(response.cookies)
for (const header of toAdd) {
headers.append("set-cookie", header)
}
}
if (withoutBody) {
if (options?.withoutBody) {
return new Response(undefined, {
status: response.status,
statusText: response.statusText as string,
Expand Down Expand Up @@ -544,7 +548,7 @@ export const toWeb = (response: ServerResponse.HttpServerResponse, withoutBody =
})
}
case "Stream": {
return new Response(Stream.toReadableStream(body.stream), {
return new Response(Stream.toReadableStreamRuntime(body.stream, options?.runtime ?? Runtime.defaultRuntime), {
status: response.status,
statusText: response.statusText,
headers
Expand Down
14 changes: 13 additions & 1 deletion packages/platform/test/HttpApp.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HttpApp, HttpServerResponse } from "@effect/platform"
import { Stream } from "effect"
import { FiberRef, Runtime, Stream } from "effect"
import { assert, describe, test } from "vitest"

describe("Http/App", () => {
Expand Down Expand Up @@ -34,5 +34,17 @@ describe("Http/App", () => {
const response = await handler(new Request("http://localhost:3000/"))
assert.strictEqual(await response.text(), "foobar")
})

test("stream runtime", async () => {
const handler = HttpApp.toWebHandlerRuntime(
Runtime.defaultRuntime.pipe(
Runtime.setFiberRef(FiberRef.currentConcurrency, 420)
)
)(HttpServerResponse.stream(
FiberRef.get(FiberRef.currentConcurrency).pipe(Stream.map(String), Stream.encodeText)
))
const response = await handler(new Request("http://localhost:3000/"))
assert.strictEqual(await response.text(), "420")
})
})
})

0 comments on commit fcecff7

Please sign in to comment.