valdres 0.2.0-alpha.75 → 0.2.0-alpha.77
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 +219 -132
- package/dist/types/src/indexConstructor.d.ts +3 -1
- package/dist/types/src/lib/deleteFamilyAtom.d.ts +3 -0
- package/dist/types/src/lib/getState.d.ts +2 -1
- package/dist/types/src/lib/initAtom.d.ts +1 -1
- package/dist/types/src/lib/initSelector.d.ts +1 -1
- package/dist/types/src/lib/propagateUpdatedAtoms.d.ts +3 -2
- package/dist/types/src/lib/setValueInData.d.ts +2 -1
- package/dist/types/src/lib/stringifyFamilyArgs.d.ts +1 -1
- package/dist/types/src/lib/transaction.d.ts +1 -1
- package/dist/types/src/types/AtomFamily.d.ts +2 -4
- package/dist/types/src/types/AtomFamilyAtom.d.ts +2 -1
- package/dist/types/src/types/AtomFamilySelector.d.ts +1 -1
- package/dist/types/src/types/GetValue.d.ts +2 -1
- package/dist/types/src/types/Selector.d.ts +1 -1
- package/dist/types/src/types/Store.d.ts +2 -0
- package/dist/types/src/types/StoreData.d.ts +1 -1
- package/dist/types/src/types/TransactionInterface.d.ts +2 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -92,6 +92,9 @@ var equal = (a, b) => {
|
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
94
|
|
|
95
|
+
// src/utils/isAtomFamily.ts
|
|
96
|
+
var isAtomFamily = (state) => state && Object.hasOwn(state, "__valdresAtomFamilyMap");
|
|
97
|
+
|
|
95
98
|
// src/utils/isAtom.ts
|
|
96
99
|
var isAtom = (state) => Object.hasOwn(state, "defaultValue");
|
|
97
100
|
|
|
@@ -101,32 +104,11 @@ var isFamilyState = (state) => state && Object.hasOwn(state, "family");
|
|
|
101
104
|
// src/utils/isFamilyAtom.ts
|
|
102
105
|
var isFamilyAtom = (state) => isFamilyState(state) && isAtom(state);
|
|
103
106
|
|
|
104
|
-
// src/lib/updateStateSubscribers.ts
|
|
105
|
-
var updateStateSubscribers = (state, data) => {
|
|
106
|
-
const subscribtions = data.subscriptions.get(state);
|
|
107
|
-
if (subscribtions?.size) {
|
|
108
|
-
for (const subscribtion of subscribtions) {
|
|
109
|
-
subscribtion.callback();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (isFamilyState(state)) {
|
|
113
|
-
const familySubscriptions = data.subscriptions.get(state.family);
|
|
114
|
-
if (familySubscriptions?.size) {
|
|
115
|
-
for (const subscribtion of familySubscriptions) {
|
|
116
|
-
subscribtion.callback(...state.familyKey);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
107
|
// src/utils/isPromiseLike.ts
|
|
123
108
|
var isPromiseLike = (object) => {
|
|
124
109
|
return object && object.then && typeof object.then === "function";
|
|
125
110
|
};
|
|
126
111
|
|
|
127
|
-
// src/utils/isAtomFamily.ts
|
|
128
|
-
var isAtomFamily = (state) => state && Object.hasOwn(state, "__valdresAtomFamilyMap");
|
|
129
|
-
|
|
130
112
|
// src/utils/isSelector.ts
|
|
131
113
|
var isSelector = (state) => state && Object.hasOwn(state, "get");
|
|
132
114
|
|
|
@@ -226,11 +208,10 @@ var initAtom = (atom, data) => {
|
|
|
226
208
|
const tmpVal = getAtomInitValue(atom, data);
|
|
227
209
|
let value = setValueInData(atom, tmpVal, data);
|
|
228
210
|
if (isFamilyAtom(atom)) {
|
|
229
|
-
const
|
|
230
|
-
if (!
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
setAtom(atom.family.__keysAtom, newSet, data);
|
|
211
|
+
const currentAtoms = data.values.get(atom.family) || [];
|
|
212
|
+
if (!currentAtoms.includes(atom)) {
|
|
213
|
+
data.values.set(atom.family, [...currentAtoms, atom]);
|
|
214
|
+
propagateUpdatedAtoms([atom.family], data);
|
|
234
215
|
}
|
|
235
216
|
}
|
|
236
217
|
if (atom.onInit)
|
|
@@ -250,14 +231,17 @@ function getState(state, data, circularDependencySet) {
|
|
|
250
231
|
return getState(state, data.parent, circularDependencySet);
|
|
251
232
|
return initAtom(state, data);
|
|
252
233
|
}
|
|
253
|
-
if (isSelector(state))
|
|
254
|
-
|
|
234
|
+
if (isSelector(state)) {
|
|
235
|
+
initSelector(state, data, circularDependencySet);
|
|
236
|
+
return data.values.get(state);
|
|
237
|
+
}
|
|
255
238
|
if (isAtomFamily(state)) {
|
|
256
239
|
if ("parent" in data) {
|
|
257
|
-
const closestData = findClosestStoreWithAtomInitialized(state
|
|
258
|
-
return getState(state
|
|
240
|
+
const closestData = findClosestStoreWithAtomInitialized(state, data);
|
|
241
|
+
return getState(state, closestData, circularDependencySet);
|
|
259
242
|
}
|
|
260
|
-
|
|
243
|
+
data.values.set(state, []);
|
|
244
|
+
return data.values.get(state);
|
|
261
245
|
}
|
|
262
246
|
if (isSelectorFamily(state)) {
|
|
263
247
|
const array = Array.from(state.__valdresSelectorFamilyMap.keys());
|
|
@@ -276,6 +260,24 @@ var findClosestStoreWithAtomInitialized = (atom, data) => {
|
|
|
276
260
|
return findClosestStoreWithAtomInitialized(atom, data.parent);
|
|
277
261
|
};
|
|
278
262
|
|
|
263
|
+
// src/lib/updateStateSubscribers.ts
|
|
264
|
+
var updateStateSubscribers = (state, data) => {
|
|
265
|
+
const subscribtions = data.subscriptions.get(state);
|
|
266
|
+
if (subscribtions?.size) {
|
|
267
|
+
for (const subscribtion of subscribtions) {
|
|
268
|
+
subscribtion.callback();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (isFamilyState(state)) {
|
|
272
|
+
const familySubscriptions = data.subscriptions.get(state.family);
|
|
273
|
+
if (familySubscriptions?.size) {
|
|
274
|
+
for (const subscribtion of familySubscriptions) {
|
|
275
|
+
subscribtion.callback(...state.familyArgs);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
279
281
|
// src/errors/lib/generateSelectorTrace.ts
|
|
280
282
|
var generateSelectorTrace = (selectors) => {
|
|
281
283
|
const lastIndex = selectors.length - 1;
|
|
@@ -331,11 +333,11 @@ class SuspendAndWaitForResolveError extends Error {
|
|
|
331
333
|
}
|
|
332
334
|
}
|
|
333
335
|
var getOrInitConsumersSet = (state, data) => {
|
|
334
|
-
const set = data.
|
|
336
|
+
const set = data.stateDependents.get(state);
|
|
335
337
|
if (set)
|
|
336
338
|
return set;
|
|
337
339
|
const newSet = new Set;
|
|
338
|
-
data.
|
|
340
|
+
data.stateDependents.set(state, newSet);
|
|
339
341
|
return newSet;
|
|
340
342
|
};
|
|
341
343
|
var evaluateSelector = (selector, data, circularDependencyMap = new WeakSet) => {
|
|
@@ -392,6 +394,16 @@ var handleSelectorResult = (value, selector, data) => {
|
|
|
392
394
|
}
|
|
393
395
|
};
|
|
394
396
|
var initSelector = (selector, data, circularDependencySet = new WeakSet) => {
|
|
397
|
+
const existingValue = data.values.get(selector);
|
|
398
|
+
const udpatedValue = evaluate(selector, data, circularDependencySet);
|
|
399
|
+
if (selector.equal(existingValue, udpatedValue)) {
|
|
400
|
+
return false;
|
|
401
|
+
} else {
|
|
402
|
+
setValueInData(selector, udpatedValue, data);
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
var evaluate = (selector, data, circularDependencySet) => {
|
|
395
407
|
let tmpValue;
|
|
396
408
|
try {
|
|
397
409
|
tmpValue = evaluateSelector(selector, data, circularDependencySet);
|
|
@@ -400,14 +412,7 @@ var initSelector = (selector, data, circularDependencySet = new WeakSet) => {
|
|
|
400
412
|
e.track(selector);
|
|
401
413
|
throw e;
|
|
402
414
|
}
|
|
403
|
-
|
|
404
|
-
if (data.expiredValues.has(selector)) {
|
|
405
|
-
const expiredValue = data.expiredValues.get(selector);
|
|
406
|
-
if (selector.equal(expiredValue, value)) {
|
|
407
|
-
return setValueInData(selector, expiredValue, data);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
return setValueInData(selector, value, data);
|
|
415
|
+
return handleSelectorResult(tmpValue, selector, data);
|
|
411
416
|
};
|
|
412
417
|
|
|
413
418
|
// src/lib/updateSelectorSubscribers.ts
|
|
@@ -416,14 +421,6 @@ var updateSelectorSubscribers = (selector, data) => {
|
|
|
416
421
|
const familySubscriptions = selector.family && data.subscriptions.get(selector.family);
|
|
417
422
|
if (!subscribtions?.size && !familySubscriptions?.size)
|
|
418
423
|
return;
|
|
419
|
-
if (subscribtions?.size && data.subscriptionsRequireEqualCheck.get(selector) || familySubscriptions?.size && selector.family && data.subscriptionsRequireEqualCheck.get(selector.family)) {
|
|
420
|
-
try {
|
|
421
|
-
const oldValue = data.expiredValues.get(selector);
|
|
422
|
-
const newValue = initSelector(selector, data);
|
|
423
|
-
if (selector.equal(newValue, oldValue))
|
|
424
|
-
return;
|
|
425
|
-
} catch (e) {}
|
|
426
|
-
}
|
|
427
424
|
if (subscribtions?.size) {
|
|
428
425
|
for (const subscribtion of subscribtions) {
|
|
429
426
|
subscribtion.callback();
|
|
@@ -431,21 +428,53 @@ var updateSelectorSubscribers = (selector, data) => {
|
|
|
431
428
|
}
|
|
432
429
|
if (familySubscriptions?.size) {
|
|
433
430
|
for (const subscribtion of familySubscriptions) {
|
|
434
|
-
subscribtion.callback(...selector.
|
|
431
|
+
subscribtion.callback(...selector.familyArgs);
|
|
435
432
|
}
|
|
436
433
|
}
|
|
437
434
|
};
|
|
438
435
|
|
|
439
436
|
// src/lib/propagateUpdatedAtoms.ts
|
|
437
|
+
var revalidate = (selector, data) => {
|
|
438
|
+
try {
|
|
439
|
+
return initSelector(selector, data);
|
|
440
|
+
} catch (e) {
|
|
441
|
+
data.expiredValues.set(selector, data.values.get(selector));
|
|
442
|
+
data.values.delete(selector);
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
};
|
|
440
446
|
var recursivlyResetSelectorTree = (selectors, data, clearedSelectors) => {
|
|
441
447
|
for (const selector of selectors) {
|
|
442
448
|
if (!clearedSelectors.has(selector)) {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
+
const subscribers = data.subscriptions.get(selector);
|
|
450
|
+
const dependents = data.stateDependents.get(selector);
|
|
451
|
+
if (!dependents && !subscribers) {
|
|
452
|
+
data.expiredValues.set(selector, data.values.get(selector));
|
|
453
|
+
data.values.delete(selector);
|
|
454
|
+
} else if (dependents && subscribers) {
|
|
455
|
+
if (dependents.size === 0)
|
|
456
|
+
throw new Error("Should not happen");
|
|
457
|
+
if (subscribers.size === 0)
|
|
458
|
+
throw new Error("Should not happen");
|
|
459
|
+
const isValueUpdated = revalidate(selector, data);
|
|
460
|
+
if (isValueUpdated) {
|
|
461
|
+
recursivlyResetSelectorTree(dependents, data, clearedSelectors);
|
|
462
|
+
updateSelectorSubscribers(selector, data);
|
|
463
|
+
}
|
|
464
|
+
} else if (dependents) {
|
|
465
|
+
if (dependents.size === 0)
|
|
466
|
+
throw new Error("Should not happen");
|
|
467
|
+
const valueUpdated = revalidate(selector, data);
|
|
468
|
+
if (valueUpdated) {
|
|
469
|
+
recursivlyResetSelectorTree(dependents, data, clearedSelectors);
|
|
470
|
+
}
|
|
471
|
+
} else if (subscribers) {
|
|
472
|
+
if (subscribers.size === 0)
|
|
473
|
+
throw new Error("Should not happen");
|
|
474
|
+
const isValueUpdated = revalidate(selector, data);
|
|
475
|
+
if (isValueUpdated) {
|
|
476
|
+
updateSelectorSubscribers(selector, data);
|
|
477
|
+
}
|
|
449
478
|
}
|
|
450
479
|
}
|
|
451
480
|
}
|
|
@@ -453,21 +482,20 @@ var recursivlyResetSelectorTree = (selectors, data, clearedSelectors) => {
|
|
|
453
482
|
var propagateUpdatedAtoms = (atoms, data) => {
|
|
454
483
|
const clearedSelectors = new Set;
|
|
455
484
|
for (const atom of atoms) {
|
|
456
|
-
const
|
|
457
|
-
if (
|
|
458
|
-
recursivlyResetSelectorTree(
|
|
485
|
+
const dependents = data.stateDependents.get(atom);
|
|
486
|
+
if (dependents && dependents.size) {
|
|
487
|
+
recursivlyResetSelectorTree(dependents, data, clearedSelectors);
|
|
459
488
|
}
|
|
460
489
|
if (isFamilyAtom(atom)) {
|
|
461
|
-
const consumersFamily = data.
|
|
490
|
+
const consumersFamily = data.stateDependents.get(atom.family);
|
|
462
491
|
if (consumersFamily?.size) {
|
|
463
492
|
recursivlyResetSelectorTree(consumersFamily, data, clearedSelectors);
|
|
464
493
|
}
|
|
465
494
|
}
|
|
466
495
|
}
|
|
467
|
-
for (const selector of clearedSelectors) {
|
|
468
|
-
updateSelectorSubscribers(selector, data);
|
|
469
|
-
}
|
|
470
496
|
for (const atom of atoms) {
|
|
497
|
+
if (isAtomFamily(atom))
|
|
498
|
+
continue;
|
|
471
499
|
updateStateSubscribers(atom, data);
|
|
472
500
|
}
|
|
473
501
|
};
|
|
@@ -481,7 +509,7 @@ var generateStoreData = (id = generateId()) => {
|
|
|
481
509
|
expiredValues: new WeakMap,
|
|
482
510
|
subscriptions: new WeakMap,
|
|
483
511
|
subscriptionsRequireEqualCheck: new WeakMap,
|
|
484
|
-
|
|
512
|
+
stateDependents: new WeakMap,
|
|
485
513
|
stateDependencies: new WeakMap,
|
|
486
514
|
scopes: {}
|
|
487
515
|
};
|
|
@@ -498,6 +526,20 @@ function createStoreData(id, parent) {
|
|
|
498
526
|
}
|
|
499
527
|
}
|
|
500
528
|
|
|
529
|
+
// src/lib/deleteFamilyAtom.ts
|
|
530
|
+
var deleteFamilyAtom = (atom, data) => {
|
|
531
|
+
const array = data.values.get(atom.family);
|
|
532
|
+
const index = array.indexOf(atom);
|
|
533
|
+
const newArray = [
|
|
534
|
+
...array.slice(0, index),
|
|
535
|
+
...array.slice(index + 1)
|
|
536
|
+
];
|
|
537
|
+
data.values.delete(atom);
|
|
538
|
+
propagateUpdatedAtoms([atom], data);
|
|
539
|
+
setValueInData(atom.family, newArray, data);
|
|
540
|
+
propagateUpdatedAtoms([atom.family], data);
|
|
541
|
+
};
|
|
542
|
+
|
|
501
543
|
// src/lib/resetAtom.ts
|
|
502
544
|
var resetAtom = (atom, data) => {
|
|
503
545
|
let value = getAtomInitValue(atom, data);
|
|
@@ -651,12 +693,12 @@ var setAtoms = (pairs, data) => {
|
|
|
651
693
|
|
|
652
694
|
// src/lib/transaction.ts
|
|
653
695
|
var findDependencies = (state, data, result = new Set) => {
|
|
654
|
-
const
|
|
655
|
-
if (
|
|
656
|
-
for (const
|
|
657
|
-
if (!result.has(
|
|
658
|
-
result.add(
|
|
659
|
-
findDependencies(
|
|
696
|
+
const dependents = data.stateDependents.get(state);
|
|
697
|
+
if (dependents?.size) {
|
|
698
|
+
for (const dependent of dependents) {
|
|
699
|
+
if (!result.has(dependent)) {
|
|
700
|
+
result.add(dependent);
|
|
701
|
+
findDependencies(dependent, data, result);
|
|
660
702
|
}
|
|
661
703
|
}
|
|
662
704
|
}
|
|
@@ -670,33 +712,39 @@ var recursivlyResetTxnSelectorCache = (state, txnSubscribers, txnSelectorCache)
|
|
|
670
712
|
}
|
|
671
713
|
}
|
|
672
714
|
};
|
|
673
|
-
var captureScopedTransaction = (scopedData,
|
|
715
|
+
var captureScopedTransaction = (scopedData, parentGetInTxnOrData) => {
|
|
674
716
|
let txn;
|
|
675
717
|
transaction((scopedTxn) => {
|
|
676
718
|
txn = scopedTxn;
|
|
677
|
-
}, scopedData, false,
|
|
719
|
+
}, scopedData, false, parentGetInTxnOrData);
|
|
678
720
|
return txn;
|
|
679
721
|
};
|
|
680
|
-
var
|
|
722
|
+
var deleteAtomFamilyAtoms = (set, data) => {
|
|
723
|
+
set.forEach((atom) => {
|
|
724
|
+
data.values.delete(atom);
|
|
725
|
+
});
|
|
726
|
+
};
|
|
727
|
+
var transaction = (callback, data, autoCommit = true, parentGetInTxnOrData) => {
|
|
681
728
|
const txnAtomMap = new Map;
|
|
729
|
+
const txnAtomDeleteSet = new Set;
|
|
682
730
|
const txnSelectorCache = new Map;
|
|
683
731
|
const txnSubscribers = new Map;
|
|
684
732
|
const dirtySelectors = new Set;
|
|
685
733
|
let scopedTransactions;
|
|
686
|
-
const
|
|
734
|
+
const getInTxnOrData = (state) => {
|
|
687
735
|
if (txnAtomMap.has(state)) {
|
|
688
736
|
return txnAtomMap.get(state);
|
|
689
737
|
}
|
|
690
738
|
if (data.values.has(state)) {
|
|
691
739
|
return data.values.get(state);
|
|
692
740
|
}
|
|
693
|
-
if (
|
|
694
|
-
return
|
|
741
|
+
if (parentGetInTxnOrData) {
|
|
742
|
+
return parentGetInTxnOrData(state);
|
|
695
743
|
}
|
|
696
744
|
};
|
|
697
745
|
const txnGet = (state) => {
|
|
698
746
|
if (isAtom(state)) {
|
|
699
|
-
const value =
|
|
747
|
+
const value = getInTxnOrData(state);
|
|
700
748
|
if (value)
|
|
701
749
|
return value;
|
|
702
750
|
return getState(state, data);
|
|
@@ -718,7 +766,10 @@ var transaction = (callback, data, autoCommit = true, parentGetFromTxnOrData) =>
|
|
|
718
766
|
txnSelectorCache.set(state, res);
|
|
719
767
|
return res;
|
|
720
768
|
} else if (isAtomFamily(state)) {
|
|
721
|
-
|
|
769
|
+
const value = getInTxnOrData(state);
|
|
770
|
+
if (value)
|
|
771
|
+
return value;
|
|
772
|
+
return getState(state, data);
|
|
722
773
|
} else {
|
|
723
774
|
throw new Error("Unsupported state");
|
|
724
775
|
}
|
|
@@ -743,11 +794,10 @@ var transaction = (callback, data, autoCommit = true, parentGetFromTxnOrData) =>
|
|
|
743
794
|
txnAtomMap.set(atom, deepFreeze(value));
|
|
744
795
|
}
|
|
745
796
|
if (isFamilyAtom(atom)) {
|
|
746
|
-
const
|
|
747
|
-
if (!
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
txnSet(atom.family.__keysAtom, newSet);
|
|
797
|
+
const currentFamilyList = txnGet(atom.family);
|
|
798
|
+
if (!currentFamilyList.includes(atom)) {
|
|
799
|
+
const newArr = [...currentFamilyList, atom];
|
|
800
|
+
txnAtomMap.set(atom.family, newArr);
|
|
751
801
|
}
|
|
752
802
|
}
|
|
753
803
|
return value;
|
|
@@ -757,8 +807,26 @@ var transaction = (callback, data, autoCommit = true, parentGetFromTxnOrData) =>
|
|
|
757
807
|
txnAtomMap.set(atom, value);
|
|
758
808
|
return value;
|
|
759
809
|
};
|
|
810
|
+
const txnDel = (atom) => {
|
|
811
|
+
const array = txnGet(atom.family);
|
|
812
|
+
const index = array.indexOf(atom);
|
|
813
|
+
const newArr = [
|
|
814
|
+
...array.slice(0, index),
|
|
815
|
+
...array.slice(index + 1)
|
|
816
|
+
];
|
|
817
|
+
txnAtomMap.set(atom.family, newArr);
|
|
818
|
+
if (data.values.has(atom)) {
|
|
819
|
+
txnAtomDeleteSet.add(atom);
|
|
820
|
+
}
|
|
821
|
+
if (txnAtomMap.has(atom)) {
|
|
822
|
+
txnAtomMap.delete(atom);
|
|
823
|
+
}
|
|
824
|
+
};
|
|
760
825
|
const commit = () => {
|
|
761
826
|
setAtoms(txnAtomMap, data);
|
|
827
|
+
if (txnAtomDeleteSet.size) {
|
|
828
|
+
deleteAtomFamilyAtoms(txnAtomDeleteSet, data);
|
|
829
|
+
}
|
|
762
830
|
dirtySelectors.clear();
|
|
763
831
|
if (scopedTransactions) {
|
|
764
832
|
for (const scopedTxn of Object.values(scopedTransactions)) {
|
|
@@ -769,6 +837,7 @@ var transaction = (callback, data, autoCommit = true, parentGetFromTxnOrData) =>
|
|
|
769
837
|
const result = callback({
|
|
770
838
|
set: txnSet,
|
|
771
839
|
get: txnGet,
|
|
840
|
+
del: txnDel,
|
|
772
841
|
reset: txnReset,
|
|
773
842
|
commit,
|
|
774
843
|
scope: (scopeId, callback2) => {
|
|
@@ -778,7 +847,7 @@ var transaction = (callback, data, autoCommit = true, parentGetFromTxnOrData) =>
|
|
|
778
847
|
scopedTransactions = {};
|
|
779
848
|
}
|
|
780
849
|
if (scopedTransactions[scopeId] === undefined) {
|
|
781
|
-
scopedTransactions[scopeId] = captureScopedTransaction(scopedData,
|
|
850
|
+
scopedTransactions[scopeId] = captureScopedTransaction(scopedData, getInTxnOrData);
|
|
782
851
|
}
|
|
783
852
|
return callback2(scopedTransactions[scopeId]);
|
|
784
853
|
} else {
|
|
@@ -810,6 +879,7 @@ function storeFromStoreData(data, detach) {
|
|
|
810
879
|
throw new Error(InvalidStateSetError);
|
|
811
880
|
};
|
|
812
881
|
const reset = (atom) => resetAtom(atom, data);
|
|
882
|
+
const deleteFn = (atom) => deleteFamilyAtom(atom, data);
|
|
813
883
|
const sub = (state, callback, deepEqualCheckBeforeCallback = true) => subscribe(state, callback, deepEqualCheckBeforeCallback, data);
|
|
814
884
|
const txn = (callback) => transaction(callback, data);
|
|
815
885
|
const scope = (scopeId) => {
|
|
@@ -837,6 +907,7 @@ function storeFromStoreData(data, detach) {
|
|
|
837
907
|
sub,
|
|
838
908
|
txn,
|
|
839
909
|
reset,
|
|
910
|
+
delete: deleteFn,
|
|
840
911
|
data,
|
|
841
912
|
scope,
|
|
842
913
|
detach
|
|
@@ -848,6 +919,7 @@ function storeFromStoreData(data, detach) {
|
|
|
848
919
|
sub,
|
|
849
920
|
txn,
|
|
850
921
|
reset,
|
|
922
|
+
delete: deleteFn,
|
|
851
923
|
data,
|
|
852
924
|
scope
|
|
853
925
|
};
|
|
@@ -941,13 +1013,6 @@ function atom(defaultValue, options) {
|
|
|
941
1013
|
...options
|
|
942
1014
|
};
|
|
943
1015
|
}
|
|
944
|
-
// src/selector.ts
|
|
945
|
-
var selector = (get, options) => {
|
|
946
|
-
if (!options)
|
|
947
|
-
return { equal, get };
|
|
948
|
-
return { equal, ...options, get };
|
|
949
|
-
};
|
|
950
|
-
|
|
951
1016
|
// src/lib/atomFamilyAtom.ts
|
|
952
1017
|
function atomFamilyAtom(defaultValue, options) {
|
|
953
1018
|
if (options.global) {
|
|
@@ -1014,22 +1079,23 @@ var stableStringify = (x) => {
|
|
|
1014
1079
|
};
|
|
1015
1080
|
|
|
1016
1081
|
// src/lib/stringifyFamilyArgs.ts
|
|
1017
|
-
var stringifyFamilyArgs = (
|
|
1082
|
+
var stringifyFamilyArgs = (args) => {
|
|
1018
1083
|
return args.length === 1 ? stableStringify(args[0]) : stableStringify(args);
|
|
1019
1084
|
};
|
|
1020
1085
|
|
|
1021
1086
|
// src/lib/createAtomFamily.ts
|
|
1022
|
-
var createOptions = (options = {}, family,
|
|
1087
|
+
var createOptions = (options = {}, family, familyArgs, familyArgsStringified) => {
|
|
1023
1088
|
if (options.name) {
|
|
1024
1089
|
return {
|
|
1025
1090
|
equal,
|
|
1026
1091
|
...options,
|
|
1027
|
-
name: options?.name + "_" +
|
|
1092
|
+
name: options?.name + "_" + familyArgsStringified,
|
|
1028
1093
|
family,
|
|
1029
|
-
|
|
1094
|
+
familyArgs,
|
|
1095
|
+
familyArgsStringified
|
|
1030
1096
|
};
|
|
1031
1097
|
} else {
|
|
1032
|
-
return { equal, ...options, family,
|
|
1098
|
+
return { equal, ...options, family, familyArgs, familyArgsStringified };
|
|
1033
1099
|
}
|
|
1034
1100
|
};
|
|
1035
1101
|
var handleDefaultValue = (defaultValue, ...args) => {
|
|
@@ -1041,20 +1107,18 @@ var handleDefaultValue = (defaultValue, ...args) => {
|
|
|
1041
1107
|
};
|
|
1042
1108
|
var createAtomFamily = (defaultValue, options) => {
|
|
1043
1109
|
const map = new Map;
|
|
1044
|
-
const keysAtom = atom(new Set);
|
|
1045
1110
|
const atomFamily = Object.assign((...args) => {
|
|
1046
|
-
const
|
|
1047
|
-
if (map.has(
|
|
1048
|
-
return map.get(
|
|
1111
|
+
const argsStringified = stringifyFamilyArgs(args);
|
|
1112
|
+
if (map.has(argsStringified)) {
|
|
1113
|
+
return map.get(argsStringified);
|
|
1049
1114
|
}
|
|
1050
|
-
const familyAtom = atomFamilyAtom(handleDefaultValue(defaultValue, ...args), createOptions(options, atomFamily, args,
|
|
1051
|
-
map.set(
|
|
1115
|
+
const familyAtom = atomFamilyAtom(handleDefaultValue(defaultValue, ...args), createOptions(options, atomFamily, args, argsStringified));
|
|
1116
|
+
map.set(argsStringified, familyAtom);
|
|
1052
1117
|
return familyAtom;
|
|
1053
1118
|
}, {
|
|
1054
1119
|
__valdresAtomFamilyMap: map,
|
|
1055
|
-
release: (...args) => map.delete(stringifyFamilyArgs(
|
|
1056
|
-
|
|
1057
|
-
__keysSelector: selector((get) => Array.from(get(keysAtom)))
|
|
1120
|
+
release: (...args) => map.delete(stringifyFamilyArgs(args)),
|
|
1121
|
+
equal
|
|
1058
1122
|
});
|
|
1059
1123
|
if (options?.name)
|
|
1060
1124
|
Object.defineProperty(atomFamily, "name", {
|
|
@@ -1083,8 +1147,8 @@ function atomFamily(defaultValue, options) {
|
|
|
1083
1147
|
return createAtomFamily(defaultValue, options);
|
|
1084
1148
|
}
|
|
1085
1149
|
// src/createStoreWithSelectorSet.ts
|
|
1086
|
-
var setSelector = (
|
|
1087
|
-
return
|
|
1150
|
+
var setSelector = (selector, values, store2) => {
|
|
1151
|
+
return selector.set(store2.set, store2.get, store2.reset, ...values);
|
|
1088
1152
|
};
|
|
1089
1153
|
var createStoreWithSelectorSet = (id) => {
|
|
1090
1154
|
const data = createStoreData(id);
|
|
@@ -1099,59 +1163,82 @@ var createStoreWithSelectorSet = (id) => {
|
|
|
1099
1163
|
store2.kind = "storeWithSelectorSet";
|
|
1100
1164
|
return store2;
|
|
1101
1165
|
};
|
|
1166
|
+
// src/selector.ts
|
|
1167
|
+
var selector = (get, options) => {
|
|
1168
|
+
if (!options)
|
|
1169
|
+
return { equal, get };
|
|
1170
|
+
return { equal, ...options, get };
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1102
1173
|
// src/indexConstructor.ts
|
|
1103
|
-
var index = (family, callback) => {
|
|
1174
|
+
var index = (family, callback, options) => {
|
|
1104
1175
|
const map = new Map;
|
|
1105
|
-
|
|
1176
|
+
const indexFn = (term) => {
|
|
1106
1177
|
const termKey = stableStringify(term);
|
|
1107
1178
|
if (map.has(termKey))
|
|
1108
1179
|
return map.get(termKey);
|
|
1109
|
-
const
|
|
1110
|
-
const
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1180
|
+
const termIndexSelectorSet = new Set;
|
|
1181
|
+
const termIndexSelectorMap = new Map;
|
|
1182
|
+
const termIndexSelector = selector((get) => {
|
|
1183
|
+
const allFamilyAtoms = new Set(get(family));
|
|
1184
|
+
const deletedAtoms = termIndexSelectorSet.symmetricDifference(allFamilyAtoms);
|
|
1185
|
+
const addedAtoms = allFamilyAtoms.difference(termIndexSelectorSet);
|
|
1186
|
+
if (deletedAtoms.size || addedAtoms.size) {
|
|
1187
|
+
deletedAtoms.forEach((atom2) => {
|
|
1188
|
+
termIndexSelectorSet.delete(atom2);
|
|
1189
|
+
termIndexSelectorMap.delete(atom2);
|
|
1190
|
+
});
|
|
1191
|
+
addedAtoms.forEach((atom2) => {
|
|
1192
|
+
termIndexSelectorSet.add(atom2);
|
|
1193
|
+
termIndexSelectorMap.set(atom2, selector((get2) => callback(get2(atom2), term), {
|
|
1194
|
+
name: `index:callback:selector:${atom2.name}`
|
|
1195
|
+
}));
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
return termIndexSelectorSet;
|
|
1199
|
+
}, { name: `index:${options?.name}:${termKey}` });
|
|
1119
1200
|
const filteredSelector = selector((get) => {
|
|
1120
|
-
const
|
|
1201
|
+
const set = get(termIndexSelector);
|
|
1121
1202
|
const res = [];
|
|
1122
|
-
|
|
1123
|
-
if (get(
|
|
1124
|
-
res.push(
|
|
1203
|
+
set.forEach((atom2) => {
|
|
1204
|
+
if (get(termIndexSelectorMap.get(atom2))) {
|
|
1205
|
+
res.push(atom2);
|
|
1125
1206
|
}
|
|
1126
1207
|
});
|
|
1127
1208
|
return res;
|
|
1209
|
+
}, {
|
|
1210
|
+
name: `index:${options?.name}:${termKey}:termSelector`
|
|
1128
1211
|
});
|
|
1129
1212
|
map.set(termKey, filteredSelector);
|
|
1130
1213
|
return filteredSelector;
|
|
1131
1214
|
};
|
|
1215
|
+
return Object.assign(indexFn, {
|
|
1216
|
+
map
|
|
1217
|
+
});
|
|
1132
1218
|
};
|
|
1133
1219
|
// src/selectorFamily.ts
|
|
1134
|
-
var createOptions2 = (options = {}, family,
|
|
1220
|
+
var createOptions2 = (options = {}, family, familyArgs, familyArgsStringified) => {
|
|
1135
1221
|
if (options.name) {
|
|
1136
1222
|
return {
|
|
1137
1223
|
equal,
|
|
1138
1224
|
...options,
|
|
1139
|
-
name: options?.name + "_" +
|
|
1225
|
+
name: options?.name + "_" + familyArgsStringified,
|
|
1140
1226
|
family,
|
|
1141
|
-
|
|
1227
|
+
familyArgs,
|
|
1228
|
+
familyArgsStringified
|
|
1142
1229
|
};
|
|
1143
1230
|
} else {
|
|
1144
|
-
return { equal, ...options, family,
|
|
1231
|
+
return { equal, ...options, family, familyArgs, familyArgsStringified };
|
|
1145
1232
|
}
|
|
1146
1233
|
};
|
|
1147
1234
|
var selectorFamily = (callback, options) => {
|
|
1148
1235
|
const map = new Map;
|
|
1149
1236
|
const selectorFamily2 = (...args) => {
|
|
1150
|
-
const
|
|
1151
|
-
if (map.has(
|
|
1152
|
-
return map.get(
|
|
1153
|
-
const newSelector = selector((selectorArgs) => callback(...args)(selectorArgs), createOptions2(options, selectorFamily2, args,
|
|
1154
|
-
map.set(
|
|
1237
|
+
const argsStringified = stringifyFamilyArgs(args);
|
|
1238
|
+
if (map.has(argsStringified))
|
|
1239
|
+
return map.get(argsStringified);
|
|
1240
|
+
const newSelector = selector((selectorArgs) => callback(...args)(selectorArgs), createOptions2(options, selectorFamily2, args, argsStringified));
|
|
1241
|
+
map.set(argsStringified, newSelector);
|
|
1155
1242
|
return newSelector;
|
|
1156
1243
|
};
|
|
1157
1244
|
selectorFamily2.__valdresSelectorFamilyMap = map;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { AtomFamily } from "./types/AtomFamily";
|
|
2
2
|
import type { Selector } from "./types/Selector";
|
|
3
|
-
export declare const index: <Term, Value extends unknown, FamilyArgs extends [any, ...any[]] = [any, ...any[]]>(family: AtomFamily<Value, FamilyArgs>, callback: (value: Value, term: Term) => boolean
|
|
3
|
+
export declare const index: <Term, Value extends unknown, FamilyArgs extends [any, ...any[]] = [any, ...any[]]>(family: AtomFamily<Value, FamilyArgs>, callback: (value: Value, term: Term) => boolean, options?: {
|
|
4
|
+
name?: string;
|
|
5
|
+
}) => ((term: Term) => Selector<Term[]>);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AtomFamilyAtom } from "../types/AtomFamilyAtom";
|
|
2
|
+
import type { StoreData } from "../types/StoreData";
|
|
3
|
+
export declare const deleteFamilyAtom: <Value extends unknown, Args extends [any, ...any[]] = [any, ...any[]]>(atom: AtomFamilyAtom<Value, Args>, data: StoreData) => void;
|
|
@@ -2,6 +2,7 @@ import type { Atom } from "../types/Atom";
|
|
|
2
2
|
import type { AtomFamily } from "../types/AtomFamily";
|
|
3
3
|
import type { Selector } from "../types/Selector";
|
|
4
4
|
import type { StoreData } from "../types/StoreData";
|
|
5
|
+
import type { AtomFamilyAtom } from "../types/AtomFamilyAtom";
|
|
5
6
|
export declare function getState<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]>(atom: Atom<Value>, data: StoreData, circularDependencySet?: WeakSet<Selector>): Value;
|
|
6
7
|
export declare function getState<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]>(selector: Selector<Value>, data: StoreData, circularDependencySet?: WeakSet<Selector>): Value;
|
|
7
|
-
export declare function getState<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]>(family: AtomFamily<Value, Args>, data: StoreData, circularDependencySet?: WeakSet<Selector>): Args[];
|
|
8
|
+
export declare function getState<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]>(family: AtomFamily<Value, Args>, data: StoreData, circularDependencySet?: WeakSet<Selector>): AtomFamilyAtom<Value, Args>[];
|
|
@@ -2,4 +2,4 @@ import type { Atom } from "../types/Atom";
|
|
|
2
2
|
import type { AtomFamilyAtom } from "../types/AtomFamilyAtom";
|
|
3
3
|
import type { StoreData } from "../types/StoreData";
|
|
4
4
|
export declare const getAtomInitValue: <V = any>(atom: Atom<V>, data: StoreData) => any;
|
|
5
|
-
export declare const initAtom: <Value extends unknown, Args extends [any, ...any[]] = [any, ...any[]]>(atom: Atom<Value> | AtomFamilyAtom<Value, Args>, data: StoreData) =>
|
|
5
|
+
export declare const initAtom: <Value extends unknown, Args extends [any, ...any[]] = [any, ...any[]]>(atom: Atom<Value> | AtomFamilyAtom<Value, Args>, data: StoreData) => any;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { StoreData } from "../types/StoreData";
|
|
2
2
|
import type { Selector } from "../types/Selector";
|
|
3
|
-
export declare const initSelector: <V>(selector: Selector<V>, data: StoreData, circularDependencySet?: WeakSet<WeakKey>) =>
|
|
3
|
+
export declare const initSelector: <V>(selector: Selector<V>, data: StoreData, circularDependencySet?: WeakSet<WeakKey>) => boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Atom } from "../types/Atom";
|
|
2
|
-
import type {
|
|
2
|
+
import type { AtomFamily } from "../types/AtomFamily";
|
|
3
3
|
import type { AtomFamilyAtom } from "../types/AtomFamilyAtom";
|
|
4
|
-
|
|
4
|
+
import type { StoreData } from "../types/StoreData";
|
|
5
|
+
export declare const propagateUpdatedAtoms: (atoms: (Atom<any> | AtomFamilyAtom<any, any> | AtomFamily<any, any>)[], data: StoreData) => void;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { Atom } from "../types/Atom";
|
|
2
|
+
import type { AtomFamily } from "../types/AtomFamily";
|
|
2
3
|
import type { StoreData } from "../types/StoreData";
|
|
3
|
-
export declare const setValueInData: <Value
|
|
4
|
+
export declare const setValueInData: <Value extends unknown>(atom: Atom<Value> | AtomFamily<any, any>, value: Value, data: StoreData) => Value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const stringifyFamilyArgs: (
|
|
1
|
+
export declare const stringifyFamilyArgs: (args: any[]) => string | number | boolean;
|
|
@@ -4,5 +4,5 @@ import type { TransactionFn } from "../types/TransactionFn";
|
|
|
4
4
|
type GetAtomValue = {
|
|
5
5
|
<V>(atom: Atom<V>): V;
|
|
6
6
|
};
|
|
7
|
-
export declare const transaction: (callback: TransactionFn, data: StoreData, autoCommit?: boolean,
|
|
7
|
+
export declare const transaction: (callback: TransactionFn, data: StoreData, autoCommit?: boolean, parentGetInTxnOrData?: GetAtomValue) => any;
|
|
8
8
|
export {};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import type { Atom } from "./Atom";
|
|
2
1
|
import type { AtomFamilyAtom } from "./AtomFamilyAtom";
|
|
3
|
-
import type {
|
|
2
|
+
import type { EqualFunc } from "./EqualFunc";
|
|
4
3
|
export type AtomFamily<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]> = {
|
|
5
4
|
(...args: Args): AtomFamilyAtom<Value, Args>;
|
|
6
5
|
release: (...args: Args) => void;
|
|
6
|
+
equal: EqualFunc<Value>;
|
|
7
7
|
name?: string;
|
|
8
8
|
__valdresAtomFamilyMap: Map<Value, AtomFamilyAtom<Value, Args>>;
|
|
9
|
-
__keysAtom: Atom<Set<Args>>;
|
|
10
|
-
__keysSelector: Selector<Args[]>;
|
|
11
9
|
};
|
|
@@ -2,5 +2,6 @@ import type { Atom } from "./Atom";
|
|
|
2
2
|
import type { AtomFamily } from "./AtomFamily";
|
|
3
3
|
export type AtomFamilyAtom<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]> = Atom<Value> & {
|
|
4
4
|
family: AtomFamily<Value, Args>;
|
|
5
|
-
|
|
5
|
+
familyArgs: Args;
|
|
6
|
+
familyArgsStringified: string;
|
|
6
7
|
};
|
|
@@ -2,5 +2,5 @@ import type { Selector } from "./Selector";
|
|
|
2
2
|
import type { SelectorFamily } from "./SelectorFamily";
|
|
3
3
|
export type AtomFamilySelector<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]> = Selector<Value> & {
|
|
4
4
|
family: SelectorFamily<Value, Args>;
|
|
5
|
-
|
|
5
|
+
familyArgs: Args;
|
|
6
6
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Atom } from "./Atom";
|
|
2
2
|
import type { AtomFamily } from "./AtomFamily";
|
|
3
|
+
import type { AtomFamilyAtom } from "./AtomFamilyAtom";
|
|
3
4
|
import type { Selector } from "./Selector";
|
|
4
5
|
export type GetValue = {
|
|
5
6
|
<Value extends any>(atom: Atom<Value>): Value;
|
|
6
7
|
<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]>(selector: Selector<Value, Args>): Value;
|
|
7
|
-
<Value extends any, Args extends [any, ...any[]]>(family: AtomFamily<Value, Args>): Args[];
|
|
8
|
+
<Value extends any, Args extends [any, ...any[]]>(family: AtomFamily<Value, Args>): AtomFamilyAtom<Value, Args>[];
|
|
8
9
|
};
|
|
@@ -6,6 +6,6 @@ export type Selector<Value extends any = any, FamilyArgs extends [any, ...any[]]
|
|
|
6
6
|
equal: EqualFunc<Value>;
|
|
7
7
|
name?: string;
|
|
8
8
|
family?: SelectorFamily<Value, FamilyArgs>;
|
|
9
|
-
|
|
9
|
+
familyArgs?: FamilyArgs;
|
|
10
10
|
onMount?: () => void | (() => void);
|
|
11
11
|
};
|
|
@@ -9,12 +9,14 @@ type SetAtom = {
|
|
|
9
9
|
<Value extends any, Args extends [any, ...any[]] = [any, ...any[]]>(atom: AtomFamilyAtom<Value, Args>, value: Value): void;
|
|
10
10
|
<Value extends any>(atom: Atom<Value>, value: Value): void;
|
|
11
11
|
};
|
|
12
|
+
type DeleteAtom = <Value extends any, Args extends [any, ...any[]] = [any, ...any[]]>(atom: AtomFamilyAtom<Value, Args>) => void;
|
|
12
13
|
export type Store<T = StoreData> = {
|
|
13
14
|
data: T;
|
|
14
15
|
get: GetValue;
|
|
15
16
|
set: SetAtom;
|
|
16
17
|
sub: SubscribeFn;
|
|
17
18
|
reset: ResetAtom;
|
|
19
|
+
delete: DeleteAtom;
|
|
18
20
|
txn: (callback: TransactionFn) => void;
|
|
19
21
|
scope: (scopeId: string) => ScopedStore;
|
|
20
22
|
};
|
|
@@ -4,7 +4,7 @@ export type RootStoreData = {
|
|
|
4
4
|
expiredValues: WeakMap<WeakKey, any>;
|
|
5
5
|
subscriptions: WeakMap<WeakKey, Set<any>>;
|
|
6
6
|
subscriptionsRequireEqualCheck: WeakMap<WeakKey, boolean>;
|
|
7
|
-
|
|
7
|
+
stateDependents: WeakMap<WeakKey, any>;
|
|
8
8
|
stateDependencies: WeakMap<WeakKey, any>;
|
|
9
9
|
scopes: {
|
|
10
10
|
[scopeId: string]: ScopedStoreData;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Atom } from "./Atom";
|
|
2
|
+
import type { AtomFamilyAtom } from "./AtomFamilyAtom";
|
|
2
3
|
import type { GetValue } from "./GetValue";
|
|
3
4
|
import type { ResetAtom } from "./ResetAtom";
|
|
4
5
|
import type { SetAtom } from "./SetAtom";
|
|
@@ -10,6 +11,7 @@ export type SetAtom2 = {
|
|
|
10
11
|
export type TransactionInterface = {
|
|
11
12
|
set: SetAtom;
|
|
12
13
|
get: GetValue;
|
|
14
|
+
del: (atom: AtomFamilyAtom<any, any>) => void;
|
|
13
15
|
reset: ResetAtom;
|
|
14
16
|
commit: () => void;
|
|
15
17
|
scope: <Callback extends TransactionFn>(scopeId: string, callback: Callback) => ReturnType<Callback>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valdres",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.77",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Eigil Sagafos"
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"access": "public",
|
|
37
37
|
"registry": "https://registry.npmjs.org/"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "5db5dd8048a395672fc07c874108a620deb5d06d"
|
|
40
40
|
}
|