yuustate 3.9.0 → 3.10.1
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/esm/react/create-query.d.mts +1 -1
- package/esm/react/create-store.d.mts +1 -1
- package/esm/react/use-store.d.mts +1 -2
- package/esm/react.mjs +61 -36
- package/package.json +3 -3
- package/react/create-query.d.ts +1 -1
- package/react/create-store.d.ts +1 -1
- package/react/use-store.d.ts +1 -2
- package/react.js +60 -35
|
@@ -350,7 +350,7 @@ export declare const createQuery: <TData, TVariable extends StoreKey = never, TE
|
|
|
350
350
|
*/
|
|
351
351
|
initialDataIsStale?: boolean;
|
|
352
352
|
} | {
|
|
353
|
-
initialData?: never;
|
|
353
|
+
initialData?: never | undefined;
|
|
354
354
|
initialDataIsStale?: never;
|
|
355
355
|
})) => QueryState<TData, TError>) & {
|
|
356
356
|
setState: (value: SetStateInput<QueryState<TData, TError>>) => void;
|
|
@@ -31,5 +31,5 @@ export declare const createStore: <TState extends Record<string, any>>(initialSt
|
|
|
31
31
|
/**
|
|
32
32
|
* Initial state used on first render (and will also update the store state right after that)
|
|
33
33
|
*/
|
|
34
|
-
initialState?: Partial<TState
|
|
34
|
+
initialState?: Partial<TState> | undefined;
|
|
35
35
|
}) => TState) & import("../vanilla.d.mts").StoreApi<TState>;
|
|
@@ -4,7 +4,6 @@ export declare const getValueByPath: (obj: any, path: Path) => any;
|
|
|
4
4
|
export declare const isPrefixPath: (candidatePrefix: Path, targetPath: Path) => boolean;
|
|
5
5
|
export declare const compressPaths: (paths: Path[]) => Path[];
|
|
6
6
|
export declare const useStoreStateProxy: <TState extends Record<string, any>>(storeState: TState) => readonly [TState, import("react").RefObject<Path[]>];
|
|
7
|
-
export declare const NO_INITIAL_VALUE: {};
|
|
8
7
|
export declare const useStoreStateWithInitializer: <TState extends Record<string, any>>(store: StoreApi<TState>, initialState?: Partial<TState>) => readonly [TState, import("react").RefObject<WeakMap<StoreApi<TState>, number>>];
|
|
9
8
|
/**
|
|
10
9
|
* React hook for subscribing to a store using automatic dependency tracking.
|
|
@@ -29,6 +28,6 @@ export declare const useStoreStateWithInitializer: <TState extends Record<string
|
|
|
29
28
|
* // Component will only re-render if `user.name` changes
|
|
30
29
|
*/
|
|
31
30
|
export declare const useStoreState: <TState extends Record<string, any>>(store: StoreApi<TState>, options?: {
|
|
32
|
-
initialState?: Partial<TState
|
|
31
|
+
initialState?: Partial<TState> | undefined;
|
|
33
32
|
}) => TState;
|
|
34
33
|
export {};
|
package/esm/react.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useLayoutEffect, useEffect,
|
|
1
|
+
import { useLayoutEffect, useEffect, useRef, useSyncExternalStore, useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import { isClient, initStore, getHash, noop } from 'yuustate/vanilla';
|
|
3
3
|
|
|
4
4
|
const useIsomorphicLayoutEffect = isClient ? useLayoutEffect : useEffect;
|
|
@@ -49,34 +49,46 @@ const useStoreStateProxy = (storeState) => {
|
|
|
49
49
|
}, [storeState]);
|
|
50
50
|
return [trackedState, usedPathsRef];
|
|
51
51
|
};
|
|
52
|
-
const
|
|
53
|
-
const useStoreStateWithInitializer = (store, initialState = NO_INITIAL_VALUE) => {
|
|
52
|
+
const useStoreStateWithInitializer = (store, initialState) => {
|
|
54
53
|
const initiatedAt = useRef(new WeakMap([[store, 0]]));
|
|
55
54
|
useEffect(() => {
|
|
56
|
-
if (initialState ===
|
|
55
|
+
if (initialState === void 0 || initiatedAt.current.get(store)) return;
|
|
57
56
|
store.setState(initialState);
|
|
58
57
|
initiatedAt.current.set(store, Date.now());
|
|
59
58
|
}, [store, initialState]);
|
|
60
59
|
const storeState = store.getState();
|
|
61
|
-
const finalState = initialState ===
|
|
60
|
+
const finalState = initialState === void 0 || initiatedAt.current.get(store) ? storeState : { ...storeState, ...initialState };
|
|
62
61
|
return [finalState, initiatedAt];
|
|
63
62
|
};
|
|
64
63
|
const useStoreState = (store, options = {}) => {
|
|
65
64
|
const [state] = useStoreStateWithInitializer(store, options.initialState);
|
|
66
65
|
const [trackedState, usedPathsRef] = useStoreStateProxy(state);
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
66
|
+
const snapshotRef = useRef(store.getState());
|
|
67
|
+
const getSnapshot = () => snapshotRef.current;
|
|
68
|
+
useSyncExternalStore(
|
|
69
|
+
useCallback(
|
|
70
|
+
(onStoreChange) => {
|
|
71
|
+
return store.subscribe((nextState, prevState, changedKeys) => {
|
|
72
|
+
const paths = compressPaths(usedPathsRef.current);
|
|
73
|
+
for (const path of paths) {
|
|
74
|
+
const rootKey = path[0];
|
|
75
|
+
if (!changedKeys.includes(rootKey)) continue;
|
|
76
|
+
const prevVal = getValueByPath(prevState, path);
|
|
77
|
+
const nextVal = getValueByPath(nextState, path);
|
|
78
|
+
if (!Object.is(prevVal, nextVal)) {
|
|
79
|
+
snapshotRef.current = nextState;
|
|
80
|
+
return onStoreChange();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
// False positive (missing dependency: 'usedPathsRef'): usedPathsRef is a ref, no need to add to deps
|
|
86
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
87
|
+
[store]
|
|
88
|
+
),
|
|
89
|
+
getSnapshot,
|
|
90
|
+
getSnapshot
|
|
91
|
+
);
|
|
80
92
|
return trackedState;
|
|
81
93
|
};
|
|
82
94
|
|
|
@@ -413,14 +425,14 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
413
425
|
}
|
|
414
426
|
const useStore = (options2 = {}) => {
|
|
415
427
|
const {
|
|
416
|
-
initialData
|
|
428
|
+
initialData,
|
|
417
429
|
initialDataIsStale = false,
|
|
418
430
|
revalidateOnMount = true,
|
|
419
431
|
keepPreviousData
|
|
420
432
|
} = options2;
|
|
421
433
|
const [storeState, initialDataInitiatedAt] = useStoreStateWithInitializer(
|
|
422
434
|
store,
|
|
423
|
-
initialData ===
|
|
435
|
+
initialData === void 0 ? void 0 : {
|
|
424
436
|
state: "SUCCESS",
|
|
425
437
|
isSuccess: true,
|
|
426
438
|
data: initialData
|
|
@@ -444,22 +456,35 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
444
456
|
{ ...storeStateToBeUsed, isPending: true }
|
|
445
457
|
) : storeStateToBeUsed
|
|
446
458
|
);
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
459
|
+
const snapshotRef = useRef(store.getState());
|
|
460
|
+
const getSnapshot = () => snapshotRef.current;
|
|
461
|
+
useSyncExternalStore(
|
|
462
|
+
useCallback(
|
|
463
|
+
(onStoreChange) => {
|
|
464
|
+
return store.subscribe((nextState, prevState2, changedKeys) => {
|
|
465
|
+
if (prevState2.state === "INITIAL" && !prevState2.isPending && nextState.isPending && !nextState.isRetrying) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const paths = compressPaths(usedPathsRef.current);
|
|
469
|
+
for (const path of paths) {
|
|
470
|
+
const rootKey = path[0];
|
|
471
|
+
if (!changedKeys.includes(rootKey)) continue;
|
|
472
|
+
const prevVal = getValueByPath(prevState2, path);
|
|
473
|
+
const nextVal = getValueByPath(nextState, path);
|
|
474
|
+
if (!Object.is(prevVal, nextVal)) {
|
|
475
|
+
snapshotRef.current = nextState;
|
|
476
|
+
return onStoreChange();
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
},
|
|
481
|
+
// False positive (missing dependency: 'usedPathsRef'): usedPathsRef is a ref, no need to add to deps
|
|
482
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
483
|
+
[store]
|
|
484
|
+
),
|
|
485
|
+
getSnapshot,
|
|
486
|
+
getSnapshot
|
|
487
|
+
);
|
|
463
488
|
useEffect(() => {
|
|
464
489
|
if (revalidateOnMount !== false) {
|
|
465
490
|
if (!initialDataIsStale) {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "yuustate",
|
|
3
3
|
"description": "Lightweight unified state management for sync and async data.",
|
|
4
4
|
"private": false,
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.10.1",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"utilities",
|
|
8
8
|
"store",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
},
|
|
71
71
|
"packageManager": "pnpm@10.32.1",
|
|
72
72
|
"peerDependencies": {
|
|
73
|
-
"@types/react": ">=
|
|
74
|
-
"react": ">=
|
|
73
|
+
"@types/react": ">=18.0",
|
|
74
|
+
"react": ">=18.0"
|
|
75
75
|
},
|
|
76
76
|
"peerDependenciesMeta": {
|
|
77
77
|
"@types/react": {
|
package/react/create-query.d.ts
CHANGED
|
@@ -350,7 +350,7 @@ export declare const createQuery: <TData, TVariable extends StoreKey = never, TE
|
|
|
350
350
|
*/
|
|
351
351
|
initialDataIsStale?: boolean;
|
|
352
352
|
} | {
|
|
353
|
-
initialData?: never;
|
|
353
|
+
initialData?: never | undefined;
|
|
354
354
|
initialDataIsStale?: never;
|
|
355
355
|
})) => QueryState<TData, TError>) & {
|
|
356
356
|
setState: (value: SetStateInput<QueryState<TData, TError>>) => void;
|
package/react/create-store.d.ts
CHANGED
|
@@ -31,5 +31,5 @@ export declare const createStore: <TState extends Record<string, any>>(initialSt
|
|
|
31
31
|
/**
|
|
32
32
|
* Initial state used on first render (and will also update the store state right after that)
|
|
33
33
|
*/
|
|
34
|
-
initialState?: Partial<TState
|
|
34
|
+
initialState?: Partial<TState> | undefined;
|
|
35
35
|
}) => TState) & import("../vanilla.ts").StoreApi<TState>;
|
package/react/use-store.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ export declare const getValueByPath: (obj: any, path: Path) => any;
|
|
|
4
4
|
export declare const isPrefixPath: (candidatePrefix: Path, targetPath: Path) => boolean;
|
|
5
5
|
export declare const compressPaths: (paths: Path[]) => Path[];
|
|
6
6
|
export declare const useStoreStateProxy: <TState extends Record<string, any>>(storeState: TState) => readonly [TState, import("react").RefObject<Path[]>];
|
|
7
|
-
export declare const NO_INITIAL_VALUE: {};
|
|
8
7
|
export declare const useStoreStateWithInitializer: <TState extends Record<string, any>>(store: StoreApi<TState>, initialState?: Partial<TState>) => readonly [TState, import("react").RefObject<WeakMap<StoreApi<TState>, number>>];
|
|
9
8
|
/**
|
|
10
9
|
* React hook for subscribing to a store using automatic dependency tracking.
|
|
@@ -29,6 +28,6 @@ export declare const useStoreStateWithInitializer: <TState extends Record<string
|
|
|
29
28
|
* // Component will only re-render if `user.name` changes
|
|
30
29
|
*/
|
|
31
30
|
export declare const useStoreState: <TState extends Record<string, any>>(store: StoreApi<TState>, options?: {
|
|
32
|
-
initialState?: Partial<TState
|
|
31
|
+
initialState?: Partial<TState> | undefined;
|
|
33
32
|
}) => TState;
|
|
34
33
|
export {};
|
package/react.js
CHANGED
|
@@ -51,34 +51,46 @@ const useStoreStateProxy = (storeState) => {
|
|
|
51
51
|
}, [storeState]);
|
|
52
52
|
return [trackedState, usedPathsRef];
|
|
53
53
|
};
|
|
54
|
-
const
|
|
55
|
-
const useStoreStateWithInitializer = (store, initialState = NO_INITIAL_VALUE) => {
|
|
54
|
+
const useStoreStateWithInitializer = (store, initialState) => {
|
|
56
55
|
const initiatedAt = react.useRef(new WeakMap([[store, 0]]));
|
|
57
56
|
react.useEffect(() => {
|
|
58
|
-
if (initialState ===
|
|
57
|
+
if (initialState === void 0 || initiatedAt.current.get(store)) return;
|
|
59
58
|
store.setState(initialState);
|
|
60
59
|
initiatedAt.current.set(store, Date.now());
|
|
61
60
|
}, [store, initialState]);
|
|
62
61
|
const storeState = store.getState();
|
|
63
|
-
const finalState = initialState ===
|
|
62
|
+
const finalState = initialState === void 0 || initiatedAt.current.get(store) ? storeState : { ...storeState, ...initialState };
|
|
64
63
|
return [finalState, initiatedAt];
|
|
65
64
|
};
|
|
66
65
|
const useStoreState = (store, options = {}) => {
|
|
67
66
|
const [state] = useStoreStateWithInitializer(store, options.initialState);
|
|
68
67
|
const [trackedState, usedPathsRef] = useStoreStateProxy(state);
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
68
|
+
const snapshotRef = react.useRef(store.getState());
|
|
69
|
+
const getSnapshot = () => snapshotRef.current;
|
|
70
|
+
react.useSyncExternalStore(
|
|
71
|
+
react.useCallback(
|
|
72
|
+
(onStoreChange) => {
|
|
73
|
+
return store.subscribe((nextState, prevState, changedKeys) => {
|
|
74
|
+
const paths = compressPaths(usedPathsRef.current);
|
|
75
|
+
for (const path of paths) {
|
|
76
|
+
const rootKey = path[0];
|
|
77
|
+
if (!changedKeys.includes(rootKey)) continue;
|
|
78
|
+
const prevVal = getValueByPath(prevState, path);
|
|
79
|
+
const nextVal = getValueByPath(nextState, path);
|
|
80
|
+
if (!Object.is(prevVal, nextVal)) {
|
|
81
|
+
snapshotRef.current = nextState;
|
|
82
|
+
return onStoreChange();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
// False positive (missing dependency: 'usedPathsRef'): usedPathsRef is a ref, no need to add to deps
|
|
88
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
89
|
+
[store]
|
|
90
|
+
),
|
|
91
|
+
getSnapshot,
|
|
92
|
+
getSnapshot
|
|
93
|
+
);
|
|
82
94
|
return trackedState;
|
|
83
95
|
};
|
|
84
96
|
|
|
@@ -415,14 +427,14 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
415
427
|
}
|
|
416
428
|
const useStore = (options2 = {}) => {
|
|
417
429
|
const {
|
|
418
|
-
initialData
|
|
430
|
+
initialData,
|
|
419
431
|
initialDataIsStale = false,
|
|
420
432
|
revalidateOnMount = true,
|
|
421
433
|
keepPreviousData
|
|
422
434
|
} = options2;
|
|
423
435
|
const [storeState, initialDataInitiatedAt] = useStoreStateWithInitializer(
|
|
424
436
|
store,
|
|
425
|
-
initialData ===
|
|
437
|
+
initialData === void 0 ? void 0 : {
|
|
426
438
|
state: "SUCCESS",
|
|
427
439
|
isSuccess: true,
|
|
428
440
|
data: initialData
|
|
@@ -446,22 +458,35 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
446
458
|
{ ...storeStateToBeUsed, isPending: true }
|
|
447
459
|
) : storeStateToBeUsed
|
|
448
460
|
);
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
461
|
+
const snapshotRef = react.useRef(store.getState());
|
|
462
|
+
const getSnapshot = () => snapshotRef.current;
|
|
463
|
+
react.useSyncExternalStore(
|
|
464
|
+
react.useCallback(
|
|
465
|
+
(onStoreChange) => {
|
|
466
|
+
return store.subscribe((nextState, prevState2, changedKeys) => {
|
|
467
|
+
if (prevState2.state === "INITIAL" && !prevState2.isPending && nextState.isPending && !nextState.isRetrying) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
const paths = compressPaths(usedPathsRef.current);
|
|
471
|
+
for (const path of paths) {
|
|
472
|
+
const rootKey = path[0];
|
|
473
|
+
if (!changedKeys.includes(rootKey)) continue;
|
|
474
|
+
const prevVal = getValueByPath(prevState2, path);
|
|
475
|
+
const nextVal = getValueByPath(nextState, path);
|
|
476
|
+
if (!Object.is(prevVal, nextVal)) {
|
|
477
|
+
snapshotRef.current = nextState;
|
|
478
|
+
return onStoreChange();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
},
|
|
483
|
+
// False positive (missing dependency: 'usedPathsRef'): usedPathsRef is a ref, no need to add to deps
|
|
484
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
485
|
+
[store]
|
|
486
|
+
),
|
|
487
|
+
getSnapshot,
|
|
488
|
+
getSnapshot
|
|
489
|
+
);
|
|
465
490
|
react.useEffect(() => {
|
|
466
491
|
if (revalidateOnMount !== false) {
|
|
467
492
|
if (!initialDataIsStale) {
|