memorio 4.6.6 → 4.6.7
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/package.json +3 -2
- package/types/cache.d.ts +1 -1
- package/types/idb.d.ts +1 -1
- package/types/observer.d.ts +1 -1
- package/types/useObserver.d.ts +1 -1
- package/COPYRIGHT.md +0 -6
- package/SECURITY.md +0 -48
- package/SUMMARY.md +0 -28
- package/examples/basic.ts +0 -115
- package/examples/browser-vanilla.html +0 -358
- package/examples/cache.ts +0 -72
- package/examples/idb.ts +0 -109
- package/examples/node-server.ts +0 -308
- package/examples/observer.ts +0 -60
- package/examples/platform.ts +0 -115
- package/examples/react-app.tsx +0 -362
- package/examples/session-advanced.ts +0 -91
- package/examples/state-advanced.ts +0 -89
- package/examples/store-advanced.ts +0 -117
- package/examples/useObserver.tsx +0 -141
- package/index.cjs +0 -1371
- package/index.d.ts +0 -18
- package/index.js +0 -1346
- package/llms.txt +0 -405
- package/markdown/CACHE.md +0 -90
- package/markdown/CHANGELOG.md +0 -161
- package/markdown/DEVTOOLS.md +0 -122
- package/markdown/DISPATCH.md +0 -168
- package/markdown/IDB.md +0 -169
- package/markdown/IMPORT.md +0 -139
- package/markdown/LOGGER.md +0 -147
- package/markdown/OBSERVER.md +0 -200
- package/markdown/PLATFORM.md +0 -265
- package/markdown/SECURITY.md +0 -323
- package/markdown/SESSION.md +0 -154
- package/markdown/STATE.md +0 -153
- package/markdown/STORE.md +0 -164
- package/markdown/USEOBSERVER.md +0 -259
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memorio",
|
|
3
3
|
"codeName": "memorio",
|
|
4
|
-
"version": "4.6.
|
|
4
|
+
"version": "4.6.7",
|
|
5
5
|
"description": "Memorio, State + Observer, Store and iDB for an easy life - Cross-platform compatible",
|
|
6
6
|
"main": "./index.cjs",
|
|
7
7
|
"browser": "./index.js",
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
"node": ">=18.0.0"
|
|
50
50
|
},
|
|
51
51
|
"files": [
|
|
52
|
-
"
|
|
52
|
+
"dist/",
|
|
53
|
+
"types/"
|
|
53
54
|
],
|
|
54
55
|
"publishConfig": {
|
|
55
56
|
"access": "public"
|
package/types/cache.d.ts
CHANGED
package/types/idb.d.ts
CHANGED
package/types/observer.d.ts
CHANGED
package/types/useObserver.d.ts
CHANGED
package/COPYRIGHT.md
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
# Copyright
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025, Dario Passariello. All rights reserved.
|
|
4
|
-
<https://dario.passariello.ca>
|
|
5
|
-
|
|
6
|
-
This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.
|
package/SECURITY.md
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# Security
|
|
2
|
-
|
|
3
|
-
Memorio follows NIST and NSA security standards at the enterprise level.
|
|
4
|
-
|
|
5
|
-
## Security Standards
|
|
6
|
-
|
|
7
|
-
- **NIST Guidelines**: Follows NIST SP 800-53 security controls and NIST Cybersecurity Framework
|
|
8
|
-
- **NSA Standards**: Defense-grade security practices; considers nation-state level threats in risk assessment
|
|
9
|
-
|
|
10
|
-
## Supply Chain Security
|
|
11
|
-
|
|
12
|
-
- **Socket.dev**: Minimum target score 90%; all alarms must be resolved before release
|
|
13
|
-
- **Dependency Management**: Zero production dependencies (fully dependency-free); dev dependencies audited regularly
|
|
14
|
-
- **Prohibited**: No `eval()` usage, no encrypted/obfuscated code in builds, no hardcoded secrets
|
|
15
|
-
|
|
16
|
-
## Code Security
|
|
17
|
-
|
|
18
|
-
- No hardcoded credentials or API keys
|
|
19
|
-
- Secure random session ID generation (`crypto.randomUUID` → `crypto.getRandomValues` → fallback)
|
|
20
|
-
- Input validation on all public APIs
|
|
21
|
-
- XSS prevention on DevTools data export
|
|
22
|
-
- Property-based access control on global objects (`Object.defineProperty` with `enumerable: false`)
|
|
23
|
-
|
|
24
|
-
## OWASP Compliance
|
|
25
|
-
|
|
26
|
-
Addresses OWASP Top 10 (2021):
|
|
27
|
-
- A01:2021 — Broken Access Control (global object protection, property locks)
|
|
28
|
-
- A02:2021 — Cryptographic Failures (crypto.randomUUID for session IDs)
|
|
29
|
-
- A03:2021 — Injection (CSS sanitization in devtools)
|
|
30
|
-
- A05:2021 — Security Misconfiguration (minimal surface area, no bundled secrets)
|
|
31
|
-
- A06:2021 — Vulnerable and Outdated Components (regular npm audit, Socket.dev)
|
|
32
|
-
- A07:2021 — Identification and Authentication Failures (N/A — library, no auth)
|
|
33
|
-
- A08:2021 — Software and Data Integrity Failures (strict tsconfig, lock files)
|
|
34
|
-
- A09:2021 — Security Logging and Monitoring Failures (DevTools inspect, Logger module)
|
|
35
|
-
- A10:2021 — Server-Side Request Forgery (N/A — no network requests)
|
|
36
|
-
|
|
37
|
-
## Reporting Security Issues
|
|
38
|
-
|
|
39
|
-
If you find a security vulnerability:
|
|
40
|
-
|
|
41
|
-
1. Email [Dario Passariello](mailto:dariopassarielloa@gmail.com)
|
|
42
|
-
2. Or visit https://dario.passariello.ca/contact/
|
|
43
|
-
|
|
44
|
-
Do not open public issues for security vulnerabilities.
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
*Document version: 2.0 — Last updated: 2026-05-19*
|
|
48
|
-
*Owner: BigLogic Security Team*
|
package/SUMMARY.md
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Table of contents
|
|
2
|
-
|
|
3
|
-
* [README](README.md)
|
|
4
|
-
|
|
5
|
-
## Core Modules
|
|
6
|
-
|
|
7
|
-
* [State](markdown/STATE.md) - Reactive global state management
|
|
8
|
-
* [Observer](markdown/OBSERVER.md) - Object observation pattern
|
|
9
|
-
* [useObserver](markdown/USEOBSERVER.md) - React hook for state observation
|
|
10
|
-
* [Dispatch](markdown/DISPATCH.md) - Event system for vanilla JS applications
|
|
11
|
-
* [Cache](markdown/CACHE.md) - In-memory caching (lost on refresh)
|
|
12
|
-
* [Store](markdown/STORE.md) - Persistent localStorage management
|
|
13
|
-
* [Session](markdown/SESSION.md) - Temporary sessionStorage management
|
|
14
|
-
* [IDB](markdown/IDB.md) - IndexedDB for large data storage
|
|
15
|
-
|
|
16
|
-
## Platform & Compatibility
|
|
17
|
-
|
|
18
|
-
* [Platform & Context Isolation](markdown/PLATFORM.md) - Cross-platform support, session isolation
|
|
19
|
-
* [Security](markdown/SECURITY.md) - Security measures, vulnerability prevention
|
|
20
|
-
* [Changelog](markdown/CHANGELOG.md) - Version history and migration guide
|
|
21
|
-
* [Classic Import](markdown/IMPORT.md) - Named export guide for `import { state } from 'memorio'`
|
|
22
|
-
|
|
23
|
-
## Additional Resources
|
|
24
|
-
|
|
25
|
-
* [License](../LICENSE.md)
|
|
26
|
-
* [Contributing](../CONTRIBUTING.md)
|
|
27
|
-
* [Code of Conduct](../CODE_OF_CONDUCT.md)
|
|
28
|
-
* [Security](../SECURITY.md)
|
package/examples/basic.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memorio Basic Example
|
|
3
|
-
*
|
|
4
|
-
* This example shows the fundamental features of Memorio:
|
|
5
|
-
* - State management
|
|
6
|
-
* - Store (localStorage)
|
|
7
|
-
* - Session storage
|
|
8
|
-
* - Platform detection
|
|
9
|
-
*
|
|
10
|
-
* Run: npx ts-node examples/basic.ts
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import 'memorio'
|
|
14
|
-
|
|
15
|
-
// ============================================
|
|
16
|
-
// PLATFORM DETECTION
|
|
17
|
-
// ============================================
|
|
18
|
-
|
|
19
|
-
console.debug('=== Platform Detection ===')
|
|
20
|
-
console.debug('Memorio version:', memorio.version)
|
|
21
|
-
|
|
22
|
-
// Check platform
|
|
23
|
-
if (memorio.isBrowser()) {
|
|
24
|
-
console.debug('Platform: Browser')
|
|
25
|
-
} else if (memorio.isNode()) {
|
|
26
|
-
console.debug('Platform: Node.js')
|
|
27
|
-
} else if (memorio.isDeno()) {
|
|
28
|
-
console.debug('Platform: Deno')
|
|
29
|
-
} else if (memorio.isEdge()) {
|
|
30
|
-
console.debug('Platform: Edge Worker')
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Get capabilities
|
|
34
|
-
const caps = memorio.getCapabilities()
|
|
35
|
-
console.debug('Capabilities:', {
|
|
36
|
-
platform: caps.platform,
|
|
37
|
-
hasLocalStorage: caps.hasLocalStorage,
|
|
38
|
-
hasSessionStorage: caps.hasSessionStorage,
|
|
39
|
-
hasIndexedDB: caps.hasIndexedDB
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
// ============================================
|
|
43
|
-
// STATE - In-memory reactive state
|
|
44
|
-
// ============================================
|
|
45
|
-
|
|
46
|
-
console.debug('\n=== State Management ===')
|
|
47
|
-
|
|
48
|
-
// Set some state values
|
|
49
|
-
state.name = 'Mario'
|
|
50
|
-
state.age = 30
|
|
51
|
-
state.isActive = true
|
|
52
|
-
state.profile = {
|
|
53
|
-
email: 'mario@example.com',
|
|
54
|
-
avatar: 'https://example.com/mario.png'
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Get state values
|
|
58
|
-
console.debug('Name:', state.name)
|
|
59
|
-
console.debug('Age:', state.age)
|
|
60
|
-
console.debug('Profile:', state.profile)
|
|
61
|
-
|
|
62
|
-
// List all states
|
|
63
|
-
console.debug('All states:', state.list)
|
|
64
|
-
|
|
65
|
-
// ============================================
|
|
66
|
-
// STORE - Persistent localStorage
|
|
67
|
-
// ============================================
|
|
68
|
-
|
|
69
|
-
console.debug('\n=== Store (Persistent Storage) ===')
|
|
70
|
-
|
|
71
|
-
// Check persistence
|
|
72
|
-
console.debug('Is persistent:', store.isPersistent) // true in browser, false in Node.js/Deno
|
|
73
|
-
|
|
74
|
-
// Save to localStorage
|
|
75
|
-
store.set('username', 'mario')
|
|
76
|
-
store.set('preferences', { theme: 'dark', language: 'en' })
|
|
77
|
-
store.set('lastLogin', Date.now())
|
|
78
|
-
|
|
79
|
-
// Read from localStorage
|
|
80
|
-
console.debug('Username:', store.get('username'))
|
|
81
|
-
console.debug('Preferences:', store.get('preferences'))
|
|
82
|
-
|
|
83
|
-
// Get storage size
|
|
84
|
-
console.debug('Storage size:', store.size(), 'bytes')
|
|
85
|
-
|
|
86
|
-
// ============================================
|
|
87
|
-
// SESSION - Temporary session storage
|
|
88
|
-
// ============================================
|
|
89
|
-
|
|
90
|
-
console.debug('\n=== Session (Temporary Storage) ===')
|
|
91
|
-
|
|
92
|
-
// Check persistence
|
|
93
|
-
console.debug('Is persistent:', session.isPersistent) // true in browser, false in Node.js/Deno
|
|
94
|
-
|
|
95
|
-
// Save session data (cleared when tab closes)
|
|
96
|
-
session.set('token', 'abc123xyz')
|
|
97
|
-
session.set('userId', 42)
|
|
98
|
-
|
|
99
|
-
// Read session data
|
|
100
|
-
console.debug('Token:', session.get('token'))
|
|
101
|
-
console.debug('User ID:', session.get('userId'))
|
|
102
|
-
|
|
103
|
-
// ============================================
|
|
104
|
-
// CLEANUP
|
|
105
|
-
// ============================================
|
|
106
|
-
|
|
107
|
-
// Clear specific items
|
|
108
|
-
store.remove('username')
|
|
109
|
-
session.remove('token')
|
|
110
|
-
|
|
111
|
-
// Clear all
|
|
112
|
-
store.removeAll()
|
|
113
|
-
session.removeAll()
|
|
114
|
-
|
|
115
|
-
console.debug('\nExample complete!')
|
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>Memorio Vanilla JS Example</title>
|
|
8
|
-
<style>
|
|
9
|
-
/* Simple CSS */
|
|
10
|
-
body {
|
|
11
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
12
|
-
max-width: 800px;
|
|
13
|
-
margin: 0 auto;
|
|
14
|
-
padding: 20px;
|
|
15
|
-
background: #f5f5f5;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.card {
|
|
19
|
-
background: white;
|
|
20
|
-
border-radius: 8px;
|
|
21
|
-
padding: 20px;
|
|
22
|
-
margin-bottom: 20px;
|
|
23
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
h1 {
|
|
27
|
-
color: #333;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
h2 {
|
|
31
|
-
color: #666;
|
|
32
|
-
margin-top: 0;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
button {
|
|
36
|
-
background: #007bff;
|
|
37
|
-
color: white;
|
|
38
|
-
border: none;
|
|
39
|
-
padding: 10px 20px;
|
|
40
|
-
border-radius: 4px;
|
|
41
|
-
cursor: pointer;
|
|
42
|
-
margin: 5px;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
button:hover {
|
|
46
|
-
background: #0056b3;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
button.danger {
|
|
50
|
-
background: #dc3545;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
button.danger:hover {
|
|
54
|
-
background: #c82333;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
button.success {
|
|
58
|
-
background: #28a745;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
button.success:hover {
|
|
62
|
-
background: #218838;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
input,
|
|
66
|
-
select {
|
|
67
|
-
padding: 8px;
|
|
68
|
-
border: 1px solid #ddd;
|
|
69
|
-
border-radius: 4px;
|
|
70
|
-
margin: 5px;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
pre {
|
|
74
|
-
background: #f8f9fa;
|
|
75
|
-
padding: 10px;
|
|
76
|
-
border-radius: 4px;
|
|
77
|
-
overflow-x: auto;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.output {
|
|
81
|
-
background: #e9ecef;
|
|
82
|
-
padding: 10px;
|
|
83
|
-
border-radius: 4px;
|
|
84
|
-
font-family: monospace;
|
|
85
|
-
white-space: pre-wrap;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.grid {
|
|
89
|
-
display: grid;
|
|
90
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
91
|
-
gap: 10px;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.stat {
|
|
95
|
-
background: #e7f3ff;
|
|
96
|
-
padding: 10px;
|
|
97
|
-
border-radius: 4px;
|
|
98
|
-
text-align: center;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.stat-value {
|
|
102
|
-
font-size: 24px;
|
|
103
|
-
font-weight: bold;
|
|
104
|
-
color: #007bff;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.stat-label {
|
|
108
|
-
font-size: 12px;
|
|
109
|
-
color: #666;
|
|
110
|
-
}
|
|
111
|
-
</style>
|
|
112
|
-
</head>
|
|
113
|
-
|
|
114
|
-
<body>
|
|
115
|
-
<h1>🧠 Memorio Vanilla JS Demo</h1>
|
|
116
|
-
|
|
117
|
-
<!-- State Section -->
|
|
118
|
-
<div class="card">
|
|
119
|
-
<h2>1. State (Reactive)</h2>
|
|
120
|
-
<p>Global reactive state - changes trigger UI updates automatically</p>
|
|
121
|
-
|
|
122
|
-
<div class="grid">
|
|
123
|
-
<div class="stat">
|
|
124
|
-
<div class="stat-value" id="counter">0</div>
|
|
125
|
-
<div class="stat-label">Counter</div>
|
|
126
|
-
</div>
|
|
127
|
-
<div class="stat">
|
|
128
|
-
<div class="stat-value" id="username">-</div>
|
|
129
|
-
<div class="stat-label">Username</div>
|
|
130
|
-
</div>
|
|
131
|
-
<div class="stat">
|
|
132
|
-
<div class="stat-value" id="theme">light</div>
|
|
133
|
-
<div class="stat-label">Theme</div>
|
|
134
|
-
</div>
|
|
135
|
-
</div>
|
|
136
|
-
|
|
137
|
-
<br>
|
|
138
|
-
<button onclick="state.counter++">Increment Counter</button>
|
|
139
|
-
<button onclick="state.counter--">Decrement</button>
|
|
140
|
-
<button onclick="state.counter = 0">Reset</button>
|
|
141
|
-
|
|
142
|
-
<h3>Set Username:</h3>
|
|
143
|
-
<input type="text" id="nameInput" placeholder="Enter name">
|
|
144
|
-
<button onclick="state.username = document.getElementById('nameInput').value">Set</button>
|
|
145
|
-
|
|
146
|
-
<h3>Theme:</h3>
|
|
147
|
-
<button onclick="state.theme = 'light'">Light</button>
|
|
148
|
-
<button onclick="state.theme = 'dark'">Dark</button>
|
|
149
|
-
|
|
150
|
-
<h3>All State:</h3>
|
|
151
|
-
<pre id="stateOutput" class="output"></pre>
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
|
-
<!-- Store Section -->
|
|
155
|
-
<div class="card">
|
|
156
|
-
<h2>2. Store (localStorage)</h2>
|
|
157
|
-
<p>Permanent storage - survives page refresh</p>
|
|
158
|
-
<p>Persistent: <span id="storePersistent">checking...</span></p>
|
|
159
|
-
|
|
160
|
-
<input type="text" id="storeKey" placeholder="Key">
|
|
161
|
-
<input type="text" id="storeValue" placeholder="Value">
|
|
162
|
-
<button
|
|
163
|
-
onclick="store.set(document.getElementById('storeKey').value, document.getElementById('storeValue').value)">Save</button>
|
|
164
|
-
<button
|
|
165
|
-
onclick="document.getElementById('storeOutput').textContent = JSON.stringify(store.get(document.getElementById('storeKey').value), null, 2)">Get</button>
|
|
166
|
-
<button class="danger" onclick="store.remove(document.getElementById('storeKey').value)">Delete</button>
|
|
167
|
-
|
|
168
|
-
<h3>All Store Data:</h3>
|
|
169
|
-
<pre id="storeOutput" class="output"></pre>
|
|
170
|
-
</div>
|
|
171
|
-
|
|
172
|
-
<!-- Session Section -->
|
|
173
|
-
<div class="card">
|
|
174
|
-
<h2>3. Session (sessionStorage)</h2>
|
|
175
|
-
<p>Temporary storage - cleared when tab closes</p>
|
|
176
|
-
<p>Persistent: <span id="sessionPersistent">checking...</span></p>
|
|
177
|
-
|
|
178
|
-
<input type="text" id="sessionKey" placeholder="Key">
|
|
179
|
-
<input type="text" id="sessionValue" placeholder="Value">
|
|
180
|
-
<button
|
|
181
|
-
onclick="session.set(document.getElementById('sessionKey').value, document.getElementById('sessionValue').value)">Save</button>
|
|
182
|
-
<button
|
|
183
|
-
onclick="document.getElementById('sessionOutput').textContent = JSON.stringify(session.get(document.getElementById('sessionKey').value), null, 2)">Get</button>
|
|
184
|
-
<button class="danger" onclick="session.remove(document.getElementById('sessionKey').value)">Delete</button>
|
|
185
|
-
|
|
186
|
-
<h3>All Session Data:</h3>
|
|
187
|
-
<pre id="sessionOutput" class="output"></pre>
|
|
188
|
-
</div>
|
|
189
|
-
|
|
190
|
-
<!-- Cache Section -->
|
|
191
|
-
<div class="card">
|
|
192
|
-
<h2>4. Cache (In-Memory)</h2>
|
|
193
|
-
<p>Temporary cache - cleared on refresh</p>
|
|
194
|
-
|
|
195
|
-
<input type="text" id="cacheKey" placeholder="Key">
|
|
196
|
-
<input type="text" id="cacheValue" placeholder="Value">
|
|
197
|
-
<button
|
|
198
|
-
onclick="cache.set(document.getElementById('cacheKey').value, document.getElementById('cacheValue').value)">Save</button>
|
|
199
|
-
<button
|
|
200
|
-
onclick="document.getElementById('cacheOutput').textContent = JSON.stringify(cache.get(document.getElementById('cacheKey').value), null, 2)">Get</button>
|
|
201
|
-
<button class="danger" onclick="cache.remove(document.getElementById('cacheKey').value)">Delete</button>
|
|
202
|
-
|
|
203
|
-
<h3>All Cache Data:</h3>
|
|
204
|
-
<pre id="cacheOutput" class="output"></pre>
|
|
205
|
-
</div>
|
|
206
|
-
|
|
207
|
-
<!-- Observer Section -->
|
|
208
|
-
<div class="card">
|
|
209
|
-
<h2>5. Observer (Auto-Reactive)</h2>
|
|
210
|
-
<p>Watch for state changes automatically</p>
|
|
211
|
-
|
|
212
|
-
<button class="success" id="startObserver">Start Observer</button>
|
|
213
|
-
<button class="danger" id="stopObserver">Stop Observer</button>
|
|
214
|
-
<button onclick="state.testValue = Math.random()">Trigger Change</button>
|
|
215
|
-
|
|
216
|
-
<h3>Observer Log:</h3>
|
|
217
|
-
<pre id="observerLog" class="output"></pre>
|
|
218
|
-
</div>
|
|
219
|
-
|
|
220
|
-
<!-- Platform Info -->
|
|
221
|
-
<div class="card">
|
|
222
|
-
<h2>6. Platform Info</h2>
|
|
223
|
-
<div id="platformInfo" class="output"></div>
|
|
224
|
-
</div>
|
|
225
|
-
|
|
226
|
-
<!-- Load Memorio -->
|
|
227
|
-
<script src="https://cdn.jsdelivr.net/npm/memorio/index.cjs"></script>
|
|
228
|
-
|
|
229
|
-
<script>
|
|
230
|
-
// ============================================
|
|
231
|
-
// MEMORIO VANILLA JS EXAMPLE
|
|
232
|
-
// ============================================
|
|
233
|
-
|
|
234
|
-
// 1. REACTIVE STATE
|
|
235
|
-
// -----------------
|
|
236
|
-
|
|
237
|
-
// Initialize state
|
|
238
|
-
state.counter = 0
|
|
239
|
-
state.username = 'Guest'
|
|
240
|
-
state.theme = 'light'
|
|
241
|
-
state.testValue = 0
|
|
242
|
-
|
|
243
|
-
// Update UI when state changes
|
|
244
|
-
function updateStateUI() {
|
|
245
|
-
document.getElementById('counter').textContent = state.counter
|
|
246
|
-
document.getElementById('username').textContent = state.username
|
|
247
|
-
document.getElementById('theme').textContent = state.theme
|
|
248
|
-
document.getElementById('stateOutput').textContent = JSON.stringify({
|
|
249
|
-
counter: state.counter,
|
|
250
|
-
username: state.username,
|
|
251
|
-
theme: state.theme,
|
|
252
|
-
testValue: state.testValue
|
|
253
|
-
}, null, 2)
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Use observer to react to changes
|
|
257
|
-
useObserver(() => {
|
|
258
|
-
updateStateUI()
|
|
259
|
-
document.body.className = state.theme
|
|
260
|
-
}, [state.counter, state.username, state.theme, state.testValue])
|
|
261
|
-
|
|
262
|
-
// 2. PERSISTENT STORE
|
|
263
|
-
// -------------------
|
|
264
|
-
|
|
265
|
-
// Check persistence
|
|
266
|
-
document.getElementById('storePersistent').textContent = store.isPersistent ? '✅ Yes (localStorage)' : '❌ No (memory)'
|
|
267
|
-
|
|
268
|
-
// Save sample data
|
|
269
|
-
store.set('visits', '0')
|
|
270
|
-
store.set('lastVisit', new Date().toISOString())
|
|
271
|
-
|
|
272
|
-
function updateStoreUI() {
|
|
273
|
-
document.getElementById('storeOutput').textContent = 'Visits: ' + store.get('visits') + '\nLast Visit: ' + store.get('lastVisit')
|
|
274
|
-
}
|
|
275
|
-
updateStoreUI()
|
|
276
|
-
|
|
277
|
-
// Increment visits
|
|
278
|
-
let visits = parseInt(store.get('visits') || '0')
|
|
279
|
-
store.set('visits', (visits + 1).toString())
|
|
280
|
-
|
|
281
|
-
// 3. SESSION STORAGE
|
|
282
|
-
// ------------------
|
|
283
|
-
|
|
284
|
-
document.getElementById('sessionPersistent').textContent = session.isPersistent ? '✅ Yes (sessionStorage)' : '❌ No (memory)'
|
|
285
|
-
|
|
286
|
-
session.set('pageViews', '0')
|
|
287
|
-
|
|
288
|
-
function updateSessionUI() {
|
|
289
|
-
document.getElementById('sessionOutput').textContent = 'Page Views: ' + session.get('pageViews')
|
|
290
|
-
}
|
|
291
|
-
updateSessionUI()
|
|
292
|
-
|
|
293
|
-
// Increment page views
|
|
294
|
-
let pageViews = parseInt(session.get('pageViews') || '0')
|
|
295
|
-
session.set('pageViews', (pageViews + 1).toString())
|
|
296
|
-
|
|
297
|
-
// 4. CACHE (In-Memory)
|
|
298
|
-
// --------------------
|
|
299
|
-
|
|
300
|
-
cache.set('tempData', { computed: true, timestamp: Date.now() })
|
|
301
|
-
|
|
302
|
-
function updateCacheUI() {
|
|
303
|
-
document.getElementById('cacheOutput').textContent = JSON.stringify(cache.get('tempData'), null, 2)
|
|
304
|
-
}
|
|
305
|
-
updateCacheUI()
|
|
306
|
-
|
|
307
|
-
// 5. OBSERVER
|
|
308
|
-
// -----------
|
|
309
|
-
|
|
310
|
-
let observerActive = false
|
|
311
|
-
const logEl = document.getElementById('observerLog')
|
|
312
|
-
|
|
313
|
-
document.getElementById('startObserver').onclick = () => {
|
|
314
|
-
observerActive = true
|
|
315
|
-
logEl.textContent += 'Observer started!\n'
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
document.getElementById('stopObserver').onclick = () => {
|
|
319
|
-
observerActive = false
|
|
320
|
-
logEl.textContent += 'Observer stopped!\n'
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// This creates a persistent observer
|
|
324
|
-
useObserver((newVal, oldVal) => {
|
|
325
|
-
if (observerActive) {
|
|
326
|
-
logEl.textContent += `Changed: ${oldVal} → ${newVal}\n`
|
|
327
|
-
logEl.scrollTop = logEl.scrollHeight
|
|
328
|
-
}
|
|
329
|
-
}, [state.testValue])
|
|
330
|
-
|
|
331
|
-
// 6. PLATFORM INFO
|
|
332
|
-
// ----------------
|
|
333
|
-
|
|
334
|
-
const platformInfo = document.getElementById('platformInfo')
|
|
335
|
-
platformInfo.textContent = `
|
|
336
|
-
Platform Detection:
|
|
337
|
-
-----------------
|
|
338
|
-
Browser: ${memorio.isBrowser() ? '✅' : '❌'}
|
|
339
|
-
Node.js: ${memorio.isNode() ? '✅' : '❌'}
|
|
340
|
-
Deno: ${memorio.isDeno() ? '✅' : '❌'}
|
|
341
|
-
Edge: ${memorio.isEdge() ? '✅' : '❌'}
|
|
342
|
-
|
|
343
|
-
Capabilities:
|
|
344
|
-
-------------
|
|
345
|
-
localStorage: ${memorio.getCapabilities().hasLocalStorage ? '✅' : '❌'}
|
|
346
|
-
sessionStorage: ${memorio.getCapabilities().hasSessionStorage ? '✅' : '❌'}
|
|
347
|
-
IndexedDB: ${memorio.getCapabilities().hasIndexedDB ? '✅' : '❌'}
|
|
348
|
-
|
|
349
|
-
Session ID: ${memorio.getCapabilities().sessionId.substring(0, 8)}...
|
|
350
|
-
`.trim()
|
|
351
|
-
|
|
352
|
-
// Log welcome
|
|
353
|
-
console.debug('🧠 Memorio loaded!')
|
|
354
|
-
console.debug('Platform:', memorio.getCapabilities().platform)
|
|
355
|
-
</script>
|
|
356
|
-
</body>
|
|
357
|
-
|
|
358
|
-
</html>
|
package/examples/cache.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memorio Cache Example
|
|
3
|
-
*
|
|
4
|
-
* This example demonstrates the cache module for in-memory storage.
|
|
5
|
-
* Cache is perfect for temporary data that doesn't need persistence.
|
|
6
|
-
*
|
|
7
|
-
* Run: npx ts-node examples/cache.ts
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import 'memorio'
|
|
11
|
-
|
|
12
|
-
// ============================================
|
|
13
|
-
// BASIC CACHE OPERATIONS
|
|
14
|
-
// ============================================
|
|
15
|
-
|
|
16
|
-
// Set values
|
|
17
|
-
cache.set('username', 'Mario')
|
|
18
|
-
cache.set('score', 1500)
|
|
19
|
-
cache.set('player', { name: 'Mario', level: 5 })
|
|
20
|
-
|
|
21
|
-
// Get values
|
|
22
|
-
console.debug('Username:', cache.get('username'))
|
|
23
|
-
console.debug('Score:', cache.get('score'))
|
|
24
|
-
console.debug('Player:', cache.get('player'))
|
|
25
|
-
|
|
26
|
-
// Direct property access
|
|
27
|
-
cache.tempData = 'Hello'
|
|
28
|
-
console.debug('Temp data:', cache.tempData)
|
|
29
|
-
|
|
30
|
-
// ============================================
|
|
31
|
-
// CACHE WITH OBJECTS
|
|
32
|
-
// ============================================
|
|
33
|
-
|
|
34
|
-
// Store complex objects
|
|
35
|
-
cache.set('gameState', {
|
|
36
|
-
level: 3,
|
|
37
|
-
score: 2500,
|
|
38
|
-
inventory: ['sword', 'shield', 'potion'],
|
|
39
|
-
position: { x: 100, y: 200 }
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
const gameState = cache.get('gameState')
|
|
43
|
-
console.debug('Game level:', gameState?.level)
|
|
44
|
-
console.debug('Inventory:', gameState?.inventory)
|
|
45
|
-
|
|
46
|
-
// ============================================
|
|
47
|
-
// CACHE SIZE
|
|
48
|
-
// ============================================
|
|
49
|
-
|
|
50
|
-
// Add multiple items
|
|
51
|
-
for (let i = 0; i < 10; i++) {
|
|
52
|
-
cache.set(`item_${i}`, { id: i, data: `item-${i}` })
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
console.debug('Cache keys:', Object.keys(cache))
|
|
56
|
-
|
|
57
|
-
// ============================================
|
|
58
|
-
// CLEANUP
|
|
59
|
-
// ============================================
|
|
60
|
-
|
|
61
|
-
// Remove single item
|
|
62
|
-
cache.remove('username')
|
|
63
|
-
|
|
64
|
-
// Clear all cache
|
|
65
|
-
cache.removeAll()
|
|
66
|
-
|
|
67
|
-
// Or use clearAll alias
|
|
68
|
-
// cache.clearAll()
|
|
69
|
-
|
|
70
|
-
console.debug('Cache after clear:', cache.get('score'))
|
|
71
|
-
|
|
72
|
-
console.debug('Cache example complete!')
|