@asaidimu/react-store 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("react"),t=require("@asaidimu/utils-store");var r=class{selectorCache=new WeakMap;create(e){return t=>{let r=this.selectorCache.get(e);if(r&&r.lastState===t)return r.lastResult;const n=e(t);return this.selectorCache.set(e,{lastState:t,lastResult:n}),n}}},n=class{executions=[];maxHistory=100;listeners=new Set;track(e){this.executions.unshift(e),this.executions.length>this.maxHistory&&this.executions.pop(),this.notify()}getExecutions(){return[...this.executions]}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){this.listeners.forEach((e=>e()))}};function s(e,t=new WeakMap){return void 0===e?"undefined":"function"==typeof e||"symbol"==typeof e?"":"string"==typeof e?`"${e}"`:"number"==typeof e||"boolean"==typeof e||null===e?String(e):Array.isArray(e)?`[${e.map((e=>s(e,t))).join(",")}]`:"object"==typeof e?t.has(e)?'"__circular__"':(t.set(e,!0),`{${Object.keys(e).sort().map((r=>`"${r}":${s(e[r],t)}`)).join(",")}}`):""}function o(e){let t=3421674724,r=2216829733;const n=s(e);for(let e=0;e<n.length;e++){r^=n.charCodeAt(e);const s=Math.imul(r,435),o=Math.imul(r,435)+Math.imul(t,435);r=s>>>0,t=o>>>0}return(t>>>0).toString(16)+(r>>>0).toString(16)}exports.createStore=function(s,{enableMetrics:i,debounceTime:a=0,...c}={}){const u=new t.ReactiveDataStore(s.state,c.persistence),l=new t.ReactiveDataStore(Object.fromEntries(Object.keys(s.actions).map((e=>[e,!1])))),h=i?new t.StoreObserver(u,c):void 0,d=new r,f=i?new n:void 0,y=i?new Map:void 0;s.middleware&&Object.entries(s.middleware).forEach((([e,t])=>u.use({name:e,action:t}))),s.blockingMiddleware&&Object.entries(s.blockingMiddleware).forEach((([e,t])=>u.use({block:!0,name:e,action:t})));const m=Object.entries(s.actions).reduce(((e,[t,r])=>(e[t]=function(e,t){if(0===t)return e;let r=null;return function(...n){return new Promise(((s,o)=>{r&&clearTimeout(r);const i=this;r=setTimeout((()=>{r=null,e.apply(i,n).then(s).catch(o)}),t)}))}}((async(...e)=>{const n=`${t}-${o(e)}`;if(y?.get(n))return;y?.set(n,!0);const s=f?crypto.randomUUID():void 0,i=f?performance.now():void 0,a=f?{id:s,name:t,params:e,startTime:i}:{};try{return l.set((e=>({...e,[t]:!0}))),await u.set((async t=>{const n=await r(t,...e);return f&&(a.result=n),n})),f&&(a.status="success"),u.get()}catch(e){throw f&&(a.status="error",a.error=e instanceof Error?e:new Error(String(e))),console.error(`Error in action ${t}:`,e),e}finally{l.set((e=>({...e,[t]:!1}))),f&&(a.endTime=performance.now(),a.duration=a.endTime-i,f.track(a)),y?.delete(n)}}),a),e)),{});function p(e,t){const r=function(e,t="."){const r=[],n={get:(e,t)=>{const s=[];return r.length>0&&s.push(...r[r.length-1]),s.push(t),r.push(s),new Proxy({},n)}};return e(new Proxy({},n)),r.map((e=>e.join(t)))}(e);return u.subscribe(r,t)}const b=()=>u.get(),w=e=>(u.isReady()&&e(),u.onStoreEvent("persistence:ready",e)),g=()=>u.isReady(),S=new Map;return function(){const t=e.useCallback((t=>{S.has(t)||S.set(t,d.create(t));const r=S.get(t);return e.useSyncExternalStore((e=>p(r,e)),(()=>r(u.get())),(()=>r(u.get())))}),[]),r=e.useCallback((()=>e.useSyncExternalStore((e=>u.subscribe("",e)),b,b)),[]),n=e.useSyncExternalStore(w,g,g);return{store:u,observer:h,select:t,actions:m,isReady:n,actionTracker:f,watch:t=>e.useSyncExternalStore((e=>l.subscribe(t,e)),(()=>l.get()[t]),(()=>l.get()[t])),get state(){return r}}}};
1
+ "use strict";var e=require("react"),t=require("@asaidimu/utils-store"),r=class{executions=[];maxHistory=100;listeners=new Set;track(e){this.executions.unshift(e),this.executions.length>this.maxHistory&&this.executions.pop(),this.notify()}getExecutions(){return[...this.executions]}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){this.listeners.forEach((e=>e()))}};exports.createStore=function(s,{enableMetrics:n,...a}={}){const i=new t.ReactiveDataStore(s.state,a.persistence),c=Object.keys(s.actions).reduce(((e,t)=>(e[t]=!1,e)),{}),o=new t.ReactiveDataStore(c),u=n?new t.StoreObserver(i,a):void 0,d=n?new r:void 0;n&&d&&(i.on("action:start",(({name:e})=>{o.set((()=>({[e]:!0})))})),i.on("action:complete",(e=>{o.set((()=>({[e.name]:!1}))),d.track({id:e.actionId,name:e.name,params:e.params,startTime:e.startTime,endTime:e.endTime,duration:e.duration,status:"success",result:e.result})})),i.on("action:error",(e=>{o.set((()=>({[e.name]:!1}))),d.track({id:e.actionId,name:e.name,params:e.params,startTime:e.startTime,endTime:e.endTime,duration:e.duration,status:"error",error:e.error})}))),s.middleware&&Object.entries(s.middleware).forEach((([e,t])=>i.use({name:e,action:t}))),s.blockingMiddleware&&Object.entries(s.blockingMiddleware).forEach((([e,t])=>i.use({block:!0,name:e,action:t})));const l=e=>(i.isReady()&&e(),i.on("persistence:ready",e)),m=()=>i.isReady(),h=new t.ArtifactContainer(i);s.artifacts&&Object.entries(s.artifacts).forEach((([e,t])=>{h.register({key:e,factory:t.factory,scope:t.scope,lazy:t.lazy})}));const y=Object.entries(s.actions).reduce(((e,[t,r])=>(i.register({name:t,fn:(e,...t)=>{const s={state:e,resolve:h.resolve.bind(h)};return r(s,...t)}}),e[t]=(...e)=>i.dispatch(t,...e),e)),{});return function(){const t=()=>e.useSyncExternalStore((e=>i.watch("",e)),(()=>i.get()),(()=>i.get())),r=e.useSyncExternalStore(l,m,m);return{store:i,observer:u,select:t=>{const r=i.select(t);return e.useSyncExternalStore((e=>r.subscribe(e)),(()=>r.get()),(()=>r.get()))},actions:y,isReady:r,actionTracker:d,watch:t=>e.useSyncExternalStore((e=>o.watch(t,e)),(()=>!!o.get()[t]),(()=>!!o.get()[t])),resolve:t=>{const r=e.useSyncExternalStore((e=>h.subscribeToArtifact(t,e)),(()=>h.get(t)),(()=>h.get(t)));e.useEffect((()=>{void 0!==r||h.isLoading(t)||h.resolve(t).catch(console.error)}),[t,r]);return[r,null!=r]},get state(){return t}}}};
package/index.d.cts CHANGED
@@ -1,82 +1,65 @@
1
1
  import { SimplePersistence } from '@asaidimu/utils-persistence';
2
- import { ObservabilityOptions, DeepPartial, BlockingMiddleware, Middleware, ReactiveDataStore, StoreObserver } from '@asaidimu/utils-store';
2
+ import { DeepPartial, ArtifactFactory, ArtifactScope, ObserverOptions, BlockingMiddleware, Middleware } from '@asaidimu/utils-store';
3
3
 
4
- type StoreOptions<T> = ObservabilityOptions & {
4
+ interface ActionContext<TState extends object, TResolvedArtifacts extends object> {
5
+ /**
6
+ * Resolve an artifact.
7
+ * This records a dependency between the caller and the requested artifact.
8
+ */
9
+ resolve<K extends keyof TResolvedArtifacts>(key: K): Promise<TResolvedArtifacts[K]>;
10
+ state: TState;
11
+ }
12
+ type ActionImplementation<TState extends object, TResolvedArtifacts extends object, TArgs extends any[]> = (ctx: ActionContext<TState, TResolvedArtifacts>, ...args: TArgs) => DeepPartial<TState> | Promise<DeepPartial<TState>>;
13
+ type ArtifactDefinition<TState extends Object, R> = {
14
+ factory: ArtifactFactory<TState, R>;
15
+ scope?: ArtifactScope;
16
+ lazy?: boolean;
17
+ };
18
+ type ArtifactsMap<TState extends object> = Record<string, ArtifactDefinition<TState, any>>;
19
+ type ExtractArtifactInstanceFromConfig<T> = T extends {
20
+ factory: ArtifactFactory<any, infer I>;
21
+ } ? I : never;
22
+ type ExtractInstanceFromMap<TMap extends ArtifactsMap<any>, TKey extends keyof TMap> = ExtractArtifactInstanceFromConfig<TMap[TKey]>;
23
+ type ResolvedArtifactsMap<TArtifactsMap extends ArtifactsMap<any>> = {
24
+ [K in keyof TArtifactsMap]: ExtractInstanceFromMap<TArtifactsMap, K>;
25
+ };
26
+ type ActionMap<TState extends object, TArtifactsMap extends ArtifactsMap<TState>> = Record<string, ActionImplementation<TState, ResolvedArtifactsMap<TArtifactsMap>, any[]>>;
27
+ /**
28
+ * Bounds the actions for the resulting store hook, removing the context argument.
29
+ */
30
+ type BoundActions<TState extends object, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>> = {
31
+ [K in keyof TActions]: (...args: Parameters<TActions[K]> extends [ActionContext<any, any>, ...infer R] ? R : never) => Promise<TState>;
32
+ };
33
+ type LoadingState<TActions> = Partial<Record<keyof TActions, boolean>>;
34
+ type StoreOptions<T> = ObserverOptions & {
5
35
  enableMetrics?: boolean;
6
36
  persistence?: SimplePersistence<T>;
7
37
  };
8
- type Action<T> = (state: T, ...args: any[]) => DeepPartial<T>;
9
- type LoadingState<T extends string> = Record<T, boolean>;
10
- type StoreSelector<T, S> = (state: T) => S;
11
- type Actions<T> = {
12
- [K: string]: (state: T, ...args: any[]) => DeepPartial<T> | Promise<DeepPartial<T>>;
13
- };
14
- interface StoreDefinition<T, R extends Actions<T>> {
15
- state: T;
16
- actions: R;
17
- loading?: LoadingState<keyof R & string>;
18
- sync?: (args: T) => void;
19
- blockingMiddleware?: Record<string, BlockingMiddleware<T>>;
20
- middleware?: Record<string, Middleware<T>>;
38
+ interface StoreDefinition<TState extends object, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>> {
39
+ state: TState;
40
+ actions: TActions;
41
+ artifacts?: TArtifactsMap;
42
+ loading?: LoadingState<TActions>;
43
+ sync?: (args: TState) => void;
44
+ blockingMiddleware?: Record<string, BlockingMiddleware<TState>>;
45
+ middleware?: Record<string, Middleware<TState>>;
21
46
  }
22
- type StoreHook<T, R extends Actions<T>> = () => {
47
+ type StoreHook<TState extends object, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>> = () => {
23
48
  store: any;
24
49
  observer: any;
25
- select: <S>(selector: (state: T) => S) => S;
26
- actions: R;
50
+ select: <S>(selector: (state: TState) => S) => S;
51
+ actions: BoundActions<TState, TArtifactsMap, TActions>;
52
+ /**
53
+ * Reactive Artifact Resolver.
54
+ * Returns [instance, isReady].
55
+ */
56
+ resolve: <K extends keyof TArtifactsMap>(key: K) => readonly [ExtractInstanceFromMap<TArtifactsMap, K>, true] | readonly [ExtractInstanceFromMap<TArtifactsMap, K> | undefined, false];
27
57
  isReady: boolean;
28
58
  actionTracker: any;
29
- watch: (action: keyof R & string) => boolean;
30
- state: () => T;
59
+ watch: (action: keyof TActions) => boolean;
60
+ state: () => TState;
31
61
  };
32
62
 
33
- interface ActionExecution {
34
- id: string;
35
- name: string;
36
- params: unknown[];
37
- startTime: number;
38
- endTime: number;
39
- duration: number;
40
- status: 'success' | 'error';
41
- error?: Error;
42
- result?: unknown;
43
- }
44
- declare class ActionTracker {
45
- private executions;
46
- private maxHistory;
47
- private listeners;
48
- track(execution: ActionExecution): void;
49
- getExecutions(): ActionExecution[];
50
- subscribe(listener: () => void): () => boolean;
51
- private notify;
52
- }
53
-
54
- /**
55
- * Creates a new store with state management
56
- * @template T - The type of state being managed
57
- * @template R - The type of actions available
58
- * @param definition - The store definition including initial state and actions
59
- * @param options - Configuration options for the store
60
- * @returns A hook for accessing and updating store state
61
- */
62
- declare function createStore<T extends Record<string, unknown>, R extends Actions<T>>(definition: StoreDefinition<T, R>, { enableMetrics, debounceTime, ...options }?: StoreOptions<T> & {
63
- debounceTime?: number;
64
- }): () => {
65
- /** Direct store instance access */
66
- readonly store: ReactiveDataStore<T>;
67
- /** Performance monitoring tools when enabled */
68
- readonly observer: StoreObserver<T> | undefined;
69
- /** Selector creator for subscribing to specific state */
70
- readonly select: <S>(selector: (state: T) => S) => S;
71
- /** Action dispatchers */
72
- readonly actions: { [K in keyof R]: (...args: Parameters<R[K]> extends [T, ...infer P] ? P : never) => Promise<T>; };
73
- readonly isReady: boolean;
74
- /** track actions */
75
- readonly actionTracker: ActionTracker | undefined;
76
- /** watch loading state */
77
- readonly watch: (action: keyof R & string) => LoadingState<keyof R & string>[keyof R & string];
78
- /** Complete store state */
79
- readonly state: () => T;
80
- };
63
+ declare function createStore<TState extends Record<string, unknown>, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>>(definition: StoreDefinition<TState, TArtifactsMap, TActions>, { enableMetrics, ...options }?: StoreOptions<TState>): StoreHook<TState, TArtifactsMap, TActions>;
81
64
 
82
- export { type Action, type Actions, type LoadingState, type StoreDefinition, type StoreHook, type StoreOptions, type StoreSelector, createStore };
65
+ export { type ActionContext, type ActionImplementation, type ActionMap, type ArtifactDefinition, type ArtifactsMap, type BoundActions, type ExtractArtifactInstanceFromConfig, type ExtractInstanceFromMap, type LoadingState, type ResolvedArtifactsMap, type StoreDefinition, type StoreHook, type StoreOptions, createStore };
package/index.d.ts CHANGED
@@ -1,82 +1,65 @@
1
1
  import { SimplePersistence } from '@asaidimu/utils-persistence';
2
- import { ObservabilityOptions, DeepPartial, BlockingMiddleware, Middleware, ReactiveDataStore, StoreObserver } from '@asaidimu/utils-store';
2
+ import { DeepPartial, ArtifactFactory, ArtifactScope, ObserverOptions, BlockingMiddleware, Middleware } from '@asaidimu/utils-store';
3
3
 
4
- type StoreOptions<T> = ObservabilityOptions & {
4
+ interface ActionContext<TState extends object, TResolvedArtifacts extends object> {
5
+ /**
6
+ * Resolve an artifact.
7
+ * This records a dependency between the caller and the requested artifact.
8
+ */
9
+ resolve<K extends keyof TResolvedArtifacts>(key: K): Promise<TResolvedArtifacts[K]>;
10
+ state: TState;
11
+ }
12
+ type ActionImplementation<TState extends object, TResolvedArtifacts extends object, TArgs extends any[]> = (ctx: ActionContext<TState, TResolvedArtifacts>, ...args: TArgs) => DeepPartial<TState> | Promise<DeepPartial<TState>>;
13
+ type ArtifactDefinition<TState extends Object, R> = {
14
+ factory: ArtifactFactory<TState, R>;
15
+ scope?: ArtifactScope;
16
+ lazy?: boolean;
17
+ };
18
+ type ArtifactsMap<TState extends object> = Record<string, ArtifactDefinition<TState, any>>;
19
+ type ExtractArtifactInstanceFromConfig<T> = T extends {
20
+ factory: ArtifactFactory<any, infer I>;
21
+ } ? I : never;
22
+ type ExtractInstanceFromMap<TMap extends ArtifactsMap<any>, TKey extends keyof TMap> = ExtractArtifactInstanceFromConfig<TMap[TKey]>;
23
+ type ResolvedArtifactsMap<TArtifactsMap extends ArtifactsMap<any>> = {
24
+ [K in keyof TArtifactsMap]: ExtractInstanceFromMap<TArtifactsMap, K>;
25
+ };
26
+ type ActionMap<TState extends object, TArtifactsMap extends ArtifactsMap<TState>> = Record<string, ActionImplementation<TState, ResolvedArtifactsMap<TArtifactsMap>, any[]>>;
27
+ /**
28
+ * Bounds the actions for the resulting store hook, removing the context argument.
29
+ */
30
+ type BoundActions<TState extends object, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>> = {
31
+ [K in keyof TActions]: (...args: Parameters<TActions[K]> extends [ActionContext<any, any>, ...infer R] ? R : never) => Promise<TState>;
32
+ };
33
+ type LoadingState<TActions> = Partial<Record<keyof TActions, boolean>>;
34
+ type StoreOptions<T> = ObserverOptions & {
5
35
  enableMetrics?: boolean;
6
36
  persistence?: SimplePersistence<T>;
7
37
  };
8
- type Action<T> = (state: T, ...args: any[]) => DeepPartial<T>;
9
- type LoadingState<T extends string> = Record<T, boolean>;
10
- type StoreSelector<T, S> = (state: T) => S;
11
- type Actions<T> = {
12
- [K: string]: (state: T, ...args: any[]) => DeepPartial<T> | Promise<DeepPartial<T>>;
13
- };
14
- interface StoreDefinition<T, R extends Actions<T>> {
15
- state: T;
16
- actions: R;
17
- loading?: LoadingState<keyof R & string>;
18
- sync?: (args: T) => void;
19
- blockingMiddleware?: Record<string, BlockingMiddleware<T>>;
20
- middleware?: Record<string, Middleware<T>>;
38
+ interface StoreDefinition<TState extends object, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>> {
39
+ state: TState;
40
+ actions: TActions;
41
+ artifacts?: TArtifactsMap;
42
+ loading?: LoadingState<TActions>;
43
+ sync?: (args: TState) => void;
44
+ blockingMiddleware?: Record<string, BlockingMiddleware<TState>>;
45
+ middleware?: Record<string, Middleware<TState>>;
21
46
  }
22
- type StoreHook<T, R extends Actions<T>> = () => {
47
+ type StoreHook<TState extends object, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>> = () => {
23
48
  store: any;
24
49
  observer: any;
25
- select: <S>(selector: (state: T) => S) => S;
26
- actions: R;
50
+ select: <S>(selector: (state: TState) => S) => S;
51
+ actions: BoundActions<TState, TArtifactsMap, TActions>;
52
+ /**
53
+ * Reactive Artifact Resolver.
54
+ * Returns [instance, isReady].
55
+ */
56
+ resolve: <K extends keyof TArtifactsMap>(key: K) => readonly [ExtractInstanceFromMap<TArtifactsMap, K>, true] | readonly [ExtractInstanceFromMap<TArtifactsMap, K> | undefined, false];
27
57
  isReady: boolean;
28
58
  actionTracker: any;
29
- watch: (action: keyof R & string) => boolean;
30
- state: () => T;
59
+ watch: (action: keyof TActions) => boolean;
60
+ state: () => TState;
31
61
  };
32
62
 
33
- interface ActionExecution {
34
- id: string;
35
- name: string;
36
- params: unknown[];
37
- startTime: number;
38
- endTime: number;
39
- duration: number;
40
- status: 'success' | 'error';
41
- error?: Error;
42
- result?: unknown;
43
- }
44
- declare class ActionTracker {
45
- private executions;
46
- private maxHistory;
47
- private listeners;
48
- track(execution: ActionExecution): void;
49
- getExecutions(): ActionExecution[];
50
- subscribe(listener: () => void): () => boolean;
51
- private notify;
52
- }
53
-
54
- /**
55
- * Creates a new store with state management
56
- * @template T - The type of state being managed
57
- * @template R - The type of actions available
58
- * @param definition - The store definition including initial state and actions
59
- * @param options - Configuration options for the store
60
- * @returns A hook for accessing and updating store state
61
- */
62
- declare function createStore<T extends Record<string, unknown>, R extends Actions<T>>(definition: StoreDefinition<T, R>, { enableMetrics, debounceTime, ...options }?: StoreOptions<T> & {
63
- debounceTime?: number;
64
- }): () => {
65
- /** Direct store instance access */
66
- readonly store: ReactiveDataStore<T>;
67
- /** Performance monitoring tools when enabled */
68
- readonly observer: StoreObserver<T> | undefined;
69
- /** Selector creator for subscribing to specific state */
70
- readonly select: <S>(selector: (state: T) => S) => S;
71
- /** Action dispatchers */
72
- readonly actions: { [K in keyof R]: (...args: Parameters<R[K]> extends [T, ...infer P] ? P : never) => Promise<T>; };
73
- readonly isReady: boolean;
74
- /** track actions */
75
- readonly actionTracker: ActionTracker | undefined;
76
- /** watch loading state */
77
- readonly watch: (action: keyof R & string) => LoadingState<keyof R & string>[keyof R & string];
78
- /** Complete store state */
79
- readonly state: () => T;
80
- };
63
+ declare function createStore<TState extends Record<string, unknown>, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>>(definition: StoreDefinition<TState, TArtifactsMap, TActions>, { enableMetrics, ...options }?: StoreOptions<TState>): StoreHook<TState, TArtifactsMap, TActions>;
81
64
 
82
- export { type Action, type Actions, type LoadingState, type StoreDefinition, type StoreHook, type StoreOptions, type StoreSelector, createStore };
65
+ export { type ActionContext, type ActionImplementation, type ActionMap, type ArtifactDefinition, type ArtifactsMap, type BoundActions, type ExtractArtifactInstanceFromConfig, type ExtractInstanceFromMap, type LoadingState, type ResolvedArtifactsMap, type StoreDefinition, type StoreHook, type StoreOptions, createStore };
package/index.js CHANGED
@@ -1 +1 @@
1
- import{useCallback as e,useSyncExternalStore as t}from"react";import{ReactiveDataStore as n,StoreObserver as r}from"@asaidimu/utils-store";var s=class{selectorCache=new WeakMap;create(e){return t=>{let n=this.selectorCache.get(e);if(n&&n.lastState===t)return n.lastResult;const r=e(t);return this.selectorCache.set(e,{lastState:t,lastResult:r}),r}}},o=class{executions=[];maxHistory=100;listeners=new Set;track(e){this.executions.unshift(e),this.executions.length>this.maxHistory&&this.executions.pop(),this.notify()}getExecutions(){return[...this.executions]}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){this.listeners.forEach((e=>e()))}};function i(e,t=new WeakMap){return void 0===e?"undefined":"function"==typeof e||"symbol"==typeof e?"":"string"==typeof e?`"${e}"`:"number"==typeof e||"boolean"==typeof e||null===e?String(e):Array.isArray(e)?`[${e.map((e=>i(e,t))).join(",")}]`:"object"==typeof e?t.has(e)?'"__circular__"':(t.set(e,!0),`{${Object.keys(e).sort().map((n=>`"${n}":${i(e[n],t)}`)).join(",")}}`):""}function c(e){let t=3421674724,n=2216829733;const r=i(e);for(let e=0;e<r.length;e++){n^=r.charCodeAt(e);const s=Math.imul(n,435),o=Math.imul(n,435)+Math.imul(t,435);n=s>>>0,t=o>>>0}return(t>>>0).toString(16)+(n>>>0).toString(16)}function a(i,{enableMetrics:a,debounceTime:u=0,...l}={}){const h=new n(i.state,l.persistence),d=new n(Object.fromEntries(Object.keys(i.actions).map((e=>[e,!1])))),f=a?new r(h,l):void 0,m=new s,p=a?new o:void 0,y=a?new Map:void 0;i.middleware&&Object.entries(i.middleware).forEach((([e,t])=>h.use({name:e,action:t}))),i.blockingMiddleware&&Object.entries(i.blockingMiddleware).forEach((([e,t])=>h.use({block:!0,name:e,action:t})));const b=Object.entries(i.actions).reduce(((e,[t,n])=>(e[t]=function(e,t){if(0===t)return e;let n=null;return function(...r){return new Promise(((s,o)=>{n&&clearTimeout(n);const i=this;n=setTimeout((()=>{n=null,e.apply(i,r).then(s).catch(o)}),t)}))}}((async(...e)=>{const r=`${t}-${c(e)}`;if(y?.get(r))return;y?.set(r,!0);const s=p?crypto.randomUUID():void 0,o=p?performance.now():void 0,i=p?{id:s,name:t,params:e,startTime:o}:{};try{return d.set((e=>({...e,[t]:!0}))),await h.set((async t=>{const r=await n(t,...e);return p&&(i.result=r),r})),p&&(i.status="success"),h.get()}catch(e){throw p&&(i.status="error",i.error=e instanceof Error?e:new Error(String(e))),console.error(`Error in action ${t}:`,e),e}finally{d.set((e=>({...e,[t]:!1}))),p&&(i.endTime=performance.now(),i.duration=i.endTime-o,p.track(i)),y?.delete(r)}}),u),e)),{});function w(e,t){const n=function(e,t="."){const n=[],r={get:(e,t)=>{const s=[];return n.length>0&&s.push(...n[n.length-1]),s.push(t),n.push(s),new Proxy({},r)}};return e(new Proxy({},r)),n.map((e=>e.join(t)))}(e);return h.subscribe(n,t)}const g=()=>h.get(),x=e=>(h.isReady()&&e(),h.onStoreEvent("persistence:ready",e)),j=()=>h.isReady(),k=new Map;return function(){const n=e((e=>{k.has(e)||k.set(e,m.create(e));const n=k.get(e);return t((e=>w(n,e)),(()=>n(h.get())),(()=>n(h.get())))}),[]),r=e((()=>t((e=>h.subscribe("",e)),g,g)),[]),s=t(x,j,j);return{store:h,observer:f,select:n,actions:b,isReady:s,actionTracker:p,watch:e=>t((t=>d.subscribe(e,t)),(()=>d.get()[e]),(()=>d.get()[e])),get state(){return r}}}}export{a as createStore};
1
+ import{useSyncExternalStore as e,useEffect as t}from"react";import{ReactiveDataStore as s,StoreObserver as r,ArtifactContainer as i}from"@asaidimu/utils-store";var n=class{executions=[];maxHistory=100;listeners=new Set;track(e){this.executions.unshift(e),this.executions.length>this.maxHistory&&this.executions.pop(),this.notify()}getExecutions(){return[...this.executions]}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){this.listeners.forEach((e=>e()))}};function a(a,{enableMetrics:o,...c}={}){const d=new s(a.state,c.persistence),u=Object.keys(a.actions).reduce(((e,t)=>(e[t]=!1,e)),{}),m=new s(u),l=o?new r(d,c):void 0,h=o?new n:void 0;o&&h&&(d.on("action:start",(({name:e})=>{m.set((()=>({[e]:!0})))})),d.on("action:complete",(e=>{m.set((()=>({[e.name]:!1}))),h.track({id:e.actionId,name:e.name,params:e.params,startTime:e.startTime,endTime:e.endTime,duration:e.duration,status:"success",result:e.result})})),d.on("action:error",(e=>{m.set((()=>({[e.name]:!1}))),h.track({id:e.actionId,name:e.name,params:e.params,startTime:e.startTime,endTime:e.endTime,duration:e.duration,status:"error",error:e.error})}))),a.middleware&&Object.entries(a.middleware).forEach((([e,t])=>d.use({name:e,action:t}))),a.blockingMiddleware&&Object.entries(a.blockingMiddleware).forEach((([e,t])=>d.use({block:!0,name:e,action:t})));const b=e=>(d.isReady()&&e(),d.on("persistence:ready",e)),f=()=>d.isReady(),g=new i(d);a.artifacts&&Object.entries(a.artifacts).forEach((([e,t])=>{g.register({key:e,factory:t.factory,scope:t.scope,lazy:t.lazy})}));const p=Object.entries(a.actions).reduce(((e,[t,s])=>(d.register({name:t,fn:(e,...t)=>{const r={state:e,resolve:g.resolve.bind(g)};return s(r,...t)}}),e[t]=(...e)=>d.dispatch(t,...e),e)),{});return function(){const s=()=>e((e=>d.watch("",e)),(()=>d.get()),(()=>d.get())),r=e(b,f,f);return{store:d,observer:l,select:t=>{const s=d.select(t);return e((e=>s.subscribe(e)),(()=>s.get()),(()=>s.get()))},actions:p,isReady:r,actionTracker:h,watch:t=>e((e=>m.watch(t,e)),(()=>!!m.get()[t]),(()=>!!m.get()[t])),resolve:s=>{const r=e((e=>g.subscribeToArtifact(s,e)),(()=>g.get(s)),(()=>g.get(s)));t((()=>{void 0!==r||g.isLoading(s)||g.resolve(s).catch(console.error)}),[s,r]);return[r,null!=r]},get state(){return s}}}}export{a as createStore};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/react-store",
3
- "version": "2.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "Efficient react state manager.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@asaidimu/utils-persistence": "^2.1.0",
30
- "@asaidimu/utils-store": "^2.2.0",
30
+ "@asaidimu/utils-store": "^4.0.0",
31
31
  "hash-wasm": "^4.12.0",
32
32
  "react": "^19.0.0",
33
33
  "uuid": "^11.1.0"