valdres 1.0.0-beta.7 → 1.0.0-beta.8
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
|
@@ -122,40 +122,7 @@ var isFamilyAtom = (state) => isFamilyState(state) && isAtom(state);
|
|
|
122
122
|
// src/utils/isSelectorFamily.ts
|
|
123
123
|
var isSelectorFamily = (state) => state && Object.hasOwn(state, "__valdresSelectorFamilyMap");
|
|
124
124
|
|
|
125
|
-
// src/
|
|
126
|
-
var deepFreeze = (obj, seen) => {
|
|
127
|
-
if (obj === null || obj === undefined)
|
|
128
|
-
return obj;
|
|
129
|
-
if (typeof obj !== "object" && typeof obj !== "function")
|
|
130
|
-
return obj;
|
|
131
|
-
if (Object.isFrozen(obj) || seen?.has(obj))
|
|
132
|
-
return obj;
|
|
133
|
-
if (Array.isArray(obj)) {
|
|
134
|
-
for (const item of obj) {
|
|
135
|
-
if (item && typeof item === "object") {
|
|
136
|
-
seen ??= new WeakSet;
|
|
137
|
-
seen.add(obj);
|
|
138
|
-
deepFreeze(item, seen);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
} else {
|
|
142
|
-
const propNames = Object.getOwnPropertyNames(obj);
|
|
143
|
-
for (const name of propNames) {
|
|
144
|
-
const value = obj[name];
|
|
145
|
-
if (value && typeof value === "object") {
|
|
146
|
-
seen ??= new WeakSet;
|
|
147
|
-
seen.add(obj);
|
|
148
|
-
deepFreeze(value, seen);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return Object.freeze(obj);
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// src/lib/IS_PROD.ts
|
|
156
|
-
var IS_PROD = typeof process !== "undefined" && process.env != null && process.env.NODE_ENV === "production";
|
|
157
|
-
|
|
158
|
-
// src/lib/setValueInData.ts
|
|
125
|
+
// src/lib/trackScopeValue.ts
|
|
159
126
|
var trackScopeValue = (key, data) => {
|
|
160
127
|
const parent = data.parent;
|
|
161
128
|
const indexKeys = data.scopeIndexKeys;
|
|
@@ -170,30 +137,6 @@ var trackScopeValue = (key, data) => {
|
|
|
170
137
|
set.add(data);
|
|
171
138
|
indexKeys.add(key);
|
|
172
139
|
};
|
|
173
|
-
var setValueInData = (atom, value, data) => {
|
|
174
|
-
const isNewAtomInScope = data.parent && Object.hasOwn(atom, "defaultValue") && !data.values.has(atom);
|
|
175
|
-
let written;
|
|
176
|
-
if (atom.mutable || IS_PROD) {
|
|
177
|
-
data.values.set(atom, value);
|
|
178
|
-
written = value;
|
|
179
|
-
} else {
|
|
180
|
-
const frozenValue = value !== null && (typeof value === "object" || typeof value === "function") ? deepFreeze(value) : value;
|
|
181
|
-
data.values.set(atom, frozenValue);
|
|
182
|
-
written = frozenValue;
|
|
183
|
-
}
|
|
184
|
-
if (isNewAtomInScope) {
|
|
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
|
-
}
|
|
192
|
-
if (atom.maxAge !== undefined) {
|
|
193
|
-
data.lastValueWriteAt.set(atom, Date.now());
|
|
194
|
-
}
|
|
195
|
-
return written;
|
|
196
|
-
};
|
|
197
140
|
|
|
198
141
|
// src/lib/atomFamilyIndex.ts
|
|
199
142
|
var getAtomFamilyRenderedMap = (index) => {
|
|
@@ -292,13 +235,29 @@ var recursivelyUpdateIndexes = (data, family) => {
|
|
|
292
235
|
recursivelyUpdateIndexes(scopedData, family);
|
|
293
236
|
}
|
|
294
237
|
};
|
|
238
|
+
var ensureFamilyAncestorChain = (family, data) => {
|
|
239
|
+
if (!data.parent)
|
|
240
|
+
return;
|
|
241
|
+
const parentIndex = initFamilyIndex(family, data.parent);
|
|
242
|
+
const own = data.values.get(family).__index;
|
|
243
|
+
if (own.parentIndex !== parentIndex) {
|
|
244
|
+
own.parentIndex = parentIndex;
|
|
245
|
+
own.rendered = null;
|
|
246
|
+
own.renderedArray = null;
|
|
247
|
+
data.values.set(family, renderAtomFamilyIndex(own));
|
|
248
|
+
recursivelyUpdateIndexes(data, family);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
295
251
|
var addFamilyAtomsToSet = (family, familyAtoms, data, timestamp) => {
|
|
296
252
|
if (familyAtoms.size === 0)
|
|
297
|
-
return;
|
|
253
|
+
return false;
|
|
298
254
|
const index = findFamilyIndex(family, data);
|
|
299
255
|
if (!index)
|
|
300
256
|
throw new Error("index not found");
|
|
257
|
+
let membershipChanged = false;
|
|
301
258
|
for (const atom of familyAtoms) {
|
|
259
|
+
if (!(index.created.has(atom) && !index.deleted.has(atom)))
|
|
260
|
+
membershipChanged = true;
|
|
302
261
|
index.created.set(atom, timestamp);
|
|
303
262
|
index.deleted.delete(atom);
|
|
304
263
|
}
|
|
@@ -306,6 +265,7 @@ var addFamilyAtomsToSet = (family, familyAtoms, data, timestamp) => {
|
|
|
306
265
|
index.renderedArray = null;
|
|
307
266
|
data.values.set(family, renderAtomFamilyIndex(index));
|
|
308
267
|
recursivelyUpdateIndexes(data, family);
|
|
268
|
+
return membershipChanged;
|
|
309
269
|
};
|
|
310
270
|
|
|
311
271
|
// src/errors/lib/generateSelectorTrace.ts
|
|
@@ -610,6 +570,69 @@ var flushChangeSink = (sink) => {
|
|
|
610
570
|
}
|
|
611
571
|
};
|
|
612
572
|
|
|
573
|
+
// src/utils/deepFreeze.ts
|
|
574
|
+
var deepFreeze = (obj, seen) => {
|
|
575
|
+
if (obj === null || obj === undefined)
|
|
576
|
+
return obj;
|
|
577
|
+
if (typeof obj !== "object" && typeof obj !== "function")
|
|
578
|
+
return obj;
|
|
579
|
+
if (Object.isFrozen(obj) || seen?.has(obj))
|
|
580
|
+
return obj;
|
|
581
|
+
if (Array.isArray(obj)) {
|
|
582
|
+
for (const item of obj) {
|
|
583
|
+
if (item && typeof item === "object") {
|
|
584
|
+
seen ??= new WeakSet;
|
|
585
|
+
seen.add(obj);
|
|
586
|
+
deepFreeze(item, seen);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
} else {
|
|
590
|
+
const propNames = Object.getOwnPropertyNames(obj);
|
|
591
|
+
for (const name of propNames) {
|
|
592
|
+
const value = obj[name];
|
|
593
|
+
if (value && typeof value === "object") {
|
|
594
|
+
seen ??= new WeakSet;
|
|
595
|
+
seen.add(obj);
|
|
596
|
+
deepFreeze(value, seen);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
return Object.freeze(obj);
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
// src/lib/IS_PROD.ts
|
|
604
|
+
var IS_PROD = typeof process !== "undefined" && process.env != null && process.env.NODE_ENV === "production";
|
|
605
|
+
|
|
606
|
+
// src/lib/setValueInData.ts
|
|
607
|
+
var setValueInData = (atom, value, data) => {
|
|
608
|
+
const isNewAtomInScope = data.parent && Object.hasOwn(atom, "defaultValue") && !data.values.has(atom);
|
|
609
|
+
const isNewFamilyInScope = !!data.parent && !data.values.has(atom) && isAtomFamily(atom);
|
|
610
|
+
let written;
|
|
611
|
+
if (atom.mutable || IS_PROD) {
|
|
612
|
+
data.values.set(atom, value);
|
|
613
|
+
written = value;
|
|
614
|
+
} else {
|
|
615
|
+
const frozenValue = value !== null && (typeof value === "object" || typeof value === "function") ? deepFreeze(value) : value;
|
|
616
|
+
data.values.set(atom, frozenValue);
|
|
617
|
+
written = frozenValue;
|
|
618
|
+
}
|
|
619
|
+
if (isNewAtomInScope) {
|
|
620
|
+
trackScopeValue(atom, data);
|
|
621
|
+
const subs = data.subscriptions.get(atom);
|
|
622
|
+
if (subs) {
|
|
623
|
+
for (const sub of subs)
|
|
624
|
+
sub.reRoot?.();
|
|
625
|
+
}
|
|
626
|
+
} else if (isNewFamilyInScope) {
|
|
627
|
+
trackScopeValue(atom, data);
|
|
628
|
+
ensureFamilyAncestorChain(atom, data);
|
|
629
|
+
}
|
|
630
|
+
if (atom.maxAge !== undefined) {
|
|
631
|
+
data.lastValueWriteAt.set(atom, Date.now());
|
|
632
|
+
}
|
|
633
|
+
return written;
|
|
634
|
+
};
|
|
635
|
+
|
|
613
636
|
// src/lib/initSelector.ts
|
|
614
637
|
var neverAbortedSignal = new AbortController().signal;
|
|
615
638
|
var syncOptionsCache = new WeakMap;
|
|
@@ -1017,6 +1040,7 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify, report, skip
|
|
|
1017
1040
|
updatedFamilyAtoms.get(atom.family).add(atom);
|
|
1018
1041
|
}
|
|
1019
1042
|
}
|
|
1043
|
+
let membershipChanged;
|
|
1020
1044
|
if (updatedFamilyAtoms.size > 0) {
|
|
1021
1045
|
const timestamp = performance.now();
|
|
1022
1046
|
for (const [family, familyAtoms] of updatedFamilyAtoms) {
|
|
@@ -1024,7 +1048,11 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify, report, skip
|
|
|
1024
1048
|
addSetToSet(data.subscriptions.get(family), subscriptions);
|
|
1025
1049
|
if (familyAtoms.size === 0)
|
|
1026
1050
|
throw new Error("Should not be possible");
|
|
1027
|
-
addFamilyAtomsToSet(family, familyAtoms, data, timestamp)
|
|
1051
|
+
if (addFamilyAtomsToSet(family, familyAtoms, data, timestamp)) {
|
|
1052
|
+
if (!membershipChanged)
|
|
1053
|
+
membershipChanged = new Set;
|
|
1054
|
+
membershipChanged.add(family);
|
|
1055
|
+
}
|
|
1028
1056
|
}
|
|
1029
1057
|
}
|
|
1030
1058
|
if (data.scopes && data.scopes.size > 0) {
|
|
@@ -1058,7 +1086,15 @@ var propagateAtomUpdate = (atoms, data, isInitOnly = false, notify, report, skip
|
|
|
1058
1086
|
if (watching && reportIsSink)
|
|
1059
1087
|
emitOrigin(effectiveReport);
|
|
1060
1088
|
if (hasScopes) {
|
|
1061
|
-
|
|
1089
|
+
let scopeAtoms = atoms;
|
|
1090
|
+
if (membershipChanged) {
|
|
1091
|
+
scopeAtoms = atoms.slice();
|
|
1092
|
+
for (const family of membershipChanged) {
|
|
1093
|
+
if (!scopeAtoms.includes(family))
|
|
1094
|
+
scopeAtoms.push(family);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
propagateToScopes(scopeAtoms, data, isInitOnly, notify, effectiveReport);
|
|
1062
1098
|
}
|
|
1063
1099
|
if (watching && !reportIsSink)
|
|
1064
1100
|
emitOrigin(effectiveReport);
|
|
@@ -2520,7 +2556,13 @@ class Transaction {
|
|
|
2520
2556
|
if (moveUpIfParent && this.parentTransaction)
|
|
2521
2557
|
return this.parentTransaction.cloneFamilyIntoTxn(family, parentIndex, moveUpIfParent);
|
|
2522
2558
|
const currentFamilyList = this.get(family);
|
|
2523
|
-
const
|
|
2559
|
+
const scopeFirstMaterialization = this.data.parent && !this._atomMap.has(family) && !this.data.values.has(family);
|
|
2560
|
+
let clonedIndex;
|
|
2561
|
+
if (scopeFirstMaterialization) {
|
|
2562
|
+
clonedIndex = createAtomFamilyIndex(parentIndex ?? currentFamilyList.__index);
|
|
2563
|
+
} else {
|
|
2564
|
+
clonedIndex = cloneAtomFamilyIndex(currentFamilyList.__index, parentIndex);
|
|
2565
|
+
}
|
|
2524
2566
|
if (this._scopedTransactions?.size) {
|
|
2525
2567
|
for (const [, scopedTxn] of this._scopedTransactions) {
|
|
2526
2568
|
scopedTxn.cloneFamilyIntoTxn(family, clonedIndex, false);
|
|
@@ -3310,9 +3352,9 @@ var isFamilySelector = (state) => isFamilyState(state) && isSelector(state);
|
|
|
3310
3352
|
|
|
3311
3353
|
// src/index.ts
|
|
3312
3354
|
if (globalThis.__valdres__) {
|
|
3313
|
-
throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${"1.0.0-beta.
|
|
3355
|
+
throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${"1.0.0-beta.8"}`);
|
|
3314
3356
|
} else {
|
|
3315
|
-
globalThis.__valdres__ = "1.0.0-beta.
|
|
3357
|
+
globalThis.__valdres__ = "1.0.0-beta.8";
|
|
3316
3358
|
}
|
|
3317
3359
|
export {
|
|
3318
3360
|
store,
|
|
@@ -14,5 +14,7 @@ export type AtomFamilyIndex = {
|
|
|
14
14
|
export declare const cloneAtomFamilyIndex: (index: AtomFamilyIndex, parentIndexOverride?: AtomFamilyIndex) => AtomFamilyIndex;
|
|
15
15
|
export declare const createAtomFamilyIndex: (parentIndex?: AtomFamilyIndex) => AtomFamilyIndex;
|
|
16
16
|
export declare const deleteFamilyAtomsFromSet: (family: Family<any>, familyAtoms: Set<AtomFamilyAtom<any>>, data: StoreData, timestamp: number) => void;
|
|
17
|
+
export declare const initFamilyIndex: (family: Family<any>, data: StoreData) => any;
|
|
17
18
|
export declare const recursivelyUpdateIndexes: (data: StoreData, family: Family<any>) => void;
|
|
18
|
-
export declare const
|
|
19
|
+
export declare const ensureFamilyAncestorChain: (family: Family<any>, data: StoreData) => void;
|
|
20
|
+
export declare const addFamilyAtomsToSet: (family: Family<any>, familyAtoms: Set<AtomFamilyAtom<any>>, data: StoreData, timestamp: number) => boolean;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { Atom } from "../types/Atom";
|
|
2
2
|
import type { AtomFamily } from "../types/AtomFamily";
|
|
3
3
|
import type { StoreData } from "../types/StoreData";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* scoped stores (see createStoreData). */
|
|
7
|
-
export declare const trackScopeValue: (key: WeakKey, data: StoreData) => void;
|
|
4
|
+
import { trackScopeValue } from "./trackScopeValue";
|
|
5
|
+
export { trackScopeValue };
|
|
8
6
|
export declare const setValueInData: <Value extends unknown>(atom: Atom<Value> | AtomFamily<any, any>, value: Value, data: StoreData) => Value;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { StoreData } from "../types/StoreData";
|
|
2
|
+
/** Register `key` (an atom or family) in the parent's scopeValueIndex, recording
|
|
3
|
+
* it in this scope's scopeIndexKeys for cleanup on detach. Throws if called on
|
|
4
|
+
* a root store — `parent` and `scopeIndexKeys` are only populated for scoped
|
|
5
|
+
* stores (see createStoreData).
|
|
6
|
+
*
|
|
7
|
+
* Lives in its own module (rather than setValueInData) so both the scope-value
|
|
8
|
+
* write path (setValueInData) and the family-index path (atomFamilyIndex) can
|
|
9
|
+
* depend on it without an import cycle. */
|
|
10
|
+
export declare const trackScopeValue: (key: WeakKey, data: StoreData) => void;
|