🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@statx/core

Package Overview
Dependencies
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@statx/core - npm Package Compare versions

Comparing version
1.0.27
to
1.1.0
+2
build/index.modern.js
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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"}