@tanstack/form-core 1.24.5 → 1.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,36 +13,94 @@ const defaultFieldMeta = {
13
13
  errorSourceMap: {}
14
14
  };
15
15
  function metaHelper(formApi) {
16
- function handleArrayFieldMetaShift(field, index, mode, secondIndex) {
17
- const affectedFields = getAffectedFields(field, index, mode, secondIndex);
18
- const handlers = {
19
- insert: () => handleInsertMode(affectedFields, field, index),
20
- remove: () => handleRemoveMode(affectedFields),
21
- swap: () => secondIndex !== void 0 && handleSwapMode(affectedFields, field, index, secondIndex),
22
- move: () => secondIndex !== void 0 && handleMoveMode(affectedFields, field, index, secondIndex)
23
- };
24
- handlers[mode]();
16
+ function handleArrayMove(field, fromIndex, toIndex) {
17
+ const affectedFields = getAffectedFields(field, fromIndex, "move", toIndex);
18
+ const startIndex = Math.min(fromIndex, toIndex);
19
+ const endIndex = Math.max(fromIndex, toIndex);
20
+ for (let i = startIndex; i <= endIndex; i++) {
21
+ affectedFields.push(getFieldPath(field, i));
22
+ }
23
+ const fromFields = Object.keys(formApi.fieldInfo).reduce(
24
+ (fieldMap, fieldKey) => {
25
+ if (fieldKey.startsWith(getFieldPath(field, fromIndex))) {
26
+ fieldMap.set(
27
+ fieldKey,
28
+ formApi.getFieldMeta(fieldKey)
29
+ );
30
+ }
31
+ return fieldMap;
32
+ },
33
+ /* @__PURE__ */ new Map()
34
+ );
35
+ shiftMeta(affectedFields, fromIndex < toIndex ? "up" : "down");
36
+ Object.keys(formApi.fieldInfo).filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex))).forEach((fieldKey) => {
37
+ const fromKey = fieldKey.replace(
38
+ getFieldPath(field, toIndex),
39
+ getFieldPath(field, fromIndex)
40
+ );
41
+ const fromMeta = fromFields.get(fromKey);
42
+ if (fromMeta) {
43
+ formApi.setFieldMeta(fieldKey, fromMeta);
44
+ }
45
+ });
46
+ }
47
+ function handleArrayRemove(field, index) {
48
+ const affectedFields = getAffectedFields(field, index, "remove");
49
+ shiftMeta(affectedFields, "up");
50
+ }
51
+ function handleArraySwap(field, index, secondIndex) {
52
+ const affectedFields = getAffectedFields(field, index, "swap", secondIndex);
53
+ affectedFields.forEach((fieldKey) => {
54
+ if (!fieldKey.toString().startsWith(getFieldPath(field, index))) {
55
+ return;
56
+ }
57
+ const swappedKey = fieldKey.toString().replace(
58
+ getFieldPath(field, index),
59
+ getFieldPath(field, secondIndex)
60
+ );
61
+ const [meta1, meta2] = [
62
+ formApi.getFieldMeta(fieldKey),
63
+ formApi.getFieldMeta(swappedKey)
64
+ ];
65
+ if (meta1) formApi.setFieldMeta(swappedKey, meta1);
66
+ if (meta2) formApi.setFieldMeta(fieldKey, meta2);
67
+ });
68
+ }
69
+ function handleArrayInsert(field, insertIndex) {
70
+ const affectedFields = getAffectedFields(field, insertIndex, "insert");
71
+ shiftMeta(affectedFields, "down");
72
+ affectedFields.forEach((fieldKey) => {
73
+ if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {
74
+ formApi.setFieldMeta(fieldKey, getEmptyFieldMeta());
75
+ }
76
+ });
25
77
  }
26
78
  function getFieldPath(field, index) {
27
79
  return `${field}[${index}]`;
28
80
  }
29
81
  function getAffectedFields(field, index, mode, secondIndex) {
30
82
  const affectedFieldKeys = [getFieldPath(field, index)];
31
- if (mode === "swap") {
32
- affectedFieldKeys.push(getFieldPath(field, secondIndex));
33
- } else if (mode === "move") {
34
- const [startIndex, endIndex] = [
35
- Math.min(index, secondIndex),
36
- Math.max(index, secondIndex)
37
- ];
38
- for (let i = startIndex; i <= endIndex; i++) {
39
- affectedFieldKeys.push(getFieldPath(field, i));
83
+ switch (mode) {
84
+ case "swap":
85
+ affectedFieldKeys.push(getFieldPath(field, secondIndex));
86
+ break;
87
+ case "move": {
88
+ const [startIndex, endIndex] = [
89
+ Math.min(index, secondIndex),
90
+ Math.max(index, secondIndex)
91
+ ];
92
+ for (let i = startIndex; i <= endIndex; i++) {
93
+ affectedFieldKeys.push(getFieldPath(field, i));
94
+ }
95
+ break;
40
96
  }
41
- } else {
42
- const currentValue = formApi.getFieldValue(field);
43
- const fieldItems = Array.isArray(currentValue) ? currentValue.length : 0;
44
- for (let i = index + 1; i < fieldItems; i++) {
45
- affectedFieldKeys.push(getFieldPath(field, i));
97
+ default: {
98
+ const currentValue = formApi.getFieldValue(field);
99
+ const fieldItems = Array.isArray(currentValue) ? currentValue.length : 0;
100
+ for (let i = index + 1; i < fieldItems; i++) {
101
+ affectedFieldKeys.push(getFieldPath(field, i));
102
+ }
103
+ break;
46
104
  }
47
105
  }
48
106
  return Object.keys(formApi.fieldInfo).filter(
@@ -69,54 +127,12 @@ function metaHelper(formApi) {
69
127
  });
70
128
  }
71
129
  const getEmptyFieldMeta = () => defaultFieldMeta;
72
- const handleInsertMode = (fields, field, insertIndex) => {
73
- shiftMeta(fields, "down");
74
- fields.forEach((fieldKey) => {
75
- if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {
76
- formApi.setFieldMeta(fieldKey, getEmptyFieldMeta());
77
- }
78
- });
79
- };
80
- const handleRemoveMode = (fields) => {
81
- shiftMeta(fields, "up");
82
- };
83
- const handleMoveMode = (fields, field, fromIndex, toIndex) => {
84
- const fromFields = new Map(
85
- Object.keys(formApi.fieldInfo).filter(
86
- (fieldKey) => fieldKey.startsWith(getFieldPath(field, fromIndex))
87
- ).map((fieldKey) => [
88
- fieldKey,
89
- formApi.getFieldMeta(fieldKey)
90
- ])
91
- );
92
- shiftMeta(fields, fromIndex < toIndex ? "up" : "down");
93
- Object.keys(formApi.fieldInfo).filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex))).forEach((fieldKey) => {
94
- const fromKey = fieldKey.replace(
95
- getFieldPath(field, toIndex),
96
- getFieldPath(field, fromIndex)
97
- );
98
- const fromMeta = fromFields.get(fromKey);
99
- if (fromMeta) {
100
- formApi.setFieldMeta(fieldKey, fromMeta);
101
- }
102
- });
103
- };
104
- const handleSwapMode = (fields, field, index, secondIndex) => {
105
- fields.forEach((fieldKey) => {
106
- if (!fieldKey.toString().startsWith(getFieldPath(field, index))) return;
107
- const swappedKey = fieldKey.toString().replace(
108
- getFieldPath(field, index),
109
- getFieldPath(field, secondIndex)
110
- );
111
- const [meta1, meta2] = [
112
- formApi.getFieldMeta(fieldKey),
113
- formApi.getFieldMeta(swappedKey)
114
- ];
115
- if (meta1) formApi.setFieldMeta(swappedKey, meta1);
116
- if (meta2) formApi.setFieldMeta(fieldKey, meta2);
117
- });
130
+ return {
131
+ handleArrayMove,
132
+ handleArrayRemove,
133
+ handleArraySwap,
134
+ handleArrayInsert
118
135
  };
119
- return { handleArrayFieldMetaShift };
120
136
  }
121
137
  exports.defaultFieldMeta = defaultFieldMeta;
122
138
  exports.metaHelper = metaHelper;
@@ -1 +1 @@
1
- {"version":3,"file":"metaHelper.cjs","sources":["../../src/metaHelper.ts"],"sourcesContent":["import type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMeta } from './FieldApi'\nimport type { DeepKeys } from './util-types'\n\ntype ArrayFieldMode = 'insert' | 'remove' | 'swap' | 'move'\n\nexport const defaultFieldMeta: AnyFieldMeta = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n isValid: true,\n isDefaultValue: true,\n errors: [],\n errorMap: {},\n errorSourceMap: {},\n}\n\nexport function metaHelper<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta,\n>(\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n function handleArrayFieldMetaShift(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ArrayFieldMode,\n secondIndex?: number,\n ) {\n const affectedFields = getAffectedFields(field, index, mode, secondIndex)\n\n const handlers = {\n insert: () => handleInsertMode(affectedFields, field, index),\n remove: () => handleRemoveMode(affectedFields),\n swap: () =>\n secondIndex !== undefined &&\n handleSwapMode(affectedFields, field, index, secondIndex),\n move: () =>\n secondIndex !== undefined &&\n handleMoveMode(affectedFields, field, index, secondIndex),\n }\n\n handlers[mode]()\n }\n\n function getFieldPath(field: DeepKeys<TFormData>, index: number): string {\n return `${field}[${index}]`\n }\n\n function getAffectedFields(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ArrayFieldMode,\n secondIndex?: number,\n ): DeepKeys<TFormData>[] {\n const affectedFieldKeys = [getFieldPath(field, index)]\n\n if (mode === 'swap') {\n affectedFieldKeys.push(getFieldPath(field, secondIndex!))\n } else if (mode === 'move') {\n const [startIndex, endIndex] = [\n Math.min(index, secondIndex!),\n Math.max(index, secondIndex!),\n ]\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n } else {\n const currentValue = formApi.getFieldValue(field)\n const fieldItems = Array.isArray(currentValue)\n ? (currentValue as Array<unknown>).length\n : 0\n for (let i = index + 1; i < fieldItems; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n }\n\n return Object.keys(formApi.fieldInfo).filter((fieldKey) =>\n affectedFieldKeys.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n }\n\n function updateIndex(\n fieldKey: string,\n direction: 'up' | 'down',\n ): DeepKeys<TFormData> {\n return fieldKey.replace(/\\[(\\d+)\\]/, (_, num) => {\n const currIndex = parseInt(num, 10)\n const newIndex =\n direction === 'up' ? currIndex + 1 : Math.max(0, currIndex - 1)\n return `[${newIndex}]`\n }) as DeepKeys<TFormData>\n }\n\n function shiftMeta(fields: DeepKeys<TFormData>[], direction: 'up' | 'down') {\n const sortedFields = direction === 'up' ? fields : [...fields].reverse()\n\n sortedFields.forEach((fieldKey) => {\n const nextFieldKey = updateIndex(fieldKey.toString(), direction)\n const nextFieldMeta = formApi.getFieldMeta(nextFieldKey)\n if (nextFieldMeta) {\n formApi.setFieldMeta(fieldKey, nextFieldMeta)\n } else {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const getEmptyFieldMeta = (): AnyFieldMeta => defaultFieldMeta\n\n const handleInsertMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n insertIndex: number,\n ) => {\n shiftMeta(fields, 'down')\n\n fields.forEach((fieldKey) => {\n if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const handleRemoveMode = (fields: DeepKeys<TFormData>[]) => {\n shiftMeta(fields, 'up')\n }\n\n const handleMoveMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n fromIndex: number,\n toIndex: number,\n ) => {\n // Store the original field meta that will be reapplied at the destination index\n const fromFields = new Map(\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) =>\n fieldKey.startsWith(getFieldPath(field, fromIndex)),\n )\n .map((fieldKey) => [\n fieldKey as DeepKeys<TFormData>,\n formApi.getFieldMeta(fieldKey as DeepKeys<TFormData>),\n ]),\n )\n\n shiftMeta(fields, fromIndex < toIndex ? 'up' : 'down')\n\n // Reapply the stored field meta at the destination index\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex)))\n .forEach((fieldKey) => {\n const fromKey = fieldKey.replace(\n getFieldPath(field, toIndex),\n getFieldPath(field, fromIndex),\n ) as DeepKeys<TFormData>\n\n const fromMeta = fromFields.get(fromKey)\n if (fromMeta) {\n formApi.setFieldMeta(fieldKey as DeepKeys<TFormData>, fromMeta)\n }\n })\n }\n\n const handleSwapMode = (\n fields: DeepKeys<TFormData>[],\n field: DeepKeys<TFormData>,\n index: number,\n secondIndex: number,\n ) => {\n fields.forEach((fieldKey) => {\n if (!fieldKey.toString().startsWith(getFieldPath(field, index))) return\n\n const swappedKey = fieldKey\n .toString()\n .replace(\n getFieldPath(field, index),\n getFieldPath(field, secondIndex),\n ) as DeepKeys<TFormData>\n\n const [meta1, meta2] = [\n formApi.getFieldMeta(fieldKey),\n formApi.getFieldMeta(swappedKey),\n ]\n\n if (meta1) formApi.setFieldMeta(swappedKey, meta1)\n if (meta2) formApi.setFieldMeta(fieldKey, meta2)\n })\n }\n\n return { handleArrayFieldMetaShift }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"metaHelper.cjs","sources":["../../src/metaHelper.ts"],"sourcesContent":["import type {\n FormApi,\n FormAsyncValidateOrFn,\n FormValidateOrFn,\n} from './FormApi'\nimport type { AnyFieldMeta } from './FieldApi'\nimport type { DeepKeys } from './util-types'\n\ntype ValueFieldMode = 'insert' | 'remove' | 'swap' | 'move'\n\nexport const defaultFieldMeta: AnyFieldMeta = {\n isValidating: false,\n isTouched: false,\n isBlurred: false,\n isDirty: false,\n isPristine: true,\n isValid: true,\n isDefaultValue: true,\n errors: [],\n errorMap: {},\n errorSourceMap: {},\n}\n\nexport function metaHelper<\n TFormData,\n TOnMount extends undefined | FormValidateOrFn<TFormData>,\n TOnChange extends undefined | FormValidateOrFn<TFormData>,\n TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnBlur extends undefined | FormValidateOrFn<TFormData>,\n TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnSubmit extends undefined | FormValidateOrFn<TFormData>,\n TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnDynamic extends undefined | FormValidateOrFn<TFormData>,\n TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>,\n TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,\n TSubmitMeta = never,\n>(\n formApi: FormApi<\n TFormData,\n TOnMount,\n TOnChange,\n TOnChangeAsync,\n TOnBlur,\n TOnBlurAsync,\n TOnSubmit,\n TOnSubmitAsync,\n TOnDynamic,\n TOnDynamicAsync,\n TOnServer,\n TSubmitMeta\n >,\n) {\n /**\n * Handle the meta shift caused from moving a field from one index to another.\n */\n function handleArrayMove(\n field: DeepKeys<TFormData>,\n fromIndex: number,\n toIndex: number,\n ) {\n const affectedFields = getAffectedFields(field, fromIndex, 'move', toIndex)\n\n const startIndex = Math.min(fromIndex, toIndex)\n const endIndex = Math.max(fromIndex, toIndex)\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFields.push(getFieldPath(field, i))\n }\n\n // Store the original field meta that will be reapplied at the destination index\n const fromFields = Object.keys(formApi.fieldInfo).reduce(\n (fieldMap, fieldKey) => {\n if (fieldKey.startsWith(getFieldPath(field, fromIndex))) {\n fieldMap.set(\n fieldKey as DeepKeys<TFormData>,\n formApi.getFieldMeta(fieldKey as DeepKeys<TFormData>),\n )\n }\n return fieldMap\n },\n new Map<DeepKeys<TFormData>, AnyFieldMeta | undefined>(),\n )\n\n shiftMeta(affectedFields, fromIndex < toIndex ? 'up' : 'down')\n\n // Reapply the stored field meta at the destination index\n Object.keys(formApi.fieldInfo)\n .filter((fieldKey) => fieldKey.startsWith(getFieldPath(field, toIndex)))\n .forEach((fieldKey) => {\n const fromKey = fieldKey.replace(\n getFieldPath(field, toIndex),\n getFieldPath(field, fromIndex),\n ) as DeepKeys<TFormData>\n\n const fromMeta = fromFields.get(fromKey)\n if (fromMeta) {\n formApi.setFieldMeta(fieldKey as DeepKeys<TFormData>, fromMeta)\n }\n })\n }\n\n /**\n * Handle the meta shift from removing a field at the specified index.\n */\n function handleArrayRemove(field: DeepKeys<TFormData>, index: number) {\n const affectedFields = getAffectedFields(field, index, 'remove')\n\n shiftMeta(affectedFields, 'up')\n }\n\n /**\n * Handle the meta shift from swapping two fields at the specified indeces.\n */\n function handleArraySwap(\n field: DeepKeys<TFormData>,\n index: number,\n secondIndex: number,\n ) {\n const affectedFields = getAffectedFields(field, index, 'swap', secondIndex)\n\n affectedFields.forEach((fieldKey) => {\n if (!fieldKey.toString().startsWith(getFieldPath(field, index))) {\n return\n }\n\n const swappedKey = fieldKey\n .toString()\n .replace(\n getFieldPath(field, index),\n getFieldPath(field, secondIndex),\n ) as DeepKeys<TFormData>\n\n const [meta1, meta2] = [\n formApi.getFieldMeta(fieldKey),\n formApi.getFieldMeta(swappedKey),\n ]\n\n if (meta1) formApi.setFieldMeta(swappedKey, meta1)\n if (meta2) formApi.setFieldMeta(fieldKey, meta2)\n })\n }\n\n /**\n * Handle the meta shift from inserting a field at the specified index.\n */\n function handleArrayInsert(field: DeepKeys<TFormData>, insertIndex: number) {\n const affectedFields = getAffectedFields(field, insertIndex, 'insert')\n\n shiftMeta(affectedFields, 'down')\n\n affectedFields.forEach((fieldKey) => {\n if (fieldKey.toString().startsWith(getFieldPath(field, insertIndex))) {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n function getFieldPath(\n field: DeepKeys<TFormData>,\n index: number,\n ): DeepKeys<TFormData> {\n return `${field}[${index}]` as DeepKeys<TFormData>\n }\n\n function getAffectedFields(\n field: DeepKeys<TFormData>,\n index: number,\n mode: ValueFieldMode,\n secondIndex?: number,\n ): DeepKeys<TFormData>[] {\n const affectedFieldKeys = [getFieldPath(field, index)]\n\n switch (mode) {\n case 'swap':\n affectedFieldKeys.push(getFieldPath(field, secondIndex!))\n break\n case 'move': {\n const [startIndex, endIndex] = [\n Math.min(index, secondIndex!),\n Math.max(index, secondIndex!),\n ]\n for (let i = startIndex; i <= endIndex; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n default: {\n const currentValue = formApi.getFieldValue(field)\n const fieldItems = Array.isArray(currentValue)\n ? (currentValue as Array<unknown>).length\n : 0\n for (let i = index + 1; i < fieldItems; i++) {\n affectedFieldKeys.push(getFieldPath(field, i))\n }\n break\n }\n }\n\n return Object.keys(formApi.fieldInfo).filter((fieldKey) =>\n affectedFieldKeys.some((key) => fieldKey.startsWith(key)),\n ) as DeepKeys<TFormData>[]\n }\n\n function updateIndex(\n fieldKey: string,\n direction: 'up' | 'down',\n ): DeepKeys<TFormData> {\n return fieldKey.replace(/\\[(\\d+)\\]/, (_, num) => {\n const currIndex = parseInt(num, 10)\n const newIndex =\n direction === 'up' ? currIndex + 1 : Math.max(0, currIndex - 1)\n return `[${newIndex}]`\n }) as DeepKeys<TFormData>\n }\n\n function shiftMeta(fields: DeepKeys<TFormData>[], direction: 'up' | 'down') {\n const sortedFields = direction === 'up' ? fields : [...fields].reverse()\n\n sortedFields.forEach((fieldKey) => {\n const nextFieldKey = updateIndex(fieldKey.toString(), direction)\n const nextFieldMeta = formApi.getFieldMeta(nextFieldKey)\n if (nextFieldMeta) {\n formApi.setFieldMeta(fieldKey, nextFieldMeta)\n } else {\n formApi.setFieldMeta(fieldKey, getEmptyFieldMeta())\n }\n })\n }\n\n const getEmptyFieldMeta = (): AnyFieldMeta => defaultFieldMeta\n\n return {\n handleArrayMove,\n handleArrayRemove,\n handleArraySwap,\n handleArrayInsert,\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.cjs';
2
2
  import { AnyFieldMeta } from './FieldApi.cjs';
3
3
  import { DeepKeys } from './util-types.cjs';
4
- type ArrayFieldMode = 'insert' | 'remove' | 'swap' | 'move';
5
4
  export declare const defaultFieldMeta: AnyFieldMeta;
6
- export declare function metaHelper<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta>(formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>): {
7
- handleArrayFieldMetaShift: (field: DeepKeys<TFormData>, index: number, mode: ArrayFieldMode, secondIndex?: number) => void;
5
+ export declare function metaHelper<TFormData, TOnMount extends undefined | FormValidateOrFn<TFormData>, TOnChange extends undefined | FormValidateOrFn<TFormData>, TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnBlur extends undefined | FormValidateOrFn<TFormData>, TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnSubmit extends undefined | FormValidateOrFn<TFormData>, TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnDynamic extends undefined | FormValidateOrFn<TFormData>, TOnDynamicAsync extends undefined | FormAsyncValidateOrFn<TFormData>, TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>, TSubmitMeta = never>(formApi: FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnDynamic, TOnDynamicAsync, TOnServer, TSubmitMeta>): {
6
+ handleArrayMove: (field: DeepKeys<TFormData>, fromIndex: number, toIndex: number) => void;
7
+ handleArrayRemove: (field: DeepKeys<TFormData>, index: number) => void;
8
+ handleArraySwap: (field: DeepKeys<TFormData>, index: number, secondIndex: number) => void;
9
+ handleArrayInsert: (field: DeepKeys<TFormData>, insertIndex: number) => void;
8
10
  };
9
- export {};
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["import { defaultValidationLogic } from './ValidationLogic'\nimport type { ValidationLogicProps } from './ValidationLogic'\nimport type { FieldValidators } from './FieldApi'\nimport type { FormValidators } from './FormApi'\nimport type {\n GlobalFormValidationError,\n ValidationCause,\n ValidationError,\n ValidationSource,\n} from './types'\n\nexport type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\n/**\n * @private\n */\nexport function functionalUpdate<TInput, TOutput = TInput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as UpdaterFn<TInput, TOutput>)(input)\n : updater\n}\n\n/**\n * Get a value from an object using a path, including dot notation.\n * @private\n */\nexport function getBy(obj: any, path: any) {\n const pathObj = makePathArray(path)\n return pathObj.reduce((current: any, pathPart: any) => {\n if (current === null) return null\n if (typeof current !== 'undefined') {\n return current[pathPart]\n }\n return undefined\n }, obj)\n}\n\n/**\n * Set a value on an object using a path, including dot notation.\n * @private\n */\nexport function setBy(obj: any, _path: any, updater: Updater<any>) {\n const path = makePathArray(_path)\n\n function doSet(parent?: any): any {\n if (!path.length) {\n return functionalUpdate(updater, parent)\n }\n\n const key = path.shift()\n\n if (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\n if (typeof parent === 'object') {\n if (parent === null) {\n parent = {}\n }\n return {\n ...parent,\n [key]: doSet(parent[key]),\n }\n }\n return {\n [key]: doSet(),\n }\n }\n\n if (Array.isArray(parent) && typeof key === 'number') {\n const prefix = parent.slice(0, key)\n return [\n ...(prefix.length ? prefix : new Array(key)),\n doSet(parent[key]),\n ...parent.slice(key + 1),\n ]\n }\n return [...new Array(key), doSet()]\n }\n\n return doSet(obj)\n}\n\n/**\n * Delete a field on an object using a path, including dot notation.\n * @private\n */\nexport function deleteBy(obj: any, _path: any) {\n const path = makePathArray(_path)\n\n function doDelete(parent: any): any {\n if (!parent) return\n if (path.length === 1) {\n const finalPath = path[0]!\n if (Array.isArray(parent) && typeof finalPath === 'number') {\n return parent.filter((_, i) => i !== finalPath)\n }\n const { [finalPath]: remove, ...rest } = parent\n return rest\n }\n\n const key = path.shift()\n\n if (typeof key === 'string') {\n if (typeof parent === 'object') {\n return {\n ...parent,\n [key]: doDelete(parent[key]),\n }\n }\n }\n\n if (typeof key === 'number') {\n if (Array.isArray(parent)) {\n if (key >= parent.length) {\n return parent\n }\n const prefix = parent.slice(0, key)\n return [\n ...(prefix.length ? prefix : new Array(key)),\n doDelete(parent[key]),\n ...parent.slice(key + 1),\n ]\n }\n }\n\n throw new Error('It seems we have created an infinite loop in deleteBy. ')\n }\n\n return doDelete(obj)\n}\n\nconst reLineOfOnlyDigits = /^(\\d+)$/gm\n// the second dot must be in a lookahead or the engine\n// will skip subsequent numbers (like foo.0.1.)\nconst reDigitsBetweenDots = /\\.(\\d+)(?=\\.)/gm\nconst reStartWithDigitThenDot = /^(\\d+)\\./gm\nconst reDotWithDigitsToEnd = /\\.(\\d+$)/gm\nconst reMultipleDots = /\\.{2,}/gm\n\nconst intPrefix = '__int__'\nconst intReplace = `${intPrefix}$1`\n\n/**\n * @private\n */\nexport function makePathArray(str: string | Array<string | number>) {\n if (Array.isArray(str)) {\n return [...str]\n }\n\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n return (\n str\n // Leading `[` may lead to wrong parsing down the line\n // (Example: '[0][1]' should be '0.1', not '.0.1')\n .replace(/(^\\[)|]/gm, '')\n .replace(/\\[/g, '.')\n .replace(reLineOfOnlyDigits, intReplace)\n .replace(reDigitsBetweenDots, `.${intReplace}.`)\n .replace(reStartWithDigitThenDot, `${intReplace}.`)\n .replace(reDotWithDigitsToEnd, `.${intReplace}`)\n .replace(reMultipleDots, '.')\n .split('.')\n .map((d) => {\n if (d.startsWith(intPrefix)) {\n const numStr = d.substring(intPrefix.length)\n const num = parseInt(numStr, 10)\n\n if (String(num) === numStr) {\n return num\n }\n return numStr\n }\n return d\n })\n )\n}\n\n/**\n * @private\n */\nexport function concatenatePaths(path1: string, path2: string): string {\n if (path1.length === 0) return path2\n if (path2.length === 0) return path1\n\n if (path2.startsWith('[')) {\n return path1 + path2\n }\n\n // In cases where parent and child withFieldGroup forms are both nested\n if (path2.startsWith('.')) {\n return path1 + path2\n }\n\n return `${path1}.${path2}`\n}\n\n/**\n * @private\n */\nexport function isNonEmptyArray(obj: any) {\n return !(Array.isArray(obj) && obj.length === 0)\n}\n\ninterface AsyncValidatorArrayPartialOptions<T> {\n validators?: T\n asyncDebounceMs?: number\n}\n\n/**\n * @private\n */\nexport interface AsyncValidator<T> {\n cause: ValidationCause\n validate: T\n debounceMs: number\n}\n\ninterface SyncValidatorArrayPartialOptions<T> {\n validators?: T\n}\n\n/**\n * @private\n */\nexport interface SyncValidator<T> {\n cause: ValidationCause\n validate: T\n}\n\n/**\n * @private\n */\nexport function getSyncValidatorArray<T>(\n cause: ValidationCause,\n options: SyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : never {\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n return {\n cause: validator!.cause,\n validate: validator!.fn,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n validators: options.validators,\n event: { type: cause, async: false },\n runValidation,\n })\n}\n\n/**\n * @private\n */\nexport function getAsyncValidatorArray<T>(\n cause: ValidationCause,\n options: AsyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : never {\n const { asyncDebounceMs } = options\n const {\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n onDynamicAsyncDebounceMs,\n } = (options.validators || {}) as\n | FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n\n const defaultDebounceMs = asyncDebounceMs ?? 0\n\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n const validatorCause = validator?.cause || cause\n\n let debounceMs = defaultDebounceMs\n\n switch (validatorCause) {\n case 'change':\n debounceMs = onChangeAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'blur':\n debounceMs = onBlurAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'dynamic':\n debounceMs = onDynamicAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'submit':\n debounceMs = 0 // submit validators are always run immediately\n break\n default:\n break\n }\n\n if (cause === 'submit') {\n debounceMs = 0\n }\n\n return {\n cause: validatorCause,\n validate: validator!.fn,\n debounceMs: debounceMs,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n validators: options.validators,\n event: { type: cause, async: true },\n runValidation,\n })\n}\n\nexport const isGlobalFormValidationError = (\n error: unknown,\n): error is GlobalFormValidationError<unknown> => {\n return !!error && typeof error === 'object' && 'fields' in error\n}\n\nexport function evaluate<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n return objA.getTime() === objB.getTime()\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n const keysA = Object.keys(objA)\n const keysB = Object.keys(objB)\n\n if (keysA.length !== keysB.length) {\n return false\n }\n\n for (const key of keysA) {\n // performs recursive search down the object tree\n\n if (\n !keysB.includes(key) ||\n !evaluate(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the form level sync/async validation.\n * @private\n */\nexport const determineFormLevelErrorSourceAndValue = ({\n newFormValidatorError,\n isPreviousErrorFromFormValidator,\n previousErrorValue,\n}: {\n newFormValidatorError: ValidationError\n isPreviousErrorFromFormValidator: boolean\n previousErrorValue: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // All falsy values are not considered errors\n if (newFormValidatorError) {\n return { newErrorValue: newFormValidatorError, newSource: 'form' }\n }\n\n // Clears form level error since it's now stale\n if (isPreviousErrorFromFormValidator) {\n return { newErrorValue: undefined, newSource: undefined }\n }\n\n // At this point, we have a preivous error which must have been set by the field validator, keep as is\n if (previousErrorValue) {\n return { newErrorValue: previousErrorValue, newSource: 'field' }\n }\n\n // No new or previous error, clear the error\n return { newErrorValue: undefined, newSource: undefined }\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the field level sync/async validation.\n * @private\n */\nexport const determineFieldLevelErrorSourceAndValue = ({\n formLevelError,\n fieldLevelError,\n}: {\n formLevelError: ValidationError\n fieldLevelError: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // At field level, we prioritize the field level error\n if (fieldLevelError) {\n return { newErrorValue: fieldLevelError, newSource: 'field' }\n }\n\n // If there is no field level error, and there is a form level error, we set the form level error\n if (formLevelError) {\n return { newErrorValue: formLevelError, newSource: 'form' }\n }\n\n return { newErrorValue: undefined, newSource: undefined }\n}\n\nexport function createFieldMap<T>(values: Readonly<T>): { [K in keyof T]: K } {\n const output: { [K in keyof T]: K } = {} as any\n\n for (const key in values) {\n output[key] = key\n }\n\n return output\n}\n\n/**\n * Merge the first parameter with the given overrides.\n * @private\n */\nexport function mergeOpts<T>(\n originalOpts: T | undefined | null,\n overrides: T,\n): T {\n if (originalOpts === undefined || originalOpts === null) {\n return overrides\n }\n\n return { ...originalOpts, ...overrides }\n}\n\n/*\n/ credit is due to https://github.com/lukeed/uuid for this code, with current npm\n/ attacks we didn't feel comfortable installing directly from npm. But big appreciation\n/ from the TanStack Form team <3.\n*/\n\nlet IDX = 256\nconst HEX: string[] = []\nlet BUFFER: number[] | undefined\n\nwhile (IDX--) {\n HEX[IDX] = (IDX + 256).toString(16).substring(1)\n}\n\nexport function uuid(): string {\n let i = 0\n let num: number\n let out = ''\n\n if (!BUFFER || IDX + 16 > 256) {\n BUFFER = new Array<number>(256)\n i = 256\n while (i--) {\n BUFFER[i] = (256 * Math.random()) | 0\n }\n i = 0\n IDX = 0\n }\n\n for (; i < 16; i++) {\n num = BUFFER[IDX + i] as number\n if (i === 6) out += HEX[(num & 15) | 64]\n else if (i === 8) out += HEX[(num & 63) | 128]\n else out += HEX[num]\n\n if (i & 1 && i > 1 && i < 11) out += '-'\n }\n\n IDX++\n return out\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["import { defaultValidationLogic } from './ValidationLogic'\nimport type { ValidationLogicProps } from './ValidationLogic'\nimport type { FieldValidators } from './FieldApi'\nimport type { FormValidators } from './FormApi'\nimport type {\n GlobalFormValidationError,\n ValidationCause,\n ValidationError,\n ValidationSource,\n} from './types'\n\nexport type UpdaterFn<TInput, TOutput = TInput> = (input: TInput) => TOutput\n\nexport type Updater<TInput, TOutput = TInput> =\n | TOutput\n | UpdaterFn<TInput, TOutput>\n\n/**\n * @private\n */\nexport function functionalUpdate<TInput, TOutput = TInput>(\n updater: Updater<TInput, TOutput>,\n input: TInput,\n): TOutput {\n return typeof updater === 'function'\n ? (updater as UpdaterFn<TInput, TOutput>)(input)\n : updater\n}\n\n/**\n * Get a value from an object using a path, including dot notation.\n * @private\n */\nexport function getBy(obj: unknown, path: string | (string | number)[]): any {\n const pathObj = makePathArray(path)\n return pathObj.reduce((current: any, pathPart) => {\n if (current === null) return null\n if (typeof current !== 'undefined') {\n return current[pathPart]\n }\n return undefined\n }, obj)\n}\n\n/**\n * Set a value on an object using a path, including dot notation.\n * @private\n */\nexport function setBy(obj: any, _path: any, updater: Updater<any>) {\n const path = makePathArray(_path)\n\n function doSet(parent?: any): any {\n if (!path.length) {\n return functionalUpdate(updater, parent)\n }\n\n const key = path.shift()\n\n if (\n typeof key === 'string' ||\n (typeof key === 'number' && !Array.isArray(parent))\n ) {\n if (typeof parent === 'object') {\n if (parent === null) {\n parent = {}\n }\n return {\n ...parent,\n [key]: doSet(parent[key]),\n }\n }\n return {\n [key]: doSet(),\n }\n }\n\n if (Array.isArray(parent) && typeof key === 'number') {\n const prefix = parent.slice(0, key)\n return [\n ...(prefix.length ? prefix : new Array(key)),\n doSet(parent[key]),\n ...parent.slice(key + 1),\n ]\n }\n return [...new Array(key), doSet()]\n }\n\n return doSet(obj)\n}\n\n/**\n * Delete a field on an object using a path, including dot notation.\n * @private\n */\nexport function deleteBy(obj: any, _path: any) {\n const path = makePathArray(_path)\n\n function doDelete(parent: any): any {\n if (!parent) return\n if (path.length === 1) {\n const finalPath = path[0]!\n if (Array.isArray(parent) && typeof finalPath === 'number') {\n return parent.filter((_, i) => i !== finalPath)\n }\n const { [finalPath]: remove, ...rest } = parent\n return rest\n }\n\n const key = path.shift()\n\n if (typeof key === 'string') {\n if (typeof parent === 'object') {\n return {\n ...parent,\n [key]: doDelete(parent[key]),\n }\n }\n }\n\n if (typeof key === 'number') {\n if (Array.isArray(parent)) {\n if (key >= parent.length) {\n return parent\n }\n const prefix = parent.slice(0, key)\n return [\n ...(prefix.length ? prefix : new Array(key)),\n doDelete(parent[key]),\n ...parent.slice(key + 1),\n ]\n }\n }\n\n throw new Error('It seems we have created an infinite loop in deleteBy. ')\n }\n\n return doDelete(obj)\n}\n\nconst reLineOfOnlyDigits = /^(\\d+)$/gm\n// the second dot must be in a lookahead or the engine\n// will skip subsequent numbers (like foo.0.1.)\nconst reDigitsBetweenDots = /\\.(\\d+)(?=\\.)/gm\nconst reStartWithDigitThenDot = /^(\\d+)\\./gm\nconst reDotWithDigitsToEnd = /\\.(\\d+$)/gm\nconst reMultipleDots = /\\.{2,}/gm\n\nconst intPrefix = '__int__'\nconst intReplace = `${intPrefix}$1`\n\n/**\n * @private\n */\nexport function makePathArray(str: string | Array<string | number>) {\n if (Array.isArray(str)) {\n return [...str]\n }\n\n if (typeof str !== 'string') {\n throw new Error('Path must be a string.')\n }\n\n return (\n str\n // Leading `[` may lead to wrong parsing down the line\n // (Example: '[0][1]' should be '0.1', not '.0.1')\n .replace(/(^\\[)|]/gm, '')\n .replace(/\\[/g, '.')\n .replace(reLineOfOnlyDigits, intReplace)\n .replace(reDigitsBetweenDots, `.${intReplace}.`)\n .replace(reStartWithDigitThenDot, `${intReplace}.`)\n .replace(reDotWithDigitsToEnd, `.${intReplace}`)\n .replace(reMultipleDots, '.')\n .split('.')\n .map((d) => {\n if (d.startsWith(intPrefix)) {\n const numStr = d.substring(intPrefix.length)\n const num = parseInt(numStr, 10)\n\n if (String(num) === numStr) {\n return num\n }\n return numStr\n }\n return d\n })\n )\n}\n\n/**\n * @private\n */\nexport function concatenatePaths(path1: string, path2: string): string {\n if (path1.length === 0) return path2\n if (path2.length === 0) return path1\n\n if (path2.startsWith('[')) {\n return path1 + path2\n }\n\n // In cases where parent and child withFieldGroup forms are both nested\n if (path2.startsWith('.')) {\n return path1 + path2\n }\n\n return `${path1}.${path2}`\n}\n\n/**\n * @private\n */\nexport function isNonEmptyArray(obj: any) {\n return !(Array.isArray(obj) && obj.length === 0)\n}\n\ninterface AsyncValidatorArrayPartialOptions<T> {\n validators?: T\n asyncDebounceMs?: number\n}\n\n/**\n * @private\n */\nexport interface AsyncValidator<T> {\n cause: ValidationCause\n validate: T\n debounceMs: number\n}\n\ninterface SyncValidatorArrayPartialOptions<T> {\n validators?: T\n}\n\n/**\n * @private\n */\nexport interface SyncValidator<T> {\n cause: ValidationCause\n validate: T\n}\n\n/**\n * @private\n */\nexport function getSyncValidatorArray<T>(\n cause: ValidationCause,\n options: SyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n SyncValidator<\n | T['onChange']\n | T['onBlur']\n | T['onSubmit']\n | T['onMount']\n | T['onDynamic']\n >\n >\n : never {\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n return {\n cause: validator!.cause,\n validate: validator!.fn,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n validators: options.validators,\n event: { type: cause, async: false },\n runValidation,\n })\n}\n\n/**\n * @private\n */\nexport function getAsyncValidatorArray<T>(\n cause: ValidationCause,\n options: AsyncValidatorArrayPartialOptions<T> & {\n validationLogic?: any\n form?: any\n },\n): T extends FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : T extends FormValidators<any, any, any, any, any, any, any, any, any, any>\n ? Array<\n AsyncValidator<\n | T['onChangeAsync']\n | T['onBlurAsync']\n | T['onSubmitAsync']\n | T['onDynamicAsync']\n >\n >\n : never {\n const { asyncDebounceMs } = options\n const {\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n onDynamicAsyncDebounceMs,\n } = (options.validators || {}) as\n | FieldValidators<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >\n | FormValidators<any, any, any, any, any, any, any, any, any, any>\n\n const defaultDebounceMs = asyncDebounceMs ?? 0\n\n const runValidation = (\n props: Parameters<ValidationLogicProps['runValidation']>[0],\n ) => {\n return props.validators.filter(Boolean).map((validator) => {\n const validatorCause = validator?.cause || cause\n\n let debounceMs = defaultDebounceMs\n\n switch (validatorCause) {\n case 'change':\n debounceMs = onChangeAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'blur':\n debounceMs = onBlurAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'dynamic':\n debounceMs = onDynamicAsyncDebounceMs ?? defaultDebounceMs\n break\n case 'submit':\n debounceMs = 0 // submit validators are always run immediately\n break\n default:\n break\n }\n\n if (cause === 'submit') {\n debounceMs = 0\n }\n\n return {\n cause: validatorCause,\n validate: validator!.fn,\n debounceMs: debounceMs,\n }\n })\n }\n\n return options.validationLogic({\n form: options.form,\n validators: options.validators,\n event: { type: cause, async: true },\n runValidation,\n })\n}\n\nexport const isGlobalFormValidationError = (\n error: unknown,\n): error is GlobalFormValidationError<unknown> => {\n return !!error && typeof error === 'object' && 'fields' in error\n}\n\nexport function evaluate<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n return objA.getTime() === objB.getTime()\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n const keysA = Object.keys(objA)\n const keysB = Object.keys(objB)\n\n if (keysA.length !== keysB.length) {\n return false\n }\n\n for (const key of keysA) {\n // performs recursive search down the object tree\n\n if (\n !keysB.includes(key) ||\n !evaluate(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the form level sync/async validation.\n * @private\n */\nexport const determineFormLevelErrorSourceAndValue = ({\n newFormValidatorError,\n isPreviousErrorFromFormValidator,\n previousErrorValue,\n}: {\n newFormValidatorError: ValidationError\n isPreviousErrorFromFormValidator: boolean\n previousErrorValue: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // All falsy values are not considered errors\n if (newFormValidatorError) {\n return { newErrorValue: newFormValidatorError, newSource: 'form' }\n }\n\n // Clears form level error since it's now stale\n if (isPreviousErrorFromFormValidator) {\n return { newErrorValue: undefined, newSource: undefined }\n }\n\n // At this point, we have a preivous error which must have been set by the field validator, keep as is\n if (previousErrorValue) {\n return { newErrorValue: previousErrorValue, newSource: 'field' }\n }\n\n // No new or previous error, clear the error\n return { newErrorValue: undefined, newSource: undefined }\n}\n\n/**\n * Determines the logic for determining the error source and value to set on the field meta within the field level sync/async validation.\n * @private\n */\nexport const determineFieldLevelErrorSourceAndValue = ({\n formLevelError,\n fieldLevelError,\n}: {\n formLevelError: ValidationError\n fieldLevelError: ValidationError\n}): {\n newErrorValue: ValidationError\n newSource: ValidationSource | undefined\n} => {\n // At field level, we prioritize the field level error\n if (fieldLevelError) {\n return { newErrorValue: fieldLevelError, newSource: 'field' }\n }\n\n // If there is no field level error, and there is a form level error, we set the form level error\n if (formLevelError) {\n return { newErrorValue: formLevelError, newSource: 'form' }\n }\n\n return { newErrorValue: undefined, newSource: undefined }\n}\n\nexport function createFieldMap<T>(values: Readonly<T>): { [K in keyof T]: K } {\n const output: { [K in keyof T]: K } = {} as any\n\n for (const key in values) {\n output[key] = key\n }\n\n return output\n}\n\n/**\n * Merge the first parameter with the given overrides.\n * @private\n */\nexport function mergeOpts<T>(\n originalOpts: T | undefined | null,\n overrides: T,\n): T {\n if (originalOpts === undefined || originalOpts === null) {\n return overrides\n }\n\n return { ...originalOpts, ...overrides }\n}\n\n/*\n/ credit is due to https://github.com/lukeed/uuid for this code, with current npm\n/ attacks we didn't feel comfortable installing directly from npm. But big appreciation\n/ from the TanStack Form team <3.\n*/\n\nlet IDX = 256\nconst HEX: string[] = []\nlet BUFFER: number[] | undefined\n\nwhile (IDX--) {\n HEX[IDX] = (IDX + 256).toString(16).substring(1)\n}\n\nexport function uuid(): string {\n let i = 0\n let num: number\n let out = ''\n\n if (!BUFFER || IDX + 16 > 256) {\n BUFFER = new Array<number>(256)\n i = 256\n while (i--) {\n BUFFER[i] = (256 * Math.random()) | 0\n }\n i = 0\n IDX = 0\n }\n\n for (; i < 16; i++) {\n num = BUFFER[IDX + i] as number\n if (i === 6) out += HEX[(num & 15) | 64]\n else if (i === 8) out += HEX[(num & 63) | 128]\n else out += HEX[num]\n\n if (i & 1 && i > 1 && i < 11) out += '-'\n }\n\n IDX++\n return out\n}\n"],"names":[],"mappings":";;AAoBO,SAAS,iBACd,SACA,OACS;AACT,SAAO,OAAO,YAAY,aACrB,QAAuC,KAAK,IAC7C;AACN;AAMO,SAAS,MAAM,KAAc,MAAyC;AAC3E,QAAM,UAAU,cAAc,IAAI;AAClC,SAAO,QAAQ,OAAO,CAAC,SAAc,aAAa;AAChD,QAAI,YAAY,KAAM,QAAO;AAC7B,QAAI,OAAO,YAAY,aAAa;AAClC,aAAO,QAAQ,QAAQ;AAAA,IACzB;AACA,WAAO;AAAA,EACT,GAAG,GAAG;AACR;AAMO,SAAS,MAAM,KAAU,OAAY,SAAuB;AACjE,QAAM,OAAO,cAAc,KAAK;AAEhC,WAAS,MAAM,QAAmB;AAChC,QAAI,CAAC,KAAK,QAAQ;AAChB,aAAO,iBAAiB,SAAS,MAAM;AAAA,IACzC;AAEA,UAAM,MAAM,KAAK,MAAA;AAEjB,QACE,OAAO,QAAQ,YACd,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,MAAM,GACjD;AACA,UAAI,OAAO,WAAW,UAAU;AAC9B,YAAI,WAAW,MAAM;AACnB,mBAAS,CAAA;AAAA,QACX;AACA,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,GAAG,GAAG,MAAM,OAAO,GAAG,CAAC;AAAA,QAAA;AAAA,MAE5B;AACA,aAAO;AAAA,QACL,CAAC,GAAG,GAAG,MAAA;AAAA,MAAM;AAAA,IAEjB;AAEA,QAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,QAAQ,UAAU;AACpD,YAAM,SAAS,OAAO,MAAM,GAAG,GAAG;AAClC,aAAO;AAAA,QACL,GAAI,OAAO,SAAS,SAAS,IAAI,MAAM,GAAG;AAAA,QAC1C,MAAM,OAAO,GAAG,CAAC;AAAA,QACjB,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,MAAA;AAAA,IAE3B;AACA,WAAO,CAAC,GAAG,IAAI,MAAM,GAAG,GAAG,OAAO;AAAA,EACpC;AAEA,SAAO,MAAM,GAAG;AAClB;AAMO,SAAS,SAAS,KAAU,OAAY;AAC7C,QAAM,OAAO,cAAc,KAAK;AAEhC,WAAS,SAAS,QAAkB;AAClC,QAAI,CAAC,OAAQ;AACb,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,YAAY,KAAK,CAAC;AACxB,UAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,cAAc,UAAU;AAC1D,eAAO,OAAO,OAAO,CAAC,GAAG,MAAM,MAAM,SAAS;AAAA,MAChD;AACA,YAAM,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,SAAS;AACzC,aAAO;AAAA,IACT;AAEA,UAAM,MAAM,KAAK,MAAA;AAEjB,QAAI,OAAO,QAAQ,UAAU;AAC3B,UAAI,OAAO,WAAW,UAAU;AAC9B,eAAO;AAAA,UACL,GAAG;AAAA,UACH,CAAC,GAAG,GAAG,SAAS,OAAO,GAAG,CAAC;AAAA,QAAA;AAAA,MAE/B;AAAA,IACF;AAEA,QAAI,OAAO,QAAQ,UAAU;AAC3B,UAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAI,OAAO,OAAO,QAAQ;AACxB,iBAAO;AAAA,QACT;AACA,cAAM,SAAS,OAAO,MAAM,GAAG,GAAG;AAClC,eAAO;AAAA,UACL,GAAI,OAAO,SAAS,SAAS,IAAI,MAAM,GAAG;AAAA,UAC1C,SAAS,OAAO,GAAG,CAAC;AAAA,UACpB,GAAG,OAAO,MAAM,MAAM,CAAC;AAAA,QAAA;AAAA,MAE3B;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,SAAO,SAAS,GAAG;AACrB;AAEA,MAAM,qBAAqB;AAG3B,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAChC,MAAM,uBAAuB;AAC7B,MAAM,iBAAiB;AAEvB,MAAM,YAAY;AAClB,MAAM,aAAa,GAAG,SAAS;AAKxB,SAAS,cAAc,KAAsC;AAClE,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,CAAC,GAAG,GAAG;AAAA,EAChB;AAEA,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AAEA,SACE,IAGG,QAAQ,aAAa,EAAE,EACvB,QAAQ,OAAO,GAAG,EAClB,QAAQ,oBAAoB,UAAU,EACtC,QAAQ,qBAAqB,IAAI,UAAU,GAAG,EAC9C,QAAQ,yBAAyB,GAAG,UAAU,GAAG,EACjD,QAAQ,sBAAsB,IAAI,UAAU,EAAE,EAC9C,QAAQ,gBAAgB,GAAG,EAC3B,MAAM,GAAG,EACT,IAAI,CAAC,MAAM;AACV,QAAI,EAAE,WAAW,SAAS,GAAG;AAC3B,YAAM,SAAS,EAAE,UAAU,UAAU,MAAM;AAC3C,YAAM,MAAM,SAAS,QAAQ,EAAE;AAE/B,UAAI,OAAO,GAAG,MAAM,QAAQ;AAC1B,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AAEP;AAKO,SAAS,iBAAiB,OAAe,OAAuB;AACrE,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,MAAI,MAAM,WAAW,GAAG,GAAG;AACzB,WAAO,QAAQ;AAAA,EACjB;AAGA,MAAI,MAAM,WAAW,GAAG,GAAG;AACzB,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO,GAAG,KAAK,IAAI,KAAK;AAC1B;AAKO,SAAS,gBAAgB,KAAU;AACxC,SAAO,EAAE,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW;AAChD;AA+BO,SAAS,sBACd,OACA,SAqCU;AACV,QAAM,gBAAgB,CACpB,UACG;AACH,WAAO,MAAM,WAAW,OAAO,OAAO,EAAE,IAAI,CAAC,cAAc;AACzD,aAAO;AAAA,QACL,OAAO,UAAW;AAAA,QAClB,UAAU,UAAW;AAAA,MAAA;AAAA,IAEzB,CAAC;AAAA,EACH;AAEA,SAAO,QAAQ,gBAAgB;AAAA,IAC7B,MAAM,QAAQ;AAAA,IACd,YAAY,QAAQ;AAAA,IACpB,OAAO,EAAE,MAAM,OAAO,OAAO,MAAA;AAAA,IAC7B;AAAA,EAAA,CACD;AACH;AAKO,SAAS,uBACd,OACA,SAmCU;AACV,QAAM,EAAE,oBAAoB;AAC5B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACG,QAAQ,cAAc,CAAA;AAiB3B,QAAM,oBAAoB,mBAAmB;AAE7C,QAAM,gBAAgB,CACpB,UACG;AACH,WAAO,MAAM,WAAW,OAAO,OAAO,EAAE,IAAI,CAAC,cAAc;AACzD,YAAM,iBAAiB,WAAW,SAAS;AAE3C,UAAI,aAAa;AAEjB,cAAQ,gBAAA;AAAA,QACN,KAAK;AACH,uBAAa,2BAA2B;AACxC;AAAA,QACF,KAAK;AACH,uBAAa,yBAAyB;AACtC;AAAA,QACF,KAAK;AACH,uBAAa,4BAA4B;AACzC;AAAA,QACF,KAAK;AACH,uBAAa;AACb;AAAA,MAEA;AAGJ,UAAI,UAAU,UAAU;AACtB,qBAAa;AAAA,MACf;AAEA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU,UAAW;AAAA,QACrB;AAAA,MAAA;AAAA,IAEJ,CAAC;AAAA,EACH;AAEA,SAAO,QAAQ,gBAAgB;AAAA,IAC7B,MAAM,QAAQ;AAAA,IACd,YAAY,QAAQ;AAAA,IACpB,OAAO,EAAE,MAAM,OAAO,OAAO,KAAA;AAAA,IAC7B;AAAA,EAAA,CACD;AACH;AAEO,MAAM,8BAA8B,CACzC,UACgD;AAChD,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,YAAY;AAC7D;AAEO,SAAS,SAAY,MAAS,MAAS;AAC5C,MAAI,OAAO,GAAG,MAAM,IAAI,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MACE,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,SAAS,YAChB,SAAS,MACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,QAAQ,gBAAgB,MAAM;AAChD,WAAO,KAAK,cAAc,KAAK,QAAA;AAAA,EACjC;AAEA,MAAI,gBAAgB,OAAO,gBAAgB,KAAK;AAC9C,QAAI,KAAK,SAAS,KAAK,KAAM,QAAO;AACpC,eAAW,CAAC,GAAG,CAAC,KAAK,MAAM;AACzB,UAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,EAAG,QAAO;AAAA,IACzD;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,OAAO,gBAAgB,KAAK;AAC9C,QAAI,KAAK,SAAS,KAAK,KAAM,QAAO;AACpC,eAAW,KAAK,MAAM;AACpB,UAAI,CAAC,KAAK,IAAI,CAAC,EAAG,QAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,QAAM,QAAQ,OAAO,KAAK,IAAI;AAE9B,MAAI,MAAM,WAAW,MAAM,QAAQ;AACjC,WAAO;AAAA,EACT;AAEA,aAAW,OAAO,OAAO;AAGvB,QACE,CAAC,MAAM,SAAS,GAAG,KACnB,CAAC,SAAS,KAAK,GAAc,GAAG,KAAK,GAAc,CAAC,GACpD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAMO,MAAM,wCAAwC,CAAC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AACF,MAOK;AAEH,MAAI,uBAAuB;AACzB,WAAO,EAAE,eAAe,uBAAuB,WAAW,OAAA;AAAA,EAC5D;AAGA,MAAI,kCAAkC;AACpC,WAAO,EAAE,eAAe,QAAW,WAAW,OAAA;AAAA,EAChD;AAGA,MAAI,oBAAoB;AACtB,WAAO,EAAE,eAAe,oBAAoB,WAAW,QAAA;AAAA,EACzD;AAGA,SAAO,EAAE,eAAe,QAAW,WAAW,OAAA;AAChD;AAMO,MAAM,yCAAyC,CAAC;AAAA,EACrD;AAAA,EACA;AACF,MAMK;AAEH,MAAI,iBAAiB;AACnB,WAAO,EAAE,eAAe,iBAAiB,WAAW,QAAA;AAAA,EACtD;AAGA,MAAI,gBAAgB;AAClB,WAAO,EAAE,eAAe,gBAAgB,WAAW,OAAA;AAAA,EACrD;AAEA,SAAO,EAAE,eAAe,QAAW,WAAW,OAAA;AAChD;AAEO,SAAS,eAAkB,QAA4C;AAC5E,QAAM,SAAgC,CAAA;AAEtC,aAAW,OAAO,QAAQ;AACxB,WAAO,GAAG,IAAI;AAAA,EAChB;AAEA,SAAO;AACT;AAMO,SAAS,UACd,cACA,WACG;AACH,MAAI,iBAAiB,UAAa,iBAAiB,MAAM;AACvD,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,GAAG,cAAc,GAAG,UAAA;AAC/B;AAQA,IAAI,MAAM;AACV,MAAM,MAAgB,CAAA;AACtB,IAAI;AAEJ,OAAO,OAAO;AACZ,MAAI,GAAG,KAAK,MAAM,KAAK,SAAS,EAAE,EAAE,UAAU,CAAC;AACjD;AAEO,SAAS,OAAe;AAC7B,MAAI,IAAI;AACR,MAAI;AACJ,MAAI,MAAM;AAEV,MAAI,CAAC,UAAU,MAAM,KAAK,KAAK;AAC7B,aAAS,IAAI,MAAc,GAAG;AAC9B,QAAI;AACJ,WAAO,KAAK;AACV,aAAO,CAAC,IAAK,MAAM,KAAK,WAAY;AAAA,IACtC;AACA,QAAI;AACJ,UAAM;AAAA,EACR;AAEA,SAAO,IAAI,IAAI,KAAK;AAClB,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,MAAM,EAAG,QAAO,IAAK,MAAM,KAAM,EAAE;AAAA,aAC9B,MAAM,EAAG,QAAO,IAAK,MAAM,KAAM,GAAG;AAAA,QACxC,QAAO,IAAI,GAAG;AAEnB,QAAI,IAAI,KAAK,IAAI,KAAK,IAAI,GAAI,QAAO;AAAA,EACvC;AAEA;AACA,SAAO;AACT;;;;;;;;;;;;;;;;;"}
@@ -11,7 +11,7 @@ export declare function functionalUpdate<TInput, TOutput = TInput>(updater: Upda
11
11
  * Get a value from an object using a path, including dot notation.
12
12
  * @private
13
13
  */
14
- export declare function getBy(obj: any, path: any): any;
14
+ export declare function getBy(obj: unknown, path: string | (string | number)[]): any;
15
15
  /**
16
16
  * Set a value on an object using a path, including dot notation.
17
17
  * @private
@@ -3,8 +3,7 @@ class FormEventClient extends EventClient {
3
3
  constructor() {
4
4
  super({
5
5
  pluginId: "form-devtools",
6
- debug: true,
7
- reconnectEveryMs: 4e3
6
+ reconnectEveryMs: 1e3
8
7
  });
9
8
  }
10
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EventClient.js","sources":["../../src/EventClient.ts"],"sourcesContent":["import { EventClient } from '@tanstack/devtools-event-client'\n\nimport type { AnyFormOptions, AnyFormState } from './FormApi'\n\ntype ExtractEventNames<T> = T extends `${string}:${infer EventName}`\n ? EventName\n : never\n\nexport type BroadcastFormState = {\n id: string\n state: AnyFormState\n}\n\nexport type BroadcastFormApi = {\n id: string\n state: AnyFormState\n options: AnyFormOptions\n}\n\nexport type BroadcastFormSubmissionState =\n | {\n id: string\n submissionAttempt: number\n successful: false\n stage: 'validateAllFields' | 'validate'\n errors: any[]\n }\n | {\n id: string\n submissionAttempt: number\n successful: false\n stage: 'inflight'\n onError: unknown\n }\n | {\n id: string\n submissionAttempt: number\n successful: true\n }\n\nexport type BroadcastFormId = {\n id: string\n}\n\ntype EventMap = {\n 'form-devtools:form-state': BroadcastFormState\n 'form-devtools:form-api': BroadcastFormApi\n 'form-devtools:form-submission': BroadcastFormSubmissionState\n\n 'form-devtools:request-form-state': BroadcastFormId\n 'form-devtools:request-form-reset': BroadcastFormId\n 'form-devtools:request-form-force-submit': BroadcastFormId\n\n 'form-devtools:form-unmounted': BroadcastFormId\n}\n\nexport type EventClientEventMap = keyof EventMap\n\nexport type EventClientEventNames = ExtractEventNames<EventClientEventMap>\n\nclass FormEventClient extends EventClient<EventMap> {\n constructor() {\n super({\n pluginId: 'form-devtools',\n debug: true,\n reconnectEveryMs: 4000,\n })\n }\n}\n\nexport const formEventClient = new FormEventClient()\n"],"names":[],"mappings":";AA4DA,MAAM,wBAAwB,YAAsB;AAAA,EAClD,cAAc;AACZ,UAAM;AAAA,MACJ,UAAU;AAAA,MACV,OAAO;AAAA,MACP,kBAAkB;AAAA,IAAA,CACnB;AAAA,EACH;AACF;AAEO,MAAM,kBAAkB,IAAI,gBAAA;"}
1
+ {"version":3,"file":"EventClient.js","sources":["../../src/EventClient.ts"],"sourcesContent":["import { EventClient } from '@tanstack/devtools-event-client'\n\nimport type { AnyFormOptions, AnyFormState } from './FormApi'\n\ntype ExtractEventNames<T> = T extends `${string}:${infer EventName}`\n ? EventName\n : never\n\nexport type BroadcastFormState = {\n id: string\n state: AnyFormState\n}\n\nexport type BroadcastFormApi = {\n id: string\n state: AnyFormState\n options: AnyFormOptions\n}\n\nexport type BroadcastFormSubmissionState =\n | {\n id: string\n submissionAttempt: number\n successful: false\n stage: 'validateAllFields' | 'validate'\n errors: any[]\n }\n | {\n id: string\n submissionAttempt: number\n successful: false\n stage: 'inflight'\n onError: unknown\n }\n | {\n id: string\n submissionAttempt: number\n successful: true\n }\n\nexport type BroadcastFormId = {\n id: string\n}\n\ntype EventMap = {\n 'form-devtools:form-state': BroadcastFormState\n 'form-devtools:form-api': BroadcastFormApi\n 'form-devtools:form-submission': BroadcastFormSubmissionState\n\n 'form-devtools:request-form-state': BroadcastFormId\n 'form-devtools:request-form-reset': BroadcastFormId\n 'form-devtools:request-form-force-submit': BroadcastFormId\n\n 'form-devtools:form-unmounted': BroadcastFormId\n}\n\nexport type EventClientEventMap = keyof EventMap\n\nexport type EventClientEventNames = ExtractEventNames<EventClientEventMap>\n\nclass FormEventClient extends EventClient<EventMap> {\n constructor() {\n super({\n pluginId: 'form-devtools',\n reconnectEveryMs: 1000,\n })\n }\n}\n\nexport const formEventClient = new FormEventClient()\n"],"names":[],"mappings":";AA4DA,MAAM,wBAAwB,YAAsB;AAAA,EAClD,cAAc;AACZ,UAAM;AAAA,MACJ,UAAU;AAAA,MACV,kBAAkB;AAAA,IAAA,CACnB;AAAA,EACH;AACF;AAEO,MAAM,kBAAkB,IAAI,gBAAA;"}
@@ -256,7 +256,7 @@ export declare class FieldApi<in out TParentData, in out TName extends DeepKeys<
256
256
  /**
257
257
  * The field name.
258
258
  */
259
- name: DeepKeys<TParentData>;
259
+ name: TName;
260
260
  /**
261
261
  * The field options.
262
262
  */
@@ -1,7 +1,7 @@
1
1
  import { batch, Derived } from "@tanstack/store";
2
2
  import { standardSchemaValidators, isStandardSchemaValidator } from "./standardSchemaValidator.js";
3
3
  import { defaultFieldMeta } from "./metaHelper.js";
4
- import { getBy, mergeOpts, getSyncValidatorArray, getAsyncValidatorArray, determineFieldLevelErrorSourceAndValue } from "./utils.js";
4
+ import { evaluate, mergeOpts, getSyncValidatorArray, getAsyncValidatorArray, determineFieldLevelErrorSourceAndValue } from "./utils.js";
5
5
  import { defaultValidationLogic } from "./ValidationLogic.js";
6
6
  class FieldApi {
7
7
  /**
@@ -11,7 +11,7 @@ class FieldApi {
11
11
  this.options = {};
12
12
  this.mount = () => {
13
13
  const cleanup = this.store.mount();
14
- if (this.options.defaultValue !== void 0) {
14
+ if (this.options.defaultValue !== void 0 && !this.getMeta().isTouched) {
15
15
  this.form.setFieldValue(this.name, this.options.defaultValue, {
16
16
  dontUpdateMeta: true
17
17
  });
@@ -53,23 +53,19 @@ class FieldApi {
53
53
  };
54
54
  this.update = (opts2) => {
55
55
  this.options = opts2;
56
- const nameHasChanged = this.name !== opts2.name;
57
56
  this.name = opts2.name;
58
- if (this.state.value === void 0) {
59
- const formDefault = getBy(opts2.form.options.defaultValues, opts2.name);
60
- const defaultValue = opts2.defaultValue ?? formDefault;
61
- if (nameHasChanged) {
62
- this.setValue((val) => val || defaultValue, {
63
- dontUpdateMeta: true
64
- });
65
- } else if (defaultValue !== void 0) {
66
- this.setValue(defaultValue, {
67
- dontUpdateMeta: true
57
+ if (!this.state.meta.isTouched && this.options.defaultValue !== void 0) {
58
+ const formField = this.form.getFieldValue(this.name);
59
+ if (!evaluate(formField, opts2.defaultValue)) {
60
+ this.form.setFieldValue(this.name, opts2.defaultValue, {
61
+ dontUpdateMeta: true,
62
+ dontValidate: true,
63
+ dontRunListeners: true
68
64
  });
69
65
  }
70
66
  }
71
- if (this.form.getFieldMeta(this.name) === void 0) {
72
- this.setMeta(this.state.meta);
67
+ if (!this.form.getFieldMeta(this.name)) {
68
+ this.form.setFieldMeta(this.name, this.state.meta);
73
69
  }
74
70
  };
75
71
  this.getValue = () => {
@@ -426,6 +422,7 @@ class FieldApi {
426
422
  };
427
423
  this.form = opts.form;
428
424
  this.name = opts.name;
425
+ this.options = opts;
429
426
  this.timeoutIds = {
430
427
  validations: {},
431
428
  listeners: {},
@@ -434,18 +431,20 @@ class FieldApi {
434
431
  this.store = new Derived({
435
432
  deps: [this.form.store],
436
433
  fn: () => {
437
- const value = this.form.getFieldValue(this.name);
438
434
  const meta = this.form.getFieldMeta(this.name) ?? {
439
435
  ...defaultFieldMeta,
440
436
  ...opts.defaultMeta
441
437
  };
438
+ let value = this.form.getFieldValue(this.name);
439
+ if (!meta.isTouched && value === void 0 && this.options.defaultValue !== void 0 && !evaluate(value, this.options.defaultValue)) {
440
+ value = this.options.defaultValue;
441
+ }
442
442
  return {
443
443
  value,
444
444
  meta
445
445
  };
446
446
  }
447
447
  });
448
- this.options = opts;
449
448
  }
450
449
  /**
451
450
  * The current field state.