valdres 0.1.0-alpha.9 → 0.2.0-alpha.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.
- package/dist/index.js +565 -1
- package/package.json +13 -6
package/dist/index.js
CHANGED
|
@@ -1 +1,565 @@
|
|
|
1
|
-
|
|
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";
|
|
12
|
+
|
|
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);
|
|
65
|
+
};
|
|
66
|
+
|
|
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
|
+
// src/lib/updateStateSubscribers.ts
|
|
97
|
+
var updateStateSubscribers = (state2, data) => {
|
|
98
|
+
const subscribtions = data.subscriptions.get(state2);
|
|
99
|
+
if (subscribtions?.size) {
|
|
100
|
+
for (const subscribtion of subscribtions) {
|
|
101
|
+
subscribtion.callback();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (state2.family) {
|
|
105
|
+
const familySubscriptions = data.subscriptions.get(state2.family);
|
|
106
|
+
if (familySubscriptions?.size) {
|
|
107
|
+
for (const subscribtion of familySubscriptions) {
|
|
108
|
+
subscribtion.callback(state2.familyKey);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// src/lib/updateSelectorSubscribers.ts
|
|
115
|
+
import equal2 from "fast-deep-equal";
|
|
116
|
+
|
|
117
|
+
// src/lib/initSelector.ts
|
|
118
|
+
import equal from "fast-deep-equal";
|
|
119
|
+
class SuspendAndWaitForResolveError extends Error {
|
|
120
|
+
promise;
|
|
121
|
+
constructor(promise) {
|
|
122
|
+
super();
|
|
123
|
+
this.promise = promise;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
var getOrInitConsumersSet = (state2, data) => {
|
|
127
|
+
const set = data.stateConsumers.get(state2);
|
|
128
|
+
if (set)
|
|
129
|
+
return set;
|
|
130
|
+
const newSet = new Set;
|
|
131
|
+
data.stateConsumers.set(state2, newSet);
|
|
132
|
+
return newSet;
|
|
133
|
+
};
|
|
134
|
+
var evaluateSelector = (selector, data) => {
|
|
135
|
+
const currentDependencies = data.stateDependencies.get(selector) ?? new Set;
|
|
136
|
+
const updatedDependencies = new Set;
|
|
137
|
+
let result;
|
|
138
|
+
try {
|
|
139
|
+
result = selector.get((state2) => {
|
|
140
|
+
const value = getState2(state2, data);
|
|
141
|
+
updatedDependencies.add(state2);
|
|
142
|
+
if (isPromiseLike(value))
|
|
143
|
+
throw new SuspendAndWaitForResolveError(value);
|
|
144
|
+
return value;
|
|
145
|
+
});
|
|
146
|
+
} catch (error) {
|
|
147
|
+
if (error instanceof SuspendAndWaitForResolveError) {
|
|
148
|
+
result = error;
|
|
149
|
+
} else {
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const added = updatedDependencies?.difference(currentDependencies);
|
|
154
|
+
const removed = currentDependencies?.difference(updatedDependencies);
|
|
155
|
+
for (const state2 of added) {
|
|
156
|
+
const set = getOrInitConsumersSet(state2, data);
|
|
157
|
+
set.add(selector);
|
|
158
|
+
}
|
|
159
|
+
for (const state2 of removed) {
|
|
160
|
+
const set = getOrInitConsumersSet(state2, data);
|
|
161
|
+
set.delete(selector);
|
|
162
|
+
}
|
|
163
|
+
data.stateDependencies.set(selector, updatedDependencies);
|
|
164
|
+
return result;
|
|
165
|
+
};
|
|
166
|
+
var handleSelectorResult = (value, selector, data) => {
|
|
167
|
+
if (value instanceof SuspendAndWaitForResolveError) {
|
|
168
|
+
value.promise.then(() => initSelector(selector, data));
|
|
169
|
+
return value.promise;
|
|
170
|
+
} else if (isPromiseLike(value)) {
|
|
171
|
+
value.then((resolved) => {
|
|
172
|
+
data.values.set(selector, resolved);
|
|
173
|
+
updateStateSubscribers(selector, data);
|
|
174
|
+
console.log(`TODO: Should we check if other selectors are using this?`);
|
|
175
|
+
});
|
|
176
|
+
return value;
|
|
177
|
+
} else {
|
|
178
|
+
return value;
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
var initSelector = (selector, data) => {
|
|
182
|
+
const tmpValue = evaluateSelector(selector, data);
|
|
183
|
+
const value = handleSelectorResult(tmpValue, selector, data);
|
|
184
|
+
if (data.expiredValues.has(selector)) {
|
|
185
|
+
const expiredValue = data.expiredValues.get(selector);
|
|
186
|
+
if (equal(expiredValue, value)) {
|
|
187
|
+
data.values.set(selector, expiredValue);
|
|
188
|
+
return expiredValue;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
data.values.set(selector, value);
|
|
192
|
+
return value;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// src/lib/updateSelectorSubscribers.ts
|
|
196
|
+
var updateSelectorSubscribers = (selector, data) => {
|
|
197
|
+
const subscribtions = data.subscriptions.get(selector);
|
|
198
|
+
const familySubscriptions = selector.family && data.subscriptions.get(selector.family);
|
|
199
|
+
if (!subscribtions?.size && !familySubscriptions?.size)
|
|
200
|
+
return;
|
|
201
|
+
if (subscribtions?.size && data.subscriptionsRequireEqualCheck.get(selector) || familySubscriptions?.size && data.subscriptionsRequireEqualCheck.get(selector.family)) {
|
|
202
|
+
try {
|
|
203
|
+
const oldValue = data.expiredValues.get(selector);
|
|
204
|
+
const newValue = initSelector(selector, data);
|
|
205
|
+
if (equal2(newValue, oldValue))
|
|
206
|
+
return;
|
|
207
|
+
} catch (e) {
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (subscribtions?.size) {
|
|
211
|
+
for (const subscribtion of subscribtions) {
|
|
212
|
+
subscribtion.callback();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (familySubscriptions?.size) {
|
|
216
|
+
for (const subscribtion of familySubscriptions) {
|
|
217
|
+
subscribtion.callback(state.familyKey);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/lib/propagateUpdatedAtoms.ts
|
|
223
|
+
var recursivlyResetSelectorTree = (selectors, data, clearedSelectors) => {
|
|
224
|
+
for (const selector of selectors) {
|
|
225
|
+
if (!clearedSelectors.has(selector)) {
|
|
226
|
+
clearedSelectors.add(selector);
|
|
227
|
+
data.expiredValues.set(selector, data.values.get(selector));
|
|
228
|
+
data.values.delete(selector);
|
|
229
|
+
const consumers = data.stateConsumers.get(selector);
|
|
230
|
+
if (consumers?.size) {
|
|
231
|
+
recursivlyResetSelectorTree(consumers, data, clearedSelectors);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
var propagateUpdatedAtoms = (atoms, data) => {
|
|
237
|
+
const clearedSelectors = new Set;
|
|
238
|
+
for (const atom3 of atoms) {
|
|
239
|
+
const consumers = data.stateConsumers.get(atom3);
|
|
240
|
+
if (consumers && consumers.size) {
|
|
241
|
+
recursivlyResetSelectorTree(consumers, data, clearedSelectors);
|
|
242
|
+
}
|
|
243
|
+
if (atom3.family) {
|
|
244
|
+
const consumersFamily = data.stateConsumers.get(atom3.family);
|
|
245
|
+
if (consumersFamily?.size) {
|
|
246
|
+
recursivlyResetSelectorTree(consumersFamily, data, clearedSelectors);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
for (const selector of clearedSelectors) {
|
|
251
|
+
updateSelectorSubscribers(selector, data);
|
|
252
|
+
}
|
|
253
|
+
for (const atom3 of atoms) {
|
|
254
|
+
updateStateSubscribers(atom3, data);
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// src/lib/setAtom.ts
|
|
259
|
+
import equal3 from "fast-deep-equal";
|
|
260
|
+
var setAtom = (atom3, newValue, data) => {
|
|
261
|
+
const currentValue = getState2(atom3, data);
|
|
262
|
+
if (typeof newValue === "function") {
|
|
263
|
+
newValue = newValue(currentValue);
|
|
264
|
+
if (isPromiseLike(newValue) || isPromiseLike(currentValue))
|
|
265
|
+
throw new Error("Todo, how should we handle this?");
|
|
266
|
+
}
|
|
267
|
+
if (equal3(currentValue, newValue))
|
|
268
|
+
return;
|
|
269
|
+
data.values.set(atom3, newValue);
|
|
270
|
+
if (currentValue?.__isEmptyAtomPromise__) {
|
|
271
|
+
currentValue.__resolveEmptyAtomPromise__(newValue);
|
|
272
|
+
}
|
|
273
|
+
propagateUpdatedAtoms([atom3], data);
|
|
274
|
+
};
|
|
275
|
+
|
|
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
|
+
});
|
|
293
|
+
}
|
|
294
|
+
return value;
|
|
295
|
+
} else {
|
|
296
|
+
return atom3.defaultValue;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
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;
|
|
307
|
+
};
|
|
308
|
+
|
|
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)]);
|
|
330
|
+
}
|
|
331
|
+
return res;
|
|
332
|
+
}
|
|
333
|
+
throw new Error("Invalid object passed to get");
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// src/lib/unsubscribe.ts
|
|
337
|
+
var unsubscribe = (state2, subscription, data, mountRes) => {
|
|
338
|
+
const subscribers = data.subscriptions.get(state2);
|
|
339
|
+
if (subscribers) {
|
|
340
|
+
subscribers.delete(subscription);
|
|
341
|
+
if (data.subscriptionsRequireEqualCheck.get(state2)) {
|
|
342
|
+
let remove = true;
|
|
343
|
+
for (const subscriber of subscribers) {
|
|
344
|
+
if (subscriber.requireDeepEqualCheckBeforeCallback) {
|
|
345
|
+
remove = false;
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (remove) {
|
|
350
|
+
data.subscriptionsRequireEqualCheck.delete(state2);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (subscribers.size === 0) {
|
|
354
|
+
if (state2.onUnmount) {
|
|
355
|
+
state2.onUnmount(mountRes);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// src/lib/subscribe.ts
|
|
362
|
+
var initSubscribers = (state2, data) => {
|
|
363
|
+
const set = new Set;
|
|
364
|
+
data.subscriptions.set(state2, set);
|
|
365
|
+
return set;
|
|
366
|
+
};
|
|
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);
|
|
371
|
+
}
|
|
372
|
+
let subscription;
|
|
373
|
+
if (isFamily(state2)) {
|
|
374
|
+
subscription = {
|
|
375
|
+
callback,
|
|
376
|
+
state: state2,
|
|
377
|
+
requireDeepEqualCheckBeforeCallback
|
|
378
|
+
};
|
|
379
|
+
} else {
|
|
380
|
+
subscription = {
|
|
381
|
+
callback,
|
|
382
|
+
requireDeepEqualCheckBeforeCallback
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
let mountRes;
|
|
386
|
+
if (subscribers.size === 0 && state2.onMount) {
|
|
387
|
+
mountRes = state2.onMount((value) => {
|
|
388
|
+
setAtom(state2, value, data);
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
subscribers.add(subscription);
|
|
392
|
+
if (requireDeepEqualCheckBeforeCallback && data.subscriptionsRequireEqualCheck.get(state2) !== true) {
|
|
393
|
+
data.subscriptionsRequireEqualCheck.set(state2, true);
|
|
394
|
+
}
|
|
395
|
+
return () => unsubscribe(state2, subscription, data, mountRes);
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// src/lib/setAtoms.ts
|
|
399
|
+
import equal4 from "fast-deep-equal";
|
|
400
|
+
var setAtoms = (pairs, data) => {
|
|
401
|
+
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);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
propagateUpdatedAtoms(updatedAtoms, data);
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
// src/lib/transaction.ts
|
|
413
|
+
var findDependencies = (state2, data, result = new Set) => {
|
|
414
|
+
const consumers = data.stateConsumers.get(state2);
|
|
415
|
+
if (consumers?.size) {
|
|
416
|
+
for (const consumer of consumers) {
|
|
417
|
+
if (!result.has(consumer)) {
|
|
418
|
+
result.add(consumer);
|
|
419
|
+
findDependencies(consumer, data, result);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return result;
|
|
424
|
+
};
|
|
425
|
+
var transaction = (callback, data) => {
|
|
426
|
+
let txnAtomMap = new Map;
|
|
427
|
+
let txnSelectorCache = new Map;
|
|
428
|
+
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);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
const txnSet = (atom3, value) => {
|
|
445
|
+
if (!isAtom(atom3))
|
|
446
|
+
throw new Error("Not an atom");
|
|
447
|
+
if (typeof value === "function") {
|
|
448
|
+
const currentValue = txnGet(atom3);
|
|
449
|
+
value = value(currentValue);
|
|
450
|
+
}
|
|
451
|
+
for (const selector of findDependencies(atom3, data)) {
|
|
452
|
+
dirtySelectors.add(selector);
|
|
453
|
+
txnSelectorCache.delete(selector);
|
|
454
|
+
}
|
|
455
|
+
txnAtomMap.set(atom3, value);
|
|
456
|
+
};
|
|
457
|
+
const txnReset = (atom3) => {
|
|
458
|
+
const value = getAtomInitValue(atom3, data);
|
|
459
|
+
txnAtomMap.set(atom3, value);
|
|
460
|
+
return value;
|
|
461
|
+
};
|
|
462
|
+
const commit = () => {
|
|
463
|
+
setAtoms(txnAtomMap, data);
|
|
464
|
+
dirtySelectors.clear();
|
|
465
|
+
};
|
|
466
|
+
const result = callback(txnSet, txnGet, txnReset, commit);
|
|
467
|
+
commit();
|
|
468
|
+
return result;
|
|
469
|
+
};
|
|
470
|
+
|
|
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
|
|
491
|
+
};
|
|
492
|
+
const get = (state2) => getState2(state2, data);
|
|
493
|
+
const set = (state2, value) => {
|
|
494
|
+
if (isAtom(state2)) {
|
|
495
|
+
return setAtom(state2, value, data);
|
|
496
|
+
} else {
|
|
497
|
+
if (isSelector(state2)) {
|
|
498
|
+
if (state2.set) {
|
|
499
|
+
txn((set2, get2) => state2.set({ get: get2, set: set2 }, value));
|
|
500
|
+
return;
|
|
501
|
+
} else {
|
|
502
|
+
throw new Error("set on selector is not supported");
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
throw new Error("Invalid state object passed to set");
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
const reset = (atom3) => resetAtom(atom3, data);
|
|
509
|
+
const sub = (state2, callback, deepEqualCheckBeforeCallback = true) => subscribe(state2, callback, deepEqualCheckBeforeCallback, data);
|
|
510
|
+
const txn = (callback) => transaction(callback, data);
|
|
511
|
+
return {
|
|
512
|
+
get,
|
|
513
|
+
set,
|
|
514
|
+
sub,
|
|
515
|
+
txn,
|
|
516
|
+
reset,
|
|
517
|
+
data
|
|
518
|
+
};
|
|
519
|
+
};
|
|
520
|
+
// src/getDefaultStore.ts
|
|
521
|
+
if (!globalThis._valdresStore) {
|
|
522
|
+
globalThis._valdresStore = createStore("default");
|
|
523
|
+
}
|
|
524
|
+
var getDefaultStore = () => globalThis._valdresStore;
|
|
525
|
+
var resetDefaultStore = () => globalThis._valdresStore = createStore();
|
|
526
|
+
// src/selector.ts
|
|
527
|
+
var selector = (get, debugLabel) => ({
|
|
528
|
+
get,
|
|
529
|
+
debugLabel
|
|
530
|
+
});
|
|
531
|
+
// src/selectorFamily.ts
|
|
532
|
+
var selectorFamily = (get, debugLabel) => {
|
|
533
|
+
const map = new Map;
|
|
534
|
+
const selectorFamily2 = (key) => {
|
|
535
|
+
let keyStringified;
|
|
536
|
+
try {
|
|
537
|
+
keyStringified = stableStringify(key);
|
|
538
|
+
} catch (e) {
|
|
539
|
+
console.log(`errro`, { key, debugLabel, e });
|
|
540
|
+
throw e;
|
|
541
|
+
}
|
|
542
|
+
if (map.has(keyStringified))
|
|
543
|
+
return map.get(keyStringified);
|
|
544
|
+
const selectorDebugLabel = debugLabel ? debugLabel + "_" + keyStringified : undefined;
|
|
545
|
+
const newSelector = selector((selectorArgs) => get(key)(selectorArgs), selectorDebugLabel);
|
|
546
|
+
newSelector.family = selectorFamily2;
|
|
547
|
+
map.set(keyStringified, newSelector);
|
|
548
|
+
return newSelector;
|
|
549
|
+
};
|
|
550
|
+
selectorFamily2._map = map;
|
|
551
|
+
return selectorFamily2;
|
|
552
|
+
};
|
|
553
|
+
export {
|
|
554
|
+
selectorFamily,
|
|
555
|
+
selector,
|
|
556
|
+
resetDefaultStore,
|
|
557
|
+
isSelector,
|
|
558
|
+
isPromiseLike,
|
|
559
|
+
isFamily,
|
|
560
|
+
isAtom,
|
|
561
|
+
getDefaultStore,
|
|
562
|
+
createStore,
|
|
563
|
+
atomFamily,
|
|
564
|
+
atom
|
|
565
|
+
};
|
package/package.json
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valdres",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0-alpha.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Eigil Sagafos"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"exports": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
6
13
|
"files": [
|
|
7
14
|
"dist"
|
|
8
15
|
],
|
|
9
|
-
"type": "module",
|
|
10
16
|
"scripts": {
|
|
11
|
-
"build": "bun scripts/build.ts",
|
|
17
|
+
"build": "NODE_ENV=production bun scripts/build.ts",
|
|
12
18
|
"build:types": "tsc index.ts --declaration --emitDeclarationOnly --outDir dist",
|
|
13
19
|
"test": "bun test"
|
|
14
20
|
},
|
|
@@ -17,6 +23,7 @@
|
|
|
17
23
|
},
|
|
18
24
|
"devDependencies": {
|
|
19
25
|
"@testing-library/react-hooks": "8.0.1",
|
|
26
|
+
"mitata": "0.1.14",
|
|
20
27
|
"react": ">=18",
|
|
21
28
|
"react-dom": ">=18",
|
|
22
29
|
"recoil": "0.7.7",
|
|
@@ -26,5 +33,5 @@
|
|
|
26
33
|
"access": "public",
|
|
27
34
|
"registry": "https://registry.npmjs.org/"
|
|
28
35
|
},
|
|
29
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "ec1d460976eb7aa8b97c5def2c39bc406670d74c"
|
|
30
37
|
}
|