@freik/node-utils
Version:
My personal set of utilities for NodeJS
2 lines (1 loc) • 2.69 kB
JavaScript
import*as l from"fs";import{promises as f}from"fs";import*as v from"./PathUtil.js";import{MakeLog as x}from"@freik/logger";import O from"@freik/seqnum";import{MakeReaderWriter as V,OnlyOneWaiting as j}from"@freik/sync";import{hasStrField as h}from"@freik/typechk";const{log:i,err:o}=x("node-utils:persist");function G(b){const s=new Map,g=new Map,A=O(),y=new Map;function d(t){const e=y.get(t);if(e!==void 0)return e;{const r=V(0);return y.set(t,r),r}}function u(){return v.xplat(b)}function c(t){return v.join(u(),`${t}.json`)}i(`User data location: ${c("test")}`);function I(t){let e=s.get(t);if(e)return e;try{if(e=l.readFileSync(c(t),"utf8"),e)return s.set(t,e),e}catch(r){if(r instanceof Error&&h(r,"code")&&r.code==="ENOENT")return;o("Error occurred during readFile"),o(r)}}async function P(t){const e=s.get(t);if(e)return i("returning cached data for "+t),e;const r=d(t);await r.read();try{const n=await f.readFile(c(t),"utf8");return s.set(t,n),n}catch(n){if(n instanceof Error&&h(n,"code")&&n.code==="ENOENT")return;o("Error occurred during readFileAsync"),o(n)}finally{r.leaveRead()}}function L(t,e){s.set(t,e);try{l.mkdirSync(u(),{recursive:!0})}catch{}l.writeFileSync(c(t),e,"utf8")}const m=new Map;async function $(t,e){try{await f.mkdir(u(),{recursive:!0})}catch{}const r=d(t);await r.write(),s.set(t,e);try{m.has(t)||m.set(t,j(async()=>{const a=s.get(t);a!==void 0&&await f.writeFile(c(t),a,"utf8")},500));const n=m.get(t);if(!n)throw Error("Horrific synchronization bug in persist.writeFileAsync");await n()}finally{r.leaveWrite()}}function E(t){try{l.unlinkSync(c(t)),s.delete(t)}catch(e){o("Error occurred during deleteFile"),o(e)}}async function M(t){const e=d(t);await e.write();try{s.delete(t),await f.unlink(c(t))}catch(r){o("Error occurred during deleteFileAsync"),o(r)}finally{e.leaveWrite()}}function p(t,e){const r=g.get(t);if(r)for(const[,n]of r)i(`Updating ${t} to ${e}`),n(e)}function N(t,e){const r=A();let n=g.get(t);return n||(n=new Map,g.set(t,n)),n.set(r,e),`${r}-${t}`}function W(t){const e=t.indexOf("-"),r=t.substr(0,e),n=t.substr(e+1),a=g.get(n);return a?a.delete(r):!1}function w(t){return i("Reading "+t),I(t)}async function F(t){return i("Async Reading "+t),await P(t)}function k(t,e){w(t)===e?i(`No change to ${t} - not re-writing`):(i(`Writing ${t}:`),i(e),L(t,e),p(t,e))}async function S(t,e){await F(t)===e?i(`No change to ${t} - not re-writing`):(i(`Async Writing ${t}:`),i(e),await $(t,e),p(t,e))}function R(t){i(`deleting ${t}`),E(t)}async function U(t){i(`deleting ${t}`),await M(t)}return{getLocation:u,getItem:w,getItemAsync:F,setItem:k,setItemAsync:S,deleteItem:R,deleteItemAsync:U,subscribe:N,unsubscribe:W}}export{G as MakePersistence};