import { Button, Container, Flex, Heading, Slider, Text } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { Effect, Schema, SubscriptionRef } from "effect" import { HttpClient } from "effect/unstable/http" import { AsyncResult } from "effect/unstable/reactivity" import { Component, Lens, Mutation, Query, View } from "effect-view" import { runtime } from "@/runtime" const Post = Schema.Struct({ userId: Schema.Int, id: Schema.Int, title: Schema.String, body: Schema.String, }) interface PostResultViewProps { readonly result: AsyncResult.AsyncResult } const PostResultView = (props: PostResultViewProps) => AsyncResult.match(props.result, { onInitial: result => result.waiting ? Loading... : No data., onFailure: result => Request failed: { result.cause.toString() }, onSuccess: result => <> {result.waiting && Refreshing...} {result.value.title} {result.value.body} , }) const QueryRouteComponent = Component.make("QueryRouteView")(function*() { const [idLens, query, mutation] = yield* Component.useOnMount(() => Effect.gen(function*() { const keyLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(["post", 1 as number] as const)) const idLens = Lens.focusTupleAt(keyLens, 1) const query = yield* Query.service({ key: keyLens, f: ([, id]) => HttpClient.HttpClient.pipe( Effect.tap(Effect.sleep("1 second")), Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ id }`)), Effect.andThen(response => response.json), Effect.andThen(Schema.decodeUnknownEffect(Post)), ), staleTime: "10 seconds", }) const mutation = yield* Mutation.make({ f: ([id]: [id: number]) => HttpClient.HttpClient.pipe( Effect.tap(Effect.sleep("1 second")), Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ id }`)), Effect.andThen(response => response.json), Effect.andThen(Schema.decodeUnknownEffect(Post)), ), }) return [idLens, query, mutation] as const })) const [id, setId] = yield* Lens.useState(idLens) const [queryState, mutationState] = yield* View.useAll([query.state, mutation.state]) const runSync = yield* Component.useRunSync() return ( setId(value ?? 1)} /> ) }).pipe( Component.withContext(runtime.context), ) export const Route = createFileRoute("/query")({ component: QueryRouteComponent, })