Captures and restores external state before and after function calls. Supports manual snapshots and automatic snapshots before each execution.
State decorators capture and restore application state around function execution.
snapshot link
What it is link
Captures and restores external state before and after function calls. Supports manual snapshots and automatic snapshots before each execution.
When to use it link
- Undo/redo functionality
- Rollback operations
- Checkpointing long-running workflows
Async / sync support link
Func<R> | Func1<T, R> | Func2<T1, T2, R> | FuncSync<R> |
|---|
| ✅ | ✅ | ✅ | ❌ |
API reference link
1
2
3
4
5
6
7
8
| // api-reference
SnapshotExtension<R, S> snapshot<S>({
required S Function() getState,
required void Function(S state) setState,
bool autoSnapshot = false,
void Function(Snapshot<S> snapshot)? onSnapshot,
void Function(Snapshot<S> snapshot)? onRestore,
})
|
Methods:
Snapshot<S> createSnapshot() — capture current state.void restoreSnapshot(Snapshot<S> snapshot) — restore state.List<Snapshot<S>> get snapshots — immutable history.void clearSnapshots() — remove all snapshots.
Examples link
Minimal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| var counter = 0;
final step = Func<int>(() async {
return ++counter;
}).snapshot(
getState: () => counter,
setState: (s) => counter = s,
);
void main() async {
await step(); // counter = 1
final snap = step.createSnapshot();
await step(); // counter = 2
step.restoreSnapshot(snap); // counter = 1
print(counter); // 1
}
|
Real world
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| class UndoStack {
final List<Snapshot<Document>> _history = [];
void push(Snapshot<Document> s) => _history.add(s);
}
extension DocumentExt on Document {
Document apply(EditOperation op) => this; // placeholder transformation
}
var document = Document();
final undoStack = UndoStack();
final edit = Func1<EditOperation, void>((op) async {
document = document.apply(op);
}).snapshot(
getState: () => document,
setState: (d) => document = d,
autoSnapshot: true,
onSnapshot: (s) => undoStack.push(s),
);
void main() async {
await edit(EditOperation());
}
|
Best practices link
- Keep snapshots immutable or deep-copy mutable state.
- Enable
autoSnapshot only when every execution should be reversible.
Common pitfalls link
setState receives the captured state object; mutations affect the snapshot if it is not copied.- Snapshot history grows unbounded unless
clearSnapshots() is called.