memorio 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CODE_OF_CONDUCT.md +1 -1
- package/README.md +202 -332
- package/SECURITY.md +48 -3
- package/docs/README.md +202 -332
- package/examples/basic.ts +22 -22
- package/examples/browser-vanilla.html +2 -2
- package/examples/cache.ts +9 -9
- package/examples/idb.ts +8 -8
- package/examples/node-server.ts +39 -39
- package/examples/observer.ts +5 -5
- package/examples/platform.ts +37 -37
- package/examples/react-app.tsx +3 -3
- package/examples/session-advanced.ts +8 -8
- package/examples/state-advanced.ts +10 -10
- package/examples/store-advanced.ts +9 -9
- package/examples/useObserver.tsx +1 -1
- package/index.cjs +27 -26
- package/index.js +25 -26
- package/package.json +3 -3
- package/types/cache.d.ts +1 -1
- package/types/idb.d.ts +1 -1
- package/types/observer.d.ts +1 -1
- package/types/store.d.ts +10 -10
- package/types/useObserver.d.ts +1 -1
package/docs/README.md
CHANGED
|
@@ -1,430 +1,300 @@
|
|
|
1
1
|
# [memorio](https://npmjs.com/package/memorio)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
8
|
|
|
9
9
|

|
|
10
|
-

|
|
11
|
+

|
|
12
12
|

|
|
13
|
-

|
|
14
|
+

|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-

|
|
16
|
+
**State management that actually makes your life easier.**
|
|
17
|
+
Zero friction. Zero bloat. Single import. Works everywhere JavaScript runs.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
[Get Started](#-quick-start) · [API Reference](#-api-reference) · [License: MIT](https://opensource.org/licenses/MIT)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- [Features](#features)
|
|
24
|
-
- [Installation](#installation)
|
|
25
|
-
- [Quick Start](#quick-start)
|
|
26
|
-
- [API Reference](#api-reference)
|
|
27
|
-
- [State Management](#state-management)
|
|
28
|
-
- [Observer](#observer)
|
|
29
|
-
- [useObserver](#useobserver)
|
|
30
|
-
- [Store](#store)
|
|
31
|
-
- [Session](#session)
|
|
32
|
-
- [Cache](#cache)
|
|
33
|
-
- [idb](#idb)
|
|
34
|
-
- [DevTools](#devtools)
|
|
35
|
-
- [Logger](#logger)
|
|
36
|
-
- [Testing](#testing)
|
|
37
|
-
- [Security](#security)
|
|
38
|
-
- [License](#license)
|
|
39
|
-
- [Cross-Platform Support](#cross-platform-support)
|
|
40
|
-
- [Platform & Context Isolation](docs/markdown/PLATFORM.md)
|
|
21
|
+
---
|
|
41
22
|
|
|
42
|
-
##
|
|
23
|
+
## Why memorio?
|
|
43
24
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- **Logger**: Automatic logging of state changes
|
|
25
|
+
| | memorio | Redux | Zustand |
|
|
26
|
+
|---|---|---|---|
|
|
27
|
+
| **Setup** | 1 import | Boilerplate hell | Moderate |
|
|
28
|
+
| **Bundle size** | **~8 KB** | ~30 KB | ~15 KB |
|
|
29
|
+
| **Dependencies** | **Zero** | Many | Few |
|
|
30
|
+
| **TypeScript** | ✅ Native | ✅ | ✅ |
|
|
31
|
+
| **Binary storage** | ✅ Built-in IDB | ❌ Add-on | ❌ |
|
|
32
|
+
| **Observer** | ✅ Built-in | ❌ Add-on | ❌ |
|
|
33
|
+
| **DevTools** | ✅ Built-in | ❌ Extension | ❌ |
|
|
34
|
+
| **Running on the edge** | ✅ Workers, Deno | ⚠️ Limited | ⚠️ Limited |
|
|
55
35
|
|
|
56
|
-
|
|
36
|
+
If you need a `store` on the server. A `cache` in the edge worker.
|
|
37
|
+
Session isolation in Next.js. IndexedDB in a Service Worker.
|
|
38
|
+
All from one import, zero configuration.
|
|
57
39
|
|
|
58
|
-
|
|
59
|
-
npm i -D memorio
|
|
60
|
-
```
|
|
40
|
+
---
|
|
61
41
|
|
|
62
|
-
|
|
42
|
+
## Features
|
|
63
43
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
|
|
44
|
+
| | |
|
|
45
|
+
|---|---|
|
|
46
|
+
| **`state`** | Reactive, volatile state — listen with `useObserver` |
|
|
47
|
+
| **`store`** | localStorage persistence — survives refresh |
|
|
48
|
+
| **`session`** | sessionStorage — dies with the tab |
|
|
49
|
+
| **`cache`** | In-memory cache — fastest read possible |
|
|
50
|
+
| **`idb`** | IndexedDB with typed tables — structured, persistent, async |
|
|
51
|
+
| **`observer`** | Object watcher — legacy, still works |
|
|
52
|
+
| **`useObserver`** | React hook with auto-discovery — drops in |
|
|
53
|
+
| **`devtools`** | `memorio.devtools.inspect()` — see everything in console |
|
|
54
|
+
| **`logger`** | Auto-log every state change with timestamps |
|
|
55
|
+
| **Session Isolation** | Every browser tab, every request: isolated namespace |
|
|
56
|
+
| **Platform Detection** | `isBrowser`, `isNode`, `isDeno`, `isEdge` |
|
|
57
|
+
|
|
58
|
+
No Zustand. No Redux. No provider boilerplate.
|
|
59
|
+
Just import it and start storing.
|
|
72
60
|
|
|
73
|
-
|
|
61
|
+
---
|
|
74
62
|
|
|
75
63
|
## Quick Start
|
|
76
64
|
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
IMPORTANT!
|
|
80
|
-
Add import only at first start of your SPA. Became global!.
|
|
81
|
-
You don't need to import any time you need to use memorio
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
import 'memorio';
|
|
85
|
-
|
|
86
|
-
// State Management
|
|
87
|
-
state.counter = 0;
|
|
88
|
-
state.active = false;
|
|
89
|
-
state.name = "john";
|
|
90
|
-
state.user = { name: 'John', age: 30 };
|
|
91
|
-
state.hours = [2,3,10,23]
|
|
92
|
-
|
|
93
|
-
// useObserver Pattern for react app
|
|
94
|
-
// Example: if you change the state.counter you get a console.log
|
|
95
|
-
useObserver(
|
|
96
|
-
() => {
|
|
97
|
-
console.log(`Counter changed to ${state.counter}`);
|
|
98
|
-
},
|
|
99
|
-
[state.counter]
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// Store (Persistent Storage)
|
|
104
|
-
store.set('preferences', { theme: 'dark' });
|
|
105
|
-
const preferences = store.get('preferences');
|
|
106
|
-
|
|
107
|
-
// Session Storage
|
|
108
|
-
session.set('token', 'user-jwt-token');
|
|
109
|
-
const token = session.get('token');
|
|
110
|
-
|
|
111
|
-
// DevTools
|
|
112
|
-
memorio.devtools.inspect();
|
|
113
|
-
|
|
114
|
-
// Logger
|
|
115
|
-
memorio.logger.configure({ enabled: true, logToConsole: true })
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## API Reference
|
|
119
|
-
|
|
120
|
-
### State Management
|
|
121
|
-
|
|
122
|
-
State in Memorio is globally accessible and reactive:
|
|
123
|
-
|
|
124
|
-
```javascript
|
|
125
|
-
// Setting state
|
|
126
|
-
state.user = { name: 'John' };
|
|
127
|
-
|
|
128
|
-
// Getting state
|
|
129
|
-
const userName = state.user.name;
|
|
130
|
-
|
|
131
|
-
// Listing all states
|
|
132
|
-
console.log(state.list);
|
|
133
|
-
|
|
134
|
-
// Removing state
|
|
135
|
-
state.remove('user');
|
|
136
|
-
|
|
137
|
-
// Clearing all states
|
|
138
|
-
state.removeAll();
|
|
65
|
+
```bash
|
|
66
|
+
npm i memorio
|
|
139
67
|
```
|
|
140
68
|
|
|
141
|
-
|
|
69
|
+
```typescript
|
|
70
|
+
// memorio/index.ts — import once at your app entry point
|
|
71
|
+
import 'memorio'
|
|
142
72
|
|
|
143
|
-
|
|
73
|
+
// Memory
|
|
74
|
+
state.user = { name: 'Sara', role: 'admin' }
|
|
75
|
+
state.counter++
|
|
76
|
+
state.settings = { theme: 'dark', lang: 'it' }
|
|
144
77
|
|
|
145
|
-
|
|
146
|
-
// Basic useObserver - array syntax with state path
|
|
78
|
+
// Call it "a store" but make it observe automatically
|
|
147
79
|
useObserver(
|
|
148
|
-
() => {
|
|
149
|
-
console.log('User updated:', state.user);
|
|
150
|
-
},
|
|
80
|
+
() => { console.debug('user changed:', state.user) },
|
|
151
81
|
[state.user]
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
// Multiple states
|
|
155
|
-
useObserver(
|
|
156
|
-
() => {
|
|
157
|
-
console.log('States changed:', state.user, state.counter, state.settings);
|
|
158
|
-
},
|
|
159
|
-
[state.user, state.counter, state.settings]
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
// With options
|
|
163
|
-
useObserver(
|
|
164
|
-
() => {
|
|
165
|
-
console.log('Value changed');
|
|
166
|
-
},
|
|
167
|
-
[state.value],
|
|
168
|
-
{ immediate: true }
|
|
169
|
-
);
|
|
82
|
+
)
|
|
170
83
|
```
|
|
171
84
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
85
|
+
That is it.
|
|
86
|
+
No context providers. No `<Store>` wrappers. No action creators.
|
|
87
|
+
Import → assign → done.
|
|
175
88
|
|
|
176
|
-
|
|
177
|
-
// Setting values
|
|
178
|
-
store.set('config', { theme: 'dark', language: 'en' });
|
|
89
|
+
---
|
|
179
90
|
|
|
180
|
-
|
|
181
|
-
const config = store.get('config');
|
|
91
|
+
## API Reference
|
|
182
92
|
|
|
183
|
-
|
|
184
|
-
store.remove('config');
|
|
93
|
+
### `state` — Volatile reactive state
|
|
185
94
|
|
|
186
|
-
|
|
187
|
-
const size = store.size();
|
|
95
|
+
Global, Proxy-based, reactive. Access anywhere.
|
|
188
96
|
|
|
189
|
-
|
|
190
|
-
|
|
97
|
+
```javascript
|
|
98
|
+
// Set
|
|
99
|
+
state.user = { name: 'Sara', role: 'admin' }
|
|
100
|
+
state.items = [1, 2, 3]
|
|
191
101
|
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
console.log('Using real localStorage');
|
|
195
|
-
} else {
|
|
196
|
-
console.log('Using memory fallback (server environment)');
|
|
197
|
-
}
|
|
198
|
-
```
|
|
102
|
+
// Get
|
|
103
|
+
const name = state.user.name // 'Sara'
|
|
199
104
|
|
|
200
|
-
|
|
105
|
+
// List all keys
|
|
106
|
+
console.debug(state.list) // ['user', 'items']
|
|
201
107
|
|
|
202
|
-
|
|
108
|
+
// Remove one key
|
|
109
|
+
state.remove('items')
|
|
203
110
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
lastActive: Date.now()
|
|
210
|
-
}
|
|
211
|
-
);
|
|
111
|
+
// Clear all — lock/unlock available for frozen objects
|
|
112
|
+
state.removeAll()
|
|
113
|
+
state.lock() // freeze everything
|
|
114
|
+
state.unlock() // unfreeze
|
|
115
|
+
```
|
|
212
116
|
|
|
213
|
-
|
|
214
|
-
const userData = session.get('userSession');
|
|
117
|
+
### `useObserver` — React hook (with auto-discovery)
|
|
215
118
|
|
|
216
|
-
|
|
217
|
-
|
|
119
|
+
```jsx
|
|
120
|
+
import 'memorio'
|
|
121
|
+
import { useObserver } from 'memorio'
|
|
218
122
|
|
|
219
|
-
|
|
220
|
-
|
|
123
|
+
function Counter() {
|
|
124
|
+
const [, forceUpdate] = useReducer(x => x + 1, 0)
|
|
221
125
|
|
|
222
|
-
|
|
223
|
-
|
|
126
|
+
useObserver(forceUpdate, [state.counter])
|
|
127
|
+
// State path auto-discovered during render — no manual deps needed
|
|
224
128
|
|
|
225
|
-
|
|
226
|
-
if (session.isPersistent) {
|
|
227
|
-
console.log('Using real sessionStorage');
|
|
228
|
-
} else {
|
|
229
|
-
console.log('Using memory fallback (server environment)');
|
|
129
|
+
return <div>Count: {state.counter}</div>
|
|
230
130
|
}
|
|
231
131
|
```
|
|
232
132
|
|
|
233
|
-
###
|
|
234
|
-
|
|
235
|
-
In-memory cache for temporary data storage:
|
|
236
|
-
|
|
237
|
-
```js
|
|
238
|
-
// Setting cache data
|
|
239
|
-
cache.set('tempData', { computed: true, value: 42 });
|
|
133
|
+
### `store` — localStorage, survives refresh
|
|
240
134
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
//
|
|
248
|
-
cache.remove('tempData');
|
|
249
|
-
|
|
250
|
-
// Clearing all cache data
|
|
251
|
-
cache.removeAll();
|
|
135
|
+
```javascript
|
|
136
|
+
store.set('preferences', { theme: 'dark' })
|
|
137
|
+
const prefs = store.get('preferences') // { theme: 'dark' } or null
|
|
138
|
+
store.remove('preferences')
|
|
139
|
+
store.removeAll()
|
|
140
|
+
console.debug(store.size(), 'chars stored')
|
|
141
|
+
console.debug(store.isPersistent) // true → real localStorage
|
|
252
142
|
```
|
|
253
143
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
### idb
|
|
257
|
-
|
|
258
|
-
Permanent storage using browser database:
|
|
144
|
+
### `session` — sessionStorage, dies with tab
|
|
259
145
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
146
|
+
```javascript
|
|
147
|
+
session.set('token', 'user-abc-123')
|
|
148
|
+
const token = session.get('token') // 'user-abc-123' or null
|
|
149
|
+
session.removeAll()
|
|
264
150
|
```
|
|
265
151
|
|
|
266
|
-
|
|
152
|
+
### `cache` — In-memory, disappears on refresh
|
|
267
153
|
|
|
268
|
-
```
|
|
269
|
-
|
|
154
|
+
```javascript
|
|
155
|
+
cache.set('temp', computeExpensiveResult())
|
|
156
|
+
const result = cache.get('temp') // undefined or the value
|
|
157
|
+
cache.clear() // empty it all
|
|
270
158
|
```
|
|
271
159
|
|
|
272
|
-
|
|
160
|
+
### `idb` — IndexedDB, structured & typed
|
|
273
161
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
162
|
+
```javascript
|
|
163
|
+
// Create a database
|
|
164
|
+
await idb.db.create('my-db')
|
|
165
|
+
// Then create tables
|
|
166
|
+
await idb.table.create('my-db', 'users')
|
|
167
|
+
await idb.table.create('my-db', 'posts')
|
|
168
|
+
|
|
169
|
+
// CRUD
|
|
170
|
+
await idb.data.set('my-db', 'users', { id: 1, name: 'Sara' })
|
|
171
|
+
const user = await idb.data.get('my-db', 'users', 1) // { id: 1, name: 'Sara' }
|
|
172
|
+
await idb.data.delete('my-db', 'users', 1)
|
|
278
173
|
```
|
|
279
174
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
> [in development]
|
|
175
|
+
### `devtools` — inspect everything in one call
|
|
283
176
|
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
|
|
177
|
+
```javascript
|
|
178
|
+
memorio.devtools.inspect() // pretty-prints state, store, session, cache
|
|
179
|
+
memorio.devtools.stats() // { stateKeys, storeKeys, sessionKeys, ... }
|
|
180
|
+
memorio.devtools.clear('state')
|
|
181
|
+
memorio.devtools.exportData() // JSON snapshot
|
|
182
|
+
$state // console shortcut — same as globalThis.state
|
|
287
183
|
```
|
|
288
184
|
|
|
289
|
-
###
|
|
290
|
-
|
|
291
|
-
Browser console debugging tools for inspecting state, store, session, cache:
|
|
185
|
+
### `logger` — track every change
|
|
292
186
|
|
|
293
187
|
```javascript
|
|
294
|
-
|
|
295
|
-
memorio.
|
|
296
|
-
|
|
297
|
-
//
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
// Clear specific module
|
|
301
|
-
memorio.devtools.clear('state');
|
|
302
|
-
|
|
303
|
-
// Clear all modules
|
|
304
|
-
memorio.devtools.clearAll();
|
|
305
|
-
|
|
306
|
-
// Watch a path for changes
|
|
307
|
-
memorio.devtools.watch('state', 'user.name');
|
|
188
|
+
memorio.logger.configure({ enabled: true, logToConsole: true })
|
|
189
|
+
memorio.logger.getHistory() // [{ timestamp, module, action, path, value }, ...]
|
|
190
|
+
memorio.logger.getStats() // { total, state, set, get, ... }
|
|
191
|
+
memorio.logger.exportLogs() // JSON string of all history
|
|
192
|
+
```
|
|
308
193
|
|
|
309
|
-
|
|
310
|
-
memorio.devtools.exportData();
|
|
194
|
+
---
|
|
311
195
|
|
|
312
|
-
|
|
313
|
-
memorio.devtools.importData(jsonString);
|
|
196
|
+
## Cross-Platform
|
|
314
197
|
|
|
315
|
-
|
|
316
|
-
memorio.devtools.help();
|
|
198
|
+
Memorio runs in every JavaScript environment, with automatic fallbacks.
|
|
317
199
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
200
|
+
| | Browser | Node.js | Deno | Edge / Workers |
|
|
201
|
+
|---|---|---|---|---|
|
|
202
|
+
| `state` | ✅ | ✅ | ✅ | ✅ |
|
|
203
|
+
| `observer` / `useObserver` | ✅ | ✅ | ✅ | ✅ |
|
|
204
|
+
| `cache` | ✅ | ✅ | ✅ | ✅ |
|
|
205
|
+
| `store` | ✅ localStorage | ⚠️ memory | ⚠️ memory | ✅ localStorage |
|
|
206
|
+
| `session` | ✅ sessionStorage | ⚠️ memory | ⚠️ memory | ✅ sessionStorage |
|
|
207
|
+
| `idb` | ✅ IndexedDB | ❌ | ❌ | ⚠️ |
|
|
208
|
+
| `devtools` | ✅ | ❌ | ❌ | ⚠️ |
|
|
324
209
|
|
|
325
|
-
|
|
210
|
+
> **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.
|
|
326
211
|
|
|
327
|
-
|
|
212
|
+
### Detecting the environment
|
|
328
213
|
|
|
329
214
|
```javascript
|
|
330
|
-
|
|
331
|
-
memorio.logger.configure({ enabled: true, logToConsole: true });
|
|
215
|
+
import { isBrowser, isNode, isDeno, isEdge, getCapabilities } from 'memorio'
|
|
332
216
|
|
|
333
|
-
//
|
|
334
|
-
|
|
335
|
-
|
|
217
|
+
isBrowser() // true in Chrome, Firefox, Safari
|
|
218
|
+
isNode() // true in Node.js
|
|
219
|
+
isDeno() // true in Deno
|
|
220
|
+
isEdge() // true in Cloudflare Workers, Vercel Edge
|
|
336
221
|
|
|
337
|
-
|
|
338
|
-
|
|
222
|
+
const c = getCapabilities()
|
|
223
|
+
// { platform: 'browser', isBrowser: true, hasLocalStorage: true, hasIndexedDB: true }
|
|
224
|
+
```
|
|
339
225
|
|
|
340
|
-
|
|
341
|
-
memorio.logger.getStats();
|
|
226
|
+
---
|
|
342
227
|
|
|
343
|
-
|
|
344
|
-
memorio.logger.clearHistory();
|
|
228
|
+
## Testing
|
|
345
229
|
|
|
346
|
-
// Export logs as JSON
|
|
347
|
-
memorio.logger.exportLogs();
|
|
348
230
|
```
|
|
231
|
+
71 tests · 8 suites · all passing
|
|
349
232
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
All test suites are passing:
|
|
233
|
+
state | store | session | cache | observer | useObserver | devtools | logger
|
|
234
|
+
```
|
|
353
235
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
- Cache operations tests
|
|
358
|
-
- Observer pattern tests
|
|
359
|
-
- useObserver pattern tests
|
|
360
|
-
- DevTools tests
|
|
361
|
-
- Logger tests
|
|
236
|
+
```bash
|
|
237
|
+
npm test
|
|
238
|
+
```
|
|
362
239
|
|
|
363
|
-
|
|
240
|
+
---
|
|
364
241
|
|
|
365
242
|
## Security
|
|
366
243
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
-
|
|
370
|
-
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
MIT License
|
|
375
|
-
|
|
376
|
-
Copyright (c) [Dario Passariello](https://dario.passariello.ca/)
|
|
244
|
+
- Zero production dependencies — no supply chain surprises
|
|
245
|
+
- NIST & NSA aligned — enterprise-grade security standards
|
|
246
|
+
- No `eval`, no obfuscation, no hardcoded secrets
|
|
247
|
+
- All inputs validated, keys sanitized, errors caught
|
|
248
|
+
- Secure random session IDs via `crypto.randomUUID`
|
|
249
|
+
- MIT license — full audit trail on [`SECURITY.md`](.github/SECURITY.md)
|
|
377
250
|
|
|
378
251
|
---
|
|
379
252
|
|
|
380
|
-
##
|
|
253
|
+
## Installation options
|
|
381
254
|
|
|
382
|
-
|
|
255
|
+
```bash
|
|
256
|
+
# npm
|
|
257
|
+
npm i memorio
|
|
383
258
|
|
|
384
|
-
|
|
259
|
+
# pnpm
|
|
260
|
+
pnpm add memorio
|
|
385
261
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
| `state` | ✅ | ✅ | ✅ | ✅ |
|
|
389
|
-
| `observer` | ✅ | ✅ | ✅ | ✅ |
|
|
390
|
-
| `useObserver` | ✅ | ⚠️ | ⚠️ | ✅ |
|
|
391
|
-
| `cache` | ✅ | ✅ | ✅ | ✅ |
|
|
392
|
-
| `store` | ✅ (localStorage) | ⚠️ (memory) | ⚠️ (memory) | ✅ (localStorage) |
|
|
393
|
-
| `session` | ✅ (sessionStorage) | ⚠️ (memory) | ⚠️ (memory) | ✅ (sessionStorage) |
|
|
394
|
-
| `idb` | ✅ | ❌ | ❌ | ⚠️ |
|
|
395
|
-
| `devtools` | ✅ | ❌ | ❌ | ⚠️ |
|
|
396
|
-
| `logger` | ✅ | ✅ | ✅ | ✅ |
|
|
262
|
+
# yarn
|
|
263
|
+
yarn add memorio
|
|
397
264
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
265
|
+
# React peer dep (optional, React ≥ 16.8)
|
|
266
|
+
npm i react react-dom
|
|
267
|
+
```
|
|
401
268
|
|
|
402
|
-
|
|
269
|
+
---
|
|
403
270
|
|
|
404
|
-
|
|
271
|
+
## Testing
|
|
405
272
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
- **State Isolation**: `state` is isolated per-instance
|
|
273
|
+
```
|
|
274
|
+
95 tests · 8 suites · all passing
|
|
409
275
|
|
|
410
|
-
|
|
276
|
+
basic | state | store | session | cache | idb | observer | useObserver
|
|
277
|
+
```
|
|
411
278
|
|
|
412
|
-
|
|
279
|
+
| Suite | Tests | Status |
|
|
280
|
+
|-------|-------|--------|
|
|
281
|
+
| Basic | 7 | ✅ |
|
|
282
|
+
| State | 24 | ✅ |
|
|
283
|
+
| Store | 17 | ✅ |
|
|
284
|
+
| Session | 12 | ✅ |
|
|
285
|
+
| IDB | 7 | ✅ |
|
|
286
|
+
| Cache | 5 | ✅ |
|
|
287
|
+
| Observer | 12 | ✅ |
|
|
288
|
+
| useObserver | 12 | ✅ |
|
|
413
289
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
290
|
+
```bash
|
|
291
|
+
npm test
|
|
292
|
+
```
|
|
417
293
|
|
|
418
|
-
|
|
294
|
+
---
|
|
419
295
|
|
|
420
|
-
|
|
421
|
-
import { isBrowser, isNode, isDeno, getCapabilities } from 'memorio';
|
|
296
|
+
## License
|
|
422
297
|
|
|
423
|
-
|
|
424
|
-
console.log('Node.js:', isNode()); // true in Node.js
|
|
425
|
-
console.log('Deno:', isDeno()); // true in Deno
|
|
298
|
+
MIT © [Dario Passariello](https://dario.passariello.ca)
|
|
426
299
|
|
|
427
|
-
|
|
428
|
-
console.log('Platform:', caps.platform); // 'browser' | 'node' | 'deno' | 'edge'
|
|
429
|
-
console.log('Persistent:', store.isPersistent); // true if using real storage
|
|
430
|
-
```
|
|
300
|
+
© [BigLogic Inc Canada](https//biglogic.ca)
|