@tanstack/form-core 0.23.3 → 0.24.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.
@@ -43,11 +43,7 @@ class FieldApi {
43
43
  }
44
44
  }
45
45
  return () => {
46
- const preserveValue = this.options.preserveValue;
47
46
  unsubscribe();
48
- if (!preserveValue) {
49
- this.form.deleteField(this.name);
50
- }
51
47
  };
52
48
  };
53
49
  this.update = (opts2) => {
@@ -62,9 +58,6 @@ class FieldApi {
62
58
  if (this._getMeta() === void 0) {
63
59
  this.setMeta(this.state.meta);
64
60
  }
65
- if (opts2.defaultValue === void 0 && this.form._tempDefaultValue !== void 0 && this.form._tempDefaultValue.field === this.name) {
66
- opts2.defaultValue = this.form._tempDefaultValue.value;
67
- }
68
61
  this.options = opts2;
69
62
  };
70
63
  this.getValue = () => {
@@ -292,9 +285,6 @@ class FieldApi {
292
285
  };
293
286
  this.form = opts.form;
294
287
  this.name = opts.name;
295
- if (opts.defaultValue === void 0 && this.form._tempDefaultValue !== void 0 && this.form._tempDefaultValue.field === this.name) {
296
- opts.defaultValue = this.form._tempDefaultValue.value;
297
- }
298
288
  if (opts.defaultValue !== void 0) {
299
289
  this.form.setFieldValue(this.name, opts.defaultValue);
300
290
  }
@@ -322,11 +312,6 @@ class FieldApi {
322
312
  state.meta.isPristine = !state.meta.isDirty;
323
313
  this.prevState = state;
324
314
  this.state = state;
325
- setTimeout(() => {
326
- if (this.form._tempDefaultValue !== void 0 && this.form._tempDefaultValue.field === this.name) {
327
- this.form._tempDefaultValue = void 0;
328
- }
329
- }, 0);
330
315
  }
331
316
  }
332
317
  );
@@ -1 +1 @@
1
- {"version":3,"file":"FieldApi.cjs","sources":["../../src/FieldApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport { getAsyncValidatorArray, getBy, getSyncValidatorArray } from './utils'\nimport type { FieldInfo, FormApi } from './FormApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n Validator,\n} from './types'\nimport type { AsyncValidator, SyncValidator, Updater } from './utils'\nimport type { DeepKeys, DeepValue, NoInfer } from './util-types'\n\n/**\n * @private\n */\nexport type FieldValidateFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (props: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n}) => ValidationError\n\n/**\n * @private\n */\nexport type FieldValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\n/**\n * @private\n */\nexport type FieldValidateAsyncFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (options: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\n/**\n * @private\n */\nexport type FieldAsyncValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\nexport interface FieldValidators<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * An optional function that takes a param of `formApi` which is a generic type of `TData` and `TParentData`\n */\n onMount?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property that takes a `ValidateFn` which is a generic of `TData` and `TParentData`.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onChange?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onChange` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onChangeAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional number to represent how long the `onChangeAsync` should wait before running\n *\n * 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 * An optional list of field names that should trigger this field's `onChange` and `onChangeAsync` events when its value changes\n */\n onChangeListenTo?: DeepKeys<TParentData>[]\n /**\n * An optional function, that when run when subscribing to blur event of input.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onBlur?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onBlur` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onBlurAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\n /**\n * An optional number to represent how long the `onBlurAsync` should wait before running\n *\n * 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 /**\n * An optional list of field names that should trigger this field's `onBlur` and `onBlurAsync` events when its value changes\n */\n onBlurListenTo?: DeepKeys<TParentData>[]\n /**\n * An optional function, that when run when subscribing to submit event of input.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onSubmit?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onSubmit` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onSubmitAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n}\n\n/**\n * An object type representing the options for a field in a form.\n */\nexport interface FieldOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.\n */\n name: TName\n /**\n * An optional default value for the field.\n */\n defaultValue?: NoInfer<TData>\n /**\n * The default time to debounce async validation if there is not a more specific debounce time passed.\n */\n asyncDebounceMs?: number\n /**\n * If `true`, always run async validation, even if there are errors emitted during synchronous validation.\n */\n asyncAlways?: boolean\n preserveValue?: boolean\n /**\n * A validator provided by an extension, like `yupValidator` from `@tanstack/yup-form-adapter`\n */\n validatorAdapter?: TFieldValidator\n /**\n * A list of validators to pass to the field\n */\n validators?: FieldValidators<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional object with default metadata for the field.\n */\n defaultMeta?: Partial<FieldMeta>\n}\n\n/**\n * An object type representing the required options for the FieldApi class.\n */\nexport interface FieldApiOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> extends FieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > {\n form: FormApi<TParentData, TFormValidator>\n}\n\n/**\n * An object type representing the metadata of a field in a form.\n */\nexport type FieldMeta = {\n /**\n * A flag indicating whether the field has been touched.\n */\n isTouched: boolean\n /**\n * A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.\n */\n isPristine: boolean\n /**\n * A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.\n */\n isDirty: boolean\n /**\n * An array of errors related to the touched state of the field.\n */\n touchedErrors: ValidationError[]\n /**\n * An array of errors related to the field value.\n */\n errors: ValidationError[]\n /**\n * A map of errors related to the field value.\n */\n errorMap: ValidationErrorMap\n /**\n * A flag indicating whether the field is currently being validated.\n */\n isValidating: boolean\n}\n\n/**\n * An object type representing the state of a field.\n */\nexport type FieldState<TData> = {\n /**\n * The current value of the field.\n */\n value: TData\n /**\n * The current metadata of the field.\n */\n meta: FieldMeta\n}\n\n/**\n * A class representing the API for managing a form field.\n *\n * Normally, you will not need to create a new `FieldApi` instance directly.\n * Instead, you will use a framework hook/function like `useField` or `createField`\n * 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\n * the `new FieldApi` constructor.\n */\nexport class FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * A reference to the form API instance.\n */\n form: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >['form']\n /**\n * The field name.\n */\n name!: DeepKeys<TParentData>\n /**\n * The field options.\n */\n options: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > = {} as any\n /**\n * The field state store.\n */\n store!: Store<FieldState<TData>>\n /**\n * The current field state.\n */\n state!: FieldState<TData>\n /**\n * @private\n */\n prevState!: FieldState<TData>\n\n /**\n * Initializes a new `FieldApi` instance.\n */\n constructor(\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) {\n this.form = opts.form as never\n this.name = opts.name as never\n\n if (\n opts.defaultValue === undefined &&\n this.form._tempDefaultValue !== undefined &&\n this.form._tempDefaultValue.field === this.name\n ) {\n opts.defaultValue = this.form._tempDefaultValue.value as never\n }\n\n if (opts.defaultValue !== undefined) {\n this.form.setFieldValue(this.name, opts.defaultValue as never)\n }\n\n this.store = new Store<FieldState<TData>>(\n {\n value: this.getValue(),\n\n meta: this._getMeta() ?? {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...opts.defaultMeta,\n },\n },\n {\n onUpdate: () => {\n const state = this.store.state\n\n state.meta.errors = Object.values(state.meta.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n\n state.meta.touchedErrors = state.meta.isTouched\n ? state.meta.errors\n : []\n\n state.meta.isPristine = !state.meta.isDirty\n\n this.prevState = state\n this.state = state\n\n // Cleanup the temp value after this \"tick\"\n // (Everything occurs sync otherwise)\n setTimeout(() => {\n if (\n this.form._tempDefaultValue !== undefined &&\n this.form._tempDefaultValue.field === this.name\n ) {\n this.form._tempDefaultValue = undefined\n }\n }, 0)\n },\n },\n )\n\n this.state = this.store.state\n this.prevState = this.state\n this.options = opts as never\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends { value: TData; fieldApi: FieldApi<any, any, any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FieldValidateOrFn<any, any, any, any>\n : FieldAsyncValidateOrFn<any, any, any, any>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapters = [\n this.form.options.validatorAdapter,\n this.options.validatorAdapter,\n ] as const\n for (const adapter of adapters) {\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](\n props.value as never,\n props.validate,\n ) as never\n }\n }\n\n return (props.validate as FieldValidateFn<any, any>)(props.value) as never\n }\n\n /**\n * Mounts the field instance to the form.\n */\n mount = () => {\n const info = this.getInfo()\n info.instance = this as never\n const unsubscribe = this.form.store.subscribe(() => {\n this.store.batch(() => {\n const nextValue = this.getValue()\n const nextMeta = this.getMeta()\n\n if (nextValue !== this.state.value) {\n this.store.setState((prev) => ({ ...prev, value: nextValue }))\n }\n\n if (nextMeta !== this.state.meta) {\n this.store.setState((prev) => ({ ...prev, meta: nextMeta }))\n }\n })\n })\n\n this.update(this.options as never)\n const { onMount } = this.options.validators || {}\n\n if (onMount) {\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.value,\n fieldApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.setMeta((prev) => ({\n ...prev,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n errorMap: { ...prev?.errorMap, onMount: error },\n }))\n }\n }\n\n return () => {\n const preserveValue = this.options.preserveValue\n unsubscribe()\n if (!preserveValue) {\n this.form.deleteField(this.name)\n }\n }\n }\n\n /**\n * Updates the field instance with new options.\n */\n update = (\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => {\n // Default Value\n\n if (this.state.value === undefined) {\n const formDefault = getBy(opts.form.options.defaultValues, opts.name)\n\n if (opts.defaultValue !== undefined) {\n this.setValue(opts.defaultValue as never)\n } else if (formDefault !== undefined) {\n this.setValue(formDefault as never)\n }\n }\n\n // Default Meta\n if (this._getMeta() === undefined) {\n this.setMeta(this.state.meta)\n }\n\n if (\n opts.defaultValue === undefined &&\n this.form._tempDefaultValue !== undefined &&\n this.form._tempDefaultValue.field === this.name\n ) {\n opts.defaultValue = this.form._tempDefaultValue.value as never\n }\n\n this.options = opts as never\n }\n\n /**\n * Gets the current field value.\n */\n getValue = (): TData => {\n return this.form.getFieldValue(this.name) as TData\n }\n\n /**\n * Sets the field value and run the `change` validator.\n */\n setValue = (\n updater: Updater<TData>,\n options?: { touch?: boolean; notify?: boolean },\n ) => {\n this.form.setFieldValue(this.name, updater as never, options)\n this.validate('change')\n }\n\n /**\n * @private\n */\n _getMeta = () => this.form.getFieldMeta(this.name)\n\n /**\n * Gets the current field metadata.\n */\n getMeta = () =>\n this._getMeta() ??\n ({\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...this.options.defaultMeta,\n } as FieldMeta)\n\n /**\n * Sets the field metadata.\n */\n setMeta = (updater: Updater<FieldMeta>) =>\n this.form.setFieldMeta(this.name, updater)\n\n /**\n * Gets the field information object.\n */\n getInfo = () => this.form.getFieldInfo(this.name)\n\n /**\n * Pushes a new value to the field.\n */\n pushValue = (\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.pushFieldValue(this.name, value as any, opts)\n\n /**\n * Inserts a value at the specified index, shifting the subsequent values to the right.\n */\n insertValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.insertFieldValue(this.name, index, value as any, opts)\n\n /**\n * Replaces a value at the specified index.\n */\n replaceValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.replaceFieldValue(this.name, index, value as any, opts)\n\n /**\n * Removes a value at the specified index.\n */\n removeValue = (index: number, opts?: { touch: boolean }) =>\n this.form.removeFieldValue(this.name, index, opts)\n\n /**\n * Swaps the values at the specified indices.\n */\n swapValues = (aIndex: number, bIndex: number, opts?: { touch?: boolean }) =>\n this.form.swapFieldValues(this.name, aIndex, bIndex, opts)\n\n /**\n * Moves the value at the first specified index to the second specified index.\n */\n moveValue = (aIndex: number, bIndex: number, opts?: { touch?: boolean }) =>\n this.form.moveFieldValues(this.name, aIndex, bIndex, opts)\n\n /**\n * @private\n */\n getLinkedFields = (cause: ValidationCause) => {\n const fields = Object.values(this.form.fieldInfo) as FieldInfo<\n any,\n TFormValidator\n >[]\n\n const linkedFields: FieldApi<any, any, any, any>[] = []\n for (const field of fields) {\n if (!field.instance) continue\n const { onChangeListenTo, onBlurListenTo } =\n field.instance.options.validators || {}\n if (\n cause === 'change' &&\n onChangeListenTo?.includes(this.name as string)\n ) {\n linkedFields.push(field.instance)\n }\n if (cause === 'blur' && onBlurListenTo?.includes(this.name as string)) {\n linkedFields.push(field.instance)\n }\n }\n\n return linkedFields\n }\n\n /**\n * @private\n */\n validateSync = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getSyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<SyncValidator<any> & { field: FieldApi<any, any, any, any> }>,\n )\n\n // Needs type cast as eslint errantly believes this is always falsy\n let hasErrored = false as boolean\n\n this.form.store.batch(() => {\n const validateFieldFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: SyncValidator<any>,\n ) => {\n const error = normalizeError(\n field.runValidator({\n validate: validateObj.validate,\n value: { value: field.getValue(), fieldApi: field },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (field.state.meta.errorMap[errorMapKey] !== error) {\n field.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(validateObj.cause)]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\n }\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldFn(this, validateObj)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldFn(fieldValitateObj.field, fieldValitateObj)\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.meta.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n /**\n * @private\n */\n validateAsync = async (cause: ValidationCause) => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getAsyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<\n AsyncValidator<any> & { field: FieldApi<any, any, any, any> }\n >,\n )\n\n if (!this.state.meta.isValidating) {\n this.setMeta((prev) => ({ ...prev, isValidating: true }))\n }\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: 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 validatesPromises: Promise<ValidationError | undefined>[] = []\n const linkedPromises: Promise<ValidationError | undefined>[] = []\n\n const validateFieldAsyncFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: AsyncValidator<any>,\n promises: Promise<ValidationError | undefined>[],\n ) => {\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = field.getInfo().validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.getInfo().validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | 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: field.getValue(),\n fieldApi: field,\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 error = normalizeError(rawError)\n field.setMeta((prev) => {\n return {\n ...prev,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }\n })\n\n resolve(error)\n }),\n )\n }\n\n // TODO: Dedupe this logic to reduce bundle size\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldAsyncFn(this, validateObj, validatesPromises)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldAsyncFn(\n fieldValitateObj.field,\n fieldValitateObj,\n linkedPromises,\n )\n }\n\n let results: ValidationError[] = []\n if (validatesPromises.length || linkedPromises.length) {\n results = await Promise.all(validatesPromises)\n await Promise.all(linkedPromises)\n }\n\n this.setMeta((prev) => ({ ...prev, isValidating: false }))\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: false }))\n }\n\n return results.filter(Boolean)\n }\n\n /**\n * Validates the field value.\n */\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // If the field is pristine and validatePristine is false, do not validate\n if (!this.state.meta.isTouched) return []\n\n try {\n this.form.validate(cause)\n } catch (_) {}\n\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.meta.errors\n }\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n /**\n * Handles the change event.\n */\n handleChange = (updater: Updater<TData>) => {\n this.setValue(updater, { touch: true })\n }\n\n /**\n * Handles the blur event.\n */\n handleBlur = () => {\n const prevTouched = this.state.meta.isTouched\n if (!prevTouched) {\n this.setMeta((prev) => ({ ...prev, isTouched: true }))\n this.validate('change')\n }\n this.validate('blur')\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return 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","getBy","getSyncValidatorArray","getAsyncValidatorArray","Store"],"mappings":"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"}
1
+ {"version":3,"file":"FieldApi.cjs","sources":["../../src/FieldApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport { getAsyncValidatorArray, getBy, getSyncValidatorArray } from './utils'\nimport type { FieldInfo, FormApi } from './FormApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n Validator,\n} from './types'\nimport type { AsyncValidator, SyncValidator, Updater } from './utils'\nimport type { DeepKeys, DeepValue, NoInfer } from './util-types'\n\n/**\n * @private\n */\nexport type FieldValidateFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (props: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n}) => ValidationError\n\n/**\n * @private\n */\nexport type FieldValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\n/**\n * @private\n */\nexport type FieldValidateAsyncFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (options: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\n/**\n * @private\n */\nexport type FieldAsyncValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\nexport interface FieldValidators<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * An optional function that takes a param of `formApi` which is a generic type of `TData` and `TParentData`\n */\n onMount?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property that takes a `ValidateFn` which is a generic of `TData` and `TParentData`.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onChange?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onChange` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onChangeAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional number to represent how long the `onChangeAsync` should wait before running\n *\n * 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 * An optional list of field names that should trigger this field's `onChange` and `onChangeAsync` events when its value changes\n */\n onChangeListenTo?: DeepKeys<TParentData>[]\n /**\n * An optional function, that when run when subscribing to blur event of input.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onBlur?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onBlur` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onBlurAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\n /**\n * An optional number to represent how long the `onBlurAsync` should wait before running\n *\n * 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 /**\n * An optional list of field names that should trigger this field's `onBlur` and `onBlurAsync` events when its value changes\n */\n onBlurListenTo?: DeepKeys<TParentData>[]\n /**\n * An optional function, that when run when subscribing to submit event of input.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onSubmit?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onSubmit` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onSubmitAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n}\n\n/**\n * An object type representing the options for a field in a form.\n */\nexport interface FieldOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.\n */\n name: TName\n /**\n * An optional default value for the field.\n */\n defaultValue?: NoInfer<TData>\n /**\n * The default time to debounce async validation if there is not a more specific debounce time passed.\n */\n asyncDebounceMs?: number\n /**\n * If `true`, always run async validation, even if there are errors emitted during synchronous validation.\n */\n asyncAlways?: boolean\n /**\n * A validator provided by an extension, like `yupValidator` from `@tanstack/yup-form-adapter`\n */\n validatorAdapter?: TFieldValidator\n /**\n * A list of validators to pass to the field\n */\n validators?: FieldValidators<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional object with default metadata for the field.\n */\n defaultMeta?: Partial<FieldMeta>\n}\n\n/**\n * An object type representing the required options for the FieldApi class.\n */\nexport interface FieldApiOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> extends FieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > {\n form: FormApi<TParentData, TFormValidator>\n}\n\n/**\n * An object type representing the metadata of a field in a form.\n */\nexport type FieldMeta = {\n /**\n * A flag indicating whether the field has been touched.\n */\n isTouched: boolean\n /**\n * A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.\n */\n isPristine: boolean\n /**\n * A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.\n */\n isDirty: boolean\n /**\n * An array of errors related to the touched state of the field.\n */\n touchedErrors: ValidationError[]\n /**\n * An array of errors related to the field value.\n */\n errors: ValidationError[]\n /**\n * A map of errors related to the field value.\n */\n errorMap: ValidationErrorMap\n /**\n * A flag indicating whether the field is currently being validated.\n */\n isValidating: boolean\n}\n\n/**\n * An object type representing the state of a field.\n */\nexport type FieldState<TData> = {\n /**\n * The current value of the field.\n */\n value: TData\n /**\n * The current metadata of the field.\n */\n meta: FieldMeta\n}\n\n/**\n * A class representing the API for managing a form field.\n *\n * Normally, you will not need to create a new `FieldApi` instance directly.\n * Instead, you will use a framework hook/function like `useField` or `createField`\n * 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\n * the `new FieldApi` constructor.\n */\nexport class FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * A reference to the form API instance.\n */\n form: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >['form']\n /**\n * The field name.\n */\n name!: DeepKeys<TParentData>\n /**\n * The field options.\n */\n options: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > = {} as any\n /**\n * The field state store.\n */\n store!: Store<FieldState<TData>>\n /**\n * The current field state.\n */\n state!: FieldState<TData>\n /**\n * @private\n */\n prevState!: FieldState<TData>\n\n /**\n * Initializes a new `FieldApi` instance.\n */\n constructor(\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) {\n this.form = opts.form as never\n this.name = opts.name as never\n\n if (opts.defaultValue !== undefined) {\n this.form.setFieldValue(this.name, opts.defaultValue as never)\n }\n\n this.store = new Store<FieldState<TData>>(\n {\n value: this.getValue(),\n\n meta: this._getMeta() ?? {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...opts.defaultMeta,\n },\n },\n {\n onUpdate: () => {\n const state = this.store.state\n\n state.meta.errors = Object.values(state.meta.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n\n state.meta.touchedErrors = state.meta.isTouched\n ? state.meta.errors\n : []\n\n state.meta.isPristine = !state.meta.isDirty\n\n this.prevState = state\n this.state = state\n },\n },\n )\n\n this.state = this.store.state\n this.prevState = this.state\n this.options = opts as never\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends { value: TData; fieldApi: FieldApi<any, any, any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FieldValidateOrFn<any, any, any, any>\n : FieldAsyncValidateOrFn<any, any, any, any>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapters = [\n this.form.options.validatorAdapter,\n this.options.validatorAdapter,\n ] as const\n for (const adapter of adapters) {\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](\n props.value as never,\n props.validate,\n ) as never\n }\n }\n\n return (props.validate as FieldValidateFn<any, any>)(props.value) as never\n }\n\n /**\n * Mounts the field instance to the form.\n */\n mount = () => {\n const info = this.getInfo()\n info.instance = this as never\n const unsubscribe = this.form.store.subscribe(() => {\n this.store.batch(() => {\n const nextValue = this.getValue()\n const nextMeta = this.getMeta()\n\n if (nextValue !== this.state.value) {\n this.store.setState((prev) => ({ ...prev, value: nextValue }))\n }\n\n if (nextMeta !== this.state.meta) {\n this.store.setState((prev) => ({ ...prev, meta: nextMeta }))\n }\n })\n })\n\n this.update(this.options as never)\n const { onMount } = this.options.validators || {}\n\n if (onMount) {\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.value,\n fieldApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.setMeta((prev) => ({\n ...prev,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n errorMap: { ...prev?.errorMap, onMount: error },\n }))\n }\n }\n\n return () => {\n unsubscribe()\n }\n }\n\n /**\n * Updates the field instance with new options.\n */\n update = (\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => {\n // Default Value\n\n if (this.state.value === undefined) {\n const formDefault = getBy(opts.form.options.defaultValues, opts.name)\n\n if (opts.defaultValue !== undefined) {\n this.setValue(opts.defaultValue as never)\n } else if (formDefault !== undefined) {\n this.setValue(formDefault as never)\n }\n }\n\n // Default Meta\n if (this._getMeta() === undefined) {\n this.setMeta(this.state.meta)\n }\n\n this.options = opts as never\n }\n\n /**\n * Gets the current field value.\n */\n getValue = (): TData => {\n return this.form.getFieldValue(this.name) as TData\n }\n\n /**\n * Sets the field value and run the `change` validator.\n */\n setValue = (\n updater: Updater<TData>,\n options?: { touch?: boolean; notify?: boolean },\n ) => {\n this.form.setFieldValue(this.name, updater as never, options)\n this.validate('change')\n }\n\n /**\n * @private\n */\n _getMeta = () => this.form.getFieldMeta(this.name)\n\n /**\n * Gets the current field metadata.\n */\n getMeta = () =>\n this._getMeta() ??\n ({\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...this.options.defaultMeta,\n } as FieldMeta)\n\n /**\n * Sets the field metadata.\n */\n setMeta = (updater: Updater<FieldMeta>) =>\n this.form.setFieldMeta(this.name, updater)\n\n /**\n * Gets the field information object.\n */\n getInfo = () => this.form.getFieldInfo(this.name)\n\n /**\n * Pushes a new value to the field.\n */\n pushValue = (\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.pushFieldValue(this.name, value as any, opts)\n\n /**\n * Inserts a value at the specified index, shifting the subsequent values to the right.\n */\n insertValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.insertFieldValue(this.name, index, value as any, opts)\n\n /**\n * Replaces a value at the specified index.\n */\n replaceValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.replaceFieldValue(this.name, index, value as any, opts)\n\n /**\n * Removes a value at the specified index.\n */\n removeValue = (index: number, opts?: { touch: boolean }) =>\n this.form.removeFieldValue(this.name, index, opts)\n\n /**\n * Swaps the values at the specified indices.\n */\n swapValues = (aIndex: number, bIndex: number, opts?: { touch?: boolean }) =>\n this.form.swapFieldValues(this.name, aIndex, bIndex, opts)\n\n /**\n * Moves the value at the first specified index to the second specified index.\n */\n moveValue = (aIndex: number, bIndex: number, opts?: { touch?: boolean }) =>\n this.form.moveFieldValues(this.name, aIndex, bIndex, opts)\n\n /**\n * @private\n */\n getLinkedFields = (cause: ValidationCause) => {\n const fields = Object.values(this.form.fieldInfo) as FieldInfo<\n any,\n TFormValidator\n >[]\n\n const linkedFields: FieldApi<any, any, any, any>[] = []\n for (const field of fields) {\n if (!field.instance) continue\n const { onChangeListenTo, onBlurListenTo } =\n field.instance.options.validators || {}\n if (\n cause === 'change' &&\n onChangeListenTo?.includes(this.name as string)\n ) {\n linkedFields.push(field.instance)\n }\n if (cause === 'blur' && onBlurListenTo?.includes(this.name as string)) {\n linkedFields.push(field.instance)\n }\n }\n\n return linkedFields\n }\n\n /**\n * @private\n */\n validateSync = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getSyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<SyncValidator<any> & { field: FieldApi<any, any, any, any> }>,\n )\n\n // Needs type cast as eslint errantly believes this is always falsy\n let hasErrored = false as boolean\n\n this.form.store.batch(() => {\n const validateFieldFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: SyncValidator<any>,\n ) => {\n const error = normalizeError(\n field.runValidator({\n validate: validateObj.validate,\n value: { value: field.getValue(), fieldApi: field },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (field.state.meta.errorMap[errorMapKey] !== error) {\n field.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(validateObj.cause)]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\n }\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldFn(this, validateObj)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldFn(fieldValitateObj.field, fieldValitateObj)\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.meta.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n /**\n * @private\n */\n validateAsync = async (cause: ValidationCause) => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getAsyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<\n AsyncValidator<any> & { field: FieldApi<any, any, any, any> }\n >,\n )\n\n if (!this.state.meta.isValidating) {\n this.setMeta((prev) => ({ ...prev, isValidating: true }))\n }\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: 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 validatesPromises: Promise<ValidationError | undefined>[] = []\n const linkedPromises: Promise<ValidationError | undefined>[] = []\n\n const validateFieldAsyncFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: AsyncValidator<any>,\n promises: Promise<ValidationError | undefined>[],\n ) => {\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = field.getInfo().validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.getInfo().validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | 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: field.getValue(),\n fieldApi: field,\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 error = normalizeError(rawError)\n field.setMeta((prev) => {\n return {\n ...prev,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }\n })\n\n resolve(error)\n }),\n )\n }\n\n // TODO: Dedupe this logic to reduce bundle size\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldAsyncFn(this, validateObj, validatesPromises)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldAsyncFn(\n fieldValitateObj.field,\n fieldValitateObj,\n linkedPromises,\n )\n }\n\n let results: ValidationError[] = []\n if (validatesPromises.length || linkedPromises.length) {\n results = await Promise.all(validatesPromises)\n await Promise.all(linkedPromises)\n }\n\n this.setMeta((prev) => ({ ...prev, isValidating: false }))\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: false }))\n }\n\n return results.filter(Boolean)\n }\n\n /**\n * Validates the field value.\n */\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // If the field is pristine and validatePristine is false, do not validate\n if (!this.state.meta.isTouched) return []\n\n try {\n this.form.validate(cause)\n } catch (_) {}\n\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.meta.errors\n }\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n /**\n * Handles the change event.\n */\n handleChange = (updater: Updater<TData>) => {\n this.setValue(updater, { touch: true })\n }\n\n /**\n * Handles the blur event.\n */\n handleBlur = () => {\n const prevTouched = this.state.meta.isTouched\n if (!prevTouched) {\n this.setMeta((prev) => ({ ...prev, isTouched: true }))\n this.validate('change')\n }\n this.validate('blur')\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return 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","getBy","getSyncValidatorArray","getAsyncValidatorArray","Store"],"mappings":";;;;AA+XO,MAAM,SAUX;AAAA;AAAA;AAAA;AAAA,EAyCA,YACE,MAOA;AA/BF,SAAA,UAMI;AAyGJ,SAAA,QAAQ,MAAM;AACN,YAAA,OAAO,KAAK;AAClB,WAAK,WAAW;AAChB,YAAM,cAAc,KAAK,KAAK,MAAM,UAAU,MAAM;AAC7C,aAAA,MAAM,MAAM,MAAM;AACf,gBAAA,YAAY,KAAK;AACjB,gBAAA,WAAW,KAAK;AAElB,cAAA,cAAc,KAAK,MAAM,OAAO;AAC7B,iBAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,UAAY,EAAA;AAAA,UAC/D;AAEI,cAAA,aAAa,KAAK,MAAM,MAAM;AAC3B,iBAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,SAAW,EAAA;AAAA,UAC7D;AAAA,QAAA,CACD;AAAA,MAAA,CACF;AAEI,WAAA,OAAO,KAAK,OAAgB;AACjC,YAAM,EAAE,QAAQ,IAAI,KAAK,QAAQ,cAAc,CAAA;AAE/C,UAAI,SAAS;AACL,cAAA,QAAQ,KAAK,aAAa;AAAA,UAC9B,UAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAO,KAAK,MAAM;AAAA,YAClB,UAAU;AAAA,UACZ;AAAA,UACA,MAAM;AAAA,QAAA,CACP;AACD,YAAI,OAAO;AACJ,eAAA,QAAQ,CAAC,UAAU;AAAA,YACtB,GAAG;AAAA;AAAA,YAEH,UAAU,EAAE,GAAG,6BAAM,UAAU,SAAS,MAAM;AAAA,UAC9C,EAAA;AAAA,QACJ;AAAA,MACF;AAEA,aAAO,MAAM;AACC;MAAA;AAAA,IACd;AAMF,SAAA,SAAS,CACPA,UAOG;AAGC,UAAA,KAAK,MAAM,UAAU,QAAW;AAClC,cAAM,cAAcC,MAAM,MAAAD,MAAK,KAAK,QAAQ,eAAeA,MAAK,IAAI;AAEhE,YAAAA,MAAK,iBAAiB,QAAW;AAC9B,eAAA,SAASA,MAAK,YAAqB;AAAA,QAAA,WAC/B,gBAAgB,QAAW;AACpC,eAAK,SAAS,WAAoB;AAAA,QACpC;AAAA,MACF;AAGI,UAAA,KAAK,eAAe,QAAW;AAC5B,aAAA,QAAQ,KAAK,MAAM,IAAI;AAAA,MAC9B;AAEA,WAAK,UAAUA;AAAA,IAAA;AAMjB,SAAA,WAAW,MAAa;AACtB,aAAO,KAAK,KAAK,cAAc,KAAK,IAAI;AAAA,IAAA;AAM/B,SAAA,WAAA,CACT,SACA,YACG;AACH,WAAK,KAAK,cAAc,KAAK,MAAM,SAAkB,OAAO;AAC5D,WAAK,SAAS,QAAQ;AAAA,IAAA;AAMxB,SAAA,WAAW,MAAM,KAAK,KAAK,aAAa,KAAK,IAAI;AAKvC,SAAA,UAAA,MACR,KAAK,SAAA,KACJ;AAAA,MACC,cAAc;AAAA,MACd,WAAW;AAAA,MACX,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,eAAe,CAAC;AAAA,MAChB,QAAQ,CAAC;AAAA,MACT,UAAU,CAAC;AAAA,MACX,GAAG,KAAK,QAAQ;AAAA,IAAA;AAMpB,SAAA,UAAU,CAAC,YACT,KAAK,KAAK,aAAa,KAAK,MAAM,OAAO;AAK3C,SAAA,UAAU,MAAM,KAAK,KAAK,aAAa,KAAK,IAAI;AAKpC,SAAA,YAAA,CACV,OACAA,UACG,KAAK,KAAK,eAAe,KAAK,MAAM,OAAcA,KAAI;AAK7C,SAAA,cAAA,CACZ,OACA,OACAA,UACG,KAAK,KAAK,iBAAiB,KAAK,MAAM,OAAO,OAAcA,KAAI;AAKrD,SAAA,eAAA,CACb,OACA,OACAA,UACG,KAAK,KAAK,kBAAkB,KAAK,MAAM,OAAO,OAAcA,KAAI;AAKvD,SAAA,cAAA,CAAC,OAAeA,UAC5B,KAAK,KAAK,iBAAiB,KAAK,MAAM,OAAOA,KAAI;AAKtC,SAAA,aAAA,CAAC,QAAgB,QAAgBA,UAC5C,KAAK,KAAK,gBAAgB,KAAK,MAAM,QAAQ,QAAQA,KAAI;AAK/C,SAAA,YAAA,CAAC,QAAgB,QAAgBA,UAC3C,KAAK,KAAK,gBAAgB,KAAK,MAAM,QAAQ,QAAQA,KAAI;AAK3D,SAAA,kBAAkB,CAAC,UAA2B;AAC5C,YAAM,SAAS,OAAO,OAAO,KAAK,KAAK,SAAS;AAKhD,YAAM,eAA+C,CAAA;AACrD,iBAAW,SAAS,QAAQ;AAC1B,YAAI,CAAC,MAAM;AAAU;AACf,cAAA,EAAE,kBAAkB,mBACxB,MAAM,SAAS,QAAQ,cAAc;AACvC,YACE,UAAU,aACV,qDAAkB,SAAS,KAAK,QAChC;AACa,uBAAA,KAAK,MAAM,QAAQ;AAAA,QAClC;AACA,YAAI,UAAU,WAAU,iDAAgB,SAAS,KAAK,QAAiB;AACxD,uBAAA,KAAK,MAAM,QAAQ;AAAA,QAClC;AAAA,MACF;AAEO,aAAA;AAAA,IAAA;AAMT,SAAA,eAAe,CAAC,UAA2B;AACzC,YAAM,YAAYE,MAAA,sBAAsB,OAAO,KAAK,OAAO;AAErD,YAAA,eAAe,KAAK,gBAAgB,KAAK;AAC/C,YAAM,uBAAuB,aAAa;AAAA,QACxC,CAAC,KAAK,UAAU;AACd,gBAAM,iBAAiBA,MAAA,sBAAsB,OAAO,MAAM,OAAO;AAClD,yBAAA,QAAQ,CAAC,aAAa;AACjC,qBAAiB,QAAQ;AAAA,UAAA,CAC5B;AACM,iBAAA,IAAI,OAAO,cAAuB;AAAA,QAC3C;AAAA,QACA,CAAC;AAAA,MAAA;AAIH,UAAI,aAAa;AAEZ,WAAA,KAAK,MAAM,MAAM,MAAM;AACpB,cAAA,kBAAkB,CACtB,OACA,gBACG;AACH,gBAAM,QAAQ;AAAA,YACZ,MAAM,aAAa;AAAA,cACjB,UAAU,YAAY;AAAA,cACtB,OAAO,EAAE,OAAO,MAAM,SAAS,GAAG,UAAU,MAAM;AAAA,cAClD,MAAM;AAAA,YAAA,CACP;AAAA,UAAA;AAEG,gBAAA,cAAc,eAAe,YAAY,KAAK;AACpD,cAAI,MAAM,MAAM,KAAK,SAAS,WAAW,MAAM,OAAO;AAC9C,kBAAA,QAAQ,CAAC,UAAU;AAAA,cACvB,GAAG;AAAA,cACH,UAAU;AAAA,gBACR,GAAG,KAAK;AAAA,gBACR,CAAC,eAAe,YAAY,KAAK,CAAC,GAAG;AAAA,cACvC;AAAA,YACA,EAAA;AAAA,UACJ;AACA,cAAI,OAAO;AACI,yBAAA;AAAA,UACf;AAAA,QAAA;AAGF,mBAAW,eAAe,WAAW;AACnC,cAAI,CAAC,YAAY;AAAU;AAC3B,0BAAgB,MAAM,WAAW;AAAA,QACnC;AACA,mBAAW,oBAAoB,sBAAsB;AACnD,cAAI,CAAC,iBAAiB;AAAU;AAChB,0BAAA,iBAAiB,OAAO,gBAAgB;AAAA,QAC1D;AAAA,MAAA,CACD;AAMK,YAAA,eAAe,eAAe,QAAQ;AAE1C,UAAA,KAAK,MAAM,KAAK,SAAS,YAAY,KACrC,UAAU,YACV,CAAC,YACD;AACK,aAAA,QAAQ,CAAC,UAAU;AAAA,UACtB,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,KAAK;AAAA,YACR,CAAC,YAAY,GAAG;AAAA,UAClB;AAAA,QACA,EAAA;AAAA,MACJ;AAEA,aAAO,EAAE,WAAW;AAAA,IAAA;AAMtB,SAAA,gBAAgB,OAAO,UAA2B;AAChD,YAAM,YAAYC,MAAA,uBAAuB,OAAO,KAAK,OAAO;AAEtD,YAAA,eAAe,KAAK,gBAAgB,KAAK;AAC/C,YAAM,uBAAuB,aAAa;AAAA,QACxC,CAAC,KAAK,UAAU;AACd,gBAAM,iBAAiBA,MAAA,uBAAuB,OAAO,MAAM,OAAO;AACnD,yBAAA,QAAQ,CAAC,aAAa;AACjC,qBAAiB,QAAQ;AAAA,UAAA,CAC5B;AACM,iBAAA,IAAI,OAAO,cAAuB;AAAA,QAC3C;AAAA,QACA,CAAC;AAAA,MAAA;AAKH,UAAI,CAAC,KAAK,MAAM,KAAK,cAAc;AAC5B,aAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,KAAO,EAAA;AAAA,MAC1D;AAEA,iBAAW,eAAe,cAAc;AAC1B,oBAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,KAAO,EAAA;AAAA,MACjE;AAMA,YAAM,oBAA4D,CAAA;AAClE,YAAM,iBAAyD,CAAA;AAE/D,YAAM,uBAAuB,CAC3B,OACA,aACA,aACG;AACG,cAAA,MAAM,eAAe,YAAY,KAAK;AAC5C,cAAM,qBAAqB,MAAM,QAAQ,EAAE,kBAAkB,GAAG;AAEhE,iEAAoB,oBAAoB;AAClC,cAAA,aAAa,IAAI;AAEvB,aAAK,QAAQ,EAAE,kBAAkB,GAAG,IAAI;AAAA,UACtC,qBAAqB;AAAA,QAAA;AAGd,iBAAA;AAAA,UACP,IAAI,QAAqC,OAAO,YAAY;AACtD,gBAAA;AACA,gBAAA;AACF,yBAAW,MAAM,IAAI,QAAQ,CAAC,YAAY,cAAc;AACtD,2BAAW,YAAY;AACrB,sBAAI,WAAW,OAAO;AAAS,2BAAO,WAAW,MAAS;AACtD,sBAAA;AACF;AAAA,sBACE,MAAM,KAAK,aAAa;AAAA,wBACtB,UAAU,YAAY;AAAA,wBACtB,OAAO;AAAA,0BACL,OAAO,MAAM,SAAS;AAAA,0BACtB,UAAU;AAAA,0BACV,QAAQ,WAAW;AAAA,wBACrB;AAAA,wBACA,MAAM;AAAA,sBAAA,CACP;AAAA,oBAAA;AAAA,2BAEI,GAAG;AACV,8BAAU,CAAC;AAAA,kBACb;AAAA,gBAAA,GACC,YAAY,UAAU;AAAA,cAAA,CAC1B;AAAA,qBACM,GAAY;AACR,yBAAA;AAAA,YACb;AACM,kBAAA,QAAQ,eAAe,QAAQ;AAC/B,kBAAA,QAAQ,CAAC,SAAS;AACf,qBAAA;AAAA,gBACL,GAAG;AAAA,gBACH,UAAU;AAAA;AAAA,kBAER,GAAG,6BAAM;AAAA,kBACT,CAAC,eAAe,KAAK,CAAC,GAAG;AAAA,gBAC3B;AAAA,cAAA;AAAA,YACF,CACD;AAED,oBAAQ,KAAK;AAAA,UAAA,CACd;AAAA,QAAA;AAAA,MACH;AAIF,iBAAW,eAAe,WAAW;AACnC,YAAI,CAAC,YAAY;AAAU;AACN,6BAAA,MAAM,aAAa,iBAAiB;AAAA,MAC3D;AACA,iBAAW,oBAAoB,sBAAsB;AACnD,YAAI,CAAC,iBAAiB;AAAU;AAChC;AAAA,UACE,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAEA,UAAI,UAA6B,CAAA;AAC7B,UAAA,kBAAkB,UAAU,eAAe,QAAQ;AAC3C,kBAAA,MAAM,QAAQ,IAAI,iBAAiB;AACvC,cAAA,QAAQ,IAAI,cAAc;AAAA,MAClC;AAEK,WAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,MAAQ,EAAA;AAEzD,iBAAW,eAAe,cAAc;AAC1B,oBAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,MAAQ,EAAA;AAAA,MAClE;AAEO,aAAA,QAAQ,OAAO,OAAO;AAAA,IAAA;AAM/B,SAAA,WAAW,CACT,UACmD;AAE/C,UAAA,CAAC,KAAK,MAAM,KAAK;AAAW,eAAO;AAEnC,UAAA;AACG,aAAA,KAAK,SAAS,KAAK;AAAA,eACjB,GAAG;AAAA,MAAC;AAGb,YAAM,EAAE,WAAe,IAAA,KAAK,aAAa,KAAK;AAE9C,UAAI,cAAc,CAAC,KAAK,QAAQ,aAAa;AACpC,eAAA,KAAK,MAAM,KAAK;AAAA,MACzB;AAEO,aAAA,KAAK,cAAc,KAAK;AAAA,IAAA;AAMjC,SAAA,eAAe,CAAC,YAA4B;AAC1C,WAAK,SAAS,SAAS,EAAE,OAAO,KAAM,CAAA;AAAA,IAAA;AAMxC,SAAA,aAAa,MAAM;AACX,YAAA,cAAc,KAAK,MAAM,KAAK;AACpC,UAAI,CAAC,aAAa;AACX,aAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,KAAO,EAAA;AACrD,aAAK,SAAS,QAAQ;AAAA,MACxB;AACA,WAAK,SAAS,MAAM;AAAA,IAAA;AAvgBpB,SAAK,OAAO,KAAK;AACjB,SAAK,OAAO,KAAK;AAEb,QAAA,KAAK,iBAAiB,QAAW;AACnC,WAAK,KAAK,cAAc,KAAK,MAAM,KAAK,YAAqB;AAAA,IAC/D;AAEA,SAAK,QAAQ,IAAIC,MAAA;AAAA,MACf;AAAA,QACE,OAAO,KAAK,SAAS;AAAA,QAErB,MAAM,KAAK,cAAc;AAAA,UACvB,cAAc;AAAA,UACd,WAAW;AAAA,UACX,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,eAAe,CAAC;AAAA,UAChB,QAAQ,CAAC;AAAA,UACT,UAAU,CAAC;AAAA,UACX,GAAG,KAAK;AAAA,QACV;AAAA,MACF;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACR,gBAAA,QAAQ,KAAK,MAAM;AAEzB,gBAAM,KAAK,SAAS,OAAO,OAAO,MAAM,KAAK,QAAQ,EAAE;AAAA,YACrD,CAAC,QAAiB,QAAQ;AAAA,UAAA;AAGtB,gBAAA,KAAK,gBAAgB,MAAM,KAAK,YAClC,MAAM,KAAK,SACX;AAEJ,gBAAM,KAAK,aAAa,CAAC,MAAM,KAAK;AAEpC,eAAK,YAAY;AACjB,eAAK,QAAQ;AAAA,QACf;AAAA,MACF;AAAA,IAAA;AAGG,SAAA,QAAQ,KAAK,MAAM;AACxB,SAAK,YAAY,KAAK;AACtB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,aAGE,OAMgD;AAChD,UAAM,WAAW;AAAA,MACf,KAAK,KAAK,QAAQ;AAAA,MAClB,KAAK,QAAQ;AAAA,IAAA;AAEf,eAAW,WAAW,UAAU;AAC9B,UAAI,WAAW,OAAO,MAAM,aAAa,YAAY;AAC5C,eAAA,QAAA,EAAU,MAAM,IAAI;AAAA,UACzB,MAAM;AAAA,UACN,MAAM;AAAA,QAAA;AAAA,MAEV;AAAA,IACF;AAEQ,WAAA,MAAM,SAAuC,MAAM,KAAK;AAAA,EAClE;AA+bF;AAEA,SAAS,eAAe,UAA4B;AAClD,MAAI,UAAU;AACR,QAAA,OAAO,aAAa,UAAU;AACzB,aAAA;AAAA,IACT;AAEO,WAAA;AAAA,EACT;AAEO,SAAA;AACT;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,EACX;AACF;;"}
@@ -115,7 +115,6 @@ export interface FieldOptions<TParentData, TName extends DeepKeys<TParentData>,
115
115
  * If `true`, always run async validation, even if there are errors emitted during synchronous validation.
116
116
  */
117
117
  asyncAlways?: boolean;
118
- preserveValue?: boolean;
119
118
  /**
120
119
  * A validator provided by an extension, like `yupValidator` from `@tanstack/yup-form-adapter`
121
120
  */
@@ -39,7 +39,6 @@ class FormApi {
39
39
  this.options = {};
40
40
  this.fieldInfo = {};
41
41
  this.prevTransformArray = [];
42
- this._tempDefaultValue = void 0;
43
42
  this.mount = () => {
44
43
  const { onMount } = this.options.validators || {};
45
44
  if (!onMount)
@@ -379,11 +378,6 @@ class FormApi {
379
378
  delete this.fieldInfo[field];
380
379
  };
381
380
  this.pushFieldValue = (field, value, opts2) => {
382
- const fieldVal = this.getFieldValue(field) ?? [];
383
- this._tempDefaultValue = {
384
- value,
385
- field: `${field}[${fieldVal.length}]`
386
- };
387
381
  this.setFieldValue(
388
382
  field,
389
383
  (prev) => [...Array.isArray(prev) ? prev : [], value],
@@ -392,7 +386,6 @@ class FormApi {
392
386
  this.validateField(field, "change");
393
387
  };
394
388
  this.insertFieldValue = async (field, index, value, opts2) => {
395
- this._tempDefaultValue = { value, field: `${field}[${index}]` };
396
389
  this.setFieldValue(
397
390
  field,
398
391
  (prev) => {
@@ -407,7 +400,6 @@ class FormApi {
407
400
  await this.validateField(field, "change");
408
401
  };
409
402
  this.replaceFieldValue = async (field, index, value, opts2) => {
410
- this._tempDefaultValue = { value, field: `${field}[${index}]` };
411
403
  this.setFieldValue(
412
404
  field,
413
405
  (prev) => {
@@ -1 +1 @@
1
- {"version":3,"file":"FormApi.cjs","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isNonEmptyArray,\n setBy,\n} from './utils'\nimport type { Updater } from './utils'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { FieldApi, FieldMeta } from './FieldApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n Validator,\n} from './types'\n\n/**\n * @private\n */\nexport type FormValidateFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n}) => ValidationError\n\n/**\n * @private\n */\nexport type FormValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer TFN>\n ? TFN\n : FormValidateFn<TFormData, TFormValidator>\n\n/**\n * @private\n */\nexport type FormValidateAsyncFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\n/**\n * @private\n */\nexport type FormAsyncValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | FormValidateAsyncFn<TFormData, TFormValidator>\n : FormValidateAsyncFn<TFormData, TFormValidator>\n\nexport interface FormValidators<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * Optional function that fires as soon as the component mounts.\n */\n onMount?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional function that checks the validity of your data whenever a value changes\n */\n onChange?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.\n */\n onChangeAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\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 ValidationError\n */\n onBlur?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional onBlur asynchronous validation method for when a field loses focus return a `ValidationError` or a promise of `Promise<ValidationError>`\n */\n onBlurAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\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?: FormValidateOrFn<TFormData, TFormValidator>\n onSubmitAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n}\n\n/**\n * @private\n */\nexport interface FormTransform<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n fn: (\n formBase: FormApi<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n deps: unknown[]\n}\n\n/**\n * An object representing the options for a form.\n */\nexport interface FormOptions<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\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<FormState<TFormData>>\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 validator adapter to support usage of extra validation types (IE: Zod, Yup, or Valibot usage)\n */\n validatorAdapter?: TFormValidator\n /**\n * A list of validators to pass to the form\n */\n validators?: FormValidators<TFormData, TFormValidator>\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<TFormData, TFormValidator>\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<TFormData, TFormValidator>\n }) => void\n transform?: FormTransform<TFormData, TFormValidator>\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<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n /**\n * An instance of the FieldAPI.\n */\n instance: FieldApi<\n TFormData,\n any,\n Validator<unknown, unknown> | undefined,\n TFormValidator\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 FormState<TFormData> = {\n /**\n * The current values of the form fields.\n */\n values: TFormData\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: ValidationError[]\n /**\n * The error map for the form itself.\n */\n errorMap: ValidationErrorMap\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.\n */\n fieldMeta: Record<DeepKeys<TFormData>, FieldMeta>\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 the form is currently submitting.\n */\n isSubmitting: 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'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 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 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 counter for tracking the number of submission attempts.\n */\n submissionAttempts: number\n}\n\nfunction getDefaultFormState<TFormData>(\n defaultState: Partial<FormState<TFormData>>,\n): FormState<TFormData> {\n return {\n values: defaultState.values ?? ({} as never),\n errors: defaultState.errors ?? [],\n errorMap: defaultState.errorMap ?? {},\n fieldMeta: defaultState.fieldMeta ?? ({} as never),\n canSubmit: defaultState.canSubmit ?? true,\n isFieldsValid: defaultState.isFieldsValid ?? false,\n isFieldsValidating: defaultState.isFieldsValidating ?? false,\n isFormValid: defaultState.isFormValid ?? false,\n isFormValidating: defaultState.isFormValidating ?? false,\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isTouched: defaultState.isTouched ?? false,\n isPristine: defaultState.isPristine ?? true,\n isDirty: defaultState.isDirty ?? false,\n isValid: defaultState.isValid ?? 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 * 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 TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * The options for the form.\n */\n options: FormOptions<TFormData, TFormValidator> = {}\n /**\n * A [TanStack Store instance](https://tanstack.com/store/latest/docs/reference/Store) that keeps track of the form's state.\n */\n store!: Store<FormState<TFormData>>\n /**\n * The current state of the form.\n *\n * **Note:**\n * Do not use `state` directly, as it is not reactive.\n * Please use form.useStore() utility to subscribe to state\n */\n state!: FormState<TFormData>\n /**\n * A record of field information for each field in the form.\n */\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData, TFormValidator>> =\n {} as any\n\n /**\n * @private\n */\n prevTransformArray: unknown[] = []\n\n /**\n * @private\n * Used to handle the edgecase of `pushFieldValue` not adding a `defaultValue` to the child `FieldAPI`s that are\n * subsequently generated from the `pushFieldValue` (and friends)\n * @see https://github.com/TanStack/form/issues/704#issuecomment-2184080607\n */\n _tempDefaultValue:\n | undefined\n | {\n field: string\n value: unknown\n } = undefined\n\n /**\n * Constructs a new `FormApi` instance with the given form options.\n */\n constructor(opts?: FormOptions<TFormData, TFormValidator>) {\n this.store = new Store<FormState<TFormData>>(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n {\n onUpdate: () => {\n let { state } = this.store\n // Computed state\n const fieldMetaValues = Object.values(state.fieldMeta) as (\n | FieldMeta\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\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const isValidating = isFieldsValidating || state.isFormValidating\n state.errors = Object.values(state.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n const isFormValid = state.errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (state.submissionAttempts === 0 && !isTouched) ||\n (!isValidating && !state.isSubmitting && isValid)\n\n state = {\n ...state,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isPristine,\n isDirty,\n }\n\n this.state = state\n this.store.state = this.state\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 // This mutates the state\n this.options.transform?.fn(this)\n this.store.state = this.state\n this.prevTransformArray = transformArray\n }\n },\n },\n )\n\n this.state = this.store.state\n\n this.update(opts || {})\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends { value: TFormData; formApi: FormApi<any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData, TFormValidator>\n : FormAsyncValidateOrFn<TFormData, TFormValidator>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapter = this.options.validatorAdapter\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](props.value, props.validate) as never\n }\n\n return (props.validate as FormValidateFn<any, any>)(props.value) as never\n }\n\n mount = () => {\n const { onMount } = this.options.validators || {}\n if (!onMount) return\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: { ...prev.errorMap, onMount: error },\n }))\n }\n }\n\n /**\n * Updates the form options and form state.\n */\n update = (options?: FormOptions<TFormData, TFormValidator>) => {\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 this.store.batch(() => {\n const shouldUpdateValues =\n options.defaultValues &&\n options.defaultValues !== oldOptions.defaultValues &&\n !this.state.isTouched\n\n const shouldUpdateState =\n options.defaultState !== oldOptions.defaultState &&\n !this.state.isTouched\n\n this.store.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 */\n reset = () => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMeta = this.resetFieldMeta(currentFieldMeta)\n this.store.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values: this.options.defaultValues ?? this.options.defaultState?.values,\n fieldMeta,\n }),\n )\n }\n\n /**\n * Validates all fields in the form using the correct handlers for a given validation type.\n */\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n this.store.batch(() => {\n void (\n Object.values(this.fieldInfo) as FieldInfo<any, TFormValidator>[]\n ).forEach((field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n Promise.resolve().then(() => fieldInstance.validate(cause)),\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 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 this.store.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 = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n this.store.batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const error = normalizeError(\n this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (this.state.errorMap[errorMapKey] !== error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\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.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n /**\n * @private\n */\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<ValidationError[]> => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.store.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<ValidationError | 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<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | 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 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 error = normalizeError(rawError)\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }))\n\n resolve(error)\n }),\n )\n }\n\n let results: ValidationError[] = []\n if (promises.length) {\n results = await Promise.all(promises)\n }\n\n this.store.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return results.filter(Boolean)\n }\n\n /**\n * @private\n */\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.errors\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 = async () => {\n this.store.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.store.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.store.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n // Validate all fields\n await this.validateAllFields('submit')\n\n // Fields are invalid, do not submit\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 // Run validation for the form\n await this.validate('submit')\n\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 try {\n // Run the submit code\n await this.options.onSubmit?.({ value: this.state.values, formApi: this })\n\n this.store.batch(() => {\n this.store.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 ): FieldMeta | 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, TFormValidator> => {\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<FieldMeta>,\n ) => {\n this.store.setState((prev) => {\n return {\n ...prev,\n fieldMeta: {\n ...prev.fieldMeta,\n [field]: functionalUpdate(updater, prev.fieldMeta[field]),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, FieldMeta>,\n ): Record<TField, FieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, FieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, FieldMeta>,\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?: { touch?: boolean },\n ) => {\n const touch = opts?.touch\n\n this.store.batch(() => {\n if (touch) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n }))\n }\n\n this.store.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.store.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMeta[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?: { touch?: boolean },\n ) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldVal = (this.getFieldValue(field) as unknown[]) ?? []\n this._tempDefaultValue = {\n value,\n field: `${field}[${fieldVal.length}]`,\n } as never\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 /**\n * Inserts a value into an array field at the specified index, shifting the subsequent values to the right.\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?: { touch?: boolean },\n ) => {\n this._tempDefaultValue = { value, field: `${field}[${index}]` } as never\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\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?: { touch?: boolean },\n ) => {\n this._tempDefaultValue = { value, field: `${field}[${index}]` } as never\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?: { touch?: boolean },\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 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?: { touch?: boolean },\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 // 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?: { touch?: boolean },\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 // 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\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return 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","getSyncValidatorArray","getAsyncValidatorArray","getBy","functionalUpdate","opts","setBy","deleteBy","Store","isNonEmptyArray"],"mappings":"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"}
1
+ {"version":3,"file":"FormApi.cjs","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isNonEmptyArray,\n setBy,\n} from './utils'\nimport type { Updater } from './utils'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { FieldApi, FieldMeta } from './FieldApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n Validator,\n} from './types'\n\n/**\n * @private\n */\nexport type FormValidateFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n}) => ValidationError\n\n/**\n * @private\n */\nexport type FormValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer TFN>\n ? TFN\n : FormValidateFn<TFormData, TFormValidator>\n\n/**\n * @private\n */\nexport type FormValidateAsyncFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\n/**\n * @private\n */\nexport type FormAsyncValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | FormValidateAsyncFn<TFormData, TFormValidator>\n : FormValidateAsyncFn<TFormData, TFormValidator>\n\nexport interface FormValidators<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * Optional function that fires as soon as the component mounts.\n */\n onMount?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional function that checks the validity of your data whenever a value changes\n */\n onChange?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.\n */\n onChangeAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\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 ValidationError\n */\n onBlur?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional onBlur asynchronous validation method for when a field loses focus return a `ValidationError` or a promise of `Promise<ValidationError>`\n */\n onBlurAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\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?: FormValidateOrFn<TFormData, TFormValidator>\n onSubmitAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n}\n\n/**\n * @private\n */\nexport interface FormTransform<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n fn: (\n formBase: FormApi<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n deps: unknown[]\n}\n\n/**\n * An object representing the options for a form.\n */\nexport interface FormOptions<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\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<FormState<TFormData>>\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 validator adapter to support usage of extra validation types (IE: Zod, Yup, or Valibot usage)\n */\n validatorAdapter?: TFormValidator\n /**\n * A list of validators to pass to the form\n */\n validators?: FormValidators<TFormData, TFormValidator>\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<TFormData, TFormValidator>\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<TFormData, TFormValidator>\n }) => void\n transform?: FormTransform<TFormData, TFormValidator>\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<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n /**\n * An instance of the FieldAPI.\n */\n instance: FieldApi<\n TFormData,\n any,\n Validator<unknown, unknown> | undefined,\n TFormValidator\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 FormState<TFormData> = {\n /**\n * The current values of the form fields.\n */\n values: TFormData\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: ValidationError[]\n /**\n * The error map for the form itself.\n */\n errorMap: ValidationErrorMap\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.\n */\n fieldMeta: Record<DeepKeys<TFormData>, FieldMeta>\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 the form is currently submitting.\n */\n isSubmitting: 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'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 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 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 counter for tracking the number of submission attempts.\n */\n submissionAttempts: number\n}\n\nfunction getDefaultFormState<TFormData>(\n defaultState: Partial<FormState<TFormData>>,\n): FormState<TFormData> {\n return {\n values: defaultState.values ?? ({} as never),\n errors: defaultState.errors ?? [],\n errorMap: defaultState.errorMap ?? {},\n fieldMeta: defaultState.fieldMeta ?? ({} as never),\n canSubmit: defaultState.canSubmit ?? true,\n isFieldsValid: defaultState.isFieldsValid ?? false,\n isFieldsValidating: defaultState.isFieldsValidating ?? false,\n isFormValid: defaultState.isFormValid ?? false,\n isFormValidating: defaultState.isFormValidating ?? false,\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isTouched: defaultState.isTouched ?? false,\n isPristine: defaultState.isPristine ?? true,\n isDirty: defaultState.isDirty ?? false,\n isValid: defaultState.isValid ?? 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 * 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 TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * The options for the form.\n */\n options: FormOptions<TFormData, TFormValidator> = {}\n /**\n * A [TanStack Store instance](https://tanstack.com/store/latest/docs/reference/Store) that keeps track of the form's state.\n */\n store!: Store<FormState<TFormData>>\n /**\n * The current state of the form.\n *\n * **Note:**\n * Do not use `state` directly, as it is not reactive.\n * Please use form.useStore() utility to subscribe to state\n */\n state!: FormState<TFormData>\n /**\n * A record of field information for each field in the form.\n */\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData, TFormValidator>> =\n {} as any\n\n /**\n * @private\n */\n prevTransformArray: unknown[] = []\n\n /**\n * Constructs a new `FormApi` instance with the given form options.\n */\n constructor(opts?: FormOptions<TFormData, TFormValidator>) {\n this.store = new Store<FormState<TFormData>>(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n {\n onUpdate: () => {\n let { state } = this.store\n // Computed state\n const fieldMetaValues = Object.values(state.fieldMeta) as (\n | FieldMeta\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\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const isValidating = isFieldsValidating || state.isFormValidating\n state.errors = Object.values(state.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n const isFormValid = state.errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (state.submissionAttempts === 0 && !isTouched) ||\n (!isValidating && !state.isSubmitting && isValid)\n\n state = {\n ...state,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isPristine,\n isDirty,\n }\n\n this.state = state\n this.store.state = this.state\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 // This mutates the state\n this.options.transform?.fn(this)\n this.store.state = this.state\n this.prevTransformArray = transformArray\n }\n },\n },\n )\n\n this.state = this.store.state\n\n this.update(opts || {})\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends { value: TFormData; formApi: FormApi<any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData, TFormValidator>\n : FormAsyncValidateOrFn<TFormData, TFormValidator>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapter = this.options.validatorAdapter\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](props.value, props.validate) as never\n }\n\n return (props.validate as FormValidateFn<any, any>)(props.value) as never\n }\n\n mount = () => {\n const { onMount } = this.options.validators || {}\n if (!onMount) return\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: { ...prev.errorMap, onMount: error },\n }))\n }\n }\n\n /**\n * Updates the form options and form state.\n */\n update = (options?: FormOptions<TFormData, TFormValidator>) => {\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 this.store.batch(() => {\n const shouldUpdateValues =\n options.defaultValues &&\n options.defaultValues !== oldOptions.defaultValues &&\n !this.state.isTouched\n\n const shouldUpdateState =\n options.defaultState !== oldOptions.defaultState &&\n !this.state.isTouched\n\n this.store.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 */\n reset = () => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMeta = this.resetFieldMeta(currentFieldMeta)\n this.store.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values: this.options.defaultValues ?? this.options.defaultState?.values,\n fieldMeta,\n }),\n )\n }\n\n /**\n * Validates all fields in the form using the correct handlers for a given validation type.\n */\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n this.store.batch(() => {\n void (\n Object.values(this.fieldInfo) as FieldInfo<any, TFormValidator>[]\n ).forEach((field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n Promise.resolve().then(() => fieldInstance.validate(cause)),\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 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 this.store.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 = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n this.store.batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const error = normalizeError(\n this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (this.state.errorMap[errorMapKey] !== error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\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.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n /**\n * @private\n */\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<ValidationError[]> => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.store.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<ValidationError | 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<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | 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 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 error = normalizeError(rawError)\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }))\n\n resolve(error)\n }),\n )\n }\n\n let results: ValidationError[] = []\n if (promises.length) {\n results = await Promise.all(promises)\n }\n\n this.store.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return results.filter(Boolean)\n }\n\n /**\n * @private\n */\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.errors\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 = async () => {\n this.store.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.store.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.store.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n // Validate all fields\n await this.validateAllFields('submit')\n\n // Fields are invalid, do not submit\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 // Run validation for the form\n await this.validate('submit')\n\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 try {\n // Run the submit code\n await this.options.onSubmit?.({ value: this.state.values, formApi: this })\n\n this.store.batch(() => {\n this.store.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 ): FieldMeta | 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, TFormValidator> => {\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<FieldMeta>,\n ) => {\n this.store.setState((prev) => {\n return {\n ...prev,\n fieldMeta: {\n ...prev.fieldMeta,\n [field]: functionalUpdate(updater, prev.fieldMeta[field]),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, FieldMeta>,\n ): Record<TField, FieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, FieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, FieldMeta>,\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?: { touch?: boolean },\n ) => {\n const touch = opts?.touch\n\n this.store.batch(() => {\n if (touch) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n }))\n }\n\n this.store.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.store.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMeta[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?: { touch?: boolean },\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 /**\n * Inserts a value into an array field at the specified index, shifting the subsequent values to the right.\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?: { touch?: boolean },\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\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?: { touch?: boolean },\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?: { touch?: boolean },\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 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?: { touch?: boolean },\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 // 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?: { touch?: boolean },\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 // 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\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return 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","getSyncValidatorArray","getAsyncValidatorArray","getBy","functionalUpdate","opts","setBy","deleteBy","Store","isNonEmptyArray"],"mappings":";;;;AA+QA,SAAS,oBACP,cACsB;AACf,SAAA;AAAA,IACL,QAAQ,aAAa,UAAW,CAAC;AAAA,IACjC,QAAQ,aAAa,UAAU,CAAC;AAAA,IAChC,UAAU,aAAa,YAAY,CAAC;AAAA,IACpC,WAAW,aAAa,aAAc,CAAC;AAAA,IACvC,WAAW,aAAa,aAAa;AAAA,IACrC,eAAe,aAAa,iBAAiB;AAAA,IAC7C,oBAAoB,aAAa,sBAAsB;AAAA,IACvD,aAAa,aAAa,eAAe;AAAA,IACzC,kBAAkB,aAAa,oBAAoB;AAAA,IACnD,aAAa,aAAa,eAAe;AAAA,IACzC,cAAc,aAAa,gBAAgB;AAAA,IAC3C,WAAW,aAAa,aAAa;AAAA,IACrC,YAAY,aAAa,cAAc;AAAA,IACvC,SAAS,aAAa,WAAW;AAAA,IACjC,SAAS,aAAa,WAAW;AAAA,IACjC,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,IACZ;AAAA,EAAA;AAEJ;AASO,MAAM,QAGX;AAAA;AAAA;AAAA;AAAA,EA+BA,YAAY,MAA+C;;AA3B3D,SAAA,UAAkD;AAgBlD,SAAA,YACE;AAKF,SAAA,qBAAgC;AAuGhC,SAAA,QAAQ,MAAM;AACZ,YAAM,EAAE,QAAQ,IAAI,KAAK,QAAQ,cAAc,CAAA;AAC/C,UAAI,CAAC;AAAS;AACR,YAAA,QAAQ,KAAK,aAAa;AAAA,QAC9B,UAAU;AAAA,QACV,OAAO;AAAA,UACL,OAAO,KAAK,MAAM;AAAA,UAClB,SAAS;AAAA,QACX;AAAA,QACA,MAAM;AAAA,MAAA,CACP;AACD,UAAI,OAAO;AACJ,aAAA,MAAM,SAAS,CAAC,UAAU;AAAA,UAC7B,GAAG;AAAA,UACH,UAAU,EAAE,GAAG,KAAK,UAAU,SAAS,MAAM;AAAA,QAC7C,EAAA;AAAA,MACJ;AAAA,IAAA;AAMF,SAAA,SAAS,CAAC,YAAqD;AAC7D,UAAI,CAAC;AAAS;AAEd,YAAM,aAAa,KAAK;AAGxB,WAAK,UAAU;AAEV,WAAA,MAAM,MAAM,MAAM;AACf,cAAA,qBACJ,QAAQ,iBACR,QAAQ,kBAAkB,WAAW,iBACrC,CAAC,KAAK,MAAM;AAEd,cAAM,oBACJ,QAAQ,iBAAiB,WAAW,gBACpC,CAAC,KAAK,MAAM;AAEd,aAAK,MAAM;AAAA,UAAS,MAClB;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,YACP;AAAA,UACF;AAAA,QAAA;AAAA,MACF,CACD;AAAA,IAAA;AAMH,SAAA,QAAQ,MAAM;AACZ,YAAM,EAAE,WAAW,qBAAqB,KAAK;AACvC,YAAA,YAAY,KAAK,eAAe,gBAAgB;AACtD,WAAK,MAAM;AAAA,QAAS,MAAA;;AAClB,qCAAoB;AAAA,YAClB,GAAI,KAAK,QAAQ;AAAA,YACjB,QAAQ,KAAK,QAAQ,mBAAiBA,MAAA,KAAK,QAAQ,iBAAb,gBAAAA,IAA2B;AAAA,YACjE;AAAA,UAAA,CACD;AAAA;AAAA,MAAA;AAAA,IACH;AAMF,SAAA,oBAAoB,OAAO,UAA2B;AACpD,YAAM,0BAAwD,CAAA;AACzD,WAAA,MAAM,MAAM,MAAM;AACrB,aACE,OAAO,OAAO,KAAK,SAAS,EAC5B,QAAQ,CAAC,UAAU;AACnB,cAAI,CAAC,MAAM;AAAU;AACrB,gBAAM,gBAAgB,MAAM;AAEJ,kCAAA;AAAA,YACtB,QAAQ,UAAU,KAAK,MAAM,cAAc,SAAS,KAAK,CAAC;AAAA,UAAA;AAG5D,cAAI,CAAC,MAAM,SAAS,MAAM,KAAK,WAAW;AAElC,kBAAA,SAAS,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,KAAO,EAAA;AAAA,UACjE;AAAA,QAAA,CACD;AAAA,MAAA,CACF;AAED,YAAM,mBAAmB,MAAM,QAAQ,IAAI,uBAAuB;AAClE,aAAO,iBAAiB;IAAK;AAMG,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,MAC3C;AAGA,YAAM,mBAAmB,OAAO,KAAK,KAAK,SAAS,EAAE;AAAA,QAAO,CAAC,aAC3D,oBAAoB,KAAK,CAAC,QAAQ,SAAS,WAAW,GAAG,CAAC;AAAA,MAAA;AAI5D,YAAM,0BAAwD,CAAA;AACzD,WAAA,MAAM,MAAM,MAAM;AACJ,yBAAA,QAAQ,CAAC,gBAAgB;AAChB,kCAAA;AAAA,YACtB,QAAQ,QAAU,EAAA,KAAK,MAAM,KAAK,cAAc,aAAa,KAAK,CAAC;AAAA,UAAA;AAAA,QACrE,CACD;AAAA,MAAA,CACF;AAED,YAAM,mBAAmB,MAAM,QAAQ,IAAI,uBAAuB;AAClE,aAAO,iBAAiB;IAAK;AAMf,SAAA,gBAAA,CACd,OACA,UACG;;AAEH,YAAM,iBAAgBA,MAAA,KAAK,UAAU,KAAK,MAApB,gBAAAA,IAAuB;AAC7C,UAAI,CAAC;AAAe,eAAO;AAG3B,UAAI,CAAC,cAAc,MAAM,KAAK,WAAW;AAEzB,sBAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,KAAO,EAAA;AAAA,MAChE;AAEO,aAAA,cAAc,SAAS,KAAK;AAAA,IAAA;AAOrC,SAAA,eAAe,CAAC,UAA2B;AACzC,YAAM,YAAYC,MAAA,sBAAsB,OAAO,KAAK,OAAO;AAC3D,UAAI,aAAa;AAEZ,WAAA,MAAM,MAAM,MAAM;AACrB,mBAAW,eAAe,WAAW;AACnC,cAAI,CAAC,YAAY;AAAU;AAE3B,gBAAM,QAAQ;AAAA,YACZ,KAAK,aAAa;AAAA,cAChB,UAAU,YAAY;AAAA,cACtB,OAAO;AAAA,gBACL,OAAO,KAAK,MAAM;AAAA,gBAClB,SAAS;AAAA,cACX;AAAA,cACA,MAAM;AAAA,YAAA,CACP;AAAA,UAAA;AAEG,gBAAA,cAAc,eAAe,YAAY,KAAK;AACpD,cAAI,KAAK,MAAM,SAAS,WAAW,MAAM,OAAO;AACzC,iBAAA,MAAM,SAAS,CAAC,UAAU;AAAA,cAC7B,GAAG;AAAA,cACH,UAAU;AAAA,gBACR,GAAG,KAAK;AAAA,gBACR,CAAC,WAAW,GAAG;AAAA,cACjB;AAAA,YACA,EAAA;AAAA,UACJ;AACA,cAAI,OAAO;AACI,yBAAA;AAAA,UACf;AAAA,QACF;AAAA,MAAA,CACD;AAMK,YAAA,eAAe,eAAe,QAAQ;AAE1C,UAAA,KAAK,MAAM,SAAS,YAAY,KAChC,UAAU,YACV,CAAC,YACD;AACK,aAAA,MAAM,SAAS,CAAC,UAAU;AAAA,UAC7B,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,KAAK;AAAA,YACR,CAAC,YAAY,GAAG;AAAA,UAClB;AAAA,QACA,EAAA;AAAA,MACJ;AAEA,aAAO,EAAE,WAAW;AAAA,IAAA;AAMtB,SAAA,gBAAgB,OACd,UAC+B;AAC/B,YAAM,YAAYC,MAAA,uBAAuB,OAAO,KAAK,OAAO;AAExD,UAAA,CAAC,KAAK,MAAM,kBAAkB;AAC3B,aAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,kBAAkB,KAAO,EAAA;AAAA,MACrE;AAMA,YAAM,WAAmD,CAAA;AAEzD,iBAAW,eAAe,WAAW;AACnC,YAAI,CAAC,YAAY;AAAU;AACrB,cAAA,MAAM,eAAe,YAAY,KAAK;AAC5C,cAAM,qBAAqB,KAAK,MAAM,kBAAkB,GAAG;AAE3D,iEAAoB,oBAAoB;AAClC,cAAA,aAAa,IAAI;AAElB,aAAA,MAAM,kBAAkB,GAAG,IAAI;AAAA,UAClC,qBAAqB;AAAA,QAAA;AAGd,iBAAA;AAAA,UACP,IAAI,QAAqC,OAAO,YAAY;AACtD,gBAAA;AACA,gBAAA;AACF,yBAAW,MAAM,IAAI,QAAQ,CAAC,YAAY,cAAc;AACtD,2BAAW,YAAY;AACrB,sBAAI,WAAW,OAAO;AAAS,2BAAO,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,QAAQ,WAAW;AAAA,wBACrB;AAAA,wBACA,MAAM;AAAA,sBAAA,CACP;AAAA,oBAAA;AAAA,2BAEI,GAAG;AACV,8BAAU,CAAC;AAAA,kBACb;AAAA,gBAAA,GACC,YAAY,UAAU;AAAA,cAAA,CAC1B;AAAA,qBACM,GAAY;AACR,yBAAA;AAAA,YACb;AACM,kBAAA,QAAQ,eAAe,QAAQ;AAChC,iBAAA,MAAM,SAAS,CAAC,UAAU;AAAA,cAC7B,GAAG;AAAA,cACH,UAAU;AAAA,gBACR,GAAG,KAAK;AAAA,gBACR,CAAC,eAAe,KAAK,CAAC,GAAG;AAAA,cAC3B;AAAA,YACA,EAAA;AAEF,oBAAQ,KAAK;AAAA,UAAA,CACd;AAAA,QAAA;AAAA,MAEL;AAEA,UAAI,UAA6B,CAAA;AACjC,UAAI,SAAS,QAAQ;AACT,kBAAA,MAAM,QAAQ,IAAI,QAAQ;AAAA,MACtC;AAEK,WAAA,MAAM,SAAS,CAAC,UAAU;AAAA,QAC7B,GAAG;AAAA,QACH,kBAAkB;AAAA,MAClB,EAAA;AAEK,aAAA,QAAQ,OAAO,OAAO;AAAA,IAAA;AAM/B,SAAA,WAAW,CACT,UACmD;AAEnD,YAAM,EAAE,WAAe,IAAA,KAAK,aAAa,KAAK;AAE9C,UAAI,cAAc,CAAC,KAAK,QAAQ,aAAa;AAC3C,eAAO,KAAK,MAAM;AAAA,MACpB;AAGO,aAAA,KAAK,cAAc,KAAK;AAAA,IAAA;AAMjC,SAAA,eAAe,YAAY;;AACpB,WAAA,MAAM,SAAS,CAAC,SAAS;AAAA,QAC5B,GAAG;AAAA;AAAA,QAEH,aAAa;AAAA;AAAA,QAEb,oBAAoB,IAAI,qBAAqB;AAAA,MAC7C,EAAA;AAGE,UAAA,CAAC,KAAK,MAAM;AAAW;AAEtB,WAAA,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,cAAc,KAAO,EAAA;AAEzD,YAAM,OAAO,MAAM;AACZ,aAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,MAAQ,EAAA;AAAA,MAAA;AAI5D,YAAA,KAAK,kBAAkB,QAAQ;AAGjC,UAAA,CAAC,KAAK,MAAM,eAAe;AACxB;AACL,eAAAF,MAAA,KAAK,SAAQ,oBAAb,wBAAAA,KAA+B;AAAA,UAC7B,OAAO,KAAK,MAAM;AAAA,UAClB,SAAS;AAAA,QAAA;AAEX;AAAA,MACF;AAGM,YAAA,KAAK,SAAS,QAAQ;AAExB,UAAA,CAAC,KAAK,MAAM,SAAS;AAClB;AACL,yBAAK,SAAQ,oBAAb,4BAA+B;AAAA,UAC7B,OAAO,KAAK,MAAM;AAAA,UAClB,SAAS;AAAA,QAAA;AAEX;AAAA,MACF;AAEI,UAAA;AAEI,gBAAA,gBAAK,SAAQ,aAAb,4BAAwB,EAAE,OAAO,KAAK,MAAM,QAAQ,SAAS,KAAM;AAEpE,aAAA,MAAM,MAAM,MAAM;AAChB,eAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,KAAO,EAAA;AACzD;QAAA,CACN;AAAA,eACM,KAAK;AACP;AACC,cAAA;AAAA,MACR;AAAA,IAAA;AAMF,SAAA,gBAAgB,CACd,UACiCG,MAAAA,MAAM,KAAK,MAAM,QAAQ,KAAK;AAKjE,SAAA,eAAe,CACb,UAC0B;AACnB,aAAA,KAAK,MAAM,UAAU,KAAK;AAAA,IAAA;AAMnC,SAAA,eAAe,CACb,UACyC;;AAEjC,cAAAH,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,QACZ;AAAA,MAAA;AAAA,IACF;AAMa,SAAA,eAAA,CACb,OACA,YACG;AACE,WAAA,MAAM,SAAS,CAAC,SAAS;AACrB,eAAA;AAAA,UACL,GAAG;AAAA,UACH,WAAW;AAAA,YACT,GAAG,KAAK;AAAA,YACR,CAAC,KAAK,GAAGI,MAAAA,iBAAiB,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA,UAC1D;AAAA,QAAA;AAAA,MACF,CACD;AAAA,IAAA;AAGH,SAAA,iBAAiB,CACf,cAC8B;AACvB,aAAA,OAAO,KAAK,SAAS,EAAE;AAAA,QAC5B,CAAC,KAAgC,QAAQ;AACvC,gBAAM,WAAW;AACjB,cAAI,QAAQ,IAAI;AAAA,YACd,cAAc;AAAA,YACd,WAAW;AAAA,YACX,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,eAAe,CAAC;AAAA,YAChB,QAAQ,CAAC;AAAA,YACT,UAAU,CAAC;AAAA,UAAA;AAEN,iBAAA;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MAAA;AAAA,IACH;AAMc,SAAA,gBAAA,CACd,OACA,SACAC,UACG;AACH,YAAM,QAAQA,SAAA,gBAAAA,MAAM;AAEf,WAAA,MAAM,MAAM,MAAM;AACrB,YAAI,OAAO;AACJ,eAAA,aAAa,OAAO,CAAC,UAAU;AAAA,YAClC,GAAG;AAAA,YACH,WAAW;AAAA,YACX,SAAS;AAAA,UACT,EAAA;AAAA,QACJ;AAEK,aAAA,MAAM,SAAS,CAAC,SAAS;AACrB,iBAAA;AAAA,YACL,GAAG;AAAA,YACH,QAAQC,MAAAA,MAAM,KAAK,QAAQ,OAAO,OAAO;AAAA,UAAA;AAAA,QAC3C,CACD;AAAA,MAAA,CACF;AAAA,IAAA;AAGH,SAAA,cAAc,CAAqC,UAAkB;AAC9D,WAAA,MAAM,SAAS,CAAC,SAAS;AACtB,cAAA,WAAW,EAAE,GAAG;AACtB,iBAAS,SAASC,MAAA,SAAS,SAAS,QAAQ,KAAK;AAC1C,eAAA,SAAS,UAAU,KAAK;AAExB,eAAA;AAAA,MAAA,CACR;AACM,aAAA,KAAK,UAAU,KAAK;AAAA,IAAA;AAMZ,SAAA,iBAAA,CACf,OACA,OAGAF,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAS,CAAC,GAAI,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAI,KAAK;AAAA,QACtDA;AAAA,MAAA;AAEG,WAAA,cAAc,OAAO,QAAQ;AAAA,IAAA;AAMpC,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,UAAA;AAAA,QAE3D;AAAA,QACAA;AAAA,MAAA;AAII,YAAA,KAAK,cAAc,OAAO,QAAQ;AAAA,IAAA;AAM1C,SAAA,oBAAoB,OAClB,OACA,OACA,OAGAA,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAS;AACR,iBAAQ,KAAwC;AAAA,YAAI,CAAC,GAAG,MACtD,MAAM,QAAQ,QAAQ;AAAA,UAAA;AAAA,QAE1B;AAAA,QACAA;AAAA,MAAA;AAII,YAAA,KAAK,cAAc,OAAO,QAAQ;AACxC,YAAM,KAAK,gCAAgC,OAAO,OAAO,QAAQ;AAAA,IAAA;AAMhD,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,UAAA;AAAA,QAErB;AAAA,QACAA;AAAA,MAAA;AAGF,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,QAAA;AAIpB,uBAAe,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAW,CAAC;AAAA,MAC7D;AAGM,YAAA,KAAK,cAAc,OAAO,QAAQ;AACxC,YAAM,KAAK,gCAAgC,OAAO,OAAO,QAAQ;AAAA,IAAA;AAMnE,SAAA,kBAAkB,CAChB,OACA,QACA,QACAA,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAc;AACP,gBAAA,QAAQ,KAAK,MAAM;AACnB,gBAAA,QAAQ,KAAK,MAAM;AAClB,iBAAAC,MAAA,MAAMA,MAAM,MAAA,MAAM,GAAG,MAAM,IAAI,KAAK,GAAG,GAAG,MAAM,IAAI,KAAK;AAAA,QAClE;AAAA,QACAD;AAAA,MAAA;AAIG,WAAA,cAAc,OAAO,QAAQ;AAElC,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AACzE,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AAAA,IAAA;AAM3E,SAAA,kBAAkB,CAChB,OACA,QACA,QACAA,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,MAAA;AAIG,WAAA,cAAc,OAAO,QAAQ;AAElC,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AACzE,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AAAA,IAAA;AA7uBzE,SAAK,QAAQ,IAAIG,MAAA;AAAA,MACf,oBAAoB;AAAA,QAClB,GAAI,6BAAM;AAAA,QACV,SAAQ,6BAAM,oBAAiB,kCAAM,iBAAN,mBAAoB;AAAA,QACnD,aAAa;AAAA,MAAA,CACd;AAAA,MACD;AAAA,QACE,UAAU,MAAM;;AACV,cAAA,EAAE,MAAM,IAAI,KAAK;AAErB,gBAAM,kBAAkB,OAAO,OAAO,MAAM,SAAS;AAKrD,gBAAM,qBAAqB,gBAAgB;AAAA,YACzC,CAAC,UAAU,+BAAO;AAAA,UAAA;AAGd,gBAAA,gBAAgB,CAAC,gBAAgB;AAAA,YACrC,CAAC,WACC,+BAAO,aACPC,MAAgB,gBAAA,OAAO,OAAO,MAAM,QAAQ,EAAE,OAAO,OAAO,CAAC;AAAA,UAAA;AAGjE,gBAAM,YAAY,gBAAgB,KAAK,CAAC,UAAU,+BAAO,SAAS;AAElE,gBAAM,UAAU,gBAAgB,KAAK,CAAC,UAAU,+BAAO,OAAO;AAC9D,gBAAM,aAAa,CAAC;AAEd,gBAAA,eAAe,sBAAsB,MAAM;AACjD,gBAAM,SAAS,OAAO,OAAO,MAAM,QAAQ,EAAE;AAAA,YAC3C,CAAC,QAAiB,QAAQ;AAAA,UAAA;AAEtB,gBAAA,cAAc,MAAM,OAAO,WAAW;AAC5C,gBAAM,UAAU,iBAAiB;AAC3B,gBAAA,YACH,MAAM,uBAAuB,KAAK,CAAC,aACnC,CAAC,gBAAgB,CAAC,MAAM,gBAAgB;AAEnC,kBAAA;AAAA,YACN,GAAG;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAGF,eAAK,QAAQ;AACR,eAAA,MAAM,QAAQ,KAAK;AAGxB,gBAAM,mBAAiBT,MAAA,KAAK,QAAQ,cAAb,gBAAAA,IAAwB,SAAQ,CAAA;AACvD,gBAAM,kBACJ,eAAe,WAAW,KAAK,mBAAmB,UAClD,eAAe,KAAK,CAAC,KAAK,MAAM,QAAQ,KAAK,mBAAmB,CAAC,CAAC;AAEpE,cAAI,iBAAiB;AAEd,uBAAA,QAAQ,cAAR,mBAAmB,GAAG;AACtB,iBAAA,MAAM,QAAQ,KAAK;AACxB,iBAAK,qBAAqB;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,IAAA;AAGG,SAAA,QAAQ,KAAK,MAAM;AAEnB,SAAA,OAAO,QAAQ,CAAA,CAAE;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,aAGE,OAMgD;AAC1C,UAAA,UAAU,KAAK,QAAQ;AAC7B,QAAI,WAAW,OAAO,MAAM,aAAa,YAAY;AAC5C,aAAA,QAAA,EAAU,MAAM,IAAI,EAAE,MAAM,OAAO,MAAM,QAAQ;AAAA,IAC1D;AAEQ,WAAA,MAAM,SAAsC,MAAM,KAAK;AAAA,EACjE;AAgpBF;AAEA,SAAS,eAAe,UAA4B;AAClD,MAAI,UAAU;AACR,QAAA,OAAO,aAAa,UAAU;AACzB,aAAA;AAAA,IACT;AAEO,WAAA;AAAA,EACT;AAEO,SAAA;AACT;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,EACX;AACF;;"}
@@ -241,16 +241,6 @@ export declare class FormApi<TFormData, TFormValidator extends Validator<TFormDa
241
241
  * @private
242
242
  */
243
243
  prevTransformArray: unknown[];
244
- /**
245
- * @private
246
- * Used to handle the edgecase of `pushFieldValue` not adding a `defaultValue` to the child `FieldAPI`s that are
247
- * subsequently generated from the `pushFieldValue` (and friends)
248
- * @see https://github.com/TanStack/form/issues/704#issuecomment-2184080607
249
- */
250
- _tempDefaultValue: undefined | {
251
- field: string;
252
- value: unknown;
253
- };
254
244
  /**
255
245
  * Constructs a new `FormApi` instance with the given form options.
256
246
  */
@@ -115,7 +115,6 @@ export interface FieldOptions<TParentData, TName extends DeepKeys<TParentData>,
115
115
  * If `true`, always run async validation, even if there are errors emitted during synchronous validation.
116
116
  */
117
117
  asyncAlways?: boolean;
118
- preserveValue?: boolean;
119
118
  /**
120
119
  * A validator provided by an extension, like `yupValidator` from `@tanstack/yup-form-adapter`
121
120
  */
@@ -41,11 +41,7 @@ class FieldApi {
41
41
  }
42
42
  }
43
43
  return () => {
44
- const preserveValue = this.options.preserveValue;
45
44
  unsubscribe();
46
- if (!preserveValue) {
47
- this.form.deleteField(this.name);
48
- }
49
45
  };
50
46
  };
51
47
  this.update = (opts2) => {
@@ -60,9 +56,6 @@ class FieldApi {
60
56
  if (this._getMeta() === void 0) {
61
57
  this.setMeta(this.state.meta);
62
58
  }
63
- if (opts2.defaultValue === void 0 && this.form._tempDefaultValue !== void 0 && this.form._tempDefaultValue.field === this.name) {
64
- opts2.defaultValue = this.form._tempDefaultValue.value;
65
- }
66
59
  this.options = opts2;
67
60
  };
68
61
  this.getValue = () => {
@@ -290,9 +283,6 @@ class FieldApi {
290
283
  };
291
284
  this.form = opts.form;
292
285
  this.name = opts.name;
293
- if (opts.defaultValue === void 0 && this.form._tempDefaultValue !== void 0 && this.form._tempDefaultValue.field === this.name) {
294
- opts.defaultValue = this.form._tempDefaultValue.value;
295
- }
296
286
  if (opts.defaultValue !== void 0) {
297
287
  this.form.setFieldValue(this.name, opts.defaultValue);
298
288
  }
@@ -320,11 +310,6 @@ class FieldApi {
320
310
  state.meta.isPristine = !state.meta.isDirty;
321
311
  this.prevState = state;
322
312
  this.state = state;
323
- setTimeout(() => {
324
- if (this.form._tempDefaultValue !== void 0 && this.form._tempDefaultValue.field === this.name) {
325
- this.form._tempDefaultValue = void 0;
326
- }
327
- }, 0);
328
313
  }
329
314
  }
330
315
  );
@@ -1 +1 @@
1
- {"version":3,"file":"FieldApi.js","sources":["../../src/FieldApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport { getAsyncValidatorArray, getBy, getSyncValidatorArray } from './utils'\nimport type { FieldInfo, FormApi } from './FormApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n Validator,\n} from './types'\nimport type { AsyncValidator, SyncValidator, Updater } from './utils'\nimport type { DeepKeys, DeepValue, NoInfer } from './util-types'\n\n/**\n * @private\n */\nexport type FieldValidateFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (props: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n}) => ValidationError\n\n/**\n * @private\n */\nexport type FieldValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\n/**\n * @private\n */\nexport type FieldValidateAsyncFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (options: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\n/**\n * @private\n */\nexport type FieldAsyncValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\nexport interface FieldValidators<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * An optional function that takes a param of `formApi` which is a generic type of `TData` and `TParentData`\n */\n onMount?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property that takes a `ValidateFn` which is a generic of `TData` and `TParentData`.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onChange?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onChange` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onChangeAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional number to represent how long the `onChangeAsync` should wait before running\n *\n * 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 * An optional list of field names that should trigger this field's `onChange` and `onChangeAsync` events when its value changes\n */\n onChangeListenTo?: DeepKeys<TParentData>[]\n /**\n * An optional function, that when run when subscribing to blur event of input.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onBlur?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onBlur` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onBlurAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\n /**\n * An optional number to represent how long the `onBlurAsync` should wait before running\n *\n * 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 /**\n * An optional list of field names that should trigger this field's `onBlur` and `onBlurAsync` events when its value changes\n */\n onBlurListenTo?: DeepKeys<TParentData>[]\n /**\n * An optional function, that when run when subscribing to submit event of input.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onSubmit?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onSubmit` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onSubmitAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n}\n\n/**\n * An object type representing the options for a field in a form.\n */\nexport interface FieldOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.\n */\n name: TName\n /**\n * An optional default value for the field.\n */\n defaultValue?: NoInfer<TData>\n /**\n * The default time to debounce async validation if there is not a more specific debounce time passed.\n */\n asyncDebounceMs?: number\n /**\n * If `true`, always run async validation, even if there are errors emitted during synchronous validation.\n */\n asyncAlways?: boolean\n preserveValue?: boolean\n /**\n * A validator provided by an extension, like `yupValidator` from `@tanstack/yup-form-adapter`\n */\n validatorAdapter?: TFieldValidator\n /**\n * A list of validators to pass to the field\n */\n validators?: FieldValidators<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional object with default metadata for the field.\n */\n defaultMeta?: Partial<FieldMeta>\n}\n\n/**\n * An object type representing the required options for the FieldApi class.\n */\nexport interface FieldApiOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> extends FieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > {\n form: FormApi<TParentData, TFormValidator>\n}\n\n/**\n * An object type representing the metadata of a field in a form.\n */\nexport type FieldMeta = {\n /**\n * A flag indicating whether the field has been touched.\n */\n isTouched: boolean\n /**\n * A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.\n */\n isPristine: boolean\n /**\n * A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.\n */\n isDirty: boolean\n /**\n * An array of errors related to the touched state of the field.\n */\n touchedErrors: ValidationError[]\n /**\n * An array of errors related to the field value.\n */\n errors: ValidationError[]\n /**\n * A map of errors related to the field value.\n */\n errorMap: ValidationErrorMap\n /**\n * A flag indicating whether the field is currently being validated.\n */\n isValidating: boolean\n}\n\n/**\n * An object type representing the state of a field.\n */\nexport type FieldState<TData> = {\n /**\n * The current value of the field.\n */\n value: TData\n /**\n * The current metadata of the field.\n */\n meta: FieldMeta\n}\n\n/**\n * A class representing the API for managing a form field.\n *\n * Normally, you will not need to create a new `FieldApi` instance directly.\n * Instead, you will use a framework hook/function like `useField` or `createField`\n * 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\n * the `new FieldApi` constructor.\n */\nexport class FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * A reference to the form API instance.\n */\n form: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >['form']\n /**\n * The field name.\n */\n name!: DeepKeys<TParentData>\n /**\n * The field options.\n */\n options: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > = {} as any\n /**\n * The field state store.\n */\n store!: Store<FieldState<TData>>\n /**\n * The current field state.\n */\n state!: FieldState<TData>\n /**\n * @private\n */\n prevState!: FieldState<TData>\n\n /**\n * Initializes a new `FieldApi` instance.\n */\n constructor(\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) {\n this.form = opts.form as never\n this.name = opts.name as never\n\n if (\n opts.defaultValue === undefined &&\n this.form._tempDefaultValue !== undefined &&\n this.form._tempDefaultValue.field === this.name\n ) {\n opts.defaultValue = this.form._tempDefaultValue.value as never\n }\n\n if (opts.defaultValue !== undefined) {\n this.form.setFieldValue(this.name, opts.defaultValue as never)\n }\n\n this.store = new Store<FieldState<TData>>(\n {\n value: this.getValue(),\n\n meta: this._getMeta() ?? {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...opts.defaultMeta,\n },\n },\n {\n onUpdate: () => {\n const state = this.store.state\n\n state.meta.errors = Object.values(state.meta.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n\n state.meta.touchedErrors = state.meta.isTouched\n ? state.meta.errors\n : []\n\n state.meta.isPristine = !state.meta.isDirty\n\n this.prevState = state\n this.state = state\n\n // Cleanup the temp value after this \"tick\"\n // (Everything occurs sync otherwise)\n setTimeout(() => {\n if (\n this.form._tempDefaultValue !== undefined &&\n this.form._tempDefaultValue.field === this.name\n ) {\n this.form._tempDefaultValue = undefined\n }\n }, 0)\n },\n },\n )\n\n this.state = this.store.state\n this.prevState = this.state\n this.options = opts as never\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends { value: TData; fieldApi: FieldApi<any, any, any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FieldValidateOrFn<any, any, any, any>\n : FieldAsyncValidateOrFn<any, any, any, any>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapters = [\n this.form.options.validatorAdapter,\n this.options.validatorAdapter,\n ] as const\n for (const adapter of adapters) {\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](\n props.value as never,\n props.validate,\n ) as never\n }\n }\n\n return (props.validate as FieldValidateFn<any, any>)(props.value) as never\n }\n\n /**\n * Mounts the field instance to the form.\n */\n mount = () => {\n const info = this.getInfo()\n info.instance = this as never\n const unsubscribe = this.form.store.subscribe(() => {\n this.store.batch(() => {\n const nextValue = this.getValue()\n const nextMeta = this.getMeta()\n\n if (nextValue !== this.state.value) {\n this.store.setState((prev) => ({ ...prev, value: nextValue }))\n }\n\n if (nextMeta !== this.state.meta) {\n this.store.setState((prev) => ({ ...prev, meta: nextMeta }))\n }\n })\n })\n\n this.update(this.options as never)\n const { onMount } = this.options.validators || {}\n\n if (onMount) {\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.value,\n fieldApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.setMeta((prev) => ({\n ...prev,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n errorMap: { ...prev?.errorMap, onMount: error },\n }))\n }\n }\n\n return () => {\n const preserveValue = this.options.preserveValue\n unsubscribe()\n if (!preserveValue) {\n this.form.deleteField(this.name)\n }\n }\n }\n\n /**\n * Updates the field instance with new options.\n */\n update = (\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => {\n // Default Value\n\n if (this.state.value === undefined) {\n const formDefault = getBy(opts.form.options.defaultValues, opts.name)\n\n if (opts.defaultValue !== undefined) {\n this.setValue(opts.defaultValue as never)\n } else if (formDefault !== undefined) {\n this.setValue(formDefault as never)\n }\n }\n\n // Default Meta\n if (this._getMeta() === undefined) {\n this.setMeta(this.state.meta)\n }\n\n if (\n opts.defaultValue === undefined &&\n this.form._tempDefaultValue !== undefined &&\n this.form._tempDefaultValue.field === this.name\n ) {\n opts.defaultValue = this.form._tempDefaultValue.value as never\n }\n\n this.options = opts as never\n }\n\n /**\n * Gets the current field value.\n */\n getValue = (): TData => {\n return this.form.getFieldValue(this.name) as TData\n }\n\n /**\n * Sets the field value and run the `change` validator.\n */\n setValue = (\n updater: Updater<TData>,\n options?: { touch?: boolean; notify?: boolean },\n ) => {\n this.form.setFieldValue(this.name, updater as never, options)\n this.validate('change')\n }\n\n /**\n * @private\n */\n _getMeta = () => this.form.getFieldMeta(this.name)\n\n /**\n * Gets the current field metadata.\n */\n getMeta = () =>\n this._getMeta() ??\n ({\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...this.options.defaultMeta,\n } as FieldMeta)\n\n /**\n * Sets the field metadata.\n */\n setMeta = (updater: Updater<FieldMeta>) =>\n this.form.setFieldMeta(this.name, updater)\n\n /**\n * Gets the field information object.\n */\n getInfo = () => this.form.getFieldInfo(this.name)\n\n /**\n * Pushes a new value to the field.\n */\n pushValue = (\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.pushFieldValue(this.name, value as any, opts)\n\n /**\n * Inserts a value at the specified index, shifting the subsequent values to the right.\n */\n insertValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.insertFieldValue(this.name, index, value as any, opts)\n\n /**\n * Replaces a value at the specified index.\n */\n replaceValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.replaceFieldValue(this.name, index, value as any, opts)\n\n /**\n * Removes a value at the specified index.\n */\n removeValue = (index: number, opts?: { touch: boolean }) =>\n this.form.removeFieldValue(this.name, index, opts)\n\n /**\n * Swaps the values at the specified indices.\n */\n swapValues = (aIndex: number, bIndex: number, opts?: { touch?: boolean }) =>\n this.form.swapFieldValues(this.name, aIndex, bIndex, opts)\n\n /**\n * Moves the value at the first specified index to the second specified index.\n */\n moveValue = (aIndex: number, bIndex: number, opts?: { touch?: boolean }) =>\n this.form.moveFieldValues(this.name, aIndex, bIndex, opts)\n\n /**\n * @private\n */\n getLinkedFields = (cause: ValidationCause) => {\n const fields = Object.values(this.form.fieldInfo) as FieldInfo<\n any,\n TFormValidator\n >[]\n\n const linkedFields: FieldApi<any, any, any, any>[] = []\n for (const field of fields) {\n if (!field.instance) continue\n const { onChangeListenTo, onBlurListenTo } =\n field.instance.options.validators || {}\n if (\n cause === 'change' &&\n onChangeListenTo?.includes(this.name as string)\n ) {\n linkedFields.push(field.instance)\n }\n if (cause === 'blur' && onBlurListenTo?.includes(this.name as string)) {\n linkedFields.push(field.instance)\n }\n }\n\n return linkedFields\n }\n\n /**\n * @private\n */\n validateSync = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getSyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<SyncValidator<any> & { field: FieldApi<any, any, any, any> }>,\n )\n\n // Needs type cast as eslint errantly believes this is always falsy\n let hasErrored = false as boolean\n\n this.form.store.batch(() => {\n const validateFieldFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: SyncValidator<any>,\n ) => {\n const error = normalizeError(\n field.runValidator({\n validate: validateObj.validate,\n value: { value: field.getValue(), fieldApi: field },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (field.state.meta.errorMap[errorMapKey] !== error) {\n field.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(validateObj.cause)]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\n }\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldFn(this, validateObj)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldFn(fieldValitateObj.field, fieldValitateObj)\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.meta.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n /**\n * @private\n */\n validateAsync = async (cause: ValidationCause) => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getAsyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<\n AsyncValidator<any> & { field: FieldApi<any, any, any, any> }\n >,\n )\n\n if (!this.state.meta.isValidating) {\n this.setMeta((prev) => ({ ...prev, isValidating: true }))\n }\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: 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 validatesPromises: Promise<ValidationError | undefined>[] = []\n const linkedPromises: Promise<ValidationError | undefined>[] = []\n\n const validateFieldAsyncFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: AsyncValidator<any>,\n promises: Promise<ValidationError | undefined>[],\n ) => {\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = field.getInfo().validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.getInfo().validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | 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: field.getValue(),\n fieldApi: field,\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 error = normalizeError(rawError)\n field.setMeta((prev) => {\n return {\n ...prev,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }\n })\n\n resolve(error)\n }),\n )\n }\n\n // TODO: Dedupe this logic to reduce bundle size\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldAsyncFn(this, validateObj, validatesPromises)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldAsyncFn(\n fieldValitateObj.field,\n fieldValitateObj,\n linkedPromises,\n )\n }\n\n let results: ValidationError[] = []\n if (validatesPromises.length || linkedPromises.length) {\n results = await Promise.all(validatesPromises)\n await Promise.all(linkedPromises)\n }\n\n this.setMeta((prev) => ({ ...prev, isValidating: false }))\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: false }))\n }\n\n return results.filter(Boolean)\n }\n\n /**\n * Validates the field value.\n */\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // If the field is pristine and validatePristine is false, do not validate\n if (!this.state.meta.isTouched) return []\n\n try {\n this.form.validate(cause)\n } catch (_) {}\n\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.meta.errors\n }\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n /**\n * Handles the change event.\n */\n handleChange = (updater: Updater<TData>) => {\n this.setValue(updater, { touch: true })\n }\n\n /**\n * Handles the blur event.\n */\n handleBlur = () => {\n const prevTouched = this.state.meta.isTouched\n if (!prevTouched) {\n this.setMeta((prev) => ({ ...prev, isTouched: true }))\n this.validate('change')\n }\n this.validate('blur')\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return 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"],"mappings":"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"}
1
+ {"version":3,"file":"FieldApi.js","sources":["../../src/FieldApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport { getAsyncValidatorArray, getBy, getSyncValidatorArray } from './utils'\nimport type { FieldInfo, FormApi } from './FormApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n Validator,\n} from './types'\nimport type { AsyncValidator, SyncValidator, Updater } from './utils'\nimport type { DeepKeys, DeepValue, NoInfer } from './util-types'\n\n/**\n * @private\n */\nexport type FieldValidateFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (props: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n}) => ValidationError\n\n/**\n * @private\n */\nexport type FieldValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\n/**\n * @private\n */\nexport type FieldValidateAsyncFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = (options: {\n value: TData\n fieldApi: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\n/**\n * @private\n */\nexport type FieldAsyncValidateOrFn<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> = TFieldValidator extends Validator<TData, infer TFN>\n ?\n | TFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : TFormValidator extends Validator<TParentData, infer FFN>\n ?\n | FFN\n | FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n : FieldValidateAsyncFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\nexport interface FieldValidators<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * An optional function that takes a param of `formApi` which is a generic type of `TData` and `TParentData`\n */\n onMount?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property that takes a `ValidateFn` which is a generic of `TData` and `TParentData`.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onChange?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onChange` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onChangeAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional number to represent how long the `onChangeAsync` should wait before running\n *\n * 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 * An optional list of field names that should trigger this field's `onChange` and `onChangeAsync` events when its value changes\n */\n onChangeListenTo?: DeepKeys<TParentData>[]\n /**\n * An optional function, that when run when subscribing to blur event of input.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onBlur?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onBlur` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onBlurAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n\n /**\n * An optional number to represent how long the `onBlurAsync` should wait before running\n *\n * 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 /**\n * An optional list of field names that should trigger this field's `onBlur` and `onBlurAsync` events when its value changes\n */\n onBlurListenTo?: DeepKeys<TParentData>[]\n /**\n * An optional function, that when run when subscribing to submit event of input.\n * If `validatorAdapter` is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().min(1)` if `zodAdapter` is passed\n */\n onSubmit?: FieldValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional property similar to `onSubmit` but async validation. If `validatorAdapter`\n * is passed, this may also accept a property from the respective adapter\n *\n * @example `z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' })` if `zodAdapter` is passed\n */\n onSubmitAsync?: FieldAsyncValidateOrFn<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n}\n\n/**\n * An object type representing the options for a field in a form.\n */\nexport interface FieldOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * The field name. The type will be `DeepKeys<TParentData>` to ensure your name is a deep key of the parent dataset.\n */\n name: TName\n /**\n * An optional default value for the field.\n */\n defaultValue?: NoInfer<TData>\n /**\n * The default time to debounce async validation if there is not a more specific debounce time passed.\n */\n asyncDebounceMs?: number\n /**\n * If `true`, always run async validation, even if there are errors emitted during synchronous validation.\n */\n asyncAlways?: boolean\n /**\n * A validator provided by an extension, like `yupValidator` from `@tanstack/yup-form-adapter`\n */\n validatorAdapter?: TFieldValidator\n /**\n * A list of validators to pass to the field\n */\n validators?: FieldValidators<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >\n /**\n * An optional object with default metadata for the field.\n */\n defaultMeta?: Partial<FieldMeta>\n}\n\n/**\n * An object type representing the required options for the FieldApi class.\n */\nexport interface FieldApiOptions<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> extends FieldOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > {\n form: FormApi<TParentData, TFormValidator>\n}\n\n/**\n * An object type representing the metadata of a field in a form.\n */\nexport type FieldMeta = {\n /**\n * A flag indicating whether the field has been touched.\n */\n isTouched: boolean\n /**\n * A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`.\n */\n isPristine: boolean\n /**\n * A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`.\n */\n isDirty: boolean\n /**\n * An array of errors related to the touched state of the field.\n */\n touchedErrors: ValidationError[]\n /**\n * An array of errors related to the field value.\n */\n errors: ValidationError[]\n /**\n * A map of errors related to the field value.\n */\n errorMap: ValidationErrorMap\n /**\n * A flag indicating whether the field is currently being validated.\n */\n isValidating: boolean\n}\n\n/**\n * An object type representing the state of a field.\n */\nexport type FieldState<TData> = {\n /**\n * The current value of the field.\n */\n value: TData\n /**\n * The current metadata of the field.\n */\n meta: FieldMeta\n}\n\n/**\n * A class representing the API for managing a form field.\n *\n * Normally, you will not need to create a new `FieldApi` instance directly.\n * Instead, you will use a framework hook/function like `useField` or `createField`\n * 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\n * the `new FieldApi` constructor.\n */\nexport class FieldApi<\n TParentData,\n TName extends DeepKeys<TParentData>,\n TFieldValidator extends\n | Validator<DeepValue<TParentData, TName>, unknown>\n | undefined = undefined,\n TFormValidator extends\n | Validator<TParentData, unknown>\n | undefined = undefined,\n TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,\n> {\n /**\n * A reference to the form API instance.\n */\n form: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >['form']\n /**\n * The field name.\n */\n name!: DeepKeys<TParentData>\n /**\n * The field options.\n */\n options: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n > = {} as any\n /**\n * The field state store.\n */\n store!: Store<FieldState<TData>>\n /**\n * The current field state.\n */\n state!: FieldState<TData>\n /**\n * @private\n */\n prevState!: FieldState<TData>\n\n /**\n * Initializes a new `FieldApi` instance.\n */\n constructor(\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) {\n this.form = opts.form as never\n this.name = opts.name as never\n\n if (opts.defaultValue !== undefined) {\n this.form.setFieldValue(this.name, opts.defaultValue as never)\n }\n\n this.store = new Store<FieldState<TData>>(\n {\n value: this.getValue(),\n\n meta: this._getMeta() ?? {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...opts.defaultMeta,\n },\n },\n {\n onUpdate: () => {\n const state = this.store.state\n\n state.meta.errors = Object.values(state.meta.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n\n state.meta.touchedErrors = state.meta.isTouched\n ? state.meta.errors\n : []\n\n state.meta.isPristine = !state.meta.isDirty\n\n this.prevState = state\n this.state = state\n },\n },\n )\n\n this.state = this.store.state\n this.prevState = this.state\n this.options = opts as never\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends { value: TData; fieldApi: FieldApi<any, any, any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FieldValidateOrFn<any, any, any, any>\n : FieldAsyncValidateOrFn<any, any, any, any>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapters = [\n this.form.options.validatorAdapter,\n this.options.validatorAdapter,\n ] as const\n for (const adapter of adapters) {\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](\n props.value as never,\n props.validate,\n ) as never\n }\n }\n\n return (props.validate as FieldValidateFn<any, any>)(props.value) as never\n }\n\n /**\n * Mounts the field instance to the form.\n */\n mount = () => {\n const info = this.getInfo()\n info.instance = this as never\n const unsubscribe = this.form.store.subscribe(() => {\n this.store.batch(() => {\n const nextValue = this.getValue()\n const nextMeta = this.getMeta()\n\n if (nextValue !== this.state.value) {\n this.store.setState((prev) => ({ ...prev, value: nextValue }))\n }\n\n if (nextMeta !== this.state.meta) {\n this.store.setState((prev) => ({ ...prev, meta: nextMeta }))\n }\n })\n })\n\n this.update(this.options as never)\n const { onMount } = this.options.validators || {}\n\n if (onMount) {\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.value,\n fieldApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.setMeta((prev) => ({\n ...prev,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n errorMap: { ...prev?.errorMap, onMount: error },\n }))\n }\n }\n\n return () => {\n unsubscribe()\n }\n }\n\n /**\n * Updates the field instance with new options.\n */\n update = (\n opts: FieldApiOptions<\n TParentData,\n TName,\n TFieldValidator,\n TFormValidator,\n TData\n >,\n ) => {\n // Default Value\n\n if (this.state.value === undefined) {\n const formDefault = getBy(opts.form.options.defaultValues, opts.name)\n\n if (opts.defaultValue !== undefined) {\n this.setValue(opts.defaultValue as never)\n } else if (formDefault !== undefined) {\n this.setValue(formDefault as never)\n }\n }\n\n // Default Meta\n if (this._getMeta() === undefined) {\n this.setMeta(this.state.meta)\n }\n\n this.options = opts as never\n }\n\n /**\n * Gets the current field value.\n */\n getValue = (): TData => {\n return this.form.getFieldValue(this.name) as TData\n }\n\n /**\n * Sets the field value and run the `change` validator.\n */\n setValue = (\n updater: Updater<TData>,\n options?: { touch?: boolean; notify?: boolean },\n ) => {\n this.form.setFieldValue(this.name, updater as never, options)\n this.validate('change')\n }\n\n /**\n * @private\n */\n _getMeta = () => this.form.getFieldMeta(this.name)\n\n /**\n * Gets the current field metadata.\n */\n getMeta = () =>\n this._getMeta() ??\n ({\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n ...this.options.defaultMeta,\n } as FieldMeta)\n\n /**\n * Sets the field metadata.\n */\n setMeta = (updater: Updater<FieldMeta>) =>\n this.form.setFieldMeta(this.name, updater)\n\n /**\n * Gets the field information object.\n */\n getInfo = () => this.form.getFieldInfo(this.name)\n\n /**\n * Pushes a new value to the field.\n */\n pushValue = (\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.pushFieldValue(this.name, value as any, opts)\n\n /**\n * Inserts a value at the specified index, shifting the subsequent values to the right.\n */\n insertValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.insertFieldValue(this.name, index, value as any, opts)\n\n /**\n * Replaces a value at the specified index.\n */\n replaceValue = (\n index: number,\n value: TData extends any[] ? TData[number] : never,\n opts?: { touch?: boolean },\n ) => this.form.replaceFieldValue(this.name, index, value as any, opts)\n\n /**\n * Removes a value at the specified index.\n */\n removeValue = (index: number, opts?: { touch: boolean }) =>\n this.form.removeFieldValue(this.name, index, opts)\n\n /**\n * Swaps the values at the specified indices.\n */\n swapValues = (aIndex: number, bIndex: number, opts?: { touch?: boolean }) =>\n this.form.swapFieldValues(this.name, aIndex, bIndex, opts)\n\n /**\n * Moves the value at the first specified index to the second specified index.\n */\n moveValue = (aIndex: number, bIndex: number, opts?: { touch?: boolean }) =>\n this.form.moveFieldValues(this.name, aIndex, bIndex, opts)\n\n /**\n * @private\n */\n getLinkedFields = (cause: ValidationCause) => {\n const fields = Object.values(this.form.fieldInfo) as FieldInfo<\n any,\n TFormValidator\n >[]\n\n const linkedFields: FieldApi<any, any, any, any>[] = []\n for (const field of fields) {\n if (!field.instance) continue\n const { onChangeListenTo, onBlurListenTo } =\n field.instance.options.validators || {}\n if (\n cause === 'change' &&\n onChangeListenTo?.includes(this.name as string)\n ) {\n linkedFields.push(field.instance)\n }\n if (cause === 'blur' && onBlurListenTo?.includes(this.name as string)) {\n linkedFields.push(field.instance)\n }\n }\n\n return linkedFields\n }\n\n /**\n * @private\n */\n validateSync = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getSyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<SyncValidator<any> & { field: FieldApi<any, any, any, any> }>,\n )\n\n // Needs type cast as eslint errantly believes this is always falsy\n let hasErrored = false as boolean\n\n this.form.store.batch(() => {\n const validateFieldFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: SyncValidator<any>,\n ) => {\n const error = normalizeError(\n field.runValidator({\n validate: validateObj.validate,\n value: { value: field.getValue(), fieldApi: field },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (field.state.meta.errorMap[errorMapKey] !== error) {\n field.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(validateObj.cause)]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\n }\n\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldFn(this, validateObj)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldFn(fieldValitateObj.field, fieldValitateObj)\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.meta.errorMap[submitErrKey] &&\n cause !== 'submit' &&\n !hasErrored\n ) {\n this.setMeta((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n /**\n * @private\n */\n validateAsync = async (cause: ValidationCause) => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n const linkedFields = this.getLinkedFields(cause)\n const linkedFieldValidates = linkedFields.reduce(\n (acc, field) => {\n const fieldValidates = getAsyncValidatorArray(cause, field.options)\n fieldValidates.forEach((validate) => {\n ;(validate as any).field = field\n })\n return acc.concat(fieldValidates as never)\n },\n [] as Array<\n AsyncValidator<any> & { field: FieldApi<any, any, any, any> }\n >,\n )\n\n if (!this.state.meta.isValidating) {\n this.setMeta((prev) => ({ ...prev, isValidating: true }))\n }\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: 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 validatesPromises: Promise<ValidationError | undefined>[] = []\n const linkedPromises: Promise<ValidationError | undefined>[] = []\n\n const validateFieldAsyncFn = (\n field: FieldApi<any, any, any, any>,\n validateObj: AsyncValidator<any>,\n promises: Promise<ValidationError | undefined>[],\n ) => {\n const key = getErrorMapKey(validateObj.cause)\n const fieldValidatorMeta = field.getInfo().validationMetaMap[key]\n\n fieldValidatorMeta?.lastAbortController.abort()\n const controller = new AbortController()\n\n this.getInfo().validationMetaMap[key] = {\n lastAbortController: controller,\n }\n\n promises.push(\n new Promise<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | 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: field.getValue(),\n fieldApi: field,\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 error = normalizeError(rawError)\n field.setMeta((prev) => {\n return {\n ...prev,\n errorMap: {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n ...prev?.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }\n })\n\n resolve(error)\n }),\n )\n }\n\n // TODO: Dedupe this logic to reduce bundle size\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n validateFieldAsyncFn(this, validateObj, validatesPromises)\n }\n for (const fieldValitateObj of linkedFieldValidates) {\n if (!fieldValitateObj.validate) continue\n validateFieldAsyncFn(\n fieldValitateObj.field,\n fieldValitateObj,\n linkedPromises,\n )\n }\n\n let results: ValidationError[] = []\n if (validatesPromises.length || linkedPromises.length) {\n results = await Promise.all(validatesPromises)\n await Promise.all(linkedPromises)\n }\n\n this.setMeta((prev) => ({ ...prev, isValidating: false }))\n\n for (const linkedField of linkedFields) {\n linkedField.setMeta((prev) => ({ ...prev, isValidating: false }))\n }\n\n return results.filter(Boolean)\n }\n\n /**\n * Validates the field value.\n */\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // If the field is pristine and validatePristine is false, do not validate\n if (!this.state.meta.isTouched) return []\n\n try {\n this.form.validate(cause)\n } catch (_) {}\n\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.meta.errors\n }\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n /**\n * Handles the change event.\n */\n handleChange = (updater: Updater<TData>) => {\n this.setValue(updater, { touch: true })\n }\n\n /**\n * Handles the blur event.\n */\n handleBlur = () => {\n const prevTouched = this.state.meta.isTouched\n if (!prevTouched) {\n this.setMeta((prev) => ({ ...prev, isTouched: true }))\n this.validate('change')\n }\n this.validate('blur')\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return 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"],"mappings":";;AA+XO,MAAM,SAUX;AAAA;AAAA;AAAA;AAAA,EAyCA,YACE,MAOA;AA/BF,SAAA,UAMI;AAyGJ,SAAA,QAAQ,MAAM;AACN,YAAA,OAAO,KAAK;AAClB,WAAK,WAAW;AAChB,YAAM,cAAc,KAAK,KAAK,MAAM,UAAU,MAAM;AAC7C,aAAA,MAAM,MAAM,MAAM;AACf,gBAAA,YAAY,KAAK;AACjB,gBAAA,WAAW,KAAK;AAElB,cAAA,cAAc,KAAK,MAAM,OAAO;AAC7B,iBAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,UAAY,EAAA;AAAA,UAC/D;AAEI,cAAA,aAAa,KAAK,MAAM,MAAM;AAC3B,iBAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,SAAW,EAAA;AAAA,UAC7D;AAAA,QAAA,CACD;AAAA,MAAA,CACF;AAEI,WAAA,OAAO,KAAK,OAAgB;AACjC,YAAM,EAAE,QAAQ,IAAI,KAAK,QAAQ,cAAc,CAAA;AAE/C,UAAI,SAAS;AACL,cAAA,QAAQ,KAAK,aAAa;AAAA,UAC9B,UAAU;AAAA,UACV,OAAO;AAAA,YACL,OAAO,KAAK,MAAM;AAAA,YAClB,UAAU;AAAA,UACZ;AAAA,UACA,MAAM;AAAA,QAAA,CACP;AACD,YAAI,OAAO;AACJ,eAAA,QAAQ,CAAC,UAAU;AAAA,YACtB,GAAG;AAAA;AAAA,YAEH,UAAU,EAAE,GAAG,6BAAM,UAAU,SAAS,MAAM;AAAA,UAC9C,EAAA;AAAA,QACJ;AAAA,MACF;AAEA,aAAO,MAAM;AACC;MAAA;AAAA,IACd;AAMF,SAAA,SAAS,CACPA,UAOG;AAGC,UAAA,KAAK,MAAM,UAAU,QAAW;AAClC,cAAM,cAAc,MAAMA,MAAK,KAAK,QAAQ,eAAeA,MAAK,IAAI;AAEhE,YAAAA,MAAK,iBAAiB,QAAW;AAC9B,eAAA,SAASA,MAAK,YAAqB;AAAA,QAAA,WAC/B,gBAAgB,QAAW;AACpC,eAAK,SAAS,WAAoB;AAAA,QACpC;AAAA,MACF;AAGI,UAAA,KAAK,eAAe,QAAW;AAC5B,aAAA,QAAQ,KAAK,MAAM,IAAI;AAAA,MAC9B;AAEA,WAAK,UAAUA;AAAA,IAAA;AAMjB,SAAA,WAAW,MAAa;AACtB,aAAO,KAAK,KAAK,cAAc,KAAK,IAAI;AAAA,IAAA;AAM/B,SAAA,WAAA,CACT,SACA,YACG;AACH,WAAK,KAAK,cAAc,KAAK,MAAM,SAAkB,OAAO;AAC5D,WAAK,SAAS,QAAQ;AAAA,IAAA;AAMxB,SAAA,WAAW,MAAM,KAAK,KAAK,aAAa,KAAK,IAAI;AAKvC,SAAA,UAAA,MACR,KAAK,SAAA,KACJ;AAAA,MACC,cAAc;AAAA,MACd,WAAW;AAAA,MACX,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,eAAe,CAAC;AAAA,MAChB,QAAQ,CAAC;AAAA,MACT,UAAU,CAAC;AAAA,MACX,GAAG,KAAK,QAAQ;AAAA,IAAA;AAMpB,SAAA,UAAU,CAAC,YACT,KAAK,KAAK,aAAa,KAAK,MAAM,OAAO;AAK3C,SAAA,UAAU,MAAM,KAAK,KAAK,aAAa,KAAK,IAAI;AAKpC,SAAA,YAAA,CACV,OACAA,UACG,KAAK,KAAK,eAAe,KAAK,MAAM,OAAcA,KAAI;AAK7C,SAAA,cAAA,CACZ,OACA,OACAA,UACG,KAAK,KAAK,iBAAiB,KAAK,MAAM,OAAO,OAAcA,KAAI;AAKrD,SAAA,eAAA,CACb,OACA,OACAA,UACG,KAAK,KAAK,kBAAkB,KAAK,MAAM,OAAO,OAAcA,KAAI;AAKvD,SAAA,cAAA,CAAC,OAAeA,UAC5B,KAAK,KAAK,iBAAiB,KAAK,MAAM,OAAOA,KAAI;AAKtC,SAAA,aAAA,CAAC,QAAgB,QAAgBA,UAC5C,KAAK,KAAK,gBAAgB,KAAK,MAAM,QAAQ,QAAQA,KAAI;AAK/C,SAAA,YAAA,CAAC,QAAgB,QAAgBA,UAC3C,KAAK,KAAK,gBAAgB,KAAK,MAAM,QAAQ,QAAQA,KAAI;AAK3D,SAAA,kBAAkB,CAAC,UAA2B;AAC5C,YAAM,SAAS,OAAO,OAAO,KAAK,KAAK,SAAS;AAKhD,YAAM,eAA+C,CAAA;AACrD,iBAAW,SAAS,QAAQ;AAC1B,YAAI,CAAC,MAAM;AAAU;AACf,cAAA,EAAE,kBAAkB,mBACxB,MAAM,SAAS,QAAQ,cAAc;AACvC,YACE,UAAU,aACV,qDAAkB,SAAS,KAAK,QAChC;AACa,uBAAA,KAAK,MAAM,QAAQ;AAAA,QAClC;AACA,YAAI,UAAU,WAAU,iDAAgB,SAAS,KAAK,QAAiB;AACxD,uBAAA,KAAK,MAAM,QAAQ;AAAA,QAClC;AAAA,MACF;AAEO,aAAA;AAAA,IAAA;AAMT,SAAA,eAAe,CAAC,UAA2B;AACzC,YAAM,YAAY,sBAAsB,OAAO,KAAK,OAAO;AAErD,YAAA,eAAe,KAAK,gBAAgB,KAAK;AAC/C,YAAM,uBAAuB,aAAa;AAAA,QACxC,CAAC,KAAK,UAAU;AACd,gBAAM,iBAAiB,sBAAsB,OAAO,MAAM,OAAO;AAClD,yBAAA,QAAQ,CAAC,aAAa;AACjC,qBAAiB,QAAQ;AAAA,UAAA,CAC5B;AACM,iBAAA,IAAI,OAAO,cAAuB;AAAA,QAC3C;AAAA,QACA,CAAC;AAAA,MAAA;AAIH,UAAI,aAAa;AAEZ,WAAA,KAAK,MAAM,MAAM,MAAM;AACpB,cAAA,kBAAkB,CACtB,OACA,gBACG;AACH,gBAAM,QAAQ;AAAA,YACZ,MAAM,aAAa;AAAA,cACjB,UAAU,YAAY;AAAA,cACtB,OAAO,EAAE,OAAO,MAAM,SAAS,GAAG,UAAU,MAAM;AAAA,cAClD,MAAM;AAAA,YAAA,CACP;AAAA,UAAA;AAEG,gBAAA,cAAc,eAAe,YAAY,KAAK;AACpD,cAAI,MAAM,MAAM,KAAK,SAAS,WAAW,MAAM,OAAO;AAC9C,kBAAA,QAAQ,CAAC,UAAU;AAAA,cACvB,GAAG;AAAA,cACH,UAAU;AAAA,gBACR,GAAG,KAAK;AAAA,gBACR,CAAC,eAAe,YAAY,KAAK,CAAC,GAAG;AAAA,cACvC;AAAA,YACA,EAAA;AAAA,UACJ;AACA,cAAI,OAAO;AACI,yBAAA;AAAA,UACf;AAAA,QAAA;AAGF,mBAAW,eAAe,WAAW;AACnC,cAAI,CAAC,YAAY;AAAU;AAC3B,0BAAgB,MAAM,WAAW;AAAA,QACnC;AACA,mBAAW,oBAAoB,sBAAsB;AACnD,cAAI,CAAC,iBAAiB;AAAU;AAChB,0BAAA,iBAAiB,OAAO,gBAAgB;AAAA,QAC1D;AAAA,MAAA,CACD;AAMK,YAAA,eAAe,eAAe,QAAQ;AAE1C,UAAA,KAAK,MAAM,KAAK,SAAS,YAAY,KACrC,UAAU,YACV,CAAC,YACD;AACK,aAAA,QAAQ,CAAC,UAAU;AAAA,UACtB,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,KAAK;AAAA,YACR,CAAC,YAAY,GAAG;AAAA,UAClB;AAAA,QACA,EAAA;AAAA,MACJ;AAEA,aAAO,EAAE,WAAW;AAAA,IAAA;AAMtB,SAAA,gBAAgB,OAAO,UAA2B;AAChD,YAAM,YAAY,uBAAuB,OAAO,KAAK,OAAO;AAEtD,YAAA,eAAe,KAAK,gBAAgB,KAAK;AAC/C,YAAM,uBAAuB,aAAa;AAAA,QACxC,CAAC,KAAK,UAAU;AACd,gBAAM,iBAAiB,uBAAuB,OAAO,MAAM,OAAO;AACnD,yBAAA,QAAQ,CAAC,aAAa;AACjC,qBAAiB,QAAQ;AAAA,UAAA,CAC5B;AACM,iBAAA,IAAI,OAAO,cAAuB;AAAA,QAC3C;AAAA,QACA,CAAC;AAAA,MAAA;AAKH,UAAI,CAAC,KAAK,MAAM,KAAK,cAAc;AAC5B,aAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,KAAO,EAAA;AAAA,MAC1D;AAEA,iBAAW,eAAe,cAAc;AAC1B,oBAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,KAAO,EAAA;AAAA,MACjE;AAMA,YAAM,oBAA4D,CAAA;AAClE,YAAM,iBAAyD,CAAA;AAE/D,YAAM,uBAAuB,CAC3B,OACA,aACA,aACG;AACG,cAAA,MAAM,eAAe,YAAY,KAAK;AAC5C,cAAM,qBAAqB,MAAM,QAAQ,EAAE,kBAAkB,GAAG;AAEhE,iEAAoB,oBAAoB;AAClC,cAAA,aAAa,IAAI;AAEvB,aAAK,QAAQ,EAAE,kBAAkB,GAAG,IAAI;AAAA,UACtC,qBAAqB;AAAA,QAAA;AAGd,iBAAA;AAAA,UACP,IAAI,QAAqC,OAAO,YAAY;AACtD,gBAAA;AACA,gBAAA;AACF,yBAAW,MAAM,IAAI,QAAQ,CAAC,YAAY,cAAc;AACtD,2BAAW,YAAY;AACrB,sBAAI,WAAW,OAAO;AAAS,2BAAO,WAAW,MAAS;AACtD,sBAAA;AACF;AAAA,sBACE,MAAM,KAAK,aAAa;AAAA,wBACtB,UAAU,YAAY;AAAA,wBACtB,OAAO;AAAA,0BACL,OAAO,MAAM,SAAS;AAAA,0BACtB,UAAU;AAAA,0BACV,QAAQ,WAAW;AAAA,wBACrB;AAAA,wBACA,MAAM;AAAA,sBAAA,CACP;AAAA,oBAAA;AAAA,2BAEI,GAAG;AACV,8BAAU,CAAC;AAAA,kBACb;AAAA,gBAAA,GACC,YAAY,UAAU;AAAA,cAAA,CAC1B;AAAA,qBACM,GAAY;AACR,yBAAA;AAAA,YACb;AACM,kBAAA,QAAQ,eAAe,QAAQ;AAC/B,kBAAA,QAAQ,CAAC,SAAS;AACf,qBAAA;AAAA,gBACL,GAAG;AAAA,gBACH,UAAU;AAAA;AAAA,kBAER,GAAG,6BAAM;AAAA,kBACT,CAAC,eAAe,KAAK,CAAC,GAAG;AAAA,gBAC3B;AAAA,cAAA;AAAA,YACF,CACD;AAED,oBAAQ,KAAK;AAAA,UAAA,CACd;AAAA,QAAA;AAAA,MACH;AAIF,iBAAW,eAAe,WAAW;AACnC,YAAI,CAAC,YAAY;AAAU;AACN,6BAAA,MAAM,aAAa,iBAAiB;AAAA,MAC3D;AACA,iBAAW,oBAAoB,sBAAsB;AACnD,YAAI,CAAC,iBAAiB;AAAU;AAChC;AAAA,UACE,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAEA,UAAI,UAA6B,CAAA;AAC7B,UAAA,kBAAkB,UAAU,eAAe,QAAQ;AAC3C,kBAAA,MAAM,QAAQ,IAAI,iBAAiB;AACvC,cAAA,QAAQ,IAAI,cAAc;AAAA,MAClC;AAEK,WAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,MAAQ,EAAA;AAEzD,iBAAW,eAAe,cAAc;AAC1B,oBAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,MAAQ,EAAA;AAAA,MAClE;AAEO,aAAA,QAAQ,OAAO,OAAO;AAAA,IAAA;AAM/B,SAAA,WAAW,CACT,UACmD;AAE/C,UAAA,CAAC,KAAK,MAAM,KAAK;AAAW,eAAO;AAEnC,UAAA;AACG,aAAA,KAAK,SAAS,KAAK;AAAA,eACjB,GAAG;AAAA,MAAC;AAGb,YAAM,EAAE,WAAe,IAAA,KAAK,aAAa,KAAK;AAE9C,UAAI,cAAc,CAAC,KAAK,QAAQ,aAAa;AACpC,eAAA,KAAK,MAAM,KAAK;AAAA,MACzB;AAEO,aAAA,KAAK,cAAc,KAAK;AAAA,IAAA;AAMjC,SAAA,eAAe,CAAC,YAA4B;AAC1C,WAAK,SAAS,SAAS,EAAE,OAAO,KAAM,CAAA;AAAA,IAAA;AAMxC,SAAA,aAAa,MAAM;AACX,YAAA,cAAc,KAAK,MAAM,KAAK;AACpC,UAAI,CAAC,aAAa;AACX,aAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,KAAO,EAAA;AACrD,aAAK,SAAS,QAAQ;AAAA,MACxB;AACA,WAAK,SAAS,MAAM;AAAA,IAAA;AAvgBpB,SAAK,OAAO,KAAK;AACjB,SAAK,OAAO,KAAK;AAEb,QAAA,KAAK,iBAAiB,QAAW;AACnC,WAAK,KAAK,cAAc,KAAK,MAAM,KAAK,YAAqB;AAAA,IAC/D;AAEA,SAAK,QAAQ,IAAI;AAAA,MACf;AAAA,QACE,OAAO,KAAK,SAAS;AAAA,QAErB,MAAM,KAAK,cAAc;AAAA,UACvB,cAAc;AAAA,UACd,WAAW;AAAA,UACX,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,eAAe,CAAC;AAAA,UAChB,QAAQ,CAAC;AAAA,UACT,UAAU,CAAC;AAAA,UACX,GAAG,KAAK;AAAA,QACV;AAAA,MACF;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACR,gBAAA,QAAQ,KAAK,MAAM;AAEzB,gBAAM,KAAK,SAAS,OAAO,OAAO,MAAM,KAAK,QAAQ,EAAE;AAAA,YACrD,CAAC,QAAiB,QAAQ;AAAA,UAAA;AAGtB,gBAAA,KAAK,gBAAgB,MAAM,KAAK,YAClC,MAAM,KAAK,SACX;AAEJ,gBAAM,KAAK,aAAa,CAAC,MAAM,KAAK;AAEpC,eAAK,YAAY;AACjB,eAAK,QAAQ;AAAA,QACf;AAAA,MACF;AAAA,IAAA;AAGG,SAAA,QAAQ,KAAK,MAAM;AACxB,SAAK,YAAY,KAAK;AACtB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,aAGE,OAMgD;AAChD,UAAM,WAAW;AAAA,MACf,KAAK,KAAK,QAAQ;AAAA,MAClB,KAAK,QAAQ;AAAA,IAAA;AAEf,eAAW,WAAW,UAAU;AAC9B,UAAI,WAAW,OAAO,MAAM,aAAa,YAAY;AAC5C,eAAA,QAAA,EAAU,MAAM,IAAI;AAAA,UACzB,MAAM;AAAA,UACN,MAAM;AAAA,QAAA;AAAA,MAEV;AAAA,IACF;AAEQ,WAAA,MAAM,SAAuC,MAAM,KAAK;AAAA,EAClE;AA+bF;AAEA,SAAS,eAAe,UAA4B;AAClD,MAAI,UAAU;AACR,QAAA,OAAO,aAAa,UAAU;AACzB,aAAA;AAAA,IACT;AAEO,WAAA;AAAA,EACT;AAEO,SAAA;AACT;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,EACX;AACF;"}
@@ -241,16 +241,6 @@ export declare class FormApi<TFormData, TFormValidator extends Validator<TFormDa
241
241
  * @private
242
242
  */
243
243
  prevTransformArray: unknown[];
244
- /**
245
- * @private
246
- * Used to handle the edgecase of `pushFieldValue` not adding a `defaultValue` to the child `FieldAPI`s that are
247
- * subsequently generated from the `pushFieldValue` (and friends)
248
- * @see https://github.com/TanStack/form/issues/704#issuecomment-2184080607
249
- */
250
- _tempDefaultValue: undefined | {
251
- field: string;
252
- value: unknown;
253
- };
254
244
  /**
255
245
  * Constructs a new `FormApi` instance with the given form options.
256
246
  */
@@ -37,7 +37,6 @@ class FormApi {
37
37
  this.options = {};
38
38
  this.fieldInfo = {};
39
39
  this.prevTransformArray = [];
40
- this._tempDefaultValue = void 0;
41
40
  this.mount = () => {
42
41
  const { onMount } = this.options.validators || {};
43
42
  if (!onMount)
@@ -377,11 +376,6 @@ class FormApi {
377
376
  delete this.fieldInfo[field];
378
377
  };
379
378
  this.pushFieldValue = (field, value, opts2) => {
380
- const fieldVal = this.getFieldValue(field) ?? [];
381
- this._tempDefaultValue = {
382
- value,
383
- field: `${field}[${fieldVal.length}]`
384
- };
385
379
  this.setFieldValue(
386
380
  field,
387
381
  (prev) => [...Array.isArray(prev) ? prev : [], value],
@@ -390,7 +384,6 @@ class FormApi {
390
384
  this.validateField(field, "change");
391
385
  };
392
386
  this.insertFieldValue = async (field, index, value, opts2) => {
393
- this._tempDefaultValue = { value, field: `${field}[${index}]` };
394
387
  this.setFieldValue(
395
388
  field,
396
389
  (prev) => {
@@ -405,7 +398,6 @@ class FormApi {
405
398
  await this.validateField(field, "change");
406
399
  };
407
400
  this.replaceFieldValue = async (field, index, value, opts2) => {
408
- this._tempDefaultValue = { value, field: `${field}[${index}]` };
409
401
  this.setFieldValue(
410
402
  field,
411
403
  (prev) => {
@@ -1 +1 @@
1
- {"version":3,"file":"FormApi.js","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isNonEmptyArray,\n setBy,\n} from './utils'\nimport type { Updater } from './utils'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { FieldApi, FieldMeta } from './FieldApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n Validator,\n} from './types'\n\n/**\n * @private\n */\nexport type FormValidateFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n}) => ValidationError\n\n/**\n * @private\n */\nexport type FormValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer TFN>\n ? TFN\n : FormValidateFn<TFormData, TFormValidator>\n\n/**\n * @private\n */\nexport type FormValidateAsyncFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\n/**\n * @private\n */\nexport type FormAsyncValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | FormValidateAsyncFn<TFormData, TFormValidator>\n : FormValidateAsyncFn<TFormData, TFormValidator>\n\nexport interface FormValidators<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * Optional function that fires as soon as the component mounts.\n */\n onMount?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional function that checks the validity of your data whenever a value changes\n */\n onChange?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.\n */\n onChangeAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\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 ValidationError\n */\n onBlur?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional onBlur asynchronous validation method for when a field loses focus return a `ValidationError` or a promise of `Promise<ValidationError>`\n */\n onBlurAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\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?: FormValidateOrFn<TFormData, TFormValidator>\n onSubmitAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n}\n\n/**\n * @private\n */\nexport interface FormTransform<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n fn: (\n formBase: FormApi<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n deps: unknown[]\n}\n\n/**\n * An object representing the options for a form.\n */\nexport interface FormOptions<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\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<FormState<TFormData>>\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 validator adapter to support usage of extra validation types (IE: Zod, Yup, or Valibot usage)\n */\n validatorAdapter?: TFormValidator\n /**\n * A list of validators to pass to the form\n */\n validators?: FormValidators<TFormData, TFormValidator>\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<TFormData, TFormValidator>\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<TFormData, TFormValidator>\n }) => void\n transform?: FormTransform<TFormData, TFormValidator>\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<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n /**\n * An instance of the FieldAPI.\n */\n instance: FieldApi<\n TFormData,\n any,\n Validator<unknown, unknown> | undefined,\n TFormValidator\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 FormState<TFormData> = {\n /**\n * The current values of the form fields.\n */\n values: TFormData\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: ValidationError[]\n /**\n * The error map for the form itself.\n */\n errorMap: ValidationErrorMap\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.\n */\n fieldMeta: Record<DeepKeys<TFormData>, FieldMeta>\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 the form is currently submitting.\n */\n isSubmitting: 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'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 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 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 counter for tracking the number of submission attempts.\n */\n submissionAttempts: number\n}\n\nfunction getDefaultFormState<TFormData>(\n defaultState: Partial<FormState<TFormData>>,\n): FormState<TFormData> {\n return {\n values: defaultState.values ?? ({} as never),\n errors: defaultState.errors ?? [],\n errorMap: defaultState.errorMap ?? {},\n fieldMeta: defaultState.fieldMeta ?? ({} as never),\n canSubmit: defaultState.canSubmit ?? true,\n isFieldsValid: defaultState.isFieldsValid ?? false,\n isFieldsValidating: defaultState.isFieldsValidating ?? false,\n isFormValid: defaultState.isFormValid ?? false,\n isFormValidating: defaultState.isFormValidating ?? false,\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isTouched: defaultState.isTouched ?? false,\n isPristine: defaultState.isPristine ?? true,\n isDirty: defaultState.isDirty ?? false,\n isValid: defaultState.isValid ?? 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 * 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 TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * The options for the form.\n */\n options: FormOptions<TFormData, TFormValidator> = {}\n /**\n * A [TanStack Store instance](https://tanstack.com/store/latest/docs/reference/Store) that keeps track of the form's state.\n */\n store!: Store<FormState<TFormData>>\n /**\n * The current state of the form.\n *\n * **Note:**\n * Do not use `state` directly, as it is not reactive.\n * Please use form.useStore() utility to subscribe to state\n */\n state!: FormState<TFormData>\n /**\n * A record of field information for each field in the form.\n */\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData, TFormValidator>> =\n {} as any\n\n /**\n * @private\n */\n prevTransformArray: unknown[] = []\n\n /**\n * @private\n * Used to handle the edgecase of `pushFieldValue` not adding a `defaultValue` to the child `FieldAPI`s that are\n * subsequently generated from the `pushFieldValue` (and friends)\n * @see https://github.com/TanStack/form/issues/704#issuecomment-2184080607\n */\n _tempDefaultValue:\n | undefined\n | {\n field: string\n value: unknown\n } = undefined\n\n /**\n * Constructs a new `FormApi` instance with the given form options.\n */\n constructor(opts?: FormOptions<TFormData, TFormValidator>) {\n this.store = new Store<FormState<TFormData>>(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n {\n onUpdate: () => {\n let { state } = this.store\n // Computed state\n const fieldMetaValues = Object.values(state.fieldMeta) as (\n | FieldMeta\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\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const isValidating = isFieldsValidating || state.isFormValidating\n state.errors = Object.values(state.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n const isFormValid = state.errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (state.submissionAttempts === 0 && !isTouched) ||\n (!isValidating && !state.isSubmitting && isValid)\n\n state = {\n ...state,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isPristine,\n isDirty,\n }\n\n this.state = state\n this.store.state = this.state\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 // This mutates the state\n this.options.transform?.fn(this)\n this.store.state = this.state\n this.prevTransformArray = transformArray\n }\n },\n },\n )\n\n this.state = this.store.state\n\n this.update(opts || {})\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends { value: TFormData; formApi: FormApi<any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData, TFormValidator>\n : FormAsyncValidateOrFn<TFormData, TFormValidator>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapter = this.options.validatorAdapter\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](props.value, props.validate) as never\n }\n\n return (props.validate as FormValidateFn<any, any>)(props.value) as never\n }\n\n mount = () => {\n const { onMount } = this.options.validators || {}\n if (!onMount) return\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: { ...prev.errorMap, onMount: error },\n }))\n }\n }\n\n /**\n * Updates the form options and form state.\n */\n update = (options?: FormOptions<TFormData, TFormValidator>) => {\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 this.store.batch(() => {\n const shouldUpdateValues =\n options.defaultValues &&\n options.defaultValues !== oldOptions.defaultValues &&\n !this.state.isTouched\n\n const shouldUpdateState =\n options.defaultState !== oldOptions.defaultState &&\n !this.state.isTouched\n\n this.store.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 */\n reset = () => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMeta = this.resetFieldMeta(currentFieldMeta)\n this.store.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values: this.options.defaultValues ?? this.options.defaultState?.values,\n fieldMeta,\n }),\n )\n }\n\n /**\n * Validates all fields in the form using the correct handlers for a given validation type.\n */\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n this.store.batch(() => {\n void (\n Object.values(this.fieldInfo) as FieldInfo<any, TFormValidator>[]\n ).forEach((field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n Promise.resolve().then(() => fieldInstance.validate(cause)),\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 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 this.store.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 = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n this.store.batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const error = normalizeError(\n this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (this.state.errorMap[errorMapKey] !== error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\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.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n /**\n * @private\n */\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<ValidationError[]> => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.store.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<ValidationError | 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<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | 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 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 error = normalizeError(rawError)\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }))\n\n resolve(error)\n }),\n )\n }\n\n let results: ValidationError[] = []\n if (promises.length) {\n results = await Promise.all(promises)\n }\n\n this.store.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return results.filter(Boolean)\n }\n\n /**\n * @private\n */\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.errors\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 = async () => {\n this.store.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.store.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.store.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n // Validate all fields\n await this.validateAllFields('submit')\n\n // Fields are invalid, do not submit\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 // Run validation for the form\n await this.validate('submit')\n\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 try {\n // Run the submit code\n await this.options.onSubmit?.({ value: this.state.values, formApi: this })\n\n this.store.batch(() => {\n this.store.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 ): FieldMeta | 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, TFormValidator> => {\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<FieldMeta>,\n ) => {\n this.store.setState((prev) => {\n return {\n ...prev,\n fieldMeta: {\n ...prev.fieldMeta,\n [field]: functionalUpdate(updater, prev.fieldMeta[field]),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, FieldMeta>,\n ): Record<TField, FieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, FieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, FieldMeta>,\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?: { touch?: boolean },\n ) => {\n const touch = opts?.touch\n\n this.store.batch(() => {\n if (touch) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n }))\n }\n\n this.store.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.store.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMeta[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?: { touch?: boolean },\n ) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const fieldVal = (this.getFieldValue(field) as unknown[]) ?? []\n this._tempDefaultValue = {\n value,\n field: `${field}[${fieldVal.length}]`,\n } as never\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 /**\n * Inserts a value into an array field at the specified index, shifting the subsequent values to the right.\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?: { touch?: boolean },\n ) => {\n this._tempDefaultValue = { value, field: `${field}[${index}]` } as never\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\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?: { touch?: boolean },\n ) => {\n this._tempDefaultValue = { value, field: `${field}[${index}]` } as never\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?: { touch?: boolean },\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 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?: { touch?: boolean },\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 // 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?: { touch?: boolean },\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 // 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\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return 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"],"mappings":"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"}
1
+ {"version":3,"file":"FormApi.js","sources":["../../src/FormApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport {\n deleteBy,\n functionalUpdate,\n getAsyncValidatorArray,\n getBy,\n getSyncValidatorArray,\n isNonEmptyArray,\n setBy,\n} from './utils'\nimport type { Updater } from './utils'\nimport type { DeepKeys, DeepValue } from './util-types'\nimport type { FieldApi, FieldMeta } from './FieldApi'\nimport type {\n ValidationCause,\n ValidationError,\n ValidationErrorMap,\n ValidationErrorMapKeys,\n Validator,\n} from './types'\n\n/**\n * @private\n */\nexport type FormValidateFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n}) => ValidationError\n\n/**\n * @private\n */\nexport type FormValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer TFN>\n ? TFN\n : FormValidateFn<TFormData, TFormValidator>\n\n/**\n * @private\n */\nexport type FormValidateAsyncFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = (props: {\n value: TFormData\n formApi: FormApi<TFormData, TFormValidator>\n signal: AbortSignal\n}) => ValidationError | Promise<ValidationError>\n\n/**\n * @private\n */\nexport type FormAsyncValidateOrFn<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = TFormValidator extends Validator<TFormData, infer FFN>\n ? FFN | FormValidateAsyncFn<TFormData, TFormValidator>\n : FormValidateAsyncFn<TFormData, TFormValidator>\n\nexport interface FormValidators<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * Optional function that fires as soon as the component mounts.\n */\n onMount?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional function that checks the validity of your data whenever a value changes\n */\n onChange?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional onChange asynchronous counterpart to onChange. Useful for more complex validation logic that might involve server requests.\n */\n onChangeAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\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 ValidationError\n */\n onBlur?: FormValidateOrFn<TFormData, TFormValidator>\n /**\n * Optional onBlur asynchronous validation method for when a field loses focus return a `ValidationError` or a promise of `Promise<ValidationError>`\n */\n onBlurAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\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?: FormValidateOrFn<TFormData, TFormValidator>\n onSubmitAsync?: FormAsyncValidateOrFn<TFormData, TFormValidator>\n}\n\n/**\n * @private\n */\nexport interface FormTransform<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n fn: (\n formBase: FormApi<TFormData, TFormValidator>,\n ) => FormApi<TFormData, TFormValidator>\n deps: unknown[]\n}\n\n/**\n * An object representing the options for a form.\n */\nexport interface FormOptions<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\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<FormState<TFormData>>\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 validator adapter to support usage of extra validation types (IE: Zod, Yup, or Valibot usage)\n */\n validatorAdapter?: TFormValidator\n /**\n * A list of validators to pass to the form\n */\n validators?: FormValidators<TFormData, TFormValidator>\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<TFormData, TFormValidator>\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<TFormData, TFormValidator>\n }) => void\n transform?: FormTransform<TFormData, TFormValidator>\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<\n TFormData,\n TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> = {\n /**\n * An instance of the FieldAPI.\n */\n instance: FieldApi<\n TFormData,\n any,\n Validator<unknown, unknown> | undefined,\n TFormValidator\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 FormState<TFormData> = {\n /**\n * The current values of the form fields.\n */\n values: TFormData\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: ValidationError[]\n /**\n * The error map for the form itself.\n */\n errorMap: ValidationErrorMap\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.\n */\n fieldMeta: Record<DeepKeys<TFormData>, FieldMeta>\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 the form is currently submitting.\n */\n isSubmitting: 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'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 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 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 counter for tracking the number of submission attempts.\n */\n submissionAttempts: number\n}\n\nfunction getDefaultFormState<TFormData>(\n defaultState: Partial<FormState<TFormData>>,\n): FormState<TFormData> {\n return {\n values: defaultState.values ?? ({} as never),\n errors: defaultState.errors ?? [],\n errorMap: defaultState.errorMap ?? {},\n fieldMeta: defaultState.fieldMeta ?? ({} as never),\n canSubmit: defaultState.canSubmit ?? true,\n isFieldsValid: defaultState.isFieldsValid ?? false,\n isFieldsValidating: defaultState.isFieldsValidating ?? false,\n isFormValid: defaultState.isFormValid ?? false,\n isFormValidating: defaultState.isFormValidating ?? false,\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isTouched: defaultState.isTouched ?? false,\n isPristine: defaultState.isPristine ?? true,\n isDirty: defaultState.isDirty ?? false,\n isValid: defaultState.isValid ?? 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 * 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 TFormValidator extends Validator<TFormData, unknown> | undefined = undefined,\n> {\n /**\n * The options for the form.\n */\n options: FormOptions<TFormData, TFormValidator> = {}\n /**\n * A [TanStack Store instance](https://tanstack.com/store/latest/docs/reference/Store) that keeps track of the form's state.\n */\n store!: Store<FormState<TFormData>>\n /**\n * The current state of the form.\n *\n * **Note:**\n * Do not use `state` directly, as it is not reactive.\n * Please use form.useStore() utility to subscribe to state\n */\n state!: FormState<TFormData>\n /**\n * A record of field information for each field in the form.\n */\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData, TFormValidator>> =\n {} as any\n\n /**\n * @private\n */\n prevTransformArray: unknown[] = []\n\n /**\n * Constructs a new `FormApi` instance with the given form options.\n */\n constructor(opts?: FormOptions<TFormData, TFormValidator>) {\n this.store = new Store<FormState<TFormData>>(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n {\n onUpdate: () => {\n let { state } = this.store\n // Computed state\n const fieldMetaValues = Object.values(state.fieldMeta) as (\n | FieldMeta\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\n const isDirty = fieldMetaValues.some((field) => field?.isDirty)\n const isPristine = !isDirty\n\n const isValidating = isFieldsValidating || state.isFormValidating\n state.errors = Object.values(state.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n const isFormValid = state.errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (state.submissionAttempts === 0 && !isTouched) ||\n (!isValidating && !state.isSubmitting && isValid)\n\n state = {\n ...state,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n isPristine,\n isDirty,\n }\n\n this.state = state\n this.store.state = this.state\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 // This mutates the state\n this.options.transform?.fn(this)\n this.store.state = this.state\n this.prevTransformArray = transformArray\n }\n },\n },\n )\n\n this.state = this.store.state\n\n this.update(opts || {})\n }\n\n /**\n * @private\n */\n runValidator<\n TValue extends { value: TFormData; formApi: FormApi<any, any> },\n TType extends 'validate' | 'validateAsync',\n >(props: {\n validate: TType extends 'validate'\n ? FormValidateOrFn<TFormData, TFormValidator>\n : FormAsyncValidateOrFn<TFormData, TFormValidator>\n value: TValue\n type: TType\n }): ReturnType<ReturnType<Validator<any>>[TType]> {\n const adapter = this.options.validatorAdapter\n if (adapter && typeof props.validate !== 'function') {\n return adapter()[props.type](props.value, props.validate) as never\n }\n\n return (props.validate as FormValidateFn<any, any>)(props.value) as never\n }\n\n mount = () => {\n const { onMount } = this.options.validators || {}\n if (!onMount) return\n const error = this.runValidator({\n validate: onMount,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n })\n if (error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: { ...prev.errorMap, onMount: error },\n }))\n }\n }\n\n /**\n * Updates the form options and form state.\n */\n update = (options?: FormOptions<TFormData, TFormValidator>) => {\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 this.store.batch(() => {\n const shouldUpdateValues =\n options.defaultValues &&\n options.defaultValues !== oldOptions.defaultValues &&\n !this.state.isTouched\n\n const shouldUpdateState =\n options.defaultState !== oldOptions.defaultState &&\n !this.state.isTouched\n\n this.store.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 */\n reset = () => {\n const { fieldMeta: currentFieldMeta } = this.state\n const fieldMeta = this.resetFieldMeta(currentFieldMeta)\n this.store.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values: this.options.defaultValues ?? this.options.defaultState?.values,\n fieldMeta,\n }),\n )\n }\n\n /**\n * Validates all fields in the form using the correct handlers for a given validation type.\n */\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n this.store.batch(() => {\n void (\n Object.values(this.fieldInfo) as FieldInfo<any, TFormValidator>[]\n ).forEach((field) => {\n if (!field.instance) return\n const fieldInstance = field.instance\n // Validate the field\n fieldValidationPromises.push(\n Promise.resolve().then(() => fieldInstance.validate(cause)),\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 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 this.store.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 = (cause: ValidationCause) => {\n const validates = getSyncValidatorArray(cause, this.options)\n let hasErrored = false as boolean\n\n this.store.batch(() => {\n for (const validateObj of validates) {\n if (!validateObj.validate) continue\n\n const error = normalizeError(\n this.runValidator({\n validate: validateObj.validate,\n value: {\n value: this.state.values,\n formApi: this,\n },\n type: 'validate',\n }),\n )\n const errorMapKey = getErrorMapKey(validateObj.cause)\n if (this.state.errorMap[errorMapKey] !== error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: error,\n },\n }))\n }\n if (error) {\n hasErrored = true\n }\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.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [submitErrKey]: undefined,\n },\n }))\n }\n\n return { hasErrored }\n }\n\n /**\n * @private\n */\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<ValidationError[]> => {\n const validates = getAsyncValidatorArray(cause, this.options)\n\n if (!this.state.isFormValidating) {\n this.store.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<ValidationError | 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<ValidationError | undefined>(async (resolve) => {\n let rawError!: ValidationError | 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 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 error = normalizeError(rawError)\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }))\n\n resolve(error)\n }),\n )\n }\n\n let results: ValidationError[] = []\n if (promises.length) {\n results = await Promise.all(promises)\n }\n\n this.store.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n\n return results.filter(Boolean)\n }\n\n /**\n * @private\n */\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // Attempt to sync validate first\n const { hasErrored } = this.validateSync(cause)\n\n if (hasErrored && !this.options.asyncAlways) {\n return this.state.errors\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 = async () => {\n this.store.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.store.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.store.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n // Validate all fields\n await this.validateAllFields('submit')\n\n // Fields are invalid, do not submit\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 // Run validation for the form\n await this.validate('submit')\n\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 try {\n // Run the submit code\n await this.options.onSubmit?.({ value: this.state.values, formApi: this })\n\n this.store.batch(() => {\n this.store.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 ): FieldMeta | 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, TFormValidator> => {\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<FieldMeta>,\n ) => {\n this.store.setState((prev) => {\n return {\n ...prev,\n fieldMeta: {\n ...prev.fieldMeta,\n [field]: functionalUpdate(updater, prev.fieldMeta[field]),\n },\n }\n })\n }\n\n resetFieldMeta = <TField extends DeepKeys<TFormData>>(\n fieldMeta: Record<TField, FieldMeta>,\n ): Record<TField, FieldMeta> => {\n return Object.keys(fieldMeta).reduce(\n (acc: Record<TField, FieldMeta>, key) => {\n const fieldKey = key as TField\n acc[fieldKey] = {\n isValidating: false,\n isTouched: false,\n isDirty: false,\n isPristine: true,\n touchedErrors: [],\n errors: [],\n errorMap: {},\n }\n return acc\n },\n {} as Record<TField, FieldMeta>,\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?: { touch?: boolean },\n ) => {\n const touch = opts?.touch\n\n this.store.batch(() => {\n if (touch) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n isDirty: true,\n }))\n }\n\n this.store.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.store.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMeta[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?: { touch?: boolean },\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 /**\n * Inserts a value into an array field at the specified index, shifting the subsequent values to the right.\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?: { touch?: boolean },\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\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?: { touch?: boolean },\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?: { touch?: boolean },\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 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?: { touch?: boolean },\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 // 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?: { touch?: boolean },\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 // 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\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return 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"],"mappings":";;AA+QA,SAAS,oBACP,cACsB;AACf,SAAA;AAAA,IACL,QAAQ,aAAa,UAAW,CAAC;AAAA,IACjC,QAAQ,aAAa,UAAU,CAAC;AAAA,IAChC,UAAU,aAAa,YAAY,CAAC;AAAA,IACpC,WAAW,aAAa,aAAc,CAAC;AAAA,IACvC,WAAW,aAAa,aAAa;AAAA,IACrC,eAAe,aAAa,iBAAiB;AAAA,IAC7C,oBAAoB,aAAa,sBAAsB;AAAA,IACvD,aAAa,aAAa,eAAe;AAAA,IACzC,kBAAkB,aAAa,oBAAoB;AAAA,IACnD,aAAa,aAAa,eAAe;AAAA,IACzC,cAAc,aAAa,gBAAgB;AAAA,IAC3C,WAAW,aAAa,aAAa;AAAA,IACrC,YAAY,aAAa,cAAc;AAAA,IACvC,SAAS,aAAa,WAAW;AAAA,IACjC,SAAS,aAAa,WAAW;AAAA,IACjC,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,IACZ;AAAA,EAAA;AAEJ;AASO,MAAM,QAGX;AAAA;AAAA;AAAA;AAAA,EA+BA,YAAY,MAA+C;;AA3B3D,SAAA,UAAkD;AAgBlD,SAAA,YACE;AAKF,SAAA,qBAAgC;AAuGhC,SAAA,QAAQ,MAAM;AACZ,YAAM,EAAE,QAAQ,IAAI,KAAK,QAAQ,cAAc,CAAA;AAC/C,UAAI,CAAC;AAAS;AACR,YAAA,QAAQ,KAAK,aAAa;AAAA,QAC9B,UAAU;AAAA,QACV,OAAO;AAAA,UACL,OAAO,KAAK,MAAM;AAAA,UAClB,SAAS;AAAA,QACX;AAAA,QACA,MAAM;AAAA,MAAA,CACP;AACD,UAAI,OAAO;AACJ,aAAA,MAAM,SAAS,CAAC,UAAU;AAAA,UAC7B,GAAG;AAAA,UACH,UAAU,EAAE,GAAG,KAAK,UAAU,SAAS,MAAM;AAAA,QAC7C,EAAA;AAAA,MACJ;AAAA,IAAA;AAMF,SAAA,SAAS,CAAC,YAAqD;AAC7D,UAAI,CAAC;AAAS;AAEd,YAAM,aAAa,KAAK;AAGxB,WAAK,UAAU;AAEV,WAAA,MAAM,MAAM,MAAM;AACf,cAAA,qBACJ,QAAQ,iBACR,QAAQ,kBAAkB,WAAW,iBACrC,CAAC,KAAK,MAAM;AAEd,cAAM,oBACJ,QAAQ,iBAAiB,WAAW,gBACpC,CAAC,KAAK,MAAM;AAEd,aAAK,MAAM;AAAA,UAAS,MAClB;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,YACP;AAAA,UACF;AAAA,QAAA;AAAA,MACF,CACD;AAAA,IAAA;AAMH,SAAA,QAAQ,MAAM;AACZ,YAAM,EAAE,WAAW,qBAAqB,KAAK;AACvC,YAAA,YAAY,KAAK,eAAe,gBAAgB;AACtD,WAAK,MAAM;AAAA,QAAS,MAAA;;AAClB,qCAAoB;AAAA,YAClB,GAAI,KAAK,QAAQ;AAAA,YACjB,QAAQ,KAAK,QAAQ,mBAAiBA,MAAA,KAAK,QAAQ,iBAAb,gBAAAA,IAA2B;AAAA,YACjE;AAAA,UAAA,CACD;AAAA;AAAA,MAAA;AAAA,IACH;AAMF,SAAA,oBAAoB,OAAO,UAA2B;AACpD,YAAM,0BAAwD,CAAA;AACzD,WAAA,MAAM,MAAM,MAAM;AACrB,aACE,OAAO,OAAO,KAAK,SAAS,EAC5B,QAAQ,CAAC,UAAU;AACnB,cAAI,CAAC,MAAM;AAAU;AACrB,gBAAM,gBAAgB,MAAM;AAEJ,kCAAA;AAAA,YACtB,QAAQ,UAAU,KAAK,MAAM,cAAc,SAAS,KAAK,CAAC;AAAA,UAAA;AAG5D,cAAI,CAAC,MAAM,SAAS,MAAM,KAAK,WAAW;AAElC,kBAAA,SAAS,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,KAAO,EAAA;AAAA,UACjE;AAAA,QAAA,CACD;AAAA,MAAA,CACF;AAED,YAAM,mBAAmB,MAAM,QAAQ,IAAI,uBAAuB;AAClE,aAAO,iBAAiB;IAAK;AAMG,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,MAC3C;AAGA,YAAM,mBAAmB,OAAO,KAAK,KAAK,SAAS,EAAE;AAAA,QAAO,CAAC,aAC3D,oBAAoB,KAAK,CAAC,QAAQ,SAAS,WAAW,GAAG,CAAC;AAAA,MAAA;AAI5D,YAAM,0BAAwD,CAAA;AACzD,WAAA,MAAM,MAAM,MAAM;AACJ,yBAAA,QAAQ,CAAC,gBAAgB;AAChB,kCAAA;AAAA,YACtB,QAAQ,QAAU,EAAA,KAAK,MAAM,KAAK,cAAc,aAAa,KAAK,CAAC;AAAA,UAAA;AAAA,QACrE,CACD;AAAA,MAAA,CACF;AAED,YAAM,mBAAmB,MAAM,QAAQ,IAAI,uBAAuB;AAClE,aAAO,iBAAiB;IAAK;AAMf,SAAA,gBAAA,CACd,OACA,UACG;;AAEH,YAAM,iBAAgBA,MAAA,KAAK,UAAU,KAAK,MAApB,gBAAAA,IAAuB;AAC7C,UAAI,CAAC;AAAe,eAAO;AAG3B,UAAI,CAAC,cAAc,MAAM,KAAK,WAAW;AAEzB,sBAAA,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,KAAO,EAAA;AAAA,MAChE;AAEO,aAAA,cAAc,SAAS,KAAK;AAAA,IAAA;AAOrC,SAAA,eAAe,CAAC,UAA2B;AACzC,YAAM,YAAY,sBAAsB,OAAO,KAAK,OAAO;AAC3D,UAAI,aAAa;AAEZ,WAAA,MAAM,MAAM,MAAM;AACrB,mBAAW,eAAe,WAAW;AACnC,cAAI,CAAC,YAAY;AAAU;AAE3B,gBAAM,QAAQ;AAAA,YACZ,KAAK,aAAa;AAAA,cAChB,UAAU,YAAY;AAAA,cACtB,OAAO;AAAA,gBACL,OAAO,KAAK,MAAM;AAAA,gBAClB,SAAS;AAAA,cACX;AAAA,cACA,MAAM;AAAA,YAAA,CACP;AAAA,UAAA;AAEG,gBAAA,cAAc,eAAe,YAAY,KAAK;AACpD,cAAI,KAAK,MAAM,SAAS,WAAW,MAAM,OAAO;AACzC,iBAAA,MAAM,SAAS,CAAC,UAAU;AAAA,cAC7B,GAAG;AAAA,cACH,UAAU;AAAA,gBACR,GAAG,KAAK;AAAA,gBACR,CAAC,WAAW,GAAG;AAAA,cACjB;AAAA,YACA,EAAA;AAAA,UACJ;AACA,cAAI,OAAO;AACI,yBAAA;AAAA,UACf;AAAA,QACF;AAAA,MAAA,CACD;AAMK,YAAA,eAAe,eAAe,QAAQ;AAE1C,UAAA,KAAK,MAAM,SAAS,YAAY,KAChC,UAAU,YACV,CAAC,YACD;AACK,aAAA,MAAM,SAAS,CAAC,UAAU;AAAA,UAC7B,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,KAAK;AAAA,YACR,CAAC,YAAY,GAAG;AAAA,UAClB;AAAA,QACA,EAAA;AAAA,MACJ;AAEA,aAAO,EAAE,WAAW;AAAA,IAAA;AAMtB,SAAA,gBAAgB,OACd,UAC+B;AAC/B,YAAM,YAAY,uBAAuB,OAAO,KAAK,OAAO;AAExD,UAAA,CAAC,KAAK,MAAM,kBAAkB;AAC3B,aAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,kBAAkB,KAAO,EAAA;AAAA,MACrE;AAMA,YAAM,WAAmD,CAAA;AAEzD,iBAAW,eAAe,WAAW;AACnC,YAAI,CAAC,YAAY;AAAU;AACrB,cAAA,MAAM,eAAe,YAAY,KAAK;AAC5C,cAAM,qBAAqB,KAAK,MAAM,kBAAkB,GAAG;AAE3D,iEAAoB,oBAAoB;AAClC,cAAA,aAAa,IAAI;AAElB,aAAA,MAAM,kBAAkB,GAAG,IAAI;AAAA,UAClC,qBAAqB;AAAA,QAAA;AAGd,iBAAA;AAAA,UACP,IAAI,QAAqC,OAAO,YAAY;AACtD,gBAAA;AACA,gBAAA;AACF,yBAAW,MAAM,IAAI,QAAQ,CAAC,YAAY,cAAc;AACtD,2BAAW,YAAY;AACrB,sBAAI,WAAW,OAAO;AAAS,2BAAO,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,QAAQ,WAAW;AAAA,wBACrB;AAAA,wBACA,MAAM;AAAA,sBAAA,CACP;AAAA,oBAAA;AAAA,2BAEI,GAAG;AACV,8BAAU,CAAC;AAAA,kBACb;AAAA,gBAAA,GACC,YAAY,UAAU;AAAA,cAAA,CAC1B;AAAA,qBACM,GAAY;AACR,yBAAA;AAAA,YACb;AACM,kBAAA,QAAQ,eAAe,QAAQ;AAChC,iBAAA,MAAM,SAAS,CAAC,UAAU;AAAA,cAC7B,GAAG;AAAA,cACH,UAAU;AAAA,gBACR,GAAG,KAAK;AAAA,gBACR,CAAC,eAAe,KAAK,CAAC,GAAG;AAAA,cAC3B;AAAA,YACA,EAAA;AAEF,oBAAQ,KAAK;AAAA,UAAA,CACd;AAAA,QAAA;AAAA,MAEL;AAEA,UAAI,UAA6B,CAAA;AACjC,UAAI,SAAS,QAAQ;AACT,kBAAA,MAAM,QAAQ,IAAI,QAAQ;AAAA,MACtC;AAEK,WAAA,MAAM,SAAS,CAAC,UAAU;AAAA,QAC7B,GAAG;AAAA,QACH,kBAAkB;AAAA,MAClB,EAAA;AAEK,aAAA,QAAQ,OAAO,OAAO;AAAA,IAAA;AAM/B,SAAA,WAAW,CACT,UACmD;AAEnD,YAAM,EAAE,WAAe,IAAA,KAAK,aAAa,KAAK;AAE9C,UAAI,cAAc,CAAC,KAAK,QAAQ,aAAa;AAC3C,eAAO,KAAK,MAAM;AAAA,MACpB;AAGO,aAAA,KAAK,cAAc,KAAK;AAAA,IAAA;AAMjC,SAAA,eAAe,YAAY;;AACpB,WAAA,MAAM,SAAS,CAAC,SAAS;AAAA,QAC5B,GAAG;AAAA;AAAA,QAEH,aAAa;AAAA;AAAA,QAEb,oBAAoB,IAAI,qBAAqB;AAAA,MAC7C,EAAA;AAGE,UAAA,CAAC,KAAK,MAAM;AAAW;AAEtB,WAAA,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,cAAc,KAAO,EAAA;AAEzD,YAAM,OAAO,MAAM;AACZ,aAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,cAAc,MAAQ,EAAA;AAAA,MAAA;AAI5D,YAAA,KAAK,kBAAkB,QAAQ;AAGjC,UAAA,CAAC,KAAK,MAAM,eAAe;AACxB;AACL,eAAAA,MAAA,KAAK,SAAQ,oBAAb,wBAAAA,KAA+B;AAAA,UAC7B,OAAO,KAAK,MAAM;AAAA,UAClB,SAAS;AAAA,QAAA;AAEX;AAAA,MACF;AAGM,YAAA,KAAK,SAAS,QAAQ;AAExB,UAAA,CAAC,KAAK,MAAM,SAAS;AAClB;AACL,yBAAK,SAAQ,oBAAb,4BAA+B;AAAA,UAC7B,OAAO,KAAK,MAAM;AAAA,UAClB,SAAS;AAAA,QAAA;AAEX;AAAA,MACF;AAEI,UAAA;AAEI,gBAAA,gBAAK,SAAQ,aAAb,4BAAwB,EAAE,OAAO,KAAK,MAAM,QAAQ,SAAS,KAAM;AAEpE,aAAA,MAAM,MAAM,MAAM;AAChB,eAAA,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,KAAO,EAAA;AACzD;QAAA,CACN;AAAA,eACM,KAAK;AACP;AACC,cAAA;AAAA,MACR;AAAA,IAAA;AAMF,SAAA,gBAAgB,CACd,UACiC,MAAM,KAAK,MAAM,QAAQ,KAAK;AAKjE,SAAA,eAAe,CACb,UAC0B;AACnB,aAAA,KAAK,MAAM,UAAU,KAAK;AAAA,IAAA;AAMnC,SAAA,eAAe,CACb,UACyC;;AAEjC,cAAAA,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,QACZ;AAAA,MAAA;AAAA,IACF;AAMa,SAAA,eAAA,CACb,OACA,YACG;AACE,WAAA,MAAM,SAAS,CAAC,SAAS;AACrB,eAAA;AAAA,UACL,GAAG;AAAA,UACH,WAAW;AAAA,YACT,GAAG,KAAK;AAAA,YACR,CAAC,KAAK,GAAG,iBAAiB,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA,UAC1D;AAAA,QAAA;AAAA,MACF,CACD;AAAA,IAAA;AAGH,SAAA,iBAAiB,CACf,cAC8B;AACvB,aAAA,OAAO,KAAK,SAAS,EAAE;AAAA,QAC5B,CAAC,KAAgC,QAAQ;AACvC,gBAAM,WAAW;AACjB,cAAI,QAAQ,IAAI;AAAA,YACd,cAAc;AAAA,YACd,WAAW;AAAA,YACX,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,eAAe,CAAC;AAAA,YAChB,QAAQ,CAAC;AAAA,YACT,UAAU,CAAC;AAAA,UAAA;AAEN,iBAAA;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MAAA;AAAA,IACH;AAMc,SAAA,gBAAA,CACd,OACA,SACAC,UACG;AACH,YAAM,QAAQA,SAAA,gBAAAA,MAAM;AAEf,WAAA,MAAM,MAAM,MAAM;AACrB,YAAI,OAAO;AACJ,eAAA,aAAa,OAAO,CAAC,UAAU;AAAA,YAClC,GAAG;AAAA,YACH,WAAW;AAAA,YACX,SAAS;AAAA,UACT,EAAA;AAAA,QACJ;AAEK,aAAA,MAAM,SAAS,CAAC,SAAS;AACrB,iBAAA;AAAA,YACL,GAAG;AAAA,YACH,QAAQ,MAAM,KAAK,QAAQ,OAAO,OAAO;AAAA,UAAA;AAAA,QAC3C,CACD;AAAA,MAAA,CACF;AAAA,IAAA;AAGH,SAAA,cAAc,CAAqC,UAAkB;AAC9D,WAAA,MAAM,SAAS,CAAC,SAAS;AACtB,cAAA,WAAW,EAAE,GAAG;AACtB,iBAAS,SAAS,SAAS,SAAS,QAAQ,KAAK;AAC1C,eAAA,SAAS,UAAU,KAAK;AAExB,eAAA;AAAA,MAAA,CACR;AACM,aAAA,KAAK,UAAU,KAAK;AAAA,IAAA;AAMZ,SAAA,iBAAA,CACf,OACA,OAGAA,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAS,CAAC,GAAI,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAI,KAAK;AAAA,QACtDA;AAAA,MAAA;AAEG,WAAA,cAAc,OAAO,QAAQ;AAAA,IAAA;AAMpC,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,UAAA;AAAA,QAE3D;AAAA,QACAA;AAAA,MAAA;AAII,YAAA,KAAK,cAAc,OAAO,QAAQ;AAAA,IAAA;AAM1C,SAAA,oBAAoB,OAClB,OACA,OACA,OAGAA,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAS;AACR,iBAAQ,KAAwC;AAAA,YAAI,CAAC,GAAG,MACtD,MAAM,QAAQ,QAAQ;AAAA,UAAA;AAAA,QAE1B;AAAA,QACAA;AAAA,MAAA;AAII,YAAA,KAAK,cAAc,OAAO,QAAQ;AACxC,YAAM,KAAK,gCAAgC,OAAO,OAAO,QAAQ;AAAA,IAAA;AAMhD,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,UAAA;AAAA,QAErB;AAAA,QACAA;AAAA,MAAA;AAGF,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,QAAA;AAIpB,uBAAe,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAW,CAAC;AAAA,MAC7D;AAGM,YAAA,KAAK,cAAc,OAAO,QAAQ;AACxC,YAAM,KAAK,gCAAgC,OAAO,OAAO,QAAQ;AAAA,IAAA;AAMnE,SAAA,kBAAkB,CAChB,OACA,QACA,QACAA,UACG;AACE,WAAA;AAAA,QACH;AAAA,QACA,CAAC,SAAc;AACP,gBAAA,QAAQ,KAAK,MAAM;AACnB,gBAAA,QAAQ,KAAK,MAAM;AAClB,iBAAA,MAAM,MAAM,MAAM,GAAG,MAAM,IAAI,KAAK,GAAG,GAAG,MAAM,IAAI,KAAK;AAAA,QAClE;AAAA,QACAA;AAAA,MAAA;AAIG,WAAA,cAAc,OAAO,QAAQ;AAElC,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AACzE,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AAAA,IAAA;AAM3E,SAAA,kBAAkB,CAChB,OACA,QACA,QACAA,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,MAAA;AAIG,WAAA,cAAc,OAAO,QAAQ;AAElC,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AACzE,WAAK,cAAc,GAAG,KAAK,IAAI,MAAM,KAA4B,QAAQ;AAAA,IAAA;AA7uBzE,SAAK,QAAQ,IAAI;AAAA,MACf,oBAAoB;AAAA,QAClB,GAAI,6BAAM;AAAA,QACV,SAAQ,6BAAM,oBAAiB,kCAAM,iBAAN,mBAAoB;AAAA,QACnD,aAAa;AAAA,MAAA,CACd;AAAA,MACD;AAAA,QACE,UAAU,MAAM;;AACV,cAAA,EAAE,MAAM,IAAI,KAAK;AAErB,gBAAM,kBAAkB,OAAO,OAAO,MAAM,SAAS;AAKrD,gBAAM,qBAAqB,gBAAgB;AAAA,YACzC,CAAC,UAAU,+BAAO;AAAA,UAAA;AAGd,gBAAA,gBAAgB,CAAC,gBAAgB;AAAA,YACrC,CAAC,WACC,+BAAO,aACP,gBAAgB,OAAO,OAAO,MAAM,QAAQ,EAAE,OAAO,OAAO,CAAC;AAAA,UAAA;AAGjE,gBAAM,YAAY,gBAAgB,KAAK,CAAC,UAAU,+BAAO,SAAS;AAElE,gBAAM,UAAU,gBAAgB,KAAK,CAAC,UAAU,+BAAO,OAAO;AAC9D,gBAAM,aAAa,CAAC;AAEd,gBAAA,eAAe,sBAAsB,MAAM;AACjD,gBAAM,SAAS,OAAO,OAAO,MAAM,QAAQ,EAAE;AAAA,YAC3C,CAAC,QAAiB,QAAQ;AAAA,UAAA;AAEtB,gBAAA,cAAc,MAAM,OAAO,WAAW;AAC5C,gBAAM,UAAU,iBAAiB;AAC3B,gBAAA,YACH,MAAM,uBAAuB,KAAK,CAAC,aACnC,CAAC,gBAAgB,CAAC,MAAM,gBAAgB;AAEnC,kBAAA;AAAA,YACN,GAAG;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAGF,eAAK,QAAQ;AACR,eAAA,MAAM,QAAQ,KAAK;AAGxB,gBAAM,mBAAiBD,MAAA,KAAK,QAAQ,cAAb,gBAAAA,IAAwB,SAAQ,CAAA;AACvD,gBAAM,kBACJ,eAAe,WAAW,KAAK,mBAAmB,UAClD,eAAe,KAAK,CAAC,KAAK,MAAM,QAAQ,KAAK,mBAAmB,CAAC,CAAC;AAEpE,cAAI,iBAAiB;AAEd,uBAAA,QAAQ,cAAR,mBAAmB,GAAG;AACtB,iBAAA,MAAM,QAAQ,KAAK;AACxB,iBAAK,qBAAqB;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,IAAA;AAGG,SAAA,QAAQ,KAAK,MAAM;AAEnB,SAAA,OAAO,QAAQ,CAAA,CAAE;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,aAGE,OAMgD;AAC1C,UAAA,UAAU,KAAK,QAAQ;AAC7B,QAAI,WAAW,OAAO,MAAM,aAAa,YAAY;AAC5C,aAAA,QAAA,EAAU,MAAM,IAAI,EAAE,MAAM,OAAO,MAAM,QAAQ;AAAA,IAC1D;AAEQ,WAAA,MAAM,SAAsC,MAAM,KAAK;AAAA,EACjE;AAgpBF;AAEA,SAAS,eAAe,UAA4B;AAClD,MAAI,UAAU;AACR,QAAA,OAAO,aAAa,UAAU;AACzB,aAAA;AAAA,IACT;AAEO,WAAA;AAAA,EACT;AAEO,SAAA;AACT;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,EACX;AACF;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/form-core",
3
- "version": "0.23.3",
3
+ "version": "0.24.2",
4
4
  "description": "Powerful, type-safe, framework agnostic forms.",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
package/src/FieldApi.ts CHANGED
@@ -281,7 +281,6 @@ export interface FieldOptions<
281
281
  * If `true`, always run async validation, even if there are errors emitted during synchronous validation.
282
282
  */
283
283
  asyncAlways?: boolean
284
- preserveValue?: boolean
285
284
  /**
286
285
  * A validator provided by an extension, like `yupValidator` from `@tanstack/yup-form-adapter`
287
286
  */
@@ -445,14 +444,6 @@ export class FieldApi<
445
444
  this.form = opts.form as never
446
445
  this.name = opts.name as never
447
446
 
448
- if (
449
- opts.defaultValue === undefined &&
450
- this.form._tempDefaultValue !== undefined &&
451
- this.form._tempDefaultValue.field === this.name
452
- ) {
453
- opts.defaultValue = this.form._tempDefaultValue.value as never
454
- }
455
-
456
447
  if (opts.defaultValue !== undefined) {
457
448
  this.form.setFieldValue(this.name, opts.defaultValue as never)
458
449
  }
@@ -488,17 +479,6 @@ export class FieldApi<
488
479
 
489
480
  this.prevState = state
490
481
  this.state = state
491
-
492
- // Cleanup the temp value after this "tick"
493
- // (Everything occurs sync otherwise)
494
- setTimeout(() => {
495
- if (
496
- this.form._tempDefaultValue !== undefined &&
497
- this.form._tempDefaultValue.field === this.name
498
- ) {
499
- this.form._tempDefaultValue = undefined
500
- }
501
- }, 0)
502
482
  },
503
483
  },
504
484
  )
@@ -580,11 +560,7 @@ export class FieldApi<
580
560
  }
581
561
 
582
562
  return () => {
583
- const preserveValue = this.options.preserveValue
584
563
  unsubscribe()
585
- if (!preserveValue) {
586
- this.form.deleteField(this.name)
587
- }
588
564
  }
589
565
  }
590
566
 
@@ -617,14 +593,6 @@ export class FieldApi<
617
593
  this.setMeta(this.state.meta)
618
594
  }
619
595
 
620
- if (
621
- opts.defaultValue === undefined &&
622
- this.form._tempDefaultValue !== undefined &&
623
- this.form._tempDefaultValue.field === this.name
624
- ) {
625
- opts.defaultValue = this.form._tempDefaultValue.value as never
626
- }
627
-
628
596
  this.options = opts as never
629
597
  }
630
598
 
package/src/FormApi.ts CHANGED
@@ -338,19 +338,6 @@ export class FormApi<
338
338
  */
339
339
  prevTransformArray: unknown[] = []
340
340
 
341
- /**
342
- * @private
343
- * Used to handle the edgecase of `pushFieldValue` not adding a `defaultValue` to the child `FieldAPI`s that are
344
- * subsequently generated from the `pushFieldValue` (and friends)
345
- * @see https://github.com/TanStack/form/issues/704#issuecomment-2184080607
346
- */
347
- _tempDefaultValue:
348
- | undefined
349
- | {
350
- field: string
351
- value: unknown
352
- } = undefined
353
-
354
341
  /**
355
342
  * Constructs a new `FormApi` instance with the given form options.
356
343
  */
@@ -956,12 +943,6 @@ export class FormApi<
956
943
  : never,
957
944
  opts?: { touch?: boolean },
958
945
  ) => {
959
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
960
- const fieldVal = (this.getFieldValue(field) as unknown[]) ?? []
961
- this._tempDefaultValue = {
962
- value,
963
- field: `${field}[${fieldVal.length}]`,
964
- } as never
965
946
  this.setFieldValue(
966
947
  field,
967
948
  (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,
@@ -981,7 +962,6 @@ export class FormApi<
981
962
  : never,
982
963
  opts?: { touch?: boolean },
983
964
  ) => {
984
- this._tempDefaultValue = { value, field: `${field}[${index}]` } as never
985
965
  this.setFieldValue(
986
966
  field,
987
967
  (prev) => {
@@ -1009,7 +989,6 @@ export class FormApi<
1009
989
  : never,
1010
990
  opts?: { touch?: boolean },
1011
991
  ) => {
1012
- this._tempDefaultValue = { value, field: `${field}[${index}]` } as never
1013
992
  this.setFieldValue(
1014
993
  field,
1015
994
  (prev) => {