tinybase
Version:
A reactive data store and sync engine.
2 lines (1 loc) • 3.88 kB
JavaScript
import{existsSync as t,writeFileSync as a,watch as e}from"fs";import{writeFile as s,readFile as n}from"fs/promises";const r="utf8",o=t=>(a,e,s)=>t(a)?s?.():e(a),i=t=>null==t,c=t=>void 0===t,u=t=>null===t,y=o(i),l=o(c),d=t=>Array.isArray(t),w=t=>t.length,g=t=>{throw Error(t)},p=async(t,a,e)=>{try{return await t()}catch(t){a?.(t)}},h=(t,a)=>t.forEach(a),f=(t,a)=>t.map(a),v=(t,...a)=>t.push(...a),C=t=>t.shift(),S=Object,A=t=>S.getPrototypeOf(t),b=S.entries,m=t=>!i(t)&&y(A(t),t=>t==S.prototype||i(A(t)),()=>!0),L=S.keys,M=S.freeze,P=t=>m(t)&&0==(t=>w(L(t)))(t),E=JSON.stringify,O=JSON.parse,T=t=>""===t?void 0:d(t)?f(t,T):m(t)?((t,a)=>((t=[])=>S.fromEntries(t))(((t,a)=>f(b(t),([t,e])=>a(e,t)))(t,(t,e)=>[e,a(t,e)])))(t,T):t,z=t=>c(t)||0==(t=>t?.size??0)(t),D=(t,a)=>t?.forEach(a),F=(t,a)=>t?.delete(a),J=Map,N=t=>new J(t),j=(t,a)=>t?.get(a),k=(t,a,e)=>c(e)?(F(t,a),t):t?.set(a,e),x=(t,a,e,s)=>{var n,r;return n=t,r=a,n?.has(r)?s?.(j(t,a)):k(t,a,e()),j(t,a)},$=(t,a,e,s,n=0)=>l((e?x:j)(t,a[n],n>w(a)-2?e:N),r=>{if(n>w(a)-2)return s?.(r)&&k(t,a[n]),r;const o=$(r,a,e,s,n+1);return z(r)&&k(t,a[n]),o}),q=/^\d+$/,B=t=>new Set(d(t)||c(t)?t:[t]),G=N(),H=N(),I=(t,a,e,s,n,r,o,i={},y=0,f=[])=>{let S,A,b,m=0,L=0,E=0;x(G,f,()=>0),x(H,f,()=>[]);const O=N(),[T,J,I,K,Q]=((t=1,a,e)=>1!=t&&a.isMergeable()?[1,a.getMergeableContent,()=>a.getTransactionMergeableChanges(!e),([[t],[a]])=>!P(t)||!P(a),a.setDefaultContent]:2!=t?[0,a.getContent,a.getTransactionChanges,([t,a])=>!P(t)||!P(a),a.setContent]:g("Store type not supported by this Persister"))(o,t,y),[R,U,V]=(()=>{let t;const[a,e]=(()=>{const t=[];let a=0;return[e=>(e?C(t):null)??""+a++,a=>{q.test(a)&&w(t)<1e3&&v(t,a)}]})(),s=N();return[(e,n,r,o=[],i=()=>[])=>{t??=it;const c=a(1);var u,y;return k(s,c,[e,n,r,o,i]),u=$(n,r??[""],B),y=c,u?.add(y),c},(a,e,...n)=>h(((t,a=[""])=>{const e=[],s=(t,n)=>n==w(a)?v(e,t):u(a[n])?D(t,t=>s(t,n+1)):h([a[n],null],a=>s(j(t,a),n+1));return s(t,0),e})(a,e),a=>D(a,a=>j(s,a)[0](t,...e??[],...n))),t=>l(j(s,t),([,a,n])=>($(a,n??[""],void 0,a=>(F(a,t),z(a)?1:0)),k(s,t),e(t),n)),a=>l(j(s,a),([a,,e=[],s,n])=>{const r=(...o)=>{const i=w(o);i==w(e)?a(t,...o,...n(o)):u(e[i])?h(s[i]?.(...o)??[],t=>r(...o,t)):r(...o,e[i])};r()})]})(),W=t=>{t!=m&&(m=t,U(O,void 0,m))},X=a=>{(T&&d(a?.[0])?1===a?.[2]?t.applyMergeableChanges:t.setMergeableContent:1===a?.[2]?t.applyChanges:t.setContent)(a)},Y=async()=>{nt()&&t.hadMutated?.()&&await at()},Z=async t=>(2!=m&&(W(1),L++,await ot(async()=>{await p(async()=>{const e=await a();d(e)?X(e):t?Q(t):g("Content is not an array: "+e)},()=>{t&&Q(t)}),W(0),await Y()})),it),_=async t=>(tt(),await Z(t),await p(async()=>A=await s(async(t,a)=>{a||t?2!=m&&(W(1),L++,X(a??t),W(0),await Y()):await Z()}),r),it),tt=async()=>(A&&(await p(()=>n(A),r),A=void 0),it),at=async t=>(1!=m&&(W(2),E++,await ot(async()=>{await p(()=>e(J,t),r),W(0)})),it),et=async()=>(st(),await at(),b=t.addDidFinishTransactionListener(()=>{const t=I();K(t)&&at(t)}),it),st=async()=>(b&&(t.delListener(b),b=void 0),it),nt=()=>!c(b),rt=async(t=!1)=>{const[a,e]=t?[st,tt]:[tt,st];return await a(),await e(),it},ot=async(...t)=>(v(j(H,f),...t),await(async()=>{if(!j(G,f)){for(k(G,f,1);!c(S=C(j(H,f)));)await p(S,r);k(G,f,0)}})(),it),it={load:Z,startAutoLoad:_,stopAutoLoad:tt,isAutoLoading:()=>!c(A),save:at,startAutoSave:et,stopAutoSave:st,isAutoSaving:nt,startAutoPersisting:async(t,a=!1)=>{const[e,s]=a?[et,_]:[_,et];return await e(t),await s(t),it},stopAutoPersisting:rt,getStatus:()=>m,addStatusListener:t=>R(t,O),delListener:a=>(V(a),t),schedule:ot,getStore:()=>t,destroy:()=>(j(H,f).splice(0,void 0),rt()),getStats:()=>({loads:L,saves:E}),...i};return M(it)},K=(o,i,u)=>I(o,async()=>{return t=await n(i,r),T(O(t));var t},async t=>{return await s(i,(a=t(),E(a,(t,a)=>c(a)?"":a)),r);var a},s=>(t(i)||a(i,"",r),e(i,()=>s())),t=>t?.close(),u,3,{getFilePath:()=>i});export{K as createFilePersister};