memorio 4.9.10 → 4.9.31
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/AGENTS.md +126 -126
- package/README.md +241 -100
- package/examples/basic.ts +1 -1
- package/examples/cross-platform-guards.ts +57 -57
- package/examples/multi-tenant-context.ts +44 -44
- package/examples/react-observer.tsx +63 -63
- package/examples/semantic-memory.ts +60 -60
- package/examples/session-advanced.ts +1 -1
- package/examples/sqlite-batched-writes.ts +57 -57
- package/examples/store-advanced.ts +1 -1
- package/index.cjs +74 -44
- package/index.js +74 -44
- package/llms.txt +13 -5
- package/modules/redux.cjs +2677 -0
- package/modules/redux.cjs.map +1 -0
- package/modules/redux.d.ts +119 -0
- package/modules/redux.js +2669 -0
- package/modules/redux.js.map +1 -0
- package/package.json +9 -3
- package/types/memorio.d.ts +1 -1
package/index.cjs
CHANGED
|
@@ -645,24 +645,29 @@ var init_store = __esm({
|
|
|
645
645
|
}, "value")
|
|
646
646
|
},
|
|
647
647
|
/**
|
|
648
|
-
* Calculates total size of all memorio items
|
|
648
|
+
* Calculates total size of all memorio items in kilobytes.
|
|
649
|
+
* Counts each prefixed key and its JSON-serialized value, summing their
|
|
650
|
+
* byte lengths and converting to whole kilobytes (Math.ceil). Replaces
|
|
651
|
+
* the previous character-only total which did not express real usage.
|
|
652
|
+
* @returns Total size in kilobytes (0 when empty / no memorio items).
|
|
649
653
|
*/
|
|
650
654
|
size: {
|
|
651
655
|
value: /* @__PURE__ */ __name(() => {
|
|
652
|
-
let
|
|
656
|
+
let totalBytes = 0;
|
|
653
657
|
if (_hasStorage) {
|
|
654
|
-
|
|
655
|
-
|
|
658
|
+
for (let i = 0; i < _localStorage.length; i++) {
|
|
659
|
+
const key = _localStorage.key(i);
|
|
660
|
+
if (key && key.startsWith(_getPrefix())) {
|
|
656
661
|
const item = _localStorage.getItem(key);
|
|
657
|
-
if (item)
|
|
662
|
+
if (item) totalBytes += key.length + item.length;
|
|
658
663
|
}
|
|
659
|
-
}
|
|
664
|
+
}
|
|
660
665
|
} else {
|
|
661
|
-
_getFallbackStorage().forEach((value) => {
|
|
662
|
-
|
|
666
|
+
_getFallbackStorage().forEach((value, key) => {
|
|
667
|
+
totalBytes += key.length + value.length;
|
|
663
668
|
});
|
|
664
669
|
}
|
|
665
|
-
return
|
|
670
|
+
return totalBytes === 0 ? 0 : Math.ceil(totalBytes / 1024);
|
|
666
671
|
}, "value")
|
|
667
672
|
},
|
|
668
673
|
/**
|
|
@@ -1733,30 +1738,51 @@ var dispatch = {
|
|
|
1733
1738
|
}, "set"),
|
|
1734
1739
|
///
|
|
1735
1740
|
/**
|
|
1736
|
-
*
|
|
1741
|
+
* Subscribes a callback to an event name. Maintains a *list* of handlers per
|
|
1742
|
+
* name, so multiple subscribers on the same path (e.g. several
|
|
1743
|
+
* `useObserver` calls observing `state.report`) each keep firing and each
|
|
1744
|
+
* get an independent unsubscribe. The previous single-slot-per-name
|
|
1745
|
+
* behaviour silently dropped the second subscriber and let any unsubscribe
|
|
1746
|
+
* cancel every other subscriber on that path.
|
|
1737
1747
|
* @param name The name of the event to listen for.
|
|
1738
1748
|
* @param cb The callback function to execute when the event is triggered.
|
|
1749
|
+
* @returns An unsubscribe function for this subscriber, or void if no callback.
|
|
1739
1750
|
*/
|
|
1740
1751
|
listen: /* @__PURE__ */ __name((name, cb = null, _flag) => {
|
|
1741
|
-
if (
|
|
1742
|
-
const
|
|
1752
|
+
if (!cb) return;
|
|
1753
|
+
const wrapped = /* @__PURE__ */ __name((e) => {
|
|
1743
1754
|
const target = e;
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1755
|
+
if (globalThis.queueMicrotask) {
|
|
1756
|
+
globalThis.queueMicrotask(() => cb(target));
|
|
1757
|
+
} else {
|
|
1758
|
+
Promise.resolve().then(() => cb(target));
|
|
1759
|
+
}
|
|
1760
|
+
}, "wrapped");
|
|
1761
|
+
globalThis.addEventListener(name, wrapped);
|
|
1762
|
+
const list = globalThis.events[name] = globalThis.events[name] ?? [];
|
|
1763
|
+
list.push(wrapped);
|
|
1764
|
+
return () => {
|
|
1765
|
+
globalThis.removeEventListener(name, wrapped);
|
|
1766
|
+
const idx = list.indexOf(wrapped);
|
|
1767
|
+
if (idx > -1) list.splice(idx, 1);
|
|
1768
|
+
if (!list.length) delete globalThis.events[name];
|
|
1769
|
+
};
|
|
1748
1770
|
}, "listen"),
|
|
1749
1771
|
///
|
|
1750
1772
|
/**
|
|
1751
|
-
* Removes
|
|
1752
|
-
*
|
|
1773
|
+
* Removes ALL handlers for the specified event name (imperative bulk
|
|
1774
|
+
* removal). For per-subscriber teardown, use the unsubscribe function
|
|
1775
|
+
* returned by `listen`.
|
|
1776
|
+
* @param name The name of the event to remove the listeners for.
|
|
1753
1777
|
*/
|
|
1754
1778
|
remove: /* @__PURE__ */ __name((name) => {
|
|
1755
|
-
const
|
|
1756
|
-
if (
|
|
1757
|
-
globalThis.removeEventListener(name,
|
|
1758
|
-
|
|
1779
|
+
const entry = globalThis.events?.[name];
|
|
1780
|
+
if (Array.isArray(entry)) {
|
|
1781
|
+
entry.forEach((h) => globalThis.removeEventListener(name, h));
|
|
1782
|
+
} else if (typeof entry === "function") {
|
|
1783
|
+
globalThis.removeEventListener(name, entry);
|
|
1759
1784
|
}
|
|
1785
|
+
delete globalThis.events[name];
|
|
1760
1786
|
}, "remove")
|
|
1761
1787
|
};
|
|
1762
1788
|
|
|
@@ -2285,27 +2311,28 @@ if (globalThis[SESSION_INSTANCE_KEY]) {
|
|
|
2285
2311
|
}, "value")
|
|
2286
2312
|
},
|
|
2287
2313
|
/**
|
|
2288
|
-
*
|
|
2289
|
-
*
|
|
2314
|
+
* Calculates total size of all memorio session items in kilobytes.
|
|
2315
|
+
* Counts each prefixed key and its JSON-serialized value, summing their
|
|
2316
|
+
* byte lengths and converting to whole kilobytes (Math.ceil).
|
|
2317
|
+
* @returns Total size in kilobytes (0 when empty / no memorio items).
|
|
2290
2318
|
*/
|
|
2291
2319
|
size: {
|
|
2292
2320
|
value: /* @__PURE__ */ __name(() => {
|
|
2293
|
-
let
|
|
2321
|
+
let totalBytes = 0;
|
|
2294
2322
|
if (_hasStorage2) {
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
}
|
|
2323
|
+
for (let i = 0; i < _sessionStorage.length; i++) {
|
|
2324
|
+
const key = _sessionStorage.key(i);
|
|
2325
|
+
if (key && key.startsWith(_getPrefix2())) {
|
|
2326
|
+
const item = _sessionStorage.getItem(key);
|
|
2327
|
+
if (item) totalBytes += key.length + item.length;
|
|
2301
2328
|
}
|
|
2302
|
-
|
|
2329
|
+
}
|
|
2303
2330
|
} else {
|
|
2304
|
-
_getFallbackStorage2().forEach((value) => {
|
|
2305
|
-
|
|
2331
|
+
_getFallbackStorage2().forEach((value, key) => {
|
|
2332
|
+
totalBytes += key.length + value.length;
|
|
2306
2333
|
});
|
|
2307
2334
|
}
|
|
2308
|
-
return
|
|
2335
|
+
return totalBytes === 0 ? 0 : Math.ceil(totalBytes / 1024);
|
|
2309
2336
|
}, "value")
|
|
2310
2337
|
},
|
|
2311
2338
|
/**
|
|
@@ -2524,6 +2551,7 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2524
2551
|
};
|
|
2525
2552
|
}
|
|
2526
2553
|
const handlers = [];
|
|
2554
|
+
const unsubs = [];
|
|
2527
2555
|
const depList = Array.isArray(deps) && !deps.__path ? deps : [deps];
|
|
2528
2556
|
try {
|
|
2529
2557
|
depList.forEach((dep) => {
|
|
@@ -2537,8 +2565,11 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2537
2565
|
if (t) {
|
|
2538
2566
|
t = t.replace(/^(\(\)\s*=>\s*)/, "").replace(/^globalThis\./, "").replace(/^state\./, "");
|
|
2539
2567
|
const path = t.startsWith("store.") || t.startsWith("state.") ? t : "state." + t;
|
|
2540
|
-
|
|
2541
|
-
|
|
2568
|
+
if (!handlers.includes(path)) {
|
|
2569
|
+
handlers.push(path);
|
|
2570
|
+
const off = dispatch.listen(path, () => func());
|
|
2571
|
+
if (typeof off === "function") unsubs.push({ path, off });
|
|
2572
|
+
}
|
|
2542
2573
|
} else {
|
|
2543
2574
|
exports.internal.clearTrackedPaths();
|
|
2544
2575
|
exports.internal.tracking = true;
|
|
@@ -2550,8 +2581,9 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2550
2581
|
exports.internal.trackedPaths.forEach((path) => {
|
|
2551
2582
|
if (!handlers.includes(path)) {
|
|
2552
2583
|
message_default(`useObserver: [Auto-Discovery] -> "${path}"`);
|
|
2553
|
-
dispatch.listen(path, () => func());
|
|
2554
2584
|
handlers.push(path);
|
|
2585
|
+
const off = dispatch.listen(path, () => func());
|
|
2586
|
+
if (typeof off === "function") unsubs.push({ path, off });
|
|
2555
2587
|
}
|
|
2556
2588
|
});
|
|
2557
2589
|
}
|
|
@@ -2562,11 +2594,9 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2562
2594
|
console.warn(`useObserver: No paths resolved for monitoring. Check your dependencies!`);
|
|
2563
2595
|
}
|
|
2564
2596
|
return () => {
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
message_default(`useObserver: Stopped monitoring "${path}"`);
|
|
2569
|
-
}
|
|
2597
|
+
unsubs.forEach(({ path, off }) => {
|
|
2598
|
+
off();
|
|
2599
|
+
message_default(`useObserver: Stopped monitoring "${path}"`);
|
|
2570
2600
|
});
|
|
2571
2601
|
};
|
|
2572
2602
|
} catch (err) {
|
|
@@ -3273,7 +3303,7 @@ init_internal();
|
|
|
3273
3303
|
|
|
3274
3304
|
// package.json
|
|
3275
3305
|
var package_default = {
|
|
3276
|
-
version: "4.9.
|
|
3306
|
+
version: "4.9.31"};
|
|
3277
3307
|
|
|
3278
3308
|
// core/global.ts
|
|
3279
3309
|
init_env();
|
package/index.js
CHANGED
|
@@ -642,24 +642,29 @@ var init_store = __esm({
|
|
|
642
642
|
}, "value")
|
|
643
643
|
},
|
|
644
644
|
/**
|
|
645
|
-
* Calculates total size of all memorio items
|
|
645
|
+
* Calculates total size of all memorio items in kilobytes.
|
|
646
|
+
* Counts each prefixed key and its JSON-serialized value, summing their
|
|
647
|
+
* byte lengths and converting to whole kilobytes (Math.ceil). Replaces
|
|
648
|
+
* the previous character-only total which did not express real usage.
|
|
649
|
+
* @returns Total size in kilobytes (0 when empty / no memorio items).
|
|
646
650
|
*/
|
|
647
651
|
size: {
|
|
648
652
|
value: /* @__PURE__ */ __name(() => {
|
|
649
|
-
let
|
|
653
|
+
let totalBytes = 0;
|
|
650
654
|
if (_hasStorage) {
|
|
651
|
-
|
|
652
|
-
|
|
655
|
+
for (let i = 0; i < _localStorage.length; i++) {
|
|
656
|
+
const key = _localStorage.key(i);
|
|
657
|
+
if (key && key.startsWith(_getPrefix())) {
|
|
653
658
|
const item = _localStorage.getItem(key);
|
|
654
|
-
if (item)
|
|
659
|
+
if (item) totalBytes += key.length + item.length;
|
|
655
660
|
}
|
|
656
|
-
}
|
|
661
|
+
}
|
|
657
662
|
} else {
|
|
658
|
-
_getFallbackStorage().forEach((value) => {
|
|
659
|
-
|
|
663
|
+
_getFallbackStorage().forEach((value, key) => {
|
|
664
|
+
totalBytes += key.length + value.length;
|
|
660
665
|
});
|
|
661
666
|
}
|
|
662
|
-
return
|
|
667
|
+
return totalBytes === 0 ? 0 : Math.ceil(totalBytes / 1024);
|
|
663
668
|
}, "value")
|
|
664
669
|
},
|
|
665
670
|
/**
|
|
@@ -1730,30 +1735,51 @@ var dispatch = {
|
|
|
1730
1735
|
}, "set"),
|
|
1731
1736
|
///
|
|
1732
1737
|
/**
|
|
1733
|
-
*
|
|
1738
|
+
* Subscribes a callback to an event name. Maintains a *list* of handlers per
|
|
1739
|
+
* name, so multiple subscribers on the same path (e.g. several
|
|
1740
|
+
* `useObserver` calls observing `state.report`) each keep firing and each
|
|
1741
|
+
* get an independent unsubscribe. The previous single-slot-per-name
|
|
1742
|
+
* behaviour silently dropped the second subscriber and let any unsubscribe
|
|
1743
|
+
* cancel every other subscriber on that path.
|
|
1734
1744
|
* @param name The name of the event to listen for.
|
|
1735
1745
|
* @param cb The callback function to execute when the event is triggered.
|
|
1746
|
+
* @returns An unsubscribe function for this subscriber, or void if no callback.
|
|
1736
1747
|
*/
|
|
1737
1748
|
listen: /* @__PURE__ */ __name((name, cb = null, _flag) => {
|
|
1738
|
-
if (
|
|
1739
|
-
const
|
|
1749
|
+
if (!cb) return;
|
|
1750
|
+
const wrapped = /* @__PURE__ */ __name((e) => {
|
|
1740
1751
|
const target = e;
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1752
|
+
if (globalThis.queueMicrotask) {
|
|
1753
|
+
globalThis.queueMicrotask(() => cb(target));
|
|
1754
|
+
} else {
|
|
1755
|
+
Promise.resolve().then(() => cb(target));
|
|
1756
|
+
}
|
|
1757
|
+
}, "wrapped");
|
|
1758
|
+
globalThis.addEventListener(name, wrapped);
|
|
1759
|
+
const list = globalThis.events[name] = globalThis.events[name] ?? [];
|
|
1760
|
+
list.push(wrapped);
|
|
1761
|
+
return () => {
|
|
1762
|
+
globalThis.removeEventListener(name, wrapped);
|
|
1763
|
+
const idx = list.indexOf(wrapped);
|
|
1764
|
+
if (idx > -1) list.splice(idx, 1);
|
|
1765
|
+
if (!list.length) delete globalThis.events[name];
|
|
1766
|
+
};
|
|
1745
1767
|
}, "listen"),
|
|
1746
1768
|
///
|
|
1747
1769
|
/**
|
|
1748
|
-
* Removes
|
|
1749
|
-
*
|
|
1770
|
+
* Removes ALL handlers for the specified event name (imperative bulk
|
|
1771
|
+
* removal). For per-subscriber teardown, use the unsubscribe function
|
|
1772
|
+
* returned by `listen`.
|
|
1773
|
+
* @param name The name of the event to remove the listeners for.
|
|
1750
1774
|
*/
|
|
1751
1775
|
remove: /* @__PURE__ */ __name((name) => {
|
|
1752
|
-
const
|
|
1753
|
-
if (
|
|
1754
|
-
globalThis.removeEventListener(name,
|
|
1755
|
-
|
|
1776
|
+
const entry = globalThis.events?.[name];
|
|
1777
|
+
if (Array.isArray(entry)) {
|
|
1778
|
+
entry.forEach((h) => globalThis.removeEventListener(name, h));
|
|
1779
|
+
} else if (typeof entry === "function") {
|
|
1780
|
+
globalThis.removeEventListener(name, entry);
|
|
1756
1781
|
}
|
|
1782
|
+
delete globalThis.events[name];
|
|
1757
1783
|
}, "remove")
|
|
1758
1784
|
};
|
|
1759
1785
|
|
|
@@ -2282,27 +2308,28 @@ if (globalThis[SESSION_INSTANCE_KEY]) {
|
|
|
2282
2308
|
}, "value")
|
|
2283
2309
|
},
|
|
2284
2310
|
/**
|
|
2285
|
-
*
|
|
2286
|
-
*
|
|
2311
|
+
* Calculates total size of all memorio session items in kilobytes.
|
|
2312
|
+
* Counts each prefixed key and its JSON-serialized value, summing their
|
|
2313
|
+
* byte lengths and converting to whole kilobytes (Math.ceil).
|
|
2314
|
+
* @returns Total size in kilobytes (0 when empty / no memorio items).
|
|
2287
2315
|
*/
|
|
2288
2316
|
size: {
|
|
2289
2317
|
value: /* @__PURE__ */ __name(() => {
|
|
2290
|
-
let
|
|
2318
|
+
let totalBytes = 0;
|
|
2291
2319
|
if (_hasStorage2) {
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
}
|
|
2320
|
+
for (let i = 0; i < _sessionStorage.length; i++) {
|
|
2321
|
+
const key = _sessionStorage.key(i);
|
|
2322
|
+
if (key && key.startsWith(_getPrefix2())) {
|
|
2323
|
+
const item = _sessionStorage.getItem(key);
|
|
2324
|
+
if (item) totalBytes += key.length + item.length;
|
|
2298
2325
|
}
|
|
2299
|
-
|
|
2326
|
+
}
|
|
2300
2327
|
} else {
|
|
2301
|
-
_getFallbackStorage2().forEach((value) => {
|
|
2302
|
-
|
|
2328
|
+
_getFallbackStorage2().forEach((value, key) => {
|
|
2329
|
+
totalBytes += key.length + value.length;
|
|
2303
2330
|
});
|
|
2304
2331
|
}
|
|
2305
|
-
return
|
|
2332
|
+
return totalBytes === 0 ? 0 : Math.ceil(totalBytes / 1024);
|
|
2306
2333
|
}, "value")
|
|
2307
2334
|
},
|
|
2308
2335
|
/**
|
|
@@ -2521,6 +2548,7 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2521
2548
|
};
|
|
2522
2549
|
}
|
|
2523
2550
|
const handlers = [];
|
|
2551
|
+
const unsubs = [];
|
|
2524
2552
|
const depList = Array.isArray(deps) && !deps.__path ? deps : [deps];
|
|
2525
2553
|
try {
|
|
2526
2554
|
depList.forEach((dep) => {
|
|
@@ -2534,8 +2562,11 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2534
2562
|
if (t) {
|
|
2535
2563
|
t = t.replace(/^(\(\)\s*=>\s*)/, "").replace(/^globalThis\./, "").replace(/^state\./, "");
|
|
2536
2564
|
const path2 = t.startsWith("store.") || t.startsWith("state.") ? t : "state." + t;
|
|
2537
|
-
|
|
2538
|
-
|
|
2565
|
+
if (!handlers.includes(path2)) {
|
|
2566
|
+
handlers.push(path2);
|
|
2567
|
+
const off = dispatch.listen(path2, () => func());
|
|
2568
|
+
if (typeof off === "function") unsubs.push({ path: path2, off });
|
|
2569
|
+
}
|
|
2539
2570
|
} else {
|
|
2540
2571
|
internal_default.clearTrackedPaths();
|
|
2541
2572
|
internal_default.tracking = true;
|
|
@@ -2547,8 +2578,9 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2547
2578
|
internal_default.trackedPaths.forEach((path2) => {
|
|
2548
2579
|
if (!handlers.includes(path2)) {
|
|
2549
2580
|
message_default(`useObserver: [Auto-Discovery] -> "${path2}"`);
|
|
2550
|
-
dispatch.listen(path2, () => func());
|
|
2551
2581
|
handlers.push(path2);
|
|
2582
|
+
const off = dispatch.listen(path2, () => func());
|
|
2583
|
+
if (typeof off === "function") unsubs.push({ path: path2, off });
|
|
2552
2584
|
}
|
|
2553
2585
|
});
|
|
2554
2586
|
}
|
|
@@ -2559,11 +2591,9 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2559
2591
|
console.warn(`useObserver: No paths resolved for monitoring. Check your dependencies!`);
|
|
2560
2592
|
}
|
|
2561
2593
|
return () => {
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
message_default(`useObserver: Stopped monitoring "${path2}"`);
|
|
2566
|
-
}
|
|
2594
|
+
unsubs.forEach(({ path: path2, off }) => {
|
|
2595
|
+
off();
|
|
2596
|
+
message_default(`useObserver: Stopped monitoring "${path2}"`);
|
|
2567
2597
|
});
|
|
2568
2598
|
};
|
|
2569
2599
|
} catch (err) {
|
|
@@ -3270,7 +3300,7 @@ init_internal();
|
|
|
3270
3300
|
|
|
3271
3301
|
// package.json
|
|
3272
3302
|
var package_default = {
|
|
3273
|
-
version: "4.9.
|
|
3303
|
+
version: "4.9.31"};
|
|
3274
3304
|
|
|
3275
3305
|
// core/global.ts
|
|
3276
3306
|
init_env();
|
package/llms.txt
CHANGED
|
@@ -100,7 +100,7 @@ store.removeAll()
|
|
|
100
100
|
store.clearAll() // alias
|
|
101
101
|
|
|
102
102
|
// Check size
|
|
103
|
-
console.debug(store.size(), '
|
|
103
|
+
console.debug(store.size(), 'kilobytes')
|
|
104
104
|
|
|
105
105
|
// Check if persistent (real localStorage vs memory fallback)
|
|
106
106
|
console.debug(store.isPersistent) // true → real localStorage
|
|
@@ -134,7 +134,7 @@ session.removeAll()
|
|
|
134
134
|
session.clearAll() // alias
|
|
135
135
|
|
|
136
136
|
// Check size
|
|
137
|
-
console.debug(session.size(), '
|
|
137
|
+
console.debug(session.size(), 'kilobytes')
|
|
138
138
|
|
|
139
139
|
// Check if persistent
|
|
140
140
|
console.debug(session.isPersistent)
|
|
@@ -466,15 +466,23 @@ MIT © Dario Passariello (BigLogic Inc Canada)
|
|
|
466
466
|
|
|
467
467
|
Internal event system used by state changes; also usable directly for custom events.
|
|
468
468
|
|
|
469
|
+
Listeners are stored as a *list* per event name, so multiple subscribers on the
|
|
470
|
+
same name each keep firing. `dispatch.listen` returns an unsubscribe function
|
|
471
|
+
for that specific subscriber - call it to remove only that one listener without
|
|
472
|
+
affecting others registered under the same name.
|
|
473
|
+
|
|
469
474
|
```javascript
|
|
470
475
|
// Dispatch a custom event
|
|
471
476
|
memorio.dispatch.set('custom:event', { detail: { data: 'value' } })
|
|
472
477
|
|
|
473
|
-
// Listen for an event
|
|
474
|
-
memorio.dispatch.listen('custom:event', (e) => {
|
|
478
|
+
// Listen for an event (returns an unsubscribe function)
|
|
479
|
+
const off = memorio.dispatch.listen('custom:event', (e) => {
|
|
475
480
|
console.debug('Event triggered:', e.detail)
|
|
476
481
|
})
|
|
477
482
|
|
|
478
|
-
// Remove listener
|
|
483
|
+
// Remove only this listener via the returned unsubscribe
|
|
484
|
+
off()
|
|
485
|
+
|
|
486
|
+
// Remove *all* listeners for a name (imperative bulk removal)
|
|
479
487
|
memorio.dispatch.remove('custom:event')
|
|
480
488
|
```
|