memorio 2.5.1 → 2.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/CACHE.md +77 -0
- package/docs/DEVTOOLS.md +120 -0
- package/docs/IDB.md +156 -0
- package/docs/LOGGER.md +145 -0
- package/docs/OBSERVER.md +180 -0
- package/docs/SESSION.md +129 -0
- package/docs/STATE.md +135 -0
- package/docs/STORE.md +137 -0
- package/docs/SUMMARY.md +25 -0
- package/docs/USEOBSERVER.md +156 -0
- package/examples/basic.ts +75 -0
- package/examples/cache.ts +72 -0
- package/examples/idb.ts +109 -0
- package/examples/observer.ts +60 -0
- package/examples/session-advanced.ts +78 -0
- package/examples/state-advanced.ts +89 -0
- package/examples/store-advanced.ts +104 -0
- package/examples/useObserver.ts +141 -0
- package/index.js +1 -1
- package/package.json +5 -4
- package/COPYRIGHT.md +0 -6
- package/FUNDING.yml +0 -12
- package/SECURITY.md +0 -3
- package/index.js.map +0 -7
- package/index.mjs +0 -23
- package/index.mjs.map +0 -7
package/docs/CACHE.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Cache - Memorio
|
|
2
|
+
|
|
3
|
+
Cache provides in-memory storage with a simple API. Data is lost on page refresh.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install memorio
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
import 'memorio';
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quick Examples
|
|
18
|
+
|
|
19
|
+
### Example 1: Basic Usage
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
// Save data
|
|
23
|
+
cache.set('username', 'Mario');
|
|
24
|
+
cache.set('score', 1500);
|
|
25
|
+
|
|
26
|
+
// Read data
|
|
27
|
+
console.log(cache.get('username')); // "Mario"
|
|
28
|
+
console.log(cache.get('score')); // 1500
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Example 2: Intermediate
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
// Store objects
|
|
35
|
+
cache.set('user', { name: 'Luigi', level: 5 });
|
|
36
|
+
const user = cache.get('user');
|
|
37
|
+
console.log(user.name); // "Luigi"
|
|
38
|
+
|
|
39
|
+
// Remove single item
|
|
40
|
+
cache.remove('username');
|
|
41
|
+
|
|
42
|
+
// Clear all cache
|
|
43
|
+
cache.removeAll();
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## API Reference
|
|
49
|
+
|
|
50
|
+
### Methods
|
|
51
|
+
|
|
52
|
+
| Method | Parameters | Returns | Description |
|
|
53
|
+
|--------|------------|---------|-------------|
|
|
54
|
+
| `cache.get(name)` | `name: string` | `any` | Get value from cache |
|
|
55
|
+
| `cache.set(name, value)` | `name: string, value: any` | `void` | Save value to cache |
|
|
56
|
+
| `cache.remove(name)` | `name: string` | `boolean` | Remove single item |
|
|
57
|
+
| `cache.removeAll()` | `none` | `boolean` | Clear all cache |
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Storage Comparison
|
|
62
|
+
|
|
63
|
+
| Feature | Cache | Store | Session | IDB |
|
|
64
|
+
|---------|-------|-------|---------|-----|
|
|
65
|
+
| Storage | Memory | localStorage | sessionStorage | IndexedDB |
|
|
66
|
+
| Lifetime | Until refresh | Forever | Until tab closes | Forever |
|
|
67
|
+
| Capacity | Unlimited | ~5-10 MB | ~5-10 MB | 50+ MB |
|
|
68
|
+
| Use case | Temporary data | User preferences | Auth tokens | Large data |
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Best Practices
|
|
73
|
+
|
|
74
|
+
1. Use for temporary data that doesn't need persistence
|
|
75
|
+
2. Great for computed values or API response caching
|
|
76
|
+
3. Data is lost on page refresh - don't use for important data
|
|
77
|
+
4. Clear with `cache.removeAll()` when no longer needed
|
package/docs/DEVTOOLS.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Memorio DevTools
|
|
2
|
+
|
|
3
|
+
Browser console debugging tools for inspecting and managing Memorio state.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
// Load memorio first
|
|
9
|
+
import 'memorio'
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Available Methods
|
|
13
|
+
|
|
14
|
+
### inspect()
|
|
15
|
+
|
|
16
|
+
Inspect all Memorio modules in the console.
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
memorio.devtools.inspect()
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### stats()
|
|
23
|
+
|
|
24
|
+
Get statistics about all modules.
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
memorio.devtools.stats()
|
|
28
|
+
// Returns: { stateKeys, storeKeys, sessionKeys, cacheKeys, idbDatabases, lastUpdate }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### clear(module)
|
|
32
|
+
|
|
33
|
+
Clear data from a specific module.
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
memorio.devtools.clear('state')
|
|
37
|
+
memorio.devtools.clear('store')
|
|
38
|
+
memorio.devtools.clear('session')
|
|
39
|
+
memorio.devtools.clear('cache')
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### clearAll()
|
|
43
|
+
|
|
44
|
+
Clear all Memorio data.
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
memorio.devtools.clearAll()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### watch(module, path)
|
|
51
|
+
|
|
52
|
+
Watch a specific path for changes.
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
memorio.devtools.watch('state', 'user.name')
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### exportData()
|
|
59
|
+
|
|
60
|
+
Export all data as JSON.
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
const json = memorio.devtools.exportData()
|
|
64
|
+
console.log(json)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### importData(jsonString)
|
|
68
|
+
|
|
69
|
+
Import data from JSON.
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
memorio.devtools.importData('{"state":{"key":"value"}}')
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### help()
|
|
76
|
+
|
|
77
|
+
Show help information.
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
memorio.devtools.help()
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Console Shortcuts
|
|
84
|
+
|
|
85
|
+
Memorio provides global shortcuts for quick access:
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
$state // globalThis.state
|
|
89
|
+
$store // globalThis.store
|
|
90
|
+
$session // globalThis.session
|
|
91
|
+
$cache // globalThis.cache
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Examples
|
|
95
|
+
|
|
96
|
+
### Inspect current state
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
memorio.devtools.inspect()
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Export and restore state
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
// Export
|
|
106
|
+
const backup = memorio.devtools.exportData()
|
|
107
|
+
|
|
108
|
+
// Later... import
|
|
109
|
+
memorio.devtools.importData(backup)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Monitor changes
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
// Watch a specific path
|
|
116
|
+
memorio.devtools.watch('state', 'counter')
|
|
117
|
+
|
|
118
|
+
// Now changes will be logged to console
|
|
119
|
+
state.counter = 42 // Console shows: 👁 Change: state.counter = 42
|
|
120
|
+
```
|
package/docs/IDB.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# IDB - Memorio
|
|
2
|
+
|
|
3
|
+
IDB provides access to browser IndexedDB for large data storage. Unlike localStorage, IDB can store large amounts of structured data.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install memorio
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
import 'memorio';
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quick Examples
|
|
18
|
+
|
|
19
|
+
### Example 1: Basic Usage
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
// Create a database
|
|
23
|
+
idb.db.create('myApp');
|
|
24
|
+
|
|
25
|
+
// Add data
|
|
26
|
+
idb.data.set('myApp', 'users', { id: 1, name: 'Mario' });
|
|
27
|
+
|
|
28
|
+
// Get data
|
|
29
|
+
const user = idb.data.get('myApp', 'users', 1);
|
|
30
|
+
console.log(user.name); // "Mario"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Example 2: Intermediate
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
// Create database with tables
|
|
37
|
+
idb.db.create('store');
|
|
38
|
+
idb.table.create('store', 'products');
|
|
39
|
+
|
|
40
|
+
// Add multiple records
|
|
41
|
+
idb.data.set('store', 'products', { id: 1, name: 'Apple', price: 1.5 });
|
|
42
|
+
idb.data.set('store', 'products', { id: 2, name: 'Banana', price: 0.8 });
|
|
43
|
+
|
|
44
|
+
// List databases
|
|
45
|
+
const databases = idb.db.list();
|
|
46
|
+
console.log(databases); // ['myApp', 'store']
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Example 3: Advanced
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
// Check database support
|
|
53
|
+
if (idb.db.support()) {
|
|
54
|
+
// Use IDB
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Get database info
|
|
58
|
+
const version = idb.db.version('store');
|
|
59
|
+
const size = idb.db.size('store');
|
|
60
|
+
|
|
61
|
+
// Delete database
|
|
62
|
+
idb.db.delete('store');
|
|
63
|
+
|
|
64
|
+
// Handle quota
|
|
65
|
+
const quota = idb.db.quota();
|
|
66
|
+
console.log(`Using ${quota.used} of ${quota.total} bytes`);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## API Reference
|
|
72
|
+
|
|
73
|
+
### Database Methods
|
|
74
|
+
|
|
75
|
+
| Method | Parameters | Returns | Description |
|
|
76
|
+
|--------|------------|---------|-------------|
|
|
77
|
+
| `idb.db.create(name)` | `name: string` | `void` | Create database |
|
|
78
|
+
| `idb.db.delete(name)` | `name: string` | `void` | Delete database |
|
|
79
|
+
| `idb.db.list()` | none | `string[]` | List all databases |
|
|
80
|
+
| `idb.db.exist(name)` | `name: string` | `boolean` | Check if exists |
|
|
81
|
+
| `idb.db.size(name)` | `name: string` | `number` | Get database size |
|
|
82
|
+
| `idb.db.version(name)` | `name: string` | `number` | Get version |
|
|
83
|
+
| `idb.db.support()` | none | `boolean` | Check browser support |
|
|
84
|
+
| `idb.db.quota()` | none | `object` | Get storage quota |
|
|
85
|
+
|
|
86
|
+
### Table Methods
|
|
87
|
+
|
|
88
|
+
| Method | Parameters | Returns | Description |
|
|
89
|
+
|--------|------------|---------|-------------|
|
|
90
|
+
| `idb.table.create(db, table)` | `db: string, table: string` | `void` | Create table |
|
|
91
|
+
| `idb.table.size(db, table)` | `db: string, table: string` | `number` | Get table size |
|
|
92
|
+
|
|
93
|
+
### Data Methods
|
|
94
|
+
|
|
95
|
+
| Method | Parameters | Returns | Description |
|
|
96
|
+
|--------|------------|---------|-------------|
|
|
97
|
+
| `idb.data.get(db, table, id)` | `db, table, id` | `any` | Get single record |
|
|
98
|
+
| `idb.data.set(db, table, data)` | `db, table, data` | `void` | Set record |
|
|
99
|
+
| `idb.data.delete(db, table, id)` | `db, table, id` | `void` | Delete record |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Data Structure
|
|
104
|
+
|
|
105
|
+
Each record needs an `id` field:
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
idb.data.set('myDB', 'users', {
|
|
109
|
+
id: 1, // Required!
|
|
110
|
+
name: 'Mario',
|
|
111
|
+
email: 'm@test.com'
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Storage Limits
|
|
118
|
+
|
|
119
|
+
- **Desktop browsers**: 50+ MB (often unlimited)
|
|
120
|
+
- **Mobile browsers**: 50-100 MB
|
|
121
|
+
- **More than localStorage**: Much higher limits
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Best Practices
|
|
126
|
+
|
|
127
|
+
1. Always include `id` in records
|
|
128
|
+
2. Use for large data: images, caches, offline data
|
|
129
|
+
3. Check support: `idb.db.support()`
|
|
130
|
+
4. Clean up: `idb.db.delete('tempDB')`
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Use Cases
|
|
135
|
+
|
|
136
|
+
### Offline Data
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
// Cache API response
|
|
140
|
+
idb.data.set('cache', 'apiResponse', {
|
|
141
|
+
id: 'users',
|
|
142
|
+
data: usersArray,
|
|
143
|
+
timestamp: Date.now()
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Large User Data
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
// Store user-generated content
|
|
151
|
+
idb.data.set('app', 'uploads', {
|
|
152
|
+
id: Date.now(),
|
|
153
|
+
file: fileData,
|
|
154
|
+
userId: currentUser.id
|
|
155
|
+
});
|
|
156
|
+
```
|
package/docs/LOGGER.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Memorio Logger
|
|
2
|
+
|
|
3
|
+
Automatic logging middleware for tracking all state changes in Memorio.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The logger automatically tracks all operations (set, delete, clear) across all modules:
|
|
8
|
+
- State
|
|
9
|
+
- Store
|
|
10
|
+
- Session
|
|
11
|
+
- Cache
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
### configure(options)
|
|
16
|
+
|
|
17
|
+
Configure the logger.
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
memorio.logger.configure({
|
|
21
|
+
enabled: true, // Enable/disable logging
|
|
22
|
+
logToConsole: true, // Log to browser console
|
|
23
|
+
customHandler: function(entry) { ... }, // Custom handler
|
|
24
|
+
modules: ['state', 'store', 'session', 'cache'], // Modules to log
|
|
25
|
+
maxEntries: 1000 // Maximum log history size
|
|
26
|
+
})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### enable()
|
|
30
|
+
|
|
31
|
+
Enable logging.
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
memorio.logger.enable()
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### disable()
|
|
38
|
+
|
|
39
|
+
Disable logging.
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
memorio.logger.disable()
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Methods
|
|
46
|
+
|
|
47
|
+
### getHistory()
|
|
48
|
+
|
|
49
|
+
Get all log entries.
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
const history = memorio.logger.getHistory()
|
|
53
|
+
// Returns array of LogEntry objects
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### getStats()
|
|
57
|
+
|
|
58
|
+
Get statistics about logged operations.
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
const stats = memorio.logger.getStats()
|
|
62
|
+
// Returns: { total, state, store, session, cache, set, get, delete, clear }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### clearHistory()
|
|
66
|
+
|
|
67
|
+
Clear log history.
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
memorio.logger.clearHistory()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### exportLogs()
|
|
74
|
+
|
|
75
|
+
Export logs as JSON string.
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const json = memorio.logger.exportLogs()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Log Entry Structure
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
{
|
|
85
|
+
timestamp: "2026-02-18T12:00:00.000Z",
|
|
86
|
+
module: "state",
|
|
87
|
+
action: "set",
|
|
88
|
+
path: "user.name",
|
|
89
|
+
value: "John",
|
|
90
|
+
previousValue: "Jane"
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Examples
|
|
95
|
+
|
|
96
|
+
### Basic usage
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
// Logging is enabled by default
|
|
100
|
+
state.user = { name: 'John' }
|
|
101
|
+
// Console: [Memorio:STATE] set user → value: { name: 'John' }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Get statistics
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
const stats = memorio.logger.getStats()
|
|
108
|
+
console.log(stats)
|
|
109
|
+
// { total: 15, state: 5, store: 3, session: 2, cache: 5, set: 10, get: 0, delete: 3, clear: 2 }
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Disable specific modules
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
memorio.logger.configure({
|
|
116
|
+
modules: ['state'] // Only log state changes
|
|
117
|
+
})
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Custom handler
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
memorio.logger.configure({
|
|
124
|
+
customHandler: (entry) => {
|
|
125
|
+
// Send to analytics
|
|
126
|
+
analytics.track('memorio_change', entry)
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Export and analyze
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
// Get all logs
|
|
135
|
+
const logs = memorio.logger.getHistory()
|
|
136
|
+
|
|
137
|
+
// Filter by module
|
|
138
|
+
const stateLogs = logs.filter(l => l.module === 'state')
|
|
139
|
+
|
|
140
|
+
// Filter by action
|
|
141
|
+
const setOperations = logs.filter(l => l.action === 'set')
|
|
142
|
+
|
|
143
|
+
// Export for debugging
|
|
144
|
+
console.log(memorio.logger.exportLogs())
|
|
145
|
+
```
|
package/docs/OBSERVER.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Observer - Memorio
|
|
2
|
+
|
|
3
|
+
> ⚠️ **DEPRECATED**: This function is deprecated and will be removed in future versions. Please use [`useObserver`](USEOBSERVER.md) instead.
|
|
4
|
+
|
|
5
|
+
Observer lets you react to state changes. When a state key changes, your callback function runs.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install memorio
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
import 'memorio';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Quick Examples
|
|
20
|
+
|
|
21
|
+
### Example 1: Basic Usage
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
// Simple observer (DEPRECATED - use useObserver instead)
|
|
25
|
+
console.warn('observer() is deprecated. Please use useObserver() for React or memorio.dispatch for vanilla JS.');
|
|
26
|
+
|
|
27
|
+
observer('state.counter', (newValue) => {
|
|
28
|
+
console.log('Counter is now:', newValue);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
state.counter = 1;
|
|
32
|
+
// Output: "Counter is now: 1"
|
|
33
|
+
|
|
34
|
+
state.counter = 5;
|
|
35
|
+
// Output: "Counter is now: 5"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> **Note**: For new projects, use [`useObserver`](USEOBSERVER.md) for React or [`memorio.dispatch`](SUMMARY.md) for vanilla JS.
|
|
39
|
+
|
|
40
|
+
### Example 2: Intermediate
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
// Observer with old value
|
|
44
|
+
observer('state.user', (newValue, oldValue) => {
|
|
45
|
+
console.log(`User changed from ${oldValue?.name} to ${newValue?.name}`);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
state.user = { name: 'Mario' };
|
|
49
|
+
// Output: "User changed from undefined to Mario"
|
|
50
|
+
|
|
51
|
+
state.user = { name: 'Luigi' };
|
|
52
|
+
// Output: "User changed from Mario to Luigi"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Example 3: Advanced
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
// Multiple observers
|
|
59
|
+
const obs1 = observer('state.data', handler1);
|
|
60
|
+
const obs2 = observer('state.data', handler2);
|
|
61
|
+
|
|
62
|
+
// List all observers
|
|
63
|
+
console.log(observer.list);
|
|
64
|
+
// Output: [{ name: 'state.data', id: '...' }, ...]
|
|
65
|
+
|
|
66
|
+
// Remove specific observer
|
|
67
|
+
observer.remove('state.data');
|
|
68
|
+
|
|
69
|
+
// Remove all observers
|
|
70
|
+
observer.removeAll();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## API Reference
|
|
76
|
+
|
|
77
|
+
### observer(path, callback)
|
|
78
|
+
|
|
79
|
+
| Parameter | Type | Description |
|
|
80
|
+
|-----------|------|-------------|
|
|
81
|
+
| `path` | `string` | State path to watch (e.g., `'state.counter'`) |
|
|
82
|
+
| `callback` | `function` | Function called on change |
|
|
83
|
+
|
|
84
|
+
### Callback Parameters
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
observer('state.key', (newValue, oldValue) => {
|
|
88
|
+
// newValue: the new value
|
|
89
|
+
// oldValue: the previous value
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Properties
|
|
94
|
+
|
|
95
|
+
| Property | Type | Description |
|
|
96
|
+
|----------|------|-------------|
|
|
97
|
+
| `observer.list` | `Array` | Get all active observers |
|
|
98
|
+
|
|
99
|
+
### Methods
|
|
100
|
+
|
|
101
|
+
| Method | Parameters | Description |
|
|
102
|
+
|--------|------------|-------------|
|
|
103
|
+
| `observer.remove(name)` | `string` | Remove observer for specific path |
|
|
104
|
+
| `observer.removeAll()` | none | Remove all observers |
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## React Integration
|
|
109
|
+
|
|
110
|
+
### With useState
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
const [count, setCount] = useState(0);
|
|
114
|
+
|
|
115
|
+
observer('state.counter', () => {
|
|
116
|
+
setCount(state.counter);
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### With useEffect
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
const handleChange = (newVal) => {
|
|
125
|
+
console.log('Changed:', newVal);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
observer('state.data', handleChange);
|
|
129
|
+
|
|
130
|
+
// Cleanup
|
|
131
|
+
return () => observer.remove('state.data');
|
|
132
|
+
}, []);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## How It Works
|
|
138
|
+
|
|
139
|
+
Observer subscribes to state changes via the Proxy's set trap. When `state.key = value` is called:
|
|
140
|
+
1. The Proxy intercepts the set
|
|
141
|
+
2. Fires all callbacks registered for that path
|
|
142
|
+
3. Callbacks receive newValue and oldValue
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Best Practices
|
|
147
|
+
|
|
148
|
+
1. Clean up observers in React `useEffect` return
|
|
149
|
+
2. Use specific paths: `'state.user.name'` not `'state'`
|
|
150
|
+
3. Remove observers when components unmount
|
|
151
|
+
4. Use `observer.removeAll()` on page navigation
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Common Patterns
|
|
156
|
+
|
|
157
|
+
### Form Validation
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
observer('state.form.email', (email) => {
|
|
161
|
+
const isValid = email.includes('@');
|
|
162
|
+
state.form.isValid = isValid;
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Analytics
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
observer('state.page', (page) => {
|
|
170
|
+
analytics.track('page_view', { page });
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Auto-save
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
observer('state.draft', (content) => {
|
|
178
|
+
store.set('autosave', content);
|
|
179
|
+
});
|
|
180
|
+
```
|