@lomray/react-mobx-manager 2.0.0-beta.1 → 2.0.0-beta.11
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 +32 -34
- package/lib/context.d.ts +5 -17
- package/lib/context.js +1 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.js +1 -1
- package/lib/manager.d.ts +32 -16
- package/lib/manager.js +1 -1
- package/lib/on-change-listener.d.ts +1 -1
- package/lib/storages/async-storage.d.ts +1 -1
- package/lib/storages/local-storage.d.ts +1 -1
- package/lib/store-status.d.ts +7 -0
- package/lib/store-status.js +1 -0
- package/lib/suspense-query.d.ts +1 -1
- package/lib/suspense-query.js +1 -1
- package/lib/{types-abd34741.d.ts → types-9745a837.d.ts} +12 -3
- package/lib/wakeup.d.ts +3 -3
- package/lib/wakeup.js +1 -1
- package/lib/with-stores.d.ts +1 -1
- package/lib/with-stores.js +1 -1
- package/package.json +16 -4
- package/.nvmrc +0 -1
- package/lib/mobx-suspense.d.ts +0 -8
- package/lib/mobx-suspense.js +0 -1
- package/lib/stream-stores.d.ts +0 -72
- package/lib/stream-stores.js +0 -1
- package/tsconfig.checks.json +0 -6
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<h1 align='center'>Mobx stores manager for React</h1>
|
|
6
6
|
|
|
7
7
|
- One way to escape state tree 🌲🌳🌴.
|
|
8
|
+
- Ready to use with Suspense.
|
|
8
9
|
- Manage your Mobx stores like a boss - debug like a hacker.
|
|
9
10
|
- Simple idea - simple implementation.
|
|
10
11
|
- Small package size.
|
|
@@ -37,8 +38,8 @@
|
|
|
37
38
|
- [Manager](#manager)
|
|
38
39
|
- [withStores](#withstores)
|
|
39
40
|
- [StoreManagerProvider](#storemanagerprovider)
|
|
40
|
-
- [useStoreManagerContext](#
|
|
41
|
-
- [useStoreManagerParentContext](#
|
|
41
|
+
- [useStoreManagerContext](#usestoremanager)
|
|
42
|
+
- [useStoreManagerParentContext](#usestoremanagerparent)
|
|
42
43
|
- [Store](#store)
|
|
43
44
|
- [React Native Debug Plugin](#react-native-debug-plugin)
|
|
44
45
|
- [Bugs and feature requests](#bugs-and-feature-requests)
|
|
@@ -52,6 +53,8 @@ The React-mobx-manager package is distributed using [npm](https://www.npmjs.com/
|
|
|
52
53
|
npm i --save @lomray/react-mobx-manager
|
|
53
54
|
```
|
|
54
55
|
|
|
56
|
+
__WARNING:__ this package use [@lomray/consistent-suspense](https://github.com/Lomray-Software/consistent-suspense) for generate stable id's inside Suspense.
|
|
57
|
+
|
|
55
58
|
**Optional:** Configure your bundler to keep classnames and function names in production OR use `id` for each store:
|
|
56
59
|
|
|
57
60
|
- **React:** (craco or webpack config, terser options)
|
|
@@ -77,24 +80,27 @@ Import `Manager, StoreManagerProvider` from `@lomray/react-mobx-manager` into yo
|
|
|
77
80
|
```typescript jsx
|
|
78
81
|
import React from 'react';
|
|
79
82
|
import ReactDOM from 'react-dom/client';
|
|
80
|
-
import '
|
|
83
|
+
import { ConsistentSuspenseProvider } from '@lomray/consistent-suspense';
|
|
81
84
|
import { Manager, StoreManagerProvider, MobxLocalStorage } from '@lomray/react-mobx-manager';
|
|
82
85
|
import App from './app';
|
|
83
86
|
import MyApiClient from './services/my-api-client';
|
|
87
|
+
import './index.css';
|
|
84
88
|
|
|
85
89
|
const apiClient = new MyApiClient();
|
|
86
90
|
const storeManager = new Manager({
|
|
87
91
|
storage: new MobxLocalStorage(), // optional: needs for persisting stores
|
|
88
|
-
storesParams: { apiClient }, // optional: we can provide our api client for access from the store
|
|
92
|
+
storesParams: { apiClient }, // optional: we can provide our api client for access from the each store
|
|
89
93
|
});
|
|
90
94
|
|
|
91
95
|
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
|
|
92
96
|
|
|
93
97
|
root.render(
|
|
94
98
|
<React.StrictMode>
|
|
95
|
-
<
|
|
96
|
-
<
|
|
97
|
-
|
|
99
|
+
<ConsistentSuspenseProvider> {/** required, see warning above **/}
|
|
100
|
+
<StoreManagerProvider storeManager={storeManager} shouldInit>
|
|
101
|
+
<App />
|
|
102
|
+
</StoreManagerProvider>
|
|
103
|
+
</ConsistentSuspenseProvider>
|
|
98
104
|
</React.StrictMode>,
|
|
99
105
|
);
|
|
100
106
|
```
|
|
@@ -253,10 +259,13 @@ const storeManager = new Manager({
|
|
|
253
259
|
*/
|
|
254
260
|
shouldRemoveInitState: true,
|
|
255
261
|
/**
|
|
256
|
-
*
|
|
257
|
-
* Default: false
|
|
262
|
+
* Configure store destroy timers
|
|
258
263
|
*/
|
|
259
|
-
|
|
264
|
+
destroyTimers: {
|
|
265
|
+
init: 500,
|
|
266
|
+
touched: 10000, // NOTE: set to max request timeout
|
|
267
|
+
unused: 1000,
|
|
268
|
+
},
|
|
260
269
|
}
|
|
261
270
|
});
|
|
262
271
|
|
|
@@ -285,16 +294,11 @@ const store2 = storeManager.getStore(SomeStore, { contextId: 'necessary-context-
|
|
|
285
294
|
*/
|
|
286
295
|
const relations = storeManager.getStoresRelations();
|
|
287
296
|
|
|
288
|
-
/**
|
|
289
|
-
* Generate unique context id
|
|
290
|
-
*/
|
|
291
|
-
const contextId = storeManager.createContextId();
|
|
292
|
-
|
|
293
297
|
/**
|
|
294
298
|
* Manually create stores for component
|
|
295
299
|
* NOTE: 'withStores' wrapper use this method, probably you won't need it
|
|
296
300
|
*/
|
|
297
|
-
const stores = storeManager.createStores(['someStore', MyStore], 'parent-id', 'context-id', 'HomePage');
|
|
301
|
+
const stores = storeManager.createStores(['someStore', MyStore], 'parent-id', 'context-id', 'suspense-id', 'HomePage', { componentProp: 'test' });
|
|
298
302
|
|
|
299
303
|
/**
|
|
300
304
|
* Mount/Unmount simple stores to component
|
|
@@ -338,10 +342,10 @@ const storeClass = Manager.persistStore(class MyStore {}, 'my-store');
|
|
|
338
342
|
import { withStores } from '@lomray/react-mobx-manager';
|
|
339
343
|
|
|
340
344
|
/**
|
|
341
|
-
* Create and connect 'stores' to component
|
|
345
|
+
* Create and connect 'stores' to component with custom context id
|
|
342
346
|
* NOTE: In most cases, you don't need to pass a third argument (contextId).
|
|
343
347
|
*/
|
|
344
|
-
withStores(Component, stores, 'optional-context-id');
|
|
348
|
+
withStores(Component, stores, { customContextId: 'optional-context-id' });
|
|
345
349
|
|
|
346
350
|
const stores = { myStore: MyStore, anotherStore: AnotherStore };
|
|
347
351
|
```
|
|
@@ -361,27 +365,27 @@ import { StoreManagerProvider } from '@lomray/react-mobx-manager';
|
|
|
361
365
|
</StoreManagerProvider>
|
|
362
366
|
```
|
|
363
367
|
|
|
364
|
-
###
|
|
368
|
+
### useStoreManager
|
|
365
369
|
```typescript jsx
|
|
366
|
-
import {
|
|
370
|
+
import { useStoreManager } from '@lomray/react-mobx-manager';
|
|
367
371
|
|
|
368
372
|
const MyComponent: FC = () => {
|
|
369
373
|
/**
|
|
370
374
|
* Get store manager inside your function component
|
|
371
375
|
*/
|
|
372
|
-
const storeManager =
|
|
376
|
+
const storeManager = useStoreManager();
|
|
373
377
|
}
|
|
374
378
|
```
|
|
375
379
|
|
|
376
|
-
###
|
|
380
|
+
### useStoreManagerParent
|
|
377
381
|
```typescript jsx
|
|
378
|
-
import {
|
|
382
|
+
import { useStoreManagerParent } from '@lomray/react-mobx-manager';
|
|
379
383
|
|
|
380
384
|
const MyComponent: FC = () => {
|
|
381
385
|
/**
|
|
382
386
|
* Get parent context id
|
|
383
387
|
*/
|
|
384
|
-
const { parentId } =
|
|
388
|
+
const { parentId } = useStoreManagerParent();
|
|
385
389
|
}
|
|
386
390
|
```
|
|
387
391
|
|
|
@@ -414,7 +418,7 @@ class MyStore {
|
|
|
414
418
|
/**
|
|
415
419
|
* @private
|
|
416
420
|
*/
|
|
417
|
-
private someParentStore: ClassReturnType<typeof SomeParentStore>;
|
|
421
|
+
private readonly someParentStore: ClassReturnType<typeof SomeParentStore>;
|
|
418
422
|
|
|
419
423
|
/**
|
|
420
424
|
* @constructor
|
|
@@ -445,14 +449,6 @@ class MyStore {
|
|
|
445
449
|
// do something
|
|
446
450
|
}
|
|
447
451
|
|
|
448
|
-
/**
|
|
449
|
-
* Define this method if you want to do something when a component with this store is mount
|
|
450
|
-
* @private
|
|
451
|
-
*/
|
|
452
|
-
private onMount(): void {
|
|
453
|
-
// do something
|
|
454
|
-
}
|
|
455
|
-
|
|
456
452
|
/**
|
|
457
453
|
* Define this method if you want to do something when a component with this store is unmount
|
|
458
454
|
* @private
|
|
@@ -476,9 +472,11 @@ Lifecycles:
|
|
|
476
472
|
- constructor
|
|
477
473
|
- wakeup (restore state from persisted store)
|
|
478
474
|
- init
|
|
479
|
-
- onMount
|
|
480
475
|
- onDestroy
|
|
481
476
|
|
|
477
|
+
## Demo
|
|
478
|
+
Explore [demo app](https://github.com/Lomray-Software/vite-template) to more understand.
|
|
479
|
+
|
|
482
480
|
## React Native debug plugin
|
|
483
481
|
For debug state, you can use [Reactotron debug plugin](https://github.com/Lomray-Software/reactotron-mobx-store-manager)
|
|
484
482
|
|
package/lib/context.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { FC, ReactElement } from "react";
|
|
4
4
|
import Manager from "./manager.js";
|
|
5
|
+
import { TStores } from "./types-9745a837.js";
|
|
5
6
|
interface IStoreManagerProvider {
|
|
6
7
|
storeManager: Manager;
|
|
7
8
|
shouldInit?: boolean;
|
|
@@ -9,12 +10,9 @@ interface IStoreManagerProvider {
|
|
|
9
10
|
children?: React.ReactNode;
|
|
10
11
|
}
|
|
11
12
|
interface IStoreManagerParentProvider {
|
|
12
|
-
children?: React.ReactNode;
|
|
13
13
|
parentId: string;
|
|
14
|
-
}
|
|
15
|
-
interface IStoreManagerSuspenseProvider {
|
|
16
14
|
children?: React.ReactNode;
|
|
17
|
-
|
|
15
|
+
initStores?: TStores;
|
|
18
16
|
}
|
|
19
17
|
/**
|
|
20
18
|
* Mobx store manager context
|
|
@@ -24,15 +22,6 @@ declare const StoreManagerContext: React.Context<Manager>;
|
|
|
24
22
|
* To spread relationships
|
|
25
23
|
*/
|
|
26
24
|
declare const StoreManagerParentContext: React.Context<string>;
|
|
27
|
-
/**
|
|
28
|
-
* Generate id for suspended component stores
|
|
29
|
-
*/
|
|
30
|
-
declare const StoreManagerSuspenseContext: React.Context<string | null>;
|
|
31
|
-
/**
|
|
32
|
-
* Mobx store manager parent provider
|
|
33
|
-
* @constructor
|
|
34
|
-
*/
|
|
35
|
-
declare const StoreManagerSuspenseProvider: FC<IStoreManagerSuspenseProvider>;
|
|
36
25
|
/**
|
|
37
26
|
* Mobx store manager parent provider
|
|
38
27
|
* @constructor
|
|
@@ -43,7 +32,6 @@ declare const StoreManagerParentProvider: FC<Omit<IStoreManagerParentProvider, '
|
|
|
43
32
|
* @constructor
|
|
44
33
|
*/
|
|
45
34
|
declare const StoreManagerProvider: FC<IStoreManagerProvider>;
|
|
46
|
-
declare const
|
|
47
|
-
declare const
|
|
48
|
-
|
|
49
|
-
export { StoreManagerContext, StoreManagerParentContext, StoreManagerSuspenseContext, StoreManagerProvider, StoreManagerParentProvider, StoreManagerSuspenseProvider, useStoreManagerContext, useStoreManagerParentContext, useStoreManagerSuspenseContext };
|
|
35
|
+
declare const useStoreManager: () => Manager;
|
|
36
|
+
declare const useStoreManagerParent: () => IStoreManagerParentProvider['parentId'];
|
|
37
|
+
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({}),
|
|
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({}),o=r.default.createContext("root"),n=({parentId:e,children:t,initStores:a})=>{const n=s();return a&&n.touchedStores(a),r.default.createElement(o.Provider,{value:e,children:t})},s=()=>e.useContext(a);exports.StoreManagerContext=a,exports.StoreManagerParentContext=o,exports.StoreManagerParentProvider=n,exports.StoreManagerProvider=({children:t,storeManager:o,fallback:s,shouldInit:u=!1})=>{const[l,c]=e.useState(!u);return e.useEffect((()=>{u&&o.init().then((()=>c(!0))).catch((e=>{console.error("Failed initialized store manager: ",e)}))}),[u,o]),r.default.createElement(a.Provider,{value:o},r.default.createElement(n,{parentId:"root"},l?t:s||t))},exports.useStoreManager=s,exports.useStoreManagerParent=()=>e.useContext(o);
|
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
export * from "./types-
|
|
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
7
|
export { default as Events } from "./events.js";
|
|
8
|
-
export { default as MobxSuspense } from "./mobx-suspense.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"),
|
|
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
|
|
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
|
*/
|
|
@@ -104,13 +117,6 @@ declare class Manager {
|
|
|
104
117
|
* @protected
|
|
105
118
|
*/
|
|
106
119
|
protected getStoreId<T>(store: IConstructableStore<T> | TInitStore, params?: IStoreParams): string;
|
|
107
|
-
/**
|
|
108
|
-
* Generate new context id
|
|
109
|
-
*/
|
|
110
|
-
/**
|
|
111
|
-
* Generate new context id
|
|
112
|
-
*/
|
|
113
|
-
createContextId(id?: string): string;
|
|
114
120
|
/**
|
|
115
121
|
* Get exist store
|
|
116
122
|
*/
|
|
@@ -142,25 +148,21 @@ declare class Manager {
|
|
|
142
148
|
/**
|
|
143
149
|
* Create stores for component
|
|
144
150
|
*/
|
|
145
|
-
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;
|
|
146
152
|
/**
|
|
147
153
|
* Prepare store before usage
|
|
148
|
-
* @protected
|
|
149
154
|
*/
|
|
150
155
|
/**
|
|
151
156
|
* Prepare store before usage
|
|
152
|
-
* @protected
|
|
153
157
|
*/
|
|
154
158
|
protected prepareStore(store: TStores[string]): void;
|
|
155
159
|
/**
|
|
156
|
-
*
|
|
157
|
-
* @protected
|
|
160
|
+
* Remove store
|
|
158
161
|
*/
|
|
159
162
|
/**
|
|
160
|
-
*
|
|
161
|
-
* @protected
|
|
163
|
+
* Remove store
|
|
162
164
|
*/
|
|
163
|
-
protected
|
|
165
|
+
protected removeStore(store: TStores[string]): void;
|
|
164
166
|
/**
|
|
165
167
|
* Mount stores to component
|
|
166
168
|
*/
|
|
@@ -168,6 +170,20 @@ declare class Manager {
|
|
|
168
170
|
* Mount stores to component
|
|
169
171
|
*/
|
|
170
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;
|
|
171
187
|
/**
|
|
172
188
|
* Get store's state
|
|
173
189
|
*/
|
package/lib/manager.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("@lomray/event-manager"),t=require("mobx"),s=require("./events.js"),
|
|
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;
|
|
@@ -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;
|
package/lib/suspense-query.d.ts
CHANGED
package/lib/suspense-query.js
CHANGED
|
@@ -1 +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:
|
|
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,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import Manager from "./manager.js";
|
|
3
|
+
import StoreStatus from "./store-status.js";
|
|
2
4
|
interface IWindowManager {
|
|
3
5
|
pushInit: (state: Record<string, any>) => void;
|
|
4
6
|
}
|
|
@@ -14,13 +16,15 @@ interface IConstructorParams<TProps = Record<string, any>> {
|
|
|
14
16
|
}
|
|
15
17
|
interface IStoreLifecycle {
|
|
16
18
|
onDestroy?: () => void;
|
|
17
|
-
onMount?: () => void | (() => void);
|
|
18
19
|
}
|
|
19
20
|
interface IStore extends IStoreLifecycle {
|
|
20
21
|
libStoreId?: string;
|
|
21
22
|
libStoreContextId?: string;
|
|
22
23
|
libStoreParentId?: string;
|
|
24
|
+
libStoreSuspenseId?: string;
|
|
23
25
|
libStoreComponentName?: string;
|
|
26
|
+
libStoreStatus?: StoreStatus;
|
|
27
|
+
libDestroyTimer?: NodeJS.Timeout;
|
|
24
28
|
isSingleton?: boolean;
|
|
25
29
|
init?: () => void;
|
|
26
30
|
toJSON?: () => Record<string, any>;
|
|
@@ -47,7 +51,7 @@ interface IManagerParams {
|
|
|
47
51
|
options?: IManagerOptions;
|
|
48
52
|
initState?: Record<string, any>;
|
|
49
53
|
}
|
|
50
|
-
type TWakeup = (
|
|
54
|
+
type TWakeup = (state: {
|
|
51
55
|
initState?: Record<string, any>;
|
|
52
56
|
persistedState?: Record<string, any>;
|
|
53
57
|
}) => void;
|
|
@@ -59,7 +63,11 @@ interface IStorage {
|
|
|
59
63
|
interface IManagerOptions {
|
|
60
64
|
shouldDisablePersist?: boolean;
|
|
61
65
|
shouldRemoveInitState?: boolean;
|
|
62
|
-
|
|
66
|
+
destroyTimers?: {
|
|
67
|
+
init?: number;
|
|
68
|
+
touched?: number;
|
|
69
|
+
unused?: number;
|
|
70
|
+
};
|
|
63
71
|
}
|
|
64
72
|
type TStores = {
|
|
65
73
|
[storeKey: string]: IStore | IStorePersisted;
|
|
@@ -81,6 +89,7 @@ interface IStoreParams {
|
|
|
81
89
|
key?: string;
|
|
82
90
|
contextId?: string;
|
|
83
91
|
parentId?: string;
|
|
92
|
+
suspenseId?: string;
|
|
84
93
|
componentName?: string;
|
|
85
94
|
componentProps?: Record<string, any>;
|
|
86
95
|
}
|
package/lib/wakeup.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TStores, TWakeup } from "./types-9745a837.js";
|
|
2
2
|
/**
|
|
3
|
-
* Restore store state
|
|
3
|
+
* Restore persisted store state
|
|
4
4
|
*/
|
|
5
|
-
declare
|
|
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=(
|
|
1
|
+
"use strict";module.exports=function({persistedState:t}){t&&Object.assign(this,t)};
|
package/lib/with-stores.d.ts
CHANGED
package/lib/with-stores.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("hoist-non-react-statics"),
|
|
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": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.11",
|
|
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"
|
|
@@ -39,15 +51,15 @@
|
|
|
39
51
|
"prepare": "husky install"
|
|
40
52
|
},
|
|
41
53
|
"dependencies": {
|
|
54
|
+
"@lomray/consistent-suspense": "^1.2.2",
|
|
42
55
|
"@lomray/event-manager": "^1.2.2"
|
|
43
56
|
},
|
|
44
57
|
"devDependencies": {
|
|
45
|
-
"@commitlint/cli": "^17.6.
|
|
46
|
-
"@commitlint/config-conventional": "^17.6.
|
|
58
|
+
"@commitlint/cli": "^17.6.6",
|
|
59
|
+
"@commitlint/config-conventional": "^17.6.6",
|
|
47
60
|
"@lomray/eslint-config-react": "^3.0.0",
|
|
48
61
|
"@lomray/prettier-config": "^1.2.0",
|
|
49
62
|
"@rollup/plugin-terser": "^0.4.3",
|
|
50
|
-
"@types/express": "^4.17.17",
|
|
51
63
|
"@types/hoist-non-react-statics": "^3.3.1",
|
|
52
64
|
"@types/react": "^18.2.7",
|
|
53
65
|
"eslint": "^8.41.0",
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
18.13.0
|
package/lib/mobx-suspense.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { FC, SuspenseProps } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* Wrapper around react suspense
|
|
4
|
-
* Create unique id for each suspense (used for create/stream stores state)
|
|
5
|
-
* @constructor
|
|
6
|
-
*/
|
|
7
|
-
declare const MobxSuspense: FC<SuspenseProps>;
|
|
8
|
-
export { MobxSuspense as default };
|
package/lib/mobx-suspense.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var e=require("react"),t=require("./context.js");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=a(e);module.exports=({children:a,fallback:l,...n})=>{var u;const d=e.useId(),c=e.Children.map(a,((e,a)=>r.default.createElement(t.StoreManagerSuspenseProvider,{id:`${d}${a}`},e))),i=r.default.createElement(r.default.Fragment,null,r.default.createElement("script",{"data-context-id":d,"data-count":null!==(u=null==c?void 0:c.length)&&void 0!==u?u:0}),l);return r.default.createElement(e.Suspense,{...n,children:c,fallback:i})};
|
package/lib/stream-stores.d.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { Response } from 'express';
|
|
2
|
-
import Manager from "./manager.js";
|
|
3
|
-
/**
|
|
4
|
-
* Stream mobx manager stores
|
|
5
|
-
* NOTE: use with renderToPipeableStream
|
|
6
|
-
*/
|
|
7
|
-
declare class StreamStores {
|
|
8
|
-
/**
|
|
9
|
-
* Obtained suspensions from application shell
|
|
10
|
-
* @protected
|
|
11
|
-
*/
|
|
12
|
-
protected suspendIds: Record<string, {
|
|
13
|
-
contextId: string;
|
|
14
|
-
count: number;
|
|
15
|
-
}>;
|
|
16
|
-
/**
|
|
17
|
-
* Mobx store manager instance
|
|
18
|
-
* @protected
|
|
19
|
-
*/
|
|
20
|
-
protected readonly manager: Manager;
|
|
21
|
-
/**
|
|
22
|
-
* @constructor
|
|
23
|
-
* @protected
|
|
24
|
-
*/
|
|
25
|
-
/**
|
|
26
|
-
* @constructor
|
|
27
|
-
* @protected
|
|
28
|
-
*/
|
|
29
|
-
protected constructor(manager: Manager);
|
|
30
|
-
/**
|
|
31
|
-
* Listen react stream and push suspense stores state to client
|
|
32
|
-
*/
|
|
33
|
-
/**
|
|
34
|
-
* Listen react stream and push suspense stores state to client
|
|
35
|
-
*/
|
|
36
|
-
static stream(res: Response, manager: Manager): StreamStores;
|
|
37
|
-
/**
|
|
38
|
-
* Begin listen stream
|
|
39
|
-
*/
|
|
40
|
-
/**
|
|
41
|
-
* Begin listen stream
|
|
42
|
-
*/
|
|
43
|
-
protected beginStream(res: Response): void;
|
|
44
|
-
/**
|
|
45
|
-
* Parse suspensions and related stores context id from application shell
|
|
46
|
-
* @protected
|
|
47
|
-
*/
|
|
48
|
-
/**
|
|
49
|
-
* Parse suspensions and related stores context id from application shell
|
|
50
|
-
* @protected
|
|
51
|
-
*/
|
|
52
|
-
protected obtainSuspensions(html: string): void;
|
|
53
|
-
/**
|
|
54
|
-
* Replace suspend id
|
|
55
|
-
* @protected
|
|
56
|
-
*/
|
|
57
|
-
/**
|
|
58
|
-
* Replace suspend id
|
|
59
|
-
* @protected
|
|
60
|
-
*/
|
|
61
|
-
protected replaceSuspendIds(formId: string, toId: string): string | undefined;
|
|
62
|
-
/**
|
|
63
|
-
* Parse complete suspense chunk
|
|
64
|
-
* @protected
|
|
65
|
-
*/
|
|
66
|
-
/**
|
|
67
|
-
* Parse complete suspense chunk
|
|
68
|
-
* @protected
|
|
69
|
-
*/
|
|
70
|
-
protected obtainCompleteSuspense(html: string): Uint8Array | undefined;
|
|
71
|
-
}
|
|
72
|
-
export { StreamStores as default };
|
package/lib/stream-stores.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";class t{constructor(t){Object.defineProperty(this,"suspendIds",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"manager",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.manager=t}static stream(e,s){const n=new t(s);return n.beginStream(e),n}beginStream(t){const e=t.write.bind(t);t.write=(t,...s)=>{const n=Buffer.from(t).toString();this.obtainSuspensions(n);const r=this.obtainCompleteSuspense(n);return r?e(Buffer.concat([r,t]),...s):e(t,...s)}}obtainSuspensions(t){if(this.suspendIds)return;const e=[...t.matchAll(/<template id="(?<templateId>[^"]+)".+?<script data-context-id="(?<contextId>[^"]+)".+?data-count="(?<count>[^"]+)">/g)];e.length&&(this.suspendIds=e.reduce(((t,{groups:e})=>{const{templateId:s,contextId:n,count:r}=null!=e?e:{};return s?{...t,[s]:{contextId:n,count:Number(r)}}:t}),{}))}replaceSuspendIds(t,e){if(t)return this.suspendIds[e]=this.suspendIds[t],delete this.suspendIds[t],e}obtainCompleteSuspense(t){var e,s,n;if(!t.startsWith("<div hidden id="))return;const{from:r,to:i}=null!==(s=null===(e=t.match(/\$RC\("(?<from>[^"]+)","(?<to>[^"]+)"\)/))||void 0===e?void 0:e.groups)&&void 0!==s?s:{},o=this.replaceSuspendIds(r,i);if(!o)return;const{contextId:u,count:d}=null!==(n=this.suspendIds[o])&&void 0!==n?n:{};if(!u||!d)return;const a=this.manager.getStoresRelations(),c=this.manager.createContextId(u),l=[...Array(d)].reduce(((t,e,s)=>{const n=`${c}${s}`;return a.has(n)&&t.push(...a.get(n).ids),t}),[]);if(!l.length)return;const p=JSON.stringify(this.manager.toJSON(l));return Buffer.from(`<script>window.mobxManager.pushInit(${p});<\/script>`,"utf8")}}module.exports=t;
|