fluent-state
Version:
Fluent, immutable, deeply reactive state for React — powered by Proxies and fine-grained tracking
3 lines (2 loc) • 2.41 kB
JavaScript
import{useRef as t,useEffect as r,useState as e,useCallback as n,useMemo as c}from"react";function o(t,r){return t.reduce((t,r)=>t?.[r],r)}function i(t,r,e){if(0===t.length)return e;const[n,...c]=t,o=r?.[n],u=i(c,o,e);if(Object.is(o,u))return r;if(Array.isArray(r)){const t=[...r];return t[n]=u,t}return{...r,[n]:u}}class u{_state;_proxy;_onChange;proxyCache=new Map;currentExecutionStack;constructor(t,r){this._state=t,this.currentExecutionStack=void 0,this.proxyCache=new Map,this._onChange=r,this._proxy=this.createProxy()}getState(){return this._state}getProxy(){return this._proxy}createProxy(t=[]){const r=t.join(".");if(this.proxyCache.has(r))return this.proxyCache.get(r);const e=(...r)=>{if(0===r.length)return void 0!==this.currentExecutionStack&&this.currentExecutionStack.add([...t].join(".")),o(t,this._state);{const[e]=r,n=o(t,this._state),c="function"==typeof e?e(n):e;Object.is(n,c)||(this._state=i(t,this._state,c),this._onChange())}},n=new Proxy(e,{get:(r,n)=>"symbol"==typeof n?Reflect.get(e,n):this.createProxy([...t,String(n)])});return this.proxyCache.set(r,n),n}}const s=(e,n)=>{const c=t(new Set),i=t(void 0),u=t(!1),s=t(n);s.current=n,r(()=>{if(!u.current){c.current.clear(),e.currentExecutionStack=c.current;try{s.current()}finally{e.currentExecutionStack=void 0,u.current=!0}i.current=e.getState()}},[]),r(()=>{const t=e.getState(),r=i.current;if(r)for(const e of c.current){const n=e.split("."),c=o(n,r),u=o(n,t);if(!Object.is(c,u))return i.current=t,void s.current()}})};const a=(n,c)=>{const[,i]=e(0),u=t(new Set),s=t(void 0),a=t(!1),h=t(void 0),f=t(c);return f.current=c,r(()=>{if(!a.current){u.current.clear(),n.currentExecutionStack=u.current;try{h.current=f.current()}finally{n.currentExecutionStack=void 0,a.current=!0}s.current=n.getState()}},[]),r(()=>{const t=n.getState(),r=s.current;if(!r)return;let e=!1;for(const n of u.current){const c=n.split("."),i=o(c,r),u=o(c,t);if(!Object.is(i,u)){e=!0;break}}e&&(h.current=f.current(),s.current=t,i(t=>t+1))}),()=>h.current};function h(r){if("object"!=typeof r||null===r)throw new Error("useFluentState requires an initial state of type object or array");const[,o]=e(0),i=n(()=>{o(t=>t+1)},[]),h=c(()=>new u(r,i),[]),f=h.getProxy(),y=t((x=h,t=>s(x,t)));var x;const l=t(function(t){return r=>a(t,r)}(h));return[f,y.current,l.current]}export{u as FluentProxy,o as getValue,h as useFluentState};
//# sourceMappingURL=index.esm.js.map