0.2.6 #49

Merged
Thilawyn merged 48 commits from next into master 2026-05-04 02:10:53 +02:00
2 changed files with 16 additions and 14 deletions
Showing only changes of commit 51f01ce402 - Show all commits

View File

@@ -209,7 +209,7 @@ export class SynchronizedFormImpl<
readonly isValidating: Subscribable.Subscribable<boolean, never, never>, readonly isValidating: Subscribable.Subscribable<boolean, never, never>,
readonly canCommit: Subscribable.Subscribable<boolean, never, never>, readonly canCommit: Subscribable.Subscribable<boolean, never, never>,
readonly isCommitting: Subscribable.Subscribable<boolean, never, never>, readonly isCommitting: Lens.Lens<boolean, never, never>,
readonly runSemaphore: Effect.Semaphore, readonly runSemaphore: Effect.Semaphore,
) { ) {
@@ -248,7 +248,13 @@ export class SynchronizedFormImpl<
)).pipe( )).pipe(
Effect.tap(fiber => Lens.set(this.validationFiber, Option.some(fiber))), Effect.tap(fiber => Lens.set(this.validationFiber, Option.some(fiber))),
Effect.andThen(Fiber.join), Effect.andThen(Fiber.join),
Effect.tap(value => Lens.set(this.target, value)), Effect.tap(value => Effect.onExit(
Effect.andThen(
Lens.set(this.isCommitting, true),
Lens.set(this.target, value),
),
() => Lens.set(this.isCommitting, false),
)),
Effect.forkScoped, Effect.forkScoped,
) )
), ),
@@ -280,12 +286,6 @@ export const isForm = (u: unknown): u is Form<readonly PropertyKey[], unknown, u
export const isSubmittableForm = (u: unknown): u is SubmittableForm<unknown, unknown, unknown, unknown, unknown, unknown, unknown> => Predicate.hasProperty(u, SubmittableFormTypeId) export const isSubmittableForm = (u: unknown): u is SubmittableForm<unknown, unknown, unknown, unknown, unknown, unknown, unknown> => Predicate.hasProperty(u, SubmittableFormTypeId)
export const isSynchronizedForm = (u: unknown): u is SynchronizedForm<unknown, unknown, unknown, unknown, unknown, unknown, unknown> => Predicate.hasProperty(u, SynchronizedFormTypeId) export const isSynchronizedForm = (u: unknown): u is SynchronizedForm<unknown, unknown, unknown, unknown, unknown, unknown, unknown> => Predicate.hasProperty(u, SynchronizedFormTypeId)
const falseSubscribable: Subscribable.Subscribable<boolean, never, never> = Subscribable.make({
get: Effect.succeed(false),
changes: Stream.make(false),
})
export declare namespace makeSubmittable { export declare namespace makeSubmittable {
export interface Options<in out A, in out I = A, in out R = never, in out MA = void, in out ME = never, in out MR = never, in out MP = never> export interface Options<in out A, in out I = A, in out R = never, in out MA = void, in out ME = never, in out MR = never, in out MP = never>
extends Mutation.make.Options< extends Mutation.make.Options<
@@ -369,6 +369,7 @@ export const makeSynchronized = Effect.fnUntraced(function* <A, I = A, R = never
const valueLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none<A>())) const valueLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none<A>()))
const issuesLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make<readonly ParseResult.ArrayFormatterIssue[]>(Array.empty())) const issuesLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make<readonly ParseResult.ArrayFormatterIssue[]>(Array.empty()))
const validationFiberLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none<Fiber.Fiber<A, ParseResult.ParseError>>())) const validationFiberLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none<Fiber.Fiber<A, ParseResult.ParseError>>()))
const isCommittingLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(false))
const initialEncodedValue = yield* Lens.get(options.target).pipe( const initialEncodedValue = yield* Lens.get(options.target).pipe(
Effect.flatMap(Schema.encode(options.schema, { errors: "all" })), Effect.flatMap(Schema.encode(options.schema, { errors: "all" })),
) )
@@ -385,14 +386,15 @@ export const makeSynchronized = Effect.fnUntraced(function* <A, I = A, R = never
Subscribable.map(validationFiberLens, Option.isSome), Subscribable.map(validationFiberLens, Option.isSome),
Subscribable.map( Subscribable.map(
Subscribable.zipLatestAll(valueLens, issuesLens, validationFiberLens), Subscribable.zipLatestAll(valueLens, issuesLens, validationFiberLens, isCommittingLens),
([value, issues, validationFiber]) => ( ([value, issues, validationFiber, isCommitting]) => (
Option.isSome(value) && Option.isSome(value) &&
Array.isEmptyReadonlyArray(issues) && Array.isEmptyReadonlyArray(issues) &&
Option.isNone(validationFiber) Option.isNone(validationFiber) &&
!isCommitting
), ),
), ),
falseSubscribable, isCommittingLens,
yield* Effect.makeSemaphore(1), yield* Effect.makeSemaphore(1),
) )
@@ -565,7 +567,7 @@ export const useInput = Effect.fnUntraced(function* <P extends readonly Property
), ),
internalValue => Lens.set(form.encodedValue, internalValue), internalValue => Lens.set(form.encodedValue, internalValue),
), ),
], { concurrency: "unbounded" })) ], { concurrency: "unbounded", discard: true }))
return internalValueLens return internalValueLens
}), [form, options?.debounce]) }), [form, options?.debounce])

View File

@@ -1,4 +1,4 @@
import { Cause, Context, Data, Effect, Equal, Exit, type Fiber, Hash, Layer, Match, pipe, Pipeable, Predicate, PubSub, Ref, type Scope, Stream, type Subscribable, SynchronizedRef } from "effect" import { Cause, Context, Data, Effect, Equal, Exit, type Fiber, Hash, Layer, Match, Pipeable, Predicate, PubSub, pipe, Ref, type Scope, Stream, type Subscribable, SynchronizedRef } from "effect"
import { Lens } from "effect-lens" import { Lens } from "effect-lens"