forked from effect-app/boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontrollers.ts
More file actions
90 lines (83 loc) · 2.89 KB
/
controllers.ts
File metadata and controls
90 lines (83 loc) · 2.89 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { UserRepo } from "#api/Accounts/UserRepo"
import { Events } from "#api/Events"
import { matchFor, Router } from "#api/lib/routing"
import { BlogPost } from "#Domain/Blog"
import { BogusEvent } from "#resources/Events"
import { Operations } from "@effect-app/infra/Operations"
import { Duration, Effect, Schedule } from "effect"
import { Option } from "effect-app"
import { NonEmptyString2k, NonNegativeInt } from "effect-app/Schema"
import { OperationsDefault } from "../lib/layers.js"
import { BlogPostRepo } from "./BlogPostRepo.js"
import { BlogRsc } from "./resources.js"
export default Router(BlogRsc)({
dependencies: [
BlogPostRepo.Default,
UserRepo.Default,
OperationsDefault,
Events.Default
],
effect: Effect.gen(function*() {
const blogPostRepo = yield* BlogPostRepo
const userRepo = yield* UserRepo
const events = yield* Events
const operations = yield* Operations
return matchFor(BlogRsc)({
FindPost: (req) =>
blogPostRepo
.find(req.id)
.pipe(Effect.andThen(Option.getOrNull)),
GetPosts: blogPostRepo
.all
.pipe(Effect.andThen((items) => ({ items }))),
CreatePost: (req) =>
userRepo
.getCurrentUser
.pipe(
Effect.andThen((author) => (new BlogPost({ ...req, author }, true))),
Effect.tap(blogPostRepo.save)
),
PublishPost: (req) =>
Effect.gen(function*() {
const post = yield* blogPostRepo.get(req.id)
console.log("publishing post", post)
const targets = [
"google",
"twitter",
"facebook"
]
const done: string[] = []
const op = yield* operations.fork(
(opId) =>
operations
.update(opId, {
total: NonNegativeInt(targets.length),
completed: NonNegativeInt(done.length)
})
.pipe(
Effect.andThen(Effect.forEach(targets, (_) =>
Effect
.sync(() => done.push(_))
.pipe(
Effect.tap(() =>
operations.update(opId, {
total: NonNegativeInt(targets.length),
completed: NonNegativeInt(done.length)
})
),
Effect.delay(Duration.seconds(4))
))),
Effect.andThen(() => "the answer to the universe is 41")
),
// while operation is running...
(_opId) =>
Effect
.suspend(() => events.publish(new BogusEvent()))
.pipe(Effect.schedule(Schedule.spaced(Duration.seconds(1)))),
NonEmptyString2k("post publishing")
)
return op.id
})
})
})
})