valdres 0.2.0-alpha.7 → 0.2.0-alpha.70
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 +856 -284
- package/dist/types/src/atom.d.ts +16 -0
- package/dist/types/src/atomFamily.d.ts +4 -0
- package/dist/types/src/createStoreWithSelectorSet.d.ts +2 -0
- package/dist/types/src/errors/SelectorCircularDependencyError.d.ts +5 -0
- package/dist/types/src/errors/SelectorEvaluationError.d.ts +7 -0
- package/dist/types/src/errors/lib/generateSelectorTrace.d.ts +2 -0
- package/dist/types/src/globalStore.d.ts +4 -0
- package/dist/types/src/index.d.ts +36 -0
- package/dist/types/src/indexConstructor.d.ts +4 -0
- package/dist/types/src/lib/atomFamilyAtom.d.ts +8 -0
- package/dist/types/src/lib/createAtomFamily.d.ts +4 -0
- package/dist/types/src/lib/createGlobalAtomFamily.d.ts +5 -0
- package/dist/types/src/lib/createStoreData.d.ts +3 -0
- package/dist/types/src/lib/equal.d.ts +1 -0
- package/dist/types/src/lib/getState.d.ts +7 -0
- package/dist/types/src/lib/globalAtom.d.ts +4 -0
- package/dist/types/src/lib/initAtom.d.ts +5 -0
- package/dist/types/src/lib/initSelector.d.ts +3 -0
- package/dist/types/src/lib/isFunction.d.ts +1 -0
- package/dist/types/src/lib/propagateUpdatedAtoms.d.ts +4 -0
- package/dist/types/src/lib/resetAtom.d.ts +3 -0
- package/dist/types/src/lib/setAtom.d.ts +3 -0
- package/dist/types/src/lib/setAtoms.d.ts +3 -0
- package/dist/types/src/lib/setValueInData.d.ts +3 -0
- package/dist/types/src/lib/stableStringify.d.ts +1 -0
- package/dist/types/src/lib/storeFromStoreData.d.ts +4 -0
- package/dist/types/src/lib/subscribe.d.ts +4 -0
- package/dist/types/src/lib/transaction.d.ts +8 -0
- package/dist/types/src/lib/unsubscribe.d.ts +5 -0
- package/dist/types/src/lib/updateSelectorSubscribers.d.ts +3 -0
- package/dist/types/src/lib/updateStateSubscribers.d.ts +3 -0
- package/dist/types/src/selector.d.ts +4 -0
- package/dist/types/src/selectorFamily.d.ts +4 -0
- package/dist/types/src/store.d.ts +1 -0
- package/dist/types/src/types/Atom.d.ts +14 -0
- package/dist/types/src/types/AtomDefaultValue.d.ts +2 -0
- package/dist/types/src/types/AtomFamily.d.ts +12 -0
- package/dist/types/src/types/AtomFamilyAtom.d.ts +6 -0
- package/dist/types/src/types/AtomFamilyDefaultValue.d.ts +5 -0
- package/dist/types/src/types/AtomFamilyGlobalAtom.d.ts +3 -0
- package/dist/types/src/types/AtomFamilySelector.d.ts +6 -0
- package/dist/types/src/types/AtomOnInit.d.ts +2 -0
- package/dist/types/src/types/AtomOnSet.d.ts +2 -0
- package/dist/types/src/types/AtomOptions.d.ts +13 -0
- package/dist/types/src/types/EqualFunc.d.ts +1 -0
- package/dist/types/src/types/Family.d.ts +3 -0
- package/dist/types/src/types/FamilyKey.d.ts +3 -0
- package/dist/types/src/types/GetValue.d.ts +8 -0
- package/dist/types/src/types/GlobalAtom.d.ts +11 -0
- package/dist/types/src/types/GlobalAtomGetSelfFunc.d.ts +1 -0
- package/dist/types/src/types/GlobalAtomResetSelfFunc.d.ts +1 -0
- package/dist/types/src/types/GlobalAtomSetSelfFunc.d.ts +1 -0
- package/dist/types/src/types/ResetAtom.d.ts +2 -0
- package/dist/types/src/types/Selector.d.ts +11 -0
- package/dist/types/src/types/SelectorFamily.d.ts +6 -0
- package/dist/types/src/types/SelectorOptions.d.ts +5 -0
- package/dist/types/src/types/SetAtom.d.ts +5 -0
- package/dist/types/src/types/SetAtomValue.d.ts +1 -0
- package/dist/types/src/types/State.d.ts +4 -0
- package/dist/types/src/types/Store.d.ts +24 -0
- package/dist/types/src/types/StoreData.d.ts +17 -0
- package/dist/types/src/types/SubscribeFn.d.ts +9 -0
- package/dist/types/src/types/Subscription.d.ts +1 -0
- package/dist/types/src/types/TransactionFn.d.ts +2 -0
- package/dist/types/src/types/TransactionInterface.d.ts +17 -0
- package/dist/types/src/utils/deepFreeze.d.ts +1 -0
- package/dist/types/src/utils/isAtom.d.ts +2 -0
- package/dist/types/src/utils/isAtomFamily.d.ts +2 -0
- package/dist/types/src/utils/isFamily.d.ts +1 -0
- package/dist/types/src/utils/isFamilyAtom.d.ts +2 -0
- package/dist/types/src/utils/isFamilySelector.d.ts +2 -0
- package/dist/types/src/utils/isFamilyState.d.ts +3 -0
- package/dist/types/src/utils/isPromiseLike.d.ts +1 -0
- package/dist/types/src/utils/isSelector.d.ts +2 -0
- package/dist/types/src/utils/isSelectorFamily.d.ts +2 -0
- package/package.json +7 -10
package/dist/index.js
CHANGED
|
@@ -1,108 +1,105 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
if (!options)
|
|
4
|
-
return { defaultValue };
|
|
5
|
-
return {
|
|
6
|
-
defaultValue,
|
|
7
|
-
...options
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
|
-
// src/utils/isPromiseLike.ts
|
|
11
|
-
var isPromiseLike = (object) => {
|
|
12
|
-
return object && object.then && typeof object.then === "function";
|
|
13
|
-
};
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { version } from "../package.json";
|
|
14
3
|
|
|
15
|
-
// src/lib/
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
if (typeof x !== "object") {
|
|
37
|
-
return JSON.stringify(x) ?? "";
|
|
38
|
-
}
|
|
39
|
-
if (isPromiseLike(x)) {
|
|
40
|
-
return "__PROMISE__";
|
|
41
|
-
}
|
|
42
|
-
if (Array.isArray(x)) {
|
|
43
|
-
return `[${x.map((v, i) => stableStringifyRecurse(v, i.toString()))}]`;
|
|
44
|
-
}
|
|
45
|
-
if (typeof x.toJSON === "function") {
|
|
46
|
-
return stableStringifyRecurse(x.toJSON(key), key);
|
|
47
|
-
}
|
|
48
|
-
if (x instanceof Map) {
|
|
49
|
-
const obj = {};
|
|
50
|
-
for (const [k, v] of x) {
|
|
51
|
-
obj[typeof k === "string" ? k : stringify(k, opt)] = v;
|
|
4
|
+
// src/lib/equal.ts
|
|
5
|
+
var hasElementType = typeof Element !== "undefined";
|
|
6
|
+
var hasMap = typeof Map === "function";
|
|
7
|
+
var hasSet = typeof Set === "function";
|
|
8
|
+
var hasArrayBuffer = typeof ArrayBuffer === "function" && !!ArrayBuffer.isView;
|
|
9
|
+
var deepEqualFn = (a, b) => {
|
|
10
|
+
if (a === b)
|
|
11
|
+
return true;
|
|
12
|
+
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
13
|
+
if (a.constructor !== b.constructor)
|
|
14
|
+
return false;
|
|
15
|
+
var length, i, keys;
|
|
16
|
+
if (Array.isArray(a)) {
|
|
17
|
+
length = a.length;
|
|
18
|
+
if (length != b.length)
|
|
19
|
+
return false;
|
|
20
|
+
for (i = length;i-- !== 0; )
|
|
21
|
+
if (!deepEqualFn(a[i], b[i]))
|
|
22
|
+
return false;
|
|
23
|
+
return true;
|
|
52
24
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
25
|
+
var it;
|
|
26
|
+
if (hasMap && a instanceof Map && b instanceof Map) {
|
|
27
|
+
if (a.size !== b.size)
|
|
28
|
+
return false;
|
|
29
|
+
it = a.entries();
|
|
30
|
+
while (!(i = it.next()).done)
|
|
31
|
+
if (!b.has(i.value[0]))
|
|
32
|
+
return false;
|
|
33
|
+
it = a.entries();
|
|
34
|
+
while (!(i = it.next()).done)
|
|
35
|
+
if (!deepEqualFn(i.value[1], b.get(i.value[0])))
|
|
36
|
+
return false;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
if (hasSet && a instanceof Set && b instanceof Set) {
|
|
40
|
+
if (a.size !== b.size)
|
|
41
|
+
return false;
|
|
42
|
+
it = a.entries();
|
|
43
|
+
while (!(i = it.next()).done)
|
|
44
|
+
if (!b.has(i.value[0]))
|
|
45
|
+
return false;
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (hasArrayBuffer && ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
|
|
49
|
+
length = a.length;
|
|
50
|
+
if (length != b.length)
|
|
51
|
+
return false;
|
|
52
|
+
for (i = length;i-- !== 0; )
|
|
53
|
+
if (a[i] !== b[i])
|
|
54
|
+
return false;
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
if (a.constructor === RegExp)
|
|
58
|
+
return a.source === b.source && a.flags === b.flags;
|
|
59
|
+
if (a.valueOf !== Object.prototype.valueOf && typeof a.valueOf === "function" && typeof b.valueOf === "function")
|
|
60
|
+
return a.valueOf() === b.valueOf();
|
|
61
|
+
if (a.toString !== Object.prototype.toString && typeof a.toString === "function" && typeof b.toString === "function")
|
|
62
|
+
return a.toString() === b.toString();
|
|
63
|
+
keys = Object.keys(a);
|
|
64
|
+
length = keys.length;
|
|
65
|
+
if (length !== Object.keys(b).length)
|
|
66
|
+
return false;
|
|
67
|
+
for (i = length;i-- !== 0; )
|
|
68
|
+
if (!Object.prototype.hasOwnProperty.call(b, keys[i]))
|
|
69
|
+
return false;
|
|
70
|
+
if (hasElementType && a instanceof Element)
|
|
71
|
+
return false;
|
|
72
|
+
for (i = length;i-- !== 0; ) {
|
|
73
|
+
if ((keys[i] === "_owner" || keys[i] === "__v" || keys[i] === "__o") && a.$$typeof) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!deepEqualFn(a[keys[i]], b[keys[i]]))
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return true;
|
|
60
80
|
}
|
|
61
|
-
return
|
|
81
|
+
return a !== a && b !== b;
|
|
62
82
|
};
|
|
63
|
-
var
|
|
64
|
-
|
|
65
|
-
return
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
var atomFamily = (defaultValue, debugLabel) => {
|
|
71
|
-
const map = new Map;
|
|
72
|
-
const atomFamily2 = (key, defaultOverride) => {
|
|
73
|
-
const keyStringified = stableStringify(key);
|
|
74
|
-
if (map.has(keyStringified)) {
|
|
75
|
-
return map.get(keyStringified);
|
|
83
|
+
var equal = (a, b) => {
|
|
84
|
+
try {
|
|
85
|
+
return deepEqualFn(a, b);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
if ((error.message || "").match(/stack|recursion/i)) {
|
|
88
|
+
console.warn("react-fast-compare cannot handle circular refs");
|
|
89
|
+
return false;
|
|
76
90
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
label: atomDebugLabel
|
|
80
|
-
});
|
|
81
|
-
newAtom.family = atomFamily2;
|
|
82
|
-
newAtom.familyKey = Object.freeze(key);
|
|
83
|
-
map.set(keyStringified, newAtom);
|
|
84
|
-
return newAtom;
|
|
85
|
-
};
|
|
86
|
-
atomFamily2._map = map;
|
|
87
|
-
return atomFamily2;
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
88
93
|
};
|
|
89
|
-
// src/lib/createStoreData.ts
|
|
90
|
-
var generateId = () => (Math.random() + 1).toString(36).substring(7);
|
|
91
|
-
var createStoreData = (id = generateId()) => ({
|
|
92
|
-
id,
|
|
93
|
-
values: new WeakMap,
|
|
94
|
-
expiredValues: new WeakMap,
|
|
95
|
-
subscriptions: new WeakMap,
|
|
96
|
-
subscriptionsRequireEqualCheck: new WeakMap,
|
|
97
|
-
stateConsumers: new WeakMap,
|
|
98
|
-
stateDependencies: new WeakMap
|
|
99
|
-
});
|
|
100
94
|
|
|
101
95
|
// src/utils/isAtom.ts
|
|
102
96
|
var isAtom = (state) => Object.hasOwn(state, "defaultValue");
|
|
103
97
|
|
|
104
|
-
// src/
|
|
105
|
-
|
|
98
|
+
// src/utils/isFamilyState.ts
|
|
99
|
+
var isFamilyState = (state) => state && Object.hasOwn(state, "family");
|
|
100
|
+
|
|
101
|
+
// src/utils/isFamilyAtom.ts
|
|
102
|
+
var isFamilyAtom = (state) => isFamilyState(state) && isAtom(state);
|
|
106
103
|
|
|
107
104
|
// src/lib/updateStateSubscribers.ts
|
|
108
105
|
var updateStateSubscribers = (state, data) => {
|
|
@@ -112,7 +109,7 @@ var updateStateSubscribers = (state, data) => {
|
|
|
112
109
|
subscribtion.callback();
|
|
113
110
|
}
|
|
114
111
|
}
|
|
115
|
-
if (state
|
|
112
|
+
if (isFamilyState(state)) {
|
|
116
113
|
const familySubscriptions = data.subscriptions.get(state.family);
|
|
117
114
|
if (familySubscriptions?.size) {
|
|
118
115
|
for (const subscribtion of familySubscriptions) {
|
|
@@ -122,11 +119,206 @@ var updateStateSubscribers = (state, data) => {
|
|
|
122
119
|
}
|
|
123
120
|
};
|
|
124
121
|
|
|
125
|
-
// src/
|
|
126
|
-
|
|
122
|
+
// src/utils/isPromiseLike.ts
|
|
123
|
+
var isPromiseLike = (object) => {
|
|
124
|
+
return object && object.then && typeof object.then === "function";
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// src/utils/isAtomFamily.ts
|
|
128
|
+
var isAtomFamily = (state) => state && Object.hasOwn(state, "__valdresAtomFamilyMap");
|
|
129
|
+
|
|
130
|
+
// src/utils/isSelector.ts
|
|
131
|
+
var isSelector = (state) => state && Object.hasOwn(state, "get");
|
|
132
|
+
|
|
133
|
+
// src/utils/isSelectorFamily.ts
|
|
134
|
+
var isSelectorFamily = (state) => state && Object.hasOwn(state, "__valdresSelectorFamilyMap");
|
|
135
|
+
|
|
136
|
+
// src/lib/isFunction.ts
|
|
137
|
+
var isFunction = (value) => typeof value === "function";
|
|
138
|
+
|
|
139
|
+
// src/utils/deepFreeze.ts
|
|
140
|
+
var deepFreeze = (obj, seen = new WeakSet) => {
|
|
141
|
+
if (seen.has(obj))
|
|
142
|
+
return obj;
|
|
143
|
+
if (obj && typeof obj === "object")
|
|
144
|
+
seen.add(obj);
|
|
145
|
+
if (Array.isArray(obj)) {
|
|
146
|
+
for (const item of obj) {
|
|
147
|
+
if (item && typeof item === "object") {
|
|
148
|
+
deepFreeze(item, seen);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
const propNames = Object.getOwnPropertyNames(obj);
|
|
153
|
+
for (const name of propNames) {
|
|
154
|
+
const value = obj[name];
|
|
155
|
+
if (value && typeof value === "object") {
|
|
156
|
+
deepFreeze(value, seen);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return Object.freeze(obj);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// src/lib/setValueInData.ts
|
|
164
|
+
var isProd = true;
|
|
165
|
+
var setValueInData = (atom, value, data) => {
|
|
166
|
+
if (isProd) {
|
|
167
|
+
data.values.set(atom, value);
|
|
168
|
+
return value;
|
|
169
|
+
} else {
|
|
170
|
+
const frozenValue = deepFreeze(value);
|
|
171
|
+
data.values.set(atom, frozenValue);
|
|
172
|
+
return frozenValue;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/lib/setAtom.ts
|
|
177
|
+
var setAtom = (atom, newValue, data, skipOnSet = false) => {
|
|
178
|
+
const currentValue = getState(atom, data);
|
|
179
|
+
if (isFunction(newValue)) {
|
|
180
|
+
newValue = newValue(currentValue);
|
|
181
|
+
if (isPromiseLike(newValue) || isPromiseLike(currentValue))
|
|
182
|
+
throw new Error("Todo, how should we handle this?");
|
|
183
|
+
}
|
|
184
|
+
if (atom.equal(currentValue, newValue))
|
|
185
|
+
return newValue;
|
|
186
|
+
newValue = setValueInData(atom, newValue, data);
|
|
187
|
+
if (atom.onSet && !skipOnSet)
|
|
188
|
+
atom.onSet(newValue, data);
|
|
189
|
+
if (currentValue?.__isEmptyAtomPromise__) {
|
|
190
|
+
currentValue.__resolveEmptyAtomPromise__(newValue);
|
|
191
|
+
}
|
|
192
|
+
propagateUpdatedAtoms([atom], data);
|
|
193
|
+
return newValue;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// src/lib/initAtom.ts
|
|
197
|
+
var getAtomInitValue = (atom, data) => {
|
|
198
|
+
if (atom.defaultValue === undefined) {
|
|
199
|
+
let promiseResolve;
|
|
200
|
+
const promise = new Promise((resolve) => {
|
|
201
|
+
promiseResolve = resolve;
|
|
202
|
+
});
|
|
203
|
+
promise.__isEmptyAtomPromise__ = true;
|
|
204
|
+
promise.__resolveEmptyAtomPromise__ = promiseResolve;
|
|
205
|
+
return promise;
|
|
206
|
+
} else if (typeof atom.defaultValue === "function") {
|
|
207
|
+
const value = atom.defaultValue();
|
|
208
|
+
if (isPromiseLike(value)) {
|
|
209
|
+
value.then((resolvedValue) => {
|
|
210
|
+
setValueInData(atom, resolvedValue, data);
|
|
211
|
+
propagateUpdatedAtoms([atom], data);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return value;
|
|
215
|
+
} else if (isSelector(atom.defaultValue)) {
|
|
216
|
+
return getState(atom.defaultValue, data);
|
|
217
|
+
} else {
|
|
218
|
+
return atom.defaultValue;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
var initAtom = (atom, data) => {
|
|
222
|
+
const tmpVal = getAtomInitValue(atom, data);
|
|
223
|
+
let value = setValueInData(atom, tmpVal, data);
|
|
224
|
+
if (isFamilyAtom(atom)) {
|
|
225
|
+
const currentKeySet = getState(atom.family.__keysAtom, data);
|
|
226
|
+
if (!currentKeySet.has(atom.familyKey)) {
|
|
227
|
+
const newSet = new Set(currentKeySet);
|
|
228
|
+
newSet.add(atom.familyKey);
|
|
229
|
+
setAtom(atom.family.__keysAtom, newSet, data);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (atom.onInit)
|
|
233
|
+
atom.onInit((newVal) => {
|
|
234
|
+
value = newVal;
|
|
235
|
+
setAtom(atom, newVal, data, true);
|
|
236
|
+
}, data);
|
|
237
|
+
return value;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// src/lib/getState.ts
|
|
241
|
+
function getState(state, data, circularDependencySet) {
|
|
242
|
+
if (data.values.has(state))
|
|
243
|
+
return data.values.get(state);
|
|
244
|
+
if (isAtom(state)) {
|
|
245
|
+
if ("parent" in data)
|
|
246
|
+
return getState(state, data.parent, circularDependencySet);
|
|
247
|
+
return initAtom(state, data);
|
|
248
|
+
}
|
|
249
|
+
if (isSelector(state))
|
|
250
|
+
return initSelector(state, data, circularDependencySet);
|
|
251
|
+
if (isAtomFamily(state)) {
|
|
252
|
+
if ("parent" in data) {
|
|
253
|
+
const closestData = findClosestStoreWithAtomInitialized(state.__keysAtom, data);
|
|
254
|
+
return getState(state.__keysSelector, closestData, circularDependencySet);
|
|
255
|
+
}
|
|
256
|
+
return getState(state.__keysSelector, data, circularDependencySet);
|
|
257
|
+
}
|
|
258
|
+
if (isSelectorFamily(state)) {
|
|
259
|
+
const array = Array.from(state.__valdresSelectorFamilyMap.keys());
|
|
260
|
+
if (equal(array, state._keyArray))
|
|
261
|
+
return state._keyArray;
|
|
262
|
+
state._keyArray = array;
|
|
263
|
+
return array;
|
|
264
|
+
}
|
|
265
|
+
throw new Error("Invalid object passed to get");
|
|
266
|
+
}
|
|
267
|
+
var findClosestStoreWithAtomInitialized = (atom, data) => {
|
|
268
|
+
if ("parent" in data === false)
|
|
269
|
+
return data;
|
|
270
|
+
if (data.values.has(atom))
|
|
271
|
+
return data;
|
|
272
|
+
return findClosestStoreWithAtomInitialized(atom, data.parent);
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// src/errors/lib/generateSelectorTrace.ts
|
|
276
|
+
var generateSelectorTrace = (selectors) => {
|
|
277
|
+
const lastIndex = selectors.length - 1;
|
|
278
|
+
return [...selectors].reverse().map((selector, index) => {
|
|
279
|
+
const name = selector.name ?? "Anonymous Selector";
|
|
280
|
+
if (index === 0) {
|
|
281
|
+
return `[START] ${name}`;
|
|
282
|
+
} else if (index === lastIndex) {
|
|
283
|
+
return `[CRASH] ${name}`;
|
|
284
|
+
} else {
|
|
285
|
+
return ` ${" ".repeat(index)}${name}`;
|
|
286
|
+
}
|
|
287
|
+
}).join(`
|
|
288
|
+
`);
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// src/errors/SelectorEvaluationError.ts
|
|
292
|
+
class SelectorEvaluationError extends Error {
|
|
293
|
+
selectors;
|
|
294
|
+
constructor(cause) {
|
|
295
|
+
super();
|
|
296
|
+
this.cause = cause;
|
|
297
|
+
this.selectors = [];
|
|
298
|
+
}
|
|
299
|
+
track(selector) {
|
|
300
|
+
this.selectors.push(selector);
|
|
301
|
+
}
|
|
302
|
+
get message() {
|
|
303
|
+
const firstSelectorName = this.selectors[0].name ?? "Anonymous Selector";
|
|
304
|
+
return `Selector eval crashed in '${firstSelectorName}'
|
|
305
|
+
${generateSelectorTrace(this.selectors)}`;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/errors/SelectorCircularDependencyError.ts
|
|
310
|
+
class SelectorCircularDependencyError extends SelectorEvaluationError {
|
|
311
|
+
constructor() {
|
|
312
|
+
super();
|
|
313
|
+
}
|
|
314
|
+
get message() {
|
|
315
|
+
const firstSelectorName = this.selectors[0].name ?? "Anonymous Selector";
|
|
316
|
+
return `Circular dependency detected in '${firstSelectorName}'
|
|
317
|
+
${generateSelectorTrace(this.selectors)}`;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
127
320
|
|
|
128
321
|
// src/lib/initSelector.ts
|
|
129
|
-
import equal from "fast-deep-equal";
|
|
130
322
|
class SuspendAndWaitForResolveError extends Error {
|
|
131
323
|
promise;
|
|
132
324
|
constructor(promise) {
|
|
@@ -142,25 +334,31 @@ var getOrInitConsumersSet = (state, data) => {
|
|
|
142
334
|
data.stateConsumers.set(state, newSet);
|
|
143
335
|
return newSet;
|
|
144
336
|
};
|
|
145
|
-
var evaluateSelector = (selector, data) => {
|
|
146
|
-
const currentDependencies = data.stateDependencies.get(selector) ?? new Set;
|
|
337
|
+
var evaluateSelector = (selector, data, circularDependencyMap = new WeakSet) => {
|
|
147
338
|
const updatedDependencies = new Set;
|
|
339
|
+
if (circularDependencyMap.has(selector)) {
|
|
340
|
+
throw new SelectorCircularDependencyError;
|
|
341
|
+
}
|
|
342
|
+
circularDependencyMap.add(selector);
|
|
148
343
|
let result;
|
|
149
344
|
try {
|
|
150
345
|
result = selector.get((state) => {
|
|
151
|
-
const value = getState(state, data);
|
|
346
|
+
const value = getState(state, data, circularDependencyMap);
|
|
152
347
|
updatedDependencies.add(state);
|
|
153
348
|
if (isPromiseLike(value))
|
|
154
349
|
throw new SuspendAndWaitForResolveError(value);
|
|
155
350
|
return value;
|
|
156
|
-
});
|
|
351
|
+
}, data.id);
|
|
157
352
|
} catch (error) {
|
|
158
353
|
if (error instanceof SuspendAndWaitForResolveError) {
|
|
159
354
|
result = error;
|
|
160
|
-
} else {
|
|
355
|
+
} else if (error instanceof SelectorEvaluationError) {
|
|
161
356
|
throw error;
|
|
357
|
+
} else {
|
|
358
|
+
throw new SelectorEvaluationError(error);
|
|
162
359
|
}
|
|
163
360
|
}
|
|
361
|
+
const currentDependencies = data.stateDependencies.get(selector) ?? new Set;
|
|
164
362
|
const added = updatedDependencies?.difference(currentDependencies);
|
|
165
363
|
const removed = currentDependencies?.difference(updatedDependencies);
|
|
166
364
|
for (const state of added) {
|
|
@@ -180,7 +378,7 @@ var handleSelectorResult = (value, selector, data) => {
|
|
|
180
378
|
return value.promise;
|
|
181
379
|
} else if (isPromiseLike(value)) {
|
|
182
380
|
value.then((resolved) => {
|
|
183
|
-
|
|
381
|
+
setValueInData(selector, resolved, data);
|
|
184
382
|
updateStateSubscribers(selector, data);
|
|
185
383
|
console.log("Should we reEvaluate?");
|
|
186
384
|
});
|
|
@@ -189,18 +387,23 @@ var handleSelectorResult = (value, selector, data) => {
|
|
|
189
387
|
return value;
|
|
190
388
|
}
|
|
191
389
|
};
|
|
192
|
-
var initSelector = (selector, data) => {
|
|
193
|
-
|
|
390
|
+
var initSelector = (selector, data, circularDependencySet = new WeakSet) => {
|
|
391
|
+
let tmpValue;
|
|
392
|
+
try {
|
|
393
|
+
tmpValue = evaluateSelector(selector, data, circularDependencySet);
|
|
394
|
+
} catch (e) {
|
|
395
|
+
if (e instanceof SelectorEvaluationError)
|
|
396
|
+
e.track(selector);
|
|
397
|
+
throw e;
|
|
398
|
+
}
|
|
194
399
|
const value = handleSelectorResult(tmpValue, selector, data);
|
|
195
400
|
if (data.expiredValues.has(selector)) {
|
|
196
401
|
const expiredValue = data.expiredValues.get(selector);
|
|
197
|
-
if (equal(expiredValue, value)) {
|
|
198
|
-
|
|
199
|
-
return expiredValue;
|
|
402
|
+
if (selector.equal(expiredValue, value)) {
|
|
403
|
+
return setValueInData(selector, expiredValue, data);
|
|
200
404
|
}
|
|
201
405
|
}
|
|
202
|
-
|
|
203
|
-
return value;
|
|
406
|
+
return setValueInData(selector, value, data);
|
|
204
407
|
};
|
|
205
408
|
|
|
206
409
|
// src/lib/updateSelectorSubscribers.ts
|
|
@@ -213,7 +416,7 @@ var updateSelectorSubscribers = (selector, data) => {
|
|
|
213
416
|
try {
|
|
214
417
|
const oldValue = data.expiredValues.get(selector);
|
|
215
418
|
const newValue = initSelector(selector, data);
|
|
216
|
-
if (
|
|
419
|
+
if (selector.equal(newValue, oldValue))
|
|
217
420
|
return;
|
|
218
421
|
} catch (e) {
|
|
219
422
|
}
|
|
@@ -246,13 +449,13 @@ var recursivlyResetSelectorTree = (selectors, data, clearedSelectors) => {
|
|
|
246
449
|
};
|
|
247
450
|
var propagateUpdatedAtoms = (atoms, data) => {
|
|
248
451
|
const clearedSelectors = new Set;
|
|
249
|
-
for (const
|
|
250
|
-
const consumers = data.stateConsumers.get(
|
|
452
|
+
for (const atom of atoms) {
|
|
453
|
+
const consumers = data.stateConsumers.get(atom);
|
|
251
454
|
if (consumers && consumers.size) {
|
|
252
455
|
recursivlyResetSelectorTree(consumers, data, clearedSelectors);
|
|
253
456
|
}
|
|
254
|
-
if (
|
|
255
|
-
const consumersFamily = data.stateConsumers.get(
|
|
457
|
+
if (isFamilyAtom(atom)) {
|
|
458
|
+
const consumersFamily = data.stateConsumers.get(atom.family);
|
|
256
459
|
if (consumersFamily?.size) {
|
|
257
460
|
recursivlyResetSelectorTree(consumersFamily, data, clearedSelectors);
|
|
258
461
|
}
|
|
@@ -261,98 +464,52 @@ var propagateUpdatedAtoms = (atoms, data) => {
|
|
|
261
464
|
for (const selector of clearedSelectors) {
|
|
262
465
|
updateSelectorSubscribers(selector, data);
|
|
263
466
|
}
|
|
264
|
-
for (const
|
|
265
|
-
updateStateSubscribers(
|
|
467
|
+
for (const atom of atoms) {
|
|
468
|
+
updateStateSubscribers(atom, data);
|
|
266
469
|
}
|
|
267
470
|
};
|
|
268
471
|
|
|
269
|
-
// src/lib/
|
|
270
|
-
|
|
271
|
-
var
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
currentValue.__resolveEmptyAtomPromise__(newValue);
|
|
283
|
-
}
|
|
284
|
-
propagateUpdatedAtoms([atom2], data);
|
|
472
|
+
// src/lib/createStoreData.ts
|
|
473
|
+
var generateId = () => (Math.random() + 1).toString(36).substring(7);
|
|
474
|
+
var generateStoreData = (id = generateId()) => {
|
|
475
|
+
return {
|
|
476
|
+
id,
|
|
477
|
+
values: new WeakMap,
|
|
478
|
+
expiredValues: new WeakMap,
|
|
479
|
+
subscriptions: new WeakMap,
|
|
480
|
+
subscriptionsRequireEqualCheck: new WeakMap,
|
|
481
|
+
stateConsumers: new WeakMap,
|
|
482
|
+
stateDependencies: new WeakMap,
|
|
483
|
+
scopes: {}
|
|
484
|
+
};
|
|
285
485
|
};
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
});
|
|
294
|
-
promise.__isEmptyAtomPromise__ = true;
|
|
295
|
-
promise.__resolveEmptyAtomPromise__ = promiseResolve;
|
|
296
|
-
return promise;
|
|
297
|
-
} else if (typeof atom2.defaultValue === "function") {
|
|
298
|
-
const value = atom2.defaultValue();
|
|
299
|
-
if (isPromiseLike(value)) {
|
|
300
|
-
value.then((resolvedValue) => {
|
|
301
|
-
data.values.set(atom2, resolvedValue);
|
|
302
|
-
propagateUpdatedAtoms([atom2], data);
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
return value;
|
|
486
|
+
function createStoreData(id, parent) {
|
|
487
|
+
if (parent) {
|
|
488
|
+
return {
|
|
489
|
+
...generateStoreData(id),
|
|
490
|
+
parent,
|
|
491
|
+
scopeConsumers: parent ? new Set : undefined
|
|
492
|
+
};
|
|
306
493
|
} else {
|
|
307
|
-
return
|
|
494
|
+
return generateStoreData(id);
|
|
308
495
|
}
|
|
309
|
-
};
|
|
310
|
-
var initAtom = (atom2, data) => {
|
|
311
|
-
let value = getAtomInitValue(atom2, data);
|
|
312
|
-
data.values.set(atom2, value);
|
|
313
|
-
if (atom2.onInit)
|
|
314
|
-
atom2.onInit((newVal) => {
|
|
315
|
-
value = newVal;
|
|
316
|
-
setAtom(atom2, newVal, data);
|
|
317
|
-
});
|
|
318
|
-
return value;
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
// src/utils/isSelector.ts
|
|
322
|
-
var isSelector = (state) => Object.hasOwn(state, "get");
|
|
323
|
-
|
|
324
|
-
// src/utils/isFamily.ts
|
|
325
|
-
var isFamily = (state) => Object.hasOwn(state, "_map");
|
|
326
|
-
|
|
327
|
-
// src/lib/getState.ts
|
|
328
|
-
function getState(state, data) {
|
|
329
|
-
if (data.values.has(state))
|
|
330
|
-
return data.values.get(state);
|
|
331
|
-
if (isAtom(state))
|
|
332
|
-
return initAtom(state, data);
|
|
333
|
-
if (isSelector(state))
|
|
334
|
-
return initSelector(state, data);
|
|
335
|
-
if (isFamily(state)) {
|
|
336
|
-
const array = Array.from(state._map.keys());
|
|
337
|
-
if (equal4(array, state._keyArray))
|
|
338
|
-
return state._keyArray;
|
|
339
|
-
state._keyArray = array;
|
|
340
|
-
return array;
|
|
341
|
-
}
|
|
342
|
-
throw new Error("Invalid object passed to get");
|
|
343
496
|
}
|
|
344
497
|
|
|
345
498
|
// src/lib/resetAtom.ts
|
|
346
|
-
var resetAtom = (
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
499
|
+
var resetAtom = (atom, data) => {
|
|
500
|
+
let value = getAtomInitValue(atom, data);
|
|
501
|
+
setValueInData(atom, value, data);
|
|
502
|
+
if (!isPromiseLike(value)) {
|
|
503
|
+
propagateUpdatedAtoms([atom], data);
|
|
350
504
|
}
|
|
351
|
-
return
|
|
505
|
+
return value;
|
|
352
506
|
};
|
|
353
507
|
|
|
508
|
+
// src/utils/isFamily.ts
|
|
509
|
+
var isFamily = (state) => isAtomFamily(state) || isSelectorFamily(state);
|
|
510
|
+
|
|
354
511
|
// src/lib/unsubscribe.ts
|
|
355
|
-
var unsubscribe = (state, subscription, data, mount) => {
|
|
512
|
+
var unsubscribe = (state, subscription, data, mount, maxAgeCleanup) => {
|
|
356
513
|
const subscribers = data.subscriptions.get(state);
|
|
357
514
|
if (subscribers) {
|
|
358
515
|
subscribers.delete(subscription);
|
|
@@ -368,6 +525,11 @@ var unsubscribe = (state, subscription, data, mount) => {
|
|
|
368
525
|
data.subscriptionsRequireEqualCheck.delete(state);
|
|
369
526
|
}
|
|
370
527
|
}
|
|
528
|
+
if (subscribers.size === 0) {
|
|
529
|
+
if (maxAgeCleanup)
|
|
530
|
+
maxAgeCleanup();
|
|
531
|
+
data.subscriptions.delete(state);
|
|
532
|
+
}
|
|
371
533
|
if (mount) {
|
|
372
534
|
if (subscribers.size === mount.mountSubscriptions.size) {
|
|
373
535
|
if (typeof mount.onUnmount === "function") {
|
|
@@ -385,10 +547,24 @@ var initSubscribers = (state, data) => {
|
|
|
385
547
|
return set;
|
|
386
548
|
};
|
|
387
549
|
var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) => {
|
|
388
|
-
|
|
550
|
+
let parentUnsubscribe;
|
|
551
|
+
if ("parent" in data && (!data.values.has(state) && isAtom(state) || isAtomFamily(state))) {
|
|
552
|
+
const originalCallback = callback;
|
|
553
|
+
parentUnsubscribe = subscribe(state, originalCallback, requireDeepEqualCheckBeforeCallback, data.parent);
|
|
554
|
+
callback = (arg) => {
|
|
555
|
+
if (parentUnsubscribe) {
|
|
556
|
+
parentUnsubscribe();
|
|
557
|
+
parentUnsubscribe = undefined;
|
|
558
|
+
}
|
|
559
|
+
originalCallback(arg);
|
|
560
|
+
};
|
|
561
|
+
} else if (!data.values.has(state) && isAtom(state)) {
|
|
562
|
+
initAtom(state, data);
|
|
563
|
+
}
|
|
389
564
|
if (isSelector(state) && !data.values.has(state)) {
|
|
390
565
|
initSelector(state, data);
|
|
391
566
|
}
|
|
567
|
+
const subscribers = data.subscriptions.get(state) || initSubscribers(state, data);
|
|
392
568
|
let subscription;
|
|
393
569
|
if (isFamily(state)) {
|
|
394
570
|
subscription = {
|
|
@@ -404,34 +580,67 @@ var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) =>
|
|
|
404
580
|
}
|
|
405
581
|
subscribers.add(subscription);
|
|
406
582
|
let mount;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
583
|
+
let maxAgeCleanup;
|
|
584
|
+
if (subscribers.size === 1) {
|
|
585
|
+
if (isAtom(state) && state.maxAge) {
|
|
586
|
+
let timeout;
|
|
587
|
+
const interval = setInterval(() => {
|
|
588
|
+
let value = getAtomInitValue(state, data);
|
|
589
|
+
if (isPromiseLike(value)) {
|
|
590
|
+
if (state.staleWhileRevalidate) {
|
|
591
|
+
const oldValue = data.values.get(state);
|
|
592
|
+
timeout = setTimeout(() => {
|
|
593
|
+
const nowValue = data.values.get(state);
|
|
594
|
+
console.log("todo", oldValue);
|
|
595
|
+
}, state.staleWhileRevalidate);
|
|
596
|
+
value.then((res) => clearTimeout(timeout));
|
|
597
|
+
}
|
|
598
|
+
} else {
|
|
599
|
+
setValueInData(state, value, data);
|
|
600
|
+
propagateUpdatedAtoms([state], data);
|
|
601
|
+
}
|
|
602
|
+
}, state.maxAge);
|
|
603
|
+
maxAgeCleanup = () => {
|
|
604
|
+
clearInterval(interval);
|
|
605
|
+
if (timeout)
|
|
606
|
+
clearTimeout(timeout);
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
if (state.onMount) {
|
|
610
|
+
const store = storeFromStoreData(data);
|
|
611
|
+
const mountSubscriptions = new Set;
|
|
612
|
+
const originalSub = store.sub;
|
|
613
|
+
store.sub = (state2, callback2) => {
|
|
614
|
+
mountSubscriptions.add(callback2);
|
|
615
|
+
return originalSub(state2, callback2);
|
|
616
|
+
};
|
|
617
|
+
mount = {
|
|
618
|
+
onUnmount: state.onMount(store, state),
|
|
619
|
+
mountSubscriptions
|
|
620
|
+
};
|
|
621
|
+
}
|
|
419
622
|
}
|
|
420
623
|
if (requireDeepEqualCheckBeforeCallback && data.subscriptionsRequireEqualCheck.get(state) !== true) {
|
|
421
624
|
data.subscriptionsRequireEqualCheck.set(state, true);
|
|
422
625
|
}
|
|
423
|
-
return () =>
|
|
626
|
+
return () => {
|
|
627
|
+
if (parentUnsubscribe) {
|
|
628
|
+
parentUnsubscribe();
|
|
629
|
+
}
|
|
630
|
+
unsubscribe(state, subscription, data, mount, maxAgeCleanup);
|
|
631
|
+
};
|
|
424
632
|
};
|
|
425
633
|
|
|
426
634
|
// src/lib/setAtoms.ts
|
|
427
|
-
import equal5 from "fast-deep-equal";
|
|
428
635
|
var setAtoms = (pairs, data) => {
|
|
429
636
|
const updatedAtoms = [];
|
|
430
|
-
for (let [
|
|
431
|
-
const currentValue = getState(
|
|
432
|
-
if (!
|
|
433
|
-
updatedAtoms.push(
|
|
434
|
-
|
|
637
|
+
for (let [atom, value] of pairs) {
|
|
638
|
+
const currentValue = getState(atom, data);
|
|
639
|
+
if (!atom.equal(currentValue, value)) {
|
|
640
|
+
updatedAtoms.push(atom);
|
|
641
|
+
if (atom.onSet)
|
|
642
|
+
atom.onSet(value, data);
|
|
643
|
+
setValueInData(atom, value, data);
|
|
435
644
|
}
|
|
436
645
|
}
|
|
437
646
|
propagateUpdatedAtoms(updatedAtoms, data);
|
|
@@ -458,14 +667,36 @@ var recursivlyResetTxnSelectorCache = (state, txnSubscribers, txnSelectorCache)
|
|
|
458
667
|
}
|
|
459
668
|
}
|
|
460
669
|
};
|
|
461
|
-
var
|
|
462
|
-
let
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
670
|
+
var captureScopedTransaction = (scopedData, parentGetFromTxnOrData) => {
|
|
671
|
+
let txn;
|
|
672
|
+
transaction((scopedTxn) => {
|
|
673
|
+
txn = scopedTxn;
|
|
674
|
+
}, scopedData, false, parentGetFromTxnOrData);
|
|
675
|
+
return txn;
|
|
676
|
+
};
|
|
677
|
+
var transaction = (callback, data, autoCommit = true, parentGetFromTxnOrData) => {
|
|
678
|
+
const txnAtomMap = new Map;
|
|
679
|
+
const txnSelectorCache = new Map;
|
|
680
|
+
const txnSubscribers = new Map;
|
|
681
|
+
const dirtySelectors = new Set;
|
|
682
|
+
let scopedTransactions;
|
|
683
|
+
const getFromTxnOrData = (state) => {
|
|
684
|
+
if (txnAtomMap.has(state)) {
|
|
685
|
+
return txnAtomMap.get(state);
|
|
686
|
+
}
|
|
687
|
+
if (data.values.has(state)) {
|
|
688
|
+
return data.values.get(state);
|
|
689
|
+
}
|
|
690
|
+
if (parentGetFromTxnOrData) {
|
|
691
|
+
return parentGetFromTxnOrData(state);
|
|
692
|
+
}
|
|
693
|
+
};
|
|
466
694
|
const txnGet = (state) => {
|
|
467
695
|
if (isAtom(state)) {
|
|
468
|
-
|
|
696
|
+
const value = getFromTxnOrData(state);
|
|
697
|
+
if (value)
|
|
698
|
+
return value;
|
|
699
|
+
return getState(state, data);
|
|
469
700
|
} else if (isSelector(state)) {
|
|
470
701
|
if (txnSelectorCache.has(state)) {
|
|
471
702
|
return txnSelectorCache.get(state);
|
|
@@ -474,7 +705,7 @@ var transaction = (callback, data) => {
|
|
|
474
705
|
const res = state.get((s) => {
|
|
475
706
|
deps.add(s);
|
|
476
707
|
return txnGet(s);
|
|
477
|
-
});
|
|
708
|
+
}, data.id);
|
|
478
709
|
for (const dep of deps) {
|
|
479
710
|
if (!txnSubscribers.has(dep)) {
|
|
480
711
|
txnSubscribers.set(dep, new Set);
|
|
@@ -483,127 +714,468 @@ var transaction = (callback, data) => {
|
|
|
483
714
|
}
|
|
484
715
|
txnSelectorCache.set(state, res);
|
|
485
716
|
return res;
|
|
717
|
+
} else if (isAtomFamily(state)) {
|
|
718
|
+
return txnGet(state.__keysSelector);
|
|
486
719
|
} else {
|
|
487
720
|
throw new Error("Unsupported state");
|
|
488
721
|
}
|
|
489
722
|
};
|
|
490
|
-
const txnSet = (
|
|
491
|
-
if (!isAtom(
|
|
723
|
+
const txnSet = (atom, value) => {
|
|
724
|
+
if (!isAtom(atom))
|
|
492
725
|
throw new Error("Not an atom");
|
|
493
|
-
if (
|
|
494
|
-
const currentValue = txnGet(
|
|
726
|
+
if (isFunction(value)) {
|
|
727
|
+
const currentValue = txnGet(atom);
|
|
495
728
|
value = value(currentValue);
|
|
496
729
|
}
|
|
497
|
-
for (const selector of findDependencies(
|
|
730
|
+
for (const selector of findDependencies(atom, data)) {
|
|
498
731
|
dirtySelectors.add(selector);
|
|
499
732
|
txnSelectorCache.delete(selector);
|
|
500
733
|
}
|
|
501
|
-
if (txnSubscribers.get(
|
|
502
|
-
recursivlyResetTxnSelectorCache(
|
|
734
|
+
if (txnSubscribers.get(atom)?.size) {
|
|
735
|
+
recursivlyResetTxnSelectorCache(atom, txnSubscribers, txnSelectorCache);
|
|
503
736
|
}
|
|
504
|
-
txnAtomMap.set(
|
|
737
|
+
txnAtomMap.set(atom, value);
|
|
738
|
+
if (isFamilyAtom(atom)) {
|
|
739
|
+
const currentKeySet = txnGet(atom.family.__keysAtom);
|
|
740
|
+
if (!currentKeySet.has(atom.familyKey)) {
|
|
741
|
+
const newSet = new Set(currentKeySet);
|
|
742
|
+
newSet.add(atom.familyKey);
|
|
743
|
+
txnSet(atom.family.__keysAtom, newSet);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
return value;
|
|
505
747
|
};
|
|
506
|
-
const txnReset = (
|
|
507
|
-
const value = getAtomInitValue(
|
|
508
|
-
txnAtomMap.set(
|
|
748
|
+
const txnReset = (atom) => {
|
|
749
|
+
const value = getAtomInitValue(atom, data);
|
|
750
|
+
txnAtomMap.set(atom, value);
|
|
509
751
|
return value;
|
|
510
752
|
};
|
|
511
753
|
const commit = () => {
|
|
512
754
|
setAtoms(txnAtomMap, data);
|
|
513
755
|
dirtySelectors.clear();
|
|
756
|
+
if (scopedTransactions) {
|
|
757
|
+
for (const scopedTxn of Object.values(scopedTransactions)) {
|
|
758
|
+
scopedTxn.commit();
|
|
759
|
+
}
|
|
760
|
+
}
|
|
514
761
|
};
|
|
515
|
-
const result = callback(
|
|
516
|
-
|
|
762
|
+
const result = callback({
|
|
763
|
+
set: txnSet,
|
|
764
|
+
get: txnGet,
|
|
765
|
+
reset: txnReset,
|
|
766
|
+
commit,
|
|
767
|
+
scope: (scopeId, callback2) => {
|
|
768
|
+
if (scopeId in data.scopes) {
|
|
769
|
+
const scopedData = data.scopes[scopeId];
|
|
770
|
+
if (scopedTransactions === undefined) {
|
|
771
|
+
scopedTransactions = {};
|
|
772
|
+
}
|
|
773
|
+
if (scopedTransactions[scopeId] === undefined) {
|
|
774
|
+
scopedTransactions[scopeId] = captureScopedTransaction(scopedData, getFromTxnOrData);
|
|
775
|
+
}
|
|
776
|
+
return callback2(scopedTransactions[scopeId]);
|
|
777
|
+
} else {
|
|
778
|
+
throw new Error(`Scope '${scopeId}' not found. Registered scopes: ${Object.keys(data.scopes).join(", ")}`);
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
data
|
|
782
|
+
});
|
|
783
|
+
if (autoCommit)
|
|
784
|
+
commit();
|
|
517
785
|
return result;
|
|
518
786
|
};
|
|
519
787
|
|
|
520
788
|
// src/lib/storeFromStoreData.ts
|
|
521
|
-
var
|
|
789
|
+
var SelectorProvidedToSetError = `Invalid state object passed to set().
|
|
790
|
+
You provided a \`selector\`.
|
|
791
|
+
Only \`atom\` cam be set.
|
|
792
|
+
`;
|
|
793
|
+
var InvalidStateSetError = `Invalid state object passed to set().
|
|
794
|
+
Only \`atom\` can be set.
|
|
795
|
+
`;
|
|
796
|
+
function storeFromStoreData(data, detach) {
|
|
522
797
|
const get = (state) => getState(state, data);
|
|
523
798
|
const set = (state, value) => {
|
|
524
|
-
if (
|
|
525
|
-
|
|
526
|
-
|
|
799
|
+
if (isAtom(state))
|
|
800
|
+
return setAtom(state, value, data);
|
|
801
|
+
if (isSelector(state))
|
|
802
|
+
throw new Error(SelectorProvidedToSetError);
|
|
803
|
+
throw new Error(InvalidStateSetError);
|
|
527
804
|
};
|
|
528
|
-
const reset = (
|
|
805
|
+
const reset = (atom) => resetAtom(atom, data);
|
|
529
806
|
const sub = (state, callback, deepEqualCheckBeforeCallback = true) => subscribe(state, callback, deepEqualCheckBeforeCallback, data);
|
|
530
807
|
const txn = (callback) => transaction(callback, data);
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
808
|
+
const scope = (scopeId) => {
|
|
809
|
+
let scopedStoreData;
|
|
810
|
+
if (scopeId in data.scopes) {
|
|
811
|
+
scopedStoreData = data.scopes[scopeId];
|
|
812
|
+
} else {
|
|
813
|
+
scopedStoreData = createStoreData(scopeId, data);
|
|
814
|
+
data.scopes[scopeId] = scopedStoreData;
|
|
815
|
+
}
|
|
816
|
+
const detach2 = () => {
|
|
817
|
+
scopedStoreData.scopeConsumers.delete(detach2);
|
|
818
|
+
if (scopedStoreData.scopeConsumers.size === 0) {
|
|
819
|
+
delete data.scopes[scopeId];
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
scopedStoreData.scopeConsumers.add(detach2);
|
|
823
|
+
const newStore = storeFromStoreData(data.scopes[scopeId], detach2);
|
|
824
|
+
return newStore;
|
|
538
825
|
};
|
|
539
|
-
|
|
826
|
+
if (detach) {
|
|
827
|
+
return {
|
|
828
|
+
get,
|
|
829
|
+
set,
|
|
830
|
+
sub,
|
|
831
|
+
txn,
|
|
832
|
+
reset,
|
|
833
|
+
data,
|
|
834
|
+
scope,
|
|
835
|
+
detach
|
|
836
|
+
};
|
|
837
|
+
} else {
|
|
838
|
+
return {
|
|
839
|
+
get,
|
|
840
|
+
set,
|
|
841
|
+
sub,
|
|
842
|
+
txn,
|
|
843
|
+
reset,
|
|
844
|
+
data,
|
|
845
|
+
scope
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
}
|
|
540
849
|
|
|
541
|
-
// src/
|
|
542
|
-
var
|
|
850
|
+
// src/store.ts
|
|
851
|
+
var store = (id) => {
|
|
543
852
|
const data = createStoreData(id);
|
|
544
853
|
return storeFromStoreData(data);
|
|
545
854
|
};
|
|
855
|
+
|
|
856
|
+
// src/globalStore.ts
|
|
857
|
+
var globalStore = Object.assign(store("valdres-global-store"), {
|
|
858
|
+
atoms: new Map,
|
|
859
|
+
atomFamilies: new Map
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
// src/lib/globalAtom.ts
|
|
863
|
+
var globalAtom = (defaultValue, options) => {
|
|
864
|
+
const stores = new Set;
|
|
865
|
+
let value;
|
|
866
|
+
let initialized = false;
|
|
867
|
+
let onReset;
|
|
868
|
+
if (options.onSet)
|
|
869
|
+
throw new Error("onSet on globalAtom is currently not supported");
|
|
870
|
+
const onInit = (setSelf2, data) => {
|
|
871
|
+
setSelf2(globalStore.get(atom));
|
|
872
|
+
if (!initialized && options.onInit) {
|
|
873
|
+
onReset = options.onInit((newVal) => {
|
|
874
|
+
setSelf2(newVal);
|
|
875
|
+
value = newVal;
|
|
876
|
+
}, data);
|
|
877
|
+
initialized = true;
|
|
878
|
+
}
|
|
879
|
+
stores.add(data);
|
|
880
|
+
};
|
|
881
|
+
const onSet = (newValue, currentStore) => {
|
|
882
|
+
value = newValue;
|
|
883
|
+
if (stores.size > 1) {
|
|
884
|
+
for (const store2 of stores) {
|
|
885
|
+
if (store2.id !== currentStore.id) {
|
|
886
|
+
setAtom(atom, value, store2, true);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
const getSelf = () => globalStore.get(atom);
|
|
892
|
+
const setSelf = (newValue) => globalStore.set(atom, newValue);
|
|
893
|
+
const resetSelf = () => {
|
|
894
|
+
value = undefined;
|
|
895
|
+
initialized = false;
|
|
896
|
+
for (const store2 of stores) {
|
|
897
|
+
if (store2.stateDependencies.has(atom)) {
|
|
898
|
+
throw new Error("TODO: Reset support for stateDependencies");
|
|
899
|
+
}
|
|
900
|
+
store2.values.delete(atom);
|
|
901
|
+
store2.expiredValues.delete(atom);
|
|
902
|
+
propagateUpdatedAtoms([atom], store2);
|
|
903
|
+
stores.delete(store2);
|
|
904
|
+
onReset?.();
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
const atom = {
|
|
908
|
+
equal,
|
|
909
|
+
...options,
|
|
910
|
+
defaultValue,
|
|
911
|
+
name: options?.name,
|
|
912
|
+
onInit,
|
|
913
|
+
onSet,
|
|
914
|
+
setSelf,
|
|
915
|
+
getSelf,
|
|
916
|
+
resetSelf,
|
|
917
|
+
get stores() {
|
|
918
|
+
return stores;
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
return atom;
|
|
922
|
+
};
|
|
923
|
+
|
|
924
|
+
// src/atom.ts
|
|
925
|
+
function atom(defaultValue, options) {
|
|
926
|
+
if (!options)
|
|
927
|
+
return { equal, defaultValue };
|
|
928
|
+
if (options.global) {
|
|
929
|
+
return globalAtom(defaultValue, options);
|
|
930
|
+
}
|
|
931
|
+
return {
|
|
932
|
+
equal,
|
|
933
|
+
defaultValue,
|
|
934
|
+
...options
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
// src/selector.ts
|
|
938
|
+
var selector = (get, options) => {
|
|
939
|
+
if (!options)
|
|
940
|
+
return { equal, get };
|
|
941
|
+
return { equal, ...options, get };
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
// src/lib/atomFamilyAtom.ts
|
|
945
|
+
function atomFamilyAtom(defaultValue, options) {
|
|
946
|
+
if (options.global) {
|
|
947
|
+
return globalAtom(defaultValue, options);
|
|
948
|
+
}
|
|
949
|
+
return {
|
|
950
|
+
...options,
|
|
951
|
+
defaultValue
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
// src/lib/stableStringify.ts
|
|
956
|
+
var stableStringifyRecurse = (x, key) => {
|
|
957
|
+
if (typeof x === "string" && !x.includes('"') && !x.includes("\\")) {
|
|
958
|
+
return `"${x}"`;
|
|
959
|
+
}
|
|
960
|
+
switch (typeof x) {
|
|
961
|
+
case "undefined":
|
|
962
|
+
return "";
|
|
963
|
+
case "boolean":
|
|
964
|
+
return x ? "true" : "false";
|
|
965
|
+
case "number":
|
|
966
|
+
case "symbol":
|
|
967
|
+
return String(x);
|
|
968
|
+
case "string":
|
|
969
|
+
return JSON.stringify(x);
|
|
970
|
+
case "function":
|
|
971
|
+
return `__FUNCTION(${x.toString()})__`;
|
|
972
|
+
}
|
|
973
|
+
if (x === null) {
|
|
974
|
+
return "null";
|
|
975
|
+
}
|
|
976
|
+
if (typeof x !== "object") {
|
|
977
|
+
return JSON.stringify(x) ?? "";
|
|
978
|
+
}
|
|
979
|
+
if (isPromiseLike(x)) {
|
|
980
|
+
return "__PROMISE__";
|
|
981
|
+
}
|
|
982
|
+
if (Array.isArray(x)) {
|
|
983
|
+
return `[${x.map((v, i) => stableStringifyRecurse(v, i.toString()))}]`;
|
|
984
|
+
}
|
|
985
|
+
if (typeof x.toJSON === "function") {
|
|
986
|
+
return stableStringifyRecurse(x.toJSON(key), key);
|
|
987
|
+
}
|
|
988
|
+
if (x instanceof Map) {
|
|
989
|
+
const obj = {};
|
|
990
|
+
for (const [k, v] of x) {
|
|
991
|
+
obj[typeof k === "string" ? k : stringify(k, opt)] = v;
|
|
992
|
+
}
|
|
993
|
+
return stableStringifyRecurse(obj, key);
|
|
994
|
+
}
|
|
995
|
+
if (x instanceof Set) {
|
|
996
|
+
return stableStringifyRecurse(Array.from(x).sort((a, b) => stableStringifyRecurse(a).localeCompare(stableStringifyRecurse(b))), key);
|
|
997
|
+
}
|
|
998
|
+
if (Symbol !== undefined && x[Symbol.iterator] != null && typeof x[Symbol.iterator] === "function") {
|
|
999
|
+
return stableStringifyRecurse(Array.from(x), key);
|
|
1000
|
+
}
|
|
1001
|
+
return `{${Object.keys(x).filter((k) => x[k] !== undefined).sort().map((k) => `${stableStringifyRecurse(k)}:${stableStringifyRecurse(x[k], k)}`).join(",")}}`;
|
|
1002
|
+
};
|
|
1003
|
+
var stableStringify = (x) => {
|
|
1004
|
+
if (typeof x === "string" || typeof x === "boolean" || typeof x === "number")
|
|
1005
|
+
return x;
|
|
1006
|
+
return stableStringifyRecurse(x);
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
// src/lib/createAtomFamily.ts
|
|
1010
|
+
var createOptions = (options = {}, family, familyKey, keyStringified) => {
|
|
1011
|
+
if (options.name) {
|
|
1012
|
+
return {
|
|
1013
|
+
equal,
|
|
1014
|
+
...options,
|
|
1015
|
+
name: options?.name + "_" + keyStringified,
|
|
1016
|
+
family,
|
|
1017
|
+
familyKey
|
|
1018
|
+
};
|
|
1019
|
+
} else {
|
|
1020
|
+
return { equal, ...options, family, familyKey };
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
var handleDefaultValue = (defaultValue, key) => {
|
|
1024
|
+
if (isSelectorFamily(defaultValue))
|
|
1025
|
+
return defaultValue(key);
|
|
1026
|
+
if (typeof defaultValue === "function")
|
|
1027
|
+
return () => defaultValue(key);
|
|
1028
|
+
return defaultValue;
|
|
1029
|
+
};
|
|
1030
|
+
var createAtomFamily = (defaultValue, options) => {
|
|
1031
|
+
const map = new Map;
|
|
1032
|
+
const keysAtom = atom(new Set);
|
|
1033
|
+
const atomFamily = Object.assign((key) => {
|
|
1034
|
+
const keyStringified = stableStringify(key);
|
|
1035
|
+
if (map.has(keyStringified)) {
|
|
1036
|
+
return map.get(keyStringified);
|
|
1037
|
+
}
|
|
1038
|
+
const familyAtom = atomFamilyAtom(handleDefaultValue(defaultValue, key), createOptions(options, atomFamily, Object.freeze(key), keyStringified));
|
|
1039
|
+
map.set(keyStringified, familyAtom);
|
|
1040
|
+
return familyAtom;
|
|
1041
|
+
}, {
|
|
1042
|
+
__valdresAtomFamilyMap: map,
|
|
1043
|
+
release: (key) => map.delete(key),
|
|
1044
|
+
__keysAtom: keysAtom,
|
|
1045
|
+
__keysSelector: selector((get) => Array.from(get(keysAtom)))
|
|
1046
|
+
});
|
|
1047
|
+
if (options?.name)
|
|
1048
|
+
Object.defineProperty(atomFamily, "name", {
|
|
1049
|
+
value: options.name,
|
|
1050
|
+
writable: false
|
|
1051
|
+
});
|
|
1052
|
+
return atomFamily;
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
// src/lib/createGlobalAtomFamily.ts
|
|
1056
|
+
var createGlobalAtomFamily = (defaultValue, options) => {
|
|
1057
|
+
if (!options.name)
|
|
1058
|
+
throw new Error(`Missing name for global atomFamiliy`);
|
|
1059
|
+
if (globalStore.atomFamilies.has(options.name)) {
|
|
1060
|
+
return globalStore.atomFamilies.get(options.name);
|
|
1061
|
+
}
|
|
1062
|
+
const family = createAtomFamily(defaultValue, options);
|
|
1063
|
+
globalStore.atomFamilies.set(options.name, family);
|
|
1064
|
+
return family;
|
|
1065
|
+
};
|
|
1066
|
+
|
|
1067
|
+
// src/atomFamily.ts
|
|
1068
|
+
function atomFamily(defaultValue, options) {
|
|
1069
|
+
if (options?.global)
|
|
1070
|
+
return createGlobalAtomFamily(defaultValue, options);
|
|
1071
|
+
return createAtomFamily(defaultValue, options);
|
|
1072
|
+
}
|
|
546
1073
|
// src/createStoreWithSelectorSet.ts
|
|
547
|
-
var setSelector = (
|
|
548
|
-
return
|
|
1074
|
+
var setSelector = (selector2, values, store2) => {
|
|
1075
|
+
return selector2.set(store2.set, store2.get, store2.reset, ...values);
|
|
549
1076
|
};
|
|
550
1077
|
var createStoreWithSelectorSet = (id) => {
|
|
551
1078
|
const data = createStoreData(id);
|
|
552
|
-
const
|
|
553
|
-
|
|
1079
|
+
const store2 = storeFromStoreData(data);
|
|
1080
|
+
store2.set = (state, value, ...rest) => {
|
|
554
1081
|
if (isAtom(state))
|
|
555
1082
|
return setAtom(state, value, data);
|
|
556
1083
|
if (isSelector(state))
|
|
557
|
-
return setSelector(state, [value, ...rest],
|
|
1084
|
+
return setSelector(state, [value, ...rest], store2);
|
|
558
1085
|
throw new Error("Invalid state object");
|
|
559
1086
|
};
|
|
560
|
-
|
|
561
|
-
return
|
|
1087
|
+
store2.kind = "storeWithSelectorSet";
|
|
1088
|
+
return store2;
|
|
1089
|
+
};
|
|
1090
|
+
// src/indexConstructor.ts
|
|
1091
|
+
var index = (family, callback) => {
|
|
1092
|
+
const map = new Map;
|
|
1093
|
+
return (term) => {
|
|
1094
|
+
const termKey = stableStringify(term);
|
|
1095
|
+
if (map.has(termKey))
|
|
1096
|
+
return map.get(termKey);
|
|
1097
|
+
const itemSelectorMap = new Map;
|
|
1098
|
+
const selectorMapIndex = selector((get) => {
|
|
1099
|
+
const ids = get(family);
|
|
1100
|
+
ids.forEach((id) => {
|
|
1101
|
+
if (itemSelectorMap.has(id))
|
|
1102
|
+
return;
|
|
1103
|
+
itemSelectorMap.set(id, selector((get2) => callback(get2(family(id)), term)));
|
|
1104
|
+
});
|
|
1105
|
+
return itemSelectorMap;
|
|
1106
|
+
});
|
|
1107
|
+
const filteredSelector = selector((get) => {
|
|
1108
|
+
const map2 = get(selectorMapIndex);
|
|
1109
|
+
const res = [];
|
|
1110
|
+
map2.forEach((selector2, key) => {
|
|
1111
|
+
if (get(selector2)) {
|
|
1112
|
+
res.push(key);
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
return res;
|
|
1116
|
+
});
|
|
1117
|
+
map.set(termKey, filteredSelector);
|
|
1118
|
+
return filteredSelector;
|
|
1119
|
+
};
|
|
562
1120
|
};
|
|
563
|
-
// src/getDefaultStore.ts
|
|
564
|
-
if (!globalThis._valdresStore) {
|
|
565
|
-
globalThis._valdresStore = createStore("default");
|
|
566
|
-
}
|
|
567
|
-
var getDefaultStore = () => globalThis._valdresStore;
|
|
568
|
-
var resetDefaultStore = () => globalThis._valdresStore = createStore();
|
|
569
|
-
// src/selector.ts
|
|
570
|
-
var selector = (get, debugLabel) => ({
|
|
571
|
-
get,
|
|
572
|
-
debugLabel
|
|
573
|
-
});
|
|
574
1121
|
// src/selectorFamily.ts
|
|
575
|
-
var
|
|
1122
|
+
var createOptions2 = (options = {}, family, familyKey, keyStringified) => {
|
|
1123
|
+
if (options.name) {
|
|
1124
|
+
return {
|
|
1125
|
+
equal,
|
|
1126
|
+
...options,
|
|
1127
|
+
name: options?.name + "_" + keyStringified,
|
|
1128
|
+
family,
|
|
1129
|
+
familyKey
|
|
1130
|
+
};
|
|
1131
|
+
} else {
|
|
1132
|
+
return { equal, ...options, family, familyKey };
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
var selectorFamily = (get, options) => {
|
|
576
1136
|
const map = new Map;
|
|
577
1137
|
const selectorFamily2 = (key) => {
|
|
578
|
-
|
|
579
|
-
try {
|
|
580
|
-
keyStringified = stableStringify(key);
|
|
581
|
-
} catch (e) {
|
|
582
|
-
console.log(`errro`, { key, debugLabel, e });
|
|
583
|
-
throw e;
|
|
584
|
-
}
|
|
1138
|
+
const keyStringified = stableStringify(key);
|
|
585
1139
|
if (map.has(keyStringified))
|
|
586
1140
|
return map.get(keyStringified);
|
|
587
|
-
const
|
|
588
|
-
const newSelector = selector((selectorArgs) => get(key)(selectorArgs), selectorDebugLabel);
|
|
589
|
-
newSelector.family = selectorFamily2;
|
|
1141
|
+
const newSelector = selector((selectorArgs) => get(key)(selectorArgs), createOptions2(options, selectorFamily2, key, keyStringified));
|
|
590
1142
|
map.set(keyStringified, newSelector);
|
|
591
1143
|
return newSelector;
|
|
592
1144
|
};
|
|
593
|
-
selectorFamily2.
|
|
1145
|
+
selectorFamily2.__valdresSelectorFamilyMap = map;
|
|
1146
|
+
if (options?.name)
|
|
1147
|
+
Object.defineProperty(selectorFamily2, "name", {
|
|
1148
|
+
value: options.name,
|
|
1149
|
+
writable: false
|
|
1150
|
+
});
|
|
594
1151
|
return selectorFamily2;
|
|
595
1152
|
};
|
|
1153
|
+
// src/utils/isFamilySelector.ts
|
|
1154
|
+
var isFamilySelector = (state) => isFamilyState(state) && isSelector(state);
|
|
1155
|
+
|
|
1156
|
+
// src/index.ts
|
|
1157
|
+
if (globalThis.__valdres__) {
|
|
1158
|
+
throw new Error(`Error! An instance of valdres is already loaded. Loaded: ${globalThis.__valdres__}. Attempted to load: ${version}`);
|
|
1159
|
+
} else {
|
|
1160
|
+
globalThis.__valdres__ = version;
|
|
1161
|
+
}
|
|
596
1162
|
export {
|
|
1163
|
+
store,
|
|
597
1164
|
selectorFamily,
|
|
598
1165
|
selector,
|
|
599
|
-
|
|
1166
|
+
isSelectorFamily,
|
|
600
1167
|
isSelector,
|
|
601
1168
|
isPromiseLike,
|
|
1169
|
+
isFamilyState,
|
|
1170
|
+
isFamilySelector,
|
|
1171
|
+
isFamilyAtom,
|
|
602
1172
|
isFamily,
|
|
1173
|
+
isAtomFamily,
|
|
603
1174
|
isAtom,
|
|
604
|
-
|
|
1175
|
+
index,
|
|
1176
|
+
globalStore,
|
|
1177
|
+
deepFreeze,
|
|
605
1178
|
createStoreWithSelectorSet,
|
|
606
|
-
createStore,
|
|
607
1179
|
atomFamily,
|
|
608
1180
|
atom
|
|
609
1181
|
};
|