@statx/core
Advanced tools
| var e=void 0;let t,s=new WeakMap,r=!1;const n="Unnamed state",o=new Set,a=[],i=new Set,c=e=>s.get(e),d=e=>e&&o.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),n):e||n,u=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,l=e=>{try{const s=c(e);if(((e,t)=>!1===e.hasParentUpdates&&void 0!==t)(e,s))return e.depends.forEach(e=>{t.add(e)}),s;g(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),a.push(e),e.isComputing=!0;const r=e.reducer(s??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,a.pop(),y(e,r),r}catch(e){return void console.error(e.message)}},p=e=>{const s=u(e);try{const r=a.at(-1);return r&&!e.childs.has(r)&&(e.childs.add(r),r.depends.add(e)),s?l(s):c(e)}finally{t&&!s&&t.add(e)}},b=(e,t)=>{const s=h(t)?((e,t)=>t(c(e)))(e,t):t;s!==c(e)&&(y(e,s),f(e),m())},f=e=>{const t=[e];for(;t.length;){const e=t.pop();e.childs.forEach(e=>t.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&i.add(e)}},m=()=>{!1===r&&(r=!0,queueMicrotask(()=>{i.forEach(e=>{try{e.subscribes.forEach(t=>t(p(e)))}catch(t){console.error("Error in subscriber function of:",e.name)}}),i.clear(),r=!1}))},y=(e,t)=>{((e,t)=>{s.set(e,t)})(e,t),((e,t)=>{const s=e.historyCursor;e.history[s]=t,e.historyCursor=(s+1)%e.history.length})(e,t)},w=(e,t)=>{if(e.subscribes.has(t))return()=>({});const s=u(e);return s&&l(s),e.subscribes.add(t),()=>{e.subscribes.delete(t),0===e.subscribes.size&&e.depends.forEach(t=>t.childs.delete(e))}},g=(e,t)=>{if(e)throw new Error(t)};exports.action=(t,s)=>({run:function(){return t(...[].slice.call(arguments)),e},name:d(s),onAction:void 0}),exports.computed=(e,t)=>{const s={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:t?.initial,isComputing:!1,name:d(t?.name),reducer:e,subscribes:new Set},r=function(){return p(s)};return Object.defineProperty(r,"name",{value:s.name}),r.subscribe=e=>w(s,e),r._internal=s,r},exports.flushStates=()=>{const e=t;return t=void 0,e},exports.setContext=()=>{s=new WeakMap},exports.startRecord=()=>{t=new Set},exports.state=function(e,t){g(h(e),"Function not allowed in state");const s={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:d(t?.name),subscribes:new Set,hasParentUpdates:void 0};b(s,e);const r=function(){return p(s)};return Object.defineProperty(r,"name",{value:s.name}),r.subscribe=e=>w(s,e),r.set=e=>b(s,e),r._internal=s,r},exports.subscribe=w; | ||
| //# sourceMappingURL=index.js.map |
| The MIT License (MIT) | ||
| Copyright (c) 2022-present Andrey Larkin | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
+1
-1
@@ -1,2 +0,2 @@ | ||
| var e=void 0;let t,s=new WeakMap,r=!1;const n="Unnamed state",o=new Set,a=[],i=new Set,c=e=>s.get(e),u=e=>e&&o.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),n):e||n,d=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,l=e=>{try{const t=c(e);if(((e,t)=>!1===e.hasParentUpdates&&void 0!==t)(e,t))return t;g(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),a.push(e),e.isComputing=!0;const s=e.reducer(t??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,a.pop(),y(e,s),s}catch(e){return void console.error(e.message)}},p=e=>{const s=d(e);try{const r=a.at(-1);return r&&!e.childs.has(r)&&(e.childs.add(r),r.depends.add(e)),s?l(s):c(e)}finally{t&&!s&&t.add(e)}},b=(e,t)=>{const s=h(t)?((e,t)=>t(c(e)))(e,t):t;s!==c(e)&&(y(e,s),f(e),m())},f=e=>{const t=[e];for(;t.length;){const e=t.pop();e.childs.forEach(e=>t.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&i.add(e)}},m=()=>{!1===r&&(r=!0,queueMicrotask(()=>{i.forEach(e=>{try{e.subscribes.forEach(t=>t(p(e)))}catch(t){console.error("Error in subscriber function of:",e.name)}}),i.clear(),r=!1}))},y=(e,t)=>{((e,t)=>{s.set(e,t)})(e,t),((e,t)=>{const s=e.historyCursor;e.history[s]=t,e.historyCursor=(s+1)%e.history.length})(e,t)},w=(e,t)=>{if(e.subscribes.has(t))return()=>({});const s=d(e);return s&&l(s),e.subscribes.add(t),()=>{e.subscribes.delete(t),0===e.subscribes.size&&e.depends.forEach(t=>t.childs.delete(e))}},g=(e,t)=>{if(e)throw new Error(t)};exports.action=(t,s)=>({run:function(){return t(...[].slice.call(arguments)),e},name:u(s),onAction:void 0}),exports.computed=(e,t)=>{const s={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:t?.initial,isComputing:!1,name:u(t?.name),reducer:e,subscribes:new Set},r=function(){return p(s)};return Object.defineProperty(r,"name",{value:s.name}),r.subscribe=e=>w(s,e),r._internal=s,r},exports.flushStates=()=>{const e=t;return t=void 0,e},exports.setContext=()=>{s=new WeakMap},exports.startRecord=()=>{t=new Set},exports.state=function(e,t){g(h(e),"Function not allowed in state");const s={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:u(t?.name),subscribes:new Set,hasParentUpdates:void 0};b(s,e);const r=function(){return p(s)};return Object.defineProperty(r,"name",{value:s.name}),r.subscribe=e=>w(s,e),r.set=e=>b(s,e),r._internal=s,r},exports.subscribe=w; | ||
| var e=void 0;let t,s=new WeakMap,r=!1;const n="Unnamed state",o=new Set,a=[],i=new Set,c=e=>s.get(e),d=e=>e&&o.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),n):e||n,u=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,l=e=>{try{const s=c(e);if(((e,t)=>!1===e.hasParentUpdates&&void 0!==t)(e,s))return e.depends.forEach(e=>{t.add(e)}),s;g(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),a.push(e),e.isComputing=!0;const r=e.reducer(s??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,a.pop(),y(e,r),r}catch(e){return void console.error(e.message)}},p=e=>{const s=u(e);try{const r=a.at(-1);return r&&!e.childs.has(r)&&(e.childs.add(r),r.depends.add(e)),s?l(s):c(e)}finally{t&&!s&&t.add(e)}},b=(e,t)=>{const s=h(t)?((e,t)=>t(c(e)))(e,t):t;s!==c(e)&&(y(e,s),f(e),m())},f=e=>{const t=[e];for(;t.length;){const e=t.pop();e.childs.forEach(e=>t.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&i.add(e)}},m=()=>{!1===r&&(r=!0,queueMicrotask(()=>{i.forEach(e=>{try{e.subscribes.forEach(t=>t(p(e)))}catch(t){console.error("Error in subscriber function of:",e.name)}}),i.clear(),r=!1}))},y=(e,t)=>{((e,t)=>{s.set(e,t)})(e,t),((e,t)=>{const s=e.historyCursor;e.history[s]=t,e.historyCursor=(s+1)%e.history.length})(e,t)},w=(e,t)=>{if(e.subscribes.has(t))return()=>({});const s=u(e);return s&&l(s),e.subscribes.add(t),()=>{e.subscribes.delete(t),0===e.subscribes.size&&e.depends.forEach(t=>t.childs.delete(e))}},g=(e,t)=>{if(e)throw new Error(t)};exports.action=(t,s)=>({run:function(){return t(...[].slice.call(arguments)),e},name:d(s),onAction:void 0}),exports.computed=(e,t)=>{const s={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:t?.initial,isComputing:!1,name:d(t?.name),reducer:e,subscribes:new Set},r=function(){return p(s)};return Object.defineProperty(r,"name",{value:s.name}),r.subscribe=e=>w(s,e),r._internal=s,r},exports.flushStates=()=>{const e=t;return t=void 0,e},exports.setContext=()=>{s=new WeakMap},exports.startRecord=()=>{t=new Set},exports.state=function(e,t){g(h(e),"Function not allowed in state");const s={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:d(t?.name),subscribes:new Set,hasParentUpdates:void 0};b(s,e);const r=function(){return p(s)};return Object.defineProperty(r,"name",{value:s.name}),r.subscribe=e=>w(s,e),r.set=e=>b(s,e),r._internal=s,r},exports.subscribe=w; | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.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} from './types.js'\r\n\r\nlet cache = new WeakMap<StateVariants, StateType>()\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// <T extends StateType>(state: StateVariants<T>\r\nexport const getCachValue = (state: StateVariants): unknown => {\r\n return cache.get(state)\r\n}\r\n\r\nconst setCacheValue = (state: StateVariants, value: StateType): void => {\r\n cache.set(state, 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\nexport const setContext = () => {\r\n cache = new WeakMap<object, StateType>()\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 updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\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 = getCachValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\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\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 applyUpdates(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 getCachValue(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 = getCachValue(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 === getCachValue(state)) {\r\n return\r\n }\r\n applyUpdates(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\nconst applyUpdates = (state: CommonInternal, value: unknown): void => {\r\n setCacheValue(state, value)\r\n updateHistory(state, value)\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 if (computedState) {\r\n getComputedValue(computedState)\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: 0,\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: 0,\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 *\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): 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(name),\r\n onAction: undefined,\r\n }\r\n}\r\n"],"names":["_this","this","recording","cache","WeakMap","isNotifying","defaultName","names","Set","requesters","states2notify","getCachValue","state","get","getName","name","has","console","error","getComputed","isFunction","v","getComputedValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","assert","isComputing","push","value","reducer","initial","pop","applyUpdates","e","message","getValue","lastRequester","at","childs","add","depends","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","length","st","forEach","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","computedState","delete","parent","condtion","msg","run","slice","call","arguments","onAction","options","data","Array","from","publicApi","Object","defineProperty","subscribe","_internal"],"mappings":"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"} | ||
| {"version":3,"file":"index.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} from './types.js'\r\n\r\nlet cache = new WeakMap<StateVariants, StateType>()\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// <T extends StateType>(state: StateVariants<T>\r\nexport const getCachValue = (state: StateVariants): unknown => {\r\n return cache.get(state)\r\n}\r\n\r\nconst setCacheValue = (state: StateVariants, value: StateType): void => {\r\n cache.set(state, 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\nexport const setContext = () => {\r\n cache = new WeakMap<object, StateType>()\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 updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\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 = getCachValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n state.depends.forEach((item) => {\r\n recording.add(item)\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\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 applyUpdates(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 getCachValue(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 = getCachValue(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 === getCachValue(state)) {\r\n return\r\n }\r\n applyUpdates(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\nconst applyUpdates = (state: CommonInternal, value: unknown): void => {\r\n setCacheValue(state, value)\r\n updateHistory(state, value)\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 if (computedState) {\r\n getComputedValue(computedState)\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: 0,\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: 0,\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 *\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): 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(name),\r\n onAction: undefined,\r\n }\r\n}\r\n"],"names":["_this","this","recording","cache","WeakMap","isNotifying","defaultName","names","requesters","states2notify","Set","getCachValue","state","get","getName","name","has","console","error","getComputed","isFunction","v","getComputedValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","push","value","reducer","initial","pop","applyUpdates","e","message","getValue","lastRequester","at","childs","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","length","st","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","subscribe","computedState","delete","parent","condtion","msg","Error","run","slice","call","arguments","onAction","options","data","Array","from","Object","defineProperty","publicApi","_internal"],"mappings":"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"} |
@@ -1,2 +0,2 @@ | ||
| let e,n=new WeakMap,r=!1;const s="Unnamed state",t=new Set,o=[],i=new Set,a=e=>n.get(e),c=e=>e&&t.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),s):e||s,u=()=>{n=new WeakMap},d=e=>{if("reducer"in e)return e},l=e=>"function"==typeof e,h=e=>{try{var n;const r=a(e);if(((e,n)=>!1===e.hasParentUpdates&&void 0!==n)(e,r))return r;S(e.isComputing,`Loops dosen't allows. Name: ${null!=(n=e.name)?n:"Unnamed state"}`),o.push(e),e.isComputing=!0;const s=e.reducer(null!=r?r:e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,o.pop(),y(e,s),s}catch(e){return void console.error(e.message)}},p=n=>{const r=d(n);try{const s=o.at(-1);return s&&!n.childs.has(s)&&(n.childs.add(s),s.depends.add(n)),r?h(r):a(n)}finally{e&&!r&&e.add(n)}},b=(e,n)=>{const r=l(n)?((e,n)=>n(a(e)))(e,n):n;r!==a(e)&&(y(e,r),f(e),m())},f=e=>{const n=[e];for(;n.length;){const e=n.pop();e.childs.forEach(e=>n.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&i.add(e)}},m=()=>{!1===r&&(r=!0,queueMicrotask(()=>{i.forEach(e=>{try{e.subscribes.forEach(n=>n(p(e)))}catch(n){console.error("Error in subscriber function of:",e.name)}}),i.clear(),r=!1}))},y=(e,r)=>{((e,r)=>{n.set(e,r)})(e,r),((e,n)=>{const r=e.historyCursor;e.history[r]=n,e.historyCursor=(r+1)%e.history.length})(e,r)},w=()=>{e=new Set},v=()=>{const n=e;return e=void 0,n},g=(e,n)=>{if(e.subscribes.has(n))return()=>({});const r=d(e);return r&&h(r),e.subscribes.add(n),()=>{e.subscribes.delete(n),0===e.subscribes.size&&e.depends.forEach(n=>n.childs.delete(e))}},S=(e,n)=>{if(e)throw new Error(n)};function C(e,n){S(l(e),"Function not allowed in state");const r={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:c(null==n?void 0:n.name),subscribes:new Set,hasParentUpdates:void 0};b(r,e);const s=function(){return p(r)};return Object.defineProperty(s,"name",{value:r.name}),s.subscribe=e=>g(r,e),s.set=e=>b(r,e),s._internal=r,s}const P=(e,n)=>{const r={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:null==n?void 0:n.initial,isComputing:!1,name:c(null==n?void 0:n.name),reducer:e,subscribes:new Set},s=function(){return p(r)};return Object.defineProperty(s,"name",{value:r.name}),s.subscribe=e=>g(r,e),s._internal=r,s},U=(e,n)=>({run:(...n)=>{e(...n)},name:c(n),onAction:void 0});export{U as action,P as computed,v as flushStates,u as setContext,w as startRecord,C as state,g as subscribe}; | ||
| let e,n=new WeakMap,r=!1;const s="Unnamed state",t=new Set,o=[],a=new Set,i=e=>n.get(e),c=e=>e&&t.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),s):e||s,d=()=>{n=new WeakMap},u=e=>{if("reducer"in e)return e},l=e=>"function"==typeof e,h=n=>{try{var r;const s=i(n);if(((e,n)=>!1===e.hasParentUpdates&&void 0!==n)(n,s))return n.depends.forEach(n=>{e.add(n)}),s;S(n.isComputing,`Loops dosen't allows. Name: ${null!=(r=n.name)?r:"Unnamed state"}`),o.push(n),n.isComputing=!0;const t=n.reducer(null!=s?s:n.initial);return n.isComputing=!1,n.hasParentUpdates=!1,o.pop(),y(n,t),t}catch(e){return void console.error(e.message)}},p=n=>{const r=u(n);try{const s=o.at(-1);return s&&!n.childs.has(s)&&(n.childs.add(s),s.depends.add(n)),r?h(r):i(n)}finally{e&&!r&&e.add(n)}},b=(e,n)=>{const r=l(n)?((e,n)=>n(i(e)))(e,n):n;r!==i(e)&&(y(e,r),f(e),m())},f=e=>{const n=[e];for(;n.length;){const e=n.pop();e.childs.forEach(e=>n.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&a.add(e)}},m=()=>{!1===r&&(r=!0,queueMicrotask(()=>{a.forEach(e=>{try{e.subscribes.forEach(n=>n(p(e)))}catch(n){console.error("Error in subscriber function of:",e.name)}}),a.clear(),r=!1}))},y=(e,r)=>{((e,r)=>{n.set(e,r)})(e,r),((e,n)=>{const r=e.historyCursor;e.history[r]=n,e.historyCursor=(r+1)%e.history.length})(e,r)},w=()=>{e=new Set},v=()=>{const n=e;return e=void 0,n},g=(e,n)=>{if(e.subscribes.has(n))return()=>({});const r=u(e);return r&&h(r),e.subscribes.add(n),()=>{e.subscribes.delete(n),0===e.subscribes.size&&e.depends.forEach(n=>n.childs.delete(e))}},S=(e,n)=>{if(e)throw new Error(n)};function C(e,n){S(l(e),"Function not allowed in state");const r={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:c(null==n?void 0:n.name),subscribes:new Set,hasParentUpdates:void 0};b(r,e);const s=function(){return p(r)};return Object.defineProperty(s,"name",{value:r.name}),s.subscribe=e=>g(r,e),s.set=e=>b(r,e),s._internal=r,s}const E=(e,n)=>{const r={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:null==n?void 0:n.initial,isComputing:!1,name:c(null==n?void 0:n.name),reducer:e,subscribes:new Set},s=function(){return p(r)};return Object.defineProperty(s,"name",{value:r.name}),s.subscribe=e=>g(r,e),s._internal=r,s},P=(e,n)=>({run:(...n)=>{e(...n)},name:c(n),onAction:void 0});export{P as action,E as computed,v as flushStates,d as setContext,w as startRecord,C as state,g as subscribe}; | ||
| //# sourceMappingURL=index.modern.mjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.modern.mjs","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} from './types.js'\r\n\r\nlet cache = new WeakMap<StateVariants, StateType>()\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// <T extends StateType>(state: StateVariants<T>\r\nexport const getCachValue = (state: StateVariants): unknown => {\r\n return cache.get(state)\r\n}\r\n\r\nconst setCacheValue = (state: StateVariants, value: StateType): void => {\r\n cache.set(state, 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\nexport const setContext = () => {\r\n cache = new WeakMap<object, StateType>()\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 updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\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 = getCachValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\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\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 applyUpdates(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 getCachValue(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 = getCachValue(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 === getCachValue(state)) {\r\n return\r\n }\r\n applyUpdates(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\nconst applyUpdates = (state: CommonInternal, value: unknown): void => {\r\n setCacheValue(state, value)\r\n updateHistory(state, value)\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 if (computedState) {\r\n getComputedValue(computedState)\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: 0,\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: 0,\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 *\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): 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(name),\r\n onAction: undefined,\r\n }\r\n}\r\n"],"names":["recording","cache","WeakMap","isNotifying","defaultName","names","requesters","states2notify","Set","getCachValue","state","get","getName","name","has","console","error","getComputed","isFunction","v","getComputedValue","_state$name","prevState","hasParentUpdates","undefined","isDontNeedRecalc","assert","isComputing","push","value","reducer","initial","pop","applyUpdates","e","message","getValue","lastRequester","at","childs","add","depends","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","length","st","forEach","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","startRecord","flushStates","data","subscribe","computedState","delete","parent","condtion","msg","options","Array","from","publicApi","Object","defineProperty","_internal","computed","action","run","args","this","onAction"],"mappings":"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"} | ||
| {"version":3,"file":"index.modern.mjs","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} from './types.js'\r\n\r\nlet cache = new WeakMap<StateVariants, StateType>()\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// <T extends StateType>(state: StateVariants<T>\r\nexport const getCachValue = (state: StateVariants): unknown => {\r\n return cache.get(state)\r\n}\r\n\r\nconst setCacheValue = (state: StateVariants, value: StateType): void => {\r\n cache.set(state, 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\nexport const setContext = () => {\r\n cache = new WeakMap<object, StateType>()\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 updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\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 = getCachValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n state.depends.forEach((item) => {\r\n recording.add(item)\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\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 applyUpdates(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 getCachValue(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 = getCachValue(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 === getCachValue(state)) {\r\n return\r\n }\r\n applyUpdates(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\nconst applyUpdates = (state: CommonInternal, value: unknown): void => {\r\n setCacheValue(state, value)\r\n updateHistory(state, value)\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 if (computedState) {\r\n getComputedValue(computedState)\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: 0,\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: 0,\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 *\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): 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(name),\r\n onAction: undefined,\r\n }\r\n}\r\n"],"names":["recording","cache","WeakMap","isNotifying","defaultName","names","requesters","states2notify","Set","state","get","getName","name","has","console","error","setContext","isFunction","v","getComputedValue","prevState","getCachValue","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","_state$name","push","value","reducer","initial","pop","applyUpdates","e","message","getValue","getComputed","lastRequester","at","childs","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","length","st","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","startRecord","data","computedState","delete","parent","condtion","msg","Error","options","Array","from","publicApi","Object","defineProperty","subscribe","_internal","computed","action","run","args","this","onAction"],"mappings":"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"} |
@@ -1,2 +0,2 @@ | ||
| var e=void 0;let n,r=new WeakMap,t=!1;const s="Unnamed state",o=new Set,i=[],a=new Set,c=e=>r.get(e),d=e=>e&&o.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),s):e||s,u=()=>{r=new WeakMap},h=e=>{if("reducer"in e)return e},l=e=>"function"==typeof e,p=e=>{try{const n=c(e);if(((e,n)=>!1===e.hasParentUpdates&&void 0!==n)(e,n))return n;C(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),i.push(e),e.isComputing=!0;const r=e.reducer(n??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,i.pop(),w(e,r),r}catch(e){return void console.error(e.message)}},b=e=>{const r=h(e);try{const t=i.at(-1);return t&&!e.childs.has(t)&&(e.childs.add(t),t.depends.add(e)),r?p(r):c(e)}finally{n&&!r&&n.add(e)}},f=(e,n)=>{const r=l(n)?((e,n)=>n(c(e)))(e,n):n;r!==c(e)&&(w(e,r),m(e),y())},m=e=>{const n=[e];for(;n.length;){const e=n.pop();e.childs.forEach(e=>n.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&a.add(e)}},y=()=>{!1===t&&(t=!0,queueMicrotask(()=>{a.forEach(e=>{try{e.subscribes.forEach(n=>n(b(e)))}catch(n){console.error("Error in subscriber function of:",e.name)}}),a.clear(),t=!1}))},w=(e,n)=>{((e,n)=>{r.set(e,n)})(e,n),((e,n)=>{const r=e.historyCursor;e.history[r]=n,e.historyCursor=(r+1)%e.history.length})(e,n)},g=()=>{n=new Set},v=()=>{const e=n;return n=void 0,e},S=(e,n)=>{if(e.subscribes.has(n))return()=>({});const r=h(e);return r&&p(r),e.subscribes.add(n),()=>{e.subscribes.delete(n),0===e.subscribes.size&&e.depends.forEach(n=>n.childs.delete(e))}},C=(e,n)=>{if(e)throw new Error(n)};function P(e,n){C(l(e),"Function not allowed in state");const r={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:d(n?.name),subscribes:new Set,hasParentUpdates:void 0};f(r,e);const t=function(){return b(r)};return Object.defineProperty(t,"name",{value:r.name}),t.subscribe=e=>S(r,e),t.set=e=>f(r,e),t._internal=r,t}const U=(e,n)=>{const r={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:n?.initial,isComputing:!1,name:d(n?.name),reducer:e,subscribes:new Set},t=function(){return b(r)};return Object.defineProperty(t,"name",{value:r.name}),t.subscribe=e=>S(r,e),t._internal=r,t},E=(n,r)=>({run:function(){return n(...[].slice.call(arguments)),e},name:d(r),onAction:void 0});export{E as action,U as computed,v as flushStates,u as setContext,g as startRecord,P as state,S as subscribe}; | ||
| var e=void 0;let n,r=new WeakMap,s=!1;const t="Unnamed state",o=new Set,a=[],i=new Set,c=e=>r.get(e),d=e=>e&&o.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),t):e||t,u=()=>{r=new WeakMap},h=e=>{if("reducer"in e)return e},l=e=>"function"==typeof e,p=e=>{try{const r=c(e);if(((e,n)=>!1===e.hasParentUpdates&&void 0!==n)(e,r))return e.depends.forEach(e=>{n.add(e)}),r;C(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),a.push(e),e.isComputing=!0;const s=e.reducer(r??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,a.pop(),w(e,s),s}catch(e){return void console.error(e.message)}},b=e=>{const r=h(e);try{const s=a.at(-1);return s&&!e.childs.has(s)&&(e.childs.add(s),s.depends.add(e)),r?p(r):c(e)}finally{n&&!r&&n.add(e)}},f=(e,n)=>{const r=l(n)?((e,n)=>n(c(e)))(e,n):n;r!==c(e)&&(w(e,r),m(e),y())},m=e=>{const n=[e];for(;n.length;){const e=n.pop();e.childs.forEach(e=>n.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&i.add(e)}},y=()=>{!1===s&&(s=!0,queueMicrotask(()=>{i.forEach(e=>{try{e.subscribes.forEach(n=>n(b(e)))}catch(n){console.error("Error in subscriber function of:",e.name)}}),i.clear(),s=!1}))},w=(e,n)=>{((e,n)=>{r.set(e,n)})(e,n),((e,n)=>{const r=e.historyCursor;e.history[r]=n,e.historyCursor=(r+1)%e.history.length})(e,n)},g=()=>{n=new Set},v=()=>{const e=n;return n=void 0,e},S=(e,n)=>{if(e.subscribes.has(n))return()=>({});const r=h(e);return r&&p(r),e.subscribes.add(n),()=>{e.subscribes.delete(n),0===e.subscribes.size&&e.depends.forEach(n=>n.childs.delete(e))}},C=(e,n)=>{if(e)throw new Error(n)};function E(e,n){C(l(e),"Function not allowed in state");const r={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:d(n?.name),subscribes:new Set,hasParentUpdates:void 0};f(r,e);const s=function(){return b(r)};return Object.defineProperty(s,"name",{value:r.name}),s.subscribe=e=>S(r,e),s.set=e=>f(r,e),s._internal=r,s}const P=(e,n)=>{const r={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:n?.initial,isComputing:!1,name:d(n?.name),reducer:e,subscribes:new Set},s=function(){return b(r)};return Object.defineProperty(s,"name",{value:r.name}),s.subscribe=e=>S(r,e),s._internal=r,s},U=(n,r)=>({run:function(){return n(...[].slice.call(arguments)),e},name:d(r),onAction:void 0});export{U as action,P as computed,v as flushStates,u as setContext,g as startRecord,E as state,S as subscribe}; | ||
| //# sourceMappingURL=index.module.js.map |
@@ -1,1 +0,1 @@ | ||
| {"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} from './types.js'\r\n\r\nlet cache = new WeakMap<StateVariants, StateType>()\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// <T extends StateType>(state: StateVariants<T>\r\nexport const getCachValue = (state: StateVariants): unknown => {\r\n return cache.get(state)\r\n}\r\n\r\nconst setCacheValue = (state: StateVariants, value: StateType): void => {\r\n cache.set(state, 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\nexport const setContext = () => {\r\n cache = new WeakMap<object, StateType>()\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 updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\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 = getCachValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\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\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 applyUpdates(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 getCachValue(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 = getCachValue(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 === getCachValue(state)) {\r\n return\r\n }\r\n applyUpdates(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\nconst applyUpdates = (state: CommonInternal, value: unknown): void => {\r\n setCacheValue(state, value)\r\n updateHistory(state, value)\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 if (computedState) {\r\n getComputedValue(computedState)\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: 0,\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: 0,\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 *\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): 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(name),\r\n onAction: undefined,\r\n }\r\n}\r\n"],"names":["_this","this","recording","cache","WeakMap","isNotifying","defaultName","names","Set","requesters","states2notify","getCachValue","state","get","getName","name","has","console","error","setContext","getComputed","isFunction","v","getComputedValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","assert","isComputing","push","value","reducer","initial","pop","applyUpdates","e","message","getValue","lastRequester","at","childs","add","depends","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","length","st","forEach","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","startRecord","data","computedState","delete","parent","condtion","msg","options","Array","from","publicApi","Object","defineProperty","subscribe","_internal","computed","action","run","slice","call","arguments","onAction"],"mappings":"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"} | ||
| {"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} from './types.js'\r\n\r\nlet cache = new WeakMap<StateVariants, StateType>()\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// <T extends StateType>(state: StateVariants<T>\r\nexport const getCachValue = (state: StateVariants): unknown => {\r\n return cache.get(state)\r\n}\r\n\r\nconst setCacheValue = (state: StateVariants, value: StateType): void => {\r\n cache.set(state, 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\nexport const setContext = () => {\r\n cache = new WeakMap<object, StateType>()\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 updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\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 = getCachValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n state.depends.forEach((item) => {\r\n recording.add(item)\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\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 applyUpdates(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 getCachValue(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 = getCachValue(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 === getCachValue(state)) {\r\n return\r\n }\r\n applyUpdates(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\nconst applyUpdates = (state: CommonInternal, value: unknown): void => {\r\n setCacheValue(state, value)\r\n updateHistory(state, value)\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 if (computedState) {\r\n getComputedValue(computedState)\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: 0,\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: 0,\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 *\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): 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(name),\r\n onAction: undefined,\r\n }\r\n}\r\n"],"names":["_this","this","recording","cache","WeakMap","isNotifying","defaultName","names","requesters","states2notify","Set","getCachValue","state","get","getName","name","has","console","error","getComputed","isFunction","v","getComputedValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","push","value","reducer","initial","pop","applyUpdates","e","message","getValue","lastRequester","at","childs","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","length","st","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","startRecord","flushStates","data","subscribe","computedState","delete","parent","condtion","msg","Error","options","Array","from","publicApi","Object","defineProperty","_internal","computed","action","run","slice","call","arguments","onAction"],"mappings":"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"} |
@@ -1,2 +0,2 @@ | ||
| !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e||self).core={})}(this,function(e){var t=void 0;let n,s=new WeakMap,r=!1;const o="Unnamed state",i=new Set,a=[],c=new Set,d=e=>s.get(e),u=e=>e&&i.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),o):e||o,l=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,f=e=>{try{const t=d(e);if(((e,t)=>!1===e.hasParentUpdates&&void 0!==t)(e,t))return t;S(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),a.push(e),e.isComputing=!0;const n=e.reducer(t??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,a.pop(),w(e,n),n}catch(e){return void console.error(e.message)}},p=e=>{const t=l(e);try{const s=a.at(-1);return s&&!e.childs.has(s)&&(e.childs.add(s),s.depends.add(e)),t?f(t):d(e)}finally{n&&!t&&n.add(e)}},b=(e,t)=>{const n=h(t)?((e,t)=>t(d(e)))(e,t):t;n!==d(e)&&(w(e,n),m(e),y())},m=e=>{const t=[e];for(;t.length;){const e=t.pop();e.childs.forEach(e=>t.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&c.add(e)}},y=()=>{!1===r&&(r=!0,queueMicrotask(()=>{c.forEach(e=>{try{e.subscribes.forEach(t=>t(p(e)))}catch(t){console.error("Error in subscriber function of:",e.name)}}),c.clear(),r=!1}))},w=(e,t)=>{((e,t)=>{s.set(e,t)})(e,t),((e,t)=>{const n=e.historyCursor;e.history[n]=t,e.historyCursor=(n+1)%e.history.length})(e,t)},g=(e,t)=>{if(e.subscribes.has(t))return()=>({});const n=l(e);return n&&f(n),e.subscribes.add(t),()=>{e.subscribes.delete(t),0===e.subscribes.size&&e.depends.forEach(t=>t.childs.delete(e))}},S=(e,t)=>{if(e)throw new Error(t)};e.action=(e,n)=>({run:function(){return e(...[].slice.call(arguments)),t},name:u(n),onAction:void 0}),e.computed=(e,t)=>{const n={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:t?.initial,isComputing:!1,name:u(t?.name),reducer:e,subscribes:new Set},s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>g(n,e),s._internal=n,s},e.flushStates=()=>{const e=n;return n=void 0,e},e.setContext=()=>{s=new WeakMap},e.startRecord=()=>{n=new Set},e.state=function(e,t){S(h(e),"Function not allowed in state");const n={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:u(t?.name),subscribes:new Set,hasParentUpdates:void 0};b(n,e);const s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>g(n,e),s.set=e=>b(n,e),s._internal=n,s},e.subscribe=g}); | ||
| !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e||self).core={})}(this,function(e){var t=void 0;let n,s=new WeakMap,r=!1;const o="Unnamed state",i=new Set,a=[],c=new Set,d=e=>s.get(e),u=e=>e&&i.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),o):e||o,l=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,f=e=>{try{const t=d(e);if(((e,t)=>!1===e.hasParentUpdates&&void 0!==t)(e,t))return e.depends.forEach(e=>{n.add(e)}),t;S(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),a.push(e),e.isComputing=!0;const s=e.reducer(t??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,a.pop(),w(e,s),s}catch(e){return void console.error(e.message)}},p=e=>{const t=l(e);try{const s=a.at(-1);return s&&!e.childs.has(s)&&(e.childs.add(s),s.depends.add(e)),t?f(t):d(e)}finally{n&&!t&&n.add(e)}},b=(e,t)=>{const n=h(t)?((e,t)=>t(d(e)))(e,t):t;n!==d(e)&&(w(e,n),m(e),y())},m=e=>{const t=[e];for(;t.length;){const e=t.pop();e.childs.forEach(e=>t.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&c.add(e)}},y=()=>{!1===r&&(r=!0,queueMicrotask(()=>{c.forEach(e=>{try{e.subscribes.forEach(t=>t(p(e)))}catch(t){console.error("Error in subscriber function of:",e.name)}}),c.clear(),r=!1}))},w=(e,t)=>{((e,t)=>{s.set(e,t)})(e,t),((e,t)=>{const n=e.historyCursor;e.history[n]=t,e.historyCursor=(n+1)%e.history.length})(e,t)},g=(e,t)=>{if(e.subscribes.has(t))return()=>({});const n=l(e);return n&&f(n),e.subscribes.add(t),()=>{e.subscribes.delete(t),0===e.subscribes.size&&e.depends.forEach(t=>t.childs.delete(e))}},S=(e,t)=>{if(e)throw new Error(t)};e.action=(e,n)=>({run:function(){return e(...[].slice.call(arguments)),t},name:u(n),onAction:void 0}),e.computed=(e,t)=>{const n={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:t?.initial,isComputing:!1,name:u(t?.name),reducer:e,subscribes:new Set},s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>g(n,e),s._internal=n,s},e.flushStates=()=>{const e=n;return n=void 0,e},e.setContext=()=>{s=new WeakMap},e.startRecord=()=>{n=new Set},e.state=function(e,t){S(h(e),"Function not allowed in state");const n={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:u(t?.name),subscribes:new Set,hasParentUpdates:void 0};b(n,e);const s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>g(n,e),s.set=e=>b(n,e),s._internal=n,s},e.subscribe=g}); | ||
| //# sourceMappingURL=index.umd.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.umd.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} from './types.js'\r\n\r\nlet cache = new WeakMap<StateVariants, StateType>()\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// <T extends StateType>(state: StateVariants<T>\r\nexport const getCachValue = (state: StateVariants): unknown => {\r\n return cache.get(state)\r\n}\r\n\r\nconst setCacheValue = (state: StateVariants, value: StateType): void => {\r\n cache.set(state, 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\nexport const setContext = () => {\r\n cache = new WeakMap<object, StateType>()\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 updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\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 = getCachValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\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\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 applyUpdates(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 getCachValue(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 = getCachValue(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 === getCachValue(state)) {\r\n return\r\n }\r\n applyUpdates(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\nconst applyUpdates = (state: CommonInternal, value: unknown): void => {\r\n setCacheValue(state, value)\r\n updateHistory(state, value)\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 if (computedState) {\r\n getComputedValue(computedState)\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: 0,\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: 0,\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 *\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): 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(name),\r\n onAction: undefined,\r\n }\r\n}\r\n"],"names":["_this","this","recording","cache","WeakMap","isNotifying","defaultName","names","Set","requesters","states2notify","getCachValue","state","get","getName","name","has","console","error","getComputed","isFunction","v","getComputedValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","assert","isComputing","push","value","reducer","initial","pop","applyUpdates","e","message","getValue","lastRequester","at","childs","add","depends","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","length","st","forEach","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","computedState","delete","parent","condtion","msg","run","slice","call","arguments","onAction","options","data","Array","from","publicApi","Object","defineProperty","subscribe","_internal"],"mappings":"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"} | ||
| {"version":3,"file":"index.umd.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} from './types.js'\r\n\r\nlet cache = new WeakMap<StateVariants, StateType>()\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// <T extends StateType>(state: StateVariants<T>\r\nexport const getCachValue = (state: StateVariants): unknown => {\r\n return cache.get(state)\r\n}\r\n\r\nconst setCacheValue = (state: StateVariants, value: StateType): void => {\r\n cache.set(state, 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\nexport const setContext = () => {\r\n cache = new WeakMap<object, StateType>()\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 updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\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 = getCachValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n state.depends.forEach((item) => {\r\n recording.add(item)\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\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 applyUpdates(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 getCachValue(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 = getCachValue(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 === getCachValue(state)) {\r\n return\r\n }\r\n applyUpdates(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\nconst applyUpdates = (state: CommonInternal, value: unknown): void => {\r\n setCacheValue(state, value)\r\n updateHistory(state, value)\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 if (computedState) {\r\n getComputedValue(computedState)\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: 0,\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: 0,\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 *\r\n * @param value - Action function\r\n * @param name\r\n */\r\nexport const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): 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(name),\r\n onAction: undefined,\r\n }\r\n}\r\n"],"names":["_this","this","recording","cache","WeakMap","isNotifying","defaultName","names","requesters","states2notify","Set","getCachValue","state","get","getName","name","has","console","error","getComputed","isFunction","v","getComputedValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","push","value","reducer","initial","pop","applyUpdates","e","message","getValue","lastRequester","at","childs","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","length","st","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","subscribe","computedState","delete","parent","condtion","msg","Error","run","slice","call","arguments","onAction","options","data","Array","from","Object","defineProperty","publicApi","_internal"],"mappings":"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"} |
+1
-3
@@ -25,5 +25,3 @@ export type Func = (...args: unknown[]) => unknown; | ||
| childs: Set<CommonInternal>; | ||
| depends: Set<{ | ||
| childs: Set<CommonInternal>; | ||
| }>; | ||
| depends: Set<CommonInternal>; | ||
| subscribes: Set<Listner>; | ||
@@ -30,0 +28,0 @@ name: string; |
+2
-2
| { | ||
| "name": "@statx/core", | ||
| "version": "1.0.12", | ||
| "version": "1.0.17", | ||
| "private": false, | ||
@@ -70,3 +70,3 @@ "description": "Extry tiny smart state manager", | ||
| }, | ||
| "gitHead": "6725eba840c607e6afed7a7d83b1d5a969af6299" | ||
| "gitHead": "e8221fc01699d8f7cbd4421633ddaaf1f1698b86" | ||
| } |
+3
-0
@@ -88,2 +88,5 @@ import { | ||
| if (isDontNeedRecalc(state, prevState)) { | ||
| state.depends.forEach((item) => { | ||
| recording.add(item) | ||
| }) | ||
| return prevState | ||
@@ -90,0 +93,0 @@ } |
+1
-3
@@ -53,5 +53,3 @@ export type Func = (...args: unknown[]) => unknown | ||
| childs: Set<CommonInternal> | ||
| depends: Set<{ | ||
| childs: Set<CommonInternal> | ||
| }> | ||
| depends: Set<CommonInternal> | ||
| subscribes: Set<Listner> | ||
@@ -58,0 +56,0 @@ name: string |
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
93441
4.7%22
10%771
1.31%5
25%