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