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