UNPKG

tinybase

Version:

A reactive data store and sync engine.

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