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