tinybase
Version:
A reactive data store and sync engine.
2 lines (1 loc) • 4.15 kB
JavaScript
const t=t=>null==t,e=(e,a,n)=>t(e)?n?.():a(e),a=t=>Array.isArray(t),n=t=>t.length,s=t=>{throw Error(t)},r=(t,e)=>t.forEach(e),o=(t,...e)=>t.push(...e),c=t=>t.shift(),i=Object,d=t=>i.getPrototypeOf(t),l=i.entries,u=i.keys,y=i.freeze,g=(t=[])=>i.fromEntries(t),h=(t,a)=>e(t,(t=>t[a])),v=(t,e)=>e in t,p=(t,e)=>(delete t[e],t),w=(t,e)=>g(((t,e)=>((t,e)=>t.map(e))(l(t),(([t,a])=>e(a,t))))(t,((t,a)=>[a,e(t,a)]))),f=t=>n(u(t)),C=a=>(a=>!t(a)&&e(d(a),(e=>e==i.prototype||t(d(e))),(()=>!0)))(a)&&0==f(a),S=(t,e,a)=>(v(t,e)||(t[e]=a()),t[e]),A=e=>t(e)||0==(t=>t?.size??0)(e),b=(t,e)=>t?.forEach(e),L=(t,e)=>t?.delete(e),M=t=>new Map(t),E=(t,e)=>t?.get(e),m=(e,a,n)=>t(n)?(L(e,a),e):e?.set(a,n),D=(t,e,a,n)=>{var s,r;return s=t,r=e,s?.has(r)?n?.(E(t,e)):m(t,e,a()),E(t,e)},T=(t,a,s,r,o=0)=>e((s?D:E)(t,a[o],o>n(a)-2?s:M),(e=>{if(o>n(a)-2)return r?.(e)&&m(t,a[o]),e;const c=T(e,a,s,r,o+1);return A(e)&&m(t,a[o]),c})),z=/^\d+$/,O=e=>new Set(a(e)||t(e)?e:[e]),P=M(),j=M(),k=(i,d,l,u,g,h,v,p={},w=0,f=[])=>{let S,k,x,F=0,H=0,$=0;D(P,f,(()=>0)),D(j,f,(()=>[]));const q=M(),[B,G,I,J,K]=((t=1,e,a)=>1!=t&&e.isMergeable()?[1,e.getMergeableContent,()=>e.getTransactionMergeableChanges(!a),([[t],[e]])=>!C(t)||!C(e),e.setDefaultContent]:2!=t?[0,e.getContent,e.getTransactionChanges,([t,e])=>!C(t)||!C(e),e.setContent]:s("Store type not supported by this Persister"))(v,i,w),[N,Q,R]=(()=>{let a;const[s,i]=(()=>{const t=[];let e=0;return[a=>(a?c(t):null)??""+e++,e=>{z.test(e)&&n(t)<1e3&&o(t,e)}]})(),d=M();return[(t,e,n,r=[],o=()=>[])=>{a??=tt;const c=s(1);var i,l;return m(d,c,[t,e,n,r,o]),i=T(e,n??[""],O),l=c,i?.add(l),c},(t,e,...s)=>r(((t,e=[""])=>{const a=[],s=(t,c)=>c==n(e)?o(a,t):null===e[c]?b(t,(t=>s(t,c+1))):r([e[c],null],(e=>s(E(t,e),c+1)));return s(t,0),a})(t,e),(t=>b(t,(t=>E(d,t)[0](a,...e??[],...s))))),t=>e(E(d,t),(([,e,a])=>(T(e,a??[""],void 0,(e=>(L(e,t),A(e)?1:0))),m(d,t),i(t),a))),s=>e(E(d,s),(([e,,s=[],o,c])=>{const i=(...d)=>{const l=n(d);l==n(s)?e(a,...d,...c(d)):t(s[l])?r(o[l]?.(...d)??[],(t=>i(...d,t))):i(...d,s[l])};i()}))]})(),U=t=>{t!=F&&(F=t,Q(q,void 0,F))},V=t=>{(B&&a(t?.[0])?1===t?.[2]?i.applyMergeableChanges:i.setMergeableContent:1===t?.[2]?i.applyChanges:i.setContent)(t)},W=async t=>(2!=F&&(U(1),H++,await _((async()=>{try{const e=await d();a(e)?V(e):t?K(t):s("Content is not an array: "+e)}catch(e){h?.(e),t&&K(t)}U(0)}))),tt),X=()=>(k&&(g(k),k=void 0),tt),Y=async t=>(1!=F&&(U(2),$++,await _((async()=>{try{await l(G,t)}catch(t){h?.(t)}U(0)}))),tt),Z=()=>(x&&(i.delListener(x),x=void 0),tt),_=async(...e)=>(o(E(j,f),...e),await(async()=>{if(!E(P,f)){for(m(P,f,1);!t(S=c(E(j,f)));)try{await S()}catch(t){h?.(t)}m(P,f,0)}})(),tt),tt={load:W,startAutoLoad:async t=>{X(),await W(t);try{k=await u((async(t,e)=>{e||t?2!=F&&(U(1),H++,V(e??t),U(0)):await W()}))}catch(t){h?.(t)}return tt},stopAutoLoad:X,isAutoLoading:()=>!t(k),save:Y,startAutoSave:async()=>(Z(),await Y(),x=i.addDidFinishTransactionListener((()=>{const t=I();J(t)&&Y(t)})),tt),stopAutoSave:Z,isAutoSaving:()=>!t(x),getStatus:()=>F,addStatusListener:t=>N(t,q),delListener:t=>(R(t),i),schedule:_,getStore:()=>i,destroy:()=>(E(j,f).splice(0,void 0),X().stopAutoSave()),getStats:()=>({loads:H,saves:$}),...p};return y(tt)},x=(t,e)=>[t[e].t,t[e].v],F=(e,a,n,s)=>{const r=t(a)?e:S(e,a,(()=>({})));let o;return w(n,((t,e)=>{s(r,e,t)&&(o=1)})),w(r,((t,e)=>{v(n,e)||(p(r,e),o=1)})),!t(a)&&C(r)&&p(e,a),o},H=(a,n,s="tinybase",r)=>(n.change((t=>S(t,s,g))),k(a,(async()=>{const t=await n.doc();return 2==f(t?.[s])?x(t,s):void 0}),(async(a,r)=>n.change((n=>((a,n,s,r)=>{((t,e)=>{C(t[e])&&(t[e]={t:{},v:{}})})(a,n);const[o,c]=x(a,n),i=()=>{d=1};let d=1;if(e(r,(([a,n])=>{d=0,w(a,((a,n)=>d?0:t(a)?p(o,n):e(o[n],(n=>w(a,((a,s)=>d?0:t(a)?p(n,s):e(h(n,s),(e=>w(a,((a,n)=>t(a)?p(e,n):e[n]=a))),i)))),i))),w(n,((e,a)=>d?0:t(e)?p(c,a):c[a]=e))})),d){const[t,e]=s();F(o,void 0,t,((t,e,a)=>F(o,e,a,((t,e,a)=>F(t,e,a,((t,e,a)=>{if(h(t,e)!==a)return t[e]=a,1})))))),F(c,void 0,e,((t,e,a)=>{h(c,e)!==a&&(c[e]=a)}))}})(n,s,a,r)))),(t=>{const e=({doc:e})=>t(x(e,s));return n.on("change",e),e}),(t=>{n.removeListener("change",t)}),r,1,{getDocHandle:()=>n}));export{H as createAutomergePersister};