@lomray/react-mobx-manager 1.5.3-beta.1 → 2.0.0-beta.10

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.
package/README.md CHANGED
@@ -8,6 +8,7 @@
8
8
  - Manage your Mobx stores like a boss - debug like a hacker.
9
9
  - Simple idea - simple implementation.
10
10
  - Small package size.
11
+ - Support render to stream.
11
12
  - Support code splitting out of the box.
12
13
  - Access stores from other stores.
13
14
  - Can be a replacement for react context.
@@ -36,8 +37,8 @@
36
37
  - [Manager](#manager)
37
38
  - [withStores](#withstores)
38
39
  - [StoreManagerProvider](#storemanagerprovider)
39
- - [useStoreManagerContext](#usestoremanagercontext)
40
- - [useStoreManagerParentContext](#usestoremanagerparentcontext)
40
+ - [useStoreManagerContext](#usestoremanager)
41
+ - [useStoreManagerParentContext](#usestoremanagerparent)
41
42
  - [Store](#store)
42
43
  - [React Native Debug Plugin](#react-native-debug-plugin)
43
44
  - [Bugs and feature requests](#bugs-and-feature-requests)
@@ -252,10 +253,13 @@ const storeManager = new Manager({
252
253
  */
253
254
  shouldRemoveInitState: true,
254
255
  /**
255
- * Enable this option if your application support server-side rendering (on both side, client and server)
256
- * Default: false
256
+ * Configure store destroy timers
257
257
  */
258
- isSSR: false,
258
+ destroyTimers: {
259
+ init: 500,
260
+ touched: 10000, // NOTE: set to max request timeout
261
+ unused: 1000,
262
+ },
259
263
  }
260
264
  });
261
265
 
@@ -284,16 +288,11 @@ const store2 = storeManager.getStore(SomeStore, { contextId: 'necessary-context-
284
288
  */
285
289
  const relations = storeManager.getStoresRelations();
286
290
 
287
- /**
288
- * Generate unique context id
289
- */
290
- const contextId = storeManager.createContextId();
291
-
292
291
  /**
293
292
  * Manually create stores for component
294
293
  * NOTE: 'withStores' wrapper use this method, probably you won't need it
295
294
  */
296
- const stores = storeManager.createStores(['someStore', MyStore], 'parent-id', 'context-id', 'HomePage');
295
+ const stores = storeManager.createStores(['someStore', MyStore], 'parent-id', 'context-id', 'suspense-id', 'HomePage', { componentProp: 'test' });
297
296
 
298
297
  /**
299
298
  * Mount/Unmount simple stores to component
@@ -337,10 +336,10 @@ const storeClass = Manager.persistStore(class MyStore {}, 'my-store');
337
336
  import { withStores } from '@lomray/react-mobx-manager';
338
337
 
339
338
  /**
340
- * Create and connect 'stores' to component
339
+ * Create and connect 'stores' to component with custom context id
341
340
  * NOTE: In most cases, you don't need to pass a third argument (contextId).
342
341
  */
343
- withStores(Component, stores, 'optional-context-id');
342
+ withStores(Component, stores, { customContextId: 'optional-context-id' });
344
343
 
345
344
  const stores = { myStore: MyStore, anotherStore: AnotherStore };
346
345
  ```
@@ -360,27 +359,27 @@ import { StoreManagerProvider } from '@lomray/react-mobx-manager';
360
359
  </StoreManagerProvider>
361
360
  ```
362
361
 
363
- ### useStoreManagerContext
362
+ ### useStoreManager
364
363
  ```typescript jsx
365
- import { useStoreManagerContext } from '@lomray/react-mobx-manager';
364
+ import { useStoreManager } from '@lomray/react-mobx-manager';
366
365
 
367
366
  const MyComponent: FC = () => {
368
367
  /**
369
368
  * Get store manager inside your function component
370
369
  */
371
- const storeManager = useStoreManagerContext();
370
+ const storeManager = useStoreManager();
372
371
  }
373
372
  ```
374
373
 
375
- ### useStoreManagerParentContext
374
+ ### useStoreManagerParent
376
375
  ```typescript jsx
377
- import { useStoreManagerParentContext } from '@lomray/react-mobx-manager';
376
+ import { useStoreManagerParent } from '@lomray/react-mobx-manager';
378
377
 
379
378
  const MyComponent: FC = () => {
380
379
  /**
381
380
  * Get parent context id
382
381
  */
383
- const { parentId } = useStoreManagerParentContext();
382
+ const { parentId } = useStoreManagerParent();
384
383
  }
385
384
  ```
386
385
 
@@ -413,7 +412,7 @@ class MyStore {
413
412
  /**
414
413
  * @private
415
414
  */
416
- private someParentStore: ClassReturnType<typeof SomeParentStore>;
415
+ private readonly someParentStore: ClassReturnType<typeof SomeParentStore>;
417
416
 
418
417
  /**
419
418
  * @constructor
@@ -444,14 +443,6 @@ class MyStore {
444
443
  // do something
445
444
  }
446
445
 
447
- /**
448
- * Define this method if you want to do something when a component with this store is mount
449
- * @private
450
- */
451
- private onMount(): void {
452
- // do something
453
- }
454
-
455
446
  /**
456
447
  * Define this method if you want to do something when a component with this store is unmount
457
448
  * @private
@@ -471,6 +462,12 @@ class MyStore {
471
462
  }
472
463
  ```
473
464
 
465
+ Lifecycles:
466
+ - constructor
467
+ - wakeup (restore state from persisted store)
468
+ - init
469
+ - onDestroy
470
+
474
471
  ## React Native debug plugin
475
472
  For debug state, you can use [Reactotron debug plugin](https://github.com/Lomray-Software/reactotron-mobx-store-manager)
476
473
 
package/lib/context.d.ts CHANGED
@@ -1,16 +1,20 @@
1
1
  /// <reference types="react" />
2
+ import { IConsistentSuspense } from '@lomray/consistent-suspense';
2
3
  import React from 'react';
3
4
  import { FC, ReactElement } from "react";
4
5
  import Manager from "./manager.js";
6
+ import { TStores } from "./types-9745a837.js";
5
7
  interface IStoreManagerProvider {
6
8
  storeManager: Manager;
7
9
  shouldInit?: boolean;
8
10
  fallback?: ReactElement;
9
11
  children?: React.ReactNode;
12
+ suspenseProvider?: Partial<IConsistentSuspense>;
10
13
  }
11
14
  interface IStoreManagerParentProvider {
12
- children?: React.ReactNode;
13
15
  parentId: string;
16
+ children?: React.ReactNode;
17
+ initStores?: TStores;
14
18
  }
15
19
  /**
16
20
  * Mobx store manager context
@@ -19,7 +23,7 @@ declare const StoreManagerContext: React.Context<Manager>;
19
23
  /**
20
24
  * To spread relationships
21
25
  */
22
- declare const StoreManagerParentContext: React.Context<IStoreManagerParentProvider>;
26
+ declare const StoreManagerParentContext: React.Context<string>;
23
27
  /**
24
28
  * Mobx store manager parent provider
25
29
  * @constructor
@@ -30,6 +34,6 @@ declare const StoreManagerParentProvider: FC<Omit<IStoreManagerParentProvider, '
30
34
  * @constructor
31
35
  */
32
36
  declare const StoreManagerProvider: FC<IStoreManagerProvider>;
33
- declare const useStoreManagerContext: () => Manager;
34
- declare const useStoreManagerParentContext: () => Omit<IStoreManagerParentProvider, 'children'>;
35
- export { StoreManagerProvider, StoreManagerContext, StoreManagerParentContext, useStoreManagerContext, StoreManagerParentProvider, useStoreManagerParentContext };
37
+ declare const useStoreManager: () => Manager;
38
+ declare const useStoreManagerParent: () => IStoreManagerParentProvider['parentId'];
39
+ export { StoreManagerContext, StoreManagerParentContext, StoreManagerProvider, StoreManagerParentProvider, useStoreManager, useStoreManagerParent };
package/lib/context.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=t(e);const a=r.default.createContext({}),n=r.default.createContext({parentId:"root"}),o=({children:t,parentId:a})=>{const o=e.useMemo((()=>({parentId:a})),[a]);return r.default.createElement(n.Provider,{value:o,children:t})};exports.StoreManagerContext=a,exports.StoreManagerParentContext=n,exports.StoreManagerParentProvider=o,exports.StoreManagerProvider=({children:t,storeManager:n,fallback:u,shouldInit:s=!1})=>{const[d,l]=e.useState(!s);return e.useEffect((()=>{s&&n.init().then((()=>l(!0))).catch((e=>{console.error("Failed initialized store manager: ",e)}))}),[s,n]),r.default.createElement(a.Provider,{value:n},r.default.createElement(o,{parentId:"root"},d?t:u||t))},exports.useStoreManagerContext=()=>e.useContext(a),exports.useStoreManagerParentContext=()=>e.useContext(n);
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@lomray/consistent-suspense"),t=require("react");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=r(t);const o=n.default.createContext({}),a=n.default.createContext("root"),s=({parentId:e,children:t,initStores:r})=>{const o=u();return r&&o.touchedStores(r),n.default.createElement(a.Provider,{value:e,children:t})},u=()=>t.useContext(o);exports.StoreManagerContext=o,exports.StoreManagerParentContext=a,exports.StoreManagerParentProvider=s,exports.StoreManagerProvider=({children:r,storeManager:a,fallback:u,suspenseProvider:i={},shouldInit:l=!1})=>{const[d,c]=t.useState(!l);return t.useEffect((()=>{l&&a.init().then((()=>c(!0))).catch((e=>{console.error("Failed initialized store manager: ",e)}))}),[l,a]),n.default.createElement(e.ConsistentSuspenseProvider,{...i},n.default.createElement(o.Provider,{value:a},n.default.createElement(s,{parentId:"root"},d?r:u||r)))},exports.useStoreManager=u,exports.useStoreManagerParent=()=>t.useContext(a);
package/lib/index.d.ts CHANGED
@@ -1,9 +1,7 @@
1
- export * from "./types-c6a5e53a.js";
1
+ export * from "./types-9745a837.js";
2
2
  export * from "./context.js";
3
3
  export { default as Manager } from "./manager.js";
4
4
  export { default as onChangeListener } from "./on-change-listener.js";
5
5
  export { default as wakeup } from "./wakeup.js";
6
6
  export { default as withStores } from "./with-stores.js";
7
- export { default as MobxLocalStorage } from "./storages/local-storage.js";
8
- export { default as MobxAsyncStorage } from "./storages/async-storage.js";
9
7
  export { default as Events } from "./events.js";
package/lib/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./context.js"),r=require("./manager.js"),t=require("./on-change-listener.js"),o=require("./wakeup.js"),a=require("./with-stores.js"),s=require("./storages/local-storage.js"),n=require("./storages/async-storage.js"),x=require("./events.js");exports.StoreManagerContext=e.StoreManagerContext,exports.StoreManagerParentContext=e.StoreManagerParentContext,exports.StoreManagerParentProvider=e.StoreManagerParentProvider,exports.StoreManagerProvider=e.StoreManagerProvider,exports.useStoreManagerContext=e.useStoreManagerContext,exports.useStoreManagerParentContext=e.useStoreManagerParentContext,exports.Manager=r,exports.onChangeListener=t,exports.wakeup=o,exports.withStores=a,exports.MobxLocalStorage=s,exports.MobxAsyncStorage=n,exports.Events=x;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./context.js"),r=require("./manager.js"),t=require("./on-change-listener.js"),a=require("./wakeup.js"),o=require("./with-stores.js"),n=require("./events.js");exports.StoreManagerContext=e.StoreManagerContext,exports.StoreManagerParentContext=e.StoreManagerParentContext,exports.StoreManagerParentProvider=e.StoreManagerParentProvider,exports.StoreManagerProvider=e.StoreManagerProvider,exports.useStoreManager=e.useStoreManager,exports.useStoreManagerParent=e.useStoreManagerParent,exports.Manager=r,exports.onChangeListener=t,exports.wakeup=a,exports.withStores=o,exports.Events=n;
package/lib/manager.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { IConstructableStore, IManagerParams, IStorage, IStore, TStoreDefinition, IManagerOptions, TStores, IStoreLifecycle, TInitStore, IStoreParams } from "./types-c6a5e53a.js";
1
+ import StoreStatus from "./store-status.js";
2
+ import { IConstructableStore, IManagerOptions, IManagerParams, IStorage, IStore, IStoreParams, TInitStore, TStoreDefinition, TStores } from "./types-9745a837.js";
2
3
  /**
3
4
  * Mobx stores manager
4
5
  */
@@ -48,6 +49,11 @@ declare class Manager {
48
49
  * Manager options
49
50
  */
50
51
  readonly options: IManagerOptions;
52
+ /**
53
+ * Suspense stores relations
54
+ * @see withStores
55
+ */
56
+ protected suspenseRelations: Map<string, Set<string>>;
51
57
  /**
52
58
  * @constructor
53
59
  */
@@ -83,6 +89,13 @@ declare class Manager {
83
89
  * Get stores relations
84
90
  */
85
91
  getStoresRelations(): Manager['storesRelations'];
92
+ /**
93
+ * Get suspense relations with stores
94
+ */
95
+ /**
96
+ * Get suspense relations with stores
97
+ */
98
+ getSuspenseRelations(): Manager['suspenseRelations'];
86
99
  /**
87
100
  * Get persisted stores ids
88
101
  */
@@ -90,6 +103,11 @@ declare class Manager {
90
103
  * Get persisted stores ids
91
104
  */
92
105
  static getPersistedStoresIds(): Set<string>;
106
+ /**
107
+ * Push initial state dynamically
108
+ * E.g. when stream html
109
+ */
110
+ pushInitState: (storesState?: Record<string, any>) => void;
93
111
  /**
94
112
  * Get store identity
95
113
  * @protected
@@ -99,13 +117,6 @@ declare class Manager {
99
117
  * @protected
100
118
  */
101
119
  protected getStoreId<T>(store: IConstructableStore<T> | TInitStore, params?: IStoreParams): string;
102
- /**
103
- * Generate new context id
104
- */
105
- /**
106
- * Generate new context id
107
- */
108
- createContextId(id?: string): string;
109
120
  /**
110
121
  * Get exist store
111
122
  */
@@ -137,25 +148,21 @@ declare class Manager {
137
148
  /**
138
149
  * Create stores for component
139
150
  */
140
- createStores(map: [string, TStoreDefinition][], parentId: string, contextId: string, componentName: string, componentProps?: Record<string, any>): TStores;
151
+ createStores(map: [string, TStoreDefinition][], parentId: string, contextId: string, suspenseId: string, componentName: string, componentProps?: Record<string, any>): TStores;
141
152
  /**
142
153
  * Prepare store before usage
143
- * @protected
144
154
  */
145
155
  /**
146
156
  * Prepare store before usage
147
- * @protected
148
157
  */
149
158
  protected prepareStore(store: TStores[string]): void;
150
159
  /**
151
- * Prepare store before mount to component
152
- * @protected
160
+ * Remove store
153
161
  */
154
162
  /**
155
- * Prepare store before mount to component
156
- * @protected
163
+ * Remove store
157
164
  */
158
- protected prepareMount(store: TStores[string]): Required<IStoreLifecycle>['onDestroy'][];
165
+ protected removeStore(store: TStores[string]): void;
159
166
  /**
160
167
  * Mount stores to component
161
168
  */
@@ -163,13 +170,27 @@ declare class Manager {
163
170
  * Mount stores to component
164
171
  */
165
172
  mountStores(stores: TStores): () => void;
173
+ /**
174
+ * Change the stores status to touched
175
+ */
176
+ /**
177
+ * Change the stores status to touched
178
+ */
179
+ touchedStores(stores: TStores): void;
180
+ /**
181
+ * Change store status
182
+ */
183
+ /**
184
+ * Change store status
185
+ */
186
+ protected setStoreStatus(store: TStores[string], status: StoreStatus): void;
166
187
  /**
167
188
  * Get store's state
168
189
  */
169
190
  /**
170
191
  * Get store's state
171
192
  */
172
- toJSON(): Record<string, any>;
193
+ toJSON(ids?: string[]): Record<string, any>;
173
194
  /**
174
195
  * Get persisted store's data
175
196
  */
package/lib/manager.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("@lomray/event-manager"),t=require("mobx"),s=require("./events.js"),r=require("./on-change-listener.js"),o=require("./wakeup.js");function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=i(e);class a{constructor({initState:e,storesParams:t,storage:s,options:r}={}){Object.defineProperty(this,"stores",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"storesRelations",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"initState",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"storage",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"persistData",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"storesParams",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"options",{enumerable:!0,configurable:!0,writable:!0,value:{shouldDisablePersist:!1,shouldRemoveInitState:!0,isSSR:!1}}),this.initState=e||{},this.storesParams=t||{},this.storage=s,Object.assign(this.options,r||{}),a.instance=this}async init(){return this.storage&&(this.persistData=await this.storage.get()||{}),this}static get(){if(!a.instance)throw new Error("Store manager is not initialized.");return a.instance}getStores(){return this.stores}getStoresRelations(){return this.storesRelations}static getPersistedStoresIds(){return a.persistedStores}getStoreId(e,t={}){const{id:s,contextId:r,key:o}=t;if(s)return s;if(e.libStoreId)return e.libStoreId;let i=e.name||e.constructor.name;return e.isSingleton?i:(i=`${i}--${r}`,o?`${i}--${o}`:i)}createContextId(e){return`ctx${e||this.storesRelations.size+1}`}getStore(e,t={}){const s=this.getStoreId(e,t);return this.stores.has(s)?this.stores.get(s):e.isSingleton?this.createStore(e,{id:s,contextId:"singleton",parentId:"root",componentName:"root-app",componentProps:{}}):this.lookupStore(s,t)}lookupStore(e,t){var s,r;const{contextId:o,parentId:i}=t,n=null===(s=e.split("--"))||void 0===s?void 0:s[0],{ids:a,parentId:l}=null!==(r=this.storesRelations.get(o))&&void 0!==r?r:{ids:new Set,parentId:i},d=[...a].filter((e=>e.startsWith(`${n}--`)));if(1===d.length)return this.stores.get(d[0]);if(d.length>1)console.error("Parent context has multiple stores with the same id, please pass key to getStore function.");else if(l&&"root"!==l)return this.lookupStore(e,{contextId:l})}createStore(e,t){var r,o;const{isSSR:i}=this.options,{id:l,contextId:d,parentId:u,componentName:p,componentProps:c}=t;if((e.isSingleton||i)&&this.stores.has(l))return this.stores.get(l);const h=new e({...this.storesParams,storeManager:this,getStore:(e,t={contextId:d,parentId:u})=>this.getStore(e,t),componentProps:c});h.libStoreId=l,h.isSingleton=e.isSingleton,h.libStoreContextId=e.isSingleton?"singleton":d,h.libStoreParentId=e.isSingleton||!u||u===d?"root":u,h.libStoreComponentName=p;const S=this.initState[l],b=this.persistData[l];return S&&Object.assign(h,S),n.default.publish(s.CREATE_STORE,{store:e}),"wakeup"in h&&a.persistedStores.has(l)&&(null===(r=h.wakeup)||void 0===r||r.call(h,h,{initState:S,persistedState:b})),null===(o=h.init)||void 0===o||o.call(h),this.prepareStore(h),(h.isSingleton||i)&&this.prepareMount(h),h}createStores(e,t,s,r,o={}){return e.reduce(((e,[i,n])=>{const[a,l]="store"in n?[n.store,n.id]:[n,this.getStoreId(n,{key:i,contextId:s})];return{...e,[i]:this.createStore(a,{id:l,contextId:s,parentId:t,componentName:r,componentProps:o})}}),{})}prepareStore(e){const t=e.libStoreId,r=e.libStoreContextId;this.storesRelations.has(r)||this.storesRelations.set(r,{ids:new Set,parentId:e.libStoreParentId&&e.libStoreParentId!==r?e.libStoreParentId:"root",componentName:e.libStoreComponentName});const{ids:o}=this.storesRelations.get(r);this.stores.has(t)||(this.stores.set(t,e),o.add(t),n.default.publish(s.ADD_STORE,{store:e}))}prepareMount(e){const{shouldRemoveInitState:t}=this.options,s=e.libStoreId,r=[];return a.persistedStores.has(s)&&"addOnChangeListener"in e&&r.push(e.addOnChangeListener(e,this)),t&&this.initState[s]&&delete this.initState[s],r}mountStores(e){const t=[];return Object.values(e).forEach((e=>{var r;if(t.push(...this.prepareMount(e)),n.default.publish(s.MOUNT_STORE,{store:e}),"onMount"in e){const s=null===(r=e.onMount)||void 0===r?void 0:r.call(e);"function"==typeof s&&t.push(s)}"onDestroy"in e&&t.push((()=>{var t;return null===(t=e.onDestroy)||void 0===t?void 0:t.call(e)}))})),()=>{t.forEach((e=>e())),Object.values(e).forEach((e=>{var t;const r=e.libStoreId;if(n.default.publish(s.UNMOUNT_STORE,{store:e}),!e.isSingleton){const{ids:o}=null!==(t=this.storesRelations.get(e.libStoreContextId))&&void 0!==t?t:{ids:new Set};this.stores.delete(r),o.delete(r),n.default.publish(s.DELETE_STORE,{store:e}),o.size||this.storesRelations.delete(e.libStoreContextId)}}))}}toJSON(){var e,t;const s={};for(const[r,o]of this.stores.entries())s[r]=null!==(t=null===(e=o.toJSON)||void 0===e?void 0:e.call(o))&&void 0!==t?t:a.getObservableProps(o);return s}toPersistedJSON(){var e,t;const s={};for(const r of a.persistedStores){const o=this.stores.get(r);o&&(s[r]=null!==(t=null===(e=o.toJSON)||void 0===e?void 0:e.call(o))&&void 0!==t?t:a.getObservableProps(o))}return s}static getObservableProps(e){const s=t.toJS(e);return Object.entries(s).reduce(((s,[r,o])=>({...s,...t.isObservableProp(e,r)?{[r]:o}:{}})),{})}static persistStore(e,t){return a.persistedStores.has(t)?(console.warn(`Duplicate serializable store key: ${t}`),e):(a.persistedStores.add(t),e.libStoreId=t,"wakeup"in e.prototype||(e.prototype.wakeup=o),"addOnChangeListener"in e.prototype||(e.prototype.addOnChangeListener=r),e)}}Object.defineProperty(a,"persistedStores",{enumerable:!0,configurable:!0,writable:!0,value:new Set}),module.exports=a;
1
+ "use strict";var e=require("@lomray/event-manager"),t=require("mobx"),s=require("./events.js"),o=require("./on-change-listener.js"),r=require("./store-status.js"),i=require("./wakeup.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=n(e);class l{constructor({initState:e,storesParams:t,storage:s,options:o}={}){Object.defineProperty(this,"stores",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"storesRelations",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"initState",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"storage",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"persistData",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"storesParams",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"options",{enumerable:!0,configurable:!0,writable:!0,value:{shouldDisablePersist:!1,shouldRemoveInitState:!0}}),Object.defineProperty(this,"suspenseRelations",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"pushInitState",{enumerable:!0,configurable:!0,writable:!0,value:(e={})=>{for(const[t,s]of Object.entries(e))this.initState[t]=s}}),this.initState=e||{},this.storesParams=t||{},this.storage=s,Object.assign(this.options,o||{}),l.instance=this,"undefined"==typeof window||window.mobxManager||(window.mobxManager={pushInit:this.pushInitState})}async init(){return this.storage&&(this.persistData=await this.storage.get()||{}),this}static get(){if(!l.instance)throw new Error("Store manager is not initialized.");return l.instance}getStores(){return this.stores}getStoresRelations(){return this.storesRelations}getSuspenseRelations(){return this.suspenseRelations}static getPersistedStoresIds(){return l.persistedStores}getStoreId(e,t={}){const{id:s,contextId:o,key:r}=t;if(s)return s;if(e.libStoreId)return e.libStoreId;let i=e.name||e.constructor.name;return e.isSingleton?i:(i=`${i}--${o}`,r?`${i}--${r}`:i)}getStore(e,t={}){const s=this.getStoreId(e,t);return this.stores.has(s)?this.stores.get(s):e.isSingleton?this.createStore(e,{id:s,contextId:"singleton",parentId:"root",suspenseId:"",componentName:"root-app",componentProps:{}}):this.lookupStore(s,t)}lookupStore(e,t){var s,o;const{contextId:r,parentId:i}=t,n=null===(s=e.split("--"))||void 0===s?void 0:s[0],{ids:a,parentId:l}=null!==(o=this.storesRelations.get(r))&&void 0!==o?o:{ids:new Set,parentId:i},u=[...a].filter((e=>e.startsWith(`${n}--`)));if(1===u.length)return this.stores.get(u[0]);if(u.length>1)console.error("Parent context has multiple stores with the same id, please pass key to getStore function.");else if(l&&"root"!==l)return this.lookupStore(e,{contextId:l})}createStore(e,t){const{id:o,contextId:i,parentId:n,suspenseId:l,componentName:u,componentProps:d}=t;if(this.stores.has(o))return this.stores.get(o);const h=new e({...this.storesParams,storeManager:this,getStore:(e,t={contextId:i,parentId:n})=>this.getStore(e,t),componentProps:d});return h.libStoreId=o,h.isSingleton=e.isSingleton,h.libStoreContextId=e.isSingleton?"singleton":i,h.libStoreParentId=e.isSingleton||!n||n===i?"root":n,h.libStoreSuspenseId=l,h.libStoreComponentName=u,this.setStoreStatus(h,e.isSingleton?r.inUse:r.init),this.prepareStore(h),a.default.publish(s.CREATE_STORE,{store:e}),h}createStores(e,t,s,o,r,i={}){return e.reduce(((e,[n,a])=>{const[l,u]="store"in a?[a.store,a.id]:[a,this.getStoreId(a,{key:n,contextId:s})];return{...e,[n]:this.createStore(l,{id:u,contextId:s,parentId:t,suspenseId:o,componentName:r,componentProps:i})}}),{})}prepareStore(e){var t,o,r;const i=e.libStoreId,n=e.libStoreContextId,u=e.libStoreSuspenseId,d=this.initState[i],h=this.persistData[i];if(this.stores.has(i))return;if(d&&Object.assign(e,d),"wakeup"in e&&l.persistedStores.has(i)&&(null===(t=e.wakeup)||void 0===t||t.call(e,{initState:d,persistedState:h})),l.persistedStores.has(i)&&"addOnChangeListener"in e){const t=null===(o=e.onDestroy)||void 0===o?void 0:o.bind(e),s=e.addOnChangeListener(e,this);e.onDestroy=()=>{null==s||s(),null==t||t()}}null===(r=e.init)||void 0===r||r.call(e),this.storesRelations.has(n)||this.storesRelations.set(n,{ids:new Set,parentId:e.libStoreParentId&&e.libStoreParentId!==n?e.libStoreParentId:"root",componentName:e.libStoreComponentName}),this.suspenseRelations.has(u)||this.suspenseRelations.set(u,new Set);const{ids:c}=this.storesRelations.get(n);this.stores.set(i,e),c.add(i),this.suspenseRelations.get(u).add(i),a.default.publish(s.ADD_STORE,{store:e})}removeStore(e){var t,o,r;const i=e.libStoreId,n=e.libStoreSuspenseId,{ids:l}=null!==(t=this.storesRelations.get(e.libStoreContextId))&&void 0!==t?t:{ids:new Set};this.stores.has(i)&&(this.stores.delete(i),l.delete(i),n&&(null===(o=this.suspenseRelations.get(n))||void 0===o?void 0:o.has(i))&&this.suspenseRelations.get(n).delete(i),l.size||this.storesRelations.delete(e.libStoreContextId),"onDestroy"in e&&(null===(r=e.onDestroy)||void 0===r||r.call(e)),a.default.publish(s.DELETE_STORE,{store:e}))}mountStores(e){const{shouldRemoveInitState:t}=this.options;return Object.values(e).forEach((e=>{const o=e.libStoreId;t&&this.initState[o]&&delete this.initState[o],this.setStoreStatus(e,r.inUse),a.default.publish(s.MOUNT_STORE,{store:e})})),()=>{Object.values(e).forEach((e=>{e.isSingleton||(this.setStoreStatus(e,r.unused),a.default.publish(s.UNMOUNT_STORE,{store:e}))}))}}touchedStores(e){Object.values(e).forEach((e=>{e.libStoreStatus!==r.init||e.isSingleton||this.setStoreStatus(e,r.touched)}))}setStoreStatus(e,t){const{destroyTimers:{init:s=500,touched:o=1e4,unused:i=1e3}={}}=this.options;e.libStoreStatus=t,clearTimeout(e.libDestroyTimer);let n=0;switch(t){case r.init:n=s;break;case r.touched:n=o;break;case r.unused:n=i}n&&(e.libDestroyTimer=setTimeout((()=>this.removeStore(e)),n))}toJSON(e){var t,s,o;const r={},i=null!==(t=null==e?void 0:e.reduce(((e,t)=>(this.stores.has(t)&&e.set(t,this.stores.get(t)),e)),new Map))&&void 0!==t?t:this.stores;for(const[e,t]of i.entries())r[e]=null!==(o=null===(s=t.toJSON)||void 0===s?void 0:s.call(t))&&void 0!==o?o:l.getObservableProps(t);return r}toPersistedJSON(){var e,t;const s={};for(const o of l.persistedStores){const r=this.stores.get(o);r&&(s[o]=null!==(t=null===(e=r.toJSON)||void 0===e?void 0:e.call(r))&&void 0!==t?t:l.getObservableProps(r))}return s}static getObservableProps(e){const s=t.toJS(e);return Object.entries(s).reduce(((s,[o,r])=>({...s,...t.isObservableProp(e,o)?{[o]:r}:{}})),{})}static persistStore(e,t){return l.persistedStores.has(t)?(console.warn(`Duplicate serializable store key: ${t}`),e):(l.persistedStores.add(t),e.libStoreId=t,"wakeup"in e.prototype||(e.prototype.wakeup=i.bind(e)),"addOnChangeListener"in e.prototype||(e.prototype.addOnChangeListener=o),e)}}Object.defineProperty(l,"persistedStores",{enumerable:!0,configurable:!0,writable:!0,value:new Set}),module.exports=l;
@@ -1,4 +1,4 @@
1
- import { IStorePersisted } from "./types-c6a5e53a.js";
1
+ import { IStorePersisted } from "./types-9745a837.js";
2
2
  /**
3
3
  * Listen persist store changes
4
4
  */
@@ -1,4 +1,4 @@
1
- import { IStorage } from "../types-c6a5e53a.js";
1
+ import { IStorage } from "../types-9745a837.js";
2
2
  interface IAsyncStorage {
3
3
  getItem: (key: string) => Promise<string | null>;
4
4
  setItem: (key: string, value: string) => Promise<void>;
@@ -1,4 +1,4 @@
1
- import { IStorage } from "../types-c6a5e53a.js";
1
+ import { IStorage } from "../types-9745a837.js";
2
2
  /**
3
3
  * Local storage for mobx store manager
4
4
  */
@@ -0,0 +1,7 @@
1
+ declare enum StoreStatus {
2
+ init = "init",
3
+ touched = "touched",
4
+ inUse = "in-use",
5
+ unused = "unused"
6
+ }
7
+ export { StoreStatus as default };
@@ -0,0 +1 @@
1
+ "use strict";var u;!function(u){u.init="init",u.touched="touched",u.inUse="in-use",u.unused="unused"}(u||(u={}));var e=u;module.exports=e;
@@ -0,0 +1,50 @@
1
+ import { TInitStore } from "./types-9745a837.js";
2
+ interface IPromise<TReturn> extends Promise<TReturn> {
3
+ status?: 'fulfilled' | 'pending' | 'rejected';
4
+ value?: TReturn;
5
+ reason?: any;
6
+ }
7
+ interface ISuspenseQueryParams {
8
+ fieldName?: string;
9
+ }
10
+ /**
11
+ * Run request and cache promise
12
+ * Sync suspense status between server and client
13
+ */
14
+ declare class SuspenseQuery {
15
+ /**
16
+ * @private
17
+ */
18
+ protected promise: Promise<any> | undefined;
19
+ /**
20
+ * @private
21
+ */
22
+ protected error?: Error;
23
+ /**
24
+ * Target store
25
+ * @private
26
+ */
27
+ protected readonly store: TInitStore;
28
+ /**
29
+ * @protected
30
+ */
31
+ protected readonly params: Required<ISuspenseQueryParams>;
32
+ /**
33
+ * @constructor
34
+ */
35
+ /**
36
+ * @constructor
37
+ */
38
+ constructor(store: TInitStore, { fieldName, ...rest }?: ISuspenseQueryParams);
39
+ /**
40
+ * Run request
41
+ * Save request resolve status
42
+ */
43
+ query: <TReturn>(promise: () => Promise<TReturn>) => TReturn | undefined;
44
+ /**
45
+ * Change status of promise.
46
+ * Throw promise to react suspense
47
+ */
48
+ static run: <TReturn>(promise: IPromise<TReturn> | undefined) => TReturn | undefined;
49
+ }
50
+ export { SuspenseQuery as default };
@@ -0,0 +1 @@
1
+ "use strict";var e=require("mobx");class r{constructor(t,{fieldName:i="isSuspenseDone",...s}={}){Object.defineProperty(this,"promise",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"error",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"store",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"params",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"query",{enumerable:!0,configurable:!0,writable:!0,value:t=>{const{fieldName:i}=this.params;if(!this.store[i])return this.promise||(this.promise=t(),this.promise.then((()=>{e.runInAction((()=>{this.store[i]=!0}))}),(r=>{e.runInAction((()=>{this.store[i]=!0,this.error=r}))}))),r.run(this.promise)}}),this.store=t,this.params={...s,fieldName:i},e.extendObservable(t,{[i]:!1},{[i]:e.observable})}}Object.defineProperty(r,"run",{enumerable:!0,configurable:!0,writable:!0,value:e=>{if(e){switch(e.status){case"fulfilled":return e.value;case"pending":throw e;case"rejected":throw e.reason;default:e.status="pending",e.then((r=>{e.status="fulfilled",e.value=r}),(r=>{e.status="rejected",e.reason=r}))}throw e}}}),module.exports=r;
@@ -1,4 +1,14 @@
1
+ /// <reference types="node" />
1
2
  import Manager from "./manager.js";
3
+ import StoreStatus from "./store-status.js";
4
+ interface IWindowManager {
5
+ pushInit: (state: Record<string, any>) => void;
6
+ }
7
+ declare global {
8
+ interface Window {
9
+ mobxManager: IWindowManager;
10
+ }
11
+ }
2
12
  interface IConstructorParams<TProps = Record<string, any>> {
3
13
  storeManager: Manager;
4
14
  getStore: <T>(store: IConstructableStore<T>, params?: Partial<IStoreParams>) => T | undefined;
@@ -6,13 +16,15 @@ interface IConstructorParams<TProps = Record<string, any>> {
6
16
  }
7
17
  interface IStoreLifecycle {
8
18
  onDestroy?: () => void;
9
- onMount?: () => void | (() => void);
10
19
  }
11
20
  interface IStore extends IStoreLifecycle {
12
21
  libStoreId?: string;
13
22
  libStoreContextId?: string;
14
23
  libStoreParentId?: string;
24
+ libStoreSuspenseId?: string;
15
25
  libStoreComponentName?: string;
26
+ libStoreStatus?: StoreStatus;
27
+ libDestroyTimer?: NodeJS.Timeout;
16
28
  isSingleton?: boolean;
17
29
  init?: () => void;
18
30
  toJSON?: () => Record<string, any>;
@@ -39,7 +51,7 @@ interface IManagerParams {
39
51
  options?: IManagerOptions;
40
52
  initState?: Record<string, any>;
41
53
  }
42
- type TWakeup = (store: IStore, state: {
54
+ type TWakeup = (state: {
43
55
  initState?: Record<string, any>;
44
56
  persistedState?: Record<string, any>;
45
57
  }) => void;
@@ -51,7 +63,11 @@ interface IStorage {
51
63
  interface IManagerOptions {
52
64
  shouldDisablePersist?: boolean;
53
65
  shouldRemoveInitState?: boolean;
54
- isSSR?: boolean;
66
+ destroyTimers?: {
67
+ init?: number;
68
+ touched?: number;
69
+ unused?: number;
70
+ };
55
71
  }
56
72
  type TStores = {
57
73
  [storeKey: string]: IStore | IStorePersisted;
@@ -73,7 +89,11 @@ interface IStoreParams {
73
89
  key?: string;
74
90
  contextId?: string;
75
91
  parentId?: string;
92
+ suspenseId?: string;
76
93
  componentName?: string;
77
94
  componentProps?: Record<string, any>;
78
95
  }
79
- export { IConstructorParams, IStoreLifecycle, IStore, IStorePersisted, TInitStore, IConstructableStore, IStoreConfig, TStoreDefinition, TMapStores, IManagerParams, TWakeup, IStorage, IManagerOptions, TStores, ClassReturnType, StoresType, IStoreParams };
96
+ interface IWithStoreOptions {
97
+ customContextId?: string;
98
+ }
99
+ export { IWindowManager, IConstructorParams, IStoreLifecycle, IStore, IStorePersisted, TInitStore, IConstructableStore, IStoreConfig, TStoreDefinition, TMapStores, IManagerParams, TWakeup, IStorage, IManagerOptions, TStores, ClassReturnType, StoresType, IStoreParams, IWithStoreOptions };
package/lib/wakeup.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { IStorePersisted } from "./types-c6a5e53a.js";
1
+ import { TStores, TWakeup } from "./types-9745a837.js";
2
2
  /**
3
- * Restore store state from initial state
3
+ * Restore persisted store state
4
4
  */
5
- declare const wakeup: IStorePersisted['wakeup'];
5
+ declare function wakeup(this: TStores[string], { persistedState }: Parameters<TWakeup>[0]): void;
6
6
  export { wakeup as default };
package/lib/wakeup.js CHANGED
@@ -1 +1 @@
1
- "use strict";module.exports=(e,{persistedState:s})=>{s&&Object.assign(e,s)};
1
+ "use strict";module.exports=function({persistedState:t}){t&&Object.assign(this,t)};
@@ -1,7 +1,7 @@
1
1
  import { FC } from 'react';
2
- import { TMapStores } from "./types-c6a5e53a.js";
2
+ import { TMapStores, IWithStoreOptions } from "./types-9745a837.js";
3
3
  /**
4
4
  * Make component observable and pass stores as props
5
5
  */
6
- declare const withStores: <T extends Record<string, any>, TS extends TMapStores>(Component: FC<T>, stores: TS, customContextId?: string) => FC<Omit<T, keyof TS>>;
6
+ declare const withStores: <T extends Record<string, any>, TS extends TMapStores>(Component: FC<T>, stores: TS, { customContextId }?: IWithStoreOptions) => FC<Omit<T, keyof TS>>;
7
7
  export { withStores as default };
@@ -1 +1 @@
1
- "use strict";var e=require("hoist-non-react-statics"),t=require("mobx-react-lite"),r=require("react"),a=require("./context.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=n(e),u=n(r);module.exports=(e,n,s)=>{const i=t.observer(e),c=s||e.libStoreContextId,d=e.displayName||e.name,l=({...e})=>{var t;const o=a.useStoreManagerContext(),{parentId:s}=a.useStoreManagerParentContext(),l=null===(t=u.default.useId)||void 0===t?void 0:t.call(u.default),[{contextId:f,initStores:x}]=r.useState((()=>{const t=o.createContextId(c||l);return{contextId:t,initStores:o.createStores(Object.entries(n),s,t,d,e)}}));return r.useEffect((()=>o.mountStores(x)),[x,o]),u.default.createElement(a.StoreManagerParentProvider,{parentId:f},u.default.createElement(i,{...x,...e}))};return o.default(l,e),l.displayName=`Mobx(${d})`,l};
1
+ "use strict";var e=require("@lomray/consistent-suspense"),t=require("hoist-non-react-statics"),r=require("mobx-react-lite"),n=require("react"),s=require("./context.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=o(t),u=o(n);module.exports=(t,o,{customContextId:i}={})=>{const c=r.observer(t),d=i||t.libStoreContextId,l=t.displayName||t.name,m=t=>{const r=s.useStoreManager(),a=s.useStoreManagerParent(),{suspenseId:i}=e.useConsistentSuspense(),m=e.useId(),[{contextId:S,initStores:f,mountStores:p}]=n.useState((()=>{const e=d||m;return{contextId:e,initStores:r.createStores(Object.entries(o),a,e,i,l,t),mountStores:()=>r.mountStores(f)}}));return n.useEffect(p,[p]),u.default.createElement(s.StoreManagerParentProvider,{parentId:S,initStores:f},u.default.createElement(c,{...t,...f}))};return a.default(m,t),m.displayName=`Mobx(${l})`,Object.defineProperty(m,"name",{value:m.displayName,writable:!1,enumerable:!1})};
package/package.json CHANGED
@@ -1,9 +1,21 @@
1
1
  {
2
2
  "name": "@lomray/react-mobx-manager",
3
- "version": "1.5.3-beta.1",
3
+ "version": "2.0.0-beta.10",
4
4
  "description": "This package provides Mobx stores manager for react.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
+ "exports": {
8
+ ".": "./lib/index.js",
9
+ "./*": "./lib/*.js"
10
+ },
11
+ "typesVersions": {
12
+ "*": {
13
+ "./*": [
14
+ "lib/*",
15
+ "lib/storages/*"
16
+ ]
17
+ }
18
+ },
7
19
  "repository": {
8
20
  "type": "git",
9
21
  "url": "https://github.com/Lomray-Software/react-mobx-manager"
@@ -38,9 +50,13 @@
38
50
  "ts:check": "tsc --project ./tsconfig.checks.json --skipLibCheck --noemit",
39
51
  "prepare": "husky install"
40
52
  },
53
+ "dependencies": {
54
+ "@lomray/consistent-suspense": "^1.2.2",
55
+ "@lomray/event-manager": "^1.2.2"
56
+ },
41
57
  "devDependencies": {
42
- "@commitlint/cli": "^17.6.3",
43
- "@commitlint/config-conventional": "^17.6.3",
58
+ "@commitlint/cli": "^17.6.6",
59
+ "@commitlint/config-conventional": "^17.6.6",
44
60
  "@lomray/eslint-config-react": "^3.0.0",
45
61
  "@lomray/prettier-config": "^1.2.0",
46
62
  "@rollup/plugin-terser": "^0.4.3",
@@ -64,8 +80,5 @@
64
80
  "mobx": "^6.9.0",
65
81
  "mobx-react-lite": "^3.4.3",
66
82
  "react": "^18 || ^17"
67
- },
68
- "dependencies": {
69
- "@lomray/event-manager": "^1.2.1"
70
83
  }
71
84
  }
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- 18.13.0
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "include": [
4
- "src/**/*"
5
- ]
6
- }