tinybase
Version:
A reactive data store and sync engine.
2 lines (1 loc) • 4.25 kB
JavaScript
const t=t=>(e,a,n)=>t(e)?n?.():a(e),e=globalThis.window,a=t=>null==t,n=t=>void 0===t,s=t=>null===t,r=t(a),o=t(n),i=t=>Array.isArray(t),c=t=>t.length,l=t=>{throw Error(t)},y=async(t,e,a)=>{try{return await t()}catch(t){e?.(t)}},w=(t,e)=>t.forEach(e),g=(t,e)=>t.map(e),d=(t,...e)=>t.push(...e),u=t=>t.shift(),p=Object,v=t=>p.getPrototypeOf(t),h=p.entries,S=t=>!a(t)&&r(v(t),t=>t==p.prototype||a(v(t)),()=>!0),b=p.keys,f=p.freeze,A=t=>S(t)&&0==(t=>c(b(t)))(t),C=JSON.stringify,L=JSON.parse,m=t=>C(t,(t,e)=>n(e)?"":e),M=t=>E(L(t)),E=t=>""===t?void 0:i(t)?g(t,E):S(t)?((t,e)=>((t=[])=>p.fromEntries(t))(((t,e)=>g(h(t),([t,a])=>e(a,t)))(t,(t,a)=>[a,e(t,a)])))(t,E):t,O=t=>n(t)||0==(t=>t?.size??0)(t),P=(t,e)=>t?.forEach(e),T=(t,e)=>t?.delete(e),F=Map,N=t=>new F(t),k=(t,e)=>t?.get(e),x=(t,e,a)=>n(a)?(T(t,e),t):t?.set(e,a),z=(t,e,a,n)=>{var s,r;return s=t,r=e,s?.has(r)?n?.(k(t,e)):x(t,e,a()),k(t,e)},D=(t,e,a,n,s=0)=>o((a?z:k)(t,e[s],s>c(e)-2?a:N),r=>{if(s>c(e)-2)return n?.(r)&&x(t,e[s]),r;const o=D(r,e,a,n,s+1);return O(r)&&x(t,e[s]),o}),I=/^\d+$/,J=t=>new Set(i(t)||n(t)?t:[t]),j=N(),H=N(),V=(t,e,a,r,g,p,v,h={},S=0,b=[])=>{let C,L,m,M=0,E=0,F=0;z(j,b,()=>0),z(H,b,()=>[]);const V=N(),[W,$,q,B,G]=((t=1,e,a)=>1!=t&&e.isMergeable()?[1,e.getMergeableContent,()=>e.getTransactionMergeableChanges(!a),([[t],[e]])=>!A(t)||!A(e),e.setDefaultContent]:2!=t?[0,e.getContent,e.getTransactionChanges,([t,e])=>!A(t)||!A(e),e.setContent]:l("Store type not supported by this Persister"))(v,t,S),[K,Q,R]=(()=>{let t;const[e,a]=(()=>{const t=[];let e=0;return[a=>(a?u(t):null)??""+e++,e=>{I.test(e)&&c(t)<1e3&&d(t,e)}]})(),n=N();return[(a,s,r,o=[],i=()=>[])=>{t??=it;const c=e(1);var l,y;return x(n,c,[a,s,r,o,i]),l=D(s,r??[""],J),y=c,l?.add(y),c},(e,a,...r)=>w(((t,e=[""])=>{const a=[],n=(t,r)=>r==c(e)?d(a,t):s(e[r])?P(t,t=>n(t,r+1)):w([e[r],null],e=>n(k(t,e),r+1));return n(t,0),a})(e,a),e=>P(e,e=>k(n,e)[0](t,...a??[],...r))),t=>o(k(n,t),([,e,s])=>(D(e,s??[""],void 0,e=>(T(e,t),O(e)?1:0)),x(n,t),a(t),s)),e=>o(k(n,e),([e,,a=[],n,r])=>{const o=(...i)=>{const l=c(i);l==c(a)?e(t,...i,...r(i)):s(a[l])?w(n[l]?.(...i)??[],t=>o(...i,t)):o(...i,a[l])};o()})]})(),U=t=>{t!=M&&(M=t,Q(V,void 0,M))},X=e=>{(W&&i(e?.[0])?1===e?.[2]?t.applyMergeableChanges:t.setMergeableContent:1===e?.[2]?t.applyChanges:t.setContent)(e)},Y=async()=>{st()&&t.hadMutated?.()&&await et()},Z=async t=>(2!=M&&(U(1),E++,await ot(async()=>{await y(async()=>{const a=await e();i(a)?X(a):t?G(t):l("Content is not an array: "+a)},()=>{t&&G(t)}),U(0),await Y()})),it),_=async t=>(tt(),await Z(t),await y(async()=>L=await r(async(t,e)=>{e||t?2!=M&&(U(1),E++,X(e??t),U(0),await Y()):await Z()}),p),it),tt=async()=>(L&&(await y(()=>g(L),p),L=void 0),it),et=async t=>(1!=M&&(U(2),F++,await ot(async()=>{await y(()=>a($,t),p),U(0)})),it),at=async()=>(nt(),await et(),m=t.addDidFinishTransactionListener(()=>{const t=q();B(t)&&et(t)}),it),nt=async()=>(m&&(t.delListener(m),m=void 0),it),st=()=>!n(m),rt=async(t=!1)=>{const[e,a]=t?[nt,tt]:[tt,nt];return await e(),await a(),it},ot=async(...t)=>(d(k(H,b),...t),await(async()=>{if(!k(j,b)){for(x(j,b,1);!n(C=u(k(H,b)));)await y(C,p);x(j,b,0)}})(),it),it={load:Z,startAutoLoad:_,stopAutoLoad:tt,isAutoLoading:()=>!n(L),save:et,startAutoSave:at,stopAutoSave:nt,isAutoSaving:st,startAutoPersisting:async(t,e=!1)=>{const[a,n]=e?[at,_]:[_,at];return await a(t),await n(t),it},stopAutoPersisting:rt,getStatus:()=>M,addStatusListener:t=>K(t,V),delListener:e=>(R(e),t),schedule:ot,getStore:()=>t,destroy:()=>(k(H,b).splice(0,void 0),rt()),getStats:()=>({loads:E,saves:F}),...h};return f(it)},W="storage",$=(t,a,n,s)=>V(t,async()=>M(n.getItem(a)),async t=>n.setItem(a,m(t())),t=>{const s=e=>{e.storageArea===n&&e.key===a&&y(()=>t(M(e.newValue)),t)};return e.addEventListener(W,s),s},t=>e.removeEventListener(W,t),s,3,{getStorageName:()=>a}),q=(t,e,a)=>$(t,e,localStorage,a),B=(t,e,a)=>$(t,e,sessionStorage,a),G=(t,e,a)=>V(t,async()=>M(await(await e.getFile()).text()),async t=>{const a=await e.createWritable();await a.write(m(t())),await a.close()},async t=>{const a=new FileSystemObserver(()=>t());return await a.observe(e),a},t=>t?.disconnect(),a,3,{getHandle:()=>e});export{q as createLocalPersister,G as createOpfsPersister,B as createSessionPersister};