UNPKG

tinybase

Version:

A reactive data store and sync engine.

2 lines (1 loc) 7.29 kB
import{DurableObject as t}from"cloudflare:workers";const e="",s=(t,e="",s)=>t.split(e,s),a=Promise,n=t=>(e,s,a)=>t(e)?a?.():s(e),r=globalThis,i=(t,e=0)=>setTimeout(t,1e3*e),o=Math,c=o.floor,l=t=>null==t,g=t=>void 0===t,u=t=>null===t,d=n(l),h=n(g),y=t=>Array.isArray(t),w=(t,e,s)=>t.slice(e,s),C=t=>t.length,p=t=>{throw Error(t)},S=async(t,e,s)=>{try{return await t()}catch(t){e?.(t)}},v=(t,e)=>t.forEach(e),b=(t,e)=>t.map(e),f=(t,...e)=>t.push(...e),M=t=>t.shift(),A=Object,m=t=>A.getPrototypeOf(t),P=A.entries,k=A.keys,T=A.freeze,x=(t,e)=>v(P(t),([t,s])=>e(s,t)),L=t=>(t=>!l(t)&&d(m(t),t=>t==A.prototype||l(m(t)),()=>!0))(t)&&0==(t=>C(k(t)))(t),I=(t,e,s)=>(((t,e)=>e in t)(t,e)||(t[e]=s()),t[e]),H=JSON.stringify,D=JSON.parse,O=(t,e)=>{const s=t.indexOf("\n");-1!==s&&e(w(t,0,s),w(t,s+1))},R=(t,...s)=>E(t??e,H(s,(t,e)=>g(e)?"":e)),E=(t,e)=>t+"\n"+e,N=t=>g(t)||0==(t=>t?.size??0)(t),W=(t,e)=>t?.forEach(e),z=(t,e)=>t?.delete(e),U=t=>new Map(t),V=(t,e)=>t?.get(e),F=(t,e,s)=>g(s)?(z(t,e),t):t?.set(e,s),J=(t,e,s,a)=>{var n,r;return n=t,r=e,n?.has(r)?a?.(V(t,e)):F(t,e,s()),V(t,e)},$=(t,e,s,a,n=0)=>h((s?J:V)(t,e[n],n>C(e)-2?s:U),r=>{if(n>C(e)-2)return a?.(r)&&F(t,e[n]),r;const i=$(r,e,s,a,n+1);return N(r)&&F(t,e[n]),i}),j=s("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"),q=r.crypto?t=>r.crypto.getRandomValues(t):t=>b(t,()=>c(256*o.random())),B=(t=16)=>{return e=(t,e)=>t+j[63&e],q(new Uint8Array(t)).reduce(e,"");var e},G=(t,e)=>e?[t,e]:[t],K=(t,e)=>((t??"")>(e??"")?t:e)??"",Q=(t="")=>G(((t=[])=>A.fromEntries(t))(),t),X=/^\d+$/,Y=t=>new Set(y(t)||g(t)?t:[t]),Z=U(),_=U(),tt=(t,s,a,n,r,i,o,c={},l=0,d=[])=>{let w,b,A,m=0,P=0,k=0;J(Z,d,()=>0),J(_,d,()=>[]);const x=U(),[I,H,D,O,R]=((t=1,e,s)=>1!=t&&e.isMergeable()?[1,e.getMergeableContent,()=>e.getTransactionMergeableChanges(!s),([[t],[e]])=>!L(t)||!L(e),e.setDefaultContent]:2!=t?[0,e.getContent,e.getTransactionChanges,([t,e])=>!L(t)||!L(e),e.setContent]:p("Store type not supported by this Persister"))(o,t,l),[E,j,q]=(()=>{let t;const[s,a]=(()=>{const t=[];let s=0;return[a=>(a?M(t):null)??e+s++,e=>{X.test(e)&&C(t)<1e3&&f(t,e)}]})(),n=U();return[(a,r,i,o=[],c=()=>[])=>{t??=it;const l=s(1);var g,u;return F(n,l,[a,r,i,o,c]),g=$(r,i??[e],Y),u=l,g?.add(u),l},(s,a,...r)=>v(((t,s=[e])=>{const a=[],n=(t,e)=>e==C(s)?f(a,t):u(s[e])?W(t,t=>n(t,e+1)):v([s[e],null],s=>n(V(t,s),e+1));return n(t,0),a})(s,a),e=>W(e,e=>V(n,e)[0](t,...a??[],...r))),t=>h(V(n,t),([,s,r])=>($(s,r??[e],void 0,e=>(z(e,t),N(e)?1:0)),F(n,t),a(t),r)),e=>h(V(n,e),([e,,s=[],a,n])=>{const r=(...i)=>{const o=C(i);o==C(s)?e(t,...i,...n(i)):u(s[o])?v(a[o]?.(...i)??[],t=>r(...i,t)):r(...i,s[o])};r()})]})(),B=t=>{t!=m&&(m=t,j(x,void 0,m))},G=e=>{(I&&y(e?.[0])?1===e?.[2]?t.applyMergeableChanges:t.setMergeableContent:1===e?.[2]?t.applyChanges:t.setContent)(e)},K=async t=>(2!=m&&(B(1),P++,await rt(async()=>{await S(async()=>{const e=await s();y(e)?G(e):t?R(t):p("Content is not an array: "+e)},()=>{t&&R(t)}),B(0)})),it),Q=async t=>(tt(),await K(t),await S(async()=>b=await n(async(t,e)=>{e||t?2!=m&&(B(1),P++,G(e??t),B(0)):await K()}),i),it),tt=async()=>(b&&(await S(()=>r(b),i),b=void 0),it),et=async t=>(1!=m&&(B(2),k++,await rt(async()=>{await S(()=>a(H,t),i),B(0)})),it),st=async()=>(at(),await et(),A=t.addDidFinishTransactionListener(()=>{const t=D();O(t)&&et(t)}),it),at=async()=>(A&&(t.delListener(A),A=void 0),it),nt=async(t=!1)=>{const[e,s]=t?[at,tt]:[tt,at];return await e(),await s(),it},rt=async(...t)=>(f(V(_,d),...t),await(async()=>{if(!V(Z,d)){for(F(Z,d,1);!g(w=M(V(_,d)));)await S(w,i);F(Z,d,0)}})(),it),it={load:K,startAutoLoad:Q,stopAutoLoad:tt,isAutoLoading:()=>!g(b),save:et,startAutoSave:st,stopAutoSave:at,isAutoSaving:()=>!g(A),startAutoPersisting:async(t,e=!1)=>{const[s,a]=e?[st,Q]:[Q,st];return await s(t),await a(t),it},stopAutoPersisting:nt,getStatus:()=>m,addStatusListener:t=>E(t,x),delListener:e=>(q(e),t),schedule:rt,getStore:()=>t,destroy:()=>(V(_,d).splice(0,void 0),nt()),getStats:()=>({loads:P,saves:k}),...c};return T(it)},et=/\/([^?]*)/,st="S",at=t=>{return(s=new URL(t.url).pathname,a=et,s?.match(a))?.[1]??e;var s,a},nt=t=>"websocket"==t.headers.get("upgrade")?.toLowerCase()?t.headers.get("sec-websocket-key"):null,rt=(t,e=null,s=null)=>new Response(s,{status:t,webSocket:e}),it=()=>rt(426,null,"Upgrade required");class ot extends t{#t;constructor(t,s){super(t,s),this.ctx.blockConcurrencyWhile(async()=>await h(await this.createPersister(),async t=>{const s=((t,s,n,r,o,c,l,d,y={})=>{let w,C=0,p=0,v=0;const b=U(),f=()=>B(11),M=(t,e,a,n)=>{p++,s(t,e,a,n)},A=async(t,e,s,n)=>new a((a,r)=>{const c=n+"."+B(4),l=i(()=>{z(b,c),r(`No response from ${t??"anyone"} to ${c}, `+e)},o);F(b,c,[t,(t,e)=>{clearTimeout(l),z(b,c),a([t,e,n])}]),M(t,c,e,s)}),m=(t,[e,s])=>{x(e,([e,s],a)=>{const n=I(t[0],a,Q);x(e,([t,e],s)=>{const a=I(n[0],s,Q);x(t,([t,e],s)=>a[0][s]=G(t,e)),a[1]=K(a[1],e)}),n[1]=K(n[1],s)}),t[1]=K(t[1],s)},P=(s=null,a,n=f())=>S(async()=>{g(a)&&([a,s,n]=await A(null,1,e,n));const[r,i]=a,[o,c]=t.getMergeableContentHashes();let l=Q();if(o!=r){const[e,a]=(await A(s,4,t.getMergeableTableHashes(),n))[0];if(l=e,!L(a)){const[e,r]=(await A(s,5,t.getMergeableRowHashes(a),n))[0];if(m(l,e),!L(r)){const e=(await A(s,6,t.getMergeableCellHashes(r),n))[0];m(l,e)}}}return[l,c==i?Q():(await A(s,7,t.getMergeableValueHashes(),n))[0],1]},d),k=tt(t,async()=>{const t=await P();return!t||L(t[0][0])&&L(t[1][0])?void 0:t},async(e,s)=>s?M(null,f(),3,s):M(null,f(),2,t.getMergeableContentHashes()),t=>w=t,()=>w=void 0,d,2,{startSync:async t=>(C=1,await k.startAutoPersisting(t)),stopSync:async()=>(C=0,await k.stopAutoPersisting(),k),destroy:async()=>(await k.stopSync(),k),getSynchronizerStats:()=>({sends:p,receives:v}),...y},1);return n((e,s,a,n)=>{const r=C||k.isAutoLoading();v++,0==a?h(V(b,s),([t,s])=>u(t)||t==e?s(n,e):0):2==a&&r?P(e,n,s??void 0).then(t=>{w?.(void 0,t)}).catch(d):3==a&&r?w?.(void 0,n):h(1==a&&(C||k.isAutoSaving())?t.getMergeableContentHashes():4==a?t.getMergeableTableDiff(n):5==a?t.getMergeableRowDiff(n):6==a?t.getMergeableCellDiff(n):7==a?t.getMergeableValueDiff(n):void 0,t=>{M(e,s,0,t)})}),k})(t.getStore(),(t,e,s,a)=>this.#e(st,R(t,e,s,a)),t=>this.#t=e=>((t,e)=>O(t,(t,s)=>{return e(t,...(a=s,D(a,(t,e)=>""===e?void 0:e)));var a}))(e,t),0,1);await t.load(),await t.startAutoSave(),i(s.startSync)}))}fetch(t){const s=at(t);return h(nt(t),t=>{const[a,n]=(r=new WebSocketPair,A.values(r));var r,i;return i=this.#s(),0==C(i)&&this.onPathId(s,1),this.ctx.acceptWebSocket(n,[t,s]),this.onClientId(s,t,1),n.send(R(st,null,1,e)),rt(101,a)},it)}webSocketMessage(t,e){h(this.ctx.getTags(t)[0],s=>this.#e(s,e.toString(),t))}webSocketClose(t){const[e,s]=this.ctx.getTags(t);this.onClientId(s,e,-1),1==C(this.#s())&&this.onPathId(s,-1)}#e(t,s,a){O(s.toString(),(s,n)=>{const r=E(t,n);this.onMessage(t,s,n),s==e?(t!=st&&this.#t?.(r),v(this.#s(),t=>{t!=a&&t.send(r)})):s==st?this.#t?.(r):s!=t&&this.#s(s)[0]?.send(r)})}#s(t){return this.ctx.getWebSockets(t)}createPersister(){}getPathId(){return this.ctx.getTags(this.#s()[0])?.[1]}getClientIds(){return b(this.#s(),t=>this.ctx.getTags(t)[0])}onPathId(t,e){}onClientId(t,e,s){}onMessage(t,e,s){}}const ct=t=>(e,s)=>nt(e)?s[t].get(s[t].idFromName(at(e))).fetch(e):it();export{ot as WsServerDurableObject,ct as getWsServerDurableObjectFetch};