@lucas-barake/effect-form 0.14.0 → 0.16.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/dist/cjs/Field.js.map +1 -1
- package/dist/cjs/FormAtoms.js +8 -1
- package/dist/cjs/FormAtoms.js.map +1 -1
- package/dist/cjs/FormBuilder.js.map +1 -1
- package/dist/cjs/Mode.js.map +1 -1
- package/dist/cjs/Path.js.map +1 -1
- package/dist/cjs/Validation.js.map +1 -1
- package/dist/cjs/internal/dirty.js.map +1 -1
- package/dist/cjs/internal/weak-registry.js.map +1 -1
- package/dist/dts/Field.d.ts.map +1 -1
- package/dist/dts/FormAtoms.d.ts +2 -0
- package/dist/dts/FormAtoms.d.ts.map +1 -1
- package/dist/dts/FormBuilder.d.ts.map +1 -1
- package/dist/dts/Mode.d.ts.map +1 -1
- package/dist/dts/Path.d.ts.map +1 -1
- package/dist/dts/Validation.d.ts.map +1 -1
- package/dist/dts/internal/dirty.d.ts.map +1 -1
- package/dist/dts/internal/weak-registry.d.ts.map +1 -1
- package/dist/esm/FormAtoms.js +9 -2
- package/dist/esm/FormAtoms.js.map +1 -1
- package/package.json +1 -1
- package/src/Field.ts +40 -40
- package/src/FormAtoms.ts +281 -265
- package/src/FormBuilder.ts +70 -70
- package/src/Mode.ts +14 -14
- package/src/Path.ts +37 -37
- package/src/Validation.ts +54 -54
- package/src/internal/dirty.ts +40 -40
- package/src/internal/weak-registry.ts +17 -17
package/src/internal/dirty.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as Equal from "effect/Equal"
|
|
2
|
-
import * as Utils from "effect/Utils"
|
|
3
|
-
import { getNestedValue, isPathUnderRoot } from "../Path.js"
|
|
1
|
+
import * as Equal from "effect/Equal";
|
|
2
|
+
import * as Utils from "effect/Utils";
|
|
3
|
+
import { getNestedValue, isPathUnderRoot } from "../Path.js";
|
|
4
4
|
|
|
5
5
|
export const recalculateDirtyFieldsForArray = (
|
|
6
6
|
dirtyFields: ReadonlySet<string>,
|
|
@@ -8,38 +8,38 @@ export const recalculateDirtyFieldsForArray = (
|
|
|
8
8
|
arrayPath: string,
|
|
9
9
|
newItems: ReadonlyArray<unknown>,
|
|
10
10
|
): ReadonlySet<string> => {
|
|
11
|
-
const initialItems = (getNestedValue(initialValues, arrayPath) ?? []) as ReadonlyArray<unknown
|
|
11
|
+
const initialItems = (getNestedValue(initialValues, arrayPath) ?? []) as ReadonlyArray<unknown>;
|
|
12
12
|
|
|
13
13
|
if (newItems === initialItems) {
|
|
14
|
-
return dirtyFields
|
|
14
|
+
return dirtyFields;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const nextDirty = new Set(
|
|
18
18
|
Array.from(dirtyFields).filter((path) => !isPathUnderRoot(path, arrayPath)),
|
|
19
|
-
)
|
|
19
|
+
);
|
|
20
20
|
|
|
21
|
-
const loopLength = Math.max(newItems.length, initialItems.length)
|
|
21
|
+
const loopLength = Math.max(newItems.length, initialItems.length);
|
|
22
22
|
for (let i = 0; i < loopLength; i++) {
|
|
23
|
-
const itemPath = `${arrayPath}[${i}]
|
|
24
|
-
const newItem = newItems[i]
|
|
25
|
-
const initialItem = initialItems[i]
|
|
23
|
+
const itemPath = `${arrayPath}[${i}]`;
|
|
24
|
+
const newItem = newItems[i];
|
|
25
|
+
const initialItem = initialItems[i];
|
|
26
26
|
|
|
27
|
-
if (newItem === initialItem) continue
|
|
27
|
+
if (newItem === initialItem) continue;
|
|
28
28
|
|
|
29
|
-
const isEqual = Utils.structuralRegion(() => Equal.equals(newItem, initialItem))
|
|
29
|
+
const isEqual = Utils.structuralRegion(() => Equal.equals(newItem, initialItem));
|
|
30
30
|
if (!isEqual) {
|
|
31
|
-
nextDirty.add(itemPath)
|
|
31
|
+
nextDirty.add(itemPath);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
if (newItems.length !== initialItems.length) {
|
|
36
|
-
nextDirty.add(arrayPath)
|
|
36
|
+
nextDirty.add(arrayPath);
|
|
37
37
|
} else {
|
|
38
|
-
nextDirty.delete(arrayPath)
|
|
38
|
+
nextDirty.delete(arrayPath);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
return nextDirty
|
|
42
|
-
}
|
|
41
|
+
return nextDirty;
|
|
42
|
+
};
|
|
43
43
|
|
|
44
44
|
export const recalculateDirtySubtree = (
|
|
45
45
|
currentDirty: ReadonlySet<string>,
|
|
@@ -47,61 +47,61 @@ export const recalculateDirtySubtree = (
|
|
|
47
47
|
allValues: unknown,
|
|
48
48
|
rootPath: string = "",
|
|
49
49
|
): ReadonlySet<string> => {
|
|
50
|
-
const targetValue = rootPath ? getNestedValue(allValues, rootPath) : allValues
|
|
51
|
-
const targetInitial = rootPath ? getNestedValue(allInitial, rootPath) : allInitial
|
|
50
|
+
const targetValue = rootPath ? getNestedValue(allValues, rootPath) : allValues;
|
|
51
|
+
const targetInitial = rootPath ? getNestedValue(allInitial, rootPath) : allInitial;
|
|
52
52
|
|
|
53
53
|
if (targetValue === targetInitial) {
|
|
54
54
|
if (rootPath === "") {
|
|
55
|
-
return new Set()
|
|
55
|
+
return new Set();
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
let changed = false
|
|
59
|
-
const nextDirty = new Set(currentDirty)
|
|
58
|
+
let changed = false;
|
|
59
|
+
const nextDirty = new Set(currentDirty);
|
|
60
60
|
for (const path of currentDirty) {
|
|
61
61
|
if (isPathUnderRoot(path, rootPath)) {
|
|
62
|
-
nextDirty.delete(path)
|
|
63
|
-
changed = true
|
|
62
|
+
nextDirty.delete(path);
|
|
63
|
+
changed = true;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
return changed ? nextDirty : currentDirty
|
|
66
|
+
return changed ? nextDirty : currentDirty;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
const nextDirty = new Set(currentDirty)
|
|
69
|
+
const nextDirty = new Set(currentDirty);
|
|
70
70
|
|
|
71
71
|
if (rootPath === "") {
|
|
72
|
-
nextDirty.clear()
|
|
72
|
+
nextDirty.clear();
|
|
73
73
|
} else {
|
|
74
74
|
for (const path of nextDirty) {
|
|
75
75
|
if (isPathUnderRoot(path, rootPath)) {
|
|
76
|
-
nextDirty.delete(path)
|
|
76
|
+
nextDirty.delete(path);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const recurse = (current: unknown, initial: unknown, path: string): void => {
|
|
82
|
-
if (current === initial) return
|
|
82
|
+
if (current === initial) return;
|
|
83
83
|
|
|
84
84
|
if (Array.isArray(current)) {
|
|
85
|
-
const initialArr = (initial ?? []) as ReadonlyArray<unknown
|
|
85
|
+
const initialArr = (initial ?? []) as ReadonlyArray<unknown>;
|
|
86
86
|
for (let i = 0; i < Math.max(current.length, initialArr.length); i++) {
|
|
87
|
-
recurse(current[i], initialArr[i], path ? `${path}[${i}]` : `[${i}]`)
|
|
87
|
+
recurse(current[i], initialArr[i], path ? `${path}[${i}]` : `[${i}]`);
|
|
88
88
|
}
|
|
89
89
|
} else if (current !== null && typeof current === "object") {
|
|
90
|
-
const initialObj = (initial ?? {}) as Record<string, unknown
|
|
90
|
+
const initialObj = (initial ?? {}) as Record<string, unknown>;
|
|
91
91
|
for (const key in current as object) {
|
|
92
|
-
recurse((current as Record<string, unknown>)[key], initialObj[key], path ? `${path}.${key}` : key)
|
|
92
|
+
recurse((current as Record<string, unknown>)[key], initialObj[key], path ? `${path}.${key}` : key);
|
|
93
93
|
}
|
|
94
94
|
for (const key in initialObj) {
|
|
95
95
|
if (!(key in (current as object))) {
|
|
96
|
-
recurse(undefined, initialObj[key], path ? `${path}.${key}` : key)
|
|
96
|
+
recurse(undefined, initialObj[key], path ? `${path}.${key}` : key);
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
} else {
|
|
100
|
-
const isEqual = Utils.structuralRegion(() => Equal.equals(current, initial))
|
|
101
|
-
if (!isEqual && path) nextDirty.add(path)
|
|
100
|
+
const isEqual = Utils.structuralRegion(() => Equal.equals(current, initial));
|
|
101
|
+
if (!isEqual && path) nextDirty.add(path);
|
|
102
102
|
}
|
|
103
|
-
}
|
|
103
|
+
};
|
|
104
104
|
|
|
105
|
-
recurse(targetValue, targetInitial, rootPath)
|
|
106
|
-
return nextDirty
|
|
107
|
-
}
|
|
105
|
+
recurse(targetValue, targetInitial, rootPath);
|
|
106
|
+
return nextDirty;
|
|
107
|
+
};
|
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
export interface WeakRegistry<V extends object> {
|
|
2
|
-
readonly get: (key: string) => V | undefined
|
|
3
|
-
readonly set: (key: string, value: V) => void
|
|
4
|
-
readonly delete: (key: string) => boolean
|
|
5
|
-
readonly clear: () => void
|
|
6
|
-
readonly values: () => IterableIterator<V
|
|
2
|
+
readonly get: (key: string) => V | undefined;
|
|
3
|
+
readonly set: (key: string, value: V) => void;
|
|
4
|
+
readonly delete: (key: string) => boolean;
|
|
5
|
+
readonly clear: () => void;
|
|
6
|
+
readonly values: () => IterableIterator<V>;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export const createWeakRegistry = <V extends object>(): WeakRegistry<V> => {
|
|
10
10
|
if (typeof WeakRef === "undefined" || typeof FinalizationRegistry === "undefined") {
|
|
11
|
-
const map = new Map<string, V>()
|
|
11
|
+
const map = new Map<string, V>();
|
|
12
12
|
return {
|
|
13
13
|
get: (key) => map.get(key),
|
|
14
14
|
set: (key, value) => {
|
|
15
|
-
map.set(key, value)
|
|
15
|
+
map.set(key, value);
|
|
16
16
|
},
|
|
17
17
|
delete: (key) => map.delete(key),
|
|
18
18
|
clear: () => map.clear(),
|
|
19
19
|
values: () => map.values(),
|
|
20
|
-
}
|
|
20
|
+
};
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const map = new Map<string, WeakRef<V>>()
|
|
23
|
+
const map = new Map<string, WeakRef<V>>();
|
|
24
24
|
const registry = new FinalizationRegistry<string>((key) => {
|
|
25
|
-
map.delete(key)
|
|
26
|
-
})
|
|
25
|
+
map.delete(key);
|
|
26
|
+
});
|
|
27
27
|
|
|
28
28
|
return {
|
|
29
29
|
get: (key) => map.get(key)?.deref(),
|
|
30
30
|
set: (key, value) => {
|
|
31
|
-
map.set(key, new WeakRef(value))
|
|
32
|
-
registry.register(value, key)
|
|
31
|
+
map.set(key, new WeakRef(value));
|
|
32
|
+
registry.register(value, key);
|
|
33
33
|
},
|
|
34
34
|
delete: (key) => map.delete(key),
|
|
35
35
|
clear: () => map.clear(),
|
|
36
36
|
*values() {
|
|
37
37
|
for (const ref of map.values()) {
|
|
38
|
-
const value = ref.deref()
|
|
39
|
-
if (value !== undefined) yield value
|
|
38
|
+
const value = ref.deref();
|
|
39
|
+
if (value !== undefined) yield value;
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
|
-
}
|
|
43
|
-
}
|
|
42
|
+
};
|
|
43
|
+
};
|