valdres 1.0.0-beta.5 → 1.0.0-beta.7
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 +720 -158
- package/dist/types/index.d.ts +5 -0
- package/dist/types/indexConstructor.d.ts +2 -1
- package/dist/types/lib/createStoreData.d.ts +4 -0
- package/dist/types/lib/notifyChangeListeners.d.ts +96 -0
- package/dist/types/lib/onStoreChange.d.ts +15 -0
- package/dist/types/lib/propagateUpdatedAtoms.d.ts +11 -4
- package/dist/types/lib/resolveAtomDefaultValue.d.ts +3 -0
- package/dist/types/lib/resolvePendingDefault.d.ts +32 -0
- package/dist/types/lib/setAtoms.d.ts +2 -1
- package/dist/types/lib/snapshot.d.ts +7 -0
- package/dist/types/lib/transaction.d.ts +9 -1
- package/dist/types/lib/unsetValue.d.ts +50 -0
- package/dist/types/store.d.ts +3 -1
- package/dist/types/types/Atom.d.ts +6 -0
- package/dist/types/types/Selector.d.ts +5 -0
- package/dist/types/types/SnapshotEntry.d.ts +24 -0
- package/dist/types/types/Store.d.ts +60 -1
- package/dist/types/types/StoreChange.d.ts +62 -0
- package/dist/types/types/StoreChangeCallback.d.ts +16 -0
- package/dist/types/types/StoreChangeMeta.d.ts +11 -0
- package/dist/types/types/StoreChangeSource.d.ts +21 -0
- package/dist/types/types/StoreData.d.ts +22 -1
- package/dist/types/types/Subscription.d.ts +7 -0
- package/dist/types/types/TransactionInterface.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -97,10 +97,10 @@ var equal = (a, b, updatedAtomsSet) => {
|
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
// src/utils/isAtom.ts
|
|
100
|
-
var isAtom = (state) => Object.hasOwn(state, "defaultValue");
|
|
100
|
+
var isAtom = (state) => state && Object.hasOwn(state, "defaultValue");
|
|
101
101
|
|
|
102
102
|
// src/utils/isGlobalAtom.ts
|
|
103
|
-
var isGlobalAtom = (state) => Object.hasOwn(state, "stores");
|
|
103
|
+
var isGlobalAtom = (state) => state && Object.hasOwn(state, "stores");
|
|
104
104
|
|
|
105
105
|
// src/utils/isSelector.ts
|
|
106
106
|
var isSelector = (state) => state && Object.hasOwn(state, "get");
|
|
@@ -108,6 +108,11 @@ var isSelector = (state) => state && Object.hasOwn(state, "get");
|
|
|
108
108
|
// src/utils/isAtomFamily.ts
|
|
109
109
|
var isAtomFamily = (state) => state && Object.hasOwn(state, "__valdresAtomFamilyMap");
|
|
110
110
|
|
|
111
|
+
// src/utils/isPromiseLike.ts
|
|
112
|
+
var isPromiseLike = (object) => {
|
|
113
|
+
return object && object.then && typeof object.then === "function";
|
|
114
|
+
};
|
|
115
|
+
|
|
111
116
|
// src/utils/isFamilyState.ts
|
|
112
117
|
var isFamilyState = (state) => state && Object.hasOwn(state, "family");
|
|
113
118
|
|
|
@@ -117,11 +122,6 @@ var isFamilyAtom = (state) => isFamilyState(state) && isAtom(state);
|
|
|
117
122
|
// src/utils/isSelectorFamily.ts
|
|
118
123
|
var isSelectorFamily = (state) => state && Object.hasOwn(state, "__valdresSelectorFamilyMap");
|
|
119
124
|
|
|
120
|
-
// src/utils/isPromiseLike.ts
|
|
121
|
-
var isPromiseLike = (object) => {
|
|
122
|
-
return object && object.then && typeof object.then === "function";
|
|
123
|
-
};
|
|
124
|
-
|
|
125
125
|
// src/utils/deepFreeze.ts
|
|
126
126
|
var deepFreeze = (obj, seen) => {
|
|
127
127
|
if (obj === null || obj === undefined)
|
|
@@ -403,6 +403,213 @@ var cleanUpRejectedPromise = (selector, data, promise) => {
|
|
|
403
403
|
data.values.delete(selector);
|
|
404
404
|
};
|
|
405
405
|
|
|
406
|
+
// src/lib/notifyChangeListeners.ts
|
|
407
|
+
var changeListenerRegistry = { count: 0, selectorCount: 0 };
|
|
408
|
+
var hasChangeListener = (data) => {
|
|
409
|
+
if (changeListenerRegistry.count === 0)
|
|
410
|
+
return false;
|
|
411
|
+
let store = data;
|
|
412
|
+
while (store) {
|
|
413
|
+
const listeners = store.changeListeners;
|
|
414
|
+
if (listeners !== undefined && listeners.size > 0)
|
|
415
|
+
return true;
|
|
416
|
+
store = store.parent;
|
|
417
|
+
}
|
|
418
|
+
return false;
|
|
419
|
+
};
|
|
420
|
+
var hasSelectorChangeListener = (data) => {
|
|
421
|
+
if (changeListenerRegistry.selectorCount === 0)
|
|
422
|
+
return false;
|
|
423
|
+
let store = data;
|
|
424
|
+
while (store) {
|
|
425
|
+
const listeners = store.changeListeners;
|
|
426
|
+
if (listeners !== undefined) {
|
|
427
|
+
for (const flags of listeners.values()) {
|
|
428
|
+
if (flags.selectors)
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
store = store.parent;
|
|
433
|
+
}
|
|
434
|
+
return false;
|
|
435
|
+
};
|
|
436
|
+
var scopePath = (data) => {
|
|
437
|
+
const path = [];
|
|
438
|
+
let store = data;
|
|
439
|
+
while (store && store.parent) {
|
|
440
|
+
path.push(store.id);
|
|
441
|
+
store = store.parent;
|
|
442
|
+
}
|
|
443
|
+
path.reverse();
|
|
444
|
+
return path;
|
|
445
|
+
};
|
|
446
|
+
var notifyChangeListeners = (groups, meta) => {
|
|
447
|
+
let buckets;
|
|
448
|
+
for (const group of groups) {
|
|
449
|
+
if (group.changes.length === 0)
|
|
450
|
+
continue;
|
|
451
|
+
let store = group.data;
|
|
452
|
+
while (store) {
|
|
453
|
+
const listeners = store.changeListeners;
|
|
454
|
+
if (listeners !== undefined && listeners.size > 0) {
|
|
455
|
+
if (!buckets)
|
|
456
|
+
buckets = new Map;
|
|
457
|
+
let bucket = buckets.get(store);
|
|
458
|
+
if (!bucket) {
|
|
459
|
+
bucket = [];
|
|
460
|
+
buckets.set(store, bucket);
|
|
461
|
+
}
|
|
462
|
+
for (const change of group.changes)
|
|
463
|
+
bucket.push(change);
|
|
464
|
+
}
|
|
465
|
+
store = store.parent;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (!buckets)
|
|
469
|
+
return;
|
|
470
|
+
for (const [store, changes] of buckets) {
|
|
471
|
+
const listeners = store.changeListeners;
|
|
472
|
+
if (listeners === undefined || listeners.size === 0)
|
|
473
|
+
continue;
|
|
474
|
+
let hasSelector;
|
|
475
|
+
let hasAtom;
|
|
476
|
+
let atomOnly;
|
|
477
|
+
let selectorOnly;
|
|
478
|
+
let firstError;
|
|
479
|
+
let hasError = false;
|
|
480
|
+
for (const [listener, flags] of [...listeners]) {
|
|
481
|
+
let payload;
|
|
482
|
+
if (flags.atoms && flags.selectors) {
|
|
483
|
+
payload = changes;
|
|
484
|
+
} else if (flags.atoms) {
|
|
485
|
+
if (atomOnly === undefined) {
|
|
486
|
+
hasSelector ??= changes.some((c) => c.type === "selector");
|
|
487
|
+
atomOnly = hasSelector ? changes.filter((c) => c.type === "atom") : changes;
|
|
488
|
+
}
|
|
489
|
+
payload = atomOnly;
|
|
490
|
+
} else if (flags.selectors) {
|
|
491
|
+
if (selectorOnly === undefined) {
|
|
492
|
+
hasAtom ??= changes.some((c) => c.type === "atom");
|
|
493
|
+
selectorOnly = hasAtom ? changes.filter((c) => c.type === "selector") : changes;
|
|
494
|
+
}
|
|
495
|
+
payload = selectorOnly;
|
|
496
|
+
} else {
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
if (payload.length === 0)
|
|
500
|
+
continue;
|
|
501
|
+
try {
|
|
502
|
+
listener(payload, meta);
|
|
503
|
+
} catch (error) {
|
|
504
|
+
if (!hasError) {
|
|
505
|
+
firstError = error;
|
|
506
|
+
hasError = true;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (hasError)
|
|
511
|
+
throw firstError;
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
var buildChangeGroup = (data, changedAtoms, deletedAtoms, changedSelectors) => {
|
|
515
|
+
const scope = scopePath(data);
|
|
516
|
+
const changes = [];
|
|
517
|
+
let seen;
|
|
518
|
+
if (changedAtoms) {
|
|
519
|
+
for (const atom of changedAtoms) {
|
|
520
|
+
if (atom.__valdresInternal || isAtomFamily(atom))
|
|
521
|
+
continue;
|
|
522
|
+
if (seen?.has(atom))
|
|
523
|
+
continue;
|
|
524
|
+
(seen ??= new Set).add(atom);
|
|
525
|
+
changes.push({
|
|
526
|
+
type: "atom",
|
|
527
|
+
kind: "set",
|
|
528
|
+
state: atom,
|
|
529
|
+
value: data.values.get(atom),
|
|
530
|
+
scope
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (deletedAtoms) {
|
|
535
|
+
for (const atom of deletedAtoms) {
|
|
536
|
+
if (atom.__valdresInternal || isAtomFamily(atom))
|
|
537
|
+
continue;
|
|
538
|
+
changes.push({ type: "atom", kind: "delete", state: atom, scope });
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
if (changedSelectors) {
|
|
542
|
+
for (const selector of changedSelectors) {
|
|
543
|
+
if (selector.__valdresInternal || isSelectorFamily(selector))
|
|
544
|
+
continue;
|
|
545
|
+
if (!data.values.has(selector))
|
|
546
|
+
continue;
|
|
547
|
+
changes.push({
|
|
548
|
+
type: "selector",
|
|
549
|
+
state: selector,
|
|
550
|
+
value: data.values.get(selector),
|
|
551
|
+
scope
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return { data, changes };
|
|
556
|
+
};
|
|
557
|
+
var emitGroup = (group, report) => {
|
|
558
|
+
if (group.changes.length === 0)
|
|
559
|
+
return;
|
|
560
|
+
if (typeof report === "string") {
|
|
561
|
+
notifyChangeListeners([group], { source: report });
|
|
562
|
+
} else {
|
|
563
|
+
report.groups.push(group);
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
var reportAtomChanges = (atoms, data, report, changedSelectors) => {
|
|
567
|
+
if (!hasChangeListener(data))
|
|
568
|
+
return;
|
|
569
|
+
const selectors = changedSelectors && changedSelectors.size > 0 && hasSelectorChangeListener(data) ? changedSelectors : undefined;
|
|
570
|
+
emitGroup(buildChangeGroup(data, atoms, undefined, selectors), report);
|
|
571
|
+
};
|
|
572
|
+
var reportUnsetAtom = (atom, data, revertedValue, report) => {
|
|
573
|
+
if (!hasChangeListener(data))
|
|
574
|
+
return;
|
|
575
|
+
const group = {
|
|
576
|
+
data,
|
|
577
|
+
changes: [
|
|
578
|
+
{
|
|
579
|
+
type: "atom",
|
|
580
|
+
kind: "unset",
|
|
581
|
+
state: atom,
|
|
582
|
+
value: revertedValue,
|
|
583
|
+
scope: scopePath(data)
|
|
584
|
+
}
|
|
585
|
+
]
|
|
586
|
+
};
|
|
587
|
+
emitGroup(group, report);
|
|
588
|
+
};
|
|
589
|
+
var reportDeletedAtoms = (atoms, data, report, changedSelectors) => {
|
|
590
|
+
if (!hasChangeListener(data))
|
|
591
|
+
return;
|
|
592
|
+
const selectors = changedSelectors && changedSelectors.size > 0 && hasSelectorChangeListener(data) ? changedSelectors : undefined;
|
|
593
|
+
emitGroup(buildChangeGroup(data, undefined, atoms, selectors), report);
|
|
594
|
+
};
|
|
595
|
+
var reportSelectorChanges = (changedSelectors, data, report) => {
|
|
596
|
+
if (changedSelectors.size === 0)
|
|
597
|
+
return;
|
|
598
|
+
if (!hasSelectorChangeListener(data))
|
|
599
|
+
return;
|
|
600
|
+
emitGroup(buildChangeGroup(data, undefined, undefined, changedSelectors), report);
|
|
601
|
+
};
|
|
602
|
+
var createChangeSink = (name, source = "transaction") => ({
|
|
603
|
+
source,
|
|
604
|
+
name,
|
|
605
|
+
groups: []
|
|
606
|
+
});
|
|
607
|
+
var flushChangeSink = (sink) => {
|
|
608
|
+
if (sink.groups.length > 0) {
|
|
609
|
+
notifyChangeListeners(sink.groups, { source: sink.source, name: sink.name });
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
406
613
|
// src/lib/initSelector.ts
|
|
407
614
|
var neverAbortedSignal = new AbortController().signal;
|
|
408
615
|
var syncOptionsCache = new WeakMap;
|
|
@@ -549,7 +756,7 @@ var handleSelectorResult = (value, selector, data) => {
|
|
|
549
756
|
const initializedAtomsSet = new Set;
|
|
550
757
|
const res = initSelector(selector, data, initializedAtomsSet);
|
|
551
758
|
if (initializedAtomsSet.size > 0) {
|
|
552
|
-
propagateAtomUpdate([...initializedAtomsSet], data);
|
|
759
|
+
propagateAtomUpdate([...initializedAtomsSet], data, false, undefined, "async-set");
|
|
553
760
|
}
|
|
554
761
|
return res;
|
|
555
762
|
}).catch(() => {
|
|
@@ -590,7 +797,12 @@ var handleSelectorResult = (value, selector, data) => {
|
|
|
590
797
|
const dependents = data.stateDependents.get(selector);
|
|
591
798
|
const subs = data.subscriptions.get(selector);
|
|
592
799
|
if (subs && subs.size > 0 || dependents && dependents.size > 0) {
|
|
593
|
-
|
|
800
|
+
const changedSelectors = changeListenerRegistry.selectorCount !== 0 && hasSelectorChangeListener(data) ? new Set : undefined;
|
|
801
|
+
propagateDirtySelectors([], new Set(dependents), data, new Set(subs), new Map, false, undefined, changedSelectors);
|
|
802
|
+
if (changedSelectors) {
|
|
803
|
+
changedSelectors.add(selector);
|
|
804
|
+
reportSelectorChanges(changedSelectors, data, "async-set");
|
|
805
|
+
}
|
|
594
806
|
}
|
|
595
807
|
}).catch(() => {
|
|
596
808
|
pendingAsyncDeps.delete(value);
|
|
@@ -628,6 +840,14 @@ var evaluate = (selector, data, initializedAtomsSet, circularDependencySet) => {
|
|
|
628
840
|
};
|
|
629
841
|
|
|
630
842
|
// src/lib/propagateUpdatedAtoms.ts
|
|
843
|
+
var notifyEntryFor = (notify, data) => {
|
|
844
|
+
let entry = notify.get(data);
|
|
845
|
+
if (entry === undefined) {
|
|
846
|
+
entry = { subscriptions: new Set, families: new Map };
|
|
847
|
+
notify.set(data, entry);
|
|
848
|
+
}
|
|
849
|
+
return entry;
|
|
850
|
+
};
|
|
631
851
|
var reEvaluateSelector = (selector, data, updatedAtoms, depsChange, existingValue) => {
|
|
632
852
|
try {
|
|
633
853
|
const rawValue = evaluateSelector(selector, data, updatedAtoms, undefined, depsChange);
|
|
@@ -674,6 +894,35 @@ var callSubscribers = (subscriptions, families) => {
|
|
|
674
894
|
if (hasError)
|
|
675
895
|
throw firstError;
|
|
676
896
|
};
|
|
897
|
+
var notifyDeferred = (notify) => {
|
|
898
|
+
let firstError;
|
|
899
|
+
let hasError = false;
|
|
900
|
+
for (const entry of notify.values()) {
|
|
901
|
+
if (entry.subscriptions.size > 0) {
|
|
902
|
+
try {
|
|
903
|
+
callSubscribers(entry.subscriptions, entry.families);
|
|
904
|
+
} catch (error) {
|
|
905
|
+
if (!hasError) {
|
|
906
|
+
firstError = error;
|
|
907
|
+
hasError = true;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
if (hasError)
|
|
913
|
+
throw firstError;
|
|
914
|
+
};
|
|
915
|
+
var collectFamilyAtomsForNotify = (entry, changedByFamily) => {
|
|
916
|
+
for (const [family, atoms] of changedByFamily) {
|
|
917
|
+
let target = entry.families.get(family);
|
|
918
|
+
if (target === undefined) {
|
|
919
|
+
target = new Set;
|
|
920
|
+
entry.families.set(family, target);
|
|
921
|
+
}
|
|
922
|
+
for (const atom of atoms)
|
|
923
|
+
target.add(atom);
|
|
924
|
+
}
|
|
925
|
+
};
|
|
677
926
|
var addSetToSet = (fromSet, toSet) => {
|
|
678
927
|
if (fromSet && fromSet.size > 0) {
|
|
679
928
|
for (const item of fromSet) {
|
|
@@ -681,20 +930,24 @@ var addSetToSet = (fromSet, toSet) => {
|
|
|
681
930
|
}
|
|
682
931
|
}
|
|
683
932
|
};
|
|
684
|
-
var propagateDeletedAtoms = (atoms, data, subscriptions = new Set,
|
|
933
|
+
var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, deletedFamilyAtoms = new Map, timestamp = performance.now(), notify, report) => {
|
|
934
|
+
const notifyEntry = notify ? notifyEntryFor(notify, data) : undefined;
|
|
935
|
+
if (notifyEntry) {
|
|
936
|
+
subscriptions = notifyEntry.subscriptions;
|
|
937
|
+
}
|
|
685
938
|
const selectors = new Set;
|
|
686
939
|
for (const atom of atoms) {
|
|
687
940
|
addSetToSet(data.stateDependents.get(atom), selectors);
|
|
688
941
|
addSetToSet(data.subscriptions.get(atom), subscriptions);
|
|
689
942
|
if (isFamilyAtom(atom)) {
|
|
690
|
-
if (!
|
|
691
|
-
|
|
943
|
+
if (!deletedFamilyAtoms.has(atom.family)) {
|
|
944
|
+
deletedFamilyAtoms.set(atom.family, new Set);
|
|
692
945
|
}
|
|
693
|
-
|
|
946
|
+
deletedFamilyAtoms.get(atom.family).add(atom);
|
|
694
947
|
}
|
|
695
948
|
}
|
|
696
|
-
if (
|
|
697
|
-
for (const [family, familyAtoms] of
|
|
949
|
+
if (deletedFamilyAtoms.size > 0) {
|
|
950
|
+
for (const [family, familyAtoms] of deletedFamilyAtoms) {
|
|
698
951
|
addSetToSet(data.stateDependents.get(family), selectors);
|
|
699
952
|
addSetToSet(data.subscriptions.get(family), subscriptions);
|
|
700
953
|
if (familyAtoms.size === 0)
|
|
@@ -702,28 +955,35 @@ var propagateDeletedAtoms = (atoms, data, subscriptions = new Set, families = ne
|
|
|
702
955
|
deleteFamilyAtomsFromSet(family, familyAtoms, data, timestamp);
|
|
703
956
|
}
|
|
704
957
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}
|
|
726
|
-
|
|
958
|
+
const selectorActive = report !== undefined && changeListenerRegistry.selectorCount !== 0 && hasSelectorChangeListener(data);
|
|
959
|
+
const changedSelectors = selectorActive ? new Set : undefined;
|
|
960
|
+
propagateDirtySelectors(atoms, selectors, data, subscriptions, deletedFamilyAtoms, false, notify, changedSelectors);
|
|
961
|
+
if (notifyEntry)
|
|
962
|
+
collectFamilyAtomsForNotify(notifyEntry, deletedFamilyAtoms);
|
|
963
|
+
const hasScopeCascade = !!data.scopes && data.scopes.size > 0;
|
|
964
|
+
const watching = report !== undefined && changeListenerRegistry.count !== 0;
|
|
965
|
+
let localSink;
|
|
966
|
+
let effectiveReport = report;
|
|
967
|
+
if (selectorActive && hasScopeCascade && typeof report === "string") {
|
|
968
|
+
localSink = createChangeSink(undefined, report);
|
|
969
|
+
effectiveReport = localSink;
|
|
970
|
+
}
|
|
971
|
+
const reportIsSink = effectiveReport !== undefined && typeof effectiveReport !== "string";
|
|
972
|
+
if (watching && reportIsSink)
|
|
973
|
+
reportDeletedAtoms(atoms, data, effectiveReport, changedSelectors);
|
|
974
|
+
if (hasScopeCascade) {
|
|
975
|
+
const scopeAtoms = atoms.slice();
|
|
976
|
+
for (const family of deletedFamilyAtoms.keys()) {
|
|
977
|
+
scopeAtoms.push(family);
|
|
978
|
+
}
|
|
979
|
+
propagateToScopes(scopeAtoms, data, false, notify, effectiveReport);
|
|
980
|
+
}
|
|
981
|
+
if (watching && !reportIsSink)
|
|
982
|
+
reportDeletedAtoms(atoms, data, effectiveReport, changedSelectors);
|
|
983
|
+
if (localSink)
|
|
984
|
+
flushChangeSink(localSink);
|
|
985
|
+
};
|
|
986
|
+
var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify, report, skipFamilyIndexUpdate = false, reportAtoms = true) => {
|
|
727
987
|
if (atoms.length === 1) {
|
|
728
988
|
const atom = atoms[0];
|
|
729
989
|
if (!isFamilyAtom(atom) && !isAtomFamily(atom)) {
|
|
@@ -731,28 +991,35 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, evaluatedSelectors)
|
|
|
731
991
|
if ((!dependents || dependents.size === 0) && (!data.scopes || data.scopes.size === 0)) {
|
|
732
992
|
const subs = data.subscriptions.get(atom);
|
|
733
993
|
if (subs && subs.size > 0) {
|
|
734
|
-
|
|
994
|
+
if (notify)
|
|
995
|
+
addSetToSet(subs, notifyEntryFor(notify, data).subscriptions);
|
|
996
|
+
else
|
|
997
|
+
callSubscribers(subs);
|
|
998
|
+
}
|
|
999
|
+
if (reportAtoms && report !== undefined && changeListenerRegistry.count !== 0 && !isInitOnly) {
|
|
1000
|
+
reportAtomChanges(atoms, data, report);
|
|
735
1001
|
}
|
|
736
1002
|
return;
|
|
737
1003
|
}
|
|
738
1004
|
}
|
|
739
1005
|
}
|
|
740
|
-
const
|
|
741
|
-
const
|
|
1006
|
+
const notifyEntry = notify ? notifyEntryFor(notify, data) : undefined;
|
|
1007
|
+
const subscriptions = notifyEntry ? notifyEntry.subscriptions : new Set;
|
|
1008
|
+
const updatedFamilyAtoms = new Map;
|
|
742
1009
|
const selectors = new Set;
|
|
743
1010
|
for (const atom of atoms) {
|
|
744
1011
|
addSetToSet(data.stateDependents.get(atom), selectors);
|
|
745
1012
|
addSetToSet(data.subscriptions.get(atom), subscriptions);
|
|
746
|
-
if (isFamilyAtom(atom)) {
|
|
747
|
-
if (!
|
|
748
|
-
|
|
1013
|
+
if (isFamilyAtom(atom) && !skipFamilyIndexUpdate) {
|
|
1014
|
+
if (!updatedFamilyAtoms.has(atom.family)) {
|
|
1015
|
+
updatedFamilyAtoms.set(atom.family, new Set);
|
|
749
1016
|
}
|
|
750
|
-
|
|
1017
|
+
updatedFamilyAtoms.get(atom.family).add(atom);
|
|
751
1018
|
}
|
|
752
1019
|
}
|
|
753
|
-
if (
|
|
1020
|
+
if (updatedFamilyAtoms.size > 0) {
|
|
754
1021
|
const timestamp = performance.now();
|
|
755
|
-
for (const [family, familyAtoms] of
|
|
1022
|
+
for (const [family, familyAtoms] of updatedFamilyAtoms) {
|
|
756
1023
|
addSetToSet(data.stateDependents.get(family), selectors);
|
|
757
1024
|
addSetToSet(data.subscriptions.get(family), subscriptions);
|
|
758
1025
|
if (familyAtoms.size === 0)
|
|
@@ -762,35 +1029,65 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, evaluatedSelectors)
|
|
|
762
1029
|
}
|
|
763
1030
|
if (data.scopes && data.scopes.size > 0) {
|
|
764
1031
|
for (const atom of atoms) {
|
|
765
|
-
if (isAtomFamily(atom) && !
|
|
1032
|
+
if (isAtomFamily(atom) && !updatedFamilyAtoms.has(atom)) {
|
|
766
1033
|
recursivelyUpdateIndexes(data, atom);
|
|
767
1034
|
}
|
|
768
1035
|
}
|
|
769
1036
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
1037
|
+
const selectorActive = report !== undefined && !isInitOnly && changeListenerRegistry.selectorCount !== 0 && hasSelectorChangeListener(data);
|
|
1038
|
+
const changedSelectors = selectorActive ? new Set : undefined;
|
|
1039
|
+
propagateDirtySelectors(atoms, selectors, data, subscriptions, updatedFamilyAtoms, isInitOnly, notify, changedSelectors);
|
|
1040
|
+
if (notifyEntry)
|
|
1041
|
+
collectFamilyAtomsForNotify(notifyEntry, updatedFamilyAtoms);
|
|
1042
|
+
const hasScopes = !!data.scopes && data.scopes.size > 0;
|
|
1043
|
+
const watching = report !== undefined && changeListenerRegistry.count !== 0 && !isInitOnly;
|
|
1044
|
+
let localSink;
|
|
1045
|
+
let effectiveReport = report;
|
|
1046
|
+
if (selectorActive && hasScopes && typeof report === "string") {
|
|
1047
|
+
localSink = createChangeSink(undefined, report);
|
|
1048
|
+
effectiveReport = localSink;
|
|
773
1049
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
1050
|
+
const reportIsSink = effectiveReport !== undefined && typeof effectiveReport !== "string";
|
|
1051
|
+
const emitOrigin = (rpt) => {
|
|
1052
|
+
if (reportAtoms) {
|
|
1053
|
+
reportAtomChanges(atoms, data, rpt, changedSelectors);
|
|
1054
|
+
} else if (changedSelectors && changedSelectors.size > 0) {
|
|
1055
|
+
reportSelectorChanges(changedSelectors, data, rpt);
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
if (watching && reportIsSink)
|
|
1059
|
+
emitOrigin(effectiveReport);
|
|
1060
|
+
if (hasScopes) {
|
|
1061
|
+
propagateToScopes(atoms, data, isInitOnly, notify, effectiveReport);
|
|
1062
|
+
}
|
|
1063
|
+
if (watching && !reportIsSink)
|
|
1064
|
+
emitOrigin(effectiveReport);
|
|
1065
|
+
if (localSink)
|
|
1066
|
+
flushChangeSink(localSink);
|
|
1067
|
+
};
|
|
1068
|
+
var propagateInScope = (atoms, data, isInitOnly = false, notify, report) => {
|
|
1069
|
+
const subscriptions = notify ? notifyEntryFor(notify, data).subscriptions : new Set;
|
|
777
1070
|
const families = new Map;
|
|
778
1071
|
const selectors = new Set;
|
|
779
1072
|
for (const atom of atoms) {
|
|
780
1073
|
addSetToSet(data.stateDependents.get(atom), selectors);
|
|
781
1074
|
}
|
|
782
|
-
|
|
1075
|
+
const changedSelectors = report !== undefined && !isInitOnly && changeListenerRegistry.selectorCount !== 0 && hasSelectorChangeListener(data) ? new Set : undefined;
|
|
1076
|
+
propagateDirtySelectors(atoms, selectors, data, subscriptions, families, isInitOnly, notify, changedSelectors);
|
|
1077
|
+
if (changedSelectors && changedSelectors.size > 0) {
|
|
1078
|
+
reportSelectorChanges(changedSelectors, data, report);
|
|
1079
|
+
}
|
|
783
1080
|
if (data.scopes && data.scopes.size > 0) {
|
|
784
|
-
propagateToScopes(atoms, data, isInitOnly,
|
|
1081
|
+
propagateToScopes(atoms, data, isInitOnly, notify, report);
|
|
785
1082
|
}
|
|
786
1083
|
};
|
|
787
|
-
var propagateToScopes = (atoms, data, isInitOnly,
|
|
1084
|
+
var propagateToScopes = (atoms, data, isInitOnly, notify, report) => {
|
|
788
1085
|
if (atoms.length === 1) {
|
|
789
1086
|
const atom = atoms[0];
|
|
790
1087
|
const shadowingScopes = isAtomFamily(atom) ? undefined : data.scopeValueIndex.get(atom);
|
|
791
1088
|
for (const [, scope] of data.scopes) {
|
|
792
1089
|
if (!shadowingScopes || !shadowingScopes.has(scope)) {
|
|
793
|
-
propagateInScope(atoms, scope, isInitOnly,
|
|
1090
|
+
propagateInScope(atoms, scope, isInitOnly, notify, report);
|
|
794
1091
|
}
|
|
795
1092
|
}
|
|
796
1093
|
return;
|
|
@@ -810,7 +1107,7 @@ var propagateToScopes = (atoms, data, isInitOnly, evaluatedSelectors) => {
|
|
|
810
1107
|
}
|
|
811
1108
|
if (!anyShadowed) {
|
|
812
1109
|
for (const [, scope] of data.scopes) {
|
|
813
|
-
propagateInScope(atoms, scope, isInitOnly,
|
|
1110
|
+
propagateInScope(atoms, scope, isInitOnly, notify, report);
|
|
814
1111
|
}
|
|
815
1112
|
return;
|
|
816
1113
|
}
|
|
@@ -827,20 +1124,20 @@ var propagateToScopes = (atoms, data, isInitOnly, evaluatedSelectors) => {
|
|
|
827
1124
|
}
|
|
828
1125
|
}
|
|
829
1126
|
if (atomsToUpdateInScope.length > 0) {
|
|
830
|
-
propagateInScope(atomsToUpdateInScope, scope, isInitOnly,
|
|
1127
|
+
propagateInScope(atomsToUpdateInScope, scope, isInitOnly, notify, report);
|
|
831
1128
|
}
|
|
832
1129
|
}
|
|
833
1130
|
};
|
|
834
|
-
var propagateDirtySelectors = (updatedAtoms, selectors, data, subscriptions, families, isInitOnly = false,
|
|
1131
|
+
var propagateDirtySelectors = (updatedAtoms, selectors, data, subscriptions, families, isInitOnly = false, notify, changedSelectors) => {
|
|
835
1132
|
const updatedInitializedAtoms = new Set(updatedAtoms);
|
|
836
1133
|
if (selectors.size > 0) {
|
|
837
|
-
propagateSelectorUpdates(selectors, data, subscriptions, updatedInitializedAtoms, isInitOnly,
|
|
1134
|
+
propagateSelectorUpdates(selectors, data, subscriptions, updatedInitializedAtoms, isInitOnly, changedSelectors);
|
|
838
1135
|
}
|
|
839
|
-
if (subscriptions.size > 0) {
|
|
1136
|
+
if (!notify && subscriptions.size > 0) {
|
|
840
1137
|
callSubscribers(subscriptions, families);
|
|
841
1138
|
}
|
|
842
1139
|
};
|
|
843
|
-
var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly,
|
|
1140
|
+
var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly, changedSelectors) => {
|
|
844
1141
|
const closure = new Set(seeds);
|
|
845
1142
|
{
|
|
846
1143
|
const stack = [...seeds];
|
|
@@ -901,10 +1198,6 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
901
1198
|
let head = 0;
|
|
902
1199
|
while (head < ready.length) {
|
|
903
1200
|
const selector = ready[head++];
|
|
904
|
-
if (evaluatedSelectors !== undefined && evaluatedSelectors.has(selector)) {
|
|
905
|
-
advance(selector, false);
|
|
906
|
-
continue;
|
|
907
|
-
}
|
|
908
1201
|
const currentValue = data.values.get(selector);
|
|
909
1202
|
if (isPromiseLike(currentValue) && isInitOnly) {
|
|
910
1203
|
advance(selector, false);
|
|
@@ -924,8 +1217,6 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
924
1217
|
depsChange.added = undefined;
|
|
925
1218
|
depsChange.removed = undefined;
|
|
926
1219
|
const wasValueUpdated = reEvaluateSelector(selector, data, updatedInitializedAtoms, depsChange, currentValue);
|
|
927
|
-
if (evaluatedSelectors !== undefined)
|
|
928
|
-
evaluatedSelectors.add(selector);
|
|
929
1220
|
const added = depsChange.added;
|
|
930
1221
|
const removed = depsChange.removed;
|
|
931
1222
|
if (added || removed) {
|
|
@@ -946,8 +1237,11 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
946
1237
|
}
|
|
947
1238
|
}
|
|
948
1239
|
advance(selector, wasValueUpdated);
|
|
949
|
-
if (wasValueUpdated
|
|
950
|
-
|
|
1240
|
+
if (wasValueUpdated) {
|
|
1241
|
+
if (changedSelectors)
|
|
1242
|
+
changedSelectors.add(selector);
|
|
1243
|
+
if (subscribers)
|
|
1244
|
+
addSetToSet(subscribers, collectedSubscribers);
|
|
951
1245
|
}
|
|
952
1246
|
}
|
|
953
1247
|
if (!graphMutated)
|
|
@@ -978,8 +1272,6 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
978
1272
|
depsChange.added = undefined;
|
|
979
1273
|
depsChange.removed = undefined;
|
|
980
1274
|
const wasValueUpdated = reEvaluateSelector(selector, data, updatedInitializedAtoms, depsChange, currentValue);
|
|
981
|
-
if (evaluatedSelectors !== undefined)
|
|
982
|
-
evaluatedSelectors.add(selector);
|
|
983
1275
|
const added = depsChange.added;
|
|
984
1276
|
const removed = depsChange.removed;
|
|
985
1277
|
if ((added || removed) && isLive(selector, data)) {
|
|
@@ -997,6 +1289,8 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
997
1289
|
}
|
|
998
1290
|
}
|
|
999
1291
|
if (wasValueUpdated) {
|
|
1292
|
+
if (changedSelectors)
|
|
1293
|
+
changedSelectors.add(selector);
|
|
1000
1294
|
if (subscribers)
|
|
1001
1295
|
addSetToSet(subscribers, collectedSubscribers);
|
|
1002
1296
|
const downstream = data.stateDependents.get(selector);
|
|
@@ -1009,15 +1303,12 @@ var propagateDownstreamTopo = (seeds, data, collectedSubscribers, updatedInitial
|
|
|
1009
1303
|
work = next;
|
|
1010
1304
|
}
|
|
1011
1305
|
};
|
|
1012
|
-
var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly = false,
|
|
1306
|
+
var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly = false, changedSelectors) => {
|
|
1013
1307
|
if (selectors.size === 0)
|
|
1014
1308
|
return;
|
|
1015
1309
|
let downstreamSeeds;
|
|
1016
1310
|
const depsChange = {};
|
|
1017
1311
|
for (const selector of selectors) {
|
|
1018
|
-
if (evaluatedSelectors !== undefined && evaluatedSelectors.has(selector)) {
|
|
1019
|
-
continue;
|
|
1020
|
-
}
|
|
1021
1312
|
const currentValue = data.values.get(selector);
|
|
1022
1313
|
if (isPromiseLike(currentValue) && isInitOnly)
|
|
1023
1314
|
continue;
|
|
@@ -1030,8 +1321,6 @@ var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedIn
|
|
|
1030
1321
|
depsChange.added = undefined;
|
|
1031
1322
|
depsChange.removed = undefined;
|
|
1032
1323
|
const wasValueUpdated = reEvaluateSelector(selector, data, updatedInitializedAtoms, depsChange, currentValue);
|
|
1033
|
-
if (evaluatedSelectors !== undefined)
|
|
1034
|
-
evaluatedSelectors.add(selector);
|
|
1035
1324
|
const added = depsChange.added;
|
|
1036
1325
|
const removed = depsChange.removed;
|
|
1037
1326
|
if ((added || removed) && isLive(selector, data)) {
|
|
@@ -1050,6 +1339,8 @@ var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedIn
|
|
|
1050
1339
|
}
|
|
1051
1340
|
if (!wasValueUpdated)
|
|
1052
1341
|
continue;
|
|
1342
|
+
if (changedSelectors)
|
|
1343
|
+
changedSelectors.add(selector);
|
|
1053
1344
|
if (subscribers)
|
|
1054
1345
|
addSetToSet(subscribers, collectedSubscribers);
|
|
1055
1346
|
const downstream = data.stateDependents.get(selector);
|
|
@@ -1061,14 +1352,14 @@ var propagateSelectorUpdates = (selectors, data, collectedSubscribers, updatedIn
|
|
|
1061
1352
|
}
|
|
1062
1353
|
}
|
|
1063
1354
|
if (downstreamSeeds && downstreamSeeds.size > 0) {
|
|
1064
|
-
propagateDownstreamTopo(downstreamSeeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly,
|
|
1355
|
+
propagateDownstreamTopo(downstreamSeeds, data, collectedSubscribers, updatedInitializedAtoms, isInitOnly, changedSelectors);
|
|
1065
1356
|
}
|
|
1066
1357
|
};
|
|
1067
1358
|
|
|
1068
1359
|
// src/lib/isFunction.ts
|
|
1069
1360
|
var isFunction = (value) => typeof value === "function";
|
|
1070
1361
|
|
|
1071
|
-
// src/lib/
|
|
1362
|
+
// src/lib/resolvePendingDefault.ts
|
|
1072
1363
|
var resolvePendingDefault = (atom, data, value) => {
|
|
1073
1364
|
let cur = data;
|
|
1074
1365
|
while (cur) {
|
|
@@ -1081,6 +1372,8 @@ var resolvePendingDefault = (atom, data, value) => {
|
|
|
1081
1372
|
cur = "parent" in cur ? cur.parent : undefined;
|
|
1082
1373
|
}
|
|
1083
1374
|
};
|
|
1375
|
+
|
|
1376
|
+
// src/lib/setAtom.ts
|
|
1084
1377
|
var handlePromise = (atom, promise, currentValue, data, skipOnSet) => {
|
|
1085
1378
|
setValueInData(atom, promise, data);
|
|
1086
1379
|
promise.then((resolvedValue) => {
|
|
@@ -1090,12 +1383,12 @@ var handlePromise = (atom, promise, currentValue, data, skipOnSet) => {
|
|
|
1090
1383
|
if (atom.onSet && !skipOnSet)
|
|
1091
1384
|
atom.onSet(resolvedValue, data);
|
|
1092
1385
|
resolvePendingDefault(atom, data, resolvedValue);
|
|
1093
|
-
propagateAtomUpdate([atom], data);
|
|
1386
|
+
propagateAtomUpdate([atom], data, false, undefined, "async-set");
|
|
1094
1387
|
}).catch(() => {
|
|
1095
1388
|
if (data.values.get(atom) !== promise)
|
|
1096
1389
|
return;
|
|
1097
1390
|
setValueInData(atom, currentValue, data);
|
|
1098
|
-
propagateAtomUpdate([atom], data);
|
|
1391
|
+
propagateAtomUpdate([atom], data, false, undefined, "async-set");
|
|
1099
1392
|
});
|
|
1100
1393
|
};
|
|
1101
1394
|
var setAtom = (atom, newValue, data, skipOnSet = false) => {
|
|
@@ -1117,9 +1410,9 @@ var setAtom = (atom, newValue, data, skipOnSet = false) => {
|
|
|
1117
1410
|
handlePromise(atom, promise, currentValue, data, skipOnSet);
|
|
1118
1411
|
if (initializedAtomsSet && initializedAtomsSet.size > 0) {
|
|
1119
1412
|
initializedAtomsSet.add(atom);
|
|
1120
|
-
propagateAtomUpdate([...initializedAtomsSet], data);
|
|
1413
|
+
propagateAtomUpdate([...initializedAtomsSet], data, false, undefined, "set");
|
|
1121
1414
|
} else {
|
|
1122
|
-
propagateAtomUpdate([atom], data);
|
|
1415
|
+
propagateAtomUpdate([atom], data, false, undefined, "set");
|
|
1123
1416
|
}
|
|
1124
1417
|
return promise;
|
|
1125
1418
|
}
|
|
@@ -1133,9 +1426,9 @@ var setAtom = (atom, newValue, data, skipOnSet = false) => {
|
|
|
1133
1426
|
resolvePendingDefault(atom, data, syncValue);
|
|
1134
1427
|
if (initializedAtomsSet && initializedAtomsSet.size > 0) {
|
|
1135
1428
|
initializedAtomsSet.add(atom);
|
|
1136
|
-
propagateAtomUpdate([...initializedAtomsSet], data);
|
|
1429
|
+
propagateAtomUpdate([...initializedAtomsSet], data, false, undefined, "set");
|
|
1137
1430
|
} else {
|
|
1138
|
-
propagateAtomUpdate([atom], data);
|
|
1431
|
+
propagateAtomUpdate([atom], data, false, undefined, "set");
|
|
1139
1432
|
}
|
|
1140
1433
|
return syncValue;
|
|
1141
1434
|
};
|
|
@@ -1156,7 +1449,7 @@ var getAtomInitValue = (atom, data, initializedAtomsSet) => {
|
|
|
1156
1449
|
if (data.values.get(atom) !== value)
|
|
1157
1450
|
return;
|
|
1158
1451
|
setValueInData(atom, resolvedValue, data);
|
|
1159
|
-
propagateAtomUpdate([atom], data);
|
|
1452
|
+
propagateAtomUpdate([atom], data, false, undefined, "async-set");
|
|
1160
1453
|
}, () => {
|
|
1161
1454
|
if (data.values.get(atom) === value) {
|
|
1162
1455
|
data.values.delete(atom);
|
|
@@ -1180,6 +1473,23 @@ var initAtom = (atom, data, initializedAtomsSet) => {
|
|
|
1180
1473
|
}, data);
|
|
1181
1474
|
};
|
|
1182
1475
|
|
|
1476
|
+
// src/lib/resolveAtomDefaultValue.ts
|
|
1477
|
+
var resolveAtomDefaultValue = (atom, data, initializedAtomsSet) => {
|
|
1478
|
+
if (atom.defaultValue === undefined) {
|
|
1479
|
+
let resolve;
|
|
1480
|
+
const promise = new Promise((r) => {
|
|
1481
|
+
resolve = r;
|
|
1482
|
+
});
|
|
1483
|
+
data.pendingDefaults.set(atom, { promise, resolve });
|
|
1484
|
+
return promise;
|
|
1485
|
+
} else if (typeof atom.defaultValue === "function") {
|
|
1486
|
+
return atom.defaultValue();
|
|
1487
|
+
} else if (isSelector(atom.defaultValue)) {
|
|
1488
|
+
return getState(atom.defaultValue, data, initializedAtomsSet);
|
|
1489
|
+
}
|
|
1490
|
+
return atom.defaultValue;
|
|
1491
|
+
};
|
|
1492
|
+
|
|
1183
1493
|
// src/lib/getState.ts
|
|
1184
1494
|
function getState(state, data, initializedAtomsSet, circularDependencySet) {
|
|
1185
1495
|
if (data.values.has(state))
|
|
@@ -1191,7 +1501,21 @@ function getState(state, data, initializedAtomsSet, circularDependencySet) {
|
|
|
1191
1501
|
const familyValue = data.values.get(state.family);
|
|
1192
1502
|
if (familyValue?.__index) {
|
|
1193
1503
|
if (isAtomDeletedInFamilyIndex(state, familyValue.__index)) {
|
|
1194
|
-
|
|
1504
|
+
const value = resolveAtomDefaultValue(state, data, initializedAtomsSet);
|
|
1505
|
+
const cached = setValueInData(state, value, data);
|
|
1506
|
+
if (isPromiseLike(cached)) {
|
|
1507
|
+
cached.then((resolvedValue) => {
|
|
1508
|
+
if (data.values.get(state) !== cached)
|
|
1509
|
+
return;
|
|
1510
|
+
setValueInData(state, resolvedValue, data);
|
|
1511
|
+
propagateAtomUpdate([state], data, false, undefined, undefined, true);
|
|
1512
|
+
}, () => {
|
|
1513
|
+
if (data.values.get(state) === cached) {
|
|
1514
|
+
data.values.delete(state);
|
|
1515
|
+
}
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
return cached;
|
|
1195
1519
|
}
|
|
1196
1520
|
}
|
|
1197
1521
|
}
|
|
@@ -1249,6 +1573,63 @@ var resolveReactive = (value, data) => {
|
|
|
1249
1573
|
return value;
|
|
1250
1574
|
};
|
|
1251
1575
|
|
|
1576
|
+
// src/lib/unsetValue.ts
|
|
1577
|
+
var InvalidStateError = "unset() expects an atom.";
|
|
1578
|
+
var detachOwnValue = (atom, data) => {
|
|
1579
|
+
if (!data.values.has(atom))
|
|
1580
|
+
return false;
|
|
1581
|
+
data.values.delete(atom);
|
|
1582
|
+
if (atom.maxAge !== undefined)
|
|
1583
|
+
data.lastValueWriteAt.delete(atom);
|
|
1584
|
+
const parent = data.parent;
|
|
1585
|
+
if (parent) {
|
|
1586
|
+
const scopes = parent.scopeValueIndex.get(atom);
|
|
1587
|
+
if (scopes) {
|
|
1588
|
+
scopes.delete(data);
|
|
1589
|
+
if (scopes.size === 0)
|
|
1590
|
+
parent.scopeValueIndex.delete(atom);
|
|
1591
|
+
}
|
|
1592
|
+
data.scopeIndexKeys.delete(atom);
|
|
1593
|
+
}
|
|
1594
|
+
return true;
|
|
1595
|
+
};
|
|
1596
|
+
var reDelegateScopeSubscriptions = (atom, data) => {
|
|
1597
|
+
const subs = data.subscriptions.get(atom);
|
|
1598
|
+
if (subs) {
|
|
1599
|
+
for (const sub of subs)
|
|
1600
|
+
sub.reDelegate?.();
|
|
1601
|
+
}
|
|
1602
|
+
};
|
|
1603
|
+
var effectiveValueAfterUnset = (atom, data) => {
|
|
1604
|
+
const parent = data.parent;
|
|
1605
|
+
if (parent) {
|
|
1606
|
+
const initSet = new Set;
|
|
1607
|
+
const value = getState(atom, parent, initSet);
|
|
1608
|
+
if (initSet.size > 0)
|
|
1609
|
+
propagateAtomUpdate([...initSet], parent, true);
|
|
1610
|
+
return value;
|
|
1611
|
+
}
|
|
1612
|
+
if (data.values.has(atom))
|
|
1613
|
+
return data.values.get(atom);
|
|
1614
|
+
return getAtomInitValue(atom, data, new Set);
|
|
1615
|
+
};
|
|
1616
|
+
var unsetValue = (atom, data) => {
|
|
1617
|
+
if (!isAtom(atom))
|
|
1618
|
+
throw new Error(InvalidStateError);
|
|
1619
|
+
if (!detachOwnValue(atom, data))
|
|
1620
|
+
return;
|
|
1621
|
+
if (hasChangeListener(data)) {
|
|
1622
|
+
const sink = createChangeSink(undefined, "unset");
|
|
1623
|
+
reportUnsetAtom(atom, data, effectiveValueAfterUnset(atom, data), sink);
|
|
1624
|
+
propagateAtomUpdate([atom], data, false, undefined, sink, false, false);
|
|
1625
|
+
reDelegateScopeSubscriptions(atom, data);
|
|
1626
|
+
flushChangeSink(sink);
|
|
1627
|
+
} else {
|
|
1628
|
+
propagateAtomUpdate([atom], data, false);
|
|
1629
|
+
reDelegateScopeSubscriptions(atom, data);
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
|
|
1252
1633
|
// src/lib/createStoreData.ts
|
|
1253
1634
|
var nextId = 0;
|
|
1254
1635
|
var generateId = () => "__valdres_store_" + nextId++;
|
|
@@ -1282,7 +1663,10 @@ Object.defineProperties(lazyProto, {
|
|
|
1282
1663
|
function createStoreData(id, parent, options) {
|
|
1283
1664
|
const data = Object.create(lazyProto);
|
|
1284
1665
|
data.id = id ?? generateId();
|
|
1285
|
-
|
|
1666
|
+
const enumerable = options?.enumerable ?? parent?.enumerable ?? false;
|
|
1667
|
+
if (enumerable)
|
|
1668
|
+
data.enumerable = true;
|
|
1669
|
+
data.values = enumerable ? new Map : new WeakMap;
|
|
1286
1670
|
data.scopes = new Map;
|
|
1287
1671
|
data.scopeValueIndex = new WeakMap;
|
|
1288
1672
|
data.pendingDefaults = new WeakMap;
|
|
@@ -1303,7 +1687,42 @@ var deleteFamilyAtom = (atom, data) => {
|
|
|
1303
1687
|
if (atom.family) {
|
|
1304
1688
|
atom.family.release(...atom.familyArgs);
|
|
1305
1689
|
}
|
|
1306
|
-
propagateDeletedAtoms([atom], data);
|
|
1690
|
+
propagateDeletedAtoms([atom], data, undefined, undefined, undefined, undefined, "delete");
|
|
1691
|
+
};
|
|
1692
|
+
|
|
1693
|
+
// src/lib/onStoreChange.ts
|
|
1694
|
+
var onStoreChange = (callback, data, options) => {
|
|
1695
|
+
const atoms = options?.atoms ?? true;
|
|
1696
|
+
const selectors = options?.selectors ?? false;
|
|
1697
|
+
if (!atoms && !selectors)
|
|
1698
|
+
return () => {};
|
|
1699
|
+
let listeners = data.changeListeners;
|
|
1700
|
+
if (!listeners) {
|
|
1701
|
+
listeners = new Map;
|
|
1702
|
+
data.changeListeners = listeners;
|
|
1703
|
+
}
|
|
1704
|
+
const prev = listeners.get(callback);
|
|
1705
|
+
listeners.set(callback, { atoms, selectors });
|
|
1706
|
+
if (!prev)
|
|
1707
|
+
changeListenerRegistry.count++;
|
|
1708
|
+
const prevSelectors = prev?.selectors ?? false;
|
|
1709
|
+
if (selectors && !prevSelectors)
|
|
1710
|
+
changeListenerRegistry.selectorCount++;
|
|
1711
|
+
else if (!selectors && prevSelectors)
|
|
1712
|
+
changeListenerRegistry.selectorCount--;
|
|
1713
|
+
return () => {
|
|
1714
|
+
const current = data.changeListeners;
|
|
1715
|
+
if (!current)
|
|
1716
|
+
return;
|
|
1717
|
+
const flags = current.get(callback);
|
|
1718
|
+
if (flags && current.delete(callback)) {
|
|
1719
|
+
changeListenerRegistry.count--;
|
|
1720
|
+
if (flags.selectors)
|
|
1721
|
+
changeListenerRegistry.selectorCount--;
|
|
1722
|
+
if (current.size === 0)
|
|
1723
|
+
data.changeListeners = undefined;
|
|
1724
|
+
}
|
|
1725
|
+
};
|
|
1307
1726
|
};
|
|
1308
1727
|
|
|
1309
1728
|
// src/lib/resetAtom.ts
|
|
@@ -1312,7 +1731,7 @@ var resetAtom = (atom, data) => {
|
|
|
1312
1731
|
let value = getAtomInitValue(atom, data, initializedAtomsSet);
|
|
1313
1732
|
setValueInData(atom, value, data);
|
|
1314
1733
|
if (!isPromiseLike(value)) {
|
|
1315
|
-
propagateAtomUpdate([atom], data);
|
|
1734
|
+
propagateAtomUpdate([atom], data, false, undefined, "reset");
|
|
1316
1735
|
}
|
|
1317
1736
|
if (initializedAtomsSet.size > 0) {
|
|
1318
1737
|
throw new Error("Todo - propagateAtomUpdate on reset");
|
|
@@ -1320,6 +1739,38 @@ var resetAtom = (atom, data) => {
|
|
|
1320
1739
|
return value;
|
|
1321
1740
|
};
|
|
1322
1741
|
|
|
1742
|
+
// src/lib/snapshot.ts
|
|
1743
|
+
var warnedStores = new WeakSet;
|
|
1744
|
+
var collect = (data, scope, out) => {
|
|
1745
|
+
for (const [state, value] of data.values) {
|
|
1746
|
+
if (state.__valdresInternal)
|
|
1747
|
+
continue;
|
|
1748
|
+
if (isAtomFamily(state) || isSelectorFamily(state))
|
|
1749
|
+
continue;
|
|
1750
|
+
out.push({
|
|
1751
|
+
type: isSelector(state) ? "selector" : "atom",
|
|
1752
|
+
state,
|
|
1753
|
+
value,
|
|
1754
|
+
scope
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1757
|
+
for (const [id, scopeData] of data.scopes) {
|
|
1758
|
+
collect(scopeData, [...scope, id], out);
|
|
1759
|
+
}
|
|
1760
|
+
};
|
|
1761
|
+
var snapshot = (data) => {
|
|
1762
|
+
if (!data.enumerable) {
|
|
1763
|
+
if (!warnedStores.has(data)) {
|
|
1764
|
+
warnedStores.add(data);
|
|
1765
|
+
console.warn("store.snapshot() requires an enumerable store. Create it with " + "`store({ enumerable: true })` or `store(id, { enumerable: true })` " + "to retain state enumerably. Returning [].");
|
|
1766
|
+
}
|
|
1767
|
+
return [];
|
|
1768
|
+
}
|
|
1769
|
+
const out = [];
|
|
1770
|
+
collect(data, [], out);
|
|
1771
|
+
return out;
|
|
1772
|
+
};
|
|
1773
|
+
|
|
1323
1774
|
// src/utils/isFamily.ts
|
|
1324
1775
|
var isFamily = (state) => isAtomFamily(state) || isSelectorFamily(state);
|
|
1325
1776
|
|
|
@@ -1409,11 +1860,11 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1409
1860
|
const existing = globalState?.maxAgeInterval;
|
|
1410
1861
|
if (existing) {
|
|
1411
1862
|
existing.refCount++;
|
|
1412
|
-
const metaAtom2 = state.__cacheMeta ??= { equal, defaultValue: null };
|
|
1863
|
+
const metaAtom2 = state.__cacheMeta ??= { equal, defaultValue: null, __valdresInternal: true };
|
|
1413
1864
|
for (const s of globalState.stores) {
|
|
1414
1865
|
if (s !== data && s.values.has(metaAtom2)) {
|
|
1415
1866
|
setValueInData(metaAtom2, s.values.get(metaAtom2), data);
|
|
1416
|
-
propagateAtomUpdate([metaAtom2], data);
|
|
1867
|
+
propagateAtomUpdate([metaAtom2], data, false, undefined, "revalidate");
|
|
1417
1868
|
break;
|
|
1418
1869
|
}
|
|
1419
1870
|
}
|
|
@@ -1440,7 +1891,7 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1440
1891
|
const getMaxAge = () => resolveReactive(state.maxAge, data);
|
|
1441
1892
|
const getSWR = () => state.staleWhileRevalidate !== undefined ? resolveReactive(state.staleWhileRevalidate, data) : Infinity;
|
|
1442
1893
|
const getStaleIfError = () => state.staleIfError !== undefined ? resolveReactive(state.staleIfError, data) : Infinity;
|
|
1443
|
-
const metaAtom = state.__cacheMeta ??= { equal, defaultValue: null };
|
|
1894
|
+
const metaAtom = state.__cacheMeta ??= { equal, defaultValue: null, __valdresInternal: true };
|
|
1444
1895
|
const updateMeta = () => {
|
|
1445
1896
|
const meta = {
|
|
1446
1897
|
isRevalidating: revalidating,
|
|
@@ -1452,11 +1903,11 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1452
1903
|
if (globalState) {
|
|
1453
1904
|
for (const store of globalState.stores) {
|
|
1454
1905
|
setValueInData(metaAtom, meta, store);
|
|
1455
|
-
propagateAtomUpdate([metaAtom], store);
|
|
1906
|
+
propagateAtomUpdate([metaAtom], store, false, undefined, "revalidate");
|
|
1456
1907
|
}
|
|
1457
1908
|
} else {
|
|
1458
1909
|
setValueInData(metaAtom, meta, data);
|
|
1459
|
-
propagateAtomUpdate([metaAtom], data);
|
|
1910
|
+
propagateAtomUpdate([metaAtom], data, false, undefined, "revalidate");
|
|
1460
1911
|
}
|
|
1461
1912
|
};
|
|
1462
1913
|
const isPastStaleIfErrorWindow = () => {
|
|
@@ -1467,11 +1918,11 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1467
1918
|
if (globalState) {
|
|
1468
1919
|
for (const store of globalState.stores) {
|
|
1469
1920
|
setValueInData(atom, val, store);
|
|
1470
|
-
propagateAtomUpdate([atom], store);
|
|
1921
|
+
propagateAtomUpdate([atom], store, false, undefined, "revalidate");
|
|
1471
1922
|
}
|
|
1472
1923
|
} else {
|
|
1473
1924
|
setValueInData(atom, val, data);
|
|
1474
|
-
propagateAtomUpdate([atom], data);
|
|
1925
|
+
propagateAtomUpdate([atom], data, false, undefined, "revalidate");
|
|
1475
1926
|
}
|
|
1476
1927
|
};
|
|
1477
1928
|
const getValueStore = () => {
|
|
@@ -1602,15 +2053,24 @@ var installMaxAgeTimer = (state, data) => {
|
|
|
1602
2053
|
var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) => {
|
|
1603
2054
|
let parentUnsubscribe;
|
|
1604
2055
|
let dropDelegate;
|
|
1605
|
-
|
|
2056
|
+
let reDelegate;
|
|
2057
|
+
if (data.parent && (isAtom(state) || isAtomFamily(state))) {
|
|
1606
2058
|
const originalCallback = callback;
|
|
1607
|
-
|
|
2059
|
+
const delegateToParent = () => subscribe(state, originalCallback, requireDeepEqualCheckBeforeCallback, data.parent);
|
|
2060
|
+
if (isAtomFamily(state) || !data.values.has(state)) {
|
|
2061
|
+
parentUnsubscribe = delegateToParent();
|
|
2062
|
+
}
|
|
1608
2063
|
dropDelegate = () => {
|
|
1609
2064
|
if (parentUnsubscribe) {
|
|
1610
2065
|
parentUnsubscribe();
|
|
1611
2066
|
parentUnsubscribe = undefined;
|
|
1612
2067
|
}
|
|
1613
2068
|
};
|
|
2069
|
+
reDelegate = () => {
|
|
2070
|
+
if (!parentUnsubscribe) {
|
|
2071
|
+
parentUnsubscribe = delegateToParent();
|
|
2072
|
+
}
|
|
2073
|
+
};
|
|
1614
2074
|
callback = (arg) => {
|
|
1615
2075
|
dropDelegate();
|
|
1616
2076
|
originalCallback(arg);
|
|
@@ -1635,13 +2095,15 @@ var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) =>
|
|
|
1635
2095
|
callback,
|
|
1636
2096
|
state,
|
|
1637
2097
|
requireDeepEqualCheckBeforeCallback,
|
|
1638
|
-
reRoot: dropDelegate
|
|
2098
|
+
reRoot: dropDelegate,
|
|
2099
|
+
reDelegate
|
|
1639
2100
|
};
|
|
1640
2101
|
} else {
|
|
1641
2102
|
subscription = {
|
|
1642
2103
|
callback,
|
|
1643
2104
|
requireDeepEqualCheckBeforeCallback,
|
|
1644
|
-
reRoot: dropDelegate
|
|
2105
|
+
reRoot: dropDelegate,
|
|
2106
|
+
reDelegate
|
|
1645
2107
|
};
|
|
1646
2108
|
}
|
|
1647
2109
|
subscribers.add(subscription);
|
|
@@ -1670,7 +2132,8 @@ var writeAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false, onSetQueu
|
|
|
1670
2132
|
const updatedAtoms = [];
|
|
1671
2133
|
for (let [atom, value] of pairs) {
|
|
1672
2134
|
const currentValue = getState(atom, data, initializedAtomsSet);
|
|
1673
|
-
const
|
|
2135
|
+
const currentIsPromise = isPromiseLike(currentValue);
|
|
2136
|
+
const areEqual = currentIsPromise || isPromiseLike(value) ? currentValue === value : atom.equal(currentValue, value);
|
|
1674
2137
|
if (!areEqual) {
|
|
1675
2138
|
updatedAtoms.push(atom);
|
|
1676
2139
|
value = setValueInData(atom, value, data);
|
|
@@ -1680,6 +2143,9 @@ var writeAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false, onSetQueu
|
|
|
1680
2143
|
else
|
|
1681
2144
|
atom.onSet(value, data);
|
|
1682
2145
|
}
|
|
2146
|
+
if (currentIsPromise && !isPromiseLike(value)) {
|
|
2147
|
+
resolvePendingDefault(atom, data, value);
|
|
2148
|
+
}
|
|
1683
2149
|
} else {
|
|
1684
2150
|
setValueInData(atom, value, data);
|
|
1685
2151
|
}
|
|
@@ -1693,10 +2159,10 @@ var writeAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false, onSetQueu
|
|
|
1693
2159
|
};
|
|
1694
2160
|
|
|
1695
2161
|
// src/lib/setAtoms.ts
|
|
1696
|
-
var setAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false) => {
|
|
2162
|
+
var setAtoms = (pairs, data, initializedAtomsSet, skipOnSet = false, report) => {
|
|
1697
2163
|
const updatedAtoms = writeAtoms(pairs, data, initializedAtomsSet, skipOnSet);
|
|
1698
2164
|
if (updatedAtoms.length > 0) {
|
|
1699
|
-
propagateAtomUpdate(updatedAtoms, data);
|
|
2165
|
+
propagateAtomUpdate(updatedAtoms, data, false, undefined, report);
|
|
1700
2166
|
}
|
|
1701
2167
|
};
|
|
1702
2168
|
|
|
@@ -1711,9 +2177,11 @@ class Transaction {
|
|
|
1711
2177
|
data;
|
|
1712
2178
|
parentTransaction;
|
|
1713
2179
|
dirty;
|
|
2180
|
+
name;
|
|
1714
2181
|
_scopedTransactions;
|
|
1715
2182
|
_initializedAtomsSet;
|
|
1716
2183
|
_deleteSet;
|
|
2184
|
+
_unsetSet;
|
|
1717
2185
|
_selectorDependencies;
|
|
1718
2186
|
_selectorCache;
|
|
1719
2187
|
_atomMap;
|
|
@@ -1721,6 +2189,7 @@ class Transaction {
|
|
|
1721
2189
|
this.data = data;
|
|
1722
2190
|
this.parentTransaction = parentTransaction;
|
|
1723
2191
|
this.dirty = false;
|
|
2192
|
+
this.name = undefined;
|
|
1724
2193
|
this._atomMap = new Map;
|
|
1725
2194
|
if (childTransaction) {
|
|
1726
2195
|
this._scopedTransactions = new Map([
|
|
@@ -1731,6 +2200,9 @@ class Transaction {
|
|
|
1731
2200
|
hasTxnOrData = (state) => {
|
|
1732
2201
|
if (this._atomMap.has(state))
|
|
1733
2202
|
return true;
|
|
2203
|
+
if (this._unsetSet?.has(state)) {
|
|
2204
|
+
return this.parentTransaction ? this.parentTransaction.hasTxnOrData(state) : false;
|
|
2205
|
+
}
|
|
1734
2206
|
if (this.data.values.has(state))
|
|
1735
2207
|
return true;
|
|
1736
2208
|
if (this.parentTransaction)
|
|
@@ -1741,6 +2213,9 @@ class Transaction {
|
|
|
1741
2213
|
if (this._atomMap.has(state)) {
|
|
1742
2214
|
return this._atomMap.get(state);
|
|
1743
2215
|
}
|
|
2216
|
+
if (this._unsetSet?.has(state)) {
|
|
2217
|
+
return this.parentTransaction ? this.parentTransaction.valueFromTxnOrData(state) : undefined;
|
|
2218
|
+
}
|
|
1744
2219
|
if (this.data.values.has(state)) {
|
|
1745
2220
|
return this.data.values.get(state);
|
|
1746
2221
|
}
|
|
@@ -1753,6 +2228,9 @@ class Transaction {
|
|
|
1753
2228
|
if (this.hasTxnOrData(state)) {
|
|
1754
2229
|
return this.valueFromTxnOrData(state);
|
|
1755
2230
|
}
|
|
2231
|
+
if (this._unsetSet?.has(state)) {
|
|
2232
|
+
return this.data.parent ? getState(state, this.data.parent, this.initializedAtomsSet) : getAtomInitValue(state, this.data, this.initializedAtomsSet);
|
|
2233
|
+
}
|
|
1756
2234
|
return getState(state, this.data, this.initializedAtomsSet);
|
|
1757
2235
|
} else if (isSelector(state)) {
|
|
1758
2236
|
if (this.dirty) {
|
|
@@ -1788,6 +2266,7 @@ class Transaction {
|
|
|
1788
2266
|
resolved = deepFreeze(resolved);
|
|
1789
2267
|
}
|
|
1790
2268
|
this._atomMap.set(atom, resolved);
|
|
2269
|
+
this._unsetSet?.delete(atom);
|
|
1791
2270
|
if (!this.dirty)
|
|
1792
2271
|
this.dirty = true;
|
|
1793
2272
|
if (isFamilyAtom(atom)) {
|
|
@@ -1816,6 +2295,7 @@ class Transaction {
|
|
|
1816
2295
|
if (index.deleted.has(atom))
|
|
1817
2296
|
index.deleted.delete(atom);
|
|
1818
2297
|
this._atomMap.set(atom, value);
|
|
2298
|
+
this._unsetSet?.delete(atom);
|
|
1819
2299
|
}
|
|
1820
2300
|
index.rendered = null;
|
|
1821
2301
|
index.renderedArray = null;
|
|
@@ -1839,6 +2319,22 @@ class Transaction {
|
|
|
1839
2319
|
this._atomMap.delete(atom);
|
|
1840
2320
|
}
|
|
1841
2321
|
};
|
|
2322
|
+
unset = (atom) => {
|
|
2323
|
+
if (!isAtom(atom))
|
|
2324
|
+
throw new Error("unset() expects an atom.");
|
|
2325
|
+
this._atomMap.delete(atom);
|
|
2326
|
+
if (!this._unsetSet)
|
|
2327
|
+
this._unsetSet = new Set;
|
|
2328
|
+
this._unsetSet.add(atom);
|
|
2329
|
+
};
|
|
2330
|
+
applyUnsets = (unsetSet, data) => {
|
|
2331
|
+
const unsetAtoms = [];
|
|
2332
|
+
for (const atom of unsetSet) {
|
|
2333
|
+
if (detachOwnValue(atom, data))
|
|
2334
|
+
unsetAtoms.push(atom);
|
|
2335
|
+
}
|
|
2336
|
+
return unsetAtoms;
|
|
2337
|
+
};
|
|
1842
2338
|
scope = (scopeId, callback) => {
|
|
1843
2339
|
if (this.data.scopes.has(scopeId)) {
|
|
1844
2340
|
return this.scopedTransaction(scopeId).execute(callback, false);
|
|
@@ -1858,6 +2354,7 @@ class Transaction {
|
|
|
1858
2354
|
reset = (atom) => {
|
|
1859
2355
|
const value = getAtomInitValue(atom, this.data, this.initializedAtomsSet);
|
|
1860
2356
|
this._atomMap.set(atom, value);
|
|
2357
|
+
this._unsetSet?.delete(atom);
|
|
1861
2358
|
return value;
|
|
1862
2359
|
};
|
|
1863
2360
|
execute = (callback, autoCommit = true) => {
|
|
@@ -1874,18 +2371,58 @@ class Transaction {
|
|
|
1874
2371
|
}
|
|
1875
2372
|
};
|
|
1876
2373
|
commit = () => {
|
|
2374
|
+
if (changeListenerRegistry.count === 0) {
|
|
2375
|
+
this.commitWork(undefined);
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2378
|
+
const sink = createChangeSink(this.name);
|
|
2379
|
+
try {
|
|
2380
|
+
this.commitWork(sink);
|
|
2381
|
+
} catch (error) {
|
|
2382
|
+
try {
|
|
2383
|
+
flushChangeSink(sink);
|
|
2384
|
+
} catch {}
|
|
2385
|
+
throw error;
|
|
2386
|
+
}
|
|
2387
|
+
flushChangeSink(sink);
|
|
2388
|
+
};
|
|
2389
|
+
commitWork = (sink) => {
|
|
1877
2390
|
if (!this._scopedTransactions) {
|
|
1878
2391
|
const initializedAtomsSet = new Set;
|
|
1879
|
-
if (this.
|
|
1880
|
-
const
|
|
2392
|
+
if (this._unsetSet?.size) {
|
|
2393
|
+
const notify2 = new Map;
|
|
1881
2394
|
const updatedAtoms = writeAtoms(this._atomMap, this.data, initializedAtomsSet);
|
|
1882
2395
|
if (updatedAtoms.length > 0) {
|
|
1883
|
-
propagateAtomUpdate(updatedAtoms, this.data, false,
|
|
2396
|
+
propagateAtomUpdate(updatedAtoms, this.data, false, notify2, sink);
|
|
2397
|
+
}
|
|
2398
|
+
if (this._deleteSet?.size) {
|
|
2399
|
+
deleteAtomFamilyAtoms(this._deleteSet, this.data);
|
|
2400
|
+
propagateDeletedAtoms([...this._deleteSet], this.data, undefined, undefined, undefined, notify2, sink);
|
|
2401
|
+
}
|
|
2402
|
+
const unsetAtoms = this.applyUnsets(this._unsetSet, this.data);
|
|
2403
|
+
if (unsetAtoms.length > 0) {
|
|
2404
|
+
if (sink) {
|
|
2405
|
+
for (const atom of unsetAtoms) {
|
|
2406
|
+
reportUnsetAtom(atom, this.data, effectiveValueAfterUnset(atom, this.data), sink);
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
propagateAtomUpdate(unsetAtoms, this.data, false, notify2, sink, false, false);
|
|
2410
|
+
}
|
|
2411
|
+
notifyDeferred(notify2);
|
|
2412
|
+
for (const atom of unsetAtoms) {
|
|
2413
|
+
reDelegateScopeSubscriptions(atom, this.data);
|
|
2414
|
+
}
|
|
2415
|
+
} else if (this._deleteSet?.size) {
|
|
2416
|
+
const notify2 = new Map;
|
|
2417
|
+
const updatedAtoms = writeAtoms(this._atomMap, this.data, initializedAtomsSet);
|
|
2418
|
+
if (updatedAtoms.length > 0) {
|
|
2419
|
+
propagateAtomUpdate(updatedAtoms, this.data, false, notify2, sink);
|
|
1884
2420
|
}
|
|
1885
2421
|
deleteAtomFamilyAtoms(this._deleteSet, this.data);
|
|
1886
|
-
propagateDeletedAtoms([...this._deleteSet], this.data, undefined, undefined, undefined,
|
|
2422
|
+
propagateDeletedAtoms([...this._deleteSet], this.data, undefined, undefined, undefined, notify2, sink);
|
|
2423
|
+
notifyDeferred(notify2);
|
|
1887
2424
|
} else {
|
|
1888
|
-
setAtoms(this._atomMap, this.data, initializedAtomsSet);
|
|
2425
|
+
setAtoms(this._atomMap, this.data, initializedAtomsSet, false, sink);
|
|
1889
2426
|
}
|
|
1890
2427
|
return;
|
|
1891
2428
|
}
|
|
@@ -1899,19 +2436,38 @@ class Transaction {
|
|
|
1899
2436
|
deleteAtomFamilyAtoms(txn._deleteSet, entry.data);
|
|
1900
2437
|
entry.deleted = [...txn._deleteSet];
|
|
1901
2438
|
}
|
|
2439
|
+
if (txn._unsetSet?.size) {
|
|
2440
|
+
entry.unsetAtoms = txn.applyUnsets(txn._unsetSet, entry.data);
|
|
2441
|
+
}
|
|
1902
2442
|
}
|
|
1903
2443
|
for (const entry of plan) {
|
|
1904
2444
|
for (const [atom, value, data] of entry.onSets) {
|
|
1905
2445
|
atom.onSet(value, data);
|
|
1906
2446
|
}
|
|
1907
2447
|
}
|
|
1908
|
-
const
|
|
1909
|
-
for (const { data, updatedAtoms, deleted } of plan) {
|
|
2448
|
+
const notify = new Map;
|
|
2449
|
+
for (const { data, updatedAtoms, deleted, unsetAtoms } of plan) {
|
|
1910
2450
|
if (updatedAtoms.length > 0) {
|
|
1911
|
-
propagateAtomUpdate(updatedAtoms, data, false,
|
|
2451
|
+
propagateAtomUpdate(updatedAtoms, data, false, notify, sink);
|
|
1912
2452
|
}
|
|
1913
2453
|
if (deleted) {
|
|
1914
|
-
propagateDeletedAtoms(deleted, data, undefined, undefined, undefined,
|
|
2454
|
+
propagateDeletedAtoms(deleted, data, undefined, undefined, undefined, notify, sink);
|
|
2455
|
+
}
|
|
2456
|
+
if (unsetAtoms && unsetAtoms.length > 0) {
|
|
2457
|
+
if (sink) {
|
|
2458
|
+
for (const atom of unsetAtoms) {
|
|
2459
|
+
reportUnsetAtom(atom, data, effectiveValueAfterUnset(atom, data), sink);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
propagateAtomUpdate(unsetAtoms, data, false, notify, sink, false, false);
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
notifyDeferred(notify);
|
|
2466
|
+
for (const { data, unsetAtoms } of plan) {
|
|
2467
|
+
if (unsetAtoms) {
|
|
2468
|
+
for (const atom of unsetAtoms) {
|
|
2469
|
+
reDelegateScopeSubscriptions(atom, data);
|
|
2470
|
+
}
|
|
1915
2471
|
}
|
|
1916
2472
|
}
|
|
1917
2473
|
};
|
|
@@ -1921,6 +2477,7 @@ class Transaction {
|
|
|
1921
2477
|
data: this.data,
|
|
1922
2478
|
updatedAtoms: [],
|
|
1923
2479
|
deleted: undefined,
|
|
2480
|
+
unsetAtoms: undefined,
|
|
1924
2481
|
onSets: []
|
|
1925
2482
|
});
|
|
1926
2483
|
if (this._scopedTransactions) {
|
|
@@ -1984,8 +2541,9 @@ class Transaction {
|
|
|
1984
2541
|
}
|
|
1985
2542
|
}
|
|
1986
2543
|
}
|
|
1987
|
-
var transaction = (callback, data) => {
|
|
2544
|
+
var transaction = (callback, data, name) => {
|
|
1988
2545
|
const txn = new Transaction(data);
|
|
2546
|
+
txn.name = name;
|
|
1989
2547
|
return txn.execute(callback);
|
|
1990
2548
|
};
|
|
1991
2549
|
|
|
@@ -2096,12 +2654,19 @@ function storeFromStoreData(data, detach) {
|
|
|
2096
2654
|
flushPendingTxn();
|
|
2097
2655
|
return deleteFamilyAtom(atom, data);
|
|
2098
2656
|
};
|
|
2657
|
+
const unset = (atom) => {
|
|
2658
|
+
if (data.batchUpdates)
|
|
2659
|
+
flushPendingTxn();
|
|
2660
|
+
return unsetValue(atom, data);
|
|
2661
|
+
};
|
|
2099
2662
|
const sub = (state, callback, deepEqualCheckBeforeCallback = true) => subscribe(state, callback, deepEqualCheckBeforeCallback, data);
|
|
2100
|
-
const txn = (callback) => {
|
|
2663
|
+
const txn = (callback, name) => {
|
|
2101
2664
|
if (data.batchUpdates)
|
|
2102
2665
|
flushPendingTxn();
|
|
2103
|
-
return transaction(callback, data);
|
|
2666
|
+
return transaction(callback, data, name);
|
|
2104
2667
|
};
|
|
2668
|
+
const onChange = (callback, options) => onStoreChange(callback, data, options);
|
|
2669
|
+
const storeSnapshot = () => snapshot(data);
|
|
2105
2670
|
const scope = (scopeId, callback) => {
|
|
2106
2671
|
if (callback) {
|
|
2107
2672
|
if (!data.scopes.has(scopeId)) {
|
|
@@ -2154,8 +2719,11 @@ function storeFromStoreData(data, detach) {
|
|
|
2154
2719
|
txn,
|
|
2155
2720
|
reset,
|
|
2156
2721
|
del,
|
|
2722
|
+
unset,
|
|
2157
2723
|
data,
|
|
2158
2724
|
scope,
|
|
2725
|
+
onChange,
|
|
2726
|
+
snapshot: storeSnapshot,
|
|
2159
2727
|
detach
|
|
2160
2728
|
};
|
|
2161
2729
|
} else {
|
|
@@ -2166,8 +2734,11 @@ function storeFromStoreData(data, detach) {
|
|
|
2166
2734
|
txn,
|
|
2167
2735
|
reset,
|
|
2168
2736
|
del,
|
|
2737
|
+
unset,
|
|
2169
2738
|
data,
|
|
2170
|
-
scope
|
|
2739
|
+
scope,
|
|
2740
|
+
onChange,
|
|
2741
|
+
snapshot: storeSnapshot
|
|
2171
2742
|
};
|
|
2172
2743
|
}
|
|
2173
2744
|
}
|
|
@@ -2348,12 +2919,13 @@ var unmountOrphanedDeps = (state, data, visited) => {
|
|
|
2348
2919
|
};
|
|
2349
2920
|
|
|
2350
2921
|
// src/store.ts
|
|
2351
|
-
|
|
2352
|
-
const
|
|
2353
|
-
const
|
|
2922
|
+
function store(idOrOptions, maybeOptions) {
|
|
2923
|
+
const optionsObject = typeof idOrOptions === "object" && idOrOptions !== null ? idOrOptions : undefined;
|
|
2924
|
+
const id = typeof idOrOptions === "string" ? idOrOptions : optionsObject?.id;
|
|
2925
|
+
const options = optionsObject ?? maybeOptions;
|
|
2354
2926
|
const data = createStoreData(id, undefined, options);
|
|
2355
2927
|
return storeFromStoreData(data);
|
|
2356
|
-
}
|
|
2928
|
+
}
|
|
2357
2929
|
|
|
2358
2930
|
// src/globalStore.ts
|
|
2359
2931
|
var globalStore = Object.assign(store("valdres-global-store"), {
|
|
@@ -2407,9 +2979,9 @@ var globalAtom = (defaultValue, options) => {
|
|
|
2407
2979
|
const getSelf = () => globalStore.get(atom);
|
|
2408
2980
|
const setSelf = (newValue) => globalStore.set(atom, newValue);
|
|
2409
2981
|
const resetSelf = () => {
|
|
2410
|
-
const
|
|
2982
|
+
const snapshot2 = [...stores];
|
|
2411
2983
|
const subscribedStores = [];
|
|
2412
|
-
for (const s of
|
|
2984
|
+
for (const s of snapshot2) {
|
|
2413
2985
|
if (isLive(atom, s)) {
|
|
2414
2986
|
subscribedStores.push(s);
|
|
2415
2987
|
}
|
|
@@ -2419,7 +2991,7 @@ var globalAtom = (defaultValue, options) => {
|
|
|
2419
2991
|
if (!firstError)
|
|
2420
2992
|
firstError = e;
|
|
2421
2993
|
};
|
|
2422
|
-
for (const s of
|
|
2994
|
+
for (const s of snapshot2) {
|
|
2423
2995
|
try {
|
|
2424
2996
|
unmountAtom(atom, s);
|
|
2425
2997
|
} catch (e) {
|
|
@@ -2431,11 +3003,11 @@ var globalAtom = (defaultValue, options) => {
|
|
|
2431
3003
|
atom.maxAgeInterval.refCount = 0;
|
|
2432
3004
|
atom.maxAgeInterval = undefined;
|
|
2433
3005
|
}
|
|
2434
|
-
for (const store2 of
|
|
3006
|
+
for (const store2 of snapshot2) {
|
|
2435
3007
|
stores.delete(store2);
|
|
2436
3008
|
store2.values.delete(atom);
|
|
2437
3009
|
try {
|
|
2438
|
-
propagateAtomUpdate([atom], store2);
|
|
3010
|
+
propagateAtomUpdate([atom], store2, false, undefined, "reset");
|
|
2439
3011
|
} catch (e) {
|
|
2440
3012
|
recordError(e);
|
|
2441
3013
|
}
|
|
@@ -2659,9 +3231,10 @@ var cacheMeta = (sourceAtom) => {
|
|
|
2659
3231
|
if (sourceAtom.__cacheMetaSelector)
|
|
2660
3232
|
return sourceAtom.__cacheMetaSelector;
|
|
2661
3233
|
if (!sourceAtom.__cacheMeta) {
|
|
2662
|
-
sourceAtom.__cacheMeta = { equal, defaultValue: null };
|
|
3234
|
+
sourceAtom.__cacheMeta = { equal, defaultValue: null, __valdresInternal: true };
|
|
2663
3235
|
}
|
|
2664
3236
|
sourceAtom.__cacheMetaSelector = selector((get) => get(sourceAtom.__cacheMeta));
|
|
3237
|
+
sourceAtom.__cacheMetaSelector.__valdresInternal = true;
|
|
2665
3238
|
return sourceAtom.__cacheMetaSelector;
|
|
2666
3239
|
};
|
|
2667
3240
|
// src/indexConstructor.ts
|
|
@@ -2669,38 +3242,27 @@ var index = (family, callback, options) => {
|
|
|
2669
3242
|
const map = new Map;
|
|
2670
3243
|
const index2 = (term) => {
|
|
2671
3244
|
const termKey = stableStringify(term);
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
const
|
|
2676
|
-
const
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
deletedAtoms.forEach((atom2) => {
|
|
2682
|
-
termIndexSelectorSet.delete(atom2);
|
|
2683
|
-
termIndexSelectorMap.delete(atom2);
|
|
2684
|
-
});
|
|
2685
|
-
addedAtoms.forEach((atom2) => {
|
|
2686
|
-
termIndexSelectorSet.add(atom2);
|
|
2687
|
-
termIndexSelectorMap.set(atom2, selector((get2) => callback(get2(atom2), term), {
|
|
2688
|
-
name: `index:callback:selector:${atom2.name}`
|
|
2689
|
-
}));
|
|
3245
|
+
const existing = map.get(termKey);
|
|
3246
|
+
if (existing)
|
|
3247
|
+
return existing;
|
|
3248
|
+
const predicateSelectors = new WeakMap;
|
|
3249
|
+
const predicateFor = (atom2) => {
|
|
3250
|
+
let sel = predicateSelectors.get(atom2);
|
|
3251
|
+
if (!sel) {
|
|
3252
|
+
sel = selector((get) => callback(get(atom2), term), {
|
|
3253
|
+
name: `index:callback:selector:${atom2.name}`
|
|
2690
3254
|
});
|
|
2691
|
-
|
|
2692
|
-
} else {
|
|
2693
|
-
return termIndexSelectorSet;
|
|
3255
|
+
predicateSelectors.set(atom2, sel);
|
|
2694
3256
|
}
|
|
2695
|
-
|
|
3257
|
+
return sel;
|
|
3258
|
+
};
|
|
2696
3259
|
const filteredSelector = selector((get) => {
|
|
2697
|
-
const set = get(termIndexSelector);
|
|
2698
3260
|
const res = [];
|
|
2699
|
-
|
|
2700
|
-
|
|
3261
|
+
const members = get(family);
|
|
3262
|
+
for (const atom2 of members) {
|
|
3263
|
+
if (get(predicateFor(atom2)))
|
|
2701
3264
|
res.push(atom2);
|
|
2702
|
-
|
|
2703
|
-
});
|
|
3265
|
+
}
|
|
2704
3266
|
return res;
|
|
2705
3267
|
}, {
|
|
2706
3268
|
name: `index:${options?.name}:${termKey}:termSelector`
|
|
@@ -2748,9 +3310,9 @@ var isFamilySelector = (state) => isFamilyState(state) && isSelector(state);
|
|
|
2748
3310
|
|
|
2749
3311
|
// src/index.ts
|
|
2750
3312
|
if (globalThis.__valdres__) {
|
|
2751
|
-
throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${"1.0.0-beta.
|
|
3313
|
+
throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${"1.0.0-beta.7"}`);
|
|
2752
3314
|
} else {
|
|
2753
|
-
globalThis.__valdres__ = "1.0.0-beta.
|
|
3315
|
+
globalThis.__valdres__ = "1.0.0-beta.7";
|
|
2754
3316
|
}
|
|
2755
3317
|
export {
|
|
2756
3318
|
store,
|