@formisch/svelte 0.9.0 → 0.10.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.
- package/README.md +1 -1
- package/dist/core/index.svelte.d.ts +222 -167
- package/dist/core/index.svelte.js +90 -98
- package/dist/methods/index.svelte.d.ts +264 -7
- package/dist/methods/index.svelte.js +60 -26
- package/dist/runes/createForm/createForm.svelte.js +4 -0
- package/dist/runes/useField/useField.svelte.js +4 -0
- package/dist/runes/useFieldArray/useFieldArray.svelte.js +4 -0
- package/dist/types/field.d.ts +8 -0
- package/dist/types/form.d.ts +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ Every form starts with the `createForm` function. It initializes your form's sto
|
|
|
56
56
|
</Form>
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
In addition, Formisch offers several functions (we call them "methods") that can be used to read and manipulate the form state. These include `focus`, `
|
|
59
|
+
In addition, Formisch offers several functions (we call them "methods") that can be used to read and manipulate the form state. These include `focus`, `getDeepErrorEntries`, `getDeepErrors`, `getDirtyInput`, `getDirtyPaths`, `getErrors`, `getInput`, `handleSubmit`, `insert`, `isDirty`, `isEdited`, `isTouched`, `isValid`, `move`, `pickDirty`, `remove`, `replace`, `reset`, `setErrors`, `setInput`, `submit`, `swap` and `validate`. These methods allow you to control the form programmatically.
|
|
60
60
|
|
|
61
61
|
## Comparison
|
|
62
62
|
|
|
@@ -1,6 +1,177 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
2
|
import { untrack } from "svelte";
|
|
3
3
|
|
|
4
|
+
//#region src/types/utils/utils.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Checks if a type is `any`.
|
|
7
|
+
*/
|
|
8
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
9
|
+
/**
|
|
10
|
+
* Checks if a type is `never`.
|
|
11
|
+
*/
|
|
12
|
+
type IsNever<T> = [T] extends [never] ? true : false;
|
|
13
|
+
/**
|
|
14
|
+
* Constructs a type that is maybe a promise.
|
|
15
|
+
*/
|
|
16
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
17
|
+
/**
|
|
18
|
+
* Makes all properties deeply optional.
|
|
19
|
+
*/
|
|
20
|
+
type DeepPartial<TValue> = TValue extends Record<PropertyKey, unknown> | readonly unknown[] ? { [TKey in keyof TValue]?: DeepPartial<TValue[TKey]> | undefined } : TValue | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Makes all value properties optional.
|
|
23
|
+
*
|
|
24
|
+
* Hint: For dynamic arrays, only plain objects and nested arrays have their
|
|
25
|
+
* values made optional. Primitives and class instances are kept as-is to avoid
|
|
26
|
+
* types like `(string | undefined)[]`.
|
|
27
|
+
*/
|
|
28
|
+
type PartialValues<TValue> = TValue extends readonly (infer TItem)[] ? number extends TValue["length"] ? (TItem extends Record<PropertyKey, unknown> | readonly unknown[] ? { [TKey in keyof TItem]: PartialValues<TItem[TKey]> } : TItem)[] : { [TKey in keyof TValue]: PartialValues<TValue[TKey]> } : TValue extends Record<PropertyKey, unknown> ? { [TKey in keyof TValue]: PartialValues<TValue[TKey]> } : TValue | undefined;
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/types/path/path.d.ts
|
|
31
|
+
/**
|
|
32
|
+
* Path key type.
|
|
33
|
+
*/
|
|
34
|
+
type PathKey = string | number;
|
|
35
|
+
/**
|
|
36
|
+
* Path type.
|
|
37
|
+
*/
|
|
38
|
+
type Path = readonly PathKey[];
|
|
39
|
+
/**
|
|
40
|
+
* Required path type.
|
|
41
|
+
*/
|
|
42
|
+
type RequiredPath = readonly [PathKey, ...Path];
|
|
43
|
+
/**
|
|
44
|
+
* Extracts the exact keys of a tuple, array or object. Tuples return their
|
|
45
|
+
* literal numeric indices, dynamic arrays return `number`, objects return
|
|
46
|
+
* their `keyof` keys, and any other input returns `never`.
|
|
47
|
+
*/
|
|
48
|
+
type ExactKeysOf<TValue> = IsAny<TValue> extends true ? never : TValue extends readonly unknown[] ? number extends TValue["length"] ? number : { [TKey in keyof TValue]: TKey extends `${infer TIndex extends number}` ? TIndex : never }[number] : TValue extends Record<PropertyKey, unknown> ? keyof TValue & PathKey : never;
|
|
49
|
+
/**
|
|
50
|
+
* Returns the flat object of all indexable properties of `TValue`. For object
|
|
51
|
+
* unions, properties from every member are merged so that any single property
|
|
52
|
+
* is accessible. For primitives and other non-indexable types, the result is
|
|
53
|
+
* `{}`.
|
|
54
|
+
*
|
|
55
|
+
* Hint: This is necessary to make properties accessible across union members.
|
|
56
|
+
* By default, properties that do not exist in all union options are not
|
|
57
|
+
* accessible and result in "any" when accessed.
|
|
58
|
+
*/
|
|
59
|
+
type PropertiesOf<TValue> = { [TKey in ExactKeysOf<TValue>]: TValue extends Record<TKey, infer TItem> ? TItem : never };
|
|
60
|
+
/**
|
|
61
|
+
* Lazily evaluates only the first valid path segment based on the given value.
|
|
62
|
+
*/
|
|
63
|
+
type LazyPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValidPath : TPathToCheck extends readonly [infer TFirstKey extends ExactKeysOf<TValue>, ...infer TPathRest extends Path] ? LazyPath<Required<PropertiesOf<TValue>[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever<ExactKeysOf<TValue>> extends false ? readonly [...TValidPath, ExactKeysOf<TValue>] : TValidPath;
|
|
64
|
+
/**
|
|
65
|
+
* Returns the path if valid, otherwise the first possible valid path based on
|
|
66
|
+
* the given value.
|
|
67
|
+
*/
|
|
68
|
+
type ValidPath<TValue, TPath extends RequiredPath> = TPath extends LazyPath<Required<TValue>, TPath> ? TPath : LazyPath<Required<TValue>, TPath>;
|
|
69
|
+
/**
|
|
70
|
+
* Detects whether the consuming project is configured with
|
|
71
|
+
* `exactOptionalPropertyTypes: true`.
|
|
72
|
+
*
|
|
73
|
+
* Hint: If `false` the built-in `Required<T>` strips `| undefined` from
|
|
74
|
+
* optional properties, so `Required<{ key?: undefined }>['key']` collapses
|
|
75
|
+
* to `never` — under strict mode the same expression yields `undefined`.
|
|
76
|
+
*/
|
|
77
|
+
type IsExactOptionalProps = Required<{
|
|
78
|
+
key?: undefined;
|
|
79
|
+
}>["key"] extends never ? false : true;
|
|
80
|
+
/**
|
|
81
|
+
* Like the built-in `Required<T>`, but preserves `| undefined` in two
|
|
82
|
+
* places where `Required<T>` strips it:
|
|
83
|
+
*
|
|
84
|
+
* 1. Optional property values under `exactOptionalPropertyTypes: false`
|
|
85
|
+
* — without this, input typings for `v.optional`/`v.nullish` schemas
|
|
86
|
+
* narrow incorrectly (issue #15).
|
|
87
|
+
* 2. Array/tuple element types — e.g. `(string | undefined)[]` stays
|
|
88
|
+
* `(string | undefined)[]` instead of becoming `string[]`. Arrays
|
|
89
|
+
* fall through unchanged because they only have a numeric index
|
|
90
|
+
* signature and don't structurally extend `Record<PropertyKey,
|
|
91
|
+
* unknown>` (which requires string keys).
|
|
92
|
+
*/
|
|
93
|
+
type ExactRequired<TValue> = TValue extends Record<PropertyKey, unknown> ? IsExactOptionalProps extends true ? Required<TValue> : { [TKey in keyof Required<TValue>]: TValue[TKey] } : TValue;
|
|
94
|
+
/**
|
|
95
|
+
* Extracts the value type at the given path.
|
|
96
|
+
*/
|
|
97
|
+
type PathValue<TValue, TPath extends Path> = TPath extends readonly [infer TKey, ...infer TRest extends Path] ? TKey extends ExactKeysOf<ExactRequired<TValue>> ? PathValue<PropertiesOf<ExactRequired<TValue>>[TKey], TRest> : unknown : TValue;
|
|
98
|
+
/**
|
|
99
|
+
* Checks whether a value is a dynamic array or contains one anywhere in its
|
|
100
|
+
* shape. A fixed-length tuple is not itself a dynamic array, but it counts when
|
|
101
|
+
* it contains one, so paths can still navigate through tuples to reach nested
|
|
102
|
+
* arrays.
|
|
103
|
+
*
|
|
104
|
+
* Hint: The inner conditionals (`TValue extends readonly unknown[]` and
|
|
105
|
+
* `TValue extends Record<PropertyKey, unknown>`) distribute over union members,
|
|
106
|
+
* so the inner expression returns the union of each member's result (e.g.
|
|
107
|
+
* `true | false` when some members contain arrays and others don't).
|
|
108
|
+
* Downstream code uses `IsOrHasArray<T> extends true`, but
|
|
109
|
+
* `boolean extends true` is `false` — so we collapse the result via
|
|
110
|
+
* `true extends ...`, which is `true` whenever at least one union member
|
|
111
|
+
* contributed `true`.
|
|
112
|
+
*/
|
|
113
|
+
type IsOrHasArray<TValue> = true extends (IsAny<TValue> extends true ? false : TValue extends readonly unknown[] ? number extends TValue["length"] ? true : IsOrHasArray<TValue[number]> : TValue extends Record<PropertyKey, unknown> ? { [TKey in keyof TValue]: IsOrHasArray<TValue[TKey]> }[keyof TValue] : false) ? true : false;
|
|
114
|
+
/**
|
|
115
|
+
* Extracts the exact keys of a tuple, array or object that contain arrays.
|
|
116
|
+
*/
|
|
117
|
+
type ExactKeysOfArrayPath<TValue> = IsAny<TValue> extends true ? never : TValue extends readonly (infer TItem)[] ? number extends TValue["length"] ? IsOrHasArray<TItem> extends true ? number : never : { [TKey in keyof TValue]: TKey extends `${infer TIndex extends number}` ? IsOrHasArray<NonNullable<TValue[TKey]>> extends true ? TIndex : never : never }[number] : TValue extends Record<PropertyKey, unknown> ? { [TKey in keyof TValue]: IsOrHasArray<NonNullable<TValue[TKey]>> extends true ? TKey : never }[keyof TValue] & PathKey : never;
|
|
118
|
+
/**
|
|
119
|
+
* Returns the flat object of indexable properties of `TValue` whose values
|
|
120
|
+
* are or contain arrays. Mirrors `PropertiesOf` but keyed by
|
|
121
|
+
* `ExactKeysOfArrayPath` so the lookup is provably valid for array-path
|
|
122
|
+
* navigation in `LazyArrayPath`.
|
|
123
|
+
*/
|
|
124
|
+
type PropertiesOfArrayPath<TValue> = { [TKey in ExactKeysOfArrayPath<TValue>]: TValue extends Record<TKey, infer TItem> ? TItem : never };
|
|
125
|
+
/**
|
|
126
|
+
* Lazily evaluates only the first valid array path segment based on the given value.
|
|
127
|
+
*/
|
|
128
|
+
type LazyArrayPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValue extends readonly unknown[] ? number extends TValue["length"] ? TValidPath : IsNever<ExactKeysOfArrayPath<TValue>> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : never : readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : TPathToCheck extends readonly [infer TFirstKey extends ExactKeysOfArrayPath<TValue>, ...infer TPathRest extends Path] ? LazyArrayPath<Required<PropertiesOfArrayPath<TValue>[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever<ExactKeysOfArrayPath<TValue>> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : never;
|
|
129
|
+
/**
|
|
130
|
+
* Returns the path if valid, otherwise the first possible valid array path
|
|
131
|
+
* based on the given value.
|
|
132
|
+
*/
|
|
133
|
+
type ValidArrayPath<TValue, TPath extends RequiredPath> = TPath extends LazyArrayPath<Required<TValue>, TPath> ? TPath : LazyArrayPath<Required<TValue>, TPath>;
|
|
134
|
+
/**
|
|
135
|
+
* Recursive helper for `DirtyPath` that prepends `TKey` to each deeper path,
|
|
136
|
+
* or falls through to `never` when the child is not an object.
|
|
137
|
+
*/
|
|
138
|
+
type DeepDirtyPath<TChild, TKey$1 extends PathKey, TDepth extends 0[]> = TChild extends Record<PropertyKey, unknown> ? readonly [TKey$1, ...DirtyPath<TChild, [...TDepth, 0]>] : never;
|
|
139
|
+
/**
|
|
140
|
+
* Returns the union of all `RequiredPath`s that `getDirtyPaths` can emit
|
|
141
|
+
* for a given input type. Object fields contribute their own path and the
|
|
142
|
+
* paths of their descendants; arrays and tuples are atomic and contribute
|
|
143
|
+
* only their own path, because dirty arrays are returned as complete units.
|
|
144
|
+
*
|
|
145
|
+
* Narrowing is exact for the first 5 levels of nesting; deeper paths fall
|
|
146
|
+
* back to `RequiredPath` to keep the result a complete superset of any
|
|
147
|
+
* path the runtime can address.
|
|
148
|
+
*
|
|
149
|
+
* Hint: Arrays and tuples are atomic because they don't structurally
|
|
150
|
+
* extend `Record<PropertyKey, unknown>` and so fall through to `never`
|
|
151
|
+
* via `DeepDirtyPath` — no explicit array check is needed. `TDepth` is
|
|
152
|
+
* a tuple-length counter capped at 5 to bound TypeScript instantiation
|
|
153
|
+
* cost.
|
|
154
|
+
*/
|
|
155
|
+
type DirtyPath<TValue, TDepth extends 0[] = []> = TDepth["length"] extends 5 ? RequiredPath : TValue extends Record<PropertyKey, unknown> ? { [TKey in ExactKeysOf<TValue>]: readonly [TKey] | DeepDirtyPath<NonNullable<PropertiesOf<TValue>[TKey]>, TKey, TDepth> }[ExactKeysOf<TValue>] : never;
|
|
156
|
+
/**
|
|
157
|
+
* Recursive helper for `FieldPath` that prepends `TKey` to each deeper field
|
|
158
|
+
* path, or falls through to `never` when the child is a leaf value.
|
|
159
|
+
*/
|
|
160
|
+
type DeepFieldPath<TChild, TKey$1 extends PathKey, TDepth extends 0[]> = TChild extends readonly unknown[] | Record<PropertyKey, unknown> ? readonly [TKey$1, ...FieldPath<TChild, [...TDepth, 0]>] : never;
|
|
161
|
+
/**
|
|
162
|
+
* Returns the union of all `RequiredPath`s that address a field within the
|
|
163
|
+
* given input type. Object and array fields contribute their own path and the
|
|
164
|
+
* paths of their descendants; unlike `DirtyPath`, arrays are recursed into so
|
|
165
|
+
* that fields at any depth, including array items, can be addressed. Leaf
|
|
166
|
+
* values contribute only their own path (emitted by their parent).
|
|
167
|
+
*
|
|
168
|
+
* Narrowing is exact for the first 5 levels of nesting; deeper paths fall
|
|
169
|
+
* back to `RequiredPath` to keep the result a complete superset of any path
|
|
170
|
+
* the runtime can address. `TDepth` is a tuple-length counter capped at 5 to
|
|
171
|
+
* bound TypeScript instantiation cost.
|
|
172
|
+
*/
|
|
173
|
+
type FieldPath<TValue, TDepth extends 0[] = []> = TDepth["length"] extends 5 ? RequiredPath : TValue extends readonly unknown[] | Record<PropertyKey, unknown> ? { [TKey in ExactKeysOf<TValue>]: readonly [TKey] | DeepFieldPath<NonNullable<PropertiesOf<TValue>[TKey]>, TKey, TDepth> }[ExactKeysOf<TValue>] : never;
|
|
174
|
+
//#endregion
|
|
4
175
|
//#region src/types/schema/schema.d.ts
|
|
5
176
|
/**
|
|
6
177
|
* Schema type.
|
|
@@ -73,6 +244,10 @@ interface InternalBaseStore {
|
|
|
73
244
|
*/
|
|
74
245
|
name: string;
|
|
75
246
|
/**
|
|
247
|
+
* The path to the field.
|
|
248
|
+
*/
|
|
249
|
+
path: Path;
|
|
250
|
+
/**
|
|
76
251
|
* The schema of the field.
|
|
77
252
|
*/
|
|
78
253
|
schema: Schema;
|
|
@@ -100,6 +275,15 @@ interface InternalBaseStore {
|
|
|
100
275
|
*/
|
|
101
276
|
isTouched: Signal<boolean>;
|
|
102
277
|
/**
|
|
278
|
+
* The edited state of the field.
|
|
279
|
+
*
|
|
280
|
+
* Hint: Unlike `isTouched`, which is also set when a field is focused, this
|
|
281
|
+
* is only set when the field's value is changed. Unlike `isDirty`, it stays
|
|
282
|
+
* `true` even if the value is changed back to its initial value. It is only
|
|
283
|
+
* reset when the field is reset.
|
|
284
|
+
*/
|
|
285
|
+
isEdited: Signal<boolean>;
|
|
286
|
+
/**
|
|
103
287
|
* The dirty state of the field.
|
|
104
288
|
*/
|
|
105
289
|
isDirty: Signal<boolean>;
|
|
@@ -113,6 +297,14 @@ interface InternalArrayStore extends InternalBaseStore {
|
|
|
113
297
|
*/
|
|
114
298
|
kind: "array";
|
|
115
299
|
/**
|
|
300
|
+
* Whether the array schema is wrapped in a nullish schema.
|
|
301
|
+
*
|
|
302
|
+
* Hint: This indicates whether a missing input should be represented as the
|
|
303
|
+
* nullish value (`null`/`undefined`) or as a present but empty array
|
|
304
|
+
* (`true`). It keeps resetting consistent with the initial state.
|
|
305
|
+
*/
|
|
306
|
+
isNullish: boolean;
|
|
307
|
+
/**
|
|
116
308
|
* The children of the array field.
|
|
117
309
|
*/
|
|
118
310
|
children: InternalFieldStore[];
|
|
@@ -165,6 +357,14 @@ interface InternalObjectStore extends InternalBaseStore {
|
|
|
165
357
|
*/
|
|
166
358
|
kind: "object";
|
|
167
359
|
/**
|
|
360
|
+
* Whether the object schema is wrapped in a nullish schema.
|
|
361
|
+
*
|
|
362
|
+
* Hint: This indicates whether a missing input should be represented as the
|
|
363
|
+
* nullish value (`null`/`undefined`) or as a present but empty object
|
|
364
|
+
* (`true`). It keeps resetting consistent with the initial state.
|
|
365
|
+
*/
|
|
366
|
+
isNullish: boolean;
|
|
367
|
+
/**
|
|
168
368
|
* The children of the object field.
|
|
169
369
|
*/
|
|
170
370
|
children: Record<string, InternalFieldStore>;
|
|
@@ -228,32 +428,6 @@ type InternalFieldStore = InternalArrayStore | InternalObjectStore | InternalVal
|
|
|
228
428
|
*/
|
|
229
429
|
declare const INTERNAL: "~internal";
|
|
230
430
|
//#endregion
|
|
231
|
-
//#region src/types/utils/utils.d.ts
|
|
232
|
-
/**
|
|
233
|
-
* Checks if a type is `any`.
|
|
234
|
-
*/
|
|
235
|
-
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
236
|
-
/**
|
|
237
|
-
* Checks if a type is `never`.
|
|
238
|
-
*/
|
|
239
|
-
type IsNever<T> = [T] extends [never] ? true : false;
|
|
240
|
-
/**
|
|
241
|
-
* Constructs a type that is maybe a promise.
|
|
242
|
-
*/
|
|
243
|
-
type MaybePromise<T> = T | Promise<T>;
|
|
244
|
-
/**
|
|
245
|
-
* Makes all properties deeply optional.
|
|
246
|
-
*/
|
|
247
|
-
type DeepPartial<TValue> = TValue extends Record<PropertyKey, unknown> | readonly unknown[] ? { [TKey in keyof TValue]?: DeepPartial<TValue[TKey]> | undefined } : TValue | undefined;
|
|
248
|
-
/**
|
|
249
|
-
* Makes all value properties optional.
|
|
250
|
-
*
|
|
251
|
-
* Hint: For dynamic arrays, only plain objects and nested arrays have their
|
|
252
|
-
* values made optional. Primitives and class instances are kept as-is to avoid
|
|
253
|
-
* types like `(string | undefined)[]`.
|
|
254
|
-
*/
|
|
255
|
-
type PartialValues<TValue> = TValue extends readonly (infer TItem)[] ? number extends TValue["length"] ? (TItem extends Record<PropertyKey, unknown> | readonly unknown[] ? { [TKey in keyof TItem]: PartialValues<TItem[TKey]> } : TItem)[] : { [TKey in keyof TValue]: PartialValues<TValue[TKey]> } : TValue extends Record<PropertyKey, unknown> ? { [TKey in keyof TValue]: PartialValues<TValue[TKey]> } : TValue | undefined;
|
|
256
|
-
//#endregion
|
|
257
431
|
//#region src/types/form/form.d.ts
|
|
258
432
|
/**
|
|
259
433
|
* Validation mode type.
|
|
@@ -337,139 +511,13 @@ type SubmitHandler<TSchema extends FormSchema> = (output: v.InferOutput<TSchema>
|
|
|
337
511
|
*/
|
|
338
512
|
type SubmitEventHandler<TSchema extends FormSchema> = (output: v.InferOutput<TSchema>, event: SubmitEvent) => MaybePromise<unknown>;
|
|
339
513
|
//#endregion
|
|
340
|
-
//#region src/types/path/path.d.ts
|
|
341
|
-
/**
|
|
342
|
-
* Path key type.
|
|
343
|
-
*/
|
|
344
|
-
type PathKey = string | number;
|
|
345
|
-
/**
|
|
346
|
-
* Path type.
|
|
347
|
-
*/
|
|
348
|
-
type Path = readonly PathKey[];
|
|
349
|
-
/**
|
|
350
|
-
* Required path type.
|
|
351
|
-
*/
|
|
352
|
-
type RequiredPath = readonly [PathKey, ...Path];
|
|
353
|
-
/**
|
|
354
|
-
* Extracts the exact keys of a tuple, array or object. Tuples return their
|
|
355
|
-
* literal numeric indices, dynamic arrays return `number`, objects return
|
|
356
|
-
* their `keyof` keys, and any other input returns `never`.
|
|
357
|
-
*/
|
|
358
|
-
type ExactKeysOf<TValue> = IsAny<TValue> extends true ? never : TValue extends readonly unknown[] ? number extends TValue["length"] ? number : { [TKey in keyof TValue]: TKey extends `${infer TIndex extends number}` ? TIndex : never }[number] : TValue extends Record<PropertyKey, unknown> ? keyof TValue & PathKey : never;
|
|
359
|
-
/**
|
|
360
|
-
* Returns the flat object of all indexable properties of `TValue`. For object
|
|
361
|
-
* unions, properties from every member are merged so that any single property
|
|
362
|
-
* is accessible. For primitives and other non-indexable types, the result is
|
|
363
|
-
* `{}`.
|
|
364
|
-
*
|
|
365
|
-
* Hint: This is necessary to make properties accessible across union members.
|
|
366
|
-
* By default, properties that do not exist in all union options are not
|
|
367
|
-
* accessible and result in "any" when accessed.
|
|
368
|
-
*/
|
|
369
|
-
type PropertiesOf<TValue> = { [TKey in ExactKeysOf<TValue>]: TValue extends Record<TKey, infer TItem> ? TItem : never };
|
|
370
|
-
/**
|
|
371
|
-
* Lazily evaluates only the first valid path segment based on the given value.
|
|
372
|
-
*/
|
|
373
|
-
type LazyPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValidPath : TPathToCheck extends readonly [infer TFirstKey extends ExactKeysOf<TValue>, ...infer TPathRest extends Path] ? LazyPath<Required<PropertiesOf<TValue>[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever<ExactKeysOf<TValue>> extends false ? readonly [...TValidPath, ExactKeysOf<TValue>] : TValidPath;
|
|
374
|
-
/**
|
|
375
|
-
* Returns the path if valid, otherwise the first possible valid path based on
|
|
376
|
-
* the given value.
|
|
377
|
-
*/
|
|
378
|
-
type ValidPath<TValue, TPath extends RequiredPath> = TPath extends LazyPath<Required<TValue>, TPath> ? TPath : LazyPath<Required<TValue>, TPath>;
|
|
379
|
-
/**
|
|
380
|
-
* Detects whether the consuming project is configured with
|
|
381
|
-
* `exactOptionalPropertyTypes: true`.
|
|
382
|
-
*
|
|
383
|
-
* Hint: If `false` the built-in `Required<T>` strips `| undefined` from
|
|
384
|
-
* optional properties, so `Required<{ key?: undefined }>['key']` collapses
|
|
385
|
-
* to `never` — under strict mode the same expression yields `undefined`.
|
|
386
|
-
*/
|
|
387
|
-
type IsExactOptionalProps = Required<{
|
|
388
|
-
key?: undefined;
|
|
389
|
-
}>["key"] extends never ? false : true;
|
|
390
|
-
/**
|
|
391
|
-
* Like the built-in `Required<T>`, but preserves `| undefined` in two
|
|
392
|
-
* places where `Required<T>` strips it:
|
|
393
|
-
*
|
|
394
|
-
* 1. Optional property values under `exactOptionalPropertyTypes: false`
|
|
395
|
-
* — without this, input typings for `v.optional`/`v.nullish` schemas
|
|
396
|
-
* narrow incorrectly (issue #15).
|
|
397
|
-
* 2. Array/tuple element types — e.g. `(string | undefined)[]` stays
|
|
398
|
-
* `(string | undefined)[]` instead of becoming `string[]`. Arrays
|
|
399
|
-
* fall through unchanged because they only have a numeric index
|
|
400
|
-
* signature and don't structurally extend `Record<PropertyKey,
|
|
401
|
-
* unknown>` (which requires string keys).
|
|
402
|
-
*/
|
|
403
|
-
type ExactRequired<TValue> = TValue extends Record<PropertyKey, unknown> ? IsExactOptionalProps extends true ? Required<TValue> : { [TKey in keyof Required<TValue>]: TValue[TKey] } : TValue;
|
|
404
|
-
/**
|
|
405
|
-
* Extracts the value type at the given path.
|
|
406
|
-
*/
|
|
407
|
-
type PathValue<TValue, TPath extends Path> = TPath extends readonly [infer TKey, ...infer TRest extends Path] ? TKey extends ExactKeysOf<ExactRequired<TValue>> ? PathValue<PropertiesOf<ExactRequired<TValue>>[TKey], TRest> : unknown : TValue;
|
|
408
|
-
/**
|
|
409
|
-
* Checks whether a value is a dynamic array or contains one anywhere in its
|
|
410
|
-
* shape. A fixed-length tuple is not itself a dynamic array, but it counts when
|
|
411
|
-
* it contains one, so paths can still navigate through tuples to reach nested
|
|
412
|
-
* arrays.
|
|
413
|
-
*
|
|
414
|
-
* Hint: The inner conditionals (`TValue extends readonly unknown[]` and
|
|
415
|
-
* `TValue extends Record<PropertyKey, unknown>`) distribute over union members,
|
|
416
|
-
* so the inner expression returns the union of each member's result (e.g.
|
|
417
|
-
* `true | false` when some members contain arrays and others don't).
|
|
418
|
-
* Downstream code uses `IsOrHasArray<T> extends true`, but
|
|
419
|
-
* `boolean extends true` is `false` — so we collapse the result via
|
|
420
|
-
* `true extends ...`, which is `true` whenever at least one union member
|
|
421
|
-
* contributed `true`.
|
|
422
|
-
*/
|
|
423
|
-
type IsOrHasArray<TValue> = true extends (IsAny<TValue> extends true ? false : TValue extends readonly unknown[] ? number extends TValue["length"] ? true : IsOrHasArray<TValue[number]> : TValue extends Record<PropertyKey, unknown> ? { [TKey in keyof TValue]: IsOrHasArray<TValue[TKey]> }[keyof TValue] : false) ? true : false;
|
|
424
|
-
/**
|
|
425
|
-
* Extracts the exact keys of a tuple, array or object that contain arrays.
|
|
426
|
-
*/
|
|
427
|
-
type ExactKeysOfArrayPath<TValue> = IsAny<TValue> extends true ? never : TValue extends readonly (infer TItem)[] ? number extends TValue["length"] ? IsOrHasArray<TItem> extends true ? number : never : { [TKey in keyof TValue]: TKey extends `${infer TIndex extends number}` ? IsOrHasArray<NonNullable<TValue[TKey]>> extends true ? TIndex : never : never }[number] : TValue extends Record<PropertyKey, unknown> ? { [TKey in keyof TValue]: IsOrHasArray<NonNullable<TValue[TKey]>> extends true ? TKey : never }[keyof TValue] & PathKey : never;
|
|
428
|
-
/**
|
|
429
|
-
* Returns the flat object of indexable properties of `TValue` whose values
|
|
430
|
-
* are or contain arrays. Mirrors `PropertiesOf` but keyed by
|
|
431
|
-
* `ExactKeysOfArrayPath` so the lookup is provably valid for array-path
|
|
432
|
-
* navigation in `LazyArrayPath`.
|
|
433
|
-
*/
|
|
434
|
-
type PropertiesOfArrayPath<TValue> = { [TKey in ExactKeysOfArrayPath<TValue>]: TValue extends Record<TKey, infer TItem> ? TItem : never };
|
|
435
|
-
/**
|
|
436
|
-
* Lazily evaluates only the first valid array path segment based on the given value.
|
|
437
|
-
*/
|
|
438
|
-
type LazyArrayPath<TValue, TPathToCheck extends Path, TValidPath extends Path = readonly []> = TPathToCheck extends readonly [] ? TValue extends readonly unknown[] ? number extends TValue["length"] ? TValidPath : IsNever<ExactKeysOfArrayPath<TValue>> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : never : readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : TPathToCheck extends readonly [infer TFirstKey extends ExactKeysOfArrayPath<TValue>, ...infer TPathRest extends Path] ? LazyArrayPath<Required<PropertiesOfArrayPath<TValue>[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever<ExactKeysOfArrayPath<TValue>> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath<TValue>] : never;
|
|
439
|
-
/**
|
|
440
|
-
* Returns the path if valid, otherwise the first possible valid array path
|
|
441
|
-
* based on the given value.
|
|
442
|
-
*/
|
|
443
|
-
type ValidArrayPath<TValue, TPath extends RequiredPath> = TPath extends LazyArrayPath<Required<TValue>, TPath> ? TPath : LazyArrayPath<Required<TValue>, TPath>;
|
|
444
|
-
/**
|
|
445
|
-
* Recursive helper for `DirtyPath` that prepends `TKey` to each deeper path,
|
|
446
|
-
* or falls through to `never` when the child is not an object.
|
|
447
|
-
*/
|
|
448
|
-
type DeepDirtyPath<TChild, TKey$1 extends PathKey, TDepth extends 0[]> = TChild extends Record<PropertyKey, unknown> ? readonly [TKey$1, ...DirtyPath<TChild, [...TDepth, 0]>] : never;
|
|
449
|
-
/**
|
|
450
|
-
* Returns the union of all `RequiredPath`s that `getDirtyPaths` can emit
|
|
451
|
-
* for a given input type. Object fields contribute their own path and the
|
|
452
|
-
* paths of their descendants; arrays and tuples are atomic and contribute
|
|
453
|
-
* only their own path, because dirty arrays are returned as complete units.
|
|
454
|
-
*
|
|
455
|
-
* Narrowing is exact for the first 5 levels of nesting; deeper paths fall
|
|
456
|
-
* back to `RequiredPath` to keep the result a complete superset of any
|
|
457
|
-
* path the runtime can address.
|
|
458
|
-
*
|
|
459
|
-
* Hint: Arrays and tuples are atomic because they don't structurally
|
|
460
|
-
* extend `Record<PropertyKey, unknown>` and so fall through to `never`
|
|
461
|
-
* via `DeepDirtyPath` — no explicit array check is needed. `TDepth` is
|
|
462
|
-
* a tuple-length counter capped at 5 to bound TypeScript instantiation
|
|
463
|
-
* cost.
|
|
464
|
-
*/
|
|
465
|
-
type DirtyPath<TValue, TDepth extends 0[] = []> = TDepth["length"] extends 5 ? RequiredPath : TValue extends Record<PropertyKey, unknown> ? { [TKey in ExactKeysOf<TValue>]: readonly [TKey] | DeepDirtyPath<NonNullable<PropertiesOf<TValue>[TKey]>, TKey, TDepth> }[ExactKeysOf<TValue>] : never;
|
|
466
|
-
//#endregion
|
|
467
514
|
//#region src/array/copyItemState/copyItemState.d.ts
|
|
468
515
|
/**
|
|
469
516
|
* Copies the deeply nested state (signal values) from one field store to
|
|
470
517
|
* another. This includes the `elements`, `errors`, `startInput`, `input`,
|
|
471
|
-
* `isTouched`, `isDirty`, and for arrays `startItems` and `items`
|
|
472
|
-
* Recursively walks through the field stores and copies all signal
|
|
518
|
+
* `isTouched`, `isEdited`, `isDirty`, and for arrays `startItems` and `items`
|
|
519
|
+
* properties. Recursively walks through the field stores and copies all signal
|
|
520
|
+
* values.
|
|
473
521
|
*
|
|
474
522
|
* @param fromInternalFieldStore The source field store to copy from.
|
|
475
523
|
* @param toInternalFieldStore The destination field store to copy to.
|
|
@@ -479,10 +527,10 @@ declare function copyItemState(fromInternalFieldStore: InternalFieldStore, toInt
|
|
|
479
527
|
//#region src/array/resetItemState/resetItemState.d.ts
|
|
480
528
|
/**
|
|
481
529
|
* Resets the state of a field store (signal values) deeply nested. Sets
|
|
482
|
-
* `elements` to empty array, `errors` to `null`, `isTouched
|
|
483
|
-
* `false`, and `startInput`, `input`, `startItems`, and `items` to
|
|
484
|
-
* input value. Keeps the `initialInput` and `initialItems` state
|
|
485
|
-
* form reset functionality.
|
|
530
|
+
* `elements` to empty array, `errors` to `null`, `isTouched`, `isEdited` and
|
|
531
|
+
* `isDirty` to `false`, and `startInput`, `input`, `startItems`, and `items` to
|
|
532
|
+
* the new input value. Keeps the `initialInput` and `initialItems` state
|
|
533
|
+
* unchanged for form reset functionality.
|
|
486
534
|
*
|
|
487
535
|
* @param internalFieldStore The field store to reset.
|
|
488
536
|
* @param input The new input value (can be any type including array or object).
|
|
@@ -496,8 +544,8 @@ declare function resetItemState(internalFieldStore: InternalFieldStore, input: u
|
|
|
496
544
|
/**
|
|
497
545
|
* Swaps the deeply nested state (signal values) between two field stores. This
|
|
498
546
|
* includes the `elements`, `errors`, `startInput`, `input`, `isTouched`,
|
|
499
|
-
* `isDirty`, and for arrays `startItems` and `items` properties.
|
|
500
|
-
* walks through the field stores and swaps all signal values.
|
|
547
|
+
* `isEdited`, `isDirty`, and for arrays `startItems` and `items` properties.
|
|
548
|
+
* Recursively walks through the field stores and swaps all signal values.
|
|
501
549
|
*
|
|
502
550
|
* @param firstInternalFieldStore The first field store to swap.
|
|
503
551
|
* @param secondInternalFieldStore The second field store to swap.
|
|
@@ -558,7 +606,7 @@ declare function getElementInput(element: FieldElement, internalFieldStore: Inte
|
|
|
558
606
|
*
|
|
559
607
|
* @returns Whether the property is true.
|
|
560
608
|
*/
|
|
561
|
-
declare function getFieldBool(internalFieldStore: InternalFieldStore, type: "errors" | "isTouched" | "isDirty"): boolean;
|
|
609
|
+
declare function getFieldBool(internalFieldStore: InternalFieldStore, type: "errors" | "isTouched" | "isEdited" | "isDirty"): boolean;
|
|
562
610
|
//#endregion
|
|
563
611
|
//#region src/field/getFieldInput/getFieldInput.d.ts
|
|
564
612
|
/**
|
|
@@ -597,7 +645,7 @@ type FieldSchema = v.ArraySchema<v.BaseSchema<unknown, unknown, v.BaseIssue<unkn
|
|
|
597
645
|
* @param path The path to the field in the form.
|
|
598
646
|
* @param nullish Whether the schema is wrapped in a nullish schema.
|
|
599
647
|
*/
|
|
600
|
-
declare function initializeFieldStore(internalFieldStore: Partial<InternalFieldStore>, schema: FieldSchema, initialInput: unknown, path:
|
|
648
|
+
declare function initializeFieldStore(internalFieldStore: Partial<InternalFieldStore>, schema: FieldSchema, initialInput: unknown, path: Path, nullish?: boolean): void;
|
|
601
649
|
//#endregion
|
|
602
650
|
//#region src/field/setFieldBool/setFieldBool.d.ts
|
|
603
651
|
/**
|
|
@@ -635,12 +683,19 @@ declare function setInitialFieldInput(internalFieldStore: InternalFieldStore, in
|
|
|
635
683
|
//#region src/field/walkFieldStore/walkFieldStore.d.ts
|
|
636
684
|
/**
|
|
637
685
|
* Walks through the field store and all nested children, calling the callback
|
|
638
|
-
* for each field store in depth-first order.
|
|
686
|
+
* for each field store in depth-first order. The callback may return `true` to
|
|
687
|
+
* stop the walk early, in which case `walkFieldStore` returns `true` as well.
|
|
688
|
+
*
|
|
689
|
+
* The walk reads array `items` reactively, so a reactive caller subscribes to
|
|
690
|
+
* structural changes naturally. Imperative callers that must not subscribe
|
|
691
|
+
* (e.g. when invoked inside an effect) should wrap the call in `untrack`.
|
|
639
692
|
*
|
|
640
693
|
* @param internalFieldStore The field store to walk.
|
|
641
|
-
* @param callback The callback to invoke for each field store.
|
|
694
|
+
* @param callback The callback to invoke for each field store. Return `true` to stop the walk early.
|
|
695
|
+
*
|
|
696
|
+
* @returns Whether the walk was stopped early by the callback.
|
|
642
697
|
*/
|
|
643
|
-
declare function walkFieldStore(internalFieldStore: InternalFieldStore, callback: (internalFieldStore: InternalFieldStore) => void):
|
|
698
|
+
declare function walkFieldStore(internalFieldStore: InternalFieldStore, callback: (internalFieldStore: InternalFieldStore) => boolean | void): boolean;
|
|
644
699
|
//#endregion
|
|
645
700
|
//#region src/form/createFormStore/createFormStore.d.ts
|
|
646
701
|
/**
|
|
@@ -741,4 +796,4 @@ declare function createSignal<T>(initialValue: T): Signal<T>;
|
|
|
741
796
|
*/
|
|
742
797
|
declare function batch<T>(fn: () => T): T;
|
|
743
798
|
//#endregion
|
|
744
|
-
export { BaseFormStore, Batch, DeepPartial, DirtyPath, FieldElement, FieldSchema, FormConfig, FormSchema, INTERNAL, InternalArrayStore, InternalBaseStore, InternalFieldStore, InternalFormStore, InternalObjectStore, InternalValueStore, IsAny, IsNever, MaybePromise, PartialValues, Path, PathKey, PathValue, RequiredPath, Schema, Signal, SubmitEventHandler, SubmitHandler, Untrack, ValidArrayPath, ValidPath, ValidateFormInputConfig, ValidationMode, batch, copyItemState, createFormStore, createId, createSignal, decodeFormData, focusFieldElement, framework, getDirtyFieldInput, getElementInput, getFieldBool, getFieldInput, getFieldStore, initializeFieldStore, resetItemState, setFieldBool, setFieldInput, setInitialFieldInput, swapItemState, untrack, validateFormInput, validateIfRequired, walkFieldStore };
|
|
799
|
+
export { BaseFormStore, Batch, DeepPartial, DirtyPath, FieldElement, FieldPath, FieldSchema, FormConfig, FormSchema, INTERNAL, InternalArrayStore, InternalBaseStore, InternalFieldStore, InternalFormStore, InternalObjectStore, InternalValueStore, IsAny, IsNever, MaybePromise, PartialValues, Path, PathKey, PathValue, RequiredPath, Schema, Signal, SubmitEventHandler, SubmitHandler, Untrack, ValidArrayPath, ValidPath, ValidateFormInputConfig, ValidationMode, batch, copyItemState, createFormStore, createId, createSignal, decodeFormData, focusFieldElement, framework, getDirtyFieldInput, getElementInput, getFieldBool, getFieldInput, getFieldStore, initializeFieldStore, resetItemState, setFieldBool, setFieldInput, setInitialFieldInput, swapItemState, untrack, validateFormInput, validateIfRequired, walkFieldStore };
|