valdres 0.2.0-alpha.9 → 0.2.0-y.0

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