UNPKG

tinybase

Version:

A reactive data store and sync engine.

2 lines (1 loc) 5.4 kB
const t=(t,e="",a)=>t.split(e,a),e=Promise,a=globalThis,n=Math,s=n.floor,o=t=>null==t,r=(t,e,a)=>o(t)?a?.():e(t),i=t=>Array.isArray(t),l=t=>t.length,c=t=>{throw Error(t)},g=(t,e)=>t.forEach(e),u=(t,...e)=>t.push(...e),y=t=>t.shift(),d=t=>o(t)||0==(t=>t?.size??0)(t),f=(t,e)=>t?.forEach(e),h=(t,e)=>t?.delete(e),p=Object,w=t=>p.getPrototypeOf(t),v=p.entries,b=p.keys,C=p.freeze,M=(t,e)=>g(v(t),(([t,a])=>e(a,t))),S=t=>(t=>!o(t)&&r(w(t),(t=>t==p.prototype||o(w(t))),(()=>!0)))(t)&&0==(t=>l(b(t)))(t),A=(t,e,a)=>(((t,e)=>e in t)(t,e)||(t[e]=a()),t[e]),D=t=>new Map(t),L=(t,e)=>t?.get(e),H=(t,e,a)=>o(a)?(h(t,e),t):t?.set(e,a),T=(t,e,a,n)=>{var s,o;return s=t,o=e,s?.has(o)?n?.(L(t,e)):H(t,e,a()),L(t,e)},m=(t,e,a,n,s=0)=>r((a?T:L)(t,e[s],s>l(e)-2?a:D),(o=>{if(s>l(e)-2)return n?.(o)&&H(t,e[s]),o;const r=m(o,e,a,n,s+1);return d(o)&&H(t,e[s]),r})),G=t("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"),R=a.crypto?t=>a.crypto.getRandomValues(t):t=>(t=>t.map((()=>s(256*n.random()))))(t),E=(t=16)=>{return e=(t,e)=>t+G[63&e],R(new Uint8Array(t)).reduce(e,"");var e},V=(t,e)=>e?[t,e]:[t],z=(t,e)=>((t??"")>(e??"")?t:e)??"",P=(t="")=>V(((t=[])=>p.fromEntries(t))(),t),O=/^\d+$/,$=t=>new Set(i(t)||o(t)?t:[t]),j=D(),k=D(),x=(t,e,a,n,s,p,w,v={},b=0,M=[])=>{let A,G,R,E=0,V=0,z=0;T(j,M,(()=>0)),T(k,M,(()=>[]));const P=D(),[x,F,N,U,q]=((t=1,e,a)=>1!=t&&e.isMergeable()?[1,e.getMergeableContent,()=>e.getTransactionMergeableChanges(!a),([[t],[e]])=>!S(t)||!S(e),e.setDefaultContent]:2!=t?[0,e.getContent,e.getTransactionChanges,([t,e])=>!S(t)||!S(e),e.setContent]:c("Store type not supported by this Persister"))(w,t,b),[B,I,J]=(()=>{let t;const[e,a]=(()=>{const t=[];let e=0;return[a=>(a?y(t):null)??""+e++,e=>{O.test(e)&&l(t)<1e3&&u(t,e)}]})(),n=D();return[(a,s,o,r=[],i=()=>[])=>{t??=tt;const l=e(1);var c,g;return H(n,l,[a,s,o,r,i]),c=m(s,o??[""],$),g=l,c?.add(g),l},(e,a,...s)=>g(((t,e=[""])=>{const a=[],n=(t,s)=>s==l(e)?u(a,t):null===e[s]?f(t,(t=>n(t,s+1))):g([e[s],null],(e=>n(L(t,e),s+1)));return n(t,0),a})(e,a),(e=>f(e,(e=>L(n,e)[0](t,...a??[],...s))))),t=>r(L(n,t),(([,e,s])=>(m(e,s??[""],void 0,(e=>(h(e,t),d(e)?1:0))),H(n,t),a(t),s))),e=>r(L(n,e),(([e,,a=[],n,s])=>{const r=(...i)=>{const c=l(i);c==l(a)?e(t,...i,...s(i)):o(a[c])?g(n[c]?.(...i)??[],(t=>r(...i,t))):r(...i,a[c])};r()}))]})(),K=t=>{t!=E&&(E=t,I(P,void 0,E))},Q=e=>{(x&&i(e?.[0])?1===e?.[2]?t.applyMergeableChanges:t.setMergeableContent:1===e?.[2]?t.applyChanges:t.setContent)(e)},W=async t=>(2!=E&&(K(1),V++,await _((async()=>{try{const a=await e();i(a)?Q(a):t?q(t):c("Content is not an array: "+a)}catch(e){p?.(e),t&&q(t)}K(0)}))),tt),X=()=>(G&&(s(G),G=void 0),tt),Y=async t=>(1!=E&&(K(2),z++,await _((async()=>{try{await a(F,t)}catch(t){p?.(t)}K(0)}))),tt),Z=()=>(R&&(t.delListener(R),R=void 0),tt),_=async(...t)=>(u(L(k,M),...t),await(async()=>{if(!L(j,M)){for(H(j,M,1);!o(A=y(L(k,M)));)try{await A()}catch(t){p?.(t)}H(j,M,0)}})(),tt),tt={load:W,startAutoLoad:async t=>{X(),await W(t);try{G=await n((async(t,e)=>{e||t?2!=E&&(K(1),V++,Q(e??t),K(0)):await W()}))}catch(t){p?.(t)}return tt},stopAutoLoad:X,isAutoLoading:()=>!o(G),save:Y,startAutoSave:async()=>(Z(),await Y(),R=t.addDidFinishTransactionListener((()=>{const t=N();U(t)&&Y(t)})),tt),stopAutoSave:Z,isAutoSaving:()=>!o(R),getStatus:()=>E,addStatusListener:t=>B(t,P),delListener:e=>(J(e),t),schedule:_,getStore:()=>t,destroy:()=>(L(k,M).splice(0,void 0),X().stopAutoSave()),getStats:()=>({loads:V,saves:z}),...v};return C(tt)},F={Response:0,GetContentHashes:1,ContentHashes:2,ContentDiff:3,GetTableDiff:4,GetRowDiff:5,GetCellDiff:6,GetValueDiff:7},N=(t,a,n,s,i,l,c,g,u={})=>{let y,d=0,f=0,p=0;const w=D(),v=()=>E(11),b=(t,e,n,s)=>{f++,l?.(t,e,n,s),a(t,e,n,s)},C=async(t,a,n,s)=>new e(((e,o)=>{const r=s+"."+E(4),l=((t,e=0)=>setTimeout(t,1e3*e))((()=>{h(w,r),o(`No response from ${t??"anyone"} to ${r}, `+a)}),i);H(w,r,[t,(t,a)=>{clearTimeout(l),h(w,r),e([t,a,s])}]),b(t,r,a,n)})),T=(t,[e,a])=>{M(e,(([e,a],n)=>{const s=A(t[0],n,P);M(e,(([t,e],a)=>{const n=A(s[0],a,P);M(t,(([t,e],a)=>n[0][a]=V(t,e))),n[1]=z(n[1],e)})),s[1]=z(s[1],a)})),t[1]=z(t[1],a)},m=async(e=null,a,n=v())=>{try{o(a)&&([a,e,n]=await C(null,1,"",n));const[s,r]=a,[i,l]=t.getMergeableContentHashes();let c=P();if(i!=s){const[a,s]=(await C(e,4,t.getMergeableTableHashes(),n))[0];if(c=a,!S(s)){const[a,o]=(await C(e,5,t.getMergeableRowHashes(s),n))[0];if(T(c,a),!S(o)){const a=(await C(e,6,t.getMergeableCellHashes(o),n))[0];T(c,a)}}}return[c,l==r?P():(await C(e,7,t.getMergeableValueHashes(),n))[0],1]}catch(t){g?.(t)}},G=x(t,(async()=>{const t=await m();return!t||S(t[0][0])&&S(t[1][0])?void 0:t}),(async(e,a)=>a?b(null,v(),3,a):b(null,v(),2,t.getMergeableContentHashes())),(t=>y=t),(()=>y=void 0),g,2,{startSync:async t=>(d=1,await(await G.startAutoLoad(t)).startAutoSave()),stopSync:()=>(d=0,G.stopAutoLoad().stopAutoSave()),destroy:()=>(s(),G.stopSync()),getSynchronizerStats:()=>({sends:f,receives:p}),...u},1);return n(((e,a,n,s)=>{const i=d||G.isAutoLoading();p++,c?.(e,a,n,s),0==n?r(L(w,a),(([t,a])=>o(t)||t==e?a(s,e):0)):2==n&&i?m(e,s,a??void 0).then((t=>{y?.(void 0,t)})).catch(g):3==n&&i?y?.(void 0,s):r(1==n&&(d||G.isAutoSaving())?t.getMergeableContentHashes():4==n?t.getMergeableTableDiff(s):5==n?t.getMergeableRowDiff(s):6==n?t.getMergeableCellDiff(s):7==n?t.getMergeableValueDiff(s):void 0,(t=>{b(e,a,0,t)}))})),G};export{F as Message,N as createCustomSynchronizer};