UNPKG

tinybase

Version:

A reactive data store and sync engine.

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