0.2.6 #49
@@ -1,4 +1,4 @@
|
|||||||
import { Array, Cause, Chunk, type Context, Effect, Exit, Fiber, Option, ParseResult, Pipeable, Predicate, Schema, type Scope, SubscriptionRef } from "effect"
|
import { Array, Cause, Chunk, type Context, Effect, Exit, Fiber, Option, ParseResult, Pipeable, Predicate, Schema, type Scope, Stream, SubscriptionRef } from "effect"
|
||||||
import * as Form from "./Form.js"
|
import * as Form from "./Form.js"
|
||||||
import * as Lens from "./Lens.js"
|
import * as Lens from "./Lens.js"
|
||||||
import * as Subscribable from "./Subscribable.js"
|
import * as Subscribable from "./Subscribable.js"
|
||||||
@@ -39,6 +39,7 @@ export class SynchronizedFormImpl<
|
|||||||
readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId = SynchronizedFormTypeId
|
readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId = SynchronizedFormTypeId
|
||||||
|
|
||||||
readonly path = [] as const
|
readonly path = [] as const
|
||||||
|
readonly value: Subscribable.Subscribable<Option.Option<A>, never, never>
|
||||||
readonly encodedValue: Lens.Lens<I, never, never, never, never>
|
readonly encodedValue: Lens.Lens<I, never, never, never, never>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -46,7 +47,6 @@ export class SynchronizedFormImpl<
|
|||||||
readonly context: Context.Context<Scope.Scope | R | TRR | TRW>,
|
readonly context: Context.Context<Scope.Scope | R | TRR | TRW>,
|
||||||
readonly target: Lens.Lens<A, TER, TEW, TRR, TRW>,
|
readonly target: Lens.Lens<A, TER, TEW, TRR, TRW>,
|
||||||
|
|
||||||
readonly value: Lens.Lens<Option.Option<A>, never, never, never, never>,
|
|
||||||
readonly internalEncodedValue: Lens.Lens<I, never, never, never, never>,
|
readonly internalEncodedValue: Lens.Lens<I, never, never, never, never>,
|
||||||
readonly issues: Lens.Lens<readonly ParseResult.ArrayFormatterIssue[], 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 validationFiber: Lens.Lens<Option.Option<Fiber.Fiber<A, ParseResult.ParseError>>, never, never, never, never>,
|
||||||
@@ -58,6 +58,8 @@ export class SynchronizedFormImpl<
|
|||||||
readonly runSemaphore: Effect.Semaphore,
|
readonly runSemaphore: Effect.Semaphore,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
|
this.value = makeValueSubscribable(this)
|
||||||
this.encodedValue = makeEncodedValueLens(this)
|
this.encodedValue = makeEncodedValueLens(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,10 +74,7 @@ export class SynchronizedFormImpl<
|
|||||||
Schema.decode(this.schema, { errors: "all" })(encodedValue),
|
Schema.decode(this.schema, { errors: "all" })(encodedValue),
|
||||||
exit => Effect.andThen(
|
exit => Effect.andThen(
|
||||||
Exit.matchEffect(exit, {
|
Exit.matchEffect(exit, {
|
||||||
onSuccess: v => Effect.andThen(
|
onSuccess: () => Lens.set(this.issues, Array.empty()),
|
||||||
Lens.set(this.value, Option.some(v)),
|
|
||||||
Lens.set(this.issues, Array.empty()),
|
|
||||||
),
|
|
||||||
onFailure: c => Option.match(
|
onFailure: c => Option.match(
|
||||||
Chunk.findFirst(Cause.failures(c), e => e._tag === "ParseError"),
|
Chunk.findFirst(Cause.failures(c), e => e._tag === "ParseError"),
|
||||||
{
|
{
|
||||||
@@ -127,7 +126,6 @@ export class SynchronizedFormImpl<
|
|||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// Effect.andThen(
|
// Effect.andThen(
|
||||||
// Lens.set(this.value, Option.some(targetValue)),
|
|
||||||
// Lens.set(this.issues, Array.empty()),
|
// Lens.set(this.issues, Array.empty()),
|
||||||
// ),
|
// ),
|
||||||
// )),
|
// )),
|
||||||
@@ -141,6 +139,13 @@ export class SynchronizedFormImpl<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const makeValueSubscribable = <A, I, R, TER, TEW, TRR, TRW>(
|
||||||
|
self: SynchronizedFormImpl<A, I, R, TER, TEW, TRR, TRW>
|
||||||
|
): Subscribable.Subscribable<Option.Option<A>, never, never> => Subscribable.make({
|
||||||
|
get get() { return Effect.provide(Effect.option(self.target.get), self.context) },
|
||||||
|
get changes() { return Stream.provideContext(self.target.changes, self.context) }
|
||||||
|
})
|
||||||
|
|
||||||
const makeEncodedValueLens = <A, I, R, TER, TEW, TRR, TRW>(
|
const makeEncodedValueLens = <A, I, R, TER, TEW, TRR, TRW>(
|
||||||
self: SynchronizedFormImpl<A, I, R, TER, TEW, TRR, TRW>
|
self: SynchronizedFormImpl<A, I, R, TER, TEW, TRR, TRW>
|
||||||
): Lens.Lens<I, never, never, never, never> => Lens.make({
|
): Lens.Lens<I, never, never, never, never> => Lens.make({
|
||||||
@@ -184,11 +189,6 @@ export const make = Effect.fnUntraced(function* <A, I = A, R = never, TER = neve
|
|||||||
ParseResult.ParseError | TER,
|
ParseResult.ParseError | TER,
|
||||||
Scope.Scope | R | TRR | TRW
|
Scope.Scope | R | TRR | TRW
|
||||||
> {
|
> {
|
||||||
const valueLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none<A>()))
|
|
||||||
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 isCommittingLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(false))
|
|
||||||
|
|
||||||
const initialEncodedValue = options.initialEncodedValue !== undefined
|
const initialEncodedValue = options.initialEncodedValue !== undefined
|
||||||
? options.initialEncodedValue
|
? options.initialEncodedValue
|
||||||
: yield* Effect.flatMap(
|
: yield* Effect.flatMap(
|
||||||
@@ -196,21 +196,24 @@ export const make = Effect.fnUntraced(function* <A, I = A, R = never, TER = neve
|
|||||||
Schema.encode(options.schema, { errors: "all" }),
|
Schema.encode(options.schema, { errors: "all" }),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const internalEncodedValueLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(initialEncodedValue))
|
||||||
|
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 isCommittingLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(false))
|
||||||
|
|
||||||
return new SynchronizedFormImpl(
|
return new SynchronizedFormImpl(
|
||||||
options.schema,
|
options.schema,
|
||||||
yield* Effect.context<Scope.Scope | R | TRR | TRW>(),
|
yield* Effect.context<Scope.Scope | R | TRR | TRW>(),
|
||||||
options.target,
|
options.target,
|
||||||
|
|
||||||
valueLens,
|
internalEncodedValueLens,
|
||||||
Lens.fromSubscriptionRef(yield* SubscriptionRef.make(initialEncodedValue)),
|
|
||||||
issuesLens,
|
issuesLens,
|
||||||
validationFiberLens,
|
validationFiberLens,
|
||||||
Subscribable.map(validationFiberLens, Option.isSome),
|
Subscribable.map(validationFiberLens, Option.isSome),
|
||||||
|
|
||||||
Subscribable.map(
|
Subscribable.map(
|
||||||
Subscribable.zipLatestAll(valueLens, issuesLens, validationFiberLens, isCommittingLens),
|
Subscribable.zipLatestAll(issuesLens, validationFiberLens, isCommittingLens),
|
||||||
([value, issues, validationFiber, isCommitting]) => (
|
([issues, validationFiber, isCommitting]) => (
|
||||||
Option.isSome(value) &&
|
|
||||||
Array.isEmptyReadonlyArray(issues) &&
|
Array.isEmptyReadonlyArray(issues) &&
|
||||||
Option.isNone(validationFiber) &&
|
Option.isNone(validationFiber) &&
|
||||||
!isCommitting
|
!isCommitting
|
||||||
|
|||||||
Reference in New Issue
Block a user