memorio 4.7.3 → 4.8.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.
- package/README.md +206 -0
- package/SUMMARY.md +7 -0
- package/index.cjs +68 -60
- package/index.d.ts +1 -0
- package/index.js +23 -14
- package/markdown/MEMORY-ATTACHMENT.md +95 -0
- package/markdown/SQLITE.md +181 -0
- package/markdown/SYNC.md +170 -0
- package/package.json +9 -3
- package/types/exports.d.ts +2 -0
- package/types/memorio.d.ts +29 -0
- package/types/memory.d.ts +57 -0
- package/types/sqlite.d.ts +35 -0
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'path';
|
|
2
2
|
import 'url';
|
|
3
3
|
|
|
4
|
-
var S=(e,t)=>()=>(e&&(t=e(e=0)),t);var a=S(()=>{});var m,Ct,Ke,ae,l,C=S(()=>{a();m={debug:false,tracking:false,trackedPaths:new Set,locked:false,lastAccessedPath:"",stateVersion:0,currentContext:null,mutations:[],undoStack:[],redoStack:[],maxHistory:100,historyEnabled:false},Ct={get debug(){return m.debug},set debug(e){m.debug=e;},get tracking(){return m.tracking},set tracking(e){m.tracking=e;},get trackedPaths(){return m.trackedPaths},clearTrackedPaths(){m.trackedPaths.clear();},get locked(){return m.locked},set locked(e){m.locked=e;},get lastAccessedPath(){return m.lastAccessedPath},set lastAccessedPath(e){m.lastAccessedPath=e;},get stateVersion(){return m.stateVersion},bumpStateVersion(){return m.stateVersion=(m.stateVersion||0)+1,m.stateVersion},get currentContext(){return m.currentContext},set currentContext(e){m.currentContext=e;},get mutations(){return m.mutations},get undoStack(){return m.undoStack},get redoStack(){return m.redoStack},get maxHistory(){return m.maxHistory},set maxHistory(e){m.maxHistory=e;},get historyEnabled(){return m.historyEnabled},set historyEnabled(e){m.historyEnabled=e;},recordMutation(e){m.historyEnabled&&(m.mutations.push(e),m.mutations.length>m.maxHistory&&m.mutations.shift(),m.undoStack.push(e),m.undoStack.length>m.maxHistory&&m.undoStack.shift(),m.redoStack=[]);},popUndo(){let e=m.undoStack.pop();return e&&m.redoStack.push(e),e},popRedo(){let e=m.redoStack.pop();return e&&m.undoStack.push(e),e},canUndo(){return m.undoStack.length>0},canRedo(){return m.redoStack.length>0},clearHistory(){m.mutations=[],m.undoStack=[],m.redoStack=[];},clearRedo(){m.redoStack=[];}},Ke=["list","state","store","idb","observer","useObserver","remove","removeAll","_platform","_capabilities","_sessionId"],ae=(e,t)=>String(t!==void 0?t:e).replace("() => ",""),l=Ct;});var T,c,x=S(()=>{a();C();T=(...e)=>{l.debug===true&&console.debug(...e);},c=T;});function Q(){let e=globalThis;if(typeof e.crypto<"u"&&e.crypto.randomUUID)return e.crypto.randomUUID();if(typeof e.crypto<"u"&&e.crypto.getRandomValues){let t=new Uint8Array(16);return e.crypto.getRandomValues(t),Array.from(t,r=>r.toString(16).padStart(2,"0")).join("")}return `session_${Date.now()}_${Math.random().toString(36).substring(2,15)}`}function q(){let e=globalThis;return e.Deno&&e.Deno.version?"deno":typeof process<"u"&&process.versions&&process.versions.node?"node":typeof globalThis<"u"&&typeof globalThis.ServiceWorkerGlobalScope<"u"?"edge":typeof window<"u"&&typeof document<"u"?"browser":"unknown"}function le(){return q()==="browser"}function ce(){return q()==="node"}function ue(){return q()==="deno"}function me(){return q()==="edge"}function de(){try{if(typeof sessionStorage<"u"){let e="__memorio_test__";return sessionStorage.setItem(e,"1"),sessionStorage.removeItem(e),sessionStorage}}catch{}return null}function fe(){try{if(typeof localStorage<"u"){let e="__memorio_test__";return localStorage.setItem(e,"1"),localStorage.removeItem(e),localStorage}}catch{}return null}function pe(){return typeof indexedDB<"u"}function $t(){return typeof globalThis.dispatchEvent=="function"}function F(){let e=q(),t=typeof globalThis.isSecureContext<"u"?globalThis.isSecureContext:e==="browser";return {platform:e,hasSessionStorage:de()!==null,hasLocalStorage:fe()!==null,hasIndexedDB:pe(),hasDispatchEvent:$t(),hasNavigator:typeof navigator<"u",hasProcess:typeof process<"u",isSecureContext:t,sessionId:Q()}}function Ze(){let e=F(),t=globalThis;e.hasDispatchEvent||(t.dispatchEvent=function(r){return true},typeof CustomEvent>"u"&&(t.CustomEvent=class{type;detail;constructor(s,o={}){this.type=s,this.detail=o;}})),typeof t.addEventListener!="function"&&(t.addEventListener=function(r,s){U.has(r)||U.set(r,[]),U.get(r).push(s);},t.removeEventListener=function(r,s){let o=U.get(r);if(o){let n=o.indexOf(s);n>-1&&o.splice(n,1);}},t.dispatchEvent=function(r){let s=U.get(r.type);return s&&s.forEach(o=>{try{o(r);}catch(n){console.error("Event listener error:",n);}}),true});}function W(e){let t=e||`context_${Q()}`;he(t);let r={state:{},store:new Map,session:new Map,cache:new Map};return ge.set(t,r),{id:t,state:r.state,store:{get:s=>{let o=r.store.get(s);return o?JSON.parse(o):null},set:(s,o)=>{r.store.set(s,JSON.stringify(o));},remove:s=>r.store.delete(s),removeAll:()=>r.store.clear(),clearAll:()=>r.store.clear(),size:()=>r.store.size,isPersistent:false},session:{get:s=>{let o=r.session.get(s);return o?JSON.parse(o):null},set:(s,o)=>{r.session.set(s,JSON.stringify(o));},remove:s=>r.session.delete(s),removeAll:()=>r.session.clear(),clearAll:()=>r.session.clear(),size:()=>r.session.size,isPersistent:false},cache:{get:s=>r.cache.get(s),set:(s,o)=>r.cache.set(s,o),remove:s=>r.cache.delete(s),removeAll:()=>r.cache.clear(),clear:()=>r.cache.clear()}}}function ye(){return Array.from(ge.keys())}function be(e){return ge.delete(e)}function he(e){l.currentContext=e;}var U,ge,K=S(()=>{a();C();U=new Map;ge=new Map;});var Nt={};var et=S(()=>{a();E();x();u.db.create=(e,t=1)=>new Promise((r,s)=>{if(!u.db.support())return s(new Error("IndexedDB not supported"));let o=globalThis.indexedDB.open(e,t);o.onerror=()=>{c(`IndexedDB error: ${o.error?.message}`),s(o.error);},o.onsuccess=()=>{c(`Database ${e} connected successfully`),r(o.result);},o.onupgradeneeded=()=>{c(`Database ${e} upgrade/creation initiated`);};});});var Vt={};var tt=S(()=>{a();E();u.db.list=async()=>{if(!("indexedDB"in globalThis)||!indexedDB.databases)return [];try{let e=await indexedDB.databases();return globalThis.idbases=e||[],await u.db.size(),globalThis.idbases}catch(e){return console.error("Error listing databases:",e),[]}};});var Bt={};var rt=S(()=>{a();E();u.db.exist=e=>idbases?.some(t=>t.name===e);});var Lt={};var ot=S(()=>{a();E();u.db.quota=()=>navigator.storage.estimate();});var Ht={};var st=S(()=>{a();E();x();u.db.delete=e=>new Promise((t,r)=>{c(`Removing database ${e}...`),(()=>{let o=indexedDB.deleteDatabase(e);o.onsuccess=()=>{c(`${e} database removed successfully`),u.db.list(),t();},o.onerror=()=>{console.error(`Error removing ${e}:`,o.error),r(o.error);},o.onblocked=()=>{console.warn(`Deletion of ${e} is blocked. Please close other tabs.`);};})();});});var Jt={};var nt=S(()=>{a();E();x();u.db.size=async()=>{if(!(!idbases||idbases.length===0))for(let e=0;e<idbases.length;e++){let t=idbases[e];try{let r=await u.db.create(t.name,t.version),s=Array.from(r.objectStoreNames),o=0;for(let n of s){let i=await u.table.size(r,n);o+=i;}t.size=o,r.close();}catch(r){c(`Could not calculate size for ${t.name}:${r}`);}}};});var zt={};var it=S(()=>{a();E();u.db.version=e=>{let t=0;for(let r of idbases){r.name===e&&(t=r.version);break}return t};});var Kt={};var at=S(()=>{a();E();x();u.db.support=()=>{let e="indexedDB"in globalThis;return e||c("Your environment doesn't support IndexedDB"),e};});var Ut={};var lt=S(()=>{a();E();x();u.table.create=(e,t)=>new Promise((r,s)=>{try{let n=(Number(u.db.version(e))||0)+1,i=indexedDB.open(e,n);i.onupgradeneeded=d=>{let f=d.target.result;if(!f.objectStoreNames.contains(t)){let y=f.createObjectStore(t,{keyPath:"id",autoIncrement:!0});y.createIndex("id","id",{unique:!0}),y.createIndex("data","data",{unique:!1}),c(`Table ${t} created in ${e}`);}},i.onsuccess=()=>{i.result.close(),u.db.list(),r();},i.onerror=()=>{console.error(`Error creating table ${t}:`,i.error),s(i.error);};}catch(o){console.error("Critical error in table.create:",o),s(o);}});});var qt={};var ct=S(()=>{a();E();x();u.table.size=(e,t)=>new Promise((r,s)=>{if(!e)return s(new Error("Database instance is required"));if(!e.objectStoreNames.contains(t))return r(0);let o=0,n=0,f=e.transaction([t],"readonly").objectStore(t).openCursor();f.onsuccess=async y=>{let b=y.target.result;if(b){try{let k=b.value;o+=JSON.stringify(k).length;}catch(k){c(`Error stringifying IDB value tracking size:${k}`);}n++,n%200===0&&await new Promise(k=>setTimeout(k,0)),b.continue();}else r(o);},f.onerror=()=>{s(f.error);};});});var Ft={};var ut=S(()=>{a();E();x();u.data.delete=(e,t,r)=>new Promise((s,o)=>{let n=indexedDB.open(e);n.onsuccess=()=>{let i=n.result;if(!i.objectStoreNames.contains(t))return i.close(),o(new Error(`Table ${t} not found`));let y=i.transaction(t,"readwrite").objectStore(t).delete(r);y.onsuccess=()=>{i.close(),c(`Record ${r} deleted from ${t}`),s();},y.onerror=()=>{i.close(),o(y.error);};},n.onerror=()=>o(n.error);});u.data.delete.all=(e,t)=>new Promise((r,s)=>{let o=indexedDB.open(e);o.onsuccess=n=>{let i=n.target.result;if(!i.objectStoreNames.contains(t))return i.close(),s(new Error(`Table ${t} not found`));let y=i.transaction(t,"readwrite").objectStore(t).clear();y.onsuccess=()=>{i.close(),c(`All data cleared from ${t}`),r();},y.onerror=()=>{i.close(),s(y.error);};},o.onerror=()=>s(o.error);});});var Wt={};var mt=S(()=>{a();E();x();u.data.set=(e,t,r)=>new Promise((s,o)=>{let n=indexedDB.open(e);n.onsuccess=()=>{let i=n.result;if(!i.objectStoreNames.contains(t))return i.close(),o(new Error(`Table ${t} does not exist in ${e}`));let y=i.transaction(t,"readwrite").objectStore(t).put(r);y.onsuccess=()=>{i.close(),c(`Data saved in ${e}.${t}`),s(y.result);},y.onerror=b=>{i.close(),c(`Database insert error: ${y.error?.message}`),o(y.error);};},n.onerror=()=>{o(n.error);};});});var Gt={};var dt=S(()=>{a();E();u.data.get=(e,t,r)=>new Promise((s,o)=>{let n=indexedDB.open(e);n.onsuccess=i=>{let d=i.target.result;if(!d.objectStoreNames.contains(t))return d.close(),o(new Error(`Table ${t} not found in ${e}`));let b=d.transaction(t,"readonly").objectStore(t).get(r);b.onsuccess=()=>{d.close(),s(b.result);},b.onerror=()=>{d.close(),o(b.error);};},n.onerror=()=>{o(n.error);};});});var Yt,u,E=S(()=>{a();K();Yt=pe(),u={db:{},table:{},data:{}};Yt?(async()=>(Object.defineProperty(u,"db",{value:{},writable:true,configurable:true}),Object.defineProperty(u,"table",{value:{},writable:true,configurable:true}),Object.defineProperty(u,"data",{value:{},writable:true,configurable:true}),Object.defineProperty(globalThis,"idbases",{value:[],writable:true,configurable:true,enumerable:false}),await Promise.all([Promise.resolve().then(()=>(et(),Nt)),Promise.resolve().then(()=>(tt(),Vt)),Promise.resolve().then(()=>(rt(),Bt)),Promise.resolve().then(()=>(ot(),Lt)),Promise.resolve().then(()=>(st(),Ht)),Promise.resolve().then(()=>(nt(),Jt)),Promise.resolve().then(()=>(it(),zt)),Promise.resolve().then(()=>(at(),Kt)),Promise.resolve().then(()=>(lt(),Ut)),Promise.resolve().then(()=>(ct(),qt)),Promise.resolve().then(()=>(ut(),Ft)),Promise.resolve().then(()=>(mt(),Wt)),Promise.resolve().then(()=>(dt(),Gt))]),Object.preventExtensions(u),Object.seal(u),Object.freeze(u)))():(u._disabled=true,u._warning="IndexedDB is not available in this environment (Node.js/Deno). Use store or session for persistence.",console.warn("Memorio IDB: IndexedDB is not available in this environment. Use store or session for data persistence."));});a();a();C();x();a();var v={set:(e,t={})=>{globalThis.dispatchEvent(new CustomEvent(String(e),t));},listen:(e,t=null,r)=>{if(globalThis.events?.[e])return;let s=t?o=>{let n=o;return globalThis.queueMicrotask?globalThis.queueMicrotask(()=>t(n)):Promise.resolve().then(()=>t(n))}:void 0;s&&globalThis.addEventListener(e,s),s&&(globalThis.events[e]=s);},remove:e=>{let t=globalThis.events?.[e];t&&(globalThis.removeEventListener(e,t),delete globalThis.events[e]);}};a();x();var z=new Map,Ue=(e,t,r)=>{let s=[];if(t.type&&t.type!=="any"){let o=Array.isArray(e)?"array":typeof e;if(o!==t.type)return s.push(`${r}: expected ${t.type}, got ${o}`),{valid:false,errors:s}}if(t.enum&&!t.enum.includes(e)&&s.push(`${r}: value must be one of [${t.enum.map(String).join(", ")}]`),t.validator){let o=t.validator(e);o!==true&&s.push(`${r}: ${typeof o=="string"?o:"validation failed"}`);}if(typeof e=="number"&&(t.min!==void 0&&e<t.min&&s.push(`${r}: value ${e} is less than minimum ${t.min}`),t.max!==void 0&&e>t.max&&s.push(`${r}: value ${e} exceeds maximum ${t.max}`)),typeof e=="string"&&(t.min!==void 0&&e.length<t.min&&s.push(`${r}: string length ${e.length} is less than minimum ${t.min}`),t.max!==void 0&&e.length>t.max&&s.push(`${r}: string length ${e.length} exceeds maximum ${t.max}`),t.pattern&&!t.pattern.test(e)&&s.push(`${r}: string does not match required pattern`)),t.type==="object"&&e&&typeof e=="object"&&!Array.isArray(e)){if(t.required)for(let o of t.required)o in e||s.push(`${r}: missing required property '${o}'`);if(t.properties){for(let[o,n]of Object.entries(t.properties))if(o in e&&e[o]!==void 0){let i=Ue(e[o],n,`${r}.${o}`);i.valid||s.push(...i.errors||[]);}}}return s.length===0?{valid:true}:{valid:false,errors:s}},qe=(e,t)=>{let r=z.get(e);return r?Ue(t,r,e):{valid:true}},Fe=(e,t)=>{typeof t=="function"?z.set(e,{validator:t}):z.set(e,t),c(`[memorio schema] Registered schema for '${e}'`);},We=e=>z.delete(e),Ge=()=>Array.from(z.keys()),_t=e=>z.get(e),M={register:Fe,validate:qe,unregister:We,list:Ge,get:_t};var X=Symbol("memorio.target"),Ye=new WeakMap,A=(e,t=null)=>{if(e===null||typeof e!="object")return e;if(e[X]!==void 0)return A(e[X],t);if(t){if(t.has(e))return e;t.add(e);}let r=e.constructor?.name;if(r!=="Object"&&r!=="Array")return e;let s=Array.isArray(e)?[]:{};for(let o of Reflect.ownKeys(e))s[o]=A(e[o],t);return s},Xe=(e,t,r=".")=>t.concat(e).join(r),Qe=(e,t,r=[])=>{let s=o=>{try{v.set(o,{detail:{name:o}});}catch{}};return new Proxy(e,{get(o,n){if(n==="__path")return r.length>0?"state."+r.join("."):"state";if(n===X||o[X]!==void 0)return o;if(n==="list")return c('Some state could be hidden when you use "state.list". Use "state" to see the complete list '),JSON.parse(JSON.stringify(o));if(typeof n=="string"){let i=r.length>0?"state."+r.concat(n).join("."):"state."+n;l.lastAccessedPath=i,l.tracking&&l.trackedPaths.add(i);}if(n==="_lastPath")return l.lastAccessedPath;if(n==="remove")return i=>(delete o[i],true);if(n==="removeAll")return ()=>{try{for(let i in o)typeof o[i]!="function"&&!["list","remove","removeAll","lock","unlock"].includes(i)&&delete o[i];}catch(i){console.error(i);}};if(Object.isFrozen(o[n]))return o[n];if(n==="lock"||n==="unlock"){let i=Reflect.get(o,n);if(i)return i}try{let i=Reflect.get(o,n);if(i&&typeof i=="object"&&["Array","Object"].includes(i.constructor.name)){let d=Ye.get(i);return d||(d=Qe(i,t,r.concat(n)),Ye.set(i,d)),d}return i}catch(i){console.error("Error: ",i);return}},set(o,n,i){if(l.locked)return console.error("Error: state is locked. Use state.unlock() to enable modifications."),false;if(Ke.includes(n))return console.error("key "+n+" is protected"),false;if(o[n]&&typeof o[n]=="object"&&Object.isFrozen(o[n]))return console.error(`Error: state '${n}' is locked`),false;if(o[n]&&typeof o[n]=="object"&&o[n].__locked)return console.error(`Error: state '${n}' is locked. Use state.${n}.unlock() to enable modifications.`),false;try{let d=Xe(n,r),f=A(i),y=M.validate(d,f);if(!y.valid)return l.debug&&console.error(`[memorio schema] Validation failed for '${d}':`,y.errors),c(`[memorio schema] Validation failed for '${d}': `+(y.errors?.join(", ")||"unknown error")),!1;if(t({action:"set",path:d,target:o,newValue:f,previousValue:Reflect.get(o,n)}),s("state."+d),Reflect.set(o,n,f),l.bumpStateVersion(),o[n]&&typeof o[n]=="object"){let b=o[n];if(b&&typeof b=="object")try{Object.defineProperty(b,"__locked",{writable:!0,enumerable:!1,configurable:!1,value:!1}),Object.defineProperty(b,"lock",{writable:!1,enumerable:!1,configurable:!1,value:()=>{Object.defineProperty(b,"__locked",{writable:!0,enumerable:!1,configurable:!1,value:!0}),c(`State '${n}' is now locked.`);}}),Object.defineProperty(b,"unlock",{writable:!1,enumerable:!1,configurable:!1,value:()=>{Object.defineProperty(b,"__locked",{writable:!0,enumerable:!1,configurable:!1,value:!1}),c(`State '${n}' is now unlocked.`);}});}catch{}}return !0}catch(d){return console.error("Error in set trap:",d),false}},deleteProperty(o,n){try{let i=Xe(n,r),d=Reflect.get(o,n);return t({action:"delete",path:i,target:o,previousValue:d}),Reflect.deleteProperty(o,n)}catch(i){return console.error("Error in deleteProperty trap:",i),false}},ownKeys(o){return Reflect.ownKeys(o)},getOwnPropertyDescriptor(o,n){return Reflect.getOwnPropertyDescriptor(o,n)}})},h=Qe({},e=>{l.historyEnabled&&l.recordMutation({path:e.path,action:e.action,newValue:e.newValue,previousValue:e.previousValue,timestamp:Date.now()});});h.lock=()=>{l.locked=true,c("State is now locked. All modifications are blocked.");};h.unlock=()=>{l.locked=false,c("State is now unlocked. Modifications are allowed.");};a();K();C();x();var P=fe(),ve=new Map;function V(){let t=l.currentContext||""||"default";return ve.has(t)||ve.set(t,new Map),ve.get(t)}var N=P!==null;function I(){let e=l.currentContext||"";return e?`${e}-`:"memorio_store_"}function xe(e){return !e||typeof e!="string"?(console.warn("[memorio store] key is empty or not a string - operation aborted"),""):e.length>512?(console.warn(`[memorio store] key "${e}" exceeds 512 chars - operation aborted`),""):I()+e}function Dt(e){let t=N?P.getItem(e):V().get(e);return t&&JSON.parse(t)}function Rt(e,t){let r=JSON.stringify(t);N?P.setItem(e,r):V().set(e,r);}function At(e){if(N){if(P.getItem(e))return P.removeItem(e),true}else if(V().has(e))return V().delete(e),true;return false}var w=new Proxy({},{});Object.defineProperty(globalThis,"store",{value:w,enumerable:false,configurable:true});Object.defineProperties(w,{get:{value:e=>{if(!e)return console.warn("[memorio store] store.get() called with empty or null key - returning null"),null;try{return Dt(xe(e))}catch(t){T(`Error parsing store item '${e}': ${t}`);}return null}},getMultiple:{value:e=>{let t={};for(let r of e)try{let s=w.get(r);s&&(t[r]=s);}catch(s){console.debug(`[memorio store] getMultiple error for key "${r}":`,s);}return t}},set:{value:(e,t)=>{if(!e)return console.warn("[memorio store] store.set() called with empty or null key - write aborted"),false;let r=xe(e);if(!r)return false;if(typeof t=="function")return console.warn("[memorio store] functions are not storable - write aborted for key: "+e),T("Storing functions is not secure and is blocked for safety."),false;try{Rt(r,t);}catch(s){return T(`Error setting store item '${e}': ${s}`),false}return true}},remove:{value:e=>{if(!e)return console.debug("[memorio store] store.remove() called with empty or null key - returning false"),false;let t=xe(e);if(!t)return false;try{return At(t)}catch(r){T(`Error removing store item '${e}': ${r}`);}return false}},delete:{value:e=>w.remove(e)},removeAll:{value:()=>{if(N){let e=[];for(let t=0;t<P.length;t++){let r=P.key(t);r?.startsWith(I())&&e.push(r);}e.forEach(t=>P.removeItem(t));}else V().clear();return true}},clearAll:{value:()=>(w.removeAll(),true)},quota:{value:async()=>[0,0]},size:{value:()=>{let e=0;return N?Object.keys(P).forEach(t=>{if(t.startsWith(I())){let r=P.getItem(t);r&&(e+=r.length);}}):V().forEach(t=>{e+=t.length;}),e}},isPersistent:{get:()=>N},list:{value:()=>{let e={};try{if(N)for(let t=0;t<P.length;t++){let r=P.key(t);if(r?.startsWith(I())){let s=r.replace(I(),""),o=P.getItem(r);if(o!==null)try{e[s]=JSON.parse(o);}catch{e[s]=o;}}}else V().forEach((t,r)=>{if(r.startsWith(I())){let s=r.replace(I(),"");try{e[s]=JSON.parse(t);}catch{e[s]=t;}}});}catch(t){T(`Error listing store items: ${t}`);}return e}}});Object.freeze(w);a();K();C();x();var O=de(),Se=new Map;function H(){let t=l.currentContext||""||"default";return Se.has(t)||Se.set(t,new Map),Se.get(t)}var L=O!==null;function B(){let e=l.currentContext||"";return e?`${e}-`:"memorio_session_"}function we(e){return !e||typeof e!="string"?(console.warn("[memorio session] key is empty or not a string - operation aborted"),""):e.length>512?(console.warn(`[memorio session] key "${e}" exceeds 512 chars - operation aborted`),""):B()+e}function Mt(e){let t=L?O.getItem(e):H().get(e);return t&&JSON.parse(t)}function jt(e,t){let r=JSON.stringify(t);L?O.setItem(e,r):H().set(e,r);}function It(e){if(L){if(O.getItem(e))return O.removeItem(e),true}else if(H().has(e))return H().delete(e),true;return false}var _=new Proxy({},{});Object.defineProperty(globalThis,"session",{value:_,enumerable:false,configurable:true});Object.defineProperties(_,{get:{value:e=>{if(!e)return console.warn("[memorio session] session.get() called with empty or null key - returning null"),null;try{return Mt(we(e))}catch(t){T(`Error parsing session item '${e}':${t}`);}return null}},set:{value:(e,t)=>{if(!e)return console.warn("[memorio session] session.set() called with empty or null key - write aborted"),false;let r=we(e);if(!r)return false;if(typeof t=="function")return console.warn("[memorio session] functions are not storable - write aborted for key: "+e),T("It's not secure to session functions."),false;try{jt(r,t);}catch(s){return T(`Error setting session item '${e}': ${s}`),false}return true}},remove:{value:e=>{if(!e)return console.warn("[memorio session] session.remove() called with empty or null key - returning false"),false;let t=we(e);if(!t)return false;try{return It(t)}catch(r){T(`Error removing session item '${e}': ${r}`);}return false}},delete:{value:e=>_.remove(e)},removeAll:{value:()=>{if(L){let e=[];for(let t=0;t<O.length;t++){let r=O.key(t);r?.startsWith(B())&&e.push(r);}e.forEach(t=>O.removeItem(t));}else H().clear();return true}},clearAll:{value:()=>(_.removeAll(),true)},quota:{value:async()=>[0,0]},size:{value:()=>{let e=0;return L?Object.keys(O).forEach(t=>{if(t.startsWith(B())){let r=O.getItem(t);r&&(e+=r.length);}}):H().forEach(t=>{e+=t.length;}),e}},isPersistent:{get:()=>L},list:{value:()=>{let e={};try{if(L)for(let t=0;t<O.length;t++){let r=O.key(t);if(r?.startsWith(B())){let s=r.replace(B(),""),o=O.getItem(r);if(o!==null)try{e[s]=JSON.parse(o);}catch{e[s]=o;}}}else H().forEach((t,r)=>{if(r.startsWith(B())){let s=r.replace(B(),"");try{e[s]=JSON.parse(t);}catch{e[s]=t;}}});}catch(t){T(`Error listing session items: ${t}`);}return e}}});Object.freeze(_);a();var D={},Z=new Proxy({},{get(e,t){let r=t;return r==="get"?s=>D[s]:r==="set"?(s,o)=>{D[s]=o;}:r==="remove"?s=>(delete D[s],true):r==="removeAll"?()=>(Object.keys(D).forEach(s=>delete D[s]),true):r==="clear"?()=>(Object.keys(D).forEach(s=>delete D[s]),true):r==="list"?()=>({...D}):D[r]},set(e,t,r){return D[t]=r,true},deleteProperty(e,t){return delete D[t],true}});Object.freeze(Z);E();a();x();var ft=false,Xt=(e,t=null,r=true)=>{ft||(console.warn('DEPRECATED: "observer" is deprecated and will be removed in future versions. Please use "useObserver" instead.'),ft=true);let s=n=>typeof n=="string"?n:n&&typeof n=="object"&&n.__path?n.__path:null,o=s(e);if(!e&&!t){console.error("Observer Error: You need to setup observer correctly, Some parameters are missed!");return}if(!e&&t){console.error("Observer Error: You need to declare what state need to be monitored as string like 'state.test'.");return}if(o){let n=o.split(".");if(n[0]!=="state"&&n[0]!=="store"){console.error(`Observer Error: You need to declare 'state.' or 'store.'. The '${o}' string is incorrect!`);return}}if(e&&!t){let n=s(e);if(!n)return;globalThis.observer?.list?.[n]&&v.remove(n),c(`called: ${n}`);return}if(e&&t){let n=s(e);if(!n)return;if(typeof e!="string"&&!(e&&typeof e=="object")){console.error("Observer Error: name of state need to be a 'string' like 'state.test' or a direct state value");return}let i=Array.isArray(t)?t:[t];globalThis.observer?.list?.[n]&&v.remove(n),i.forEach(f=>{typeof f=="function"&&v.listen(n,f,r);});return}},ee=Xt;Object.defineProperties(ee,{list:{get:()=>globalThis.events},remove:{value:e=>{e&&(v.remove(e),delete globalThis.events[e]);}},removeAll:{get:()=>{let e=globalThis.observer,t=e?.list;return t&&Object.keys(t).forEach(r=>{e?.remove?.(r);}),true}},has:{value:e=>!!globalThis.observer?.list?.[e]}});a();x();C();globalThis.useObserver||(globalThis.useObserver=null);Object.defineProperty(globalThis,"useObserver",{value:null,writable:true,enumerable:false,configurable:true});var te=((e,t=[])=>{if(!t||typeof e!="function")return ()=>{};let r=[],s=Array.isArray(t)&&!t.__path?t:[t];try{return s.forEach(o=>{let n="";if(typeof o=="function"){let i=ae(o);i&&(n=i);}else typeof o=="object"&&o!==null&&(n=o.__path||(typeof o.toString=="function"&&o.toString()!=="[object Object]"?o.toString():""));if(n){n=n.replace(/^(\(\)\s*=>\s*)/,"").replace(/^globalThis\./,"").replace(/^state\./,"");let i=n.startsWith("store.")||n.startsWith("state.")?n:"state."+n;v.listen(i,()=>e()),r.push(i);}else {l.clearTrackedPaths(),l.tracking=!0;try{e();}catch{}l.tracking=!1,l.trackedPaths.forEach(i=>{r.includes(i)||(c(`useObserver: [Auto-Discovery] -> "${i}"`),v.listen(i,()=>e()),r.push(i));});}}),r.length>0?c(`useObserver: Monitoring ${r.length} paths.`):console.warn("useObserver: No paths resolved for monitoring. Check your dependencies!"),()=>{r.forEach(o=>{typeof v.remove=="function"&&(v.remove(o),c(`useObserver: Stopped monitoring "${o}"`));});}}catch(o){return c(`useObserver Error: ${o}`),()=>{}}});globalThis.useObserver=te;Object.freeze(globalThis.useObserver);x();a();C();function Qt(){return l.debug===true}function pt(){if(!globalThis.store)return {};let e={},t=globalThis.store;if(typeof t.list=="function")try{return t.list()}catch{}if(typeof t.get=="function"){for(let r of Object.keys(t))if(!["get","set","remove","delete","removeAll","clearAll","size","isPersistent","list"].includes(r))try{let s=t.get(r);s!=null&&(e[r]=s);}catch{}}return e}function gt(){if(!globalThis.session)return {};let e={},t=globalThis.session;if(typeof t.list=="function")try{return t.list()}catch{}if(typeof t.get=="function"){for(let r of Object.keys(t))if(!["get","set","remove","delete","removeAll","clearAll","size","isPersistent","list"].includes(r))try{let s=t.get(r);s!=null&&(e[r]=s);}catch{}}return e}var Zt=()=>{if(Qt()){if(globalThis.state){let e=globalThis.state.list,t;typeof e=="function"?t=e():typeof e=="object"&&e!==null?t=e:t=globalThis.state,console.table(t);}if(globalThis.store&&console.table(pt()),globalThis.session&&console.table(gt()),globalThis.cache){let e=globalThis.cache.list,t;typeof e=="function"?t=e():typeof e=="object"&&e!==null?t=e:t=globalThis.cache,console.table(t);}}},er=()=>{let e=t=>{if(!t)return 0;if(typeof t.list=="function")try{let r=t.list();return Object.keys(r).length}catch{}return Object.keys(t).length};return {stateKeys:e(globalThis.state),storeKeys:e(globalThis.store),sessionKeys:e(globalThis.session),cacheKeys:e(globalThis.cache),idbDatabases:0,lastUpdate:new Date().toISOString()}},G=e=>{globalThis[e]&&typeof globalThis[e].clear=="function"?globalThis[e].clear():console.error(`Module ${e} not found or does not support clear()`);},tr=()=>{G("state"),G("store"),G("session"),G("cache");},rr=()=>{let e=()=>{if(globalThis.state)try{return typeof globalThis.state.list=="function"?globalThis.state.list():globalThis.state}catch{return}},t=()=>pt(),r=()=>gt(),s=()=>{if(globalThis.cache)try{return typeof globalThis.cache.list=="function"?globalThis.cache.list():globalThis.cache}catch{return}},o={state:e(),store:t(),session:r(),cache:s(),exportedAt:new Date().toISOString()};return JSON.stringify(o,null,2)},or=e=>{try{let t=JSON.parse(e);t.state&&Object.entries(t.state).forEach(([r,s])=>{globalThis.state&&r!=="list"&&r!=="remove"&&r!=="removeAll"&&(globalThis.state[r]=s);}),t.store&&globalThis.store&&typeof globalThis.store.set=="function"&&Object.entries(t.store).forEach(([r,s])=>{globalThis.store.set(r,s);}),t.session&&globalThis.session&&typeof globalThis.session.set=="function"&&Object.entries(t.session).forEach(([r,s])=>{globalThis.session.set(r,s);}),t.cache&&globalThis.cache&&Object.entries(t.cache).forEach(([r,s])=>{globalThis.cache&&r!=="get"&&r!=="set"&&r!=="remove"&&r!=="clear"&&(globalThis.cache[r]=s);});}catch(t){console.error("%c\u2717 Import failed:","color: #F44336",t);}},sr=(e,t)=>{if(!globalThis[e]){console.error(`Module ${e} not found`);return}let r=globalThis[e],s=r[t];if(console.debug(`\u{1F441} Watching ${e}.${t} (initial: ${JSON.stringify(s)})`),e==="state"&&globalThis.memorio?.dispatch){let o=n=>{n.detail?.name?.includes(t)&&console.debug(`\u{1F441} Change: ${e}.${t} =`,n.detail.value);};r.addEventListener?.("memorio-change",o);}},nr=()=>{console.debug(`
|
|
4
|
+
var x=(e,t)=>()=>(e&&(t=e(e=0)),t);var a=x(()=>{});var y,dr,mt,Se,u,$=x(()=>{a();y={debug:false,tracking:false,trackedPaths:new Set,locked:false,lastAccessedPath:"",stateVersion:0,currentContext:null,mutations:[],undoStack:[],redoStack:[],maxHistory:100,historyEnabled:false},dr={get debug(){return y.debug},set debug(e){y.debug=e;},get tracking(){return y.tracking},set tracking(e){y.tracking=e;},get trackedPaths(){return y.trackedPaths},clearTrackedPaths(){y.trackedPaths.clear();},get locked(){return y.locked},set locked(e){y.locked=e;},get lastAccessedPath(){return y.lastAccessedPath},set lastAccessedPath(e){y.lastAccessedPath=e;},get stateVersion(){return y.stateVersion},bumpStateVersion(){return y.stateVersion=(y.stateVersion||0)+1,y.stateVersion},get currentContext(){return y.currentContext},set currentContext(e){y.currentContext=e;},get mutations(){return y.mutations},get undoStack(){return y.undoStack},get redoStack(){return y.redoStack},get maxHistory(){return y.maxHistory},set maxHistory(e){y.maxHistory=e;},get historyEnabled(){return y.historyEnabled},set historyEnabled(e){y.historyEnabled=e;},recordMutation(e){y.historyEnabled&&(y.mutations.push(e),y.mutations.length>y.maxHistory&&y.mutations.shift(),y.undoStack.push(e),y.undoStack.length>y.maxHistory&&y.undoStack.shift(),y.redoStack=[]);},popUndo(){let e=y.undoStack.pop();return e&&y.redoStack.push(e),e},popRedo(){let e=y.redoStack.pop();return e&&y.undoStack.push(e),e},canUndo(){return y.undoStack.length>0},canRedo(){return y.redoStack.length>0},clearHistory(){y.mutations=[],y.undoStack=[],y.redoStack=[];},clearRedo(){y.redoStack=[];}},mt=["list","state","store","idb","sqlite","observer","useObserver","remove","removeAll","_platform","_capabilities","_sessionId"],Se=(e,t)=>String(t!==void 0?t:e).replace("() => ",""),u=dr;});var P,c,w=x(()=>{a();$();P=(...e)=>{u.debug===true&&console.debug(...e);},c=P;});function ce(){let e=globalThis;if(typeof e.crypto<"u"&&e.crypto.randomUUID)return e.crypto.randomUUID();if(typeof e.crypto<"u"&&e.crypto.getRandomValues){let t=new Uint8Array(16);return e.crypto.getRandomValues(t),Array.from(t,r=>r.toString(16).padStart(2,"0")).join("")}return `session_${Date.now()}_${Math.random().toString(36).substring(2,15)}`}function te(){let e=globalThis;return e.Deno&&e.Deno.version?"deno":typeof process<"u"&&process.versions&&process.versions.node?"node":typeof globalThis<"u"&&typeof globalThis.ServiceWorkerGlobalScope<"u"?"edge":typeof window<"u"&&typeof document<"u"?"browser":"unknown"}function we(){return te()==="browser"}function Ee(){return te()==="node"}function Te(){return te()==="deno"}function Pe(){return te()==="edge"}function _e(){try{if(typeof sessionStorage<"u"){let e="__memorio_test__";return sessionStorage.setItem(e,"1"),sessionStorage.removeItem(e),sessionStorage}}catch{}return null}function ke(){try{if(typeof localStorage<"u"){let e="__memorio_test__";return localStorage.setItem(e,"1"),localStorage.removeItem(e),localStorage}}catch{}return null}function Oe(){return typeof indexedDB<"u"}function re(){let e=globalThis;return typeof e.WebAssembly>"u"||typeof e.WebAssembly.instantiate!="function"?false:typeof e.window<"u"}function pr(){return typeof globalThis.dispatchEvent=="function"}function oe(){let e=te(),t=typeof globalThis.isSecureContext<"u"?globalThis.isSecureContext:e==="browser";return {platform:e,hasSessionStorage:_e()!==null,hasLocalStorage:ke()!==null,hasIndexedDB:Oe(),hasSqlJs:re(),hasDispatchEvent:pr(),hasNavigator:typeof navigator<"u",hasProcess:typeof process<"u",isSecureContext:t,sessionId:ce()}}function xt(){let e=oe(),t=globalThis;e.hasDispatchEvent||(t.dispatchEvent=function(r){return true},typeof CustomEvent>"u"&&(t.CustomEvent=class{type;detail;constructor(o,n={}){this.type=o,this.detail=n;}})),typeof t.addEventListener!="function"&&(t.addEventListener=function(r,o){ee.has(r)||ee.set(r,[]),ee.get(r).push(o);},t.removeEventListener=function(r,o){let n=ee.get(r);if(n){let s=n.indexOf(o);s>-1&&n.splice(s,1);}},t.dispatchEvent=function(r){let o=ee.get(r.type);return o&&o.forEach(n=>{try{n(r);}catch(s){console.error("Event listener error:",s);}}),true});}function ne(e){let t=e||`context_${ce()}`;Ce(t);let r={state:{},store:new Map,session:new Map,cache:new Map};return qe.set(t,r),{id:t,state:r.state,store:{get:o=>{let n=r.store.get(o);return n?JSON.parse(n):null},set:(o,n)=>{r.store.set(o,JSON.stringify(n));},remove:o=>r.store.delete(o),removeAll:()=>r.store.clear(),clearAll:()=>r.store.clear(),size:()=>r.store.size,isPersistent:false},session:{get:o=>{let n=r.session.get(o);return n?JSON.parse(n):null},set:(o,n)=>{r.session.set(o,JSON.stringify(n));},remove:o=>r.session.delete(o),removeAll:()=>r.session.clear(),clearAll:()=>r.session.clear(),size:()=>r.session.size,isPersistent:false},cache:{get:o=>r.cache.get(o),set:(o,n)=>r.cache.set(o,n),remove:o=>r.cache.delete(o),removeAll:()=>r.cache.clear(),clear:()=>r.cache.clear()}}}function Me(){return Array.from(qe.keys())}function $e(e){return qe.delete(e)}function Ce(e){u.currentContext=e;}var ee,qe,J=x(()=>{a();$();ee=new Map;qe=new Map;});function U(){let t=u.currentContext||""||"default";return je.has(t)||je.set(t,new Map),je.get(t)}function B(){let e=u.currentContext||"";return e?`${e}-`:"memorio_store_"}function De(e){return !e||typeof e!="string"?(console.warn("[memorio store] key is empty or not a string - operation aborted"),""):e.length>512?(console.warn(`[memorio store] key "${e}" exceeds 512 chars - operation aborted`),""):B()+e}function yr(e){let t=V?q.getItem(e):U().get(e);return t&&JSON.parse(t)}function gr(e,t){let r=JSON.stringify(t);V?q.setItem(e,r):U().set(e,r);}function br(e){if(V){if(q.getItem(e))return q.removeItem(e),true}else if(U().has(e))return U().delete(e),true;return false}var q,je,V,h,G=x(()=>{a();J();$();w();q=ke(),je=new Map;V=q!==null;h=new Proxy({},{});Object.defineProperty(globalThis,"store",{value:h,enumerable:false,configurable:true});Object.defineProperties(h,{get:{value:e=>{if(!e)return console.warn("[memorio store] store.get() called with empty or null key - returning null"),null;try{return yr(De(e))}catch(t){P(`Error parsing store item '${e}': ${t}`);}return null}},getMultiple:{value:e=>{let t={};for(let r of e)try{let o=h.get(r);o&&(t[r]=o);}catch(o){console.debug(`[memorio store] getMultiple error for key "${r}":`,o);}return t}},set:{value:(e,t)=>{if(!e)return console.warn("[memorio store] store.set() called with empty or null key - write aborted"),false;let r=De(e);if(!r)return false;if(typeof t=="function")return console.warn("[memorio store] functions are not storable - write aborted for key: "+e),P("Storing functions is not secure and is blocked for safety."),false;try{gr(r,t);}catch(o){return P(`Error setting store item '${e}': ${o}`),false}return true}},remove:{value:e=>{if(!e)return console.debug("[memorio store] store.remove() called with empty or null key - returning false"),false;let t=De(e);if(!t)return false;try{return br(t)}catch(r){P(`Error removing store item '${e}': ${r}`);}return false}},delete:{value:e=>h.remove(e)},removeAll:{value:()=>{if(V){let e=[];for(let t=0;t<q.length;t++){let r=q.key(t);r?.startsWith(B())&&e.push(r);}e.forEach(t=>q.removeItem(t));}else U().clear();return true}},clearAll:{value:()=>(h.removeAll(),true)},quota:{value:async()=>[0,0]},size:{value:()=>{let e=0;return V?Object.keys(q).forEach(t=>{if(t.startsWith(B())){let r=q.getItem(t);r&&(e+=r.length);}}):U().forEach(t=>{e+=t.length;}),e}},isPersistent:{get:()=>V},list:{value:()=>{let e={};try{if(V)for(let t=0;t<q.length;t++){let r=q.key(t);if(r?.startsWith(B())){let o=r.replace(B(),""),n=q.getItem(r);if(n!==null)try{e[o]=JSON.parse(n);}catch{e[o]=n;}}}else U().forEach((t,r)=>{if(r.startsWith(B())){let o=r.replace(B(),"");try{e[o]=JSON.parse(t);}catch{e[o]=t;}}});}catch(t){P(`Error listing store items: ${t}`);}return e}}});Object.freeze(h);});var Sr={};var St=x(()=>{a();T();w();d.db.create=(e,t=1)=>new Promise((r,o)=>{if(!d.db.support())return o(new Error("IndexedDB not supported"));let n=globalThis.indexedDB.open(e,t);n.onerror=()=>{c(`IndexedDB error: ${n.error?.message}`),o(n.error);},n.onsuccess=()=>{c(`Database ${e} connected successfully`),r(n.result);},n.onupgradeneeded=()=>{c(`Database ${e} upgrade/creation initiated`);};});});var wr={};var wt=x(()=>{a();T();d.db.list=async()=>{if(!("indexedDB"in globalThis)||!indexedDB.databases)return [];try{let e=await indexedDB.databases();return globalThis.idbases=e||[],await d.db.size(),globalThis.idbases}catch(e){return console.error("Error listing databases:",e),[]}};});var Er={};var Et=x(()=>{a();T();d.db.exist=e=>idbases?.some(t=>t.name===e);});var Tr={};var Tt=x(()=>{a();T();d.db.quota=()=>navigator.storage.estimate();});var Pr={};var Pt=x(()=>{a();T();w();d.db.delete=e=>new Promise((t,r)=>{c(`Removing database ${e}...`),(()=>{let n=indexedDB.deleteDatabase(e);n.onsuccess=()=>{c(`${e} database removed successfully`),d.db.list(),t();},n.onerror=()=>{console.error(`Error removing ${e}:`,n.error),r(n.error);},n.onblocked=()=>{console.warn(`Deletion of ${e} is blocked. Please close other tabs.`);};})();});});var _r={};var _t=x(()=>{a();T();w();d.db.size=async()=>{if(!(!idbases||idbases.length===0))for(let e=0;e<idbases.length;e++){let t=idbases[e];try{let r=await d.db.create(t.name,t.version),o=Array.from(r.objectStoreNames),n=0;for(let s of o){let i=await d.table.size(r,s);n+=i;}t.size=n,r.close();}catch(r){c(`Could not calculate size for ${t.name}:${r}`);}}};});var kr={};var kt=x(()=>{a();T();d.db.version=e=>{let t=0;for(let r of idbases){r.name===e&&(t=r.version);break}return t};});var Or={};var Ot=x(()=>{a();T();w();d.db.support=()=>{let e="indexedDB"in globalThis;return e||c("Your environment doesn't support IndexedDB"),e};});var qr={};var qt=x(()=>{a();T();w();d.table.create=(e,t)=>new Promise((r,o)=>{try{let s=(Number(d.db.version(e))||0)+1,i=indexedDB.open(e,s);i.onupgradeneeded=l=>{let g=l.target.result;if(!g.objectStoreNames.contains(t)){let b=g.createObjectStore(t,{keyPath:"id",autoIncrement:!0});b.createIndex("id","id",{unique:!0}),b.createIndex("data","data",{unique:!1}),c(`Table ${t} created in ${e}`);}},i.onsuccess=()=>{i.result.close(),d.db.list(),r();},i.onerror=()=>{console.error(`Error creating table ${t}:`,i.error),o(i.error);};}catch(n){console.error("Critical error in table.create:",n),o(n);}});});var Mr={};var Mt=x(()=>{a();T();w();d.table.size=(e,t)=>new Promise((r,o)=>{if(!e)return o(new Error("Database instance is required"));if(!e.objectStoreNames.contains(t))return r(0);let n=0,s=0,g=e.transaction([t],"readonly").objectStore(t).openCursor();g.onsuccess=async b=>{let v=b.target.result;if(v){try{let O=v.value;n+=JSON.stringify(O).length;}catch(O){c(`Error stringifying IDB value tracking size:${O}`);}s++,s%200===0&&await new Promise(O=>setTimeout(O,0)),v.continue();}else r(n);},g.onerror=()=>{o(g.error);};});});var $r={};var $t=x(()=>{a();T();w();d.data.delete=(e,t,r)=>new Promise((o,n)=>{let s=indexedDB.open(e);s.onsuccess=()=>{let i=s.result;if(!i.objectStoreNames.contains(t))return i.close(),n(new Error(`Table ${t} not found`));let b=i.transaction(t,"readwrite").objectStore(t).delete(r);b.onsuccess=()=>{i.close(),c(`Record ${r} deleted from ${t}`),o();},b.onerror=()=>{i.close(),n(b.error);};},s.onerror=()=>n(s.error);});d.data.delete.all=(e,t)=>new Promise((r,o)=>{let n=indexedDB.open(e);n.onsuccess=s=>{let i=s.target.result;if(!i.objectStoreNames.contains(t))return i.close(),o(new Error(`Table ${t} not found`));let b=i.transaction(t,"readwrite").objectStore(t).clear();b.onsuccess=()=>{i.close(),c(`All data cleared from ${t}`),r();},b.onerror=()=>{i.close(),o(b.error);};},n.onerror=()=>o(n.error);});});var Cr={};var Ct=x(()=>{a();T();w();d.data.set=(e,t,r)=>new Promise((o,n)=>{let s=indexedDB.open(e);s.onsuccess=()=>{let i=s.result;if(!i.objectStoreNames.contains(t))return i.close(),n(new Error(`Table ${t} does not exist in ${e}`));let b=i.transaction(t,"readwrite").objectStore(t).put(r);b.onsuccess=()=>{i.close(),c(`Data saved in ${e}.${t}`),o(b.result);},b.onerror=v=>{i.close(),c(`Database insert error: ${b.error?.message}`),n(b.error);};},s.onerror=()=>{n(s.error);};});});var jr={};var jt=x(()=>{a();T();d.data.get=(e,t,r)=>new Promise((o,n)=>{let s=indexedDB.open(e);s.onsuccess=i=>{let l=i.target.result;if(!l.objectStoreNames.contains(t))return l.close(),n(new Error(`Table ${t} not found in ${e}`));let v=l.transaction(t,"readonly").objectStore(t).get(r);v.onsuccess=()=>{l.close(),o(v.result);},v.onerror=()=>{l.close(),n(v.error);};},s.onerror=()=>{n(s.error);};});});var Dr,d,T=x(()=>{a();J();Dr=Oe(),d={db:{},table:{},data:{}};Dr?(async()=>(Object.defineProperty(d,"db",{value:{},writable:true,configurable:true}),Object.defineProperty(d,"table",{value:{},writable:true,configurable:true}),Object.defineProperty(d,"data",{value:{},writable:true,configurable:true}),Object.defineProperty(globalThis,"idbases",{value:[],writable:true,configurable:true,enumerable:false}),await Promise.all([Promise.resolve().then(()=>(St(),Sr)),Promise.resolve().then(()=>(wt(),wr)),Promise.resolve().then(()=>(Et(),Er)),Promise.resolve().then(()=>(Tt(),Tr)),Promise.resolve().then(()=>(Pt(),Pr)),Promise.resolve().then(()=>(_t(),_r)),Promise.resolve().then(()=>(kt(),kr)),Promise.resolve().then(()=>(Ot(),Or)),Promise.resolve().then(()=>(qt(),qr)),Promise.resolve().then(()=>(Mt(),Mr)),Promise.resolve().then(()=>($t(),$r)),Promise.resolve().then(()=>(Ct(),Cr)),Promise.resolve().then(()=>(jt(),jr))]),Object.preventExtensions(d),Object.seal(d),Object.freeze(d)))():(d._disabled=true,d._warning="IndexedDB is not available in this environment (Node.js/Deno). Use store or session for persistence.",console.warn("Memorio IDB: IndexedDB is not available in this environment. Use store or session for data persistence."));});var Nr={};function Ir(){let e=globalThis;return typeof e.document<"u"&&typeof e.document.createElement=="function"}function Lr(e){let t=globalThis;return t.__memorioSqlJsScript===e?Promise.resolve():(Ie||(Ie=new Promise((r,o)=>{if(t.initSqlJs&&typeof t.initSqlJs=="function"){t.__memorioSqlJsScript=e,r();return}if(!Ir()){o(new Error("memorio sqlite: no document available to load sql.js"));return}let n=t.document.createElement("script");n.src=e,n.async=true,n.onload=()=>{t.__memorioSqlJsScript=e,r();},n.onerror=()=>o(new Error(`memorio sqlite: failed to load sql.js from ${e}`)),t.document.head.appendChild(n);})),Ie)}var me,de,Dt,Ar,Rr,Ie,Jr,At=x(()=>{a();_();J();w();me=null,de=null,Dt="https://cdn.jsdelivr.net/npm/sql.js/dist/sql-wasm-browser.js",Ar=Dt.replace(/sql-wasm-browser\.js$/,""),Rr=e=>(globalThis.sqliteWasmBase||Ar)+e,Ie=null;Jr=async()=>{let e=globalThis;return typeof e.initSqlJs=="function"?e.initSqlJs:(await Lr(Dt),e.initSqlJs||e)};m.db.support=()=>re();m.db.getSQL=async()=>{if(de)return de;if(me)return me;let e=globalThis,t=e.sqliteConfig||{},r=(async()=>{if(typeof t.loader=="function")return await t.loader();let o=await Jr(),s=await(typeof o=="function"?o:o&&(o.default||o))({locateFile:t.locateFile||Rr});return e.sqliteVersion=s?.version||"sql.js",c("Memorio SQLite: sql.js engine loaded"),s})();me=r;try{return de=await r,de}catch(o){try{m._disabled=!0;}catch{}try{m._warning='Memorio SQLite: sql.js could not be loaded. Install sql.js (npm i sql.js) and configure a loader via sqlite.config({ loader: () => import("sql.js") }).';}catch{}throw console.warn("Memorio SQLite: failed to load sql.js",o),o}finally{me=null;}};m.db.version=()=>globalThis.sqliteVersion||null;});function Br(){let e=D.sqliteConfig||{};return e.namespace?`ns:${e.namespace}`:"default"}function Le(e){return `memorio:sqlite:db:${Br()}:${e}`}function Vr(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),r="",o=t.byteLength;for(let n=0;n<o;n++)r+=String.fromCharCode(t[n]);return typeof btoa=="function"?btoa(r):typeof Buffer<"u"?Buffer.from(t).toString("base64"):""}function Ur(e){if(typeof Buffer<"u")return new Uint8Array(Buffer.from(e,"base64"));if(typeof atob!="function")throw new Error("memorio sqlite: no base64 decoder available");let t=atob(e),r=t.length,o=new Uint8Array(r);for(let n=0;n<r;n++)o[n]=t.charCodeAt(n);return o}function fe(e){return new Promise(t=>{let r=D.__sqliteDbs&&D.__sqliteDbs[e];if(!r||typeof r.export!="function"){t(false);return}try{let o=r.export();h.set(Le(e),Vr(o)),c(`Memorio SQLite: persisted '${e}' to store`),t(!0);}catch(o){console.warn("Memorio SQLite: persist snapshot failed",o),t(false);}})}function Je(e){let t=h.get(Le(e));if(!t)return null;try{return Ur(t)}catch{return null}}function Hr(e){h.remove(Le(e));}function It(e,t){if(!(!t||typeof t.updateHook!="function")){Rt[e]=true;try{t.updateHook(()=>{K[e]&&clearTimeout(K[e]),K[e]=setTimeout(()=>{K[e]=null,fe(e);},250);});}catch(r){console.warn("Memorio SQLite: could not attach updateHook",r);}}}var D,Rt,K,Lt=x(()=>{a();_();G();w();D=globalThis,Rt={},K={};m.db.persist=async(e="memorio")=>fe(e);m.db.download=async(e="memorio",t=`${e}.sqlite`)=>{let r=globalThis;if(!(r.__sqliteDbs&&r.__sqliteDbs[e]))return console.warn(`Memorio SQLite: cannot download '${e}' \u2014 database not found. Create it with sqlite.db.create('${e}').`),false;let n;try{n=await m.db.export(e);}catch(g){return console.warn("Memorio SQLite: export failed during download",g),false}if(!n)return false;if(typeof r.document>"u"||typeof r.Blob>"u")return console.warn("Memorio SQLite: sqlite.db.download() requires a browser environment."),false;let s=r.URL||r.webkitURL;if(!s||typeof s.createObjectURL!="function")return false;let i=s.createObjectURL(new Blob([n],{type:"application/x-sqlite3"})),l=r.document.createElement("a");return l.style.display="none",l.href=i,l.download=t,r.document.body.appendChild(l),l.click(),setTimeout(()=>{try{s.revokeObjectURL(i);}catch{}l.remove();},1e3),true};m.db.close=async(e="memorio")=>{let t=D.__sqliteDbs&&D.__sqliteDbs[e];if(t&&typeof t.close=="function"){try{await fe(e);}catch{}try{t.close();}catch(r){console.warn("Memorio SQLite: close failed",r);}}if(D.__sqliteDbs&&delete D.__sqliteDbs[e],D.sqlbases){let r=D.sqlbases.findIndex(o=>o&&o.name===e);r>-1&&D.sqlbases.splice(r,1);}delete Rt[e],K[e]&&(clearTimeout(K[e]),K[e]=null),Hr(e);};m.db.loadSnapshot=Je;m.db.saveSnapshot=fe;});var zr={};var Jt=x(()=>{a();_();w();Lt();m.db.create=async(e="memorio",t={})=>{let r=await m.db.getSQL(),o=globalThis,n=!!(t&&t.persistence)||!!(o.sqliteConfig&&o.sqliteConfig.persistence),s;if(n&&!t.data){let v=Je(e);v&&(s=v);}let i=t&&t.data||s,l;i&&typeof i.byteLength=="number"?(l=new r.Database(i),c(`Memorio SQLite: database '${e}' opened (persistence=${n})`)):(l=new r.Database,c(`Memorio SQLite: database '${e}' created (persistence=${n})`));let g={...t,persistence:n};o.__sqliteDbs||(o.__sqliteDbs={}),o.__sqliteDbs[e]=l,o.sqlbases||(o.sqlbases=[]);let b=o.sqlbases.findIndex(v=>v&&v.name===e);return b>-1?o.sqlbases[b]={name:e,db:l,persistence:g.persistence}:o.sqlbases.push({name:e,db:l,persistence:g.persistence}),n&&It(e,l),l};});var Qr={};var Nt=x(()=>{a();_();m.db.get=(e="memorio")=>{let t=globalThis.__sqliteDbs;if(!t||!t[e])throw new Error(`SQLite database '${e}' does not exist. Create it with sqlite.db.create('${e}').`);return t[e]};});var Kr={};var Bt=x(()=>{a();_();w();m.db.delete=e=>{let t=globalThis.__sqliteDbs;if(!t||!t[e])return false;try{t[e].close();}catch{}delete t[e];let r=globalThis;return r.sqlbases&&(r.sqlbases=r.sqlbases.filter(o=>o&&o.name!==e)),c(`Memorio SQLite: database '${e}' deleted`),true};});var Wr={};var Vt=x(()=>{a();_();m.db.list=()=>{let e=globalThis.__sqliteDbs;return e?Object.keys(e):[]};});var Fr={};var Ut=x(()=>{a();_();m.db.size=async e=>{let t=globalThis.__sqliteDbs;if(!t)return 0;let r=n=>n&&(n.byteLength||n.length)||0;if(e){let n=m.db.get(e);return r(n.export())}let o=0;for(let n of Object.keys(t))try{o+=r(t[n].export());}catch{}return o};});var Gr={};var Ht=x(()=>{a();_();m.db.export=async(e="memorio")=>m.db.get(e).export();});var Yr={};var zt=x(()=>{a();_();m.db.import=async(e,t)=>m.db.create(e,{data:t});});var Xr={};var Qt=x(()=>{a();_();w();m.query.run=async(e="memorio",t,r=[])=>{let o=m.db.get(e);return c(`Memorio SQLite: run -> ${t}`),o.run(t,r),o.getRowsModified()};});var Zr={};var Kt=x(()=>{a();_();m.query.select=async(e="memorio",t,r=[])=>{let n=m.db.get(e).prepare(t,r),s=[];try{for(;n.step();)s.push(n.getAsObject());}finally{try{n.free();}catch{}}return s};});var eo={};var Wt=x(()=>{a();_();m.data.set=async(e="memorio",t,r=[])=>m.query.run(e,t,r);});var to={};var Ft=x(()=>{a();_();m.data.get=async(e="memorio",t,r=[])=>{let o=await m.query.select(e,t,r);return o.length?o[0]:null};});var ro,m,_=x(()=>{a();J();ro=re(),m={db:{},query:{},data:{}};m.config=e=>{let t=globalThis;return t.sqliteConfig={...t.sqliteConfig,...e},e&&e.wasmUrl&&(t.sqliteWasmBase=e.wasmUrl.endsWith("/")?e.wasmUrl:e.wasmUrl+"/"),m};Object.defineProperty(m,"ready",{enumerable:false,configurable:false,get:()=>{let e=globalThis;return e.sqliteReady||(e.sqliteReady=typeof m.db.getSQL=="function"?m.db.getSQL().then(()=>{}).catch(()=>{}):Promise.resolve()),e.sqliteReady}});ro?(async()=>(Object.defineProperty(m,"db",{value:{},writable:false,configurable:true,enumerable:true}),Object.defineProperty(m,"query",{value:{},writable:false,configurable:true,enumerable:true}),Object.defineProperty(m,"data",{value:{},writable:false,configurable:true,enumerable:true}),Object.defineProperty(globalThis,"sqlbases",{value:[],writable:true,configurable:true,enumerable:false}),await Promise.all([Promise.resolve().then(()=>(At(),Nr)),Promise.resolve().then(()=>(Jt(),zr)),Promise.resolve().then(()=>(Nt(),Qr)),Promise.resolve().then(()=>(Bt(),Kr)),Promise.resolve().then(()=>(Vt(),Wr)),Promise.resolve().then(()=>(Ut(),Fr)),Promise.resolve().then(()=>(Ht(),Gr)),Promise.resolve().then(()=>(zt(),Yr)),Promise.resolve().then(()=>(Qt(),Xr)),Promise.resolve().then(()=>(Kt(),Zr)),Promise.resolve().then(()=>(Wt(),eo)),Promise.resolve().then(()=>(Ft(),to))])))():(globalThis.sqliteDisabled=true,globalThis.sqliteWarning='SQLite (sql.js) is not available in this environment. It requires a browser with WebAssembly support. Install the optional "sql.js" package to enable it.',m._disabled=true,m._warning=globalThis.sqliteWarning,console.warn("Memorio SQLite: sql.js is not available in this environment (requires browser + WebAssembly). Use store or session for persistence."));});a();a();$();w();a();var E={set:(e,t={})=>{globalThis.dispatchEvent(new CustomEvent(String(e),t));},listen:(e,t=null,r)=>{if(globalThis.events?.[e])return;let o=t?n=>{let s=n;return globalThis.queueMicrotask?globalThis.queueMicrotask(()=>t(s)):Promise.resolve().then(()=>t(s))}:void 0;o&&globalThis.addEventListener(e,o),o&&(globalThis.events[e]=o);},remove:e=>{let t=globalThis.events?.[e];t&&(globalThis.removeEventListener(e,t),delete globalThis.events[e]);}};a();w();var F=new Map,dt=(e,t,r)=>{let o=[];if(t.type&&t.type!=="any"){let n=Array.isArray(e)?"array":typeof e;if(n!==t.type)return o.push(`${r}: expected ${t.type}, got ${n}`),{valid:false,errors:o}}if(t.enum&&!t.enum.includes(e)&&o.push(`${r}: value must be one of [${t.enum.map(String).join(", ")}]`),t.validator){let n=t.validator(e);n!==true&&o.push(`${r}: ${typeof n=="string"?n:"validation failed"}`);}if(typeof e=="number"&&(t.min!==void 0&&e<t.min&&o.push(`${r}: value ${e} is less than minimum ${t.min}`),t.max!==void 0&&e>t.max&&o.push(`${r}: value ${e} exceeds maximum ${t.max}`)),typeof e=="string"&&(t.min!==void 0&&e.length<t.min&&o.push(`${r}: string length ${e.length} is less than minimum ${t.min}`),t.max!==void 0&&e.length>t.max&&o.push(`${r}: string length ${e.length} exceeds maximum ${t.max}`),t.pattern&&!t.pattern.test(e)&&o.push(`${r}: string does not match required pattern`)),t.type==="object"&&e&&typeof e=="object"&&!Array.isArray(e)){if(t.required)for(let n of t.required)n in e||o.push(`${r}: missing required property '${n}'`);if(t.properties){for(let[n,s]of Object.entries(t.properties))if(n in e&&e[n]!==void 0){let i=dt(e[n],s,`${r}.${n}`);i.valid||o.push(...i.errors||[]);}}}return o.length===0?{valid:true}:{valid:false,errors:o}},ft=(e,t)=>{let r=F.get(e);return r?dt(t,r,e):{valid:true}},pt=(e,t)=>{typeof t=="function"?F.set(e,{validator:t}):F.set(e,t),c(`[memorio schema] Registered schema for '${e}'`);},yt=e=>F.delete(e),gt=()=>Array.from(F.keys()),fr=e=>F.get(e),L={register:pt,validate:ft,unregister:yt,list:gt,get:fr};var le=Symbol("memorio.target"),bt=new WeakMap,R=(e,t=null)=>{if(e===null||typeof e!="object")return e;if(e[le]!==void 0)return R(e[le],t);if(t){if(t.has(e))return e;t.add(e);}let r=e.constructor?.name;if(r!=="Object"&&r!=="Array")return e;let o=Array.isArray(e)?[]:{};for(let n of Reflect.ownKeys(e))o[n]=R(e[n],t);return o},ht=(e,t,r=".")=>t.concat(e).join(r),vt=(e,t,r=[])=>{let o=n=>{try{E.set(n,{detail:{name:n}});}catch{}};return new Proxy(e,{get(n,s){if(s==="__path")return r.length>0?"state."+r.join("."):"state";if(s===le||n[le]!==void 0)return n;if(s==="list")return c('Some state could be hidden when you use "state.list". Use "state" to see the complete list '),JSON.parse(JSON.stringify(n));if(typeof s=="string"){let i=r.length>0?"state."+r.concat(s).join("."):"state."+s;u.lastAccessedPath=i,u.tracking&&u.trackedPaths.add(i);}if(s==="_lastPath")return u.lastAccessedPath;if(s==="remove")return i=>(delete n[i],true);if(s==="removeAll")return ()=>{try{for(let i in n)typeof n[i]!="function"&&!["list","remove","removeAll","lock","unlock"].includes(i)&&delete n[i];}catch(i){console.error(i);}};if(Object.isFrozen(n[s]))return n[s];if(s==="lock"||s==="unlock"){let i=Reflect.get(n,s);if(i)return i}try{let i=Reflect.get(n,s);if(i&&typeof i=="object"&&["Array","Object"].includes(i.constructor.name)){let l=bt.get(i);return l||(l=vt(i,t,r.concat(s)),bt.set(i,l)),l}return i}catch(i){console.error("Error: ",i);return}},set(n,s,i){if(u.locked)return console.error("Error: state is locked. Use state.unlock() to enable modifications."),false;if(mt.includes(s))return console.error("key "+s+" is protected"),false;if(n[s]&&typeof n[s]=="object"&&Object.isFrozen(n[s]))return console.error(`Error: state '${s}' is locked`),false;if(n[s]&&typeof n[s]=="object"&&n[s].__locked)return console.error(`Error: state '${s}' is locked. Use state.${s}.unlock() to enable modifications.`),false;try{let l=ht(s,r),g=R(i),b=L.validate(l,g);if(!b.valid)return u.debug&&console.error(`[memorio schema] Validation failed for '${l}':`,b.errors),c(`[memorio schema] Validation failed for '${l}': `+(b.errors?.join(", ")||"unknown error")),!1;if(t({action:"set",path:l,target:n,newValue:g,previousValue:Reflect.get(n,s)}),o("state."+l),Reflect.set(n,s,g),u.bumpStateVersion(),n[s]&&typeof n[s]=="object"){let v=n[s];if(v&&typeof v=="object")try{Object.defineProperty(v,"__locked",{writable:!0,enumerable:!1,configurable:!1,value:!1}),Object.defineProperty(v,"lock",{writable:!1,enumerable:!1,configurable:!1,value:()=>{Object.defineProperty(v,"__locked",{writable:!0,enumerable:!1,configurable:!1,value:!0}),c(`State '${s}' is now locked.`);}}),Object.defineProperty(v,"unlock",{writable:!1,enumerable:!1,configurable:!1,value:()=>{Object.defineProperty(v,"__locked",{writable:!0,enumerable:!1,configurable:!1,value:!1}),c(`State '${s}' is now unlocked.`);}});}catch{}}return !0}catch(l){return console.error("Error in set trap:",l),false}},deleteProperty(n,s){try{let i=ht(s,r),l=Reflect.get(n,s);return t({action:"delete",path:i,target:n,previousValue:l}),Reflect.deleteProperty(n,s)}catch(i){return console.error("Error in deleteProperty trap:",i),false}},ownKeys(n){return Reflect.ownKeys(n)},getOwnPropertyDescriptor(n,s){return Reflect.getOwnPropertyDescriptor(n,s)}})},S=vt({},e=>{u.historyEnabled&&u.recordMutation({path:e.path,action:e.action,newValue:e.newValue,previousValue:e.previousValue,timestamp:Date.now()});});S.lock=()=>{u.locked=true,c("State is now locked. All modifications are blocked.");};S.unlock=()=>{u.locked=false,c("State is now unlocked. Modifications are allowed.");};G();a();J();$();w();var M=_e(),Ae=new Map;function Q(){let t=u.currentContext||""||"default";return Ae.has(t)||Ae.set(t,new Map),Ae.get(t)}var z=M!==null;function H(){let e=u.currentContext||"";return e?`${e}-`:"memorio_session_"}function Re(e){return !e||typeof e!="string"?(console.warn("[memorio session] key is empty or not a string - operation aborted"),""):e.length>512?(console.warn(`[memorio session] key "${e}" exceeds 512 chars - operation aborted`),""):H()+e}function hr(e){let t=z?M.getItem(e):Q().get(e);return t&&JSON.parse(t)}function vr(e,t){let r=JSON.stringify(t);z?M.setItem(e,r):Q().set(e,r);}function xr(e){if(z){if(M.getItem(e))return M.removeItem(e),true}else if(Q().has(e))return Q().delete(e),true;return false}var C=new Proxy({},{});Object.defineProperty(globalThis,"session",{value:C,enumerable:false,configurable:true});Object.defineProperties(C,{get:{value:e=>{if(!e)return console.warn("[memorio session] session.get() called with empty or null key - returning null"),null;try{return hr(Re(e))}catch(t){P(`Error parsing session item '${e}':${t}`);}return null}},set:{value:(e,t)=>{if(!e)return console.warn("[memorio session] session.set() called with empty or null key - write aborted"),false;let r=Re(e);if(!r)return false;if(typeof t=="function")return console.warn("[memorio session] functions are not storable - write aborted for key: "+e),P("It's not secure to session functions."),false;try{vr(r,t);}catch(o){return P(`Error setting session item '${e}': ${o}`),false}return true}},remove:{value:e=>{if(!e)return console.warn("[memorio session] session.remove() called with empty or null key - returning false"),false;let t=Re(e);if(!t)return false;try{return xr(t)}catch(r){P(`Error removing session item '${e}': ${r}`);}return false}},delete:{value:e=>C.remove(e)},removeAll:{value:()=>{if(z){let e=[];for(let t=0;t<M.length;t++){let r=M.key(t);r?.startsWith(H())&&e.push(r);}e.forEach(t=>M.removeItem(t));}else Q().clear();return true}},clearAll:{value:()=>(C.removeAll(),true)},quota:{value:async()=>[0,0]},size:{value:()=>{let e=0;return z?Object.keys(M).forEach(t=>{if(t.startsWith(H())){let r=M.getItem(t);r&&(e+=r.length);}}):Q().forEach(t=>{e+=t.length;}),e}},isPersistent:{get:()=>z},list:{value:()=>{let e={};try{if(z)for(let t=0;t<M.length;t++){let r=M.key(t);if(r?.startsWith(H())){let o=r.replace(H(),""),n=M.getItem(r);if(n!==null)try{e[o]=JSON.parse(n);}catch{e[o]=n;}}}else Q().forEach((t,r)=>{if(r.startsWith(H())){let o=r.replace(H(),"");try{e[o]=JSON.parse(t);}catch{e[o]=t;}}});}catch(t){P(`Error listing session items: ${t}`);}return e}}});Object.freeze(C);a();var j={},ue=new Proxy({},{get(e,t){let r=t;return r==="get"?o=>j[o]:r==="set"?(o,n)=>{j[o]=n;}:r==="remove"?o=>(delete j[o],true):r==="removeAll"?()=>(Object.keys(j).forEach(o=>delete j[o]),true):r==="clear"?()=>(Object.keys(j).forEach(o=>delete j[o]),true):r==="list"?()=>({...j}):j[r]},set(e,t,r){return j[t]=r,true},deleteProperty(e,t){return delete j[t],true}});Object.freeze(ue);T();_();a();w();var oo=(e,t=null,r=true)=>{let o=s=>typeof s=="string"?s:s&&typeof s=="object"&&s.__path?s.__path:null,n=o(e);if(!e&&!t){console.error("Observer Error: You need to setup observer correctly, Some parameters are missed!");return}if(!e&&t){console.error("Observer Error: You need to declare what state need to be monitored as string like 'state.test'.");return}if(n){let s=n.split(".");if(s[0]!=="state"&&s[0]!=="store"){console.error(`Observer Error: You need to declare 'state.' or 'store.'. The '${n}' string is incorrect!`);return}}if(e&&!t){let s=o(e);if(!s)return;globalThis.observer?.list?.[s]&&E.remove(s),c(`called: ${s}`);return}if(e&&t){let s=o(e);if(!s)return;if(typeof e!="string"&&!(e&&typeof e=="object")){console.error("Observer Error: name of state need to be a 'string' like 'state.test' or a direct state value");return}let i=Array.isArray(t)?t:[t];globalThis.observer?.list?.[s]&&E.remove(s),i.forEach(g=>{typeof g=="function"&&E.listen(s,g,r);});return}},pe=oo;Object.defineProperties(pe,{list:{get:()=>globalThis.events},remove:{value:e=>{e&&(E.remove(e),delete globalThis.events[e]);}},removeAll:{get:()=>{let e=globalThis.observer,t=e?.list;return t&&Object.keys(t).forEach(r=>{e?.remove?.(r);}),true}},has:{value:e=>!!globalThis.observer?.list?.[e]}});a();w();$();globalThis.useObserver||(globalThis.useObserver=null);Object.defineProperty(globalThis,"useObserver",{value:null,writable:true,enumerable:false,configurable:true});var ye=((e,t=[])=>{if(!t||typeof e!="function")return ()=>{};let r=[],o=Array.isArray(t)&&!t.__path?t:[t];try{return o.forEach(n=>{let s="";if(typeof n=="function"){let i=Se(n);i&&(s=i);}else typeof n=="object"&&n!==null&&(s=n.__path||(typeof n.toString=="function"&&n.toString()!=="[object Object]"?n.toString():""));if(s){s=s.replace(/^(\(\)\s*=>\s*)/,"").replace(/^globalThis\./,"").replace(/^state\./,"");let i=s.startsWith("store.")||s.startsWith("state.")?s:"state."+s;E.listen(i,()=>e()),r.push(i);}else {u.clearTrackedPaths(),u.tracking=!0;try{e();}catch{}u.tracking=!1,u.trackedPaths.forEach(i=>{r.includes(i)||(c(`useObserver: [Auto-Discovery] -> "${i}"`),E.listen(i,()=>e()),r.push(i));});}}),r.length>0?c(`useObserver: Monitoring ${r.length} paths.`):console.warn("useObserver: No paths resolved for monitoring. Check your dependencies!"),()=>{r.forEach(n=>{typeof E.remove=="function"&&(E.remove(n),c(`useObserver: Stopped monitoring "${n}"`));});}}catch(n){return c(`useObserver Error: ${n}`),()=>{}}});globalThis.useObserver=ye;Object.freeze(globalThis.useObserver);w();a();$();function no(){return u.debug===true}function Gt(){if(!globalThis.store)return {};let e={},t=globalThis.store;if(typeof t.list=="function")try{return t.list()}catch{}if(typeof t.get=="function"){for(let r of Object.keys(t))if(!["get","set","remove","delete","removeAll","clearAll","size","isPersistent","list"].includes(r))try{let o=t.get(r);o!=null&&(e[r]=o);}catch{}}return e}function Yt(){if(!globalThis.session)return {};let e={},t=globalThis.session;if(typeof t.list=="function")try{return t.list()}catch{}if(typeof t.get=="function"){for(let r of Object.keys(t))if(!["get","set","remove","delete","removeAll","clearAll","size","isPersistent","list"].includes(r))try{let o=t.get(r);o!=null&&(e[r]=o);}catch{}}return e}var so=()=>{if(no()){if(globalThis.state){let e=globalThis.state.list,t;typeof e=="function"?t=e():typeof e=="object"&&e!==null?t=e:t=globalThis.state,console.table(t);}if(globalThis.store&&console.table(Gt()),globalThis.session&&console.table(Yt()),globalThis.cache){let e=globalThis.cache.list,t;typeof e=="function"?t=e():typeof e=="object"&&e!==null?t=e:t=globalThis.cache,console.table(t);}}},io=()=>{let e=t=>{if(!t)return 0;if(typeof t.list=="function")try{let r=t.list();return Object.keys(r).length}catch{}return Object.keys(t).length};return {stateKeys:e(globalThis.state),storeKeys:e(globalThis.store),sessionKeys:e(globalThis.session),cacheKeys:e(globalThis.cache),idbDatabases:0,sqliteDbCount:typeof globalThis.sqlite?.db?.list=="function"?globalThis.sqlite.db.list().length:(globalThis.sqlbases||[]).length,lastUpdate:new Date().toISOString()}},se=e=>{globalThis[e]&&typeof globalThis[e].clear=="function"?globalThis[e].clear():console.error(`Module ${e} not found or does not support clear()`);},ao=()=>{se("state"),se("store"),se("session"),se("cache");},lo=()=>{let e=()=>{if(globalThis.state)try{return typeof globalThis.state.list=="function"?globalThis.state.list():globalThis.state}catch{return}},t=()=>Gt(),r=()=>Yt(),o=()=>{if(globalThis.cache)try{return typeof globalThis.cache.list=="function"?globalThis.cache.list():globalThis.cache}catch{return}},n={state:e(),store:t(),session:r(),cache:o(),exportedAt:new Date().toISOString()};return JSON.stringify(n,null,2)},co=e=>{try{let t=JSON.parse(e);t.state&&Object.entries(t.state).forEach(([r,o])=>{globalThis.state&&r!=="list"&&r!=="remove"&&r!=="removeAll"&&(globalThis.state[r]=o);}),t.store&&globalThis.store&&typeof globalThis.store.set=="function"&&Object.entries(t.store).forEach(([r,o])=>{globalThis.store.set(r,o);}),t.session&&globalThis.session&&typeof globalThis.session.set=="function"&&Object.entries(t.session).forEach(([r,o])=>{globalThis.session.set(r,o);}),t.cache&&globalThis.cache&&Object.entries(t.cache).forEach(([r,o])=>{globalThis.cache&&r!=="get"&&r!=="set"&&r!=="remove"&&r!=="clear"&&(globalThis.cache[r]=o);});}catch(t){console.error("%c\u2717 Import failed:","color: #F44336",t);}},uo=(e,t)=>{if(!globalThis[e]){console.error(`Module ${e} not found`);return}let r=globalThis[e],o=r[t];if(console.debug(`\u{1F441} Watching ${e}.${t} (initial: ${JSON.stringify(o)})`),e==="state"&&globalThis.memorio?.dispatch){let n=s=>{s.detail?.name?.includes(t)&&console.debug(`\u{1F441} Change: ${e}.${t} =`,s.detail.value);};r.addEventListener?.("memorio-change",n);}},mo=()=>{console.debug(`
|
|
5
5
|
\u{1F9E0} Memorio DevTools Help
|
|
6
6
|
|
|
7
7
|
Available commands:
|
|
@@ -19,10 +19,11 @@ Shortcuts:
|
|
|
19
19
|
store - globalThis.store
|
|
20
20
|
session - globalThis.session
|
|
21
21
|
cache - globalThis.cache
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
color: inherit`),s!==void 0&&c(` \u2192 value:${s}`),o!==void 0&&c(` \u2190 previous:${o}`);}R.customHandler&&R.customHandler(n);},dr=e=>({state:"#4CAF50",store:"#2196F3",session:"#FF9800",cache:"#9C27B0",idb:"#F44336"})[e]||"#888888",fr=()=>[...j],pr=()=>{j.length=0;},gr=()=>{let e={total:j.length,state:0,store:0,session:0,cache:0,idb:0,set:0,get:0,delete:0,clear:0};for(let t of j)if(t){let r=t.module,s=t.action;r&&typeof e[r]=="number"&&e[r]++,s&&typeof e[s]=="number"&&e[s]++;}return e},yr=()=>JSON.stringify(j,null,2),Te={configure:lr,enable:cr,disable:ur,isEnabled:yt,log:mr,getHistory:fr,clearHistory:pr,getStats:gr,exportLogs:yr};C();K();a();K();C();var re={version:"4.7.3"};E();x();a();function ke(){return h}a();C();x();function bt(e){if(e===null||typeof e!="object")return e;let t=e.constructor?.name;if(t!=="Object"&&t!=="Array")return e;try{return JSON.parse(JSON.stringify(e))}catch{return e}}var Oe=()=>bt(A(h)),Ce=e=>{let t=[],r=(s,o,n)=>{let i=s?Object.keys(s):[],d=o?Object.keys(o):[];for(let f of d){let y=n?`${n}.${f}`:f,b=s?s[f]:void 0,k=o[f];b!==k&&(typeof b!==typeof k||b===void 0?t.push({path:y,oldValue:b,newValue:k}):b&&typeof b=="object"?r(b,k,y):b!==k&&t.push({path:y,oldValue:b,newValue:k}));}for(let f of i)if(!(f in(o||{}))){let y=n?`${n}.${f}`:f;t.push({path:y,oldValue:s[f],newValue:void 0});}};return r(e,A(h),""),t},_e=(e=true)=>{l.historyEnabled=e,c(`[memorio history] Tracking ${e?"enabled":"disabled"}`);};var $e=()=>[...l.mutations],De=()=>l.canUndo(),Re=()=>l.canRedo(),Ae=()=>{if(!l.historyEnabled){c("[memorio history] History is not enabled");return}let e=l.popUndo();if(e)return hr(e),c(`[memorio history] Undid: ${e.action} ${e.path}`),e},Me=()=>{if(!l.historyEnabled){c("[memorio history] History is not enabled");return}let e=l.popRedo();if(e)return vr(e),c(`[memorio history] Redid: ${e.action} ${e.path}`),e};function hr(e){let t=l.historyEnabled;l.historyEnabled=false;try{e.action==="set"?e.previousValue===void 0?ht(e.path):Pe(e.path,e.previousValue):e.action==="delete"&&e.previousValue!==void 0&&Pe(e.path,e.previousValue);}finally{l.historyEnabled=t;}}function vr(e){let t=l.historyEnabled;l.historyEnabled=false;try{e.action==="set"?Pe(e.path,e.newValue):e.action==="delete"&&ht(e.path);}finally{l.historyEnabled=t;}}function Pe(e,t){let r=e.split("."),s=h;for(let o=0;o<r.length-1;o++){let n=r[o];s[n]===void 0&&(s[n]={}),s=s[n];}s[r[r.length-1]]=t;}function ht(e){let t=e.split(".");if(t.length===1){h.remove(t[0]);return}let r=h;for(let s=0;s<t.length-1;s++){let o=t[s];if(r[o]===void 0)return;r=r[o];}delete r[t[t.length-1]];}var je=e=>{h.removeAll();for(let t of Object.keys(e))h[t]=bt(e[t]);l.clearHistory(),c("[memorio history] State rolled back to snapshot");},Ie=()=>{l.clearHistory(),c("[memorio history] History cleared");},Ne=()=>{l.clearRedo();};a();var Ve=()=>{let e=A(h);return Object.keys(e).filter(t=>!["list","remove","removeAll","lock","unlock"].includes(t))},Be=e=>{if(!e||typeof e!="string")return false;let t=e.replace(/^state\./,"").split("."),r=h;for(let s of t){if(r==null)return false;r=r[s];}return r!==void 0},Le=e=>{let[t,r]=vt(e);return !t||r===void 0?"undefined":Array.isArray(r)?"array":typeof r},He=e=>{let[t,r]=vt(e);if(!(!t||r===void 0))return xr(r)},Je=()=>{let e=[],t=(r,s)=>{if(r===null||typeof r!="object"||Array.isArray(r))return;let o=Object.keys(r).filter(n=>!["list","remove","removeAll","lock","unlock"].includes(n));for(let n of o){let i=s?`${s}.${n}`:n,d=r[n],f=d!==void 0,y=f?Array.isArray(d)?"array":typeof d:"undefined";e.push({path:i,type:y,defined:f}),f&&typeof d=="object"&&!Array.isArray(d)&&d.constructor?.name==="Object"&&t(d,i);}};return t(A(h),""),e};function vt(e){if(!e||typeof e!="string")return [false,void 0];let t=e.replace(/^state\./,"").split("."),r=h;for(let s of t){if(r==null)return [false,void 0];r=r[s];}return [r!==void 0,r]}function xr(e){if(e===null||typeof e!="object")return e;let t=e.constructor?.name;if(t!=="Object"&&t!=="Array")return e;try{return JSON.parse(JSON.stringify(e))}catch{return e}}a();E();var se="__memorio_memory_index__",xt="__memorio_superseded__";function ze(e){return e.startsWith(xt)?e:`${xt}${e}`}function St(e){return e?Array.isArray(e)?e:[e]:[]}function Sr(e,t){if(t.scope)return t.scope;let r=JSON.stringify(e).length;return r>1e6?"durable":("local")}function $(){return Date.now()}function ne(e){return e.ttl===null||e.ttl===void 0?false:$()-e.createdAt>e.ttl}function wr(e,t){return e.status==="obsolete"||e.status==="superseded"||ne(e)?t.includeObsolete??false:!(t.type&&!(Array.isArray(t.type)?t.type:[t.type]).includes(e.type)||t.minConfidence!==void 0&&e.confidence<t.minConfidence)}function Er(e,t){return !(e.status!=="active"||ne(e)||t.tags&&!(Array.isArray(t.tags)?t.tags:[t.tags]).some(o=>e.tags.includes(o))||t.types&&!(Array.isArray(t.types)?t.types:[t.types]).includes(e.type)||t.minConfidence!==void 0&&e.confidence<t.minConfidence||t.scopes&&!t.scopes.includes(e.scope))}function Tr(e){let t=($()-e.createdAt)/36e5,r=Math.max(.1,1/(1+t*.5)),s=e.confidence,o=1+e.tags.length*.1,n={decision:1.5,context:1.3,preference:1.2,task:1,fact:.8},i={hot:1.5,session:1.2,local:1,durable:.8};return r*s*o*n[e.type]*i[e.scope]}function Et(e,t){if(!t||typeof t!="string")return;let r=t.replace(/^state\./,"").split("."),s=e;for(let o of r){if(s==null)return;s=s[o];}return s}function Tt(e,t,r){if(!t||typeof t!="string")return;let s=t.replace(/^state\./,"").split("."),o=e;for(let n=0;n<s.length-1;n++){let i=s[n];(o[i]===void 0||o[i]===null)&&(o[i]={}),o=o[i];}o[s[s.length-1]]=r;}async function J(e){let t=e.status==="superseded"?ze(e.id||e.key):e.key,r=JSON.stringify(e);switch(e.scope){case "hot":Tt(h,t,e.value);break;case "session":_.set(t,r);break;case "local":w.set(t,r);break;case "durable":await u.set("memories",t,r);break}await kr(e.id||e.key,e.scope,e.status==="superseded");}async function kt(e,t,r=false){let s=r?ze(e):e,o;switch(t){case "hot":{let n=Et(h,s);return n===void 0?null:Pt(e,n,t)}case "session":o=_.get(s);break;case "local":o=w.get(s);break;case "durable":o=await u.get("memories",s);break}if(!o)return null;try{let n=JSON.parse(o);return n.id=n.id||e,n}catch{return null}}function Pt(e,t,r){return {id:e,key:e,value:t,type:"fact",confidence:1,scope:r,ttl:null,tags:[],status:"active",createdAt:$(),lastConfirmedAt:$(),supersededId:null}}async function wt(e,t,r=false){let s=r?ze(e):e;switch(t){case "hot":Tt(h,s,void 0);break;case "session":_.remove(s);break;case "local":w.remove(s);break;case "durable":await u.deleteKey("memories",s);break}await Pr(e,r);}async function Y(){try{let e=w.get(se);return e?JSON.parse(e):{}}catch{return {}}}async function kr(e,t,r=false){let s=await Y();s[e]={scope:t,superseded:r},w.set(se,JSON.stringify(s));}async function Pr(e,t=false){let r=await Y(),s=r[e];s&&(t&&s.superseded||!t&&!s.superseded)&&delete r[e],w.set(se,JSON.stringify(r));}async function oe(){let e=await Y(),t=[];for(let[r,s]of Object.entries(e)){let o=await kt(r,s.scope,s.superseded);o&&(o.id=o.id||r,o.supersededId=o.supersededId??null,t.push(o));}return t}async function Or(){let e=await oe(),t=0;for(let r of e)ne(r)&&r.status==="active"&&(r.status="obsolete",await J(r),t++);return t}var ie={async remember(e,t,r={}){let s=await this._getEntry(e);if(s&&s.status==="active"){let d=`${s.id}__v${Date.now()}`,f={...s,id:d,key:s.key,status:"superseded",supersededId:null,lastConfirmedAt:$()};await J(f);}let o=Sr(t,r),n=St(r.tags),i={id:r.id||e,key:e,value:t,type:r.type||"fact",confidence:r.confidence??1,scope:o,ttl:r.ttl??null,tags:n,source:r.source,status:"active",createdAt:$(),lastConfirmedAt:$(),supersededId:s?s.id:null};await J(i),v.set("memorio:memory:remembered",{key:e,scope:o,entryId:i.id});},async recall(e,t={}){let r=await this._getEntry(e);return !r||!wr(r,t)?null:(r.lastConfirmedAt=$(),await J(r),v.set("memorio:memory:recalled",{key:e}),r.value)},async context(e={}){return (await oe()).filter(o=>Er(o,e)).map(o=>({entry:o,score:Tr(o)})).sort((o,n)=>n.score-o.score).slice(0,e.maxEntries??25).map(({entry:o})=>({key:o.key,value:o.value,type:o.type,confidence:o.confidence,scope:o.scope,tags:o.tags,age:$()-o.createdAt,accessCount:o.tags.length+1,lastAccessedAt:o.lastConfirmedAt}))},async forget(e){let t=await this._getEntry(e);t&&(await wt(t.id||e,t.scope,t.status==="superseded"),v.set("memorio:memory:forgotten",{key:e}));},async update(e,t,r={}){let s=await this._getEntry(e);if(!s){await this.remember(e,t,r);return}let o=`${s.id}__v${$()}`,n={...s,id:o,key:s.key,status:"superseded",supersededId:null,lastConfirmedAt:$()};await J(n);let i={...s,value:t,lastConfirmedAt:$(),...r.scope?{scope:r.scope}:{},...r.ttl!==void 0?{ttl:r.ttl}:{},...r.type?{type:r.type}:{},...r.confidence!==void 0?{confidence:r.confidence}:{},...r.tags!==void 0?{tags:St(r.tags)}:{},...r.source?{source:r.source}:{}};await J(i),v.set("memorio:memory:updated",{key:e,entryId:i.id});},async stats(){let e=await oe(),t={hot:0,session:0,local:0,durable:0},r={},s=0;for(let o of e)t[o.scope]=(t[o.scope]||0)+1,ne(o)&&s++,r[o.type]=(r[o.type]||0)+1;return {total:e.length,byScope:t,byType:r,expired:s}},async forgetExpired(){return Or()},async clear(){let e=await Y();for(let[t,r]of Object.entries(e))await wt(t,r.scope,r.superseded);w.remove(se);},async _getEntry(e){let r=(await Y())[e];if(!r){let s=Et(h,e);return s!==void 0?Pt(e,s,"hot"):null}return kt(e,r.scope,r.superseded)},async _loadAll(){return oe()},async _save(e){await J(e);}};Object.defineProperty(globalThis,"memorio",{value:{setProps:()=>{},obj:{},array:[],dispatch:v,message:T,devtools:Ee,logger:Te,setDescription:()=>{}},writable:false,configurable:true,enumerable:false});Object.defineProperty(globalThis,"events",{value:{},writable:true,enumerable:false});typeof globalThis.addEventListener=="function"&&v.listen("memorio:memory:cleanup",async()=>ie.forgetExpired?.());Object.defineProperty(memorio,"version",{writable:false,enumerable:false,value:re.version});Object.defineProperty(memorio,"debug",{get:()=>l.debug,set:e=>{l.debug=e;},enumerable:false});var Ot=F();Object.defineProperty(memorio,"_platform",{writable:false,enumerable:false,value:Ot.platform});Object.defineProperty(memorio,"_capabilities",{writable:false,enumerable:false,value:Ot});Object.defineProperty(memorio,"_sessionId",{writable:false,enumerable:false,value:Q()});Ze();memorio.isBrowser=le;memorio.isNode=ce;memorio.isDeno=ue;memorio.isEdge=me;memorio.getCapabilities=F;memorio.createContext=W;memorio.listContexts=ye;memorio.deleteContext=be;memorio.isolate=e=>W(e);memorio.registerSchema=M.register;memorio.validate=M.validate;memorio.unregisterSchema=M.unregister;memorio.listSchemas=M.list;memorio.typed=ke;memorio.snapshot=Oe;memorio.diff=Ce;memorio.undo=Ae;memorio.redo=Me;memorio.canUndo=De;memorio.canRedo=Re;memorio.rollback=je;memorio.trace=$e;memorio.enableHistory=_e;memorio.clearHistory=Ie;memorio.clearRedo=Ne;memorio.stateKeys=Ve;memorio.pathExists=Be;memorio.stateType=Le;memorio.stateGet=He;memorio.stateSchema=Je;memorio.memory=ie;Object.defineProperty(globalThis,"state",{value:h,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"store",{value:w,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"session",{value:_,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"cache",{value:Z,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"idb",{value:u,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"observer",{value:ee,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"useObserver",{value:te,writable:true,enumerable:false,configurable:true});Object.defineProperty(memorio,"dispatch",{value:v,writable:true,enumerable:false,configurable:true});Object.defineProperty(memorio,"setContext",{writable:false,enumerable:false,value:e=>he(e)});Object.defineProperty(memorio,"getContext",{writable:false,enumerable:false,value:()=>l.currentContext});Object.defineProperty(globalThis,"$state",{get:()=>globalThis.state,configurable:true});Object.defineProperty(globalThis,"$store",{get:()=>globalThis.store,configurable:true});Object.defineProperty(globalThis,"$session",{get:()=>globalThis.session,configurable:true});Object.defineProperty(globalThis,"$cache",{get:()=>globalThis.cache,configurable:true});memorio.help=function(){console.debug(`
|
|
25
|
-
\u{1F9E0} Memorio ${re.version} - Help
|
|
22
|
+
sqlite - globalThis.sqlite (SQLite / sql.js, browser only)
|
|
23
|
+
`);},Ne={inspect:so,stats:io,clear:se,clearAll:ao,exportData:lo,importData:co,watch:uo,help:mo};a();$();w();var fo={enabled:true,logToConsole:true,modules:["state","store","session","cache","idb"],maxEntries:1e3};function po(){return u.debug===true}var A={...fo},N=[],yo=e=>{A={...A,...e};},go=()=>{A.enabled=true;},bo=()=>{A.enabled=false;},Xt=e=>A.enabled&&A.modules.includes(e),ho=(e,t,r,o,n)=>{if(!Xt(e))return;let s={timestamp:new Date().toISOString(),module:e,action:t,path:r,value:o,previousValue:n};if(N.push(s),N.length>A.maxEntries&&N.shift(),A.logToConsole&&po()){let i=`[Memorio:${e.toUpperCase()}]`,l=vo(e);c(`%c${i}%c ${t} ${r},
|
|
24
|
+
color: ${l}; font-weight: bold,
|
|
25
|
+
color: inherit`),o!==void 0&&c(` \u2192 value:${o}`),n!==void 0&&c(` \u2190 previous:${n}`);}A.customHandler&&A.customHandler(s);},vo=e=>({state:"#4CAF50",store:"#2196F3",session:"#FF9800",cache:"#9C27B0",idb:"#F44336"})[e]||"#888888",xo=()=>[...N],So=()=>{N.length=0;},wo=()=>{let e={total:N.length,state:0,store:0,session:0,cache:0,idb:0,set:0,get:0,delete:0,clear:0};for(let t of N)if(t){let r=t.module,o=t.action;r&&typeof e[r]=="number"&&e[r]++,o&&typeof e[o]=="number"&&e[o]++;}return e},Eo=()=>JSON.stringify(N,null,2),Be={configure:yo,enable:go,disable:bo,isEnabled:Xt,log:ho,getHistory:xo,clearHistory:So,getStats:wo,exportLogs:Eo};$();J();a();J();$();var ge={version:"4.8.0"};G();T();_();w();a();function Ve(){return S}a();$();w();function Zt(e){if(e===null||typeof e!="object")return e;let t=e.constructor?.name;if(t!=="Object"&&t!=="Array")return e;try{return JSON.parse(JSON.stringify(e))}catch{return e}}var He=()=>Zt(R(S)),ze=e=>{let t=[],r=(o,n,s)=>{let i=o?Object.keys(o):[],l=n?Object.keys(n):[];for(let g of l){let b=s?`${s}.${g}`:g,v=o?o[g]:void 0,O=n[g];v!==O&&(typeof v!==typeof O||v===void 0?t.push({path:b,oldValue:v,newValue:O}):v&&typeof v=="object"?r(v,O,b):v!==O&&t.push({path:b,oldValue:v,newValue:O}));}for(let g of i)if(!(g in(n||{}))){let b=s?`${s}.${g}`:g;t.push({path:b,oldValue:o[g],newValue:void 0});}};return r(e,R(S),""),t},Qe=(e=true)=>{u.historyEnabled=e,c(`[memorio history] Tracking ${e?"enabled":"disabled"}`);};var Ke=()=>[...u.mutations],We=()=>u.canUndo(),Fe=()=>u.canRedo(),Ge=()=>{if(!u.historyEnabled){c("[memorio history] History is not enabled");return}let e=u.popUndo();if(e)return Po(e),c(`[memorio history] Undid: ${e.action} ${e.path}`),e},Ye=()=>{if(!u.historyEnabled){c("[memorio history] History is not enabled");return}let e=u.popRedo();if(e)return _o(e),c(`[memorio history] Redid: ${e.action} ${e.path}`),e};function Po(e){let t=u.historyEnabled;u.historyEnabled=false;try{e.action==="set"?e.previousValue===void 0?er(e.path):Ue(e.path,e.previousValue):e.action==="delete"&&e.previousValue!==void 0&&Ue(e.path,e.previousValue);}finally{u.historyEnabled=t;}}function _o(e){let t=u.historyEnabled;u.historyEnabled=false;try{e.action==="set"?Ue(e.path,e.newValue):e.action==="delete"&&er(e.path);}finally{u.historyEnabled=t;}}function Ue(e,t){let r=e.split("."),o=S;for(let n=0;n<r.length-1;n++){let s=r[n];o[s]===void 0&&(o[s]={}),o=o[s];}o[r[r.length-1]]=t;}function er(e){let t=e.split(".");if(t.length===1){S.remove(t[0]);return}let r=S;for(let o=0;o<t.length-1;o++){let n=t[o];if(r[n]===void 0)return;r=r[n];}delete r[t[t.length-1]];}var Xe=e=>{S.removeAll();for(let t of Object.keys(e))S[t]=Zt(e[t]);u.clearHistory(),c("[memorio history] State rolled back to snapshot");},Ze=()=>{u.clearHistory(),c("[memorio history] History cleared");},et=()=>{u.clearRedo();};a();var tt=()=>{let e=R(S);return Object.keys(e).filter(t=>!["list","remove","removeAll","lock","unlock"].includes(t))},rt=e=>{if(!e||typeof e!="string")return false;let t=e.replace(/^state\./,"").split("."),r=S;for(let o of t){if(r==null)return false;r=r[o];}return r!==void 0},ot=e=>{let[t,r]=tr(e);return !t||r===void 0?"undefined":Array.isArray(r)?"array":typeof r},nt=e=>{let[t,r]=tr(e);if(!(!t||r===void 0))return ko(r)},st=()=>{let e=[],t=(r,o)=>{if(r===null||typeof r!="object"||Array.isArray(r))return;let n=Object.keys(r).filter(s=>!["list","remove","removeAll","lock","unlock"].includes(s));for(let s of n){let i=o?`${o}.${s}`:s,l=r[s],g=l!==void 0,b=g?Array.isArray(l)?"array":typeof l:"undefined";e.push({path:i,type:b,defined:g}),g&&typeof l=="object"&&!Array.isArray(l)&&l.constructor?.name==="Object"&&t(l,i);}};return t(R(S),""),e};function tr(e){if(!e||typeof e!="string")return [false,void 0];let t=e.replace(/^state\./,"").split("."),r=S;for(let o of t){if(r==null)return [false,void 0];r=r[o];}return [r!==void 0,r]}function ko(e){if(e===null||typeof e!="object")return e;let t=e.constructor?.name;if(t!=="Object"&&t!=="Array")return e;try{return JSON.parse(JSON.stringify(e))}catch{return e}}a();G();T();a();G();var I=globalThis,Oo=10*1024*1024;function ie(){let e=I.memorioSyncConfig;if(e&&typeof e.namespace=="string"&&e.namespace)return `ns:${e.namespace}`;let t=I.memorio?I.memorio._currentContext:void 0,r=typeof t=="string"&&t?t:"";return r?`ctx:${r}`:"default"}function rr(){return !!I.memorioSyncConfig}var X=e=>`memorio:sync:${e}:`,Y=e=>`${X(e)}index`;function qo(e){let t=JSON.stringify(e);if(t.length>Oo)throw new Error("memorio sync: memory entry exceeds maximum size");return t}function it(e){try{return JSON.parse(e)}catch{return null}}var at={async append(e,t){let r=ie(),o={...e,operation:t,updatedAt:e.updatedAt||Date.now(),version:e.version||1,sync:"pending"},n=qo(o),s=`${X(r)}${o.id}`;h.set(s,n);let i=h.get(Y(r))||[];return i.includes(o.id)||i.push(o.id),h.set(Y(r),JSON.stringify(i)),o},async pending(){let e=ie(),t=[],r=h.get(Y(e))||[];for(let o of r){let n=h.get(`${X(e)}${o}`);if(!n)continue;let s=it(n);s&&s.sync!=="synced"&&t.push(s);}return t.sort((o,n)=>(o.updatedAt||0)-(n.updatedAt||0)),t},async markSynced(e){if(!e.length)return 0;let t=ie(),r=0,o=h.get(Y(t))||[];for(let n of o){if(!e.includes(n))continue;let s=`${X(t)}${n}`,i=h.get(s);if(!i)continue;let l=it(i);!l||l.sync==="synced"||(l.sync="synced",h.set(s,JSON.stringify(l)),r++);}return r},async get(e){let t=ie(),r=h.get(`${X(t)}${e}`);return it(r??"")},async clear(){let e=ie(),t=h.get(Y(e))||[];for(let r of t)h.remove(`${X(e)}${r}`);h.remove(Y(e));},async replay(){let e={synced:[]};if(!rr())return e;let r=(I.memorioSyncConfig||{}).provider;if(!r||typeof r.push!="function")return e;let o=await this.pending();if(o.length)try{let n=await r.push(o);e.synced=n?.synced||[],e.conflicts=n?.conflicts,e.error=n?.error,e.synced.length&&await this.markSynced(e.synced);}catch(n){e.error=String(n);}if(typeof r.pull=="function")try{let n=o.length?Math.min(...o.map(i=>i.updatedAt||0)):0,s=await r.pull(n);for(let i of s||[])await this.append(i,i.operation||"confirm"),await this.markSynced([i.id]);}catch{}return e},status(){return Promise.resolve("store")}};function or(e){let t=I.memorioSyncConfig||{};return I.memorioSyncConfig={...t,...e},at}if(typeof I.addEventListener=="function"){let e=false;I.addEventListener("focus",()=>{e||!rr()||(e=true,at.replay().finally(()=>{e=false;}));});}var lt=at;var ve="__memorio_memory_index__",nr="__memorio_superseded__";function ct(){return !!globalThis.memorioSyncConfig}async function Z(e,t){if(ct()&&e.scope!=="hot")try{await lt.append(e,t);}catch{}}function ut(e){return e.startsWith(nr)?e:`${nr}${e}`}function sr(e){return e?Array.isArray(e)?e:[e]:[]}function Mo(e,t){if(t.scope)return t.scope;let r=JSON.stringify(e).length;return r>1e6?"durable":("local")}function k(){return Date.now()}function he(e){return e.ttl===null||e.ttl===void 0?false:k()-e.createdAt>e.ttl}function $o(e,t){return e.status==="obsolete"||e.status==="superseded"||he(e)?t.includeObsolete??false:!(t.type&&!(Array.isArray(t.type)?t.type:[t.type]).includes(e.type)||t.minConfidence!==void 0&&e.confidence<t.minConfidence)}function Co(e,t){return !(e.status!=="active"||he(e)||t.tags&&!(Array.isArray(t.tags)?t.tags:[t.tags]).some(n=>e.tags.includes(n))||t.types&&!(Array.isArray(t.types)?t.types:[t.types]).includes(e.type)||t.minConfidence!==void 0&&e.confidence<t.minConfidence||t.scopes&&!t.scopes.includes(e.scope))}function jo(e){let t=(k()-e.createdAt)/36e5,r=Math.max(.1,1/(1+t*.5)),o=e.confidence,n=1+e.tags.length*.1,s={decision:1.5,context:1.3,preference:1.2,task:1,fact:.8},i={hot:1.5,session:1.2,local:1,durable:.8};return r*o*n*s[e.type]*i[e.scope]}function ar(e,t){if(!t||typeof t!="string")return;let r=t.replace(/^state\./,"").split("."),o=e;for(let n of r){if(o==null)return;o=o[n];}return o}function lr(e,t,r){if(!t||typeof t!="string")return;let o=t.replace(/^state\./,"").split("."),n=e;for(let s=0;s<o.length-1;s++){let i=o[s];(n[i]===void 0||n[i]===null)&&(n[i]={}),n=n[i];}n[o[o.length-1]]=r;}async function W(e){let t=e.status==="superseded"?ut(e.id||e.key):e.key,r=JSON.stringify(e);switch(e.scope){case "hot":lr(S,t,e.value);break;case "session":C.set(t,r);break;case "local":h.set(t,r);break;case "durable":await d.set("memories",t,r);break}await Do(e.id||e.key,e.scope,e.status==="superseded");}async function cr(e,t,r=false){let o=r?ut(e):e,n;switch(t){case "hot":{let s=ar(S,o);return s===void 0?null:ur(e,s,t)}case "session":n=C.get(o);break;case "local":n=h.get(o);break;case "durable":n=await d.get("memories",o);break}if(!n)return null;try{let s=JSON.parse(n);return s.id=s.id||e,s}catch{return null}}function ur(e,t,r){return {id:e,key:e,value:t,type:"fact",confidence:1,scope:r,ttl:null,tags:[],status:"active",createdAt:k(),lastConfirmedAt:k(),supersededId:null}}async function ir(e,t,r=false){let o=r?ut(e):e;switch(t){case "hot":lr(S,o,void 0);break;case "session":C.remove(o);break;case "local":h.remove(o);break;case "durable":await d.deleteKey("memories",o);break}await Ao(e,r);}async function ae(){try{let e=h.get(ve);return e?JSON.parse(e):{}}catch{return {}}}async function Do(e,t,r=false){let o=await ae();o[e]={scope:t,superseded:r},h.set(ve,JSON.stringify(o));}async function Ao(e,t=false){let r=await ae(),o=r[e];o&&(t&&o.superseded||!t&&!o.superseded)&&delete r[e],h.set(ve,JSON.stringify(r));}async function be(){let e=await ae(),t=[];for(let[r,o]of Object.entries(e)){let n=await cr(r,o.scope,o.superseded);n&&(n.id=n.id||r,n.supersededId=n.supersededId??null,t.push(n));}return t}var xe={async remember(e,t,r={}){let o=await this._getEntry(e);if(o&&o.status==="active"){let l=`${o.id}__v${Date.now()}`,g={...o,id:l,key:o.key,status:"superseded",supersededId:null,lastConfirmedAt:k()};await W(g),await Z(g,"supersede");}let n=Mo(t,r),s=sr(r.tags),i={id:r.id||e,key:e,value:t,type:r.type||"fact",confidence:r.confidence??1,scope:n,ttl:r.ttl??null,tags:s,source:r.source,status:"active",createdAt:k(),lastConfirmedAt:k(),updatedAt:k(),version:o&&o.version?o.version+1:1,sync:ct()?"pending":void 0,supersededId:o?o.id:null};await W(i),await Z(i,"remember"),E.set("memorio:memory:remembered",{key:e,scope:n,entryId:i.id});},async recall(e,t={}){let r=await this._getEntry(e);return !r||!$o(r,t)?null:(r.lastConfirmedAt=k(),await W(r),E.set("memorio:memory:recalled",{key:e}),r.value)},async context(e={}){return (await be()).filter(n=>Co(n,e)).map(n=>({entry:n,score:jo(n)})).sort((n,s)=>s.score-n.score).slice(0,e.maxEntries??25).map(({entry:n})=>({key:n.key,value:n.value,type:n.type,confidence:n.confidence,scope:n.scope,tags:n.tags,age:k()-n.createdAt,accessCount:n.tags.length+1,lastAccessedAt:n.lastConfirmedAt}))},async forget(e){let t=await this._getEntry(e);t&&(await ir(t.id||e,t.scope,t.status==="superseded"),await Z(t,"forget"),E.set("memorio:memory:forgotten",{key:e}));},async update(e,t,r={}){let o=await this._getEntry(e);if(!o){await this.remember(e,t,r);return}let n=`${o.id}__v${k()}`,s={...o,id:n,key:o.key,status:"superseded",supersededId:null,lastConfirmedAt:k()};await W(s),await Z(s,"supersede");let i={...o,value:t,lastConfirmedAt:k(),updatedAt:k(),version:(o.version?o.version:0)+1,sync:ct()?"pending":void 0,...r.scope?{scope:r.scope}:{},...r.ttl!==void 0?{ttl:r.ttl}:{},...r.type?{type:r.type}:{},...r.confidence!==void 0?{confidence:r.confidence}:{},...r.tags!==void 0?{tags:sr(r.tags)}:{},...r.source?{source:r.source}:{}};await W(i),await Z(i,"update"),E.set("memorio:memory:updated",{key:e,entryId:i.id});},async stats(){let e=await be(),t={hot:0,session:0,local:0,durable:0},r={},o=0;for(let n of e)t[n.scope]=(t[n.scope]||0)+1,he(n)&&o++,r[n.type]=(r[n.type]||0)+1;return {total:e.length,byScope:t,byType:r,expired:o}},async forgetExpired(){let e=await be(),t=0;for(let r of e)he(r)&&r.status==="active"&&(r.status="obsolete",r.updatedAt=k(),r.operation="expire",await W(r),await Z(r,"expire"),t++);return t},async clear(){let e=await ae();for(let[t,r]of Object.entries(e))await ir(t,r.scope,r.superseded);h.remove(ve);},async _getEntry(e){let r=(await ae())[e];if(!r){let o=ar(S,e);return o!==void 0?ur(e,o,"hot"):null}return cr(e,r.scope,r.superseded)},async _loadAll(){return be()},async _save(e){await W(e);},journal:lt,configure(e){return or(e),this}};Object.defineProperty(globalThis,"memorio",{value:{setProps:()=>{},obj:{},array:[],dispatch:E,message:P,devtools:Ne,logger:Be,setDescription:()=>{}},writable:false,configurable:true,enumerable:false});Object.defineProperty(globalThis,"events",{value:{},writable:true,enumerable:false});typeof globalThis.addEventListener=="function"&&E.listen("memorio:memory:cleanup",async()=>xe.forgetExpired?.());Object.defineProperty(memorio,"version",{writable:false,enumerable:false,value:ge.version});Object.defineProperty(memorio,"debug",{get:()=>u.debug,set:e=>{u.debug=e;},enumerable:false});var mr=oe();Object.defineProperty(memorio,"_platform",{writable:false,enumerable:false,value:mr.platform});Object.defineProperty(memorio,"_capabilities",{writable:false,enumerable:false,value:mr});Object.defineProperty(memorio,"_sessionId",{writable:false,enumerable:false,value:ce()});xt();memorio.isBrowser=we;memorio.isNode=Ee;memorio.isDeno=Te;memorio.isEdge=Pe;memorio.getCapabilities=oe;memorio.createContext=ne;memorio.listContexts=Me;memorio.deleteContext=$e;memorio.isolate=e=>ne(e);memorio.registerSchema=L.register;memorio.validate=L.validate;memorio.unregisterSchema=L.unregister;memorio.listSchemas=L.list;memorio.typed=Ve;memorio.snapshot=He;memorio.diff=ze;memorio.undo=Ge;memorio.redo=Ye;memorio.canUndo=We;memorio.canRedo=Fe;memorio.rollback=Xe;memorio.trace=Ke;memorio.enableHistory=Qe;memorio.clearHistory=Ze;memorio.clearRedo=et;memorio.stateKeys=tt;memorio.pathExists=rt;memorio.stateType=ot;memorio.stateGet=nt;memorio.stateSchema=st;memorio.memory=xe;Object.defineProperty(globalThis,"state",{value:S,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"store",{value:h,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"session",{value:C,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"cache",{value:ue,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"idb",{value:d,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"sqlite",{value:m,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"observer",{value:pe,writable:true,enumerable:false,configurable:true});Object.defineProperty(globalThis,"useObserver",{value:ye,writable:true,enumerable:false,configurable:true});Object.defineProperty(memorio,"dispatch",{value:E,writable:true,enumerable:false,configurable:true});Object.defineProperty(memorio,"setContext",{writable:false,enumerable:false,value:e=>Ce(e)});Object.defineProperty(memorio,"getContext",{writable:false,enumerable:false,value:()=>u.currentContext});Object.defineProperty(globalThis,"$state",{get:()=>globalThis.state,configurable:true});Object.defineProperty(globalThis,"$store",{get:()=>globalThis.store,configurable:true});Object.defineProperty(globalThis,"$session",{get:()=>globalThis.session,configurable:true});Object.defineProperty(globalThis,"$cache",{get:()=>globalThis.cache,configurable:true});memorio.help=function(){console.debug(`
|
|
26
|
+
\u{1F9E0} Memorio ${ge.version} - Help
|
|
26
27
|
|
|
27
28
|
Core Modules:
|
|
28
29
|
state - Reactive state management
|
|
@@ -30,6 +31,7 @@ Core Modules:
|
|
|
30
31
|
session - Session storage (sessionStorage/Map)
|
|
31
32
|
cache - In-memory cache
|
|
32
33
|
idb - IndexedDB (browser only)
|
|
34
|
+
sqlite - SQLite in browser (sql.js, optional)
|
|
33
35
|
|
|
34
36
|
API:
|
|
35
37
|
memorio.typed<T>() - Type-safe view of global state (compile-time only)
|
|
@@ -66,14 +68,17 @@ Memory System:
|
|
|
66
68
|
memorio.memory.forget(key) - Delete a specific memory
|
|
67
69
|
memorio.memory.context(opts) - Get ranked relevant memories (semantic context for AI)
|
|
68
70
|
memorio.memory.stats() - Memory usage statistics
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
memorio.memory.forgetExpired() - Remove all expired entries
|
|
72
|
+
memorio.memory.clear() - Wipe all memories
|
|
73
|
+
memorio.memory.configure({ sync }) - Optional cloud-sync provider + namespace
|
|
74
|
+
memorio.memory.journal.pending() - Local op journal (SQLite/store)
|
|
71
75
|
|
|
72
76
|
Scopes:
|
|
73
77
|
hot - In-memory reactive state (volatile, fastest)
|
|
74
78
|
session - sessionStorage (persists across page reloads, cleared on tab close)
|
|
75
79
|
local - localStorage (persistent, survives browser restart)
|
|
76
80
|
durable - IndexedDB (large datasets, async)
|
|
81
|
+
sql - SQLite / sql.js (browser, optional, full SQL)
|
|
77
82
|
|
|
78
83
|
TTL options:
|
|
79
84
|
ttl: number (milliseconds) or null (never expires)
|
|
@@ -82,9 +87,9 @@ Memory types:
|
|
|
82
87
|
fact, preference, decision, task, context
|
|
83
88
|
|
|
84
89
|
Shortcuts:
|
|
85
|
-
state, store, session, cache, idb - direct access to modules
|
|
90
|
+
state, store, session, cache, idb, sqlite - direct access to modules
|
|
86
91
|
`);};memorio.help=function(){console.debug(`
|
|
87
|
-
\u{1F9E0} Memorio ${
|
|
92
|
+
\u{1F9E0} Memorio ${ge.version} - Help
|
|
88
93
|
|
|
89
94
|
Core Modules:
|
|
90
95
|
state - Reactive state management
|
|
@@ -92,6 +97,7 @@ Core Modules:
|
|
|
92
97
|
session - Session storage (sessionStorage/Map)
|
|
93
98
|
cache - In-memory cache
|
|
94
99
|
idb - IndexedDB (browser only)
|
|
100
|
+
sqlite - SQLite in browser (sql.js, optional)
|
|
95
101
|
|
|
96
102
|
API:
|
|
97
103
|
memorio.typed<T>() - Type-safe view of global state (compile-time only)
|
|
@@ -145,14 +151,17 @@ Memory System:
|
|
|
145
151
|
memorio.memory.forget(key) - Delete a specific memory
|
|
146
152
|
memorio.memory.context(opts) - Get ranked relevant memories (semantic context for AI)
|
|
147
153
|
memorio.memory.stats() - Memory usage statistics
|
|
148
|
-
|
|
149
|
-
|
|
154
|
+
memorio.memory.forgetExpired() - Remove all expired entries
|
|
155
|
+
memorio.memory.clear() - Wipe all memories
|
|
156
|
+
memorio.memory.configure({ sync }) - Optional cloud-sync provider + namespace
|
|
157
|
+
memorio.memory.journal.pending() - Local op journal (SQLite/store)
|
|
150
158
|
|
|
151
159
|
Scopes:
|
|
152
160
|
hot - In-memory reactive state (volatile, fastest)
|
|
153
161
|
session - sessionStorage (persists across page reloads, cleared on tab close)
|
|
154
162
|
local - localStorage (persistent, survives browser restart)
|
|
155
163
|
durable - IndexedDB (large datasets, async)
|
|
164
|
+
sql - SQLite / sql.js (browser, optional, full SQL)
|
|
156
165
|
|
|
157
166
|
TTL options:
|
|
158
167
|
ttl: number (milliseconds) or null (never expires)
|
|
@@ -161,7 +170,7 @@ Memory types:
|
|
|
161
170
|
fact, preference, decision, task, context
|
|
162
171
|
|
|
163
172
|
Shortcuts:
|
|
164
|
-
state, store, session, cache, idb - direct access to modules
|
|
165
|
-
`);};var
|
|
173
|
+
state, store, session, cache, idb, sqlite - direct access to modules
|
|
174
|
+
`);};var Ro=globalThis.memorio,fa=globalThis.events,pa=e=>ne(e),ya=globalThis.memorio?.help,ga=e=>u.currentContext=e,ba=()=>u.currentContext,ha=Ro;
|
|
166
175
|
|
|
167
|
-
export {
|
|
176
|
+
export { ue as cache, Fe as canRedo, We as canUndo, Ze as clearHistory, et as clearRedo, ne as createContext, ha as default, $e as deleteContext, Ne as devtools, ze as diff, E as dispatch, Qe as enableHistory, fa as events, oe as getCapabilities, ba as getContext, ya as help, d as idb, u as internal, we as isBrowser, Te as isDeno, Pe as isEdge, Ee as isNode, pa as isolate, Me as listContexts, gt as listSchemas, Be as logger, Ro as memorio, xe as memory, P as message, pe as observer, rt as pathExists, Se as propertyName, Ye as redo, pt as registerSchema, Xe as rollback, L as schema, C as session, ga as setContext, He as snapshot, m as sqlite, S as state, nt as stateGet, tt as stateKeys, st as stateSchema, ot as stateType, h as store, Ke as trace, Ve as typed, Ge as undo, yt as unregisterSchema, ye as useObserver, ft as validate };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Node Attachment System
|
|
2
|
+
|
|
3
|
+
`memorio.memory` extends with a **Node Attachment System** allowing memory elements to dynamically attach, reference, or connect to other memory elements at runtime.
|
|
4
|
+
|
|
5
|
+
This is an **extension**, not a replacement, of existing memory semantics.
|
|
6
|
+
|
|
7
|
+
## Concepts
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
Memory
|
|
11
|
+
└── Node
|
|
12
|
+
├── identity
|
|
13
|
+
├── value
|
|
14
|
+
├── metadata
|
|
15
|
+
└── relationships
|
|
16
|
+
└── Edge
|
|
17
|
+
├── target
|
|
18
|
+
├── relation
|
|
19
|
+
├── metadata
|
|
20
|
+
├── confidence
|
|
21
|
+
└── lifecycle
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
const user = await memory.remember("user", { name: "Alice" })
|
|
28
|
+
const project = await memory.remember("project", { name: "Memorio" })
|
|
29
|
+
|
|
30
|
+
await user.connect(project, { relation: "works-on", confidence: 0.95 })
|
|
31
|
+
await user.attach(project) // → connect with relation "attached-to"
|
|
32
|
+
|
|
33
|
+
const related = await user.related({ direction: "both", relation: "works-on" })
|
|
34
|
+
const tree = await user.traverse({ depth: 3 })
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Methods
|
|
38
|
+
|
|
39
|
+
| Method | Description |
|
|
40
|
+
|--------|-------------|
|
|
41
|
+
| `node.connect(target, opts?)` | Create a directed relationship |
|
|
42
|
+
| `node.disconnect(target, opts?)` | Remove a relationship |
|
|
43
|
+
| `node.related(opts?)` | Query related nodes |
|
|
44
|
+
| `node.traverse(opts?)` | Bounded graph traversal |
|
|
45
|
+
| `memory.connect(source, target, opts?)` | Low-level connect |
|
|
46
|
+
| `memory.disconnect(source, target, opts?)` | Low-level disconnect |
|
|
47
|
+
|
|
48
|
+
## Scopes
|
|
49
|
+
|
|
50
|
+
Relationship visibility respects memory scopes — a query in one scope cannot leak inaccessible nodes from another.
|
|
51
|
+
|
|
52
|
+
## Persistence
|
|
53
|
+
|
|
54
|
+
Relationships use **IDs**, never embedded objects:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"id": "user",
|
|
59
|
+
"relationships": [
|
|
60
|
+
{ "target": "project", "relation": "works-on" }
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Lifecycle
|
|
66
|
+
|
|
67
|
+
- **TTL**: independent per node/edge — does not propagate
|
|
68
|
+
- **Confidence**: independent — node and edge have separate confidence values
|
|
69
|
+
- **Deletion**: deleting a node removes its edges (default policy)
|
|
70
|
+
- **Cycles**: supported with visited-set protection during traversal
|
|
71
|
+
- **Dangling references**: `retain` by default (configurable)
|
|
72
|
+
|
|
73
|
+
## Security
|
|
74
|
+
|
|
75
|
+
Relationship traversal inherits the same scope/access rules as direct retrieval. A user cannot gain access to Node B merely because Node A connects to it.
|
|
76
|
+
|
|
77
|
+
## Experimental Substrate Evaluation
|
|
78
|
+
|
|
79
|
+
Runtime substrate choices (Object Graph, WeakMap, DOM) are under benchmark evaluation. See:
|
|
80
|
+
|
|
81
|
+
- [Leak Detection Protocol](../experimental/memory-substrates/LEAK-DETECTION.md)
|
|
82
|
+
|
|
83
|
+
## Serialization
|
|
84
|
+
|
|
85
|
+
Nodes serialize to IDs only — never recursively embedded graphs.
|
|
86
|
+
|
|
87
|
+
## Performance
|
|
88
|
+
|
|
89
|
+
- `O(1)` indexed lookup for direct node retrieval
|
|
90
|
+
- Graph traversal only on explicit request
|
|
91
|
+
- Indexable by `source`, `target`, `relation`
|
|
92
|
+
|
|
93
|
+
## Backward Compatibility
|
|
94
|
+
|
|
95
|
+
Existing APIs (`remember`, `get`, `forget`, `search`) continue to work unchanged. A node-enabled memory entry remains usable as a normal memory entry.
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# SQLite - Memorio
|
|
2
|
+
|
|
3
|
+
> The `sql.js` package is **optional** — if it is not installed, Memorio loads `sql.js` on first use by injecting the `sql-wasm-browser.js` UMD build from the jsDelivr CDN as a classic `<script>` (which exposes the `initSqlJs` factory on `globalThis`). No bare `import('sql.js')` is ever emitted, so bundlers never resolve the optional dependency at build time. Not available in Node.js/Deno.
|
|
4
|
+
|
|
5
|
+
SQLite brings a full SQL engine into the browser through [`sql.js`](https://sql.js.org), a port of SQLite to JavaScript via WebAssembly. Memorio loads it **lazily** on first use, so it only affects bundles that actually use the `sqlite` module.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install memorio
|
|
11
|
+
# Optional: install the SQLite engine locally (the default loader fetches it from the CDN)
|
|
12
|
+
npm install sql.js
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import 'memorio';
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> The default loader injects the sql.js UMD build (`sql-wasm-browser.js`) from the jsDelivr CDN as a classic `<script>`, exposing the `initSqlJs` factory on `globalThis`. This keeps `sql.js` (and its WASM) out of your build graph entirely — it's only fetched when `sqlite` is first used. For production/self-hosted setups, install `sql.js` and configure a custom `loader` (e.g. `sqlite.config({ loader: () => import('sql.js') })` under a bundler), or set the wasm base with `sqlite.config({ wasmUrl })` / `sqlite.config({ locateFile })`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick Examples
|
|
24
|
+
|
|
25
|
+
### Example 1: Basic Usage
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
// Create an in-memory database and a table
|
|
29
|
+
await sqlite.db.create('myApp');
|
|
30
|
+
await sqlite.query.run('myApp', 'CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)');
|
|
31
|
+
|
|
32
|
+
// Insert data
|
|
33
|
+
await sqlite.query.run('myApp', 'INSERT INTO users (name) VALUES (?)', ['Mario']);
|
|
34
|
+
|
|
35
|
+
// Select data
|
|
36
|
+
const rows = await sqlite.query.select('myApp', 'SELECT * FROM users');
|
|
37
|
+
console.debug(rows); // [{ id: 1, name: 'Mario' }]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Example 2: CRUD shortcuts
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
const db = 'store';
|
|
44
|
+
|
|
45
|
+
await sqlite.db.create(db);
|
|
46
|
+
await sqlite.query.run(db, 'CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price REAL)');
|
|
47
|
+
await sqlite.data.set(db, 'INSERT INTO products (name, price) VALUES (?, ?)', ['Apple', 1.5]);
|
|
48
|
+
await sqlite.data.set(db, 'INSERT INTO products (name, price) VALUES (?, ?)', ['Banana', 0.8]);
|
|
49
|
+
|
|
50
|
+
// First matching row
|
|
51
|
+
const apple = await sqlite.data.get(db, 'SELECT * FROM products WHERE name = ?', ['Apple']);
|
|
52
|
+
console.debug(apple); // { id: 1, name: 'Apple', price: 1.5 }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Example 3: Export / Import
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
await sqlite.db.create('myApp');
|
|
59
|
+
await sqlite.query.run('myApp', 'CREATE TABLE todos (id INTEGER PRIMARY KEY, task TEXT)');
|
|
60
|
+
await sqlite.data.set('myApp', 'INSERT INTO todos (task) VALUES (?)', ['Write docs']);
|
|
61
|
+
|
|
62
|
+
// Export the in-memory database to a portable binary dump
|
|
63
|
+
const dump = await sqlite.db.export('myApp');
|
|
64
|
+
|
|
65
|
+
// Later... import it back
|
|
66
|
+
await sqlite.db.import('restored', dump);
|
|
67
|
+
const rows = await sqlite.query.select('restored', 'SELECT * FROM todos');
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Example 4: Engine control
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
// Configure the wasm location BEFORE first use (sets the locateFile base)
|
|
74
|
+
sqlite.config({ wasmUrl: '/static/sql.js/' });
|
|
75
|
+
|
|
76
|
+
// Or provide a fully custom loader (e.g. a local/npm build of sql.js)
|
|
77
|
+
sqlite.config({ loader: async () => {
|
|
78
|
+
return await import('sql.js'); // local install — resolves at runtime
|
|
79
|
+
}});
|
|
80
|
+
|
|
81
|
+
// Enable automatic persistence of one or more databases (see Example 5)
|
|
82
|
+
sqlite.config({ persistence: true });
|
|
83
|
+
|
|
84
|
+
// Wait until the engine is ready
|
|
85
|
+
await sqlite.ready;
|
|
86
|
+
console.debug('SQLite version:', sqlite.db.version());
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Example 5: Persistence & dev download
|
|
90
|
+
|
|
91
|
+
> **Important:** sql.js databases live in **WebAssembly memory** — they are
|
|
92
|
+
> in-memory and **volatile** (lost on page refresh) unless you persist them.
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
// Opt into auto-persistence at create time (global config or per-create)
|
|
96
|
+
await sqlite.db.create('app', { persistence: true });
|
|
97
|
+
|
|
98
|
+
await sqlite.query.run('app', 'CREATE TABLE notes (id INTEGER PRIMARY KEY, body TEXT)');
|
|
99
|
+
// writes are snapshotted to localStorage automatically (debounced via updateHook)
|
|
100
|
+
|
|
101
|
+
await sqlite.db.persist('app'); // force an immediate snapshot
|
|
102
|
+
// After a refresh, reopening restores the data:
|
|
103
|
+
await sqlite.db.create('app', { persistence: true });
|
|
104
|
+
|
|
105
|
+
// Dev convenience: download the current db as a .sqlite file from the browser
|
|
106
|
+
await sqlite.db.download('app', 'app.sqlite');
|
|
107
|
+
|
|
108
|
+
// Flush + persist + release the handle
|
|
109
|
+
await sqlite.db.close('app');
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Persistence is stored on `store` (localStorage, namespaced per
|
|
113
|
+
`sqlite.config({ namespace })` / memorio context) as a base64 snapshot under
|
|
114
|
+
`memorio:sqlite:db:<ns>:<name>`. It is best-effort: if `store` is unavailable
|
|
115
|
+
the database simply behaves as in-memory.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## API Reference
|
|
120
|
+
|
|
121
|
+
### Engine Control
|
|
122
|
+
|
|
123
|
+
| Method | Parameters | Returns | Description |
|
|
124
|
+
|--------|------------|---------|-------------|
|
|
125
|
+
| `sqlite.config(opts)` | `opts: { loader?, locateFile?, wasmUrl?, persistence?, namespace? }` | `sqlite` | Configure the engine. `loader` fully replaces the initializer (default = CDN `<script>`); `locateFile` customizes wasm resolution; `wasmUrl` sets the wasm base directory; `persistence` toggles automatic db snapshots; `namespace` partitions persisted snapshots. Chainable. |
|
|
126
|
+
| `sqlite.db.create(name, opts)` | `name: string, opts?: { data?, persistence? }` | `Database` | Opens/creates a named in-memory db. With `persistence: true` (or global config), a snapshot is restored if present and writes are auto-saved. |
|
|
127
|
+
| `sqlite.db.persist(name)` | `name: string` | `Promise<boolean>` | Force an immediate snapshot of a persisted database to `store`. |
|
|
128
|
+
| `sqlite.db.download(name, filename?)` | `name: string, filename?: string` | `Promise<boolean>` | Dev-only: trigger a browser download of the db as a `.sqlite` file. |
|
|
129
|
+
| `sqlite.db.close(name)` | `name: string` | `Promise<void>` | Persist (if enabled), close, and release the handle. |
|
|
130
|
+
| `sqlite.ready` | none | `Promise<void>` | Resolves once `sql.js` has been initialized. Rejects (and sets `_disabled`) if the engine can't load. |
|
|
131
|
+
| `sqlite.db.version()` | none | `string \| null` | Engine version, available after initialization. |
|
|
132
|
+
| `sqlite._disabled` | none | `boolean` | `true` when the module is disabled (non-browser env / load failure). |
|
|
133
|
+
| `sqlite._warning` | none | `string \| undefined` | Reason text when disabled, if applicable. |
|
|
134
|
+
|
|
135
|
+
### Database Methods
|
|
136
|
+
|
|
137
|
+
| Method | Parameters | Returns | Description |
|
|
138
|
+
|--------|------------|---------|-------------|
|
|
139
|
+
| `sqlite.db.support()` | none | `boolean` | Check whether SQLite can run in this environment. |
|
|
140
|
+
| `sqlite.db.create(name, opts?)` | `name: string`, `opts?: { data }` | `Promise<Database>` | Create an in-memory database (or reopen one from a binary dump). |
|
|
141
|
+
| `sqlite.db.get(name)` | `name: string` | `Database` | Retrieve an open database handle. |
|
|
142
|
+
| `sqlite.db.delete(name)` | `name: string` | `boolean` | Close and remove a database handle. |
|
|
143
|
+
| `sqlite.db.list()` | none | `string[]` | List open database names. |
|
|
144
|
+
| `sqlite.db.size(name?)` | `name?: string` | `Promise<number>` | Size in bytes of one or all databases. |
|
|
145
|
+
| `sqlite.db.export(name)` | `name: string` | `Promise<Uint8Array>` | Export a database to a binary dump. |
|
|
146
|
+
| `sqlite.db.import(name, data)` | `name: string`, `data` | `Promise<Database>` | Create/replace a database from a binary dump. |
|
|
147
|
+
|
|
148
|
+
### Query Methods
|
|
149
|
+
|
|
150
|
+
| Method | Parameters | Returns | Description |
|
|
151
|
+
|--------|------------|---------|-------------|
|
|
152
|
+
| `sqlite.query.run(name, sql, params?)` | `name: string`, `sql: string`, `params?: any[]` | `Promise<number>` | Run a statement that does not return rows (INSERT / UPDATE / DELETE / CREATE). Returns modified-row count. |
|
|
153
|
+
| `sqlite.query.select(name, sql, params?)` | `name: string`, `sql: string`, `params?: any[]` | `Promise<object[]>` | Run a query and return the rows as plain objects. |
|
|
154
|
+
|
|
155
|
+
### Data Methods (CRUD shortcuts)
|
|
156
|
+
|
|
157
|
+
| Method | Parameters | Returns | Description |
|
|
158
|
+
|--------|------------|---------|-------------|
|
|
159
|
+
| `sqlite.data.set(name, sql, params?)` | `name: string`, `sql: string`, `params?: any[]` | `Promise<number>` | Alias of `sqlite.query.run`. |
|
|
160
|
+
| `sqlite.data.get(name, sql, params?)` | `name: string`, `sql: string`, `params?: any[]` | `Promise<object \| null>` | Alias of `sqlite.query.select` returning the first row (or `null`). |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Platform Support
|
|
165
|
+
|
|
166
|
+
| Platform | Support | Notes |
|
|
167
|
+
|----------|---------|-------|
|
|
168
|
+
| Browser | ✅ Full | Requires WebAssembly + the `sql.js` package (or CDN fallback) |
|
|
169
|
+
| Edge Worker | ⚠️ Limited | WebAssembly may be available; configure a `loader` manually |
|
|
170
|
+
| Node.js | ❌ Not available | Use `store` or `session` instead |
|
|
171
|
+
| Deno | ❌ Not available | Use `store` or `session` instead |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Best Practices
|
|
176
|
+
|
|
177
|
+
1. Configure the wasm path for production: `sqlite.config({ wasmUrl })` or `sqlite.config({ loader })`.
|
|
178
|
+
2. Create one named database per feature and reuse the handle: `const db = await sqlite.db.create('app')`.
|
|
179
|
+
3. Always release databases you no longer need: `sqlite.db.delete('temp')`.
|
|
180
|
+
4. Use `await sqlite.ready` before running statements to ensure the engine is loaded.
|
|
181
|
+
5. Use `?` placeholders and `params` to avoid SQL injection.
|