forked from effect-app/boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathresolvers.ts
More file actions
46 lines (43 loc) · 1.8 KB
/
resolvers.ts
File metadata and controls
46 lines (43 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { UserId } from "#Accounts/models"
import { UserView } from "#Accounts/views"
import { clientFor } from "#resources/lib"
import { Effect, Exit, Request, RequestResolver } from "effect"
import { Array, Option, pipe, S } from "effect-app"
import { ApiClientFactory, NotFoundError } from "effect-app/client"
import { type Schema } from "effect-app/Schema"
import { IndexUsers } from "./IndexUsers.js"
interface GetUserViewById extends Request.Request<UserView, NotFoundError<"User">> {
readonly _tag: "GetUserViewById"
readonly id: UserId
}
const GetUserViewById = Request.tagged<GetUserViewById>("GetUserViewById")
const getUserViewByIdResolver = RequestResolver
.makeBatched((requests: GetUserViewById[]) =>
clientFor({ IndexUsers }).pipe(
Effect.flatMap((client) =>
client
.IndexUsers
.handler({ filterByIds: pipe(requests.map((_) => _.id), Array.toNonEmptyArray, Option.getOrUndefined)! })
),
Effect.andThen(({ users }) =>
Effect.forEach(requests, (r) =>
Request.complete(
r,
Array
.findFirst(users, (_) => _.id === r.id ? Option.some(Exit.succeed(_)) : Option.none())
.pipe(Option.getOrElse(() => Exit.fail(new NotFoundError({ type: "User", id: r.id }))))
), { discard: true })
),
Effect.orDie
)
)
.pipe(RequestResolver.batchN(25), RequestResolver.contextFromServices(ApiClientFactory))
// TODO: How to globally cache - right now we had to move the RequestCache from the runtime to clientFor
export const UserViewFromId: Schema<UserView, string, ApiClientFactory> = S.transformOrFail(
UserId,
S.typeSchema(UserView),
{
decode: (id) => Effect.request(GetUserViewById({ id }), getUserViewByIdResolver).pipe(Effect.orDie),
encode: (u) => Effect.succeed(u.id)
}
)