Skip to content

Commit 2f9e5e9

Browse files
committed
Add a case of publishing SSE Events and listening and acting on it in the Frontend.
1 parent 5a74643 commit 2f9e5e9

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

_project/api/_src/Usecases/Blog.Controllers.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { NotFoundError } from "@/errors.js"
2-
import { BlogPostRepo, Operations } from "@/services.js"
2+
import { BlogPostRepo, Events, Operations } from "@/services.js"
33
import { BlogPost } from "@effect-app-boilerplate/models/Blog"
44
import { BlogRsc } from "@effect-app-boilerplate/resources"
5+
import { BogusEvent } from "@effect-app-boilerplate/resources/Events"
56
import { PositiveInt } from "@effect-app/prelude/schema"
67

78
const { controllers, matchWithServices } = matchFor(BlogRsc)
@@ -27,8 +28,8 @@ const CreatePost = matchWithServices("CreatePost")(
2728
)
2829

2930
const PublishPost = matchWithServices("PublishPost")(
30-
{ BlogPostRepo, Operations },
31-
(req, { BlogPostRepo, Operations }) =>
31+
{ BlogPostRepo, Events, Operations },
32+
(req, { BlogPostRepo, Events, Operations }) =>
3233
Do($ => {
3334
$(
3435
BlogPostRepo.find(req.id)
@@ -44,7 +45,7 @@ const PublishPost = matchWithServices("PublishPost")(
4445
const done: string[] = []
4546

4647
const operationId = $(
47-
Effect.forkOperation(
48+
Effect.forkOperationWithEffect(
4849
opId =>
4950
Operations.update(opId, {
5051
total: PositiveInt(targets.length),
@@ -61,7 +62,12 @@ const PublishPost = matchWithServices("PublishPost")(
6162
)
6263
.delay(Duration.seconds(4))
6364
)
64-
.map(() => "the answer to the universe is 41")
65+
.map(() => "the answer to the universe is 41"),
66+
// while operation is running...
67+
_opId =>
68+
Effect.suspendSucceed(() => Events.publish(new BogusEvent({})))
69+
.delay(DUR.seconds(1))
70+
.forever
6571
)
6672
)
6773

_project/frontend-nuxt/pages/blog/[id].vue

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import { BlogRsc } from "@effect-app-boilerplate/resources"
3+
import type { ClientEvents } from "@effect-app-boilerplate/resources"
34
import { BlogPostId } from "@effect-app-boilerplate/models/Blog"
45
56
const { id } = useRouteParams({ id: BlogPostId })
@@ -9,6 +10,18 @@ const [, latestPost, reloadPost] = useSafeQueryWithArg(blogClient.findPost, {
910
id,
1011
})
1112
13+
const bogusOutput = ref<ClientEvents>()
14+
15+
onMountedWithCleanup(() => {
16+
const callback = (_: ClientEvents) => {
17+
bogusOutput.value = _
18+
}
19+
bus.on("serverEvents", callback)
20+
return () => {
21+
bus.off("serverEvents", callback)
22+
}
23+
})
24+
1225
const progress = ref("")
1326
const [publishing, publish] = useAndHandleMutation(
1427
refreshAndWaitForOperation(
@@ -23,6 +36,9 @@ const [publishing, publish] = useAndHandleMutation(
2336
</script>
2437

2538
<template>
39+
<div v-if="bogusOutput">
40+
The latest bogus event is: {{ bogusOutput.id }} at {{ bogusOutput.at }}
41+
</div>
2642
<div v-if="latestPost">
2743
<v-btn @click="publish({ id })" :disabled="publishing.loading">
2844
Publish to all blog sites {{ publishing.loading && `(${progress})` }}

0 commit comments

Comments
 (0)