@lomray/react-mobx-manager 3.2.0-beta.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Deep compare two objects
3
+ */
4
+ declare const deepCompare: (obj1: unknown, obj2: unknown) => boolean;
5
+ export { deepCompare as default };
@@ -0,0 +1,2 @@
1
+ const e=(t,n)=>{if(t===n)return!0;if("object"!=typeof t||null===t||"object"!=typeof n||null===n)return!1;const r=Object.keys(t),o=Object.keys(n);if(r.length!==o.length)return!1;for(const f of r)if(!o.includes(f)||!e(t[f],n[f]))return!1;return!0};export{e as default};
2
+ //# sourceMappingURL=deep-compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-compare.js","sources":["../src/deep-compare.ts"],"sourcesContent":["/**\n * Deep compare two objects\n */\nconst deepCompare = (obj1: unknown, obj2: unknown): boolean => {\n if (obj1 === obj2) {\n return true;\n }\n\n if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {\n return false;\n }\n\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) {\n return false;\n }\n\n for (const key of keys1) {\n if (!keys2.includes(key) || !deepCompare(obj1[key], obj2[key])) {\n return false;\n }\n }\n\n return true;\n};\n\nexport default deepCompare;\n"],"names":["deepCompare","obj1","obj2","keys1","Object","keys","keys2","length","key","includes"],"mappings":"AAGA,MAAMA,EAAc,CAACC,EAAeC,KAClC,GAAID,IAASC,EACX,OAAO,EAGT,GAAoB,iBAATD,GAA8B,OAATA,GAAiC,iBAATC,GAA8B,OAATA,EAC3E,OAAO,EAGT,MAAMC,EAAQC,OAAOC,KAAKJ,GACpBK,EAAQF,OAAOC,KAAKH,GAE1B,GAAIC,EAAMI,SAAWD,EAAMC,OACzB,OAAO,EAGT,IAAK,MAAMC,KAAOL,EAChB,IAAKG,EAAMG,SAASD,KAASR,EAAYC,EAAKO,GAAMN,EAAKM,IACvD,OAAO,EAIX,OAAO,CAAI"}
package/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export{StoreManagerContext,StoreManagerParentContext,StoreManagerParentProvider,StoreManagerProvider,useStoreManager,useStoreManagerParent}from"./context.js";export{default as Manager}from"./manager.js";export{default as onChangeListener}from"./on-change-listener.js";export{default as wakeup}from"./wakeup.js";export{default as withStores}from"./with-stores.js";export{isPropObservableExported,isPropSimpleExported,makeExported}from"./make-exported.js";export{default as Events}from"./events.js";
1
+ export{StoreManagerContext,StoreManagerParentContext,StoreManagerParentProvider,StoreManagerProvider,useStoreManager,useStoreManagerParent}from"./context.js";export{default as Manager}from"./manager.js";export{default as onChangeListener}from"./on-change-listener.js";export{default as wakeup}from"./wakeup.js";export{default as withStores}from"./with-stores.js";export{isPropExcludedFromExport,isPropObservableExported,isPropSimpleExported,makeExported}from"./make-exported.js";export{default as Events}from"./events.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -3,7 +3,7 @@ import { TAnyStore } from "./types.js";
3
3
  * Make store props exported for Manager.toJSON
4
4
  * @see Manager.toJSON
5
5
  */
6
- declare const makeExported: <T extends object>(store: T, props: { [P in Exclude<keyof T, "toString">]?: "observable" | "simple" | undefined; }) => void;
6
+ declare const makeExported: <T extends object>(store: T, props: { [P in Exclude<keyof T, "toString">]?: "observable" | "simple" | "excluded" | undefined; }) => void;
7
7
  /**
8
8
  * Check if store prop is observable exported
9
9
  */
@@ -12,4 +12,8 @@ declare const isPropObservableExported: (store: TAnyStore, prop: string) => bool
12
12
  * Check if store prop is simple exported
13
13
  */
14
14
  declare const isPropSimpleExported: (store: TAnyStore, prop: string) => boolean;
15
- export { makeExported, isPropObservableExported, isPropSimpleExported };
15
+ /**
16
+ * Check if store prop is excluded from export
17
+ */
18
+ declare const isPropExcludedFromExport: (store: TAnyStore, prop: string) => boolean;
19
+ export { makeExported, isPropObservableExported, isPropSimpleExported, isPropExcludedFromExport };
package/make-exported.js CHANGED
@@ -1,2 +1,2 @@
1
- const e="libExported",o=(o,b)=>{o[e]=b},b=(o,b)=>"observable"===o?.[e]?.[b],l=(o,b)=>"simple"===o?.[e]?.[b];export{b as isPropObservableExported,l as isPropSimpleExported,o as makeExported};
1
+ const e="libExported",l=(l,o)=>{l[e]=o},o=(l,o)=>"observable"===l?.[e]?.[o],b=(l,o)=>"simple"===l?.[e]?.[o],d=(l,o)=>"excluded"===l?.[e]?.[o];export{d as isPropExcludedFromExport,o as isPropObservableExported,b as isPropSimpleExported,l as makeExported};
2
2
  //# sourceMappingURL=make-exported.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"make-exported.js","sources":["../src/make-exported.ts"],"sourcesContent":["import type { TAnyStore } from '@src/types';\n\nconst exportedPropName = 'libExported';\n\n/**\n * Make store props exported for Manager.toJSON\n * @see Manager.toJSON\n */\nconst makeExported = <T extends object>(\n store: T,\n props: {\n [P in Exclude<keyof T, 'toString'>]?: 'observable' | 'simple';\n },\n): void => {\n store[exportedPropName] = props;\n};\n\n/**\n * Check if store prop is observable exported\n */\nconst isPropObservableExported = (store: TAnyStore, prop: string): boolean =>\n store?.[exportedPropName]?.[prop] === 'observable';\n\n/**\n * Check if store prop is simple exported\n */\nconst isPropSimpleExported = (store: TAnyStore, prop: string): boolean =>\n store?.[exportedPropName]?.[prop] === 'simple';\n\nexport { makeExported, isPropObservableExported, isPropSimpleExported };\n"],"names":["exportedPropName","makeExported","store","props","isPropObservableExported","prop","isPropSimpleExported"],"mappings":"AAEA,MAAMA,EAAmB,cAMnBC,EAAe,CACnBC,EACAC,KAIAD,EAAMF,GAAoBG,CAAK,EAM3BC,EAA2B,CAACF,EAAkBG,IACZ,eAAtCH,IAAQF,KAAoBK,GAKxBC,EAAuB,CAACJ,EAAkBG,IACR,WAAtCH,IAAQF,KAAoBK"}
1
+ {"version":3,"file":"make-exported.js","sources":["../src/make-exported.ts"],"sourcesContent":["import type { TAnyStore } from '@src/types';\n\nconst exportedPropName = 'libExported';\n\n/**\n * Make store props exported for Manager.toJSON\n * @see Manager.toJSON\n */\nconst makeExported = <T extends object>(\n store: T,\n props: {\n [P in Exclude<keyof T, 'toString'>]?: 'observable' | 'simple' | 'excluded';\n },\n): void => {\n store[exportedPropName] = props;\n};\n\n/**\n * Check if store prop is observable exported\n */\nconst isPropObservableExported = (store: TAnyStore, prop: string): boolean =>\n store?.[exportedPropName]?.[prop] === 'observable';\n\n/**\n * Check if store prop is simple exported\n */\nconst isPropSimpleExported = (store: TAnyStore, prop: string): boolean =>\n store?.[exportedPropName]?.[prop] === 'simple';\n\n/**\n * Check if store prop is excluded from export\n */\nconst isPropExcludedFromExport = (store: TAnyStore, prop: string): boolean =>\n store?.[exportedPropName]?.[prop] === 'excluded';\n\nexport { makeExported, isPropObservableExported, isPropSimpleExported, isPropExcludedFromExport };\n"],"names":["exportedPropName","makeExported","store","props","isPropObservableExported","prop","isPropSimpleExported","isPropExcludedFromExport"],"mappings":"AAEA,MAAMA,EAAmB,cAMnBC,EAAe,CACnBC,EACAC,KAIAD,EAAMF,GAAoBG,CAAK,EAM3BC,EAA2B,CAACF,EAAkBG,IACZ,eAAtCH,IAAQF,KAAoBK,GAKxBC,EAAuB,CAACJ,EAAkBG,IACR,WAAtCH,IAAQF,KAAoBK,GAKxBE,EAA2B,CAACL,EAAkBG,IACZ,aAAtCH,IAAQF,KAAoBK"}
package/manager.js CHANGED
@@ -1,2 +1,2 @@
1
- import t from"@lomray/event-manager";import{toJS as e,isObservableProp as s}from"mobx";import{ROOT_CONTEXT_ID as o}from"./constants.js";import r from"./deep-merge.js";import i from"./events.js";import{isPropSimpleExported as n,isPropObservableExported as a}from"./make-exported.js";import l from"./on-change-listener.js";import h from"./storages/combined-storage.js";import d from"./store-status.js";import S from"./wakeup.js";class p{static instance;stores=new Map;storesRelations=new Map;static persistedStores=new Set;initState;storage;storesParams;options={shouldDisablePersist:!1,shouldRemoveInitState:!0};suspenseRelations=new Map;constructor({initState:t,storesParams:e,storage:s,options:o}={}){if(this.initState=t||{},this.storesParams=e||{},this.storage=s instanceof h?s:s?new h({default:s}):void 0,Object.assign(this.options,o||{}),p.instance=this,"undefined"!=typeof window){const t=window.mbxM;window.mbxM={push:this.pushInitState},(Array.isArray(t)?t:[]).forEach(this.pushInitState)}}async init(){return this.storage&&await this.storage.get(),this}static get(){if(!p.instance)throw new Error("Store manager is not initialized.");return p.instance}getStores(){return this.stores}getStoresRelations(){return this.storesRelations}getSuspenseRelations(){return this.suspenseRelations}static getPersistedStoresIds(){return p.persistedStores}pushInitState=(t={})=>{for(const[e,s]of Object.entries(t))this.initState[e]=s};getStoreId(t,e={}){const{id:s,contextId:o,key:r}=e;if(s)return s;if(t.libStoreId)return t.libStoreId;let i=t.id||t.name||t.constructor.name;return t.isGlobal?i:(i=`${i}--${o}`,r?`${i}--${r}`:i)}getStore(t,e={}){const s=this.getStoreId(t,e);return this.stores.has(s)?this.stores.get(s):t.isGlobal?this.createStore(t,{id:s,contextId:"global",parentId:o,suspenseId:"",componentName:"root-app",componentProps:{}}):this.lookupStore(s,e)}lookupStore(t,e){const{contextId:s,parentId:r}=e,i=t.split("--")?.[0],{ids:n,parentId:a}=this.storesRelations.get(s)??{ids:new Set,parentId:r},l=[...n].filter((t=>t.startsWith(`${i}--`)));if(1===l.length)return this.stores.get(l[0]);if(l.length>1)console.error("Parent context has multiple stores with the same id, please pass key to getStore function.");else if(a&&a!==o)return this.lookupStore(t,{contextId:this.getBiggerContext(a,r)})}getBiggerContext(t,e){if(!t)return e;if(!e)return t;const s=/[^a-zA-Z]/g;return t.replace(s,"")>e.replace(s,"")?t:e}createStore(e,s){const{id:r,contextId:n,parentId:a,suspenseId:l,componentName:h,componentProps:S}=s;if(this.stores.has(r))return this.stores.get(r);const p=new e({...this.storesParams,storeManager:this,getStore:(t,e={contextId:n,parentId:a})=>this.getStore(t,e),componentProps:S,initState:this.initState[r]});return p.libStoreId=r,p.isGlobal=e.isGlobal,p.libStoreContextId=e.isGlobal?"global":n,p.libStoreParentId=e.isGlobal||!a||a===n?o:a,p.libStoreSuspenseId=l,p.libStoreComponentName=h,this.setStoreStatus(p,e.isGlobal?d.inUse:d.init),this.prepareStore(p),t.publish(i.CREATE_STORE,{store:e}),p}createStores(t,e,s,o,r,i={}){const n=t.reduce(((t,[n,a])=>{const{id:l,store:h,isParent:d=!1}="store"in a?a:{store:a,id:void 0,isParent:!1},S=l||(d?this.getStore(h,{contextId:s,parentId:e})?.libStoreId:this.getStoreId(h,{key:n,contextId:s}));if(!S)return t;const p=this.createStore(h,{id:S,contextId:s,parentId:e,suspenseId:o,componentName:r,componentProps:i});return d?t.parentStores[n]=p:p.isGlobal?t.globalStores[n]=p:t.relativeStores[n]=p,t}),{relativeStores:{},parentStores:{},globalStores:{}});return this.createRelationContext(s,e,r),n}createRelationContext(t,e,s){this.storesRelations.has(t)||this.storesRelations.set(t,{ids:new Set,parentId:e&&e!==t?e:o,componentName:s})}removeRelationContext(t){const e=this.storesRelations.get(t);!e||t===o||e.ids.size>0||this.storesRelations.delete(t)}prepareStore(t){const e=t.libStoreId,s=t.libStoreContextId,o=t.libStoreSuspenseId;if(this.stores.has(e))return;const i=this.initState[e];if(i&&r(t,i),"wakeup"in t&&p.persistedStores.has(e)&&t.wakeup?.({initState:i,persistedState:this.storage?.getStoreData(t),manager:this}),p.persistedStores.has(e)&&"addOnChangeListener"in t){const e=t.onDestroy?.bind(t),s=t.addOnChangeListener(t,this);t.onDestroy=()=>{s?.(),e?.()}}t.init?.(),this.createRelationContext(s,t.libStoreParentId,t.libStoreComponentName),this.suspenseRelations.has(o)||this.suspenseRelations.set(o,new Set);const{ids:n}=this.storesRelations.get(s);this.stores.set(e,t),n.add(e),this.suspenseRelations.get(o).add(e)}removeStore(e){const s=e.libStoreId,o=e.libStoreSuspenseId,{ids:r}=this.storesRelations.get(e.libStoreContextId)??{ids:new Set};this.stores.has(s)&&(this.stores.delete(s),r.delete(s),o&&this.suspenseRelations.get(o)?.has(s)&&this.suspenseRelations.get(o).delete(s),this.removeRelationContext(e.libStoreContextId),"onDestroy"in e&&e.onDestroy?.(),t.publish(i.DELETE_STORE,{store:e}))}mountStores(e,{globalStores:s={},relativeStores:o={}}){const{shouldRemoveInitState:r}=this.options,n={...s,...o};return Object.values(n).forEach((e=>{const s=e.libStoreId;r&&this.initState[s]&&delete this.initState[s],this.setStoreStatus(e,d.inUse),t.publish(i.MOUNT_STORE,{store:e})})),()=>{Object.values(n).forEach((e=>{e.isGlobal||(this.setStoreStatus(e,d.unused),t.publish(i.UNMOUNT_STORE,{store:e}))})),this.removeRelationContext(e)}}touchedStores(t){Object.values(t).forEach((t=>{t.libStoreStatus!==d.init||t.isGlobal||this.setStoreStatus(t,d.touched)}))}setStoreStatus(t,e){const{destroyTimers:{init:s=500,touched:o=1e4,unused:r=1e3}={}}=this.options;t.libStoreStatus=e,clearTimeout(t.libDestroyTimer);let i=0;switch(e){case d.init:i=s;break;case d.touched:i=o;break;case d.unused:i=r}i&&(t.libDestroyTimer=setTimeout((()=>this.removeStore(t)),i))}getStoreState(t){return t.toJSON?.()??p.getObservableProps(t)}toJSON(t){const e={},s=Array.isArray(t)?t.reduce(((t,e)=>(this.stores.has(e)&&t.set(e,this.stores.get(e)),t)),new Map):this.stores;for(const[t,o]of s.entries())e[t]=this.getStoreState(o);return e}async savePersistedStore(t){if(this.options.shouldDisablePersist||!this.storage)return!1;try{return await this.storage.saveStoreData(t,this.getStoreState(t)),!0}catch(t){console.error("Failed to persist stores: ",t)}return!1}static getObservableProps(t){const o=e(t);return Object.entries(o).reduce(((e,[o,r])=>({...e,...s(t,o)||n(t,o)?{[o]:r}:{},...a(t,o)?{[o]:p.getObservableProps(t[o])}:{}})),{})}static persistStore(t,e,s={}){return p.persistedStores.has(e)?(console.warn(`Duplicate serializable store key: ${e}`),t):(p.persistedStores.add(e),t.libStoreId=e,t.libStorageOptions=s,"wakeup"in t.prototype||(t.prototype.wakeup=S),"addOnChangeListener"in t.prototype||(t.prototype.addOnChangeListener=l),t)}}export{p as default};
1
+ import t from"@lomray/event-manager";import{toJS as e,isObservableProp as s}from"mobx";import{ROOT_CONTEXT_ID as o}from"./constants.js";import r from"./deep-merge.js";import i from"./events.js";import{isPropExcludedFromExport as n,isPropSimpleExported as a,isPropObservableExported as l}from"./make-exported.js";import h from"./on-change-listener.js";import p from"./storages/combined-storage.js";import d from"./store-status.js";import S from"./wakeup.js";class c{static instance;stores=new Map;storesRelations=new Map;static persistedStores=new Set;initState;storage;storesParams;options={shouldDisablePersist:!1,shouldRemoveInitState:!0};suspenseRelations=new Map;constructor({initState:t,storesParams:e,storage:s,options:o}={}){if(this.initState=t||{},this.storesParams=e||{},this.storage=s instanceof p?s:s?new p({default:s}):void 0,Object.assign(this.options,o||{}),c.instance=this,"undefined"!=typeof window){const t=window.mbxM;window.mbxM={push:this.pushInitState},(Array.isArray(t)?t:[]).forEach(this.pushInitState)}}async init(){return this.storage&&await this.storage.get(),this}static get(){if(!c.instance)throw new Error("Store manager is not initialized.");return c.instance}getStores(){return this.stores}getStoresRelations(){return this.storesRelations}getSuspenseRelations(){return this.suspenseRelations}static getPersistedStoresIds(){return c.persistedStores}pushInitState=(t={})=>{for(const[e,s]of Object.entries(t))this.initState[e]=s};getStoreId(t,e={}){const{id:s,contextId:o,key:r}=e;if(s)return s;if(t.libStoreId)return t.libStoreId;let i=t.id||t.name||t.constructor.name;return t.isGlobal?i:(i=`${i}--${o}`,r?`${i}--${r}`:i)}getStore(t,e={}){const s=this.getStoreId(t,e);return this.stores.has(s)?this.stores.get(s):t.isGlobal?this.createStore(t,{id:s,contextId:"global",parentId:o,suspenseId:"",componentName:"root-app",componentProps:{}}):this.lookupStore(s,e)}lookupStore(t,e){const{contextId:s,parentId:r}=e,i=t.split("--")?.[0],{ids:n,parentId:a}=this.storesRelations.get(s)??{ids:new Set,parentId:r},l=[...n].filter((t=>t.startsWith(`${i}--`)));if(1===l.length)return this.stores.get(l[0]);if(l.length>1)console.error("Parent context has multiple stores with the same id, please pass key to getStore function.");else if(a&&a!==o)return this.lookupStore(t,{contextId:this.getBiggerContext(a,r)})}getBiggerContext(t,e){if(!t)return e;if(!e)return t;const s=/[^a-zA-Z]/g;return t.replace(s,"")>e.replace(s,"")?t:e}createStore(e,s){const{id:r,contextId:n,parentId:a,suspenseId:l,componentName:h,componentProps:p}=s;if(this.stores.has(r))return this.stores.get(r);const S=new e({...this.storesParams,storeManager:this,getStore:(t,e={contextId:n,parentId:a})=>this.getStore(t,e),componentProps:p,initState:this.initState[r]});return S.libStoreId=r,S.isGlobal=e.isGlobal,S.libStoreContextId=e.isGlobal?"global":n,S.libStoreParentId=e.isGlobal||!a||a===n?o:a,S.libStoreSuspenseId=l,S.libStoreComponentName=h,this.setStoreStatus(S,e.isGlobal?d.inUse:d.init),this.prepareStore(S),t.publish(i.CREATE_STORE,{store:e}),S}createStores(t,e,s,o,r,i={}){const n=t.reduce(((t,[n,a])=>{const{id:l,store:h,isParent:p=!1}="store"in a?a:{store:a,id:void 0,isParent:!1},d=l||(p?this.getStore(h,{contextId:s,parentId:e})?.libStoreId:this.getStoreId(h,{key:n,contextId:s}));if(!d)return t;const S=this.createStore(h,{id:d,contextId:s,parentId:e,suspenseId:o,componentName:r,componentProps:i});return p?t.parentStores[n]=S:S.isGlobal?t.globalStores[n]=S:t.relativeStores[n]=S,t}),{relativeStores:{},parentStores:{},globalStores:{}});return this.createRelationContext(s,e,r),n}createRelationContext(t,e,s){this.storesRelations.has(t)||this.storesRelations.set(t,{ids:new Set,parentId:e&&e!==t?e:o,componentName:s})}removeRelationContext(t){const e=this.storesRelations.get(t);!e||t===o||e.ids.size>0||this.storesRelations.delete(t)}prepareStore(t){const e=t.libStoreId,s=t.libStoreContextId,o=t.libStoreSuspenseId;if(this.stores.has(e))return;const i=this.initState[e];if(i&&r(t,i),"wakeup"in t&&c.persistedStores.has(e)&&t.wakeup?.({initState:i,persistedState:this.storage?.getStoreData(t),manager:this}),c.persistedStores.has(e)&&"addOnChangeListener"in t){const e=t.onDestroy?.bind(t),s=t.addOnChangeListener(t,this);t.onDestroy=()=>{s?.(),e?.()}}t.init?.(),this.createRelationContext(s,t.libStoreParentId,t.libStoreComponentName),this.suspenseRelations.has(o)||this.suspenseRelations.set(o,new Set);const{ids:n}=this.storesRelations.get(s);this.stores.set(e,t),n.add(e),this.suspenseRelations.get(o).add(e)}removeStore(e){const s=e.libStoreId,o=e.libStoreSuspenseId,{ids:r}=this.storesRelations.get(e.libStoreContextId)??{ids:new Set};this.stores.has(s)&&(this.stores.delete(s),r.delete(s),o&&this.suspenseRelations.get(o)?.has(s)&&this.suspenseRelations.get(o).delete(s),this.removeRelationContext(e.libStoreContextId),"onDestroy"in e&&e.onDestroy?.(),t.publish(i.DELETE_STORE,{store:e}))}mountStores(e,{globalStores:s={},relativeStores:o={}}){const{shouldRemoveInitState:r}=this.options,n={...s,...o};return Object.values(n).forEach((e=>{const s=e.libStoreId;r&&this.initState[s]&&delete this.initState[s],this.setStoreStatus(e,d.inUse),t.publish(i.MOUNT_STORE,{store:e})})),()=>{Object.values(n).forEach((e=>{e.isGlobal||(this.setStoreStatus(e,d.unused),t.publish(i.UNMOUNT_STORE,{store:e}))})),this.removeRelationContext(e)}}touchedStores(t){Object.values(t).forEach((t=>{t.libStoreStatus!==d.init||t.isGlobal||this.setStoreStatus(t,d.touched)}))}setStoreStatus(t,e){const{destroyTimers:{init:s=500,touched:o=1e4,unused:r=1e3}={}}=this.options;t.libStoreStatus=e,clearTimeout(t.libDestroyTimer);let i=0;switch(e){case d.init:i=s;break;case d.touched:i=o;break;case d.unused:i=r}i&&(t.libDestroyTimer=setTimeout((()=>this.removeStore(t)),i))}getStoreState(t){return t.toJSON?.()??c.getObservableProps(t)}toJSON(t){const e={},s=Array.isArray(t)?t.reduce(((t,e)=>(this.stores.has(e)&&t.set(e,this.stores.get(e)),t)),new Map):this.stores;for(const[t,o]of s.entries())e[t]=this.getStoreState(o);return e}async savePersistedStore(t){if(this.options.shouldDisablePersist||!this.storage)return!1;try{return await this.storage.saveStoreData(t,this.getStoreState(t)),!0}catch(t){console.error("Failed to persist stores: ",t)}return!1}static getObservableProps(t){const o=e(t);return Object.entries(o).reduce(((e,[o,r])=>({...e,...s(t,o)&&!n(t,o)||a(t,o)?{[o]:r}:{},...l(t,o)?{[o]:c.getObservableProps(t[o])}:{}})),{})}static persistStore(t,e,s={}){return c.persistedStores.add(e),t.libStoreId=e,"libStorageOptions"in t.prototype||(t.prototype.libStorageOptions=s),"wakeup"in t.prototype||(t.prototype.wakeup=S),"addOnChangeListener"in t.prototype||(t.prototype.addOnChangeListener=h),t}}export{c as default};
2
2
  //# sourceMappingURL=manager.js.map
package/manager.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sources":["../src/manager.ts"],"sourcesContent":["import EventManager from '@lomray/event-manager';\nimport { isObservableProp, toJS } from 'mobx';\nimport { ROOT_CONTEXT_ID } from './constants';\nimport deepMerge from './deep-merge';\nimport Events from './events';\nimport { isPropObservableExported, isPropSimpleExported } from './make-exported';\nimport onChangeListener from './on-change-listener';\nimport CombinedStorage from './storages/combined-storage';\nimport StoreStatus from './store-status';\nimport type {\n IConstructableStore,\n IGroupedStores,\n IManagerOptions,\n IManagerParams,\n IPersistOptions,\n IStoreParams,\n IStorePersisted,\n TAnyStore,\n TInitStore,\n TStoreDefinition,\n TStores,\n} from './types';\nimport wakeup from './wakeup';\n\n/**\n * Mobx stores manager\n */\nclass Manager {\n /**\n * Manger instance\n */\n protected static instance: Manager;\n\n /**\n * Created stores\n */\n protected readonly stores = new Map<string, TInitStore>();\n\n /**\n * Relations between stores\n */\n protected readonly storesRelations = new Map<\n string, // contextId\n { ids: Set<string>; parentId: string | null; componentName?: string }\n >();\n\n /**\n * Save persisted stores identities\n */\n protected static readonly persistedStores = new Set<string>();\n\n /**\n * Initial stores state (local storage, custom etc.)\n */\n protected readonly initState: Record<string, any>;\n\n /**\n * Storage for persisted stores\n */\n public readonly storage?: CombinedStorage;\n\n /**\n * Additional store's constructor params\n */\n protected readonly storesParams: IManagerParams['storesParams'];\n\n /**\n * Manager options\n */\n public readonly options: IManagerOptions = {\n shouldDisablePersist: false,\n shouldRemoveInitState: true,\n };\n\n /**\n * Suspense stores relations\n * @see withStores\n */\n protected suspenseRelations: Map<string, Set<string>> = new Map();\n\n /**\n * @constructor\n */\n public constructor({ initState, storesParams, storage, options }: IManagerParams = {}) {\n this.initState = initState || {};\n this.storesParams = storesParams || {};\n this.storage =\n storage instanceof CombinedStorage\n ? storage\n : storage\n ? new CombinedStorage({ default: storage })\n : undefined;\n\n Object.assign(this.options, options || {});\n\n Manager.instance = this;\n\n // only client side\n if (typeof window !== 'undefined') {\n const state = window.mbxM;\n\n window.mbxM = { push: this.pushInitState };\n\n (Array.isArray(state) ? state : []).forEach(this.pushInitState);\n }\n }\n\n /**\n * Init store manager\n */\n public async init(): Promise<Manager> {\n if (this.storage) {\n await this.storage.get();\n }\n\n return this;\n }\n\n /**\n * Get manager instance\n */\n public static get(): Manager {\n if (!Manager.instance) {\n throw new Error('Store manager is not initialized.');\n }\n\n return Manager.instance;\n }\n\n /**\n * Get all stores\n */\n public getStores(): Manager['stores'] {\n return this.stores;\n }\n\n /**\n * Get stores relations\n */\n public getStoresRelations(): Manager['storesRelations'] {\n return this.storesRelations;\n }\n\n /**\n * Get suspense relations with stores\n */\n public getSuspenseRelations(): Manager['suspenseRelations'] {\n return this.suspenseRelations;\n }\n\n /**\n * Get persisted stores ids\n */\n public static getPersistedStoresIds(): Set<string> {\n return Manager.persistedStores;\n }\n\n /**\n * Push initial state dynamically\n * E.g. when stream html\n */\n public pushInitState = (storesState: Record<string, any> = {}): void => {\n for (const [storeId, state] of Object.entries(storesState)) {\n this.initState[storeId] = state;\n }\n };\n\n /**\n * Get store identity\n * @protected\n */\n protected getStoreId<T extends TAnyStore>(\n store: IConstructableStore<T> | TInitStore,\n params: IStoreParams = {},\n ): string {\n const { id, contextId, key } = params;\n\n if (id) {\n return id;\n }\n\n if (store.libStoreId) {\n return store.libStoreId;\n }\n\n let storeId = (store['id'] as string) || (store['name'] as string) || store.constructor.name;\n\n if (store.isGlobal) {\n return storeId;\n }\n\n storeId = `${storeId}--${contextId!}`;\n\n return key ? `${storeId}--${key}` : storeId;\n }\n\n /**\n * Get exist store\n */\n public getStore<T>(store: IConstructableStore<T>, params: IStoreParams = {}): T | undefined {\n const storeId = this.getStoreId(store, params);\n\n // full match\n if (this.stores.has(storeId)) {\n return this.stores.get(storeId) as T;\n }\n\n // in case with global store (create if not exist)\n if (store.isGlobal) {\n return this.createStore(store, {\n id: storeId,\n contextId: 'global',\n parentId: ROOT_CONTEXT_ID,\n suspenseId: '',\n componentName: 'root-app',\n componentProps: {},\n });\n }\n\n // try to look up store in current or parent context\n return this.lookupStore(storeId, params) as T;\n }\n\n /**\n * Lookup store\n */\n protected lookupStore(id: string, params: IStoreParams): TInitStore<TAnyStore> | undefined {\n const { contextId, parentId: defaultParentId } = params;\n const clearId = id.split('--')?.[0];\n const { ids, parentId } = this.storesRelations.get(contextId!) ?? {\n ids: new Set(),\n parentId: defaultParentId,\n };\n\n const matchedIds = [...ids].filter((storeId) => storeId.startsWith(`${clearId}--`));\n\n if (matchedIds.length === 1) {\n return this.stores.get(matchedIds[0]);\n } else if (matchedIds.length > 1) {\n console.error(\n 'Parent context has multiple stores with the same id, please pass key to getStore function.',\n );\n\n return undefined;\n }\n\n if (!parentId || parentId === ROOT_CONTEXT_ID) {\n return undefined;\n }\n\n return this.lookupStore(id, { contextId: this.getBiggerContext(parentId, defaultParentId) });\n }\n\n /**\n * Get bigger context from two\n */\n protected getBiggerContext(ctx1?: string, ctx2?: string): string | undefined {\n if (!ctx1) {\n return ctx2;\n } else if (!ctx2) {\n return ctx1;\n }\n\n const regexp = /[^a-zA-Z]/g;\n\n return ctx1.replace(regexp, '') > ctx2.replace(regexp, '') ? ctx1 : ctx2;\n }\n\n /**\n * Create new store instance\n */\n protected createStore<T>(\n store: IConstructableStore<T>,\n params: Omit<Required<IStoreParams>, 'key'>,\n ): T {\n const { id, contextId, parentId, suspenseId, componentName, componentProps } = params;\n\n // only for global store\n if (this.stores.has(id)) {\n return this.stores.get(id) as T;\n }\n\n const newStore = new store({\n ...this.storesParams,\n storeManager: this,\n getStore: <TS>(\n targetStore: IConstructableStore<TS>,\n targetParams = { contextId, parentId },\n ) => this.getStore(targetStore, targetParams),\n componentProps,\n initState: this.initState[id],\n });\n\n // assign params to new store\n newStore.libStoreId = id;\n newStore.isGlobal = store.isGlobal;\n newStore.libStoreContextId = store.isGlobal ? 'global' : contextId;\n newStore.libStoreParentId =\n store.isGlobal || !parentId || parentId === contextId ? ROOT_CONTEXT_ID : parentId;\n newStore.libStoreSuspenseId = suspenseId;\n newStore.libStoreComponentName = componentName;\n\n this.setStoreStatus(newStore, store.isGlobal ? StoreStatus.inUse : StoreStatus.init);\n this.prepareStore(newStore);\n EventManager.publish(Events.CREATE_STORE, { store });\n\n return newStore as T;\n }\n\n /**\n * Create stores for component\n *\n * NOTE: use only inside withStores wrapper\n */\n public createStores(\n map: [string, TStoreDefinition][],\n parentId: string,\n contextId: string,\n suspenseId: string,\n componentName: string,\n componentProps: Record<string, any> = {},\n ): IGroupedStores {\n const result = map.reduce(\n (res, [key, store]) => {\n const {\n id,\n store: s,\n isParent = false,\n } = 'store' in store ? store : { store, id: undefined, isParent: false };\n const storeId =\n id ||\n (isParent\n ? (this.getStore(s, { contextId, parentId })?.libStoreId as string)\n : this.getStoreId(s, { key, contextId }));\n\n if (!storeId) {\n return res;\n }\n\n const storeInstance = this.createStore(s, {\n id: storeId,\n contextId,\n parentId,\n suspenseId,\n componentName,\n componentProps,\n });\n\n if (isParent) {\n res.parentStores[key] = storeInstance;\n } else if (storeInstance.isGlobal) {\n res.globalStores[key] = storeInstance;\n } else {\n res.relativeStores[key] = storeInstance;\n }\n\n return res;\n },\n { relativeStores: {}, parentStores: {}, globalStores: {} },\n );\n\n // need create context relation in case when component doesn't include relative stores\n this.createRelationContext(contextId, parentId, componentName);\n\n return result;\n }\n\n /**\n * Create empty relation context\n */\n protected createRelationContext(\n contextId: string,\n parentId?: string,\n componentName?: string,\n ): void {\n if (this.storesRelations.has(contextId)) {\n return;\n }\n\n this.storesRelations.set(contextId, {\n ids: new Set(),\n parentId: !parentId || parentId === contextId ? ROOT_CONTEXT_ID : parentId,\n componentName,\n });\n }\n\n /**\n * Delete relation context id\n */\n protected removeRelationContext(contextId: string): void {\n const storesRelations = this.storesRelations.get(contextId);\n\n if (!storesRelations || contextId === ROOT_CONTEXT_ID || storesRelations.ids.size > 0) {\n return;\n }\n\n this.storesRelations.delete(contextId);\n }\n\n /**\n * Prepare store before usage\n */\n protected prepareStore(store: TStores[string]): void {\n const storeId = store.libStoreId!;\n const contextId = store.libStoreContextId!;\n const suspenseId = store.libStoreSuspenseId!;\n\n if (this.stores.has(storeId)) {\n return;\n }\n\n // restore initial state from server\n const initState = this.initState[storeId];\n\n if (initState) {\n deepMerge(store, initState);\n }\n\n // restore persisted state\n if ('wakeup' in store && Manager.persistedStores.has(storeId)) {\n store.wakeup?.({\n initState,\n persistedState: this.storage?.getStoreData(store),\n manager: this,\n });\n }\n\n // track changes in persisted store\n if (Manager.persistedStores.has(storeId) && 'addOnChangeListener' in store) {\n const onDestroyDefault = store.onDestroy?.bind(store);\n const removeListener = store.addOnChangeListener!(store, this);\n\n store.onDestroy = () => {\n removeListener?.();\n onDestroyDefault?.();\n };\n }\n\n store.init?.();\n this.createRelationContext(contextId, store.libStoreParentId, store.libStoreComponentName);\n\n if (!this.suspenseRelations.has(suspenseId)) {\n this.suspenseRelations.set(suspenseId, new Set());\n }\n\n const { ids } = this.storesRelations.get(contextId)!;\n\n // add store to manager\n this.stores.set(storeId, store);\n ids.add(storeId);\n // add store relation with suspense\n this.suspenseRelations.get(suspenseId)!.add(storeId);\n }\n\n /**\n * Remove store\n */\n protected removeStore(store: TStores[string]): void {\n const storeId = store.libStoreId!;\n const suspenseId = store.libStoreSuspenseId!;\n const { ids } = this.storesRelations.get(store.libStoreContextId!) ?? { ids: new Set() };\n\n if (!this.stores.has(storeId)) {\n return;\n }\n\n this.stores.delete(storeId);\n ids.delete(storeId);\n\n if (suspenseId && this.suspenseRelations.get(suspenseId)?.has(storeId)) {\n this.suspenseRelations.get(suspenseId)!.delete(storeId);\n }\n\n this.removeRelationContext(store.libStoreContextId!);\n\n if ('onDestroy' in store) {\n store.onDestroy?.();\n }\n\n EventManager.publish(Events.DELETE_STORE, { store });\n }\n\n /**\n * Mount stores to component\n *\n * NOTE: use only inside withStores wrapper\n */\n public mountStores(\n contextId: string,\n { globalStores = {}, relativeStores = {} }: Partial<IGroupedStores>,\n ): () => void {\n const { shouldRemoveInitState } = this.options;\n const touchableStores = { ...globalStores, ...relativeStores };\n\n Object.values(touchableStores).forEach((store) => {\n const storeId = store.libStoreId!;\n\n // cleanup init state\n if (shouldRemoveInitState && this.initState[storeId]) {\n delete this.initState[storeId];\n }\n\n this.setStoreStatus(store, StoreStatus.inUse);\n EventManager.publish(Events.MOUNT_STORE, { store });\n });\n\n return () => {\n Object.values(touchableStores).forEach((store) => {\n if (store.isGlobal) {\n return;\n }\n\n this.setStoreStatus(store, StoreStatus.unused);\n EventManager.publish(Events.UNMOUNT_STORE, { store });\n });\n\n this.removeRelationContext(contextId);\n };\n }\n\n /**\n * Change the stores status to touched\n */\n public touchedStores(stores: TStores): void {\n Object.values(stores).forEach((store) => {\n if (store.libStoreStatus !== StoreStatus.init || store.isGlobal) {\n return;\n }\n\n this.setStoreStatus(store, StoreStatus.touched);\n });\n }\n\n /**\n * Change store status\n */\n protected setStoreStatus(store: TStores[string], status: StoreStatus): void {\n const { destroyTimers: { init = 500, touched = 10000, unused = 1000 } = {} } = this.options;\n\n store.libStoreStatus = status;\n\n clearTimeout(store.libDestroyTimer);\n\n let destroyTime = 0;\n\n switch (status) {\n case StoreStatus.init:\n destroyTime = init;\n break;\n\n case StoreStatus.touched:\n destroyTime = touched;\n break;\n\n case StoreStatus.unused:\n destroyTime = unused;\n break;\n }\n\n if (!destroyTime) {\n return;\n }\n\n store.libDestroyTimer = setTimeout(() => this.removeStore(store), destroyTime);\n }\n\n /**\n * Get store state\n */\n public getStoreState(store: TAnyStore): Record<string, any> {\n return store.toJSON?.() ?? Manager.getObservableProps(store);\n }\n\n /**\n * Get store's state\n */\n public toJSON(ids?: string[]): Record<string, any> {\n const result = {};\n const stores = Array.isArray(ids)\n ? ids.reduce((res, id) => {\n if (this.stores.has(id)) {\n res.set(id, this.stores.get(id)!);\n }\n\n return res;\n }, new Map<string, TInitStore>())\n : this.stores;\n\n for (const [storeId, store] of stores.entries()) {\n result[storeId] = this.getStoreState(store);\n }\n\n return result;\n }\n\n /**\n * Save persisted store state to provided storage\n */\n public async savePersistedStore(store: IStorePersisted): Promise<boolean> {\n if (this.options.shouldDisablePersist || !this.storage) {\n return false;\n }\n\n try {\n await this.storage.saveStoreData(store, this.getStoreState(store));\n\n return true;\n } catch (e) {\n console.error('Failed to persist stores: ', e);\n }\n\n return false;\n }\n\n /**\n * Get observable store props (fields)\n */\n public static getObservableProps(store: TAnyStore): Record<string, any> {\n const props = toJS(store);\n\n return Object.entries(props).reduce(\n (res, [prop, value]) => ({\n ...res,\n ...(isObservableProp(store, prop) || isPropSimpleExported(store, prop)\n ? { [prop]: value }\n : {}),\n ...(isPropObservableExported(store, prop)\n ? { [prop]: Manager.getObservableProps(store[prop] as TAnyStore) }\n : {}),\n }),\n {},\n );\n }\n\n /**\n * Persist store\n */\n public static persistStore<TSt>(\n store: IConstructableStore<TSt>,\n id: string,\n options: IPersistOptions = {},\n ): IConstructableStore<TSt> {\n if (Manager.persistedStores.has(id)) {\n console.warn(`Duplicate serializable store key: ${id}`);\n\n return store;\n }\n\n Manager.persistedStores.add(id);\n\n store.libStoreId = id;\n store.libStorageOptions = options;\n\n // add default wakeup handler\n if (!('wakeup' in store.prototype)) {\n store.prototype.wakeup = wakeup;\n }\n\n // add default changes listener\n if (!('addOnChangeListener' in store.prototype)) {\n store.prototype.addOnChangeListener = onChangeListener;\n }\n\n return store;\n }\n}\n\nexport default Manager;\n"],"names":["Manager","static","stores","Map","storesRelations","Set","initState","storage","storesParams","options","shouldDisablePersist","shouldRemoveInitState","suspenseRelations","constructor","this","CombinedStorage","default","undefined","Object","assign","instance","window","state","mbxM","push","pushInitState","Array","isArray","forEach","async","get","Error","getStores","getStoresRelations","getSuspenseRelations","persistedStores","storesState","storeId","entries","getStoreId","store","params","id","contextId","key","libStoreId","name","isGlobal","getStore","has","createStore","parentId","ROOT_CONTEXT_ID","suspenseId","componentName","componentProps","lookupStore","defaultParentId","clearId","split","ids","matchedIds","filter","startsWith","length","console","error","getBiggerContext","ctx1","ctx2","regexp","replace","newStore","storeManager","targetStore","targetParams","libStoreContextId","libStoreParentId","libStoreSuspenseId","libStoreComponentName","setStoreStatus","StoreStatus","inUse","init","prepareStore","EventManager","publish","Events","CREATE_STORE","createStores","map","result","reduce","res","s","isParent","storeInstance","parentStores","globalStores","relativeStores","createRelationContext","set","removeRelationContext","size","delete","deepMerge","wakeup","persistedState","getStoreData","manager","onDestroyDefault","onDestroy","bind","removeListener","addOnChangeListener","add","removeStore","DELETE_STORE","mountStores","touchableStores","values","MOUNT_STORE","unused","UNMOUNT_STORE","touchedStores","libStoreStatus","touched","status","destroyTimers","clearTimeout","libDestroyTimer","destroyTime","setTimeout","getStoreState","toJSON","getObservableProps","saveStoreData","e","props","toJS","prop","value","isObservableProp","isPropSimpleExported","isPropObservableExported","warn","libStorageOptions","prototype","onChangeListener"],"mappings":"2aA2BA,MAAMA,EAIMC,gBAKSC,OAAS,IAAIC,IAKbC,gBAAkB,IAAID,IAQ/BF,uBAAkC,IAAII,IAK7BC,UAKHC,QAKGC,aAKHC,QAA2B,CACzCC,sBAAsB,EACtBC,uBAAuB,GAOfC,kBAA8C,IAAIT,IAK5DU,aAAmBP,UAAEA,EAASE,aAAEA,EAAYD,QAAEA,EAAOE,QAAEA,GAA4B,IAejF,GAdAK,KAAKR,UAAYA,GAAa,GAC9BQ,KAAKN,aAAeA,GAAgB,GACpCM,KAAKP,QACHA,aAAmBQ,EACfR,EACAA,EACE,IAAIQ,EAAgB,CAAEC,QAAST,SAC/BU,EAERC,OAAOC,OAAOL,KAAKL,QAASA,GAAW,CAAE,GAEzCT,EAAQoB,SAAWN,KAGG,oBAAXO,OAAwB,CACjC,MAAMC,EAAQD,OAAOE,KAErBF,OAAOE,KAAO,CAAEC,KAAMV,KAAKW,gBAE1BC,MAAMC,QAAQL,GAASA,EAAQ,IAAIM,QAAQd,KAAKW,cAClD,CACF,CAKMI,aAKL,OAJIf,KAAKP,eACDO,KAAKP,QAAQuB,MAGdhB,IACR,CAKMb,aACL,IAAKD,EAAQoB,SACX,MAAM,IAAIW,MAAM,qCAGlB,OAAO/B,EAAQoB,QAChB,CAKMY,YACL,OAAOlB,KAAKZ,MACb,CAKM+B,qBACL,OAAOnB,KAAKV,eACb,CAKM8B,uBACL,OAAOpB,KAAKF,iBACb,CAKMX,+BACL,OAAOD,EAAQmC,eAChB,CAMMV,cAAgB,CAACW,EAAmC,MACzD,IAAK,MAAOC,EAASf,KAAUJ,OAAOoB,QAAQF,GAC5CtB,KAAKR,UAAU+B,GAAWf,CAC3B,EAOOiB,WACRC,EACAC,EAAuB,IAEvB,MAAMC,GAAEA,EAAEC,UAAEA,EAASC,IAAEA,GAAQH,EAE/B,GAAIC,EACF,OAAOA,EAGT,GAAIF,EAAMK,WACR,OAAOL,EAAMK,WAGf,IAAIR,EAAWG,EAAU,IAAiBA,EAAY,MAAgBA,EAAM3B,YAAYiC,KAExF,OAAIN,EAAMO,SACDV,GAGTA,EAAU,GAAGA,MAAYM,IAElBC,EAAM,GAAGP,MAAYO,IAAQP,EACrC,CAKMW,SAAYR,EAA+BC,EAAuB,IACvE,MAAMJ,EAAUvB,KAAKyB,WAAWC,EAAOC,GAGvC,OAAI3B,KAAKZ,OAAO+C,IAAIZ,GACXvB,KAAKZ,OAAO4B,IAAIO,GAIrBG,EAAMO,SACDjC,KAAKoC,YAAYV,EAAO,CAC7BE,GAAIL,EACJM,UAAW,SACXQ,SAAUC,EACVC,WAAY,GACZC,cAAe,WACfC,eAAgB,CAAE,IAKfzC,KAAK0C,YAAYnB,EAASI,EAClC,CAKSe,YAAYd,EAAYD,GAChC,MAAME,UAAEA,EAAWQ,SAAUM,GAAoBhB,EAC3CiB,EAAUhB,EAAGiB,MAAM,QAAQ,IAC3BC,IAAEA,EAAGT,SAAEA,GAAarC,KAAKV,gBAAgB0B,IAAIa,IAAe,CAChEiB,IAAK,IAAIvD,IACT8C,SAAUM,GAGNI,EAAa,IAAID,GAAKE,QAAQzB,GAAYA,EAAQ0B,WAAW,GAAGL,SAEtE,GAA0B,IAAtBG,EAAWG,OACb,OAAOlD,KAAKZ,OAAO4B,IAAI+B,EAAW,IAC7B,GAAIA,EAAWG,OAAS,EAC7BC,QAAQC,MACN,mGAMJ,GAAKf,GAAYA,IAAaC,EAI9B,OAAOtC,KAAK0C,YAAYd,EAAI,CAAEC,UAAW7B,KAAKqD,iBAAiBhB,EAAUM,IAC1E,CAKSU,iBAAiBC,EAAeC,GACxC,IAAKD,EACH,OAAOC,EACF,IAAKA,EACV,OAAOD,EAGT,MAAME,EAAS,aAEf,OAAOF,EAAKG,QAAQD,EAAQ,IAAMD,EAAKE,QAAQD,EAAQ,IAAMF,EAAOC,CACrE,CAKSnB,YACRV,EACAC,GAEA,MAAMC,GAAEA,EAAEC,UAAEA,EAASQ,SAAEA,EAAQE,WAAEA,EAAUC,cAAEA,EAAaC,eAAEA,GAAmBd,EAG/E,GAAI3B,KAAKZ,OAAO+C,IAAIP,GAClB,OAAO5B,KAAKZ,OAAO4B,IAAIY,GAGzB,MAAM8B,EAAW,IAAIhC,EAAM,IACtB1B,KAAKN,aACRiE,aAAc3D,KACdkC,SAAU,CACR0B,EACAC,EAAe,CAAEhC,YAAWQ,cACzBrC,KAAKkC,SAAS0B,EAAaC,GAChCpB,iBACAjD,UAAWQ,KAAKR,UAAUoC,KAgB5B,OAZA8B,EAAS3B,WAAaH,EACtB8B,EAASzB,SAAWP,EAAMO,SAC1ByB,EAASI,kBAAoBpC,EAAMO,SAAW,SAAWJ,EACzD6B,EAASK,iBACPrC,EAAMO,WAAaI,GAAYA,IAAaR,EAAYS,EAAkBD,EAC5EqB,EAASM,mBAAqBzB,EAC9BmB,EAASO,sBAAwBzB,EAEjCxC,KAAKkE,eAAeR,EAAUhC,EAAMO,SAAWkC,EAAYC,MAAQD,EAAYE,MAC/ErE,KAAKsE,aAAaZ,GAClBa,EAAaC,QAAQC,EAAOC,aAAc,CAAEhD,UAErCgC,CACR,CAOMiB,aACLC,EACAvC,EACAR,EACAU,EACAC,EACAC,EAAsC,IAEtC,MAAMoC,EAASD,EAAIE,QACjB,CAACC,GAAMjD,EAAKJ,MACV,MAAME,GACJA,EACAF,MAAOsD,EAACC,SACRA,GAAW,GACT,UAAWvD,EAAQA,EAAQ,CAAEA,QAAOE,QAAIzB,EAAW8E,UAAU,GAC3D1D,EACJK,IACCqD,EACIjF,KAAKkC,SAAS8C,EAAG,CAAEnD,YAAWQ,cAAaN,WAC5C/B,KAAKyB,WAAWuD,EAAG,CAAElD,MAAKD,eAEhC,IAAKN,EACH,OAAOwD,EAGT,MAAMG,EAAgBlF,KAAKoC,YAAY4C,EAAG,CACxCpD,GAAIL,EACJM,YACAQ,WACAE,aACAC,gBACAC,mBAWF,OARIwC,EACFF,EAAII,aAAarD,GAAOoD,EACfA,EAAcjD,SACvB8C,EAAIK,aAAatD,GAAOoD,EAExBH,EAAIM,eAAevD,GAAOoD,EAGrBH,CAAG,GAEZ,CAAEM,eAAgB,GAAIF,aAAc,CAAA,EAAIC,aAAc,CAAE,IAM1D,OAFApF,KAAKsF,sBAAsBzD,EAAWQ,EAAUG,GAEzCqC,CACR,CAKSS,sBACRzD,EACAQ,EACAG,GAEIxC,KAAKV,gBAAgB6C,IAAIN,IAI7B7B,KAAKV,gBAAgBiG,IAAI1D,EAAW,CAClCiB,IAAK,IAAIvD,IACT8C,SAAWA,GAAYA,IAAaR,EAA8BQ,EAAlBC,EAChDE,iBAEH,CAKSgD,sBAAsB3D,GAC9B,MAAMvC,EAAkBU,KAAKV,gBAAgB0B,IAAIa,IAE5CvC,GAAmBuC,IAAcS,GAAmBhD,EAAgBwD,IAAI2C,KAAO,GAIpFzF,KAAKV,gBAAgBoG,OAAO7D,EAC7B,CAKSyC,aAAa5C,GACrB,MAAMH,EAAUG,EAAMK,WAChBF,EAAYH,EAAMoC,kBAClBvB,EAAab,EAAMsC,mBAEzB,GAAIhE,KAAKZ,OAAO+C,IAAIZ,GAClB,OAIF,MAAM/B,EAAYQ,KAAKR,UAAU+B,GAgBjC,GAdI/B,GACFmG,EAAUjE,EAAOlC,GAIf,WAAYkC,GAASxC,EAAQmC,gBAAgBc,IAAIZ,IACnDG,EAAMkE,SAAS,CACbpG,YACAqG,eAAgB7F,KAAKP,SAASqG,aAAapE,GAC3CqE,QAAS/F,OAKTd,EAAQmC,gBAAgBc,IAAIZ,IAAY,wBAAyBG,EAAO,CAC1E,MAAMsE,EAAmBtE,EAAMuE,WAAWC,KAAKxE,GACzCyE,EAAiBzE,EAAM0E,oBAAqB1E,EAAO1B,MAEzD0B,EAAMuE,UAAY,KAChBE,MACAH,KAAoB,CAEvB,CAEDtE,EAAM2C,SACNrE,KAAKsF,sBAAsBzD,EAAWH,EAAMqC,iBAAkBrC,EAAMuC,uBAE/DjE,KAAKF,kBAAkBqC,IAAII,IAC9BvC,KAAKF,kBAAkByF,IAAIhD,EAAY,IAAIhD,KAG7C,MAAMuD,IAAEA,GAAQ9C,KAAKV,gBAAgB0B,IAAIa,GAGzC7B,KAAKZ,OAAOmG,IAAIhE,EAASG,GACzBoB,EAAIuD,IAAI9E,GAERvB,KAAKF,kBAAkBkB,IAAIuB,GAAa8D,IAAI9E,EAC7C,CAKS+E,YAAY5E,GACpB,MAAMH,EAAUG,EAAMK,WAChBQ,EAAab,EAAMsC,oBACnBlB,IAAEA,GAAQ9C,KAAKV,gBAAgB0B,IAAIU,EAAMoC,oBAAuB,CAAEhB,IAAK,IAAIvD,KAE5ES,KAAKZ,OAAO+C,IAAIZ,KAIrBvB,KAAKZ,OAAOsG,OAAOnE,GACnBuB,EAAI4C,OAAOnE,GAEPgB,GAAcvC,KAAKF,kBAAkBkB,IAAIuB,IAAaJ,IAAIZ,IAC5DvB,KAAKF,kBAAkBkB,IAAIuB,GAAamD,OAAOnE,GAGjDvB,KAAKwF,sBAAsB9D,EAAMoC,mBAE7B,cAAepC,GACjBA,EAAMuE,cAGR1B,EAAaC,QAAQC,EAAO8B,aAAc,CAAE7E,UAC7C,CAOM8E,YACL3E,GACAuD,aAAEA,EAAe,CAAA,EAAEC,eAAEA,EAAiB,CAAA,IAEtC,MAAMxF,sBAAEA,GAA0BG,KAAKL,QACjC8G,EAAkB,IAAKrB,KAAiBC,GAc9C,OAZAjF,OAAOsG,OAAOD,GAAiB3F,SAASY,IACtC,MAAMH,EAAUG,EAAMK,WAGlBlC,GAAyBG,KAAKR,UAAU+B,WACnCvB,KAAKR,UAAU+B,GAGxBvB,KAAKkE,eAAexC,EAAOyC,EAAYC,OACvCG,EAAaC,QAAQC,EAAOkC,YAAa,CAAEjF,SAAQ,IAG9C,KACLtB,OAAOsG,OAAOD,GAAiB3F,SAASY,IAClCA,EAAMO,WAIVjC,KAAKkE,eAAexC,EAAOyC,EAAYyC,QACvCrC,EAAaC,QAAQC,EAAOoC,cAAe,CAAEnF,UAAQ,IAGvD1B,KAAKwF,sBAAsB3D,EAAU,CAExC,CAKMiF,cAAc1H,GACnBgB,OAAOsG,OAAOtH,GAAQ0B,SAASY,IACzBA,EAAMqF,iBAAmB5C,EAAYE,MAAQ3C,EAAMO,UAIvDjC,KAAKkE,eAAexC,EAAOyC,EAAY6C,QAAQ,GAElD,CAKS9C,eAAexC,EAAwBuF,GAC/C,MAAQC,eAAe7C,KAAEA,EAAO,IAAG2C,QAAEA,EAAU,IAAKJ,OAAEA,EAAS,KAAS,CAAA,GAAO5G,KAAKL,QAEpF+B,EAAMqF,eAAiBE,EAEvBE,aAAazF,EAAM0F,iBAEnB,IAAIC,EAAc,EAElB,OAAQJ,GACN,KAAK9C,EAAYE,KACfgD,EAAchD,EACd,MAEF,KAAKF,EAAY6C,QACfK,EAAcL,EACd,MAEF,KAAK7C,EAAYyC,OACfS,EAAcT,EAIbS,IAIL3F,EAAM0F,gBAAkBE,YAAW,IAAMtH,KAAKsG,YAAY5E,IAAQ2F,GACnE,CAKME,cAAc7F,GACnB,OAAOA,EAAM8F,YAActI,EAAQuI,mBAAmB/F,EACvD,CAKM8F,OAAO1E,GACZ,MAAM+B,EAAS,CAAA,EACTzF,EAASwB,MAAMC,QAAQiC,GACzBA,EAAIgC,QAAO,CAACC,EAAKnD,KACX5B,KAAKZ,OAAO+C,IAAIP,IAClBmD,EAAIQ,IAAI3D,EAAI5B,KAAKZ,OAAO4B,IAAIY,IAGvBmD,IACN,IAAI1F,KACPW,KAAKZ,OAET,IAAK,MAAOmC,EAASG,KAAUtC,EAAOoC,UACpCqD,EAAOtD,GAAWvB,KAAKuH,cAAc7F,GAGvC,OAAOmD,CACR,CAKM9D,yBAAyBW,GAC9B,GAAI1B,KAAKL,QAAQC,uBAAyBI,KAAKP,QAC7C,OAAO,EAGT,IAGE,aAFMO,KAAKP,QAAQiI,cAAchG,EAAO1B,KAAKuH,cAAc7F,KAEpD,CACR,CAAC,MAAOiG,GACPxE,QAAQC,MAAM,6BAA8BuE,EAC7C,CAED,OAAO,CACR,CAKMxI,0BAA0BuC,GAC/B,MAAMkG,EAAQC,EAAKnG,GAEnB,OAAOtB,OAAOoB,QAAQoG,GAAO9C,QAC3B,CAACC,GAAM+C,EAAMC,MAAY,IACpBhD,KACCiD,EAAiBtG,EAAOoG,IAASG,EAAqBvG,EAAOoG,GAC7D,CAAEA,CAACA,GAAOC,GACV,CAAE,KACFG,EAAyBxG,EAAOoG,GAChC,CAAEA,CAACA,GAAO5I,EAAQuI,mBAAmB/F,EAAMoG,KAC3C,CAAE,KAER,CAAE,EAEL,CAKM3I,oBACLuC,EACAE,EACAjC,EAA2B,CAAA,GAE3B,OAAIT,EAAQmC,gBAAgBc,IAAIP,IAC9BuB,QAAQgF,KAAK,qCAAqCvG,KAE3CF,IAGTxC,EAAQmC,gBAAgBgF,IAAIzE,GAE5BF,EAAMK,WAAaH,EACnBF,EAAM0G,kBAAoBzI,EAGpB,WAAY+B,EAAM2G,YACtB3G,EAAM2G,UAAUzC,OAASA,GAIrB,wBAAyBlE,EAAM2G,YACnC3G,EAAM2G,UAAUjC,oBAAsBkC,GAGjC5G,EACR"}
1
+ {"version":3,"file":"manager.js","sources":["../src/manager.ts"],"sourcesContent":["import EventManager from '@lomray/event-manager';\nimport { isObservableProp, toJS } from 'mobx';\nimport { ROOT_CONTEXT_ID } from './constants';\nimport deepMerge from './deep-merge';\nimport Events from './events';\nimport {\n isPropExcludedFromExport,\n isPropObservableExported,\n isPropSimpleExported,\n} from './make-exported';\nimport onChangeListener from './on-change-listener';\nimport CombinedStorage from './storages/combined-storage';\nimport StoreStatus from './store-status';\nimport type {\n IConstructableStore,\n IGroupedStores,\n IManagerOptions,\n IManagerParams,\n IPersistOptions,\n IStoreParams,\n IStorePersisted,\n TAnyStore,\n TInitStore,\n TStoreDefinition,\n TStores,\n} from './types';\nimport wakeup from './wakeup';\n\n/**\n * Mobx stores manager\n */\nclass Manager {\n /**\n * Manger instance\n */\n protected static instance: Manager;\n\n /**\n * Created stores\n */\n protected readonly stores = new Map<string, TInitStore>();\n\n /**\n * Relations between stores\n */\n protected readonly storesRelations = new Map<\n string, // contextId\n { ids: Set<string>; parentId: string | null; componentName?: string }\n >();\n\n /**\n * Save persisted stores identities\n */\n protected static readonly persistedStores = new Set<string>();\n\n /**\n * Initial stores state (local storage, custom etc.)\n */\n protected readonly initState: Record<string, any>;\n\n /**\n * Storage for persisted stores\n */\n public readonly storage?: CombinedStorage;\n\n /**\n * Additional store's constructor params\n */\n protected readonly storesParams: IManagerParams['storesParams'];\n\n /**\n * Manager options\n */\n public readonly options: IManagerOptions = {\n shouldDisablePersist: false,\n shouldRemoveInitState: true,\n };\n\n /**\n * Suspense stores relations\n * @see withStores\n */\n protected suspenseRelations: Map<string, Set<string>> = new Map();\n\n /**\n * @constructor\n */\n public constructor({ initState, storesParams, storage, options }: IManagerParams = {}) {\n this.initState = initState || {};\n this.storesParams = storesParams || {};\n this.storage =\n storage instanceof CombinedStorage\n ? storage\n : storage\n ? new CombinedStorage({ default: storage })\n : undefined;\n\n Object.assign(this.options, options || {});\n\n Manager.instance = this;\n\n // only client side\n if (typeof window !== 'undefined') {\n const state = window.mbxM;\n\n window.mbxM = { push: this.pushInitState };\n\n (Array.isArray(state) ? state : []).forEach(this.pushInitState);\n }\n }\n\n /**\n * Init store manager\n */\n public async init(): Promise<Manager> {\n if (this.storage) {\n await this.storage.get();\n }\n\n return this;\n }\n\n /**\n * Get manager instance\n */\n public static get(): Manager {\n if (!Manager.instance) {\n throw new Error('Store manager is not initialized.');\n }\n\n return Manager.instance;\n }\n\n /**\n * Get all stores\n */\n public getStores(): Manager['stores'] {\n return this.stores;\n }\n\n /**\n * Get stores relations\n */\n public getStoresRelations(): Manager['storesRelations'] {\n return this.storesRelations;\n }\n\n /**\n * Get suspense relations with stores\n */\n public getSuspenseRelations(): Manager['suspenseRelations'] {\n return this.suspenseRelations;\n }\n\n /**\n * Get persisted stores ids\n */\n public static getPersistedStoresIds(): Set<string> {\n return Manager.persistedStores;\n }\n\n /**\n * Push initial state dynamically\n * E.g. when stream html\n */\n public pushInitState = (storesState: Record<string, any> = {}): void => {\n for (const [storeId, state] of Object.entries(storesState)) {\n this.initState[storeId] = state;\n }\n };\n\n /**\n * Get store identity\n * @protected\n */\n protected getStoreId<T extends TAnyStore>(\n store: IConstructableStore<T> | TInitStore,\n params: IStoreParams = {},\n ): string {\n const { id, contextId, key } = params;\n\n if (id) {\n return id;\n }\n\n if (store.libStoreId) {\n return store.libStoreId;\n }\n\n let storeId = (store['id'] as string) || (store['name'] as string) || store.constructor.name;\n\n if (store.isGlobal) {\n return storeId;\n }\n\n storeId = `${storeId}--${contextId!}`;\n\n return key ? `${storeId}--${key}` : storeId;\n }\n\n /**\n * Get exist store\n */\n public getStore<T>(store: IConstructableStore<T>, params: IStoreParams = {}): T | undefined {\n const storeId = this.getStoreId(store, params);\n\n // full match\n if (this.stores.has(storeId)) {\n return this.stores.get(storeId) as T;\n }\n\n // in case with global store (create if not exist)\n if (store.isGlobal) {\n return this.createStore(store, {\n id: storeId,\n contextId: 'global',\n parentId: ROOT_CONTEXT_ID,\n suspenseId: '',\n componentName: 'root-app',\n componentProps: {},\n });\n }\n\n // try to look up store in current or parent context\n return this.lookupStore(storeId, params) as T;\n }\n\n /**\n * Lookup store\n */\n protected lookupStore(id: string, params: IStoreParams): TInitStore<TAnyStore> | undefined {\n const { contextId, parentId: defaultParentId } = params;\n const clearId = id.split('--')?.[0];\n const { ids, parentId } = this.storesRelations.get(contextId!) ?? {\n ids: new Set(),\n parentId: defaultParentId,\n };\n\n const matchedIds = [...ids].filter((storeId) => storeId.startsWith(`${clearId}--`));\n\n if (matchedIds.length === 1) {\n return this.stores.get(matchedIds[0]);\n } else if (matchedIds.length > 1) {\n console.error(\n 'Parent context has multiple stores with the same id, please pass key to getStore function.',\n );\n\n return undefined;\n }\n\n if (!parentId || parentId === ROOT_CONTEXT_ID) {\n return undefined;\n }\n\n return this.lookupStore(id, { contextId: this.getBiggerContext(parentId, defaultParentId) });\n }\n\n /**\n * Get bigger context from two\n */\n protected getBiggerContext(ctx1?: string, ctx2?: string): string | undefined {\n if (!ctx1) {\n return ctx2;\n } else if (!ctx2) {\n return ctx1;\n }\n\n const regexp = /[^a-zA-Z]/g;\n\n return ctx1.replace(regexp, '') > ctx2.replace(regexp, '') ? ctx1 : ctx2;\n }\n\n /**\n * Create new store instance\n */\n protected createStore<T>(\n store: IConstructableStore<T>,\n params: Omit<Required<IStoreParams>, 'key'>,\n ): T {\n const { id, contextId, parentId, suspenseId, componentName, componentProps } = params;\n\n // only for global store\n if (this.stores.has(id)) {\n return this.stores.get(id) as T;\n }\n\n const newStore = new store({\n ...this.storesParams,\n storeManager: this,\n getStore: <TS>(\n targetStore: IConstructableStore<TS>,\n targetParams = { contextId, parentId },\n ) => this.getStore(targetStore, targetParams),\n componentProps,\n initState: this.initState[id],\n });\n\n // assign params to new store\n newStore.libStoreId = id;\n newStore.isGlobal = store.isGlobal;\n newStore.libStoreContextId = store.isGlobal ? 'global' : contextId;\n newStore.libStoreParentId =\n store.isGlobal || !parentId || parentId === contextId ? ROOT_CONTEXT_ID : parentId;\n newStore.libStoreSuspenseId = suspenseId;\n newStore.libStoreComponentName = componentName;\n\n this.setStoreStatus(newStore, store.isGlobal ? StoreStatus.inUse : StoreStatus.init);\n this.prepareStore(newStore);\n EventManager.publish(Events.CREATE_STORE, { store });\n\n return newStore as T;\n }\n\n /**\n * Create stores for component\n *\n * NOTE: use only inside withStores wrapper\n */\n public createStores(\n map: [string, TStoreDefinition][],\n parentId: string,\n contextId: string,\n suspenseId: string,\n componentName: string,\n componentProps: Record<string, any> = {},\n ): IGroupedStores {\n const result = map.reduce(\n (res, [key, store]) => {\n const {\n id,\n store: s,\n isParent = false,\n } = 'store' in store ? store : { store, id: undefined, isParent: false };\n const storeId =\n id ||\n (isParent\n ? (this.getStore(s, { contextId, parentId })?.libStoreId as string)\n : this.getStoreId(s, { key, contextId }));\n\n if (!storeId) {\n return res;\n }\n\n const storeInstance = this.createStore(s, {\n id: storeId,\n contextId,\n parentId,\n suspenseId,\n componentName,\n componentProps,\n });\n\n if (isParent) {\n res.parentStores[key] = storeInstance;\n } else if (storeInstance.isGlobal) {\n res.globalStores[key] = storeInstance;\n } else {\n res.relativeStores[key] = storeInstance;\n }\n\n return res;\n },\n { relativeStores: {}, parentStores: {}, globalStores: {} },\n );\n\n // need create context relation in case when component doesn't include relative stores\n this.createRelationContext(contextId, parentId, componentName);\n\n return result;\n }\n\n /**\n * Create empty relation context\n */\n protected createRelationContext(\n contextId: string,\n parentId?: string,\n componentName?: string,\n ): void {\n if (this.storesRelations.has(contextId)) {\n return;\n }\n\n this.storesRelations.set(contextId, {\n ids: new Set(),\n parentId: !parentId || parentId === contextId ? ROOT_CONTEXT_ID : parentId,\n componentName,\n });\n }\n\n /**\n * Delete relation context id\n */\n protected removeRelationContext(contextId: string): void {\n const storesRelations = this.storesRelations.get(contextId);\n\n if (!storesRelations || contextId === ROOT_CONTEXT_ID || storesRelations.ids.size > 0) {\n return;\n }\n\n this.storesRelations.delete(contextId);\n }\n\n /**\n * Prepare store before usage\n */\n protected prepareStore(store: TStores[string]): void {\n const storeId = store.libStoreId!;\n const contextId = store.libStoreContextId!;\n const suspenseId = store.libStoreSuspenseId!;\n\n if (this.stores.has(storeId)) {\n return;\n }\n\n // restore initial state from server\n const initState = this.initState[storeId];\n\n if (initState) {\n deepMerge(store, initState);\n }\n\n // restore persisted state\n if ('wakeup' in store && Manager.persistedStores.has(storeId)) {\n store.wakeup?.({\n initState,\n persistedState: this.storage?.getStoreData(store),\n manager: this,\n });\n }\n\n // track changes in persisted store\n if (Manager.persistedStores.has(storeId) && 'addOnChangeListener' in store) {\n const onDestroyDefault = store.onDestroy?.bind(store);\n const removeListener = store.addOnChangeListener!(store, this);\n\n store.onDestroy = () => {\n removeListener?.();\n onDestroyDefault?.();\n };\n }\n\n store.init?.();\n this.createRelationContext(contextId, store.libStoreParentId, store.libStoreComponentName);\n\n if (!this.suspenseRelations.has(suspenseId)) {\n this.suspenseRelations.set(suspenseId, new Set());\n }\n\n const { ids } = this.storesRelations.get(contextId)!;\n\n // add store to manager\n this.stores.set(storeId, store);\n ids.add(storeId);\n // add store relation with suspense\n this.suspenseRelations.get(suspenseId)!.add(storeId);\n }\n\n /**\n * Remove store\n */\n protected removeStore(store: TStores[string]): void {\n const storeId = store.libStoreId!;\n const suspenseId = store.libStoreSuspenseId!;\n const { ids } = this.storesRelations.get(store.libStoreContextId!) ?? { ids: new Set() };\n\n if (!this.stores.has(storeId)) {\n return;\n }\n\n this.stores.delete(storeId);\n ids.delete(storeId);\n\n if (suspenseId && this.suspenseRelations.get(suspenseId)?.has(storeId)) {\n this.suspenseRelations.get(suspenseId)!.delete(storeId);\n }\n\n this.removeRelationContext(store.libStoreContextId!);\n\n if ('onDestroy' in store) {\n store.onDestroy?.();\n }\n\n EventManager.publish(Events.DELETE_STORE, { store });\n }\n\n /**\n * Mount stores to component\n *\n * NOTE: use only inside withStores wrapper\n */\n public mountStores(\n contextId: string,\n { globalStores = {}, relativeStores = {} }: Partial<IGroupedStores>,\n ): () => void {\n const { shouldRemoveInitState } = this.options;\n const touchableStores = { ...globalStores, ...relativeStores };\n\n Object.values(touchableStores).forEach((store) => {\n const storeId = store.libStoreId!;\n\n // cleanup init state\n if (shouldRemoveInitState && this.initState[storeId]) {\n delete this.initState[storeId];\n }\n\n this.setStoreStatus(store, StoreStatus.inUse);\n EventManager.publish(Events.MOUNT_STORE, { store });\n });\n\n return () => {\n Object.values(touchableStores).forEach((store) => {\n if (store.isGlobal) {\n return;\n }\n\n this.setStoreStatus(store, StoreStatus.unused);\n EventManager.publish(Events.UNMOUNT_STORE, { store });\n });\n\n this.removeRelationContext(contextId);\n };\n }\n\n /**\n * Change the stores status to touched\n */\n public touchedStores(stores: TStores): void {\n Object.values(stores).forEach((store) => {\n if (store.libStoreStatus !== StoreStatus.init || store.isGlobal) {\n return;\n }\n\n this.setStoreStatus(store, StoreStatus.touched);\n });\n }\n\n /**\n * Change store status\n */\n protected setStoreStatus(store: TStores[string], status: StoreStatus): void {\n const { destroyTimers: { init = 500, touched = 10000, unused = 1000 } = {} } = this.options;\n\n store.libStoreStatus = status;\n\n clearTimeout(store.libDestroyTimer);\n\n let destroyTime = 0;\n\n switch (status) {\n case StoreStatus.init:\n destroyTime = init;\n break;\n\n case StoreStatus.touched:\n destroyTime = touched;\n break;\n\n case StoreStatus.unused:\n destroyTime = unused;\n break;\n }\n\n if (!destroyTime) {\n return;\n }\n\n store.libDestroyTimer = setTimeout(() => this.removeStore(store), destroyTime);\n }\n\n /**\n * Get store state\n */\n public getStoreState(store: TAnyStore): Record<string, any> {\n return store.toJSON?.() ?? Manager.getObservableProps(store);\n }\n\n /**\n * Get store's state\n */\n public toJSON(ids?: string[]): Record<string, any> {\n const result = {};\n const stores = Array.isArray(ids)\n ? ids.reduce((res, id) => {\n if (this.stores.has(id)) {\n res.set(id, this.stores.get(id)!);\n }\n\n return res;\n }, new Map<string, TInitStore>())\n : this.stores;\n\n for (const [storeId, store] of stores.entries()) {\n result[storeId] = this.getStoreState(store);\n }\n\n return result;\n }\n\n /**\n * Save persisted store state to provided storage\n */\n public async savePersistedStore(store: IStorePersisted): Promise<boolean> {\n if (this.options.shouldDisablePersist || !this.storage) {\n return false;\n }\n\n try {\n await this.storage.saveStoreData(store, this.getStoreState(store));\n\n return true;\n } catch (e) {\n console.error('Failed to persist stores: ', e);\n }\n\n return false;\n }\n\n /**\n * Get observable store props (fields)\n */\n public static getObservableProps(store: TAnyStore): Record<string, any> {\n const props = toJS(store);\n\n return Object.entries(props).reduce(\n (res, [prop, value]) => ({\n ...res,\n ...((isObservableProp(store, prop) && !isPropExcludedFromExport(store, prop)) ||\n isPropSimpleExported(store, prop)\n ? { [prop]: value }\n : {}),\n ...(isPropObservableExported(store, prop)\n ? { [prop]: Manager.getObservableProps(store[prop] as TAnyStore) }\n : {}),\n }),\n {},\n );\n }\n\n /**\n * Persist store\n */\n public static persistStore<TSt>(\n store: IConstructableStore<TSt>,\n id: string,\n options: IPersistOptions = {},\n ): IConstructableStore<TSt> {\n Manager.persistedStores.add(id);\n\n store.libStoreId = id;\n\n // add storage options\n if (!('libStorageOptions' in store.prototype)) {\n store.prototype.libStorageOptions = options;\n }\n\n // add default wakeup handler\n if (!('wakeup' in store.prototype)) {\n store.prototype.wakeup = wakeup;\n }\n\n // add default changes listener\n if (!('addOnChangeListener' in store.prototype)) {\n store.prototype.addOnChangeListener = onChangeListener;\n }\n\n return store;\n }\n}\n\nexport default Manager;\n"],"names":["Manager","static","stores","Map","storesRelations","Set","initState","storage","storesParams","options","shouldDisablePersist","shouldRemoveInitState","suspenseRelations","constructor","this","CombinedStorage","default","undefined","Object","assign","instance","window","state","mbxM","push","pushInitState","Array","isArray","forEach","async","get","Error","getStores","getStoresRelations","getSuspenseRelations","persistedStores","storesState","storeId","entries","getStoreId","store","params","id","contextId","key","libStoreId","name","isGlobal","getStore","has","createStore","parentId","ROOT_CONTEXT_ID","suspenseId","componentName","componentProps","lookupStore","defaultParentId","clearId","split","ids","matchedIds","filter","startsWith","length","console","error","getBiggerContext","ctx1","ctx2","regexp","replace","newStore","storeManager","targetStore","targetParams","libStoreContextId","libStoreParentId","libStoreSuspenseId","libStoreComponentName","setStoreStatus","StoreStatus","inUse","init","prepareStore","EventManager","publish","Events","CREATE_STORE","createStores","map","result","reduce","res","s","isParent","storeInstance","parentStores","globalStores","relativeStores","createRelationContext","set","removeRelationContext","size","delete","deepMerge","wakeup","persistedState","getStoreData","manager","onDestroyDefault","onDestroy","bind","removeListener","addOnChangeListener","add","removeStore","DELETE_STORE","mountStores","touchableStores","values","MOUNT_STORE","unused","UNMOUNT_STORE","touchedStores","libStoreStatus","touched","status","destroyTimers","clearTimeout","libDestroyTimer","destroyTime","setTimeout","getStoreState","toJSON","getObservableProps","saveStoreData","e","props","toJS","prop","value","isObservableProp","isPropExcludedFromExport","isPropSimpleExported","isPropObservableExported","prototype","libStorageOptions","onChangeListener"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lomray/react-mobx-manager",
3
- "version": "3.2.0-beta.1",
3
+ "version": "3.2.0",
4
4
  "description": "This package provides Mobx stores manager for react.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -31,7 +31,7 @@
31
31
  "homepage": "https://github.com/Lomray-Software/react-mobx-manager",
32
32
  "scripts": {
33
33
  "build": "rollup -c",
34
- "build:watch": "rollup -c -w --environment BUILD:development",
34
+ "build:watch": "rollup -c -w",
35
35
  "lint:check": "eslint \"src/**/*.{ts,tsx,*.ts,*tsx}\"",
36
36
  "lint:format": "eslint --fix \"src/**/*.{ts,tsx,*.ts,*tsx}\"",
37
37
  "ts:check": "tsc --project ./tsconfig.checks.json --skipLibCheck --noemit",
@@ -1,2 +1,2 @@
1
- class t{storages;persistData={};defaultId;constructor(t){this.storages=t,this.defaultId=Object.keys(t)?.[0]}async get(){try{const t=await Promise.all(Object.values(this.storages).map((t=>t.get()||{})));return this.persistData=Object.keys(this.storages).reduce(((e,s,r)=>({...e,[s]:t[r]})),{}),this.persistData}catch(t){return{}}}flush(){return Promise.all(Object.values(this.storages).map((t=>t.flush())))}set(t,e){const s=this.storages[e??this.defaultId];if(s)return s.set(t)}getStoreOptions(t){return{attributes:{[this.defaultId]:["*"]},...t.libStorageOptions??{}}}getStoreData(t){const e=t.libStoreId,{attributes:s}=this.getStoreOptions(t);return Object.entries(s).reduce(((t,[s,r])=>{const a=this.persistData?.[s]?.[e]??{};return{...t,..."*"===r[0]?a:r.reduce(((t,e)=>({...t,...void 0!==a[e]?{[e]:a[e]}:{}})),{})}}),{})}async saveStoreData(t,e){const s=t.libStoreId,{attributes:r}=this.getStoreOptions(t),a=Object.keys(e??{}),i=Object.entries(r).map((([t,r])=>{const i="*"===r[0]?e:r.reduce(((t,s)=>({...t,...a.includes(s)?{[s]:e?.[s]}:{}})),{});return this.set({...this.persistData?.[t]??{},[s]:i},t)}));await Promise.all(i)}}export{t as default};
1
+ import t from"../deep-compare.js";class e{storages;persistData={};defaultId;constructor(t){this.storages=t,this.defaultId=Object.keys(t)?.[0]}async get(){try{const t=await Promise.all(Object.values(this.storages).map((t=>t.get()||{})));return this.persistData=Object.keys(this.storages).reduce(((e,s,r)=>({...e,[s]:t[r]})),{}),this.persistData}catch(t){return{}}}flush(){return Promise.all(Object.values(this.storages).map((t=>t.flush())))}set(t,e){const s=this.storages[e??this.defaultId];if(s)return s.set(t)}getStoreOptions(t){return{attributes:{[this.defaultId]:["*"]},behaviour:"exclude",...t.libStorageOptions??{}}}getStoreData(t){const e=t.libStoreId,{attributes:s}=this.getStoreOptions(t);return Object.entries(s).reduce(((t,[s,r])=>{const a=this.persistData?.[s]?.[e]??{};return{...t,..."*"===r[0]?a:r.reduce(((t,e)=>({...t,...void 0!==a[e]?{[e]:a[e]}:{}})),{})}}),{})}async saveStoreData(e,s){const r=e.libStoreId,{attributes:a,behaviour:i}=this.getStoreOptions(e),o=new Set(Object.keys(s??{})),u=Object.entries(a).map((([e,a])=>{const u=("*"===a[0]?[...o]:a).reduce(((t,e)=>o.has(e)?("exclude"===i&&o.delete(e),{...t,[e]:s?.[e]}):t),{}),c={...this.persistData?.[e]??{},[r]:u};return t(this.persistData?.[e]?.[r]??{},u)?null:this.set(c,e)}));await Promise.all(u)}}export{e as default};
2
2
  //# sourceMappingURL=combined-storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"combined-storage.js","sources":["../../src/storages/combined-storage.ts"],"sourcesContent":["import type { IPersistOptions, IStorage, IStorePersisted } from '../types';\n\ninterface ICombinedStorage {\n [name: string]: IStorage;\n}\n\n/**\n * Combined storage for mobx store manager\n */\nclass CombinedStorage implements IStorage {\n /**\n * @protected\n */\n protected storages: ICombinedStorage;\n\n /**\n * Restored persist storage data\n * @protected\n */\n protected persistData: Record<string, any> = {};\n\n /**\n * Default storage id\n * @protected\n */\n protected defaultId: string;\n\n /**\n * @constructor\n *\n * First storage will be used as default\n */\n constructor(storages: ICombinedStorage) {\n this.storages = storages;\n this.defaultId = Object.keys(storages)?.[0];\n }\n\n /**\n * @inheritDoc\n */\n public async get(): Promise<Record<string, any> | undefined> {\n try {\n const data = await Promise.all(\n Object.values(this.storages).map((storage) => storage.get() || {}),\n );\n\n this.persistData = Object.keys(this.storages).reduce(\n (res, key, index) => ({\n ...res,\n [key]: data[index],\n }),\n {},\n );\n\n return this.persistData;\n } catch (e) {\n return {};\n }\n }\n\n /**\n * @inheritDoc\n */\n public flush(): void | Promise<any> {\n return Promise.all(Object.values(this.storages).map((storage) => storage.flush()));\n }\n\n /**\n * @inheritDoc\n */\n public set(\n value: Record<string, any> | undefined,\n storageId?: string,\n ): ReturnType<IStorage['set']> {\n const storage = this.storages[storageId ?? this.defaultId];\n\n if (!storage) {\n return;\n }\n\n return storage.set(value);\n }\n\n /**\n * Return store storage options\n */\n protected getStoreOptions(store: IStorePersisted): IPersistOptions {\n return {\n attributes: {\n [this.defaultId]: ['*'],\n },\n ...(store.libStorageOptions ?? {}),\n };\n }\n\n /**\n * Return store persist data\n */\n public getStoreData(store: IStorePersisted): Record<string, any> | undefined {\n const storeId = store.libStoreId!;\n const { attributes } = this.getStoreOptions(store);\n\n return Object.entries(attributes!).reduce((res, [storageId, attr]) => {\n const storageData = this.persistData?.[storageId]?.[storeId] ?? {};\n const allowedData =\n attr[0] === '*'\n ? storageData\n : attr.reduce(\n (r, attrName) => ({\n ...r,\n ...(storageData[attrName] !== undefined\n ? { [attrName]: storageData[attrName] }\n : {}),\n }),\n {},\n );\n\n return {\n ...res,\n ...allowedData,\n };\n }, {});\n }\n\n /**\n * Save store data in storage\n */\n public async saveStoreData(\n store: IStorePersisted,\n data: Record<string, any> | undefined,\n ): Promise<void> {\n const storeId = store.libStoreId!;\n const { attributes } = this.getStoreOptions(store);\n const dataKeys = Object.keys(data ?? {});\n\n const dataByStorages = Object.entries(attributes!).map(([storageId, attr]) => {\n const storeData =\n attr[0] === '*'\n ? data\n : attr.reduce(\n (r, attrName) => ({\n ...r,\n ...(dataKeys.includes(attrName) ? { [attrName]: data?.[attrName] } : {}),\n }),\n {},\n );\n\n return this.set(\n {\n ...(this.persistData?.[storageId] ?? {}),\n [storeId]: storeData,\n } as Record<string, any>,\n storageId,\n );\n });\n\n await Promise.all(dataByStorages);\n }\n}\n\nexport default CombinedStorage;\n"],"names":["CombinedStorage","storages","persistData","defaultId","constructor","this","Object","keys","async","data","Promise","all","values","map","storage","get","reduce","res","key","index","e","flush","set","value","storageId","getStoreOptions","store","attributes","libStorageOptions","getStoreData","storeId","libStoreId","entries","attr","storageData","r","attrName","undefined","dataKeys","dataByStorages","storeData","includes"],"mappings":"AASA,MAAMA,EAIMC,SAMAC,YAAmC,CAAA,EAMnCC,UAOVC,YAAYH,GACVI,KAAKJ,SAAWA,EAChBI,KAAKF,UAAYG,OAAOC,KAAKN,KAAY,EAC1C,CAKMO,YACL,IACE,MAAMC,QAAaC,QAAQC,IACzBL,OAAOM,OAAOP,KAAKJ,UAAUY,KAAKC,GAAYA,EAAQC,OAAS,CAAE,KAWnE,OARAV,KAAKH,YAAcI,OAAOC,KAAKF,KAAKJ,UAAUe,QAC5C,CAACC,EAAKC,EAAKC,KAAW,IACjBF,EACHC,CAACA,GAAMT,EAAKU,MAEd,CAAE,GAGGd,KAAKH,WACb,CAAC,MAAOkB,GACP,MAAO,EACR,CACF,CAKMC,QACL,OAAOX,QAAQC,IAAIL,OAAOM,OAAOP,KAAKJ,UAAUY,KAAKC,GAAYA,EAAQO,UAC1E,CAKMC,IACLC,EACAC,GAEA,MAAMV,EAAUT,KAAKJ,SAASuB,GAAanB,KAAKF,WAEhD,GAAKW,EAIL,OAAOA,EAAQQ,IAAIC,EACpB,CAKSE,gBAAgBC,GACxB,MAAO,CACLC,WAAY,CACV,CAACtB,KAAKF,WAAY,CAAC,SAEjBuB,EAAME,mBAAqB,CAAE,EAEpC,CAKMC,aAAaH,GAClB,MAAMI,EAAUJ,EAAMK,YAChBJ,WAAEA,GAAetB,KAAKoB,gBAAgBC,GAE5C,OAAOpB,OAAO0B,QAAQL,GAAaX,QAAO,CAACC,GAAMO,EAAWS,MAC1D,MAAMC,EAAc7B,KAAKH,cAAcsB,KAAaM,IAAY,GAchE,MAAO,IACFb,KAbS,MAAZgB,EAAK,GACDC,EACAD,EAAKjB,QACH,CAACmB,EAAGC,KAAc,IACbD,UAC2BE,IAA1BH,EAAYE,GACZ,CAAEA,CAACA,GAAWF,EAAYE,IAC1B,CAAE,KAER,CAAE,GAMT,GACA,CAAE,EACN,CAKM5B,oBACLkB,EACAjB,GAEA,MAAMqB,EAAUJ,EAAMK,YAChBJ,WAAEA,GAAetB,KAAKoB,gBAAgBC,GACtCY,EAAWhC,OAAOC,KAAKE,GAAQ,CAAE,GAEjC8B,EAAiBjC,OAAO0B,QAAQL,GAAad,KAAI,EAAEW,EAAWS,MAClE,MAAMO,EACQ,MAAZP,EAAK,GACDxB,EACAwB,EAAKjB,QACH,CAACmB,EAAGC,KAAc,IACbD,KACCG,EAASG,SAASL,GAAY,CAAEA,CAACA,GAAW3B,IAAO2B,IAAc,CAAE,KAEzE,CAAE,GAGV,OAAO/B,KAAKiB,IACV,IACMjB,KAAKH,cAAcsB,IAAc,CAAE,EACvCM,CAACA,GAAUU,GAEbhB,EACD,UAGGd,QAAQC,IAAI4B,EACnB"}
1
+ {"version":3,"file":"combined-storage.js","sources":["../../src/storages/combined-storage.ts"],"sourcesContent":["import deepCompare from '../deep-compare';\nimport type { IPersistOptions, IStorage, IStorePersisted } from '../types';\n\ninterface ICombinedStorage {\n [name: string]: IStorage;\n}\n\n/**\n * Combined storage for mobx store manager\n */\nclass CombinedStorage implements IStorage {\n /**\n * @protected\n */\n protected storages: ICombinedStorage;\n\n /**\n * Restored persist storage data\n * @protected\n */\n protected persistData: Record<string, any> = {};\n\n /**\n * Default storage id\n * @protected\n */\n protected defaultId: string;\n\n /**\n * @constructor\n *\n * First storage will be used as default\n */\n constructor(storages: ICombinedStorage) {\n this.storages = storages;\n this.defaultId = Object.keys(storages)?.[0];\n }\n\n /**\n * @inheritDoc\n */\n public async get(): Promise<Record<string, any> | undefined> {\n try {\n const data = await Promise.all(\n Object.values(this.storages).map((storage) => storage.get() || {}),\n );\n\n this.persistData = Object.keys(this.storages).reduce(\n (res, key, index) => ({\n ...res,\n [key]: data[index],\n }),\n {},\n );\n\n return this.persistData;\n } catch (e) {\n return {};\n }\n }\n\n /**\n * @inheritDoc\n */\n public flush(): void | Promise<any> {\n return Promise.all(Object.values(this.storages).map((storage) => storage.flush()));\n }\n\n /**\n * @inheritDoc\n */\n public set(\n value: Record<string, any> | undefined,\n storageId?: string,\n ): ReturnType<IStorage['set']> {\n const storage = this.storages[storageId ?? this.defaultId];\n\n if (!storage) {\n return;\n }\n\n return storage.set(value);\n }\n\n /**\n * Return store storage options\n */\n protected getStoreOptions(store: IStorePersisted): IPersistOptions {\n return {\n attributes: {\n [this.defaultId]: ['*'],\n },\n behaviour: 'exclude',\n ...(store.libStorageOptions ?? {}),\n };\n }\n\n /**\n * Return store persist data\n */\n public getStoreData(store: IStorePersisted): Record<string, any> | undefined {\n const storeId = store.libStoreId!;\n const { attributes } = this.getStoreOptions(store);\n\n return Object.entries(attributes!).reduce((res, [storageId, attr]) => {\n const storageData = this.persistData?.[storageId]?.[storeId] ?? {};\n const allowedData =\n attr[0] === '*'\n ? storageData\n : attr.reduce(\n (r, attrName) => ({\n ...r,\n ...(storageData[attrName] !== undefined\n ? { [attrName]: storageData[attrName] }\n : {}),\n }),\n {},\n );\n\n return {\n ...res,\n ...allowedData,\n };\n }, {});\n }\n\n /**\n * Save store data in storage\n */\n public async saveStoreData(\n store: IStorePersisted,\n data: Record<string, any> | undefined,\n ): Promise<void> {\n const storeId = store.libStoreId!;\n const { attributes, behaviour } = this.getStoreOptions(store);\n const dataKeys = new Set(Object.keys(data ?? {}));\n\n const dataByStorages = Object.entries(attributes!).map(([storageId, attr]) => {\n const storeData = (attr[0] === '*' ? [...dataKeys] : attr).reduce((r, attrName) => {\n if (!dataKeys.has(attrName)) {\n return r;\n }\n\n if (behaviour === 'exclude') {\n dataKeys.delete(attrName);\n }\n\n return {\n ...r,\n [attrName]: data?.[attrName],\n };\n }, {});\n\n const newData = {\n ...(this.persistData?.[storageId] ?? {}),\n [storeId]: storeData,\n } as Record<string, any>;\n\n // skip updating if nothing changed\n if (deepCompare(this.persistData?.[storageId]?.[storeId] ?? {}, storeData)) {\n return null;\n }\n\n return this.set(newData, storageId);\n });\n\n await Promise.all(dataByStorages);\n }\n}\n\nexport default CombinedStorage;\n"],"names":["CombinedStorage","storages","persistData","defaultId","constructor","this","Object","keys","async","data","Promise","all","values","map","storage","get","reduce","res","key","index","e","flush","set","value","storageId","getStoreOptions","store","attributes","behaviour","libStorageOptions","getStoreData","storeId","libStoreId","entries","attr","storageData","r","attrName","undefined","dataKeys","Set","dataByStorages","storeData","has","delete","newData","deepCompare"],"mappings":"kCAUA,MAAMA,EAIMC,SAMAC,YAAmC,CAAA,EAMnCC,UAOVC,YAAYH,GACVI,KAAKJ,SAAWA,EAChBI,KAAKF,UAAYG,OAAOC,KAAKN,KAAY,EAC1C,CAKMO,YACL,IACE,MAAMC,QAAaC,QAAQC,IACzBL,OAAOM,OAAOP,KAAKJ,UAAUY,KAAKC,GAAYA,EAAQC,OAAS,CAAE,KAWnE,OARAV,KAAKH,YAAcI,OAAOC,KAAKF,KAAKJ,UAAUe,QAC5C,CAACC,EAAKC,EAAKC,KAAW,IACjBF,EACHC,CAACA,GAAMT,EAAKU,MAEd,CAAE,GAGGd,KAAKH,WACb,CAAC,MAAOkB,GACP,MAAO,EACR,CACF,CAKMC,QACL,OAAOX,QAAQC,IAAIL,OAAOM,OAAOP,KAAKJ,UAAUY,KAAKC,GAAYA,EAAQO,UAC1E,CAKMC,IACLC,EACAC,GAEA,MAAMV,EAAUT,KAAKJ,SAASuB,GAAanB,KAAKF,WAEhD,GAAKW,EAIL,OAAOA,EAAQQ,IAAIC,EACpB,CAKSE,gBAAgBC,GACxB,MAAO,CACLC,WAAY,CACV,CAACtB,KAAKF,WAAY,CAAC,MAErByB,UAAW,aACPF,EAAMG,mBAAqB,CAAE,EAEpC,CAKMC,aAAaJ,GAClB,MAAMK,EAAUL,EAAMM,YAChBL,WAAEA,GAAetB,KAAKoB,gBAAgBC,GAE5C,OAAOpB,OAAO2B,QAAQN,GAAaX,QAAO,CAACC,GAAMO,EAAWU,MAC1D,MAAMC,EAAc9B,KAAKH,cAAcsB,KAAaO,IAAY,GAchE,MAAO,IACFd,KAbS,MAAZiB,EAAK,GACDC,EACAD,EAAKlB,QACH,CAACoB,EAAGC,KAAc,IACbD,UAC2BE,IAA1BH,EAAYE,GACZ,CAAEA,CAACA,GAAWF,EAAYE,IAC1B,CAAE,KAER,CAAE,GAMT,GACA,CAAE,EACN,CAKM7B,oBACLkB,EACAjB,GAEA,MAAMsB,EAAUL,EAAMM,YAChBL,WAAEA,EAAUC,UAAEA,GAAcvB,KAAKoB,gBAAgBC,GACjDa,EAAW,IAAIC,IAAIlC,OAAOC,KAAKE,GAAQ,CAAE,IAEzCgC,EAAiBnC,OAAO2B,QAAQN,GAAad,KAAI,EAAEW,EAAWU,MAClE,MAAMQ,GAAyB,MAAZR,EAAK,GAAa,IAAIK,GAAYL,GAAMlB,QAAO,CAACoB,EAAGC,IAC/DE,EAASI,IAAIN,IAIA,YAAdT,GACFW,EAASK,OAAOP,GAGX,IACFD,EACHC,CAACA,GAAW5B,IAAO4B,KATZD,GAWR,CAAE,GAECS,EAAU,IACVxC,KAAKH,cAAcsB,IAAc,CAAE,EACvCO,CAACA,GAAUW,GAIb,OAAII,EAAYzC,KAAKH,cAAcsB,KAAaO,IAAY,GAAIW,GACvD,KAGFrC,KAAKiB,IAAIuB,EAASrB,EAAU,UAG/Bd,QAAQC,IAAI8B,EACnB"}
package/types.d.ts CHANGED
@@ -123,6 +123,7 @@ interface IGroupedStores {
123
123
  globalStores: TStores;
124
124
  }
125
125
  interface IPersistOptions {
126
+ behaviour?: 'exclude' | 'include';
126
127
  attributes?: {
127
128
  [storageId: string]: string[];
128
129
  };
package/wakeup.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { TStores, TWakeup } from "./types.js";
1
+ import { IStorePersisted, TWakeup } from "./types.js";
2
2
  /**
3
3
  * Restore persisted store state
4
4
  */
5
- declare function wakeup(this: TStores[string], { initState, persistedState, manager }: Parameters<TWakeup>[0]): void;
5
+ declare function wakeup(this: IStorePersisted, { initState, persistedState, manager }: Parameters<TWakeup>[0]): void;
6
6
  export { wakeup as default };
package/wakeup.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"wakeup.js","sources":["../src/wakeup.ts"],"sourcesContent":["import deepMerge from './deep-merge';\nimport type { TStores, TWakeup } from './types';\n\n/**\n * Restore persisted store state\n */\nfunction wakeup(\n this: TStores[string],\n { initState, persistedState, manager }: Parameters<TWakeup>[0],\n) {\n const resState = {};\n\n deepMerge(resState, persistedState);\n\n const shouldSave = initState && deepMerge(resState, initState);\n\n deepMerge(this, resState);\n\n if (shouldSave) {\n void manager.savePersistedStore(this);\n }\n}\n\nexport default wakeup;\n"],"names":["wakeup","initState","persistedState","manager","resState","deepMerge","shouldSave","this","savePersistedStore"],"mappings":"+BAMA,SAASA,GAEPC,UAAEA,EAASC,eAAEA,EAAcC,QAAEA,IAE7B,MAAMC,EAAW,CAAA,EAEjBC,EAAUD,EAAUF,GAEpB,MAAMI,EAAaL,GAAaI,EAAUD,EAAUH,GAEpDI,EAAUE,KAAMH,GAEZE,GACGH,EAAQK,mBAAmBD,KAEpC"}
1
+ {"version":3,"file":"wakeup.js","sources":["../src/wakeup.ts"],"sourcesContent":["import deepMerge from './deep-merge';\nimport type { IStorePersisted, TWakeup } from './types';\n\n/**\n * Restore persisted store state\n */\nfunction wakeup(\n this: IStorePersisted,\n { initState, persistedState, manager }: Parameters<TWakeup>[0],\n) {\n const resState = {};\n\n deepMerge(resState, persistedState);\n\n const shouldSave = initState && deepMerge(resState, initState);\n\n deepMerge(this, resState);\n\n if (shouldSave) {\n void manager.savePersistedStore(this);\n }\n}\n\nexport default wakeup;\n"],"names":["wakeup","initState","persistedState","manager","resState","deepMerge","shouldSave","this","savePersistedStore"],"mappings":"+BAMA,SAASA,GAEPC,UAAEA,EAASC,eAAEA,EAAcC,QAAEA,IAE7B,MAAMC,EAAW,CAAA,EAEjBC,EAAUD,EAAUF,GAEpB,MAAMI,EAAaL,GAAaI,EAAUD,EAAUH,GAEpDI,EAAUE,KAAMH,GAEZE,GACGH,EAAQK,mBAAmBD,KAEpC"}