@asaidimu/utils-store 9.0.0 → 9.0.1

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.d.mts CHANGED
@@ -493,6 +493,18 @@ interface DataStore<T extends object> {
493
493
  * Checks whether the store is fully initialized and ready for use.
494
494
  */
495
495
  isReady(): boolean;
496
+ /**
497
+ * Returns a promise that resolves once the store is fully initialised.
498
+ * Safe to call multiple times — all callers share the same latch.
499
+ *
500
+ * @param timeout - Optional maximum wait time in milliseconds.
501
+ * @throws {TimeoutError} If the store does not become ready within the timeout.
502
+ *
503
+ * @example
504
+ * await store.ready();
505
+ * const state = store.get();
506
+ */
507
+ ready(timeout?: number): Promise<void>;
496
508
  /**
497
509
  * Returns a readonly snapshot of the current execution state of the store.
498
510
  */
package/index.d.ts CHANGED
@@ -493,6 +493,18 @@ interface DataStore<T extends object> {
493
493
  * Checks whether the store is fully initialized and ready for use.
494
494
  */
495
495
  isReady(): boolean;
496
+ /**
497
+ * Returns a promise that resolves once the store is fully initialised.
498
+ * Safe to call multiple times — all callers share the same latch.
499
+ *
500
+ * @param timeout - Optional maximum wait time in milliseconds.
501
+ * @throws {TimeoutError} If the store does not become ready within the timeout.
502
+ *
503
+ * @example
504
+ * await store.ready();
505
+ * const state = store.get();
506
+ */
507
+ ready(timeout?: number): Promise<void>;
496
508
  /**
497
509
  * Returns a readonly snapshot of the current execution state of the store.
498
510
  */
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("uuid"),t=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},s=class extends t{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},i=class extends t{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},r=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,a)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),a(new s("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}},a=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new r({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new i};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new i;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},n=class{_open=!1;_resolve;_promise;constructor(){this._promise=new Promise((e=>{this._resolve=e}))}open(){this._open||(this._open=!0,this._resolve())}async wait(e){if(this._open)return;if(null==e)return this._promise;let t;await Promise.race([this._promise.then((()=>clearTimeout(t))),new Promise(((i,r)=>{t=setTimeout((()=>r(new s("Latch timed out"))),e)}))])}isOpen(){return this._open}},o=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise((t=>{this._enqueue(e,t)}))}fire(e){this._enqueue(e,void 0)}_enqueue(e,t){if(this._pendingFn=e,t&&this._pendingResolvers.push(t),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout((()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()}),this._delay));clearTimeout(this._timer),this._timer=setTimeout((()=>{this._leadingFired=!1,this._fire()}),this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const t of e)t({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,t=this._pendingResolvers.splice(0);let s;this._pendingFn=void 0;try{s={status:"ok",value:await e()}}catch(e){s={status:"error",error:e}}for(const e of t)e(s);return s}};function c(e){const t=e??{},{deferred:s,batchSize:i,batchDelay:r,errorHandler:a,broadcast:n,channel:c}={deferred:null!=t.batch?.size,batchSize:t.batch?.size,batchDelay:t.batch?.delay||16,errorHandler:t.errorHandler||(e=>console.error("EventBus Error:",e)),broadcast:null!=t.broadcast?.channel&&t.broadcast.channel.length>0,channel:null!=t.broadcast?.channel&&t.broadcast.channel.length>0?t.broadcast?.channel:"event-bus-channel"},d=new Map;let l=[],h=0,u=0;const p=new Map,m=()=>{if(!n)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(c);return e.onmessage=e=>{const{name:t,payload:s}=e.data;f(t,s)},e};let g=m();const y=(e,t)=>{h++,u+=t,p.set(e,(p.get(e)??0)+1)},f=(e,t)=>{const s=d.get(e);if(s&&0!==s.size)for(const i of Array.from(s))try{i(t)}catch(s){const i=s instanceof Error?s:Object.assign(new Error(String(s)),{cause:s}),r=Object.assign(i,{eventName:e,payload:t});a(r)}},w=()=>{const e=l;l=[];for(const{name:t,payload:s}of e){const e=performance.now();f(t,s),y(t,performance.now()-e)}},v=new o({delay:r});return{subscribe:(e,t)=>{d.has(e)||d.set(e,new Set);const s=d.get(e);return s.add(t),()=>{s.delete(t),0===s.size&&d.delete(e)}},once:(e,t)=>{let s;const i=e=>{s(),t(e)};return s=(()=>{d.has(e)||d.set(e,new Set);const t=d.get(e);return t.add(i),()=>{t.delete(i),0===t.size&&d.delete(e)}})(),s},emit:({name:e,payload:t})=>{if(s)return l.push({name:e,payload:t}),l.length>=i?(v.cancel(),void w()):(v.fire((()=>w())),void g?.postMessage({name:e,payload:t}));const r=performance.now();f(e,t),y(e,performance.now()-r),g?.postMessage({name:e,payload:t})},metrics:()=>({totalEvents:h,activeSubscriptions:Array.from(d.values()).reduce(((e,t)=>e+t.size),0),eventCounts:p,averageEmitDuration:h>0?u/h:0}),clear:()=>{d.clear(),l=[],v.cancel(),h=0,u=0,p.clear(),g?.close(),g=m()}}}var d=Symbol.for("delete"),l=e=>Array.isArray(e)?[...e]:{...e};function h(e){const t=e?.deleteMarker||d;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const i={};for(const[r,a]of Object.entries(e))if(a!==t)if("object"==typeof a&&null!==a){const e=s(a);void 0!==e&&(i[r]=e)}else i[r]=a;return i}return e===t?void 0:e}return function(e,i){if("object"!=typeof e||null===e)return"object"==typeof i&&null!==i?s(i):i===t?{}:i;if("object"!=typeof i||null===i)return e;const r=l(e),a=[{target:r,source:i}];for(;a.length>0;){const{target:e,source:s}=a.pop();for(const i of Object.keys(s)){const r=s[i];if(r!==t)if(Array.isArray(r))e[i]=r;else if("object"==typeof r&&null!==r){const t=i in e&&"object"==typeof e[i]&&null!==e[i]?e[i]:{};e[i]=l(t),a.push({target:e[i],source:r})}else e[i]=r;else delete e[i]}}return r}}var u=h(),p=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"],m=class{reactiveSelectors=new Map;reactiveSelectorCache=new WeakMap;pathBasedCache=new Map;dependencyMap=new Map;getState;eventBus;unsubscribeFromStore;constructor(e,t){this.getState=e,this.eventBus=t,this.unsubscribeFromStore=this.eventBus.subscribe("update:complete",this.handleStoreUpdate)}handleStoreUpdate=e=>{const t=new Set;for(const s of e.deltas){const e=s.path;for(const[s,i]of this.dependencyMap)if(s===e||s.startsWith(e+".")||e.startsWith(s+"."))for(const e of i)t.add(e)}t.forEach((e=>{const t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}))};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}t!==e.lastResult&&(e.lastResult=t,e.subscribers.forEach((e=>e(t))),this.eventBus.emit({name:"selector:changed",payload:{selectorId:e.id,newResult:t,timestamp:performance.now()}}))}createReactiveSelector(e){const t=this.reactiveSelectorCache.get(e);if(t)return t;const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const a=new Proxy((()=>{}),{get:(i,a)=>{if("symbol"==typeof a||"then"===a)return;if("valueOf"===a||"toString"===a)throw new Error("Cannot perform logic/math/string operations inside a selector.");if(p.includes(a))throw new Error(`Array method .${a}() is not allowed in selectors.`);const n=e?`${e}${t}${a}`:a;return e&&s.delete(e),s.add(n),r(n)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions/methods.")}});return i.set(e,a),a};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. This usually means the selector is too complex. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e),i=`${[...s].sort().join("|")}::${e.toString()}`,r=this.pathBasedCache.get(i);if(r)return this.reactiveSelectorCache.set(e,r),r;const a=`sel-${Math.random().toString(36).slice(2,9)}`,n=e(this.getState()),o={id:a,selector:e,lastResult:n,accessedPaths:s,subscribers:new Set,reactiveSelectorInstance:null};s.forEach((e=>{this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(a)}));const c={get:()=>o.lastResult,id:a,subscribe:t=>(o.subscribers.add(t),()=>{o.subscribers.delete(t),0===o.subscribers.size&&this.cleanupSelector(a,e,i)})};return o.reactiveSelectorInstance=c,this.reactiveSelectors.set(a,o),this.reactiveSelectorCache.set(e,c),this.pathBasedCache.set(i,c),this.eventBus.emit({name:"selector:accessed",payload:{selectorId:a,accessedPaths:s,duration:0,timestamp:performance.now()}}),c}cleanupSelector(e,t,s){const i=this.reactiveSelectors.get(e);i&&(i.accessedPaths.forEach((t=>{this.dependencyMap.get(t)?.delete(e),0===this.dependencyMap.get(t)?.size&&this.dependencyMap.delete(t)})),this.reactiveSelectors.delete(e),this.reactiveSelectorCache.delete(t),this.pathBasedCache.delete(s))}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function g(e,t){if(e===t)return!0;if(e&&t&&"object"==typeof e&&"object"==typeof t){if(e.constructor!==t.constructor)return!1;let s,i;if(Array.isArray(e)){if(s=e.length,s!=t.length)return!1;for(i=s;i-- >0;)if(!g(e[i],t[i]))return!1;return!0}const[r,a]=[Object.keys(e),Object.keys(t)];if(s=r.length,s!==a.length)return!1;for(i=s;i-- >0;){const s=r[i];if(!Object.prototype.hasOwnProperty.call(t,s)||!g(e[s],t[s]))return!1}return!0}return e!=e&&t!=t}function y(e){const t=e?.deleteMarker||d;return function(e,s){const i=[],r=[{pathStr:"",orig:e||{},part:s||{}}];for(;r.length>0;){const{pathStr:e,orig:s,part:a}=r.pop();if(null!=a&&!g(s,a))if("object"!=typeof a||Array.isArray(a))e&&i.push({path:e,oldValue:s,newValue:a});else for(const n of Object.keys(a)){const o=e?e+"."+n:n,c=a[n],d=s&&"object"==typeof s?s[n]:void 0;c!==t?"object"==typeof c&&null!==c?r.push({pathStr:o,orig:d,part:c}):g(d,c)||i.push({path:o,oldValue:d,newValue:c}):void 0!==d&&i.push({path:o,oldValue:d,newValue:void 0})}}return i}}function f(e){const t=e?.deleteMarker||d;return function(e){const s=new Set,i=[{obj:e,currentPath:""}];for(;i.length>0;){const{obj:e,currentPath:r}=i.pop();if(null!=e&&"object"==typeof e&&!Array.isArray(e))for(const a of Object.keys(e)){const n=r?`${r}.${a}`:a;s.add(n);const o=e[a];"object"!=typeof o||null===o||Array.isArray(o)||o===t||i.push({obj:o,currentPath:n})}}return Array.from(s)}}var w=y(),v=f(),b=class{constructor(e,t,s){this.updateBus=t,this.diff=s,this.cache=structuredClone(e)}cache;get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,s=!1,i=[]){if(t)return this.cache=s?structuredClone(e):e,this.notifyListeners([]),[];0===i.length&&(i=[e]);const r=this.get(!1),a=new Map;for(let e=0;e<i.length;e++){const t=i[e],s=this.diff(r,t);for(let e=0;e<s.length;e++){const t=s[e];a.set(t.path,t)}}const n=a.size?[...a.values()]:[];if(n.length>0){this.cache=s?structuredClone(e):e;const t=new Set;for(let e=0;e<n.length;e++){let s=n[e].path;for(;s&&!t.has(s);){t.add(s);const e=s.lastIndexOf(".");if(e<0)break;s=s.slice(0,e)}}this.notifyListeners(t)}return n}notifyListeners(e){for(const t of e)this.updateBus.emit({name:"update",payload:t})}},S=class{constructor(e,t,s){this.eventBus=e,this.executionState=t,this.merge=s}middleware=[];blockingMiddleware=[];async executeBlocking(e,t){for(const{fn:s,name:i,id:r}of this.blockingMiddleware){const a={id:r,name:i,startTime:performance.now()};this.executionState.runningMiddleware={id:r,name:i,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:r,name:i,type:"blocking"});try{const n=await Promise.resolve(s(e,t));if(a.endTime=performance.now(),a.duration=a.endTime-a.startTime,!1===n)return a.blocked=!0,this.emitMiddlewareLifecycle("blocked",{id:r,name:i,duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0};this.emitMiddlewareLifecycle("complete",{id:r,name:i,type:"blocking",duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:{...a,blocked:!1}})}catch(e){return a.endTime=performance.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:new Error(String(e)),a.blocked=!0,this.emitMiddlewareError(r,i,a.error,a.duration),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0,error:a.error}}finally{this.executionState.runningMiddleware=null}}return{blocked:!1}}async executeTransform(e,t){let s=e,i=t;for(const{fn:e,name:r,id:a}of this.middleware){const n={id:a,name:r,startTime:performance.now()};this.executionState.runningMiddleware={id:a,name:r,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:a,name:r,type:"transform"});try{const o=await Promise.resolve(e(s,t));n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.blocked=!1,o&&"object"==typeof o&&(s=this.merge(s,o),i=this.merge(i,o)),this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareLifecycle("complete",{id:a,name:r,type:"transform",duration:n.duration})}catch(e){n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.error=e instanceof Error?e:new Error(String(e)),n.blocked=!1,this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareError(a,r,n.error,n.duration),console.error(`Middleware ${r} error:`,e)}finally{this.executionState.runningMiddleware=null}}return i}addMiddleware(e,t="unnamed-middleware"){const s=this.generateId();return this.middleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}addBlockingMiddleware(e,t="unnamed-blocking-middleware"){const s=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}removeMiddleware(e){const t=this.middleware.length+this.blockingMiddleware.length;return this.middleware=this.middleware.filter((t=>t.id!==e)),this.blockingMiddleware=this.blockingMiddleware.filter((t=>t.id!==e)),this.updateExecutionState(),this.middleware.length+this.blockingMiddleware.length<t}updateExecutionState(){this.executionState.middlewares=[...this.middleware.map((e=>e.name)),...this.blockingMiddleware.map((e=>e.name))]}emitMiddlewareLifecycle(e,t){this.emit(this.eventBus,{name:`middleware:${e}`,payload:{...t,timestamp:Date.now()}})}emitMiddlewareError(e,t,s,i){this.emit(this.eventBus,{name:"middleware:error",payload:{id:e,name:t,error:s,duration:i,timestamp:Date.now()}})}generateId(){return crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).substring(2,15)}`}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},x=class{constructor(e,t,s,i){this.eventBus=e,this.coreState=t,this.instanceID=s,this.maxRetries=i?.maxRetries??3,this.retryDelay=i?.retryDelay??1e3}persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||0===e.length)return;const s={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(s),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:"persistence:queued",payload:{taskId:s.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:s.timestamp}})}getQueueStatus(){return{queueSize:this.backgroundQueue.length,isProcessing:this.isProcessingQueue,pendingRetries:this.pendingRetries.size,oldestTask:this.backgroundQueue[0]?.timestamp}}async flush(){this.isProcessingQueue&&await new Promise((e=>{const t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()})),await this.processQueue()}discardQueue(){const e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&(clearTimeout(this.queueProcessor),this.queueProcessor=void 0),this.emit(this.eventBus,{name:"persistence:queue_cleared",payload:{clearedTasks:e,timestamp:Date.now()}})}scheduleQueueProcessing(){this.queueProcessor||this.isProcessingQueue||(this.queueProcessor=setTimeout((()=>{this.processQueue().catch((e=>{console.error("Queue processing failed:",e)}))}),10))}async processQueue(){if(!this.isProcessingQueue&&0!==this.backgroundQueue.length){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){const e=this.backgroundQueue.shift();await this.processTask(e)}}finally{this.isProcessingQueue=!1}}}async processTask(e){try{await this.persistence.set(this.instanceID,e.state)?this.emit(this.eventBus,{name:"persistence:success",payload:{taskId:e.id,changedPaths:e.changedPaths,duration:Date.now()-e.timestamp,timestamp:Date.now()}}):await this.handleTaskFailure(e,new Error("Persistence returned false"))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){const s=this.retryDelay*Math.pow(2,e.retries-1);this.emit(this.eventBus,{name:"persistence:retry",payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:s,error:t,timestamp:Date.now()}}),this.pendingRetries.add(e.id),setTimeout((()=>{this.pendingRetries.has(e.id)&&(this.pendingRetries.delete(e.id),this.backgroundQueue.unshift(e),this.scheduleQueueProcessing())}),s)}else this.emit(this.eventBus,{name:"persistence:failed",payload:{taskId:e.id,changedPaths:e.changedPaths,attempts:e.retries,error:t,timestamp:Date.now()}})}setPersistenceReady(){this.persistenceReady=!0,this.emit(this.eventBus,{name:"persistence:ready",payload:{timestamp:Date.now()}})}async setPersistence(e){this.persistence=e;try{const e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){console.error("Failed to initialize persistence:",e),this.emit(this.eventBus,{name:"persistence:init_error",payload:{error:e,timestamp:Date.now()}})}finally{this.setPersistenceReady()}this.persistence.subscribe(this.instanceID,(async e=>{const t=this.coreState.applyChanges(e);t.length>0&&this.emit(this.eventBus,{name:"update:complete",payload:{changedPaths:t,source:"external",timestamp:Date.now()}})}))}dispose(){this.discardQueue(),this.isProcessingQueue=!1,this.persistenceReady=!1}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},E=class{constructor(e,t,s){this.eventBus=e,this.coreState=t,this.executionState=s}async execute(e){const t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:"transaction:start",payload:{timestamp:Date.now()}});try{const t=await Promise.resolve(e());return this.emit(this.eventBus,{name:"transaction:complete",payload:{timestamp:Date.now()}}),this.executionState.transactionActive=!1,t}catch(e){throw this.coreState.applyChanges(t,!0,!1),this.emit(this.eventBus,{name:"transaction:error",payload:{error:e instanceof Error?e:new Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},_=class{updateCount=0;listenerExecutions=0;averageUpdateTime=0;largestUpdateSize=0;mostActiveListenerPaths=[];totalUpdates=0;blockedUpdates=0;averageUpdateDuration=0;middlewareExecutions=0;transactionCount=0;totalEventsFired=0;totalActionsDispatched=0;totalActionsSucceeded=0;totalActionsFailed=0;averageActionDuration=0;updateTimes=[];actionTimes=[];pathExecutionCounts=new Map;constructor(e){this.setupEventListeners(e)}getMetrics(){return{updateCount:this.updateCount,listenerExecutions:this.listenerExecutions,averageUpdateTime:this.averageUpdateTime,largestUpdateSize:this.largestUpdateSize,mostActiveListenerPaths:[...this.mostActiveListenerPaths],totalUpdates:this.totalUpdates,blockedUpdates:this.blockedUpdates,averageUpdateDuration:this.averageUpdateDuration,middlewareExecutions:this.middlewareExecutions,transactionCount:this.transactionCount,totalEventsFired:this.totalEventsFired,totalActionsDispatched:this.totalActionsDispatched,totalActionsSucceeded:this.totalActionsSucceeded,totalActionsFailed:this.totalActionsFailed,averageActionDuration:this.averageActionDuration}}setupEventListeners(e){const t=e.emit;e.emit=s=>(this.totalEventsFired++,t.call(e,s)),e.subscribe("update:complete",(e=>{if(this.totalUpdates++,e.blocked)this.blockedUpdates++;else{if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();const t=this.updateTimes.reduce(((e,t)=>e+t),0)/this.updateTimes.length;this.averageUpdateTime=t,this.averageUpdateDuration=t}e.deltas?.length&&(this.updateCount++,this.largestUpdateSize=Math.max(this.largestUpdateSize,e.deltas.length),e.deltas.forEach((e=>{const t=this.pathExecutionCounts.get(e.path)||0;this.pathExecutionCounts.set(e.path,t+1)})),this.mostActiveListenerPaths=Array.from(this.pathExecutionCounts.entries()).sort((([,e],[,t])=>t-e)).slice(0,5).map((([e])=>e)))}})),e.subscribe("middleware:start",(()=>{this.middlewareExecutions++})),e.subscribe("transaction:start",(()=>{this.transactionCount++})),e.subscribe("action:start",(()=>{this.totalActionsDispatched++})),e.subscribe("action:complete",(e=>{this.totalActionsSucceeded++,e.duration&&(this.actionTimes.push(e.duration),this.actionTimes.length>100&&this.actionTimes.shift(),this.averageActionDuration=this.actionTimes.reduce(((e,t)=>e+t),0)/this.actionTimes.length)})),e.subscribe("action:error",(()=>{this.totalActionsFailed++}))}reset(){this.updateCount=0,this.listenerExecutions=0,this.averageUpdateTime=0,this.largestUpdateSize=0,this.mostActiveListenerPaths=[],this.totalUpdates=0,this.blockedUpdates=0,this.averageUpdateDuration=0,this.middlewareExecutions=0,this.transactionCount=0,this.totalEventsFired=0,this.totalActionsDispatched=0,this.totalActionsSucceeded=0,this.totalActionsFailed=0,this.averageActionDuration=0,this.updateTimes=[],this.actionTimes=[],this.pathExecutionCounts.clear()}getDetailedMetrics(){return{pathExecutionCounts:new Map(this.pathExecutionCounts),recentUpdateTimes:[...this.updateTimes],successRate:this.totalUpdates>0?(this.totalUpdates-this.blockedUpdates)/this.totalUpdates:1,averagePathsPerUpdate:this.updateCount>0?Array.from(this.pathExecutionCounts.values()).reduce(((e,t)=>e+t),0)/this.updateCount:0}}dispose(){this.reset()}},k=class extends Error{constructor(){super("Action Cancelled by Debounce"),this.name="ActionCancelledError"}},T=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name="UnknownActionError"}},M=class{constructor(e,t){this.eventBus=e,this.set=t}registrations=new Map;register(t){const s={action:{name:t.name,id:e.v4(),action:t.fn,debounce:t.debounce?{...t.debounce,condition:t.debounce.condition??(()=>!0)}:void 0},debouncer:t.debounce&&t.debounce.delay>0?new o({delay:t.debounce.delay}):void 0,previousArgs:void 0};return this.registrations.set(t.name,s),()=>{const e=this.registrations.get(t.name);e&&(e.debouncer?.cancel(),this.registrations.delete(t.name))}}async dispatch(e,...t){const s=this.registrations.get(e);if(!s)throw new T({action:e});const{action:i,debouncer:r}=s,{id:a,action:n,debounce:o}=i;if(!r||!o)return this.executeAction(e,a,n,t);const c=o.condition(s.previousArgs,t);if(s.previousArgs=t,!c)return this.executeAction(e,a,n,t);const d=await r.do((()=>this.executeAction(e,a,n,t)));if("cancelled"===d.status)throw new k;if("error"===d.status&&d.error)throw d.error;return d.value}async executeAction(e,t,s,i){const r=performance.now();this.emit(this.eventBus,{name:"action:start",payload:{actionId:t,name:e,params:i||[],timestamp:r}});try{const a=await this.set((e=>s(e,...i)),{actionId:t}),n=performance.now();return this.emit(this.eventBus,{name:"action:complete",payload:{actionId:t,name:e,params:i,startTime:r,endTime:n,duration:n-r,result:a}}),a}catch(s){const a=performance.now();throw this.emit(this.eventBus,{name:"action:error",payload:{actionId:t,name:e,params:i,startTime:r,endTime:a,duration:a-r,error:s}}),s}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}};exports.ActionCancelledError=k,exports.ActionManager=M,exports.DELETE_SYMBOL=d,exports.ReactiveDataStore=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new a({yieldMode:"macrotask",capacity:1e3});readyLatch=new n;updateBus=c();eventBus;executionState;instanceID=e.v4();merge;diff;constructor(e,t,s=d,i,r={errorHandler:()=>{}}){this.eventBus=c(r),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=h({deleteMarker:s}),this.diff=y({deleteMarker:s}),this.coreState=new b(e,this.updateBus,this.diff),this.middlewareEngine=new S(this.eventBus,this.executionState,this.merge),this.persistenceHandler=new x(this.eventBus,this.coreState,this.instanceID,{maxRetries:i?.persistenceMaxRetries,retryDelay:i?.persistenceRetryDelay}),this.transactionManager=new E(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new _(this.eventBus),this.actions=new M(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(t),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new m(this.get.bind(this),this.eventBus)}isReady(){return this.readyLatch.isOpen()}async ready(e){return this.readyLatch.wait(e)}state(){return this.executionState.executing=this.updateSerializer.running(),this.executionState}get(e){return this.coreState.get(e??!1)}select(e){return this.selectorManager.createReactiveSelector(e)}register(e){return this.actions.register(e)}async dispatch(e,...t){return this.actions.dispatch(e,...t)}async set(e,t={}){const s=await this.updateSerializer.do((()=>this._performUpdate(e,t)));if(s.error)throw s.error;return s.value}async _performUpdate(e,t){const s=performance.now();this.emit(this.eventBus,{name:"update:start",payload:{timestamp:s,actionId:t.actionId}});try{if(t.force){const i=this.get(!1),r="function"==typeof e?e(i):e;this.coreState.applyChanges(r,!0);const a=performance.now();return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:[],duration:a-s,timestamp:Date.now(),actionId:t.actionId,newState:r}}),r}let i;const r=this.get(!1);if("function"==typeof e){const t=e(r);i=t instanceof Promise?await t:t}else i=e;const a=await this.middlewareEngine.executeBlocking(r,i);if(a.blocked)throw a.error||new Error("Update blocked by middleware");const n=this.merge(r,i),o=await this.middlewareEngine.executeTransform(n,i),c=this.merge(n,o),d=this.coreState.applyChanges(c,!1,!1,[i,o]),l=performance.now(),h=this.get(!1);return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:d,duration:l-s,timestamp:Date.now(),actionId:t.actionId,newState:h}}),h}catch(e){throw this.emit(this.eventBus,{name:"update:complete",payload:{blocked:!0,error:e,timestamp:Date.now(),actionId:t.actionId,newState:this.get(!1)}}),e}finally{this.executionState.executing=!1,this.executionState.changes=null,this.executionState.runningMiddleware=null,this.executionState.pendingChanges=[]}}setupReadyLatch(){this.eventBus.subscribe("persistence:ready",(()=>{this.readyLatch.open()})),this.persistenceHandler.isReady()?this.readyLatch.open():queueMicrotask((()=>{this.readyLatch.isOpen()||this.readyLatch.open()}))}setupPersistenceListener(){this.updateBus.subscribe("update",(e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))}))}watch(e,t){const s=Array.isArray(e)?e:[e],i=""===e||0===s.length;return this.updateBus.subscribe("update",(e=>{(i||s.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)}))}debouncedSetter(e){const t=new o({delay:e.delay,leading:e.leading});return(e,s={})=>{t.fire((()=>this.set(e,s)))}}subscribe(e,t){return this.watch(e,t)}id(){return this.instanceID}async transaction(e){return this.transactionManager.execute(e)}use(e){const t=(e.block?this.middlewareEngine.addBlockingMiddleware:this.middlewareEngine.addMiddleware).bind(this.middlewareEngine)(e.action,e.name);return()=>this.middlewareEngine.removeMiddleware(t)}metrics(){return this.metricsCollector.getMetrics()}on(e,t){return this.eventBus.subscribe(e,t)}onStoreEvent(e,t){return this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flushPersistence(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){this.updateSerializer.close(),this.persistenceHandler.dispose(),this.metricsCollector.dispose?.(),this.selectorManager.dispose?.()}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},exports.StoreObserver=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;constructor(e,t={}){this.store=e,this.maxEvents=t.maxEvents??500,this.maxStateHistory=t.maxStateHistory??20,this.enableConsoleLogging=t.enableConsoleLogging??!1,this.isSilent=t.silent??!1,this.logEvents={updates:t.logEvents?.updates??!0,middleware:t.logEvents?.middleware??!0,transactions:t.logEvents?.transactions??!0,actions:t.logEvents?.actions??!0,selectors:t.logEvents?.selectors??!0},this.performanceThresholds={updateTime:t.performanceThresholds?.updateTime??50,middlewareTime:t.performanceThresholds?.middlewareTime??20},this.recordStateSnapshot([]),this.setupEventListeners()}_consoleLog(e,...t){this.isSilent||"function"==typeof console[e]&&console[e](...t)}setupEventListeners(){const e=["update:start","update:complete","middleware:start","middleware:complete","middleware:error","middleware:blocked","transaction:start","transaction:complete","transaction:error","middleware:executed","action:start","action:complete","action:error","selector:accessed"];for(const t of e){const e=t.startsWith("update")&&this.logEvents.updates||t.startsWith("middleware")&&this.logEvents.middleware||t.startsWith("transaction")&&this.logEvents.transactions||t.startsWith("action")&&this.logEvents.actions||t.startsWith("selector")&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(t,(s=>{"update:complete"!==t||s.blocked||this.isTimeTraveling||this.recordStateSnapshot(s.deltas),"middleware:executed"===t?this.middlewareExecutions.push(s):"transaction:start"===t?this.activeTransactionCount++:"transaction:complete"!==t&&"transaction:error"!==t||(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),s.batchId&&(t.endsWith("start")?this.activeBatches.add(s.batchId):(t.endsWith("complete")||t.endsWith("error"))&&this.activeBatches.delete(s.batchId)),this.recordEvent(t,s),this.enableConsoleLogging&&e&&this._log(t,s),this._checkPerformance(t,s)})))}}recordStateSnapshot(e){const t={state:this.store.get(!0),timestamp:Date.now(),deltas:e};this.stateHistory.unshift(t),this.stateHistory.length>this.maxStateHistory&&this.stateHistory.pop()}recordEvent(e,t){const s={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(s),this.eventHistory.length>this.maxEvents&&this.eventHistory.pop()}getEventHistory(){return structuredClone(this.eventHistory)}getStateHistory(){return structuredClone(this.stateHistory)}getMiddlewareExecutions(){return this.middlewareExecutions}getTransactionStatus(){return{activeTransactions:this.activeTransactionCount,activeBatches:Array.from(this.activeBatches)}}createLoggingMiddleware(e={}){const{logLevel:t="debug",logUpdates:s=!0}=e;return(e,i)=>{if(s){(console[t]||console.log)("State Update:",i)}return i}}createValidationMiddleware(e){return(t,s)=>{const i=e(t,s);return"boolean"==typeof i?i:(!i.valid&&i.reason&&this._consoleLog("warn","Validation failed:",i.reason),i.valid)}}getRecentChanges(e=5){const t=[],s=Math.min(e,this.stateHistory.length);for(let e=0;e<s;e++){const s=this.stateHistory[e];if(!s.deltas||0===s.deltas.length)continue;const i={},r={},a=(e,t,s)=>{t.reduce(((e,i,r)=>(r===t.length-1?e[i]=s:e[i]=e[i]??{},e[i])),e)};for(const e of s.deltas){const t=e.path.split(".");a(i,t,e.oldValue),a(r,t,e.newValue)}t.push({timestamp:s.timestamp,changedPaths:s.deltas.map((e=>e.path)),from:i,to:r})}return t}clearHistory(){this.eventHistory=[],this.stateHistory.length>0&&(this.stateHistory=[this.stateHistory[0]])}getHistoryForAction(e){return this.eventHistory.filter((t=>t.data?.actionId===e))}async replay(e){const t=this.eventHistory.filter((e=>"update:start"===e.type))[e];t?.data.update?(this._consoleLog("log",`Replaying event at index ${e}:`,t),await this.store.set(t.data.update,{force:!0})):this._consoleLog("warn",`No replayable event found at index ${e}.`)}createTimeTravel(){let e=0,t=[];const s=this.store.on("update:complete",(s=>{this.isTimeTraveling||s.blocked||(t=[],e=0)}));this.unsubscribers.push(s);const i=()=>this.stateHistory.length,r=()=>e<i()-1,a=()=>t.length>0;return{canUndo:r,canRedo:a,undo:async()=>{if(!r())return;t.unshift(this.stateHistory[e]),e++;const s=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...s},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;const s=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...s.state},{force:!0}),this.isTimeTraveling=!1},length:i,clear:()=>{t=[],e=0}}}async saveSession(e){const t=this.store.id(),s={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,s))}async loadSession(e){const t=await Promise.resolve(e.get());return!!t&&(this.eventHistory=t.eventHistory||[],this.stateHistory=t.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),!0)}exportSession(){const e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),s=URL.createObjectURL(t),i=document.createElement("a");i.href=s,i.download=`store-observer-session-${(new Date).toISOString()}.json`,i.click(),URL.revokeObjectURL(s)}importSession(e){return new Promise(((t,s)=>{const i=new FileReader;i.onload=async e=>{try{const s=JSON.parse(e.target?.result);this.eventHistory=s.eventHistory||[],this.stateHistory=s.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){s(e)}},i.onerror=e=>s(e),i.readAsText(e)}))}disconnect(){this.unsubscribers.forEach((e=>e())),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){const s=new Date(t.timestamp||Date.now()).toISOString().split("T")[1].replace("Z","");if("update:start"===e)this._consoleLog("group",`%c⚡ Store Update Started [${s}]`,"color: #4a6da7");else if("update:complete"===e){if(t.blocked)this._consoleLog("warn",`%c✋ Update Blocked [${s}]`,"color: #bf8c0a",t.error);else{const e=t.deltas||[];e.length>0&&(this._consoleLog("log",`%c✅ Update Complete [${s}] - ${e.length} paths changed in ${t.duration?.toFixed(2)}ms`,"color: #2a9d8f"),this._consoleLog("table",e.map((e=>({path:e.path,oldValue:e.oldValue,newValue:e.newValue})))))}this._consoleLog("groupEnd")}else"middleware:start"===e?this._consoleLog("debug",`%c◀ Middleware "${t.name}" started [${s}] (${t.type})`,"color: #8c8c8c"):"middleware:complete"===e?this._consoleLog("debug",`%c▶ Middleware "${t.name}" completed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #7c9c7c"):"middleware:error"===e?this._consoleLog("error",`%c❌ Middleware "${t.name}" error [${s}]:`,"color: #e63946",t.error):"middleware:blocked"===e?this._consoleLog("warn",`%c🛑 Middleware "${t.name}" blocked update [${s}]`,"color: #e76f51"):"transaction:start"===e?this._consoleLog("group",`%c📦 Transaction Started [${s}]`,"color: #6d597a"):"transaction:complete"===e?(this._consoleLog("log",`%c📦 Transaction Complete [${s}]`,"color: #355070"),this._consoleLog("groupEnd")):"transaction:error"===e?(this._consoleLog("error",`%c📦 Transaction Error [${s}]:`,"color: #e56b6f",t.error),this._consoleLog("groupEnd")):"action:start"===e?this._consoleLog("group",`%c🚀 Action "${t.name}" Started [${s}]`,"color: #9b59b6",{params:t.params}):"action:complete"===e?(this._consoleLog("log",`%c✔️ Action "${t.name}" Complete [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #2ecc71"),this._consoleLog("groupEnd")):"action:error"===e?(this._consoleLog("error",`%c🔥 Action "${t.name}" Error [${s}]:`,"color: #e74c3c",t.error),this._consoleLog("groupEnd")):"selector:accessed"===e&&this._consoleLog("debug",`%c👀 Selector Accessed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #f1c40f",{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&("update:complete"===e&&!t.blocked&&t.duration>this.performanceThresholds.updateTime&&this._consoleLog("warn",`%c⚠️ Slow update detected [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{deltas:t.deltas,threshold:this.performanceThresholds.updateTime}),"middleware:complete"===e&&t.duration>this.performanceThresholds.middlewareTime&&this._consoleLog("warn",`%c⚠️ Slow middleware "${t.name}" [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{threshold:this.performanceThresholds.middlewareTime}))}},exports.UnknownActionError=T,exports.createDerivePaths=f,exports.createDiff=y,exports.createMerge=h,exports.derivePaths=v,exports.diff=w,exports.merge=u,exports.shallowClone=l;
1
+ "use strict";var e=require("uuid"),t=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},s=class extends t{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},i=class extends t{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},r=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,a)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),a(new s("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}},a=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new r({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new i};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new i;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},n=class{_open=!1;_resolve;_promise;constructor(){this._promise=new Promise((e=>{this._resolve=e}))}open(){this._open||(this._open=!0,this._resolve())}async wait(e){if(this._open)return;if(null==e)return this._promise;let t;await Promise.race([this._promise.then((()=>clearTimeout(t))),new Promise(((i,r)=>{t=setTimeout((()=>r(new s("Latch timed out"))),e)}))])}isOpen(){return this._open}},o=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise((t=>{this._enqueue(e,t)}))}fire(e){this._enqueue(e,void 0)}_enqueue(e,t){if(this._pendingFn=e,t&&this._pendingResolvers.push(t),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout((()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()}),this._delay));clearTimeout(this._timer),this._timer=setTimeout((()=>{this._leadingFired=!1,this._fire()}),this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const t of e)t({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,t=this._pendingResolvers.splice(0);let s;this._pendingFn=void 0;try{s={status:"ok",value:await e()}}catch(e){s={status:"error",error:e}}for(const e of t)e(s);return s}};function c(e){const t=e??{},{deferred:s,batchSize:i,batchDelay:r,errorHandler:a,broadcast:n,channel:c}={deferred:null!=t.batch?.size,batchSize:t.batch?.size,batchDelay:t.batch?.delay||16,errorHandler:t.errorHandler||(e=>console.error("EventBus Error:",e)),broadcast:null!=t.broadcast?.channel&&t.broadcast.channel.length>0,channel:null!=t.broadcast?.channel&&t.broadcast.channel.length>0?t.broadcast?.channel:"event-bus-channel"},d=new Map;let l=[],h=0,u=0;const p=new Map,m=()=>{if(!n)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(c);return e.onmessage=e=>{const{name:t,payload:s}=e.data;f(t,s)},e};let g=m();const y=(e,t)=>{h++,u+=t,p.set(e,(p.get(e)??0)+1)},f=(e,t)=>{const s=d.get(e);if(s&&0!==s.size)for(const i of Array.from(s))try{i(t)}catch(s){const i=s instanceof Error?s:Object.assign(new Error(String(s)),{cause:s}),r=Object.assign(i,{eventName:e,payload:t});a(r)}},w=()=>{const e=l;l=[];for(const{name:t,payload:s}of e){const e=performance.now();f(t,s),y(t,performance.now()-e)}},v=new o({delay:r});return{subscribe:(e,t)=>{d.has(e)||d.set(e,new Set);const s=d.get(e);return s.add(t),()=>{s.delete(t),0===s.size&&d.delete(e)}},once:(e,t)=>{let s;const i=e=>{s(),t(e)};return s=(()=>{d.has(e)||d.set(e,new Set);const t=d.get(e);return t.add(i),()=>{t.delete(i),0===t.size&&d.delete(e)}})(),s},emit:({name:e,payload:t})=>{if(s)return l.push({name:e,payload:t}),l.length>=i?(v.cancel(),void w()):(v.fire((()=>w())),void g?.postMessage({name:e,payload:t}));const r=performance.now();f(e,t),y(e,performance.now()-r),g?.postMessage({name:e,payload:t})},metrics:()=>({totalEvents:h,activeSubscriptions:Array.from(d.values()).reduce(((e,t)=>e+t.size),0),eventCounts:p,averageEmitDuration:h>0?u/h:0}),clear:()=>{d.clear(),l=[],v.cancel(),h=0,u=0,p.clear(),g?.close(),g=m()}}}var d=Symbol.for("delete"),l=e=>Array.isArray(e)?[...e]:{...e};function h(e){const t=e?.deleteMarker||d;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const i={};for(const[r,a]of Object.entries(e))if(a!==t)if("object"==typeof a&&null!==a){const e=s(a);void 0!==e&&(i[r]=e)}else i[r]=a;return i}return e===t?void 0:e}return function(e,i){if("object"!=typeof e||null===e)return"object"==typeof i&&null!==i?s(i):i===t?{}:i;if("object"!=typeof i||null===i)return e;const r=l(e),a=[{target:r,source:i}];for(;a.length>0;){const{target:e,source:s}=a.pop();for(const i of Object.keys(s)){const r=s[i];if(r!==t)if(Array.isArray(r))e[i]=r;else if("object"==typeof r&&null!==r){const t=i in e&&"object"==typeof e[i]&&null!==e[i]?e[i]:{};e[i]=l(t),a.push({target:e[i],source:r})}else e[i]=r;else delete e[i]}}return r}}var u=h(),p=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"],m=class{reactiveSelectors=new Map;reactiveSelectorCache=new WeakMap;pathBasedCache=new Map;dependencyMap=new Map;getState;eventBus;unsubscribeFromStore;constructor(e,t){this.getState=e,this.eventBus=t,this.unsubscribeFromStore=this.eventBus.subscribe("update:complete",this.handleStoreUpdate)}handleStoreUpdate=e=>{const t=new Set;for(const s of e.deltas){const e=s.path;for(const[s,i]of this.dependencyMap)if(s===e||s.startsWith(e+".")||e.startsWith(s+"."))for(const e of i)t.add(e)}t.forEach((e=>{const t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}))};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}t!==e.lastResult&&(e.lastResult=t,e.subscribers.forEach((e=>e(t))),this.eventBus.emit({name:"selector:changed",payload:{selectorId:e.id,newResult:t,timestamp:performance.now()}}))}createReactiveSelector(e){const t=this.reactiveSelectorCache.get(e);if(t)return t;const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const a=new Proxy((()=>{}),{get:(i,a)=>{if("symbol"==typeof a||"then"===a)return;if("valueOf"===a||"toString"===a)throw new Error("Cannot perform logic/math/string operations inside a selector.");if(p.includes(a))throw new Error(`Array method .${a}() is not allowed in selectors.`);const n=e?`${e}${t}${a}`:a;return e&&s.delete(e),s.add(n),r(n)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions/methods.")}});return i.set(e,a),a};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. This usually means the selector is too complex. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e),i=`${[...s].sort().join("|")}::${e.toString()}`,r=this.pathBasedCache.get(i);if(r)return this.reactiveSelectorCache.set(e,r),r;const a=`sel-${Math.random().toString(36).slice(2,9)}`,n=e(this.getState()),o={id:a,selector:e,lastResult:n,accessedPaths:s,subscribers:new Set,reactiveSelectorInstance:null};s.forEach((e=>{this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(a)}));const c={get:()=>o.lastResult,id:a,subscribe:t=>(o.subscribers.add(t),()=>{o.subscribers.delete(t),0===o.subscribers.size&&this.cleanupSelector(a,e,i)})};return o.reactiveSelectorInstance=c,this.reactiveSelectors.set(a,o),this.reactiveSelectorCache.set(e,c),this.pathBasedCache.set(i,c),this.eventBus.emit({name:"selector:accessed",payload:{selectorId:a,accessedPaths:s,duration:0,timestamp:performance.now()}}),c}cleanupSelector(e,t,s){const i=this.reactiveSelectors.get(e);i&&(i.accessedPaths.forEach((t=>{this.dependencyMap.get(t)?.delete(e),0===this.dependencyMap.get(t)?.size&&this.dependencyMap.delete(t)})),this.reactiveSelectors.delete(e),this.reactiveSelectorCache.delete(t),this.pathBasedCache.delete(s))}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function g(e,t){if(e===t)return!0;if(e&&t&&"object"==typeof e&&"object"==typeof t){if(e.constructor!==t.constructor)return!1;let s,i;if(Array.isArray(e)){if(s=e.length,s!=t.length)return!1;for(i=s;i-- >0;)if(!g(e[i],t[i]))return!1;return!0}const[r,a]=[Object.keys(e),Object.keys(t)];if(s=r.length,s!==a.length)return!1;for(i=s;i-- >0;){const s=r[i];if(!Object.prototype.hasOwnProperty.call(t,s)||!g(e[s],t[s]))return!1}return!0}return e!=e&&t!=t}function y(e){const t=e?.deleteMarker||d;return function(e,s){const i=[],r=[{pathStr:"",orig:e||{},part:s||{}}];for(;r.length>0;){const{pathStr:e,orig:s,part:a}=r.pop();if(null!=a&&!g(s,a))if("object"!=typeof a||Array.isArray(a))e&&i.push({path:e,oldValue:s,newValue:a});else for(const n of Object.keys(a)){const o=e?e+"."+n:n,c=a[n],d=s&&"object"==typeof s?s[n]:void 0;c!==t?"object"==typeof c&&null!==c?r.push({pathStr:o,orig:d,part:c}):g(d,c)||i.push({path:o,oldValue:d,newValue:c}):void 0!==d&&i.push({path:o,oldValue:d,newValue:void 0})}}return i}}function f(e){const t=e?.deleteMarker||d;return function(e){const s=new Set,i=[{obj:e,currentPath:""}];for(;i.length>0;){const{obj:e,currentPath:r}=i.pop();if(null!=e&&"object"==typeof e&&!Array.isArray(e))for(const a of Object.keys(e)){const n=r?`${r}.${a}`:a;s.add(n);const o=e[a];"object"!=typeof o||null===o||Array.isArray(o)||o===t||i.push({obj:o,currentPath:n})}}return Array.from(s)}}var w=y(),v=f(),b=class{constructor(e,t,s){this.updateBus=t,this.diff=s,this.cache=structuredClone(e)}cache;get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,s=!1,i=[]){if(t)return this.cache=s?structuredClone(e):e,this.notifyListeners([]),[];0===i.length&&(i=[e]);const r=this.get(!1),a=new Map;for(let e=0;e<i.length;e++){const t=i[e],s=this.diff(r,t);for(let e=0;e<s.length;e++){const t=s[e];a.set(t.path,t)}}const n=a.size?[...a.values()]:[];if(n.length>0){this.cache=s?structuredClone(e):e;const t=new Set;for(let e=0;e<n.length;e++){let s=n[e].path;for(;s&&!t.has(s);){t.add(s);const e=s.lastIndexOf(".");if(e<0)break;s=s.slice(0,e)}}this.notifyListeners(t)}return n}notifyListeners(e){for(const t of e)this.updateBus.emit({name:"update",payload:t})}},S=class{constructor(e,t,s){this.eventBus=e,this.executionState=t,this.merge=s}middleware=[];blockingMiddleware=[];async executeBlocking(e,t){for(const{fn:s,name:i,id:r}of this.blockingMiddleware){const a={id:r,name:i,startTime:performance.now()};this.executionState.runningMiddleware={id:r,name:i,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:r,name:i,type:"blocking"});try{const n=await Promise.resolve(s(e,t));if(a.endTime=performance.now(),a.duration=a.endTime-a.startTime,!1===n)return a.blocked=!0,this.emitMiddlewareLifecycle("blocked",{id:r,name:i,duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0};this.emitMiddlewareLifecycle("complete",{id:r,name:i,type:"blocking",duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:{...a,blocked:!1}})}catch(e){return a.endTime=performance.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:new Error(String(e)),a.blocked=!0,this.emitMiddlewareError(r,i,a.error,a.duration),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0,error:a.error}}finally{this.executionState.runningMiddleware=null}}return{blocked:!1}}async executeTransform(e,t){let s=e,i=t;for(const{fn:e,name:r,id:a}of this.middleware){const n={id:a,name:r,startTime:performance.now()};this.executionState.runningMiddleware={id:a,name:r,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:a,name:r,type:"transform"});try{const o=await Promise.resolve(e(s,t));n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.blocked=!1,o&&"object"==typeof o&&(s=this.merge(s,o),i=this.merge(i,o)),this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareLifecycle("complete",{id:a,name:r,type:"transform",duration:n.duration})}catch(e){n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.error=e instanceof Error?e:new Error(String(e)),n.blocked=!1,this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareError(a,r,n.error,n.duration),console.error(`Middleware ${r} error:`,e)}finally{this.executionState.runningMiddleware=null}}return i}addMiddleware(e,t="unnamed-middleware"){const s=this.generateId();return this.middleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}addBlockingMiddleware(e,t="unnamed-blocking-middleware"){const s=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}removeMiddleware(e){const t=this.middleware.length+this.blockingMiddleware.length;return this.middleware=this.middleware.filter((t=>t.id!==e)),this.blockingMiddleware=this.blockingMiddleware.filter((t=>t.id!==e)),this.updateExecutionState(),this.middleware.length+this.blockingMiddleware.length<t}updateExecutionState(){this.executionState.middlewares=[...this.middleware.map((e=>e.name)),...this.blockingMiddleware.map((e=>e.name))]}emitMiddlewareLifecycle(e,t){this.emit(this.eventBus,{name:`middleware:${e}`,payload:{...t,timestamp:Date.now()}})}emitMiddlewareError(e,t,s,i){this.emit(this.eventBus,{name:"middleware:error",payload:{id:e,name:t,error:s,duration:i,timestamp:Date.now()}})}generateId(){return crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).substring(2,15)}`}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},x=class{constructor(e,t,s,i){this.eventBus=e,this.coreState=t,this.instanceID=s,this.maxRetries=i?.maxRetries??3,this.retryDelay=i?.retryDelay??1e3}persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||0===e.length)return;const s={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(s),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:"persistence:queued",payload:{taskId:s.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:s.timestamp}})}getQueueStatus(){return{queueSize:this.backgroundQueue.length,isProcessing:this.isProcessingQueue,pendingRetries:this.pendingRetries.size,oldestTask:this.backgroundQueue[0]?.timestamp}}async flush(){this.isProcessingQueue&&await new Promise((e=>{const t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()})),await this.processQueue()}discardQueue(){const e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&(clearTimeout(this.queueProcessor),this.queueProcessor=void 0),this.emit(this.eventBus,{name:"persistence:queue_cleared",payload:{clearedTasks:e,timestamp:Date.now()}})}scheduleQueueProcessing(){this.queueProcessor||this.isProcessingQueue||(this.queueProcessor=setTimeout((()=>{this.processQueue().catch((e=>{console.error("Queue processing failed:",e)}))}),10))}async processQueue(){if(!this.isProcessingQueue&&0!==this.backgroundQueue.length){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){const e=this.backgroundQueue.shift();await this.processTask(e)}}finally{this.isProcessingQueue=!1}}}async processTask(e){try{await this.persistence.set(this.instanceID,e.state)?this.emit(this.eventBus,{name:"persistence:success",payload:{taskId:e.id,changedPaths:e.changedPaths,duration:Date.now()-e.timestamp,timestamp:Date.now()}}):await this.handleTaskFailure(e,new Error("Persistence returned false"))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){const s=this.retryDelay*Math.pow(2,e.retries-1);this.emit(this.eventBus,{name:"persistence:retry",payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:s,error:t,timestamp:Date.now()}}),this.pendingRetries.add(e.id),setTimeout((()=>{this.pendingRetries.has(e.id)&&(this.pendingRetries.delete(e.id),this.backgroundQueue.unshift(e),this.scheduleQueueProcessing())}),s)}else this.emit(this.eventBus,{name:"persistence:failed",payload:{taskId:e.id,changedPaths:e.changedPaths,attempts:e.retries,error:t,timestamp:Date.now()}})}setPersistenceReady(){this.persistenceReady=!0,this.emit(this.eventBus,{name:"persistence:ready",payload:{timestamp:Date.now()}})}async setPersistence(e){this.persistence=e;try{const e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){console.error("Failed to initialize persistence:",e),this.emit(this.eventBus,{name:"persistence:init_error",payload:{error:e,timestamp:Date.now()}})}finally{this.setPersistenceReady()}this.persistence.subscribe(this.instanceID,(async e=>{const t=this.coreState.applyChanges(e);t.length>0&&this.emit(this.eventBus,{name:"update:complete",payload:{changedPaths:t,source:"external",timestamp:Date.now()}})}))}dispose(){this.discardQueue(),this.isProcessingQueue=!1,this.persistenceReady=!1}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},E=class{constructor(e,t,s){this.eventBus=e,this.coreState=t,this.executionState=s}async execute(e){const t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:"transaction:start",payload:{timestamp:Date.now()}});try{const t=await Promise.resolve(e());return this.emit(this.eventBus,{name:"transaction:complete",payload:{timestamp:Date.now()}}),this.executionState.transactionActive=!1,t}catch(e){throw this.coreState.applyChanges(t,!0,!1),this.emit(this.eventBus,{name:"transaction:error",payload:{error:e instanceof Error?e:new Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},_=class{updateCount=0;listenerExecutions=0;averageUpdateTime=0;largestUpdateSize=0;mostActiveListenerPaths=[];totalUpdates=0;blockedUpdates=0;averageUpdateDuration=0;middlewareExecutions=0;transactionCount=0;totalEventsFired=0;totalActionsDispatched=0;totalActionsSucceeded=0;totalActionsFailed=0;averageActionDuration=0;updateTimes=[];actionTimes=[];pathExecutionCounts=new Map;constructor(e){this.setupEventListeners(e)}getMetrics(){return{updateCount:this.updateCount,listenerExecutions:this.listenerExecutions,averageUpdateTime:this.averageUpdateTime,largestUpdateSize:this.largestUpdateSize,mostActiveListenerPaths:[...this.mostActiveListenerPaths],totalUpdates:this.totalUpdates,blockedUpdates:this.blockedUpdates,averageUpdateDuration:this.averageUpdateDuration,middlewareExecutions:this.middlewareExecutions,transactionCount:this.transactionCount,totalEventsFired:this.totalEventsFired,totalActionsDispatched:this.totalActionsDispatched,totalActionsSucceeded:this.totalActionsSucceeded,totalActionsFailed:this.totalActionsFailed,averageActionDuration:this.averageActionDuration}}setupEventListeners(e){const t=e.emit;e.emit=s=>(this.totalEventsFired++,t.call(e,s)),e.subscribe("update:complete",(e=>{if(this.totalUpdates++,e.blocked)this.blockedUpdates++;else{if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();const t=this.updateTimes.reduce(((e,t)=>e+t),0)/this.updateTimes.length;this.averageUpdateTime=t,this.averageUpdateDuration=t}e.deltas?.length&&(this.updateCount++,this.largestUpdateSize=Math.max(this.largestUpdateSize,e.deltas.length),e.deltas.forEach((e=>{const t=this.pathExecutionCounts.get(e.path)||0;this.pathExecutionCounts.set(e.path,t+1)})),this.mostActiveListenerPaths=Array.from(this.pathExecutionCounts.entries()).sort((([,e],[,t])=>t-e)).slice(0,5).map((([e])=>e)))}})),e.subscribe("middleware:start",(()=>{this.middlewareExecutions++})),e.subscribe("transaction:start",(()=>{this.transactionCount++})),e.subscribe("action:start",(()=>{this.totalActionsDispatched++})),e.subscribe("action:complete",(e=>{this.totalActionsSucceeded++,e.duration&&(this.actionTimes.push(e.duration),this.actionTimes.length>100&&this.actionTimes.shift(),this.averageActionDuration=this.actionTimes.reduce(((e,t)=>e+t),0)/this.actionTimes.length)})),e.subscribe("action:error",(()=>{this.totalActionsFailed++}))}reset(){this.updateCount=0,this.listenerExecutions=0,this.averageUpdateTime=0,this.largestUpdateSize=0,this.mostActiveListenerPaths=[],this.totalUpdates=0,this.blockedUpdates=0,this.averageUpdateDuration=0,this.middlewareExecutions=0,this.transactionCount=0,this.totalEventsFired=0,this.totalActionsDispatched=0,this.totalActionsSucceeded=0,this.totalActionsFailed=0,this.averageActionDuration=0,this.updateTimes=[],this.actionTimes=[],this.pathExecutionCounts.clear()}getDetailedMetrics(){return{pathExecutionCounts:new Map(this.pathExecutionCounts),recentUpdateTimes:[...this.updateTimes],successRate:this.totalUpdates>0?(this.totalUpdates-this.blockedUpdates)/this.totalUpdates:1,averagePathsPerUpdate:this.updateCount>0?Array.from(this.pathExecutionCounts.values()).reduce(((e,t)=>e+t),0)/this.updateCount:0}}dispose(){this.reset()}},k=class extends Error{constructor(){super("Action Cancelled by Debounce"),this.name="ActionCancelledError"}},T=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name="UnknownActionError"}},M=class{constructor(e,t){this.eventBus=e,this.set=t}registrations=new Map;register(t){const s={action:{name:t.name,id:e.v4(),action:t.fn,debounce:t.debounce?{...t.debounce,condition:t.debounce.condition??(()=>!0)}:void 0},debouncer:t.debounce&&t.debounce.delay>0?new o({delay:t.debounce.delay}):void 0,previousArgs:void 0};return this.registrations.set(t.name,s),()=>{const e=this.registrations.get(t.name);e&&(e.debouncer?.cancel(),this.registrations.delete(t.name))}}async dispatch(e,...t){const s=this.registrations.get(e);if(!s)throw new T({action:e});const{action:i,debouncer:r}=s,{id:a,action:n,debounce:o}=i;if(!r||!o)return this.executeAction(e,a,n,t);const c=o.condition(s.previousArgs,t);if(s.previousArgs=t,!c)return this.executeAction(e,a,n,t);const d=await r.do((()=>this.executeAction(e,a,n,t)));if("cancelled"===d.status)throw new k;if("error"===d.status&&d.error)throw d.error;return d.value}async executeAction(e,t,s,i){const r=performance.now();this.emit(this.eventBus,{name:"action:start",payload:{actionId:t,name:e,params:i||[],timestamp:r}});try{const a=await this.set((e=>s(e,...i)),{actionId:t}),n=performance.now();return this.emit(this.eventBus,{name:"action:complete",payload:{actionId:t,name:e,params:i,startTime:r,endTime:n,duration:n-r,result:a}}),a}catch(s){const a=performance.now();throw this.emit(this.eventBus,{name:"action:error",payload:{actionId:t,name:e,params:i,startTime:r,endTime:a,duration:a-r,error:s}}),s}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}};exports.ActionCancelledError=k,exports.ActionManager=M,exports.DELETE_SYMBOL=d,exports.ReactiveDataStore=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new a({yieldMode:"macrotask",capacity:1e3});readyLatch=new n;updateBus=c();eventBus;executionState;instanceID=e.v4();merge;diff;constructor(e,t,s=d,i,r={errorHandler:()=>{}}){this.eventBus=c(r),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=h({deleteMarker:s}),this.diff=y({deleteMarker:s}),this.coreState=new b(e,this.updateBus,this.diff),this.middlewareEngine=new S(this.eventBus,this.executionState,this.merge),this.persistenceHandler=new x(this.eventBus,this.coreState,this.instanceID,{maxRetries:i?.persistenceMaxRetries,retryDelay:i?.persistenceRetryDelay}),this.transactionManager=new E(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new _(this.eventBus),this.actions=new M(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(t),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new m(this.get.bind(this),this.eventBus)}isReady(){return this.readyLatch.isOpen()}async ready(e){return this.readyLatch.wait(e)}state(){return this.executionState.executing=this.updateSerializer.running(),this.executionState}get(e){return this.coreState.get(e??!1)}select(e){return this.selectorManager.createReactiveSelector(e)}register(e){return this.actions.register(e)}async dispatch(e,...t){return this.actions.dispatch(e,...t)}async set(e,t={}){const s=await this.updateSerializer.do((()=>this._performUpdate(e,t)));if(s.error)throw s.error;return s.value}async _performUpdate(e,t){const s=performance.now();this.emit(this.eventBus,{name:"update:start",payload:{timestamp:s,actionId:t.actionId}});try{if(t.force){const i=this.get(!1),r="function"==typeof e?e(i):e;this.coreState.applyChanges(r,!0);const a=performance.now();return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:[],duration:a-s,timestamp:Date.now(),actionId:t.actionId,newState:r}}),r}let i;const r=this.get(!1);if("function"==typeof e){const t=e(r);i=t instanceof Promise?await t:t}else i=e;const a=await this.middlewareEngine.executeBlocking(r,i);if(a.blocked)throw a.error||new Error("Update blocked by middleware");const n=this.merge(r,i),o=await this.middlewareEngine.executeTransform(n,i),c=this.merge(n,o),d=this.coreState.applyChanges(c,!1,!1,[i,o]),l=performance.now(),h=this.get(!1);return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:d,duration:l-s,timestamp:Date.now(),actionId:t.actionId,newState:h}}),h}catch(e){throw this.emit(this.eventBus,{name:"update:complete",payload:{blocked:!0,error:e,timestamp:Date.now(),actionId:t.actionId,newState:this.get(!1)}}),e}finally{this.executionState.executing=!1,this.executionState.changes=null,this.executionState.runningMiddleware=null,this.executionState.pendingChanges=[]}}setupReadyLatch(){this.readyLatch.open(),this.persistenceHandler.isReady()?this.readyLatch.open():queueMicrotask((()=>{this.readyLatch.isOpen()||this.readyLatch.open()}))}setupPersistenceListener(){this.updateBus.subscribe("update",(e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))}))}watch(e,t){const s=Array.isArray(e)?e:[e],i=""===e||0===s.length;return this.updateBus.subscribe("update",(e=>{(i||s.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)}))}debouncedSetter(e){const t=new o({delay:e.delay,leading:e.leading});return(e,s={})=>{t.fire((()=>this.set(e,s)))}}subscribe(e,t){return this.watch(e,t)}id(){return this.instanceID}async transaction(e){return this.transactionManager.execute(e)}use(e){const t=(e.block?this.middlewareEngine.addBlockingMiddleware:this.middlewareEngine.addMiddleware).bind(this.middlewareEngine)(e.action,e.name);return()=>this.middlewareEngine.removeMiddleware(t)}metrics(){return this.metricsCollector.getMetrics()}on(e,t){return this.eventBus.subscribe(e,t)}onStoreEvent(e,t){return this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flushPersistence(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){this.updateSerializer.close(),this.persistenceHandler.dispose(),this.metricsCollector.dispose?.(),this.selectorManager.dispose?.()}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},exports.StoreObserver=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;constructor(e,t={}){this.store=e,this.maxEvents=t.maxEvents??500,this.maxStateHistory=t.maxStateHistory??20,this.enableConsoleLogging=t.enableConsoleLogging??!1,this.isSilent=t.silent??!1,this.logEvents={updates:t.logEvents?.updates??!0,middleware:t.logEvents?.middleware??!0,transactions:t.logEvents?.transactions??!0,actions:t.logEvents?.actions??!0,selectors:t.logEvents?.selectors??!0},this.performanceThresholds={updateTime:t.performanceThresholds?.updateTime??50,middlewareTime:t.performanceThresholds?.middlewareTime??20},this.recordStateSnapshot([]),this.setupEventListeners()}_consoleLog(e,...t){this.isSilent||"function"==typeof console[e]&&console[e](...t)}setupEventListeners(){const e=["update:start","update:complete","middleware:start","middleware:complete","middleware:error","middleware:blocked","transaction:start","transaction:complete","transaction:error","middleware:executed","action:start","action:complete","action:error","selector:accessed"];for(const t of e){const e=t.startsWith("update")&&this.logEvents.updates||t.startsWith("middleware")&&this.logEvents.middleware||t.startsWith("transaction")&&this.logEvents.transactions||t.startsWith("action")&&this.logEvents.actions||t.startsWith("selector")&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(t,(s=>{"update:complete"!==t||s.blocked||this.isTimeTraveling||this.recordStateSnapshot(s.deltas),"middleware:executed"===t?this.middlewareExecutions.push(s):"transaction:start"===t?this.activeTransactionCount++:"transaction:complete"!==t&&"transaction:error"!==t||(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),s.batchId&&(t.endsWith("start")?this.activeBatches.add(s.batchId):(t.endsWith("complete")||t.endsWith("error"))&&this.activeBatches.delete(s.batchId)),this.recordEvent(t,s),this.enableConsoleLogging&&e&&this._log(t,s),this._checkPerformance(t,s)})))}}recordStateSnapshot(e){const t={state:this.store.get(!0),timestamp:Date.now(),deltas:e};this.stateHistory.unshift(t),this.stateHistory.length>this.maxStateHistory&&this.stateHistory.pop()}recordEvent(e,t){const s={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(s),this.eventHistory.length>this.maxEvents&&this.eventHistory.pop()}getEventHistory(){return structuredClone(this.eventHistory)}getStateHistory(){return structuredClone(this.stateHistory)}getMiddlewareExecutions(){return this.middlewareExecutions}getTransactionStatus(){return{activeTransactions:this.activeTransactionCount,activeBatches:Array.from(this.activeBatches)}}createLoggingMiddleware(e={}){const{logLevel:t="debug",logUpdates:s=!0}=e;return(e,i)=>{if(s){(console[t]||console.log)("State Update:",i)}return i}}createValidationMiddleware(e){return(t,s)=>{const i=e(t,s);return"boolean"==typeof i?i:(!i.valid&&i.reason&&this._consoleLog("warn","Validation failed:",i.reason),i.valid)}}getRecentChanges(e=5){const t=[],s=Math.min(e,this.stateHistory.length);for(let e=0;e<s;e++){const s=this.stateHistory[e];if(!s.deltas||0===s.deltas.length)continue;const i={},r={},a=(e,t,s)=>{t.reduce(((e,i,r)=>(r===t.length-1?e[i]=s:e[i]=e[i]??{},e[i])),e)};for(const e of s.deltas){const t=e.path.split(".");a(i,t,e.oldValue),a(r,t,e.newValue)}t.push({timestamp:s.timestamp,changedPaths:s.deltas.map((e=>e.path)),from:i,to:r})}return t}clearHistory(){this.eventHistory=[],this.stateHistory.length>0&&(this.stateHistory=[this.stateHistory[0]])}getHistoryForAction(e){return this.eventHistory.filter((t=>t.data?.actionId===e))}async replay(e){const t=this.eventHistory.filter((e=>"update:start"===e.type))[e];t?.data.update?(this._consoleLog("log",`Replaying event at index ${e}:`,t),await this.store.set(t.data.update,{force:!0})):this._consoleLog("warn",`No replayable event found at index ${e}.`)}createTimeTravel(){let e=0,t=[];const s=this.store.on("update:complete",(s=>{this.isTimeTraveling||s.blocked||(t=[],e=0)}));this.unsubscribers.push(s);const i=()=>this.stateHistory.length,r=()=>e<i()-1,a=()=>t.length>0;return{canUndo:r,canRedo:a,undo:async()=>{if(!r())return;t.unshift(this.stateHistory[e]),e++;const s=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...s},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;const s=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...s.state},{force:!0}),this.isTimeTraveling=!1},length:i,clear:()=>{t=[],e=0}}}async saveSession(e){const t=this.store.id(),s={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,s))}async loadSession(e){const t=await Promise.resolve(e.get());return!!t&&(this.eventHistory=t.eventHistory||[],this.stateHistory=t.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),!0)}exportSession(){const e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),s=URL.createObjectURL(t),i=document.createElement("a");i.href=s,i.download=`store-observer-session-${(new Date).toISOString()}.json`,i.click(),URL.revokeObjectURL(s)}importSession(e){return new Promise(((t,s)=>{const i=new FileReader;i.onload=async e=>{try{const s=JSON.parse(e.target?.result);this.eventHistory=s.eventHistory||[],this.stateHistory=s.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){s(e)}},i.onerror=e=>s(e),i.readAsText(e)}))}disconnect(){this.unsubscribers.forEach((e=>e())),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){const s=new Date(t.timestamp||Date.now()).toISOString().split("T")[1].replace("Z","");if("update:start"===e)this._consoleLog("group",`%c⚡ Store Update Started [${s}]`,"color: #4a6da7");else if("update:complete"===e){if(t.blocked)this._consoleLog("warn",`%c✋ Update Blocked [${s}]`,"color: #bf8c0a",t.error);else{const e=t.deltas||[];e.length>0&&(this._consoleLog("log",`%c✅ Update Complete [${s}] - ${e.length} paths changed in ${t.duration?.toFixed(2)}ms`,"color: #2a9d8f"),this._consoleLog("table",e.map((e=>({path:e.path,oldValue:e.oldValue,newValue:e.newValue})))))}this._consoleLog("groupEnd")}else"middleware:start"===e?this._consoleLog("debug",`%c◀ Middleware "${t.name}" started [${s}] (${t.type})`,"color: #8c8c8c"):"middleware:complete"===e?this._consoleLog("debug",`%c▶ Middleware "${t.name}" completed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #7c9c7c"):"middleware:error"===e?this._consoleLog("error",`%c❌ Middleware "${t.name}" error [${s}]:`,"color: #e63946",t.error):"middleware:blocked"===e?this._consoleLog("warn",`%c🛑 Middleware "${t.name}" blocked update [${s}]`,"color: #e76f51"):"transaction:start"===e?this._consoleLog("group",`%c📦 Transaction Started [${s}]`,"color: #6d597a"):"transaction:complete"===e?(this._consoleLog("log",`%c📦 Transaction Complete [${s}]`,"color: #355070"),this._consoleLog("groupEnd")):"transaction:error"===e?(this._consoleLog("error",`%c📦 Transaction Error [${s}]:`,"color: #e56b6f",t.error),this._consoleLog("groupEnd")):"action:start"===e?this._consoleLog("group",`%c🚀 Action "${t.name}" Started [${s}]`,"color: #9b59b6",{params:t.params}):"action:complete"===e?(this._consoleLog("log",`%c✔️ Action "${t.name}" Complete [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #2ecc71"),this._consoleLog("groupEnd")):"action:error"===e?(this._consoleLog("error",`%c🔥 Action "${t.name}" Error [${s}]:`,"color: #e74c3c",t.error),this._consoleLog("groupEnd")):"selector:accessed"===e&&this._consoleLog("debug",`%c👀 Selector Accessed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #f1c40f",{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&("update:complete"===e&&!t.blocked&&t.duration>this.performanceThresholds.updateTime&&this._consoleLog("warn",`%c⚠️ Slow update detected [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{deltas:t.deltas,threshold:this.performanceThresholds.updateTime}),"middleware:complete"===e&&t.duration>this.performanceThresholds.middlewareTime&&this._consoleLog("warn",`%c⚠️ Slow middleware "${t.name}" [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{threshold:this.performanceThresholds.middlewareTime}))}},exports.UnknownActionError=T,exports.createDerivePaths=f,exports.createDiff=y,exports.createMerge=h,exports.derivePaths=v,exports.diff=w,exports.merge=u,exports.shallowClone=l;
package/index.mjs CHANGED
@@ -1 +1 @@
1
- import{v4 as e}from"uuid";var t=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},s=class extends t{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},i=class extends t{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},r=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,a)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),a(new s("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}},a=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new r({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new i};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new i;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},n=class{_open=!1;_resolve;_promise;constructor(){this._promise=new Promise((e=>{this._resolve=e}))}open(){this._open||(this._open=!0,this._resolve())}async wait(e){if(this._open)return;if(null==e)return this._promise;let t;await Promise.race([this._promise.then((()=>clearTimeout(t))),new Promise(((i,r)=>{t=setTimeout((()=>r(new s("Latch timed out"))),e)}))])}isOpen(){return this._open}},o=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise((t=>{this._enqueue(e,t)}))}fire(e){this._enqueue(e,void 0)}_enqueue(e,t){if(this._pendingFn=e,t&&this._pendingResolvers.push(t),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout((()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()}),this._delay));clearTimeout(this._timer),this._timer=setTimeout((()=>{this._leadingFired=!1,this._fire()}),this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const t of e)t({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,t=this._pendingResolvers.splice(0);let s;this._pendingFn=void 0;try{s={status:"ok",value:await e()}}catch(e){s={status:"error",error:e}}for(const e of t)e(s);return s}};function c(e){const t=e??{},{deferred:s,batchSize:i,batchDelay:r,errorHandler:a,broadcast:n,channel:c}={deferred:null!=t.batch?.size,batchSize:t.batch?.size,batchDelay:t.batch?.delay||16,errorHandler:t.errorHandler||(e=>console.error("EventBus Error:",e)),broadcast:null!=t.broadcast?.channel&&t.broadcast.channel.length>0,channel:null!=t.broadcast?.channel&&t.broadcast.channel.length>0?t.broadcast?.channel:"event-bus-channel"},d=new Map;let l=[],h=0,u=0;const p=new Map,m=()=>{if(!n)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(c);return e.onmessage=e=>{const{name:t,payload:s}=e.data;f(t,s)},e};let g=m();const y=(e,t)=>{h++,u+=t,p.set(e,(p.get(e)??0)+1)},f=(e,t)=>{const s=d.get(e);if(s&&0!==s.size)for(const i of Array.from(s))try{i(t)}catch(s){const i=s instanceof Error?s:Object.assign(new Error(String(s)),{cause:s}),r=Object.assign(i,{eventName:e,payload:t});a(r)}},w=()=>{const e=l;l=[];for(const{name:t,payload:s}of e){const e=performance.now();f(t,s),y(t,performance.now()-e)}},v=new o({delay:r});return{subscribe:(e,t)=>{d.has(e)||d.set(e,new Set);const s=d.get(e);return s.add(t),()=>{s.delete(t),0===s.size&&d.delete(e)}},once:(e,t)=>{let s;const i=e=>{s(),t(e)};return s=(()=>{d.has(e)||d.set(e,new Set);const t=d.get(e);return t.add(i),()=>{t.delete(i),0===t.size&&d.delete(e)}})(),s},emit:({name:e,payload:t})=>{if(s)return l.push({name:e,payload:t}),l.length>=i?(v.cancel(),void w()):(v.fire((()=>w())),void g?.postMessage({name:e,payload:t}));const r=performance.now();f(e,t),y(e,performance.now()-r),g?.postMessage({name:e,payload:t})},metrics:()=>({totalEvents:h,activeSubscriptions:Array.from(d.values()).reduce(((e,t)=>e+t.size),0),eventCounts:p,averageEmitDuration:h>0?u/h:0}),clear:()=>{d.clear(),l=[],v.cancel(),h=0,u=0,p.clear(),g?.close(),g=m()}}}var d=Symbol.for("delete"),l=e=>Array.isArray(e)?[...e]:{...e};function h(e){const t=e?.deleteMarker||d;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const i={};for(const[r,a]of Object.entries(e))if(a!==t)if("object"==typeof a&&null!==a){const e=s(a);void 0!==e&&(i[r]=e)}else i[r]=a;return i}return e===t?void 0:e}return function(e,i){if("object"!=typeof e||null===e)return"object"==typeof i&&null!==i?s(i):i===t?{}:i;if("object"!=typeof i||null===i)return e;const r=l(e),a=[{target:r,source:i}];for(;a.length>0;){const{target:e,source:s}=a.pop();for(const i of Object.keys(s)){const r=s[i];if(r!==t)if(Array.isArray(r))e[i]=r;else if("object"==typeof r&&null!==r){const t=i in e&&"object"==typeof e[i]&&null!==e[i]?e[i]:{};e[i]=l(t),a.push({target:e[i],source:r})}else e[i]=r;else delete e[i]}}return r}}var u=h(),p=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"],m=class{reactiveSelectors=new Map;reactiveSelectorCache=new WeakMap;pathBasedCache=new Map;dependencyMap=new Map;getState;eventBus;unsubscribeFromStore;constructor(e,t){this.getState=e,this.eventBus=t,this.unsubscribeFromStore=this.eventBus.subscribe("update:complete",this.handleStoreUpdate)}handleStoreUpdate=e=>{const t=new Set;for(const s of e.deltas){const e=s.path;for(const[s,i]of this.dependencyMap)if(s===e||s.startsWith(e+".")||e.startsWith(s+"."))for(const e of i)t.add(e)}t.forEach((e=>{const t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}))};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}t!==e.lastResult&&(e.lastResult=t,e.subscribers.forEach((e=>e(t))),this.eventBus.emit({name:"selector:changed",payload:{selectorId:e.id,newResult:t,timestamp:performance.now()}}))}createReactiveSelector(e){const t=this.reactiveSelectorCache.get(e);if(t)return t;const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const a=new Proxy((()=>{}),{get:(i,a)=>{if("symbol"==typeof a||"then"===a)return;if("valueOf"===a||"toString"===a)throw new Error("Cannot perform logic/math/string operations inside a selector.");if(p.includes(a))throw new Error(`Array method .${a}() is not allowed in selectors.`);const n=e?`${e}${t}${a}`:a;return e&&s.delete(e),s.add(n),r(n)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions/methods.")}});return i.set(e,a),a};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. This usually means the selector is too complex. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e),i=`${[...s].sort().join("|")}::${e.toString()}`,r=this.pathBasedCache.get(i);if(r)return this.reactiveSelectorCache.set(e,r),r;const a=`sel-${Math.random().toString(36).slice(2,9)}`,n=e(this.getState()),o={id:a,selector:e,lastResult:n,accessedPaths:s,subscribers:new Set,reactiveSelectorInstance:null};s.forEach((e=>{this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(a)}));const c={get:()=>o.lastResult,id:a,subscribe:t=>(o.subscribers.add(t),()=>{o.subscribers.delete(t),0===o.subscribers.size&&this.cleanupSelector(a,e,i)})};return o.reactiveSelectorInstance=c,this.reactiveSelectors.set(a,o),this.reactiveSelectorCache.set(e,c),this.pathBasedCache.set(i,c),this.eventBus.emit({name:"selector:accessed",payload:{selectorId:a,accessedPaths:s,duration:0,timestamp:performance.now()}}),c}cleanupSelector(e,t,s){const i=this.reactiveSelectors.get(e);i&&(i.accessedPaths.forEach((t=>{this.dependencyMap.get(t)?.delete(e),0===this.dependencyMap.get(t)?.size&&this.dependencyMap.delete(t)})),this.reactiveSelectors.delete(e),this.reactiveSelectorCache.delete(t),this.pathBasedCache.delete(s))}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function g(e,t){if(e===t)return!0;if(e&&t&&"object"==typeof e&&"object"==typeof t){if(e.constructor!==t.constructor)return!1;let s,i;if(Array.isArray(e)){if(s=e.length,s!=t.length)return!1;for(i=s;i-- >0;)if(!g(e[i],t[i]))return!1;return!0}const[r,a]=[Object.keys(e),Object.keys(t)];if(s=r.length,s!==a.length)return!1;for(i=s;i-- >0;){const s=r[i];if(!Object.prototype.hasOwnProperty.call(t,s)||!g(e[s],t[s]))return!1}return!0}return e!=e&&t!=t}function y(e){const t=e?.deleteMarker||d;return function(e,s){const i=[],r=[{pathStr:"",orig:e||{},part:s||{}}];for(;r.length>0;){const{pathStr:e,orig:s,part:a}=r.pop();if(null!=a&&!g(s,a))if("object"!=typeof a||Array.isArray(a))e&&i.push({path:e,oldValue:s,newValue:a});else for(const n of Object.keys(a)){const o=e?e+"."+n:n,c=a[n],d=s&&"object"==typeof s?s[n]:void 0;c!==t?"object"==typeof c&&null!==c?r.push({pathStr:o,orig:d,part:c}):g(d,c)||i.push({path:o,oldValue:d,newValue:c}):void 0!==d&&i.push({path:o,oldValue:d,newValue:void 0})}}return i}}function f(e){const t=e?.deleteMarker||d;return function(e){const s=new Set,i=[{obj:e,currentPath:""}];for(;i.length>0;){const{obj:e,currentPath:r}=i.pop();if(null!=e&&"object"==typeof e&&!Array.isArray(e))for(const a of Object.keys(e)){const n=r?`${r}.${a}`:a;s.add(n);const o=e[a];"object"!=typeof o||null===o||Array.isArray(o)||o===t||i.push({obj:o,currentPath:n})}}return Array.from(s)}}var w=y(),v=f(),b=class{constructor(e,t,s){this.updateBus=t,this.diff=s,this.cache=structuredClone(e)}cache;get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,s=!1,i=[]){if(t)return this.cache=s?structuredClone(e):e,this.notifyListeners([]),[];0===i.length&&(i=[e]);const r=this.get(!1),a=new Map;for(let e=0;e<i.length;e++){const t=i[e],s=this.diff(r,t);for(let e=0;e<s.length;e++){const t=s[e];a.set(t.path,t)}}const n=a.size?[...a.values()]:[];if(n.length>0){this.cache=s?structuredClone(e):e;const t=new Set;for(let e=0;e<n.length;e++){let s=n[e].path;for(;s&&!t.has(s);){t.add(s);const e=s.lastIndexOf(".");if(e<0)break;s=s.slice(0,e)}}this.notifyListeners(t)}return n}notifyListeners(e){for(const t of e)this.updateBus.emit({name:"update",payload:t})}},S=class{constructor(e,t,s){this.eventBus=e,this.executionState=t,this.merge=s}middleware=[];blockingMiddleware=[];async executeBlocking(e,t){for(const{fn:s,name:i,id:r}of this.blockingMiddleware){const a={id:r,name:i,startTime:performance.now()};this.executionState.runningMiddleware={id:r,name:i,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:r,name:i,type:"blocking"});try{const n=await Promise.resolve(s(e,t));if(a.endTime=performance.now(),a.duration=a.endTime-a.startTime,!1===n)return a.blocked=!0,this.emitMiddlewareLifecycle("blocked",{id:r,name:i,duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0};this.emitMiddlewareLifecycle("complete",{id:r,name:i,type:"blocking",duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:{...a,blocked:!1}})}catch(e){return a.endTime=performance.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:new Error(String(e)),a.blocked=!0,this.emitMiddlewareError(r,i,a.error,a.duration),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0,error:a.error}}finally{this.executionState.runningMiddleware=null}}return{blocked:!1}}async executeTransform(e,t){let s=e,i=t;for(const{fn:e,name:r,id:a}of this.middleware){const n={id:a,name:r,startTime:performance.now()};this.executionState.runningMiddleware={id:a,name:r,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:a,name:r,type:"transform"});try{const o=await Promise.resolve(e(s,t));n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.blocked=!1,o&&"object"==typeof o&&(s=this.merge(s,o),i=this.merge(i,o)),this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareLifecycle("complete",{id:a,name:r,type:"transform",duration:n.duration})}catch(e){n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.error=e instanceof Error?e:new Error(String(e)),n.blocked=!1,this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareError(a,r,n.error,n.duration),console.error(`Middleware ${r} error:`,e)}finally{this.executionState.runningMiddleware=null}}return i}addMiddleware(e,t="unnamed-middleware"){const s=this.generateId();return this.middleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}addBlockingMiddleware(e,t="unnamed-blocking-middleware"){const s=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}removeMiddleware(e){const t=this.middleware.length+this.blockingMiddleware.length;return this.middleware=this.middleware.filter((t=>t.id!==e)),this.blockingMiddleware=this.blockingMiddleware.filter((t=>t.id!==e)),this.updateExecutionState(),this.middleware.length+this.blockingMiddleware.length<t}updateExecutionState(){this.executionState.middlewares=[...this.middleware.map((e=>e.name)),...this.blockingMiddleware.map((e=>e.name))]}emitMiddlewareLifecycle(e,t){this.emit(this.eventBus,{name:`middleware:${e}`,payload:{...t,timestamp:Date.now()}})}emitMiddlewareError(e,t,s,i){this.emit(this.eventBus,{name:"middleware:error",payload:{id:e,name:t,error:s,duration:i,timestamp:Date.now()}})}generateId(){return crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).substring(2,15)}`}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},_=class{constructor(e,t,s,i){this.eventBus=e,this.coreState=t,this.instanceID=s,this.maxRetries=i?.maxRetries??3,this.retryDelay=i?.retryDelay??1e3}persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||0===e.length)return;const s={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(s),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:"persistence:queued",payload:{taskId:s.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:s.timestamp}})}getQueueStatus(){return{queueSize:this.backgroundQueue.length,isProcessing:this.isProcessingQueue,pendingRetries:this.pendingRetries.size,oldestTask:this.backgroundQueue[0]?.timestamp}}async flush(){this.isProcessingQueue&&await new Promise((e=>{const t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()})),await this.processQueue()}discardQueue(){const e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&(clearTimeout(this.queueProcessor),this.queueProcessor=void 0),this.emit(this.eventBus,{name:"persistence:queue_cleared",payload:{clearedTasks:e,timestamp:Date.now()}})}scheduleQueueProcessing(){this.queueProcessor||this.isProcessingQueue||(this.queueProcessor=setTimeout((()=>{this.processQueue().catch((e=>{console.error("Queue processing failed:",e)}))}),10))}async processQueue(){if(!this.isProcessingQueue&&0!==this.backgroundQueue.length){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){const e=this.backgroundQueue.shift();await this.processTask(e)}}finally{this.isProcessingQueue=!1}}}async processTask(e){try{await this.persistence.set(this.instanceID,e.state)?this.emit(this.eventBus,{name:"persistence:success",payload:{taskId:e.id,changedPaths:e.changedPaths,duration:Date.now()-e.timestamp,timestamp:Date.now()}}):await this.handleTaskFailure(e,new Error("Persistence returned false"))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){const s=this.retryDelay*Math.pow(2,e.retries-1);this.emit(this.eventBus,{name:"persistence:retry",payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:s,error:t,timestamp:Date.now()}}),this.pendingRetries.add(e.id),setTimeout((()=>{this.pendingRetries.has(e.id)&&(this.pendingRetries.delete(e.id),this.backgroundQueue.unshift(e),this.scheduleQueueProcessing())}),s)}else this.emit(this.eventBus,{name:"persistence:failed",payload:{taskId:e.id,changedPaths:e.changedPaths,attempts:e.retries,error:t,timestamp:Date.now()}})}setPersistenceReady(){this.persistenceReady=!0,this.emit(this.eventBus,{name:"persistence:ready",payload:{timestamp:Date.now()}})}async setPersistence(e){this.persistence=e;try{const e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){console.error("Failed to initialize persistence:",e),this.emit(this.eventBus,{name:"persistence:init_error",payload:{error:e,timestamp:Date.now()}})}finally{this.setPersistenceReady()}this.persistence.subscribe(this.instanceID,(async e=>{const t=this.coreState.applyChanges(e);t.length>0&&this.emit(this.eventBus,{name:"update:complete",payload:{changedPaths:t,source:"external",timestamp:Date.now()}})}))}dispose(){this.discardQueue(),this.isProcessingQueue=!1,this.persistenceReady=!1}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},E=class{constructor(e,t,s){this.eventBus=e,this.coreState=t,this.executionState=s}async execute(e){const t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:"transaction:start",payload:{timestamp:Date.now()}});try{const t=await Promise.resolve(e());return this.emit(this.eventBus,{name:"transaction:complete",payload:{timestamp:Date.now()}}),this.executionState.transactionActive=!1,t}catch(e){throw this.coreState.applyChanges(t,!0,!1),this.emit(this.eventBus,{name:"transaction:error",payload:{error:e instanceof Error?e:new Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},x=class{updateCount=0;listenerExecutions=0;averageUpdateTime=0;largestUpdateSize=0;mostActiveListenerPaths=[];totalUpdates=0;blockedUpdates=0;averageUpdateDuration=0;middlewareExecutions=0;transactionCount=0;totalEventsFired=0;totalActionsDispatched=0;totalActionsSucceeded=0;totalActionsFailed=0;averageActionDuration=0;updateTimes=[];actionTimes=[];pathExecutionCounts=new Map;constructor(e){this.setupEventListeners(e)}getMetrics(){return{updateCount:this.updateCount,listenerExecutions:this.listenerExecutions,averageUpdateTime:this.averageUpdateTime,largestUpdateSize:this.largestUpdateSize,mostActiveListenerPaths:[...this.mostActiveListenerPaths],totalUpdates:this.totalUpdates,blockedUpdates:this.blockedUpdates,averageUpdateDuration:this.averageUpdateDuration,middlewareExecutions:this.middlewareExecutions,transactionCount:this.transactionCount,totalEventsFired:this.totalEventsFired,totalActionsDispatched:this.totalActionsDispatched,totalActionsSucceeded:this.totalActionsSucceeded,totalActionsFailed:this.totalActionsFailed,averageActionDuration:this.averageActionDuration}}setupEventListeners(e){const t=e.emit;e.emit=s=>(this.totalEventsFired++,t.call(e,s)),e.subscribe("update:complete",(e=>{if(this.totalUpdates++,e.blocked)this.blockedUpdates++;else{if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();const t=this.updateTimes.reduce(((e,t)=>e+t),0)/this.updateTimes.length;this.averageUpdateTime=t,this.averageUpdateDuration=t}e.deltas?.length&&(this.updateCount++,this.largestUpdateSize=Math.max(this.largestUpdateSize,e.deltas.length),e.deltas.forEach((e=>{const t=this.pathExecutionCounts.get(e.path)||0;this.pathExecutionCounts.set(e.path,t+1)})),this.mostActiveListenerPaths=Array.from(this.pathExecutionCounts.entries()).sort((([,e],[,t])=>t-e)).slice(0,5).map((([e])=>e)))}})),e.subscribe("middleware:start",(()=>{this.middlewareExecutions++})),e.subscribe("transaction:start",(()=>{this.transactionCount++})),e.subscribe("action:start",(()=>{this.totalActionsDispatched++})),e.subscribe("action:complete",(e=>{this.totalActionsSucceeded++,e.duration&&(this.actionTimes.push(e.duration),this.actionTimes.length>100&&this.actionTimes.shift(),this.averageActionDuration=this.actionTimes.reduce(((e,t)=>e+t),0)/this.actionTimes.length)})),e.subscribe("action:error",(()=>{this.totalActionsFailed++}))}reset(){this.updateCount=0,this.listenerExecutions=0,this.averageUpdateTime=0,this.largestUpdateSize=0,this.mostActiveListenerPaths=[],this.totalUpdates=0,this.blockedUpdates=0,this.averageUpdateDuration=0,this.middlewareExecutions=0,this.transactionCount=0,this.totalEventsFired=0,this.totalActionsDispatched=0,this.totalActionsSucceeded=0,this.totalActionsFailed=0,this.averageActionDuration=0,this.updateTimes=[],this.actionTimes=[],this.pathExecutionCounts.clear()}getDetailedMetrics(){return{pathExecutionCounts:new Map(this.pathExecutionCounts),recentUpdateTimes:[...this.updateTimes],successRate:this.totalUpdates>0?(this.totalUpdates-this.blockedUpdates)/this.totalUpdates:1,averagePathsPerUpdate:this.updateCount>0?Array.from(this.pathExecutionCounts.values()).reduce(((e,t)=>e+t),0)/this.updateCount:0}}dispose(){this.reset()}},k=class extends Error{constructor(){super("Action Cancelled by Debounce"),this.name="ActionCancelledError"}},T=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name="UnknownActionError"}},M=class{constructor(e,t){this.eventBus=e,this.set=t}registrations=new Map;register(t){const s={action:{name:t.name,id:e(),action:t.fn,debounce:t.debounce?{...t.debounce,condition:t.debounce.condition??(()=>!0)}:void 0},debouncer:t.debounce&&t.debounce.delay>0?new o({delay:t.debounce.delay}):void 0,previousArgs:void 0};return this.registrations.set(t.name,s),()=>{const e=this.registrations.get(t.name);e&&(e.debouncer?.cancel(),this.registrations.delete(t.name))}}async dispatch(e,...t){const s=this.registrations.get(e);if(!s)throw new T({action:e});const{action:i,debouncer:r}=s,{id:a,action:n,debounce:o}=i;if(!r||!o)return this.executeAction(e,a,n,t);const c=o.condition(s.previousArgs,t);if(s.previousArgs=t,!c)return this.executeAction(e,a,n,t);const d=await r.do((()=>this.executeAction(e,a,n,t)));if("cancelled"===d.status)throw new k;if("error"===d.status&&d.error)throw d.error;return d.value}async executeAction(e,t,s,i){const r=performance.now();this.emit(this.eventBus,{name:"action:start",payload:{actionId:t,name:e,params:i||[],timestamp:r}});try{const a=await this.set((e=>s(e,...i)),{actionId:t}),n=performance.now();return this.emit(this.eventBus,{name:"action:complete",payload:{actionId:t,name:e,params:i,startTime:r,endTime:n,duration:n-r,result:a}}),a}catch(s){const a=performance.now();throw this.emit(this.eventBus,{name:"action:error",payload:{actionId:t,name:e,params:i,startTime:r,endTime:a,duration:a-r,error:s}}),s}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},C=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new a({yieldMode:"macrotask",capacity:1e3});readyLatch=new n;updateBus=c();eventBus;executionState;instanceID=e();merge;diff;constructor(e,t,s=d,i,r={errorHandler:()=>{}}){this.eventBus=c(r),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=h({deleteMarker:s}),this.diff=y({deleteMarker:s}),this.coreState=new b(e,this.updateBus,this.diff),this.middlewareEngine=new S(this.eventBus,this.executionState,this.merge),this.persistenceHandler=new _(this.eventBus,this.coreState,this.instanceID,{maxRetries:i?.persistenceMaxRetries,retryDelay:i?.persistenceRetryDelay}),this.transactionManager=new E(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new x(this.eventBus),this.actions=new M(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(t),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new m(this.get.bind(this),this.eventBus)}isReady(){return this.readyLatch.isOpen()}async ready(e){return this.readyLatch.wait(e)}state(){return this.executionState.executing=this.updateSerializer.running(),this.executionState}get(e){return this.coreState.get(e??!1)}select(e){return this.selectorManager.createReactiveSelector(e)}register(e){return this.actions.register(e)}async dispatch(e,...t){return this.actions.dispatch(e,...t)}async set(e,t={}){const s=await this.updateSerializer.do((()=>this._performUpdate(e,t)));if(s.error)throw s.error;return s.value}async _performUpdate(e,t){const s=performance.now();this.emit(this.eventBus,{name:"update:start",payload:{timestamp:s,actionId:t.actionId}});try{if(t.force){const i=this.get(!1),r="function"==typeof e?e(i):e;this.coreState.applyChanges(r,!0);const a=performance.now();return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:[],duration:a-s,timestamp:Date.now(),actionId:t.actionId,newState:r}}),r}let i;const r=this.get(!1);if("function"==typeof e){const t=e(r);i=t instanceof Promise?await t:t}else i=e;const a=await this.middlewareEngine.executeBlocking(r,i);if(a.blocked)throw a.error||new Error("Update blocked by middleware");const n=this.merge(r,i),o=await this.middlewareEngine.executeTransform(n,i),c=this.merge(n,o),d=this.coreState.applyChanges(c,!1,!1,[i,o]),l=performance.now(),h=this.get(!1);return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:d,duration:l-s,timestamp:Date.now(),actionId:t.actionId,newState:h}}),h}catch(e){throw this.emit(this.eventBus,{name:"update:complete",payload:{blocked:!0,error:e,timestamp:Date.now(),actionId:t.actionId,newState:this.get(!1)}}),e}finally{this.executionState.executing=!1,this.executionState.changes=null,this.executionState.runningMiddleware=null,this.executionState.pendingChanges=[]}}setupReadyLatch(){this.eventBus.subscribe("persistence:ready",(()=>{this.readyLatch.open()})),this.persistenceHandler.isReady()?this.readyLatch.open():queueMicrotask((()=>{this.readyLatch.isOpen()||this.readyLatch.open()}))}setupPersistenceListener(){this.updateBus.subscribe("update",(e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))}))}watch(e,t){const s=Array.isArray(e)?e:[e],i=""===e||0===s.length;return this.updateBus.subscribe("update",(e=>{(i||s.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)}))}debouncedSetter(e){const t=new o({delay:e.delay,leading:e.leading});return(e,s={})=>{t.fire((()=>this.set(e,s)))}}subscribe(e,t){return this.watch(e,t)}id(){return this.instanceID}async transaction(e){return this.transactionManager.execute(e)}use(e){const t=(e.block?this.middlewareEngine.addBlockingMiddleware:this.middlewareEngine.addMiddleware).bind(this.middlewareEngine)(e.action,e.name);return()=>this.middlewareEngine.removeMiddleware(t)}metrics(){return this.metricsCollector.getMetrics()}on(e,t){return this.eventBus.subscribe(e,t)}onStoreEvent(e,t){return this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flushPersistence(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){this.updateSerializer.close(),this.persistenceHandler.dispose(),this.metricsCollector.dispose?.(),this.selectorManager.dispose?.()}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},P=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;constructor(e,t={}){this.store=e,this.maxEvents=t.maxEvents??500,this.maxStateHistory=t.maxStateHistory??20,this.enableConsoleLogging=t.enableConsoleLogging??!1,this.isSilent=t.silent??!1,this.logEvents={updates:t.logEvents?.updates??!0,middleware:t.logEvents?.middleware??!0,transactions:t.logEvents?.transactions??!0,actions:t.logEvents?.actions??!0,selectors:t.logEvents?.selectors??!0},this.performanceThresholds={updateTime:t.performanceThresholds?.updateTime??50,middlewareTime:t.performanceThresholds?.middlewareTime??20},this.recordStateSnapshot([]),this.setupEventListeners()}_consoleLog(e,...t){this.isSilent||"function"==typeof console[e]&&console[e](...t)}setupEventListeners(){const e=["update:start","update:complete","middleware:start","middleware:complete","middleware:error","middleware:blocked","transaction:start","transaction:complete","transaction:error","middleware:executed","action:start","action:complete","action:error","selector:accessed"];for(const t of e){const e=t.startsWith("update")&&this.logEvents.updates||t.startsWith("middleware")&&this.logEvents.middleware||t.startsWith("transaction")&&this.logEvents.transactions||t.startsWith("action")&&this.logEvents.actions||t.startsWith("selector")&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(t,(s=>{"update:complete"!==t||s.blocked||this.isTimeTraveling||this.recordStateSnapshot(s.deltas),"middleware:executed"===t?this.middlewareExecutions.push(s):"transaction:start"===t?this.activeTransactionCount++:"transaction:complete"!==t&&"transaction:error"!==t||(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),s.batchId&&(t.endsWith("start")?this.activeBatches.add(s.batchId):(t.endsWith("complete")||t.endsWith("error"))&&this.activeBatches.delete(s.batchId)),this.recordEvent(t,s),this.enableConsoleLogging&&e&&this._log(t,s),this._checkPerformance(t,s)})))}}recordStateSnapshot(e){const t={state:this.store.get(!0),timestamp:Date.now(),deltas:e};this.stateHistory.unshift(t),this.stateHistory.length>this.maxStateHistory&&this.stateHistory.pop()}recordEvent(e,t){const s={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(s),this.eventHistory.length>this.maxEvents&&this.eventHistory.pop()}getEventHistory(){return structuredClone(this.eventHistory)}getStateHistory(){return structuredClone(this.stateHistory)}getMiddlewareExecutions(){return this.middlewareExecutions}getTransactionStatus(){return{activeTransactions:this.activeTransactionCount,activeBatches:Array.from(this.activeBatches)}}createLoggingMiddleware(e={}){const{logLevel:t="debug",logUpdates:s=!0}=e;return(e,i)=>{if(s){(console[t]||console.log)("State Update:",i)}return i}}createValidationMiddleware(e){return(t,s)=>{const i=e(t,s);return"boolean"==typeof i?i:(!i.valid&&i.reason&&this._consoleLog("warn","Validation failed:",i.reason),i.valid)}}getRecentChanges(e=5){const t=[],s=Math.min(e,this.stateHistory.length);for(let e=0;e<s;e++){const s=this.stateHistory[e];if(!s.deltas||0===s.deltas.length)continue;const i={},r={},a=(e,t,s)=>{t.reduce(((e,i,r)=>(r===t.length-1?e[i]=s:e[i]=e[i]??{},e[i])),e)};for(const e of s.deltas){const t=e.path.split(".");a(i,t,e.oldValue),a(r,t,e.newValue)}t.push({timestamp:s.timestamp,changedPaths:s.deltas.map((e=>e.path)),from:i,to:r})}return t}clearHistory(){this.eventHistory=[],this.stateHistory.length>0&&(this.stateHistory=[this.stateHistory[0]])}getHistoryForAction(e){return this.eventHistory.filter((t=>t.data?.actionId===e))}async replay(e){const t=this.eventHistory.filter((e=>"update:start"===e.type))[e];t?.data.update?(this._consoleLog("log",`Replaying event at index ${e}:`,t),await this.store.set(t.data.update,{force:!0})):this._consoleLog("warn",`No replayable event found at index ${e}.`)}createTimeTravel(){let e=0,t=[];const s=this.store.on("update:complete",(s=>{this.isTimeTraveling||s.blocked||(t=[],e=0)}));this.unsubscribers.push(s);const i=()=>this.stateHistory.length,r=()=>e<i()-1,a=()=>t.length>0;return{canUndo:r,canRedo:a,undo:async()=>{if(!r())return;t.unshift(this.stateHistory[e]),e++;const s=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...s},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;const s=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...s.state},{force:!0}),this.isTimeTraveling=!1},length:i,clear:()=>{t=[],e=0}}}async saveSession(e){const t=this.store.id(),s={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,s))}async loadSession(e){const t=await Promise.resolve(e.get());return!!t&&(this.eventHistory=t.eventHistory||[],this.stateHistory=t.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),!0)}exportSession(){const e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),s=URL.createObjectURL(t),i=document.createElement("a");i.href=s,i.download=`store-observer-session-${(new Date).toISOString()}.json`,i.click(),URL.revokeObjectURL(s)}importSession(e){return new Promise(((t,s)=>{const i=new FileReader;i.onload=async e=>{try{const s=JSON.parse(e.target?.result);this.eventHistory=s.eventHistory||[],this.stateHistory=s.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){s(e)}},i.onerror=e=>s(e),i.readAsText(e)}))}disconnect(){this.unsubscribers.forEach((e=>e())),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){const s=new Date(t.timestamp||Date.now()).toISOString().split("T")[1].replace("Z","");if("update:start"===e)this._consoleLog("group",`%c⚡ Store Update Started [${s}]`,"color: #4a6da7");else if("update:complete"===e){if(t.blocked)this._consoleLog("warn",`%c✋ Update Blocked [${s}]`,"color: #bf8c0a",t.error);else{const e=t.deltas||[];e.length>0&&(this._consoleLog("log",`%c✅ Update Complete [${s}] - ${e.length} paths changed in ${t.duration?.toFixed(2)}ms`,"color: #2a9d8f"),this._consoleLog("table",e.map((e=>({path:e.path,oldValue:e.oldValue,newValue:e.newValue})))))}this._consoleLog("groupEnd")}else"middleware:start"===e?this._consoleLog("debug",`%c◀ Middleware "${t.name}" started [${s}] (${t.type})`,"color: #8c8c8c"):"middleware:complete"===e?this._consoleLog("debug",`%c▶ Middleware "${t.name}" completed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #7c9c7c"):"middleware:error"===e?this._consoleLog("error",`%c❌ Middleware "${t.name}" error [${s}]:`,"color: #e63946",t.error):"middleware:blocked"===e?this._consoleLog("warn",`%c🛑 Middleware "${t.name}" blocked update [${s}]`,"color: #e76f51"):"transaction:start"===e?this._consoleLog("group",`%c📦 Transaction Started [${s}]`,"color: #6d597a"):"transaction:complete"===e?(this._consoleLog("log",`%c📦 Transaction Complete [${s}]`,"color: #355070"),this._consoleLog("groupEnd")):"transaction:error"===e?(this._consoleLog("error",`%c📦 Transaction Error [${s}]:`,"color: #e56b6f",t.error),this._consoleLog("groupEnd")):"action:start"===e?this._consoleLog("group",`%c🚀 Action "${t.name}" Started [${s}]`,"color: #9b59b6",{params:t.params}):"action:complete"===e?(this._consoleLog("log",`%c✔️ Action "${t.name}" Complete [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #2ecc71"),this._consoleLog("groupEnd")):"action:error"===e?(this._consoleLog("error",`%c🔥 Action "${t.name}" Error [${s}]:`,"color: #e74c3c",t.error),this._consoleLog("groupEnd")):"selector:accessed"===e&&this._consoleLog("debug",`%c👀 Selector Accessed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #f1c40f",{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&("update:complete"===e&&!t.blocked&&t.duration>this.performanceThresholds.updateTime&&this._consoleLog("warn",`%c⚠️ Slow update detected [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{deltas:t.deltas,threshold:this.performanceThresholds.updateTime}),"middleware:complete"===e&&t.duration>this.performanceThresholds.middlewareTime&&this._consoleLog("warn",`%c⚠️ Slow middleware "${t.name}" [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{threshold:this.performanceThresholds.middlewareTime}))}};export{k as ActionCancelledError,M as ActionManager,d as DELETE_SYMBOL,C as ReactiveDataStore,P as StoreObserver,T as UnknownActionError,f as createDerivePaths,y as createDiff,h as createMerge,v as derivePaths,w as diff,u as merge,l as shallowClone};
1
+ import{v4 as e}from"uuid";var t=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},s=class extends t{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},i=class extends t{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},r=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,a)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),a(new s("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}},a=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new r({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new i};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new i;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},n=class{_open=!1;_resolve;_promise;constructor(){this._promise=new Promise((e=>{this._resolve=e}))}open(){this._open||(this._open=!0,this._resolve())}async wait(e){if(this._open)return;if(null==e)return this._promise;let t;await Promise.race([this._promise.then((()=>clearTimeout(t))),new Promise(((i,r)=>{t=setTimeout((()=>r(new s("Latch timed out"))),e)}))])}isOpen(){return this._open}},o=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise((t=>{this._enqueue(e,t)}))}fire(e){this._enqueue(e,void 0)}_enqueue(e,t){if(this._pendingFn=e,t&&this._pendingResolvers.push(t),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout((()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()}),this._delay));clearTimeout(this._timer),this._timer=setTimeout((()=>{this._leadingFired=!1,this._fire()}),this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const t of e)t({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,t=this._pendingResolvers.splice(0);let s;this._pendingFn=void 0;try{s={status:"ok",value:await e()}}catch(e){s={status:"error",error:e}}for(const e of t)e(s);return s}};function c(e){const t=e??{},{deferred:s,batchSize:i,batchDelay:r,errorHandler:a,broadcast:n,channel:c}={deferred:null!=t.batch?.size,batchSize:t.batch?.size,batchDelay:t.batch?.delay||16,errorHandler:t.errorHandler||(e=>console.error("EventBus Error:",e)),broadcast:null!=t.broadcast?.channel&&t.broadcast.channel.length>0,channel:null!=t.broadcast?.channel&&t.broadcast.channel.length>0?t.broadcast?.channel:"event-bus-channel"},d=new Map;let l=[],h=0,u=0;const p=new Map,m=()=>{if(!n)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(c);return e.onmessage=e=>{const{name:t,payload:s}=e.data;f(t,s)},e};let g=m();const y=(e,t)=>{h++,u+=t,p.set(e,(p.get(e)??0)+1)},f=(e,t)=>{const s=d.get(e);if(s&&0!==s.size)for(const i of Array.from(s))try{i(t)}catch(s){const i=s instanceof Error?s:Object.assign(new Error(String(s)),{cause:s}),r=Object.assign(i,{eventName:e,payload:t});a(r)}},w=()=>{const e=l;l=[];for(const{name:t,payload:s}of e){const e=performance.now();f(t,s),y(t,performance.now()-e)}},v=new o({delay:r});return{subscribe:(e,t)=>{d.has(e)||d.set(e,new Set);const s=d.get(e);return s.add(t),()=>{s.delete(t),0===s.size&&d.delete(e)}},once:(e,t)=>{let s;const i=e=>{s(),t(e)};return s=(()=>{d.has(e)||d.set(e,new Set);const t=d.get(e);return t.add(i),()=>{t.delete(i),0===t.size&&d.delete(e)}})(),s},emit:({name:e,payload:t})=>{if(s)return l.push({name:e,payload:t}),l.length>=i?(v.cancel(),void w()):(v.fire((()=>w())),void g?.postMessage({name:e,payload:t}));const r=performance.now();f(e,t),y(e,performance.now()-r),g?.postMessage({name:e,payload:t})},metrics:()=>({totalEvents:h,activeSubscriptions:Array.from(d.values()).reduce(((e,t)=>e+t.size),0),eventCounts:p,averageEmitDuration:h>0?u/h:0}),clear:()=>{d.clear(),l=[],v.cancel(),h=0,u=0,p.clear(),g?.close(),g=m()}}}var d=Symbol.for("delete"),l=e=>Array.isArray(e)?[...e]:{...e};function h(e){const t=e?.deleteMarker||d;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const i={};for(const[r,a]of Object.entries(e))if(a!==t)if("object"==typeof a&&null!==a){const e=s(a);void 0!==e&&(i[r]=e)}else i[r]=a;return i}return e===t?void 0:e}return function(e,i){if("object"!=typeof e||null===e)return"object"==typeof i&&null!==i?s(i):i===t?{}:i;if("object"!=typeof i||null===i)return e;const r=l(e),a=[{target:r,source:i}];for(;a.length>0;){const{target:e,source:s}=a.pop();for(const i of Object.keys(s)){const r=s[i];if(r!==t)if(Array.isArray(r))e[i]=r;else if("object"==typeof r&&null!==r){const t=i in e&&"object"==typeof e[i]&&null!==e[i]?e[i]:{};e[i]=l(t),a.push({target:e[i],source:r})}else e[i]=r;else delete e[i]}}return r}}var u=h(),p=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"],m=class{reactiveSelectors=new Map;reactiveSelectorCache=new WeakMap;pathBasedCache=new Map;dependencyMap=new Map;getState;eventBus;unsubscribeFromStore;constructor(e,t){this.getState=e,this.eventBus=t,this.unsubscribeFromStore=this.eventBus.subscribe("update:complete",this.handleStoreUpdate)}handleStoreUpdate=e=>{const t=new Set;for(const s of e.deltas){const e=s.path;for(const[s,i]of this.dependencyMap)if(s===e||s.startsWith(e+".")||e.startsWith(s+"."))for(const e of i)t.add(e)}t.forEach((e=>{const t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}))};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}t!==e.lastResult&&(e.lastResult=t,e.subscribers.forEach((e=>e(t))),this.eventBus.emit({name:"selector:changed",payload:{selectorId:e.id,newResult:t,timestamp:performance.now()}}))}createReactiveSelector(e){const t=this.reactiveSelectorCache.get(e);if(t)return t;const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const a=new Proxy((()=>{}),{get:(i,a)=>{if("symbol"==typeof a||"then"===a)return;if("valueOf"===a||"toString"===a)throw new Error("Cannot perform logic/math/string operations inside a selector.");if(p.includes(a))throw new Error(`Array method .${a}() is not allowed in selectors.`);const n=e?`${e}${t}${a}`:a;return e&&s.delete(e),s.add(n),r(n)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions/methods.")}});return i.set(e,a),a};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. This usually means the selector is too complex. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e),i=`${[...s].sort().join("|")}::${e.toString()}`,r=this.pathBasedCache.get(i);if(r)return this.reactiveSelectorCache.set(e,r),r;const a=`sel-${Math.random().toString(36).slice(2,9)}`,n=e(this.getState()),o={id:a,selector:e,lastResult:n,accessedPaths:s,subscribers:new Set,reactiveSelectorInstance:null};s.forEach((e=>{this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(a)}));const c={get:()=>o.lastResult,id:a,subscribe:t=>(o.subscribers.add(t),()=>{o.subscribers.delete(t),0===o.subscribers.size&&this.cleanupSelector(a,e,i)})};return o.reactiveSelectorInstance=c,this.reactiveSelectors.set(a,o),this.reactiveSelectorCache.set(e,c),this.pathBasedCache.set(i,c),this.eventBus.emit({name:"selector:accessed",payload:{selectorId:a,accessedPaths:s,duration:0,timestamp:performance.now()}}),c}cleanupSelector(e,t,s){const i=this.reactiveSelectors.get(e);i&&(i.accessedPaths.forEach((t=>{this.dependencyMap.get(t)?.delete(e),0===this.dependencyMap.get(t)?.size&&this.dependencyMap.delete(t)})),this.reactiveSelectors.delete(e),this.reactiveSelectorCache.delete(t),this.pathBasedCache.delete(s))}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function g(e,t){if(e===t)return!0;if(e&&t&&"object"==typeof e&&"object"==typeof t){if(e.constructor!==t.constructor)return!1;let s,i;if(Array.isArray(e)){if(s=e.length,s!=t.length)return!1;for(i=s;i-- >0;)if(!g(e[i],t[i]))return!1;return!0}const[r,a]=[Object.keys(e),Object.keys(t)];if(s=r.length,s!==a.length)return!1;for(i=s;i-- >0;){const s=r[i];if(!Object.prototype.hasOwnProperty.call(t,s)||!g(e[s],t[s]))return!1}return!0}return e!=e&&t!=t}function y(e){const t=e?.deleteMarker||d;return function(e,s){const i=[],r=[{pathStr:"",orig:e||{},part:s||{}}];for(;r.length>0;){const{pathStr:e,orig:s,part:a}=r.pop();if(null!=a&&!g(s,a))if("object"!=typeof a||Array.isArray(a))e&&i.push({path:e,oldValue:s,newValue:a});else for(const n of Object.keys(a)){const o=e?e+"."+n:n,c=a[n],d=s&&"object"==typeof s?s[n]:void 0;c!==t?"object"==typeof c&&null!==c?r.push({pathStr:o,orig:d,part:c}):g(d,c)||i.push({path:o,oldValue:d,newValue:c}):void 0!==d&&i.push({path:o,oldValue:d,newValue:void 0})}}return i}}function f(e){const t=e?.deleteMarker||d;return function(e){const s=new Set,i=[{obj:e,currentPath:""}];for(;i.length>0;){const{obj:e,currentPath:r}=i.pop();if(null!=e&&"object"==typeof e&&!Array.isArray(e))for(const a of Object.keys(e)){const n=r?`${r}.${a}`:a;s.add(n);const o=e[a];"object"!=typeof o||null===o||Array.isArray(o)||o===t||i.push({obj:o,currentPath:n})}}return Array.from(s)}}var w=y(),v=f(),b=class{constructor(e,t,s){this.updateBus=t,this.diff=s,this.cache=structuredClone(e)}cache;get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,s=!1,i=[]){if(t)return this.cache=s?structuredClone(e):e,this.notifyListeners([]),[];0===i.length&&(i=[e]);const r=this.get(!1),a=new Map;for(let e=0;e<i.length;e++){const t=i[e],s=this.diff(r,t);for(let e=0;e<s.length;e++){const t=s[e];a.set(t.path,t)}}const n=a.size?[...a.values()]:[];if(n.length>0){this.cache=s?structuredClone(e):e;const t=new Set;for(let e=0;e<n.length;e++){let s=n[e].path;for(;s&&!t.has(s);){t.add(s);const e=s.lastIndexOf(".");if(e<0)break;s=s.slice(0,e)}}this.notifyListeners(t)}return n}notifyListeners(e){for(const t of e)this.updateBus.emit({name:"update",payload:t})}},S=class{constructor(e,t,s){this.eventBus=e,this.executionState=t,this.merge=s}middleware=[];blockingMiddleware=[];async executeBlocking(e,t){for(const{fn:s,name:i,id:r}of this.blockingMiddleware){const a={id:r,name:i,startTime:performance.now()};this.executionState.runningMiddleware={id:r,name:i,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:r,name:i,type:"blocking"});try{const n=await Promise.resolve(s(e,t));if(a.endTime=performance.now(),a.duration=a.endTime-a.startTime,!1===n)return a.blocked=!0,this.emitMiddlewareLifecycle("blocked",{id:r,name:i,duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0};this.emitMiddlewareLifecycle("complete",{id:r,name:i,type:"blocking",duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:{...a,blocked:!1}})}catch(e){return a.endTime=performance.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:new Error(String(e)),a.blocked=!0,this.emitMiddlewareError(r,i,a.error,a.duration),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0,error:a.error}}finally{this.executionState.runningMiddleware=null}}return{blocked:!1}}async executeTransform(e,t){let s=e,i=t;for(const{fn:e,name:r,id:a}of this.middleware){const n={id:a,name:r,startTime:performance.now()};this.executionState.runningMiddleware={id:a,name:r,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:a,name:r,type:"transform"});try{const o=await Promise.resolve(e(s,t));n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.blocked=!1,o&&"object"==typeof o&&(s=this.merge(s,o),i=this.merge(i,o)),this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareLifecycle("complete",{id:a,name:r,type:"transform",duration:n.duration})}catch(e){n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.error=e instanceof Error?e:new Error(String(e)),n.blocked=!1,this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareError(a,r,n.error,n.duration),console.error(`Middleware ${r} error:`,e)}finally{this.executionState.runningMiddleware=null}}return i}addMiddleware(e,t="unnamed-middleware"){const s=this.generateId();return this.middleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}addBlockingMiddleware(e,t="unnamed-blocking-middleware"){const s=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}removeMiddleware(e){const t=this.middleware.length+this.blockingMiddleware.length;return this.middleware=this.middleware.filter((t=>t.id!==e)),this.blockingMiddleware=this.blockingMiddleware.filter((t=>t.id!==e)),this.updateExecutionState(),this.middleware.length+this.blockingMiddleware.length<t}updateExecutionState(){this.executionState.middlewares=[...this.middleware.map((e=>e.name)),...this.blockingMiddleware.map((e=>e.name))]}emitMiddlewareLifecycle(e,t){this.emit(this.eventBus,{name:`middleware:${e}`,payload:{...t,timestamp:Date.now()}})}emitMiddlewareError(e,t,s,i){this.emit(this.eventBus,{name:"middleware:error",payload:{id:e,name:t,error:s,duration:i,timestamp:Date.now()}})}generateId(){return crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).substring(2,15)}`}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},_=class{constructor(e,t,s,i){this.eventBus=e,this.coreState=t,this.instanceID=s,this.maxRetries=i?.maxRetries??3,this.retryDelay=i?.retryDelay??1e3}persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||0===e.length)return;const s={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(s),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:"persistence:queued",payload:{taskId:s.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:s.timestamp}})}getQueueStatus(){return{queueSize:this.backgroundQueue.length,isProcessing:this.isProcessingQueue,pendingRetries:this.pendingRetries.size,oldestTask:this.backgroundQueue[0]?.timestamp}}async flush(){this.isProcessingQueue&&await new Promise((e=>{const t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()})),await this.processQueue()}discardQueue(){const e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&(clearTimeout(this.queueProcessor),this.queueProcessor=void 0),this.emit(this.eventBus,{name:"persistence:queue_cleared",payload:{clearedTasks:e,timestamp:Date.now()}})}scheduleQueueProcessing(){this.queueProcessor||this.isProcessingQueue||(this.queueProcessor=setTimeout((()=>{this.processQueue().catch((e=>{console.error("Queue processing failed:",e)}))}),10))}async processQueue(){if(!this.isProcessingQueue&&0!==this.backgroundQueue.length){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){const e=this.backgroundQueue.shift();await this.processTask(e)}}finally{this.isProcessingQueue=!1}}}async processTask(e){try{await this.persistence.set(this.instanceID,e.state)?this.emit(this.eventBus,{name:"persistence:success",payload:{taskId:e.id,changedPaths:e.changedPaths,duration:Date.now()-e.timestamp,timestamp:Date.now()}}):await this.handleTaskFailure(e,new Error("Persistence returned false"))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){const s=this.retryDelay*Math.pow(2,e.retries-1);this.emit(this.eventBus,{name:"persistence:retry",payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:s,error:t,timestamp:Date.now()}}),this.pendingRetries.add(e.id),setTimeout((()=>{this.pendingRetries.has(e.id)&&(this.pendingRetries.delete(e.id),this.backgroundQueue.unshift(e),this.scheduleQueueProcessing())}),s)}else this.emit(this.eventBus,{name:"persistence:failed",payload:{taskId:e.id,changedPaths:e.changedPaths,attempts:e.retries,error:t,timestamp:Date.now()}})}setPersistenceReady(){this.persistenceReady=!0,this.emit(this.eventBus,{name:"persistence:ready",payload:{timestamp:Date.now()}})}async setPersistence(e){this.persistence=e;try{const e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){console.error("Failed to initialize persistence:",e),this.emit(this.eventBus,{name:"persistence:init_error",payload:{error:e,timestamp:Date.now()}})}finally{this.setPersistenceReady()}this.persistence.subscribe(this.instanceID,(async e=>{const t=this.coreState.applyChanges(e);t.length>0&&this.emit(this.eventBus,{name:"update:complete",payload:{changedPaths:t,source:"external",timestamp:Date.now()}})}))}dispose(){this.discardQueue(),this.isProcessingQueue=!1,this.persistenceReady=!1}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},E=class{constructor(e,t,s){this.eventBus=e,this.coreState=t,this.executionState=s}async execute(e){const t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:"transaction:start",payload:{timestamp:Date.now()}});try{const t=await Promise.resolve(e());return this.emit(this.eventBus,{name:"transaction:complete",payload:{timestamp:Date.now()}}),this.executionState.transactionActive=!1,t}catch(e){throw this.coreState.applyChanges(t,!0,!1),this.emit(this.eventBus,{name:"transaction:error",payload:{error:e instanceof Error?e:new Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},x=class{updateCount=0;listenerExecutions=0;averageUpdateTime=0;largestUpdateSize=0;mostActiveListenerPaths=[];totalUpdates=0;blockedUpdates=0;averageUpdateDuration=0;middlewareExecutions=0;transactionCount=0;totalEventsFired=0;totalActionsDispatched=0;totalActionsSucceeded=0;totalActionsFailed=0;averageActionDuration=0;updateTimes=[];actionTimes=[];pathExecutionCounts=new Map;constructor(e){this.setupEventListeners(e)}getMetrics(){return{updateCount:this.updateCount,listenerExecutions:this.listenerExecutions,averageUpdateTime:this.averageUpdateTime,largestUpdateSize:this.largestUpdateSize,mostActiveListenerPaths:[...this.mostActiveListenerPaths],totalUpdates:this.totalUpdates,blockedUpdates:this.blockedUpdates,averageUpdateDuration:this.averageUpdateDuration,middlewareExecutions:this.middlewareExecutions,transactionCount:this.transactionCount,totalEventsFired:this.totalEventsFired,totalActionsDispatched:this.totalActionsDispatched,totalActionsSucceeded:this.totalActionsSucceeded,totalActionsFailed:this.totalActionsFailed,averageActionDuration:this.averageActionDuration}}setupEventListeners(e){const t=e.emit;e.emit=s=>(this.totalEventsFired++,t.call(e,s)),e.subscribe("update:complete",(e=>{if(this.totalUpdates++,e.blocked)this.blockedUpdates++;else{if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();const t=this.updateTimes.reduce(((e,t)=>e+t),0)/this.updateTimes.length;this.averageUpdateTime=t,this.averageUpdateDuration=t}e.deltas?.length&&(this.updateCount++,this.largestUpdateSize=Math.max(this.largestUpdateSize,e.deltas.length),e.deltas.forEach((e=>{const t=this.pathExecutionCounts.get(e.path)||0;this.pathExecutionCounts.set(e.path,t+1)})),this.mostActiveListenerPaths=Array.from(this.pathExecutionCounts.entries()).sort((([,e],[,t])=>t-e)).slice(0,5).map((([e])=>e)))}})),e.subscribe("middleware:start",(()=>{this.middlewareExecutions++})),e.subscribe("transaction:start",(()=>{this.transactionCount++})),e.subscribe("action:start",(()=>{this.totalActionsDispatched++})),e.subscribe("action:complete",(e=>{this.totalActionsSucceeded++,e.duration&&(this.actionTimes.push(e.duration),this.actionTimes.length>100&&this.actionTimes.shift(),this.averageActionDuration=this.actionTimes.reduce(((e,t)=>e+t),0)/this.actionTimes.length)})),e.subscribe("action:error",(()=>{this.totalActionsFailed++}))}reset(){this.updateCount=0,this.listenerExecutions=0,this.averageUpdateTime=0,this.largestUpdateSize=0,this.mostActiveListenerPaths=[],this.totalUpdates=0,this.blockedUpdates=0,this.averageUpdateDuration=0,this.middlewareExecutions=0,this.transactionCount=0,this.totalEventsFired=0,this.totalActionsDispatched=0,this.totalActionsSucceeded=0,this.totalActionsFailed=0,this.averageActionDuration=0,this.updateTimes=[],this.actionTimes=[],this.pathExecutionCounts.clear()}getDetailedMetrics(){return{pathExecutionCounts:new Map(this.pathExecutionCounts),recentUpdateTimes:[...this.updateTimes],successRate:this.totalUpdates>0?(this.totalUpdates-this.blockedUpdates)/this.totalUpdates:1,averagePathsPerUpdate:this.updateCount>0?Array.from(this.pathExecutionCounts.values()).reduce(((e,t)=>e+t),0)/this.updateCount:0}}dispose(){this.reset()}},k=class extends Error{constructor(){super("Action Cancelled by Debounce"),this.name="ActionCancelledError"}},T=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name="UnknownActionError"}},M=class{constructor(e,t){this.eventBus=e,this.set=t}registrations=new Map;register(t){const s={action:{name:t.name,id:e(),action:t.fn,debounce:t.debounce?{...t.debounce,condition:t.debounce.condition??(()=>!0)}:void 0},debouncer:t.debounce&&t.debounce.delay>0?new o({delay:t.debounce.delay}):void 0,previousArgs:void 0};return this.registrations.set(t.name,s),()=>{const e=this.registrations.get(t.name);e&&(e.debouncer?.cancel(),this.registrations.delete(t.name))}}async dispatch(e,...t){const s=this.registrations.get(e);if(!s)throw new T({action:e});const{action:i,debouncer:r}=s,{id:a,action:n,debounce:o}=i;if(!r||!o)return this.executeAction(e,a,n,t);const c=o.condition(s.previousArgs,t);if(s.previousArgs=t,!c)return this.executeAction(e,a,n,t);const d=await r.do((()=>this.executeAction(e,a,n,t)));if("cancelled"===d.status)throw new k;if("error"===d.status&&d.error)throw d.error;return d.value}async executeAction(e,t,s,i){const r=performance.now();this.emit(this.eventBus,{name:"action:start",payload:{actionId:t,name:e,params:i||[],timestamp:r}});try{const a=await this.set((e=>s(e,...i)),{actionId:t}),n=performance.now();return this.emit(this.eventBus,{name:"action:complete",payload:{actionId:t,name:e,params:i,startTime:r,endTime:n,duration:n-r,result:a}}),a}catch(s){const a=performance.now();throw this.emit(this.eventBus,{name:"action:error",payload:{actionId:t,name:e,params:i,startTime:r,endTime:a,duration:a-r,error:s}}),s}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},C=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new a({yieldMode:"macrotask",capacity:1e3});readyLatch=new n;updateBus=c();eventBus;executionState;instanceID=e();merge;diff;constructor(e,t,s=d,i,r={errorHandler:()=>{}}){this.eventBus=c(r),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=h({deleteMarker:s}),this.diff=y({deleteMarker:s}),this.coreState=new b(e,this.updateBus,this.diff),this.middlewareEngine=new S(this.eventBus,this.executionState,this.merge),this.persistenceHandler=new _(this.eventBus,this.coreState,this.instanceID,{maxRetries:i?.persistenceMaxRetries,retryDelay:i?.persistenceRetryDelay}),this.transactionManager=new E(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new x(this.eventBus),this.actions=new M(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(t),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new m(this.get.bind(this),this.eventBus)}isReady(){return this.readyLatch.isOpen()}async ready(e){return this.readyLatch.wait(e)}state(){return this.executionState.executing=this.updateSerializer.running(),this.executionState}get(e){return this.coreState.get(e??!1)}select(e){return this.selectorManager.createReactiveSelector(e)}register(e){return this.actions.register(e)}async dispatch(e,...t){return this.actions.dispatch(e,...t)}async set(e,t={}){const s=await this.updateSerializer.do((()=>this._performUpdate(e,t)));if(s.error)throw s.error;return s.value}async _performUpdate(e,t){const s=performance.now();this.emit(this.eventBus,{name:"update:start",payload:{timestamp:s,actionId:t.actionId}});try{if(t.force){const i=this.get(!1),r="function"==typeof e?e(i):e;this.coreState.applyChanges(r,!0);const a=performance.now();return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:[],duration:a-s,timestamp:Date.now(),actionId:t.actionId,newState:r}}),r}let i;const r=this.get(!1);if("function"==typeof e){const t=e(r);i=t instanceof Promise?await t:t}else i=e;const a=await this.middlewareEngine.executeBlocking(r,i);if(a.blocked)throw a.error||new Error("Update blocked by middleware");const n=this.merge(r,i),o=await this.middlewareEngine.executeTransform(n,i),c=this.merge(n,o),d=this.coreState.applyChanges(c,!1,!1,[i,o]),l=performance.now(),h=this.get(!1);return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:d,duration:l-s,timestamp:Date.now(),actionId:t.actionId,newState:h}}),h}catch(e){throw this.emit(this.eventBus,{name:"update:complete",payload:{blocked:!0,error:e,timestamp:Date.now(),actionId:t.actionId,newState:this.get(!1)}}),e}finally{this.executionState.executing=!1,this.executionState.changes=null,this.executionState.runningMiddleware=null,this.executionState.pendingChanges=[]}}setupReadyLatch(){this.readyLatch.open(),this.persistenceHandler.isReady()?this.readyLatch.open():queueMicrotask((()=>{this.readyLatch.isOpen()||this.readyLatch.open()}))}setupPersistenceListener(){this.updateBus.subscribe("update",(e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))}))}watch(e,t){const s=Array.isArray(e)?e:[e],i=""===e||0===s.length;return this.updateBus.subscribe("update",(e=>{(i||s.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)}))}debouncedSetter(e){const t=new o({delay:e.delay,leading:e.leading});return(e,s={})=>{t.fire((()=>this.set(e,s)))}}subscribe(e,t){return this.watch(e,t)}id(){return this.instanceID}async transaction(e){return this.transactionManager.execute(e)}use(e){const t=(e.block?this.middlewareEngine.addBlockingMiddleware:this.middlewareEngine.addMiddleware).bind(this.middlewareEngine)(e.action,e.name);return()=>this.middlewareEngine.removeMiddleware(t)}metrics(){return this.metricsCollector.getMetrics()}on(e,t){return this.eventBus.subscribe(e,t)}onStoreEvent(e,t){return this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flushPersistence(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){this.updateSerializer.close(),this.persistenceHandler.dispose(),this.metricsCollector.dispose?.(),this.selectorManager.dispose?.()}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},P=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;constructor(e,t={}){this.store=e,this.maxEvents=t.maxEvents??500,this.maxStateHistory=t.maxStateHistory??20,this.enableConsoleLogging=t.enableConsoleLogging??!1,this.isSilent=t.silent??!1,this.logEvents={updates:t.logEvents?.updates??!0,middleware:t.logEvents?.middleware??!0,transactions:t.logEvents?.transactions??!0,actions:t.logEvents?.actions??!0,selectors:t.logEvents?.selectors??!0},this.performanceThresholds={updateTime:t.performanceThresholds?.updateTime??50,middlewareTime:t.performanceThresholds?.middlewareTime??20},this.recordStateSnapshot([]),this.setupEventListeners()}_consoleLog(e,...t){this.isSilent||"function"==typeof console[e]&&console[e](...t)}setupEventListeners(){const e=["update:start","update:complete","middleware:start","middleware:complete","middleware:error","middleware:blocked","transaction:start","transaction:complete","transaction:error","middleware:executed","action:start","action:complete","action:error","selector:accessed"];for(const t of e){const e=t.startsWith("update")&&this.logEvents.updates||t.startsWith("middleware")&&this.logEvents.middleware||t.startsWith("transaction")&&this.logEvents.transactions||t.startsWith("action")&&this.logEvents.actions||t.startsWith("selector")&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(t,(s=>{"update:complete"!==t||s.blocked||this.isTimeTraveling||this.recordStateSnapshot(s.deltas),"middleware:executed"===t?this.middlewareExecutions.push(s):"transaction:start"===t?this.activeTransactionCount++:"transaction:complete"!==t&&"transaction:error"!==t||(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),s.batchId&&(t.endsWith("start")?this.activeBatches.add(s.batchId):(t.endsWith("complete")||t.endsWith("error"))&&this.activeBatches.delete(s.batchId)),this.recordEvent(t,s),this.enableConsoleLogging&&e&&this._log(t,s),this._checkPerformance(t,s)})))}}recordStateSnapshot(e){const t={state:this.store.get(!0),timestamp:Date.now(),deltas:e};this.stateHistory.unshift(t),this.stateHistory.length>this.maxStateHistory&&this.stateHistory.pop()}recordEvent(e,t){const s={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(s),this.eventHistory.length>this.maxEvents&&this.eventHistory.pop()}getEventHistory(){return structuredClone(this.eventHistory)}getStateHistory(){return structuredClone(this.stateHistory)}getMiddlewareExecutions(){return this.middlewareExecutions}getTransactionStatus(){return{activeTransactions:this.activeTransactionCount,activeBatches:Array.from(this.activeBatches)}}createLoggingMiddleware(e={}){const{logLevel:t="debug",logUpdates:s=!0}=e;return(e,i)=>{if(s){(console[t]||console.log)("State Update:",i)}return i}}createValidationMiddleware(e){return(t,s)=>{const i=e(t,s);return"boolean"==typeof i?i:(!i.valid&&i.reason&&this._consoleLog("warn","Validation failed:",i.reason),i.valid)}}getRecentChanges(e=5){const t=[],s=Math.min(e,this.stateHistory.length);for(let e=0;e<s;e++){const s=this.stateHistory[e];if(!s.deltas||0===s.deltas.length)continue;const i={},r={},a=(e,t,s)=>{t.reduce(((e,i,r)=>(r===t.length-1?e[i]=s:e[i]=e[i]??{},e[i])),e)};for(const e of s.deltas){const t=e.path.split(".");a(i,t,e.oldValue),a(r,t,e.newValue)}t.push({timestamp:s.timestamp,changedPaths:s.deltas.map((e=>e.path)),from:i,to:r})}return t}clearHistory(){this.eventHistory=[],this.stateHistory.length>0&&(this.stateHistory=[this.stateHistory[0]])}getHistoryForAction(e){return this.eventHistory.filter((t=>t.data?.actionId===e))}async replay(e){const t=this.eventHistory.filter((e=>"update:start"===e.type))[e];t?.data.update?(this._consoleLog("log",`Replaying event at index ${e}:`,t),await this.store.set(t.data.update,{force:!0})):this._consoleLog("warn",`No replayable event found at index ${e}.`)}createTimeTravel(){let e=0,t=[];const s=this.store.on("update:complete",(s=>{this.isTimeTraveling||s.blocked||(t=[],e=0)}));this.unsubscribers.push(s);const i=()=>this.stateHistory.length,r=()=>e<i()-1,a=()=>t.length>0;return{canUndo:r,canRedo:a,undo:async()=>{if(!r())return;t.unshift(this.stateHistory[e]),e++;const s=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...s},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;const s=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...s.state},{force:!0}),this.isTimeTraveling=!1},length:i,clear:()=>{t=[],e=0}}}async saveSession(e){const t=this.store.id(),s={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,s))}async loadSession(e){const t=await Promise.resolve(e.get());return!!t&&(this.eventHistory=t.eventHistory||[],this.stateHistory=t.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),!0)}exportSession(){const e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),s=URL.createObjectURL(t),i=document.createElement("a");i.href=s,i.download=`store-observer-session-${(new Date).toISOString()}.json`,i.click(),URL.revokeObjectURL(s)}importSession(e){return new Promise(((t,s)=>{const i=new FileReader;i.onload=async e=>{try{const s=JSON.parse(e.target?.result);this.eventHistory=s.eventHistory||[],this.stateHistory=s.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){s(e)}},i.onerror=e=>s(e),i.readAsText(e)}))}disconnect(){this.unsubscribers.forEach((e=>e())),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){const s=new Date(t.timestamp||Date.now()).toISOString().split("T")[1].replace("Z","");if("update:start"===e)this._consoleLog("group",`%c⚡ Store Update Started [${s}]`,"color: #4a6da7");else if("update:complete"===e){if(t.blocked)this._consoleLog("warn",`%c✋ Update Blocked [${s}]`,"color: #bf8c0a",t.error);else{const e=t.deltas||[];e.length>0&&(this._consoleLog("log",`%c✅ Update Complete [${s}] - ${e.length} paths changed in ${t.duration?.toFixed(2)}ms`,"color: #2a9d8f"),this._consoleLog("table",e.map((e=>({path:e.path,oldValue:e.oldValue,newValue:e.newValue})))))}this._consoleLog("groupEnd")}else"middleware:start"===e?this._consoleLog("debug",`%c◀ Middleware "${t.name}" started [${s}] (${t.type})`,"color: #8c8c8c"):"middleware:complete"===e?this._consoleLog("debug",`%c▶ Middleware "${t.name}" completed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #7c9c7c"):"middleware:error"===e?this._consoleLog("error",`%c❌ Middleware "${t.name}" error [${s}]:`,"color: #e63946",t.error):"middleware:blocked"===e?this._consoleLog("warn",`%c🛑 Middleware "${t.name}" blocked update [${s}]`,"color: #e76f51"):"transaction:start"===e?this._consoleLog("group",`%c📦 Transaction Started [${s}]`,"color: #6d597a"):"transaction:complete"===e?(this._consoleLog("log",`%c📦 Transaction Complete [${s}]`,"color: #355070"),this._consoleLog("groupEnd")):"transaction:error"===e?(this._consoleLog("error",`%c📦 Transaction Error [${s}]:`,"color: #e56b6f",t.error),this._consoleLog("groupEnd")):"action:start"===e?this._consoleLog("group",`%c🚀 Action "${t.name}" Started [${s}]`,"color: #9b59b6",{params:t.params}):"action:complete"===e?(this._consoleLog("log",`%c✔️ Action "${t.name}" Complete [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #2ecc71"),this._consoleLog("groupEnd")):"action:error"===e?(this._consoleLog("error",`%c🔥 Action "${t.name}" Error [${s}]:`,"color: #e74c3c",t.error),this._consoleLog("groupEnd")):"selector:accessed"===e&&this._consoleLog("debug",`%c👀 Selector Accessed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #f1c40f",{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&("update:complete"===e&&!t.blocked&&t.duration>this.performanceThresholds.updateTime&&this._consoleLog("warn",`%c⚠️ Slow update detected [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{deltas:t.deltas,threshold:this.performanceThresholds.updateTime}),"middleware:complete"===e&&t.duration>this.performanceThresholds.middlewareTime&&this._consoleLog("warn",`%c⚠️ Slow middleware "${t.name}" [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{threshold:this.performanceThresholds.middlewareTime}))}};export{k as ActionCancelledError,M as ActionManager,d as DELETE_SYMBOL,C as ReactiveDataStore,P as StoreObserver,T as UnknownActionError,f as createDerivePaths,y as createDiff,h as createMerge,v as derivePaths,w as diff,u as merge,l as shallowClone};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-store",
3
- "version": "9.0.0",
3
+ "version": "9.0.1",
4
4
  "description": "A reactive data store",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -29,7 +29,7 @@
29
29
  "access": "public"
30
30
  },
31
31
  "dependencies": {
32
- "@asaidimu/utils-persistence": "4.0.0",
32
+ "@asaidimu/utils-persistence": "5.0.0",
33
33
  "uuid": "^11.1.0"
34
34
  },
35
35
  "exports": {