useManualHistory
A hook for manually managing Observable change history. It only records a snapshot when commit() is called, and allows navigating previous states via undo/redo.
Useful when auto-tracking is not needed, or when you want to record history only on explicit “save” actions.
The counter can move as much as you want, but history updates only when you explicitly save a snapshot.
Increment or decrement first, then decide when that state deserves a place in history.
Newest snapshot is pinned at the top.
import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useManualHistory
useManualHistory } from "@usels/web";
const const counter$: any
counter$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable(0);const { const commit: any
commit, const undo: any
undo, const redo: any
redo, const canUndo$: any
canUndo$, const canRedo$: any
canRedo$ } = import useManualHistory
useManualHistory(const counter$: any
counter$);
const counter$: any
counter$.any
set(1);const commit: any
commit(); // snapshot: 1
const counter$: any
counter$.any
set(2);const commit: any
commit(); // snapshot: 2
const undo: any
undo(); // counter$ → 1const redo: any
redo(); // counter$ → 2capacity — limit history size
Section titled “capacity — limit history size”import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useManualHistory
useManualHistory } from "@usels/web";
const const value$: any
value$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable(0);
// Keep at most 10 undo steps; older records are discarded automaticallyconst { const commit: any
commit, const undo: any
undo } = import useManualHistory
useManualHistory(const value$: any
value$, { capacity: number
capacity: 10 });dump / parse — custom serialization
Section titled “dump / parse — custom serialization”Use dump and parse to store a compact or transformed representation instead of raw value clones.
import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useManualHistory
useManualHistory } from "@usels/web";
const const items$: any
items$ = useObservable<{}>(value: Promise<{}> | (() => {}) | {}, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable<string[]>([]);
const { const commit: any
commit, const undo: any
undo, const history$: any
history$ } = import useManualHistory
useManualHistory(const items$: any
items$, { // Store as comma-separated string to save memory dump: (arr: any) => any
dump: (arr: any
arr) => arr: any
arr.any
join(","), parse: (str: any) => any
parse: (str: any
str) => (str: any
str ? str: any
str.any
split(",") : []),});
const items$: any
items$.any
set(["a", "b", "c"]);const commit: any
commit(); // stored as "a,b,c"
const undo: any
undo(); // restored to ["a", "b", "c"]reset — revert uncommitted changes
Section titled “reset — revert uncommitted changes”reset() restores the source to the last committed value without touching the undo/redo stacks.
import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useManualHistory
useManualHistory } from "@usels/web";
const const text$: any
text$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable("saved");const { const commit: any
commit, const reset: any
reset } = import useManualHistory
useManualHistory(const text$: any
text$);
const commit: any
commit(); // snapshot: "saved"const text$: any
text$.any
set("unsaved"); // uncommitted editconst reset: any
reset(); // text$ → "saved" (stacks unchanged)clear — wipe all history
Section titled “clear — wipe all history”import { function useObservable<T>(): Observable<T | undefined> (+3 overloads)
A React hook that creates a new observable
useObservable } from "@legendapp/state/react";import { import useManualHistory
useManualHistory } from "@usels/web";
const const value$: any
value$ = useObservable<unknown>(value: Promise<unknown> | (() => unknown) | unknown, deps?: React.DependencyList): any (+3 overloads)
A React hook that creates a new observable
useObservable(0);const { const commit: any
commit, const clear: any
clear, const history$: any
history$ } = import useManualHistory
useManualHistory(const value$: any
value$);
const value$: any
value$.any
set(1);const commit: any
commit();const value$: any
value$.any
set(2);const commit: any
commit();
const clear: any
clear(); // history$ → [{ snapshot: 2, timestamp: ... }], stacks emptyType Declarations
Section titled “Type Declarations”export interface UseManualHistoryOptions<Raw, Serialized = Raw> { capacity?: number; clone?: boolean | ((value: Raw) => Raw); dump?: (value: Raw) => Serialized; parse?: (value: Serialized) => Raw;}export interface UseManualHistoryReturn<Raw, Serialized = Raw> { readonly canUndo$: ReadonlyObservable<boolean>; readonly canRedo$: ReadonlyObservable<boolean>; readonly history$: ReadonlyObservable<UseHistoryRecord<Serialized>[]>; readonly last$: ReadonlyObservable<UseHistoryRecord<Serialized>>; commit: Fn; undo: Fn; redo: Fn; clear: Fn; reset: Fn;}export declare function useManualHistory<Raw, Serialized = Raw>(source$: Observable<Raw>, options?: DeepMaybeObservable<UseManualHistoryOptions<Raw, Serialized>>): UseManualHistoryReturn<Raw, Serialized>;Source
Section titled “Source”Contributors
Section titled “Contributors”- tigerwest
Changelog
Section titled “Changelog”a7392ab2026-03-06 - feat(core,browser): add sync strategy hooks (tigerwest)