@asaidimu/utils-store 9.0.1 → 9.0.3
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/README.md +666 -454
- package/index.d.mts +56 -102
- package/index.d.ts +56 -102
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +2 -2
package/index.d.mts
CHANGED
|
@@ -1,102 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Options for configuring the EventBus.
|
|
3
|
-
* Each field has an independent default — passing a partial object is safe.
|
|
4
|
-
*/
|
|
5
|
-
interface EventBusOptions {
|
|
6
|
-
batch?: {
|
|
7
|
-
/**
|
|
8
|
-
* Maximum number of events to accumulate before forcing a synchronous
|
|
9
|
-
* flush, regardless of the batch delay timer.
|
|
10
|
-
*/
|
|
11
|
-
size: number;
|
|
12
|
-
/**
|
|
13
|
-
* Milliseconds to wait (quiet period) before flushing a batch.
|
|
14
|
-
* Only applies when `deferred: true`.
|
|
15
|
-
* @default 16
|
|
16
|
-
*/
|
|
17
|
-
delay?: number;
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* Called when a subscriber callback throws. Defaults to console.error.
|
|
21
|
-
* Errors in one subscriber do not prevent other subscribers from running.
|
|
22
|
-
*/
|
|
23
|
-
errorHandler?: (error: EventError) => void;
|
|
24
|
-
/**
|
|
25
|
-
* When set, events are broadcast to other instances via BroadcastChannel.
|
|
26
|
-
* Only applies in environments that support BroadcastChannel.
|
|
27
|
-
*/
|
|
28
|
-
broadcast?: {
|
|
29
|
-
/**
|
|
30
|
-
* The BroadcastChannel name used for cross-tab communication.
|
|
31
|
-
* Must be unique per logical bus if you run multiple buses.
|
|
32
|
-
* Only applies when `crossTab: true`.
|
|
33
|
-
*/
|
|
34
|
-
channel: string;
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Interface defining the shape of the EventBus.
|
|
39
|
-
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
40
|
-
*/
|
|
41
|
-
interface EventBus<TEventMap extends Record<string, any>> {
|
|
42
|
-
/**
|
|
43
|
-
* Subscribes to a specific event by name.
|
|
44
|
-
* @param eventName - The name of the event to subscribe to.
|
|
45
|
-
* @param callback - The function to call when the event is emitted.
|
|
46
|
-
* @returns A function to unsubscribe from the event.
|
|
47
|
-
*/
|
|
48
|
-
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
49
|
-
/**
|
|
50
|
-
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
51
|
-
* @param eventName - The name of the event to subscribe to.
|
|
52
|
-
* @param callback - The function to call when the event is emitted.
|
|
53
|
-
* @returns A function to cancel the one-shot subscription before it fires.
|
|
54
|
-
*/
|
|
55
|
-
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
56
|
-
/**
|
|
57
|
-
* Emits an event with a payload to all subscribed listeners.
|
|
58
|
-
* @param event - An object containing the event name and payload.
|
|
59
|
-
*/
|
|
60
|
-
emit: <TEventName extends keyof TEventMap>(event: {
|
|
61
|
-
name: TEventName;
|
|
62
|
-
payload: TEventMap[TEventName];
|
|
63
|
-
}) => void;
|
|
64
|
-
/**
|
|
65
|
-
* Retrieves metrics about event bus usage.
|
|
66
|
-
* @returns An object containing various metrics.
|
|
67
|
-
*/
|
|
68
|
-
metrics: () => EventMetrics;
|
|
69
|
-
/**
|
|
70
|
-
* Clears all subscriptions and resets metrics.
|
|
71
|
-
* After calling clear(), the bus is fully reset and can be reused —
|
|
72
|
-
* cross-tab communication is re-established if it was previously enabled.
|
|
73
|
-
*/
|
|
74
|
-
clear: () => void;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Interface defining the metrics tracked by the EventBus.
|
|
78
|
-
*/
|
|
79
|
-
interface EventMetrics {
|
|
80
|
-
/** Total number of events emitted (both sync and deferred paths). */
|
|
81
|
-
totalEvents: number;
|
|
82
|
-
/** Number of active subscriptions across all event names. */
|
|
83
|
-
activeSubscriptions: number;
|
|
84
|
-
/** Map of event names to their emission counts. */
|
|
85
|
-
eventCounts: Map<string, number>;
|
|
86
|
-
/** Average duration of event dispatch in milliseconds. */
|
|
87
|
-
averageEmitDuration: number;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Custom error interface for event bus errors.
|
|
91
|
-
* @extends Error
|
|
92
|
-
*/
|
|
93
|
-
interface EventError extends Error {
|
|
94
|
-
/** Optional name of the event that caused the error. */
|
|
95
|
-
eventName?: string;
|
|
96
|
-
/** Optional payload that caused the error. */
|
|
97
|
-
payload?: unknown;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
1
|
interface SimplePersistence<T> {
|
|
101
2
|
/**
|
|
102
3
|
* Persists data to storage.
|
|
@@ -367,8 +268,8 @@ type StateUpdater<T> = T | DeepPartial<T> | ((state: T) => DeepPartial<T> | Prom
|
|
|
367
268
|
*/
|
|
368
269
|
declare const DELETE_SYMBOL: unique symbol;
|
|
369
270
|
/**
|
|
370
|
-
* Core types for the reactive data store
|
|
371
|
-
*/
|
|
271
|
+
* Core types for the reactive data store
|
|
272
|
+
*/
|
|
372
273
|
/**
|
|
373
274
|
* Type for a Transform Middleware function.
|
|
374
275
|
* It modifies (transforms) the incoming changes and must return a `DeepPartial<T>`.
|
|
@@ -661,7 +562,7 @@ declare class ReactiveDataStore<T extends object> implements DataStore<T> {
|
|
|
661
562
|
constructor(initialData: T, persistence?: SimplePersistence<T>, deleteMarker?: symbol, options?: {
|
|
662
563
|
persistenceMaxRetries?: number;
|
|
663
564
|
persistenceRetryDelay?: number;
|
|
664
|
-
}
|
|
565
|
+
});
|
|
665
566
|
/**
|
|
666
567
|
* Returns true if the store has finished initialising (persistence loaded).
|
|
667
568
|
* For async flows, prefer `await store.ready()` over polling this.
|
|
@@ -1075,6 +976,59 @@ declare function createMerge(options?: {
|
|
|
1075
976
|
declare const merge: <T extends object>(original: T, changes: DeepPartial<T> | symbol) => T;
|
|
1076
977
|
type MergeFunction = ReturnType<typeof createMerge>;
|
|
1077
978
|
|
|
979
|
+
/**
|
|
980
|
+
* Interface defining the shape of the EventBus.
|
|
981
|
+
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
982
|
+
*/
|
|
983
|
+
interface EventBus<TEventMap extends Record<string, any>> {
|
|
984
|
+
/**
|
|
985
|
+
* Subscribes to a specific event by name.
|
|
986
|
+
* @param eventName - The name of the event to subscribe to.
|
|
987
|
+
* @param callback - The function to call when the event is emitted.
|
|
988
|
+
* @returns A function to unsubscribe from the event.
|
|
989
|
+
*/
|
|
990
|
+
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
991
|
+
/**
|
|
992
|
+
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
993
|
+
* @param eventName - The name of the event to subscribe to.
|
|
994
|
+
* @param callback - The function to call when the event is emitted.
|
|
995
|
+
* @returns A function to cancel the one-shot subscription before it fires.
|
|
996
|
+
*/
|
|
997
|
+
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
998
|
+
/**
|
|
999
|
+
* Emits an event with a payload to all subscribed listeners.
|
|
1000
|
+
* @param event - An object containing the event name and payload.
|
|
1001
|
+
*/
|
|
1002
|
+
emit: <TEventName extends keyof TEventMap>(event: {
|
|
1003
|
+
name: TEventName;
|
|
1004
|
+
payload: TEventMap[TEventName];
|
|
1005
|
+
}) => void;
|
|
1006
|
+
/**
|
|
1007
|
+
* Retrieves metrics about event bus usage.
|
|
1008
|
+
* @returns An object containing various metrics.
|
|
1009
|
+
*/
|
|
1010
|
+
metrics: () => EventMetrics;
|
|
1011
|
+
/**
|
|
1012
|
+
* Clears all subscriptions and resets metrics.
|
|
1013
|
+
* After calling clear(), the bus is fully reset and can be reused —
|
|
1014
|
+
* cross-tab communication is re-established if it was previously enabled.
|
|
1015
|
+
*/
|
|
1016
|
+
clear: () => void;
|
|
1017
|
+
}
|
|
1018
|
+
/**
|
|
1019
|
+
* Interface defining the metrics tracked by the EventBus.
|
|
1020
|
+
*/
|
|
1021
|
+
interface EventMetrics {
|
|
1022
|
+
/** Total number of events emitted (both sync and deferred paths). */
|
|
1023
|
+
totalEvents: number;
|
|
1024
|
+
/** Number of active subscriptions across all event names. */
|
|
1025
|
+
activeSubscriptions: number;
|
|
1026
|
+
/** Map of event names to their emission counts. */
|
|
1027
|
+
eventCounts: Map<string, number>;
|
|
1028
|
+
/** Average duration of event dispatch in milliseconds. */
|
|
1029
|
+
averageEmitDuration: number;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1078
1032
|
declare class ActionCancelledError extends Error {
|
|
1079
1033
|
constructor();
|
|
1080
1034
|
}
|
package/index.d.ts
CHANGED
|
@@ -1,102 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Options for configuring the EventBus.
|
|
3
|
-
* Each field has an independent default — passing a partial object is safe.
|
|
4
|
-
*/
|
|
5
|
-
interface EventBusOptions {
|
|
6
|
-
batch?: {
|
|
7
|
-
/**
|
|
8
|
-
* Maximum number of events to accumulate before forcing a synchronous
|
|
9
|
-
* flush, regardless of the batch delay timer.
|
|
10
|
-
*/
|
|
11
|
-
size: number;
|
|
12
|
-
/**
|
|
13
|
-
* Milliseconds to wait (quiet period) before flushing a batch.
|
|
14
|
-
* Only applies when `deferred: true`.
|
|
15
|
-
* @default 16
|
|
16
|
-
*/
|
|
17
|
-
delay?: number;
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* Called when a subscriber callback throws. Defaults to console.error.
|
|
21
|
-
* Errors in one subscriber do not prevent other subscribers from running.
|
|
22
|
-
*/
|
|
23
|
-
errorHandler?: (error: EventError) => void;
|
|
24
|
-
/**
|
|
25
|
-
* When set, events are broadcast to other instances via BroadcastChannel.
|
|
26
|
-
* Only applies in environments that support BroadcastChannel.
|
|
27
|
-
*/
|
|
28
|
-
broadcast?: {
|
|
29
|
-
/**
|
|
30
|
-
* The BroadcastChannel name used for cross-tab communication.
|
|
31
|
-
* Must be unique per logical bus if you run multiple buses.
|
|
32
|
-
* Only applies when `crossTab: true`.
|
|
33
|
-
*/
|
|
34
|
-
channel: string;
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Interface defining the shape of the EventBus.
|
|
39
|
-
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
40
|
-
*/
|
|
41
|
-
interface EventBus<TEventMap extends Record<string, any>> {
|
|
42
|
-
/**
|
|
43
|
-
* Subscribes to a specific event by name.
|
|
44
|
-
* @param eventName - The name of the event to subscribe to.
|
|
45
|
-
* @param callback - The function to call when the event is emitted.
|
|
46
|
-
* @returns A function to unsubscribe from the event.
|
|
47
|
-
*/
|
|
48
|
-
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
49
|
-
/**
|
|
50
|
-
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
51
|
-
* @param eventName - The name of the event to subscribe to.
|
|
52
|
-
* @param callback - The function to call when the event is emitted.
|
|
53
|
-
* @returns A function to cancel the one-shot subscription before it fires.
|
|
54
|
-
*/
|
|
55
|
-
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
56
|
-
/**
|
|
57
|
-
* Emits an event with a payload to all subscribed listeners.
|
|
58
|
-
* @param event - An object containing the event name and payload.
|
|
59
|
-
*/
|
|
60
|
-
emit: <TEventName extends keyof TEventMap>(event: {
|
|
61
|
-
name: TEventName;
|
|
62
|
-
payload: TEventMap[TEventName];
|
|
63
|
-
}) => void;
|
|
64
|
-
/**
|
|
65
|
-
* Retrieves metrics about event bus usage.
|
|
66
|
-
* @returns An object containing various metrics.
|
|
67
|
-
*/
|
|
68
|
-
metrics: () => EventMetrics;
|
|
69
|
-
/**
|
|
70
|
-
* Clears all subscriptions and resets metrics.
|
|
71
|
-
* After calling clear(), the bus is fully reset and can be reused —
|
|
72
|
-
* cross-tab communication is re-established if it was previously enabled.
|
|
73
|
-
*/
|
|
74
|
-
clear: () => void;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Interface defining the metrics tracked by the EventBus.
|
|
78
|
-
*/
|
|
79
|
-
interface EventMetrics {
|
|
80
|
-
/** Total number of events emitted (both sync and deferred paths). */
|
|
81
|
-
totalEvents: number;
|
|
82
|
-
/** Number of active subscriptions across all event names. */
|
|
83
|
-
activeSubscriptions: number;
|
|
84
|
-
/** Map of event names to their emission counts. */
|
|
85
|
-
eventCounts: Map<string, number>;
|
|
86
|
-
/** Average duration of event dispatch in milliseconds. */
|
|
87
|
-
averageEmitDuration: number;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Custom error interface for event bus errors.
|
|
91
|
-
* @extends Error
|
|
92
|
-
*/
|
|
93
|
-
interface EventError extends Error {
|
|
94
|
-
/** Optional name of the event that caused the error. */
|
|
95
|
-
eventName?: string;
|
|
96
|
-
/** Optional payload that caused the error. */
|
|
97
|
-
payload?: unknown;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
1
|
interface SimplePersistence<T> {
|
|
101
2
|
/**
|
|
102
3
|
* Persists data to storage.
|
|
@@ -367,8 +268,8 @@ type StateUpdater<T> = T | DeepPartial<T> | ((state: T) => DeepPartial<T> | Prom
|
|
|
367
268
|
*/
|
|
368
269
|
declare const DELETE_SYMBOL: unique symbol;
|
|
369
270
|
/**
|
|
370
|
-
* Core types for the reactive data store
|
|
371
|
-
*/
|
|
271
|
+
* Core types for the reactive data store
|
|
272
|
+
*/
|
|
372
273
|
/**
|
|
373
274
|
* Type for a Transform Middleware function.
|
|
374
275
|
* It modifies (transforms) the incoming changes and must return a `DeepPartial<T>`.
|
|
@@ -661,7 +562,7 @@ declare class ReactiveDataStore<T extends object> implements DataStore<T> {
|
|
|
661
562
|
constructor(initialData: T, persistence?: SimplePersistence<T>, deleteMarker?: symbol, options?: {
|
|
662
563
|
persistenceMaxRetries?: number;
|
|
663
564
|
persistenceRetryDelay?: number;
|
|
664
|
-
}
|
|
565
|
+
});
|
|
665
566
|
/**
|
|
666
567
|
* Returns true if the store has finished initialising (persistence loaded).
|
|
667
568
|
* For async flows, prefer `await store.ready()` over polling this.
|
|
@@ -1075,6 +976,59 @@ declare function createMerge(options?: {
|
|
|
1075
976
|
declare const merge: <T extends object>(original: T, changes: DeepPartial<T> | symbol) => T;
|
|
1076
977
|
type MergeFunction = ReturnType<typeof createMerge>;
|
|
1077
978
|
|
|
979
|
+
/**
|
|
980
|
+
* Interface defining the shape of the EventBus.
|
|
981
|
+
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
982
|
+
*/
|
|
983
|
+
interface EventBus<TEventMap extends Record<string, any>> {
|
|
984
|
+
/**
|
|
985
|
+
* Subscribes to a specific event by name.
|
|
986
|
+
* @param eventName - The name of the event to subscribe to.
|
|
987
|
+
* @param callback - The function to call when the event is emitted.
|
|
988
|
+
* @returns A function to unsubscribe from the event.
|
|
989
|
+
*/
|
|
990
|
+
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
991
|
+
/**
|
|
992
|
+
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
993
|
+
* @param eventName - The name of the event to subscribe to.
|
|
994
|
+
* @param callback - The function to call when the event is emitted.
|
|
995
|
+
* @returns A function to cancel the one-shot subscription before it fires.
|
|
996
|
+
*/
|
|
997
|
+
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
998
|
+
/**
|
|
999
|
+
* Emits an event with a payload to all subscribed listeners.
|
|
1000
|
+
* @param event - An object containing the event name and payload.
|
|
1001
|
+
*/
|
|
1002
|
+
emit: <TEventName extends keyof TEventMap>(event: {
|
|
1003
|
+
name: TEventName;
|
|
1004
|
+
payload: TEventMap[TEventName];
|
|
1005
|
+
}) => void;
|
|
1006
|
+
/**
|
|
1007
|
+
* Retrieves metrics about event bus usage.
|
|
1008
|
+
* @returns An object containing various metrics.
|
|
1009
|
+
*/
|
|
1010
|
+
metrics: () => EventMetrics;
|
|
1011
|
+
/**
|
|
1012
|
+
* Clears all subscriptions and resets metrics.
|
|
1013
|
+
* After calling clear(), the bus is fully reset and can be reused —
|
|
1014
|
+
* cross-tab communication is re-established if it was previously enabled.
|
|
1015
|
+
*/
|
|
1016
|
+
clear: () => void;
|
|
1017
|
+
}
|
|
1018
|
+
/**
|
|
1019
|
+
* Interface defining the metrics tracked by the EventBus.
|
|
1020
|
+
*/
|
|
1021
|
+
interface EventMetrics {
|
|
1022
|
+
/** Total number of events emitted (both sync and deferred paths). */
|
|
1023
|
+
totalEvents: number;
|
|
1024
|
+
/** Number of active subscriptions across all event names. */
|
|
1025
|
+
activeSubscriptions: number;
|
|
1026
|
+
/** Map of event names to their emission counts. */
|
|
1027
|
+
eventCounts: Map<string, number>;
|
|
1028
|
+
/** Average duration of event dispatch in milliseconds. */
|
|
1029
|
+
averageEmitDuration: number;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1078
1032
|
declare class ActionCancelledError extends Error {
|
|
1079
1033
|
constructor();
|
|
1080
1034
|
}
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("uuid"),t=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},s=class extends t{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},i=class extends t{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},r=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const i=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await i;let r;await Promise.race([i.then((()=>clearTimeout(r))),new Promise(((i,a)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),a(new s("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},a=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new r({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new i};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new i;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},n=class{_open=!1;_resolve;_promise;constructor(){this._promise=new Promise((e=>{this._resolve=e}))}open(){this._open||(this._open=!0,this._resolve())}async wait(e){if(this._open)return;if(null==e)return this._promise;let t;await Promise.race([this._promise.then((()=>clearTimeout(t))),new Promise(((i,r)=>{t=setTimeout((()=>r(new s("Latch timed out"))),e)}))])}isOpen(){return this._open}},o=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise((t=>{this._enqueue(e,t)}))}fire(e){this._enqueue(e,void 0)}_enqueue(e,t){if(this._pendingFn=e,t&&this._pendingResolvers.push(t),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout((()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()}),this._delay));clearTimeout(this._timer),this._timer=setTimeout((()=>{this._leadingFired=!1,this._fire()}),this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const t of e)t({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,t=this._pendingResolvers.splice(0);let s;this._pendingFn=void 0;try{s={status:"ok",value:await e()}}catch(e){s={status:"error",error:e}}for(const e of t)e(s);return s}};function c(e){const t=e??{},{deferred:s,batchSize:i,batchDelay:r,errorHandler:a,broadcast:n,channel:c}={deferred:null!=t.batch?.size,batchSize:t.batch?.size,batchDelay:t.batch?.delay||16,errorHandler:t.errorHandler||(e=>console.error("EventBus Error:",e)),broadcast:null!=t.broadcast?.channel&&t.broadcast.channel.length>0,channel:null!=t.broadcast?.channel&&t.broadcast.channel.length>0?t.broadcast?.channel:"event-bus-channel"},d=new Map;let l=[],h=0,u=0;const p=new Map,m=()=>{if(!n)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(c);return e.onmessage=e=>{const{name:t,payload:s}=e.data;f(t,s)},e};let g=m();const y=(e,t)=>{h++,u+=t,p.set(e,(p.get(e)??0)+1)},f=(e,t)=>{const s=d.get(e);if(s&&0!==s.size)for(const i of Array.from(s))try{i(t)}catch(s){const i=s instanceof Error?s:Object.assign(new Error(String(s)),{cause:s}),r=Object.assign(i,{eventName:e,payload:t});a(r)}},w=()=>{const e=l;l=[];for(const{name:t,payload:s}of e){const e=performance.now();f(t,s),y(t,performance.now()-e)}},v=new o({delay:r});return{subscribe:(e,t)=>{d.has(e)||d.set(e,new Set);const s=d.get(e);return s.add(t),()=>{s.delete(t),0===s.size&&d.delete(e)}},once:(e,t)=>{let s;const i=e=>{s(),t(e)};return s=(()=>{d.has(e)||d.set(e,new Set);const t=d.get(e);return t.add(i),()=>{t.delete(i),0===t.size&&d.delete(e)}})(),s},emit:({name:e,payload:t})=>{if(s)return l.push({name:e,payload:t}),l.length>=i?(v.cancel(),void w()):(v.fire((()=>w())),void g?.postMessage({name:e,payload:t}));const r=performance.now();f(e,t),y(e,performance.now()-r),g?.postMessage({name:e,payload:t})},metrics:()=>({totalEvents:h,activeSubscriptions:Array.from(d.values()).reduce(((e,t)=>e+t.size),0),eventCounts:p,averageEmitDuration:h>0?u/h:0}),clear:()=>{d.clear(),l=[],v.cancel(),h=0,u=0,p.clear(),g?.close(),g=m()}}}var d=Symbol.for("delete"),l=e=>Array.isArray(e)?[...e]:{...e};function h(e){const t=e?.deleteMarker||d;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const i={};for(const[r,a]of Object.entries(e))if(a!==t)if("object"==typeof a&&null!==a){const e=s(a);void 0!==e&&(i[r]=e)}else i[r]=a;return i}return e===t?void 0:e}return function(e,i){if("object"!=typeof e||null===e)return"object"==typeof i&&null!==i?s(i):i===t?{}:i;if("object"!=typeof i||null===i)return e;const r=l(e),a=[{target:r,source:i}];for(;a.length>0;){const{target:e,source:s}=a.pop();for(const i of Object.keys(s)){const r=s[i];if(r!==t)if(Array.isArray(r))e[i]=r;else if("object"==typeof r&&null!==r){const t=i in e&&"object"==typeof e[i]&&null!==e[i]?e[i]:{};e[i]=l(t),a.push({target:e[i],source:r})}else e[i]=r;else delete e[i]}}return r}}var u=h(),p=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"],m=class{reactiveSelectors=new Map;reactiveSelectorCache=new WeakMap;pathBasedCache=new Map;dependencyMap=new Map;getState;eventBus;unsubscribeFromStore;constructor(e,t){this.getState=e,this.eventBus=t,this.unsubscribeFromStore=this.eventBus.subscribe("update:complete",this.handleStoreUpdate)}handleStoreUpdate=e=>{const t=new Set;for(const s of e.deltas){const e=s.path;for(const[s,i]of this.dependencyMap)if(s===e||s.startsWith(e+".")||e.startsWith(s+"."))for(const e of i)t.add(e)}t.forEach((e=>{const t=this.reactiveSelectors.get(e);t&&this.evaluateEntry(t)}))};evaluateEntry(e){let t;try{t=e.selector(this.getState())}catch{t=void 0}t!==e.lastResult&&(e.lastResult=t,e.subscribers.forEach((e=>e(t))),this.eventBus.emit({name:"selector:changed",payload:{selectorId:e.id,newResult:t,timestamp:performance.now()}}))}createReactiveSelector(e){const t=this.reactiveSelectorCache.get(e);if(t)return t;const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const a=new Proxy((()=>{}),{get:(i,a)=>{if("symbol"==typeof a||"then"===a)return;if("valueOf"===a||"toString"===a)throw new Error("Cannot perform logic/math/string operations inside a selector.");if(p.includes(a))throw new Error(`Array method .${a}() is not allowed in selectors.`);const n=e?`${e}${t}${a}`:a;return e&&s.delete(e),s.add(n),r(n)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions/methods.")}});return i.set(e,a),a};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. This usually means the selector is too complex. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e),i=`${[...s].sort().join("|")}::${e.toString()}`,r=this.pathBasedCache.get(i);if(r)return this.reactiveSelectorCache.set(e,r),r;const a=`sel-${Math.random().toString(36).slice(2,9)}`,n=e(this.getState()),o={id:a,selector:e,lastResult:n,accessedPaths:s,subscribers:new Set,reactiveSelectorInstance:null};s.forEach((e=>{this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(a)}));const c={get:()=>o.lastResult,id:a,subscribe:t=>(o.subscribers.add(t),()=>{o.subscribers.delete(t),0===o.subscribers.size&&this.cleanupSelector(a,e,i)})};return o.reactiveSelectorInstance=c,this.reactiveSelectors.set(a,o),this.reactiveSelectorCache.set(e,c),this.pathBasedCache.set(i,c),this.eventBus.emit({name:"selector:accessed",payload:{selectorId:a,accessedPaths:s,duration:0,timestamp:performance.now()}}),c}cleanupSelector(e,t,s){const i=this.reactiveSelectors.get(e);i&&(i.accessedPaths.forEach((t=>{this.dependencyMap.get(t)?.delete(e),0===this.dependencyMap.get(t)?.size&&this.dependencyMap.delete(t)})),this.reactiveSelectors.delete(e),this.reactiveSelectorCache.delete(t),this.pathBasedCache.delete(s))}dispose(){this.unsubscribeFromStore(),this.reactiveSelectors.clear(),this.dependencyMap.clear(),this.pathBasedCache.clear()}};function g(e,t){if(e===t)return!0;if(e&&t&&"object"==typeof e&&"object"==typeof t){if(e.constructor!==t.constructor)return!1;let s,i;if(Array.isArray(e)){if(s=e.length,s!=t.length)return!1;for(i=s;i-- >0;)if(!g(e[i],t[i]))return!1;return!0}const[r,a]=[Object.keys(e),Object.keys(t)];if(s=r.length,s!==a.length)return!1;for(i=s;i-- >0;){const s=r[i];if(!Object.prototype.hasOwnProperty.call(t,s)||!g(e[s],t[s]))return!1}return!0}return e!=e&&t!=t}function y(e){const t=e?.deleteMarker||d;return function(e,s){const i=[],r=[{pathStr:"",orig:e||{},part:s||{}}];for(;r.length>0;){const{pathStr:e,orig:s,part:a}=r.pop();if(null!=a&&!g(s,a))if("object"!=typeof a||Array.isArray(a))e&&i.push({path:e,oldValue:s,newValue:a});else for(const n of Object.keys(a)){const o=e?e+"."+n:n,c=a[n],d=s&&"object"==typeof s?s[n]:void 0;c!==t?"object"==typeof c&&null!==c?r.push({pathStr:o,orig:d,part:c}):g(d,c)||i.push({path:o,oldValue:d,newValue:c}):void 0!==d&&i.push({path:o,oldValue:d,newValue:void 0})}}return i}}function f(e){const t=e?.deleteMarker||d;return function(e){const s=new Set,i=[{obj:e,currentPath:""}];for(;i.length>0;){const{obj:e,currentPath:r}=i.pop();if(null!=e&&"object"==typeof e&&!Array.isArray(e))for(const a of Object.keys(e)){const n=r?`${r}.${a}`:a;s.add(n);const o=e[a];"object"!=typeof o||null===o||Array.isArray(o)||o===t||i.push({obj:o,currentPath:n})}}return Array.from(s)}}var w=y(),v=f(),b=class{constructor(e,t,s){this.updateBus=t,this.diff=s,this.cache=structuredClone(e)}cache;get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,s=!1,i=[]){if(t)return this.cache=s?structuredClone(e):e,this.notifyListeners([]),[];0===i.length&&(i=[e]);const r=this.get(!1),a=new Map;for(let e=0;e<i.length;e++){const t=i[e],s=this.diff(r,t);for(let e=0;e<s.length;e++){const t=s[e];a.set(t.path,t)}}const n=a.size?[...a.values()]:[];if(n.length>0){this.cache=s?structuredClone(e):e;const t=new Set;for(let e=0;e<n.length;e++){let s=n[e].path;for(;s&&!t.has(s);){t.add(s);const e=s.lastIndexOf(".");if(e<0)break;s=s.slice(0,e)}}this.notifyListeners(t)}return n}notifyListeners(e){for(const t of e)this.updateBus.emit({name:"update",payload:t})}},S=class{constructor(e,t,s){this.eventBus=e,this.executionState=t,this.merge=s}middleware=[];blockingMiddleware=[];async executeBlocking(e,t){for(const{fn:s,name:i,id:r}of this.blockingMiddleware){const a={id:r,name:i,startTime:performance.now()};this.executionState.runningMiddleware={id:r,name:i,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:r,name:i,type:"blocking"});try{const n=await Promise.resolve(s(e,t));if(a.endTime=performance.now(),a.duration=a.endTime-a.startTime,!1===n)return a.blocked=!0,this.emitMiddlewareLifecycle("blocked",{id:r,name:i,duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0};this.emitMiddlewareLifecycle("complete",{id:r,name:i,type:"blocking",duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:{...a,blocked:!1}})}catch(e){return a.endTime=performance.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:new Error(String(e)),a.blocked=!0,this.emitMiddlewareError(r,i,a.error,a.duration),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0,error:a.error}}finally{this.executionState.runningMiddleware=null}}return{blocked:!1}}async executeTransform(e,t){let s=e,i=t;for(const{fn:e,name:r,id:a}of this.middleware){const n={id:a,name:r,startTime:performance.now()};this.executionState.runningMiddleware={id:a,name:r,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:a,name:r,type:"transform"});try{const o=await Promise.resolve(e(s,t));n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.blocked=!1,o&&"object"==typeof o&&(s=this.merge(s,o),i=this.merge(i,o)),this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareLifecycle("complete",{id:a,name:r,type:"transform",duration:n.duration})}catch(e){n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.error=e instanceof Error?e:new Error(String(e)),n.blocked=!1,this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareError(a,r,n.error,n.duration),console.error(`Middleware ${r} error:`,e)}finally{this.executionState.runningMiddleware=null}}return i}addMiddleware(e,t="unnamed-middleware"){const s=this.generateId();return this.middleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}addBlockingMiddleware(e,t="unnamed-blocking-middleware"){const s=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}removeMiddleware(e){const t=this.middleware.length+this.blockingMiddleware.length;return this.middleware=this.middleware.filter((t=>t.id!==e)),this.blockingMiddleware=this.blockingMiddleware.filter((t=>t.id!==e)),this.updateExecutionState(),this.middleware.length+this.blockingMiddleware.length<t}updateExecutionState(){this.executionState.middlewares=[...this.middleware.map((e=>e.name)),...this.blockingMiddleware.map((e=>e.name))]}emitMiddlewareLifecycle(e,t){this.emit(this.eventBus,{name:`middleware:${e}`,payload:{...t,timestamp:Date.now()}})}emitMiddlewareError(e,t,s,i){this.emit(this.eventBus,{name:"middleware:error",payload:{id:e,name:t,error:s,duration:i,timestamp:Date.now()}})}generateId(){return crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).substring(2,15)}`}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},x=class{constructor(e,t,s,i){this.eventBus=e,this.coreState=t,this.instanceID=s,this.maxRetries=i?.maxRetries??3,this.retryDelay=i?.retryDelay??1e3}persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||0===e.length)return;const s={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(s),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:"persistence:queued",payload:{taskId:s.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:s.timestamp}})}getQueueStatus(){return{queueSize:this.backgroundQueue.length,isProcessing:this.isProcessingQueue,pendingRetries:this.pendingRetries.size,oldestTask:this.backgroundQueue[0]?.timestamp}}async flush(){this.isProcessingQueue&&await new Promise((e=>{const t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()})),await this.processQueue()}discardQueue(){const e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&(clearTimeout(this.queueProcessor),this.queueProcessor=void 0),this.emit(this.eventBus,{name:"persistence:queue_cleared",payload:{clearedTasks:e,timestamp:Date.now()}})}scheduleQueueProcessing(){this.queueProcessor||this.isProcessingQueue||(this.queueProcessor=setTimeout((()=>{this.processQueue().catch((e=>{console.error("Queue processing failed:",e)}))}),10))}async processQueue(){if(!this.isProcessingQueue&&0!==this.backgroundQueue.length){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){const e=this.backgroundQueue.shift();await this.processTask(e)}}finally{this.isProcessingQueue=!1}}}async processTask(e){try{await this.persistence.set(this.instanceID,e.state)?this.emit(this.eventBus,{name:"persistence:success",payload:{taskId:e.id,changedPaths:e.changedPaths,duration:Date.now()-e.timestamp,timestamp:Date.now()}}):await this.handleTaskFailure(e,new Error("Persistence returned false"))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){const s=this.retryDelay*Math.pow(2,e.retries-1);this.emit(this.eventBus,{name:"persistence:retry",payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:s,error:t,timestamp:Date.now()}}),this.pendingRetries.add(e.id),setTimeout((()=>{this.pendingRetries.has(e.id)&&(this.pendingRetries.delete(e.id),this.backgroundQueue.unshift(e),this.scheduleQueueProcessing())}),s)}else this.emit(this.eventBus,{name:"persistence:failed",payload:{taskId:e.id,changedPaths:e.changedPaths,attempts:e.retries,error:t,timestamp:Date.now()}})}setPersistenceReady(){this.persistenceReady=!0,this.emit(this.eventBus,{name:"persistence:ready",payload:{timestamp:Date.now()}})}async setPersistence(e){this.persistence=e;try{const e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){console.error("Failed to initialize persistence:",e),this.emit(this.eventBus,{name:"persistence:init_error",payload:{error:e,timestamp:Date.now()}})}finally{this.setPersistenceReady()}this.persistence.subscribe(this.instanceID,(async e=>{const t=this.coreState.applyChanges(e);t.length>0&&this.emit(this.eventBus,{name:"update:complete",payload:{changedPaths:t,source:"external",timestamp:Date.now()}})}))}dispose(){this.discardQueue(),this.isProcessingQueue=!1,this.persistenceReady=!1}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},E=class{constructor(e,t,s){this.eventBus=e,this.coreState=t,this.executionState=s}async execute(e){const t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:"transaction:start",payload:{timestamp:Date.now()}});try{const t=await Promise.resolve(e());return this.emit(this.eventBus,{name:"transaction:complete",payload:{timestamp:Date.now()}}),this.executionState.transactionActive=!1,t}catch(e){throw this.coreState.applyChanges(t,!0,!1),this.emit(this.eventBus,{name:"transaction:error",payload:{error:e instanceof Error?e:new Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},_=class{updateCount=0;listenerExecutions=0;averageUpdateTime=0;largestUpdateSize=0;mostActiveListenerPaths=[];totalUpdates=0;blockedUpdates=0;averageUpdateDuration=0;middlewareExecutions=0;transactionCount=0;totalEventsFired=0;totalActionsDispatched=0;totalActionsSucceeded=0;totalActionsFailed=0;averageActionDuration=0;updateTimes=[];actionTimes=[];pathExecutionCounts=new Map;constructor(e){this.setupEventListeners(e)}getMetrics(){return{updateCount:this.updateCount,listenerExecutions:this.listenerExecutions,averageUpdateTime:this.averageUpdateTime,largestUpdateSize:this.largestUpdateSize,mostActiveListenerPaths:[...this.mostActiveListenerPaths],totalUpdates:this.totalUpdates,blockedUpdates:this.blockedUpdates,averageUpdateDuration:this.averageUpdateDuration,middlewareExecutions:this.middlewareExecutions,transactionCount:this.transactionCount,totalEventsFired:this.totalEventsFired,totalActionsDispatched:this.totalActionsDispatched,totalActionsSucceeded:this.totalActionsSucceeded,totalActionsFailed:this.totalActionsFailed,averageActionDuration:this.averageActionDuration}}setupEventListeners(e){const t=e.emit;e.emit=s=>(this.totalEventsFired++,t.call(e,s)),e.subscribe("update:complete",(e=>{if(this.totalUpdates++,e.blocked)this.blockedUpdates++;else{if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();const t=this.updateTimes.reduce(((e,t)=>e+t),0)/this.updateTimes.length;this.averageUpdateTime=t,this.averageUpdateDuration=t}e.deltas?.length&&(this.updateCount++,this.largestUpdateSize=Math.max(this.largestUpdateSize,e.deltas.length),e.deltas.forEach((e=>{const t=this.pathExecutionCounts.get(e.path)||0;this.pathExecutionCounts.set(e.path,t+1)})),this.mostActiveListenerPaths=Array.from(this.pathExecutionCounts.entries()).sort((([,e],[,t])=>t-e)).slice(0,5).map((([e])=>e)))}})),e.subscribe("middleware:start",(()=>{this.middlewareExecutions++})),e.subscribe("transaction:start",(()=>{this.transactionCount++})),e.subscribe("action:start",(()=>{this.totalActionsDispatched++})),e.subscribe("action:complete",(e=>{this.totalActionsSucceeded++,e.duration&&(this.actionTimes.push(e.duration),this.actionTimes.length>100&&this.actionTimes.shift(),this.averageActionDuration=this.actionTimes.reduce(((e,t)=>e+t),0)/this.actionTimes.length)})),e.subscribe("action:error",(()=>{this.totalActionsFailed++}))}reset(){this.updateCount=0,this.listenerExecutions=0,this.averageUpdateTime=0,this.largestUpdateSize=0,this.mostActiveListenerPaths=[],this.totalUpdates=0,this.blockedUpdates=0,this.averageUpdateDuration=0,this.middlewareExecutions=0,this.transactionCount=0,this.totalEventsFired=0,this.totalActionsDispatched=0,this.totalActionsSucceeded=0,this.totalActionsFailed=0,this.averageActionDuration=0,this.updateTimes=[],this.actionTimes=[],this.pathExecutionCounts.clear()}getDetailedMetrics(){return{pathExecutionCounts:new Map(this.pathExecutionCounts),recentUpdateTimes:[...this.updateTimes],successRate:this.totalUpdates>0?(this.totalUpdates-this.blockedUpdates)/this.totalUpdates:1,averagePathsPerUpdate:this.updateCount>0?Array.from(this.pathExecutionCounts.values()).reduce(((e,t)=>e+t),0)/this.updateCount:0}}dispose(){this.reset()}},k=class extends Error{constructor(){super("Action Cancelled by Debounce"),this.name="ActionCancelledError"}},T=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name="UnknownActionError"}},M=class{constructor(e,t){this.eventBus=e,this.set=t}registrations=new Map;register(t){const s={action:{name:t.name,id:e.v4(),action:t.fn,debounce:t.debounce?{...t.debounce,condition:t.debounce.condition??(()=>!0)}:void 0},debouncer:t.debounce&&t.debounce.delay>0?new o({delay:t.debounce.delay}):void 0,previousArgs:void 0};return this.registrations.set(t.name,s),()=>{const e=this.registrations.get(t.name);e&&(e.debouncer?.cancel(),this.registrations.delete(t.name))}}async dispatch(e,...t){const s=this.registrations.get(e);if(!s)throw new T({action:e});const{action:i,debouncer:r}=s,{id:a,action:n,debounce:o}=i;if(!r||!o)return this.executeAction(e,a,n,t);const c=o.condition(s.previousArgs,t);if(s.previousArgs=t,!c)return this.executeAction(e,a,n,t);const d=await r.do((()=>this.executeAction(e,a,n,t)));if("cancelled"===d.status)throw new k;if("error"===d.status&&d.error)throw d.error;return d.value}async executeAction(e,t,s,i){const r=performance.now();this.emit(this.eventBus,{name:"action:start",payload:{actionId:t,name:e,params:i||[],timestamp:r}});try{const a=await this.set((e=>s(e,...i)),{actionId:t}),n=performance.now();return this.emit(this.eventBus,{name:"action:complete",payload:{actionId:t,name:e,params:i,startTime:r,endTime:n,duration:n-r,result:a}}),a}catch(s){const a=performance.now();throw this.emit(this.eventBus,{name:"action:error",payload:{actionId:t,name:e,params:i,startTime:r,endTime:a,duration:a-r,error:s}}),s}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}};exports.ActionCancelledError=k,exports.ActionManager=M,exports.DELETE_SYMBOL=d,exports.ReactiveDataStore=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new a({yieldMode:"macrotask",capacity:1e3});readyLatch=new n;updateBus=c();eventBus;executionState;instanceID=e.v4();merge;diff;constructor(e,t,s=d,i,r={errorHandler:()=>{}}){this.eventBus=c(r),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=h({deleteMarker:s}),this.diff=y({deleteMarker:s}),this.coreState=new b(e,this.updateBus,this.diff),this.middlewareEngine=new S(this.eventBus,this.executionState,this.merge),this.persistenceHandler=new x(this.eventBus,this.coreState,this.instanceID,{maxRetries:i?.persistenceMaxRetries,retryDelay:i?.persistenceRetryDelay}),this.transactionManager=new E(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new _(this.eventBus),this.actions=new M(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(t),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new m(this.get.bind(this),this.eventBus)}isReady(){return this.readyLatch.isOpen()}async ready(e){return this.readyLatch.wait(e)}state(){return this.executionState.executing=this.updateSerializer.running(),this.executionState}get(e){return this.coreState.get(e??!1)}select(e){return this.selectorManager.createReactiveSelector(e)}register(e){return this.actions.register(e)}async dispatch(e,...t){return this.actions.dispatch(e,...t)}async set(e,t={}){const s=await this.updateSerializer.do((()=>this._performUpdate(e,t)));if(s.error)throw s.error;return s.value}async _performUpdate(e,t){const s=performance.now();this.emit(this.eventBus,{name:"update:start",payload:{timestamp:s,actionId:t.actionId}});try{if(t.force){const i=this.get(!1),r="function"==typeof e?e(i):e;this.coreState.applyChanges(r,!0);const a=performance.now();return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:[],duration:a-s,timestamp:Date.now(),actionId:t.actionId,newState:r}}),r}let i;const r=this.get(!1);if("function"==typeof e){const t=e(r);i=t instanceof Promise?await t:t}else i=e;const a=await this.middlewareEngine.executeBlocking(r,i);if(a.blocked)throw a.error||new Error("Update blocked by middleware");const n=this.merge(r,i),o=await this.middlewareEngine.executeTransform(n,i),c=this.merge(n,o),d=this.coreState.applyChanges(c,!1,!1,[i,o]),l=performance.now(),h=this.get(!1);return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:d,duration:l-s,timestamp:Date.now(),actionId:t.actionId,newState:h}}),h}catch(e){throw this.emit(this.eventBus,{name:"update:complete",payload:{blocked:!0,error:e,timestamp:Date.now(),actionId:t.actionId,newState:this.get(!1)}}),e}finally{this.executionState.executing=!1,this.executionState.changes=null,this.executionState.runningMiddleware=null,this.executionState.pendingChanges=[]}}setupReadyLatch(){this.readyLatch.open(),this.persistenceHandler.isReady()?this.readyLatch.open():queueMicrotask((()=>{this.readyLatch.isOpen()||this.readyLatch.open()}))}setupPersistenceListener(){this.updateBus.subscribe("update",(e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))}))}watch(e,t){const s=Array.isArray(e)?e:[e],i=""===e||0===s.length;return this.updateBus.subscribe("update",(e=>{(i||s.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)}))}debouncedSetter(e){const t=new o({delay:e.delay,leading:e.leading});return(e,s={})=>{t.fire((()=>this.set(e,s)))}}subscribe(e,t){return this.watch(e,t)}id(){return this.instanceID}async transaction(e){return this.transactionManager.execute(e)}use(e){const t=(e.block?this.middlewareEngine.addBlockingMiddleware:this.middlewareEngine.addMiddleware).bind(this.middlewareEngine)(e.action,e.name);return()=>this.middlewareEngine.removeMiddleware(t)}metrics(){return this.metricsCollector.getMetrics()}on(e,t){return this.eventBus.subscribe(e,t)}onStoreEvent(e,t){return this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flushPersistence(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){this.updateSerializer.close(),this.persistenceHandler.dispose(),this.metricsCollector.dispose?.(),this.selectorManager.dispose?.()}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},exports.StoreObserver=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;constructor(e,t={}){this.store=e,this.maxEvents=t.maxEvents??500,this.maxStateHistory=t.maxStateHistory??20,this.enableConsoleLogging=t.enableConsoleLogging??!1,this.isSilent=t.silent??!1,this.logEvents={updates:t.logEvents?.updates??!0,middleware:t.logEvents?.middleware??!0,transactions:t.logEvents?.transactions??!0,actions:t.logEvents?.actions??!0,selectors:t.logEvents?.selectors??!0},this.performanceThresholds={updateTime:t.performanceThresholds?.updateTime??50,middlewareTime:t.performanceThresholds?.middlewareTime??20},this.recordStateSnapshot([]),this.setupEventListeners()}_consoleLog(e,...t){this.isSilent||"function"==typeof console[e]&&console[e](...t)}setupEventListeners(){const e=["update:start","update:complete","middleware:start","middleware:complete","middleware:error","middleware:blocked","transaction:start","transaction:complete","transaction:error","middleware:executed","action:start","action:complete","action:error","selector:accessed"];for(const t of e){const e=t.startsWith("update")&&this.logEvents.updates||t.startsWith("middleware")&&this.logEvents.middleware||t.startsWith("transaction")&&this.logEvents.transactions||t.startsWith("action")&&this.logEvents.actions||t.startsWith("selector")&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(t,(s=>{"update:complete"!==t||s.blocked||this.isTimeTraveling||this.recordStateSnapshot(s.deltas),"middleware:executed"===t?this.middlewareExecutions.push(s):"transaction:start"===t?this.activeTransactionCount++:"transaction:complete"!==t&&"transaction:error"!==t||(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),s.batchId&&(t.endsWith("start")?this.activeBatches.add(s.batchId):(t.endsWith("complete")||t.endsWith("error"))&&this.activeBatches.delete(s.batchId)),this.recordEvent(t,s),this.enableConsoleLogging&&e&&this._log(t,s),this._checkPerformance(t,s)})))}}recordStateSnapshot(e){const t={state:this.store.get(!0),timestamp:Date.now(),deltas:e};this.stateHistory.unshift(t),this.stateHistory.length>this.maxStateHistory&&this.stateHistory.pop()}recordEvent(e,t){const s={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(s),this.eventHistory.length>this.maxEvents&&this.eventHistory.pop()}getEventHistory(){return structuredClone(this.eventHistory)}getStateHistory(){return structuredClone(this.stateHistory)}getMiddlewareExecutions(){return this.middlewareExecutions}getTransactionStatus(){return{activeTransactions:this.activeTransactionCount,activeBatches:Array.from(this.activeBatches)}}createLoggingMiddleware(e={}){const{logLevel:t="debug",logUpdates:s=!0}=e;return(e,i)=>{if(s){(console[t]||console.log)("State Update:",i)}return i}}createValidationMiddleware(e){return(t,s)=>{const i=e(t,s);return"boolean"==typeof i?i:(!i.valid&&i.reason&&this._consoleLog("warn","Validation failed:",i.reason),i.valid)}}getRecentChanges(e=5){const t=[],s=Math.min(e,this.stateHistory.length);for(let e=0;e<s;e++){const s=this.stateHistory[e];if(!s.deltas||0===s.deltas.length)continue;const i={},r={},a=(e,t,s)=>{t.reduce(((e,i,r)=>(r===t.length-1?e[i]=s:e[i]=e[i]??{},e[i])),e)};for(const e of s.deltas){const t=e.path.split(".");a(i,t,e.oldValue),a(r,t,e.newValue)}t.push({timestamp:s.timestamp,changedPaths:s.deltas.map((e=>e.path)),from:i,to:r})}return t}clearHistory(){this.eventHistory=[],this.stateHistory.length>0&&(this.stateHistory=[this.stateHistory[0]])}getHistoryForAction(e){return this.eventHistory.filter((t=>t.data?.actionId===e))}async replay(e){const t=this.eventHistory.filter((e=>"update:start"===e.type))[e];t?.data.update?(this._consoleLog("log",`Replaying event at index ${e}:`,t),await this.store.set(t.data.update,{force:!0})):this._consoleLog("warn",`No replayable event found at index ${e}.`)}createTimeTravel(){let e=0,t=[];const s=this.store.on("update:complete",(s=>{this.isTimeTraveling||s.blocked||(t=[],e=0)}));this.unsubscribers.push(s);const i=()=>this.stateHistory.length,r=()=>e<i()-1,a=()=>t.length>0;return{canUndo:r,canRedo:a,undo:async()=>{if(!r())return;t.unshift(this.stateHistory[e]),e++;const s=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...s},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;const s=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...s.state},{force:!0}),this.isTimeTraveling=!1},length:i,clear:()=>{t=[],e=0}}}async saveSession(e){const t=this.store.id(),s={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,s))}async loadSession(e){const t=await Promise.resolve(e.get());return!!t&&(this.eventHistory=t.eventHistory||[],this.stateHistory=t.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),!0)}exportSession(){const e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),s=URL.createObjectURL(t),i=document.createElement("a");i.href=s,i.download=`store-observer-session-${(new Date).toISOString()}.json`,i.click(),URL.revokeObjectURL(s)}importSession(e){return new Promise(((t,s)=>{const i=new FileReader;i.onload=async e=>{try{const s=JSON.parse(e.target?.result);this.eventHistory=s.eventHistory||[],this.stateHistory=s.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){s(e)}},i.onerror=e=>s(e),i.readAsText(e)}))}disconnect(){this.unsubscribers.forEach((e=>e())),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){const s=new Date(t.timestamp||Date.now()).toISOString().split("T")[1].replace("Z","");if("update:start"===e)this._consoleLog("group",`%c⚡ Store Update Started [${s}]`,"color: #4a6da7");else if("update:complete"===e){if(t.blocked)this._consoleLog("warn",`%c✋ Update Blocked [${s}]`,"color: #bf8c0a",t.error);else{const e=t.deltas||[];e.length>0&&(this._consoleLog("log",`%c✅ Update Complete [${s}] - ${e.length} paths changed in ${t.duration?.toFixed(2)}ms`,"color: #2a9d8f"),this._consoleLog("table",e.map((e=>({path:e.path,oldValue:e.oldValue,newValue:e.newValue})))))}this._consoleLog("groupEnd")}else"middleware:start"===e?this._consoleLog("debug",`%c◀ Middleware "${t.name}" started [${s}] (${t.type})`,"color: #8c8c8c"):"middleware:complete"===e?this._consoleLog("debug",`%c▶ Middleware "${t.name}" completed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #7c9c7c"):"middleware:error"===e?this._consoleLog("error",`%c❌ Middleware "${t.name}" error [${s}]:`,"color: #e63946",t.error):"middleware:blocked"===e?this._consoleLog("warn",`%c🛑 Middleware "${t.name}" blocked update [${s}]`,"color: #e76f51"):"transaction:start"===e?this._consoleLog("group",`%c📦 Transaction Started [${s}]`,"color: #6d597a"):"transaction:complete"===e?(this._consoleLog("log",`%c📦 Transaction Complete [${s}]`,"color: #355070"),this._consoleLog("groupEnd")):"transaction:error"===e?(this._consoleLog("error",`%c📦 Transaction Error [${s}]:`,"color: #e56b6f",t.error),this._consoleLog("groupEnd")):"action:start"===e?this._consoleLog("group",`%c🚀 Action "${t.name}" Started [${s}]`,"color: #9b59b6",{params:t.params}):"action:complete"===e?(this._consoleLog("log",`%c✔️ Action "${t.name}" Complete [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #2ecc71"),this._consoleLog("groupEnd")):"action:error"===e?(this._consoleLog("error",`%c🔥 Action "${t.name}" Error [${s}]:`,"color: #e74c3c",t.error),this._consoleLog("groupEnd")):"selector:accessed"===e&&this._consoleLog("debug",`%c👀 Selector Accessed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #f1c40f",{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&("update:complete"===e&&!t.blocked&&t.duration>this.performanceThresholds.updateTime&&this._consoleLog("warn",`%c⚠️ Slow update detected [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{deltas:t.deltas,threshold:this.performanceThresholds.updateTime}),"middleware:complete"===e&&t.duration>this.performanceThresholds.middlewareTime&&this._consoleLog("warn",`%c⚠️ Slow middleware "${t.name}" [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{threshold:this.performanceThresholds.middlewareTime}))}},exports.UnknownActionError=T,exports.createDerivePaths=f,exports.createDiff=y,exports.createMerge=h,exports.derivePaths=v,exports.diff=w,exports.merge=u,exports.shallowClone=l;
|
|
1
|
+
"use strict";var e=require("uuid"),t=class{_delay;_leading;_timer;_pendingFn;_pendingResolvers=[];_leadingFired=!1;constructor(e){this._delay=e?.delay??300,this._leading=e?.leading??!1}do(e){return new Promise((t=>{this._enqueue(e,t)}))}fire(e){this._enqueue(e,void 0)}_enqueue(e,t){if(this._pendingFn=e,t&&this._pendingResolvers.push(t),this._leading&&!this._leadingFired)return this._leadingFired=!0,this._fire(),clearTimeout(this._timer),void(this._timer=setTimeout((()=>{this._leadingFired=!1,void 0!==this._pendingFn&&this._fire()}),this._delay));clearTimeout(this._timer),this._timer=setTimeout((()=>{this._leadingFired=!1,this._fire()}),this._delay)}cancel(){clearTimeout(this._timer),this._timer=void 0,this._pendingFn=void 0,this._leadingFired=!1;const e=this._pendingResolvers.splice(0);for(const t of e)t({status:"cancelled"})}async flush(){return this._pendingFn?(clearTimeout(this._timer),this._timer=void 0,this._leadingFired=!1,this._fire()):null}pending(){return void 0!==this._pendingFn}async _fire(){const e=this._pendingFn,t=this._pendingResolvers.splice(0);let s;this._pendingFn=void 0;try{s={status:"ok",value:await e()}}catch(e){s={status:"error",error:e}}for(const e of t)e(s);return s}},s=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},i=class extends s{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},r=class extends s{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},a=class{_open=!1;_resolve;_promise;constructor(){this._promise=new Promise((e=>{this._resolve=e}))}open(){this._open||(this._open=!0,this._resolve())}async wait(e){if(this._open)return;if(null==e)return this._promise;let t;await Promise.race([this._promise.then((()=>clearTimeout(t))),new Promise(((s,r)=>{t=setTimeout((()=>r(new i("Latch timed out"))),e)}))])}isOpen(){return this._open}},n=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let r;await Promise.race([s.then((()=>clearTimeout(r))),new Promise(((s,a)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),a(new i("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},o=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new n({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new r};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,i=null;try{if(this._done)throw new r;i=await e(),this._lastValue=i,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:i,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function c(e){const s={},{deferred:i,batchSize:r,batchDelay:a,errorHandler:n,broadcast:o,channel:c}={deferred:null!=s.batch?.size,batchSize:s.batch?.size,batchDelay:s.batch?.delay||16,errorHandler:s.errorHandler||(e=>console.error("EventBus Error:",e)),broadcast:null!=s.broadcast?.channel&&s.broadcast.channel.length>0,channel:null!=s.broadcast?.channel&&s.broadcast.channel.length>0?s.broadcast?.channel:"event-bus-channel"},d=new Map;let l=[],h=0,u=0;const p=new Map,m=()=>{if(!o)return null;if("undefined"==typeof BroadcastChannel)return console.warn("EventBus: BroadcastChannel is not supported in this environment. Cross-tab notifications are disabled."),null;const e=new BroadcastChannel(c);return e.onmessage=e=>{const{name:t,payload:s}=e.data;f(t,s)},e};let g=m();const y=(e,t)=>{h++,u+=t,p.set(e,(p.get(e)??0)+1)},f=(e,t)=>{const s=d.get(e);if(s&&0!==s.size)for(const i of Array.from(s))try{i(t)}catch(s){const i=s instanceof Error?s:Object.assign(new Error(String(s)),{cause:s}),r=Object.assign(i,{eventName:e,payload:t});n(r)}},w=()=>{const e=l;l=[];for(const{name:t,payload:s}of e){const e=performance.now();f(t,s),y(t,performance.now()-e)}},v=new t({delay:a});return{subscribe:(e,t)=>{d.has(e)||d.set(e,new Set);const s=d.get(e);return s.add(t),()=>{s.delete(t),0===s.size&&d.delete(e)}},once:(e,t)=>{let s;const i=e=>{s(),t(e)};return s=(()=>{d.has(e)||d.set(e,new Set);const t=d.get(e);return t.add(i),()=>{t.delete(i),0===t.size&&d.delete(e)}})(),s},emit:({name:e,payload:t})=>{if(i)return l.push({name:e,payload:t}),l.length>=r?(v.cancel(),void w()):(v.fire((()=>w())),void g?.postMessage({name:e,payload:t}));const s=performance.now();f(e,t),y(e,performance.now()-s),g?.postMessage({name:e,payload:t})},metrics:()=>({totalEvents:h,activeSubscriptions:Array.from(d.values()).reduce(((e,t)=>e+t.size),0),eventCounts:p,averageEmitDuration:h>0?u/h:0}),clear:()=>{d.clear(),l=[],v.cancel(),h=0,u=0,p.clear(),g?.close(),g=m()}}}var d=Symbol.for("delete"),l=e=>Array.isArray(e)?[...e]:{...e};function h(e){const t=e?.deleteMarker||d;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const i={};for(const[r,a]of Object.entries(e))if(a!==t)if("object"==typeof a&&null!==a){const e=s(a);void 0!==e&&(i[r]=e)}else i[r]=a;return i}return e===t?void 0:e}return function(e,i){if("object"!=typeof e||null===e)return"object"==typeof i&&null!==i?s(i):i===t?{}:i;if("object"!=typeof i||null===i)return e;const r=l(e),a=[{target:r,source:i}];for(;a.length>0;){const{target:e,source:s}=a.pop();for(const i of Object.keys(s)){const r=s[i];if(r!==t)if(Array.isArray(r))e[i]=r;else if("object"==typeof r&&null!==r){const t=i in e&&"object"==typeof e[i]&&null!==e[i]?e[i]:{};e[i]=l(t),a.push({target:e[i],source:r})}else e[i]=r;else delete e[i]}}return r}}var u=h(),p=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"],m=class{reactiveSelectors=new Map;pathBasedCache=new Map;dependencyMap=new Map;getState;eventBus;unsubscribeFromStore;constructor(e,t){this.getState=e,this.eventBus=t,this.unsubscribeFromStore=this.eventBus.subscribe("update:complete",this.handleStoreUpdate)}handleStoreUpdate=e=>{const t=new Set;for(const s of e.deltas){const e=s.path;for(const[s,i]of this.dependencyMap)if(s===e||s.startsWith(e+".")||e.startsWith(s+"."))for(const e of i)t.add(e)}for(const e of t){const 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(const s of e.subscribers)s(t);this.eventBus.emit({name:"selector:changed",payload:{selectorId:e.id,newResult:t,timestamp:performance.now()}})}}createReactiveSelector(e){const t=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const a=new Proxy((()=>{}),{get:(i,a)=>{if("symbol"==typeof a||"then"===a)return;if("valueOf"===a||"toString"===a)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(p.includes(a))throw new Error(`Array method .${a}() is not allowed in selectors.`);const n=e?`${e}${t}${a}`:a;return e&&s.delete(e),s.add(n),r(n)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return i.set(e,a),a};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e),s=[...t].sort().join("|"),i=this.pathBasedCache.get(s);if(i)return void 0!==i.cleanupTimer&&(clearTimeout(i.cleanupTimer),i.cleanupTimer=void 0),i.reactiveSelectorInstance;const r=`sel-${Math.random().toString(36).slice(2,9)}`,a={id:r,selector:e,lastResult:e(this.getState()),accessedPaths:t,subscribers:new Set,count:0,cleanupTimer:void 0,pathCacheKey:s,reactiveSelectorInstance:null};for(const e of t)this.dependencyMap.has(e)||this.dependencyMap.set(e,new Set),this.dependencyMap.get(e).add(r);const n={id:r,get:()=>{try{return a.selector(this.getState())}catch{return}},subscribe:e=>(void 0!==a.cleanupTimer&&(clearTimeout(a.cleanupTimer),a.cleanupTimer=void 0),a.subscribers.add(e),a.count++,()=>{a.subscribers.delete(e),a.count--,0===a.count&&(a.cleanupTimer=setTimeout((()=>{0===a.count&&this.evictEntry(a)}),0))})};return a.reactiveSelectorInstance=n,this.reactiveSelectors.set(r,a),this.pathBasedCache.set(s,a),this.eventBus.emit({name:"selector:accessed",payload:{selectorId:r,accessedPaths:t,duration:0,timestamp:performance.now()}}),n}evictEntry(e){for(const t of e.accessedPaths){const s=this.dependencyMap.get(t);s&&(s.delete(e.id),0===s.size&&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 g(e,t){if(e===t)return!0;if(e&&t&&"object"==typeof e&&"object"==typeof t){if(e.constructor!==t.constructor)return!1;let s,i;if(Array.isArray(e)){if(s=e.length,s!=t.length)return!1;for(i=s;i-- >0;)if(!g(e[i],t[i]))return!1;return!0}const[r,a]=[Object.keys(e),Object.keys(t)];if(s=r.length,s!==a.length)return!1;for(i=s;i-- >0;){const s=r[i];if(!Object.prototype.hasOwnProperty.call(t,s)||!g(e[s],t[s]))return!1}return!0}return e!=e&&t!=t}function y(e){const t=e?.deleteMarker||d;return function(e,s){const i=[],r=[{pathStr:"",orig:e||{},part:s||{}}];for(;r.length>0;){const{pathStr:e,orig:s,part:a}=r.pop();if(null!=a&&!g(s,a))if("object"!=typeof a||Array.isArray(a))e&&i.push({path:e,oldValue:s,newValue:a});else for(const n of Object.keys(a)){const o=e?e+"."+n:n,c=a[n],d=s&&"object"==typeof s?s[n]:void 0;c!==t?"object"==typeof c&&null!==c?r.push({pathStr:o,orig:d,part:c}):g(d,c)||i.push({path:o,oldValue:d,newValue:c}):void 0!==d&&i.push({path:o,oldValue:d,newValue:void 0})}}return i}}function f(e){const t=e?.deleteMarker||d;return function(e){const s=new Set,i=[{obj:e,currentPath:""}];for(;i.length>0;){const{obj:e,currentPath:r}=i.pop();if(null!=e&&"object"==typeof e&&!Array.isArray(e))for(const a of Object.keys(e)){const n=r?`${r}.${a}`:a;s.add(n);const o=e[a];"object"!=typeof o||null===o||Array.isArray(o)||o===t||i.push({obj:o,currentPath:n})}}return Array.from(s)}}var w=y(),v=f(),b=class{constructor(e,t,s){this.updateBus=t,this.diff=s,this.cache=structuredClone(e)}cache;get(e){return e?structuredClone(this.cache):this.cache}applyChanges(e,t=!1,s=!1,i=[]){if(t)return this.cache=s?structuredClone(e):e,this.notifyListeners([]),[];0===i.length&&(i=[e]);const r=this.get(!1),a=new Map;for(let e=0;e<i.length;e++){const t=i[e],s=this.diff(r,t);for(let e=0;e<s.length;e++){const t=s[e];a.set(t.path,t)}}const n=a.size?[...a.values()]:[];if(n.length>0){this.cache=s?structuredClone(e):e;const t=new Set;for(let e=0;e<n.length;e++){let s=n[e].path;for(;s&&!t.has(s);){t.add(s);const e=s.lastIndexOf(".");if(e<0)break;s=s.slice(0,e)}}this.notifyListeners(t)}return n}notifyListeners(e){for(const t of e)this.updateBus.emit({name:"update",payload:t})}},S=class{constructor(e,t,s){this.eventBus=e,this.executionState=t,this.merge=s}middleware=[];blockingMiddleware=[];async executeBlocking(e,t){for(const{fn:s,name:i,id:r}of this.blockingMiddleware){const a={id:r,name:i,startTime:performance.now()};this.executionState.runningMiddleware={id:r,name:i,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:r,name:i,type:"blocking"});try{const n=await Promise.resolve(s(e,t));if(a.endTime=performance.now(),a.duration=a.endTime-a.startTime,!1===n)return a.blocked=!0,this.emitMiddlewareLifecycle("blocked",{id:r,name:i,duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0};this.emitMiddlewareLifecycle("complete",{id:r,name:i,type:"blocking",duration:a.duration}),this.emit(this.eventBus,{name:"middleware:executed",payload:{...a,blocked:!1}})}catch(e){return a.endTime=performance.now(),a.duration=a.endTime-a.startTime,a.error=e instanceof Error?e:new Error(String(e)),a.blocked=!0,this.emitMiddlewareError(r,i,a.error,a.duration),this.emit(this.eventBus,{name:"middleware:executed",payload:a}),{blocked:!0,error:a.error}}finally{this.executionState.runningMiddleware=null}}return{blocked:!1}}async executeTransform(e,t){let s=e,i=t;for(const{fn:e,name:r,id:a}of this.middleware){const n={id:a,name:r,startTime:performance.now()};this.executionState.runningMiddleware={id:a,name:r,startTime:performance.now()},this.emitMiddlewareLifecycle("start",{id:a,name:r,type:"transform"});try{const o=await Promise.resolve(e(s,t));n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.blocked=!1,o&&"object"==typeof o&&(s=this.merge(s,o),i=this.merge(i,o)),this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareLifecycle("complete",{id:a,name:r,type:"transform",duration:n.duration})}catch(e){n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.error=e instanceof Error?e:new Error(String(e)),n.blocked=!1,this.emit(this.eventBus,{name:"middleware:executed",payload:n}),this.emitMiddlewareError(a,r,n.error,n.duration),console.error(`Middleware ${r} error:`,e)}finally{this.executionState.runningMiddleware=null}}return i}addMiddleware(e,t="unnamed-middleware"){const s=this.generateId();return this.middleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}addBlockingMiddleware(e,t="unnamed-blocking-middleware"){const s=this.generateId();return this.blockingMiddleware.push({fn:e,name:t,id:s}),this.updateExecutionState(),s}removeMiddleware(e){const t=this.middleware.length+this.blockingMiddleware.length;return this.middleware=this.middleware.filter((t=>t.id!==e)),this.blockingMiddleware=this.blockingMiddleware.filter((t=>t.id!==e)),this.updateExecutionState(),this.middleware.length+this.blockingMiddleware.length<t}updateExecutionState(){this.executionState.middlewares=[...this.middleware.map((e=>e.name)),...this.blockingMiddleware.map((e=>e.name))]}emitMiddlewareLifecycle(e,t){this.emit(this.eventBus,{name:`middleware:${e}`,payload:{...t,timestamp:Date.now()}})}emitMiddlewareError(e,t,s,i){this.emit(this.eventBus,{name:"middleware:error",payload:{id:e,name:t,error:s,duration:i,timestamp:Date.now()}})}generateId(){return crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).substring(2,15)}`}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},x=class{constructor(e,t,s,i){this.eventBus=e,this.coreState=t,this.instanceID=s,this.maxRetries=i?.maxRetries??3,this.retryDelay=i?.retryDelay??1e3}persistence;instanceID;persistenceReady=!1;backgroundQueue=[];isProcessingQueue=!1;maxRetries=3;retryDelay=1e3;queueProcessor;pendingRetries=new Set;async initialize(e){e?await this.setPersistence(e):this.setPersistenceReady()}isReady(){return this.persistenceReady}handleStateChange(e,t){if(!this.persistence||0===e.length)return;const s={id:`${Date.now()}-${Math.random().toString(36).slice(2,11)}`,state:structuredClone(t),changedPaths:[...e],timestamp:Date.now(),retries:0};this.backgroundQueue.push(s),this.scheduleQueueProcessing(),this.emit(this.eventBus,{name:"persistence:queued",payload:{taskId:s.id,changedPaths:e,queueSize:this.backgroundQueue.length,timestamp:s.timestamp}})}getQueueStatus(){return{queueSize:this.backgroundQueue.length,isProcessing:this.isProcessingQueue,pendingRetries:this.pendingRetries.size,oldestTask:this.backgroundQueue[0]?.timestamp}}async flush(){this.isProcessingQueue&&await new Promise((e=>{const t=()=>{this.isProcessingQueue?setTimeout(t,10):e()};t()})),await this.processQueue()}discardQueue(){const e=this.backgroundQueue.length+this.pendingRetries.size;this.backgroundQueue=[],this.pendingRetries.clear(),this.queueProcessor&&(clearTimeout(this.queueProcessor),this.queueProcessor=void 0),this.emit(this.eventBus,{name:"persistence:queue_cleared",payload:{clearedTasks:e,timestamp:Date.now()}})}scheduleQueueProcessing(){this.queueProcessor||this.isProcessingQueue||(this.queueProcessor=setTimeout((()=>{this.processQueue().catch((e=>{console.error("Queue processing failed:",e)}))}),10))}async processQueue(){if(!this.isProcessingQueue&&0!==this.backgroundQueue.length){this.isProcessingQueue=!0,this.queueProcessor=void 0;try{for(;this.backgroundQueue.length>0;){const e=this.backgroundQueue.shift();await this.processTask(e)}}finally{this.isProcessingQueue=!1}}}async processTask(e){try{await this.persistence.set(this.instanceID,e.state)?this.emit(this.eventBus,{name:"persistence:success",payload:{taskId:e.id,changedPaths:e.changedPaths,duration:Date.now()-e.timestamp,timestamp:Date.now()}}):await this.handleTaskFailure(e,new Error("Persistence returned false"))}catch(t){await this.handleTaskFailure(e,t)}}async handleTaskFailure(e,t){if(e.retries++,e.retries<=this.maxRetries){const s=this.retryDelay*Math.pow(2,e.retries-1);this.emit(this.eventBus,{name:"persistence:retry",payload:{taskId:e.id,attempt:e.retries,maxRetries:this.maxRetries,nextRetryIn:s,error:t,timestamp:Date.now()}}),this.pendingRetries.add(e.id),setTimeout((()=>{this.pendingRetries.has(e.id)&&(this.pendingRetries.delete(e.id),this.backgroundQueue.unshift(e),this.scheduleQueueProcessing())}),s)}else this.emit(this.eventBus,{name:"persistence:failed",payload:{taskId:e.id,changedPaths:e.changedPaths,attempts:e.retries,error:t,timestamp:Date.now()}})}setPersistenceReady(){this.persistenceReady=!0,this.emit(this.eventBus,{name:"persistence:ready",payload:{timestamp:Date.now()}})}async setPersistence(e){this.persistence=e;try{const e=await this.persistence.get();e&&this.coreState.applyChanges(e)}catch(e){console.error("Failed to initialize persistence:",e),this.emit(this.eventBus,{name:"persistence:init_error",payload:{error:e,timestamp:Date.now()}})}finally{this.setPersistenceReady()}this.persistence.subscribe(this.instanceID,(async e=>{const t=this.coreState.applyChanges(e);t.length>0&&this.emit(this.eventBus,{name:"update:complete",payload:{changedPaths:t,source:"external",timestamp:Date.now()}})}))}dispose(){this.discardQueue(),this.isProcessingQueue=!1,this.persistenceReady=!1}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},T=class{constructor(e,t,s){this.eventBus=e,this.coreState=t,this.executionState=s}async execute(e){const t=this.coreState.get(!0);this.executionState.transactionActive=!0,this.emit(this.eventBus,{name:"transaction:start",payload:{timestamp:Date.now()}});try{const t=await Promise.resolve(e());return this.emit(this.eventBus,{name:"transaction:complete",payload:{timestamp:Date.now()}}),this.executionState.transactionActive=!1,t}catch(e){throw this.coreState.applyChanges(t,!0,!1),this.emit(this.eventBus,{name:"transaction:error",payload:{error:e instanceof Error?e:new Error(String(e)),timestamp:Date.now()}}),this.executionState.transactionActive=!1,e}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},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){const t=e.emit;e.emit=s=>(this.totalEventsFired++,t.call(e,s)),e.subscribe("update:complete",(e=>{if(this.totalUpdates++,e.blocked)this.blockedUpdates++;else{if(e.duration){this.updateTimes.push(e.duration),this.updateTimes.length>100&&this.updateTimes.shift();const t=this.updateTimes.reduce(((e,t)=>e+t),0)/this.updateTimes.length;this.averageUpdateTime=t,this.averageUpdateDuration=t}e.deltas?.length&&(this.updateCount++,this.largestUpdateSize=Math.max(this.largestUpdateSize,e.deltas.length),e.deltas.forEach((e=>{const t=this.pathExecutionCounts.get(e.path)||0;this.pathExecutionCounts.set(e.path,t+1)})),this.mostActiveListenerPaths=Array.from(this.pathExecutionCounts.entries()).sort((([,e],[,t])=>t-e)).slice(0,5).map((([e])=>e)))}})),e.subscribe("middleware:start",(()=>{this.middlewareExecutions++})),e.subscribe("transaction:start",(()=>{this.transactionCount++})),e.subscribe("action:start",(()=>{this.totalActionsDispatched++})),e.subscribe("action:complete",(e=>{this.totalActionsSucceeded++,e.duration&&(this.actionTimes.push(e.duration),this.actionTimes.length>100&&this.actionTimes.shift(),this.averageActionDuration=this.actionTimes.reduce(((e,t)=>e+t),0)/this.actionTimes.length)})),e.subscribe("action:error",(()=>{this.totalActionsFailed++}))}reset(){this.updateCount=0,this.listenerExecutions=0,this.averageUpdateTime=0,this.largestUpdateSize=0,this.mostActiveListenerPaths=[],this.totalUpdates=0,this.blockedUpdates=0,this.averageUpdateDuration=0,this.middlewareExecutions=0,this.transactionCount=0,this.totalEventsFired=0,this.totalActionsDispatched=0,this.totalActionsSucceeded=0,this.totalActionsFailed=0,this.averageActionDuration=0,this.updateTimes=[],this.actionTimes=[],this.pathExecutionCounts.clear()}getDetailedMetrics(){return{pathExecutionCounts:new Map(this.pathExecutionCounts),recentUpdateTimes:[...this.updateTimes],successRate:this.totalUpdates>0?(this.totalUpdates-this.blockedUpdates)/this.totalUpdates:1,averagePathsPerUpdate:this.updateCount>0?Array.from(this.pathExecutionCounts.values()).reduce(((e,t)=>e+t),0)/this.updateCount:0}}dispose(){this.reset()}},_=class extends Error{constructor(){super("Action Cancelled by Debounce"),this.name="ActionCancelledError"}},k=class extends Error{constructor({action:e}){super(`Unknown action: "${e}"`),this.name="UnknownActionError"}},M=class{constructor(e,t){this.eventBus=e,this.set=t}registrations=new Map;register(s){const i={action:{name:s.name,id:e.v4(),action:s.fn,debounce:s.debounce?{...s.debounce,condition:s.debounce.condition??(()=>!0)}:void 0},debouncer:s.debounce&&s.debounce.delay>0?new t({delay:s.debounce.delay}):void 0,previousArgs:void 0};return this.registrations.set(s.name,i),()=>{const e=this.registrations.get(s.name);e&&(e.debouncer?.cancel(),this.registrations.delete(s.name))}}async dispatch(e,...t){const s=this.registrations.get(e);if(!s)throw new k({action:e});const{action:i,debouncer:r}=s,{id:a,action:n,debounce:o}=i;if(!r||!o)return this.executeAction(e,a,n,t);const c=o.condition(s.previousArgs,t);if(s.previousArgs=t,!c)return this.executeAction(e,a,n,t);const d=await r.do((()=>this.executeAction(e,a,n,t)));if("cancelled"===d.status)throw new _;if("error"===d.status&&d.error)throw d.error;return d.value}async executeAction(e,t,s,i){const r=performance.now();this.emit(this.eventBus,{name:"action:start",payload:{actionId:t,name:e,params:i||[],timestamp:r}});try{const a=await this.set((e=>s(e,...i)),{actionId:t}),n=performance.now();return this.emit(this.eventBus,{name:"action:complete",payload:{actionId:t,name:e,params:i,startTime:r,endTime:n,duration:n-r,result:a}}),a}catch(s){const a=performance.now();throw this.emit(this.eventBus,{name:"action:error",payload:{actionId:t,name:e,params:i,startTime:r,endTime:a,duration:a-r,error:s}}),s}}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}};exports.ActionCancelledError=_,exports.ActionManager=M,exports.DELETE_SYMBOL=d,exports.ReactiveDataStore=class{coreState;middlewareEngine;persistenceHandler;transactionManager;metricsCollector;selectorManager;actions;updateSerializer=new o({yieldMode:"macrotask",capacity:1e3});readyLatch=new a;updateBus=c();eventBus;executionState;instanceID=e.v4();merge;diff;constructor(e,t,s=d,i){this.eventBus=c(),this.executionState={executing:!1,changes:null,pendingChanges:[],middlewares:[],runningMiddleware:null,transactionActive:!1},this.merge=h({deleteMarker:s}),this.diff=y({deleteMarker:s}),this.coreState=new b(e,this.updateBus,this.diff),this.middlewareEngine=new S(this.eventBus,this.executionState,this.merge),this.persistenceHandler=new x(this.eventBus,this.coreState,this.instanceID,{maxRetries:i?.persistenceMaxRetries,retryDelay:i?.persistenceRetryDelay}),this.transactionManager=new T(this.eventBus,this.coreState,this.executionState),this.metricsCollector=new E(this.eventBus),this.actions=new M(this.eventBus,this.set.bind(this)),this.persistenceHandler.initialize(t),this.setupPersistenceListener(),this.setupReadyLatch(),this.selectorManager=new m(this.get.bind(this),this.eventBus)}isReady(){return this.readyLatch.isOpen()}async ready(e){return this.readyLatch.wait(e)}state(){return this.executionState.executing=this.updateSerializer.running(),this.executionState}get(e){return this.coreState.get(e??!1)}select(e){return this.selectorManager.createReactiveSelector(e)}register(e){return this.actions.register(e)}async dispatch(e,...t){return this.actions.dispatch(e,...t)}async set(e,t={}){const s=await this.updateSerializer.do((()=>this._performUpdate(e,t)));if(s.error)throw s.error;return s.value}async _performUpdate(e,t){const s=performance.now();this.emit(this.eventBus,{name:"update:start",payload:{timestamp:s,actionId:t.actionId}});try{if(t.force){const i=this.get(!1),r="function"==typeof e?e(i):e;this.coreState.applyChanges(r,!0);const a=performance.now();return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:[],duration:a-s,timestamp:Date.now(),actionId:t.actionId,newState:r}}),r}let i;const r=this.get(!1);if("function"==typeof e){const t=e(r);i=t instanceof Promise?await t:t}else i=e;const a=await this.middlewareEngine.executeBlocking(r,i);if(a.blocked)throw a.error||new Error("Update blocked by middleware");const n=this.merge(r,i),o=await this.middlewareEngine.executeTransform(n,i),c=this.merge(n,o),d=this.coreState.applyChanges(c,!1,!1,[i,o]),l=performance.now(),h=this.get(!1);return this.emit(this.eventBus,{name:"update:complete",payload:{deltas:d,duration:l-s,timestamp:Date.now(),actionId:t.actionId,newState:h}}),h}catch(e){throw this.emit(this.eventBus,{name:"update:complete",payload:{blocked:!0,error:e,timestamp:Date.now(),actionId:t.actionId,newState:this.get(!1)}}),e}finally{this.executionState.executing=!1,this.executionState.changes=null,this.executionState.runningMiddleware=null,this.executionState.pendingChanges=[]}}setupReadyLatch(){this.readyLatch.open(),this.persistenceHandler.isReady()?this.readyLatch.open():queueMicrotask((()=>{this.readyLatch.isOpen()||this.readyLatch.open()}))}setupPersistenceListener(){this.updateBus.subscribe("update",(e=>{e&&this.persistenceHandler.isReady()&&this.persistenceHandler.handleStateChange([e],this.get(!1))}))}watch(e,t){const s=Array.isArray(e)?e:[e],i=""===e||0===s.length;return this.updateBus.subscribe("update",(e=>{(i||s.includes(e))&&(t(this.get(!1)),this.metricsCollector.listenerExecutions++)}))}debouncedSetter(e){const s=new t({delay:e.delay,leading:e.leading});return(e,t={})=>{s.fire((()=>this.set(e,t)))}}subscribe(e,t){return this.watch(e,t)}id(){return this.instanceID}async transaction(e){return this.transactionManager.execute(e)}use(e){const t=(e.block?this.middlewareEngine.addBlockingMiddleware:this.middlewareEngine.addMiddleware).bind(this.middlewareEngine)(e.action,e.name);return()=>this.middlewareEngine.removeMiddleware(t)}metrics(){return this.metricsCollector.getMetrics()}on(e,t){return this.eventBus.subscribe(e,t)}onStoreEvent(e,t){return this.eventBus.subscribe(e,t)}getPersistenceStatus(){return this.persistenceHandler.getQueueStatus()}async flushPersistence(){return this.persistenceHandler.flush()}discardPersistenceQueue(){this.persistenceHandler.discardQueue()}dispose(){this.updateSerializer.close(),this.persistenceHandler.dispose(),this.metricsCollector.dispose?.(),this.selectorManager.dispose?.()}emit(e,t){queueMicrotask((()=>{e.emit(t)}))}},exports.StoreObserver=class{store;eventHistory=[];stateHistory=[];unsubscribers=[];isTimeTraveling=!1;devTools=null;middlewareExecutions=[];activeTransactionCount=0;activeBatches=new Set;maxEvents;maxStateHistory;enableConsoleLogging;isSilent;logEvents;performanceThresholds;constructor(e,t={}){this.store=e,this.maxEvents=t.maxEvents??500,this.maxStateHistory=t.maxStateHistory??20,this.enableConsoleLogging=t.enableConsoleLogging??!1,this.isSilent=t.silent??!1,this.logEvents={updates:t.logEvents?.updates??!0,middleware:t.logEvents?.middleware??!0,transactions:t.logEvents?.transactions??!0,actions:t.logEvents?.actions??!0,selectors:t.logEvents?.selectors??!0},this.performanceThresholds={updateTime:t.performanceThresholds?.updateTime??50,middlewareTime:t.performanceThresholds?.middlewareTime??20},this.recordStateSnapshot([]),this.setupEventListeners()}_consoleLog(e,...t){this.isSilent||"function"==typeof console[e]&&console[e](...t)}setupEventListeners(){const e=["update:start","update:complete","middleware:start","middleware:complete","middleware:error","middleware:blocked","transaction:start","transaction:complete","transaction:error","middleware:executed","action:start","action:complete","action:error","selector:accessed"];for(const t of e){const e=t.startsWith("update")&&this.logEvents.updates||t.startsWith("middleware")&&this.logEvents.middleware||t.startsWith("transaction")&&this.logEvents.transactions||t.startsWith("action")&&this.logEvents.actions||t.startsWith("selector")&&this.logEvents.selectors;this.unsubscribers.push(this.store.on(t,(s=>{"update:complete"!==t||s.blocked||this.isTimeTraveling||this.recordStateSnapshot(s.deltas),"middleware:executed"===t?this.middlewareExecutions.push(s):"transaction:start"===t?this.activeTransactionCount++:"transaction:complete"!==t&&"transaction:error"!==t||(this.activeTransactionCount=Math.max(0,this.activeTransactionCount-1)),s.batchId&&(t.endsWith("start")?this.activeBatches.add(s.batchId):(t.endsWith("complete")||t.endsWith("error"))&&this.activeBatches.delete(s.batchId)),this.recordEvent(t,s),this.enableConsoleLogging&&e&&this._log(t,s),this._checkPerformance(t,s)})))}}recordStateSnapshot(e){const t={state:this.store.get(!0),timestamp:Date.now(),deltas:e};this.stateHistory.unshift(t),this.stateHistory.length>this.maxStateHistory&&this.stateHistory.pop()}recordEvent(e,t){const s={type:e,timestamp:Date.now(),data:structuredClone(t)};this.eventHistory.unshift(s),this.eventHistory.length>this.maxEvents&&this.eventHistory.pop()}getEventHistory(){return structuredClone(this.eventHistory)}getStateHistory(){return structuredClone(this.stateHistory)}getMiddlewareExecutions(){return this.middlewareExecutions}getTransactionStatus(){return{activeTransactions:this.activeTransactionCount,activeBatches:Array.from(this.activeBatches)}}createLoggingMiddleware(e={}){const{logLevel:t="debug",logUpdates:s=!0}=e;return(e,i)=>{if(s){(console[t]||console.log)("State Update:",i)}return i}}createValidationMiddleware(e){return(t,s)=>{const i=e(t,s);return"boolean"==typeof i?i:(!i.valid&&i.reason&&this._consoleLog("warn","Validation failed:",i.reason),i.valid)}}getRecentChanges(e=5){const t=[],s=Math.min(e,this.stateHistory.length);for(let e=0;e<s;e++){const s=this.stateHistory[e];if(!s.deltas||0===s.deltas.length)continue;const i={},r={},a=(e,t,s)=>{t.reduce(((e,i,r)=>(r===t.length-1?e[i]=s:e[i]=e[i]??{},e[i])),e)};for(const e of s.deltas){const t=e.path.split(".");a(i,t,e.oldValue),a(r,t,e.newValue)}t.push({timestamp:s.timestamp,changedPaths:s.deltas.map((e=>e.path)),from:i,to:r})}return t}clearHistory(){this.eventHistory=[],this.stateHistory.length>0&&(this.stateHistory=[this.stateHistory[0]])}getHistoryForAction(e){return this.eventHistory.filter((t=>t.data?.actionId===e))}async replay(e){const t=this.eventHistory.filter((e=>"update:start"===e.type))[e];t?.data.update?(this._consoleLog("log",`Replaying event at index ${e}:`,t),await this.store.set(t.data.update,{force:!0})):this._consoleLog("warn",`No replayable event found at index ${e}.`)}createTimeTravel(){let e=0,t=[];const s=this.store.on("update:complete",(s=>{this.isTimeTraveling||s.blocked||(t=[],e=0)}));this.unsubscribers.push(s);const i=()=>this.stateHistory.length,r=()=>e<i()-1,a=()=>t.length>0;return{canUndo:r,canRedo:a,undo:async()=>{if(!r())return;t.unshift(this.stateHistory[e]),e++;const s=this.stateHistory[e].state;this.isTimeTraveling=!0,await this.store.set({...s},{force:!0}),this.isTimeTraveling=!1},redo:async()=>{if(!a())return;const s=t.shift();e--,this.isTimeTraveling=!0,await this.store.set({...s.state},{force:!0}),this.isTimeTraveling=!1},length:i,clear:()=>{t=[],e=0}}}async saveSession(e){const t=this.store.id(),s={eventHistory:this.eventHistory,stateHistory:this.stateHistory};return Promise.resolve(e.set(t,s))}async loadSession(e){const t=await Promise.resolve(e.get());return!!t&&(this.eventHistory=t.eventHistory||[],this.stateHistory=t.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),!0)}exportSession(){const e={eventHistory:this.eventHistory,stateHistory:this.stateHistory},t=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),s=URL.createObjectURL(t),i=document.createElement("a");i.href=s,i.download=`store-observer-session-${(new Date).toISOString()}.json`,i.click(),URL.revokeObjectURL(s)}importSession(e){return new Promise(((t,s)=>{const i=new FileReader;i.onload=async e=>{try{const s=JSON.parse(e.target?.result);this.eventHistory=s.eventHistory||[],this.stateHistory=s.stateHistory||[],this.stateHistory.length>0&&await this.store.set(this.stateHistory[0].state,{force:!0}),t()}catch(e){s(e)}},i.onerror=e=>s(e),i.readAsText(e)}))}disconnect(){this.unsubscribers.forEach((e=>e())),this.unsubscribers=[],this.devTools?.disconnect(),this.clearHistory()}_log(e,t){const s=new Date(t.timestamp||Date.now()).toISOString().split("T")[1].replace("Z","");if("update:start"===e)this._consoleLog("group",`%c⚡ Store Update Started [${s}]`,"color: #4a6da7");else if("update:complete"===e){if(t.blocked)this._consoleLog("warn",`%c✋ Update Blocked [${s}]`,"color: #bf8c0a",t.error);else{const e=t.deltas||[];e.length>0&&(this._consoleLog("log",`%c✅ Update Complete [${s}] - ${e.length} paths changed in ${t.duration?.toFixed(2)}ms`,"color: #2a9d8f"),this._consoleLog("table",e.map((e=>({path:e.path,oldValue:e.oldValue,newValue:e.newValue})))))}this._consoleLog("groupEnd")}else"middleware:start"===e?this._consoleLog("debug",`%c◀ Middleware "${t.name}" started [${s}] (${t.type})`,"color: #8c8c8c"):"middleware:complete"===e?this._consoleLog("debug",`%c▶ Middleware "${t.name}" completed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #7c9c7c"):"middleware:error"===e?this._consoleLog("error",`%c❌ Middleware "${t.name}" error [${s}]:`,"color: #e63946",t.error):"middleware:blocked"===e?this._consoleLog("warn",`%c🛑 Middleware "${t.name}" blocked update [${s}]`,"color: #e76f51"):"transaction:start"===e?this._consoleLog("group",`%c📦 Transaction Started [${s}]`,"color: #6d597a"):"transaction:complete"===e?(this._consoleLog("log",`%c📦 Transaction Complete [${s}]`,"color: #355070"),this._consoleLog("groupEnd")):"transaction:error"===e?(this._consoleLog("error",`%c📦 Transaction Error [${s}]:`,"color: #e56b6f",t.error),this._consoleLog("groupEnd")):"action:start"===e?this._consoleLog("group",`%c🚀 Action "${t.name}" Started [${s}]`,"color: #9b59b6",{params:t.params}):"action:complete"===e?(this._consoleLog("log",`%c✔️ Action "${t.name}" Complete [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #2ecc71"),this._consoleLog("groupEnd")):"action:error"===e?(this._consoleLog("error",`%c🔥 Action "${t.name}" Error [${s}]:`,"color: #e74c3c",t.error),this._consoleLog("groupEnd")):"selector:accessed"===e&&this._consoleLog("debug",`%c👀 Selector Accessed [${s}] in ${t.duration?.toFixed(2)}ms`,"color: #f1c40f",{accessedPaths:t.accessedPaths,selectorId:t.selectorId})}_checkPerformance(e,t){this.enableConsoleLogging&&("update:complete"===e&&!t.blocked&&t.duration>this.performanceThresholds.updateTime&&this._consoleLog("warn",`%c⚠️ Slow update detected [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{deltas:t.deltas,threshold:this.performanceThresholds.updateTime}),"middleware:complete"===e&&t.duration>this.performanceThresholds.middlewareTime&&this._consoleLog("warn",`%c⚠️ Slow middleware "${t.name}" [${t.duration.toFixed(2)}ms]`,"color: #ff9f1c",{threshold:this.performanceThresholds.middlewareTime}))}},exports.UnknownActionError=k,exports.createDerivePaths=f,exports.createDiff=y,exports.createMerge=h,exports.derivePaths=v,exports.diff=w,exports.merge=u,exports.shallowClone=l;
|