From b9e787f42bdd87b1ea72cfa93175cabd601f1463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 18 May 2025 15:45:31 +0200 Subject: [PATCH] Todos refactoring --- .../example/src/todos/services/TodosState.ts | 30 ++----------------- packages/example/src/todos/views/VNewTodo.tsx | 4 +-- packages/example/src/todos/views/VTodo.tsx | 21 +++++++------ 3 files changed, 16 insertions(+), 39 deletions(-) diff --git a/packages/example/src/todos/services/TodosState.ts b/packages/example/src/todos/services/TodosState.ts index a3735c8..4475c39 100644 --- a/packages/example/src/todos/services/TodosState.ts +++ b/packages/example/src/todos/services/TodosState.ts @@ -7,15 +7,8 @@ import { Chunk, Context, Effect, identity, Layer, ParseResult, Ref, Schema, Stre export class TodosState extends Context.Tag("TodosState")> - readonly load: Effect.Effect readonly save: Effect.Effect - - readonly prepend: (todo: Todo.Todo) => Effect.Effect - readonly replace: (index: number, todo: Todo.Todo) => Effect.Effect - readonly remove: (index: number) => Effect.Effect - // readonly moveUp: (index: number) => Effect.Effect - // readonly moveDown: (index: number) => Effect.Effect }>() {} @@ -41,30 +34,11 @@ export const make = (key: string) => Layer.effect(TodosState, Effect.gen(functio ) const todos = yield* SubscriptionRef.make(yield* readFromLocalStorage) - const load = Effect.flatMap(readFromLocalStorage, v => Ref.set(todos, v)) const save = Effect.flatMap(todos, writeToLocalStorage) - const prepend = (todo: Todo.Todo) => Ref.update(todos, Chunk.prepend(todo)) - const replace = (index: number, todo: Todo.Todo) => Ref.update(todos, Chunk.replace(index, todo)) - const remove = (index: number) => Ref.update(todos, Chunk.remove(index)) - - // const moveUp = (index: number) => Effect.gen(function*() { - - // }) - // Sync changes with local storage - yield* Effect.forkScoped(todos.changes.pipe( - Stream.debounce("500 millis"), - Stream.runForEach(writeToLocalStorage), - )) + yield* Effect.forkScoped(Stream.runForEach(todos.changes, writeToLocalStorage)) - return { - todos, - load, - save, - prepend, - replace, - remove, - } + return { todos, load, save } })) diff --git a/packages/example/src/todos/views/VNewTodo.tsx b/packages/example/src/todos/views/VNewTodo.tsx index 64d47ac..873942a 100644 --- a/packages/example/src/todos/views/VNewTodo.tsx +++ b/packages/example/src/todos/views/VNewTodo.tsx @@ -1,7 +1,7 @@ import { Todo } from "@/domain" import { Box, Button, Card, Flex, TextArea } from "@radix-ui/themes" import { GetRandomValues, makeUuid4 } from "@typed/id" -import { Effect, Option, Ref } from "effect" +import { Chunk, Effect, Option, Ref } from "effect" import { R } from "../reffuse" import { TodosState } from "../services" @@ -18,7 +18,7 @@ export function VNewTodo() { const [content, setContent] = R.useRefState(R.useSubRefFromPath(todoRef, ["content"])) const add = R.useCallbackSync(() => Effect.all([TodosState.TodosState, todoRef]).pipe( - Effect.flatMap(([state, todo]) => state.prepend(todo)), + Effect.flatMap(([state, todo]) => Ref.update(state.todos, Chunk.prepend(todo))), Effect.andThen(createEmptyTodo), Effect.flatMap(v => Ref.set(todoRef, v)), ), [todoRef]) diff --git a/packages/example/src/todos/views/VTodo.tsx b/packages/example/src/todos/views/VTodo.tsx index 11a7c43..6d75b68 100644 --- a/packages/example/src/todos/views/VTodo.tsx +++ b/packages/example/src/todos/views/VTodo.tsx @@ -1,6 +1,6 @@ import { Todo } from "@/domain" import { Box, Card, Flex, IconButton, TextArea } from "@radix-ui/themes" -import { Effect, Ref, SubscriptionRef } from "effect" +import { Effect, Ref, Stream, SubscriptionRef } from "effect" import { Delete } from "lucide-react" import { useState } from "react" import { R } from "../reffuse" @@ -14,7 +14,15 @@ export interface VTodoProps { export function VTodo({ todoRef, remove }: VTodoProps) { const runSync = R.useRunSync() - const [todo] = R.useSubscribeRefs(todoRef) + + const localTodoRef = R.useRef(() => todoRef) + const [content, setContent] = R.useRefState(R.useSubRefFromPath(localTodoRef, ["content"])) + + R.useFork(() => localTodoRef.changes.pipe( + Stream.debounce("250 millis"), + Stream.runForEach(v => Ref.set(todoRef, v)), + ), [localTodoRef]) + const editorMode = useState(false) @@ -23,13 +31,8 @@ export function VTodo({ todoRef, remove }: VTodoProps) {