Skip to content

ChronicleDeep Observable State with Time-Travel

A powerful state observation library with deep proxy-based tracking, history recording, and time-travel debugging for JavaScript objects

Quick Example

Track and manage state changes with Chronicle:

typescript
import { chronicle } from '@arcmantle/chronicle';

// Observe an object
const state = chronicle({
  count: 0,
  user: { name: 'Alice', email: 'alice@example.com' }
});

// Listen to specific changes (string selector)
chronicle.listen(state, 'count', (path, newValue, oldValue) => {
  console.log(`Count changed from ${oldValue} to ${newValue}`);
});

// Or use a function selector for better type safety
chronicle.listen(state, s => s.count, (path, newValue, oldValue) => {
  console.log(`Count changed from ${oldValue} to ${newValue}`);
});

// Listen to nested changes
chronicle.listen(state, 'user', (path, newValue, oldValue) => {
  console.log(`User changed at ${path.join('.')}`);
}, 'down');

// Or with function selector
chronicle.listen(state, s => s.user, (path, newValue, oldValue) => {
  console.log(`User changed at ${path.join('.')}`);
}, 'down');

// Make changes (listeners fire automatically)
state.count = 1;
state.user.name = 'Bob';

// Undo changes
chronicle.undo(state); // user.name back to 'Alice'
chronicle.undo(state); // count back to 0

// Redo
chronicle.redo(state); // count back to 1

Installation

sh
npm install @arcmantle/chronicle
sh
pnpm add @arcmantle/chronicle
sh
yarn add @arcmantle/chronicle

Basic Usage

typescript
import { chronicle } from '@arcmantle/chronicle';

// Create an observable state
const state = chronicle({
  todos: [],
  filter: 'all'
});

// React to changes
chronicle.listen(state, s => s.todos, () => {
  console.log('Todos updated:', state.todos);
}, 'down');

// Make changes
state.todos.push({ id: 1, text: 'Learn Chronicle', done: false });

// Time travel
chronicle.undo(state);
chronicle.redo(state);

Now you're ready to start using Chronicle! 🚀

Released under the Apache-2.0 License.