@tanstack/form-core 0.47.0 → 0.47.2

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.
@@ -31,7 +31,7 @@ class FormApi {
31
31
  this.options = {};
32
32
  this.fieldInfo = {};
33
33
  this.prevTransformArray = [];
34
- this.prevFieldsErrorMap = {};
34
+ this.cumulativeFieldsErrorMap = {};
35
35
  this.mount = () => {
36
36
  const cleanupFieldMetaDerived = this.fieldMetaDerived.mount();
37
37
  const cleanupStoreDerived = this.store.mount();
@@ -45,12 +45,16 @@ class FormApi {
45
45
  return cleanup;
46
46
  };
47
47
  this.update = (options) => {
48
+ var _a2, _b;
48
49
  if (!options) return;
49
50
  const oldOptions = this.options;
50
51
  this.options = options;
52
+ const shouldUpdateReeval = !!((_b = (_a2 = options.transform) == null ? void 0 : _a2.deps) == null ? void 0 : _b.some(
53
+ (val, i) => val !== this.prevTransformArray[i]
54
+ ));
51
55
  const shouldUpdateValues = options.defaultValues && !utils.shallow(options.defaultValues, oldOptions.defaultValues) && !this.state.isTouched;
52
56
  const shouldUpdateState = !utils.shallow(options.defaultState, oldOptions.defaultState) && !this.state.isTouched;
53
- if (!shouldUpdateValues && !shouldUpdateState) return;
57
+ if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return;
54
58
  store.batch(() => {
55
59
  this.baseStore.setState(
56
60
  () => getDefaultFormState(
@@ -60,7 +64,8 @@ class FormApi {
60
64
  shouldUpdateState ? options.defaultState : {},
61
65
  shouldUpdateValues ? {
62
66
  values: options.defaultValues
63
- } : {}
67
+ } : {},
68
+ shouldUpdateReeval ? { _force_re_eval: !this.state._force_re_eval } : {}
64
69
  )
65
70
  )
66
71
  );
@@ -141,7 +146,7 @@ class FormApi {
141
146
  this.validateSync = (cause) => {
142
147
  const validates = utils.getSyncValidatorArray(cause, this.options);
143
148
  let hasErrored = false;
144
- const newFieldsErrorMap = {};
149
+ const currentValidationErrorMap = {};
145
150
  store.batch(() => {
146
151
  var _a2;
147
152
  for (const validateObj of validates) {
@@ -159,12 +164,13 @@ class FormApi {
159
164
  const errorMapKey = getErrorMapKey(validateObj.cause);
160
165
  if (fieldErrors) {
161
166
  for (const [field, fieldError] of Object.entries(fieldErrors)) {
162
- const oldErrorMap = newFieldsErrorMap[field] || {};
167
+ const oldErrorMap = this.cumulativeFieldsErrorMap[field] || {};
163
168
  const newErrorMap = {
164
169
  ...oldErrorMap,
165
170
  [errorMapKey]: fieldError
166
171
  };
167
- newFieldsErrorMap[field] = newErrorMap;
172
+ currentValidationErrorMap[field] = newErrorMap;
173
+ this.cumulativeFieldsErrorMap[field] = newErrorMap;
168
174
  const fieldMeta = this.getFieldMeta(field);
169
175
  if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {
170
176
  this.setFieldMeta(field, (prev) => ({
@@ -177,9 +183,13 @@ class FormApi {
177
183
  }
178
184
  }
179
185
  }
180
- for (const field of Object.keys(this.prevFieldsErrorMap)) {
186
+ for (const field of Object.keys(this.cumulativeFieldsErrorMap)) {
181
187
  const fieldMeta = this.getFieldMeta(field);
182
- if ((fieldMeta == null ? void 0 : fieldMeta.errorMap[errorMapKey]) && !((_a2 = newFieldsErrorMap[field]) == null ? void 0 : _a2[errorMapKey])) {
188
+ if ((fieldMeta == null ? void 0 : fieldMeta.errorMap[errorMapKey]) && !((_a2 = currentValidationErrorMap[field]) == null ? void 0 : _a2[errorMapKey])) {
189
+ this.cumulativeFieldsErrorMap[field] = {
190
+ ...this.cumulativeFieldsErrorMap[field],
191
+ [errorMapKey]: void 0
192
+ };
183
193
  this.setFieldMeta(field, (prev) => ({
184
194
  ...prev,
185
195
  errorMap: {
@@ -213,8 +223,7 @@ class FormApi {
213
223
  }));
214
224
  }
215
225
  });
216
- this.prevFieldsErrorMap = newFieldsErrorMap;
217
- return { hasErrored, fieldsErrorMap: newFieldsErrorMap };
226
+ return { hasErrored, fieldsErrorMap: currentValidationErrorMap };
218
227
  };
219
228
  this.validateAsync = async (cause) => {
220
229
  const validates = utils.getAsyncValidatorArray(cause, this.options);
@@ -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\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 map of errors originated from form level validators\n */\n prevFieldsErrorMap: 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 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) 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 ),\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 const newFieldsErrorMap: 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)) {\n const oldErrorMap =\n newFieldsErrorMap[field as DeepKeys<TFormData>] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n newFieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap\n\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\n for (const field of Object.keys(this.prevFieldsErrorMap) as Array<\n DeepKeys<TFormData>\n >) {\n const fieldMeta = this.getFieldMeta(field)\n if (\n fieldMeta?.errorMap[errorMapKey] &&\n !newFieldsErrorMap[field]?.[errorMapKey]\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 this.prevFieldsErrorMap = newFieldsErrorMap\n\n return { hasErrored, fieldsErrorMap: newFieldsErrorMap }\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":["shallow","batch","opts","_a","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 * @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":";;;;;;AA+jBA,SAAS,oBAWP,cAuBA;AACO,SAAA;AAAA,IACL,QAAQ,aAAa,UAAW,CAAC;AAAA,IACjC,UAAU,aAAa,YAAY,CAAC;AAAA,IACpC,eAAe,aAAa,iBAAkB,CAAC;AAAA,IAC/C,aAAa,aAAa,eAAe;AAAA,IACzC,cAAc,aAAa,gBAAgB;AAAA,IAC3C,cAAc,aAAa,gBAAgB;AAAA,IAC3C,oBAAoB,aAAa,sBAAsB;AAAA,IACvD,mBAAmB,aAAa,qBAAqB;AAAA,MACnD,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,SAAS;AAAA,MACT,UAAU;AAAA,IAAA;AAAA,EAEd;AACF;AA2BO,MAAM,QAWX;AAAA;AAAA;AAAA;AAAA,EA4EA,YACE,MAYA;;AArFF,SAAA,UAWI,CAAC;AA+BL,SAAA,YAA+D,CAAC;AAShE,SAAA,qBAAgC,CAAC;AAOjC,SAAA,2BASI,CAAC;AAkTL,SAAA,QAAQ,MAAM;AACN,YAAA,0BAA0B,KAAK,iBAAiB,MAAM;AACtD,YAAA,sBAAsB,KAAK,MAAM,MAAM;AAC7C,YAAM,UAAU,MAAM;AACI,gCAAA;AACJ,4BAAA;AAAA,MACtB;AACA,YAAM,EAAE,QAAQ,IAAI,KAAK,QAAQ,cAAc,CAAC;AAC5C,UAAA,CAAC,QAAgB,QAAA;AACrB,WAAK,aAAa,OAAO;AAElB,aAAA;AAAA,IACT;AAKA,SAAA,SAAS,CACP,YAYG;;AACH,UAAI,CAAC,QAAS;AAEd,YAAM,aAAa,KAAK;AAGxB,WAAK,UAAU;AAGf,YAAM,qBAAqB,CAAC,GAAC,MAAAA,MAAA,QAAQ,cAAR,gBAAAA,IAAmB,SAAnB,mBAAyB;AAAA,QACpD,CAAC,KAAK,MAAM,QAAQ,KAAK,mBAAmB,CAAC;AAAA;AAG/C,YAAM,qBACJ,QAAQ,iBACR,CAACC,MAAQ,QAAA,QAAQ,eAAe,WAAW,aAAa,KACxD,CAAC,KAAK,MAAM;AAER,YAAA,oBACJ,CAACA,cAAQ,QAAQ,cAAc,WAAW,YAAY,KACtD,CAAC,KAAK,MAAM;AAEd,UAAI,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,mBAAoB;AAEtEC,YAAAA,MAAM,MAAM;AACV,aAAK,UAAU;AAAA,UAAS,MACtB;AAAA,YACE,OAAO;AAAA,cACL,CAAC;AAAA,cACD,KAAK;AAAA,cAEL,oBAAoB,QAAQ,eAAe,CAAC;AAAA,cAE5C,qBACI;AAAA,gBACE,QAAQ,QAAQ;AAAA,cAAA,IAElB,CAAC;AAAA,cAEL,qBACI,EAAE,gBAAgB,CAAC,KAAK,MAAM,eAAA,IAC9B,CAAA;AAAA,YAAC;AAAA,UACP;AAAA,QAEJ;AAAA,MAAA,CACD;AAAA,IACH;AASQ,SAAA,QAAA,CAAC,QAAoBC,UAA2C;AACtE,YAAM,EAAE,WAAW,iBAAiB,IAAI,KAAK;AACvC,YAAA,gBAAgB,KAAK,eAAe,gBAAgB;AAEtD,UAAA,UAAU,EAACA,SAAA,gBAAAA,MAAM,oBAAmB;AACtC,aAAK,UAAU;AAAA,UACb,GAAG,KAAK;AAAA,UACR,eAAe;AAAA,QACjB;AAAA,MAAA;AAGF,WAAK,UAAU;AAAA,QAAS,MAAA;;AACtB,qCAAoB;AAAA,YAClB,GAAI,KAAK,QAAQ;AAAA,YACjB,QACE,UACA,KAAK,QAAQ,mBACbH,MAAA,KAAK,QAAQ,iBAAb,gBAAAA,IAA2B;AAAA,YAC7B;AAAA,UACD,CAAA;AAAA;AAAA,MACH;AAAA,IACF;AAKA,SAAA,oBAAoB,OAAO,UAA2B;AACpD,YAAM,0BAAwD,CAAC;AAC/DE,YAAAA,MAAM,MAAM;AACV,aAAM,OAAO,OAAO,KAAK,SAAS,EAAuB;AAAA,UACvD,CAAC,UAAU;AACL,gBAAA,CAAC,MAAM,SAAU;AACrB,kBAAM,gBAAgB,MAAM;AAEJ,oCAAA;AAAA;AAAA,cAEtB,QAAQ,UAAU;AAAA,gBAAK,MACrB,cAAc,SAAS,OAAO,EAAE,oBAAoB,KAAM,CAAA;AAAA,cAAA;AAAA,YAE9D;AAEA,gBAAI,CAAC,MAAM,SAAS,MAAM,KAAK,WAAW;AAElC,oBAAA,SAAS,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,KAAA,EAAO;AAAA,YAAA;AAAA,UACjE;AAAA,QAEJ;AAAA,MAAA,CACD;AAED,YAAM,mBAAmB,MAAM,QAAQ,IAAI,uBAAuB;AAClE,aAAO,iBAAiB,KAAK;AAAA,IAC/B;AAKkC,SAAA,kCAAA,OAChC,OACA,OACA,UACG;AACG,YAAA,eAAe,KAAK,cAAc,KAAK;AAEvC,YAAA,YAAY,MAAM,QAAQ,YAAY,IACxC,KAAK,IAAI,aAAa,SAAS,GAAG,CAAC,IACnC;AAGJ,YAAM,sBAAsB,CAAC,GAAG,KAAK,IAAI,KAAK,GAAG;AACjD,eAAS,IAAI,QAAQ,GAAG,MAAM,aAAa,IAAI,KAAK;AAClD,4BAAoB,KAAK,GAAG,KAAK,IAAI,CAAC,GAAG;AAAA,MAAA;AAI3C,YAAM,mBAAmB,OAAO,KAAK,KAAK,SAAS,EAAE;AAAA,QAAO,CAAC,aAC3D,oBAAoB,KAAK,CAAC,QAAQ,SAAS,WAAW,GAAG,CAAC;AAAA,MAC5D;AAGA,YAAM,0BAAwD,CAAC;AAC/DA,YAAAA,MAAM,MAAM;AACO,yBAAA,QAAQ,CAAC,gBAAgB;AAChB,kCAAA;AAAA,YACtB,QAAQ,UAAU,KAAK,MAAM,KAAK,cAAc,aAAa,KAAK,CAAC;AAAA,UACrE;AAAA,QAAA,CACD;AAAA,MAAA,CACF;AAED,YAAM,mBAAmB,MAAM,QAAQ,IAAI,uBAAuB;AAClE,aAAO,iBAAiB,KAAK;AAAA,IAC/B;AAKgB,SAAA,gBAAA,CACd,OACA,UACG;;AAEH,YAAM,iBAAgBF,MAAA,KAAK,UAAU,KAAK,MAApB,gBAAAA,IAAuB;AACzC,UAAA,CAAC,cAAe,QAAO,CAAC;AAG5B,UAAI,CAAC,cAAc,MAAM,KAAK,WAAW;AAEzB,sBAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,OAAO;AAAA,MAAA;AAGzD,aAAA,cAAc,SAAS,KAAK;AAAA,IACrC;AAMA,SAAA,eAAe,CACb,UAaG;AACH,YAAM,YAAYI,MAAA,sBAAsB,OAAO,KAAK,OAAO;AAC3D,UAAI,aAAa;AAGjB,YAAM,4BASF,CAAC;AAELF,YAAAA,MAAM,MAAM;;AACV,mBAAW,eAAe,WAAW;AAC/B,cAAA,CAAC,YAAY,SAAU;AAErB,gBAAA,WAAW,KAAK,aAAa;AAAA,YACjC,UAAU,YAAY;AAAA,YACtB,OAAO;AAAA,cACL,OAAO,KAAK,MAAM;AAAA,cAClB,SAAS;AAAA,cACT,kBAAkB;AAAA,YACpB;AAAA,YACA,MAAM;AAAA,UAAA,CACP;AAED,gBAAM,EAAE,WAAW,gBAAgB,eAA0B,QAAQ;AAE/D,gBAAA,cAAc,eAAe,YAAY,KAAK;AAEpD,cAAI,aAAa;AACf,uBAAW,CAAC,OAAO,UAAU,KAAK,OAAO,QAAQ,WAAW,GAGvD;AACH,oBAAM,cAAc,KAAK,yBAAyB,KAAK,KAAK,CAAC;AAC7D,oBAAM,cAAc;AAAA,gBAClB,GAAG;AAAA,gBACH,CAAC,WAAW,GAAG;AAAA,cACjB;AACA,wCAA0B,KAAK,IAAI;AAC9B,mBAAA,yBAAyB,KAAK,IAAI;AAEjC,oBAAA,YAAY,KAAK,aAAa,KAAK;AACzC,kBAAI,aAAa,UAAU,SAAS,WAAW,MAAM,YAAY;AAC1D,qBAAA,aAAa,OAAO,CAAC,UAAU;AAAA,kBAClC,GAAG;AAAA,kBACH,UAAU;AAAA,oBACR,GAAG,KAAK;AAAA,oBACR,CAAC,WAAW,GAAG;AAAA,kBAAA;AAAA,gBACjB,EACA;AAAA,cAAA;AAAA,YACJ;AAAA,UACF;AAGF,qBAAW,SAAS,OAAO,KAAK,KAAK,wBAAwB,GAE1D;AACK,kBAAA,YAAY,KAAK,aAAa,KAAK;AAEvC,iBAAA,uCAAW,SAAS,iBACpB,GAACF,MAAA,0BAA0B,KAAK,MAA/B,gBAAAA,IAAmC,eACpC;AACK,mBAAA,yBAAyB,KAAK,IAAI;AAAA,gBACrC,GAAG,KAAK,yBAAyB,KAAK;AAAA,gBACtC,CAAC,WAAW,GAAG;AAAA,cACjB;AAEK,mBAAA,aAAa,OAAO,CAAC,UAAU;AAAA,gBAClC,GAAG;AAAA,gBACH,UAAU;AAAA,kBACR,GAAG,KAAK;AAAA,kBACR,CAAC,WAAW,GAAG;AAAA,gBAAA;AAAA,cACjB,EACA;AAAA,YAAA;AAAA,UACJ;AAGF,cAAI,KAAK,MAAM,SAAS,WAAW,MAAM,WAAW;AAC7C,iBAAA,UAAU,SAAS,CAAC,UAAU;AAAA,cACjC,GAAG;AAAA,cACH,UAAU;AAAA,gBACR,GAAG,KAAK;AAAA,gBACR,CAAC,WAAW,GAAG;AAAA,cAAA;AAAA,YACjB,EACA;AAAA,UAAA;AAGJ,cAAI,aAAa,aAAa;AACf,yBAAA;AAAA,UAAA;AAAA,QACf;AAOI,cAAA,eAAe,eAAe,QAAQ;AAE1C,YAAA,KAAK,MAAM,SAAS,YAAY,KAChC,UAAU,YACV,CAAC,YACD;AACK,eAAA,UAAU,SAAS,CAAC,UAAU;AAAA,YACjC,GAAG;AAAA,YACH,UAAU;AAAA,cACR,GAAG,KAAK;AAAA,cACR,CAAC,YAAY,GAAG;AAAA,YAAA;AAAA,UAClB,EACA;AAAA,QAAA;AAAA,MACJ,CACD;AAEM,aAAA,EAAE,YAAY,gBAAgB,0BAA0B;AAAA,IACjE;AAKA,SAAA,gBAAgB,OACd,UAYG;AACH,YAAM,YAAYK,MAAA,uBAAuB,OAAO,KAAK,OAAO;AAExD,UAAA,CAAC,KAAK,MAAM,kBAAkB;AAC3B,aAAA,UAAU,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,kBAAkB,KAAA,EAAO;AAAA,MAAA;AAOzE,YAAM,WAA0D,CAAC;AAE7D,UAAA;AAIJ,iBAAW,eAAe,WAAW;AAC/B,YAAA,CAAC,YAAY,SAAU;AACrB,cAAA,MAAM,eAAe,YAAY,KAAK;AAC5C,cAAM,qBAAqB,KAAK,MAAM,kBAAkB,GAAG;AAE3D,iEAAoB,oBAAoB;AAClC,cAAA,aAAa,IAAI,gBAAgB;AAElC,aAAA,MAAM,kBAAkB,GAAG,IAAI;AAAA,UAClC,qBAAqB;AAAA,QACvB;AAES,iBAAA;AAAA,UACP,IAAI,QAA4C,OAAO,YAAY;AAC7D,gBAAA;AAIA,gBAAA;AACF,yBAAW,MAAM,IAAI,QAAQ,CAAC,YAAY,cAAc;AACtD,2BAAW,YAAY;AACrB,sBAAI,WAAW,OAAO,QAAS,QAAO,WAAW,MAAS;AACtD,sBAAA;AACF;AAAA,sBACE,MAAM,KAAK,aAAa;AAAA,wBACtB,UAAU,YAAY;AAAA,wBACtB,OAAO;AAAA,0BACL,OAAO,KAAK,MAAM;AAAA,0BAClB,SAAS;AAAA,0BACT,kBAAkB;AAAA,0BAClB,QAAQ,WAAW;AAAA,wBACrB;AAAA,wBACA,MAAM;AAAA,sBACP,CAAA;AAAA,oBACH;AAAA,2BACO,GAAG;AACV,8BAAU,CAAC;AAAA,kBAAA;AAAA,gBACb,GACC,YAAY,UAAU;AAAA,cAAA,CAC1B;AAAA,qBACM,GAAY;AACR,yBAAA;AAAA,YAAA;AAEb,kBAAM,EAAE,WAAW,aAAa,8BAA8B,IAC5D,eAA0B,QAAQ;AAEpC,gBAAI,+BAA+B;AACjC,4BAAc,cACV,EAAE,GAAG,aAAa,GAAG,8BACrB,IAAA;AAAA,YAAA;AAEA,kBAAA,cAAc,eAAe,YAAY,KAAK;AAEpD,gBAAI,aAAa;AACf,yBAAW,CAAC,OAAO,UAAU,KAAK,OAAO,QAAQ,WAAW,GAAG;AACvD,sBAAA,YAAY,KAAK,aAAa,KAA4B;AAChE,oBAAI,aAAa,UAAU,SAAS,WAAW,MAAM,YAAY;AAC1D,uBAAA,aAAa,OAA8B,CAAC,UAAU;AAAA,oBACzD,GAAG;AAAA,oBACH,UAAU;AAAA,sBACR,GAAG,KAAK;AAAA,sBACR,CAAC,WAAW,GAAG;AAAA,oBAAA;AAAA,kBACjB,EACA;AAAA,gBAAA;AAAA,cACJ;AAAA,YACF;AAEG,iBAAA,UAAU,SAAS,CAAC,UAAU;AAAA,cACjC,GAAG;AAAA,cACH,UAAU;AAAA,gBACR,GAAG,KAAK;AAAA,gBACR,CAAC,WAAW,GAAG;AAAA,cAAA;AAAA,YACjB,EACA;AAEF,oBAAQ,cAAc,EAAE,aAAa,YAAA,IAAgB,MAAS;AAAA,UAC/D,CAAA;AAAA,QACH;AAAA,MAAA;AAGF,UAAI,UAAgD,CAAC;AAErD,YAAM,iBASF,CAAC;AACL,UAAI,SAAS,QAAQ;AACT,kBAAA,MAAM,QAAQ,IAAI,QAAQ;AACpC,mBAAW,yBAAyB,SAAS;AAC3C,cAAI,+DAAuB,aAAa;AAChC,kBAAA,EAAE,gBAAgB;AAExB,uBAAW,CAAC,OAAO,UAAU,KAAK,OAAO;AAAA,cACvC,sBAAsB;AAAA,YAAA,GACrB;AACD,oBAAM,cACJ,eAAe,KAA4B,KAAK,CAAC;AACnD,oBAAM,cAAc;AAAA,gBAClB,GAAG;AAAA,gBACH,CAAC,WAAW,GAAG;AAAA,cACjB;AACA,6BAAe,KAA4B,IAAI;AAAA,YAAA;AAAA,UACjD;AAAA,QACF;AAAA,MACF;AAGG,WAAA,UAAU,SAAS,CAAC,UAAU;AAAA,QACjC,GAAG;AAAA,QACH,kBAAkB;AAAA,MAAA,EAClB;AAEK,aAAA;AAAA,IACT;AAKA,SAAA,WAAW,CACT,UAuBO;AAEP,YAAM,EAAE,YAAY,eAAA,IAAmB,KAAK,aAAa,KAAK;AAE9D,UAAI,cAAc,CAAC,KAAK,QAAQ,aAAa;AACpC,eAAA;AAAA,MAAA;AAIF,aAAA,KAAK,cAAc,KAAK;AAAA,IACjC;AAgFA,SAAA,gBAAgB,CACd,UACiCC,MAAAA,MAAM,KAAK,MAAM,QAAQ,KAAK;AAKjE,SAAA,eAAe,CACb,UAC6B;AACtB,aAAA,KAAK,MAAM,UAAU,KAAK;AAAA,IACnC;AAKA,SAAA,eAAe,CACb,UACyB;;AAEjB,cAAAN,MAAA,KAAK,WAAL,WAAAA,IAAA,SAA0B;AAAA,QAChC,UAAU;AAAA,QACV,mBAAmB;AAAA,UACjB,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,SAAS;AAAA,UACT,UAAU;AAAA,QAAA;AAAA,MAEd;AAAA,IACF;AAKe,SAAA,eAAA,CACb,OACA,YACG;AACE,WAAA,UAAU,SAAS,CAAC,SAAS;AACzB,eAAA;AAAA,UACL,GAAG;AAAA,UACH,eAAe;AAAA,YACb,GAAG,KAAK;AAAA,YACR,CAAC,KAAK,GAAGO,MAAA;AAAA,cACP;AAAA,cACA,KAAK,cAAc,KAAK;AAAA,YAAA;AAAA,UAC1B;AAAA,QAEJ;AAAA,MAAA,CACD;AAAA,IACH;AAEA,SAAA,iBAAiB,CACf,cACiC;AAC1B,aAAA,OAAO,KAAK,SAAS,EAAE;AAAA,QAC5B,CAAC,KAAmC,QAAQ;AAC1C,gBAAM,WAAW;AACjB,cAAI,QAAQ,IAAI;AAAA,YACd,cAAc;AAAA,YACd,WAAW;AAAA,YACX,WAAW;AAAA,YACX,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,QAAQ,CAAC;AAAA,YACT,UAAU,CAAA;AAAA,UACZ;AACO,iBAAA;AAAA,QACT;AAAA,QACA,CAAA;AAAA,MACF;AAAA,IACF;AAKgB,SAAA,gBAAA,CACd,OACA,SACAJ,UACG;AACG,YAAA,kBAAiBA,SAAA,gBAAAA,MAAM,mBAAkB;AAE/CD,YAAAA,MAAM,MAAM;AACV,YAAI,CAAC,gBAAgB;AACd,eAAA,aAAa,OAAO,CAAC,UAAU;AAAA,YAClC,GAAG;AAAA,YACH,WAAW;AAAA,YACX,SAAS;AAAA,YACT,UAAU;AAAA;AAAA,cAER,GAAG,6BAAM;AAAA,cACT,SAAS;AAAA,YAAA;AAAA,UACX,EACA;AAAA,QAAA;AAGC,aAAA,UAAU,SAAS,CAAC,SAAS;AACzB,iBAAA;AAAA,YACL,GAAG;AAAA,YACH,QAAQM,MAAAA,MAAM,KAAK,QAAQ,OAAO,OAAO;AAAA,UAC3C;AAAA,QAAA,CACD;AAAA,MAAA,CACF;AAAA,IACH;AAEA,SAAA,cAAc,CAAqC,UAAkB;AAC9D,WAAA,UAAU,SAAS,CAAC,SAAS;AAC1B,cAAA,WAAW,EAAE,GAAG,KAAK;AAC3B,iBAAS,SAASC,MAAAA,SAAS,SAAS,QAAQ,KAAK;AAC1C,eAAA,SAAS,cAAc,KAAK;AAE5B,eAAA;AAAA,MAAA,CACR;AACM,aAAA,KAAK,UAAU,KAAK;AAAA,IAC7B;AAKiB,SAAA,iBAAA,CACf,OACA,OAGAN,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAS,CAAC,GAAI,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAI,KAAK;AAAA,QACtDA;AAAA,MACF;AACK,WAAA,cAAc,OAAO,QAAQ;AAAA,IACpC;AAEA,SAAA,mBAAmB,OACjB,OACA,OACA,OAGAA,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAS;AACD,iBAAA;AAAA,YACL,GAAI,KAAwC,MAAM,GAAG,KAAK;AAAA,YAC1D;AAAA,YACA,GAAI,KAAwC,MAAM,KAAK;AAAA,UACzD;AAAA,QACF;AAAA,QACAA;AAAA,MACF;AAGM,YAAA,KAAK,cAAc,OAAO,QAAQ;AAGxCO,iBAAA,WAAW,IAAI,EAAE,0BAA0B,OAAO,OAAO,QAAQ;AAEjE,YAAM,KAAK,gCAAgC,OAAO,OAAO,QAAQ;AAAA,IACnE;AAKA,SAAA,oBAAoB,OAClB,OACA,OACA,OAGAP,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAS;AACR,iBAAQ,KAAwC;AAAA,YAAI,CAAC,GAAG,MACtD,MAAM,QAAQ,QAAQ;AAAA,UACxB;AAAA,QACF;AAAA,QACAA;AAAA,MACF;AAGM,YAAA,KAAK,cAAc,OAAO,QAAQ;AACxC,YAAM,KAAK,gCAAgC,OAAO,OAAO,QAAQ;AAAA,IACnE;AAKmB,SAAA,mBAAA,OACjB,OACA,OACAA,UACG;AACG,YAAA,aAAa,KAAK,cAAc,KAAK;AAErC,YAAA,YAAY,MAAM,QAAQ,UAAU,IACtC,KAAK,IAAI,WAAW,SAAS,GAAG,CAAC,IACjC;AAEC,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAS;AACR,iBAAQ,KAAwC;AAAA,YAC9C,CAAC,IAAI,MAAM,MAAM;AAAA,UACnB;AAAA,QACF;AAAA,QACAA;AAAA,MACF;AAGAO,iBAAA,WAAW,IAAI,EAAE,0BAA0B,OAAO,OAAO,QAAQ;AAEjE,UAAI,cAAc,MAAM;AACtB,cAAM,QAAQ,GAAG,KAAK,IAAI,SAAS;AACnC,cAAM,iBAAiB,OAAO,KAAK,KAAK,SAAS,EAAE;AAAA,UAAO,CAAC,MACzD,EAAE,WAAW,KAAK;AAAA,QACpB;AAGA,uBAAe,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAW,CAAC;AAAA,MAAA;AAIvD,YAAA,KAAK,cAAc,OAAO,QAAQ;AACxC,YAAM,KAAK,gCAAgC,OAAO,OAAO,QAAQ;AAAA,IACnE;AAKA,SAAA,kBAAkB,CAChB,OACA,QACA,QACAP,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAc;AACP,gBAAA,QAAQ,KAAK,MAAM;AACnB,gBAAA,QAAQ,KAAK,MAAM;AAClB,iBAAAK,YAAMA,MAAAA,MAAM,MAAM,GAAG,MAAM,IAAI,KAAK,GAAG,GAAG,MAAM,IAAI,KAAK;AAAA,QAClE;AAAA,QACAL;AAAA,MACF;AAGAO,iBAAA,WAAW,IAAI,EAAE,0BAA0B,OAAO,QAAQ,QAAQ,MAAM;AAGnE,WAAA,cAAc,OAAO,QAAQ;AAElC,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AACzE,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AAAA,IAC3E;AAKA,SAAA,kBAAkB,CAChB,OACA,QACA,QACAP,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAc;AACR,eAAA,OAAO,QAAQ,GAAG,KAAK,OAAO,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzC,iBAAA;AAAA,QACT;AAAA,QACAA;AAAA,MACF;AAGAO,iBAAA,WAAW,IAAI,EAAE,0BAA0B,OAAO,QAAQ,QAAQ,MAAM;AAGnE,WAAA,cAAc,OAAO,QAAQ;AAElC,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AACzE,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AAAA,IAC3E;AA8BA,SAAA,eAAe,MA2BV;AACI,aAAA;AAAA,QACL,MAAM;AAAA,UACJ,QAAQ,KAAK,MAAM;AAAA,UACnB,UAAU,KAAK,MAAM;AAAA,QACvB;AAAA,QACA,QAAQ,OAAO,QAAQ,KAAK,MAAM,SAAS,EAAE;AAAA,UAC3C,CAAC,KAAK,CAAC,WAAW,SAAS,MAAM;AAC/B,gBACE,OAAO,KAAK,SAAyB,EAAE,UACtC,UAA2B,OAAO,QACnC;AACA,kBAAI,SAAgC,IAAI;AAAA,gBACtC,QAAS,UAA2B;AAAA,gBACpC,UAAW,UAA2B;AAAA,cACxC;AAAA,YAAA;AAGK,mBAAA;AAAA,UACT;AAAA,UACA,CAAA;AAAA,QAAC;AAAA,MAKL;AAAA,IACF;AAjvCE,SAAK,YAAY,IAAIC,MAAA;AAAA,MACnB,oBAAoB;AAAA,QAClB,GAAI,6BAAM;AAAA,QACV,SAAQ,6BAAM,oBAAiB,kCAAM,iBAAN,mBAAoB;AAAA,MAErD,CAAC;AAAA,IACH;AAEK,SAAA,mBAAmB,IAAIC,cAAQ;AAAA,MAClC,MAAM,CAAC,KAAK,SAAS;AAAA,MACrB,IAAI,CAAC,EAAE,aAAa,aAAa,SAAS,eAAe;;AACvD,cAAM,UAAU;AAGV,cAAA,gBAAgB,2CAAc;AAC9B,cAAA,gBAAgB,YAAY,CAAC;AAEnC,YAAI,oBAAoB;AAExB,cAAM,YAAY,CAAC;AAYnB,mBAAW,aAAa,OAAO;AAAA,UAC7B,cAAc;AAAA,QAAA,GACsC;AAC9C,gBAAA,cAAc,cAAc,cAChC,SACF;AAEM,gBAAA,cAAc,+CAAe,cACjC;AAGI,gBAAA,gBACJ,mCAAU;AAEZ,cAAI,cAAc,+CAAe;AACjC,cAAI,CAAC,eAAe,YAAY,aAAa,YAAY,UAAU;AAEjE,0BAAc,OAAO,OAAO,YAAY,YAAY,CAAE,CAAA,EAAE;AAAA,cACtD,CAAC,QAAQ,QAAQ;AAAA,YACnB;AAGA,kBAAM,iBAAgBZ,MAAA,KAAK,aAAa,SAAS,MAA3B,gBAAAA,IAA8B;AAEpD,gBAAI,iBAAiB,CAAC,cAAc,QAAQ,kBAAkB;AAC5D,4BAAe,2CAAsC;AAAA,gBACnD;AAAA;AAAA,YACF;AAAA,UACF;AAII,gBAAA,kBAAkB,CAAC,YAAY;AAGnC,cAAA,iBACA,cAAc,eAAe,mBAC7B,cAAc,WAAW,eACzB,gBAAgB,aAChB;AACA,sBAAU,SAAS,IAAI;AACvB;AACA;AAAA,UAAA;AAGF,oBAAU,SAAS,IAAI;AAAA,YACrB,GAAG;AAAA,YACH,QAAQ;AAAA,YACR,YAAY;AAAA,UACd;AAAA,QAAA;AAGF,YACE,WACA,sBAAsB,OAAO,KAAK,cAAc,aAAa,EAAE,QAC/D;AACO,iBAAA;AAAA,QAAA;AAGF,eAAA;AAAA,MAAA;AAAA,IACT,CACD;AAEI,SAAA,QAAQ,IAAIY,cAAQ;AAAA,MACvB,MAAM,CAAC,KAAK,WAAW,KAAK,gBAAgB;AAAA,MAC5C,IAAI,CAAC,EAAE,aAAa,aAAa,SAAS,eAAe;;AACvD,cAAM,UAAU;AAaV,cAAA,gBAAgB,2CAAc;AAC9B,cAAA,gBAAgB,YAAY,CAAC;AAGnC,cAAM,kBAAkB,OAAO,OAAO,cAAc,aAAa;AAKjE,cAAM,qBAAqB,gBAAgB;AAAA,UACzC,CAAC,UAAU,+BAAO;AAAA,QACpB;AAEM,cAAA,gBAAgB,CAAC,gBAAgB;AAAA,UACrC,CAAC,WACC,+BAAO,aACPC,sBAAgB,OAAO,OAAO,MAAM,QAAQ,EAAE,OAAO,OAAO,CAAC;AAAA,QACjE;AAEA,cAAM,YAAY,gBAAgB,KAAK,CAAC,UAAU,+BAAO,SAAS;AAClE,cAAM,YAAY,gBAAgB,KAAK,CAAC,UAAU,+BAAO,SAAS;AAE5D,cAAA;AAAA;AAAA,UAEJ,eAAab,MAAA,+CAAe,aAAf,gBAAAA,IAAyB;AAAA;AAExC,cAAM,UAAU,gBAAgB,KAAK,CAAC,UAAU,+BAAO,OAAO;AAC9D,cAAM,aAAa,CAAC;AAEpB,cAAM,kBAAkB;AAAA;AAAA,YAEtB,mBAAc,aAAd,mBAAwB;AAAA,UAEtB,gBAAgB,KAAK,CAAC,MAAM;;AAAA,oBAAAA,MAAA,uBAAG,aAAH,gBAAAA,IAAa;AAAA,WAAO;AAAA,QACpD;AAEM,cAAA,eAAe,CAAC,CAAC;AAGnB,YAAA,UAAS,mCAAS,WAAU,CAAC;AACjC,YACE,CAAC,iBACD,cAAc,aAAa,cAAc,UACzC;AACS,mBAAA,OAAO,OAAO,cAAc,QAAQ,EAAE,OAW7C,CAAC,MAAM,SAAS;AACZ,gBAAA,SAAS,OAAkB,QAAA;AAE3B,gBAAA,QAAQc,kCAA4B,IAAI,GAAG;AACxC,mBAAA,KAAK,KAAK,IAAa;AACrB,qBAAA;AAAA,YAAA;AAET,iBAAK,KAAK,IAAa;AAChB,mBAAA;AAAA,UACT,GAAG,EAAE;AAAA,QAAA;AAGD,cAAA,cAAc,OAAO,WAAW;AACtC,cAAM,UAAU,iBAAiB;AACjC,cAAM,YACH,cAAc,uBAAuB,KACpC,CAAC,aACD,CAAC,mBACF,CAAC,gBAAgB,CAAC,cAAc,gBAAgB;AAEnD,YAAI,WAAW,cAAc;AAC7B,YAAI,yBAAyB;AAC3B,mBAAS,OAAO;AAAA,YACd,CAAC,QAAQ,QAAQ,cAAc,SAAS;AAAA,UAC1C;AACA,qBAAW,OAAO,OAAO,UAAU,EAAE,SAAS,QAAW;AAAA,QAAA;AAG3D,YACE,WACA,iBACA,QAAQ,aAAa,YACrB,QAAQ,cAAc,KAAK,iBAAiB,SAC5C,QAAQ,WAAW,UACnB,QAAQ,uBAAuB,sBAC/B,QAAQ,kBAAkB,iBAC1B,QAAQ,gBAAgB,eACxB,QAAQ,YAAY,WACpB,QAAQ,cAAc,aACtB,QAAQ,cAAc,aACtB,QAAQ,cAAc,aACtB,QAAQ,eAAe,cACvB,QAAQ,YAAY,WACpBb,MAAQ,QAAA,eAAe,aAAa,GACpC;AACO,iBAAA;AAAA,QAAA;AAGT,YAAI,QAAQ;AAAA,UACV,GAAG;AAAA,UACH;AAAA,UACA,WAAW,KAAK,iBAAiB;AAAA,UACjC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAaA,cAAM,mBAAiB,UAAK,QAAQ,cAAb,mBAAwB,SAAQ,CAAC;AACxD,cAAM,kBACJ,eAAe,WAAW,KAAK,mBAAmB,UAClD,eAAe,KAAK,CAAC,KAAK,MAAM,QAAQ,KAAK,mBAAmB,CAAC,CAAC;AAEpE,YAAI,iBAAiB;AACb,gBAAA,SAAS,OAAO,OAAO,IAAI,MAAM,EAAE,OAAO;AAE3C,qBAAA,QAAQ,cAAR,mBAAmB,GAAG;AAC3B,kBAAQ,OAAO;AACf,eAAK,qBAAqB;AAAA,QAAA;AAGrB,eAAA;AAAA,MAAA;AAAA,IACT,CACD;AAED,SAAK,eAAe,KAAK,aAAa,KAAK,IAAI;AAE1C,SAAA,OAAO,QAAQ,EAAE;AAAA,EAAA;AAAA,EA7SxB,IAAI,QAAQ;AACV,WAAO,KAAK,MAAM;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAkTpB,aAKE,OAMU;AACN,QAAAc,wBAAA,0BAA0B,MAAM,QAAQ,GAAG;AACtC,aAAAC,wBAAA,yBAAyB,MAAM,IAAI;AAAA,QACxC,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IAAA;AAGM,WAAA,MAAM,SAAiC,MAAM,KAAK;AAAA,EAAA;AAAA,EAyhB5D,MAAM,aAAa,YAAyC;;AACrD,SAAA,UAAU,SAAS,CAAC,SAAS;AAAA,MAChC,GAAG;AAAA;AAAA,MAEH,aAAa;AAAA;AAAA,MAEb,oBAAoB,IAAI,qBAAqB;AAAA,IAAA,EAC7C;AAGE,QAAA,CAAC,KAAK,MAAM,UAAW;AAEtB,SAAA,UAAU,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,cAAc,KAAA,EAAO;AAE7D,UAAM,OAAO,MAAM;AACZ,WAAA,UAAU,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,MAAA,EAAQ;AAAA,IACtE;AAEM,UAAA,KAAK,kBAAkB,QAAQ;AAEjC,QAAA,CAAC,KAAK,MAAM,eAAe;AACxB,WAAA;AACL,uBAAK,SAAQ,oBAAb,4BAA+B;AAAA,QAC7B,OAAO,KAAK,MAAM;AAAA,QAClB,SAAS;AAAA,MAAA;AAEX;AAAA,IAAA;AAGI,UAAA,KAAK,SAAS,QAAQ;AAGxB,QAAA,CAAC,KAAK,MAAM,SAAS;AAClB,WAAA;AACL,uBAAK,SAAQ,oBAAb,4BAA+B;AAAA,QAC7B,OAAO,KAAK,MAAM;AAAA,QAClB,SAAS;AAAA,MAAA;AAEX;AAAA,IAAA;AAGFd,UAAAA,MAAM,MAAM;AACV,WAAM,OAAO,OAAO,KAAK,SAAS,EAA6B;AAAA,QAC7D,CAAC,UAAU;;AACH,WAAAe,OAAAC,OAAAlB,MAAA,MAAA,aAAA,gBAAAA,IAAU,QAAQ,cAAlB,gBAAAkB,IAA6B,aAA7B,gBAAAD,IAAA,KAAAC,KAAwC;AAAA,YAC5C,OAAO,MAAM,SAAS,MAAM;AAAA,YAC5B,UAAU,MAAM;AAAA,UAAA;AAAA,QACjB;AAAA,MAEL;AAAA,IAAA,CACD;AAEG,QAAA;AAEI,cAAA,gBAAK,SAAQ,aAAb,4BAAwB;AAAA,QAC5B,OAAO,KAAK,MAAM;AAAA,QAClB,SAAS;AAAA,QACT,MAAM,cAAc,KAAK,QAAQ;AAAA,MAAA;AAGnChB,YAAAA,MAAM,MAAM;AACL,aAAA,UAAU,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,KAAA,EAAO;AAC7D,aAAA;AAAA,MAAA,CACN;AAAA,aACM,KAAK;AACP,WAAA;AACC,YAAA;AAAA,IAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EA0SF,YACE,UASA;AACA,SAAK,UAAU;AAAA,MACb,CAAC,UACE;AAAA,QACC,GAAG;AAAA,QACH,UAAU;AAAA,UACR,GAAG,KAAK;AAAA,UACR,GAAG;AAAA,QAAA;AAAA,MAEP;AAAA,IACJ;AAAA,EAAA;AA4DJ;AAEA,SAAS,eAA0B,UAGjC;AACA,MAAI,UAAU;AACR,QAAAY,MAAAA,4BAA4B,QAAQ,GAAG;AACzC,YAAM,YAAY,eAAe,SAAS,IAAI,EAAE;AAChD,YAAM,cAAc,SAAS;AACtB,aAAA,EAAE,WAAW,YAAY;AAAA,IAAA;AAG3B,WAAA,EAAE,WAAW,SAAS;AAAA,EAAA;AAGxB,SAAA,EAAE,WAAW,OAAU;AAChC;AAEA,SAAS,eAAe,OAAwB;AAC9C,UAAQ,OAAO;AAAA,IACb,KAAK;AACI,aAAA;AAAA,IACT,KAAK;AACI,aAAA;AAAA,IACT,KAAK;AACI,aAAA;AAAA,IACT,KAAK;AACI,aAAA;AAAA,IACT,KAAK;AAAA,IACL;AACS,aAAA;AAAA,EAAA;AAEb;;"}
@@ -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
+ * @private, used to force a re-evaluation of the form state when options change
194
+ */
195
+ _force_re_eval?: boolean;
192
196
  };
193
197
  export type DerivedFormState<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = {
194
198
  /**
@@ -273,9 +277,11 @@ export declare class FormApi<TFormData, TOnMount extends undefined | FormValidat
273
277
  */
274
278
  prevTransformArray: unknown[];
275
279
  /**
276
- * @private map of errors originated from form level validators
280
+ * @private Persistent store of all field validation errors originating from form-level validators.
281
+ * Maintains the cumulative state across validation cycles, including cleared errors (undefined values).
282
+ * This map preserves the complete validation state for all fields.
277
283
  */
278
- prevFieldsErrorMap: FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>;
284
+ cumulativeFieldsErrorMap: FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>;
279
285
  /**
280
286
  * Constructs a new `FormApi` instance with the given form options.
281
287
  */
@@ -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
+ * @private, used to force a re-evaluation of the form state when options change
194
+ */
195
+ _force_re_eval?: boolean;
192
196
  };
193
197
  export type DerivedFormState<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>> = {
194
198
  /**
@@ -273,9 +277,11 @@ export declare class FormApi<TFormData, TOnMount extends undefined | FormValidat
273
277
  */
274
278
  prevTransformArray: unknown[];
275
279
  /**
276
- * @private map of errors originated from form level validators
280
+ * @private Persistent store of all field validation errors originating from form-level validators.
281
+ * Maintains the cumulative state across validation cycles, including cleared errors (undefined values).
282
+ * This map preserves the complete validation state for all fields.
277
283
  */
278
- prevFieldsErrorMap: FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>;
284
+ cumulativeFieldsErrorMap: FormErrorMapFromValidator<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync>;
279
285
  /**
280
286
  * Constructs a new `FormApi` instance with the given form options.
281
287
  */
@@ -29,7 +29,7 @@ class FormApi {
29
29
  this.options = {};
30
30
  this.fieldInfo = {};
31
31
  this.prevTransformArray = [];
32
- this.prevFieldsErrorMap = {};
32
+ this.cumulativeFieldsErrorMap = {};
33
33
  this.mount = () => {
34
34
  const cleanupFieldMetaDerived = this.fieldMetaDerived.mount();
35
35
  const cleanupStoreDerived = this.store.mount();
@@ -43,12 +43,16 @@ class FormApi {
43
43
  return cleanup;
44
44
  };
45
45
  this.update = (options) => {
46
+ var _a2, _b;
46
47
  if (!options) return;
47
48
  const oldOptions = this.options;
48
49
  this.options = options;
50
+ const shouldUpdateReeval = !!((_b = (_a2 = options.transform) == null ? void 0 : _a2.deps) == null ? void 0 : _b.some(
51
+ (val, i) => val !== this.prevTransformArray[i]
52
+ ));
49
53
  const shouldUpdateValues = options.defaultValues && !shallow(options.defaultValues, oldOptions.defaultValues) && !this.state.isTouched;
50
54
  const shouldUpdateState = !shallow(options.defaultState, oldOptions.defaultState) && !this.state.isTouched;
51
- if (!shouldUpdateValues && !shouldUpdateState) return;
55
+ if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return;
52
56
  batch(() => {
53
57
  this.baseStore.setState(
54
58
  () => getDefaultFormState(
@@ -58,7 +62,8 @@ class FormApi {
58
62
  shouldUpdateState ? options.defaultState : {},
59
63
  shouldUpdateValues ? {
60
64
  values: options.defaultValues
61
- } : {}
65
+ } : {},
66
+ shouldUpdateReeval ? { _force_re_eval: !this.state._force_re_eval } : {}
62
67
  )
63
68
  )
64
69
  );
@@ -139,7 +144,7 @@ class FormApi {
139
144
  this.validateSync = (cause) => {
140
145
  const validates = getSyncValidatorArray(cause, this.options);
141
146
  let hasErrored = false;
142
- const newFieldsErrorMap = {};
147
+ const currentValidationErrorMap = {};
143
148
  batch(() => {
144
149
  var _a2;
145
150
  for (const validateObj of validates) {
@@ -157,12 +162,13 @@ class FormApi {
157
162
  const errorMapKey = getErrorMapKey(validateObj.cause);
158
163
  if (fieldErrors) {
159
164
  for (const [field, fieldError] of Object.entries(fieldErrors)) {
160
- const oldErrorMap = newFieldsErrorMap[field] || {};
165
+ const oldErrorMap = this.cumulativeFieldsErrorMap[field] || {};
161
166
  const newErrorMap = {
162
167
  ...oldErrorMap,
163
168
  [errorMapKey]: fieldError
164
169
  };
165
- newFieldsErrorMap[field] = newErrorMap;
170
+ currentValidationErrorMap[field] = newErrorMap;
171
+ this.cumulativeFieldsErrorMap[field] = newErrorMap;
166
172
  const fieldMeta = this.getFieldMeta(field);
167
173
  if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {
168
174
  this.setFieldMeta(field, (prev) => ({
@@ -175,9 +181,13 @@ class FormApi {
175
181
  }
176
182
  }
177
183
  }
178
- for (const field of Object.keys(this.prevFieldsErrorMap)) {
184
+ for (const field of Object.keys(this.cumulativeFieldsErrorMap)) {
179
185
  const fieldMeta = this.getFieldMeta(field);
180
- if ((fieldMeta == null ? void 0 : fieldMeta.errorMap[errorMapKey]) && !((_a2 = newFieldsErrorMap[field]) == null ? void 0 : _a2[errorMapKey])) {
186
+ if ((fieldMeta == null ? void 0 : fieldMeta.errorMap[errorMapKey]) && !((_a2 = currentValidationErrorMap[field]) == null ? void 0 : _a2[errorMapKey])) {
187
+ this.cumulativeFieldsErrorMap[field] = {
188
+ ...this.cumulativeFieldsErrorMap[field],
189
+ [errorMapKey]: void 0
190
+ };
181
191
  this.setFieldMeta(field, (prev) => ({
182
192
  ...prev,
183
193
  errorMap: {
@@ -211,8 +221,7 @@ class FormApi {
211
221
  }));
212
222
  }
213
223
  });
214
- this.prevFieldsErrorMap = newFieldsErrorMap;
215
- return { hasErrored, fieldsErrorMap: newFieldsErrorMap };
224
+ return { hasErrored, fieldsErrorMap: currentValidationErrorMap };
216
225
  };
217
226
  this.validateAsync = async (cause) => {
218
227
  const validates = getAsyncValidatorArray(cause, this.options);
@@ -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\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 map of errors originated from form level validators\n */\n prevFieldsErrorMap: 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 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) 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 ),\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 const newFieldsErrorMap: 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)) {\n const oldErrorMap =\n newFieldsErrorMap[field as DeepKeys<TFormData>] || {}\n const newErrorMap = {\n ...oldErrorMap,\n [errorMapKey]: fieldError,\n }\n newFieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap\n\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\n for (const field of Object.keys(this.prevFieldsErrorMap) as Array<\n DeepKeys<TFormData>\n >) {\n const fieldMeta = this.getFieldMeta(field)\n if (\n fieldMeta?.errorMap[errorMapKey] &&\n !newFieldsErrorMap[field]?.[errorMapKey]\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 this.prevFieldsErrorMap = newFieldsErrorMap\n\n return { hasErrored, fieldsErrorMap: newFieldsErrorMap }\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":["opts","_a","_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 * @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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/form-core",
3
- "version": "0.47.0",
3
+ "version": "0.47.2",
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
+ * @private, used to force a re-evaluation of the form state when options change
457
+ */
458
+ _force_re_eval?: boolean
455
459
  }
456
460
 
457
461
  export type DerivedFormState<
@@ -716,9 +720,11 @@ export class FormApi<
716
720
  prevTransformArray: unknown[] = []
717
721
 
718
722
  /**
719
- * @private map of errors originated from form level validators
723
+ * @private Persistent store of all field validation errors originating from form-level validators.
724
+ * Maintains the cumulative state across validation cycles, including cleared errors (undefined values).
725
+ * This map preserves the complete validation state for all fields.
720
726
  */
721
- prevFieldsErrorMap: FormErrorMapFromValidator<
727
+ cumulativeFieldsErrorMap: FormErrorMapFromValidator<
722
728
  TFormData,
723
729
  TOnMount,
724
730
  TOnChange,
@@ -1071,6 +1077,11 @@ export class FormApi<
1071
1077
  // Options need to be updated first so that when the store is updated, the state is correct for the derived state
1072
1078
  this.options = options
1073
1079
 
1080
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1081
+ const shouldUpdateReeval = !!options.transform?.deps?.some(
1082
+ (val, i) => val !== this.prevTransformArray[i],
1083
+ )
1084
+
1074
1085
  const shouldUpdateValues =
1075
1086
  options.defaultValues &&
1076
1087
  !shallow(options.defaultValues, oldOptions.defaultValues) &&
@@ -1080,7 +1091,7 @@ export class FormApi<
1080
1091
  !shallow(options.defaultState, oldOptions.defaultState) &&
1081
1092
  !this.state.isTouched
1082
1093
 
1083
- if (!shouldUpdateValues && !shouldUpdateState) return
1094
+ if (!shouldUpdateValues && !shouldUpdateState && !shouldUpdateReeval) return
1084
1095
 
1085
1096
  batch(() => {
1086
1097
  this.baseStore.setState(() =>
@@ -1096,6 +1107,10 @@ export class FormApi<
1096
1107
  values: options.defaultValues,
1097
1108
  }
1098
1109
  : {},
1110
+
1111
+ shouldUpdateReeval
1112
+ ? { _force_re_eval: !this.state._force_re_eval }
1113
+ : {},
1099
1114
  ),
1100
1115
  ),
1101
1116
  )
@@ -1243,7 +1258,8 @@ export class FormApi<
1243
1258
  const validates = getSyncValidatorArray(cause, this.options)
1244
1259
  let hasErrored = false as boolean
1245
1260
 
1246
- const newFieldsErrorMap: FormErrorMapFromValidator<
1261
+ // This map will only include fields that have errors in the current validation cycle
1262
+ const currentValidationErrorMap: FormErrorMapFromValidator<
1247
1263
  TFormData,
1248
1264
  TOnMount,
1249
1265
  TOnChange,
@@ -1273,18 +1289,21 @@ export class FormApi<
1273
1289
  const errorMapKey = getErrorMapKey(validateObj.cause)
1274
1290
 
1275
1291
  if (fieldErrors) {
1276
- for (const [field, fieldError] of Object.entries(fieldErrors)) {
1277
- const oldErrorMap =
1278
- newFieldsErrorMap[field as DeepKeys<TFormData>] || {}
1292
+ for (const [field, fieldError] of Object.entries(fieldErrors) as [
1293
+ DeepKeys<TFormData>,
1294
+ ValidationError,
1295
+ ][]) {
1296
+ const oldErrorMap = this.cumulativeFieldsErrorMap[field] || {}
1279
1297
  const newErrorMap = {
1280
1298
  ...oldErrorMap,
1281
1299
  [errorMapKey]: fieldError,
1282
1300
  }
1283
- newFieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap
1301
+ currentValidationErrorMap[field] = newErrorMap
1302
+ this.cumulativeFieldsErrorMap[field] = newErrorMap
1284
1303
 
1285
- const fieldMeta = this.getFieldMeta(field as DeepKeys<TFormData>)
1304
+ const fieldMeta = this.getFieldMeta(field)
1286
1305
  if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {
1287
- this.setFieldMeta(field as DeepKeys<TFormData>, (prev) => ({
1306
+ this.setFieldMeta(field, (prev) => ({
1288
1307
  ...prev,
1289
1308
  errorMap: {
1290
1309
  ...prev.errorMap,
@@ -1295,14 +1314,19 @@ export class FormApi<
1295
1314
  }
1296
1315
  }
1297
1316
 
1298
- for (const field of Object.keys(this.prevFieldsErrorMap) as Array<
1317
+ for (const field of Object.keys(this.cumulativeFieldsErrorMap) as Array<
1299
1318
  DeepKeys<TFormData>
1300
1319
  >) {
1301
1320
  const fieldMeta = this.getFieldMeta(field)
1302
1321
  if (
1303
1322
  fieldMeta?.errorMap[errorMapKey] &&
1304
- !newFieldsErrorMap[field]?.[errorMapKey]
1323
+ !currentValidationErrorMap[field]?.[errorMapKey]
1305
1324
  ) {
1325
+ this.cumulativeFieldsErrorMap[field] = {
1326
+ ...this.cumulativeFieldsErrorMap[field],
1327
+ [errorMapKey]: undefined,
1328
+ }
1329
+
1306
1330
  this.setFieldMeta(field, (prev) => ({
1307
1331
  ...prev,
1308
1332
  errorMap: {
@@ -1348,9 +1372,7 @@ export class FormApi<
1348
1372
  }
1349
1373
  })
1350
1374
 
1351
- this.prevFieldsErrorMap = newFieldsErrorMap
1352
-
1353
- return { hasErrored, fieldsErrorMap: newFieldsErrorMap }
1375
+ return { hasErrored, fieldsErrorMap: currentValidationErrorMap }
1354
1376
  }
1355
1377
 
1356
1378
  /**