@tanstack/form-core 0.13.0 → 0.13.3

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.
Files changed (52) hide show
  1. package/dist/cjs/FieldApi.cjs +300 -0
  2. package/dist/cjs/FieldApi.cjs.map +1 -0
  3. package/dist/cjs/FormApi.cjs +438 -0
  4. package/dist/cjs/FormApi.cjs.map +1 -0
  5. package/dist/{mjs/FormApi.d.ts → cjs/FormApi.d.cts} +0 -1
  6. package/dist/cjs/index.cjs +15 -923
  7. package/dist/cjs/index.cjs.map +1 -1
  8. package/dist/cjs/mergeForm.cjs +32 -0
  9. package/dist/cjs/mergeForm.cjs.map +1 -0
  10. package/dist/cjs/utils.cjs +173 -0
  11. package/dist/cjs/utils.cjs.map +1 -0
  12. package/dist/esm/FieldApi.js +300 -0
  13. package/dist/esm/FieldApi.js.map +1 -0
  14. package/dist/{cjs → esm}/FormApi.d.ts +0 -1
  15. package/dist/esm/FormApi.js +438 -0
  16. package/dist/esm/FormApi.js.map +1 -0
  17. package/dist/esm/index.js +18 -0
  18. package/dist/esm/index.js.map +1 -0
  19. package/dist/esm/mergeForm.js +32 -0
  20. package/dist/esm/mergeForm.js.map +1 -0
  21. package/dist/esm/utils.js +173 -0
  22. package/dist/esm/utils.js.map +1 -0
  23. package/package.json +11 -11
  24. package/src/tests/utils.spec.ts +7 -0
  25. package/src/utils.ts +4 -0
  26. package/dist/cjs/index.js +0 -926
  27. package/dist/cjs/tests/FieldApi.spec.d.ts +0 -1
  28. package/dist/cjs/tests/FieldApi.test-d.d.ts +0 -1
  29. package/dist/cjs/tests/FormApi.spec.d.ts +0 -1
  30. package/dist/cjs/tests/mutateMergeDeep.spec.d.ts +0 -1
  31. package/dist/cjs/tests/utils.d.ts +0 -1
  32. package/dist/cjs/tests/utils.spec.d.ts +0 -1
  33. package/dist/mjs/index.d.mts +0 -5
  34. package/dist/mjs/index.d.ts +0 -5
  35. package/dist/mjs/index.js +0 -926
  36. package/dist/mjs/index.mjs +0 -926
  37. package/dist/mjs/index.mjs.map +0 -1
  38. package/dist/mjs/tests/FieldApi.spec.d.ts +0 -1
  39. package/dist/mjs/tests/FieldApi.test-d.d.ts +0 -1
  40. package/dist/mjs/tests/FormApi.spec.d.ts +0 -1
  41. package/dist/mjs/tests/mutateMergeDeep.spec.d.ts +0 -1
  42. package/dist/mjs/tests/utils.d.ts +0 -1
  43. package/dist/mjs/tests/utils.spec.d.ts +0 -1
  44. /package/dist/cjs/{FieldApi.d.ts → FieldApi.d.cts} +0 -0
  45. /package/dist/cjs/{mergeForm.d.ts → mergeForm.d.cts} +0 -0
  46. /package/dist/cjs/{types.d.ts → types.d.cts} +0 -0
  47. /package/dist/cjs/{utils.d.ts → utils.d.cts} +0 -0
  48. /package/dist/{mjs → esm}/FieldApi.d.ts +0 -0
  49. /package/dist/{cjs → esm}/index.d.ts +0 -0
  50. /package/dist/{mjs → esm}/mergeForm.d.ts +0 -0
  51. /package/dist/{mjs → esm}/types.d.ts +0 -0
  52. /package/dist/{mjs → esm}/utils.d.ts +0 -0
package/dist/cjs/index.js DELETED
@@ -1,926 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const store = require("@tanstack/store");
4
- function functionalUpdate(updater, input) {
5
- return typeof updater === "function" ? updater(input) : updater;
6
- }
7
- function getBy(obj, path) {
8
- const pathObj = makePathArray(path);
9
- return pathObj.reduce((current, pathPart) => {
10
- if (typeof current !== "undefined") {
11
- return current[pathPart];
12
- }
13
- return void 0;
14
- }, obj);
15
- }
16
- function setBy(obj, _path, updater) {
17
- const path = makePathArray(_path);
18
- function doSet(parent) {
19
- if (!path.length) {
20
- return functionalUpdate(updater, parent);
21
- }
22
- const key = path.shift();
23
- if (typeof key === "string") {
24
- if (typeof parent === "object") {
25
- return {
26
- ...parent,
27
- [key]: doSet(parent[key])
28
- };
29
- }
30
- return {
31
- [key]: doSet()
32
- };
33
- }
34
- if (Array.isArray(parent) && key !== void 0) {
35
- const prefix = parent.slice(0, key);
36
- return [
37
- ...prefix.length ? prefix : new Array(key),
38
- doSet(parent[key]),
39
- ...parent.slice(key + 1)
40
- ];
41
- }
42
- return [...new Array(key), doSet()];
43
- }
44
- return doSet(obj);
45
- }
46
- function deleteBy(obj, _path) {
47
- const path = makePathArray(_path);
48
- function doDelete(parent) {
49
- if (path.length === 1) {
50
- const finalPath = path[0];
51
- const { [finalPath]: remove, ...rest } = parent;
52
- return rest;
53
- }
54
- const key = path.shift();
55
- if (typeof key === "string") {
56
- if (typeof parent === "object") {
57
- return {
58
- ...parent,
59
- [key]: doDelete(parent[key])
60
- };
61
- }
62
- }
63
- if (typeof key === "number") {
64
- if (Array.isArray(parent)) {
65
- const prefix = parent.slice(0, key);
66
- return [
67
- ...prefix.length ? prefix : new Array(key),
68
- doDelete(parent[key]),
69
- ...parent.slice(key + 1)
70
- ];
71
- }
72
- }
73
- throw new Error("It seems we have created an infinite loop in deleteBy. ");
74
- }
75
- return doDelete(obj);
76
- }
77
- const reFindNumbers0 = /^(\d*)$/gm;
78
- const reFindNumbers1 = /\.(\d*)\./gm;
79
- const reFindNumbers2 = /^(\d*)\./gm;
80
- const reFindNumbers3 = /\.(\d*$)/gm;
81
- const reFindMultiplePeriods = /\.{2,}/gm;
82
- const intPrefix = "__int__";
83
- const intReplace = `${intPrefix}$1`;
84
- function makePathArray(str) {
85
- if (typeof str !== "string") {
86
- throw new Error("Path must be a string.");
87
- }
88
- return str.replace("[", ".").replace("]", "").replace(reFindNumbers0, intReplace).replace(reFindNumbers1, `.${intReplace}.`).replace(reFindNumbers2, `${intReplace}.`).replace(reFindNumbers3, `.${intReplace}`).replace(reFindMultiplePeriods, ".").split(".").map((d) => {
89
- if (d.indexOf(intPrefix) === 0) {
90
- return parseInt(d.substring(intPrefix.length), 10);
91
- }
92
- return d;
93
- });
94
- }
95
- function isNonEmptyArray(obj) {
96
- return !(Array.isArray(obj) && obj.length === 0);
97
- }
98
- function getAsyncValidatorArray(cause, options) {
99
- const { asyncDebounceMs } = options;
100
- const {
101
- onChangeAsync,
102
- onBlurAsync,
103
- onSubmitAsync,
104
- onBlurAsyncDebounceMs,
105
- onChangeAsyncDebounceMs,
106
- onSubmitAsyncDebounceMs
107
- } = options.validators || {};
108
- const defaultDebounceMs = asyncDebounceMs ?? 0;
109
- const changeValidator = {
110
- cause: "change",
111
- validate: onChangeAsync,
112
- debounceMs: onChangeAsyncDebounceMs ?? defaultDebounceMs
113
- };
114
- const blurValidator = {
115
- cause: "blur",
116
- validate: onBlurAsync,
117
- debounceMs: onBlurAsyncDebounceMs ?? defaultDebounceMs
118
- };
119
- const submitValidator = {
120
- cause: "submit",
121
- validate: onSubmitAsync,
122
- debounceMs: onSubmitAsyncDebounceMs ?? defaultDebounceMs
123
- };
124
- switch (cause) {
125
- case "submit":
126
- return [changeValidator, blurValidator, submitValidator];
127
- case "server":
128
- return [];
129
- case "blur":
130
- return [blurValidator];
131
- case "change":
132
- default:
133
- return [changeValidator];
134
- }
135
- }
136
- function getSyncValidatorArray(cause, options) {
137
- const { onChange, onBlur, onSubmit } = options.validators || {};
138
- const changeValidator = { cause: "change", validate: onChange };
139
- const blurValidator = { cause: "blur", validate: onBlur };
140
- const submitValidator = { cause: "submit", validate: onSubmit };
141
- const serverValidator = {
142
- cause: "server",
143
- validate: () => void 0
144
- };
145
- switch (cause) {
146
- case "submit":
147
- return [
148
- changeValidator,
149
- blurValidator,
150
- submitValidator,
151
- serverValidator
152
- ];
153
- case "server":
154
- return [serverValidator];
155
- case "blur":
156
- return [blurValidator, serverValidator];
157
- case "change":
158
- default:
159
- return [changeValidator, serverValidator];
160
- }
161
- }
162
- function getDefaultFormState(defaultState) {
163
- return {
164
- values: defaultState.values ?? {},
165
- errors: defaultState.errors ?? [],
166
- errorMap: defaultState.errorMap ?? {},
167
- fieldMeta: defaultState.fieldMeta ?? {},
168
- canSubmit: defaultState.canSubmit ?? true,
169
- isFieldsValid: defaultState.isFieldsValid ?? false,
170
- isFieldsValidating: defaultState.isFieldsValidating ?? false,
171
- isFormValid: defaultState.isFormValid ?? false,
172
- isFormValidating: defaultState.isFormValidating ?? false,
173
- isSubmitted: defaultState.isSubmitted ?? false,
174
- isSubmitting: defaultState.isSubmitting ?? false,
175
- isTouched: defaultState.isTouched ?? false,
176
- isValid: defaultState.isValid ?? false,
177
- isValidating: defaultState.isValidating ?? false,
178
- submissionAttempts: defaultState.submissionAttempts ?? 0,
179
- validationMetaMap: defaultState.validationMetaMap ?? {
180
- onChange: void 0,
181
- onBlur: void 0,
182
- onSubmit: void 0,
183
- onMount: void 0,
184
- onServer: void 0
185
- }
186
- };
187
- }
188
- class FormApi {
189
- constructor(opts) {
190
- var _a;
191
- this.options = {};
192
- this.fieldInfo = {};
193
- this.prevTransformArray = [];
194
- this.mount = () => {
195
- const { onMount } = this.options.validators || {};
196
- if (!onMount)
197
- return;
198
- const error = this.runValidator({
199
- validate: onMount,
200
- value: {
201
- value: this.state.values,
202
- formApi: this
203
- },
204
- type: "validate"
205
- });
206
- if (error) {
207
- this.store.setState((prev) => ({
208
- ...prev,
209
- errorMap: { ...prev.errorMap, onMount: error }
210
- }));
211
- }
212
- };
213
- this.update = (options) => {
214
- if (!options)
215
- return;
216
- const oldOptions = this.options;
217
- this.options = options;
218
- this.store.batch(() => {
219
- const shouldUpdateValues = options.defaultValues && options.defaultValues !== oldOptions.defaultValues && !this.state.isTouched;
220
- const shouldUpdateState = options.defaultState !== oldOptions.defaultState && !this.state.isTouched;
221
- this.store.setState(
222
- () => getDefaultFormState(
223
- Object.assign(
224
- {},
225
- this.state,
226
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
227
- shouldUpdateState ? options.defaultState : {},
228
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
229
- shouldUpdateValues ? {
230
- values: options.defaultValues
231
- } : {}
232
- )
233
- )
234
- );
235
- });
236
- };
237
- this.reset = () => this.store.setState(
238
- () => {
239
- var _a2;
240
- return getDefaultFormState({
241
- ...this.options.defaultState,
242
- values: this.options.defaultValues ?? ((_a2 = this.options.defaultState) == null ? void 0 : _a2.values)
243
- });
244
- }
245
- );
246
- this.validateAllFields = async (cause) => {
247
- const fieldValidationPromises = [];
248
- this.store.batch(() => {
249
- void Object.values(this.fieldInfo).forEach((field) => {
250
- Object.values(field.instances).forEach((instance) => {
251
- fieldValidationPromises.push(
252
- Promise.resolve().then(() => instance.validate(cause))
253
- );
254
- if (!instance.state.meta.isTouched) {
255
- instance.setMeta((prev) => ({ ...prev, isTouched: true }));
256
- }
257
- });
258
- });
259
- });
260
- const fieldErrorMapMap = await Promise.all(fieldValidationPromises);
261
- return fieldErrorMapMap.flat();
262
- };
263
- this.validateSync = (cause) => {
264
- const validates = getSyncValidatorArray(cause, this.options);
265
- let hasErrored = false;
266
- this.store.batch(() => {
267
- for (const validateObj of validates) {
268
- if (!validateObj.validate)
269
- continue;
270
- const error = normalizeError$1(
271
- this.runValidator({
272
- validate: validateObj.validate,
273
- value: {
274
- value: this.state.values,
275
- formApi: this
276
- },
277
- type: "validate"
278
- })
279
- );
280
- const errorMapKey = getErrorMapKey$1(validateObj.cause);
281
- if (this.state.errorMap[errorMapKey] !== error) {
282
- this.store.setState((prev) => ({
283
- ...prev,
284
- errorMap: {
285
- ...prev.errorMap,
286
- [errorMapKey]: error
287
- }
288
- }));
289
- }
290
- if (error) {
291
- hasErrored = true;
292
- }
293
- }
294
- });
295
- const submitErrKey = getErrorMapKey$1("submit");
296
- if (this.state.errorMap[submitErrKey] && cause !== "submit" && !hasErrored) {
297
- this.store.setState((prev) => ({
298
- ...prev,
299
- errorMap: {
300
- ...prev.errorMap,
301
- [submitErrKey]: void 0
302
- }
303
- }));
304
- }
305
- return { hasErrored };
306
- };
307
- this.validateAsync = async (cause) => {
308
- const validates = getAsyncValidatorArray(cause, this.options);
309
- if (!this.state.isFormValidating) {
310
- this.store.setState((prev) => ({ ...prev, isFormValidating: true }));
311
- }
312
- const promises = [];
313
- for (const validateObj of validates) {
314
- if (!validateObj.validate)
315
- continue;
316
- const key = getErrorMapKey$1(validateObj.cause);
317
- const fieldValidatorMeta = this.state.validationMetaMap[key];
318
- fieldValidatorMeta == null ? void 0 : fieldValidatorMeta.lastAbortController.abort();
319
- const controller = new AbortController();
320
- this.state.validationMetaMap[key] = {
321
- lastAbortController: controller
322
- };
323
- promises.push(
324
- new Promise(async (resolve) => {
325
- let rawError;
326
- try {
327
- rawError = await new Promise((rawResolve, rawReject) => {
328
- setTimeout(async () => {
329
- if (controller.signal.aborted)
330
- return rawResolve(void 0);
331
- try {
332
- rawResolve(
333
- await this.runValidator({
334
- validate: validateObj.validate,
335
- value: {
336
- value: this.state.values,
337
- formApi: this,
338
- signal: controller.signal
339
- },
340
- type: "validateAsync"
341
- })
342
- );
343
- } catch (e) {
344
- rawReject(e);
345
- }
346
- }, validateObj.debounceMs);
347
- });
348
- } catch (e) {
349
- rawError = e;
350
- }
351
- const error = normalizeError$1(rawError);
352
- this.store.setState((prev) => ({
353
- ...prev,
354
- errorMap: {
355
- ...prev.errorMap,
356
- [getErrorMapKey$1(cause)]: error
357
- }
358
- }));
359
- resolve(error);
360
- })
361
- );
362
- }
363
- let results = [];
364
- if (promises.length) {
365
- results = await Promise.all(promises);
366
- }
367
- this.store.setState((prev) => ({
368
- ...prev,
369
- isFormValidating: false
370
- }));
371
- return results.filter(Boolean);
372
- };
373
- this.validate = (cause) => {
374
- const { hasErrored } = this.validateSync(cause);
375
- if (hasErrored && !this.options.asyncAlways) {
376
- return this.state.errors;
377
- }
378
- return this.validateAsync(cause);
379
- };
380
- this.handleSubmit = async () => {
381
- var _a2, _b, _c, _d, _e, _f;
382
- this.store.setState((old) => ({
383
- ...old,
384
- // Submission attempts mark the form as not submitted
385
- isSubmitted: false,
386
- // Count submission attempts
387
- submissionAttempts: old.submissionAttempts + 1
388
- }));
389
- if (!this.state.canSubmit)
390
- return;
391
- this.store.setState((d) => ({ ...d, isSubmitting: true }));
392
- const done = () => {
393
- this.store.setState((prev) => ({ ...prev, isSubmitting: false }));
394
- };
395
- await this.validateAllFields("submit");
396
- if (!this.state.isFieldsValid) {
397
- done();
398
- (_b = (_a2 = this.options).onSubmitInvalid) == null ? void 0 : _b.call(_a2, {
399
- value: this.state.values,
400
- formApi: this
401
- });
402
- return;
403
- }
404
- await this.validate("submit");
405
- if (!this.state.isValid) {
406
- done();
407
- (_d = (_c = this.options).onSubmitInvalid) == null ? void 0 : _d.call(_c, {
408
- value: this.state.values,
409
- formApi: this
410
- });
411
- return;
412
- }
413
- try {
414
- await ((_f = (_e = this.options).onSubmit) == null ? void 0 : _f.call(_e, { value: this.state.values, formApi: this }));
415
- this.store.batch(() => {
416
- this.store.setState((prev) => ({ ...prev, isSubmitted: true }));
417
- done();
418
- });
419
- } catch (err) {
420
- done();
421
- throw err;
422
- }
423
- };
424
- this.getFieldValue = (field) => getBy(this.state.values, field);
425
- this.getFieldMeta = (field) => {
426
- return this.state.fieldMeta[field];
427
- };
428
- this.getFieldInfo = (field) => {
429
- var _a2;
430
- return (_a2 = this.fieldInfo)[field] || (_a2[field] = {
431
- instances: {},
432
- validationMetaMap: {
433
- onChange: void 0,
434
- onBlur: void 0,
435
- onSubmit: void 0,
436
- onMount: void 0,
437
- onServer: void 0
438
- }
439
- });
440
- };
441
- this.setFieldMeta = (field, updater) => {
442
- this.store.setState((prev) => {
443
- return {
444
- ...prev,
445
- fieldMeta: {
446
- ...prev.fieldMeta,
447
- [field]: functionalUpdate(updater, prev.fieldMeta[field])
448
- }
449
- };
450
- });
451
- };
452
- this.setFieldValue = (field, updater, opts2) => {
453
- const touch = opts2 == null ? void 0 : opts2.touch;
454
- this.store.batch(() => {
455
- if (touch) {
456
- this.setFieldMeta(field, (prev) => ({
457
- ...prev,
458
- isTouched: true
459
- }));
460
- }
461
- this.store.setState((prev) => {
462
- return {
463
- ...prev,
464
- values: setBy(prev.values, field, updater)
465
- };
466
- });
467
- });
468
- };
469
- this.deleteField = (field) => {
470
- this.store.setState((prev) => {
471
- const newState = { ...prev };
472
- newState.values = deleteBy(newState.values, field);
473
- delete newState.fieldMeta[field];
474
- return newState;
475
- });
476
- };
477
- this.pushFieldValue = (field, value, opts2) => {
478
- return this.setFieldValue(
479
- field,
480
- (prev) => [...Array.isArray(prev) ? prev : [], value],
481
- opts2
482
- );
483
- };
484
- this.insertFieldValue = (field, index, value, opts2) => {
485
- this.setFieldValue(
486
- field,
487
- (prev) => {
488
- return prev.map(
489
- (d, i) => i === index ? value : d
490
- );
491
- },
492
- opts2
493
- );
494
- };
495
- this.removeFieldValue = (field, index, opts2) => {
496
- this.setFieldValue(
497
- field,
498
- (prev) => {
499
- return prev.filter(
500
- (_d, i) => i !== index
501
- );
502
- },
503
- opts2
504
- );
505
- };
506
- this.swapFieldValues = (field, index1, index2) => {
507
- this.setFieldValue(field, (prev) => {
508
- const prev1 = prev[index1];
509
- const prev2 = prev[index2];
510
- return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1);
511
- });
512
- };
513
- this.store = new store.Store(
514
- getDefaultFormState({
515
- ...opts == null ? void 0 : opts.defaultState,
516
- values: (opts == null ? void 0 : opts.defaultValues) ?? ((_a = opts == null ? void 0 : opts.defaultState) == null ? void 0 : _a.values),
517
- isFormValid: true
518
- }),
519
- {
520
- onUpdate: () => {
521
- var _a2, _b;
522
- let { state } = this.store;
523
- const fieldMetaValues = Object.values(state.fieldMeta);
524
- const isFieldsValidating = fieldMetaValues.some(
525
- (field) => field == null ? void 0 : field.isValidating
526
- );
527
- const isFieldsValid = !fieldMetaValues.some(
528
- (field) => (field == null ? void 0 : field.errorMap) && isNonEmptyArray(Object.values(field.errorMap).filter(Boolean))
529
- );
530
- const isTouched = fieldMetaValues.some((field) => field == null ? void 0 : field.isTouched);
531
- const isValidating = isFieldsValidating || state.isFormValidating;
532
- state.errors = Object.values(state.errorMap).filter(
533
- (val) => val !== void 0
534
- );
535
- const isFormValid = state.errors.length === 0;
536
- const isValid = isFieldsValid && isFormValid;
537
- const canSubmit = state.submissionAttempts === 0 && !isTouched || !isValidating && !state.isSubmitting && isValid;
538
- state = {
539
- ...state,
540
- isFieldsValidating,
541
- isFieldsValid,
542
- isFormValid,
543
- isValid,
544
- canSubmit,
545
- isTouched
546
- };
547
- this.state = state;
548
- this.store.state = this.state;
549
- const transformArray = ((_a2 = this.options.transform) == null ? void 0 : _a2.deps) ?? [];
550
- const shouldTransform = transformArray.length !== this.prevTransformArray.length || transformArray.some((val, i) => val !== this.prevTransformArray[i]);
551
- if (shouldTransform) {
552
- (_b = this.options.transform) == null ? void 0 : _b.fn(this);
553
- this.store.state = this.state;
554
- this.prevTransformArray = transformArray;
555
- }
556
- }
557
- }
558
- );
559
- this.state = this.store.state;
560
- this.update(opts || {});
561
- }
562
- runValidator(props) {
563
- const adapter = this.options.validatorAdapter;
564
- if (adapter && typeof props.validate !== "function") {
565
- return adapter()[props.type](props.value, props.validate);
566
- }
567
- return props.validate(props.value);
568
- }
569
- }
570
- function normalizeError$1(rawError) {
571
- if (rawError) {
572
- if (typeof rawError !== "string") {
573
- return "Invalid Form Values";
574
- }
575
- return rawError;
576
- }
577
- return void 0;
578
- }
579
- function getErrorMapKey$1(cause) {
580
- switch (cause) {
581
- case "submit":
582
- return "onSubmit";
583
- case "blur":
584
- return "onBlur";
585
- case "mount":
586
- return "onMount";
587
- case "server":
588
- return "onServer";
589
- case "change":
590
- default:
591
- return "onChange";
592
- }
593
- }
594
- let uid = 0;
595
- class FieldApi {
596
- constructor(opts) {
597
- this.options = {};
598
- this.mount = () => {
599
- const info = this.getInfo();
600
- info.instances[this.uid] = this;
601
- const unsubscribe = this.form.store.subscribe(() => {
602
- this.store.batch(() => {
603
- const nextValue = this.getValue();
604
- const nextMeta = this.getMeta();
605
- if (nextValue !== this.state.value) {
606
- this.store.setState((prev) => ({ ...prev, value: nextValue }));
607
- }
608
- if (nextMeta !== this.state.meta) {
609
- this.store.setState((prev) => ({ ...prev, meta: nextMeta }));
610
- }
611
- });
612
- });
613
- this.update(this.options);
614
- const { onMount } = this.options.validators || {};
615
- if (onMount) {
616
- const error = this.runValidator({
617
- validate: onMount,
618
- value: {
619
- value: this.state.value,
620
- fieldApi: this
621
- },
622
- type: "validate"
623
- });
624
- if (error) {
625
- this.setMeta((prev) => ({
626
- ...prev,
627
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
628
- errorMap: { ...prev == null ? void 0 : prev.errorMap, onMount: error }
629
- }));
630
- }
631
- }
632
- return () => {
633
- const preserveValue = this.options.preserveValue;
634
- unsubscribe();
635
- if (!preserveValue) {
636
- delete info.instances[this.uid];
637
- this.form.deleteField(this.name);
638
- }
639
- if (!Object.keys(info.instances).length && !preserveValue) {
640
- delete this.form.fieldInfo[this.name];
641
- }
642
- };
643
- };
644
- this.update = (opts2) => {
645
- var _a;
646
- if (this.state.value === void 0) {
647
- const formDefault = (_a = opts2.form.options.defaultValues) == null ? void 0 : _a[opts2.name];
648
- if (opts2.defaultValue !== void 0) {
649
- this.setValue(opts2.defaultValue);
650
- } else if (formDefault !== void 0) {
651
- this.setValue(formDefault);
652
- }
653
- }
654
- if (this._getMeta() === void 0) {
655
- this.setMeta(this.state.meta);
656
- }
657
- this.options = opts2;
658
- };
659
- this.getValue = () => {
660
- return this.form.getFieldValue(this.name);
661
- };
662
- this.setValue = (updater, options) => {
663
- this.form.setFieldValue(this.name, updater, options);
664
- this.validate("change", this.state.value);
665
- };
666
- this._getMeta = () => this.form.getFieldMeta(this.name);
667
- this.getMeta = () => this._getMeta() ?? {
668
- isValidating: false,
669
- isTouched: false,
670
- touchedErrors: [],
671
- errors: [],
672
- errorMap: {},
673
- ...this.options.defaultMeta
674
- };
675
- this.setMeta = (updater) => this.form.setFieldMeta(this.name, updater);
676
- this.getInfo = () => this.form.getFieldInfo(this.name);
677
- this.pushValue = (value) => this.form.pushFieldValue(this.name, value);
678
- this.insertValue = (index, value) => this.form.insertFieldValue(this.name, index, value);
679
- this.removeValue = (index) => this.form.removeFieldValue(this.name, index);
680
- this.swapValues = (aIndex, bIndex) => this.form.swapFieldValues(this.name, aIndex, bIndex);
681
- this.getSubField = (name) => new FieldApi({
682
- name: `${this.name}.${name}`,
683
- form: this.form
684
- });
685
- this.validateSync = (value = this.state.value, cause) => {
686
- const validates = getSyncValidatorArray(cause, this.options);
687
- let hasErrored = false;
688
- this.form.store.batch(() => {
689
- for (const validateObj of validates) {
690
- if (!validateObj.validate)
691
- continue;
692
- const error = normalizeError(
693
- this.runValidator({
694
- validate: validateObj.validate,
695
- value: { value, fieldApi: this },
696
- type: "validate"
697
- })
698
- );
699
- const errorMapKey = getErrorMapKey(validateObj.cause);
700
- if (this.state.meta.errorMap[errorMapKey] !== error) {
701
- this.setMeta((prev) => ({
702
- ...prev,
703
- errorMap: {
704
- ...prev.errorMap,
705
- [getErrorMapKey(validateObj.cause)]: error
706
- }
707
- }));
708
- }
709
- if (error) {
710
- hasErrored = true;
711
- }
712
- }
713
- });
714
- const submitErrKey = getErrorMapKey("submit");
715
- if (this.state.meta.errorMap[submitErrKey] && cause !== "submit" && !hasErrored) {
716
- this.setMeta((prev) => ({
717
- ...prev,
718
- errorMap: {
719
- ...prev.errorMap,
720
- [submitErrKey]: void 0
721
- }
722
- }));
723
- }
724
- return { hasErrored };
725
- };
726
- this.validateAsync = async (value = this.state.value, cause) => {
727
- const validates = getAsyncValidatorArray(cause, this.options);
728
- if (!this.state.meta.isValidating) {
729
- this.setMeta((prev) => ({ ...prev, isValidating: true }));
730
- }
731
- const promises = [];
732
- for (const validateObj of validates) {
733
- if (!validateObj.validate)
734
- continue;
735
- const key = getErrorMapKey(validateObj.cause);
736
- const fieldValidatorMeta = this.getInfo().validationMetaMap[key];
737
- fieldValidatorMeta == null ? void 0 : fieldValidatorMeta.lastAbortController.abort();
738
- const controller = new AbortController();
739
- this.getInfo().validationMetaMap[key] = {
740
- lastAbortController: controller
741
- };
742
- promises.push(
743
- new Promise(async (resolve) => {
744
- let rawError;
745
- try {
746
- rawError = await new Promise((rawResolve, rawReject) => {
747
- setTimeout(async () => {
748
- if (controller.signal.aborted)
749
- return rawResolve(void 0);
750
- try {
751
- rawResolve(
752
- await this.runValidator({
753
- validate: validateObj.validate,
754
- value: {
755
- value,
756
- fieldApi: this,
757
- signal: controller.signal
758
- },
759
- type: "validateAsync"
760
- })
761
- );
762
- } catch (e) {
763
- rawReject(e);
764
- }
765
- }, validateObj.debounceMs);
766
- });
767
- } catch (e) {
768
- rawError = e;
769
- }
770
- const error = normalizeError(rawError);
771
- this.setMeta((prev) => {
772
- return {
773
- ...prev,
774
- errorMap: {
775
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
776
- ...prev == null ? void 0 : prev.errorMap,
777
- [getErrorMapKey(cause)]: error
778
- }
779
- };
780
- });
781
- resolve(error);
782
- })
783
- );
784
- }
785
- let results = [];
786
- if (promises.length) {
787
- results = await Promise.all(promises);
788
- }
789
- this.setMeta((prev) => ({ ...prev, isValidating: false }));
790
- return results.filter(Boolean);
791
- };
792
- this.validate = (cause, value) => {
793
- if (!this.state.meta.isTouched)
794
- return [];
795
- try {
796
- this.form.validate(cause);
797
- } catch (_) {
798
- }
799
- const { hasErrored } = this.validateSync(value, cause);
800
- if (hasErrored && !this.options.asyncAlways) {
801
- return this.state.meta.errors;
802
- }
803
- return this.validateAsync(value, cause);
804
- };
805
- this.handleChange = (updater) => {
806
- this.setValue(updater, { touch: true });
807
- };
808
- this.handleBlur = () => {
809
- const prevTouched = this.state.meta.isTouched;
810
- if (!prevTouched) {
811
- this.setMeta((prev) => ({ ...prev, isTouched: true }));
812
- this.validate("change");
813
- }
814
- this.validate("blur");
815
- };
816
- this.form = opts.form;
817
- this.uid = uid++;
818
- this.name = opts.name;
819
- if (opts.defaultValue !== void 0) {
820
- this.form.setFieldValue(this.name, opts.defaultValue);
821
- }
822
- this.store = new store.Store(
823
- {
824
- value: this.getValue(),
825
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
826
- meta: this._getMeta() ?? {
827
- isValidating: false,
828
- isTouched: false,
829
- touchedErrors: [],
830
- errors: [],
831
- errorMap: {},
832
- ...opts.defaultMeta
833
- }
834
- },
835
- {
836
- onUpdate: () => {
837
- const state = this.store.state;
838
- state.meta.errors = Object.values(state.meta.errorMap).filter(
839
- (val) => val !== void 0
840
- );
841
- state.meta.touchedErrors = state.meta.isTouched ? state.meta.errors : [];
842
- this.prevState = state;
843
- this.state = state;
844
- }
845
- }
846
- );
847
- this.state = this.store.state;
848
- this.prevState = this.state;
849
- this.options = opts;
850
- }
851
- runValidator(props) {
852
- const adapters = [
853
- this.form.options.validatorAdapter,
854
- this.options.validatorAdapter
855
- ];
856
- for (const adapter of adapters) {
857
- if (adapter && typeof props.validate !== "function") {
858
- return adapter()[props.type](props.value, props.validate);
859
- }
860
- }
861
- return props.validate(props.value);
862
- }
863
- }
864
- function normalizeError(rawError) {
865
- if (rawError) {
866
- if (typeof rawError !== "string") {
867
- return "Invalid Form Values";
868
- }
869
- return rawError;
870
- }
871
- return void 0;
872
- }
873
- function getErrorMapKey(cause) {
874
- switch (cause) {
875
- case "submit":
876
- return "onSubmit";
877
- case "blur":
878
- return "onBlur";
879
- case "mount":
880
- return "onMount";
881
- case "server":
882
- return "onServer";
883
- case "change":
884
- default:
885
- return "onChange";
886
- }
887
- }
888
- function mutateMergeDeep(target, source) {
889
- const targetKeys = Object.keys(target);
890
- const sourceKeys = Object.keys(source);
891
- const keySet = /* @__PURE__ */ new Set([...targetKeys, ...sourceKeys]);
892
- for (const key of keySet) {
893
- const targetKey = key;
894
- const sourceKey = key;
895
- if (Array.isArray(target[targetKey]) && Array.isArray(source[sourceKey])) {
896
- target[targetKey] = [
897
- ...target[targetKey],
898
- ...source[sourceKey]
899
- ];
900
- } else if (typeof target[targetKey] === "object" && typeof source[sourceKey] === "object") {
901
- mutateMergeDeep(target[targetKey], source[sourceKey]);
902
- } else {
903
- if (!(sourceKey in source) && source[sourceKey] === void 0) {
904
- continue;
905
- }
906
- target[targetKey] = source[sourceKey];
907
- }
908
- }
909
- return target;
910
- }
911
- function mergeForm(baseForm, state) {
912
- mutateMergeDeep(baseForm.state, state);
913
- return baseForm;
914
- }
915
- exports.FieldApi = FieldApi;
916
- exports.FormApi = FormApi;
917
- exports.deleteBy = deleteBy;
918
- exports.functionalUpdate = functionalUpdate;
919
- exports.getAsyncValidatorArray = getAsyncValidatorArray;
920
- exports.getBy = getBy;
921
- exports.getSyncValidatorArray = getSyncValidatorArray;
922
- exports.isNonEmptyArray = isNonEmptyArray;
923
- exports.mergeForm = mergeForm;
924
- exports.mutateMergeDeep = mutateMergeDeep;
925
- exports.setBy = setBy;
926
- //# sourceMappingURL=index.cjs.map