memorio 2.8.0 → 2.9.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.
@@ -0,0 +1,161 @@
1
+ # Store - Memorio
2
+
3
+ > 🖥️ **Browser & Edge**: Uses localStorage for persistence
4
+ > ⚙️ **Node.js/Deno**: Falls back to in-memory storage (not persistent)
5
+
6
+ Store provides persistent localStorage management with a simple API. Data survives page refreshes and browser restarts.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install memorio
12
+ ```
13
+
14
+ ```javascript
15
+ import 'memorio';
16
+ ```
17
+
18
+ ---
19
+
20
+ ## Quick Examples
21
+
22
+ ### Example 1: Basic Usage
23
+
24
+ ```javascript
25
+ // Save data
26
+ store.set('username', 'Mario');
27
+ store.set('score', 1500);
28
+
29
+ // Read data
30
+ console.log(store.get('username')); // "Mario"
31
+ console.log(store.get('score')); // 1500
32
+
33
+ // Check if using real persistence
34
+ console.log(store.isPersistent); // true in browser, false in Node.js/Deno
35
+ ```
36
+
37
+ ### Example 2: Intermediate
38
+
39
+ ```javascript
40
+ // Store objects
41
+ store.set('user', { name: 'Luigi', level: 5 });
42
+ const user = store.get('user');
43
+ console.log(user.name); // "Luigi"
44
+
45
+ // Remove single item
46
+ store.remove('username');
47
+
48
+ // Check size
49
+ const totalSize = store.size();
50
+ console.log(`${totalSize} bytes`);
51
+ ```
52
+
53
+ ### Example 3: Advanced
54
+
55
+ ```javascript
56
+ // Get storage quota (returns Promise<[usage, quota]> in KB)
57
+ const [used, total] = await store.quota();
58
+ console.log(`Using ${used} out of ${total} KB`);
59
+
60
+ // Get total size in characters
61
+ const size = store.size();
62
+ console.log(`${size} bytes`);
63
+
64
+ // Clear all data
65
+ store.removeAll();
66
+ // or use alias
67
+ store.clearAll();
68
+
69
+ // Handle errors gracefully
70
+ try {
71
+ store.set('largeData', hugeObject);
72
+ } catch (err) {
73
+ console.error('Storage full:', err);
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ## API Reference
80
+
81
+ ### Methods
82
+
83
+ | Method | Parameters | Returns | Description |
84
+ |--------|------------|---------|-------------|
85
+ | `store.get(name)` | `name: string` | `any` | Get value from storage |
86
+ | `store.set(name, value)` | `name: string, value: any` | `void` | Save value to storage |
87
+ | `store.remove(name)` | `name: string` | `boolean` | Remove single item |
88
+ | `store.delete(name)` | `name: string` | `boolean` | Alias for remove |
89
+ | `store.removeAll()` | none | `boolean` | Clear all storage |
90
+ | `store.clearAll()` | none | `boolean` | Alias for removeAll |
91
+ | `store.size()` | none | `number` | Get total size in characters |
92
+ | `store.quota()` | none | `Promise<[number, number]>` | Get storage usage/quota in KB |
93
+
94
+ ### Properties
95
+
96
+ | Property | Type | Description |
97
+ |----------|------|-------------|
98
+ | `store.isPersistent` | `boolean` | `true` if using real localStorage, `false` if in-memory fallback |
99
+
100
+ ### Supported Types
101
+
102
+ ```javascript
103
+ // All JSON-serializable types work
104
+ store.set('string', 'hello');
105
+ store.set('number', 42);
106
+ store.set('boolean', true);
107
+ store.set('array', [1, 2, 3]);
108
+ store.set('object', { key: 'value' });
109
+ store.set('null', null);
110
+ store.set('undefined', null); // converted to null
111
+ ```
112
+
113
+ ### Not Supported
114
+
115
+ ```javascript
116
+ // Functions will log an error
117
+ store.set('myFunc', () => {});
118
+ // Output: "It's not secure to store functions."
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Platform Comparison
124
+
125
+ | Feature | Store | Session | Cache | IDB |
126
+ |---------|-------|---------|-------|-----|
127
+ | **Storage** | localStorage | sessionStorage | Memory | IndexedDB |
128
+ | **Lifetime** | Forever | Until tab closes | Until refresh | Forever |
129
+ | **Capacity** | ~5-10 MB | ~5-10 MB | Unlimited | 50+ MB |
130
+ | **Platform** | Browser/Edge | Browser/Edge | All | Browser |
131
+ | **Persistence** | ✅ true | N/A | ❌ false | ✅ true |
132
+
133
+ ---
134
+
135
+ ## How It Works
136
+
137
+ Store wraps the browser's `localStorage` API with:
138
+
139
+ - Automatic JSON serialization/deserialization
140
+ - Error handling for parse failures
141
+ - Size calculation
142
+ - Quota monitoring
143
+
144
+ ---
145
+
146
+ ## Storage Limits
147
+
148
+ - **Chrome/Safari**: ~5-10 MB
149
+ - **Firefox**: ~10 MB
150
+ - **Edge**: ~5-10 MB
151
+
152
+ Use `store.quota()` to monitor usage.
153
+
154
+ ---
155
+
156
+ ## Best Practices
157
+
158
+ 1. Prefix keys: `store.set('app_username', '...')`
159
+ 2. Check before set: `if (store.get('key')) { ... }`
160
+ 3. Handle quota: Try/catch around large data
161
+ 4. Clean up: `store.removeAll()` on logout
@@ -0,0 +1,158 @@
1
+ # useObserver - Memorio
2
+
3
+ > ⚛️ **React Only**: This is a React hook and only works within React components
4
+
5
+ useObserver is a React hook for observing state changes. It automatically subscribes to state changes and includes powerful auto-discovery features.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install memorio
11
+ ```
12
+
13
+ ```javascript
14
+ import 'memorio';
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Quick Examples
20
+
21
+ ### Example 1: Basic Usage
22
+
23
+ ```javascript
24
+ import 'memorio';
25
+
26
+ function Counter() {
27
+ useObserver(() => {
28
+ console.debug('Counter changed:', state.counter);
29
+ }, [state.counter]);
30
+
31
+ return <div>{state.counter}</div>;
32
+ }
33
+ ```
34
+
35
+ ### Auto-Discovery (Magic Mode)
36
+
37
+ ```javascript
38
+ // Pass your callback WITHOUT dependencies - it auto-discovers!
39
+ function MyComponent() {
40
+ useObserver(() => {
41
+ // This will automatically track ALL state properties used inside
42
+ console.debug('Something changed:', state.user.name, state.items.length);
43
+ });
44
+
45
+ return <div>{state.user.name}</div>;
46
+ }
47
+ ```
48
+
49
+ ### Example 2: Intermediate
50
+
51
+ ```javascript
52
+ function UserProfile() {
53
+ const [localState, setLocalState] = useState(null);
54
+
55
+ useObserver(() => {
56
+ setLocalState(state.user);
57
+ }, [state.user]);
58
+
59
+ return <div>{localState?.name}</div>;
60
+ }
61
+ ```
62
+
63
+ ### Example 3: Advanced
64
+
65
+ ```javascript
66
+ // Multiple watchers with array
67
+ function MultiWatch() {
68
+ useObserver(() => {
69
+ console.debug('A or B changed:', state.a, state.b);
70
+ }, [state.a, state.b]);
71
+
72
+ return <div>{state.a} - {state.b}</div>;
73
+ }
74
+ ```
75
+ // With string path (for store)
76
+ function StoreWatcher() {
77
+ useObserver(() => {
78
+ console.debug('Store changed');
79
+ }, 'store.userPreferences');
80
+
81
+ return <div />;
82
+ }
83
+ ```
84
+
85
+ ---
86
+
87
+ ## API Reference
88
+
89
+ ### useObserver(callback, deps)
90
+
91
+ | Parameter | Type | Description |
92
+ | --------- | ---- | ----------- |
93
+ | `callback` | `function` | Function to run on change |
94
+ | `deps` | `function \| string \| array` | State path(s) to watch |
95
+
96
+ ### Callback Parameters
97
+
98
+ ```javascript
99
+ useObserver((newValue, oldValue) => {
100
+ console.debug('Changed:', newValue);
101
+ }, [state.key]);
102
+ ```
103
+
104
+ ### Auto-Discovery Mode
105
+
106
+ When `deps` is omitted, useObserver automatically discovers all state properties accessed inside the callback:
107
+
108
+ ```javascript
109
+ // No deps needed - magic auto-discovery!
110
+ useObserver(() => {
111
+ // Automatically tracks state.user, state.items, state.counter
112
+ console.log(state.user.name, state.items.length, state.counter);
113
+ });
114
+ ```
115
+
116
+ Returns a cleanup function:
117
+
118
+ ## useObserver vs observer
119
+
120
+ | Feature | observer | useObserver |
121
+ | ------- | -------- | ----------- |
122
+ | Framework | Vanilla JS | React |
123
+ | Auto-cleanup | Manual | Auto |
124
+ | React lifecycle | No | Yes |
125
+
126
+ ---
127
+
128
+ ## Common Patterns
129
+
130
+ ### Sync with useState
131
+
132
+ ```javascript
133
+ function MyComponent() {
134
+ const [data, setData] = useState(null);
135
+
136
+ useObserver((newVal) => {
137
+ setData(newVal);
138
+ }, [state.data]);
139
+
140
+ return <div>{data}</div>;
141
+ }
142
+ ```
143
+
144
+ ### Multiple Watchers
145
+
146
+ ```javascript
147
+ }, [state.a, state.b]);
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Best Practices
153
+
154
+ 1. Always use in React components
155
+ 2. Use auto-discovery for simpler code: `useObserver(() => { ... })`
156
+ 3. No manual cleanup needed - returns cleanup function automatically
157
+ 4. Use with state for reactive UI
158
+ 5. Check console for auto-discovery logs
package/examples/basic.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  * Run: npx ts-node examples/basic.ts
11
11
  */
12
12
 
13
- import '../index'
13
+ import 'memorio'
14
14
 
15
15
  // ============================================
16
16
  // PLATFORM DETECTION
package/examples/cache.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * Run: npx ts-node examples/cache.ts
8
8
  */
9
9
 
10
- import '../index'
10
+ import 'memorio'
11
11
 
12
12
  // ============================================
13
13
  // BASIC CACHE OPERATIONS
package/examples/idb.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * Run: npx ts-node examples/idb.ts
8
8
  */
9
9
 
10
- import '../index'
10
+ import 'memorio'
11
11
 
12
12
  // ============================================
13
13
  // CHECK SUPPORT
@@ -7,7 +7,7 @@
7
7
  * Run: npx ts-node examples/node-server.ts
8
8
  */
9
9
 
10
- import '../index'
10
+ import 'memorio'
11
11
 
12
12
  // ============================================
13
13
  // 1. BASIC USAGE
@@ -7,7 +7,7 @@
7
7
  * Run: npx ts-node examples/observer.ts
8
8
  */
9
9
 
10
- import '../index'
10
+ import 'memorio'
11
11
 
12
12
  // ============================================
13
13
  // SIMPLE OBSERVER
@@ -9,7 +9,7 @@
9
9
  * Run: npx ts-node examples/platform.ts
10
10
  */
11
11
 
12
- import '../index'
12
+ import 'memorio'
13
13
 
14
14
  // ============================================
15
15
  // PLATFORM DETECTION
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import React, { useState, useEffect } from 'react'
11
- import '../index'
11
+ import 'memorio'
12
12
 
13
13
  // ============================================
14
14
  // 1. SETUP - Import once at app start
@@ -7,7 +7,7 @@
7
7
  * Run: npx ts-node examples/session-advanced.ts
8
8
  */
9
9
 
10
- import '../index'
10
+ import 'memorio'
11
11
 
12
12
  // ============================================
13
13
  // CHECK PERSISTENCE
@@ -6,7 +6,7 @@
6
6
  * Run: npx ts-node examples/state-advanced.ts
7
7
  */
8
8
 
9
- import '../index'
9
+ import 'memorio'
10
10
 
11
11
  // ============================================
12
12
  // NESTED OBJECTS
@@ -6,7 +6,7 @@
6
6
  * Run: npx ts-node examples/store-advanced.ts
7
7
  */
8
8
 
9
- import '../index'
9
+ import 'memorio'
10
10
 
11
11
  // ============================================
12
12
  // CHECK PERSISTENCE
@@ -8,7 +8,7 @@
8
8
  * Run in a React environment.
9
9
  */
10
10
 
11
- import '../index'
11
+ import 'memorio'
12
12
 
13
13
  // ============================================
14
14
  // BASIC USEOBSERVER
@@ -22,7 +22,7 @@ function Counter() {
22
22
  console.debug('Count changed:', state.count)
23
23
  }, [state.count])
24
24
 
25
- return <div>{ state.count } </div>
25
+ return <div>{state.count} </div>
26
26
  }
27
27
 
28
28
  // ============================================
@@ -35,7 +35,7 @@ function UserProfile() {
35
35
  console.debug('User or theme changed')
36
36
  }, [state.user, state.theme])
37
37
 
38
- return <div>{ state.user.name } </div>
38
+ return <div>{state.user.name} </div>
39
39
  }
40
40
 
41
41
  // ============================================
@@ -49,7 +49,7 @@ function AutoDiscovery() {
49
49
  console.debug('Changed:', state.user.name, state.items.length, state.count)
50
50
  })
51
51
 
52
- return <div>{ state.user.name } </div>
52
+ return <div>{state.user.name} </div>
53
53
  }
54
54
 
55
55
  // ============================================
@@ -64,7 +64,7 @@ function SyncedComponent() {
64
64
  setLocalData(newValue)
65
65
  }, [state.data])
66
66
 
67
- return <div>{ localData } </div>
67
+ return <div>{localData} </div>
68
68
  }
69
69
 
70
70
  // ============================================
@@ -72,7 +72,7 @@ function SyncedComponent() {
72
72
  // ============================================
73
73
 
74
74
  // Real-world React component example:
75
- import { useObserver } from 'memorio'
75
+ import 'memorio'
76
76
 
77
77
  function TodoApp() {
78
78
  // Track todos
@@ -105,36 +105,36 @@ function TodoApp() {
105
105
 
106
106
  return (
107
107
  <div>
108
- <select
109
- value= { state.filter }
110
- onChange = { e => state.filter = e.target.value }
111
- >
112
- <option value="all" > All </option>
113
- < option value = "done" > Done </option>
114
- < option value = "todo" > Todo </option>
115
- </select>
116
- <ul>
117
- {
118
- filteredTodos.map((todo, i) => (
119
- <li
120
- key= { i }
121
- onClick = {() => toggleTodo(i)}
122
- style = {{ textDecoration: todo.done ? 'line-through' : 'none' }
123
- }
124
- >
125
- { todo.text }
126
- </li>
127
- ))}
128
- </ul>
129
- < input
130
- onKeyDown = { e => {
131
- if (e.key === 'Enter') {
132
- addTodo(e.target.value)
133
- e.target.value = ''
134
- }
135
- }}
108
+ <select
109
+ value={state.filter}
110
+ onChange={e => state.filter = e.target.value}
111
+ >
112
+ <option value="all" > All </option>
113
+ < option value="done" > Done </option>
114
+ < option value="todo" > Todo </option>
115
+ </select>
116
+ <ul>
117
+ {
118
+ filteredTodos.map((todo, i) => (
119
+ <li
120
+ key={i}
121
+ onClick={() => toggleTodo(i)}
122
+ style={{ textDecoration: todo.done ? 'line-through' : 'none' }
123
+ }
124
+ >
125
+ {todo.text}
126
+ </li>
127
+ ))}
128
+ </ul>
129
+ < input
130
+ onKeyDown={e => {
131
+ if (e.key === 'Enter') {
132
+ addTodo(e.target.value)
133
+ e.target.value = ''
134
+ }
135
+ }}
136
136
  />
137
- </div>
137
+ </div>
138
138
  )
139
139
  }
140
140
 
package/index.cjs CHANGED
@@ -310,7 +310,7 @@ Object.defineProperty(globalThis, "memorio", {
310
310
  }), Object.defineProperty(memorio, "version", {
311
311
  writable: !1,
312
312
  enumerable: !1,
313
- value: "2.8.0"
313
+ value: "2.9.0"
314
314
  });
315
315
 
316
316
  var B = [ "list", "state", "store", "idb", "observer", "useObserver", "remove", "removeAll", "_platform", "_capabilities", "_sessionId" ];
package/index.js CHANGED
@@ -310,7 +310,7 @@ Object.defineProperty(globalThis, "memorio", {
310
310
  }), Object.defineProperty(memorio, "version", {
311
311
  writable: !1,
312
312
  enumerable: !1,
313
- value: "2.8.0"
313
+ value: "2.9.0"
314
314
  });
315
315
 
316
316
  var B = [ "list", "state", "store", "idb", "observer", "useObserver", "remove", "removeAll", "_platform", "_capabilities", "_sessionId" ];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "memorio",
3
3
  "code": "memorio",
4
- "version": "2.8.0",
4
+ "version": "2.9.0",
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.cjs",