@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,21 @@
1
+ /*
2
+ ### TODO
3
+
4
+ Монорепозиторий экосистемы [redux-devtools](https://github.com/reduxjs/redux-devtools)
5
+
6
+ Пример кастомной [интеграции redux-devtools с mobx](https://github.com/zalmoxisus/mobx-remotedev/blob/master/src/monitorActions.js)
7
+
8
+ Интегрированный в DevTools функционал:
9
+
10
+ 1. Лог экшенов
11
+ 2. Состояние стейта
12
+ 3. Dispatch
13
+ 4. ~~Time Traveling~~
14
+ */
15
+ // eslint-disable-next-line import/no-mutable-exports
16
+ let middleware = () => () => (next) => (event) => next(event);
17
+ if (process.env.NODE_ENV !== 'production') {
18
+ middleware = require('./middleware.es.js').middleware;
19
+ }
20
+
21
+ export { middleware };
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ /*
6
+ ### TODO
7
+
8
+ Монорепозиторий экосистемы [redux-devtools](https://github.com/reduxjs/redux-devtools)
9
+
10
+ Пример кастомной [интеграции redux-devtools с mobx](https://github.com/zalmoxisus/mobx-remotedev/blob/master/src/monitorActions.js)
11
+
12
+ Интегрированный в DevTools функционал:
13
+
14
+ 1. Лог экшенов
15
+ 2. Состояние стейта
16
+ 3. Dispatch
17
+ 4. ~~Time Traveling~~
18
+ */
19
+ // eslint-disable-next-line import/no-mutable-exports
20
+ exports.middleware = () => () => (next) => (event) => next(event);
21
+ if (process.env.NODE_ENV !== 'production') {
22
+ exports.middleware = require('./middleware.js').middleware;
23
+ }
@@ -0,0 +1,37 @@
1
+ import pick from '@tinkoff/utils/object/pick';
2
+ import { devTools } from './devTools.es.js';
3
+ import { DISPATCH } from './constants.es.js';
4
+
5
+ const middleware = ({ pickState } = {}) => (api) => (next) => {
6
+ const getState = pickState && pickState.length ? () => pick(pickState, api.getState()) : api.getState;
7
+ // TODO: типизировать message
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ devTools.subscribe((message) => {
10
+ if (message.type === 'DISPATCH' && message.state) {
11
+ switch (message.payload.type) {
12
+ // TODO: имплементировать все возможные действия из DevTools
13
+ }
14
+ }
15
+ else if (message.type === 'ACTION' && message.payload) {
16
+ try {
17
+ // eslint-disable-next-line no-new-func
18
+ const action = new Function(`return ${message.payload}`)();
19
+ api.dispatch(action);
20
+ }
21
+ catch (e) {
22
+ devTools.error(e.message);
23
+ }
24
+ }
25
+ });
26
+ devTools.init(getState());
27
+ return (event) => {
28
+ const result = next(event);
29
+ devTools.send({
30
+ type: `${DISPATCH} ${event.type}`,
31
+ event,
32
+ }, getState());
33
+ return result;
34
+ };
35
+ };
36
+
37
+ export { middleware };
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var pick = require('@tinkoff/utils/object/pick');
6
+ var devTools = require('./devTools.js');
7
+ var constants = require('./constants.js');
8
+
9
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
+
11
+ var pick__default = /*#__PURE__*/_interopDefaultLegacy(pick);
12
+
13
+ const middleware = ({ pickState } = {}) => (api) => (next) => {
14
+ const getState = pickState && pickState.length ? () => pick__default["default"](pickState, api.getState()) : api.getState;
15
+ // TODO: типизировать message
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ devTools.devTools.subscribe((message) => {
18
+ if (message.type === 'DISPATCH' && message.state) {
19
+ switch (message.payload.type) {
20
+ // TODO: имплементировать все возможные действия из DevTools
21
+ }
22
+ }
23
+ else if (message.type === 'ACTION' && message.payload) {
24
+ try {
25
+ // eslint-disable-next-line no-new-func
26
+ const action = new Function(`return ${message.payload}`)();
27
+ api.dispatch(action);
28
+ }
29
+ catch (e) {
30
+ devTools.devTools.error(e.message);
31
+ }
32
+ }
33
+ });
34
+ devTools.devTools.init(getState());
35
+ return (event) => {
36
+ const result = next(event);
37
+ devTools.devTools.send({
38
+ type: `${constants.DISPATCH} ${event.type}`,
39
+ event,
40
+ }, getState());
41
+ return result;
42
+ };
43
+ };
44
+
45
+ exports.middleware = middleware;
@@ -0,0 +1,46 @@
1
+ import { DispatcherContext } from './dispatcherContext.es.js';
2
+
3
+ class ChildDispatcherContext extends DispatcherContext {
4
+ /**
5
+ * @param context The context to be used for store instances
6
+ */
7
+ constructor({ dispatcher, context, initialState, parentDispatcherContext, middlewares, parentAllowedStores, }) {
8
+ super(dispatcher, context, initialState, middlewares);
9
+ this.allowedParentStores = new Set();
10
+ this.parentDispatcherContext = parentDispatcherContext;
11
+ parentAllowedStores === null || parentAllowedStores === void 0 ? void 0 : parentAllowedStores.forEach((store) => {
12
+ const storeName = this.dispatcher.getStoreName(typeof store === 'object' ? store.store : store);
13
+ this.allowedParentStores.add(storeName);
14
+ // use just storeName to prevent store initialization on the root-app side
15
+ this.getStore({ store: storeName, optional: true });
16
+ });
17
+ }
18
+ getStore(storeClass) {
19
+ let storeClassPrepared;
20
+ if (typeof storeClass === 'object') {
21
+ storeClassPrepared = storeClass.store;
22
+ }
23
+ else {
24
+ storeClassPrepared = storeClass;
25
+ }
26
+ const storeName = this.dispatcher.getStoreName(storeClassPrepared);
27
+ if (this.dispatcher.stores[storeName]) {
28
+ return super.getStore(storeClass);
29
+ }
30
+ if (this.allowedParentStores.has(storeName)) {
31
+ // use just storeName to prevent store initialization on the root-app side
32
+ const storeInstance = this.parentDispatcherContext.getStore({
33
+ store: storeName,
34
+ optional: true,
35
+ });
36
+ if (!storeInstance) {
37
+ return null;
38
+ }
39
+ this.storeSubscribe(storeName, storeInstance);
40
+ return storeInstance;
41
+ }
42
+ return super.getStore(storeClass);
43
+ }
44
+ }
45
+
46
+ export { ChildDispatcherContext };
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var dispatcherContext = require('./dispatcherContext.js');
6
+
7
+ class ChildDispatcherContext extends dispatcherContext.DispatcherContext {
8
+ /**
9
+ * @param context The context to be used for store instances
10
+ */
11
+ constructor({ dispatcher, context, initialState, parentDispatcherContext, middlewares, parentAllowedStores, }) {
12
+ super(dispatcher, context, initialState, middlewares);
13
+ this.allowedParentStores = new Set();
14
+ this.parentDispatcherContext = parentDispatcherContext;
15
+ parentAllowedStores === null || parentAllowedStores === void 0 ? void 0 : parentAllowedStores.forEach((store) => {
16
+ const storeName = this.dispatcher.getStoreName(typeof store === 'object' ? store.store : store);
17
+ this.allowedParentStores.add(storeName);
18
+ // use just storeName to prevent store initialization on the root-app side
19
+ this.getStore({ store: storeName, optional: true });
20
+ });
21
+ }
22
+ getStore(storeClass) {
23
+ let storeClassPrepared;
24
+ if (typeof storeClass === 'object') {
25
+ storeClassPrepared = storeClass.store;
26
+ }
27
+ else {
28
+ storeClassPrepared = storeClass;
29
+ }
30
+ const storeName = this.dispatcher.getStoreName(storeClassPrepared);
31
+ if (this.dispatcher.stores[storeName]) {
32
+ return super.getStore(storeClass);
33
+ }
34
+ if (this.allowedParentStores.has(storeName)) {
35
+ // use just storeName to prevent store initialization on the root-app side
36
+ const storeInstance = this.parentDispatcherContext.getStore({
37
+ store: storeName,
38
+ optional: true,
39
+ });
40
+ if (!storeInstance) {
41
+ return null;
42
+ }
43
+ this.storeSubscribe(storeName, storeInstance);
44
+ return storeInstance;
45
+ }
46
+ return super.getStore(storeClass);
47
+ }
48
+ }
49
+
50
+ exports.ChildDispatcherContext = ChildDispatcherContext;
@@ -0,0 +1,105 @@
1
+ import { DispatcherContext } from './dispatcherContext.es.js';
2
+
3
+ class Dispatcher {
4
+ /**
5
+ * @class Dispatcher
6
+ * @param options Dispatcher options
7
+ * @param options.stores Array of stores to register
8
+ * @constructor
9
+ */
10
+ constructor(options) {
11
+ // eslint-disable-next-line no-param-reassign
12
+ options = options || {};
13
+ // eslint-disable-next-line no-param-reassign
14
+ options.stores = options.stores || [];
15
+ this.stores = {};
16
+ this.handlers = {};
17
+ options.stores.forEach((store) => {
18
+ this.registerStore(store);
19
+ });
20
+ }
21
+ createContext(context, initialState, middlewares) {
22
+ return new DispatcherContext(this, context, initialState, middlewares);
23
+ }
24
+ hasStore(store) {
25
+ return !!this.stores[store.storeName];
26
+ }
27
+ /**
28
+ * Registers a store so that it can handle actions.ß
29
+ * @param store A store class to be registered. The store should have a static
30
+ * `storeName` property so that it can be loaded later.
31
+ * @throws {Error} if store is invalid
32
+ * @throws {Error} if store is already registered
33
+ */
34
+ registerStore(store) {
35
+ const { storeName } = store;
36
+ if (this.stores[storeName]) {
37
+ if (this.stores[storeName] === store) {
38
+ // Store is already registered, nothing to do
39
+ return;
40
+ }
41
+ if (process.env.NODE_ENV !== 'production') {
42
+ throw new Error(`Store with name '${storeName}' has already been registered.
43
+ Make sure you do not have multiple copies of the store installed.
44
+ exist ${this.stores[storeName]}
45
+ try ${store}`);
46
+ }
47
+ }
48
+ this.stores[storeName] = store;
49
+ if (store.handlers) {
50
+ Object.keys(store.handlers).forEach((action) => {
51
+ const handler = store.handlers[action];
52
+ this.registerHandler(action, storeName, handler);
53
+ });
54
+ }
55
+ }
56
+ unregisterStore(store) {
57
+ const { storeName } = store;
58
+ if (!this.stores[storeName]) {
59
+ return;
60
+ }
61
+ delete this.stores[storeName];
62
+ if (store.handlers) {
63
+ Object.keys(store.handlers).forEach((action) => {
64
+ const handler = store.handlers[action];
65
+ this.unregisterHandler(action, storeName, handler);
66
+ });
67
+ }
68
+ }
69
+ /**
70
+ * Gets a name from a store
71
+ * @param {String|Object} store The store name or class from which to extract
72
+ */
73
+ // eslint-disable-next-line class-methods-use-this
74
+ getStoreName(store) {
75
+ if (typeof store === 'string') {
76
+ return store;
77
+ }
78
+ return store.storeName;
79
+ }
80
+ /**
81
+ * Adds a handler function to be called for the given action
82
+ * @param action Name of the action
83
+ * @param name Name of the store that handles the action
84
+ * @param handler The function or name of the method that handles the action
85
+ */
86
+ registerHandler(action, name, handler) {
87
+ this.handlers[action] = this.handlers[action] || [];
88
+ this.handlers[action].push({
89
+ name,
90
+ handler,
91
+ });
92
+ }
93
+ unregisterHandler(action, name, handler) {
94
+ if (Array.isArray(this.handlers[action])) {
95
+ this.handlers[action] = this.handlers[action].filter((actionHandlers) => {
96
+ return !(actionHandlers.name === name && actionHandlers.handler === handler);
97
+ });
98
+ }
99
+ }
100
+ }
101
+ function createDispatcher(options) {
102
+ return new Dispatcher(options);
103
+ }
104
+
105
+ export { Dispatcher, createDispatcher };
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var dispatcherContext = require('./dispatcherContext.js');
6
+
7
+ class Dispatcher {
8
+ /**
9
+ * @class Dispatcher
10
+ * @param options Dispatcher options
11
+ * @param options.stores Array of stores to register
12
+ * @constructor
13
+ */
14
+ constructor(options) {
15
+ // eslint-disable-next-line no-param-reassign
16
+ options = options || {};
17
+ // eslint-disable-next-line no-param-reassign
18
+ options.stores = options.stores || [];
19
+ this.stores = {};
20
+ this.handlers = {};
21
+ options.stores.forEach((store) => {
22
+ this.registerStore(store);
23
+ });
24
+ }
25
+ createContext(context, initialState, middlewares) {
26
+ return new dispatcherContext.DispatcherContext(this, context, initialState, middlewares);
27
+ }
28
+ hasStore(store) {
29
+ return !!this.stores[store.storeName];
30
+ }
31
+ /**
32
+ * Registers a store so that it can handle actions.ß
33
+ * @param store A store class to be registered. The store should have a static
34
+ * `storeName` property so that it can be loaded later.
35
+ * @throws {Error} if store is invalid
36
+ * @throws {Error} if store is already registered
37
+ */
38
+ registerStore(store) {
39
+ const { storeName } = store;
40
+ if (this.stores[storeName]) {
41
+ if (this.stores[storeName] === store) {
42
+ // Store is already registered, nothing to do
43
+ return;
44
+ }
45
+ if (process.env.NODE_ENV !== 'production') {
46
+ throw new Error(`Store with name '${storeName}' has already been registered.
47
+ Make sure you do not have multiple copies of the store installed.
48
+ exist ${this.stores[storeName]}
49
+ try ${store}`);
50
+ }
51
+ }
52
+ this.stores[storeName] = store;
53
+ if (store.handlers) {
54
+ Object.keys(store.handlers).forEach((action) => {
55
+ const handler = store.handlers[action];
56
+ this.registerHandler(action, storeName, handler);
57
+ });
58
+ }
59
+ }
60
+ unregisterStore(store) {
61
+ const { storeName } = store;
62
+ if (!this.stores[storeName]) {
63
+ return;
64
+ }
65
+ delete this.stores[storeName];
66
+ if (store.handlers) {
67
+ Object.keys(store.handlers).forEach((action) => {
68
+ const handler = store.handlers[action];
69
+ this.unregisterHandler(action, storeName, handler);
70
+ });
71
+ }
72
+ }
73
+ /**
74
+ * Gets a name from a store
75
+ * @param {String|Object} store The store name or class from which to extract
76
+ */
77
+ // eslint-disable-next-line class-methods-use-this
78
+ getStoreName(store) {
79
+ if (typeof store === 'string') {
80
+ return store;
81
+ }
82
+ return store.storeName;
83
+ }
84
+ /**
85
+ * Adds a handler function to be called for the given action
86
+ * @param action Name of the action
87
+ * @param name Name of the store that handles the action
88
+ * @param handler The function or name of the method that handles the action
89
+ */
90
+ registerHandler(action, name, handler) {
91
+ this.handlers[action] = this.handlers[action] || [];
92
+ this.handlers[action].push({
93
+ name,
94
+ handler,
95
+ });
96
+ }
97
+ unregisterHandler(action, name, handler) {
98
+ if (Array.isArray(this.handlers[action])) {
99
+ this.handlers[action] = this.handlers[action].filter((actionHandlers) => {
100
+ return !(actionHandlers.name === name && actionHandlers.handler === handler);
101
+ });
102
+ }
103
+ }
104
+ }
105
+ function createDispatcher(options) {
106
+ return new Dispatcher(options);
107
+ }
108
+
109
+ exports.Dispatcher = Dispatcher;
110
+ exports.createDispatcher = createDispatcher;