UNPKG

tinybase

Version:

A reactive data store and sync engine.

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