@tramvai/state 2.70.0 → 2.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/lib/connect/Provider.es.js +8 -0
  2. package/lib/connect/Provider.js +12 -0
  3. package/lib/connect/Subscription.es.js +37 -0
  4. package/lib/connect/Subscription.js +41 -0
  5. package/lib/connect/connectAdvanced.es.js +159 -0
  6. package/lib/connect/connectAdvanced.js +170 -0
  7. package/lib/connect/context.es.js +6 -0
  8. package/lib/connect/context.js +11 -0
  9. package/lib/connect/hooks/useActions.es.js +17 -0
  10. package/lib/connect/hooks/useActions.js +25 -0
  11. package/lib/connect/hooks/useConsumerContext.es.js +12 -0
  12. package/lib/connect/hooks/useConsumerContext.js +16 -0
  13. package/lib/connect/hooks/useSelector.es.js +53 -0
  14. package/lib/connect/hooks/useSelector.js +63 -0
  15. package/lib/connect/hooks/useStore.es.js +37 -0
  16. package/lib/connect/hooks/useStore.js +41 -0
  17. package/lib/connect/hooks/useStoreSelector.es.js +11 -0
  18. package/lib/connect/hooks/useStoreSelector.js +15 -0
  19. package/lib/connect/index.es.js +91 -0
  20. package/lib/connect/index.js +107 -0
  21. package/lib/connect/scheduling.es.js +12 -0
  22. package/lib/connect/scheduling.js +16 -0
  23. package/lib/connect/selectorFactory.es.js +95 -0
  24. package/lib/connect/selectorFactory.js +101 -0
  25. package/lib/connect/toProps/mapContextToProps.es.js +23 -0
  26. package/lib/connect/toProps/mapContextToProps.js +34 -0
  27. package/lib/connect/toProps/mapStateToProps.es.js +17 -0
  28. package/lib/connect/toProps/mapStateToProps.js +27 -0
  29. package/lib/connect/toProps/mergeProps.es.js +36 -0
  30. package/lib/connect/toProps/mergeProps.js +42 -0
  31. package/lib/connect/toProps/wrapMapToProps.es.js +73 -0
  32. package/lib/connect/toProps/wrapMapToProps.js +85 -0
  33. package/lib/connect/utils/verifyFunction.es.js +10 -0
  34. package/lib/connect/utils/verifyFunction.js +18 -0
  35. package/lib/connect/utils/verifyMapToProps.es.js +20 -0
  36. package/lib/connect/utils/verifyMapToProps.js +28 -0
  37. package/lib/connect/utils/verifyPlainObject.es.js +10 -0
  38. package/lib/connect/utils/verifyPlainObject.js +18 -0
  39. package/lib/createEvent/createEvent.es.js +22 -0
  40. package/lib/createEvent/createEvent.js +31 -0
  41. package/lib/createReducer/createReducer.es.js +60 -0
  42. package/lib/createReducer/createReducer.js +64 -0
  43. package/lib/devTools/constants.es.js +3 -0
  44. package/lib/devTools/constants.js +7 -0
  45. package/lib/{index_middleware.es.js → devTools/devTools.es.js} +2 -36
  46. package/lib/{index_middleware.js → devTools/devTools.js} +4 -40
  47. package/lib/devTools/index.es.js +21 -0
  48. package/lib/devTools/index.js +23 -0
  49. package/lib/devTools/middleware.es.js +37 -0
  50. package/lib/devTools/middleware.js +45 -0
  51. package/lib/dispatcher/childDispatcherContext.es.js +46 -0
  52. package/lib/dispatcher/childDispatcherContext.js +50 -0
  53. package/lib/dispatcher/dispatcher.es.js +105 -0
  54. package/lib/dispatcher/dispatcher.js +110 -0
  55. package/lib/dispatcher/dispatcherContext.es.js +279 -0
  56. package/lib/dispatcher/dispatcherContext.js +288 -0
  57. package/lib/dispatcher/storeSubscribe.es.js +8 -0
  58. package/lib/dispatcher/storeSubscribe.js +12 -0
  59. package/lib/index.es.js +16 -1246
  60. package/lib/index.js +36 -1281
  61. package/lib/logger.es.js +3 -0
  62. package/lib/logger.js +7 -0
  63. package/lib/stores/BaseStore.es.js +53 -0
  64. package/lib/stores/BaseStore.js +61 -0
  65. package/lib/stores/SimpleEmitter.es.js +30 -0
  66. package/lib/stores/SimpleEmitter.js +34 -0
  67. package/package.json +6 -7
@@ -0,0 +1,279 @@
1
+ import compose from '@tinkoff/utils/function/compose';
2
+ import { subscribe } from './storeSubscribe.es.js';
3
+ import { SimpleEmitter } from '../stores/SimpleEmitter.es.js';
4
+
5
+ const eventExecutor = (event, handlerFns) => {
6
+ const keys = Object.keys(handlerFns);
7
+ for (let index = 0; index < keys.length; index++) {
8
+ const storeName = keys[index];
9
+ const handlerFn = handlerFns[storeName];
10
+ if (!handlerFn) {
11
+ throw new Error(`${storeName} does not have a handler for action ${event.type}`);
12
+ }
13
+ handlerFn(event.payload, event.type);
14
+ }
15
+ };
16
+ // Конвертация старого типа экшенов в новый
17
+ const convertAction = (actionOrNameEvent, payload) => {
18
+ if (typeof actionOrNameEvent === 'string') {
19
+ return {
20
+ payload,
21
+ type: actionOrNameEvent,
22
+ error: false,
23
+ };
24
+ }
25
+ return actionOrNameEvent;
26
+ };
27
+ // Это форкнутый вариант dispatchr
28
+ class DispatcherContext extends SimpleEmitter {
29
+ /**
30
+ * @param context The context to be used for store instances
31
+ */
32
+ constructor(dispatcher, context, initialState, middlewares) {
33
+ super();
34
+ this.applyDispatch = (event) => {
35
+ const eventHandlers = this.dispatcher.handlers[event.type] || [];
36
+ if (!eventHandlers.length) {
37
+ if (process.env.NODE_ENV === 'development') {
38
+ console.warn(`
39
+ The event "${event.type}" has been dispatched, but no reducers for this event were registered.
40
+ Have you forgot to register reducer or add event handler in existing reducer?
41
+ `);
42
+ }
43
+ return event.payload;
44
+ }
45
+ this.applyHandlers(event, eventHandlers);
46
+ return event.payload;
47
+ };
48
+ this.dispatcher = dispatcher;
49
+ this.storeInstances = {};
50
+ this.storeUnsubscribeCallbacks = {};
51
+ this.context = context;
52
+ this.dispatcherInterface = {
53
+ getContext: () => this.context,
54
+ getStore: this.getStore.bind(this),
55
+ };
56
+ this.rehydratedStoreState = {};
57
+ this.fullState = {};
58
+ // Заполняем стейт данными
59
+ if (initialState) {
60
+ this.rehydrate(initialState);
61
+ }
62
+ if (middlewares === null || middlewares === void 0 ? void 0 : middlewares.length) {
63
+ this.applyDispatch = this.applyMiddlewares(middlewares);
64
+ }
65
+ // Инцииализируем уже имеющиеся сторы
66
+ Object.keys(this.dispatcher.stores).forEach((store) => {
67
+ this.getStore(store);
68
+ });
69
+ }
70
+ applyMiddlewares(middlewares) {
71
+ let dispatch = (...args) => {
72
+ throw new Error('Dispatching while constructing your middleware is not allowed. Other middleware would not be applied to this dispatch.');
73
+ };
74
+ const api = {
75
+ getState: this.getState.bind(this),
76
+ subscribe: this.subscribe.bind(this),
77
+ dispatch: (...args) => dispatch(...args),
78
+ };
79
+ dispatch = compose(...middlewares.map((middleware) => middleware(api)))(this.applyDispatch);
80
+ return dispatch;
81
+ }
82
+ storeSubscribe(storeName, storeInstance) {
83
+ const subscribeHandler = () => {
84
+ const newState = storeInstance.getState();
85
+ if (newState !== this.fullState[storeName]) {
86
+ this.fullState = {
87
+ ...this.fullState,
88
+ [storeName]: newState,
89
+ };
90
+ this.emit('change');
91
+ }
92
+ };
93
+ subscribe(storeInstance, subscribeHandler);
94
+ const unsubscribe = () => {
95
+ storeInstance.off('change', subscribeHandler);
96
+ };
97
+ this.storeUnsubscribeCallbacks[storeName] = unsubscribe;
98
+ }
99
+ // eslint-disable-next-line max-statements
100
+ getStore(storeClass) {
101
+ let storeClassPrepared;
102
+ let optional = false;
103
+ if (typeof storeClass === 'object') {
104
+ storeClassPrepared = storeClass.store;
105
+ optional = storeClass.optional;
106
+ }
107
+ else {
108
+ storeClassPrepared = storeClass;
109
+ }
110
+ const storeName = this.dispatcher.getStoreName(storeClassPrepared);
111
+ if (!this.storeInstances[storeName]) {
112
+ let Store = this.dispatcher.stores[storeName];
113
+ if (!Store) {
114
+ if (typeof storeClassPrepared === 'function') {
115
+ this.dispatcher.registerStore(storeClassPrepared);
116
+ Store = storeClassPrepared;
117
+ }
118
+ else {
119
+ if (optional) {
120
+ return null;
121
+ }
122
+ throw new Error(`Store ${storeName} was not registered.`);
123
+ }
124
+ }
125
+ const storeInstance = new Store(this.dispatcherInterface);
126
+ this.storeInstances[storeName] = storeInstance;
127
+ if (this.rehydratedStoreState && this.rehydratedStoreState[storeName]) {
128
+ const state = this.rehydratedStoreState[storeName];
129
+ if (storeInstance.rehydrate) {
130
+ storeInstance.rehydrate(state);
131
+ }
132
+ this.rehydratedStoreState[storeName] = null;
133
+ }
134
+ this.storeSubscribe(storeName, storeInstance);
135
+ // TODO: убрать после того отпадёт надобность связывать сторы router и application
136
+ if (Store.dependencies) {
137
+ Store.dependencies.forEach((dependencyStoreClass) => {
138
+ const dependency = this.getStore(dependencyStoreClass);
139
+ subscribe(dependency, () => {
140
+ storeInstance.emit('change');
141
+ });
142
+ });
143
+ }
144
+ }
145
+ return this.storeInstances[storeName];
146
+ }
147
+ /**
148
+ * Dispatches a new action or throws if one is already in progress
149
+ * @param eventOrType Name of the event to be dispatched
150
+ * @param payload Parameters to describe the action
151
+ * @throws {Error} if store has handler registered that does not exist
152
+ */
153
+ dispatch(eventOrType, payload) {
154
+ if (!eventOrType) {
155
+ throw new Error(`eventOrType parameter ${eventOrType} is invalid.`);
156
+ }
157
+ // конвертим старый тип экшенов
158
+ const event = convertAction(eventOrType, payload);
159
+ return this.applyDispatch(event);
160
+ }
161
+ applyHandlers(action, handlers) {
162
+ const handlerFns = {};
163
+ const storeInstanceGet = (store) => {
164
+ if (handlerFns[store.name]) {
165
+ // Don't call the default if the store has an explicit action handler
166
+ return;
167
+ }
168
+ const storeInstance = this.getStore(store.name);
169
+ if (!storeInstance) {
170
+ return;
171
+ }
172
+ if (typeof store.handler === 'function') {
173
+ handlerFns[store.name] = store.handler.bind(storeInstance);
174
+ }
175
+ else {
176
+ if (process.env.NODE_ENV !== 'production') {
177
+ if (!storeInstance[store.handler]) {
178
+ throw new Error(`${store.name} does not have a method called ${store.handler}`);
179
+ }
180
+ }
181
+ handlerFns[store.name] = storeInstance[store.handler].bind(storeInstance);
182
+ }
183
+ };
184
+ const handlersLength = handlers.length;
185
+ for (let index = 0; index < handlersLength; index++) {
186
+ storeInstanceGet(handlers[index]);
187
+ }
188
+ return eventExecutor(action, handlerFns);
189
+ }
190
+ /**
191
+ * Returns a raw data object representation of the current state of the
192
+ * dispatcher and all store instances. If the store implements a shouldDehdyrate
193
+ * function, then it will be called and only dehydrate if the method returns `true`
194
+ * @method dehydrate
195
+ * @returns dehydrated dispatcher data
196
+ */
197
+ dehydrate() {
198
+ const stores = {};
199
+ const keys = Object.keys(this.storeInstances);
200
+ for (let i = 0; i < keys.length; i++) {
201
+ const storeName = keys[i];
202
+ const store = this.storeInstances[storeName];
203
+ if (!store.dehydrate()) {
204
+ continue;
205
+ }
206
+ stores[storeName] = store.dehydrate();
207
+ }
208
+ return {
209
+ stores,
210
+ };
211
+ }
212
+ /**
213
+ * Takes a raw data object and rehydrates the dispatcher and store instances
214
+ * @method rehydrate
215
+ * @param dispatcherState raw state typically retrieved from `dehydrate` method
216
+ */
217
+ rehydrate(dispatcherState) {
218
+ if (dispatcherState.stores) {
219
+ const keys = Object.keys(dispatcherState.stores);
220
+ for (let index = 0; index < keys.length; index++) {
221
+ const storeName = keys[index];
222
+ this.rehydratedStoreState[storeName] = dispatcherState.stores[storeName];
223
+ }
224
+ }
225
+ }
226
+ subscribe(...args) {
227
+ if ('storeName' in args[0]) {
228
+ const reducer = args[0];
229
+ const callback = args[1];
230
+ const reducerInstance = this.getStore(reducer);
231
+ const listener = () => {
232
+ const state = this.getState(reducer);
233
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
234
+ callback(state);
235
+ };
236
+ reducerInstance.on('change', listener);
237
+ return () => {
238
+ reducerInstance.off('change', listener);
239
+ };
240
+ }
241
+ const callback = args[0];
242
+ const listener = () => {
243
+ const state = this.getState();
244
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
245
+ callback(state);
246
+ };
247
+ this.on('change', listener);
248
+ return () => {
249
+ this.off('change', listener);
250
+ };
251
+ }
252
+ getState(reducer) {
253
+ if (reducer) {
254
+ return this.fullState[reducer.storeName];
255
+ }
256
+ return this.fullState;
257
+ }
258
+ // Для отложенной инициализации контекста, в будующем нужно удалить
259
+ setContext(context) {
260
+ this.context = context;
261
+ }
262
+ hasStore(store) {
263
+ return store.storeName in this.storeInstances && this.dispatcher.hasStore(store);
264
+ }
265
+ registerStore(store) {
266
+ this.dispatcher.registerStore(store);
267
+ this.getStore(store);
268
+ }
269
+ unregisterStore(store) {
270
+ const { storeName } = store;
271
+ this.dispatcher.unregisterStore(store);
272
+ this.storeUnsubscribeCallbacks[storeName]();
273
+ delete this.storeUnsubscribeCallbacks[storeName];
274
+ delete this.rehydratedStoreState[storeName];
275
+ delete this.storeInstances[storeName];
276
+ }
277
+ }
278
+
279
+ export { DispatcherContext, convertAction };
@@ -0,0 +1,288 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var compose = require('@tinkoff/utils/function/compose');
6
+ var storeSubscribe = require('./storeSubscribe.js');
7
+ var SimpleEmitter = require('../stores/SimpleEmitter.js');
8
+
9
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
+
11
+ var compose__default = /*#__PURE__*/_interopDefaultLegacy(compose);
12
+
13
+ const eventExecutor = (event, handlerFns) => {
14
+ const keys = Object.keys(handlerFns);
15
+ for (let index = 0; index < keys.length; index++) {
16
+ const storeName = keys[index];
17
+ const handlerFn = handlerFns[storeName];
18
+ if (!handlerFn) {
19
+ throw new Error(`${storeName} does not have a handler for action ${event.type}`);
20
+ }
21
+ handlerFn(event.payload, event.type);
22
+ }
23
+ };
24
+ // Конвертация старого типа экшенов в новый
25
+ const convertAction = (actionOrNameEvent, payload) => {
26
+ if (typeof actionOrNameEvent === 'string') {
27
+ return {
28
+ payload,
29
+ type: actionOrNameEvent,
30
+ error: false,
31
+ };
32
+ }
33
+ return actionOrNameEvent;
34
+ };
35
+ // Это форкнутый вариант dispatchr
36
+ class DispatcherContext extends SimpleEmitter.SimpleEmitter {
37
+ /**
38
+ * @param context The context to be used for store instances
39
+ */
40
+ constructor(dispatcher, context, initialState, middlewares) {
41
+ super();
42
+ this.applyDispatch = (event) => {
43
+ const eventHandlers = this.dispatcher.handlers[event.type] || [];
44
+ if (!eventHandlers.length) {
45
+ if (process.env.NODE_ENV === 'development') {
46
+ console.warn(`
47
+ The event "${event.type}" has been dispatched, but no reducers for this event were registered.
48
+ Have you forgot to register reducer or add event handler in existing reducer?
49
+ `);
50
+ }
51
+ return event.payload;
52
+ }
53
+ this.applyHandlers(event, eventHandlers);
54
+ return event.payload;
55
+ };
56
+ this.dispatcher = dispatcher;
57
+ this.storeInstances = {};
58
+ this.storeUnsubscribeCallbacks = {};
59
+ this.context = context;
60
+ this.dispatcherInterface = {
61
+ getContext: () => this.context,
62
+ getStore: this.getStore.bind(this),
63
+ };
64
+ this.rehydratedStoreState = {};
65
+ this.fullState = {};
66
+ // Заполняем стейт данными
67
+ if (initialState) {
68
+ this.rehydrate(initialState);
69
+ }
70
+ if (middlewares === null || middlewares === void 0 ? void 0 : middlewares.length) {
71
+ this.applyDispatch = this.applyMiddlewares(middlewares);
72
+ }
73
+ // Инцииализируем уже имеющиеся сторы
74
+ Object.keys(this.dispatcher.stores).forEach((store) => {
75
+ this.getStore(store);
76
+ });
77
+ }
78
+ applyMiddlewares(middlewares) {
79
+ let dispatch = (...args) => {
80
+ throw new Error('Dispatching while constructing your middleware is not allowed. Other middleware would not be applied to this dispatch.');
81
+ };
82
+ const api = {
83
+ getState: this.getState.bind(this),
84
+ subscribe: this.subscribe.bind(this),
85
+ dispatch: (...args) => dispatch(...args),
86
+ };
87
+ dispatch = compose__default["default"](...middlewares.map((middleware) => middleware(api)))(this.applyDispatch);
88
+ return dispatch;
89
+ }
90
+ storeSubscribe(storeName, storeInstance) {
91
+ const subscribeHandler = () => {
92
+ const newState = storeInstance.getState();
93
+ if (newState !== this.fullState[storeName]) {
94
+ this.fullState = {
95
+ ...this.fullState,
96
+ [storeName]: newState,
97
+ };
98
+ this.emit('change');
99
+ }
100
+ };
101
+ storeSubscribe.subscribe(storeInstance, subscribeHandler);
102
+ const unsubscribe = () => {
103
+ storeInstance.off('change', subscribeHandler);
104
+ };
105
+ this.storeUnsubscribeCallbacks[storeName] = unsubscribe;
106
+ }
107
+ // eslint-disable-next-line max-statements
108
+ getStore(storeClass) {
109
+ let storeClassPrepared;
110
+ let optional = false;
111
+ if (typeof storeClass === 'object') {
112
+ storeClassPrepared = storeClass.store;
113
+ optional = storeClass.optional;
114
+ }
115
+ else {
116
+ storeClassPrepared = storeClass;
117
+ }
118
+ const storeName = this.dispatcher.getStoreName(storeClassPrepared);
119
+ if (!this.storeInstances[storeName]) {
120
+ let Store = this.dispatcher.stores[storeName];
121
+ if (!Store) {
122
+ if (typeof storeClassPrepared === 'function') {
123
+ this.dispatcher.registerStore(storeClassPrepared);
124
+ Store = storeClassPrepared;
125
+ }
126
+ else {
127
+ if (optional) {
128
+ return null;
129
+ }
130
+ throw new Error(`Store ${storeName} was not registered.`);
131
+ }
132
+ }
133
+ const storeInstance = new Store(this.dispatcherInterface);
134
+ this.storeInstances[storeName] = storeInstance;
135
+ if (this.rehydratedStoreState && this.rehydratedStoreState[storeName]) {
136
+ const state = this.rehydratedStoreState[storeName];
137
+ if (storeInstance.rehydrate) {
138
+ storeInstance.rehydrate(state);
139
+ }
140
+ this.rehydratedStoreState[storeName] = null;
141
+ }
142
+ this.storeSubscribe(storeName, storeInstance);
143
+ // TODO: убрать после того отпадёт надобность связывать сторы router и application
144
+ if (Store.dependencies) {
145
+ Store.dependencies.forEach((dependencyStoreClass) => {
146
+ const dependency = this.getStore(dependencyStoreClass);
147
+ storeSubscribe.subscribe(dependency, () => {
148
+ storeInstance.emit('change');
149
+ });
150
+ });
151
+ }
152
+ }
153
+ return this.storeInstances[storeName];
154
+ }
155
+ /**
156
+ * Dispatches a new action or throws if one is already in progress
157
+ * @param eventOrType Name of the event to be dispatched
158
+ * @param payload Parameters to describe the action
159
+ * @throws {Error} if store has handler registered that does not exist
160
+ */
161
+ dispatch(eventOrType, payload) {
162
+ if (!eventOrType) {
163
+ throw new Error(`eventOrType parameter ${eventOrType} is invalid.`);
164
+ }
165
+ // конвертим старый тип экшенов
166
+ const event = convertAction(eventOrType, payload);
167
+ return this.applyDispatch(event);
168
+ }
169
+ applyHandlers(action, handlers) {
170
+ const handlerFns = {};
171
+ const storeInstanceGet = (store) => {
172
+ if (handlerFns[store.name]) {
173
+ // Don't call the default if the store has an explicit action handler
174
+ return;
175
+ }
176
+ const storeInstance = this.getStore(store.name);
177
+ if (!storeInstance) {
178
+ return;
179
+ }
180
+ if (typeof store.handler === 'function') {
181
+ handlerFns[store.name] = store.handler.bind(storeInstance);
182
+ }
183
+ else {
184
+ if (process.env.NODE_ENV !== 'production') {
185
+ if (!storeInstance[store.handler]) {
186
+ throw new Error(`${store.name} does not have a method called ${store.handler}`);
187
+ }
188
+ }
189
+ handlerFns[store.name] = storeInstance[store.handler].bind(storeInstance);
190
+ }
191
+ };
192
+ const handlersLength = handlers.length;
193
+ for (let index = 0; index < handlersLength; index++) {
194
+ storeInstanceGet(handlers[index]);
195
+ }
196
+ return eventExecutor(action, handlerFns);
197
+ }
198
+ /**
199
+ * Returns a raw data object representation of the current state of the
200
+ * dispatcher and all store instances. If the store implements a shouldDehdyrate
201
+ * function, then it will be called and only dehydrate if the method returns `true`
202
+ * @method dehydrate
203
+ * @returns dehydrated dispatcher data
204
+ */
205
+ dehydrate() {
206
+ const stores = {};
207
+ const keys = Object.keys(this.storeInstances);
208
+ for (let i = 0; i < keys.length; i++) {
209
+ const storeName = keys[i];
210
+ const store = this.storeInstances[storeName];
211
+ if (!store.dehydrate()) {
212
+ continue;
213
+ }
214
+ stores[storeName] = store.dehydrate();
215
+ }
216
+ return {
217
+ stores,
218
+ };
219
+ }
220
+ /**
221
+ * Takes a raw data object and rehydrates the dispatcher and store instances
222
+ * @method rehydrate
223
+ * @param dispatcherState raw state typically retrieved from `dehydrate` method
224
+ */
225
+ rehydrate(dispatcherState) {
226
+ if (dispatcherState.stores) {
227
+ const keys = Object.keys(dispatcherState.stores);
228
+ for (let index = 0; index < keys.length; index++) {
229
+ const storeName = keys[index];
230
+ this.rehydratedStoreState[storeName] = dispatcherState.stores[storeName];
231
+ }
232
+ }
233
+ }
234
+ subscribe(...args) {
235
+ if ('storeName' in args[0]) {
236
+ const reducer = args[0];
237
+ const callback = args[1];
238
+ const reducerInstance = this.getStore(reducer);
239
+ const listener = () => {
240
+ const state = this.getState(reducer);
241
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
242
+ callback(state);
243
+ };
244
+ reducerInstance.on('change', listener);
245
+ return () => {
246
+ reducerInstance.off('change', listener);
247
+ };
248
+ }
249
+ const callback = args[0];
250
+ const listener = () => {
251
+ const state = this.getState();
252
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
253
+ callback(state);
254
+ };
255
+ this.on('change', listener);
256
+ return () => {
257
+ this.off('change', listener);
258
+ };
259
+ }
260
+ getState(reducer) {
261
+ if (reducer) {
262
+ return this.fullState[reducer.storeName];
263
+ }
264
+ return this.fullState;
265
+ }
266
+ // Для отложенной инициализации контекста, в будующем нужно удалить
267
+ setContext(context) {
268
+ this.context = context;
269
+ }
270
+ hasStore(store) {
271
+ return store.storeName in this.storeInstances && this.dispatcher.hasStore(store);
272
+ }
273
+ registerStore(store) {
274
+ this.dispatcher.registerStore(store);
275
+ this.getStore(store);
276
+ }
277
+ unregisterStore(store) {
278
+ const { storeName } = store;
279
+ this.dispatcher.unregisterStore(store);
280
+ this.storeUnsubscribeCallbacks[storeName]();
281
+ delete this.storeUnsubscribeCallbacks[storeName];
282
+ delete this.rehydratedStoreState[storeName];
283
+ delete this.storeInstances[storeName];
284
+ }
285
+ }
286
+
287
+ exports.DispatcherContext = DispatcherContext;
288
+ exports.convertAction = convertAction;
@@ -0,0 +1,8 @@
1
+ const subscribe = (store, handler) => {
2
+ // подписываемся на изменения
3
+ store.on('change', handler);
4
+ // вызываем сразу, чтобы заполнить начальное состояние
5
+ handler();
6
+ };
7
+
8
+ export { subscribe };
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const subscribe = (store, handler) => {
6
+ // подписываемся на изменения
7
+ store.on('change', handler);
8
+ // вызываем сразу, чтобы заполнить начальное состояние
9
+ handler();
10
+ };
11
+
12
+ exports.subscribe = subscribe;