memorio 4.9.8 → 4.9.30

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,2669 @@
1
+ import 'path';
2
+ import 'url';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var init_esm_shims = __esm({
11
+ "node_modules/tsup/assets/esm_shims.js"() {
12
+ }
13
+ });
14
+
15
+ // core/internal.ts
16
+ var INTERNAL_KEY, state, internal, protect, internal_default;
17
+ var init_internal = __esm({
18
+ "core/internal.ts"() {
19
+ init_esm_shims();
20
+ INTERNAL_KEY = "__memorio_internal_state";
21
+ state = globalThis[INTERNAL_KEY] || {
22
+ debug: false,
23
+ tracking: false,
24
+ trackedPaths: /* @__PURE__ */ new Set(),
25
+ locked: false,
26
+ lastAccessedPath: "",
27
+ stateVersion: 0,
28
+ currentContext: null,
29
+ mutations: [],
30
+ undoStack: [],
31
+ redoStack: [],
32
+ maxHistory: 100,
33
+ historyEnabled: false
34
+ };
35
+ if (!globalThis[INTERNAL_KEY]) {
36
+ globalThis[INTERNAL_KEY] = state;
37
+ }
38
+ internal = {
39
+ get debug() {
40
+ return state.debug;
41
+ },
42
+ set debug(value) {
43
+ state.debug = value;
44
+ },
45
+ get tracking() {
46
+ return state.tracking;
47
+ },
48
+ set tracking(value) {
49
+ state.tracking = value;
50
+ },
51
+ get trackedPaths() {
52
+ return state.trackedPaths;
53
+ },
54
+ clearTrackedPaths() {
55
+ state.trackedPaths.clear();
56
+ },
57
+ get locked() {
58
+ return state.locked;
59
+ },
60
+ set locked(value) {
61
+ state.locked = value;
62
+ },
63
+ get lastAccessedPath() {
64
+ return state.lastAccessedPath;
65
+ },
66
+ set lastAccessedPath(value) {
67
+ state.lastAccessedPath = value;
68
+ },
69
+ get stateVersion() {
70
+ return state.stateVersion;
71
+ },
72
+ bumpStateVersion() {
73
+ state.stateVersion = (state.stateVersion || 0) + 1;
74
+ return state.stateVersion;
75
+ },
76
+ get currentContext() {
77
+ return state.currentContext;
78
+ },
79
+ set currentContext(value) {
80
+ state.currentContext = value;
81
+ },
82
+ get mutations() {
83
+ return state.mutations;
84
+ },
85
+ get undoStack() {
86
+ return state.undoStack;
87
+ },
88
+ get redoStack() {
89
+ return state.redoStack;
90
+ },
91
+ get maxHistory() {
92
+ return state.maxHistory;
93
+ },
94
+ set maxHistory(value) {
95
+ state.maxHistory = value;
96
+ },
97
+ get historyEnabled() {
98
+ return state.historyEnabled;
99
+ },
100
+ set historyEnabled(value) {
101
+ state.historyEnabled = value;
102
+ },
103
+ /**
104
+ * Records a mutation in the trace log and undo/redo stacks.
105
+ * Called by the state proxy's callback.
106
+ */
107
+ recordMutation(record) {
108
+ if (!state.historyEnabled) return;
109
+ state.mutations.push(record);
110
+ if (state.mutations.length > state.maxHistory) {
111
+ state.mutations.shift();
112
+ }
113
+ state.undoStack.push(record);
114
+ if (state.undoStack.length > state.maxHistory) {
115
+ state.undoStack.shift();
116
+ }
117
+ state.redoStack = [];
118
+ },
119
+ /**
120
+ * Pops a record from the undo stack and pushes to redo stack.
121
+ * Returns the record or undefined if empty.
122
+ */
123
+ popUndo() {
124
+ const record = state.undoStack.pop();
125
+ if (record) {
126
+ state.redoStack.push(record);
127
+ }
128
+ return record;
129
+ },
130
+ /**
131
+ * Pops a record from the redo stack and pushes to undo stack.
132
+ * Returns the record or undefined if empty.
133
+ */
134
+ popRedo() {
135
+ const record = state.redoStack.pop();
136
+ if (record) {
137
+ state.undoStack.push(record);
138
+ }
139
+ return record;
140
+ },
141
+ canUndo() {
142
+ return state.undoStack.length > 0;
143
+ },
144
+ canRedo() {
145
+ return state.redoStack.length > 0;
146
+ },
147
+ clearHistory() {
148
+ state.mutations = [];
149
+ state.undoStack = [];
150
+ state.redoStack = [];
151
+ },
152
+ clearRedo() {
153
+ state.redoStack = [];
154
+ }
155
+ };
156
+ protect = [
157
+ "list",
158
+ "state",
159
+ "store",
160
+ "idb",
161
+ "sqlite",
162
+ "observer",
163
+ "useObserver",
164
+ "remove",
165
+ "removeAll",
166
+ // Platform-related protected keys
167
+ "_platform",
168
+ "_capabilities",
169
+ "_sessionId"
170
+ ];
171
+ internal_default = internal;
172
+ }
173
+ });
174
+
175
+ // core/env.ts
176
+ var DEV;
177
+ var init_env = __esm({
178
+ "core/env.ts"() {
179
+ init_esm_shims();
180
+ DEV = typeof process !== "undefined" ? false : true;
181
+ }
182
+ });
183
+
184
+ // functions/message/index.ts
185
+ var message, message_default;
186
+ var init_message = __esm({
187
+ "functions/message/index.ts"() {
188
+ init_esm_shims();
189
+ init_internal();
190
+ init_env();
191
+ message = /* @__PURE__ */ __name((...args) => {
192
+ if (DEV && internal_default.debug === true) {
193
+ console.debug(...args);
194
+ }
195
+ }, "message");
196
+ message_default = message;
197
+ }
198
+ });
199
+
200
+ // core/platform.ts
201
+ function getSessionStorage() {
202
+ try {
203
+ if (typeof sessionStorage !== "undefined") {
204
+ const testKey = "__memorio_test__";
205
+ sessionStorage.setItem(testKey, "1");
206
+ sessionStorage.removeItem(testKey);
207
+ return sessionStorage;
208
+ }
209
+ } catch (_) {
210
+ }
211
+ return null;
212
+ }
213
+ function getLocalStorage() {
214
+ try {
215
+ if (typeof localStorage !== "undefined") {
216
+ const testKey = "__memorio_test__";
217
+ localStorage.setItem(testKey, "1");
218
+ localStorage.removeItem(testKey);
219
+ return localStorage;
220
+ }
221
+ } catch (_) {
222
+ }
223
+ return null;
224
+ }
225
+ function hasIndexedDB() {
226
+ if (typeof indexedDB !== "undefined") {
227
+ return true;
228
+ }
229
+ return false;
230
+ }
231
+ var CONTEXTS_KEY, _contexts;
232
+ var init_platform = __esm({
233
+ "core/platform.ts"() {
234
+ init_esm_shims();
235
+ init_internal();
236
+ __name(getSessionStorage, "getSessionStorage");
237
+ __name(getLocalStorage, "getLocalStorage");
238
+ __name(hasIndexedDB, "hasIndexedDB");
239
+ CONTEXTS_KEY = "__memorio_contexts__";
240
+ _contexts = globalThis[CONTEXTS_KEY] || /* @__PURE__ */ new Map();
241
+ if (!globalThis[CONTEXTS_KEY]) {
242
+ globalThis[CONTEXTS_KEY] = _contexts;
243
+ }
244
+ }
245
+ });
246
+
247
+ // functions/idb/tools/db.create.ts
248
+ var db_create_exports = {};
249
+ var init_db_create = __esm({
250
+ "functions/idb/tools/db.create.ts"() {
251
+ init_esm_shims();
252
+ init_idb();
253
+ init_message();
254
+ idb.db.create = (dbName, ver = 1) => {
255
+ return new Promise((resolve, reject) => {
256
+ if (!idb.db.support()) {
257
+ return reject(new Error("IndexedDB not supported"));
258
+ }
259
+ const request = globalThis.indexedDB.open(dbName, ver);
260
+ request.onerror = () => {
261
+ message_default(`IndexedDB error: ${request.error?.message}`);
262
+ reject(request.error);
263
+ };
264
+ request.onsuccess = () => {
265
+ message_default(`Database ${dbName} connected successfully`);
266
+ resolve(request.result);
267
+ };
268
+ request.onupgradeneeded = () => {
269
+ message_default(`Database ${dbName} upgrade/creation initiated`);
270
+ };
271
+ });
272
+ };
273
+ }
274
+ });
275
+
276
+ // functions/idb/tools/db.list.ts
277
+ var db_list_exports = {};
278
+ var init_db_list = __esm({
279
+ "functions/idb/tools/db.list.ts"() {
280
+ init_esm_shims();
281
+ init_idb();
282
+ idb.db.list = async () => {
283
+ if (!("indexedDB" in globalThis) || !indexedDB.databases) return [];
284
+ try {
285
+ const result = await indexedDB.databases();
286
+ globalThis.idbases = result || [];
287
+ await idb.db.size();
288
+ return globalThis.idbases;
289
+ } catch (err) {
290
+ console.error("Error listing databases:", err);
291
+ return [];
292
+ }
293
+ };
294
+ }
295
+ });
296
+
297
+ // functions/idb/tools/db.exist.ts
298
+ var db_exist_exports = {};
299
+ var init_db_exist = __esm({
300
+ "functions/idb/tools/db.exist.ts"() {
301
+ init_esm_shims();
302
+ init_idb();
303
+ idb.db.exist = (storeName) => {
304
+ return idbases?.some((db) => db.name === storeName);
305
+ };
306
+ }
307
+ });
308
+
309
+ // functions/idb/tools/db.quota.ts
310
+ var db_quota_exports = {};
311
+ var init_db_quota = __esm({
312
+ "functions/idb/tools/db.quota.ts"() {
313
+ init_esm_shims();
314
+ init_idb();
315
+ idb.db.quota = () => {
316
+ return navigator.storage.estimate();
317
+ };
318
+ }
319
+ });
320
+
321
+ // functions/idb/tools/db.delete.ts
322
+ var db_delete_exports = {};
323
+ var init_db_delete = __esm({
324
+ "functions/idb/tools/db.delete.ts"() {
325
+ init_esm_shims();
326
+ init_idb();
327
+ init_message();
328
+ idb.db.delete = (storeName) => {
329
+ return new Promise((resolve, reject) => {
330
+ message_default(`Removing database ${storeName}...`);
331
+ const performDelete = /* @__PURE__ */ __name(() => {
332
+ const request = indexedDB.deleteDatabase(storeName);
333
+ request.onsuccess = () => {
334
+ message_default(`${storeName} database removed successfully`);
335
+ idb.db.list();
336
+ resolve();
337
+ };
338
+ request.onerror = () => {
339
+ console.error(`Error removing ${storeName}:`, request.error);
340
+ reject(request.error);
341
+ };
342
+ request.onblocked = () => {
343
+ console.warn(`Deletion of ${storeName} is blocked. Please close other tabs.`);
344
+ };
345
+ }, "performDelete");
346
+ performDelete();
347
+ });
348
+ };
349
+ }
350
+ });
351
+
352
+ // functions/idb/tools/db.size.ts
353
+ var db_size_exports = {};
354
+ var init_db_size = __esm({
355
+ "functions/idb/tools/db.size.ts"() {
356
+ init_esm_shims();
357
+ init_idb();
358
+ init_message();
359
+ idb.db.size = async () => {
360
+ if (!idbases || idbases.length === 0) return;
361
+ for (let i = 0; i < idbases.length; i++) {
362
+ const dbInfo = idbases[i];
363
+ try {
364
+ const db = await idb.db.create(dbInfo.name, dbInfo.version);
365
+ const tableNames = Array.from(db.objectStoreNames);
366
+ let totalDbSize = 0;
367
+ for (const tableName of tableNames) {
368
+ const tableSize = await idb.table.size(db, tableName);
369
+ totalDbSize += tableSize;
370
+ }
371
+ dbInfo.size = totalDbSize;
372
+ db.close();
373
+ } catch (err) {
374
+ message_default(`Could not calculate size for ${dbInfo.name}:${err}`);
375
+ }
376
+ }
377
+ };
378
+ }
379
+ });
380
+
381
+ // functions/idb/tools/db.version.ts
382
+ var db_version_exports = {};
383
+ var init_db_version = __esm({
384
+ "functions/idb/tools/db.version.ts"() {
385
+ init_esm_shims();
386
+ init_idb();
387
+ idb.db.version = (storeName) => {
388
+ let idbVer = 0;
389
+ for (const v of idbases) {
390
+ if (v.name === storeName) idbVer = v.version;
391
+ break;
392
+ }
393
+ return idbVer;
394
+ };
395
+ }
396
+ });
397
+
398
+ // functions/idb/tools/db.support.ts
399
+ var db_support_exports = {};
400
+ var init_db_support = __esm({
401
+ "functions/idb/tools/db.support.ts"() {
402
+ init_esm_shims();
403
+ init_idb();
404
+ init_message();
405
+ idb.db.support = () => {
406
+ const isSupported = "indexedDB" in globalThis;
407
+ if (!isSupported) {
408
+ message_default("Your environment doesn't support IndexedDB");
409
+ }
410
+ return isSupported;
411
+ };
412
+ }
413
+ });
414
+
415
+ // functions/idb/tools/table.create.ts
416
+ var table_create_exports = {};
417
+ var init_table_create = __esm({
418
+ "functions/idb/tools/table.create.ts"() {
419
+ init_esm_shims();
420
+ init_idb();
421
+ init_message();
422
+ idb.table.create = (dbName, dbTable) => {
423
+ return new Promise((resolve, reject) => {
424
+ try {
425
+ const currentVersion = Number(idb.db.version(dbName)) || 0;
426
+ const nextVersion = currentVersion + 1;
427
+ const request = indexedDB.open(dbName, nextVersion);
428
+ request.onupgradeneeded = (e) => {
429
+ const db = e.target.result;
430
+ if (!db.objectStoreNames.contains(dbTable)) {
431
+ const store2 = db.createObjectStore(dbTable, {
432
+ keyPath: "id",
433
+ autoIncrement: true
434
+ });
435
+ store2.createIndex("id", "id", { unique: true });
436
+ store2.createIndex("data", "data", { unique: false });
437
+ message_default(`Table ${dbTable} created in ${dbName}`);
438
+ }
439
+ };
440
+ request.onsuccess = () => {
441
+ request.result.close();
442
+ idb.db.list();
443
+ resolve();
444
+ };
445
+ request.onerror = () => {
446
+ console.error(`Error creating table ${dbTable}:`, request.error);
447
+ reject(request.error);
448
+ };
449
+ } catch (err) {
450
+ console.error("Critical error in table.create:", err);
451
+ reject(err);
452
+ }
453
+ });
454
+ };
455
+ }
456
+ });
457
+
458
+ // functions/idb/tools/table.size.ts
459
+ var table_size_exports = {};
460
+ var init_table_size = __esm({
461
+ "functions/idb/tools/table.size.ts"() {
462
+ init_esm_shims();
463
+ init_idb();
464
+ init_message();
465
+ idb.table.size = (db, table) => {
466
+ return new Promise((resolve, reject) => {
467
+ if (!db) return reject(new Error("Database instance is required"));
468
+ if (!db.objectStoreNames.contains(table)) return resolve(0);
469
+ let size = 0;
470
+ let count = 0;
471
+ const transaction = db.transaction([table], "readonly");
472
+ const store2 = transaction.objectStore(table);
473
+ const request = store2.openCursor();
474
+ request.onsuccess = async (event) => {
475
+ const cursor = event.target.result;
476
+ if (cursor) {
477
+ try {
478
+ const value = cursor.value;
479
+ size += JSON.stringify(value).length;
480
+ } catch (err) {
481
+ message_default(`Error stringifying IDB value tracking size:${err}`);
482
+ }
483
+ count++;
484
+ if (count % 200 === 0) {
485
+ await new Promise((resolve2) => setTimeout(resolve2, 0));
486
+ }
487
+ cursor.continue();
488
+ } else {
489
+ resolve(size);
490
+ }
491
+ };
492
+ request.onerror = () => {
493
+ reject(request.error);
494
+ };
495
+ });
496
+ };
497
+ }
498
+ });
499
+
500
+ // functions/idb/crud/data.delete.ts
501
+ var data_delete_exports = {};
502
+ var init_data_delete = __esm({
503
+ "functions/idb/crud/data.delete.ts"() {
504
+ init_esm_shims();
505
+ init_idb();
506
+ init_message();
507
+ idb.data.delete = (storeName, table, key) => {
508
+ return new Promise((resolve, reject) => {
509
+ const request = indexedDB.open(storeName);
510
+ request.onsuccess = () => {
511
+ const db = request.result;
512
+ if (!db.objectStoreNames.contains(table)) {
513
+ db.close();
514
+ return reject(new Error(`Table ${table} not found`));
515
+ }
516
+ const transaction = db.transaction(table, "readwrite");
517
+ const objectStore = transaction.objectStore(table);
518
+ const deleteRequest = objectStore.delete(key);
519
+ deleteRequest.onsuccess = () => {
520
+ db.close();
521
+ message_default(`Record ${key} deleted from ${table}`);
522
+ resolve();
523
+ };
524
+ deleteRequest.onerror = () => {
525
+ db.close();
526
+ reject(deleteRequest.error);
527
+ };
528
+ };
529
+ request.onerror = () => reject(request.error);
530
+ });
531
+ };
532
+ idb.data.delete.all = (storeName, table) => {
533
+ return new Promise((resolve, reject) => {
534
+ const request = indexedDB.open(storeName);
535
+ request.onsuccess = (event) => {
536
+ const db = event.target.result;
537
+ if (!db.objectStoreNames.contains(table)) {
538
+ db.close();
539
+ return reject(new Error(`Table ${table} not found`));
540
+ }
541
+ const transaction = db.transaction(table, "readwrite");
542
+ const store2 = transaction.objectStore(table);
543
+ const clearRequest = store2.clear();
544
+ clearRequest.onsuccess = () => {
545
+ db.close();
546
+ message_default(`All data cleared from ${table}`);
547
+ resolve();
548
+ };
549
+ clearRequest.onerror = () => {
550
+ db.close();
551
+ reject(clearRequest.error);
552
+ };
553
+ };
554
+ request.onerror = () => reject(request.error);
555
+ });
556
+ };
557
+ }
558
+ });
559
+
560
+ // functions/idb/crud/data.set.ts
561
+ var data_set_exports = {};
562
+ var init_data_set = __esm({
563
+ "functions/idb/crud/data.set.ts"() {
564
+ init_esm_shims();
565
+ init_idb();
566
+ init_message();
567
+ idb.data.set = (storeName, table, value) => {
568
+ return new Promise((resolve, reject) => {
569
+ const request = indexedDB.open(storeName);
570
+ request.onsuccess = () => {
571
+ const db = request.result;
572
+ if (!db.objectStoreNames.contains(table)) {
573
+ db.close();
574
+ return reject(new Error(`Table ${table} does not exist in ${storeName}`));
575
+ }
576
+ const transaction = db.transaction(table, "readwrite");
577
+ const objectStore = transaction.objectStore(table);
578
+ const putRequest = objectStore.put(value);
579
+ putRequest.onsuccess = () => {
580
+ db.close();
581
+ message_default(`Data saved in ${storeName}.${table}`);
582
+ resolve(putRequest.result);
583
+ };
584
+ putRequest.onerror = (_) => {
585
+ db.close();
586
+ message_default(`Database insert error: ${putRequest.error?.message}`);
587
+ reject(putRequest.error);
588
+ };
589
+ };
590
+ request.onerror = () => {
591
+ reject(request.error);
592
+ };
593
+ });
594
+ };
595
+ }
596
+ });
597
+
598
+ // functions/idb/crud/data.get.ts
599
+ var data_get_exports = {};
600
+ var init_data_get = __esm({
601
+ "functions/idb/crud/data.get.ts"() {
602
+ init_esm_shims();
603
+ init_idb();
604
+ idb.data.get = (storeName, table, key) => {
605
+ return new Promise((resolve, reject) => {
606
+ const request = indexedDB.open(storeName);
607
+ request.onsuccess = (event) => {
608
+ const db = event.target.result;
609
+ if (!db.objectStoreNames.contains(table)) {
610
+ db.close();
611
+ return reject(new Error(`Table ${table} not found in ${storeName}`));
612
+ }
613
+ const transaction = db.transaction(table, "readonly");
614
+ const store2 = transaction.objectStore(table);
615
+ const getRequest = store2.get(key);
616
+ getRequest.onsuccess = () => {
617
+ db.close();
618
+ resolve(getRequest.result);
619
+ };
620
+ getRequest.onerror = () => {
621
+ db.close();
622
+ reject(getRequest.error);
623
+ };
624
+ };
625
+ request.onerror = () => {
626
+ reject(request.error);
627
+ };
628
+ });
629
+ };
630
+ }
631
+ });
632
+
633
+ // functions/idb/index.ts
634
+ var _hasIDB, idb;
635
+ var init_idb = __esm({
636
+ "functions/idb/index.ts"() {
637
+ init_esm_shims();
638
+ init_platform();
639
+ init_env();
640
+ _hasIDB = hasIndexedDB();
641
+ idb = {
642
+ db: {},
643
+ table: {},
644
+ data: {}
645
+ };
646
+ if (_hasIDB) {
647
+ (async () => {
648
+ Object.defineProperty(idb, "db", { value: {}, writable: true, configurable: true });
649
+ Object.defineProperty(idb, "table", { value: {}, writable: true, configurable: true });
650
+ Object.defineProperty(idb, "data", { value: {}, writable: true, configurable: true });
651
+ Object.defineProperty(globalThis, "idbases", {
652
+ value: [],
653
+ writable: true,
654
+ configurable: true,
655
+ enumerable: false
656
+ });
657
+ await Promise.all([
658
+ Promise.resolve().then(() => (init_db_create(), db_create_exports)),
659
+ Promise.resolve().then(() => (init_db_list(), db_list_exports)),
660
+ Promise.resolve().then(() => (init_db_exist(), db_exist_exports)),
661
+ Promise.resolve().then(() => (init_db_quota(), db_quota_exports)),
662
+ Promise.resolve().then(() => (init_db_delete(), db_delete_exports)),
663
+ Promise.resolve().then(() => (init_db_size(), db_size_exports)),
664
+ Promise.resolve().then(() => (init_db_version(), db_version_exports)),
665
+ Promise.resolve().then(() => (init_db_support(), db_support_exports)),
666
+ Promise.resolve().then(() => (init_table_create(), table_create_exports)),
667
+ Promise.resolve().then(() => (init_table_size(), table_size_exports)),
668
+ Promise.resolve().then(() => (init_data_delete(), data_delete_exports)),
669
+ Promise.resolve().then(() => (init_data_set(), data_set_exports)),
670
+ Promise.resolve().then(() => (init_data_get(), data_get_exports))
671
+ ]);
672
+ Object.preventExtensions(idb);
673
+ Object.seal(idb);
674
+ Object.freeze(idb);
675
+ })();
676
+ } else {
677
+ idb._disabled = true;
678
+ idb._warning = "IndexedDB is not available in this environment (Node.js/Deno). Use store or session for persistence.";
679
+ if (DEV) {
680
+ console.warn("Memorio IDB: IndexedDB is not available in this environment. Use store or session for data persistence.");
681
+ }
682
+ }
683
+ }
684
+ });
685
+
686
+ // modules/redux.ts
687
+ init_esm_shims();
688
+
689
+ // adapters/redux/index.ts
690
+ init_esm_shims();
691
+
692
+ // adapters/redux/middleware.ts
693
+ init_esm_shims();
694
+
695
+ // adapters/redux/selectors.ts
696
+ init_esm_shims();
697
+ function normalizeMappings(mappings) {
698
+ const out = {};
699
+ if (!mappings) return out;
700
+ for (const key of Object.keys(mappings)) {
701
+ const v = mappings[key];
702
+ if (typeof v === "function") {
703
+ out[key] = { selector: v };
704
+ } else if (v && typeof v === "object") {
705
+ out[key] = v;
706
+ }
707
+ }
708
+ return out;
709
+ }
710
+ __name(normalizeMappings, "normalizeMappings");
711
+ function selectValues(state3, mappings) {
712
+ const values = {};
713
+ for (const key of Object.keys(mappings)) {
714
+ try {
715
+ values[key] = mappings[key].selector(state3);
716
+ } catch {
717
+ values[key] = void 0;
718
+ }
719
+ }
720
+ return values;
721
+ }
722
+ __name(selectValues, "selectValues");
723
+ function deepEqual(a, b) {
724
+ if (a === b) return true;
725
+ if (a == null || b == null) return false;
726
+ if (typeof a !== typeof b) return false;
727
+ if (typeof a !== "object") return a === b;
728
+ if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
729
+ if (a instanceof RegExp && b instanceof RegExp) return a.source === b.source && a.flags === b.flags;
730
+ const ak = Object.keys(a);
731
+ const bk = Object.keys(b);
732
+ if (ak.length !== bk.length) return false;
733
+ if (Array.isArray(a) || Array.isArray(b)) {
734
+ if (!Array.isArray(a) || !Array.isArray(b)) return false;
735
+ if (a.length !== b.length) return false;
736
+ for (let i = 0; i < a.length; i++) {
737
+ if (!deepEqual(a[i], b[i])) return false;
738
+ }
739
+ return true;
740
+ }
741
+ for (const k of ak) {
742
+ if (!(k in b)) return false;
743
+ if (!deepEqual(a[k], b[k])) return false;
744
+ }
745
+ return true;
746
+ }
747
+ __name(deepEqual, "deepEqual");
748
+ function actionType(action) {
749
+ return action && typeof action === "object" ? action.type : void 0;
750
+ }
751
+ __name(actionType, "actionType");
752
+ function shouldIgnoreAction(action, opts, mapping) {
753
+ const t = actionType(action);
754
+ if (opts.blacklist && opts.blacklist.length && opts.blacklist.includes(t)) return true;
755
+ if (opts.whitelist && opts.whitelist.length && !opts.whitelist.includes(t)) return true;
756
+ if (mapping && mapping.ignoreActions && mapping.ignoreActions.length && mapping.ignoreActions.includes(t)) {
757
+ return true;
758
+ }
759
+ return false;
760
+ }
761
+ __name(shouldIgnoreAction, "shouldIgnoreAction");
762
+ function collectDirtyMappings(action, opts, mappings) {
763
+ const dirty = [];
764
+ for (const key of Object.keys(mappings)) {
765
+ if (!shouldIgnoreAction(action, opts, mappings[key])) dirty.push(key);
766
+ }
767
+ return dirty;
768
+ }
769
+ __name(collectDirtyMappings, "collectDirtyMappings");
770
+
771
+ // adapters/redux/persist.ts
772
+ init_esm_shims();
773
+
774
+ // functions/memory/index.ts
775
+ init_esm_shims();
776
+
777
+ // functions/state/index.ts
778
+ init_esm_shims();
779
+ init_internal();
780
+ init_message();
781
+
782
+ // core/dispatch.ts
783
+ init_esm_shims();
784
+ var dispatch = {
785
+ /**
786
+ * Dispatches a custom event with the specified name and value.
787
+ * @param name The name of the event.
788
+ * @param value The value to pass with the event.
789
+ */
790
+ set: /* @__PURE__ */ __name((name, value = {}) => {
791
+ globalThis.dispatchEvent(new CustomEvent(String(name), value));
792
+ }, "set"),
793
+ ///
794
+ /**
795
+ * Subscribes a callback to an event name. Maintains a *list* of handlers per
796
+ * name, so multiple subscribers on the same path (e.g. several
797
+ * `useObserver` calls observing `state.report`) each keep firing and each
798
+ * get an independent unsubscribe. The previous single-slot-per-name
799
+ * behaviour silently dropped the second subscriber and let any unsubscribe
800
+ * cancel every other subscriber on that path.
801
+ * @param name The name of the event to listen for.
802
+ * @param cb The callback function to execute when the event is triggered.
803
+ * @returns An unsubscribe function for this subscriber, or void if no callback.
804
+ */
805
+ listen: /* @__PURE__ */ __name((name, cb = null, _flag) => {
806
+ if (!cb) return;
807
+ const wrapped = /* @__PURE__ */ __name((e) => {
808
+ const target = e;
809
+ if (globalThis.queueMicrotask) {
810
+ globalThis.queueMicrotask(() => cb(target));
811
+ } else {
812
+ Promise.resolve().then(() => cb(target));
813
+ }
814
+ }, "wrapped");
815
+ globalThis.addEventListener(name, wrapped);
816
+ const list = globalThis.events[name] = globalThis.events[name] ?? [];
817
+ list.push(wrapped);
818
+ return () => {
819
+ globalThis.removeEventListener(name, wrapped);
820
+ const idx = list.indexOf(wrapped);
821
+ if (idx > -1) list.splice(idx, 1);
822
+ if (!list.length) delete globalThis.events[name];
823
+ };
824
+ }, "listen"),
825
+ ///
826
+ /**
827
+ * Removes ALL handlers for the specified event name (imperative bulk
828
+ * removal). For per-subscriber teardown, use the unsubscribe function
829
+ * returned by `listen`.
830
+ * @param name The name of the event to remove the listeners for.
831
+ */
832
+ remove: /* @__PURE__ */ __name((name) => {
833
+ const entry = globalThis.events?.[name];
834
+ if (Array.isArray(entry)) {
835
+ entry.forEach((h) => globalThis.removeEventListener(name, h));
836
+ } else if (typeof entry === "function") {
837
+ globalThis.removeEventListener(name, entry);
838
+ }
839
+ delete globalThis.events[name];
840
+ }, "remove")
841
+ };
842
+
843
+ // functions/schema/index.ts
844
+ init_esm_shims();
845
+ init_message();
846
+ var _schemas = /* @__PURE__ */ new Map();
847
+ var _validateValue = /* @__PURE__ */ __name((value, schema2, path2) => {
848
+ const errors = [];
849
+ if (schema2.type && schema2.type !== "any") {
850
+ const actualType = Array.isArray(value) ? "array" : typeof value;
851
+ if (actualType !== schema2.type) {
852
+ errors.push(`${path2}: expected ${schema2.type}, got ${actualType}`);
853
+ return { valid: false, errors };
854
+ }
855
+ }
856
+ if (schema2.enum && !schema2.enum.includes(value)) {
857
+ errors.push(`${path2}: value must be one of [${schema2.enum.map(String).join(", ")}]`);
858
+ }
859
+ if (schema2.validator) {
860
+ const result = schema2.validator(value);
861
+ if (result !== true) {
862
+ errors.push(`${path2}: ${typeof result === "string" ? result : "validation failed"}`);
863
+ }
864
+ }
865
+ if (typeof value === "number") {
866
+ if (schema2.min !== void 0 && value < schema2.min) {
867
+ errors.push(`${path2}: value ${value} is less than minimum ${schema2.min}`);
868
+ }
869
+ if (schema2.max !== void 0 && value > schema2.max) {
870
+ errors.push(`${path2}: value ${value} exceeds maximum ${schema2.max}`);
871
+ }
872
+ }
873
+ if (typeof value === "string") {
874
+ if (schema2.min !== void 0 && value.length < schema2.min) {
875
+ errors.push(`${path2}: string length ${value.length} is less than minimum ${schema2.min}`);
876
+ }
877
+ if (schema2.max !== void 0 && value.length > schema2.max) {
878
+ errors.push(`${path2}: string length ${value.length} exceeds maximum ${schema2.max}`);
879
+ }
880
+ if (schema2.pattern && !schema2.pattern.test(value)) {
881
+ errors.push(`${path2}: string does not match required pattern`);
882
+ }
883
+ }
884
+ if (schema2.type === "object" && value && typeof value === "object" && !Array.isArray(value)) {
885
+ if (schema2.required) {
886
+ for (const req of schema2.required) {
887
+ if (!(req in value)) {
888
+ errors.push(`${path2}: missing required property '${req}'`);
889
+ }
890
+ }
891
+ }
892
+ if (schema2.properties) {
893
+ for (const [prop, propSchema] of Object.entries(schema2.properties)) {
894
+ if (prop in value && value[prop] !== void 0) {
895
+ const propResult = _validateValue(value[prop], propSchema, `${path2}.${prop}`);
896
+ if (!propResult.valid) {
897
+ errors.push(...propResult.errors || []);
898
+ }
899
+ }
900
+ }
901
+ }
902
+ }
903
+ if (schema2.type === "array" && Array.isArray(value) && schema2.items) {
904
+ for (let i = 0; i < value.length; i++) {
905
+ const itemResult = _validateValue(value[i], schema2.items, `${path2}[${i}]`);
906
+ if (!itemResult.valid) {
907
+ errors.push(...itemResult.errors || []);
908
+ }
909
+ }
910
+ }
911
+ return errors.length === 0 ? { valid: true } : { valid: false, errors };
912
+ }, "_validateValue");
913
+ var validate = /* @__PURE__ */ __name((path2, value) => {
914
+ const schema2 = _schemas.get(path2);
915
+ if (!schema2) {
916
+ return { valid: true };
917
+ }
918
+ return _validateValue(value, schema2, path2);
919
+ }, "validate");
920
+ var registerSchema = /* @__PURE__ */ __name((path2, schema2) => {
921
+ if (typeof schema2 === "function") {
922
+ _schemas.set(path2, { validator: schema2 });
923
+ } else {
924
+ _schemas.set(path2, schema2);
925
+ }
926
+ message_default(`[memorio schema] Registered schema for '${path2}'`);
927
+ }, "registerSchema");
928
+ var unregisterSchema = /* @__PURE__ */ __name((path2) => {
929
+ return _schemas.delete(path2);
930
+ }, "unregisterSchema");
931
+ var listSchemas = /* @__PURE__ */ __name(() => {
932
+ return Array.from(_schemas.keys());
933
+ }, "listSchemas");
934
+ var getSchema = /* @__PURE__ */ __name((path2) => {
935
+ return _schemas.get(path2);
936
+ }, "getSchema");
937
+ var schema = {
938
+ register: registerSchema,
939
+ validate,
940
+ unregister: unregisterSchema,
941
+ list: listSchemas,
942
+ get: getSchema
943
+ };
944
+
945
+ // functions/state/index.ts
946
+ init_env();
947
+ var TARGET = /* @__PURE__ */ Symbol("memorio.target");
948
+ var wrapperCache = /* @__PURE__ */ new WeakMap();
949
+ var deepRaw = /* @__PURE__ */ __name((val, seen = null) => {
950
+ if (val === null || typeof val !== "object") return val;
951
+ if (val[TARGET] !== void 0) return deepRaw(val[TARGET], seen);
952
+ if (seen) {
953
+ if (seen.has(val)) return val;
954
+ seen.add(val);
955
+ }
956
+ const ctor = val.constructor?.name;
957
+ if (ctor !== "Object" && ctor !== "Array") return val;
958
+ const copy = Array.isArray(val) ? [] : {};
959
+ for (const k of Reflect.ownKeys(val)) {
960
+ copy[k] = deepRaw(val[k], seen);
961
+ }
962
+ return copy;
963
+ }, "deepRaw");
964
+ var objPath = /* @__PURE__ */ __name((prop, object, separator = ".") => {
965
+ return object.concat(prop).join(separator);
966
+ }, "objPath");
967
+ var buildProxy = /* @__PURE__ */ __name((obj, callback, tree = []) => {
968
+ const event = /* @__PURE__ */ __name((name) => {
969
+ try {
970
+ dispatch.set(name, { detail: { name } });
971
+ } catch (err) {
972
+ if (DEV) console.warn("[memorio state] event dispatch failed:", err);
973
+ }
974
+ return;
975
+ }, "event");
976
+ return new Proxy(
977
+ obj,
978
+ {
979
+ get(target, prop) {
980
+ if (prop === "__path") {
981
+ return tree.length > 0 ? "state." + tree.join(".") : "state";
982
+ }
983
+ if (prop === TARGET) {
984
+ return target;
985
+ }
986
+ if (target[TARGET] !== void 0) {
987
+ return target;
988
+ }
989
+ if (prop === "list") {
990
+ message_default('Some state could be hidden when you use "state.list". Use "state" to see the complete list ');
991
+ return deepRaw(target, /* @__PURE__ */ new WeakSet());
992
+ }
993
+ if (typeof prop === "string") {
994
+ const path2 = tree.length > 0 ? "state." + tree.concat(prop).join(".") : "state." + prop;
995
+ internal_default.lastAccessedPath = path2;
996
+ if (internal_default.tracking) {
997
+ internal_default.trackedPaths.add(path2);
998
+ }
999
+ }
1000
+ if (prop === "_lastPath") {
1001
+ return internal_default.lastAccessedPath;
1002
+ }
1003
+ if (prop === "remove") {
1004
+ return (key) => {
1005
+ delete target[key];
1006
+ return true;
1007
+ };
1008
+ }
1009
+ if (prop === "removeAll") {
1010
+ return () => {
1011
+ try {
1012
+ for (const key in target) {
1013
+ if (typeof target[key] !== "function" && !["list", "remove", "removeAll", "lock", "unlock"].includes(key)) {
1014
+ delete target[key];
1015
+ }
1016
+ }
1017
+ } catch (error) {
1018
+ console.error(error);
1019
+ }
1020
+ return;
1021
+ };
1022
+ }
1023
+ if (Object.isFrozen(target[prop])) return target[prop];
1024
+ if (prop === "lock" || prop === "unlock") {
1025
+ const value = Reflect.get(target, prop);
1026
+ if (value) return value;
1027
+ }
1028
+ try {
1029
+ const value = Reflect.get(target, prop);
1030
+ if (value && typeof value === "object" && ["Array", "Object"].includes(value.constructor.name)) {
1031
+ let wrapper = wrapperCache.get(value);
1032
+ if (!wrapper) {
1033
+ wrapper = buildProxy(value, callback, tree.concat(prop));
1034
+ wrapperCache.set(value, wrapper);
1035
+ }
1036
+ return wrapper;
1037
+ }
1038
+ return value;
1039
+ } catch (error) {
1040
+ console.error("Error: ", error);
1041
+ return void 0;
1042
+ }
1043
+ },
1044
+ set(target, key, value) {
1045
+ if (internal_default.locked) {
1046
+ console.error("Error: state is locked. Use state.unlock() to enable modifications.");
1047
+ return false;
1048
+ }
1049
+ if (protect.includes(key)) {
1050
+ console.error("key " + key + " is protected");
1051
+ return false;
1052
+ }
1053
+ if (target[key] && typeof target[key] === "object" && Object.isFrozen(target[key])) {
1054
+ console.error(`Error: state '${key}' is locked`);
1055
+ return false;
1056
+ }
1057
+ if (target[key] && typeof target[key] === "object" && target[key].__locked) {
1058
+ console.error(`Error: state '${key}' is locked. Use state.${key}.unlock() to enable modifications.`);
1059
+ return false;
1060
+ }
1061
+ try {
1062
+ const path2 = objPath(key, tree);
1063
+ const rawValue = deepRaw(value);
1064
+ const _schemaResult = schema.validate(path2, rawValue);
1065
+ if (!_schemaResult.valid) {
1066
+ if (DEV && internal_default.debug) {
1067
+ console.error(
1068
+ `[memorio schema] Validation failed for '${path2}':`,
1069
+ _schemaResult.errors
1070
+ );
1071
+ }
1072
+ message_default(
1073
+ `[memorio schema] Validation failed for '${path2}': ` + (_schemaResult.errors?.join(", ") || "unknown error")
1074
+ );
1075
+ return false;
1076
+ }
1077
+ callback(
1078
+ {
1079
+ action: "set",
1080
+ path: path2,
1081
+ target,
1082
+ newValue: rawValue,
1083
+ previousValue: Reflect.get(target, key)
1084
+ }
1085
+ );
1086
+ event("state." + path2);
1087
+ Reflect.set(target, key, rawValue);
1088
+ internal_default.bumpStateVersion();
1089
+ if (target[key] && typeof target[key] === "object") {
1090
+ const lockValue = target[key];
1091
+ if (lockValue && typeof lockValue === "object") {
1092
+ try {
1093
+ Object.defineProperty(lockValue, "__locked", {
1094
+ writable: true,
1095
+ enumerable: false,
1096
+ configurable: false,
1097
+ value: false
1098
+ });
1099
+ Object.defineProperty(lockValue, "lock", {
1100
+ writable: false,
1101
+ enumerable: false,
1102
+ configurable: false,
1103
+ value: /* @__PURE__ */ __name(() => {
1104
+ Object.defineProperty(lockValue, "__locked", {
1105
+ writable: true,
1106
+ enumerable: false,
1107
+ configurable: false,
1108
+ value: true
1109
+ });
1110
+ message_default(`State '${key}' is now locked.`);
1111
+ }, "value")
1112
+ });
1113
+ Object.defineProperty(lockValue, "unlock", {
1114
+ writable: false,
1115
+ enumerable: false,
1116
+ configurable: false,
1117
+ value: /* @__PURE__ */ __name(() => {
1118
+ Object.defineProperty(lockValue, "__locked", {
1119
+ writable: true,
1120
+ enumerable: false,
1121
+ configurable: false,
1122
+ value: false
1123
+ });
1124
+ message_default(`State '${key}' is now unlocked.`);
1125
+ }, "value")
1126
+ });
1127
+ } catch (err) {
1128
+ if (DEV) console.warn("[memorio state] lock/unlock defineProperty failed:", err);
1129
+ }
1130
+ }
1131
+ }
1132
+ return true;
1133
+ } catch (error) {
1134
+ console.error("Error in set trap:", error);
1135
+ return false;
1136
+ }
1137
+ },
1138
+ deleteProperty(target, prop) {
1139
+ try {
1140
+ const path2 = objPath(prop, tree);
1141
+ const previousValue = Reflect.get(target, prop);
1142
+ callback({ action: "delete", path: path2, target, previousValue });
1143
+ return Reflect.deleteProperty(target, prop);
1144
+ } catch (error) {
1145
+ console.error("Error in deleteProperty trap:", error);
1146
+ return false;
1147
+ }
1148
+ },
1149
+ ownKeys(target) {
1150
+ return Reflect.ownKeys(target);
1151
+ },
1152
+ getOwnPropertyDescriptor(target, prop) {
1153
+ return Reflect.getOwnPropertyDescriptor(target, prop);
1154
+ }
1155
+ }
1156
+ );
1157
+ }, "buildProxy");
1158
+ var STATE_INSTANCE_KEY = "__memorio_state_instance__";
1159
+ var state2;
1160
+ if (globalThis[STATE_INSTANCE_KEY]) {
1161
+ state2 = globalThis[STATE_INSTANCE_KEY];
1162
+ } else {
1163
+ state2 = buildProxy({}, (mutation) => {
1164
+ if (internal_default.historyEnabled) {
1165
+ internal_default.recordMutation({
1166
+ path: mutation.path,
1167
+ action: mutation.action,
1168
+ newValue: mutation.newValue,
1169
+ previousValue: mutation.previousValue,
1170
+ timestamp: Date.now()
1171
+ });
1172
+ }
1173
+ });
1174
+ state2.lock = () => {
1175
+ internal_default.locked = true;
1176
+ message_default("State is now locked. All modifications are blocked.");
1177
+ };
1178
+ state2.unlock = () => {
1179
+ internal_default.locked = false;
1180
+ message_default("State is now unlocked. Modifications are allowed.");
1181
+ };
1182
+ globalThis[STATE_INSTANCE_KEY] = state2;
1183
+ }
1184
+
1185
+ // functions/store/index.ts
1186
+ init_esm_shims();
1187
+ init_platform();
1188
+ init_internal();
1189
+ init_message();
1190
+ var _localStorage = getLocalStorage();
1191
+ var _fallbackStorageByContext = /* @__PURE__ */ new Map();
1192
+ function _getFallbackStorage() {
1193
+ const contextName = internal_default.currentContext || "";
1194
+ const key = contextName || "default";
1195
+ if (!_fallbackStorageByContext.has(key)) {
1196
+ _fallbackStorageByContext.set(key, /* @__PURE__ */ new Map());
1197
+ }
1198
+ return _fallbackStorageByContext.get(key);
1199
+ }
1200
+ __name(_getFallbackStorage, "_getFallbackStorage");
1201
+ var _hasStorage = _localStorage !== null;
1202
+ function _getPrefix() {
1203
+ const contextName = internal_default.currentContext || "";
1204
+ return contextName ? `${contextName}-` : `memorio_store_`;
1205
+ }
1206
+ __name(_getPrefix, "_getPrefix");
1207
+ function _prefixKey(name) {
1208
+ if (!name || typeof name !== "string") {
1209
+ console.warn(`[memorio store] key is empty or not a string - operation aborted`);
1210
+ return "";
1211
+ }
1212
+ if (name.length > 512) {
1213
+ console.warn(`[memorio store] key "${name}" exceeds 512 chars - operation aborted`);
1214
+ return "";
1215
+ }
1216
+ return _getPrefix() + name;
1217
+ }
1218
+ __name(_prefixKey, "_prefixKey");
1219
+ function _read(prefixedName) {
1220
+ const raw = _hasStorage ? _localStorage.getItem(prefixedName) : _getFallbackStorage().get(prefixedName);
1221
+ return raw ? JSON.parse(raw) : raw;
1222
+ }
1223
+ __name(_read, "_read");
1224
+ function _write(prefixedName, value) {
1225
+ const json = JSON.stringify(value);
1226
+ if (_hasStorage) _localStorage.setItem(prefixedName, json);
1227
+ else _getFallbackStorage().set(prefixedName, json);
1228
+ }
1229
+ __name(_write, "_write");
1230
+ function _remove(prefixedName) {
1231
+ if (_hasStorage) {
1232
+ if (_localStorage.getItem(prefixedName)) {
1233
+ _localStorage.removeItem(prefixedName);
1234
+ return true;
1235
+ }
1236
+ } else if (_getFallbackStorage().has(prefixedName)) {
1237
+ _getFallbackStorage().delete(prefixedName);
1238
+ return true;
1239
+ }
1240
+ return false;
1241
+ }
1242
+ __name(_remove, "_remove");
1243
+ var STORE_INSTANCE_KEY = "__memorio_store_instance__";
1244
+ var store;
1245
+ if (globalThis[STORE_INSTANCE_KEY]) {
1246
+ store = globalThis[STORE_INSTANCE_KEY];
1247
+ } else {
1248
+ store = new Proxy({}, {});
1249
+ Object.defineProperties(
1250
+ store,
1251
+ {
1252
+ /**
1253
+ * Gets a value from storage.
1254
+ * @param name The key to retrieve.
1255
+ * @returns The parsed value or null if not found.
1256
+ */
1257
+ get: {
1258
+ value: /* @__PURE__ */ __name((name) => {
1259
+ if (!name) {
1260
+ console.warn("[memorio store] store.get() called with empty or null key - returning null");
1261
+ return null;
1262
+ }
1263
+ try {
1264
+ return _read(_prefixKey(name));
1265
+ } catch (err) {
1266
+ message(`Error parsing store item '${name}': ${err}`);
1267
+ }
1268
+ return null;
1269
+ }, "value")
1270
+ },
1271
+ getMultiple: {
1272
+ value: /* @__PURE__ */ __name((keys) => {
1273
+ const result = {};
1274
+ for (const key of keys) {
1275
+ try {
1276
+ const item = store.get(key);
1277
+ if (item) result[key] = item;
1278
+ } catch (err) {
1279
+ console.debug(`[memorio store] getMultiple error for key "${key}":`, err);
1280
+ }
1281
+ }
1282
+ return result;
1283
+ }, "value")
1284
+ },
1285
+ /**
1286
+ * Sets a value in storage.
1287
+ * @param name The key to set.
1288
+ * @param value The value to store (objects, arrays, primitives).
1289
+ * @returns true if written, false if the key was rejected.
1290
+ */
1291
+ set: {
1292
+ value: /* @__PURE__ */ __name((name, value) => {
1293
+ if (!name) {
1294
+ console.warn("[memorio store] store.set() called with empty or null key - write aborted");
1295
+ return false;
1296
+ }
1297
+ const prefixedName = _prefixKey(name);
1298
+ if (!prefixedName) return false;
1299
+ if (typeof value === "function") {
1300
+ console.warn("[memorio store] functions are not storable - write aborted for key: " + name);
1301
+ message("Storing functions is not secure and is blocked for safety.");
1302
+ return false;
1303
+ }
1304
+ try {
1305
+ _write(prefixedName, value);
1306
+ } catch (err) {
1307
+ message(`Error setting store item '${name}': ${err}`);
1308
+ return false;
1309
+ }
1310
+ return true;
1311
+ }, "value")
1312
+ },
1313
+ /**
1314
+ * Removes a value from storage.
1315
+ * @param name The key to remove.
1316
+ * @returns True if removed, false if not found.
1317
+ */
1318
+ remove: {
1319
+ value: /* @__PURE__ */ __name((name) => {
1320
+ if (!name) {
1321
+ console.debug("[memorio store] store.remove() called with empty or null key - returning false");
1322
+ return false;
1323
+ }
1324
+ const prefixedName = _prefixKey(name);
1325
+ if (!prefixedName) return false;
1326
+ try {
1327
+ return _remove(prefixedName);
1328
+ } catch (err) {
1329
+ message(`Error removing store item '${name}': ${err}`);
1330
+ }
1331
+ return false;
1332
+ }, "value")
1333
+ },
1334
+ /**
1335
+ * Alias for remove.
1336
+ * @param name The key to delete.
1337
+ */
1338
+ delete: {
1339
+ value: /* @__PURE__ */ __name((name) => {
1340
+ return store.remove(name);
1341
+ }, "value")
1342
+ },
1343
+ /**
1344
+ * Clears all memorio items from storage.
1345
+ */
1346
+ removeAll: {
1347
+ value: /* @__PURE__ */ __name(() => {
1348
+ if (_hasStorage) {
1349
+ const keysToRemove = [];
1350
+ for (let i = 0; i < _localStorage.length; i++) {
1351
+ const key = _localStorage.key(i);
1352
+ if (key?.startsWith(_getPrefix())) keysToRemove.push(key);
1353
+ }
1354
+ keysToRemove.forEach((key) => _localStorage.removeItem(key));
1355
+ } else {
1356
+ _getFallbackStorage().clear();
1357
+ }
1358
+ return true;
1359
+ }, "value")
1360
+ },
1361
+ /**
1362
+ * Alias for removeAll.
1363
+ */
1364
+ clearAll: {
1365
+ value: /* @__PURE__ */ __name(() => {
1366
+ store.removeAll();
1367
+ return true;
1368
+ }, "value")
1369
+ },
1370
+ /**
1371
+ * Estimates storage quota usage.
1372
+ * @returns Promise with [usage, quota].
1373
+ */
1374
+ quota: {
1375
+ value: /* @__PURE__ */ __name(async () => {
1376
+ return [0, 0];
1377
+ }, "value")
1378
+ },
1379
+ /**
1380
+ * Calculates total size of all memorio items in kilobytes.
1381
+ * Counts each prefixed key and its JSON-serialized value, summing their
1382
+ * byte lengths and converting to whole kilobytes (Math.ceil). Replaces
1383
+ * the previous character-only total which did not express real usage.
1384
+ * @returns Total size in kilobytes (0 when empty / no memorio items).
1385
+ */
1386
+ size: {
1387
+ value: /* @__PURE__ */ __name(() => {
1388
+ let totalBytes = 0;
1389
+ if (_hasStorage) {
1390
+ for (let i = 0; i < _localStorage.length; i++) {
1391
+ const key = _localStorage.key(i);
1392
+ if (key && key.startsWith(_getPrefix())) {
1393
+ const item = _localStorage.getItem(key);
1394
+ if (item) totalBytes += key.length + item.length;
1395
+ }
1396
+ }
1397
+ } else {
1398
+ _getFallbackStorage().forEach((value, key) => {
1399
+ totalBytes += key.length + value.length;
1400
+ });
1401
+ }
1402
+ return totalBytes === 0 ? 0 : Math.ceil(totalBytes / 1024);
1403
+ }, "value")
1404
+ },
1405
+ /**
1406
+ * Check if using real localStorage or fallback
1407
+ */
1408
+ isPersistent: {
1409
+ get: /* @__PURE__ */ __name(() => _hasStorage, "get")
1410
+ },
1411
+ /**
1412
+ * Get a list of all memorio store items.
1413
+ */
1414
+ list: {
1415
+ value: /* @__PURE__ */ __name(() => {
1416
+ const result = {};
1417
+ try {
1418
+ if (_hasStorage) {
1419
+ for (let i = 0; i < _localStorage.length; i++) {
1420
+ const key = _localStorage.key(i);
1421
+ if (key?.startsWith(_getPrefix())) {
1422
+ const cleanKey = key.replace(_getPrefix(), "");
1423
+ const item = _localStorage.getItem(key);
1424
+ if (item !== null) {
1425
+ try {
1426
+ result[cleanKey] = JSON.parse(item);
1427
+ } catch {
1428
+ result[cleanKey] = item;
1429
+ }
1430
+ }
1431
+ }
1432
+ }
1433
+ } else {
1434
+ _getFallbackStorage().forEach((value, key) => {
1435
+ if (key.startsWith(_getPrefix())) {
1436
+ const cleanKey = key.replace(_getPrefix(), "");
1437
+ try {
1438
+ result[cleanKey] = JSON.parse(value);
1439
+ } catch {
1440
+ result[cleanKey] = value;
1441
+ }
1442
+ }
1443
+ });
1444
+ }
1445
+ } catch (err) {
1446
+ message(`Error listing store items: ${err}`);
1447
+ }
1448
+ return result;
1449
+ }, "value")
1450
+ }
1451
+ }
1452
+ );
1453
+ Object.freeze(store);
1454
+ globalThis[STORE_INSTANCE_KEY] = store;
1455
+ }
1456
+
1457
+ // functions/session/index.ts
1458
+ init_esm_shims();
1459
+ init_platform();
1460
+ init_internal();
1461
+ init_message();
1462
+ var _sessionStorage = getSessionStorage();
1463
+ var _fallbackStorageByContext2 = /* @__PURE__ */ new Map();
1464
+ function _getFallbackStorage2() {
1465
+ const contextName = internal_default.currentContext || "";
1466
+ const key = contextName || "default";
1467
+ if (!_fallbackStorageByContext2.has(key)) {
1468
+ _fallbackStorageByContext2.set(key, /* @__PURE__ */ new Map());
1469
+ }
1470
+ return _fallbackStorageByContext2.get(key);
1471
+ }
1472
+ __name(_getFallbackStorage2, "_getFallbackStorage");
1473
+ var _hasStorage2 = _sessionStorage !== null;
1474
+ function _getPrefix2() {
1475
+ const contextName = internal_default.currentContext || "";
1476
+ return contextName ? `${contextName}-` : `memorio_session_`;
1477
+ }
1478
+ __name(_getPrefix2, "_getPrefix");
1479
+ function _prefixKey2(name) {
1480
+ if (!name || typeof name !== "string") {
1481
+ console.warn("[memorio session] key is empty or not a string - operation aborted");
1482
+ return "";
1483
+ }
1484
+ if (name.length > 512) {
1485
+ console.warn(`[memorio session] key "${name}" exceeds 512 chars - operation aborted`);
1486
+ return "";
1487
+ }
1488
+ return _getPrefix2() + name;
1489
+ }
1490
+ __name(_prefixKey2, "_prefixKey");
1491
+ function _read2(prefixedName) {
1492
+ const raw = _hasStorage2 ? _sessionStorage.getItem(prefixedName) : _getFallbackStorage2().get(prefixedName);
1493
+ return raw ? JSON.parse(raw) : raw;
1494
+ }
1495
+ __name(_read2, "_read");
1496
+ function _write2(prefixedName, value) {
1497
+ const json = JSON.stringify(value);
1498
+ if (_hasStorage2) _sessionStorage.setItem(prefixedName, json);
1499
+ else _getFallbackStorage2().set(prefixedName, json);
1500
+ }
1501
+ __name(_write2, "_write");
1502
+ function _remove2(prefixedName) {
1503
+ if (_hasStorage2) {
1504
+ if (_sessionStorage.getItem(prefixedName)) {
1505
+ _sessionStorage.removeItem(prefixedName);
1506
+ return true;
1507
+ }
1508
+ } else if (_getFallbackStorage2().has(prefixedName)) {
1509
+ _getFallbackStorage2().delete(prefixedName);
1510
+ return true;
1511
+ }
1512
+ return false;
1513
+ }
1514
+ __name(_remove2, "_remove");
1515
+ var SESSION_INSTANCE_KEY = "__memorio_session_instance__";
1516
+ var session;
1517
+ if (globalThis[SESSION_INSTANCE_KEY]) {
1518
+ session = globalThis[SESSION_INSTANCE_KEY];
1519
+ } else {
1520
+ session = new Proxy({}, {});
1521
+ Object.defineProperties(
1522
+ session,
1523
+ {
1524
+ /**
1525
+ * Gets a value from storage.
1526
+ * @param name The key to retrieve.
1527
+ * @returns The parsed value or null if not found.
1528
+ */
1529
+ get: {
1530
+ value: /* @__PURE__ */ __name((name) => {
1531
+ if (!name) {
1532
+ console.warn("[memorio session] session.get() called with empty or null key - returning null");
1533
+ return null;
1534
+ }
1535
+ try {
1536
+ return _read2(_prefixKey2(name));
1537
+ } catch (err) {
1538
+ message(`Error parsing session item '${name}':${err}`);
1539
+ }
1540
+ return null;
1541
+ }, "value")
1542
+ },
1543
+ /**
1544
+ * Sets a value in storage.
1545
+ * @param name The key to set.
1546
+ * @param value The value to store.
1547
+ * @returns true if written, false if the key was rejected.
1548
+ */
1549
+ set: {
1550
+ value: /* @__PURE__ */ __name((name, value) => {
1551
+ if (!name) {
1552
+ console.warn("[memorio session] session.set() called with empty or null key - write aborted");
1553
+ return false;
1554
+ }
1555
+ const prefixedName = _prefixKey2(name);
1556
+ if (!prefixedName) return false;
1557
+ if (typeof value === "function") {
1558
+ console.warn("[memorio session] functions are not storable - write aborted for key: " + name);
1559
+ message("It's not secure to session functions.");
1560
+ return false;
1561
+ }
1562
+ try {
1563
+ _write2(prefixedName, value);
1564
+ } catch (err) {
1565
+ message(`Error setting session item '${name}': ${err}`);
1566
+ return false;
1567
+ }
1568
+ return true;
1569
+ }, "value")
1570
+ },
1571
+ /**
1572
+ * Removes a value from storage.
1573
+ * @param name The key to remove.
1574
+ * @returns True if removed.
1575
+ */
1576
+ remove: {
1577
+ value: /* @__PURE__ */ __name((name) => {
1578
+ if (!name) {
1579
+ console.warn("[memorio session] session.remove() called with empty or null key - returning false");
1580
+ return false;
1581
+ }
1582
+ const prefixedName = _prefixKey2(name);
1583
+ if (!prefixedName) return false;
1584
+ try {
1585
+ return _remove2(prefixedName);
1586
+ } catch (err) {
1587
+ message(`Error removing session item '${name}': ${err}`);
1588
+ }
1589
+ return false;
1590
+ }, "value")
1591
+ },
1592
+ /**
1593
+ * Alias for remove.
1594
+ * @param name The key to delete.
1595
+ * @returns True if removed.
1596
+ */
1597
+ delete: {
1598
+ value: /* @__PURE__ */ __name((name) => {
1599
+ return session.remove(name);
1600
+ }, "value")
1601
+ },
1602
+ /**
1603
+ * Clears all sessionStorage items.
1604
+ */
1605
+ removeAll: {
1606
+ value: /* @__PURE__ */ __name(() => {
1607
+ if (_hasStorage2) {
1608
+ const keysToRemove = [];
1609
+ for (let i = 0; i < _sessionStorage.length; i++) {
1610
+ const key = _sessionStorage.key(i);
1611
+ if (key?.startsWith(_getPrefix2())) {
1612
+ keysToRemove.push(key);
1613
+ }
1614
+ }
1615
+ keysToRemove.forEach((key) => _sessionStorage.removeItem(key));
1616
+ } else {
1617
+ _getFallbackStorage2().clear();
1618
+ }
1619
+ return true;
1620
+ }, "value")
1621
+ },
1622
+ /**
1623
+ * Alias for removeAll.
1624
+ */
1625
+ clearAll: {
1626
+ value: /* @__PURE__ */ __name(() => {
1627
+ session.removeAll();
1628
+ return true;
1629
+ }, "value")
1630
+ },
1631
+ quota: {
1632
+ value: /* @__PURE__ */ __name(async () => {
1633
+ return [0, 0];
1634
+ }, "value")
1635
+ },
1636
+ /**
1637
+ * Calculates total size of all memorio session items in kilobytes.
1638
+ * Counts each prefixed key and its JSON-serialized value, summing their
1639
+ * byte lengths and converting to whole kilobytes (Math.ceil).
1640
+ * @returns Total size in kilobytes (0 when empty / no memorio items).
1641
+ */
1642
+ size: {
1643
+ value: /* @__PURE__ */ __name(() => {
1644
+ let totalBytes = 0;
1645
+ if (_hasStorage2) {
1646
+ for (let i = 0; i < _sessionStorage.length; i++) {
1647
+ const key = _sessionStorage.key(i);
1648
+ if (key && key.startsWith(_getPrefix2())) {
1649
+ const item = _sessionStorage.getItem(key);
1650
+ if (item) totalBytes += key.length + item.length;
1651
+ }
1652
+ }
1653
+ } else {
1654
+ _getFallbackStorage2().forEach((value, key) => {
1655
+ totalBytes += key.length + value.length;
1656
+ });
1657
+ }
1658
+ return totalBytes === 0 ? 0 : Math.ceil(totalBytes / 1024);
1659
+ }, "value")
1660
+ },
1661
+ /**
1662
+ * Check if using real sessionStorage or fallback
1663
+ */
1664
+ isPersistent: {
1665
+ get: /* @__PURE__ */ __name(() => _hasStorage2, "get")
1666
+ },
1667
+ /**
1668
+ * Get a list of all memorio session items.
1669
+ */
1670
+ list: {
1671
+ value: /* @__PURE__ */ __name(() => {
1672
+ const result = {};
1673
+ try {
1674
+ if (_hasStorage2) {
1675
+ for (let i = 0; i < _sessionStorage.length; i++) {
1676
+ const key = _sessionStorage.key(i);
1677
+ if (key?.startsWith(_getPrefix2())) {
1678
+ const cleanKey = key.replace(_getPrefix2(), "");
1679
+ const item = _sessionStorage.getItem(key);
1680
+ if (item !== null) {
1681
+ try {
1682
+ result[cleanKey] = JSON.parse(item);
1683
+ } catch {
1684
+ result[cleanKey] = item;
1685
+ }
1686
+ }
1687
+ }
1688
+ }
1689
+ } else {
1690
+ _getFallbackStorage2().forEach((value, key) => {
1691
+ if (key.startsWith(_getPrefix2())) {
1692
+ const cleanKey = key.replace(_getPrefix2(), "");
1693
+ try {
1694
+ result[cleanKey] = JSON.parse(value);
1695
+ } catch {
1696
+ result[cleanKey] = value;
1697
+ }
1698
+ }
1699
+ });
1700
+ }
1701
+ } catch (err) {
1702
+ message(`Error listing session items: ${err}`);
1703
+ }
1704
+ return result;
1705
+ }, "value")
1706
+ }
1707
+ }
1708
+ );
1709
+ Object.freeze(session);
1710
+ globalThis[SESSION_INSTANCE_KEY] = session;
1711
+ }
1712
+
1713
+ // functions/memory/index.ts
1714
+ init_idb();
1715
+
1716
+ // core/hlc.ts
1717
+ init_esm_shims();
1718
+ var NODE_ID_KEY = "__memorio_hlc_node";
1719
+ function getNodeId() {
1720
+ if (typeof globalThis === "undefined") return "node";
1721
+ try {
1722
+ if (typeof sessionStorage !== "undefined" && sessionStorage) {
1723
+ let id = sessionStorage.getItem(NODE_ID_KEY);
1724
+ if (!id) {
1725
+ id = generateNodeId();
1726
+ sessionStorage.setItem(NODE_ID_KEY, id);
1727
+ }
1728
+ return id;
1729
+ }
1730
+ } catch {
1731
+ }
1732
+ if (!globalThis.__memorioHlcNodeId) {
1733
+ globalThis.__memorioHlcNodeId = generateNodeId();
1734
+ }
1735
+ return globalThis.__memorioHlcNodeId;
1736
+ }
1737
+ __name(getNodeId, "getNodeId");
1738
+ function generateNodeId() {
1739
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
1740
+ return crypto.randomUUID().slice(0, 8);
1741
+ }
1742
+ return Math.random().toString(36).slice(2, 10);
1743
+ }
1744
+ __name(generateNodeId, "generateNodeId");
1745
+ var HLC_KEY = "__memorio_hlc_local";
1746
+ var local = globalThis[HLC_KEY] || {
1747
+ physical: 0,
1748
+ logical: 0,
1749
+ node: getNodeId()
1750
+ };
1751
+ if (!globalThis[HLC_KEY]) {
1752
+ globalThis[HLC_KEY] = local;
1753
+ }
1754
+ function tick(_incoming) {
1755
+ const now2 = Date.now();
1756
+ const base = local.physical;
1757
+ let physical;
1758
+ let logical;
1759
+ if (now2 > base) {
1760
+ physical = now2;
1761
+ logical = 0;
1762
+ } else if (now2 < base) {
1763
+ physical = base;
1764
+ logical = local.logical + 1;
1765
+ } else {
1766
+ physical = base;
1767
+ logical = local.logical + 1;
1768
+ }
1769
+ local.physical = physical;
1770
+ local.logical = logical;
1771
+ return { physical, logical, node: local.node };
1772
+ }
1773
+ __name(tick, "tick");
1774
+ function receive(remote) {
1775
+ const now2 = Date.now();
1776
+ if (remote.physical > local.physical) {
1777
+ local.physical = remote.physical > now2 ? remote.physical : now2;
1778
+ local.logical = 1;
1779
+ } else if (remote.physical === local.physical) {
1780
+ local.logical = Math.max(local.logical, remote.logical) + 1;
1781
+ }
1782
+ local.node = getNodeId();
1783
+ return { ...local };
1784
+ }
1785
+ __name(receive, "receive");
1786
+ function compare(a, b) {
1787
+ if (a.physical !== b.physical) {
1788
+ return a.physical < b.physical ? -1 : 1;
1789
+ }
1790
+ if (a.logical !== b.logical) {
1791
+ return a.logical < b.logical ? -1 : 1;
1792
+ }
1793
+ if (a.node !== b.node) {
1794
+ return a.node < b.node ? -1 : 1;
1795
+ }
1796
+ return 0;
1797
+ }
1798
+ __name(compare, "compare");
1799
+ function happenedBefore(a, b) {
1800
+ return compare(a, b) < 0;
1801
+ }
1802
+ __name(happenedBefore, "happenedBefore");
1803
+ function serialize(hlc2) {
1804
+ return `hlc:${hlc2.physical}:${hlc2.logical}:${hlc2.node}`;
1805
+ }
1806
+ __name(serialize, "serialize");
1807
+ function parse(serialized) {
1808
+ if (!serialized.startsWith("hlc:")) return null;
1809
+ const parts = serialized.split(":");
1810
+ if (parts.length !== 4) return null;
1811
+ const physical = parseInt(parts[1], 10);
1812
+ const logical = parseInt(parts[2], 10);
1813
+ const node = parts[3];
1814
+ if (isNaN(physical) || isNaN(logical)) return null;
1815
+ return { physical, logical, node };
1816
+ }
1817
+ __name(parse, "parse");
1818
+ var hlc = {
1819
+ tick,
1820
+ receive,
1821
+ compare,
1822
+ happenedBefore,
1823
+ serialize,
1824
+ parse,
1825
+ getNodeId
1826
+ };
1827
+
1828
+ // functions/memory/index.ts
1829
+ init_env();
1830
+
1831
+ // functions/memory/journal.ts
1832
+ init_esm_shims();
1833
+ init_env();
1834
+ var g = globalThis;
1835
+ function namespace() {
1836
+ const cfg = g.memorioSyncConfig;
1837
+ if (cfg && typeof cfg.namespace === "string" && cfg.namespace) return `ns:${cfg.namespace}`;
1838
+ const ctx = g.memorio ? g.memorio._currentContext : void 0;
1839
+ const ctxName = typeof ctx === "string" && ctx ? ctx : "";
1840
+ return ctxName ? `ctx:${ctxName}` : "default";
1841
+ }
1842
+ __name(namespace, "namespace");
1843
+ function isSyncEnabled() {
1844
+ return !!g.memorioSyncConfig;
1845
+ }
1846
+ __name(isSyncEnabled, "isSyncEnabled");
1847
+ var STORE_PREFIX = /* @__PURE__ */ __name((ns) => `memorio:sync:${ns}:`, "STORE_PREFIX");
1848
+ var INDEX_KEY = /* @__PURE__ */ __name((ns) => `${STORE_PREFIX(ns)}index`, "INDEX_KEY");
1849
+ function parseEntry(raw) {
1850
+ try {
1851
+ if (typeof raw === "string") return JSON.parse(raw);
1852
+ return raw;
1853
+ } catch (err) {
1854
+ if (DEV) console.warn("[memorio memory] failed to parse journal entry:", err);
1855
+ return null;
1856
+ }
1857
+ }
1858
+ __name(parseEntry, "parseEntry");
1859
+ var journal = {
1860
+ /** Append (or replace) a journal row for the current namespace. */
1861
+ async append(entry, operation) {
1862
+ const ns = namespace();
1863
+ const row = {
1864
+ ...entry,
1865
+ operation,
1866
+ updatedAt: entry.updatedAt || Date.now(),
1867
+ version: entry.version || 1,
1868
+ sync: "pending",
1869
+ hlc: entry.hlc || hlc.serialize(hlc.tick())
1870
+ };
1871
+ const key = `${STORE_PREFIX(ns)}${row.id}`;
1872
+ store.set(key, row);
1873
+ const idx = store.get(INDEX_KEY(ns)) || [];
1874
+ if (!idx.includes(row.id)) idx.push(row.id);
1875
+ store.set(INDEX_KEY(ns), idx);
1876
+ return row;
1877
+ },
1878
+ /** All pending (not-yet-synced) entries for the current namespace. */
1879
+ async pending() {
1880
+ const ns = namespace();
1881
+ const out = [];
1882
+ const idx = store.get(INDEX_KEY(ns)) || [];
1883
+ for (const id of idx) {
1884
+ const raw = store.get(`${STORE_PREFIX(ns)}${id}`);
1885
+ if (!raw) continue;
1886
+ const e = parseEntry(raw);
1887
+ if (e && e.sync !== "synced") out.push(e);
1888
+ }
1889
+ out.sort((a, b) => {
1890
+ if (a.hlc && b.hlc) {
1891
+ const ha = hlc.parse(a.hlc);
1892
+ const hb = hlc.parse(b.hlc);
1893
+ if (ha && hb) return hlc.compare(ha, hb);
1894
+ }
1895
+ return (a.updatedAt || 0) - (b.updatedAt || 0);
1896
+ });
1897
+ return out;
1898
+ },
1899
+ /**
1900
+ * Mark entries as synced. Returns the number of rows actually advanced to
1901
+ * `synced` (namespace-scoped).
1902
+ */
1903
+ async markSynced(ids) {
1904
+ if (!ids.length) return 0;
1905
+ const ns = namespace();
1906
+ let count = 0;
1907
+ const idx = store.get(INDEX_KEY(ns)) || [];
1908
+ for (const id of idx) {
1909
+ if (!ids.includes(id)) continue;
1910
+ const key = `${STORE_PREFIX(ns)}${id}`;
1911
+ const raw = store.get(key);
1912
+ if (!raw) continue;
1913
+ const e = parseEntry(raw);
1914
+ if (!e || e.sync === "synced") continue;
1915
+ e.sync = "synced";
1916
+ store.set(key, e);
1917
+ count++;
1918
+ }
1919
+ return count;
1920
+ },
1921
+ async get(id) {
1922
+ const ns = namespace();
1923
+ const raw = store.get(`${STORE_PREFIX(ns)}${id}`);
1924
+ return parseEntry(raw ?? "");
1925
+ },
1926
+ /** Remove all journal rows for the current namespace. */
1927
+ async clear() {
1928
+ const ns = namespace();
1929
+ const idx = store.get(INDEX_KEY(ns)) || [];
1930
+ for (const id of idx) store.remove(`${STORE_PREFIX(ns)}${id}`);
1931
+ store.remove(INDEX_KEY(ns));
1932
+ },
1933
+ /**
1934
+ * Reconcile the local journal against the configured provider. Pushes pending
1935
+ * local operations, then optionally pulls newer remote operations and applies
1936
+ * them. No-op (empty ack) when no provider is configured.
1937
+ *
1938
+ * When pulling remote entries, HLC timestamps are used to order operations
1939
+ * causally. Concurrent writes to the same key (HLC tie) are resolved via the
1940
+ * provider's `resolveConflict` method (if provided), otherwise the REMOTE
1941
+ * entry wins by default (logged at warn level in dev). Provide a resolver on
1942
+ * the sync provider to override this behaviour and prevent silent local data
1943
+ * loss.
1944
+ */
1945
+ async replay() {
1946
+ const ack = { synced: [], resolved: [] };
1947
+ if (!isSyncEnabled()) return ack;
1948
+ const transport = g.memorioSyncConfig || {};
1949
+ const provider = transport.provider;
1950
+ if (!provider || typeof provider.push !== "function") return ack;
1951
+ const pending = await this.pending();
1952
+ if (pending.length) {
1953
+ try {
1954
+ const res = await provider.push(pending);
1955
+ ack.synced = res?.synced || [];
1956
+ ack.conflicts = res?.conflicts;
1957
+ ack.error = res?.error;
1958
+ if (ack.synced.length) await this.markSynced(ack.synced);
1959
+ } catch (err) {
1960
+ ack.error = String(err);
1961
+ }
1962
+ }
1963
+ if (typeof provider.pull === "function") {
1964
+ try {
1965
+ const since = pending.length ? Math.min(...pending.map((p) => p.updatedAt || 0)) : 0;
1966
+ const remote = await provider.pull(since);
1967
+ for (const e of remote || []) {
1968
+ if (e.hlc) {
1969
+ const parsed = hlc.parse(e.hlc);
1970
+ if (parsed) hlc.receive(parsed);
1971
+ }
1972
+ const localEntry = await this.get(e.id);
1973
+ if (localEntry && e.hlc && localEntry.hlc) {
1974
+ const ha = hlc.parse(localEntry.hlc);
1975
+ const hb = hlc.parse(e.hlc);
1976
+ if (ha && hb) {
1977
+ const cmp = hlc.compare(ha, hb);
1978
+ if (cmp === 0) {
1979
+ const hasResolver = typeof provider.resolveConflict === "function";
1980
+ const resolution = hasResolver ? await provider.resolveConflict(localEntry, e) : "remote";
1981
+ if (!hasResolver && DEV) {
1982
+ console.warn(`[memorio memory] replay() conflict for "${e.id}": no resolveConflict handler provided, defaulting to remote-wins`);
1983
+ }
1984
+ ack.resolved?.push({ id: e.id, resolution });
1985
+ if (resolution === "local") continue;
1986
+ } else if (cmp > 0) {
1987
+ continue;
1988
+ }
1989
+ }
1990
+ }
1991
+ await this.append(e, e.operation || "confirm");
1992
+ await this.markSynced([e.id]);
1993
+ }
1994
+ } catch (err) {
1995
+ if (DEV) console.warn("[memorio memory] sync pull failed:", err);
1996
+ }
1997
+ }
1998
+ return ack;
1999
+ },
2000
+ status() {
2001
+ return Promise.resolve("store");
2002
+ }
2003
+ };
2004
+ function configure(opts) {
2005
+ const prev = g.memorioSyncConfig || {};
2006
+ g.memorioSyncConfig = { ...prev, ...opts };
2007
+ return journal;
2008
+ }
2009
+ __name(configure, "configure");
2010
+ if (typeof g.addEventListener === "function") {
2011
+ let armed = false;
2012
+ g.addEventListener("focus", () => {
2013
+ if (armed || !isSyncEnabled()) return;
2014
+ armed = true;
2015
+ void journal.replay().finally(() => {
2016
+ armed = false;
2017
+ });
2018
+ });
2019
+ }
2020
+ var journal_default = journal;
2021
+
2022
+ // functions/memory/index.ts
2023
+ var MEMORY_INDEX_KEY = "__memorio_memory_index__";
2024
+ var SUPERSEDED_PREFIX = "__memorio_superseded__";
2025
+ function isSyncEnabled2() {
2026
+ return !!globalThis.memorioSyncConfig;
2027
+ }
2028
+ __name(isSyncEnabled2, "isSyncEnabled");
2029
+ async function recordJournal(entry, operation) {
2030
+ if (!isSyncEnabled2()) return;
2031
+ if (entry.scope === "hot") return;
2032
+ try {
2033
+ await journal_default.append(entry, operation);
2034
+ } catch (err) {
2035
+ if (DEV) console.warn("[memorio memory] journal append failed:", err);
2036
+ }
2037
+ }
2038
+ __name(recordJournal, "recordJournal");
2039
+ function memoryEntryKey(id) {
2040
+ return id.startsWith(SUPERSEDED_PREFIX) ? id : `${SUPERSEDED_PREFIX}${id}`;
2041
+ }
2042
+ __name(memoryEntryKey, "memoryEntryKey");
2043
+ function normalizeTags(tags) {
2044
+ if (!tags) return [];
2045
+ return Array.isArray(tags) ? tags : [tags];
2046
+ }
2047
+ __name(normalizeTags, "normalizeTags");
2048
+ function resolveScope(value, opts) {
2049
+ if (opts.scope) return opts.scope;
2050
+ const size = JSON.stringify(value).length;
2051
+ if (size > 1e6) return "durable";
2052
+ if (size > 1e5) return "local";
2053
+ return "local";
2054
+ }
2055
+ __name(resolveScope, "resolveScope");
2056
+ function now() {
2057
+ return Date.now();
2058
+ }
2059
+ __name(now, "now");
2060
+ function isExpired(entry) {
2061
+ if (entry.ttl === null || entry.ttl === void 0) return false;
2062
+ return now() - entry.createdAt > entry.ttl;
2063
+ }
2064
+ __name(isExpired, "isExpired");
2065
+ function matchesFilters(entry, opts) {
2066
+ if (entry.status === "obsolete") return opts.includeObsolete ?? false;
2067
+ if (entry.status === "superseded") return opts.includeObsolete ?? false;
2068
+ if (isExpired(entry)) {
2069
+ return opts.includeObsolete ?? false;
2070
+ }
2071
+ if (opts.type) {
2072
+ const types = Array.isArray(opts.type) ? opts.type : [opts.type];
2073
+ if (!types.includes(entry.type)) return false;
2074
+ }
2075
+ if (opts.minConfidence !== void 0 && entry.confidence < opts.minConfidence) return false;
2076
+ return true;
2077
+ }
2078
+ __name(matchesFilters, "matchesFilters");
2079
+ function matchesContextFilters(entry, opts) {
2080
+ if (entry.status !== "active") return false;
2081
+ if (isExpired(entry)) return false;
2082
+ if (opts.tags) {
2083
+ const tags = Array.isArray(opts.tags) ? opts.tags : [opts.tags];
2084
+ const hasMatch = tags.some((t) => entry.tags.includes(t));
2085
+ if (!hasMatch) return false;
2086
+ }
2087
+ if (opts.types) {
2088
+ const types = Array.isArray(opts.types) ? opts.types : [opts.types];
2089
+ if (!types.includes(entry.type)) return false;
2090
+ }
2091
+ if (opts.minConfidence !== void 0 && entry.confidence < opts.minConfidence) return false;
2092
+ if (opts.scopes && !opts.scopes.includes(entry.scope)) return false;
2093
+ return true;
2094
+ }
2095
+ __name(matchesContextFilters, "matchesContextFilters");
2096
+ function computeRelevance(entry) {
2097
+ const ageHours = (now() - entry.createdAt) / (1e3 * 3600);
2098
+ const recencyScore = Math.max(0.1, 1 / (1 + ageHours * 0.5));
2099
+ const confidenceScore = entry.confidence;
2100
+ const accessScore = 1 + entry.tags.length * 0.1;
2101
+ const typeBoost = {
2102
+ decision: 1.5,
2103
+ context: 1.3,
2104
+ preference: 1.2,
2105
+ task: 1,
2106
+ fact: 0.8
2107
+ };
2108
+ const scopeBoost = {
2109
+ hot: 1.5,
2110
+ session: 1.2,
2111
+ local: 1,
2112
+ durable: 0.8
2113
+ };
2114
+ return recencyScore * confidenceScore * accessScore * typeBoost[entry.type] * scopeBoost[entry.scope];
2115
+ }
2116
+ __name(computeRelevance, "computeRelevance");
2117
+ function getNestedPath(obj, path2) {
2118
+ if (!path2 || typeof path2 !== "string") return void 0;
2119
+ const parts = path2.replace(/^state\./, "").split(".");
2120
+ let current = obj;
2121
+ for (const part of parts) {
2122
+ if (current === null || current === void 0) return void 0;
2123
+ current = current[part];
2124
+ }
2125
+ return current;
2126
+ }
2127
+ __name(getNestedPath, "getNestedPath");
2128
+ function setNestedPath(obj, path2, value) {
2129
+ if (!path2 || typeof path2 !== "string") return;
2130
+ const parts = path2.replace(/^state\./, "").split(".");
2131
+ let current = obj;
2132
+ for (let i = 0; i < parts.length - 1; i++) {
2133
+ const part = parts[i];
2134
+ if (current[part] === void 0 || current[part] === null) {
2135
+ current[part] = {};
2136
+ }
2137
+ current = current[part];
2138
+ }
2139
+ current[parts[parts.length - 1]] = value;
2140
+ }
2141
+ __name(setNestedPath, "setNestedPath");
2142
+ function deleteNestedPath(obj, path2) {
2143
+ if (!path2 || typeof path2 !== "string") return;
2144
+ const parts = path2.replace(/^state\./, "").split(".");
2145
+ let current = obj;
2146
+ for (let i = 0; i < parts.length - 1; i++) {
2147
+ const part = parts[i];
2148
+ if (current[part] === void 0 || current[part] === null) return;
2149
+ current = current[part];
2150
+ }
2151
+ delete current[parts[parts.length - 1]];
2152
+ }
2153
+ __name(deleteNestedPath, "deleteNestedPath");
2154
+ async function saveToScope(entry) {
2155
+ const storageKey = entry.status === "superseded" ? memoryEntryKey(entry.id || entry.key) : entry.key;
2156
+ const serialized = JSON.stringify(entry);
2157
+ switch (entry.scope) {
2158
+ case "hot":
2159
+ setNestedPath(state2, storageKey, entry.value);
2160
+ break;
2161
+ case "session":
2162
+ session.set(storageKey, serialized);
2163
+ break;
2164
+ case "local":
2165
+ store.set(storageKey, serialized);
2166
+ break;
2167
+ case "durable":
2168
+ await idb.set("memories", storageKey, serialized);
2169
+ break;
2170
+ }
2171
+ await updateIndex(entry.id || entry.key, entry.scope, entry.status === "superseded");
2172
+ }
2173
+ __name(saveToScope, "saveToScope");
2174
+ async function loadFromScope(id, scope, isSuperseded = false) {
2175
+ const storageKey = isSuperseded ? memoryEntryKey(id) : id;
2176
+ let raw;
2177
+ switch (scope) {
2178
+ case "hot": {
2179
+ const val = getNestedPath(state2, storageKey);
2180
+ if (val === void 0) return null;
2181
+ return reconstructEntry(id, val, scope);
2182
+ }
2183
+ case "session":
2184
+ raw = session.get(storageKey);
2185
+ break;
2186
+ case "local":
2187
+ raw = store.get(storageKey);
2188
+ break;
2189
+ case "durable":
2190
+ raw = await idb.get("memories", storageKey);
2191
+ break;
2192
+ }
2193
+ if (!raw) return null;
2194
+ try {
2195
+ const entry = JSON.parse(raw);
2196
+ entry.id = entry.id || id;
2197
+ return entry;
2198
+ } catch (err) {
2199
+ if (DEV) console.warn("[memorio memory] failed to parse memory entry:", err);
2200
+ return null;
2201
+ }
2202
+ }
2203
+ __name(loadFromScope, "loadFromScope");
2204
+ function reconstructEntry(key, value, scope) {
2205
+ return {
2206
+ id: key,
2207
+ key,
2208
+ value,
2209
+ type: "fact",
2210
+ confidence: 1,
2211
+ scope,
2212
+ ttl: null,
2213
+ tags: [],
2214
+ status: "active",
2215
+ createdAt: now(),
2216
+ lastConfirmedAt: now(),
2217
+ supersededId: null
2218
+ };
2219
+ }
2220
+ __name(reconstructEntry, "reconstructEntry");
2221
+ async function removeFromScope(id, scope, isSuperseded = false) {
2222
+ const storageKey = isSuperseded ? memoryEntryKey(id) : id;
2223
+ switch (scope) {
2224
+ case "hot":
2225
+ setNestedPath(state2, storageKey, void 0);
2226
+ break;
2227
+ case "session":
2228
+ session.remove(storageKey);
2229
+ break;
2230
+ case "local":
2231
+ store.remove(storageKey);
2232
+ break;
2233
+ case "durable":
2234
+ await idb.deleteKey("memories", storageKey);
2235
+ break;
2236
+ }
2237
+ await removeFromIndex(id, isSuperseded);
2238
+ }
2239
+ __name(removeFromScope, "removeFromScope");
2240
+ async function getAllIndexes() {
2241
+ try {
2242
+ const raw = store.get(MEMORY_INDEX_KEY);
2243
+ if (!raw) return {};
2244
+ return JSON.parse(raw);
2245
+ } catch (err) {
2246
+ if (DEV) console.warn("[memorio memory] failed to parse memory index:", err);
2247
+ return {};
2248
+ }
2249
+ }
2250
+ __name(getAllIndexes, "getAllIndexes");
2251
+ async function updateIndex(id, scope, isSuperseded = false) {
2252
+ const index = await getAllIndexes();
2253
+ index[id] = { scope, superseded: isSuperseded };
2254
+ store.set(MEMORY_INDEX_KEY, JSON.stringify(index));
2255
+ }
2256
+ __name(updateIndex, "updateIndex");
2257
+ async function removeFromIndex(id, isSuperseded = false) {
2258
+ const index = await getAllIndexes();
2259
+ const entry = index[id];
2260
+ if (entry) {
2261
+ if (isSuperseded && entry.superseded) {
2262
+ delete index[id];
2263
+ } else if (!isSuperseded && !entry.superseded) {
2264
+ delete index[id];
2265
+ }
2266
+ }
2267
+ store.set(MEMORY_INDEX_KEY, JSON.stringify(index));
2268
+ }
2269
+ __name(removeFromIndex, "removeFromIndex");
2270
+ async function loadAll() {
2271
+ const index = await getAllIndexes();
2272
+ const entries = [];
2273
+ for (const [id, info] of Object.entries(index)) {
2274
+ const entry = await loadFromScope(id, info.scope, info.superseded);
2275
+ if (entry) {
2276
+ entry.id = entry.id || id;
2277
+ entry.supersededId = entry.supersededId ?? null;
2278
+ entries.push(entry);
2279
+ }
2280
+ }
2281
+ return entries;
2282
+ }
2283
+ __name(loadAll, "loadAll");
2284
+ var memory = {
2285
+ async remember(key, value, opts = {}) {
2286
+ const existing = await this._getEntry(key);
2287
+ if (existing && existing.status === "active") {
2288
+ const supersededId = `${existing.id}__v${Date.now()}`;
2289
+ const superseded = {
2290
+ ...existing,
2291
+ id: supersededId,
2292
+ key: existing.key,
2293
+ status: "superseded",
2294
+ supersededId: null,
2295
+ lastConfirmedAt: now()
2296
+ };
2297
+ await saveToScope(superseded);
2298
+ await recordJournal(superseded, "supersede");
2299
+ }
2300
+ const scope = resolveScope(value, opts);
2301
+ const tags = normalizeTags(opts.tags);
2302
+ const entry = {
2303
+ id: opts.id || key,
2304
+ key,
2305
+ value,
2306
+ type: opts.type || "fact",
2307
+ confidence: opts.confidence ?? 1,
2308
+ scope,
2309
+ ttl: opts.ttl ?? null,
2310
+ tags,
2311
+ source: opts.source,
2312
+ status: "active",
2313
+ createdAt: now(),
2314
+ lastConfirmedAt: now(),
2315
+ updatedAt: now(),
2316
+ version: existing ? existing.version ? existing.version + 1 : 1 : 1,
2317
+ sync: isSyncEnabled2() ? "pending" : void 0,
2318
+ supersededId: existing ? existing.id : null,
2319
+ hlc: hlc.serialize(hlc.tick())
2320
+ };
2321
+ await saveToScope(entry);
2322
+ await recordJournal(entry, "remember");
2323
+ dispatch.set("memorio:memory:remembered", { key, scope, entryId: entry.id });
2324
+ },
2325
+ async recall(query, opts = {}) {
2326
+ const entry = await this._getEntry(query);
2327
+ if (!entry) return null;
2328
+ if (!matchesFilters(entry, opts)) return null;
2329
+ entry.lastConfirmedAt = now();
2330
+ await saveToScope(entry);
2331
+ dispatch.set("memorio:memory:recalled", { key: query });
2332
+ return entry.value;
2333
+ },
2334
+ async context(opts = {}) {
2335
+ const entries = await loadAll();
2336
+ const filtered = entries.filter((e) => matchesContextFilters(e, opts));
2337
+ const ranked = filtered.map((entry) => ({
2338
+ entry,
2339
+ score: computeRelevance(entry)
2340
+ })).sort((a, b) => b.score - a.score).slice(0, opts.maxEntries ?? 25);
2341
+ return ranked.map(({ entry }) => ({
2342
+ key: entry.key,
2343
+ value: entry.value,
2344
+ type: entry.type,
2345
+ confidence: entry.confidence,
2346
+ scope: entry.scope,
2347
+ tags: entry.tags,
2348
+ age: now() - entry.createdAt,
2349
+ accessCount: entry.tags.length + 1,
2350
+ lastAccessedAt: entry.lastConfirmedAt
2351
+ }));
2352
+ },
2353
+ async forget(key) {
2354
+ const entry = await this._getEntry(key);
2355
+ if (!entry) {
2356
+ const tombstone2 = {
2357
+ id: key,
2358
+ key,
2359
+ value: null,
2360
+ type: "fact",
2361
+ confidence: 1,
2362
+ scope: "local",
2363
+ ttl: null,
2364
+ tags: [],
2365
+ status: "obsolete",
2366
+ operation: "delete",
2367
+ createdAt: now(),
2368
+ lastConfirmedAt: now(),
2369
+ updatedAt: now(),
2370
+ version: 1,
2371
+ sync: isSyncEnabled2() ? "pending" : void 0,
2372
+ hlc: hlc.serialize(hlc.tick())
2373
+ };
2374
+ await recordJournal(tombstone2, "delete");
2375
+ return;
2376
+ }
2377
+ await removeFromScope(entry.id || key, entry.scope, entry.status === "superseded");
2378
+ const tombstone = {
2379
+ ...entry,
2380
+ value: null,
2381
+ status: "obsolete",
2382
+ operation: "delete",
2383
+ updatedAt: now(),
2384
+ version: (entry.version ? entry.version : 0) + 1,
2385
+ sync: isSyncEnabled2() ? "pending" : void 0,
2386
+ hlc: hlc.serialize(hlc.tick())
2387
+ };
2388
+ await recordJournal(tombstone, "delete");
2389
+ dispatch.set("memorio:memory:forgotten", { key });
2390
+ },
2391
+ async update(key, value, opts = {}) {
2392
+ const existing = await this._getEntry(key);
2393
+ if (!existing) {
2394
+ await this.remember(key, value, opts);
2395
+ return;
2396
+ }
2397
+ const supersededId = `${existing.id}__v${now()}`;
2398
+ const superseded = {
2399
+ ...existing,
2400
+ id: supersededId,
2401
+ key: existing.key,
2402
+ status: "superseded",
2403
+ supersededId: null,
2404
+ lastConfirmedAt: now()
2405
+ };
2406
+ await saveToScope(superseded);
2407
+ await recordJournal(superseded, "supersede");
2408
+ const updated = {
2409
+ ...existing,
2410
+ value,
2411
+ lastConfirmedAt: now(),
2412
+ updatedAt: now(),
2413
+ version: (existing.version ? existing.version : 0) + 1,
2414
+ sync: isSyncEnabled2() ? "pending" : void 0,
2415
+ hlc: hlc.serialize(hlc.tick()),
2416
+ ...opts.scope ? { scope: opts.scope } : {},
2417
+ ...opts.ttl !== void 0 ? { ttl: opts.ttl } : {},
2418
+ ...opts.type ? { type: opts.type } : {},
2419
+ ...opts.confidence !== void 0 ? { confidence: opts.confidence } : {},
2420
+ ...opts.tags !== void 0 ? { tags: normalizeTags(opts.tags) } : {},
2421
+ ...opts.source ? { source: opts.source } : {}
2422
+ };
2423
+ await saveToScope(updated);
2424
+ await recordJournal(updated, "update");
2425
+ dispatch.set("memorio:memory:updated", { key, entryId: updated.id });
2426
+ },
2427
+ async stats() {
2428
+ const entries = await loadAll();
2429
+ const byScope = { hot: 0, session: 0, local: 0, durable: 0 };
2430
+ const byType = {};
2431
+ let expired = 0;
2432
+ for (const entry of entries) {
2433
+ byScope[entry.scope] = (byScope[entry.scope] || 0) + 1;
2434
+ if (isExpired(entry)) expired++;
2435
+ byType[entry.type] = (byType[entry.type] || 0) + 1;
2436
+ }
2437
+ return { total: entries.length, byScope, byType, expired };
2438
+ },
2439
+ async forgetExpired() {
2440
+ const entries = await loadAll();
2441
+ let count = 0;
2442
+ for (const entry of entries) {
2443
+ if (isExpired(entry) && entry.status === "active") {
2444
+ entry.status = "obsolete";
2445
+ entry.updatedAt = now();
2446
+ entry.operation = "expire";
2447
+ await saveToScope(entry);
2448
+ await recordJournal(entry, "expire");
2449
+ count++;
2450
+ }
2451
+ }
2452
+ return count;
2453
+ },
2454
+ async clear() {
2455
+ const index = await getAllIndexes();
2456
+ for (const [id, info] of Object.entries(index)) {
2457
+ await removeFromScope(id, info.scope, info.superseded);
2458
+ }
2459
+ store.remove(MEMORY_INDEX_KEY);
2460
+ },
2461
+ async _getEntry(key) {
2462
+ const index = await getAllIndexes();
2463
+ const info = index[key];
2464
+ if (!info) {
2465
+ const val = getNestedPath(state2, key);
2466
+ if (val !== void 0) return reconstructEntry(key, val, "hot");
2467
+ return null;
2468
+ }
2469
+ return loadFromScope(key, info.scope, info.superseded);
2470
+ },
2471
+ async _loadAll() {
2472
+ return loadAll();
2473
+ },
2474
+ async _save(entry) {
2475
+ await saveToScope(entry);
2476
+ },
2477
+ /** Apply a field-level path patch to an existing memory entry. */
2478
+ async patch(key, patches) {
2479
+ const entry = await this._getEntry(key);
2480
+ if (!entry) return;
2481
+ let patched = false;
2482
+ for (const p of patches) {
2483
+ if (p.op === "set") {
2484
+ setNestedPath({ [entry.key]: entry.value }, p.path.replace(/^[^.]+\./, ""), p.value);
2485
+ patched = true;
2486
+ } else if (p.op === "delete") {
2487
+ deleteNestedPath({ [entry.key]: entry.value }, p.path.replace(/^[^.]+\./, ""));
2488
+ patched = true;
2489
+ }
2490
+ }
2491
+ if (!patched) return;
2492
+ const updated = {
2493
+ ...entry,
2494
+ updatedAt: now(),
2495
+ lastConfirmedAt: now(),
2496
+ version: (entry.version ? entry.version : 0) + 1,
2497
+ sync: isSyncEnabled2() ? "pending" : void 0,
2498
+ hlc: hlc.serialize(hlc.tick()),
2499
+ patches,
2500
+ path: patches[0]?.path
2501
+ };
2502
+ await saveToScope(updated);
2503
+ await recordJournal(updated, "patch");
2504
+ dispatch.set("memorio:memory:patched", { key, patches });
2505
+ },
2506
+ /** Local operation journal (namespaced). No-op substrate when sqlite/idb unavailable. */
2507
+ journal: journal_default,
2508
+ /** Configure the optional cloud-sync layer (namespace + provider). Chainable. */
2509
+ configure(opts) {
2510
+ configure(opts);
2511
+ return this;
2512
+ }
2513
+ };
2514
+
2515
+ // adapters/redux/persist.ts
2516
+ function createPersistContext() {
2517
+ return { cache: {}, hydrating: false, pending: false, dirty: /* @__PURE__ */ new Set() };
2518
+ }
2519
+ __name(createPersistContext, "createPersistContext");
2520
+ function schedulePersist(getState, mappings, ctx, opts) {
2521
+ if (ctx.hydrating) return;
2522
+ if (ctx.pending) return;
2523
+ ctx.pending = true;
2524
+ queueMicrotask(() => {
2525
+ ctx.pending = false;
2526
+ void flushPersist(getState, mappings, ctx, opts);
2527
+ });
2528
+ }
2529
+ __name(schedulePersist, "schedulePersist");
2530
+ async function flushPersist(getState, mappings, ctx, opts) {
2531
+ const keys = Array.from(ctx.dirty);
2532
+ ctx.dirty.clear();
2533
+ if (keys.length === 0) return;
2534
+ const state3 = getState();
2535
+ const values = selectValues(state3, mappings);
2536
+ for (const key of keys) {
2537
+ const mapping = mappings[key];
2538
+ const next = values[key];
2539
+ const prev = ctx.cache[key];
2540
+ if (!deepEqual(next, prev)) {
2541
+ ctx.cache[key] = next;
2542
+ try {
2543
+ await memory.remember(key, next, {
2544
+ type: mapping.type,
2545
+ confidence: mapping.confidence ?? 0.9,
2546
+ scope: mapping.scope ?? "local",
2547
+ ttl: mapping.ttl ?? null,
2548
+ tags: mapping.tags,
2549
+ source: mapping.source ?? "redux"
2550
+ });
2551
+ if (opts.debug) {
2552
+ console.debug(`[memorio/redux] persisted "${key}"`);
2553
+ }
2554
+ } catch (err) {
2555
+ if (opts.failSoft === false) throw err;
2556
+ opts.onError?.(err, "persist");
2557
+ if (opts.debug) {
2558
+ console.debug(`[memorio/redux] persist failed for "${key}"`, err);
2559
+ }
2560
+ }
2561
+ }
2562
+ }
2563
+ }
2564
+ __name(flushPersist, "flushPersist");
2565
+
2566
+ // adapters/redux/middleware.ts
2567
+ function createMemorioMiddleware(opts = {}) {
2568
+ const mappings = normalizeMappings(opts.mappings);
2569
+ const ctx = createPersistContext();
2570
+ let getState = null;
2571
+ const middleware = /* @__PURE__ */ __name((api) => {
2572
+ getState = api.getState;
2573
+ return (next) => (action) => {
2574
+ const result = next(action);
2575
+ if (shouldIgnoreAction(action, opts)) return result;
2576
+ const dirty = collectDirtyMappings(action, opts, mappings);
2577
+ if (dirty.length === 0) return result;
2578
+ for (const key of dirty) ctx.dirty.add(key);
2579
+ void schedulePersist(getState, mappings, ctx, opts);
2580
+ return result;
2581
+ };
2582
+ }, "middleware");
2583
+ return {
2584
+ middleware,
2585
+ cache: ctx.cache,
2586
+ setHydrating: /* @__PURE__ */ __name((v) => {
2587
+ ctx.hydrating = v;
2588
+ }, "setHydrating"),
2589
+ flush: /* @__PURE__ */ __name(() => getState ? flushPersist(getState, mappings, ctx, opts) : Promise.resolve(), "flush")
2590
+ };
2591
+ }
2592
+ __name(createMemorioMiddleware, "createMemorioMiddleware");
2593
+
2594
+ // adapters/redux/hydration.ts
2595
+ init_esm_shims();
2596
+ async function hydrateMemorio(mappings, opts = {}, bridge) {
2597
+ const canonical = normalizeMappings(mappings);
2598
+ const values = {};
2599
+ let ok = true;
2600
+ bridge?.setHydrating(true);
2601
+ try {
2602
+ for (const key of Object.keys(canonical)) {
2603
+ try {
2604
+ const recalled = await memory.recall(key);
2605
+ if (recalled !== null && recalled !== void 0) values[key] = recalled;
2606
+ } catch (err) {
2607
+ ok = false;
2608
+ if (opts.failSoft === false) throw err;
2609
+ opts.onError?.(err, "hydrate");
2610
+ if (opts.debug) {
2611
+ console.debug(`[memorio/redux] hydrate recall failed for "${key}"`, err);
2612
+ }
2613
+ }
2614
+ }
2615
+ if (opts.onHydration) {
2616
+ opts.onHydration(values);
2617
+ if (bridge) {
2618
+ const selected = selectValues(bridge.getState(), canonical);
2619
+ for (const key of Object.keys(selected)) {
2620
+ bridge.cache[key] = selected[key];
2621
+ }
2622
+ }
2623
+ }
2624
+ } finally {
2625
+ bridge?.setHydrating(false);
2626
+ }
2627
+ return { values, ok };
2628
+ }
2629
+ __name(hydrateMemorio, "hydrateMemorio");
2630
+
2631
+ // adapters/redux/bridge.ts
2632
+ init_esm_shims();
2633
+ function createMemorioReduxBridge(opts = {}) {
2634
+ const handle = createMemorioMiddleware(opts);
2635
+ let disconnected = false;
2636
+ return {
2637
+ middleware: handle.middleware,
2638
+ cache: handle.cache,
2639
+ flush: handle.flush,
2640
+ disconnect: /* @__PURE__ */ __name(() => {
2641
+ if (disconnected) return;
2642
+ disconnected = true;
2643
+ handle.cache && Object.keys(handle.cache).forEach((k) => delete handle.cache[k]);
2644
+ handle.setHydrating(false);
2645
+ }, "disconnect"),
2646
+ hydrate: /* @__PURE__ */ __name(async (store2, hopts = {}) => {
2647
+ const res = await hydrateMemorio(
2648
+ opts.mappings,
2649
+ {
2650
+ failSoft: opts.failSoft,
2651
+ onError: opts.onError,
2652
+ debug: opts.debug,
2653
+ onHydration: hopts.onHydration
2654
+ },
2655
+ {
2656
+ cache: handle.cache,
2657
+ setHydrating: handle.setHydrating,
2658
+ getState: /* @__PURE__ */ __name(() => store2.getState(), "getState")
2659
+ }
2660
+ );
2661
+ return { values: res.values, ok: res.ok };
2662
+ }, "hydrate")
2663
+ };
2664
+ }
2665
+ __name(createMemorioReduxBridge, "createMemorioReduxBridge");
2666
+
2667
+ export { actionType, createMemorioMiddleware, createMemorioReduxBridge, deepEqual, hydrateMemorio, normalizeMappings, selectValues, shouldIgnoreAction };
2668
+ //# sourceMappingURL=redux.js.map
2669
+ //# sourceMappingURL=redux.js.map