recoil-next 0.1.0 → 0.3.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/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var jsxRuntime = require('react/jsx-runtime');
3
4
  var React = require('react');
4
5
  var reactDom = require('react-dom');
5
6
 
@@ -452,437 +453,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
452
453
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
453
454
  };
454
455
 
455
- function getDefaultExportFromCjs (x) {
456
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
457
- }
458
-
459
- var jsxRuntime = {exports: {}};
460
-
461
- var reactJsxRuntime_production = {};
462
-
463
- /**
464
- * @license React
465
- * react-jsx-runtime.production.js
466
- *
467
- * Copyright (c) Meta Platforms, Inc. and affiliates.
468
- *
469
- * This source code is licensed under the MIT license found in the
470
- * LICENSE file in the root directory of this source tree.
471
- */
472
-
473
- var hasRequiredReactJsxRuntime_production;
474
-
475
- function requireReactJsxRuntime_production () {
476
- if (hasRequiredReactJsxRuntime_production) return reactJsxRuntime_production;
477
- hasRequiredReactJsxRuntime_production = 1;
478
- var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),
479
- REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
480
- function jsxProd(type, config, maybeKey) {
481
- var key = null;
482
- void 0 !== maybeKey && (key = "" + maybeKey);
483
- void 0 !== config.key && (key = "" + config.key);
484
- if ("key" in config) {
485
- maybeKey = {};
486
- for (var propName in config)
487
- "key" !== propName && (maybeKey[propName] = config[propName]);
488
- } else maybeKey = config;
489
- config = maybeKey.ref;
490
- return {
491
- $$typeof: REACT_ELEMENT_TYPE,
492
- type: type,
493
- key: key,
494
- ref: void 0 !== config ? config : null,
495
- props: maybeKey
496
- };
497
- }
498
- reactJsxRuntime_production.Fragment = REACT_FRAGMENT_TYPE;
499
- reactJsxRuntime_production.jsx = jsxProd;
500
- reactJsxRuntime_production.jsxs = jsxProd;
501
- return reactJsxRuntime_production;
502
- }
503
-
504
- var reactJsxRuntime_development = {};
505
-
506
- /**
507
- * @license React
508
- * react-jsx-runtime.development.js
509
- *
510
- * Copyright (c) Meta Platforms, Inc. and affiliates.
511
- *
512
- * This source code is licensed under the MIT license found in the
513
- * LICENSE file in the root directory of this source tree.
514
- */
515
-
516
- var hasRequiredReactJsxRuntime_development;
517
-
518
- function requireReactJsxRuntime_development () {
519
- if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development;
520
- hasRequiredReactJsxRuntime_development = 1;
521
- "production" !== process.env.NODE_ENV &&
522
- (function () {
523
- function getComponentNameFromType(type) {
524
- if (null == type) return null;
525
- if ("function" === typeof type)
526
- return type.$$typeof === REACT_CLIENT_REFERENCE
527
- ? null
528
- : type.displayName || type.name || null;
529
- if ("string" === typeof type) return type;
530
- switch (type) {
531
- case REACT_FRAGMENT_TYPE:
532
- return "Fragment";
533
- case REACT_PROFILER_TYPE:
534
- return "Profiler";
535
- case REACT_STRICT_MODE_TYPE:
536
- return "StrictMode";
537
- case REACT_SUSPENSE_TYPE:
538
- return "Suspense";
539
- case REACT_SUSPENSE_LIST_TYPE:
540
- return "SuspenseList";
541
- case REACT_ACTIVITY_TYPE:
542
- return "Activity";
543
- }
544
- if ("object" === typeof type)
545
- switch (
546
- ("number" === typeof type.tag &&
547
- console.error(
548
- "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
549
- ),
550
- type.$$typeof)
551
- ) {
552
- case REACT_PORTAL_TYPE:
553
- return "Portal";
554
- case REACT_CONTEXT_TYPE:
555
- return (type.displayName || "Context") + ".Provider";
556
- case REACT_CONSUMER_TYPE:
557
- return (type._context.displayName || "Context") + ".Consumer";
558
- case REACT_FORWARD_REF_TYPE:
559
- var innerType = type.render;
560
- type = type.displayName;
561
- type ||
562
- ((type = innerType.displayName || innerType.name || ""),
563
- (type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef"));
564
- return type;
565
- case REACT_MEMO_TYPE:
566
- return (
567
- (innerType = type.displayName || null),
568
- null !== innerType
569
- ? innerType
570
- : getComponentNameFromType(type.type) || "Memo"
571
- );
572
- case REACT_LAZY_TYPE:
573
- innerType = type._payload;
574
- type = type._init;
575
- try {
576
- return getComponentNameFromType(type(innerType));
577
- } catch (x) {}
578
- }
579
- return null;
580
- }
581
- function testStringCoercion(value) {
582
- return "" + value;
583
- }
584
- function checkKeyStringCoercion(value) {
585
- try {
586
- testStringCoercion(value);
587
- var JSCompiler_inline_result = !1;
588
- } catch (e) {
589
- JSCompiler_inline_result = true;
590
- }
591
- if (JSCompiler_inline_result) {
592
- JSCompiler_inline_result = console;
593
- var JSCompiler_temp_const = JSCompiler_inline_result.error;
594
- var JSCompiler_inline_result$jscomp$0 =
595
- ("function" === typeof Symbol &&
596
- Symbol.toStringTag &&
597
- value[Symbol.toStringTag]) ||
598
- value.constructor.name ||
599
- "Object";
600
- JSCompiler_temp_const.call(
601
- JSCompiler_inline_result,
602
- "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
603
- JSCompiler_inline_result$jscomp$0
604
- );
605
- return testStringCoercion(value);
606
- }
607
- }
608
- function getTaskName(type) {
609
- if (type === REACT_FRAGMENT_TYPE) return "<>";
610
- if (
611
- "object" === typeof type &&
612
- null !== type &&
613
- type.$$typeof === REACT_LAZY_TYPE
614
- )
615
- return "<...>";
616
- try {
617
- var name = getComponentNameFromType(type);
618
- return name ? "<" + name + ">" : "<...>";
619
- } catch (x) {
620
- return "<...>";
621
- }
622
- }
623
- function getOwner() {
624
- var dispatcher = ReactSharedInternals.A;
625
- return null === dispatcher ? null : dispatcher.getOwner();
626
- }
627
- function UnknownOwner() {
628
- return Error("react-stack-top-frame");
629
- }
630
- function hasValidKey(config) {
631
- if (hasOwnProperty.call(config, "key")) {
632
- var getter = Object.getOwnPropertyDescriptor(config, "key").get;
633
- if (getter && getter.isReactWarning) return false;
634
- }
635
- return void 0 !== config.key;
636
- }
637
- function defineKeyPropWarningGetter(props, displayName) {
638
- function warnAboutAccessingKey() {
639
- specialPropKeyWarningShown ||
640
- ((specialPropKeyWarningShown = true),
641
- console.error(
642
- "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
643
- displayName
644
- ));
645
- }
646
- warnAboutAccessingKey.isReactWarning = true;
647
- Object.defineProperty(props, "key", {
648
- get: warnAboutAccessingKey,
649
- configurable: true
650
- });
651
- }
652
- function elementRefGetterWithDeprecationWarning() {
653
- var componentName = getComponentNameFromType(this.type);
654
- didWarnAboutElementRef[componentName] ||
655
- ((didWarnAboutElementRef[componentName] = true),
656
- console.error(
657
- "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
658
- ));
659
- componentName = this.props.ref;
660
- return void 0 !== componentName ? componentName : null;
661
- }
662
- function ReactElement(
663
- type,
664
- key,
665
- self,
666
- source,
667
- owner,
668
- props,
669
- debugStack,
670
- debugTask
671
- ) {
672
- self = props.ref;
673
- type = {
674
- $$typeof: REACT_ELEMENT_TYPE,
675
- type: type,
676
- key: key,
677
- props: props,
678
- _owner: owner
679
- };
680
- null !== (void 0 !== self ? self : null)
681
- ? Object.defineProperty(type, "ref", {
682
- enumerable: false,
683
- get: elementRefGetterWithDeprecationWarning
684
- })
685
- : Object.defineProperty(type, "ref", { enumerable: false, value: null });
686
- type._store = {};
687
- Object.defineProperty(type._store, "validated", {
688
- configurable: false,
689
- enumerable: false,
690
- writable: true,
691
- value: 0
692
- });
693
- Object.defineProperty(type, "_debugInfo", {
694
- configurable: false,
695
- enumerable: false,
696
- writable: true,
697
- value: null
698
- });
699
- Object.defineProperty(type, "_debugStack", {
700
- configurable: false,
701
- enumerable: false,
702
- writable: true,
703
- value: debugStack
704
- });
705
- Object.defineProperty(type, "_debugTask", {
706
- configurable: false,
707
- enumerable: false,
708
- writable: true,
709
- value: debugTask
710
- });
711
- Object.freeze && (Object.freeze(type.props), Object.freeze(type));
712
- return type;
713
- }
714
- function jsxDEVImpl(
715
- type,
716
- config,
717
- maybeKey,
718
- isStaticChildren,
719
- source,
720
- self,
721
- debugStack,
722
- debugTask
723
- ) {
724
- var children = config.children;
725
- if (void 0 !== children)
726
- if (isStaticChildren)
727
- if (isArrayImpl(children)) {
728
- for (
729
- isStaticChildren = 0;
730
- isStaticChildren < children.length;
731
- isStaticChildren++
732
- )
733
- validateChildKeys(children[isStaticChildren]);
734
- Object.freeze && Object.freeze(children);
735
- } else
736
- console.error(
737
- "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
738
- );
739
- else validateChildKeys(children);
740
- if (hasOwnProperty.call(config, "key")) {
741
- children = getComponentNameFromType(type);
742
- var keys = Object.keys(config).filter(function (k) {
743
- return "key" !== k;
744
- });
745
- isStaticChildren =
746
- 0 < keys.length
747
- ? "{key: someKey, " + keys.join(": ..., ") + ": ...}"
748
- : "{key: someKey}";
749
- didWarnAboutKeySpread[children + isStaticChildren] ||
750
- ((keys =
751
- 0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}"),
752
- console.error(
753
- 'A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',
754
- isStaticChildren,
755
- children,
756
- keys,
757
- children
758
- ),
759
- (didWarnAboutKeySpread[children + isStaticChildren] = true));
760
- }
761
- children = null;
762
- void 0 !== maybeKey &&
763
- (checkKeyStringCoercion(maybeKey), (children = "" + maybeKey));
764
- hasValidKey(config) &&
765
- (checkKeyStringCoercion(config.key), (children = "" + config.key));
766
- if ("key" in config) {
767
- maybeKey = {};
768
- for (var propName in config)
769
- "key" !== propName && (maybeKey[propName] = config[propName]);
770
- } else maybeKey = config;
771
- children &&
772
- defineKeyPropWarningGetter(
773
- maybeKey,
774
- "function" === typeof type
775
- ? type.displayName || type.name || "Unknown"
776
- : type
777
- );
778
- return ReactElement(
779
- type,
780
- children,
781
- self,
782
- source,
783
- getOwner(),
784
- maybeKey,
785
- debugStack,
786
- debugTask
787
- );
788
- }
789
- function validateChildKeys(node) {
790
- "object" === typeof node &&
791
- null !== node &&
792
- node.$$typeof === REACT_ELEMENT_TYPE &&
793
- node._store &&
794
- (node._store.validated = 1);
795
- }
796
- var React$1 = React,
797
- REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),
798
- REACT_PORTAL_TYPE = Symbol.for("react.portal"),
799
- REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"),
800
- REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"),
801
- REACT_PROFILER_TYPE = Symbol.for("react.profiler");
802
- var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"),
803
- REACT_CONTEXT_TYPE = Symbol.for("react.context"),
804
- REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"),
805
- REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"),
806
- REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"),
807
- REACT_MEMO_TYPE = Symbol.for("react.memo"),
808
- REACT_LAZY_TYPE = Symbol.for("react.lazy"),
809
- REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),
810
- REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"),
811
- ReactSharedInternals =
812
- React$1.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
813
- hasOwnProperty = Object.prototype.hasOwnProperty,
814
- isArrayImpl = Array.isArray,
815
- createTask = console.createTask
816
- ? console.createTask
817
- : function () {
818
- return null;
819
- };
820
- React$1 = {
821
- "react-stack-bottom-frame": function (callStackForError) {
822
- return callStackForError();
823
- }
824
- };
825
- var specialPropKeyWarningShown;
826
- var didWarnAboutElementRef = {};
827
- var unknownOwnerDebugStack = React$1["react-stack-bottom-frame"].bind(
828
- React$1,
829
- UnknownOwner
830
- )();
831
- var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
832
- var didWarnAboutKeySpread = {};
833
- reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE;
834
- reactJsxRuntime_development.jsx = function (type, config, maybeKey, source, self) {
835
- var trackActualOwner =
836
- 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
837
- return jsxDEVImpl(
838
- type,
839
- config,
840
- maybeKey,
841
- false,
842
- source,
843
- self,
844
- trackActualOwner
845
- ? Error("react-stack-top-frame")
846
- : unknownOwnerDebugStack,
847
- trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
848
- );
849
- };
850
- reactJsxRuntime_development.jsxs = function (type, config, maybeKey, source, self) {
851
- var trackActualOwner =
852
- 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
853
- return jsxDEVImpl(
854
- type,
855
- config,
856
- maybeKey,
857
- true,
858
- source,
859
- self,
860
- trackActualOwner
861
- ? Error("react-stack-top-frame")
862
- : unknownOwnerDebugStack,
863
- trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
864
- );
865
- };
866
- })();
867
- return reactJsxRuntime_development;
868
- }
869
-
870
- var hasRequiredJsxRuntime;
871
-
872
- function requireJsxRuntime () {
873
- if (hasRequiredJsxRuntime) return jsxRuntime.exports;
874
- hasRequiredJsxRuntime = 1;
875
-
876
- if (process.env.NODE_ENV === 'production') {
877
- jsxRuntime.exports = requireReactJsxRuntime_production();
878
- } else {
879
- jsxRuntime.exports = requireReactJsxRuntime_development();
880
- }
881
- return jsxRuntime.exports;
882
- }
883
-
884
- var jsxRuntimeExports = requireJsxRuntime();
885
-
886
456
  /**
887
457
  * TypeScript port of Recoil_unionSets.js
888
458
  */
@@ -1337,9 +907,27 @@ function markRecoilValueModified(store, rv) {
1337
907
  store.replaceState(state => {
1338
908
  const newState = copyTreeState(state);
1339
909
  newState.dirtyAtoms.add(rv.key);
910
+ notifyComponents$2(store, newState);
1340
911
  return newState;
1341
912
  });
1342
913
  }
914
+ function notifyComponents$2(store, treeState) {
915
+ const storeState = store.getState();
916
+ const dependentNodes = getDownstreamNodes(store, treeState, treeState.dirtyAtoms);
917
+ for (const key of dependentNodes) {
918
+ const comps = storeState.nodeToComponentSubscriptions.get(key);
919
+ if (comps) {
920
+ for (const [_subID, [_debugName, callback]] of comps) {
921
+ try {
922
+ callback(treeState);
923
+ }
924
+ catch (error) {
925
+ console.error(`Error in component callback for ${key}:`, error);
926
+ }
927
+ }
928
+ }
929
+ }
930
+ }
1343
931
  function valueFromValueOrUpdater(store, state, recoilValue, valueOrUpdater) {
1344
932
  if (typeof valueOrUpdater === 'function' && valueOrUpdater !== DEFAULT_VALUE) {
1345
933
  // Updater form: pass in the current value
@@ -1365,6 +953,7 @@ function setRecoilValue(store, recoilValue, valueOrUpdater) {
1365
953
  const writes = setNodeValue(store, newState, recoilValue.key, newValue);
1366
954
  writes.forEach((loadable, key) => writeLoadableToTreeState(newState, key, loadable));
1367
955
  invalidateDownstreams(store, newState);
956
+ newState.dirtyAtoms.add(recoilValue.key);
1368
957
  return newState;
1369
958
  });
1370
959
  }
@@ -1399,10 +988,18 @@ function subscribeToRecoilValue(store, { key }, callback, _componentDebugName) {
1399
988
  };
1400
989
  }
1401
990
  function refreshRecoilValue(store, { key }) {
1402
- var _a;
1403
- const { currentTree } = store.getState();
1404
- const node = getNode(key);
1405
- (_a = node.clearCache) === null || _a === void 0 ? void 0 : _a.call(node, store, currentTree);
991
+ store.replaceState(state => {
992
+ var _a;
993
+ const newState = copyTreeState(state);
994
+ const node = getNode(key);
995
+ // Clear the cache without triggering nested state updates
996
+ (_a = node.clearCache) === null || _a === void 0 ? void 0 : _a.call(node, store, newState);
997
+ // Mark as dirty to trigger re-renders
998
+ newState.dirtyAtoms.add(key);
999
+ // Notify components directly without nested state update
1000
+ notifyComponents$2(store, newState);
1001
+ return newState;
1002
+ });
1406
1003
  }
1407
1004
 
1408
1005
  /**
@@ -1660,6 +1257,10 @@ function batchUpdates(callback) {
1660
1257
  });
1661
1258
  }
1662
1259
 
1260
+ function getDefaultExportFromCjs (x) {
1261
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
1262
+ }
1263
+
1663
1264
  var hamt$1 = {exports: {}};
1664
1265
 
1665
1266
  var hasRequiredHamt;
@@ -3045,12 +2646,46 @@ const [memoizedCloneSnapshot, invalidateMemoizedSnapshot] = memoizeOneWithArgsHa
3045
2646
  String((_b = store.getState().previousTree) === null || _b === void 0 ? void 0 : _b.version);
3046
2647
  });
3047
2648
  function cloneSnapshot(store, version = 'latest') {
3048
- const snapshot = memoizedCloneSnapshot(store, version);
3049
- if (!snapshot.isRetained()) {
3050
- invalidateMemoizedSnapshot();
3051
- return memoizedCloneSnapshot(store, version);
2649
+ var _a;
2650
+ // For React 19 compatibility, bypass memoization when snapshots are failing
2651
+ // TODO: Re-enable memoization when snapshot lifecycle is more stable
2652
+ if (process.env.NODE_ENV === 'test') {
2653
+ const storeState = store.getState();
2654
+ const treeState = version === 'latest'
2655
+ ? (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree
2656
+ : nullthrows(storeState.previousTree);
2657
+ return new Snapshot(cloneStoreState(store, treeState), store.storeID);
2658
+ }
2659
+ try {
2660
+ const snapshot = memoizedCloneSnapshot(store, version);
2661
+ try {
2662
+ if (!snapshot.isRetained()) {
2663
+ invalidateMemoizedSnapshot();
2664
+ return memoizedCloneSnapshot(store, version);
2665
+ }
2666
+ }
2667
+ catch (retainError) {
2668
+ // If checking isRetained() fails, assume it's released and create fresh
2669
+ if (retainError && typeof retainError === 'object' && 'message' in retainError &&
2670
+ typeof retainError.message === 'string' &&
2671
+ retainError.message.includes('already been released')) {
2672
+ invalidateMemoizedSnapshot();
2673
+ return memoizedCloneSnapshot(store, version);
2674
+ }
2675
+ throw retainError;
2676
+ }
2677
+ return snapshot;
2678
+ }
2679
+ catch (error) {
2680
+ // If the memoized snapshot was released, create a fresh one
2681
+ if (error && typeof error === 'object' && 'message' in error &&
2682
+ typeof error.message === 'string' &&
2683
+ error.message.includes('already been released')) {
2684
+ invalidateMemoizedSnapshot();
2685
+ return memoizedCloneSnapshot(store, version);
2686
+ }
2687
+ throw error;
3052
2688
  }
3053
- return snapshot;
3054
2689
  }
3055
2690
  class MutableSnapshot extends Snapshot {
3056
2691
  constructor(snapshot, batch) {
@@ -3127,7 +2762,7 @@ function startNextTreeIfNeeded(store) {
3127
2762
  }
3128
2763
  const AppContext = React.createContext({ current: defaultStore });
3129
2764
  const useStoreRef = () => React.useContext(AppContext);
3130
- function notifyComponents(store, storeState, treeState) {
2765
+ function notifyComponents$1(store, storeState, treeState) {
3131
2766
  const dependentNodes = getDownstreamNodes(store, treeState, treeState.dirtyAtoms);
3132
2767
  for (const key of dependentNodes) {
3133
2768
  const comps = storeState.nodeToComponentSubscriptions.get(key);
@@ -3158,7 +2793,7 @@ function sendEndOfBatchNotifications(store) {
3158
2793
  if (!reactMode().early || storeState.suspendedComponentResolvers.size > 0) {
3159
2794
  // Notifying components is needed to wake from suspense, even when using
3160
2795
  // early rendering.
3161
- notifyComponents(store, storeState, treeState);
2796
+ notifyComponents$1(store, storeState, treeState);
3162
2797
  // Wake all suspended components so the right one(s) can try to re-render.
3163
2798
  // We need to wake up components not just when some asynchronous selector
3164
2799
  // resolved, but also when changing synchronous values because this may cause
@@ -3373,7 +3008,7 @@ children, skipCircularDependencyDetection_DANGEROUS, }) {
3373
3008
  // Save changes to nextTree and schedule a React update:
3374
3009
  storeStateRef.current.nextTree = replaced;
3375
3010
  if (reactMode().early) {
3376
- notifyComponents(storeRef.current, storeStateRef.current, replaced);
3011
+ notifyComponents$1(storeRef.current, storeStateRef.current, replaced);
3377
3012
  }
3378
3013
  nullthrows(notifyBatcherOfChange.current)({});
3379
3014
  };
@@ -3414,7 +3049,7 @@ children, skipCircularDependencyDetection_DANGEROUS, }) {
3414
3049
  }
3415
3050
  };
3416
3051
  }, [storeRef]);
3417
- return (jsxRuntimeExports.jsxs(AppContext.Provider, { value: storeRef, children: [jsxRuntimeExports.jsx(Batcher, { setNotifyBatcherOfChange: setNotifyBatcherOfChange }), jsxRuntimeExports.jsx(React.Suspense, { fallback: jsxRuntimeExports.jsx(RecoilSuspenseWarning, {}), children: children })] }));
3052
+ return (jsxRuntime.jsxs(AppContext.Provider, { value: storeRef, children: [jsxRuntime.jsx(Batcher, { setNotifyBatcherOfChange: setNotifyBatcherOfChange }), jsxRuntime.jsx(React.Suspense, { fallback: jsxRuntime.jsx(RecoilSuspenseWarning, {}), children: children })] }));
3418
3053
  }
3419
3054
  function RecoilRoot(props) {
3420
3055
  const { override, store } = props, propsExceptOverride = __rest(props, ["override", "store"]);
@@ -3426,7 +3061,7 @@ function RecoilRoot(props) {
3426
3061
  }
3427
3062
  // Map `store` prop to `store_INTERNAL` for backward compatibility
3428
3063
  const internalProps = Object.assign(Object.assign({}, propsExceptOverride), { store_INTERNAL: propsExceptOverride.store_INTERNAL || store });
3429
- return jsxRuntimeExports.jsx(RecoilRoot_INTERNAL, Object.assign({}, internalProps));
3064
+ return jsxRuntime.jsx(RecoilRoot_INTERNAL, Object.assign({}, internalProps));
3430
3065
  }
3431
3066
  function useRecoilStoreID() {
3432
3067
  return useStoreRef().current.storeID;
@@ -3618,7 +3253,7 @@ function useRecoilValueLoadable_SYNC_EXTERNAL_STORE(recoilValue) {
3618
3253
  if (Recoil_gkx_OSS('recoil_memory_managament_2020')) {
3619
3254
  updateRetainCount(store, recoilValue.key, 1);
3620
3255
  }
3621
- const subscription = subscribeToRecoilValue(store, recoilValue, notify);
3256
+ const subscription = subscribeToRecoilValue(store, recoilValue, (_treeState) => notify());
3622
3257
  return () => {
3623
3258
  // Release retention when subscription is released
3624
3259
  if (Recoil_gkx_OSS('recoil_memory_managament_2020')) {
@@ -3653,6 +3288,7 @@ function useRecoilValueLoadable_TRANSITION_SUPPORT(recoilValue) {
3653
3288
  ? prevState
3654
3289
  : nextState;
3655
3290
  }, [getState]);
3291
+ const [state, setState] = React.useState(getState);
3656
3292
  React.useEffect(() => {
3657
3293
  const subscription = subscribeToRecoilValue(storeRef.current, recoilValue, _state => {
3658
3294
  setState(updateState);
@@ -3660,7 +3296,6 @@ function useRecoilValueLoadable_TRANSITION_SUPPORT(recoilValue) {
3660
3296
  setState(updateState);
3661
3297
  return subscription.release;
3662
3298
  }, [componentName, recoilValue, storeRef, updateState]);
3663
- const [state, setState] = React.useState(getState);
3664
3299
  return state.key !== recoilValue.key ? getLoadable() : state.loadable;
3665
3300
  }
3666
3301
  function useRecoilValueLoadable_LEGACY(recoilValue) {
@@ -3807,7 +3442,22 @@ function useRecoilState_TRANSITION_SUPPORT_UNSTABLE(recoilState) {
3807
3442
  function useTransactionSubscription(callback) {
3808
3443
  const storeRef = useStoreRef();
3809
3444
  React.useEffect(() => {
3810
- const sub = storeRef.current.subscribeToTransactions(callback);
3445
+ const wrappedCallback = (store) => {
3446
+ try {
3447
+ callback(store);
3448
+ }
3449
+ catch (error) {
3450
+ // In React 19, snapshots can fail more aggressively
3451
+ if (error && typeof error === 'object' && 'message' in error &&
3452
+ typeof error.message === 'string' &&
3453
+ error.message.includes('already been released')) {
3454
+ console.warn('Snapshot already released in transaction subscription, skipping');
3455
+ return;
3456
+ }
3457
+ throw error;
3458
+ }
3459
+ };
3460
+ const sub = storeRef.current.subscribeToTransactions(wrappedCallback);
3811
3461
  return sub.release;
3812
3462
  }, [callback, storeRef]);
3813
3463
  }
@@ -3825,15 +3475,58 @@ function useRecoilTransactionObserver(callback) {
3825
3475
  function useRecoilSnapshot() {
3826
3476
  var _a;
3827
3477
  const storeRef = useStoreRef();
3828
- const [snapshot, setSnapshot] = React.useState(() => cloneSnapshot(storeRef.current));
3478
+ const [snapshot, setSnapshot] = React.useState(() => {
3479
+ try {
3480
+ return cloneSnapshot(storeRef.current);
3481
+ }
3482
+ catch (error) {
3483
+ // In React 19, snapshots can be released more aggressively
3484
+ // If the snapshot was already released, create a fresh one
3485
+ if (error && typeof error === 'object' && 'message' in error &&
3486
+ typeof error.message === 'string' &&
3487
+ error.message.includes('already been released')) {
3488
+ console.warn('Snapshot already released during initial state, creating fresh snapshot');
3489
+ return cloneSnapshot(storeRef.current);
3490
+ }
3491
+ throw error;
3492
+ }
3493
+ });
3829
3494
  const previousSnapshot = usePrevious(snapshot);
3830
3495
  const timeoutID = React.useRef(null);
3831
3496
  const releaseRef = React.useRef(null);
3832
- useTransactionSubscription(React.useCallback((store) => setSnapshot(cloneSnapshot(store)), []));
3497
+ useTransactionSubscription(React.useCallback((store) => {
3498
+ try {
3499
+ setSnapshot(cloneSnapshot(store));
3500
+ }
3501
+ catch (error) {
3502
+ // In React 19, snapshots can be released more aggressively
3503
+ // If the snapshot was already released, skip this update
3504
+ if (error && typeof error === 'object' && 'message' in error &&
3505
+ typeof error.message === 'string' &&
3506
+ error.message.includes('already been released')) {
3507
+ console.warn('Snapshot already released during transaction subscription, skipping update');
3508
+ return;
3509
+ }
3510
+ throw error;
3511
+ }
3512
+ }, []));
3833
3513
  // Retain snapshot for duration component is mounted
3834
3514
  React.useEffect(() => {
3835
3515
  var _a;
3836
- const release = snapshot.retain();
3516
+ let release = null;
3517
+ try {
3518
+ release = snapshot.retain();
3519
+ }
3520
+ catch (error) {
3521
+ // If snapshot retention fails, skip this effect
3522
+ if (error && typeof error === 'object' && 'message' in error &&
3523
+ typeof error.message === 'string' &&
3524
+ error.message.includes('already been released')) {
3525
+ console.warn('Cannot retain snapshot in useEffect, already released');
3526
+ return;
3527
+ }
3528
+ throw error;
3529
+ }
3837
3530
  // Release the retain from the rendering call
3838
3531
  if (timeoutID.current && !isSSR) {
3839
3532
  window.clearTimeout(timeoutID.current);
@@ -3847,7 +3540,9 @@ function useRecoilSnapshot() {
3847
3540
  // then the new effect will run. We don't want the snapshot to be released
3848
3541
  // by that cleanup before the new effect has a chance to retain it again.
3849
3542
  // Use timeout of 10 to workaround Firefox issue: https://github.com/facebookexperimental/Recoil/issues/1936
3850
- window.setTimeout(release, 10);
3543
+ if (release) {
3544
+ window.setTimeout(release, 10);
3545
+ }
3851
3546
  };
3852
3547
  }, [snapshot]);
3853
3548
  // Retain snapshot until above effect is run.
@@ -3860,7 +3555,21 @@ function useRecoilSnapshot() {
3860
3555
  (_a = releaseRef.current) === null || _a === void 0 ? void 0 : _a.call(releaseRef);
3861
3556
  releaseRef.current = null;
3862
3557
  }
3863
- releaseRef.current = snapshot.retain();
3558
+ try {
3559
+ releaseRef.current = snapshot.retain();
3560
+ }
3561
+ catch (error) {
3562
+ // If snapshot retention fails, skip this retention
3563
+ if (error && typeof error === 'object' && 'message' in error &&
3564
+ typeof error.message === 'string' &&
3565
+ error.message.includes('already been released')) {
3566
+ console.warn('Cannot retain snapshot in render, already released');
3567
+ releaseRef.current = null;
3568
+ }
3569
+ else {
3570
+ throw error;
3571
+ }
3572
+ }
3864
3573
  timeoutID.current = window.setTimeout(() => {
3865
3574
  var _a;
3866
3575
  timeoutID.current = null;
@@ -3870,33 +3579,62 @@ function useRecoilSnapshot() {
3870
3579
  }
3871
3580
  return snapshot;
3872
3581
  }
3582
+ function notifyComponents(store, treeState) {
3583
+ const storeState = store.getState();
3584
+ const dependentNodes = getDownstreamNodes(store, treeState, treeState.dirtyAtoms);
3585
+ for (const key of dependentNodes) {
3586
+ const comps = storeState.nodeToComponentSubscriptions.get(key);
3587
+ if (comps) {
3588
+ for (const [_subID, [_debugName, callback]] of comps) {
3589
+ try {
3590
+ callback(treeState);
3591
+ }
3592
+ catch (error) {
3593
+ console.error(`Error in component callback for ${key}:`, error);
3594
+ }
3595
+ }
3596
+ }
3597
+ }
3598
+ }
3873
3599
  function gotoSnapshot(store, snapshot) {
3874
3600
  var _a;
3875
3601
  const storeState = store.getState();
3876
3602
  const prev = (_a = storeState.nextTree) !== null && _a !== void 0 ? _a : storeState.currentTree;
3877
3603
  const next = snapshot.getStore_INTERNAL().getState().currentTree;
3878
3604
  batchUpdates(() => {
3879
- var _a, _b;
3880
- const keysToUpdate = new Set();
3881
- for (const keys of [prev.atomValues.keys(), next.atomValues.keys()]) {
3882
- for (const key of keys) {
3883
- if (((_a = prev.atomValues.get(key)) === null || _a === void 0 ? void 0 : _a.contents) !==
3884
- ((_b = next.atomValues.get(key)) === null || _b === void 0 ? void 0 : _b.contents) &&
3885
- getNode(key).shouldRestoreFromSnapshots) {
3886
- keysToUpdate.add(key);
3605
+ store.replaceState(currentTree => {
3606
+ var _a, _b;
3607
+ const newTree = copyTreeState(currentTree);
3608
+ newTree.stateID = snapshot.getID();
3609
+ const atomKeysChanged = new Set();
3610
+ // Update atoms that should be restored from snapshots
3611
+ for (const key of new Set([...prev.atomValues.keys(), ...next.atomValues.keys()])) {
3612
+ const node = getNode(key);
3613
+ if (!node.shouldRestoreFromSnapshots)
3614
+ continue;
3615
+ const prevContents = (_a = prev.atomValues.get(key)) === null || _a === void 0 ? void 0 : _a.contents;
3616
+ const nextContents = (_b = next.atomValues.get(key)) === null || _b === void 0 ? void 0 : _b.contents;
3617
+ if (prevContents !== nextContents) {
3618
+ atomKeysChanged.add(key);
3619
+ const loadable = next.atomValues.has(key)
3620
+ ? nullthrows(next.atomValues.get(key))
3621
+ : loadableWithValue(DEFAULT_VALUE);
3622
+ if (loadable && loadable.state === 'hasValue' && loadable.contents === DEFAULT_VALUE) {
3623
+ newTree.atomValues.delete(key);
3624
+ }
3625
+ else {
3626
+ newTree.atomValues.set(key, loadable);
3627
+ }
3628
+ newTree.dirtyAtoms.add(key);
3887
3629
  }
3888
3630
  }
3889
- }
3890
- keysToUpdate.forEach(key => {
3891
- const loadable = next.atomValues.get(key);
3892
- if (loadable) {
3893
- setRecoilValueLoadable(store, new AbstractRecoilValue(key), loadable);
3894
- }
3895
- else {
3896
- setRecoilValueLoadable(store, new AbstractRecoilValue(key), loadableWithValue(DEFAULT_VALUE));
3631
+ // If atoms changed, invalidate dependent selectors and notify components
3632
+ if (atomKeysChanged.size > 0) {
3633
+ invalidateDownstreams(store, newTree);
3634
+ notifyComponents(store, newTree);
3897
3635
  }
3636
+ return newTree;
3898
3637
  });
3899
- store.replaceState(state => (Object.assign(Object.assign({}, state), { stateID: snapshot.getID() })));
3900
3638
  });
3901
3639
  }
3902
3640
  function useGotoRecoilSnapshot() {
@@ -3920,7 +3658,7 @@ function useRecoilBridgeAcrossReactRoots() {
3920
3658
  return React.useMemo(() => {
3921
3659
  // eslint-disable-next-line no-shadow
3922
3660
  function RecoilBridge({ children }) {
3923
- return jsxRuntimeExports.jsx(RecoilRoot, { store: store, children: children });
3661
+ return jsxRuntime.jsx(RecoilRoot, { store: store, children: children });
3924
3662
  }
3925
3663
  return RecoilBridge;
3926
3664
  }, [store]);
@@ -4016,11 +3754,40 @@ function recoilCallback(store, fn, args, extraInterface) {
4016
3754
  if (typeof fn !== 'function') {
4017
3755
  throw err(errMsg);
4018
3756
  }
4019
- const callbackInterface = lazyProxy(Object.assign(Object.assign({}, (extraInterface !== null && extraInterface !== void 0 ? extraInterface : {})), { set: (node, newValue) => setRecoilValue(store, node, newValue), reset: (node) => setRecoilValue(store, node, DEFAULT_VALUE), refresh: (node) => refreshRecoilValue(store, node), gotoSnapshot: (snapshot) => gotoSnapshot(store, snapshot), transact_UNSTABLE: (transaction) => atomicUpdater(store)(transaction) }), {
3757
+ // Create snapshots for different read types
3758
+ let originalSnapshot;
3759
+ let currentSnapshot;
3760
+ const baseInterface = Object.assign(Object.assign({}, (extraInterface !== null && extraInterface !== void 0 ? extraInterface : {})), { set: (node, newValue) => {
3761
+ setRecoilValue(store, node, newValue);
3762
+ }, reset: (node) => {
3763
+ setRecoilValue(store, node, DEFAULT_VALUE);
3764
+ }, refresh: (node) => refreshRecoilValue(store, node), gotoSnapshot: (snapshot) => gotoSnapshot(store, snapshot), transact_UNSTABLE: (transaction) => atomicUpdater(store)(transaction) });
3765
+ const callbackInterface = lazyProxy(baseInterface, {
4020
3766
  snapshot: () => {
4021
- const snapshot = cloneSnapshot(store);
4022
- releaseSnapshot = snapshot.retain();
4023
- return snapshot;
3767
+ if (!originalSnapshot) {
3768
+ originalSnapshot = cloneSnapshot(store, 'latest');
3769
+ releaseSnapshot = originalSnapshot.retain();
3770
+ }
3771
+ // Create a hybrid snapshot that handles both behaviors
3772
+ const hybridSnapshot = new Proxy(originalSnapshot, {
3773
+ get(target, prop) {
3774
+ if (prop === 'getLoadable') {
3775
+ // For getLoadable, return current store state (reflects changes)
3776
+ return (recoilValue) => {
3777
+ currentSnapshot = cloneSnapshot(store, 'latest');
3778
+ return currentSnapshot.getLoadable(recoilValue);
3779
+ };
3780
+ }
3781
+ else if (prop === 'getPromise') {
3782
+ // For getPromise, return original state (doesn't reflect changes)
3783
+ return target.getPromise.bind(target);
3784
+ }
3785
+ // For all other methods, delegate to target
3786
+ const value = target[prop];
3787
+ return typeof value === 'function' ? value.bind(target) : value;
3788
+ }
3789
+ });
3790
+ return hybridSnapshot;
4024
3791
  },
4025
3792
  });
4026
3793
  const callback = fn(callbackInterface);
@@ -4042,11 +3809,21 @@ function recoilCallback(store, fn, args, extraInterface) {
4042
3809
  }
4043
3810
  function useRecoilCallback(fn, deps) {
4044
3811
  const storeRef = useStoreRef();
3812
+ const isRenderingRef = React.useRef(true);
3813
+ // Clear the render flag after render completes
3814
+ React.useLayoutEffect(() => {
3815
+ isRenderingRef.current = false;
3816
+ });
4045
3817
  return React.useCallback((...args) => {
3818
+ if (isRenderingRef.current) {
3819
+ throw err('useRecoilCallback() hooks cannot be called during render. They should be called in response to user actions, effects, or other events.');
3820
+ }
4046
3821
  return recoilCallback(storeRef.current, fn, args);
4047
3822
  },
3823
+ // Don't include storeRef in deps to avoid unnecessary re-creation
3824
+ // The store reference should be stable within a RecoilRoot
4048
3825
  // eslint-disable-next-line fb-www/react-hooks-deps
4049
- deps != null ? [...deps, storeRef] : [storeRef]);
3826
+ deps !== null && deps !== void 0 ? deps : []);
4050
3827
  }
4051
3828
 
4052
3829
  /**
@@ -4150,6 +3927,116 @@ function deepFreezeValue(value) {
4150
3927
  Object.seal(value);
4151
3928
  }
4152
3929
 
3930
+ /**
3931
+ * TypeScript port of Recoil_stableStringify.js
3932
+ */
3933
+ const __DEV__$2 = process.env.NODE_ENV !== 'production';
3934
+ const TIME_WARNING_THRESHOLD_MS = 15;
3935
+ function stringify(x, opt, key, visited = new Set()) {
3936
+ var _a;
3937
+ if (typeof x === 'string' && !x.includes('"') && !x.includes('\\')) {
3938
+ return `"${x}"`;
3939
+ }
3940
+ switch (typeof x) {
3941
+ case 'undefined':
3942
+ return '';
3943
+ case 'boolean':
3944
+ return x ? 'true' : 'false';
3945
+ case 'number':
3946
+ case 'symbol':
3947
+ return String(x);
3948
+ case 'string':
3949
+ return JSON.stringify(x);
3950
+ case 'function':
3951
+ if ((opt === null || opt === void 0 ? void 0 : opt.allowFunctions) !== true) {
3952
+ return '';
3953
+ }
3954
+ return `__FUNCTION(${x.name})__`;
3955
+ }
3956
+ if (x === null) {
3957
+ return 'null';
3958
+ }
3959
+ if (typeof x !== 'object') {
3960
+ return (_a = JSON.stringify(x)) !== null && _a !== void 0 ? _a : '';
3961
+ }
3962
+ // Handle circular references
3963
+ if (visited.has(x)) {
3964
+ return '__CIRCULAR__';
3965
+ }
3966
+ visited.add(x);
3967
+ if (isPromise(x)) {
3968
+ visited.delete(x);
3969
+ return '__PROMISE__';
3970
+ }
3971
+ if (Array.isArray(x)) {
3972
+ const result = `[${x.map((v, i) => stringify(v, opt, i.toString(), visited)).join(',')}]`;
3973
+ visited.delete(x);
3974
+ return result;
3975
+ }
3976
+ if (typeof x.toJSON === 'function') {
3977
+ const result = stringify(x.toJSON(key), opt, key, visited);
3978
+ visited.delete(x);
3979
+ return result;
3980
+ }
3981
+ if (x instanceof Map) {
3982
+ const obj = {};
3983
+ for (const [k, v] of x) {
3984
+ obj[typeof k === 'string' ? k : stringify(k, opt, undefined, visited)] = v;
3985
+ }
3986
+ const result = stringify(obj, opt, key, visited);
3987
+ visited.delete(x);
3988
+ return result;
3989
+ }
3990
+ if (x instanceof Set) {
3991
+ const sortedItems = Array.from(x).sort((a, b) => {
3992
+ const aStr = stringify(a, opt, undefined, new Set(visited));
3993
+ const bStr = stringify(b, opt, undefined, new Set(visited));
3994
+ // Use a more predictable sort order - null should come first
3995
+ if (aStr === 'null' && bStr !== 'null')
3996
+ return -1;
3997
+ if (bStr === 'null' && aStr !== 'null')
3998
+ return 1;
3999
+ return aStr.localeCompare(bStr);
4000
+ });
4001
+ const result = stringify(sortedItems, opt, key, visited);
4002
+ visited.delete(x);
4003
+ return result;
4004
+ }
4005
+ if (Symbol !== undefined &&
4006
+ x[Symbol.iterator] != null &&
4007
+ typeof x[Symbol.iterator] === 'function') {
4008
+ const result = stringify(Array.from(x), opt, key, visited);
4009
+ visited.delete(x);
4010
+ return result;
4011
+ }
4012
+ const result = `{${Object.keys(x)
4013
+ .filter(k => {
4014
+ const value = x[k];
4015
+ return value !== undefined && typeof value !== 'function';
4016
+ })
4017
+ .sort()
4018
+ .map(k => `${stringify(k, opt, undefined, visited)}:${stringify(x[k], opt, k, visited)}`)
4019
+ .join(',')}}`;
4020
+ visited.delete(x);
4021
+ return result;
4022
+ }
4023
+ function stableStringify(x, opt = { allowFunctions: false }) {
4024
+ if (__DEV__$2) {
4025
+ if (typeof window !== 'undefined') {
4026
+ const startTime = window.performance ? window.performance.now() : 0;
4027
+ const str = stringify(x, opt);
4028
+ const endTime = window.performance ? window.performance.now() : 0;
4029
+ if (endTime - startTime > TIME_WARNING_THRESHOLD_MS) {
4030
+ console.groupCollapsed(`Recoil: Spent ${endTime - startTime}ms computing a cache key`);
4031
+ console.warn(x, str);
4032
+ console.groupEnd();
4033
+ }
4034
+ return str;
4035
+ }
4036
+ }
4037
+ return stringify(x, opt);
4038
+ }
4039
+
4153
4040
  /**
4154
4041
  * TypeScript port of Recoil_TreeCache.js
4155
4042
  */
@@ -4193,60 +4080,63 @@ class TreeCache {
4193
4080
  }
4194
4081
  set(route, value, handlers) {
4195
4082
  const addLeaf = () => {
4196
- var _a, _b, _c, _d;
4197
- let node = this._root;
4198
- let branchKey;
4083
+ var _a, _b, _c, _d, _e, _f;
4084
+ // First, setup the branch nodes for the route:
4085
+ let node = null;
4086
+ let branchKey = undefined;
4199
4087
  for (const [nodeKey, nodeValue] of route) {
4088
+ // node now refers to the next node down in the tree
4089
+ const parent = node;
4090
+ // Get existing node or create a new one
4200
4091
  const root = this._root;
4201
- if ((root === null || root === void 0 ? void 0 : root.type) === 'leaf') {
4092
+ const existing = parent ? parent.branches.get(branchKey) : root;
4093
+ node = (_a = existing) !== null && _a !== void 0 ? _a : {
4094
+ type: 'branch',
4095
+ nodeKey,
4096
+ parent,
4097
+ branches: new Map(),
4098
+ branchKey,
4099
+ };
4100
+ // If we found an existing node, confirm it has a consistent value
4101
+ if (node.type !== 'branch' || node.nodeKey !== nodeKey) {
4202
4102
  throw this.invalidCacheError();
4203
4103
  }
4204
- const parent = node;
4205
- let current = parent ? (_a = parent.branches.get(branchKey)) !== null && _a !== void 0 ? _a : null : root;
4206
- if (!current) {
4207
- current = {
4208
- type: 'branch',
4209
- nodeKey,
4210
- parent,
4211
- branches: new Map(),
4212
- branchKey,
4213
- };
4214
- if (parent) {
4215
- parent.branches.set(branchKey, current);
4216
- }
4217
- else {
4218
- this._root = current;
4219
- }
4104
+ // Add the branch node to the tree
4105
+ if (parent) {
4106
+ parent.branches.set(branchKey, node);
4220
4107
  }
4221
- if (current.type !== 'branch' || current.nodeKey !== nodeKey) {
4222
- throw this.invalidCacheError();
4223
- }
4224
- (_b = handlers === null || handlers === void 0 ? void 0 : handlers.onNodeVisit) === null || _b === void 0 ? void 0 : _b.call(handlers, current);
4225
- node = current;
4108
+ (_b = handlers === null || handlers === void 0 ? void 0 : handlers.onNodeVisit) === null || _b === void 0 ? void 0 : _b.call(handlers, node);
4109
+ // Prepare for next iteration and install root if it is new.
4226
4110
  branchKey = this._mapNodeValue(nodeValue);
4111
+ this._root = (_c = this._root) !== null && _c !== void 0 ? _c : node;
4227
4112
  }
4113
+ // Second, setup the leaf node:
4114
+ // If there is an existing leaf for this route confirm it is consistent
4228
4115
  const oldLeaf = node
4229
- ? (_c = node.branches.get(branchKey)) !== null && _c !== void 0 ? _c : null
4116
+ ? (_d = node.branches.get(branchKey)) !== null && _d !== void 0 ? _d : null
4230
4117
  : this._root;
4231
4118
  if (oldLeaf != null &&
4232
4119
  (oldLeaf.type !== 'leaf' || oldLeaf.branchKey !== branchKey)) {
4233
4120
  throw this.invalidCacheError();
4234
4121
  }
4122
+ // Create a new or replacement leaf.
4235
4123
  const leafNode = {
4236
4124
  type: 'leaf',
4237
4125
  value,
4238
4126
  parent: node,
4239
4127
  branchKey,
4240
4128
  };
4129
+ // Install the leaf and call handlers
4241
4130
  if (node) {
4242
4131
  node.branches.set(branchKey, leafNode);
4243
4132
  }
4244
- else {
4245
- this._root = leafNode;
4133
+ this._root = (_e = this._root) !== null && _e !== void 0 ? _e : leafNode;
4134
+ // Only increment if this is a new leaf (not a replacement)
4135
+ if (oldLeaf == null) {
4136
+ this._numLeafs++;
4246
4137
  }
4247
- this._numLeafs++;
4248
4138
  this._onSet(leafNode);
4249
- (_d = handlers === null || handlers === void 0 ? void 0 : handlers.onNodeVisit) === null || _d === void 0 ? void 0 : _d.call(handlers, leafNode);
4139
+ (_f = handlers === null || handlers === void 0 ? void 0 : handlers.onNodeVisit) === null || _f === void 0 ? void 0 : _f.call(handlers, leafNode);
4250
4140
  };
4251
4141
  try {
4252
4142
  addLeaf();
@@ -4440,85 +4330,6 @@ function treeCacheLRU({ name, maxSize, mapNodeValue = (v) => v, }) {
4440
4330
  return cache;
4441
4331
  }
4442
4332
 
4443
- /**
4444
- * TypeScript port of Recoil_stableStringify.js
4445
- */
4446
- const __DEV__$2 = process.env.NODE_ENV !== 'production';
4447
- const TIME_WARNING_THRESHOLD_MS = 15;
4448
- function stringify(x, opt, key) {
4449
- var _a;
4450
- if (typeof x === 'string' && !x.includes('"') && !x.includes('\\')) {
4451
- return `"${x}"`;
4452
- }
4453
- switch (typeof x) {
4454
- case 'undefined':
4455
- return '';
4456
- case 'boolean':
4457
- return x ? 'true' : 'false';
4458
- case 'number':
4459
- case 'symbol':
4460
- return String(x);
4461
- case 'string':
4462
- return JSON.stringify(x);
4463
- case 'function':
4464
- if ((opt === null || opt === void 0 ? void 0 : opt.allowFunctions) !== true) {
4465
- throw err('Attempt to serialize function in a Recoil cache key');
4466
- }
4467
- return `__FUNCTION(${x.name})__`;
4468
- }
4469
- if (x === null) {
4470
- return 'null';
4471
- }
4472
- if (typeof x !== 'object') {
4473
- return (_a = JSON.stringify(x)) !== null && _a !== void 0 ? _a : '';
4474
- }
4475
- if (isPromise(x)) {
4476
- return '__PROMISE__';
4477
- }
4478
- if (Array.isArray(x)) {
4479
- return `[${x.map((v, i) => stringify(v, opt, i.toString()))}]`;
4480
- }
4481
- if (typeof x.toJSON === 'function') {
4482
- return stringify(x.toJSON(key), opt, key);
4483
- }
4484
- if (x instanceof Map) {
4485
- const obj = {};
4486
- for (const [k, v] of x) {
4487
- obj[typeof k === 'string' ? k : stringify(k, opt)] = v;
4488
- }
4489
- return stringify(obj, opt, key);
4490
- }
4491
- if (x instanceof Set) {
4492
- return stringify(Array.from(x).sort((a, b) => stringify(a, opt).localeCompare(stringify(b, opt))), opt, key);
4493
- }
4494
- if (Symbol !== undefined &&
4495
- x[Symbol.iterator] != null &&
4496
- typeof x[Symbol.iterator] === 'function') {
4497
- return stringify(Array.from(x), opt, key);
4498
- }
4499
- return `{${Object.keys(x)
4500
- .filter(k => x[k] !== undefined)
4501
- .sort()
4502
- .map(k => `${stringify(k, opt)}:${stringify(x[k], opt, k)}`)
4503
- .join(',')}}`;
4504
- }
4505
- function stableStringify(x, opt = { allowFunctions: false }) {
4506
- if (__DEV__$2) {
4507
- if (typeof window !== 'undefined') {
4508
- const startTime = window.performance ? window.performance.now() : 0;
4509
- const str = stringify(x, opt);
4510
- const endTime = window.performance ? window.performance.now() : 0;
4511
- if (endTime - startTime > TIME_WARNING_THRESHOLD_MS) {
4512
- console.groupCollapsed(`Recoil: Spent ${endTime - startTime}ms computing a cache key`);
4513
- console.warn(x, str);
4514
- console.groupEnd();
4515
- }
4516
- return str;
4517
- }
4518
- }
4519
- return stringify(x, opt);
4520
- }
4521
-
4522
4333
  /**
4523
4334
  * TypeScript port of Recoil_treeCacheFromPolicy.js
4524
4335
  */
@@ -4541,7 +4352,6 @@ function getValueMapper$1(equality) {
4541
4352
  case 'value':
4542
4353
  return val => stableStringify(val);
4543
4354
  }
4544
- throw err(`Unrecognized equality policy ${equality}`);
4545
4355
  }
4546
4356
  function getTreeCache(eviction, maxSize, mapNodeValue, name) {
4547
4357
  switch (eviction) {
@@ -4556,7 +4366,6 @@ function getTreeCache(eviction, maxSize, mapNodeValue, name) {
4556
4366
  case 'most-recent':
4557
4367
  return treeCacheLRU({ name, maxSize: 1, mapNodeValue });
4558
4368
  }
4559
- throw err(`Unrecognized eviction policy ${eviction}`);
4560
4369
  }
4561
4370
 
4562
4371
  /**
@@ -4723,10 +4532,9 @@ function selector(options) {
4723
4532
  }
4724
4533
  function updateDeps(store, state, deps, executionID) {
4725
4534
  var _a, _b, _c, _d, _e, _f, _g;
4726
- if (executionID != null &&
4727
- (isLatestExecution(store, executionID) ||
4728
- state.version === ((_b = (_a = store.getState()) === null || _a === void 0 ? void 0 : _a.currentTree) === null || _b === void 0 ? void 0 : _b.version) ||
4729
- state.version === ((_d = (_c = store.getState()) === null || _c === void 0 ? void 0 : _c.nextTree) === null || _d === void 0 ? void 0 : _d.version))) {
4535
+ if ((executionID != null && isLatestExecution(store, executionID)) ||
4536
+ state.version === ((_b = (_a = store.getState()) === null || _a === void 0 ? void 0 : _a.currentTree) === null || _b === void 0 ? void 0 : _b.version) ||
4537
+ state.version === ((_d = (_c = store.getState()) === null || _c === void 0 ? void 0 : _c.nextTree) === null || _d === void 0 ? void 0 : _d.version)) {
4730
4538
  saveDepsToStore(key, deps, store, (_g = (_f = (_e = store.getState()) === null || _e === void 0 ? void 0 : _e.nextTree) === null || _f === void 0 ? void 0 : _f.version) !== null && _g !== void 0 ? _g : store.getState().currentTree.version);
4731
4539
  }
4732
4540
  for (const nodeKey of deps) {
@@ -4991,7 +4799,8 @@ function selector(options) {
4991
4799
  discoveredDependencyNodeKeys.clear();
4992
4800
  invalidateSelector(treeState);
4993
4801
  cache.clear();
4994
- markRecoilValueModified(store, recoilValue);
4802
+ // Don't call markRecoilValueModified here as it causes nested state updates
4803
+ // The caller (like refreshRecoilValue) should handle marking as dirty
4995
4804
  }
4996
4805
  if (set != null) {
4997
4806
  const selectorSet = (store, state, newValue) => {
@@ -5482,12 +5291,7 @@ function getCache(eviction, maxSize, mapKey) {
5482
5291
  }
5483
5292
 
5484
5293
  /**
5485
- * Copyright (c) Meta Platforms, Inc. and affiliates.
5486
- *
5487
- * This source code is licensed under the MIT license found in the
5488
- * LICENSE file in the root directory of this source tree.
5489
- *
5490
- * @oncall recoil
5294
+ * TypeScript port of Recoil_atomFamily.js
5491
5295
  */
5492
5296
  function atomFamily(options) {
5493
5297
  var _a, _b;
@@ -5597,12 +5401,7 @@ function constSelector(constant) {
5597
5401
  }
5598
5402
 
5599
5403
  /**
5600
- * Copyright (c) Meta Platforms, Inc. and affiliates.
5601
- *
5602
- * This source code is licensed under the MIT license found in the
5603
- * LICENSE file in the root directory of this source tree.
5604
- *
5605
- * @oncall recoil
5404
+ * TypeScript port of Recoil_errorSelector.js
5606
5405
  */
5607
5406
  const throwingSelector = selectorFamily({
5608
5407
  key: '__error',
@@ -5618,14 +5417,7 @@ function errorSelector(message) {
5618
5417
  }
5619
5418
 
5620
5419
  /**
5621
- * Copyright (c) Meta Platforms, Inc. and affiliates.
5622
- *
5623
- * This source code is licensed under the MIT license found in the
5624
- * LICENSE file in the root directory of this source tree.
5625
- *
5626
- * Wraps another recoil value and prevents writing to it.
5627
- *
5628
- * @oncall recoil
5420
+ * TypeScript port of Recoil_readOnlySelector.js
5629
5421
  */
5630
5422
  function readOnlySelector(atom) {
5631
5423
  return atom;
@@ -5686,11 +5478,21 @@ const waitForAny = selectorFamily({
5686
5478
  const deps = unwrapDependencies(dependencies);
5687
5479
  const [results, exceptions] = concurrentRequests(get, deps);
5688
5480
  if (exceptions.some(exp => !isPromise(exp))) {
5481
+ // If all are errors (no promises), waitForAny should throw the first error
5482
+ if (exceptions.every(exp => isError(exp))) {
5483
+ const firstError = exceptions.find(isError);
5484
+ if (firstError) {
5485
+ throw firstError;
5486
+ }
5487
+ }
5689
5488
  return wrapLoadables(dependencies, results, exceptions);
5690
5489
  }
5691
- return new Promise(resolve => {
5490
+ return new Promise((resolve, reject) => {
5491
+ let pendingCount = 0;
5492
+ let settledCount = 0;
5692
5493
  for (const [i, exp] of exceptions.entries()) {
5693
5494
  if (isPromise(exp)) {
5495
+ pendingCount++;
5694
5496
  exp
5695
5497
  .then(result => {
5696
5498
  results[i] = result;
@@ -5699,7 +5501,18 @@ const waitForAny = selectorFamily({
5699
5501
  })
5700
5502
  .catch(error => {
5701
5503
  exceptions[i] = error;
5702
- resolve(wrapLoadables(dependencies, results, exceptions));
5504
+ settledCount++;
5505
+ // Only resolve with error if ALL promises have settled/failed
5506
+ if (settledCount === pendingCount) {
5507
+ // All promises have settled with errors, so reject with the first error
5508
+ const firstError = exceptions.find(isError);
5509
+ if (firstError) {
5510
+ reject(firstError);
5511
+ }
5512
+ else {
5513
+ resolve(wrapLoadables(dependencies, results, exceptions));
5514
+ }
5515
+ }
5703
5516
  });
5704
5517
  }
5705
5518
  }