@@ -0,0 +1,58 @@
|
||||
import { Array, Effect, Option, ParseResult, Pipeable, Schema, Stream, Subscribable, SubscriptionRef } from "effect"
|
||||
import * as React from "react"
|
||||
import { PropertyPath, Subscribable as SubscribableInternal, SubscriptionSubRef } from "./types/index.js"
|
||||
|
||||
|
||||
export const TypeId: unique symbol = Symbol.for("effect-fc/Form")
|
||||
export type TypeId = typeof TypeId
|
||||
|
||||
export interface Form<in out A, in out I = A, out R = never>
|
||||
extends Pipeable.Pipeable {
|
||||
readonly schema: Schema.Schema<A, I, R>
|
||||
readonly valueRef: SubscriptionRef.SubscriptionRef<A>
|
||||
readonly errorSubscribable: Subscribable.Subscribable<Option.Option<ParseResult.ParseError>>
|
||||
|
||||
useRef<P extends PropertyPath.Paths<A>>(path: P): SubscriptionRef.SubscriptionRef<PropertyPath.ValueFromPath<A, P>>
|
||||
useIssuesSubscribable(path: PropertyPath.Paths<A>): Subscribable.Subscribable<readonly ParseResult.ArrayFormatterIssue[]>
|
||||
}
|
||||
|
||||
class FormImpl<in out A, in out I, out R>
|
||||
extends Pipeable.Class() implements Form<A, I, R> {
|
||||
readonly [TypeId]: TypeId = TypeId
|
||||
|
||||
constructor(
|
||||
readonly schema: Schema.Schema<A, I, R>,
|
||||
readonly valueRef: SubscriptionRef.SubscriptionRef<A>,
|
||||
readonly errorSubscribable: Subscribable.Subscribable<Option.Option<ParseResult.ParseError>>
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
useRef<P extends PropertyPath.Paths<A>>(path: P) {
|
||||
return React.useMemo(() => SubscriptionSubRef.makeFromPath(this.valueRef, path), [this.valueRef, ...path])
|
||||
}
|
||||
|
||||
useIssuesSubscribable(path: PropertyPath.Paths<A>) {
|
||||
return React.useMemo(() => {
|
||||
const filter = Option.match({
|
||||
onSome: (v: ParseResult.ParseError) => Effect.andThen(
|
||||
ParseResult.ArrayFormatter.formatError(v),
|
||||
Array.filter(issue => PropertyPath.equivalence(issue.path, path)),
|
||||
),
|
||||
onNone: () => Effect.succeed([]),
|
||||
})
|
||||
|
||||
const errorSubscribable = this.errorSubscribable
|
||||
return SubscribableInternal.make({
|
||||
get: Effect.andThen(errorSubscribable.get, filter),
|
||||
get changes() { return Stream.flatMap(errorSubscribable.changes, filter) },
|
||||
})
|
||||
}, [this.errorSubscribable, ...path])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const TestSchema = Schema.Struct({
|
||||
name: Schema.String
|
||||
})
|
||||
declare const form: Form<typeof TestSchema["Type"], typeof TestSchema["Encoded"], typeof TestSchema["Context"]>
|
||||
Reference in New Issue
Block a user