memorio 5.0.0 → 5.1.1
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/README.md +98 -435
- package/SECURITY.md +152 -42
- package/SUMMARY.md +1 -1
- package/adr/001-state-proxy-model.md +95 -96
- package/adr/002-observer-semantics.md +179 -180
- package/adr/003-deep-mutation-semantics.md +7 -8
- package/adr/004-array-mutation-semantics.md +127 -128
- package/adr/005-scheduler-contract.md +148 -149
- package/adr/006-context-isolation.md +91 -92
- package/adr/007-mutation-records.md +5 -6
- package/adr/008-transactions.md +6 -7
- package/adr/009-history-model.md +6 -7
- package/adr/README.md +46 -46
- package/adr/template.md +48 -49
- package/bin/cli.js +68 -0
- package/global.cjs +1462 -323
- package/global.js +1459 -324
- package/index.cjs +1462 -323
- package/index.d.ts +1 -0
- package/index.js +1459 -324
- package/llms.txt +42 -5
- package/markdown/AUDIT-REPORT.md +7 -8
- package/markdown/CACHE.md +190 -99
- package/markdown/DEVTOOLS.md +0 -1
- package/markdown/DISPATCH.md +0 -1
- package/markdown/HISTORY.md +0 -1
- package/markdown/IDB.md +0 -1
- package/markdown/IMPORT.md +0 -1
- package/markdown/INSPECT.md +0 -1
- package/markdown/LOGGER.md +0 -1
- package/markdown/MEMORY-ATTACHMENT.md +0 -1
- package/markdown/MEMORY.md +0 -1
- package/markdown/OBSERVER.md +0 -1
- package/markdown/PLATFORM.md +277 -271
- package/markdown/REDUX.md +54 -0
- package/markdown/SCHEMA.md +0 -1
- package/markdown/SESSION.md +0 -1
- package/markdown/SQLITE.md +0 -1
- package/markdown/STATE.md +0 -1
- package/markdown/STORE.md +0 -1
- package/markdown/SYNC.md +0 -1
- package/markdown/TYPED.md +0 -1
- package/markdown/USEOBSERVER.md +0 -1
- package/modules/redux.cjs +381 -10
- package/modules/redux.cjs.map +1 -1
- package/modules/redux.js +381 -10
- package/modules/redux.js.map +1 -1
- package/package.json +14 -2
- package/types/broadcast.d.ts +61 -0
- package/types/computed.d.ts +96 -0
- package/types/encryption.d.ts +129 -0
- package/types/exports.d.ts +9 -0
- package/types/memorio.d.ts +19 -12
- package/types/security.d.ts +67 -0
- package/types/session.d.ts +23 -5
- package/types/store.d.ts +19 -3
- package/vsix/memorio.vsix +0 -0
- package/markdown/CHANGELOG.md +0 -243
- package/markdown/PROJECT.md +0 -311
- package/markdown/SECURITY.md +0 -330
package/llms.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
**Memorio** is
|
|
5
|
+
**Memorio** is the memory layer for AI agents and apps - owned by the user, not the vendor. It manages application state, remembers how it changed, understands causal relationships, enables deterministic replay, and can simulate the impact of future changes. It provides reactive state, persistence, observation, and optional AES-GCM encryption capabilities with zero production dependencies. It works in Node.js, Deno, browsers, and edge environments.
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
npm i memorio
|
|
@@ -21,8 +21,10 @@ Memorio provides 6 storage modules plus utilities:
|
|
|
21
21
|
| `session` | sessionStorage | Dies with browser tab; falls back to non-durable in-memory `Map` in Node.js/Deno |
|
|
22
22
|
| `cache` | In-memory cache | Fastest read, no persistence |
|
|
23
23
|
| `idb` | IndexedDB | Structured, async, persistent (browser-only - disabled in Node.js/Deno) |
|
|
24
|
+
| `sqlite` | SQLite via sql.js (WebAssembly) | Browser-only relational SQL |
|
|
24
25
|
| `observer` | Object watcher | Legacy; string-based paths, not statically checked against `state`'s shape |
|
|
25
26
|
| `useObserver` | React hook | Auto-discovery of state paths |
|
|
27
|
+
| `encryption` | AES-GCM + PBKDF2 | Encrypt/decrypt values, store/session integration |
|
|
26
28
|
|
|
27
29
|
## Quick Start
|
|
28
30
|
|
|
@@ -349,23 +351,58 @@ By default, `state` is a **shared global namespace** - a value set in one place
|
|
|
349
351
|
To isolate a slice of state (e.g. per tenant, per request), create an explicit context:
|
|
350
352
|
|
|
351
353
|
```javascript
|
|
354
|
+
// Basic context: namespace isolation via key prefixes
|
|
352
355
|
const ctx = memorio.createContext('tenant-name')
|
|
353
356
|
ctx.state.user = { name: 'Isolated' }
|
|
354
357
|
|
|
355
358
|
console.debug(state.user) // undefined - separate namespace from ctx.state
|
|
356
359
|
|
|
357
|
-
|
|
358
|
-
memorio.
|
|
359
|
-
memorio.
|
|
360
|
+
// Encrypted context: namespace + cryptographic isolation
|
|
361
|
+
const key = await memorio.encryption.deriveKey('tenant-password', 'tenant-salt')
|
|
362
|
+
const ctx = memorio.createContext('tenant-name', { encryptionKey: key })
|
|
363
|
+
await ctx.store.set('secrets', { apiKey: 'sk-12345' }) // encrypted at rest
|
|
364
|
+
const secrets = await ctx.store.get('secrets') // decrypted on read
|
|
360
365
|
```
|
|
361
366
|
|
|
362
367
|
Isolation is implemented as a **key-prefix convention** inside the same underlying storage, not a hard memory or process boundary. In a shared Node.js process or an edge isolate that may be reused across requests:
|
|
363
368
|
|
|
364
369
|
- generate context IDs from trusted server-side data, never directly from client-controlled input, to prevent collisions or spoofing;
|
|
365
370
|
- don't treat this as your only isolation layer for data that must not cross tenants - enforce that at the process/request level as well.
|
|
371
|
+
- when encryption is enabled on a context, encrypted values provide a cryptographic wall on top of the namespace prefix, but key management is your responsibility.
|
|
366
372
|
|
|
367
373
|
`getCapabilities().sessionId` provides a per-session identifier for browser contexts but is not itself an isolation mechanism - use `createContext` for that.
|
|
368
374
|
|
|
375
|
+
### `memorio.encryption` - Encryption (opt-in)
|
|
376
|
+
|
|
377
|
+
Built on the Web Crypto API (`crypto.subtle`). AES-GCM for authenticated encryption, PBKDF2 for password-based key derivation. Works in browsers, Node.js 18+, Deno 1.13+, and modern edge runtimes.
|
|
378
|
+
|
|
379
|
+
```javascript
|
|
380
|
+
// Derive a key from a password (PBKDF2, 600k iterations - NIST SP 800-132)
|
|
381
|
+
const key = await memorio.encryption.deriveKey('password', 'salt')
|
|
382
|
+
|
|
383
|
+
// Or generate a random key
|
|
384
|
+
const key = await memorio.encryption.generateKey()
|
|
385
|
+
|
|
386
|
+
// Encrypt/decrypt
|
|
387
|
+
const envelope = await memorio.encryption.encrypt({ secret: 'value' }, key)
|
|
388
|
+
const original = await memorio.encryption.decrypt(envelope, key)
|
|
389
|
+
|
|
390
|
+
// Password-based convenience (returns JSON string, for direct persistence)
|
|
391
|
+
const json = await memorio.encryption.encryptWithPassword(value, 'password', 'salt')
|
|
392
|
+
const decrypted = await memorio.encryption.decryptWithPassword(json, 'password', 'salt')
|
|
393
|
+
|
|
394
|
+
// Store-level encryption
|
|
395
|
+
await store.set('api_token', secret, { encrypt: key })
|
|
396
|
+
await store.get('api_token', { decrypt: key })
|
|
397
|
+
|
|
398
|
+
// Or configure a default key for transparent encryption
|
|
399
|
+
store.config({ encryptionKey: key })
|
|
400
|
+
await store.set('api_token', secret) // encrypted automatically
|
|
401
|
+
const token = store.get('api_token') // decrypted automatically (returns a Promise)
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
> Encryption is **opt-in** - no layer encrypts by default. Key management is the application's responsibility. Never hardcode keys in client bundles.
|
|
405
|
+
|
|
369
406
|
### `memorio.typed<T>()` - Typed Store (compile-time safety)
|
|
370
407
|
|
|
371
408
|
Returns the global `state` proxy cast to type `T`. The same Proxy instance - no overhead. Use for TypeScript autocomplete and static type checking.
|
|
@@ -520,7 +557,7 @@ memorio.stateSchema() // [{ path, type, defined }, ...] - full tree report
|
|
|
520
557
|
- No `eval`, no dynamic code execution, no obfuscation, no hardcoded secrets.
|
|
521
558
|
- Inputs validated, keys sanitized before use.
|
|
522
559
|
- Secure random session IDs via `crypto.randomUUID`.
|
|
523
|
-
- Data in `store`, `session`, and `idb` is **not encrypted** - these are thin wrappers over browser storage APIs that persist data in the clear on the user's device.
|
|
560
|
+
- Data in `store`, `session`, and `idb` is **not encrypted by default** - these are thin wrappers over browser storage APIs that persist data in the clear on the user's device. For sensitive data (tokens, secrets, PII), use `memorio.encryption` (AES-GCM + PBKDF2) to encrypt before persisting, or enable auto-encrypt via `store.config({ encryptionKey })` / `createContext(id, { encryptionKey })`. Key management is the application's responsibility.
|
|
524
561
|
|
|
525
562
|
Engineering practices are informed by recognized guidance (e.g. NIST SP 800-53 practices) as a design input - this is a statement about how the library is built, not a compliance certification, and no third-party audit has been performed. Report security issues privately (see `SECURITY.md`) rather than in a public issue.
|
|
526
563
|
|
package/markdown/AUDIT-REPORT.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
> **Status:** Accepted
|
|
2
2
|
> **Date:** 2026-09-12
|
|
3
|
-
> **
|
|
4
|
-
> **
|
|
5
|
-
> **Standard**: NIST SP 800-53, OWASP ASVS, NSA Cybersecurity Guidelines
|
|
3
|
+
> **Scope**: Internal self-audit - Security, Performance, Reliability, Code Quality
|
|
4
|
+
> **Note**: This is a self-conducted audit, not a certified third-party assessment. No claim of conformance to any external standard (NIST, OWASP, NSA, etc.) is made or implied.
|
|
6
5
|
>
|
|
7
6
|
---
|
|
8
|
-
# Audit Report - Memorio
|
|
7
|
+
# Audit Report - Memorio v5.1.0
|
|
9
8
|
|
|
10
9
|
## 1. Security Audit
|
|
11
10
|
|
|
@@ -81,12 +80,12 @@
|
|
|
81
80
|
## 5. Documentation Audit
|
|
82
81
|
|
|
83
82
|
### Actions Taken
|
|
84
|
-
- **Merged changelogs**: Combined `.project/CHANGELOG.md` (
|
|
85
|
-
- **Updated version references**: Changed v3.0.2 →
|
|
83
|
+
- **Merged changelogs**: Combined `.project/CHANGELOG.md` (v5.1.0 detailed) into `.project/markdown/CHANGELOG.md`
|
|
84
|
+
- **Updated version references**: Changed v3.0.2 → v5.1.0 throughout
|
|
86
85
|
- **Updated stack**: Jest → vitest, `config/` → `core/`
|
|
87
86
|
- **Removed `__DEV__` mentions**: All documentation comments updated
|
|
88
87
|
- **Added "Module deduplication strategy"** section to `docs/README.md`
|
|
89
|
-
- **Updated CHANGELOG** with
|
|
88
|
+
- **Updated CHANGELOG** with v5.1.0 entry documenting all fixes
|
|
90
89
|
|
|
91
90
|
---
|
|
92
91
|
|
|
@@ -129,7 +128,7 @@
|
|
|
129
128
|
| `types/env.d.ts` | Removed `__DEV__` from comments |
|
|
130
129
|
| `.oxlintrc.json` | New lint configuration |
|
|
131
130
|
| `tsup.config.ts` | Disabled minification + enabled sourcemaps to avoid socket.dev false positives |
|
|
132
|
-
| `.project/markdown/CHANGELOG.md` | Merged changelogs, added
|
|
131
|
+
| `.project/markdown/CHANGELOG.md` | Merged changelogs, added v5.1.0 entry |
|
|
133
132
|
| `.project/markdown/PROJECT.md` | Updated version, stack, structure (was memorio.md) |
|
|
134
133
|
| `docs/README.md` | Added module deduplication strategy section |
|
|
135
134
|
| `tests/scripts/update-node-modules-memorio.cjs` | New deploy script for user app |
|
package/markdown/CACHE.md
CHANGED
|
@@ -1,100 +1,191 @@
|
|
|
1
|
-
> **Status:** Published
|
|
2
|
-
> **Date:** 2026-09-12
|
|
3
|
-
> **
|
|
4
|
-
> **
|
|
5
|
-
>
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
> **Status:** Published
|
|
2
|
+
> **Date:** 2026-09-12
|
|
3
|
+
> **Scope**: API Reference
|
|
4
|
+
> **Standard**: Memorio API Specification v5
|
|
5
|
+
>
|
|
6
|
+
---
|
|
7
|
+
|
|
8
8
|
# Cache - Memorio
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
> ✅ **Universal**: Works in Browser, Node.js, Deno, and Edge Workers
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Cache provides in-memory storage with a simple API. Data is lost on page refresh or process restart.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
|
|
25
|
+
npm install memorio
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
|
|
33
|
+
import { cache } from 'memorio';
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
> **Classic `import`**: `cache` is also available via the global entrypoint.
|
|
40
|
+
|
|
41
|
+
> `import 'memorio/global'` exposes the same instance as `globalThis.cache`.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Quick Examples
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
### Example 1: Basic Usage
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
|
|
59
|
+
// Save data
|
|
60
|
+
|
|
61
|
+
cache.set('username', 'Mario');
|
|
62
|
+
|
|
63
|
+
cache.set('score', 1500);
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
// Read data
|
|
68
|
+
|
|
69
|
+
console.debug(cache.get('username')); // "Mario"
|
|
70
|
+
|
|
71
|
+
console.debug(cache.get('score')); // 1500
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
### Example 2: Intermediate
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
|
|
83
|
+
// Store objects
|
|
84
|
+
|
|
85
|
+
cache.set('user', { name: 'Luigi', level: 5 });
|
|
86
|
+
|
|
87
|
+
const user = cache.get('user');
|
|
88
|
+
|
|
89
|
+
console.debug(user.name); // "Luigi"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
// Remove single item
|
|
94
|
+
|
|
95
|
+
cache.remove('username');
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
// Clear all cache
|
|
100
|
+
|
|
101
|
+
cache.removeAll();
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
## API Reference
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
### Methods
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
| Method | Parameters | Returns | Description |
|
|
120
|
+
|
|
121
|
+
|--------|------------|---------|-------------|
|
|
122
|
+
|
|
123
|
+
| `cache.get(name)` | `name: string` | `any` | Get value from cache |
|
|
124
|
+
|
|
125
|
+
| `cache.set(name, value)` | `name: string, value: any` | `void` | Save value to cache |
|
|
126
|
+
|
|
127
|
+
| `cache.remove(name)` | `name: string` | `boolean` | Remove single item |
|
|
128
|
+
|
|
129
|
+
| `cache.removeAll()` | `none` | `boolean` | Clear all cache |
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
## Storage Comparison
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
| Feature | Cache | Store | Session | IDB |
|
|
142
|
+
|
|
143
|
+
|---------|-------|-------|---------|-----|
|
|
144
|
+
|
|
145
|
+
| Platform Support | All (universal) | Browser/Edge | Browser/Edge | Browser only |
|
|
146
|
+
|
|
147
|
+
| Lifetime | Until refresh | Forever | Until tab closes | Forever |
|
|
148
|
+
|
|
149
|
+
| Capacity | Unlimited | ~5-10 MB | ~5-10 MB | 50+ MB |
|
|
150
|
+
|
|
151
|
+
| Use case | Temporary data | User preferences | Auth tokens | Large data |
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
## Platform Support
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
| Platform | Support | Notes |
|
|
164
|
+
|
|
165
|
+
|----------|---------|-------|
|
|
166
|
+
|
|
167
|
+
| Browser | ✅ Full | In-memory, lost on refresh |
|
|
168
|
+
|
|
169
|
+
| Node.js | ✅ Full | In-memory, lost on restart |
|
|
170
|
+
|
|
171
|
+
| Deno | ✅ Full | In-memory, lost on restart |
|
|
172
|
+
|
|
173
|
+
| Edge Workers | ✅ Full | In-memory, lost on function cold start |
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
## Best Practices
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
1. Use for temporary data that doesn't need persistence
|
|
186
|
+
|
|
187
|
+
2. Great for computed values or API response caching
|
|
188
|
+
|
|
189
|
+
3. Data is lost on page refresh - don't use for important data
|
|
190
|
+
|
|
191
|
+
4. Clear with `cache.removeAll()` when no longer needed
|
package/markdown/DEVTOOLS.md
CHANGED
package/markdown/DISPATCH.md
CHANGED
package/markdown/HISTORY.md
CHANGED
package/markdown/IDB.md
CHANGED
package/markdown/IMPORT.md
CHANGED
package/markdown/INSPECT.md
CHANGED
package/markdown/LOGGER.md
CHANGED
package/markdown/MEMORY.md
CHANGED