UNPKG

tinybase

Version:

A reactive data store and sync engine.

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