@vuehookform/core 0.3.3 → 0.4.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.
@@ -1,34 +1,45 @@
1
- import { ShallowRef } from 'vue';
1
+ import { Ref, ShallowRef } from 'vue';
2
2
  /**
3
- * Mark a field as dirty (value has changed from default)
3
+ * Mark a field as dirty (value has changed from default).
4
+ * Optimized to skip clone if already dirty.
5
+ * Maintains O(1) dirty field count for performance.
4
6
  *
5
7
  * @param dirtyFields - The reactive dirty fields record
8
+ * @param dirtyFieldCount - Counter for O(1) isDirty checks
6
9
  * @param fieldName - Name of the field to mark as dirty
7
10
  */
8
- export declare function markFieldDirty(dirtyFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
11
+ export declare function markFieldDirty(dirtyFields: ShallowRef<Record<string, boolean>>, dirtyFieldCount: Ref<number>, fieldName: string): void;
9
12
  /**
10
- * Mark a field as touched (user has interacted with it)
13
+ * Mark a field as touched (user has interacted with it).
14
+ * Optimized to skip clone if already touched.
15
+ * Maintains O(1) touched field count for performance.
11
16
  *
12
17
  * @param touchedFields - The reactive touched fields record
18
+ * @param touchedFieldCount - Counter for O(1) touched checks
13
19
  * @param fieldName - Name of the field to mark as touched
14
20
  */
15
- export declare function markFieldTouched(touchedFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
21
+ export declare function markFieldTouched(touchedFields: ShallowRef<Record<string, boolean>>, touchedFieldCount: Ref<number>, fieldName: string): void;
16
22
  /**
17
- * Clear dirty state for a field
23
+ * Clear dirty state for a field.
24
+ * Maintains O(1) dirty field count for performance.
18
25
  *
19
26
  * @param dirtyFields - The reactive dirty fields record
27
+ * @param dirtyFieldCount - Counter for O(1) isDirty checks
20
28
  * @param fieldName - Name of the field to clear
21
29
  */
22
- export declare function clearFieldDirty(dirtyFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
30
+ export declare function clearFieldDirty(dirtyFields: ShallowRef<Record<string, boolean>>, dirtyFieldCount: Ref<number>, fieldName: string): void;
23
31
  /**
24
- * Clear touched state for a field
32
+ * Clear touched state for a field.
33
+ * Maintains O(1) touched field count for performance.
25
34
  *
26
35
  * @param touchedFields - The reactive touched fields record
36
+ * @param touchedFieldCount - Counter for O(1) touched checks
27
37
  * @param fieldName - Name of the field to clear
28
38
  */
29
- export declare function clearFieldTouched(touchedFields: ShallowRef<Record<string, boolean>>, fieldName: string): void;
39
+ export declare function clearFieldTouched(touchedFields: ShallowRef<Record<string, boolean>>, touchedFieldCount: Ref<number>, fieldName: string): void;
30
40
  /**
31
- * Clear errors for a field and its nested paths
41
+ * Clear errors for a field and its nested paths.
42
+ * Optimized with early exit if nothing to delete.
32
43
  *
33
44
  * @param errors - The reactive errors record
34
45
  * @param fieldName - Name of the field (clears exact match and all nested paths)
@@ -33,7 +33,7 @@ export interface FormContext<FormValues> {
33
33
  submitCount: Ref<number>;
34
34
  defaultValuesError: Ref<unknown>;
35
35
  isSubmitSuccessful: Ref<boolean>;
36
- validatingFields: ShallowRef<Record<string, boolean>>;
36
+ validatingFields: ShallowRef<Set<string>>;
37
37
  externalErrors: ShallowRef<FieldErrors<FormValues>>;
38
38
  errorDelayTimers: Map<string, ReturnType<typeof setTimeout>>;
39
39
  pendingErrors: Map<string, FieldErrorValue>;
@@ -45,6 +45,13 @@ export interface FormContext<FormValues> {
45
45
  validationRequestIds: Map<string, number>;
46
46
  resetGeneration: Ref<number>;
47
47
  isDisabled: Ref<boolean>;
48
+ dirtyFieldCount: Ref<number>;
49
+ touchedFieldCount: Ref<number>;
50
+ validationCache: Map<string, {
51
+ hash: string;
52
+ isValid: boolean;
53
+ }>;
54
+ schemaValidationTimers: Map<string, ReturnType<typeof setTimeout>>;
48
55
  options: UseFormOptions<ZodType>;
49
56
  }
50
57
  /**
package/dist/types.d.ts CHANGED
@@ -170,8 +170,8 @@ export interface FormState<T> {
170
170
  isReady: boolean;
171
171
  /** Whether any field is currently being validated */
172
172
  isValidating: boolean;
173
- /** Record of fields currently being validated */
174
- validatingFields: Record<string, boolean>;
173
+ /** Set of field paths currently being validated */
174
+ validatingFields: Set<string>;
175
175
  /** Record of touched field paths */
176
176
  touchedFields: Record<string, boolean>;
177
177
  /** Record of dirty field paths */
@@ -571,6 +571,22 @@ export interface UseFormOptions<TSchema extends ZodType> {
571
571
  * ```
572
572
  */
573
573
  delayError?: number;
574
+ /**
575
+ * Debounce time in milliseconds for schema validation in onChange mode.
576
+ * Prevents excessive validation calls during rapid typing.
577
+ * Unlike delayError which delays showing errors, this delays the validation itself.
578
+ *
579
+ * @example Debounce validation by 150ms
580
+ * ```ts
581
+ * useForm({
582
+ * schema,
583
+ * mode: 'onChange',
584
+ * validationDebounce: 150 // Wait 150ms of idle time before validating
585
+ * })
586
+ * // Reduces validation calls during rapid typing
587
+ * ```
588
+ */
589
+ validationDebounce?: number;
574
590
  /**
575
591
  * External values to sync to form. Changes update formData without marking dirty.
576
592
  * Useful for server-fetched data or parent component state.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Deep clone utility for form values.
3
+ * Handles common types without JSON.parse/stringify overhead.
4
+ *
5
+ * Properly handles:
6
+ * - Primitives (pass-through)
7
+ * - Plain objects (recursive clone)
8
+ * - Arrays (recursive clone)
9
+ * - Date objects (new Date instance)
10
+ * - null/undefined (pass-through)
11
+ *
12
+ * Does NOT handle (by design, not needed for form data):
13
+ * - Circular references
14
+ * - Map/Set/WeakMap/WeakSet
15
+ * - Functions
16
+ * - Symbols
17
+ * - Class instances (cloned as plain objects)
18
+ */
19
+ export declare function deepClone<T>(obj: T): T;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Fast value hashing for validation cache.
3
+ * Uses JSON.stringify for objects/arrays, direct conversion for primitives.
4
+ * Returns a string that can be compared for equality.
5
+ */
6
+ export declare function hashValue(value: unknown): string;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Clear the path cache. Useful for testing or when paths change significantly.
3
+ * @internal
4
+ */
5
+ export declare function clearPathCache(): void;
1
6
  /**
2
7
  * Get value from object using dot notation path
3
8
  * @example get({ user: { name: 'John' } }, 'user.name') => 'John'
@@ -0,0 +1,42 @@
1
+ import { ZodType } from 'zod';
2
+ interface SchemaPathAnalysis {
3
+ canPartialValidate: boolean;
4
+ subSchema?: ZodType;
5
+ reason?: 'root-checks' | 'path-checks' | 'unsupported-type' | 'invalid-path';
6
+ }
7
+ /**
8
+ * Check if the root schema has refinements/checks
9
+ * Root-level checks may depend on multiple fields, requiring full validation
10
+ */
11
+ export declare function hasRootEffects(schema: ZodType): boolean;
12
+ /**
13
+ * Extract sub-schema for a given path
14
+ *
15
+ * Returns the sub-schema and whether any checks/refinements were encountered.
16
+ * If checks are found at object level, partial validation isn't safe because
17
+ * the refinement may depend on other fields.
18
+ *
19
+ * @param schema - Root form schema
20
+ * @param path - Dot-notation field path (e.g., "user.address.city")
21
+ * @returns Sub-schema and effects flag, or null if path invalid
22
+ */
23
+ export declare function extractSubSchema(schema: ZodType, path: string): {
24
+ schema: ZodType;
25
+ hasEffects: boolean;
26
+ } | null;
27
+ /**
28
+ * Analyze if a path can be validated in isolation
29
+ *
30
+ * This is the main entry point for determining partial validation eligibility.
31
+ * Results are cached per-schema for performance.
32
+ *
33
+ * @param schema - Root form schema
34
+ * @param path - Dot-notation field path
35
+ * @returns Analysis result with eligibility and reason
36
+ */
37
+ export declare function analyzeSchemaPath(schema: ZodType, path: string): SchemaPathAnalysis;
38
+ /**
39
+ * Clear the analysis cache (useful for testing)
40
+ */
41
+ export declare function clearAnalysisCache(): void;
42
+ export {};