memorio 4.1.0 → 4.1.5

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/index.cjs CHANGED
@@ -1,5 +1,3 @@
1
- "use strict";
2
-
3
1
  var e = Object.getOwnPropertyNames, t = (t, o) => function() {
4
2
  return t && (o = (0, t[e(t)[0]])(t = 0)), o;
5
3
  }, o = {}, r = t({
@@ -323,7 +321,7 @@ Object.defineProperty(globalThis, "memorio", {
323
321
  }), Object.defineProperty(memorio, "version", {
324
322
  writable: !1,
325
323
  enumerable: !1,
326
- value: "4.1.0"
324
+ value: "4.1.5"
327
325
  }), Object.defineProperty(memorio, "debug", {
328
326
  writable: !0,
329
327
  enumerable: !1,
@@ -392,7 +390,10 @@ Object.defineProperty(memorio, "_sessionId", {
392
390
  },
393
391
  listen: (e, t = null, o = !1) => {
394
392
  globalThis.observer?.list?.[e]?.length > 0 && globalThis.observer?.remove?.(e);
395
- const r = t ? e => setTimeout(() => t(e), 1) : void 0;
393
+ const r = t ? e => {
394
+ const o = e;
395
+ return globalThis.queueMicrotask ? globalThis.queueMicrotask(() => t(o)) : Promise.resolve().then(() => t(o));
396
+ } : void 0;
396
397
  r && globalThis.addEventListener(e, r), r && (globalThis.events[e] = r);
397
398
  },
398
399
  remove: e => {
@@ -621,7 +622,7 @@ globalThis.observer = (e, t = null, o = !0) => {
621
622
 
622
623
  var W = x(), R = new Map, U = null !== W, K = "memorio_store_";
623
624
 
624
- function F(e) {
625
+ function q(e) {
625
626
  return e && "string" == typeof e ? e.length > 512 ? (memorio.message("Key too long (max 512 characters)"),
626
627
  "") : /^[a-zA-Z0-9_.-]+$/.test(e) ? K + e : (memorio.message("Key contains invalid characters (only a-z, A-Z, 0-9, _, ., - allowed)"),
627
628
  "") : "";
@@ -635,7 +636,7 @@ Object.defineProperty(globalThis, "store", {
635
636
  get: {
636
637
  value: e => {
637
638
  if (!e) return;
638
- const t = F(e);
639
+ const t = q(e);
639
640
  try {
640
641
  if (U) {
641
642
  const e = W.getItem(t);
@@ -654,7 +655,7 @@ Object.defineProperty(globalThis, "store", {
654
655
  set: {
655
656
  value: (e, t) => {
656
657
  if (!e) return;
657
- const o = F(e);
658
+ const o = q(e);
658
659
  try {
659
660
  if (U) {
660
661
  if (null == t) W.setItem(o, JSON.stringify(null)); else if ("object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t) W.setItem(o, JSON.stringify(t)); else if ("function" == typeof t) return void memorio.message("Storing functions is not secure and is blocked for safety.");
@@ -668,7 +669,7 @@ Object.defineProperty(globalThis, "store", {
668
669
  remove: {
669
670
  value: e => {
670
671
  if (!e) return;
671
- const t = F(e);
672
+ const t = q(e);
672
673
  try {
673
674
  if (U) {
674
675
  if (W.getItem(t)) return W.removeItem(t), !0;
@@ -749,7 +750,7 @@ Object.defineProperty(globalThis, "store", {
749
750
  }
750
751
  }), Object.freeze(store);
751
752
 
752
- var q = D(), L = new Map, H = null !== q, V = "memorio_session_";
753
+ var F = D(), L = new Map, H = null !== F, V = "memorio_session_";
753
754
 
754
755
  function Y(e) {
755
756
  return e && "string" == typeof e ? e.length > 512 ? (memorio.message("Key too long (max 512 characters)"),
@@ -768,7 +769,7 @@ Object.defineProperty(globalThis, "session", {
768
769
  const t = Y(e);
769
770
  try {
770
771
  if (H) {
771
- const e = q.getItem(t);
772
+ const e = F.getItem(t);
772
773
  return e ? JSON.parse(e) : e;
773
774
  }
774
775
  {
@@ -785,7 +786,7 @@ Object.defineProperty(globalThis, "session", {
785
786
  if (!e) return;
786
787
  const o = Y(e);
787
788
  try {
788
- H ? null == t ? q.setItem(o, JSON.stringify(null)) : "object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t ? q.setItem(o, JSON.stringify(t)) : "function" == typeof t && memorio.message("It's not secure to session functions.") : null == t ? L.set(o, JSON.stringify(null)) : "object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t ? L.set(o, JSON.stringify(t)) : "function" == typeof t && memorio.message("It's not secure to session functions.");
789
+ H ? null == t ? F.setItem(o, JSON.stringify(null)) : "object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t ? F.setItem(o, JSON.stringify(t)) : "function" == typeof t && memorio.message("It's not secure to session functions.") : null == t ? L.set(o, JSON.stringify(null)) : "object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t ? L.set(o, JSON.stringify(t)) : "function" == typeof t && memorio.message("It's not secure to session functions.");
789
790
  } catch (t) {
790
791
  memorio.message(`Error setting session item '${e}': ${t}`);
791
792
  }
@@ -797,7 +798,7 @@ Object.defineProperty(globalThis, "session", {
797
798
  const t = Y(e);
798
799
  try {
799
800
  if (H) {
800
- if (q.getItem(t)) return q.removeItem(t), !0;
801
+ if (F.getItem(t)) return F.removeItem(t), !0;
801
802
  } else if (L.has(t)) return L.delete(t), !0;
802
803
  } catch (t) {
803
804
  memorio.message(`Error removing session item '${e}': ${t}`);
@@ -811,11 +812,11 @@ Object.defineProperty(globalThis, "session", {
811
812
  value: () => {
812
813
  if (H) {
813
814
  const e = [];
814
- for (let t = 0; t < q.length; t++) {
815
- const o = q.key(t);
815
+ for (let t = 0; t < F.length; t++) {
816
+ const o = F.key(t);
816
817
  o?.startsWith(V) && e.push(o);
817
818
  }
818
- e.forEach(e => q.removeItem(e));
819
+ e.forEach(e => F.removeItem(e));
819
820
  } else L.clear();
820
821
  return !0;
821
822
  }
@@ -829,9 +830,9 @@ Object.defineProperty(globalThis, "session", {
829
830
  size: {
830
831
  value: () => {
831
832
  let e = 0;
832
- return H ? Object.keys(q).forEach(t => {
833
+ return H ? Object.keys(F).forEach(t => {
833
834
  if (t.startsWith(V)) {
834
- const o = q.getItem(t);
835
+ const o = F.getItem(t);
835
836
  o && (e += o.length);
836
837
  }
837
838
  }) : L.forEach(t => {
@@ -846,10 +847,10 @@ Object.defineProperty(globalThis, "session", {
846
847
  value: () => {
847
848
  const e = {};
848
849
  try {
849
- if (H) for (let t = 0; t < q.length; t++) {
850
- const o = q.key(t);
850
+ if (H) for (let t = 0; t < F.length; t++) {
851
+ const o = F.key(t);
851
852
  if (o?.startsWith(V)) {
852
- const t = o.replace(V, ""), r = q.getItem(o);
853
+ const t = o.replace(V, ""), r = F.getItem(o);
853
854
  if (null !== r) try {
854
855
  e[t] = JSON.parse(r);
855
856
  } catch {
package/index.js CHANGED
@@ -321,7 +321,7 @@ Object.defineProperty(globalThis, "memorio", {
321
321
  }), Object.defineProperty(memorio, "version", {
322
322
  writable: !1,
323
323
  enumerable: !1,
324
- value: "4.1.0"
324
+ value: "4.1.5"
325
325
  }), Object.defineProperty(memorio, "debug", {
326
326
  writable: !0,
327
327
  enumerable: !1,
@@ -390,7 +390,10 @@ Object.defineProperty(memorio, "_sessionId", {
390
390
  },
391
391
  listen: (e, t = null, o = !1) => {
392
392
  globalThis.observer?.list?.[e]?.length > 0 && globalThis.observer?.remove?.(e);
393
- const r = t ? e => setTimeout(() => t(e), 1) : void 0;
393
+ const r = t ? e => {
394
+ const o = e;
395
+ return globalThis.queueMicrotask ? globalThis.queueMicrotask(() => t(o)) : Promise.resolve().then(() => t(o));
396
+ } : void 0;
394
397
  r && globalThis.addEventListener(e, r), r && (globalThis.events[e] = r);
395
398
  },
396
399
  remove: e => {
@@ -619,7 +622,7 @@ globalThis.observer = (e, t = null, o = !0) => {
619
622
 
620
623
  var W = x(), R = new Map, U = null !== W, K = "memorio_store_";
621
624
 
622
- function F(e) {
625
+ function q(e) {
623
626
  return e && "string" == typeof e ? e.length > 512 ? (memorio.message("Key too long (max 512 characters)"),
624
627
  "") : /^[a-zA-Z0-9_.-]+$/.test(e) ? K + e : (memorio.message("Key contains invalid characters (only a-z, A-Z, 0-9, _, ., - allowed)"),
625
628
  "") : "";
@@ -633,7 +636,7 @@ Object.defineProperty(globalThis, "store", {
633
636
  get: {
634
637
  value: e => {
635
638
  if (!e) return;
636
- const t = F(e);
639
+ const t = q(e);
637
640
  try {
638
641
  if (U) {
639
642
  const e = W.getItem(t);
@@ -652,7 +655,7 @@ Object.defineProperty(globalThis, "store", {
652
655
  set: {
653
656
  value: (e, t) => {
654
657
  if (!e) return;
655
- const o = F(e);
658
+ const o = q(e);
656
659
  try {
657
660
  if (U) {
658
661
  if (null == t) W.setItem(o, JSON.stringify(null)); else if ("object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t) W.setItem(o, JSON.stringify(t)); else if ("function" == typeof t) return void memorio.message("Storing functions is not secure and is blocked for safety.");
@@ -666,7 +669,7 @@ Object.defineProperty(globalThis, "store", {
666
669
  remove: {
667
670
  value: e => {
668
671
  if (!e) return;
669
- const t = F(e);
672
+ const t = q(e);
670
673
  try {
671
674
  if (U) {
672
675
  if (W.getItem(t)) return W.removeItem(t), !0;
@@ -747,7 +750,7 @@ Object.defineProperty(globalThis, "store", {
747
750
  }
748
751
  }), Object.freeze(store);
749
752
 
750
- var q = D(), L = new Map, H = null !== q, V = "memorio_session_";
753
+ var F = D(), L = new Map, H = null !== F, V = "memorio_session_";
751
754
 
752
755
  function Y(e) {
753
756
  return e && "string" == typeof e ? e.length > 512 ? (memorio.message("Key too long (max 512 characters)"),
@@ -766,7 +769,7 @@ Object.defineProperty(globalThis, "session", {
766
769
  const t = Y(e);
767
770
  try {
768
771
  if (H) {
769
- const e = q.getItem(t);
772
+ const e = F.getItem(t);
770
773
  return e ? JSON.parse(e) : e;
771
774
  }
772
775
  {
@@ -783,7 +786,7 @@ Object.defineProperty(globalThis, "session", {
783
786
  if (!e) return;
784
787
  const o = Y(e);
785
788
  try {
786
- H ? null == t ? q.setItem(o, JSON.stringify(null)) : "object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t ? q.setItem(o, JSON.stringify(t)) : "function" == typeof t && memorio.message("It's not secure to session functions.") : null == t ? L.set(o, JSON.stringify(null)) : "object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t ? L.set(o, JSON.stringify(t)) : "function" == typeof t && memorio.message("It's not secure to session functions.");
789
+ H ? null == t ? F.setItem(o, JSON.stringify(null)) : "object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t ? F.setItem(o, JSON.stringify(t)) : "function" == typeof t && memorio.message("It's not secure to session functions.") : null == t ? L.set(o, JSON.stringify(null)) : "object" == typeof t || "number" == typeof t || "boolean" == typeof t || "string" == typeof t ? L.set(o, JSON.stringify(t)) : "function" == typeof t && memorio.message("It's not secure to session functions.");
787
790
  } catch (t) {
788
791
  memorio.message(`Error setting session item '${e}': ${t}`);
789
792
  }
@@ -795,7 +798,7 @@ Object.defineProperty(globalThis, "session", {
795
798
  const t = Y(e);
796
799
  try {
797
800
  if (H) {
798
- if (q.getItem(t)) return q.removeItem(t), !0;
801
+ if (F.getItem(t)) return F.removeItem(t), !0;
799
802
  } else if (L.has(t)) return L.delete(t), !0;
800
803
  } catch (t) {
801
804
  memorio.message(`Error removing session item '${e}': ${t}`);
@@ -809,11 +812,11 @@ Object.defineProperty(globalThis, "session", {
809
812
  value: () => {
810
813
  if (H) {
811
814
  const e = [];
812
- for (let t = 0; t < q.length; t++) {
813
- const o = q.key(t);
815
+ for (let t = 0; t < F.length; t++) {
816
+ const o = F.key(t);
814
817
  o?.startsWith(V) && e.push(o);
815
818
  }
816
- e.forEach(e => q.removeItem(e));
819
+ e.forEach(e => F.removeItem(e));
817
820
  } else L.clear();
818
821
  return !0;
819
822
  }
@@ -827,9 +830,9 @@ Object.defineProperty(globalThis, "session", {
827
830
  size: {
828
831
  value: () => {
829
832
  let e = 0;
830
- return H ? Object.keys(q).forEach(t => {
833
+ return H ? Object.keys(F).forEach(t => {
831
834
  if (t.startsWith(V)) {
832
- const o = q.getItem(t);
835
+ const o = F.getItem(t);
833
836
  o && (e += o.length);
834
837
  }
835
838
  }) : L.forEach(t => {
@@ -844,10 +847,10 @@ Object.defineProperty(globalThis, "session", {
844
847
  value: () => {
845
848
  const e = {};
846
849
  try {
847
- if (H) for (let t = 0; t < q.length; t++) {
848
- const o = q.key(t);
850
+ if (H) for (let t = 0; t < F.length; t++) {
851
+ const o = F.key(t);
849
852
  if (o?.startsWith(V)) {
850
- const t = o.replace(V, ""), r = q.getItem(o);
853
+ const t = o.replace(V, ""), r = F.getItem(o);
851
854
  if (null !== r) try {
852
855
  e[t] = JSON.parse(r);
853
856
  } catch {
package/llms.txt ADDED
@@ -0,0 +1,405 @@
1
+ # Memorio - LLM Documentation
2
+
3
+ ## Overview
4
+
5
+ **Memorio** is a cross-platform state management library that provides reactive state, persistence, and observation capabilities with zero dependencies. It works in Node.js, Deno, browsers, and edge environments.
6
+
7
+ ```
8
+ npm i memorio
9
+ ```
10
+
11
+ ## Core Concepts
12
+
13
+ Memorio provides 6 storage modules plus utilities:
14
+
15
+ | Module | Purpose | Persistence |
16
+ |--------|---------|-------------|
17
+ | `state` | Reactive, volatile state | In-memory (resets on refresh) |
18
+ | `store` | localStorage persistence | Survives browser refresh |
19
+ | `session` | sessionStorage | Dies with browser tab |
20
+ | `cache` | In-memory cache | Fastest read, no persistence |
21
+ | `idb` | IndexedDB | Structured, async, persistent (browser-only) |
22
+ | `observer` | Object watcher | Legacy, deprecated |
23
+ | `useObserver` | React hook | Auto-discovery of state paths |
24
+
25
+ ## Quick Start
26
+
27
+ ```javascript
28
+ import 'memorio'
29
+
30
+ // Set reactive state
31
+ state.user = { name: 'Sara', role: 'admin' }
32
+ state.counter = 0
33
+
34
+ // Observe changes (React hook)
35
+ useObserver(
36
+ () => { console.log('counter:', state.counter) },
37
+ [state.counter]
38
+ )
39
+ ```
40
+
41
+ ## API Reference
42
+
43
+ ### `state` — Reactive State
44
+
45
+ Global, Proxy-based, reactive state management.
46
+
47
+ ```javascript
48
+ // Set values
49
+ state.user = { name: 'Sara', role: 'admin' }
50
+ state.items = [1, 2, 3]
51
+ state.counter = 0
52
+
53
+ // Get values
54
+ const name = state.user.name // 'Sara'
55
+
56
+ // List all keys
57
+ console.log(state.list) // ['user', 'items', 'counter']
58
+
59
+ // Remove one key
60
+ state.remove('items')
61
+
62
+ // Clear all
63
+ state.removeAll()
64
+
65
+ // Lock/unlock for frozen objects
66
+ state.lock() // freeze everything
67
+ state.unlock() // unfreeze
68
+ ```
69
+
70
+ **Features:**
71
+ - Automatic path tracking via `__path` property
72
+ - Nested proxy support
73
+ - Lock/unlock per-key or globally
74
+ - Auto-dispatches events on changes
75
+
76
+ ### `store` — localStorage Persistence
77
+
78
+ Persistent storage that survives browser refresh.
79
+
80
+ ```javascript
81
+ // Set
82
+ store.set('preferences', { theme: 'dark' })
83
+
84
+ // Get
85
+ const prefs = store.get('preferences') // { theme: 'dark' } or null
86
+
87
+ // List all keys
88
+ store.list() // { preferences: { theme: 'dark' } }
89
+
90
+ // Remove
91
+ store.remove('preferences')
92
+
93
+ // Delete (alias for remove)
94
+ store.delete('preferences')
95
+
96
+ // Clear all memorio items
97
+ store.removeAll()
98
+
99
+ // Clear all (alias for removeAll)
100
+ store.clearAll()
101
+
102
+ // Check size
103
+ console.log(store.size(), 'chars stored')
104
+
105
+ // Check if persistent (real localStorage vs memory fallback)
106
+ console.log(store.isPersistent) // true → real localStorage
107
+
108
+ // Estimate quota usage (returns [0, 0] for localStorage)
109
+ await store.quota() // [usage, quota] in KB
110
+ ```
111
+
112
+ ### `session` — sessionStorage
113
+
114
+ Storage that dies when browser tab closes.
115
+
116
+ ```javascript
117
+ // Set
118
+ session.set('token', 'user-abc-123')
119
+
120
+ // Get
121
+ const token = session.get('token') // 'user-abc-123' or null
122
+
123
+ // List all keys
124
+ session.list() // { token: 'user-abc-123' }
125
+
126
+ // Remove
127
+ session.remove('token')
128
+
129
+ // Delete (alias for remove)
130
+ session.delete('token')
131
+
132
+ // Clear all
133
+ session.removeAll()
134
+
135
+ // Clear all (alias for removeAll)
136
+ session.clearAll()
137
+
138
+ // Check size
139
+ console.log(session.size(), 'chars stored')
140
+
141
+ // Check if persistent
142
+ console.log(session.isPersistent)
143
+ ```
144
+
145
+ ### `cache` — In-Memory Cache
146
+
147
+ Fastest possible read, data lost on refresh.
148
+
149
+ ```javascript
150
+ // Set
151
+ cache.set('temp', computeExpensiveResult())
152
+
153
+ // Get
154
+ const result = cache.get('temp') // undefined or the value
155
+
156
+ // List all keys
157
+ cache.list() // { temp: <value> }
158
+
159
+ // Remove
160
+ cache.remove('temp')
161
+
162
+ // Clear all
163
+ cache.clear()
164
+
165
+ // Remove all (alias for clear)
166
+ cache.removeAll()
167
+
168
+ // Direct access (also works)
169
+ cache['myKey'] = value
170
+ const value = cache['myKey']
171
+ delete cache['myKey']
172
+ ```
173
+
174
+ ### `idb` — IndexedDB
175
+
176
+ Structured, persistent, async database (browser-only).
177
+
178
+ ```javascript
179
+ // Create database
180
+ await idb.db.create('my-db', 1) // version defaults to 1
181
+
182
+ // Create table (object store)
183
+ await idb.table.create('my-db', 'users')
184
+
185
+ // Set data
186
+ await idb.data.set('my-db', 'users', { id: 1, name: 'Sara' })
187
+
188
+ // Get data by key
189
+ const user = await idb.data.get('my-db', 'users', 1)
190
+
191
+ // Delete data
192
+ await idb.data.delete('my-db', 'users', 1)
193
+
194
+ // List databases
195
+ const dbs = await idb.db.list()
196
+
197
+ // Check if database exists
198
+ const exists = await idb.db.exist('my-db')
199
+
200
+ // Delete database
201
+ await idb.db.delete('my-db')
202
+
203
+ // Get database size
204
+ const size = await idb.db.size('my-db')
205
+
206
+ // Get table size
207
+ const tableSize = await idb.table.size('my-db', 'users')
208
+
209
+ // Check support
210
+ idb.db.support() // true if IndexedDB available
211
+
212
+ // Check quota
213
+ const [usage, quota] = await idb.db.quota()
214
+ ```
215
+
216
+ **Note:** In Node.js/Deno, `idb` is disabled with a warning. Use `store` or `session` instead.
217
+
218
+ ### `observer` — Object Watcher (DEPRECATED)
219
+
220
+ Legacy observer API. Use `useObserver` instead.
221
+
222
+ ```javascript
223
+ // Listen to state changes
224
+ observer('state.user', (newVal, oldVal) => {
225
+ console.log('user changed:', newVal, oldVal)
226
+ })
227
+
228
+ // Toggle listening (no callback)
229
+ observer('state.counter')
230
+
231
+ // Remove observer
232
+ observer.remove('state.user')
233
+
234
+ // List all observers
235
+ console.log(observer.list)
236
+
237
+ // Remove all observers
238
+ observer.removeAll()
239
+ ```
240
+
241
+ ### `useObserver` — React Hook
242
+
243
+ Primary way to observe state changes in React components.
244
+
245
+ ```jsx
246
+ import 'memorio'
247
+ import { useReducer } from 'react'
248
+
249
+ function Counter() {
250
+ const [, forceUpdate] = useReducer(x => x + 1, 0)
251
+
252
+ // Auto-discovery mode (no deps)
253
+ useObserver(() => {
254
+ console.log('counter:', state.counter)
255
+ }, state.counter)
256
+
257
+ // Explicit deps mode
258
+ useObserver(
259
+ () => { console.log('user:', state.user) },
260
+ [state.user]
261
+ )
262
+
263
+ return <div>Count: {state.counter}</div>
264
+ }
265
+ ```
266
+
267
+ **Features:**
268
+ - Auto-discovery of state paths during render
269
+ - Returns cleanup function to stop monitoring
270
+ - Supports both Proxy objects and string paths
271
+
272
+ ### `devtools` — Inspection Tools
273
+
274
+ Inspect all memorio data in console.
275
+
276
+ ```javascript
277
+ // Pretty-print state, store, session, cache
278
+ memorio.devtools.inspect()
279
+
280
+ // Get stats
281
+ memorio.devtools.stats() // { stateKeys, storeKeys, sessionKeys, ... }
282
+
283
+ // Clear specific module
284
+ memorio.devtools.clear('state')
285
+
286
+ // Clear all modules
287
+ memorio.devtools.clearAll()
288
+
289
+ // Export all data as JSON
290
+ memorio.devtools.exportData()
291
+
292
+ // Import data from JSON
293
+ memorio.devtools.importData(jsonString)
294
+
295
+ // Show help
296
+ memorio.devtools.help()
297
+
298
+ // Console shortcuts
299
+ $state // same as globalThis.state
300
+ $store // same as globalThis.store
301
+ $session // same as globalThis.session
302
+ $cache // same as globalThis.cache
303
+ ```
304
+
305
+ ### `logger` — Change Tracking
306
+
307
+ Track every state change with timestamps.
308
+
309
+ ```javascript
310
+ // Configure logger
311
+ memorio.logger.configure({
312
+ enabled: true,
313
+ logToConsole: true,
314
+ modules: ['state', 'store', 'session', 'cache', 'idb']
315
+ })
316
+
317
+ // Get history
318
+ memorio.logger.getHistory() // [{ timestamp, module, action, path, value }, ...]
319
+
320
+ // Get stats
321
+ memorio.logger.getStats() // { total, state, store, session, cache, idb, set, get, ... }
322
+
323
+ // Clear history
324
+ memorio.logger.clearHistory()
325
+
326
+ // Export logs
327
+ memorio.logger.exportLogs() // JSON string of all history
328
+ ```
329
+
330
+ ## Platform Detection
331
+
332
+ Access via `memorio.*` after `import 'memorio'`:
333
+
334
+ ```javascript
335
+ memorio.isBrowser() // true in Chrome, Firefox, Safari
336
+ memorio.isNode() // true in Node.js
337
+ memorio.isDeno() // true in Deno
338
+ memorio.isEdge() // true in Cloudflare Workers, Vercel Edge
339
+
340
+ const caps = memorio.getCapabilities()
341
+ // { platform: 'browser', hasLocalStorage: true, hasIndexedDB: true, sessionId: 'uuid', ... }
342
+
343
+ // Create isolated context
344
+ memorio.createContext('tenant-name')
345
+ memorio.listContexts()
346
+ memorio.deleteContext('context-id')
347
+ memorio.isolate('tenant-name') // alias for createContext
348
+ ```
349
+
350
+ ## Cross-Platform Support
351
+
352
+ | Module | Browser | Node.js | Deno | Edge/Workers |
353
+ |--------|---------|---------|------|--------------|
354
+ | `state` | ✅ | ✅ | ✅ | ✅ |
355
+ | `observer` / `useObserver` | ✅ | ✅ | ✅ | ✅ |
356
+ | `cache` | ✅ | ✅ | ✅ | ✅ |
357
+ | `store` | ✅ localStorage | ⚠️ memory | ⚠️ memory | ✅ localStorage |
358
+ | `session` | ✅ sessionStorage | ⚠️ memory | ⚠️ memory | ✅ sessionStorage |
359
+ | `idb` | ✅ IndexedDB | ❌ | ❌ | ⚠️ |
360
+ | `devtools` | ✅ | ❌ | ❌ | ⚠️ |
361
+
362
+ **Note:** `store` and `session` fall back to in-memory `Map` in Node.js/Deno.
363
+
364
+ ## Session Isolation
365
+
366
+ Each browser tab and server request gets an isolated namespace automatically via session IDs.
367
+
368
+ ```javascript
369
+ // Create isolated context
370
+ memorio.createContext('tenant-name')
371
+ memorio.listContexts()
372
+ memorio.deleteContext('context-id')
373
+ memorio.isolate('tenant-name') // alias for createContext
374
+ ```
375
+
376
+ ## Security
377
+
378
+ - Zero production dependencies
379
+ - NIST & NSA aligned security standards
380
+ - No `eval`, no obfuscation, no hardcoded secrets
381
+ - All inputs validated, keys sanitized
382
+ - Secure random session IDs via `crypto.randomUUID`
383
+
384
+ ## License
385
+
386
+ MIT © Dario Passariello (BigLogic Inc Canada)
387
+
388
+ ## Utilities
389
+
390
+ ### `memorio.dispatch` — Event Dispatch System
391
+
392
+ Internal event system used by state changes.
393
+
394
+ ```javascript
395
+ // Dispatch a custom event
396
+ memorio.dispatch.set('custom:event', { detail: { data: 'value' } })
397
+
398
+ // Listen for an event
399
+ memorio.dispatch.listen('custom:event', (e) => {
400
+ console.log('Event triggered:', e.detail)
401
+ })
402
+
403
+ // Remove listener
404
+ memorio.dispatch.remove('custom:event')
405
+ ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "memorio",
3
3
  "codeName": "memorio",
4
- "version": "4.1.0",
4
+ "version": "4.1.5",
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",
@@ -54,7 +54,7 @@ interface _observer {
54
54
 
55
55
  }
56
56
 
57
- declare var observer: _observer | null
57
+ declare var observer: _observer
58
58
  type observer = _observer
59
59
 
60
60
  // Extend globalThis to include observer