memorio 3.0.1 → 4.0.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/README.md +61 -54
- package/docs/README.md +61 -54
- package/docs/markdown/CACHE.md +3 -3
- package/docs/markdown/CHANGELOG.md +63 -154
- package/docs/markdown/DEVTOOLS.md +1 -1
- package/docs/markdown/IDB.md +3 -3
- package/docs/markdown/LOGGER.md +2 -2
- package/docs/markdown/OBSERVER.md +4 -4
- package/docs/markdown/PLATFORM.md +5 -5
- package/docs/markdown/SECURITY.md +16 -4
- package/docs/markdown/SESSION.md +4 -4
- package/docs/markdown/STATE.md +7 -7
- package/docs/markdown/STORE.md +7 -7
- package/docs/markdown/USEOBSERVER.md +1 -1
- package/examples/react-app.tsx +6 -1
- package/index.cjs +461 -143
- package/index.js +461 -141
- package/package.json +10 -1
- package/types/memorio.d.ts +6 -0
package/README.md
CHANGED
|
@@ -25,12 +25,11 @@ Zero friction. Zero bloat. Single import. Works everywhere JavaScript runs.
|
|
|
25
25
|
| | memorio | Redux | Zustand |
|
|
26
26
|
|---|---|---|---|
|
|
27
27
|
| **Setup** | 1 import | Boilerplate hell | Moderate |
|
|
28
|
-
| **Bundle size** | **~8 KB** | ~30 KB | ~15 KB |
|
|
29
28
|
| **Dependencies** | **Zero** | Many | Few |
|
|
30
29
|
| **TypeScript** | ✅ Native | ✅ | ✅ |
|
|
31
30
|
| **Binary storage** | ✅ Built-in IDB | ❌ Add-on | ❌ |
|
|
32
31
|
| **Observer** | ✅ Built-in | ❌ Add-on | ❌ |
|
|
33
|
-
| **DevTools** | ✅ Built-in | ❌ Extension | ❌ |
|
|
32
|
+
| **DevTools** | ✅ Built-in + dphelper-manager extension | ❌ Extension | ❌ |
|
|
34
33
|
| **Running on the edge** | ✅ Workers, Deno | ⚠️ Limited | ⚠️ Limited |
|
|
35
34
|
|
|
36
35
|
If you need a `store` on the server. A `cache` in the edge worker.
|
|
@@ -114,22 +113,6 @@ state.lock() // freeze everything
|
|
|
114
113
|
state.unlock() // unfreeze
|
|
115
114
|
```
|
|
116
115
|
|
|
117
|
-
### `useObserver` — React hook (with auto-discovery)
|
|
118
|
-
|
|
119
|
-
```jsx
|
|
120
|
-
import 'memorio'
|
|
121
|
-
import { useObserver } from 'memorio'
|
|
122
|
-
|
|
123
|
-
function Counter() {
|
|
124
|
-
const [, forceUpdate] = useReducer(x => x + 1, 0)
|
|
125
|
-
|
|
126
|
-
useObserver(forceUpdate, [state.counter])
|
|
127
|
-
// State path auto-discovered during render — no manual deps needed
|
|
128
|
-
|
|
129
|
-
return <div>Count: {state.counter}</div>
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
116
|
### `store` — localStorage, survives refresh
|
|
134
117
|
|
|
135
118
|
```javascript
|
|
@@ -160,16 +143,35 @@ cache.clear() // empty it all
|
|
|
160
143
|
### `idb` — IndexedDB, structured & typed
|
|
161
144
|
|
|
162
145
|
```javascript
|
|
163
|
-
// Create a database
|
|
164
146
|
await idb.db.create('my-db')
|
|
165
|
-
// Then create tables
|
|
166
147
|
await idb.table.create('my-db', 'users')
|
|
167
|
-
await idb.table.create('my-db', 'posts')
|
|
168
|
-
|
|
169
|
-
// CRUD
|
|
170
148
|
await idb.data.set('my-db', 'users', { id: 1, name: 'Sara' })
|
|
171
|
-
const user = await idb.data.get('my-db', 'users', 1)
|
|
172
|
-
|
|
149
|
+
const user = await idb.data.get('my-db', 'users', 1)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### `observer` — Object watcher (DEPRECATED)
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
globalThis.observer('state.user', (newVal, oldVal) => {
|
|
156
|
+
console.debug('user changed:', newVal, oldVal)
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### `useObserver` — React observer hook
|
|
161
|
+
|
|
162
|
+
Available globally after `import 'memorio'`.
|
|
163
|
+
|
|
164
|
+
```jsx
|
|
165
|
+
import 'memorio'
|
|
166
|
+
|
|
167
|
+
function Counter() {
|
|
168
|
+
const [, forceUpdate] = useReducer(x => x + 1, 0)
|
|
169
|
+
|
|
170
|
+
useObserver(forceUpdate, [state.counter])
|
|
171
|
+
// State path auto-discovered during render — no manual deps needed
|
|
172
|
+
|
|
173
|
+
return <div>Count: {state.counter}</div>
|
|
174
|
+
}
|
|
173
175
|
```
|
|
174
176
|
|
|
175
177
|
### `devtools` — inspect everything in one call
|
|
@@ -182,6 +184,8 @@ memorio.devtools.exportData() // JSON snapshot
|
|
|
182
184
|
$state // console shortcut — same as globalThis.state
|
|
183
185
|
```
|
|
184
186
|
|
|
187
|
+
> **Browser Extension Integration:** When used with dphelper-manager browser extension, memorio's global state namespace is automatically detected and visualized through a dedicated DevTools panel, providing time-travel debugging and structural guardrails.
|
|
188
|
+
|
|
185
189
|
### `logger` — track every change
|
|
186
190
|
|
|
187
191
|
```javascript
|
|
@@ -191,6 +195,29 @@ memorio.logger.getStats() // { total, state, set, get, ... }
|
|
|
191
195
|
memorio.logger.exportLogs() // JSON string of all history
|
|
192
196
|
```
|
|
193
197
|
|
|
198
|
+
### Platform detection
|
|
199
|
+
|
|
200
|
+
Access via `memorio.*`:
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
memorio.isBrowser() // true in Chrome, Firefox, Safari
|
|
204
|
+
memorio.isNode() // true in Node.js
|
|
205
|
+
memorio.isDeno() // true in Deno
|
|
206
|
+
memorio.isEdge() // true in Cloudflare Workers, Vercel Edge
|
|
207
|
+
|
|
208
|
+
const caps = memorio.getCapabilities()
|
|
209
|
+
// { platform: 'browser', hasLocalStorage: true, hasIndexedDB: true, ... }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Context (multi-tenant)
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
memorio.createContext('tenant-name')
|
|
216
|
+
memorio.listContexts()
|
|
217
|
+
memorio.deleteContext('context-id')
|
|
218
|
+
memorio.isolate('tenant-name')
|
|
219
|
+
```
|
|
220
|
+
|
|
194
221
|
---
|
|
195
222
|
|
|
196
223
|
## Cross-Platform
|
|
@@ -209,32 +236,18 @@ Memorio runs in every JavaScript environment, with automatic fallbacks.
|
|
|
209
236
|
|
|
210
237
|
> **Why memory fallbacks on the server?** There is no browser. `store` and `session` gracefully fall back to `Map`. You still get the same API. Same `state`, same `cache`, same `useObserver`. No extra config required.
|
|
211
238
|
|
|
212
|
-
###
|
|
213
|
-
|
|
214
|
-
```javascript
|
|
215
|
-
import { isBrowser, isNode, isDeno, isEdge, getCapabilities } from 'memorio'
|
|
239
|
+
### Platform detection
|
|
216
240
|
|
|
217
|
-
|
|
218
|
-
isNode() // true in Node.js
|
|
219
|
-
isDeno() // true in Deno
|
|
220
|
-
isEdge() // true in Cloudflare Workers, Vercel Edge
|
|
241
|
+
Access via `memorio.*` after `import 'memorio'`:
|
|
221
242
|
|
|
222
|
-
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
## Testing
|
|
229
|
-
|
|
230
|
-
```
|
|
231
|
-
71 tests · 8 suites · all passing
|
|
232
|
-
|
|
233
|
-
state | store | session | cache | observer | useObserver | devtools | logger
|
|
234
|
-
```
|
|
243
|
+
```javascript
|
|
244
|
+
memorio.isBrowser() // true in Chrome, Firefox, Safari
|
|
245
|
+
memorio.isNode() // true in Node.js
|
|
246
|
+
memorio.isDeno() // true in Deno
|
|
247
|
+
memorio.isEdge() // true in Cloudflare Workers, Vercel Edge
|
|
235
248
|
|
|
236
|
-
|
|
237
|
-
|
|
249
|
+
const c = memorio.getCapabilities()
|
|
250
|
+
// { platform: 'browser', hasLocalStorage: true, hasIndexedDB: true, ... }
|
|
238
251
|
```
|
|
239
252
|
|
|
240
253
|
---
|
|
@@ -287,14 +300,8 @@ basic | state | store | session | cache | idb | observer | useObserver
|
|
|
287
300
|
| Observer | 12 | ✅ |
|
|
288
301
|
| useObserver | 12 | ✅ |
|
|
289
302
|
|
|
290
|
-
```bash
|
|
291
|
-
npm test
|
|
292
|
-
```
|
|
293
|
-
|
|
294
303
|
---
|
|
295
304
|
|
|
296
305
|
## License
|
|
297
306
|
|
|
298
307
|
MIT © [Dario Passariello](https://dario.passariello.ca)
|
|
299
|
-
|
|
300
|
-
© [BigLogic Inc Canada](https//biglogic.ca)
|
package/docs/README.md
CHANGED
|
@@ -25,12 +25,11 @@ Zero friction. Zero bloat. Single import. Works everywhere JavaScript runs.
|
|
|
25
25
|
| | memorio | Redux | Zustand |
|
|
26
26
|
|---|---|---|---|
|
|
27
27
|
| **Setup** | 1 import | Boilerplate hell | Moderate |
|
|
28
|
-
| **Bundle size** | **~8 KB** | ~30 KB | ~15 KB |
|
|
29
28
|
| **Dependencies** | **Zero** | Many | Few |
|
|
30
29
|
| **TypeScript** | ✅ Native | ✅ | ✅ |
|
|
31
30
|
| **Binary storage** | ✅ Built-in IDB | ❌ Add-on | ❌ |
|
|
32
31
|
| **Observer** | ✅ Built-in | ❌ Add-on | ❌ |
|
|
33
|
-
| **DevTools** | ✅ Built-in | ❌ Extension | ❌ |
|
|
32
|
+
| **DevTools** | ✅ Built-in + dphelper-manager extension | ❌ Extension | ❌ |
|
|
34
33
|
| **Running on the edge** | ✅ Workers, Deno | ⚠️ Limited | ⚠️ Limited |
|
|
35
34
|
|
|
36
35
|
If you need a `store` on the server. A `cache` in the edge worker.
|
|
@@ -114,22 +113,6 @@ state.lock() // freeze everything
|
|
|
114
113
|
state.unlock() // unfreeze
|
|
115
114
|
```
|
|
116
115
|
|
|
117
|
-
### `useObserver` — React hook (with auto-discovery)
|
|
118
|
-
|
|
119
|
-
```jsx
|
|
120
|
-
import 'memorio'
|
|
121
|
-
import { useObserver } from 'memorio'
|
|
122
|
-
|
|
123
|
-
function Counter() {
|
|
124
|
-
const [, forceUpdate] = useReducer(x => x + 1, 0)
|
|
125
|
-
|
|
126
|
-
useObserver(forceUpdate, [state.counter])
|
|
127
|
-
// State path auto-discovered during render — no manual deps needed
|
|
128
|
-
|
|
129
|
-
return <div>Count: {state.counter}</div>
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
116
|
### `store` — localStorage, survives refresh
|
|
134
117
|
|
|
135
118
|
```javascript
|
|
@@ -160,16 +143,35 @@ cache.clear() // empty it all
|
|
|
160
143
|
### `idb` — IndexedDB, structured & typed
|
|
161
144
|
|
|
162
145
|
```javascript
|
|
163
|
-
// Create a database
|
|
164
146
|
await idb.db.create('my-db')
|
|
165
|
-
// Then create tables
|
|
166
147
|
await idb.table.create('my-db', 'users')
|
|
167
|
-
await idb.table.create('my-db', 'posts')
|
|
168
|
-
|
|
169
|
-
// CRUD
|
|
170
148
|
await idb.data.set('my-db', 'users', { id: 1, name: 'Sara' })
|
|
171
|
-
const user = await idb.data.get('my-db', 'users', 1)
|
|
172
|
-
|
|
149
|
+
const user = await idb.data.get('my-db', 'users', 1)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### `observer` — Object watcher (DEPRECATED)
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
globalThis.observer('state.user', (newVal, oldVal) => {
|
|
156
|
+
console.debug('user changed:', newVal, oldVal)
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### `useObserver` — React observer hook
|
|
161
|
+
|
|
162
|
+
Available globally after `import 'memorio'`.
|
|
163
|
+
|
|
164
|
+
```jsx
|
|
165
|
+
import 'memorio'
|
|
166
|
+
|
|
167
|
+
function Counter() {
|
|
168
|
+
const [, forceUpdate] = useReducer(x => x + 1, 0)
|
|
169
|
+
|
|
170
|
+
useObserver(forceUpdate, [state.counter])
|
|
171
|
+
// State path auto-discovered during render — no manual deps needed
|
|
172
|
+
|
|
173
|
+
return <div>Count: {state.counter}</div>
|
|
174
|
+
}
|
|
173
175
|
```
|
|
174
176
|
|
|
175
177
|
### `devtools` — inspect everything in one call
|
|
@@ -182,6 +184,8 @@ memorio.devtools.exportData() // JSON snapshot
|
|
|
182
184
|
$state // console shortcut — same as globalThis.state
|
|
183
185
|
```
|
|
184
186
|
|
|
187
|
+
> **Browser Extension Integration:** When used with dphelper-manager browser extension, memorio's global state namespace is automatically detected and visualized through a dedicated DevTools panel, providing time-travel debugging and structural guardrails.
|
|
188
|
+
|
|
185
189
|
### `logger` — track every change
|
|
186
190
|
|
|
187
191
|
```javascript
|
|
@@ -191,6 +195,29 @@ memorio.logger.getStats() // { total, state, set, get, ... }
|
|
|
191
195
|
memorio.logger.exportLogs() // JSON string of all history
|
|
192
196
|
```
|
|
193
197
|
|
|
198
|
+
### Platform detection
|
|
199
|
+
|
|
200
|
+
Access via `memorio.*`:
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
memorio.isBrowser() // true in Chrome, Firefox, Safari
|
|
204
|
+
memorio.isNode() // true in Node.js
|
|
205
|
+
memorio.isDeno() // true in Deno
|
|
206
|
+
memorio.isEdge() // true in Cloudflare Workers, Vercel Edge
|
|
207
|
+
|
|
208
|
+
const caps = memorio.getCapabilities()
|
|
209
|
+
// { platform: 'browser', hasLocalStorage: true, hasIndexedDB: true, ... }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Context (multi-tenant)
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
memorio.createContext('tenant-name')
|
|
216
|
+
memorio.listContexts()
|
|
217
|
+
memorio.deleteContext('context-id')
|
|
218
|
+
memorio.isolate('tenant-name')
|
|
219
|
+
```
|
|
220
|
+
|
|
194
221
|
---
|
|
195
222
|
|
|
196
223
|
## Cross-Platform
|
|
@@ -209,32 +236,18 @@ Memorio runs in every JavaScript environment, with automatic fallbacks.
|
|
|
209
236
|
|
|
210
237
|
> **Why memory fallbacks on the server?** There is no browser. `store` and `session` gracefully fall back to `Map`. You still get the same API. Same `state`, same `cache`, same `useObserver`. No extra config required.
|
|
211
238
|
|
|
212
|
-
###
|
|
213
|
-
|
|
214
|
-
```javascript
|
|
215
|
-
import { isBrowser, isNode, isDeno, isEdge, getCapabilities } from 'memorio'
|
|
239
|
+
### Platform detection
|
|
216
240
|
|
|
217
|
-
|
|
218
|
-
isNode() // true in Node.js
|
|
219
|
-
isDeno() // true in Deno
|
|
220
|
-
isEdge() // true in Cloudflare Workers, Vercel Edge
|
|
241
|
+
Access via `memorio.*` after `import 'memorio'`:
|
|
221
242
|
|
|
222
|
-
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
## Testing
|
|
229
|
-
|
|
230
|
-
```
|
|
231
|
-
71 tests · 8 suites · all passing
|
|
232
|
-
|
|
233
|
-
state | store | session | cache | observer | useObserver | devtools | logger
|
|
234
|
-
```
|
|
243
|
+
```javascript
|
|
244
|
+
memorio.isBrowser() // true in Chrome, Firefox, Safari
|
|
245
|
+
memorio.isNode() // true in Node.js
|
|
246
|
+
memorio.isDeno() // true in Deno
|
|
247
|
+
memorio.isEdge() // true in Cloudflare Workers, Vercel Edge
|
|
235
248
|
|
|
236
|
-
|
|
237
|
-
|
|
249
|
+
const c = memorio.getCapabilities()
|
|
250
|
+
// { platform: 'browser', hasLocalStorage: true, hasIndexedDB: true, ... }
|
|
238
251
|
```
|
|
239
252
|
|
|
240
253
|
---
|
|
@@ -287,14 +300,8 @@ basic | state | store | session | cache | idb | observer | useObserver
|
|
|
287
300
|
| Observer | 12 | ✅ |
|
|
288
301
|
| useObserver | 12 | ✅ |
|
|
289
302
|
|
|
290
|
-
```bash
|
|
291
|
-
npm test
|
|
292
|
-
```
|
|
293
|
-
|
|
294
303
|
---
|
|
295
304
|
|
|
296
305
|
## License
|
|
297
306
|
|
|
298
307
|
MIT © [Dario Passariello](https://dario.passariello.ca)
|
|
299
|
-
|
|
300
|
-
© [BigLogic Inc Canada](https//biglogic.ca)
|
package/docs/markdown/CACHE.md
CHANGED
|
@@ -26,8 +26,8 @@ cache.set('username', 'Mario');
|
|
|
26
26
|
cache.set('score', 1500);
|
|
27
27
|
|
|
28
28
|
// Read data
|
|
29
|
-
console.
|
|
30
|
-
console.
|
|
29
|
+
console.debug(cache.get('username')); // "Mario"
|
|
30
|
+
console.debug(cache.get('score')); // 1500
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
### Example 2: Intermediate
|
|
@@ -36,7 +36,7 @@ console.log(cache.get('score')); // 1500
|
|
|
36
36
|
// Store objects
|
|
37
37
|
cache.set('user', { name: 'Luigi', level: 5 });
|
|
38
38
|
const user = cache.get('user');
|
|
39
|
-
console.
|
|
39
|
+
console.debug(user.name); // "Luigi"
|
|
40
40
|
|
|
41
41
|
// Remove single item
|
|
42
42
|
cache.remove('username');
|
|
@@ -4,181 +4,90 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
### 🚀 New Features
|
|
10
|
-
|
|
11
|
-
#### 1. Platform Compatibility Layer
|
|
12
|
-
- **Auto-detection**: Automatically detects Browser, Node.js, Deno, Edge Workers
|
|
13
|
-
- **Polyfills**: Automatic fallback for server environments
|
|
14
|
-
- **New exports**:
|
|
15
|
-
- `memorio.isBrowser()` - Check if running in browser
|
|
16
|
-
- `memorio.isNode()` - Check if running in Node.js
|
|
17
|
-
- `memorio.isDeno()` - Check if running in Deno
|
|
18
|
-
- `memorio.isEdge()` - Check if running in Edge Worker
|
|
19
|
-
- `memorio.getCapabilities()` - Get platform capabilities
|
|
20
|
-
|
|
21
|
-
#### 2. Session Isolation
|
|
22
|
-
- **Unique Session IDs**: Each import/session gets unique ID via `crypto.randomUUID()`
|
|
23
|
-
- **Namespaced Storage**: Keys prefixed with session ID to prevent cross-contamination
|
|
24
|
-
- **Format**: `memorio_store_[session-uuid]_keyname`
|
|
25
|
-
|
|
26
|
-
#### 3. Context Isolation (Multi-Tenant Support)
|
|
27
|
-
- **New API**:
|
|
28
|
-
- `memorio.createContext(name?)` - Create isolated context
|
|
29
|
-
- `memorio.listContexts()` - List all contexts
|
|
30
|
-
- `memorio.deleteContext(id)` - Delete context
|
|
31
|
-
- `memorio.isolate(name?)` - Alias for createContext
|
|
32
|
-
|
|
33
|
-
#### 4. Persistence Detection
|
|
34
|
-
- **New Properties**:
|
|
35
|
-
- `store.isPersistent` - Check if using real localStorage
|
|
36
|
-
- `session.isPersistent` - Check if using real sessionStorage
|
|
7
|
+
## v3.0.2 (Current) - 2026-05-19 — Bug Fix, Security & API Expansion
|
|
37
8
|
|
|
38
|
-
###
|
|
39
|
-
|
|
40
|
-
| Feature | Before v2.7.0 | After v2.7.0 |
|
|
41
|
-
|---------|---------------|--------------|
|
|
42
|
-
| Session ID | `Math.random()` | `crypto.randomUUID()` |
|
|
43
|
-
| Key Validation | None | Max 512 chars + whitelist |
|
|
44
|
-
| Server Isolation | None | Context system |
|
|
45
|
-
| Fallback Security | Basic | `crypto.getRandomValues()` |
|
|
46
|
-
|
|
47
|
-
### 📝 Documentation Updates
|
|
48
|
-
|
|
49
|
-
- **New Documents**:
|
|
50
|
-
- [`PLATFORM.md`](PLATFORM.md) - Platform compatibility guide
|
|
51
|
-
- [`SECURITY.md`](SECURITY.md) - Security documentation
|
|
9
|
+
### 🐛 Bug Fixes
|
|
52
10
|
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
11
|
+
- Removed dead code: `buildPathTracker` from `functions/state/index.ts` (unused Proxy builder, exported nowhere)
|
|
12
|
+
- Removed double `delete` in state `removeAll` handler (redundant null-check + delete on same key)
|
|
13
|
+
- Removed unbound `globalThis.state` reference in state init (would throw `ReferenceError` in strict mode)
|
|
14
|
+
- Removed `Object.freeze(observer)` referencing undeclared variable (`ReferenceError` on module load)
|
|
15
|
+
- Removed `confirm()` synchronous blocking call from `idb.db.delete` (library must not block main thread)
|
|
57
16
|
|
|
58
|
-
###
|
|
17
|
+
### 🔒 Security Improvements
|
|
59
18
|
|
|
60
|
-
-
|
|
61
|
-
|
|
19
|
+
- Removed `esbuild-sass-plugin` and `esbuild-scss-modules-plugin` from `devDependencies` (unnecessary for a library with no styles)
|
|
20
|
+
- Removed `injectStyle: true`, `sassPlugin()` and `.css` loader from `tsup.config.ts`
|
|
21
|
+
- Deleted `tsup.plugin.injectCss.ts` (code injection vector completely removed from build pipeline)
|
|
22
|
+
- `console.error`/`console.warn` → `console.debug` in `devtools` and `idb` error handlers (consistent debug-only logging policy)
|
|
23
|
+
- `store.set()` now blocks function values instead of silently logging and continuing
|
|
24
|
+
- All `PRIVATE License` headers in `functions/idb/` replaced with `MIT License`
|
|
62
25
|
|
|
63
|
-
|
|
64
|
-
- [`examples/basic.ts`](../examples/basic.ts) - Platform detection added
|
|
65
|
-
- [`examples/store-advanced.ts`](../examples/store-advanced.ts) - isPersistent check
|
|
66
|
-
- [`examples/session-advanced.ts`](../examples/session-advanced.ts) - isPersistent check
|
|
26
|
+
### 🔧 Code Quality
|
|
67
27
|
|
|
68
|
-
|
|
28
|
+
- Added JSDoc to `observerFunction` in `functions/observer/index.ts`
|
|
29
|
+
- Added JSDoc to `cache` global in `functions/cache/index.ts`
|
|
30
|
+
- `lint` and `tsc` pass clean — 0 vulnerabilities from `npm audit`
|
|
69
31
|
|
|
70
|
-
|
|
71
|
-
|--------|--------|-----------|
|
|
72
|
-
| Key validation | Low | Invalid keys now rejected with debug message |
|
|
73
|
-
| Storage key format | Low | Keys now prefixed with session ID |
|
|
32
|
+
### 🆕 API — New in 3.0.2
|
|
74
33
|
|
|
75
|
-
|
|
34
|
+
| Function | Description |
|
|
35
|
+
|----------|-------------|
|
|
36
|
+
| `memorio.isBrowser()` | Returns `true` when running in a browser |
|
|
37
|
+
| `memorio.isNode()` | Returns `true` when running in Node.js |
|
|
38
|
+
| `memorio.isDeno()` | Returns `true` when running in Deno |
|
|
39
|
+
| `memorio.isEdge()` | Returns `true` in Cloudflare Workers, Vercel Edge, etc. |
|
|
40
|
+
| `memorio.getCapabilities()` | Full capabilities object (`platform`, `hasLocalStorage`, `hasIndexedDB`, …) |
|
|
41
|
+
| `memorio.createContext(name?)` | Create multi-tenant isolated context |
|
|
42
|
+
| `memorio.listContexts()` | List all active isolated contexts |
|
|
43
|
+
| `memorio.deleteContext(id)` | Delete isolated context by ID |
|
|
44
|
+
| `memorio.isolate(name?)` | Shorthand alias for `createContext` |
|
|
76
45
|
|
|
77
|
-
|
|
78
|
-
- `config/platform.ts` - Platform detection + Context system
|
|
46
|
+
### 🧪 Tests
|
|
79
47
|
|
|
80
|
-
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
- `functions/session/index.ts` - Added validation + isPersistent
|
|
48
|
+
- Created `tests/jest/tests/observer.test.ts` — 12 tests (deprecation warning, input validation, `.list`, `.remove`, `.removeAll`)
|
|
49
|
+
- Created `tests/jest/tests/useObserver.test.ts` — 12 tests (existence, edge cases, proxy/string deps, auto-discovery, cleanup)
|
|
50
|
+
- **Result: 8 suites · 95 passed · 3 skipped · 0 failed**
|
|
84
51
|
|
|
85
|
-
|
|
52
|
+
### 🗑️ Dependency Changes
|
|
86
53
|
|
|
87
|
-
|
|
54
|
+
| Removed | Reason |
|
|
55
|
+
|---------|--------|
|
|
56
|
+
| `esbuild-sass-plugin@3.7.0` | No SCSS in a library |
|
|
57
|
+
| `esbuild-scss-modules-plugin@1.1.1` | No SCSS in a library |
|
|
58
|
+
| 36 transitive packages | Removed from `node_modules` |
|
|
88
59
|
|
|
89
|
-
|
|
60
|
+
### 📝 Documentation Updates
|
|
90
61
|
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
- Cache (in-memory)
|
|
98
|
-
- IDB (IndexedDB wrapper)
|
|
99
|
-
- DevTools
|
|
100
|
-
- Logger
|
|
62
|
+
- `docs/README.md`: replaced `console.log` with `console.debug` in usage examples; fixed `esbuild` badge → `tsup`
|
|
63
|
+
- `.github/CHANGELOG.md`: restructured with fix / security / changed sections
|
|
64
|
+
- `.github/HISTORY.md`: complete rewrite through v3.0.2
|
|
65
|
+
- `.github/SECURITY.md`: NIST/NSA standard + OWASP Top 10 mapping
|
|
66
|
+
- `.github/CITATION.cff`: license PRIVATE → MIT to match `package.json`
|
|
67
|
+
- `.project/*`: all context documents updated to v3.0.2
|
|
101
68
|
|
|
102
69
|
---
|
|
103
70
|
|
|
104
|
-
##
|
|
105
|
-
|
|
106
|
-
### 1. Platform Detection (Optional)
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
// NEW: Check platform
|
|
110
|
-
if (memorio.isNode()) {
|
|
111
|
-
console.log('Running on server')
|
|
112
|
-
}
|
|
113
|
-
```
|
|
71
|
+
## v2.9.0 — 2026-05-13
|
|
114
72
|
|
|
115
|
-
###
|
|
73
|
+
### Added
|
|
74
|
+
- DevTools — `memorio.devtools.inspect()`, `stats()`, `exportData()`
|
|
75
|
+
- Logger with full history, stats and export
|
|
76
|
+
- Platform detection (`isBrowser`, `isNode`, `isDeno`, `isEdge`, `getCapabilities`)
|
|
77
|
+
- Session isolation via `crypto.randomUUID()`
|
|
116
78
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
console.warn('Data will be lost on restart!')
|
|
121
|
-
}
|
|
122
|
-
```
|
|
79
|
+
### Changed
|
|
80
|
+
- Updated dependencies to latest versions
|
|
81
|
+
- Improved cross-platform support (Deno, Edge Workers, Node.js)
|
|
123
82
|
|
|
124
|
-
###
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// NEW: Create isolated context per request
|
|
128
|
-
app.use((req, res, next) => {
|
|
129
|
-
req.ctx = memorio.createContext(`req-${req.id}`)
|
|
130
|
-
next()
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
app.get('/data', (req, res) => {
|
|
134
|
-
req.ctx.state.user = getUser()
|
|
135
|
-
// Each request has isolated state
|
|
136
|
-
})
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### 4. Key Validation (Automatic)
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
// Keys are now validated - invalid keys rejected
|
|
143
|
-
store.set('valid-key', 'value') // ✅ Works
|
|
144
|
-
store.set('key with spaces', 'x') // ❌ Rejected (debug message)
|
|
145
|
-
store.set('key>1000chars', 'x') // ❌ Rejected if >512 chars
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## Comparison Table: v2.6.x vs v2.7.0
|
|
151
|
-
|
|
152
|
-
| Feature | v2.6.x | v2.7.0 |
|
|
153
|
-
|---------|--------|--------|
|
|
154
|
-
| **Platform Support** | | |
|
|
155
|
-
| Browser | ✅ | ✅ |
|
|
156
|
-
| Node.js | ⚠️ Partial | ✅ Full |
|
|
157
|
-
| Deno | ❌ | ✅ Full |
|
|
158
|
-
| Edge Workers | ❌ | ✅ |
|
|
159
|
-
| **Security** | | |
|
|
160
|
-
| Secure Random | ❌ | ✅ |
|
|
161
|
-
| Key Validation | ❌ | ✅ |
|
|
162
|
-
| Session Isolation | ❌ | ✅ |
|
|
163
|
-
| Context Isolation | ❌ | ✅ |
|
|
164
|
-
| **API** | | |
|
|
165
|
-
| isPersistent | ❌ | ✅ |
|
|
166
|
-
| createContext | ❌ | ✅ |
|
|
167
|
-
| Platform APIs | ❌ | ✅ |
|
|
168
|
-
| **Documentation** | | |
|
|
169
|
-
| Platform Guide | ❌ | ✅ |
|
|
170
|
-
| Security Docs | ❌ | ✅ |
|
|
171
|
-
| Platform Tables | ❌ | ✅ |
|
|
83
|
+
### Security
|
|
84
|
+
- Secure random session IDs replaced `Math.random()`
|
|
85
|
+
- Key validation (max 512 chars + character whitelist)
|
|
172
86
|
|
|
173
87
|
---
|
|
174
88
|
|
|
175
|
-
##
|
|
176
|
-
|
|
177
|
-
| Feature | Status | Alternative |
|
|
178
|
-
|---------|--------|---------|
|
|
179
|
-
| `observer()` | ⚠️ Deprecated | Use `useObserver()` in React |
|
|
180
|
-
| Global state in Node.js | ⚡ Discouraged | Use `memorio.createContext()` |
|
|
181
|
-
|
|
182
|
-
---
|
|
89
|
+
## v2.5.0 — 2026-02-17
|
|
183
90
|
|
|
184
|
-
|
|
91
|
+
- Initial release of memorio (state, store, session, cache, idb)
|
|
92
|
+
- Observer pattern (`observer`)
|
|
93
|
+
- `useObserver` React hook
|
package/docs/markdown/IDB.md
CHANGED
|
@@ -29,7 +29,7 @@ idb.data.set('myApp', 'users', { id: 1, name: 'Mario' });
|
|
|
29
29
|
|
|
30
30
|
// Get data
|
|
31
31
|
const user = idb.data.get('myApp', 'users', 1);
|
|
32
|
-
console.
|
|
32
|
+
console.debug(user.name); // "Mario"
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
### Example 2: Intermediate
|
|
@@ -45,7 +45,7 @@ idb.data.set('store', 'products', { id: 2, name: 'Banana', price: 0.8 });
|
|
|
45
45
|
|
|
46
46
|
// List databases
|
|
47
47
|
const databases = idb.db.list();
|
|
48
|
-
console.
|
|
48
|
+
console.debug(databases); // ['myApp', 'store']
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
### Example 3: Advanced
|
|
@@ -65,7 +65,7 @@ idb.db.delete('store');
|
|
|
65
65
|
|
|
66
66
|
// Handle quota
|
|
67
67
|
const quota = idb.db.quota();
|
|
68
|
-
console.
|
|
68
|
+
console.debug(`Using ${quota.used} of ${quota.total} bytes`);
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
---
|
package/docs/markdown/LOGGER.md
CHANGED
|
@@ -107,7 +107,7 @@ state.user = { name: 'John' }
|
|
|
107
107
|
|
|
108
108
|
```javascript
|
|
109
109
|
const stats = memorio.logger.getStats()
|
|
110
|
-
console.
|
|
110
|
+
console.debug(stats)
|
|
111
111
|
// { total: 15, state: 5, store: 3, session: 2, cache: 5, set: 10, get: 0, delete: 3, clear: 2 }
|
|
112
112
|
```
|
|
113
113
|
|
|
@@ -143,5 +143,5 @@ const stateLogs = logs.filter(l => l.module === 'state')
|
|
|
143
143
|
const setOperations = logs.filter(l => l.action === 'set')
|
|
144
144
|
|
|
145
145
|
// Export for debugging
|
|
146
|
-
console.
|
|
146
|
+
console.debug(memorio.logger.exportLogs())
|
|
147
147
|
```
|