valdres 0.2.0-alpha.9 → 0.2.0-pre.2

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