@tanstack/form-core 0.47.2 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,6 +13,7 @@ function getDefaultFormState(defaultState) {
13
13
  isSubmitting: defaultState.isSubmitting ?? false,
14
14
  isValidating: defaultState.isValidating ?? false,
15
15
  submissionAttempts: defaultState.submissionAttempts ?? 0,
16
+ isSubmitSuccessful: defaultState.isSubmitSuccessful ?? false,
16
17
  validationMetaMap: defaultState.validationMetaMap ?? {
17
18
  onChange: void 0,
18
19
  onBlur: void 0,
@@ -680,7 +681,9 @@ class FormApi {
680
681
  // Submission attempts mark the form as not submitted
681
682
  isSubmitted: false,
682
683
  // Count submission attempts
683
- submissionAttempts: old.submissionAttempts + 1
684
+ submissionAttempts: old.submissionAttempts + 1,
685
+ isSubmitSuccessful: false
686
+ // Reset isSubmitSuccessful at the start of submission
684
687
  }));
685
688
  if (!this.state.canSubmit) return;
686
689
  this.baseStore.setState((d) => ({ ...d, isSubmitting: true }));
@@ -723,10 +726,20 @@ class FormApi {
723
726
  meta: submitMeta ?? this.options.onSubmitMeta
724
727
  }));
725
728
  store.batch(() => {
726
- this.baseStore.setState((prev) => ({ ...prev, isSubmitted: true }));
729
+ this.baseStore.setState((prev) => ({
730
+ ...prev,
731
+ isSubmitted: true,
732
+ isSubmitSuccessful: true
733
+ // Set isSubmitSuccessful to true on successful submission
734
+ }));
727
735
  done();
728
736
  });
729
737
  } catch (err) {
738
+ this.baseStore.setState((prev) => ({
739
+ ...prev,
740
+ isSubmitSuccessful: false
741
+ // Ensure isSubmitSuccessful is false if an error occurs
742
+ }));
730
743
  done();
731
744
  throw err;
732
745
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FormApi.cjs","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Derived, Store, batch } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isGlobalFormValidationError,\n isNonEmptyArray,\n setBy,\n shallow,\n} from './utils'\nimport {\n isStandardSchemaValidator,\n standardSchemaValidators,\n} from './standardSchemaValidator'\nimport { metaHelper } from './metaHelper'\nimport type {\n StandardSchemaV1,\n StandardSchemaV1Issue,\n TStandardSchemaValidatorValue,\n} from './standardSchemaValidator'\nimport type { AnyFieldMeta, AnyFieldMetaBase, FieldApi } from './FieldApi'\nimport type {\n FormValidationError,\n FormValidationErrorMap,\n UpdateMetaOptions,\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n} from './types'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { Updater } from './utils'\n\n/**\n * @private\n */\n// TODO: Add the `Unwrap` type to the errors\ntype FormErrorMapFromValidator<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = Partial<\n Record<\n DeepKeys<TFormData>,\n ValidationErrorMap<\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n >\n>\n\nexport type FormValidateFn<TFormData> = (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n // This is technically an edge-type; which we try to keep non-`any`, but in this case\n // It's referring to an inaccessible type from the field validate function inner types, so it's not a big deal\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n}) => unknown\n\n/**\n * @private\n */\nexport type FormValidateOrFn<TFormData> =\n | FormValidateFn<TFormData>\n | StandardSchemaV1<TFormData, unknown>\n\nexport type UnwrapFormValidateOrFn<\n TValidateOrFn extends undefined | FormValidateOrFn<any>,\n> = [TValidateOrFn] extends [FormValidateFn<any>]\n ? ReturnType<TValidateOrFn>\n : [TValidateOrFn] extends [StandardSchemaV1<any, any>]\n ? Record<string, StandardSchemaV1Issue[]>\n : undefined\n\n/**\n * @private\n */\nexport type FormValidateAsyncFn<TFormData> = (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n // This is technically an edge-type; which we try to keep non-`any`, but in this case\n // It's referring to an inaccessible type from the field validate function inner types, so it's not a big deal\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n signal: AbortSignal\n}) => unknown | Promise<unknown>\n\nexport type FormValidator<TFormData, TType, TFn = unknown> = {\n validate(options: { value: TType }, fn: TFn): ValidationError\n validateAsync(\n options: { value: TType },\n fn: TFn,\n ): Promise<FormValidationError<TFormData>>\n}\n\ntype ValidationPromiseResult<TFormData> =\n | {\n fieldErrors: Partial<Record<DeepKeys<TFormData>, ValidationError>>\n errorMapKey: ValidationErrorMapKeys\n }\n | undefined\n\n/**\n * @private\n */\nexport type FormAsyncValidateOrFn<TFormData> =\n | FormValidateAsyncFn<TFormData>\n | StandardSchemaV1<TFormData, unknown>\n\nexport type UnwrapFormAsyncValidateOrFn<\n TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>,\n> = [TValidateOrFn] extends [FormValidateAsyncFn<any>]\n ? Awaited<ReturnType<TValidateOrFn>>\n : [TValidateOrFn] extends [StandardSchemaV1<any, any>]\n ? Record<string, StandardSchemaV1Issue[]>\n : undefined\n\nexport interface FormValidators<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n> {\n /**\n * Optional function that fires as soon as the component mounts.\n */\n onMount?: TOnMount\n /**\n * Optional function that checks the validity of your data whenever a value changes\n */\n onChange?: TOnChange\n /**\n * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.\n */\n onChangeAsync?: TOnChangeAsync\n /**\n * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.\n */\n onChangeAsyncDebounceMs?: number\n /**\n * Optional function that validates the form data when a field loses focus, returns a `FormValidationError`\n */\n onBlur?: TOnBlur\n /**\n * Optional onBlur asynchronous validation method for when a field loses focus returns a ` FormValidationError` or a promise of `Promise<FormValidationError>`\n */\n onBlurAsync?: TOnBlurAsync\n /**\n * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.\n */\n onBlurAsyncDebounceMs?: number\n onSubmit?: TOnSubmit\n onSubmitAsync?: TOnSubmitAsync\n}\n\n/**\n * @private\n */\nexport interface FormTransform<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n fn: (\n formBase: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) => FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n deps: unknown[]\n}\n\n/**\n * An object representing the options for a form.\n */\nexport interface FormOptions<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n /**\n * Set initial values for your form.\n */\n defaultValues?: TFormData\n /**\n * The default state for the form.\n */\n defaultState?: Partial<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n /**\n * If true, always run async validation, even when sync validation has produced an error. Defaults to undefined.\n */\n asyncAlways?: boolean\n /**\n * Optional time in milliseconds if you want to introduce a delay before firing off an async action.\n */\n asyncDebounceMs?: number\n /**\n * A list of validators to pass to the form\n */\n validators?: FormValidators<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n\n /**\n * A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`\n */\n onSubmit?: (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n meta: TSubmitMeta\n }) => any | Promise<any>\n /**\n * Specify an action for scenarios where the user tries to submit an invalid form.\n */\n onSubmitInvalid?: (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n }) => void\n transform?: FormTransform<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n}\n\n/**\n * An object representing the validation metadata for a field. Not intended for public usage.\n */\nexport type ValidationMeta = {\n /**\n * An abort controller stored in memory to cancel previous async validation attempts.\n */\n lastAbortController: AbortController\n}\n\n/**\n * An object representing the field information for a specific field within the form.\n */\nexport type FieldInfo<TFormData> = {\n /**\n * An instance of the FieldAPI.\n */\n instance: FieldApi<\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > | null\n /**\n * A record of field validation internal handling.\n */\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n}\n\n/**\n * An object representing the current state of the form.\n */\nexport type BaseFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = {\n /**\n * The current values of the form fields.\n */\n values: TFormData\n /**\n * The error map for the form itself.\n */\n errorMap: FormValidationErrorMap<\n UnwrapFormValidateOrFn<TOnMount>,\n UnwrapFormValidateOrFn<TOnChange>,\n UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,\n UnwrapFormValidateOrFn<TOnBlur>,\n UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,\n UnwrapFormValidateOrFn<TOnSubmit>,\n UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,\n UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n /**\n * An internal mechanism used for keeping track of validation logic in a form.\n */\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n /**\n * A record of field metadata for each field in the form, not including the derived properties, like `errors` and such\n */\n fieldMetaBase: Record<DeepKeys<TFormData>, AnyFieldMetaBase>\n /**\n * A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.\n *\n * Goes back to `false` when submission completes for one of the following reasons:\n * - the validation step returned errors.\n * - the `onSubmit` function has completed.\n *\n * Note: if you're running async operations in your `onSubmit` function make sure to await them to ensure `isSubmitting` is set to `false` only when the async operation completes.\n *\n * This is useful for displaying loading indicators or disabling form inputs during submission.\n *\n */\n isSubmitting: boolean\n /**\n * A boolean indicating if the form has been submitted.\n */\n isSubmitted: boolean\n /**\n * A boolean indicating if the form or any of its fields are currently validating.\n */\n isValidating: boolean\n /**\n * A counter for tracking the number of submission attempts.\n */\n submissionAttempts: number\n /**\n * @private, used to force a re-evaluation of the form state when options change\n */\n _force_re_eval?: boolean\n}\n\nexport type DerivedFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = {\n /**\n * A boolean indicating if the form is currently validating.\n */\n isFormValidating: boolean\n /**\n * A boolean indicating if the form is valid.\n */\n isFormValid: boolean\n /**\n * The error array for the form itself.\n */\n errors: Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n /**\n * A boolean indicating if any of the form fields are currently validating.\n */\n isFieldsValidating: boolean\n /**\n * A boolean indicating if all the form fields are valid.\n */\n isFieldsValid: boolean\n /**\n * A boolean indicating if any of the form fields have been touched.\n */\n isTouched: boolean\n /**\n * A boolean indicating if any of the form fields have been blurred.\n */\n isBlurred: boolean\n /**\n * A boolean indicating if any of the form's fields' values have been modified by the user. `True` if the user have modified at least one of the fields. Opposite of `isPristine`.\n */\n isDirty: boolean\n /**\n * A boolean indicating if none of the form's fields' values have been modified by the user. `True` if the user have not modified any of the fields. Opposite of `isDirty`.\n */\n isPristine: boolean\n /**\n * A boolean indicating if the form and all its fields are valid.\n */\n isValid: boolean\n /**\n * A boolean indicating if the form can be submitted based on its current state.\n */\n canSubmit: boolean\n /**\n * A record of field metadata for each field in the form.\n */\n fieldMeta: Record<DeepKeys<TFormData>, AnyFieldMeta>\n}\n\nexport type FormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n> &\n DerivedFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n\nexport type AnyFormState = FormState<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nfunction getDefaultFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n>(\n defaultState: Partial<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >,\n): BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n> {\n return {\n values: defaultState.values ?? ({} as never),\n errorMap: defaultState.errorMap ?? {},\n fieldMetaBase: defaultState.fieldMetaBase ?? ({} as never),\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isValidating: defaultState.isValidating ?? false,\n submissionAttempts: defaultState.submissionAttempts ?? 0,\n validationMetaMap: defaultState.validationMetaMap ?? {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n }\n}\n\n/**\n * @public\n *\n * A type representing the Form API with all generics set to `any` for convenience.\n */\nexport type AnyFormApi = FormApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\n/**\n * A class representing the Form API. It handles the logic and interactions with the form state.\n *\n * Normally, you will not need to create a new `FormApi` instance directly. Instead, you will use a framework\n * hook/function like `useForm` or `createForm` to create a new instance for you that uses your framework's reactivity model.\n * However, if you need to create a new instance manually, you can do so by calling the `new FormApi` constructor.\n */\nexport class FormApi<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n /**\n * The options for the form.\n */\n options: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n > = {}\n baseStore!: Store<\n BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n fieldMetaDerived!: Derived<Record<DeepKeys<TFormData>, AnyFieldMeta>>\n store!: Derived<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n /**\n * A record of field information for each field in the form.\n */\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData>> = {} as any\n\n get state() {\n return this.store.state\n }\n\n /**\n * @private\n */\n prevTransformArray: unknown[] = []\n\n /**\n * @private Persistent store of all field validation errors originating from form-level validators.\n * Maintains the cumulative state across validation cycles, including cleared errors (undefined values).\n * This map preserves the complete validation state for all fields.\n */\n cumulativeFieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n\n /**\n * Constructs a new `FormApi` instance with the given form options.\n */\n constructor(\n opts?: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n this.baseStore = new Store(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n )\n\n this.fieldMetaDerived = new Derived({\n deps: [this.baseStore],\n fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {\n const prevVal = _prevVal as\n | Record<DeepKeys<TFormData>, AnyFieldMeta>\n | undefined\n const prevBaseStore = prevDepVals?.[0]\n const currBaseStore = currDepVals[0]\n\n let originalMetaCount = 0\n\n const fieldMeta = {} as FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >['fieldMeta']\n\n for (const fieldName of Object.keys(\n currBaseStore.fieldMetaBase,\n ) as Array<keyof typeof currBaseStore.fieldMetaBase>) {\n const currBaseVal = currBaseStore.fieldMetaBase[\n fieldName as never\n ] as AnyFieldMetaBase\n\n const prevBaseVal = prevBaseStore?.fieldMetaBase[\n fieldName as never\n ] as AnyFieldMetaBase | undefined\n\n const prevFieldInfo =\n prevVal?.[fieldName as never as keyof typeof prevVal]\n\n let fieldErrors = prevFieldInfo?.errors\n if (!prevBaseVal || currBaseVal.errorMap !== prevBaseVal.errorMap) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n fieldErrors = Object.values(currBaseVal.errorMap ?? {}).filter(\n (val) => val !== undefined,\n ) as never\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.getFieldInfo(fieldName)?.instance\n\n if (fieldInstance && !fieldInstance.options.disableErrorFlat) {\n fieldErrors = (fieldErrors as undefined | string[])?.flat(\n 1,\n ) as never\n }\n }\n\n // As a primitive, we don't need to aggressively persist the same referential value for performance reasons\n const isFieldPristine = !currBaseVal.isDirty\n\n if (\n prevFieldInfo &&\n prevFieldInfo.isPristine === isFieldPristine &&\n prevFieldInfo.errors === fieldErrors &&\n currBaseVal === prevBaseVal\n ) {\n fieldMeta[fieldName] = prevFieldInfo\n originalMetaCount++\n continue\n }\n\n fieldMeta[fieldName] = {\n ...currBaseVal,\n errors: fieldErrors,\n isPristine: isFieldPristine,\n } as AnyFieldMeta\n }\n\n if (\n prevVal &&\n originalMetaCount === Object.keys(currBaseStore.fieldMetaBase).length\n ) {\n return prevVal\n }\n\n return fieldMeta\n },\n })\n\n this.store = new Derived({\n deps: [this.baseStore, this.fieldMetaDerived],\n fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {\n const prevVal = _prevVal as\n | FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n | undefined\n const prevBaseStore = prevDepVals?.[0]\n const currBaseStore = currDepVals[0]\n\n // Computed state\n const fieldMetaValues = Object.values(currBaseStore.fieldMetaBase) as (\n | AnyFieldMeta\n | undefined\n )[]\n\n const isFieldsValidating = fieldMetaValues.some(\n (field) => field?.isValidating,\n )\n\n const isFieldsValid = !fieldMetaValues.some(\n (field) =>\n field?.errorMap &&\n isNonEmptyArray(Object.values(field.errorMap).filter(Boolean)),\n )\n\n const isTouched = fieldMetaValues.some((field) => field?.isTouched)\n const isBlurred = fieldMetaValues.some((field) => field?.isBlurred)\n\n const shouldInvalidateOnMount =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n isTouched && currBaseStore?.errorMap?.onMount\n\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const hasOnMountError = Boolean(\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n currBaseStore.errorMap?.onMount ||\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n fieldMetaValues.some((f) => f?.errorMap?.onMount),\n )\n\n const isValidating = !!isFieldsValidating\n\n // As `errors` is not a primitive, we need to aggressively persist the same referencial value for performance reasons\n let errors = prevVal?.errors ?? []\n if (\n !prevBaseStore ||\n currBaseStore.errorMap !== prevBaseStore.errorMap\n ) {\n errors = Object.values(currBaseStore.errorMap).reduce<\n Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n >((prev, curr) => {\n if (curr === undefined) return prev\n\n if (curr && isGlobalFormValidationError(curr)) {\n prev.push(curr.form as never)\n return prev\n }\n prev.push(curr as never)\n return prev\n }, [])\n }\n\n const isFormValid = errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (currBaseStore.submissionAttempts === 0 &&\n !isTouched &&\n !hasOnMountError) ||\n (!isValidating && !currBaseStore.isSubmitting && isValid)\n\n let errorMap = currBaseStore.errorMap\n if (shouldInvalidateOnMount) {\n errors = errors.filter(\n (err) => err !== currBaseStore.errorMap.onMount,\n )\n errorMap = Object.assign(errorMap, { onMount: undefined })\n }\n\n if (\n prevVal &&\n prevBaseStore &&\n prevVal.errorMap === errorMap &&\n prevVal.fieldMeta === this.fieldMetaDerived.state &&\n prevVal.errors === errors &&\n prevVal.isFieldsValidating === isFieldsValidating &&\n prevVal.isFieldsValid === isFieldsValid &&\n prevVal.isFormValid === isFormValid &&\n prevVal.isValid === isValid &&\n prevVal.canSubmit === canSubmit &&\n prevVal.isTouched === isTouched &&\n prevVal.isBlurred === isBlurred &&\n prevVal.isPristine === isPristine &&\n prevVal.isDirty === isDirty &&\n shallow(prevBaseStore, currBaseStore)\n ) {\n return prevVal\n }\n\n let state = {\n ...currBaseStore,\n errorMap,\n fieldMeta: this.fieldMetaDerived.state,\n errors,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isBlurred,\n isPristine,\n isDirty,\n } as FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n\n // Only run transform if state has shallowly changed - IE how React.useEffect works\n const transformArray = this.options.transform?.deps ?? []\n const shouldTransform =\n transformArray.length !== this.prevTransformArray.length ||\n transformArray.some((val, i) => val !== this.prevTransformArray[i])\n\n if (shouldTransform) {\n const newObj = Object.assign({}, this, { state })\n // This mutates the state\n this.options.transform?.fn(newObj)\n state = newObj.state\n this.prevTransformArray = transformArray\n }\n\n return state\n },\n })\n\n this.handleSubmit = this.handleSubmit.bind(this)\n\n this.update(opts || {})\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends TStandardSchemaValidatorValue<TFormData> & {\n formApi: AnyFormApi\n },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData>\n : FormAsyncValidateOrFn<TFormData>\n value: TValue\n type: TType\n }): unknown {\n if (isStandardSchemaValidator(props.validate)) {\n return standardSchemaValidators[props.type](\n props.value,\n props.validate,\n ) as never\n }\n\n return (props.validate as FormValidateFn<any>)(props.value) as never\n }\n\n mount = () => {\n const cleanupFieldMetaDerived = this.fieldMetaDerived.mount()\n const cleanupStoreDerived = this.store.mount()\n const cleanup = () => {\n cleanupFieldMetaDerived()\n cleanupStoreDerived()\n }\n const { onMount } = this.options.validators || {}\n if (!onMount) return cleanup\n this.validateSync('mount')\n\n return cleanup\n }\n\n /**\n * Updates the form options and form state.\n */\n update = (\n options?: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) => {\n if (!options) return\n\n const oldOptions = this.options\n\n // Options need to be updated first so that when the store is updated, the state is correct for the derived state\n this.options = options\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const shouldUpdateReeval = !!options.transform?.deps?.some(\n (val, i) => val !== this.prevTransformArray[i],\n )\n\n const shouldUpdateValues =\n options.defaultValues &&\n !shallow(options.defaultValues, oldOptions.defaultValues) &&\n !this.state.isTouched\n\n const shouldUpdateState =\n !shallow(options.defaultState, oldOptions.defaultState) &&\n !this.state.isTouched\n\n if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return\n\n batch(() => {\n this.baseStore.setState(() =>\n getDefaultFormState(\n Object.assign(\n {},\n this.state as any,\n\n shouldUpdateState ? options.defaultState : {},\n\n shouldUpdateValues\n ? {\n values: options.defaultValues,\n }\n : {},\n\n shouldUpdateReeval\n ? { _force_re_eval: !this.state._force_re_eval }\n : {},\n ),\n ),\n )\n })\n }\n\n /**\n * Resets the form state to the default values.\n * If values are provided, the form will be reset to those values instead and the default values will be updated.\n *\n * @param values - Optional values to reset the form to.\n * @param opts - Optional options to control the reset behavior.\n */\n reset = (values?: TFormData, opts?: { keepDefaultValues?: boolean }) => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMetaBase = this.resetFieldMeta(currentFieldMeta)\n\n if (values && !opts?.keepDefaultValues) {\n this.options = {\n ...this.options,\n defaultValues: values,\n }\n }\n\n this.baseStore.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values:\n values ??\n this.options.defaultValues ??\n this.options.defaultState?.values,\n fieldMetaBase,\n }),\n )\n }\n\n /**\n * Validates all fields using the correct handlers for a given validation cause.\n */\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n batch(() => {\n void (Object.values(this.fieldInfo) as FieldInfo<any>[]).forEach(\n (field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n // Remember, `validate` is either a sync operation or a promise\n Promise.resolve().then(() =>\n fieldInstance.validate(cause, { skipFormValidation: true }),\n ),\n )\n // If any fields are not touched\n if (!field.instance.state.meta.isTouched) {\n // Mark them as touched\n field.instance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n },\n )\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n const currentValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(currentValue)\n ? Math.max(currentValue.length - 1, 0)\n : null\n\n // We have to validate all fields that have shifted (at least the current field)\n const fieldKeysToValidate = [`${field}[${index}]`]\n for (let i = index + 1; i <= (lastIndex ?? 0); i++) {\n fieldKeysToValidate.push(`${field}[${i}]`)\n }\n\n // We also have to include all fields that are nested in the shifted fields\n const fieldsToValidate = Object.keys(this.fieldInfo).filter((fieldKey) =>\n fieldKeysToValidate.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n\n // Validate the fields\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n batch(() => {\n fieldsToValidate.forEach((nestedField) => {\n fieldValidationPromises.push(\n Promise.resolve().then(() => this.validateField(nestedField, cause)),\n )\n })\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFormData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.fieldInfo[field]?.instance\n if (!fieldInstance) return []\n\n // If the field is not touched (same logic as in validateAllFields)\n if (!fieldInstance.state.meta.isTouched) {\n // Mark it as touched\n fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n\n return fieldInstance.validate(cause)\n }\n\n /**\n * TODO: This code is copied from FieldApi, we should refactor to share\n * @private\n */\n validateSync = (\n cause: ValidationCause,\n ): {\n hasErrored: boolean\n fieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n } => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n // This map will only include fields that have errors in the current validation cycle\n const currentValidationErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n\n batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const rawError = this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n validationSource: 'form',\n },\n type: 'validate',\n })\n\n const { formError, fieldErrors } = normalizeError<TFormData>(rawError)\n\n const errorMapKey = getErrorMapKey(validateObj.cause)\n\n if (fieldErrors) {\n for (const [field, fieldError] of Object.entries(fieldErrors) as [\n DeepKeys<TFormData>,\n ValidationError,\n ][]) {\n const oldErrorMap = this.cumulativeFieldsErrorMap[field] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n currentValidationErrorMap[field] = newErrorMap\n this.cumulativeFieldsErrorMap[field] = newErrorMap\n\n const fieldMeta = this.getFieldMeta(field)\n if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: fieldError,\n },\n }))\n }\n }\n }\n\n for (const field of Object.keys(this.cumulativeFieldsErrorMap) as Array<\n DeepKeys<TFormData>\n >) {\n const fieldMeta = this.getFieldMeta(field)\n if (\n fieldMeta?.errorMap[errorMapKey] &&\n !currentValidationErrorMap[field]?.[errorMapKey]\n ) {\n this.cumulativeFieldsErrorMap[field] = {\n ...this.cumulativeFieldsErrorMap[field],\n [errorMapKey]: undefined,\n }\n\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: undefined,\n },\n }))\n }\n }\n\n if (this.state.errorMap[errorMapKey] !== formError) {\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: formError,\n },\n }))\n }\n\n if (formError || fieldErrors) {\n hasErrored = true\n }\n }\n\n /**\n * when we have an error for onSubmit in the state, we want\n * to clear the error as soon as the user enters a valid value in the field\n */\n const submitErrKey = getErrorMapKey('submit')\n if (\n this.state.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n })\n\n return { hasErrored, fieldsErrorMap: currentValidationErrorMap }\n }\n\n /**\n * @private\n */\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<\n FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n > => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.baseStore.setState((prev) => ({ ...prev, isFormValidating: true }))\n }\n\n /**\n * We have to use a for loop and generate our promises this way, otherwise it won't be sync\n * when there are no validators needed to be run\n */\n const promises: Promise<ValidationPromiseResult<TFormData>>[] = []\n\n let fieldErrors:\n | Partial<Record<DeepKeys<TFormData>, ValidationError>>\n | undefined\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = this.state.validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.state.validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationPromiseResult<TFormData>>(async (resolve) => {\n let rawError!:\n | ValidationError\n | FormValidationError<unknown>\n | undefined\n try {\n rawError = await new Promise((rawResolve, rawReject) => {\n setTimeout(async () => {\n if (controller.signal.aborted) return rawResolve(undefined)\n try {\n rawResolve(\n await this.runValidator({\n validate: validateObj.validate!,\n value: {\n value: this.state.values,\n formApi: this,\n validationSource: 'form',\n signal: controller.signal,\n },\n type: 'validateAsync',\n }),\n )\n } catch (e) {\n rawReject(e)\n }\n }, validateObj.debounceMs)\n })\n } catch (e: unknown) {\n rawError = e as ValidationError\n }\n const { formError, fieldErrors: fieldErrorsFromNormalizeError } =\n normalizeError<TFormData>(rawError)\n\n if (fieldErrorsFromNormalizeError) {\n fieldErrors = fieldErrors\n ? { ...fieldErrors, ...fieldErrorsFromNormalizeError }\n : fieldErrorsFromNormalizeError\n }\n const errorMapKey = getErrorMapKey(validateObj.cause)\n\n if (fieldErrors) {\n for (const [field, fieldError] of Object.entries(fieldErrors)) {\n const fieldMeta = this.getFieldMeta(field as DeepKeys<TFormData>)\n if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {\n this.setFieldMeta(field as DeepKeys<TFormData>, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: fieldError,\n },\n }))\n }\n }\n }\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: formError,\n },\n }))\n\n resolve(fieldErrors ? { fieldErrors, errorMapKey } : undefined)\n }),\n )\n }\n\n let results: ValidationPromiseResult<TFormData>[] = []\n\n const fieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n if (promises.length) {\n results = await Promise.all(promises)\n for (const fieldValidationResult of results) {\n if (fieldValidationResult?.fieldErrors) {\n const { errorMapKey } = fieldValidationResult\n\n for (const [field, fieldError] of Object.entries(\n fieldValidationResult.fieldErrors,\n )) {\n const oldErrorMap =\n fieldsErrorMap[field as DeepKeys<TFormData>] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n fieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap\n }\n }\n }\n }\n\n this.baseStore.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return fieldsErrorMap\n }\n\n /**\n * @private\n */\n validate = (\n cause: ValidationCause,\n ):\n | FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n | Promise<\n FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n > => {\n // Attempt to sync validate first\n const { hasErrored, fieldsErrorMap } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return fieldsErrorMap\n }\n\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n this.baseStore.setState((old) => ({\n ...old,\n // Submission attempts mark the form as not submitted\n isSubmitted: false,\n // Count submission attempts\n submissionAttempts: old.submissionAttempts + 1,\n }))\n\n // Don't let invalid forms submit\n if (!this.state.canSubmit) return\n\n this.baseStore.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.baseStore.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n await this.validateAllFields('submit')\n\n if (!this.state.isFieldsValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n await this.validate('submit')\n\n // Fields are invalid, do not submit\n if (!this.state.isValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n batch(() => {\n void (Object.values(this.fieldInfo) as FieldInfo<TFormData>[]).forEach(\n (field) => {\n field.instance?.options.listeners?.onSubmit?.({\n value: field.instance.state.value,\n fieldApi: field.instance,\n })\n },\n )\n })\n\n try {\n // Run the submit code\n await this.options.onSubmit?.({\n value: this.state.values,\n formApi: this,\n meta: submitMeta ?? this.options.onSubmitMeta,\n } as any)\n\n batch(() => {\n this.baseStore.setState((prev) => ({ ...prev, isSubmitted: true }))\n done()\n })\n } catch (err) {\n done()\n throw err\n }\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): DeepValue<TFormData, TField> => getBy(this.state.values, field)\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): AnyFieldMeta | undefined => {\n return this.state.fieldMeta[field]\n }\n\n /**\n * Gets the field info of the specified field.\n */\n getFieldInfo = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldInfo<TFormData> => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (this.fieldInfo[field] ||= {\n instance: null,\n validationMetaMap: {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n })\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<AnyFieldMeta>,\n ) => {\n this.baseStore.setState((prev) => {\n return {\n ...prev,\n fieldMetaBase: {\n ...prev.fieldMetaBase,\n [field]: functionalUpdate(\n updater,\n prev.fieldMetaBase[field] as never,\n ),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, AnyFieldMeta>,\n ): Record<TField, AnyFieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, AnyFieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, AnyFieldMeta>,\n )\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<DeepValue<TFormData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n const dontUpdateMeta = opts?.dontUpdateMeta ?? false\n\n batch(() => {\n if (!dontUpdateMeta) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n onMount: undefined,\n },\n }))\n }\n\n this.baseStore.setState((prev) => {\n return {\n ...prev,\n values: setBy(prev.values, field, updater),\n }\n })\n })\n }\n\n deleteField = <TField extends DeepKeys<TFormData>>(field: TField) => {\n this.baseStore.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMetaBase[field]\n\n return newState\n })\n delete this.fieldInfo[field]\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,\n opts,\n )\n this.validateField(field, 'change')\n }\n\n insertFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return [\n ...(prev as DeepValue<TFormData, TField>[]).slice(0, index),\n value,\n ...(prev as DeepValue<TFormData, TField>[]).slice(index),\n ] as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n\n // Shift down all meta after validating to make sure the new field has been mounted\n metaHelper(this).handleArrayFieldMetaShift(field, index, 'insert')\n\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).map((d, i) =>\n i === index ? value : d,\n ) as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n const fieldValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(fieldValue)\n ? Math.max(fieldValue.length - 1, 0)\n : null\n\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).filter(\n (_d, i) => i !== index,\n ) as any\n },\n opts,\n )\n\n // Shift up all meta\n metaHelper(this).handleArrayFieldMetaShift(field, index, 'remove')\n\n if (lastIndex !== null) {\n const start = `${field}[${lastIndex}]`\n const fieldsToDelete = Object.keys(this.fieldInfo).filter((f) =>\n f.startsWith(start),\n )\n\n // Cleanup the last fields\n fieldsToDelete.forEach((f) => this.deleteField(f as TField))\n }\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev: any) => {\n const prev1 = prev[index1]!\n const prev2 = prev[index2]!\n return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1)\n },\n opts,\n )\n\n // Swap meta\n metaHelper(this).handleArrayFieldMetaShift(field, index1, 'swap', index2)\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the swapped fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev: any) => {\n prev.splice(index2, 0, prev.splice(index1, 1)[0])\n return prev\n },\n opts,\n )\n\n // Move meta between index1 and index2\n metaHelper(this).handleArrayFieldMetaShift(field, index1, 'move', index2)\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the moved fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n /**\n * Updates the form's errorMap\n */\n setErrorMap(\n errorMap: ValidationErrorMap<\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >,\n ) {\n this.baseStore.setState(\n (prev) =>\n ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n ...errorMap,\n },\n }) as never,\n )\n }\n\n /**\n * Returns form and field level errors\n */\n getAllErrors = (): {\n form: {\n errors: Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n errorMap: FormValidationErrorMap<\n UnwrapFormValidateOrFn<TOnMount>,\n UnwrapFormValidateOrFn<TOnChange>,\n UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,\n UnwrapFormValidateOrFn<TOnBlur>,\n UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,\n UnwrapFormValidateOrFn<TOnSubmit>,\n UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,\n UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n }\n fields: Record<\n DeepKeys<TFormData>,\n { errors: ValidationError[]; errorMap: ValidationErrorMap }\n >\n } => {\n return {\n form: {\n errors: this.state.errors,\n errorMap: this.state.errorMap,\n },\n fields: Object.entries(this.state.fieldMeta).reduce(\n (acc, [fieldName, fieldMeta]) => {\n if (\n Object.keys(fieldMeta as AnyFieldMeta).length &&\n (fieldMeta as AnyFieldMeta).errors.length\n ) {\n acc[fieldName as DeepKeys<TFormData>] = {\n errors: (fieldMeta as AnyFieldMeta).errors,\n errorMap: (fieldMeta as AnyFieldMeta).errorMap,\n }\n }\n\n return acc\n },\n {} as Record<\n DeepKeys<TFormData>,\n { errors: ValidationError[]; errorMap: ValidationErrorMap }\n >,\n ),\n }\n }\n}\n\nfunction normalizeError<TFormData>(rawError?: FormValidationError<unknown>): {\n formError: ValidationError\n fieldErrors?: Partial<Record<DeepKeys<TFormData>, ValidationError>>\n} {\n if (rawError) {\n if (isGlobalFormValidationError(rawError)) {\n const formError = normalizeError(rawError.form).formError\n const fieldErrors = rawError.fields\n return { formError, fieldErrors } as never\n }\n\n return { formError: rawError }\n }\n\n return { formError: undefined }\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n case 'server':\n return 'onServer'\n case 'change':\n default:\n return 'onChange'\n }\n}\n"],"names":["_a","shallow","batch","opts","getSyncValidatorArray","getAsyncValidatorArray","getBy","functionalUpdate","setBy","deleteBy","metaHelper","Store","Derived","isNonEmptyArray","isGlobalFormValidationError","isStandardSchemaValidator","standardSchemaValidators","_c","_b"],"mappings":"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"}
1
+ {"version":3,"file":"FormApi.cjs","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Derived, Store, batch } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isGlobalFormValidationError,\n isNonEmptyArray,\n setBy,\n shallow,\n} from './utils'\nimport {\n isStandardSchemaValidator,\n standardSchemaValidators,\n} from './standardSchemaValidator'\nimport { metaHelper } from './metaHelper'\nimport type {\n StandardSchemaV1,\n StandardSchemaV1Issue,\n TStandardSchemaValidatorValue,\n} from './standardSchemaValidator'\nimport type { AnyFieldMeta, AnyFieldMetaBase, FieldApi } from './FieldApi'\nimport type {\n FormValidationError,\n FormValidationErrorMap,\n UpdateMetaOptions,\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n} from './types'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { Updater } from './utils'\n\n/**\n * @private\n */\n// TODO: Add the `Unwrap` type to the errors\ntype FormErrorMapFromValidator<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = Partial<\n Record<\n DeepKeys<TFormData>,\n ValidationErrorMap<\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n >\n>\n\nexport type FormValidateFn<TFormData> = (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n // This is technically an edge-type; which we try to keep non-`any`, but in this case\n // It's referring to an inaccessible type from the field validate function inner types, so it's not a big deal\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n}) => unknown\n\n/**\n * @private\n */\nexport type FormValidateOrFn<TFormData> =\n | FormValidateFn<TFormData>\n | StandardSchemaV1<TFormData, unknown>\n\nexport type UnwrapFormValidateOrFn<\n TValidateOrFn extends undefined | FormValidateOrFn<any>,\n> = [TValidateOrFn] extends [FormValidateFn<any>]\n ? ReturnType<TValidateOrFn>\n : [TValidateOrFn] extends [StandardSchemaV1<any, any>]\n ? Record<string, StandardSchemaV1Issue[]>\n : undefined\n\n/**\n * @private\n */\nexport type FormValidateAsyncFn<TFormData> = (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n // This is technically an edge-type; which we try to keep non-`any`, but in this case\n // It's referring to an inaccessible type from the field validate function inner types, so it's not a big deal\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n signal: AbortSignal\n}) => unknown | Promise<unknown>\n\nexport type FormValidator<TFormData, TType, TFn = unknown> = {\n validate(options: { value: TType }, fn: TFn): ValidationError\n validateAsync(\n options: { value: TType },\n fn: TFn,\n ): Promise<FormValidationError<TFormData>>\n}\n\ntype ValidationPromiseResult<TFormData> =\n | {\n fieldErrors: Partial<Record<DeepKeys<TFormData>, ValidationError>>\n errorMapKey: ValidationErrorMapKeys\n }\n | undefined\n\n/**\n * @private\n */\nexport type FormAsyncValidateOrFn<TFormData> =\n | FormValidateAsyncFn<TFormData>\n | StandardSchemaV1<TFormData, unknown>\n\nexport type UnwrapFormAsyncValidateOrFn<\n TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>,\n> = [TValidateOrFn] extends [FormValidateAsyncFn<any>]\n ? Awaited<ReturnType<TValidateOrFn>>\n : [TValidateOrFn] extends [StandardSchemaV1<any, any>]\n ? Record<string, StandardSchemaV1Issue[]>\n : undefined\n\nexport interface FormValidators<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n> {\n /**\n * Optional function that fires as soon as the component mounts.\n */\n onMount?: TOnMount\n /**\n * Optional function that checks the validity of your data whenever a value changes\n */\n onChange?: TOnChange\n /**\n * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.\n */\n onChangeAsync?: TOnChangeAsync\n /**\n * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.\n */\n onChangeAsyncDebounceMs?: number\n /**\n * Optional function that validates the form data when a field loses focus, returns a `FormValidationError`\n */\n onBlur?: TOnBlur\n /**\n * Optional onBlur asynchronous validation method for when a field loses focus returns a ` FormValidationError` or a promise of `Promise<FormValidationError>`\n */\n onBlurAsync?: TOnBlurAsync\n /**\n * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.\n */\n onBlurAsyncDebounceMs?: number\n onSubmit?: TOnSubmit\n onSubmitAsync?: TOnSubmitAsync\n}\n\n/**\n * @private\n */\nexport interface FormTransform<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n fn: (\n formBase: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) => FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n deps: unknown[]\n}\n\n/**\n * An object representing the options for a form.\n */\nexport interface FormOptions<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n /**\n * Set initial values for your form.\n */\n defaultValues?: TFormData\n /**\n * The default state for the form.\n */\n defaultState?: Partial<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n /**\n * If true, always run async validation, even when sync validation has produced an error. Defaults to undefined.\n */\n asyncAlways?: boolean\n /**\n * Optional time in milliseconds if you want to introduce a delay before firing off an async action.\n */\n asyncDebounceMs?: number\n /**\n * A list of validators to pass to the form\n */\n validators?: FormValidators<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n\n /**\n * A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`\n */\n onSubmit?: (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n meta: TSubmitMeta\n }) => any | Promise<any>\n /**\n * Specify an action for scenarios where the user tries to submit an invalid form.\n */\n onSubmitInvalid?: (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n }) => void\n transform?: FormTransform<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n}\n\n/**\n * An object representing the validation metadata for a field. Not intended for public usage.\n */\nexport type ValidationMeta = {\n /**\n * An abort controller stored in memory to cancel previous async validation attempts.\n */\n lastAbortController: AbortController\n}\n\n/**\n * An object representing the field information for a specific field within the form.\n */\nexport type FieldInfo<TFormData> = {\n /**\n * An instance of the FieldAPI.\n */\n instance: FieldApi<\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > | null\n /**\n * A record of field validation internal handling.\n */\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n}\n\n/**\n * An object representing the current state of the form.\n */\nexport type BaseFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = {\n /**\n * The current values of the form fields.\n */\n values: TFormData\n /**\n * The error map for the form itself.\n */\n errorMap: FormValidationErrorMap<\n UnwrapFormValidateOrFn<TOnMount>,\n UnwrapFormValidateOrFn<TOnChange>,\n UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,\n UnwrapFormValidateOrFn<TOnBlur>,\n UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,\n UnwrapFormValidateOrFn<TOnSubmit>,\n UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,\n UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n /**\n * An internal mechanism used for keeping track of validation logic in a form.\n */\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n /**\n * A record of field metadata for each field in the form, not including the derived properties, like `errors` and such\n */\n fieldMetaBase: Record<DeepKeys<TFormData>, AnyFieldMetaBase>\n /**\n * A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.\n *\n * Goes back to `false` when submission completes for one of the following reasons:\n * - the validation step returned errors.\n * - the `onSubmit` function has completed.\n *\n * Note: if you're running async operations in your `onSubmit` function make sure to await them to ensure `isSubmitting` is set to `false` only when the async operation completes.\n *\n * This is useful for displaying loading indicators or disabling form inputs during submission.\n *\n */\n isSubmitting: boolean\n /**\n * A boolean indicating if the form has been submitted.\n */\n isSubmitted: boolean\n /**\n * A boolean indicating if the form or any of its fields are currently validating.\n */\n isValidating: boolean\n /**\n * A counter for tracking the number of submission attempts.\n */\n submissionAttempts: number\n /**\n * A boolean indicating if the last submission was successful.\n */\n isSubmitSuccessful: boolean\n /**\n * @private, used to force a re-evaluation of the form state when options change\n */\n _force_re_eval?: boolean\n}\n\nexport type DerivedFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = {\n /**\n * A boolean indicating if the form is currently validating.\n */\n isFormValidating: boolean\n /**\n * A boolean indicating if the form is valid.\n */\n isFormValid: boolean\n /**\n * The error array for the form itself.\n */\n errors: Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n /**\n * A boolean indicating if any of the form fields are currently validating.\n */\n isFieldsValidating: boolean\n /**\n * A boolean indicating if all the form fields are valid.\n */\n isFieldsValid: boolean\n /**\n * A boolean indicating if any of the form fields have been touched.\n */\n isTouched: boolean\n /**\n * A boolean indicating if any of the form fields have been blurred.\n */\n isBlurred: boolean\n /**\n * A boolean indicating if any of the form's fields' values have been modified by the user. `True` if the user have modified at least one of the fields. Opposite of `isPristine`.\n */\n isDirty: boolean\n /**\n * A boolean indicating if none of the form's fields' values have been modified by the user. `True` if the user have not modified any of the fields. Opposite of `isDirty`.\n */\n isPristine: boolean\n /**\n * A boolean indicating if the form and all its fields are valid.\n */\n isValid: boolean\n /**\n * A boolean indicating if the form can be submitted based on its current state.\n */\n canSubmit: boolean\n /**\n * A record of field metadata for each field in the form.\n */\n fieldMeta: Record<DeepKeys<TFormData>, AnyFieldMeta>\n}\n\nexport type FormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n> &\n DerivedFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n\nexport type AnyFormState = FormState<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nfunction getDefaultFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n>(\n defaultState: Partial<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >,\n): BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n> {\n return {\n values: defaultState.values ?? ({} as never),\n errorMap: defaultState.errorMap ?? {},\n fieldMetaBase: defaultState.fieldMetaBase ?? ({} as never),\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isValidating: defaultState.isValidating ?? false,\n submissionAttempts: defaultState.submissionAttempts ?? 0,\n isSubmitSuccessful: defaultState.isSubmitSuccessful ?? false,\n validationMetaMap: defaultState.validationMetaMap ?? {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n }\n}\n\n/**\n * @public\n *\n * A type representing the Form API with all generics set to `any` for convenience.\n */\nexport type AnyFormApi = FormApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\n/**\n * A class representing the Form API. It handles the logic and interactions with the form state.\n *\n * Normally, you will not need to create a new `FormApi` instance directly. Instead, you will use a framework\n * hook/function like `useForm` or `createForm` to create a new instance for you that uses your framework's reactivity model.\n * However, if you need to create a new instance manually, you can do so by calling the `new FormApi` constructor.\n */\nexport class FormApi<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n /**\n * The options for the form.\n */\n options: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n > = {}\n baseStore!: Store<\n BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n fieldMetaDerived!: Derived<Record<DeepKeys<TFormData>, AnyFieldMeta>>\n store!: Derived<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n /**\n * A record of field information for each field in the form.\n */\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData>> = {} as any\n\n get state() {\n return this.store.state\n }\n\n /**\n * @private\n */\n prevTransformArray: unknown[] = []\n\n /**\n * @private Persistent store of all field validation errors originating from form-level validators.\n * Maintains the cumulative state across validation cycles, including cleared errors (undefined values).\n * This map preserves the complete validation state for all fields.\n */\n cumulativeFieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n\n /**\n * Constructs a new `FormApi` instance with the given form options.\n */\n constructor(\n opts?: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n this.baseStore = new Store(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n )\n\n this.fieldMetaDerived = new Derived({\n deps: [this.baseStore],\n fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {\n const prevVal = _prevVal as\n | Record<DeepKeys<TFormData>, AnyFieldMeta>\n | undefined\n const prevBaseStore = prevDepVals?.[0]\n const currBaseStore = currDepVals[0]\n\n let originalMetaCount = 0\n\n const fieldMeta = {} as FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >['fieldMeta']\n\n for (const fieldName of Object.keys(\n currBaseStore.fieldMetaBase,\n ) as Array<keyof typeof currBaseStore.fieldMetaBase>) {\n const currBaseVal = currBaseStore.fieldMetaBase[\n fieldName as never\n ] as AnyFieldMetaBase\n\n const prevBaseVal = prevBaseStore?.fieldMetaBase[\n fieldName as never\n ] as AnyFieldMetaBase | undefined\n\n const prevFieldInfo =\n prevVal?.[fieldName as never as keyof typeof prevVal]\n\n let fieldErrors = prevFieldInfo?.errors\n if (!prevBaseVal || currBaseVal.errorMap !== prevBaseVal.errorMap) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n fieldErrors = Object.values(currBaseVal.errorMap ?? {}).filter(\n (val) => val !== undefined,\n ) as never\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.getFieldInfo(fieldName)?.instance\n\n if (fieldInstance && !fieldInstance.options.disableErrorFlat) {\n fieldErrors = (fieldErrors as undefined | string[])?.flat(\n 1,\n ) as never\n }\n }\n\n // As a primitive, we don't need to aggressively persist the same referential value for performance reasons\n const isFieldPristine = !currBaseVal.isDirty\n\n if (\n prevFieldInfo &&\n prevFieldInfo.isPristine === isFieldPristine &&\n prevFieldInfo.errors === fieldErrors &&\n currBaseVal === prevBaseVal\n ) {\n fieldMeta[fieldName] = prevFieldInfo\n originalMetaCount++\n continue\n }\n\n fieldMeta[fieldName] = {\n ...currBaseVal,\n errors: fieldErrors,\n isPristine: isFieldPristine,\n } as AnyFieldMeta\n }\n\n if (\n prevVal &&\n originalMetaCount === Object.keys(currBaseStore.fieldMetaBase).length\n ) {\n return prevVal\n }\n\n return fieldMeta\n },\n })\n\n this.store = new Derived({\n deps: [this.baseStore, this.fieldMetaDerived],\n fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {\n const prevVal = _prevVal as\n | FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n | undefined\n const prevBaseStore = prevDepVals?.[0]\n const currBaseStore = currDepVals[0]\n\n // Computed state\n const fieldMetaValues = Object.values(currBaseStore.fieldMetaBase) as (\n | AnyFieldMeta\n | undefined\n )[]\n\n const isFieldsValidating = fieldMetaValues.some(\n (field) => field?.isValidating,\n )\n\n const isFieldsValid = !fieldMetaValues.some(\n (field) =>\n field?.errorMap &&\n isNonEmptyArray(Object.values(field.errorMap).filter(Boolean)),\n )\n\n const isTouched = fieldMetaValues.some((field) => field?.isTouched)\n const isBlurred = fieldMetaValues.some((field) => field?.isBlurred)\n\n const shouldInvalidateOnMount =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n isTouched && currBaseStore?.errorMap?.onMount\n\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const hasOnMountError = Boolean(\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n currBaseStore.errorMap?.onMount ||\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n fieldMetaValues.some((f) => f?.errorMap?.onMount),\n )\n\n const isValidating = !!isFieldsValidating\n\n // As `errors` is not a primitive, we need to aggressively persist the same referencial value for performance reasons\n let errors = prevVal?.errors ?? []\n if (\n !prevBaseStore ||\n currBaseStore.errorMap !== prevBaseStore.errorMap\n ) {\n errors = Object.values(currBaseStore.errorMap).reduce<\n Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n >((prev, curr) => {\n if (curr === undefined) return prev\n\n if (curr && isGlobalFormValidationError(curr)) {\n prev.push(curr.form as never)\n return prev\n }\n prev.push(curr as never)\n return prev\n }, [])\n }\n\n const isFormValid = errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (currBaseStore.submissionAttempts === 0 &&\n !isTouched &&\n !hasOnMountError) ||\n (!isValidating && !currBaseStore.isSubmitting && isValid)\n\n let errorMap = currBaseStore.errorMap\n if (shouldInvalidateOnMount) {\n errors = errors.filter(\n (err) => err !== currBaseStore.errorMap.onMount,\n )\n errorMap = Object.assign(errorMap, { onMount: undefined })\n }\n\n if (\n prevVal &&\n prevBaseStore &&\n prevVal.errorMap === errorMap &&\n prevVal.fieldMeta === this.fieldMetaDerived.state &&\n prevVal.errors === errors &&\n prevVal.isFieldsValidating === isFieldsValidating &&\n prevVal.isFieldsValid === isFieldsValid &&\n prevVal.isFormValid === isFormValid &&\n prevVal.isValid === isValid &&\n prevVal.canSubmit === canSubmit &&\n prevVal.isTouched === isTouched &&\n prevVal.isBlurred === isBlurred &&\n prevVal.isPristine === isPristine &&\n prevVal.isDirty === isDirty &&\n shallow(prevBaseStore, currBaseStore)\n ) {\n return prevVal\n }\n\n let state = {\n ...currBaseStore,\n errorMap,\n fieldMeta: this.fieldMetaDerived.state,\n errors,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isBlurred,\n isPristine,\n isDirty,\n } as FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n\n // Only run transform if state has shallowly changed - IE how React.useEffect works\n const transformArray = this.options.transform?.deps ?? []\n const shouldTransform =\n transformArray.length !== this.prevTransformArray.length ||\n transformArray.some((val, i) => val !== this.prevTransformArray[i])\n\n if (shouldTransform) {\n const newObj = Object.assign({}, this, { state })\n // This mutates the state\n this.options.transform?.fn(newObj)\n state = newObj.state\n this.prevTransformArray = transformArray\n }\n\n return state\n },\n })\n\n this.handleSubmit = this.handleSubmit.bind(this)\n\n this.update(opts || {})\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends TStandardSchemaValidatorValue<TFormData> & {\n formApi: AnyFormApi\n },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData>\n : FormAsyncValidateOrFn<TFormData>\n value: TValue\n type: TType\n }): unknown {\n if (isStandardSchemaValidator(props.validate)) {\n return standardSchemaValidators[props.type](\n props.value,\n props.validate,\n ) as never\n }\n\n return (props.validate as FormValidateFn<any>)(props.value) as never\n }\n\n mount = () => {\n const cleanupFieldMetaDerived = this.fieldMetaDerived.mount()\n const cleanupStoreDerived = this.store.mount()\n const cleanup = () => {\n cleanupFieldMetaDerived()\n cleanupStoreDerived()\n }\n const { onMount } = this.options.validators || {}\n if (!onMount) return cleanup\n this.validateSync('mount')\n\n return cleanup\n }\n\n /**\n * Updates the form options and form state.\n */\n update = (\n options?: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) => {\n if (!options) return\n\n const oldOptions = this.options\n\n // Options need to be updated first so that when the store is updated, the state is correct for the derived state\n this.options = options\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const shouldUpdateReeval = !!options.transform?.deps?.some(\n (val, i) => val !== this.prevTransformArray[i],\n )\n\n const shouldUpdateValues =\n options.defaultValues &&\n !shallow(options.defaultValues, oldOptions.defaultValues) &&\n !this.state.isTouched\n\n const shouldUpdateState =\n !shallow(options.defaultState, oldOptions.defaultState) &&\n !this.state.isTouched\n\n if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return\n\n batch(() => {\n this.baseStore.setState(() =>\n getDefaultFormState(\n Object.assign(\n {},\n this.state as any,\n\n shouldUpdateState ? options.defaultState : {},\n\n shouldUpdateValues\n ? {\n values: options.defaultValues,\n }\n : {},\n\n shouldUpdateReeval\n ? { _force_re_eval: !this.state._force_re_eval }\n : {},\n ),\n ),\n )\n })\n }\n\n /**\n * Resets the form state to the default values.\n * If values are provided, the form will be reset to those values instead and the default values will be updated.\n *\n * @param values - Optional values to reset the form to.\n * @param opts - Optional options to control the reset behavior.\n */\n reset = (values?: TFormData, opts?: { keepDefaultValues?: boolean }) => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMetaBase = this.resetFieldMeta(currentFieldMeta)\n\n if (values && !opts?.keepDefaultValues) {\n this.options = {\n ...this.options,\n defaultValues: values,\n }\n }\n\n this.baseStore.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values:\n values ??\n this.options.defaultValues ??\n this.options.defaultState?.values,\n fieldMetaBase,\n }),\n )\n }\n\n /**\n * Validates all fields using the correct handlers for a given validation cause.\n */\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n batch(() => {\n void (Object.values(this.fieldInfo) as FieldInfo<any>[]).forEach(\n (field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n // Remember, `validate` is either a sync operation or a promise\n Promise.resolve().then(() =>\n fieldInstance.validate(cause, { skipFormValidation: true }),\n ),\n )\n // If any fields are not touched\n if (!field.instance.state.meta.isTouched) {\n // Mark them as touched\n field.instance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n },\n )\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n const currentValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(currentValue)\n ? Math.max(currentValue.length - 1, 0)\n : null\n\n // We have to validate all fields that have shifted (at least the current field)\n const fieldKeysToValidate = [`${field}[${index}]`]\n for (let i = index + 1; i <= (lastIndex ?? 0); i++) {\n fieldKeysToValidate.push(`${field}[${i}]`)\n }\n\n // We also have to include all fields that are nested in the shifted fields\n const fieldsToValidate = Object.keys(this.fieldInfo).filter((fieldKey) =>\n fieldKeysToValidate.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n\n // Validate the fields\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n batch(() => {\n fieldsToValidate.forEach((nestedField) => {\n fieldValidationPromises.push(\n Promise.resolve().then(() => this.validateField(nestedField, cause)),\n )\n })\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFormData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.fieldInfo[field]?.instance\n if (!fieldInstance) return []\n\n // If the field is not touched (same logic as in validateAllFields)\n if (!fieldInstance.state.meta.isTouched) {\n // Mark it as touched\n fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n\n return fieldInstance.validate(cause)\n }\n\n /**\n * TODO: This code is copied from FieldApi, we should refactor to share\n * @private\n */\n validateSync = (\n cause: ValidationCause,\n ): {\n hasErrored: boolean\n fieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n } => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n // This map will only include fields that have errors in the current validation cycle\n const currentValidationErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n\n batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const rawError = this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n validationSource: 'form',\n },\n type: 'validate',\n })\n\n const { formError, fieldErrors } = normalizeError<TFormData>(rawError)\n\n const errorMapKey = getErrorMapKey(validateObj.cause)\n\n if (fieldErrors) {\n for (const [field, fieldError] of Object.entries(fieldErrors) as [\n DeepKeys<TFormData>,\n ValidationError,\n ][]) {\n const oldErrorMap = this.cumulativeFieldsErrorMap[field] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n currentValidationErrorMap[field] = newErrorMap\n this.cumulativeFieldsErrorMap[field] = newErrorMap\n\n const fieldMeta = this.getFieldMeta(field)\n if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: fieldError,\n },\n }))\n }\n }\n }\n\n for (const field of Object.keys(this.cumulativeFieldsErrorMap) as Array<\n DeepKeys<TFormData>\n >) {\n const fieldMeta = this.getFieldMeta(field)\n if (\n fieldMeta?.errorMap[errorMapKey] &&\n !currentValidationErrorMap[field]?.[errorMapKey]\n ) {\n this.cumulativeFieldsErrorMap[field] = {\n ...this.cumulativeFieldsErrorMap[field],\n [errorMapKey]: undefined,\n }\n\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: undefined,\n },\n }))\n }\n }\n\n if (this.state.errorMap[errorMapKey] !== formError) {\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: formError,\n },\n }))\n }\n\n if (formError || fieldErrors) {\n hasErrored = true\n }\n }\n\n /**\n * when we have an error for onSubmit in the state, we want\n * to clear the error as soon as the user enters a valid value in the field\n */\n const submitErrKey = getErrorMapKey('submit')\n if (\n this.state.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n })\n\n return { hasErrored, fieldsErrorMap: currentValidationErrorMap }\n }\n\n /**\n * @private\n */\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<\n FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n > => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.baseStore.setState((prev) => ({ ...prev, isFormValidating: true }))\n }\n\n /**\n * We have to use a for loop and generate our promises this way, otherwise it won't be sync\n * when there are no validators needed to be run\n */\n const promises: Promise<ValidationPromiseResult<TFormData>>[] = []\n\n let fieldErrors:\n | Partial<Record<DeepKeys<TFormData>, ValidationError>>\n | undefined\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = this.state.validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.state.validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationPromiseResult<TFormData>>(async (resolve) => {\n let rawError!:\n | ValidationError\n | FormValidationError<unknown>\n | undefined\n try {\n rawError = await new Promise((rawResolve, rawReject) => {\n setTimeout(async () => {\n if (controller.signal.aborted) return rawResolve(undefined)\n try {\n rawResolve(\n await this.runValidator({\n validate: validateObj.validate!,\n value: {\n value: this.state.values,\n formApi: this,\n validationSource: 'form',\n signal: controller.signal,\n },\n type: 'validateAsync',\n }),\n )\n } catch (e) {\n rawReject(e)\n }\n }, validateObj.debounceMs)\n })\n } catch (e: unknown) {\n rawError = e as ValidationError\n }\n const { formError, fieldErrors: fieldErrorsFromNormalizeError } =\n normalizeError<TFormData>(rawError)\n\n if (fieldErrorsFromNormalizeError) {\n fieldErrors = fieldErrors\n ? { ...fieldErrors, ...fieldErrorsFromNormalizeError }\n : fieldErrorsFromNormalizeError\n }\n const errorMapKey = getErrorMapKey(validateObj.cause)\n\n if (fieldErrors) {\n for (const [field, fieldError] of Object.entries(fieldErrors)) {\n const fieldMeta = this.getFieldMeta(field as DeepKeys<TFormData>)\n if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {\n this.setFieldMeta(field as DeepKeys<TFormData>, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: fieldError,\n },\n }))\n }\n }\n }\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: formError,\n },\n }))\n\n resolve(fieldErrors ? { fieldErrors, errorMapKey } : undefined)\n }),\n )\n }\n\n let results: ValidationPromiseResult<TFormData>[] = []\n\n const fieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n if (promises.length) {\n results = await Promise.all(promises)\n for (const fieldValidationResult of results) {\n if (fieldValidationResult?.fieldErrors) {\n const { errorMapKey } = fieldValidationResult\n\n for (const [field, fieldError] of Object.entries(\n fieldValidationResult.fieldErrors,\n )) {\n const oldErrorMap =\n fieldsErrorMap[field as DeepKeys<TFormData>] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n fieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap\n }\n }\n }\n }\n\n this.baseStore.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return fieldsErrorMap\n }\n\n /**\n * @private\n */\n validate = (\n cause: ValidationCause,\n ):\n | FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n | Promise<\n FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n > => {\n // Attempt to sync validate first\n const { hasErrored, fieldsErrorMap } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return fieldsErrorMap\n }\n\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n this.baseStore.setState((old) => ({\n ...old,\n // Submission attempts mark the form as not submitted\n isSubmitted: false,\n // Count submission attempts\n submissionAttempts: old.submissionAttempts + 1,\n isSubmitSuccessful: false, // Reset isSubmitSuccessful at the start of submission\n }))\n\n // Don't let invalid forms submit\n if (!this.state.canSubmit) return\n\n this.baseStore.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.baseStore.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n await this.validateAllFields('submit')\n\n if (!this.state.isFieldsValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n await this.validate('submit')\n\n // Fields are invalid, do not submit\n if (!this.state.isValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n batch(() => {\n void (Object.values(this.fieldInfo) as FieldInfo<TFormData>[]).forEach(\n (field) => {\n field.instance?.options.listeners?.onSubmit?.({\n value: field.instance.state.value,\n fieldApi: field.instance,\n })\n },\n )\n })\n\n try {\n // Run the submit code\n await this.options.onSubmit?.({\n value: this.state.values,\n formApi: this,\n meta: submitMeta ?? this.options.onSubmitMeta,\n } as any)\n\n batch(() => {\n this.baseStore.setState((prev) => ({\n ...prev,\n isSubmitted: true,\n isSubmitSuccessful: true, // Set isSubmitSuccessful to true on successful submission\n }))\n done()\n })\n } catch (err) {\n this.baseStore.setState((prev) => ({\n ...prev,\n isSubmitSuccessful: false, // Ensure isSubmitSuccessful is false if an error occurs\n }))\n done()\n throw err\n }\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): DeepValue<TFormData, TField> => getBy(this.state.values, field)\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): AnyFieldMeta | undefined => {\n return this.state.fieldMeta[field]\n }\n\n /**\n * Gets the field info of the specified field.\n */\n getFieldInfo = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldInfo<TFormData> => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (this.fieldInfo[field] ||= {\n instance: null,\n validationMetaMap: {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n })\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<AnyFieldMeta>,\n ) => {\n this.baseStore.setState((prev) => {\n return {\n ...prev,\n fieldMetaBase: {\n ...prev.fieldMetaBase,\n [field]: functionalUpdate(\n updater,\n prev.fieldMetaBase[field] as never,\n ),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, AnyFieldMeta>,\n ): Record<TField, AnyFieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, AnyFieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, AnyFieldMeta>,\n )\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<DeepValue<TFormData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n const dontUpdateMeta = opts?.dontUpdateMeta ?? false\n\n batch(() => {\n if (!dontUpdateMeta) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n onMount: undefined,\n },\n }))\n }\n\n this.baseStore.setState((prev) => {\n return {\n ...prev,\n values: setBy(prev.values, field, updater),\n }\n })\n })\n }\n\n deleteField = <TField extends DeepKeys<TFormData>>(field: TField) => {\n this.baseStore.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMetaBase[field]\n\n return newState\n })\n delete this.fieldInfo[field]\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,\n opts,\n )\n this.validateField(field, 'change')\n }\n\n insertFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return [\n ...(prev as DeepValue<TFormData, TField>[]).slice(0, index),\n value,\n ...(prev as DeepValue<TFormData, TField>[]).slice(index),\n ] as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n\n // Shift down all meta after validating to make sure the new field has been mounted\n metaHelper(this).handleArrayFieldMetaShift(field, index, 'insert')\n\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).map((d, i) =>\n i === index ? value : d,\n ) as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n const fieldValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(fieldValue)\n ? Math.max(fieldValue.length - 1, 0)\n : null\n\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).filter(\n (_d, i) => i !== index,\n ) as any\n },\n opts,\n )\n\n // Shift up all meta\n metaHelper(this).handleArrayFieldMetaShift(field, index, 'remove')\n\n if (lastIndex !== null) {\n const start = `${field}[${lastIndex}]`\n const fieldsToDelete = Object.keys(this.fieldInfo).filter((f) =>\n f.startsWith(start),\n )\n\n // Cleanup the last fields\n fieldsToDelete.forEach((f) => this.deleteField(f as TField))\n }\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev: any) => {\n const prev1 = prev[index1]!\n const prev2 = prev[index2]!\n return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1)\n },\n opts,\n )\n\n // Swap meta\n metaHelper(this).handleArrayFieldMetaShift(field, index1, 'swap', index2)\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the swapped fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev: any) => {\n prev.splice(index2, 0, prev.splice(index1, 1)[0])\n return prev\n },\n opts,\n )\n\n // Move meta between index1 and index2\n metaHelper(this).handleArrayFieldMetaShift(field, index1, 'move', index2)\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the moved fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n /**\n * Updates the form's errorMap\n */\n setErrorMap(\n errorMap: ValidationErrorMap<\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >,\n ) {\n this.baseStore.setState(\n (prev) =>\n ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n ...errorMap,\n },\n }) as never,\n )\n }\n\n /**\n * Returns form and field level errors\n */\n getAllErrors = (): {\n form: {\n errors: Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n errorMap: FormValidationErrorMap<\n UnwrapFormValidateOrFn<TOnMount>,\n UnwrapFormValidateOrFn<TOnChange>,\n UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,\n UnwrapFormValidateOrFn<TOnBlur>,\n UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,\n UnwrapFormValidateOrFn<TOnSubmit>,\n UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,\n UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n }\n fields: Record<\n DeepKeys<TFormData>,\n { errors: ValidationError[]; errorMap: ValidationErrorMap }\n >\n } => {\n return {\n form: {\n errors: this.state.errors,\n errorMap: this.state.errorMap,\n },\n fields: Object.entries(this.state.fieldMeta).reduce(\n (acc, [fieldName, fieldMeta]) => {\n if (\n Object.keys(fieldMeta as AnyFieldMeta).length &&\n (fieldMeta as AnyFieldMeta).errors.length\n ) {\n acc[fieldName as DeepKeys<TFormData>] = {\n errors: (fieldMeta as AnyFieldMeta).errors,\n errorMap: (fieldMeta as AnyFieldMeta).errorMap,\n }\n }\n\n return acc\n },\n {} as Record<\n DeepKeys<TFormData>,\n { errors: ValidationError[]; errorMap: ValidationErrorMap }\n >,\n ),\n }\n }\n}\n\nfunction normalizeError<TFormData>(rawError?: FormValidationError<unknown>): {\n formError: ValidationError\n fieldErrors?: Partial<Record<DeepKeys<TFormData>, ValidationError>>\n} {\n if (rawError) {\n if (isGlobalFormValidationError(rawError)) {\n const formError = normalizeError(rawError.form).formError\n const fieldErrors = rawError.fields\n return { formError, fieldErrors } as never\n }\n\n return { formError: rawError }\n }\n\n return { formError: undefined }\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n case 'server':\n return 'onServer'\n case 'change':\n default:\n return 'onChange'\n }\n}\n"],"names":["_a","shallow","batch","opts","getSyncValidatorArray","getAsyncValidatorArray","getBy","functionalUpdate","setBy","deleteBy","metaHelper","Store","Derived","isNonEmptyArray","isGlobalFormValidationError","isStandardSchemaValidator","standardSchemaValidators","_c","_b"],"mappings":"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"}
@@ -189,6 +189,10 @@ export type BaseFormState<TFormData, TOnMount extends undefined | FormValidateOr
189
189
  * A counter for tracking the number of submission attempts.
190
190
  */
191
191
  submissionAttempts: number;
192
+ /**
193
+ * A boolean indicating if the last submission was successful.
194
+ */
195
+ isSubmitSuccessful: boolean;
192
196
  /**
193
197
  * @private, used to force a re-evaluation of the form state when options change
194
198
  */
@@ -189,6 +189,10 @@ export type BaseFormState<TFormData, TOnMount extends undefined | FormValidateOr
189
189
  * A counter for tracking the number of submission attempts.
190
190
  */
191
191
  submissionAttempts: number;
192
+ /**
193
+ * A boolean indicating if the last submission was successful.
194
+ */
195
+ isSubmitSuccessful: boolean;
192
196
  /**
193
197
  * @private, used to force a re-evaluation of the form state when options change
194
198
  */
@@ -11,6 +11,7 @@ function getDefaultFormState(defaultState) {
11
11
  isSubmitting: defaultState.isSubmitting ?? false,
12
12
  isValidating: defaultState.isValidating ?? false,
13
13
  submissionAttempts: defaultState.submissionAttempts ?? 0,
14
+ isSubmitSuccessful: defaultState.isSubmitSuccessful ?? false,
14
15
  validationMetaMap: defaultState.validationMetaMap ?? {
15
16
  onChange: void 0,
16
17
  onBlur: void 0,
@@ -678,7 +679,9 @@ class FormApi {
678
679
  // Submission attempts mark the form as not submitted
679
680
  isSubmitted: false,
680
681
  // Count submission attempts
681
- submissionAttempts: old.submissionAttempts + 1
682
+ submissionAttempts: old.submissionAttempts + 1,
683
+ isSubmitSuccessful: false
684
+ // Reset isSubmitSuccessful at the start of submission
682
685
  }));
683
686
  if (!this.state.canSubmit) return;
684
687
  this.baseStore.setState((d) => ({ ...d, isSubmitting: true }));
@@ -721,10 +724,20 @@ class FormApi {
721
724
  meta: submitMeta ?? this.options.onSubmitMeta
722
725
  }));
723
726
  batch(() => {
724
- this.baseStore.setState((prev) => ({ ...prev, isSubmitted: true }));
727
+ this.baseStore.setState((prev) => ({
728
+ ...prev,
729
+ isSubmitted: true,
730
+ isSubmitSuccessful: true
731
+ // Set isSubmitSuccessful to true on successful submission
732
+ }));
725
733
  done();
726
734
  });
727
735
  } catch (err) {
736
+ this.baseStore.setState((prev) => ({
737
+ ...prev,
738
+ isSubmitSuccessful: false
739
+ // Ensure isSubmitSuccessful is false if an error occurs
740
+ }));
728
741
  done();
729
742
  throw err;
730
743
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FormApi.js","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Derived, Store, batch } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isGlobalFormValidationError,\n isNonEmptyArray,\n setBy,\n shallow,\n} from './utils'\nimport {\n isStandardSchemaValidator,\n standardSchemaValidators,\n} from './standardSchemaValidator'\nimport { metaHelper } from './metaHelper'\nimport type {\n StandardSchemaV1,\n StandardSchemaV1Issue,\n TStandardSchemaValidatorValue,\n} from './standardSchemaValidator'\nimport type { AnyFieldMeta, AnyFieldMetaBase, FieldApi } from './FieldApi'\nimport type {\n FormValidationError,\n FormValidationErrorMap,\n UpdateMetaOptions,\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n} from './types'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { Updater } from './utils'\n\n/**\n * @private\n */\n// TODO: Add the `Unwrap` type to the errors\ntype FormErrorMapFromValidator<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = Partial<\n Record<\n DeepKeys<TFormData>,\n ValidationErrorMap<\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n >\n>\n\nexport type FormValidateFn<TFormData> = (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n // This is technically an edge-type; which we try to keep non-`any`, but in this case\n // It's referring to an inaccessible type from the field validate function inner types, so it's not a big deal\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n}) => unknown\n\n/**\n * @private\n */\nexport type FormValidateOrFn<TFormData> =\n | FormValidateFn<TFormData>\n | StandardSchemaV1<TFormData, unknown>\n\nexport type UnwrapFormValidateOrFn<\n TValidateOrFn extends undefined | FormValidateOrFn<any>,\n> = [TValidateOrFn] extends [FormValidateFn<any>]\n ? ReturnType<TValidateOrFn>\n : [TValidateOrFn] extends [StandardSchemaV1<any, any>]\n ? Record<string, StandardSchemaV1Issue[]>\n : undefined\n\n/**\n * @private\n */\nexport type FormValidateAsyncFn<TFormData> = (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n // This is technically an edge-type; which we try to keep non-`any`, but in this case\n // It's referring to an inaccessible type from the field validate function inner types, so it's not a big deal\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n signal: AbortSignal\n}) => unknown | Promise<unknown>\n\nexport type FormValidator<TFormData, TType, TFn = unknown> = {\n validate(options: { value: TType }, fn: TFn): ValidationError\n validateAsync(\n options: { value: TType },\n fn: TFn,\n ): Promise<FormValidationError<TFormData>>\n}\n\ntype ValidationPromiseResult<TFormData> =\n | {\n fieldErrors: Partial<Record<DeepKeys<TFormData>, ValidationError>>\n errorMapKey: ValidationErrorMapKeys\n }\n | undefined\n\n/**\n * @private\n */\nexport type FormAsyncValidateOrFn<TFormData> =\n | FormValidateAsyncFn<TFormData>\n | StandardSchemaV1<TFormData, unknown>\n\nexport type UnwrapFormAsyncValidateOrFn<\n TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>,\n> = [TValidateOrFn] extends [FormValidateAsyncFn<any>]\n ? Awaited<ReturnType<TValidateOrFn>>\n : [TValidateOrFn] extends [StandardSchemaV1<any, any>]\n ? Record<string, StandardSchemaV1Issue[]>\n : undefined\n\nexport interface FormValidators<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n> {\n /**\n * Optional function that fires as soon as the component mounts.\n */\n onMount?: TOnMount\n /**\n * Optional function that checks the validity of your data whenever a value changes\n */\n onChange?: TOnChange\n /**\n * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.\n */\n onChangeAsync?: TOnChangeAsync\n /**\n * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.\n */\n onChangeAsyncDebounceMs?: number\n /**\n * Optional function that validates the form data when a field loses focus, returns a `FormValidationError`\n */\n onBlur?: TOnBlur\n /**\n * Optional onBlur asynchronous validation method for when a field loses focus returns a ` FormValidationError` or a promise of `Promise<FormValidationError>`\n */\n onBlurAsync?: TOnBlurAsync\n /**\n * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.\n */\n onBlurAsyncDebounceMs?: number\n onSubmit?: TOnSubmit\n onSubmitAsync?: TOnSubmitAsync\n}\n\n/**\n * @private\n */\nexport interface FormTransform<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n fn: (\n formBase: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) => FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n deps: unknown[]\n}\n\n/**\n * An object representing the options for a form.\n */\nexport interface FormOptions<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n /**\n * Set initial values for your form.\n */\n defaultValues?: TFormData\n /**\n * The default state for the form.\n */\n defaultState?: Partial<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n /**\n * If true, always run async validation, even when sync validation has produced an error. Defaults to undefined.\n */\n asyncAlways?: boolean\n /**\n * Optional time in milliseconds if you want to introduce a delay before firing off an async action.\n */\n asyncDebounceMs?: number\n /**\n * A list of validators to pass to the form\n */\n validators?: FormValidators<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n\n /**\n * A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`\n */\n onSubmit?: (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n meta: TSubmitMeta\n }) => any | Promise<any>\n /**\n * Specify an action for scenarios where the user tries to submit an invalid form.\n */\n onSubmitInvalid?: (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n }) => void\n transform?: FormTransform<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n}\n\n/**\n * An object representing the validation metadata for a field. Not intended for public usage.\n */\nexport type ValidationMeta = {\n /**\n * An abort controller stored in memory to cancel previous async validation attempts.\n */\n lastAbortController: AbortController\n}\n\n/**\n * An object representing the field information for a specific field within the form.\n */\nexport type FieldInfo<TFormData> = {\n /**\n * An instance of the FieldAPI.\n */\n instance: FieldApi<\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > | null\n /**\n * A record of field validation internal handling.\n */\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n}\n\n/**\n * An object representing the current state of the form.\n */\nexport type BaseFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = {\n /**\n * The current values of the form fields.\n */\n values: TFormData\n /**\n * The error map for the form itself.\n */\n errorMap: FormValidationErrorMap<\n UnwrapFormValidateOrFn<TOnMount>,\n UnwrapFormValidateOrFn<TOnChange>,\n UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,\n UnwrapFormValidateOrFn<TOnBlur>,\n UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,\n UnwrapFormValidateOrFn<TOnSubmit>,\n UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,\n UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n /**\n * An internal mechanism used for keeping track of validation logic in a form.\n */\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n /**\n * A record of field metadata for each field in the form, not including the derived properties, like `errors` and such\n */\n fieldMetaBase: Record<DeepKeys<TFormData>, AnyFieldMetaBase>\n /**\n * A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.\n *\n * Goes back to `false` when submission completes for one of the following reasons:\n * - the validation step returned errors.\n * - the `onSubmit` function has completed.\n *\n * Note: if you're running async operations in your `onSubmit` function make sure to await them to ensure `isSubmitting` is set to `false` only when the async operation completes.\n *\n * This is useful for displaying loading indicators or disabling form inputs during submission.\n *\n */\n isSubmitting: boolean\n /**\n * A boolean indicating if the form has been submitted.\n */\n isSubmitted: boolean\n /**\n * A boolean indicating if the form or any of its fields are currently validating.\n */\n isValidating: boolean\n /**\n * A counter for tracking the number of submission attempts.\n */\n submissionAttempts: number\n /**\n * @private, used to force a re-evaluation of the form state when options change\n */\n _force_re_eval?: boolean\n}\n\nexport type DerivedFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = {\n /**\n * A boolean indicating if the form is currently validating.\n */\n isFormValidating: boolean\n /**\n * A boolean indicating if the form is valid.\n */\n isFormValid: boolean\n /**\n * The error array for the form itself.\n */\n errors: Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n /**\n * A boolean indicating if any of the form fields are currently validating.\n */\n isFieldsValidating: boolean\n /**\n * A boolean indicating if all the form fields are valid.\n */\n isFieldsValid: boolean\n /**\n * A boolean indicating if any of the form fields have been touched.\n */\n isTouched: boolean\n /**\n * A boolean indicating if any of the form fields have been blurred.\n */\n isBlurred: boolean\n /**\n * A boolean indicating if any of the form's fields' values have been modified by the user. `True` if the user have modified at least one of the fields. Opposite of `isPristine`.\n */\n isDirty: boolean\n /**\n * A boolean indicating if none of the form's fields' values have been modified by the user. `True` if the user have not modified any of the fields. Opposite of `isDirty`.\n */\n isPristine: boolean\n /**\n * A boolean indicating if the form and all its fields are valid.\n */\n isValid: boolean\n /**\n * A boolean indicating if the form can be submitted based on its current state.\n */\n canSubmit: boolean\n /**\n * A record of field metadata for each field in the form.\n */\n fieldMeta: Record<DeepKeys<TFormData>, AnyFieldMeta>\n}\n\nexport type FormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n> &\n DerivedFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n\nexport type AnyFormState = FormState<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nfunction getDefaultFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n>(\n defaultState: Partial<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >,\n): BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n> {\n return {\n values: defaultState.values ?? ({} as never),\n errorMap: defaultState.errorMap ?? {},\n fieldMetaBase: defaultState.fieldMetaBase ?? ({} as never),\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isValidating: defaultState.isValidating ?? false,\n submissionAttempts: defaultState.submissionAttempts ?? 0,\n validationMetaMap: defaultState.validationMetaMap ?? {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n }\n}\n\n/**\n * @public\n *\n * A type representing the Form API with all generics set to `any` for convenience.\n */\nexport type AnyFormApi = FormApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\n/**\n * A class representing the Form API. It handles the logic and interactions with the form state.\n *\n * Normally, you will not need to create a new `FormApi` instance directly. Instead, you will use a framework\n * hook/function like `useForm` or `createForm` to create a new instance for you that uses your framework's reactivity model.\n * However, if you need to create a new instance manually, you can do so by calling the `new FormApi` constructor.\n */\nexport class FormApi<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n /**\n * The options for the form.\n */\n options: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n > = {}\n baseStore!: Store<\n BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n fieldMetaDerived!: Derived<Record<DeepKeys<TFormData>, AnyFieldMeta>>\n store!: Derived<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n /**\n * A record of field information for each field in the form.\n */\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData>> = {} as any\n\n get state() {\n return this.store.state\n }\n\n /**\n * @private\n */\n prevTransformArray: unknown[] = []\n\n /**\n * @private Persistent store of all field validation errors originating from form-level validators.\n * Maintains the cumulative state across validation cycles, including cleared errors (undefined values).\n * This map preserves the complete validation state for all fields.\n */\n cumulativeFieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n\n /**\n * Constructs a new `FormApi` instance with the given form options.\n */\n constructor(\n opts?: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n this.baseStore = new Store(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n )\n\n this.fieldMetaDerived = new Derived({\n deps: [this.baseStore],\n fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {\n const prevVal = _prevVal as\n | Record<DeepKeys<TFormData>, AnyFieldMeta>\n | undefined\n const prevBaseStore = prevDepVals?.[0]\n const currBaseStore = currDepVals[0]\n\n let originalMetaCount = 0\n\n const fieldMeta = {} as FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >['fieldMeta']\n\n for (const fieldName of Object.keys(\n currBaseStore.fieldMetaBase,\n ) as Array<keyof typeof currBaseStore.fieldMetaBase>) {\n const currBaseVal = currBaseStore.fieldMetaBase[\n fieldName as never\n ] as AnyFieldMetaBase\n\n const prevBaseVal = prevBaseStore?.fieldMetaBase[\n fieldName as never\n ] as AnyFieldMetaBase | undefined\n\n const prevFieldInfo =\n prevVal?.[fieldName as never as keyof typeof prevVal]\n\n let fieldErrors = prevFieldInfo?.errors\n if (!prevBaseVal || currBaseVal.errorMap !== prevBaseVal.errorMap) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n fieldErrors = Object.values(currBaseVal.errorMap ?? {}).filter(\n (val) => val !== undefined,\n ) as never\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.getFieldInfo(fieldName)?.instance\n\n if (fieldInstance && !fieldInstance.options.disableErrorFlat) {\n fieldErrors = (fieldErrors as undefined | string[])?.flat(\n 1,\n ) as never\n }\n }\n\n // As a primitive, we don't need to aggressively persist the same referential value for performance reasons\n const isFieldPristine = !currBaseVal.isDirty\n\n if (\n prevFieldInfo &&\n prevFieldInfo.isPristine === isFieldPristine &&\n prevFieldInfo.errors === fieldErrors &&\n currBaseVal === prevBaseVal\n ) {\n fieldMeta[fieldName] = prevFieldInfo\n originalMetaCount++\n continue\n }\n\n fieldMeta[fieldName] = {\n ...currBaseVal,\n errors: fieldErrors,\n isPristine: isFieldPristine,\n } as AnyFieldMeta\n }\n\n if (\n prevVal &&\n originalMetaCount === Object.keys(currBaseStore.fieldMetaBase).length\n ) {\n return prevVal\n }\n\n return fieldMeta\n },\n })\n\n this.store = new Derived({\n deps: [this.baseStore, this.fieldMetaDerived],\n fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {\n const prevVal = _prevVal as\n | FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n | undefined\n const prevBaseStore = prevDepVals?.[0]\n const currBaseStore = currDepVals[0]\n\n // Computed state\n const fieldMetaValues = Object.values(currBaseStore.fieldMetaBase) as (\n | AnyFieldMeta\n | undefined\n )[]\n\n const isFieldsValidating = fieldMetaValues.some(\n (field) => field?.isValidating,\n )\n\n const isFieldsValid = !fieldMetaValues.some(\n (field) =>\n field?.errorMap &&\n isNonEmptyArray(Object.values(field.errorMap).filter(Boolean)),\n )\n\n const isTouched = fieldMetaValues.some((field) => field?.isTouched)\n const isBlurred = fieldMetaValues.some((field) => field?.isBlurred)\n\n const shouldInvalidateOnMount =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n isTouched && currBaseStore?.errorMap?.onMount\n\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const hasOnMountError = Boolean(\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n currBaseStore.errorMap?.onMount ||\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n fieldMetaValues.some((f) => f?.errorMap?.onMount),\n )\n\n const isValidating = !!isFieldsValidating\n\n // As `errors` is not a primitive, we need to aggressively persist the same referencial value for performance reasons\n let errors = prevVal?.errors ?? []\n if (\n !prevBaseStore ||\n currBaseStore.errorMap !== prevBaseStore.errorMap\n ) {\n errors = Object.values(currBaseStore.errorMap).reduce<\n Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n >((prev, curr) => {\n if (curr === undefined) return prev\n\n if (curr && isGlobalFormValidationError(curr)) {\n prev.push(curr.form as never)\n return prev\n }\n prev.push(curr as never)\n return prev\n }, [])\n }\n\n const isFormValid = errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (currBaseStore.submissionAttempts === 0 &&\n !isTouched &&\n !hasOnMountError) ||\n (!isValidating && !currBaseStore.isSubmitting && isValid)\n\n let errorMap = currBaseStore.errorMap\n if (shouldInvalidateOnMount) {\n errors = errors.filter(\n (err) => err !== currBaseStore.errorMap.onMount,\n )\n errorMap = Object.assign(errorMap, { onMount: undefined })\n }\n\n if (\n prevVal &&\n prevBaseStore &&\n prevVal.errorMap === errorMap &&\n prevVal.fieldMeta === this.fieldMetaDerived.state &&\n prevVal.errors === errors &&\n prevVal.isFieldsValidating === isFieldsValidating &&\n prevVal.isFieldsValid === isFieldsValid &&\n prevVal.isFormValid === isFormValid &&\n prevVal.isValid === isValid &&\n prevVal.canSubmit === canSubmit &&\n prevVal.isTouched === isTouched &&\n prevVal.isBlurred === isBlurred &&\n prevVal.isPristine === isPristine &&\n prevVal.isDirty === isDirty &&\n shallow(prevBaseStore, currBaseStore)\n ) {\n return prevVal\n }\n\n let state = {\n ...currBaseStore,\n errorMap,\n fieldMeta: this.fieldMetaDerived.state,\n errors,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isBlurred,\n isPristine,\n isDirty,\n } as FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n\n // Only run transform if state has shallowly changed - IE how React.useEffect works\n const transformArray = this.options.transform?.deps ?? []\n const shouldTransform =\n transformArray.length !== this.prevTransformArray.length ||\n transformArray.some((val, i) => val !== this.prevTransformArray[i])\n\n if (shouldTransform) {\n const newObj = Object.assign({}, this, { state })\n // This mutates the state\n this.options.transform?.fn(newObj)\n state = newObj.state\n this.prevTransformArray = transformArray\n }\n\n return state\n },\n })\n\n this.handleSubmit = this.handleSubmit.bind(this)\n\n this.update(opts || {})\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends TStandardSchemaValidatorValue<TFormData> & {\n formApi: AnyFormApi\n },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData>\n : FormAsyncValidateOrFn<TFormData>\n value: TValue\n type: TType\n }): unknown {\n if (isStandardSchemaValidator(props.validate)) {\n return standardSchemaValidators[props.type](\n props.value,\n props.validate,\n ) as never\n }\n\n return (props.validate as FormValidateFn<any>)(props.value) as never\n }\n\n mount = () => {\n const cleanupFieldMetaDerived = this.fieldMetaDerived.mount()\n const cleanupStoreDerived = this.store.mount()\n const cleanup = () => {\n cleanupFieldMetaDerived()\n cleanupStoreDerived()\n }\n const { onMount } = this.options.validators || {}\n if (!onMount) return cleanup\n this.validateSync('mount')\n\n return cleanup\n }\n\n /**\n * Updates the form options and form state.\n */\n update = (\n options?: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) => {\n if (!options) return\n\n const oldOptions = this.options\n\n // Options need to be updated first so that when the store is updated, the state is correct for the derived state\n this.options = options\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const shouldUpdateReeval = !!options.transform?.deps?.some(\n (val, i) => val !== this.prevTransformArray[i],\n )\n\n const shouldUpdateValues =\n options.defaultValues &&\n !shallow(options.defaultValues, oldOptions.defaultValues) &&\n !this.state.isTouched\n\n const shouldUpdateState =\n !shallow(options.defaultState, oldOptions.defaultState) &&\n !this.state.isTouched\n\n if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return\n\n batch(() => {\n this.baseStore.setState(() =>\n getDefaultFormState(\n Object.assign(\n {},\n this.state as any,\n\n shouldUpdateState ? options.defaultState : {},\n\n shouldUpdateValues\n ? {\n values: options.defaultValues,\n }\n : {},\n\n shouldUpdateReeval\n ? { _force_re_eval: !this.state._force_re_eval }\n : {},\n ),\n ),\n )\n })\n }\n\n /**\n * Resets the form state to the default values.\n * If values are provided, the form will be reset to those values instead and the default values will be updated.\n *\n * @param values - Optional values to reset the form to.\n * @param opts - Optional options to control the reset behavior.\n */\n reset = (values?: TFormData, opts?: { keepDefaultValues?: boolean }) => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMetaBase = this.resetFieldMeta(currentFieldMeta)\n\n if (values && !opts?.keepDefaultValues) {\n this.options = {\n ...this.options,\n defaultValues: values,\n }\n }\n\n this.baseStore.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values:\n values ??\n this.options.defaultValues ??\n this.options.defaultState?.values,\n fieldMetaBase,\n }),\n )\n }\n\n /**\n * Validates all fields using the correct handlers for a given validation cause.\n */\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n batch(() => {\n void (Object.values(this.fieldInfo) as FieldInfo<any>[]).forEach(\n (field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n // Remember, `validate` is either a sync operation or a promise\n Promise.resolve().then(() =>\n fieldInstance.validate(cause, { skipFormValidation: true }),\n ),\n )\n // If any fields are not touched\n if (!field.instance.state.meta.isTouched) {\n // Mark them as touched\n field.instance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n },\n )\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n const currentValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(currentValue)\n ? Math.max(currentValue.length - 1, 0)\n : null\n\n // We have to validate all fields that have shifted (at least the current field)\n const fieldKeysToValidate = [`${field}[${index}]`]\n for (let i = index + 1; i <= (lastIndex ?? 0); i++) {\n fieldKeysToValidate.push(`${field}[${i}]`)\n }\n\n // We also have to include all fields that are nested in the shifted fields\n const fieldsToValidate = Object.keys(this.fieldInfo).filter((fieldKey) =>\n fieldKeysToValidate.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n\n // Validate the fields\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n batch(() => {\n fieldsToValidate.forEach((nestedField) => {\n fieldValidationPromises.push(\n Promise.resolve().then(() => this.validateField(nestedField, cause)),\n )\n })\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFormData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.fieldInfo[field]?.instance\n if (!fieldInstance) return []\n\n // If the field is not touched (same logic as in validateAllFields)\n if (!fieldInstance.state.meta.isTouched) {\n // Mark it as touched\n fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n\n return fieldInstance.validate(cause)\n }\n\n /**\n * TODO: This code is copied from FieldApi, we should refactor to share\n * @private\n */\n validateSync = (\n cause: ValidationCause,\n ): {\n hasErrored: boolean\n fieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n } => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n // This map will only include fields that have errors in the current validation cycle\n const currentValidationErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n\n batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const rawError = this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n validationSource: 'form',\n },\n type: 'validate',\n })\n\n const { formError, fieldErrors } = normalizeError<TFormData>(rawError)\n\n const errorMapKey = getErrorMapKey(validateObj.cause)\n\n if (fieldErrors) {\n for (const [field, fieldError] of Object.entries(fieldErrors) as [\n DeepKeys<TFormData>,\n ValidationError,\n ][]) {\n const oldErrorMap = this.cumulativeFieldsErrorMap[field] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n currentValidationErrorMap[field] = newErrorMap\n this.cumulativeFieldsErrorMap[field] = newErrorMap\n\n const fieldMeta = this.getFieldMeta(field)\n if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: fieldError,\n },\n }))\n }\n }\n }\n\n for (const field of Object.keys(this.cumulativeFieldsErrorMap) as Array<\n DeepKeys<TFormData>\n >) {\n const fieldMeta = this.getFieldMeta(field)\n if (\n fieldMeta?.errorMap[errorMapKey] &&\n !currentValidationErrorMap[field]?.[errorMapKey]\n ) {\n this.cumulativeFieldsErrorMap[field] = {\n ...this.cumulativeFieldsErrorMap[field],\n [errorMapKey]: undefined,\n }\n\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: undefined,\n },\n }))\n }\n }\n\n if (this.state.errorMap[errorMapKey] !== formError) {\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: formError,\n },\n }))\n }\n\n if (formError || fieldErrors) {\n hasErrored = true\n }\n }\n\n /**\n * when we have an error for onSubmit in the state, we want\n * to clear the error as soon as the user enters a valid value in the field\n */\n const submitErrKey = getErrorMapKey('submit')\n if (\n this.state.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n })\n\n return { hasErrored, fieldsErrorMap: currentValidationErrorMap }\n }\n\n /**\n * @private\n */\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<\n FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n > => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.baseStore.setState((prev) => ({ ...prev, isFormValidating: true }))\n }\n\n /**\n * We have to use a for loop and generate our promises this way, otherwise it won't be sync\n * when there are no validators needed to be run\n */\n const promises: Promise<ValidationPromiseResult<TFormData>>[] = []\n\n let fieldErrors:\n | Partial<Record<DeepKeys<TFormData>, ValidationError>>\n | undefined\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = this.state.validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.state.validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationPromiseResult<TFormData>>(async (resolve) => {\n let rawError!:\n | ValidationError\n | FormValidationError<unknown>\n | undefined\n try {\n rawError = await new Promise((rawResolve, rawReject) => {\n setTimeout(async () => {\n if (controller.signal.aborted) return rawResolve(undefined)\n try {\n rawResolve(\n await this.runValidator({\n validate: validateObj.validate!,\n value: {\n value: this.state.values,\n formApi: this,\n validationSource: 'form',\n signal: controller.signal,\n },\n type: 'validateAsync',\n }),\n )\n } catch (e) {\n rawReject(e)\n }\n }, validateObj.debounceMs)\n })\n } catch (e: unknown) {\n rawError = e as ValidationError\n }\n const { formError, fieldErrors: fieldErrorsFromNormalizeError } =\n normalizeError<TFormData>(rawError)\n\n if (fieldErrorsFromNormalizeError) {\n fieldErrors = fieldErrors\n ? { ...fieldErrors, ...fieldErrorsFromNormalizeError }\n : fieldErrorsFromNormalizeError\n }\n const errorMapKey = getErrorMapKey(validateObj.cause)\n\n if (fieldErrors) {\n for (const [field, fieldError] of Object.entries(fieldErrors)) {\n const fieldMeta = this.getFieldMeta(field as DeepKeys<TFormData>)\n if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {\n this.setFieldMeta(field as DeepKeys<TFormData>, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: fieldError,\n },\n }))\n }\n }\n }\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: formError,\n },\n }))\n\n resolve(fieldErrors ? { fieldErrors, errorMapKey } : undefined)\n }),\n )\n }\n\n let results: ValidationPromiseResult<TFormData>[] = []\n\n const fieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n if (promises.length) {\n results = await Promise.all(promises)\n for (const fieldValidationResult of results) {\n if (fieldValidationResult?.fieldErrors) {\n const { errorMapKey } = fieldValidationResult\n\n for (const [field, fieldError] of Object.entries(\n fieldValidationResult.fieldErrors,\n )) {\n const oldErrorMap =\n fieldsErrorMap[field as DeepKeys<TFormData>] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n fieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap\n }\n }\n }\n }\n\n this.baseStore.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return fieldsErrorMap\n }\n\n /**\n * @private\n */\n validate = (\n cause: ValidationCause,\n ):\n | FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n | Promise<\n FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n > => {\n // Attempt to sync validate first\n const { hasErrored, fieldsErrorMap } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return fieldsErrorMap\n }\n\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n this.baseStore.setState((old) => ({\n ...old,\n // Submission attempts mark the form as not submitted\n isSubmitted: false,\n // Count submission attempts\n submissionAttempts: old.submissionAttempts + 1,\n }))\n\n // Don't let invalid forms submit\n if (!this.state.canSubmit) return\n\n this.baseStore.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.baseStore.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n await this.validateAllFields('submit')\n\n if (!this.state.isFieldsValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n await this.validate('submit')\n\n // Fields are invalid, do not submit\n if (!this.state.isValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n batch(() => {\n void (Object.values(this.fieldInfo) as FieldInfo<TFormData>[]).forEach(\n (field) => {\n field.instance?.options.listeners?.onSubmit?.({\n value: field.instance.state.value,\n fieldApi: field.instance,\n })\n },\n )\n })\n\n try {\n // Run the submit code\n await this.options.onSubmit?.({\n value: this.state.values,\n formApi: this,\n meta: submitMeta ?? this.options.onSubmitMeta,\n } as any)\n\n batch(() => {\n this.baseStore.setState((prev) => ({ ...prev, isSubmitted: true }))\n done()\n })\n } catch (err) {\n done()\n throw err\n }\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): DeepValue<TFormData, TField> => getBy(this.state.values, field)\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): AnyFieldMeta | undefined => {\n return this.state.fieldMeta[field]\n }\n\n /**\n * Gets the field info of the specified field.\n */\n getFieldInfo = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldInfo<TFormData> => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (this.fieldInfo[field] ||= {\n instance: null,\n validationMetaMap: {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n })\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<AnyFieldMeta>,\n ) => {\n this.baseStore.setState((prev) => {\n return {\n ...prev,\n fieldMetaBase: {\n ...prev.fieldMetaBase,\n [field]: functionalUpdate(\n updater,\n prev.fieldMetaBase[field] as never,\n ),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, AnyFieldMeta>,\n ): Record<TField, AnyFieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, AnyFieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, AnyFieldMeta>,\n )\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<DeepValue<TFormData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n const dontUpdateMeta = opts?.dontUpdateMeta ?? false\n\n batch(() => {\n if (!dontUpdateMeta) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n onMount: undefined,\n },\n }))\n }\n\n this.baseStore.setState((prev) => {\n return {\n ...prev,\n values: setBy(prev.values, field, updater),\n }\n })\n })\n }\n\n deleteField = <TField extends DeepKeys<TFormData>>(field: TField) => {\n this.baseStore.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMetaBase[field]\n\n return newState\n })\n delete this.fieldInfo[field]\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,\n opts,\n )\n this.validateField(field, 'change')\n }\n\n insertFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return [\n ...(prev as DeepValue<TFormData, TField>[]).slice(0, index),\n value,\n ...(prev as DeepValue<TFormData, TField>[]).slice(index),\n ] as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n\n // Shift down all meta after validating to make sure the new field has been mounted\n metaHelper(this).handleArrayFieldMetaShift(field, index, 'insert')\n\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).map((d, i) =>\n i === index ? value : d,\n ) as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n const fieldValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(fieldValue)\n ? Math.max(fieldValue.length - 1, 0)\n : null\n\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).filter(\n (_d, i) => i !== index,\n ) as any\n },\n opts,\n )\n\n // Shift up all meta\n metaHelper(this).handleArrayFieldMetaShift(field, index, 'remove')\n\n if (lastIndex !== null) {\n const start = `${field}[${lastIndex}]`\n const fieldsToDelete = Object.keys(this.fieldInfo).filter((f) =>\n f.startsWith(start),\n )\n\n // Cleanup the last fields\n fieldsToDelete.forEach((f) => this.deleteField(f as TField))\n }\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev: any) => {\n const prev1 = prev[index1]!\n const prev2 = prev[index2]!\n return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1)\n },\n opts,\n )\n\n // Swap meta\n metaHelper(this).handleArrayFieldMetaShift(field, index1, 'swap', index2)\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the swapped fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev: any) => {\n prev.splice(index2, 0, prev.splice(index1, 1)[0])\n return prev\n },\n opts,\n )\n\n // Move meta between index1 and index2\n metaHelper(this).handleArrayFieldMetaShift(field, index1, 'move', index2)\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the moved fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n /**\n * Updates the form's errorMap\n */\n setErrorMap(\n errorMap: ValidationErrorMap<\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >,\n ) {\n this.baseStore.setState(\n (prev) =>\n ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n ...errorMap,\n },\n }) as never,\n )\n }\n\n /**\n * Returns form and field level errors\n */\n getAllErrors = (): {\n form: {\n errors: Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n errorMap: FormValidationErrorMap<\n UnwrapFormValidateOrFn<TOnMount>,\n UnwrapFormValidateOrFn<TOnChange>,\n UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,\n UnwrapFormValidateOrFn<TOnBlur>,\n UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,\n UnwrapFormValidateOrFn<TOnSubmit>,\n UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,\n UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n }\n fields: Record<\n DeepKeys<TFormData>,\n { errors: ValidationError[]; errorMap: ValidationErrorMap }\n >\n } => {\n return {\n form: {\n errors: this.state.errors,\n errorMap: this.state.errorMap,\n },\n fields: Object.entries(this.state.fieldMeta).reduce(\n (acc, [fieldName, fieldMeta]) => {\n if (\n Object.keys(fieldMeta as AnyFieldMeta).length &&\n (fieldMeta as AnyFieldMeta).errors.length\n ) {\n acc[fieldName as DeepKeys<TFormData>] = {\n errors: (fieldMeta as AnyFieldMeta).errors,\n errorMap: (fieldMeta as AnyFieldMeta).errorMap,\n }\n }\n\n return acc\n },\n {} as Record<\n DeepKeys<TFormData>,\n { errors: ValidationError[]; errorMap: ValidationErrorMap }\n >,\n ),\n }\n }\n}\n\nfunction normalizeError<TFormData>(rawError?: FormValidationError<unknown>): {\n formError: ValidationError\n fieldErrors?: Partial<Record<DeepKeys<TFormData>, ValidationError>>\n} {\n if (rawError) {\n if (isGlobalFormValidationError(rawError)) {\n const formError = normalizeError(rawError.form).formError\n const fieldErrors = rawError.fields\n return { formError, fieldErrors } as never\n }\n\n return { formError: rawError }\n }\n\n return { formError: undefined }\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n case 'server':\n return 'onServer'\n case 'change':\n default:\n return 'onChange'\n }\n}\n"],"names":["_a","opts","_c","_b"],"mappings":"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"}
1
+ {"version":3,"file":"FormApi.js","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Derived, Store, batch } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isGlobalFormValidationError,\n isNonEmptyArray,\n setBy,\n shallow,\n} from './utils'\nimport {\n isStandardSchemaValidator,\n standardSchemaValidators,\n} from './standardSchemaValidator'\nimport { metaHelper } from './metaHelper'\nimport type {\n StandardSchemaV1,\n StandardSchemaV1Issue,\n TStandardSchemaValidatorValue,\n} from './standardSchemaValidator'\nimport type { AnyFieldMeta, AnyFieldMetaBase, FieldApi } from './FieldApi'\nimport type {\n FormValidationError,\n FormValidationErrorMap,\n UpdateMetaOptions,\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n} from './types'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { Updater } from './utils'\n\n/**\n * @private\n */\n// TODO: Add the `Unwrap` type to the errors\ntype FormErrorMapFromValidator<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = Partial<\n Record<\n DeepKeys<TFormData>,\n ValidationErrorMap<\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n >\n>\n\nexport type FormValidateFn<TFormData> = (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n // This is technically an edge-type; which we try to keep non-`any`, but in this case\n // It's referring to an inaccessible type from the field validate function inner types, so it's not a big deal\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n}) => unknown\n\n/**\n * @private\n */\nexport type FormValidateOrFn<TFormData> =\n | FormValidateFn<TFormData>\n | StandardSchemaV1<TFormData, unknown>\n\nexport type UnwrapFormValidateOrFn<\n TValidateOrFn extends undefined | FormValidateOrFn<any>,\n> = [TValidateOrFn] extends [FormValidateFn<any>]\n ? ReturnType<TValidateOrFn>\n : [TValidateOrFn] extends [StandardSchemaV1<any, any>]\n ? Record<string, StandardSchemaV1Issue[]>\n : undefined\n\n/**\n * @private\n */\nexport type FormValidateAsyncFn<TFormData> = (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n // This is technically an edge-type; which we try to keep non-`any`, but in this case\n // It's referring to an inaccessible type from the field validate function inner types, so it's not a big deal\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n signal: AbortSignal\n}) => unknown | Promise<unknown>\n\nexport type FormValidator<TFormData, TType, TFn = unknown> = {\n validate(options: { value: TType }, fn: TFn): ValidationError\n validateAsync(\n options: { value: TType },\n fn: TFn,\n ): Promise<FormValidationError<TFormData>>\n}\n\ntype ValidationPromiseResult<TFormData> =\n | {\n fieldErrors: Partial<Record<DeepKeys<TFormData>, ValidationError>>\n errorMapKey: ValidationErrorMapKeys\n }\n | undefined\n\n/**\n * @private\n */\nexport type FormAsyncValidateOrFn<TFormData> =\n | FormValidateAsyncFn<TFormData>\n | StandardSchemaV1<TFormData, unknown>\n\nexport type UnwrapFormAsyncValidateOrFn<\n TValidateOrFn extends undefined | FormAsyncValidateOrFn<any>,\n> = [TValidateOrFn] extends [FormValidateAsyncFn<any>]\n ? Awaited<ReturnType<TValidateOrFn>>\n : [TValidateOrFn] extends [StandardSchemaV1<any, any>]\n ? Record<string, StandardSchemaV1Issue[]>\n : undefined\n\nexport interface FormValidators<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n> {\n /**\n * Optional function that fires as soon as the component mounts.\n */\n onMount?: TOnMount\n /**\n * Optional function that checks the validity of your data whenever a value changes\n */\n onChange?: TOnChange\n /**\n * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.\n */\n onChangeAsync?: TOnChangeAsync\n /**\n * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.\n */\n onChangeAsyncDebounceMs?: number\n /**\n * Optional function that validates the form data when a field loses focus, returns a `FormValidationError`\n */\n onBlur?: TOnBlur\n /**\n * Optional onBlur asynchronous validation method for when a field loses focus returns a ` FormValidationError` or a promise of `Promise<FormValidationError>`\n */\n onBlurAsync?: TOnBlurAsync\n /**\n * The default time in milliseconds that if set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds.\n */\n onBlurAsyncDebounceMs?: number\n onSubmit?: TOnSubmit\n onSubmitAsync?: TOnSubmitAsync\n}\n\n/**\n * @private\n */\nexport interface FormTransform<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n fn: (\n formBase: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) => FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n deps: unknown[]\n}\n\n/**\n * An object representing the options for a form.\n */\nexport interface FormOptions<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n /**\n * Set initial values for your form.\n */\n defaultValues?: TFormData\n /**\n * The default state for the form.\n */\n defaultState?: Partial<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n /**\n * If true, always run async validation, even when sync validation has produced an error. Defaults to undefined.\n */\n asyncAlways?: boolean\n /**\n * Optional time in milliseconds if you want to introduce a delay before firing off an async action.\n */\n asyncDebounceMs?: number\n /**\n * A list of validators to pass to the form\n */\n validators?: FormValidators<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n\n /**\n * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props\n */\n onSubmitMeta?: TSubmitMeta\n\n /**\n * A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise<any>`\n */\n onSubmit?: (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n meta: TSubmitMeta\n }) => any | Promise<any>\n /**\n * Specify an action for scenarios where the user tries to submit an invalid form.\n */\n onSubmitInvalid?: (props: {\n value: TFormData\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n }) => void\n transform?: FormTransform<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >\n}\n\n/**\n * An object representing the validation metadata for a field. Not intended for public usage.\n */\nexport type ValidationMeta = {\n /**\n * An abort controller stored in memory to cancel previous async validation attempts.\n */\n lastAbortController: AbortController\n}\n\n/**\n * An object representing the field information for a specific field within the form.\n */\nexport type FieldInfo<TFormData> = {\n /**\n * An instance of the FieldAPI.\n */\n instance: FieldApi<\n TFormData,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > | null\n /**\n * A record of field validation internal handling.\n */\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n}\n\n/**\n * An object representing the current state of the form.\n */\nexport type BaseFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = {\n /**\n * The current values of the form fields.\n */\n values: TFormData\n /**\n * The error map for the form itself.\n */\n errorMap: FormValidationErrorMap<\n UnwrapFormValidateOrFn<TOnMount>,\n UnwrapFormValidateOrFn<TOnChange>,\n UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,\n UnwrapFormValidateOrFn<TOnBlur>,\n UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,\n UnwrapFormValidateOrFn<TOnSubmit>,\n UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,\n UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n /**\n * An internal mechanism used for keeping track of validation logic in a form.\n */\n validationMetaMap: Record<ValidationErrorMapKeys, ValidationMeta | undefined>\n /**\n * A record of field metadata for each field in the form, not including the derived properties, like `errors` and such\n */\n fieldMetaBase: Record<DeepKeys<TFormData>, AnyFieldMetaBase>\n /**\n * A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called.\n *\n * Goes back to `false` when submission completes for one of the following reasons:\n * - the validation step returned errors.\n * - the `onSubmit` function has completed.\n *\n * Note: if you're running async operations in your `onSubmit` function make sure to await them to ensure `isSubmitting` is set to `false` only when the async operation completes.\n *\n * This is useful for displaying loading indicators or disabling form inputs during submission.\n *\n */\n isSubmitting: boolean\n /**\n * A boolean indicating if the form has been submitted.\n */\n isSubmitted: boolean\n /**\n * A boolean indicating if the form or any of its fields are currently validating.\n */\n isValidating: boolean\n /**\n * A counter for tracking the number of submission attempts.\n */\n submissionAttempts: number\n /**\n * A boolean indicating if the last submission was successful.\n */\n isSubmitSuccessful: boolean\n /**\n * @private, used to force a re-evaluation of the form state when options change\n */\n _force_re_eval?: boolean\n}\n\nexport type DerivedFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = {\n /**\n * A boolean indicating if the form is currently validating.\n */\n isFormValidating: boolean\n /**\n * A boolean indicating if the form is valid.\n */\n isFormValid: boolean\n /**\n * The error array for the form itself.\n */\n errors: Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n /**\n * A boolean indicating if any of the form fields are currently validating.\n */\n isFieldsValidating: boolean\n /**\n * A boolean indicating if all the form fields are valid.\n */\n isFieldsValid: boolean\n /**\n * A boolean indicating if any of the form fields have been touched.\n */\n isTouched: boolean\n /**\n * A boolean indicating if any of the form fields have been blurred.\n */\n isBlurred: boolean\n /**\n * A boolean indicating if any of the form's fields' values have been modified by the user. `True` if the user have modified at least one of the fields. Opposite of `isPristine`.\n */\n isDirty: boolean\n /**\n * A boolean indicating if none of the form's fields' values have been modified by the user. `True` if the user have not modified any of the fields. Opposite of `isDirty`.\n */\n isPristine: boolean\n /**\n * A boolean indicating if the form and all its fields are valid.\n */\n isValid: boolean\n /**\n * A boolean indicating if the form can be submitted based on its current state.\n */\n canSubmit: boolean\n /**\n * A record of field metadata for each field in the form.\n */\n fieldMeta: Record<DeepKeys<TFormData>, AnyFieldMeta>\n}\n\nexport type FormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n> = BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n> &\n DerivedFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n\nexport type AnyFormState = FormState<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nfunction getDefaultFormState<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n>(\n defaultState: Partial<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >,\n): BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n> {\n return {\n values: defaultState.values ?? ({} as never),\n errorMap: defaultState.errorMap ?? {},\n fieldMetaBase: defaultState.fieldMetaBase ?? ({} as never),\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isValidating: defaultState.isValidating ?? false,\n submissionAttempts: defaultState.submissionAttempts ?? 0,\n isSubmitSuccessful: defaultState.isSubmitSuccessful ?? false,\n validationMetaMap: defaultState.validationMetaMap ?? {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n }\n}\n\n/**\n * @public\n *\n * A type representing the Form API with all generics set to `any` for convenience.\n */\nexport type AnyFormApi = FormApi<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\n/**\n * A class representing the Form API. It handles the logic and interactions with the form state.\n *\n * Normally, you will not need to create a new `FormApi` instance directly. Instead, you will use a framework\n * hook/function like `useForm` or `createForm` to create a new instance for you that uses your framework's reactivity model.\n * However, if you need to create a new instance manually, you can do so by calling the `new FormApi` constructor.\n */\nexport class FormApi<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n> {\n /**\n * The options for the form.\n */\n options: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n > = {}\n baseStore!: Store<\n BaseFormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n fieldMetaDerived!: Derived<Record<DeepKeys<TFormData>, AnyFieldMeta>>\n store!: Derived<\n FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n >\n /**\n * A record of field information for each field in the form.\n */\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData>> = {} as any\n\n get state() {\n return this.store.state\n }\n\n /**\n * @private\n */\n prevTransformArray: unknown[] = []\n\n /**\n * @private Persistent store of all field validation errors originating from form-level validators.\n * Maintains the cumulative state across validation cycles, including cleared errors (undefined values).\n * This map preserves the complete validation state for all fields.\n */\n cumulativeFieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n\n /**\n * Constructs a new `FormApi` instance with the given form options.\n */\n constructor(\n opts?: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) {\n this.baseStore = new Store(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n )\n\n this.fieldMetaDerived = new Derived({\n deps: [this.baseStore],\n fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {\n const prevVal = _prevVal as\n | Record<DeepKeys<TFormData>, AnyFieldMeta>\n | undefined\n const prevBaseStore = prevDepVals?.[0]\n const currBaseStore = currDepVals[0]\n\n let originalMetaCount = 0\n\n const fieldMeta = {} as FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >['fieldMeta']\n\n for (const fieldName of Object.keys(\n currBaseStore.fieldMetaBase,\n ) as Array<keyof typeof currBaseStore.fieldMetaBase>) {\n const currBaseVal = currBaseStore.fieldMetaBase[\n fieldName as never\n ] as AnyFieldMetaBase\n\n const prevBaseVal = prevBaseStore?.fieldMetaBase[\n fieldName as never\n ] as AnyFieldMetaBase | undefined\n\n const prevFieldInfo =\n prevVal?.[fieldName as never as keyof typeof prevVal]\n\n let fieldErrors = prevFieldInfo?.errors\n if (!prevBaseVal || currBaseVal.errorMap !== prevBaseVal.errorMap) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n fieldErrors = Object.values(currBaseVal.errorMap ?? {}).filter(\n (val) => val !== undefined,\n ) as never\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.getFieldInfo(fieldName)?.instance\n\n if (fieldInstance && !fieldInstance.options.disableErrorFlat) {\n fieldErrors = (fieldErrors as undefined | string[])?.flat(\n 1,\n ) as never\n }\n }\n\n // As a primitive, we don't need to aggressively persist the same referential value for performance reasons\n const isFieldPristine = !currBaseVal.isDirty\n\n if (\n prevFieldInfo &&\n prevFieldInfo.isPristine === isFieldPristine &&\n prevFieldInfo.errors === fieldErrors &&\n currBaseVal === prevBaseVal\n ) {\n fieldMeta[fieldName] = prevFieldInfo\n originalMetaCount++\n continue\n }\n\n fieldMeta[fieldName] = {\n ...currBaseVal,\n errors: fieldErrors,\n isPristine: isFieldPristine,\n } as AnyFieldMeta\n }\n\n if (\n prevVal &&\n originalMetaCount === Object.keys(currBaseStore.fieldMetaBase).length\n ) {\n return prevVal\n }\n\n return fieldMeta\n },\n })\n\n this.store = new Derived({\n deps: [this.baseStore, this.fieldMetaDerived],\n fn: ({ prevDepVals, currDepVals, prevVal: _prevVal }) => {\n const prevVal = _prevVal as\n | FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n | undefined\n const prevBaseStore = prevDepVals?.[0]\n const currBaseStore = currDepVals[0]\n\n // Computed state\n const fieldMetaValues = Object.values(currBaseStore.fieldMetaBase) as (\n | AnyFieldMeta\n | undefined\n )[]\n\n const isFieldsValidating = fieldMetaValues.some(\n (field) => field?.isValidating,\n )\n\n const isFieldsValid = !fieldMetaValues.some(\n (field) =>\n field?.errorMap &&\n isNonEmptyArray(Object.values(field.errorMap).filter(Boolean)),\n )\n\n const isTouched = fieldMetaValues.some((field) => field?.isTouched)\n const isBlurred = fieldMetaValues.some((field) => field?.isBlurred)\n\n const shouldInvalidateOnMount =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n isTouched && currBaseStore?.errorMap?.onMount\n\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const hasOnMountError = Boolean(\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n currBaseStore.errorMap?.onMount ||\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n fieldMetaValues.some((f) => f?.errorMap?.onMount),\n )\n\n const isValidating = !!isFieldsValidating\n\n // As `errors` is not a primitive, we need to aggressively persist the same referencial value for performance reasons\n let errors = prevVal?.errors ?? []\n if (\n !prevBaseStore ||\n currBaseStore.errorMap !== prevBaseStore.errorMap\n ) {\n errors = Object.values(currBaseStore.errorMap).reduce<\n Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n >((prev, curr) => {\n if (curr === undefined) return prev\n\n if (curr && isGlobalFormValidationError(curr)) {\n prev.push(curr.form as never)\n return prev\n }\n prev.push(curr as never)\n return prev\n }, [])\n }\n\n const isFormValid = errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (currBaseStore.submissionAttempts === 0 &&\n !isTouched &&\n !hasOnMountError) ||\n (!isValidating && !currBaseStore.isSubmitting && isValid)\n\n let errorMap = currBaseStore.errorMap\n if (shouldInvalidateOnMount) {\n errors = errors.filter(\n (err) => err !== currBaseStore.errorMap.onMount,\n )\n errorMap = Object.assign(errorMap, { onMount: undefined })\n }\n\n if (\n prevVal &&\n prevBaseStore &&\n prevVal.errorMap === errorMap &&\n prevVal.fieldMeta === this.fieldMetaDerived.state &&\n prevVal.errors === errors &&\n prevVal.isFieldsValidating === isFieldsValidating &&\n prevVal.isFieldsValid === isFieldsValid &&\n prevVal.isFormValid === isFormValid &&\n prevVal.isValid === isValid &&\n prevVal.canSubmit === canSubmit &&\n prevVal.isTouched === isTouched &&\n prevVal.isBlurred === isBlurred &&\n prevVal.isPristine === isPristine &&\n prevVal.isDirty === isDirty &&\n shallow(prevBaseStore, currBaseStore)\n ) {\n return prevVal\n }\n\n let state = {\n ...currBaseStore,\n errorMap,\n fieldMeta: this.fieldMetaDerived.state,\n errors,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isBlurred,\n isPristine,\n isDirty,\n } as FormState<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer\n >\n\n // Only run transform if state has shallowly changed - IE how React.useEffect works\n const transformArray = this.options.transform?.deps ?? []\n const shouldTransform =\n transformArray.length !== this.prevTransformArray.length ||\n transformArray.some((val, i) => val !== this.prevTransformArray[i])\n\n if (shouldTransform) {\n const newObj = Object.assign({}, this, { state })\n // This mutates the state\n this.options.transform?.fn(newObj)\n state = newObj.state\n this.prevTransformArray = transformArray\n }\n\n return state\n },\n })\n\n this.handleSubmit = this.handleSubmit.bind(this)\n\n this.update(opts || {})\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends TStandardSchemaValidatorValue<TFormData> & {\n formApi: AnyFormApi\n },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData>\n : FormAsyncValidateOrFn<TFormData>\n value: TValue\n type: TType\n }): unknown {\n if (isStandardSchemaValidator(props.validate)) {\n return standardSchemaValidators[props.type](\n props.value,\n props.validate,\n ) as never\n }\n\n return (props.validate as FormValidateFn<any>)(props.value) as never\n }\n\n mount = () => {\n const cleanupFieldMetaDerived = this.fieldMetaDerived.mount()\n const cleanupStoreDerived = this.store.mount()\n const cleanup = () => {\n cleanupFieldMetaDerived()\n cleanupStoreDerived()\n }\n const { onMount } = this.options.validators || {}\n if (!onMount) return cleanup\n this.validateSync('mount')\n\n return cleanup\n }\n\n /**\n * Updates the form options and form state.\n */\n update = (\n options?: FormOptions<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnServer,\n TSubmitMeta\n >,\n ) => {\n if (!options) return\n\n const oldOptions = this.options\n\n // Options need to be updated first so that when the store is updated, the state is correct for the derived state\n this.options = options\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const shouldUpdateReeval = !!options.transform?.deps?.some(\n (val, i) => val !== this.prevTransformArray[i],\n )\n\n const shouldUpdateValues =\n options.defaultValues &&\n !shallow(options.defaultValues, oldOptions.defaultValues) &&\n !this.state.isTouched\n\n const shouldUpdateState =\n !shallow(options.defaultState, oldOptions.defaultState) &&\n !this.state.isTouched\n\n if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return\n\n batch(() => {\n this.baseStore.setState(() =>\n getDefaultFormState(\n Object.assign(\n {},\n this.state as any,\n\n shouldUpdateState ? options.defaultState : {},\n\n shouldUpdateValues\n ? {\n values: options.defaultValues,\n }\n : {},\n\n shouldUpdateReeval\n ? { _force_re_eval: !this.state._force_re_eval }\n : {},\n ),\n ),\n )\n })\n }\n\n /**\n * Resets the form state to the default values.\n * If values are provided, the form will be reset to those values instead and the default values will be updated.\n *\n * @param values - Optional values to reset the form to.\n * @param opts - Optional options to control the reset behavior.\n */\n reset = (values?: TFormData, opts?: { keepDefaultValues?: boolean }) => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMetaBase = this.resetFieldMeta(currentFieldMeta)\n\n if (values && !opts?.keepDefaultValues) {\n this.options = {\n ...this.options,\n defaultValues: values,\n }\n }\n\n this.baseStore.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values:\n values ??\n this.options.defaultValues ??\n this.options.defaultState?.values,\n fieldMetaBase,\n }),\n )\n }\n\n /**\n * Validates all fields using the correct handlers for a given validation cause.\n */\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n batch(() => {\n void (Object.values(this.fieldInfo) as FieldInfo<any>[]).forEach(\n (field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n // Remember, `validate` is either a sync operation or a promise\n Promise.resolve().then(() =>\n fieldInstance.validate(cause, { skipFormValidation: true }),\n ),\n )\n // If any fields are not touched\n if (!field.instance.state.meta.isTouched) {\n // Mark them as touched\n field.instance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n },\n )\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n /**\n * Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.\n */\n validateArrayFieldsStartingFrom = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n cause: ValidationCause,\n ) => {\n const currentValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(currentValue)\n ? Math.max(currentValue.length - 1, 0)\n : null\n\n // We have to validate all fields that have shifted (at least the current field)\n const fieldKeysToValidate = [`${field}[${index}]`]\n for (let i = index + 1; i <= (lastIndex ?? 0); i++) {\n fieldKeysToValidate.push(`${field}[${i}]`)\n }\n\n // We also have to include all fields that are nested in the shifted fields\n const fieldsToValidate = Object.keys(this.fieldInfo).filter((fieldKey) =>\n fieldKeysToValidate.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n\n // Validate the fields\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n batch(() => {\n fieldsToValidate.forEach((nestedField) => {\n fieldValidationPromises.push(\n Promise.resolve().then(() => this.validateField(nestedField, cause)),\n )\n })\n })\n\n const fieldErrorMapMap = await Promise.all(fieldValidationPromises)\n return fieldErrorMapMap.flat()\n }\n\n /**\n * Validates a specified field in the form using the correct handlers for a given validation type.\n */\n validateField = <TField extends DeepKeys<TFormData>>(\n field: TField,\n cause: ValidationCause,\n ) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldInstance = this.fieldInfo[field]?.instance\n if (!fieldInstance) return []\n\n // If the field is not touched (same logic as in validateAllFields)\n if (!fieldInstance.state.meta.isTouched) {\n // Mark it as touched\n fieldInstance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n\n return fieldInstance.validate(cause)\n }\n\n /**\n * TODO: This code is copied from FieldApi, we should refactor to share\n * @private\n */\n validateSync = (\n cause: ValidationCause,\n ): {\n hasErrored: boolean\n fieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n } => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n // This map will only include fields that have errors in the current validation cycle\n const currentValidationErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n\n batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const rawError = this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n validationSource: 'form',\n },\n type: 'validate',\n })\n\n const { formError, fieldErrors } = normalizeError<TFormData>(rawError)\n\n const errorMapKey = getErrorMapKey(validateObj.cause)\n\n if (fieldErrors) {\n for (const [field, fieldError] of Object.entries(fieldErrors) as [\n DeepKeys<TFormData>,\n ValidationError,\n ][]) {\n const oldErrorMap = this.cumulativeFieldsErrorMap[field] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n currentValidationErrorMap[field] = newErrorMap\n this.cumulativeFieldsErrorMap[field] = newErrorMap\n\n const fieldMeta = this.getFieldMeta(field)\n if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: fieldError,\n },\n }))\n }\n }\n }\n\n for (const field of Object.keys(this.cumulativeFieldsErrorMap) as Array<\n DeepKeys<TFormData>\n >) {\n const fieldMeta = this.getFieldMeta(field)\n if (\n fieldMeta?.errorMap[errorMapKey] &&\n !currentValidationErrorMap[field]?.[errorMapKey]\n ) {\n this.cumulativeFieldsErrorMap[field] = {\n ...this.cumulativeFieldsErrorMap[field],\n [errorMapKey]: undefined,\n }\n\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: undefined,\n },\n }))\n }\n }\n\n if (this.state.errorMap[errorMapKey] !== formError) {\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: formError,\n },\n }))\n }\n\n if (formError || fieldErrors) {\n hasErrored = true\n }\n }\n\n /**\n * when we have an error for onSubmit in the state, we want\n * to clear the error as soon as the user enters a valid value in the field\n */\n const submitErrKey = getErrorMapKey('submit')\n if (\n this.state.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n })\n\n return { hasErrored, fieldsErrorMap: currentValidationErrorMap }\n }\n\n /**\n * @private\n */\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<\n FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n > => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.baseStore.setState((prev) => ({ ...prev, isFormValidating: true }))\n }\n\n /**\n * We have to use a for loop and generate our promises this way, otherwise it won't be sync\n * when there are no validators needed to be run\n */\n const promises: Promise<ValidationPromiseResult<TFormData>>[] = []\n\n let fieldErrors:\n | Partial<Record<DeepKeys<TFormData>, ValidationError>>\n | undefined\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = this.state.validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.state.validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationPromiseResult<TFormData>>(async (resolve) => {\n let rawError!:\n | ValidationError\n | FormValidationError<unknown>\n | undefined\n try {\n rawError = await new Promise((rawResolve, rawReject) => {\n setTimeout(async () => {\n if (controller.signal.aborted) return rawResolve(undefined)\n try {\n rawResolve(\n await this.runValidator({\n validate: validateObj.validate!,\n value: {\n value: this.state.values,\n formApi: this,\n validationSource: 'form',\n signal: controller.signal,\n },\n type: 'validateAsync',\n }),\n )\n } catch (e) {\n rawReject(e)\n }\n }, validateObj.debounceMs)\n })\n } catch (e: unknown) {\n rawError = e as ValidationError\n }\n const { formError, fieldErrors: fieldErrorsFromNormalizeError } =\n normalizeError<TFormData>(rawError)\n\n if (fieldErrorsFromNormalizeError) {\n fieldErrors = fieldErrors\n ? { ...fieldErrors, ...fieldErrorsFromNormalizeError }\n : fieldErrorsFromNormalizeError\n }\n const errorMapKey = getErrorMapKey(validateObj.cause)\n\n if (fieldErrors) {\n for (const [field, fieldError] of Object.entries(fieldErrors)) {\n const fieldMeta = this.getFieldMeta(field as DeepKeys<TFormData>)\n if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {\n this.setFieldMeta(field as DeepKeys<TFormData>, (prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: fieldError,\n },\n }))\n }\n }\n }\n this.baseStore.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: formError,\n },\n }))\n\n resolve(fieldErrors ? { fieldErrors, errorMapKey } : undefined)\n }),\n )\n }\n\n let results: ValidationPromiseResult<TFormData>[] = []\n\n const fieldsErrorMap: FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n > = {}\n if (promises.length) {\n results = await Promise.all(promises)\n for (const fieldValidationResult of results) {\n if (fieldValidationResult?.fieldErrors) {\n const { errorMapKey } = fieldValidationResult\n\n for (const [field, fieldError] of Object.entries(\n fieldValidationResult.fieldErrors,\n )) {\n const oldErrorMap =\n fieldsErrorMap[field as DeepKeys<TFormData>] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n fieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap\n }\n }\n }\n }\n\n this.baseStore.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return fieldsErrorMap\n }\n\n /**\n * @private\n */\n validate = (\n cause: ValidationCause,\n ):\n | FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n | Promise<\n FormErrorMapFromValidator<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >\n > => {\n // Attempt to sync validate first\n const { hasErrored, fieldsErrorMap } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return fieldsErrorMap\n }\n\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n /**\n * Handles the form submission, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.\n */\n handleSubmit(): Promise<void>\n handleSubmit(submitMeta: TSubmitMeta): Promise<void>\n async handleSubmit(submitMeta?: TSubmitMeta): Promise<void> {\n this.baseStore.setState((old) => ({\n ...old,\n // Submission attempts mark the form as not submitted\n isSubmitted: false,\n // Count submission attempts\n submissionAttempts: old.submissionAttempts + 1,\n isSubmitSuccessful: false, // Reset isSubmitSuccessful at the start of submission\n }))\n\n // Don't let invalid forms submit\n if (!this.state.canSubmit) return\n\n this.baseStore.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.baseStore.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n await this.validateAllFields('submit')\n\n if (!this.state.isFieldsValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n await this.validate('submit')\n\n // Fields are invalid, do not submit\n if (!this.state.isValid) {\n done()\n this.options.onSubmitInvalid?.({\n value: this.state.values,\n formApi: this,\n })\n return\n }\n\n batch(() => {\n void (Object.values(this.fieldInfo) as FieldInfo<TFormData>[]).forEach(\n (field) => {\n field.instance?.options.listeners?.onSubmit?.({\n value: field.instance.state.value,\n fieldApi: field.instance,\n })\n },\n )\n })\n\n try {\n // Run the submit code\n await this.options.onSubmit?.({\n value: this.state.values,\n formApi: this,\n meta: submitMeta ?? this.options.onSubmitMeta,\n } as any)\n\n batch(() => {\n this.baseStore.setState((prev) => ({\n ...prev,\n isSubmitted: true,\n isSubmitSuccessful: true, // Set isSubmitSuccessful to true on successful submission\n }))\n done()\n })\n } catch (err) {\n this.baseStore.setState((prev) => ({\n ...prev,\n isSubmitSuccessful: false, // Ensure isSubmitSuccessful is false if an error occurs\n }))\n done()\n throw err\n }\n }\n\n /**\n * Gets the value of the specified field.\n */\n getFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): DeepValue<TFormData, TField> => getBy(this.state.values, field)\n\n /**\n * Gets the metadata of the specified field.\n */\n getFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): AnyFieldMeta | undefined => {\n return this.state.fieldMeta[field]\n }\n\n /**\n * Gets the field info of the specified field.\n */\n getFieldInfo = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldInfo<TFormData> => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (this.fieldInfo[field] ||= {\n instance: null,\n validationMetaMap: {\n onChange: undefined,\n onBlur: undefined,\n onSubmit: undefined,\n onMount: undefined,\n onServer: undefined,\n },\n })\n }\n\n /**\n * Updates the metadata of the specified field.\n */\n setFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<AnyFieldMeta>,\n ) => {\n this.baseStore.setState((prev) => {\n return {\n ...prev,\n fieldMetaBase: {\n ...prev.fieldMetaBase,\n [field]: functionalUpdate(\n updater,\n prev.fieldMetaBase[field] as never,\n ),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, AnyFieldMeta>,\n ): Record<TField, AnyFieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, AnyFieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, AnyFieldMeta>,\n )\n }\n\n /**\n * Sets the value of the specified field and optionally updates the touched state.\n */\n setFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<DeepValue<TFormData, TField>>,\n opts?: UpdateMetaOptions,\n ) => {\n const dontUpdateMeta = opts?.dontUpdateMeta ?? false\n\n batch(() => {\n if (!dontUpdateMeta) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n onMount: undefined,\n },\n }))\n }\n\n this.baseStore.setState((prev) => {\n return {\n ...prev,\n values: setBy(prev.values, field, updater),\n }\n })\n })\n }\n\n deleteField = <TField extends DeepKeys<TFormData>>(field: TField) => {\n this.baseStore.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMetaBase[field]\n\n return newState\n })\n delete this.fieldInfo[field]\n }\n\n /**\n * Pushes a value into an array field.\n */\n pushFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,\n opts,\n )\n this.validateField(field, 'change')\n }\n\n insertFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return [\n ...(prev as DeepValue<TFormData, TField>[]).slice(0, index),\n value,\n ...(prev as DeepValue<TFormData, TField>[]).slice(index),\n ] as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n\n // Shift down all meta after validating to make sure the new field has been mounted\n metaHelper(this).handleArrayFieldMetaShift(field, index, 'insert')\n\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Replaces a value into an array field at the specified index.\n */\n replaceFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).map((d, i) =>\n i === index ? value : d,\n ) as any\n },\n opts,\n )\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Removes a value from an array field at the specified index.\n */\n removeFieldValue = async <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n opts?: UpdateMetaOptions,\n ) => {\n const fieldValue = this.getFieldValue(field)\n\n const lastIndex = Array.isArray(fieldValue)\n ? Math.max(fieldValue.length - 1, 0)\n : null\n\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).filter(\n (_d, i) => i !== index,\n ) as any\n },\n opts,\n )\n\n // Shift up all meta\n metaHelper(this).handleArrayFieldMetaShift(field, index, 'remove')\n\n if (lastIndex !== null) {\n const start = `${field}[${lastIndex}]`\n const fieldsToDelete = Object.keys(this.fieldInfo).filter((f) =>\n f.startsWith(start),\n )\n\n // Cleanup the last fields\n fieldsToDelete.forEach((f) => this.deleteField(f as TField))\n }\n\n // Validate the whole array + all fields that have shifted\n await this.validateField(field, 'change')\n await this.validateArrayFieldsStartingFrom(field, index, 'change')\n }\n\n /**\n * Swaps the values at the specified indices within an array field.\n */\n swapFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev: any) => {\n const prev1 = prev[index1]!\n const prev2 = prev[index2]!\n return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1)\n },\n opts,\n )\n\n // Swap meta\n metaHelper(this).handleArrayFieldMetaShift(field, index1, 'swap', index2)\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the swapped fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n\n /**\n * Moves the value at the first specified index to the second specified index within an array field.\n */\n moveFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n opts?: UpdateMetaOptions,\n ) => {\n this.setFieldValue(\n field,\n (prev: any) => {\n prev.splice(index2, 0, prev.splice(index1, 1)[0])\n return prev\n },\n opts,\n )\n\n // Move meta between index1 and index2\n metaHelper(this).handleArrayFieldMetaShift(field, index1, 'move', index2)\n\n // Validate the whole array\n this.validateField(field, 'change')\n // Validate the moved fields\n this.validateField(`${field}[${index1}]` as DeepKeys<TFormData>, 'change')\n this.validateField(`${field}[${index2}]` as DeepKeys<TFormData>, 'change')\n }\n /**\n * Updates the form's errorMap\n */\n setErrorMap(\n errorMap: ValidationErrorMap<\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync\n >,\n ) {\n this.baseStore.setState(\n (prev) =>\n ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n ...errorMap,\n },\n }) as never,\n )\n }\n\n /**\n * Returns form and field level errors\n */\n getAllErrors = (): {\n form: {\n errors: Array<\n | UnwrapFormValidateOrFn<TOnMount>\n | UnwrapFormValidateOrFn<TOnChange>\n | UnwrapFormAsyncValidateOrFn<TOnChangeAsync>\n | UnwrapFormValidateOrFn<TOnBlur>\n | UnwrapFormAsyncValidateOrFn<TOnBlurAsync>\n | UnwrapFormValidateOrFn<TOnSubmit>\n | UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>\n | UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n errorMap: FormValidationErrorMap<\n UnwrapFormValidateOrFn<TOnMount>,\n UnwrapFormValidateOrFn<TOnChange>,\n UnwrapFormAsyncValidateOrFn<TOnChangeAsync>,\n UnwrapFormValidateOrFn<TOnBlur>,\n UnwrapFormAsyncValidateOrFn<TOnBlurAsync>,\n UnwrapFormValidateOrFn<TOnSubmit>,\n UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>,\n UnwrapFormAsyncValidateOrFn<TOnServer>\n >\n }\n fields: Record<\n DeepKeys<TFormData>,\n { errors: ValidationError[]; errorMap: ValidationErrorMap }\n >\n } => {\n return {\n form: {\n errors: this.state.errors,\n errorMap: this.state.errorMap,\n },\n fields: Object.entries(this.state.fieldMeta).reduce(\n (acc, [fieldName, fieldMeta]) => {\n if (\n Object.keys(fieldMeta as AnyFieldMeta).length &&\n (fieldMeta as AnyFieldMeta).errors.length\n ) {\n acc[fieldName as DeepKeys<TFormData>] = {\n errors: (fieldMeta as AnyFieldMeta).errors,\n errorMap: (fieldMeta as AnyFieldMeta).errorMap,\n }\n }\n\n return acc\n },\n {} as Record<\n DeepKeys<TFormData>,\n { errors: ValidationError[]; errorMap: ValidationErrorMap }\n >,\n ),\n }\n }\n}\n\nfunction normalizeError<TFormData>(rawError?: FormValidationError<unknown>): {\n formError: ValidationError\n fieldErrors?: Partial<Record<DeepKeys<TFormData>, ValidationError>>\n} {\n if (rawError) {\n if (isGlobalFormValidationError(rawError)) {\n const formError = normalizeError(rawError.form).formError\n const fieldErrors = rawError.fields\n return { formError, fieldErrors } as never\n }\n\n return { formError: rawError }\n }\n\n return { formError: undefined }\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n case 'server':\n return 'onServer'\n case 'change':\n default:\n return 'onChange'\n }\n}\n"],"names":["_a","opts","_c","_b"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/form-core",
3
- "version": "0.47.2",
3
+ "version": "0.48.0",
4
4
  "description": "Powerful, type-safe, framework agnostic forms.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
package/src/FormApi.ts CHANGED
@@ -452,6 +452,10 @@ export type BaseFormState<
452
452
  * A counter for tracking the number of submission attempts.
453
453
  */
454
454
  submissionAttempts: number
455
+ /**
456
+ * A boolean indicating if the last submission was successful.
457
+ */
458
+ isSubmitSuccessful: boolean
455
459
  /**
456
460
  * @private, used to force a re-evaluation of the form state when options change
457
461
  */
@@ -616,6 +620,7 @@ function getDefaultFormState<
616
620
  isSubmitting: defaultState.isSubmitting ?? false,
617
621
  isValidating: defaultState.isValidating ?? false,
618
622
  submissionAttempts: defaultState.submissionAttempts ?? 0,
623
+ isSubmitSuccessful: defaultState.isSubmitSuccessful ?? false,
619
624
  validationMetaMap: defaultState.validationMetaMap ?? {
620
625
  onChange: undefined,
621
626
  onBlur: undefined,
@@ -1580,6 +1585,7 @@ export class FormApi<
1580
1585
  isSubmitted: false,
1581
1586
  // Count submission attempts
1582
1587
  submissionAttempts: old.submissionAttempts + 1,
1588
+ isSubmitSuccessful: false, // Reset isSubmitSuccessful at the start of submission
1583
1589
  }))
1584
1590
 
1585
1591
  // Don't let invalid forms submit
@@ -1634,10 +1640,18 @@ export class FormApi<
1634
1640
  } as any)
1635
1641
 
1636
1642
  batch(() => {
1637
- this.baseStore.setState((prev) => ({ ...prev, isSubmitted: true }))
1643
+ this.baseStore.setState((prev) => ({
1644
+ ...prev,
1645
+ isSubmitted: true,
1646
+ isSubmitSuccessful: true, // Set isSubmitSuccessful to true on successful submission
1647
+ }))
1638
1648
  done()
1639
1649
  })
1640
1650
  } catch (err) {
1651
+ this.baseStore.setState((prev) => ({
1652
+ ...prev,
1653
+ isSubmitSuccessful: false, // Ensure isSubmitSuccessful is false if an error occurs
1654
+ }))
1641
1655
  done()
1642
1656
  throw err
1643
1657
  }