@asaidimu/react-store 2.0.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/README.md +516 -263
- package/index.cjs +1 -1
- package/index.d.cts +57 -60
- package/index.d.ts +57 -60
- package/index.js +1 -1
- package/package.json +3 -7
package/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("react"),t=require("@asaidimu/utils-store")
|
|
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,68 +1,65 @@
|
|
|
1
1
|
import { SimplePersistence } from '@asaidimu/utils-persistence';
|
|
2
|
-
import {
|
|
2
|
+
import { DeepPartial, ArtifactFactory, ArtifactScope, ObserverOptions, BlockingMiddleware, Middleware } from '@asaidimu/utils-store';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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;
|
|
7
17
|
};
|
|
8
|
-
type
|
|
9
|
-
type
|
|
10
|
-
|
|
11
|
-
|
|
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>;
|
|
12
25
|
};
|
|
13
|
-
|
|
14
|
-
state: T;
|
|
15
|
-
actions: R;
|
|
16
|
-
sync?: (args: T) => void;
|
|
17
|
-
blockingMiddleware?: Record<string, BlockingMiddleware<T>>;
|
|
18
|
-
middleware?: Record<string, Middleware<T>>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface ActionExecution {
|
|
22
|
-
id: string;
|
|
23
|
-
name: string;
|
|
24
|
-
params: unknown[];
|
|
25
|
-
startTime: number;
|
|
26
|
-
endTime: number;
|
|
27
|
-
duration: number;
|
|
28
|
-
status: 'success' | 'error';
|
|
29
|
-
error?: Error;
|
|
30
|
-
result?: unknown;
|
|
31
|
-
}
|
|
32
|
-
declare class ActionTracker {
|
|
33
|
-
private executions;
|
|
34
|
-
private maxHistory;
|
|
35
|
-
private listeners;
|
|
36
|
-
track(execution: ActionExecution): void;
|
|
37
|
-
getExecutions(): ActionExecution[];
|
|
38
|
-
subscribe(listener: () => void): () => boolean;
|
|
39
|
-
private notify;
|
|
40
|
-
}
|
|
41
|
-
|
|
26
|
+
type ActionMap<TState extends object, TArtifactsMap extends ArtifactsMap<TState>> = Record<string, ActionImplementation<TState, ResolvedArtifactsMap<TArtifactsMap>, any[]>>;
|
|
42
27
|
/**
|
|
43
|
-
*
|
|
44
|
-
* @template T - The type of state being managed
|
|
45
|
-
* @template R - The type of actions available
|
|
46
|
-
* @param definition - The store definition including initial state and actions
|
|
47
|
-
* @param options - Configuration options for the store
|
|
48
|
-
* @returns A hook for accessing and updating store state
|
|
28
|
+
* Bounds the actions for the resulting store hook, removing the context argument.
|
|
49
29
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
/** Selector creator for subscribing to specific state */
|
|
58
|
-
readonly select: <S>(selector: (state: T) => S) => S;
|
|
59
|
-
/** Action dispatchers */
|
|
60
|
-
readonly actions: { [K in keyof R]: (...args: Parameters<R[K]> extends [T, ...infer P] ? P : never) => Promise<T>; };
|
|
61
|
-
readonly isReady: boolean;
|
|
62
|
-
/** track actions */
|
|
63
|
-
readonly actionTracker: ActionTracker;
|
|
64
|
-
/** Complete store state */
|
|
65
|
-
readonly state: () => T;
|
|
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 & {
|
|
35
|
+
enableMetrics?: boolean;
|
|
36
|
+
persistence?: SimplePersistence<T>;
|
|
66
37
|
};
|
|
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>>;
|
|
46
|
+
}
|
|
47
|
+
type StoreHook<TState extends object, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>> = () => {
|
|
48
|
+
store: any;
|
|
49
|
+
observer: any;
|
|
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];
|
|
57
|
+
isReady: boolean;
|
|
58
|
+
actionTracker: any;
|
|
59
|
+
watch: (action: keyof TActions) => boolean;
|
|
60
|
+
state: () => TState;
|
|
61
|
+
};
|
|
62
|
+
|
|
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>;
|
|
67
64
|
|
|
68
|
-
export { type
|
|
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,68 +1,65 @@
|
|
|
1
1
|
import { SimplePersistence } from '@asaidimu/utils-persistence';
|
|
2
|
-
import {
|
|
2
|
+
import { DeepPartial, ArtifactFactory, ArtifactScope, ObserverOptions, BlockingMiddleware, Middleware } from '@asaidimu/utils-store';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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;
|
|
7
17
|
};
|
|
8
|
-
type
|
|
9
|
-
type
|
|
10
|
-
|
|
11
|
-
|
|
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>;
|
|
12
25
|
};
|
|
13
|
-
|
|
14
|
-
state: T;
|
|
15
|
-
actions: R;
|
|
16
|
-
sync?: (args: T) => void;
|
|
17
|
-
blockingMiddleware?: Record<string, BlockingMiddleware<T>>;
|
|
18
|
-
middleware?: Record<string, Middleware<T>>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface ActionExecution {
|
|
22
|
-
id: string;
|
|
23
|
-
name: string;
|
|
24
|
-
params: unknown[];
|
|
25
|
-
startTime: number;
|
|
26
|
-
endTime: number;
|
|
27
|
-
duration: number;
|
|
28
|
-
status: 'success' | 'error';
|
|
29
|
-
error?: Error;
|
|
30
|
-
result?: unknown;
|
|
31
|
-
}
|
|
32
|
-
declare class ActionTracker {
|
|
33
|
-
private executions;
|
|
34
|
-
private maxHistory;
|
|
35
|
-
private listeners;
|
|
36
|
-
track(execution: ActionExecution): void;
|
|
37
|
-
getExecutions(): ActionExecution[];
|
|
38
|
-
subscribe(listener: () => void): () => boolean;
|
|
39
|
-
private notify;
|
|
40
|
-
}
|
|
41
|
-
|
|
26
|
+
type ActionMap<TState extends object, TArtifactsMap extends ArtifactsMap<TState>> = Record<string, ActionImplementation<TState, ResolvedArtifactsMap<TArtifactsMap>, any[]>>;
|
|
42
27
|
/**
|
|
43
|
-
*
|
|
44
|
-
* @template T - The type of state being managed
|
|
45
|
-
* @template R - The type of actions available
|
|
46
|
-
* @param definition - The store definition including initial state and actions
|
|
47
|
-
* @param options - Configuration options for the store
|
|
48
|
-
* @returns A hook for accessing and updating store state
|
|
28
|
+
* Bounds the actions for the resulting store hook, removing the context argument.
|
|
49
29
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
/** Selector creator for subscribing to specific state */
|
|
58
|
-
readonly select: <S>(selector: (state: T) => S) => S;
|
|
59
|
-
/** Action dispatchers */
|
|
60
|
-
readonly actions: { [K in keyof R]: (...args: Parameters<R[K]> extends [T, ...infer P] ? P : never) => Promise<T>; };
|
|
61
|
-
readonly isReady: boolean;
|
|
62
|
-
/** track actions */
|
|
63
|
-
readonly actionTracker: ActionTracker;
|
|
64
|
-
/** Complete store state */
|
|
65
|
-
readonly state: () => T;
|
|
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 & {
|
|
35
|
+
enableMetrics?: boolean;
|
|
36
|
+
persistence?: SimplePersistence<T>;
|
|
66
37
|
};
|
|
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>>;
|
|
46
|
+
}
|
|
47
|
+
type StoreHook<TState extends object, TArtifactsMap extends ArtifactsMap<TState>, TActions extends ActionMap<TState, TArtifactsMap>> = () => {
|
|
48
|
+
store: any;
|
|
49
|
+
observer: any;
|
|
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];
|
|
57
|
+
isReady: boolean;
|
|
58
|
+
actionTracker: any;
|
|
59
|
+
watch: (action: keyof TActions) => boolean;
|
|
60
|
+
state: () => TState;
|
|
61
|
+
};
|
|
62
|
+
|
|
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>;
|
|
67
64
|
|
|
68
|
-
export { type
|
|
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{
|
|
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": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Efficient react state manager.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -26,12 +26,8 @@
|
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@asaidimu/
|
|
30
|
-
"@asaidimu/
|
|
31
|
-
"@asaidimu/node": "^1.0.6",
|
|
32
|
-
"@asaidimu/query": "^1.1.2",
|
|
33
|
-
"@asaidimu/utils-persistence": "^2.0.1",
|
|
34
|
-
"@asaidimu/utils-store": "^2.1.0",
|
|
29
|
+
"@asaidimu/utils-persistence": "^2.1.0",
|
|
30
|
+
"@asaidimu/utils-store": "^4.0.0",
|
|
35
31
|
"hash-wasm": "^4.12.0",
|
|
36
32
|
"react": "^19.0.0",
|
|
37
33
|
"uuid": "^11.1.0"
|