valdres 0.2.0-alpha.1 → 0.2.0-alpha.11

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 (36) hide show
  1. package/dist/index.d.ts +7 -0
  2. package/dist/index.js +372 -293
  3. package/dist/src/atom.d.ts +3 -8
  4. package/dist/src/atomFamily.d.ts +4 -1
  5. package/dist/src/createStoreWithSelectorSet.d.ts +2 -0
  6. package/dist/src/lib/createStoreData.d.ts +2 -0
  7. package/dist/src/lib/getState.d.ts +6 -2
  8. package/dist/src/lib/initSelector.d.ts +1 -1
  9. package/dist/src/lib/setAtom.d.ts +1 -1
  10. package/dist/src/lib/storeFromStoreData.d.ts +3 -0
  11. package/dist/src/lib/subscribe.d.ts +2 -1
  12. package/dist/src/lib/transaction.d.ts +2 -1
  13. package/dist/src/lib/unsubscribe.d.ts +3 -1
  14. package/dist/src/lib/updateSelectorSubscribers.d.ts +1 -1
  15. package/dist/src/selector.d.ts +3 -4
  16. package/dist/src/selectorFamily.d.ts +3 -4
  17. package/dist/src/types/Atom.d.ts +6 -1
  18. package/dist/src/types/AtomFamily.d.ts +2 -1
  19. package/dist/src/types/AtomOnInit.d.ts +2 -0
  20. package/dist/src/types/AtomOnSet.d.ts +2 -0
  21. package/dist/src/types/AtomOptions.d.ts +9 -0
  22. package/dist/src/types/Family.d.ts +1 -1
  23. package/dist/src/types/GetValue.d.ts +8 -2
  24. package/dist/src/types/ResetAtom.d.ts +1 -1
  25. package/dist/src/types/Selector.d.ts +8 -3
  26. package/dist/src/types/SelectorFamily.d.ts +5 -1
  27. package/dist/src/types/SelectorOptions.d.ts +3 -0
  28. package/dist/src/types/SetAtom.d.ts +2 -1
  29. package/dist/src/types/SetAtomValue.d.ts +1 -0
  30. package/dist/src/types/StoreData.d.ts +3 -1
  31. package/dist/src/types/SubscribeFn.d.ts +1 -1
  32. package/dist/src/types/Subscription.d.ts +1 -0
  33. package/dist/src/utils/isAtom.d.ts +2 -2
  34. package/dist/src/utils/isPromiseLike.d.ts +1 -1
  35. package/dist/src/utils/isSelector.d.ts +1 -2
  36. package/package.json +10 -5
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { atom } from "./src/atom";
2
2
  export { atomFamily } from "./src/atomFamily";
3
3
  export { createStore } from "./src/createStore";
4
+ export { createStoreWithSelectorSet } from "./src/createStoreWithSelectorSet";
4
5
  export { getDefaultStore, resetDefaultStore } from "./src/getDefaultStore";
5
6
  export { selector } from "./src/selector";
6
7
  export { selectorFamily } from "./src/selectorFamily";
@@ -9,6 +10,12 @@ export { isSelector } from "./src/utils/isSelector";
9
10
  export { isFamily } from "./src/utils/isFamily";
10
11
  export { isPromiseLike } from "./src/utils/isPromiseLike";
11
12
  export type { Atom } from "./src/types/Atom";
13
+ export type { AtomFamily } from "./src/types/AtomFamily";
14
+ export type { GetValue } from "./src/types/GetValue";
12
15
  export type { Selector } from "./src/types/Selector";
16
+ export type { SelectorFamily } from "./src/types/SelectorFamily";
17
+ export type { SetAtom } from "./src/types/SetAtom";
18
+ export type { SetAtomValue } from "./src/types/SetAtomValue";
13
19
  export type { State } from "./src/types/State";
14
20
  export type { Store } from "./src/types/Store";
21
+ export type { StoreData } from "./src/types/StoreData";
package/dist/index.js CHANGED
@@ -1,121 +1,100 @@
1
- // src/atom.ts
2
- var atom = (defaultValue, options) => {
3
- if (!options)
4
- return { defaultValue };
5
- return {
6
- defaultValue,
7
- ...options
8
- };
9
- };
10
- // src/utils/isPromiseLike.ts
11
- var isPromiseLike = (object) => object && object.then && typeof object.then === "function";
1
+ // src/lib/setAtom.ts
2
+ import equal4 from "fast-deep-equal";
12
3
 
13
- // src/lib/stableStringify.ts
14
- var stableStringifyRecurse = (x, key) => {
15
- if (typeof x === "string" && !x.includes('"') && !x.includes("\\")) {
16
- return `"${x}"`;
17
- }
18
- switch (typeof x) {
19
- case "undefined":
20
- return "";
21
- case "boolean":
22
- return x ? "true" : "false";
23
- case "number":
24
- case "symbol":
25
- return String(x);
26
- case "string":
27
- return JSON.stringify(x);
28
- case "function":
29
- return `__FUNCTION(${x.toString()})__`;
30
- }
31
- if (x === null) {
32
- return "null";
33
- }
34
- if (typeof x !== "object") {
35
- return JSON.stringify(x) ?? "";
36
- }
37
- if (isPromiseLike(x)) {
38
- return "__PROMISE__";
39
- }
40
- if (Array.isArray(x)) {
41
- return `[${x.map((v, i) => stableStringifyRecurse(v, i.toString()))}]`;
42
- }
43
- if (typeof x.toJSON === "function") {
44
- return stableStringifyRecurse(x.toJSON(key), key);
45
- }
46
- if (x instanceof Map) {
47
- const obj = {};
48
- for (const [k, v] of x) {
49
- obj[typeof k === "string" ? k : stringify(k, opt)] = v;
50
- }
51
- return stableStringifyRecurse(obj, key);
52
- }
53
- if (x instanceof Set) {
54
- return stableStringifyRecurse(Array.from(x).sort((a, b) => stableStringifyRecurse(a).localeCompare(stableStringifyRecurse(b))), key);
55
- }
56
- if (Symbol !== undefined && x[Symbol.iterator] != null && typeof x[Symbol.iterator] === "function") {
57
- return stableStringifyRecurse(Array.from(x), key);
58
- }
59
- return `{${Object.keys(x).filter((k) => x[k] !== undefined).sort().map((k) => `${stableStringifyRecurse(k)}:${stableStringifyRecurse(x[k], k)}`).join(",")}}`;
60
- };
61
- var stableStringify = (x) => {
62
- if (typeof x === "string" || typeof x === "boolean" || typeof x === "number")
63
- return x;
64
- return stableStringifyRecurse(x);
4
+ // src/utils/isPromiseLike.ts
5
+ var isPromiseLike = (object) => {
6
+ return object && object.then && typeof object.then === "function";
65
7
  };
66
8
 
67
- // src/atomFamily.ts
68
- var handleDefaultValue = (defaultValue, override, key) => {
69
- if (override) {
70
- return typeof override === "function" ? () => typeof defaultValue === "function" ? override(defaultValue(key)) : override(defaultValue) : override;
71
- } else {
72
- return typeof defaultValue === "function" ? () => defaultValue(key) : defaultValue;
73
- }
74
- };
75
- var atomFamily = (defaultValue, debugLabel) => {
76
- const map = new Map;
77
- const atomFamily2 = (key, defaultOverride) => {
78
- const keyStringified = stableStringify(key);
79
- if (map.has(keyStringified)) {
80
- if (defaultOverride)
81
- throw new Error("defaultOverride is only allowed first time an atom is initiaizlied");
82
- return map.get(keyStringified);
83
- }
84
- const atomDebugLabel = debugLabel && debugLabel + "_" + keyStringified;
85
- const newAtom = atom(handleDefaultValue(defaultValue, defaultOverride, key), {
86
- label: atomDebugLabel
87
- });
88
- newAtom.family = atomFamily2;
89
- newAtom.familyKey = Object.freeze(key);
90
- map.set(keyStringified, newAtom);
91
- return newAtom;
92
- };
93
- atomFamily2._map = map;
94
- return atomFamily2;
95
- };
96
9
  // src/lib/updateStateSubscribers.ts
97
- var updateStateSubscribers = (state2, data) => {
98
- const subscribtions = data.subscriptions.get(state2);
10
+ var updateStateSubscribers = (state, data) => {
11
+ const subscribtions = data.subscriptions.get(state);
99
12
  if (subscribtions?.size) {
100
13
  for (const subscribtion of subscribtions) {
101
14
  subscribtion.callback();
102
15
  }
103
16
  }
104
- if (state2.family) {
105
- const familySubscriptions = data.subscriptions.get(state2.family);
17
+ if (state.family) {
18
+ const familySubscriptions = data.subscriptions.get(state.family);
106
19
  if (familySubscriptions?.size) {
107
20
  for (const subscribtion of familySubscriptions) {
108
- subscribtion.callback(state2.familyKey);
21
+ subscribtion.callback(state.familyKey);
109
22
  }
110
23
  }
111
24
  }
112
25
  };
113
26
 
114
27
  // src/lib/updateSelectorSubscribers.ts
115
- import equal2 from "fast-deep-equal";
28
+ import equal3 from "fast-deep-equal";
116
29
 
117
30
  // src/lib/initSelector.ts
31
+ import equal2 from "fast-deep-equal";
32
+
33
+ // src/lib/getState.ts
118
34
  import equal from "fast-deep-equal";
35
+
36
+ // src/lib/initAtom.ts
37
+ var getAtomInitValue = (atom, data) => {
38
+ if (atom.defaultValue === undefined) {
39
+ let promiseResolve;
40
+ const promise = new Promise((resolve) => {
41
+ promiseResolve = resolve;
42
+ });
43
+ promise.__isEmptyAtomPromise__ = true;
44
+ promise.__resolveEmptyAtomPromise__ = promiseResolve;
45
+ return promise;
46
+ } else if (typeof atom.defaultValue === "function") {
47
+ const value = atom.defaultValue();
48
+ if (isPromiseLike(value)) {
49
+ value.then((resolvedValue) => {
50
+ data.values.set(atom, resolvedValue);
51
+ propagateUpdatedAtoms([atom], data);
52
+ });
53
+ }
54
+ return value;
55
+ } else {
56
+ return atom.defaultValue;
57
+ }
58
+ };
59
+ var initAtom = (atom, data) => {
60
+ let value = getAtomInitValue(atom, data);
61
+ data.values.set(atom, value);
62
+ if (atom.onInit)
63
+ atom.onInit((newVal) => {
64
+ value = newVal;
65
+ setAtom(atom, newVal, data, true);
66
+ }, data);
67
+ return value;
68
+ };
69
+
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
+ // src/lib/getState.ts
80
+ function getState(state, data) {
81
+ if (data.values.has(state))
82
+ 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());
89
+ if (equal(array, state._keyArray))
90
+ return state._keyArray;
91
+ state._keyArray = array;
92
+ return array;
93
+ }
94
+ throw new Error("Invalid object passed to get");
95
+ }
96
+
97
+ // src/lib/initSelector.ts
119
98
  class SuspendAndWaitForResolveError extends Error {
120
99
  promise;
121
100
  constructor(promise) {
@@ -123,26 +102,25 @@ class SuspendAndWaitForResolveError extends Error {
123
102
  this.promise = promise;
124
103
  }
125
104
  }
126
- var getOrInitConsumersSet = (state2, data) => {
127
- const set = data.stateConsumers.get(state2);
105
+ var getOrInitConsumersSet = (state, data) => {
106
+ const set = data.stateConsumers.get(state);
128
107
  if (set)
129
108
  return set;
130
109
  const newSet = new Set;
131
- data.stateConsumers.set(state2, newSet);
110
+ data.stateConsumers.set(state, newSet);
132
111
  return newSet;
133
112
  };
134
113
  var evaluateSelector = (selector, data) => {
135
- const currentDependencies = data.stateDependencies.get(selector) ?? new Set;
136
114
  const updatedDependencies = new Set;
137
115
  let result;
138
116
  try {
139
- result = selector.get((state2) => {
140
- const value = getState2(state2, data);
141
- updatedDependencies.add(state2);
117
+ result = selector.get((state) => {
118
+ const value = getState(state, data);
119
+ updatedDependencies.add(state);
142
120
  if (isPromiseLike(value))
143
121
  throw new SuspendAndWaitForResolveError(value);
144
122
  return value;
145
- });
123
+ }, data.id);
146
124
  } catch (error) {
147
125
  if (error instanceof SuspendAndWaitForResolveError) {
148
126
  result = error;
@@ -150,14 +128,15 @@ var evaluateSelector = (selector, data) => {
150
128
  throw error;
151
129
  }
152
130
  }
131
+ const currentDependencies = data.stateDependencies.get(selector) ?? new Set;
153
132
  const added = updatedDependencies?.difference(currentDependencies);
154
133
  const removed = currentDependencies?.difference(updatedDependencies);
155
- for (const state2 of added) {
156
- const set = getOrInitConsumersSet(state2, data);
134
+ for (const state of added) {
135
+ const set = getOrInitConsumersSet(state, data);
157
136
  set.add(selector);
158
137
  }
159
- for (const state2 of removed) {
160
- const set = getOrInitConsumersSet(state2, data);
138
+ for (const state of removed) {
139
+ const set = getOrInitConsumersSet(state, data);
161
140
  set.delete(selector);
162
141
  }
163
142
  data.stateDependencies.set(selector, updatedDependencies);
@@ -171,7 +150,7 @@ var handleSelectorResult = (value, selector, data) => {
171
150
  value.then((resolved) => {
172
151
  data.values.set(selector, resolved);
173
152
  updateStateSubscribers(selector, data);
174
- console.log(`TODO: Should we check if other selectors are using this?`);
153
+ console.log("Should we reEvaluate?");
175
154
  });
176
155
  return value;
177
156
  } else {
@@ -183,7 +162,7 @@ var initSelector = (selector, data) => {
183
162
  const value = handleSelectorResult(tmpValue, selector, data);
184
163
  if (data.expiredValues.has(selector)) {
185
164
  const expiredValue = data.expiredValues.get(selector);
186
- if (equal(expiredValue, value)) {
165
+ if (equal2(expiredValue, value)) {
187
166
  data.values.set(selector, expiredValue);
188
167
  return expiredValue;
189
168
  }
@@ -198,11 +177,11 @@ var updateSelectorSubscribers = (selector, data) => {
198
177
  const familySubscriptions = selector.family && data.subscriptions.get(selector.family);
199
178
  if (!subscribtions?.size && !familySubscriptions?.size)
200
179
  return;
201
- if (subscribtions?.size && data.subscriptionsRequireEqualCheck.get(selector) || familySubscriptions?.size && data.subscriptionsRequireEqualCheck.get(selector.family)) {
180
+ if (subscribtions?.size && data.subscriptionsRequireEqualCheck.get(selector) || familySubscriptions?.size && selector.family && data.subscriptionsRequireEqualCheck.get(selector.family)) {
202
181
  try {
203
182
  const oldValue = data.expiredValues.get(selector);
204
183
  const newValue = initSelector(selector, data);
205
- if (equal2(newValue, oldValue))
184
+ if (equal3(newValue, oldValue))
206
185
  return;
207
186
  } catch (e) {
208
187
  }
@@ -214,7 +193,7 @@ var updateSelectorSubscribers = (selector, data) => {
214
193
  }
215
194
  if (familySubscriptions?.size) {
216
195
  for (const subscribtion of familySubscriptions) {
217
- subscribtion.callback(state.familyKey);
196
+ subscribtion.callback(selector.familyKey);
218
197
  }
219
198
  }
220
199
  };
@@ -235,13 +214,13 @@ var recursivlyResetSelectorTree = (selectors, data, clearedSelectors) => {
235
214
  };
236
215
  var propagateUpdatedAtoms = (atoms, data) => {
237
216
  const clearedSelectors = new Set;
238
- for (const atom3 of atoms) {
239
- const consumers = data.stateConsumers.get(atom3);
217
+ for (const atom of atoms) {
218
+ const consumers = data.stateConsumers.get(atom);
240
219
  if (consumers && consumers.size) {
241
220
  recursivlyResetSelectorTree(consumers, data, clearedSelectors);
242
221
  }
243
- if (atom3.family) {
244
- const consumersFamily = data.stateConsumers.get(atom3.family);
222
+ if (atom.family) {
223
+ const consumersFamily = data.stateConsumers.get(atom.family);
245
224
  if (consumersFamily?.size) {
246
225
  recursivlyResetSelectorTree(consumersFamily, data, clearedSelectors);
247
226
  }
@@ -250,95 +229,176 @@ var propagateUpdatedAtoms = (atoms, data) => {
250
229
  for (const selector of clearedSelectors) {
251
230
  updateSelectorSubscribers(selector, data);
252
231
  }
253
- for (const atom3 of atoms) {
254
- updateStateSubscribers(atom3, data);
232
+ for (const atom of atoms) {
233
+ updateStateSubscribers(atom, data);
255
234
  }
256
235
  };
257
236
 
258
237
  // src/lib/setAtom.ts
259
- import equal3 from "fast-deep-equal";
260
- var setAtom = (atom3, newValue, data) => {
261
- const currentValue = getState2(atom3, data);
238
+ var setAtom = (atom, newValue, data, skipOnSet = false) => {
239
+ const currentValue = getState(atom, data);
262
240
  if (typeof newValue === "function") {
263
241
  newValue = newValue(currentValue);
264
242
  if (isPromiseLike(newValue) || isPromiseLike(currentValue))
265
243
  throw new Error("Todo, how should we handle this?");
266
244
  }
267
- if (equal3(currentValue, newValue))
245
+ if (equal4(currentValue, newValue))
268
246
  return;
269
- data.values.set(atom3, newValue);
247
+ data.values.set(atom, newValue);
248
+ if (atom.onSet && !skipOnSet)
249
+ atom.onSet(newValue, data);
270
250
  if (currentValue?.__isEmptyAtomPromise__) {
271
251
  currentValue.__resolveEmptyAtomPromise__(newValue);
272
252
  }
273
- propagateUpdatedAtoms([atom3], data);
253
+ propagateUpdatedAtoms([atom], data);
274
254
  };
275
255
 
276
- // src/lib/initAtom.ts
277
- var getAtomInitValue = (atom3, data) => {
278
- if (atom3.defaultValue === undefined) {
279
- let promiseResolve;
280
- const promise = new Promise((resolve) => {
281
- promiseResolve = resolve;
282
- });
283
- promise.__isEmptyAtomPromise__ = true;
284
- promise.__resolveEmptyAtomPromise__ = promiseResolve;
285
- return promise;
286
- } else if (typeof atom3.defaultValue === "function") {
287
- const value = atom3.defaultValue();
288
- if (isPromiseLike(value)) {
289
- value.then((resolvedValue) => {
290
- data.values.set(atom3, resolvedValue);
291
- propagateUpdatedAtoms([atom3], data);
292
- });
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
+ }
293
268
  }
294
- return value;
295
- } else {
296
- return atom3.defaultValue;
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
+ }
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) ?? "";
297
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);
337
+ }
338
+ return `{${Object.keys(x).filter((k) => x[k] !== undefined).sort().map((k) => `${stableStringifyRecurse(k)}:${stableStringifyRecurse(x[k], k)}`).join(",")}}`;
298
339
  };
299
- var initAtom = (atom3, data) => {
300
- const value = getAtomInitValue(atom3, data);
301
- data.values.set(atom3, value);
302
- if (atom3.onInit)
303
- atom3.onInit((newVal) => {
304
- setAtom(atom3, newVal, data);
305
- });
306
- return value;
340
+ var stableStringify = (x) => {
341
+ if (typeof x === "string" || typeof x === "boolean" || typeof x === "number")
342
+ return x;
343
+ return stableStringifyRecurse(x);
307
344
  };
308
345
 
309
- // src/utils/isAtom.ts
310
- var isAtom = (state2) => Object.hasOwn(state2, "defaultValue");
311
-
312
- // src/utils/isSelector.ts
313
- var isSelector = (state2) => Object.hasOwn(state2, "get");
314
-
315
- // src/utils/isFamily.ts
316
- var isFamily = (state2) => Object.hasOwn(state2, "_map");
317
-
318
- // src/lib/getState.ts
319
- var getState2 = (state2, data) => {
320
- if (data.values.has(state2))
321
- return data.values.get(state2);
322
- if (isAtom(state2))
323
- return initAtom(state2, data);
324
- if (isSelector(state2))
325
- return initSelector(state2, data);
326
- if (isFamily(state2)) {
327
- const res = [];
328
- for (const atom3 of state2._map.values()) {
329
- res.push([atom3.familyKey, getState2(atom3, data)]);
346
+ // src/atomFamily.ts
347
+ var createOptions = (options, key) => {
348
+ if (options.label) {
349
+ return {
350
+ ...options,
351
+ label: options?.label + "_" + key
352
+ };
353
+ } else {
354
+ return options;
355
+ }
356
+ };
357
+ var atomFamily = (defaultValue, options) => {
358
+ const map = new Map;
359
+ const atomFamily2 = (key) => {
360
+ const keyStringified = stableStringify(key);
361
+ if (map.has(keyStringified)) {
362
+ return map.get(keyStringified);
330
363
  }
331
- return res;
364
+ const newAtom = atom(typeof defaultValue === "function" ? () => defaultValue(key) : defaultValue, options ? createOptions(options, keyStringified) : undefined);
365
+ newAtom.family = atomFamily2;
366
+ newAtom.familyKey = Object.freeze(key);
367
+ map.set(keyStringified, newAtom);
368
+ return newAtom;
369
+ };
370
+ atomFamily2._map = map;
371
+ if (options?.label)
372
+ atomFamily2.label = options.label;
373
+ return atomFamily2;
374
+ };
375
+ // src/lib/createStoreData.ts
376
+ var generateId = () => (Math.random() + 1).toString(36).substring(7);
377
+ var createStoreData = (id = generateId()) => ({
378
+ id,
379
+ values: new WeakMap,
380
+ expiredValues: new WeakMap,
381
+ subscriptions: new WeakMap,
382
+ subscriptionsRequireEqualCheck: new WeakMap,
383
+ stateConsumers: new WeakMap,
384
+ stateDependencies: new WeakMap
385
+ });
386
+
387
+ // src/lib/resetAtom.ts
388
+ var resetAtom = (atom2, data) => {
389
+ const res = initAtom(atom2, data);
390
+ if (!isPromiseLike(res)) {
391
+ propagateUpdatedAtoms([atom2], data);
332
392
  }
333
- throw new Error("Invalid object passed to get");
393
+ return res;
334
394
  };
335
395
 
336
396
  // src/lib/unsubscribe.ts
337
- var unsubscribe = (state2, subscription, data, mountRes) => {
338
- const subscribers = data.subscriptions.get(state2);
397
+ var unsubscribe = (state, subscription, data, mount) => {
398
+ const subscribers = data.subscriptions.get(state);
339
399
  if (subscribers) {
340
400
  subscribers.delete(subscription);
341
- if (data.subscriptionsRequireEqualCheck.get(state2)) {
401
+ if (data.subscriptionsRequireEqualCheck.get(state)) {
342
402
  let remove = true;
343
403
  for (const subscriber of subscribers) {
344
404
  if (subscriber.requireDeepEqualCheckBeforeCallback) {
@@ -347,33 +407,35 @@ var unsubscribe = (state2, subscription, data, mountRes) => {
347
407
  }
348
408
  }
349
409
  if (remove) {
350
- data.subscriptionsRequireEqualCheck.delete(state2);
410
+ data.subscriptionsRequireEqualCheck.delete(state);
351
411
  }
352
412
  }
353
- if (subscribers.size === 0) {
354
- if (state2.onUnmount) {
355
- state2.onUnmount(mountRes);
413
+ if (mount) {
414
+ if (subscribers.size === mount.mountSubscriptions.size) {
415
+ if (typeof mount.onUnmount === "function") {
416
+ mount.onUnmount();
417
+ }
356
418
  }
357
419
  }
358
420
  }
359
421
  };
360
422
 
361
423
  // src/lib/subscribe.ts
362
- var initSubscribers = (state2, data) => {
424
+ var initSubscribers = (state, data) => {
363
425
  const set = new Set;
364
- data.subscriptions.set(state2, set);
426
+ data.subscriptions.set(state, set);
365
427
  return set;
366
428
  };
367
- var subscribe = (state2, callback, requireDeepEqualCheckBeforeCallback, data) => {
368
- const subscribers = data.subscriptions.get(state2) || initSubscribers(state2, data);
369
- if (isSelector(state2) && !data.values.has(state2)) {
370
- initSelector(state2, data);
429
+ var subscribe = (state, callback, requireDeepEqualCheckBeforeCallback, data) => {
430
+ const subscribers = data.subscriptions.get(state) || initSubscribers(state, data);
431
+ if (isSelector(state) && !data.values.has(state)) {
432
+ initSelector(state, data);
371
433
  }
372
434
  let subscription;
373
- if (isFamily(state2)) {
435
+ if (isFamily(state)) {
374
436
  subscription = {
375
437
  callback,
376
- state: state2,
438
+ state,
377
439
  requireDeepEqualCheckBeforeCallback
378
440
  };
379
441
  } else {
@@ -382,36 +444,44 @@ var subscribe = (state2, callback, requireDeepEqualCheckBeforeCallback, data) =>
382
444
  requireDeepEqualCheckBeforeCallback
383
445
  };
384
446
  }
385
- let mountRes;
386
- if (subscribers.size === 0 && state2.onMount) {
387
- mountRes = state2.onMount((value) => {
388
- setAtom(state2, value, data);
389
- });
390
- }
391
447
  subscribers.add(subscription);
392
- if (requireDeepEqualCheckBeforeCallback && data.subscriptionsRequireEqualCheck.get(state2) !== true) {
393
- data.subscriptionsRequireEqualCheck.set(state2, true);
448
+ let mount;
449
+ if (subscribers.size === 1 && state.onMount) {
450
+ const store = storeFromStoreData(data);
451
+ const mountSubscriptions = new Set;
452
+ const originalSub = store.sub;
453
+ store.sub = (state2, callback2) => {
454
+ mountSubscriptions.add(callback2);
455
+ return originalSub(state2, callback2);
456
+ };
457
+ mount = {
458
+ onUnmount: state.onMount(store, state),
459
+ mountSubscriptions
460
+ };
461
+ }
462
+ if (requireDeepEqualCheckBeforeCallback && data.subscriptionsRequireEqualCheck.get(state) !== true) {
463
+ data.subscriptionsRequireEqualCheck.set(state, true);
394
464
  }
395
- return () => unsubscribe(state2, subscription, data, mountRes);
465
+ return () => unsubscribe(state, subscription, data, mount);
396
466
  };
397
467
 
398
468
  // src/lib/setAtoms.ts
399
- import equal4 from "fast-deep-equal";
469
+ import equal5 from "fast-deep-equal";
400
470
  var setAtoms = (pairs, data) => {
401
471
  const updatedAtoms = [];
402
- for (let [atom3, value] of pairs) {
403
- const currentValue = getState2(atom3, data);
404
- if (!equal4(currentValue, value)) {
405
- updatedAtoms.push(atom3);
406
- data.values.set(atom3, value);
472
+ for (let [atom2, value] of pairs) {
473
+ const currentValue = getState(atom2, data);
474
+ if (!equal5(currentValue, value)) {
475
+ updatedAtoms.push(atom2);
476
+ data.values.set(atom2, value);
407
477
  }
408
478
  }
409
479
  propagateUpdatedAtoms(updatedAtoms, data);
410
480
  };
411
481
 
412
482
  // src/lib/transaction.ts
413
- var findDependencies = (state2, data, result = new Set) => {
414
- const consumers = data.stateConsumers.get(state2);
483
+ var findDependencies = (state, data, result = new Set) => {
484
+ const consumers = data.stateConsumers.get(state);
415
485
  if (consumers?.size) {
416
486
  for (const consumer of consumers) {
417
487
  if (!result.has(consumer)) {
@@ -422,41 +492,62 @@ var findDependencies = (state2, data, result = new Set) => {
422
492
  }
423
493
  return result;
424
494
  };
495
+ var recursivlyResetTxnSelectorCache = (state, txnSubscribers, txnSelectorCache) => {
496
+ for (const dep of txnSubscribers.get(state)) {
497
+ txnSelectorCache.delete(dep);
498
+ if (txnSubscribers.get(dep)?.size) {
499
+ recursivlyResetTxnSelectorCache(dep, txnSubscribers, txnSelectorCache);
500
+ }
501
+ }
502
+ };
425
503
  var transaction = (callback, data) => {
426
504
  let txnAtomMap = new Map;
427
505
  let txnSelectorCache = new Map;
506
+ let txnSubscribers = new Map;
428
507
  let dirtySelectors = new Set;
429
- const txnGet = (state2) => {
430
- if (isAtom(state2)) {
431
- return txnAtomMap.has(state2) ? txnAtomMap.get(state2) : getState2(state2, data);
432
- } else {
433
- if (txnSelectorCache.has(state2)) {
434
- return txnSelectorCache.get(state2);
435
- } else if (dirtySelectors.has(state2)) {
436
- const res = state2.get(txnGet);
437
- txnSelectorCache.set(state2, res);
438
- return res;
439
- } else {
440
- return getState2(state2, data);
508
+ const txnGet = (state) => {
509
+ if (isAtom(state)) {
510
+ return txnAtomMap.has(state) ? txnAtomMap.get(state) : getState(state, data);
511
+ } else if (isSelector(state)) {
512
+ if (txnSelectorCache.has(state)) {
513
+ return txnSelectorCache.get(state);
441
514
  }
515
+ const deps = new Set;
516
+ const res = state.get((s) => {
517
+ deps.add(s);
518
+ return txnGet(s);
519
+ }, data.id);
520
+ for (const dep of deps) {
521
+ if (!txnSubscribers.has(dep)) {
522
+ txnSubscribers.set(dep, new Set);
523
+ }
524
+ txnSubscribers.get(dep).add(state);
525
+ }
526
+ txnSelectorCache.set(state, res);
527
+ return res;
528
+ } else {
529
+ throw new Error("Unsupported state");
442
530
  }
443
531
  };
444
- const txnSet = (atom3, value) => {
445
- if (!isAtom(atom3))
532
+ const txnSet = (atom2, value) => {
533
+ if (!isAtom(atom2))
446
534
  throw new Error("Not an atom");
447
535
  if (typeof value === "function") {
448
- const currentValue = txnGet(atom3);
536
+ const currentValue = txnGet(atom2);
449
537
  value = value(currentValue);
450
538
  }
451
- for (const selector of findDependencies(atom3, data)) {
539
+ for (const selector of findDependencies(atom2, data)) {
452
540
  dirtySelectors.add(selector);
453
541
  txnSelectorCache.delete(selector);
454
542
  }
455
- txnAtomMap.set(atom3, value);
543
+ if (txnSubscribers.get(atom2)?.size) {
544
+ recursivlyResetTxnSelectorCache(atom2, txnSubscribers, txnSelectorCache);
545
+ }
546
+ txnAtomMap.set(atom2, value);
456
547
  };
457
- const txnReset = (atom3) => {
458
- const value = getAtomInitValue(atom3, data);
459
- txnAtomMap.set(atom3, value);
548
+ const txnReset = (atom2) => {
549
+ const value = getAtomInitValue(atom2, data);
550
+ txnAtomMap.set(atom2, value);
460
551
  return value;
461
552
  };
462
553
  const commit = () => {
@@ -468,59 +559,19 @@ var transaction = (callback, data) => {
468
559
  return result;
469
560
  };
470
561
 
471
- // src/lib/resetAtom.ts
472
- var resetAtom = (atom3, data) => {
473
- const res = initAtom(atom3, data);
474
- if (!isPromiseLike(res)) {
475
- propagateUpdatedAtoms([atom3], data);
476
- }
477
- return res;
478
- };
479
-
480
- // src/createStore.ts
481
- var generateId = () => (Math.random() + 1).toString(36).substring(7);
482
- var createStore = (id) => {
483
- const data = {
484
- id: id ?? generateId(),
485
- values: new WeakMap,
486
- expiredValues: new WeakMap,
487
- subscriptions: new WeakMap,
488
- subscriptionsRequireEqualCheck: new WeakMap,
489
- stateConsumers: new WeakMap,
490
- stateDependencies: new WeakMap
562
+ // src/lib/storeFromStoreData.ts
563
+ var storeFromStoreData = (data) => {
564
+ const get = (state) => getState(state, data);
565
+ const set = (state, value) => {
566
+ if (!isAtom(state))
567
+ throw new Error("Invalid state object");
568
+ return setAtom(state, value, data);
491
569
  };
492
- const get = (state2) => getState2(state2, data);
493
- const getWithDefault = (atom3, defaultValue) => {
494
- if (!isAtom(atom3))
495
- throw new Error("Only atom allowed");
496
- if (data.values.has(atom3)) {
497
- return data.values.get(atom3);
498
- } else {
499
- data.values.set(atom3, defaultValue);
500
- return defaultValue;
501
- }
502
- };
503
- const set = (state2, value) => {
504
- if (isAtom(state2)) {
505
- return setAtom(state2, value, data);
506
- } else {
507
- if (isSelector(state2)) {
508
- if (state2.set) {
509
- txn((set2, get2) => state2.set({ get: get2, set: set2 }, value));
510
- return;
511
- } else {
512
- throw new Error("set on selector is not supported");
513
- }
514
- }
515
- throw new Error("Invalid state object passed to set");
516
- }
517
- };
518
- const reset = (atom3) => resetAtom(atom3, data);
519
- const sub = (state2, callback, deepEqualCheckBeforeCallback = true) => subscribe(state2, callback, deepEqualCheckBeforeCallback, data);
570
+ const reset = (atom2) => resetAtom(atom2, data);
571
+ const sub = (state, callback, deepEqualCheckBeforeCallback = true) => subscribe(state, callback, deepEqualCheckBeforeCallback, data);
520
572
  const txn = (callback) => transaction(callback, data);
521
573
  return {
522
574
  get,
523
- getWithDefault,
524
575
  set,
525
576
  sub,
526
577
  txn,
@@ -528,6 +579,29 @@ var createStore = (id) => {
528
579
  data
529
580
  };
530
581
  };
582
+
583
+ // src/createStore.ts
584
+ var createStore = (id) => {
585
+ const data = createStoreData(id);
586
+ return storeFromStoreData(data);
587
+ };
588
+ // src/createStoreWithSelectorSet.ts
589
+ var setSelector = (selector, values, store) => {
590
+ return selector.set(store.set, store.get, store.reset, ...values);
591
+ };
592
+ var createStoreWithSelectorSet = (id) => {
593
+ const data = createStoreData(id);
594
+ const store = storeFromStoreData(data);
595
+ store.set = (state, value, ...rest) => {
596
+ if (isAtom(state))
597
+ return setAtom(state, value, data);
598
+ if (isSelector(state))
599
+ return setSelector(state, [value, ...rest], store);
600
+ throw new Error("Invalid state object");
601
+ };
602
+ store.kind = "storeWithSelectorSet";
603
+ return store;
604
+ };
531
605
  // src/getDefaultStore.ts
532
606
  if (!globalThis._valdresStore) {
533
607
  globalThis._valdresStore = createStore("default");
@@ -535,25 +609,29 @@ if (!globalThis._valdresStore) {
535
609
  var getDefaultStore = () => globalThis._valdresStore;
536
610
  var resetDefaultStore = () => globalThis._valdresStore = createStore();
537
611
  // src/selector.ts
538
- var selector = (get, debugLabel) => ({
539
- get,
540
- debugLabel
541
- });
612
+ var selector = (get, options) => {
613
+ if (!options)
614
+ return { get };
615
+ return { ...options, get };
616
+ };
542
617
  // src/selectorFamily.ts
543
- var selectorFamily = (get, debugLabel) => {
618
+ var createOptions2 = (options, key) => {
619
+ if (options.label) {
620
+ return {
621
+ ...options,
622
+ label: options?.label + "_" + key
623
+ };
624
+ } else {
625
+ return options;
626
+ }
627
+ };
628
+ var selectorFamily = (get, options) => {
544
629
  const map = new Map;
545
630
  const selectorFamily2 = (key) => {
546
- let keyStringified;
547
- try {
548
- keyStringified = stableStringify(key);
549
- } catch (e) {
550
- console.log(`errro`, { key, debugLabel, e });
551
- throw e;
552
- }
631
+ const keyStringified = stableStringify(key);
553
632
  if (map.has(keyStringified))
554
633
  return map.get(keyStringified);
555
- const selectorDebugLabel = debugLabel ? debugLabel + "_" + keyStringified : undefined;
556
- const newSelector = selector((selectorArgs) => get(key)(selectorArgs), selectorDebugLabel);
634
+ const newSelector = selector((selectorArgs) => get(key)(selectorArgs), options ? createOptions2(options, keyStringified) : undefined);
557
635
  newSelector.family = selectorFamily2;
558
636
  map.set(keyStringified, newSelector);
559
637
  return newSelector;
@@ -570,6 +648,7 @@ export {
570
648
  isFamily,
571
649
  isAtom,
572
650
  getDefaultStore,
651
+ createStoreWithSelectorSet,
573
652
  createStore,
574
653
  atomFamily,
575
654
  atom
@@ -1,9 +1,4 @@
1
1
  import type { Atom } from "./types/Atom";
2
- type AtomOptions<M = any> = {
3
- label?: string;
4
- onInit?: () => void;
5
- onMount?: () => M;
6
- onUnmount?: (mountRes?: M) => void;
7
- };
8
- export declare const atom: <Value, FamilyKey = undefined, MountReturnValue = undefined>(defaultValue?: Value | (() => Value | Promise<Value>), options?: AtomOptions<MountReturnValue>) => Atom<Value, FamilyKey>;
9
- export {};
2
+ import type { AtomOptions } from "./types/AtomOptions";
3
+ export declare const globalAtom: <Value = any, FamilyKey = undefined>(defaultValue: Value | (() => Value | Promise<Value>), options: AtomOptions<Value>) => Atom<Value>;
4
+ export declare const atom: <Value = any, FamilyKey = undefined>(defaultValue?: Value | (() => Value | Promise<Value>), options?: AtomOptions<Value>) => Atom<Value, FamilyKey>;
@@ -1,2 +1,5 @@
1
1
  import type { AtomFamily } from "./types/AtomFamily";
2
- export declare const atomFamily: <Value, Key>(defaultValue?: Value | ((arg: Key) => Value | Promise<Value>), debugLabel?: string) => AtomFamily<Value, Key>;
2
+ import type { AtomOptions } from "./types/AtomOptions";
3
+ type DefaultValueCallback<Key, Value> = (arg: Key) => Value | Promise<Value>;
4
+ export declare const atomFamily: <Value = unknown, Key = unknown>(defaultValue?: Value | DefaultValueCallback<Key, Value>, options?: AtomOptions<Value>) => AtomFamily<Value, Key>;
5
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { Store } from "./types/Store";
2
+ export declare const createStoreWithSelectorSet: (id?: string) => Store;
@@ -0,0 +1,2 @@
1
+ import type { StoreData } from "../types/StoreData";
2
+ export declare const createStoreData: (id?: string) => StoreData;
@@ -1,3 +1,7 @@
1
- import type { State } from "../types/State";
2
1
  import type { StoreData } from "../types/StoreData";
3
- export declare const getState: <V>(state: State<V>, data: StoreData) => V | Promise<V>;
2
+ import type { Atom } from "../types/Atom";
3
+ import type { AtomFamily } from "../types/AtomFamily";
4
+ import type { Selector } from "../types/Selector";
5
+ export declare function getState<V, K>(atom: Atom<V>, data: StoreData): V;
6
+ export declare function getState<V, K>(selector: Selector<V>, data: StoreData): V;
7
+ export declare function getState<V, K>(family: AtomFamily<V, K>, data: StoreData): K[];
@@ -1,4 +1,4 @@
1
1
  import type { StoreData } from "../types/StoreData";
2
2
  import type { Selector } from "../types/Selector";
3
3
  export declare const reEvaluateSelector: <V>(selector: Selector<V>, data: StoreData) => void;
4
- export declare const initSelector: <V>(selector: Selector<V>, data: StoreData) => V;
4
+ export declare const initSelector: <V>(selector: Selector<V>, data: StoreData) => V | Promise<V>;
@@ -1,3 +1,3 @@
1
1
  import type { Atom } from "../types/Atom";
2
2
  import type { StoreData } from "../types/StoreData";
3
- export declare const setAtom: <V>(atom: Atom<V>, newValue: V, data: StoreData) => void;
3
+ export declare const setAtom: <Value = any>(atom: Atom<Value>, newValue: Value, data: StoreData, skipOnSet?: boolean) => void;
@@ -0,0 +1,3 @@
1
+ import type { Store } from "../types/Store";
2
+ import type { StoreData } from "../types/StoreData";
3
+ export declare const storeFromStoreData: (data: StoreData) => Store;
@@ -1,3 +1,4 @@
1
+ import type { Family } from "../types/Family";
1
2
  import type { State } from "../types/State";
2
3
  import type { StoreData } from "../types/StoreData";
3
- export declare const subscribe: <V>(state: State<V>, callback: any, data: StoreData) => () => void;
4
+ export declare const subscribe: <V>(state: State<V> | Family<V>, callback: any, requireDeepEqualCheckBeforeCallback: boolean, data: StoreData) => () => void;
@@ -1,8 +1,9 @@
1
1
  import type { State } from "../types/State";
2
2
  import type { StoreData } from "../types/StoreData";
3
+ import type { Atom } from "../types/Atom";
3
4
  type GetValdresValue = <V>(state: State<V>) => V;
4
5
  type SetValdresValue = <V>(state: State<V>, value: V) => void;
5
- type ResetValdresValue = <V>(state: State<V>) => V;
6
+ type ResetValdresValue = <V>(atom: Atom<V>) => V;
6
7
  type TransactionInterface = (set: SetValdresValue, get: GetValdresValue, reset: ResetValdresValue, commit: () => void) => void;
7
8
  export declare const transaction: (callback: TransactionInterface, data: StoreData) => void;
8
9
  export {};
@@ -1,3 +1,5 @@
1
+ import type { Family } from "../types/Family";
1
2
  import type { State } from "../types/State";
2
3
  import type { StoreData } from "../types/StoreData";
3
- export declare const unsubscribe: <V>(state: State<V>, subscription: any, store: StoreData, mountRes?: any) => void;
4
+ import type { Subscription } from "../types/Subscription";
5
+ export declare const unsubscribe: <V>(state: State<V> | Family<V>, subscription: Subscription, data: StoreData, mount?: any) => void;
@@ -1,3 +1,3 @@
1
1
  import type { Selector } from "../types/Selector";
2
2
  import type { StoreData } from "../types/StoreData";
3
- export declare const updateSelectorSubscribers: (selector: Selector, data: StoreData, oldValue: any) => void;
3
+ export declare const updateSelectorSubscribers: (selector: Selector, data: StoreData) => void;
@@ -1,5 +1,4 @@
1
1
  import type { GetValue } from "./types/GetValue";
2
- export declare const selector: (get: GetValue, debugLabel?: string) => {
3
- get: GetValue;
4
- debugLabel: string;
5
- };
2
+ import type { Selector } from "./types/Selector";
3
+ import type { SelectorOptions } from "./types/SelectorOptions";
4
+ export declare const selector: <Value, FamilyKey = undefined>(get: (get: GetValue, storeId: string) => Value, options?: SelectorOptions) => Selector<Value, FamilyKey>;
@@ -1,4 +1,3 @@
1
- export declare const selectorFamily: <V, A>(get: any, debugLabel?: string) => {
2
- (key: A): any;
3
- _map: Map<any, any>;
4
- };
1
+ import type { SelectorFamily } from "./types/SelectorFamily";
2
+ import type { SelectorOptions } from "./types/SelectorOptions";
3
+ export declare const selectorFamily: <Value, Key>(get: any, options?: SelectorOptions) => SelectorFamily<Value, Key>;
@@ -1,7 +1,12 @@
1
1
  import type { AtomFamily } from "./AtomFamily";
2
- export type Atom<Value = unknown, FamilyKey = undefined> = {
2
+ import type { AtomOnInit } from "./AtomOnInit";
3
+ import type { AtomOnSet } from "./AtomOnSet";
4
+ export type Atom<Value = any, FamilyKey = undefined> = {
3
5
  defaultValue?: Value | (() => Value | Promise<Value>);
4
6
  label?: string;
5
7
  family?: AtomFamily<Value, FamilyKey>;
6
8
  familyKey?: FamilyKey;
9
+ onInit?: AtomOnInit<Value>;
10
+ onSet?: AtomOnSet<Value>;
11
+ onMount?: () => void | (() => void);
7
12
  };
@@ -1,5 +1,6 @@
1
1
  import type { Atom } from "./Atom";
2
2
  export type AtomFamily<Value, Key> = {
3
- (key: Key, defaultOverride?: any): Atom<Value, Key>;
3
+ (key: Key, defaultOverride?: any): Atom<Value>;
4
+ label?: string;
4
5
  _map: Map<Key, Atom<Value, Key>>;
5
6
  };
@@ -0,0 +1,2 @@
1
+ import type { StoreData } from "./StoreData";
2
+ export type AtomOnInit<Value = unknown> = (setSelf: (value: Value) => void, store: StoreData) => void;
@@ -0,0 +1,2 @@
1
+ import type { StoreData } from "./StoreData";
2
+ export type AtomOnSet<Value = unknown> = (value: Value, store: StoreData) => void;
@@ -0,0 +1,9 @@
1
+ import type { AtomOnSet } from "./AtomOnSet";
2
+ import type { StoreData } from "./StoreData";
3
+ export type AtomOptions<Value = any> = {
4
+ global?: boolean;
5
+ label?: string;
6
+ onInit?: (setSelf: (value: Value) => void, store: StoreData) => void;
7
+ onSet?: AtomOnSet<Value>;
8
+ onMount?: () => () => void;
9
+ };
@@ -1,3 +1,3 @@
1
1
  import type { SelectorFamily } from "./SelectorFamily";
2
2
  import type { AtomFamily } from "./AtomFamily";
3
- export type Family<V, K> = AtomFamily<V, K> | SelectorFamily<V, K>;
3
+ export type Family<V, K = any> = AtomFamily<V, K> | SelectorFamily<V, K>;
@@ -1,2 +1,8 @@
1
- import type { State } from "./State";
2
- export type GetValue = <V>(state: State<V>) => V;
1
+ import type { Atom } from "./Atom";
2
+ import type { AtomFamily } from "./AtomFamily";
3
+ import type { Selector } from "./Selector";
4
+ export type GetValue = {
5
+ <V, K>(atom: Atom<V>): V;
6
+ <V, K>(selector: Selector<V>): V;
7
+ <V, K>(family: AtomFamily<V, K>): K[];
8
+ };
@@ -1,2 +1,2 @@
1
1
  import type { Atom } from "./Atom";
2
- export type ResetAtom = <V>(state: Atom<V>) => V;
2
+ export type ResetAtom = <V>(state: Atom<V>) => V | Promise<V>;
@@ -1,4 +1,9 @@
1
- export type Selector<V = any> = {
2
- get: () => {};
3
- debugLabel?: string;
1
+ import type { GetValue } from "./GetValue";
2
+ import type { SelectorFamily } from "./SelectorFamily";
3
+ export type Selector<Value = unknown, FamilyKey = undefined> = {
4
+ get: (get: GetValue, storeId: string) => Value;
5
+ label?: string;
6
+ family?: SelectorFamily<Value, FamilyKey>;
7
+ familyKey?: FamilyKey;
8
+ onMount?: () => void | (() => void);
4
9
  };
@@ -1 +1,5 @@
1
- export type SelectorFamily<A, V> = {};
1
+ import type { Selector } from "./Selector";
2
+ export type SelectorFamily<Value, Key> = {
3
+ (key: Key, defaultOverride?: any): Selector<Value>;
4
+ _map: Map<Key, Selector<Value, Key>>;
5
+ };
@@ -0,0 +1,3 @@
1
+ export type SelectorOptions = {
2
+ label?: string;
3
+ };
@@ -1,2 +1,3 @@
1
1
  import type { Atom } from "./Atom";
2
- export type SetAtom = <V>(atom: Atom<V>, value: V) => void;
2
+ import type { SetAtomValue } from "./SetAtomValue";
3
+ export type SetAtom<V = any> = (atom: Atom<V>, value: SetAtomValue<V>) => void;
@@ -0,0 +1 @@
1
+ export type SetAtomValue<V> = V | ((current: V) => V);
@@ -1,7 +1,9 @@
1
1
  export type StoreData = {
2
2
  id: string;
3
3
  values: WeakMap<WeakKey, any>;
4
- subscriptions: WeakMap<WeakKey, any>;
4
+ expiredValues: WeakMap<WeakKey, any>;
5
+ subscriptions: WeakMap<WeakKey, Set<any>>;
6
+ subscriptionsRequireEqualCheck: WeakMap<WeakKey, boolean>;
5
7
  stateConsumers: WeakMap<WeakKey, any>;
6
8
  stateDependencies: WeakMap<WeakKey, any>;
7
9
  };
@@ -1,2 +1,2 @@
1
1
  import type { State } from "./State";
2
- export type SubscribeFn = <V>(state: State<V>, callback: () => void) => () => void;
2
+ export type SubscribeFn = <V>(state: State<V>, callback: () => void, requireDeepEqualCheckBeforeCallback?: boolean) => () => void;
@@ -0,0 +1 @@
1
+ export type Subscription = {};
@@ -1,2 +1,2 @@
1
- import type { State } from "../types/State";
2
- export declare const isAtom: (state: State) => boolean;
1
+ import type { Atom } from "../types/Atom";
2
+ export declare const isAtom: (state: any) => state is Atom;
@@ -1 +1 @@
1
- export declare const isPromiseLike: (object: any) => boolean;
1
+ export declare const isPromiseLike: <T>(object: any) => object is Promise<T>;
@@ -1,3 +1,2 @@
1
1
  import type { Selector } from "../types/Selector";
2
- import type { State } from "../types/State";
3
- export declare const isSelector: (state: State) => state is Selector;
2
+ export declare const isSelector: (state: any) => state is Selector;
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "valdres",
3
- "version": "0.2.0-alpha.1",
3
+ "version": "0.2.0-alpha.11",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Eigil Sagafos"
7
7
  },
8
+ "homepage": "https://valdres.dev",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/eigilsagafos/valdres.git"
12
+ },
8
13
  "type": "module",
9
14
  "exports": {
10
15
  "types": "./dist/index.d.ts",
@@ -14,8 +19,8 @@
14
19
  "dist"
15
20
  ],
16
21
  "scripts": {
17
- "build": "NODE_ENV=production bun scripts/build.ts",
18
- "build:types": "tsc index.ts --declaration --emitDeclarationOnly --outDir dist",
22
+ "build": "rm -rf dist && NODE_ENV=production bun scripts/build.ts",
23
+ "build:types": "tsc",
19
24
  "test": "bun test"
20
25
  },
21
26
  "dependencies": {
@@ -28,11 +33,11 @@
28
33
  "react": ">=18",
29
34
  "react-dom": ">=18",
30
35
  "recoil": "0.7.7",
31
- "typescript": "5.5.4"
36
+ "typescript": "5.6.2"
32
37
  },
33
38
  "publishConfig": {
34
39
  "access": "public",
35
40
  "registry": "https://registry.npmjs.org/"
36
41
  },
37
- "gitHead": "b0f3eaf25483d7cb7231439cb3cc23cff5cab9c1"
42
+ "gitHead": "081fe9031067f895bb2f79dec2648a88ac891cc9"
38
43
  }