jotai-state-tree 1.4.2 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-Q6QPBXHH.mjs → chunk-5OCZ6YLH.mjs} +279 -225
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +278 -225
- package/dist/index.mjs +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +278 -258
- package/dist/react.mjs +97 -31
- package/dist/{undo-DL1pyOkT.d.mts → undo-quCDYz_6.d.mts} +7 -5
- package/dist/{undo-DL1pyOkT.d.ts → undo-quCDYz_6.d.ts} +7 -5
- package/package.json +1 -1
- package/src/__tests__/react.react.test.tsx +112 -0
- package/src/react.ts +96 -33
- package/src/undo.ts +394 -345
|
@@ -953,29 +953,32 @@ function unfreeze(target) {
|
|
|
953
953
|
}
|
|
954
954
|
|
|
955
955
|
// src/undo.ts
|
|
956
|
-
|
|
957
|
-
var
|
|
958
|
-
var
|
|
956
|
+
import { atom as atom2 } from "jotai";
|
|
957
|
+
var historyTrackersRegistry = /* @__PURE__ */ new WeakMap();
|
|
958
|
+
var HistoryTracker = class {
|
|
959
959
|
constructor(target, options = {}) {
|
|
960
|
-
|
|
961
|
-
this.
|
|
962
|
-
this.
|
|
963
|
-
this.isRedoing = false;
|
|
960
|
+
// Transient state
|
|
961
|
+
this.autoRecord = false;
|
|
962
|
+
this.isApplyingHistory = false;
|
|
964
963
|
this.skipRecording = false;
|
|
965
964
|
this.grouping = false;
|
|
966
965
|
this.actionGrouping = false;
|
|
967
966
|
this.currentGroup = [];
|
|
968
967
|
this.currentGroupInverse = [];
|
|
968
|
+
this.lastChangeTime = 0;
|
|
969
969
|
this.disposer = null;
|
|
970
970
|
this.actionDisposer = null;
|
|
971
|
-
this.lastChangeTime = 0;
|
|
972
971
|
this.target = target;
|
|
973
|
-
this.
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
972
|
+
this.maxHistoryLength = options.maxHistoryLength ?? options.maxSnapshots ?? 100;
|
|
973
|
+
this.groupByTime = options.groupByTime ?? false;
|
|
974
|
+
this.groupingWindow = options.groupingWindow ?? 200;
|
|
975
|
+
this.autoRecord = options.autoRecord ?? false;
|
|
976
|
+
const initialSnapshot = getSnapshot(target);
|
|
977
|
+
this.historyAtom = atom2({
|
|
978
|
+
entries: [],
|
|
979
|
+
currentIndex: -1,
|
|
980
|
+
initialSnapshot
|
|
981
|
+
});
|
|
979
982
|
this.disposer = onPatch(target, (patch, reversePatch) => {
|
|
980
983
|
this.recordPatch(patch, reversePatch);
|
|
981
984
|
});
|
|
@@ -988,32 +991,18 @@ var UndoManager = class {
|
|
|
988
991
|
}
|
|
989
992
|
});
|
|
990
993
|
}
|
|
991
|
-
get canUndo() {
|
|
992
|
-
return this.currentIndex >= 0;
|
|
993
|
-
}
|
|
994
|
-
get canRedo() {
|
|
995
|
-
return this.currentIndex < this.historyEntries.length - 1;
|
|
996
|
-
}
|
|
997
|
-
get undoLevels() {
|
|
998
|
-
return this.currentIndex + 1;
|
|
999
|
-
}
|
|
1000
|
-
get redoLevels() {
|
|
1001
|
-
return this.historyEntries.length - this.currentIndex - 1;
|
|
1002
|
-
}
|
|
1003
|
-
get history() {
|
|
1004
|
-
return [...this.historyEntries];
|
|
1005
|
-
}
|
|
1006
|
-
get historyIndex() {
|
|
1007
|
-
return this.currentIndex;
|
|
1008
|
-
}
|
|
1009
994
|
recordPatch(patch, reversePatch) {
|
|
1010
|
-
if (this.
|
|
995
|
+
if (!this.autoRecord) {
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
if (this.isApplyingHistory || this.skipRecording) {
|
|
1011
999
|
return;
|
|
1012
1000
|
}
|
|
1013
1001
|
const node = getStateTreeNode(this.target);
|
|
1014
1002
|
if (node.getRoot().$isApplyingHistory) {
|
|
1015
1003
|
return;
|
|
1016
1004
|
}
|
|
1005
|
+
const store = getGlobalStore();
|
|
1017
1006
|
const now = Date.now();
|
|
1018
1007
|
if (isActionRunning() && !this.grouping) {
|
|
1019
1008
|
this.grouping = true;
|
|
@@ -1031,86 +1020,172 @@ var UndoManager = class {
|
|
|
1031
1020
|
this.currentGroupInverse.push({ ...patch });
|
|
1032
1021
|
return;
|
|
1033
1022
|
}
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1023
|
+
store.set(this.historyAtom, (prev) => {
|
|
1024
|
+
let entries = prev.currentIndex < prev.entries.length - 1 ? prev.entries.slice(0, prev.currentIndex + 1) : [...prev.entries];
|
|
1025
|
+
if (this.groupByTime && entries.length > 0 && now - this.lastChangeTime < this.groupingWindow && prev.currentIndex === prev.entries.length - 1) {
|
|
1026
|
+
const lastEntry = { ...entries[entries.length - 1] };
|
|
1027
|
+
lastEntry.patches = [...lastEntry.patches, reversePatch];
|
|
1028
|
+
lastEntry.inversePatches = [...lastEntry.inversePatches, { ...patch }];
|
|
1029
|
+
lastEntry.timestamp = now;
|
|
1030
|
+
lastEntry.snapshot = getSnapshot(this.target);
|
|
1031
|
+
entries[entries.length - 1] = lastEntry;
|
|
1032
|
+
this.lastChangeTime = now;
|
|
1033
|
+
return {
|
|
1034
|
+
...prev,
|
|
1035
|
+
entries
|
|
1036
|
+
};
|
|
1037
|
+
} else {
|
|
1038
|
+
const newEntry = {
|
|
1039
|
+
patches: [reversePatch],
|
|
1040
|
+
inversePatches: [{ ...patch }],
|
|
1041
|
+
timestamp: now,
|
|
1042
|
+
snapshot: getSnapshot(this.target)
|
|
1043
|
+
};
|
|
1044
|
+
entries.push(newEntry);
|
|
1045
|
+
let newIndex = entries.length - 1;
|
|
1046
|
+
if (entries.length > this.maxHistoryLength) {
|
|
1047
|
+
const excess = entries.length - this.maxHistoryLength;
|
|
1048
|
+
entries = entries.slice(excess);
|
|
1049
|
+
newIndex -= excess;
|
|
1050
|
+
}
|
|
1051
|
+
this.lastChangeTime = now;
|
|
1052
|
+
return {
|
|
1053
|
+
...prev,
|
|
1054
|
+
entries,
|
|
1055
|
+
currentIndex: newIndex
|
|
1056
|
+
};
|
|
1053
1057
|
}
|
|
1054
|
-
}
|
|
1055
|
-
this.lastChangeTime = now;
|
|
1058
|
+
});
|
|
1056
1059
|
}
|
|
1057
1060
|
undo() {
|
|
1058
|
-
|
|
1061
|
+
const store = getGlobalStore();
|
|
1062
|
+
const state = store.get(this.historyAtom);
|
|
1063
|
+
if (state.currentIndex < 0) {
|
|
1059
1064
|
return;
|
|
1060
1065
|
}
|
|
1061
1066
|
const node = getStateTreeNode(this.target);
|
|
1062
1067
|
const rootNode = node.getRoot();
|
|
1063
1068
|
const wasApplying = rootNode.$isApplyingHistory;
|
|
1064
1069
|
rootNode.$isApplyingHistory = true;
|
|
1065
|
-
this.
|
|
1070
|
+
this.isApplyingHistory = true;
|
|
1066
1071
|
try {
|
|
1067
|
-
const entry =
|
|
1072
|
+
const entry = state.entries[state.currentIndex];
|
|
1068
1073
|
for (let i = entry.patches.length - 1; i >= 0; i--) {
|
|
1069
1074
|
applyPatch(this.target, entry.patches[i]);
|
|
1070
1075
|
}
|
|
1071
|
-
this.
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
const M = this.historyEntries.length;
|
|
1076
|
-
const ttIndex = this.currentIndex + 1 + (N - 1 - M);
|
|
1077
|
-
tt.index = Math.max(0, Math.min(N - 1, ttIndex));
|
|
1078
|
-
}
|
|
1076
|
+
store.set(this.historyAtom, (prev) => ({
|
|
1077
|
+
...prev,
|
|
1078
|
+
currentIndex: prev.currentIndex - 1
|
|
1079
|
+
}));
|
|
1079
1080
|
} finally {
|
|
1080
|
-
this.
|
|
1081
|
+
this.isApplyingHistory = false;
|
|
1081
1082
|
rootNode.$isApplyingHistory = wasApplying;
|
|
1082
1083
|
}
|
|
1083
1084
|
}
|
|
1084
1085
|
redo() {
|
|
1085
|
-
|
|
1086
|
+
const store = getGlobalStore();
|
|
1087
|
+
const state = store.get(this.historyAtom);
|
|
1088
|
+
if (state.currentIndex >= state.entries.length - 1) {
|
|
1086
1089
|
return;
|
|
1087
1090
|
}
|
|
1088
1091
|
const node = getStateTreeNode(this.target);
|
|
1089
1092
|
const rootNode = node.getRoot();
|
|
1090
1093
|
const wasApplying = rootNode.$isApplyingHistory;
|
|
1091
1094
|
rootNode.$isApplyingHistory = true;
|
|
1092
|
-
this.
|
|
1095
|
+
this.isApplyingHistory = true;
|
|
1093
1096
|
try {
|
|
1094
|
-
|
|
1095
|
-
const entry =
|
|
1097
|
+
const nextIndex = state.currentIndex + 1;
|
|
1098
|
+
const entry = state.entries[nextIndex];
|
|
1096
1099
|
for (const patch of entry.inversePatches) {
|
|
1097
1100
|
applyPatch(this.target, patch);
|
|
1098
1101
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1102
|
+
store.set(this.historyAtom, (prev) => ({
|
|
1103
|
+
...prev,
|
|
1104
|
+
currentIndex: nextIndex
|
|
1105
|
+
}));
|
|
1106
|
+
} finally {
|
|
1107
|
+
this.isApplyingHistory = false;
|
|
1108
|
+
rootNode.$isApplyingHistory = wasApplying;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
goTo(index) {
|
|
1112
|
+
const store = getGlobalStore();
|
|
1113
|
+
const state = store.get(this.historyAtom);
|
|
1114
|
+
const maxIdx = state.entries.length;
|
|
1115
|
+
if (index < 0 || index > maxIdx) {
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
const node = getStateTreeNode(this.target);
|
|
1119
|
+
const rootNode = node.getRoot();
|
|
1120
|
+
const wasApplying = rootNode.$isApplyingHistory;
|
|
1121
|
+
rootNode.$isApplyingHistory = true;
|
|
1122
|
+
this.isApplyingHistory = true;
|
|
1123
|
+
try {
|
|
1124
|
+
const targetSnapshot = index === 0 ? state.initialSnapshot : state.entries[index - 1].snapshot;
|
|
1125
|
+
applySnapshot(this.target, targetSnapshot);
|
|
1126
|
+
store.set(this.historyAtom, (prev) => ({
|
|
1127
|
+
...prev,
|
|
1128
|
+
currentIndex: index - 1
|
|
1129
|
+
}));
|
|
1106
1130
|
} finally {
|
|
1107
|
-
this.
|
|
1131
|
+
this.isApplyingHistory = false;
|
|
1108
1132
|
rootNode.$isApplyingHistory = wasApplying;
|
|
1109
1133
|
}
|
|
1110
1134
|
}
|
|
1135
|
+
goBack() {
|
|
1136
|
+
const store = getGlobalStore();
|
|
1137
|
+
const state = store.get(this.historyAtom);
|
|
1138
|
+
const currentSnapshotIndex = state.currentIndex + 1;
|
|
1139
|
+
if (currentSnapshotIndex > 0) {
|
|
1140
|
+
this.goTo(currentSnapshotIndex - 1);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
goForward() {
|
|
1144
|
+
const store = getGlobalStore();
|
|
1145
|
+
const state = store.get(this.historyAtom);
|
|
1146
|
+
const currentSnapshotIndex = state.currentIndex + 1;
|
|
1147
|
+
if (currentSnapshotIndex < state.entries.length) {
|
|
1148
|
+
this.goTo(currentSnapshotIndex + 1);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
record() {
|
|
1152
|
+
const store = getGlobalStore();
|
|
1153
|
+
const state = store.get(this.historyAtom);
|
|
1154
|
+
let entries = state.currentIndex < state.entries.length - 1 ? state.entries.slice(0, state.currentIndex + 1) : [...state.entries];
|
|
1155
|
+
const newEntry = {
|
|
1156
|
+
patches: [],
|
|
1157
|
+
inversePatches: [],
|
|
1158
|
+
timestamp: Date.now(),
|
|
1159
|
+
snapshot: getSnapshot(this.target)
|
|
1160
|
+
};
|
|
1161
|
+
entries.push(newEntry);
|
|
1162
|
+
let newIndex = entries.length - 1;
|
|
1163
|
+
if (entries.length > this.maxHistoryLength) {
|
|
1164
|
+
const excess = entries.length - this.maxHistoryLength;
|
|
1165
|
+
entries = entries.slice(excess);
|
|
1166
|
+
newIndex -= excess;
|
|
1167
|
+
}
|
|
1168
|
+
store.set(this.historyAtom, {
|
|
1169
|
+
...state,
|
|
1170
|
+
entries,
|
|
1171
|
+
currentIndex: newIndex
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
getSnapshot(index) {
|
|
1175
|
+
const store = getGlobalStore();
|
|
1176
|
+
const state = store.get(this.historyAtom);
|
|
1177
|
+
if (index < 0 || index > state.entries.length) {
|
|
1178
|
+
throw new Error(`[jotai-state-tree] Invalid snapshot index: ${index}`);
|
|
1179
|
+
}
|
|
1180
|
+
return index === 0 ? state.initialSnapshot : state.entries[index - 1].snapshot;
|
|
1181
|
+
}
|
|
1111
1182
|
clear() {
|
|
1112
|
-
|
|
1113
|
-
this.
|
|
1183
|
+
const store = getGlobalStore();
|
|
1184
|
+
store.set(this.historyAtom, {
|
|
1185
|
+
entries: [],
|
|
1186
|
+
currentIndex: -1,
|
|
1187
|
+
initialSnapshot: getSnapshot(this.target)
|
|
1188
|
+
});
|
|
1114
1189
|
this.currentGroup = [];
|
|
1115
1190
|
this.currentGroupInverse = [];
|
|
1116
1191
|
this.grouping = false;
|
|
@@ -1129,20 +1204,28 @@ var UndoManager = class {
|
|
|
1129
1204
|
this.grouping = false;
|
|
1130
1205
|
this.actionGrouping = false;
|
|
1131
1206
|
if (this.currentGroup.length > 0) {
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1207
|
+
const store = getGlobalStore();
|
|
1208
|
+
store.set(this.historyAtom, (prev) => {
|
|
1209
|
+
let entries = prev.currentIndex < prev.entries.length - 1 ? prev.entries.slice(0, prev.currentIndex + 1) : [...prev.entries];
|
|
1210
|
+
const newEntry = {
|
|
1211
|
+
patches: [...this.currentGroup],
|
|
1212
|
+
inversePatches: [...this.currentGroupInverse],
|
|
1213
|
+
timestamp: Date.now(),
|
|
1214
|
+
snapshot: getSnapshot(this.target)
|
|
1215
|
+
};
|
|
1216
|
+
entries.push(newEntry);
|
|
1217
|
+
let newIndex = entries.length - 1;
|
|
1218
|
+
if (entries.length > this.maxHistoryLength) {
|
|
1219
|
+
const excess = entries.length - this.maxHistoryLength;
|
|
1220
|
+
entries = entries.slice(excess);
|
|
1221
|
+
newIndex -= excess;
|
|
1222
|
+
}
|
|
1223
|
+
return {
|
|
1224
|
+
...prev,
|
|
1225
|
+
entries,
|
|
1226
|
+
currentIndex: newIndex
|
|
1227
|
+
};
|
|
1139
1228
|
});
|
|
1140
|
-
this.currentIndex++;
|
|
1141
|
-
if (this.historyEntries.length > this.options.maxHistoryLength) {
|
|
1142
|
-
const excess = this.historyEntries.length - this.options.maxHistoryLength;
|
|
1143
|
-
this.historyEntries.splice(0, excess);
|
|
1144
|
-
this.currentIndex -= excess;
|
|
1145
|
-
}
|
|
1146
1229
|
}
|
|
1147
1230
|
this.currentGroup = [];
|
|
1148
1231
|
this.currentGroupInverse = [];
|
|
@@ -1156,7 +1239,7 @@ var UndoManager = class {
|
|
|
1156
1239
|
}
|
|
1157
1240
|
}
|
|
1158
1241
|
dispose() {
|
|
1159
|
-
|
|
1242
|
+
historyTrackersRegistry.delete(this.target);
|
|
1160
1243
|
if (this.disposer) {
|
|
1161
1244
|
this.disposer();
|
|
1162
1245
|
this.disposer = null;
|
|
@@ -1165,143 +1248,113 @@ var UndoManager = class {
|
|
|
1165
1248
|
this.actionDisposer();
|
|
1166
1249
|
this.actionDisposer = null;
|
|
1167
1250
|
}
|
|
1168
|
-
this.clear();
|
|
1169
1251
|
}
|
|
1170
1252
|
};
|
|
1171
|
-
function
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
this.snapshots = [];
|
|
1177
|
-
this.index = -1;
|
|
1178
|
-
this.isApplying = false;
|
|
1179
|
-
this.disposer = null;
|
|
1180
|
-
this.actionDisposer = null;
|
|
1181
|
-
this.pendingRecord = false;
|
|
1182
|
-
this.actionGrouping = false;
|
|
1183
|
-
this.target = target;
|
|
1184
|
-
this.maxSnapshots = options.maxSnapshots ?? 50;
|
|
1185
|
-
this.autoRecord = options.autoRecord ?? false;
|
|
1186
|
-
timeTravelManagersRegistry.set(target, this);
|
|
1187
|
-
this.record();
|
|
1188
|
-
if (this.autoRecord) {
|
|
1189
|
-
this.disposer = onPatch(target, () => {
|
|
1190
|
-
if (this.isApplying) return;
|
|
1191
|
-
const node = getStateTreeNode(this.target);
|
|
1192
|
-
if (node.getRoot().$isApplyingHistory) {
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
|
-
if (isActionRunning()) {
|
|
1196
|
-
this.pendingRecord = true;
|
|
1197
|
-
if (!this.actionGrouping) {
|
|
1198
|
-
this.actionGrouping = true;
|
|
1199
|
-
Promise.resolve().then(() => {
|
|
1200
|
-
if (this.actionGrouping) {
|
|
1201
|
-
this.commitPendingRecord();
|
|
1202
|
-
}
|
|
1203
|
-
});
|
|
1204
|
-
}
|
|
1205
|
-
} else {
|
|
1206
|
-
this.record();
|
|
1207
|
-
}
|
|
1208
|
-
});
|
|
1209
|
-
this.actionDisposer = onAction(target, () => {
|
|
1210
|
-
const current = getCurrentAction();
|
|
1211
|
-
if (current && !current.parent) {
|
|
1212
|
-
if (this.actionGrouping) {
|
|
1213
|
-
this.commitPendingRecord();
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
});
|
|
1217
|
-
}
|
|
1253
|
+
function getOrCreateHistoryTracker(target, options = {}) {
|
|
1254
|
+
let tracker = historyTrackersRegistry.get(target);
|
|
1255
|
+
if (!tracker) {
|
|
1256
|
+
tracker = new HistoryTracker(target, options);
|
|
1257
|
+
historyTrackersRegistry.set(target, tracker);
|
|
1218
1258
|
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
const N = this.snapshots.length;
|
|
1271
|
-
const M = undo.historyEntries.length;
|
|
1272
|
-
const undoIndex = this.index - 1 - (N - 1 - M);
|
|
1273
|
-
undo.currentIndex = Math.max(-1, Math.min(M - 1, undoIndex));
|
|
1274
|
-
}
|
|
1275
|
-
} finally {
|
|
1276
|
-
this.isApplying = false;
|
|
1277
|
-
rootNode.$isApplyingHistory = wasApplying;
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
getSnapshot(index) {
|
|
1281
|
-
if (index < 0 || index >= this.snapshots.length) {
|
|
1282
|
-
throw new Error(`[jotai-state-tree] Invalid snapshot index: ${index}`);
|
|
1259
|
+
return tracker;
|
|
1260
|
+
}
|
|
1261
|
+
function createUndoManager(target, options) {
|
|
1262
|
+
const tracker = getOrCreateHistoryTracker(target, options);
|
|
1263
|
+
tracker.autoRecord = true;
|
|
1264
|
+
const store = getGlobalStore();
|
|
1265
|
+
return {
|
|
1266
|
+
get canUndo() {
|
|
1267
|
+
const state = store.get(tracker.historyAtom);
|
|
1268
|
+
return state.currentIndex >= 0;
|
|
1269
|
+
},
|
|
1270
|
+
get canRedo() {
|
|
1271
|
+
const state = store.get(tracker.historyAtom);
|
|
1272
|
+
return state.currentIndex < state.entries.length - 1;
|
|
1273
|
+
},
|
|
1274
|
+
get undoLevels() {
|
|
1275
|
+
const state = store.get(tracker.historyAtom);
|
|
1276
|
+
return state.currentIndex + 1;
|
|
1277
|
+
},
|
|
1278
|
+
get redoLevels() {
|
|
1279
|
+
const state = store.get(tracker.historyAtom);
|
|
1280
|
+
return state.entries.length - state.currentIndex - 1;
|
|
1281
|
+
},
|
|
1282
|
+
get history() {
|
|
1283
|
+
const state = store.get(tracker.historyAtom);
|
|
1284
|
+
return state.entries;
|
|
1285
|
+
},
|
|
1286
|
+
get historyIndex() {
|
|
1287
|
+
const state = store.get(tracker.historyAtom);
|
|
1288
|
+
return state.currentIndex;
|
|
1289
|
+
},
|
|
1290
|
+
undo() {
|
|
1291
|
+
tracker.undo();
|
|
1292
|
+
},
|
|
1293
|
+
redo() {
|
|
1294
|
+
tracker.redo();
|
|
1295
|
+
},
|
|
1296
|
+
clear() {
|
|
1297
|
+
tracker.clear();
|
|
1298
|
+
},
|
|
1299
|
+
startGroup() {
|
|
1300
|
+
tracker.startGroup();
|
|
1301
|
+
},
|
|
1302
|
+
endGroup() {
|
|
1303
|
+
tracker.endGroup();
|
|
1304
|
+
},
|
|
1305
|
+
withoutUndo(fn) {
|
|
1306
|
+
return tracker.withoutUndo(fn);
|
|
1307
|
+
},
|
|
1308
|
+
dispose() {
|
|
1309
|
+
tracker.dispose();
|
|
1283
1310
|
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
function createTimeTravelManager(target, options) {
|
|
1314
|
+
const tracker = getOrCreateHistoryTracker(target, options);
|
|
1315
|
+
if (options?.autoRecord) {
|
|
1316
|
+
tracker.autoRecord = true;
|
|
1290
1317
|
}
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1318
|
+
const store = getGlobalStore();
|
|
1319
|
+
return {
|
|
1320
|
+
get currentIndex() {
|
|
1321
|
+
const state = store.get(tracker.historyAtom);
|
|
1322
|
+
return state.currentIndex + 1;
|
|
1323
|
+
},
|
|
1324
|
+
get snapshotCount() {
|
|
1325
|
+
const state = store.get(tracker.historyAtom);
|
|
1326
|
+
return state.entries.length + 1;
|
|
1327
|
+
},
|
|
1328
|
+
get canGoBack() {
|
|
1329
|
+
const state = store.get(tracker.historyAtom);
|
|
1330
|
+
return state.currentIndex + 1 > 0;
|
|
1331
|
+
},
|
|
1332
|
+
get canGoForward() {
|
|
1333
|
+
const state = store.get(tracker.historyAtom);
|
|
1334
|
+
return state.currentIndex + 1 < state.entries.length + 1 - 1;
|
|
1335
|
+
},
|
|
1336
|
+
record() {
|
|
1337
|
+
tracker.record();
|
|
1338
|
+
},
|
|
1339
|
+
goBack() {
|
|
1340
|
+
tracker.goBack();
|
|
1341
|
+
},
|
|
1342
|
+
goForward() {
|
|
1343
|
+
tracker.goForward();
|
|
1344
|
+
},
|
|
1345
|
+
goTo(index) {
|
|
1346
|
+
tracker.goTo(index);
|
|
1347
|
+
},
|
|
1348
|
+
getSnapshot(index) {
|
|
1349
|
+
return tracker.getSnapshot(index);
|
|
1350
|
+
},
|
|
1351
|
+
clear() {
|
|
1352
|
+
tracker.clear();
|
|
1353
|
+
},
|
|
1354
|
+
dispose() {
|
|
1355
|
+
tracker.dispose();
|
|
1300
1356
|
}
|
|
1301
|
-
}
|
|
1302
|
-
};
|
|
1303
|
-
function createTimeTravelManager(target, options) {
|
|
1304
|
-
return new TimeTravelManager(target, options);
|
|
1357
|
+
};
|
|
1305
1358
|
}
|
|
1306
1359
|
var ActionRecorder = class {
|
|
1307
1360
|
constructor(target) {
|
|
@@ -1443,6 +1496,7 @@ export {
|
|
|
1443
1496
|
freeze,
|
|
1444
1497
|
isFrozen,
|
|
1445
1498
|
unfreeze,
|
|
1499
|
+
getOrCreateHistoryTracker,
|
|
1446
1500
|
createUndoManager,
|
|
1447
1501
|
createTimeTravelManager,
|
|
1448
1502
|
createActionRecorder
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as ISimpleType, a as IType, b as IIdentifierType, c as IIdentifierNumberType, d as ILiteralType, e as IEnumerationType, f as IFrozenType, M as ModelProperties, g as IModelType, h as MixinConfig, i as IMixin, j as IAnyType, k as IArrayType, l as IMapType, m as IOptionalType, n as IMaybeType, o as IMaybeNullType, p as IUnionType, U as UnionOptions, q as ILateType, r as IAnyModelType, R as ReferenceOptions, s as IReferenceType, t as ISafeReferenceType, u as IRefinementType, v as IDisposer, S as SnapshotIn, w as Instance } from './undo-
|
|
2
|
-
export { L as CustomTypeOptions, aG as IActionRecorder, aH as IActionRecording, C as IAnyComplexType, D as IAnyMixin, aE as IHistoryEntry, F as IJsonPatch, y as IMSTArray, z as IMSTMap, G as IReversibleJsonPatch, x as IStateTreeNode, aF as ITimeTravelManager, aC as IUndoManager, aD as IUndoManagerOptions, H as IValidationContext, K as IValidationError, J as IValidationResult, A as ModelInstance, E as ModelSelf, B as SnapshotOut, T as applyPatch, O as applySnapshot, aw as cleanupStaleEntries, ax as clearAllRegistries, aa as clone, aq as cloneDeep, aB as createActionRecorder, aA as createTimeTravelManager, az as createUndoManager, a8 as destroy, a9 as detach, am as findAll, an as findFirst, as as freeze, a2 as getEnv, ag as getGlobalStore, a4 as getIdentifier, af as getMembers, ar as getOrCreatePath, Y as getParent, $ as getParentOfType, a0 as getPath, a1 as getPathParts, av as getRegistryStats, aj as getRelativePath, X as getRoot, N as getSnapshot, ap as getTreeStats, a3 as getType, _ as hasParent, al as haveSameRoot, a5 as isAlive, ak as isAncestor, at as isFrozen, a6 as isRoot, a7 as isStateTreeNode, ao as isValidReference, W as onAction, ay as onLifecycleChange, Q as onPatch, P as onSnapshot, V as recordPatches, ai as resetGlobalStore, ae as resolveIdentifier, ac as resolvePath, ah as setGlobalStore, Z as tryGetParent, ad as tryResolve, au as unfreeze, ab as walk } from './undo-
|
|
1
|
+
import { I as ISimpleType, a as IType, b as IIdentifierType, c as IIdentifierNumberType, d as ILiteralType, e as IEnumerationType, f as IFrozenType, M as ModelProperties, g as IModelType, h as MixinConfig, i as IMixin, j as IAnyType, k as IArrayType, l as IMapType, m as IOptionalType, n as IMaybeType, o as IMaybeNullType, p as IUnionType, U as UnionOptions, q as ILateType, r as IAnyModelType, R as ReferenceOptions, s as IReferenceType, t as ISafeReferenceType, u as IRefinementType, v as IDisposer, S as SnapshotIn, w as Instance } from './undo-quCDYz_6.mjs';
|
|
2
|
+
export { L as CustomTypeOptions, aG as IActionRecorder, aH as IActionRecording, C as IAnyComplexType, D as IAnyMixin, aE as IHistoryEntry, F as IJsonPatch, y as IMSTArray, z as IMSTMap, G as IReversibleJsonPatch, x as IStateTreeNode, aF as ITimeTravelManager, aC as IUndoManager, aD as IUndoManagerOptions, H as IValidationContext, K as IValidationError, J as IValidationResult, A as ModelInstance, E as ModelSelf, B as SnapshotOut, T as applyPatch, O as applySnapshot, aw as cleanupStaleEntries, ax as clearAllRegistries, aa as clone, aq as cloneDeep, aB as createActionRecorder, aA as createTimeTravelManager, az as createUndoManager, a8 as destroy, a9 as detach, am as findAll, an as findFirst, as as freeze, a2 as getEnv, ag as getGlobalStore, a4 as getIdentifier, af as getMembers, ar as getOrCreatePath, Y as getParent, $ as getParentOfType, a0 as getPath, a1 as getPathParts, av as getRegistryStats, aj as getRelativePath, X as getRoot, N as getSnapshot, ap as getTreeStats, a3 as getType, _ as hasParent, al as haveSameRoot, a5 as isAlive, ak as isAncestor, at as isFrozen, a6 as isRoot, a7 as isStateTreeNode, ao as isValidReference, W as onAction, ay as onLifecycleChange, Q as onPatch, P as onSnapshot, V as recordPatches, ai as resetGlobalStore, ae as resolveIdentifier, ac as resolvePath, ah as setGlobalStore, Z as tryGetParent, ad as tryResolve, au as unfreeze, ab as walk } from './undo-quCDYz_6.mjs';
|
|
3
3
|
import 'jotai/vanilla/internals';
|
|
4
4
|
import 'jotai';
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as ISimpleType, a as IType, b as IIdentifierType, c as IIdentifierNumberType, d as ILiteralType, e as IEnumerationType, f as IFrozenType, M as ModelProperties, g as IModelType, h as MixinConfig, i as IMixin, j as IAnyType, k as IArrayType, l as IMapType, m as IOptionalType, n as IMaybeType, o as IMaybeNullType, p as IUnionType, U as UnionOptions, q as ILateType, r as IAnyModelType, R as ReferenceOptions, s as IReferenceType, t as ISafeReferenceType, u as IRefinementType, v as IDisposer, S as SnapshotIn, w as Instance } from './undo-
|
|
2
|
-
export { L as CustomTypeOptions, aG as IActionRecorder, aH as IActionRecording, C as IAnyComplexType, D as IAnyMixin, aE as IHistoryEntry, F as IJsonPatch, y as IMSTArray, z as IMSTMap, G as IReversibleJsonPatch, x as IStateTreeNode, aF as ITimeTravelManager, aC as IUndoManager, aD as IUndoManagerOptions, H as IValidationContext, K as IValidationError, J as IValidationResult, A as ModelInstance, E as ModelSelf, B as SnapshotOut, T as applyPatch, O as applySnapshot, aw as cleanupStaleEntries, ax as clearAllRegistries, aa as clone, aq as cloneDeep, aB as createActionRecorder, aA as createTimeTravelManager, az as createUndoManager, a8 as destroy, a9 as detach, am as findAll, an as findFirst, as as freeze, a2 as getEnv, ag as getGlobalStore, a4 as getIdentifier, af as getMembers, ar as getOrCreatePath, Y as getParent, $ as getParentOfType, a0 as getPath, a1 as getPathParts, av as getRegistryStats, aj as getRelativePath, X as getRoot, N as getSnapshot, ap as getTreeStats, a3 as getType, _ as hasParent, al as haveSameRoot, a5 as isAlive, ak as isAncestor, at as isFrozen, a6 as isRoot, a7 as isStateTreeNode, ao as isValidReference, W as onAction, ay as onLifecycleChange, Q as onPatch, P as onSnapshot, V as recordPatches, ai as resetGlobalStore, ae as resolveIdentifier, ac as resolvePath, ah as setGlobalStore, Z as tryGetParent, ad as tryResolve, au as unfreeze, ab as walk } from './undo-
|
|
1
|
+
import { I as ISimpleType, a as IType, b as IIdentifierType, c as IIdentifierNumberType, d as ILiteralType, e as IEnumerationType, f as IFrozenType, M as ModelProperties, g as IModelType, h as MixinConfig, i as IMixin, j as IAnyType, k as IArrayType, l as IMapType, m as IOptionalType, n as IMaybeType, o as IMaybeNullType, p as IUnionType, U as UnionOptions, q as ILateType, r as IAnyModelType, R as ReferenceOptions, s as IReferenceType, t as ISafeReferenceType, u as IRefinementType, v as IDisposer, S as SnapshotIn, w as Instance } from './undo-quCDYz_6.js';
|
|
2
|
+
export { L as CustomTypeOptions, aG as IActionRecorder, aH as IActionRecording, C as IAnyComplexType, D as IAnyMixin, aE as IHistoryEntry, F as IJsonPatch, y as IMSTArray, z as IMSTMap, G as IReversibleJsonPatch, x as IStateTreeNode, aF as ITimeTravelManager, aC as IUndoManager, aD as IUndoManagerOptions, H as IValidationContext, K as IValidationError, J as IValidationResult, A as ModelInstance, E as ModelSelf, B as SnapshotOut, T as applyPatch, O as applySnapshot, aw as cleanupStaleEntries, ax as clearAllRegistries, aa as clone, aq as cloneDeep, aB as createActionRecorder, aA as createTimeTravelManager, az as createUndoManager, a8 as destroy, a9 as detach, am as findAll, an as findFirst, as as freeze, a2 as getEnv, ag as getGlobalStore, a4 as getIdentifier, af as getMembers, ar as getOrCreatePath, Y as getParent, $ as getParentOfType, a0 as getPath, a1 as getPathParts, av as getRegistryStats, aj as getRelativePath, X as getRoot, N as getSnapshot, ap as getTreeStats, a3 as getType, _ as hasParent, al as haveSameRoot, a5 as isAlive, ak as isAncestor, at as isFrozen, a6 as isRoot, a7 as isStateTreeNode, ao as isValidReference, W as onAction, ay as onLifecycleChange, Q as onPatch, P as onSnapshot, V as recordPatches, ai as resetGlobalStore, ae as resolveIdentifier, ac as resolvePath, ah as setGlobalStore, Z as tryGetParent, ad as tryResolve, au as unfreeze, ab as walk } from './undo-quCDYz_6.js';
|
|
3
3
|
import 'jotai/vanilla/internals';
|
|
4
4
|
import 'jotai';
|
|
5
5
|
|