@@ -1,4 +1,4 @@
|
|||||||
import { type Duration, Effect, Equal, type Equivalence, flow, identity, Option, type ParseResult, Ref, Schema, Stream, SubscriptionRef } from "effect"
|
import { type Duration, Effect, Equal, Equivalence, flow, identity, Option, type ParseResult, Ref, Schema, Stream, SubscriptionRef } from "effect"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { useFork } from "../useFork.js"
|
import { useFork } from "../useFork.js"
|
||||||
import { useOnce } from "../useOnce.js"
|
import { useOnce } from "../useOnce.js"
|
||||||
@@ -32,7 +32,7 @@ export const useInput: {
|
|||||||
yield* useFork(() => Effect.all([
|
yield* useFork(() => Effect.all([
|
||||||
// Sync the upstream state with the internal state
|
// Sync the upstream state with the internal state
|
||||||
// Only mutate the internal state if the upstream value is actually different. This avoids infinite re-render loops.
|
// Only mutate the internal state if the upstream value is actually different. This avoids infinite re-render loops.
|
||||||
Stream.runForEach(options.ref.changes, upstreamValue =>
|
Stream.runForEach(Stream.drop(Stream.changesWith(options.ref.changes, Equivalence.strict()), 1), upstreamValue =>
|
||||||
Effect.whenEffect(
|
Effect.whenEffect(
|
||||||
Effect.andThen(
|
Effect.andThen(
|
||||||
Schema.encode(options.schema)(upstreamValue),
|
Schema.encode(options.schema)(upstreamValue),
|
||||||
@@ -48,7 +48,11 @@ export const useInput: {
|
|||||||
|
|
||||||
// Sync all changes to the internal state with upstream
|
// Sync all changes to the internal state with upstream
|
||||||
Stream.runForEach(
|
Stream.runForEach(
|
||||||
internalRef.changes.pipe(options.debounce ? Stream.debounce(options.debounce) : identity),
|
internalRef.changes.pipe(
|
||||||
|
Stream.changesWith(Equivalence.strict()),
|
||||||
|
options.debounce ? Stream.debounce(options.debounce) : identity,
|
||||||
|
Stream.drop(1),
|
||||||
|
),
|
||||||
flow(
|
flow(
|
||||||
Schema.decode(options.schema),
|
Schema.decode(options.schema),
|
||||||
Effect.andThen(v => Ref.set(options.ref, v)),
|
Effect.andThen(v => Ref.set(options.ref, v)),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { type Duration, Effect, Equal, type Equivalence, flow, identity, Option, type ParseResult, Ref, Schema, Stream, SubscriptionRef } from "effect"
|
import { type Duration, Effect, Equal, Equivalence, flow, identity, Option, type ParseResult, Ref, Schema, Stream, SubscriptionRef } from "effect"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { SetStateAction } from "../../../types/index.js"
|
import { SetStateAction } from "../../../types/index.js"
|
||||||
import { useCallbackSync } from "../useCallbackSync.js"
|
import { useCallbackSync } from "../useCallbackSync.js"
|
||||||
@@ -50,7 +50,7 @@ export const useOptionalInput: {
|
|||||||
yield* useFork(() => Effect.all([
|
yield* useFork(() => Effect.all([
|
||||||
// Sync the upstream state with the internal state
|
// Sync the upstream state with the internal state
|
||||||
// Only mutate the internal state if the upstream value is actually different. This avoids infinite re-render loops.
|
// Only mutate the internal state if the upstream value is actually different. This avoids infinite re-render loops.
|
||||||
Stream.runForEach(options.ref.changes, Option.match({
|
Stream.runForEach(Stream.drop(Stream.changesWith(options.ref.changes, Equivalence.strict()), 1), Option.match({
|
||||||
onSome: upstreamValue => Effect.whenEffect(
|
onSome: upstreamValue => Effect.whenEffect(
|
||||||
Effect.andThen(
|
Effect.andThen(
|
||||||
Schema.encode(options.schema)(upstreamValue),
|
Schema.encode(options.schema)(upstreamValue),
|
||||||
@@ -68,7 +68,11 @@ export const useOptionalInput: {
|
|||||||
|
|
||||||
// Sync all changes to the internal state with upstream
|
// Sync all changes to the internal state with upstream
|
||||||
Stream.runForEach(
|
Stream.runForEach(
|
||||||
internalRef.changes.pipe(options.debounce ? Stream.debounce(options.debounce) : identity),
|
internalRef.changes.pipe(
|
||||||
|
Stream.changesWith(Equivalence.strict()),
|
||||||
|
options.debounce ? Stream.debounce(options.debounce) : identity,
|
||||||
|
Stream.drop(1),
|
||||||
|
),
|
||||||
flow(
|
flow(
|
||||||
Schema.decode(options.schema),
|
Schema.decode(options.schema),
|
||||||
Effect.andThen(v => Ref.set(options.ref, Option.some(v))),
|
Effect.andThen(v => Ref.set(options.ref, Option.some(v))),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const useRefState: {
|
|||||||
const [reactStateValue, setReactStateValue] = React.useState(yield* useOnce(() => ref))
|
const [reactStateValue, setReactStateValue] = React.useState(yield* useOnce(() => ref))
|
||||||
|
|
||||||
yield* useFork(() => Stream.runForEach(
|
yield* useFork(() => Stream.runForEach(
|
||||||
Stream.changesWith(ref.changes, Equivalence.strict()),
|
Stream.drop(Stream.changesWith(ref.changes, Equivalence.strict()), 1),
|
||||||
v => Effect.sync(() => setReactStateValue(v)),
|
v => Effect.sync(() => setReactStateValue(v)),
|
||||||
), [ref])
|
), [ref])
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const useSubscribeRefs: {
|
|||||||
))
|
))
|
||||||
|
|
||||||
yield* useFork(() => pipe(
|
yield* useFork(() => pipe(
|
||||||
refs.map(ref => Stream.changesWith(ref.changes, Equivalence.strict())),
|
refs.map(ref => Stream.drop(Stream.changesWith(ref.changes, Equivalence.strict()), 1)),
|
||||||
streams => Stream.zipLatestAll(...streams),
|
streams => Stream.zipLatestAll(...streams),
|
||||||
Stream.runForEach(v =>
|
Stream.runForEach(v =>
|
||||||
Effect.sync(() => setReactStateValue(v))
|
Effect.sync(() => setReactStateValue(v))
|
||||||
|
|||||||
Reference in New Issue
Block a user