From 4c253fcfe848c566f9f57bc445b0b31f91da4459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 2 Oct 2025 12:08:04 +0200 Subject: [PATCH] Fixes --- .../example/src/lib/input/TextAreaInput.tsx | 2 +- .../example/src/lib/input/TextFieldInput.tsx | 2 +- .../src/routes/dev/async-rendering.tsx | 11 ++++---- packages/example/src/routes/dev/input.tsx | 13 ++++----- packages/example/src/routes/dev/memo.tsx | 6 ++-- packages/example/src/routes/form.tsx | 28 +++++++++---------- packages/example/src/routes/index.tsx | 9 +++--- packages/example/src/todo/Todo.tsx | 8 ++++-- packages/example/src/todo/Todos.tsx | 7 ++--- 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/packages/example/src/lib/input/TextAreaInput.tsx b/packages/example/src/lib/input/TextAreaInput.tsx index 64fb1a0..03d4359 100644 --- a/packages/example/src/lib/input/TextAreaInput.tsx +++ b/packages/example/src/lib/input/TextAreaInput.tsx @@ -16,7 +16,7 @@ export const TextAreaInput = (options: { React.JSX.Element, ParseResult.ParseError, R -> => Component.makeUntraced("TextFieldInput")(function* TextFieldInput(props) { +> => Component.makeUntraced("TextFieldInput")(function*(props) { const input = yield* useInput({ ...options, ...props }) const issue = React.useMemo(() => input.error.pipe( Option.map(ParseResult.ArrayFormatter.formatErrorSync), diff --git a/packages/example/src/lib/input/TextFieldInput.tsx b/packages/example/src/lib/input/TextFieldInput.tsx index 905c0f8..e0bf339 100644 --- a/packages/example/src/lib/input/TextFieldInput.tsx +++ b/packages/example/src/lib/input/TextFieldInput.tsx @@ -19,7 +19,7 @@ export const TextFieldInput = (options: { readonly optional?: O readonly schema: Schema.Schema readonly equivalence?: Equivalence.Equivalence -}) => Component.makeUntraced("TextFieldInput")(function* TextFieldInput(props: O extends true +}) => Component.makeUntraced("TextFieldInput")(function*(props: O extends true ? TextFieldOptionalInputProps : TextFieldInputProps ) { diff --git a/packages/example/src/routes/dev/async-rendering.tsx b/packages/example/src/routes/dev/async-rendering.tsx index fadd316..e5a23e8 100644 --- a/packages/example/src/routes/dev/async-rendering.tsx +++ b/packages/example/src/routes/dev/async-rendering.tsx @@ -1,11 +1,10 @@ -import { runtime } from "@/runtime" import { Flex, Text, TextField } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { GetRandomValues, makeUuid4 } from "@typed/id" import { Effect } from "effect" -import { Component, Memo, Suspense } from "effect-fc" -import { Hooks } from "effect-fc/hooks" +import { Async, Component, Hooks, Memoized } from "effect-fc" import * as React from "react" +import { runtime } from "@/runtime" // Generator version @@ -64,10 +63,10 @@ class AsyncComponent extends Component.makeUntraced("AsyncComponent")(function*( ) }).pipe( - Suspense.suspense, - Suspense.withOptions({ defaultFallback:

Loading...

}), + Async.async, + Async.withOptions({ defaultFallback:

Loading...

}), ) {} -class MemoizedAsyncComponent extends Memo.memo(AsyncComponent) {} +class MemoizedAsyncComponent extends Memoized.memoized(AsyncComponent) {} class SubComponent extends Component.makeUntraced("SubComponent")(function*() { const [state] = React.useState(yield* Hooks.useOnce(() => Effect.provide(makeUuid4, GetRandomValues.CryptoRandom))) diff --git a/packages/example/src/routes/dev/input.tsx b/packages/example/src/routes/dev/input.tsx index 9a8a53f..ef20057 100644 --- a/packages/example/src/routes/dev/input.tsx +++ b/packages/example/src/routes/dev/input.tsx @@ -1,10 +1,9 @@ -import { TextFieldInput } from "@/lib/input/TextFieldInput" -import { runtime } from "@/runtime" import { Container } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { Schema, SubscriptionRef } from "effect" -import { Component, Memo } from "effect-fc" -import { useOnce } from "effect-fc/hooks" +import { Component, Hooks, Memoized } from "effect-fc" +import { TextFieldInput } from "@/lib/input/TextFieldInput" +import { runtime } from "@/runtime" const IntFromString = Schema.NumberFromString.pipe(Schema.int()) @@ -16,9 +15,9 @@ const Input = Component.makeUntraced("Input")(function*() { const IntTextFieldInputFC = yield* IntTextFieldInput const StringTextFieldInputFC = yield* StringTextFieldInput - const intRef1 = yield* useOnce(() => SubscriptionRef.make(0)) + const intRef1 = yield* Hooks.useOnce(() => SubscriptionRef.make(0)) // const intRef2 = yield* useOnce(() => SubscriptionRef.make(0)) - const stringRef = yield* useOnce(() => SubscriptionRef.make("")) + const stringRef = yield* Hooks.useOnce(() => SubscriptionRef.make("")) // yield* useFork(() => Stream.runForEach(intRef1.changes, Console.log), [intRef1]) // const input2 = yield* useInput({ schema: IntFromString, ref: intRef2 }) @@ -33,7 +32,7 @@ const Input = Component.makeUntraced("Input")(function*() { ) }).pipe( - Memo.memo, + Memoized.memoized, Component.withRuntime(runtime.context) ) diff --git a/packages/example/src/routes/dev/memo.tsx b/packages/example/src/routes/dev/memo.tsx index b81f132..87ece9c 100644 --- a/packages/example/src/routes/dev/memo.tsx +++ b/packages/example/src/routes/dev/memo.tsx @@ -1,10 +1,10 @@ -import { runtime } from "@/runtime" import { Flex, Text, TextField } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { GetRandomValues, makeUuid4 } from "@typed/id" import { Effect } from "effect" -import { Component, Memo } from "effect-fc" +import { Component, Memoized } from "effect-fc" import * as React from "react" +import { runtime } from "@/runtime" const RouteComponent = Component.makeUntraced("RouteComponent")(function*() { @@ -30,7 +30,7 @@ class SubComponent extends Component.makeUntraced("SubComponent")(function*() { return {id} }) {} -class MemoizedSubComponent extends Memo.memo(SubComponent) {} +class MemoizedSubComponent extends Memoized.memoized(SubComponent) {} export const Route = createFileRoute("/dev/memo")({ component: RouteComponent, diff --git a/packages/example/src/routes/form.tsx b/packages/example/src/routes/form.tsx index 879f2f8..83c74ee 100644 --- a/packages/example/src/routes/form.tsx +++ b/packages/example/src/routes/form.tsx @@ -1,8 +1,8 @@ import { Button, Container, Flex } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { Effect, ParseResult, Schema } from "effect" -import { Component, Form } from "effect-fc" -import { useContext, useSubscribables } from "effect-fc/Hooks" +import { Component, Form, Hooks } from "effect-fc" +import { useSubscribables } from "effect-fc/Hooks" import { TextFieldFormInput } from "@/lib/form/TextFieldFormInput" import { runtime } from "@/runtime" @@ -29,7 +29,7 @@ class RegisterForm extends Effect.Service()("RegisterForm", { Schema.typeSchema(RegisterFormSchema), { decode: v => Effect.andThen(Effect.sleep("500 millis"), ParseResult.succeed(v)), - encode: v => Effect.andThen(Effect.sleep("500 millis"), ParseResult.succeed(v)), + encode: ParseResult.succeed, }, ), initialEncodedValue: { email: "", password: "" }, @@ -48,7 +48,7 @@ class RegisterPage extends Component.makeUntraced("RegisterPage")(function*() { const TextFieldFormInputFC = yield* TextFieldFormInput return ( - +
{ e.preventDefault() void submit() @@ -72,15 +72,15 @@ class RegisterPage extends Component.makeUntraced("RegisterPage")(function*() { }) {} -const RegisterRoute = Component.makeUntraced(function* RegisterRoute() { - const context = yield* useContext(RegisterForm.Default, { finalizerExecutionMode: "fork" }) - const RegisterRouteFC = yield* Effect.provide(RegisterPage, context) - - return -}).pipe( - Component.withRuntime(runtime.context) -) - export const Route = createFileRoute("/form")({ - component: RegisterRoute + component: Component.makeUntraced("RegisterRoute")(function*() { + const RegisterRouteFC = yield* Effect.provide( + RegisterPage, + yield* Hooks.useContext(RegisterForm.Default, { finalizerExecutionMode: "fork" }), + ) + + return + }).pipe( + Component.withRuntime(runtime.context) + ) }) diff --git a/packages/example/src/routes/index.tsx b/packages/example/src/routes/index.tsx index 3e0835c..8da0367 100644 --- a/packages/example/src/routes/index.tsx +++ b/packages/example/src/routes/index.tsx @@ -1,7 +1,6 @@ import { createFileRoute } from "@tanstack/react-router" import { Effect } from "effect" -import { Component } from "effect-fc" -import { useContext } from "effect-fc/Hooks" +import { Component, Hooks } from "effect-fc" import { runtime } from "@/runtime" import { Todos } from "@/todo/Todos" import { TodosState } from "@/todo/TodosState.service" @@ -10,8 +9,10 @@ import { TodosState } from "@/todo/TodosState.service" const TodosStateLive = TodosState.Default("todos") const Index = Component.makeUntraced("Index")(function*() { - const context = yield* useContext(TodosStateLive, { finalizerExecutionMode: "fork" }) - const TodosFC = yield* Effect.provide(Todos, context) + const TodosFC = yield* Effect.provide( + Todos, + yield* Hooks.useContext(TodosStateLive, { finalizerExecutionMode: "fork" }), + ) return }).pipe( diff --git a/packages/example/src/todo/Todo.tsx b/packages/example/src/todo/Todo.tsx index e84c504..9d575f1 100644 --- a/packages/example/src/todo/Todo.tsx +++ b/packages/example/src/todo/Todo.tsx @@ -1,7 +1,7 @@ import { Box, Button, Flex, IconButton } from "@radix-ui/themes" import { GetRandomValues, makeUuid4 } from "@typed/id" import { Chunk, DateTime, Effect, Match, Option, Ref, Runtime, Schema, Stream, SubscriptionRef } from "effect" -import { Component, Hooks } from "effect-fc" +import { Component, Hooks, Memoized, Subscribable, SubscriptionSubRef } from "effect-fc" import { FaArrowDown, FaArrowUp } from "react-icons/fa" import { FaDeleteLeft } from "react-icons/fa6" import * as Domain from "@/domain" @@ -64,7 +64,7 @@ export class Todo extends Component.makeUntraced("Todo")(function*(props: TodoPr DateTime.now)} + defaultValue={yield* Hooks.useOnce(() => DateTime.now)} /> {props._tag === "new" && @@ -106,4 +106,6 @@ export class Todo extends Component.makeUntraced("Todo")(function*(props: TodoPr } ) -}).pipe(Memo.memo) {} +}).pipe( + Memoized.memoized +) {} diff --git a/packages/example/src/todo/Todos.tsx b/packages/example/src/todo/Todos.tsx index 9b84082..3fb4076 100644 --- a/packages/example/src/todo/Todos.tsx +++ b/packages/example/src/todo/Todos.tsx @@ -1,16 +1,15 @@ import { Container, Flex, Heading } from "@radix-ui/themes" import { Chunk, Console, Effect } from "effect" -import { Component } from "effect-fc" -import { useOnce, useSubscribables } from "effect-fc/hooks" +import { Component, Hooks } from "effect-fc" import { Todo } from "./Todo" import { TodosState } from "./TodosState.service" export class Todos extends Component.makeUntraced("Todos")(function*() { const state = yield* TodosState - const [todos] = yield* useSubscribables(state.ref) + const [todos] = yield* Hooks.useSubscribables(state.ref) - yield* useOnce(() => Effect.andThen( + yield* Hooks.useOnce(() => Effect.andThen( Console.log("Todos mounted"), Effect.addFinalizer(() => Console.log("Todos unmounted")), ))