Files
effect-view/packages/example-next/src/routes/query.tsx
T
Julien Valverdé 31d87ffcab
Lint / lint (push) Successful in 38s
Fix
2026-07-19 04:00:46 +02:00

86 lines
2.8 KiB
TypeScript

import { Button, Container, Flex, Heading, Slider, Text } from "@radix-ui/themes"
import { createFileRoute } from "@tanstack/react-router"
import { Effect, SubscriptionRef } from "effect"
import { AsyncResult } from "effect/unstable/reactivity"
import { Component, Lens, Mutation, Query, View } from "effect-fc-next"
import { fetchPost, type Post } from "@/post"
import { runtime } from "@/runtime"
interface PostResultViewProps {
readonly result: AsyncResult.AsyncResult<Post, Error>
}
const PostResultView = (props: PostResultViewProps) =>
AsyncResult.match(props.result, {
onInitial: () => <Text>Loading...</Text>,
onFailure: () => <Text>Request failed.</Text>,
onSuccess: result => (
<>
<Heading>{result.value.title}</Heading>
<Text>{result.value.body}</Text>
</>
),
})
const QueryRouteComponent = Component.make("QueryRouteView")(function*() {
const [idLens, query, mutation] = yield* Component.useOnMount(() => Effect.gen(function*() {
const idLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(1))
const query = yield* Query.service({
key: idLens,
f: fetchPost,
staleTime: "10 seconds",
})
const mutation = yield* Mutation.make({
f: fetchPost,
})
return [idLens, query, mutation] as const
}))
const [id] = yield* View.useAll([idLens])
const [queryState, mutationResult] = yield* View.useAll([
query.state,
mutation.state,
])
const runPromise = yield* Component.useRunPromise()
return (
<Container>
<Flex direction="column" align="center" gap="2">
<Slider
value={[id]}
min={1}
max={10}
onValueChange={([value]) =>
void runPromise(Lens.set(idLens, value ?? 1))
}
/>
<PostResultView result={queryState.result} />
<Flex direction="row" justify="center" align="center" gap="1">
<Button onClick={() => void runPromise(query.refresh)}>
Refresh
</Button>
<Button onClick={() => void runPromise(query.invalidateCache)}>
Invalidate cache
</Button>
</Flex>
<PostResultView result={mutationResult} />
<Button onClick={() => void runPromise(mutation.mutate(id))}>
Mutate
</Button>
</Flex>
</Container>
)
}).pipe(
Component.withRuntime(runtime.context),
)
export const Route = createFileRoute("/query")({
component: QueryRouteComponent,
})