recoil-next 0.3.0 → 0.4.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/README.md +5 -5
- package/dist/index.cjs +81 -51
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.mjs +81 -51
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ npm install recoil-next
|
|
|
22
22
|
|
|
23
23
|
```jsx
|
|
24
24
|
import React from 'react';
|
|
25
|
-
import {
|
|
25
|
+
import {RecoilRoot, atom, useRecoilState} from 'recoil-next';
|
|
26
26
|
|
|
27
27
|
const textState = atom({
|
|
28
28
|
key: 'textState',
|
|
@@ -42,7 +42,7 @@ function CharacterCounter() {
|
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
44
|
<div>
|
|
45
|
-
<input type="text" value={text} onChange={
|
|
45
|
+
<input type="text" value={text} onChange={e => setText(e.target.value)} />
|
|
46
46
|
<p>Character count: {text.length}</p>
|
|
47
47
|
</div>
|
|
48
48
|
);
|
|
@@ -70,10 +70,10 @@ This library is a drop-in replacement for the original Recoil library. Simply re
|
|
|
70
70
|
|
|
71
71
|
```jsx
|
|
72
72
|
// Before
|
|
73
|
-
import {
|
|
73
|
+
import {RecoilRoot, atom, useRecoilState} from 'recoil';
|
|
74
74
|
|
|
75
75
|
// After
|
|
76
|
-
import {
|
|
76
|
+
import {RecoilRoot, atom, useRecoilState} from 'recoil-next';
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
## Requirements
|
|
@@ -90,4 +90,4 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
90
90
|
|
|
91
91
|
## Community
|
|
92
92
|
|
|
93
|
-
This is a community-maintained continuation of the original Recoil project. We aim to maintain compatibility while adding new features and improvements.
|
|
93
|
+
This is a community-maintained continuation of the original Recoil project. We aim to maintain compatibility while adding new features and improvements.
|
package/dist/index.cjs
CHANGED
|
@@ -13,7 +13,9 @@ function err(message) {
|
|
|
13
13
|
try {
|
|
14
14
|
throw error;
|
|
15
15
|
}
|
|
16
|
-
catch (_) {
|
|
16
|
+
catch (_) {
|
|
17
|
+
/* T-ignore */
|
|
18
|
+
}
|
|
17
19
|
}
|
|
18
20
|
return error;
|
|
19
21
|
}
|
|
@@ -114,7 +116,8 @@ class BaseLoadable {
|
|
|
114
116
|
throw err(`Loadable expected error, but in "${this.state}" state`);
|
|
115
117
|
}
|
|
116
118
|
is(other) {
|
|
117
|
-
return other.state === this.state &&
|
|
119
|
+
return (other.state === this.state &&
|
|
120
|
+
Object.is(other.contents, this.contents));
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
123
|
class ValueLoadable extends BaseLoadable {
|
|
@@ -824,7 +827,6 @@ const getNextComponentID = () => nextComponentID++;
|
|
|
824
827
|
/** React mode and feature detection helpers */
|
|
825
828
|
var _a;
|
|
826
829
|
// Access either useSyncExternalStore or unstable_useSyncExternalStore depending on React version.
|
|
827
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
828
830
|
const useSyncExternalStore =
|
|
829
831
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
830
832
|
(_a = React.useSyncExternalStore) !== null && _a !== void 0 ? _a :
|
|
@@ -835,14 +837,17 @@ let ReactRendererVersionMismatchWarnOnce = false;
|
|
|
835
837
|
function currentRendererSupportsUseSyncExternalStore() {
|
|
836
838
|
var _a;
|
|
837
839
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
838
|
-
const internals = React
|
|
840
|
+
const internals = React
|
|
841
|
+
.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
839
842
|
if (!internals)
|
|
840
843
|
return false;
|
|
841
844
|
const { ReactCurrentDispatcher, ReactCurrentOwner } = internals;
|
|
842
845
|
// The dispatcher can be on ReactCurrentDispatcher.current (newer) or ReactCurrentOwner.currentDispatcher (older)
|
|
843
846
|
const dispatcher = (_a = ReactCurrentDispatcher === null || ReactCurrentDispatcher === void 0 ? void 0 : ReactCurrentDispatcher.current) !== null && _a !== void 0 ? _a : ReactCurrentOwner === null || ReactCurrentOwner === void 0 ? void 0 : ReactCurrentOwner.currentDispatcher;
|
|
844
847
|
const isSupported = (dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.useSyncExternalStore) != null;
|
|
845
|
-
if (useSyncExternalStore !== undefined &&
|
|
848
|
+
if (useSyncExternalStore !== undefined &&
|
|
849
|
+
!isSupported &&
|
|
850
|
+
!ReactRendererVersionMismatchWarnOnce) {
|
|
846
851
|
ReactRendererVersionMismatchWarnOnce = true;
|
|
847
852
|
recoverableViolation('A React renderer without React 18+ API support is being used with React 18+.');
|
|
848
853
|
}
|
|
@@ -893,7 +898,8 @@ writes) {
|
|
|
893
898
|
return result;
|
|
894
899
|
}
|
|
895
900
|
function writeLoadableToTreeState(state, key, loadable) {
|
|
896
|
-
if (loadable.state === 'hasValue' &&
|
|
901
|
+
if (loadable.state === 'hasValue' &&
|
|
902
|
+
loadable.contents instanceof DefaultValue) {
|
|
897
903
|
state.atomValues.delete(key);
|
|
898
904
|
}
|
|
899
905
|
else {
|
|
@@ -929,7 +935,8 @@ function notifyComponents$2(store, treeState) {
|
|
|
929
935
|
}
|
|
930
936
|
}
|
|
931
937
|
function valueFromValueOrUpdater(store, state, recoilValue, valueOrUpdater) {
|
|
932
|
-
if (typeof valueOrUpdater === 'function' &&
|
|
938
|
+
if (typeof valueOrUpdater === 'function' &&
|
|
939
|
+
valueOrUpdater !== DEFAULT_VALUE) {
|
|
933
940
|
// Updater form: pass in the current value
|
|
934
941
|
const current = getRecoilValueAsLoadable(store, recoilValue, state);
|
|
935
942
|
if (current.state === 'loading') {
|
|
@@ -2382,8 +2389,7 @@ function* concatIterables(iters) {
|
|
|
2382
2389
|
* TypeScript port of Recoil_Environment.js
|
|
2383
2390
|
*/
|
|
2384
2391
|
const isSSR = typeof window === 'undefined';
|
|
2385
|
-
const isWindow = (value) => !isSSR &&
|
|
2386
|
-
(value === window || value instanceof Window);
|
|
2392
|
+
const isWindow = (value) => !isSSR && (value === window || value instanceof Window);
|
|
2387
2393
|
const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
2388
2394
|
|
|
2389
2395
|
/**
|
|
@@ -2453,7 +2459,8 @@ class Snapshot {
|
|
|
2453
2459
|
? recoilValues.values()
|
|
2454
2460
|
: opt.isInitialized === true
|
|
2455
2461
|
? recoilValuesForKeys(concatIterables([knownAtoms, knownSelectors]))
|
|
2456
|
-
: filterIterable(recoilValues.values(),
|
|
2462
|
+
: filterIterable(recoilValues.values(), recoilValue => !knownAtoms.has(recoilValue.key) &&
|
|
2463
|
+
!knownSelectors.has(recoilValue.key));
|
|
2457
2464
|
};
|
|
2458
2465
|
// Report the current status of a node.
|
|
2459
2466
|
// This peeks the current state and does not affect the snapshot state at all
|
|
@@ -2618,10 +2625,7 @@ function cloneStoreState(store, treeState, bumpVersion = false) {
|
|
|
2618
2625
|
// FIXME here's a copy
|
|
2619
2626
|
// Create blank cleanup handlers for atoms so snapshots don't re-run
|
|
2620
2627
|
// atom effects.
|
|
2621
|
-
nodeCleanupFunctions: new Map(mapIterable(storeState.nodeCleanupFunctions.entries(), ([key]) => [
|
|
2622
|
-
key,
|
|
2623
|
-
() => { },
|
|
2624
|
-
])),
|
|
2628
|
+
nodeCleanupFunctions: new Map(mapIterable(storeState.nodeCleanupFunctions.entries(), ([key]) => [key, () => { }])),
|
|
2625
2629
|
};
|
|
2626
2630
|
}
|
|
2627
2631
|
// Factory to build a fresh snapshot
|
|
@@ -2634,7 +2638,7 @@ const [memoizedCloneSnapshot, invalidateMemoizedSnapshot] = memoizeOneWithArgsHa
|
|
|
2634
2638
|
var _a;
|
|
2635
2639
|
const storeState = store.getState();
|
|
2636
2640
|
const treeState = version === 'latest'
|
|
2637
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
2641
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
2638
2642
|
: nullthrows(storeState.previousTree);
|
|
2639
2643
|
return new Snapshot(cloneStoreState(store, treeState), store.storeID);
|
|
2640
2644
|
}, (store, version) => {
|
|
@@ -2652,7 +2656,7 @@ function cloneSnapshot(store, version = 'latest') {
|
|
|
2652
2656
|
if (process.env.NODE_ENV === 'test') {
|
|
2653
2657
|
const storeState = store.getState();
|
|
2654
2658
|
const treeState = version === 'latest'
|
|
2655
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
2659
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
2656
2660
|
: nullthrows(storeState.previousTree);
|
|
2657
2661
|
return new Snapshot(cloneStoreState(store, treeState), store.storeID);
|
|
2658
2662
|
}
|
|
@@ -2666,7 +2670,9 @@ function cloneSnapshot(store, version = 'latest') {
|
|
|
2666
2670
|
}
|
|
2667
2671
|
catch (retainError) {
|
|
2668
2672
|
// If checking isRetained() fails, assume it's released and create fresh
|
|
2669
|
-
if (retainError &&
|
|
2673
|
+
if (retainError &&
|
|
2674
|
+
typeof retainError === 'object' &&
|
|
2675
|
+
'message' in retainError &&
|
|
2670
2676
|
typeof retainError.message === 'string' &&
|
|
2671
2677
|
retainError.message.includes('already been released')) {
|
|
2672
2678
|
invalidateMemoizedSnapshot();
|
|
@@ -2678,7 +2684,9 @@ function cloneSnapshot(store, version = 'latest') {
|
|
|
2678
2684
|
}
|
|
2679
2685
|
catch (error) {
|
|
2680
2686
|
// If the memoized snapshot was released, create a fresh one
|
|
2681
|
-
if (error &&
|
|
2687
|
+
if (error &&
|
|
2688
|
+
typeof error === 'object' &&
|
|
2689
|
+
'message' in error &&
|
|
2682
2690
|
typeof error.message === 'string' &&
|
|
2683
2691
|
error.message.includes('already been released')) {
|
|
2684
2692
|
invalidateMemoizedSnapshot();
|
|
@@ -3229,7 +3237,7 @@ function useRecoilValueLoadable_SYNC_EXTERNAL_STORE(recoilValue) {
|
|
|
3229
3237
|
const store = storeRef.current;
|
|
3230
3238
|
const storeState = store.getState();
|
|
3231
3239
|
const treeState = reactMode().early
|
|
3232
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
3240
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
3233
3241
|
: storeState.currentTree;
|
|
3234
3242
|
const loadable = getRecoilValueAsLoadable(store, recoilValue, treeState);
|
|
3235
3243
|
return { loadable, key: recoilValue.key };
|
|
@@ -3253,7 +3261,7 @@ function useRecoilValueLoadable_SYNC_EXTERNAL_STORE(recoilValue) {
|
|
|
3253
3261
|
if (Recoil_gkx_OSS('recoil_memory_managament_2020')) {
|
|
3254
3262
|
updateRetainCount(store, recoilValue.key, 1);
|
|
3255
3263
|
}
|
|
3256
|
-
const subscription = subscribeToRecoilValue(store, recoilValue,
|
|
3264
|
+
const subscription = subscribeToRecoilValue(store, recoilValue, _treeState => notify());
|
|
3257
3265
|
return () => {
|
|
3258
3266
|
// Release retention when subscription is released
|
|
3259
3267
|
if (Recoil_gkx_OSS('recoil_memory_managament_2020')) {
|
|
@@ -3266,7 +3274,8 @@ function useRecoilValueLoadable_SYNC_EXTERNAL_STORE(recoilValue) {
|
|
|
3266
3274
|
if (React.useSyncExternalStore === undefined) {
|
|
3267
3275
|
throw new Error('useSyncExternalStore is not available in this version of React');
|
|
3268
3276
|
}
|
|
3269
|
-
return React.useSyncExternalStore(subscribe, getMemoizedSnapshot, () => ssrSnapshot)
|
|
3277
|
+
return React.useSyncExternalStore(subscribe, getMemoizedSnapshot, () => ssrSnapshot)
|
|
3278
|
+
.loadable;
|
|
3270
3279
|
}
|
|
3271
3280
|
function useRecoilValueLoadable_TRANSITION_SUPPORT(recoilValue) {
|
|
3272
3281
|
const storeRef = useStoreRef();
|
|
@@ -3276,7 +3285,7 @@ function useRecoilValueLoadable_TRANSITION_SUPPORT(recoilValue) {
|
|
|
3276
3285
|
const store = storeRef.current;
|
|
3277
3286
|
const storeState = store.getState();
|
|
3278
3287
|
const treeState = reactMode().early
|
|
3279
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
3288
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
3280
3289
|
: storeState.currentTree;
|
|
3281
3290
|
return getRecoilValueAsLoadable(store, recoilValue, treeState);
|
|
3282
3291
|
}, [storeRef, recoilValue]);
|
|
@@ -3307,7 +3316,7 @@ function useRecoilValueLoadable_LEGACY(recoilValue) {
|
|
|
3307
3316
|
const store = storeRef.current;
|
|
3308
3317
|
const storeState = store.getState();
|
|
3309
3318
|
const treeState = reactMode().early
|
|
3310
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
3319
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
3311
3320
|
: storeState.currentTree;
|
|
3312
3321
|
return getRecoilValueAsLoadable(store, recoilValue, treeState);
|
|
3313
3322
|
}, [storeRef, recoilValue]);
|
|
@@ -3448,7 +3457,9 @@ function useTransactionSubscription(callback) {
|
|
|
3448
3457
|
}
|
|
3449
3458
|
catch (error) {
|
|
3450
3459
|
// In React 19, snapshots can fail more aggressively
|
|
3451
|
-
if (error &&
|
|
3460
|
+
if (error &&
|
|
3461
|
+
typeof error === 'object' &&
|
|
3462
|
+
'message' in error &&
|
|
3452
3463
|
typeof error.message === 'string' &&
|
|
3453
3464
|
error.message.includes('already been released')) {
|
|
3454
3465
|
console.warn('Snapshot already released in transaction subscription, skipping');
|
|
@@ -3482,7 +3493,9 @@ function useRecoilSnapshot() {
|
|
|
3482
3493
|
catch (error) {
|
|
3483
3494
|
// In React 19, snapshots can be released more aggressively
|
|
3484
3495
|
// If the snapshot was already released, create a fresh one
|
|
3485
|
-
if (error &&
|
|
3496
|
+
if (error &&
|
|
3497
|
+
typeof error === 'object' &&
|
|
3498
|
+
'message' in error &&
|
|
3486
3499
|
typeof error.message === 'string' &&
|
|
3487
3500
|
error.message.includes('already been released')) {
|
|
3488
3501
|
console.warn('Snapshot already released during initial state, creating fresh snapshot');
|
|
@@ -3501,7 +3514,9 @@ function useRecoilSnapshot() {
|
|
|
3501
3514
|
catch (error) {
|
|
3502
3515
|
// In React 19, snapshots can be released more aggressively
|
|
3503
3516
|
// If the snapshot was already released, skip this update
|
|
3504
|
-
if (error &&
|
|
3517
|
+
if (error &&
|
|
3518
|
+
typeof error === 'object' &&
|
|
3519
|
+
'message' in error &&
|
|
3505
3520
|
typeof error.message === 'string' &&
|
|
3506
3521
|
error.message.includes('already been released')) {
|
|
3507
3522
|
console.warn('Snapshot already released during transaction subscription, skipping update');
|
|
@@ -3519,7 +3534,9 @@ function useRecoilSnapshot() {
|
|
|
3519
3534
|
}
|
|
3520
3535
|
catch (error) {
|
|
3521
3536
|
// If snapshot retention fails, skip this effect
|
|
3522
|
-
if (error &&
|
|
3537
|
+
if (error &&
|
|
3538
|
+
typeof error === 'object' &&
|
|
3539
|
+
'message' in error &&
|
|
3523
3540
|
typeof error.message === 'string' &&
|
|
3524
3541
|
error.message.includes('already been released')) {
|
|
3525
3542
|
console.warn('Cannot retain snapshot in useEffect, already released');
|
|
@@ -3560,7 +3577,9 @@ function useRecoilSnapshot() {
|
|
|
3560
3577
|
}
|
|
3561
3578
|
catch (error) {
|
|
3562
3579
|
// If snapshot retention fails, skip this retention
|
|
3563
|
-
if (error &&
|
|
3580
|
+
if (error &&
|
|
3581
|
+
typeof error === 'object' &&
|
|
3582
|
+
'message' in error &&
|
|
3564
3583
|
typeof error.message === 'string' &&
|
|
3565
3584
|
error.message.includes('already been released')) {
|
|
3566
3585
|
console.warn('Cannot retain snapshot in render, already released');
|
|
@@ -3608,7 +3627,10 @@ function gotoSnapshot(store, snapshot) {
|
|
|
3608
3627
|
newTree.stateID = snapshot.getID();
|
|
3609
3628
|
const atomKeysChanged = new Set();
|
|
3610
3629
|
// Update atoms that should be restored from snapshots
|
|
3611
|
-
for (const key of new Set([
|
|
3630
|
+
for (const key of new Set([
|
|
3631
|
+
...prev.atomValues.keys(),
|
|
3632
|
+
...next.atomValues.keys(),
|
|
3633
|
+
])) {
|
|
3612
3634
|
const node = getNode(key);
|
|
3613
3635
|
if (!node.shouldRestoreFromSnapshots)
|
|
3614
3636
|
continue;
|
|
@@ -3619,7 +3641,9 @@ function gotoSnapshot(store, snapshot) {
|
|
|
3619
3641
|
const loadable = next.atomValues.has(key)
|
|
3620
3642
|
? nullthrows(next.atomValues.get(key))
|
|
3621
3643
|
: loadableWithValue(DEFAULT_VALUE);
|
|
3622
|
-
if (loadable &&
|
|
3644
|
+
if (loadable &&
|
|
3645
|
+
loadable.state === 'hasValue' &&
|
|
3646
|
+
loadable.contents === DEFAULT_VALUE) {
|
|
3623
3647
|
newTree.atomValues.delete(key);
|
|
3624
3648
|
}
|
|
3625
3649
|
else {
|
|
@@ -3656,7 +3680,6 @@ function useGetRecoilValueInfo() {
|
|
|
3656
3680
|
function useRecoilBridgeAcrossReactRoots() {
|
|
3657
3681
|
const store = useStoreRef().current;
|
|
3658
3682
|
return React.useMemo(() => {
|
|
3659
|
-
// eslint-disable-next-line no-shadow
|
|
3660
3683
|
function RecoilBridge({ children }) {
|
|
3661
3684
|
return jsxRuntime.jsx(RecoilRoot, { store: store, children: children });
|
|
3662
3685
|
}
|
|
@@ -3785,7 +3808,7 @@ function recoilCallback(store, fn, args, extraInterface) {
|
|
|
3785
3808
|
// For all other methods, delegate to target
|
|
3786
3809
|
const value = target[prop];
|
|
3787
3810
|
return typeof value === 'function' ? value.bind(target) : value;
|
|
3788
|
-
}
|
|
3811
|
+
},
|
|
3789
3812
|
});
|
|
3790
3813
|
return hybridSnapshot;
|
|
3791
3814
|
},
|
|
@@ -3822,7 +3845,6 @@ function useRecoilCallback(fn, deps) {
|
|
|
3822
3845
|
},
|
|
3823
3846
|
// Don't include storeRef in deps to avoid unnecessary re-creation
|
|
3824
3847
|
// The store reference should be stable within a RecoilRoot
|
|
3825
|
-
// eslint-disable-next-line fb-www/react-hooks-deps
|
|
3826
3848
|
deps !== null && deps !== void 0 ? deps : []);
|
|
3827
3849
|
}
|
|
3828
3850
|
|
|
@@ -3867,7 +3889,7 @@ function isNode(object) {
|
|
|
3867
3889
|
if (typeof window === 'undefined') {
|
|
3868
3890
|
return false;
|
|
3869
3891
|
}
|
|
3870
|
-
const doc = object != null ? (_a = object.ownerDocument) !== null && _a !== void 0 ? _a : document : document;
|
|
3892
|
+
const doc = object != null ? ((_a = object.ownerDocument) !== null && _a !== void 0 ? _a : document) : document;
|
|
3871
3893
|
const defaultView = (_b = doc.defaultView) !== null && _b !== void 0 ? _b : window;
|
|
3872
3894
|
return !!(object != null &&
|
|
3873
3895
|
(typeof defaultView.Node === 'function'
|
|
@@ -3981,7 +4003,8 @@ function stringify(x, opt, key, visited = new Set()) {
|
|
|
3981
4003
|
if (x instanceof Map) {
|
|
3982
4004
|
const obj = {};
|
|
3983
4005
|
for (const [k, v] of x) {
|
|
3984
|
-
obj[typeof k === 'string' ? k : stringify(k, opt, undefined, visited)] =
|
|
4006
|
+
obj[typeof k === 'string' ? k : stringify(k, opt, undefined, visited)] =
|
|
4007
|
+
v;
|
|
3985
4008
|
}
|
|
3986
4009
|
const result = stringify(obj, opt, key, visited);
|
|
3987
4010
|
visited.delete(x);
|
|
@@ -4113,7 +4136,7 @@ class TreeCache {
|
|
|
4113
4136
|
// Second, setup the leaf node:
|
|
4114
4137
|
// If there is an existing leaf for this route confirm it is consistent
|
|
4115
4138
|
const oldLeaf = node
|
|
4116
|
-
? (_d = node.branches.get(branchKey)) !== null && _d !== void 0 ? _d : null
|
|
4139
|
+
? ((_d = node.branches.get(branchKey)) !== null && _d !== void 0 ? _d : null)
|
|
4117
4140
|
: this._root;
|
|
4118
4141
|
if (oldLeaf != null &&
|
|
4119
4142
|
(oldLeaf.type !== 'leaf' || oldLeaf.branchKey !== branchKey)) {
|
|
@@ -4339,9 +4362,11 @@ const defaultPolicy$1 = {
|
|
|
4339
4362
|
maxSize: Infinity,
|
|
4340
4363
|
};
|
|
4341
4364
|
function treeCacheFromPolicy(policy = defaultPolicy$1, name) {
|
|
4342
|
-
const { equality = defaultPolicy$1.equality
|
|
4365
|
+
const { equality = defaultPolicy$1.equality } = policy;
|
|
4343
4366
|
const eviction = 'eviction' in policy ? policy.eviction : 'keep-all';
|
|
4344
|
-
const maxSize = 'maxSize' in policy && policy.eviction === 'lru'
|
|
4367
|
+
const maxSize = 'maxSize' in policy && policy.eviction === 'lru'
|
|
4368
|
+
? policy.maxSize
|
|
4369
|
+
: defaultPolicy$1.maxSize;
|
|
4345
4370
|
const valueMapper = getValueMapper$1(equality);
|
|
4346
4371
|
return getTreeCache(eviction, maxSize, valueMapper, name);
|
|
4347
4372
|
}
|
|
@@ -4644,8 +4669,7 @@ function selector(options) {
|
|
|
4644
4669
|
});
|
|
4645
4670
|
}
|
|
4646
4671
|
catch (error) {
|
|
4647
|
-
throw err(`Problem with cache lookup for selector "${key}": ${error
|
|
4648
|
-
.message}`);
|
|
4672
|
+
throw err(`Problem with cache lookup for selector "${key}": ${error.message}`);
|
|
4649
4673
|
}
|
|
4650
4674
|
if (cachedLoadable) {
|
|
4651
4675
|
state.atomValues.set(key, cachedLoadable);
|
|
@@ -4750,8 +4774,7 @@ function selector(options) {
|
|
|
4750
4774
|
cache.set(depValuesToDepRoute(depValues), loadable);
|
|
4751
4775
|
}
|
|
4752
4776
|
catch (error) {
|
|
4753
|
-
throw err(`Problem with setting cache for selector "${key}": ${error
|
|
4754
|
-
.message}`);
|
|
4777
|
+
throw err(`Problem with setting cache for selector "${key}": ${error.message}`);
|
|
4755
4778
|
}
|
|
4756
4779
|
}
|
|
4757
4780
|
function detectCircularDependencies(fn) {
|
|
@@ -5047,7 +5070,8 @@ function baseAtom(options) {
|
|
|
5047
5070
|
var _a;
|
|
5048
5071
|
const { release } = store.subscribeToTransactions(currentStore => {
|
|
5049
5072
|
var _a, _b;
|
|
5050
|
-
let {
|
|
5073
|
+
let { previousTree } = currentStore.getState();
|
|
5074
|
+
const { currentTree } = currentStore.getState();
|
|
5051
5075
|
if (!previousTree) {
|
|
5052
5076
|
recoverableViolation('Transaction subscribers notified without a next tree being present -- this is a bug in Recoil');
|
|
5053
5077
|
previousTree = currentTree;
|
|
@@ -5147,7 +5171,9 @@ function baseAtom(options) {
|
|
|
5147
5171
|
function setAtom(_store, state, newValue) {
|
|
5148
5172
|
if (state.atomValues.has(key)) {
|
|
5149
5173
|
const existing = state.atomValues.get(key);
|
|
5150
|
-
if (existing &&
|
|
5174
|
+
if (existing &&
|
|
5175
|
+
existing.state === 'hasValue' &&
|
|
5176
|
+
newValue === existing.contents) {
|
|
5151
5177
|
return new Map();
|
|
5152
5178
|
}
|
|
5153
5179
|
}
|
|
@@ -5262,9 +5288,11 @@ const defaultPolicy = {
|
|
|
5262
5288
|
maxSize: Infinity,
|
|
5263
5289
|
};
|
|
5264
5290
|
function cacheFromPolicy(policy = defaultPolicy) {
|
|
5265
|
-
const { equality = defaultPolicy.equality
|
|
5291
|
+
const { equality = defaultPolicy.equality } = policy;
|
|
5266
5292
|
const eviction = 'eviction' in policy ? policy.eviction : 'keep-all';
|
|
5267
|
-
const maxSize = 'maxSize' in policy && policy.eviction === 'lru'
|
|
5293
|
+
const maxSize = 'maxSize' in policy && policy.eviction === 'lru'
|
|
5294
|
+
? policy.maxSize
|
|
5295
|
+
: defaultPolicy.maxSize;
|
|
5268
5296
|
const valueMapper = getValueMapper(equality);
|
|
5269
5297
|
const cache = getCache(eviction, maxSize, valueMapper);
|
|
5270
5298
|
return cache;
|
|
@@ -5283,7 +5311,10 @@ function getCache(eviction, maxSize, mapKey) {
|
|
|
5283
5311
|
case 'keep-all':
|
|
5284
5312
|
return new MapCache({ mapKey: mapKey });
|
|
5285
5313
|
case 'lru':
|
|
5286
|
-
return new LRUCache({
|
|
5314
|
+
return new LRUCache({
|
|
5315
|
+
mapKey: mapKey,
|
|
5316
|
+
maxSize: nullthrows(maxSize),
|
|
5317
|
+
});
|
|
5287
5318
|
case 'most-recent':
|
|
5288
5319
|
return new LRUCache({ mapKey: mapKey, maxSize: 1 });
|
|
5289
5320
|
}
|
|
@@ -5317,7 +5348,7 @@ function atomFamily(options) {
|
|
|
5317
5348
|
? options.effects(params)
|
|
5318
5349
|
: typeof options.effects_UNSTABLE === 'function'
|
|
5319
5350
|
? options.effects_UNSTABLE(params)
|
|
5320
|
-
: (_b = options.effects) !== null && _b !== void 0 ? _b : options.effects_UNSTABLE }));
|
|
5351
|
+
: ((_b = options.effects) !== null && _b !== void 0 ? _b : options.effects_UNSTABLE) }));
|
|
5321
5352
|
atomCache.set(params, newAtom);
|
|
5322
5353
|
setConfigDeletionHandler(newAtom.key, () => {
|
|
5323
5354
|
atomCache.delete(params);
|
|
@@ -5544,7 +5575,7 @@ const waitForAllSettled = selectorFamily({
|
|
|
5544
5575
|
if (exceptions.every(exp => !isPromise(exp))) {
|
|
5545
5576
|
return wrapLoadables(dependencies, results, exceptions);
|
|
5546
5577
|
}
|
|
5547
|
-
return
|
|
5578
|
+
return Promise.all(exceptions.map((exp, i) => isPromise(exp)
|
|
5548
5579
|
? exp
|
|
5549
5580
|
.then(result => {
|
|
5550
5581
|
results[i] = result;
|
|
@@ -5554,8 +5585,7 @@ const waitForAllSettled = selectorFamily({
|
|
|
5554
5585
|
results[i] = undefined;
|
|
5555
5586
|
exceptions[i] = error;
|
|
5556
5587
|
})
|
|
5557
|
-
: null))
|
|
5558
|
-
.then(() => wrapLoadables(dependencies, results, exceptions)));
|
|
5588
|
+
: null)).then(() => wrapLoadables(dependencies, results, exceptions));
|
|
5559
5589
|
},
|
|
5560
5590
|
dangerouslyAllowMutability: true,
|
|
5561
5591
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -16,7 +16,7 @@ declare abstract class BaseLoadable<T> {
|
|
|
16
16
|
is(other: Loadable<any>): boolean;
|
|
17
17
|
}
|
|
18
18
|
declare class ValueLoadable<T> extends BaseLoadable<T> {
|
|
19
|
-
state:
|
|
19
|
+
state: "hasValue";
|
|
20
20
|
contents: T;
|
|
21
21
|
constructor(value: T);
|
|
22
22
|
getValue(): T;
|
|
@@ -28,7 +28,7 @@ declare class ValueLoadable<T> extends BaseLoadable<T> {
|
|
|
28
28
|
map<S>(map: (value: T) => Promise<S> | Loadable<S> | S): Loadable<S>;
|
|
29
29
|
}
|
|
30
30
|
declare class ErrorLoadable<T> extends BaseLoadable<T> {
|
|
31
|
-
state:
|
|
31
|
+
state: "hasError";
|
|
32
32
|
contents: unknown;
|
|
33
33
|
constructor(error: unknown);
|
|
34
34
|
getValue(): T;
|
|
@@ -40,7 +40,7 @@ declare class ErrorLoadable<T> extends BaseLoadable<T> {
|
|
|
40
40
|
map<S>(_map: (value: T) => Promise<S> | Loadable<S> | S): Loadable<S>;
|
|
41
41
|
}
|
|
42
42
|
declare class LoadingLoadable<T> extends BaseLoadable<T> {
|
|
43
|
-
state:
|
|
43
|
+
state: "loading";
|
|
44
44
|
contents: Promise<T>;
|
|
45
45
|
constructor(promise: Promise<T>);
|
|
46
46
|
getValue(): T;
|
|
@@ -486,7 +486,7 @@ declare function useRecoilTransactionObserver(callback: (info: {
|
|
|
486
486
|
declare function useRecoilSnapshot(): Snapshot;
|
|
487
487
|
declare function useGotoRecoilSnapshot(): (snapshot: Snapshot) => void;
|
|
488
488
|
|
|
489
|
-
declare function useGetRecoilValueInfo():
|
|
489
|
+
declare function useGetRecoilValueInfo(): <T>(recoilValue: RecoilValue<T>) => RecoilValueInfo<T>;
|
|
490
490
|
|
|
491
491
|
declare function useRecoilRefresher<T>(recoilValue: RecoilValue<T>): () => void;
|
|
492
492
|
|
|
@@ -508,9 +508,9 @@ type AtomFamilyOptionsWithoutDefault<T, P extends Parameter> = Readonly<AtomOpti
|
|
|
508
508
|
retainedBy_UNSTABLE?: RetainedBy | ((param: P) => RetainedBy);
|
|
509
509
|
cachePolicyForParams_UNSTABLE?: CachePolicyWithoutEviction;
|
|
510
510
|
}>;
|
|
511
|
-
type AtomFamilyOptions<T, P extends Parameter> =
|
|
511
|
+
type AtomFamilyOptions<T, P extends Parameter> = Readonly<AtomFamilyOptionsWithoutDefault<T, P> & {
|
|
512
512
|
default: RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T> | T | ((param: P) => T | RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T>);
|
|
513
|
-
}>
|
|
513
|
+
}> | AtomFamilyOptionsWithoutDefault<T, P>;
|
|
514
514
|
declare function atomFamily<T, P extends Parameter>(options: AtomFamilyOptions<T, P>): (params: P) => RecoilState<T>;
|
|
515
515
|
|
|
516
516
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ declare abstract class BaseLoadable<T> {
|
|
|
16
16
|
is(other: Loadable<any>): boolean;
|
|
17
17
|
}
|
|
18
18
|
declare class ValueLoadable<T> extends BaseLoadable<T> {
|
|
19
|
-
state:
|
|
19
|
+
state: "hasValue";
|
|
20
20
|
contents: T;
|
|
21
21
|
constructor(value: T);
|
|
22
22
|
getValue(): T;
|
|
@@ -28,7 +28,7 @@ declare class ValueLoadable<T> extends BaseLoadable<T> {
|
|
|
28
28
|
map<S>(map: (value: T) => Promise<S> | Loadable<S> | S): Loadable<S>;
|
|
29
29
|
}
|
|
30
30
|
declare class ErrorLoadable<T> extends BaseLoadable<T> {
|
|
31
|
-
state:
|
|
31
|
+
state: "hasError";
|
|
32
32
|
contents: unknown;
|
|
33
33
|
constructor(error: unknown);
|
|
34
34
|
getValue(): T;
|
|
@@ -40,7 +40,7 @@ declare class ErrorLoadable<T> extends BaseLoadable<T> {
|
|
|
40
40
|
map<S>(_map: (value: T) => Promise<S> | Loadable<S> | S): Loadable<S>;
|
|
41
41
|
}
|
|
42
42
|
declare class LoadingLoadable<T> extends BaseLoadable<T> {
|
|
43
|
-
state:
|
|
43
|
+
state: "loading";
|
|
44
44
|
contents: Promise<T>;
|
|
45
45
|
constructor(promise: Promise<T>);
|
|
46
46
|
getValue(): T;
|
|
@@ -486,7 +486,7 @@ declare function useRecoilTransactionObserver(callback: (info: {
|
|
|
486
486
|
declare function useRecoilSnapshot(): Snapshot;
|
|
487
487
|
declare function useGotoRecoilSnapshot(): (snapshot: Snapshot) => void;
|
|
488
488
|
|
|
489
|
-
declare function useGetRecoilValueInfo():
|
|
489
|
+
declare function useGetRecoilValueInfo(): <T>(recoilValue: RecoilValue<T>) => RecoilValueInfo<T>;
|
|
490
490
|
|
|
491
491
|
declare function useRecoilRefresher<T>(recoilValue: RecoilValue<T>): () => void;
|
|
492
492
|
|
|
@@ -508,9 +508,9 @@ type AtomFamilyOptionsWithoutDefault<T, P extends Parameter> = Readonly<AtomOpti
|
|
|
508
508
|
retainedBy_UNSTABLE?: RetainedBy | ((param: P) => RetainedBy);
|
|
509
509
|
cachePolicyForParams_UNSTABLE?: CachePolicyWithoutEviction;
|
|
510
510
|
}>;
|
|
511
|
-
type AtomFamilyOptions<T, P extends Parameter> =
|
|
511
|
+
type AtomFamilyOptions<T, P extends Parameter> = Readonly<AtomFamilyOptionsWithoutDefault<T, P> & {
|
|
512
512
|
default: RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T> | T | ((param: P) => T | RecoilValue<T> | Promise<T> | Loadable<T> | WrappedValue<T>);
|
|
513
|
-
}>
|
|
513
|
+
}> | AtomFamilyOptionsWithoutDefault<T, P>;
|
|
514
514
|
declare function atomFamily<T, P extends Parameter>(options: AtomFamilyOptions<T, P>): (params: P) => RecoilState<T>;
|
|
515
515
|
|
|
516
516
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -11,7 +11,9 @@ function err(message) {
|
|
|
11
11
|
try {
|
|
12
12
|
throw error;
|
|
13
13
|
}
|
|
14
|
-
catch (_) {
|
|
14
|
+
catch (_) {
|
|
15
|
+
/* T-ignore */
|
|
16
|
+
}
|
|
15
17
|
}
|
|
16
18
|
return error;
|
|
17
19
|
}
|
|
@@ -112,7 +114,8 @@ class BaseLoadable {
|
|
|
112
114
|
throw err(`Loadable expected error, but in "${this.state}" state`);
|
|
113
115
|
}
|
|
114
116
|
is(other) {
|
|
115
|
-
return other.state === this.state &&
|
|
117
|
+
return (other.state === this.state &&
|
|
118
|
+
Object.is(other.contents, this.contents));
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
class ValueLoadable extends BaseLoadable {
|
|
@@ -822,7 +825,6 @@ const getNextComponentID = () => nextComponentID++;
|
|
|
822
825
|
/** React mode and feature detection helpers */
|
|
823
826
|
var _a;
|
|
824
827
|
// Access either useSyncExternalStore or unstable_useSyncExternalStore depending on React version.
|
|
825
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
826
828
|
const useSyncExternalStore =
|
|
827
829
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
828
830
|
(_a = React.useSyncExternalStore) !== null && _a !== void 0 ? _a :
|
|
@@ -833,14 +835,17 @@ let ReactRendererVersionMismatchWarnOnce = false;
|
|
|
833
835
|
function currentRendererSupportsUseSyncExternalStore() {
|
|
834
836
|
var _a;
|
|
835
837
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
836
|
-
const internals = React
|
|
838
|
+
const internals = React
|
|
839
|
+
.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
837
840
|
if (!internals)
|
|
838
841
|
return false;
|
|
839
842
|
const { ReactCurrentDispatcher, ReactCurrentOwner } = internals;
|
|
840
843
|
// The dispatcher can be on ReactCurrentDispatcher.current (newer) or ReactCurrentOwner.currentDispatcher (older)
|
|
841
844
|
const dispatcher = (_a = ReactCurrentDispatcher === null || ReactCurrentDispatcher === void 0 ? void 0 : ReactCurrentDispatcher.current) !== null && _a !== void 0 ? _a : ReactCurrentOwner === null || ReactCurrentOwner === void 0 ? void 0 : ReactCurrentOwner.currentDispatcher;
|
|
842
845
|
const isSupported = (dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.useSyncExternalStore) != null;
|
|
843
|
-
if (useSyncExternalStore !== undefined &&
|
|
846
|
+
if (useSyncExternalStore !== undefined &&
|
|
847
|
+
!isSupported &&
|
|
848
|
+
!ReactRendererVersionMismatchWarnOnce) {
|
|
844
849
|
ReactRendererVersionMismatchWarnOnce = true;
|
|
845
850
|
recoverableViolation('A React renderer without React 18+ API support is being used with React 18+.');
|
|
846
851
|
}
|
|
@@ -891,7 +896,8 @@ writes) {
|
|
|
891
896
|
return result;
|
|
892
897
|
}
|
|
893
898
|
function writeLoadableToTreeState(state, key, loadable) {
|
|
894
|
-
if (loadable.state === 'hasValue' &&
|
|
899
|
+
if (loadable.state === 'hasValue' &&
|
|
900
|
+
loadable.contents instanceof DefaultValue) {
|
|
895
901
|
state.atomValues.delete(key);
|
|
896
902
|
}
|
|
897
903
|
else {
|
|
@@ -927,7 +933,8 @@ function notifyComponents$2(store, treeState) {
|
|
|
927
933
|
}
|
|
928
934
|
}
|
|
929
935
|
function valueFromValueOrUpdater(store, state, recoilValue, valueOrUpdater) {
|
|
930
|
-
if (typeof valueOrUpdater === 'function' &&
|
|
936
|
+
if (typeof valueOrUpdater === 'function' &&
|
|
937
|
+
valueOrUpdater !== DEFAULT_VALUE) {
|
|
931
938
|
// Updater form: pass in the current value
|
|
932
939
|
const current = getRecoilValueAsLoadable(store, recoilValue, state);
|
|
933
940
|
if (current.state === 'loading') {
|
|
@@ -2380,8 +2387,7 @@ function* concatIterables(iters) {
|
|
|
2380
2387
|
* TypeScript port of Recoil_Environment.js
|
|
2381
2388
|
*/
|
|
2382
2389
|
const isSSR = typeof window === 'undefined';
|
|
2383
|
-
const isWindow = (value) => !isSSR &&
|
|
2384
|
-
(value === window || value instanceof Window);
|
|
2390
|
+
const isWindow = (value) => !isSSR && (value === window || value instanceof Window);
|
|
2385
2391
|
const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
2386
2392
|
|
|
2387
2393
|
/**
|
|
@@ -2451,7 +2457,8 @@ class Snapshot {
|
|
|
2451
2457
|
? recoilValues.values()
|
|
2452
2458
|
: opt.isInitialized === true
|
|
2453
2459
|
? recoilValuesForKeys(concatIterables([knownAtoms, knownSelectors]))
|
|
2454
|
-
: filterIterable(recoilValues.values(),
|
|
2460
|
+
: filterIterable(recoilValues.values(), recoilValue => !knownAtoms.has(recoilValue.key) &&
|
|
2461
|
+
!knownSelectors.has(recoilValue.key));
|
|
2455
2462
|
};
|
|
2456
2463
|
// Report the current status of a node.
|
|
2457
2464
|
// This peeks the current state and does not affect the snapshot state at all
|
|
@@ -2616,10 +2623,7 @@ function cloneStoreState(store, treeState, bumpVersion = false) {
|
|
|
2616
2623
|
// FIXME here's a copy
|
|
2617
2624
|
// Create blank cleanup handlers for atoms so snapshots don't re-run
|
|
2618
2625
|
// atom effects.
|
|
2619
|
-
nodeCleanupFunctions: new Map(mapIterable(storeState.nodeCleanupFunctions.entries(), ([key]) => [
|
|
2620
|
-
key,
|
|
2621
|
-
() => { },
|
|
2622
|
-
])),
|
|
2626
|
+
nodeCleanupFunctions: new Map(mapIterable(storeState.nodeCleanupFunctions.entries(), ([key]) => [key, () => { }])),
|
|
2623
2627
|
};
|
|
2624
2628
|
}
|
|
2625
2629
|
// Factory to build a fresh snapshot
|
|
@@ -2632,7 +2636,7 @@ const [memoizedCloneSnapshot, invalidateMemoizedSnapshot] = memoizeOneWithArgsHa
|
|
|
2632
2636
|
var _a;
|
|
2633
2637
|
const storeState = store.getState();
|
|
2634
2638
|
const treeState = version === 'latest'
|
|
2635
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
2639
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
2636
2640
|
: nullthrows(storeState.previousTree);
|
|
2637
2641
|
return new Snapshot(cloneStoreState(store, treeState), store.storeID);
|
|
2638
2642
|
}, (store, version) => {
|
|
@@ -2650,7 +2654,7 @@ function cloneSnapshot(store, version = 'latest') {
|
|
|
2650
2654
|
if (process.env.NODE_ENV === 'test') {
|
|
2651
2655
|
const storeState = store.getState();
|
|
2652
2656
|
const treeState = version === 'latest'
|
|
2653
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
2657
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
2654
2658
|
: nullthrows(storeState.previousTree);
|
|
2655
2659
|
return new Snapshot(cloneStoreState(store, treeState), store.storeID);
|
|
2656
2660
|
}
|
|
@@ -2664,7 +2668,9 @@ function cloneSnapshot(store, version = 'latest') {
|
|
|
2664
2668
|
}
|
|
2665
2669
|
catch (retainError) {
|
|
2666
2670
|
// If checking isRetained() fails, assume it's released and create fresh
|
|
2667
|
-
if (retainError &&
|
|
2671
|
+
if (retainError &&
|
|
2672
|
+
typeof retainError === 'object' &&
|
|
2673
|
+
'message' in retainError &&
|
|
2668
2674
|
typeof retainError.message === 'string' &&
|
|
2669
2675
|
retainError.message.includes('already been released')) {
|
|
2670
2676
|
invalidateMemoizedSnapshot();
|
|
@@ -2676,7 +2682,9 @@ function cloneSnapshot(store, version = 'latest') {
|
|
|
2676
2682
|
}
|
|
2677
2683
|
catch (error) {
|
|
2678
2684
|
// If the memoized snapshot was released, create a fresh one
|
|
2679
|
-
if (error &&
|
|
2685
|
+
if (error &&
|
|
2686
|
+
typeof error === 'object' &&
|
|
2687
|
+
'message' in error &&
|
|
2680
2688
|
typeof error.message === 'string' &&
|
|
2681
2689
|
error.message.includes('already been released')) {
|
|
2682
2690
|
invalidateMemoizedSnapshot();
|
|
@@ -3227,7 +3235,7 @@ function useRecoilValueLoadable_SYNC_EXTERNAL_STORE(recoilValue) {
|
|
|
3227
3235
|
const store = storeRef.current;
|
|
3228
3236
|
const storeState = store.getState();
|
|
3229
3237
|
const treeState = reactMode().early
|
|
3230
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
3238
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
3231
3239
|
: storeState.currentTree;
|
|
3232
3240
|
const loadable = getRecoilValueAsLoadable(store, recoilValue, treeState);
|
|
3233
3241
|
return { loadable, key: recoilValue.key };
|
|
@@ -3251,7 +3259,7 @@ function useRecoilValueLoadable_SYNC_EXTERNAL_STORE(recoilValue) {
|
|
|
3251
3259
|
if (Recoil_gkx_OSS('recoil_memory_managament_2020')) {
|
|
3252
3260
|
updateRetainCount(store, recoilValue.key, 1);
|
|
3253
3261
|
}
|
|
3254
|
-
const subscription = subscribeToRecoilValue(store, recoilValue,
|
|
3262
|
+
const subscription = subscribeToRecoilValue(store, recoilValue, _treeState => notify());
|
|
3255
3263
|
return () => {
|
|
3256
3264
|
// Release retention when subscription is released
|
|
3257
3265
|
if (Recoil_gkx_OSS('recoil_memory_managament_2020')) {
|
|
@@ -3264,7 +3272,8 @@ function useRecoilValueLoadable_SYNC_EXTERNAL_STORE(recoilValue) {
|
|
|
3264
3272
|
if (useSyncExternalStore$1 === undefined) {
|
|
3265
3273
|
throw new Error('useSyncExternalStore is not available in this version of React');
|
|
3266
3274
|
}
|
|
3267
|
-
return useSyncExternalStore$1(subscribe, getMemoizedSnapshot, () => ssrSnapshot)
|
|
3275
|
+
return useSyncExternalStore$1(subscribe, getMemoizedSnapshot, () => ssrSnapshot)
|
|
3276
|
+
.loadable;
|
|
3268
3277
|
}
|
|
3269
3278
|
function useRecoilValueLoadable_TRANSITION_SUPPORT(recoilValue) {
|
|
3270
3279
|
const storeRef = useStoreRef();
|
|
@@ -3274,7 +3283,7 @@ function useRecoilValueLoadable_TRANSITION_SUPPORT(recoilValue) {
|
|
|
3274
3283
|
const store = storeRef.current;
|
|
3275
3284
|
const storeState = store.getState();
|
|
3276
3285
|
const treeState = reactMode().early
|
|
3277
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
3286
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
3278
3287
|
: storeState.currentTree;
|
|
3279
3288
|
return getRecoilValueAsLoadable(store, recoilValue, treeState);
|
|
3280
3289
|
}, [storeRef, recoilValue]);
|
|
@@ -3305,7 +3314,7 @@ function useRecoilValueLoadable_LEGACY(recoilValue) {
|
|
|
3305
3314
|
const store = storeRef.current;
|
|
3306
3315
|
const storeState = store.getState();
|
|
3307
3316
|
const treeState = reactMode().early
|
|
3308
|
-
? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
|
|
3317
|
+
? ((_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree)
|
|
3309
3318
|
: storeState.currentTree;
|
|
3310
3319
|
return getRecoilValueAsLoadable(store, recoilValue, treeState);
|
|
3311
3320
|
}, [storeRef, recoilValue]);
|
|
@@ -3446,7 +3455,9 @@ function useTransactionSubscription(callback) {
|
|
|
3446
3455
|
}
|
|
3447
3456
|
catch (error) {
|
|
3448
3457
|
// In React 19, snapshots can fail more aggressively
|
|
3449
|
-
if (error &&
|
|
3458
|
+
if (error &&
|
|
3459
|
+
typeof error === 'object' &&
|
|
3460
|
+
'message' in error &&
|
|
3450
3461
|
typeof error.message === 'string' &&
|
|
3451
3462
|
error.message.includes('already been released')) {
|
|
3452
3463
|
console.warn('Snapshot already released in transaction subscription, skipping');
|
|
@@ -3480,7 +3491,9 @@ function useRecoilSnapshot() {
|
|
|
3480
3491
|
catch (error) {
|
|
3481
3492
|
// In React 19, snapshots can be released more aggressively
|
|
3482
3493
|
// If the snapshot was already released, create a fresh one
|
|
3483
|
-
if (error &&
|
|
3494
|
+
if (error &&
|
|
3495
|
+
typeof error === 'object' &&
|
|
3496
|
+
'message' in error &&
|
|
3484
3497
|
typeof error.message === 'string' &&
|
|
3485
3498
|
error.message.includes('already been released')) {
|
|
3486
3499
|
console.warn('Snapshot already released during initial state, creating fresh snapshot');
|
|
@@ -3499,7 +3512,9 @@ function useRecoilSnapshot() {
|
|
|
3499
3512
|
catch (error) {
|
|
3500
3513
|
// In React 19, snapshots can be released more aggressively
|
|
3501
3514
|
// If the snapshot was already released, skip this update
|
|
3502
|
-
if (error &&
|
|
3515
|
+
if (error &&
|
|
3516
|
+
typeof error === 'object' &&
|
|
3517
|
+
'message' in error &&
|
|
3503
3518
|
typeof error.message === 'string' &&
|
|
3504
3519
|
error.message.includes('already been released')) {
|
|
3505
3520
|
console.warn('Snapshot already released during transaction subscription, skipping update');
|
|
@@ -3517,7 +3532,9 @@ function useRecoilSnapshot() {
|
|
|
3517
3532
|
}
|
|
3518
3533
|
catch (error) {
|
|
3519
3534
|
// If snapshot retention fails, skip this effect
|
|
3520
|
-
if (error &&
|
|
3535
|
+
if (error &&
|
|
3536
|
+
typeof error === 'object' &&
|
|
3537
|
+
'message' in error &&
|
|
3521
3538
|
typeof error.message === 'string' &&
|
|
3522
3539
|
error.message.includes('already been released')) {
|
|
3523
3540
|
console.warn('Cannot retain snapshot in useEffect, already released');
|
|
@@ -3558,7 +3575,9 @@ function useRecoilSnapshot() {
|
|
|
3558
3575
|
}
|
|
3559
3576
|
catch (error) {
|
|
3560
3577
|
// If snapshot retention fails, skip this retention
|
|
3561
|
-
if (error &&
|
|
3578
|
+
if (error &&
|
|
3579
|
+
typeof error === 'object' &&
|
|
3580
|
+
'message' in error &&
|
|
3562
3581
|
typeof error.message === 'string' &&
|
|
3563
3582
|
error.message.includes('already been released')) {
|
|
3564
3583
|
console.warn('Cannot retain snapshot in render, already released');
|
|
@@ -3606,7 +3625,10 @@ function gotoSnapshot(store, snapshot) {
|
|
|
3606
3625
|
newTree.stateID = snapshot.getID();
|
|
3607
3626
|
const atomKeysChanged = new Set();
|
|
3608
3627
|
// Update atoms that should be restored from snapshots
|
|
3609
|
-
for (const key of new Set([
|
|
3628
|
+
for (const key of new Set([
|
|
3629
|
+
...prev.atomValues.keys(),
|
|
3630
|
+
...next.atomValues.keys(),
|
|
3631
|
+
])) {
|
|
3610
3632
|
const node = getNode(key);
|
|
3611
3633
|
if (!node.shouldRestoreFromSnapshots)
|
|
3612
3634
|
continue;
|
|
@@ -3617,7 +3639,9 @@ function gotoSnapshot(store, snapshot) {
|
|
|
3617
3639
|
const loadable = next.atomValues.has(key)
|
|
3618
3640
|
? nullthrows(next.atomValues.get(key))
|
|
3619
3641
|
: loadableWithValue(DEFAULT_VALUE);
|
|
3620
|
-
if (loadable &&
|
|
3642
|
+
if (loadable &&
|
|
3643
|
+
loadable.state === 'hasValue' &&
|
|
3644
|
+
loadable.contents === DEFAULT_VALUE) {
|
|
3621
3645
|
newTree.atomValues.delete(key);
|
|
3622
3646
|
}
|
|
3623
3647
|
else {
|
|
@@ -3654,7 +3678,6 @@ function useGetRecoilValueInfo() {
|
|
|
3654
3678
|
function useRecoilBridgeAcrossReactRoots() {
|
|
3655
3679
|
const store = useStoreRef().current;
|
|
3656
3680
|
return useMemo(() => {
|
|
3657
|
-
// eslint-disable-next-line no-shadow
|
|
3658
3681
|
function RecoilBridge({ children }) {
|
|
3659
3682
|
return jsx(RecoilRoot, { store: store, children: children });
|
|
3660
3683
|
}
|
|
@@ -3783,7 +3806,7 @@ function recoilCallback(store, fn, args, extraInterface) {
|
|
|
3783
3806
|
// For all other methods, delegate to target
|
|
3784
3807
|
const value = target[prop];
|
|
3785
3808
|
return typeof value === 'function' ? value.bind(target) : value;
|
|
3786
|
-
}
|
|
3809
|
+
},
|
|
3787
3810
|
});
|
|
3788
3811
|
return hybridSnapshot;
|
|
3789
3812
|
},
|
|
@@ -3820,7 +3843,6 @@ function useRecoilCallback(fn, deps) {
|
|
|
3820
3843
|
},
|
|
3821
3844
|
// Don't include storeRef in deps to avoid unnecessary re-creation
|
|
3822
3845
|
// The store reference should be stable within a RecoilRoot
|
|
3823
|
-
// eslint-disable-next-line fb-www/react-hooks-deps
|
|
3824
3846
|
deps !== null && deps !== void 0 ? deps : []);
|
|
3825
3847
|
}
|
|
3826
3848
|
|
|
@@ -3865,7 +3887,7 @@ function isNode(object) {
|
|
|
3865
3887
|
if (typeof window === 'undefined') {
|
|
3866
3888
|
return false;
|
|
3867
3889
|
}
|
|
3868
|
-
const doc = object != null ? (_a = object.ownerDocument) !== null && _a !== void 0 ? _a : document : document;
|
|
3890
|
+
const doc = object != null ? ((_a = object.ownerDocument) !== null && _a !== void 0 ? _a : document) : document;
|
|
3869
3891
|
const defaultView = (_b = doc.defaultView) !== null && _b !== void 0 ? _b : window;
|
|
3870
3892
|
return !!(object != null &&
|
|
3871
3893
|
(typeof defaultView.Node === 'function'
|
|
@@ -3979,7 +4001,8 @@ function stringify(x, opt, key, visited = new Set()) {
|
|
|
3979
4001
|
if (x instanceof Map) {
|
|
3980
4002
|
const obj = {};
|
|
3981
4003
|
for (const [k, v] of x) {
|
|
3982
|
-
obj[typeof k === 'string' ? k : stringify(k, opt, undefined, visited)] =
|
|
4004
|
+
obj[typeof k === 'string' ? k : stringify(k, opt, undefined, visited)] =
|
|
4005
|
+
v;
|
|
3983
4006
|
}
|
|
3984
4007
|
const result = stringify(obj, opt, key, visited);
|
|
3985
4008
|
visited.delete(x);
|
|
@@ -4111,7 +4134,7 @@ class TreeCache {
|
|
|
4111
4134
|
// Second, setup the leaf node:
|
|
4112
4135
|
// If there is an existing leaf for this route confirm it is consistent
|
|
4113
4136
|
const oldLeaf = node
|
|
4114
|
-
? (_d = node.branches.get(branchKey)) !== null && _d !== void 0 ? _d : null
|
|
4137
|
+
? ((_d = node.branches.get(branchKey)) !== null && _d !== void 0 ? _d : null)
|
|
4115
4138
|
: this._root;
|
|
4116
4139
|
if (oldLeaf != null &&
|
|
4117
4140
|
(oldLeaf.type !== 'leaf' || oldLeaf.branchKey !== branchKey)) {
|
|
@@ -4337,9 +4360,11 @@ const defaultPolicy$1 = {
|
|
|
4337
4360
|
maxSize: Infinity,
|
|
4338
4361
|
};
|
|
4339
4362
|
function treeCacheFromPolicy(policy = defaultPolicy$1, name) {
|
|
4340
|
-
const { equality = defaultPolicy$1.equality
|
|
4363
|
+
const { equality = defaultPolicy$1.equality } = policy;
|
|
4341
4364
|
const eviction = 'eviction' in policy ? policy.eviction : 'keep-all';
|
|
4342
|
-
const maxSize = 'maxSize' in policy && policy.eviction === 'lru'
|
|
4365
|
+
const maxSize = 'maxSize' in policy && policy.eviction === 'lru'
|
|
4366
|
+
? policy.maxSize
|
|
4367
|
+
: defaultPolicy$1.maxSize;
|
|
4343
4368
|
const valueMapper = getValueMapper$1(equality);
|
|
4344
4369
|
return getTreeCache(eviction, maxSize, valueMapper, name);
|
|
4345
4370
|
}
|
|
@@ -4642,8 +4667,7 @@ function selector(options) {
|
|
|
4642
4667
|
});
|
|
4643
4668
|
}
|
|
4644
4669
|
catch (error) {
|
|
4645
|
-
throw err(`Problem with cache lookup for selector "${key}": ${error
|
|
4646
|
-
.message}`);
|
|
4670
|
+
throw err(`Problem with cache lookup for selector "${key}": ${error.message}`);
|
|
4647
4671
|
}
|
|
4648
4672
|
if (cachedLoadable) {
|
|
4649
4673
|
state.atomValues.set(key, cachedLoadable);
|
|
@@ -4748,8 +4772,7 @@ function selector(options) {
|
|
|
4748
4772
|
cache.set(depValuesToDepRoute(depValues), loadable);
|
|
4749
4773
|
}
|
|
4750
4774
|
catch (error) {
|
|
4751
|
-
throw err(`Problem with setting cache for selector "${key}": ${error
|
|
4752
|
-
.message}`);
|
|
4775
|
+
throw err(`Problem with setting cache for selector "${key}": ${error.message}`);
|
|
4753
4776
|
}
|
|
4754
4777
|
}
|
|
4755
4778
|
function detectCircularDependencies(fn) {
|
|
@@ -5045,7 +5068,8 @@ function baseAtom(options) {
|
|
|
5045
5068
|
var _a;
|
|
5046
5069
|
const { release } = store.subscribeToTransactions(currentStore => {
|
|
5047
5070
|
var _a, _b;
|
|
5048
|
-
let {
|
|
5071
|
+
let { previousTree } = currentStore.getState();
|
|
5072
|
+
const { currentTree } = currentStore.getState();
|
|
5049
5073
|
if (!previousTree) {
|
|
5050
5074
|
recoverableViolation('Transaction subscribers notified without a next tree being present -- this is a bug in Recoil');
|
|
5051
5075
|
previousTree = currentTree;
|
|
@@ -5145,7 +5169,9 @@ function baseAtom(options) {
|
|
|
5145
5169
|
function setAtom(_store, state, newValue) {
|
|
5146
5170
|
if (state.atomValues.has(key)) {
|
|
5147
5171
|
const existing = state.atomValues.get(key);
|
|
5148
|
-
if (existing &&
|
|
5172
|
+
if (existing &&
|
|
5173
|
+
existing.state === 'hasValue' &&
|
|
5174
|
+
newValue === existing.contents) {
|
|
5149
5175
|
return new Map();
|
|
5150
5176
|
}
|
|
5151
5177
|
}
|
|
@@ -5260,9 +5286,11 @@ const defaultPolicy = {
|
|
|
5260
5286
|
maxSize: Infinity,
|
|
5261
5287
|
};
|
|
5262
5288
|
function cacheFromPolicy(policy = defaultPolicy) {
|
|
5263
|
-
const { equality = defaultPolicy.equality
|
|
5289
|
+
const { equality = defaultPolicy.equality } = policy;
|
|
5264
5290
|
const eviction = 'eviction' in policy ? policy.eviction : 'keep-all';
|
|
5265
|
-
const maxSize = 'maxSize' in policy && policy.eviction === 'lru'
|
|
5291
|
+
const maxSize = 'maxSize' in policy && policy.eviction === 'lru'
|
|
5292
|
+
? policy.maxSize
|
|
5293
|
+
: defaultPolicy.maxSize;
|
|
5266
5294
|
const valueMapper = getValueMapper(equality);
|
|
5267
5295
|
const cache = getCache(eviction, maxSize, valueMapper);
|
|
5268
5296
|
return cache;
|
|
@@ -5281,7 +5309,10 @@ function getCache(eviction, maxSize, mapKey) {
|
|
|
5281
5309
|
case 'keep-all':
|
|
5282
5310
|
return new MapCache({ mapKey: mapKey });
|
|
5283
5311
|
case 'lru':
|
|
5284
|
-
return new LRUCache({
|
|
5312
|
+
return new LRUCache({
|
|
5313
|
+
mapKey: mapKey,
|
|
5314
|
+
maxSize: nullthrows(maxSize),
|
|
5315
|
+
});
|
|
5285
5316
|
case 'most-recent':
|
|
5286
5317
|
return new LRUCache({ mapKey: mapKey, maxSize: 1 });
|
|
5287
5318
|
}
|
|
@@ -5315,7 +5346,7 @@ function atomFamily(options) {
|
|
|
5315
5346
|
? options.effects(params)
|
|
5316
5347
|
: typeof options.effects_UNSTABLE === 'function'
|
|
5317
5348
|
? options.effects_UNSTABLE(params)
|
|
5318
|
-
: (_b = options.effects) !== null && _b !== void 0 ? _b : options.effects_UNSTABLE }));
|
|
5349
|
+
: ((_b = options.effects) !== null && _b !== void 0 ? _b : options.effects_UNSTABLE) }));
|
|
5319
5350
|
atomCache.set(params, newAtom);
|
|
5320
5351
|
setConfigDeletionHandler(newAtom.key, () => {
|
|
5321
5352
|
atomCache.delete(params);
|
|
@@ -5542,7 +5573,7 @@ const waitForAllSettled = selectorFamily({
|
|
|
5542
5573
|
if (exceptions.every(exp => !isPromise(exp))) {
|
|
5543
5574
|
return wrapLoadables(dependencies, results, exceptions);
|
|
5544
5575
|
}
|
|
5545
|
-
return
|
|
5576
|
+
return Promise.all(exceptions.map((exp, i) => isPromise(exp)
|
|
5546
5577
|
? exp
|
|
5547
5578
|
.then(result => {
|
|
5548
5579
|
results[i] = result;
|
|
@@ -5552,8 +5583,7 @@ const waitForAllSettled = selectorFamily({
|
|
|
5552
5583
|
results[i] = undefined;
|
|
5553
5584
|
exceptions[i] = error;
|
|
5554
5585
|
})
|
|
5555
|
-
: null))
|
|
5556
|
-
.then(() => wrapLoadables(dependencies, results, exceptions)));
|
|
5586
|
+
: null)).then(() => wrapLoadables(dependencies, results, exceptions));
|
|
5557
5587
|
},
|
|
5558
5588
|
dangerouslyAllowMutability: true,
|
|
5559
5589
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "recoil-next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Continuation of Recoil - A state management library for React",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mutesa Cedric",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@types/react": "^18.2.39",
|
|
51
51
|
"@types/react-dom": "^18.2.14",
|
|
52
52
|
"@typescript-eslint/eslint-plugin": "^8.36.0",
|
|
53
|
-
"@vitest/ui": "^2.
|
|
53
|
+
"@vitest/ui": "^3.2.4",
|
|
54
54
|
"bumpp": "^10.2.2",
|
|
55
55
|
"eslint-config-prettier": "^10.1.5",
|
|
56
56
|
"eslint-plugin-prettier": "^5.5.1",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"rollup-plugin-dts": "^6.2.1",
|
|
61
61
|
"tslib": "^2.6.0",
|
|
62
62
|
"typescript": "^5.4.2",
|
|
63
|
-
"vitest": "^2.
|
|
63
|
+
"vitest": "^3.2.4"
|
|
64
64
|
},
|
|
65
65
|
"repository": "https://github.com/Mutesa-Cedric/Recoil-next.git",
|
|
66
66
|
"license": "MIT"
|
|
67
|
-
}
|
|
67
|
+
}
|