UNPKG

tinybase

Version:

A reactive data store and sync engine.

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