atom.io 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +11 -3
  2. package/dist/index.d.ts +83 -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 +1579 -0
  17. package/react-devtools/dist/index.js.map +1 -0
  18. package/react-devtools/dist/index.mjs +1551 -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 +49 -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 +2 -2
  53. package/src/web-effects/index.ts +1 -0
  54. package/src/web-effects/storage.ts +30 -0
package/dist/index.mjs CHANGED
@@ -38,6 +38,7 @@ var __export = (target2, all) => {
38
38
  var internal_exports = {};
39
39
  __export(internal_exports, {
40
40
  IMPLICIT: () => IMPLICIT,
41
+ META: () => meta_exports,
41
42
  TRANSACTION_PHASES: () => TRANSACTION_PHASES,
42
43
  abortTransaction: () => abortTransaction,
43
44
  applyTransaction: () => applyTransaction,
@@ -94,7 +95,8 @@ __export(internal_exports, {
94
95
  });
95
96
 
96
97
  // src/internal/atom-internal.ts
97
- import * as Rx2 from "rxjs";
98
+ import HAMT5 from "hamt_plus";
99
+ import * as Rx3 from "rxjs";
98
100
 
99
101
  // src/internal/get.ts
100
102
  import HAMT from "hamt_plus";
@@ -155,6 +157,7 @@ import HAMT3 from "hamt_plus";
155
157
 
156
158
  // src/internal/store.ts
157
159
  import HAMT2 from "hamt_plus";
160
+ import * as Rx from "rxjs";
158
161
 
159
162
  // ../anvl/src/function/index.ts
160
163
  var doNothing = () => void 0;
@@ -246,18 +249,68 @@ var hasExactProperties = (
246
249
  (isValue) => hasProperties(isValue, { allowExtraProperties: false })
247
250
  );
248
251
 
252
+ // ../anvl/src/refinement/index.ts
253
+ var canExist = (_) => true;
254
+ var cannotExist = (_) => false;
255
+ var isLiteral = (value) => (input) => input === value;
256
+ var couldBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
257
+ const name = `(${refinements.map((r) => r.name || `anon`).join(` | `)})`;
258
+ const _ = {
259
+ [name]: (input) => refinements.some(
260
+ (refinement) => {
261
+ var _a;
262
+ return logging && console.log(
263
+ refinements.map((r) => r.name || `anon`).join(` | `),
264
+ `>`,
265
+ (_a = refinement.name) != null ? _a : `anon`,
266
+ `:`,
267
+ refinement(input)
268
+ ), refinement(input);
269
+ }
270
+ )
271
+ };
272
+ const checkTypes = Object.assign(_[name], {
273
+ or: (isTypeB) => couldBe(isTypeB, logging, [...refinements, isTypeB])
274
+ });
275
+ return checkTypes;
276
+ };
277
+ var isUnion = couldBe(cannotExist);
278
+ var mustBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
279
+ const name = `(${refinements.map((r) => r.name || `anon`).join(` & `)})`;
280
+ const _ = {
281
+ [name]: (input) => refinements.every(
282
+ (refinement) => (logging && console.log(
283
+ refinements.map((r) => r.name || `anon`).join(` & `),
284
+ `>`,
285
+ refinement.name || `anon`,
286
+ `:`,
287
+ refinement(input)
288
+ ), refinement(input))
289
+ )
290
+ };
291
+ const checkTypes = Object.assign(_[name], {
292
+ and: (isTypeB) => mustBe(isTypeB, logging, [...refinements, isTypeB])
293
+ });
294
+ return checkTypes;
295
+ };
296
+ var isIntersection = mustBe(canExist);
297
+
249
298
  // ../anvl/src/join/core-relation-data.ts
250
299
  var RELATION_TYPES = [`1:1`, `1:n`, `n:n`];
251
300
  var isRelationType = (x) => RELATION_TYPES.includes(x);
252
301
  var EMPTY_RELATION_DATA = {
253
302
  contents: {},
254
303
  relations: {},
255
- relationType: `n:n`
304
+ relationType: `n:n`,
305
+ a: `from`,
306
+ b: `to`
256
307
  };
257
- var isRelationData = (isContent) => (input) => hasExactProperties({
308
+ var isRelationData = (isContent, a = `from`, b = `to`) => (input) => hasExactProperties({
258
309
  contents: isContent ? isRecord(isString, isContent) : hasExactProperties({}),
259
310
  relations: isRecord(isString, isArray(isString)),
260
- relationType: isRelationType
311
+ relationType: isRelationType,
312
+ a: isLiteral(a),
313
+ b: isLiteral(b)
261
314
  })(input);
262
315
 
263
316
  // ../anvl/src/join/get-related-ids.ts
@@ -346,7 +399,11 @@ var removeAll = (current, idToRemove) => {
346
399
  });
347
400
  return next;
348
401
  };
349
- var removeRelation = (current, idA, idB) => idB ? removeSpecific(current, idA, idB) : removeAll(current, idA);
402
+ var removeRelation = (current, relation) => {
403
+ const idA = relation[current.a];
404
+ const idB = relation[current.b];
405
+ return idB ? removeSpecific(current, idA, idB) : removeAll(current, idA);
406
+ };
350
407
 
351
408
  // ../anvl/src/join/set-relation.ts
352
409
  var setManyToMany = (map2, idA, idB, ...rest) => {
@@ -390,7 +447,8 @@ var set1To1 = (current, wifeId, husbandId, ...rest) => {
390
447
  const content = rest[0];
391
448
  return content ? setContent(next, wifeId, husbandId, content) : next;
392
449
  };
393
- var setRelationWithContent = (current, idA, idB, ...rest) => {
450
+ var setRelationWithContent = (current, relation, ...rest) => {
451
+ const { [current.a]: idA, [current.b]: idB } = relation;
394
452
  switch (current.relationType) {
395
453
  case `1:1`:
396
454
  return set1To1(current, idA, idB, ...rest);
@@ -414,96 +472,69 @@ var getRelations = (relationMap, id) => getRelationEntries(relationMap, id).map(
414
472
  id: id2
415
473
  }, content)
416
474
  );
417
- var setRelations = (current, idA, relations) => pipe5(
418
- current,
419
- (relationData) => {
420
- const relatedIds = getRelatedIds(current, idA);
421
- const removedIds = relatedIds.filter(
422
- (id) => !relations.some((r) => r.id === id)
423
- );
424
- let step = relationData;
425
- for (const idB of removedIds)
426
- step = removeRelation(step, idA, idB);
427
- return step;
428
- },
429
- (relationData) => {
430
- let step = relationData;
431
- for (const _a of relations) {
432
- const _b = _a, { id: idB } = _b, rest = __objRest(_b, ["id"]);
433
- const content = isEmptyObject(rest) ? void 0 : rest;
434
- step = setRelationWithContent(step, idA, idB, content);
435
- }
436
- return step;
437
- },
438
- (relationData) => {
439
- const newlyOrderedIds = relations.map((r) => r.id);
440
- return __spreadProps(__spreadValues({}, relationData), {
441
- relations: __spreadProps(__spreadValues({}, relationData.relations), {
442
- [idA]: newlyOrderedIds
443
- })
444
- });
445
- }
446
- );
447
-
448
- // ../anvl/src/refinement/index.ts
449
- var canExist = (_) => true;
450
- var cannotExist = (_) => false;
451
- var couldBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
452
- const name = `(${refinements.map((r) => r.name || `anon`).join(` | `)})`;
453
- const _ = {
454
- [name]: (input) => refinements.some(
455
- (refinement) => {
456
- var _a;
457
- return logging && console.log(
458
- refinements.map((r) => r.name || `anon`).join(` | `),
459
- `>`,
460
- (_a = refinement.name) != null ? _a : `anon`,
461
- `:`,
462
- refinement(input)
463
- ), refinement(input);
475
+ var setRelations = (current, subject, relations) => {
476
+ const idA = subject[current.a];
477
+ const idB = subject[current.b];
478
+ return pipe5(
479
+ current,
480
+ (relationData) => {
481
+ const relatedIds = getRelatedIds(current, idA);
482
+ const removedIds = relatedIds.filter(
483
+ (id) => !relations.some((r) => r.id === id)
484
+ );
485
+ let step = relationData;
486
+ for (const id of removedIds) {
487
+ const remove = {
488
+ [current.a]: idA != null ? idA : id,
489
+ [current.b]: idB != null ? idB : id
490
+ };
491
+ step = removeRelation(step, remove);
464
492
  }
465
- )
466
- };
467
- const checkTypes = Object.assign(_[name], {
468
- or: (isTypeB) => couldBe(isTypeB, logging, [...refinements, isTypeB])
469
- });
470
- return checkTypes;
471
- };
472
- var isUnion = couldBe(cannotExist);
473
- var mustBe = (isTypeA, logging = false, refinements = [isTypeA]) => {
474
- const name = `(${refinements.map((r) => r.name || `anon`).join(` & `)})`;
475
- const _ = {
476
- [name]: (input) => refinements.every(
477
- (refinement) => (logging && console.log(
478
- refinements.map((r) => r.name || `anon`).join(` & `),
479
- `>`,
480
- refinement.name || `anon`,
481
- `:`,
482
- refinement(input)
483
- ), refinement(input))
484
- )
485
- };
486
- const checkTypes = Object.assign(_[name], {
487
- and: (isTypeB) => mustBe(isTypeB, logging, [...refinements, isTypeB])
488
- });
489
- return checkTypes;
493
+ return step;
494
+ },
495
+ (relationData) => {
496
+ let step = relationData;
497
+ for (const _a of relations) {
498
+ const _b = _a, { id } = _b, rest = __objRest(_b, ["id"]);
499
+ const content = isEmptyObject(rest) ? void 0 : rest;
500
+ step = setRelationWithContent(
501
+ step,
502
+ { [current.a]: idA != null ? idA : id, [current.b]: idB != null ? idB : id },
503
+ // @ts-expect-error hacky
504
+ content
505
+ );
506
+ }
507
+ return step;
508
+ },
509
+ (relationData) => {
510
+ const newlyOrderedIds = relations.map((r) => r.id);
511
+ return __spreadProps(__spreadValues({}, relationData), {
512
+ relations: __spreadProps(__spreadValues({}, relationData.relations), {
513
+ [idA != null ? idA : idB]: newlyOrderedIds
514
+ })
515
+ });
516
+ }
517
+ );
490
518
  };
491
- var isIntersection = mustBe(canExist);
492
519
 
493
520
  // ../anvl/src/join/index.ts
494
521
  var Join = class {
495
522
  constructor(json) {
523
+ this.a = `from`;
524
+ this.b = `to`;
496
525
  Object.assign(this, __spreadValues(__spreadValues({}, EMPTY_RELATION_DATA), json));
497
526
  }
498
527
  toJSON() {
499
528
  return {
500
529
  relationType: this.relationType,
501
530
  relations: this.relations,
502
- contents: this.contents
531
+ contents: this.contents,
532
+ a: this.a,
533
+ b: this.b
503
534
  };
504
535
  }
505
- static fromJSON(json, isContent = cannotExist) {
506
- const isValid = isRelationData(isContent)(json);
536
+ static fromJSON(json, isContent = cannotExist, a = `from`, b = `to`) {
537
+ const isValid = isRelationData(isContent, a, b)(json);
507
538
  if (isValid) {
508
539
  return new Join(json);
509
540
  }
@@ -511,6 +542,12 @@ var Join = class {
511
542
  `Saved JSON for this Join is invalid: ${JSON.stringify(json)}`
512
543
  );
513
544
  }
545
+ from(newA) {
546
+ return new Join(__spreadProps(__spreadValues({}, this), { a: newA }));
547
+ }
548
+ to(newB) {
549
+ return new Join(__spreadProps(__spreadValues({}, this), { b: newB }));
550
+ }
514
551
  getRelatedId(id) {
515
552
  return getRelatedId(this, id);
516
553
  }
@@ -532,14 +569,16 @@ var Join = class {
532
569
  getRelations(id) {
533
570
  return getRelations(this, id);
534
571
  }
535
- setRelations(id, relations) {
536
- return new Join(setRelations(this, id, relations));
572
+ setRelations(subject, relations) {
573
+ return new Join(setRelations(this, subject, relations));
537
574
  }
538
- set(idA, idB, ...rest) {
539
- return new Join(setRelationWithContent(this, idA, idB, ...rest));
575
+ set(relation, ...rest) {
576
+ return new Join(setRelationWithContent(this, relation, ...rest));
540
577
  }
541
- remove(idA, idB) {
542
- return new Join(removeRelation(this, idA, idB));
578
+ remove(relation) {
579
+ return new Join(
580
+ removeRelation(this, relation)
581
+ );
543
582
  }
544
583
  };
545
584
 
@@ -548,14 +587,20 @@ var createStore = (name) => ({
548
587
  atoms: HAMT2.make(),
549
588
  atomsThatAreDefault: /* @__PURE__ */ new Set(),
550
589
  readonlySelectors: HAMT2.make(),
551
- selectorAtoms: new Join({ relationType: `n:n` }),
590
+ selectorAtoms: new Join({ relationType: `n:n` }).from(`selectorKey`).to(`atomKey`),
552
591
  selectorGraph: new Join({ relationType: `n:n` }),
553
592
  selectors: HAMT2.make(),
554
593
  timelines: HAMT2.make(),
555
- timelineAtoms: new Join({ relationType: `1:n` }),
594
+ timelineAtoms: new Join({ relationType: `1:n` }).from(`timelineKey`).to(`atomKey`),
556
595
  timelineStore: HAMT2.make(),
557
596
  transactions: HAMT2.make(),
558
597
  valueMap: HAMT2.make(),
598
+ subject: {
599
+ atomCreation: new Rx.Subject(),
600
+ selectorCreation: new Rx.Subject(),
601
+ transactionCreation: new Rx.Subject(),
602
+ timelineCreation: new Rx.Subject()
603
+ },
559
604
  operation: {
560
605
  open: false
561
606
  },
@@ -588,7 +633,6 @@ var openOperation = (token, store) => {
588
633
  var _a, _b;
589
634
  const core = target(store);
590
635
  if (core.operation.open) {
591
- console.warn(core.operation.open);
592
636
  (_a = store.config.logger) == null ? void 0 : _a.error(
593
637
  `\u274C failed to setState to "${token.key}" during a setState for "${core.operation.token.key}"`
594
638
  );
@@ -675,7 +719,7 @@ var hasKeyBeenUsed = (key, store = IMPLICIT.STORE) => {
675
719
 
676
720
  // src/internal/transaction-internal.ts
677
721
  import HAMT4 from "hamt_plus";
678
- import * as Rx from "rxjs";
722
+ import * as Rx2 from "rxjs";
679
723
  var TRANSACTION_PHASES = [`idle`, `building`, `applying`];
680
724
  var buildTransaction = (key, params, store) => {
681
725
  var _a;
@@ -702,7 +746,7 @@ var buildTransaction = (key, params, store) => {
702
746
  (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F6EB}`, `transaction "${key}" started`);
703
747
  };
704
748
  var applyTransaction = (output, store) => {
705
- var _a, _b, _c;
749
+ var _a, _b, _c, _d;
706
750
  if (store.transactionStatus.phase !== `building`) {
707
751
  (_a = store.config.logger) == null ? void 0 : _a.warn(
708
752
  `abortTransaction called outside of a transaction. This is probably a bug.`
@@ -710,13 +754,19 @@ var applyTransaction = (output, store) => {
710
754
  return;
711
755
  }
712
756
  (_b = store.config.logger) == null ? void 0 : _b.info(
713
- ` \u25B6\uFE0F apply transaction "${store.transactionStatus.key}" (init)`
757
+ `\u{1F6C3} apply transaction "${store.transactionStatus.key}"`
714
758
  );
715
759
  store.transactionStatus.phase = `applying`;
716
760
  store.transactionStatus.output = output;
717
761
  const { atomUpdates } = store.transactionStatus;
718
- for (const { key, oldValue, newValue } of atomUpdates) {
762
+ for (const { key, newValue } of atomUpdates) {
719
763
  const token = { key, type: `atom` };
764
+ if (!HAMT4.has(token.key, store.valueMap)) {
765
+ const atom2 = HAMT4.get(token.key, store.transactionStatus.core.atoms);
766
+ store.atoms = HAMT4.set(atom2.key, atom2, store.atoms);
767
+ store.valueMap = HAMT4.set(atom2.key, atom2.default, store.valueMap);
768
+ (_c = store.config.logger) == null ? void 0 : _c.info(`\u{1F527}`, `add atom "${atom2.key}"`);
769
+ }
720
770
  const state = withdraw(token, store);
721
771
  setState(state, newValue, store);
722
772
  }
@@ -731,12 +781,12 @@ var applyTransaction = (output, store) => {
731
781
  params: store.transactionStatus.params
732
782
  });
733
783
  store.transactionStatus = { phase: `idle` };
734
- (_c = store.config.logger) == null ? void 0 : _c.info(`\u{1F6EC}`, `transaction done`);
784
+ (_d = store.config.logger) == null ? void 0 : _d.info(`\u{1F6EC}`, `transaction done`);
735
785
  };
736
786
  var undoTransactionUpdate = (update, store) => {
737
787
  var _a;
738
788
  (_a = store.config.logger) == null ? void 0 : _a.info(` \u23EE undo transaction "${update.key}" (undo)`);
739
- for (const { key, oldValue, newValue } of update.atomUpdates) {
789
+ for (const { key, oldValue } of update.atomUpdates) {
740
790
  const token = { key, type: `atom` };
741
791
  const state = withdraw(token, store);
742
792
  setState(state, oldValue, store);
@@ -745,7 +795,7 @@ var undoTransactionUpdate = (update, store) => {
745
795
  var redoTransactionUpdate = (update, store) => {
746
796
  var _a;
747
797
  (_a = store.config.logger) == null ? void 0 : _a.info(` \u23ED redo transaction "${update.key}" (redo)`);
748
- for (const { key, oldValue, newValue } of update.atomUpdates) {
798
+ for (const { key, newValue } of update.atomUpdates) {
749
799
  const token = { key, type: `atom` };
750
800
  const state = withdraw(token, store);
751
801
  setState(state, newValue, store);
@@ -785,7 +835,7 @@ function transaction__INTERNAL(options, store = IMPLICIT.STORE) {
785
835
  throw thrown;
786
836
  }
787
837
  },
788
- subject: new Rx.Subject()
838
+ subject: new Rx2.Subject()
789
839
  };
790
840
  const core = target(store);
791
841
  core.transactions = HAMT4.set(
@@ -794,6 +844,7 @@ function transaction__INTERNAL(options, store = IMPLICIT.STORE) {
794
844
  core.transactions
795
845
  );
796
846
  const token = deposit(newTransaction);
847
+ store.subject.transactionCreation.next(token);
797
848
  return token;
798
849
  }
799
850
  var target = (store = IMPLICIT.STORE) => store.transactionStatus.phase === `building` ? store.transactionStatus.core : store;
@@ -809,24 +860,28 @@ function atom__INTERNAL(options, family, store = IMPLICIT.STORE) {
809
860
  );
810
861
  return deposit(core.atoms.get(options.key));
811
862
  }
812
- const subject = new Rx2.Subject();
863
+ const subject = new Rx3.Subject();
813
864
  const newAtom = __spreadValues(__spreadProps(__spreadValues({}, options), {
814
865
  subject,
815
866
  type: `atom`
816
867
  }), family && { family });
817
868
  const initialValue = options.default instanceof Function ? options.default() : options.default;
818
- storeAtom(newAtom, store);
869
+ core.atoms = HAMT5.set(newAtom.key, newAtom, core.atoms);
819
870
  markAtomAsDefault(options.key, store);
820
871
  cacheValue(options.key, initialValue, store);
821
872
  const token = deposit(newAtom);
822
- const setSelf = (next) => setState(token, next, store);
823
- const onSet = (handle) => subscribe(token, handle, store);
824
- (_c = options.effects) == null ? void 0 : _c.forEach((effect) => effect({ setSelf, onSet }));
873
+ (_c = options.effects) == null ? void 0 : _c.forEach(
874
+ (effect) => effect({
875
+ setSelf: (next) => setState(token, next, store),
876
+ onSet: (handle) => subscribe(token, handle, store)
877
+ })
878
+ );
879
+ store.subject.atomCreation.next(token);
825
880
  return token;
826
881
  }
827
882
 
828
883
  // src/internal/families-internal.ts
829
- import * as Rx3 from "rxjs";
884
+ import * as Rx4 from "rxjs";
830
885
 
831
886
  // ../anvl/src/json/index.ts
832
887
  import { pipe as pipe6 } from "fp-ts/function";
@@ -834,7 +889,7 @@ var stringifyJson = (json) => JSON.stringify(json);
834
889
 
835
890
  // src/internal/families-internal.ts
836
891
  function atomFamily__INTERNAL(options, store = IMPLICIT.STORE) {
837
- const subject = new Rx3.Subject();
892
+ const subject = new Rx4.Subject();
838
893
  return Object.assign(
839
894
  (key) => {
840
895
  var _a;
@@ -863,7 +918,7 @@ function atomFamily__INTERNAL(options, store = IMPLICIT.STORE) {
863
918
  }
864
919
  function readonlySelectorFamily__INTERNAL(options, store) {
865
920
  const core = target(store);
866
- const subject = new Rx3.Subject();
921
+ const subject = new Rx4.Subject();
867
922
  return Object.assign(
868
923
  (key) => {
869
924
  const subKey = stringifyJson(key);
@@ -895,7 +950,7 @@ function selectorFamily__INTERNAL(options, store = IMPLICIT.STORE) {
895
950
  return readonlySelectorFamily__INTERNAL(options, store);
896
951
  }
897
952
  const core = target(store);
898
- const subject = new Rx3.Subject();
953
+ const subject = new Rx4.Subject();
899
954
  return Object.assign(
900
955
  (key) => {
901
956
  const subKey = stringifyJson(key);
@@ -924,9 +979,123 @@ function selectorFamily__INTERNAL(options, store = IMPLICIT.STORE) {
924
979
  );
925
980
  }
926
981
 
982
+ // src/internal/meta/index.ts
983
+ var meta_exports = {};
984
+ __export(meta_exports, {
985
+ attachMetaAtoms: () => attachMetaAtoms,
986
+ attachMetaSelectors: () => attachMetaSelectors,
987
+ attachMetaState: () => attachMetaState
988
+ });
989
+
990
+ // src/internal/meta/meta-state.ts
991
+ var attachMetaAtoms = (store = IMPLICIT.STORE) => {
992
+ const atomTokenIndexState__INTERNAL = atom({
993
+ key: `\u{1F441}\u200D\u{1F5E8}_atom_token_index__INTERNAL`,
994
+ default: () => [...store.atoms].reduce((acc, [key]) => {
995
+ acc[key] = { key, type: `atom` };
996
+ return acc;
997
+ }, {}),
998
+ effects: [
999
+ ({ setSelf }) => {
1000
+ store.subject.atomCreation.subscribe((atomToken) => {
1001
+ if (store.operation.open) {
1002
+ return;
1003
+ }
1004
+ setSelf((state) => {
1005
+ const { key, family } = atomToken;
1006
+ if (family) {
1007
+ const { key: familyKey, subKey } = family;
1008
+ const current = state[familyKey];
1009
+ if (current === void 0 || `familyMembers` in current) {
1010
+ const familyKeyState = current || {
1011
+ key: familyKey,
1012
+ familyMembers: {}
1013
+ };
1014
+ return __spreadProps(__spreadValues({}, state), {
1015
+ [familyKey]: __spreadProps(__spreadValues({}, familyKeyState), {
1016
+ familyMembers: __spreadProps(__spreadValues({}, familyKeyState.familyMembers), {
1017
+ [subKey]: atomToken
1018
+ })
1019
+ })
1020
+ });
1021
+ }
1022
+ }
1023
+ return __spreadProps(__spreadValues({}, state), {
1024
+ [key]: atomToken
1025
+ });
1026
+ });
1027
+ });
1028
+ }
1029
+ ]
1030
+ });
1031
+ return selector({
1032
+ key: `\u{1F441}\u200D\u{1F5E8}_atom_token_index`,
1033
+ get: ({ get }) => get(atomTokenIndexState__INTERNAL)
1034
+ });
1035
+ };
1036
+ var attachMetaSelectors = (store = IMPLICIT.STORE) => {
1037
+ const readonlySelectorTokenIndexState__INTERNAL = atom({
1038
+ key: `\u{1F441}\u200D\u{1F5E8}_selector_token_index__INTERNAL`,
1039
+ default: () => Object.assign(
1040
+ [...store.readonlySelectors].reduce((acc, [key]) => {
1041
+ acc[key] = { key, type: `readonly_selector` };
1042
+ return acc;
1043
+ }, {}),
1044
+ [...store.selectors].reduce((acc, [key]) => {
1045
+ acc[key] = { key, type: `selector` };
1046
+ return acc;
1047
+ }, {})
1048
+ ),
1049
+ effects: [
1050
+ ({ setSelf }) => {
1051
+ store.subject.selectorCreation.subscribe((selectorToken) => {
1052
+ if (store.operation.open) {
1053
+ return;
1054
+ }
1055
+ setSelf((state) => {
1056
+ const { key, family } = selectorToken;
1057
+ if (family) {
1058
+ const { key: familyKey, subKey } = family;
1059
+ const current = state[familyKey];
1060
+ if (current === void 0 || `familyMembers` in current) {
1061
+ const familyKeyState = current || {
1062
+ key: familyKey,
1063
+ familyMembers: {}
1064
+ };
1065
+ return __spreadProps(__spreadValues({}, state), {
1066
+ [familyKey]: __spreadProps(__spreadValues({}, familyKeyState), {
1067
+ familyMembers: __spreadProps(__spreadValues({}, familyKeyState.familyMembers), {
1068
+ [subKey]: selectorToken
1069
+ })
1070
+ })
1071
+ });
1072
+ }
1073
+ }
1074
+ return __spreadProps(__spreadValues({}, state), {
1075
+ [key]: selectorToken
1076
+ });
1077
+ });
1078
+ });
1079
+ }
1080
+ ]
1081
+ });
1082
+ return selector({
1083
+ key: `\u{1F441}\u200D\u{1F5E8}_selector_token_index`,
1084
+ get: ({ get }) => get(readonlySelectorTokenIndexState__INTERNAL)
1085
+ });
1086
+ };
1087
+
1088
+ // src/internal/meta/attach-meta.ts
1089
+ var attachMetaState = (store = IMPLICIT.STORE) => {
1090
+ return {
1091
+ atomTokenIndexState: attachMetaAtoms(store),
1092
+ selectorTokenIndexState: attachMetaSelectors(store)
1093
+ };
1094
+ };
1095
+
927
1096
  // src/internal/selector-internal.ts
928
- import HAMT5 from "hamt_plus";
929
- import * as Rx4 from "rxjs";
1097
+ import HAMT6 from "hamt_plus";
1098
+ import * as Rx5 from "rxjs";
930
1099
  var lookupSelectorSources = (key, store) => target(store).selectorGraph.getRelations(key).filter(({ source }) => source !== key).map(({ source }) => lookup(source, store));
931
1100
  var traceSelectorAtoms = (selectorKey, dependency, store) => {
932
1101
  const roots = [];
@@ -958,7 +1127,10 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
958
1127
  var _a, _b;
959
1128
  const core = target(store);
960
1129
  if (dependency.type === `atom`) {
961
- core.selectorAtoms = core.selectorAtoms.set(selectorKey, dependency.key);
1130
+ core.selectorAtoms = core.selectorAtoms.set({
1131
+ selectorKey,
1132
+ atomKey: dependency.key
1133
+ });
962
1134
  (_a = store.config.logger) == null ? void 0 : _a.info(
963
1135
  ` || adding root for "${selectorKey}": ${dependency.key}`
964
1136
  );
@@ -970,7 +1142,10 @@ var updateSelectorAtoms = (selectorKey, dependency, store) => {
970
1142
  roots.map((r) => r.key)
971
1143
  );
972
1144
  for (const root of roots) {
973
- core.selectorAtoms = core.selectorAtoms.set(selectorKey, root.key);
1145
+ core.selectorAtoms = core.selectorAtoms.set({
1146
+ selectorKey,
1147
+ atomKey: root.key
1148
+ });
974
1149
  }
975
1150
  };
976
1151
  var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
@@ -991,9 +1166,12 @@ var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
991
1166
  dependencyValue,
992
1167
  `)`
993
1168
  );
994
- core.selectorGraph = core.selectorGraph.set(selectorKey, dependency.key, {
995
- source: dependency.key
996
- });
1169
+ core.selectorGraph = core.selectorGraph.set(
1170
+ { from: dependency.key, to: selectorKey },
1171
+ {
1172
+ source: dependency.key
1173
+ }
1174
+ );
997
1175
  }
998
1176
  updateSelectorAtoms(selectorKey, dependency, store);
999
1177
  return dependencyValue;
@@ -1006,12 +1184,12 @@ var registerSelector = (selectorKey, store = IMPLICIT.STORE) => ({
1006
1184
  function selector__INTERNAL(options, family, store = IMPLICIT.STORE) {
1007
1185
  var _a, _b, _c;
1008
1186
  const core = target(store);
1009
- if (HAMT5.has(options.key, core.selectors)) {
1187
+ if (HAMT6.has(options.key, core.selectors)) {
1010
1188
  (_a = store.config.logger) == null ? void 0 : _a.error(
1011
1189
  `Key "${options.key}" already exists in the store.`
1012
1190
  );
1013
1191
  }
1014
- const subject = new Rx4.Subject();
1192
+ const subject = new Rx5.Subject();
1015
1193
  const { get, set } = registerSelector(options.key, store);
1016
1194
  const getSelf = () => {
1017
1195
  const value = options.get({ get });
@@ -1024,14 +1202,20 @@ function selector__INTERNAL(options, family, store = IMPLICIT.STORE) {
1024
1202
  get: getSelf,
1025
1203
  type: `readonly_selector`
1026
1204
  }), family && { family });
1027
- core.readonlySelectors = HAMT5.set(
1205
+ core.readonlySelectors = HAMT6.set(
1028
1206
  options.key,
1029
1207
  readonlySelector,
1030
1208
  core.readonlySelectors
1031
1209
  );
1032
1210
  const initialValue2 = getSelf();
1033
1211
  (_b = store.config.logger) == null ? void 0 : _b.info(` \u2728 "${options.key}" =`, initialValue2);
1034
- return __spreadProps(__spreadValues({}, readonlySelector), { type: `readonly_selector` });
1212
+ const token2 = {
1213
+ key: options.key,
1214
+ type: `readonly_selector`,
1215
+ family
1216
+ };
1217
+ store.subject.selectorCreation.next(token2);
1218
+ return token2;
1035
1219
  }
1036
1220
  const setSelf = (next) => {
1037
1221
  var _a2;
@@ -1051,14 +1235,20 @@ function selector__INTERNAL(options, family, store = IMPLICIT.STORE) {
1051
1235
  set: setSelf,
1052
1236
  type: `selector`
1053
1237
  }), family && { family });
1054
- core.selectors = HAMT5.set(options.key, mySelector, core.selectors);
1238
+ core.selectors = HAMT6.set(options.key, mySelector, core.selectors);
1055
1239
  const initialValue = getSelf();
1056
1240
  (_c = store.config.logger) == null ? void 0 : _c.info(` \u2728 "${options.key}" =`, initialValue);
1057
- return __spreadProps(__spreadValues({}, mySelector), { type: `selector` });
1241
+ const token = {
1242
+ key: options.key,
1243
+ type: `selector`,
1244
+ family
1245
+ };
1246
+ store.subject.selectorCreation.next(token);
1247
+ return token;
1058
1248
  }
1059
1249
 
1060
1250
  // src/internal/set.ts
1061
- import HAMT6 from "hamt_plus";
1251
+ import HAMT7 from "hamt_plus";
1062
1252
  var evictDownStream = (state, store = IMPLICIT.STORE) => {
1063
1253
  var _a, _b;
1064
1254
  const core = target(store);
@@ -1077,7 +1267,7 @@ var evictDownStream = (state, store = IMPLICIT.STORE) => {
1077
1267
  (_a2 = store.config.logger) == null ? void 0 : _a2.info(` || ${stateKey} already done`);
1078
1268
  return;
1079
1269
  }
1080
- const state2 = (_b2 = HAMT6.get(stateKey, core.selectors)) != null ? _b2 : HAMT6.get(stateKey, core.readonlySelectors);
1270
+ const state2 = (_b2 = HAMT7.get(stateKey, core.selectors)) != null ? _b2 : HAMT7.get(stateKey, core.readonlySelectors);
1081
1271
  if (!state2) {
1082
1272
  (_c = store.config.logger) == null ? void 0 : _c.info(
1083
1273
  ` || ${stateKey} is an atom, and can't be downstream`
@@ -1178,43 +1368,123 @@ var subscribeToRootAtoms = (state, store) => {
1178
1368
  return dependencySubscriptions;
1179
1369
  };
1180
1370
 
1371
+ // src/internal/time-travel-internal.ts
1372
+ var redo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1373
+ var _a, _b, _c, _d;
1374
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u23E9 redo "${token.key}"`);
1375
+ const timelineData = store.timelineStore.get(token.key);
1376
+ if (!timelineData) {
1377
+ (_b = store.config.logger) == null ? void 0 : _b.error(
1378
+ `Failed to redo on timeline "${token.key}". This timeline has not been initialized.`
1379
+ );
1380
+ return;
1381
+ }
1382
+ if (timelineData.at === timelineData.history.length) {
1383
+ (_c = store.config.logger) == null ? void 0 : _c.warn(
1384
+ `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`
1385
+ );
1386
+ return;
1387
+ }
1388
+ timelineData.timeTraveling = true;
1389
+ const update = timelineData.history[timelineData.at];
1390
+ switch (update.type) {
1391
+ case `atom_update`: {
1392
+ const { key, newValue } = update;
1393
+ setState({ key, type: `atom` }, newValue);
1394
+ break;
1395
+ }
1396
+ case `selector_update`:
1397
+ case `transaction_update`: {
1398
+ for (const atomUpdate of update.atomUpdates) {
1399
+ const { key, newValue } = atomUpdate;
1400
+ setState({ key, type: `atom` }, newValue);
1401
+ }
1402
+ break;
1403
+ }
1404
+ }
1405
+ ++timelineData.at;
1406
+ timelineData.timeTraveling = false;
1407
+ (_d = store.config.logger) == null ? void 0 : _d.info(
1408
+ `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1409
+ );
1410
+ };
1411
+ var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1412
+ var _a, _b, _c, _d;
1413
+ (_a = store.config.logger) == null ? void 0 : _a.info(`\u23EA undo "${token.key}"`);
1414
+ const timelineData = store.timelineStore.get(token.key);
1415
+ if (!timelineData) {
1416
+ (_b = store.config.logger) == null ? void 0 : _b.error(
1417
+ `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`
1418
+ );
1419
+ return;
1420
+ }
1421
+ if (timelineData.at === 0) {
1422
+ (_c = store.config.logger) == null ? void 0 : _c.warn(
1423
+ `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`
1424
+ );
1425
+ return;
1426
+ }
1427
+ timelineData.timeTraveling = true;
1428
+ --timelineData.at;
1429
+ const update = timelineData.history[timelineData.at];
1430
+ switch (update.type) {
1431
+ case `atom_update`: {
1432
+ const { key, oldValue } = update;
1433
+ setState({ key, type: `atom` }, oldValue);
1434
+ break;
1435
+ }
1436
+ case `selector_update`:
1437
+ case `transaction_update`: {
1438
+ for (const atomUpdate of update.atomUpdates) {
1439
+ const { key, oldValue } = atomUpdate;
1440
+ setState({ key, type: `atom` }, oldValue);
1441
+ }
1442
+ break;
1443
+ }
1444
+ }
1445
+ timelineData.timeTraveling = false;
1446
+ (_d = store.config.logger) == null ? void 0 : _d.info(
1447
+ `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1448
+ );
1449
+ };
1450
+
1181
1451
  // src/internal/timeline-internal.ts
1182
- import HAMT7 from "hamt_plus";
1452
+ import HAMT8 from "hamt_plus";
1183
1453
  function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1184
1454
  var _a, _b;
1185
- let incompleteSelectorTime = null;
1186
- let incompleteTransactionKey = null;
1187
1455
  const timelineData = {
1188
1456
  at: 0,
1189
1457
  timeTraveling: false,
1190
- history: []
1458
+ history: [],
1459
+ selectorTime: null,
1460
+ transactionKey: null
1191
1461
  };
1192
- const subscribeToAtom = (token) => {
1193
- const state = withdraw(token, store);
1462
+ const subscribeToAtom = (token2) => {
1463
+ const state = withdraw(token2, store);
1194
1464
  state.subject.subscribe((update) => {
1195
1465
  var _a2, _b2, _c, _d, _e;
1196
1466
  const storeCurrentSelectorKey = store.operation.open && store.operation.token.type === `selector` ? store.operation.token.key : null;
1197
1467
  const storeCurrentSelectorTime = store.operation.open && store.operation.token.type === `selector` ? store.operation.time : null;
1198
1468
  const storeCurrentTransactionKey = store.transactionStatus.phase === `applying` ? store.transactionStatus.key : null;
1199
1469
  (_a2 = store.config.logger) == null ? void 0 : _a2.info(
1200
- `\u23F3 timeline "${options.key}" saw atom "${token.key}" go (`,
1470
+ `\u23F3 timeline "${options.key}" saw atom "${token2.key}" go (`,
1201
1471
  update.oldValue,
1202
1472
  `->`,
1203
1473
  update.newValue,
1204
- storeCurrentTransactionKey ? `) in "${storeCurrentTransactionKey}"` : `) independently`
1474
+ storeCurrentTransactionKey ? `) in transaction "${storeCurrentTransactionKey}"` : storeCurrentSelectorKey ? `) in selector "${storeCurrentSelectorKey}"` : `)`
1205
1475
  );
1206
1476
  if (storeCurrentTransactionKey && store.transactionStatus.phase === `applying`) {
1207
1477
  const currentTransaction = withdraw(
1208
1478
  { key: storeCurrentTransactionKey, type: `transaction` },
1209
1479
  store
1210
1480
  );
1211
- if (incompleteTransactionKey !== storeCurrentTransactionKey) {
1212
- if (incompleteTransactionKey) {
1481
+ if (timelineData.transactionKey !== storeCurrentTransactionKey) {
1482
+ if (timelineData.transactionKey) {
1213
1483
  (_b2 = store.config.logger) == null ? void 0 : _b2.error(
1214
- `Timeline "${options.key}" was unable to resolve transaction "${incompleteTransactionKey}. This is probably a bug.`
1484
+ `Timeline "${options.key}" was unable to resolve transaction "${timelineData.transactionKey}. This is probably a bug.`
1215
1485
  );
1216
1486
  }
1217
- incompleteTransactionKey = storeCurrentTransactionKey;
1487
+ timelineData.transactionKey = storeCurrentTransactionKey;
1218
1488
  const subscription = currentTransaction.subject.subscribe((update2) => {
1219
1489
  var _a3;
1220
1490
  if (timelineData.timeTraveling === false) {
@@ -1231,7 +1501,7 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1231
1501
  }
1232
1502
  timelineData.at = timelineData.history.length;
1233
1503
  subscription.unsubscribe();
1234
- incompleteTransactionKey = null;
1504
+ timelineData.transactionKey = null;
1235
1505
  (_a3 = store.config.logger) == null ? void 0 : _a3.info(
1236
1506
  `\u231B timeline "${options.key}" got a transaction_update "${update2.key}"`
1237
1507
  );
@@ -1239,14 +1509,14 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1239
1509
  }
1240
1510
  } else if (storeCurrentSelectorKey) {
1241
1511
  if (timelineData.timeTraveling === false) {
1242
- if (storeCurrentSelectorTime !== incompleteSelectorTime) {
1512
+ if (storeCurrentSelectorTime !== timelineData.selectorTime) {
1243
1513
  const newSelectorUpdate = {
1244
1514
  type: `selector_update`,
1245
1515
  key: storeCurrentSelectorKey,
1246
1516
  atomUpdates: []
1247
1517
  };
1248
1518
  newSelectorUpdate.atomUpdates.push(__spreadValues({
1249
- key: token.key,
1519
+ key: token2.key,
1250
1520
  type: `atom_update`
1251
1521
  }, update));
1252
1522
  if (timelineData.at !== timelineData.history.length) {
@@ -1258,12 +1528,12 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1258
1528
  newSelectorUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
1259
1529
  );
1260
1530
  timelineData.at = timelineData.history.length;
1261
- incompleteSelectorTime = storeCurrentSelectorTime;
1531
+ timelineData.selectorTime = storeCurrentSelectorTime;
1262
1532
  } else {
1263
1533
  const latestUpdate = timelineData.history.at(-1);
1264
1534
  if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
1265
1535
  latestUpdate.atomUpdates.push(__spreadValues({
1266
- key: token.key,
1536
+ key: token2.key,
1267
1537
  type: `atom_update`
1268
1538
  }, update));
1269
1539
  (_d = store.config.logger) == null ? void 0 : _d.info(
@@ -1275,18 +1545,18 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1275
1545
  }
1276
1546
  } else {
1277
1547
  if (timelineData.timeTraveling === false) {
1278
- incompleteSelectorTime = null;
1548
+ timelineData.selectorTime = null;
1279
1549
  if (timelineData.at !== timelineData.history.length) {
1280
1550
  timelineData.history.splice(timelineData.at);
1281
1551
  }
1282
1552
  timelineData.history.push({
1283
1553
  type: `atom_update`,
1284
- key: token.key,
1554
+ key: token2.key,
1285
1555
  oldValue: update.oldValue,
1286
1556
  newValue: update.newValue
1287
1557
  });
1288
1558
  (_e = store.config.logger) == null ? void 0 : _e.info(
1289
- `\u231B timeline "${options.key}" got a state_update to "${token.key}"`
1559
+ `\u231B timeline "${options.key}" got a state_update to "${token2.key}"`
1290
1560
  );
1291
1561
  timelineData.at = timelineData.history.length;
1292
1562
  }
@@ -1304,108 +1574,35 @@ function timeline__INTERNAL(options, store = IMPLICIT.STORE) {
1304
1574
  }
1305
1575
  if (tokenOrFamily.type === `atom_family`) {
1306
1576
  const family = tokenOrFamily;
1307
- family.subject.subscribe((token) => subscribeToAtom(token));
1577
+ family.subject.subscribe((token2) => subscribeToAtom(token2));
1308
1578
  } else {
1309
- const token = tokenOrFamily;
1310
- if (`family` in token && token.family) {
1579
+ const token2 = tokenOrFamily;
1580
+ if (`family` in token2 && token2.family) {
1311
1581
  const familyTimelineKey = core.timelineAtoms.getRelatedId(
1312
- token.family.key
1582
+ token2.family.key
1313
1583
  );
1314
1584
  if (familyTimelineKey) {
1315
1585
  (_b = store.config.logger) == null ? void 0 : _b.error(
1316
- `\u274C Failed to add atom "${token.key}" to timeline "${options.key}" because its family "${token.family.key}" belongs to timeline "${familyTimelineKey}"`
1586
+ `\u274C Failed to add atom "${token2.key}" to timeline "${options.key}" because its family "${token2.family.key}" belongs to timeline "${familyTimelineKey}"`
1317
1587
  );
1318
1588
  continue;
1319
1589
  }
1320
1590
  }
1321
- subscribeToAtom(token);
1591
+ subscribeToAtom(token2);
1322
1592
  }
1323
- core.timelineAtoms = core.timelineAtoms.set(tokenOrFamily.key, options.key);
1593
+ core.timelineAtoms = core.timelineAtoms.set({
1594
+ atomKey: tokenOrFamily.key,
1595
+ timelineKey: options.key
1596
+ });
1324
1597
  }
1325
- store.timelineStore = HAMT7.set(options.key, timelineData, store.timelineStore);
1326
- return {
1598
+ store.timelineStore = HAMT8.set(options.key, timelineData, store.timelineStore);
1599
+ const token = {
1327
1600
  key: options.key,
1328
1601
  type: `timeline`
1329
1602
  };
1603
+ store.subject.timelineCreation.next(token);
1604
+ return token;
1330
1605
  }
1331
- var redo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1332
- var _a, _b, _c, _d;
1333
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u23E9 redo "${token.key}"`);
1334
- const timelineData = store.timelineStore.get(token.key);
1335
- if (!timelineData) {
1336
- (_b = store.config.logger) == null ? void 0 : _b.error(
1337
- `Failed to redo on timeline "${token.key}". This timeline has not been initialized.`
1338
- );
1339
- return;
1340
- }
1341
- if (timelineData.at === timelineData.history.length) {
1342
- (_c = store.config.logger) == null ? void 0 : _c.warn(
1343
- `Failed to redo at the end of timeline "${token.key}". There is nothing to redo.`
1344
- );
1345
- return;
1346
- }
1347
- timelineData.timeTraveling = true;
1348
- const update = timelineData.history[timelineData.at];
1349
- switch (update.type) {
1350
- case `atom_update`: {
1351
- const { key, newValue } = update;
1352
- setState({ key, type: `atom` }, newValue);
1353
- break;
1354
- }
1355
- case `selector_update`:
1356
- case `transaction_update`: {
1357
- for (const atomUpdate of update.atomUpdates) {
1358
- const { key, newValue } = atomUpdate;
1359
- setState({ key, type: `atom` }, newValue);
1360
- }
1361
- break;
1362
- }
1363
- }
1364
- ++timelineData.at;
1365
- timelineData.timeTraveling = false;
1366
- (_d = store.config.logger) == null ? void 0 : _d.info(
1367
- `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1368
- );
1369
- };
1370
- var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1371
- var _a, _b, _c, _d;
1372
- (_a = store.config.logger) == null ? void 0 : _a.info(`\u23EA undo "${token.key}"`);
1373
- const timelineData = store.timelineStore.get(token.key);
1374
- if (!timelineData) {
1375
- (_b = store.config.logger) == null ? void 0 : _b.error(
1376
- `Failed to undo on timeline "${token.key}". This timeline has not been initialized.`
1377
- );
1378
- return;
1379
- }
1380
- if (timelineData.at === 0) {
1381
- (_c = store.config.logger) == null ? void 0 : _c.warn(
1382
- `Failed to undo at the beginning of timeline "${token.key}". There is nothing to undo.`
1383
- );
1384
- return;
1385
- }
1386
- timelineData.timeTraveling = true;
1387
- --timelineData.at;
1388
- const update = timelineData.history[timelineData.at];
1389
- switch (update.type) {
1390
- case `atom_update`: {
1391
- const { key, oldValue } = update;
1392
- setState({ key, type: `atom` }, oldValue);
1393
- break;
1394
- }
1395
- case `selector_update`:
1396
- case `transaction_update`: {
1397
- for (const atomUpdate of update.atomUpdates) {
1398
- const { key, oldValue } = atomUpdate;
1399
- setState({ key, type: `atom` }, oldValue);
1400
- }
1401
- break;
1402
- }
1403
- }
1404
- timelineData.timeTraveling = false;
1405
- (_d = store.config.logger) == null ? void 0 : _d.info(
1406
- `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
1407
- );
1408
- };
1409
1606
 
1410
1607
  // src/atom.ts
1411
1608
  function atom(options) {