UNPKG

tinybase

Version:

A reactive data store and sync engine.

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