cross-state 0.19.3 → 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/cjs/hash.cjs +18 -0
- package/dist/cjs/hash.cjs.map +1 -0
- package/dist/cjs/index.cjs +10 -10
- package/dist/cjs/react/index.cjs +249 -188
- package/dist/cjs/react/index.cjs.map +1 -1
- package/dist/cjs/react/register.cjs +12 -12
- package/dist/cjs/react/register.cjs.map +1 -1
- package/dist/cjs/scope.cjs +572 -19
- package/dist/cjs/scope.cjs.map +1 -1
- package/dist/cjs/{cache.cjs → scope2.cjs} +14 -3
- package/dist/cjs/scope2.cjs.map +1 -0
- package/dist/cjs/store.cjs +26 -5
- package/dist/cjs/store.cjs.map +1 -1
- package/dist/es/hash.mjs +19 -0
- package/dist/es/hash.mjs.map +1 -0
- package/dist/es/index.mjs +6 -6
- package/dist/es/react/index.mjs +245 -184
- package/dist/es/react/index.mjs.map +1 -1
- package/dist/es/react/register.mjs +4 -4
- package/dist/es/scope.mjs +573 -20
- package/dist/es/scope.mjs.map +1 -1
- package/dist/es/{cache.mjs → scope2.mjs} +14 -3
- package/dist/es/scope2.mjs.map +1 -0
- package/dist/es/store.mjs +26 -5
- package/dist/es/store.mjs.map +1 -1
- package/dist/types/core/commonTypes.d.ts +0 -1
- package/dist/types/lib/debounce.d.ts +5 -1
- package/dist/types/react/form/form.d.ts +47 -48
- package/dist/types/react/form/formField.d.ts +0 -1
- package/dist/types/react/form/useFormAutosave.d.ts +9 -0
- package/package.json +17 -17
- package/dist/cjs/cache.cjs.map +0 -1
- package/dist/cjs/useCache.cjs +0 -583
- package/dist/cjs/useCache.cjs.map +0 -1
- package/dist/es/cache.mjs.map +0 -1
- package/dist/es/useCache.mjs +0 -584
- package/dist/es/useCache.mjs.map +0 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
function hash(value) {
|
|
3
|
+
if (value instanceof Set) {
|
|
4
|
+
return `s[${[...value].map(hash).sort().join(",")}]`;
|
|
5
|
+
}
|
|
6
|
+
if (value instanceof Map) {
|
|
7
|
+
return `m[${[...value.entries()].map(hash).sort().join(",")}]`;
|
|
8
|
+
}
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
return `[${value.map(hash).join(",")}]`;
|
|
11
|
+
}
|
|
12
|
+
if (value instanceof Object) {
|
|
13
|
+
return `o[${Object.entries(value).map(hash).sort().join(",")}]`;
|
|
14
|
+
}
|
|
15
|
+
return JSON.stringify(value);
|
|
16
|
+
}
|
|
17
|
+
exports.hash = hash;
|
|
18
|
+
//# sourceMappingURL=hash.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.cjs","sources":["../../src/lib/hash.ts"],"sourcesContent":["export function hash(value: unknown): string {\n if (value instanceof Set) {\n return `s[${[...value].map(hash).sort().join(',')}]`;\n }\n\n if (value instanceof Map) {\n return `m[${[...value.entries()].map(hash).sort().join(',')}]`;\n }\n\n if (Array.isArray(value)) {\n return `[${value.map(hash).join(',')}]`;\n }\n\n if (value instanceof Object) {\n return `o[${Object.entries(value).map(hash).sort().join(',')}]`;\n }\n\n return JSON.stringify(value);\n}\n"],"names":[],"mappings":";AAAO,SAAS,KAAK,OAAwB;AAC3C,MAAI,iBAAiB,KAAK;AACxB,WAAO,KAAK,CAAC,GAAG,KAAK,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,EACnD;AAEA,MAAI,iBAAiB,KAAK;AACxB,WAAO,KAAK,CAAC,GAAG,MAAM,QAAS,CAAA,EAAE,IAAI,IAAI,EAAE,KAAA,EAAO,KAAK,GAAG,CAAC;AAAA,EAC7D;AAEI,MAAA,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,IAAI,MAAM,IAAI,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,EACtC;AAEA,MAAI,iBAAiB,QAAQ;AAC3B,WAAO,KAAK,OAAO,QAAQ,KAAK,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,EAC9D;AAEO,SAAA,KAAK,UAAU,KAAK;AAC7B;;"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const store = require("./store.cjs");
|
|
4
|
-
const
|
|
5
|
-
const scope = require("./scope.cjs");
|
|
4
|
+
const scope = require("./scope2.cjs");
|
|
6
5
|
const urlStore = require("./urlStore.cjs");
|
|
6
|
+
require("./hash.cjs");
|
|
7
7
|
class SubstriptionCache extends store.Store {
|
|
8
8
|
constructor(connectFunction, options, derivedFromSubscriptionCache, _call) {
|
|
9
9
|
super(options.default, options, void 0, _call);
|
|
@@ -68,7 +68,7 @@ function create(cacheFunction, ...[options = {}]) {
|
|
|
68
68
|
options = Object.assign({}, defaultOptions, options);
|
|
69
69
|
const { clearUnusedAfter, resourceGroup } = options;
|
|
70
70
|
let baseInstance;
|
|
71
|
-
const instanceCache = new
|
|
71
|
+
const instanceCache = new scope.InstanceCache(
|
|
72
72
|
(...args) => {
|
|
73
73
|
if (args.length === 0 && baseInstance) {
|
|
74
74
|
return baseInstance;
|
|
@@ -107,7 +107,7 @@ function create(cacheFunction, ...[options = {}]) {
|
|
|
107
107
|
}
|
|
108
108
|
);
|
|
109
109
|
const groups = Array.isArray(resourceGroup) ? resourceGroup : resourceGroup ? [resourceGroup] : [];
|
|
110
|
-
for (const group of groups.concat(
|
|
110
|
+
for (const group of groups.concat(scope.allResources)) {
|
|
111
111
|
group.add(baseInstance);
|
|
112
112
|
}
|
|
113
113
|
get(...[]);
|
|
@@ -429,13 +429,13 @@ exports.mapMethods = store.mapMethods;
|
|
|
429
429
|
exports.recordMethods = store.recordMethods;
|
|
430
430
|
exports.set = store.set;
|
|
431
431
|
exports.setMethods = store.setMethods;
|
|
432
|
-
exports.Cache =
|
|
433
|
-
exports.InstanceCache =
|
|
434
|
-
exports.ResourceGroup =
|
|
435
|
-
exports.allResources = cache.allResources;
|
|
436
|
-
exports.createCache = cache.createCache;
|
|
437
|
-
exports.createResourceGroup = cache.createResourceGroup;
|
|
432
|
+
exports.Cache = scope.Cache;
|
|
433
|
+
exports.InstanceCache = scope.InstanceCache;
|
|
434
|
+
exports.ResourceGroup = scope.ResourceGroup;
|
|
438
435
|
exports.Scope = scope.Scope;
|
|
436
|
+
exports.allResources = scope.allResources;
|
|
437
|
+
exports.createCache = scope.createCache;
|
|
438
|
+
exports.createResourceGroup = scope.createResourceGroup;
|
|
439
439
|
exports.createScope = scope.createScope;
|
|
440
440
|
exports.connectUrl = urlStore.connectUrl;
|
|
441
441
|
exports.createUrlStore = urlStore.createUrlStore;
|
package/dist/cjs/react/index.cjs
CHANGED
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const
|
|
3
|
+
const scope = require("../scope.cjs");
|
|
4
4
|
const require$$0 = require("react");
|
|
5
5
|
const store = require("../store.cjs");
|
|
6
|
-
const
|
|
6
|
+
const hash = require("../hash.cjs");
|
|
7
7
|
const jsxRuntime = require("react/jsx-runtime");
|
|
8
8
|
const urlStore = require("../urlStore.cjs");
|
|
9
|
-
function wildcardMatch(s, w) {
|
|
10
|
-
if (typeof s === "string") {
|
|
11
|
-
s = store.castArrayPath(s);
|
|
12
|
-
}
|
|
13
|
-
if (typeof w === "string") {
|
|
14
|
-
w = store.castArrayPath(w);
|
|
15
|
-
}
|
|
16
|
-
return s.length === w.length && s.every((s2, i) => w[i] === "*" || s2 === w[i]);
|
|
17
|
-
}
|
|
18
9
|
function getWildCardMatches(object, path) {
|
|
19
10
|
const matches = {};
|
|
20
11
|
const [first, second, ...rest] = store.castArrayPath(path);
|
|
@@ -40,8 +31,8 @@ function getWildCardMatches(object, path) {
|
|
|
40
31
|
}
|
|
41
32
|
function FormArray({ name, renderElement, children }) {
|
|
42
33
|
const form = this.useForm();
|
|
43
|
-
const names = this.useFormState((
|
|
44
|
-
const field =
|
|
34
|
+
const names = this.useFormState(() => {
|
|
35
|
+
const field = form.getField(name);
|
|
45
36
|
return field.names;
|
|
46
37
|
});
|
|
47
38
|
const append = require$$0.useCallback(
|
|
@@ -80,8 +71,9 @@ function FormArray({ name, renderElement, children }) {
|
|
|
80
71
|
] });
|
|
81
72
|
}
|
|
82
73
|
function FormError({ name }) {
|
|
83
|
-
const
|
|
84
|
-
|
|
74
|
+
const hasTriggeredValidations = this.useFormState((form) => form.hasTriggeredValidations);
|
|
75
|
+
const { errors } = this.useField(name);
|
|
76
|
+
return hasTriggeredValidations ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: errors.join(", ") }) : null;
|
|
85
77
|
}
|
|
86
78
|
function FormField({
|
|
87
79
|
// id,
|
|
@@ -96,16 +88,12 @@ function FormField({
|
|
|
96
88
|
...restProps
|
|
97
89
|
}) {
|
|
98
90
|
const id = "";
|
|
99
|
-
const
|
|
100
|
-
const state = useCache.useScope(this.state);
|
|
91
|
+
const { options } = this.useForm();
|
|
101
92
|
const { value, setValue, errors } = this.useField(name);
|
|
102
|
-
const errorString =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}).join("\n"),
|
|
107
|
-
[errors, form.options.localizeError]
|
|
108
|
-
);
|
|
93
|
+
const errorString = errors.map((error) => {
|
|
94
|
+
var _a;
|
|
95
|
+
return ((_a = options.localizeError) == null ? void 0 : _a.call(options, error, name)) ?? error;
|
|
96
|
+
}).join("\n");
|
|
109
97
|
const [localValue, setLocalValue] = require$$0.useState();
|
|
110
98
|
const _id = require$$0.useMemo(
|
|
111
99
|
() => `f${Math.random().toString(36).slice(2, 15)}${Math.random().toString(36).slice(2, 15)}`,
|
|
@@ -148,15 +136,6 @@ function FormField({
|
|
|
148
136
|
}
|
|
149
137
|
(_a = restProps.onChange) == null ? void 0 : _a.call(restProps, event, ...moreArgs);
|
|
150
138
|
},
|
|
151
|
-
onFocus(...args) {
|
|
152
|
-
var _a;
|
|
153
|
-
state.set("touched", (touched) => {
|
|
154
|
-
touched = new Set(touched);
|
|
155
|
-
touched.add(_id);
|
|
156
|
-
return touched;
|
|
157
|
-
});
|
|
158
|
-
(_a = restProps.onFocus) == null ? void 0 : _a.apply(null, args);
|
|
159
|
-
},
|
|
160
139
|
onBlur(...args) {
|
|
161
140
|
var _a;
|
|
162
141
|
if (localValue !== void 0) {
|
|
@@ -171,11 +150,65 @@ function FormField({
|
|
|
171
150
|
}
|
|
172
151
|
return require$$0.createElement(component, props);
|
|
173
152
|
}
|
|
153
|
+
function useFormAutosave(form) {
|
|
154
|
+
var _a;
|
|
155
|
+
const { formState, options, getDraft } = form;
|
|
156
|
+
const debounceTime = store.calcDuration(((_a = options.autoSave) == null ? void 0 : _a.debounce) ?? 2e3);
|
|
157
|
+
const latestRef = require$$0.useRef({ options });
|
|
158
|
+
const lastValue = require$$0.useRef();
|
|
159
|
+
const q = require$$0.useMemo(() => store.queue(), []);
|
|
160
|
+
const run = require$$0.useMemo(
|
|
161
|
+
() => store.debounce(async () => {
|
|
162
|
+
var _a2;
|
|
163
|
+
const { options: options2 } = latestRef.current;
|
|
164
|
+
const save = (_a2 = options2.autoSave) == null ? void 0 : _a2.save;
|
|
165
|
+
const draft = getDraft();
|
|
166
|
+
lastValue.current = draft;
|
|
167
|
+
q.clear();
|
|
168
|
+
q(async () => {
|
|
169
|
+
var _a3;
|
|
170
|
+
try {
|
|
171
|
+
formState.set("saveInProgress", true);
|
|
172
|
+
await (save == null ? void 0 : save(draft, form));
|
|
173
|
+
if (q.size === 0 && ((_a3 = options2.autoSave) == null ? void 0 : _a3.resetAfterSave)) {
|
|
174
|
+
form.reset();
|
|
175
|
+
}
|
|
176
|
+
} finally {
|
|
177
|
+
formState.set("saveInProgress", false);
|
|
178
|
+
if (q.size === 0) {
|
|
179
|
+
formState.set("saveScheduled", false);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}, debounceTime),
|
|
184
|
+
[formState, debounceTime]
|
|
185
|
+
);
|
|
186
|
+
require$$0.useEffect(() => {
|
|
187
|
+
var _a2;
|
|
188
|
+
if (!((_a2 = options.autoSave) == null ? void 0 : _a2.save)) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
return formState.map((state) => state.draft).subscribe(
|
|
192
|
+
() => {
|
|
193
|
+
if (store.deepEqual(getDraft(), lastValue.current)) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
run();
|
|
197
|
+
formState.set("saveScheduled", true);
|
|
198
|
+
},
|
|
199
|
+
{ runNow: false }
|
|
200
|
+
);
|
|
201
|
+
}, [formState]);
|
|
202
|
+
require$$0.useEffect(() => {
|
|
203
|
+
latestRef.current = { options };
|
|
204
|
+
});
|
|
205
|
+
}
|
|
174
206
|
function FormContainer({
|
|
175
207
|
form,
|
|
176
208
|
...formProps
|
|
177
209
|
}) {
|
|
178
|
-
const
|
|
210
|
+
const { validate, options, getErrors: getErrors2 } = form.useForm();
|
|
211
|
+
const errors = getErrors2();
|
|
179
212
|
const hasTriggeredValidations = form.useFormState((state) => state.hasTriggeredValidations);
|
|
180
213
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
181
214
|
"form",
|
|
@@ -186,16 +219,16 @@ function FormContainer({
|
|
|
186
219
|
onSubmit: (event) => {
|
|
187
220
|
var _a;
|
|
188
221
|
event.preventDefault();
|
|
189
|
-
const isValid =
|
|
222
|
+
const isValid = validate();
|
|
190
223
|
let button;
|
|
191
224
|
if (event.nativeEvent instanceof SubmitEvent && (button = event.nativeEvent.submitter) && (button instanceof HTMLButtonElement || button instanceof HTMLInputElement) && button.setCustomValidity) {
|
|
192
|
-
const
|
|
193
|
-
(
|
|
194
|
-
var _a2
|
|
195
|
-
return ((
|
|
196
|
-
}
|
|
197
|
-
);
|
|
198
|
-
button.setCustomValidity(
|
|
225
|
+
const errorString = [...errors.entries()].flatMap(
|
|
226
|
+
([field, errors2]) => errors2.map((error) => {
|
|
227
|
+
var _a2;
|
|
228
|
+
return ((_a2 = options.localizeError) == null ? void 0 : _a2.call(options, error, field)) ?? error;
|
|
229
|
+
})
|
|
230
|
+
).join("\n");
|
|
231
|
+
button.setCustomValidity(errorString);
|
|
199
232
|
}
|
|
200
233
|
event.currentTarget.reportValidity();
|
|
201
234
|
if (isValid) {
|
|
@@ -205,147 +238,92 @@ function FormContainer({
|
|
|
205
238
|
}
|
|
206
239
|
);
|
|
207
240
|
}
|
|
208
|
-
function
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
(state2) => state2.draft ?? original ?? options.defaultValue,
|
|
213
|
-
(draft) => (state2) => ({ ...state2, draft })
|
|
214
|
-
),
|
|
215
|
-
options,
|
|
216
|
-
getField: (path) => {
|
|
217
|
-
const { draft } = instance;
|
|
218
|
-
return {
|
|
219
|
-
get originalValue() {
|
|
220
|
-
return original !== void 0 ? store.get(original, path) : void 0;
|
|
221
|
-
},
|
|
222
|
-
get value() {
|
|
223
|
-
return store.get(draft.get(), path);
|
|
224
|
-
},
|
|
225
|
-
setValue(update) {
|
|
226
|
-
draft.set(path, update);
|
|
227
|
-
},
|
|
228
|
-
get isDirty() {
|
|
229
|
-
const comparisonValue = this.originalValue ?? store.get(options.defaultValue, path);
|
|
230
|
-
return state.get().hasTriggeredValidations || !store.deepEqual(comparisonValue, this.value);
|
|
231
|
-
},
|
|
232
|
-
get errors() {
|
|
233
|
-
const blocks = Object.entries(options.validations ?? {}).filter(([key]) => wildcardMatch(path, key)).map(([, value2]) => value2);
|
|
234
|
-
const value = this.value;
|
|
235
|
-
const draftValue = draft.get();
|
|
236
|
-
const errors = [];
|
|
237
|
-
for (const block of blocks ?? []) {
|
|
238
|
-
for (const [validationName, validate] of Object.entries(block)) {
|
|
239
|
-
if (!validate(value, { draft: draftValue, original, field: path })) {
|
|
240
|
-
errors.push(validationName);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return errors;
|
|
245
|
-
},
|
|
246
|
-
get names() {
|
|
247
|
-
const { value } = this;
|
|
248
|
-
return Array.isArray(value) ? value.map((_, index) => `${path}.${index}`) : [];
|
|
249
|
-
},
|
|
250
|
-
append(...elements) {
|
|
251
|
-
this.setValue(
|
|
252
|
-
(value) => Array.isArray(value) ? [...value, ...elements] : elements
|
|
253
|
-
);
|
|
254
|
-
},
|
|
255
|
-
remove(index) {
|
|
256
|
-
this.setValue(
|
|
257
|
-
(value) => Array.isArray(value) ? [...value.slice(0, index), ...value.slice(index + 1)] : value
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
241
|
+
function getField(derivedState, original, path) {
|
|
242
|
+
return {
|
|
243
|
+
get originalValue() {
|
|
244
|
+
return original !== void 0 ? store.get(original, path) : void 0;
|
|
261
245
|
},
|
|
262
|
-
get
|
|
263
|
-
const { draft } =
|
|
264
|
-
return
|
|
246
|
+
get value() {
|
|
247
|
+
const { draft } = derivedState.get();
|
|
248
|
+
return store.get(draft, path);
|
|
265
249
|
},
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
block
|
|
272
|
-
)) {
|
|
273
|
-
let matched = false;
|
|
274
|
-
for (const [field, value] of Object.entries(getWildCardMatches(draft, path))) {
|
|
275
|
-
matched = true;
|
|
276
|
-
if (!validate(value, { draft, original, field })) {
|
|
277
|
-
errors.add({ field, error: validationName });
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
if (!matched && !path.includes("*")) {
|
|
281
|
-
if (!validate(void 0, { draft, original, field: path })) {
|
|
282
|
-
errors.add({ field: path, error: validationName });
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return [...errors];
|
|
250
|
+
setValue(update) {
|
|
251
|
+
derivedState.set(`draft.${path}`, update);
|
|
252
|
+
},
|
|
253
|
+
get hasChange() {
|
|
254
|
+
return !store.deepEqual(this.originalValue, this.value);
|
|
288
255
|
},
|
|
289
|
-
get
|
|
290
|
-
|
|
256
|
+
get errors() {
|
|
257
|
+
const { errors } = derivedState.get();
|
|
258
|
+
return errors.get(path) ?? [];
|
|
291
259
|
},
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return
|
|
260
|
+
get names() {
|
|
261
|
+
const { value } = this;
|
|
262
|
+
return Array.isArray(value) ? value.map((_, index) => `${path}.${index}`) : [];
|
|
295
263
|
},
|
|
296
|
-
|
|
297
|
-
|
|
264
|
+
append(...elements) {
|
|
265
|
+
this.setValue((value) => Array.isArray(value) ? [...value, ...elements] : elements);
|
|
298
266
|
},
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
267
|
+
remove(index) {
|
|
268
|
+
this.setValue(
|
|
269
|
+
(value) => Array.isArray(value) ? [...value.slice(0, index), ...value.slice(index + 1)] : value
|
|
270
|
+
);
|
|
302
271
|
}
|
|
303
272
|
};
|
|
304
|
-
|
|
273
|
+
}
|
|
274
|
+
function getErrors(draft, original, validations) {
|
|
275
|
+
const errors = /* @__PURE__ */ new Map();
|
|
276
|
+
for (const [path, block] of Object.entries(validations ?? {})) {
|
|
277
|
+
for (const [validationName, validate] of Object.entries(
|
|
278
|
+
block
|
|
279
|
+
)) {
|
|
280
|
+
let matched = false;
|
|
281
|
+
for (const [field, value] of Object.entries(getWildCardMatches(draft, path))) {
|
|
282
|
+
matched = true;
|
|
283
|
+
if (!validate(value, { draft, original, field })) {
|
|
284
|
+
const fieldErrors = errors.get(field) ?? [];
|
|
285
|
+
fieldErrors.push(validationName);
|
|
286
|
+
errors.set(field, fieldErrors);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (!matched && !path.includes("*")) {
|
|
290
|
+
if (!validate(void 0, { draft, original, field: path })) {
|
|
291
|
+
const fieldErrors = errors.get(path) ?? [];
|
|
292
|
+
fieldErrors.push(validationName);
|
|
293
|
+
errors.set(path, fieldErrors);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return errors;
|
|
305
299
|
}
|
|
306
300
|
class Form {
|
|
307
301
|
constructor(options) {
|
|
308
302
|
this.options = options;
|
|
309
|
-
this.context = require$$0.createContext(
|
|
310
|
-
original: void 0,
|
|
311
|
-
options: this.options
|
|
312
|
-
});
|
|
313
|
-
this.state = new scope.Scope({
|
|
314
|
-
touched: /* @__PURE__ */ new Set(),
|
|
315
|
-
errors: /* @__PURE__ */ new Map()
|
|
316
|
-
});
|
|
303
|
+
this.context = require$$0.createContext(null);
|
|
317
304
|
store.autobind(Form);
|
|
318
305
|
}
|
|
319
306
|
useForm() {
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
const { original, options } = require$$0.useContext(this.context);
|
|
326
|
-
const state = useCache.useScope(this.state);
|
|
327
|
-
return useCache.useStore(state.map(() => selector(getFormInstance(original, options, state))));
|
|
307
|
+
const context = require$$0.useContext(this.context);
|
|
308
|
+
if (!context) {
|
|
309
|
+
throw new Error("Form context not found");
|
|
310
|
+
}
|
|
311
|
+
return context;
|
|
328
312
|
}
|
|
329
|
-
|
|
313
|
+
useFormState(selector, useStoreOptions) {
|
|
330
314
|
const form = this.useForm();
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
315
|
+
return scope.useStore(
|
|
316
|
+
form.derivedState.map(
|
|
317
|
+
(state) => selector({
|
|
318
|
+
...form,
|
|
319
|
+
...state
|
|
320
|
+
})
|
|
321
|
+
),
|
|
338
322
|
useStoreOptions
|
|
339
323
|
);
|
|
340
|
-
return form.getField(path);
|
|
341
324
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
return useCache.useStore(form.draft.map(() => form.hasChanges));
|
|
345
|
-
}
|
|
346
|
-
useIsValid() {
|
|
347
|
-
const form = this.useForm();
|
|
348
|
-
return useCache.useStore(form.draft.map(() => form.isValid));
|
|
325
|
+
useField(path, useStoreOptions) {
|
|
326
|
+
return this.useFormState((form) => form.getField(path), useStoreOptions);
|
|
349
327
|
}
|
|
350
328
|
// ///////////////////////////////////////////////////////////////////////////
|
|
351
329
|
// React Components
|
|
@@ -356,34 +334,117 @@ class Form {
|
|
|
356
334
|
validations,
|
|
357
335
|
localizeError,
|
|
358
336
|
urlState,
|
|
337
|
+
autoSave,
|
|
338
|
+
transform,
|
|
359
339
|
...formProps
|
|
360
340
|
}) {
|
|
361
|
-
const
|
|
362
|
-
|
|
341
|
+
const options = {
|
|
342
|
+
defaultValue: { ...this.options.defaultValue, ...defaultValue },
|
|
343
|
+
validations: { ...this.options.validations, ...validations },
|
|
344
|
+
localizeError: localizeError ?? this.options.localizeError,
|
|
345
|
+
autoSave: autoSave ?? this.options.autoSave,
|
|
346
|
+
transform: transform ?? this.options.transform
|
|
347
|
+
};
|
|
348
|
+
const formState = require$$0.useMemo(() => {
|
|
349
|
+
return store.createStore({
|
|
350
|
+
draft: void 0,
|
|
351
|
+
hasTriggeredValidations: false,
|
|
352
|
+
saveScheduled: false,
|
|
353
|
+
saveInProgress: false
|
|
354
|
+
});
|
|
355
|
+
}, []);
|
|
356
|
+
const derivedState = require$$0.useMemo(() => {
|
|
357
|
+
return formState.map(
|
|
358
|
+
(state) => {
|
|
359
|
+
const {
|
|
360
|
+
draft = original ?? options.defaultValue,
|
|
361
|
+
hasTriggeredValidations,
|
|
362
|
+
saveScheduled,
|
|
363
|
+
saveInProgress
|
|
364
|
+
} = state;
|
|
365
|
+
const errors = getErrors(draft, original, options.validations);
|
|
366
|
+
return {
|
|
367
|
+
draft,
|
|
368
|
+
hasTriggeredValidations,
|
|
369
|
+
saveScheduled,
|
|
370
|
+
saveInProgress,
|
|
371
|
+
hasChanges: !!draft && !store.deepEqual(draft, original),
|
|
372
|
+
errors,
|
|
373
|
+
isValid: errors.size === 0
|
|
374
|
+
};
|
|
375
|
+
},
|
|
376
|
+
(newState) => ({
|
|
377
|
+
draft: newState.draft,
|
|
378
|
+
hasTriggeredValidations: newState.hasTriggeredValidations,
|
|
379
|
+
saveScheduled: newState.saveScheduled,
|
|
380
|
+
saveInProgress: newState.saveInProgress
|
|
381
|
+
})
|
|
382
|
+
);
|
|
383
|
+
}, [formState, original, options.validations, options.defaultValue]);
|
|
384
|
+
const context = require$$0.useMemo(() => {
|
|
385
|
+
return {
|
|
386
|
+
formState,
|
|
387
|
+
derivedState,
|
|
388
|
+
options,
|
|
363
389
|
original,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
390
|
+
getField(path) {
|
|
391
|
+
return getField(derivedState, original, path);
|
|
392
|
+
},
|
|
393
|
+
getDraft() {
|
|
394
|
+
return formState.get().draft ?? original ?? options.defaultValue;
|
|
395
|
+
},
|
|
396
|
+
hasTriggeredValidations() {
|
|
397
|
+
return formState.get().hasTriggeredValidations;
|
|
398
|
+
},
|
|
399
|
+
hasChanges() {
|
|
400
|
+
return derivedState.get().hasChanges;
|
|
401
|
+
},
|
|
402
|
+
getErrors() {
|
|
403
|
+
return derivedState.get().errors;
|
|
404
|
+
},
|
|
405
|
+
isValid() {
|
|
406
|
+
return derivedState.get().isValid;
|
|
407
|
+
},
|
|
408
|
+
validate() {
|
|
409
|
+
formState.set("hasTriggeredValidations", true);
|
|
410
|
+
return derivedState.get().isValid;
|
|
411
|
+
},
|
|
412
|
+
reset() {
|
|
413
|
+
formState.set("draft", void 0);
|
|
414
|
+
formState.set("hasTriggeredValidations", false);
|
|
368
415
|
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
);
|
|
372
|
-
const store$1 = require$$0.useMemo(() => {
|
|
373
|
-
return store.createStore(this.state.defaultValue);
|
|
374
|
-
}, []);
|
|
416
|
+
};
|
|
417
|
+
}, [formState, derivedState, original, defaultValue, validations, localizeError, urlState]);
|
|
375
418
|
require$$0.useEffect(() => {
|
|
376
419
|
if (urlState) {
|
|
377
420
|
return urlStore.connectUrl(
|
|
378
|
-
|
|
421
|
+
formState.map("draft"),
|
|
379
422
|
typeof urlState === "object" ? urlState : { key: "form" }
|
|
380
423
|
);
|
|
381
424
|
}
|
|
382
425
|
return void 0;
|
|
383
|
-
}, [
|
|
384
|
-
|
|
426
|
+
}, [formState, hash.hash(urlState)]);
|
|
427
|
+
require$$0.useEffect(() => {
|
|
428
|
+
var _a;
|
|
429
|
+
const handles = (_a = options.transform) == null ? void 0 : _a.map(({ trigger, update }) => {
|
|
430
|
+
const draft = derivedState.map("draft");
|
|
431
|
+
const triggerStore = trigger ? draft.map(trigger) : draft;
|
|
432
|
+
return triggerStore.subscribe(() => {
|
|
433
|
+
const value = trigger ? store.get(draft.get(), trigger) : draft.get();
|
|
434
|
+
const result = update(value, draft);
|
|
435
|
+
if (result !== void 0) {
|
|
436
|
+
draft.set(result);
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
});
|
|
440
|
+
return () => {
|
|
441
|
+
handles == null ? void 0 : handles.forEach((handle) => handle());
|
|
442
|
+
};
|
|
443
|
+
}, [options.transform]);
|
|
444
|
+
useFormAutosave(context);
|
|
445
|
+
return /* @__PURE__ */ jsxRuntime.jsx(this.context.Provider, { value: context, children: /* @__PURE__ */ jsxRuntime.jsx(FormContainer, { ...formProps, form: this }) });
|
|
385
446
|
}
|
|
386
|
-
|
|
447
|
+
FormState({
|
|
387
448
|
selector,
|
|
388
449
|
children
|
|
389
450
|
}) {
|
|
@@ -404,7 +465,7 @@ function createForm(options) {
|
|
|
404
465
|
return new Form(options);
|
|
405
466
|
}
|
|
406
467
|
function read(cache, options) {
|
|
407
|
-
const { status, value, error } =
|
|
468
|
+
const { status, value, error } = scope.useCache(cache, options);
|
|
408
469
|
if (status === "value") {
|
|
409
470
|
return value;
|
|
410
471
|
}
|
|
@@ -438,7 +499,7 @@ function useDecoupledState(value, onChange, options = {}) {
|
|
|
438
499
|
setDirty({ v: value2 });
|
|
439
500
|
delayedUpdate(value2);
|
|
440
501
|
};
|
|
441
|
-
}, [
|
|
502
|
+
}, [hash.hash([options.debounce, options.throttle])]);
|
|
442
503
|
return [dirty ? dirty.v : value, update];
|
|
443
504
|
}
|
|
444
505
|
function castArray(value) {
|
|
@@ -458,15 +519,15 @@ function useUrlParamScope({
|
|
|
458
519
|
url[type] = parameters.toString();
|
|
459
520
|
window.history.replaceState(null, "", url.toString());
|
|
460
521
|
},
|
|
461
|
-
[
|
|
522
|
+
[hash.hash(key), type]
|
|
462
523
|
);
|
|
463
524
|
}
|
|
464
|
-
exports.ScopeProvider =
|
|
465
|
-
exports.reactMethods =
|
|
466
|
-
exports.useCache =
|
|
467
|
-
exports.useProp =
|
|
468
|
-
exports.useScope =
|
|
469
|
-
exports.useStore =
|
|
525
|
+
exports.ScopeProvider = scope.ScopeProvider;
|
|
526
|
+
exports.reactMethods = scope.reactMethods;
|
|
527
|
+
exports.useCache = scope.useCache;
|
|
528
|
+
exports.useProp = scope.useProp;
|
|
529
|
+
exports.useScope = scope.useScope;
|
|
530
|
+
exports.useStore = scope.useStore;
|
|
470
531
|
exports.Form = Form;
|
|
471
532
|
exports.createForm = createForm;
|
|
472
533
|
exports.read = read;
|