valdres 1.0.0-beta.3 → 1.0.0-beta.5

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
@@ -123,17 +123,18 @@ var isPromiseLike = (object) => {
123
123
  };
124
124
 
125
125
  // src/utils/deepFreeze.ts
126
- var deepFreeze = (obj, seen = new WeakSet) => {
126
+ var deepFreeze = (obj, seen) => {
127
127
  if (obj === null || obj === undefined)
128
128
  return obj;
129
129
  if (typeof obj !== "object" && typeof obj !== "function")
130
130
  return obj;
131
- if (seen.has(obj) || Object.isFrozen(obj))
131
+ if (Object.isFrozen(obj) || seen?.has(obj))
132
132
  return obj;
133
- seen.add(obj);
134
133
  if (Array.isArray(obj)) {
135
134
  for (const item of obj) {
136
135
  if (item && typeof item === "object") {
136
+ seen ??= new WeakSet;
137
+ seen.add(obj);
137
138
  deepFreeze(item, seen);
138
139
  }
139
140
  }
@@ -142,6 +143,8 @@ var deepFreeze = (obj, seen = new WeakSet) => {
142
143
  for (const name of propNames) {
143
144
  const value = obj[name];
144
145
  if (value && typeof value === "object") {
146
+ seen ??= new WeakSet;
147
+ seen.add(obj);
145
148
  deepFreeze(value, seen);
146
149
  }
147
150
  }
@@ -149,26 +152,28 @@ var deepFreeze = (obj, seen = new WeakSet) => {
149
152
  return Object.freeze(obj);
150
153
  };
151
154
 
152
- // src/lib/isProd.ts
153
- var isProd = () => {
154
- return false;
155
- };
155
+ // src/lib/IS_PROD.ts
156
+ var IS_PROD = typeof process !== "undefined" && process.env != null && process.env.NODE_ENV === "production";
156
157
 
157
158
  // src/lib/setValueInData.ts
158
159
  var trackScopeValue = (key, data) => {
159
160
  const parent = data.parent;
161
+ const indexKeys = data.scopeIndexKeys;
162
+ if (!parent || !indexKeys) {
163
+ throw new Error("trackScopeValue called on a root store");
164
+ }
160
165
  let set = parent.scopeValueIndex.get(key);
161
166
  if (!set) {
162
167
  set = new Set;
163
168
  parent.scopeValueIndex.set(key, set);
164
169
  }
165
170
  set.add(data);
166
- data.scopeIndexKeys.add(key);
171
+ indexKeys.add(key);
167
172
  };
168
173
  var setValueInData = (atom, value, data) => {
169
- const isNewAtomInScope = "parent" in data && Object.hasOwn(atom, "defaultValue") && !data.values.has(atom);
174
+ const isNewAtomInScope = data.parent && Object.hasOwn(atom, "defaultValue") && !data.values.has(atom);
170
175
  let written;
171
- if (atom.mutable || isProd()) {
176
+ if (atom.mutable || IS_PROD) {
172
177
  data.values.set(atom, value);
173
178
  written = value;
174
179
  } else {
@@ -176,8 +181,14 @@ var setValueInData = (atom, value, data) => {
176
181
  data.values.set(atom, frozenValue);
177
182
  written = frozenValue;
178
183
  }
179
- if (isNewAtomInScope)
184
+ if (isNewAtomInScope) {
180
185
  trackScopeValue(atom, data);
186
+ const subs = data.subscriptions.get(atom);
187
+ if (subs) {
188
+ for (const sub of subs)
189
+ sub.reRoot?.();
190
+ }
191
+ }
181
192
  if (atom.maxAge !== undefined) {
182
193
  data.lastValueWriteAt.set(atom, Date.now());
183
194
  }
@@ -245,14 +256,14 @@ var initFamilyIndex = (family, data) => {
245
256
  if (data.values.has(family))
246
257
  return data.values.get(family).__index;
247
258
  let parentIndex;
248
- if ("parent" in data) {
259
+ if (data.parent) {
249
260
  parentIndex = initFamilyIndex(family, data.parent);
250
261
  if (!parentIndex)
251
262
  throw new Error("Parent index is missing");
252
263
  }
253
264
  const index = createAtomFamilyIndex(parentIndex);
254
265
  data.values.set(family, renderAtomFamilyIndex(index));
255
- if ("parent" in data) {
266
+ if (data.parent) {
256
267
  trackScopeValue(family, data);
257
268
  }
258
269
  return index;
@@ -271,8 +282,10 @@ var recursivelyUpdateIndexes = (data, family) => {
271
282
  const childScopesWithFamily = data.scopeValueIndex.get(family);
272
283
  if (!childScopesWithFamily || childScopesWithFamily.size === 0)
273
284
  return;
285
+ const parentIndex = data.values.get(family).__index;
274
286
  for (const scopedData of childScopesWithFamily) {
275
287
  const index = scopedData.values.get(family).__index;
288
+ index.parentIndex = parentIndex;
276
289
  index.rendered = null;
277
290
  index.renderedArray = null;
278
291
  scopedData.values.set(family, renderAtomFamilyIndex(index));
@@ -343,7 +356,6 @@ ${generateSelectorTrace(this.selectors)}`;
343
356
 
344
357
  // src/lib/asyncDependencyTracking.ts
345
358
  var pendingAsyncDeps = new WeakMap;
346
- var latestEvalContext = new WeakMap;
347
359
 
348
360
  class SuspendAndWaitForResolveError extends Error {
349
361
  promise;
@@ -379,7 +391,8 @@ var lateGet = (state, selector, data) => {
379
391
  try {
380
392
  return getState(state, data, lateInitSet);
381
393
  } finally {
382
- if (isNewDep && isTransitivelySubscribed(selector, data)) {
394
+ if (isNewDep && isLive(selector, data)) {
395
+ onLiveDependencyAdded(state, data);
383
396
  mountTransitiveDeps(state, data);
384
397
  }
385
398
  }
@@ -391,23 +404,22 @@ var cleanUpRejectedPromise = (selector, data, promise) => {
391
404
  };
392
405
 
393
406
  // src/lib/initSelector.ts
394
- class NeedsInitError {
395
- selector;
396
- constructor(selector) {
397
- this.selector = selector;
398
- }
399
- }
400
- var _evalDepth = 0;
401
- var _inTrampoline = false;
402
- var MAX_EVAL_DEPTH = 100;
403
- var sharedCircularDepSet = new WeakSet;
404
407
  var neverAbortedSignal = new AbortController().signal;
405
408
  var syncOptionsCache = new WeakMap;
406
- var evaluateSelector = (selector, data, initializedAtomsSet, circularDependencySet = sharedCircularDepSet, addedDepsOut, removedDepsOut) => {
409
+ var getSyncOptions = (data) => {
410
+ let cached = syncOptionsCache.get(data);
411
+ if (!cached) {
412
+ cached = { signal: neverAbortedSignal, storeId: data.id };
413
+ syncOptionsCache.set(data, cached);
414
+ }
415
+ return cached;
416
+ };
417
+ var evaluateSelector = (selector, data, initializedAtomsSet, circularDependencySet = data.circularDepSet, depsChangeOut) => {
407
418
  const currentDependencies = data.stateDependencies.get(selector);
408
419
  const updatedDepsArray = [];
409
420
  let depsChanged = false;
410
421
  let evaluationComplete = false;
422
+ const latestEvalContext = data.latestEvalContext;
411
423
  const prevCtx = latestEvalContext.get(selector);
412
424
  if (prevCtx)
413
425
  prevCtx.revoked = true;
@@ -418,34 +430,33 @@ var evaluateSelector = (selector, data, initializedAtomsSet, circularDependencyS
418
430
  }
419
431
  circularDependencySet.add(selector);
420
432
  try {
421
- const prev = data.abortControllers.get(selector);
422
433
  let options;
423
- if (prev === false) {
424
- let cached = syncOptionsCache.get(data);
425
- if (!cached) {
426
- cached = { signal: neverAbortedSignal, storeId: data.id };
427
- syncOptionsCache.set(data, cached);
428
- }
429
- options = cached;
434
+ if (selector.get.length < 2) {
435
+ options = getSyncOptions(data);
430
436
  } else {
431
- if (prev)
432
- prev.abort();
433
- let controller;
434
- const myEvalCtx = evalCtx;
435
- options = {
436
- storeId: data.id,
437
- get signal() {
438
- if (!controller) {
439
- controller = new AbortController;
440
- if (myEvalCtx.revoked) {
441
- controller.abort();
442
- } else {
443
- data.abortControllers.set(selector, controller);
437
+ const prev = data.abortControllers.get(selector);
438
+ if (prev === false) {
439
+ options = getSyncOptions(data);
440
+ } else {
441
+ if (prev)
442
+ prev.abort();
443
+ let controller;
444
+ const myEvalCtx = evalCtx;
445
+ options = {
446
+ storeId: data.id,
447
+ get signal() {
448
+ if (!controller) {
449
+ controller = new AbortController;
450
+ if (myEvalCtx.revoked) {
451
+ controller.abort();
452
+ } else {
453
+ data.abortControllers.set(selector, controller);
454
+ }
444
455
  }
456
+ return controller.signal;
445
457
  }
446
- return controller.signal;
447
- }
448
- };
458
+ };
459
+ }
449
460
  }
450
461
  let allDepsThisEval;
451
462
  let result;
@@ -470,8 +481,6 @@ var evaluateSelector = (selector, data, initializedAtomsSet, circularDependencyS
470
481
  return value;
471
482
  }, options);
472
483
  } catch (error) {
473
- if (error instanceof NeedsInitError)
474
- throw error;
475
484
  if (error instanceof SuspendAndWaitForResolveError) {
476
485
  result = error;
477
486
  } else if (error instanceof SelectorEvaluationError) {
@@ -492,22 +501,28 @@ var evaluateSelector = (selector, data, initializedAtomsSet, circularDependencyS
492
501
  updatedDependencies.add(dep);
493
502
  }
494
503
  }
495
- const prev2 = currentDependencies ?? new Set;
504
+ const prev = currentDependencies ?? new Set;
496
505
  for (const state of updatedDependencies) {
497
- if (!prev2.has(state)) {
506
+ if (!prev.has(state)) {
498
507
  const set = getOrInitDependentsSet(state, data);
499
508
  set.add(selector);
500
- if (addedDepsOut)
501
- addedDepsOut.add(state);
509
+ if (depsChangeOut) {
510
+ if (!depsChangeOut.added)
511
+ depsChangeOut.added = new Set;
512
+ depsChangeOut.added.add(state);
513
+ }
502
514
  }
503
515
  }
504
516
  if (!isAsyncResult) {
505
- for (const state of prev2) {
517
+ for (const state of prev) {
506
518
  if (!updatedDependencies.has(state)) {
507
519
  const set = getOrInitDependentsSet(state, data);
508
520
  set.delete(selector);
509
- if (removedDepsOut)
510
- removedDepsOut.add(state);
521
+ if (depsChangeOut) {
522
+ if (!depsChangeOut.removed)
523
+ depsChangeOut.removed = new Set;
524
+ depsChangeOut.removed.add(state);
525
+ }
511
526
  }
512
527
  }
513
528
  }
@@ -534,7 +549,7 @@ var handleSelectorResult = (value, selector, data) => {
534
549
  const initializedAtomsSet = new Set;
535
550
  const res = initSelector(selector, data, initializedAtomsSet);
536
551
  if (initializedAtomsSet.size > 0) {
537
- propagateUpdatedAtoms([...initializedAtomsSet], data);
552
+ propagateAtomUpdate([...initializedAtomsSet], data);
538
553
  }
539
554
  return res;
540
555
  }).catch(() => {
@@ -556,12 +571,16 @@ var handleSelectorResult = (value, selector, data) => {
556
571
  pendingAsyncDeps.delete(value);
557
572
  const currentDeps = data.stateDependencies.get(selector);
558
573
  if (currentDeps) {
574
+ const selectorIsLive = isLive(selector, data);
559
575
  for (const dep of currentDeps) {
560
576
  if (!evalDeps.has(dep)) {
561
577
  currentDeps.delete(dep);
562
578
  const dependents2 = data.stateDependents.get(dep);
563
579
  if (dependents2)
564
580
  dependents2.delete(selector);
581
+ if (selectorIsLive) {
582
+ onLiveDependencyRemoved(dep, data);
583
+ }
565
584
  unmountOrphanedDeps(dep, data);
566
585
  }
567
586
  }
@@ -579,11 +598,13 @@ var handleSelectorResult = (value, selector, data) => {
579
598
  });
580
599
  return value;
581
600
  } else {
582
- data.abortControllers.set(selector, false);
601
+ if (selector.get.length >= 2) {
602
+ data.abortControllers.set(selector, false);
603
+ }
583
604
  return value;
584
605
  }
585
606
  };
586
- var initSelectorDirect = (selector, data, initializedAtomsSet, circularDependencySet) => {
607
+ var initSelector = (selector, data, initializedAtomsSet, circularDependencySet = data.circularDepSet) => {
587
608
  const existingValue = data.values.get(selector);
588
609
  const updatedValue = evaluate(selector, data, initializedAtomsSet, circularDependencySet);
589
610
  const areEqual = isPromiseLike(existingValue) || isPromiseLike(updatedValue) ? existingValue === updatedValue : selector.equal(existingValue, updatedValue);
@@ -594,56 +615,6 @@ var initSelectorDirect = (selector, data, initializedAtomsSet, circularDependenc
594
615
  return true;
595
616
  }
596
617
  };
597
- var initSelectorTrampoline = (selector, data, initializedAtomsSet, circularDependencySet) => {
598
- const stack = [selector];
599
- const inStack = new Set([selector]);
600
- while (stack.length > 0) {
601
- const current = stack[stack.length - 1];
602
- if (data.values.has(current)) {
603
- stack.pop();
604
- inStack.delete(current);
605
- continue;
606
- }
607
- try {
608
- initSelectorDirect(current, data, initializedAtomsSet, circularDependencySet);
609
- stack.pop();
610
- inStack.delete(current);
611
- } catch (e) {
612
- if (e instanceof NeedsInitError) {
613
- if (inStack.has(e.selector)) {
614
- throw new SelectorCircularDependencyError;
615
- }
616
- stack.push(e.selector);
617
- inStack.add(e.selector);
618
- } else {
619
- throw e;
620
- }
621
- }
622
- }
623
- };
624
- var initSelector = (selector, data, initializedAtomsSet, circularDependencySet = sharedCircularDepSet) => {
625
- const isTopLevel = _evalDepth === 0 && !_inTrampoline;
626
- _evalDepth++;
627
- const existingValue = data.values.get(selector);
628
- try {
629
- return initSelectorDirect(selector, data, initializedAtomsSet, circularDependencySet);
630
- } catch (e) {
631
- if (e instanceof NeedsInitError && isTopLevel) {
632
- _inTrampoline = true;
633
- try {
634
- initSelectorTrampoline(selector, data, initializedAtomsSet, circularDependencySet);
635
- } finally {
636
- _inTrampoline = false;
637
- }
638
- const newValue = data.values.get(selector);
639
- const areEqual = isPromiseLike(existingValue) || isPromiseLike(newValue) ? existingValue === newValue : selector.equal(existingValue, newValue);
640
- return !areEqual;
641
- }
642
- throw e;
643
- } finally {
644
- _evalDepth--;
645
- }
646
- };
647
618
  var evaluate = (selector, data, initializedAtomsSet, circularDependencySet) => {
648
619
  let tmpValue;
649
620
  try {
@@ -657,23 +628,18 @@ var evaluate = (selector, data, initializedAtomsSet, circularDependencySet) => {
657
628
  };
658
629
 
659
630
  // src/lib/propagateUpdatedAtoms.ts
660
- var reEvaluteSelector = (selector, data, updatedAtoms) => {
661
- const existingValue = data.values.get(selector);
662
- const addedDeps = new Set;
663
- const removedDeps = new Set;
631
+ var reEvaluateSelector = (selector, data, updatedAtoms, depsChange, existingValue) => {
664
632
  try {
665
- const rawValue = evaluateSelector(selector, data, updatedAtoms, undefined, addedDeps, removedDeps);
666
- const udpatedValue = handleSelectorResult(rawValue, selector, data);
667
- const areEqual = isPromiseLike(existingValue) || isPromiseLike(udpatedValue) ? existingValue === udpatedValue : selector.equal(existingValue, udpatedValue, updatedAtoms);
668
- if (areEqual) {
669
- return [false, false, undefined, addedDeps, removedDeps];
670
- } else {
671
- setValueInData(selector, udpatedValue, data);
672
- return [true, false, undefined, addedDeps, removedDeps];
673
- }
674
- } catch (error) {
633
+ const rawValue = evaluateSelector(selector, data, updatedAtoms, undefined, depsChange);
634
+ const updatedValue = handleSelectorResult(rawValue, selector, data);
635
+ const areEqual = isPromiseLike(existingValue) || isPromiseLike(updatedValue) ? existingValue === updatedValue : selector.equal(existingValue, updatedValue, updatedAtoms);
636
+ if (areEqual)
637
+ return false;
638
+ setValueInData(selector, updatedValue, data);
639
+ return true;
640
+ } catch {
675
641
  data.values.delete(selector);
676
- return [true, true, error, addedDeps, removedDeps];
642
+ return true;
677
643
  }
678
644
  };
679
645
  var callSubscribers = (subscriptions, families) => {
@@ -715,7 +681,7 @@ var addSetToSet = (fromSet, toSet) => {
715
681
  }
716
682
  }
717
683
  };
718
- var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, families = new Map, timestamp = performance.now()) => {
684
+ var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, families = new Map, timestamp = performance.now(), evaluatedSelectors) => {
719
685
  const selectors = new Set;
720
686
  for (const atom of atoms) {
721
687
  addSetToSet(data.stateDependents.get(atom), selectors);
@@ -736,7 +702,7 @@ var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, families = ne
736
702
  deleteFamilyAtomsFromSet(family, familyAtoms, data, timestamp);
737
703
  }
738
704
  }
739
- propagateDirtySelectors(atoms, selectors, data, subscriptions, families);
705
+ propagateDirtySelectors(atoms, selectors, data, subscriptions, families, false, evaluatedSelectors);
740
706
  if (families.size > 0 && data.scopes && data.scopes.size > 0) {
741
707
  const scopeFamilies = new Map;
742
708
  for (const family of families.keys()) {
@@ -753,12 +719,12 @@ var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, families = ne
753
719
  }
754
720
  }
755
721
  for (const [scope, familiesInScope] of scopeFamilies) {
756
- propagateUpdatedAtoms(familiesInScope, scope, undefined, undefined, false, timestamp, true);
722
+ propagateInScope(familiesInScope, scope, false, evaluatedSelectors);
757
723
  }
758
724
  }
759
725
  };
760
- var propagateUpdatedAtoms = (atoms, data, subscriptions, families, isRecursive = false, timestamp = performance.now(), selectorsOnly = false, isInitOnly = false) => {
761
- if (atoms.length === 1 && !isRecursive && !selectorsOnly) {
726
+ var propagateAtomUpdate = (atoms, data, isInitOnly = false, evaluatedSelectors) => {
727
+ if (atoms.length === 1) {
762
728
  const atom = atoms[0];
763
729
  if (!isFamilyAtom(atom) && !isAtomFamily(atom)) {
764
730
  const dependents = data.stateDependents.get(atom);
@@ -771,24 +737,21 @@ var propagateUpdatedAtoms = (atoms, data, subscriptions, families, isRecursive =
771
737
  }
772
738
  }
773
739
  }
774
- if (!subscriptions)
775
- subscriptions = new Set;
776
- if (!families)
777
- families = new Map;
740
+ const subscriptions = new Set;
741
+ const families = new Map;
778
742
  const selectors = new Set;
779
743
  for (const atom of atoms) {
780
744
  addSetToSet(data.stateDependents.get(atom), selectors);
781
- if (!selectorsOnly) {
782
- addSetToSet(data.subscriptions.get(atom), subscriptions);
783
- if (isFamilyAtom(atom)) {
784
- if (!families.has(atom.family)) {
785
- families.set(atom.family, new Set);
786
- }
787
- families.get(atom.family).add(atom);
745
+ addSetToSet(data.subscriptions.get(atom), subscriptions);
746
+ if (isFamilyAtom(atom)) {
747
+ if (!families.has(atom.family)) {
748
+ families.set(atom.family, new Set);
788
749
  }
750
+ families.get(atom.family).add(atom);
789
751
  }
790
752
  }
791
753
  if (families.size > 0) {
754
+ const timestamp = performance.now();
792
755
  for (const [family, familyAtoms] of families) {
793
756
  addSetToSet(data.stateDependents.get(family), selectors);
794
757
  addSetToSet(data.subscriptions.get(family), subscriptions);
@@ -797,96 +760,308 @@ var propagateUpdatedAtoms = (atoms, data, subscriptions, families, isRecursive =
797
760
  addFamilyAtomsToSet(family, familyAtoms, data, timestamp);
798
761
  }
799
762
  }
800
- if (!isRecursive) {
801
- propagateDirtySelectors(atoms, selectors, data, subscriptions, families, isInitOnly);
802
- if (data.scopes && data.scopes.size > 0) {
803
- if (atoms.length === 1) {
804
- const atom = atoms[0];
805
- const shadowingScopes = isAtomFamily(atom) ? undefined : data.scopeValueIndex.get(atom);
806
- for (const [, scope] of data.scopes) {
807
- if (!shadowingScopes || !shadowingScopes.has(scope)) {
808
- propagateUpdatedAtoms(atoms, scope, undefined, undefined, false, timestamp, true, isInitOnly);
809
- }
810
- }
763
+ if (data.scopes && data.scopes.size > 0) {
764
+ for (const atom of atoms) {
765
+ if (isAtomFamily(atom) && !families.has(atom)) {
766
+ recursivelyUpdateIndexes(data, atom);
767
+ }
768
+ }
769
+ }
770
+ propagateDirtySelectors(atoms, selectors, data, subscriptions, families, isInitOnly, evaluatedSelectors);
771
+ if (data.scopes && data.scopes.size > 0) {
772
+ propagateToScopes(atoms, data, isInitOnly, evaluatedSelectors);
773
+ }
774
+ };
775
+ var propagateInScope = (atoms, data, isInitOnly = false, evaluatedSelectors) => {
776
+ const subscriptions = new Set;
777
+ const families = new Map;
778
+ const selectors = new Set;
779
+ for (const atom of atoms) {
780
+ addSetToSet(data.stateDependents.get(atom), selectors);
781
+ }
782
+ propagateDirtySelectors(atoms, selectors, data, subscriptions, families, isInitOnly, evaluatedSelectors);
783
+ if (data.scopes && data.scopes.size > 0) {
784
+ propagateToScopes(atoms, data, isInitOnly, evaluatedSelectors);
785
+ }
786
+ };
787
+ var propagateToScopes = (atoms, data, isInitOnly, evaluatedSelectors) => {
788
+ if (atoms.length === 1) {
789
+ const atom = atoms[0];
790
+ const shadowingScopes = isAtomFamily(atom) ? undefined : data.scopeValueIndex.get(atom);
791
+ for (const [, scope] of data.scopes) {
792
+ if (!shadowingScopes || !shadowingScopes.has(scope)) {
793
+ propagateInScope(atoms, scope, isInitOnly, evaluatedSelectors);
794
+ }
795
+ }
796
+ return;
797
+ }
798
+ let anyShadowed = false;
799
+ let atomShadows;
800
+ for (const atom of atoms) {
801
+ if (!isAtomFamily(atom)) {
802
+ const s = data.scopeValueIndex.get(atom);
803
+ if (s && s.size > 0) {
804
+ if (!atomShadows)
805
+ atomShadows = new Map;
806
+ atomShadows.set(atom, s);
807
+ anyShadowed = true;
808
+ }
809
+ }
810
+ }
811
+ if (!anyShadowed) {
812
+ for (const [, scope] of data.scopes) {
813
+ propagateInScope(atoms, scope, isInitOnly, evaluatedSelectors);
814
+ }
815
+ return;
816
+ }
817
+ for (const [, scope] of data.scopes) {
818
+ const atomsToUpdateInScope = [];
819
+ for (const atom of atoms) {
820
+ if (isAtomFamily(atom)) {
821
+ atomsToUpdateInScope.push(atom);
811
822
  } else {
812
- let anyShadowed = false;
813
- let atomShadows;
814
- for (const atom of atoms) {
815
- if (!isAtomFamily(atom)) {
816
- const s = data.scopeValueIndex.get(atom);
817
- if (s && s.size > 0) {
818
- if (!atomShadows)
819
- atomShadows = new Map;
820
- atomShadows.set(atom, s);
821
- anyShadowed = true;
822
- }
823
- }
824
- }
825
- if (!anyShadowed) {
826
- for (const [, scope] of data.scopes) {
827
- propagateUpdatedAtoms(atoms, scope, undefined, undefined, false, timestamp, true, isInitOnly);
828
- }
829
- } else {
830
- for (const [, scope] of data.scopes) {
831
- const atomsToUpdateInScope = [];
832
- for (const atom of atoms) {
833
- if (isAtomFamily(atom)) {
834
- atomsToUpdateInScope.push(atom);
835
- } else {
836
- const s = atomShadows.get(atom);
837
- if (!s || !s.has(scope)) {
838
- atomsToUpdateInScope.push(atom);
839
- }
840
- }
841
- }
842
- if (atomsToUpdateInScope.length > 0) {
843
- propagateUpdatedAtoms(atomsToUpdateInScope, scope, undefined, undefined, false, timestamp, true, isInitOnly);
844
- }
845
- }
823
+ const s = atomShadows.get(atom);
824
+ if (!s || !s.has(scope)) {
825
+ atomsToUpdateInScope.push(atom);
846
826
  }
847
827
  }
848
828
  }
829
+ if (atomsToUpdateInScope.length > 0) {
830
+ propagateInScope(atomsToUpdateInScope, scope, isInitOnly, evaluatedSelectors);
831
+ }
849
832
  }
850
833
  };
851
- var propagateDirtySelectors = (updatedAtoms, selectors, data, subscriptions, families, isInitOnly = false) => {
834
+ var propagateDirtySelectors = (updatedAtoms, selectors, data, subscriptions, families, isInitOnly = false, evaluatedSelectors) => {
852
835
  const updatedInitializedAtoms = new Set(updatedAtoms);
853
836
  if (selectors.size > 0) {
854
- propagateSelectorUpdates(selectors, data, subscriptions, updatedInitializedAtoms, isInitOnly);
837
+ propagateSelectorUpdates(selectors, data, subscriptions, updatedInitializedAtoms, isInitOnly, evaluatedSelectors);
855
838
  }
856
839
  if (subscriptions.size > 0) {
857
840
  callSubscribers(subscriptions, families);
858
841
  }
859
842
  };
860
- var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly = false) => {
861
- let currentSelectors = selectors;
862
- while (currentSelectors.size > 0) {
863
- const selectorsForNextPass = new Set;
864
- for (const selector of currentSelectors) {
865
- const currentValue = data.values.get(selector);
866
- if (isPromiseLike(currentValue) && isInitOnly) {
843
+ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly, evaluatedSelectors) => {
844
+ const closure = new Set(seeds);
845
+ {
846
+ const stack = [...seeds];
847
+ while (stack.length > 0) {
848
+ const s = stack.pop();
849
+ const downstream = data.stateDependents.get(s);
850
+ if (downstream) {
851
+ for (const d of downstream) {
852
+ if (!closure.has(d)) {
853
+ closure.add(d);
854
+ stack.push(d);
855
+ }
856
+ }
857
+ }
858
+ }
859
+ }
860
+ const pending = new Map;
861
+ const ready = [];
862
+ for (const s of closure) {
863
+ const deps = data.stateDependencies.get(s);
864
+ let count = 0;
865
+ if (deps) {
866
+ for (const d of deps) {
867
+ if (closure.has(d))
868
+ count++;
869
+ }
870
+ }
871
+ pending.set(s, count);
872
+ if (count === 0)
873
+ ready.push(s);
874
+ }
875
+ const needsEval = new Set(seeds);
876
+ let graphMutated = false;
877
+ const advance = (selector, propagateChange) => {
878
+ const downstream = data.stateDependents.get(selector);
879
+ if (!downstream)
880
+ return;
881
+ for (const d of downstream) {
882
+ if (!closure.has(d)) {
883
+ if (propagateChange) {
884
+ graphMutated = true;
885
+ closure.add(d);
886
+ pending.set(d, 0);
887
+ needsEval.add(d);
888
+ ready.push(d);
889
+ }
867
890
  continue;
868
891
  }
892
+ const c = (pending.get(d) ?? 0) - 1;
893
+ pending.set(d, c);
894
+ if (propagateChange)
895
+ needsEval.add(d);
896
+ if (c <= 0)
897
+ ready.push(d);
898
+ }
899
+ };
900
+ const depsChange = {};
901
+ let head = 0;
902
+ while (head < ready.length) {
903
+ const selector = ready[head++];
904
+ if (evaluatedSelectors !== undefined && evaluatedSelectors.has(selector)) {
905
+ advance(selector, false);
906
+ continue;
907
+ }
908
+ const currentValue = data.values.get(selector);
909
+ if (isPromiseLike(currentValue) && isInitOnly) {
910
+ advance(selector, false);
911
+ continue;
912
+ }
913
+ if (!needsEval.has(selector)) {
914
+ advance(selector, false);
915
+ continue;
916
+ }
917
+ const dependents = data.stateDependents.get(selector);
918
+ const subscribers = data.subscriptions.get(selector);
919
+ if (!isPromiseLike(currentValue) && (!dependents || dependents.size === 0) && (!subscribers || subscribers.size === 0)) {
920
+ data.values.delete(selector);
921
+ advance(selector, false);
922
+ continue;
923
+ }
924
+ depsChange.added = undefined;
925
+ depsChange.removed = undefined;
926
+ const wasValueUpdated = reEvaluateSelector(selector, data, updatedInitializedAtoms, depsChange, currentValue);
927
+ if (evaluatedSelectors !== undefined)
928
+ evaluatedSelectors.add(selector);
929
+ const added = depsChange.added;
930
+ const removed = depsChange.removed;
931
+ if (added || removed) {
932
+ graphMutated = true;
933
+ if (isLive(selector, data)) {
934
+ if (added) {
935
+ for (const dep of added) {
936
+ onLiveDependencyAdded(dep, data);
937
+ mountTransitiveDeps(dep, data);
938
+ }
939
+ }
940
+ if (removed) {
941
+ for (const dep of removed) {
942
+ onLiveDependencyRemoved(dep, data);
943
+ unmountOrphanedDeps(dep, data);
944
+ }
945
+ }
946
+ }
947
+ }
948
+ advance(selector, wasValueUpdated);
949
+ if (wasValueUpdated && subscribers) {
950
+ addSetToSet(subscribers, collectedSubscribers);
951
+ }
952
+ }
953
+ if (!graphMutated)
954
+ return;
955
+ let stranded;
956
+ for (const s of closure) {
957
+ if (needsEval.has(s) && (pending.get(s) ?? 0) > 0) {
958
+ if (!stranded)
959
+ stranded = new Set;
960
+ stranded.add(s);
961
+ }
962
+ }
963
+ if (!stranded)
964
+ return;
965
+ let work = stranded;
966
+ while (work.size > 0) {
967
+ const next = new Set;
968
+ for (const selector of work) {
969
+ const currentValue = data.values.get(selector);
970
+ if (isPromiseLike(currentValue) && isInitOnly)
971
+ continue;
869
972
  const dependents = data.stateDependents.get(selector);
870
973
  const subscribers = data.subscriptions.get(selector);
871
974
  if (!isPromiseLike(currentValue) && (!dependents || dependents.size === 0) && (!subscribers || subscribers.size === 0)) {
872
975
  data.values.delete(selector);
873
- } else {
874
- const [wasValueUpdated, didEvalCrash, error, addedDeps, removedDeps] = reEvaluteSelector(selector, data, updatedInitializedAtoms);
875
- if ((addedDeps.size > 0 || removedDeps.size > 0) && isTransitivelySubscribed(selector, data)) {
876
- for (const dep of addedDeps) {
976
+ continue;
977
+ }
978
+ depsChange.added = undefined;
979
+ depsChange.removed = undefined;
980
+ const wasValueUpdated = reEvaluateSelector(selector, data, updatedInitializedAtoms, depsChange, currentValue);
981
+ if (evaluatedSelectors !== undefined)
982
+ evaluatedSelectors.add(selector);
983
+ const added = depsChange.added;
984
+ const removed = depsChange.removed;
985
+ if ((added || removed) && isLive(selector, data)) {
986
+ if (added) {
987
+ for (const dep of added) {
988
+ onLiveDependencyAdded(dep, data);
877
989
  mountTransitiveDeps(dep, data);
878
990
  }
879
- for (const dep of removedDeps) {
991
+ }
992
+ if (removed) {
993
+ for (const dep of removed) {
994
+ onLiveDependencyRemoved(dep, data);
880
995
  unmountOrphanedDeps(dep, data);
881
996
  }
882
997
  }
883
- if (!wasValueUpdated)
884
- continue;
885
- addSetToSet(data.stateDependents.get(selector), selectorsForNextPass);
886
- addSetToSet(subscribers, collectedSubscribers);
998
+ }
999
+ if (wasValueUpdated) {
1000
+ if (subscribers)
1001
+ addSetToSet(subscribers, collectedSubscribers);
1002
+ const downstream = data.stateDependents.get(selector);
1003
+ if (downstream) {
1004
+ for (const d of downstream)
1005
+ next.add(d);
1006
+ }
887
1007
  }
888
1008
  }
889
- currentSelectors = selectorsForNextPass;
1009
+ work = next;
1010
+ }
1011
+ };
1012
+ var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly = false, evaluatedSelectors) => {
1013
+ if (selectors.size === 0)
1014
+ return;
1015
+ let downstreamSeeds;
1016
+ const depsChange = {};
1017
+ for (const selector of selectors) {
1018
+ if (evaluatedSelectors !== undefined && evaluatedSelectors.has(selector)) {
1019
+ continue;
1020
+ }
1021
+ const currentValue = data.values.get(selector);
1022
+ if (isPromiseLike(currentValue) && isInitOnly)
1023
+ continue;
1024
+ const dependents = data.stateDependents.get(selector);
1025
+ const subscribers = data.subscriptions.get(selector);
1026
+ if (!isPromiseLike(currentValue) && (!dependents || dependents.size === 0) && (!subscribers || subscribers.size === 0)) {
1027
+ data.values.delete(selector);
1028
+ continue;
1029
+ }
1030
+ depsChange.added = undefined;
1031
+ depsChange.removed = undefined;
1032
+ const wasValueUpdated = reEvaluateSelector(selector, data, updatedInitializedAtoms, depsChange, currentValue);
1033
+ if (evaluatedSelectors !== undefined)
1034
+ evaluatedSelectors.add(selector);
1035
+ const added = depsChange.added;
1036
+ const removed = depsChange.removed;
1037
+ if ((added || removed) && isLive(selector, data)) {
1038
+ if (added) {
1039
+ for (const dep of added) {
1040
+ onLiveDependencyAdded(dep, data);
1041
+ mountTransitiveDeps(dep, data);
1042
+ }
1043
+ }
1044
+ if (removed) {
1045
+ for (const dep of removed) {
1046
+ onLiveDependencyRemoved(dep, data);
1047
+ unmountOrphanedDeps(dep, data);
1048
+ }
1049
+ }
1050
+ }
1051
+ if (!wasValueUpdated)
1052
+ continue;
1053
+ if (subscribers)
1054
+ addSetToSet(subscribers, collectedSubscribers);
1055
+ const downstream = data.stateDependents.get(selector);
1056
+ if (downstream && downstream.size > 0) {
1057
+ if (!downstreamSeeds)
1058
+ downstreamSeeds = new Set;
1059
+ for (const d of downstream)
1060
+ downstreamSeeds.add(d);
1061
+ }
1062
+ }
1063
+ if (downstreamSeeds && downstreamSeeds.size > 0) {
1064
+ propagateDownstreamTopo(downstreamSeeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly, evaluatedSelectors);
890
1065
  }
891
1066
  };
892
1067
 
@@ -894,11 +1069,19 @@ var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedIn
894
1069
  var isFunction = (value) => typeof value === "function";
895
1070
 
896
1071
  // src/lib/setAtom.ts
897
- var handlePromise = (atom, promise, currentValue, data, skipOnSet) => {
898
- const emptyAtomPromise = currentValue?.__isEmptyAtomPromise__ ? currentValue : currentValue?.__emptyAtomPromiseOrigin__ ?? null;
899
- if (emptyAtomPromise) {
900
- promise.__emptyAtomPromiseOrigin__ = emptyAtomPromise;
1072
+ var resolvePendingDefault = (atom, data, value) => {
1073
+ let cur = data;
1074
+ while (cur) {
1075
+ const entry = cur.pendingDefaults.get(atom);
1076
+ if (entry) {
1077
+ entry.resolve(value);
1078
+ cur.pendingDefaults.delete(atom);
1079
+ return;
1080
+ }
1081
+ cur = "parent" in cur ? cur.parent : undefined;
901
1082
  }
1083
+ };
1084
+ var handlePromise = (atom, promise, currentValue, data, skipOnSet) => {
902
1085
  setValueInData(atom, promise, data);
903
1086
  promise.then((resolvedValue) => {
904
1087
  if (data.values.get(atom) !== promise)
@@ -906,15 +1089,13 @@ var handlePromise = (atom, promise, currentValue, data, skipOnSet) => {
906
1089
  setValueInData(atom, resolvedValue, data);
907
1090
  if (atom.onSet && !skipOnSet)
908
1091
  atom.onSet(resolvedValue, data);
909
- if (emptyAtomPromise) {
910
- emptyAtomPromise.__resolveEmptyAtomPromise__(resolvedValue);
911
- }
912
- propagateUpdatedAtoms([atom], data);
1092
+ resolvePendingDefault(atom, data, resolvedValue);
1093
+ propagateAtomUpdate([atom], data);
913
1094
  }).catch(() => {
914
1095
  if (data.values.get(atom) !== promise)
915
1096
  return;
916
1097
  setValueInData(atom, currentValue, data);
917
- propagateUpdatedAtoms([atom], data);
1098
+ propagateAtomUpdate([atom], data);
918
1099
  });
919
1100
  };
920
1101
  var setAtom = (atom, newValue, data, skipOnSet = false) => {
@@ -936,9 +1117,9 @@ var setAtom = (atom, newValue, data, skipOnSet = false) => {
936
1117
  handlePromise(atom, promise, currentValue, data, skipOnSet);
937
1118
  if (initializedAtomsSet && initializedAtomsSet.size > 0) {
938
1119
  initializedAtomsSet.add(atom);
939
- propagateUpdatedAtoms([...initializedAtomsSet], data);
1120
+ propagateAtomUpdate([...initializedAtomsSet], data);
940
1121
  } else {
941
- propagateUpdatedAtoms([atom], data);
1122
+ propagateAtomUpdate([atom], data);
942
1123
  }
943
1124
  return promise;
944
1125
  }
@@ -949,14 +1130,12 @@ var setAtom = (atom, newValue, data, skipOnSet = false) => {
949
1130
  syncValue = setValueInData(atom, syncValue, data);
950
1131
  if (atom.onSet && !skipOnSet)
951
1132
  atom.onSet(syncValue, data);
952
- if (currentValue?.__isEmptyAtomPromise__) {
953
- currentValue.__resolveEmptyAtomPromise__(syncValue);
954
- }
1133
+ resolvePendingDefault(atom, data, syncValue);
955
1134
  if (initializedAtomsSet && initializedAtomsSet.size > 0) {
956
1135
  initializedAtomsSet.add(atom);
957
- propagateUpdatedAtoms([...initializedAtomsSet], data);
1136
+ propagateAtomUpdate([...initializedAtomsSet], data);
958
1137
  } else {
959
- propagateUpdatedAtoms([atom], data);
1138
+ propagateAtomUpdate([atom], data);
960
1139
  }
961
1140
  return syncValue;
962
1141
  };
@@ -964,12 +1143,11 @@ var setAtom = (atom, newValue, data, skipOnSet = false) => {
964
1143
  // src/lib/initAtom.ts
965
1144
  var getAtomInitValue = (atom, data, initializedAtomsSet) => {
966
1145
  if (atom.defaultValue === undefined) {
967
- let promiseResolve;
968
- const promise = new Promise((resolve) => {
969
- promiseResolve = resolve;
1146
+ let resolve;
1147
+ const promise = new Promise((r) => {
1148
+ resolve = r;
970
1149
  });
971
- promise.__isEmptyAtomPromise__ = true;
972
- promise.__resolveEmptyAtomPromise__ = promiseResolve;
1150
+ data.pendingDefaults.set(atom, { promise, resolve });
973
1151
  return promise;
974
1152
  } else if (typeof atom.defaultValue === "function") {
975
1153
  const value = atom.defaultValue();
@@ -978,7 +1156,7 @@ var getAtomInitValue = (atom, data, initializedAtomsSet) => {
978
1156
  if (data.values.get(atom) !== value)
979
1157
  return;
980
1158
  setValueInData(atom, resolvedValue, data);
981
- propagateUpdatedAtoms([atom], data);
1159
+ propagateAtomUpdate([atom], data);
982
1160
  }, () => {
983
1161
  if (data.values.get(atom) === value) {
984
1162
  data.values.delete(atom);
@@ -1007,7 +1185,7 @@ function getState(state, data, initializedAtomsSet, circularDependencySet) {
1007
1185
  if (data.values.has(state))
1008
1186
  return data.values.get(state);
1009
1187
  if (isAtom(state)) {
1010
- if ("parent" in data)
1188
+ if (data.parent)
1011
1189
  return getState(state, data.parent, initializedAtomsSet, circularDependencySet);
1012
1190
  if (isFamilyAtom(state)) {
1013
1191
  const familyValue = data.values.get(state.family);
@@ -1022,14 +1200,11 @@ function getState(state, data, initializedAtomsSet, circularDependencySet) {
1022
1200
  return data.values.get(state);
1023
1201
  }
1024
1202
  if (isSelector(state)) {
1025
- if (_evalDepth >= MAX_EVAL_DEPTH) {
1026
- throw new NeedsInitError(state);
1027
- }
1028
1203
  initSelector(state, data, initializedAtomsSet, circularDependencySet);
1029
1204
  return data.values.get(state);
1030
1205
  }
1031
1206
  if (isAtomFamily(state)) {
1032
- if ("parent" in data) {
1207
+ if (data.parent) {
1033
1208
  const closestData = findClosestStoreWithAtomInitialized(state, data);
1034
1209
  return getState(state, closestData, initializedAtomsSet, circularDependencySet);
1035
1210
  }
@@ -1047,7 +1222,7 @@ function getState(state, data, initializedAtomsSet, circularDependencySet) {
1047
1222
  throw new Error("Invalid object passed to get");
1048
1223
  }
1049
1224
  var findClosestStoreWithAtomInitialized = (atom, data) => {
1050
- if ("parent" in data === false)
1225
+ if (!data.parent)
1051
1226
  return data;
1052
1227
  if (data.values.has(atom))
1053
1228
  return data;
@@ -1077,16 +1252,16 @@ var resolveReactive = (value, data) => {
1077
1252
  // src/lib/createStoreData.ts
1078
1253
  var nextId = 0;
1079
1254
  var generateId = () => "__valdres_store_" + nextId++;
1080
- function makeLazyGetter(key) {
1255
+ function makeLazyGetter(key, factory = () => new WeakMap) {
1081
1256
  return {
1082
1257
  get() {
1083
- const map = new WeakMap;
1258
+ const value = factory();
1084
1259
  Object.defineProperty(this, key, {
1085
- value: map,
1260
+ value,
1086
1261
  writable: true,
1087
1262
  configurable: true
1088
1263
  });
1089
- return map;
1264
+ return value;
1090
1265
  },
1091
1266
  configurable: true
1092
1267
  };
@@ -1098,8 +1273,11 @@ Object.defineProperties(lazyProto, {
1098
1273
  stateDependents: makeLazyGetter("stateDependents"),
1099
1274
  stateDependencies: makeLazyGetter("stateDependencies"),
1100
1275
  mounts: makeLazyGetter("mounts"),
1276
+ liveDependentCount: makeLazyGetter("liveDependentCount"),
1101
1277
  abortControllers: makeLazyGetter("abortControllers"),
1102
- lastValueWriteAt: makeLazyGetter("lastValueWriteAt")
1278
+ lastValueWriteAt: makeLazyGetter("lastValueWriteAt"),
1279
+ circularDepSet: makeLazyGetter("circularDepSet", () => new WeakSet),
1280
+ latestEvalContext: makeLazyGetter("latestEvalContext")
1103
1281
  });
1104
1282
  function createStoreData(id, parent, options) {
1105
1283
  const data = Object.create(lazyProto);
@@ -1107,6 +1285,7 @@ function createStoreData(id, parent, options) {
1107
1285
  data.values = new WeakMap;
1108
1286
  data.scopes = new Map;
1109
1287
  data.scopeValueIndex = new WeakMap;
1288
+ data.pendingDefaults = new WeakMap;
1110
1289
  if (options?.batchUpdates) {
1111
1290
  data.batchUpdates = true;
1112
1291
  }
@@ -1133,10 +1312,10 @@ var resetAtom = (atom, data) => {
1133
1312
  let value = getAtomInitValue(atom, data, initializedAtomsSet);
1134
1313
  setValueInData(atom, value, data);
1135
1314
  if (!isPromiseLike(value)) {
1136
- propagateUpdatedAtoms([atom], data);
1315
+ propagateAtomUpdate([atom], data);
1137
1316
  }
1138
1317
  if (initializedAtomsSet.size > 0) {
1139
- throw new Error("Todo - propagateUpdatedAtoms on reset");
1318
+ throw new Error("Todo - propagateAtomUpdate on reset");
1140
1319
  }
1141
1320
  return value;
1142
1321
  };
@@ -1185,6 +1364,7 @@ var unsubscribe = (state, subscription, data) => {
1185
1364
  deleteMaxAgeCleanup(data, state);
1186
1365
  }
1187
1366
  data.subscriptions.delete(state);
1367
+ onLastDirectSubscriber(state, data);
1188
1368
  unmountOrphanedDeps(state, data);
1189
1369
  cleanupOrphanedDeps(state, data);
1190
1370
  }
@@ -1194,7 +1374,7 @@ var cleanupOrphanedDeps = (state, data, visited = new Set) => {
1194
1374
  if (visited.has(state))
1195
1375
  return;
1196
1376
  visited.add(state);
1197
- if (isTransitivelySubscribed(state, data))
1377
+ if (isLive(state, data))
1198
1378
  return;
1199
1379
  const deps = data.stateDependencies.get(state);
1200
1380
  if (deps) {
@@ -1223,7 +1403,7 @@ var initSubscribers = (state, data) => {
1223
1403
  return set;
1224
1404
  };
1225
1405
  var installMaxAgeTimer = (state, data) => {
1226
- if (!state.maxAge)
1406
+ if (state.maxAge === undefined)
1227
1407
  return;
1228
1408
  const globalState = isGlobalAtom(state) ? state : undefined;
1229
1409
  const existing = globalState?.maxAgeInterval;
@@ -1233,7 +1413,7 @@ var installMaxAgeTimer = (state, data) => {
1233
1413
  for (const s of globalState.stores) {
1234
1414
  if (s !== data && s.values.has(metaAtom2)) {
1235
1415
  setValueInData(metaAtom2, s.values.get(metaAtom2), data);
1236
- propagateUpdatedAtoms([metaAtom2], data);
1416
+ propagateAtomUpdate([metaAtom2], data);
1237
1417
  break;
1238
1418
  }
1239
1419
  }
@@ -1272,11 +1452,11 @@ var installMaxAgeTimer = (state, data) => {
1272
1452
  if (globalState) {
1273
1453
  for (const store of globalState.stores) {
1274
1454
  setValueInData(metaAtom, meta, store);
1275
- propagateUpdatedAtoms([metaAtom], store);
1455
+ propagateAtomUpdate([metaAtom], store);
1276
1456
  }
1277
1457
  } else {
1278
1458
  setValueInData(metaAtom, meta, data);
1279
- propagateUpdatedAtoms([metaAtom], data);
1459
+ propagateAtomUpdate([metaAtom], data);
1280
1460
  }
1281
1461
  };
1282
1462
  const isPastStaleIfErrorWindow = () => {
@@ -1287,11 +1467,11 @@ var installMaxAgeTimer = (state, data) => {
1287
1467
  if (globalState) {
1288
1468
  for (const store of globalState.stores) {
1289
1469
  setValueInData(atom, val, store);
1290
- propagateUpdatedAtoms([atom], store);
1470
+ propagateAtomUpdate([atom], store);
1291
1471
  }
1292
1472
  } else {
1293
1473
  setValueInData(atom, val, data);
1294
- propagateUpdatedAtoms([atom], data);
1474
+ propagateAtomUpdate([atom], data);
1295
1475
  }
1296
1476
  };
1297
1477
  const getValueStore = () => {
@@ -1421,14 +1601,18 @@ var installMaxAgeTimer = (state, data) => {
1421
1601
  };
1422
1602
  var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) => {
1423
1603
  let parentUnsubscribe;
1424
- if ("parent" in data && (!data.values.has(state) && isAtom(state) || isAtomFamily(state))) {
1604
+ let dropDelegate;
1605
+ if (data.parent && (!data.values.has(state) && isAtom(state) || isAtomFamily(state))) {
1425
1606
  const originalCallback = callback;
1426
1607
  parentUnsubscribe = subscribe(state, originalCallback, requireDeepEqualCheckBeforeCallback, data.parent);
1427
- callback = (arg) => {
1608
+ dropDelegate = () => {
1428
1609
  if (parentUnsubscribe) {
1429
1610
  parentUnsubscribe();
1430
1611
  parentUnsubscribe = undefined;
1431
1612
  }
1613
+ };
1614
+ callback = (arg) => {
1615
+ dropDelegate();
1432
1616
  originalCallback(arg);
1433
1617
  };
1434
1618
  } else if (!data.values.has(state) && isAtom(state)) {
@@ -1450,20 +1634,23 @@ var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) =>
1450
1634
  subscription = {
1451
1635
  callback,
1452
1636
  state,
1453
- requireDeepEqualCheckBeforeCallback
1637
+ requireDeepEqualCheckBeforeCallback,
1638
+ reRoot: dropDelegate
1454
1639
  };
1455
1640
  } else {
1456
1641
  subscription = {
1457
1642
  callback,
1458
- requireDeepEqualCheckBeforeCallback
1643
+ requireDeepEqualCheckBeforeCallback,
1644
+ reRoot: dropDelegate
1459
1645
  };
1460
1646
  }
1461
1647
  subscribers.add(subscription);
1462
1648
  if (subscribers.size === 1) {
1463
- if (isAtom(state) && state.maxAge) {
1649
+ if (isAtom(state) && state.maxAge !== undefined && !data.parent) {
1464
1650
  installMaxAgeTimer(state, data);
1465
1651
  }
1466
1652
  if (!isFamily(state)) {
1653
+ onFirstDirectSubscriber(state, data);
1467
1654
  mountTransitiveDeps(state, data);
1468
1655
  }
1469
1656
  }
@@ -1478,8 +1665,8 @@ var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) =>
1478
1665
  };
1479
1666
  };
1480
1667
 
1481
- // src/lib/setAtoms.ts
1482
- var setAtoms = (pairs, data, initializedAtomsSet) => {
1668
+ // src/lib/writeAtoms.ts
1669
+ var writeAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false, onSetQueue) => {
1483
1670
  const updatedAtoms = [];
1484
1671
  for (let [atom, value] of pairs) {
1485
1672
  const currentValue = getState(atom, data, initializedAtomsSet);
@@ -1487,8 +1674,12 @@ var setAtoms = (pairs, data, initializedAtomsSet) => {
1487
1674
  if (!areEqual) {
1488
1675
  updatedAtoms.push(atom);
1489
1676
  value = setValueInData(atom, value, data);
1490
- if (atom.onSet)
1491
- atom.onSet(value, data);
1677
+ if (atom.onSet && !skipOnSet) {
1678
+ if (onSetQueue)
1679
+ onSetQueue.push([atom, value, data]);
1680
+ else
1681
+ atom.onSet(value, data);
1682
+ }
1492
1683
  } else {
1493
1684
  setValueInData(atom, value, data);
1494
1685
  }
@@ -1498,8 +1689,14 @@ var setAtoms = (pairs, data, initializedAtomsSet) => {
1498
1689
  updatedAtoms.push(atom);
1499
1690
  }
1500
1691
  }
1692
+ return updatedAtoms;
1693
+ };
1694
+
1695
+ // src/lib/setAtoms.ts
1696
+ var setAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false) => {
1697
+ const updatedAtoms = writeAtoms(pairs, data, initializedAtomsSet, skipOnSet);
1501
1698
  if (updatedAtoms.length > 0) {
1502
- propagateUpdatedAtoms(updatedAtoms, data);
1699
+ propagateAtomUpdate(updatedAtoms, data);
1503
1700
  }
1504
1701
  };
1505
1702
 
@@ -1587,7 +1784,7 @@ class Transaction {
1587
1784
  } else {
1588
1785
  resolved = value;
1589
1786
  }
1590
- if (!atom.mutable && !isProd() && resolved !== null && (typeof resolved === "object" || typeof resolved === "function")) {
1787
+ if (!atom.mutable && !IS_PROD && resolved !== null && (typeof resolved === "object" || typeof resolved === "function")) {
1591
1788
  resolved = deepFreeze(resolved);
1592
1789
  }
1593
1790
  this._atomMap.set(atom, resolved);
@@ -1651,6 +1848,9 @@ class Transaction {
1651
1848
  };
1652
1849
  parentScope = (callback) => {
1653
1850
  if (!this.parentTransaction) {
1851
+ if (!this.data.parent) {
1852
+ throw new Error("Cannot access parentScope on root store");
1853
+ }
1654
1854
  this.parentTransaction = new Transaction(this.data.parent, undefined, this);
1655
1855
  }
1656
1856
  return this.parentTransaction.execute(callback, false);
@@ -1674,15 +1874,58 @@ class Transaction {
1674
1874
  }
1675
1875
  };
1676
1876
  commit = () => {
1677
- const initializedAtomsSet = new Set;
1678
- setAtoms(this._atomMap, this.data, initializedAtomsSet);
1679
- if (this.deleteSet?.size) {
1680
- deleteAtomFamilyAtoms(this.deleteSet, this.data);
1681
- propagateDeletedAtoms([...this.deleteSet], this.data);
1877
+ if (!this._scopedTransactions) {
1878
+ const initializedAtomsSet = new Set;
1879
+ if (this._deleteSet?.size) {
1880
+ const evaluatedSelectors2 = new Set;
1881
+ const updatedAtoms = writeAtoms(this._atomMap, this.data, initializedAtomsSet);
1882
+ if (updatedAtoms.length > 0) {
1883
+ propagateAtomUpdate(updatedAtoms, this.data, false, evaluatedSelectors2);
1884
+ }
1885
+ deleteAtomFamilyAtoms(this._deleteSet, this.data);
1886
+ propagateDeletedAtoms([...this._deleteSet], this.data, undefined, undefined, undefined, evaluatedSelectors2);
1887
+ } else {
1888
+ setAtoms(this._atomMap, this.data, initializedAtomsSet);
1889
+ }
1890
+ return;
1891
+ }
1892
+ const plan = [];
1893
+ this.collectStores(plan);
1894
+ for (let i = plan.length - 1;i >= 0; i--) {
1895
+ const entry = plan[i];
1896
+ const txn = entry.txn;
1897
+ entry.updatedAtoms = writeAtoms(txn._atomMap, entry.data, new Set, false, entry.onSets);
1898
+ if (txn._deleteSet?.size) {
1899
+ deleteAtomFamilyAtoms(txn._deleteSet, entry.data);
1900
+ entry.deleted = [...txn._deleteSet];
1901
+ }
1682
1902
  }
1903
+ for (const entry of plan) {
1904
+ for (const [atom, value, data] of entry.onSets) {
1905
+ atom.onSet(value, data);
1906
+ }
1907
+ }
1908
+ const evaluatedSelectors = new Set;
1909
+ for (const { data, updatedAtoms, deleted } of plan) {
1910
+ if (updatedAtoms.length > 0) {
1911
+ propagateAtomUpdate(updatedAtoms, data, false, evaluatedSelectors);
1912
+ }
1913
+ if (deleted) {
1914
+ propagateDeletedAtoms(deleted, data, undefined, undefined, undefined, evaluatedSelectors);
1915
+ }
1916
+ }
1917
+ };
1918
+ collectStores = (plan) => {
1919
+ plan.push({
1920
+ txn: this,
1921
+ data: this.data,
1922
+ updatedAtoms: [],
1923
+ deleted: undefined,
1924
+ onSets: []
1925
+ });
1683
1926
  if (this._scopedTransactions) {
1684
1927
  for (const [, scopedTxn] of this._scopedTransactions) {
1685
- scopedTxn.commit();
1928
+ scopedTxn.collectStores(plan);
1686
1929
  }
1687
1930
  }
1688
1931
  };
@@ -1759,6 +2002,8 @@ var isCachedValueStale = (state, data) => {
1759
2002
  const maxAge = atom.maxAge;
1760
2003
  if (maxAge === undefined)
1761
2004
  return false;
2005
+ if (data.parent)
2006
+ return false;
1762
2007
  if (isGlobalAtom(atom)) {
1763
2008
  if (atom.maxAgeInterval !== undefined)
1764
2009
  return false;
@@ -1813,7 +2058,7 @@ function storeFromStoreData(data, detach) {
1813
2058
  if (_initSet.size) {
1814
2059
  const atoms = [..._initSet];
1815
2060
  _initSet.clear();
1816
- propagateUpdatedAtoms(atoms, data, undefined, undefined, false, undefined, false, true);
2061
+ propagateAtomUpdate(atoms, data, true);
1817
2062
  }
1818
2063
  }
1819
2064
  return res;
@@ -1874,11 +2119,13 @@ function storeFromStoreData(data, detach) {
1874
2119
  scopedStoreData = createStoreData(scopeId, data, data.batchUpdates ? { batchUpdates: true } : undefined);
1875
2120
  data.scopes.set(scopeId, scopedStoreData);
1876
2121
  }
2122
+ const consumers = scopedStoreData.scopeConsumers;
2123
+ const indexKeys = scopedStoreData.scopeIndexKeys;
1877
2124
  const detach2 = (expectedToDestroy = false) => {
1878
- scopedStoreData.scopeConsumers.delete(detach2);
1879
- if (scopedStoreData.scopeConsumers.size === 0) {
2125
+ consumers.delete(detach2);
2126
+ if (consumers.size === 0) {
1880
2127
  data.scopes.delete(scopeId);
1881
- for (const key of scopedStoreData.scopeIndexKeys) {
2128
+ for (const key of indexKeys) {
1882
2129
  const set2 = data.scopeValueIndex.get(key);
1883
2130
  if (set2) {
1884
2131
  set2.delete(scopedStoreData);
@@ -1886,15 +2133,15 @@ function storeFromStoreData(data, detach) {
1886
2133
  data.scopeValueIndex.delete(key);
1887
2134
  }
1888
2135
  }
1889
- scopedStoreData.scopeIndexKeys.clear();
2136
+ indexKeys.clear();
1890
2137
  return true;
1891
2138
  }
1892
2139
  if (expectedToDestroy) {
1893
- console.warn(`Scope ${scopeId} still has ${scopedStoreData.scopeConsumers.size} consumers, will not detach`);
2140
+ console.warn(`Scope ${scopeId} still has ${consumers.size} consumers, will not detach`);
1894
2141
  }
1895
2142
  return false;
1896
2143
  };
1897
- scopedStoreData.scopeConsumers.add(detach2);
2144
+ consumers.add(detach2);
1898
2145
  const newStore = storeFromStoreData(data.scopes.get(scopeId), detach2);
1899
2146
  return newStore;
1900
2147
  }
@@ -1926,25 +2173,83 @@ function storeFromStoreData(data, detach) {
1926
2173
  }
1927
2174
 
1928
2175
  // src/lib/mountAtom.ts
1929
- var isTransitivelySubscribed = (state, data, visited = new Set) => {
1930
- const stack = [state];
2176
+ var hasDirectSubscribers = (state, data) => {
2177
+ const subs = data.subscriptions.get(state);
2178
+ return !!subs && subs.size > 0;
2179
+ };
2180
+ var isLive = (state, data) => {
2181
+ if (hasDirectSubscribers(state, data))
2182
+ return true;
2183
+ const count = data.liveDependentCount.get(state);
2184
+ return !!count && count > 0;
2185
+ };
2186
+ var propagateLive = (root, data) => {
2187
+ const stack = [root];
1931
2188
  while (stack.length > 0) {
1932
2189
  const current = stack.pop();
1933
- if (visited.has(current))
2190
+ const deps = data.stateDependencies.get(current);
2191
+ if (!deps)
1934
2192
  continue;
1935
- visited.add(current);
1936
- const subs = data.subscriptions.get(current);
1937
- if (subs && subs.size > 0)
1938
- return true;
1939
- const dependents = data.stateDependents.get(current);
1940
- if (dependents) {
1941
- for (const dep of dependents) {
1942
- if (!visited.has(dep))
1943
- stack.push(dep);
2193
+ for (const dep of deps) {
2194
+ const prev = data.liveDependentCount.get(dep) ?? 0;
2195
+ data.liveDependentCount.set(dep, prev + 1);
2196
+ if (prev === 0 && !hasDirectSubscribers(dep, data)) {
2197
+ stack.push(dep);
1944
2198
  }
1945
2199
  }
1946
2200
  }
1947
- return false;
2201
+ };
2202
+ var propagateNotLive = (root, data) => {
2203
+ const stack = [root];
2204
+ while (stack.length > 0) {
2205
+ const current = stack.pop();
2206
+ const deps = data.stateDependencies.get(current);
2207
+ if (!deps)
2208
+ continue;
2209
+ for (const dep of deps) {
2210
+ const prev = data.liveDependentCount.get(dep) ?? 0;
2211
+ const next = prev - 1;
2212
+ if (next <= 0) {
2213
+ data.liveDependentCount.delete(dep);
2214
+ } else {
2215
+ data.liveDependentCount.set(dep, next);
2216
+ }
2217
+ if (prev === 1 && !hasDirectSubscribers(dep, data)) {
2218
+ stack.push(dep);
2219
+ }
2220
+ }
2221
+ }
2222
+ };
2223
+ var onFirstDirectSubscriber = (state, data) => {
2224
+ const liveDepCount = data.liveDependentCount.get(state) ?? 0;
2225
+ if (liveDepCount === 0) {
2226
+ propagateLive(state, data);
2227
+ }
2228
+ };
2229
+ var onLastDirectSubscriber = (state, data) => {
2230
+ const liveDepCount = data.liveDependentCount.get(state) ?? 0;
2231
+ if (liveDepCount === 0) {
2232
+ propagateNotLive(state, data);
2233
+ }
2234
+ };
2235
+ var onLiveDependencyAdded = (dep, data) => {
2236
+ const prev = data.liveDependentCount.get(dep) ?? 0;
2237
+ data.liveDependentCount.set(dep, prev + 1);
2238
+ if (prev === 0 && !hasDirectSubscribers(dep, data)) {
2239
+ propagateLive(dep, data);
2240
+ }
2241
+ };
2242
+ var onLiveDependencyRemoved = (dep, data) => {
2243
+ const prev = data.liveDependentCount.get(dep) ?? 0;
2244
+ const next = prev - 1;
2245
+ if (next <= 0) {
2246
+ data.liveDependentCount.delete(dep);
2247
+ } else {
2248
+ data.liveDependentCount.set(dep, next);
2249
+ }
2250
+ if (prev === 1 && !hasDirectSubscribers(dep, data)) {
2251
+ propagateNotLive(dep, data);
2252
+ }
1948
2253
  };
1949
2254
  var mountAtom = (state, data) => {
1950
2255
  const onMountFn = state.__valdresOnMount ?? state.onMount;
@@ -1954,7 +2259,9 @@ var mountAtom = (state, data) => {
1954
2259
  data.mounts.set(state, mountEntry);
1955
2260
  const store = data.storeRef ?? storeFromStoreData(data);
1956
2261
  try {
1957
- mountEntry.cleanup = onMountFn(store, state);
2262
+ const result = onMountFn(store, state);
2263
+ if (typeof result === "function")
2264
+ mountEntry.cleanup = result;
1958
2265
  } catch (error) {
1959
2266
  data.mounts.delete(state);
1960
2267
  throw error;
@@ -1969,14 +2276,20 @@ var unmountAtom = (state, data) => {
1969
2276
  mount.cleanup();
1970
2277
  }
1971
2278
  };
1972
- var mountTransitiveDeps = (state, data, visited = new Set) => {
2279
+ var mountTransitiveDeps = (state, data, visited) => {
2280
+ if (!state.__valdresOnMount && !state.onMount) {
2281
+ const deps = data.stateDependencies.get(state);
2282
+ if (!deps || deps.size === 0)
2283
+ return;
2284
+ }
2285
+ const seen = visited ?? new Set;
1973
2286
  let firstError = null;
1974
2287
  const stack = [state];
1975
2288
  while (stack.length > 0) {
1976
2289
  const current = stack.pop();
1977
- if (visited.has(current))
2290
+ if (seen.has(current))
1978
2291
  continue;
1979
- visited.add(current);
2292
+ seen.add(current);
1980
2293
  if (current.__valdresOnMount || current.onMount) {
1981
2294
  try {
1982
2295
  mountAtom(current, data);
@@ -1988,7 +2301,7 @@ var mountTransitiveDeps = (state, data, visited = new Set) => {
1988
2301
  const deps = data.stateDependencies.get(current);
1989
2302
  if (deps) {
1990
2303
  for (const dep of deps) {
1991
- if (!visited.has(dep))
2304
+ if (!seen.has(dep))
1992
2305
  stack.push(dep);
1993
2306
  }
1994
2307
  }
@@ -1997,16 +2310,22 @@ var mountTransitiveDeps = (state, data, visited = new Set) => {
1997
2310
  throw firstError.value;
1998
2311
  }
1999
2312
  };
2000
- var unmountOrphanedDeps = (state, data, visited = new Set) => {
2313
+ var unmountOrphanedDeps = (state, data, visited) => {
2314
+ if (!state.__valdresOnMount && !state.onMount) {
2315
+ const deps = data.stateDependencies.get(state);
2316
+ if (!deps || deps.size === 0)
2317
+ return;
2318
+ }
2319
+ const seen = visited ?? new Set;
2001
2320
  let firstError = null;
2002
2321
  const stack = [state];
2003
2322
  while (stack.length > 0) {
2004
2323
  const current = stack.pop();
2005
- if (visited.has(current))
2324
+ if (seen.has(current))
2006
2325
  continue;
2007
- visited.add(current);
2326
+ seen.add(current);
2008
2327
  if ((current.__valdresOnMount || current.onMount) && data.mounts.has(current)) {
2009
- if (!isTransitivelySubscribed(current, data)) {
2328
+ if (!isLive(current, data)) {
2010
2329
  try {
2011
2330
  unmountAtom(current, data);
2012
2331
  } catch (error) {
@@ -2018,7 +2337,7 @@ var unmountOrphanedDeps = (state, data, visited = new Set) => {
2018
2337
  const deps = data.stateDependencies.get(current);
2019
2338
  if (deps) {
2020
2339
  for (const dep of deps) {
2021
- if (!visited.has(dep))
2340
+ if (!seen.has(dep))
2022
2341
  stack.push(dep);
2023
2342
  }
2024
2343
  }
@@ -2045,8 +2364,7 @@ var globalStore = Object.assign(store("valdres-global-store"), {
2045
2364
  // src/lib/globalAtom.ts
2046
2365
  var globalAtom = (defaultValue, options) => {
2047
2366
  const stores = new Set;
2048
- if (options.onSet)
2049
- throw new Error("onSet on globalAtom is currently not supported");
2367
+ const userOnSet = options.onSet;
2050
2368
  const onInit = (setSelf2, data) => {
2051
2369
  setSelf2(globalStore.get(atom));
2052
2370
  stores.add(data);
@@ -2059,6 +2377,7 @@ var globalAtom = (defaultValue, options) => {
2059
2377
  }
2060
2378
  }
2061
2379
  }
2380
+ userOnSet?.(newValue, currentStore);
2062
2381
  };
2063
2382
  let mountCount = 0;
2064
2383
  let userCleanup;
@@ -2091,7 +2410,7 @@ var globalAtom = (defaultValue, options) => {
2091
2410
  const snapshot = [...stores];
2092
2411
  const subscribedStores = [];
2093
2412
  for (const s of snapshot) {
2094
- if (isTransitivelySubscribed(atom, s)) {
2413
+ if (isLive(atom, s)) {
2095
2414
  subscribedStores.push(s);
2096
2415
  }
2097
2416
  }
@@ -2116,14 +2435,14 @@ var globalAtom = (defaultValue, options) => {
2116
2435
  stores.delete(store2);
2117
2436
  store2.values.delete(atom);
2118
2437
  try {
2119
- propagateUpdatedAtoms([atom], store2);
2438
+ propagateAtomUpdate([atom], store2);
2120
2439
  } catch (e) {
2121
2440
  recordError(e);
2122
2441
  }
2123
2442
  }
2124
2443
  for (const s of subscribedStores) {
2125
2444
  stores.add(s);
2126
- if (atom.maxAge && (s.subscriptions.get(atom)?.size ?? 0) > 0) {
2445
+ if (atom.maxAge !== undefined && (s.subscriptions.get(atom)?.size ?? 0) > 0) {
2127
2446
  installMaxAgeTimer(atom, s);
2128
2447
  }
2129
2448
  try {
@@ -2149,9 +2468,7 @@ var globalAtom = (defaultValue, options) => {
2149
2468
  getSelf,
2150
2469
  resetSelf,
2151
2470
  detach,
2152
- get stores() {
2153
- return stores;
2154
- },
2471
+ stores,
2155
2472
  maxAgeInterval: undefined
2156
2473
  };
2157
2474
  return atom;
@@ -2247,11 +2564,7 @@ var createAtomFamily = (defaultValue, options) => {
2247
2564
  const isFunctionDefault = !isSelectorFamilyDefault && typeof defaultValue === "function";
2248
2565
  const hasName = !!options?.name;
2249
2566
  const isGlobal = !!options?.global;
2250
- const atomFamily = (...args) => {
2251
- const key = familyKey(args);
2252
- const cached = map.get(key);
2253
- if (cached !== undefined)
2254
- return cached;
2567
+ const build = (args, key) => {
2255
2568
  let dv;
2256
2569
  if (isSelectorFamilyDefault) {
2257
2570
  dv = defaultValue(...args);
@@ -2281,14 +2594,34 @@ var createAtomFamily = (defaultValue, options) => {
2281
2594
  map.set(key, familyAtom);
2282
2595
  return familyAtom;
2283
2596
  };
2597
+ function atomFamily(a0) {
2598
+ if (arguments.length === 1) {
2599
+ const t = typeof a0;
2600
+ if (t === "string" || t === "number" || t === "boolean") {
2601
+ const cached2 = map.get(a0);
2602
+ if (cached2 !== undefined)
2603
+ return cached2;
2604
+ return build([a0], a0);
2605
+ }
2606
+ }
2607
+ const args = Array.prototype.slice.call(arguments);
2608
+ const key = familyKey(args);
2609
+ const cached = map.get(key);
2610
+ if (cached !== undefined)
2611
+ return cached;
2612
+ return build(args, key);
2613
+ }
2284
2614
  if (hasName)
2285
2615
  Object.defineProperty(atomFamily, "name", {
2286
2616
  value: options.name,
2287
2617
  writable: false
2288
2618
  });
2289
- return Object.assign(atomFamily, {
2619
+ const callable = atomFamily;
2620
+ return Object.assign(callable, {
2290
2621
  __valdresAtomFamilyMap: map,
2291
- release: (...args) => map.delete(familyKey(args)),
2622
+ release: (...args) => {
2623
+ map.delete(familyKey(args));
2624
+ },
2292
2625
  equal
2293
2626
  });
2294
2627
  };
@@ -2389,11 +2722,10 @@ var selectorFamily = (callback, options) => {
2389
2722
  const cached = map.get(key);
2390
2723
  if (cached !== undefined)
2391
2724
  return cached;
2392
- const get = (selectorArgs) => callback(...args)(selectorArgs);
2393
2725
  const newSelector = {
2394
2726
  equal,
2395
2727
  ...options,
2396
- get,
2728
+ get: callback(...args),
2397
2729
  family: selectorFamily2,
2398
2730
  familyArgs: args,
2399
2731
  familyArgsStringified: key,
@@ -2416,9 +2748,9 @@ var isFamilySelector = (state) => isFamilyState(state) && isSelector(state);
2416
2748
 
2417
2749
  // src/index.ts
2418
2750
  if (globalThis.__valdres__) {
2419
- throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${"1.0.0-beta.3"}`);
2751
+ throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${"1.0.0-beta.5"}`);
2420
2752
  } else {
2421
- globalThis.__valdres__ = "1.0.0-beta.3";
2753
+ globalThis.__valdres__ = "1.0.0-beta.5";
2422
2754
  }
2423
2755
  export {
2424
2756
  store,