# Observer - Memorio

> ⚠️ **DEPRECATED**: This function is deprecated and will be removed in future versions. Please use [`useObserver`](USEOBSERVER.md) instead.

Observer lets you react to state changes. When a state key changes, your callback function runs.

## Installation

```bash
npm install memorio
```

```javascript
import 'memorio';
```

---

## Quick Examples

### Example 1: Basic Usage

```javascript
// Simple observer (DEPRECATED - use useObserver instead)
console.warn('observer() is deprecated. Please use useObserver() for React or memorio.dispatch for vanilla JS.');

observer('state.counter', (newValue) => {
  console.debug('Counter is now:', newValue);
});

state.counter = 1;
// Output: "Counter is now: 1"

state.counter = 5;
// Output: "Counter is now: 5"
```

> **Note**: For new projects, use [`useObserver`](USEOBSERVER.md) for React or [`memorio.dispatch`](SUMMARY.md) for vanilla JS.

### Example 2: Intermediate

```javascript
// Observer with old value
observer('state.user', (newValue, oldValue) => {
  console.debug(`User changed from ${oldValue?.name} to ${newValue?.name}`);
});

state.user = { name: 'Mario' };
// Output: "User changed from undefined to Mario"

state.user = { name: 'Luigi' };
// Output: "User changed from Mario to Luigi"
```

### Example 3: Advanced

```javascript
// Multiple observers
const obs1 = observer('state.data', handler1);
const obs2 = observer('state.data', handler2);

// List all observers
console.debug(observer.list);
// Output: [{ name: 'state.data', id: '...' }, ...]

// Remove specific observer
observer.remove('state.data');

// Remove all observers
observer.removeAll();
```

---

## API Reference

### observer(path, callback)

| Parameter | Type | Description |
|-----------|------|-------------|
| `path` | `string` | State path to watch (e.g., `'state.counter'`) |
| `callback` | `function` | Function called on change |

### Callback Parameters

```javascript
observer('state.key', (newValue, oldValue) => {
  // newValue: the new value
  // oldValue: the previous value
});
```

### Properties

| Property | Type | Description |
|----------|------|-------------|
| `observer.list` | `Array` | Get all active observers |

### Methods

| Method | Parameters | Description |
|--------|------------|-------------|
| `observer.remove(name)` | `string` | Remove observer for specific path |
| `observer.removeAll()` | none | Remove all observers |

---

## React Integration

### With useState

```javascript
const [count, setCount] = useState(0);

observer('state.counter', () => {
  setCount(state.counter);
});
```

### With useEffect

```javascript
useEffect(() => {
  const handleChange = (newVal) => {
    console.debug('Changed:', newVal);
  };

  observer('state.data', handleChange);

  // Cleanup
  return () => observer.remove('state.data');
}, []);
```

---

## How It Works

Observer subscribes to state changes via the Proxy's set trap. When `state.key = value` is called:
1. The Proxy intercepts the set
2. Fires all callbacks registered for that path
3. Callbacks receive newValue and oldValue

---

## Best Practices

1. Clean up observers in React `useEffect` return
2. Use specific paths: `'state.user.name'` not `'state'`
3. Remove observers when components unmount
4. Use `observer.removeAll()` on page navigation

---

## Common Patterns

### Form Validation

```javascript
observer('state.form.email', (email) => {
  const isValid = email.includes('@');
  state.form.isValid = isValid;
});
```

### Analytics

```javascript
observer('state.page', (page) => {
  analytics.track('page_view', { page });
});
```

### Auto-save

```javascript
observer('state.draft', (content) => {
  store.set('autosave', content);
});
```
