@lomray/react-mobx-manager 2.0.0-beta.2 → 2.0.0-beta.21
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 +94 -53
- 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-stream.d.ts +29 -0
- package/lib/manager-stream.js +1 -0
- package/lib/manager.d.ts +32 -16
- package/lib/manager.js +1 -1
- package/lib/on-change-listener.d.ts +1 -1
- package/lib/plugins/helpers.d.ts +43 -0
- package/lib/plugins/helpers.js +1 -0
- package/lib/plugins/vite/hydration-update-fix.d.ts +7 -0
- package/lib/plugins/vite/hydration-update-fix.js +1 -0
- package/lib/plugins/vite/id-generator.d.ts +15 -0
- package/lib/plugins/vite/id-generator.js +1 -0
- package/lib/plugins/vite/index.d.ts +7 -0
- package/lib/plugins/vite/index.js +1 -0
- 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 +28 -6
- package/lib/suspense-query.js +1 -1
- package/lib/{types-abd34741.d.ts → types-a8f9023c.d.ts} +15 -6
- 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 +7 -7
- package/lib/mobx-suspense.d.ts +0 -8
- package/lib/mobx-suspense.js +0 -1
- package/lib/server/stream-stores.d.ts +0 -72
- package/lib/server/stream-stores.js +0 -1
package/README.md
CHANGED
|
@@ -5,10 +5,12 @@
|
|
|
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.
|
|
9
|
+
- Support SSR.
|
|
10
|
+
- Support render to stream.
|
|
8
11
|
- Manage your Mobx stores like a boss - debug like a hacker.
|
|
9
12
|
- Simple idea - simple implementation.
|
|
10
13
|
- Small package size.
|
|
11
|
-
- Support render to stream.
|
|
12
14
|
- Support code splitting out of the box.
|
|
13
15
|
- Access stores from other stores.
|
|
14
16
|
- Can be a replacement for react context.
|
|
@@ -37,9 +39,10 @@
|
|
|
37
39
|
- [Manager](#manager)
|
|
38
40
|
- [withStores](#withstores)
|
|
39
41
|
- [StoreManagerProvider](#storemanagerprovider)
|
|
40
|
-
- [useStoreManagerContext](#
|
|
41
|
-
- [useStoreManagerParentContext](#
|
|
42
|
+
- [useStoreManagerContext](#usestoremanager)
|
|
43
|
+
- [useStoreManagerParentContext](#usestoremanagerparent)
|
|
42
44
|
- [Store](#store)
|
|
45
|
+
- [Example](#demo)
|
|
43
46
|
- [React Native Debug Plugin](#react-native-debug-plugin)
|
|
44
47
|
- [Bugs and feature requests](#bugs-and-feature-requests)
|
|
45
48
|
- [License](#license)
|
|
@@ -49,26 +52,68 @@
|
|
|
49
52
|
The React-mobx-manager package is distributed using [npm](https://www.npmjs.com/), the node package manager.
|
|
50
53
|
|
|
51
54
|
```
|
|
52
|
-
npm i --save @lomray/react-mobx-manager
|
|
55
|
+
npm i --save @lomray/react-mobx-manager @lomray/consistent-suspense
|
|
53
56
|
```
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
__NOTE:__ this package use [@lomray/consistent-suspense](https://github.com/Lomray-Software/consistent-suspense) for generate stable id's inside Suspense.
|
|
59
|
+
|
|
60
|
+
__Choose one of store id generating strategy__:
|
|
56
61
|
|
|
62
|
+
1. Configure your bundler to keep classnames and function names. Store id will be generated from class names (chose unique class names).
|
|
57
63
|
- **React:** (craco or webpack config, terser options)
|
|
58
64
|
```bash
|
|
59
65
|
terserOptions.keep_classnames = true;
|
|
60
66
|
terserOptions.keep_fnames = true;
|
|
61
67
|
```
|
|
62
68
|
|
|
63
|
-
- **React Native:** (metro bundler config)
|
|
69
|
+
- **React Native:** (metro bundler config: metro.config.js)
|
|
70
|
+
```js
|
|
71
|
+
module.exports = {
|
|
72
|
+
transformer: {
|
|
73
|
+
minifierConfig: {
|
|
74
|
+
keep_classnames: true,
|
|
75
|
+
keep_fnames: true,
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
}
|
|
64
79
|
```
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
2. Define `id` for each store.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { makeObservable } from "mobx";
|
|
84
|
+
|
|
85
|
+
class MyStore {
|
|
86
|
+
/**
|
|
87
|
+
* Define unique store id
|
|
88
|
+
*/
|
|
89
|
+
static id = 'Unique-store-id';
|
|
90
|
+
|
|
91
|
+
constructor() {
|
|
92
|
+
makeObservable(this, {})
|
|
93
|
+
}
|
|
70
94
|
}
|
|
71
95
|
```
|
|
96
|
+
3. Use `Vite plugins`.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { defineConfig } from 'vite';
|
|
100
|
+
import react from '@vitejs/plugin-react';
|
|
101
|
+
import MobxManager from '@lomray/react-mobx-manager/plugins/vite/index';
|
|
102
|
+
|
|
103
|
+
// https://vitejs.dev/config/
|
|
104
|
+
export default defineConfig({
|
|
105
|
+
/**
|
|
106
|
+
* Store id's will be generated automatically, just chill
|
|
107
|
+
*/
|
|
108
|
+
plugins: [react(), MobxManager()]
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Detect mobx store:
|
|
113
|
+
- by makeObservable or makeAutoObservable
|
|
114
|
+
- by @mobx-store jsdoc before class
|
|
115
|
+
*/
|
|
116
|
+
```
|
|
72
117
|
|
|
73
118
|
## Usage
|
|
74
119
|
|
|
@@ -77,24 +122,27 @@ Import `Manager, StoreManagerProvider` from `@lomray/react-mobx-manager` into yo
|
|
|
77
122
|
```typescript jsx
|
|
78
123
|
import React from 'react';
|
|
79
124
|
import ReactDOM from 'react-dom/client';
|
|
80
|
-
import '
|
|
125
|
+
import { ConsistentSuspenseProvider } from '@lomray/consistent-suspense';
|
|
81
126
|
import { Manager, StoreManagerProvider, MobxLocalStorage } from '@lomray/react-mobx-manager';
|
|
82
127
|
import App from './app';
|
|
83
128
|
import MyApiClient from './services/my-api-client';
|
|
129
|
+
import './index.css';
|
|
84
130
|
|
|
85
131
|
const apiClient = new MyApiClient();
|
|
86
132
|
const storeManager = new Manager({
|
|
87
133
|
storage: new MobxLocalStorage(), // optional: needs for persisting stores
|
|
88
|
-
storesParams: { apiClient }, // optional: we can provide our api client for access from the store
|
|
134
|
+
storesParams: { apiClient }, // optional: we can provide our api client for access from the each store
|
|
89
135
|
});
|
|
90
136
|
|
|
91
137
|
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
|
|
92
138
|
|
|
93
139
|
root.render(
|
|
94
140
|
<React.StrictMode>
|
|
95
|
-
<
|
|
96
|
-
<
|
|
97
|
-
|
|
141
|
+
<ConsistentSuspenseProvider> {/** required **/}
|
|
142
|
+
<StoreManagerProvider storeManager={storeManager} shouldInit>
|
|
143
|
+
<App />
|
|
144
|
+
</StoreManagerProvider>
|
|
145
|
+
</ConsistentSuspenseProvider>
|
|
98
146
|
</React.StrictMode>,
|
|
99
147
|
);
|
|
100
148
|
```
|
|
@@ -126,10 +174,10 @@ class UserStore {
|
|
|
126
174
|
static id = 'user';
|
|
127
175
|
|
|
128
176
|
/**
|
|
129
|
-
* You can also enable
|
|
177
|
+
* You can also enable behavior for global application stores
|
|
130
178
|
* Default: false
|
|
131
179
|
*/
|
|
132
|
-
static
|
|
180
|
+
static isGlobal = true;
|
|
133
181
|
|
|
134
182
|
/**
|
|
135
183
|
* Our state
|
|
@@ -198,16 +246,17 @@ const User: FC<TProps> = ({ userStore: { name } }) => {
|
|
|
198
246
|
export default withStores(User, stores);
|
|
199
247
|
```
|
|
200
248
|
|
|
201
|
-
[See app example](
|
|
249
|
+
[See app example](https://github.com/Lomray-Software/vite-template) for a better understanding.
|
|
202
250
|
|
|
203
251
|
## Support SSR
|
|
204
252
|
Does this library support SSR? Short answer - yes, but we need some steps to prepare our framework.
|
|
253
|
+
- Look at [Vite demo app](https://github.com/Lomray-Software/vite-template) for a better understanding.
|
|
205
254
|
- Look at [After.js (razzle) based project](https://github.com/Lomray-Software/microservices-dashboard/blob/staging/src/pages/user/index.tsx#L82) for a better understanding.
|
|
206
255
|
- Look at [NextJS example](https://github.com/Lomray-Software/nextjs-mobx-store-manager-example) for a better understanding (needs writing a wrapper).
|
|
207
256
|
|
|
208
257
|
## Important Tips
|
|
209
|
-
- Create **
|
|
210
|
-
- To get started, stick to the concept: Store for Component. Don't connect (through withStores) not
|
|
258
|
+
- Create **global** store only for e.g: application settings, logged user, theme, etc.
|
|
259
|
+
- To get started, stick to the concept: Store for Component. Don't connect (through withStores) not global store to several components.
|
|
211
260
|
|
|
212
261
|
## Documentation
|
|
213
262
|
|
|
@@ -253,10 +302,13 @@ const storeManager = new Manager({
|
|
|
253
302
|
*/
|
|
254
303
|
shouldRemoveInitState: true,
|
|
255
304
|
/**
|
|
256
|
-
*
|
|
257
|
-
* Default: false
|
|
305
|
+
* Configure store destroy timers
|
|
258
306
|
*/
|
|
259
|
-
|
|
307
|
+
destroyTimers: {
|
|
308
|
+
init: 500,
|
|
309
|
+
touched: 10000, // NOTE: set to max request timeout
|
|
310
|
+
unused: 1000,
|
|
311
|
+
},
|
|
260
312
|
}
|
|
261
313
|
});
|
|
262
314
|
|
|
@@ -277,7 +329,7 @@ const managerStores = storeManager.getStores();
|
|
|
277
329
|
/**
|
|
278
330
|
* Get specific store
|
|
279
331
|
*/
|
|
280
|
-
const store = storeManager.getStore(
|
|
332
|
+
const store = storeManager.getStore(SomeGlobalStore);
|
|
281
333
|
const store2 = storeManager.getStore(SomeStore, { contextId: 'necessary-context-id' });
|
|
282
334
|
|
|
283
335
|
/**
|
|
@@ -285,16 +337,11 @@ const store2 = storeManager.getStore(SomeStore, { contextId: 'necessary-context-
|
|
|
285
337
|
*/
|
|
286
338
|
const relations = storeManager.getStoresRelations();
|
|
287
339
|
|
|
288
|
-
/**
|
|
289
|
-
* Generate unique context id
|
|
290
|
-
*/
|
|
291
|
-
const contextId = storeManager.createContextId();
|
|
292
|
-
|
|
293
340
|
/**
|
|
294
341
|
* Manually create stores for component
|
|
295
342
|
* NOTE: 'withStores' wrapper use this method, probably you won't need it
|
|
296
343
|
*/
|
|
297
|
-
const stores = storeManager.createStores(['someStore', MyStore], 'parent-id', 'context-id', 'HomePage');
|
|
344
|
+
const stores = storeManager.createStores(['someStore', MyStore], 'parent-id', 'context-id', 'suspense-id', 'HomePage', { componentProp: 'test' });
|
|
298
345
|
|
|
299
346
|
/**
|
|
300
347
|
* Mount/Unmount simple stores to component
|
|
@@ -338,10 +385,10 @@ const storeClass = Manager.persistStore(class MyStore {}, 'my-store');
|
|
|
338
385
|
import { withStores } from '@lomray/react-mobx-manager';
|
|
339
386
|
|
|
340
387
|
/**
|
|
341
|
-
* Create and connect 'stores' to component
|
|
388
|
+
* Create and connect 'stores' to component with custom context id
|
|
342
389
|
* NOTE: In most cases, you don't need to pass a third argument (contextId).
|
|
343
390
|
*/
|
|
344
|
-
withStores(Component, stores, 'optional-context-id');
|
|
391
|
+
withStores(Component, stores, { customContextId: 'optional-context-id' });
|
|
345
392
|
|
|
346
393
|
const stores = { myStore: MyStore, anotherStore: AnotherStore };
|
|
347
394
|
```
|
|
@@ -361,27 +408,27 @@ import { StoreManagerProvider } from '@lomray/react-mobx-manager';
|
|
|
361
408
|
</StoreManagerProvider>
|
|
362
409
|
```
|
|
363
410
|
|
|
364
|
-
###
|
|
411
|
+
### useStoreManager
|
|
365
412
|
```typescript jsx
|
|
366
|
-
import {
|
|
413
|
+
import { useStoreManager } from '@lomray/react-mobx-manager';
|
|
367
414
|
|
|
368
415
|
const MyComponent: FC = () => {
|
|
369
416
|
/**
|
|
370
417
|
* Get store manager inside your function component
|
|
371
418
|
*/
|
|
372
|
-
const storeManager =
|
|
419
|
+
const storeManager = useStoreManager();
|
|
373
420
|
}
|
|
374
421
|
```
|
|
375
422
|
|
|
376
|
-
###
|
|
423
|
+
### useStoreManagerParent
|
|
377
424
|
```typescript jsx
|
|
378
|
-
import {
|
|
425
|
+
import { useStoreManagerParent } from '@lomray/react-mobx-manager';
|
|
379
426
|
|
|
380
427
|
const MyComponent: FC = () => {
|
|
381
428
|
/**
|
|
382
429
|
* Get parent context id
|
|
383
430
|
*/
|
|
384
|
-
const { parentId } =
|
|
431
|
+
const { parentId } = useStoreManagerParent();
|
|
385
432
|
}
|
|
386
433
|
```
|
|
387
434
|
|
|
@@ -398,10 +445,10 @@ class MyStore {
|
|
|
398
445
|
static id = 'user';
|
|
399
446
|
|
|
400
447
|
/**
|
|
401
|
-
* You can also enable
|
|
448
|
+
* You can also enable behavior for global application stores
|
|
402
449
|
* Default: false
|
|
403
450
|
*/
|
|
404
|
-
static
|
|
451
|
+
static isGlobal = true;
|
|
405
452
|
|
|
406
453
|
/**
|
|
407
454
|
* Store observable state
|
|
@@ -414,12 +461,12 @@ class MyStore {
|
|
|
414
461
|
/**
|
|
415
462
|
* @private
|
|
416
463
|
*/
|
|
417
|
-
private someParentStore: ClassReturnType<typeof SomeParentStore>;
|
|
464
|
+
private readonly someParentStore: ClassReturnType<typeof SomeParentStore>;
|
|
418
465
|
|
|
419
466
|
/**
|
|
420
467
|
* @constructor
|
|
421
468
|
*
|
|
422
|
-
* getStore - get parent store or
|
|
469
|
+
* getStore - get parent store or global store
|
|
423
470
|
* storeManager - access to store manager
|
|
424
471
|
* apiClient - your custom param, see 'storesParams' in Manager
|
|
425
472
|
*/
|
|
@@ -427,7 +474,7 @@ class MyStore {
|
|
|
427
474
|
this.apiClient = apiClient;
|
|
428
475
|
this.someParentStore = getStore(SomeParentStore);
|
|
429
476
|
|
|
430
|
-
// In case when store is't
|
|
477
|
+
// In case when store is't global you can get access to component props
|
|
431
478
|
console.log(componentProps);
|
|
432
479
|
|
|
433
480
|
makeObservable(this, {
|
|
@@ -445,14 +492,6 @@ class MyStore {
|
|
|
445
492
|
// do something
|
|
446
493
|
}
|
|
447
494
|
|
|
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
495
|
/**
|
|
457
496
|
* Define this method if you want to do something when a component with this store is unmount
|
|
458
497
|
* @private
|
|
@@ -476,9 +515,11 @@ Lifecycles:
|
|
|
476
515
|
- constructor
|
|
477
516
|
- wakeup (restore state from persisted store)
|
|
478
517
|
- init
|
|
479
|
-
- onMount
|
|
480
518
|
- onDestroy
|
|
481
519
|
|
|
520
|
+
## Demo
|
|
521
|
+
Explore [demo app](https://github.com/Lomray-Software/vite-template) to more understand.
|
|
522
|
+
|
|
482
523
|
## React Native debug plugin
|
|
483
524
|
For debug state, you can use [Reactotron debug plugin](https://github.com/Lomray-Software/reactotron-mobx-store-manager)
|
|
484
525
|
|
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-a8f9023c.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-a8f9023c.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;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Manager from "./manager.js";
|
|
2
|
+
/**
|
|
3
|
+
* Stream mobx manager stores
|
|
4
|
+
*/
|
|
5
|
+
declare class ManagerStream {
|
|
6
|
+
/**
|
|
7
|
+
* Already pushed preamble
|
|
8
|
+
*/
|
|
9
|
+
protected isPreamblePushed: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Mobx store manager
|
|
12
|
+
*/
|
|
13
|
+
protected manager: Manager;
|
|
14
|
+
/**
|
|
15
|
+
* @constructor
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* @constructor
|
|
19
|
+
*/
|
|
20
|
+
constructor(manager: Manager);
|
|
21
|
+
/**
|
|
22
|
+
* Return script with suspense stores to push on stream
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Return script with suspense stores to push on stream
|
|
26
|
+
*/
|
|
27
|
+
take(suspenseId: string): string | void;
|
|
28
|
+
}
|
|
29
|
+
export { ManagerStream as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";module.exports=class{constructor(e){Object.defineProperty(this,"isPreamblePushed",{enumerable:!0,configurable:!0,writable:!0,value:!1}),Object.defineProperty(this,"manager",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.manager=e}take(e){const s=this.manager.getSuspenseRelations().get(e);if(!(null==s?void 0:s.size))return;const i=JSON.stringify(this.manager.toJSON([...s])),t=this.isPreamblePushed?"":"<script>!window.mbxM && (window.mbxM = []);<\/script>";return this.isPreamblePushed||(this.isPreamblePushed=!0),`${t}<script>window.mbxM.push(${i});<\/script>`}};
|
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-a8f9023c.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"),r=require("./on-change-listener.js"),o=require("./wakeup.js");function
|
|
1
|
+
"use strict";var e=require("@lomray/event-manager"),t=require("mobx"),s=require("./events.js"),r=require("./on-change-listener.js"),o=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:r}={}){if(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,r||{}),l.instance=this,"undefined"!=typeof window){const e=window.mbxM;window.mbxM={push:this.pushInitState},(Array.isArray(e)?e:[]).forEach(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:r,key:o}=t;if(s)return s;if(e.libStoreId)return e.libStoreId;let i=e.id||e.name||e.constructor.name;return e.isGlobal?i:(i=`${i}--${r}`,o?`${i}--${o}`:i)}getStore(e,t={}){const s=this.getStoreId(e,t);return this.stores.has(s)?this.stores.get(s):e.isGlobal?this.createStore(e,{id:s,contextId:"global",parentId:"root",suspenseId:"",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},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:r,contextId:i,parentId:n,suspenseId:l,componentName:u,componentProps:d}=t;if(this.stores.has(r))return this.stores.get(r);const h=new e({...this.storesParams,storeManager:this,getStore:(e,t={contextId:i,parentId:n})=>this.getStore(e,t),componentProps:d});return h.libStoreId=r,h.isGlobal=e.isGlobal,h.libStoreContextId=e.isGlobal?"global":i,h.libStoreParentId=e.isGlobal||!n||n===i?"root":n,h.libStoreSuspenseId=l,h.libStoreComponentName=u,this.setStoreStatus(h,e.isGlobal?o.inUse:o.init),this.prepareStore(h),a.default.publish(s.CREATE_STORE,{store:e}),h}createStores(e,t,s,r,o,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:r,componentName:o,componentProps:i})}}),{})}prepareStore(e){var t,r,o;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===(r=e.onDestroy)||void 0===r?void 0:r.bind(e),s=e.addOnChangeListener(e,this);e.onDestroy=()=>{null==s||s(),null==t||t()}}null===(o=e.init)||void 0===o||o.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,r,o;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===(r=this.suspenseRelations.get(n))||void 0===r?void 0:r.has(i))&&this.suspenseRelations.get(n).delete(i),l.size||this.storesRelations.delete(e.libStoreContextId),"onDestroy"in e&&(null===(o=e.onDestroy)||void 0===o||o.call(e)),a.default.publish(s.DELETE_STORE,{store:e}))}mountStores(e){const{shouldRemoveInitState:t}=this.options;return Object.values(e).forEach((e=>{const r=e.libStoreId;t&&this.initState[r]&&delete this.initState[r],this.setStoreStatus(e,o.inUse),a.default.publish(s.MOUNT_STORE,{store:e})})),()=>{Object.values(e).forEach((e=>{e.isGlobal||(this.setStoreStatus(e,o.unused),a.default.publish(s.UNMOUNT_STORE,{store:e}))}))}}touchedStores(e){Object.values(e).forEach((e=>{e.libStoreStatus!==o.init||e.isGlobal||this.setStoreStatus(e,o.touched)}))}setStoreStatus(e,t){const{destroyTimers:{init:s=500,touched:r=1e4,unused:i=1e3}={}}=this.options;e.libStoreStatus=t,clearTimeout(e.libDestroyTimer);let n=0;switch(t){case o.init:n=s;break;case o.touched:n=r;break;case o.unused:n=i}n&&(e.libDestroyTimer=setTimeout((()=>this.removeStore(e)),n))}toJSON(e){var t,s,r;const o={},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())o[e]=null!==(r=null===(s=t.toJSON)||void 0===s?void 0:s.call(t))&&void 0!==r?r:l.getObservableProps(t);return o}toPersistedJSON(){var e,t;const s={};for(const r of l.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:l.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 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=r),e)}}Object.defineProperty(l,"persistedStores",{enumerable:!0,configurable:!0,writable:!0,value:new Set}),module.exports=l;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
type ICache = Map<string, {
|
|
2
|
+
storeId: string;
|
|
3
|
+
classname: string;
|
|
4
|
+
}>;
|
|
5
|
+
/**
|
|
6
|
+
* Load cached store id's by file name
|
|
7
|
+
*/
|
|
8
|
+
declare const loadCache: (isProd?: boolean) => ICache;
|
|
9
|
+
/**
|
|
10
|
+
* Save store id's cache
|
|
11
|
+
*/
|
|
12
|
+
declare const saveCache: (cache: ICache) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Get next letter
|
|
15
|
+
*/
|
|
16
|
+
declare const getNextLetter: (str?: string) => string;
|
|
17
|
+
/**
|
|
18
|
+
* Store is generator
|
|
19
|
+
*/
|
|
20
|
+
declare class Generator {
|
|
21
|
+
cache: ICache;
|
|
22
|
+
protected root: string;
|
|
23
|
+
protected lastId: string;
|
|
24
|
+
// keep last generated production store id (letter)
|
|
25
|
+
constructor(root: string, isProd?: boolean);
|
|
26
|
+
/**
|
|
27
|
+
* Inject store id
|
|
28
|
+
*/
|
|
29
|
+
injectId: (code: string, fileId: string) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Get development id
|
|
32
|
+
*/
|
|
33
|
+
getDevId: (id: string, classname: string) => string;
|
|
34
|
+
/**
|
|
35
|
+
* Get production store id
|
|
36
|
+
*/
|
|
37
|
+
getProdId: () => string;
|
|
38
|
+
/**
|
|
39
|
+
* Try to find mobx store
|
|
40
|
+
*/
|
|
41
|
+
matchMobxStore: (code: string) => string | undefined;
|
|
42
|
+
}
|
|
43
|
+
export { saveCache, loadCache, getNextLetter, Generator };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}Object.defineProperty(exports,"__esModule",{value:!0});var t=e(require("node:fs"));const r=`${__dirname.split("node_modules")[0]}node_modules/.cache/@lomray/react-mobx-manager`,s=`${r}/store-ids.json`,a=(e=!1)=>{if(e&&t.default.existsSync(s)){const e=JSON.parse(t.default.readFileSync(s,{encoding:"utf-8"}));return new Map(e)}return new Map},i=(e="")=>{var t;const r=e.split(""),s=null!==(t=r.pop())&&void 0!==t?t:"`";if("z"===s)return[...r,"A"].join("");if("Z"===s){const e=r.pop();return e?[i([...r,e].join("")),"a"].join(""):"aa"}return[...r,String.fromCharCode(s.charCodeAt(0)+1)].join("")};exports.Generator=class{constructor(e,t=!1){Object.defineProperty(this,"cache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"root",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"lastId",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"injectId",{enumerable:!0,configurable:!0,writable:!0,value:(e,t)=>{const{classname:r,storeId:s}=this.cache.get(t),a=new RegExp(`(class\\s${r}\\s+?{)`);return e.replace(a,`$1static id = '${s}';`)}}),Object.defineProperty(this,"getDevId",{enumerable:!0,configurable:!0,writable:!0,value:(e,t)=>`${e.replace(this.root,"").replace(/\/index.(js|ts|tsx)/,"").split("/").filter(Boolean).join("-")}-${t}`}),Object.defineProperty(this,"getProdId",{enumerable:!0,configurable:!0,writable:!0,value:()=>{const e=i(this.lastId),t=`S${e}`;return this.lastId=e,t}}),Object.defineProperty(this,"matchMobxStore",{enumerable:!0,configurable:!0,writable:!0,value:e=>{var t,r,s,a;const{classname:i}=null!==(r=null===(t=e.match(/class\s(?<classname>\w+)\s+?{(?!.*static\sid\s*=.*).+(makeObservable|makeAutoObservable)(?!.*persistStore\(\1.*)/s))||void 0===t?void 0:t.groups)&&void 0!==r?r:{};if(i)return i;const{classname:o}=null!==(a=null===(s=e.match(/(@mobx-store).+class\s(?<classname>\w+)\s+?{(?!.*static\sid\s*=.*).+}(?!.*persistStore.*)/s))||void 0===s?void 0:s.groups)&&void 0!==a?a:{};return o}}),this.root=e,this.cache=a(t)}},exports.getNextLetter=i,exports.loadCache=a,exports.saveCache=e=>{t.default.existsSync(r)||t.default.mkdirSync(r,{recursive:!0}),t.default.writeFileSync(s,JSON.stringify([...e.entries()],null,2),{encoding:"utf-8"})};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("node:path");module.exports=function(){return{name:"@lomray/react-mobx-manager-hydration-fix",transform(r,t){const n=e.extname(t).split("?")[0];if([".js",".ts",".tsx"].includes(n)&&r.includes("function useObserver"))return{code:r.replace(/(}\);[^f]+)(forceUpdate\(\);)/s,"$1/*$2*/"),map:{mappings:""}}}}};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
interface IPluginOptions {
|
|
3
|
+
root?: string;
|
|
4
|
+
isProd?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Generate unique store id's
|
|
8
|
+
*
|
|
9
|
+
* Detect mobx store:
|
|
10
|
+
* - by makeObservable or makeAutoObservable
|
|
11
|
+
* - by @mobx-store jsdoc before class
|
|
12
|
+
* @constructor
|
|
13
|
+
*/
|
|
14
|
+
declare function IdGenerator({ root, isProd }?: IPluginOptions): Plugin;
|
|
15
|
+
export { IdGenerator as default, IPluginOptions };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("node:path"),r=require("node:process"),t=require("../helpers.js");module.exports=function({root:s=r.cwd(),isProd:a=!1}={}){const n=new t.Generator(s,a);return{name:"@lomray/react-mobx-manager-id-generator",transform(r,t){const s=e.extname(t).split("?")[0];if(t.includes("node_modules")||![".js",".ts",".tsx"].includes(s)||!/(makeObservable|makeAutoObservable)\(/.test(r))return;if(n.cache.has(t))return{code:n.injectId(r,t),map:{mappings:""}};const o=n.matchMobxStore(r);if(o){if(!n.cache.has(t)){const e=a?n.getProdId():n.getDevId(t,o);n.cache.set(t,{classname:o,storeId:e})}return{code:n.injectId(r,t),map:{mappings:""}}}},buildEnd(){a&&t.saveCache(n.cache)}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("node:process"),r=require("./hydration-update-fix.js"),t=require("./id-generator.js");function n(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var o=n(e);const i=e=>"production"===e||"production"===o.env.NODE_ENV;module.exports=function(){let e;return[{...r(),apply:()=>!i()},{name:t().name,configResolved({root:r}){e=t({root:r,isProd:i()})},transform(...r){var t;return null===(t=e.transform)||void 0===t?void 0:t.call(this,...r)},buildEnd(...r){var t;null===(t=e.buildEnd)||void 0===t||t.call(this,...r)}}]};
|
|
@@ -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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TInitStore } from "./types-
|
|
1
|
+
import { TInitStore } from "./types-a8f9023c.js";
|
|
2
2
|
interface IPromise<TReturn> extends Promise<TReturn> {
|
|
3
3
|
status?: 'fulfilled' | 'pending' | 'rejected';
|
|
4
4
|
value?: TReturn;
|
|
@@ -6,6 +6,7 @@ interface IPromise<TReturn> extends Promise<TReturn> {
|
|
|
6
6
|
}
|
|
7
7
|
interface ISuspenseQueryParams {
|
|
8
8
|
fieldName?: string;
|
|
9
|
+
errorFields?: string[];
|
|
9
10
|
}
|
|
10
11
|
/**
|
|
11
12
|
* Run request and cache promise
|
|
@@ -16,10 +17,6 @@ declare class SuspenseQuery {
|
|
|
16
17
|
* @private
|
|
17
18
|
*/
|
|
18
19
|
protected promise: Promise<any> | undefined;
|
|
19
|
-
/**
|
|
20
|
-
* @private
|
|
21
|
-
*/
|
|
22
|
-
protected error?: Error;
|
|
23
20
|
/**
|
|
24
21
|
* Target store
|
|
25
22
|
* @private
|
|
@@ -35,7 +32,32 @@ declare class SuspenseQuery {
|
|
|
35
32
|
/**
|
|
36
33
|
* @constructor
|
|
37
34
|
*/
|
|
38
|
-
constructor(store: TInitStore, { fieldName,
|
|
35
|
+
constructor(store: TInitStore, { fieldName, errorFields }?: ISuspenseQueryParams);
|
|
36
|
+
/**
|
|
37
|
+
* Error to json
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Error to json
|
|
41
|
+
*/
|
|
42
|
+
protected errorJson(e: any): void;
|
|
43
|
+
/**
|
|
44
|
+
* Assign custom error fields to error
|
|
45
|
+
*/
|
|
46
|
+
/**
|
|
47
|
+
* Assign custom error fields to error
|
|
48
|
+
*/
|
|
49
|
+
protected jsonToError(e: Error, values: Record<string, any>): Error;
|
|
50
|
+
/**
|
|
51
|
+
* Detect if suspense is restored from server side:
|
|
52
|
+
* - throw error if exist
|
|
53
|
+
* - skip run suspense if already completed
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Detect if suspense is restored from server side:
|
|
57
|
+
* - throw error if exist
|
|
58
|
+
* - skip run suspense if already completed
|
|
59
|
+
*/
|
|
60
|
+
protected isComplete(): boolean;
|
|
39
61
|
/**
|
|
40
62
|
* Run request
|
|
41
63
|
* Save request resolve status
|
package/lib/suspense-query.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("mobx");class r{constructor(t,{fieldName:i="
|
|
1
|
+
"use strict";var e=require("mobx");class r{constructor(t,{fieldName:i="sR",errorFields:s=["name","message"]}={}){var o;Object.defineProperty(this,"promise",{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.isComplete())return this.promise||(this.promise=t(),this.promise.then((()=>{e.runInAction((()=>{this.store[i]=!0}))}),(r=>{e.runInAction((()=>{this.errorJson(r),this.store[i]=r}))}))),r.run(this.promise)}}),this.store=t,this.params={fieldName:i,errorFields:s};const a=null===(o=t.init)||void 0===o?void 0:o.bind(t);t.init=()=>{this.isComplete(),null==a||a()},e.extendObservable(t,{[i]:!1},{[i]:e.observable})}errorJson(e){e.toJSON=()=>this.params.errorFields.reduce(((r,t)=>({...r,[t]:null==e?void 0:e[t]})),{})}jsonToError(e,r){return this.params.errorFields.forEach((t=>{e[t]=null==r?void 0:r[t]})),e}isComplete(){var e;const r=this.store[this.params.fieldName];if("boolean"!==typeof r)throw this.jsonToError(new Error(null!==(e=null==r?void 0:r.message)&&void 0!==e?e:null==r?void 0:r.name),r);return!0===r}}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,10 +1,12 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import Manager from "./manager.js";
|
|
3
|
+
import StoreStatus from "./store-status.js";
|
|
2
4
|
interface IWindowManager {
|
|
3
|
-
|
|
5
|
+
push: (state: Record<string, any>) => void;
|
|
4
6
|
}
|
|
5
7
|
declare global {
|
|
6
8
|
interface Window {
|
|
7
|
-
|
|
9
|
+
mbxM: Record<string, any>[] | IWindowManager;
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
12
|
interface IConstructorParams<TProps = Record<string, any>> {
|
|
@@ -14,14 +16,16 @@ 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;
|
|
24
|
-
|
|
26
|
+
libStoreStatus?: StoreStatus;
|
|
27
|
+
libDestroyTimer?: NodeJS.Timeout;
|
|
28
|
+
isGlobal?: boolean;
|
|
25
29
|
init?: () => void;
|
|
26
30
|
toJSON?: () => Record<string, any>;
|
|
27
31
|
}
|
|
@@ -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-a8f9023c.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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lomray/react-mobx-manager",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.21",
|
|
4
4
|
"description": "This package provides Mobx stores manager for react.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
"*": {
|
|
13
13
|
"./*": [
|
|
14
14
|
"lib/*",
|
|
15
|
-
"lib/storages/*"
|
|
16
|
-
"lib/server/*"
|
|
15
|
+
"lib/storages/*"
|
|
17
16
|
]
|
|
18
17
|
}
|
|
19
18
|
},
|
|
@@ -52,15 +51,15 @@
|
|
|
52
51
|
"prepare": "husky install"
|
|
53
52
|
},
|
|
54
53
|
"dependencies": {
|
|
54
|
+
"@lomray/consistent-suspense": "^1.3.0",
|
|
55
55
|
"@lomray/event-manager": "^1.2.2"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@commitlint/cli": "^17.6.
|
|
59
|
-
"@commitlint/config-conventional": "^17.6.
|
|
58
|
+
"@commitlint/cli": "^17.6.6",
|
|
59
|
+
"@commitlint/config-conventional": "^17.6.6",
|
|
60
60
|
"@lomray/eslint-config-react": "^3.0.0",
|
|
61
61
|
"@lomray/prettier-config": "^1.2.0",
|
|
62
62
|
"@rollup/plugin-terser": "^0.4.3",
|
|
63
|
-
"@types/express": "^4.17.17",
|
|
64
63
|
"@types/hoist-non-react-statics": "^3.3.1",
|
|
65
64
|
"@types/react": "^18.2.7",
|
|
66
65
|
"eslint": "^8.41.0",
|
|
@@ -74,7 +73,8 @@
|
|
|
74
73
|
"rollup-plugin-ts": "^3.2.0",
|
|
75
74
|
"semantic-release": "^21.0.2",
|
|
76
75
|
"ttypescript": "^1.5.15",
|
|
77
|
-
"typescript": "^4.7.4"
|
|
76
|
+
"typescript": "^4.7.4",
|
|
77
|
+
"vite": "^4.4.4"
|
|
78
78
|
},
|
|
79
79
|
"peerDependencies": {
|
|
80
80
|
"hoist-non-react-statics": "^3.3.2",
|
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})};
|
|
@@ -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 };
|
|
@@ -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;
|