atom.io 0.1.0 → 0.2.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.js CHANGED
@@ -63,7 +63,7 @@ __export(src_exports, {
63
63
  atomFamily: () => atomFamily,
64
64
  configure: () => configure,
65
65
  getState: () => getState,
66
- registerSelector: () => registerSelector,
66
+ isDefault: () => isDefault,
67
67
  selector: () => selector,
68
68
  selectorFamily: () => selectorFamily,
69
69
  setState: () => setState,
@@ -81,24 +81,34 @@ __export(internal_exports, {
81
81
  configure: () => configure,
82
82
  createStore: () => createStore,
83
83
  deposit: () => deposit,
84
+ evictDownStream: () => evictDownStream,
84
85
  finishAction: () => finishAction,
85
86
  finishTransaction: () => finishTransaction,
86
87
  getCachedState: () => getCachedState,
87
88
  getSelectorState: () => getSelectorState,
88
89
  getState__INTERNAL: () => getState__INTERNAL,
90
+ isAtomDefault: () => isAtomDefault,
89
91
  isDone: () => isDone,
92
+ isSelectorDefault: () => isSelectorDefault,
93
+ lookup: () => lookup,
94
+ lookupSelectorSources: () => lookupSelectorSources,
90
95
  markDone: () => markDone,
91
- propagateDown: () => propagateDown,
92
- recall: () => recall,
96
+ recallState: () => recallState,
97
+ registerSelector: () => registerSelector,
93
98
  setAtomState: () => setAtomState,
94
99
  setSelectorState: () => setSelectorState,
95
100
  setState__INTERNAL: () => setState__INTERNAL,
96
101
  startAction: () => startAction,
97
102
  startTransaction: () => startTransaction,
103
+ subscribeToRootAtoms: () => subscribeToRootAtoms,
104
+ traceAllSelectorAtoms: () => traceAllSelectorAtoms,
105
+ traceSelectorAtoms: () => traceSelectorAtoms,
106
+ updateSelectorAtoms: () => updateSelectorAtoms,
98
107
  withdraw: () => withdraw
99
108
  });
100
109
 
101
110
  // src/internal/get.ts
111
+ var import_function7 = require("fp-ts/function");
102
112
  var import_hamt_plus2 = __toESM(require("hamt_plus"));
103
113
 
104
114
  // src/internal/store.ts
@@ -494,7 +504,9 @@ var Join = class {
494
504
  var createStore = (name) => ({
495
505
  valueMap: import_hamt_plus.default.make(),
496
506
  selectorGraph: new Join({ relationType: `n:n` }),
507
+ selectorAtoms: new Join({ relationType: `n:n` }),
497
508
  atoms: import_hamt_plus.default.make(),
509
+ atomsAreDefault: import_hamt_plus.default.make(),
498
510
  selectors: import_hamt_plus.default.make(),
499
511
  readonlySelectors: import_hamt_plus.default.make(),
500
512
  operation: {
@@ -526,10 +538,25 @@ var clearStore = (store = IMPLICIT.STORE) => {
526
538
 
527
539
  // src/internal/get.ts
528
540
  var getCachedState = (state, store = IMPLICIT.STORE) => {
541
+ const path = [];
542
+ if (`default` in state) {
543
+ const atomKey = state.key;
544
+ store.selectorAtoms = (0, import_function7.pipe)(store.selectorAtoms, (oldValue) => {
545
+ let newValue = oldValue;
546
+ for (const selectorKey of path) {
547
+ newValue = newValue.set(selectorKey, atomKey);
548
+ }
549
+ return newValue;
550
+ });
551
+ }
529
552
  const value = import_hamt_plus2.default.get(state.key, store.valueMap);
530
553
  return value;
531
554
  };
532
555
  var getSelectorState = (selector2) => selector2.get();
556
+ function lookup(key, store) {
557
+ const type = import_hamt_plus2.default.has(key, store.atoms) ? `atom` : import_hamt_plus2.default.has(key, store.selectors) ? `selector` : `readonly_selector`;
558
+ return { key, type };
559
+ }
533
560
  function withdraw(token, store) {
534
561
  var _a, _b;
535
562
  return (_b = (_a = import_hamt_plus2.default.get(token.key, store.atoms)) != null ? _a : import_hamt_plus2.default.get(token.key, store.selectors)) != null ? _b : import_hamt_plus2.default.get(token.key, store.readonlySelectors);
@@ -544,14 +571,16 @@ function deposit(state) {
544
571
  return { key: state.key, type: `atom` };
545
572
  }
546
573
  var getState__INTERNAL = (state, store = IMPLICIT.STORE) => {
547
- var _a;
574
+ var _a, _b, _c;
548
575
  if (import_hamt_plus2.default.has(state.key, store.valueMap)) {
576
+ (_a = store.config.logger) == null ? void 0 : _a.info(`>> read "${state.key}"`);
549
577
  return getCachedState(state, store);
550
578
  }
551
579
  if (`get` in state) {
580
+ (_b = store.config.logger) == null ? void 0 : _b.info(`-> calc "${state.key}"`);
552
581
  return getSelectorState(state);
553
582
  }
554
- (_a = store.config.logger) == null ? void 0 : _a.error(
583
+ (_c = store.config.logger) == null ? void 0 : _c.error(
555
584
  `Attempted to get atom "${state.key}", which was never initialized in store "${store.config.name}".`
556
585
  );
557
586
  return state.default;
@@ -569,12 +598,12 @@ var startAction = (store) => {
569
598
  done: /* @__PURE__ */ new Set(),
570
599
  prev: store.valueMap
571
600
  };
572
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u2610`, `operation start`);
601
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u2B55`, `operation start`);
573
602
  };
574
603
  var finishAction = (store) => {
575
604
  var _a;
576
605
  store.operation = { open: false };
577
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u2611\uFE0F`, `operation done`);
606
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F534}`, `operation done`);
578
607
  };
579
608
  var isDone = (key, store = IMPLICIT.STORE) => {
580
609
  var _a;
@@ -596,7 +625,7 @@ var markDone = (key, store = IMPLICIT.STORE) => {
596
625
  }
597
626
  store.operation.done.add(key);
598
627
  };
599
- var recall = (state, store = IMPLICIT.STORE) => {
628
+ var recallState = (state, store = IMPLICIT.STORE) => {
600
629
  var _a;
601
630
  if (!store.operation.open) {
602
631
  (_a = store.config.logger) == null ? void 0 : _a.warn(
@@ -608,87 +637,60 @@ var recall = (state, store = IMPLICIT.STORE) => {
608
637
  };
609
638
 
610
639
  // src/internal/set.ts
611
- var propagateDown = (state, store = IMPLICIT.STORE) => {
640
+ var evictDownStream = (state, store = IMPLICIT.STORE) => {
612
641
  var _a, _b;
613
- const relatedStateKeys = store.selectorGraph.getRelations(state.key);
642
+ const downstream = store.selectorAtoms.getRelations(state.key);
643
+ const downstreamKeys = downstream.map(({ id }) => id);
614
644
  (_a = store.config.logger) == null ? void 0 : _a.info(
615
- ` ||`,
616
- `bumping`,
617
- relatedStateKeys.length,
618
- `states:`,
619
- relatedStateKeys.map(({ id }) => id)
645
+ ` || ${downstreamKeys.length} downstream:`,
646
+ downstreamKeys
620
647
  );
621
648
  if (store.operation.open) {
622
- (_b = store.config.logger) == null ? void 0 : _b.info(` ||`, `done:`, store.operation.done);
649
+ (_b = store.config.logger) == null ? void 0 : _b.info(` ||`, [...store.operation.done], `already done`);
623
650
  }
624
- relatedStateKeys.forEach(({ id: stateKey }) => {
625
- var _a2, _b2, _c, _d, _e;
651
+ downstream.forEach(({ id: stateKey }) => {
652
+ var _a2, _b2, _c, _d;
626
653
  if (isDone(stateKey, store)) {
627
- (_a2 = store.config.logger) == null ? void 0 : _a2.info(` ||`, stateKey, `already done`);
654
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(` || ${stateKey} already done`);
628
655
  return;
629
656
  }
630
- (_b2 = store.config.logger) == null ? void 0 : _b2.info(`->`, `bumping`, stateKey);
631
- const state2 = (_c = import_hamt_plus4.default.get(stateKey, store.selectors)) != null ? _c : import_hamt_plus4.default.get(stateKey, store.readonlySelectors);
657
+ const state2 = (_b2 = import_hamt_plus4.default.get(stateKey, store.selectors)) != null ? _b2 : import_hamt_plus4.default.get(stateKey, store.readonlySelectors);
632
658
  if (!state2) {
633
- (_d = store.config.logger) == null ? void 0 : _d.info(
634
- ` ||`,
635
- stateKey,
636
- `is an atom - no need to propagate down`
659
+ (_c = store.config.logger) == null ? void 0 : _c.info(
660
+ ` || ${stateKey} is an atom, and can't be downstream`
637
661
  );
638
662
  return;
639
663
  }
640
664
  store.valueMap = import_hamt_plus4.default.remove(stateKey, store.valueMap);
641
- const newValue = getState__INTERNAL(state2, store);
642
- (_e = store.config.logger) == null ? void 0 : _e.info(` <-`, stateKey, `became`, newValue);
643
- const oldValue = recall(state2, store);
644
- state2.subject.next({ newValue, oldValue });
665
+ (_d = store.config.logger) == null ? void 0 : _d.info(` xx evicted "${stateKey}"`);
645
666
  markDone(stateKey, store);
646
- if (`set` in state2)
647
- propagateDown(state2, store);
648
667
  });
649
668
  };
650
669
  var setAtomState = (atom2, next, store = IMPLICIT.STORE) => {
651
670
  var _a, _b;
652
671
  const oldValue = getState__INTERNAL(atom2, store);
653
672
  const newValue = become(next)(oldValue);
654
- (_a = store.config.logger) == null ? void 0 : _a.info(
655
- `->`,
656
- `setting atom`,
657
- `"${atom2.key}"`,
658
- `to`,
659
- newValue
660
- );
673
+ (_a = store.config.logger) == null ? void 0 : _a.info(`-> setting atom "${atom2.key}" to`, newValue);
661
674
  store.valueMap = import_hamt_plus4.default.set(atom2.key, newValue, store.valueMap);
675
+ if (isAtomDefault(atom2.key)) {
676
+ store.atomsAreDefault = import_hamt_plus4.default.set(atom2.key, false, store.atomsAreDefault);
677
+ }
662
678
  markDone(atom2.key, store);
663
- atom2.subject.next({ newValue, oldValue });
664
679
  (_b = store.config.logger) == null ? void 0 : _b.info(
665
- ` ||`,
666
- `propagating change made to`,
667
- `"${atom2.key}"`
680
+ ` || evicting caches downstream from "${atom2.key}"`
668
681
  );
669
- propagateDown(atom2, store);
682
+ evictDownStream(atom2, store);
683
+ atom2.subject.next({ newValue, oldValue });
670
684
  };
671
685
  var setSelectorState = (selector2, next, store = IMPLICIT.STORE) => {
672
686
  var _a, _b;
673
687
  const oldValue = getState__INTERNAL(selector2, store);
674
688
  const newValue = become(next)(oldValue);
675
- (_a = store.config.logger) == null ? void 0 : _a.info(
676
- `->`,
677
- `setting selector`,
678
- `"${selector2.key}"`,
679
- `to`,
680
- newValue
681
- );
682
- (_b = store.config.logger) == null ? void 0 : _b.info(
683
- ` ||`,
684
- `propagating change made to`,
685
- `"${selector2.key}"`
686
- );
689
+ (_a = store.config.logger) == null ? void 0 : _a.info(`-> setting selector "${selector2.key}" to`, newValue);
690
+ (_b = store.config.logger) == null ? void 0 : _b.info(` || propagating change made to "${selector2.key}"`);
687
691
  selector2.set(newValue);
688
- propagateDown(selector2, store);
689
692
  };
690
- var setState__INTERNAL = (token, value, store = IMPLICIT.STORE) => {
691
- const state = withdraw(token, store);
693
+ var setState__INTERNAL = (state, value, store = IMPLICIT.STORE) => {
692
694
  if (`set` in state) {
693
695
  setSelectorState(state, value, store);
694
696
  } else {
@@ -696,6 +698,114 @@ var setState__INTERNAL = (token, value, store = IMPLICIT.STORE) => {
696
698
  }
697
699
  };
698
700
 
701
+ // src/internal/is-default.ts
702
+ var import_hamt_plus5 = __toESM(require("hamt_plus"));
703
+ var isAtomDefault = (key, store = IMPLICIT.STORE) => {
704
+ return import_hamt_plus5.default.get(key, store.atomsAreDefault);
705
+ };
706
+ var isSelectorDefault = (key, store = IMPLICIT.STORE) => {
707
+ const roots = traceAllSelectorAtoms(key, store);
708
+ return roots.every((root) => isAtomDefault(root.key, store));
709
+ };
710
+
711
+ // src/internal/selector-internal.ts
712
+ var lookupSelectorSources = (key, store) => store.selectorGraph.getRelations(key).filter(({ source }) => source !== key).map(({ source }) => lookup(source, store));
713
+ var traceSelectorAtoms = (selectorKey, dependency, store) => {
714
+ const roots = [];
715
+ const sources = lookupSelectorSources(dependency.key, store);
716
+ let depth = 0;
717
+ while (sources.length > 0) {
718
+ const source = sources.shift();
719
+ ++depth;
720
+ if (depth > 999) {
721
+ throw new Error(
722
+ `Maximum selector dependency depth exceeded in selector "${selectorKey}".`
723
+ );
724
+ }
725
+ if (source.type !== `atom`) {
726
+ sources.push(...lookupSelectorSources(source.key, store));
727
+ } else {
728
+ roots.push(source);
729
+ }
730
+ }
731
+ return roots;
732
+ };
733
+ var traceAllSelectorAtoms = (selectorKey, store) => {
734
+ const sources = lookupSelectorSources(selectorKey, store);
735
+ return sources.flatMap(
736
+ (source) => source.type === `atom` ? source : traceSelectorAtoms(selectorKey, source, store)
737
+ );
738
+ };
739
+ var updateSelectorAtoms = (selectorKey, dependency, store) => {
740
+ var _a, _b;
741
+ if (dependency.type === `atom`) {
742
+ store.selectorAtoms = store.selectorAtoms.set(selectorKey, dependency.key);
743
+ (_a = store.config.logger) == null ? void 0 : _a.info(
744
+ ` || adding root for "${selectorKey}": ${dependency.key}`
745
+ );
746
+ return;
747
+ }
748
+ const roots = traceSelectorAtoms(selectorKey, dependency, store);
749
+ (_b = store.config.logger) == null ? void 0 : _b.info(` || adding roots for "${selectorKey}":`, roots);
750
+ for (const root of roots) {
751
+ store.selectorAtoms = store.selectorAtoms.set(selectorKey, root.key);
752
+ }
753
+ };
754
+ var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
755
+ get: (dependency) => {
756
+ var _a, _b;
757
+ const alreadyRegistered = store.selectorGraph.getRelations(selectorKey).some(({ source }) => source === dependency.key);
758
+ const dependencyState = withdraw(dependency, store);
759
+ const dependencyValue = getState__INTERNAL(dependencyState, store);
760
+ if (alreadyRegistered) {
761
+ (_a = store.config.logger) == null ? void 0 : _a.info(
762
+ ` || ${selectorKey} <- ${dependency.key} =`,
763
+ dependencyValue
764
+ );
765
+ } else {
766
+ (_b = store.config.logger) == null ? void 0 : _b.info(
767
+ `\u{1F50C} registerSelector "${selectorKey}" <- "${dependency.key}" =`,
768
+ dependencyValue
769
+ );
770
+ store.selectorGraph = store.selectorGraph.set(
771
+ selectorKey,
772
+ dependency.key,
773
+ {
774
+ source: dependency.key
775
+ }
776
+ );
777
+ }
778
+ updateSelectorAtoms(selectorKey, dependency, store);
779
+ return dependencyValue;
780
+ },
781
+ set: (stateToken, newValue) => {
782
+ const state = withdraw(stateToken, store);
783
+ setState__INTERNAL(state, newValue, store);
784
+ }
785
+ });
786
+
787
+ // src/internal/subscribe-internal.ts
788
+ var subscribeToRootAtoms = (state, store = IMPLICIT.STORE) => {
789
+ const dependencySubscriptions = `default` in state ? null : traceAllSelectorAtoms(state.key, store).map((atomToken) => {
790
+ const atom2 = withdraw(atomToken, store);
791
+ return atom2.subject.subscribe((atomChange) => {
792
+ var _a, _b;
793
+ (_a = store.config.logger) == null ? void 0 : _a.info(
794
+ `\u{1F4E2} atom changed: "${atomToken.key}" (`,
795
+ atomChange.oldValue,
796
+ `->`,
797
+ atomChange.newValue,
798
+ `) re-evaluating "${state.key}"`
799
+ );
800
+ const oldValue = recallState(state, store);
801
+ const newValue = getState__INTERNAL(state, store);
802
+ (_b = store.config.logger) == null ? void 0 : _b.info(` <- ${state.key} became`, newValue);
803
+ state.subject.next({ newValue, oldValue });
804
+ });
805
+ });
806
+ return dependencySubscriptions;
807
+ };
808
+
699
809
  // src/internal/transaction-internal.ts
700
810
  var finishTransaction = (store) => {
701
811
  var _a;
@@ -734,17 +844,17 @@ var abortTransaction = (store) => {
734
844
  };
735
845
 
736
846
  // src/atom.ts
737
- var import_hamt_plus5 = __toESM(require("hamt_plus"));
847
+ var import_hamt_plus6 = __toESM(require("hamt_plus"));
738
848
  var Rx = __toESM(require("rxjs"));
739
849
 
740
850
  // ../anvl/src/json/index.ts
741
- var import_function8 = require("fp-ts/function");
851
+ var import_function9 = require("fp-ts/function");
742
852
  var stringifyJson = (json) => JSON.stringify(json);
743
853
 
744
854
  // src/atom.ts
745
855
  var atom = (options, store = IMPLICIT.STORE) => {
746
856
  var _a, _b, _c;
747
- if (import_hamt_plus5.default.has(options.key, store.atoms)) {
857
+ if (import_hamt_plus6.default.has(options.key, store.atoms)) {
748
858
  (_b = (_a = store.config.logger) == null ? void 0 : _a.error) == null ? void 0 : _b.call(
749
859
  _a,
750
860
  `Key "${options.key}" already exists in the store.`
@@ -753,12 +863,13 @@ var atom = (options, store = IMPLICIT.STORE) => {
753
863
  }
754
864
  const subject = new Rx.Subject();
755
865
  const newAtom = __spreadProps(__spreadValues({}, options), { subject });
756
- store.atoms = import_hamt_plus5.default.set(options.key, newAtom, store.atoms);
757
- store.valueMap = import_hamt_plus5.default.set(options.key, options.default, store.valueMap);
866
+ const initialValue = options.default instanceof Function ? options.default() : options.default;
867
+ store.atoms = import_hamt_plus6.default.set(options.key, newAtom, store.atoms);
868
+ store.atomsAreDefault = import_hamt_plus6.default.set(options.key, true, store.atomsAreDefault);
869
+ store.valueMap = import_hamt_plus6.default.set(options.key, initialValue, store.valueMap);
758
870
  const token = deposit(newAtom);
759
871
  const setSelf = (next) => setState(token, next, store);
760
872
  const onSet = (observe) => subscribe(token, observe, store);
761
- setSelf(options.default);
762
873
  (_c = options.effects) == null ? void 0 : _c.forEach((effect) => effect({ setSelf, onSet }));
763
874
  return token;
764
875
  };
@@ -780,18 +891,18 @@ var atomFamily = (options, store = IMPLICIT.STORE) => (key) => {
780
891
  };
781
892
 
782
893
  // src/selector.ts
783
- var import_hamt_plus6 = __toESM(require("hamt_plus"));
894
+ var import_hamt_plus7 = __toESM(require("hamt_plus"));
784
895
  var Rx2 = __toESM(require("rxjs"));
785
896
  function selector(options, store = IMPLICIT.STORE) {
786
897
  var _a, _b;
787
- if (import_hamt_plus6.default.has(options.key, store.selectors)) {
898
+ if (import_hamt_plus7.default.has(options.key, store.selectors)) {
788
899
  throw new Error(`Key "${options.key}" already exists in the store.`);
789
900
  }
790
901
  const subject = new Rx2.Subject();
791
902
  const { get, set } = registerSelector(options.key, store);
792
903
  const getSelf = () => {
793
904
  const value = options.get({ get });
794
- store.valueMap = import_hamt_plus6.default.set(options.key, value, store.valueMap);
905
+ store.valueMap = import_hamt_plus7.default.set(options.key, value, store.valueMap);
795
906
  return value;
796
907
  };
797
908
  if (!(`set` in options)) {
@@ -799,21 +910,21 @@ function selector(options, store = IMPLICIT.STORE) {
799
910
  subject,
800
911
  get: getSelf
801
912
  });
802
- store.readonlySelectors = import_hamt_plus6.default.set(
913
+ store.readonlySelectors = import_hamt_plus7.default.set(
803
914
  options.key,
804
915
  readonlySelector,
805
916
  store.readonlySelectors
806
917
  );
807
918
  const initialValue2 = getSelf();
808
- (_a = store.config.logger) == null ? void 0 : _a.info(` \u2728`, options.key, `=`, initialValue2);
919
+ (_a = store.config.logger) == null ? void 0 : _a.info(` \u2728 "${options.key}" =`, initialValue2);
809
920
  return __spreadProps(__spreadValues({}, readonlySelector), { type: `readonly_selector` });
810
921
  }
811
922
  const setSelf = (next) => {
812
923
  var _a2;
813
- (_a2 = store.config.logger) == null ? void 0 : _a2.info(`${options.key}.set`, next);
924
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(` <- "${options.key}" became`, next);
814
925
  const oldValue = getSelf();
815
926
  const newValue = become(next)(oldValue);
816
- store.valueMap = import_hamt_plus6.default.set(options.key, newValue, store.valueMap);
927
+ store.valueMap = import_hamt_plus7.default.set(options.key, newValue, store.valueMap);
817
928
  markDone(options.key, store);
818
929
  subject.next({ newValue, oldValue });
819
930
  options.set({ get, set }, newValue);
@@ -823,9 +934,9 @@ function selector(options, store = IMPLICIT.STORE) {
823
934
  get: getSelf,
824
935
  set: setSelf
825
936
  });
826
- store.selectors = import_hamt_plus6.default.set(options.key, mySelector, store.selectors);
937
+ store.selectors = import_hamt_plus7.default.set(options.key, mySelector, store.selectors);
827
938
  const initialValue = getSelf();
828
- (_b = store.config.logger) == null ? void 0 : _b.info(` \u2728`, options.key, `=`, initialValue);
939
+ (_b = store.config.logger) == null ? void 0 : _b.info(` \u2728 "${options.key}" =`, initialValue);
829
940
  return __spreadProps(__spreadValues({}, mySelector), { type: `selector` });
830
941
  }
831
942
  function selectorFamily(options, store = IMPLICIT.STORE) {
@@ -854,30 +965,6 @@ function selectorFamily(options, store = IMPLICIT.STORE) {
854
965
  );
855
966
  };
856
967
  }
857
- var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
858
- get: (state) => {
859
- var _a, _b, _c;
860
- const isRegistered = store.selectorGraph.getRelatedIds(selectorKey).includes(state.key);
861
- if (isRegistered) {
862
- (_a = store.config.logger) == null ? void 0 : _a.info(` ||`, selectorKey, `<-`, state.key);
863
- } else {
864
- (_b = store.config.logger) == null ? void 0 : _b.info(
865
- `\u{1F50C} registerSelector`,
866
- selectorKey,
867
- `<-`,
868
- state.key
869
- );
870
- store.selectorGraph = store.selectorGraph.set(selectorKey, state.key);
871
- }
872
- const currentValue = getState(state, store);
873
- (_c = store.config.logger) == null ? void 0 : _c.info(` ||`, state.key, `=`, currentValue);
874
- return currentValue;
875
- },
876
- set: (token, newValue) => {
877
- store.selectorGraph.set(token.key, selectorKey);
878
- setState__INTERNAL(token, newValue, store);
879
- }
880
- });
881
968
 
882
969
  // src/transaction.ts
883
970
  var transaction = (options, store = IMPLICIT.STORE) => Object.assign(
@@ -908,15 +995,34 @@ var getState = (token, store = IMPLICIT.STORE) => {
908
995
  const state = withdraw(token, store);
909
996
  return getState__INTERNAL(state, store);
910
997
  };
911
- var setState = (state, value, store = IMPLICIT.STORE) => {
998
+ var setState = (token, value, store = IMPLICIT.STORE) => {
912
999
  startAction(store);
1000
+ const state = withdraw(token, store);
913
1001
  setState__INTERNAL(state, value, store);
914
1002
  finishAction(store);
915
1003
  };
1004
+ var isDefault = (token, store = IMPLICIT.STORE) => token.type === `atom` ? isAtomDefault(token.key, store) : isSelectorDefault(token.key, store);
916
1005
  var subscribe = (token, observe, store = IMPLICIT.STORE) => {
1006
+ var _a;
917
1007
  const state = withdraw(token, store);
918
1008
  const subscription = state.subject.subscribe(observe);
919
- return () => subscription.unsubscribe();
1009
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F440} subscribe to "${state.key}"`);
1010
+ const dependencySubscriptions = subscribeToRootAtoms(state, store);
1011
+ const unsubscribe = dependencySubscriptions === null ? () => {
1012
+ var _a2;
1013
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(`\u{1F648} unsubscribe from "${state.key}"`);
1014
+ subscription.unsubscribe();
1015
+ } : () => {
1016
+ var _a2;
1017
+ (_a2 = store.config.logger) == null ? void 0 : _a2.info(
1018
+ `\u{1F648} unsubscribe from "${state.key}" and its dependencies`
1019
+ );
1020
+ subscription.unsubscribe();
1021
+ for (const dependencySubscription of dependencySubscriptions) {
1022
+ dependencySubscription.unsubscribe();
1023
+ }
1024
+ };
1025
+ return unsubscribe;
920
1026
  };
921
1027
  // Annotate the CommonJS export names for ESM import in node:
922
1028
  0 && (module.exports = {
@@ -925,7 +1031,7 @@ var subscribe = (token, observe, store = IMPLICIT.STORE) => {
925
1031
  atomFamily,
926
1032
  configure,
927
1033
  getState,
928
- registerSelector,
1034
+ isDefault,
929
1035
  selector,
930
1036
  selectorFamily,
931
1037
  setState,