/
observer-snapshot.js
80 lines (68 loc) · 1.71 KB
/
observer-snapshot.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
72
73
74
75
76
77
78
79
80
/*
one snapshot only and it is not intended to be saveable, the usage case for snapshot is a'la SQL transaction
start transaction - takeSnapshot
rollback - restoreFromSnapshot
commit - releaseSnapshot
*/
import { createInstance, ObserverHistory } from './observer-history.js';
const max = 1000;
class ObserverSnapshot extends ObserverHistory {
takeSnapshot() {
if (this.snapshot) return;
this.snapshot = {
pos: this.pos,
max: this.max,
};
this.max = max;
return true;
}
set(serialized = {}) {
super.set(serialized);
this.snapshot = serialized.snapshot;
if (this.snapshot) this.max = max;
}
serialize() {
let ser = super.serialize();
if (this.snapshot) {
ser.snapshot = this.snapshot;
}
return ser;
}
releaseSnapshot() {
if (!this.snapshot) return;
this.max = this.snapshot.max;
if (this.stack.length > this.max) {
let toDelete = this.stack.length - this.max;
this.stack.splice(0, toDelete);
this.pos -= toDelete;
}
this.snapshot = undefined;
return true;
}
restoreFromSnapshot() {
if (!this.snapshot) return;
this.commit('snapshot');
let restored = this.snapshot.pos < this.pos;
while (this.snapshot.pos < this.pos) {
super.undo();
}
this.max = this.snapshot.max;
if (this.stack.length > this.pos) {
this.stack.length = this.pos + 1;
}
this.snapshot = undefined;
return restored;
}
mixin(target, map = {}) {
super.mixin(target, {
takeSnapshot: 0,
releaseSnapshot: 0,
restoreFromSnapshot: 0,
...map,
});
}
}
function createSnapshotObserver(...args) {
return createInstance(ObserverSnapshot, ...args);
}
export { createSnapshotObserver };