import { HttpClient } from "@effect/platform" import { Container, Flex, Heading, Slider, Text } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { Array, Effect, flow, Option, Schema } from "effect" import { Async, Component, Memoized } from "effect-fc" import * as React from "react" import { runtime } from "@/runtime" const Post = Schema.Struct({ userId: Schema.Int, id: Schema.Int, title: Schema.String, body: Schema.String, }) interface AsyncFetchPostViewProps { readonly id: number } class AsyncFetchPostView extends Component.make("AsyncFetchPostView")(function*(props: AsyncFetchPostViewProps) { const post = yield* Component.useOnChange(() => HttpClient.HttpClient.pipe( Effect.tap(Effect.sleep("500 millis")), Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ props.id }`)), Effect.andThen(response => response.json), Effect.andThen(Schema.decodeUnknown(Post)), ), [props.id]) return (
{post.title} {post.body}
) }).pipe( Async.async, Async.withOptions({ defaultFallback: Loading post... }), Memoized.memoized, ) {} const AsyncRouteComponent = Component.make("AsyncRouteView")(function*() { const [id, setId] = React.useState(1) const AsyncFetchPost = yield* AsyncFetchPostView.use return ( ) }).pipe( Component.withRuntime(runtime.context) ) export const Route = createFileRoute("/async")({ component: AsyncRouteComponent, })