Skip to content
Reactivity

useDebouncedHistory

A hook that tracks Observable change history with debounce. A thin wrapper around useDataHistory with debounceFilter applied — it only records history after typing has stopped. Ideal for text inputs or search fields where you want to snapshot only when a burst of changes has "settled".

Settling editor
Commit after 600ms

Type quickly, pause, then inspect how only the settled value lands in history.

Snapshots: 1
Debounced timeline

Newest snapshot is pinned at the top.

#1
""
import {
import useDebouncedHistory
useDebouncedHistory
,
import useObservable
useObservable
} from "@usels/web";
function
function Component(): JSX.Element
Component
() {
const
const search$: any
search$
=
import useObservable
useObservable
("");
// Record a snapshot 500ms after the user stops typing
const {
const undo: any
undo
,
const redo: any
redo
,
const canUndo$: any
canUndo$
} =
import useDebouncedHistory
useDebouncedHistory
(
const search$: any
search$
, {
debounce: number
debounce
: 500 });
return <
JSX.IntrinsicElements.input: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
input
InputHTMLAttributes<HTMLInputElement>.value?: string | number | {} | undefined
value
={
const search$: any
search$
.
any
get
()}
InputHTMLAttributes<HTMLInputElement>.onChange?: ChangeEventHandler<HTMLInputElement, HTMLInputElement> | undefined
onChange
={(
e: ChangeEvent<HTMLInputElement, HTMLInputElement>
e
) =>
const search$: any
search$
.
any
set
(
e: ChangeEvent<HTMLInputElement, HTMLInputElement>
e
.
ChangeEvent<HTMLInputElement, HTMLInputElement>.target: EventTarget & HTMLInputElement
target
.
any
value
)} />;
}

maxWait — force commit after maximum delay

Section titled “maxWait — force commit after maximum delay”

Even if the user keeps typing, a snapshot is forced after maxWait ms.

import { useDebouncedHistory, useObservable } from "@usels/web";
function Component() {
const text$ = useObservable("");
// Commit after 500ms idle, or every 2s at most even if still typing
const { undo, redo } = useDebouncedHistory(text$, {
debounce: 500,
maxWait: 2000,
});
}
import { useDebouncedHistory, useObservable } from "@usels/web";
function Component() {
const note$ = useObservable("");
const { undo, redo } = useDebouncedHistory(note$, {
debounce: 800,
capacity: 30,
});
}
ParameterTypeDescription
source$Observable<Raw>- The Observable to track.
optionsDebouncedHistoryOptions<Raw, Serialized> (optional)- Debounce timing and history configuration.
OptionTypeDefaultDescription
debouncenumber200Debounce delay in milliseconds.
maxWaitnumber-Maximum time to wait before forcing a commit, regardless of activity.
shouldCommit((newValue: Raw) => boolean)-Gate function called before each auto-commit. Return false to skip recording the current value.
capacitynumberInfinityMaximum number of undo records to keep. When exceeded, the oldest records are discarded.
cloneboolean | ((value: Raw) => Raw)-Clone strategy for snapshots. - true (default): uses structuredClone - false: stores references (safe for primitives only) - (value) => cloned: custom clone function
dump((value: Raw) => Serialized)-Custom serializer: Raw → Serialized for storage. When provided, clone is ignored and parse must also be provided.
parse((value: Serialized) => Raw)-Custom deserializer: Serialized → Raw for restore. When provided, clone is ignored and dump must also be provided.

DataHistoryReturn<Raw, Serialized>

NameTypeDescription
isTracking$ReadonlyObservable<boolean>Whether auto-tracking is currently active.
pauseFnStop auto-committing.
resume(commitCurrent?: boolean | undefined) => voidRestart auto-committing. If commitCurrent is true, immediately commit current value.
transaction(fn: (cancel: Fn) => void) => voidGroup multiple mutations into a single history record. Call cancel() inside fn to abort.
canUndo$ReadonlyObservable<boolean>Whether undo is possible (undoStack is non-empty).
canRedo$ReadonlyObservable<boolean>Whether redo is possible (redoStack is non-empty).
history$ReadonlyObservable<UseHistoryRecord<Serialized>[]>Full history array, newest first: [current, previous, ...].
last$ReadonlyObservable<UseHistoryRecord<Serialized>>The most recent (current) history record.
commitFnRecord the current source value as a new history point. Clears redo stack.
undoFnRestore the previous committed value.
redoFnRe-apply the next value after an undo.
clearFnWipe all history and create a fresh initial record from current source.
resetFnRestore source to the last committed value without modifying stacks.

View on GitHub