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