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

@statx/core

Package Overview
Dependencies
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@statx/core - npm Package Compare versions

Comparing version
1.0.18
to
1.0.20
+1
-1
./build/index.js

@@ -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),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 t&&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;
var e=void 0;let r,s=!1;const t="Unnamed state",n=new Set,o=[],a=new Set,i=e=>e.history[e.historyCursor],c=(e,r)=>{const s=e.historyCursor;e.history[s]=r,e.historyCursor=(s+1)%e.history.length},d=e=>e&&n.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),t):e||t,u=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,l=e=>{try{const s=i(e);if(((e,r)=>!1===e.hasParentUpdates&&void 0!==r)(e,s))return r&&e.depends.forEach(e=>{r?.add(e)}),s;w(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),o.push(e),e.depends.forEach(r=>{r.childs.delete(e)}),e.depends.clear(),e.isComputing=!0;const t=e.reducer(s??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,o.pop(),c(e,t),t}catch(e){return void console.error(e.message)}},p=e=>{const s=u(e);try{const t=o.at(-1);return t&&!e.childs.has(t)&&(e.childs.add(t),t.depends.add(e)),s?l(s):i(e)}finally{r&&!s&&r.add(e)}},f=(e,r)=>{const s=h(r)?((e,r)=>r(i(e)))(e,r):r;s!==i(e)&&(c(e,s),b(e),m())},b=e=>{const r=[e];for(;r.length;){const e=r.pop();e.childs.forEach(e=>r.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&a.add(e)}},m=()=>{!1===s&&(s=!0,queueMicrotask(()=>{a.forEach(e=>{try{e.subscribes.forEach(r=>r(p(e)))}catch(r){console.error("Error in subscriber function of:",e.name)}}),a.clear(),s=!1}))},y=(e,r)=>{if(e.subscribes.has(r))return()=>({});const s=u(e);return s&&(l(s),e.depends.forEach(r=>r.childs.add(e))),e.subscribes.add(r),()=>{e.subscribes.delete(r),0===e.subscribes.size&&e.depends.forEach(r=>r.childs.delete(e))}},w=(e,r)=>{if(e)throw new Error(r)};exports.action=(r,s)=>({run:function(){return r(...[].slice.call(arguments)),e},name:d(s.name),onAction:s.onAction}),exports.computed=(e,r)=>{const s={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:r?.initial,isComputing:!1,name:d(r?.name),reducer:e,subscribes:new Set},t=function(){return p(s)};return Object.defineProperty(t,"name",{value:s.name}),t.subscribe=e=>y(s,e),t._internal=s,t},exports.flushStates=()=>{const e=r;return r=void 0,e},exports.startRecord=()=>{r=new Set},exports.state=function(e,r){w(h(e),"Function not allowed in state");const s={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:d(r?.name),subscribes:new Set,hasParentUpdates:void 0};f(s,e);const t=function(){return p(s)};return Object.defineProperty(t,"name",{value:s.name}),t.subscribe=e=>y(s,e),t.set=e=>f(s,e),t._internal=s,t},exports.subscribe=y;
//# sourceMappingURL=index.js.map

@@ -1,5 +0,4 @@

import { Listner, StateType, Settings, StateVariants, Action, Options, ComputedInternalOptions, StatlessFunc, GetStatlessFunc, State, Computed, UnSubscribe, CommonInternal, StateInternal } from './types.js';
export declare const getCachValue: (state: StateVariants) => unknown;
import { Listner, StateType, Settings, StateVariants, Action, Options, ComputedInternalOptions, StatlessFunc, GetStatlessFunc, State, Computed, UnSubscribe, CommonInternal, StateInternal, ActionOptions } from './types.js';
export declare const getHistoryValue: (state: StateVariants) => unknown;
export declare const setSetting: (data: Partial<Settings>) => void;
export declare const setContext: () => void;
export declare const startRecord: () => void;

@@ -10,2 +9,2 @@ export declare const flushStates: () => Set<StateInternal>;

export declare const computed: <T extends unknown = -1, S extends StatlessFunc<T> = StatlessFunc<T>, O extends ComputedInternalOptions<unknown> = ComputedInternalOptions<unknown>>(value: GetStatlessFunc<T, S, O>, options?: O) => Computed<T>;
export declare const action: <T extends unknown[]>(value: (...args: T) => void, name?: string) => Action<T>;
export declare const action: <T extends unknown[]>(value: (...args: T) => void, options?: ActionOptions) => Action<T>;

@@ -1,2 +0,2 @@

export { state, action, computed, subscribe, startRecord, flushStates, setContext } from './core.js';
export { state, action, computed, subscribe, startRecord, flushStates } from './core.js';
export * from './types.js';

@@ -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),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 t&&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;
var e=void 0;let r,s=!1;const t="Unnamed state",n=new Set,o=[],a=new Set,i=e=>e.history[e.historyCursor],c=(e,r)=>{const s=e.historyCursor;e.history[s]=r,e.historyCursor=(s+1)%e.history.length},d=e=>e&&n.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),t):e||t,u=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,l=e=>{try{const s=i(e);if(((e,r)=>!1===e.hasParentUpdates&&void 0!==r)(e,s))return r&&e.depends.forEach(e=>{r?.add(e)}),s;w(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),o.push(e),e.depends.forEach(r=>{r.childs.delete(e)}),e.depends.clear(),e.isComputing=!0;const t=e.reducer(s??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,o.pop(),c(e,t),t}catch(e){return void console.error(e.message)}},p=e=>{const s=u(e);try{const t=o.at(-1);return t&&!e.childs.has(t)&&(e.childs.add(t),t.depends.add(e)),s?l(s):i(e)}finally{r&&!s&&r.add(e)}},f=(e,r)=>{const s=h(r)?((e,r)=>r(i(e)))(e,r):r;s!==i(e)&&(c(e,s),b(e),m())},b=e=>{const r=[e];for(;r.length;){const e=r.pop();e.childs.forEach(e=>r.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&a.add(e)}},m=()=>{!1===s&&(s=!0,queueMicrotask(()=>{a.forEach(e=>{try{e.subscribes.forEach(r=>r(p(e)))}catch(r){console.error("Error in subscriber function of:",e.name)}}),a.clear(),s=!1}))},y=(e,r)=>{if(e.subscribes.has(r))return()=>({});const s=u(e);return s&&(l(s),e.depends.forEach(r=>r.childs.add(e))),e.subscribes.add(r),()=>{e.subscribes.delete(r),0===e.subscribes.size&&e.depends.forEach(r=>r.childs.delete(e))}},w=(e,r)=>{if(e)throw new Error(r)};exports.action=(r,s)=>({run:function(){return r(...[].slice.call(arguments)),e},name:d(s.name),onAction:s.onAction}),exports.computed=(e,r)=>{const s={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:r?.initial,isComputing:!1,name:d(r?.name),reducer:e,subscribes:new Set},t=function(){return p(s)};return Object.defineProperty(t,"name",{value:s.name}),t.subscribe=e=>y(s,e),t._internal=s,t},exports.flushStates=()=>{const e=r;return r=void 0,e},exports.startRecord=()=>{r=new Set},exports.state=function(e,r){w(h(e),"Function not allowed in state");const s={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:d(r?.name),subscribes:new Set,hasParentUpdates:void 0};f(s,e);const t=function(){return p(s)};return Object.defineProperty(t,"name",{value:s.name}),t.subscribe=e=>y(s,e),t.set=e=>f(s,e),t._internal=s,t},exports.subscribe=y;
//# 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 if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n\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","reducer","initial","pop","applyUpdates","value","e","message","getValue","lastRequester","at","childs","setValue","getValueOfSetterFunction","newValue","invalidateSubtree","notifySubscribers","stack","length","st","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","computedState","delete","parent","condtion","msg","Error","run","slice","call","arguments","onAction","options","data","Array","from","Object","defineProperty","publicApi","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 ActionOptions,\r\n} from './types.js'\r\n\r\nlet isNotifying = false\r\nlet isActionNow = false\r\nlet recording: Set<StateInternal> | undefined\r\n\r\nconst defaultName = 'Unnamed state'\r\nconst names = new Set()\r\nconst requesters: ComputedInternal[] = []\r\nconst states2notify = new Set<StateVariants>()\r\nconst settings: Settings = {\r\n historyLength: 5,\r\n}\r\n\r\nexport const getHistoryValue = (state: StateVariants): unknown => {\r\n return state.history[state.historyCursor]\r\n}\r\nconst pushHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\r\n}\r\n\r\nconst getName = (name?: string): string => {\r\n if (name && names.has(name)) {\r\n console.error(`Name ${name} already used! Replaced to undefined`)\r\n return defaultName\r\n }\r\n if (name) {\r\n return name\r\n }\r\n return defaultName\r\n}\r\n\r\nexport const setSetting = (data: Partial<Settings>) => {\r\n Object.assign(settings, data)\r\n}\r\n\r\nconst getComputed = (state: CommonInternal | ComputedInternal) => {\r\n if ('reducer' in state) {\r\n return state\r\n }\r\n}\r\n\r\nconst isFunction = (v: unknown): v is Func => {\r\n return typeof v === 'function'\r\n}\r\n\r\nconst isDontNeedRecalc = (state: CommonInternal, prevState: unknown): boolean => {\r\n return state.hasParentUpdates === false && prevState !== undefined\r\n}\r\n\r\nconst getComputedValue = (state: ComputedInternal): unknown => {\r\n try {\r\n const prevState = getHistoryValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n state.depends.forEach((item) => {\r\n item.childs.delete(state)\r\n })\r\n state.depends.clear()\r\n state.isComputing = true\r\n const value = state.reducer(prevState ?? state.initial)\r\n state.isComputing = false\r\n state.hasParentUpdates = false\r\n\r\n requesters.pop()\r\n pushHistory(state, value)\r\n\r\n return value\r\n } catch (e) {\r\n console.error((e as Error).message)\r\n return undefined\r\n }\r\n}\r\n\r\nconst getValue = (state: CommonInternal) => {\r\n const reducer = getComputed(state)\r\n try {\r\n const lastRequester = requesters.at(-1)\r\n if (lastRequester && !state.childs.has(lastRequester)) {\r\n state.childs.add(lastRequester)\r\n lastRequester.depends.add(state)\r\n }\r\n if (reducer) {\r\n return getComputedValue(reducer)\r\n }\r\n return getHistoryValue(state)\r\n } finally {\r\n if (recording && !reducer) {\r\n recording.add(state)\r\n }\r\n }\r\n}\r\n\r\nconst getValueOfSetterFunction = (state: CommonInternal, value: SetterFunc): unknown => {\r\n const prevValue = getHistoryValue(state)\r\n return value(prevValue)\r\n}\r\n\r\nconst setValue = (state: CommonInternal, value: unknown): void => {\r\n const newValue = isFunction(value) ? getValueOfSetterFunction(state, value) : value\r\n\r\n if (newValue === getHistoryValue(state)) {\r\n return\r\n }\r\n pushHistory(state, newValue)\r\n invalidateSubtree(state)\r\n notifySubscribers()\r\n}\r\n\r\n/**\r\n * Mark all subtree is non actual.\r\n * Collect all nodes to notify subscribers im microtask queue.\r\n */\r\nconst invalidateSubtree = (state: CommonInternal) => {\r\n const stack: CommonInternal[] = [state]\r\n\r\n while (stack.length) {\r\n const st = stack.pop()\r\n st.childs.forEach((it) => stack.push(it))\r\n st.hasParentUpdates = true\r\n if (st.subscribes.size) {\r\n states2notify.add(st)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all collected subscribers once in microtask queue\r\n */\r\nconst notifySubscribers = () => {\r\n if (isNotifying === false) {\r\n isNotifying = true\r\n queueMicrotask(() => {\r\n // Нужно обновить дерево\r\n states2notify.forEach((state) => {\r\n try {\r\n state.subscribes.forEach((listner) => {\r\n return listner(getValue(state))\r\n })\r\n } catch (e) {\r\n console.error('Error in subscriber function of:', state.name)\r\n }\r\n })\r\n states2notify.clear()\r\n isNotifying = false\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * Start collecting all non computed states.\r\n *\r\n * Helper for render adapters.\r\n */\r\nexport const startRecord = () => {\r\n recording = new Set()\r\n}\r\n\r\n/**\r\n * Flush all collected non computed states.\r\n */\r\nexport const flushStates = (): Set<StateInternal> => {\r\n const data = recording\r\n recording = undefined\r\n return data\r\n}\r\n\r\nexport const subscribe = (state: CommonInternal | CommonInternal, listner: Listner): UnSubscribe => {\r\n /**\r\n * Если значение стейта ниразу не расчитывалось, его нужно обновить\r\n * Если подписываемся на вычисляемый стэйт, то нужно узнать всех родителей\r\n * Родители могут меняться, поэтому после каждого вычисления нужно обновлять зависимости дерева\r\n *\r\n * При отписке нужно оповестить всех на кого были опдписанты о том что мы отписались\r\n *\r\n */\r\n\r\n if (state.subscribes.has(listner)) {\r\n return () => ({})\r\n }\r\n\r\n const computedState = getComputed(state)\r\n // Нужно актуализировать в родилеях зависимость\r\n if (computedState) {\r\n getComputedValue(computedState)\r\n state.depends.forEach((parent) => parent.childs.add(state))\r\n }\r\n\r\n state.subscribes.add(listner)\r\n\r\n return () => {\r\n state.subscribes.delete(listner)\r\n if (state.subscribes.size === 0) {\r\n state.depends.forEach((parent) => parent.childs.delete(state))\r\n }\r\n }\r\n}\r\n\r\nconst assert = (condtion: boolean, msg: string) => {\r\n if (condtion) {\r\n throw new Error(msg)\r\n }\r\n}\r\n\r\n/**\r\n *\r\n * @param value - Reducer or value\r\n * @param name - name of state. For loggin or easy debug\r\n * @returns State<T>\r\n */\r\nexport function state<T extends StateType = StateType>(value: T, options?: Options): State<T> {\r\n assert(isFunction(value), 'Function not allowed in state')\r\n\r\n const data: CommonInternal = {\r\n childs: new Set(),\r\n depends: new Set(),\r\n history: Array.from({length: settings.historyLength}),\r\n historyCursor: 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[]>(\r\n value: (...args: T) => void,\r\n options?: ActionOptions,\r\n): Action<T> => {\r\n return {\r\n run: (...args: T) => {\r\n isActionNow = true\r\n value(...args)\r\n isActionNow = false\r\n return this\r\n },\r\n name: getName(options.name),\r\n onAction: options.onAction,\r\n }\r\n}\r\n"],"names":["_this","this","recording","isNotifying","names","Set","requesters","states2notify","getHistoryValue","state","history","historyCursor","pushHistory","value","cursorHistory","length","getName","name","has","console","error","defaultName","isFunction","v","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","push","childs","delete","clear","reducer","initial","pop","e","message","getValue","getComputed","lastRequester","at","getComputedValue","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","st","it","subscribes","size","queueMicrotask","listner","subscribe","computedState","parent","condtion","msg","Error","options","run","slice","call","arguments","onAction","data","Array","from","publicApi","Object","defineProperty","_internal","set"],"mappings":"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"}

@@ -1,2 +0,2 @@

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 e&&n.depends.forEach(n=>{var r;null==(r=e)||r.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};
let e,n=!1;const r="Unnamed state",s=new Set,t=[],o=new Set,i=e=>e.history[e.historyCursor],a=(e,n)=>{const r=e.historyCursor;e.history[r]=n,e.historyCursor=(r+1)%e.history.length},d=e=>e&&s.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),r):e||r,c=e=>{if("reducer"in e)return e},u=e=>"function"==typeof e,l=n=>{try{var r;const s=i(n);if(((e,n)=>!1===e.hasParentUpdates&&void 0!==n)(n,s))return e&&n.depends.forEach(n=>{var r;null==(r=e)||r.add(n)}),s;v(n.isComputing,`Loops dosen't allows. Name: ${null!=(r=n.name)?r:"Unnamed state"}`),t.push(n),n.depends.forEach(e=>{e.childs.delete(n)}),n.depends.clear(),n.isComputing=!0;const o=n.reducer(null!=s?s:n.initial);return n.isComputing=!1,n.hasParentUpdates=!1,t.pop(),a(n,o),o}catch(e){return void console.error(e.message)}},h=n=>{const r=c(n);try{const s=t.at(-1);return s&&!n.childs.has(s)&&(n.childs.add(s),s.depends.add(n)),r?l(r):i(n)}finally{e&&!r&&e.add(n)}},p=(e,n)=>{const r=u(n)?((e,n)=>n(i(e)))(e,n):n;r!==i(e)&&(a(e,r),f(e),b())},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&&o.add(e)}},b=()=>{!1===n&&(n=!0,queueMicrotask(()=>{o.forEach(e=>{try{e.subscribes.forEach(n=>n(h(e)))}catch(n){console.error("Error in subscriber function of:",e.name)}}),o.clear(),n=!1}))},m=()=>{e=new Set},y=()=>{const n=e;return e=void 0,n},w=(e,n)=>{if(e.subscribes.has(n))return()=>({});const r=c(e);return r&&(l(r),e.depends.forEach(n=>n.childs.add(e))),e.subscribes.add(n),()=>{e.subscribes.delete(n),0===e.subscribes.size&&e.depends.forEach(n=>n.childs.delete(e))}},v=(e,n)=>{if(e)throw new Error(n)};function g(e,n){v(u(e),"Function not allowed in state");const r={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:d(null==n?void 0:n.name),subscribes:new Set,hasParentUpdates:void 0};p(r,e);const s=function(){return h(r)};return Object.defineProperty(s,"name",{value:r.name}),s.subscribe=e=>w(r,e),s.set=e=>p(r,e),s._internal=r,s}const C=(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:d(null==n?void 0:n.name),reducer:e,subscribes:new Set},s=function(){return h(r)};return Object.defineProperty(s,"name",{value:r.name}),s.subscribe=e=>w(r,e),s._internal=r,s},E=(e,n)=>({run:(...n)=>{e(...n)},name:d(n.name),onAction:n.onAction});export{E as action,C as computed,y as flushStates,m as startRecord,g as state,w 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 if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n\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","getComputed","isFunction","v","getComputedValue","_state$name","getCachValue","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","_recording","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","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 ActionOptions,\r\n} from './types.js'\r\n\r\nlet isNotifying = false\r\nlet isActionNow = false\r\nlet recording: Set<StateInternal> | undefined\r\n\r\nconst defaultName = 'Unnamed state'\r\nconst names = new Set()\r\nconst requesters: ComputedInternal[] = []\r\nconst states2notify = new Set<StateVariants>()\r\nconst settings: Settings = {\r\n historyLength: 5,\r\n}\r\n\r\nexport const getHistoryValue = (state: StateVariants): unknown => {\r\n return state.history[state.historyCursor]\r\n}\r\nconst pushHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\r\n}\r\n\r\nconst getName = (name?: string): string => {\r\n if (name && names.has(name)) {\r\n console.error(`Name ${name} already used! Replaced to undefined`)\r\n return defaultName\r\n }\r\n if (name) {\r\n return name\r\n }\r\n return defaultName\r\n}\r\n\r\nexport const setSetting = (data: Partial<Settings>) => {\r\n Object.assign(settings, data)\r\n}\r\n\r\nconst getComputed = (state: CommonInternal | ComputedInternal) => {\r\n if ('reducer' in state) {\r\n return state\r\n }\r\n}\r\n\r\nconst isFunction = (v: unknown): v is Func => {\r\n return typeof v === 'function'\r\n}\r\n\r\nconst isDontNeedRecalc = (state: CommonInternal, prevState: unknown): boolean => {\r\n return state.hasParentUpdates === false && prevState !== undefined\r\n}\r\n\r\nconst getComputedValue = (state: ComputedInternal): unknown => {\r\n try {\r\n const prevState = getHistoryValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n state.depends.forEach((item) => {\r\n item.childs.delete(state)\r\n })\r\n state.depends.clear()\r\n state.isComputing = true\r\n const value = state.reducer(prevState ?? state.initial)\r\n state.isComputing = false\r\n state.hasParentUpdates = false\r\n\r\n requesters.pop()\r\n pushHistory(state, value)\r\n\r\n return value\r\n } catch (e) {\r\n console.error((e as Error).message)\r\n return undefined\r\n }\r\n}\r\n\r\nconst getValue = (state: CommonInternal) => {\r\n const reducer = getComputed(state)\r\n try {\r\n const lastRequester = requesters.at(-1)\r\n if (lastRequester && !state.childs.has(lastRequester)) {\r\n state.childs.add(lastRequester)\r\n lastRequester.depends.add(state)\r\n }\r\n if (reducer) {\r\n return getComputedValue(reducer)\r\n }\r\n return getHistoryValue(state)\r\n } finally {\r\n if (recording && !reducer) {\r\n recording.add(state)\r\n }\r\n }\r\n}\r\n\r\nconst getValueOfSetterFunction = (state: CommonInternal, value: SetterFunc): unknown => {\r\n const prevValue = getHistoryValue(state)\r\n return value(prevValue)\r\n}\r\n\r\nconst setValue = (state: CommonInternal, value: unknown): void => {\r\n const newValue = isFunction(value) ? getValueOfSetterFunction(state, value) : value\r\n\r\n if (newValue === getHistoryValue(state)) {\r\n return\r\n }\r\n pushHistory(state, newValue)\r\n invalidateSubtree(state)\r\n notifySubscribers()\r\n}\r\n\r\n/**\r\n * Mark all subtree is non actual.\r\n * Collect all nodes to notify subscribers im microtask queue.\r\n */\r\nconst invalidateSubtree = (state: CommonInternal) => {\r\n const stack: CommonInternal[] = [state]\r\n\r\n while (stack.length) {\r\n const st = stack.pop()\r\n st.childs.forEach((it) => stack.push(it))\r\n st.hasParentUpdates = true\r\n if (st.subscribes.size) {\r\n states2notify.add(st)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all collected subscribers once in microtask queue\r\n */\r\nconst notifySubscribers = () => {\r\n if (isNotifying === false) {\r\n isNotifying = true\r\n queueMicrotask(() => {\r\n // Нужно обновить дерево\r\n states2notify.forEach((state) => {\r\n try {\r\n state.subscribes.forEach((listner) => {\r\n return listner(getValue(state))\r\n })\r\n } catch (e) {\r\n console.error('Error in subscriber function of:', state.name)\r\n }\r\n })\r\n states2notify.clear()\r\n isNotifying = false\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * Start collecting all non computed states.\r\n *\r\n * Helper for render adapters.\r\n */\r\nexport const startRecord = () => {\r\n recording = new Set()\r\n}\r\n\r\n/**\r\n * Flush all collected non computed states.\r\n */\r\nexport const flushStates = (): Set<StateInternal> => {\r\n const data = recording\r\n recording = undefined\r\n return data\r\n}\r\n\r\nexport const subscribe = (state: CommonInternal | CommonInternal, listner: Listner): UnSubscribe => {\r\n /**\r\n * Если значение стейта ниразу не расчитывалось, его нужно обновить\r\n * Если подписываемся на вычисляемый стэйт, то нужно узнать всех родителей\r\n * Родители могут меняться, поэтому после каждого вычисления нужно обновлять зависимости дерева\r\n *\r\n * При отписке нужно оповестить всех на кого были опдписанты о том что мы отписались\r\n *\r\n */\r\n\r\n if (state.subscribes.has(listner)) {\r\n return () => ({})\r\n }\r\n\r\n const computedState = getComputed(state)\r\n // Нужно актуализировать в родилеях зависимость\r\n if (computedState) {\r\n getComputedValue(computedState)\r\n state.depends.forEach((parent) => parent.childs.add(state))\r\n }\r\n\r\n state.subscribes.add(listner)\r\n\r\n return () => {\r\n state.subscribes.delete(listner)\r\n if (state.subscribes.size === 0) {\r\n state.depends.forEach((parent) => parent.childs.delete(state))\r\n }\r\n }\r\n}\r\n\r\nconst assert = (condtion: boolean, msg: string) => {\r\n if (condtion) {\r\n throw new Error(msg)\r\n }\r\n}\r\n\r\n/**\r\n *\r\n * @param value - Reducer or value\r\n * @param name - name of state. For loggin or easy debug\r\n * @returns State<T>\r\n */\r\nexport function state<T extends StateType = StateType>(value: T, options?: Options): State<T> {\r\n assert(isFunction(value), 'Function not allowed in state')\r\n\r\n const data: CommonInternal = {\r\n childs: new Set(),\r\n depends: new Set(),\r\n history: Array.from({length: settings.historyLength}),\r\n historyCursor: 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[]>(\r\n value: (...args: T) => void,\r\n options?: ActionOptions,\r\n): Action<T> => {\r\n return {\r\n run: (...args: T) => {\r\n isActionNow = true\r\n value(...args)\r\n isActionNow = false\r\n return this\r\n },\r\n name: getName(options.name),\r\n onAction: options.onAction,\r\n }\r\n}\r\n"],"names":["recording","isNotifying","names","Set","requesters","states2notify","getHistoryValue","state","history","historyCursor","pushHistory","value","cursorHistory","length","getName","name","has","console","error","defaultName","getComputed","isFunction","v","getComputedValue","_state$name","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","_recording","add","assert","isComputing","push","childs","delete","clear","reducer","initial","pop","e","message","getValue","at","lastRequester","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","st","it","subscribes","size","queueMicrotask","listner","startRecord","flushStates","data","subscribe","computedState","parent","condtion","msg","options","Array","from","publicApi","Object","defineProperty","set","_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,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 n&&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};
var e=void 0;let r,n=!1;const s="Unnamed state",t=new Set,o=[],i=new Set,a=e=>e.history[e.historyCursor],c=(e,r)=>{const n=e.historyCursor;e.history[n]=r,e.historyCursor=(n+1)%e.history.length},d=e=>e&&t.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),s):e||s,u=e=>{if("reducer"in e)return e},h=e=>"function"==typeof e,l=e=>{try{const n=a(e);if(((e,r)=>!1===e.hasParentUpdates&&void 0!==r)(e,n))return r&&e.depends.forEach(e=>{r?.add(e)}),n;C(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),o.push(e),e.depends.forEach(r=>{r.childs.delete(e)}),e.depends.clear(),e.isComputing=!0;const s=e.reducer(n??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,o.pop(),c(e,s),s}catch(e){return void console.error(e.message)}},p=e=>{const n=u(e);try{const s=o.at(-1);return s&&!e.childs.has(s)&&(e.childs.add(s),s.depends.add(e)),n?l(n):a(e)}finally{r&&!n&&r.add(e)}},f=(e,r)=>{const n=h(r)?((e,r)=>r(a(e)))(e,r):r;n!==a(e)&&(c(e,n),b(e),m())},b=e=>{const r=[e];for(;r.length;){const e=r.pop();e.childs.forEach(e=>r.push(e)),e.hasParentUpdates=!0,e.subscribes.size&&i.add(e)}},m=()=>{!1===n&&(n=!0,queueMicrotask(()=>{i.forEach(e=>{try{e.subscribes.forEach(r=>r(p(e)))}catch(r){console.error("Error in subscriber function of:",e.name)}}),i.clear(),n=!1}))},y=()=>{r=new Set},w=()=>{const e=r;return r=void 0,e},g=(e,r)=>{if(e.subscribes.has(r))return()=>({});const n=u(e);return n&&(l(n),e.depends.forEach(r=>r.childs.add(e))),e.subscribes.add(r),()=>{e.subscribes.delete(r),0===e.subscribes.size&&e.depends.forEach(r=>r.childs.delete(e))}},C=(e,r)=>{if(e)throw new Error(r)};function E(e,r){C(h(e),"Function not allowed in state");const n={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:d(r?.name),subscribes:new Set,hasParentUpdates:void 0};f(n,e);const s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>g(n,e),s.set=e=>f(n,e),s._internal=n,s}const S=(e,r)=>{const n={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:r?.initial,isComputing:!1,name:d(r?.name),reducer:e,subscribes:new Set},s=function(){return p(n)};return Object.defineProperty(s,"name",{value:n.name}),s.subscribe=e=>g(n,e),s._internal=n,s},v=(r,n)=>({run:function(){return r(...[].slice.call(arguments)),e},name:d(n.name),onAction:n.onAction});export{v as action,S as computed,w as flushStates,y as startRecord,E as state,g 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 if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n\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","reducer","initial","pop","applyUpdates","value","e","message","getValue","lastRequester","at","childs","setValue","getValueOfSetterFunction","newValue","invalidateSubtree","notifySubscribers","stack","length","st","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","startRecord","flushStates","data","computedState","delete","parent","condtion","msg","Error","options","Array","from","Object","defineProperty","publicApi","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 ActionOptions,\r\n} from './types.js'\r\n\r\nlet isNotifying = false\r\nlet isActionNow = false\r\nlet recording: Set<StateInternal> | undefined\r\n\r\nconst defaultName = 'Unnamed state'\r\nconst names = new Set()\r\nconst requesters: ComputedInternal[] = []\r\nconst states2notify = new Set<StateVariants>()\r\nconst settings: Settings = {\r\n historyLength: 5,\r\n}\r\n\r\nexport const getHistoryValue = (state: StateVariants): unknown => {\r\n return state.history[state.historyCursor]\r\n}\r\nconst pushHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\r\n}\r\n\r\nconst getName = (name?: string): string => {\r\n if (name && names.has(name)) {\r\n console.error(`Name ${name} already used! Replaced to undefined`)\r\n return defaultName\r\n }\r\n if (name) {\r\n return name\r\n }\r\n return defaultName\r\n}\r\n\r\nexport const setSetting = (data: Partial<Settings>) => {\r\n Object.assign(settings, data)\r\n}\r\n\r\nconst getComputed = (state: CommonInternal | ComputedInternal) => {\r\n if ('reducer' in state) {\r\n return state\r\n }\r\n}\r\n\r\nconst isFunction = (v: unknown): v is Func => {\r\n return typeof v === 'function'\r\n}\r\n\r\nconst isDontNeedRecalc = (state: CommonInternal, prevState: unknown): boolean => {\r\n return state.hasParentUpdates === false && prevState !== undefined\r\n}\r\n\r\nconst getComputedValue = (state: ComputedInternal): unknown => {\r\n try {\r\n const prevState = getHistoryValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n state.depends.forEach((item) => {\r\n item.childs.delete(state)\r\n })\r\n state.depends.clear()\r\n state.isComputing = true\r\n const value = state.reducer(prevState ?? state.initial)\r\n state.isComputing = false\r\n state.hasParentUpdates = false\r\n\r\n requesters.pop()\r\n pushHistory(state, value)\r\n\r\n return value\r\n } catch (e) {\r\n console.error((e as Error).message)\r\n return undefined\r\n }\r\n}\r\n\r\nconst getValue = (state: CommonInternal) => {\r\n const reducer = getComputed(state)\r\n try {\r\n const lastRequester = requesters.at(-1)\r\n if (lastRequester && !state.childs.has(lastRequester)) {\r\n state.childs.add(lastRequester)\r\n lastRequester.depends.add(state)\r\n }\r\n if (reducer) {\r\n return getComputedValue(reducer)\r\n }\r\n return getHistoryValue(state)\r\n } finally {\r\n if (recording && !reducer) {\r\n recording.add(state)\r\n }\r\n }\r\n}\r\n\r\nconst getValueOfSetterFunction = (state: CommonInternal, value: SetterFunc): unknown => {\r\n const prevValue = getHistoryValue(state)\r\n return value(prevValue)\r\n}\r\n\r\nconst setValue = (state: CommonInternal, value: unknown): void => {\r\n const newValue = isFunction(value) ? getValueOfSetterFunction(state, value) : value\r\n\r\n if (newValue === getHistoryValue(state)) {\r\n return\r\n }\r\n pushHistory(state, newValue)\r\n invalidateSubtree(state)\r\n notifySubscribers()\r\n}\r\n\r\n/**\r\n * Mark all subtree is non actual.\r\n * Collect all nodes to notify subscribers im microtask queue.\r\n */\r\nconst invalidateSubtree = (state: CommonInternal) => {\r\n const stack: CommonInternal[] = [state]\r\n\r\n while (stack.length) {\r\n const st = stack.pop()\r\n st.childs.forEach((it) => stack.push(it))\r\n st.hasParentUpdates = true\r\n if (st.subscribes.size) {\r\n states2notify.add(st)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all collected subscribers once in microtask queue\r\n */\r\nconst notifySubscribers = () => {\r\n if (isNotifying === false) {\r\n isNotifying = true\r\n queueMicrotask(() => {\r\n // Нужно обновить дерево\r\n states2notify.forEach((state) => {\r\n try {\r\n state.subscribes.forEach((listner) => {\r\n return listner(getValue(state))\r\n })\r\n } catch (e) {\r\n console.error('Error in subscriber function of:', state.name)\r\n }\r\n })\r\n states2notify.clear()\r\n isNotifying = false\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * Start collecting all non computed states.\r\n *\r\n * Helper for render adapters.\r\n */\r\nexport const startRecord = () => {\r\n recording = new Set()\r\n}\r\n\r\n/**\r\n * Flush all collected non computed states.\r\n */\r\nexport const flushStates = (): Set<StateInternal> => {\r\n const data = recording\r\n recording = undefined\r\n return data\r\n}\r\n\r\nexport const subscribe = (state: CommonInternal | CommonInternal, listner: Listner): UnSubscribe => {\r\n /**\r\n * Если значение стейта ниразу не расчитывалось, его нужно обновить\r\n * Если подписываемся на вычисляемый стэйт, то нужно узнать всех родителей\r\n * Родители могут меняться, поэтому после каждого вычисления нужно обновлять зависимости дерева\r\n *\r\n * При отписке нужно оповестить всех на кого были опдписанты о том что мы отписались\r\n *\r\n */\r\n\r\n if (state.subscribes.has(listner)) {\r\n return () => ({})\r\n }\r\n\r\n const computedState = getComputed(state)\r\n // Нужно актуализировать в родилеях зависимость\r\n if (computedState) {\r\n getComputedValue(computedState)\r\n state.depends.forEach((parent) => parent.childs.add(state))\r\n }\r\n\r\n state.subscribes.add(listner)\r\n\r\n return () => {\r\n state.subscribes.delete(listner)\r\n if (state.subscribes.size === 0) {\r\n state.depends.forEach((parent) => parent.childs.delete(state))\r\n }\r\n }\r\n}\r\n\r\nconst assert = (condtion: boolean, msg: string) => {\r\n if (condtion) {\r\n throw new Error(msg)\r\n }\r\n}\r\n\r\n/**\r\n *\r\n * @param value - Reducer or value\r\n * @param name - name of state. For loggin or easy debug\r\n * @returns State<T>\r\n */\r\nexport function state<T extends StateType = StateType>(value: T, options?: Options): State<T> {\r\n assert(isFunction(value), 'Function not allowed in state')\r\n\r\n const data: CommonInternal = {\r\n childs: new Set(),\r\n depends: new Set(),\r\n history: Array.from({length: settings.historyLength}),\r\n historyCursor: 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[]>(\r\n value: (...args: T) => void,\r\n options?: ActionOptions,\r\n): Action<T> => {\r\n return {\r\n run: (...args: T) => {\r\n isActionNow = true\r\n value(...args)\r\n isActionNow = false\r\n return this\r\n },\r\n name: getName(options.name),\r\n onAction: options.onAction,\r\n }\r\n}\r\n"],"names":["_this","this","recording","isNotifying","names","Set","requesters","states2notify","getHistoryValue","state","history","historyCursor","pushHistory","value","cursorHistory","length","getName","name","has","console","error","defaultName","isFunction","v","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","push","childs","delete","clear","reducer","initial","pop","e","message","getValue","getComputed","lastRequester","at","getComputedValue","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","st","it","subscribes","size","queueMicrotask","listner","startRecord","flushStates","data","subscribe","computedState","parent","condtion","msg","Error","options","Array","from","publicApi","Object","defineProperty","set","_internal","computed","action","run","slice","call","arguments","onAction"],"mappings":"AAuBA,IAAAA,OAAAC,EAAA,IAEIC,EAFWC,GAAG,EAIlB,QAAoB,gBACTC,EAAG,IAAIC,IACZC,EAAiC,GACpBC,EAAG,IAAwBF,IAKlBG,EAAIC,GACvBA,EAAMC,QAAQD,EAAME,eAEvBC,EAAc,CAA4BH,EAAUI,KACxD,MAAmBC,EAAGL,EAAME,cAC5BF,EAAMC,QAAQI,GAAiBD,EAC/BJ,EAAME,eAAiBG,EAAgB,GAAKL,EAAMC,QAAQK,MAAAA,EAG/CC,EAAIC,GACXA,GAAQb,EAAMc,IAAID,IACpBE,QAAQC,cAAcH,yCACfI,GAELJ,GAGGI,IAOYZ,IACnB,GAAI,YAAaA,EACf,OACDA,CAAA,EAGaa,EAAIC,GACE,mBAALA,IAOSd,IACxB,IACE,MAAee,EAAGhB,EAAgBC,GAElC,GARqB,EAACA,EAAuBe,KACb,IAA3Bf,EAAMgB,uBAA4CC,IAAdF,EAOrCG,CAAiBlB,EAAOe,GAM1B,OALItB,GACFO,EAAMmB,QAAQC,QAASC,IACrB5B,GAAW6B,IAAID,EACjB,GAGHN,EAEDQ,EAAOvB,EAAMwB,YAAa,+BAA+BxB,EAAMQ,MAAQ,mBAEvEX,EAAW4B,KAAKzB,GAChBA,EAAMmB,QAAQC,QAASC,IACrBA,EAAKK,OAAOC,OAAO3B,EACrB,GACAA,EAAMmB,QAAQS,QACd5B,EAAMwB,aAAc,EACpB,MAAMpB,EAAQJ,EAAM6B,QAAQd,GAAaf,EAAM8B,SAO/C,OANA9B,EAAMwB,aAAc,EACpBxB,EAAMgB,kBAAmB,EAEzBnB,EAAWkC,MACX5B,EAAYH,EAAOI,GAGpBA,CAGA,CAHC,MAAO4B,GAEP,YADAtB,QAAQC,MAAOqB,EAAYC,QAE5B,GAGWC,EAAIlC,IAChB,QAAgBmC,EAAYnC,GAC5B,IACE,MAAmBoC,EAAGvC,EAAWwC,IAAI,GAKrC,OAJID,IAAkBpC,EAAM0B,OAAOjB,IAAI2B,KACrCpC,EAAM0B,OAAOJ,IAAIc,GACjBA,EAAcjB,QAAQG,IAAItB,IAExB6B,EACqBS,EAACT,GAEJ9B,EAACC,EAKxB,CAJA,QACKP,IAAcoC,GAChBpC,EAAU6B,IAAItB,EAEjB,GAQWuC,EAAG,CAACvC,EAAuBI,KACvC,MAAcoC,EAAG3B,EAAWT,GANG,EAACJ,EAAuBI,IAE3CA,EADML,EAAgBC,IAKGyC,CAAyBzC,EAAOI,GAASA,EAE1EoC,IAAazC,EAAgBC,KAGjCG,EAAYH,EAAOwC,GACnBE,EAAkB1C,GAClB2C,IAAiB,EAOID,EAAI1C,IACzB,MAAM4C,EAA0B,CAAC5C,GAEjC,KAAO4C,EAAMtC,QAAQ,CACnB,MAAMuC,EAAKD,EAAMb,MACjBc,EAAGnB,OAAON,QAAS0B,GAAOF,EAAMnB,KAAKqB,IACrCD,EAAG7B,kBAAmB,EAClB6B,EAAGE,WAAWC,MAChBlD,EAAcwB,IAAIuB,EAErB,GAMoBF,EAAG,MACJ,IAAhBjD,IACFA,GAAc,EACduD,eAAe,KAEbnD,EAAcsB,QAASpB,IACrB,IACEA,EAAM+C,WAAW3B,QAAS8B,GACjBA,EAAQhB,EAASlC,IAI3B,CAFC,MAAOgC,GACPtB,QAAQC,MAAM,mCAAoCX,EAAMQ,KACzD,IAEHV,EAAc8B,QACdlC,GAAc,CAAA,GAEjB,EAQqByD,EAAG,KACzB1D,EAAY,IACdG,GAAA,EAKwBwD,EAAG,KACzB,MAAMC,EAAO5D,EAEb,OADAA,OAAYwB,EACLoC,GAGIC,EAAY,CAACtD,EAAwCkD,KAUhE,GAAIlD,EAAM+C,WAAWtC,IAAIyC,GACvB,MAAO,KAAA,CAAS,GAGlB,QAAsBf,EAAYnC,GASlC,OAPIuD,IACFjB,EAAiBiB,GACjBvD,EAAMmB,QAAQC,QAASoC,GAAWA,EAAO9B,OAAOJ,IAAItB,KAGtDA,EAAM+C,WAAWzB,IAAI4B,GAEd,KACLlD,EAAM+C,WAAWpB,OAAOuB,GACM,IAA1BlD,EAAM+C,WAAWC,MACnBhD,EAAMmB,QAAQC,QAASoC,GAAWA,EAAO9B,OAAOC,OAAO3B,GACxD,CACH,EAGIuB,EAAS,CAACkC,EAAmBC,KACjC,GAAID,EACF,MAAUE,IAAAA,MAAMD,EACjB,EASa1D,SAAAA,EAAuCI,EAAUwD,GAC/DrC,EAAOV,EAAWT,GAAQ,iCAE1B,MAAUiD,EAAmB,CAC3B3B,OAAQ,IAAI9B,IACZuB,QAAS,QACTlB,QAAS4D,MAAMC,KAAK,CAACxD,OA1NR,IA2NbJ,cAAe,EACfM,KAAMD,EAAQqD,GAASpD,MACvBuC,WAAY,IAAInD,IAChBoB,sBAAkBC,GAGpBsB,EAASc,EAAMjD,GAEf,MAAe2D,EAAG,WAChB,OAAO7B,EAASmB,EAClB,EAOA,OALAW,OAAOC,eAAeF,EAAW,OAAQ,CAAC3D,MAAOiD,EAAK7C,OACtDuD,EAAUT,UAAaJ,GAAqBI,EAAUD,EAAMH,GAC5Da,EAAUG,IAAO9D,GAAamC,EAASc,EAAMjD,GAC7C2D,EAAUI,UAAYd,EAEfU,CACT,CAEaK,MAAQA,EAAG,CAKtBhE,EACAwD,KAEA,MAAUP,EAAqB,CAC7B3B,OAAQ,QACRP,QAAS,QACTH,kBAAkB,EAClBf,QAAS4D,MAAMC,KAAK,CAACxD,OA3PR,IA4PbJ,cAAe,EACf4B,QAAS8B,GAAS9B,QAClBN,aAAa,EACbhB,KAAMD,EAAQqD,GAASpD,MACvBqB,QAASzB,EACT2C,WAAY,SAGRgB,EAAY,WAChB,SAAgBV,EAClB,EAMA,OAJAW,OAAOC,eAAeF,EAAW,OAAQ,CAAC3D,MAAOiD,EAAK7C,OACtDuD,EAAUT,UAAaJ,GAAwBI,EAAUD,EAAMH,GAC/Da,EAAUI,UAAYd,EAEfU,GASIM,EAAS,CACpBjE,EACAwD,KAEO,CACLU,IAAK,WAIH,OAFAlE,KAAa,GAAAmE,MAAAC,KAAAC,YAENlF,CACT,EACAiB,KAAMD,EAAQqD,EAAQpD,MACtBkE,SAAUd,EAAQc"}

@@ -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 n&&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});
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e||self).core={})}(this,function(e){var n=void 0;let t,s=!1;const r="Unnamed state",o=new Set,i=[],a=new Set,c=e=>e.history[e.historyCursor],d=(e,n)=>{const t=e.historyCursor;e.history[t]=n,e.historyCursor=(t+1)%e.history.length},u=e=>e&&o.has(e)?(console.error(`Name ${e} already used! Replaced to undefined`),r):e||r,h=e=>{if("reducer"in e)return e},l=e=>"function"==typeof e,f=e=>{try{const n=c(e);if(((e,n)=>!1===e.hasParentUpdates&&void 0!==n)(e,n))return t&&e.depends.forEach(e=>{t?.add(e)}),n;g(e.isComputing,`Loops dosen't allows. Name: ${e.name??"Unnamed state"}`),i.push(e),e.depends.forEach(n=>{n.childs.delete(e)}),e.depends.clear(),e.isComputing=!0;const s=e.reducer(n??e.initial);return e.isComputing=!1,e.hasParentUpdates=!1,i.pop(),d(e,s),s}catch(e){return void console.error(e.message)}},p=e=>{const n=h(e);try{const s=i.at(-1);return s&&!e.childs.has(s)&&(e.childs.add(s),s.depends.add(e)),n?f(n):c(e)}finally{t&&!n&&t.add(e)}},b=(e,n)=>{const t=l(n)?((e,n)=>n(c(e)))(e,n):n;t!==c(e)&&(d(e,t),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===s&&(s=!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(),s=!1}))},w=(e,n)=>{if(e.subscribes.has(n))return()=>({});const t=h(e);return t&&(f(t),e.depends.forEach(n=>n.childs.add(e))),e.subscribes.add(n),()=>{e.subscribes.delete(n),0===e.subscribes.size&&e.depends.forEach(n=>n.childs.delete(e))}},g=(e,n)=>{if(e)throw new Error(n)};e.action=(e,t)=>({run:function(){return e(...[].slice.call(arguments)),n},name:u(t.name),onAction:t.onAction}),e.computed=(e,n)=>{const t={childs:new Set,depends:new Set,hasParentUpdates:!0,history:Array.from({length:5}),historyCursor:0,initial:n?.initial,isComputing:!1,name:u(n?.name),reducer:e,subscribes:new Set},s=function(){return p(t)};return Object.defineProperty(s,"name",{value:t.name}),s.subscribe=e=>w(t,e),s._internal=t,s},e.flushStates=()=>{const e=t;return t=void 0,e},e.startRecord=()=>{t=new Set},e.state=function(e,n){g(l(e),"Function not allowed in state");const t={childs:new Set,depends:new Set,history:Array.from({length:5}),historyCursor:0,name:u(n?.name),subscribes:new Set,hasParentUpdates:void 0};b(t,e);const s=function(){return p(t)};return Object.defineProperty(s,"name",{value:t.name}),s.subscribe=e=>w(t,e),s.set=e=>b(t,e),s._internal=t,s},e.subscribe=w});
//# 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 if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n\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","reducer","initial","pop","applyUpdates","value","e","message","getValue","lastRequester","at","childs","setValue","getValueOfSetterFunction","newValue","invalidateSubtree","notifySubscribers","stack","length","st","it","subscribes","size","queueMicrotask","listner","clear","set","setCacheValue","cursorHistory","historyCursor","history","updateHistory","computedState","delete","parent","condtion","msg","Error","run","slice","call","arguments","onAction","options","data","Array","from","Object","defineProperty","publicApi","subscribe","_internal"],"mappings":"8NAsBA,IAAAA,OAAAC,EAAA,IAG6CC,EAHpCC,EAAG,IAAIC,QACZC,GAAc,EAIlB,MAAMC,EAAc,gBACdC,EAAQ,QACEC,EAAuB,GACpBC,EAAG,IAAIC,IAKDC,EAAIC,GACfT,EAACU,IAAID,GAONE,EAAIC,GACXA,GAAQR,EAAMS,IAAID,IACpBE,QAAQC,cAAcH,yCAEvBT,GACGS,GAGGT,EAWHa,EAAeP,IACnB,GAAI,YAAkBA,EACpB,OACDA,CAAA,EAGaQ,EAAIC,GACE,mBAALA,EAaXC,EAAoBV,IACxB,IACE,QAAkBD,EAAaC,GAE/B,GARqB,EAACA,EAAuBW,KACb,IAA3BX,EAAMY,uBAA4CC,IAAdF,EAOrCG,CAAiBd,EAAOW,GAM1B,OALIrB,GACFU,EAAMe,QAAQC,QAASC,IACrB3B,GAAW4B,IAAID,EACjB,GAGHN,EAEDQ,EAAOnB,EAAMoB,YAAa,+BAA+BpB,EAAMG,MAAQ,mBAEvEP,EAAWyB,KAAKrB,GAEhBA,EAAMoB,aAAc,EACpB,QAAcpB,EAAMsB,QAAQX,GAAaX,EAAMuB,SAO/C,OANAvB,EAAMoB,aAAc,EACpBpB,EAAMY,kBAAmB,EAEzBhB,EAAW4B,MACXC,EAAazB,EAAO0B,GAGrBA,CAGA,CAHC,MAAOC,GAEP,YADAtB,QAAQC,MAAOqB,EAAYC,QAE5B,GAGGC,EAAY7B,IAChB,MAAasB,EAAGf,EAAYP,GAC5B,IACE,MAAmB8B,EAAGlC,EAAWmC,IAAI,GAKrC,OAJID,IAAkB9B,EAAMgC,OAAO5B,IAAI0B,KACrC9B,EAAMgC,OAAOd,IAAIY,GACjBA,EAAcf,QAAQG,IAAIlB,IAExBsB,EACqBZ,EAACY,GAEnBvB,EAAaC,EAKrB,CAJA,QACKV,IAAcgC,GAChBhC,EAAU4B,IAAIlB,EAEjB,GAQWiC,EAAG,CAACjC,EAAuB0B,KACvC,QAAiBlB,EAAWkB,GANG,EAAC1B,EAAuB0B,IAE3CA,EADM3B,EAAaC,IAKMkC,CAAyBlC,EAAO0B,GAASA,EAE1ES,IAAapC,EAAaC,KAG9ByB,EAAazB,EAAOmC,GACpBC,EAAkBpC,GAClBqC,IAAiB,EAObD,EAAqBpC,IACzB,MAAMsC,EAA0B,CAACtC,GAEjC,KAAOsC,EAAMC,QAAQ,CACnB,MAAMC,EAAKF,EAAMd,MACjBgB,EAAGR,OAAOhB,QAASyB,GAAOH,EAAMjB,KAAKoB,IACrCD,EAAG5B,kBAAmB,EAClB4B,EAAGE,WAAWC,MAChB9C,EAAcqB,IAAIsB,EAErB,GAMGH,EAAoB,MACJ,IAAhB5C,IACFA,GAAc,EACdmD,eAAe,KAEb/C,EAAcmB,QAAShB,IACrB,IACEA,EAAM0C,WAAW1B,QAAS6B,GACjBA,EAAQhB,EAAS7B,IAI3B,CAFC,MAAO2B,GACPtB,QAAQC,MAAM,mCAAoCN,EAAMG,KACzD,IAEHN,EAAciD,QACdrD,GAAc,CAAA,GAEjB,EAGGgC,EAAe,CAACzB,EAAuB0B,KAtJvB,EAAC1B,EAAsB0B,KAC3CnC,EAAMwD,IAAI/C,EAAO0B,EAAK,EAsJtBsB,CAAchD,EAAO0B,GAtHD,EAA4B1B,EAAU0B,KAC1D,MAAMuB,EAAgBjD,EAAMkD,cAC5BlD,EAAMmD,QAAQF,GAAiBvB,EAC/B1B,EAAMkD,eAAiBD,EAAgB,GAAKjD,EAAMmD,QAAQZ,MAAAA,EAoH1Da,CAAcpD,EAAO0B,EAAK,IAqBH,CAAC1B,EAAwC6C,KAUhE,GAAI7C,EAAM0C,WAAWtC,IAAIyC,GACvB,MAAO,MAAS,GAGlB,MAAmBQ,EAAG9C,EAAYP,GAOlC,OANIqD,GACF3C,EAAiB2C,GAGnBrD,EAAM0C,WAAWxB,IAAI2B,GAEd,KACL7C,EAAM0C,WAAWY,OAAOT,GACM,IAA1B7C,EAAM0C,WAAWC,MACnB3C,EAAMe,QAAQC,QAASuC,GAAWA,EAAOvB,OAAOsB,OAAOtD,GACxD,CACH,EAGImB,EAAS,CAACqC,EAAmBC,KACjC,GAAID,EACF,MAAUE,IAAAA,MAAMD,EACjB,WA0EmB,CAAsB/B,EAA6BvB,KAChE,CACLwD,IAAK,WAIH,OAFAjC,KAAa,GAAAkC,MAAAC,KAAAC,YAEN1E,CACT,EACAe,KAAMD,EAAQC,GACd4D,cAAUlD,eA/CU,CAKtBa,EACAsC,KAEA,MAAMC,EAAyB,CAC7BjC,OAAQ,QACRjB,QAAS,QACTH,kBAAkB,EAClBuC,QAASe,MAAMC,KAAK,CAAC5B,OApQR,IAqQbW,cAAe,EACf3B,QAASyC,GAASzC,QAClBH,aAAa,EACbjB,KAAMD,EAAQ8D,GAAS7D,MACvBmB,QAASI,EACTgB,WAAY,WAGI,WAChB,OAAeb,EAACoC,EAClB,EAMA,OAJAG,OAAOC,eAAeC,EAAW,OAAQ,CAAC5C,MAAOuC,EAAK9D,OACtDmE,EAAUC,UAAa1B,GAAwB0B,EAAUN,EAAMpB,GAC/DyB,EAAUE,UAAYP,EAEfK,iBAvGkB,KACzB,MAAML,EAAO3E,EAEb,OADAA,OAAYuB,EACLoD,gBAvJiB,KACxB1E,EAAQ,IACVC,uBA2I2B,KACzBF,EAAY,IAAIQ,GAClB,UAoDgBE,SAAuC0B,EAAUsC,GAC/D7C,EAAOX,EAAWkB,GAAQ,iCAE1B,MAAUuC,EAAmB,CAC3BjC,OAAQ,IAAIlC,IACZiB,QAAS,IAASjB,IAClBqD,QAASe,MAAMC,KAAK,CAAC5B,OAnOR,IAoObW,cAAe,EACf/C,KAAMD,EAAQ8D,GAAS7D,MACvBuC,WAAY,IAAS5C,IACrBc,sBAAkBC,GAGpBoB,EAASgC,EAAMvC,GAEf,QAAkB,WAChB,SAAgBuC,EAClB,EAOA,OALAG,OAAOC,eAAeC,EAAW,OAAQ,CAAC5C,MAAOuC,EAAK9D,OACtDmE,EAAUC,UAAa1B,GAAqB0B,EAAUN,EAAMpB,GAC5DyB,EAAUvB,IAAOrB,GAAaO,EAASgC,EAAMvC,GAC7C4C,EAAUE,UAAYP,GAGxB"}
{"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 ActionOptions,\r\n} from './types.js'\r\n\r\nlet isNotifying = false\r\nlet isActionNow = false\r\nlet recording: Set<StateInternal> | undefined\r\n\r\nconst defaultName = 'Unnamed state'\r\nconst names = new Set()\r\nconst requesters: ComputedInternal[] = []\r\nconst states2notify = new Set<StateVariants>()\r\nconst settings: Settings = {\r\n historyLength: 5,\r\n}\r\n\r\nexport const getHistoryValue = (state: StateVariants): unknown => {\r\n return state.history[state.historyCursor]\r\n}\r\nconst pushHistory = <T extends HistoryInternal>(state: T, value: unknown) => {\r\n const cursorHistory = state.historyCursor\r\n state.history[cursorHistory] = value\r\n state.historyCursor = (cursorHistory + 1) % state.history.length\r\n}\r\n\r\nconst getName = (name?: string): string => {\r\n if (name && names.has(name)) {\r\n console.error(`Name ${name} already used! Replaced to undefined`)\r\n return defaultName\r\n }\r\n if (name) {\r\n return name\r\n }\r\n return defaultName\r\n}\r\n\r\nexport const setSetting = (data: Partial<Settings>) => {\r\n Object.assign(settings, data)\r\n}\r\n\r\nconst getComputed = (state: CommonInternal | ComputedInternal) => {\r\n if ('reducer' in state) {\r\n return state\r\n }\r\n}\r\n\r\nconst isFunction = (v: unknown): v is Func => {\r\n return typeof v === 'function'\r\n}\r\n\r\nconst isDontNeedRecalc = (state: CommonInternal, prevState: unknown): boolean => {\r\n return state.hasParentUpdates === false && prevState !== undefined\r\n}\r\n\r\nconst getComputedValue = (state: ComputedInternal): unknown => {\r\n try {\r\n const prevState = getHistoryValue(state)\r\n\r\n if (isDontNeedRecalc(state, prevState)) {\r\n if (recording) {\r\n state.depends.forEach((item) => {\r\n recording?.add(item)\r\n })\r\n }\r\n return prevState\r\n }\r\n\r\n assert(state.isComputing, `Loops dosen't allows. Name: ${state.name ?? 'Unnamed state'}`)\r\n\r\n requesters.push(state)\r\n state.depends.forEach((item) => {\r\n item.childs.delete(state)\r\n })\r\n state.depends.clear()\r\n state.isComputing = true\r\n const value = state.reducer(prevState ?? state.initial)\r\n state.isComputing = false\r\n state.hasParentUpdates = false\r\n\r\n requesters.pop()\r\n pushHistory(state, value)\r\n\r\n return value\r\n } catch (e) {\r\n console.error((e as Error).message)\r\n return undefined\r\n }\r\n}\r\n\r\nconst getValue = (state: CommonInternal) => {\r\n const reducer = getComputed(state)\r\n try {\r\n const lastRequester = requesters.at(-1)\r\n if (lastRequester && !state.childs.has(lastRequester)) {\r\n state.childs.add(lastRequester)\r\n lastRequester.depends.add(state)\r\n }\r\n if (reducer) {\r\n return getComputedValue(reducer)\r\n }\r\n return getHistoryValue(state)\r\n } finally {\r\n if (recording && !reducer) {\r\n recording.add(state)\r\n }\r\n }\r\n}\r\n\r\nconst getValueOfSetterFunction = (state: CommonInternal, value: SetterFunc): unknown => {\r\n const prevValue = getHistoryValue(state)\r\n return value(prevValue)\r\n}\r\n\r\nconst setValue = (state: CommonInternal, value: unknown): void => {\r\n const newValue = isFunction(value) ? getValueOfSetterFunction(state, value) : value\r\n\r\n if (newValue === getHistoryValue(state)) {\r\n return\r\n }\r\n pushHistory(state, newValue)\r\n invalidateSubtree(state)\r\n notifySubscribers()\r\n}\r\n\r\n/**\r\n * Mark all subtree is non actual.\r\n * Collect all nodes to notify subscribers im microtask queue.\r\n */\r\nconst invalidateSubtree = (state: CommonInternal) => {\r\n const stack: CommonInternal[] = [state]\r\n\r\n while (stack.length) {\r\n const st = stack.pop()\r\n st.childs.forEach((it) => stack.push(it))\r\n st.hasParentUpdates = true\r\n if (st.subscribes.size) {\r\n states2notify.add(st)\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all collected subscribers once in microtask queue\r\n */\r\nconst notifySubscribers = () => {\r\n if (isNotifying === false) {\r\n isNotifying = true\r\n queueMicrotask(() => {\r\n // Нужно обновить дерево\r\n states2notify.forEach((state) => {\r\n try {\r\n state.subscribes.forEach((listner) => {\r\n return listner(getValue(state))\r\n })\r\n } catch (e) {\r\n console.error('Error in subscriber function of:', state.name)\r\n }\r\n })\r\n states2notify.clear()\r\n isNotifying = false\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * Start collecting all non computed states.\r\n *\r\n * Helper for render adapters.\r\n */\r\nexport const startRecord = () => {\r\n recording = new Set()\r\n}\r\n\r\n/**\r\n * Flush all collected non computed states.\r\n */\r\nexport const flushStates = (): Set<StateInternal> => {\r\n const data = recording\r\n recording = undefined\r\n return data\r\n}\r\n\r\nexport const subscribe = (state: CommonInternal | CommonInternal, listner: Listner): UnSubscribe => {\r\n /**\r\n * Если значение стейта ниразу не расчитывалось, его нужно обновить\r\n * Если подписываемся на вычисляемый стэйт, то нужно узнать всех родителей\r\n * Родители могут меняться, поэтому после каждого вычисления нужно обновлять зависимости дерева\r\n *\r\n * При отписке нужно оповестить всех на кого были опдписанты о том что мы отписались\r\n *\r\n */\r\n\r\n if (state.subscribes.has(listner)) {\r\n return () => ({})\r\n }\r\n\r\n const computedState = getComputed(state)\r\n // Нужно актуализировать в родилеях зависимость\r\n if (computedState) {\r\n getComputedValue(computedState)\r\n state.depends.forEach((parent) => parent.childs.add(state))\r\n }\r\n\r\n state.subscribes.add(listner)\r\n\r\n return () => {\r\n state.subscribes.delete(listner)\r\n if (state.subscribes.size === 0) {\r\n state.depends.forEach((parent) => parent.childs.delete(state))\r\n }\r\n }\r\n}\r\n\r\nconst assert = (condtion: boolean, msg: string) => {\r\n if (condtion) {\r\n throw new Error(msg)\r\n }\r\n}\r\n\r\n/**\r\n *\r\n * @param value - Reducer or value\r\n * @param name - name of state. For loggin or easy debug\r\n * @returns State<T>\r\n */\r\nexport function state<T extends StateType = StateType>(value: T, options?: Options): State<T> {\r\n assert(isFunction(value), 'Function not allowed in state')\r\n\r\n const data: CommonInternal = {\r\n childs: new Set(),\r\n depends: new Set(),\r\n history: Array.from({length: settings.historyLength}),\r\n historyCursor: 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[]>(\r\n value: (...args: T) => void,\r\n options?: ActionOptions,\r\n): Action<T> => {\r\n return {\r\n run: (...args: T) => {\r\n isActionNow = true\r\n value(...args)\r\n isActionNow = false\r\n return this\r\n },\r\n name: getName(options.name),\r\n onAction: options.onAction,\r\n }\r\n}\r\n"],"names":["_this","this","recording","isNotifying","names","Set","requesters","states2notify","getHistoryValue","state","history","historyCursor","pushHistory","value","cursorHistory","length","getName","name","has","console","error","defaultName","isFunction","v","prevState","hasParentUpdates","undefined","isDontNeedRecalc","depends","forEach","item","add","assert","isComputing","push","childs","delete","clear","reducer","initial","pop","e","message","getValue","getComputed","lastRequester","at","getComputedValue","setValue","newValue","getValueOfSetterFunction","invalidateSubtree","notifySubscribers","stack","st","it","subscribes","size","queueMicrotask","listner","subscribe","computedState","parent","condtion","msg","Error","options","run","slice","call","arguments","onAction","data","Array","from","publicApi","Object","defineProperty","_internal","set"],"mappings":"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"}

@@ -16,5 +16,3 @@ export type Func = (...args: unknown[]) => unknown;

};
export type Options = {
name?: string;
};
type Scheduler = () => void;
export type HistoryInternal = {

@@ -29,3 +27,3 @@ historyCursor: number;

name: string;
onUpdate?: SetterFunc;
onUpdate?: Scheduler;
hasParentUpdates: boolean | undefined;

@@ -59,3 +57,12 @@ };

run: (...args: T) => void;
onAction?: () => void;
onAction?: Scheduler;
}
export type ActionOptions = {
name?: string;
onAction?: Scheduler;
};
export type Options = {
name?: string;
onUpdate?: Scheduler;
};
export {};
{
"name": "@statx/core",
"version": "1.0.18",
"version": "1.0.20",
"private": false,

@@ -70,3 +70,3 @@ "description": "Extry tiny smart state manager",

},
"gitHead": "004b8b5ec9f23c2d4a54ac839e79aff4bf6d8ba0"
"gitHead": "62673cc79ed70a117903fa5adfed62dacfcd794b"
}

@@ -21,5 +21,5 @@ import {

SetterFunc,
ActionOptions,
} from './types.js'
let cache = new WeakMap<StateVariants, StateType>()
let isNotifying = false

@@ -36,10 +36,11 @@ let isActionNow = false

}
// <T extends StateType>(state: StateVariants<T>
export const getCachValue = (state: StateVariants): unknown => {
return cache.get(state)
}
const setCacheValue = (state: StateVariants, value: StateType): void => {
cache.set(state, value)
export const getHistoryValue = (state: StateVariants): unknown => {
return state.history[state.historyCursor]
}
const pushHistory = <T extends HistoryInternal>(state: T, value: unknown) => {
const cursorHistory = state.historyCursor
state.history[cursorHistory] = value
state.historyCursor = (cursorHistory + 1) % state.history.length
}

@@ -61,6 +62,2 @@ const getName = (name?: string): string => {

export const setContext = () => {
cache = new WeakMap<object, StateType>()
}
const getComputed = (state: CommonInternal | ComputedInternal) => {

@@ -76,8 +73,2 @@ if ('reducer' in state) {

const updateHistory = <T extends HistoryInternal>(state: T, value: unknown) => {
const cursorHistory = state.historyCursor
state.history[cursorHistory] = value
state.historyCursor = (cursorHistory + 1) % state.history.length
}
const isDontNeedRecalc = (state: CommonInternal, prevState: unknown): boolean => {

@@ -89,3 +80,3 @@ return state.hasParentUpdates === false && prevState !== undefined

try {
const prevState = getCachValue(state)
const prevState = getHistoryValue(state)

@@ -104,3 +95,6 @@ if (isDontNeedRecalc(state, prevState)) {

requesters.push(state)
state.depends.forEach((item) => {
item.childs.delete(state)
})
state.depends.clear()
state.isComputing = true

@@ -112,3 +106,3 @@ const value = state.reducer(prevState ?? state.initial)

requesters.pop()
applyUpdates(state, value)
pushHistory(state, value)

@@ -133,3 +127,3 @@ return value

}
return getCachValue(state)
return getHistoryValue(state)
} finally {

@@ -143,3 +137,3 @@ if (recording && !reducer) {

const getValueOfSetterFunction = (state: CommonInternal, value: SetterFunc): unknown => {
const prevValue = getCachValue(state)
const prevValue = getHistoryValue(state)
return value(prevValue)

@@ -151,6 +145,6 @@ }

if (newValue === getCachValue(state)) {
if (newValue === getHistoryValue(state)) {
return
}
applyUpdates(state, newValue)
pushHistory(state, newValue)
invalidateSubtree(state)

@@ -200,7 +194,2 @@ notifySubscribers()

const applyUpdates = (state: CommonInternal, value: unknown): void => {
setCacheValue(state, value)
updateHistory(state, value)
}
/**

@@ -239,4 +228,6 @@ * Start collecting all non computed states.

const computedState = getComputed(state)
// Нужно актуализировать в родилеях зависимость
if (computedState) {
getComputedValue(computedState)
state.depends.forEach((parent) => parent.childs.add(state))
}

@@ -331,3 +322,6 @@

*/
export const action = <T extends unknown[]>(value: (...args: T) => void, name?: string): Action<T> => {
export const action = <T extends unknown[]>(
value: (...args: T) => void,
options?: ActionOptions,
): Action<T> => {
return {

@@ -340,5 +334,5 @@ run: (...args: T) => {

},
name: getName(name),
onAction: undefined,
name: getName(options.name),
onAction: options.onAction,
}
}
import {test} from 'uvu'
import * as assert from 'uvu/assert'
import {state, computed, action, getCachValue} from './core.js'
import {state, computed, action, getHistoryValue} from './core.js'

@@ -126,3 +126,3 @@ type Mock = {

// No calculations if no subs
assert.is(getCachValue(c._internal), undefined)
assert.is(getHistoryValue(c._internal), undefined)

@@ -133,3 +133,3 @@ const unsub = c.subscribe(() => {

// Recalc on subscribe
assert.is(getCachValue(c._internal), 23 * 100 + 20)
assert.is(getHistoryValue(c._internal), 23 * 100 + 20)

@@ -139,3 +139,3 @@ v.set(1)

assert.is(getCachValue(c._internal), 1 * 100 + 20)
assert.is(getHistoryValue(c._internal), 1 * 100 + 20)

@@ -146,3 +146,3 @@ // No recalc after unsub

assert.is(getCachValue(c._internal), 1 * 100 + 20)
assert.is(getHistoryValue(c._internal), 1 * 100 + 20)
})

@@ -149,0 +149,0 @@ test(`Recalculate all computed tree`, () => {

@@ -1,2 +0,2 @@

export {state, action, computed, subscribe, startRecord, flushStates, setContext} from './core.js'
export {state, action, computed, subscribe, startRecord, flushStates} from './core.js'
export * from './types.js'

@@ -42,5 +42,3 @@ export type Func = (...args: unknown[]) => unknown

export type Options = {
name?: string
}
type Scheduler = () => void

@@ -57,3 +55,3 @@ export type HistoryInternal = {

name: string
onUpdate?: SetterFunc
onUpdate?: Scheduler
hasParentUpdates: boolean | undefined

@@ -104,3 +102,13 @@ }

run: (...args: T) => void
onAction?: () => void
onAction?: Scheduler
}
export type ActionOptions = {
name?: string
onAction?: Scheduler
}
export type Options = {
name?: string
onUpdate?: Scheduler
}