@statx/core
Advanced tools
| var e=void 0;let r,n=!1;const s="Unnamed state",t=new Set,o=[],i=new Set,a=e=>e.history[e.historyCursor],c=(e,r)=>{e.historyCursor=(e.historyCursor+1)%e.history.length,e.history[e.historyCursor]=r},d=e=>e&&t.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),s):e||s,u=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,l=e=>{try{const n=a(e);if(((e,r)=>!1===e.hasParentUpdates&&void 0!==r)(e,n))return r&&e.depends.forEach(e=>{r?.add(e)}),n;g(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),o.push(e),e.depends.forEach(r=>{r.childs.delete(e)}),e.depends.clear(),e.isComputing=!0;const s=e.reducer(n??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,o.pop(),c(e,s),s}catch(e){return void console.error(e.message)}},p=e=>{const n=u(e);try{const s=o.at(-1);return s&&!e.childs.has(s)&&(e.childs.add(s),s.depends.add(e)),n?l(n):a(e)}finally{r&&!n&&r.add(e)}},f=(e,r)=>{const n=h(r)?((e,r)=>r(a(e)))(e,r):r;n!==a(e)&&(c(e,n),b(e),m())},b=e=>{const r=[e];for(;r.length;){const e=r.pop();e.childs.forEach(e=>r.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&i.add(e)}},m=()=>{!1===n&&(n=!0,queueMicrotask(()=>{i.forEach(e=>{try{e.subscribes.forEach(r=>r(p(e)))}catch(r){console.error("Error in subscriber function of:",e.name)}}),i.clear(),n=!1}))},y=()=>{r=new Set},w=()=>{const e=r;return r=void 0,e},C=(e,r)=>{if(e.subscribes.has(r))return()=>({});const n=u(e);return n&&(l(n),e.depends.forEach(r=>r.childs.add(e))),e.subscribes.add(r),()=>{e.subscribes.delete(r),0===e.subscribes.size&&e.depends.forEach(r=>r.childs.delete(e))}},g=(e,r)=>{if(e)throw new Error(r)};function E(e,r){g(h(e),"Function not allowed in state");const n={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:-1,name:d(r?.name),subscribes:new Set,hasParentUpdates:void 0};f(n,e);const s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>C(n,e),s.set=e=>f(n,e),s._internal=n,s}const S=(e,r)=>{const n={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:-1,initial:r?.initial,isComputing:!1,name:d(r?.name),reducer:e,subscribes:new Set},s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>C(n,e),s._internal=n,s},v=(r,n)=>({run:function(){return r(...[].slice.call(arguments)),e},name:d(n?.name),onAction:n?.onAction});export{v as action,S as computed,w as flushStates,y as startRecord,E as state,C as subscribe}; | ||
| //# sourceMappingURL=index.modern.js.map |
| {"version":3,"file":"index.modern.js","sources":["../src/core.ts"],"sourcesContent":["import {\r\n ComputedInternal,\r\n Listner,\r\n StateType,\r\n Settings,\r\n StateVariants,\r\n Action,\r\n Options,\r\n ComputedInternalOptions,\r\n Nullable,\r\n StatlessFunc,\r\n GetStatlessFunc,\r\n HistoryInternal,\r\n State,\r\n Computed,\r\n Func,\r\n UnSubscribe,\r\n CommonInternal,\r\n StateInternal,\r\n SetterFunc,\r\n ActionOptions,\r\n} from './types.js'\r\n\r\nlet isNotifying = false\r\nlet isActionNow = false\r\nlet recording: Set<StateInternal> | undefined\r\n\r\nconst defaultName = 'Unnamed state'\r\nconst names = new Set()\r\nconst requesters: ComputedInternal[] = []\r\nconst states2notify = new Set<StateVariants>()\r\nconst settings: Settings = {\r\n historyLength: 5,\r\n}\r\n\r\nexport const getHistoryValue = (state: StateVariants): unknown => {\r\n return state.history[state.historyCursor]\r\n}\r\nconst pushHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\r\n state.history[state.historyCursor] = value\r\n}\r\n\r\nconst getName = (name?: string): string => {\r\n if (name && names.has(name)) {\r\n console.error(`Name ${name} already used! Replaced to undefined`)\r\n return defaultName\r\n }\r\n if (name) {\r\n return name\r\n }\r\n return defaultName\r\n}\r\n\r\nexport const setSetting = (data: Partial<Settings>) => {\r\n Object.assign(settings, data)\r\n}\r\n\r\nconst getComputed = (state: CommonInternal | ComputedInternal) => {\r\n if ('reducer' in state) {\r\n return state\r\n }\r\n}\r\n\r\nconst isFunction = (v: unknown): v is Func => {\r\n return typeof v === 'function'\r\n}\r\n\r\nconst isDontNeedRecalc = (state: CommonInternal, prevState: unknown): boolean => {\r\n return state.hasParentUpdates === false && prevState !== undefined\r\n}\r\n\r\nconst getComputedValue = (state: ComputedInternal): unknown => {\r\n try {\r\n const prevState = getHistoryValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n state.depends.forEach((item) => {\r\n item.childs.delete(state)\r\n })\r\n state.depends.clear()\r\n state.isComputing = true\r\n const value = state.reducer(prevState ?? state.initial)\r\n state.isComputing = false\r\n state.hasParentUpdates = false\r\n\r\n requesters.pop()\r\n pushHistory(state, value)\r\n\r\n return value\r\n } catch (e) {\r\n console.error((e as Error).message)\r\n return undefined\r\n }\r\n}\r\n\r\nconst getValue = (state: CommonInternal) => {\r\n const reducer = getComputed(state)\r\n try {\r\n const lastRequester = requesters.at(-1)\r\n if (lastRequester && !state.childs.has(lastRequester)) {\r\n state.childs.add(lastRequester)\r\n lastRequester.depends.add(state)\r\n }\r\n if (reducer) {\r\n return getComputedValue(reducer)\r\n }\r\n return getHistoryValue(state)\r\n } finally {\r\n if (recording && !reducer) {\r\n recording.add(state)\r\n }\r\n }\r\n}\r\n\r\nconst getValueOfSetterFunction = (state: CommonInternal, value: SetterFunc): unknown => {\r\n const prevValue = getHistoryValue(state)\r\n return value(prevValue)\r\n}\r\n\r\nconst setValue = (state: CommonInternal, value: unknown): void => {\r\n const newValue = isFunction(value) ? getValueOfSetterFunction(state, value) : value\r\n\r\n if (newValue === getHistoryValue(state)) {\r\n return\r\n }\r\n pushHistory(state, newValue)\r\n invalidateSubtree(state)\r\n notifySubscribers()\r\n}\r\n\r\n/**\r\n * Mark all subtree is non actual.\r\n * Collect all nodes to notify subscribers im microtask queue.\r\n */\r\nconst invalidateSubtree = (state: CommonInternal) => {\r\n const stack: CommonInternal[] = [state]\r\n\r\n while (stack.length) {\r\n const st = stack.pop()\r\n st.childs.forEach((it) => stack.push(it))\r\n st.hasParentUpdates = true\r\n if (st.subscribes.size) {\r\n states2notify.add(st)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all collected subscribers once in microtask queue\r\n */\r\nconst notifySubscribers = () => {\r\n if (isNotifying === false) {\r\n isNotifying = true\r\n queueMicrotask(() => {\r\n // Нужно обновить дерево\r\n states2notify.forEach((state) => {\r\n try {\r\n state.subscribes.forEach((listner) => {\r\n return listner(getValue(state))\r\n })\r\n } catch (e) {\r\n console.error('Error in subscriber function of:', state.name)\r\n }\r\n })\r\n states2notify.clear()\r\n isNotifying = false\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * Start collecting all non computed states.\r\n *\r\n * Helper for render adapters.\r\n */\r\nexport const startRecord = () => {\r\n recording = new Set()\r\n}\r\n\r\n/**\r\n * Flush all collected non computed states.\r\n */\r\nexport const flushStates = (): Set<StateInternal> => {\r\n const data = recording\r\n recording = undefined\r\n return data\r\n}\r\n\r\nexport const subscribe = (state: CommonInternal | CommonInternal, listner: Listner): UnSubscribe => {\r\n /**\r\n * Если значение стейта ниразу не расчитывалось, его нужно обновить\r\n * Если подписываемся на вычисляемый стэйт, то нужно узнать всех родителей\r\n * Родители могут меняться, поэтому после каждого вычисления нужно обновлять зависимости дерева\r\n *\r\n * При отписке нужно оповестить всех на кого были опдписанты о том что мы отписались\r\n *\r\n */\r\n\r\n if (state.subscribes.has(listner)) {\r\n return () => ({})\r\n }\r\n\r\n const computedState = getComputed(state)\r\n // Нужно актуализировать в родилеях зависимость\r\n if (computedState) {\r\n getComputedValue(computedState)\r\n state.depends.forEach((parent) => parent.childs.add(state))\r\n }\r\n\r\n state.subscribes.add(listner)\r\n\r\n return () => {\r\n state.subscribes.delete(listner)\r\n if (state.subscribes.size === 0) {\r\n state.depends.forEach((parent) => parent.childs.delete(state))\r\n }\r\n }\r\n}\r\n\r\nconst assert = (condtion: boolean, msg: string) => {\r\n if (condtion) {\r\n throw new Error(msg)\r\n }\r\n}\r\n\r\n/**\r\n *\r\n * @param value - Reducer or value\r\n * @param name - name of state. For loggin or easy debug\r\n * @returns State<T>\r\n */\r\nexport function state<T extends StateType = StateType>(value: T, options?: Options): State<T> {\r\n assert(isFunction(value), 'Function not allowed in state')\r\n\r\n const data: CommonInternal = {\r\n childs: new Set(),\r\n depends: new Set(),\r\n history: Array.from({length: settings.historyLength}),\r\n historyCursor: -1,\r\n name: getName(options?.name),\r\n subscribes: new Set(),\r\n hasParentUpdates: undefined,\r\n }\r\n\r\n setValue(data, value)\r\n\r\n const publicApi = function () {\r\n return getValue(data)\r\n }\r\n\r\n Object.defineProperty(publicApi, 'name', {value: data.name})\r\n publicApi.subscribe = (listner: Listner) => subscribe(data, listner)\r\n publicApi.set = (value: T) => setValue(data, value)\r\n publicApi._internal = data\r\n\r\n return publicApi as State<T>\r\n}\r\n\r\nexport const computed = <\r\n T extends StateType = -1,\r\n S extends StatlessFunc<T> = StatlessFunc<T>,\r\n O extends Nullable<ComputedInternalOptions> = Nullable<ComputedInternalOptions>,\r\n>(\r\n value: GetStatlessFunc<T, S, O>,\r\n options?: O,\r\n): Computed<T> => {\r\n const data: ComputedInternal = {\r\n childs: new Set(),\r\n depends: new Set(),\r\n hasParentUpdates: true,\r\n history: Array.from({length: settings.historyLength}),\r\n historyCursor: -1,\r\n initial: options?.initial as ReturnType<typeof value> | undefined,\r\n isComputing: false,\r\n name: getName(options?.name),\r\n reducer: value,\r\n subscribes: new Set(),\r\n }\r\n\r\n const publicApi = function () {\r\n return getValue(data)\r\n }\r\n\r\n Object.defineProperty(publicApi, 'name', {value: data.name})\r\n publicApi.subscribe = (listner: Listner<T>) => subscribe(data, listner as Listner)\r\n publicApi._internal = data\r\n\r\n return publicApi as Computed<T>\r\n}\r\n\r\n/**\r\n * Action state\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(\r\n value: (...args: T) => void,\r\n options?: ActionOptions,\r\n): Action<T> => {\r\n return {\r\n run: (...args: T) => {\r\n isActionNow = true\r\n value(...args)\r\n isActionNow = false\r\n return this\r\n },\r\n name: getName(options?.name),\r\n onAction: options?.onAction,\r\n }\r\n}\r\n"],"names":["_this","this","recording","isNotifying","names","Set","requesters","states2notify","getHistoryValue","state","history","historyCursor","pushHistory","value","length","getName","name","has","console","error","defaultName","getComputed","isFunction","v","getComputedValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","push","childs","delete","clear","reducer","initial","pop","e","message","getValue","lastRequester","at","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","st","it","subscribes","size","queueMicrotask","listner","startRecord","data","subscribe","computedState","parent","condtion","msg","Error","options","Array","from","publicApi","Object","defineProperty","set","_internal","computed","action","run","slice","call","arguments","onAction"],"mappings":"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"} |
+4
-4
| { | ||
| "name": "@statx/core", | ||
| "version": "1.0.27", | ||
| "version": "1.1.0", | ||
| "private": false, | ||
@@ -28,6 +28,6 @@ "description": "Extry tiny smart state manager", | ||
| "types": "./build/index.d.ts", | ||
| "default": "./build/index.modern.mjs" | ||
| "default": "./build/index.modern.js" | ||
| }, | ||
| "main": "./build/index.js", | ||
| "module": "./build/index.module.js", | ||
| "module": "./build/index.modern.js", | ||
| "unpkg": "./build/index.umd.js", | ||
@@ -71,3 +71,3 @@ "types": "./build/index.d.ts", | ||
| }, | ||
| "gitHead": "7499f9feeba7c5d3f2181ee76c8cf06370cab2e0" | ||
| "gitHead": "0c3f0bee1aaed49928d9c1813d81e9c611a1ca87" | ||
| } |
| var e=void 0;let r,n=!1;const s="Unnamed state",t=new Set,o=[],i=new Set,a=e=>e.history[e.historyCursor],c=(e,r)=>{e.historyCursor=(e.historyCursor+1)%e.history.length,e.history[e.historyCursor]=r},d=e=>e&&t.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),s):e||s,u=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,l=e=>{try{const n=a(e);if(((e,r)=>!1===e.hasParentUpdates&&void 0!==r)(e,n))return r&&e.depends.forEach(e=>{r?.add(e)}),n;g(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),o.push(e),e.depends.forEach(r=>{r.childs.delete(e)}),e.depends.clear(),e.isComputing=!0;const s=e.reducer(n??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,o.pop(),c(e,s),s}catch(e){return void console.error(e.message)}},p=e=>{const n=u(e);try{const s=o.at(-1);return s&&!e.childs.has(s)&&(e.childs.add(s),s.depends.add(e)),n?l(n):a(e)}finally{r&&!n&&r.add(e)}},f=(e,r)=>{const n=h(r)?((e,r)=>r(a(e)))(e,r):r;n!==a(e)&&(c(e,n),b(e),m())},b=e=>{const r=[e];for(;r.length;){const e=r.pop();e.childs.forEach(e=>r.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&i.add(e)}},m=()=>{!1===n&&(n=!0,queueMicrotask(()=>{i.forEach(e=>{try{e.subscribes.forEach(r=>r(p(e)))}catch(r){console.error("Error in subscriber function of:",e.name)}}),i.clear(),n=!1}))},y=()=>{r=new Set},w=()=>{const e=r;return r=void 0,e},C=(e,r)=>{if(e.subscribes.has(r))return()=>({});const n=u(e);return n&&(l(n),e.depends.forEach(r=>r.childs.add(e))),e.subscribes.add(r),()=>{e.subscribes.delete(r),0===e.subscribes.size&&e.depends.forEach(r=>r.childs.delete(e))}},g=(e,r)=>{if(e)throw new Error(r)};function E(e,r){g(h(e),"Function not allowed in state");const n={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:-1,name:d(r?.name),subscribes:new Set,hasParentUpdates:void 0};f(n,e);const s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>C(n,e),s.set=e=>f(n,e),s._internal=n,s}const S=(e,r)=>{const n={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:-1,initial:r?.initial,isComputing:!1,name:d(r?.name),reducer:e,subscribes:new Set},s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>C(n,e),s._internal=n,s},v=(r,n)=>({run:function(){return r(...[].slice.call(arguments)),e},name:d(n?.name),onAction:n?.onAction});export{v as action,S as computed,w as flushStates,y as startRecord,E as state,C as subscribe}; | ||
| //# sourceMappingURL=index.module.js.map |
| {"version":3,"file":"index.module.js","sources":["../src/core.ts"],"sourcesContent":["import {\r\n ComputedInternal,\r\n Listner,\r\n StateType,\r\n Settings,\r\n StateVariants,\r\n Action,\r\n Options,\r\n ComputedInternalOptions,\r\n Nullable,\r\n StatlessFunc,\r\n GetStatlessFunc,\r\n HistoryInternal,\r\n State,\r\n Computed,\r\n Func,\r\n UnSubscribe,\r\n CommonInternal,\r\n StateInternal,\r\n SetterFunc,\r\n ActionOptions,\r\n} from './types.js'\r\n\r\nlet isNotifying = false\r\nlet isActionNow = false\r\nlet recording: Set<StateInternal> | undefined\r\n\r\nconst defaultName = 'Unnamed state'\r\nconst names = new Set()\r\nconst requesters: ComputedInternal[] = []\r\nconst states2notify = new Set<StateVariants>()\r\nconst settings: Settings = {\r\n historyLength: 5,\r\n}\r\n\r\nexport const getHistoryValue = (state: StateVariants): unknown => {\r\n return state.history[state.historyCursor]\r\n}\r\nconst pushHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\r\n state.history[state.historyCursor] = value\r\n}\r\n\r\nconst getName = (name?: string): string => {\r\n if (name && names.has(name)) {\r\n console.error(`Name ${name} already used! Replaced to undefined`)\r\n return defaultName\r\n }\r\n if (name) {\r\n return name\r\n }\r\n return defaultName\r\n}\r\n\r\nexport const setSetting = (data: Partial<Settings>) => {\r\n Object.assign(settings, data)\r\n}\r\n\r\nconst getComputed = (state: CommonInternal | ComputedInternal) => {\r\n if ('reducer' in state) {\r\n return state\r\n }\r\n}\r\n\r\nconst isFunction = (v: unknown): v is Func => {\r\n return typeof v === 'function'\r\n}\r\n\r\nconst isDontNeedRecalc = (state: CommonInternal, prevState: unknown): boolean => {\r\n return state.hasParentUpdates === false && prevState !== undefined\r\n}\r\n\r\nconst getComputedValue = (state: ComputedInternal): unknown => {\r\n try {\r\n const prevState = getHistoryValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n state.depends.forEach((item) => {\r\n item.childs.delete(state)\r\n })\r\n state.depends.clear()\r\n state.isComputing = true\r\n const value = state.reducer(prevState ?? state.initial)\r\n state.isComputing = false\r\n state.hasParentUpdates = false\r\n\r\n requesters.pop()\r\n pushHistory(state, value)\r\n\r\n return value\r\n } catch (e) {\r\n console.error((e as Error).message)\r\n return undefined\r\n }\r\n}\r\n\r\nconst getValue = (state: CommonInternal) => {\r\n const reducer = getComputed(state)\r\n try {\r\n const lastRequester = requesters.at(-1)\r\n if (lastRequester && !state.childs.has(lastRequester)) {\r\n state.childs.add(lastRequester)\r\n lastRequester.depends.add(state)\r\n }\r\n if (reducer) {\r\n return getComputedValue(reducer)\r\n }\r\n return getHistoryValue(state)\r\n } finally {\r\n if (recording && !reducer) {\r\n recording.add(state)\r\n }\r\n }\r\n}\r\n\r\nconst getValueOfSetterFunction = (state: CommonInternal, value: SetterFunc): unknown => {\r\n const prevValue = getHistoryValue(state)\r\n return value(prevValue)\r\n}\r\n\r\nconst setValue = (state: CommonInternal, value: unknown): void => {\r\n const newValue = isFunction(value) ? getValueOfSetterFunction(state, value) : value\r\n\r\n if (newValue === getHistoryValue(state)) {\r\n return\r\n }\r\n pushHistory(state, newValue)\r\n invalidateSubtree(state)\r\n notifySubscribers()\r\n}\r\n\r\n/**\r\n * Mark all subtree is non actual.\r\n * Collect all nodes to notify subscribers im microtask queue.\r\n */\r\nconst invalidateSubtree = (state: CommonInternal) => {\r\n const stack: CommonInternal[] = [state]\r\n\r\n while (stack.length) {\r\n const st = stack.pop()\r\n st.childs.forEach((it) => stack.push(it))\r\n st.hasParentUpdates = true\r\n if (st.subscribes.size) {\r\n states2notify.add(st)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all collected subscribers once in microtask queue\r\n */\r\nconst notifySubscribers = () => {\r\n if (isNotifying === false) {\r\n isNotifying = true\r\n queueMicrotask(() => {\r\n // Нужно обновить дерево\r\n states2notify.forEach((state) => {\r\n try {\r\n state.subscribes.forEach((listner) => {\r\n return listner(getValue(state))\r\n })\r\n } catch (e) {\r\n console.error('Error in subscriber function of:', state.name)\r\n }\r\n })\r\n states2notify.clear()\r\n isNotifying = false\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * Start collecting all non computed states.\r\n *\r\n * Helper for render adapters.\r\n */\r\nexport const startRecord = () => {\r\n recording = new Set()\r\n}\r\n\r\n/**\r\n * Flush all collected non computed states.\r\n */\r\nexport const flushStates = (): Set<StateInternal> => {\r\n const data = recording\r\n recording = undefined\r\n return data\r\n}\r\n\r\nexport const subscribe = (state: CommonInternal | CommonInternal, listner: Listner): UnSubscribe => {\r\n /**\r\n * Если значение стейта ниразу не расчитывалось, его нужно обновить\r\n * Если подписываемся на вычисляемый стэйт, то нужно узнать всех родителей\r\n * Родители могут меняться, поэтому после каждого вычисления нужно обновлять зависимости дерева\r\n *\r\n * При отписке нужно оповестить всех на кого были опдписанты о том что мы отписались\r\n *\r\n */\r\n\r\n if (state.subscribes.has(listner)) {\r\n return () => ({})\r\n }\r\n\r\n const computedState = getComputed(state)\r\n // Нужно актуализировать в родилеях зависимость\r\n if (computedState) {\r\n getComputedValue(computedState)\r\n state.depends.forEach((parent) => parent.childs.add(state))\r\n }\r\n\r\n state.subscribes.add(listner)\r\n\r\n return () => {\r\n state.subscribes.delete(listner)\r\n if (state.subscribes.size === 0) {\r\n state.depends.forEach((parent) => parent.childs.delete(state))\r\n }\r\n }\r\n}\r\n\r\nconst assert = (condtion: boolean, msg: string) => {\r\n if (condtion) {\r\n throw new Error(msg)\r\n }\r\n}\r\n\r\n/**\r\n *\r\n * @param value - Reducer or value\r\n * @param name - name of state. For loggin or easy debug\r\n * @returns State<T>\r\n */\r\nexport function state<T extends StateType = StateType>(value: T, options?: Options): State<T> {\r\n assert(isFunction(value), 'Function not allowed in state')\r\n\r\n const data: CommonInternal = {\r\n childs: new Set(),\r\n depends: new Set(),\r\n history: Array.from({length: settings.historyLength}),\r\n historyCursor: -1,\r\n name: getName(options?.name),\r\n subscribes: new Set(),\r\n hasParentUpdates: undefined,\r\n }\r\n\r\n setValue(data, value)\r\n\r\n const publicApi = function () {\r\n return getValue(data)\r\n }\r\n\r\n Object.defineProperty(publicApi, 'name', {value: data.name})\r\n publicApi.subscribe = (listner: Listner) => subscribe(data, listner)\r\n publicApi.set = (value: T) => setValue(data, value)\r\n publicApi._internal = data\r\n\r\n return publicApi as State<T>\r\n}\r\n\r\nexport const computed = <\r\n T extends StateType = -1,\r\n S extends StatlessFunc<T> = StatlessFunc<T>,\r\n O extends Nullable<ComputedInternalOptions> = Nullable<ComputedInternalOptions>,\r\n>(\r\n value: GetStatlessFunc<T, S, O>,\r\n options?: O,\r\n): Computed<T> => {\r\n const data: ComputedInternal = {\r\n childs: new Set(),\r\n depends: new Set(),\r\n hasParentUpdates: true,\r\n history: Array.from({length: settings.historyLength}),\r\n historyCursor: -1,\r\n initial: options?.initial as ReturnType<typeof value> | undefined,\r\n isComputing: false,\r\n name: getName(options?.name),\r\n reducer: value,\r\n subscribes: new Set(),\r\n }\r\n\r\n const publicApi = function () {\r\n return getValue(data)\r\n }\r\n\r\n Object.defineProperty(publicApi, 'name', {value: data.name})\r\n publicApi.subscribe = (listner: Listner<T>) => subscribe(data, listner as Listner)\r\n publicApi._internal = data\r\n\r\n return publicApi as Computed<T>\r\n}\r\n\r\n/**\r\n * Action state\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(\r\n value: (...args: T) => void,\r\n options?: ActionOptions,\r\n): Action<T> => {\r\n return {\r\n run: (...args: T) => {\r\n isActionNow = true\r\n value(...args)\r\n isActionNow = false\r\n return this\r\n },\r\n name: getName(options?.name),\r\n onAction: options?.onAction,\r\n }\r\n}\r\n"],"names":["_this","this","recording","isNotifying","names","Set","requesters","states2notify","getHistoryValue","state","history","historyCursor","pushHistory","value","length","getName","name","has","console","error","defaultName","getComputed","isFunction","v","getComputedValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","push","childs","delete","clear","reducer","initial","pop","e","message","getValue","lastRequester","at","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","st","it","subscribes","size","queueMicrotask","listner","startRecord","data","subscribe","computedState","parent","condtion","msg","Error","options","Array","from","publicApi","Object","defineProperty","set","_internal","computed","action","run","slice","call","arguments","onAction"],"mappings":"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"} |
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
93026
0