tinybase
Version:
A reactive data store and sync engine.
2 lines (1 loc) • 3.08 kB
JavaScript
const a=a=>typeof a,t="",e=a(t),s="t",n=(a,t)=>a.startsWith(t),i=Promise,r=a=>(t,e,s)=>a(t)?s?.():e(t),c=a=>null==a,o=a=>void 0===a,l=r(c),w=r(o),y=(a,t,e)=>a.slice(t,e),g=a=>a.length,h=async a=>i.all(a),f=(a,t)=>a.map(t),u=(a,...t)=>a.push(...t),p=Object,d=a=>p.getPrototypeOf(a),P=p.entries,S=(a=[])=>p.fromEntries(a),m=(a,t)=>f(P(a),([a,e])=>t(e,a)),x=(a,t,e)=>(((a,t)=>t in a)(a,t)||(a[t]=e()),a[t]),D=JSON.stringify,R=JSON.parse,b=a=>D(a,(a,t)=>t instanceof Map?p.fromEntries([...t]):t),v=a=>C(R(a)),C=a=>""===a?void 0:Array.isArray(a)?f(a,C):(a=>!c(a)&&l(d(a),a=>a==p.prototype||c(d(a)),()=>!0))(a)?((a,t)=>S(m(a,(a,e)=>[e,t(a,e)])))(a,C):a,O=(a,t)=>((a,t)=>a?.forEach(t))(a,(a,e)=>t(e,a)),T="/store",A=(t,s,n)=>t+s+(a(n)==e?n:D(n,(a,t)=>o(t)?"":t)),V=(a,t,e)=>{const s=g(a);return n(t,a)?[t[s],(e?v:String)(y(t,s+1))]:void 0},E="hasStore",H=S(f(["Origin","Methods","Headers"],a=>["Access-Control-Allow-"+a,"*"])),M=async(a,e=t)=>!!await a.get(e+E),J=async(a,e=t)=>{const n={},i={};return O(await a.list(),(a,t)=>w(V(e,a),([a,e])=>{if(a==s){const[a,s,i]=R("["+e+"]");x(x(n,a,S),s,S)[i]=t}else"v"==a&&(i[e]=t)})),[n,i]},N=async(a,e,s)=>a.party.broadcast(A(a.config.messagePrefix??t,"s",e),s),U=async(a,e,i,r)=>{const c=a.party.storage,l=a.config.storagePrefix??t,w={[l+E]:1},y=[],f=[];await h(m(e[0],async(t,e)=>o(t)?!i&&await a.canDelTable(e,r)&&((a,...t)=>a.unshift(...t))(f,W(l,s,e)):await a.canSetTable(e,i,r)&&await h(m(t,async(t,n)=>o(t)?!i&&await a.canDelRow(e,n,r)&&u(f,W(l,s,e,n)):await a.canSetRow(e,n,i,r)&&await h(m(t,async(t,g)=>{const h=[e,n,g],f=W(l,s,...h);o(t)?!i&&await a.canDelCell(...h,r)&&u(y,f):await a.canSetCell(...h,t,i,r,await c.get(f))&&(w[f]=t)})))))),await h(m(e[1],async(t,e)=>{const s=l+"v"+e;o(t)?!i&&await a.canDelValue(e,r)&&u(y,s):await a.canSetValue(e,t,i,r,await c.get(s))&&(w[s]=t)})),0!=g(f)&&O(await c.list(),a=>f.every(t=>!n(a,t)||u(y,a)&&0)),await c.delete(y),await c.put(w)},W=(a,t,...e)=>A(a,t,y(b(e),1,-1)),j=async(a,t,e=null)=>new Response(e,{status:t,headers:a.config.responseHeaders});class q{constructor(a){this.party=a,this.config.storePath??=T,this.config.messagePrefix??=t,this.config.storagePrefix??=t,this.config.responseHeaders??=H}config={};async onRequest(a){const{party:{storage:e},config:{storePath:s=T,storagePrefix:n}}=this;if(new URL(a.url).pathname.endsWith(s)){const s=await M(e,n),i=await a.text();return"PUT"==a.method?s?j(this,205):(await U(this,R(i),!0,a),j(this,201)):j(this,200,s?b(await J(e,n)):t)}return j(this,404)}async onMessage(a,e){const{config:{messagePrefix:s=t,storagePrefix:n}}=this;await w(V(s,a,1),async([a,t])=>{"s"==a&&await M(this.party.storage,n)&&(await U(this,t,!1,e),N(this,t,[e.id]))})}async canSetTable(a,t,e){return!0}async canDelTable(a,t){return!0}async canSetRow(a,t,e,s){return!0}async canDelRow(a,t,e){return!0}async canSetCell(a,t,e,s,n,i,r){return!0}async canDelCell(a,t,e,s){return!0}async canSetValue(a,t,e,s,n){return!0}async canDelValue(a,t){return!0}}export{q as TinyBasePartyKitServer,N as broadcastChanges,M as hasStoreInStorage,J as loadStoreFromStorage};