From 2ff38c435f7cb7ec31b25c72411c8821dc9185f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 2 Jul 2025 21:00:23 +0200 Subject: [PATCH] Todo work --- packages/example/src/routes/__root.tsx | 2 +- packages/example/src/routes/index.tsx | 9 ++-- packages/example/src/todo/Todo.tsx | 72 ++++++++++++++++++++++++++ packages/example/src/todo/Todos.tsx | 56 ++++++++++++++++++++ 4 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 packages/example/src/todo/Todo.tsx create mode 100644 packages/example/src/todo/Todos.tsx diff --git a/packages/example/src/routes/__root.tsx b/packages/example/src/routes/__root.tsx index 4f94c20..67b0910 100644 --- a/packages/example/src/routes/__root.tsx +++ b/packages/example/src/routes/__root.tsx @@ -13,7 +13,7 @@ export const Route = createRootRoute({ function Root() { return ( - + Index Blank diff --git a/packages/example/src/routes/index.tsx b/packages/example/src/routes/index.tsx index 51ef0ab..2d4878c 100644 --- a/packages/example/src/routes/index.tsx +++ b/packages/example/src/routes/index.tsx @@ -1,4 +1,5 @@ import { runtime } from "@/runtime" +import { Todos } from "@/todo/Todos" import { TodosState } from "@/todo/TodosState.service" import { createFileRoute } from "@tanstack/react-router" import { Effect, pipe } from "effect" @@ -7,9 +8,11 @@ import { ReactComponent, ReactHook } from "effect-fc" export const Route = createFileRoute("/")({ component: pipe( - Effect.fn(function*() { - const context = yield* ReactHook.useMemoLayer(TodosState.Default("todos")) - return
Hello "/"!
+ Effect.fn("Route")(function*() { + return yield* Effect.provide( + ReactComponent.use(Todos, Todos => ), + yield* ReactHook.useMemoLayer(TodosState.Default("todos")), + ) }), ReactComponent.withDisplayName("Index"), diff --git a/packages/example/src/todo/Todo.tsx b/packages/example/src/todo/Todo.tsx new file mode 100644 index 0000000..413a0e0 --- /dev/null +++ b/packages/example/src/todo/Todo.tsx @@ -0,0 +1,72 @@ +import * as Domain from "@/domain" +import { Button, Flex, TextArea } from "@radix-ui/themes" +import { GetRandomValues, makeUuid4 } from "@typed/id" +import { Chunk, Effect, Match, Option, pipe, Ref, Runtime, SubscriptionRef } from "effect" +import { ReactComponent, ReactHook } from "effect-fc" +import { SubscriptionSubRef } from "effect-fc/types" +import * as React from "react" +import { TodosState } from "./TodosState.service" + + +export type TodoProps = ( + | { + readonly _tag: "new" + readonly ref?: never + } + | { + readonly _tag: "edit" + readonly ref: SubscriptionRef.SubscriptionRef + } +) + +export const Todo = pipe( + Effect.fn(function*(props: TodoProps) { + const runtime = yield* Effect.runtime() + const state = yield* TodosState + + const ref = yield* ReactHook.useMemo(() => Match.value(props).pipe( + Match.tag("new", () => Effect.andThen(makeTodo, SubscriptionRef.make)), + Match.tag("edit", ({ ref }) => Effect.succeed(ref)), + Match.exhaustive, + ), [props._tag, props.ref]) + + const contentRef = React.useMemo(() => SubscriptionSubRef.makeFromPath(ref, ["content"]), [ref]) + const [todo] = yield* ReactHook.useSubscribeRefs(ref) + + return ( + +