UNPKG

@alwatr/nitrobase-engine

Version:

Nitrobase is a blazingly fast, lightweight database built on JSON. It stores data entirely in memory for lightning-quick access, while also providing a JSON file backup for persistence. You can easily serve your data over the web using our high-performanc

6 lines (4 loc) 5.3 kB
/* 📦 @alwatr/nitrobase-engine v10.0.0 */ import{delay as H}from"@alwatr/delay";import{exitHook as k}from"@alwatr/exit-hook";import{getStoreId as U,getStorePath as X}from"@alwatr/nitrobase-helper";import{CollectionReference as V,DocumentReference as Y}from"@alwatr/nitrobase-reference";import{StoreFileType as O,StoreFileExtension as L,Region as D}from"@alwatr/nitrobase-types";import{existsSync as A,readJson as $,resolve as W,unlink as J,writeJson as j}from"@alwatr/node-fs";import{createLogger as G}from"@alwatr/logger";var K=G("@alwatr/nitrobase-engine");class Z{config;static version="10.0.0";static rootDbStat__={name:".nitrobase",region:D.Secret,type:O.Collection,extension:L.Json,changeDebounce:40};rootDb__;cacheReferences__={};constructor(q){this.config=q;this.storeChanged_=this.storeChanged_.bind(this),K.logMethodArgs?.("new",q),this.config.defaultChangeDebounce??=40,this.rootDb__=this.loadRootDb__(),k(this.exitHook__.bind(this))}hasStore(q){let z=U(q),B=this.rootDb__.hasItem(z);return K.logMethodFull?.("hasStore",z,B),B}newDocument(q,z){return K.logMethodArgs?.("newDocument",q),this.newStoreFile__({...q,type:O.Document},z)}newCollection(q){return K.logMethodArgs?.("newCollection",q),this.newStoreFile__({...q,type:O.Collection})}newStoreFile__(q,z){K.logMethodArgs?.("newStoreFile__",q),q.changeDebounce??=this.config.defaultChangeDebounce;let B;if(q.type===O.Document){if(z===void 0)throw Error("document_data_required",{cause:q});B=Y.newRefFromData(q,z,this.storeChanged_)}else if(q.type===O.Collection)B=V.newRefFromData(q,this.storeChanged_);else throw Error("store_file_type_not_supported",{cause:q});if(this.rootDb__.hasItem(B.id))throw Error("store_file_already_defined",{cause:q});this.rootDb__.addItem(B.id,q),this.cacheReferences__[B.id]=B,this.storeChanged_(B)}async openDocument(q){let z=U(q);if(K.logMethodArgs?.("openDocument",z),Object.hasOwn(this.cacheReferences__,z)){if(!(this.cacheReferences__[z]instanceof Y))throw Error("document_wrong_type",{cause:z});return this.cacheReferences__[z]}if(!this.rootDb__.hasItem(z))throw Error("document_not_found",{cause:z});let B=this.rootDb__.getItemData(z);if(B.type!=O.Document)throw Error("document_wrong_type",{cause:z});let Q=await this.readContext__(B),M=Y.newRefFromContext(Q,this.storeChanged_);return this.cacheReferences__[z]=M,M}async openCollection(q){let z=U(q);if(K.logMethodArgs?.("openCollection",z),Object.hasOwn(this.cacheReferences__,z)){if(!(this.cacheReferences__[z]instanceof V))throw Error("collection_wrong_type",{cause:z});return this.cacheReferences__[z]}if(!this.rootDb__.hasItem(z))throw Error("collection_not_found",{cause:z});let B=this.rootDb__.getItemData(z);if(B.type!=O.Collection)throw Error("collection_not_found",{cause:z});let Q=await this.readContext__(B),M=V.newRefFromContext(Q,this.storeChanged_);return this.cacheReferences__[z]=M,M}unloadStore(q){let z=U(q);K.logMethodArgs?.("unloadStore",z);let B=this.cacheReferences__[z];if(B===void 0)return;if(B.hasUnprocessedChanges_===!0)B.updateDelayed_=!1,this.storeChanged_(B);delete this.cacheReferences__[z]}async removeStore(q){let z=U(q);if(K.logMethodArgs?.("removeStore",z),!this.rootDb__.hasItem(z))throw Error("document_not_found",{cause:z});let B=this.cacheReferences__[z];if(B!==void 0)B.freeze=!0,B.updateDelayed_=!1,B.hasUnprocessedChanges_=!1,delete this.cacheReferences__[z];let Q=X(this.rootDb__.getItemData(z));this.rootDb__.removeItem(z),await H.by(0);try{await J(W(this.config.rootPath,Q))}catch(M){K.error("removeStore","remove_file_failed",M,{id:q,path:Q})}}async saveAll(){K.logMethod?.("saveAll");for(let q of Object.values(this.cacheReferences__))if(q.hasUnprocessedChanges_===!0&&q.freeze!==!0)q.updateDelayed_=!1,await this.storeChanged_(q)}async readContext__(q){if(typeof q!=="string")q=X(q);K.logMethodArgs?.("readContext__",q),K.time?.(`readContext__time(${q})`);let z=await $(W(this.config.rootPath,q));return K.timeEnd?.(`readContext__time(${q})`),z}writeContext__(q,z){if(typeof q!=="string")q=X(q);return K.logMethodArgs?.("writeContext__",q),j(W(this.config.rootPath,q),z)}async storeChanged_(q){K.logMethodArgs?.("storeChanged__",q.id);let z=q.getStoreMeta().rev;try{if(await this.writeContext__(q.path,q.getFullContext_()),z===q.getStoreMeta().rev)q.hasUnprocessedChanges_=!1}catch(B){K.error("storeChanged__","write_context_failed",{id:q.id,error:B})}}loadRootDb__(){K.logMethod?.("loadRootDb__");let q=W(this.config.rootPath,X(Z.rootDbStat__));if(!A(q)){if(this.config.errorWhenNotInitialized===!0)throw Error("store_not_found",{cause:"Nitrobase not initialized"});return K.banner("Initialize new alwatr-nitrobase"),V.newRefFromData(Z.rootDbStat__,this.storeChanged_)}let z=$(q,!0);return V.newRefFromContext(z,this.storeChanged_,"root-db")}exitHook__(){K.logMethod?.("exitHook__");for(let q of Object.values(this.cacheReferences__))if(K.logProperty?.(`StoreFile.${q.id}.hasUnprocessedChanges`,q.hasUnprocessedChanges_),q.hasUnprocessedChanges_===!0&&q.freeze!==!0)K.incident?.("exitHook__","rescue_unsaved_context",{id:q.id}),j(W(this.config.rootPath,q.path),q.getFullContext_(),!0),q.hasUnprocessedChanges_=!1}getStoreList(){return K.logMethod?.("getStoreList"),this.rootDb__.values()}}export{Z as AlwatrNitrobase}; //# debugId=092C85CD72F41FBD64756E2164756E21 //# sourceMappingURL=main.js.map