diff --git a/packages/effect-fc/src/Form.ts b/packages/effect-fc/src/Form.ts index 3df3bc0..26a1e6b 100644 --- a/packages/effect-fc/src/Form.ts +++ b/packages/effect-fc/src/Form.ts @@ -15,14 +15,15 @@ export interface Form, - readonly submit: (value: NoInfer) => Effect.Effect, + readonly schema: Schema.Schema + readonly submit: (value: NoInfer) => Effect.Effect + readonly debounce: Option.Option - readonly valueRef: SubscriptionRef.SubscriptionRef>, - readonly encodedValueRef: SubscriptionRef.SubscriptionRef, - readonly errorRef: SubscriptionRef.SubscriptionRef>, + readonly valueRef: SubscriptionRef.SubscriptionRef> + readonly encodedValueRef: SubscriptionRef.SubscriptionRef + readonly errorRef: SubscriptionRef.SubscriptionRef> readonly validationFiberRef: SubscriptionRef.SubscriptionRef>> - readonly submitStateRef: SubscriptionRef.SubscriptionRef>, + readonly submitStateRef: SubscriptionRef.SubscriptionRef> readonly canSubmitSubscribable: Subscribable.Subscribable } @@ -34,6 +35,7 @@ extends Pipeable.Class() implements Form { constructor( readonly schema: Schema.Schema, readonly submit: (value: NoInfer) => Effect.Effect, + readonly debounce: Option.Option, readonly valueRef: SubscriptionRef.SubscriptionRef>, readonly encodedValueRef: SubscriptionRef.SubscriptionRef, @@ -53,7 +55,8 @@ export namespace make { export interface Options { readonly schema: Schema.Schema readonly initialEncodedValue: NoInfer - readonly submit: (value: NoInfer) => Effect.Effect + readonly submit: (value: NoInfer) => Effect.Effect, + readonly debounce?: Duration.DurationInput, } } @@ -72,6 +75,7 @@ export const make: { return new FormImpl( options.schema, options.submit, + Option.fromNullable(options.debounce), valueRef, yield* SubscriptionRef.make(options.initialEncodedValue), @@ -108,7 +112,10 @@ export const make: { export const run = ( self: Form ): Effect.Effect => Stream.runForEach( - self.encodedValueRef.changes, + self.encodedValueRef.changes.pipe( + Option.isSome(self.debounce) ? Stream.debounce(self.debounce.value) : identity + ), + encodedValue => self.validationFiberRef.pipe( Effect.andThen(Option.match({ onSome: Fiber.interrupt, @@ -268,7 +275,7 @@ export const useForm: { options: make.Options, deps: React.DependencyList, ) { - const form = yield* Hooks.useMemo(() => make(options), deps) + const form = yield* Hooks.useMemo(() => make(options), [options.debounce, ...deps]) yield* Hooks.useFork(() => run(form), [form]) return form })