@asaidimu/utils-persistence 6.1.7 → 6.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t,i=require("@asaidimu/utils-events"),r=require("@asaidimu/utils-database"),s=Object.create,o=Object.defineProperty,n=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,c=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty,h=(e={"node_modules/@asaidimu/query/index.js"(e,t){var i,r=Object.defineProperty,s=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var i in t)r(e,i,{get:t[i],enumerable:!0})})(a,{QueryBuilder:()=>c,createJoiner:()=>y,createMatcher:()=>h,createPaginator:()=>O,createProjector:()=>E,createSorter:()=>b}),t.exports=(i=a,((e,t,i,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))!n.call(e,c)&&c!==i&&r(e,c,{get:()=>t[c],enumerable:!(a=s(t,c))||a.enumerable});return e})(r({},"__esModule",{value:!0}),i));var c=class{query;constructor(){this.query={}}where(e){return this.query.filters=e,this}orderBy(e,t){return this.query.sort||(this.query.sort=[]),this.query.sort.push({field:e,direction:t}),this}offset(e,t){return this.query.pagination={type:"offset",offset:e,limit:t},this}cursor(e,t,i){return this.query.pagination={type:"cursor",cursor:e,limit:t,direction:i},this}include(e){return this.query.projection||(this.query.projection={}),this.query.projection.include=e,this}exclude(e){return this.query.projection||(this.query.projection={}),this.query.projection.exclude=e,this}computed(e,t){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"computed",expression:e,alias:t}),this}case(e,t,i){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"case",conditions:e,else:t,alias:i}),this}join(e,t,i){return this.query.joins||(this.query.joins=[]),this.query.joins.push({relation:e,alias:i,query:t}),this}aggregate(e,t){return this.query.aggregations={groupBy:e,metrics:t},this}window(e){return this.query.window||(this.query.window=[]),this.query.window.push(e),this}hint(e){return this.query.hints||(this.query.hints=[]),this.query.hints.push(e),this}build(){return this.query}};function u(e){function t(e,t){return function(e){return"field"===e?.type}(t)?e[t.field]:function(e){return"value"===e?.type}(t)?t.value:function(e){return"function"===e?.type}(t)?r(t,e):function(e){return"computed"===e?.type}(t)?r(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let i of t.conditions)if(s(e,i.when))return i.then;return t.else}(e,t):t}let i=new Map([["and",(e,t)=>t.every((t=>s(e,t)))],["or",(e,t)=>t.some((t=>s(e,t)))],["not",(e,t)=>!t.every((t=>s(e,t)))],["nor",(e,t)=>!t.some((t=>s(e,t)))],["xor",(e,t)=>1===t.filter((t=>s(e,t))).length]]);function r(i,r){let s=i.arguments.map((e=>t(r,e)));if(e[i.function])return e[i.function](...s);throw new Error(`Function ${i.function} not found!`)}function s(r,s){if(function(e){return!!e&&void 0!==e.conditions}(s))return function(e,t){let{operator:r,conditions:s}=t,o=i.get(r);if(o)return o(e,s);throw new Error(`Unsupported logical operator: ${r}`)}(r,s);if(!s||!s.field)return!1;let{field:o,operator:n,value:a}=s,c=r[o],u=t(r,a),h=new Map([["eq",(e,t)=>e===t],["neq",(e,t)=>e!==t],["lt",(e,t)=>e<t],["lte",(e,t)=>e<=t],["gt",(e,t)=>e>t],["gte",(e,t)=>e>=t],["in",(e,t)=>Array.isArray(t)&&t.includes(e)],["nin",(e,t)=>Array.isArray(t)&&!t.includes(e)],["contains",(e,t)=>"string"==typeof e?e.includes(t):!!Array.isArray(e)&&e.includes(a)],["ncontains",(e,t)=>"string"==typeof e&&!e.includes(t)],["startswith",(e,t)=>"string"==typeof e&&e.startsWith(t)],["endswith",(e,t)=>"string"==typeof e&&e.endsWith(t)],["exists",e=>null!=e],["nexists",e=>null==e]]),l=e[n]||h.get(n);if(l)return l(c,u);throw new Error(`Unsupported comparison operator: ${n}`)}return{resolve:t,evaluate:s}}function h(e){let{evaluate:t}=u(e),i=new WeakMap;function r(e,r){let s=i.get(e);s||(s=new Map,i.set(e,s));let o=JSON.stringify(r);if(s.has(o))return s.get(o);let n=t(e,r);return s.set(o,n),n}return{matcher:r,match:r}}var l=class extends Error{constructor(e,t){super(e),this.code=t,this.name="JoinError"}},d=e=>e&&"field"in e&&"operator"in e&&"value"in e,p=(e,t)=>{if(e){if(d(e)&&e){let i=(e=>"object"==typeof e&&null!==e&&"type"in e&&"field"===e.type)(e.value)?((e,t)=>t.split(".").reduce(((e,t)=>e?.[t]),e))(t,e.value.field):e.value;return{...e,value:i}}if((e=>"operator"in e&&"conditions"in e)(e)){let i={...e};return e.conditions&&(i.conditions=e.conditions.map((e=>p(e,t)))),i}return e}},f=async(e,t,i,r)=>{try{if(((e,t)=>{if(!e.relation)throw new l("Join configuration must specify a relation","INVALID_CONFIG");if(!t[e.relation])throw new l(`Collection "${e.relation}" not found in database`,"COLLECTION_NOT_FOUND");if(e.alias&&"string"!=typeof e.alias)throw new l("Join alias must be a string","INVALID_ALIAS")})(i,e),!Array.isArray(t))throw new l("Source data must be an array","INVALID_SOURCE_DATA");let s,o=e[i.relation];return i.query?.filters&&d(i.query.filters)&&(s=((e,t)=>{let i=new Map;return e.forEach((e=>{let r=e[t];i.has(r)||i.set(r,[]),i.get(r).push(e)})),i})(o,i.query.filters.field)),(await Promise.all(t.map((async e=>{let t,n=((e,t)=>{if(!e)return{};let i=p(e.filters,t);return{...e,filters:i}})(i.query,e);return t=n.filters&&d(n.filters)&&s?.has(n.filters.value)?s.get(n.filters.value)||[]:o.filter((e=>r.matcher(e,n.filters))),((e,t,i)=>{let r=i.alias||i.relation;return[{...e,[r]:t}]})(e,await[e=>n.sort?r.sorter(e,n.sort):e,e=>n.projection?r.projector(e,n.projection):e,async e=>n.pagination?await r.paginator(e,n.pagination):e].reduce((async(e,t)=>t(await e)),Promise.resolve(t)),i)})))).flat()}catch(e){throw e instanceof l?e:new l(`Join operation failed: ${e.message}`,"JOIN_EXECUTION_ERROR")}},g=async(e,t,i,r)=>i.reduce((async(t,i)=>f(e,await t,i,r)),Promise.resolve(t));function y(){return{join:g}}var m=class extends Error{constructor(e,t){super(`Unsupported comparison between ${typeof e} and ${typeof t}`),this.name="UnsupportedComparisonError"}},w=class extends Error{constructor(e){super(`Unsupported sort direction: ${e}`),this.name="InvalidSortDirectionError"}};function v(e,t,i){if(e===t)return 0;if(null==e||null==t)return null==e?"asc"===i?-1:1:"asc"===i?1:-1;if("string"==typeof e&&"string"==typeof t)return"asc"===i?e.localeCompare(t):t.localeCompare(e);if("number"==typeof e&&"number"==typeof t)return"asc"===i?e-t:t-e;throw new m(e,t)}function _(e,t){let i=Array.from(e);return 0===t.length?i:i.sort(((e,i)=>{for(let r of t){let{field:t,direction:s}=r,o=e[t],n=i[t];try{if("asc"!==s&&"desc"!==s)throw new w(s);let e=v(o,n,s);if(0!==e)return e}catch(e){throw e instanceof m||e instanceof w?e:new Error(`Error comparing field '${t}': ${e.message}`)}}return 0}))}function b(){return{sort:_}}function E(e){let{resolve:t}=u(e);function i(e,r){let s={};return r.include?.length&&function(e,t,r){for(let s of t)if("string"!=typeof s){for(let[t,o]of Object.entries(s))if(Object.prototype.hasOwnProperty.call(e,t)){let s=i(e[t],o);r[t]=s}}else{let t=s;r[t]=e[t]}}(e,r.include,s),r.exclude?.length&&function(e,t,r){0===Object.keys(r).length&&Object.assign(r,e);for(let e of t)if("string"!=typeof e)for(let[t,s]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(r,t))continue;let e=r[t];e&&"object"==typeof e?r[t]=i(e,s):delete r[t]}else delete r[e]}(e,r.exclude,s),r.computed?.length&&function(e,i,r){for(let s of i)r[s.alias]=t(e,s)}(e,r.computed,s),s}return{project:i}}async function*S(e,t,i=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:i,limit:r}=t,s=0,o=r,n=[];for await(let t of e)o<=0&&(yield n,n=[],o=r),s<i?s++:(n.push(t),o--);n.length>0&&(yield n)}(e,t):yield*async function*(e,t,i){let{cursor:r,limit:s,direction:o}=t,n=s,a=void 0===r,c=[];if("forward"===o)for await(let t of e)n<=0&&(yield c,c=[],n=s),a?(c.push(t),n--):a=i(t)===r;else{let t=[];for await(let i of e)t.push(i);for(let e=t.length-1;e>=0;e--){let o=t[e];a?(c.push(o),n--,n<=0&&(yield c,c=[],n=s)):a=i(o)===r}}c.length>0&&(yield c)}(e,t,i)}function O(){return{paginate:S}}}},function(){return t||(0,e[a(e)[0]])((t={exports:{}}).exports,t),t.exports}),l=((e,t,i)=>(i=null!=e?s(c(e)):{},((e,t,i,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let s of a(t))u.call(e,s)||s===i||o(e,s,{get:()=>t[s],enumerable:!(r=n(t,s))||r.enumerable});return e})(e&&e.__esModule?i:o(i,"default",{value:e,enumerable:!0}),e)))(h()),d={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},p=new Map;var f=class e extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(t){const i={...function(e){const t=Object.values(d).find((t=>t.code===e));if(t)return t;return p.get(e)||{code:e,name:e.replace(/-/g,"_"),description:`Unknown error: ${e}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(t.code),...t.metadata,code:t.code};super(t.message??i.description),this.name="SystemError",this.code=t.code,this.codeMetadata=i,this.severity=t.severity??"error",this.path=t.path,this.operation=t.operation,this.issues=t.issues??[],this.cause=t.cause,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}withPath(t){return new e({code:this.code,message:this.message,severity:this.severity,path:t,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:t,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,t],cause:this.cause,metadata:this.codeMetadata})}withIssues(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...t],cause:this.cause,metadata:this.codeMetadata})}withCause(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:t,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},g=class e extends f{constructor(t,i){super({code:"SYNC_ERROR",message:t,cause:i}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},y=class e extends g{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},m=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const i=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await i;let r;await Promise.race([i.then((()=>clearTimeout(r))),new Promise(((i,s)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),s(new y("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},w=class{mutex=new m({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,i="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,s)=>{r=setTimeout((()=>s(new y(i))),t)}))])}},v=class{constructor(e,t,i={}){this.factory=e,this.onCleanup=t,this.options=i}_count=0;init=new w({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}},_=class e{static dbResources=new Map;static eventBusMap=new Map;static createDatabaseFactory(e){return async()=>{const{database:t,enableTelemetry:i=!1,collection:s="stores"}=e,o=await r.DatabaseConnection({database:t,enableTelemetry:i},r.createIndexedDbStore);try{await o.createCollection({name:s,version:"1.0.0",nestedSchemas:{},fields:{store:{name:"store",type:"string",required:!0},data:{name:"data",type:"object",required:!0},version:{name:"version",type:"string",required:!0},app:{name:"app",type:"string",required:!0}}})}catch(e){if(e instanceof r.DatabaseError&&"SCHEMA_ALREADY_EXISTS"!==e.type)throw e}return o}}static createDatabaseCleanup(t){return i=>{i?.close();const r=[];e.eventBusMap.forEach(((e,i)=>{i.startsWith(`${t}_store_`)&&(e.clear(),r.push(i))})),r.forEach((t=>e.eventBusMap.delete(t)))}}static async acquireDatabase(t){const i=t.database;if(!e.dbResources.has(i)){const r=new v(e.createDatabaseFactory(t),e.createDatabaseCleanup(i),{gracePeriod:"microtask"});e.dbResources.set(i,r)}return e.dbResources.get(i).acquire()}static releaseDatabase(t){const i=e.dbResources.get(t);i&&i.release()}static async getCollection(t){const i=await e.acquireDatabase(t),r=t.collection??"stores";return i.collection(r)}static getEventBus(t,r){const s=`${t}_store_${r}`;return e.eventBusMap.has(s)||e.eventBusMap.set(s,i.createEventBus({errorHandler:e=>console.error(`Event bus error for ${t}:${r}:`,e),broadcast:{channel:s}})),e.eventBusMap.get(s)}};exports.EphemeralPersistence=class{eventBus;inMemoryState=null;config;constructor(e){this.config=e,this.eventBus=this.initializeEventBus(),this.setupLwwSynchronizationListener()}initializeEventBus(){const e={errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey} (Ephemeral LWW):`,e)};return"undefined"!=typeof process&&"test"===process.env.NODE_ENV||(e.broadcast={channel:`ephemeral_lww_${this.config.storageKey}`}),i.createEventBus(e)}setupLwwSynchronizationListener(){this.eventBus.subscribe("store:updated",(({storageKey:e,instanceId:t,state:i,timestamp:r,version:s})=>{e===this.config.storageKey&&(!this.inMemoryState||r&&r>this.inMemoryState.timestamp)&&(this.inMemoryState={data:i,timestamp:r,instanceId:t,version:s})}))}set(e,t){try{const i=Date.now();return this.inMemoryState={data:structuredClone(t),timestamp:i,instanceId:e,version:this.config.version},this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,timestamp:i,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to set state in EphemeralPersistence (LWW) for ${this.config.storageKey}:`,e),!1}}get(){return this.inMemoryState?.data??null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.config.storageKey&&r!==e&&t(s)}))}clear(){try{const e=Date.now(),t="clear-initiator";return this.inMemoryState={data:null,timestamp:e,instanceId:t,version:this.config.version},this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:t,state:null,timestamp:e,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear state in EphemeralPersistence (LWW) for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}},exports.IndexedDBPersistence=class{collection=null;collectionPromise;config;eventBus;initialized=!1;_initializing=!1;initializationCallbacks=[];doc=null;getStoreName(){return`_${this.config.app}_${this.config.store}_`}constructor(e){this.config=e,this.collectionPromise=_.getCollection(this.config),this.collectionPromise.then((e=>{this.collection=e,this.initialize()})).catch((e=>{console.error(`Failed to initialize collection for store ${this.getStoreName()}:`,e)})),this.eventBus=_.getEventBus(this.config.database,this.getStoreName()),this.eventBus.subscribe("store:updated",(({storageKey:e})=>{e===this.getStoreName()&&(this.doc=null)}))}async initialize(){this._initializing=!0;try{const e=await this._get();if(e&&e.version!==this.config.version&&this.config.onUpgrade){const{state:t}=await this.config.onUpgrade({data:e.data,version:e.version,app:e.app});await this.set("migration",t)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize and upgrade store ${this.getStoreName()}:`,e)}finally{this._initializing=!1}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}async getCollection(){return this.collection??this.collectionPromise}async set(e,t){this.initialized||this._initializing||await new Promise((e=>this._onInitialized(e)));try{const i=await this.getCollection(),r=await this._read(),s={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let o;return r?o=await r.update(s):(this.doc=await i.create(s),o=!0),o&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:e,state:t,version:this.config.version,app:this.config.app}}),o}catch(t){return console.error(`Failed to set state for store ${this.getStoreName()} in database ${this.config.database} by instance ${e}:`,t),!1}}async _read(){if(this.doc)return this.doc;const e=await this.getCollection(),t=(new l.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build();return this.doc=await e.find(t.filters),this.doc}async _get(){try{const e=await this._read();return e?e.read().then((()=>e)):null}catch(e){return console.error(`Failed to get state for store ${this.getStoreName()} in database ${this.config.database}:`,e),null}}async get(){this.initialized||await new Promise((e=>this._onInitialized(e)));const e=await this._get();return e?e.data:null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.getStoreName()&&r!==e&&t(s)}))}async clear(){this.initialized||await new Promise((e=>this._onInitialized(e)));try{const e=await this._read();return!e||!await e.delete()||(this.doc=null,this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:"",state:null,version:this.config.version,app:this.config.app}}),!0)}catch(e){return console.error(`Failed to clear state for store ${this.getStoreName()} in database ${this.config.database}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}async close(){_.releaseDatabase(this.config.database)}},exports.WebStoragePersistence=class{eventBus;storage;config;initialized=!1;initializationCallbacks=[];constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}async initialize(){try{const e=this.storage.getItem(this.getStoreName());if(e){const t=JSON.parse(e);if(t.version!==this.config.version&&this.config.onUpgrade){const{state:e}=await this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}initializeEventBus(){const e={errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey}:`,e)};return"undefined"!=typeof process&&"test"===process.env.NODE_ENV||(e.broadcast={channel:`storage_${this.getStoreName()}`}),i.createEventBus(e)}getStoreName(){return`_${this.config.app}_${this.config.storageKey}_`}setupStorageEventListener(){window.addEventListener("storage",(e=>{if(e.key===this.getStoreName()&&e.newValue)try{const t=JSON.parse(e.newValue);t&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"external",state:t.state,version:t.version,app:t.app}})}catch(e){console.error("Failed to parse storage event data:",e)}}))}set(e,t){try{const i={state:structuredClone(t),version:this.config.version,app:this.config.app},r=JSON.stringify(i);return this.storage.setItem(this.getStoreName(),r),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to persist state to web storage for ${this.config.storageKey}:`,e),!1}}_get(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return null;return JSON.parse(e).state}catch(e){return console.error(`Failed to retrieve state from web storage for ${this.config.storageKey}:`,e),null}}async get(){return this.initialized||await new Promise((e=>{this._onInitialized(e)})),this._get()}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.config.storageKey&&r!==e&&t(s)}))}clear(){try{return this.storage.removeItem(this.getStoreName()),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"clear-initiator",state:null,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear persisted state for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}};
|
|
1
|
+
"use strict";var e,t,i=require("@asaidimu/utils-events"),r=require("@asaidimu/utils-database"),s=Object.create,o=Object.defineProperty,n=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,c=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty,h=(e={"node_modules/@asaidimu/query/index.js"(e,t){var i,r=Object.defineProperty,s=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var i in t)r(e,i,{get:t[i],enumerable:!0})})(a,{QueryBuilder:()=>c,createJoiner:()=>y,createMatcher:()=>h,createPaginator:()=>O,createProjector:()=>E,createSorter:()=>b}),t.exports=(i=a,((e,t,i,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))!n.call(e,c)&&c!==i&&r(e,c,{get:()=>t[c],enumerable:!(a=s(t,c))||a.enumerable});return e})(r({},"__esModule",{value:!0}),i));var c=class{query;constructor(){this.query={}}where(e){return this.query.filters=e,this}orderBy(e,t){return this.query.sort||(this.query.sort=[]),this.query.sort.push({field:e,direction:t}),this}offset(e,t){return this.query.pagination={type:"offset",offset:e,limit:t},this}cursor(e,t,i){return this.query.pagination={type:"cursor",cursor:e,limit:t,direction:i},this}include(e){return this.query.projection||(this.query.projection={}),this.query.projection.include=e,this}exclude(e){return this.query.projection||(this.query.projection={}),this.query.projection.exclude=e,this}computed(e,t){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"computed",expression:e,alias:t}),this}case(e,t,i){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"case",conditions:e,else:t,alias:i}),this}join(e,t,i){return this.query.joins||(this.query.joins=[]),this.query.joins.push({relation:e,alias:i,query:t}),this}aggregate(e,t){return this.query.aggregations={groupBy:e,metrics:t},this}window(e){return this.query.window||(this.query.window=[]),this.query.window.push(e),this}hint(e){return this.query.hints||(this.query.hints=[]),this.query.hints.push(e),this}build(){return this.query}};function u(e){function t(e,t){return function(e){return"field"===e?.type}(t)?e[t.field]:function(e){return"value"===e?.type}(t)?t.value:function(e){return"function"===e?.type}(t)?r(t,e):function(e){return"computed"===e?.type}(t)?r(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let i of t.conditions)if(s(e,i.when))return i.then;return t.else}(e,t):t}let i=new Map([["and",(e,t)=>t.every((t=>s(e,t)))],["or",(e,t)=>t.some((t=>s(e,t)))],["not",(e,t)=>!t.every((t=>s(e,t)))],["nor",(e,t)=>!t.some((t=>s(e,t)))],["xor",(e,t)=>1===t.filter((t=>s(e,t))).length]]);function r(i,r){let s=i.arguments.map((e=>t(r,e)));if(e[i.function])return e[i.function](...s);throw new Error(`Function ${i.function} not found!`)}function s(r,s){if(function(e){return!!e&&void 0!==e.conditions}(s))return function(e,t){let{operator:r,conditions:s}=t,o=i.get(r);if(o)return o(e,s);throw new Error(`Unsupported logical operator: ${r}`)}(r,s);if(!s||!s.field)return!1;let{field:o,operator:n,value:a}=s,c=r[o],u=t(r,a),h=new Map([["eq",(e,t)=>e===t],["neq",(e,t)=>e!==t],["lt",(e,t)=>e<t],["lte",(e,t)=>e<=t],["gt",(e,t)=>e>t],["gte",(e,t)=>e>=t],["in",(e,t)=>Array.isArray(t)&&t.includes(e)],["nin",(e,t)=>Array.isArray(t)&&!t.includes(e)],["contains",(e,t)=>"string"==typeof e?e.includes(t):!!Array.isArray(e)&&e.includes(a)],["ncontains",(e,t)=>"string"==typeof e&&!e.includes(t)],["startswith",(e,t)=>"string"==typeof e&&e.startsWith(t)],["endswith",(e,t)=>"string"==typeof e&&e.endsWith(t)],["exists",e=>null!=e],["nexists",e=>null==e]]),l=e[n]||h.get(n);if(l)return l(c,u);throw new Error(`Unsupported comparison operator: ${n}`)}return{resolve:t,evaluate:s}}function h(e){let{evaluate:t}=u(e),i=new WeakMap;function r(e,r){let s=i.get(e);s||(s=new Map,i.set(e,s));let o=JSON.stringify(r);if(s.has(o))return s.get(o);let n=t(e,r);return s.set(o,n),n}return{matcher:r,match:r}}var l=class extends Error{constructor(e,t){super(e),this.code=t,this.name="JoinError"}},d=e=>e&&"field"in e&&"operator"in e&&"value"in e,p=(e,t)=>{if(e){if(d(e)&&e){let i=(e=>"object"==typeof e&&null!==e&&"type"in e&&"field"===e.type)(e.value)?((e,t)=>t.split(".").reduce(((e,t)=>e?.[t]),e))(t,e.value.field):e.value;return{...e,value:i}}if((e=>"operator"in e&&"conditions"in e)(e)){let i={...e};return e.conditions&&(i.conditions=e.conditions.map((e=>p(e,t)))),i}return e}},f=async(e,t,i,r)=>{try{if(((e,t)=>{if(!e.relation)throw new l("Join configuration must specify a relation","INVALID_CONFIG");if(!t[e.relation])throw new l(`Collection "${e.relation}" not found in database`,"COLLECTION_NOT_FOUND");if(e.alias&&"string"!=typeof e.alias)throw new l("Join alias must be a string","INVALID_ALIAS")})(i,e),!Array.isArray(t))throw new l("Source data must be an array","INVALID_SOURCE_DATA");let s,o=e[i.relation];return i.query?.filters&&d(i.query.filters)&&(s=((e,t)=>{let i=new Map;return e.forEach((e=>{let r=e[t];i.has(r)||i.set(r,[]),i.get(r).push(e)})),i})(o,i.query.filters.field)),(await Promise.all(t.map((async e=>{let t,n=((e,t)=>{if(!e)return{};let i=p(e.filters,t);return{...e,filters:i}})(i.query,e);return t=n.filters&&d(n.filters)&&s?.has(n.filters.value)?s.get(n.filters.value)||[]:o.filter((e=>r.matcher(e,n.filters))),((e,t,i)=>{let r=i.alias||i.relation;return[{...e,[r]:t}]})(e,await[e=>n.sort?r.sorter(e,n.sort):e,e=>n.projection?r.projector(e,n.projection):e,async e=>n.pagination?await r.paginator(e,n.pagination):e].reduce((async(e,t)=>t(await e)),Promise.resolve(t)),i)})))).flat()}catch(e){throw e instanceof l?e:new l(`Join operation failed: ${e.message}`,"JOIN_EXECUTION_ERROR")}},g=async(e,t,i,r)=>i.reduce((async(t,i)=>f(e,await t,i,r)),Promise.resolve(t));function y(){return{join:g}}var m=class extends Error{constructor(e,t){super(`Unsupported comparison between ${typeof e} and ${typeof t}`),this.name="UnsupportedComparisonError"}},w=class extends Error{constructor(e){super(`Unsupported sort direction: ${e}`),this.name="InvalidSortDirectionError"}};function v(e,t,i){if(e===t)return 0;if(null==e||null==t)return null==e?"asc"===i?-1:1:"asc"===i?1:-1;if("string"==typeof e&&"string"==typeof t)return"asc"===i?e.localeCompare(t):t.localeCompare(e);if("number"==typeof e&&"number"==typeof t)return"asc"===i?e-t:t-e;throw new m(e,t)}function _(e,t){let i=Array.from(e);return 0===t.length?i:i.sort(((e,i)=>{for(let r of t){let{field:t,direction:s}=r,o=e[t],n=i[t];try{if("asc"!==s&&"desc"!==s)throw new w(s);let e=v(o,n,s);if(0!==e)return e}catch(e){throw e instanceof m||e instanceof w?e:new Error(`Error comparing field '${t}': ${e.message}`)}}return 0}))}function b(){return{sort:_}}function E(e){let{resolve:t}=u(e);function i(e,r){let s={};return r.include?.length&&function(e,t,r){for(let s of t)if("string"!=typeof s){for(let[t,o]of Object.entries(s))if(Object.prototype.hasOwnProperty.call(e,t)){let s=i(e[t],o);r[t]=s}}else{let t=s;r[t]=e[t]}}(e,r.include,s),r.exclude?.length&&function(e,t,r){0===Object.keys(r).length&&Object.assign(r,e);for(let e of t)if("string"!=typeof e)for(let[t,s]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(r,t))continue;let e=r[t];e&&"object"==typeof e?r[t]=i(e,s):delete r[t]}else delete r[e]}(e,r.exclude,s),r.computed?.length&&function(e,i,r){for(let s of i)r[s.alias]=t(e,s)}(e,r.computed,s),s}return{project:i}}async function*S(e,t,i=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:i,limit:r}=t,s=0,o=r,n=[];for await(let t of e)o<=0&&(yield n,n=[],o=r),s<i?s++:(n.push(t),o--);n.length>0&&(yield n)}(e,t):yield*async function*(e,t,i){let{cursor:r,limit:s,direction:o}=t,n=s,a=void 0===r,c=[];if("forward"===o)for await(let t of e)n<=0&&(yield c,c=[],n=s),a?(c.push(t),n--):a=i(t)===r;else{let t=[];for await(let i of e)t.push(i);for(let e=t.length-1;e>=0;e--){let o=t[e];a?(c.push(o),n--,n<=0&&(yield c,c=[],n=s)):a=i(o)===r}}c.length>0&&(yield c)}(e,t,i)}function O(){return{paginate:S}}}},function(){return t||(0,e[a(e)[0]])((t={exports:{}}).exports,t),t.exports}),l=((e,t,i)=>(i=null!=e?s(c(e)):{},((e,t,i,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let s of a(t))u.call(e,s)||s===i||o(e,s,{get:()=>t[s],enumerable:!(r=n(t,s))||r.enumerable});return e})(e&&e.__esModule?i:o(i,"default",{value:e,enumerable:!0}),e)))(h()),d={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},p=new Map;var f=class e extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(t){const i={...function(e){const t=Object.values(d).find((t=>t.code===e));if(t)return t;return p.get(e)||{code:e,name:e.replace(/-/g,"_"),description:`Unknown error: ${e}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(t.code),...t.metadata,code:t.code};super(t.message??i.description),this.name="SystemError",this.code=t.code,this.codeMetadata=i,this.severity=t.severity??"error",this.path=t.path,this.operation=t.operation,this.issues=t.issues??[],this.cause=t.cause,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}withPath(t){return new e({code:this.code,message:this.message,severity:this.severity,path:t,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:t,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,t],cause:this.cause,metadata:this.codeMetadata})}withIssues(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...t],cause:this.cause,metadata:this.codeMetadata})}withCause(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:t,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},g=class e extends f{constructor(t,i){super({code:"SYNC_ERROR",message:t,cause:i}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},y=class e extends g{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},m=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const i=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await i;let r;await Promise.race([i.then((()=>clearTimeout(r))),new Promise(((i,s)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),s(new y("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},w=class{mutex=new m({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}resolve(e){if(this._done)throw new Error("Cannot resolve: operation is already completed.");if(this.running())throw new Error("Cannot resolve: operation is currently running.");this._value=e,this._done=!0}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,i="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,s)=>{r=setTimeout((()=>s(new y(i))),t)}))])}},v=class{constructor(e,t,i={}){this.factory=e,this.onCleanup=t,this.options=i}_count=0;init=new w({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}},_=class e{static dbResources=new Map;static eventBusMap=new Map;static createDatabaseFactory(e){return async()=>{const{database:t,enableTelemetry:i=!1,collection:s="stores"}=e,o=await r.DatabaseConnection({database:t,enableTelemetry:i},r.createIndexedDbStore);try{await o.createCollection({name:s,version:"1.0.0",nestedSchemas:{},fields:{store:{name:"store",type:"string",required:!0},data:{name:"data",type:"object",required:!0},version:{name:"version",type:"string",required:!0},app:{name:"app",type:"string",required:!0}}})}catch(e){if(e instanceof r.DatabaseError&&"SCHEMA_ALREADY_EXISTS"!==e.type)throw e}return o}}static createDatabaseCleanup(t){return i=>{i?.close();const r=[];e.eventBusMap.forEach(((e,i)=>{i.startsWith(`${t}_store_`)&&(e.clear(),r.push(i))})),r.forEach((t=>e.eventBusMap.delete(t)))}}static async acquireDatabase(t){const i=t.database;if(!e.dbResources.has(i)){const r=new v(e.createDatabaseFactory(t),e.createDatabaseCleanup(i),{gracePeriod:"microtask"});e.dbResources.set(i,r)}return e.dbResources.get(i).acquire()}static releaseDatabase(t){const i=e.dbResources.get(t);i&&i.release()}static async getCollection(t){const i=await e.acquireDatabase(t),r=t.collection??"stores";return i.collection(r)}static getEventBus(t,r){const s=`${t}_store_${r}`;return e.eventBusMap.has(s)||e.eventBusMap.set(s,i.createEventBus({errorHandler:e=>console.error(`Event bus error for ${t}:${r}:`,e),broadcast:{channel:s}})),e.eventBusMap.get(s)}};exports.EphemeralPersistence=class{eventBus;inMemoryState=null;config;constructor(e){this.config=e,this.eventBus=this.initializeEventBus(),this.setupLwwSynchronizationListener()}initializeEventBus(){const e={errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey} (Ephemeral LWW):`,e)};return"undefined"!=typeof process&&"test"===process.env.NODE_ENV||(e.broadcast={channel:`ephemeral_lww_${this.config.storageKey}`}),i.createEventBus(e)}setupLwwSynchronizationListener(){this.eventBus.subscribe("store:updated",(({storageKey:e,instanceId:t,state:i,timestamp:r,version:s})=>{e===this.config.storageKey&&(!this.inMemoryState||r&&r>this.inMemoryState.timestamp)&&(this.inMemoryState={data:i,timestamp:r,instanceId:t,version:s})}))}set(e,t){try{const i=Date.now();return this.inMemoryState={data:structuredClone(t),timestamp:i,instanceId:e,version:this.config.version},this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,timestamp:i,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to set state in EphemeralPersistence (LWW) for ${this.config.storageKey}:`,e),!1}}get(){return this.inMemoryState?.data??null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.config.storageKey&&r!==e&&t(s)}))}clear(){try{const e=Date.now(),t="clear-initiator";return this.inMemoryState={data:null,timestamp:e,instanceId:t,version:this.config.version},this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:t,state:null,timestamp:e,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear state in EphemeralPersistence (LWW) for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}},exports.IndexedDBPersistence=class{collection=null;collectionPromise;config;eventBus;initialized=!1;_initializing=!1;initializationCallbacks=[];doc=null;getStoreName(){return`_${this.config.app}_${this.config.store}_`}constructor(e){this.config=e,this.collectionPromise=_.getCollection(this.config),this.collectionPromise.then((e=>{this.collection=e,this.initialize()})).catch((e=>{console.error(`Failed to initialize collection for store ${this.getStoreName()}:`,e)})),this.eventBus=_.getEventBus(this.config.database,this.getStoreName()),this.eventBus.subscribe("store:updated",(({storageKey:e})=>{e===this.getStoreName()&&(this.doc=null)}))}async initialize(){this._initializing=!0;try{const e=await this._get();if(e&&e.version!==this.config.version&&this.config.onUpgrade){const{state:t}=await this.config.onUpgrade({data:e.data,version:e.version,app:e.app});await this.set("migration",t)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize and upgrade store ${this.getStoreName()}:`,e)}finally{this._initializing=!1}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}async getCollection(){return this.collection??this.collectionPromise}async set(e,t){this.initialized||this._initializing||await new Promise((e=>this._onInitialized(e)));try{const i=await this.getCollection(),r=await this._read(),s={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let o;return r?o=await r.update(s):(this.doc=await i.create(s),o=!0),o&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:e,state:t,version:this.config.version,app:this.config.app}}),o}catch(t){return console.error(`Failed to set state for store ${this.getStoreName()} in database ${this.config.database} by instance ${e}:`,t),!1}}async _read(){if(this.doc)return this.doc;const e=await this.getCollection(),t=(new l.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build();return this.doc=await e.find(t.filters),this.doc}async _get(){try{const e=await this._read();return e?e.read().then((()=>e)):null}catch(e){return console.error(`Failed to get state for store ${this.getStoreName()} in database ${this.config.database}:`,e),null}}async get(){this.initialized||await new Promise((e=>this._onInitialized(e)));const e=await this._get();return e?e.data:null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.getStoreName()&&r!==e&&t(s)}))}async clear(){this.initialized||await new Promise((e=>this._onInitialized(e)));try{const e=await this._read();return!e||!await e.delete()||(this.doc=null,this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:"",state:null,version:this.config.version,app:this.config.app}}),!0)}catch(e){return console.error(`Failed to clear state for store ${this.getStoreName()} in database ${this.config.database}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}async close(){_.releaseDatabase(this.config.database)}},exports.WebStoragePersistence=class{eventBus;storage;config;initialized=!1;initializationCallbacks=[];constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}async initialize(){try{const e=this.storage.getItem(this.getStoreName());if(e){const t=JSON.parse(e);if(t.version!==this.config.version&&this.config.onUpgrade){const{state:e}=await this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}initializeEventBus(){const e={batch:{size:0,delay:0},errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey}:`,e)};return"undefined"!=typeof process&&"test"===process.env.NODE_ENV||(e.broadcast={channel:`storage_${this.getStoreName()}`}),i.createEventBus(e)}getStoreName(){return`_${this.config.app}_${this.config.storageKey}_`}setupStorageEventListener(){window.addEventListener("storage",(e=>{if(e.key===this.getStoreName()&&e.newValue)try{const t=JSON.parse(e.newValue);t&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"external",state:t.state,version:t.version,app:t.app}})}catch(e){console.error("Failed to parse storage event data:",e)}}))}set(e,t){try{const i={state:structuredClone(t),version:this.config.version,app:this.config.app},r=JSON.stringify(i);return this.storage.setItem(this.getStoreName(),r),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to persist state to web storage for ${this.config.storageKey}:`,e),!1}}_get(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return null;return JSON.parse(e).state}catch(e){return console.error(`Failed to retrieve state from web storage for ${this.config.storageKey}:`,e),null}}async get(){return this.initialized||await new Promise((e=>{this._onInitialized(e)})),this._get()}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.config.storageKey&&r!==e&&t(s)}))}clear(){try{return this.storage.removeItem(this.getStoreName()),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"clear-initiator",state:null,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear persisted state for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}};
|
package/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createEventBus as e}from"@asaidimu/utils-events";import{DatabaseConnection as t,createIndexedDbStore as i,DatabaseError as r}from"@asaidimu/utils-database";var s,o,n=Object.create,a=Object.defineProperty,c=Object.getOwnPropertyDescriptor,u=Object.getOwnPropertyNames,h=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,d=(s={"node_modules/@asaidimu/query/index.js"(e,t){var i,r=Object.defineProperty,s=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var i in t)r(e,i,{get:t[i],enumerable:!0})})(a,{QueryBuilder:()=>c,createJoiner:()=>y,createMatcher:()=>h,createPaginator:()=>O,createProjector:()=>E,createSorter:()=>b}),t.exports=(i=a,((e,t,i,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))!n.call(e,c)&&c!==i&&r(e,c,{get:()=>t[c],enumerable:!(a=s(t,c))||a.enumerable});return e})(r({},"__esModule",{value:!0}),i));var c=class{query;constructor(){this.query={}}where(e){return this.query.filters=e,this}orderBy(e,t){return this.query.sort||(this.query.sort=[]),this.query.sort.push({field:e,direction:t}),this}offset(e,t){return this.query.pagination={type:"offset",offset:e,limit:t},this}cursor(e,t,i){return this.query.pagination={type:"cursor",cursor:e,limit:t,direction:i},this}include(e){return this.query.projection||(this.query.projection={}),this.query.projection.include=e,this}exclude(e){return this.query.projection||(this.query.projection={}),this.query.projection.exclude=e,this}computed(e,t){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"computed",expression:e,alias:t}),this}case(e,t,i){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"case",conditions:e,else:t,alias:i}),this}join(e,t,i){return this.query.joins||(this.query.joins=[]),this.query.joins.push({relation:e,alias:i,query:t}),this}aggregate(e,t){return this.query.aggregations={groupBy:e,metrics:t},this}window(e){return this.query.window||(this.query.window=[]),this.query.window.push(e),this}hint(e){return this.query.hints||(this.query.hints=[]),this.query.hints.push(e),this}build(){return this.query}};function u(e){function t(e,t){return function(e){return"field"===e?.type}(t)?e[t.field]:function(e){return"value"===e?.type}(t)?t.value:function(e){return"function"===e?.type}(t)?r(t,e):function(e){return"computed"===e?.type}(t)?r(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let i of t.conditions)if(s(e,i.when))return i.then;return t.else}(e,t):t}let i=new Map([["and",(e,t)=>t.every((t=>s(e,t)))],["or",(e,t)=>t.some((t=>s(e,t)))],["not",(e,t)=>!t.every((t=>s(e,t)))],["nor",(e,t)=>!t.some((t=>s(e,t)))],["xor",(e,t)=>1===t.filter((t=>s(e,t))).length]]);function r(i,r){let s=i.arguments.map((e=>t(r,e)));if(e[i.function])return e[i.function](...s);throw new Error(`Function ${i.function} not found!`)}function s(r,s){if(function(e){return!!e&&void 0!==e.conditions}(s))return function(e,t){let{operator:r,conditions:s}=t,o=i.get(r);if(o)return o(e,s);throw new Error(`Unsupported logical operator: ${r}`)}(r,s);if(!s||!s.field)return!1;let{field:o,operator:n,value:a}=s,c=r[o],u=t(r,a),h=new Map([["eq",(e,t)=>e===t],["neq",(e,t)=>e!==t],["lt",(e,t)=>e<t],["lte",(e,t)=>e<=t],["gt",(e,t)=>e>t],["gte",(e,t)=>e>=t],["in",(e,t)=>Array.isArray(t)&&t.includes(e)],["nin",(e,t)=>Array.isArray(t)&&!t.includes(e)],["contains",(e,t)=>"string"==typeof e?e.includes(t):!!Array.isArray(e)&&e.includes(a)],["ncontains",(e,t)=>"string"==typeof e&&!e.includes(t)],["startswith",(e,t)=>"string"==typeof e&&e.startsWith(t)],["endswith",(e,t)=>"string"==typeof e&&e.endsWith(t)],["exists",e=>null!=e],["nexists",e=>null==e]]),l=e[n]||h.get(n);if(l)return l(c,u);throw new Error(`Unsupported comparison operator: ${n}`)}return{resolve:t,evaluate:s}}function h(e){let{evaluate:t}=u(e),i=new WeakMap;function r(e,r){let s=i.get(e);s||(s=new Map,i.set(e,s));let o=JSON.stringify(r);if(s.has(o))return s.get(o);let n=t(e,r);return s.set(o,n),n}return{matcher:r,match:r}}var l=class extends Error{constructor(e,t){super(e),this.code=t,this.name="JoinError"}},d=e=>e&&"field"in e&&"operator"in e&&"value"in e,p=(e,t)=>{if(e){if(d(e)&&e){let i=(e=>"object"==typeof e&&null!==e&&"type"in e&&"field"===e.type)(e.value)?((e,t)=>t.split(".").reduce(((e,t)=>e?.[t]),e))(t,e.value.field):e.value;return{...e,value:i}}if((e=>"operator"in e&&"conditions"in e)(e)){let i={...e};return e.conditions&&(i.conditions=e.conditions.map((e=>p(e,t)))),i}return e}},f=async(e,t,i,r)=>{try{if(((e,t)=>{if(!e.relation)throw new l("Join configuration must specify a relation","INVALID_CONFIG");if(!t[e.relation])throw new l(`Collection "${e.relation}" not found in database`,"COLLECTION_NOT_FOUND");if(e.alias&&"string"!=typeof e.alias)throw new l("Join alias must be a string","INVALID_ALIAS")})(i,e),!Array.isArray(t))throw new l("Source data must be an array","INVALID_SOURCE_DATA");let s,o=e[i.relation];return i.query?.filters&&d(i.query.filters)&&(s=((e,t)=>{let i=new Map;return e.forEach((e=>{let r=e[t];i.has(r)||i.set(r,[]),i.get(r).push(e)})),i})(o,i.query.filters.field)),(await Promise.all(t.map((async e=>{let t,n=((e,t)=>{if(!e)return{};let i=p(e.filters,t);return{...e,filters:i}})(i.query,e);return t=n.filters&&d(n.filters)&&s?.has(n.filters.value)?s.get(n.filters.value)||[]:o.filter((e=>r.matcher(e,n.filters))),((e,t,i)=>{let r=i.alias||i.relation;return[{...e,[r]:t}]})(e,await[e=>n.sort?r.sorter(e,n.sort):e,e=>n.projection?r.projector(e,n.projection):e,async e=>n.pagination?await r.paginator(e,n.pagination):e].reduce((async(e,t)=>t(await e)),Promise.resolve(t)),i)})))).flat()}catch(e){throw e instanceof l?e:new l(`Join operation failed: ${e.message}`,"JOIN_EXECUTION_ERROR")}},g=async(e,t,i,r)=>i.reduce((async(t,i)=>f(e,await t,i,r)),Promise.resolve(t));function y(){return{join:g}}var m=class extends Error{constructor(e,t){super(`Unsupported comparison between ${typeof e} and ${typeof t}`),this.name="UnsupportedComparisonError"}},w=class extends Error{constructor(e){super(`Unsupported sort direction: ${e}`),this.name="InvalidSortDirectionError"}};function v(e,t,i){if(e===t)return 0;if(null==e||null==t)return null==e?"asc"===i?-1:1:"asc"===i?1:-1;if("string"==typeof e&&"string"==typeof t)return"asc"===i?e.localeCompare(t):t.localeCompare(e);if("number"==typeof e&&"number"==typeof t)return"asc"===i?e-t:t-e;throw new m(e,t)}function _(e,t){let i=Array.from(e);return 0===t.length?i:i.sort(((e,i)=>{for(let r of t){let{field:t,direction:s}=r,o=e[t],n=i[t];try{if("asc"!==s&&"desc"!==s)throw new w(s);let e=v(o,n,s);if(0!==e)return e}catch(e){throw e instanceof m||e instanceof w?e:new Error(`Error comparing field '${t}': ${e.message}`)}}return 0}))}function b(){return{sort:_}}function E(e){let{resolve:t}=u(e);function i(e,r){let s={};return r.include?.length&&function(e,t,r){for(let s of t)if("string"!=typeof s){for(let[t,o]of Object.entries(s))if(Object.prototype.hasOwnProperty.call(e,t)){let s=i(e[t],o);r[t]=s}}else{let t=s;r[t]=e[t]}}(e,r.include,s),r.exclude?.length&&function(e,t,r){0===Object.keys(r).length&&Object.assign(r,e);for(let e of t)if("string"!=typeof e)for(let[t,s]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(r,t))continue;let e=r[t];e&&"object"==typeof e?r[t]=i(e,s):delete r[t]}else delete r[e]}(e,r.exclude,s),r.computed?.length&&function(e,i,r){for(let s of i)r[s.alias]=t(e,s)}(e,r.computed,s),s}return{project:i}}async function*S(e,t,i=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:i,limit:r}=t,s=0,o=r,n=[];for await(let t of e)o<=0&&(yield n,n=[],o=r),s<i?s++:(n.push(t),o--);n.length>0&&(yield n)}(e,t):yield*async function*(e,t,i){let{cursor:r,limit:s,direction:o}=t,n=s,a=void 0===r,c=[];if("forward"===o)for await(let t of e)n<=0&&(yield c,c=[],n=s),a?(c.push(t),n--):a=i(t)===r;else{let t=[];for await(let i of e)t.push(i);for(let e=t.length-1;e>=0;e--){let o=t[e];a?(c.push(o),n--,n<=0&&(yield c,c=[],n=s)):a=i(o)===r}}c.length>0&&(yield c)}(e,t,i)}function O(){return{paginate:S}}}},function(){return o||(0,s[u(s)[0]])((o={exports:{}}).exports,o),o.exports}),p=class{eventBus;storage;config;initialized=!1;initializationCallbacks=[];constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}async initialize(){try{const e=this.storage.getItem(this.getStoreName());if(e){const t=JSON.parse(e);if(t.version!==this.config.version&&this.config.onUpgrade){const{state:e}=await this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}initializeEventBus(){const t={errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey}:`,e)};return"undefined"!=typeof process&&"test"===process.env.NODE_ENV||(t.broadcast={channel:`storage_${this.getStoreName()}`}),e(t)}getStoreName(){return`_${this.config.app}_${this.config.storageKey}_`}setupStorageEventListener(){window.addEventListener("storage",(e=>{if(e.key===this.getStoreName()&&e.newValue)try{const t=JSON.parse(e.newValue);t&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"external",state:t.state,version:t.version,app:t.app}})}catch(e){console.error("Failed to parse storage event data:",e)}}))}set(e,t){try{const i={state:structuredClone(t),version:this.config.version,app:this.config.app},r=JSON.stringify(i);return this.storage.setItem(this.getStoreName(),r),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to persist state to web storage for ${this.config.storageKey}:`,e),!1}}_get(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return null;return JSON.parse(e).state}catch(e){return console.error(`Failed to retrieve state from web storage for ${this.config.storageKey}:`,e),null}}async get(){return this.initialized||await new Promise((e=>{this._onInitialized(e)})),this._get()}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.config.storageKey&&r!==e&&t(s)}))}clear(){try{return this.storage.removeItem(this.getStoreName()),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"clear-initiator",state:null,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear persisted state for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}},f=((e,t,i)=>(i=null!=e?n(h(e)):{},((e,t,i,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let s of u(t))l.call(e,s)||s===i||a(e,s,{get:()=>t[s],enumerable:!(r=c(t,s))||r.enumerable});return e})(e&&e.__esModule?i:a(i,"default",{value:e,enumerable:!0}),e)))(d()),g={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},y=new Map;var m=class e extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(t){const i={...function(e){const t=Object.values(g).find((t=>t.code===e));if(t)return t;return y.get(e)||{code:e,name:e.replace(/-/g,"_"),description:`Unknown error: ${e}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(t.code),...t.metadata,code:t.code};super(t.message??i.description),this.name="SystemError",this.code=t.code,this.codeMetadata=i,this.severity=t.severity??"error",this.path=t.path,this.operation=t.operation,this.issues=t.issues??[],this.cause=t.cause,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}withPath(t){return new e({code:this.code,message:this.message,severity:this.severity,path:t,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:t,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,t],cause:this.cause,metadata:this.codeMetadata})}withIssues(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...t],cause:this.cause,metadata:this.codeMetadata})}withCause(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:t,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},w=class e extends m{constructor(t,i){super({code:"SYNC_ERROR",message:t,cause:i}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},v=class e extends w{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},_=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const i=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await i;let r;await Promise.race([i.then((()=>clearTimeout(r))),new Promise(((i,s)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),s(new v("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},b=class{mutex=new _({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,i="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,s)=>{r=setTimeout((()=>s(new v(i))),t)}))])}},E=class{constructor(e,t,i={}){this.factory=e,this.onCleanup=t,this.options=i}_count=0;init=new b({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}},S=class s{static dbResources=new Map;static eventBusMap=new Map;static createDatabaseFactory(e){return async()=>{const{database:s,enableTelemetry:o=!1,collection:n="stores"}=e,a=await t({database:s,enableTelemetry:o},i);try{await a.createCollection({name:n,version:"1.0.0",nestedSchemas:{},fields:{store:{name:"store",type:"string",required:!0},data:{name:"data",type:"object",required:!0},version:{name:"version",type:"string",required:!0},app:{name:"app",type:"string",required:!0}}})}catch(e){if(e instanceof r&&"SCHEMA_ALREADY_EXISTS"!==e.type)throw e}return a}}static createDatabaseCleanup(e){return t=>{t?.close();const i=[];s.eventBusMap.forEach(((t,r)=>{r.startsWith(`${e}_store_`)&&(t.clear(),i.push(r))})),i.forEach((e=>s.eventBusMap.delete(e)))}}static async acquireDatabase(e){const t=e.database;if(!s.dbResources.has(t)){const i=new E(s.createDatabaseFactory(e),s.createDatabaseCleanup(t),{gracePeriod:"microtask"});s.dbResources.set(t,i)}return s.dbResources.get(t).acquire()}static releaseDatabase(e){const t=s.dbResources.get(e);t&&t.release()}static async getCollection(e){const t=await s.acquireDatabase(e),i=e.collection??"stores";return t.collection(i)}static getEventBus(t,i){const r=`${t}_store_${i}`;return s.eventBusMap.has(r)||s.eventBusMap.set(r,e({errorHandler:e=>console.error(`Event bus error for ${t}:${i}:`,e),broadcast:{channel:r}})),s.eventBusMap.get(r)}},O=class{collection=null;collectionPromise;config;eventBus;initialized=!1;_initializing=!1;initializationCallbacks=[];doc=null;getStoreName(){return`_${this.config.app}_${this.config.store}_`}constructor(e){this.config=e,this.collectionPromise=S.getCollection(this.config),this.collectionPromise.then((e=>{this.collection=e,this.initialize()})).catch((e=>{console.error(`Failed to initialize collection for store ${this.getStoreName()}:`,e)})),this.eventBus=S.getEventBus(this.config.database,this.getStoreName()),this.eventBus.subscribe("store:updated",(({storageKey:e})=>{e===this.getStoreName()&&(this.doc=null)}))}async initialize(){this._initializing=!0;try{const e=await this._get();if(e&&e.version!==this.config.version&&this.config.onUpgrade){const{state:t}=await this.config.onUpgrade({data:e.data,version:e.version,app:e.app});await this.set("migration",t)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize and upgrade store ${this.getStoreName()}:`,e)}finally{this._initializing=!1}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}async getCollection(){return this.collection??this.collectionPromise}async set(e,t){this.initialized||this._initializing||await new Promise((e=>this._onInitialized(e)));try{const i=await this.getCollection(),r=await this._read(),s={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let o;return r?o=await r.update(s):(this.doc=await i.create(s),o=!0),o&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:e,state:t,version:this.config.version,app:this.config.app}}),o}catch(t){return console.error(`Failed to set state for store ${this.getStoreName()} in database ${this.config.database} by instance ${e}:`,t),!1}}async _read(){if(this.doc)return this.doc;const e=await this.getCollection(),t=(new f.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build();return this.doc=await e.find(t.filters),this.doc}async _get(){try{const e=await this._read();return e?e.read().then((()=>e)):null}catch(e){return console.error(`Failed to get state for store ${this.getStoreName()} in database ${this.config.database}:`,e),null}}async get(){this.initialized||await new Promise((e=>this._onInitialized(e)));const e=await this._get();return e?e.data:null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.getStoreName()&&r!==e&&t(s)}))}async clear(){this.initialized||await new Promise((e=>this._onInitialized(e)));try{const e=await this._read();return!e||!await e.delete()||(this.doc=null,this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:"",state:null,version:this.config.version,app:this.config.app}}),!0)}catch(e){return console.error(`Failed to clear state for store ${this.getStoreName()} in database ${this.config.database}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}async close(){S.releaseDatabase(this.config.database)}},I=class{eventBus;inMemoryState=null;config;constructor(e){this.config=e,this.eventBus=this.initializeEventBus(),this.setupLwwSynchronizationListener()}initializeEventBus(){const t={errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey} (Ephemeral LWW):`,e)};return"undefined"!=typeof process&&"test"===process.env.NODE_ENV||(t.broadcast={channel:`ephemeral_lww_${this.config.storageKey}`}),e(t)}setupLwwSynchronizationListener(){this.eventBus.subscribe("store:updated",(({storageKey:e,instanceId:t,state:i,timestamp:r,version:s})=>{e===this.config.storageKey&&(!this.inMemoryState||r&&r>this.inMemoryState.timestamp)&&(this.inMemoryState={data:i,timestamp:r,instanceId:t,version:s})}))}set(e,t){try{const i=Date.now();return this.inMemoryState={data:structuredClone(t),timestamp:i,instanceId:e,version:this.config.version},this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,timestamp:i,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to set state in EphemeralPersistence (LWW) for ${this.config.storageKey}:`,e),!1}}get(){return this.inMemoryState?.data??null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.config.storageKey&&r!==e&&t(s)}))}clear(){try{const e=Date.now(),t="clear-initiator";return this.inMemoryState={data:null,timestamp:e,instanceId:t,version:this.config.version},this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:t,state:null,timestamp:e,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear state in EphemeralPersistence (LWW) for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}};export{I as EphemeralPersistence,O as IndexedDBPersistence,p as WebStoragePersistence};
|
|
1
|
+
import{createEventBus as e}from"@asaidimu/utils-events";import{DatabaseConnection as t,createIndexedDbStore as i,DatabaseError as r}from"@asaidimu/utils-database";var s,o,n=Object.create,a=Object.defineProperty,c=Object.getOwnPropertyDescriptor,u=Object.getOwnPropertyNames,h=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,d=(s={"node_modules/@asaidimu/query/index.js"(e,t){var i,r=Object.defineProperty,s=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,n=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var i in t)r(e,i,{get:t[i],enumerable:!0})})(a,{QueryBuilder:()=>c,createJoiner:()=>y,createMatcher:()=>h,createPaginator:()=>O,createProjector:()=>E,createSorter:()=>b}),t.exports=(i=a,((e,t,i,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))!n.call(e,c)&&c!==i&&r(e,c,{get:()=>t[c],enumerable:!(a=s(t,c))||a.enumerable});return e})(r({},"__esModule",{value:!0}),i));var c=class{query;constructor(){this.query={}}where(e){return this.query.filters=e,this}orderBy(e,t){return this.query.sort||(this.query.sort=[]),this.query.sort.push({field:e,direction:t}),this}offset(e,t){return this.query.pagination={type:"offset",offset:e,limit:t},this}cursor(e,t,i){return this.query.pagination={type:"cursor",cursor:e,limit:t,direction:i},this}include(e){return this.query.projection||(this.query.projection={}),this.query.projection.include=e,this}exclude(e){return this.query.projection||(this.query.projection={}),this.query.projection.exclude=e,this}computed(e,t){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"computed",expression:e,alias:t}),this}case(e,t,i){return this.query.projection||(this.query.projection={}),this.query.projection.computed||(this.query.projection.computed=[]),this.query.projection.computed.push({type:"case",conditions:e,else:t,alias:i}),this}join(e,t,i){return this.query.joins||(this.query.joins=[]),this.query.joins.push({relation:e,alias:i,query:t}),this}aggregate(e,t){return this.query.aggregations={groupBy:e,metrics:t},this}window(e){return this.query.window||(this.query.window=[]),this.query.window.push(e),this}hint(e){return this.query.hints||(this.query.hints=[]),this.query.hints.push(e),this}build(){return this.query}};function u(e){function t(e,t){return function(e){return"field"===e?.type}(t)?e[t.field]:function(e){return"value"===e?.type}(t)?t.value:function(e){return"function"===e?.type}(t)?r(t,e):function(e){return"computed"===e?.type}(t)?r(t.expression,e):function(e){return"case"===e?.type}(t)?function(e,t){for(let i of t.conditions)if(s(e,i.when))return i.then;return t.else}(e,t):t}let i=new Map([["and",(e,t)=>t.every((t=>s(e,t)))],["or",(e,t)=>t.some((t=>s(e,t)))],["not",(e,t)=>!t.every((t=>s(e,t)))],["nor",(e,t)=>!t.some((t=>s(e,t)))],["xor",(e,t)=>1===t.filter((t=>s(e,t))).length]]);function r(i,r){let s=i.arguments.map((e=>t(r,e)));if(e[i.function])return e[i.function](...s);throw new Error(`Function ${i.function} not found!`)}function s(r,s){if(function(e){return!!e&&void 0!==e.conditions}(s))return function(e,t){let{operator:r,conditions:s}=t,o=i.get(r);if(o)return o(e,s);throw new Error(`Unsupported logical operator: ${r}`)}(r,s);if(!s||!s.field)return!1;let{field:o,operator:n,value:a}=s,c=r[o],u=t(r,a),h=new Map([["eq",(e,t)=>e===t],["neq",(e,t)=>e!==t],["lt",(e,t)=>e<t],["lte",(e,t)=>e<=t],["gt",(e,t)=>e>t],["gte",(e,t)=>e>=t],["in",(e,t)=>Array.isArray(t)&&t.includes(e)],["nin",(e,t)=>Array.isArray(t)&&!t.includes(e)],["contains",(e,t)=>"string"==typeof e?e.includes(t):!!Array.isArray(e)&&e.includes(a)],["ncontains",(e,t)=>"string"==typeof e&&!e.includes(t)],["startswith",(e,t)=>"string"==typeof e&&e.startsWith(t)],["endswith",(e,t)=>"string"==typeof e&&e.endsWith(t)],["exists",e=>null!=e],["nexists",e=>null==e]]),l=e[n]||h.get(n);if(l)return l(c,u);throw new Error(`Unsupported comparison operator: ${n}`)}return{resolve:t,evaluate:s}}function h(e){let{evaluate:t}=u(e),i=new WeakMap;function r(e,r){let s=i.get(e);s||(s=new Map,i.set(e,s));let o=JSON.stringify(r);if(s.has(o))return s.get(o);let n=t(e,r);return s.set(o,n),n}return{matcher:r,match:r}}var l=class extends Error{constructor(e,t){super(e),this.code=t,this.name="JoinError"}},d=e=>e&&"field"in e&&"operator"in e&&"value"in e,p=(e,t)=>{if(e){if(d(e)&&e){let i=(e=>"object"==typeof e&&null!==e&&"type"in e&&"field"===e.type)(e.value)?((e,t)=>t.split(".").reduce(((e,t)=>e?.[t]),e))(t,e.value.field):e.value;return{...e,value:i}}if((e=>"operator"in e&&"conditions"in e)(e)){let i={...e};return e.conditions&&(i.conditions=e.conditions.map((e=>p(e,t)))),i}return e}},f=async(e,t,i,r)=>{try{if(((e,t)=>{if(!e.relation)throw new l("Join configuration must specify a relation","INVALID_CONFIG");if(!t[e.relation])throw new l(`Collection "${e.relation}" not found in database`,"COLLECTION_NOT_FOUND");if(e.alias&&"string"!=typeof e.alias)throw new l("Join alias must be a string","INVALID_ALIAS")})(i,e),!Array.isArray(t))throw new l("Source data must be an array","INVALID_SOURCE_DATA");let s,o=e[i.relation];return i.query?.filters&&d(i.query.filters)&&(s=((e,t)=>{let i=new Map;return e.forEach((e=>{let r=e[t];i.has(r)||i.set(r,[]),i.get(r).push(e)})),i})(o,i.query.filters.field)),(await Promise.all(t.map((async e=>{let t,n=((e,t)=>{if(!e)return{};let i=p(e.filters,t);return{...e,filters:i}})(i.query,e);return t=n.filters&&d(n.filters)&&s?.has(n.filters.value)?s.get(n.filters.value)||[]:o.filter((e=>r.matcher(e,n.filters))),((e,t,i)=>{let r=i.alias||i.relation;return[{...e,[r]:t}]})(e,await[e=>n.sort?r.sorter(e,n.sort):e,e=>n.projection?r.projector(e,n.projection):e,async e=>n.pagination?await r.paginator(e,n.pagination):e].reduce((async(e,t)=>t(await e)),Promise.resolve(t)),i)})))).flat()}catch(e){throw e instanceof l?e:new l(`Join operation failed: ${e.message}`,"JOIN_EXECUTION_ERROR")}},g=async(e,t,i,r)=>i.reduce((async(t,i)=>f(e,await t,i,r)),Promise.resolve(t));function y(){return{join:g}}var m=class extends Error{constructor(e,t){super(`Unsupported comparison between ${typeof e} and ${typeof t}`),this.name="UnsupportedComparisonError"}},w=class extends Error{constructor(e){super(`Unsupported sort direction: ${e}`),this.name="InvalidSortDirectionError"}};function v(e,t,i){if(e===t)return 0;if(null==e||null==t)return null==e?"asc"===i?-1:1:"asc"===i?1:-1;if("string"==typeof e&&"string"==typeof t)return"asc"===i?e.localeCompare(t):t.localeCompare(e);if("number"==typeof e&&"number"==typeof t)return"asc"===i?e-t:t-e;throw new m(e,t)}function _(e,t){let i=Array.from(e);return 0===t.length?i:i.sort(((e,i)=>{for(let r of t){let{field:t,direction:s}=r,o=e[t],n=i[t];try{if("asc"!==s&&"desc"!==s)throw new w(s);let e=v(o,n,s);if(0!==e)return e}catch(e){throw e instanceof m||e instanceof w?e:new Error(`Error comparing field '${t}': ${e.message}`)}}return 0}))}function b(){return{sort:_}}function E(e){let{resolve:t}=u(e);function i(e,r){let s={};return r.include?.length&&function(e,t,r){for(let s of t)if("string"!=typeof s){for(let[t,o]of Object.entries(s))if(Object.prototype.hasOwnProperty.call(e,t)){let s=i(e[t],o);r[t]=s}}else{let t=s;r[t]=e[t]}}(e,r.include,s),r.exclude?.length&&function(e,t,r){0===Object.keys(r).length&&Object.assign(r,e);for(let e of t)if("string"!=typeof e)for(let[t,s]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(r,t))continue;let e=r[t];e&&"object"==typeof e?r[t]=i(e,s):delete r[t]}else delete r[e]}(e,r.exclude,s),r.computed?.length&&function(e,i,r){for(let s of i)r[s.alias]=t(e,s)}(e,r.computed,s),s}return{project:i}}async function*S(e,t,i=e=>String(e)){"offset"===t.type?yield*async function*(e,t){let{offset:i,limit:r}=t,s=0,o=r,n=[];for await(let t of e)o<=0&&(yield n,n=[],o=r),s<i?s++:(n.push(t),o--);n.length>0&&(yield n)}(e,t):yield*async function*(e,t,i){let{cursor:r,limit:s,direction:o}=t,n=s,a=void 0===r,c=[];if("forward"===o)for await(let t of e)n<=0&&(yield c,c=[],n=s),a?(c.push(t),n--):a=i(t)===r;else{let t=[];for await(let i of e)t.push(i);for(let e=t.length-1;e>=0;e--){let o=t[e];a?(c.push(o),n--,n<=0&&(yield c,c=[],n=s)):a=i(o)===r}}c.length>0&&(yield c)}(e,t,i)}function O(){return{paginate:S}}}},function(){return o||(0,s[u(s)[0]])((o={exports:{}}).exports,o),o.exports}),p=class{eventBus;storage;config;initialized=!1;initializationCallbacks=[];constructor(e){this.config=e,this.storage=e.session?sessionStorage:localStorage,this.eventBus=this.initializeEventBus(),this.initialize(),e.session||this.setupStorageEventListener()}async initialize(){try{const e=this.storage.getItem(this.getStoreName());if(e){const t=JSON.parse(e);if(t.version!==this.config.version&&this.config.onUpgrade){const{state:e}=await this.config.onUpgrade({data:t.state,version:t.version,app:t.app});this.set("migration",e)}}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize WebStoragePersistence for ${this.config.storageKey}:`,e)}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}initializeEventBus(){const t={batch:{size:0,delay:0},errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey}:`,e)};return"undefined"!=typeof process&&"test"===process.env.NODE_ENV||(t.broadcast={channel:`storage_${this.getStoreName()}`}),e(t)}getStoreName(){return`_${this.config.app}_${this.config.storageKey}_`}setupStorageEventListener(){window.addEventListener("storage",(e=>{if(e.key===this.getStoreName()&&e.newValue)try{const t=JSON.parse(e.newValue);t&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"external",state:t.state,version:t.version,app:t.app}})}catch(e){console.error("Failed to parse storage event data:",e)}}))}set(e,t){try{const i={state:structuredClone(t),version:this.config.version,app:this.config.app},r=JSON.stringify(i);return this.storage.setItem(this.getStoreName(),r),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to persist state to web storage for ${this.config.storageKey}:`,e),!1}}_get(){try{const e=this.storage.getItem(this.getStoreName());if(!e)return null;return JSON.parse(e).state}catch(e){return console.error(`Failed to retrieve state from web storage for ${this.config.storageKey}:`,e),null}}async get(){return this.initialized||await new Promise((e=>{this._onInitialized(e)})),this._get()}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.config.storageKey&&r!==e&&t(s)}))}clear(){try{return this.storage.removeItem(this.getStoreName()),this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:"clear-initiator",state:null,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear persisted state for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}},f=((e,t,i)=>(i=null!=e?n(h(e)):{},((e,t,i,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let s of u(t))l.call(e,s)||s===i||a(e,s,{get:()=>t[s],enumerable:!(r=c(t,s))||r.enumerable});return e})(e&&e.__esModule?i:a(i,"default",{value:e,enumerable:!0}),e)))(d()),g={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},y=new Map;var m=class e extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(t){const i={...function(e){const t=Object.values(g).find((t=>t.code===e));if(t)return t;return y.get(e)||{code:e,name:e.replace(/-/g,"_"),description:`Unknown error: ${e}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(t.code),...t.metadata,code:t.code};super(t.message??i.description),this.name="SystemError",this.code=t.code,this.codeMetadata=i,this.severity=t.severity??"error",this.path=t.path,this.operation=t.operation,this.issues=t.issues??[],this.cause=t.cause,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}withPath(t){return new e({code:this.code,message:this.message,severity:this.severity,path:t,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:t,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,t],cause:this.cause,metadata:this.codeMetadata})}withIssues(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...t],cause:this.cause,metadata:this.codeMetadata})}withCause(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:t,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},w=class e extends m{constructor(t,i){super({code:"SYNC_ERROR",message:t,cause:i}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},v=class e extends w{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},_=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const i=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await i;let r;await Promise.race([i.then((()=>clearTimeout(r))),new Promise(((i,s)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),s(new v("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},b=class{mutex=new _({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}resolve(e){if(this._done)throw new Error("Cannot resolve: operation is already completed.");if(this.running())throw new Error("Cannot resolve: operation is currently running.");this._value=e,this._done=!0}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,i="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,s)=>{r=setTimeout((()=>s(new v(i))),t)}))])}},E=class{constructor(e,t,i={}){this.factory=e,this.onCleanup=t,this.options=i}_count=0;init=new b({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}},S=class s{static dbResources=new Map;static eventBusMap=new Map;static createDatabaseFactory(e){return async()=>{const{database:s,enableTelemetry:o=!1,collection:n="stores"}=e,a=await t({database:s,enableTelemetry:o},i);try{await a.createCollection({name:n,version:"1.0.0",nestedSchemas:{},fields:{store:{name:"store",type:"string",required:!0},data:{name:"data",type:"object",required:!0},version:{name:"version",type:"string",required:!0},app:{name:"app",type:"string",required:!0}}})}catch(e){if(e instanceof r&&"SCHEMA_ALREADY_EXISTS"!==e.type)throw e}return a}}static createDatabaseCleanup(e){return t=>{t?.close();const i=[];s.eventBusMap.forEach(((t,r)=>{r.startsWith(`${e}_store_`)&&(t.clear(),i.push(r))})),i.forEach((e=>s.eventBusMap.delete(e)))}}static async acquireDatabase(e){const t=e.database;if(!s.dbResources.has(t)){const i=new E(s.createDatabaseFactory(e),s.createDatabaseCleanup(t),{gracePeriod:"microtask"});s.dbResources.set(t,i)}return s.dbResources.get(t).acquire()}static releaseDatabase(e){const t=s.dbResources.get(e);t&&t.release()}static async getCollection(e){const t=await s.acquireDatabase(e),i=e.collection??"stores";return t.collection(i)}static getEventBus(t,i){const r=`${t}_store_${i}`;return s.eventBusMap.has(r)||s.eventBusMap.set(r,e({errorHandler:e=>console.error(`Event bus error for ${t}:${i}:`,e),broadcast:{channel:r}})),s.eventBusMap.get(r)}},O=class{collection=null;collectionPromise;config;eventBus;initialized=!1;_initializing=!1;initializationCallbacks=[];doc=null;getStoreName(){return`_${this.config.app}_${this.config.store}_`}constructor(e){this.config=e,this.collectionPromise=S.getCollection(this.config),this.collectionPromise.then((e=>{this.collection=e,this.initialize()})).catch((e=>{console.error(`Failed to initialize collection for store ${this.getStoreName()}:`,e)})),this.eventBus=S.getEventBus(this.config.database,this.getStoreName()),this.eventBus.subscribe("store:updated",(({storageKey:e})=>{e===this.getStoreName()&&(this.doc=null)}))}async initialize(){this._initializing=!0;try{const e=await this._get();if(e&&e.version!==this.config.version&&this.config.onUpgrade){const{state:t}=await this.config.onUpgrade({data:e.data,version:e.version,app:e.app});await this.set("migration",t)}this.initialized=!0,this.initializationCallbacks.forEach((e=>e())),this.initializationCallbacks=[]}catch(e){console.error(`Failed to initialize and upgrade store ${this.getStoreName()}:`,e)}finally{this._initializing=!1}}_onInitialized(e){this.initialized?e():this.initializationCallbacks.push(e)}async getCollection(){return this.collection??this.collectionPromise}async set(e,t){this.initialized||this._initializing||await new Promise((e=>this._onInitialized(e)));try{const i=await this.getCollection(),r=await this._read(),s={store:this.getStoreName(),data:t,version:this.config.version,app:this.config.app};let o;return r?o=await r.update(s):(this.doc=await i.create(s),o=!0),o&&this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:e,state:t,version:this.config.version,app:this.config.app}}),o}catch(t){return console.error(`Failed to set state for store ${this.getStoreName()} in database ${this.config.database} by instance ${e}:`,t),!1}}async _read(){if(this.doc)return this.doc;const e=await this.getCollection(),t=(new f.QueryBuilder).where({field:"store",operator:"eq",value:this.getStoreName()}).build();return this.doc=await e.find(t.filters),this.doc}async _get(){try{const e=await this._read();return e?e.read().then((()=>e)):null}catch(e){return console.error(`Failed to get state for store ${this.getStoreName()} in database ${this.config.database}:`,e),null}}async get(){this.initialized||await new Promise((e=>this._onInitialized(e)));const e=await this._get();return e?e.data:null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.getStoreName()&&r!==e&&t(s)}))}async clear(){this.initialized||await new Promise((e=>this._onInitialized(e)));try{const e=await this._read();return!e||!await e.delete()||(this.doc=null,this.eventBus.emit({name:"store:updated",payload:{storageKey:this.getStoreName(),instanceId:"",state:null,version:this.config.version,app:this.config.app}}),!0)}catch(e){return console.error(`Failed to clear state for store ${this.getStoreName()} in database ${this.config.database}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}async close(){S.releaseDatabase(this.config.database)}},I=class{eventBus;inMemoryState=null;config;constructor(e){this.config=e,this.eventBus=this.initializeEventBus(),this.setupLwwSynchronizationListener()}initializeEventBus(){const t={errorHandler:e=>console.error(`Event bus error for ${this.config.storageKey} (Ephemeral LWW):`,e)};return"undefined"!=typeof process&&"test"===process.env.NODE_ENV||(t.broadcast={channel:`ephemeral_lww_${this.config.storageKey}`}),e(t)}setupLwwSynchronizationListener(){this.eventBus.subscribe("store:updated",(({storageKey:e,instanceId:t,state:i,timestamp:r,version:s})=>{e===this.config.storageKey&&(!this.inMemoryState||r&&r>this.inMemoryState.timestamp)&&(this.inMemoryState={data:i,timestamp:r,instanceId:t,version:s})}))}set(e,t){try{const i=Date.now();return this.inMemoryState={data:structuredClone(t),timestamp:i,instanceId:e,version:this.config.version},this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:e,state:t,timestamp:i,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to set state in EphemeralPersistence (LWW) for ${this.config.storageKey}:`,e),!1}}get(){return this.inMemoryState?.data??null}subscribe(e,t){return this.eventBus.subscribe("store:updated",(({storageKey:i,instanceId:r,state:s})=>{i===this.config.storageKey&&r!==e&&t(s)}))}clear(){try{const e=Date.now(),t="clear-initiator";return this.inMemoryState={data:null,timestamp:e,instanceId:t,version:this.config.version},this.eventBus.emit({name:"store:updated",payload:{storageKey:this.config.storageKey,instanceId:t,state:null,timestamp:e,version:this.config.version,app:this.config.app}}),!0}catch(e){return console.error(`Failed to clear state in EphemeralPersistence (LWW) for ${this.config.storageKey}:`,e),!1}}stats(){return{version:this.config.version,id:this.config.app}}};export{I as EphemeralPersistence,O as IndexedDBPersistence,p as WebStoragePersistence};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asaidimu/utils-persistence",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.9",
|
|
4
4
|
"description": "Persistence utilities.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@asaidimu/indexed": "^3.0.1",
|
|
33
33
|
"@asaidimu/query": "^1.1.2",
|
|
34
|
-
"@asaidimu/utils-database": "^3.1.
|
|
34
|
+
"@asaidimu/utils-database": "^3.1.7",
|
|
35
35
|
"@asaidimu/utils-events": "^1.0.0",
|
|
36
|
-
"uuid": "^
|
|
36
|
+
"uuid": "^14.0.0"
|
|
37
37
|
},
|
|
38
38
|
"exports": {
|
|
39
39
|
".": {
|