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.
- package/AGENTS.md +3 -3
- package/README.md +95 -516
- package/SECURITY.md +159 -33
- package/SUMMARY.md +59 -45
- package/adr/001-state-proxy-model.md +95 -0
- package/adr/002-observer-semantics.md +179 -0
- package/adr/003-deep-mutation-semantics.md +128 -0
- package/adr/004-array-mutation-semantics.md +127 -0
- package/adr/005-scheduler-contract.md +148 -0
- package/adr/006-context-isolation.md +91 -0
- package/adr/007-mutation-records.md +117 -0
- package/adr/008-transactions.md +105 -0
- package/adr/009-history-model.md +109 -0
- package/adr/README.md +46 -0
- package/adr/template.md +48 -0
- package/bin/cli.js +68 -0
- package/examples/basic.ts +115 -115
- package/examples/browser-vanilla.html +358 -358
- package/examples/cache.ts +72 -72
- package/examples/cross-platform-guards.ts +57 -57
- package/examples/history.ts +104 -0
- package/examples/idb.ts +109 -109
- package/examples/multi-tenant-context.ts +44 -44
- package/examples/node-server.ts +308 -308
- package/examples/observer.ts +60 -60
- package/examples/platform.ts +115 -115
- package/examples/react-app.tsx +362 -362
- package/examples/react-observer.tsx +63 -63
- package/examples/semantic-memory.ts +60 -60
- package/examples/session-advanced.ts +91 -91
- package/examples/sqlite-batched-writes.ts +57 -57
- package/examples/state-advanced.ts +89 -89
- package/examples/store-advanced.ts +117 -117
- package/examples/sync.ts +90 -0
- package/examples/typed-and-schema.ts +102 -100
- package/examples/useObserver.tsx +140 -141
- package/global.cjs +5733 -0
- package/global.d.ts +8 -0
- package/global.js +5667 -0
- package/index.cjs +2202 -1041
- package/index.d.ts +2 -0
- package/index.js +2178 -1040
- package/llms.txt +113 -8
- package/markdown/AUDIT-REPORT.md +134 -0
- package/markdown/CACHE.md +191 -0
- package/markdown/DEVTOOLS.md +128 -0
- package/markdown/DISPATCH.md +176 -0
- package/markdown/HISTORY.md +198 -0
- package/markdown/IDB.md +177 -0
- package/markdown/IMPORT.md +152 -0
- package/markdown/INSPECT.md +122 -0
- package/markdown/LOGGER.md +153 -0
- package/markdown/MEMORY-ATTACHMENT.md +95 -0
- package/markdown/MEMORY.md +161 -0
- package/markdown/OBSERVER.md +208 -0
- package/markdown/PLATFORM.md +277 -0
- package/markdown/REDUX.md +54 -0
- package/markdown/SCHEMA.md +175 -0
- package/markdown/SESSION.md +164 -0
- package/markdown/SQLITE.md +189 -0
- package/markdown/STATE.md +159 -0
- package/markdown/STORE.md +170 -0
- package/markdown/SYNC.md +318 -0
- package/markdown/TYPED.md +164 -0
- package/markdown/USEOBSERVER.md +256 -0
- package/modules/redux.cjs +701 -177
- package/modules/redux.cjs.map +1 -1
- package/modules/redux.js +701 -177
- package/modules/redux.js.map +1 -1
- package/package.json +26 -4
- package/types/broadcast.d.ts +61 -0
- package/types/computed.d.ts +96 -0
- package/types/encryption.d.ts +129 -0
- package/types/env.d.ts +19 -9
- package/types/exports.d.ts +29 -0
- package/types/history.d.ts +13 -1
- package/types/memorio.d.ts +25 -6
- package/types/mutation.d.ts +75 -0
- 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/examples/observer.ts
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memorio Observer Example
|
|
3
|
-
*
|
|
4
|
-
* This example demonstrates the observer pattern for reactive state changes.
|
|
5
|
-
* Perfect for logging, analytics, auto-save, and UI updates.
|
|
6
|
-
*
|
|
7
|
-
* Run: npx ts-node examples/observer.ts
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import 'memorio'
|
|
11
|
-
|
|
12
|
-
// ============================================
|
|
13
|
-
// SIMPLE OBSERVER
|
|
14
|
-
// ============================================
|
|
15
|
-
|
|
16
|
-
// Watch a single value
|
|
17
|
-
observer('state.counter', (newValue, oldValue) => {
|
|
18
|
-
console.debug(`Counter: ${oldValue} → ${newValue}`)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
state.counter = 0
|
|
22
|
-
state.counter = 1
|
|
23
|
-
state.counter = 2
|
|
24
|
-
|
|
25
|
-
// ============================================
|
|
26
|
-
// OBJECT OBSERVER
|
|
27
|
-
// ============================================
|
|
28
|
-
|
|
29
|
-
// Watch entire objects
|
|
30
|
-
observer('state.user', (newUser, oldUser) => {
|
|
31
|
-
console.debug(`User changed: ${oldUser?.name} → ${newUser?.name}`)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
state.user = { name: 'Mario', level: 1 }
|
|
35
|
-
state.user = { name: 'Luigi', level: 2 }
|
|
36
|
-
|
|
37
|
-
// ============================================
|
|
38
|
-
// MULTIPLE OBSERVERS
|
|
39
|
-
// ============================================
|
|
40
|
-
|
|
41
|
-
// Multiple observers on same path
|
|
42
|
-
observer('state.notifications', (count) => {
|
|
43
|
-
console.debug(`New notification count: ${count}`)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
// List all observers
|
|
47
|
-
console.debug('Active observers:', observer.list)
|
|
48
|
-
|
|
49
|
-
// ============================================
|
|
50
|
-
// CLEANUP
|
|
51
|
-
// ============================================
|
|
52
|
-
|
|
53
|
-
// Remove specific observer
|
|
54
|
-
observer.remove('state.counter')
|
|
55
|
-
|
|
56
|
-
// Remove all observers - call remove for each path
|
|
57
|
-
// observer.remove('state.counter')
|
|
58
|
-
// observer.remove('state.notifications')
|
|
59
|
-
|
|
60
|
-
console.debug('Observer example complete!')
|
|
1
|
+
/**
|
|
2
|
+
* Memorio Observer Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates the observer pattern for reactive state changes.
|
|
5
|
+
* Perfect for logging, analytics, auto-save, and UI updates.
|
|
6
|
+
*
|
|
7
|
+
* Run: npx ts-node examples/observer.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { observer, state } from 'memorio'
|
|
11
|
+
|
|
12
|
+
// ============================================
|
|
13
|
+
// SIMPLE OBSERVER
|
|
14
|
+
// ============================================
|
|
15
|
+
|
|
16
|
+
// Watch a single value
|
|
17
|
+
observer('state.counter', (newValue, oldValue) => {
|
|
18
|
+
console.debug(`Counter: ${oldValue} → ${newValue}`)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
state.counter = 0
|
|
22
|
+
state.counter = 1
|
|
23
|
+
state.counter = 2
|
|
24
|
+
|
|
25
|
+
// ============================================
|
|
26
|
+
// OBJECT OBSERVER
|
|
27
|
+
// ============================================
|
|
28
|
+
|
|
29
|
+
// Watch entire objects
|
|
30
|
+
observer('state.user', (newUser, oldUser) => {
|
|
31
|
+
console.debug(`User changed: ${oldUser?.name} → ${newUser?.name}`)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
state.user = { name: 'Mario', level: 1 }
|
|
35
|
+
state.user = { name: 'Luigi', level: 2 }
|
|
36
|
+
|
|
37
|
+
// ============================================
|
|
38
|
+
// MULTIPLE OBSERVERS
|
|
39
|
+
// ============================================
|
|
40
|
+
|
|
41
|
+
// Multiple observers on same path
|
|
42
|
+
observer('state.notifications', (count) => {
|
|
43
|
+
console.debug(`New notification count: ${count}`)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// List all observers
|
|
47
|
+
console.debug('Active observers:', observer.list)
|
|
48
|
+
|
|
49
|
+
// ============================================
|
|
50
|
+
// CLEANUP
|
|
51
|
+
// ============================================
|
|
52
|
+
|
|
53
|
+
// Remove specific observer
|
|
54
|
+
observer.remove('state.counter')
|
|
55
|
+
|
|
56
|
+
// Remove all observers - call remove for each path
|
|
57
|
+
// observer.remove('state.counter')
|
|
58
|
+
// observer.remove('state.notifications')
|
|
59
|
+
|
|
60
|
+
console.debug('Observer example complete!')
|
package/examples/platform.ts
CHANGED
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memorio Platform & Context Example
|
|
3
|
-
*
|
|
4
|
-
* This example demonstrates:
|
|
5
|
-
* - Platform detection
|
|
6
|
-
* - Checking storage persistence
|
|
7
|
-
* - Context isolation for server-side multi-tenancy
|
|
8
|
-
*
|
|
9
|
-
* Run: npx ts-node examples/platform.ts
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import 'memorio'
|
|
13
|
-
|
|
14
|
-
// ============================================
|
|
15
|
-
// PLATFORM DETECTION
|
|
16
|
-
// ============================================
|
|
17
|
-
|
|
18
|
-
console.debug('=== Platform Detection ===')
|
|
19
|
-
console.debug('Memorio version:', memorio.version)
|
|
20
|
-
|
|
21
|
-
// Check which platform we're on
|
|
22
|
-
if (memorio.isBrowser()) {
|
|
23
|
-
console.debug('Running in: Browser')
|
|
24
|
-
console.debug('store.isPersistent:', store.isPersistent) // true
|
|
25
|
-
console.debug('session.isPersistent:', session.isPersistent) // true
|
|
26
|
-
} else if (memorio.isNode()) {
|
|
27
|
-
console.debug('Running in: Node.js')
|
|
28
|
-
console.debug('store.isPersistent:', store.isPersistent) // false (memory fallback)
|
|
29
|
-
console.debug('session.isPersistent:', session.isPersistent) // false (memory fallback)
|
|
30
|
-
} else if (memorio.isDeno()) {
|
|
31
|
-
console.debug('Running in: Deno')
|
|
32
|
-
console.debug('store.isPersistent:', store.isPersistent) // false (memory fallback)
|
|
33
|
-
console.debug('session.isPersistent:', session.isPersistent) // false (memory fallback)
|
|
34
|
-
} else if (memorio.isEdge()) {
|
|
35
|
-
console.debug('Running in: Edge Worker')
|
|
36
|
-
console.debug('store.isPersistent:', store.isPersistent) // true
|
|
37
|
-
console.debug('session.isPersistent:', session.isPersistent) // true
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Get detailed capabilities
|
|
41
|
-
const caps = memorio.getCapabilities()
|
|
42
|
-
console.debug('\nCapabilities:')
|
|
43
|
-
console.debug(' Platform:', caps.platform)
|
|
44
|
-
console.debug(' localStorage:', caps.hasLocalStorage ? '✅' : '❌')
|
|
45
|
-
console.debug(' sessionStorage:', caps.hasSessionStorage ? '✅' : '❌')
|
|
46
|
-
console.debug(' IndexedDB:', caps.hasIndexedDB ? '✅' : '❌')
|
|
47
|
-
console.debug(' Session ID:', caps.sessionId)
|
|
48
|
-
|
|
49
|
-
// ============================================
|
|
50
|
-
// CONTEXT ISOLATION (Server-Side)
|
|
51
|
-
// ============================================
|
|
52
|
-
|
|
53
|
-
console.debug('\n=== Context Isolation ===')
|
|
54
|
-
console.debug('Use memorio.createContext() for multi-tenant server applications')
|
|
55
|
-
|
|
56
|
-
// Example: Simulating different users/requests
|
|
57
|
-
// In a real app, you'd create a context per HTTP request
|
|
58
|
-
|
|
59
|
-
// Create isolated context for User A
|
|
60
|
-
const userAContext = memorio.createContext('user-A')
|
|
61
|
-
userAContext.state.name = 'Mario'
|
|
62
|
-
userAContext.store.set('preferences', { theme: 'dark' })
|
|
63
|
-
userAContext.session.set('token', 'user-A-token')
|
|
64
|
-
|
|
65
|
-
// Create isolated context for User B
|
|
66
|
-
const userBContext = memorio.createContext('user-B')
|
|
67
|
-
userBContext.state.name = 'Luigi'
|
|
68
|
-
userBContext.store.set('preferences', { theme: 'light' })
|
|
69
|
-
userBContext.session.set('token', 'user-B-token')
|
|
70
|
-
|
|
71
|
-
// Verify isolation - each context has its own data
|
|
72
|
-
console.debug('\nUser A context:')
|
|
73
|
-
console.debug(' state.name:', userAContext.state.name) // 'Mario'
|
|
74
|
-
console.debug(' store.preferences:', userAContext.store.get('preferences')) // { theme: 'dark' }
|
|
75
|
-
console.debug(' session.token:', userAContext.session.get('token')) // 'user-A-token'
|
|
76
|
-
|
|
77
|
-
console.debug('\nUser B context:')
|
|
78
|
-
console.debug(' state.name:', userBContext.state.name) // 'Luigi'
|
|
79
|
-
console.debug(' store.preferences:', userBContext.store.get('preferences')) // { theme: 'light' }
|
|
80
|
-
console.debug(' session.token:', userBContext.session.get('token')) // 'user-B-token'
|
|
81
|
-
|
|
82
|
-
// Global state is separate from contexts
|
|
83
|
-
console.debug('\nGlobal state (not affected by contexts):')
|
|
84
|
-
console.debug(' state.name:', state.name) // undefined
|
|
85
|
-
|
|
86
|
-
// List all contexts
|
|
87
|
-
console.debug('\nActive contexts:', memorio.listContexts()) // ['user-A', 'user-B']
|
|
88
|
-
|
|
89
|
-
// Cleanup - delete a context when done
|
|
90
|
-
memorio.deleteContext('user-A')
|
|
91
|
-
console.debug('After deleting user-A:', memorio.listContexts()) // ['user-B']
|
|
92
|
-
|
|
93
|
-
// ============================================
|
|
94
|
-
// USE CASE: EXPRESS/FASTIFY MIDDLEWARE EXAMPLE
|
|
95
|
-
// ============================================
|
|
96
|
-
|
|
97
|
-
console.debug('\n=== Server Use Case ===')
|
|
98
|
-
console.debug(`
|
|
99
|
-
// Example: Express middleware for request isolation
|
|
100
|
-
app.use((req, res, next) => {
|
|
101
|
-
// Create isolated context per request
|
|
102
|
-
const ctx = memorio.createContext(\`req-\${req.id}\`)
|
|
103
|
-
req.memorio = ctx
|
|
104
|
-
next()
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
// In your route handler:
|
|
108
|
-
app.get('/user', (req, res) => {
|
|
109
|
-
// This state is isolated per request
|
|
110
|
-
req.memorio.state.user = getUserData()
|
|
111
|
-
req.memorio.store.set('cache', data)
|
|
112
|
-
})
|
|
113
|
-
`)
|
|
114
|
-
|
|
115
|
-
console.debug('\nPlatform & Context example complete!')
|
|
1
|
+
/**
|
|
2
|
+
* Memorio Platform & Context Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates:
|
|
5
|
+
* - Platform detection
|
|
6
|
+
* - Checking storage persistence
|
|
7
|
+
* - Context isolation for server-side multi-tenancy
|
|
8
|
+
*
|
|
9
|
+
* Run: npx ts-node examples/platform.ts
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { memorio, state, store, session } from 'memorio'
|
|
13
|
+
|
|
14
|
+
// ============================================
|
|
15
|
+
// PLATFORM DETECTION
|
|
16
|
+
// ============================================
|
|
17
|
+
|
|
18
|
+
console.debug('=== Platform Detection ===')
|
|
19
|
+
console.debug('Memorio version:', memorio.version)
|
|
20
|
+
|
|
21
|
+
// Check which platform we're on
|
|
22
|
+
if (memorio.isBrowser()) {
|
|
23
|
+
console.debug('Running in: Browser')
|
|
24
|
+
console.debug('store.isPersistent:', store.isPersistent) // true
|
|
25
|
+
console.debug('session.isPersistent:', session.isPersistent) // true
|
|
26
|
+
} else if (memorio.isNode()) {
|
|
27
|
+
console.debug('Running in: Node.js')
|
|
28
|
+
console.debug('store.isPersistent:', store.isPersistent) // false (memory fallback)
|
|
29
|
+
console.debug('session.isPersistent:', session.isPersistent) // false (memory fallback)
|
|
30
|
+
} else if (memorio.isDeno()) {
|
|
31
|
+
console.debug('Running in: Deno')
|
|
32
|
+
console.debug('store.isPersistent:', store.isPersistent) // false (memory fallback)
|
|
33
|
+
console.debug('session.isPersistent:', session.isPersistent) // false (memory fallback)
|
|
34
|
+
} else if (memorio.isEdge()) {
|
|
35
|
+
console.debug('Running in: Edge Worker')
|
|
36
|
+
console.debug('store.isPersistent:', store.isPersistent) // true
|
|
37
|
+
console.debug('session.isPersistent:', session.isPersistent) // true
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Get detailed capabilities
|
|
41
|
+
const caps = memorio.getCapabilities()
|
|
42
|
+
console.debug('\nCapabilities:')
|
|
43
|
+
console.debug(' Platform:', caps.platform)
|
|
44
|
+
console.debug(' localStorage:', caps.hasLocalStorage ? '✅' : '❌')
|
|
45
|
+
console.debug(' sessionStorage:', caps.hasSessionStorage ? '✅' : '❌')
|
|
46
|
+
console.debug(' IndexedDB:', caps.hasIndexedDB ? '✅' : '❌')
|
|
47
|
+
console.debug(' Session ID:', caps.sessionId)
|
|
48
|
+
|
|
49
|
+
// ============================================
|
|
50
|
+
// CONTEXT ISOLATION (Server-Side)
|
|
51
|
+
// ============================================
|
|
52
|
+
|
|
53
|
+
console.debug('\n=== Context Isolation ===')
|
|
54
|
+
console.debug('Use memorio.createContext() for multi-tenant server applications')
|
|
55
|
+
|
|
56
|
+
// Example: Simulating different users/requests
|
|
57
|
+
// In a real app, you'd create a context per HTTP request
|
|
58
|
+
|
|
59
|
+
// Create isolated context for User A
|
|
60
|
+
const userAContext = memorio.createContext('user-A')
|
|
61
|
+
userAContext.state.name = 'Mario'
|
|
62
|
+
userAContext.store.set('preferences', { theme: 'dark' })
|
|
63
|
+
userAContext.session.set('token', 'user-A-token')
|
|
64
|
+
|
|
65
|
+
// Create isolated context for User B
|
|
66
|
+
const userBContext = memorio.createContext('user-B')
|
|
67
|
+
userBContext.state.name = 'Luigi'
|
|
68
|
+
userBContext.store.set('preferences', { theme: 'light' })
|
|
69
|
+
userBContext.session.set('token', 'user-B-token')
|
|
70
|
+
|
|
71
|
+
// Verify isolation - each context has its own data
|
|
72
|
+
console.debug('\nUser A context:')
|
|
73
|
+
console.debug(' state.name:', userAContext.state.name) // 'Mario'
|
|
74
|
+
console.debug(' store.preferences:', userAContext.store.get('preferences')) // { theme: 'dark' }
|
|
75
|
+
console.debug(' session.token:', userAContext.session.get('token')) // 'user-A-token'
|
|
76
|
+
|
|
77
|
+
console.debug('\nUser B context:')
|
|
78
|
+
console.debug(' state.name:', userBContext.state.name) // 'Luigi'
|
|
79
|
+
console.debug(' store.preferences:', userBContext.store.get('preferences')) // { theme: 'light' }
|
|
80
|
+
console.debug(' session.token:', userBContext.session.get('token')) // 'user-B-token'
|
|
81
|
+
|
|
82
|
+
// Global state is separate from contexts
|
|
83
|
+
console.debug('\nGlobal state (not affected by contexts):')
|
|
84
|
+
console.debug(' state.name:', state.name) // undefined
|
|
85
|
+
|
|
86
|
+
// List all contexts
|
|
87
|
+
console.debug('\nActive contexts:', memorio.listContexts()) // ['user-A', 'user-B']
|
|
88
|
+
|
|
89
|
+
// Cleanup - delete a context when done
|
|
90
|
+
memorio.deleteContext('user-A')
|
|
91
|
+
console.debug('After deleting user-A:', memorio.listContexts()) // ['user-B']
|
|
92
|
+
|
|
93
|
+
// ============================================
|
|
94
|
+
// USE CASE: EXPRESS/FASTIFY MIDDLEWARE EXAMPLE
|
|
95
|
+
// ============================================
|
|
96
|
+
|
|
97
|
+
console.debug('\n=== Server Use Case ===')
|
|
98
|
+
console.debug(`
|
|
99
|
+
// Example: Express middleware for request isolation
|
|
100
|
+
app.use((req, res, next) => {
|
|
101
|
+
// Create isolated context per request
|
|
102
|
+
const ctx = memorio.createContext(\`req-\${req.id}\`)
|
|
103
|
+
req.memorio = ctx
|
|
104
|
+
next()
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// In your route handler:
|
|
108
|
+
app.get('/user', (req, res) => {
|
|
109
|
+
// This state is isolated per request
|
|
110
|
+
req.memorio.state.user = getUserData()
|
|
111
|
+
req.memorio.store.set('cache', data)
|
|
112
|
+
})
|
|
113
|
+
`)
|
|
114
|
+
|
|
115
|
+
console.debug('\nPlatform & Context example complete!')
|