Version History
Editu provides a version history system that lets you save, view, and restore document snapshots.
Overview
Version history enables:
- Save snapshots — capture document state at any point
- Restore versions — revert to a previous snapshot
- Browse history — list all saved versions with timestamps
- Storage flexibility — use localStorage or a custom backend
- Version limits — automatic cleanup of old versions
Quick Start
React
tsx
import { useEdituEditor, useEdituVersionHistory, EdituProvider, EdituEditor } from "@editu/react";
function Editor() {
const editor = useEdituEditor({});
const { snapshots, saveVersion, restoreVersion, deleteVersion } =
useEdituVersionHistory(() => editor, {
maxVersions: 20,
key: "my-doc-versions",
});
return (
<EdituProvider editor={editor}>
<EdituEditor />
<button onClick={() => saveVersion("Manual save")}>
Save Version
</button>
<ul>
{snapshots.map((s) => (
<li key={s.id}>
{s.description ?? "Untitled"} —{" "}
{new Date(s.timestamp).toLocaleString()}
<button onClick={() => restoreVersion(s.id)}>Restore</button>
<button onClick={() => deleteVersion(s.id)}>Delete</button>
</li>
))}
</ul>
</EdituProvider>
);
}Options
typescript
interface EdituVersionHistoryOptions {
/** Enable version history (default: true) */
enabled?: boolean;
/** Maximum number of versions to keep (default: 50) */
maxVersions?: number;
/** Storage backend (default: 'localStorage') */
storage?: EdituVersionStorage;
/** Storage key for localStorage (default: 'editu-versions') */
key?: string;
/** Callback when a version is saved */
onSave?: (snapshot: EdituVersionSnapshot) => void;
/** Callback when an error occurs */
onError?: (error: Error) => void;
/** Callback when a version is restored */
onRestore?: (snapshot: EdituVersionSnapshot) => void;
}maxVersions
Limits the number of stored snapshots. When the limit is reached, Editu removes the oldest snapshot.
typescript
useEdituVersionHistory(() => editor, {
maxVersions: 10, // Keep only the last 10 versions
});storage
You can choose between built-in localStorage or a custom backend.
typescript
// localStorage (default)
useEdituVersionHistory(() => editor, {
storage: "localStorage",
});
// Custom backend (e.g., API)
useEdituVersionHistory(() => editor, {
storage: {
save: async (snapshots) => {
await fetch("/api/versions", {
method: "PUT",
body: JSON.stringify(snapshots),
});
},
load: async () => {
const res = await fetch("/api/versions");
return res.json();
},
},
});Version Snapshot
Each snapshot contains:
typescript
interface EdituVersionSnapshot {
/** Unique identifier */
id: string;
/** Document content as JSON */
content: JSONContent;
/** Unix timestamp (milliseconds) */
timestamp: number;
/** Optional description */
description?: string;
/** Optional author name */
author?: string;
}API Reference
Hook / Composable / Rune
| Framework | Function |
|---|---|
| React | useEdituVersionHistory(getEditor, options) |
Return Values
| Property | Type | Description |
|---|---|---|
snapshots | EdituVersionSnapshot[] | All stored snapshots (newest first) |
isLoading | boolean | Whether history is loading |
error | Error | null | Last error that occurred |
saveVersion(desc?, author?) | Promise<EdituVersionSnapshot | null> | Save current state |
restoreVersion(id) | Promise<boolean> | Restore to a version |
loadVersions() | Promise<EdituVersionSnapshot[]> | Reload from storage |
deleteVersion(id) | Promise<void> | Delete a version |
clearVersions() | Promise<void> | Delete all versions |
Core Handlers
For advanced use cases, you can use the core handlers directly:
typescript
import {
createEdituVersionHistoryHandlers,
type EdituVersionHistoryState,
} from "@editu/core";
const handlers = createEdituVersionHistoryHandlers(
() => editor,
{ maxVersions: 20, key: "my-versions" },
(state: Partial<EdituVersionHistoryState>) => {
// Handle state changes
}
);
await handlers.saveVersion("Initial draft", "Alice");
const versions = await handlers.loadVersions();
await handlers.restoreVersion(versions[0].id);