UNPKG

yq-store

Version:

A high-performance, persistent and in-memory key-value store with TTL support, built for Node.js applications.

251 lines (241 loc) 45 kB
var K=Object.defineProperty;var P=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var w=(o,e)=>()=>(o&&(e=o(o=0)),e);var V=(o,e)=>{for(var t in e)K(o,t,{get:e[t],enumerable:!0})};var y,p,u,x,b=w(()=>{"use strict";y="_default",p=9007199254740991,u=1,x=["namespace","key","value","created_at","expires_at","is_deleted","last_accessed"]});var C={};V(C,{checkSchema:()=>M,findDatabases:()=>H,migrate:()=>W});import Y from"node:path";import N from"node:fs";function L(){return typeof Bun<"u"&&!!Bun?.version}async function U(o){if(L()){let{Database:e}=await import("bun:sqlite");return new e(o)}else{let{DatabaseSync:e}=await import("node:sqlite");return new e(o)}}function v(o,e){o.exec(e)}function O(o,e){return L()?o.query(e).get():o.prepare(e).get()}function j(o,e){return L()?o.query(e).all():o.prepare(e).all()}function B(o){o.close()}async function M(o){if(!N.existsSync(o))return{needsMigration:!1,validation:{isValid:!0,expectedVersion:1,missingColumns:[],extraColumns:[]},dbPath:o,exists:!1};let t=await U(o);try{if(!O(t,"SELECT name FROM sqlite_master WHERE type='table' AND name='kv_store'"))return{needsMigration:!1,validation:{isValid:!0,expectedVersion:1,missingColumns:[],extraColumns:[]},dbPath:o,exists:!0};let r=j(t,"PRAGMA table_info(kv_store)").map(m=>m.name),i;try{if(O(t,"SELECT name FROM sqlite_master WHERE type='table' AND name='yq_meta'")){let T=O(t,"SELECT value FROM yq_meta WHERE key = 'schema_version'");T&&(i=parseInt(T.value,10))}}catch{}let a=[...x],c=a.filter(m=>!r.includes(m)),l=r.filter(m=>!a.includes(m)),h=c.length===0&&(i===void 0||i===1);return{needsMigration:!h,validation:{isValid:h,currentVersion:i,expectedVersion:1,missingColumns:c,extraColumns:l,message:h?void 0:"Schema mismatch detected"},dbPath:o,exists:!0}}finally{B(t)}}async function W(o){let{dbPath:e,backup:t=!0,dryRun:s=!1,verbose:n=!1}=o,r=[],i=d=>{n&&console.log(`[migrate] ${d}`),r.push(d)};if(!N.existsSync(e))return{success:!1,fromVersion:null,toVersion:1,changes:["Database file does not exist"],error:`Database file not found: ${e}`};let a=await M(e);if(!a.needsMigration)return i("Schema is already up to date"),{success:!0,fromVersion:a.validation.currentVersion??1,toVersion:1,changes:r};let c=a.validation.currentVersion??0,l;if(t&&!s&&(l=`${e}.backup.${Date.now()}`,N.copyFileSync(e,l),i(`Created backup at: ${l}`)),s)return i("DRY RUN - No changes will be made"),i(`Would migrate from v${c} to v${1}`),a.validation.missingColumns.length>0&&i(`Would add columns: ${a.validation.missingColumns.join(", ")}`),{success:!0,fromVersion:c,toVersion:1,changes:r};let h=await U(e);try{v(h,"BEGIN TRANSACTION");for(let d of a.validation.missingColumns){let m=Z(d),T=J(d);i(`Adding column: ${d} (${T})`),v(h,`ALTER TABLE kv_store ADD COLUMN ${d} ${T} ${m}`)}return i("Creating/updating indexes"),v(h,` CREATE INDEX IF NOT EXISTS idx_kv_ns_active ON kv_store(namespace, is_deleted, expires_at, key) WHERE is_deleted = 0; CREATE INDEX IF NOT EXISTS idx_kv_global_active ON kv_store(is_deleted, expires_at, namespace, key) WHERE is_deleted = 0; CREATE INDEX IF NOT EXISTS idx_kv_ns_lru ON kv_store(namespace, last_accessed) WHERE is_deleted = 0; CREATE INDEX IF NOT EXISTS idx_kv_expiry ON kv_store(expires_at) WHERE is_deleted = 0 AND expires_at < ${9007199254740991}; CREATE INDEX IF NOT EXISTS idx_kv_ns_stats ON kv_store(namespace, is_deleted); `),i("Updating schema version"),v(h,` CREATE TABLE IF NOT EXISTS yq_meta ( key TEXT PRIMARY KEY, value TEXT NOT NULL ); INSERT OR REPLACE INTO yq_meta (key, value) VALUES ('schema_version', '${1}'); `),v(h,"COMMIT"),i(`Migration complete: v${c} -> v${1}`),{success:!0,fromVersion:c,toVersion:1,changes:r,backupPath:l}}catch(d){try{v(h,"ROLLBACK")}catch{}let m=d instanceof Error?d.message:String(d);return i(`Migration failed: ${m}`),{success:!1,fromVersion:c,toVersion:1,changes:r,backupPath:l,error:m}}finally{B(h)}}function J(o){switch(o){case"namespace":case"key":return"TEXT NOT NULL";case"value":return"BLOB NOT NULL";case"created_at":case"expires_at":case"last_accessed":return"INTEGER NOT NULL";case"is_deleted":return"INTEGER NOT NULL";default:return"TEXT"}}function Z(o){switch(o){case"namespace":return`DEFAULT '${y}'`;case"expires_at":return`DEFAULT ${9007199254740991}`;case"is_deleted":return"DEFAULT 0";case"last_accessed":return"DEFAULT 0";case"created_at":return`DEFAULT ${Date.now()}`;default:return""}}function H(o,e="*.yqs"){let t=[];if(!N.existsSync(o))return t;let s=N.readdirSync(o),n=new RegExp("^"+e.replace(/\*/g,".*").replace(/\?/g,".")+"$");for(let r of s)n.test(r)&&t.push(Y.join(o,r));return t}var R=w(()=>{"use strict";b()});function _(){process.env.NODE_NO_WARNINGS="1",process.removeAllListeners("warning"),process.on("warning",e=>{e.name==="ExperimentalWarning"&&e.message.includes("SQLite is an experimental feature")||e.message.includes("ExperimentalWarning")});let o=process.emitWarning;process.emitWarning=function(e,...t){let s=typeof e=="string"?e:e.message;if(!(s.includes("ExperimentalWarning")&&s.includes("SQLite")||s.includes("ExperimentalWarning")))return o.call(this,e,...t)}}_();import ee from"node:os";import te from"node:crypto";import{EventEmitter as q}from"node:events";var A=class{emitter=new q;addEventListener(e,t){return this.emitter.on(e,t),this}on(e,t){return this.addEventListener(e,t)}removeEventListener(e,t){return this.emitter.removeListener(e,t),this}off(e,t){return this.removeEventListener(e,t)}emit(e,...t){return this.emitter.emit(e,...t)}};b();var E=class o extends Error{validationResult;constructor(e){let t=o.buildMessage(e);super(t),this.name="SchemaMismatchError",this.validationResult=e}static buildMessage(e){let t=["","\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557","\u2551 SCHEMA MIGRATION REQUIRED \u2551","\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D","",`Your database schema (v${e.currentVersion??"unknown"}) is incompatible with the current version (v${e.expectedVersion}).`,""];return e.missingColumns.length>0&&t.push(`Missing columns: ${e.missingColumns.join(", ")}`),e.extraColumns.length>0&&t.push(`Unknown columns: ${e.extraColumns.join(", ")}`),t.push("","To migrate your database, run:",""," npx yqstore migrate","","Or with Bun:",""," bunx yqstore migrate","","For more options (backup, dry-run, etc.):",""," npx yqstore migrate --help",""),t.join(` `)}},g=class{config;emitter;isInitialized=!1;metrics={operations:{get:{count:0,totalMs:0},set:{count:0,totalMs:0},delete:{count:0,totalMs:0},has:{count:0,totalMs:0}},cache:{hits:0,misses:0},errors:{count:0}};constructor(e,t){this.emitter=t,this.config={dbDir:e.dbDir,dbName:e.dbName,inMemory:e.inMemory??!1,dbFileName:e.dbFileName??`${e.dbName}.yqs`,softDelete:e.softDelete??!0,trackLRU:e.trackLRU??!0,maxEntries:e.maxEntries??1e6,sqlite:{journalMode:e.sqlite?.journalMode??"WAL",synchronous:e.sqlite?.synchronous??"NORMAL",cacheSize:e.sqlite?.cacheSize??-64e3,tempStore:e.sqlite?.tempStore??"memory",busyTimeout:e.sqlite?.busyTimeout??5e3,mmapSize:e.sqlite?.mmapSize??268435456},debug:e.debug??!1,keepAlive:e.keepAlive??!1}}ensureInitialized(){if(!this.isInitialized)throw new Error("Storage engine not initialized. Call initialize() first.")}now(){return Date.now()}calculateExpiresAt(e){return!e||e<=0?9007199254740991:this.now()+e*1e3}normalizeNamespace(e){return e||y}serialize(e){let t=JSON.stringify(e);return new TextEncoder().encode(t)}deserialize(e){let t=new TextDecoder().decode(e);return JSON.parse(t)}trackMetric(e,t){this.metrics.operations[e].count++,this.metrics.operations[e].totalMs+=t}trackCacheHit(e){e?this.metrics.cache.hits++:this.metrics.cache.misses++}trackError(e){this.metrics.errors.count++,this.metrics.errors.lastError=e}getMetrics(){return{...this.metrics}}resetMetrics(){this.metrics={operations:{get:{count:0,totalMs:0},set:{count:0,totalMs:0},delete:{count:0,totalMs:0},has:{count:0,totalMs:0}},cache:{hits:0,misses:0},errors:{count:0}}}debug(e,...t){this.config.debug&&console.log(`[StorageEngine] ${e}`,...t)}isBunRuntime(){return typeof Bun<"u"&&!!Bun?.version}validateSchema(e,t){let s=[...x],n=s.filter(a=>!e.includes(a)),r=e.filter(a=>!s.includes(a)),i=n.length===0&&(t===void 0||t===1);return{isValid:i,currentVersion:t,expectedVersion:1,missingColumns:n,extraColumns:r,message:i?void 0:"Schema mismatch detected"}}getTableExistsSQL(){return"SELECT name FROM sqlite_master WHERE type='table' AND name='kv_store'"}getTableInfoSQL(){return"PRAGMA table_info(kv_store)"}getSchemaVersionTableSQL(){return` CREATE TABLE IF NOT EXISTS yq_meta ( key TEXT PRIMARY KEY, value TEXT NOT NULL ); INSERT OR REPLACE INTO yq_meta (key, value) VALUES ('schema_version', '${1}'); `}getSchemaVersionSQL(){return"SELECT value FROM yq_meta WHERE key = 'schema_version'"}getCreateTableSQL(){return` CREATE TABLE IF NOT EXISTS kv_store ( namespace TEXT NOT NULL DEFAULT '${y}', key TEXT NOT NULL, value BLOB NOT NULL, created_at INTEGER NOT NULL, expires_at INTEGER NOT NULL DEFAULT ${9007199254740991}, is_deleted INTEGER NOT NULL DEFAULT 0, last_accessed INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (namespace, key) ) WITHOUT ROWID; -- Namespace-scoped active records (main query pattern) CREATE INDEX IF NOT EXISTS idx_kv_ns_active ON kv_store(namespace, is_deleted, expires_at, key) WHERE is_deleted = 0; -- Global active records (cross-namespace queries) CREATE INDEX IF NOT EXISTS idx_kv_global_active ON kv_store(is_deleted, expires_at, namespace, key) WHERE is_deleted = 0; -- LRU per namespace CREATE INDEX IF NOT EXISTS idx_kv_ns_lru ON kv_store(namespace, last_accessed) WHERE is_deleted = 0; -- Expiration cleanup CREATE INDEX IF NOT EXISTS idx_kv_expiry ON kv_store(expires_at) WHERE is_deleted = 0 AND expires_at < ${9007199254740991}; -- Namespace stats CREATE INDEX IF NOT EXISTS idx_kv_ns_stats ON kv_store(namespace, is_deleted); `}getPragmaSQL(){let e=this.config.sqlite,t=[];return this.config.inMemory?t.push("PRAGMA journal_mode = MEMORY;","PRAGMA synchronous = OFF;","PRAGMA cache_size = 10000;","PRAGMA temp_store = MEMORY;"):t.push(`PRAGMA journal_mode = ${e.journalMode};`,`PRAGMA synchronous = ${e.synchronous};`,`PRAGMA cache_size = ${e.cacheSize};`,`PRAGMA temp_store = ${e.tempStore};`,`PRAGMA mmap_size = ${e.mmapSize};`,"PRAGMA page_size = 4096;","PRAGMA auto_vacuum = INCREMENTAL;"),t.push(`PRAGMA busy_timeout = ${e.busyTimeout};`),t}};import z from"node:path";import $ from"node:fs/promises";b();var f=class extends g{db;statements;dbFilePath;pendingAccessUpdates=new Map;accessFlushTimer;constructor(e,t){super(e,t),this.config.inMemory?this.dbFilePath=":memory:":this.dbFilePath=z.resolve(this.config.dbDir,this.config.dbFileName)}async initialize(){if(this.isInitialized)return;this.config.inMemory||await $.mkdir(z.dirname(this.dbFilePath),{recursive:!0});let{Database:e}=await import("bun:sqlite");this.db=new e(this.dbFilePath);for(let s of this.getPragmaSQL())this.db.exec(s);if(this.db.query(this.getTableExistsSQL()).get()){let n=this.db.query(this.getTableInfoSQL()).all().map(a=>a.name),r;try{if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='yq_meta'").get()){let c=this.db.query(this.getSchemaVersionSQL()).get();c&&(r=parseInt(c.value,10))}}catch{}let i=this.validateSchema(n,r);if(!i.isValid)throw this.db.close(),this.db=void 0,new E(i);this.debug("Existing schema validated successfully")}this.db.exec(this.getCreateTableSQL()),this.db.exec(this.getSchemaVersionTableSQL()),this.prepareStatements(),this.config.trackLRU&&(this.accessFlushTimer=setInterval(()=>{this.flushAccessUpdates()},1e3),!this.config.keepAlive&&this.accessFlushTimer.unref&&this.accessFlushTimer.unref()),this.isInitialized=!0,this.debug("Initialized BunStorageEngine")}prepareStatements(){if(!this.db)throw new Error("Database not initialized");let e=this.now();this.statements={get:this.db.prepare(` SELECT namespace, key, value, created_at, expires_at, is_deleted, last_accessed FROM kv_store WHERE namespace = ? AND key = ? AND is_deleted = 0 AND expires_at > ? `),set:this.db.prepare(` INSERT OR REPLACE INTO kv_store (namespace, key, value, created_at, expires_at, is_deleted, last_accessed) VALUES (?, ?, ?, ?, ?, 0, ?) `),delete:this.db.prepare(` DELETE FROM kv_store WHERE namespace = ? AND key = ? `),softDelete:this.db.prepare(` UPDATE kv_store SET is_deleted = 1 WHERE namespace = ? AND key = ? AND is_deleted = 0 `),has:this.db.prepare(` SELECT 1 FROM kv_store WHERE namespace = ? AND key = ? AND is_deleted = 0 AND expires_at > ? LIMIT 1 `),updateAccess:this.db.prepare(` UPDATE kv_store SET last_accessed = ? WHERE namespace = ? AND key = ? `),countActive:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE is_deleted = 0 AND expires_at > ? `),countActiveByNamespace:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at > ? `),countDeleted:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE is_deleted = 1 `),countExpired:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `),countAll:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store `),deleteExpired:this.db.prepare(` DELETE FROM kv_store WHERE is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `),deleteDeleted:this.db.prepare(` DELETE FROM kv_store WHERE is_deleted = 1 `),deleteNamespace:this.db.prepare(` DELETE FROM kv_store WHERE namespace = ? `),softDeleteNamespace:this.db.prepare(` UPDATE kv_store SET is_deleted = 1 WHERE namespace = ? AND is_deleted = 0 `),deleteAll:this.db.prepare(` DELETE FROM kv_store `),softDeleteAll:this.db.prepare(` UPDATE kv_store SET is_deleted = 1 WHERE is_deleted = 0 `),selectLRU:this.db.prepare(` SELECT namespace, key FROM kv_store WHERE is_deleted = 0 ORDER BY last_accessed ASC LIMIT ? `),deleteLRU:this.db.prepare(` DELETE FROM kv_store WHERE namespace = ? AND key = ? `),listNamespaces:this.db.prepare(` SELECT DISTINCT namespace FROM kv_store WHERE is_deleted = 0 AND expires_at > ? ORDER BY namespace `)}}async close(){if(this.flushAccessUpdates(),this.accessFlushTimer&&(clearInterval(this.accessFlushTimer),this.accessFlushTimer=void 0),this.db){try{this.db.close()}catch(e){this.debug("Error closing database:",e)}this.db=void 0,this.statements=void 0}this.isInitialized=!1,this.emitter.emit("close")}async set(e,t,s,n){this.ensureInitialized();let r=performance.now(),i=this.normalizeNamespace(n),a=this.now(),c=this.calculateExpiresAt(s),l=this.serialize(t);this.statements.set.run(i,e,l,a,c,a),this.trackMetric("set",performance.now()-r),this.emitter.emit("set",e,t)}async get(e,t){this.ensureInitialized();let s=performance.now(),n=this.normalizeNamespace(t),r=this.now(),i=this.statements.get.get(n,e,r);return i?(this.config.trackLRU&&this.queueAccessUpdate(n,e,r),this.trackMetric("get",performance.now()-s),this.trackCacheHit(!0),{key:i.key,namespace:i.namespace,value:this.deserialize(i.value),createdAt:i.created_at,expiresAt:i.expires_at<9007199254740991?i.expires_at:void 0,isDeleted:!1,lastAccessed:i.last_accessed}):(this.trackMetric("get",performance.now()-s),this.trackCacheHit(!1),null)}async delete(e,t){this.ensureInitialized();let s=performance.now(),n=this.normalizeNamespace(t),r;this.config.softDelete?r=this.statements.softDelete.run(n,e):r=this.statements.delete.run(n,e);let i=r.changes>0;return this.trackMetric("delete",performance.now()-s),i&&this.emitter.emit("delete",e),i}async has(e,t){this.ensureInitialized();let s=performance.now(),n=this.normalizeNamespace(t),r=this.now(),i=this.statements.has.get(n,e,r);return this.trackMetric("has",performance.now()-s),i!==null}async getMany(e,t){this.ensureInitialized();let s=this.normalizeNamespace(t),n=this.now(),r=new Map;if(e.length===0)return r;let i=e.map(()=>"?").join(", "),c=this.db.prepare(` SELECT key, value FROM kv_store WHERE namespace = ? AND key IN (${i}) AND is_deleted = 0 AND expires_at > ? `).all(s,...e,n);for(let l of c)r.set(l.key,this.deserialize(l.value));if(this.config.trackLRU)for(let l of r.keys())this.queueAccessUpdate(s,l,n);return r}async setMany(e,t){if(this.ensureInitialized(),e.length===0)return;let s=this.normalizeNamespace(t),n=this.now();this.db.transaction(()=>{for(let i of e){let a=this.calculateExpiresAt(i.ttl),c=this.serialize(i.value);this.statements.set.run(s,i.key,c,n,a,n)}})();for(let i of e)this.emitter.emit("set",i.key,i.value)}async deleteMany(e,t){if(this.ensureInitialized(),e.length===0)return 0;let s=this.normalizeNamespace(t),n=0;return this.db.transaction(()=>{for(let i of e){let a;this.config.softDelete?a=this.statements.softDelete.run(s,i):a=this.statements.delete.run(s,i),a.changes>0&&(n++,this.emitter.emit("delete",i))}})(),n}async batch(e){if(this.ensureInitialized(),e.length===0)return;let t=this.now();this.db.transaction(()=>{for(let n of e){let r=this.normalizeNamespace(n.namespace);if(n.type==="put"){let i=this.calculateExpiresAt(n.ttl),a=this.serialize(n.value);this.statements.set.run(r,n.key,a,t,i,t),this.emitter.emit("set",n.key,n.value)}else n.type==="del"&&(this.config.softDelete?this.statements.softDelete.run(r,n.key):this.statements.delete.run(r,n.key),this.emitter.emit("delete",n.key))}})()}async listKeys(e){this.ensureInitialized();let t=this.now(),s=e?.namespace,n=e?.prefix,r=e?.suffix,i=e?.limit??1e3,a=e?.offset??0,c=` SELECT key FROM kv_store WHERE is_deleted = 0 AND expires_at > ? `,l=[t];return s&&(c+=" AND namespace = ?",l.push(s)),n&&(c+=" AND key LIKE ?",l.push(n+"%")),r&&(c+=" AND key LIKE ?",l.push("%"+r)),c+=" ORDER BY key LIMIT ? OFFSET ?",l.push(i,a),this.db.prepare(c).all(...l).map(m=>m.key)}async listEntries(e){this.ensureInitialized();let t=this.now(),s=e?.namespace,n=e?.prefix,r=e?.suffix,i=e?.limit??100,a=e?.offset??0,c=` SELECT namespace, key, value, created_at, expires_at, is_deleted, last_accessed FROM kv_store WHERE is_deleted = 0 AND expires_at > ? `,l=[t];return s&&(c+=" AND namespace = ?",l.push(s)),n&&(c+=" AND key LIKE ?",l.push(n+"%")),r&&(c+=" AND key LIKE ?",l.push("%"+r)),c+=" ORDER BY key LIMIT ? OFFSET ?",l.push(i,a),this.db.prepare(c).all(...l).map(m=>({key:m.key,namespace:m.namespace,value:this.deserialize(m.value),createdAt:m.created_at,expiresAt:m.expires_at<9007199254740991?m.expires_at:void 0,isDeleted:!1,lastAccessed:m.last_accessed}))}async getSize(e,t){this.ensureInitialized();let s=this.now(),n=t?.namespace,r=e??"active",i;if(n)switch(r){case"active":i=this.statements.countActiveByNamespace.get(n,s);break;case"deleted":i=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 1 `).get(n);break;case"expired":i=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `).get(n,s);break;case"all":i=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? `).get(n);break}else switch(r){case"active":i=this.statements.countActive.get(s);break;case"deleted":i=this.statements.countDeleted.get();break;case"expired":i=this.statements.countExpired.get(s);break;case"all":i=this.statements.countAll.get();break}return i?.count??0}async clearExpired(){this.ensureInitialized();let e=this.now(),t=this.db.prepare(` SELECT key FROM kv_store WHERE is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `).all(e),s=this.statements.deleteExpired.run(e);for(let n of t)this.emitter.emit("expire",n.key);return s.changes}async clearDeleted(){return this.ensureInitialized(),this.statements.deleteDeleted.run().changes}async clearNamespace(e){this.ensureInitialized();let t;return this.config.softDelete?t=this.statements.softDeleteNamespace.run(e):t=this.statements.deleteNamespace.run(e),t.changes}async clearAll(){this.ensureInitialized(),this.config.softDelete?this.statements.softDeleteAll.run():this.statements.deleteAll.run()}queueAccessUpdate(e,t,s){let n=`${e}:${t}`;this.pendingAccessUpdates.set(n,s),this.pendingAccessUpdates.size>=100&&this.flushAccessUpdates()}flushAccessUpdates(){if(!this.db||!this.statements||this.pendingAccessUpdates.size===0)return;let e=Array.from(this.pendingAccessUpdates.entries());this.pendingAccessUpdates.clear();try{this.db.transaction(()=>{for(let[s,n]of e){let[r,...i]=s.split(":"),a=i.join(":");this.statements.updateAccess.run(n,r,a)}})()}catch(t){this.debug("Error flushing access updates:",t)}}async evictLRU(e){this.ensureInitialized();let t=e??this.config.maxEntries,s=await this.getSize("active");if(s<=t)return 0;let n=s-t,r=this.statements.selectLRU.all(n);return this.db.transaction(()=>{for(let a of r)this.statements.deleteLRU.run(a.namespace,a.key),this.emitter.emit("evict",a.key)})(),r.length}async listNamespaces(){this.ensureInitialized();let e=this.now();return this.statements.listNamespaces.all(e).map(s=>s.namespace)}async getNamespaceStats(e){this.ensureInitialized();let t=this.now(),s=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at > ? `).get(e,t),n=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 1 `).get(e),r=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `).get(e,t),i=this.db.prepare(` SELECT COALESCE(SUM(LENGTH(value)), 0) as size FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at > ? `).get(e,t);return{namespace:e,activeCount:s?.count??0,deletedCount:n?.count??0,expiredCount:r?.count??0,sizeBytes:i?.size??0}}getDbFilePath(){return this.dbFilePath}};import F from"node:path";import X from"node:fs/promises";b();var S=class extends g{db;statements;dbFilePath;pendingAccessUpdates=new Map;accessFlushTimer;constructor(e,t){super(e,t),this.config.inMemory?this.dbFilePath=":memory:":this.dbFilePath=F.resolve(this.config.dbDir,this.config.dbFileName)}async initialize(){if(this.isInitialized)return;this.config.inMemory||await X.mkdir(F.dirname(this.dbFilePath),{recursive:!0});let{DatabaseSync:e}=await import("node:sqlite");this.db=new e(this.dbFilePath);for(let n of this.getPragmaSQL())this.db.exec(n);if(this.db.prepare(this.getTableExistsSQL()).get()){let i=this.db.prepare(this.getTableInfoSQL()).all().map(l=>l.name),a;try{if(this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='yq_meta'").get()){let m=this.db.prepare(this.getSchemaVersionSQL()).get();m&&(a=parseInt(m.value,10))}}catch{}let c=this.validateSchema(i,a);if(!c.isValid)throw this.db.close(),this.db=void 0,new E(c);this.debug("Existing schema validated successfully")}this.db.exec(this.getCreateTableSQL()),this.db.exec(this.getSchemaVersionTableSQL()),this.prepareStatements(),this.config.trackLRU&&(this.accessFlushTimer=setInterval(()=>{this.flushAccessUpdates()},1e3),!this.config.keepAlive&&this.accessFlushTimer.unref&&this.accessFlushTimer.unref()),this.isInitialized=!0,this.debug("Initialized NodeStorageEngine")}prepareStatements(){if(!this.db)throw new Error("Database not initialized");this.statements={get:this.db.prepare(` SELECT namespace, key, value, created_at, expires_at, is_deleted, last_accessed FROM kv_store WHERE namespace = ? AND key = ? AND is_deleted = 0 AND expires_at > ? `),set:this.db.prepare(` INSERT OR REPLACE INTO kv_store (namespace, key, value, created_at, expires_at, is_deleted, last_accessed) VALUES (?, ?, ?, ?, ?, 0, ?) `),delete:this.db.prepare(` DELETE FROM kv_store WHERE namespace = ? AND key = ? `),softDelete:this.db.prepare(` UPDATE kv_store SET is_deleted = 1 WHERE namespace = ? AND key = ? AND is_deleted = 0 `),has:this.db.prepare(` SELECT 1 FROM kv_store WHERE namespace = ? AND key = ? AND is_deleted = 0 AND expires_at > ? LIMIT 1 `),updateAccess:this.db.prepare(` UPDATE kv_store SET last_accessed = ? WHERE namespace = ? AND key = ? `),countActive:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE is_deleted = 0 AND expires_at > ? `),countActiveByNamespace:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at > ? `),countDeleted:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE is_deleted = 1 `),countExpired:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `),countAll:this.db.prepare(` SELECT COUNT(*) as count FROM kv_store `),deleteExpired:this.db.prepare(` DELETE FROM kv_store WHERE is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `),deleteDeleted:this.db.prepare(` DELETE FROM kv_store WHERE is_deleted = 1 `),deleteNamespace:this.db.prepare(` DELETE FROM kv_store WHERE namespace = ? `),softDeleteNamespace:this.db.prepare(` UPDATE kv_store SET is_deleted = 1 WHERE namespace = ? AND is_deleted = 0 `),deleteAll:this.db.prepare(` DELETE FROM kv_store `),softDeleteAll:this.db.prepare(` UPDATE kv_store SET is_deleted = 1 WHERE is_deleted = 0 `),selectLRU:this.db.prepare(` SELECT namespace, key FROM kv_store WHERE is_deleted = 0 ORDER BY last_accessed ASC LIMIT ? `),deleteLRU:this.db.prepare(` DELETE FROM kv_store WHERE namespace = ? AND key = ? `),listNamespaces:this.db.prepare(` SELECT DISTINCT namespace FROM kv_store WHERE is_deleted = 0 AND expires_at > ? ORDER BY namespace `)}}async close(){if(this.flushAccessUpdates(),this.accessFlushTimer&&(clearInterval(this.accessFlushTimer),this.accessFlushTimer=void 0),this.db){try{this.db.close()}catch(e){this.debug("Error closing database:",e)}this.db=void 0,this.statements=void 0}this.isInitialized=!1,this.emitter.emit("close")}async set(e,t,s,n){this.ensureInitialized();let r=performance.now(),i=this.normalizeNamespace(n),a=this.now(),c=this.calculateExpiresAt(s),l=this.serialize(t);this.statements.set.run(i,e,l,a,c,a),this.trackMetric("set",performance.now()-r),this.emitter.emit("set",e,t)}async get(e,t){this.ensureInitialized();let s=performance.now(),n=this.normalizeNamespace(t),r=this.now(),i=this.statements.get.get(n,e,r);return i?(this.config.trackLRU&&this.queueAccessUpdate(n,e,r),this.trackMetric("get",performance.now()-s),this.trackCacheHit(!0),{key:i.key,namespace:i.namespace,value:this.deserialize(i.value),createdAt:i.created_at,expiresAt:i.expires_at<9007199254740991?i.expires_at:void 0,isDeleted:!1,lastAccessed:i.last_accessed}):(this.trackMetric("get",performance.now()-s),this.trackCacheHit(!1),null)}async delete(e,t){this.ensureInitialized();let s=performance.now(),n=this.normalizeNamespace(t),r;this.config.softDelete?r=this.statements.softDelete.run(n,e).changes:r=this.statements.delete.run(n,e).changes;let i=r>0;return this.trackMetric("delete",performance.now()-s),i&&this.emitter.emit("delete",e),i}async has(e,t){this.ensureInitialized();let s=performance.now(),n=this.normalizeNamespace(t),r=this.now(),i=this.statements.has.get(n,e,r);return this.trackMetric("has",performance.now()-s),i!==void 0}async getMany(e,t){this.ensureInitialized();let s=this.normalizeNamespace(t),n=this.now(),r=new Map;if(e.length===0)return r;let i=e.map(()=>"?").join(", "),c=this.db.prepare(` SELECT key, value FROM kv_store WHERE namespace = ? AND key IN (${i}) AND is_deleted = 0 AND expires_at > ? `).all(s,...e,n);for(let l of c)r.set(l.key,this.deserialize(l.value));if(this.config.trackLRU)for(let l of r.keys())this.queueAccessUpdate(s,l,n);return r}async setMany(e,t){if(this.ensureInitialized(),e.length===0)return;let s=this.normalizeNamespace(t),n=this.now();this.db.exec("BEGIN TRANSACTION");try{for(let r of e){let i=this.calculateExpiresAt(r.ttl),a=this.serialize(r.value);this.statements.set.run(s,r.key,a,n,i,n)}this.db.exec("COMMIT");for(let r of e)this.emitter.emit("set",r.key,r.value)}catch(r){throw this.db.exec("ROLLBACK"),r}}async deleteMany(e,t){if(this.ensureInitialized(),e.length===0)return 0;let s=this.normalizeNamespace(t),n=0;this.db.exec("BEGIN TRANSACTION");try{for(let r of e){let i;this.config.softDelete?i=this.statements.softDelete.run(s,r).changes:i=this.statements.delete.run(s,r).changes,i>0&&n++}this.db.exec("COMMIT");for(let r of e)this.emitter.emit("delete",r)}catch(r){throw this.db.exec("ROLLBACK"),r}return n}async batch(e){if(this.ensureInitialized(),e.length===0)return;let t=this.now();this.db.exec("BEGIN TRANSACTION");try{for(let s of e){let n=this.normalizeNamespace(s.namespace);if(s.type==="put"){let r=this.calculateExpiresAt(s.ttl),i=this.serialize(s.value);this.statements.set.run(n,s.key,i,t,r,t)}else s.type==="del"&&(this.config.softDelete?this.statements.softDelete.run(n,s.key):this.statements.delete.run(n,s.key))}this.db.exec("COMMIT");for(let s of e)s.type==="put"?this.emitter.emit("set",s.key,s.value):this.emitter.emit("delete",s.key)}catch(s){throw this.db.exec("ROLLBACK"),s}}async listKeys(e){this.ensureInitialized();let t=this.now(),s=e?.namespace,n=e?.prefix,r=e?.suffix,i=e?.limit??1e3,a=e?.offset??0,c=` SELECT key FROM kv_store WHERE is_deleted = 0 AND expires_at > ? `,l=[t];return s&&(c+=" AND namespace = ?",l.push(s)),n&&(c+=" AND key LIKE ?",l.push(n+"%")),r&&(c+=" AND key LIKE ?",l.push("%"+r)),c+=" ORDER BY key LIMIT ? OFFSET ?",l.push(i,a),this.db.prepare(c).all(...l).map(m=>m.key)}async listEntries(e){this.ensureInitialized();let t=this.now(),s=e?.namespace,n=e?.prefix,r=e?.suffix,i=e?.limit??100,a=e?.offset??0,c=` SELECT namespace, key, value, created_at, expires_at, is_deleted, last_accessed FROM kv_store WHERE is_deleted = 0 AND expires_at > ? `,l=[t];return s&&(c+=" AND namespace = ?",l.push(s)),n&&(c+=" AND key LIKE ?",l.push(n+"%")),r&&(c+=" AND key LIKE ?",l.push("%"+r)),c+=" ORDER BY key LIMIT ? OFFSET ?",l.push(i,a),this.db.prepare(c).all(...l).map(m=>({key:m.key,namespace:m.namespace,value:this.deserialize(m.value),createdAt:m.created_at,expiresAt:m.expires_at<9007199254740991?m.expires_at:void 0,isDeleted:!1,lastAccessed:m.last_accessed}))}async getSize(e,t){this.ensureInitialized();let s=this.now(),n=t?.namespace,r=e??"active",i;if(n)switch(r){case"active":i=this.statements.countActiveByNamespace.get(n,s);break;case"deleted":i=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 1 `).get(n);break;case"expired":i=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `).get(n,s);break;case"all":i=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? `).get(n);break}else switch(r){case"active":i=this.statements.countActive.get(s);break;case"deleted":i=this.statements.countDeleted.get();break;case"expired":i=this.statements.countExpired.get(s);break;case"all":i=this.statements.countAll.get();break}return i?.count??0}async clearExpired(){this.ensureInitialized();let e=this.now(),t=this.db.prepare(` SELECT key FROM kv_store WHERE is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `).all(e),s=this.statements.deleteExpired.run(e);for(let n of t)this.emitter.emit("expire",n.key);return s.changes}async clearDeleted(){return this.ensureInitialized(),this.statements.deleteDeleted.run().changes}async clearNamespace(e){this.ensureInitialized();let t;return this.config.softDelete?t=this.statements.softDeleteNamespace.run(e).changes:t=this.statements.deleteNamespace.run(e).changes,t}async clearAll(){this.ensureInitialized(),this.config.softDelete?this.statements.softDeleteAll.run():this.statements.deleteAll.run()}queueAccessUpdate(e,t,s){let n=`${e}:${t}`;this.pendingAccessUpdates.set(n,s),this.pendingAccessUpdates.size>=100&&this.flushAccessUpdates()}flushAccessUpdates(){if(!this.db||!this.statements||this.pendingAccessUpdates.size===0)return;let e=Array.from(this.pendingAccessUpdates.entries());this.pendingAccessUpdates.clear();try{this.db.exec("BEGIN TRANSACTION");for(let[t,s]of e){let[n,...r]=t.split(":"),i=r.join(":");this.statements.updateAccess.run(s,n,i)}this.db.exec("COMMIT")}catch(t){try{this.db.exec("ROLLBACK")}catch{}this.debug("Error flushing access updates:",t)}}async evictLRU(e){this.ensureInitialized();let t=e??this.config.maxEntries,s=await this.getSize("active");if(s<=t)return 0;let n=s-t,r=this.statements.selectLRU.all(n);this.db.exec("BEGIN TRANSACTION");try{for(let i of r)this.statements.deleteLRU.run(i.namespace,i.key);this.db.exec("COMMIT");for(let i of r)this.emitter.emit("evict",i.key)}catch(i){throw this.db.exec("ROLLBACK"),i}return r.length}async listNamespaces(){this.ensureInitialized();let e=this.now();return this.statements.listNamespaces.all(e).map(s=>s.namespace)}async getNamespaceStats(e){this.ensureInitialized();let t=this.now(),s=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at > ? `).get(e,t),n=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 1 `).get(e),r=this.db.prepare(` SELECT COUNT(*) as count FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at <= ? AND expires_at < ${9007199254740991} `).get(e,t),i=this.db.prepare(` SELECT COALESCE(SUM(LENGTH(value)), 0) as size FROM kv_store WHERE namespace = ? AND is_deleted = 0 AND expires_at > ? `).get(e,t);return{namespace:e,activeCount:s?.count??0,deletedCount:n?.count??0,expiredCount:r?.count??0,sizeBytes:i?.size??0}}getDbFilePath(){return this.dbFilePath}};function G(){return typeof Bun<"u"&&!!Bun?.version}function k(o,e){return G()?new f(o,e):new S(o,e)}function Q(o,e,t){switch(o){case"bun":return new f(e,t);case"node":return new S(e,t);default:return k(e,t)}}b();function se(o){return te.createHash("md5").update(o).digest("hex")}var I=class{constructor(e,t){this.name=e;this.store=t}async set(e,t,s){return this.store.set(e,t,{ttl:s,namespace:this.name})}async get(e){return this.store.get(e,{namespace:this.name})}async delete(e){return this.store.delete(e,{namespace:this.name})}async has(e){return this.store.has(e,{namespace:this.name})}async getMany(e){return this.store.getMany(e,{namespace:this.name})}async setMany(e){return this.store.setMany(e,{namespace:this.name})}async deleteMany(e){return this.store.deleteMany(e,{namespace:this.name})}async listKeys(e){return this.store.listKeys({...e,namespace:this.name})}async list(e){return this.store.list({...e,namespace:this.name})}async getSize(e){return e?this.store.getSize(e,{namespace:this.name}):this.store.getSize({namespace:this.name})}async clear(){return this.store.clearNamespace(this.name)}async getStats(){return this.store.getNamespaceStats(this.name)}},D=class o{options;emitter=new A;engine;namespaceCache=new Map;compactionTimer;evictionTimer;isCompacting=!1;isClosing=!1;dbName="store_storage";constructor(e){let t=ee.tmpdir();e?.storage?.persistence?.dbDir?t=e.storage.persistence.dbDir:this.dbName=se(process.cwd())+"_"+this.dbName,e?.storage?.persistence?.dbFileName&&(this.dbName=e.storage.persistence.dbFileName),this.options={compactionInterval:e?.compactionInterval??36e5,ttl:e?.ttl??0,softDelete:e?.softDelete??!0,storage:{type:e?.storage?.type??"persistence",maxEntries:e?.storage?.maxEntries,maxMemory:e?.storage?.maxMemory,evictionInterval:e?.storage?.evictionInterval??6e4,eviction:e?.storage?.eviction??!1,persistence:e?.storage?.persistence},logging:e?.logging??{enabled:!1},debug:{enabled:e?.debug?.enabled??!1,timing:e?.debug?.timing??!1,sqlLogging:e?.debug?.sqlLogging??!1},keepAlive:e?.keepAlive??!1};let s={dbDir:t,dbName:this.dbName,dbFileName:`${this.dbName}.yqs`,inMemory:this.options.storage.type==="memory",softDelete:this.options.softDelete,trackLRU:this.options.storage.eviction??!0,maxEntries:this.options.storage.maxEntries??1e6,sqlite:this.options.storage.persistence?.sqlite,debug:this.options.debug.enabled,keepAlive:this.options.keepAlive};this.engine=k(s,this.emitter)}static async create(e){let t=new o(e);return await t.initialize(),t}async initialize(){try{await this.engine.initialize(),this.emitter.emit("db:ready"),await this.engine.clearExpired(),this.options.compactionInterval>0&&(this.compactionTimer=setInterval(()=>{this.compact().catch(()=>{})},this.options.compactionInterval),!this.options.keepAlive&&this.compactionTimer.unref&&this.compactionTimer.unref()),this.options.storage.eviction&&(this.evictionTimer=setInterval(()=>{this.runEviction().catch(()=>{})},this.options.storage.evictionInterval),!this.options.keepAlive&&this.evictionTimer.unref&&this.evictionTimer.unref()),this.emitter.emit("ready")}catch(e){throw this.emitter.emit("error",e),e}}on(e,t){return this.emitter.on(e,t),this}off(e,t){return this.emitter.off(e,t),this}addEventListener(e,t){return this.on(e,t)}removeEventListener(e,t){return this.off(e,t)}async has(e,t){return this.engine.has(e,t?.namespace)}async get(e,t){let s=await this.engine.get(e,t?.namespace);return s?s.value:null}async set(e,t,s){let n,r;typeof s=="number"?n=s:s&&(n=s.ttl,r=s.namespace),n===void 0&&this.options.ttl>0&&(n=this.options.ttl),await this.engine.set(e,t,n,r)}async delete(e,t){return this.engine.delete(e,t?.namespace)}async getMany(e,t){return this.engine.getMany(e,t?.namespace)}async setMany(e,t){return this.engine.setMany(e,t?.namespace)}async deleteMany(e,t){return this.engine.deleteMany(e,t?.namespace)}async getSize(e,t){return e===void 0?this.engine.getSize():typeof e=="string"?this.engine.getSize(e,t):this.engine.getSize("active",e)}async listKeys(e){return this.engine.listKeys(e)}async list(e){return(await this.engine.listEntries(e)).map(s=>({key:s.key,value:s.value}))}async forEach(e,t){let s=t?.limit??100,n=t?.offset??0;for(;;){let r=await this.engine.listEntries({...t,limit:s,offset:n});if(r.length===0)break;for(let i of r)await e(i.key,i.value);if(r.length<s)break;n+=s}}ns(e){let t=this.namespaceCache.get(e);return t||(t=new I(e,this),this.namespaceCache.set(e,t)),t}namespace(e){return this.ns(e)}async listNamespaces(){return this.engine.listNamespaces()}async clearNamespace(e){return this.engine.clearNamespace(e)}async getNamespaceStats(e){return this.engine.getNamespaceStats(e)}async getStats(){let e=await this.listNamespaces(),t=[],s=0,n=0,r=0,i=0;for(let a of e){let c=await this.getNamespaceStats(a);t.push(c),s+=c.activeCount,n+=c.deletedCount,r+=c.expiredCount,i+=c.sizeBytes}return{namespaces:t,totalActive:s,totalDeleted:n,totalExpired:r,totalSizeBytes:i}}getMetrics(){return this.engine.getMetrics()}resetMetrics(){this.engine.resetMetrics()}async clearSoftDeletedEntries(){return this.engine.clearDeleted()}async clearExpiredEntries(){return this.engine.clearExpired()}async clear(){return this.engine.clearAll()}async compact(){if(!(this.isCompacting||this.isClosing)){this.isCompacting=!0,this.emitter.emit("compact:start");try{let e=await this.engine.clearDeleted(),t=await this.engine.clearExpired();this.emitter.emit("compact:end",{newSize:await this.getSize(),keysProcessed:e+t})}catch(e){this.emitter.emit("error",e)}finally{this.isCompacting=!1}}}async runEviction(){if(!this.isClosing)try{await this.engine.clearExpired();let e=await this.engine.evictLRU();e>0&&this.emitter.emit("evict",e)}catch(e){this.emitter.emit("error",e)}}async batch(e){return this.engine.batch(e)}createTransaction(){let e=[],t=!1,s=!1;return{put(n,r,i,a){if(t||s)throw new Error("Transaction has already been committed or rolled back");e.push({type:"put",key:n,value:r,ttl:i,namespace:a})},del(n,r){if(t||s)throw new Error("Transaction has already been committed or rolled back");e.push({type:"del",key:n,namespace:r})},commit:async()=>{if(t||s)throw new Error("Transaction has already been committed or rolled back");await this.batch(e),t=!0},rollback(){if(t||s)throw new Error("Transaction has already been committed or rolled back");e.length=0,s=!0}}}async close(){this.isClosing=!0,this.compactionTimer&&(clearInterval(this.compactionTimer),this.compactionTimer=void 0),this.evictionTimer&&(clearInterval(this.evictionTimer),this.evictionTimer=void 0),await this.engine.close(),this.namespaceCache.clear()}getDbFilePath(){return this.engine.getDbFilePath()}static async checkSchema(e){let{checkSchema:t}=await Promise.resolve().then(()=>(R(),C));return t(e)}static async migrate(e){let{migrate:t}=await Promise.resolve().then(()=>(R(),C));return t(e)}static findDatabases(e,t="*.yqs"){let s=P("node:fs"),n=P("node:path"),r=[];if(!s.existsSync(e))return r;let i=s.readdirSync(e),a=new RegExp("^"+t.replace(/\*/g,".*").replace(/\?/g,".")+"$");for(let c of i)a.test(c)&&r.push(n.join(e,c));return r}};b();R();_();export{g as BaseStorageEngine,f as BunStorageEngine,y as DEFAULT_NAMESPACE,p as NEVER_EXPIRES,S as NodeStorageEngine,u as SCHEMA_VERSION,E as SchemaMismatchError,A as TypedEventEmitter,D as YqStore,M as checkSchema,k as createStorageEngine,Q as createStorageEngineOfType,D as default,H as findDatabases,W as migrate}; /** * yq-store - A high-performance, zero-dependency, persistent Key-Value store for Node.js * * @author Olajide Mathew Ogundare <git@yuniq.solutions> * @license MIT */