-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtime-machine.js
71 lines (70 loc) · 2.58 KB
/
time-machine.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const createTimeMachine = (data, onUpdate) => {
const proxy = new Proxy(
{
timelines: [{ states: [{ ...data, timestamp: new Date() }] }],
$currentIndex: 0,
$currentTimeline: 0,
},
{
set(target, property, value) {
if (
target.timelines[target.$currentTimeline].states[target.$currentIndex][property] === value
)
return;
target.timelines[target.$currentTimeline].states.push(
structuredClone({
...target.timelines[target.$currentTimeline].states[target.$currentIndex],
[property]: value,
timestamp: new Date(),
})
);
target.$currentIndex++;
onUpdate();
},
get(target, property) {
if (property === "currentState") {
return target.timelines[target.$currentTimeline].states[target.$currentIndex];
} else if (property === "$currentTimeline") {
return target.$currentTimeline;
} else if (property === "states") {
return target.timelines[target.$currentTimeline].states;
} else if (property === "changeTimeline") {
return (change) => {
if (target.timelines[target.$currentTimeline + change]) {
target.$currentTimeline = target.$currentTimeline + change;
target.$currentIndex = target.timelines[target.$currentTimeline].states.length - 1;
}
onUpdate();
};
} else if (property === "backward") {
return () => {
if (target.$currentIndex) {
target.$currentIndex--;
target.timelines[target.$currentTimeline].states.pop();
onUpdate();
}
};
} else if (property === "backInTime") {
return (seconds = 10) => {
const newTimeline = {
...target.timelines[target.$currentTimeline],
};
target.timelines.push(newTimeline);
const targetTime = new Date(new Date() - seconds * 1000);
const index = target.timelines[target.$currentTimeline].states.findIndex(
(state) => state.timestamp > targetTime
);
if (index !== -1) target.$currentIndex = index;
target.timelines[target.$currentTimeline].states = target.timelines[
target.$currentTimeline
].states.slice(0, target.$currentIndex + 1);
onUpdate();
};
} else {
return target.timelines[target.$currentTimeline].states[target.$currentIndex][property];
}
},
}
);
return proxy;
};