0.2.2 #31

Merged
Thilawyn merged 184 commits from next into master 2026-01-16 17:05:31 +01:00
2 changed files with 24 additions and 8 deletions
Showing only changes of commit 87e7b74ed6 - Show all commits

View File

@@ -490,7 +490,7 @@ export const useOnMount: {
}) })
export namespace useOnChange { export namespace useOnChange {
export type Options = useScope.Options export interface Options extends useScope.Options {}
} }
export const useOnChange: { export const useOnChange: {
@@ -578,6 +578,22 @@ export const useReactLayoutEffect: {
React.useLayoutEffect(() => runReactEffect(runtime, f, options), deps) React.useLayoutEffect(() => runReactEffect(runtime, f, options), deps)
}) })
export const useRunSync: {
<R = never>(): Effect.Effect<<A, E = never>(effect: Effect.Effect<A, E, R>) => A, never, Scope.Scope | R>
} = Effect.fnUntraced(function* <Args extends unknown[], A, E, R>(
f: (...args: Args) => Effect.Effect<A, E, R>,
deps: React.DependencyList,
) {
// biome-ignore lint/style/noNonNullAssertion: context initialization
const runtimeRef = React.useRef<Runtime.Runtime<R>>(null!)
runtimeRef.current = yield* Effect.runtime<R>()
Runtime.runSync()
// biome-ignore lint/correctness/useExhaustiveDependencies: use of React.DependencyList
return React.useCallback((...args: Args) => Runtime.runSync(runtimeRef.current)(f(...args)), deps)
})
export const useCallbackSync: { export const useCallbackSync: {
<Args extends unknown[], A, E, R>( <Args extends unknown[], A, E, R>(
f: (...args: Args) => Effect.Effect<A, E, R>, f: (...args: Args) => Effect.Effect<A, E, R>,
@@ -613,13 +629,13 @@ export const useCallbackPromise: {
}) })
export namespace useContext { export namespace useContext {
export type Options = useOnChange.Options export interface Options extends useOnChange.Options {}
} }
export const useContext = <ROut, E, RIn>( export const useContext = <ROut, E, RIn>(
layer: Layer.Layer<ROut, E, RIn>, layer: Layer.Layer<ROut, E, RIn>,
options?: useContext.Options, options?: useContext.Options,
): Effect.Effect<Context.Context<ROut>, E, RIn> => useOnChange(() => Effect.context<RIn>().pipe( ): Effect.Effect<Context.Context<ROut>, E, Scope.Scope | RIn> => useOnChange(() => Effect.context<RIn>().pipe(
Effect.map(context => ManagedRuntime.make(Layer.provide(layer, Layer.succeedContext(context)))), Effect.map(context => ManagedRuntime.make(Layer.provide(layer, Layer.succeedContext(context)))),
Effect.tap(runtime => Effect.addFinalizer(() => runtime.disposeEffect)), Effect.tap(runtime => Effect.addFinalizer(() => runtime.disposeEffect)),
Effect.andThen(runtime => runtime.runtimeEffect), Effect.andThen(runtime => runtime.runtimeEffect),

View File

@@ -39,10 +39,10 @@ class RegisterForm extends Effect.Service<RegisterForm>()("RegisterForm", {
), ),
initialEncodedValue: { email: "", password: "", birth: Option.none() }, initialEncodedValue: { email: "", password: "", birth: Option.none() },
onSubmit: v => Effect.sleep("500 millis").pipe( onSubmit: Effect.fnUntraced(function*(v) {
Effect.andThen(Console.log(v)), yield* Effect.sleep("500 millis")
Effect.andThen(Effect.sync(() => alert("Done!"))), return v
), }),
debounce: "500 millis", debounce: "500 millis",
}) })
}) {} }) {}
@@ -93,7 +93,7 @@ class RegisterFormView extends Component.makeUntraced("RegisterFormView")(functi
Match.tag("Initial", () => <></>), Match.tag("Initial", () => <></>),
Match.tag("Running", () => <Text>Submitting...</Text>), Match.tag("Running", () => <Text>Submitting...</Text>),
Match.tag("Success", () => <Text>Submitted successfully!</Text>), Match.tag("Success", () => <Text>Submitted successfully!</Text>),
Match.tag("Failure", v => <Text>Error: {v.cause.toString()}</Text>), Match.tag("Failure", e => <Text>Error: {e.cause.toString()}</Text>),
Match.exhaustive, Match.exhaustive,
)} )}
</Container> </Container>