UNPKG

tinybase

Version:

A reactive data store and sync engine.

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