(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jotaiVanillaInternals = {}));
})(this, (function (exports) { 'use strict';

  function _arrayLikeToArray(r, a) {
    (null == a || a > r.length) && (a = r.length);
    for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
    return n;
  }
  function _createForOfIteratorHelperLoose(r, e) {
    var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
    if (t) return (t = t.call(r)).next.bind(t);
    if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) {
      t && (r = t);
      var o = 0;
      return function () {
        return o >= r.length ? {
          done: true
        } : {
          done: false,
          value: r[o++]
        };
      };
    }
    throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }
  function _unsupportedIterableToArray(r, a) {
    if (r) {
      if ("string" == typeof r) return _arrayLikeToArray(r, a);
      var t = {}.toString.call(r).slice(8, -1);
      return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
    }
  }

  function hasInitialValue(atom) {
    return 'init' in atom;
  }
  function isActuallyWritableAtom(atom) {
    return !!atom.write;
  }
  function hasOnMount(atom) {
    return !!atom.onMount;
  }
  function isAtomStateInitialized(atomState) {
    return 'v' in atomState || 'e' in atomState;
  }
  function returnAtomValue(atomState) {
    if ('e' in atomState) {
      throw atomState.e;
    }
    if (!('v' in atomState)) {
      throw new Error('[Bug] atom state is not initialized');
    }
    return atomState.v;
  }
  function isPromiseLike(p) {
    return typeof (p == null ? void 0 : p.then) === 'function';
  }
  function addPendingPromiseToDependency(atom, promise, dependencyAtomState) {
    if (!dependencyAtomState.p.has(atom)) {
      dependencyAtomState.p.add(atom);
      var cleanup = function cleanup() {
        return dependencyAtomState.p.delete(atom);
      };
      promise.then(cleanup, cleanup);
    }
  }
  function getMountedOrPendingDependents(atom, atomState, mountedMap) {
    var mounted = mountedMap.get(atom);
    var mountedDependents = mounted == null ? void 0 : mounted.t;
    var pendingDependents = atomState.p;
    if (!(mountedDependents != null && mountedDependents.size)) {
      return pendingDependents;
    }
    if (!pendingDependents.size) {
      return mountedDependents;
    }
    var dependents = new Set(mountedDependents);
    for (var _iterator = _createForOfIteratorHelperLoose(pendingDependents), _step; !(_step = _iterator()).done;) {
      var a = _step.value;
      dependents.add(a);
    }
    return dependents;
  }
  var createStoreHook = function createStoreHook() {
    var callbacks = new Set();
    var notify = function notify() {
      return callbacks.forEach(function (fn) {
        return fn();
      });
    };
    notify.add = function (fn) {
      callbacks.add(fn);
      return function () {
        return callbacks.delete(fn);
      };
    };
    return notify;
  };
  var createStoreHookForAtoms = function createStoreHookForAtoms() {
    var all = {};
    var callbacks = new WeakMap();
    var notify = function notify(atom) {
      var _callbacks$get, _callbacks$get2;
      (_callbacks$get = callbacks.get(all)) == null || _callbacks$get.forEach(function (fn) {
        return fn(atom);
      });
      (_callbacks$get2 = callbacks.get(atom)) == null || _callbacks$get2.forEach(function (fn) {
        return fn();
      });
    };
    notify.add = function (atom, fn) {
      var key = atom || all;
      var fns = callbacks.get(key);
      if (!fns) {
        fns = new Set();
        callbacks.set(key, fns);
      }
      fns.add(fn);
      return function () {
        fns.delete(fn);
        if (!fns.size) {
          callbacks.delete(key);
        }
      };
    };
    return notify;
  };
  function initializeStoreHooks(storeHooks) {
    var _ref, _ref2, _ref3, _ref4, _ref5, _ref6;
    (_ref = storeHooks).i || (_ref.i = createStoreHookForAtoms());
    (_ref2 = storeHooks).r || (_ref2.r = createStoreHookForAtoms());
    (_ref3 = storeHooks).c || (_ref3.c = createStoreHookForAtoms());
    (_ref4 = storeHooks).m || (_ref4.m = createStoreHookForAtoms());
    (_ref5 = storeHooks).u || (_ref5.u = createStoreHookForAtoms());
    (_ref6 = storeHooks).f || (_ref6.f = createStoreHook());
    return storeHooks;
  }
  var BUILDING_BLOCK_atomRead = function BUILDING_BLOCK_atomRead(_store, atom) {
    for (var _len = arguments.length, params = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
      params[_key - 2] = arguments[_key];
    }
    return atom.read.apply(atom, params);
  };
  var BUILDING_BLOCK_atomWrite = function BUILDING_BLOCK_atomWrite(_store, atom) {
    for (var _len2 = arguments.length, params = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
      params[_key2 - 2] = arguments[_key2];
    }
    return atom.write.apply(atom, params);
  };
  var BUILDING_BLOCK_atomOnInit = function BUILDING_BLOCK_atomOnInit(store, atom) {
    return atom.INTERNAL_onInit == null ? void 0 : atom.INTERNAL_onInit(store);
  };
  var BUILDING_BLOCK_atomOnMount = function BUILDING_BLOCK_atomOnMount(_store, atom, setAtom) {
    return atom.onMount == null ? void 0 : atom.onMount(setAtom);
  };
  var BUILDING_BLOCK_ensureAtomState = function BUILDING_BLOCK_ensureAtomState(store, atom) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var atomStateMap = buildingBlocks[0];
    var storeHooks = buildingBlocks[6];
    var atomOnInit = buildingBlocks[9];
    if (!atom) {
      throw new Error('Atom is undefined or null');
    }
    var atomState = atomStateMap.get(atom);
    if (!atomState) {
      atomState = {
        d: new Map(),
        p: new Set(),
        n: 0
      };
      atomStateMap.set(atom, atomState);
      storeHooks.i == null || storeHooks.i(atom);
      atomOnInit == null || atomOnInit(store, atom);
    }
    return atomState;
  };
  var BUILDING_BLOCK_flushCallbacks = function BUILDING_BLOCK_flushCallbacks(store) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var mountedMap = buildingBlocks[1];
    var changedAtoms = buildingBlocks[3];
    var mountCallbacks = buildingBlocks[4];
    var unmountCallbacks = buildingBlocks[5];
    var storeHooks = buildingBlocks[6];
    var recomputeInvalidatedAtoms = buildingBlocks[13];
    if (!storeHooks.f && !changedAtoms.size && !mountCallbacks.size && !unmountCallbacks.size) {
      return;
    }
    var errors = [];
    var call = function call(fn) {
      try {
        fn();
      } catch (e) {
        errors.push(e);
      }
    };
    do {
      if (storeHooks.f) {
        call(storeHooks.f);
      }
      var callbacks = new Set();
      for (var _iterator2 = _createForOfIteratorHelperLoose(changedAtoms), _step2; !(_step2 = _iterator2()).done;) {
        var _mountedMap$get;
        var _atom = _step2.value;
        var listeners = (_mountedMap$get = mountedMap.get(_atom)) == null ? void 0 : _mountedMap$get.l;
        if (listeners) {
          for (var _iterator6 = _createForOfIteratorHelperLoose(listeners), _step6; !(_step6 = _iterator6()).done;) {
            var _listener = _step6.value;
            callbacks.add(_listener);
          }
        }
      }
      changedAtoms.clear();
      for (var _iterator3 = _createForOfIteratorHelperLoose(unmountCallbacks), _step3; !(_step3 = _iterator3()).done;) {
        var fn = _step3.value;
        callbacks.add(fn);
      }
      unmountCallbacks.clear();
      for (var _iterator4 = _createForOfIteratorHelperLoose(mountCallbacks), _step4; !(_step4 = _iterator4()).done;) {
        var _fn = _step4.value;
        callbacks.add(_fn);
      }
      mountCallbacks.clear();
      for (var _iterator5 = _createForOfIteratorHelperLoose(callbacks), _step5; !(_step5 = _iterator5()).done;) {
        var _fn2 = _step5.value;
        call(_fn2);
      }
      if (changedAtoms.size) {
        recomputeInvalidatedAtoms(store);
      }
    } while (changedAtoms.size || unmountCallbacks.size || mountCallbacks.size);
    if (errors.length) {
      throw new AggregateError(errors);
    }
  };
  var BUILDING_BLOCK_recomputeInvalidatedAtoms = function BUILDING_BLOCK_recomputeInvalidatedAtoms(store) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var mountedMap = buildingBlocks[1];
    var invalidatedAtoms = buildingBlocks[2];
    var changedAtoms = buildingBlocks[3];
    var ensureAtomState = buildingBlocks[11];
    var readAtomState = buildingBlocks[14];
    var mountDependencies = buildingBlocks[17];
    if (!changedAtoms.size) {
      return;
    }
    var sortedReversedAtoms = [];
    var sortedReversedStates = [];
    var visiting = new WeakSet();
    var visited = new WeakSet();
    var stackAtoms = [];
    var stackStates = [];
    for (var _iterator7 = _createForOfIteratorHelperLoose(changedAtoms), _step7; !(_step7 = _iterator7()).done;) {
      var _atom2 = _step7.value;
      stackAtoms.push(_atom2);
      stackStates.push(ensureAtomState(store, _atom2));
    }
    while (stackAtoms.length) {
      var top = stackAtoms.length - 1;
      var a = stackAtoms[top];
      var aState = stackStates[top];
      if (visited.has(a)) {
        stackAtoms.pop();
        stackStates.pop();
        continue;
      }
      if (visiting.has(a)) {
        if (invalidatedAtoms.get(a) === aState.n) {
          sortedReversedAtoms.push(a);
          sortedReversedStates.push(aState);
        } else if (invalidatedAtoms.has(a)) {
          throw new Error('[Bug] invalidated atom exists');
        }
        visited.add(a);
        stackAtoms.pop();
        stackStates.pop();
        continue;
      }
      visiting.add(a);
      for (var _iterator8 = _createForOfIteratorHelperLoose(getMountedOrPendingDependents(a, aState, mountedMap)), _step8; !(_step8 = _iterator8()).done;) {
        var d = _step8.value;
        if (!visiting.has(d)) {
          stackAtoms.push(d);
          stackStates.push(ensureAtomState(store, d));
        }
      }
    }
    for (var i = sortedReversedAtoms.length - 1; i >= 0; --i) {
      var _a = sortedReversedAtoms[i];
      var _aState = sortedReversedStates[i];
      var hasChangedDeps = false;
      for (var _iterator9 = _createForOfIteratorHelperLoose(_aState.d.keys()), _step9; !(_step9 = _iterator9()).done;) {
        var dep = _step9.value;
        if (dep !== _a && changedAtoms.has(dep)) {
          hasChangedDeps = true;
          break;
        }
      }
      if (hasChangedDeps) {
        invalidatedAtoms.set(_a, _aState.n);
        readAtomState(store, _a);
        mountDependencies(store, _a);
      }
      invalidatedAtoms.delete(_a);
    }
  };
  var storeMutationSet = new WeakSet();
  var BUILDING_BLOCK_readAtomState = function BUILDING_BLOCK_readAtomState(store, atom) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var mountedMap = buildingBlocks[1];
    var invalidatedAtoms = buildingBlocks[2];
    var changedAtoms = buildingBlocks[3];
    var storeHooks = buildingBlocks[6];
    var atomRead = buildingBlocks[7];
    var ensureAtomState = buildingBlocks[11];
    var flushCallbacks = buildingBlocks[12];
    var recomputeInvalidatedAtoms = buildingBlocks[13];
    var readAtomState = buildingBlocks[14];
    var writeAtomState = buildingBlocks[16];
    var mountDependencies = buildingBlocks[17];
    var setAtomStateValueOrPromise = buildingBlocks[20];
    var registerAbortHandler = buildingBlocks[26];
    var storeEpochHolder = buildingBlocks[28];
    var atomState = ensureAtomState(store, atom);
    var storeEpochNumber = storeEpochHolder[0];
    if (isAtomStateInitialized(atomState)) {
      if (mountedMap.has(atom) && invalidatedAtoms.get(atom) !== atomState.n || atomState.m === storeEpochNumber) {
        atomState.m = storeEpochNumber;
        return atomState;
      }
      var hasChangedDeps = false;
      for (var _iterator0 = _createForOfIteratorHelperLoose(atomState.d), _step0; !(_step0 = _iterator0()).done;) {
        var _step0$value = _step0.value,
          a = _step0$value[0],
          _n = _step0$value[1];
        if (readAtomState(store, a).n !== _n) {
          hasChangedDeps = true;
          break;
        }
      }
      if (!hasChangedDeps) {
        atomState.m = storeEpochNumber;
        return atomState;
      }
    }
    var isSync = true;
    var prevDeps = new Set(atomState.d.keys());
    var pruneDependencies = function pruneDependencies() {
      for (var _iterator1 = _createForOfIteratorHelperLoose(prevDeps), _step1; !(_step1 = _iterator1()).done;) {
        var _a2 = _step1.value;
        atomState.d.delete(_a2);
      }
    };
    var mountDependenciesIfAsync = function mountDependenciesIfAsync() {
      if (mountedMap.has(atom)) {
        var shouldRecompute = !changedAtoms.size;
        mountDependencies(store, atom);
        if (shouldRecompute) {
          recomputeInvalidatedAtoms(store);
          flushCallbacks(store);
        }
      }
    };
    var getter = function getter(a) {
      if (a === atom) {
        var _aState2 = ensureAtomState(store, a);
        if (!isAtomStateInitialized(_aState2)) {
          if (hasInitialValue(a)) {
            setAtomStateValueOrPromise(store, a, a.init);
          } else {
            throw new Error('no atom init');
          }
        }
        return returnAtomValue(_aState2);
      }
      var aState = readAtomState(store, a);
      try {
        return returnAtomValue(aState);
      } finally {
        prevDeps.delete(a);
        atomState.d.set(a, aState.n);
        if (isPromiseLike(atomState.v)) {
          addPendingPromiseToDependency(atom, atomState.v, aState);
        }
        if (mountedMap.has(atom)) {
          var _mountedMap$get2;
          (_mountedMap$get2 = mountedMap.get(a)) == null || _mountedMap$get2.t.add(atom);
        }
        if (!isSync) {
          mountDependenciesIfAsync();
        }
      }
    };
    var controller;
    var setSelf;
    var options = {
      get signal() {
        if (!controller) {
          controller = new AbortController();
        }
        return controller.signal;
      },
      get setSelf() {
        {
          console.warn('[DEPRECATED] setSelf is deprecated and will be removed in v3.');
        }
        if (!isActuallyWritableAtom(atom)) {
          console.warn('setSelf function cannot be used with read-only atom');
        }
        if (!setSelf && isActuallyWritableAtom(atom)) {
          setSelf = function setSelf() {
            if (isSync) {
              console.warn('setSelf function cannot be called in sync');
            }
            if (!isSync) {
              try {
                for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
                  args[_key3] = arguments[_key3];
                }
                return writeAtomState.apply(void 0, [store, atom].concat(args));
              } finally {
                recomputeInvalidatedAtoms(store);
                flushCallbacks(store);
              }
            }
          };
        }
        return setSelf;
      }
    };
    var prevEpochNumber = atomState.n;
    var prevInvalidated = invalidatedAtoms.get(atom) === prevEpochNumber;
    try {
      if ("development" !== 'production') {
        storeMutationSet.delete(store);
      }
      var _valueOrPromise = atomRead(store, atom, getter, options);
      if ("development" !== 'production' && storeMutationSet.has(store)) {
        console.warn('Detected store mutation during atom read. This is not supported.');
      }
      setAtomStateValueOrPromise(store, atom, _valueOrPromise);
      if (isPromiseLike(_valueOrPromise)) {
        registerAbortHandler(store, _valueOrPromise, function () {
          var _controller;
          return (_controller = controller) == null ? void 0 : _controller.abort();
        });
        var settle = function settle() {
          pruneDependencies();
          mountDependenciesIfAsync();
        };
        _valueOrPromise.then(settle, settle);
      } else {
        pruneDependencies();
      }
      storeHooks.r == null || storeHooks.r(atom);
      atomState.m = storeEpochNumber;
      return atomState;
    } catch (error) {
      delete atomState.v;
      atomState.e = error;
      ++atomState.n;
      atomState.m = storeEpochNumber;
      return atomState;
    } finally {
      isSync = false;
      if (atomState.n !== prevEpochNumber && prevInvalidated) {
        invalidatedAtoms.set(atom, atomState.n);
        changedAtoms.add(atom);
        storeHooks.c == null || storeHooks.c(atom);
      }
    }
  };
  var BUILDING_BLOCK_invalidateDependents = function BUILDING_BLOCK_invalidateDependents(store, atom) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var mountedMap = buildingBlocks[1];
    var invalidatedAtoms = buildingBlocks[2];
    var ensureAtomState = buildingBlocks[11];
    var stack = [atom];
    while (stack.length) {
      var a = stack.pop();
      var aState = ensureAtomState(store, a);
      for (var _iterator10 = _createForOfIteratorHelperLoose(getMountedOrPendingDependents(a, aState, mountedMap)), _step10; !(_step10 = _iterator10()).done;) {
        var d = _step10.value;
        var dState = ensureAtomState(store, d);
        if (invalidatedAtoms.get(d) !== dState.n) {
          invalidatedAtoms.set(d, dState.n);
          stack.push(d);
        }
      }
    }
  };
  var BUILDING_BLOCK_writeAtomState = function BUILDING_BLOCK_writeAtomState(store, atom) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var changedAtoms = buildingBlocks[3];
    var storeHooks = buildingBlocks[6];
    var atomWrite = buildingBlocks[8];
    var ensureAtomState = buildingBlocks[11];
    var flushCallbacks = buildingBlocks[12];
    var recomputeInvalidatedAtoms = buildingBlocks[13];
    var readAtomState = buildingBlocks[14];
    var invalidateDependents = buildingBlocks[15];
    var writeAtomState = buildingBlocks[16];
    var mountDependencies = buildingBlocks[17];
    var setAtomStateValueOrPromise = buildingBlocks[20];
    var storeEpochHolder = buildingBlocks[28];
    var isSync = true;
    var getter = function getter(a) {
      return returnAtomValue(readAtomState(store, a));
    };
    var setter = function setter(a) {
      var aState = ensureAtomState(store, a);
      try {
        for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
          args[_key5 - 1] = arguments[_key5];
        }
        if (a === atom) {
          if (!hasInitialValue(a)) {
            throw new Error('atom not writable');
          }
          if ("development" !== 'production') {
            storeMutationSet.add(store);
          }
          var prevEpochNumber = aState.n;
          var v = args[0];
          setAtomStateValueOrPromise(store, a, v);
          mountDependencies(store, a);
          if (prevEpochNumber !== aState.n) {
            ++storeEpochHolder[0];
            changedAtoms.add(a);
            invalidateDependents(store, a);
            storeHooks.c == null || storeHooks.c(a);
          }
          return undefined;
        } else {
          return writeAtomState.apply(void 0, [store, a].concat(args));
        }
      } finally {
        if (!isSync) {
          recomputeInvalidatedAtoms(store);
          flushCallbacks(store);
        }
      }
    };
    try {
      for (var _len4 = arguments.length, args = new Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
        args[_key4 - 2] = arguments[_key4];
      }
      return atomWrite.apply(void 0, [store, atom, getter, setter].concat(args));
    } finally {
      isSync = false;
    }
  };
  var BUILDING_BLOCK_mountDependencies = function BUILDING_BLOCK_mountDependencies(store, atom) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var mountedMap = buildingBlocks[1];
    var changedAtoms = buildingBlocks[3];
    var storeHooks = buildingBlocks[6];
    var ensureAtomState = buildingBlocks[11];
    var invalidateDependents = buildingBlocks[15];
    var mountAtom = buildingBlocks[18];
    var unmountAtom = buildingBlocks[19];
    var atomState = ensureAtomState(store, atom);
    var mounted = mountedMap.get(atom);
    if (mounted && atomState.d.size > 0) {
      for (var _iterator11 = _createForOfIteratorHelperLoose(atomState.d), _step11; !(_step11 = _iterator11()).done;) {
        var _step11$value = _step11.value,
          a = _step11$value[0],
          _n2 = _step11$value[1];
        if (!mounted.d.has(a)) {
          var aState = ensureAtomState(store, a);
          var aMounted = mountAtom(store, a);
          aMounted.t.add(atom);
          mounted.d.add(a);
          if (_n2 !== aState.n) {
            changedAtoms.add(a);
            invalidateDependents(store, a);
            storeHooks.c == null || storeHooks.c(a);
          }
        }
      }
      for (var _iterator12 = _createForOfIteratorHelperLoose(mounted.d), _step12; !(_step12 = _iterator12()).done;) {
        var _a3 = _step12.value;
        if (!atomState.d.has(_a3)) {
          mounted.d.delete(_a3);
          var _aMounted = unmountAtom(store, _a3);
          _aMounted == null || _aMounted.t.delete(atom);
        }
      }
    }
  };
  var BUILDING_BLOCK_mountAtom = function BUILDING_BLOCK_mountAtom(store, atom) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var mountedMap = buildingBlocks[1];
    var mountCallbacks = buildingBlocks[4];
    var storeHooks = buildingBlocks[6];
    var atomOnMount = buildingBlocks[10];
    var ensureAtomState = buildingBlocks[11];
    var flushCallbacks = buildingBlocks[12];
    var recomputeInvalidatedAtoms = buildingBlocks[13];
    var readAtomState = buildingBlocks[14];
    var writeAtomState = buildingBlocks[16];
    var mountAtom = buildingBlocks[18];
    var atomState = ensureAtomState(store, atom);
    var mounted = mountedMap.get(atom);
    if (!mounted) {
      readAtomState(store, atom);
      for (var _iterator13 = _createForOfIteratorHelperLoose(atomState.d.keys()), _step13; !(_step13 = _iterator13()).done;) {
        var a = _step13.value;
        var aMounted = mountAtom(store, a);
        aMounted.t.add(atom);
      }
      mounted = {
        l: new Set(),
        d: new Set(atomState.d.keys()),
        t: new Set()
      };
      mountedMap.set(atom, mounted);
      if (isActuallyWritableAtom(atom) && hasOnMount(atom)) {
        var processOnMount = function processOnMount() {
          var isSync = true;
          var setAtom = function setAtom() {
            try {
              for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
                args[_key6] = arguments[_key6];
              }
              return writeAtomState.apply(void 0, [store, atom].concat(args));
            } finally {
              if (!isSync) {
                recomputeInvalidatedAtoms(store);
                flushCallbacks(store);
              }
            }
          };
          try {
            var onUnmount = atomOnMount(store, atom, setAtom);
            if (onUnmount) {
              mounted.u = function () {
                isSync = true;
                try {
                  onUnmount();
                } finally {
                  isSync = false;
                }
              };
            }
          } finally {
            isSync = false;
          }
        };
        mountCallbacks.add(processOnMount);
      }
      storeHooks.m == null || storeHooks.m(atom);
    }
    return mounted;
  };
  var BUILDING_BLOCK_unmountAtom = function BUILDING_BLOCK_unmountAtom(store, atom) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var mountedMap = buildingBlocks[1];
    var unmountCallbacks = buildingBlocks[5];
    var storeHooks = buildingBlocks[6];
    var ensureAtomState = buildingBlocks[11];
    var unmountAtom = buildingBlocks[19];
    var atomState = ensureAtomState(store, atom);
    var mounted = mountedMap.get(atom);
    if (!mounted || mounted.l.size) {
      return mounted;
    }
    var isDependent = false;
    for (var _iterator14 = _createForOfIteratorHelperLoose(mounted.t), _step14; !(_step14 = _iterator14()).done;) {
      var _mountedMap$get3;
      var _a4 = _step14.value;
      if ((_mountedMap$get3 = mountedMap.get(_a4)) != null && _mountedMap$get3.d.has(atom)) {
        isDependent = true;
        break;
      }
    }
    if (!isDependent) {
      if (mounted.u) {
        unmountCallbacks.add(mounted.u);
      }
      mounted = undefined;
      mountedMap.delete(atom);
      for (var _iterator15 = _createForOfIteratorHelperLoose(atomState.d.keys()), _step15; !(_step15 = _iterator15()).done;) {
        var a = _step15.value;
        var aMounted = unmountAtom(store, a);
        aMounted == null || aMounted.t.delete(atom);
      }
      storeHooks.u == null || storeHooks.u(atom);
      return undefined;
    }
    return mounted;
  };
  var BUILDING_BLOCK_setAtomStateValueOrPromise = function BUILDING_BLOCK_setAtomStateValueOrPromise(store, atom, valueOrPromise) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var ensureAtomState = buildingBlocks[11];
    var abortPromise = buildingBlocks[27];
    var atomState = ensureAtomState(store, atom);
    var hasPrevValue = 'v' in atomState;
    var prevValue = atomState.v;
    if (isPromiseLike(valueOrPromise)) {
      for (var _iterator16 = _createForOfIteratorHelperLoose(atomState.d.keys()), _step16; !(_step16 = _iterator16()).done;) {
        var a = _step16.value;
        addPendingPromiseToDependency(atom, valueOrPromise, ensureAtomState(store, a));
      }
    }
    atomState.v = valueOrPromise;
    delete atomState.e;
    if (!hasPrevValue || !Object.is(prevValue, atomState.v)) {
      ++atomState.n;
      if (isPromiseLike(prevValue)) {
        abortPromise(store, prevValue);
      }
    }
  };
  var BUILDING_BLOCK_storeGet = function BUILDING_BLOCK_storeGet(store, atom) {
    var readAtomState = getInternalBuildingBlocks(store)[14];
    return returnAtomValue(readAtomState(store, atom));
  };
  var BUILDING_BLOCK_storeSet = function BUILDING_BLOCK_storeSet(store, atom) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var changedAtoms = buildingBlocks[3];
    var flushCallbacks = buildingBlocks[12];
    var recomputeInvalidatedAtoms = buildingBlocks[13];
    var writeAtomState = buildingBlocks[16];
    var prevChangedAtomsSize = changedAtoms.size;
    try {
      for (var _len7 = arguments.length, args = new Array(_len7 > 2 ? _len7 - 2 : 0), _key7 = 2; _key7 < _len7; _key7++) {
        args[_key7 - 2] = arguments[_key7];
      }
      return writeAtomState.apply(void 0, [store, atom].concat(args));
    } finally {
      if (changedAtoms.size !== prevChangedAtomsSize) {
        recomputeInvalidatedAtoms(store);
        flushCallbacks(store);
      }
    }
  };
  var BUILDING_BLOCK_storeSub = function BUILDING_BLOCK_storeSub(store, atom, listener) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var flushCallbacks = buildingBlocks[12];
    var mountAtom = buildingBlocks[18];
    var unmountAtom = buildingBlocks[19];
    var mounted = mountAtom(store, atom);
    var listeners = mounted.l;
    listeners.add(listener);
    flushCallbacks(store);
    return function () {
      listeners.delete(listener);
      unmountAtom(store, atom);
      flushCallbacks(store);
    };
  };
  var BUILDING_BLOCK_registerAbortHandler = function BUILDING_BLOCK_registerAbortHandler(store, promise, abortHandler) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var abortHandlersMap = buildingBlocks[25];
    var abortHandlers = abortHandlersMap.get(promise);
    if (!abortHandlers) {
      abortHandlers = new Set();
      abortHandlersMap.set(promise, abortHandlers);
      var cleanup = function cleanup() {
        return abortHandlersMap.delete(promise);
      };
      promise.then(cleanup, cleanup);
    }
    abortHandlers.add(abortHandler);
  };
  var BUILDING_BLOCK_abortPromise = function BUILDING_BLOCK_abortPromise(store, promise) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var abortHandlersMap = buildingBlocks[25];
    var abortHandlers = abortHandlersMap.get(promise);
    abortHandlers == null || abortHandlers.forEach(function (fn) {
      return fn();
    });
  };
  var buildingBlockMap = new WeakMap();
  var getInternalBuildingBlocks = function getInternalBuildingBlocks(store) {
    var buildingBlocks = buildingBlockMap.get(store);
    if (!buildingBlocks) {
      throw new Error('Store must be created by buildStore to read its building blocks');
    }
    return buildingBlocks;
  };
  function getBuildingBlocks(store) {
    var buildingBlocks = getInternalBuildingBlocks(store);
    var enhanceBuildingBlocks = buildingBlocks[24];
    if (enhanceBuildingBlocks) {
      return enhanceBuildingBlocks(buildingBlocks);
    }
    return buildingBlocks;
  }
  function buildStore() {
    for (var _len8 = arguments.length, buildArgs = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
      buildArgs[_key8] = arguments[_key8];
    }
    var store = {
      get: function get(atom) {
        var storeGet = getInternalBuildingBlocks(store)[21];
        return storeGet(store, atom);
      },
      set: function set(atom) {
        var storeSet = getInternalBuildingBlocks(store)[22];
        for (var _len9 = arguments.length, args = new Array(_len9 > 1 ? _len9 - 1 : 0), _key9 = 1; _key9 < _len9; _key9++) {
          args[_key9 - 1] = arguments[_key9];
        }
        return storeSet.apply(void 0, [store, atom].concat(args));
      },
      sub: function sub(atom, listener) {
        var storeSub = getInternalBuildingBlocks(store)[23];
        return storeSub(store, atom, listener);
      }
    };
    var buildingBlocks = [new WeakMap(), new WeakMap(), new WeakMap(), new Set(), new Set(), new Set(), {}, BUILDING_BLOCK_atomRead, BUILDING_BLOCK_atomWrite, BUILDING_BLOCK_atomOnInit, BUILDING_BLOCK_atomOnMount, BUILDING_BLOCK_ensureAtomState, BUILDING_BLOCK_flushCallbacks, BUILDING_BLOCK_recomputeInvalidatedAtoms, BUILDING_BLOCK_readAtomState, BUILDING_BLOCK_invalidateDependents, BUILDING_BLOCK_writeAtomState, BUILDING_BLOCK_mountDependencies, BUILDING_BLOCK_mountAtom, BUILDING_BLOCK_unmountAtom, BUILDING_BLOCK_setAtomStateValueOrPromise, BUILDING_BLOCK_storeGet, BUILDING_BLOCK_storeSet, BUILDING_BLOCK_storeSub, undefined, new WeakMap(), BUILDING_BLOCK_registerAbortHandler, BUILDING_BLOCK_abortPromise, [0]].map(function (fn, i) {
      return buildArgs[i] || fn;
    });
    buildingBlockMap.set(store, Object.freeze(buildingBlocks));
    return store;
  }

  exports.INTERNAL_addPendingPromiseToDependency = addPendingPromiseToDependency;
  exports.INTERNAL_buildStoreRev2 = buildStore;
  exports.INTERNAL_getBuildingBlocksRev2 = getBuildingBlocks;
  exports.INTERNAL_getMountedOrPendingDependents = getMountedOrPendingDependents;
  exports.INTERNAL_hasInitialValue = hasInitialValue;
  exports.INTERNAL_initializeStoreHooksRev2 = initializeStoreHooks;
  exports.INTERNAL_isActuallyWritableAtom = isActuallyWritableAtom;
  exports.INTERNAL_isAtomStateInitialized = isAtomStateInitialized;
  exports.INTERNAL_isPromiseLike = isPromiseLike;
  exports.INTERNAL_returnAtomValue = returnAtomValue;

}));
