atom.io 0.33.21 → 0.34.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/eslint-plugin/index.js +1 -2
  2. package/dist/eslint-plugin/index.js.map +1 -1
  3. package/dist/internal/index.d.ts +10 -6
  4. package/dist/internal/index.d.ts.map +1 -1
  5. package/dist/internal/index.js +1262 -1253
  6. package/dist/internal/index.js.map +1 -1
  7. package/dist/json/index.d.ts +3 -0
  8. package/dist/json/index.d.ts.map +1 -1
  9. package/dist/json/index.js.map +1 -1
  10. package/dist/main/index.d.ts +405 -23
  11. package/dist/main/index.d.ts.map +1 -1
  12. package/dist/main/index.js +107 -11
  13. package/dist/main/index.js.map +1 -1
  14. package/dist/realtime-client/index.js +6 -10
  15. package/dist/realtime-client/index.js.map +1 -1
  16. package/dist/realtime-server/index.js +1 -1
  17. package/dist/realtime-server/index.js.map +1 -1
  18. package/dist/realtime-testing/index.d.ts.map +1 -1
  19. package/dist/realtime-testing/index.js +0 -1
  20. package/dist/realtime-testing/index.js.map +1 -1
  21. package/package.json +6 -6
  22. package/src/internal/atom/create-regular-atom.ts +6 -7
  23. package/src/internal/caching.ts +9 -9
  24. package/src/internal/future.ts +3 -0
  25. package/src/internal/get-state/read-or-compute-value.ts +12 -7
  26. package/src/internal/join/create-join.ts +27 -0
  27. package/src/internal/join/index.ts +1 -0
  28. package/src/internal/junction.ts +2 -0
  29. package/src/internal/mutable/create-mutable-atom.ts +2 -4
  30. package/src/internal/selector/create-readonly-held-selector.ts +10 -0
  31. package/src/internal/selector/create-readonly-pure-selector.ts +13 -4
  32. package/src/internal/selector/create-writable-held-selector.ts +11 -2
  33. package/src/internal/selector/create-writable-pure-selector.ts +11 -1
  34. package/src/internal/selector/trace-selector-atoms.ts +18 -40
  35. package/src/internal/selector/update-selector-atoms.ts +5 -5
  36. package/src/internal/set-state/evict-downstream.ts +2 -2
  37. package/src/internal/set-state/reset-atom-or-selector.ts +3 -3
  38. package/src/internal/store/store.ts +0 -1
  39. package/src/internal/subscribe/subscribe-to-root-atoms.ts +42 -38
  40. package/src/internal/subscribe/subscribe-to-state.ts +23 -11
  41. package/src/json/index.ts +3 -0
  42. package/src/main/atom.ts +54 -13
  43. package/src/main/dispose-state.ts +8 -2
  44. package/src/main/find-state.ts +44 -14
  45. package/src/main/get-state.ts +2 -2
  46. package/src/main/index.ts +8 -0
  47. package/src/main/join.ts +79 -22
  48. package/src/main/realm.ts +50 -4
  49. package/src/main/selector.ts +116 -6
  50. package/src/main/subscribe.ts +31 -1
  51. package/src/main/timeline.ts +17 -0
  52. package/src/main/transaction.ts +39 -3
  53. package/src/realtime-client/realtime-client-stores/client-sync-store.ts +2 -2
  54. package/src/realtime-testing/setup-realtime-test.tsx +0 -5
@@ -1,4 +1,4 @@
1
- import { arbitrary as arbitrary$1, subscribeToState as subscribeToState$1, subscribeToTimeline as subscribeToTimeline$1, subscribeToTransaction as subscribeToTransaction$1 } from "atom.io/internal";
1
+ import { Join as Join$1, arbitrary as arbitrary$1, subscribeToState as subscribeToState$1, subscribeToTimeline as subscribeToTimeline$1, subscribeToTransaction as subscribeToTransaction$1 } from "atom.io/internal";
2
2
  import { parseJson, selectJson, selectJsonFamily, stringifyJson } from "atom.io/json";
3
3
  import { Anarchy, AtomIOLogger } from "atom.io";
4
4
  import { SetRTX } from "atom.io/transceivers/set-rtx";
@@ -8,61 +8,6 @@ function arbitrary(random = Math.random) {
8
8
  return random().toString(36).slice(2);
9
9
  }
10
10
 
11
- //#endregion
12
- //#region src/internal/future.ts
13
- /**
14
- * A Promise whose incoming value can be hot swapped.
15
- * @internal
16
- * @private
17
- * @typeParam T The type of the value that the promise will resolve to.
18
- *
19
- * @remarks
20
- * Can be constructed like a Promise, or from an existing Promise.
21
- */
22
- var Future = class extends Promise {
23
- fate;
24
- resolve;
25
- reject;
26
- done = false;
27
- constructor(executor) {
28
- let superResolve;
29
- let superReject;
30
- super((resolve, reject) => {
31
- superResolve = resolve;
32
- superReject = reject;
33
- });
34
- this.resolve = superResolve;
35
- this.reject = superReject;
36
- this.use(executor instanceof Promise ? executor : new Promise(executor));
37
- }
38
- pass(promise, value) {
39
- if (promise === this.fate) {
40
- this.resolve(value);
41
- this.done = true;
42
- }
43
- }
44
- fail(promise, reason) {
45
- if (promise === this.fate) {
46
- this.reject(reason);
47
- this.done = true;
48
- }
49
- }
50
- use(value) {
51
- if (value instanceof Promise) {
52
- const promise = value;
53
- this.fate = promise;
54
- promise.then((resolved) => {
55
- this.pass(promise, resolved);
56
- }, (reason) => {
57
- this.fail(promise, reason);
58
- });
59
- } else {
60
- this.resolve(value);
61
- this.fate = void 0;
62
- }
63
- }
64
- };
65
-
66
11
  //#endregion
67
12
  //#region src/internal/lineage.ts
68
13
  function newest(scion) {
@@ -300,12 +245,11 @@ var Junction = class {
300
245
  }
301
246
  break;
302
247
  }
303
- default: {
248
+ default:
304
249
  a = params[0];
305
250
  b = params[1];
306
251
  content = params[2];
307
252
  break;
308
- }
309
253
  }
310
254
  switch (this.cardinality) {
311
255
  case `1:1`: {
@@ -432,85 +376,107 @@ var StatefulSubject = class extends Subject {
432
376
  };
433
377
 
434
378
  //#endregion
435
- //#region src/internal/transaction/is-root-store.ts
436
- function isRootStore(store) {
437
- return `epoch` in store.transactionMeta;
438
- }
439
- function isChildStore(store) {
440
- return `phase` in store.transactionMeta;
441
- }
442
-
443
- //#endregion
444
- //#region src/internal/transaction/abort-transaction.ts
445
- const abortTransaction = (store) => {
379
+ //#region src/internal/subscribe/recall-state.ts
380
+ const recallState = (store, state) => {
446
381
  const target = newest(store);
447
- if (!isChildStore(target)) {
448
- store.logger.warn(`🐞`, `transaction`, `???`, `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`);
449
- return;
450
- }
451
- store.logger.info(`🪂`, `transaction`, target.transactionMeta.update.key, `Aborting transaction`);
452
- target.parent.child = null;
382
+ if (target.operation.open) return target.operation.prev.get(state.key);
383
+ return target.valueMap.get(state.key);
453
384
  };
454
385
 
455
386
  //#endregion
456
- //#region src/internal/capitalize.ts
457
- function capitalize(string) {
458
- return string[0].toUpperCase() + string.slice(1);
459
- }
460
-
461
- //#endregion
462
- //#region src/internal/pretty-print.ts
463
- function prettyPrintTokenType(token) {
464
- return token.type.split(`_`).map(capitalize).join(` `);
387
+ //#region src/internal/subscribe/subscribe-in-store.ts
388
+ function subscribeInStore(store, token, handleUpdate, key = arbitrary$1()) {
389
+ switch (token.type) {
390
+ case `atom`:
391
+ case `mutable_atom`:
392
+ case `readonly_pure_selector`:
393
+ case `readonly_held_selector`:
394
+ case `writable_pure_selector`:
395
+ case `writable_held_selector`: return subscribeToState$1(store, token, key, handleUpdate);
396
+ case `transaction`: return subscribeToTransaction$1(store, token, key, handleUpdate);
397
+ case `timeline`: return subscribeToTimeline$1(store, token, key, handleUpdate);
398
+ }
465
399
  }
466
400
 
467
401
  //#endregion
468
- //#region src/internal/not-found-error.ts
469
- var NotFoundError = class extends Error {
470
- constructor(token, store) {
471
- super(`${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
402
+ //#region src/internal/future.ts
403
+ /**
404
+ * A Promise whose incoming value can be hot swapped.
405
+ * @internal
406
+ * @private
407
+ * @typeParam T The type of the value that the promise will resolve to.
408
+ *
409
+ * @remarks
410
+ * Can be constructed like a Promise, or from an existing Promise.
411
+ */
412
+ var Future = class extends Promise {
413
+ fate;
414
+ resolve;
415
+ reject;
416
+ done = false;
417
+ constructor(executor) {
418
+ let superResolve;
419
+ let superReject;
420
+ super((resolve, reject) => {
421
+ superResolve = resolve;
422
+ superReject = reject;
423
+ });
424
+ this.resolve = superResolve;
425
+ this.reject = superReject;
426
+ this.use(executor instanceof Promise ? executor : new Promise(executor));
427
+ }
428
+ pass(promise, value) {
429
+ if (promise === this.fate) {
430
+ this.resolve(value);
431
+ this.done = true;
432
+ }
433
+ }
434
+ fail(promise, reason) {
435
+ if (promise === this.fate) {
436
+ this.reject(reason);
437
+ this.done = true;
438
+ }
439
+ }
440
+ use(value) {
441
+ if (this === value) return;
442
+ if (value instanceof Promise) {
443
+ const promise = value;
444
+ this.fate = promise;
445
+ promise.then((resolved) => {
446
+ this.pass(promise, resolved);
447
+ }, (reason) => {
448
+ this.fail(promise, reason);
449
+ });
450
+ } else {
451
+ this.resolve(value);
452
+ this.fate = void 0;
453
+ }
472
454
  }
473
455
  };
474
456
 
475
457
  //#endregion
476
- //#region src/internal/transaction/act-upon-store.ts
477
- function actUponStore(store, token, id) {
478
- return (...parameters) => {
479
- const tx = withdraw(store, token);
480
- if (tx) return tx.run(parameters, id);
481
- throw new NotFoundError(token, store);
482
- };
458
+ //#region src/internal/set-state/copy-mutable-if-needed.ts
459
+ function copyMutableIfNeeded(target, atom$1, origin) {
460
+ const originValue = origin.valueMap.get(atom$1.key);
461
+ const targetValue = target.valueMap.get(atom$1.key);
462
+ if (originValue !== targetValue) return targetValue;
463
+ if (originValue === void 0) return atom$1.default();
464
+ origin.logger.info(`📃`, `atom`, atom$1.key, `copying`);
465
+ const jsonValue = atom$1.toJson(originValue);
466
+ const copiedValue = atom$1.fromJson(jsonValue);
467
+ target.valueMap.set(atom$1.key, copiedValue);
468
+ new Tracker(atom$1, origin);
469
+ return copiedValue;
483
470
  }
484
471
 
485
472
  //#endregion
486
- //#region src/internal/set-state/become.ts
487
- const become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
488
-
489
- //#endregion
490
- //#region src/internal/get-state/read-or-compute-value.ts
491
- const readOrComputeValue = (target, state) => {
492
- if (target.valueMap.has(state.key)) {
493
- target.logger.info(`📖`, state.type, state.key, `reading cached value`);
494
- return readCachedValue(state, target);
495
- }
496
- switch (state.type) {
497
- case `readonly_held_selector`:
498
- case `readonly_pure_selector`:
499
- case `writable_held_selector`:
500
- case `writable_pure_selector`:
501
- target.logger.info(`🧮`, state.type, state.key, `computing value`);
502
- return state.get();
503
- case `atom`:
504
- case `mutable_atom`: {
505
- const def = state.default;
506
- let fallback;
507
- if (def instanceof Function) fallback = def();
508
- else fallback = def;
509
- target.logger.info(`💁`, `atom`, state.key, `could not find cached value; using default`, fallback);
510
- return fallback;
511
- }
512
- }
513
- };
473
+ //#region src/internal/transaction/is-root-store.ts
474
+ function isRootStore(store) {
475
+ return `epoch` in store.transactionMeta;
476
+ }
477
+ function isChildStore(store) {
478
+ return `phase` in store.transactionMeta;
479
+ }
514
480
 
515
481
  //#endregion
516
482
  //#region src/internal/operation.ts
@@ -549,22 +515,6 @@ const markDone = (store, key) => {
549
515
  store.operation.done.add(key);
550
516
  };
551
517
 
552
- //#endregion
553
- //#region src/internal/set-state/emit-update.ts
554
- const emitUpdate = (store, state, update) => {
555
- switch (state.type) {
556
- case `mutable_atom`:
557
- store.logger.info(`📢`, state.type, state.key, `is now (`, update.newValue, `) subscribers:`, state.subject.subscribers);
558
- break;
559
- case `atom`:
560
- case `writable_pure_selector`:
561
- case `readonly_pure_selector`:
562
- case `writable_held_selector`:
563
- case `readonly_held_selector`: store.logger.info(`📢`, state.type, state.key, `went (`, update.oldValue, `->`, update.newValue, `) subscribers:`, state.subject.subscribers);
564
- }
565
- state.subject.next(update);
566
- };
567
-
568
518
  //#endregion
569
519
  //#region src/internal/set-state/evict-downstream.ts
570
520
  function evictDownStream(store, atom$1) {
@@ -575,7 +525,7 @@ function evictDownStream(store, atom$1) {
575
525
  if (target.operation.open) target.logger.info(`🧹`, atom$1.type, atom$1.key, `[ ${[...target.operation.done].join(`, `)} ] already done`);
576
526
  for (const key of downstreamKeys) {
577
527
  if (isDone(target, key)) continue;
578
- evictCachedValue(key, target);
528
+ evictCachedValue(target, key);
579
529
  markDone(target, key);
580
530
  }
581
531
  }
@@ -585,81 +535,117 @@ function evictDownStreamFromSelector(store, selector) {
585
535
  const relationEntries = target.selectorGraph.getRelationEntries({ upstreamSelectorKey: selector.key }).filter(([_, { source }]) => source === selector.key);
586
536
  for (const [downstreamSelectorKey] of relationEntries) {
587
537
  if (isDone(target, downstreamSelectorKey)) continue;
588
- evictCachedValue(downstreamSelectorKey, target);
538
+ evictCachedValue(target, downstreamSelectorKey);
589
539
  markDone(target, downstreamSelectorKey);
590
540
  }
591
541
  }
592
542
 
593
543
  //#endregion
594
- //#region src/internal/set-state/set-atom.ts
595
- const setAtom = (target, atom$1, next) => {
596
- const oldValue = readOrComputeValue(target, atom$1);
597
- let newValue = oldValue;
598
- if (atom$1.type === `mutable_atom` && isChildStore(target)) {
599
- const { parent } = target;
600
- const copiedValue = copyMutableIfNeeded(target, atom$1, parent);
601
- newValue = copiedValue;
602
- }
603
- newValue = become(next)(newValue);
604
- target.logger.info(`📝`, `atom`, atom$1.key, `set to`, newValue);
605
- newValue = cacheValue(target, atom$1.key, newValue, atom$1.subject);
606
- markDone(target, atom$1.key);
607
- evictDownStream(target, atom$1);
608
- const update = {
609
- oldValue,
610
- newValue
611
- };
612
- if (!isChildStore(target)) {
613
- emitUpdate(target, atom$1, update);
614
- return;
544
+ //#region src/internal/caching.ts
545
+ function cacheValue(target, key, value, subject) {
546
+ const currentValue = target.valueMap.get(key);
547
+ if (currentValue instanceof Future && !currentValue.done) {
548
+ const future = currentValue;
549
+ if (value instanceof Promise) {
550
+ future.use(value);
551
+ return future;
552
+ }
553
+ target.valueMap.set(key, value);
554
+ return value;
615
555
  }
616
- if (target.on.transactionApplying.state === null) {
617
- const { key } = atom$1;
618
- if (isTransceiver(update.newValue)) return;
619
- const atomUpdate = {
620
- type: `atom_update`,
621
- key,
622
- ...update
623
- };
624
- if (atom$1.family) atomUpdate.family = atom$1.family;
625
- target.transactionMeta.update.updates.push(atomUpdate);
626
- target.logger.info(`📁`, `atom`, key, `stowed (`, update.oldValue, `->`, update.newValue, `)`);
627
- } else if (atom$1.key.startsWith(`*`)) {
628
- const mutableKey = atom$1.key.slice(1);
629
- const mutableAtom = target.atoms.get(mutableKey);
630
- let transceiver = target.valueMap.get(mutableKey);
631
- if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
632
- const { parent } = target;
633
- const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
634
- transceiver = copiedValue;
635
- }
636
- const accepted = transceiver.do(update.newValue) === null;
637
- if (accepted) evictDownStream(target, mutableAtom);
556
+ if (value instanceof Promise) {
557
+ const future = new Future(value);
558
+ target.valueMap.set(key, future);
559
+ future.then(function handleResolvedFuture(resolved) {
560
+ const current = target.valueMap.get(key);
561
+ if (current === future) {
562
+ cacheValue(target, key, resolved, subject);
563
+ const atom$1 = target.atoms.get(key);
564
+ if (atom$1) {
565
+ openOperation(target, atom$1);
566
+ evictDownStream(target, atom$1);
567
+ closeOperation(target);
568
+ } else {
569
+ const selector = target.writableSelectors.get(key) ?? target.readonlySelectors.get(key);
570
+ if (selector) {
571
+ openOperation(target, selector);
572
+ evictDownStreamFromSelector(target, selector);
573
+ closeOperation(target);
574
+ }
575
+ }
576
+ subject.next({
577
+ newValue: resolved,
578
+ oldValue: future
579
+ });
580
+ }
581
+ }).catch((thrown) => {
582
+ target.logger.error(`💥`, `state`, key, `rejected:`, thrown);
583
+ });
584
+ return future;
585
+ }
586
+ target.valueMap.set(key, value);
587
+ return value;
588
+ }
589
+ const readCachedValue = (state, target) => {
590
+ target.logger.info(`📖`, state.type, state.key, `reading cached value`);
591
+ let value = target.valueMap.get(state.key);
592
+ if (state.type === `mutable_atom` && isChildStore(target)) {
593
+ const { parent } = target;
594
+ const copiedValue = copyMutableIfNeeded(target, state, parent);
595
+ value = copiedValue;
596
+ }
597
+ return value;
598
+ };
599
+ const evictCachedValue = (target, key) => {
600
+ const currentValue = target.valueMap.get(key);
601
+ if (currentValue instanceof Future) {
602
+ const selector = target.writableSelectors.get(key) ?? target.readonlySelectors.get(key);
603
+ if (selector) selector.get();
604
+ return;
638
605
  }
606
+ if (target.operation.open) target.operation.prev.set(key, currentValue);
607
+ target.valueMap.delete(key);
608
+ target.logger.info(`🗑`, `state`, key, `evicted`);
639
609
  };
640
610
 
641
611
  //#endregion
642
- //#region src/internal/set-state/reset-atom-or-selector.ts
643
- function resetAtom(store, state) {
644
- let def = state.default;
645
- if (def instanceof Function) def = def();
646
- setAtom(store, state, def);
647
- }
648
- function resetAtomOrSelector(store, state) {
612
+ //#region src/internal/get-state/read-or-compute-value.ts
613
+ const readOrComputeValue = (target, state) => {
614
+ if (target.valueMap.has(state.key)) return readCachedValue(state, target);
649
615
  switch (state.type) {
650
- case `atom`:
651
- case `mutable_atom`:
652
- resetAtom(store, state);
653
- break;
654
- case `writable_pure_selector`:
616
+ case `readonly_held_selector`:
617
+ case `readonly_pure_selector`:
655
618
  case `writable_held_selector`:
656
- {
657
- const atoms = traceAllSelectorAtoms(state, store);
658
- for (const atom$1 of atoms) resetAtom(store, atom$1);
659
- }
660
- break;
619
+ case `writable_pure_selector`:
620
+ target.logger.info(`🧮`, state.type, state.key, `computing value`);
621
+ return state.get();
622
+ case `atom`:
623
+ case `mutable_atom`: {
624
+ const def = state.default;
625
+ let defaultValue;
626
+ if (def instanceof Function) defaultValue = def();
627
+ else defaultValue = def;
628
+ const cachedValue = cacheValue(target, state.key, defaultValue, state.subject);
629
+ target.logger.info(`💁`, `atom`, state.key, `could not find cached value; using default`, defaultValue);
630
+ return cachedValue;
631
+ }
661
632
  }
662
- }
633
+ };
634
+
635
+ //#endregion
636
+ //#region src/internal/subscribe/subscribe-to-root-atoms.ts
637
+ const subscribeToRootDependency = (target, selector, atom$1) => {
638
+ return atom$1.subject.subscribe(`${selector.type}:${selector.key}`, (atomChange) => {
639
+ target.logger.info(`📢`, selector.type, selector.key, `root`, atom$1.key, `went`, atomChange.oldValue, `->`, atomChange.newValue);
640
+ const oldValue = recallState(target, selector);
641
+ const newValue = readOrComputeValue(target, selector);
642
+ target.logger.info(`✨`, selector.type, selector.key, `went`, oldValue, `->`, newValue);
643
+ selector.subject.next({
644
+ newValue,
645
+ oldValue
646
+ });
647
+ });
648
+ };
663
649
 
664
650
  //#endregion
665
651
  //#region src/internal/families/create-regular-atom-family.ts
@@ -711,65 +697,255 @@ function createAtomFamily(store, options) {
711
697
  }
712
698
 
713
699
  //#endregion
714
- //#region src/internal/keys.ts
715
- const isAtomKey = (store, key) => newest(store).atoms.has(key);
716
- const isSelectorKey = (store, key) => newest(store).writableSelectors.has(key);
717
- const isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
718
- const isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
700
+ //#region src/internal/set-state/become.ts
701
+ const become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing instanceof Function ? nextVersionOfThing(originalThing) : nextVersionOfThing;
719
702
 
720
703
  //#endregion
721
- //#region src/internal/selector/get-selector-dependency-keys.ts
722
- const getSelectorDependencyKeys = (store, key) => {
723
- const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
724
- return sources;
704
+ //#region src/internal/set-state/emit-update.ts
705
+ const emitUpdate = (store, state, update) => {
706
+ switch (state.type) {
707
+ case `mutable_atom`:
708
+ store.logger.info(`📢`, state.type, state.key, `is now (`, update.newValue, `) subscribers:`, state.subject.subscribers);
709
+ break;
710
+ case `atom`:
711
+ case `writable_pure_selector`:
712
+ case `readonly_pure_selector`:
713
+ case `writable_held_selector`:
714
+ case `readonly_held_selector`: store.logger.info(`📢`, state.type, state.key, `went (`, update.oldValue, `->`, update.newValue, `) subscribers:`, state.subject.subscribers);
715
+ }
716
+ state.subject.next(update);
725
717
  };
726
718
 
727
719
  //#endregion
728
- //#region src/internal/selector/trace-selector-atoms.ts
729
- const traceSelectorAtoms = (store, directDependencyKey, covered) => {
730
- const rootKeys = [];
731
- const indirectDependencyKeys = getSelectorDependencyKeys(store, directDependencyKey);
732
- while (indirectDependencyKeys.length > 0) {
733
- const indirectDependencyKey = indirectDependencyKeys.shift();
734
- if (covered.has(indirectDependencyKey)) continue;
735
- covered.add(indirectDependencyKey);
736
- if (!isAtomKey(store, indirectDependencyKey)) indirectDependencyKeys.push(...getSelectorDependencyKeys(store, indirectDependencyKey));
737
- else if (!rootKeys.includes(indirectDependencyKey)) rootKeys.push(indirectDependencyKey);
738
- }
739
- return rootKeys;
740
- };
741
- const traceAllSelectorAtoms = (selector, store) => {
742
- const selectorKey = selector.key;
743
- const directDependencyKeys = getSelectorDependencyKeys(store, selectorKey);
744
- const covered = /* @__PURE__ */ new Set();
745
- return directDependencyKeys.flatMap((depKey) => isAtomKey(store, depKey) ? depKey : traceSelectorAtoms(store, depKey, covered)).map((atomKey) => store.atoms.get(atomKey));
720
+ //#region src/internal/set-state/set-atom.ts
721
+ const setAtom = (target, atom$1, next) => {
722
+ const oldValue = readOrComputeValue(target, atom$1);
723
+ let newValue = oldValue;
724
+ if (atom$1.type === `mutable_atom` && isChildStore(target)) {
725
+ const { parent } = target;
726
+ const copiedValue = copyMutableIfNeeded(target, atom$1, parent);
727
+ newValue = copiedValue;
728
+ }
729
+ newValue = become(next)(newValue);
730
+ target.logger.info(`📝`, `atom`, atom$1.key, `set to`, newValue);
731
+ newValue = cacheValue(target, atom$1.key, newValue, atom$1.subject);
732
+ markDone(target, atom$1.key);
733
+ evictDownStream(target, atom$1);
734
+ const update = {
735
+ oldValue,
736
+ newValue
737
+ };
738
+ if (!isChildStore(target)) {
739
+ emitUpdate(target, atom$1, update);
740
+ return;
741
+ }
742
+ if (target.on.transactionApplying.state === null) {
743
+ const { key } = atom$1;
744
+ if (isTransceiver(update.newValue)) return;
745
+ const atomUpdate = {
746
+ type: `atom_update`,
747
+ key,
748
+ ...update
749
+ };
750
+ if (atom$1.family) atomUpdate.family = atom$1.family;
751
+ target.transactionMeta.update.updates.push(atomUpdate);
752
+ target.logger.info(`📁`, `atom`, key, `stowed (`, update.oldValue, `->`, update.newValue, `)`);
753
+ } else if (atom$1.key.startsWith(`*`)) {
754
+ const mutableKey = atom$1.key.slice(1);
755
+ const mutableAtom = target.atoms.get(mutableKey);
756
+ let transceiver = target.valueMap.get(mutableKey);
757
+ if (mutableAtom.type === `mutable_atom` && isChildStore(target)) {
758
+ const { parent } = target;
759
+ const copiedValue = copyMutableIfNeeded(target, mutableAtom, parent);
760
+ transceiver = copiedValue;
761
+ }
762
+ const accepted = transceiver.do(update.newValue) === null;
763
+ if (accepted) evictDownStream(target, mutableAtom);
764
+ }
746
765
  };
747
766
 
748
767
  //#endregion
749
- //#region src/internal/selector/update-selector-atoms.ts
750
- const updateSelectorAtoms = (store, selectorType, selectorKey, dependency, covered) => {
751
- const target = newest(store);
752
- const { type: dependencyType, key: dependencyKey } = dependency;
753
- if (dependencyType === `atom` || dependencyType === `mutable_atom`) {
754
- target.selectorAtoms.set({
755
- selectorKey,
756
- atomKey: dependencyKey
757
- });
758
- store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atom "${dependencyKey}"`);
768
+ //#region src/internal/set-state/reset-atom-or-selector.ts
769
+ function resetAtom(store, state) {
770
+ let def = state.default;
771
+ if (def instanceof Function) def = def();
772
+ setAtom(store, state, def);
773
+ }
774
+ function resetAtomOrSelector(store, state) {
775
+ switch (state.type) {
776
+ case `atom`:
777
+ case `mutable_atom`:
778
+ resetAtom(store, state);
779
+ break;
780
+ case `writable_pure_selector`:
781
+ case `writable_held_selector`:
782
+ {
783
+ const atoms = traceRootSelectorAtoms(store, state.key);
784
+ for (const atom$1 of atoms.values()) resetAtom(store, atom$1);
785
+ }
786
+ break;
787
+ }
788
+ }
789
+
790
+ //#endregion
791
+ //#region src/internal/families/get-family-of-token.ts
792
+ function getFamilyOfToken(store, token) {
793
+ if (token.family) {
794
+ const family = store.families.get(token.family.key);
795
+ if (family) return family;
796
+ }
797
+ }
798
+
799
+ //#endregion
800
+ //#region src/internal/set-state/reset-in-store.ts
801
+ function resetInStore(store, ...params) {
802
+ let token;
803
+ let family;
804
+ let key;
805
+ if (params.length === 1) {
806
+ token = params[0];
807
+ family = getFamilyOfToken(store, token) ?? null;
808
+ if (family) {
809
+ key = token.family ? parseJson(token.family.subKey) : null;
810
+ token = findInStore(store, family, key);
811
+ }
759
812
  } else {
760
- const rootKeys = traceSelectorAtoms(store, dependencyKey, covered);
761
- store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atoms: [ ${rootKeys.map((key) => `"${key}"`).join(`, `)} ]`);
762
- for (const atomKey of rootKeys) target.selectorAtoms = target.selectorAtoms.set({
763
- selectorKey,
764
- atomKey
813
+ family = params[0];
814
+ key = params[1];
815
+ token = findInStore(store, family, key);
816
+ }
817
+ if (`counterfeit` in token && `family` in token) {
818
+ const subKey = token.family.subKey;
819
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
820
+ store.logger.error(`❌`, token.type, token.key, `could not be reset because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
821
+ return;
822
+ }
823
+ const rejectionTime = openOperation(store, token);
824
+ if (rejectionTime) {
825
+ const unsubscribe = store.on.operationClose.subscribe(`waiting to reset "${token.key}" at T-${rejectionTime}`, () => {
826
+ unsubscribe();
827
+ store.logger.info(`🟢`, token.type, token.key, `resuming deferred resetState from T-${rejectionTime}`);
828
+ resetInStore(store, token);
765
829
  });
830
+ return;
831
+ }
832
+ const state = withdraw(store, token);
833
+ resetAtomOrSelector(store, state);
834
+ closeOperation(store);
835
+ }
836
+
837
+ //#endregion
838
+ //#region src/internal/set-state/set-atom-or-selector.ts
839
+ const setAtomOrSelector = (store, state, value) => {
840
+ switch (state.type) {
841
+ case `atom`:
842
+ case `mutable_atom`:
843
+ setAtom(store, state, value);
844
+ break;
845
+ case `writable_pure_selector`:
846
+ case `writable_held_selector`:
847
+ state.set(value);
848
+ break;
766
849
  }
767
- covered.add(dependencyKey);
768
850
  };
769
851
 
770
852
  //#endregion
771
- //#region src/internal/selector/register-selector.ts
772
- const registerSelector = (store, selectorType, selectorKey, covered) => ({
853
+ //#region src/internal/set-state/set-into-store.ts
854
+ function setIntoStore(store, ...params) {
855
+ let token;
856
+ let family;
857
+ let key;
858
+ let value;
859
+ if (params.length === 2) {
860
+ token = params[0];
861
+ value = params[1];
862
+ family = getFamilyOfToken(store, token) ?? null;
863
+ if (family) {
864
+ key = token.family ? parseJson(token.family.subKey) : null;
865
+ token = findInStore(store, family, key);
866
+ }
867
+ } else {
868
+ family = params[0];
869
+ key = params[1];
870
+ value = params[2];
871
+ token = findInStore(store, family, key);
872
+ }
873
+ if (`counterfeit` in token && `family` in token) {
874
+ const subKey = token.family.subKey;
875
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
876
+ store.logger.error(`❌`, token.type, token.key, `could not be set because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
877
+ return;
878
+ }
879
+ const rejectionTime = openOperation(store, token);
880
+ if (rejectionTime) {
881
+ const unsubscribe = store.on.operationClose.subscribe(`waiting to set "${token.key}" at T-${rejectionTime}`, () => {
882
+ unsubscribe();
883
+ store.logger.info(`🟢`, token.type, token.key, `resuming deferred setState from T-${rejectionTime}`);
884
+ setIntoStore(store, token, value);
885
+ });
886
+ return;
887
+ }
888
+ const state = withdraw(store, token);
889
+ setAtomOrSelector(store, state, value);
890
+ closeOperation(store);
891
+ }
892
+
893
+ //#endregion
894
+ //#region src/internal/keys.ts
895
+ const isAtomKey = (store, key) => newest(store).atoms.has(key);
896
+ const isSelectorKey = (store, key) => newest(store).writableSelectors.has(key);
897
+ const isReadonlySelectorKey = (store, key) => newest(store).readonlySelectors.has(key);
898
+ const isStateKey = (store, key) => isAtomKey(store, key) || isSelectorKey(store, key) || isReadonlySelectorKey(store, key);
899
+
900
+ //#endregion
901
+ //#region src/internal/selector/get-selector-dependency-keys.ts
902
+ const getSelectorDependencyKeys = (store, key) => {
903
+ const sources = newest(store).selectorGraph.getRelationEntries({ downstreamSelectorKey: key }).filter(([_, { source }]) => source !== key).map(([_, { source }]) => source).filter((source) => isStateKey(store, source));
904
+ return sources;
905
+ };
906
+
907
+ //#endregion
908
+ //#region src/internal/selector/trace-selector-atoms.ts
909
+ const traceRootSelectorAtoms = (store, selectorKey, covered = /* @__PURE__ */ new Set()) => {
910
+ const dependencies = getSelectorDependencyKeys(store, selectorKey);
911
+ const roots = /* @__PURE__ */ new Map();
912
+ while (dependencies.length > 0) {
913
+ const dependencyKey = dependencies.pop();
914
+ if (covered.has(dependencyKey)) continue;
915
+ covered.add(dependencyKey);
916
+ if (isAtomKey(store, dependencyKey)) {
917
+ const atom$1 = store.atoms.get(dependencyKey);
918
+ roots.set(atom$1.key, atom$1);
919
+ } else dependencies.push(...getSelectorDependencyKeys(store, dependencyKey));
920
+ }
921
+ return roots;
922
+ };
923
+
924
+ //#endregion
925
+ //#region src/internal/selector/update-selector-atoms.ts
926
+ const updateSelectorAtoms = (store, selectorType, selectorKey, dependency, covered) => {
927
+ const target = newest(store);
928
+ const { type: dependencyType, key: dependencyKey } = dependency;
929
+ if (dependencyType === `atom` || dependencyType === `mutable_atom`) {
930
+ target.selectorAtoms.set({
931
+ selectorKey,
932
+ atomKey: dependencyKey
933
+ });
934
+ store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atom "${dependencyKey}"`);
935
+ } else {
936
+ const rootKeys = traceRootSelectorAtoms(store, dependencyKey, covered);
937
+ store.logger.info(`🔍`, selectorType, selectorKey, `discovers root atoms: [ ${[...rootKeys.values()].map((root) => `"${root.key}"`).join(`, `)} ]`);
938
+ for (const { key: atomKey } of rootKeys.values()) target.selectorAtoms = target.selectorAtoms.set({
939
+ selectorKey,
940
+ atomKey
941
+ });
942
+ }
943
+ covered.add(dependencyKey);
944
+ };
945
+
946
+ //#endregion
947
+ //#region src/internal/selector/register-selector.ts
948
+ const registerSelector = (store, selectorType, selectorKey, covered) => ({
773
949
  get: (...params) => {
774
950
  const target = newest(store);
775
951
  let dependency;
@@ -818,6 +994,10 @@ const createReadonlyHeldSelector = (store, options, family) => {
818
994
  const type = `readonly_held_selector`;
819
995
  const { get, find, json } = registerSelector(target, type, key, covered);
820
996
  const getSelf = () => {
997
+ const innerTarget = newest(store);
998
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
999
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1000
+ innerTarget.selectorAtoms.delete(key);
821
1001
  options.get({
822
1002
  get,
823
1003
  find,
@@ -855,14 +1035,19 @@ const createReadonlyPureSelector = (store, options, family) => {
855
1035
  const type = `readonly_pure_selector`;
856
1036
  const { get, find, json } = registerSelector(target, type, key, covered);
857
1037
  const getSelf = () => {
1038
+ const innerTarget = newest(store);
1039
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1040
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1041
+ innerTarget.selectorAtoms.delete(key);
858
1042
  const value = options.get({
859
1043
  get,
860
1044
  find,
861
1045
  json
862
1046
  });
863
- cacheValue(newest(store), key, value, subject);
1047
+ const cached = cacheValue(innerTarget, key, value, subject);
1048
+ store.logger.info(`✨`, type, key, `=`, cached);
864
1049
  covered.clear();
865
- return value;
1050
+ return cached;
866
1051
  };
867
1052
  const readonlySelector = {
868
1053
  ...options,
@@ -873,8 +1058,6 @@ const createReadonlyPureSelector = (store, options, family) => {
873
1058
  ...family && { family }
874
1059
  };
875
1060
  target.readonlySelectors.set(key, readonlySelector);
876
- const initialValue = getSelf();
877
- store.logger.info(`✨`, type, key, `=`, initialValue);
878
1061
  const token = {
879
1062
  key,
880
1063
  type
@@ -884,639 +1067,66 @@ const createReadonlyPureSelector = (store, options, family) => {
884
1067
  };
885
1068
 
886
1069
  //#endregion
887
- //#region src/internal/selector/create-writable-held-selector.ts
888
- const createWritableHeldSelector = (store, options, family) => {
1070
+ //#region src/internal/transaction/abort-transaction.ts
1071
+ const abortTransaction = (store) => {
889
1072
  const target = newest(store);
890
- const subject = new Subject();
891
- const covered = /* @__PURE__ */ new Set();
892
- const { key, const: constant } = options;
893
- const type = `writable_held_selector`;
894
- const setterToolkit = registerSelector(target, type, key, covered);
895
- const { find, get, json } = setterToolkit;
896
- const getterToolkit = {
897
- find,
898
- get,
899
- json
900
- };
901
- const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
902
- getFn(getterToolkit, constant);
903
- cacheValue(innerTarget, key, constant, subject);
904
- covered.clear();
905
- return constant;
906
- };
907
- const setSelf = (next) => {
908
- const innerTarget = newest(store);
909
- const oldValue = getSelf(options.get, innerTarget);
910
- const newValue = become(next)(oldValue);
911
- store.logger.info(`📝`, type, key, `set (`, oldValue, `->`, newValue, `)`);
912
- cacheValue(innerTarget, key, newValue, subject);
913
- markDone(innerTarget, key);
914
- if (isRootStore(innerTarget)) subject.next({
915
- newValue,
916
- oldValue
917
- });
918
- options.set(setterToolkit, newValue);
919
- };
920
- const mySelector = {
921
- ...options,
922
- type,
923
- subject,
924
- install: (s) => createWritableHeldSelector(s, options, family),
925
- get: getSelf,
926
- set: setSelf,
927
- ...family && { family }
928
- };
929
- target.writableSelectors.set(key, mySelector);
930
- const initialValue = getSelf();
931
- store.logger.info(`✨`, type, key, `=`, initialValue);
932
- const token = {
933
- key,
934
- type
935
- };
936
- if (family) token.family = family;
937
- return token;
1073
+ if (!isChildStore(target)) {
1074
+ store.logger.warn(`🐞`, `transaction`, `???`, `abortTransaction called outside of a transaction. This is probably a bug in AtomIO.`);
1075
+ return;
1076
+ }
1077
+ store.logger.info(`🪂`, `transaction`, target.transactionMeta.update.key, `Aborting transaction`);
1078
+ target.parent.child = null;
938
1079
  };
939
1080
 
940
1081
  //#endregion
941
- //#region src/internal/selector/create-writable-pure-selector.ts
942
- const createWritablePureSelector = (store, options, family) => {
943
- const target = newest(store);
944
- const subject = new Subject();
945
- const covered = /* @__PURE__ */ new Set();
946
- const key = options.key;
947
- const type = `writable_pure_selector`;
948
- const setterToolkit = registerSelector(target, type, key, covered);
949
- const { find, get, json } = setterToolkit;
950
- const getterToolkit = {
951
- find,
952
- get,
953
- json
954
- };
955
- const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
956
- const value = getFn(getterToolkit);
957
- cacheValue(innerTarget, key, value, subject);
958
- covered.clear();
959
- return value;
960
- };
961
- const setSelf = (next) => {
962
- const innerTarget = newest(store);
963
- const oldValue = getSelf(options.get, innerTarget);
964
- const newValue = become(next)(oldValue);
965
- store.logger.info(`📝`, type, key, `set (`, oldValue, `->`, newValue, `)`);
966
- cacheValue(innerTarget, options.key, newValue, subject);
967
- markDone(innerTarget, options.key);
968
- if (isRootStore(innerTarget)) subject.next({
969
- newValue,
970
- oldValue
971
- });
972
- options.set(setterToolkit, newValue);
973
- };
974
- const mySelector = {
975
- ...options,
976
- type,
977
- subject,
978
- install: (s) => createWritablePureSelector(s, options, family),
979
- get: getSelf,
980
- set: setSelf,
981
- ...family && { family }
1082
+ //#region src/internal/capitalize.ts
1083
+ function capitalize(string) {
1084
+ return string[0].toUpperCase() + string.slice(1);
1085
+ }
1086
+
1087
+ //#endregion
1088
+ //#region src/internal/pretty-print.ts
1089
+ function prettyPrintTokenType(token) {
1090
+ return token.type.split(`_`).map(capitalize).join(` `);
1091
+ }
1092
+
1093
+ //#endregion
1094
+ //#region src/internal/not-found-error.ts
1095
+ var NotFoundError = class extends Error {
1096
+ constructor(token, store) {
1097
+ super(`${prettyPrintTokenType(token)} ${stringifyJson(token.key)} not found in store "${store.config.name}".`);
1098
+ }
1099
+ };
1100
+
1101
+ //#endregion
1102
+ //#region src/internal/transaction/act-upon-store.ts
1103
+ function actUponStore(store, token, id) {
1104
+ return (...parameters) => {
1105
+ const tx = withdraw(store, token);
1106
+ if (tx) return tx.run(parameters, id);
1107
+ throw new NotFoundError(token, store);
982
1108
  };
983
- target.writableSelectors.set(key, mySelector);
984
- const initialValue = getSelf();
985
- store.logger.info(`✨`, mySelector.type, mySelector.key, `=`, initialValue);
1109
+ }
1110
+
1111
+ //#endregion
1112
+ //#region src/internal/ingest-updates/ingest-atom-update.ts
1113
+ function ingestAtomUpdate(applying, atomUpdate, store) {
1114
+ const { key, newValue, oldValue } = atomUpdate;
1115
+ const value = applying === `newValue` ? newValue : oldValue;
986
1116
  const token = {
987
1117
  key,
988
- type
1118
+ type: `atom`
989
1119
  };
990
- if (family) token.family = family;
991
- return token;
992
- };
1120
+ if (atomUpdate.family) Object.assign(token, { family: atomUpdate.family });
1121
+ setIntoStore(store, token, value);
1122
+ }
993
1123
 
994
1124
  //#endregion
995
- //#region src/internal/selector/create-standalone-selector.ts
996
- function createStandaloneSelector(store, options) {
997
- const isWritable = `set` in options;
998
- const isHeld = `const` in options;
999
- if (isHeld && isWritable) {
1000
- const state$1 = createWritableHeldSelector(store, options, void 0);
1001
- store.on.selectorCreation.next(state$1);
1002
- return state$1;
1003
- }
1004
- if (isHeld) {
1005
- const state$1 = createReadonlyHeldSelector(store, options, void 0);
1006
- store.on.selectorCreation.next(state$1);
1007
- return state$1;
1008
- }
1009
- if (isWritable) {
1010
- const state$1 = createWritablePureSelector(store, options, void 0);
1011
- store.on.selectorCreation.next(state$1);
1012
- return state$1;
1013
- }
1014
- const state = createReadonlyPureSelector(store, options, void 0);
1015
- store.on.selectorCreation.next(state);
1016
- return state;
1017
- }
1018
-
1019
- //#endregion
1020
- //#region src/internal/selector/dispose-selector.ts
1021
- function disposeSelector(store, selectorToken) {
1022
- const target = newest(store);
1023
- const { key, type } = selectorToken;
1024
- const selector = withdraw(target, selectorToken);
1025
- if (!selector.family) store.logger.error(`❌`, type, key, `Standalone selectors cannot be disposed.`);
1026
- else {
1027
- const molecule = target.molecules.get(selector.family.subKey);
1028
- if (molecule) target.moleculeData.delete(selector.family.subKey, selector.family.key);
1029
- let familyToken;
1030
- switch (selectorToken.type) {
1031
- case `writable_held_selector`:
1032
- {
1033
- target.writableSelectors.delete(key);
1034
- familyToken = {
1035
- key: selector.family.key,
1036
- type: `writable_held_selector_family`
1037
- };
1038
- const family = withdraw(store, familyToken);
1039
- family.subject.next({
1040
- type: `state_disposal`,
1041
- subType: `selector`,
1042
- token: selectorToken
1043
- });
1044
- }
1045
- break;
1046
- case `writable_pure_selector`:
1047
- {
1048
- target.writableSelectors.delete(key);
1049
- familyToken = {
1050
- key: selector.family.key,
1051
- type: `writable_pure_selector_family`
1052
- };
1053
- const family = withdraw(store, familyToken);
1054
- family.subject.next({
1055
- type: `state_disposal`,
1056
- subType: `selector`,
1057
- token: selectorToken
1058
- });
1059
- }
1060
- break;
1061
- case `readonly_held_selector`:
1062
- {
1063
- target.readonlySelectors.delete(key);
1064
- familyToken = {
1065
- key: selector.family.key,
1066
- type: `readonly_held_selector_family`
1067
- };
1068
- const family = withdraw(store, familyToken);
1069
- family.subject.next({
1070
- type: `state_disposal`,
1071
- subType: `selector`,
1072
- token: selectorToken
1073
- });
1074
- }
1075
- break;
1076
- case `readonly_pure_selector`:
1077
- {
1078
- target.readonlySelectors.delete(key);
1079
- familyToken = {
1080
- key: selector.family.key,
1081
- type: `readonly_pure_selector_family`
1082
- };
1083
- const family = withdraw(store, familyToken);
1084
- family.subject.next({
1085
- type: `state_disposal`,
1086
- subType: `selector`,
1087
- token: selectorToken
1088
- });
1089
- }
1090
- break;
1091
- }
1092
- target.valueMap.delete(key);
1093
- target.selectorAtoms.delete(key);
1094
- target.selectorGraph.delete(key);
1095
- store.logger.info(`🔥`, selectorToken.type, key, `deleted`);
1096
- if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.updates.push({
1097
- type: `state_disposal`,
1098
- subType: `selector`,
1099
- token: selectorToken
1100
- });
1101
- else store.on.selectorDisposal.next(selectorToken);
1102
- }
1103
- }
1104
-
1105
- //#endregion
1106
- //#region src/internal/families/create-readonly-pure-selector-family.ts
1107
- function createReadonlyPureSelectorFamily(store, options, internalRoles) {
1108
- const familyKey = options.key;
1109
- const type = `readonly_pure_selector_family`;
1110
- const familyToken = {
1111
- key: familyKey,
1112
- type
1113
- };
1114
- const existing = store.families.get(familyKey);
1115
- if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1116
- const subject = new Subject();
1117
- const familyFunction = (key) => {
1118
- const subKey = stringifyJson(key);
1119
- const family = {
1120
- key: familyKey,
1121
- subKey
1122
- };
1123
- const fullKey = `${familyKey}(${subKey})`;
1124
- const target = newest(store);
1125
- const token = createReadonlyPureSelector(target, {
1126
- key: fullKey,
1127
- get: options.get(key)
1128
- }, family);
1129
- subject.next({
1130
- type: `state_creation`,
1131
- token
1132
- });
1133
- return token;
1134
- };
1135
- const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
1136
- internalRoles,
1137
- subject,
1138
- install: (s) => createReadonlyPureSelectorFamily(s, options),
1139
- default: (key) => {
1140
- const getFn = options.get(key);
1141
- return getFn({
1142
- get: ((...args) => getFromStore(store, ...args)),
1143
- find: ((...args) => findInStore(store, ...args)),
1144
- json: (token) => getJsonToken(store, token)
1145
- });
1146
- }
1147
- });
1148
- store.families.set(familyKey, readonlySelectorFamily);
1149
- return familyToken;
1150
- }
1151
-
1152
- //#endregion
1153
- //#region src/internal/families/create-readonly-held-selector-family.ts
1154
- function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
1155
- const familyKey = options.key;
1156
- const type = `readonly_held_selector_family`;
1157
- const familyToken = {
1158
- key: familyKey,
1159
- type
1160
- };
1161
- const existing = store.families.get(familyKey);
1162
- if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1163
- const subject = new Subject();
1164
- const familyFunction = (key) => {
1165
- const subKey = stringifyJson(key);
1166
- const family = {
1167
- key: familyKey,
1168
- subKey
1169
- };
1170
- const fullKey = `${familyKey}(${subKey})`;
1171
- const target = newest(store);
1172
- const token = createReadonlyHeldSelector(target, {
1173
- key: fullKey,
1174
- const: options.const(key),
1175
- get: options.get(key)
1176
- }, family);
1177
- subject.next({
1178
- type: `state_creation`,
1179
- token
1180
- });
1181
- return token;
1182
- };
1183
- const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
1184
- internalRoles,
1185
- subject,
1186
- install: (s) => createReadonlyHeldSelectorFamily(s, options),
1187
- default: options.const
1188
- });
1189
- store.families.set(familyKey, readonlySelectorFamily);
1190
- return familyToken;
1191
- }
1192
-
1193
- //#endregion
1194
- //#region src/internal/families/create-writable-held-selector-family.ts
1195
- function createWritableHeldSelectorFamily(store, options, internalRoles) {
1196
- const familyKey = options.key;
1197
- const type = `writable_held_selector_family`;
1198
- const familyToken = {
1199
- key: familyKey,
1200
- type
1201
- };
1202
- const existing = store.families.get(familyKey);
1203
- if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1204
- const subject = new Subject();
1205
- const familyFunction = (key) => {
1206
- const subKey = stringifyJson(key);
1207
- const family = {
1208
- key: familyKey,
1209
- subKey
1210
- };
1211
- const fullKey = `${familyKey}(${subKey})`;
1212
- const target = newest(store);
1213
- const token = createWritableHeldSelector(target, {
1214
- key: fullKey,
1215
- const: options.const(key),
1216
- get: options.get(key),
1217
- set: options.set(key)
1218
- }, family);
1219
- subject.next({
1220
- type: `state_creation`,
1221
- token
1222
- });
1223
- return token;
1224
- };
1225
- const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
1226
- internalRoles,
1227
- subject,
1228
- install: (s) => createWritableHeldSelectorFamily(s, options),
1229
- default: options.const
1230
- });
1231
- store.families.set(familyKey, selectorFamily$1);
1232
- return familyToken;
1233
- }
1234
-
1235
- //#endregion
1236
- //#region src/internal/families/create-writable-pure-selector-family.ts
1237
- function createWritablePureSelectorFamily(store, options, internalRoles) {
1238
- const familyKey = options.key;
1239
- const type = `writable_pure_selector_family`;
1240
- const familyToken = {
1241
- key: familyKey,
1242
- type
1243
- };
1244
- const existing = store.families.get(familyKey);
1245
- if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1246
- const subject = new Subject();
1247
- const familyFunction = (key) => {
1248
- const subKey = stringifyJson(key);
1249
- const family = {
1250
- key: familyKey,
1251
- subKey
1252
- };
1253
- const fullKey = `${familyKey}(${subKey})`;
1254
- const target = newest(store);
1255
- const token = createWritablePureSelector(target, {
1256
- key: fullKey,
1257
- get: options.get(key),
1258
- set: options.set(key)
1259
- }, family);
1260
- subject.next({
1261
- type: `state_creation`,
1262
- token
1263
- });
1264
- return token;
1265
- };
1266
- const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
1267
- internalRoles,
1268
- subject,
1269
- install: (s) => createWritablePureSelectorFamily(s, options),
1270
- default: (key) => {
1271
- const getFn = options.get(key);
1272
- return getFn({
1273
- get: ((...args) => getFromStore(store, ...args)),
1274
- find: ((...args) => findInStore(store, ...args)),
1275
- json: (token) => getJsonToken(store, token)
1276
- });
1277
- }
1278
- });
1279
- store.families.set(familyKey, selectorFamily$1);
1280
- return familyToken;
1281
- }
1282
-
1283
- //#endregion
1284
- //#region src/internal/families/create-selector-family.ts
1285
- function createSelectorFamily(store, options) {
1286
- const isWritable = `set` in options;
1287
- const isHeld = `const` in options;
1288
- if (isHeld && isWritable) return createWritableHeldSelectorFamily(store, options, void 0);
1289
- if (isHeld) return createReadonlyHeldSelectorFamily(store, options, void 0);
1290
- if (isWritable) return createWritablePureSelectorFamily(store, options);
1291
- return createReadonlyPureSelectorFamily(store, options);
1292
- }
1293
-
1294
- //#endregion
1295
- //#region src/internal/families/init-family-member.ts
1296
- function initFamilyMemberInStore(store, token, key) {
1297
- const family = store.families.get(token.key);
1298
- if (family === void 0) throw new NotFoundError(token, store);
1299
- const state = family(key);
1300
- const target = newest(store);
1301
- if (state.family) {
1302
- if (isRootStore(target)) switch (state.type) {
1303
- case `atom`:
1304
- case `mutable_atom`:
1305
- store.on.atomCreation.next(state);
1306
- break;
1307
- case `writable_pure_selector`:
1308
- case `readonly_pure_selector`:
1309
- case `writable_held_selector`:
1310
- case `readonly_held_selector`:
1311
- store.on.selectorCreation.next(state);
1312
- break;
1313
- }
1314
- else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.updates.push({
1315
- type: `state_creation`,
1316
- token: state
1317
- });
1318
- }
1319
- return state;
1320
- }
1321
-
1322
- //#endregion
1323
- //#region src/internal/families/seek-in-store.ts
1324
- function seekInStore(store, token, key) {
1325
- const subKey = stringifyJson(key);
1326
- const fullKey = `${token.key}(${subKey})`;
1327
- const target = newest(store);
1328
- let state;
1329
- switch (token.type) {
1330
- case `atom_family`:
1331
- case `mutable_atom_family`:
1332
- state = target.atoms.get(fullKey);
1333
- break;
1334
- case `writable_held_selector_family`:
1335
- case `writable_pure_selector_family`:
1336
- state = target.writableSelectors.get(fullKey);
1337
- break;
1338
- case `readonly_held_selector_family`:
1339
- case `readonly_pure_selector_family`:
1340
- state = target.readonlySelectors.get(fullKey);
1341
- break;
1342
- }
1343
- if (state) return deposit(state);
1344
- return state;
1345
- }
1346
-
1347
- //#endregion
1348
- //#region src/internal/families/find-in-store.ts
1349
- function findInStore(store, token, key) {
1350
- let state = seekInStore(store, token, key);
1351
- if (state) return state;
1352
- const stringKey = stringifyJson(key);
1353
- const molecule = store.molecules.get(stringKey);
1354
- if (!molecule && store.config.lifespan === `immortal`) {
1355
- const fakeToken = counterfeit(token, key);
1356
- store.logger.error(`❌`, fakeToken.type, fakeToken.key, `was not found in store "${store.config.name}"; returned a counterfeit token.`);
1357
- return fakeToken;
1358
- }
1359
- state = initFamilyMemberInStore(store, token, key);
1360
- if (molecule) {
1361
- const target = newest(store);
1362
- target.moleculeData.set(stringKey, token.key);
1363
- }
1364
- return state;
1365
- }
1366
-
1367
- //#endregion
1368
- //#region src/internal/families/dispose-from-store.ts
1369
- function disposeFromStore(store, ...params) {
1370
- let token;
1371
- if (params.length === 1) token = params[0];
1372
- else {
1373
- const family = params[0];
1374
- const key = params[1];
1375
- const maybeToken = findInStore(store, family, key);
1376
- token = maybeToken;
1377
- }
1378
- try {
1379
- withdraw(store, token);
1380
- } catch (_) {
1381
- store.logger.error(`❌`, token.type, token.key, `could not be disposed because it was not found in the store "${store.config.name}".`);
1382
- return;
1383
- }
1384
- switch (token.type) {
1385
- case `atom`:
1386
- case `mutable_atom`:
1387
- disposeAtom(store, token);
1388
- break;
1389
- case `writable_pure_selector`:
1390
- case `readonly_pure_selector`:
1391
- case `writable_held_selector`:
1392
- case `readonly_held_selector`:
1393
- disposeSelector(store, token);
1394
- break;
1395
- }
1396
- }
1397
-
1398
- //#endregion
1399
- //#region src/internal/families/get-family-of-token.ts
1400
- function getFamilyOfToken(store, token) {
1401
- if (token.family) {
1402
- const family = store.families.get(token.family.key);
1403
- if (family) return family;
1404
- }
1405
- }
1406
-
1407
- //#endregion
1408
- //#region src/internal/set-state/reset-in-store.ts
1409
- function resetInStore(store, ...params) {
1410
- let token;
1411
- let family;
1412
- let key;
1413
- if (params.length === 1) {
1414
- token = params[0];
1415
- family = getFamilyOfToken(store, token) ?? null;
1416
- if (family) {
1417
- key = token.family ? parseJson(token.family.subKey) : null;
1418
- token = findInStore(store, family, key);
1419
- }
1420
- } else {
1421
- family = params[0];
1422
- key = params[1];
1423
- token = findInStore(store, family, key);
1424
- }
1425
- if (`counterfeit` in token && `family` in token) {
1426
- const subKey = token.family.subKey;
1427
- const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
1428
- store.logger.error(`❌`, token.type, token.key, `could not be reset because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
1429
- return;
1430
- }
1431
- const rejectionTime = openOperation(store, token);
1432
- if (rejectionTime) {
1433
- const unsubscribe = store.on.operationClose.subscribe(`waiting to reset "${token.key}" at T-${rejectionTime}`, () => {
1434
- unsubscribe();
1435
- store.logger.info(`🟢`, token.type, token.key, `resuming deferred resetState from T-${rejectionTime}`);
1436
- resetInStore(store, token);
1437
- });
1438
- return;
1439
- }
1440
- const state = withdraw(store, token);
1441
- resetAtomOrSelector(store, state);
1442
- closeOperation(store);
1443
- }
1444
-
1445
- //#endregion
1446
- //#region src/internal/set-state/set-atom-or-selector.ts
1447
- const setAtomOrSelector = (store, state, value) => {
1448
- switch (state.type) {
1449
- case `atom`:
1450
- case `mutable_atom`:
1451
- setAtom(store, state, value);
1452
- break;
1453
- case `writable_pure_selector`:
1454
- case `writable_held_selector`:
1455
- state.set(value);
1456
- break;
1457
- }
1458
- };
1459
-
1460
- //#endregion
1461
- //#region src/internal/set-state/set-into-store.ts
1462
- function setIntoStore(store, ...params) {
1463
- let token;
1464
- let family;
1465
- let key;
1466
- let value;
1467
- if (params.length === 2) {
1468
- token = params[0];
1469
- value = params[1];
1470
- family = getFamilyOfToken(store, token) ?? null;
1471
- if (family) {
1472
- key = token.family ? parseJson(token.family.subKey) : null;
1473
- token = findInStore(store, family, key);
1474
- }
1475
- } else {
1476
- family = params[0];
1477
- key = params[1];
1478
- value = params[2];
1479
- token = findInStore(store, family, key);
1480
- }
1481
- if (`counterfeit` in token && `family` in token) {
1482
- const subKey = token.family.subKey;
1483
- const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
1484
- store.logger.error(`❌`, token.type, token.key, `could not be set because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
1485
- return;
1486
- }
1487
- const rejectionTime = openOperation(store, token);
1488
- if (rejectionTime) {
1489
- const unsubscribe = store.on.operationClose.subscribe(`waiting to set "${token.key}" at T-${rejectionTime}`, () => {
1490
- unsubscribe();
1491
- store.logger.info(`🟢`, token.type, token.key, `resuming deferred setState from T-${rejectionTime}`);
1492
- setIntoStore(store, token, value);
1493
- });
1494
- return;
1495
- }
1496
- const state = withdraw(store, token);
1497
- setAtomOrSelector(store, state, value);
1498
- closeOperation(store);
1499
- }
1500
-
1501
- //#endregion
1502
- //#region src/internal/ingest-updates/ingest-atom-update.ts
1503
- function ingestAtomUpdate(applying, atomUpdate, store) {
1504
- const { key, newValue, oldValue } = atomUpdate;
1505
- const value = applying === `newValue` ? newValue : oldValue;
1506
- const token = {
1507
- key,
1508
- type: `atom`
1509
- };
1510
- if (atomUpdate.family) Object.assign(token, { family: atomUpdate.family });
1511
- setIntoStore(store, token, value);
1512
- }
1513
-
1514
- //#endregion
1515
- //#region src/internal/get-trace.ts
1516
- function getTrace(error) {
1517
- const { stack } = error;
1518
- if (stack) return `\n` + stack.split(`\n`)?.slice(1)?.join(`\n`);
1519
- return ``;
1125
+ //#region src/internal/get-trace.ts
1126
+ function getTrace(error) {
1127
+ const { stack } = error;
1128
+ if (stack) return `\n` + stack.split(`\n`)?.slice(1)?.join(`\n`);
1129
+ return ``;
1520
1130
  }
1521
1131
 
1522
1132
  //#endregion
@@ -1661,27 +1271,23 @@ function claimWithinStore(store, newProvenance, claim, exclusive) {
1661
1271
  //#region src/internal/ingest-updates/ingest-creation-disposal.ts
1662
1272
  function ingestCreationEvent(update, applying, store) {
1663
1273
  switch (applying) {
1664
- case `newValue`: {
1274
+ case `newValue`:
1665
1275
  createInStore(update, store);
1666
1276
  break;
1667
- }
1668
- case `oldValue`: {
1277
+ case `oldValue`:
1669
1278
  disposeFromStore(store, update.token);
1670
1279
  break;
1671
- }
1672
1280
  }
1673
1281
  }
1674
1282
  function ingestDisposalEvent(update, applying, store) {
1675
1283
  switch (applying) {
1676
- case `newValue`: {
1284
+ case `newValue`:
1677
1285
  disposeFromStore(store, update.token);
1678
1286
  break;
1679
- }
1680
- case `oldValue`: {
1287
+ case `oldValue`:
1681
1288
  createInStore(update, store);
1682
1289
  if (update.subType === `atom`) store.valueMap.set(update.token.key, update.value);
1683
1290
  break;
1684
- }
1685
1291
  }
1686
1292
  }
1687
1293
  function createInStore(update, store) {
@@ -1830,59 +1436,25 @@ const applyTransaction = (output, store) => {
1830
1436
  type: `transaction`
1831
1437
  });
1832
1438
  myTransaction?.subject.next(child.transactionMeta.update);
1833
- store.logger.info(`🛬`, `transaction`, child.transactionMeta.update.key, `Finished applying transaction.`);
1834
- } else if (isChildStore(parent)) parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1835
- parent.on.transactionApplying.next(null);
1836
- };
1837
-
1838
- //#endregion
1839
- //#region src/internal/transaction/assign-transaction-to-continuity.ts
1840
- function assignTransactionToContinuity(store, continuityKey, transactionKey) {
1841
- const isRoot = isRootStore(store);
1842
- if (!isRoot) return;
1843
- const { epoch, actionContinuities } = store.transactionMeta;
1844
- actionContinuities.set(continuityKey, transactionKey);
1845
- if (!epoch.has(continuityKey)) epoch.set(continuityKey, -1);
1846
- }
1847
-
1848
- //#endregion
1849
- //#region src/internal/get-environment-data.ts
1850
- function getEnvironmentData(store) {
1851
- return { store };
1852
- }
1853
-
1854
- //#endregion
1855
- //#region src/internal/get-state/get-from-store.ts
1856
- function getFromStore(store, ...params) {
1857
- let token;
1858
- let family;
1859
- let key;
1860
- if (params.length === 1) token = params[0];
1861
- else {
1862
- family = params[0];
1863
- key = params[1];
1864
- token = findInStore(store, family, key);
1865
- }
1866
- if (`counterfeit` in token && `family` in token) {
1867
- family = store.families.get(token.family.key);
1868
- const subKey = token.family.subKey;
1869
- const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
1870
- store.logger.error(`❌`, token.type, token.key, `could not be retrieved because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
1871
- switch (family.type) {
1872
- case `atom_family`:
1873
- case `mutable_atom_family`: return store.defaults.get(family.key);
1874
- case `readonly_pure_selector_family`:
1875
- case `writable_pure_selector_family`:
1876
- case `readonly_held_selector_family`:
1877
- case `writable_held_selector_family`: {
1878
- if (store.defaults.has(family.key)) return store.defaults.get(token.family.key);
1879
- const defaultValue = withdraw(store, family).default(subKey);
1880
- store.defaults.set(family.key, defaultValue);
1881
- return defaultValue;
1882
- }
1883
- }
1884
- }
1885
- return readOrComputeValue(store, withdraw(store, token));
1439
+ store.logger.info(`🛬`, `transaction`, child.transactionMeta.update.key, `Finished applying transaction.`);
1440
+ } else if (isChildStore(parent)) parent.transactionMeta.update.updates.push(child.transactionMeta.update);
1441
+ parent.on.transactionApplying.next(null);
1442
+ };
1443
+
1444
+ //#endregion
1445
+ //#region src/internal/transaction/assign-transaction-to-continuity.ts
1446
+ function assignTransactionToContinuity(store, continuityKey, transactionKey) {
1447
+ const isRoot = isRootStore(store);
1448
+ if (!isRoot) return;
1449
+ const { epoch, actionContinuities } = store.transactionMeta;
1450
+ actionContinuities.set(continuityKey, transactionKey);
1451
+ if (!epoch.has(continuityKey)) epoch.set(continuityKey, -1);
1452
+ }
1453
+
1454
+ //#endregion
1455
+ //#region src/internal/get-environment-data.ts
1456
+ function getEnvironmentData(store) {
1457
+ return { store };
1886
1458
  }
1887
1459
 
1888
1460
  //#endregion
@@ -1980,264 +1552,604 @@ const buildTransaction = (store, key, params, id) => {
1980
1552
  }),
1981
1553
  env: () => getEnvironmentData(child)
1982
1554
  }
1983
- };
1984
- const child = Object.assign(childBase, { transactionMeta });
1985
- parent.child = child;
1986
- store.logger.info(`🛫`, `transaction`, key, `Building transaction with params:`, params);
1987
- return child;
1988
- };
1555
+ };
1556
+ const child = Object.assign(childBase, { transactionMeta });
1557
+ parent.child = child;
1558
+ store.logger.info(`🛫`, `transaction`, key, `Building transaction with params:`, params);
1559
+ return child;
1560
+ };
1561
+
1562
+ //#endregion
1563
+ //#region src/internal/transaction/create-transaction.ts
1564
+ function createTransaction(store, options) {
1565
+ const { key } = options;
1566
+ const transactionAlreadyExists = store.transactions.has(key);
1567
+ const newTransaction = {
1568
+ key,
1569
+ type: `transaction`,
1570
+ run: (params, id) => {
1571
+ const childStore = buildTransaction(store, key, params, id);
1572
+ try {
1573
+ const target$1 = newest(store);
1574
+ const { toolkit } = childStore.transactionMeta;
1575
+ const output = options.do(toolkit, ...params);
1576
+ applyTransaction(output, target$1);
1577
+ return output;
1578
+ } catch (thrown) {
1579
+ abortTransaction(target);
1580
+ store.logger.warn(`💥`, `transaction`, key, `caught:`, thrown);
1581
+ throw thrown;
1582
+ }
1583
+ },
1584
+ install: (s) => createTransaction(s, options),
1585
+ subject: new Subject()
1586
+ };
1587
+ const target = newest(store);
1588
+ target.transactions.set(key, newTransaction);
1589
+ const token = deposit(newTransaction);
1590
+ if (!transactionAlreadyExists) store.on.transactionCreation.next(token);
1591
+ return token;
1592
+ }
1593
+
1594
+ //#endregion
1595
+ //#region src/internal/transaction/index.ts
1596
+ const TRANSACTION_PHASES = [
1597
+ `idle`,
1598
+ `building`,
1599
+ `applying`
1600
+ ];
1601
+
1602
+ //#endregion
1603
+ //#region src/internal/selector/create-writable-held-selector.ts
1604
+ const createWritableHeldSelector = (store, options, family) => {
1605
+ const target = newest(store);
1606
+ const subject = new Subject();
1607
+ const covered = /* @__PURE__ */ new Set();
1608
+ const { key, const: constant } = options;
1609
+ const type = `writable_held_selector`;
1610
+ const setterToolkit = registerSelector(target, type, key, covered);
1611
+ const { find, get, json } = setterToolkit;
1612
+ const getterToolkit = {
1613
+ find,
1614
+ get,
1615
+ json
1616
+ };
1617
+ const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
1618
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1619
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1620
+ innerTarget.selectorAtoms.delete(key);
1621
+ getFn(getterToolkit, constant);
1622
+ cacheValue(innerTarget, key, constant, subject);
1623
+ store.logger.info(`✨`, type, key, `=`, constant);
1624
+ covered.clear();
1625
+ return constant;
1626
+ };
1627
+ const setSelf = (next) => {
1628
+ const innerTarget = newest(store);
1629
+ const oldValue = getSelf(options.get, innerTarget);
1630
+ const newValue = become(next)(oldValue);
1631
+ store.logger.info(`📝`, type, key, `set (`, oldValue, `->`, newValue, `)`);
1632
+ cacheValue(innerTarget, key, newValue, subject);
1633
+ markDone(innerTarget, key);
1634
+ if (isRootStore(innerTarget)) subject.next({
1635
+ newValue,
1636
+ oldValue
1637
+ });
1638
+ options.set(setterToolkit, newValue);
1639
+ };
1640
+ const mySelector = {
1641
+ ...options,
1642
+ type,
1643
+ subject,
1644
+ install: (s) => createWritableHeldSelector(s, options, family),
1645
+ get: getSelf,
1646
+ set: setSelf,
1647
+ ...family && { family }
1648
+ };
1649
+ target.writableSelectors.set(key, mySelector);
1650
+ const token = {
1651
+ key,
1652
+ type
1653
+ };
1654
+ if (family) token.family = family;
1655
+ return token;
1656
+ };
1657
+
1658
+ //#endregion
1659
+ //#region src/internal/selector/create-writable-pure-selector.ts
1660
+ const createWritablePureSelector = (store, options, family) => {
1661
+ const target = newest(store);
1662
+ const subject = new Subject();
1663
+ const covered = /* @__PURE__ */ new Set();
1664
+ const key = options.key;
1665
+ const type = `writable_pure_selector`;
1666
+ const setterToolkit = registerSelector(target, type, key, covered);
1667
+ const { find, get, json } = setterToolkit;
1668
+ const getterToolkit = {
1669
+ find,
1670
+ get,
1671
+ json
1672
+ };
1673
+ const getSelf = (getFn = options.get, innerTarget = newest(store)) => {
1674
+ const upstreamStates = innerTarget.selectorGraph.getRelationEntries({ downstreamSelectorKey: key });
1675
+ for (const [downstreamSelectorKey, { source }] of upstreamStates) if (source !== key) innerTarget.selectorGraph.delete(downstreamSelectorKey, key);
1676
+ innerTarget.selectorAtoms.delete(key);
1677
+ const value = getFn(getterToolkit);
1678
+ const cached = cacheValue(innerTarget, key, value, subject);
1679
+ store.logger.info(`✨`, type, key, `=`, cached);
1680
+ covered.clear();
1681
+ return value;
1682
+ };
1683
+ const setSelf = (next) => {
1684
+ const innerTarget = newest(store);
1685
+ const oldValue = getSelf(options.get, innerTarget);
1686
+ const newValue = become(next)(oldValue);
1687
+ store.logger.info(`📝`, type, key, `set (`, oldValue, `->`, newValue, `)`);
1688
+ cacheValue(innerTarget, options.key, newValue, subject);
1689
+ markDone(innerTarget, options.key);
1690
+ if (isRootStore(innerTarget)) subject.next({
1691
+ newValue,
1692
+ oldValue
1693
+ });
1694
+ options.set(setterToolkit, newValue);
1695
+ };
1696
+ const mySelector = {
1697
+ ...options,
1698
+ type,
1699
+ subject,
1700
+ install: (s) => createWritablePureSelector(s, options, family),
1701
+ get: getSelf,
1702
+ set: setSelf,
1703
+ ...family && { family }
1704
+ };
1705
+ target.writableSelectors.set(key, mySelector);
1706
+ const initialValue = getSelf();
1707
+ store.logger.info(`✨`, mySelector.type, mySelector.key, `=`, initialValue);
1708
+ const token = {
1709
+ key,
1710
+ type
1711
+ };
1712
+ if (family) token.family = family;
1713
+ return token;
1714
+ };
1715
+
1716
+ //#endregion
1717
+ //#region src/internal/selector/create-standalone-selector.ts
1718
+ function createStandaloneSelector(store, options) {
1719
+ const isWritable = `set` in options;
1720
+ const isHeld = `const` in options;
1721
+ if (isHeld && isWritable) {
1722
+ const state$1 = createWritableHeldSelector(store, options, void 0);
1723
+ store.on.selectorCreation.next(state$1);
1724
+ return state$1;
1725
+ }
1726
+ if (isHeld) {
1727
+ const state$1 = createReadonlyHeldSelector(store, options, void 0);
1728
+ store.on.selectorCreation.next(state$1);
1729
+ return state$1;
1730
+ }
1731
+ if (isWritable) {
1732
+ const state$1 = createWritablePureSelector(store, options, void 0);
1733
+ store.on.selectorCreation.next(state$1);
1734
+ return state$1;
1735
+ }
1736
+ const state = createReadonlyPureSelector(store, options, void 0);
1737
+ store.on.selectorCreation.next(state);
1738
+ return state;
1739
+ }
1740
+
1741
+ //#endregion
1742
+ //#region src/internal/selector/dispose-selector.ts
1743
+ function disposeSelector(store, selectorToken) {
1744
+ const target = newest(store);
1745
+ const { key, type } = selectorToken;
1746
+ const selector = withdraw(target, selectorToken);
1747
+ if (!selector.family) store.logger.error(`❌`, type, key, `Standalone selectors cannot be disposed.`);
1748
+ else {
1749
+ const molecule = target.molecules.get(selector.family.subKey);
1750
+ if (molecule) target.moleculeData.delete(selector.family.subKey, selector.family.key);
1751
+ let familyToken;
1752
+ switch (selectorToken.type) {
1753
+ case `writable_held_selector`:
1754
+ {
1755
+ target.writableSelectors.delete(key);
1756
+ familyToken = {
1757
+ key: selector.family.key,
1758
+ type: `writable_held_selector_family`
1759
+ };
1760
+ const family = withdraw(store, familyToken);
1761
+ family.subject.next({
1762
+ type: `state_disposal`,
1763
+ subType: `selector`,
1764
+ token: selectorToken
1765
+ });
1766
+ }
1767
+ break;
1768
+ case `writable_pure_selector`:
1769
+ {
1770
+ target.writableSelectors.delete(key);
1771
+ familyToken = {
1772
+ key: selector.family.key,
1773
+ type: `writable_pure_selector_family`
1774
+ };
1775
+ const family = withdraw(store, familyToken);
1776
+ family.subject.next({
1777
+ type: `state_disposal`,
1778
+ subType: `selector`,
1779
+ token: selectorToken
1780
+ });
1781
+ }
1782
+ break;
1783
+ case `readonly_held_selector`:
1784
+ {
1785
+ target.readonlySelectors.delete(key);
1786
+ familyToken = {
1787
+ key: selector.family.key,
1788
+ type: `readonly_held_selector_family`
1789
+ };
1790
+ const family = withdraw(store, familyToken);
1791
+ family.subject.next({
1792
+ type: `state_disposal`,
1793
+ subType: `selector`,
1794
+ token: selectorToken
1795
+ });
1796
+ }
1797
+ break;
1798
+ case `readonly_pure_selector`:
1799
+ {
1800
+ target.readonlySelectors.delete(key);
1801
+ familyToken = {
1802
+ key: selector.family.key,
1803
+ type: `readonly_pure_selector_family`
1804
+ };
1805
+ const family = withdraw(store, familyToken);
1806
+ family.subject.next({
1807
+ type: `state_disposal`,
1808
+ subType: `selector`,
1809
+ token: selectorToken
1810
+ });
1811
+ }
1812
+ break;
1813
+ }
1814
+ target.valueMap.delete(key);
1815
+ target.selectorAtoms.delete(key);
1816
+ target.selectorGraph.delete(key);
1817
+ store.logger.info(`🔥`, selectorToken.type, key, `deleted`);
1818
+ if (isChildStore(target) && target.transactionMeta.phase === `building`) target.transactionMeta.update.updates.push({
1819
+ type: `state_disposal`,
1820
+ subType: `selector`,
1821
+ token: selectorToken
1822
+ });
1823
+ else store.on.selectorDisposal.next(selectorToken);
1824
+ }
1825
+ }
1989
1826
 
1990
1827
  //#endregion
1991
- //#region src/internal/transaction/create-transaction.ts
1992
- function createTransaction(store, options) {
1993
- const { key } = options;
1994
- const transactionAlreadyExists = store.transactions.has(key);
1995
- const newTransaction = {
1996
- key,
1997
- type: `transaction`,
1998
- run: (params, id) => {
1999
- const childStore = buildTransaction(store, key, params, id);
2000
- try {
2001
- const target$1 = newest(store);
2002
- const { toolkit } = childStore.transactionMeta;
2003
- const output = options.do(toolkit, ...params);
2004
- applyTransaction(output, target$1);
2005
- return output;
2006
- } catch (thrown) {
2007
- abortTransaction(target);
2008
- store.logger.warn(`💥`, `transaction`, key, `caught:`, thrown);
2009
- throw thrown;
2010
- }
2011
- },
2012
- install: (s) => createTransaction(s, options),
2013
- subject: new Subject()
1828
+ //#region src/internal/families/create-readonly-pure-selector-family.ts
1829
+ function createReadonlyPureSelectorFamily(store, options, internalRoles) {
1830
+ const familyKey = options.key;
1831
+ const type = `readonly_pure_selector_family`;
1832
+ const familyToken = {
1833
+ key: familyKey,
1834
+ type
2014
1835
  };
2015
- const target = newest(store);
2016
- target.transactions.set(key, newTransaction);
2017
- const token = deposit(newTransaction);
2018
- if (!transactionAlreadyExists) store.on.transactionCreation.next(token);
2019
- return token;
1836
+ const existing = store.families.get(familyKey);
1837
+ if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1838
+ const subject = new Subject();
1839
+ const familyFunction = (key) => {
1840
+ const subKey = stringifyJson(key);
1841
+ const family = {
1842
+ key: familyKey,
1843
+ subKey
1844
+ };
1845
+ const fullKey = `${familyKey}(${subKey})`;
1846
+ const target = newest(store);
1847
+ const token = createReadonlyPureSelector(target, {
1848
+ key: fullKey,
1849
+ get: options.get(key)
1850
+ }, family);
1851
+ subject.next({
1852
+ type: `state_creation`,
1853
+ token
1854
+ });
1855
+ return token;
1856
+ };
1857
+ const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
1858
+ internalRoles,
1859
+ subject,
1860
+ install: (s) => createReadonlyPureSelectorFamily(s, options),
1861
+ default: (key) => {
1862
+ const getFn = options.get(key);
1863
+ return getFn({
1864
+ get: ((...args) => getFromStore(store, ...args)),
1865
+ find: ((...args) => findInStore(store, ...args)),
1866
+ json: (token) => getJsonToken(store, token)
1867
+ });
1868
+ }
1869
+ });
1870
+ store.families.set(familyKey, readonlySelectorFamily);
1871
+ return familyToken;
2020
1872
  }
2021
1873
 
2022
1874
  //#endregion
2023
- //#region src/internal/transaction/index.ts
2024
- const TRANSACTION_PHASES = [
2025
- `idle`,
2026
- `building`,
2027
- `applying`
2028
- ];
2029
-
2030
- //#endregion
2031
- //#region src/internal/store/store.ts
2032
- var Store = class {
2033
- parent = null;
2034
- child = null;
2035
- valueMap = /* @__PURE__ */ new Map();
2036
- defaults = /* @__PURE__ */ new Map();
2037
- atoms = /* @__PURE__ */ new Map();
2038
- writableSelectors = /* @__PURE__ */ new Map();
2039
- readonlySelectors = /* @__PURE__ */ new Map();
2040
- atomsThatAreDefault = /* @__PURE__ */ new Set();
2041
- selectorAtoms = new Junction({
2042
- between: [`selectorKey`, `atomKey`],
2043
- cardinality: `n:n`
2044
- });
2045
- selectorGraph = new Junction({
2046
- between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
2047
- cardinality: `n:n`
2048
- }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2049
- trackers = /* @__PURE__ */ new Map();
2050
- families = /* @__PURE__ */ new Map();
2051
- joins = /* @__PURE__ */ new Map();
2052
- transactions = /* @__PURE__ */ new Map();
2053
- transactionMeta = {
2054
- epoch: /* @__PURE__ */ new Map(),
2055
- actionContinuities: new Junction({
2056
- between: [`continuity`, `action`],
2057
- cardinality: `1:n`
2058
- })
1875
+ //#region src/internal/families/create-readonly-held-selector-family.ts
1876
+ function createReadonlyHeldSelectorFamily(store, options, internalRoles) {
1877
+ const familyKey = options.key;
1878
+ const type = `readonly_held_selector_family`;
1879
+ const familyToken = {
1880
+ key: familyKey,
1881
+ type
2059
1882
  };
2060
- timelines = /* @__PURE__ */ new Map();
2061
- timelineTopics = new Junction({
2062
- between: [`timelineKey`, `topicKey`],
2063
- cardinality: `1:n`
1883
+ const existing = store.families.get(familyKey);
1884
+ if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1885
+ const subject = new Subject();
1886
+ const familyFunction = (key) => {
1887
+ const subKey = stringifyJson(key);
1888
+ const family = {
1889
+ key: familyKey,
1890
+ subKey
1891
+ };
1892
+ const fullKey = `${familyKey}(${subKey})`;
1893
+ const target = newest(store);
1894
+ const token = createReadonlyHeldSelector(target, {
1895
+ key: fullKey,
1896
+ const: options.const(key),
1897
+ get: options.get(key)
1898
+ }, family);
1899
+ subject.next({
1900
+ type: `state_creation`,
1901
+ token
1902
+ });
1903
+ return token;
1904
+ };
1905
+ const readonlySelectorFamily = Object.assign(familyFunction, familyToken, {
1906
+ internalRoles,
1907
+ subject,
1908
+ install: (s) => createReadonlyHeldSelectorFamily(s, options),
1909
+ default: options.const
2064
1910
  });
2065
- disposalTraces = new CircularBuffer(100);
2066
- molecules = /* @__PURE__ */ new Map();
2067
- moleculeJoins = new Junction({
2068
- between: [`moleculeKey`, `joinKey`],
2069
- cardinality: `n:n`
2070
- }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2071
- moleculeGraph = new Junction({
2072
- between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
2073
- cardinality: `n:n`
2074
- }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2075
- moleculeData = new Junction({
2076
- between: [`moleculeKey`, `stateFamilyKey`],
2077
- cardinality: `n:n`
2078
- }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2079
- miscResources = /* @__PURE__ */ new Map();
2080
- on = {
2081
- atomCreation: new Subject(),
2082
- atomDisposal: new Subject(),
2083
- selectorCreation: new Subject(),
2084
- selectorDisposal: new Subject(),
2085
- timelineCreation: new Subject(),
2086
- transactionCreation: new Subject(),
2087
- transactionApplying: new StatefulSubject(null),
2088
- operationClose: new Subject(),
2089
- moleculeCreation: new Subject(),
2090
- moleculeDisposal: new Subject()
1911
+ store.families.set(familyKey, readonlySelectorFamily);
1912
+ return familyToken;
1913
+ }
1914
+
1915
+ //#endregion
1916
+ //#region src/internal/families/create-writable-held-selector-family.ts
1917
+ function createWritableHeldSelectorFamily(store, options, internalRoles) {
1918
+ const familyKey = options.key;
1919
+ const type = `writable_held_selector_family`;
1920
+ const familyToken = {
1921
+ key: familyKey,
1922
+ type
2091
1923
  };
2092
- operation = { open: false };
2093
- config = {
2094
- name: `IMPLICIT_STORE`,
2095
- lifespan: `ephemeral`
1924
+ const existing = store.families.get(familyKey);
1925
+ if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1926
+ const subject = new Subject();
1927
+ const familyFunction = (key) => {
1928
+ const subKey = stringifyJson(key);
1929
+ const family = {
1930
+ key: familyKey,
1931
+ subKey
1932
+ };
1933
+ const fullKey = `${familyKey}(${subKey})`;
1934
+ const target = newest(store);
1935
+ const token = createWritableHeldSelector(target, {
1936
+ key: fullKey,
1937
+ const: options.const(key),
1938
+ get: options.get(key),
1939
+ set: options.set(key)
1940
+ }, family);
1941
+ subject.next({
1942
+ type: `state_creation`,
1943
+ token
1944
+ });
1945
+ return token;
2096
1946
  };
2097
- loggers = [new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))];
2098
- logger = {
2099
- error: (...messages) => {
2100
- for (const logger of this.loggers) logger.error(...messages);
2101
- },
2102
- info: (...messages) => {
2103
- for (const logger of this.loggers) logger.info(...messages);
2104
- },
2105
- warn: (...messages) => {
2106
- for (const logger of this.loggers) logger.warn(...messages);
2107
- }
1947
+ const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
1948
+ internalRoles,
1949
+ subject,
1950
+ install: (s) => createWritableHeldSelectorFamily(s, options),
1951
+ default: options.const
1952
+ });
1953
+ store.families.set(familyKey, selectorFamily$1);
1954
+ return familyToken;
1955
+ }
1956
+
1957
+ //#endregion
1958
+ //#region src/internal/families/create-writable-pure-selector-family.ts
1959
+ function createWritablePureSelectorFamily(store, options, internalRoles) {
1960
+ const familyKey = options.key;
1961
+ const type = `writable_pure_selector_family`;
1962
+ const familyToken = {
1963
+ key: familyKey,
1964
+ type
2108
1965
  };
2109
- constructor(config, store = null) {
2110
- this.config = {
2111
- ...store?.config,
2112
- ...config
1966
+ const existing = store.families.get(familyKey);
1967
+ if (existing) store.logger.error(`❗`, type, familyKey, `Overwriting an existing ${prettyPrintTokenType(existing)} "${existing.key}" in store "${store.config.name}". You can safely ignore this warning if it is due to hot module replacement.`);
1968
+ const subject = new Subject();
1969
+ const familyFunction = (key) => {
1970
+ const subKey = stringifyJson(key);
1971
+ const family = {
1972
+ key: familyKey,
1973
+ subKey
2113
1974
  };
2114
- if (store !== null) {
2115
- this.valueMap = new Map(store?.valueMap);
2116
- this.operation = { ...store?.operation };
2117
- if (isRootStore(store)) this.transactionMeta = {
2118
- epoch: new Map(store?.transactionMeta.epoch),
2119
- actionContinuities: new Junction(store?.transactionMeta.actionContinuities.toJSON())
2120
- };
2121
- for (const [, family] of store.families) {
2122
- if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`)) continue;
2123
- family.install(this);
2124
- }
2125
- const mutableHelpers = /* @__PURE__ */ new Set();
2126
- for (const [, atom$1] of store.atoms) {
2127
- if (mutableHelpers.has(atom$1.key)) continue;
2128
- atom$1.install(this);
2129
- if (atom$1.type === `mutable_atom`) {
2130
- const originalJsonToken = getJsonToken(store, atom$1);
2131
- const originalUpdateToken = getUpdateToken(atom$1);
2132
- mutableHelpers.add(originalJsonToken.key);
2133
- mutableHelpers.add(originalUpdateToken.key);
2134
- }
2135
- }
2136
- for (const [, selector] of store.readonlySelectors) selector.install(this);
2137
- for (const [, selector] of store.writableSelectors) {
2138
- if (mutableHelpers.has(selector.key)) continue;
2139
- selector.install(this);
2140
- }
2141
- for (const [, tx] of store.transactions) tx.install(this);
2142
- for (const [, timeline] of store.timelines) timeline.install(this);
1975
+ const fullKey = `${familyKey}(${subKey})`;
1976
+ const target = newest(store);
1977
+ const token = createWritablePureSelector(target, {
1978
+ key: fullKey,
1979
+ get: options.get(key),
1980
+ set: options.set(key)
1981
+ }, family);
1982
+ subject.next({
1983
+ type: `state_creation`,
1984
+ token
1985
+ });
1986
+ return token;
1987
+ };
1988
+ const selectorFamily$1 = Object.assign(familyFunction, familyToken, {
1989
+ internalRoles,
1990
+ subject,
1991
+ install: (s) => createWritablePureSelectorFamily(s, options),
1992
+ default: (key) => {
1993
+ const getFn = options.get(key);
1994
+ return getFn({
1995
+ get: ((...args) => getFromStore(store, ...args)),
1996
+ find: ((...args) => findInStore(store, ...args)),
1997
+ json: (token) => getJsonToken(store, token)
1998
+ });
2143
1999
  }
2144
- }
2145
- };
2146
- const IMPLICIT = { get STORE() {
2147
- globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
2148
- name: `IMPLICIT_STORE`,
2149
- lifespan: `ephemeral`
2150
2000
  });
2151
- return globalThis.ATOM_IO_IMPLICIT_STORE;
2152
- } };
2153
- const clearStore = (store) => {
2154
- const { config } = store;
2155
- for (const disposable of store.miscResources.values()) disposable[Symbol.dispose]();
2156
- Object.assign(store, new Store(config));
2157
- store.config = config;
2158
- };
2001
+ store.families.set(familyKey, selectorFamily$1);
2002
+ return familyToken;
2003
+ }
2159
2004
 
2160
2005
  //#endregion
2161
- //#region src/internal/store/withdraw.ts
2162
- function withdraw(store, token) {
2163
- let withdrawn;
2164
- let target = store;
2165
- while (target !== null) {
2166
- switch (token.type) {
2006
+ //#region src/internal/families/create-selector-family.ts
2007
+ function createSelectorFamily(store, options) {
2008
+ const isWritable = `set` in options;
2009
+ const isHeld = `const` in options;
2010
+ if (isHeld && isWritable) return createWritableHeldSelectorFamily(store, options, void 0);
2011
+ if (isHeld) return createReadonlyHeldSelectorFamily(store, options, void 0);
2012
+ if (isWritable) return createWritablePureSelectorFamily(store, options);
2013
+ return createReadonlyPureSelectorFamily(store, options);
2014
+ }
2015
+
2016
+ //#endregion
2017
+ //#region src/internal/families/init-family-member.ts
2018
+ function initFamilyMemberInStore(store, token, key) {
2019
+ const family = store.families.get(token.key);
2020
+ if (family === void 0) throw new NotFoundError(token, store);
2021
+ const state = family(key);
2022
+ const target = newest(store);
2023
+ if (state.family) {
2024
+ if (isRootStore(target)) switch (state.type) {
2167
2025
  case `atom`:
2168
2026
  case `mutable_atom`:
2169
- withdrawn = target.atoms.get(token.key);
2027
+ store.on.atomCreation.next(state);
2170
2028
  break;
2171
2029
  case `writable_pure_selector`:
2172
- case `writable_held_selector`:
2173
- withdrawn = target.writableSelectors.get(token.key);
2174
- break;
2175
2030
  case `readonly_pure_selector`:
2031
+ case `writable_held_selector`:
2176
2032
  case `readonly_held_selector`:
2177
- withdrawn = target.readonlySelectors.get(token.key);
2178
- break;
2179
- case `atom_family`:
2180
- case `mutable_atom_family`:
2181
- case `writable_pure_selector_family`:
2182
- case `readonly_pure_selector_family`:
2183
- case `writable_held_selector_family`:
2184
- case `readonly_held_selector_family`:
2185
- withdrawn = target.families.get(token.key);
2186
- break;
2187
- case `timeline`:
2188
- withdrawn = target.timelines.get(token.key);
2189
- break;
2190
- case `transaction`:
2191
- withdrawn = target.transactions.get(token.key);
2033
+ store.on.selectorCreation.next(state);
2192
2034
  break;
2193
2035
  }
2194
- if (withdrawn) return withdrawn;
2195
- target = target.child;
2036
+ else if (isChildStore(target) && target.on.transactionApplying.state === null) target.transactionMeta.update.updates.push({
2037
+ type: `state_creation`,
2038
+ token: state
2039
+ });
2196
2040
  }
2197
- throw new NotFoundError(token, store);
2041
+ return state;
2198
2042
  }
2199
2043
 
2200
2044
  //#endregion
2201
- //#region src/internal/subscribe/recall-state.ts
2202
- const recallState = (store, state) => {
2045
+ //#region src/internal/families/seek-in-store.ts
2046
+ function seekInStore(store, token, key) {
2047
+ const subKey = stringifyJson(key);
2048
+ const fullKey = `${token.key}(${subKey})`;
2203
2049
  const target = newest(store);
2204
- if (target.operation.open) return target.operation.prev.get(state.key);
2205
- return target.valueMap.get(state.key);
2206
- };
2050
+ let state;
2051
+ switch (token.type) {
2052
+ case `atom_family`:
2053
+ case `mutable_atom_family`:
2054
+ state = target.atoms.get(fullKey);
2055
+ break;
2056
+ case `writable_held_selector_family`:
2057
+ case `writable_pure_selector_family`:
2058
+ state = target.writableSelectors.get(fullKey);
2059
+ break;
2060
+ case `readonly_held_selector_family`:
2061
+ case `readonly_pure_selector_family`:
2062
+ state = target.readonlySelectors.get(fullKey);
2063
+ break;
2064
+ }
2065
+ if (state) return deposit(state);
2066
+ return state;
2067
+ }
2207
2068
 
2208
2069
  //#endregion
2209
- //#region src/internal/subscribe/subscribe-in-store.ts
2210
- function subscribeInStore(store, token, handleUpdate, key = arbitrary$1()) {
2070
+ //#region src/internal/families/find-in-store.ts
2071
+ function findInStore(store, token, key) {
2072
+ let state = seekInStore(store, token, key);
2073
+ if (state) return state;
2074
+ const stringKey = stringifyJson(key);
2075
+ const molecule = store.molecules.get(stringKey);
2076
+ if (!molecule && store.config.lifespan === `immortal`) {
2077
+ const fakeToken = counterfeit(token, key);
2078
+ store.logger.error(`❌`, fakeToken.type, fakeToken.key, `was not found in store "${store.config.name}"; returned a counterfeit token.`);
2079
+ return fakeToken;
2080
+ }
2081
+ state = initFamilyMemberInStore(store, token, key);
2082
+ if (molecule) {
2083
+ const target = newest(store);
2084
+ target.moleculeData.set(stringKey, token.key);
2085
+ }
2086
+ return state;
2087
+ }
2088
+
2089
+ //#endregion
2090
+ //#region src/internal/families/dispose-from-store.ts
2091
+ function disposeFromStore(store, ...params) {
2092
+ let token;
2093
+ if (params.length === 1) token = params[0];
2094
+ else {
2095
+ const family = params[0];
2096
+ const key = params[1];
2097
+ const maybeToken = findInStore(store, family, key);
2098
+ token = maybeToken;
2099
+ }
2100
+ try {
2101
+ withdraw(store, token);
2102
+ } catch (_) {
2103
+ store.logger.error(`❌`, token.type, token.key, `could not be disposed because it was not found in the store "${store.config.name}".`);
2104
+ return;
2105
+ }
2211
2106
  switch (token.type) {
2212
2107
  case `atom`:
2213
2108
  case `mutable_atom`:
2109
+ disposeAtom(store, token);
2110
+ break;
2111
+ case `writable_pure_selector`:
2214
2112
  case `readonly_pure_selector`:
2113
+ case `writable_held_selector`:
2215
2114
  case `readonly_held_selector`:
2216
- case `writable_pure_selector`:
2217
- case `writable_held_selector`: return subscribeToState$1(store, token, key, handleUpdate);
2218
- case `transaction`: return subscribeToTransaction$1(store, token, key, handleUpdate);
2219
- case `timeline`: return subscribeToTimeline$1(store, token, key, handleUpdate);
2115
+ disposeSelector(store, token);
2116
+ break;
2220
2117
  }
2221
2118
  }
2222
2119
 
2223
2120
  //#endregion
2224
- //#region src/internal/subscribe/subscribe-to-root-atoms.ts
2225
- const subscribeToRootAtoms = (store, selector) => {
2226
- const target = newest(store);
2227
- const dependencySubscriptions = traceAllSelectorAtoms(selector, store).map((atom$1) => {
2228
- return atom$1.subject.subscribe(`${selector.type}:${selector.key}`, (atomChange) => {
2229
- store.logger.info(`📢`, selector.type, selector.key, `root`, atom$1.key, `went`, atomChange.oldValue, `->`, atomChange.newValue);
2230
- const oldValue = recallState(target, selector);
2231
- const newValue = readOrComputeValue(target, selector);
2232
- store.logger.info(`✨`, selector.type, selector.key, `went`, oldValue, `->`, newValue);
2233
- selector.subject.next({
2234
- newValue,
2235
- oldValue
2236
- });
2237
- });
2238
- });
2239
- return dependencySubscriptions;
2240
- };
2121
+ //#region src/internal/get-state/get-from-store.ts
2122
+ function getFromStore(store, ...params) {
2123
+ let token;
2124
+ let family;
2125
+ let key;
2126
+ if (params.length === 1) token = params[0];
2127
+ else {
2128
+ family = params[0];
2129
+ key = params[1];
2130
+ token = findInStore(store, family, key);
2131
+ }
2132
+ if (`counterfeit` in token && `family` in token) {
2133
+ family = store.families.get(token.family.key);
2134
+ const subKey = token.family.subKey;
2135
+ const disposal = store.disposalTraces.buffer.find((item) => item?.key === subKey);
2136
+ store.logger.error(`❌`, token.type, token.key, `could not be retrieved because it was not found in the store "${store.config.name}".`, disposal ? `This state was previously disposed:\n${disposal.trace}` : `No previous disposal trace was found.`);
2137
+ switch (family.type) {
2138
+ case `atom_family`:
2139
+ case `mutable_atom_family`: return store.defaults.get(family.key);
2140
+ case `readonly_pure_selector_family`:
2141
+ case `writable_pure_selector_family`:
2142
+ case `readonly_held_selector_family`:
2143
+ case `writable_held_selector_family`: {
2144
+ if (store.defaults.has(family.key)) return store.defaults.get(token.family.key);
2145
+ const defaultValue = withdraw(store, family).default(subKey);
2146
+ store.defaults.set(family.key, defaultValue);
2147
+ return defaultValue;
2148
+ }
2149
+ }
2150
+ }
2151
+ return readOrComputeValue(store, withdraw(store, token));
2152
+ }
2241
2153
 
2242
2154
  //#endregion
2243
2155
  //#region src/internal/subscribe/subscribe-to-state.ts
@@ -2253,15 +2165,22 @@ function subscribeToState(store, token, key, handleUpdate) {
2253
2165
  const state = withdraw(store, token);
2254
2166
  store.logger.info(`👀`, state.type, state.key, `Adding subscription "${key}"`);
2255
2167
  const isSelector = state.type === `writable_pure_selector` || state.type === `readonly_pure_selector`;
2256
- let dependencyUnsubFunctions = null;
2168
+ const rootSubs = /* @__PURE__ */ new Map();
2257
2169
  let updateHandler = safelyHandleUpdate;
2258
2170
  if (isSelector) {
2259
- dependencyUnsubFunctions = subscribeToRootAtoms(store, state);
2260
- updateHandler = (update) => {
2261
- if (dependencyUnsubFunctions) {
2262
- dependencyUnsubFunctions.length = 0;
2263
- dependencyUnsubFunctions.push(...subscribeToRootAtoms(store, state));
2171
+ readOrComputeValue(store, state);
2172
+ for (const [atomKey, atom$1] of traceRootSelectorAtoms(store, state.key)) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom$1));
2173
+ updateHandler = function updateRootsBeforeHandlingUpdate(update) {
2174
+ const dependencies = traceRootSelectorAtoms(store, state.key);
2175
+ for (const [previousRootKey, unsub] of rootSubs) {
2176
+ const currentRoot = dependencies.get(previousRootKey);
2177
+ if (currentRoot) dependencies.delete(previousRootKey);
2178
+ else {
2179
+ unsub();
2180
+ rootSubs.delete(previousRootKey);
2181
+ }
2264
2182
  }
2183
+ for (const [atomKey, atom$1] of dependencies) rootSubs.set(atomKey, subscribeToRootDependency(store, state, atom$1));
2265
2184
  safelyHandleUpdate(update);
2266
2185
  };
2267
2186
  }
@@ -2269,7 +2188,7 @@ function subscribeToState(store, token, key, handleUpdate) {
2269
2188
  const unsubscribe = () => {
2270
2189
  store.logger.info(`🙈`, state.type, state.key, `Removing subscription "${key}"`);
2271
2190
  mainUnsubFunction();
2272
- if (dependencyUnsubFunctions) for (const unsubFromDependency of dependencyUnsubFunctions) unsubFromDependency();
2191
+ for (const unsubFromDependency of rootSubs.values()) unsubFromDependency();
2273
2192
  };
2274
2193
  return unsubscribe;
2275
2194
  }
@@ -2395,7 +2314,7 @@ var Tracker = class {
2395
2314
  function createMutableAtom(store, options, family) {
2396
2315
  store.logger.info(`🔨`, `atom`, options.key, `creating in store "${store.config.name}"`);
2397
2316
  const target = newest(store);
2398
- const { key, default: def } = options;
2317
+ const { key } = options;
2399
2318
  const existing = target.atoms.get(key);
2400
2319
  const type = `mutable_atom`;
2401
2320
  if (existing && existing.type === type) {
@@ -2413,9 +2332,7 @@ function createMutableAtom(store, options, family) {
2413
2332
  subject
2414
2333
  };
2415
2334
  if (family) newAtom.family = family;
2416
- const initialValue = def();
2417
2335
  target.atoms.set(newAtom.key, newAtom);
2418
- cacheValue(target, key, initialValue, subject);
2419
2336
  const token = deposit(newAtom);
2420
2337
  if (options.effects) {
2421
2338
  let effectIndex = 0;
@@ -2586,93 +2503,179 @@ function isTransceiver(value) {
2586
2503
  }
2587
2504
 
2588
2505
  //#endregion
2589
- //#region src/internal/set-state/copy-mutable-if-needed.ts
2590
- function copyMutableIfNeeded(target, atom$1, origin) {
2591
- const originValue = origin.valueMap.get(atom$1.key);
2592
- const targetValue = target.valueMap.get(atom$1.key);
2593
- if (originValue !== targetValue) return targetValue;
2594
- if (originValue === void 0) return atom$1.default();
2595
- origin.logger.info(`📃`, `atom`, atom$1.key, `copying`);
2596
- const jsonValue = atom$1.toJson(originValue);
2597
- const copiedValue = atom$1.fromJson(jsonValue);
2598
- target.valueMap.set(atom$1.key, copiedValue);
2599
- new Tracker(atom$1, origin);
2600
- return copiedValue;
2601
- }
2602
-
2603
- //#endregion
2604
- //#region src/internal/caching.ts
2605
- function cacheValue(target, key, value, subject) {
2606
- const currentValue = target.valueMap.get(key);
2607
- if (currentValue instanceof Future) {
2608
- const future = currentValue;
2609
- if (value instanceof Promise) {
2610
- future.use(value);
2611
- return future;
2506
+ //#region src/internal/store/store.ts
2507
+ var Store = class {
2508
+ parent = null;
2509
+ child = null;
2510
+ valueMap = /* @__PURE__ */ new Map();
2511
+ defaults = /* @__PURE__ */ new Map();
2512
+ atoms = /* @__PURE__ */ new Map();
2513
+ writableSelectors = /* @__PURE__ */ new Map();
2514
+ readonlySelectors = /* @__PURE__ */ new Map();
2515
+ atomsThatAreDefault = /* @__PURE__ */ new Set();
2516
+ selectorAtoms = new Junction({
2517
+ between: [`selectorKey`, `atomKey`],
2518
+ cardinality: `n:n`
2519
+ });
2520
+ selectorGraph = new Junction({
2521
+ between: [`upstreamSelectorKey`, `downstreamSelectorKey`],
2522
+ cardinality: `n:n`
2523
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2524
+ trackers = /* @__PURE__ */ new Map();
2525
+ families = /* @__PURE__ */ new Map();
2526
+ joins = /* @__PURE__ */ new Map();
2527
+ transactions = /* @__PURE__ */ new Map();
2528
+ transactionMeta = {
2529
+ epoch: /* @__PURE__ */ new Map(),
2530
+ actionContinuities: new Junction({
2531
+ between: [`continuity`, `action`],
2532
+ cardinality: `1:n`
2533
+ })
2534
+ };
2535
+ timelines = /* @__PURE__ */ new Map();
2536
+ timelineTopics = new Junction({
2537
+ between: [`timelineKey`, `topicKey`],
2538
+ cardinality: `1:n`
2539
+ });
2540
+ disposalTraces = new CircularBuffer(100);
2541
+ molecules = /* @__PURE__ */ new Map();
2542
+ moleculeJoins = new Junction({
2543
+ between: [`moleculeKey`, `joinKey`],
2544
+ cardinality: `n:n`
2545
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2546
+ moleculeGraph = new Junction({
2547
+ between: [`upstreamMoleculeKey`, `downstreamMoleculeKey`],
2548
+ cardinality: `n:n`
2549
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2550
+ moleculeData = new Junction({
2551
+ between: [`moleculeKey`, `stateFamilyKey`],
2552
+ cardinality: `n:n`
2553
+ }, { makeContentKey: (...keys) => keys.sort().join(`:`) });
2554
+ miscResources = /* @__PURE__ */ new Map();
2555
+ on = {
2556
+ atomCreation: new Subject(),
2557
+ atomDisposal: new Subject(),
2558
+ selectorCreation: new Subject(),
2559
+ selectorDisposal: new Subject(),
2560
+ timelineCreation: new Subject(),
2561
+ transactionCreation: new Subject(),
2562
+ transactionApplying: new StatefulSubject(null),
2563
+ operationClose: new Subject(),
2564
+ moleculeCreation: new Subject(),
2565
+ moleculeDisposal: new Subject()
2566
+ };
2567
+ operation = { open: false };
2568
+ config = {
2569
+ name: `IMPLICIT_STORE`,
2570
+ lifespan: `ephemeral`
2571
+ };
2572
+ loggers = [new AtomIOLogger(`warn`, (_, __, key) => !isReservedIntrospectionKey(key))];
2573
+ logger = {
2574
+ error: (...messages) => {
2575
+ for (const logger of this.loggers) logger.error(...messages);
2576
+ },
2577
+ info: (...messages) => {
2578
+ for (const logger of this.loggers) logger.info(...messages);
2579
+ },
2580
+ warn: (...messages) => {
2581
+ for (const logger of this.loggers) logger.warn(...messages);
2612
2582
  }
2613
- target.valueMap.set(key, value);
2614
- return value;
2615
- }
2616
- if (value instanceof Promise) {
2617
- const future = new Future(value);
2618
- target.valueMap.set(key, future);
2619
- future.then((resolved) => {
2620
- const current = target.valueMap.get(key);
2621
- if (current === future) {
2622
- cacheValue(target, key, resolved, subject);
2623
- const atom$1 = target.atoms.get(key);
2624
- if (atom$1) {
2625
- openOperation(target, atom$1);
2626
- evictDownStream(target, atom$1);
2627
- closeOperation(target);
2628
- } else {
2629
- const selector = target.writableSelectors.get(key) ?? target.readonlySelectors.get(key);
2630
- if (selector) {
2631
- openOperation(target, selector);
2632
- evictDownStreamFromSelector(target, selector);
2633
- closeOperation(target);
2634
- }
2583
+ };
2584
+ constructor(config, store = null) {
2585
+ this.config = {
2586
+ ...store?.config,
2587
+ ...config
2588
+ };
2589
+ if (store !== null) {
2590
+ this.operation = { ...store?.operation };
2591
+ if (isRootStore(store)) this.transactionMeta = {
2592
+ epoch: new Map(store?.transactionMeta.epoch),
2593
+ actionContinuities: new Junction(store?.transactionMeta.actionContinuities.toJSON())
2594
+ };
2595
+ for (const [, family] of store.families) {
2596
+ if (family.internalRoles?.includes(`mutable`) || family.internalRoles?.includes(`join`)) continue;
2597
+ family.install(this);
2598
+ }
2599
+ const mutableHelpers = /* @__PURE__ */ new Set();
2600
+ for (const [, atom$1] of store.atoms) {
2601
+ if (mutableHelpers.has(atom$1.key)) continue;
2602
+ atom$1.install(this);
2603
+ if (atom$1.type === `mutable_atom`) {
2604
+ const originalJsonToken = getJsonToken(store, atom$1);
2605
+ const originalUpdateToken = getUpdateToken(atom$1);
2606
+ mutableHelpers.add(originalJsonToken.key);
2607
+ mutableHelpers.add(originalUpdateToken.key);
2635
2608
  }
2636
- subject.next({
2637
- newValue: resolved,
2638
- oldValue: future
2639
- });
2640
2609
  }
2641
- }).catch((thrown) => {
2642
- target.logger.error(`💥`, `state`, key, `rejected:`, thrown);
2643
- });
2644
- return future;
2645
- }
2646
- target.valueMap.set(key, value);
2647
- return value;
2648
- }
2649
- const readCachedValue = (token, target) => {
2650
- let value = target.valueMap.get(token.key);
2651
- if (token.type === `mutable_atom` && isChildStore(target)) {
2652
- const { parent } = target;
2653
- const copiedValue = copyMutableIfNeeded(target, token, parent);
2654
- value = copiedValue;
2610
+ for (const [, selector] of store.readonlySelectors) selector.install(this);
2611
+ for (const [, selector] of store.writableSelectors) {
2612
+ if (mutableHelpers.has(selector.key)) continue;
2613
+ selector.install(this);
2614
+ }
2615
+ for (const [, tx] of store.transactions) tx.install(this);
2616
+ for (const [, timeline] of store.timelines) timeline.install(this);
2617
+ }
2655
2618
  }
2656
- return value;
2657
2619
  };
2658
- const evictCachedValue = (key, target) => {
2659
- const currentValue = target.valueMap.get(key);
2660
- if (currentValue instanceof Future) {
2661
- const future = currentValue;
2662
- const selector = target.writableSelectors.get(key) ?? target.readonlySelectors.get(key);
2663
- if (selector) future.use(selector.get());
2664
- return;
2665
- }
2666
- if (target.operation.open) target.operation.prev.set(key, currentValue);
2667
- target.valueMap.delete(key);
2668
- target.logger.info(`🗑`, `state`, key, `evicted`);
2620
+ const IMPLICIT = { get STORE() {
2621
+ globalThis.ATOM_IO_IMPLICIT_STORE ??= new Store({
2622
+ name: `IMPLICIT_STORE`,
2623
+ lifespan: `ephemeral`
2624
+ });
2625
+ return globalThis.ATOM_IO_IMPLICIT_STORE;
2626
+ } };
2627
+ const clearStore = (store) => {
2628
+ const { config } = store;
2629
+ for (const disposable of store.miscResources.values()) disposable[Symbol.dispose]();
2630
+ Object.assign(store, new Store(config));
2631
+ store.config = config;
2669
2632
  };
2670
2633
 
2634
+ //#endregion
2635
+ //#region src/internal/store/withdraw.ts
2636
+ function withdraw(store, token) {
2637
+ let withdrawn;
2638
+ let target = store;
2639
+ while (target !== null) {
2640
+ switch (token.type) {
2641
+ case `atom`:
2642
+ case `mutable_atom`:
2643
+ withdrawn = target.atoms.get(token.key);
2644
+ break;
2645
+ case `writable_pure_selector`:
2646
+ case `writable_held_selector`:
2647
+ withdrawn = target.writableSelectors.get(token.key);
2648
+ break;
2649
+ case `readonly_pure_selector`:
2650
+ case `readonly_held_selector`:
2651
+ withdrawn = target.readonlySelectors.get(token.key);
2652
+ break;
2653
+ case `atom_family`:
2654
+ case `mutable_atom_family`:
2655
+ case `writable_pure_selector_family`:
2656
+ case `readonly_pure_selector_family`:
2657
+ case `writable_held_selector_family`:
2658
+ case `readonly_held_selector_family`:
2659
+ withdrawn = target.families.get(token.key);
2660
+ break;
2661
+ case `timeline`:
2662
+ withdrawn = target.timelines.get(token.key);
2663
+ break;
2664
+ case `transaction`:
2665
+ withdrawn = target.transactions.get(token.key);
2666
+ break;
2667
+ }
2668
+ if (withdrawn) return withdrawn;
2669
+ target = target.child;
2670
+ }
2671
+ throw new NotFoundError(token, store);
2672
+ }
2673
+
2671
2674
  //#endregion
2672
2675
  //#region src/internal/atom/create-regular-atom.ts
2673
2676
  function createRegularAtom(store, options, family) {
2674
2677
  const type = `atom`;
2675
- const { key, default: def } = options;
2678
+ const { key } = options;
2676
2679
  store.logger.info(`🔨`, `atom`, key, `creating in store "${store.config.name}"`);
2677
2680
  const target = newest(store);
2678
2681
  const existing = target.atoms.get(key);
@@ -2691,10 +2694,7 @@ function createRegularAtom(store, options, family) {
2691
2694
  subject
2692
2695
  };
2693
2696
  if (family) newAtom.family = family;
2694
- let initialValue = def;
2695
- if (def instanceof Function) initialValue = def();
2696
2697
  target.atoms.set(key, newAtom);
2697
- cacheValue(target, key, initialValue, subject);
2698
2698
  const token = deposit(newAtom);
2699
2699
  if (options.effects) {
2700
2700
  let effectIndex = 0;
@@ -2802,6 +2802,20 @@ function installIntoStore(tokens, target, source) {
2802
2802
  }
2803
2803
  }
2804
2804
 
2805
+ //#endregion
2806
+ //#region src/internal/join/create-join.ts
2807
+ function createJoin(store, options, defaultContent) {
2808
+ store.joins.set(options.key, new Join$1(options, defaultContent, store));
2809
+ const token = {
2810
+ key: options.key,
2811
+ type: `join`,
2812
+ a: options.between[0],
2813
+ b: options.between[1],
2814
+ cardinality: options.cardinality
2815
+ };
2816
+ return token;
2817
+ }
2818
+
2805
2819
  //#endregion
2806
2820
  //#region src/internal/join/join-internal.ts
2807
2821
  var Join = class {
@@ -3513,26 +3527,21 @@ const timeTravel = (store, action, token) => {
3513
3527
  const update = timelineData.history[timelineData.at];
3514
3528
  const applying = action === `redo` ? `newValue` : `oldValue`;
3515
3529
  switch (update.type) {
3516
- case `atom_update`: {
3530
+ case `atom_update`:
3517
3531
  ingestAtomUpdate(applying, update, store);
3518
3532
  break;
3519
- }
3520
- case `selector_update`: {
3533
+ case `selector_update`:
3521
3534
  ingestSelectorUpdate(applying, update, store);
3522
3535
  break;
3523
- }
3524
- case `transaction_update`: {
3536
+ case `transaction_update`:
3525
3537
  ingestTransactionUpdate(applying, update, store);
3526
3538
  break;
3527
- }
3528
- case `state_creation`: {
3539
+ case `state_creation`:
3529
3540
  ingestCreationEvent(update, applying, store);
3530
3541
  break;
3531
- }
3532
- case `state_disposal`: {
3542
+ case `state_disposal`:
3533
3543
  ingestDisposalEvent(update, applying, store);
3534
3544
  break;
3535
- }
3536
3545
  case `molecule_creation`:
3537
3546
  case `molecule_disposal`:
3538
3547
  }
@@ -3543,5 +3552,5 @@ const timeTravel = (store, action, token) => {
3543
3552
  };
3544
3553
 
3545
3554
  //#endregion
3546
- export { CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, Join, Junction, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, createAtomFamily, createMutableAtom, createMutableAtomFamily, createReadonlyHeldSelector, createReadonlyPureSelector, createReadonlyPureSelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableHeldSelector, createWritablePureSelector, createWritablePureSelectorFamily, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, editRelationsInStore, evictCachedValue, findInStore, findRelationsInStore, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, installIntoStore, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markDone, newest, openOperation, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootAtoms, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceAllSelectorAtoms, traceSelectorAtoms, updateSelectorAtoms, withdraw };
3555
+ export { CircularBuffer, FAMILY_MEMBER_TOKEN_TYPES, FamilyTracker, Future, IMPLICIT, Join, Junction, LazyMap, NotFoundError, StatefulSubject, Store, Subject, TRANSACTION_PHASES, Tracker, abortTransaction, actUponStore, allocateIntoStore, applyTransaction, arbitrary, assignTransactionToContinuity, become, buildTransaction, cacheValue, capitalize, claimWithinStore, clearStore, closeOperation, counterfeit, createAtomFamily, createJoin, createMutableAtom, createMutableAtomFamily, createReadonlyHeldSelector, createReadonlyPureSelector, createReadonlyPureSelectorFamily, createRegularAtom, createRegularAtomFamily, createSelectorFamily, createStandaloneAtom, createStandaloneSelector, createTimeline, createTransaction, createWritableHeldSelector, createWritablePureSelector, createWritablePureSelectorFamily, deallocateFromStore, deposit, disposeAtom, disposeFromStore, disposeSelector, editRelationsInStore, evictCachedValue, findInStore, findRelationsInStore, fuseWithinStore, getContinuityKey, getEnvironmentData, getEpochNumberOfAction, getEpochNumberOfContinuity, getFromStore, getInternalRelationsFromStore, getJoin, getJsonFamily, getJsonToken, getSelectorDependencyKeys, getTrace, getUpdateFamily, getUpdateToken, ingestAtomUpdate, ingestCreationEvent, ingestDisposalEvent, ingestMoleculeCreationEvent, ingestMoleculeDisposalEvent, ingestMoleculeTransferEvent, ingestSelectorUpdate, ingestTransactionUpdate, initFamilyMemberInStore, installIntoStore, isAtomKey, isChildStore, isDone, isReadonlySelectorKey, isReservedIntrospectionKey, isRootStore, isSelectorKey, isStateKey, isTransceiver, makeRootMoleculeInStore, markDone, newest, openOperation, prettyPrintTokenType, readCachedValue, readOrComputeValue, recallState, registerSelector, resetAtomOrSelector, resetInStore, seekInStore, setAtomOrSelector, setEpochNumberOfAction, setEpochNumberOfContinuity, setIntoStore, subscribeInStore, subscribeToRootDependency, subscribeToState, subscribeToTimeline, subscribeToTransaction, timeTravel, traceRootSelectorAtoms, updateSelectorAtoms, withdraw };
3547
3556
  //# sourceMappingURL=index.js.map