forked from effect-app/boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPublishPost.ts
More file actions
75 lines (67 loc) · 2.42 KB
/
PublishPost.ts
File metadata and controls
75 lines (67 loc) · 2.42 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
import { handlerFor } from "#api/lib/handler"
import { OperationsDefault } from "#api/lib/layers"
import { Events, Operations } from "#api/services"
import { BogusEvent } from "#resources/Events"
import { S } from "#resources/lib"
import { Duration, Effect, Schedule } from "effect-app"
import { NotFoundError } from "effect-app/client"
import { OperationId } from "effect-app/Operations"
import { NonEmptyString2k, NonNegativeInt } from "effect-app/Schema"
import { BlogPostId } from "./models.js"
import { BlogPostRepo } from "./Repo.js"
export class PublishPost extends S.Req<PublishPost>()("Blog.PublishPost", {
id: BlogPostId
}, { allowRoles: ["user"], success: OperationId, failure: S.Union(NotFoundError) }) {}
export default handlerFor(PublishPost)({
dependencies: [
BlogPostRepo.Default,
OperationsDefault,
Events.Default
],
effect: Effect.gen(function*() {
const blogPostRepo = yield* BlogPostRepo
const operations = yield* Operations
const events = yield* Events
return (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
})
})
})