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 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 currentKeySet = getState(atom.family.__keysAtom, data);
230
- if (!currentKeySet.has(atom.familyKey)) {
231
- const newSet = new Set(currentKeySet);
232
- newSet.add(atom.familyKey);
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
- return initSelector(state, data, circularDependencySet);
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.__keysAtom, data);
258
- return getState(state.__keysSelector, closestData, circularDependencySet);
240
+ const closestData = findClosestStoreWithAtomInitialized(state, data);
241
+ return getState(state, closestData, circularDependencySet);
259
242
  }
260
- return getState(state.__keysSelector, data, circularDependencySet);
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.stateConsumers.get(state);
336
+ const set = data.stateDependents.get(state);
335
337
  if (set)
336
338
  return set;
337
339
  const newSet = new Set;
338
- data.stateConsumers.set(state, newSet);
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
- const value = handleSelectorResult(tmpValue, selector, data);
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.familyKey);
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
- clearedSelectors.add(selector);
444
- data.expiredValues.set(selector, data.values.get(selector));
445
- data.values.delete(selector);
446
- const consumers = data.stateConsumers.get(selector);
447
- if (consumers?.size) {
448
- recursivlyResetSelectorTree(consumers, data, clearedSelectors);
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 consumers = data.stateConsumers.get(atom);
457
- if (consumers && consumers.size) {
458
- recursivlyResetSelectorTree(consumers, data, clearedSelectors);
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.stateConsumers.get(atom.family);
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
- stateConsumers: new WeakMap,
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 consumers = data.stateConsumers.get(state);
655
- if (consumers?.size) {
656
- for (const consumer of consumers) {
657
- if (!result.has(consumer)) {
658
- result.add(consumer);
659
- findDependencies(consumer, data, result);
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, parentGetFromTxnOrData) => {
715
+ var captureScopedTransaction = (scopedData, parentGetInTxnOrData) => {
674
716
  let txn;
675
717
  transaction((scopedTxn) => {
676
718
  txn = scopedTxn;
677
- }, scopedData, false, parentGetFromTxnOrData);
719
+ }, scopedData, false, parentGetInTxnOrData);
678
720
  return txn;
679
721
  };
680
- var transaction = (callback, data, autoCommit = true, parentGetFromTxnOrData) => {
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 getFromTxnOrData = (state) => {
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 (parentGetFromTxnOrData) {
694
- return parentGetFromTxnOrData(state);
741
+ if (parentGetInTxnOrData) {
742
+ return parentGetInTxnOrData(state);
695
743
  }
696
744
  };
697
745
  const txnGet = (state) => {
698
746
  if (isAtom(state)) {
699
- const value = getFromTxnOrData(state);
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
- return txnGet(state.__keysSelector);
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 currentKeySet = txnGet(atom.family.__keysAtom);
747
- if (!currentKeySet.has(atom.familyKey)) {
748
- const newSet = new Set(currentKeySet);
749
- newSet.add(atom.familyKey);
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, getFromTxnOrData);
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 = (...args) => {
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, familyKey, keyStringified) => {
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 + "_" + keyStringified,
1092
+ name: options?.name + "_" + familyArgsStringified,
1028
1093
  family,
1029
- familyKey
1094
+ familyArgs,
1095
+ familyArgsStringified
1030
1096
  };
1031
1097
  } else {
1032
- return { equal, ...options, family, familyKey };
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 keyStringified = stringifyFamilyArgs(...args);
1047
- if (map.has(keyStringified)) {
1048
- return map.get(keyStringified);
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, keyStringified));
1051
- map.set(keyStringified, familyAtom);
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(...args)),
1056
- __keysAtom: keysAtom,
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 = (selector2, values, store2) => {
1087
- return selector2.set(store2.set, store2.get, store2.reset, ...values);
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
- return (term) => {
1176
+ const indexFn = (term) => {
1106
1177
  const termKey = stableStringify(term);
1107
1178
  if (map.has(termKey))
1108
1179
  return map.get(termKey);
1109
- const itemSelectorMap = new Map;
1110
- const selectorMapIndex = selector((get) => {
1111
- const array = get(family);
1112
- array.forEach((args) => {
1113
- if (itemSelectorMap.has(args))
1114
- return;
1115
- itemSelectorMap.set(args, selector((get2) => callback(get2(family(...args)), term)));
1116
- });
1117
- return itemSelectorMap;
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 map2 = get(selectorMapIndex);
1201
+ const set = get(termIndexSelector);
1121
1202
  const res = [];
1122
- map2.forEach((selector2, key) => {
1123
- if (get(selector2)) {
1124
- res.push(key);
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, familyKey, keyStringified) => {
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 + "_" + keyStringified,
1225
+ name: options?.name + "_" + familyArgsStringified,
1140
1226
  family,
1141
- familyKey
1227
+ familyArgs,
1228
+ familyArgsStringified
1142
1229
  };
1143
1230
  } else {
1144
- return { equal, ...options, family, familyKey };
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 keyStringified = stringifyFamilyArgs(args);
1151
- if (map.has(keyStringified))
1152
- return map.get(keyStringified);
1153
- const newSelector = selector((selectorArgs) => callback(...args)(selectorArgs), createOptions2(options, selectorFamily2, args, keyStringified));
1154
- map.set(keyStringified, newSelector);
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) => ((term: Term) => Selector<Term[]>);
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) => Value;
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>) => V | Promise<V>;
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 { StoreData } from "../types/StoreData";
2
+ import type { AtomFamily } from "../types/AtomFamily";
3
3
  import type { AtomFamilyAtom } from "../types/AtomFamilyAtom";
4
- export declare const propagateUpdatedAtoms: (atoms: (Atom<any> | AtomFamilyAtom<any, any>)[], data: StoreData) => void;
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 = any>(atom: Atom<Value>, value: Value, data: StoreData) => 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: (...args: any[]) => string | number | boolean;
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, parentGetFromTxnOrData?: GetAtomValue) => any;
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 { Selector } from "./Selector";
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
- familyKey: Args;
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
- familyKey: Args;
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
- familyKey?: FamilyArgs;
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
- stateConsumers: WeakMap<WeakKey, any>;
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.75",
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": "c6757088042bf15b35010217442c65f2a5e666a7"
39
+ "gitHead": "5db5dd8048a395672fc07c874108a620deb5d06d"
40
40
  }