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