atom.io 0.3.1 → 0.4.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/README.md +11 -3
  2. package/dist/index.d.ts +84 -30
  3. package/dist/index.js +427 -230
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +427 -230
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +15 -5
  8. package/react/dist/index.d.ts +12 -17
  9. package/react/dist/index.js +25 -34
  10. package/react/dist/index.js.map +1 -1
  11. package/react/dist/index.mjs +21 -34
  12. package/react/dist/index.mjs.map +1 -1
  13. package/react-devtools/dist/index.css +26 -0
  14. package/react-devtools/dist/index.css.map +1 -0
  15. package/react-devtools/dist/index.d.ts +15 -0
  16. package/react-devtools/dist/index.js +1582 -0
  17. package/react-devtools/dist/index.js.map +1 -0
  18. package/react-devtools/dist/index.mjs +1554 -0
  19. package/react-devtools/dist/index.mjs.map +1 -0
  20. package/react-devtools/package.json +15 -0
  21. package/src/index.ts +3 -3
  22. package/src/internal/atom-internal.ts +10 -5
  23. package/src/internal/families-internal.ts +4 -4
  24. package/src/internal/get.ts +8 -8
  25. package/src/internal/index.ts +2 -0
  26. package/src/internal/meta/attach-meta.ts +17 -0
  27. package/src/internal/meta/index.ts +4 -0
  28. package/src/internal/meta/meta-state.ts +135 -0
  29. package/src/internal/meta/meta-timelines.ts +1 -0
  30. package/src/internal/meta/meta-transactions.ts +1 -0
  31. package/src/internal/operation.ts +0 -1
  32. package/src/internal/selector-internal.ts +34 -13
  33. package/src/internal/store.ts +35 -5
  34. package/src/internal/time-travel-internal.ts +89 -0
  35. package/src/internal/timeline-internal.ts +23 -103
  36. package/src/internal/transaction-internal.ts +14 -5
  37. package/src/react/index.ts +28 -46
  38. package/src/react-devtools/AtomIODevtools.tsx +107 -0
  39. package/src/react-devtools/StateEditor.tsx +73 -0
  40. package/src/react-devtools/TokenList.tsx +57 -0
  41. package/src/react-devtools/devtools.scss +130 -0
  42. package/src/react-devtools/index.ts +1 -0
  43. package/src/react-explorer/AtomIOExplorer.tsx +208 -0
  44. package/src/react-explorer/explorer-effects.ts +20 -0
  45. package/src/react-explorer/explorer-states.ts +224 -0
  46. package/src/react-explorer/index.ts +23 -0
  47. package/src/react-explorer/space-states.ts +73 -0
  48. package/src/react-explorer/view-states.ts +43 -0
  49. package/src/selector.ts +6 -6
  50. package/src/subscribe.ts +2 -2
  51. package/src/timeline.ts +1 -5
  52. package/src/transaction.ts +4 -2
  53. package/src/web-effects/index.ts +1 -0
  54. package/src/web-effects/storage.ts +30 -0
package/dist/index.js CHANGED
@@ -83,6 +83,7 @@ module.exports = __toCommonJS(src_exports);
83
83
  var internal_exports = {};
84
84
  __export(internal_exports, {
85
85
  IMPLICIT: () => IMPLICIT,
86
+ META: () => meta_exports,
86
87
  TRANSACTION_PHASES: () => TRANSACTION_PHASES,
87
88
  abortTransaction: () => abortTransaction,
88
89
  applyTransaction: () => applyTransaction,
@@ -139,7 +140,8 @@ __export(internal_exports, {
139
140
  });
140
141
 
141
142
  // src/internal/atom-internal.ts
142
- var Rx2 = __toESM(require("rxjs"));
143
+ var import_hamt_plus5 = __toESM(require("hamt_plus"));
144
+ var Rx3 = __toESM(require("rxjs"));
143
145
 
144
146
  // src/internal/get.ts
145
147
  var import_hamt_plus = __toESM(require("hamt_plus"));
@@ -200,6 +202,7 @@ var import_hamt_plus3 = __toESM(require("hamt_plus"));
200
202
 
201
203
  // src/internal/store.ts
202
204
  var import_hamt_plus2 = __toESM(require("hamt_plus"));
205
+ var Rx = __toESM(require("rxjs"));
203
206
 
204
207
  // ../anvl/src/function/index.ts
205
208
  var doNothing = () => void 0;
@@ -291,18 +294,68 @@ var hasExactProperties = (
291
294
  (isValue) => hasProperties(isValue, { allowExtraProperties: false })
292
295
  );
293
296
 
297
+ // ../anvl/src/refinement/index.ts
298
+ var canExist = (_) => true;
299
+ var cannotExist = (_) => false;
300
+ var isLiteral = (value) => (input) => input === value;
301
+ var couldBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
302
+ const name = `(${refinements.map((r) => r.name || `anon`).join(` | `)})`;
303
+ const _ = {
304
+ [name]: (input) => refinements.some(
305
+ (refinement) => {
306
+ var _a;
307
+ return logging && console.log(
308
+ refinements.map((r) => r.name || `anon`).join(` | `),
309
+ `>`,
310
+ (_a = refinement.name) != null ? _a : `anon`,
311
+ `:`,
312
+ refinement(input)
313
+ ), refinement(input);
314
+ }
315
+ )
316
+ };
317
+ const checkTypes = Object.assign(_[name], {
318
+ or: (isTypeB) => couldBe(isTypeB, logging, [...refinements, isTypeB])
319
+ });
320
+ return checkTypes;
321
+ };
322
+ var isUnion = couldBe(cannotExist);
323
+ var mustBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
324
+ const name = `(${refinements.map((r) => r.name || `anon`).join(` & `)})`;
325
+ const _ = {
326
+ [name]: (input) => refinements.every(
327
+ (refinement) => (logging && console.log(
328
+ refinements.map((r) => r.name || `anon`).join(` & `),
329
+ `>`,
330
+ refinement.name || `anon`,
331
+ `:`,
332
+ refinement(input)
333
+ ), refinement(input))
334
+ )
335
+ };
336
+ const checkTypes = Object.assign(_[name], {
337
+ and: (isTypeB) => mustBe(isTypeB, logging, [...refinements, isTypeB])
338
+ });
339
+ return checkTypes;
340
+ };
341
+ var isIntersection = mustBe(canExist);
342
+
294
343
  // ../anvl/src/join/core-relation-data.ts
295
344
  var RELATION_TYPES = [`1:1`, `1:n`, `n:n`];
296
345
  var isRelationType = (x) => RELATION_TYPES.includes(x);
297
346
  var EMPTY_RELATION_DATA = {
298
347
  contents: {},
299
348
  relations: {},
300
- relationType: `n:n`
349
+ relationType: `n:n`,
350
+ a: `from`,
351
+ b: `to`
301
352
  };
302
- var isRelationData = (isContent) => (input) => hasExactProperties({
353
+ var isRelationData = (isContent, a = `from`, b = `to`) => (input) => hasExactProperties({
303
354
  contents: isContent ? isRecord(import_string.isString, isContent) : hasExactProperties({}),
304
355
  relations: isRecord(import_string.isString, isArray(import_string.isString)),
305
- relationType: isRelationType
356
+ relationType: isRelationType,
357
+ a: isLiteral(a),
358
+ b: isLiteral(b)
306
359
  })(input);
307
360
 
308
361
  // ../anvl/src/join/get-related-ids.ts
@@ -391,7 +444,11 @@ var removeAll = (current, idToRemove) => {
391
444
  });
392
445
  return next;
393
446
  };
394
- var removeRelation = (current, idA, idB) => idB ? removeSpecific(current, idA, idB) : removeAll(current, idA);
447
+ var removeRelation = (current, relation) => {
448
+ const idA = relation[current.a];
449
+ const idB = relation[current.b];
450
+ return idB ? removeSpecific(current, idA, idB) : removeAll(current, idA);
451
+ };
395
452
 
396
453
  // ../anvl/src/join/set-relation.ts
397
454
  var setManyToMany = (map2, idA, idB, ...rest) => {
@@ -435,7 +492,8 @@ var set1To1 = (current, wifeId, husbandId, ...rest) => {
435
492
  const content = rest[0];
436
493
  return content ? setContent(next, wifeId, husbandId, content) : next;
437
494
  };
438
- var setRelationWithContent = (current, idA, idB, ...rest) => {
495
+ var setRelationWithContent = (current, relation, ...rest) => {
496
+ const { [current.a]: idA, [current.b]: idB } = relation;
439
497
  switch (current.relationType) {
440
498
  case `1:1`:
441
499
  return set1To1(current, idA, idB, ...rest);
@@ -459,96 +517,69 @@ var getRelations = (relationMap, id) => getRelationEntries(relationMap, id).map(
459
517
  id: id2
460
518
  }, content)
461
519
  );
462
- var setRelations = (current, idA, relations) => (0, import_function6.pipe)(
463
- current,
464
- (relationData) => {
465
- const relatedIds = getRelatedIds(current, idA);
466
- const removedIds = relatedIds.filter(
467
- (id) => !relations.some((r) => r.id === id)
468
- );
469
- let step = relationData;
470
- for (const idB of removedIds)
471
- step = removeRelation(step, idA, idB);
472
- return step;
473
- },
474
- (relationData) => {
475
- let step = relationData;
476
- for (const _a of relations) {
477
- const _b = _a, { id: idB } = _b, rest = __objRest(_b, ["id"]);
478
- const content = isEmptyObject(rest) ? void 0 : rest;
479
- step = setRelationWithContent(step, idA, idB, content);
480
- }
481
- return step;
482
- },
483
- (relationData) => {
484
- const newlyOrderedIds = relations.map((r) => r.id);
485
- return __spreadProps(__spreadValues({}, relationData), {
486
- relations: __spreadProps(__spreadValues({}, relationData.relations), {
487
- [idA]: newlyOrderedIds
488
- })
489
- });
490
- }
491
- );
492
-
493
- // ../anvl/src/refinement/index.ts
494
- var canExist = (_) => true;
495
- var cannotExist = (_) => false;
496
- var couldBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
497
- const name = `(${refinements.map((r) => r.name || `anon`).join(` | `)})`;
498
- const _ = {
499
- [name]: (input) => refinements.some(
500
- (refinement) => {
501
- var _a;
502
- return logging && console.log(
503
- refinements.map((r) => r.name || `anon`).join(` | `),
504
- `>`,
505
- (_a = refinement.name) != null ? _a : `anon`,
506
- `:`,
507
- refinement(input)
508
- ), refinement(input);
520
+ var setRelations = (current, subject, relations) => {
521
+ const idA = subject[current.a];
522
+ const idB = subject[current.b];
523
+ return (0, import_function6.pipe)(
524
+ current,
525
+ (relationData) => {
526
+ const relatedIds = getRelatedIds(current, idA);
527
+ const removedIds = relatedIds.filter(
528
+ (id) => !relations.some((r) => r.id === id)
529
+ );
530
+ let step = relationData;
531
+ for (const id of removedIds) {
532
+ const remove = {
533
+ [current.a]: idA != null ? idA : id,
534
+ [current.b]: idB != null ? idB : id
535
+ };
536
+ step = removeRelation(step, remove);
509
537
  }
510
- )
511
- };
512
- const checkTypes = Object.assign(_[name], {
513
- or: (isTypeB) => couldBe(isTypeB, logging, [...refinements, isTypeB])
514
- });
515
- return checkTypes;
516
- };
517
- var isUnion = couldBe(cannotExist);
518
- var mustBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
519
- const name = `(${refinements.map((r) => r.name || `anon`).join(` & `)})`;
520
- const _ = {
521
- [name]: (input) => refinements.every(
522
- (refinement) => (logging && console.log(
523
- refinements.map((r) => r.name || `anon`).join(` & `),
524
- `>`,
525
- refinement.name || `anon`,
526
- `:`,
527
- refinement(input)
528
- ), refinement(input))
529
- )
530
- };
531
- const checkTypes = Object.assign(_[name], {
532
- and: (isTypeB) => mustBe(isTypeB, logging, [...refinements, isTypeB])
533
- });
534
- return checkTypes;
538
+ return step;
539
+ },
540
+ (relationData) => {
541
+ let step = relationData;
542
+ for (const _a of relations) {
543
+ const _b = _a, { id } = _b, rest = __objRest(_b, ["id"]);
544
+ const content = isEmptyObject(rest) ? void 0 : rest;
545
+ step = setRelationWithContent(
546
+ step,
547
+ { [current.a]: idA != null ? idA : id, [current.b]: idB != null ? idB : id },
548
+ // @ts-expect-error hacky
549
+ content
550
+ );
551
+ }
552
+ return step;
553
+ },
554
+ (relationData) => {
555
+ const newlyOrderedIds = relations.map((r) => r.id);
556
+ return __spreadProps(__spreadValues({}, relationData), {
557
+ relations: __spreadProps(__spreadValues({}, relationData.relations), {
558
+ [idA != null ? idA : idB]: newlyOrderedIds
559
+ })
560
+ });
561
+ }
562
+ );
535
563
  };
536
- var isIntersection = mustBe(canExist);
537
564
 
538
565
  // ../anvl/src/join/index.ts
539
566
  var Join = class {
540
567
  constructor(json) {
568
+ this.a = `from`;
569
+ this.b = `to`;
541
570
  Object.assign(this, __spreadValues(__spreadValues({}, EMPTY_RELATION_DATA), json));
542
571
  }
543
572
  toJSON() {
544
573
  return {
545
574
  relationType: this.relationType,
546
575
  relations: this.relations,
547
- contents: this.contents
576
+ contents: this.contents,
577
+ a: this.a,
578
+ b: this.b
548
579
  };
549
580
  }
550
- static fromJSON(json, isContent = cannotExist) {
551
- const isValid = isRelationData(isContent)(json);
581
+ static fromJSON(json, isContent = cannotExist, a = `from`, b = `to`) {
582
+ const isValid = isRelationData(isContent, a, b)(json);
552
583
  if (isValid) {
553
584
  return new Join(json);
554
585
  }
@@ -556,6 +587,12 @@ var Join = class {
556
587
  `Saved JSON for this Join is invalid: ${JSON.stringify(json)}`
557
588
  );
558
589
  }
590
+ from(newA) {
591
+ return new Join(__spreadProps(__spreadValues({}, this), { a: newA }));
592
+ }
593
+ to(newB) {
594
+ return new Join(__spreadProps(__spreadValues({}, this), { b: newB }));
595
+ }
559
596
  getRelatedId(id) {
560
597
  return getRelatedId(this, id);
561
598
  }
@@ -577,14 +614,16 @@ var Join = class {
577
614
  getRelations(id) {
578
615
  return getRelations(this, id);
579
616
  }
580
- setRelations(id, relations) {
581
- return new Join(setRelations(this, id, relations));
617
+ setRelations(subject, relations) {
618
+ return new Join(setRelations(this, subject, relations));
582
619
  }
583
- set(idA, idB, ...rest) {
584
- return new Join(setRelationWithContent(this, idA, idB, ...rest));
620
+ set(relation, ...rest) {
621
+ return new Join(setRelationWithContent(this, relation, ...rest));
585
622
  }
586
- remove(idA, idB) {
587
- return new Join(removeRelation(this, idA, idB));
623
+ remove(relation) {
624
+ return new Join(
625
+ removeRelation(this, relation)
626
+ );
588
627
  }
589
628
  };
590
629
 
@@ -593,14 +632,20 @@ var createStore = (name) => ({
593
632
  atoms: import_hamt_plus2.default.make(),
594
633
  atomsThatAreDefault: /* @__PURE__ */ new Set(),
595
634
  readonlySelectors: import_hamt_plus2.default.make(),
596
- selectorAtoms: new Join({ relationType: `n:n` }),
635
+ selectorAtoms: new Join({ relationType: `n:n` }).from(`selectorKey`).to(`atomKey`),
597
636
  selectorGraph: new Join({ relationType: `n:n` }),
598
637
  selectors: import_hamt_plus2.default.make(),
599
638
  timelines: import_hamt_plus2.default.make(),
600
- timelineAtoms: new Join({ relationType: `1:n` }),
639
+ timelineAtoms: new Join({ relationType: `1:n` }).from(`timelineKey`).to(`atomKey`),
601
640
  timelineStore: import_hamt_plus2.default.make(),
602
641
  transactions: import_hamt_plus2.default.make(),
603
642
  valueMap: import_hamt_plus2.default.make(),
643
+ subject: {
644
+ atomCreation: new Rx.Subject(),
645
+ selectorCreation: new Rx.Subject(),
646
+ transactionCreation: new Rx.Subject(),
647
+ timelineCreation: new Rx.Subject()
648
+ },
604
649
  operation: {
605
650
  open: false
606
651
  },
@@ -633,7 +678,6 @@ var openOperation = (token, store) => {
633
678
  var _a, _b;
634
679
  const core = target(store);
635
680
  if (core.operation.open) {
636
- console.warn(core.operation.open);
637
681
  (_a = store.config.logger) == null ? void 0 : _a.error(
638
682
  `\u274C failed to setState to "${token.key}" during a setState for "${core.operation.token.key}"`
639
683
  );
@@ -720,7 +764,7 @@ var hasKeyBeenUsed = (key, store = IMPLICIT.STORE) => {
720
764
 
721
765
  // src/internal/transaction-internal.ts
722
766
  var import_hamt_plus4 = __toESM(require("hamt_plus"));
723
- var Rx = __toESM(require("rxjs"));
767
+ var Rx2 = __toESM(require("rxjs"));
724
768
  var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
725
769
  var buildTransaction = (key, params, store) => {
726
770
  var _a;
@@ -747,7 +791,7 @@ var buildTransaction = (key, params, store) => {
747
791
  (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F6EB}`, `transaction "${key}" started`);
748
792
  };
749
793
  var applyTransaction = (output, store) => {
750
- var _a, _b, _c;
794
+ var _a, _b, _c, _d;
751
795
  if (store.transactionStatus.phase !== `building`) {
752
796
  (_a = store.config.logger) == null ? void 0 : _a.warn(
753
797
  `abortTransaction called outside of a transaction. This is probably a bug.`
@@ -755,13 +799,19 @@ var applyTransaction = (output, store) => {
755
799
  return;
756
800
  }
757
801
  (_b = store.config.logger) == null ? void 0 : _b.info(
758
- ` \u25B6\uFE0F apply transaction "${store.transactionStatus.key}" (init)`
802
+ `\u{1F6C3} apply transaction "${store.transactionStatus.key}"`
759
803
  );
760
804
  store.transactionStatus.phase = `applying`;
761
805
  store.transactionStatus.output = output;
762
806
  const { atomUpdates } = store.transactionStatus;
763
- for (const { key, oldValue, newValue } of atomUpdates) {
807
+ for (const { key, newValue } of atomUpdates) {
764
808
  const token = { key, type: `atom` };
809
+ if (!import_hamt_plus4.default.has(token.key, store.valueMap)) {
810
+ const atom2 = import_hamt_plus4.default.get(token.key, store.transactionStatus.core.atoms);
811
+ store.atoms = import_hamt_plus4.default.set(atom2.key, atom2, store.atoms);
812
+ store.valueMap = import_hamt_plus4.default.set(atom2.key, atom2.default, store.valueMap);
813
+ (_c = store.config.logger) == null ? void 0 : _c.info(`\u{1F527}`, `add atom "${atom2.key}"`);
814
+ }
765
815
  const state = withdraw(token, store);
766
816
  setState(state, newValue, store);
767
817
  }
@@ -776,12 +826,12 @@ var applyTransaction = (output, store) => {
776
826
  params: store.transactionStatus.params
777
827
  });
778
828
  store.transactionStatus = { phase: `idle` };
779
- (_c = store.config.logger) == null ? void 0 : _c.info(`\u{1F6EC}`, `transaction done`);
829
+ (_d = store.config.logger) == null ? void 0 : _d.info(`\u{1F6EC}`, `transaction done`);
780
830
  };
781
831
  var undoTransactionUpdate = (update, store) => {
782
832
  var _a;
783
833
  (_a = store.config.logger) == null ? void 0 : _a.info(` \u23EE undo transaction "${update.key}" (undo)`);
784
- for (const { key, oldValue, newValue } of update.atomUpdates) {
834
+ for (const { key, oldValue } of update.atomUpdates) {
785
835
  const token = { key, type: `atom` };
786
836
  const state = withdraw(token, store);
787
837
  setState(state, oldValue, store);
@@ -790,7 +840,7 @@ var undoTransactionUpdate = (update, store) => {
790
840
  var redoTransactionUpdate = (update, store) => {
791
841
  var _a;
792
842
  (_a = store.config.logger) == null ? void 0 : _a.info(` \u23ED redo transaction "${update.key}" (redo)`);
793
- for (const { key, oldValue, newValue } of update.atomUpdates) {
843
+ for (const { key, newValue } of update.atomUpdates) {
794
844
  const token = { key, type: `atom` };
795
845
  const state = withdraw(token, store);
796
846
  setState(state, newValue, store);
@@ -830,7 +880,7 @@ function transaction__INTERNAL(options, store = IMPLICIT.STORE) {
830
880
  throw thrown;
831
881
  }
832
882
  },
833
- subject: new Rx.Subject()
883
+ subject: new Rx2.Subject()
834
884
  };
835
885
  const core = target(store);
836
886
  core.transactions = import_hamt_plus4.default.set(
@@ -839,6 +889,7 @@ function transaction__INTERNAL(options, store = IMPLICIT.STORE) {
839
889
  core.transactions
840
890
  );
841
891
  const token = deposit(newTransaction);
892
+ store.subject.transactionCreation.next(token);
842
893
  return token;
843
894
  }
844
895
  var target = (store = IMPLICIT.STORE) => store.transactionStatus.phase === `building` ? store.transactionStatus.core : store;
@@ -854,24 +905,28 @@ function atom__INTERNAL(options, family, store = IMPLICIT.STORE) {
854
905
  );
855
906
  return deposit(core.atoms.get(options.key));
856
907
  }
857
- const subject = new Rx2.Subject();
908
+ const subject = new Rx3.Subject();
858
909
  const newAtom = __spreadValues(__spreadProps(__spreadValues({}, options), {
859
910
  subject,
860
911
  type: `atom`
861
912
  }), family && { family });
862
913
  const initialValue = options.default instanceof Function ? options.default() : options.default;
863
- storeAtom(newAtom, store);
914
+ core.atoms = import_hamt_plus5.default.set(newAtom.key, newAtom, core.atoms);
864
915
  markAtomAsDefault(options.key, store);
865
916
  cacheValue(options.key, initialValue, store);
866
917
  const token = deposit(newAtom);
867
- const setSelf = (next) => setState(token, next, store);
868
- const onSet = (handle) => subscribe(token, handle, store);
869
- (_c = options.effects) == null ? void 0 : _c.forEach((effect) => effect({ setSelf, onSet }));
918
+ (_c = options.effects) == null ? void 0 : _c.forEach(
919
+ (effect) => effect({
920
+ setSelf: (next) => setState(token, next, store),
921
+ onSet: (handle) => subscribe(token, handle, store)
922
+ })
923
+ );
924
+ store.subject.atomCreation.next(token);
870
925
  return token;
871
926
  }
872
927
 
873
928
  // src/internal/families-internal.ts
874
- var Rx3 = __toESM(require("rxjs"));
929
+ var Rx4 = __toESM(require("rxjs"));
875
930
 
876
931
  // ../anvl/src/json/index.ts
877
932
  var import_function8 = require("fp-ts/function");
@@ -879,7 +934,7 @@ var stringifyJson = (json) => JSON.stringify(json);
879
934
 
880
935
  // src/internal/families-internal.ts
881
936
  function atomFamily__INTERNAL(options, store = IMPLICIT.STORE) {
882
- const subject = new Rx3.Subject();
937
+ const subject = new Rx4.Subject();
883
938
  return Object.assign(
884
939
  (key) => {
885
940
  var _a;
@@ -908,7 +963,7 @@ function atomFamily__INTERNAL(options, store = IMPLICIT.STORE) {
908
963
  }
909
964
  function readonlySelectorFamily__INTERNAL(options, store) {
910
965
  const core = target(store);
911
- const subject = new Rx3.Subject();
966
+ const subject = new Rx4.Subject();
912
967
  return Object.assign(
913
968
  (key) => {
914
969
  const subKey = stringifyJson(key);
@@ -940,7 +995,7 @@ function selectorFamily__INTERNAL(options, store = IMPLICIT.STORE) {
940
995
  return readonlySelectorFamily__INTERNAL(options, store);
941
996
  }
942
997
  const core = target(store);
943
- const subject = new Rx3.Subject();
998
+ const subject = new Rx4.Subject();
944
999
  return Object.assign(
945
1000
  (key) => {
946
1001
  const subKey = stringifyJson(key);
@@ -969,9 +1024,123 @@ function selectorFamily__INTERNAL(options, store = IMPLICIT.STORE) {
969
1024
  );
970
1025
  }
971
1026
 
1027
+ // src/internal/meta/index.ts
1028
+ var meta_exports = {};
1029
+ __export(meta_exports, {
1030
+ attachMetaAtoms: () => attachMetaAtoms,
1031
+ attachMetaSelectors: () => attachMetaSelectors,
1032
+ attachMetaState: () => attachMetaState
1033
+ });
1034
+
1035
+ // src/internal/meta/meta-state.ts
1036
+ var attachMetaAtoms = (store = IMPLICIT.STORE) => {
1037
+ const atomTokenIndexState__INTERNAL = atom({
1038
+ key: `\u{1F441}\u200D\u{1F5E8}_atom_token_index__INTERNAL`,
1039
+ default: () => [...store.atoms].reduce((acc, [key]) => {
1040
+ acc[key] = { key, type: `atom` };
1041
+ return acc;
1042
+ }, {}),
1043
+ effects: [
1044
+ ({ setSelf }) => {
1045
+ store.subject.atomCreation.subscribe((atomToken) => {
1046
+ if (store.operation.open) {
1047
+ return;
1048
+ }
1049
+ setSelf((state) => {
1050
+ const { key, family } = atomToken;
1051
+ if (family) {
1052
+ const { key: familyKey, subKey } = family;
1053
+ const current = state[familyKey];
1054
+ if (current === void 0 || `familyMembers` in current) {
1055
+ const familyKeyState = current || {
1056
+ key: familyKey,
1057
+ familyMembers: {}
1058
+ };
1059
+ return __spreadProps(__spreadValues({}, state), {
1060
+ [familyKey]: __spreadProps(__spreadValues({}, familyKeyState), {
1061
+ familyMembers: __spreadProps(__spreadValues({}, familyKeyState.familyMembers), {
1062
+ [subKey]: atomToken
1063
+ })
1064
+ })
1065
+ });
1066
+ }
1067
+ }
1068
+ return __spreadProps(__spreadValues({}, state), {
1069
+ [key]: atomToken
1070
+ });
1071
+ });
1072
+ });
1073
+ }
1074
+ ]
1075
+ });
1076
+ return selector({
1077
+ key: `\u{1F441}\u200D\u{1F5E8}_atom_token_index`,
1078
+ get: ({ get }) => get(atomTokenIndexState__INTERNAL)
1079
+ });
1080
+ };
1081
+ var attachMetaSelectors = (store = IMPLICIT.STORE) => {
1082
+ const readonlySelectorTokenIndexState__INTERNAL = atom({
1083
+ key: `\u{1F441}\u200D\u{1F5E8}_selector_token_index__INTERNAL`,
1084
+ default: () => Object.assign(
1085
+ [...store.readonlySelectors].reduce((acc, [key]) => {
1086
+ acc[key] = { key, type: `readonly_selector` };
1087
+ return acc;
1088
+ }, {}),
1089
+ [...store.selectors].reduce((acc, [key]) => {
1090
+ acc[key] = { key, type: `selector` };
1091
+ return acc;
1092
+ }, {})
1093
+ ),
1094
+ effects: [
1095
+ ({ setSelf }) => {
1096
+ store.subject.selectorCreation.subscribe((selectorToken) => {
1097
+ if (store.operation.open) {
1098
+ return;
1099
+ }
1100
+ setSelf((state) => {
1101
+ const { key, family } = selectorToken;
1102
+ if (family) {
1103
+ const { key: familyKey, subKey } = family;
1104
+ const current = state[familyKey];
1105
+ if (current === void 0 || `familyMembers` in current) {
1106
+ const familyKeyState = current || {
1107
+ key: familyKey,
1108
+ familyMembers: {}
1109
+ };
1110
+ return __spreadProps(__spreadValues({}, state), {
1111
+ [familyKey]: __spreadProps(__spreadValues({}, familyKeyState), {
1112
+ familyMembers: __spreadProps(__spreadValues({}, familyKeyState.familyMembers), {
1113
+ [subKey]: selectorToken
1114
+ })
1115
+ })
1116
+ });
1117
+ }
1118
+ }
1119
+ return __spreadProps(__spreadValues({}, state), {
1120
+ [key]: selectorToken
1121
+ });
1122
+ });
1123
+ });
1124
+ }
1125
+ ]
1126
+ });
1127
+ return selector({
1128
+ key: `\u{1F441}\u200D\u{1F5E8}_selector_token_index`,
1129
+ get: ({ get }) => get(readonlySelectorTokenIndexState__INTERNAL)
1130
+ });
1131
+ };
1132
+
1133
+ // src/internal/meta/attach-meta.ts
1134
+ var attachMetaState = (store = IMPLICIT.STORE) => {
1135
+ return {
1136
+ atomTokenIndexState: attachMetaAtoms(store),
1137
+ selectorTokenIndexState: attachMetaSelectors(store)
1138
+ };
1139
+ };
1140
+
972
1141
  // src/internal/selector-internal.ts
973
- var import_hamt_plus5 = __toESM(require("hamt_plus"));
974
- var Rx4 = __toESM(require("rxjs"));
1142
+ var import_hamt_plus6 = __toESM(require("hamt_plus"));
1143
+ var Rx5 = __toESM(require("rxjs"));
975
1144
  var lookupSelectorSources = (key, store) => target(store).selectorGraph.getRelations(key).filter(({ source }) => source !== key).map(({ source }) => lookup(source, store));
976
1145
  var traceSelectorAtoms = (selectorKey, dependency, store) => {
977
1146
  const roots = [];
@@ -1003,7 +1172,10 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
1003
1172
  var _a, _b;
1004
1173
  const core = target(store);
1005
1174
  if (dependency.type === `atom`) {
1006
- core.selectorAtoms = core.selectorAtoms.set(selectorKey, dependency.key);
1175
+ core.selectorAtoms = core.selectorAtoms.set({
1176
+ selectorKey,
1177
+ atomKey: dependency.key
1178
+ });
1007
1179
  (_a = store.config.logger) == null ? void 0 : _a.info(
1008
1180
  ` || adding root for "${selectorKey}": ${dependency.key}`
1009
1181
  );
@@ -1015,7 +1187,10 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
1015
1187
  roots.map((r) => r.key)
1016
1188
  );
1017
1189
  for (const root of roots) {
1018
- core.selectorAtoms = core.selectorAtoms.set(selectorKey, root.key);
1190
+ core.selectorAtoms = core.selectorAtoms.set({
1191
+ selectorKey,
1192
+ atomKey: root.key
1193
+ });
1019
1194
  }
1020
1195
  };
1021
1196
  var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
@@ -1036,9 +1211,12 @@ var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
1036
1211
  dependencyValue,
1037
1212
  `)`
1038
1213
  );
1039
- core.selectorGraph = core.selectorGraph.set(selectorKey, dependency.key, {
1040
- source: dependency.key
1041
- });
1214
+ core.selectorGraph = core.selectorGraph.set(
1215
+ { from: dependency.key, to: selectorKey },
1216
+ {
1217
+ source: dependency.key
1218
+ }
1219
+ );
1042
1220
  }
1043
1221
  updateSelectorAtoms(selectorKey, dependency, store);
1044
1222
  return dependencyValue;
@@ -1051,12 +1229,12 @@ var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
1051
1229
  function selector__INTERNAL(options, family, store = IMPLICIT.STORE) {
1052
1230
  var _a, _b, _c;
1053
1231
  const core = target(store);
1054
- if (import_hamt_plus5.default.has(options.key, core.selectors)) {
1232
+ if (import_hamt_plus6.default.has(options.key, core.selectors)) {
1055
1233
  (_a = store.config.logger) == null ? void 0 : _a.error(
1056
1234
  `Key "${options.key}" already exists in the store.`
1057
1235
  );
1058
1236
  }
1059
- const subject = new Rx4.Subject();
1237
+ const subject = new Rx5.Subject();
1060
1238
  const { get, set } = registerSelector(options.key, store);
1061
1239
  const getSelf = () => {
1062
1240
  const value = options.get({ get });
@@ -1069,14 +1247,20 @@ function selector__INTERNAL(options, family, store = IMPLICIT.STORE) {
1069
1247
  get: getSelf,
1070
1248
  type: `readonly_selector`
1071
1249
  }), family && { family });
1072
- core.readonlySelectors = import_hamt_plus5.default.set(
1250
+ core.readonlySelectors = import_hamt_plus6.default.set(
1073
1251
  options.key,
1074
1252
  readonlySelector,
1075
1253
  core.readonlySelectors
1076
1254
  );
1077
1255
  const initialValue2 = getSelf();
1078
1256
  (_b = store.config.logger) == null ? void 0 : _b.info(` \u2728 "${options.key}" =`, initialValue2);
1079
- return __spreadProps(__spreadValues({}, readonlySelector), { type: `readonly_selector` });
1257
+ const token2 = {
1258
+ key: options.key,
1259
+ type: `readonly_selector`,
1260
+ family
1261
+ };
1262
+ store.subject.selectorCreation.next(token2);
1263
+ return token2;
1080
1264
  }
1081
1265
  const setSelf = (next) => {
1082
1266
  var _a2;
@@ -1096,14 +1280,20 @@ function selector__INTERNAL(options, family, store = IMPLICIT.STORE) {
1096
1280
  set: setSelf,
1097
1281
  type: `selector`
1098
1282
  }), family && { family });
1099
- core.selectors = import_hamt_plus5.default.set(options.key, mySelector, core.selectors);
1283
+ core.selectors = import_hamt_plus6.default.set(options.key, mySelector, core.selectors);
1100
1284
  const initialValue = getSelf();
1101
1285
  (_c = store.config.logger) == null ? void 0 : _c.info(` \u2728 "${options.key}" =`, initialValue);
1102
- return __spreadProps(__spreadValues({}, mySelector), { type: `selector` });
1286
+ const token = {
1287
+ key: options.key,
1288
+ type: `selector`,
1289
+ family
1290
+ };
1291
+ store.subject.selectorCreation.next(token);
1292
+ return token;
1103
1293
  }
1104
1294
 
1105
1295
  // src/internal/set.ts
1106
- var import_hamt_plus6 = __toESM(require("hamt_plus"));
1296
+ var import_hamt_plus7 = __toESM(require("hamt_plus"));
1107
1297
  var evictDownStream = (state, store = IMPLICIT.STORE) => {
1108
1298
  var _a, _b;
1109
1299
  const core = target(store);
@@ -1122,7 +1312,7 @@ var evictDownStream = (state, store = IMPLICIT.STORE) => {
1122
1312
  (_a2 = store.config.logger) == null ? void 0 : _a2.info(` || ${stateKey} already done`);
1123
1313
  return;
1124
1314
  }
1125
- const state2 = (_b2 = import_hamt_plus6.default.get(stateKey, core.selectors)) != null ? _b2 : import_hamt_plus6.default.get(stateKey, core.readonlySelectors);
1315
+ const state2 = (_b2 = import_hamt_plus7.default.get(stateKey, core.selectors)) != null ? _b2 : import_hamt_plus7.default.get(stateKey, core.readonlySelectors);
1126
1316
  if (!state2) {
1127
1317
  (_c = store.config.logger) == null ? void 0 : _c.info(
1128
1318
  ` || ${stateKey} is an atom, and can't be downstream`
@@ -1223,43 +1413,123 @@ var subscribeToRootAtoms = (state, store) => {
1223
1413
  return dependencySubscriptions;
1224
1414
  };
1225
1415
 
1416
+ // src/internal/time-travel-internal.ts
1417
+ var redo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1418
+ var _a, _b, _c, _d;
1419
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u23E9 redo "${token.key}"`);
1420
+ const timelineData = store.timelineStore.get(token.key);
1421
+ if (!timelineData) {
1422
+ (_b = store.config.logger) == null ? void 0 : _b.error(
1423
+ `Failed to redo on timeline "${token.key}". This timeline has not been initialized.`
1424
+ );
1425
+ return;
1426
+ }
1427
+ if (timelineData.at === timelineData.history.length) {
1428
+ (_c = store.config.logger) == null ? void 0 : _c.warn(
1429
+ `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`
1430
+ );
1431
+ return;
1432
+ }
1433
+ timelineData.timeTraveling = true;
1434
+ const update = timelineData.history[timelineData.at];
1435
+ switch (update.type) {
1436
+ case `atom_update`: {
1437
+ const { key, newValue } = update;
1438
+ setState({ key, type: `atom` }, newValue);
1439
+ break;
1440
+ }
1441
+ case `selector_update`:
1442
+ case `transaction_update`: {
1443
+ for (const atomUpdate of update.atomUpdates) {
1444
+ const { key, newValue } = atomUpdate;
1445
+ setState({ key, type: `atom` }, newValue);
1446
+ }
1447
+ break;
1448
+ }
1449
+ }
1450
+ ++timelineData.at;
1451
+ timelineData.timeTraveling = false;
1452
+ (_d = store.config.logger) == null ? void 0 : _d.info(
1453
+ `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1454
+ );
1455
+ };
1456
+ var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1457
+ var _a, _b, _c, _d;
1458
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u23EA undo "${token.key}"`);
1459
+ const timelineData = store.timelineStore.get(token.key);
1460
+ if (!timelineData) {
1461
+ (_b = store.config.logger) == null ? void 0 : _b.error(
1462
+ `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`
1463
+ );
1464
+ return;
1465
+ }
1466
+ if (timelineData.at === 0) {
1467
+ (_c = store.config.logger) == null ? void 0 : _c.warn(
1468
+ `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`
1469
+ );
1470
+ return;
1471
+ }
1472
+ timelineData.timeTraveling = true;
1473
+ --timelineData.at;
1474
+ const update = timelineData.history[timelineData.at];
1475
+ switch (update.type) {
1476
+ case `atom_update`: {
1477
+ const { key, oldValue } = update;
1478
+ setState({ key, type: `atom` }, oldValue);
1479
+ break;
1480
+ }
1481
+ case `selector_update`:
1482
+ case `transaction_update`: {
1483
+ for (const atomUpdate of update.atomUpdates) {
1484
+ const { key, oldValue } = atomUpdate;
1485
+ setState({ key, type: `atom` }, oldValue);
1486
+ }
1487
+ break;
1488
+ }
1489
+ }
1490
+ timelineData.timeTraveling = false;
1491
+ (_d = store.config.logger) == null ? void 0 : _d.info(
1492
+ `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1493
+ );
1494
+ };
1495
+
1226
1496
  // src/internal/timeline-internal.ts
1227
- var import_hamt_plus7 = __toESM(require("hamt_plus"));
1497
+ var import_hamt_plus8 = __toESM(require("hamt_plus"));
1228
1498
  function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1229
1499
  var _a, _b;
1230
- let incompleteSelectorTime = null;
1231
- let incompleteTransactionKey = null;
1232
1500
  const timelineData = {
1233
1501
  at: 0,
1234
1502
  timeTraveling: false,
1235
- history: []
1503
+ history: [],
1504
+ selectorTime: null,
1505
+ transactionKey: null
1236
1506
  };
1237
- const subscribeToAtom = (token) => {
1238
- const state = withdraw(token, store);
1507
+ const subscribeToAtom = (token2) => {
1508
+ const state = withdraw(token2, store);
1239
1509
  state.subject.subscribe((update) => {
1240
1510
  var _a2, _b2, _c, _d, _e;
1241
1511
  const storeCurrentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
1242
1512
  const storeCurrentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
1243
1513
  const storeCurrentTransactionKey = store.transactionStatus.phase === `applying` ? store.transactionStatus.key : null;
1244
1514
  (_a2 = store.config.logger) == null ? void 0 : _a2.info(
1245
- `\u23F3 timeline "${options.key}" saw atom "${token.key}" go (`,
1515
+ `\u23F3 timeline "${options.key}" saw atom "${token2.key}" go (`,
1246
1516
  update.oldValue,
1247
1517
  `->`,
1248
1518
  update.newValue,
1249
- storeCurrentTransactionKey ? `) in "${storeCurrentTransactionKey}"` : `) independently`
1519
+ storeCurrentTransactionKey ? `) in transaction "${storeCurrentTransactionKey}"` : storeCurrentSelectorKey ? `) in selector "${storeCurrentSelectorKey}"` : `)`
1250
1520
  );
1251
1521
  if (storeCurrentTransactionKey && store.transactionStatus.phase === `applying`) {
1252
1522
  const currentTransaction = withdraw(
1253
1523
  { key: storeCurrentTransactionKey, type: `transaction` },
1254
1524
  store
1255
1525
  );
1256
- if (incompleteTransactionKey !== storeCurrentTransactionKey) {
1257
- if (incompleteTransactionKey) {
1526
+ if (timelineData.transactionKey !== storeCurrentTransactionKey) {
1527
+ if (timelineData.transactionKey) {
1258
1528
  (_b2 = store.config.logger) == null ? void 0 : _b2.error(
1259
- `Timeline "${options.key}" was unable to resolve transaction "${incompleteTransactionKey}. This is probably a bug.`
1529
+ `Timeline "${options.key}" was unable to resolve transaction "${timelineData.transactionKey}. This is probably a bug.`
1260
1530
  );
1261
1531
  }
1262
- incompleteTransactionKey = storeCurrentTransactionKey;
1532
+ timelineData.transactionKey = storeCurrentTransactionKey;
1263
1533
  const subscription = currentTransaction.subject.subscribe((update2) => {
1264
1534
  var _a3;
1265
1535
  if (timelineData.timeTraveling === false) {
@@ -1276,7 +1546,7 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1276
1546
  }
1277
1547
  timelineData.at = timelineData.history.length;
1278
1548
  subscription.unsubscribe();
1279
- incompleteTransactionKey = null;
1549
+ timelineData.transactionKey = null;
1280
1550
  (_a3 = store.config.logger) == null ? void 0 : _a3.info(
1281
1551
  `\u231B timeline "${options.key}" got a transaction_update "${update2.key}"`
1282
1552
  );
@@ -1284,14 +1554,14 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1284
1554
  }
1285
1555
  } else if (storeCurrentSelectorKey) {
1286
1556
  if (timelineData.timeTraveling === false) {
1287
- if (storeCurrentSelectorTime !== incompleteSelectorTime) {
1557
+ if (storeCurrentSelectorTime !== timelineData.selectorTime) {
1288
1558
  const newSelectorUpdate = {
1289
1559
  type: `selector_update`,
1290
1560
  key: storeCurrentSelectorKey,
1291
1561
  atomUpdates: []
1292
1562
  };
1293
1563
  newSelectorUpdate.atomUpdates.push(__spreadValues({
1294
- key: token.key,
1564
+ key: token2.key,
1295
1565
  type: `atom_update`
1296
1566
  }, update));
1297
1567
  if (timelineData.at !== timelineData.history.length) {
@@ -1303,12 +1573,12 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1303
1573
  newSelectorUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
1304
1574
  );
1305
1575
  timelineData.at = timelineData.history.length;
1306
- incompleteSelectorTime = storeCurrentSelectorTime;
1576
+ timelineData.selectorTime = storeCurrentSelectorTime;
1307
1577
  } else {
1308
1578
  const latestUpdate = timelineData.history.at(-1);
1309
1579
  if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
1310
1580
  latestUpdate.atomUpdates.push(__spreadValues({
1311
- key: token.key,
1581
+ key: token2.key,
1312
1582
  type: `atom_update`
1313
1583
  }, update));
1314
1584
  (_d = store.config.logger) == null ? void 0 : _d.info(
@@ -1320,18 +1590,18 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1320
1590
  }
1321
1591
  } else {
1322
1592
  if (timelineData.timeTraveling === false) {
1323
- incompleteSelectorTime = null;
1593
+ timelineData.selectorTime = null;
1324
1594
  if (timelineData.at !== timelineData.history.length) {
1325
1595
  timelineData.history.splice(timelineData.at);
1326
1596
  }
1327
1597
  timelineData.history.push({
1328
1598
  type: `atom_update`,
1329
- key: token.key,
1599
+ key: token2.key,
1330
1600
  oldValue: update.oldValue,
1331
1601
  newValue: update.newValue
1332
1602
  });
1333
1603
  (_e = store.config.logger) == null ? void 0 : _e.info(
1334
- `\u231B timeline "${options.key}" got a state_update to "${token.key}"`
1604
+ `\u231B timeline "${options.key}" got a state_update to "${token2.key}"`
1335
1605
  );
1336
1606
  timelineData.at = timelineData.history.length;
1337
1607
  }
@@ -1349,108 +1619,35 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1349
1619
  }
1350
1620
  if (tokenOrFamily.type === `atom_family`) {
1351
1621
  const family = tokenOrFamily;
1352
- family.subject.subscribe((token) => subscribeToAtom(token));
1622
+ family.subject.subscribe((token2) => subscribeToAtom(token2));
1353
1623
  } else {
1354
- const token = tokenOrFamily;
1355
- if (`family` in token && token.family) {
1624
+ const token2 = tokenOrFamily;
1625
+ if (`family` in token2 && token2.family) {
1356
1626
  const familyTimelineKey = core.timelineAtoms.getRelatedId(
1357
- token.family.key
1627
+ token2.family.key
1358
1628
  );
1359
1629
  if (familyTimelineKey) {
1360
1630
  (_b = store.config.logger) == null ? void 0 : _b.error(
1361
- `\u274C Failed to add atom "${token.key}" to timeline "${options.key}" because its family "${token.family.key}" belongs to timeline "${familyTimelineKey}"`
1631
+ `\u274C Failed to add atom "${token2.key}" to timeline "${options.key}" because its family "${token2.family.key}" belongs to timeline "${familyTimelineKey}"`
1362
1632
  );
1363
1633
  continue;
1364
1634
  }
1365
1635
  }
1366
- subscribeToAtom(token);
1636
+ subscribeToAtom(token2);
1367
1637
  }
1368
- core.timelineAtoms = core.timelineAtoms.set(tokenOrFamily.key, options.key);
1638
+ core.timelineAtoms = core.timelineAtoms.set({
1639
+ atomKey: tokenOrFamily.key,
1640
+ timelineKey: options.key
1641
+ });
1369
1642
  }
1370
- store.timelineStore = import_hamt_plus7.default.set(options.key, timelineData, store.timelineStore);
1371
- return {
1643
+ store.timelineStore = import_hamt_plus8.default.set(options.key, timelineData, store.timelineStore);
1644
+ const token = {
1372
1645
  key: options.key,
1373
1646
  type: `timeline`
1374
1647
  };
1648
+ store.subject.timelineCreation.next(token);
1649
+ return token;
1375
1650
  }
1376
- var redo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1377
- var _a, _b, _c, _d;
1378
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u23E9 redo "${token.key}"`);
1379
- const timelineData = store.timelineStore.get(token.key);
1380
- if (!timelineData) {
1381
- (_b = store.config.logger) == null ? void 0 : _b.error(
1382
- `Failed to redo on timeline "${token.key}". This timeline has not been initialized.`
1383
- );
1384
- return;
1385
- }
1386
- if (timelineData.at === timelineData.history.length) {
1387
- (_c = store.config.logger) == null ? void 0 : _c.warn(
1388
- `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`
1389
- );
1390
- return;
1391
- }
1392
- timelineData.timeTraveling = true;
1393
- const update = timelineData.history[timelineData.at];
1394
- switch (update.type) {
1395
- case `atom_update`: {
1396
- const { key, newValue } = update;
1397
- setState({ key, type: `atom` }, newValue);
1398
- break;
1399
- }
1400
- case `selector_update`:
1401
- case `transaction_update`: {
1402
- for (const atomUpdate of update.atomUpdates) {
1403
- const { key, newValue } = atomUpdate;
1404
- setState({ key, type: `atom` }, newValue);
1405
- }
1406
- break;
1407
- }
1408
- }
1409
- ++timelineData.at;
1410
- timelineData.timeTraveling = false;
1411
- (_d = store.config.logger) == null ? void 0 : _d.info(
1412
- `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1413
- );
1414
- };
1415
- var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1416
- var _a, _b, _c, _d;
1417
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u23EA undo "${token.key}"`);
1418
- const timelineData = store.timelineStore.get(token.key);
1419
- if (!timelineData) {
1420
- (_b = store.config.logger) == null ? void 0 : _b.error(
1421
- `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`
1422
- );
1423
- return;
1424
- }
1425
- if (timelineData.at === 0) {
1426
- (_c = store.config.logger) == null ? void 0 : _c.warn(
1427
- `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`
1428
- );
1429
- return;
1430
- }
1431
- timelineData.timeTraveling = true;
1432
- --timelineData.at;
1433
- const update = timelineData.history[timelineData.at];
1434
- switch (update.type) {
1435
- case `atom_update`: {
1436
- const { key, oldValue } = update;
1437
- setState({ key, type: `atom` }, oldValue);
1438
- break;
1439
- }
1440
- case `selector_update`:
1441
- case `transaction_update`: {
1442
- for (const atomUpdate of update.atomUpdates) {
1443
- const { key, oldValue } = atomUpdate;
1444
- setState({ key, type: `atom` }, oldValue);
1445
- }
1446
- break;
1447
- }
1448
- }
1449
- timelineData.timeTraveling = false;
1450
- (_d = store.config.logger) == null ? void 0 : _d.info(
1451
- `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1452
- );
1453
- };
1454
1651
 
1455
1652
  // src/atom.ts
1456
1653
  function atom(options) {