memorio 4.9.35 → 5.1.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.
Files changed (82) hide show
  1. package/AGENTS.md +3 -3
  2. package/README.md +95 -516
  3. package/SECURITY.md +159 -33
  4. package/SUMMARY.md +59 -45
  5. package/adr/001-state-proxy-model.md +95 -0
  6. package/adr/002-observer-semantics.md +179 -0
  7. package/adr/003-deep-mutation-semantics.md +128 -0
  8. package/adr/004-array-mutation-semantics.md +127 -0
  9. package/adr/005-scheduler-contract.md +148 -0
  10. package/adr/006-context-isolation.md +91 -0
  11. package/adr/007-mutation-records.md +117 -0
  12. package/adr/008-transactions.md +105 -0
  13. package/adr/009-history-model.md +109 -0
  14. package/adr/README.md +46 -0
  15. package/adr/template.md +48 -0
  16. package/bin/cli.js +68 -0
  17. package/examples/basic.ts +115 -115
  18. package/examples/browser-vanilla.html +358 -358
  19. package/examples/cache.ts +72 -72
  20. package/examples/cross-platform-guards.ts +57 -57
  21. package/examples/history.ts +104 -0
  22. package/examples/idb.ts +109 -109
  23. package/examples/multi-tenant-context.ts +44 -44
  24. package/examples/node-server.ts +308 -308
  25. package/examples/observer.ts +60 -60
  26. package/examples/platform.ts +115 -115
  27. package/examples/react-app.tsx +362 -362
  28. package/examples/react-observer.tsx +63 -63
  29. package/examples/semantic-memory.ts +60 -60
  30. package/examples/session-advanced.ts +91 -91
  31. package/examples/sqlite-batched-writes.ts +57 -57
  32. package/examples/state-advanced.ts +89 -89
  33. package/examples/store-advanced.ts +117 -117
  34. package/examples/sync.ts +90 -0
  35. package/examples/typed-and-schema.ts +102 -100
  36. package/examples/useObserver.tsx +140 -141
  37. package/global.cjs +5733 -0
  38. package/global.d.ts +8 -0
  39. package/global.js +5667 -0
  40. package/index.cjs +2202 -1041
  41. package/index.d.ts +2 -0
  42. package/index.js +2178 -1040
  43. package/llms.txt +113 -8
  44. package/markdown/AUDIT-REPORT.md +134 -0
  45. package/markdown/CACHE.md +191 -0
  46. package/markdown/DEVTOOLS.md +128 -0
  47. package/markdown/DISPATCH.md +176 -0
  48. package/markdown/HISTORY.md +198 -0
  49. package/markdown/IDB.md +177 -0
  50. package/markdown/IMPORT.md +152 -0
  51. package/markdown/INSPECT.md +122 -0
  52. package/markdown/LOGGER.md +153 -0
  53. package/markdown/MEMORY-ATTACHMENT.md +95 -0
  54. package/markdown/MEMORY.md +161 -0
  55. package/markdown/OBSERVER.md +208 -0
  56. package/markdown/PLATFORM.md +277 -0
  57. package/markdown/REDUX.md +54 -0
  58. package/markdown/SCHEMA.md +175 -0
  59. package/markdown/SESSION.md +164 -0
  60. package/markdown/SQLITE.md +189 -0
  61. package/markdown/STATE.md +159 -0
  62. package/markdown/STORE.md +170 -0
  63. package/markdown/SYNC.md +318 -0
  64. package/markdown/TYPED.md +164 -0
  65. package/markdown/USEOBSERVER.md +256 -0
  66. package/modules/redux.cjs +701 -177
  67. package/modules/redux.cjs.map +1 -1
  68. package/modules/redux.js +701 -177
  69. package/modules/redux.js.map +1 -1
  70. package/package.json +26 -4
  71. package/types/broadcast.d.ts +61 -0
  72. package/types/computed.d.ts +96 -0
  73. package/types/encryption.d.ts +129 -0
  74. package/types/env.d.ts +19 -9
  75. package/types/exports.d.ts +29 -0
  76. package/types/history.d.ts +13 -1
  77. package/types/memorio.d.ts +25 -6
  78. package/types/mutation.d.ts +75 -0
  79. package/types/security.d.ts +67 -0
  80. package/types/session.d.ts +23 -5
  81. package/types/store.d.ts +19 -3
  82. package/vsix/memorio.vsix +0 -0
@@ -0,0 +1,122 @@
1
+ > **Status:** Published
2
+ > **Date:** 2026-09-12
3
+ > **Scope**: API Reference
4
+ > **Standard**: Memorio API Specification v5
5
+ >
6
+ ---
7
+ # Introspection & Inspection - Memorio
8
+
9
+ > ✅ **Universal**: Works in Browser, Node.js, Deno, and Edge Workers
10
+
11
+ Introspection utilities let you programmatically discover, verify, and read the shape of the global `state` proxy. Essential for AI agents that need to check whether a path exists before writing, or enumerate available keys before reading.
12
+
13
+ ---
14
+
15
+ ## stateKeys()
16
+
17
+ Returns all top-level keys currently on the `state` proxy. Excludes internal properties.
18
+
19
+ ```javascript
20
+ import { state, memorio } from 'memorio'
21
+
22
+ state.user = { name: 'Sara' }
23
+ state.counter = 42
24
+
25
+ memorio.stateKeys() // ['user', 'counter']
26
+ ```
27
+
28
+ ---
29
+
30
+ ## pathExists(path)
31
+
32
+ Checks whether a dotted path exists in state. Returns `true` if the path resolves to a non-undefined value.
33
+
34
+ ```javascript
35
+ state.user = { name: 'Sara', profile: { age: 30 } }
36
+
37
+ memorio.pathExists('user') // true
38
+ memorio.pathExists('user.name') // true
39
+ memorio.pathExists('user.profile') // true
40
+ memorio.pathExists('user.profile.age') // true
41
+ memorio.pathExists('user.age') // false
42
+ memorio.pathExists('nonexistent') // false
43
+ ```
44
+
45
+ This is critical for AI agents: always check `pathExists` before writing to a nested path to avoid creating unintended intermediate objects.
46
+
47
+ ---
48
+
49
+ ## stateType(path)
50
+
51
+ Returns the runtime type of the value at a given state path.
52
+
53
+ ```javascript
54
+ state.count = 42
55
+ state.name = 'Sara'
56
+ state.items = [1, 2, 3]
57
+
58
+ memorio.stateType('count') // 'number'
59
+ memorio.stateType('name') // 'string'
60
+ memorio.stateType('items') // 'array'
61
+ memorio.stateType('missing') // 'undefined'
62
+ ```
63
+
64
+ ---
65
+
66
+ ## stateGet(path)
67
+
68
+ Returns the value at a dotted path, deep-cloned to prevent accidental mutation of state.
69
+
70
+ ```javascript
71
+ state.user = { name: 'Sara', tags: ['admin'] }
72
+
73
+ const user = memorio.stateGet('user') // { name: 'Sara', tags: ['admin'] }
74
+ user.name = 'Luigi' // mutates the clone, not state
75
+ state.user.name // still 'Sara'
76
+ ```
77
+
78
+ ---
79
+
80
+ ## stateSchema()
81
+
82
+ Generates a full schema report of the current state tree - every path with its type and whether it's defined.
83
+
84
+ ```javascript
85
+ state.user = { name: 'Sara', age: 30 }
86
+ state.theme = 'dark'
87
+
88
+ memorio.stateSchema()
89
+ // [
90
+ // { path: 'user', type: 'object', defined: true },
91
+ // { path: 'user.name', type: 'string', defined: true },
92
+ // { path: 'user.age', type: 'number', defined: true },
93
+ // { path: 'theme', type: 'string', defined: true }
94
+ // ]
95
+ ```
96
+
97
+ This is the **most useful for AI agents** - it gives a complete picture of what's in state and what types the values are, in a single call. Perfect for:
98
+ - Discovering available state before generating code
99
+ - Validating that expected paths exist
100
+ - Understanding the shape of nested objects
101
+
102
+ ---
103
+
104
+ ## Full API
105
+
106
+ | Method | Parameters | Returns | Description |
107
+ |--------|-----------|---------|-------------|
108
+ | `memorio.stateKeys()` | none | `string[]` | Top-level state keys |
109
+ | `memorio.pathExists(path)` | `string` | `boolean` | Whether a path resolves to a value |
110
+ | `memorio.stateType(path)` | `string` | `string` | Runtime type at path |
111
+ | `memorio.stateGet(path)` | `string` | `any` | Deep-cloned value at path |
112
+ | `memorio.stateSchema()` | none | `SchemaEntry[]` | Full state tree report |
113
+
114
+ ---
115
+
116
+ ## How It Works
117
+
118
+ All introspection functions read from the global `state` proxy via `deepRaw()` - the same function used internally by the state proxy to unwrap itself before storing. This ensures consistent, non-proxied values are returned.
119
+
120
+ - `pathExists` and `stateGet` split the path on `.` and traverse the state tree.
121
+ - `stateSchema` recursively walks the state object, collecting every path and its type.
122
+ - All returned values from `stateGet` and `snapshot` are deep clones (via JSON round-trip) to prevent accidental mutation.
@@ -0,0 +1,153 @@
1
+ > **Status:** Published
2
+ > **Date:** 2026-09-12
3
+ > **Scope**: API Reference
4
+ > **Standard**: Memorio API Specification v5
5
+ >
6
+ ---
7
+ # Memorio Logger
8
+
9
+ > 🖥️ **Browser Only**: This feature is only available in browser console
10
+
11
+ Automatic logging middleware for tracking all state changes in Memorio.
12
+
13
+ ## Overview
14
+
15
+ The logger automatically tracks all operations (set, delete, clear) across all modules:
16
+ - State
17
+ - Store
18
+ - Session
19
+ - Cache
20
+
21
+ ## Configuration
22
+
23
+ ### configure(options)
24
+
25
+ Configure the logger.
26
+
27
+ ```javascript
28
+ memorio.logger.configure({
29
+ enabled: true, // Enable/disable logging
30
+ logToConsole: true, // Log to browser console
31
+ customHandler: function(entry) { ... }, // Custom handler
32
+ modules: ['state', 'store', 'session', 'cache'], // Modules to log
33
+ maxEntries: 1000 // Maximum log history size
34
+ })
35
+ ```
36
+
37
+ ### enable()
38
+
39
+ Enable logging.
40
+
41
+ ```javascript
42
+ memorio.logger.enable()
43
+ ```
44
+
45
+ ### disable()
46
+
47
+ Disable logging.
48
+
49
+ ```javascript
50
+ memorio.logger.disable()
51
+ ```
52
+
53
+ ## Methods
54
+
55
+ ### getHistory()
56
+
57
+ Get all log entries.
58
+
59
+ ```javascript
60
+ const history = memorio.logger.getHistory()
61
+ // Returns array of LogEntry objects
62
+ ```
63
+
64
+ ### getStats()
65
+
66
+ Get statistics about logged operations.
67
+
68
+ ```javascript
69
+ const stats = memorio.logger.getStats()
70
+ // Returns: { total, state, store, session, cache, set, get, delete, clear }
71
+ ```
72
+
73
+ ### clearHistory()
74
+
75
+ Clear log history.
76
+
77
+ ```javascript
78
+ memorio.logger.clearHistory()
79
+ ```
80
+
81
+ ### exportLogs()
82
+
83
+ Export logs as JSON string.
84
+
85
+ ```javascript
86
+ const json = memorio.logger.exportLogs()
87
+ ```
88
+
89
+ ## Log Entry Structure
90
+
91
+ ```javascript
92
+ {
93
+ timestamp: "2026-02-18T12:00:00.000Z",
94
+ module: "state",
95
+ action: "set",
96
+ path: "user.name",
97
+ value: "John",
98
+ previousValue: "Jane"
99
+ }
100
+ ```
101
+
102
+ ## Examples
103
+
104
+ ### Basic usage
105
+
106
+ ```javascript
107
+ // Logging is enabled by default
108
+ state.user = { name: 'John' }
109
+ // Console: [Memorio:STATE] set user → value: { name: 'John' }
110
+ ```
111
+
112
+ ### Get statistics
113
+
114
+ ```javascript
115
+ const stats = memorio.logger.getStats()
116
+ console.debug(stats)
117
+ // { total: 15, state: 5, store: 3, session: 2, cache: 5, set: 10, get: 0, delete: 3, clear: 2 }
118
+ ```
119
+
120
+ ### Disable specific modules
121
+
122
+ ```javascript
123
+ memorio.logger.configure({
124
+ modules: ['state'] // Only log state changes
125
+ })
126
+ ```
127
+
128
+ ### Custom handler
129
+
130
+ ```javascript
131
+ memorio.logger.configure({
132
+ customHandler: (entry) => {
133
+ // Send to analytics
134
+ analytics.track('memorio_change', entry)
135
+ }
136
+ })
137
+ ```
138
+
139
+ ### Export and analyze
140
+
141
+ ```javascript
142
+ // Get all logs
143
+ const logs = memorio.logger.getHistory()
144
+
145
+ // Filter by module
146
+ const stateLogs = logs.filter(l => l.module === 'state')
147
+
148
+ // Filter by action
149
+ const setOperations = logs.filter(l => l.action === 'set')
150
+
151
+ // Export for debugging
152
+ console.debug(memorio.logger.exportLogs())
153
+ ```
@@ -0,0 +1,95 @@
1
+ > **Status:** Published
2
+ > **Date:** 2026-09-12
3
+ > **Scope**: API Reference
4
+ > **Standard**: Memorio API Specification v5
5
+ >
6
+ ---
7
+ # Node Attachment System
8
+
9
+ `memorio.memory` extends with a **Node Attachment System** allowing memory elements to dynamically attach, reference, or connect to other memory elements at runtime.
10
+
11
+ This is an **extension**, not a replacement, of existing memory semantics.
12
+
13
+ ## Concepts
14
+
15
+ ```text
16
+ Memory
17
+ └── Node
18
+ ├── identity
19
+ ├── value
20
+ ├── metadata
21
+ └── relationships
22
+ └── Edge
23
+ ├── target
24
+ ├── relation
25
+ ├── metadata
26
+ ├── confidence
27
+ └── lifecycle
28
+ ```
29
+
30
+ ## API
31
+
32
+ ```ts
33
+ const user = await memory.remember("user", { name: "Alice" })
34
+ const project = await memory.remember("project", { name: "Memorio" })
35
+
36
+ await user.connect(project, { relation: "works-on", confidence: 0.95 })
37
+ await user.attach(project) // → connect with relation "attached-to"
38
+
39
+ const related = await user.related({ direction: "both", relation: "works-on" })
40
+ const tree = await user.traverse({ depth: 3 })
41
+ ```
42
+
43
+ ### Methods
44
+
45
+ | Method | Description |
46
+ |--------|-------------|
47
+ | `node.connect(target, opts?)` | Create a directed relationship |
48
+ | `node.disconnect(target, opts?)` | Remove a relationship |
49
+ | `node.related(opts?)` | Query related nodes |
50
+ | `node.traverse(opts?)` | Bounded graph traversal |
51
+ | `memory.connect(source, target, opts?)` | Low-level connect |
52
+ | `memory.disconnect(source, target, opts?)` | Low-level disconnect |
53
+
54
+ ## Scopes
55
+
56
+ Relationship visibility respects memory scopes - a query in one scope cannot leak inaccessible nodes from another.
57
+
58
+ ## Persistence
59
+
60
+ Relationships use **IDs**, never embedded objects:
61
+
62
+ ```json
63
+ {
64
+ "id": "user",
65
+ "relationships": [
66
+ { "target": "project", "relation": "works-on" }
67
+ ]
68
+ }
69
+ ```
70
+
71
+ ## Lifecycle
72
+
73
+ - **TTL**: independent per node/edge - does not propagate
74
+ - **Confidence**: independent - node and edge have separate confidence values
75
+ - **Deletion**: deleting a node removes its edges (default policy)
76
+ - **Cycles**: supported with visited-set protection during traversal
77
+ - **Dangling references**: `retain` by default (configurable)
78
+
79
+ ## Security
80
+
81
+ Relationship traversal inherits the same scope/access rules as direct retrieval. A user cannot gain access to Node B merely because Node A connects to it.
82
+
83
+ ## Serialization
84
+
85
+ Nodes serialize to IDs only - never recursively embedded graphs.
86
+
87
+ ## Performance
88
+
89
+ - `O(1)` indexed lookup for direct node retrieval
90
+ - Graph traversal only on explicit request
91
+ - Indexable by `source`, `target`, `relation`
92
+
93
+ ## Backward Compatibility
94
+
95
+ Existing APIs (`remember`, `get`, `forget`, `search`) continue to work unchanged. A node-enabled memory entry remains usable as a normal memory entry.
@@ -0,0 +1,161 @@
1
+ > **Status:** Published
2
+ > **Date:** 2026-09-12
3
+ > **Scope**: API Reference
4
+ > **Standard**: Memorio API Specification v5
5
+ >
6
+ ---
7
+ # Memory System
8
+
9
+ `memorio.memory` provides a semantic memory layer - a key/value store with type safety, TTL, confidence scoring, tagging, and scope-based persistence.
10
+
11
+ ## Core API
12
+
13
+ ### `memorio.memory.remember(key, value, opts?)`
14
+
15
+ Stores a memory entry.
16
+
17
+ ```ts
18
+ await memorio.memory.remember('user.name', 'Dario', {
19
+ type: 'preference',
20
+ confidence: 0.92,
21
+ scope: 'local',
22
+ ttl: null,
23
+ tags: ['user', 'profile'],
24
+ source: 'conversation'
25
+ })
26
+ ```
27
+
28
+ | Option | Type | Default | Description |
29
+ |--------|------|---------|-------------|
30
+ | `id` | `string` | `key` | Custom entry ID |
31
+ | `type` | `'fact' \| 'preference' \| 'decision' \| 'task' \| 'context'` | `'fact'` | Semantic classification |
32
+ | `confidence` | `number` | `1.0` | Trust score 0.0–1.0 |
33
+ | `scope` | `'hot' \| 'session' \| 'local' \| 'durable'` | auto | Storage backend (see below) |
34
+ | `ttl` | `number \| null` | `null` | Milliseconds before expiry (`null` = never) |
35
+ | `tags` | `string \| string[]` | `[]` | Metadata for filtering |
36
+ | `source` | `string` | `undefined` | Origin of the memory |
37
+
38
+ ### `memorio.memory.recall(query, opts?)`
39
+
40
+ Retrieves a memory by key.
41
+
42
+ ```ts
43
+ const name = await memorio.memory.recall('user.name')
44
+ const highConfidence = await memorio.memory.recall('project', {
45
+ minConfidence: 0.8
46
+ })
47
+ ```
48
+
49
+ | Option | Type | Default | Description |
50
+ |--------|------|---------|-------------|
51
+ | `type` | `MemoryType \| MemoryType[]` | `*` | Filter by type |
52
+ | `tags` | `string \| string[]` | `*` | Filter by tags |
53
+ | `minConfidence` | `number` | `0` | Minimum confidence threshold |
54
+ | `includeObsolete` | `boolean` | `false` | Include expired/superseded entries |
55
+
56
+ ### `memorio.memory.update(key, value, opts?)`
57
+
58
+ Updates an existing memory. Creates a **superseded copy** of the old entry (preserving history).
59
+
60
+ ```ts
61
+ await memorio.memory.update('user.name', 'Alice', { confidence: 0.95 })
62
+ ```
63
+
64
+ ### `memorio.memory.forget(key)`
65
+
66
+ Permanently removes a memory.
67
+
68
+ ```ts
69
+ await memorio.memory.forget('user.temp')
70
+ ```
71
+
72
+ ### `memorio.memory.context(opts?)`
73
+
74
+ Returns ranked, relevant memories. Uses recency × confidence × type/scope boost algorithm.
75
+
76
+ ```ts
77
+ const ctx = await memorio.memory.context({
78
+ tags: 'project',
79
+ types: ['decision', 'preference'],
80
+ minConfidence: 0.7,
81
+ maxEntries: 10,
82
+ scopes: ['local', 'durable']
83
+ })
84
+ ```
85
+
86
+ Returns:
87
+ ```ts
88
+ Array<{
89
+ key: string
90
+ value: any
91
+ type: MemoryType
92
+ confidence: number
93
+ scope: MemoryScope
94
+ tags: string[]
95
+ age: number // milliseconds since createdAt
96
+ accessCount: number
97
+ lastAccessedAt: number
98
+ }>
99
+ ```
100
+
101
+ ### `memorio.memory.stats()`
102
+
103
+ Returns usage statistics:
104
+
105
+ ```ts
106
+ {
107
+ total: number
108
+ byScope: Record<MemoryScope, number>
109
+ byType: Partial<Record<MemoryType, number>>
110
+ expired: number
111
+ }
112
+ ```
113
+
114
+ ### `memorio.memory.forgetExpired()`
115
+
116
+ Cleans all expired entries. Returns count removed.
117
+
118
+ ### `memorio.memory.clear()`
119
+
120
+ Wipes all memories and the index.
121
+
122
+ ## Memory Entry Model
123
+
124
+ ```ts
125
+ interface MemoryEntry<T = any> {
126
+ id: string
127
+ key: string
128
+ value: T
129
+ type: 'fact' | 'preference' | 'decision' | 'task' | 'context'
130
+ confidence: number
131
+ scope: 'hot' | 'session' | 'local' | 'durable'
132
+ ttl?: number | null
133
+ tags: string[]
134
+ source?: string
135
+ status: 'active' | 'obsolete' | 'superseded'
136
+ createdAt: number
137
+ lastConfirmedAt: number
138
+ supersededId?: string | null
139
+ }
140
+ ```
141
+
142
+ ## Scopes
143
+
144
+ | Scope | Storage | TTL | Cross-session | Size limit |
145
+ |-------|---------|-----|---------------|------------|
146
+ | `hot` | `state` proxy | ✅ | ❌ | ~5MB (RAM) |
147
+ | `session` | `sessionStorage` | ✅ | Tab only | ~5MB |
148
+ | `local` | `localStorage` | ✅ | ✅ | ~10MB |
149
+ | `durable` | `IndexedDB` | ✅ | ✅ | ~1GB+ |
150
+
151
+ Default scope is `local` for values ≤100KB, `durable` for larger values.
152
+
153
+ ## Memory Lifecycle
154
+
155
+ | Event | Behavior |
156
+ |-------|----------|
157
+ | `remember()` on existing key | Old entry → `superseded`, new entry → `active` |
158
+ | Entry with TTL expires | Status → `obsolete` (cleaned by `forgetExpired()`) |
159
+ | `recall()` expired entry | Returns `null` unless `includeObsolete: true` |
160
+ | `update()` | Creates superseded copy + updated active entry |
161
+ | `clear()` | Wipes all memories + index |