This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Context, Effect, Effectable, ExecutionStrategy, Function, Predicate, Runtime, Scope, String, Tracer, type Types, type Utils } from "effect"
|
import { Context, Effect, Effectable, ExecutionStrategy, Function, Predicate, Runtime, Scope, Tracer, type Types, type Utils } from "effect"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { Hooks } from "./hooks/index.js"
|
import { Hooks } from "./hooks/index.js"
|
||||||
import * as Memo from "./Memo.js"
|
import * as Memo from "./Memo.js"
|
||||||
@@ -331,13 +331,9 @@ export const make: (
|
|||||||
) => make.Gen & make.NonGen)
|
) => make.Gen & make.NonGen)
|
||||||
) = (spanNameOrBody: Function | string, ...pipeables: any[]): any => {
|
) = (spanNameOrBody: Function | string, ...pipeables: any[]): any => {
|
||||||
if (typeof spanNameOrBody !== "string") {
|
if (typeof spanNameOrBody !== "string") {
|
||||||
const displayName = displayNameFromBody(spanNameOrBody)
|
|
||||||
return Object.setPrototypeOf(
|
return Object.setPrototypeOf(
|
||||||
Object.assign(function() {}, defaultOptions, {
|
Object.assign(function() {}, defaultOptions, {
|
||||||
body: displayName
|
body: Effect.fn(spanNameOrBody as any, ...pipeables),
|
||||||
? Effect.fn(displayName)(spanNameOrBody as any, ...pipeables as [])
|
|
||||||
: Effect.fn(spanNameOrBody as any, ...pipeables),
|
|
||||||
displayName,
|
|
||||||
}),
|
}),
|
||||||
ComponentProto,
|
ComponentProto,
|
||||||
)
|
)
|
||||||
@@ -347,26 +343,34 @@ export const make: (
|
|||||||
return (body: any, ...pipeables: any[]) => Object.setPrototypeOf(
|
return (body: any, ...pipeables: any[]) => Object.setPrototypeOf(
|
||||||
Object.assign(function() {}, defaultOptions, {
|
Object.assign(function() {}, defaultOptions, {
|
||||||
body: Effect.fn(spanNameOrBody, spanOptions)(body, ...pipeables as []),
|
body: Effect.fn(spanNameOrBody, spanOptions)(body, ...pipeables as []),
|
||||||
displayName: displayNameFromBody(body) ?? spanNameOrBody,
|
displayName: spanNameOrBody,
|
||||||
}),
|
}),
|
||||||
ComponentProto,
|
ComponentProto,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const makeUntraced: make.Gen & make.NonGen = (
|
export const makeUntraced: (
|
||||||
body: Function,
|
& make.Gen
|
||||||
...pipeables: any[]
|
& make.NonGen
|
||||||
) => Object.setPrototypeOf(
|
& ((name: string) => make.Gen & make.NonGen)
|
||||||
|
) = (spanNameOrBody: Function | string, ...pipeables: any[]): any => (
|
||||||
|
typeof spanNameOrBody !== "string"
|
||||||
|
? Object.setPrototypeOf(
|
||||||
Object.assign(function() {}, defaultOptions, {
|
Object.assign(function() {}, defaultOptions, {
|
||||||
body: Effect.fnUntraced(body as any, ...pipeables as []),
|
body: Effect.fnUntraced(spanNameOrBody as any, ...pipeables as []),
|
||||||
displayName: displayNameFromBody(body),
|
|
||||||
}),
|
}),
|
||||||
ComponentProto,
|
ComponentProto,
|
||||||
|
)
|
||||||
|
: (body: any, ...pipeables: any[]) => Object.setPrototypeOf(
|
||||||
|
Object.assign(function() {}, defaultOptions, {
|
||||||
|
body: Effect.fnUntraced(body, ...pipeables as []),
|
||||||
|
displayName: spanNameOrBody,
|
||||||
|
}),
|
||||||
|
ComponentProto,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
const displayNameFromBody = (body: Function) => !String.isEmpty(body.name) ? body.name : undefined
|
|
||||||
|
|
||||||
export const withOptions: {
|
export const withOptions: {
|
||||||
<T extends Component<any, any, any, any>>(
|
<T extends Component<any, any, any, any>>(
|
||||||
options: Partial<Component.Options>
|
options: Partial<Component.Options>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const TextAreaInput = <A, R>(options: {
|
|||||||
React.JSX.Element,
|
React.JSX.Element,
|
||||||
ParseResult.ParseError,
|
ParseResult.ParseError,
|
||||||
R
|
R
|
||||||
> => Component.makeUntraced(function* TextFieldInput(props) {
|
> => Component.makeUntraced("TextFieldInput")(function* TextFieldInput(props) {
|
||||||
const input = yield* useInput({ ...options, ...props })
|
const input = yield* useInput({ ...options, ...props })
|
||||||
const issue = React.useMemo(() => input.error.pipe(
|
const issue = React.useMemo(() => input.error.pipe(
|
||||||
Option.map(ParseResult.ArrayFormatter.formatErrorSync),
|
Option.map(ParseResult.ArrayFormatter.formatErrorSync),
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const TextFieldInput = <A, R, O extends boolean = false>(options: {
|
|||||||
readonly optional?: O
|
readonly optional?: O
|
||||||
readonly schema: Schema.Schema<A, string, R>
|
readonly schema: Schema.Schema<A, string, R>
|
||||||
readonly equivalence?: Equivalence.Equivalence<A>
|
readonly equivalence?: Equivalence.Equivalence<A>
|
||||||
}) => Component.makeUntraced(function* TextFieldInput(props: O extends true
|
}) => Component.makeUntraced("TextFieldInput")(function* TextFieldInput(props: O extends true
|
||||||
? TextFieldOptionalInputProps<A, R>
|
? TextFieldOptionalInputProps<A, R>
|
||||||
: TextFieldInputProps<A, R>
|
: TextFieldInputProps<A, R>
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const RouteComponent = Component.makeUntraced(function* AsyncRendering() {
|
|||||||
// )
|
// )
|
||||||
|
|
||||||
|
|
||||||
class AsyncComponent extends Component.makeUntraced(function* AsyncComponent() {
|
class AsyncComponent extends Component.makeUntraced("AsyncComponent")(function*() {
|
||||||
const SubComponentFC = yield* SubComponent
|
const SubComponentFC = yield* SubComponent
|
||||||
|
|
||||||
yield* Effect.sleep("500 millis") // Async operation
|
yield* Effect.sleep("500 millis") // Async operation
|
||||||
@@ -69,7 +69,7 @@ class AsyncComponent extends Component.makeUntraced(function* AsyncComponent() {
|
|||||||
) {}
|
) {}
|
||||||
class MemoizedAsyncComponent extends Memo.memo(AsyncComponent) {}
|
class MemoizedAsyncComponent extends Memo.memo(AsyncComponent) {}
|
||||||
|
|
||||||
class SubComponent extends Component.makeUntraced(function* SubComponent() {
|
class SubComponent extends Component.makeUntraced("SubComponent")(function*() {
|
||||||
const [state] = React.useState(yield* Hooks.useOnce(() => Effect.provide(makeUuid4, GetRandomValues.CryptoRandom)))
|
const [state] = React.useState(yield* Hooks.useOnce(() => Effect.provide(makeUuid4, GetRandomValues.CryptoRandom)))
|
||||||
return <Text>{state}</Text>
|
return <Text>{state}</Text>
|
||||||
}) {}
|
}) {}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Container } from "@radix-ui/themes"
|
|||||||
import { createFileRoute } from "@tanstack/react-router"
|
import { createFileRoute } from "@tanstack/react-router"
|
||||||
import { Schema, SubscriptionRef } from "effect"
|
import { Schema, SubscriptionRef } from "effect"
|
||||||
import { Component, Memo } from "effect-fc"
|
import { Component, Memo } from "effect-fc"
|
||||||
import { useInput, useOnce, useRefState } from "effect-fc/hooks"
|
import { useOnce } from "effect-fc/hooks"
|
||||||
|
|
||||||
|
|
||||||
const IntFromString = Schema.NumberFromString.pipe(Schema.int())
|
const IntFromString = Schema.NumberFromString.pipe(Schema.int())
|
||||||
@@ -12,18 +12,18 @@ const IntFromString = Schema.NumberFromString.pipe(Schema.int())
|
|||||||
const IntTextFieldInput = TextFieldInput({ schema: IntFromString })
|
const IntTextFieldInput = TextFieldInput({ schema: IntFromString })
|
||||||
const StringTextFieldInput = TextFieldInput({ schema: Schema.String })
|
const StringTextFieldInput = TextFieldInput({ schema: Schema.String })
|
||||||
|
|
||||||
const Input = Component.makeUntraced(function* Input() {
|
const Input = Component.makeUntraced("Input")(function*() {
|
||||||
const IntTextFieldInputFC = yield* IntTextFieldInput
|
const IntTextFieldInputFC = yield* IntTextFieldInput
|
||||||
const StringTextFieldInputFC = yield* StringTextFieldInput
|
const StringTextFieldInputFC = yield* StringTextFieldInput
|
||||||
|
|
||||||
const intRef1 = yield* useOnce(() => SubscriptionRef.make(0))
|
const intRef1 = yield* useOnce(() => SubscriptionRef.make(0))
|
||||||
const intRef2 = yield* useOnce(() => SubscriptionRef.make(0))
|
// const intRef2 = yield* useOnce(() => SubscriptionRef.make(0))
|
||||||
const stringRef = yield* useOnce(() => SubscriptionRef.make(""))
|
const stringRef = yield* useOnce(() => SubscriptionRef.make(""))
|
||||||
// yield* useFork(() => Stream.runForEach(intRef1.changes, Console.log), [intRef1])
|
// yield* useFork(() => Stream.runForEach(intRef1.changes, Console.log), [intRef1])
|
||||||
|
|
||||||
const input2 = yield* useInput({ schema: IntFromString, ref: intRef2 })
|
// const input2 = yield* useInput({ schema: IntFromString, ref: intRef2 })
|
||||||
|
|
||||||
const [str, setStr] = yield* useRefState(stringRef)
|
// const [str, setStr] = yield* useRefState(stringRef)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Component, Memo } from "effect-fc"
|
|||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
|
|
||||||
|
|
||||||
const RouteComponent = Component.makeUntraced(function* RouteComponent() {
|
const RouteComponent = Component.makeUntraced("RouteComponent")(function*() {
|
||||||
const [value, setValue] = React.useState("")
|
const [value, setValue] = React.useState("")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -25,7 +25,7 @@ const RouteComponent = Component.makeUntraced(function* RouteComponent() {
|
|||||||
Component.withRuntime(runtime.context)
|
Component.withRuntime(runtime.context)
|
||||||
)
|
)
|
||||||
|
|
||||||
class SubComponent extends Component.makeUntraced(function* SubComponent() {
|
class SubComponent extends Component.makeUntraced("SubComponent")(function*() {
|
||||||
const id = yield* makeUuid4.pipe(Effect.provide(GetRandomValues.CryptoRandom))
|
const id = yield* makeUuid4.pipe(Effect.provide(GetRandomValues.CryptoRandom))
|
||||||
return <Text>{id}</Text>
|
return <Text>{id}</Text>
|
||||||
}) {}
|
}) {}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class RegisterForm extends Effect.Service<RegisterForm>()("RegisterForm", {
|
|||||||
})
|
})
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
class RegisterPage extends Component.makeUntraced(function* RegisterPage() {
|
class RegisterPage extends Component.makeUntraced("RegisterPage")(function*() {
|
||||||
const form = yield* RegisterForm
|
const form = yield* RegisterForm
|
||||||
const emailInput = yield* Form.useInput(form, ["email"], { debounce: "200 millis" })
|
const emailInput = yield* Form.useInput(form, ["email"], { debounce: "200 millis" })
|
||||||
const passwordInput = yield* Form.useInput(form, ["password"], { debounce: "200 millis" })
|
const passwordInput = yield* Form.useInput(form, ["password"], { debounce: "200 millis" })
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useContext } from "effect-fc/hooks"
|
|||||||
|
|
||||||
const TodosStateLive = TodosState.Default("todos")
|
const TodosStateLive = TodosState.Default("todos")
|
||||||
|
|
||||||
const Index = Component.makeUntraced(function* Index() {
|
const Index = Component.makeUntraced("Index")(function*() {
|
||||||
const context = yield* useContext(TodosStateLive, { finalizerExecutionMode: "fork" })
|
const context = yield* useContext(TodosStateLive, { finalizerExecutionMode: "fork" })
|
||||||
const TodosFC = yield* Effect.provide(Todos, context)
|
const TodosFC = yield* Effect.provide(Todos, context)
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export type TodoProps = (
|
|||||||
| { readonly _tag: "edit", readonly id: string }
|
| { readonly _tag: "edit", readonly id: string }
|
||||||
)
|
)
|
||||||
|
|
||||||
export class Todo extends Component.makeUntraced(function* Todo(props: TodoProps) {
|
export class Todo extends Component.makeUntraced("Todo")(function*(props: TodoProps) {
|
||||||
const runtime = yield* Effect.runtime()
|
const runtime = yield* Effect.runtime()
|
||||||
const state = yield* TodosState
|
const state = yield* TodosState
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Todo } from "./Todo"
|
|||||||
import { TodosState } from "./TodosState.service"
|
import { TodosState } from "./TodosState.service"
|
||||||
|
|
||||||
|
|
||||||
export class Todos extends Component.makeUntraced(function* Todos() {
|
export class Todos extends Component.makeUntraced("Todos")(function*() {
|
||||||
const state = yield* TodosState
|
const state = yield* TodosState
|
||||||
const [todos] = yield* useSubscribe(state.ref)
|
const [todos] = yield* useSubscribe(state.ref)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user