@asaidimu/utils-store 10.2.9 → 10.2.11

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.cts CHANGED
@@ -1266,4 +1266,77 @@ declare class ActionManager<T extends object> {
1266
1266
  dispose(): void;
1267
1267
  }
1268
1268
  //#endregion
1269
- export { ActionCancelledError, ActionCompletePayload, ActionErrorPayload, ActionManager, ActionStartPayload, ActionWatcher, BlockingMiddleware, DELETE_SYMBOL, DataStore, DeepPartial, DiffFunction, MergeFunction, Middleware, MiddlewareConfig, MiddlewareExecution, type ObserverOptions, PersistenceFailedPayload, PersistenceInitErrorPayload, PersistenceQueueClearedPayload, PersistenceQueuedPayload, PersistenceRetryPayload, PersistenceSuccessPayload, ReactiveDataStore, ReactiveDataStoreOptions, ReactiveSelector, SelectorAccessedPayload, SelectorChangedPayload, StateDelta, StateUpdater, StoreAction, StoreEvent, StoreEvents, StoreExecutionState, StoreLogger, StoreMetrics, StoreObserver, StoreRegistry, StoreRegistryOptions, type SubscribeOptions, TransactionOptions, TransformMiddleware, UnknownActionError, createDerivePaths, createDiff, createMerge, createStoreLogger, derivePaths, diff, merge, shallowClone };
1269
+ //#region src/store/selector.d.ts
1270
+ /**
1271
+ * Manages reactive selectors with static path tracking.
1272
+ *
1273
+ * Selectors MUST be simple property accesses only — no transformations,
1274
+ * no iterations, no conditionals. Use store effects for derivations instead.
1275
+ *
1276
+ * Cache strategy: paths-only.
1277
+ * Because selectors are guaranteed to be pure property accessors, two selectors
1278
+ * that access the same set of paths are semantically identical and share a single
1279
+ * SelectorEntry. There is no WeakMap ref-cache (refs are unstable for inline
1280
+ * arrows) and no function-body component in the key (redundant given the
1281
+ * invariant). The sorted, pipe-joined path set is the complete identity of a
1282
+ * selector.
1283
+ *
1284
+ * Lifetime: reference-counted with deferred cleanup.
1285
+ * When the subscriber count reaches zero we schedule cleanup on a setTimeout(0)
1286
+ * rather than destroying the entry immediately. This absorbs React Strict Mode's
1287
+ * subscribe → unsubscribe → re-subscribe cycle, which otherwise causes a
1288
+ * re-initialisation storm (new id, lost lastResult, spurious re-renders).
1289
+ * If count is still zero when the timer fires, the entry is genuinely abandoned
1290
+ * and is evicted cleanly.
1291
+ *
1292
+ * @template T - The type of the root state object.
1293
+ */
1294
+ declare class SelectorManager<T extends object> {
1295
+ private reactiveSelectors;
1296
+ /**
1297
+ * Single source of truth for caching. Key: sorted paths joined by "|".
1298
+ * Maps to the live SelectorEntry (not just the ReactiveSelector facade),
1299
+ * so ref-counting and deferred cleanup operate on the same object.
1300
+ */
1301
+ private pathBasedCache;
1302
+ /** Reverse lookup: Path -> Set of Selector IDs for O(1) update dispatch. */
1303
+ private dependencyMap;
1304
+ private getState;
1305
+ private eventBus;
1306
+ private unsubscribeFromStore;
1307
+ constructor(getState: () => T, eventBus: EventBus<StoreEvents>);
1308
+ private handleStoreUpdate;
1309
+ private evaluateEntry;
1310
+ createReactiveSelector<S>(selector: (state: T) => S): ReactiveSelector<S>;
1311
+ /**
1312
+ * Fully removes a selector entry from all internal maps.
1313
+ * Only called from the deferred cleanup timer, after confirming count === 0.
1314
+ */
1315
+ private evictEntry;
1316
+ dispose(): void;
1317
+ }
1318
+ /**
1319
+ * Builds an array of leaf paths accessed by a selector.
1320
+ * Uses static proxy-based analysis — the selector is run with a proxy tree,
1321
+ * never against real state.
1322
+ *
1323
+ * Works reliably ONLY for simple property access patterns:
1324
+ * state.user.name
1325
+ * state.items[0].value
1326
+ * state.config.theme.colors.primary
1327
+ *
1328
+ * Does NOT work for (and will throw):
1329
+ * state.items.map(...) — array iteration
1330
+ * state.user.isAdmin ? ... : .. — conditionals (valueOf coercion)
1331
+ * state.a + state.b — arithmetic (valueOf coercion)
1332
+ * 'key' in state — in operator
1333
+ *
1334
+ * @param selector - The selector function to analyse
1335
+ * @param divider - The path separator (default: ".")
1336
+ * @returns Sorted array of leaf paths accessed by the selector
1337
+ *
1338
+ * @throws {Error} If the selector attempts any operation beyond property access
1339
+ */
1340
+ declare function buildPaths<T>(selector: (state: T) => any, divider?: string): string[];
1341
+ //#endregion
1342
+ export { ActionCancelledError, ActionCompletePayload, ActionErrorPayload, ActionManager, ActionStartPayload, ActionWatcher, BlockingMiddleware, DELETE_SYMBOL, DataStore, DeepPartial, DiffFunction, MergeFunction, Middleware, MiddlewareConfig, MiddlewareExecution, type ObserverOptions, PersistenceFailedPayload, PersistenceInitErrorPayload, PersistenceQueueClearedPayload, PersistenceQueuedPayload, PersistenceRetryPayload, PersistenceSuccessPayload, ReactiveDataStore, ReactiveDataStoreOptions, ReactiveSelector, SelectorAccessedPayload, SelectorChangedPayload, SelectorManager, StateDelta, StateUpdater, StoreAction, StoreEvent, StoreEvents, StoreExecutionState, StoreLogger, StoreMetrics, StoreObserver, StoreRegistry, StoreRegistryOptions, type SubscribeOptions, TransactionOptions, TransformMiddleware, UnknownActionError, buildPaths, createDerivePaths, createDiff, createMerge, createStoreLogger, derivePaths, diff, merge, shallowClone };
package/index.d.ts CHANGED
@@ -1097,4 +1097,77 @@ declare class ActionManager<T extends object> {
1097
1097
  dispose(): void;
1098
1098
  }
1099
1099
  //#endregion
1100
- export { ActionCancelledError, ActionCompletePayload, ActionErrorPayload, ActionManager, ActionStartPayload, ActionWatcher, BlockingMiddleware, DELETE_SYMBOL, DataStore, DeepPartial, DiffFunction, MergeFunction, Middleware, MiddlewareConfig, MiddlewareExecution, type ObserverOptions, PersistenceFailedPayload, PersistenceInitErrorPayload, PersistenceQueueClearedPayload, PersistenceQueuedPayload, PersistenceRetryPayload, PersistenceSuccessPayload, ReactiveDataStore, ReactiveDataStoreOptions, ReactiveSelector, SelectorAccessedPayload, SelectorChangedPayload, StateDelta, StateUpdater, StoreAction, StoreEvent, StoreEvents, StoreExecutionState, StoreLogger, StoreMetrics, StoreObserver, StoreRegistry, StoreRegistryOptions, type SubscribeOptions, TransactionOptions, TransformMiddleware, UnknownActionError, createDerivePaths, createDiff, createMerge, createStoreLogger, derivePaths, diff, merge, shallowClone };
1100
+ //#region src/store/selector.d.ts
1101
+ /**
1102
+ * Manages reactive selectors with static path tracking.
1103
+ *
1104
+ * Selectors MUST be simple property accesses only — no transformations,
1105
+ * no iterations, no conditionals. Use store effects for derivations instead.
1106
+ *
1107
+ * Cache strategy: paths-only.
1108
+ * Because selectors are guaranteed to be pure property accessors, two selectors
1109
+ * that access the same set of paths are semantically identical and share a single
1110
+ * SelectorEntry. There is no WeakMap ref-cache (refs are unstable for inline
1111
+ * arrows) and no function-body component in the key (redundant given the
1112
+ * invariant). The sorted, pipe-joined path set is the complete identity of a
1113
+ * selector.
1114
+ *
1115
+ * Lifetime: reference-counted with deferred cleanup.
1116
+ * When the subscriber count reaches zero we schedule cleanup on a setTimeout(0)
1117
+ * rather than destroying the entry immediately. This absorbs React Strict Mode's
1118
+ * subscribe → unsubscribe → re-subscribe cycle, which otherwise causes a
1119
+ * re-initialisation storm (new id, lost lastResult, spurious re-renders).
1120
+ * If count is still zero when the timer fires, the entry is genuinely abandoned
1121
+ * and is evicted cleanly.
1122
+ *
1123
+ * @template T - The type of the root state object.
1124
+ */
1125
+ declare class SelectorManager<T extends object> {
1126
+ private reactiveSelectors;
1127
+ /**
1128
+ * Single source of truth for caching. Key: sorted paths joined by "|".
1129
+ * Maps to the live SelectorEntry (not just the ReactiveSelector facade),
1130
+ * so ref-counting and deferred cleanup operate on the same object.
1131
+ */
1132
+ private pathBasedCache;
1133
+ /** Reverse lookup: Path -> Set of Selector IDs for O(1) update dispatch. */
1134
+ private dependencyMap;
1135
+ private getState;
1136
+ private eventBus;
1137
+ private unsubscribeFromStore;
1138
+ constructor(getState: () => T, eventBus: EventBus<StoreEvents>);
1139
+ private handleStoreUpdate;
1140
+ private evaluateEntry;
1141
+ createReactiveSelector<S>(selector: (state: T) => S): ReactiveSelector<S>;
1142
+ /**
1143
+ * Fully removes a selector entry from all internal maps.
1144
+ * Only called from the deferred cleanup timer, after confirming count === 0.
1145
+ */
1146
+ private evictEntry;
1147
+ dispose(): void;
1148
+ }
1149
+ /**
1150
+ * Builds an array of leaf paths accessed by a selector.
1151
+ * Uses static proxy-based analysis — the selector is run with a proxy tree,
1152
+ * never against real state.
1153
+ *
1154
+ * Works reliably ONLY for simple property access patterns:
1155
+ * state.user.name
1156
+ * state.items[0].value
1157
+ * state.config.theme.colors.primary
1158
+ *
1159
+ * Does NOT work for (and will throw):
1160
+ * state.items.map(...) — array iteration
1161
+ * state.user.isAdmin ? ... : .. — conditionals (valueOf coercion)
1162
+ * state.a + state.b — arithmetic (valueOf coercion)
1163
+ * 'key' in state — in operator
1164
+ *
1165
+ * @param selector - The selector function to analyse
1166
+ * @param divider - The path separator (default: ".")
1167
+ * @returns Sorted array of leaf paths accessed by the selector
1168
+ *
1169
+ * @throws {Error} If the selector attempts any operation beyond property access
1170
+ */
1171
+ declare function buildPaths<T>(selector: (state: T) => any, divider?: string): string[];
1172
+ //#endregion
1173
+ export { ActionCancelledError, ActionCompletePayload, ActionErrorPayload, ActionManager, ActionStartPayload, ActionWatcher, BlockingMiddleware, DELETE_SYMBOL, DataStore, DeepPartial, DiffFunction, MergeFunction, Middleware, MiddlewareConfig, MiddlewareExecution, type ObserverOptions, PersistenceFailedPayload, PersistenceInitErrorPayload, PersistenceQueueClearedPayload, PersistenceQueuedPayload, PersistenceRetryPayload, PersistenceSuccessPayload, ReactiveDataStore, ReactiveDataStoreOptions, ReactiveSelector, SelectorAccessedPayload, SelectorChangedPayload, SelectorManager, StateDelta, StateUpdater, StoreAction, StoreEvent, StoreEvents, StoreExecutionState, StoreLogger, StoreMetrics, StoreObserver, StoreRegistry, StoreRegistryOptions, type SubscribeOptions, TransactionOptions, TransformMiddleware, UnknownActionError, buildPaths, createDerivePaths, createDiff, createMerge, createStoreLogger, derivePaths, diff, merge, shallowClone };
package/index.js CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@asaidimu/utils-events"),t=require("@asaidimu/utils-sync"),n=require("uuid"),r=require("@asaidimu/utils-logger");const i=Symbol.for(`delete`),a=e=>Array.isArray(e)?[...e]:{...e};function o(e){let t=e?.deleteMarker||i;function n(e){if(e==null)return e;if(Array.isArray(e))return e.filter(e=>e!==t).map(e=>typeof e==`object`&&e&&!Array.isArray(e)?n(e):e);if(typeof e==`object`){let r={};for(let[i,a]of Object.entries(e))if(a!==t)if(typeof a==`object`&&a){let e=n(a);e!==void 0&&(r[i]=e)}else r[i]=a;return r}return e===t?void 0:e}function r(e,r){if(typeof e!=`object`||!e)return typeof r==`object`&&r?n(r):r===t?{}:r;if(typeof r!=`object`||!r)return e;let i=a(e),o=[{target:i,source:r}];for(;o.length>0;){let{target:e,source:n}=o.pop();for(let r of Object.keys(n)){let i=n[r];if(i===t){delete e[r];continue}if(Array.isArray(i)){e[r]=i;continue}typeof i==`object`&&i?(e[r]=a(r in e&&typeof e[r]==`object`&&e[r]!==null?e[r]:{}),o.push({target:e[r],source:i})):e[r]=i}}return i}return r}const s=o(),c=[`map`,`filter`,`reduce`,`forEach`,`find`,`findIndex`,`some`,`every`,`includes`,`flatMap`,`flat`,`slice`,`splice`];var l=class{reactiveSelectors=new Map;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=>{let t=new Set;for(let n of e.deltas){let e=n.path;for(let[n,r]of this.dependencyMap)if(n===e||n.startsWith(e+`.`)||e.startsWith(n+`.`))for(let e of r)t.add(e)}for(let e of t){let t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}if(t!==e.lastResult){e.lastResult=t;for(let n of e.subscribers)n(t);this.eventBus.emit({name:`selector:changed`,payload:{selectorId:e.id,newResult:t,timestamp:Date.now()}})}}createReactiveSelector(e){let t=u(e),n=[...t].sort().join(`|`),r=this.pathBasedCache.get(n);if(r)return r.cleanupTimer!==void 0&&(clearTimeout(r.cleanupTimer),r.cleanupTimer=void 0),r.reactiveSelectorInstance;let i=`sel-${Math.random().toString(36).slice(2,9)}`,a={id:i,selector:e,lastResult:e(this.getState()),accessedPaths:t,subscribers:new Set,count:0,cleanupTimer:void 0,pathCacheKey:n,reactiveSelectorInstance:null};for(let e of t)this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(i);let o={id:i,get:()=>{try{return a.selector(this.getState())}catch{return}},subscribe:e=>(a.cleanupTimer!==void 0&&(clearTimeout(a.cleanupTimer),a.cleanupTimer=void 0),a.subscribers.add(e),a.count++,()=>{a.subscribers.delete(e),a.count--,a.count===0&&(a.cleanupTimer=setTimeout(()=>{a.count===0&&this.evictEntry(a)},0))})};return a.reactiveSelectorInstance=o,this.reactiveSelectors.set(i,a),this.pathBasedCache.set(n,a),this.eventBus.emit({name:`selector:accessed`,payload:{selectorId:i,accessedPaths:t,duration:0,timestamp:Date.now()}}),o}evictEntry(e){for(let t of e.accessedPaths){let n=this.dependencyMap.get(t);n&&(n.delete(e.id),n.size===0&&this.dependencyMap.delete(t))}this.reactiveSelectors.delete(e.id),this.pathBasedCache.delete(e.pathCacheKey)}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function u(e,t=`.`){let n=new Set,r=new Map,i=(e=``)=>{if(r.has(e))return r.get(e);let a=new Proxy(()=>{},{get:(r,a)=>{if(typeof a==`symbol`||a===`then`)return;if(a===`valueOf`||a===`toString`)throw Error(`Cannot perform logic, arithmetic, or string operations inside a selector.`);if(c.includes(a))throw Error(`Array method .${a}() is not allowed in selectors.`);let o=e?`${e}${t}${a}`:a;return e&&n.delete(e),n.add(o),i(o)},has:()=>{throw Error(`The 'in' operator is not allowed in selectors.`)},apply:()=>{throw Error(`Selectors cannot call functions or methods.`)}});return r.set(e,a),a};try{e(i())}catch(e){throw Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(n)}function d(e,t){if(e===t)return!0;if(e&&t&&typeof e==`object`&&typeof t==`object`){if(e.constructor!==t.constructor)return!1;let n,r;if(Array.isArray(e)){if(n=e.length,n!=t.length)return!1;for(r=n;r-->0;)if(!d(e[r],t[r]))return!1;return!0}let[i,a]=[Object.keys(e),Object.keys(t)];if(n=i.length,n!==a.length)return!1;for(r=n;r-->0;){let n=i[r];if(!Object.prototype.hasOwnProperty.call(t,n)||!d(e[n],t[n]))return!1}return!0}return e!==e&&t!==t}function f(e){let t=e?.deleteMarker||i;function n(e,n){let r=[],i=[{pathStr:``,orig:e||{},part:n||{}}];for(;i.length>0;){let{pathStr:e,orig:n,part:a}=i.pop();if(a!=null&&!d(n,a))if(typeof a==`object`&&!Array.isArray(a))for(let o of Object.keys(a)){let s=e?e+`.`+o:o,c=a[o],l=n&&typeof n==`object`?n[o]:void 0;if(c===t){l!==void 0&&r.push({path:s,oldValue:l,newValue:void 0});continue}typeof c==`object`&&c?i.push({pathStr:s,orig:l,part:c}):d(l,c)||r.push({path:s,oldValue:l,newValue:c})}else e&&r.push({path:e,oldValue:n,newValue:a})}return r}return n}function p(e){let t=e?.deleteMarker||i;function n(e){let n=new Set,r=[{obj:e,currentPath:``}];for(;r.length>0;){let{obj:e,currentPath:i}=r.pop();if(!(typeof e!=`object`||!e||Array.isArray(e)))for(let a of Object.keys(e)){let o=i?`${i}.${a}`:a;n.add(o);let s=e[a];typeof s==`object`&&s&&!Array.isArray(s)&&s!==t&&r.push({obj:s,currentPath:o})}}return Array.from(n)}return n}const m=f(),h=p();var g=class{updateBus;diff;cache;constructor(e,t,n){this.updateBus=t,this.diff=n,this.cache=structuredClone(e)}get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,n=!1,r=[]){if(t)return this.cache=n?structuredClone(e):e,this.notifyListeners([]),[];r.length===0&&(r=[e]);let i=this.get(!1),a=new Map;for(let e=0;e<r.length;e++){let t=r[e],n=this.diff(i,t);for(let e=0;e<n.length;e++){let t=n[e];a.set(t.path,t)}}let o=a.size?[...a.values()]:[];if(o.length>0){this.cache=n?structuredClone(e):e;let t=new Set;for(let e=0;e<o.length;e++){let n=o[e].path;for(;n&&!t.has(n);){t.add(n);let e=n.lastIndexOf(`.`);if(e<0)break;n=n.slice(0,e)}}this.notifyListeners(t)}return o}notifyListeners(e){for(let t of e)this.updateBus.emit({name:`update`,payload:t})}},_=class{eventBus;executionState;merge;logger;middleware=[];blockingMiddleware=[];constructor(e,t,n,r){this.eventBus=e,this.executionState=t,this.merge=n,this.logger=r}async executeBlocking(e,t){for(let{fn:n,name:r,id:i}of this.blockingMiddleware){let a={id:i,name:r,startTime:Date.now()};this.executionState.runningMiddleware={id:i,name:r,startTime:Date.now()},this.emitMiddlewareLifecycle(`start`,{id:i,name:r,type:`blocking`});try{let o=await Promise.resolve(n(e,t));if(a.endTime=Date.now(),a.duration=a.endTime-a.startTime,o===!1)return a.blocked=!0,this.emitMiddlewareLifecycle(`blocked`,{id:i,name:r,duration:a.duration}),this.emit(this.eventBus,{name:`middleware:executed`,payload:a}),{blocked:!0};this.emitMiddlewareLifecycle(`complete`,{id:i,name:r,type:`blocking`,duration:a.duration}),this.emit(this.eventBus,{name:`middleware:executed`,payload:{...a,blocked:!1}})}catch(e){return a.endTime=Date.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:Error(String(e)),a.blocked=!0,this.emitMiddlewareError(i,r,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 n=e,r=t;for(let{fn:e,name:i,id:a}of this.middleware){let o={id:a,name:i,startTime:Date.now()};this.executionState.runningMiddleware={id:a,name:i,startTime:Date.now()},this.emitMiddlewareLifecycle(`start`,{id:a,name:i,type:`transform`});try{let s=await Promise.resolve(e(n,t));o.endTime=Date.now(),o.duration=o.endTime-o.startTime,o.blocked=!1,s&&typeof s==`object`&&(n=this.merge(n,s),r=this.merge(r,s)),this.emit(this.eventBus,{name:`middleware:executed`,payload:o}),this.emitMiddlewareLifecycle(`complete`,{id:a,name:i,type:`transform`,duration:o.duration})}catch(e){o.endTime=Date.now(),o.duration=o.endTime-o.startTime,o.error=e instanceof Error?e:Error(String(e)),o.blocked=!1,this.emit(this.eventBus,{name:`middleware:executed`,payload:o}),this.emitMiddlewareError(a,i,o.error,o.duration),this.logger.error(`Middleware error`,{name:i,error:e})}finally{this.executionState.runningMiddleware=null}}return r}addMiddleware(e,t=`unnamed-middleware`){let n=this.generateId();return this.middleware.push({fn:e,name:t,id:n}),this.updateExecutionState(),n}addBlockingMiddleware(e,t=`unnamed-blocking-middleware`){let n=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:n}),this.updateExecutionState(),n}removeMiddleware(e){let 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,n,r){this.emit(this.eventBus,{name:`middleware:error`,payload:{id:e,name:t,error:n,duration:r,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)})}};let v;function y(e){return e||(v||=new r.Logger([]),v)}var b=class{eventBus;coreState;persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;logger;constructor(e,t,n,r){this.eventBus=e,this.coreState=t,this.instanceID=n,this.maxRetries=r?.maxRetries??3,this.retryDelay=r?.retryDelay??1e3,this.logger=r?.logger??y()}async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||e.length===0)return;let n={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(n),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:`persistence:queued`,payload:{taskId:n.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:n.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=>{let t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()}),await this.processQueue()}discardQueue(){let e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&=(clearTimeout(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=>{this.logger.error(`Queue processing failed`,{error:e})})},10))}async processQueue(){if(!(this.isProcessingQueue||this.backgroundQueue.length===0)){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){let 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,Error(`Persistence returned false`))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){let n=this.retryDelay*2**(e.retries-1);this.emit(this.eventBus,{name:`persistence:retry`,payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:n,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())},n)}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{let e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){this.logger.error(`Failed to initialize persistence`,{error: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=>{let 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)})}},x=class{eventBus;coreState;executionState;constructor(e,t,n){this.eventBus=e,this.coreState=t,this.executionState=n}async execute(e){let t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:`transaction:start`,payload:{timestamp:Date.now()}});try{let 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:Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask(()=>{e.emit(t)})}},S=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){let t=e.emit;e.emit=n=>(this.totalEventsFired++,t.call(e,n)),e.subscribe(`update:complete`,e=>{if(this.totalUpdates++,e.blocked){this.blockedUpdates++;return}if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();let 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=>{let 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()}},C=class extends Error{constructor(){super(`Action Cancelled by Debounce`),this.name=`ActionCancelledError`}},w=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name=`UnknownActionError`}};const T=()=>{},E={name:`UNDEFINED ACTION`,status:()=>!1,subscribe:e=>()=>{}};var D=class{eventBus;set;registrations=new Map;constructor(e,t){this.eventBus=e,this.set=t}register(e){let r={action:{name:e.name,id:(0,n.v4)(),action:e.fn,debounce:e.debounce?{...e.debounce,condition:e.debounce.condition??(()=>!0)}:void 0},debouncer:e.debounce&&e.debounce.delay>0?new t.Debouncer({delay:e.debounce.delay}):void 0,previousArgs:void 0,running:!1,subscription:{listeners:new Set,watcher:null,watchers:new t.SharedResource(()=>[this.eventBus.subscribe(`action:start`,t=>t.name===e.name&&this.notifyStatusListeners(e.name)),this.eventBus.subscribe(`action:complete`,t=>t.name===e.name&&this.notifyStatusListeners(e.name)),this.eventBus.subscribe(`action:error`,t=>t.name===e.name&&this.notifyStatusListeners(e.name))],e=>e?.forEach(e=>e()),{gracePeriod:`microtask`})}};return this.registrations.set(e.name,r),()=>{let t=this.registrations.get(e.name);t&&(t.debouncer?.cancel(),this.registrations.delete(e.name))}}async dispatch(e,...t){let n=this.registrations.get(e);if(!n)throw new w({action:e});let{action:r,debouncer:i}=n,{debounce:a}=r;if(!i||!a)return this.executeAction(n,t);let o=a.condition(n.previousArgs,t);if(n.previousArgs=t,!o)return this.executeAction(n,t);let s=await i.do(()=>this.executeAction(n,t));if(s.status===`cancelled`)throw new C;if(s.status===`error`&&s.error)throw s.error;return s.value}async executeAction(e,t){let n=Date.now();e.running=!0,this.emit(this.eventBus,{name:`action:start`,payload:{actionId:e.action.id,name:e.action.name,params:t||[],timestamp:n}});try{let r=await this.set(n=>e.action.action(n,...t),{actionId:e.action.id}),i=Date.now();return e.running=!1,this.emit(this.eventBus,{name:`action:complete`,payload:{actionId:e.action.id,name:e.action.name,params:t,startTime:n,endTime:i,duration:i-n,result:r}}),r}catch(r){let i=Date.now();throw e.running=!1,this.emit(this.eventBus,{name:`action:error`,payload:{actionId:e.action.id,name:e.action.name,params:t,startTime:n,endTime:i,duration:i-n,error:r}}),r}}running(e){let t=this.registrations.get(e);return t?t.running:!1}subscribe(e,t){let n=this.registrations.get(e);return n?(n.subscription.listeners.add(t),n.subscription.watchers.acquire(),()=>{n.subscription.listeners.delete(t),n.subscription.watchers?.release()}):T}watch(e){let t=this.registrations.get(e);return t?(t.subscription.watcher||(t.subscription.watcher={name:e,status:()=>this.running(e),subscribe:t=>this.subscribe(e,t)}),t.subscription.watcher):E}notifyStatusListeners(e){let t=this.registrations.get(e).subscription.listeners;t&&t.forEach(e=>e())}emit(e,t){queueMicrotask(()=>{e.emit(t)})}dispose(){for(let e of this.registrations.values())e.debouncer?.cancel(),e.subscription.watchers.forceCleanup,e.subscription.listeners.clear();this.registrations.clear()}},O=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new t.Serializer({yieldMode:`macrotask`,capacity:1e3});readyLatch=new t.Latch;disposeOnce=new t.Once;updateBus;eventBus;executionState;instanceID=(0,n.v4)();merge;diff;logger;constructor(t,n,r=i,a){this.logger=y(a?.logger),this.eventBus=(0,e.createEventBus)(a?.broadcastChannel?{batch:{size:0,delay:0},broadcast:{channel:a.broadcastChannel}}:void 0),this.updateBus=(0,e.createEventBus)(a?.broadcastChannel?{batch:{size:0,delay:0},broadcast:{channel:a.broadcastChannel}}:void 0),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=o({deleteMarker:r}),this.diff=f({deleteMarker:r}),this.coreState=new g(t,this.updateBus,this.diff),this.middlewareEngine=new _(this.eventBus,this.executionState,this.merge,this.logger),this.persistenceHandler=new b(this.eventBus,this.coreState,this.instanceID,{maxRetries:a?.persistenceMaxRetries,retryDelay:a?.persistenceRetryDelay,logger:this.logger}),this.transactionManager=new x(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new S(this.eventBus),this.actions=new D(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(n),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new l(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)}subset(e,t=`.`){let n={},r=this.get();for(let i of e)n[i]=i.split(t).reduce((e,t)=>e&&e[t]!==void 0?e[t]:void 0,r);return n}select(e){return this.checkDisposed(),this.selectorManager.createReactiveSelector(e)}register(e){return this.checkDisposed(),this.actions.register(e)}async dispatch(e,...t){return this.checkDisposed(),this.actions.dispatch(e,...t)}async set(e,t={}){this.checkDisposed();let n=await this.updateSerializer.do(()=>this._performUpdate(e,t));if(n.error)throw n.error;return n.value}async _performUpdate(e,t){let n=Date.now();this.emit(this.eventBus,{name:`update:start`,payload:{timestamp:n,actionId:t.actionId}});try{if(t.force){let r=this.get(!1),i=typeof e==`function`?e(r):e;this.coreState.applyChanges(i,!0);let a=Date.now();return this.emit(this.eventBus,{name:`update:complete`,payload:{deltas:[],duration:a-n,timestamp:Date.now(),actionId:t.actionId,newState:i}}),i}let r,i=this.get(!1);if(typeof e==`function`){let t=e(i);r=t instanceof Promise?await t:t}else r=e;let a=await this.middlewareEngine.executeBlocking(i,r);if(a.blocked)throw a.error||Error(`Update blocked by middleware`);let o=this.merge(i,r),s=await this.middlewareEngine.executeTransform(o,r),c=this.merge(o,s),l=this.coreState.applyChanges(c,!1,!1,[r,s]),u=Date.now(),d=this.get(!1);return this.emit(this.eventBus,{name:`update:complete`,payload:{deltas:l,duration:u-n,timestamp:Date.now(),actionId:t.actionId,newState:d}}),d}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(){if(this.persistenceHandler.isReady())this.readyLatch.open();else{let e=this.eventBus.subscribe(`persistence:ready`,()=>{this.readyLatch.isOpen()||this.readyLatch.open(),e()})}}setupPersistenceListener(){this.updateBus.subscribe(`update`,e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))})}watch(e,t,n){let r=Array.isArray(e)?e:[e],i=e===``||r.length===0;return this.updateBus.subscribe(`update`,e=>{(i||r.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)},n)}watchAction(e){return this.checkDisposed(),this.actions.watch(e)}debouncedSetter(e){let n=new t.Debouncer({delay:e.delay,leading:e.leading});return(e,t={})=>{n.fire(()=>this.set(e,t))}}id(){return this.instanceID}async transaction(e,t){this.checkDisposed();let n=await this.transactionManager.execute(e);return t?.flush&&await this.flush(),n}use(e){this.checkDisposed();let 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.checkDisposed(),this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flush(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){return this.disposeOnce.do(async()=>{await this.flush(),this.updateSerializer.close(),this.eventBus?.clear({permanent:!0}),this.updateBus?.clear({permanent:!0}),this.actions.dispose(),this.persistenceHandler.dispose(),this.metricsCollector.dispose(),this.selectorManager.dispose(),this.coreState=null,this.middlewareEngine=null,this.transactionManager=null,this.actions=null})}checkDisposed(){if(this.disposed())throw Error(`StoreExecutionDone: Cannot perform operations on a disposed store.`)}disposed(){return this.disposeOnce.done()}emit(e,t){queueMicrotask(()=>{e.emit(t)})}},k=class{stores=new Map;storeToOnce=new WeakMap;finalizer;onEvict;logger;constructor(e){this.onEvict=e?.onEvict,this.logger=y(e?.logger),this.finalizer=new FinalizationRegistry(({storeId:e,ref:t})=>{try{this.stores.get(e)===t&&(this.stores.delete(e),this.onEvict?.(e))}catch(t){this.logger.error(`StoreRegistry Finalizer error`,{storeId:e,error:t})}})}async get(e,n={}){let r=this.stores.get(e)?.deref();if(!r){r=new t.Once({throws:!1});let n=new WeakRef(r);this.stores.set(e,n),this.finalizer.register(r,{storeId:e,ref:n},r)}let i=await r.do(async()=>{let e=new O(n.state||{},n.persistence,n.deleteMarker,n.options);return await e.ready(),e},n.timeout);if(i.error)throw this.stores.get(e)?.deref()===r&&(this.stores.delete(e),this.finalizer.unregister(r)),i.error;let a=i.value;return this.storeToOnce.set(a,r),a}getSync(e,n={}){let r=this.stores.get(e)?.deref();if(!r){r=new t.Once({throws:!1});let n=new WeakRef(r);this.stores.set(e,n),this.finalizer.register(r,{storeId:e,ref:n},r)}let i=r.doSync(()=>new O(n.state||{},n.persistence,n.deleteMarker,n.options));if(i.error)throw this.stores.get(e)?.deref()===r&&(this.stores.delete(e),this.finalizer.unregister(r)),i.error;let a=i.value;return this.storeToOnce.set(a,r),a}async release(e){let t=this.stores.get(e);if(t){let n=t.deref();if(n&&(this.finalizer.unregister(n),n.done())){let t=n.get();if(t){try{await t.dispose()}catch(t){this.logger.error(`StoreRegistry Error disposing store during release`,{storeId:e,error:t})}this.storeToOnce.delete(t)}}return this.stores.delete(e)}return!1}async clear(){for(let e of this.stores.values()){let t=e.deref();if(t&&(this.finalizer.unregister(t),t.done())){let e=t.get();if(e){try{await e.dispose()}catch{}this.storeToOnce.delete(e)}}}this.stores.clear()}has(e){return this.stores.has(e)}get size(){return this.stores.size}},A=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;logger;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.logger=y(t.logger),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){if(this.isSilent)return;if(e===`group`||e===`groupEnd`||e===`table`){typeof console[e]==`function`&&console[e](...t);return}let n=typeof t[0]==`string`?t[0]:String(t[0]??``),r=t.length>1?{detail:t.slice(1)}:void 0;switch(e){case`log`:this.logger.log(n,r);break;case`warn`:this.logger.warn(n,r);break;case`error`:this.logger.error(n,r);break;case`debug`:this.logger.debug(n,r);break}}setupEventListeners(){for(let e of[`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`]){let t=e.startsWith(`update`)&&this.logEvents.updates||e.startsWith(`middleware`)&&this.logEvents.middleware||e.startsWith(`transaction`)&&this.logEvents.transactions||e.startsWith(`action`)&&this.logEvents.actions||e.startsWith(`selector`)&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(e,n=>{this.isTimeTraveling||(e===`update:complete`&&!n.blocked&&this.recordStateSnapshot(n.deltas),e===`middleware:executed`?this.middlewareExecutions.push(n):e===`transaction:start`?this.activeTransactionCount++:(e===`transaction:complete`||e===`transaction:error`)&&(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),n.batchId&&(e.endsWith(`start`)?this.activeBatches.add(n.batchId):(e.endsWith(`complete`)||e.endsWith(`error`))&&this.activeBatches.delete(n.batchId)),this.recordEvent(e,n),this.enableConsoleLogging&&t&&this._log(e,n),this._checkPerformance(e,n))}))}}recordStateSnapshot(e){let 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){let n={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(n),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={}){let{logLevel:t=`debug`,logUpdates:n=!0}=e;return(e,r)=>(n&&this.logger[t](`State Update`,{update:r}),r)}createValidationMiddleware(e){return(t,n)=>{let r=e(t,n);return typeof r==`boolean`?r:(!r.valid&&r.reason&&this._consoleLog(`warn`,`Validation failed:`,r.reason),r.valid)}}getRecentChanges(e=5){let t=[],n=Math.min(e,this.stateHistory.length);for(let e=0;e<n;e++){let n=this.stateHistory[e];if(!n.deltas||n.deltas.length===0)continue;let r={},i={},a=(e,t,n)=>{t.reduce((e,r,i)=>(i===t.length-1?e[r]=n:e[r]=e[r]??{},e[r]),e)};for(let e of n.deltas){let t=e.path.split(`.`);a(r,t,e.oldValue),a(i,t,e.newValue)}t.push({timestamp:n.timestamp,changedPaths:n.deltas.map(e=>e.path),from:r,to:i})}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){let t=this.eventHistory.filter(e=>e.type===`update:start`)[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=[],n=this.store.on(`update:complete`,n=>{!this.isTimeTraveling&&!n.blocked&&(t=[],e=0)});this.unsubscribers.push(n);let r=()=>this.stateHistory.length,i=()=>e<r()-1,a=()=>t.length>0;return{canUndo:i,canRedo:a,undo:async()=>{if(!i())return;t.unshift(this.stateHistory[e]),e++;let n=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...n},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;let n=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...n.state},{force:!0}),this.isTimeTraveling=!1},length:r,clear:()=>{t=[],e=0}}}async saveSession(e){let t=this.store.id(),n={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,n))}async loadSession(e){let 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):!1}exportSession(){let e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`store-observer-session-${new Date().toISOString()}.json`,r.click(),URL.revokeObjectURL(n)}importSession(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=async e=>{try{let n=JSON.parse(e.target?.result);this.eventHistory=n.eventHistory||[],this.stateHistory=n.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){n(e)}},r.onerror=e=>n(e),r.readAsText(e)})}disconnect(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){let n=new Date(t.timestamp||Date.now()).toISOString().split(`T`)[1].replace(`Z`,``);if(e===`update:start`)this._consoleLog(`group`,`%c⚡ Store Update Started [${n}]`,`color: #4a6da7`);else if(e===`update:complete`){if(t.blocked)this._consoleLog(`warn`,`%c✋ Update Blocked [${n}]`,`color: #bf8c0a`,t.error);else{let e=t.deltas||[];e.length>0&&(this._consoleLog(`log`,`%c✅ Update Complete [${n}] - ${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 e===`middleware:start`?this._consoleLog(`debug`,`%c◀ Middleware \"${t.name}\" started [${n}] (${t.type})`,`color: #8c8c8c`):e===`middleware:complete`?this._consoleLog(`debug`,`%c▶ Middleware \"${t.name}\" completed [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #7c9c7c`):e===`middleware:error`?this._consoleLog(`error`,`%c❌ Middleware \"${t.name}\" error [${n}]:`,`color: #e63946`,t.error):e===`middleware:blocked`?this._consoleLog(`warn`,`%c🛑 Middleware \"${t.name}\" blocked update [${n}]`,`color: #e76f51`):e===`transaction:start`?this._consoleLog(`group`,`%c📦 Transaction Started [${n}]`,`color: #6d597a`):e===`transaction:complete`?(this._consoleLog(`log`,`%c📦 Transaction Complete [${n}]`,`color: #355070`),this._consoleLog(`groupEnd`)):e===`transaction:error`?(this._consoleLog(`error`,`%c📦 Transaction Error [${n}]:`,`color: #e56b6f`,t.error),this._consoleLog(`groupEnd`)):e===`action:start`?this._consoleLog(`group`,`%c🚀 Action \"${t.name}\" Started [${n}]`,`color: #9b59b6`,{params:t.params}):e===`action:complete`?(this._consoleLog(`log`,`%c✔️ Action \"${t.name}\" Complete [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #2ecc71`),this._consoleLog(`groupEnd`)):e===`action:error`?(this._consoleLog(`error`,`%c🔥 Action \"${t.name}\" Error [${n}]:`,`color: #e74c3c`,t.error),this._consoleLog(`groupEnd`)):e===`selector:accessed`&&this._consoleLog(`debug`,`%c👀 Selector Accessed [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #f1c40f`,{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&(e===`update:complete`&&!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}),e===`middleware:complete`&&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.ActionCancelledError=C,exports.ActionManager=D,exports.DELETE_SYMBOL=i,exports.ReactiveDataStore=O,exports.StoreObserver=A,exports.StoreRegistry=k,exports.UnknownActionError=w,exports.createDerivePaths=p,exports.createDiff=f,exports.createMerge=o,exports.createStoreLogger=y,exports.derivePaths=h,exports.diff=m,exports.merge=s,exports.shallowClone=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@asaidimu/utils-events"),t=require("@asaidimu/utils-sync"),n=require("uuid"),r=require("@asaidimu/utils-logger");const i=Symbol.for(`delete`),a=e=>Array.isArray(e)?[...e]:{...e};function o(e){let t=e?.deleteMarker||i;function n(e){if(e==null)return e;if(Array.isArray(e))return e.filter(e=>e!==t).map(e=>typeof e==`object`&&e&&!Array.isArray(e)?n(e):e);if(typeof e==`object`){let r={};for(let[i,a]of Object.entries(e))if(a!==t)if(typeof a==`object`&&a){let e=n(a);e!==void 0&&(r[i]=e)}else r[i]=a;return r}return e===t?void 0:e}function r(e,r){if(typeof e!=`object`||!e)return typeof r==`object`&&r?n(r):r===t?{}:r;if(typeof r!=`object`||!r)return e;let i=a(e),o=[{target:i,source:r}];for(;o.length>0;){let{target:e,source:n}=o.pop();for(let r of Object.keys(n)){let i=n[r];if(i===t){delete e[r];continue}if(Array.isArray(i)){e[r]=i;continue}typeof i==`object`&&i?(e[r]=a(r in e&&typeof e[r]==`object`&&e[r]!==null?e[r]:{}),o.push({target:e[r],source:i})):e[r]=i}}return i}return r}const s=o(),c=[`map`,`filter`,`reduce`,`forEach`,`find`,`findIndex`,`some`,`every`,`includes`,`flatMap`,`flat`,`slice`,`splice`];var l=class{reactiveSelectors=new Map;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=>{let t=new Set;for(let n of e.deltas){let e=n.path;for(let[n,r]of this.dependencyMap)if(n===e||n.startsWith(e+`.`)||e.startsWith(n+`.`))for(let e of r)t.add(e)}for(let e of t){let t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}if(t!==e.lastResult){e.lastResult=t;for(let n of e.subscribers)n(t);this.eventBus.emit({name:`selector:changed`,payload:{selectorId:e.id,newResult:t,timestamp:Date.now()}})}}createReactiveSelector(e){let t=u(e),n=[...t].sort().join(`|`),r=this.pathBasedCache.get(n);if(r)return r.cleanupTimer!==void 0&&(clearTimeout(r.cleanupTimer),r.cleanupTimer=void 0),r.reactiveSelectorInstance;let i=`sel-${Math.random().toString(36).slice(2,9)}`,a={id:i,selector:e,lastResult:e(this.getState()),accessedPaths:t,subscribers:new Set,count:0,cleanupTimer:void 0,pathCacheKey:n,reactiveSelectorInstance:null};for(let e of t)this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(i);let o={id:i,get:()=>{try{return a.selector(this.getState())}catch{return}},subscribe:e=>(a.cleanupTimer!==void 0&&(clearTimeout(a.cleanupTimer),a.cleanupTimer=void 0),a.subscribers.add(e),a.count++,()=>{a.subscribers.delete(e),a.count--,a.count===0&&(a.cleanupTimer=setTimeout(()=>{a.count===0&&this.evictEntry(a)},0))})};return a.reactiveSelectorInstance=o,this.reactiveSelectors.set(i,a),this.pathBasedCache.set(n,a),this.eventBus.emit({name:`selector:accessed`,payload:{selectorId:i,accessedPaths:t,duration:0,timestamp:Date.now()}}),o}evictEntry(e){for(let t of e.accessedPaths){let n=this.dependencyMap.get(t);n&&(n.delete(e.id),n.size===0&&this.dependencyMap.delete(t))}this.reactiveSelectors.delete(e.id),this.pathBasedCache.delete(e.pathCacheKey)}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function u(e,t=`.`){let n=new Set,r=new Map,i=(e=``)=>{if(r.has(e))return r.get(e);let a=new Proxy(()=>{},{get:(r,a)=>{if(typeof a==`symbol`||a===`then`)return;if(a===`valueOf`||a===`toString`)throw Error(`Cannot perform logic, arithmetic, or string operations inside a selector.`);if(c.includes(a))throw Error(`Array method .${a}() is not allowed in selectors.`);let o=e?`${e}${t}${a}`:a;return e&&n.delete(e),n.add(o),i(o)},has:()=>{throw Error(`The 'in' operator is not allowed in selectors.`)},apply:()=>{throw Error(`Selectors cannot call functions or methods.`)}});return r.set(e,a),a};try{e(i())}catch(e){throw Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(n)}function d(e,t){if(e===t)return!0;if(e&&t&&typeof e==`object`&&typeof t==`object`){if(e.constructor!==t.constructor)return!1;let n,r;if(Array.isArray(e)){if(n=e.length,n!=t.length)return!1;for(r=n;r-->0;)if(!d(e[r],t[r]))return!1;return!0}let[i,a]=[Object.keys(e),Object.keys(t)];if(n=i.length,n!==a.length)return!1;for(r=n;r-->0;){let n=i[r];if(!Object.prototype.hasOwnProperty.call(t,n)||!d(e[n],t[n]))return!1}return!0}return e!==e&&t!==t}function f(e){let t=e?.deleteMarker||i;function n(e,n){let r=[],i=[{pathStr:``,orig:e||{},part:n||{}}];for(;i.length>0;){let{pathStr:e,orig:n,part:a}=i.pop();if(a!=null&&!d(n,a))if(typeof a==`object`&&!Array.isArray(a))for(let o of Object.keys(a)){let s=e?e+`.`+o:o,c=a[o],l=n&&typeof n==`object`?n[o]:void 0;if(c===t){l!==void 0&&r.push({path:s,oldValue:l,newValue:void 0});continue}typeof c==`object`&&c?i.push({pathStr:s,orig:l,part:c}):d(l,c)||r.push({path:s,oldValue:l,newValue:c})}else e&&r.push({path:e,oldValue:n,newValue:a})}return r}return n}function p(e){let t=e?.deleteMarker||i;function n(e){let n=new Set,r=[{obj:e,currentPath:``}];for(;r.length>0;){let{obj:e,currentPath:i}=r.pop();if(!(typeof e!=`object`||!e||Array.isArray(e)))for(let a of Object.keys(e)){let o=i?`${i}.${a}`:a;n.add(o);let s=e[a];typeof s==`object`&&s&&!Array.isArray(s)&&s!==t&&r.push({obj:s,currentPath:o})}}return Array.from(n)}return n}const m=f(),h=p();var g=class{updateBus;diff;cache;constructor(e,t,n){this.updateBus=t,this.diff=n,this.cache=structuredClone(e)}get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,n=!1,r=[]){if(t)return this.cache=n?structuredClone(e):e,this.notifyListeners([]),[];r.length===0&&(r=[e]);let i=this.get(!1),a=new Map;for(let e=0;e<r.length;e++){let t=r[e],n=this.diff(i,t);for(let e=0;e<n.length;e++){let t=n[e];a.set(t.path,t)}}let o=a.size?[...a.values()]:[];if(o.length>0){this.cache=n?structuredClone(e):e;let t=new Set;for(let e=0;e<o.length;e++){let n=o[e].path;for(;n&&!t.has(n);){t.add(n);let e=n.lastIndexOf(`.`);if(e<0)break;n=n.slice(0,e)}}this.notifyListeners(t)}return o}notifyListeners(e){for(let t of e)this.updateBus.emit({name:`update`,payload:t})}},_=class{eventBus;executionState;merge;logger;middleware=[];blockingMiddleware=[];constructor(e,t,n,r){this.eventBus=e,this.executionState=t,this.merge=n,this.logger=r}async executeBlocking(e,t){for(let{fn:n,name:r,id:i}of this.blockingMiddleware){let a={id:i,name:r,startTime:Date.now()};this.executionState.runningMiddleware={id:i,name:r,startTime:Date.now()},this.emitMiddlewareLifecycle(`start`,{id:i,name:r,type:`blocking`});try{let o=await Promise.resolve(n(e,t));if(a.endTime=Date.now(),a.duration=a.endTime-a.startTime,o===!1)return a.blocked=!0,this.emitMiddlewareLifecycle(`blocked`,{id:i,name:r,duration:a.duration}),this.emit(this.eventBus,{name:`middleware:executed`,payload:a}),{blocked:!0};this.emitMiddlewareLifecycle(`complete`,{id:i,name:r,type:`blocking`,duration:a.duration}),this.emit(this.eventBus,{name:`middleware:executed`,payload:{...a,blocked:!1}})}catch(e){return a.endTime=Date.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:Error(String(e)),a.blocked=!0,this.emitMiddlewareError(i,r,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 n=e,r=t;for(let{fn:e,name:i,id:a}of this.middleware){let o={id:a,name:i,startTime:Date.now()};this.executionState.runningMiddleware={id:a,name:i,startTime:Date.now()},this.emitMiddlewareLifecycle(`start`,{id:a,name:i,type:`transform`});try{let s=await Promise.resolve(e(n,t));o.endTime=Date.now(),o.duration=o.endTime-o.startTime,o.blocked=!1,s&&typeof s==`object`&&(n=this.merge(n,s),r=this.merge(r,s)),this.emit(this.eventBus,{name:`middleware:executed`,payload:o}),this.emitMiddlewareLifecycle(`complete`,{id:a,name:i,type:`transform`,duration:o.duration})}catch(e){o.endTime=Date.now(),o.duration=o.endTime-o.startTime,o.error=e instanceof Error?e:Error(String(e)),o.blocked=!1,this.emit(this.eventBus,{name:`middleware:executed`,payload:o}),this.emitMiddlewareError(a,i,o.error,o.duration),this.logger.error(`Middleware error`,{name:i,error:e})}finally{this.executionState.runningMiddleware=null}}return r}addMiddleware(e,t=`unnamed-middleware`){let n=this.generateId();return this.middleware.push({fn:e,name:t,id:n}),this.updateExecutionState(),n}addBlockingMiddleware(e,t=`unnamed-blocking-middleware`){let n=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:n}),this.updateExecutionState(),n}removeMiddleware(e){let 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,n,r){this.emit(this.eventBus,{name:`middleware:error`,payload:{id:e,name:t,error:n,duration:r,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)})}};let v;function y(e){return e||(v||=new r.Logger([]),v)}var b=class{eventBus;coreState;persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;logger;constructor(e,t,n,r){this.eventBus=e,this.coreState=t,this.instanceID=n,this.maxRetries=r?.maxRetries??3,this.retryDelay=r?.retryDelay??1e3,this.logger=r?.logger??y()}async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||e.length===0)return;let n={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(n),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:`persistence:queued`,payload:{taskId:n.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:n.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=>{let t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()}),await this.processQueue()}discardQueue(){let e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&=(clearTimeout(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=>{this.logger.error(`Queue processing failed`,{error:e})})},10))}async processQueue(){if(!(this.isProcessingQueue||this.backgroundQueue.length===0)){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){let 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,Error(`Persistence returned false`))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){let n=this.retryDelay*2**(e.retries-1);this.emit(this.eventBus,{name:`persistence:retry`,payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:n,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())},n)}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{let e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){this.logger.error(`Failed to initialize persistence`,{error: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=>{let 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)})}},x=class{eventBus;coreState;executionState;constructor(e,t,n){this.eventBus=e,this.coreState=t,this.executionState=n}async execute(e){let t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:`transaction:start`,payload:{timestamp:Date.now()}});try{let 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:Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask(()=>{e.emit(t)})}},S=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){let t=e.emit;e.emit=n=>(this.totalEventsFired++,t.call(e,n)),e.subscribe(`update:complete`,e=>{if(this.totalUpdates++,e.blocked){this.blockedUpdates++;return}if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();let 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=>{let 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()}},C=class extends Error{constructor(){super(`Action Cancelled by Debounce`),this.name=`ActionCancelledError`}},w=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name=`UnknownActionError`}};const T=()=>{},E={name:`UNDEFINED ACTION`,status:()=>!1,subscribe:e=>()=>{}};var D=class{eventBus;set;registrations=new Map;constructor(e,t){this.eventBus=e,this.set=t}register(e){let r={action:{name:e.name,id:(0,n.v4)(),action:e.fn,debounce:e.debounce?{...e.debounce,condition:e.debounce.condition??(()=>!0)}:void 0},debouncer:e.debounce&&e.debounce.delay>0?new t.Debouncer({delay:e.debounce.delay}):void 0,previousArgs:void 0,running:!1,subscription:{listeners:new Set,watcher:null,watchers:new t.SharedResource(()=>[this.eventBus.subscribe(`action:start`,t=>t.name===e.name&&this.notifyStatusListeners(e.name)),this.eventBus.subscribe(`action:complete`,t=>t.name===e.name&&this.notifyStatusListeners(e.name)),this.eventBus.subscribe(`action:error`,t=>t.name===e.name&&this.notifyStatusListeners(e.name))],e=>e?.forEach(e=>e()),{gracePeriod:`microtask`})}};return this.registrations.set(e.name,r),()=>{let t=this.registrations.get(e.name);t&&(t.debouncer?.cancel(),this.registrations.delete(e.name))}}async dispatch(e,...t){let n=this.registrations.get(e);if(!n)throw new w({action:e});let{action:r,debouncer:i}=n,{debounce:a}=r;if(!i||!a)return this.executeAction(n,t);let o=a.condition(n.previousArgs,t);if(n.previousArgs=t,!o)return this.executeAction(n,t);let s=await i.do(()=>this.executeAction(n,t));if(s.status===`cancelled`)throw new C;if(s.status===`error`&&s.error)throw s.error;return s.value}async executeAction(e,t){let n=Date.now();e.running=!0,this.emit(this.eventBus,{name:`action:start`,payload:{actionId:e.action.id,name:e.action.name,params:t||[],timestamp:n}});try{let r=await this.set(n=>e.action.action(n,...t),{actionId:e.action.id}),i=Date.now();return e.running=!1,this.emit(this.eventBus,{name:`action:complete`,payload:{actionId:e.action.id,name:e.action.name,params:t,startTime:n,endTime:i,duration:i-n,result:r}}),r}catch(r){let i=Date.now();throw e.running=!1,this.emit(this.eventBus,{name:`action:error`,payload:{actionId:e.action.id,name:e.action.name,params:t,startTime:n,endTime:i,duration:i-n,error:r}}),r}}running(e){let t=this.registrations.get(e);return t?t.running:!1}subscribe(e,t){let n=this.registrations.get(e);return n?(n.subscription.listeners.add(t),n.subscription.watchers.acquire(),()=>{n.subscription.listeners.delete(t),n.subscription.watchers?.release()}):T}watch(e){let t=this.registrations.get(e);return t?(t.subscription.watcher||(t.subscription.watcher={name:e,status:()=>this.running(e),subscribe:t=>this.subscribe(e,t)}),t.subscription.watcher):E}notifyStatusListeners(e){let t=this.registrations.get(e).subscription.listeners;t&&t.forEach(e=>e())}emit(e,t){queueMicrotask(()=>{e.emit(t)})}dispose(){for(let e of this.registrations.values())e.debouncer?.cancel(),e.subscription.watchers.forceCleanup,e.subscription.listeners.clear();this.registrations.clear()}},O=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new t.Serializer({yieldMode:`macrotask`,capacity:1e3});readyLatch=new t.Latch;disposeOnce=new t.Once;updateBus;eventBus;executionState;instanceID=(0,n.v4)();merge;diff;logger;constructor(t,n,r=i,a){this.logger=y(a?.logger),this.eventBus=(0,e.createEventBus)(a?.broadcastChannel?{batch:{size:0,delay:0},broadcast:{channel:a.broadcastChannel}}:void 0),this.updateBus=(0,e.createEventBus)(a?.broadcastChannel?{batch:{size:0,delay:0},broadcast:{channel:a.broadcastChannel}}:void 0),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=o({deleteMarker:r}),this.diff=f({deleteMarker:r}),this.coreState=new g(t,this.updateBus,this.diff),this.middlewareEngine=new _(this.eventBus,this.executionState,this.merge,this.logger),this.persistenceHandler=new b(this.eventBus,this.coreState,this.instanceID,{maxRetries:a?.persistenceMaxRetries,retryDelay:a?.persistenceRetryDelay,logger:this.logger}),this.transactionManager=new x(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new S(this.eventBus),this.actions=new D(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(n),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new l(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)}subset(e,t=`.`){let n={},r=this.get();for(let i of e)n[i]=i.split(t).reduce((e,t)=>e&&e[t]!==void 0?e[t]:void 0,r);return n}select(e){return this.checkDisposed(),this.selectorManager.createReactiveSelector(e)}register(e){return this.checkDisposed(),this.actions.register(e)}async dispatch(e,...t){return this.checkDisposed(),this.actions.dispatch(e,...t)}async set(e,t={}){this.checkDisposed();let n=await this.updateSerializer.do(()=>this._performUpdate(e,t));if(n.error)throw n.error;return n.value}async _performUpdate(e,t){let n=Date.now();this.emit(this.eventBus,{name:`update:start`,payload:{timestamp:n,actionId:t.actionId}});try{if(t.force){let r=this.get(!1),i=typeof e==`function`?e(r):e;this.coreState.applyChanges(i,!0);let a=Date.now();return this.emit(this.eventBus,{name:`update:complete`,payload:{deltas:[],duration:a-n,timestamp:Date.now(),actionId:t.actionId,newState:i}}),i}let r,i=this.get(!1);if(typeof e==`function`){let t=e(i);r=t instanceof Promise?await t:t}else r=e;let a=await this.middlewareEngine.executeBlocking(i,r);if(a.blocked)throw a.error||Error(`Update blocked by middleware`);let o=this.merge(i,r),s=await this.middlewareEngine.executeTransform(o,r),c=this.merge(o,s),l=this.coreState.applyChanges(c,!1,!1,[r,s]),u=Date.now(),d=this.get(!1);return this.emit(this.eventBus,{name:`update:complete`,payload:{deltas:l,duration:u-n,timestamp:Date.now(),actionId:t.actionId,newState:d}}),d}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(){if(this.persistenceHandler.isReady())this.readyLatch.open();else{let e=this.eventBus.subscribe(`persistence:ready`,()=>{this.readyLatch.isOpen()||this.readyLatch.open(),e()})}}setupPersistenceListener(){this.updateBus.subscribe(`update`,e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))})}watch(e,t,n){let r=Array.isArray(e)?e:[e],i=e===``||r.length===0;return this.updateBus.subscribe(`update`,e=>{(i||r.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)},n)}watchAction(e){return this.checkDisposed(),this.actions.watch(e)}debouncedSetter(e){let n=new t.Debouncer({delay:e.delay,leading:e.leading});return(e,t={})=>{n.fire(()=>this.set(e,t))}}id(){return this.instanceID}async transaction(e,t){this.checkDisposed();let n=await this.transactionManager.execute(e);return t?.flush&&await this.flush(),n}use(e){this.checkDisposed();let 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.checkDisposed(),this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flush(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){return this.disposeOnce.do(async()=>{await this.flush(),this.updateSerializer.close(),this.eventBus?.clear({permanent:!0}),this.updateBus?.clear({permanent:!0}),this.actions.dispose(),this.persistenceHandler.dispose(),this.metricsCollector.dispose(),this.selectorManager.dispose(),this.coreState=null,this.middlewareEngine=null,this.transactionManager=null,this.actions=null})}checkDisposed(){if(this.disposed())throw Error(`StoreExecutionDone: Cannot perform operations on a disposed store.`)}disposed(){return this.disposeOnce.done()}emit(e,t){queueMicrotask(()=>{e.emit(t)})}},k=class{stores=new Map;storeToOnce=new WeakMap;finalizer;onEvict;logger;constructor(e){this.onEvict=e?.onEvict,this.logger=y(e?.logger),this.finalizer=new FinalizationRegistry(({storeId:e,ref:t})=>{try{this.stores.get(e)===t&&(this.stores.delete(e),this.onEvict?.(e))}catch(t){this.logger.error(`StoreRegistry Finalizer error`,{storeId:e,error:t})}})}async get(e,n={}){let r=this.stores.get(e)?.deref();if(!r){r=new t.Once({throws:!1});let n=new WeakRef(r);this.stores.set(e,n),this.finalizer.register(r,{storeId:e,ref:n},r)}let i=await r.do(async()=>{let e=new O(n.state||{},n.persistence,n.deleteMarker,n.options);return await e.ready(),e},n.timeout);if(i.error)throw this.stores.get(e)?.deref()===r&&(this.stores.delete(e),this.finalizer.unregister(r)),i.error;let a=i.value;return this.storeToOnce.set(a,r),a}getSync(e,n={}){let r=this.stores.get(e)?.deref();if(!r){r=new t.Once({throws:!1});let n=new WeakRef(r);this.stores.set(e,n),this.finalizer.register(r,{storeId:e,ref:n},r)}let i=r.doSync(()=>new O(n.state||{},n.persistence,n.deleteMarker,n.options));if(i.error)throw this.stores.get(e)?.deref()===r&&(this.stores.delete(e),this.finalizer.unregister(r)),i.error;let a=i.value;return this.storeToOnce.set(a,r),a}async release(e){let t=this.stores.get(e);if(t){let n=t.deref();if(n&&(this.finalizer.unregister(n),n.done())){let t=n.get();if(t){try{await t.dispose()}catch(t){this.logger.error(`StoreRegistry Error disposing store during release`,{storeId:e,error:t})}this.storeToOnce.delete(t)}}return this.stores.delete(e)}return!1}async clear(){for(let e of this.stores.values()){let t=e.deref();if(t&&(this.finalizer.unregister(t),t.done())){let e=t.get();if(e){try{await e.dispose()}catch{}this.storeToOnce.delete(e)}}}this.stores.clear()}has(e){return this.stores.has(e)}get size(){return this.stores.size}},A=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;logger;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.logger=y(t.logger),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){if(this.isSilent)return;if(e===`group`||e===`groupEnd`||e===`table`){typeof console[e]==`function`&&console[e](...t);return}let n=typeof t[0]==`string`?t[0]:String(t[0]??``),r=t.length>1?{detail:t.slice(1)}:void 0;switch(e){case`log`:this.logger.log(n,r);break;case`warn`:this.logger.warn(n,r);break;case`error`:this.logger.error(n,r);break;case`debug`:this.logger.debug(n,r);break}}setupEventListeners(){for(let e of[`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`]){let t=e.startsWith(`update`)&&this.logEvents.updates||e.startsWith(`middleware`)&&this.logEvents.middleware||e.startsWith(`transaction`)&&this.logEvents.transactions||e.startsWith(`action`)&&this.logEvents.actions||e.startsWith(`selector`)&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(e,n=>{this.isTimeTraveling||(e===`update:complete`&&!n.blocked&&this.recordStateSnapshot(n.deltas),e===`middleware:executed`?this.middlewareExecutions.push(n):e===`transaction:start`?this.activeTransactionCount++:(e===`transaction:complete`||e===`transaction:error`)&&(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),n.batchId&&(e.endsWith(`start`)?this.activeBatches.add(n.batchId):(e.endsWith(`complete`)||e.endsWith(`error`))&&this.activeBatches.delete(n.batchId)),this.recordEvent(e,n),this.enableConsoleLogging&&t&&this._log(e,n),this._checkPerformance(e,n))}))}}recordStateSnapshot(e){let 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){let n={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(n),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={}){let{logLevel:t=`debug`,logUpdates:n=!0}=e;return(e,r)=>(n&&this.logger[t](`State Update`,{update:r}),r)}createValidationMiddleware(e){return(t,n)=>{let r=e(t,n);return typeof r==`boolean`?r:(!r.valid&&r.reason&&this._consoleLog(`warn`,`Validation failed:`,r.reason),r.valid)}}getRecentChanges(e=5){let t=[],n=Math.min(e,this.stateHistory.length);for(let e=0;e<n;e++){let n=this.stateHistory[e];if(!n.deltas||n.deltas.length===0)continue;let r={},i={},a=(e,t,n)=>{t.reduce((e,r,i)=>(i===t.length-1?e[r]=n:e[r]=e[r]??{},e[r]),e)};for(let e of n.deltas){let t=e.path.split(`.`);a(r,t,e.oldValue),a(i,t,e.newValue)}t.push({timestamp:n.timestamp,changedPaths:n.deltas.map(e=>e.path),from:r,to:i})}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){let t=this.eventHistory.filter(e=>e.type===`update:start`)[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=[],n=this.store.on(`update:complete`,n=>{!this.isTimeTraveling&&!n.blocked&&(t=[],e=0)});this.unsubscribers.push(n);let r=()=>this.stateHistory.length,i=()=>e<r()-1,a=()=>t.length>0;return{canUndo:i,canRedo:a,undo:async()=>{if(!i())return;t.unshift(this.stateHistory[e]),e++;let n=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...n},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;let n=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...n.state},{force:!0}),this.isTimeTraveling=!1},length:r,clear:()=>{t=[],e=0}}}async saveSession(e){let t=this.store.id(),n={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,n))}async loadSession(e){let 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):!1}exportSession(){let e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`store-observer-session-${new Date().toISOString()}.json`,r.click(),URL.revokeObjectURL(n)}importSession(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=async e=>{try{let n=JSON.parse(e.target?.result);this.eventHistory=n.eventHistory||[],this.stateHistory=n.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){n(e)}},r.onerror=e=>n(e),r.readAsText(e)})}disconnect(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){let n=new Date(t.timestamp||Date.now()).toISOString().split(`T`)[1].replace(`Z`,``);if(e===`update:start`)this._consoleLog(`group`,`%c⚡ Store Update Started [${n}]`,`color: #4a6da7`);else if(e===`update:complete`){if(t.blocked)this._consoleLog(`warn`,`%c✋ Update Blocked [${n}]`,`color: #bf8c0a`,t.error);else{let e=t.deltas||[];e.length>0&&(this._consoleLog(`log`,`%c✅ Update Complete [${n}] - ${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 e===`middleware:start`?this._consoleLog(`debug`,`%c◀ Middleware \"${t.name}\" started [${n}] (${t.type})`,`color: #8c8c8c`):e===`middleware:complete`?this._consoleLog(`debug`,`%c▶ Middleware \"${t.name}\" completed [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #7c9c7c`):e===`middleware:error`?this._consoleLog(`error`,`%c❌ Middleware \"${t.name}\" error [${n}]:`,`color: #e63946`,t.error):e===`middleware:blocked`?this._consoleLog(`warn`,`%c🛑 Middleware \"${t.name}\" blocked update [${n}]`,`color: #e76f51`):e===`transaction:start`?this._consoleLog(`group`,`%c📦 Transaction Started [${n}]`,`color: #6d597a`):e===`transaction:complete`?(this._consoleLog(`log`,`%c📦 Transaction Complete [${n}]`,`color: #355070`),this._consoleLog(`groupEnd`)):e===`transaction:error`?(this._consoleLog(`error`,`%c📦 Transaction Error [${n}]:`,`color: #e56b6f`,t.error),this._consoleLog(`groupEnd`)):e===`action:start`?this._consoleLog(`group`,`%c🚀 Action \"${t.name}\" Started [${n}]`,`color: #9b59b6`,{params:t.params}):e===`action:complete`?(this._consoleLog(`log`,`%c✔️ Action \"${t.name}\" Complete [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #2ecc71`),this._consoleLog(`groupEnd`)):e===`action:error`?(this._consoleLog(`error`,`%c🔥 Action \"${t.name}\" Error [${n}]:`,`color: #e74c3c`,t.error),this._consoleLog(`groupEnd`)):e===`selector:accessed`&&this._consoleLog(`debug`,`%c👀 Selector Accessed [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #f1c40f`,{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&(e===`update:complete`&&!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}),e===`middleware:complete`&&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.ActionCancelledError=C,exports.ActionManager=D,exports.DELETE_SYMBOL=i,exports.ReactiveDataStore=O,exports.SelectorManager=l,exports.StoreObserver=A,exports.StoreRegistry=k,exports.UnknownActionError=w,exports.buildPaths=u,exports.createDerivePaths=p,exports.createDiff=f,exports.createMerge=o,exports.createStoreLogger=y,exports.derivePaths=h,exports.diff=m,exports.merge=s,exports.shallowClone=a;
package/index.mjs CHANGED
@@ -1 +1 @@
1
- import{createEventBus as e}from"@asaidimu/utils-events";import{Debouncer as t,Latch as n,Once as r,Serializer as i,SharedResource as a}from"@asaidimu/utils-sync";import{v4 as o}from"uuid";import{Logger as s}from"@asaidimu/utils-logger";const c=Symbol.for(`delete`),l=e=>Array.isArray(e)?[...e]:{...e};function u(e){let t=e?.deleteMarker||c;function n(e){if(e==null)return e;if(Array.isArray(e))return e.filter(e=>e!==t).map(e=>typeof e==`object`&&e&&!Array.isArray(e)?n(e):e);if(typeof e==`object`){let r={};for(let[i,a]of Object.entries(e))if(a!==t)if(typeof a==`object`&&a){let e=n(a);e!==void 0&&(r[i]=e)}else r[i]=a;return r}return e===t?void 0:e}function r(e,r){if(typeof e!=`object`||!e)return typeof r==`object`&&r?n(r):r===t?{}:r;if(typeof r!=`object`||!r)return e;let i=l(e),a=[{target:i,source:r}];for(;a.length>0;){let{target:e,source:n}=a.pop();for(let r of Object.keys(n)){let i=n[r];if(i===t){delete e[r];continue}if(Array.isArray(i)){e[r]=i;continue}typeof i==`object`&&i?(e[r]=l(r in e&&typeof e[r]==`object`&&e[r]!==null?e[r]:{}),a.push({target:e[r],source:i})):e[r]=i}}return i}return r}const d=u(),f=[`map`,`filter`,`reduce`,`forEach`,`find`,`findIndex`,`some`,`every`,`includes`,`flatMap`,`flat`,`slice`,`splice`];var p=class{reactiveSelectors=new Map;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=>{let t=new Set;for(let n of e.deltas){let e=n.path;for(let[n,r]of this.dependencyMap)if(n===e||n.startsWith(e+`.`)||e.startsWith(n+`.`))for(let e of r)t.add(e)}for(let e of t){let t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}if(t!==e.lastResult){e.lastResult=t;for(let n of e.subscribers)n(t);this.eventBus.emit({name:`selector:changed`,payload:{selectorId:e.id,newResult:t,timestamp:Date.now()}})}}createReactiveSelector(e){let t=m(e),n=[...t].sort().join(`|`),r=this.pathBasedCache.get(n);if(r)return r.cleanupTimer!==void 0&&(clearTimeout(r.cleanupTimer),r.cleanupTimer=void 0),r.reactiveSelectorInstance;let i=`sel-${Math.random().toString(36).slice(2,9)}`,a={id:i,selector:e,lastResult:e(this.getState()),accessedPaths:t,subscribers:new Set,count:0,cleanupTimer:void 0,pathCacheKey:n,reactiveSelectorInstance:null};for(let e of t)this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(i);let o={id:i,get:()=>{try{return a.selector(this.getState())}catch{return}},subscribe:e=>(a.cleanupTimer!==void 0&&(clearTimeout(a.cleanupTimer),a.cleanupTimer=void 0),a.subscribers.add(e),a.count++,()=>{a.subscribers.delete(e),a.count--,a.count===0&&(a.cleanupTimer=setTimeout(()=>{a.count===0&&this.evictEntry(a)},0))})};return a.reactiveSelectorInstance=o,this.reactiveSelectors.set(i,a),this.pathBasedCache.set(n,a),this.eventBus.emit({name:`selector:accessed`,payload:{selectorId:i,accessedPaths:t,duration:0,timestamp:Date.now()}}),o}evictEntry(e){for(let t of e.accessedPaths){let n=this.dependencyMap.get(t);n&&(n.delete(e.id),n.size===0&&this.dependencyMap.delete(t))}this.reactiveSelectors.delete(e.id),this.pathBasedCache.delete(e.pathCacheKey)}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function m(e,t=`.`){let n=new Set,r=new Map,i=(e=``)=>{if(r.has(e))return r.get(e);let a=new Proxy(()=>{},{get:(r,a)=>{if(typeof a==`symbol`||a===`then`)return;if(a===`valueOf`||a===`toString`)throw Error(`Cannot perform logic, arithmetic, or string operations inside a selector.`);if(f.includes(a))throw Error(`Array method .${a}() is not allowed in selectors.`);let o=e?`${e}${t}${a}`:a;return e&&n.delete(e),n.add(o),i(o)},has:()=>{throw Error(`The 'in' operator is not allowed in selectors.`)},apply:()=>{throw Error(`Selectors cannot call functions or methods.`)}});return r.set(e,a),a};try{e(i())}catch(e){throw Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(n)}function h(e,t){if(e===t)return!0;if(e&&t&&typeof e==`object`&&typeof t==`object`){if(e.constructor!==t.constructor)return!1;let n,r;if(Array.isArray(e)){if(n=e.length,n!=t.length)return!1;for(r=n;r-->0;)if(!h(e[r],t[r]))return!1;return!0}let[i,a]=[Object.keys(e),Object.keys(t)];if(n=i.length,n!==a.length)return!1;for(r=n;r-->0;){let n=i[r];if(!Object.prototype.hasOwnProperty.call(t,n)||!h(e[n],t[n]))return!1}return!0}return e!==e&&t!==t}function g(e){let t=e?.deleteMarker||c;function n(e,n){let r=[],i=[{pathStr:``,orig:e||{},part:n||{}}];for(;i.length>0;){let{pathStr:e,orig:n,part:a}=i.pop();if(a!=null&&!h(n,a))if(typeof a==`object`&&!Array.isArray(a))for(let o of Object.keys(a)){let s=e?e+`.`+o:o,c=a[o],l=n&&typeof n==`object`?n[o]:void 0;if(c===t){l!==void 0&&r.push({path:s,oldValue:l,newValue:void 0});continue}typeof c==`object`&&c?i.push({pathStr:s,orig:l,part:c}):h(l,c)||r.push({path:s,oldValue:l,newValue:c})}else e&&r.push({path:e,oldValue:n,newValue:a})}return r}return n}function _(e){let t=e?.deleteMarker||c;function n(e){let n=new Set,r=[{obj:e,currentPath:``}];for(;r.length>0;){let{obj:e,currentPath:i}=r.pop();if(!(typeof e!=`object`||!e||Array.isArray(e)))for(let a of Object.keys(e)){let o=i?`${i}.${a}`:a;n.add(o);let s=e[a];typeof s==`object`&&s&&!Array.isArray(s)&&s!==t&&r.push({obj:s,currentPath:o})}}return Array.from(n)}return n}const v=g(),y=_();var b=class{updateBus;diff;cache;constructor(e,t,n){this.updateBus=t,this.diff=n,this.cache=structuredClone(e)}get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,n=!1,r=[]){if(t)return this.cache=n?structuredClone(e):e,this.notifyListeners([]),[];r.length===0&&(r=[e]);let i=this.get(!1),a=new Map;for(let e=0;e<r.length;e++){let t=r[e],n=this.diff(i,t);for(let e=0;e<n.length;e++){let t=n[e];a.set(t.path,t)}}let o=a.size?[...a.values()]:[];if(o.length>0){this.cache=n?structuredClone(e):e;let t=new Set;for(let e=0;e<o.length;e++){let n=o[e].path;for(;n&&!t.has(n);){t.add(n);let e=n.lastIndexOf(`.`);if(e<0)break;n=n.slice(0,e)}}this.notifyListeners(t)}return o}notifyListeners(e){for(let t of e)this.updateBus.emit({name:`update`,payload:t})}},x=class{eventBus;executionState;merge;logger;middleware=[];blockingMiddleware=[];constructor(e,t,n,r){this.eventBus=e,this.executionState=t,this.merge=n,this.logger=r}async executeBlocking(e,t){for(let{fn:n,name:r,id:i}of this.blockingMiddleware){let a={id:i,name:r,startTime:Date.now()};this.executionState.runningMiddleware={id:i,name:r,startTime:Date.now()},this.emitMiddlewareLifecycle(`start`,{id:i,name:r,type:`blocking`});try{let o=await Promise.resolve(n(e,t));if(a.endTime=Date.now(),a.duration=a.endTime-a.startTime,o===!1)return a.blocked=!0,this.emitMiddlewareLifecycle(`blocked`,{id:i,name:r,duration:a.duration}),this.emit(this.eventBus,{name:`middleware:executed`,payload:a}),{blocked:!0};this.emitMiddlewareLifecycle(`complete`,{id:i,name:r,type:`blocking`,duration:a.duration}),this.emit(this.eventBus,{name:`middleware:executed`,payload:{...a,blocked:!1}})}catch(e){return a.endTime=Date.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:Error(String(e)),a.blocked=!0,this.emitMiddlewareError(i,r,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 n=e,r=t;for(let{fn:e,name:i,id:a}of this.middleware){let o={id:a,name:i,startTime:Date.now()};this.executionState.runningMiddleware={id:a,name:i,startTime:Date.now()},this.emitMiddlewareLifecycle(`start`,{id:a,name:i,type:`transform`});try{let s=await Promise.resolve(e(n,t));o.endTime=Date.now(),o.duration=o.endTime-o.startTime,o.blocked=!1,s&&typeof s==`object`&&(n=this.merge(n,s),r=this.merge(r,s)),this.emit(this.eventBus,{name:`middleware:executed`,payload:o}),this.emitMiddlewareLifecycle(`complete`,{id:a,name:i,type:`transform`,duration:o.duration})}catch(e){o.endTime=Date.now(),o.duration=o.endTime-o.startTime,o.error=e instanceof Error?e:Error(String(e)),o.blocked=!1,this.emit(this.eventBus,{name:`middleware:executed`,payload:o}),this.emitMiddlewareError(a,i,o.error,o.duration),this.logger.error(`Middleware error`,{name:i,error:e})}finally{this.executionState.runningMiddleware=null}}return r}addMiddleware(e,t=`unnamed-middleware`){let n=this.generateId();return this.middleware.push({fn:e,name:t,id:n}),this.updateExecutionState(),n}addBlockingMiddleware(e,t=`unnamed-blocking-middleware`){let n=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:n}),this.updateExecutionState(),n}removeMiddleware(e){let 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,n,r){this.emit(this.eventBus,{name:`middleware:error`,payload:{id:e,name:t,error:n,duration:r,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)})}};let S;function C(e){return e||(S||=new s([]),S)}var w=class{eventBus;coreState;persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;logger;constructor(e,t,n,r){this.eventBus=e,this.coreState=t,this.instanceID=n,this.maxRetries=r?.maxRetries??3,this.retryDelay=r?.retryDelay??1e3,this.logger=r?.logger??C()}async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||e.length===0)return;let n={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(n),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:`persistence:queued`,payload:{taskId:n.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:n.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=>{let t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()}),await this.processQueue()}discardQueue(){let e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&=(clearTimeout(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=>{this.logger.error(`Queue processing failed`,{error:e})})},10))}async processQueue(){if(!(this.isProcessingQueue||this.backgroundQueue.length===0)){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){let 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,Error(`Persistence returned false`))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){let n=this.retryDelay*2**(e.retries-1);this.emit(this.eventBus,{name:`persistence:retry`,payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:n,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())},n)}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{let e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){this.logger.error(`Failed to initialize persistence`,{error: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=>{let 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)})}},T=class{eventBus;coreState;executionState;constructor(e,t,n){this.eventBus=e,this.coreState=t,this.executionState=n}async execute(e){let t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:`transaction:start`,payload:{timestamp:Date.now()}});try{let 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:Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask(()=>{e.emit(t)})}},E=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){let t=e.emit;e.emit=n=>(this.totalEventsFired++,t.call(e,n)),e.subscribe(`update:complete`,e=>{if(this.totalUpdates++,e.blocked){this.blockedUpdates++;return}if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();let 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=>{let 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()}},D=class extends Error{constructor(){super(`Action Cancelled by Debounce`),this.name=`ActionCancelledError`}},O=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name=`UnknownActionError`}};const k=()=>{},A={name:`UNDEFINED ACTION`,status:()=>!1,subscribe:e=>()=>{}};var j=class{eventBus;set;registrations=new Map;constructor(e,t){this.eventBus=e,this.set=t}register(e){let n={action:{name:e.name,id:o(),action:e.fn,debounce:e.debounce?{...e.debounce,condition:e.debounce.condition??(()=>!0)}:void 0},debouncer:e.debounce&&e.debounce.delay>0?new t({delay:e.debounce.delay}):void 0,previousArgs:void 0,running:!1,subscription:{listeners:new Set,watcher:null,watchers:new a(()=>[this.eventBus.subscribe(`action:start`,t=>t.name===e.name&&this.notifyStatusListeners(e.name)),this.eventBus.subscribe(`action:complete`,t=>t.name===e.name&&this.notifyStatusListeners(e.name)),this.eventBus.subscribe(`action:error`,t=>t.name===e.name&&this.notifyStatusListeners(e.name))],e=>e?.forEach(e=>e()),{gracePeriod:`microtask`})}};return this.registrations.set(e.name,n),()=>{let t=this.registrations.get(e.name);t&&(t.debouncer?.cancel(),this.registrations.delete(e.name))}}async dispatch(e,...t){let n=this.registrations.get(e);if(!n)throw new O({action:e});let{action:r,debouncer:i}=n,{debounce:a}=r;if(!i||!a)return this.executeAction(n,t);let o=a.condition(n.previousArgs,t);if(n.previousArgs=t,!o)return this.executeAction(n,t);let s=await i.do(()=>this.executeAction(n,t));if(s.status===`cancelled`)throw new D;if(s.status===`error`&&s.error)throw s.error;return s.value}async executeAction(e,t){let n=Date.now();e.running=!0,this.emit(this.eventBus,{name:`action:start`,payload:{actionId:e.action.id,name:e.action.name,params:t||[],timestamp:n}});try{let r=await this.set(n=>e.action.action(n,...t),{actionId:e.action.id}),i=Date.now();return e.running=!1,this.emit(this.eventBus,{name:`action:complete`,payload:{actionId:e.action.id,name:e.action.name,params:t,startTime:n,endTime:i,duration:i-n,result:r}}),r}catch(r){let i=Date.now();throw e.running=!1,this.emit(this.eventBus,{name:`action:error`,payload:{actionId:e.action.id,name:e.action.name,params:t,startTime:n,endTime:i,duration:i-n,error:r}}),r}}running(e){let t=this.registrations.get(e);return t?t.running:!1}subscribe(e,t){let n=this.registrations.get(e);return n?(n.subscription.listeners.add(t),n.subscription.watchers.acquire(),()=>{n.subscription.listeners.delete(t),n.subscription.watchers?.release()}):k}watch(e){let t=this.registrations.get(e);return t?(t.subscription.watcher||(t.subscription.watcher={name:e,status:()=>this.running(e),subscribe:t=>this.subscribe(e,t)}),t.subscription.watcher):A}notifyStatusListeners(e){let t=this.registrations.get(e).subscription.listeners;t&&t.forEach(e=>e())}emit(e,t){queueMicrotask(()=>{e.emit(t)})}dispose(){for(let e of this.registrations.values())e.debouncer?.cancel(),e.subscription.watchers.forceCleanup,e.subscription.listeners.clear();this.registrations.clear()}},M=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new i({yieldMode:`macrotask`,capacity:1e3});readyLatch=new n;disposeOnce=new r;updateBus;eventBus;executionState;instanceID=o();merge;diff;logger;constructor(t,n,r=c,i){this.logger=C(i?.logger),this.eventBus=e(i?.broadcastChannel?{batch:{size:0,delay:0},broadcast:{channel:i.broadcastChannel}}:void 0),this.updateBus=e(i?.broadcastChannel?{batch:{size:0,delay:0},broadcast:{channel:i.broadcastChannel}}:void 0),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=u({deleteMarker:r}),this.diff=g({deleteMarker:r}),this.coreState=new b(t,this.updateBus,this.diff),this.middlewareEngine=new x(this.eventBus,this.executionState,this.merge,this.logger),this.persistenceHandler=new w(this.eventBus,this.coreState,this.instanceID,{maxRetries:i?.persistenceMaxRetries,retryDelay:i?.persistenceRetryDelay,logger:this.logger}),this.transactionManager=new T(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new E(this.eventBus),this.actions=new j(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(n),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new p(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)}subset(e,t=`.`){let n={},r=this.get();for(let i of e)n[i]=i.split(t).reduce((e,t)=>e&&e[t]!==void 0?e[t]:void 0,r);return n}select(e){return this.checkDisposed(),this.selectorManager.createReactiveSelector(e)}register(e){return this.checkDisposed(),this.actions.register(e)}async dispatch(e,...t){return this.checkDisposed(),this.actions.dispatch(e,...t)}async set(e,t={}){this.checkDisposed();let n=await this.updateSerializer.do(()=>this._performUpdate(e,t));if(n.error)throw n.error;return n.value}async _performUpdate(e,t){let n=Date.now();this.emit(this.eventBus,{name:`update:start`,payload:{timestamp:n,actionId:t.actionId}});try{if(t.force){let r=this.get(!1),i=typeof e==`function`?e(r):e;this.coreState.applyChanges(i,!0);let a=Date.now();return this.emit(this.eventBus,{name:`update:complete`,payload:{deltas:[],duration:a-n,timestamp:Date.now(),actionId:t.actionId,newState:i}}),i}let r,i=this.get(!1);if(typeof e==`function`){let t=e(i);r=t instanceof Promise?await t:t}else r=e;let a=await this.middlewareEngine.executeBlocking(i,r);if(a.blocked)throw a.error||Error(`Update blocked by middleware`);let o=this.merge(i,r),s=await this.middlewareEngine.executeTransform(o,r),c=this.merge(o,s),l=this.coreState.applyChanges(c,!1,!1,[r,s]),u=Date.now(),d=this.get(!1);return this.emit(this.eventBus,{name:`update:complete`,payload:{deltas:l,duration:u-n,timestamp:Date.now(),actionId:t.actionId,newState:d}}),d}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(){if(this.persistenceHandler.isReady())this.readyLatch.open();else{let e=this.eventBus.subscribe(`persistence:ready`,()=>{this.readyLatch.isOpen()||this.readyLatch.open(),e()})}}setupPersistenceListener(){this.updateBus.subscribe(`update`,e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))})}watch(e,t,n){let r=Array.isArray(e)?e:[e],i=e===``||r.length===0;return this.updateBus.subscribe(`update`,e=>{(i||r.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)},n)}watchAction(e){return this.checkDisposed(),this.actions.watch(e)}debouncedSetter(e){let n=new t({delay:e.delay,leading:e.leading});return(e,t={})=>{n.fire(()=>this.set(e,t))}}id(){return this.instanceID}async transaction(e,t){this.checkDisposed();let n=await this.transactionManager.execute(e);return t?.flush&&await this.flush(),n}use(e){this.checkDisposed();let 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.checkDisposed(),this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flush(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){return this.disposeOnce.do(async()=>{await this.flush(),this.updateSerializer.close(),this.eventBus?.clear({permanent:!0}),this.updateBus?.clear({permanent:!0}),this.actions.dispose(),this.persistenceHandler.dispose(),this.metricsCollector.dispose(),this.selectorManager.dispose(),this.coreState=null,this.middlewareEngine=null,this.transactionManager=null,this.actions=null})}checkDisposed(){if(this.disposed())throw Error(`StoreExecutionDone: Cannot perform operations on a disposed store.`)}disposed(){return this.disposeOnce.done()}emit(e,t){queueMicrotask(()=>{e.emit(t)})}},N=class{stores=new Map;storeToOnce=new WeakMap;finalizer;onEvict;logger;constructor(e){this.onEvict=e?.onEvict,this.logger=C(e?.logger),this.finalizer=new FinalizationRegistry(({storeId:e,ref:t})=>{try{this.stores.get(e)===t&&(this.stores.delete(e),this.onEvict?.(e))}catch(t){this.logger.error(`StoreRegistry Finalizer error`,{storeId:e,error:t})}})}async get(e,t={}){let n=this.stores.get(e)?.deref();if(!n){n=new r({throws:!1});let t=new WeakRef(n);this.stores.set(e,t),this.finalizer.register(n,{storeId:e,ref:t},n)}let i=await n.do(async()=>{let e=new M(t.state||{},t.persistence,t.deleteMarker,t.options);return await e.ready(),e},t.timeout);if(i.error)throw this.stores.get(e)?.deref()===n&&(this.stores.delete(e),this.finalizer.unregister(n)),i.error;let a=i.value;return this.storeToOnce.set(a,n),a}getSync(e,t={}){let n=this.stores.get(e)?.deref();if(!n){n=new r({throws:!1});let t=new WeakRef(n);this.stores.set(e,t),this.finalizer.register(n,{storeId:e,ref:t},n)}let i=n.doSync(()=>new M(t.state||{},t.persistence,t.deleteMarker,t.options));if(i.error)throw this.stores.get(e)?.deref()===n&&(this.stores.delete(e),this.finalizer.unregister(n)),i.error;let a=i.value;return this.storeToOnce.set(a,n),a}async release(e){let t=this.stores.get(e);if(t){let n=t.deref();if(n&&(this.finalizer.unregister(n),n.done())){let t=n.get();if(t){try{await t.dispose()}catch(t){this.logger.error(`StoreRegistry Error disposing store during release`,{storeId:e,error:t})}this.storeToOnce.delete(t)}}return this.stores.delete(e)}return!1}async clear(){for(let e of this.stores.values()){let t=e.deref();if(t&&(this.finalizer.unregister(t),t.done())){let e=t.get();if(e){try{await e.dispose()}catch{}this.storeToOnce.delete(e)}}}this.stores.clear()}has(e){return this.stores.has(e)}get size(){return this.stores.size}},P=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;logger;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.logger=C(t.logger),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){if(this.isSilent)return;if(e===`group`||e===`groupEnd`||e===`table`){typeof console[e]==`function`&&console[e](...t);return}let n=typeof t[0]==`string`?t[0]:String(t[0]??``),r=t.length>1?{detail:t.slice(1)}:void 0;switch(e){case`log`:this.logger.log(n,r);break;case`warn`:this.logger.warn(n,r);break;case`error`:this.logger.error(n,r);break;case`debug`:this.logger.debug(n,r);break}}setupEventListeners(){for(let e of[`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`]){let t=e.startsWith(`update`)&&this.logEvents.updates||e.startsWith(`middleware`)&&this.logEvents.middleware||e.startsWith(`transaction`)&&this.logEvents.transactions||e.startsWith(`action`)&&this.logEvents.actions||e.startsWith(`selector`)&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(e,n=>{this.isTimeTraveling||(e===`update:complete`&&!n.blocked&&this.recordStateSnapshot(n.deltas),e===`middleware:executed`?this.middlewareExecutions.push(n):e===`transaction:start`?this.activeTransactionCount++:(e===`transaction:complete`||e===`transaction:error`)&&(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),n.batchId&&(e.endsWith(`start`)?this.activeBatches.add(n.batchId):(e.endsWith(`complete`)||e.endsWith(`error`))&&this.activeBatches.delete(n.batchId)),this.recordEvent(e,n),this.enableConsoleLogging&&t&&this._log(e,n),this._checkPerformance(e,n))}))}}recordStateSnapshot(e){let 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){let n={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(n),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={}){let{logLevel:t=`debug`,logUpdates:n=!0}=e;return(e,r)=>(n&&this.logger[t](`State Update`,{update:r}),r)}createValidationMiddleware(e){return(t,n)=>{let r=e(t,n);return typeof r==`boolean`?r:(!r.valid&&r.reason&&this._consoleLog(`warn`,`Validation failed:`,r.reason),r.valid)}}getRecentChanges(e=5){let t=[],n=Math.min(e,this.stateHistory.length);for(let e=0;e<n;e++){let n=this.stateHistory[e];if(!n.deltas||n.deltas.length===0)continue;let r={},i={},a=(e,t,n)=>{t.reduce((e,r,i)=>(i===t.length-1?e[r]=n:e[r]=e[r]??{},e[r]),e)};for(let e of n.deltas){let t=e.path.split(`.`);a(r,t,e.oldValue),a(i,t,e.newValue)}t.push({timestamp:n.timestamp,changedPaths:n.deltas.map(e=>e.path),from:r,to:i})}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){let t=this.eventHistory.filter(e=>e.type===`update:start`)[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=[],n=this.store.on(`update:complete`,n=>{!this.isTimeTraveling&&!n.blocked&&(t=[],e=0)});this.unsubscribers.push(n);let r=()=>this.stateHistory.length,i=()=>e<r()-1,a=()=>t.length>0;return{canUndo:i,canRedo:a,undo:async()=>{if(!i())return;t.unshift(this.stateHistory[e]),e++;let n=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...n},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;let n=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...n.state},{force:!0}),this.isTimeTraveling=!1},length:r,clear:()=>{t=[],e=0}}}async saveSession(e){let t=this.store.id(),n={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,n))}async loadSession(e){let 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):!1}exportSession(){let e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`store-observer-session-${new Date().toISOString()}.json`,r.click(),URL.revokeObjectURL(n)}importSession(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=async e=>{try{let n=JSON.parse(e.target?.result);this.eventHistory=n.eventHistory||[],this.stateHistory=n.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){n(e)}},r.onerror=e=>n(e),r.readAsText(e)})}disconnect(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){let n=new Date(t.timestamp||Date.now()).toISOString().split(`T`)[1].replace(`Z`,``);if(e===`update:start`)this._consoleLog(`group`,`%c⚡ Store Update Started [${n}]`,`color: #4a6da7`);else if(e===`update:complete`){if(t.blocked)this._consoleLog(`warn`,`%c✋ Update Blocked [${n}]`,`color: #bf8c0a`,t.error);else{let e=t.deltas||[];e.length>0&&(this._consoleLog(`log`,`%c✅ Update Complete [${n}] - ${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 e===`middleware:start`?this._consoleLog(`debug`,`%c◀ Middleware \"${t.name}\" started [${n}] (${t.type})`,`color: #8c8c8c`):e===`middleware:complete`?this._consoleLog(`debug`,`%c▶ Middleware \"${t.name}\" completed [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #7c9c7c`):e===`middleware:error`?this._consoleLog(`error`,`%c❌ Middleware \"${t.name}\" error [${n}]:`,`color: #e63946`,t.error):e===`middleware:blocked`?this._consoleLog(`warn`,`%c🛑 Middleware \"${t.name}\" blocked update [${n}]`,`color: #e76f51`):e===`transaction:start`?this._consoleLog(`group`,`%c📦 Transaction Started [${n}]`,`color: #6d597a`):e===`transaction:complete`?(this._consoleLog(`log`,`%c📦 Transaction Complete [${n}]`,`color: #355070`),this._consoleLog(`groupEnd`)):e===`transaction:error`?(this._consoleLog(`error`,`%c📦 Transaction Error [${n}]:`,`color: #e56b6f`,t.error),this._consoleLog(`groupEnd`)):e===`action:start`?this._consoleLog(`group`,`%c🚀 Action \"${t.name}\" Started [${n}]`,`color: #9b59b6`,{params:t.params}):e===`action:complete`?(this._consoleLog(`log`,`%c✔️ Action \"${t.name}\" Complete [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #2ecc71`),this._consoleLog(`groupEnd`)):e===`action:error`?(this._consoleLog(`error`,`%c🔥 Action \"${t.name}\" Error [${n}]:`,`color: #e74c3c`,t.error),this._consoleLog(`groupEnd`)):e===`selector:accessed`&&this._consoleLog(`debug`,`%c👀 Selector Accessed [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #f1c40f`,{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&(e===`update:complete`&&!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}),e===`middleware:complete`&&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{D as ActionCancelledError,j as ActionManager,c as DELETE_SYMBOL,M as ReactiveDataStore,P as StoreObserver,N as StoreRegistry,O as UnknownActionError,_ as createDerivePaths,g as createDiff,u as createMerge,C as createStoreLogger,y as derivePaths,v as diff,d as merge,l as shallowClone};
1
+ import{createEventBus as e}from"@asaidimu/utils-events";import{Debouncer as t,Latch as n,Once as r,Serializer as i,SharedResource as a}from"@asaidimu/utils-sync";import{v4 as o}from"uuid";import{Logger as s}from"@asaidimu/utils-logger";const c=Symbol.for(`delete`),l=e=>Array.isArray(e)?[...e]:{...e};function u(e){let t=e?.deleteMarker||c;function n(e){if(e==null)return e;if(Array.isArray(e))return e.filter(e=>e!==t).map(e=>typeof e==`object`&&e&&!Array.isArray(e)?n(e):e);if(typeof e==`object`){let r={};for(let[i,a]of Object.entries(e))if(a!==t)if(typeof a==`object`&&a){let e=n(a);e!==void 0&&(r[i]=e)}else r[i]=a;return r}return e===t?void 0:e}function r(e,r){if(typeof e!=`object`||!e)return typeof r==`object`&&r?n(r):r===t?{}:r;if(typeof r!=`object`||!r)return e;let i=l(e),a=[{target:i,source:r}];for(;a.length>0;){let{target:e,source:n}=a.pop();for(let r of Object.keys(n)){let i=n[r];if(i===t){delete e[r];continue}if(Array.isArray(i)){e[r]=i;continue}typeof i==`object`&&i?(e[r]=l(r in e&&typeof e[r]==`object`&&e[r]!==null?e[r]:{}),a.push({target:e[r],source:i})):e[r]=i}}return i}return r}const d=u(),f=[`map`,`filter`,`reduce`,`forEach`,`find`,`findIndex`,`some`,`every`,`includes`,`flatMap`,`flat`,`slice`,`splice`];var p=class{reactiveSelectors=new Map;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=>{let t=new Set;for(let n of e.deltas){let e=n.path;for(let[n,r]of this.dependencyMap)if(n===e||n.startsWith(e+`.`)||e.startsWith(n+`.`))for(let e of r)t.add(e)}for(let e of t){let t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}if(t!==e.lastResult){e.lastResult=t;for(let n of e.subscribers)n(t);this.eventBus.emit({name:`selector:changed`,payload:{selectorId:e.id,newResult:t,timestamp:Date.now()}})}}createReactiveSelector(e){let t=m(e),n=[...t].sort().join(`|`),r=this.pathBasedCache.get(n);if(r)return r.cleanupTimer!==void 0&&(clearTimeout(r.cleanupTimer),r.cleanupTimer=void 0),r.reactiveSelectorInstance;let i=`sel-${Math.random().toString(36).slice(2,9)}`,a={id:i,selector:e,lastResult:e(this.getState()),accessedPaths:t,subscribers:new Set,count:0,cleanupTimer:void 0,pathCacheKey:n,reactiveSelectorInstance:null};for(let e of t)this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(i);let o={id:i,get:()=>{try{return a.selector(this.getState())}catch{return}},subscribe:e=>(a.cleanupTimer!==void 0&&(clearTimeout(a.cleanupTimer),a.cleanupTimer=void 0),a.subscribers.add(e),a.count++,()=>{a.subscribers.delete(e),a.count--,a.count===0&&(a.cleanupTimer=setTimeout(()=>{a.count===0&&this.evictEntry(a)},0))})};return a.reactiveSelectorInstance=o,this.reactiveSelectors.set(i,a),this.pathBasedCache.set(n,a),this.eventBus.emit({name:`selector:accessed`,payload:{selectorId:i,accessedPaths:t,duration:0,timestamp:Date.now()}}),o}evictEntry(e){for(let t of e.accessedPaths){let n=this.dependencyMap.get(t);n&&(n.delete(e.id),n.size===0&&this.dependencyMap.delete(t))}this.reactiveSelectors.delete(e.id),this.pathBasedCache.delete(e.pathCacheKey)}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function m(e,t=`.`){let n=new Set,r=new Map,i=(e=``)=>{if(r.has(e))return r.get(e);let a=new Proxy(()=>{},{get:(r,a)=>{if(typeof a==`symbol`||a===`then`)return;if(a===`valueOf`||a===`toString`)throw Error(`Cannot perform logic, arithmetic, or string operations inside a selector.`);if(f.includes(a))throw Error(`Array method .${a}() is not allowed in selectors.`);let o=e?`${e}${t}${a}`:a;return e&&n.delete(e),n.add(o),i(o)},has:()=>{throw Error(`The 'in' operator is not allowed in selectors.`)},apply:()=>{throw Error(`Selectors cannot call functions or methods.`)}});return r.set(e,a),a};try{e(i())}catch(e){throw Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(n)}function h(e,t){if(e===t)return!0;if(e&&t&&typeof e==`object`&&typeof t==`object`){if(e.constructor!==t.constructor)return!1;let n,r;if(Array.isArray(e)){if(n=e.length,n!=t.length)return!1;for(r=n;r-->0;)if(!h(e[r],t[r]))return!1;return!0}let[i,a]=[Object.keys(e),Object.keys(t)];if(n=i.length,n!==a.length)return!1;for(r=n;r-->0;){let n=i[r];if(!Object.prototype.hasOwnProperty.call(t,n)||!h(e[n],t[n]))return!1}return!0}return e!==e&&t!==t}function g(e){let t=e?.deleteMarker||c;function n(e,n){let r=[],i=[{pathStr:``,orig:e||{},part:n||{}}];for(;i.length>0;){let{pathStr:e,orig:n,part:a}=i.pop();if(a!=null&&!h(n,a))if(typeof a==`object`&&!Array.isArray(a))for(let o of Object.keys(a)){let s=e?e+`.`+o:o,c=a[o],l=n&&typeof n==`object`?n[o]:void 0;if(c===t){l!==void 0&&r.push({path:s,oldValue:l,newValue:void 0});continue}typeof c==`object`&&c?i.push({pathStr:s,orig:l,part:c}):h(l,c)||r.push({path:s,oldValue:l,newValue:c})}else e&&r.push({path:e,oldValue:n,newValue:a})}return r}return n}function _(e){let t=e?.deleteMarker||c;function n(e){let n=new Set,r=[{obj:e,currentPath:``}];for(;r.length>0;){let{obj:e,currentPath:i}=r.pop();if(!(typeof e!=`object`||!e||Array.isArray(e)))for(let a of Object.keys(e)){let o=i?`${i}.${a}`:a;n.add(o);let s=e[a];typeof s==`object`&&s&&!Array.isArray(s)&&s!==t&&r.push({obj:s,currentPath:o})}}return Array.from(n)}return n}const v=g(),y=_();var b=class{updateBus;diff;cache;constructor(e,t,n){this.updateBus=t,this.diff=n,this.cache=structuredClone(e)}get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,n=!1,r=[]){if(t)return this.cache=n?structuredClone(e):e,this.notifyListeners([]),[];r.length===0&&(r=[e]);let i=this.get(!1),a=new Map;for(let e=0;e<r.length;e++){let t=r[e],n=this.diff(i,t);for(let e=0;e<n.length;e++){let t=n[e];a.set(t.path,t)}}let o=a.size?[...a.values()]:[];if(o.length>0){this.cache=n?structuredClone(e):e;let t=new Set;for(let e=0;e<o.length;e++){let n=o[e].path;for(;n&&!t.has(n);){t.add(n);let e=n.lastIndexOf(`.`);if(e<0)break;n=n.slice(0,e)}}this.notifyListeners(t)}return o}notifyListeners(e){for(let t of e)this.updateBus.emit({name:`update`,payload:t})}},x=class{eventBus;executionState;merge;logger;middleware=[];blockingMiddleware=[];constructor(e,t,n,r){this.eventBus=e,this.executionState=t,this.merge=n,this.logger=r}async executeBlocking(e,t){for(let{fn:n,name:r,id:i}of this.blockingMiddleware){let a={id:i,name:r,startTime:Date.now()};this.executionState.runningMiddleware={id:i,name:r,startTime:Date.now()},this.emitMiddlewareLifecycle(`start`,{id:i,name:r,type:`blocking`});try{let o=await Promise.resolve(n(e,t));if(a.endTime=Date.now(),a.duration=a.endTime-a.startTime,o===!1)return a.blocked=!0,this.emitMiddlewareLifecycle(`blocked`,{id:i,name:r,duration:a.duration}),this.emit(this.eventBus,{name:`middleware:executed`,payload:a}),{blocked:!0};this.emitMiddlewareLifecycle(`complete`,{id:i,name:r,type:`blocking`,duration:a.duration}),this.emit(this.eventBus,{name:`middleware:executed`,payload:{...a,blocked:!1}})}catch(e){return a.endTime=Date.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:Error(String(e)),a.blocked=!0,this.emitMiddlewareError(i,r,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 n=e,r=t;for(let{fn:e,name:i,id:a}of this.middleware){let o={id:a,name:i,startTime:Date.now()};this.executionState.runningMiddleware={id:a,name:i,startTime:Date.now()},this.emitMiddlewareLifecycle(`start`,{id:a,name:i,type:`transform`});try{let s=await Promise.resolve(e(n,t));o.endTime=Date.now(),o.duration=o.endTime-o.startTime,o.blocked=!1,s&&typeof s==`object`&&(n=this.merge(n,s),r=this.merge(r,s)),this.emit(this.eventBus,{name:`middleware:executed`,payload:o}),this.emitMiddlewareLifecycle(`complete`,{id:a,name:i,type:`transform`,duration:o.duration})}catch(e){o.endTime=Date.now(),o.duration=o.endTime-o.startTime,o.error=e instanceof Error?e:Error(String(e)),o.blocked=!1,this.emit(this.eventBus,{name:`middleware:executed`,payload:o}),this.emitMiddlewareError(a,i,o.error,o.duration),this.logger.error(`Middleware error`,{name:i,error:e})}finally{this.executionState.runningMiddleware=null}}return r}addMiddleware(e,t=`unnamed-middleware`){let n=this.generateId();return this.middleware.push({fn:e,name:t,id:n}),this.updateExecutionState(),n}addBlockingMiddleware(e,t=`unnamed-blocking-middleware`){let n=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:n}),this.updateExecutionState(),n}removeMiddleware(e){let 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,n,r){this.emit(this.eventBus,{name:`middleware:error`,payload:{id:e,name:t,error:n,duration:r,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)})}};let S;function C(e){return e||(S||=new s([]),S)}var w=class{eventBus;coreState;persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;logger;constructor(e,t,n,r){this.eventBus=e,this.coreState=t,this.instanceID=n,this.maxRetries=r?.maxRetries??3,this.retryDelay=r?.retryDelay??1e3,this.logger=r?.logger??C()}async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||e.length===0)return;let n={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(n),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:`persistence:queued`,payload:{taskId:n.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:n.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=>{let t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()}),await this.processQueue()}discardQueue(){let e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&=(clearTimeout(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=>{this.logger.error(`Queue processing failed`,{error:e})})},10))}async processQueue(){if(!(this.isProcessingQueue||this.backgroundQueue.length===0)){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){let 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,Error(`Persistence returned false`))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){let n=this.retryDelay*2**(e.retries-1);this.emit(this.eventBus,{name:`persistence:retry`,payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:n,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())},n)}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{let e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){this.logger.error(`Failed to initialize persistence`,{error: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=>{let 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)})}},T=class{eventBus;coreState;executionState;constructor(e,t,n){this.eventBus=e,this.coreState=t,this.executionState=n}async execute(e){let t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:`transaction:start`,payload:{timestamp:Date.now()}});try{let 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:Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask(()=>{e.emit(t)})}},E=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){let t=e.emit;e.emit=n=>(this.totalEventsFired++,t.call(e,n)),e.subscribe(`update:complete`,e=>{if(this.totalUpdates++,e.blocked){this.blockedUpdates++;return}if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();let 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=>{let 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()}},D=class extends Error{constructor(){super(`Action Cancelled by Debounce`),this.name=`ActionCancelledError`}},O=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name=`UnknownActionError`}};const k=()=>{},A={name:`UNDEFINED ACTION`,status:()=>!1,subscribe:e=>()=>{}};var j=class{eventBus;set;registrations=new Map;constructor(e,t){this.eventBus=e,this.set=t}register(e){let n={action:{name:e.name,id:o(),action:e.fn,debounce:e.debounce?{...e.debounce,condition:e.debounce.condition??(()=>!0)}:void 0},debouncer:e.debounce&&e.debounce.delay>0?new t({delay:e.debounce.delay}):void 0,previousArgs:void 0,running:!1,subscription:{listeners:new Set,watcher:null,watchers:new a(()=>[this.eventBus.subscribe(`action:start`,t=>t.name===e.name&&this.notifyStatusListeners(e.name)),this.eventBus.subscribe(`action:complete`,t=>t.name===e.name&&this.notifyStatusListeners(e.name)),this.eventBus.subscribe(`action:error`,t=>t.name===e.name&&this.notifyStatusListeners(e.name))],e=>e?.forEach(e=>e()),{gracePeriod:`microtask`})}};return this.registrations.set(e.name,n),()=>{let t=this.registrations.get(e.name);t&&(t.debouncer?.cancel(),this.registrations.delete(e.name))}}async dispatch(e,...t){let n=this.registrations.get(e);if(!n)throw new O({action:e});let{action:r,debouncer:i}=n,{debounce:a}=r;if(!i||!a)return this.executeAction(n,t);let o=a.condition(n.previousArgs,t);if(n.previousArgs=t,!o)return this.executeAction(n,t);let s=await i.do(()=>this.executeAction(n,t));if(s.status===`cancelled`)throw new D;if(s.status===`error`&&s.error)throw s.error;return s.value}async executeAction(e,t){let n=Date.now();e.running=!0,this.emit(this.eventBus,{name:`action:start`,payload:{actionId:e.action.id,name:e.action.name,params:t||[],timestamp:n}});try{let r=await this.set(n=>e.action.action(n,...t),{actionId:e.action.id}),i=Date.now();return e.running=!1,this.emit(this.eventBus,{name:`action:complete`,payload:{actionId:e.action.id,name:e.action.name,params:t,startTime:n,endTime:i,duration:i-n,result:r}}),r}catch(r){let i=Date.now();throw e.running=!1,this.emit(this.eventBus,{name:`action:error`,payload:{actionId:e.action.id,name:e.action.name,params:t,startTime:n,endTime:i,duration:i-n,error:r}}),r}}running(e){let t=this.registrations.get(e);return t?t.running:!1}subscribe(e,t){let n=this.registrations.get(e);return n?(n.subscription.listeners.add(t),n.subscription.watchers.acquire(),()=>{n.subscription.listeners.delete(t),n.subscription.watchers?.release()}):k}watch(e){let t=this.registrations.get(e);return t?(t.subscription.watcher||(t.subscription.watcher={name:e,status:()=>this.running(e),subscribe:t=>this.subscribe(e,t)}),t.subscription.watcher):A}notifyStatusListeners(e){let t=this.registrations.get(e).subscription.listeners;t&&t.forEach(e=>e())}emit(e,t){queueMicrotask(()=>{e.emit(t)})}dispose(){for(let e of this.registrations.values())e.debouncer?.cancel(),e.subscription.watchers.forceCleanup,e.subscription.listeners.clear();this.registrations.clear()}},M=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new i({yieldMode:`macrotask`,capacity:1e3});readyLatch=new n;disposeOnce=new r;updateBus;eventBus;executionState;instanceID=o();merge;diff;logger;constructor(t,n,r=c,i){this.logger=C(i?.logger),this.eventBus=e(i?.broadcastChannel?{batch:{size:0,delay:0},broadcast:{channel:i.broadcastChannel}}:void 0),this.updateBus=e(i?.broadcastChannel?{batch:{size:0,delay:0},broadcast:{channel:i.broadcastChannel}}:void 0),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=u({deleteMarker:r}),this.diff=g({deleteMarker:r}),this.coreState=new b(t,this.updateBus,this.diff),this.middlewareEngine=new x(this.eventBus,this.executionState,this.merge,this.logger),this.persistenceHandler=new w(this.eventBus,this.coreState,this.instanceID,{maxRetries:i?.persistenceMaxRetries,retryDelay:i?.persistenceRetryDelay,logger:this.logger}),this.transactionManager=new T(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new E(this.eventBus),this.actions=new j(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(n),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new p(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)}subset(e,t=`.`){let n={},r=this.get();for(let i of e)n[i]=i.split(t).reduce((e,t)=>e&&e[t]!==void 0?e[t]:void 0,r);return n}select(e){return this.checkDisposed(),this.selectorManager.createReactiveSelector(e)}register(e){return this.checkDisposed(),this.actions.register(e)}async dispatch(e,...t){return this.checkDisposed(),this.actions.dispatch(e,...t)}async set(e,t={}){this.checkDisposed();let n=await this.updateSerializer.do(()=>this._performUpdate(e,t));if(n.error)throw n.error;return n.value}async _performUpdate(e,t){let n=Date.now();this.emit(this.eventBus,{name:`update:start`,payload:{timestamp:n,actionId:t.actionId}});try{if(t.force){let r=this.get(!1),i=typeof e==`function`?e(r):e;this.coreState.applyChanges(i,!0);let a=Date.now();return this.emit(this.eventBus,{name:`update:complete`,payload:{deltas:[],duration:a-n,timestamp:Date.now(),actionId:t.actionId,newState:i}}),i}let r,i=this.get(!1);if(typeof e==`function`){let t=e(i);r=t instanceof Promise?await t:t}else r=e;let a=await this.middlewareEngine.executeBlocking(i,r);if(a.blocked)throw a.error||Error(`Update blocked by middleware`);let o=this.merge(i,r),s=await this.middlewareEngine.executeTransform(o,r),c=this.merge(o,s),l=this.coreState.applyChanges(c,!1,!1,[r,s]),u=Date.now(),d=this.get(!1);return this.emit(this.eventBus,{name:`update:complete`,payload:{deltas:l,duration:u-n,timestamp:Date.now(),actionId:t.actionId,newState:d}}),d}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(){if(this.persistenceHandler.isReady())this.readyLatch.open();else{let e=this.eventBus.subscribe(`persistence:ready`,()=>{this.readyLatch.isOpen()||this.readyLatch.open(),e()})}}setupPersistenceListener(){this.updateBus.subscribe(`update`,e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))})}watch(e,t,n){let r=Array.isArray(e)?e:[e],i=e===``||r.length===0;return this.updateBus.subscribe(`update`,e=>{(i||r.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)},n)}watchAction(e){return this.checkDisposed(),this.actions.watch(e)}debouncedSetter(e){let n=new t({delay:e.delay,leading:e.leading});return(e,t={})=>{n.fire(()=>this.set(e,t))}}id(){return this.instanceID}async transaction(e,t){this.checkDisposed();let n=await this.transactionManager.execute(e);return t?.flush&&await this.flush(),n}use(e){this.checkDisposed();let 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.checkDisposed(),this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flush(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){return this.disposeOnce.do(async()=>{await this.flush(),this.updateSerializer.close(),this.eventBus?.clear({permanent:!0}),this.updateBus?.clear({permanent:!0}),this.actions.dispose(),this.persistenceHandler.dispose(),this.metricsCollector.dispose(),this.selectorManager.dispose(),this.coreState=null,this.middlewareEngine=null,this.transactionManager=null,this.actions=null})}checkDisposed(){if(this.disposed())throw Error(`StoreExecutionDone: Cannot perform operations on a disposed store.`)}disposed(){return this.disposeOnce.done()}emit(e,t){queueMicrotask(()=>{e.emit(t)})}},N=class{stores=new Map;storeToOnce=new WeakMap;finalizer;onEvict;logger;constructor(e){this.onEvict=e?.onEvict,this.logger=C(e?.logger),this.finalizer=new FinalizationRegistry(({storeId:e,ref:t})=>{try{this.stores.get(e)===t&&(this.stores.delete(e),this.onEvict?.(e))}catch(t){this.logger.error(`StoreRegistry Finalizer error`,{storeId:e,error:t})}})}async get(e,t={}){let n=this.stores.get(e)?.deref();if(!n){n=new r({throws:!1});let t=new WeakRef(n);this.stores.set(e,t),this.finalizer.register(n,{storeId:e,ref:t},n)}let i=await n.do(async()=>{let e=new M(t.state||{},t.persistence,t.deleteMarker,t.options);return await e.ready(),e},t.timeout);if(i.error)throw this.stores.get(e)?.deref()===n&&(this.stores.delete(e),this.finalizer.unregister(n)),i.error;let a=i.value;return this.storeToOnce.set(a,n),a}getSync(e,t={}){let n=this.stores.get(e)?.deref();if(!n){n=new r({throws:!1});let t=new WeakRef(n);this.stores.set(e,t),this.finalizer.register(n,{storeId:e,ref:t},n)}let i=n.doSync(()=>new M(t.state||{},t.persistence,t.deleteMarker,t.options));if(i.error)throw this.stores.get(e)?.deref()===n&&(this.stores.delete(e),this.finalizer.unregister(n)),i.error;let a=i.value;return this.storeToOnce.set(a,n),a}async release(e){let t=this.stores.get(e);if(t){let n=t.deref();if(n&&(this.finalizer.unregister(n),n.done())){let t=n.get();if(t){try{await t.dispose()}catch(t){this.logger.error(`StoreRegistry Error disposing store during release`,{storeId:e,error:t})}this.storeToOnce.delete(t)}}return this.stores.delete(e)}return!1}async clear(){for(let e of this.stores.values()){let t=e.deref();if(t&&(this.finalizer.unregister(t),t.done())){let e=t.get();if(e){try{await e.dispose()}catch{}this.storeToOnce.delete(e)}}}this.stores.clear()}has(e){return this.stores.has(e)}get size(){return this.stores.size}},P=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;logger;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.logger=C(t.logger),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){if(this.isSilent)return;if(e===`group`||e===`groupEnd`||e===`table`){typeof console[e]==`function`&&console[e](...t);return}let n=typeof t[0]==`string`?t[0]:String(t[0]??``),r=t.length>1?{detail:t.slice(1)}:void 0;switch(e){case`log`:this.logger.log(n,r);break;case`warn`:this.logger.warn(n,r);break;case`error`:this.logger.error(n,r);break;case`debug`:this.logger.debug(n,r);break}}setupEventListeners(){for(let e of[`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`]){let t=e.startsWith(`update`)&&this.logEvents.updates||e.startsWith(`middleware`)&&this.logEvents.middleware||e.startsWith(`transaction`)&&this.logEvents.transactions||e.startsWith(`action`)&&this.logEvents.actions||e.startsWith(`selector`)&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(e,n=>{this.isTimeTraveling||(e===`update:complete`&&!n.blocked&&this.recordStateSnapshot(n.deltas),e===`middleware:executed`?this.middlewareExecutions.push(n):e===`transaction:start`?this.activeTransactionCount++:(e===`transaction:complete`||e===`transaction:error`)&&(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),n.batchId&&(e.endsWith(`start`)?this.activeBatches.add(n.batchId):(e.endsWith(`complete`)||e.endsWith(`error`))&&this.activeBatches.delete(n.batchId)),this.recordEvent(e,n),this.enableConsoleLogging&&t&&this._log(e,n),this._checkPerformance(e,n))}))}}recordStateSnapshot(e){let 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){let n={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(n),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={}){let{logLevel:t=`debug`,logUpdates:n=!0}=e;return(e,r)=>(n&&this.logger[t](`State Update`,{update:r}),r)}createValidationMiddleware(e){return(t,n)=>{let r=e(t,n);return typeof r==`boolean`?r:(!r.valid&&r.reason&&this._consoleLog(`warn`,`Validation failed:`,r.reason),r.valid)}}getRecentChanges(e=5){let t=[],n=Math.min(e,this.stateHistory.length);for(let e=0;e<n;e++){let n=this.stateHistory[e];if(!n.deltas||n.deltas.length===0)continue;let r={},i={},a=(e,t,n)=>{t.reduce((e,r,i)=>(i===t.length-1?e[r]=n:e[r]=e[r]??{},e[r]),e)};for(let e of n.deltas){let t=e.path.split(`.`);a(r,t,e.oldValue),a(i,t,e.newValue)}t.push({timestamp:n.timestamp,changedPaths:n.deltas.map(e=>e.path),from:r,to:i})}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){let t=this.eventHistory.filter(e=>e.type===`update:start`)[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=[],n=this.store.on(`update:complete`,n=>{!this.isTimeTraveling&&!n.blocked&&(t=[],e=0)});this.unsubscribers.push(n);let r=()=>this.stateHistory.length,i=()=>e<r()-1,a=()=>t.length>0;return{canUndo:i,canRedo:a,undo:async()=>{if(!i())return;t.unshift(this.stateHistory[e]),e++;let n=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...n},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;let n=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...n.state},{force:!0}),this.isTimeTraveling=!1},length:r,clear:()=>{t=[],e=0}}}async saveSession(e){let t=this.store.id(),n={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,n))}async loadSession(e){let 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):!1}exportSession(){let e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`store-observer-session-${new Date().toISOString()}.json`,r.click(),URL.revokeObjectURL(n)}importSession(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=async e=>{try{let n=JSON.parse(e.target?.result);this.eventHistory=n.eventHistory||[],this.stateHistory=n.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){n(e)}},r.onerror=e=>n(e),r.readAsText(e)})}disconnect(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){let n=new Date(t.timestamp||Date.now()).toISOString().split(`T`)[1].replace(`Z`,``);if(e===`update:start`)this._consoleLog(`group`,`%c⚡ Store Update Started [${n}]`,`color: #4a6da7`);else if(e===`update:complete`){if(t.blocked)this._consoleLog(`warn`,`%c✋ Update Blocked [${n}]`,`color: #bf8c0a`,t.error);else{let e=t.deltas||[];e.length>0&&(this._consoleLog(`log`,`%c✅ Update Complete [${n}] - ${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 e===`middleware:start`?this._consoleLog(`debug`,`%c◀ Middleware \"${t.name}\" started [${n}] (${t.type})`,`color: #8c8c8c`):e===`middleware:complete`?this._consoleLog(`debug`,`%c▶ Middleware \"${t.name}\" completed [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #7c9c7c`):e===`middleware:error`?this._consoleLog(`error`,`%c❌ Middleware \"${t.name}\" error [${n}]:`,`color: #e63946`,t.error):e===`middleware:blocked`?this._consoleLog(`warn`,`%c🛑 Middleware \"${t.name}\" blocked update [${n}]`,`color: #e76f51`):e===`transaction:start`?this._consoleLog(`group`,`%c📦 Transaction Started [${n}]`,`color: #6d597a`):e===`transaction:complete`?(this._consoleLog(`log`,`%c📦 Transaction Complete [${n}]`,`color: #355070`),this._consoleLog(`groupEnd`)):e===`transaction:error`?(this._consoleLog(`error`,`%c📦 Transaction Error [${n}]:`,`color: #e56b6f`,t.error),this._consoleLog(`groupEnd`)):e===`action:start`?this._consoleLog(`group`,`%c🚀 Action \"${t.name}\" Started [${n}]`,`color: #9b59b6`,{params:t.params}):e===`action:complete`?(this._consoleLog(`log`,`%c✔️ Action \"${t.name}\" Complete [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #2ecc71`),this._consoleLog(`groupEnd`)):e===`action:error`?(this._consoleLog(`error`,`%c🔥 Action \"${t.name}\" Error [${n}]:`,`color: #e74c3c`,t.error),this._consoleLog(`groupEnd`)):e===`selector:accessed`&&this._consoleLog(`debug`,`%c👀 Selector Accessed [${n}] in ${t.duration?.toFixed(2)}ms`,`color: #f1c40f`,{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&(e===`update:complete`&&!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}),e===`middleware:complete`&&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{D as ActionCancelledError,j as ActionManager,c as DELETE_SYMBOL,M as ReactiveDataStore,p as SelectorManager,P as StoreObserver,N as StoreRegistry,O as UnknownActionError,m as buildPaths,_ as createDerivePaths,g as createDiff,u as createMerge,C as createStoreLogger,y as derivePaths,v as diff,d as merge,l as shallowClone};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-store",
3
- "version": "10.2.9",
3
+ "version": "10.2.11",
4
4
  "description": "A reactive data store",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -29,11 +29,11 @@
29
29
  "access": "public"
30
30
  },
31
31
  "dependencies": {
32
- "@asaidimu/utils-events": "^1.2.4",
33
- "@asaidimu/utils-logger": "^1.0.6",
32
+ "@asaidimu/utils-events": "1.2.5",
33
+ "@asaidimu/utils-logger": "1.0.7",
34
34
  "uuid": "^14.0.0",
35
- "@asaidimu/utils-sync": "^2.3.3",
36
- "@asaidimu/utils-persistence": "^6.1.14"
35
+ "@asaidimu/utils-sync": "2.3.4",
36
+ "@asaidimu/utils-persistence": "6.1.15"
37
37
  },
38
38
  "exports": {
39
39
  ".": {