@asaidimu/react-store 1.1.1 → 1.1.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.
Files changed (3) hide show
  1. package/index.cjs +1 -1
  2. package/index.js +1 -1
  3. package/package.json +2 -2
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var m=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var M=(n,t)=>{for(var e in t)m(n,e,{get:t[e],enumerable:!0})},E=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of b(t))!T.call(n,r)&&r!==e&&m(n,r,{get:()=>t[r],enumerable:!(i=w(t,r))||i.enumerable});return n};var k=n=>E(m({},"__esModule",{value:!0}),n);var R={};M(R,{StateManager:()=>h,createStore:()=>x});module.exports=k(R);var g=require("react");var S=require("@asaidimu/node");var p=class{cache=new Map;maxSize;maxAge;constructor(t=100,e=5e3){this.maxSize=t,this.maxAge=e}get(t){let e=this.cache.get(t);if(e){if(Date.now()-e.timestamp>this.maxAge){this.cache.delete(t);return}return e.value}}set(t,e){if(this.cache.size>=this.maxSize){let i=Array.from(this.cache.entries()).sort(([,r],[,a])=>r.timestamp-a.timestamp)[0][0];this.cache.delete(i)}this.cache.set(t,{value:e,timestamp:Date.now()})}clear(){this.cache.clear()}};var f=class{validation;constructor(t={}){this.validation=t}validate(t,e){let i=[],r=e.split("/").pop(),a=this.validation[r];return a?(a.forEach((o,s)=>{try{o.validate(t[r])||i.push(o.message||`Validation failed for ${String(r)} at rule ${s}`)}catch(c){i.push(`Validation error at ${e}: ${c.message}`)}}),{valid:i.length===0,errors:i}):{valid:!0,errors:[]}}};var u="root",h=class{manager;subscribers=new Set;middleware;options;definition;middlewareCache;validator;lastValidationResult={valid:!0,errors:[]};constructor(t,e={}){this.definition=t,this.options=e,this.middleware=this.sortMiddleware(e.middleware||[]),this.middlewareCache=new p,this.validator=new f(e.validation),this.manager=this.initializeManager()}sortMiddleware(t){let e=new Map;t.forEach(s=>{e.set(s.id,new Set(s.dependencies||[]))});let i=[],r=new Set,a=new Set,o=s=>{if(a.has(s))throw new Error(`Circular dependency found: ${s}`);if(r.has(s))return;a.add(s),(e.get(s)||new Set).forEach(d=>o(d)),a.delete(s),r.add(s),i.push(t.find(d=>d.id===s))};return t.forEach(s=>{r.has(s.id)||o(s.id)}),i.sort((s,c)=>(c.priority||0)-(s.priority||0))}initializeManager(){let t=(0,S.createNodeManager)();t.add(u,null,{key:u});let e=(i=u,r=this.definition.state)=>{for(let[a,o]of Object.entries(r))typeof o=="object"&&!Array.isArray(o)?(t.add(`${i}/${a}`,o,{key:a}),e(`${i}/${a}`,o)):t.add(`${i}/${a}`,o,{key:a})};if(e(),this.definition.sync){let i=this.getState.bind(this);t.subscribe("node",()=>{this.definition.sync(i())})}return t}async applyMiddleware(t,e,i={value:!1}){let r=`${e}-${JSON.stringify(t)}`,a=this.middlewareCache.get(r);if(a)return a;if(this.lastValidationResult=this.validator.validate(t,e),!this.lastValidationResult.valid)throw new Error(`Validation failed: ${this.lastValidationResult.errors.join(", ")}`);let o={fullState:this.getState(),path:e,abortUpdate:()=>{i.value=!0},getValidationResult:()=>this.lastValidationResult};try{let s=t;for(let c of this.middleware){if(i.value)throw new Error("Update aborted by middleware");if(s=await Promise.resolve(c.transform(s,o)),this.lastValidationResult=this.validator.validate(s,e),!this.lastValidationResult.valid)throw new Error(`Validation failed after middleware ${c.id}: ${this.lastValidationResult.errors.join(", ")}`)}return this.middlewareCache.set(r,s),s}catch(s){throw this.handleMiddlewareError(s,t,e),s}}handleMiddlewareError(t,e,i){if(this.options.error?.onError&&this.options.error.onError(t,{action:"applyMiddleware",state:e,path:i,error:t}),this.options.error?.recovery)switch(this.middlewareCache.clear(),this.options.error.recovery.strategy){case"retry":break;case"revert":this.revertState(i);break;case"ignore":break}}revertState(t){let e=this.getState(),i=t.split("/"),r=e;for(let o=1;o<i.length-1;o++)r=r[i[o]];let a=i[i.length-1];this.manager.update(t,r[a],{force:!0})}async setState(t,e){let r=[{path:e||u,state:t}];try{this.options.lifecycleHooks?.beforeAll?.(r);let a={value:!1};for(let o of r){if(a.value)break;let s=await this.applyMiddleware(o.state,o.path,a);a.value||this.updateState(s,o.path)}this.options.lifecycleHooks?.afterAll?.(r),this.notifySubscribers()}catch(a){this.handleError(a,{action:"batchUpdate",state:r})}}updateState(t,e){let i=(r,a)=>{typeof a=="object"&&a!==null&&!Array.isArray(a)?Object.entries(a).forEach(([o,s])=>{i(`${r}/${o}`,s)}):this.manager.update(r,a,{force:!0})};Object.entries(t).forEach(([r,a])=>{let o=e===u?`${u}/${r}`:`${e}/${r}`;i(o,a)})}handleError(t,e){this.options.error?.onError&&this.options.error.onError(t,e)}getState(){return this.manager.store().map("key")[u]}getValidationResult(){return this.lastValidationResult}subscribe(t){return this.subscribers.add(t),()=>{this.subscribers.delete(t)}}notifySubscribers(){this.subscribers.forEach(t=>t())}select(t,e){let i=[],r=this.manager;function a(o){let s={get:(c,d)=>{let l=`${o}/${d}`;return r.exists(l)&&i.push(l),a(l)}};return new Proxy({},s)}return t(a(u)),r.subscribe({event:"node",path:i},()=>{e(t(this.getState()))})}getTree(){return this.manager.store().serialize()}};var v=class{metrics={updates:0,subscriptionTriggers:0,middlewareExecutions:0,batchSize:0,lastUpdateDuration:0};enableMetrics;constructor(t=!1){this.enableMetrics=t}track(t,e){if(!this.enableMetrics)return e();let i=performance.now();try{let r=e();return this.recordMetric(t,performance.now()-i),r}catch(r){throw this.recordError(t,r),r}}recordMetric(t,e){switch(t){case"update":this.metrics.updates++,this.metrics.lastUpdateDuration=e;break;case"subscription":this.metrics.subscriptionTriggers++;break;case"middleware":this.metrics.middlewareExecutions++;break}}recordError(t,e){console.error(`Error in ${t}:`,e)}getMetrics(){return{...this.metrics}}reset(){this.metrics={updates:0,subscriptionTriggers:0,middlewareExecutions:0,batchSize:0,lastUpdateDuration:0}}},y=class{selectorCache=new WeakMap;create(t){return e=>{let i=this.selectorCache.get(t);i||(i=new WeakMap,this.selectorCache.set(t,i));let r=i.get(e);if(r)return r.result;let a=t(e);return i.set(e,{result:a,deps:[]}),a}}};function x(n,t={}){let e=new h(n,t),i=new y,r=new v(t.enableMetrics),a=Object.entries(n.actions).reduce((o,[s,c])=>(o[s]=async(...d)=>{try{return await r.track("update",async()=>{let l=await c(e.getState(),...d);return e.setState(l),l})}catch(l){throw console.error(`Error in action ${s}:`,l),l}},o),{});return function(){return{select:(0,g.useCallback)(c=>{let d=i.create(c);return(0,g.useSyncExternalStore)(l=>r.track("subscription",()=>e.select(d,l)),()=>d(e.getState()),()=>d(e.getState()))},[]),actions:a,getState:()=>e.getState(),getTree:()=>e.getTree(),getMetrics:()=>r.getMetrics(),resetMetrics:()=>r.reset()}}}0&&(module.exports={StateManager,createStore});
1
+ "use strict";var m=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var M=(c,t)=>{for(var e in t)m(c,e,{get:t[e],enumerable:!0})},E=(c,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of b(t))!T.call(c,r)&&r!==e&&m(c,r,{get:()=>t[r],enumerable:!(i=w(t,r))||i.enumerable});return c};var k=c=>E(m({},"__esModule",{value:!0}),c);var R={};M(R,{StateManager:()=>u,createStore:()=>x});module.exports=k(R);var g=require("react");var S=require("@asaidimu/node");var p=class{cache=new Map;maxSize;maxAge;constructor(t=100,e=5e3){this.maxSize=t,this.maxAge=e}get(t){let e=this.cache.get(t);if(e){if(Date.now()-e.timestamp>this.maxAge){this.cache.delete(t);return}return e.value}}set(t,e){if(this.cache.size>=this.maxSize){let i=Array.from(this.cache.entries()).sort(([,r],[,a])=>r.timestamp-a.timestamp)[0][0];this.cache.delete(i)}this.cache.set(t,{value:e,timestamp:Date.now()})}clear(){this.cache.clear()}};var f=class{validation;constructor(t={}){this.validation=t}validate(t,e){let i=[],r=e.split("/").pop(),a=this.validation[r];return a?(a.forEach((o,s)=>{try{o.validate(t[r])||i.push(o.message||`Validation failed for ${String(r)} at rule ${s}`)}catch(n){i.push(`Validation error at ${e}: ${n.message}`)}}),{valid:i.length===0,errors:i}):{valid:!0,errors:[]}}};var h="root",u=class{manager;subscribers=new Set;middleware;options;definition;middlewareCache;validator;lastValidationResult={valid:!0,errors:[]};constructor(t,e={}){this.definition=t,this.options=e,this.middleware=this.sortMiddleware(e.middleware||[]),this.middlewareCache=new p,this.validator=new f(e.validation),this.manager=this.initializeManager()}sortMiddleware(t){let e=new Map;t.forEach(s=>{e.set(s.id,new Set(s.dependencies||[]))});let i=[],r=new Set,a=new Set,o=s=>{if(a.has(s))throw new Error(`Circular dependency found: ${s}`);if(r.has(s))return;a.add(s),(e.get(s)||new Set).forEach(d=>o(d)),a.delete(s),r.add(s),i.push(t.find(d=>d.id===s))};return t.forEach(s=>{r.has(s.id)||o(s.id)}),i.sort((s,n)=>(n.priority||0)-(s.priority||0))}initializeManager(){let t=(0,S.createNodeManager)();t.add(h,null,{key:h});let e=(i=h,r=this.definition.state)=>{for(let[a,o]of Object.entries(r))o&&typeof o=="object"&&!Array.isArray(o)?(t.add(`${i}/${a}`,o,{key:a}),e(`${i}/${a}`,o)):t.add(`${i}/${a}`,o,{key:a})};if(e(),this.definition.sync){let i=this.getState.bind(this);t.subscribe("node",()=>{this.definition.sync(i())})}return t}async applyMiddleware(t,e,i={value:!1}){let r=`${e}-${JSON.stringify(t)}`,a=this.middlewareCache.get(r);if(a)return a;if(this.lastValidationResult=this.validator.validate(t,e),!this.lastValidationResult.valid)throw new Error(`Validation failed: ${this.lastValidationResult.errors.join(", ")}`);let o={fullState:this.getState(),path:e,abortUpdate:()=>{i.value=!0},getValidationResult:()=>this.lastValidationResult};try{let s=t;for(let n of this.middleware){if(i.value)throw new Error("Update aborted by middleware");if(s=await Promise.resolve(n.transform(s,o)),this.lastValidationResult=this.validator.validate(s,e),!this.lastValidationResult.valid)throw new Error(`Validation failed after middleware ${n.id}: ${this.lastValidationResult.errors.join(", ")}`)}return this.middlewareCache.set(r,s),s}catch(s){throw this.handleMiddlewareError(s,t,e),s}}handleMiddlewareError(t,e,i){if(this.options.error?.onError&&this.options.error.onError(t,{action:"applyMiddleware",state:e,path:i,error:t}),this.options.error?.recovery)switch(this.middlewareCache.clear(),this.options.error.recovery.strategy){case"retry":break;case"revert":this.revertState(i);break;case"ignore":break}}revertState(t){let e=this.getState(),i=t.split("/"),r=e;for(let o=1;o<i.length-1;o++)r=r[i[o]];let a=i[i.length-1];this.manager.update(t,r[a],{force:!0})}async setState(t,e){let r=[{path:e||h,state:t}];try{this.options.lifecycleHooks?.beforeAll?.(r);let a={value:!1};for(let o of r){if(a.value)break;let s=Object.assign({},this.getState(),o.state),n=await this.applyMiddleware(s,o.path,a);a.value||this.updateState(n,o.path)}this.options.lifecycleHooks?.afterAll?.(r),this.notifySubscribers()}catch(a){this.handleError(a,{action:"batchUpdate",state:r})}}updateState(t,e){let i=(r,a,o)=>{typeof a=="object"&&a!==null&&!Array.isArray(a)?Object.entries(a).forEach(([s,n])=>{i(`${r}/${s}`,n,s)}):this.manager.update(r,a,{metadata:{key:o},force:!0})};Object.entries(t).forEach(([r,a])=>{let o=e===h?`${h}/${r}`:`${e}/${r}`;i(o,a,r)})}handleError(t,e){this.options.error?.onError&&this.options.error.onError(t,e)}getState(){return this.manager.store().map("key")[h]}getValidationResult(){return this.lastValidationResult}subscribe(t){return this.subscribers.add(t),()=>{this.subscribers.delete(t)}}notifySubscribers(){this.subscribers.forEach(t=>t())}select(t,e){let i=[],r=this.manager;function a(o){let s={get:(n,d)=>{let l=`${o}/${d}`;return i.push(l),a(l)}};return new Proxy({},s)}return t(a(h)),r.subscribe({event:"node",path:i},()=>{e(t(this.getState()))})}getTree(){return this.manager.store().serialize()}};var v=class{metrics={updates:0,subscriptionTriggers:0,middlewareExecutions:0,batchSize:0,lastUpdateDuration:0};enableMetrics;constructor(t=!1){this.enableMetrics=t}track(t,e){if(!this.enableMetrics)return e();let i=performance.now();try{let r=e();return this.recordMetric(t,performance.now()-i),r}catch(r){throw this.recordError(t,r),r}}recordMetric(t,e){switch(t){case"update":this.metrics.updates++,this.metrics.lastUpdateDuration=e;break;case"subscription":this.metrics.subscriptionTriggers++;break;case"middleware":this.metrics.middlewareExecutions++;break}}recordError(t,e){console.error(`Error in ${t}:`,e)}getMetrics(){return{...this.metrics}}reset(){this.metrics={updates:0,subscriptionTriggers:0,middlewareExecutions:0,batchSize:0,lastUpdateDuration:0}}},y=class{selectorCache=new WeakMap;create(t){return e=>{let i=this.selectorCache.get(t);i||(i=new WeakMap,this.selectorCache.set(t,i));let r=i.get(e);if(r)return r.result;let a=t(e);return i.set(e,{result:a,deps:[]}),a}}};function x(c,t={}){let e=new u(c,t),i=new y,r=new v(t.enableMetrics),a=Object.entries(c.actions).reduce((o,[s,n])=>(o[s]=async(...d)=>{try{return await r.track("update",async()=>{let l=await n(e.getState(),...d);return e.setState(l),l})}catch(l){throw console.error(`Error in action ${s}:`,l),l}},o),{});return function(){return{select:(0,g.useCallback)(n=>{let d=i.create(n);return(0,g.useSyncExternalStore)(l=>r.track("subscription",()=>e.select(d,l)),()=>d(e.getState()),()=>d(e.getState()))},[]),actions:a,getState:()=>e.getState(),getTree:()=>e.getTree(),getMetrics:()=>r.getMetrics(),resetMetrics:()=>r.reset()}}}0&&(module.exports={StateManager,createStore});
package/index.js CHANGED
@@ -1 +1 @@
1
- import{useCallback as y,useSyncExternalStore as S}from"react";import{createNodeManager as v}from"@asaidimu/node";var h=class{cache=new Map;maxSize;maxAge;constructor(t=100,e=5e3){this.maxSize=t,this.maxAge=e}get(t){let e=this.cache.get(t);if(e){if(Date.now()-e.timestamp>this.maxAge){this.cache.delete(t);return}return e.value}}set(t,e){if(this.cache.size>=this.maxSize){let i=Array.from(this.cache.entries()).sort(([,r],[,a])=>r.timestamp-a.timestamp)[0][0];this.cache.delete(i)}this.cache.set(t,{value:e,timestamp:Date.now()})}clear(){this.cache.clear()}};var p=class{validation;constructor(t={}){this.validation=t}validate(t,e){let i=[],r=e.split("/").pop(),a=this.validation[r];return a?(a.forEach((o,s)=>{try{o.validate(t[r])||i.push(o.message||`Validation failed for ${String(r)} at rule ${s}`)}catch(n){i.push(`Validation error at ${e}: ${n.message}`)}}),{valid:i.length===0,errors:i}):{valid:!0,errors:[]}}};var l="root",f=class{manager;subscribers=new Set;middleware;options;definition;middlewareCache;validator;lastValidationResult={valid:!0,errors:[]};constructor(t,e={}){this.definition=t,this.options=e,this.middleware=this.sortMiddleware(e.middleware||[]),this.middlewareCache=new h,this.validator=new p(e.validation),this.manager=this.initializeManager()}sortMiddleware(t){let e=new Map;t.forEach(s=>{e.set(s.id,new Set(s.dependencies||[]))});let i=[],r=new Set,a=new Set,o=s=>{if(a.has(s))throw new Error(`Circular dependency found: ${s}`);if(r.has(s))return;a.add(s),(e.get(s)||new Set).forEach(c=>o(c)),a.delete(s),r.add(s),i.push(t.find(c=>c.id===s))};return t.forEach(s=>{r.has(s.id)||o(s.id)}),i.sort((s,n)=>(n.priority||0)-(s.priority||0))}initializeManager(){let t=v();t.add(l,null,{key:l});let e=(i=l,r=this.definition.state)=>{for(let[a,o]of Object.entries(r))typeof o=="object"&&!Array.isArray(o)?(t.add(`${i}/${a}`,o,{key:a}),e(`${i}/${a}`,o)):t.add(`${i}/${a}`,o,{key:a})};if(e(),this.definition.sync){let i=this.getState.bind(this);t.subscribe("node",()=>{this.definition.sync(i())})}return t}async applyMiddleware(t,e,i={value:!1}){let r=`${e}-${JSON.stringify(t)}`,a=this.middlewareCache.get(r);if(a)return a;if(this.lastValidationResult=this.validator.validate(t,e),!this.lastValidationResult.valid)throw new Error(`Validation failed: ${this.lastValidationResult.errors.join(", ")}`);let o={fullState:this.getState(),path:e,abortUpdate:()=>{i.value=!0},getValidationResult:()=>this.lastValidationResult};try{let s=t;for(let n of this.middleware){if(i.value)throw new Error("Update aborted by middleware");if(s=await Promise.resolve(n.transform(s,o)),this.lastValidationResult=this.validator.validate(s,e),!this.lastValidationResult.valid)throw new Error(`Validation failed after middleware ${n.id}: ${this.lastValidationResult.errors.join(", ")}`)}return this.middlewareCache.set(r,s),s}catch(s){throw this.handleMiddlewareError(s,t,e),s}}handleMiddlewareError(t,e,i){if(this.options.error?.onError&&this.options.error.onError(t,{action:"applyMiddleware",state:e,path:i,error:t}),this.options.error?.recovery)switch(this.middlewareCache.clear(),this.options.error.recovery.strategy){case"retry":break;case"revert":this.revertState(i);break;case"ignore":break}}revertState(t){let e=this.getState(),i=t.split("/"),r=e;for(let o=1;o<i.length-1;o++)r=r[i[o]];let a=i[i.length-1];this.manager.update(t,r[a],{force:!0})}async setState(t,e){let r=[{path:e||l,state:t}];try{this.options.lifecycleHooks?.beforeAll?.(r);let a={value:!1};for(let o of r){if(a.value)break;let s=await this.applyMiddleware(o.state,o.path,a);a.value||this.updateState(s,o.path)}this.options.lifecycleHooks?.afterAll?.(r),this.notifySubscribers()}catch(a){this.handleError(a,{action:"batchUpdate",state:r})}}updateState(t,e){let i=(r,a)=>{typeof a=="object"&&a!==null&&!Array.isArray(a)?Object.entries(a).forEach(([o,s])=>{i(`${r}/${o}`,s)}):this.manager.update(r,a,{force:!0})};Object.entries(t).forEach(([r,a])=>{let o=e===l?`${l}/${r}`:`${e}/${r}`;i(o,a)})}handleError(t,e){this.options.error?.onError&&this.options.error.onError(t,e)}getState(){return this.manager.store().map("key")[l]}getValidationResult(){return this.lastValidationResult}subscribe(t){return this.subscribers.add(t),()=>{this.subscribers.delete(t)}}notifySubscribers(){this.subscribers.forEach(t=>t())}select(t,e){let i=[],r=this.manager;function a(o){let s={get:(n,c)=>{let d=`${o}/${c}`;return r.exists(d)&&i.push(d),a(d)}};return new Proxy({},s)}return t(a(l)),r.subscribe({event:"node",path:i},()=>{e(t(this.getState()))})}getTree(){return this.manager.store().serialize()}};var g=class{metrics={updates:0,subscriptionTriggers:0,middlewareExecutions:0,batchSize:0,lastUpdateDuration:0};enableMetrics;constructor(t=!1){this.enableMetrics=t}track(t,e){if(!this.enableMetrics)return e();let i=performance.now();try{let r=e();return this.recordMetric(t,performance.now()-i),r}catch(r){throw this.recordError(t,r),r}}recordMetric(t,e){switch(t){case"update":this.metrics.updates++,this.metrics.lastUpdateDuration=e;break;case"subscription":this.metrics.subscriptionTriggers++;break;case"middleware":this.metrics.middlewareExecutions++;break}}recordError(t,e){console.error(`Error in ${t}:`,e)}getMetrics(){return{...this.metrics}}reset(){this.metrics={updates:0,subscriptionTriggers:0,middlewareExecutions:0,batchSize:0,lastUpdateDuration:0}}},m=class{selectorCache=new WeakMap;create(t){return e=>{let i=this.selectorCache.get(t);i||(i=new WeakMap,this.selectorCache.set(t,i));let r=i.get(e);if(r)return r.result;let a=t(e);return i.set(e,{result:a,deps:[]}),a}}};function V(u,t={}){let e=new f(u,t),i=new m,r=new g(t.enableMetrics),a=Object.entries(u.actions).reduce((o,[s,n])=>(o[s]=async(...c)=>{try{return await r.track("update",async()=>{let d=await n(e.getState(),...c);return e.setState(d),d})}catch(d){throw console.error(`Error in action ${s}:`,d),d}},o),{});return function(){return{select:y(n=>{let c=i.create(n);return S(d=>r.track("subscription",()=>e.select(c,d)),()=>c(e.getState()),()=>c(e.getState()))},[]),actions:a,getState:()=>e.getState(),getTree:()=>e.getTree(),getMetrics:()=>r.getMetrics(),resetMetrics:()=>r.reset()}}}export{f as StateManager,V as createStore};
1
+ import{useCallback as y,useSyncExternalStore as S}from"react";import{createNodeManager as v}from"@asaidimu/node";var u=class{cache=new Map;maxSize;maxAge;constructor(t=100,e=5e3){this.maxSize=t,this.maxAge=e}get(t){let e=this.cache.get(t);if(e){if(Date.now()-e.timestamp>this.maxAge){this.cache.delete(t);return}return e.value}}set(t,e){if(this.cache.size>=this.maxSize){let i=Array.from(this.cache.entries()).sort(([,r],[,a])=>r.timestamp-a.timestamp)[0][0];this.cache.delete(i)}this.cache.set(t,{value:e,timestamp:Date.now()})}clear(){this.cache.clear()}};var p=class{validation;constructor(t={}){this.validation=t}validate(t,e){let i=[],r=e.split("/").pop(),a=this.validation[r];return a?(a.forEach((o,s)=>{try{o.validate(t[r])||i.push(o.message||`Validation failed for ${String(r)} at rule ${s}`)}catch(n){i.push(`Validation error at ${e}: ${n.message}`)}}),{valid:i.length===0,errors:i}):{valid:!0,errors:[]}}};var l="root",f=class{manager;subscribers=new Set;middleware;options;definition;middlewareCache;validator;lastValidationResult={valid:!0,errors:[]};constructor(t,e={}){this.definition=t,this.options=e,this.middleware=this.sortMiddleware(e.middleware||[]),this.middlewareCache=new u,this.validator=new p(e.validation),this.manager=this.initializeManager()}sortMiddleware(t){let e=new Map;t.forEach(s=>{e.set(s.id,new Set(s.dependencies||[]))});let i=[],r=new Set,a=new Set,o=s=>{if(a.has(s))throw new Error(`Circular dependency found: ${s}`);if(r.has(s))return;a.add(s),(e.get(s)||new Set).forEach(c=>o(c)),a.delete(s),r.add(s),i.push(t.find(c=>c.id===s))};return t.forEach(s=>{r.has(s.id)||o(s.id)}),i.sort((s,n)=>(n.priority||0)-(s.priority||0))}initializeManager(){let t=v();t.add(l,null,{key:l});let e=(i=l,r=this.definition.state)=>{for(let[a,o]of Object.entries(r))o&&typeof o=="object"&&!Array.isArray(o)?(t.add(`${i}/${a}`,o,{key:a}),e(`${i}/${a}`,o)):t.add(`${i}/${a}`,o,{key:a})};if(e(),this.definition.sync){let i=this.getState.bind(this);t.subscribe("node",()=>{this.definition.sync(i())})}return t}async applyMiddleware(t,e,i={value:!1}){let r=`${e}-${JSON.stringify(t)}`,a=this.middlewareCache.get(r);if(a)return a;if(this.lastValidationResult=this.validator.validate(t,e),!this.lastValidationResult.valid)throw new Error(`Validation failed: ${this.lastValidationResult.errors.join(", ")}`);let o={fullState:this.getState(),path:e,abortUpdate:()=>{i.value=!0},getValidationResult:()=>this.lastValidationResult};try{let s=t;for(let n of this.middleware){if(i.value)throw new Error("Update aborted by middleware");if(s=await Promise.resolve(n.transform(s,o)),this.lastValidationResult=this.validator.validate(s,e),!this.lastValidationResult.valid)throw new Error(`Validation failed after middleware ${n.id}: ${this.lastValidationResult.errors.join(", ")}`)}return this.middlewareCache.set(r,s),s}catch(s){throw this.handleMiddlewareError(s,t,e),s}}handleMiddlewareError(t,e,i){if(this.options.error?.onError&&this.options.error.onError(t,{action:"applyMiddleware",state:e,path:i,error:t}),this.options.error?.recovery)switch(this.middlewareCache.clear(),this.options.error.recovery.strategy){case"retry":break;case"revert":this.revertState(i);break;case"ignore":break}}revertState(t){let e=this.getState(),i=t.split("/"),r=e;for(let o=1;o<i.length-1;o++)r=r[i[o]];let a=i[i.length-1];this.manager.update(t,r[a],{force:!0})}async setState(t,e){let r=[{path:e||l,state:t}];try{this.options.lifecycleHooks?.beforeAll?.(r);let a={value:!1};for(let o of r){if(a.value)break;let s=Object.assign({},this.getState(),o.state),n=await this.applyMiddleware(s,o.path,a);a.value||this.updateState(n,o.path)}this.options.lifecycleHooks?.afterAll?.(r),this.notifySubscribers()}catch(a){this.handleError(a,{action:"batchUpdate",state:r})}}updateState(t,e){let i=(r,a,o)=>{typeof a=="object"&&a!==null&&!Array.isArray(a)?Object.entries(a).forEach(([s,n])=>{i(`${r}/${s}`,n,s)}):this.manager.update(r,a,{metadata:{key:o},force:!0})};Object.entries(t).forEach(([r,a])=>{let o=e===l?`${l}/${r}`:`${e}/${r}`;i(o,a,r)})}handleError(t,e){this.options.error?.onError&&this.options.error.onError(t,e)}getState(){return this.manager.store().map("key")[l]}getValidationResult(){return this.lastValidationResult}subscribe(t){return this.subscribers.add(t),()=>{this.subscribers.delete(t)}}notifySubscribers(){this.subscribers.forEach(t=>t())}select(t,e){let i=[],r=this.manager;function a(o){let s={get:(n,c)=>{let d=`${o}/${c}`;return i.push(d),a(d)}};return new Proxy({},s)}return t(a(l)),r.subscribe({event:"node",path:i},()=>{e(t(this.getState()))})}getTree(){return this.manager.store().serialize()}};var g=class{metrics={updates:0,subscriptionTriggers:0,middlewareExecutions:0,batchSize:0,lastUpdateDuration:0};enableMetrics;constructor(t=!1){this.enableMetrics=t}track(t,e){if(!this.enableMetrics)return e();let i=performance.now();try{let r=e();return this.recordMetric(t,performance.now()-i),r}catch(r){throw this.recordError(t,r),r}}recordMetric(t,e){switch(t){case"update":this.metrics.updates++,this.metrics.lastUpdateDuration=e;break;case"subscription":this.metrics.subscriptionTriggers++;break;case"middleware":this.metrics.middlewareExecutions++;break}}recordError(t,e){console.error(`Error in ${t}:`,e)}getMetrics(){return{...this.metrics}}reset(){this.metrics={updates:0,subscriptionTriggers:0,middlewareExecutions:0,batchSize:0,lastUpdateDuration:0}}},m=class{selectorCache=new WeakMap;create(t){return e=>{let i=this.selectorCache.get(t);i||(i=new WeakMap,this.selectorCache.set(t,i));let r=i.get(e);if(r)return r.result;let a=t(e);return i.set(e,{result:a,deps:[]}),a}}};function V(h,t={}){let e=new f(h,t),i=new m,r=new g(t.enableMetrics),a=Object.entries(h.actions).reduce((o,[s,n])=>(o[s]=async(...c)=>{try{return await r.track("update",async()=>{let d=await n(e.getState(),...c);return e.setState(d),d})}catch(d){throw console.error(`Error in action ${s}:`,d),d}},o),{});return function(){return{select:y(n=>{let c=i.create(n);return S(d=>r.track("subscription",()=>e.select(c,d)),()=>c(e.getState()),()=>c(e.getState()))},[]),actions:a,getState:()=>e.getState(),getTree:()=>e.getTree(),getMetrics:()=>r.getMetrics(),resetMetrics:()=>r.reset()}}}export{f as StateManager,V as createStore};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/react-store",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
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/events": "^1.0.0",
30
- "@asaidimu/node": "^1.0.5",
30
+ "@asaidimu/node": "^1.0.6",
31
31
  "react": "^19.0.0"
32
32
  }
33
33
  }