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