valdres 0.2.0-alpha.8 → 0.2.0-pre.1

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