tinybase
Version:
A reactive data store and sync engine.
2 lines (1 loc) • 8.02 kB
JavaScript
const a=a=>typeof a,t="tinybase",e="",n=",",s=a(e),i=Promise,o=clearInterval,r=a=>null==a,c=(a,t,e)=>r(a)?e?.():t(a),l=t=>a(t)==s,w=a=>Array.isArray(a),u=(a,t,e)=>a.slice(t,e),y=a=>a.length,d=async a=>i.all(a),v=a=>{throw Error(a)},p=(a,t)=>a.forEach(t),E=(a,t="")=>a.join(t),g=(a,t)=>a.map(t),A=a=>0==y(a),h=(a,t)=>a.filter(t),m=(a,...t)=>a.push(...t),f=a=>a.shift(),N=(a,t)=>a?.has(t)??!1,$=a=>r(a)||0==(a=>a?.size??0)(a),S=a=>[...a?.values()??[]],C=(a,t)=>a?.forEach(t),O=(a,t)=>a?.delete(t),T="_",I="_id",L="SELECT",b="WHERE",D="TABLE",R="ALTER "+D,M="DELETE FROM",_=L+"*FROM",P="pragma_",F="data_version",U="schema_version",j="pragma_table_",B=a=>`"${a.replace(/"/g,'""')}"`,J=(a,t=[1])=>E(g(a,(()=>"$"+t[0]++)),n),Y=Object,k=a=>Y.getPrototypeOf(a),x=Y.entries,z=Y.keys,G=Y.freeze,H=(a=[])=>Y.fromEntries(a),K=(...a)=>Y.assign({},...a),Q=(a,t)=>(delete a[t],a),V=(a,t)=>g(x(a),(([a,e])=>t(e,a))),W=(a,t)=>H(V(a,((a,e)=>[e,t(a,e)]))),X=a=>Y.values(a),q=a=>y(z(a)),Z=a=>(a=>!r(a)&&c(k(a),(a=>a==Y.prototype||r(k(a))),(()=>!0)))(a)&&0==q(a),aa=a=>new Map(a),ta=(a,t)=>a?.get(t),ea=(a,t)=>g([...a?.entries()??[]],(([a,e])=>t(e,a))),na=(a,t,e)=>r(e)?(O(a,t),a):a?.set(t,e),sa=(a,t,e,n)=>(N(a,t)?n?.(ta(a,t)):na(a,t,e()),ta(a,t)),ia=(a,t,e,n,s=0)=>c((e?sa:ta)(a,t[s],s>y(t)-2?e:aa),(i=>{if(s>y(t)-2)return n?.(i)&&na(a,t[s]),i;const o=ia(i,t,e,n,s+1);return $(i)&&na(a,t[s]),o})),oa=a=>new Set(w(a)||r(a)?a:[a]),ra=(a,t)=>a?.add(t),ca="ColumnName",la="store",wa="json",ua=la+"TableName",ya=la+"Id"+ca,da=la+ca,va="autoLoadIntervalSeconds",pa="rowId"+ca,Ea="tableId",ga="tableName",Aa="deleteEmptyColumns",ha="deleteEmptyTable",ma={mode:wa,[va]:1},fa={load:0,save:0,[ga]:t+"_values"},Na=(a,t,e,n,s)=>{const i=aa();return W(a,((a,o)=>{const c=u(X(K(t,l(a)?{[e]:a}:a)),0,q(t));r(c[0])||n(o,c[0])||(s(o,c[0]),na(i,o,c))})),i},$a=JSON.stringify,Sa=JSON.parse,Ca=/^\d+$/,Oa=aa(),Ta=aa(),Ia=(a,t,n,s,i,o,l,u={},d=0,E=[])=>{let g,A,h,N=0,S=0,T=0;sa(Oa,E,(()=>0)),sa(Ta,E,(()=>[]));const I=aa(),[L,b,D,R,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]:v("Store type not supported by this Persister"))(l,a,d),[_,P,F]=(()=>{let a;const[t,n]=(()=>{const a=[];let t=0;return[n=>(n?f(a):null)??e+t++,t=>{Ca.test(t)&&y(a)<1e3&&m(a,t)}]})(),s=aa();return[(n,i,o,r=[],c=()=>[])=>{a??=z;const l=t(1);return na(s,l,[n,i,o,r,c]),ra(ia(i,o??[e],oa),l),l},(t,n,...i)=>p(((a,t=[e])=>{const n=[],s=(a,e)=>e==y(t)?m(n,a):null===t[e]?C(a,(a=>s(a,e+1))):p([t[e],null],(t=>s(ta(a,t),e+1)));return s(a,0),n})(t,n),(t=>C(t,(t=>ta(s,t)[0](a,...n??[],...i))))),a=>c(ta(s,a),(([,t,i])=>(ia(t,i??[e],void 0,(t=>(O(t,a),$(t)?1:0))),na(s,a),n(a),i))),t=>c(ta(s,t),(([t,,e=[],n,s])=>{const i=(...o)=>{const c=y(o);c==y(e)?t(a,...o,...s(o)):r(e[c])?p(n[c]?.(...o)??[],(a=>i(...o,a))):i(...o,e[c])};i()}))]})(),U=a=>{a!=N&&(N=a,P(I,void 0,N))},j=t=>{(L&&w(t?.[0])?1===t?.[2]?a.applyMergeableChanges:a.setMergeableContent:1===t?.[2]?a.applyChanges:a.setContent)(t)},B=async a=>(2!=N&&(U(1),S++,await x((async()=>{try{const e=await t();w(e)?j(e):a?M(a):v("Content is not an array: "+e)}catch(t){o?.(t),a&&M(a)}U(0)}))),z),J=()=>(A&&(i(A),A=void 0),z),Y=async a=>(1!=N&&(U(2),T++,await x((async()=>{try{await n(b,a)}catch(a){o?.(a)}U(0)}))),z),k=()=>(h&&(a.delListener(h),h=void 0),z),x=async(...a)=>(m(ta(Ta,E),...a),await(async()=>{if(!ta(Oa,E)){for(na(Oa,E,1);!r(g=f(ta(Ta,E)));)try{await g()}catch(a){o?.(a)}na(Oa,E,0)}})(),z),z={load:B,startAutoLoad:async a=>{J(),await B(a);try{A=await s((async(a,t)=>{t||a?2!=N&&(U(1),S++,j(t??a),U(0)):await B()}))}catch(a){o?.(a)}return z},stopAutoLoad:J,isAutoLoading:()=>!r(A),save:Y,startAutoSave:async()=>(k(),await Y(),h=a.addDidFinishTransactionListener((()=>{const a=D();R(a)&&Y(a)})),z),stopAutoSave:k,isAutoSaving:()=>!r(h),getStatus:()=>N,addStatusListener:a=>_(a,I),delListener:t=>(F(t),a),schedule:x,getStore:()=>a,destroy:()=>(ta(Ta,E).splice(0,void 0),J().stopAutoSave()),getStats:()=>({loads:S,saves:T}),...u};return G(z)},La=(a,t,e,s,i,o=ba,c,l)=>{const w=aa();return[async()=>{w.clear(),g(await e(a,t),(({tn:a,cn:t})=>ra(sa(w,a,oa),t)))},async(t,e)=>((a,t)=>N(ta(w,a),t))(t,e)?H(h(g(await a(_+B(t)),(a=>[a[e],l?W(Q(a,e),l):Q(a,e)])),(([a,t])=>!r(a)&&!Z(t)))):{},async(t,e,s,l,u,y=!1)=>{const v=oa();W(s??{},(a=>g(z(a??{}),(a=>ra(v,a)))));const p=S(v);if(!y&&u&&A(p)&&N(w,t))return await a("DROP "+D+B(t)),void na(w,t);const f=ta(w,t),$=oa(S(f));if(A(p)||(N(w,t)?await d(g([e,...p],(async(n,s)=>{O($,n)||(await a(R+B(t)+"ADD"+B(n)+i),0==s&&await a("CREATE UNIQUE INDEX pk ON "+B(t)+`(${B(e)})`),ra(f,n))}))):(await a("CREATE "+D+B(t)+`(${B(e)}${i} PRIMARY KEY${E(g(p,(a=>n+B(a)+i)))});`),na(w,t,oa([e,...p])))),await d([...!y&&l?g(S($),(async n=>{n!=e&&(await a(R+B(t)+"DROP"+B(n)),O(f,n))})):[]]),y)r(s)?await a(M+B(t)+b+" true"):await d(V(s,(async(n,s)=>{r(n)?await a(M+B(t)+b+B(e)+"=$1",[s]):A(p)||await o(a,t,e,z(n),{[s]:c?g(X(n),c):X(n)},f)})));else if(A(p))N(w,t)&&await a(M+B(t)+b+" true");else{const n=h(S(ta(w,t)),(a=>a!=e)),i={},r=[];W(s??{},((a,t)=>{i[t]=g(n,(t=>c?c(a?.[t]):a?.[t])),m(r,t)})),await o(a,t,e,n,i),await a(M+B(t)+b+B(e)+`NOT IN(${J(r)})`,r)}},async t=>{let e;await a("BEGIN");try{e=await t()}catch(a){s?.(a)}return await a("END"),e}]},ba=async(a,t,e,s,i)=>{const o=[1];await a("INSERT INTO"+B(t)+"("+((...a)=>E(g(a,B),n))(e,...s)+")VALUES"+E(V(i,(a=>"($"+o[0]+++","+J(a,o)+")")),n)+"ON CONFLICT("+B(e)+")DO UPDATE SET"+E(g(s,(a=>B(a)+"=excluded."+B(a))),n),V(i,((a,t)=>[t,...g(a,(a=>a??null))])).flat())},Da=(a,t,e,n,s,i,o,[r,c,l],w,u,y,d,v,p)=>{const[E,g,A,h]=La(t,w,u,s,v,p),m=Ia(a,(async()=>await h((async()=>{return await E(),a=(await g(r,c))[T]?.[l]??"null",Sa(a,((a,t)=>""===t?void 0:t));var a}))),(async a=>await h((async()=>{var t;await E(),await A(r,c,{[T]:{[l]:(t=a()??null,$a(t,((a,t)=>void 0===t?"":t)))}},!0,!0)}))),e,n,s,o,{[d]:()=>y,destroy:()=>(m.stopAutoLoad().stopAutoSave(),i(),m)},0,y);return m},Ra=(a,t,e,n,s,i,o,[c,l,[w,u,y]],v,p,E,g,A,m,f,N)=>{const[$,S,C,O]=La(t,v,p,s,A,m,f,N),L=async(a,t)=>await d(ea(l,(async([e,n,s,i],o)=>{t&&!(o in a)||await C(e,n,a[o],s,i,t)}))),b=async(a,t)=>u?await C(y,I,{[T]:a},!0,!0,t):null,D=Ia(a,(async()=>await O((async()=>{await $();const a=await(async()=>H(h(await d(ea(c,(async([a,t],e)=>[a,await S(e,t)]))),(a=>!Z(a[1])))))(),t=await(async()=>w?(await S(y,I))[T]:{})();return Z(a)&&r(t)?void 0:[a,t]}))),(async(a,t)=>await O((async()=>{if(await $(),r(t)){const[t,e]=a();await L(t),await b(e)}else await L(t[0],!0),await b(t[1],!0)}))),e,n,s,o,{[g]:()=>E,destroy:()=>(D.stopAutoLoad().stopAutoSave(),i(),D)},0,E);return D},Ma=(a,n,s,i,r,c,w,y,d,v,p="getDb",E)=>{let g,A,h;const m=((a,t)=>t?async(e,n)=>(t(e,n),await a(e,n)):a)(s,c),[f,$,C,O]=(a=>{const e=(a=>K(ma,l(a)?{[ua]:a}:a??{}))(a),n=e[va];if(e.mode==wa){const a=e[ua]??t;return[1,n,[a,e[ya]??I,e[da]??la],oa(a)]}const{tables:{load:s={},save:i={}}={},values:o={}}=e,r=u(X(K(fa,o)),0,q(fa)),c=r[2],w=oa(c),y=oa(c);return[0,n,[Na(s,{[Ea]:null,[pa]:I},Ea,(a=>N(y,a)),(a=>ra(w,a))),Na(i,{[ga]:null,[pa]:I,[Aa]:0,[ha]:0},ga,((a,t)=>N(y,t)),((a,t)=>ra(w,t))),r],w]})(n);return(f?Da:Ra)(a,m,(a=>{let t;const e=()=>t=setInterval((async()=>{try{const[{d:t,s:e,c:n}]=await m(`${L} ${F} d,${U} s,TOTAL_CHANGES() c FROM ${P}${F} JOIN ${P}${U}`);t==g&&e==A&&n==h||(null!=g&&a(),g=t,A=e,h=n)}catch{}}),1e3*$),n=()=>{g=A=h=null,o(t)},s=i((t=>{O.has(t)&&(n(),a(),e())}));return e(),()=>{n(),r(s)}}),(a=>a()),w,y,d,C,S(O),(async(a,t)=>await a(`${L} t.name tn,c.name cn FROM ${j}list()t,${j}info(t.name)c ${b} t.schema='main'AND t.type IN('table','view')AND t.name IN(${J(t)})ORDER BY t.name,c.name`,t)),v,p,e,E,(a=>!0===a?1:!1===a?0:a),void 0)},_a="change",Pa=(a,t,e,n,s)=>Ma(a,e,(async(a,e=[])=>{return await(n=(n,s)=>t.all(a,e,((a,t)=>a?s(a):n(t))),new i(n));var n}),(a=>{const e=(t,e,n)=>a(n);return t.on(_a,e),e}),(a=>t.off(_a,a)),n,s,(()=>0),3,t);export{Pa as createSqlite3Persister};