juststore 0.4.2 → 0.4.3
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/form.d.ts +17 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mixed_state.js +15 -1
- package/package.json +1 -1
package/dist/form.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FieldPath, FieldPathValue, FieldValues, IsEqual } from './path';
|
|
2
|
-
import type { ArrayProxy, DerivedStateProps, IsNullable, MaybeNullable, ObjectMutationMethods, ValueState } from './types';
|
|
2
|
+
import type { ArrayProxy, DerivedStateProps, IsNullable, MaybeNullable, ObjectMutationMethods, Prettify, ValueState } from './types';
|
|
3
3
|
export { createForm, useForm, type CreateFormOptions, type DeepNonNullable, type FormArrayState, type FormObjectState, type FormState, type FormStore, type FormValueState };
|
|
4
4
|
/**
|
|
5
5
|
* Common form field methods available on every form state node.
|
|
@@ -13,7 +13,12 @@ type FormCommon = {
|
|
|
13
13
|
setError: (error: string | undefined) => void;
|
|
14
14
|
};
|
|
15
15
|
type FormState<T> = IsEqual<T, unknown> extends true ? never : [NonNullable<T>] extends [readonly (infer U)[]] ? FormArrayState<U, IsNullable<T>> : [NonNullable<T>] extends [FieldValues] ? FormObjectState<NonNullable<T>, IsNullable<T>> : FormValueState<T>;
|
|
16
|
-
|
|
16
|
+
type FormReadOnlyState<T> = Prettify<Pick<FormValueState<Readonly<Required<T>>>, 'value' | 'use' | 'useCompute' | 'Render' | 'Show' | 'error' | 'setError'>>;
|
|
17
|
+
interface FormValueState<T> extends Omit<ValueState<T>, 'ensureArray' | 'ensureObject' | 'withDefault' | 'derived'>, FormCommon {
|
|
18
|
+
/** Ensure the value is an array. */
|
|
19
|
+
ensureArray(): NonNullable<T> extends (infer U)[] ? FormArrayState<U> : never;
|
|
20
|
+
/** Ensure the value is an object. */
|
|
21
|
+
ensureObject(): NonNullable<T> extends FieldValues ? FormObjectState<NonNullable<T>> : never;
|
|
17
22
|
/** Return a new state with a default value, and make the type non-nullable */
|
|
18
23
|
withDefault(defaultValue: T): FormState<NonNullable<T>>;
|
|
19
24
|
/** Virtual state derived from the current value.
|
|
@@ -30,10 +35,17 @@ interface FormValueState<T> extends Omit<ValueState<T>, 'withDefault' | 'derived
|
|
|
30
35
|
*/
|
|
31
36
|
derived: <R>({ from, to }: DerivedStateProps<T, R>) => FormState<R>;
|
|
32
37
|
}
|
|
33
|
-
type
|
|
34
|
-
|
|
38
|
+
type FormObjectProxy<T extends FieldValues> = {
|
|
39
|
+
/** Virtual state for the object's keys.
|
|
40
|
+
*
|
|
41
|
+
* This does NOT read from a real `keys` property on the stored object; it results in a stable array of keys.
|
|
42
|
+
*/
|
|
43
|
+
readonly keys: FormReadOnlyState<FieldPath<T>[]>;
|
|
44
|
+
} & {
|
|
35
45
|
[K in keyof T]-?: FormState<T[K]>;
|
|
36
|
-
}
|
|
46
|
+
};
|
|
47
|
+
type FormArrayState<T, Nullable extends boolean = false> = IsEqual<T, unknown> extends true ? never : FormValueState<MaybeNullable<T[], Nullable>> & ArrayProxy<T, FormState<T>>;
|
|
48
|
+
type FormObjectState<T extends FieldValues, Nullable extends boolean = false> = FormObjectProxy<T> & FormValueState<MaybeNullable<T, Nullable>> & ObjectMutationMethods;
|
|
37
49
|
/** Type for nested objects with proxy methods */
|
|
38
50
|
type DeepNonNullable<T> = [NonNullable<T>] extends [readonly (infer U)[]] ? U[] : [NonNullable<T>] extends [FieldValues] ? {
|
|
39
51
|
[K in keyof NonNullable<T>]-?: DeepNonNullable<NonNullable<T>[K]>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { createAtom, type Atom } from './atom';
|
|
2
2
|
export type * from './form';
|
|
3
3
|
export { useForm } from './form';
|
|
4
|
+
export { isEqual } from './impl';
|
|
4
5
|
export { createMemoryStore, useMemoryStore, type MemoryStore } from './memory';
|
|
5
6
|
export { createMixedState } from './mixed_state';
|
|
6
7
|
export type * from './path';
|
package/dist/index.js
CHANGED
package/dist/mixed_state.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { isEqual } from './impl';
|
|
1
3
|
export { createMixedState };
|
|
2
4
|
/**
|
|
3
5
|
* Creates a mixed state that combines multiple states into a tuple.
|
|
@@ -22,7 +24,19 @@ function createMixedState(...states) {
|
|
|
22
24
|
},
|
|
23
25
|
use,
|
|
24
26
|
useCompute(fn) {
|
|
25
|
-
|
|
27
|
+
const [value, setValue] = useState(fn(this.value));
|
|
28
|
+
const recompute = useCallback(() => {
|
|
29
|
+
const newValue = fn(this.value);
|
|
30
|
+
// skip update if the new value is the same as the previous value
|
|
31
|
+
setValue(prev => (isEqual(prev, newValue) ? prev : newValue));
|
|
32
|
+
}, [fn]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const unsubscribeFns = states.map(state => state.subscribe(recompute));
|
|
35
|
+
return () => {
|
|
36
|
+
unsubscribeFns.forEach(unsubscribe => unsubscribe());
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
return value;
|
|
26
40
|
},
|
|
27
41
|
Render({ children }) {
|
|
28
42
|
const value = use();
|