atom.io 0.6.5 → 0.6.6

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 (60) hide show
  1. package/README.md +32 -78
  2. package/dist/index.d.mts +4 -35
  3. package/dist/index.d.ts +4 -35
  4. package/dist/index.js +45 -198
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +42 -195
  7. package/dist/index.mjs.map +1 -1
  8. package/introspection/dist/index.js +312 -0
  9. package/introspection/dist/index.js.map +1 -0
  10. package/introspection/dist/index.mjs +289 -0
  11. package/introspection/dist/index.mjs.map +1 -0
  12. package/introspection/package.json +15 -0
  13. package/package.json +16 -6
  14. package/react-devtools/dist/index.css +22 -5
  15. package/react-devtools/dist/index.css.map +1 -1
  16. package/react-devtools/dist/index.d.mts +347 -8
  17. package/react-devtools/dist/index.d.ts +347 -8
  18. package/react-devtools/dist/index.js +2722 -674
  19. package/react-devtools/dist/index.js.map +1 -1
  20. package/react-devtools/dist/index.mjs +2669 -630
  21. package/react-devtools/dist/index.mjs.map +1 -1
  22. package/src/internal/index.ts +0 -1
  23. package/src/internal/operation.ts +1 -0
  24. package/src/internal/store.ts +3 -2
  25. package/src/internal/time-travel-internal.ts +2 -0
  26. package/src/internal/timeline/add-atom-to-timeline.ts +11 -12
  27. package/src/internal/timeline-internal.ts +5 -1
  28. package/src/introspection/attach-atom-index.ts +73 -0
  29. package/src/introspection/attach-introspection-states.ts +42 -0
  30. package/src/introspection/attach-selector-index.ts +77 -0
  31. package/src/introspection/attach-timeline-family.ts +49 -0
  32. package/src/introspection/attach-timeline-index.ts +36 -0
  33. package/src/introspection/attach-transaction-index.ts +38 -0
  34. package/src/introspection/attach-transaction-logs.ts +40 -0
  35. package/src/introspection/index.ts +20 -0
  36. package/src/react-devtools/AtomIODevtools.tsx +97 -96
  37. package/src/react-devtools/Button.tsx +24 -0
  38. package/src/react-devtools/StateEditor.tsx +14 -16
  39. package/src/react-devtools/StateIndex.tsx +153 -0
  40. package/src/react-devtools/TimelineIndex.tsx +92 -0
  41. package/src/react-devtools/TransactionIndex.tsx +70 -0
  42. package/src/react-devtools/Updates.tsx +145 -0
  43. package/src/react-devtools/devtools.scss +196 -15
  44. package/src/react-devtools/index.ts +71 -0
  45. package/src/react-explorer/AtomIOExplorer.tsx +0 -1
  46. package/src/react-explorer/explorer-states.ts +1 -1
  47. package/src/react-explorer/space-states.ts +3 -1
  48. package/src/react-explorer/view-states.ts +0 -2
  49. package/realtime-testing/dist/index.d.mts +0 -49
  50. package/realtime-testing/dist/index.d.ts +0 -49
  51. package/realtime-testing/dist/index.js +0 -165
  52. package/realtime-testing/dist/index.js.map +0 -1
  53. package/realtime-testing/dist/index.mjs +0 -129
  54. package/realtime-testing/dist/index.mjs.map +0 -1
  55. package/src/internal/meta/attach-meta.ts +0 -17
  56. package/src/internal/meta/index.ts +0 -4
  57. package/src/internal/meta/meta-state.ts +0 -135
  58. package/src/internal/meta/meta-timelines.ts +0 -1
  59. package/src/internal/meta/meta-transactions.ts +0 -1
  60. package/src/react-devtools/TokenList.tsx +0 -61
package/dist/index.js CHANGED
@@ -88,7 +88,6 @@ var capitalize = (str) => str[0].toUpperCase() + str.slice(1);
88
88
  var internal_exports = {};
89
89
  __export(internal_exports, {
90
90
  IMPLICIT: () => IMPLICIT,
91
- META: () => meta_exports,
92
91
  Subject: () => Subject,
93
92
  TRANSACTION_PHASES: () => TRANSACTION_PHASES,
94
93
  abortTransaction: () => abortTransaction,
@@ -215,62 +214,8 @@ var become = (nextVersionOfThing) => (originalThing) => nextVersionOfThing insta
215
214
  ) : nextVersionOfThing;
216
215
  var pass = (...params) => (fn) => fn(...params);
217
216
 
218
- // ../../node_modules/.pnpm/fp-ts@2.16.0/node_modules/fp-ts/es6/function.js
219
- function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
220
- switch (arguments.length) {
221
- case 1:
222
- return a;
223
- case 2:
224
- return ab(a);
225
- case 3:
226
- return bc(ab(a));
227
- case 4:
228
- return cd(bc(ab(a)));
229
- case 5:
230
- return de(cd(bc(ab(a))));
231
- case 6:
232
- return ef(de(cd(bc(ab(a)))));
233
- case 7:
234
- return fg(ef(de(cd(bc(ab(a))))));
235
- case 8:
236
- return gh(fg(ef(de(cd(bc(ab(a)))))));
237
- case 9:
238
- return hi(gh(fg(ef(de(cd(bc(ab(a))))))));
239
- default: {
240
- var ret = arguments[0];
241
- for (var i = 1; i < arguments.length; i++) {
242
- ret = arguments[i](ret);
243
- }
244
- return ret;
245
- }
246
- }
247
- }
248
-
249
- // ../../node_modules/.pnpm/fp-ts@2.16.0/node_modules/fp-ts/es6/string.js
250
- var Eq = {
251
- equals: function(first, second) {
252
- return first === second;
253
- }
254
- };
255
- var Semigroup = {
256
- concat: function(first, second) {
257
- return first + second;
258
- }
259
- };
260
- var empty = "";
261
- var Monoid = {
262
- concat: Semigroup.concat,
263
- empty
264
- };
265
- var Ord = {
266
- equals: Eq.equals,
267
- compare: function(first, second) {
268
- return first < second ? -1 : first > second ? 1 : 0;
269
- }
270
- };
271
- var isString = function(u) {
272
- return typeof u === "string";
273
- };
217
+ // ../anvl/src/join/core-relation-data.ts
218
+ var import_string = require("fp-ts/string");
274
219
 
275
220
  // ../anvl/src/array/venn.ts
276
221
  var includesAll = (items) => (array) => {
@@ -291,6 +236,9 @@ var addTo = (a) => (x) => a.includes(x) ? a : [...a, x];
291
236
  var isEmptyArray = (input) => Array.isArray(input) && input.length === 0;
292
237
  var isOneOf = (...args) => (input) => args.includes(input);
293
238
 
239
+ // ../anvl/src/object/refinement.ts
240
+ var import_function2 = require("fp-ts/function");
241
+
294
242
  // ../anvl/src/object/access.ts
295
243
  var access = (k) => Object.assign((obj) => obj[k], {
296
244
  in: (obj) => obj[k]
@@ -301,7 +249,8 @@ var recordToEntries = (obj) => Object.entries(obj);
301
249
  var entriesToRecord = (entries) => Object.fromEntries(entries);
302
250
 
303
251
  // ../anvl/src/object/mapObject.ts
304
- var mapObject = (obj, fn) => pipe(
252
+ var import_function = require("fp-ts/function");
253
+ var mapObject = (obj, fn) => (0, import_function.pipe)(
305
254
  obj,
306
255
  recordToEntries,
307
256
  map(([key, val]) => [key, fn(val, key)]),
@@ -323,14 +272,14 @@ var hasProperties = (isValue, options = { allowExtraProperties: false }) => {
323
272
  isValue
324
273
  ).map(([k, v]) => String(k) + `:` + v.name).join(`,`)}}`;
325
274
  const _ = {
326
- [name]: (input) => isPlainObject(input) && pipe(
275
+ [name]: (input) => isPlainObject(input) && (0, import_function2.pipe)(
327
276
  isValue,
328
277
  Object.entries,
329
278
  every(([key, val]) => key in input || val(void 0))
330
- ) && pipe(
279
+ ) && (0, import_function2.pipe)(
331
280
  input,
332
281
  mob(
333
- (val, key) => pipe(
282
+ (val, key) => (0, import_function2.pipe)(
334
283
  isValue,
335
284
  access(key),
336
285
  ifNullish(() => options.allowExtraProperties),
@@ -410,8 +359,8 @@ var isRelationData = ({
410
359
  isContent
411
360
  } = {}) => (input) => {
412
361
  return hasExactProperties({
413
- contents: isContent ? isRecord(isString, isContent) : hasExactProperties({}),
414
- relations: isRecord(isString, isArray(isString)),
362
+ contents: isContent ? isRecord(import_string.isString, isContent) : hasExactProperties({}),
363
+ relations: isRecord(import_string.isString, isArray(import_string.isString)),
415
364
  relationType: isRelationType,
416
365
  a: isLiteral(a),
417
366
  b: isLiteral(b)
@@ -448,6 +397,9 @@ var makeJsonInterface = (join, ...params) => {
448
397
  };
449
398
  };
450
399
 
400
+ // ../anvl/src/join/relation-contents.ts
401
+ var import_function6 = require("fp-ts/function");
402
+
451
403
  // ../anvl/src/join/relation-record.ts
452
404
  var getRelationEntries = (relationMap, idA) => getRelatedIds(relationMap, idA).map((idB) => [
453
405
  idB,
@@ -455,7 +407,12 @@ var getRelationEntries = (relationMap, idA) => getRelatedIds(relationMap, idA).m
455
407
  ]);
456
408
  var getRelationRecord = (relationMap, id) => Object.fromEntries(getRelationEntries(relationMap, id));
457
409
 
410
+ // ../anvl/src/join/remove-relation.ts
411
+ var import_function5 = require("fp-ts/function");
412
+ var import_string2 = require("fp-ts/string");
413
+
458
414
  // ../anvl/src/object/index.ts
415
+ var import_function4 = require("fp-ts/function");
459
416
  var treeShake = (shouldDiscard = isUndefined) => (obj) => {
460
417
  const newObj = {};
461
418
  const entries = Object.entries(obj);
@@ -472,7 +429,7 @@ var split = (separator) => (str) => str.split(separator);
472
429
  var removeSpecific = (current, idA, idB) => {
473
430
  const isIdForRemoval = isOneOf(idA, idB);
474
431
  return __spreadProps(__spreadValues({}, current), {
475
- relations: pipe(
432
+ relations: (0, import_function5.pipe)(
476
433
  current.relations,
477
434
  recordToEntries,
478
435
  map(([id, relations]) => [
@@ -482,17 +439,17 @@ var removeSpecific = (current, idA, idB) => {
482
439
  entriesToRecord,
483
440
  treeShake(isEmptyArray)
484
441
  ),
485
- contents: pipe(
442
+ contents: (0, import_function5.pipe)(
486
443
  current.contents,
487
444
  treeShake(
488
- (_, key) => isString(key) && pipe(key, split(`/`), comprises([idA, idB]))
445
+ (_, key) => (0, import_string2.isString)(key) && (0, import_function5.pipe)(key, split(`/`), comprises([idA, idB]))
489
446
  )
490
447
  )
491
448
  });
492
449
  };
493
450
  var removeAll = (current, idToRemove) => {
494
451
  const next = __spreadProps(__spreadValues({}, current), {
495
- relations: pipe(
452
+ relations: (0, import_function5.pipe)(
496
453
  current.relations,
497
454
  recordToEntries,
498
455
  map(([id, relations]) => [
@@ -502,10 +459,10 @@ var removeAll = (current, idToRemove) => {
502
459
  entriesToRecord,
503
460
  treeShake((val, key) => key === idToRemove || isEmptyArray(val))
504
461
  ),
505
- contents: pipe(
462
+ contents: (0, import_function5.pipe)(
506
463
  current.contents,
507
464
  treeShake(
508
- (_, key) => isString(key) && key.split(`/`).includes(idToRemove)
465
+ (_, key) => (0, import_string2.isString)(key) && key.split(`/`).includes(idToRemove)
509
466
  )
510
467
  )
511
468
  });
@@ -587,7 +544,7 @@ var getRelations = (relationMap, id) => getRelationEntries(relationMap, id).map(
587
544
  var setRelations = (current, subject, relations) => {
588
545
  const idA = subject[current.a];
589
546
  const idB = subject[current.b];
590
- return pipe(
547
+ return (0, import_function6.pipe)(
591
548
  current,
592
549
  (relationData) => {
593
550
  const relatedIds = getRelatedIds(current, idA);
@@ -714,12 +671,13 @@ var createStore = (name, store = null) => {
714
671
  transactions: import_hamt_plus2.default.make(),
715
672
  timelines: import_hamt_plus2.default.make(),
716
673
  timelineAtoms: new Join({ relationType: `1:n` }).from(`timelineKey`).to(`atomKey`),
717
- subject: __spreadValues({
674
+ subject: {
718
675
  atomCreation: new Subject(),
719
676
  selectorCreation: new Subject(),
720
677
  transactionCreation: new Subject(),
721
- timelineCreation: new Subject()
722
- }, store == null ? void 0 : store.subject),
678
+ timelineCreation: new Subject(),
679
+ operationStatus: new Subject()
680
+ },
723
681
  operation: __spreadValues({
724
682
  open: false
725
683
  }, store == null ? void 0 : store.operation),
@@ -792,6 +750,7 @@ var closeOperation = (store) => {
792
750
  const core = target(store);
793
751
  core.operation = { open: false };
794
752
  (_a = store.config.logger) == null ? void 0 : _a.info(`\u{1F534} operation done`);
753
+ store.subject.operationStatus.next(core.operation);
795
754
  };
796
755
  var isDone = (key, store = IMPLICIT.STORE) => {
797
756
  var _a;
@@ -929,6 +888,7 @@ function atom__INTERNAL(options, family, store = IMPLICIT.STORE) {
929
888
  }
930
889
 
931
890
  // ../anvl/src/json/index.ts
891
+ var import_function8 = require("fp-ts/function");
932
892
  var stringifyJson = (json) => JSON.stringify(json);
933
893
 
934
894
  // src/internal/families-internal.ts
@@ -1023,120 +983,6 @@ function selectorFamily__INTERNAL(options, store = IMPLICIT.STORE) {
1023
983
  );
1024
984
  }
1025
985
 
1026
- // src/internal/meta/index.ts
1027
- var meta_exports = {};
1028
- __export(meta_exports, {
1029
- attachMetaAtoms: () => attachMetaAtoms,
1030
- attachMetaSelectors: () => attachMetaSelectors,
1031
- attachMetaState: () => attachMetaState
1032
- });
1033
-
1034
- // src/internal/meta/meta-state.ts
1035
- var attachMetaAtoms = (store = IMPLICIT.STORE) => {
1036
- const atomTokenIndexState__INTERNAL = atom({
1037
- key: `\u{1F441}\u200D\u{1F5E8}_atom_token_index__INTERNAL`,
1038
- default: () => [...store.atoms].reduce((acc, [key]) => {
1039
- acc[key] = { key, type: `atom` };
1040
- return acc;
1041
- }, {}),
1042
- effects: [
1043
- ({ setSelf }) => {
1044
- store.subject.atomCreation.subscribe((atomToken) => {
1045
- if (store.operation.open) {
1046
- return;
1047
- }
1048
- setSelf((state) => {
1049
- const { key, family } = atomToken;
1050
- if (family) {
1051
- const { key: familyKey, subKey } = family;
1052
- const current = state[familyKey];
1053
- if (current === void 0 || `familyMembers` in current) {
1054
- const familyKeyState = current || {
1055
- key: familyKey,
1056
- familyMembers: {}
1057
- };
1058
- return __spreadProps(__spreadValues({}, state), {
1059
- [familyKey]: __spreadProps(__spreadValues({}, familyKeyState), {
1060
- familyMembers: __spreadProps(__spreadValues({}, familyKeyState.familyMembers), {
1061
- [subKey]: atomToken
1062
- })
1063
- })
1064
- });
1065
- }
1066
- }
1067
- return __spreadProps(__spreadValues({}, state), {
1068
- [key]: atomToken
1069
- });
1070
- });
1071
- });
1072
- }
1073
- ]
1074
- });
1075
- return selector({
1076
- key: `\u{1F441}\u200D\u{1F5E8}_atom_token_index`,
1077
- get: ({ get }) => get(atomTokenIndexState__INTERNAL)
1078
- });
1079
- };
1080
- var attachMetaSelectors = (store = IMPLICIT.STORE) => {
1081
- const readonlySelectorTokenIndexState__INTERNAL = atom({
1082
- key: `\u{1F441}\u200D\u{1F5E8}_selector_token_index__INTERNAL`,
1083
- default: () => Object.assign(
1084
- [...store.readonlySelectors].reduce((acc, [key]) => {
1085
- acc[key] = { key, type: `readonly_selector` };
1086
- return acc;
1087
- }, {}),
1088
- [...store.selectors].reduce((acc, [key]) => {
1089
- acc[key] = { key, type: `selector` };
1090
- return acc;
1091
- }, {})
1092
- ),
1093
- effects: [
1094
- ({ setSelf }) => {
1095
- store.subject.selectorCreation.subscribe((selectorToken) => {
1096
- if (store.operation.open) {
1097
- return;
1098
- }
1099
- setSelf((state) => {
1100
- const { key, family } = selectorToken;
1101
- if (family) {
1102
- const { key: familyKey, subKey } = family;
1103
- const current = state[familyKey];
1104
- if (current === void 0 || `familyMembers` in current) {
1105
- const familyKeyState = current || {
1106
- key: familyKey,
1107
- familyMembers: {}
1108
- };
1109
- return __spreadProps(__spreadValues({}, state), {
1110
- [familyKey]: __spreadProps(__spreadValues({}, familyKeyState), {
1111
- familyMembers: __spreadProps(__spreadValues({}, familyKeyState.familyMembers), {
1112
- [subKey]: selectorToken
1113
- })
1114
- })
1115
- });
1116
- }
1117
- }
1118
- return __spreadProps(__spreadValues({}, state), {
1119
- [key]: selectorToken
1120
- });
1121
- });
1122
- });
1123
- }
1124
- ]
1125
- });
1126
- return selector({
1127
- key: `\u{1F441}\u200D\u{1F5E8}_selector_token_index`,
1128
- get: ({ get }) => get(readonlySelectorTokenIndexState__INTERNAL)
1129
- });
1130
- };
1131
-
1132
- // src/internal/meta/attach-meta.ts
1133
- var attachMetaState = (store = IMPLICIT.STORE) => {
1134
- return {
1135
- atomTokenIndexState: attachMetaAtoms(store),
1136
- selectorTokenIndexState: attachMetaSelectors(store)
1137
- };
1138
- };
1139
-
1140
986
  // src/internal/selector-internal.ts
1141
987
  var import_hamt_plus9 = __toESM(require("hamt_plus"));
1142
988
 
@@ -1519,6 +1365,7 @@ var redo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1519
1365
  }
1520
1366
  }
1521
1367
  ++timelineData.at;
1368
+ timelineData.subject.next(`redo`);
1522
1369
  timelineData.timeTraveling = false;
1523
1370
  (_d = store.config.logger) == null ? void 0 : _d.info(
1524
1371
  `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
@@ -1558,6 +1405,7 @@ var undo__INTERNAL = (token, store = IMPLICIT.STORE) => {
1558
1405
  break;
1559
1406
  }
1560
1407
  }
1408
+ timelineData.subject.next(`undo`);
1561
1409
  timelineData.timeTraveling = false;
1562
1410
  (_d = store.config.logger) == null ? void 0 : _d.info(
1563
1411
  `\u23F9\uFE0F "${token.key}" is now at ${timelineData.at} / ${timelineData.history.length}`
@@ -1596,9 +1444,6 @@ var addAtomToTimeline = (atomToken, atoms, tl, store = IMPLICIT.STORE) => {
1596
1444
  `Timeline "${tl.key}" has a selectorTime, but no history. This is most likely a bug in AtomIO.`
1597
1445
  );
1598
1446
  }
1599
- if (mostRecentUpdate.type === `selector_update`) {
1600
- tl.subject.next(mostRecentUpdate);
1601
- }
1602
1447
  }
1603
1448
  if (currentTransactionKey && store.transactionStatus.phase === `applying`) {
1604
1449
  const currentTransaction = withdraw(
@@ -1619,6 +1464,7 @@ var addAtomToTimeline = (atomToken, atoms, tl, store = IMPLICIT.STORE) => {
1619
1464
  tl.transactionKey = currentTransactionKey;
1620
1465
  const subscription = currentTransaction.subject.subscribe((update2) => {
1621
1466
  var _a2;
1467
+ subscription.unsubscribe();
1622
1468
  if (tl.timeTraveling === false && currentTransactionTime) {
1623
1469
  if (tl.at !== tl.history.length) {
1624
1470
  tl.history.splice(tl.at);
@@ -1632,10 +1478,9 @@ var addAtomToTimeline = (atomToken, atoms, tl, store = IMPLICIT.STORE) => {
1632
1478
  )
1633
1479
  });
1634
1480
  tl.history.push(timelineTransactionUpdate);
1481
+ tl.at = tl.history.length;
1635
1482
  tl.subject.next(timelineTransactionUpdate);
1636
1483
  }
1637
- tl.at = tl.history.length;
1638
- subscription.unsubscribe();
1639
1484
  tl.transactionKey = null;
1640
1485
  (_a2 = store.config.logger) == null ? void 0 : _a2.info(
1641
1486
  `\u231B timeline "${tl.key}" got a transaction_update "${update2.key}"`
@@ -1643,29 +1488,29 @@ var addAtomToTimeline = (atomToken, atoms, tl, store = IMPLICIT.STORE) => {
1643
1488
  });
1644
1489
  }
1645
1490
  } else if (currentSelectorKey && currentSelectorTime) {
1491
+ let latestUpdate = tl.history.at(-1);
1646
1492
  if (currentSelectorTime !== tl.selectorTime) {
1647
- const newSelectorUpdate = {
1493
+ latestUpdate = {
1648
1494
  type: `selector_update`,
1649
1495
  timestamp: currentSelectorTime,
1650
1496
  key: currentSelectorKey,
1651
1497
  atomUpdates: []
1652
1498
  };
1653
- newSelectorUpdate.atomUpdates.push(__spreadValues({
1499
+ latestUpdate.atomUpdates.push(__spreadValues({
1654
1500
  key: atom2.key,
1655
1501
  type: `atom_update`
1656
1502
  }, update));
1657
1503
  if (tl.at !== tl.history.length) {
1658
1504
  tl.history.splice(tl.at);
1659
1505
  }
1660
- tl.history.push(newSelectorUpdate);
1506
+ tl.history.push(latestUpdate);
1661
1507
  (_c = store.config.logger) == null ? void 0 : _c.info(
1662
1508
  `\u231B timeline "${tl.key}" got a selector_update "${currentSelectorKey}" with`,
1663
- newSelectorUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
1509
+ latestUpdate.atomUpdates.map((atomUpdate) => atomUpdate.key)
1664
1510
  );
1665
1511
  tl.at = tl.history.length;
1666
1512
  tl.selectorTime = currentSelectorTime;
1667
1513
  } else {
1668
- const latestUpdate = tl.history.at(-1);
1669
1514
  if ((latestUpdate == null ? void 0 : latestUpdate.type) === `selector_update`) {
1670
1515
  latestUpdate.atomUpdates.push(__spreadValues({
1671
1516
  key: atom2.key,
@@ -1677,6 +1522,8 @@ var addAtomToTimeline = (atomToken, atoms, tl, store = IMPLICIT.STORE) => {
1677
1522
  );
1678
1523
  }
1679
1524
  }
1525
+ if (latestUpdate)
1526
+ tl.subject.next(latestUpdate);
1680
1527
  } else {
1681
1528
  const timestamp = Date.now();
1682
1529
  tl.selectorTime = null;
@@ -1693,7 +1540,7 @@ var addAtomToTimeline = (atomToken, atoms, tl, store = IMPLICIT.STORE) => {
1693
1540
  tl.history.push(atomUpdate);
1694
1541
  tl.subject.next(atomUpdate);
1695
1542
  (_e = store.config.logger) == null ? void 0 : _e.info(
1696
- `\u231B timeline "${tl.key}" got a state_update to "${atom2.key}"`
1543
+ `\u231B timeline "${tl.key}" got an atom_update to "${atom2.key}"`
1697
1544
  );
1698
1545
  tl.at = tl.history.length;
1699
1546
  }