@lucas-barake/effect-form 0.19.0 → 0.20.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/{dts/Field.d.ts → Field.d.ts} +1 -0
- package/dist/Field.d.ts.map +1 -0
- package/dist/{esm/Field.js → Field.js} +29 -0
- package/dist/Field.js.map +1 -0
- package/dist/FieldState.d.ts +20 -0
- package/dist/FieldState.d.ts.map +1 -0
- package/dist/FieldState.js +2 -0
- package/dist/FieldState.js.map +1 -0
- package/dist/{dts/FormAtoms.d.ts → FormAtoms.d.ts} +24 -9
- package/dist/FormAtoms.d.ts.map +1 -0
- package/dist/{esm/FormAtoms.js → FormAtoms.js} +221 -15
- package/dist/FormAtoms.js.map +1 -0
- package/dist/{dts/FormBuilder.d.ts → FormBuilder.d.ts} +1 -1
- package/dist/FormBuilder.d.ts.map +1 -0
- package/dist/FormBuilder.js.map +1 -0
- package/dist/Mode.d.ts +34 -0
- package/dist/Mode.d.ts.map +1 -0
- package/dist/Mode.js +26 -0
- package/dist/Mode.js.map +1 -0
- package/dist/Path.d.ts.map +1 -0
- package/dist/Path.js.map +1 -0
- package/dist/Validation.d.ts.map +1 -0
- package/dist/{esm/Validation.js → Validation.js} +69 -36
- package/dist/Validation.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/dirty.d.ts.map +1 -0
- package/dist/internal/dirty.js.map +1 -0
- package/dist/internal/weak-registry.d.ts.map +1 -0
- package/dist/internal/weak-registry.js.map +1 -0
- package/package.json +33 -66
- package/src/Field.ts +82 -50
- package/src/FieldState.ts +22 -0
- package/src/FormAtoms.ts +544 -268
- package/src/FormBuilder.ts +102 -102
- package/src/Mode.ts +23 -23
- package/src/Path.ts +38 -38
- package/src/Validation.ts +108 -72
- package/src/index.ts +7 -28
- package/src/internal/dirty.ts +43 -43
- package/src/internal/weak-registry.ts +21 -21
- package/Field/package.json +0 -6
- package/FormAtoms/package.json +0 -6
- package/FormBuilder/package.json +0 -6
- package/Mode/package.json +0 -6
- package/Path/package.json +0 -6
- package/Validation/package.json +0 -6
- package/dist/cjs/Field.js +0 -94
- package/dist/cjs/Field.js.map +0 -1
- package/dist/cjs/FormAtoms.js +0 -362
- package/dist/cjs/FormAtoms.js.map +0 -1
- package/dist/cjs/FormBuilder.js +0 -107
- package/dist/cjs/FormBuilder.js.map +0 -1
- package/dist/cjs/Mode.js +0 -52
- package/dist/cjs/Mode.js.map +0 -1
- package/dist/cjs/Path.js +0 -71
- package/dist/cjs/Path.js.map +0 -1
- package/dist/cjs/Validation.js +0 -140
- package/dist/cjs/Validation.js.map +0 -1
- package/dist/cjs/index.js +0 -39
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/internal/dirty.js +0 -108
- package/dist/cjs/internal/dirty.js.map +0 -1
- package/dist/cjs/internal/weak-registry.js +0 -41
- package/dist/cjs/internal/weak-registry.js.map +0 -1
- package/dist/dts/Field.d.ts.map +0 -1
- package/dist/dts/FormAtoms.d.ts.map +0 -1
- package/dist/dts/FormBuilder.d.ts.map +0 -1
- package/dist/dts/Mode.d.ts +0 -29
- package/dist/dts/Mode.d.ts.map +0 -1
- package/dist/dts/Path.d.ts.map +0 -1
- package/dist/dts/Validation.d.ts.map +0 -1
- package/dist/dts/index.d.ts +0 -25
- package/dist/dts/index.d.ts.map +0 -1
- package/dist/dts/internal/dirty.d.ts.map +0 -1
- package/dist/dts/internal/weak-registry.d.ts.map +0 -1
- package/dist/esm/Field.js.map +0 -1
- package/dist/esm/FormAtoms.js.map +0 -1
- package/dist/esm/FormBuilder.js.map +0 -1
- package/dist/esm/Mode.js +0 -25
- package/dist/esm/Mode.js.map +0 -1
- package/dist/esm/Path.js.map +0 -1
- package/dist/esm/Validation.js.map +0 -1
- package/dist/esm/index.js +0 -25
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/internal/dirty.js.map +0 -1
- package/dist/esm/internal/weak-registry.js.map +0 -1
- package/dist/esm/package.json +0 -4
- /package/dist/{esm/FormBuilder.js → FormBuilder.js} +0 -0
- /package/dist/{dts/Path.d.ts → Path.d.ts} +0 -0
- /package/dist/{esm/Path.js → Path.js} +0 -0
- /package/dist/{dts/Validation.d.ts → Validation.d.ts} +0 -0
- /package/dist/{dts/internal → internal}/dirty.d.ts +0 -0
- /package/dist/{esm/internal → internal}/dirty.js +0 -0
- /package/dist/{dts/internal → internal}/weak-registry.d.ts +0 -0
- /package/dist/{esm/internal → internal}/weak-registry.js +0 -0
package/src/Validation.ts
CHANGED
|
@@ -1,96 +1,75 @@
|
|
|
1
|
-
import * as Option from "effect/Option"
|
|
2
|
-
import * as ParseResult from "effect/ParseResult"
|
|
3
|
-
import type * as AST from "effect/SchemaAST"
|
|
4
|
-
import { schemaPathToFieldPath } from "./Path.
|
|
1
|
+
import * as Option from "effect/Option"
|
|
2
|
+
import * as ParseResult from "effect/ParseResult"
|
|
3
|
+
import type * as AST from "effect/SchemaAST"
|
|
4
|
+
import { schemaPathToFieldPath } from "./Path.ts"
|
|
5
5
|
|
|
6
|
-
export type ErrorSource = "field" | "refinement"
|
|
6
|
+
export type ErrorSource = "field" | "refinement"
|
|
7
7
|
|
|
8
8
|
export interface ErrorEntry {
|
|
9
|
-
readonly message: string
|
|
10
|
-
readonly source: ErrorSource
|
|
9
|
+
readonly message: string
|
|
10
|
+
readonly source: ErrorSource
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface IssueSourceEntry {
|
|
14
|
+
readonly path: ReadonlyArray<PropertyKey>
|
|
15
|
+
readonly source: ErrorSource
|
|
16
|
+
readonly issue: ParseResult.ParseIssue
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
const getBaseAST = (ast: AST.AST): AST.AST => {
|
|
14
20
|
switch (ast._tag) {
|
|
15
21
|
case "Refinement":
|
|
16
22
|
case "Transformation":
|
|
17
|
-
return getBaseAST(ast.from)
|
|
23
|
+
return getBaseAST(ast.from)
|
|
18
24
|
default:
|
|
19
|
-
return ast
|
|
25
|
+
return ast
|
|
20
26
|
}
|
|
21
|
-
}
|
|
27
|
+
}
|
|
22
28
|
|
|
23
29
|
const isCompositeType = (ast: AST.AST): boolean => {
|
|
24
|
-
const base = getBaseAST(ast)
|
|
30
|
+
const base = getBaseAST(ast)
|
|
25
31
|
switch (base._tag) {
|
|
26
32
|
case "TypeLiteral": // Schema.Struct
|
|
27
33
|
case "TupleType": // Schema.Tuple
|
|
28
34
|
case "Declaration": // Schema.Class, Schema.TaggedClass
|
|
29
35
|
case "Union": // Schema.Union
|
|
30
36
|
case "Suspend": // Recursive schemas
|
|
31
|
-
return true
|
|
37
|
+
return true
|
|
32
38
|
default:
|
|
33
|
-
return false
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export const extractFirstError = (error: ParseResult.ParseError): Option.Option<string> => {
|
|
38
|
-
const issues = ParseResult.ArrayFormatter.formatErrorSync(error);
|
|
39
|
-
if (issues.length === 0) {
|
|
40
|
-
return Option.none();
|
|
39
|
+
return false
|
|
41
40
|
}
|
|
42
|
-
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const routeErrors = (error: ParseResult.ParseError): Map<string, string> => {
|
|
46
|
-
const result = new Map<string, string>();
|
|
47
|
-
const issues = ParseResult.ArrayFormatter.formatErrorSync(error);
|
|
48
|
-
|
|
49
|
-
for (const issue of issues) {
|
|
50
|
-
const fieldPath = schemaPathToFieldPath(issue.path);
|
|
51
|
-
if (fieldPath && !result.has(fieldPath)) {
|
|
52
|
-
result.set(fieldPath, issue.message);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return result;
|
|
57
|
-
};
|
|
41
|
+
}
|
|
58
42
|
|
|
59
|
-
const
|
|
60
|
-
const
|
|
43
|
+
const collectIssueSources = (error: ParseResult.ParseError): ReadonlyArray<IssueSourceEntry> => {
|
|
44
|
+
const entries: Array<IssueSourceEntry> = []
|
|
61
45
|
|
|
62
46
|
const walk = (issue: ParseResult.ParseIssue, path: ReadonlyArray<PropertyKey>, source: ErrorSource): void => {
|
|
63
47
|
switch (issue._tag) {
|
|
64
48
|
case "Refinement":
|
|
65
49
|
if (issue.kind === "Predicate" && isCompositeType(issue.ast.from) && path.length === 0) {
|
|
66
|
-
walk(issue.issue, path, "refinement")
|
|
50
|
+
walk(issue.issue, path, "refinement")
|
|
67
51
|
} else {
|
|
68
|
-
walk(issue.issue, path, source)
|
|
52
|
+
walk(issue.issue, path, source)
|
|
69
53
|
}
|
|
70
|
-
break
|
|
54
|
+
break
|
|
71
55
|
case "Pointer": {
|
|
72
|
-
const pointerPath = Array.isArray(issue.path) ? issue.path : [issue.path]
|
|
73
|
-
walk(issue.issue, [...path, ...pointerPath], source)
|
|
74
|
-
break
|
|
56
|
+
const pointerPath = Array.isArray(issue.path) ? issue.path : [issue.path]
|
|
57
|
+
walk(issue.issue, [...path, ...pointerPath], source)
|
|
58
|
+
break
|
|
75
59
|
}
|
|
76
60
|
case "Composite": {
|
|
77
|
-
const issues = Array.isArray(issue.issues) ? issue.issues : [issue.issues]
|
|
61
|
+
const issues = Array.isArray(issue.issues) ? issue.issues : [issue.issues]
|
|
78
62
|
for (const sub of issues) {
|
|
79
|
-
walk(sub, path, source)
|
|
63
|
+
walk(sub, path, source)
|
|
80
64
|
}
|
|
81
|
-
break
|
|
65
|
+
break
|
|
82
66
|
}
|
|
83
67
|
case "Type":
|
|
84
68
|
case "Missing":
|
|
85
69
|
case "Unexpected":
|
|
86
|
-
case "Forbidden":
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (!sources.has(key)) {
|
|
90
|
-
sources.set(key, source);
|
|
91
|
-
}
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
70
|
+
case "Forbidden":
|
|
71
|
+
entries.push({ path, source, issue })
|
|
72
|
+
break
|
|
94
73
|
case "Transformation":
|
|
95
74
|
if (
|
|
96
75
|
issue.kind === "Transformation" &&
|
|
@@ -98,31 +77,88 @@ const determineErrorSources = (error: ParseResult.ParseError): Map<string, Error
|
|
|
98
77
|
isCompositeType(issue.ast.from) &&
|
|
99
78
|
path.length === 0
|
|
100
79
|
) {
|
|
101
|
-
walk(issue.issue, path, "refinement")
|
|
80
|
+
walk(issue.issue, path, "refinement")
|
|
102
81
|
} else {
|
|
103
|
-
walk(issue.issue, path, source)
|
|
82
|
+
walk(issue.issue, path, source)
|
|
104
83
|
}
|
|
105
|
-
break
|
|
84
|
+
break
|
|
106
85
|
}
|
|
107
|
-
}
|
|
86
|
+
}
|
|
108
87
|
|
|
109
|
-
walk(error.issue, [], "field")
|
|
110
|
-
return
|
|
111
|
-
}
|
|
88
|
+
walk(error.issue, [], "field")
|
|
89
|
+
return entries
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const getIssueMessage = (issue: ParseResult.ParseIssue): string | undefined => {
|
|
93
|
+
const formatted = ParseResult.ArrayFormatter.formatIssueSync(issue)
|
|
94
|
+
return formatted[0]?.message
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const extractFirstError = (error: ParseResult.ParseError): Option.Option<string> => {
|
|
98
|
+
const issues = ParseResult.ArrayFormatter.formatErrorSync(error)
|
|
99
|
+
if (issues.length === 0) {
|
|
100
|
+
return Option.none()
|
|
101
|
+
}
|
|
102
|
+
return Option.some(issues[0].message)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const routeErrors = (error: ParseResult.ParseError): Map<string, string> => {
|
|
106
|
+
const result = new Map<string, string>()
|
|
107
|
+
const issues = ParseResult.ArrayFormatter.formatErrorSync(error)
|
|
108
|
+
|
|
109
|
+
for (const issue of issues) {
|
|
110
|
+
const fieldPath = schemaPathToFieldPath(issue.path)
|
|
111
|
+
if (fieldPath && !result.has(fieldPath)) {
|
|
112
|
+
result.set(fieldPath, issue.message)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return result
|
|
117
|
+
}
|
|
112
118
|
|
|
113
119
|
export const routeErrorsWithSource = (error: ParseResult.ParseError): Map<string, ErrorEntry> => {
|
|
114
|
-
const result = new Map<string, ErrorEntry>()
|
|
115
|
-
const formattedIssues = ParseResult.ArrayFormatter.formatErrorSync(error)
|
|
116
|
-
const
|
|
120
|
+
const result = new Map<string, ErrorEntry>()
|
|
121
|
+
const formattedIssues = ParseResult.ArrayFormatter.formatErrorSync(error)
|
|
122
|
+
const issueSources = collectIssueSources(error)
|
|
123
|
+
const messageSources = new Map<string, ErrorSource>()
|
|
124
|
+
const refinementPaths = new Set<string>()
|
|
125
|
+
|
|
126
|
+
for (const entry of issueSources) {
|
|
127
|
+
const fieldPath = schemaPathToFieldPath(entry.path) ?? ""
|
|
128
|
+
const message = getIssueMessage(entry.issue)
|
|
129
|
+
if (message !== undefined) {
|
|
130
|
+
const messageKey = `${fieldPath}::${message}`
|
|
131
|
+
const existing = messageSources.get(messageKey)
|
|
132
|
+
if (!existing || (existing === "field" && entry.source === "refinement")) {
|
|
133
|
+
messageSources.set(messageKey, entry.source)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (entry.source === "refinement") {
|
|
137
|
+
refinementPaths.add(fieldPath)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
117
140
|
|
|
118
141
|
for (const issue of formattedIssues) {
|
|
119
|
-
const fieldPath = schemaPathToFieldPath(issue.path)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
142
|
+
const fieldPath = schemaPathToFieldPath(issue.path) ?? ""
|
|
143
|
+
if (result.has(fieldPath)) continue
|
|
144
|
+
const preferredSource: ErrorSource = refinementPaths.has(fieldPath) ? "refinement" : "field"
|
|
145
|
+
const messageKey = `${fieldPath}::${issue.message}`
|
|
146
|
+
const issueSource = messageSources.get(messageKey) ?? "field"
|
|
147
|
+
if (preferredSource === "refinement" && issueSource !== "refinement") {
|
|
148
|
+
continue
|
|
124
149
|
}
|
|
150
|
+
result.set(fieldPath, { message: issue.message, source: issueSource })
|
|
125
151
|
}
|
|
126
152
|
|
|
127
|
-
|
|
128
|
-
|
|
153
|
+
if (result.size < formattedIssues.length) {
|
|
154
|
+
for (const issue of formattedIssues) {
|
|
155
|
+
const fieldPath = schemaPathToFieldPath(issue.path) ?? ""
|
|
156
|
+
if (result.has(fieldPath)) continue
|
|
157
|
+
const messageKey = `${fieldPath}::${issue.message}`
|
|
158
|
+
const issueSource = messageSources.get(messageKey) ?? "field"
|
|
159
|
+
result.set(fieldPath, { message: issue.message, source: issueSource })
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return result
|
|
164
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,34 +1,13 @@
|
|
|
1
|
+
export * as Field from "./Field.ts"
|
|
1
2
|
|
|
2
|
-
export * as
|
|
3
|
+
export * as FieldState from "./FieldState.ts"
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
* Root anchor atom for the form's dependency graph.
|
|
6
|
-
* Mount this atom to keep all form state alive even when field components unmount.
|
|
7
|
-
*
|
|
8
|
-
* Useful for:
|
|
9
|
-
* - Multi-step wizards where steps unmount but state should persist
|
|
10
|
-
* - Conditional fields (toggles) where state should survive visibility changes
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* // Keep form state alive at wizard root level
|
|
15
|
-
* function Wizard() {
|
|
16
|
-
* useAtomMount(step1Form.mount)
|
|
17
|
-
* useAtomMount(step2Form.mount)
|
|
18
|
-
* return currentStep === 1 ? <Step1 /> : <Step2 />
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export * as FormAtoms from "./FormAtoms.js"
|
|
5
|
+
export * as FormAtoms from "./FormAtoms.ts"
|
|
23
6
|
|
|
7
|
+
export * as FormBuilder from "./FormBuilder.ts"
|
|
24
8
|
|
|
25
|
-
export * as
|
|
9
|
+
export * as Mode from "./Mode.ts"
|
|
26
10
|
|
|
11
|
+
export * as Path from "./Path.ts"
|
|
27
12
|
|
|
28
|
-
export * as
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export * as Path from "./Path.js"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export * as Validation from "./Validation.js"
|
|
13
|
+
export * as Validation from "./Validation.ts"
|
package/src/internal/dirty.ts
CHANGED
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
import * as Equal from "effect/Equal"
|
|
2
|
-
import * as Utils from "effect/Utils"
|
|
3
|
-
import { getNestedValue, isPathUnderRoot } from "../Path.
|
|
1
|
+
import * as Equal from "effect/Equal"
|
|
2
|
+
import * as Utils from "effect/Utils"
|
|
3
|
+
import { getNestedValue, isPathUnderRoot } from "../Path.ts"
|
|
4
4
|
|
|
5
5
|
export const recalculateDirtyFieldsForArray = (
|
|
6
6
|
dirtyFields: ReadonlySet<string>,
|
|
7
7
|
initialValues: unknown,
|
|
8
8
|
arrayPath: string,
|
|
9
|
-
newItems: ReadonlyArray<unknown
|
|
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
|
-
Array.from(dirtyFields).filter((path) => !isPathUnderRoot(path, arrayPath))
|
|
19
|
-
)
|
|
18
|
+
Array.from(dirtyFields).filter((path) => !isPathUnderRoot(path, arrayPath))
|
|
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>,
|
|
46
46
|
allInitial: unknown,
|
|
47
47
|
allValues: unknown,
|
|
48
|
-
rootPath: string = ""
|
|
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
|
-
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
|
|
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>
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export const createWeakRegistry = <V extends object
|
|
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
|
-
values: () => map.values()
|
|
20
|
-
}
|
|
19
|
+
values: () => map.values()
|
|
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
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
package/Field/package.json
DELETED
package/FormAtoms/package.json
DELETED
package/FormBuilder/package.json
DELETED
package/Mode/package.json
DELETED
package/Path/package.json
DELETED
package/Validation/package.json
DELETED
package/dist/cjs/Field.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.makeField = exports.makeArrayField = exports.isFieldDef = exports.isArrayFieldDef = exports.getDefaultFromSchema = exports.getDefaultEncodedValues = exports.createTouchedRecord = exports.TypeId = void 0;
|
|
7
|
-
var Schema = /*#__PURE__*/_interopRequireWildcard(/*#__PURE__*/require("effect/Schema"));
|
|
8
|
-
function _interopRequireWildcard(e, t) {
|
|
9
|
-
if ("function" == typeof WeakMap) var r = new WeakMap(),
|
|
10
|
-
n = new WeakMap();
|
|
11
|
-
return (_interopRequireWildcard = function (e, t) {
|
|
12
|
-
if (!t && e && e.__esModule) return e;
|
|
13
|
-
var o,
|
|
14
|
-
i,
|
|
15
|
-
f = {
|
|
16
|
-
__proto__: null,
|
|
17
|
-
default: e
|
|
18
|
-
};
|
|
19
|
-
if (null === e || "object" != typeof e && "function" != typeof e) return f;
|
|
20
|
-
if (o = t ? n : r) {
|
|
21
|
-
if (o.has(e)) return o.get(e);
|
|
22
|
-
o.set(e, f);
|
|
23
|
-
}
|
|
24
|
-
for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]);
|
|
25
|
-
return f;
|
|
26
|
-
})(e, t);
|
|
27
|
-
}
|
|
28
|
-
const TypeId = exports.TypeId = /*#__PURE__*/Symbol.for("@lucas-barake/effect-form/Field");
|
|
29
|
-
const isArrayFieldDef = def => def._tag === "array";
|
|
30
|
-
exports.isArrayFieldDef = isArrayFieldDef;
|
|
31
|
-
const isFieldDef = def => def._tag === "field";
|
|
32
|
-
exports.isFieldDef = isFieldDef;
|
|
33
|
-
const makeField = (key, schema) => ({
|
|
34
|
-
_tag: "field",
|
|
35
|
-
key,
|
|
36
|
-
schema
|
|
37
|
-
});
|
|
38
|
-
exports.makeField = makeField;
|
|
39
|
-
const makeArrayField = (key, itemSchema) => ({
|
|
40
|
-
_tag: "array",
|
|
41
|
-
key,
|
|
42
|
-
itemSchema
|
|
43
|
-
});
|
|
44
|
-
exports.makeArrayField = makeArrayField;
|
|
45
|
-
const getDefaultFromSchema = schema => {
|
|
46
|
-
const ast = schema.ast;
|
|
47
|
-
switch (ast._tag) {
|
|
48
|
-
case "StringKeyword":
|
|
49
|
-
case "TemplateLiteral":
|
|
50
|
-
return "";
|
|
51
|
-
case "NumberKeyword":
|
|
52
|
-
return 0;
|
|
53
|
-
case "BooleanKeyword":
|
|
54
|
-
return false;
|
|
55
|
-
case "TypeLiteral":
|
|
56
|
-
{
|
|
57
|
-
const result = {};
|
|
58
|
-
for (const prop of ast.propertySignatures) {
|
|
59
|
-
result[prop.name] = getDefaultFromSchema(Schema.make(prop.type));
|
|
60
|
-
}
|
|
61
|
-
return result;
|
|
62
|
-
}
|
|
63
|
-
case "Transformation":
|
|
64
|
-
return getDefaultFromSchema(Schema.make(ast.from));
|
|
65
|
-
case "Refinement":
|
|
66
|
-
return getDefaultFromSchema(Schema.make(ast.from));
|
|
67
|
-
case "Suspend":
|
|
68
|
-
return getDefaultFromSchema(Schema.make(ast.f()));
|
|
69
|
-
default:
|
|
70
|
-
return "";
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
exports.getDefaultFromSchema = getDefaultFromSchema;
|
|
74
|
-
const getDefaultEncodedValues = fields => {
|
|
75
|
-
const result = {};
|
|
76
|
-
for (const [key, def] of Object.entries(fields)) {
|
|
77
|
-
if (isArrayFieldDef(def)) {
|
|
78
|
-
result[key] = [];
|
|
79
|
-
} else {
|
|
80
|
-
result[key] = "";
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return result;
|
|
84
|
-
};
|
|
85
|
-
exports.getDefaultEncodedValues = getDefaultEncodedValues;
|
|
86
|
-
const createTouchedRecord = (fields, value) => {
|
|
87
|
-
const result = {};
|
|
88
|
-
for (const key of Object.keys(fields)) {
|
|
89
|
-
result[key] = value;
|
|
90
|
-
}
|
|
91
|
-
return result;
|
|
92
|
-
};
|
|
93
|
-
exports.createTouchedRecord = createTouchedRecord;
|
|
94
|
-
//# sourceMappingURL=Field.js.map
|
package/dist/cjs/Field.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Field.js","names":["Schema","_interopRequireWildcard","require","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","TypeId","exports","Symbol","for","isArrayFieldDef","def","_tag","isFieldDef","makeField","key","schema","makeArrayField","itemSchema","getDefaultFromSchema","ast","result","prop","propertySignatures","name","make","type","from","getDefaultEncodedValues","fields","entries","createTouchedRecord","value","keys"],"sources":["../../src/Field.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,MAAA,gBAAAC,uBAAA,cAAAC,OAAA;AAAwC,SAAAD,wBAAAE,CAAA,EAAAC,CAAA;EAAA,yBAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA;IAAAE,CAAA,OAAAF,OAAA;EAAA,QAAAJ,uBAAA,YAAAA,CAAAE,CAAA,EAAAC,CAAA;IAAA,KAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA;IAAA,IAAAM,CAAA;MAAAC,CAAA;MAAAC,CAAA;QAAAC,SAAA;QAAAC,OAAA,EAAAV;MAAA;IAAA,aAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA;IAAA,IAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA;MAAA,IAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA;MAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA;IAAA;IAAA,WAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA;IAAA,OAAAO,CAAA;EAAA,GAAAR,CAAA,EAAAC,CAAA;AAAA;AAEjC,MAAMkB,MAAM,GAAAC,OAAA,CAAAD,MAAA,gBAAkBE,MAAM,CAACC,GAAG,CAAC,iCAAiC,CAAC;AAoB3E,MAAMC,eAAe,GAAIC,GAAgB,IAC9CA,GAAG,CAACC,IAAI,KAAK,OAAO;AAACL,OAAA,CAAAG,eAAA,GAAAA,eAAA;AAEhB,MAAMG,UAAU,GAAIF,GAAgB,IAAiDA,GAAG,CAACC,IAAI,KAAK,OAAO;AAACL,OAAA,CAAAM,UAAA,GAAAA,UAAA;AAE1G,MAAMC,SAAS,GAAGA,CACvBC,GAAM,EACNC,MAAS,MACW;EACpBJ,IAAI,EAAE,OAAO;EACbG,GAAG;EACHC;CACD,CAAC;AAACT,OAAA,CAAAO,SAAA,GAAAA,SAAA;AAEI,MAAMG,cAAc,GAAGA,CAC5BF,GAAM,EACNG,UAAa,MACY;EACzBN,IAAI,EAAE,OAAO;EACbG,GAAG;EACHG;CACD,CAAC;AAACX,OAAA,CAAAU,cAAA,GAAAA,cAAA;AAcI,MAAME,oBAAoB,GAAIH,MAAyB,IAAa;EACzE,MAAMI,GAAG,GAAGJ,MAAM,CAACI,GAAG;EACtB,QAAQA,GAAG,CAACR,IAAI;IACd,KAAK,eAAe;IACpB,KAAK,iBAAiB;MACpB,OAAO,EAAE;IACX,KAAK,eAAe;MAClB,OAAO,CAAC;IACV,KAAK,gBAAgB;MACnB,OAAO,KAAK;IACd,KAAK,aAAa;MAAE;QAClB,MAAMS,MAAM,GAA4B,EAAE;QAC1C,KAAK,MAAMC,IAAI,IAAIF,GAAG,CAACG,kBAAkB,EAAE;UACzCF,MAAM,CAACC,IAAI,CAACE,IAAc,CAAC,GAAGL,oBAAoB,CAACnC,MAAM,CAACyC,IAAI,CAACH,IAAI,CAACI,IAAI,CAAC,CAAC;QAC5E;QACA,OAAOL,MAAM;MACf;IACA,KAAK,gBAAgB;MACnB,OAAOF,oBAAoB,CAACnC,MAAM,CAACyC,IAAI,CAACL,GAAG,CAACO,IAAI,CAAC,CAAC;IACpD,KAAK,YAAY;MACf,OAAOR,oBAAoB,CAACnC,MAAM,CAACyC,IAAI,CAACL,GAAG,CAACO,IAAI,CAAC,CAAC;IACpD,KAAK,SAAS;MACZ,OAAOR,oBAAoB,CAACnC,MAAM,CAACyC,IAAI,CAACL,GAAG,CAACzB,CAAC,EAAE,CAAC,CAAC;IACnD;MACE,OAAO,EAAE;EACb;AACF,CAAC;AAACY,OAAA,CAAAY,oBAAA,GAAAA,oBAAA;AAEK,MAAMS,uBAAuB,GAAIC,MAAoB,IAA6B;EACvF,MAAMR,MAAM,GAA4B,EAAE;EAC1C,KAAK,MAAM,CAACN,GAAG,EAAEJ,GAAG,CAAC,IAAIR,MAAM,CAAC2B,OAAO,CAACD,MAAM,CAAC,EAAE;IAC/C,IAAInB,eAAe,CAACC,GAAG,CAAC,EAAE;MACxBU,MAAM,CAACN,GAAG,CAAC,GAAG,EAAE;IAClB,CAAC,MAAM;MACLM,MAAM,CAACN,GAAG,CAAC,GAAG,EAAE;IAClB;EACF;EACA,OAAOM,MAAM;AACf,CAAC;AAACd,OAAA,CAAAqB,uBAAA,GAAAA,uBAAA;AAEK,MAAMG,mBAAmB,GAAGA,CAACF,MAAoB,EAAEG,KAAc,KAA6B;EACnG,MAAMX,MAAM,GAA4B,EAAE;EAC1C,KAAK,MAAMN,GAAG,IAAIZ,MAAM,CAAC8B,IAAI,CAACJ,MAAM,CAAC,EAAE;IACrCR,MAAM,CAACN,GAAG,CAAC,GAAGiB,KAAK;EACrB;EACA,OAAOX,MAAM;AACf,CAAC;AAACd,OAAA,CAAAwB,mBAAA,GAAAA,mBAAA","ignoreList":[]}
|