UNPKG

tinybase

Version:

A reactive data store and sync engine.

2 lines (1 loc) 9.31 kB
const a=a=>typeof a,t="tinybase",e="",n=",",s=a(e),i="true",r=(a,t,e)=>a.replace(t,e),o=Promise,c=a=>(t,e,n)=>a(t)?n?.():e(t),l=globalThis,w=a=>null==a,y=a=>void 0===a,u=a=>null===a,d=c(w),E=c(y),N=t=>a(t)==s,g=a=>Array.isArray(a),A=(a,t,e)=>a.slice(t,e),T=a=>a.length,$=async a=>o.all(a),p=a=>{throw Error(a)},O=async(a,t,e)=>{try{return await a()}catch(a){t?.(a)}},R=(a,t)=>a.forEach(t),m=(a,t="")=>a.join(t),v=(a,t)=>a.map(t),C=a=>0==T(a),S=(a,t)=>a.filter(t),I=(a,...t)=>a.push(...t),L=a=>a.shift(),_=(a,t)=>a?.has(t)??!1,b=a=>y(a)||0==(a=>a?.size??0)(a),f=a=>[...a?.values()??[]],D=(a,t)=>a?.forEach(t),h=(a,t)=>a?.delete(t),P=Object,F=a=>P.getPrototypeOf(a),M=P.entries,U=P.keys,G=P.freeze,j=(a=[])=>P.fromEntries(a),x=(...a)=>P.assign({},...a),W=(a,t)=>(delete a[t],a),B=(a,t)=>v(M(a),([a,e])=>t(e,a)),H=(a,t)=>j(B(a,(a,e)=>[e,t(a,e)])),X=a=>P.values(a),Y=a=>T(U(a)),k=a=>(a=>!w(a)&&d(F(a),a=>a==P.prototype||w(F(a)),()=>!0))(a)&&0==Y(a),q=JSON.stringify,z=JSON.parse,J=a=>q(a,(a,t)=>y(t)?"":t),K=new l.TextEncoder,V=a=>new Map(a),Q=(a,t)=>a?.get(t),Z=(a,t)=>v([...a?.entries()??[]],([a,e])=>t(e,a)),aa=(a,t,e)=>y(e)?(h(a,t),a):a?.set(t,e),ta=(a,t,e,n)=>(_(a,t)?n?.(Q(a,t)):aa(a,t,e()),Q(a,t)),ea=(a,t,e,n,s=0)=>E((e?ta:Q)(a,t[s],s>T(t)-2?e:V),i=>{if(s>T(t)-2)return n?.(i)&&aa(a,t[s]),i;const r=ea(i,t,e,n,s+1);return b(i)&&aa(a,t[s]),r}),na="_",sa="_id",ia="SELECT",ra="WHERE",oa="TABLE",ca="INSERT",la="DELETE",wa="UPDATE",ya="ALTER "+oa,ua="FROM",da=la+" "+ua,Ea=ia+"*"+ua,Na="CREATE ",ga=Na+oa,Aa="OR REPLACE ",Ta="FUNCTION",$a="$tableName",pa=a=>m(v(((a,t="",e)=>a.split(t,e))(a,"."),a=>`"${r(a,/"/g,'""')}"`),"."),Oa=(...a)=>pa(m(a,"_")),Ra=(a,t=[1])=>m(v(a,()=>"$"+t[0]++),n),ma=(a,t=i)=>ra+`(${r(t,$a,pa(a))})`,va=a=>new Set(g(a)||y(a)?a:[a]),Ca=(a,t)=>a?.add(t),Sa="ColumnName",Ia="store",La="json",_a=Ia+"TableName",ba=Ia+"Id"+Sa,fa=Ia+Sa,Da="autoLoadIntervalSeconds",ha="rowId"+Sa,Pa="tableId",Fa="tableName",Ma="deleteEmptyColumns",Ua="deleteEmptyTable",Ga="condition",ja={mode:La,[Da]:1},xa={load:0,save:0,[Fa]:t+"_values"},Wa=(a,t,e,n,s)=>{const i=V();return H(a,(a,r)=>{const o=A(X(x(t,N(a)?{[e]:a}:a)),0,Y(t));u(o[0])||n(r,o[0])||(s(r,o[0]),aa(i,r,o))}),i},Ba=/^\d+$/,Ha=V(),Xa=V(),Ya=(a,t,n,s,i,r,o,c={},l=0,w=[])=>{let d,N,A,$=0,m=0,v=0;ta(Ha,w,()=>0),ta(Xa,w,()=>[]);const C=V(),[S,_,f,P,F]=((a=1,t,e)=>1!=a&&t.isMergeable()?[1,t.getMergeableContent,()=>t.getTransactionMergeableChanges(!e),([[a],[t]])=>!k(a)||!k(t),t.setDefaultContent]:2!=a?[0,t.getContent,t.getTransactionChanges,([a,t])=>!k(a)||!k(t),t.setContent]:p("Store type not supported by this Persister"))(o,a,l),[M,U,j]=(()=>{let a;const[t,n]=(()=>{const a=[];let t=0;return[n=>(n?L(a):null)??e+t++,t=>{Ba.test(t)&&T(a)<1e3&&I(a,t)}]})(),s=V();return[(n,i,r,o=[],c=()=>[])=>{a??=Z;const l=t(1);return aa(s,l,[n,i,r,o,c]),Ca(ea(i,r??[e],va),l),l},(t,n,...i)=>R(((a,t=[e])=>{const n=[],s=(a,e)=>e==T(t)?I(n,a):u(t[e])?D(a,a=>s(a,e+1)):R([t[e],null],t=>s(Q(a,t),e+1));return s(a,0),n})(t,n),t=>D(t,t=>Q(s,t)[0](a,...n??[],...i))),a=>E(Q(s,a),([,t,i])=>(ea(t,i??[e],void 0,t=>(h(t,a),b(t)?1:0)),aa(s,a),n(a),i)),t=>E(Q(s,t),([t,,e=[],n,s])=>{const i=(...r)=>{const o=T(r);o==T(e)?t(a,...r,...s(r)):u(e[o])?R(n[o]?.(...r)??[],a=>i(...r,a)):i(...r,e[o])};i()})]})(),x=a=>{a!=$&&($=a,U(C,void 0,$))},W=t=>{(S&&g(t?.[0])?1===t?.[2]?a.applyMergeableChanges:a.setMergeableContent:1===t?.[2]?a.applyChanges:a.setContent)(t)},B=async a=>(2!=$&&(x(1),m++,await K(async()=>{await O(async()=>{const e=await t();g(e)?W(e):a?F(a):p("Content is not an array: "+e)},()=>{a&&F(a)}),x(0)})),Z),H=async a=>(X(),await B(a),await O(async()=>N=await s(async(a,t)=>{t||a?2!=$&&(x(1),m++,W(t??a),x(0)):await B()}),r),Z),X=async()=>(N&&(await O(()=>i(N),r),N=void 0),Z),Y=async a=>(1!=$&&(x(2),v++,await K(async()=>{await O(()=>n(_,a),r),x(0)})),Z),q=async()=>(z(),await Y(),A=a.addDidFinishTransactionListener(()=>{const a=f();P(a)&&Y(a)}),Z),z=async()=>(A&&(a.delListener(A),A=void 0),Z),J=async(a=!1)=>{const[t,e]=a?[z,X]:[X,z];return await t(),await e(),Z},K=async(...a)=>(I(Q(Xa,w),...a),await(async()=>{if(!Q(Ha,w)){for(aa(Ha,w,1);!y(d=L(Q(Xa,w)));)await O(d,r);aa(Ha,w,0)}})(),Z),Z={load:B,startAutoLoad:H,stopAutoLoad:X,isAutoLoading:()=>!y(N),save:Y,startAutoSave:q,stopAutoSave:z,isAutoSaving:()=>!y(A),startAutoPersisting:async(a,t=!1)=>{const[e,n]=t?[q,H]:[H,q];return await e(a),await n(a),Z},stopAutoPersisting:J,getStatus:()=>$,addStatusListener:a=>M(a,C),delListener:t=>(j(t),a),schedule:K,getStore:()=>a,destroy:()=>(Q(Xa,w).splice(0,void 0),J()),getStats:()=>({loads:m,saves:v}),...c};return G(Z)},ka=(a,t,e,s,r,o=qa,c,l)=>{const w=V();return[async()=>{w.clear(),v(await e(a,t),({tn:a,cn:t})=>Ca(ta(w,a,va),t))},async(t,e,n)=>((a,t)=>_(Q(w,a),t))(t,e)?j(S(v(await a(Ea+pa(t)+ma(t,n)),a=>[a[e],l?H(W(a,e),l):W(a,e)]),([a,t])=>!y(a)&&!k(t))):{},async(t,e,s,l,u,d=!1,E=i)=>{const N=va();H(s??{},a=>v(U(a??{}),a=>Ca(N,a)));const g=f(N);if(!d&&u&&E==i&&C(g)&&_(w,t))return await a("DROP "+oa+pa(t)),void aa(w,t);const A=Q(w,t),T=va(f(A));if(C(g)||(_(w,t)?await $(v([e,...g],async(n,s)=>{h(T,n)||(await a(ya+pa(t)+"ADD"+pa(n)+r),0==s&&await a("CREATE UNIQUE INDEX pk ON "+pa(t)+`(${pa(e)})`),Ca(A,n))})):(await a(ga+pa(t)+`(${pa(e)}${r} PRIMARY KEY${m(v(g,a=>n+pa(a)+r))});`),aa(w,t,va([e,...g])))),await $([...!d&&l?v(f(T),async n=>{n!=e&&(await a(ya+pa(t)+"DROP"+pa(n)),h(A,n))}):[]]),d)y(s)?await a(da+pa(t)+ma(t,E)):await $(B(s,async(n,s)=>{y(n)?await a(da+pa(t)+ma(t,E)+`AND(${pa(e)}=$1)`,[s]):C(g)||await o(a,t,e,U(n),{[s]:c?v(X(n),c):X(n)},A)}));else if(C(g))_(w,t)&&await a(da+pa(t)+ma(t,E));else{const n=S(f(Q(w,t)),a=>a!=e),i={},r=[];H(s??{},(a,t)=>{i[t]=v(n,t=>c?c(a?.[t]):a?.[t]),I(r,t)}),await o(a,t,e,n,i),await a(da+pa(t)+ma(t,E)+`AND${pa(e)}NOT IN(${Ra(r)})`,r)}},async t=>{let e;return await a("BEGIN"),await O(async()=>e=await t(),s),await a("END"),e}]},qa=async(a,t,e,s,i)=>{const r=[1];await a(ca+" INTO"+pa(t)+"("+((...a)=>m(v(a,pa),n))(e,...s)+")VALUES"+m(B(i,a=>"($"+r[0]+++","+Ra(a,r)+")"),n)+"ON CONFLICT("+pa(e)+`)DO ${wa} SET`+m(v(s,a=>pa(a)+"=excluded."+pa(a)),n),B(i,(a,t)=>[t,...v(a,a=>a??null)]).flat())},za=(a,t,e,n,s,i,r,[o,c,l],w,y,u,d,E,N)=>{const[g,A,T,$]=ka(t,w,y,s,E,N),p=Ya(a,()=>$(async()=>{return await g(),a=(await A(o,c))[na]?.[l]??"null",z(a,(a,t)=>""===t?void 0:t);var a}),a=>$(async()=>{await g(),await T(o,c,{[na]:{[l]:J(a()??null)}},!0,!0)}),e,n,s,r,{[d]:()=>u,destroy:async()=>(await p.stopAutoPersisting(),i(),p)},0,u);return p},Ja=(a,t,e,n,s,i,r,[o,c,[l,w,u]],d,E,N,g,A,T,p,O)=>{const[R,m,v,C]=ka(t,d,E,s,A,T,p,O),I=(a,t)=>$(Z(c,async([e,n,s,i,r],o)=>{t&&!(o in a)||await v(e,n,a[o],s,i,t,r)})),L=async(a,t)=>w?await v(u,sa,{[na]:a},!0,!0,t):null,_=Ya(a,()=>C(async()=>{await R();const a=await(async()=>j(S(await $(Z(o,async([a,t,e],n)=>[a,await m(n,t,e)])),a=>!k(a[1]))))(),t=await(async()=>l?(await m(u,sa))[na]:{})();return k(a)&&y(t)?void 0:[a,t]}),(a,t)=>C(async()=>{if(await R(),y(t)){const[t,e]=a();await I(t),await L(e)}else await I(t[0],!0),await L(t[1],!0)}),e,n,s,r,{[g]:()=>N,destroy:async()=>(await _.stopAutoPersisting(),i(),_)},0,N);return _},Ka=/^([cd]:)(.+)/,Va=(a,n,s,o,c,l,w,y,u,d,g="getDb")=>{const T=((a,t)=>t?async(e,n)=>(t(e,n),await a(e,n)):a)(s,l),[p,,O,C]=(a=>{const e=(a=>x(ja,N(a)?{[_a]:a}:a??{}))(a),n=e[Da];if(e.mode==La){const a=e[_a]??t;return[1,n,[a,e[ba]??sa,e[fa]??Ia],va(a)]}const{tables:{load:s={},save:r={}}={},values:o={}}=e,c=A(X(x(xa,o)),0,Y(xa)),l=c[2],w=va(l),y=va(l),u=Wa(s,{[Pa]:null,[ha]:sa,[Ga]:i},Pa,a=>_(y,a),a=>Ca(w,a)),d=Wa(r,{[Fa]:null,[ha]:sa,[Ma]:0,[Ua]:0,[Ga]:null},Fa,(a,t)=>_(y,t),(a,t)=>Ca(w,t));var E;return E=(a,t)=>t[4]??=Q(u,t[0])?.[2]??i,D(d,(a,t)=>E(0,a)),[0,n,[u,d,c],w]})(n),S=e+(a=>{let t=2166136261;return R(K.encode(a),a=>{t^=a,t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24)}),t>>>0})(J(O)),I=t+"_"+S,L=async(a,e,n="",s="")=>{const i=Oa(t,a,S);return await T(Na+Aa+Ta+i+`()RETURNS ${n}trigger AS $$ ${s}BEGIN ${e}END;$$ LANGUAGE plpgsql;`),i},b=async(a,t,e,n)=>(await T(Na+a+"TRIGGER"+t+e+"EXECUTE "+Ta+n+"()"),t),h=a=>`PERFORM pg_notify('${I}',${a});`,P=(a,t)=>p?i:2===t?P(a,0)+" OR "+P(a,1):r(Q(O[0],a)?.[2]??i,$a,0==t?"NEW":"OLD"),F=(a,e)=>$(v([ca,la,wa],(n,s)=>b(Aa,Oa(t,"d",S,a,n),`AFTER ${n} ON${pa(a)}FOR EACH ROW WHEN(${P(a,s)})`,e)));return(p?za:Ja)(a,T,async a=>{const e=await L("c",`FOR row IN SELECT object_identity FROM pg_event_trigger_ddl_commands()${ra} command_tag='${ga}' LOOP ${h("'c:'||SPLIT_PART(row.object_identity,'.',2)")}END LOOP;`,"event_","DECLARE row record;");await b("EVENT ",Oa(t,"c",S),`ON ddl_command_end WHEN TAG IN('${ga}')`,e);const n=await L("d",h("'d:'||TG_TABLE_NAME")+"RETURN NULL;");return await $(v(f(C),async a=>(await T(ga+` IF NOT EXISTS${pa(a)}("_id"text PRIMARY KEY)`),await F(a,n)))),[await o(I,t=>{return E((e=t,s=Ka,e?.match(s)),async([,t,e])=>{_(C,e)&&("c:"==t&&await F(e,n),a())});var e,s}),[e,n]]},async([a,t])=>{c(a),await T(`DROP FUNCTION IF EXISTS${m(t,",")}CASCADE`)},w,y,u,O,f(C),async(a,t)=>await a(ia+` table_name tn,column_name cn FROM information_schema.columns ${ra} table_schema='public'AND table_name IN(${Ra(t)})`,t),d,g,"text",void 0,a=>q(a),a=>z(a))},Qa=async(a,t,e,n,s)=>{const i=await(t.reserve?.());return Va(a,e,i?.unsafe,async(a,e)=>t.listen(a,e),a=>O(a.unlisten,s),n,s,()=>i?.release?.(),3,t,"getSql")};export{Qa as createPostgresPersister};