Refactor Form
All checks were successful
Lint / lint (push) Successful in 14s

This commit is contained in:
Julien Valverdé
2026-03-30 01:00:13 +02:00
parent 7a16e17341
commit 0d1567f4a8

View File

@@ -1,4 +1,4 @@
import { Cause, Chunk, type Context, type Duration, Effect, Equal, Exit, Fiber, identity, Option, type ParseResult, Pipeable, Predicate, Schema, type Scope, Stream } from "effect"
import { Array, Cause, Chunk, type Context, type Duration, Effect, Equal, Exit, Fiber, identity, Option, ParseResult, Pipeable, Predicate, Schema, type Scope, Stream } from "effect"
import type * as React from "react"
import * as Component from "./Component.js"
import * as Lens from "./Lens.js"
@@ -18,7 +18,7 @@ extends Pipeable.Pipeable {
readonly path: P
readonly value: Subscribable.Subscribable<Option.Option<A>, ER, never>
readonly encodedValue: Lens.Lens<I, ER, EW, never, never>
readonly error: Subscribable.Subscribable<Option.Option<ParseResult.ParseError>, ER, never>
readonly issues: Subscribable.Subscribable<readonly ParseResult.ArrayFormatterIssue[], never, never>
readonly isValidating: Subscribable.Subscribable<boolean, ER, never>
readonly canSubmit: Subscribable.Subscribable<boolean, never, never>
}
@@ -31,7 +31,7 @@ extends Pipeable.Class() implements Form<P, A, I, ER, EW> {
readonly path: P,
readonly value: Subscribable.Subscribable<Option.Option<A>, ER, never>,
readonly encodedValue: Lens.Lens<I, ER, EW, never, never>,
readonly error: Subscribable.Subscribable<Option.Option<ParseResult.ParseError>, ER, never>,
readonly issues: Subscribable.Subscribable<readonly ParseResult.ArrayFormatterIssue[], never, never>,
readonly isValidating: Subscribable.Subscribable<boolean, never, never>,
readonly canSubmit: Subscribable.Subscribable<boolean, never, never>,
) {
@@ -77,7 +77,7 @@ extends Pipeable.Class() implements RootForm<A, I, R, MA, ME, MR, MP> {
readonly value: Lens.Lens<Option.Option<A>, never, never, never, never>,
readonly encodedValue: Lens.Lens<I, never, never, never, never>,
readonly error: Lens.Lens<Option.Option<ParseResult.ParseError>, never, never, never, never>,
readonly issues: Lens.Lens<readonly ParseResult.ArrayFormatterIssue[], never, never, never, never>,
readonly validationFiber: Lens.Lens<Option.Option<Fiber.Fiber<A, ParseResult.ParseError>>, never, never, never, never>,
readonly isValidating: Subscribable.Subscribable<boolean, never, never>,
readonly canSubmit: Subscribable.Subscribable<boolean, never, never>,
@@ -103,10 +103,13 @@ extends Pipeable.Class() implements RootForm<A, I, R, MA, ME, MR, MP> {
Exit.matchEffect(exit, {
onSuccess: v => Effect.andThen(
Lens.set(this.value, Option.some(v)),
Lens.set(this.error, Option.none()),
Lens.set(this.issues, Array.empty()),
),
onFailure: c => Option.match(Chunk.findFirst(Cause.failures(c), e => e._tag === "ParseError"), {
onSome: e => Lens.set(this.error, Option.some(e)),
onSome: e => Effect.flatMap(
ParseResult.ArrayFormatter.formatError(e),
v => Lens.set(this.issues, v),
),
onNone: () => Effect.void,
}),
}),
@@ -145,7 +148,10 @@ extends Pipeable.Class() implements RootForm<A, I, R, MA, ME, MR, MP> {
e => e._tag === "ParseError",
),
{
onSome: e => Lens.set(this.error, Option.some(e)),
onSome: e => Effect.flatMap(
ParseResult.ArrayFormatter.formatError(e),
v => Lens.set(this.issues, v),
),
onNone: () => Effect.void,
},
)
@@ -183,7 +189,7 @@ export const make = Effect.fnUntraced(function* <A, I = A, R = never, MA = void,
> {
const mutation = yield* Mutation.make(options)
const valueLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none<A>()))
const errorLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none<ParseResult.ParseError>()))
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>>()))
return new RootFormImpl(
@@ -194,14 +200,14 @@ export const make = Effect.fnUntraced(function* <A, I = A, R = never, MA = void,
valueLens,
Lens.fromSubscriptionRef(yield* SubscriptionRef.make(options.initialEncodedValue)),
errorLens,
issuesLens,
validationFiberLens,
Subscribable.map(validationFiberLens, Option.isSome),
Subscribable.map(
Subscribable.zipLatestAll(valueLens, errorLens, validationFiberLens, mutation.result),
([value, error, validationFiber, result]) => (
Subscribable.zipLatestAll(valueLens, issuesLens, validationFiberLens, mutation.result),
([value, issues, validationFiber, result]) => (
Option.isSome(value) &&
Option.isNone(error) &&
Array.isEmptyReadonlyArray(issues) &&
Option.isNone(validationFiber) &&
!(Result.isRunning(result) || Result.hasRefreshingFlag(result))
),
@@ -238,7 +244,7 @@ export const focusObjectField = <P extends readonly PropertyKey[], A extends obj
path,
Subscribable.map(form.value, Option.map(a => a[key])),
Lens.focusObjectField(form.encodedValue, key),
form.error,
form.issues,
form.isValidating,
form.canSubmit,
)