memorio 4.6.8 → 4.7.0
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/COPYRIGHT.md +6 -0
- package/FUNDING.yml +12 -0
- package/SECURITY.md +48 -0
- package/SUMMARY.md +28 -0
- package/index.cjs +54 -0
- package/index.d.ts +18 -0
- package/index.js +54 -0
- package/llms.txt +405 -0
- package/markdown/CACHE.md +90 -0
- package/markdown/CHANGELOG.md +161 -0
- package/markdown/DEVTOOLS.md +122 -0
- package/markdown/DISPATCH.md +168 -0
- package/markdown/IDB.md +169 -0
- package/markdown/IMPORT.md +139 -0
- package/markdown/LOGGER.md +147 -0
- package/markdown/OBSERVER.md +200 -0
- package/markdown/PLATFORM.md +265 -0
- package/markdown/SECURITY.md +323 -0
- package/markdown/SESSION.md +154 -0
- package/markdown/STATE.md +153 -0
- package/markdown/STORE.md +164 -0
- package/markdown/USEOBSERVER.md +259 -0
- package/package.json +13 -3
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Memorio DevTools
|
|
2
|
+
|
|
3
|
+
> 🖥️ **Browser Only**: This feature is only available in browser console
|
|
4
|
+
|
|
5
|
+
Browser console debugging tools for inspecting and managing Memorio state.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// Load memorio first
|
|
11
|
+
import 'memorio'
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Available Methods
|
|
15
|
+
|
|
16
|
+
### inspect()
|
|
17
|
+
|
|
18
|
+
Inspect all Memorio modules in the console.
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
memorio.devtools.inspect()
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### stats()
|
|
25
|
+
|
|
26
|
+
Get statistics about all modules.
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
memorio.devtools.stats()
|
|
30
|
+
// Returns: { stateKeys, storeKeys, sessionKeys, cacheKeys, idbDatabases, lastUpdate }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### clear(module)
|
|
34
|
+
|
|
35
|
+
Clear data from a specific module.
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
memorio.devtools.clear('state')
|
|
39
|
+
memorio.devtools.clear('store')
|
|
40
|
+
memorio.devtools.clear('session')
|
|
41
|
+
memorio.devtools.clear('cache')
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### clearAll()
|
|
45
|
+
|
|
46
|
+
Clear all Memorio data.
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
memorio.devtools.clearAll()
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### watch(module, path)
|
|
53
|
+
|
|
54
|
+
Watch a specific path for changes.
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
memorio.devtools.watch('state', 'user.name')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### exportData()
|
|
61
|
+
|
|
62
|
+
Export all data as JSON.
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const json = memorio.devtools.exportData()
|
|
66
|
+
console.debug(json)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### importData(jsonString)
|
|
70
|
+
|
|
71
|
+
Import data from JSON.
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
memorio.devtools.importData('{"state":{"key":"value"}}')
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### help()
|
|
78
|
+
|
|
79
|
+
Show help information.
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
memorio.devtools.help()
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Console Shortcuts
|
|
86
|
+
|
|
87
|
+
Memorio provides global shortcuts for quick access:
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
$state // globalThis.state
|
|
91
|
+
$store // globalThis.store
|
|
92
|
+
$session // globalThis.session
|
|
93
|
+
$cache // globalThis.cache
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Examples
|
|
97
|
+
|
|
98
|
+
### Inspect current state
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
memorio.devtools.inspect()
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Export and restore state
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
// Export
|
|
108
|
+
const backup = memorio.devtools.exportData()
|
|
109
|
+
|
|
110
|
+
// Later... import
|
|
111
|
+
memorio.devtools.importData(backup)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Monitor changes
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
// Watch a specific path
|
|
118
|
+
memorio.devtools.watch('state', 'counter')
|
|
119
|
+
|
|
120
|
+
// Now changes will be logged to console
|
|
121
|
+
state.counter = 42 // Console shows: 👁 Change: state.counter = 42
|
|
122
|
+
```
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Dispatch - Memorio
|
|
2
|
+
|
|
3
|
+
> ⚛️ **Vanilla JS**: This is for non-React applications. For React, use [`useObserver`](USEOBSERVER.md).
|
|
4
|
+
|
|
5
|
+
`memorio.dispatch` is an event system for vanilla JavaScript applications. It enables pub/sub patterns without React hooks.
|
|
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 Event Listening
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
// Listen for an event
|
|
25
|
+
memorio.dispatch.listen('my:event', (event) => {
|
|
26
|
+
console.debug('Event triggered:', event.detail);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Trigger the event
|
|
30
|
+
memorio.dispatch.set('my:event', { detail: { data: 'Hello World' } });
|
|
31
|
+
// Output: "Event triggered: { data: 'Hello World' }"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Example 2: State Reactivity (Vanilla JS)
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
// React to state changes without React
|
|
38
|
+
memorio.dispatch.listen('state.counter', (event) => {
|
|
39
|
+
console.debug('Counter is now:', event.detail);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Update state
|
|
43
|
+
state.counter = 1;
|
|
44
|
+
// Output: "Counter is now: 1"
|
|
45
|
+
|
|
46
|
+
state.counter = 5;
|
|
47
|
+
// Output: "Counter is now: 5"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Example 3: Remove Listener
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
// Remove a specific event listener
|
|
54
|
+
memorio.dispatch.remove('my:event');
|
|
55
|
+
|
|
56
|
+
// Or remove all listeners for state changes
|
|
57
|
+
memorio.dispatch.remove('state.user');
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## API Reference
|
|
63
|
+
|
|
64
|
+
### memorio.dispatch.set(name, value)
|
|
65
|
+
|
|
66
|
+
Dispatches a custom event with the specified name and value.
|
|
67
|
+
|
|
68
|
+
| Parameter | Type | Description |
|
|
69
|
+
|-----------|------|-------------|
|
|
70
|
+
| `name` | `string` | Event name (e.g., `'my:event'`, `'state.counter'`) |
|
|
71
|
+
| `value` | `object` | Object with `detail` property (default: `{}`) |
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
memorio.dispatch.set('custom:event', { detail: { data: 'value' } });
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### memorio.dispatch.listen(name, callback)
|
|
78
|
+
|
|
79
|
+
Listens for the specified event and executes the callback when triggered.
|
|
80
|
+
|
|
81
|
+
| Parameter | Type | Description |
|
|
82
|
+
|-----------|------|-------------|
|
|
83
|
+
| `name` | `string` | Event name to listen for |
|
|
84
|
+
| `callback` | `function` | Function called with the event object |
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
memorio.dispatch.listen('state.user', (event) => {
|
|
88
|
+
console.debug('User changed:', event.detail);
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### memorio.dispatch.remove(name)
|
|
93
|
+
|
|
94
|
+
Removes the event listener for the specified event name.
|
|
95
|
+
|
|
96
|
+
| Parameter | Type | Description |
|
|
97
|
+
|-----------|------|-------------|
|
|
98
|
+
| `name` | `string` | Event name to stop listening |
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
memorio.dispatch.remove('state.counter');
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Common Patterns
|
|
107
|
+
|
|
108
|
+
### Form Validation
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
memorio.dispatch.listen('state.form.email', (event) => {
|
|
112
|
+
const email = event.detail;
|
|
113
|
+
const isValid = email.includes('@');
|
|
114
|
+
state.form.isValid = isValid;
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Analytics Tracking
|
|
119
|
+
|
|
120
|
+
```javascript
|
|
121
|
+
memorio.dispatch.listen('state.page', (event) => {
|
|
122
|
+
const page = event.detail;
|
|
123
|
+
analytics.track('page_view', { page });
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Auto-save
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
memorio.dispatch.listen('state.draft', (event) => {
|
|
131
|
+
const content = event.detail;
|
|
132
|
+
store.set('autosave', content);
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Multiple Listeners
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
// Listen for multiple state changes
|
|
140
|
+
memorio.dispatch.listen('state.user', (e) => console.log('User:', e.detail));
|
|
141
|
+
memorio.dispatch.listen('state.settings', (e) => console.log('Settings:', e.detail));
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Migration from observer()
|
|
147
|
+
|
|
148
|
+
The `observer()` Replace it with `memorio.dispatch.listen()`:
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
observer('state.counter', (newValue) => {
|
|
152
|
+
console.debug('Counter:', newValue);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// NEW (recommended for vanilla JS)
|
|
156
|
+
memorio.dispatch.listen('state.counter', (event) => {
|
|
157
|
+
console.debug('Counter:', event.detail);
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Best Practices
|
|
164
|
+
|
|
165
|
+
1. Use specific event names: `'state.user.name'` not `'state'`
|
|
166
|
+
2. Clean up listeners when no longer needed with `memorio.dispatch.remove()`
|
|
167
|
+
3. Use `event.detail` to access the value
|
|
168
|
+
4. For React applications, use [`useObserver`](USEOBSERVER.md) instead
|
package/markdown/IDB.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# IDB - Memorio
|
|
2
|
+
|
|
3
|
+
> 🖥️ **Browser Only**: Requires IndexedDB (not available in Node.js/Deno)
|
|
4
|
+
|
|
5
|
+
IDB provides access to browser IndexedDB for large data storage. Unlike localStorage, IDB can store large amounts of structured data.
|
|
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
|
+
// Create a database
|
|
25
|
+
idb.db.create('myApp');
|
|
26
|
+
|
|
27
|
+
// Add data
|
|
28
|
+
idb.data.set('myApp', 'users', { id: 1, name: 'Mario' });
|
|
29
|
+
|
|
30
|
+
// Get data
|
|
31
|
+
const user = idb.data.get('myApp', 'users', 1);
|
|
32
|
+
console.debug(user.name); // "Mario"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Example 2: Intermediate
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
// Create database with tables
|
|
39
|
+
idb.db.create('store');
|
|
40
|
+
idb.table.create('store', 'products');
|
|
41
|
+
|
|
42
|
+
// Add multiple records
|
|
43
|
+
idb.data.set('store', 'products', { id: 1, name: 'Apple', price: 1.5 });
|
|
44
|
+
idb.data.set('store', 'products', { id: 2, name: 'Banana', price: 0.8 });
|
|
45
|
+
|
|
46
|
+
// List databases
|
|
47
|
+
const databases = idb.db.list();
|
|
48
|
+
console.debug(databases); // ['myApp', 'store']
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Example 3: Advanced
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
// Check database support
|
|
55
|
+
if (idb.db.support()) {
|
|
56
|
+
// Use IDB
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Get database info
|
|
60
|
+
const version = idb.db.version('store');
|
|
61
|
+
const size = idb.db.size('store');
|
|
62
|
+
|
|
63
|
+
// Delete database
|
|
64
|
+
idb.db.delete('store');
|
|
65
|
+
|
|
66
|
+
// Handle quota
|
|
67
|
+
const quota = idb.db.quota();
|
|
68
|
+
console.debug(`Using ${quota.used} of ${quota.total} bytes`);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## API Reference
|
|
74
|
+
|
|
75
|
+
### Database Methods
|
|
76
|
+
|
|
77
|
+
| Method | Parameters | Returns | Description |
|
|
78
|
+
|--------|------------|---------|-------------|
|
|
79
|
+
| `idb.db.create(name)` | `name: string` | `void` | Create database |
|
|
80
|
+
| `idb.db.delete(name)` | `name: string` | `void` | Delete database |
|
|
81
|
+
| `idb.db.list()` | none | `string[]` | List all databases |
|
|
82
|
+
| `idb.db.exist(name)` | `name: string` | `boolean` | Check if exists |
|
|
83
|
+
| `idb.db.size(name)` | `name: string` | `number` | Get database size |
|
|
84
|
+
| `idb.db.version(name)` | `name: string` | `number` | Get version |
|
|
85
|
+
| `idb.db.support()` | none | `boolean` | Check browser support |
|
|
86
|
+
| `idb.db.quota()` | none | `object` | Get storage quota |
|
|
87
|
+
|
|
88
|
+
### Table Methods
|
|
89
|
+
|
|
90
|
+
| Method | Parameters | Returns | Description |
|
|
91
|
+
|--------|------------|---------|-------------|
|
|
92
|
+
| `idb.table.create(db, table)` | `db: string, table: string` | `void` | Create table |
|
|
93
|
+
| `idb.table.size(db, table)` | `db: string, table: string` | `number` | Get table size |
|
|
94
|
+
|
|
95
|
+
### Data Methods
|
|
96
|
+
|
|
97
|
+
| Method | Parameters | Returns | Description |
|
|
98
|
+
|--------|------------|---------|-------------|
|
|
99
|
+
| `idb.data.get(db, table, id)` | `db, table, id` | `any` | Get single record |
|
|
100
|
+
| `idb.data.set(db, table, data)` | `db, table, data` | `void` | Set record |
|
|
101
|
+
| `idb.data.delete(db, table, id)` | `db, table, id` | `void` | Delete record |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Data Structure
|
|
106
|
+
|
|
107
|
+
Each record needs an `id` field:
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
idb.data.set('myDB', 'users', {
|
|
111
|
+
id: 1, // Required!
|
|
112
|
+
name: 'Mario',
|
|
113
|
+
email: 'm@test.com'
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Platform Support
|
|
120
|
+
|
|
121
|
+
| Platform | Support | Notes |
|
|
122
|
+
|----------|---------|-------|
|
|
123
|
+
| Browser | ✅ Full | Full IndexedDB support |
|
|
124
|
+
| Edge Worker | ⚠️ Limited | May not be available in all workers |
|
|
125
|
+
| Node.js | ❌ Not available | Use store or session instead |
|
|
126
|
+
| Deno | ❌ Not available | Use store or session instead |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Storage Limits
|
|
131
|
+
|
|
132
|
+
- **Desktop browsers**: 50+ MB (often unlimited)
|
|
133
|
+
- **Mobile browsers**: 50-100 MB
|
|
134
|
+
- **More than localStorage**: Much higher limits
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Best Practices
|
|
139
|
+
|
|
140
|
+
1. Always include `id` in records
|
|
141
|
+
2. Use for large data: images, caches, offline data
|
|
142
|
+
3. Check support: `idb.db.support()`
|
|
143
|
+
4. Clean up: `idb.db.delete('tempDB')`
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Use Cases
|
|
148
|
+
|
|
149
|
+
### Offline Data
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
// Cache API response
|
|
153
|
+
idb.data.set('cache', 'apiResponse', {
|
|
154
|
+
id: 'users',
|
|
155
|
+
data: usersArray,
|
|
156
|
+
timestamp: Date.now()
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Large User Data
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
// Store user-generated content
|
|
164
|
+
idb.data.set('app', 'uploads', {
|
|
165
|
+
id: Date.now(),
|
|
166
|
+
file: fileData,
|
|
167
|
+
userId: currentUser.id
|
|
168
|
+
});
|
|
169
|
+
```
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Classic `import` support
|
|
2
|
+
|
|
3
|
+
Memorio supports two equivalent styles: the original global side-effect import,
|
|
4
|
+
and the new named exports. Both share the same instances (one source of truth).
|
|
5
|
+
|
|
6
|
+
```typescript
|
|
7
|
+
// Global style (original)
|
|
8
|
+
import 'memorio'
|
|
9
|
+
state.user = { name: 'Sara' }
|
|
10
|
+
|
|
11
|
+
// Classic import style (new)
|
|
12
|
+
import { state } from 'memorio'
|
|
13
|
+
state.user = { name: 'Sara' }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`state` in both examples is the exact same Proxy object.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Why two styles?
|
|
21
|
+
|
|
22
|
+
| Style | When to use |
|
|
23
|
+
|-------|-------------|
|
|
24
|
+
| `import 'memorio'` | Zero-config, global access everywhere, legacy scripts |
|
|
25
|
+
| `import { state } from 'memorio'` | Explicit dependencies, tree-shakeable bundles, TypeScript IntelliSense |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## ESM named imports
|
|
30
|
+
|
|
31
|
+
All modules are available as named exports:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import {
|
|
35
|
+
state,
|
|
36
|
+
store,
|
|
37
|
+
session,
|
|
38
|
+
cache,
|
|
39
|
+
idb,
|
|
40
|
+
observer,
|
|
41
|
+
useObserver,
|
|
42
|
+
dispatch,
|
|
43
|
+
message,
|
|
44
|
+
devtools,
|
|
45
|
+
logger
|
|
46
|
+
} from 'memorio'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Platform helpers:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import {
|
|
53
|
+
isBrowser,
|
|
54
|
+
isNode,
|
|
55
|
+
isDeno,
|
|
56
|
+
isEdge,
|
|
57
|
+
getCapabilities,
|
|
58
|
+
createContext,
|
|
59
|
+
listContexts,
|
|
60
|
+
deleteContext
|
|
61
|
+
} from 'memorio'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Internal utilities (for tests/debug):
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import internal, { propertyName } from 'memorio'
|
|
68
|
+
import { setContext, getContext } from 'memorio'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Default export (the public `memorio` namespace):
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import memorio from 'memorio'
|
|
75
|
+
memorio.help()
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## CJS usage
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
const { state, store, memorio } = require('memorio')
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## React / useObserver
|
|
89
|
+
|
|
90
|
+
`useObserver` works the same way via named import:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { useObserver, state } from 'memorio'
|
|
94
|
+
|
|
95
|
+
function Counter() {
|
|
96
|
+
const [, forceUpdate] = useReducer(x => x + 1, 0)
|
|
97
|
+
|
|
98
|
+
useObserver(forceUpdate, [state.counter])
|
|
99
|
+
|
|
100
|
+
return <div>Count: {state.counter}</div>
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Context isolation
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { createContext, listContexts, deleteContext, isolate } from 'memorio'
|
|
110
|
+
|
|
111
|
+
const ctx = createContext('tenant-123')
|
|
112
|
+
ctx.state.user = { name: 'Isolated' }
|
|
113
|
+
ctx.store.set('settings', { theme: 'dark' })
|
|
114
|
+
|
|
115
|
+
listContexts() // ['tenant-123']
|
|
116
|
+
deleteContext('tenant-123')
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Same-instance guarantee
|
|
122
|
+
|
|
123
|
+
Named exports point to the same instances published on `globalThis` by
|
|
124
|
+
`core/global` at bootstrap. Mutating via named export mutates the global,
|
|
125
|
+
and vice versa.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { state } from 'memorio'
|
|
129
|
+
|
|
130
|
+
state.importedFlag = true
|
|
131
|
+
console.debug(globalThis.state.importedFlag) // true
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Migration from global-only
|
|
137
|
+
|
|
138
|
+
No code changes required. Existing `import 'memorio'` + `state.foo = 1`
|
|
139
|
+
continues to work unchanged. Named exports are additive.
|