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