import {
import HttpApp
HttpApp,
import HttpServerRequest
HttpServerRequest,
import HttpServerResponse
HttpServerResponse,
import UrlParams
UrlParams,
} from "@effect/platform";
import { import Effect
Effect, import Layer
Layer, import ManagedRuntime
ManagedRuntime } from "effect";
// your main layer representing all of the services your handler needs (db, auth, etc.)
declare const const mainLive: Layer.Layer<void, never, never>
mainLive: import Layer
Layer.interface Layer<in ROut, out E = never, out RIn = never>
Layer<void>;
const const managedRuntime: ManagedRuntime.ManagedRuntime<void, never>
managedRuntime = import ManagedRuntime
ManagedRuntime.const make: <void, never>(layer: Layer.Layer<void, never, never>, memoMap?: Layer.MemoMap | undefined) => ManagedRuntime.ManagedRuntime<void, never>
Convert a Layer into an ManagedRuntime, that can be used to run Effect's using
your services.make(const mainLive: Layer.Layer<void, never, never>
mainLive);
const const runtime: Runtime<void>
runtime = await const managedRuntime: ManagedRuntime.ManagedRuntime<void, never>
managedRuntime.ManagedRuntime<void, never>.runtime: () => Promise<Runtime<void>>
runtime();
// everything interesting happens in this effect- it consumes the request from context anywhere and ultimately produces some http response
declare const const effectHandler: Effect.Effect<HttpServerResponse.HttpServerResponse, never, HttpServerRequest.HttpServerRequest>
effectHandler: import Effect
Effect.interface Effect<out A, out E = never, out R = never>
The `Effect` interface defines a value that describes a workflow or job,
which can succeed or fail.
**Details**
The `Effect` interface represents a computation that can model a workflow
involving various types of operations, such as synchronous, asynchronous,
concurrent, and parallel interactions. It operates within a context of type
`R`, and the result can either be a success with a value of type `A` or a
failure with an error of type `E`. The `Effect` is designed to handle complex
interactions with external resources, offering advanced features such as
fiber-based concurrency, scheduling, interruption handling, and scalability.
This makes it suitable for tasks that require fine-grained control over
concurrency and error management.
To execute an `Effect` value, you need a `Runtime`, which provides the
environment necessary to run and manage the computation.Effect<
import HttpServerResponse
HttpServerResponse.HttpServerResponse,
never,
import HttpServerRequest
HttpServerRequest.HttpServerRequest
>;
// example:
declare const const doThing: (id: string) => Effect.Effect<{
readonly _tag: "user";
}, Error>
doThing: (
id: string
id: string,
) => import Effect
Effect.interface Effect<out A, out E = never, out R = never>
The `Effect` interface defines a value that describes a workflow or job,
which can succeed or fail.
**Details**
The `Effect` interface represents a computation that can model a workflow
involving various types of operations, such as synchronous, asynchronous,
concurrent, and parallel interactions. It operates within a context of type
`R`, and the result can either be a success with a value of type `A` or a
failure with an error of type `E`. The `Effect` is designed to handle complex
interactions with external resources, offering advanced features such as
fiber-based concurrency, scheduling, interruption handling, and scalability.
This makes it suitable for tasks that require fine-grained control over
concurrency and error management.
To execute an `Effect` value, you need a `Runtime`, which provides the
environment necessary to run and manage the computation.Effect<{ readonly _tag: "user"
_tag: "user" }, Error>;
const const exampleEffectHandler: Effect.Effect<HttpServerResponse.HttpServerResponse, never, HttpServerRequest.HttpServerRequest>
exampleEffectHandler = import Effect
Effect.const gen: <YieldWrap<Tag<HttpServerRequest.HttpServerRequest, HttpServerRequest.HttpServerRequest>> | YieldWrap<Effect.Effect<UrlParams.UrlParams, RequestError, never>> | YieldWrap<...> | YieldWrap<...> | YieldWrap<...>, HttpServerResponse.HttpServerResponse>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
**When to Use**
`Effect.gen` allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to `async/await` but with more
explicit control over the execution of effects. You can `yield*` values from
effects and return the final result at the end.gen(function* () {
const const request: HttpServerRequest.HttpServerRequest
request = yield* import HttpServerRequest
HttpServerRequest.const HttpServerRequest: Tag<HttpServerRequest.HttpServerRequest, HttpServerRequest.HttpServerRequest>
HttpServerRequest;
const const params: UrlParams.UrlParams
params = yield* const request: HttpServerRequest.HttpServerRequest
request.HttpIncomingMessage<RequestError>.urlParamsBody: Effect.Effect<UrlParams.UrlParams, RequestError, never>
urlParamsBody;
const const id: string
id = yield* import UrlParams
UrlParams.const getFirst: (self: UrlParams.UrlParams, key: string) => Option<string> (+1 overload)
getFirst(const params: UrlParams.UrlParams
params, "id").Pipeable.pipe<Option<string>, Effect.Effect<string, Error, never>>(this: Option<string>, ab: (_: Option<string>) => Effect.Effect<string, Error, never>): Effect.Effect<...> (+21 overloads)
pipe(
import Effect
Effect.const mapError: <NoSuchElementException, Error>(f: (e: NoSuchElementException) => Error) => <A, R>(self: Effect.Effect<A, NoSuchElementException, R>) => Effect.Effect<...> (+1 overload)
Transforms or modifies the error produced by an effect without affecting its
success value.
**When to Use**
This function is helpful when you want to enhance the error with additional
information, change the error type, or apply custom error handling while
keeping the original behavior of the effect's success values intact. It only
operates on the error channel and leaves the success channel unchanged.mapError(() => new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error("no id param found")),
);
const const data: {
readonly _tag: "user";
}
data = yield* const doThing: (id: string) => Effect.Effect<{
readonly _tag: "user";
}, Error>
doThing(const id: string
id);
return yield* import HttpServerResponse
HttpServerResponse.const json: (body: unknown, options?: HttpServerResponse.Options.WithContentType | undefined) => Effect.Effect<HttpServerResponse.HttpServerResponse, HttpBodyError>
json(const data: {
readonly _tag: "user";
}
data);
}).Pipeable.pipe<Effect.Effect<HttpServerResponse.HttpServerResponse, Error | RequestError | HttpBodyError, HttpServerRequest.HttpServerRequest>, Effect.Effect<...>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(
// probably want some kind of catch all (defects too)
// although the `toWebHandlerRuntime` already does quite a bit for you: https://github.com/Effect-TS/effect/blob/main/packages/platform/src/Http/App.ts#L134
import Effect
Effect.const catchAllCause: <Error | RequestError | HttpBodyError, HttpServerResponse.HttpServerResponse, never, never>(f: (cause: Cause<Error | RequestError | HttpBodyError>) => Effect.Effect<...>) => <A, R>(self: Effect.Effect<...>) => Effect.Effect<...> (+1 overload)
Handles both recoverable and unrecoverable errors by providing a recovery
effect.
**When to Use**
The `catchAllCause` function allows you to handle all errors, including
unrecoverable defects, by providing a recovery effect. The recovery logic is
based on the `Cause` of the error, which provides detailed information about
the failure.
**When to Recover from Defects**
Defects are unexpected errors that typically shouldn't be recovered from, as
they often indicate serious issues. However, in some cases, such as
dynamically loaded plugins, controlled recovery might be needed.catchAllCause((e: Cause<Error | RequestError | HttpBodyError>
e) =>
import HttpServerResponse
HttpServerResponse.const empty: (options?: HttpServerResponse.Options.WithContent | undefined) => HttpServerResponse.HttpServerResponse
empty().Pipeable.pipe<HttpServerResponse.HttpServerResponse, HttpServerResponse.HttpServerResponse>(this: HttpServerResponse.HttpServerResponse, ab: (_: HttpServerResponse.HttpServerResponse) => HttpServerResponse.HttpServerResponse): HttpServerResponse.HttpServerResponse (+21 overloads)
pipe(import HttpServerResponse
HttpServerResponse.const setStatus: (status: number, statusText?: string | undefined) => (self: HttpServerResponse.HttpServerResponse) => HttpServerResponse.HttpServerResponse (+1 overload)
setStatus(500)),
),
);
const const webHandler: (request: Request, context?: Context<never> | undefined) => Promise<Response>
webHandler = import HttpApp
HttpApp.const toWebHandlerRuntime: <void>(runtime: Runtime<void>) => <E>(self: HttpApp.Default<E, void | Scope>, middleware?: HttpMiddleware | undefined) => (request: Request, context?: Context<never> | undefined) => Promise<Response>
toWebHandlerRuntime(const runtime: Runtime<void>
runtime)(const effectHandler: Effect.Effect<HttpServerResponse.HttpServerResponse, never, HttpServerRequest.HttpServerRequest>
effectHandler);
export const const GET: (req: Request) => Promise<Response>
GET: (req: Request
req: Request) => interface Promise<T>
Represents the completion of an asynchronous operationPromise<Response> = const webHandler: (request: Request, context?: Context<never> | undefined) => Promise<Response>
webHandler;