memorio 4.9.31 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/AGENTS.md +3 -3
  2. package/README.md +327 -330
  3. package/SECURITY.md +17 -1
  4. package/SUMMARY.md +59 -45
  5. package/adr/001-state-proxy-model.md +96 -0
  6. package/adr/002-observer-semantics.md +180 -0
  7. package/adr/003-deep-mutation-semantics.md +129 -0
  8. package/adr/004-array-mutation-semantics.md +128 -0
  9. package/adr/005-scheduler-contract.md +149 -0
  10. package/adr/006-context-isolation.md +92 -0
  11. package/adr/007-mutation-records.md +118 -0
  12. package/adr/008-transactions.md +106 -0
  13. package/adr/009-history-model.md +110 -0
  14. package/adr/README.md +46 -0
  15. package/adr/template.md +49 -0
  16. package/examples/basic.ts +115 -115
  17. package/examples/browser-vanilla.html +358 -358
  18. package/examples/cache.ts +72 -72
  19. package/examples/cross-platform-guards.ts +57 -57
  20. package/examples/history.ts +104 -0
  21. package/examples/idb.ts +109 -109
  22. package/examples/multi-tenant-context.ts +44 -44
  23. package/examples/node-server.ts +308 -308
  24. package/examples/observer.ts +60 -60
  25. package/examples/platform.ts +115 -115
  26. package/examples/react-app.tsx +362 -362
  27. package/examples/react-observer.tsx +63 -63
  28. package/examples/semantic-memory.ts +60 -60
  29. package/examples/session-advanced.ts +91 -91
  30. package/examples/sqlite-batched-writes.ts +57 -57
  31. package/examples/state-advanced.ts +89 -89
  32. package/examples/store-advanced.ts +117 -117
  33. package/examples/sync.ts +90 -0
  34. package/examples/typed-and-schema.ts +102 -100
  35. package/examples/useObserver.tsx +140 -141
  36. package/global.cjs +4594 -0
  37. package/global.d.ts +8 -0
  38. package/global.js +4532 -0
  39. package/index.cjs +706 -649
  40. package/index.d.ts +1 -0
  41. package/index.js +686 -648
  42. package/llms.txt +72 -4
  43. package/markdown/AUDIT-REPORT.md +135 -0
  44. package/markdown/CACHE.md +100 -0
  45. package/markdown/CHANGELOG.md +243 -0
  46. package/markdown/DEVTOOLS.md +129 -0
  47. package/markdown/DISPATCH.md +177 -0
  48. package/markdown/HISTORY.md +199 -0
  49. package/markdown/IDB.md +178 -0
  50. package/markdown/IMPORT.md +153 -0
  51. package/markdown/INSPECT.md +123 -0
  52. package/markdown/LOGGER.md +154 -0
  53. package/markdown/MEMORY-ATTACHMENT.md +96 -0
  54. package/markdown/MEMORY.md +162 -0
  55. package/markdown/OBSERVER.md +209 -0
  56. package/markdown/PLATFORM.md +271 -0
  57. package/markdown/PROJECT.md +311 -0
  58. package/markdown/SCHEMA.md +176 -0
  59. package/markdown/SECURITY.md +330 -0
  60. package/markdown/SESSION.md +165 -0
  61. package/markdown/SQLITE.md +190 -0
  62. package/markdown/STATE.md +160 -0
  63. package/markdown/STORE.md +171 -0
  64. package/markdown/SYNC.md +319 -0
  65. package/markdown/TYPED.md +165 -0
  66. package/markdown/USEOBSERVER.md +257 -0
  67. package/modules/redux.cjs +561 -374
  68. package/modules/redux.cjs.map +1 -1
  69. package/modules/redux.js +561 -374
  70. package/modules/redux.js.map +1 -1
  71. package/package.json +13 -3
  72. package/types/env.d.ts +19 -9
  73. package/types/exports.d.ts +20 -0
  74. package/types/history.d.ts +13 -1
  75. package/types/memorio.d.ts +17 -5
  76. package/types/mutation.d.ts +75 -0
package/index.js CHANGED
@@ -17,8 +17,11 @@ var DEV, PROD;
17
17
  var init_env = __esm({
18
18
  "core/env.ts"() {
19
19
  init_esm_shims();
20
- DEV = typeof process !== "undefined" ? false : true;
20
+ DEV = false ;
21
21
  PROD = !DEV;
22
+ if (typeof globalThis !== "undefined") {
23
+ globalThis["__DEV__"] = DEV;
24
+ }
22
25
  }
23
26
  });
24
27
 
@@ -945,8 +948,8 @@ var init_table_size = __esm({
945
948
  if (!db.objectStoreNames.contains(table)) return resolve(0);
946
949
  let size = 0;
947
950
  let count = 0;
948
- const transaction = db.transaction([table], "readonly");
949
- const store2 = transaction.objectStore(table);
951
+ const transaction2 = db.transaction([table], "readonly");
952
+ const store2 = transaction2.objectStore(table);
950
953
  const request = store2.openCursor();
951
954
  request.onsuccess = async (event) => {
952
955
  const cursor = event.target.result;
@@ -990,8 +993,8 @@ var init_data_delete = __esm({
990
993
  db.close();
991
994
  return reject(new Error(`Table ${table} not found`));
992
995
  }
993
- const transaction = db.transaction(table, "readwrite");
994
- const objectStore = transaction.objectStore(table);
996
+ const transaction2 = db.transaction(table, "readwrite");
997
+ const objectStore = transaction2.objectStore(table);
995
998
  const deleteRequest = objectStore.delete(key);
996
999
  deleteRequest.onsuccess = () => {
997
1000
  db.close();
@@ -1015,8 +1018,8 @@ var init_data_delete = __esm({
1015
1018
  db.close();
1016
1019
  return reject(new Error(`Table ${table} not found`));
1017
1020
  }
1018
- const transaction = db.transaction(table, "readwrite");
1019
- const store2 = transaction.objectStore(table);
1021
+ const transaction2 = db.transaction(table, "readwrite");
1022
+ const store2 = transaction2.objectStore(table);
1020
1023
  const clearRequest = store2.clear();
1021
1024
  clearRequest.onsuccess = () => {
1022
1025
  db.close();
@@ -1050,8 +1053,8 @@ var init_data_set = __esm({
1050
1053
  db.close();
1051
1054
  return reject(new Error(`Table ${table} does not exist in ${storeName}`));
1052
1055
  }
1053
- const transaction = db.transaction(table, "readwrite");
1054
- const objectStore = transaction.objectStore(table);
1056
+ const transaction2 = db.transaction(table, "readwrite");
1057
+ const objectStore = transaction2.objectStore(table);
1055
1058
  const putRequest = objectStore.put(value);
1056
1059
  putRequest.onsuccess = () => {
1057
1060
  db.close();
@@ -1087,8 +1090,8 @@ var init_data_get = __esm({
1087
1090
  db.close();
1088
1091
  return reject(new Error(`Table ${table} not found in ${storeName}`));
1089
1092
  }
1090
- const transaction = db.transaction(table, "readonly");
1091
- const store2 = transaction.objectStore(table);
1093
+ const transaction2 = db.transaction(table, "readonly");
1094
+ const store2 = transaction2.objectStore(table);
1092
1095
  const getRequest = store2.get(key);
1093
1096
  getRequest.onsuccess = () => {
1094
1097
  db.close();
@@ -1750,9 +1753,25 @@ var dispatch = {
1750
1753
  const wrapped = /* @__PURE__ */ __name((e) => {
1751
1754
  const target = e;
1752
1755
  if (globalThis.queueMicrotask) {
1753
- globalThis.queueMicrotask(() => cb(target));
1756
+ globalThis.queueMicrotask(() => {
1757
+ try {
1758
+ cb(target);
1759
+ } catch (err) {
1760
+ if (typeof console !== "undefined") {
1761
+ console.error("[memorio dispatch] observer error:", err);
1762
+ }
1763
+ }
1764
+ });
1754
1765
  } else {
1755
- Promise.resolve().then(() => cb(target));
1766
+ Promise.resolve().then(() => {
1767
+ try {
1768
+ cb(target);
1769
+ } catch (err) {
1770
+ if (typeof console !== "undefined") {
1771
+ console.error("[memorio dispatch] observer error:", err);
1772
+ }
1773
+ }
1774
+ });
1756
1775
  }
1757
1776
  }, "wrapped");
1758
1777
  globalThis.addEventListener(name, wrapped);
@@ -1886,11 +1905,500 @@ var schema = {
1886
1905
  };
1887
1906
 
1888
1907
  // functions/state/index.ts
1908
+ init_store();
1889
1909
  init_env();
1910
+
1911
+ // core/mutation/engine.ts
1912
+ init_esm_shims();
1913
+ init_internal();
1914
+
1915
+ // core/hlc.ts
1916
+ init_esm_shims();
1917
+ var NODE_ID_KEY = "__memorio_hlc_node";
1918
+ function getNodeId() {
1919
+ if (typeof globalThis === "undefined") return "node";
1920
+ try {
1921
+ if (typeof sessionStorage !== "undefined" && sessionStorage) {
1922
+ let id = sessionStorage.getItem(NODE_ID_KEY);
1923
+ if (!id) {
1924
+ id = generateNodeId();
1925
+ sessionStorage.setItem(NODE_ID_KEY, id);
1926
+ }
1927
+ return id;
1928
+ }
1929
+ } catch {
1930
+ }
1931
+ if (!globalThis.__memorioHlcNodeId) {
1932
+ globalThis.__memorioHlcNodeId = generateNodeId();
1933
+ }
1934
+ return globalThis.__memorioHlcNodeId;
1935
+ }
1936
+ __name(getNodeId, "getNodeId");
1937
+ function generateNodeId() {
1938
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
1939
+ return crypto.randomUUID().slice(0, 8);
1940
+ }
1941
+ return Math.random().toString(36).slice(2, 10);
1942
+ }
1943
+ __name(generateNodeId, "generateNodeId");
1944
+ var HLC_KEY = "__memorio_hlc_local";
1945
+ var local = globalThis[HLC_KEY] || {
1946
+ physical: 0,
1947
+ logical: 0,
1948
+ node: getNodeId()
1949
+ };
1950
+ if (!globalThis[HLC_KEY]) {
1951
+ globalThis[HLC_KEY] = local;
1952
+ }
1953
+ function tick(_incoming) {
1954
+ const now2 = Date.now();
1955
+ const base = local.physical;
1956
+ let physical;
1957
+ let logical;
1958
+ if (now2 > base) {
1959
+ physical = now2;
1960
+ logical = 0;
1961
+ } else if (now2 < base) {
1962
+ physical = base;
1963
+ logical = local.logical + 1;
1964
+ } else {
1965
+ physical = base;
1966
+ logical = local.logical + 1;
1967
+ }
1968
+ local.physical = physical;
1969
+ local.logical = logical;
1970
+ return { physical, logical, node: local.node };
1971
+ }
1972
+ __name(tick, "tick");
1973
+ function receive(remote) {
1974
+ const now2 = Date.now();
1975
+ if (remote.physical > local.physical) {
1976
+ local.physical = remote.physical > now2 ? remote.physical : now2;
1977
+ local.logical = 1;
1978
+ } else if (remote.physical === local.physical) {
1979
+ local.logical = Math.max(local.logical, remote.logical) + 1;
1980
+ }
1981
+ local.node = getNodeId();
1982
+ return { ...local };
1983
+ }
1984
+ __name(receive, "receive");
1985
+ function compare(a, b) {
1986
+ if (a.physical !== b.physical) {
1987
+ return a.physical < b.physical ? -1 : 1;
1988
+ }
1989
+ if (a.logical !== b.logical) {
1990
+ return a.logical < b.logical ? -1 : 1;
1991
+ }
1992
+ if (a.node !== b.node) {
1993
+ return a.node < b.node ? -1 : 1;
1994
+ }
1995
+ return 0;
1996
+ }
1997
+ __name(compare, "compare");
1998
+ function happenedBefore(a, b) {
1999
+ return compare(a, b) < 0;
2000
+ }
2001
+ __name(happenedBefore, "happenedBefore");
2002
+ function serialize(hlc2) {
2003
+ return `hlc:${hlc2.physical}:${hlc2.logical}:${hlc2.node}`;
2004
+ }
2005
+ __name(serialize, "serialize");
2006
+ function parse(serialized) {
2007
+ if (!serialized.startsWith("hlc:")) return null;
2008
+ const parts = serialized.split(":");
2009
+ if (parts.length !== 4) return null;
2010
+ const physical = parseInt(parts[1], 10);
2011
+ const logical = parseInt(parts[2], 10);
2012
+ const node = parts[3];
2013
+ if (isNaN(physical) || isNaN(logical)) return null;
2014
+ return { physical, logical, node };
2015
+ }
2016
+ __name(parse, "parse");
2017
+ var hlc = {
2018
+ tick,
2019
+ receive,
2020
+ compare,
2021
+ happenedBefore,
2022
+ serialize,
2023
+ parse,
2024
+ getNodeId
2025
+ };
2026
+
2027
+ // core/mutation/id.ts
2028
+ init_esm_shims();
2029
+ function generateMutationId() {
2030
+ const now2 = hlc.tick();
2031
+ return "m_" + encodeHLC(now2);
2032
+ }
2033
+ __name(generateMutationId, "generateMutationId");
2034
+ function generateTransactionId() {
2035
+ const now2 = hlc.tick();
2036
+ return "tx_" + encodeHLC(now2);
2037
+ }
2038
+ __name(generateTransactionId, "generateTransactionId");
2039
+ function generateCommitId() {
2040
+ const now2 = hlc.tick();
2041
+ return "c_" + encodeHLC(now2);
2042
+ }
2043
+ __name(generateCommitId, "generateCommitId");
2044
+ function encodeHLC(hlcValue) {
2045
+ const timePart = hlcValue.physical.toString(36);
2046
+ const logicalPart = hlcValue.logical.toString(36).padStart(2, "0");
2047
+ const nodePart = hlcValue.node.slice(0, 4);
2048
+ return `${timePart}${logicalPart}${nodePart}`;
2049
+ }
2050
+ __name(encodeHLC, "encodeHLC");
2051
+
2052
+ // core/mutation/patch.ts
2053
+ init_esm_shims();
2054
+ function mutationToPatch(mutation) {
2055
+ if (mutation.before === mutation.after) return null;
2056
+ const op = mutationToPatchOp(mutation.operation, mutation.before, mutation.after);
2057
+ if (!op) return null;
2058
+ const patch = { op, path: mutation.path };
2059
+ if (op === "add" || op === "replace") {
2060
+ patch.value = mutation.after;
2061
+ }
2062
+ if (op === "replace") {
2063
+ patch.oldValue = mutation.before;
2064
+ }
2065
+ if (op === "remove") {
2066
+ patch.oldValue = mutation.before;
2067
+ }
2068
+ return patch;
2069
+ }
2070
+ __name(mutationToPatch, "mutationToPatch");
2071
+ function mutationToPatchOp(operation, _before, _after) {
2072
+ switch (operation) {
2073
+ case "set":
2074
+ if (_before === void 0) return "add";
2075
+ return "replace";
2076
+ case "delete":
2077
+ return "remove";
2078
+ case "insert":
2079
+ return "add";
2080
+ case "remove":
2081
+ return "remove";
2082
+ case "replace":
2083
+ return "replace";
2084
+ case "length":
2085
+ return "replace";
2086
+ default:
2087
+ return null;
2088
+ }
2089
+ }
2090
+ __name(mutationToPatchOp, "mutationToPatchOp");
2091
+ function diffToPatch(path2, before2, after2) {
2092
+ if (before2 === after2) return null;
2093
+ if (after2 === void 0) {
2094
+ return { op: "remove", path: path2, oldValue: before2 };
2095
+ }
2096
+ if (before2 === void 0) {
2097
+ return { op: "add", path: path2, value: after2 };
2098
+ }
2099
+ return { op: "replace", path: path2, value: after2, oldValue: before2 };
2100
+ }
2101
+ __name(diffToPatch, "diffToPatch");
2102
+ function canMerge(patch1, patch2) {
2103
+ return patch1.path === patch2.path && patch1.op === patch2.op;
2104
+ }
2105
+ __name(canMerge, "canMerge");
2106
+ function mergePatches(patch1, patch2) {
2107
+ const op = patch1.op === "remove" && patch2.op === "remove" ? "remove" : "replace";
2108
+ return {
2109
+ op,
2110
+ path: patch1.path,
2111
+ value: patch2.value ?? patch1.value,
2112
+ oldValue: patch1.oldValue
2113
+ };
2114
+ }
2115
+ __name(mergePatches, "mergePatches");
2116
+
2117
+ // core/mutation/transaction.ts
2118
+ init_esm_shims();
2119
+ init_internal();
2120
+ var TX_REGISTRY_KEY = "__memorio_transaction_registry__";
2121
+ var registry = globalThis[TX_REGISTRY_KEY] || /* @__PURE__ */ new Map();
2122
+ if (!globalThis[TX_REGISTRY_KEY]) {
2123
+ globalThis[TX_REGISTRY_KEY] = registry;
2124
+ }
2125
+ var TX_STACK_KEY = "__memorio_transaction_stack__";
2126
+ var txStack = globalThis[TX_STACK_KEY] || [];
2127
+ if (!globalThis[TX_STACK_KEY]) {
2128
+ globalThis[TX_STACK_KEY] = txStack;
2129
+ }
2130
+ function getActiveTxId() {
2131
+ return txStack.length > 0 ? txStack[txStack.length - 1] : null;
2132
+ }
2133
+ __name(getActiveTxId, "getActiveTxId");
2134
+ function setActiveTx(id) {
2135
+ if (id === null) {
2136
+ txStack.pop();
2137
+ } else {
2138
+ txStack.push(id);
2139
+ }
2140
+ }
2141
+ __name(setActiveTx, "setActiveTx");
2142
+ function beginTransaction(source, message2, metadata) {
2143
+ const id = generateTransactionId();
2144
+ const ctx = {
2145
+ id,
2146
+ startedAt: hlc.serialize(hlc.tick()),
2147
+ source,
2148
+ message: message2,
2149
+ metadata,
2150
+ mutations: [],
2151
+ active: true
2152
+ };
2153
+ registry.set(id, ctx);
2154
+ setActiveTx(id);
2155
+ return ctx;
2156
+ }
2157
+ __name(beginTransaction, "beginTransaction");
2158
+ function tagForTransaction() {
2159
+ const txId = getActiveTxId();
2160
+ if (!txId) return void 0;
2161
+ const ctx = registry.get(txId);
2162
+ if (ctx && ctx.active) {
2163
+ return txId;
2164
+ }
2165
+ return void 0;
2166
+ }
2167
+ __name(tagForTransaction, "tagForTransaction");
2168
+ function commitTransaction() {
2169
+ const txId = getActiveTxId();
2170
+ if (!txId) return null;
2171
+ const ctx = registry.get(txId);
2172
+ if (!ctx || !ctx.active) return null;
2173
+ ctx.active = false;
2174
+ ctx.committedAt = hlc.serialize(hlc.tick());
2175
+ const tx = {
2176
+ id: ctx.id,
2177
+ mutations: ctx.mutations,
2178
+ startedAt: ctx.startedAt,
2179
+ committedAt: ctx.committedAt,
2180
+ source: ctx.source,
2181
+ message: ctx.message,
2182
+ metadata: ctx.metadata
2183
+ };
2184
+ setActiveTx(null);
2185
+ return tx;
2186
+ }
2187
+ __name(commitTransaction, "commitTransaction");
2188
+ function _setPath(path2, value) {
2189
+ const parts = path2.replace(/^state\./, "").split(".");
2190
+ let current = globalThis.state;
2191
+ for (let i = 0; i < parts.length - 1; i++) {
2192
+ const part = parts[i];
2193
+ if (current[part] === void 0) {
2194
+ current[part] = {};
2195
+ }
2196
+ current = current[part];
2197
+ }
2198
+ current[parts[parts.length - 1]] = value;
2199
+ }
2200
+ __name(_setPath, "_setPath");
2201
+ function _deletePath(path2) {
2202
+ const parts = path2.replace(/^state\./, "").split(".");
2203
+ let current = globalThis.state;
2204
+ for (let i = 0; i < parts.length - 1; i++) {
2205
+ const part = parts[i];
2206
+ if (current[part] === void 0) return;
2207
+ current = current[part];
2208
+ }
2209
+ if (current.remove) {
2210
+ current.remove(parts[parts.length - 1]);
2211
+ } else {
2212
+ delete current[parts[parts.length - 1]];
2213
+ }
2214
+ }
2215
+ __name(_deletePath, "_deletePath");
2216
+ function _applyInverse(record) {
2217
+ const wasEnabled = internal_default.historyEnabled;
2218
+ const wasRecording = internal_default._recording;
2219
+ internal_default.historyEnabled = false;
2220
+ internal_default._recording = false;
2221
+ try {
2222
+ if (record.action === "set" || record.operation === "set") {
2223
+ if (record.previousValue === void 0) {
2224
+ _deletePath(record.path);
2225
+ } else {
2226
+ _setPath(record.path, record.previousValue);
2227
+ }
2228
+ } else if (record.action === "delete" || record.operation === "delete") {
2229
+ if (record.previousValue !== void 0) {
2230
+ _setPath(record.path, record.previousValue);
2231
+ }
2232
+ }
2233
+ } finally {
2234
+ internal_default.historyEnabled = wasEnabled;
2235
+ internal_default._recording = wasRecording;
2236
+ }
2237
+ }
2238
+ __name(_applyInverse, "_applyInverse");
2239
+ function abortTransaction() {
2240
+ const txId = getActiveTxId();
2241
+ if (!txId) return null;
2242
+ const ctx = registry.get(txId);
2243
+ if (!ctx || !ctx.active) return null;
2244
+ for (let i = ctx.mutations.length - 1; i >= 0; i--) {
2245
+ const undoStack = internal_default.undoStack;
2246
+ const idx = undoStack.findIndex((r) => r.id === ctx.mutations[i]);
2247
+ if (idx >= 0) {
2248
+ const record = undoStack[idx];
2249
+ internal_default.undoStack.splice(idx, 1);
2250
+ _applyInverse(record);
2251
+ }
2252
+ }
2253
+ ctx.active = false;
2254
+ ctx.committedAt = hlc.serialize(hlc.tick());
2255
+ const tx = {
2256
+ id: ctx.id,
2257
+ mutations: ctx.mutations,
2258
+ startedAt: ctx.startedAt,
2259
+ committedAt: ctx.committedAt,
2260
+ source: ctx.source,
2261
+ message: ctx.message,
2262
+ metadata: ctx.metadata
2263
+ };
2264
+ registry.delete(txId);
2265
+ setActiveTx(null);
2266
+ return tx;
2267
+ }
2268
+ __name(abortTransaction, "abortTransaction");
2269
+ function listTransactions() {
2270
+ const result = [];
2271
+ for (const ctx of registry.values()) {
2272
+ result.push({
2273
+ id: ctx.id,
2274
+ mutations: ctx.mutations,
2275
+ startedAt: ctx.startedAt,
2276
+ committedAt: ctx.committedAt,
2277
+ source: ctx.source,
2278
+ message: ctx.message,
2279
+ metadata: ctx.metadata
2280
+ });
2281
+ }
2282
+ return result;
2283
+ }
2284
+ __name(listTransactions, "listTransactions");
2285
+ function currentTransaction() {
2286
+ const txId = getActiveTxId();
2287
+ if (!txId) return null;
2288
+ const ctx = registry.get(txId);
2289
+ if (!ctx || !ctx.active) return null;
2290
+ return {
2291
+ id: ctx.id,
2292
+ mutations: ctx.mutations,
2293
+ startedAt: ctx.startedAt,
2294
+ source: ctx.source,
2295
+ message: ctx.message,
2296
+ metadata: ctx.metadata
2297
+ };
2298
+ }
2299
+ __name(currentTransaction, "currentTransaction");
2300
+ function registerMutationInTransaction(mutationId) {
2301
+ const txId = getActiveTxId();
2302
+ if (!txId) return;
2303
+ const ctx = registry.get(txId);
2304
+ if (ctx && ctx.active) {
2305
+ ctx.mutations.push(mutationId);
2306
+ }
2307
+ }
2308
+ __name(registerMutationInTransaction, "registerMutationInTransaction");
2309
+
2310
+ // core/mutation/engine.ts
2311
+ function currentTimestamp() {
2312
+ return hlc.serialize(hlc.tick());
2313
+ }
2314
+ __name(currentTimestamp, "currentTimestamp");
2315
+ function createMutation(path2, operation, before2, after2, options) {
2316
+ const now2 = hlc.tick();
2317
+ const mutation = {
2318
+ id: generateMutationId(),
2319
+ path: path2,
2320
+ operation,
2321
+ after: after2,
2322
+ before: before2,
2323
+ timestamp: now2.physical,
2324
+ hlc: hlc.serialize(now2),
2325
+ context: options?.context || internal_default.currentContext || void 0,
2326
+ source: options?.source,
2327
+ transactionId: options?.transactionId || (operation !== "length" ? tagForTransaction() : void 0),
2328
+ // Legacy fields for backward compatibility
2329
+ action: operation === "set" ? "set" : "delete",
2330
+ newValue: after2,
2331
+ previousValue: before2
2332
+ };
2333
+ if (mutation.transactionId) {
2334
+ registerMutationInTransaction(mutation.id);
2335
+ }
2336
+ return mutation;
2337
+ }
2338
+ __name(createMutation, "createMutation");
2339
+ function recordMutation(mutation) {
2340
+ if (!internal_default.historyEnabled) return;
2341
+ internal_default.recordMutation(mutation);
2342
+ }
2343
+ __name(recordMutation, "recordMutation");
2344
+ function toPatch(mutation) {
2345
+ return mutationToPatch(mutation);
2346
+ }
2347
+ __name(toPatch, "toPatch");
2348
+ function mutate(path2, value, options) {
2349
+ const normalizedPath = path2.startsWith("state.") ? path2 : "state." + path2;
2350
+ const keyPath = normalizedPath.replace(/^state\./, "");
2351
+ let current;
2352
+ try {
2353
+ const parts2 = keyPath.split(".");
2354
+ let obj = globalThis.state;
2355
+ for (const part of parts2) {
2356
+ obj = obj?.[part];
2357
+ }
2358
+ current = obj;
2359
+ } catch {
2360
+ current = void 0;
2361
+ }
2362
+ const operation = value === void 0 ? "delete" : "set";
2363
+ const mutation = createMutation(
2364
+ normalizedPath,
2365
+ operation,
2366
+ current,
2367
+ value === void 0 ? void 0 : value,
2368
+ options
2369
+ );
2370
+ const wasRecording = internal_default._recording;
2371
+ internal_default._recording = false;
2372
+ const parts = keyPath.split(".");
2373
+ let target = globalThis.state;
2374
+ for (let i = 0; i < parts.length - 1; i++) {
2375
+ if (target[parts[i]] === void 0) {
2376
+ target[parts[i]] = {};
2377
+ }
2378
+ target = target[parts[i]];
2379
+ }
2380
+ if (operation === "delete") {
2381
+ delete target[parts[parts.length - 1]];
2382
+ } else {
2383
+ target[parts[parts.length - 1]] = value;
2384
+ }
2385
+ internal_default._recording = wasRecording;
2386
+ recordMutation(mutation);
2387
+ return mutation;
2388
+ }
2389
+ __name(mutate, "mutate");
2390
+ function activeTransactionId() {
2391
+ return internal_default.currentTransactionId || null;
2392
+ }
2393
+ __name(activeTransactionId, "activeTransactionId");
2394
+
2395
+ // functions/state/index.ts
1890
2396
  var TARGET = /* @__PURE__ */ Symbol("memorio.target");
1891
2397
  var wrapperCache = /* @__PURE__ */ new WeakMap();
2398
+ var arrayRootDedup = /* @__PURE__ */ new Set();
1892
2399
  var deepRaw = /* @__PURE__ */ __name((val, seen = null) => {
1893
2400
  if (val === null || typeof val !== "object") return val;
2401
+ if (!seen) seen = /* @__PURE__ */ new WeakSet();
1894
2402
  if (val[TARGET] !== void 0) return deepRaw(val[TARGET], seen);
1895
2403
  if (seen) {
1896
2404
  if (seen.has(val)) return val;
@@ -1900,6 +2408,7 @@ var deepRaw = /* @__PURE__ */ __name((val, seen = null) => {
1900
2408
  if (ctor !== "Object" && ctor !== "Array") return val;
1901
2409
  const copy = Array.isArray(val) ? [] : {};
1902
2410
  for (const k of Reflect.ownKeys(val)) {
2411
+ if (!Object.prototype.propertyIsEnumerable.call(val, k)) continue;
1903
2412
  copy[k] = deepRaw(val[k], seen);
1904
2413
  }
1905
2414
  return copy;
@@ -1952,8 +2461,8 @@ var buildProxy = /* @__PURE__ */ __name((obj, callback, tree = []) => {
1952
2461
  if (prop === "removeAll") {
1953
2462
  return () => {
1954
2463
  try {
1955
- for (const key in target) {
1956
- if (typeof target[key] !== "function" && !["list", "remove", "removeAll", "lock", "unlock"].includes(key)) {
2464
+ for (const key of Reflect.ownKeys(target)) {
2465
+ if (typeof target[key] !== "function" && !["list", "remove", "removeAll", "lock", "unlock", "persist"].includes(key)) {
1957
2466
  delete target[key];
1958
2467
  }
1959
2468
  }
@@ -2027,6 +2536,16 @@ var buildProxy = /* @__PURE__ */ __name((obj, callback, tree = []) => {
2027
2536
  }
2028
2537
  );
2029
2538
  event("state." + path2);
2539
+ if (Array.isArray(target) && tree.length > 0) {
2540
+ const rootName = "state." + tree.join(".");
2541
+ if (!arrayRootDedup.has(rootName)) {
2542
+ arrayRootDedup.add(rootName);
2543
+ event(rootName);
2544
+ if (typeof globalThis.queueMicrotask === "function") {
2545
+ globalThis.queueMicrotask(() => arrayRootDedup.clear());
2546
+ }
2547
+ }
2548
+ }
2030
2549
  Reflect.set(target, key, rawValue);
2031
2550
  internal_default.bumpStateVersion();
2032
2551
  if (target[key] && typeof target[key] === "object") {
@@ -2083,6 +2602,17 @@ var buildProxy = /* @__PURE__ */ __name((obj, callback, tree = []) => {
2083
2602
  const path2 = objPath(prop, tree);
2084
2603
  const previousValue = Reflect.get(target, prop);
2085
2604
  callback({ action: "delete", path: path2, target, previousValue });
2605
+ event("state." + path2);
2606
+ if (Array.isArray(target) && tree.length > 0) {
2607
+ const rootName = "state." + tree.join(".");
2608
+ if (!arrayRootDedup.has(rootName)) {
2609
+ arrayRootDedup.add(rootName);
2610
+ event(rootName);
2611
+ if (typeof globalThis.queueMicrotask === "function") {
2612
+ globalThis.queueMicrotask(() => arrayRootDedup.clear());
2613
+ }
2614
+ }
2615
+ }
2086
2616
  return Reflect.deleteProperty(target, prop);
2087
2617
  } catch (error) {
2088
2618
  console.error("Error in deleteProperty trap:", error);
@@ -2104,28 +2634,87 @@ if (globalThis[STATE_INSTANCE_KEY]) {
2104
2634
  state2 = globalThis[STATE_INSTANCE_KEY];
2105
2635
  } else {
2106
2636
  state2 = buildProxy({}, (mutation) => {
2107
- if (internal_default.historyEnabled) {
2108
- internal_default.recordMutation({
2109
- path: mutation.path,
2110
- action: mutation.action,
2111
- newValue: mutation.newValue,
2112
- previousValue: mutation.previousValue,
2113
- timestamp: Date.now()
2114
- });
2637
+ if (internal_default.historyEnabled && internal_default._recording !== false) {
2638
+ const operation = mutation.action === "delete" ? "delete" : "set";
2639
+ const record = createMutation(
2640
+ mutation.path,
2641
+ operation,
2642
+ mutation.previousValue,
2643
+ mutation.newValue,
2644
+ {
2645
+ context: mutation.context,
2646
+ source: mutation.source
2647
+ }
2648
+ );
2649
+ internal_default.recordMutation(record);
2115
2650
  }
2116
2651
  });
2117
- state2.lock = () => {
2118
- internal_default.locked = true;
2119
- message_default("State is now locked. All modifications are blocked.");
2120
- };
2121
- state2.unlock = () => {
2122
- internal_default.locked = false;
2123
- message_default("State is now unlocked. Modifications are allowed.");
2124
- };
2125
- globalThis[STATE_INSTANCE_KEY] = state2;
2126
- }
2127
-
2128
- // index.ts
2652
+ const _rawTarget = state2[TARGET];
2653
+ try {
2654
+ Object.defineProperty(_rawTarget, "lock", {
2655
+ value: /* @__PURE__ */ __name(() => {
2656
+ internal_default.locked = true;
2657
+ message_default("State is now locked. All modifications are blocked.");
2658
+ }, "value"),
2659
+ writable: true,
2660
+ configurable: true,
2661
+ enumerable: false
2662
+ });
2663
+ Object.defineProperty(_rawTarget, "unlock", {
2664
+ value: /* @__PURE__ */ __name(() => {
2665
+ internal_default.locked = false;
2666
+ message_default("State is now unlocked. Modifications are allowed.");
2667
+ }, "value"),
2668
+ writable: true,
2669
+ configurable: true,
2670
+ enumerable: false
2671
+ });
2672
+ } catch (e) {
2673
+ if (DEV) console.warn("[memorio state] lock/unlock defineProperty failed:", e);
2674
+ }
2675
+ try {
2676
+ Object.defineProperty(_rawTarget, "persist", {
2677
+ value: /* @__PURE__ */ __name((path2) => {
2678
+ if (typeof path2 !== "string" || !path2.length) {
2679
+ if (DEV) console.warn('[memorio state] state.persist() requires a non-empty path string (e.g. "state.user")');
2680
+ return () => {
2681
+ };
2682
+ }
2683
+ const normalized = path2.startsWith("state.") ? path2 : "state." + path2;
2684
+ const key = normalized.replace(/^state\./, "");
2685
+ const segments = key.split(".");
2686
+ const initial = store.get(key);
2687
+ if (initial !== void 0 && initial !== null) {
2688
+ let acc = state2;
2689
+ for (let i = 0; i < segments.length - 1; i++) {
2690
+ const seg = segments[i];
2691
+ if (acc[seg] === void 0 || acc[seg] === null) acc[seg] = {};
2692
+ acc = acc[seg];
2693
+ }
2694
+ if (acc) acc[segments[segments.length - 1]] = deepRaw(initial);
2695
+ }
2696
+ const handler = /* @__PURE__ */ __name(() => {
2697
+ let current = state2;
2698
+ for (const seg of segments) {
2699
+ current = current === void 0 || current === null ? void 0 : current[seg];
2700
+ }
2701
+ store.set(key, deepRaw(current));
2702
+ }, "handler");
2703
+ const off = dispatch.listen(normalized, handler);
2704
+ return typeof off === "function" ? off : () => {
2705
+ };
2706
+ }, "value"),
2707
+ writable: true,
2708
+ configurable: true,
2709
+ enumerable: false
2710
+ });
2711
+ } catch (e) {
2712
+ if (DEV) console.warn("[memorio state] persist defineProperty failed:", e);
2713
+ }
2714
+ globalThis[STATE_INSTANCE_KEY] = state2;
2715
+ }
2716
+
2717
+ // index.ts
2129
2718
  init_store();
2130
2719
 
2131
2720
  // functions/session/index.ts
@@ -2473,12 +3062,17 @@ var observerFunction = /* @__PURE__ */ __name((s, cb = null, option = true) => {
2473
3062
  const callbacks = Array.isArray(cb) ? cb : [cb];
2474
3063
  const obs = globalThis.observer;
2475
3064
  if (obs?.list?.[resolvedPath]) dispatch.remove(resolvedPath);
3065
+ const unsubs = [];
2476
3066
  callbacks.forEach((callback) => {
2477
3067
  if (typeof callback === "function") {
2478
- dispatch.listen(resolvedPath, callback, option);
3068
+ const off = dispatch.listen(resolvedPath, callback, option);
3069
+ if (typeof off === "function") unsubs.push(off);
2479
3070
  }
2480
3071
  });
2481
- return;
3072
+ if (unsubs.length === 1) return unsubs[0];
3073
+ if (unsubs.length > 1) return () => unsubs.forEach((u) => u());
3074
+ return () => {
3075
+ };
2482
3076
  }
2483
3077
  }, "observerFunction");
2484
3078
  var observer = observerFunction;
@@ -2541,7 +3135,6 @@ Object.defineProperties(
2541
3135
  init_esm_shims();
2542
3136
  init_message();
2543
3137
  init_internal();
2544
- init_env();
2545
3138
  var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
2546
3139
  if (!deps || typeof func !== "function") {
2547
3140
  return () => {
@@ -2602,20 +3195,6 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
2602
3195
  };
2603
3196
  }
2604
3197
  }), "useObserver");
2605
- if (DEV && !("useObserver" in globalThis)) {
2606
- if (!globalThis.useObserver) globalThis.useObserver = null;
2607
- Object.defineProperty(
2608
- globalThis,
2609
- "useObserver",
2610
- {
2611
- value: useObserver,
2612
- writable: true,
2613
- enumerable: false,
2614
- configurable: true
2615
- }
2616
- );
2617
- Object.freeze(globalThis.useObserver);
2618
- }
2619
3198
 
2620
3199
  // index.ts
2621
3200
  init_message();
@@ -2699,7 +3278,7 @@ var clearHistory = /* @__PURE__ */ __name(() => {
2699
3278
  logHistory.length = 0;
2700
3279
  }, "clearHistory");
2701
3280
  var getStats = /* @__PURE__ */ __name(() => {
2702
- const stats2 = {
3281
+ const stats = {
2703
3282
  total: logHistory.length,
2704
3283
  state: 0,
2705
3284
  store: 0,
@@ -2715,11 +3294,11 @@ var getStats = /* @__PURE__ */ __name(() => {
2715
3294
  if (entry) {
2716
3295
  const module = entry.module;
2717
3296
  const action = entry.action;
2718
- if (module && typeof stats2[module] === "number") stats2[module]++;
2719
- if (action && typeof stats2[action] === "number") stats2[action]++;
3297
+ if (module && typeof stats[module] === "number") stats[module]++;
3298
+ if (action && typeof stats[action] === "number") stats[action]++;
2720
3299
  }
2721
3300
  }
2722
- return stats2;
3301
+ return stats;
2723
3302
  }, "getStats");
2724
3303
  var exportLogs = /* @__PURE__ */ __name(() => {
2725
3304
  return JSON.stringify(logHistory, null, 2);
@@ -2736,378 +3315,6 @@ var logger = {
2736
3315
  exportLogs
2737
3316
  };
2738
3317
 
2739
- // functions/devtools/index.ts
2740
- init_esm_shims();
2741
- init_internal();
2742
- init_env();
2743
- var _state = globalThis.__memorio_state_instance__;
2744
- var _store = globalThis.__memorio_store_instance__;
2745
- var _session = globalThis.__memorio_session_instance__;
2746
- var _cache = globalThis.__memorio_cache_instance__;
2747
- function isDebugEnabled2() {
2748
- return DEV && internal_default.debug === true;
2749
- }
2750
- __name(isDebugEnabled2, "isDebugEnabled");
2751
- function extractStoreData() {
2752
- if (!_store) return {};
2753
- const result = {};
2754
- const store2 = _store;
2755
- if (typeof store2.list === "function") {
2756
- try {
2757
- return store2.list();
2758
- } catch {
2759
- }
2760
- }
2761
- if (typeof store2.get === "function") {
2762
- for (const key of Object.keys(store2)) {
2763
- if (!["get", "set", "remove", "delete", "removeAll", "clearAll", "size", "isPersistent", "list"].includes(key)) {
2764
- try {
2765
- const val = store2.get(key);
2766
- if (val !== null && val !== void 0) {
2767
- result[key] = val;
2768
- }
2769
- } catch {
2770
- }
2771
- }
2772
- }
2773
- }
2774
- return result;
2775
- }
2776
- __name(extractStoreData, "extractStoreData");
2777
- function extractSessionData() {
2778
- if (!_session) return {};
2779
- const result = {};
2780
- const session2 = _session;
2781
- if (typeof session2.list === "function") {
2782
- try {
2783
- return session2.list();
2784
- } catch {
2785
- }
2786
- }
2787
- if (typeof session2.get === "function") {
2788
- for (const key of Object.keys(session2)) {
2789
- if (!["get", "set", "remove", "delete", "removeAll", "clearAll", "size", "isPersistent", "list"].includes(key)) {
2790
- try {
2791
- const val = session2.get(key);
2792
- if (val !== null && val !== void 0) {
2793
- result[key] = val;
2794
- }
2795
- } catch {
2796
- }
2797
- }
2798
- }
2799
- }
2800
- return result;
2801
- }
2802
- __name(extractSessionData, "extractSessionData");
2803
- var inspect = /* @__PURE__ */ __name(() => {
2804
- if (!isDebugEnabled2()) return;
2805
- if (_state) {
2806
- const stateList = _state.list;
2807
- let stateData;
2808
- if (typeof stateList === "function") {
2809
- stateData = stateList();
2810
- } else if (typeof stateList === "object" && stateList !== null) {
2811
- stateData = stateList;
2812
- } else {
2813
- stateData = _state;
2814
- }
2815
- console.table(stateData);
2816
- }
2817
- if (_store) {
2818
- console.table(extractStoreData());
2819
- }
2820
- if (_session) {
2821
- console.table(extractSessionData());
2822
- }
2823
- if (_cache) {
2824
- const cacheList = _cache.list;
2825
- let cacheData2;
2826
- if (typeof cacheList === "function") {
2827
- cacheData2 = cacheList();
2828
- } else if (typeof cacheList === "object" && cacheList !== null) {
2829
- cacheData2 = cacheList;
2830
- } else {
2831
- cacheData2 = _cache;
2832
- }
2833
- console.table(cacheData2);
2834
- }
2835
- }, "inspect");
2836
- var stats = /* @__PURE__ */ __name(() => {
2837
- const getKeys = /* @__PURE__ */ __name((obj) => {
2838
- if (!obj) return 0;
2839
- if (typeof obj.list === "function") {
2840
- try {
2841
- const list = obj.list();
2842
- return Object.keys(list).length;
2843
- } catch {
2844
- }
2845
- }
2846
- return Object.keys(obj).length;
2847
- }, "getKeys");
2848
- return {
2849
- stateKeys: getKeys(_state),
2850
- storeKeys: getKeys(_store),
2851
- sessionKeys: getKeys(_session),
2852
- cacheKeys: getKeys(_cache),
2853
- idbDatabases: 0,
2854
- sqliteDbCount: 0,
2855
- lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
2856
- };
2857
- }, "stats");
2858
- var clear = /* @__PURE__ */ __name((moduleName) => {
2859
- const targets = { state: _state, store: _store, session: _session, cache: _cache };
2860
- const target = targets[moduleName];
2861
- if (target && typeof target.clear === "function") {
2862
- target.clear();
2863
- } else if (target && typeof target.removeAll === "function") {
2864
- target.removeAll();
2865
- } else {
2866
- console.debug(`Module ${moduleName} not found or does not support clear()/removeAll()`);
2867
- }
2868
- }, "clear");
2869
- var clearAll = /* @__PURE__ */ __name(() => {
2870
- clear("state");
2871
- clear("store");
2872
- clear("session");
2873
- clear("cache");
2874
- }, "clearAll");
2875
- var exportData = /* @__PURE__ */ __name(() => {
2876
- const getStateData = /* @__PURE__ */ __name(() => {
2877
- if (!_state) return void 0;
2878
- try {
2879
- if (typeof _state.list === "function") {
2880
- return _state.list();
2881
- }
2882
- return _state;
2883
- } catch {
2884
- return void 0;
2885
- }
2886
- }, "getStateData");
2887
- const getStoreData = /* @__PURE__ */ __name(() => {
2888
- return extractStoreData();
2889
- }, "getStoreData");
2890
- const getSessionData = /* @__PURE__ */ __name(() => {
2891
- return extractSessionData();
2892
- }, "getSessionData");
2893
- const getCacheData = /* @__PURE__ */ __name(() => {
2894
- if (!_cache) return void 0;
2895
- try {
2896
- if (typeof _cache.list === "function") {
2897
- return _cache.list();
2898
- }
2899
- return _cache;
2900
- } catch {
2901
- return void 0;
2902
- }
2903
- }, "getCacheData");
2904
- const data = {
2905
- state: getStateData(),
2906
- store: getStoreData(),
2907
- session: getSessionData(),
2908
- cache: getCacheData(),
2909
- exportedAt: (/* @__PURE__ */ new Date()).toISOString()
2910
- };
2911
- return JSON.stringify(data, null, 2);
2912
- }, "exportData");
2913
- var importData = /* @__PURE__ */ __name((jsonString) => {
2914
- try {
2915
- const data = JSON.parse(jsonString);
2916
- if (data.state) {
2917
- Object.entries(data.state).forEach(([key, value]) => {
2918
- if (_state && key !== "list" && key !== "remove" && key !== "removeAll") {
2919
- ;
2920
- _state[key] = value;
2921
- }
2922
- });
2923
- }
2924
- if (data.store && _store && typeof _store.set === "function") {
2925
- Object.entries(data.store).forEach(([key, value]) => {
2926
- ;
2927
- _store.set(key, value);
2928
- });
2929
- }
2930
- if (data.session && _session && typeof _session.set === "function") {
2931
- Object.entries(data.session).forEach(([key, value]) => {
2932
- ;
2933
- _session.set(key, value);
2934
- });
2935
- }
2936
- if (data.cache && _cache) {
2937
- Object.entries(data.cache).forEach(([key, value]) => {
2938
- if (_cache && key !== "get" && key !== "set" && key !== "remove" && key !== "clear") {
2939
- ;
2940
- _cache[key] = value;
2941
- }
2942
- });
2943
- }
2944
- } catch (error) {
2945
- console.debug("Import failed:", error);
2946
- }
2947
- }, "importData");
2948
- var watch = /* @__PURE__ */ __name((moduleName, path2) => {
2949
- const targets = { state: _state, store: _store, session: _session, cache: _cache };
2950
- const target = targets[moduleName];
2951
- if (!target) {
2952
- console.debug(`Module ${moduleName} not found`);
2953
- return;
2954
- }
2955
- const initialValue = target[path2];
2956
- console.debug(`Watching ${moduleName}.${path2} (initial: ${JSON.stringify(initialValue)})`);
2957
- if (moduleName === "state" && globalThis.memorio?.dispatch) {
2958
- const handler = /* @__PURE__ */ __name((e) => {
2959
- const detail = e.detail;
2960
- if (detail?.name?.includes(path2)) {
2961
- console.debug(`Change: ${moduleName}.${path2} =`, e.detail.value);
2962
- }
2963
- }, "handler");
2964
- target.addEventListener?.("memorio-change", handler);
2965
- }
2966
- }, "watch");
2967
- var help = /* @__PURE__ */ __name(() => {
2968
- console.debug(`
2969
- Memorio DevTools Help
2970
-
2971
- Available commands:
2972
- memorio.devtools.inspect() - Inspect all state modules
2973
- memorio.devtools.stats() - Show statistics
2974
- memorio.devtools.clear('module') - Clear specific module
2975
- memorio.devtools.clearAll() - Clear all modules
2976
- memorio.devtools.exportData() - Export all data as JSON
2977
- memorio.devtools.importData(json) - Import data from JSON
2978
- memorio.devtools.watch(module, path) - Watch a path for changes
2979
- memorio.devtools.help() - Show this help
2980
-
2981
- Shortcuts (dev only):
2982
- state - global state proxy
2983
- store - localStorage wrapper
2984
- session - sessionStorage wrapper
2985
- cache - in-memory cache
2986
- `);
2987
- }, "help");
2988
- var devtools = {
2989
- inspect,
2990
- stats,
2991
- clear,
2992
- clearAll,
2993
- exportData,
2994
- importData,
2995
- watch,
2996
- help
2997
- };
2998
-
2999
- // core/hlc.ts
3000
- init_esm_shims();
3001
- var NODE_ID_KEY = "__memorio_hlc_node";
3002
- function getNodeId() {
3003
- if (typeof globalThis === "undefined") return "node";
3004
- try {
3005
- if (typeof sessionStorage !== "undefined" && sessionStorage) {
3006
- let id = sessionStorage.getItem(NODE_ID_KEY);
3007
- if (!id) {
3008
- id = generateNodeId();
3009
- sessionStorage.setItem(NODE_ID_KEY, id);
3010
- }
3011
- return id;
3012
- }
3013
- } catch {
3014
- }
3015
- if (!globalThis.__memorioHlcNodeId) {
3016
- globalThis.__memorioHlcNodeId = generateNodeId();
3017
- }
3018
- return globalThis.__memorioHlcNodeId;
3019
- }
3020
- __name(getNodeId, "getNodeId");
3021
- function generateNodeId() {
3022
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
3023
- return crypto.randomUUID().slice(0, 8);
3024
- }
3025
- return Math.random().toString(36).slice(2, 10);
3026
- }
3027
- __name(generateNodeId, "generateNodeId");
3028
- var HLC_KEY = "__memorio_hlc_local";
3029
- var local = globalThis[HLC_KEY] || {
3030
- physical: 0,
3031
- logical: 0,
3032
- node: getNodeId()
3033
- };
3034
- if (!globalThis[HLC_KEY]) {
3035
- globalThis[HLC_KEY] = local;
3036
- }
3037
- function tick(_incoming) {
3038
- const now2 = Date.now();
3039
- const base = local.physical;
3040
- let physical;
3041
- let logical;
3042
- if (now2 > base) {
3043
- physical = now2;
3044
- logical = 0;
3045
- } else if (now2 < base) {
3046
- physical = base;
3047
- logical = local.logical + 1;
3048
- } else {
3049
- physical = base;
3050
- logical = local.logical + 1;
3051
- }
3052
- local.physical = physical;
3053
- local.logical = logical;
3054
- return { physical, logical, node: local.node };
3055
- }
3056
- __name(tick, "tick");
3057
- function receive(remote) {
3058
- const now2 = Date.now();
3059
- if (remote.physical > local.physical) {
3060
- local.physical = remote.physical > now2 ? remote.physical : now2;
3061
- local.logical = 1;
3062
- } else if (remote.physical === local.physical) {
3063
- local.logical = Math.max(local.logical, remote.logical) + 1;
3064
- }
3065
- local.node = getNodeId();
3066
- return { ...local };
3067
- }
3068
- __name(receive, "receive");
3069
- function compare(a, b) {
3070
- if (a.physical !== b.physical) {
3071
- return a.physical < b.physical ? -1 : 1;
3072
- }
3073
- if (a.logical !== b.logical) {
3074
- return a.logical < b.logical ? -1 : 1;
3075
- }
3076
- if (a.node !== b.node) {
3077
- return a.node < b.node ? -1 : 1;
3078
- }
3079
- return 0;
3080
- }
3081
- __name(compare, "compare");
3082
- function happenedBefore(a, b) {
3083
- return compare(a, b) < 0;
3084
- }
3085
- __name(happenedBefore, "happenedBefore");
3086
- function serialize(hlc2) {
3087
- return `hlc:${hlc2.physical}:${hlc2.logical}:${hlc2.node}`;
3088
- }
3089
- __name(serialize, "serialize");
3090
- function parse(serialized) {
3091
- if (!serialized.startsWith("hlc:")) return null;
3092
- const parts = serialized.split(":");
3093
- if (parts.length !== 4) return null;
3094
- const physical = parseInt(parts[1], 10);
3095
- const logical = parseInt(parts[2], 10);
3096
- const node = parts[3];
3097
- if (isNaN(physical) || isNaN(logical)) return null;
3098
- return { physical, logical, node };
3099
- }
3100
- __name(parse, "parse");
3101
- var hlc = {
3102
- tick,
3103
- receive,
3104
- compare,
3105
- happenedBefore,
3106
- serialize,
3107
- parse,
3108
- getNodeId
3109
- };
3110
-
3111
3318
  // core/fractional.ts
3112
3319
  init_esm_shims();
3113
3320
  function generateBetween(left, right, minChars = 2) {
@@ -3300,7 +3507,7 @@ init_internal();
3300
3507
 
3301
3508
  // package.json
3302
3509
  var package_default = {
3303
- version: "4.9.31"};
3510
+ version: "5.0.0"};
3304
3511
 
3305
3512
  // core/global.ts
3306
3513
  init_env();
@@ -3385,7 +3592,7 @@ var undo = /* @__PURE__ */ __name(() => {
3385
3592
  }
3386
3593
  const record = internal_default.popUndo();
3387
3594
  if (!record) return void 0;
3388
- _applyInverse(record);
3595
+ _applyInverse2(record);
3389
3596
  message_default(`[memorio history] Undid: ${record.action} ${record.path}`);
3390
3597
  return record;
3391
3598
  }, "undo");
@@ -3400,41 +3607,41 @@ var redo = /* @__PURE__ */ __name(() => {
3400
3607
  message_default(`[memorio history] Redid: ${record.action} ${record.path}`);
3401
3608
  return record;
3402
3609
  }, "redo");
3403
- function _applyInverse(record) {
3610
+ function _applyInverse2(record) {
3404
3611
  const wasEnabled = internal_default.historyEnabled;
3405
3612
  internal_default.historyEnabled = false;
3406
3613
  try {
3407
3614
  if (record.action === "set") {
3408
3615
  if (record.previousValue === void 0) {
3409
- _deletePath(record.path);
3616
+ _deletePath2(record.path);
3410
3617
  } else {
3411
- _setPath(record.path, record.previousValue);
3618
+ _setPath2(record.path, record.previousValue);
3412
3619
  }
3413
3620
  } else if (record.action === "delete") {
3414
3621
  if (record.previousValue !== void 0) {
3415
- _setPath(record.path, record.previousValue);
3622
+ _setPath2(record.path, record.previousValue);
3416
3623
  }
3417
3624
  }
3418
3625
  } finally {
3419
3626
  internal_default.historyEnabled = wasEnabled;
3420
3627
  }
3421
3628
  }
3422
- __name(_applyInverse, "_applyInverse");
3629
+ __name(_applyInverse2, "_applyInverse");
3423
3630
  function _applyForward(record) {
3424
3631
  const wasEnabled = internal_default.historyEnabled;
3425
3632
  internal_default.historyEnabled = false;
3426
3633
  try {
3427
3634
  if (record.action === "set") {
3428
- _setPath(record.path, record.newValue);
3635
+ _setPath2(record.path, record.newValue);
3429
3636
  } else if (record.action === "delete") {
3430
- _deletePath(record.path);
3637
+ _deletePath2(record.path);
3431
3638
  }
3432
3639
  } finally {
3433
3640
  internal_default.historyEnabled = wasEnabled;
3434
3641
  }
3435
3642
  }
3436
3643
  __name(_applyForward, "_applyForward");
3437
- function _setPath(path2, value) {
3644
+ function _setPath2(path2, value) {
3438
3645
  const parts = path2.split(".");
3439
3646
  let current = state2;
3440
3647
  for (let i = 0; i < parts.length - 1; i++) {
@@ -3446,8 +3653,8 @@ function _setPath(path2, value) {
3446
3653
  }
3447
3654
  current[parts[parts.length - 1]] = value;
3448
3655
  }
3449
- __name(_setPath, "_setPath");
3450
- function _deletePath(path2) {
3656
+ __name(_setPath2, "_setPath");
3657
+ function _deletePath2(path2) {
3451
3658
  const parts = path2.split(".");
3452
3659
  if (parts.length === 1) {
3453
3660
  state2.remove(parts[0]);
@@ -3461,7 +3668,7 @@ function _deletePath(path2) {
3461
3668
  }
3462
3669
  delete current[parts[parts.length - 1]];
3463
3670
  }
3464
- __name(_deletePath, "_deletePath");
3671
+ __name(_deletePath2, "_deletePath");
3465
3672
  var rollback = /* @__PURE__ */ __name((snap) => {
3466
3673
  state2.removeAll();
3467
3674
  for (const key of Object.keys(snap)) {
@@ -4169,84 +4376,6 @@ var memory = {
4169
4376
  }
4170
4377
  };
4171
4378
 
4172
- // functions/inspect/index.ts
4173
- init_esm_shims();
4174
- init_env();
4175
- var stateKeys = /* @__PURE__ */ __name(() => {
4176
- const raw = deepRaw(state2);
4177
- return Object.keys(raw).filter(
4178
- (k) => !["list", "remove", "removeAll", "lock", "unlock"].includes(k)
4179
- );
4180
- }, "stateKeys");
4181
- var pathExists = /* @__PURE__ */ __name((path2) => {
4182
- if (!path2 || typeof path2 !== "string") return false;
4183
- const parts = path2.replace(/^state\./, "").split(".");
4184
- let current = state2;
4185
- for (const part of parts) {
4186
- if (current === null || current === void 0) {
4187
- return false;
4188
- }
4189
- current = current[part];
4190
- }
4191
- return current !== void 0;
4192
- }, "pathExists");
4193
- var stateType = /* @__PURE__ */ __name((path2) => {
4194
- const [exists, value] = _getValue(path2);
4195
- if (!exists || value === void 0) return "undefined";
4196
- return Array.isArray(value) ? "array" : typeof value;
4197
- }, "stateType");
4198
- var stateGet = /* @__PURE__ */ __name((path2) => {
4199
- const [exists, value] = _getValue(path2);
4200
- if (!exists || value === void 0) return void 0;
4201
- return _clone2(value);
4202
- }, "stateGet");
4203
- var stateSchema = /* @__PURE__ */ __name(() => {
4204
- const result = [];
4205
- const _walk = /* @__PURE__ */ __name((obj, prefix) => {
4206
- if (obj === null || typeof obj !== "object" || Array.isArray(obj)) {
4207
- return;
4208
- }
4209
- const keys = Object.keys(obj).filter(
4210
- (k) => !["list", "remove", "removeAll", "lock", "unlock"].includes(k)
4211
- );
4212
- for (const key of keys) {
4213
- const newPath = prefix ? `${prefix}.${key}` : key;
4214
- const value = obj[key];
4215
- const defined = value !== void 0;
4216
- const type = defined ? Array.isArray(value) ? "array" : typeof value : "undefined";
4217
- result.push({ path: newPath, type, defined });
4218
- if (defined && typeof value === "object" && !Array.isArray(value) && value.constructor?.name === "Object") {
4219
- _walk(value, newPath);
4220
- }
4221
- }
4222
- }, "_walk");
4223
- _walk(deepRaw(state2), "");
4224
- return result;
4225
- }, "stateSchema");
4226
- function _getValue(path2) {
4227
- if (!path2 || typeof path2 !== "string") return [false, void 0];
4228
- const parts = path2.replace(/^state\./, "").split(".");
4229
- let current = state2;
4230
- for (const part of parts) {
4231
- if (current === null || current === void 0) {
4232
- return [false, void 0];
4233
- }
4234
- current = current[part];
4235
- }
4236
- return [current !== void 0, current];
4237
- }
4238
- __name(_getValue, "_getValue");
4239
- function _clone2(value) {
4240
- if (value === null || typeof value !== "object") return value;
4241
- try {
4242
- return deepRaw(value, /* @__PURE__ */ new WeakSet());
4243
- } catch (err) {
4244
- if (DEV) console.warn("[memorio inspect] deep clone failed:", err);
4245
- return value;
4246
- }
4247
- }
4248
- __name(_clone2, "_clone");
4249
-
4250
4379
  // core/global.ts
4251
4380
  if (!("memorio" in globalThis)) {
4252
4381
  Object.defineProperty(
@@ -4280,6 +4409,26 @@ if (!("memorio" in globalThis)) {
4280
4409
  }
4281
4410
  );
4282
4411
  }
4412
+ if (typeof globalThis.addEventListener !== "function") {
4413
+ const listeners = {};
4414
+ globalThis.addEventListener = (name, cb) => {
4415
+ (listeners[name] = listeners[name] ?? []).push(cb);
4416
+ };
4417
+ globalThis.removeEventListener = (name, cb) => {
4418
+ const arr = listeners[name];
4419
+ if (arr) {
4420
+ const idx = arr.indexOf(cb);
4421
+ if (idx > -1) arr.splice(idx, 1);
4422
+ }
4423
+ };
4424
+ globalThis.dispatchEvent = (e) => {
4425
+ const type = (e && typeof e === "object" ? e.type : null) || String(e);
4426
+ const arr = listeners[type];
4427
+ if (arr) {
4428
+ arr.slice().forEach((cb) => cb(e));
4429
+ }
4430
+ };
4431
+ }
4283
4432
  if (typeof globalThis.addEventListener === "function") {
4284
4433
  dispatch.listen("memorio:memory:cleanup", async () => memory.forgetExpired?.());
4285
4434
  }
@@ -4321,10 +4470,17 @@ if (!("memorio" in globalThis)) {
4321
4470
  memorio.enableHistory = enableHistory;
4322
4471
  memorio.clearHistory = clearHistory2;
4323
4472
  memorio.clearRedo = clearRedo;
4473
+ memorio.mutate = mutate;
4474
+ memorio.createMutation = createMutation;
4475
+ memorio.recordMutation = recordMutation;
4476
+ memorio.toPatch = toPatch;
4477
+ memorio.transaction = beginTransaction;
4478
+ memorio.commitTransaction = commitTransaction;
4479
+ memorio.abortTransaction = abortTransaction;
4480
+ memorio.currentTransaction = currentTransaction;
4324
4481
  Object.defineProperty(memorio, "dispatch", { value: dispatch, writable: true, enumerable: false, configurable: true });
4325
- const isDev = DEV;
4326
4482
  memorio.env = {
4327
- isDev,
4483
+ isDev: DEV,
4328
4484
  isProd: PROD
4329
4485
  };
4330
4486
  memorio.global = function() {
@@ -4343,146 +4499,28 @@ if (!("memorio" in globalThis)) {
4343
4499
  Object.defineProperty(globalThis, key, {
4344
4500
  value: globalDefinitions[key],
4345
4501
  writable: true,
4346
- enumerable: false,
4347
- configurable: true
4502
+ configurable: true,
4503
+ enumerable: false
4348
4504
  });
4349
4505
  }
4350
4506
  }
4507
+ if (typeof globalThis.useObserver === "function") {
4508
+ Object.freeze(globalThis.useObserver);
4509
+ }
4351
4510
  };
4352
- if (isDev) {
4353
- memorio.global();
4354
- }
4355
- if (DEV) {
4356
- Object.defineProperty(
4357
- memorio,
4358
- "debug",
4359
- {
4360
- get: /* @__PURE__ */ __name(() => internal_default.debug, "get"),
4361
- set: /* @__PURE__ */ __name((v) => {
4362
- internal_default.debug = v;
4363
- }, "set"),
4364
- enumerable: false
4365
- }
4366
- );
4367
- const caps = getCapabilities();
4368
- Object.defineProperty(memorio, "_platform", { writable: false, enumerable: false, value: caps.platform });
4369
- Object.defineProperty(memorio, "_capabilities", { writable: false, enumerable: false, value: caps });
4370
- Object.defineProperty(memorio, "_sessionId", { writable: false, enumerable: false, value: generateSessionId() });
4371
- memorio.logger = logger;
4372
- if (!("$state" in globalThis)) Object.defineProperty(globalThis, "$state", { get: /* @__PURE__ */ __name(() => globalThis.state, "get"), configurable: true });
4373
- if (!("$store" in globalThis)) Object.defineProperty(globalThis, "$store", { get: /* @__PURE__ */ __name(() => globalThis.store, "get"), configurable: true });
4374
- if (!("$session" in globalThis)) Object.defineProperty(globalThis, "$session", { get: /* @__PURE__ */ __name(() => globalThis.session, "get"), configurable: true });
4375
- if (!("$cache" in globalThis)) Object.defineProperty(globalThis, "$cache", { get: /* @__PURE__ */ __name(() => globalThis.cache, "get"), configurable: true });
4376
- memorio.devtools = devtools;
4377
- memorio.inspect = stateKeys;
4378
- memorio.stateKeys = stateKeys;
4379
- memorio.pathExists = pathExists;
4380
- memorio.stateType = stateType;
4381
- memorio.stateGet = stateGet;
4382
- memorio.stateSchema = stateSchema;
4383
- memorio.help = function() {
4384
- console.debug(`
4385
- \u{1F9E0} Memorio ${package_default.version} - Help
4386
-
4387
- Core Modules (runtime):
4388
- state - Reactive state management (DEV global)
4389
- store - Persistent storage (localStorage/Map)
4390
- session - Session storage (sessionStorage/Map)
4391
- cache - In-memory cache
4392
- idb - IndexedDB (browser only)
4393
- sqlite - SQLite in browser (sql.js, optional)
4394
-
4395
- Platform Detection:
4396
- memorio.isBrowser() - Browser environment
4397
- memorio.isNode() - Node.js environment
4398
- memorio.isDeno() - Deno environment
4399
- memorio.isEdge() - Edge/Worker environment
4400
- memorio.getCapabilities() - Full capabilities object
4401
-
4402
- Context Management:
4403
- memorio.isolate(name) - Create isolated context
4404
- memorio.listContexts() - List all contexts
4405
- memorio.deleteContext(id) - Delete a context
4406
-
4407
- Schema Validation (runtime):
4408
- memorio.registerSchema() - Register a validator for a state path
4409
- memorio.validate() - Manually validate a value
4410
- memorio.unregisterSchema() - Remove a registered schema
4411
- memorio.listSchemas() - List all registered schema paths
4412
- memorio.typed<T>() - Type-safe view of global state (compile-time only)
4413
-
4414
- History & Time Travel (runtime):
4415
- memorio.snapshot() - Capture a deep snapshot of state
4416
- memorio.diff(snap) - Diff snapshot against current state
4417
- memorio.undo() / redo() - Undo / redo the last mutation
4418
- memorio.canUndo() / canRedo() - Check availability
4419
- memorio.rollback(snap) - Restore state from a snapshot
4420
- memorio.trace() - List all recorded mutations
4421
- memorio.enableHistory() - Enable/disable mutation tracking
4422
- memorio.clearHistory() - Clear undo/redo stacks and trace log
4423
-
4424
- DevTools (development-only):
4425
- memorio.devtools.inspect() - Inspect all modules
4426
- memorio.devtools.stats() - Show statistics
4427
- memorio.devtools.watch() - Watch a path
4428
- memorio.devtools.exportData() - Export as JSON
4429
- memorio.devtools.importData() - Import from JSON
4430
- memorio.devtools.clear() - Clear specific module
4431
- memorio.devtools.clearAll() - Clear all modules
4432
-
4433
- Introspection (development-only):
4434
- memorio.stateKeys() - List top-level state keys
4435
- memorio.pathExists(path) - Check if a state path exists
4436
- memorio.stateType(path) - Get runtime type of a state value
4437
- memorio.stateGet(path) - Get a deep-cloned value at a path
4438
- memorio.stateSchema() - Get a schema report of all state paths
4439
-
4440
- Debug:
4441
- memorio.debug = true - Enable debug output (DEV only)
4442
-
4443
- Memory System (runtime):
4444
- memorio.memory.remember(key, value, opts) - Store a memory with type, confidence, scope, TTL, tags
4445
- memorio.memory.recall(key, opts) - Retrieve a memory with filtering
4446
- memorio.memory.update(key, value, opts) - Update an existing memory
4447
- memorio.memory.forget(key) - Delete a specific memory
4448
- memorio.memory.context(opts) - Get ranked relevant memories (semantic context for AI)
4449
- memorio.memory.stats() - Memory usage statistics
4450
- memorio.memory.forgetExpired() - Remove all expired entries
4451
- memorio.memory.clear() - Wipe all memories
4452
- memorio.memory.configure({ sync }) - Optional cloud-sync provider + namespace
4453
- memorio.memory.journal.pending() - Local op journal (SQLite/store)
4454
-
4455
- Scopes:
4456
- hot - In-memory reactive state (volatile, fastest)
4457
- session - sessionStorage (persists across page reloads, cleared on tab close)
4458
- local - localStorage (persistent, survives browser restart)
4459
- durable - IndexedDB (large datasets, async)
4460
- sql - SQLite / sql.js (browser, optional, full SQL)
4461
-
4462
- TTL options:
4463
- ttl: number (milliseconds) or null (never expires)
4464
-
4465
- Memory types:
4466
- fact, preference, decision, task, context
4467
-
4468
- Console shortcuts (DEV only):
4469
- state, store, session, cache, idb, sqlite - direct access to modules
4470
- $state, $store, $session, $cache - aliases for the above
4471
- `);
4472
- };
4473
- }
4474
4511
  }
4475
4512
 
4476
4513
  // index.ts
4477
- var devtools2 = DEV ? devtools : void 0;
4514
+ var transaction = beginTransaction;
4515
+ var devtools = void 0;
4478
4516
  var memorio2 = globalThis.memorio;
4479
4517
  var events = globalThis.events;
4480
4518
  var isolate = /* @__PURE__ */ __name((name) => createContext(name), "isolate");
4481
- var help2 = globalThis.memorio?.help;
4519
+ var help = globalThis.memorio?.help;
4482
4520
  var setContext = /* @__PURE__ */ __name((id) => internal_default.currentContext = id, "setContext");
4483
4521
  var getContext = /* @__PURE__ */ __name(() => internal_default.currentContext, "getContext");
4484
4522
  var index_default = memorio2;
4485
4523
 
4486
- export { DEV, PROD, cache, canRedo, canUndo, clearHistory2 as clearHistory, clearRedo, createContext, index_default as default, deleteContext, devtools2 as devtools, diff, dispatch, enableHistory, events, fractional, getCapabilities, getContext, help2 as help, hlc, idb, internal_default as internal, isBrowser, isDeno, isEdge, isNode, isolate, listContexts, listSchemas, logger, memorio2 as memorio, memory, message, observer, propertyName, redo, registerSchema, rollback, schema, session, setContext, snapshot, sqlite, state2 as state, store, trace, typed, undo, unregisterSchema, useObserver, validate };
4524
+ export { DEV, PROD, abortTransaction, activeTransactionId, beginTransaction, cache, canMerge, canRedo, canUndo, clearHistory2 as clearHistory, clearRedo, commitTransaction, createContext, createMutation, currentTimestamp, currentTransaction, index_default as default, deleteContext, devtools, diff, diffToPatch, dispatch, enableHistory, events, fractional, generateCommitId, generateMutationId, generateTransactionId, getCapabilities, getContext, help, hlc, idb, internal_default as internal, isBrowser, isDeno, isEdge, isNode, isolate, listContexts, listSchemas, listTransactions, logger, memorio2 as memorio, memory, mergePatches, message, mutate, mutationToPatch, observer, propertyName, recordMutation, redo, registerSchema, rollback, schema, session, setContext, snapshot, sqlite, state2 as state, store, toPatch, trace, transaction, typed, undo, unregisterSchema, useObserver, validate };
4487
4525
  //# sourceMappingURL=index.js.map
4488
4526
  //# sourceMappingURL=index.js.map