@lomray/react-mobx-manager 1.0.0-beta.1 → 1.0.0-beta.4
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 +9 -0
- package/lib/context.d.ts +21 -0
- package/lib/context.js +38 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +21 -0
- package/lib/manager.d.ts +137 -0
- package/lib/manager.js +228 -0
- package/lib/on-change-listener.d.ts +6 -0
- package/lib/on-change-listener.js +25 -0
- package/lib/storages/local-storage.d.ts +26 -0
- package/lib/storages/local-storage.js +30 -0
- package/lib/types-f2f6b0e4.d.ts +58 -0
- package/lib/wakeup.d.ts +6 -0
- package/lib/wakeup.js +12 -0
- package/lib/with-stores.d.ts +7 -0
- package/lib/with-stores.js +35 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Mobx stores manager for React
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
[](https://sonarcloud.io/summary/new_code?id=Lomray-Software_react-mobx-manager)
|
|
5
|
+
[](https://sonarcloud.io/summary/new_code?id=Lomray-Software_react-mobx-manager)
|
|
6
|
+
[](https://sonarcloud.io/summary/new_code?id=Lomray-Software_react-mobx-manager)
|
|
7
|
+
[](https://sonarcloud.io/summary/new_code?id=Lomray-Software_react-mobx-manager)
|
|
8
|
+
[](https://sonarcloud.io/summary/new_code?id=Lomray-Software_react-mobx-manager)
|
|
9
|
+
[](https://sonarcloud.io/summary/new_code?id=Lomray-Software_react-mobx-manager)
|
|
10
|
+
[](https://sonarcloud.io/summary/new_code?id=Lomray-Software_react-mobx-manager)
|
|
11
|
+
|
|
3
12
|
## Usage
|
|
4
13
|
|
|
5
14
|
1. Install package:
|
package/lib/context.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { FC, ReactElement } from "react";
|
|
4
|
+
import Manager from "./manager";
|
|
5
|
+
interface IStoreManagerProvider {
|
|
6
|
+
storeManager: Manager;
|
|
7
|
+
shouldInit?: boolean;
|
|
8
|
+
fallback?: ReactElement;
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Mobx store manager context
|
|
13
|
+
*/
|
|
14
|
+
declare const StoreManagerContext: React.Context<Manager>;
|
|
15
|
+
/**
|
|
16
|
+
* Mobx store manager provider
|
|
17
|
+
* @constructor
|
|
18
|
+
*/
|
|
19
|
+
declare const StoreManagerProvider: FC<IStoreManagerProvider>;
|
|
20
|
+
declare const useStoreManagerContext: () => Manager;
|
|
21
|
+
export { StoreManagerProvider, StoreManagerContext, useStoreManagerContext };
|
package/lib/context.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
|
+
|
|
9
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Mobx store manager context
|
|
13
|
+
*/
|
|
14
|
+
const StoreManagerContext = React__default["default"].createContext({});
|
|
15
|
+
/**
|
|
16
|
+
* Mobx store manager provider
|
|
17
|
+
* @constructor
|
|
18
|
+
*/
|
|
19
|
+
const StoreManagerProvider = ({ children, storeManager, fallback, shouldInit = false, }) => {
|
|
20
|
+
const [isInit, setInit] = React.useState(!shouldInit);
|
|
21
|
+
React.useEffect(() => {
|
|
22
|
+
if (!shouldInit) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
storeManager
|
|
26
|
+
.init()
|
|
27
|
+
.then(() => setInit(true))
|
|
28
|
+
.catch((e) => {
|
|
29
|
+
console.error('Failed initialized store manager: ', e);
|
|
30
|
+
});
|
|
31
|
+
}, [shouldInit, storeManager]);
|
|
32
|
+
return (React__default["default"].createElement(StoreManagerContext.Provider, { value: storeManager, children: isInit ? children : fallback || children }));
|
|
33
|
+
};
|
|
34
|
+
const useStoreManagerContext = () => React.useContext(StoreManagerContext);
|
|
35
|
+
|
|
36
|
+
exports.StoreManagerContext = StoreManagerContext;
|
|
37
|
+
exports.StoreManagerProvider = StoreManagerProvider;
|
|
38
|
+
exports.useStoreManagerContext = useStoreManagerContext;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from "./types-f2f6b0e4";
|
|
2
|
+
export * from "./context";
|
|
3
|
+
export { default as Manager } from "./manager";
|
|
4
|
+
export { default as onChangeListener } from "./on-change-listener";
|
|
5
|
+
export { default as wakeup } from "./wakeup";
|
|
6
|
+
export { default as withStores } from "./with-stores";
|
|
7
|
+
export { default as MobxLocalStorage } from "./storages/local-storage";
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var context = require('./context.js');
|
|
6
|
+
var manager = require('./manager.js');
|
|
7
|
+
var onChangeListener = require('./on-change-listener.js');
|
|
8
|
+
var wakeup = require('./wakeup.js');
|
|
9
|
+
var withStores = require('./with-stores.js');
|
|
10
|
+
var localStorage = require('./storages/local-storage.js');
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
exports.StoreManagerContext = context.StoreManagerContext;
|
|
15
|
+
exports.StoreManagerProvider = context.StoreManagerProvider;
|
|
16
|
+
exports.useStoreManagerContext = context.useStoreManagerContext;
|
|
17
|
+
exports.Manager = manager;
|
|
18
|
+
exports.onChangeListener = onChangeListener;
|
|
19
|
+
exports.wakeup = wakeup;
|
|
20
|
+
exports.withStores = withStores;
|
|
21
|
+
exports.MobxLocalStorage = localStorage;
|
package/lib/manager.d.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { IConstructableStore, IManagerParams, IStorage, IStore, TStoreDefinition, IManagerOptions, TStores, TInitStore } from "./types-f2f6b0e4";
|
|
2
|
+
/**
|
|
3
|
+
* Mobx stores manager
|
|
4
|
+
*/
|
|
5
|
+
declare class Manager {
|
|
6
|
+
/**
|
|
7
|
+
* Manger instance
|
|
8
|
+
*/
|
|
9
|
+
protected static instance: Manager;
|
|
10
|
+
/**
|
|
11
|
+
* Created stores
|
|
12
|
+
*/
|
|
13
|
+
private readonly stores;
|
|
14
|
+
/**
|
|
15
|
+
* Save persisted stores identities
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
protected static readonly persistedStores: Set<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Initial stores state (local storage, custom etc.)
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
protected readonly initState: Record<string, any>;
|
|
24
|
+
/**
|
|
25
|
+
* Storage for persisted stores
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
readonly storage: IStorage | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Restored persist storage data
|
|
31
|
+
* @protected
|
|
32
|
+
*/
|
|
33
|
+
protected persistData: Record<string, any>;
|
|
34
|
+
/**
|
|
35
|
+
* Additional store's constructor params
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
protected readonly storesParams: IManagerParams['storesParams'];
|
|
39
|
+
/**
|
|
40
|
+
* Manager options
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
readonly options: IManagerOptions;
|
|
44
|
+
/**
|
|
45
|
+
* @constructor
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* @constructor
|
|
49
|
+
*/
|
|
50
|
+
constructor({ initState, storesParams, storage, options }?: IManagerParams);
|
|
51
|
+
/**
|
|
52
|
+
* Init store manager
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* Init store manager
|
|
56
|
+
*/
|
|
57
|
+
init(): Promise<Manager>;
|
|
58
|
+
/**
|
|
59
|
+
* Get manager instance
|
|
60
|
+
* NOTE: Need call 'init' before call this method
|
|
61
|
+
*/
|
|
62
|
+
/**
|
|
63
|
+
* Get manager instance
|
|
64
|
+
* NOTE: Need call 'init' before call this method
|
|
65
|
+
*/
|
|
66
|
+
static get(): Manager;
|
|
67
|
+
/**
|
|
68
|
+
* Get store identity
|
|
69
|
+
* @protected
|
|
70
|
+
*/
|
|
71
|
+
/**
|
|
72
|
+
* Get store identity
|
|
73
|
+
* @protected
|
|
74
|
+
*/
|
|
75
|
+
protected static getStoreKey<T>(store: IConstructableStore<T> | TInitStore, id?: string): string;
|
|
76
|
+
/**
|
|
77
|
+
* Get exist store
|
|
78
|
+
*/
|
|
79
|
+
/**
|
|
80
|
+
* Get exist store
|
|
81
|
+
*/
|
|
82
|
+
getStore<T>(store: IConstructableStore<T>, id?: string): T | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Create new store instance
|
|
85
|
+
* @protected
|
|
86
|
+
*/
|
|
87
|
+
/**
|
|
88
|
+
* Create new store instance
|
|
89
|
+
* @protected
|
|
90
|
+
*/
|
|
91
|
+
protected createStore<T>(store: IConstructableStore<T>, id?: string): T;
|
|
92
|
+
/**
|
|
93
|
+
* Create stores for component
|
|
94
|
+
*/
|
|
95
|
+
/**
|
|
96
|
+
* Create stores for component
|
|
97
|
+
*/
|
|
98
|
+
createStores(map: [string, TStoreDefinition][]): TStores;
|
|
99
|
+
/**
|
|
100
|
+
* Mount stores to component
|
|
101
|
+
*/
|
|
102
|
+
/**
|
|
103
|
+
* Mount stores to component
|
|
104
|
+
*/
|
|
105
|
+
mountStores(stores: TStores): () => void;
|
|
106
|
+
/**
|
|
107
|
+
* Get store's state
|
|
108
|
+
*/
|
|
109
|
+
/**
|
|
110
|
+
* Get store's state
|
|
111
|
+
*/
|
|
112
|
+
toJSON(): Record<string, any>;
|
|
113
|
+
/**
|
|
114
|
+
* Get persisted store's data
|
|
115
|
+
*/
|
|
116
|
+
/**
|
|
117
|
+
* Get persisted store's data
|
|
118
|
+
*/
|
|
119
|
+
toPersistedJSON(): Record<string, any>;
|
|
120
|
+
/**
|
|
121
|
+
* Get observable store props (fields)
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
/**
|
|
125
|
+
* Get observable store props (fields)
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
128
|
+
static getObservableProps(store: IStore): Record<string, any>;
|
|
129
|
+
/**
|
|
130
|
+
* Persist store
|
|
131
|
+
*/
|
|
132
|
+
/**
|
|
133
|
+
* Persist store
|
|
134
|
+
*/
|
|
135
|
+
static persistStore<TSt>(store: IConstructableStore<TSt>, id: string): IConstructableStore<TSt>;
|
|
136
|
+
}
|
|
137
|
+
export { Manager as default };
|
package/lib/manager.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var mobx = require('mobx');
|
|
4
|
+
var onChangeListener = require('./on-change-listener.js');
|
|
5
|
+
var wakeup = require('./wakeup.js');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Mobx stores manager
|
|
9
|
+
*/
|
|
10
|
+
class Manager {
|
|
11
|
+
/**
|
|
12
|
+
* Manger instance
|
|
13
|
+
*/
|
|
14
|
+
static instance;
|
|
15
|
+
/**
|
|
16
|
+
* Created stores
|
|
17
|
+
*/
|
|
18
|
+
stores = new Map();
|
|
19
|
+
/**
|
|
20
|
+
* Save persisted stores identities
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
static persistedStores = new Set();
|
|
24
|
+
/**
|
|
25
|
+
* Initial stores state (local storage, custom etc.)
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
initState;
|
|
29
|
+
/**
|
|
30
|
+
* Storage for persisted stores
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
storage;
|
|
34
|
+
/**
|
|
35
|
+
* Restored persist storage data
|
|
36
|
+
* @protected
|
|
37
|
+
*/
|
|
38
|
+
persistData = {};
|
|
39
|
+
/**
|
|
40
|
+
* Additional store's constructor params
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
storesParams;
|
|
44
|
+
/**
|
|
45
|
+
* Manager options
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
options = {
|
|
49
|
+
shouldDisablePersist: false,
|
|
50
|
+
shouldRemoveInitState: true,
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* @constructor
|
|
54
|
+
*/
|
|
55
|
+
constructor({ initState, storesParams, storage, options } = {}) {
|
|
56
|
+
this.initState = initState || {};
|
|
57
|
+
this.storesParams = storesParams || {};
|
|
58
|
+
this.storage = storage;
|
|
59
|
+
Object.assign(this.options, options || {});
|
|
60
|
+
Manager.instance = this;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Init store manager
|
|
64
|
+
*/
|
|
65
|
+
async init() {
|
|
66
|
+
if (this.storage) {
|
|
67
|
+
this.persistData = (await this.storage.get()) || {};
|
|
68
|
+
}
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get manager instance
|
|
73
|
+
* NOTE: Need call 'init' before call this method
|
|
74
|
+
*/
|
|
75
|
+
static get() {
|
|
76
|
+
if (!Manager.instance) {
|
|
77
|
+
throw new Error('Store manager is not initialized.');
|
|
78
|
+
}
|
|
79
|
+
return Manager.instance;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get store identity
|
|
83
|
+
* @protected
|
|
84
|
+
*/
|
|
85
|
+
static getStoreKey(store, id) {
|
|
86
|
+
return id || store.id || store['name'] || store.constructor.name;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get exist store
|
|
90
|
+
*/
|
|
91
|
+
getStore(store, id) {
|
|
92
|
+
const storeKey = Manager.getStoreKey(store, id);
|
|
93
|
+
if (this.stores.has(storeKey)) {
|
|
94
|
+
return this.stores.get(storeKey);
|
|
95
|
+
}
|
|
96
|
+
// in case get from another store
|
|
97
|
+
if (store.isSingleton) {
|
|
98
|
+
return this.createStore(store, id);
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create new store instance
|
|
104
|
+
* @protected
|
|
105
|
+
*/
|
|
106
|
+
createStore(store, id) {
|
|
107
|
+
const storeKey = Manager.getStoreKey(store, id);
|
|
108
|
+
const existStore = this.stores.get(storeKey);
|
|
109
|
+
if (existStore) {
|
|
110
|
+
return existStore;
|
|
111
|
+
}
|
|
112
|
+
const newStore = new store({ storeManager: this, ...this.storesParams });
|
|
113
|
+
// assign id to new store
|
|
114
|
+
newStore.id = storeKey;
|
|
115
|
+
newStore.isSingleton = store.isSingleton;
|
|
116
|
+
const initState = this.initState[storeKey];
|
|
117
|
+
const persistedState = this.persistData[storeKey];
|
|
118
|
+
if (initState) {
|
|
119
|
+
Object.assign(newStore, initState);
|
|
120
|
+
if (this.options.shouldRemoveInitState) {
|
|
121
|
+
delete this.initState[storeKey];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Detect persisted store and restore state
|
|
125
|
+
if ('wakeup' in newStore && Manager.persistedStores.has(storeKey)) {
|
|
126
|
+
newStore.wakeup?.(newStore, { initState, persistedState });
|
|
127
|
+
newStore.addOnChangeListener?.(newStore, this);
|
|
128
|
+
}
|
|
129
|
+
this.stores.set(storeKey, newStore);
|
|
130
|
+
newStore.init?.();
|
|
131
|
+
return newStore;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Create stores for component
|
|
135
|
+
*/
|
|
136
|
+
createStores(map) {
|
|
137
|
+
return map.reduce((res, [key, store]) => {
|
|
138
|
+
const [s, id] = 'store' in store ? [store.store, store.id] : [store];
|
|
139
|
+
return {
|
|
140
|
+
...res,
|
|
141
|
+
[key]: this.createStore(s, id),
|
|
142
|
+
};
|
|
143
|
+
}, {});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Mount stores to component
|
|
147
|
+
*/
|
|
148
|
+
mountStores(stores) {
|
|
149
|
+
const unmountCallbacks = [];
|
|
150
|
+
Object.values(stores).forEach((store) => {
|
|
151
|
+
if ('onMount' in store) {
|
|
152
|
+
const unsubscribe = store.onMount?.();
|
|
153
|
+
if (typeof unsubscribe === 'function') {
|
|
154
|
+
unmountCallbacks.push(unsubscribe);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if ('onDestroy' in store) {
|
|
158
|
+
unmountCallbacks.push(() => store.onDestroy?.());
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
return () => {
|
|
162
|
+
unmountCallbacks.forEach((callback) => callback());
|
|
163
|
+
Object.values(stores).forEach((store) => {
|
|
164
|
+
const storeKey = Manager.getStoreKey(store);
|
|
165
|
+
if (!store.isSingleton) {
|
|
166
|
+
this.stores.delete(storeKey);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get store's state
|
|
173
|
+
*/
|
|
174
|
+
toJSON() {
|
|
175
|
+
const result = {};
|
|
176
|
+
for (const [storeKey, store] of this.stores.entries()) {
|
|
177
|
+
result[storeKey] = store.toJSON?.() ?? Manager.getObservableProps(store);
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Get persisted store's data
|
|
183
|
+
*/
|
|
184
|
+
toPersistedJSON() {
|
|
185
|
+
const result = {};
|
|
186
|
+
for (const storeKey of Manager.persistedStores) {
|
|
187
|
+
const store = this.stores.get(storeKey);
|
|
188
|
+
if (!store) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
result[storeKey] = store['toJSON']?.() ?? Manager.getObservableProps(store);
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Get observable store props (fields)
|
|
197
|
+
* @private
|
|
198
|
+
*/
|
|
199
|
+
static getObservableProps(store) {
|
|
200
|
+
const props = mobx.toJS(store);
|
|
201
|
+
return Object.entries(props).reduce((res, [prop, value]) => ({
|
|
202
|
+
...res,
|
|
203
|
+
...(mobx.isObservableProp(store, prop) ? { [prop]: value } : {}),
|
|
204
|
+
}), {});
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Persist store
|
|
208
|
+
*/
|
|
209
|
+
static persistStore(store, id) {
|
|
210
|
+
const storeKey = Manager.getStoreKey(store, id);
|
|
211
|
+
if (Manager.persistedStores.has(storeKey)) {
|
|
212
|
+
throw new Error(`Duplicate serializable store key: ${storeKey}`);
|
|
213
|
+
}
|
|
214
|
+
Manager.persistedStores.add(id);
|
|
215
|
+
store.id = storeKey;
|
|
216
|
+
// add default wakeup handler
|
|
217
|
+
if (!('wakeup' in store.prototype)) {
|
|
218
|
+
store.prototype.wakeup = wakeup;
|
|
219
|
+
}
|
|
220
|
+
// add default changes listener
|
|
221
|
+
if (!('addOnChangeListener' in store.prototype)) {
|
|
222
|
+
store.prototype.addOnChangeListener = onChangeListener;
|
|
223
|
+
}
|
|
224
|
+
return store;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
module.exports = Manager;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var mobx = require('mobx');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Listen persist store changes
|
|
7
|
+
*/
|
|
8
|
+
const onChangeListener = (store, manager) => {
|
|
9
|
+
const { shouldDisablePersist } = manager.options;
|
|
10
|
+
if (shouldDisablePersist || !manager.storage) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
return mobx.reaction(() => store.toJSON?.() ?? mobx.toJS(store), () => {
|
|
14
|
+
try {
|
|
15
|
+
manager.storage?.set(manager.toPersistedJSON())?.catch((e) => {
|
|
16
|
+
console.error('Failed to persist stores #1: ', e);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
console.error('Failed to persist stores #2: ', e);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = onChangeListener;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { IStorage } from "../types-f2f6b0e4";
|
|
2
|
+
declare class LocalStorage implements IStorage {
|
|
3
|
+
globalKey: string;
|
|
4
|
+
/**
|
|
5
|
+
* @inheritDoc
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @inheritDoc
|
|
9
|
+
*/
|
|
10
|
+
get(): Record<string, any> | Promise<Record<string, any> | undefined>;
|
|
11
|
+
/**
|
|
12
|
+
* @inheritDoc
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* @inheritDoc
|
|
16
|
+
*/
|
|
17
|
+
flush(): void | Promise<any>;
|
|
18
|
+
/**
|
|
19
|
+
* @inheritDoc
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* @inheritDoc
|
|
23
|
+
*/
|
|
24
|
+
set(value: Record<string, any> | undefined): void;
|
|
25
|
+
}
|
|
26
|
+
export { LocalStorage as default };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
class LocalStorage {
|
|
4
|
+
globalKey = 'stores';
|
|
5
|
+
/**
|
|
6
|
+
* @inheritDoc
|
|
7
|
+
*/
|
|
8
|
+
get() {
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(localStorage.getItem(this.globalKey) || '{}');
|
|
11
|
+
}
|
|
12
|
+
catch (e) {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* @inheritDoc
|
|
18
|
+
*/
|
|
19
|
+
flush() {
|
|
20
|
+
return localStorage.removeItem(this.globalKey);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @inheritDoc
|
|
24
|
+
*/
|
|
25
|
+
set(value) {
|
|
26
|
+
return localStorage.setItem(this.globalKey, JSON.stringify(value || '{}'));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = LocalStorage;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import Manager from "./manager";
|
|
2
|
+
interface IConstructorParams {
|
|
3
|
+
storeManager: Manager;
|
|
4
|
+
}
|
|
5
|
+
interface IStoreLifecycle {
|
|
6
|
+
onDestroy?: () => void;
|
|
7
|
+
onMount?: () => void | (() => void);
|
|
8
|
+
}
|
|
9
|
+
interface IStore extends IStoreLifecycle {
|
|
10
|
+
id?: string;
|
|
11
|
+
isSingleton?: boolean;
|
|
12
|
+
init?: () => void;
|
|
13
|
+
toJSON?: () => Record<string, any>;
|
|
14
|
+
}
|
|
15
|
+
interface IStorePersisted extends IStore {
|
|
16
|
+
addOnChangeListener?: (store: IStorePersisted, manager: Manager) => (() => void) | undefined;
|
|
17
|
+
wakeup?: TWakeup;
|
|
18
|
+
}
|
|
19
|
+
type TInitStore<TSto extends IStore | IStorePersisted = IStore> = TSto & (IStorePersisted | IStore);
|
|
20
|
+
type IConstructableStore<TSto extends IStore = IStore> = (new (props: IConstructorParams) => TInitStore<TSto>) & Partial<IStorePersisted>;
|
|
21
|
+
type TStoreDefinition<TSto extends IStore | IStorePersisted = any> = IConstructableStore<TSto> | {
|
|
22
|
+
store: IConstructableStore<TSto>;
|
|
23
|
+
id: string;
|
|
24
|
+
};
|
|
25
|
+
type TMapStores = Record<string, TStoreDefinition>;
|
|
26
|
+
interface IManagerParams {
|
|
27
|
+
storesParams?: Omit<IConstructorParams, 'storeManager'>;
|
|
28
|
+
storage?: IStorage;
|
|
29
|
+
options?: IManagerOptions;
|
|
30
|
+
initState?: Record<string, any>;
|
|
31
|
+
}
|
|
32
|
+
type TWakeup = (store: IStore, state: {
|
|
33
|
+
initState?: Record<string, any>;
|
|
34
|
+
persistedState?: Record<string, any>;
|
|
35
|
+
}) => void;
|
|
36
|
+
interface IStorage {
|
|
37
|
+
get: () => Record<string, any> | undefined | Promise<Record<string, any> | undefined>;
|
|
38
|
+
set: (value: Record<string, any> | undefined) => Record<string, any> | undefined | Promise<any> | void;
|
|
39
|
+
flush: () => void | Promise<any>;
|
|
40
|
+
}
|
|
41
|
+
interface IManagerOptions {
|
|
42
|
+
shouldDisablePersist?: boolean;
|
|
43
|
+
shouldRemoveInitState?: boolean;
|
|
44
|
+
}
|
|
45
|
+
type TStores = {
|
|
46
|
+
[storeKey: string]: IStore | IStorePersisted;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Convert class type to class constructor
|
|
50
|
+
*/
|
|
51
|
+
type ClassReturnType<T> = T extends new (...args: any) => infer R ? R : never;
|
|
52
|
+
/**
|
|
53
|
+
* Stores map to type
|
|
54
|
+
*/
|
|
55
|
+
type StoresType<TSt> = {
|
|
56
|
+
[keys in keyof TSt]: ClassReturnType<TSt[keys]>;
|
|
57
|
+
};
|
|
58
|
+
export { IConstructorParams, IStoreLifecycle, IStore, IStorePersisted, TInitStore, IConstructableStore, TStoreDefinition, TMapStores, IManagerParams, TWakeup, IStorage, IManagerOptions, TStores, ClassReturnType, StoresType };
|
package/lib/wakeup.d.ts
ADDED
package/lib/wakeup.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { TMapStores } from "./types-f2f6b0e4";
|
|
3
|
+
/**
|
|
4
|
+
* Make component observable and pass stores as props
|
|
5
|
+
*/
|
|
6
|
+
declare const withStores: <T extends Record<string, any>, TS extends TMapStores>(Component: FC<T>, stores: TS) => FC<Omit<T, keyof TS>>;
|
|
7
|
+
export { withStores as default };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var hoistNonReactStatics = require('hoist-non-react-statics');
|
|
4
|
+
var mobxReactLite = require('mobx-react-lite');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var context = require('./context.js');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
|
+
|
|
10
|
+
var hoistNonReactStatics__default = /*#__PURE__*/_interopDefaultLegacy(hoistNonReactStatics);
|
|
11
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Make component observable and pass stores as props
|
|
15
|
+
*/
|
|
16
|
+
const withStores = (Component, stores) => {
|
|
17
|
+
const storesMap = Object.entries(stores);
|
|
18
|
+
const ObservableComponent = mobxReactLite.observer(Component);
|
|
19
|
+
const componentName = Component.displayName || Component.name;
|
|
20
|
+
const Element = ({ ...props }) => {
|
|
21
|
+
const storeManager = context.useStoreManagerContext();
|
|
22
|
+
const [initStores] = React.useState(() => storeManager.createStores(storesMap));
|
|
23
|
+
/**
|
|
24
|
+
* - Check if store has 'onMount' (call if exist)
|
|
25
|
+
* - Check if store has 'onDestroy' method (call if exist)
|
|
26
|
+
*/
|
|
27
|
+
React.useEffect(() => storeManager.mountStores(initStores), [initStores, storeManager]);
|
|
28
|
+
return React__default["default"].createElement(ObservableComponent, { ...initStores, ...props });
|
|
29
|
+
};
|
|
30
|
+
hoistNonReactStatics__default["default"](Element, Component);
|
|
31
|
+
Element.displayName = `Mobx(${componentName})`;
|
|
32
|
+
return Element;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = withStores;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lomray/react-mobx-manager",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.4",
|
|
4
4
|
"description": "This package provides Mobx stores manager for react.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
"homepage": "https://github.com/Lomray-Software/react-mobx-manager",
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "rollup -c",
|
|
34
|
+
"build:dev": "rollup -c --environment BUILD:development",
|
|
35
|
+
"build:watch": "rollup -c -w --environment BUILD:development",
|
|
34
36
|
"prettier:format": "prettier --write 'src/**/*.{ts,tsx,*.ts,*tsx}'",
|
|
35
37
|
"prettier:check": "prettier --check --debug-check 'src/**/*.{ts,tsx,*.ts,*tsx}'",
|
|
36
38
|
"lint:check": "eslint --ext '.ts,.tsx' 'src/**/*.{ts,tsx,*.ts,*tsx}'",
|