@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,37 @@
1
+ import { useContext, useRef, useCallback } from 'react';
2
+ import { useSyncExternalStore } from 'use-sync-external-store/shim';
3
+ import { ServerStateContext } from '../context.es.js';
4
+ import { useConsumerContext } from './useConsumerContext.es.js';
5
+
6
+ function useStore(reducer) {
7
+ const context = useConsumerContext();
8
+ const serverState = useContext(ServerStateContext);
9
+ const reducerRef = useRef(reducer);
10
+ const addedReducerRef = useRef(null);
11
+ // если текущий редьюсер не зарегистрирован в диспетчере,
12
+ // регистрируем его вручную, что бы гарантировать работоспособность `context.getState(reducer)`,
13
+ // и сохраняем в `addedReducerRef`, что бы удалить при unmount
14
+ if (!context.hasStore(reducer)) {
15
+ context.registerStore(reducer);
16
+ addedReducerRef.current = reducer.storeName;
17
+ }
18
+ const subscribe = useCallback((reactUpdate) => {
19
+ const unsubscribe = context.subscribe(reducer, reactUpdate);
20
+ // заменяем текущий редьюсер
21
+ reducerRef.current = reducer;
22
+ return () => {
23
+ // гарантируем отписку от обновлений текущего редьюсера,
24
+ // при анмаунте компонента
25
+ unsubscribe();
26
+ // если текущий редьюсер был зарегистрирован в диспетчере в этом хуке,
27
+ // удаляем его из диспетчера
28
+ if (addedReducerRef.current) {
29
+ context.unregisterStore(reducerRef.current);
30
+ addedReducerRef.current = null;
31
+ }
32
+ };
33
+ }, [reducer, context]);
34
+ return useSyncExternalStore(subscribe, () => context.getState(reducer), serverState ? () => serverState[reducer.storeName] : () => context.getState(reducer));
35
+ }
36
+
37
+ export { useStore };
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var React = require('react');
6
+ var shim = require('use-sync-external-store/shim');
7
+ var context = require('../context.js');
8
+ var useConsumerContext = require('./useConsumerContext.js');
9
+
10
+ function useStore(reducer) {
11
+ const context$1 = useConsumerContext.useConsumerContext();
12
+ const serverState = React.useContext(context.ServerStateContext);
13
+ const reducerRef = React.useRef(reducer);
14
+ const addedReducerRef = React.useRef(null);
15
+ // если текущий редьюсер не зарегистрирован в диспетчере,
16
+ // регистрируем его вручную, что бы гарантировать работоспособность `context.getState(reducer)`,
17
+ // и сохраняем в `addedReducerRef`, что бы удалить при unmount
18
+ if (!context$1.hasStore(reducer)) {
19
+ context$1.registerStore(reducer);
20
+ addedReducerRef.current = reducer.storeName;
21
+ }
22
+ const subscribe = React.useCallback((reactUpdate) => {
23
+ const unsubscribe = context$1.subscribe(reducer, reactUpdate);
24
+ // заменяем текущий редьюсер
25
+ reducerRef.current = reducer;
26
+ return () => {
27
+ // гарантируем отписку от обновлений текущего редьюсера,
28
+ // при анмаунте компонента
29
+ unsubscribe();
30
+ // если текущий редьюсер был зарегистрирован в диспетчере в этом хуке,
31
+ // удаляем его из диспетчера
32
+ if (addedReducerRef.current) {
33
+ context$1.unregisterStore(reducerRef.current);
34
+ addedReducerRef.current = null;
35
+ }
36
+ };
37
+ }, [reducer, context$1]);
38
+ return shim.useSyncExternalStore(subscribe, () => context$1.getState(reducer), serverState ? () => serverState[reducer.storeName] : () => context$1.getState(reducer));
39
+ }
40
+
41
+ exports.useStore = useStore;
@@ -0,0 +1,11 @@
1
+ import { useCallback } from 'react';
2
+ import { useSelector } from './useSelector.es.js';
3
+
4
+ const useStoreSelector = (store, selector) => {
5
+ const memoizedSelector = useCallback((stores) => {
6
+ return selector(stores[store.storeName]);
7
+ }, [store, selector]);
8
+ return useSelector(store, memoizedSelector);
9
+ };
10
+
11
+ export { useStoreSelector };
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var React = require('react');
6
+ var useSelector = require('./useSelector.js');
7
+
8
+ const useStoreSelector = (store, selector) => {
9
+ const memoizedSelector = React.useCallback((stores) => {
10
+ return selector(stores[store.storeName]);
11
+ }, [store, selector]);
12
+ return useSelector.useSelector(store, memoizedSelector);
13
+ };
14
+
15
+ exports.useStoreSelector = useStoreSelector;
@@ -0,0 +1,91 @@
1
+ import shallowEqual from '@tinkoff/utils/is/shallowEqual';
2
+ import strictEqual from '@tinkoff/utils/is/strictEqual';
3
+ import { connectAdvanced } from './connectAdvanced.es.js';
4
+ import { mapContextToPropsFactories } from './toProps/mapContextToProps.es.js';
5
+ import { mapStateToPropsFactories } from './toProps/mapStateToProps.es.js';
6
+ import { mergePropsFactories } from './toProps/mergeProps.es.js';
7
+ import { finalPropsSelectorFactory } from './selectorFactory.es.js';
8
+ import { ConnectContext } from './context.es.js';
9
+ import { scheduling } from './scheduling.es.js';
10
+ import 'react/jsx-runtime';
11
+ import 'react';
12
+ import '@tinkoff/utils/is/array';
13
+ export { useIsomorphicLayoutEffect } from '@tinkoff/react-hooks';
14
+ import 'use-sync-external-store/shim';
15
+ import 'invariant';
16
+ import '@tinkoff/utils/array/toArray';
17
+ import 'use-sync-external-store/shim/with-selector';
18
+
19
+ /*
20
+ connect is a facade over connectAdvanced. It turns its args into a compatible
21
+ selectorFactory, which has the signature:
22
+ (dispatch, options) => (nextState, nextOwnProps) => nextFinalProps
23
+
24
+ connect passes its args to connectAdvanced as options, which will in turn pass them to
25
+ selectorFactory each time a Connect component instance is instantiated or hot reloaded.
26
+ selectorFactory returns a final props selector from its mapStateToProps,
27
+ mapStateToPropsFactories, mapContextToProps, mapContextToPropsFactories, mergeProps,
28
+ mergePropsFactories, and pure args.
29
+ The resulting final props selector is called by the Connect component instance whenever
30
+ it receives new props or store state.
31
+ */
32
+ function match(arg, factories, name) {
33
+ for (let i = factories.length - 1; i >= 0; i--) {
34
+ const result = factories[i](arg);
35
+ if (result) {
36
+ return result;
37
+ }
38
+ }
39
+ return (context, options) => {
40
+ throw new Error(`Invalid value of type ${typeof arg} for ${name} argument when connecting component ${options.wrappedComponentName}.`);
41
+ };
42
+ }
43
+ // createConnect with default args builds the 'official' connect behavior. Calling it with
44
+ // different options opens up some testing and extensibility scenarios
45
+ /**
46
+ * @deprecated
47
+ */
48
+ function createConnect({ connectHOC = connectAdvanced, mapStateToPropsFactories: mapStateToPropsFactories$1 = mapStateToPropsFactories, mapContextToPropsFactories: mapContextToPropsFactories$1 = mapContextToPropsFactories, mergePropsFactories: mergePropsFactories$1 = mergePropsFactories, selectorFactory = finalPropsSelectorFactory, schedule = scheduling(), } = {}) {
49
+ return (stores, mapStateToProps, mapContextToProps, mergeProps, { pure = true, areStatesEqual = strictEqual, areOwnPropsEqual = shallowEqual, areStatePropsEqual = shallowEqual, areMergedPropsEqual = shallowEqual, ...extraOptions } = {}
50
+ // eslint-disable-next-line max-params
51
+ ) => {
52
+ // @ts-ignore
53
+ const initMapStateToProps = match(mapStateToProps, mapStateToPropsFactories$1, 'mapStateToProps');
54
+ // @ts-ignore
55
+ const initMapContextToProps = match(mapContextToProps,
56
+ // @ts-ignore
57
+ mapContextToPropsFactories$1, 'mapContextToProps');
58
+ // @ts-ignore
59
+ const initMergeProps = match(mergeProps, mergePropsFactories$1, 'mergeProps');
60
+ return connectHOC(selectorFactory, {
61
+ // @ts-ignore
62
+ stores,
63
+ // passed through to selectorFactory 2
64
+ // @ts-ignore
65
+ initMapStateToProps,
66
+ initMapContextToProps,
67
+ initMergeProps,
68
+ pure,
69
+ areStatesEqual,
70
+ areOwnPropsEqual,
71
+ areStatePropsEqual,
72
+ areMergedPropsEqual,
73
+ schedule,
74
+ // used in error messages
75
+ methodName: 'connect',
76
+ // used to compute Connect's displayName from the wrapped component's displayName.
77
+ getDisplayName: (name) => `Connect(${name})`,
78
+ // if mapStateToProps is falsy, the Connect component doesn't subscribe to store state changes
79
+ shouldHandleStateChanges: stores && stores.length > 0,
80
+ // any extra options args can override defaults of connect or connectAdvanced
81
+ ...extraOptions,
82
+ });
83
+ };
84
+ }
85
+ /**
86
+ * @deprecated
87
+ */
88
+ const connect = /* @__PURE__ */ createConnect();
89
+ const { Consumer } = ConnectContext;
90
+
91
+ export { Consumer, connect, createConnect, connect as default };
@@ -0,0 +1,107 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var shallowEqual = require('@tinkoff/utils/is/shallowEqual');
6
+ var strictEqual = require('@tinkoff/utils/is/strictEqual');
7
+ var connectAdvanced = require('./connectAdvanced.js');
8
+ var mapContextToProps = require('./toProps/mapContextToProps.js');
9
+ var mapStateToProps = require('./toProps/mapStateToProps.js');
10
+ var mergeProps = require('./toProps/mergeProps.js');
11
+ var selectorFactory = require('./selectorFactory.js');
12
+ var context = require('./context.js');
13
+ var scheduling = require('./scheduling.js');
14
+ require('react/jsx-runtime');
15
+ require('react');
16
+ require('@tinkoff/utils/is/array');
17
+ var reactHooks = require('@tinkoff/react-hooks');
18
+ require('use-sync-external-store/shim');
19
+ require('invariant');
20
+ require('@tinkoff/utils/array/toArray');
21
+ require('use-sync-external-store/shim/with-selector');
22
+
23
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
24
+
25
+ var shallowEqual__default = /*#__PURE__*/_interopDefaultLegacy(shallowEqual);
26
+ var strictEqual__default = /*#__PURE__*/_interopDefaultLegacy(strictEqual);
27
+
28
+ /*
29
+ connect is a facade over connectAdvanced. It turns its args into a compatible
30
+ selectorFactory, which has the signature:
31
+ (dispatch, options) => (nextState, nextOwnProps) => nextFinalProps
32
+
33
+ connect passes its args to connectAdvanced as options, which will in turn pass them to
34
+ selectorFactory each time a Connect component instance is instantiated or hot reloaded.
35
+ selectorFactory returns a final props selector from its mapStateToProps,
36
+ mapStateToPropsFactories, mapContextToProps, mapContextToPropsFactories, mergeProps,
37
+ mergePropsFactories, and pure args.
38
+ The resulting final props selector is called by the Connect component instance whenever
39
+ it receives new props or store state.
40
+ */
41
+ function match(arg, factories, name) {
42
+ for (let i = factories.length - 1; i >= 0; i--) {
43
+ const result = factories[i](arg);
44
+ if (result) {
45
+ return result;
46
+ }
47
+ }
48
+ return (context, options) => {
49
+ throw new Error(`Invalid value of type ${typeof arg} for ${name} argument when connecting component ${options.wrappedComponentName}.`);
50
+ };
51
+ }
52
+ // createConnect with default args builds the 'official' connect behavior. Calling it with
53
+ // different options opens up some testing and extensibility scenarios
54
+ /**
55
+ * @deprecated
56
+ */
57
+ function createConnect({ connectHOC = connectAdvanced.connectAdvanced, mapStateToPropsFactories = mapStateToProps.mapStateToPropsFactories, mapContextToPropsFactories = mapContextToProps.mapContextToPropsFactories, mergePropsFactories = mergeProps.mergePropsFactories, selectorFactory: selectorFactory$1 = selectorFactory.finalPropsSelectorFactory, schedule = scheduling.scheduling(), } = {}) {
58
+ return (stores, mapStateToProps, mapContextToProps, mergeProps, { pure = true, areStatesEqual = strictEqual__default["default"], areOwnPropsEqual = shallowEqual__default["default"], areStatePropsEqual = shallowEqual__default["default"], areMergedPropsEqual = shallowEqual__default["default"], ...extraOptions } = {}
59
+ // eslint-disable-next-line max-params
60
+ ) => {
61
+ // @ts-ignore
62
+ const initMapStateToProps = match(mapStateToProps, mapStateToPropsFactories, 'mapStateToProps');
63
+ // @ts-ignore
64
+ const initMapContextToProps = match(mapContextToProps,
65
+ // @ts-ignore
66
+ mapContextToPropsFactories, 'mapContextToProps');
67
+ // @ts-ignore
68
+ const initMergeProps = match(mergeProps, mergePropsFactories, 'mergeProps');
69
+ return connectHOC(selectorFactory$1, {
70
+ // @ts-ignore
71
+ stores,
72
+ // passed through to selectorFactory 2
73
+ // @ts-ignore
74
+ initMapStateToProps,
75
+ initMapContextToProps,
76
+ initMergeProps,
77
+ pure,
78
+ areStatesEqual,
79
+ areOwnPropsEqual,
80
+ areStatePropsEqual,
81
+ areMergedPropsEqual,
82
+ schedule,
83
+ // used in error messages
84
+ methodName: 'connect',
85
+ // used to compute Connect's displayName from the wrapped component's displayName.
86
+ getDisplayName: (name) => `Connect(${name})`,
87
+ // if mapStateToProps is falsy, the Connect component doesn't subscribe to store state changes
88
+ shouldHandleStateChanges: stores && stores.length > 0,
89
+ // any extra options args can override defaults of connect or connectAdvanced
90
+ ...extraOptions,
91
+ });
92
+ };
93
+ }
94
+ /**
95
+ * @deprecated
96
+ */
97
+ const connect = /* @__PURE__ */ createConnect();
98
+ const { Consumer } = context.ConnectContext;
99
+
100
+ Object.defineProperty(exports, 'useIsomorphicLayoutEffect', {
101
+ enumerable: true,
102
+ get: function () { return reactHooks.useIsomorphicLayoutEffect; }
103
+ });
104
+ exports.Consumer = Consumer;
105
+ exports.connect = connect;
106
+ exports.createConnect = createConnect;
107
+ exports["default"] = connect;
@@ -0,0 +1,12 @@
1
+ const contextExecution = typeof window !== 'undefined' ? window : global;
2
+ function scheduling() {
3
+ if ('requestAnimationFrame' in contextExecution) {
4
+ return requestAnimationFrame;
5
+ }
6
+ if ('setImmediate' in contextExecution) {
7
+ return contextExecution.setImmediate;
8
+ }
9
+ return setTimeout;
10
+ }
11
+
12
+ export { scheduling };
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const contextExecution = typeof window !== 'undefined' ? window : global;
6
+ function scheduling() {
7
+ if ('requestAnimationFrame' in contextExecution) {
8
+ return requestAnimationFrame;
9
+ }
10
+ if ('setImmediate' in contextExecution) {
11
+ return contextExecution.setImmediate;
12
+ }
13
+ return setTimeout;
14
+ }
15
+
16
+ exports.scheduling = scheduling;
@@ -0,0 +1,95 @@
1
+ import { verifyMapToProps } from './utils/verifyMapToProps.es.js';
2
+
3
+ function impureFinalPropsSelectorFactory(mapStateToProps, mapContextToProps, mergeProps, context) {
4
+ return function impureFinalPropsSelector(state, ownProps) {
5
+ return mergeProps(mapStateToProps(state, ownProps), mapContextToProps(context, ownProps), ownProps);
6
+ };
7
+ }
8
+ // eslint-disable-next-line max-params
9
+ function pureFinalPropsSelectorFactory(mapStateToProps, mapContextToProps, mergeProps, context, { areStatesEqual, areOwnPropsEqual, areStatePropsEqual, WrappedComponent: { defaultProps } }) {
10
+ let hasRunAtLeastOnce = false;
11
+ let state;
12
+ let ownProps;
13
+ let ownPropsWithDefault;
14
+ let stateProps;
15
+ let contextProps;
16
+ let mergedProps;
17
+ function handleFirstCall(firstState, firstOwnProps) {
18
+ state = firstState;
19
+ ownProps = firstOwnProps;
20
+ ownPropsWithDefault = { ...defaultProps, ...firstOwnProps }; // TODO проверить зачем мержить пропсы с defaultProps, взято из старого connect, иначе падают некоторые тесты
21
+ stateProps = mapStateToProps(state, ownPropsWithDefault);
22
+ contextProps = mapContextToProps(context, ownPropsWithDefault);
23
+ mergedProps = mergeProps(stateProps, contextProps, ownProps);
24
+ hasRunAtLeastOnce = true;
25
+ return mergedProps;
26
+ }
27
+ function handleNewPropsAndNewState() {
28
+ stateProps = mapStateToProps(state, ownPropsWithDefault);
29
+ if (mapContextToProps.dependsOnOwnProps) {
30
+ contextProps = mapContextToProps(context, ownPropsWithDefault);
31
+ }
32
+ mergedProps = mergeProps(stateProps, contextProps, ownProps);
33
+ return mergedProps;
34
+ }
35
+ function handleNewProps() {
36
+ if (mapStateToProps.dependsOnOwnProps) {
37
+ stateProps = mapStateToProps(state, ownPropsWithDefault);
38
+ }
39
+ if (mapContextToProps.dependsOnOwnProps) {
40
+ contextProps = mapContextToProps(context, ownPropsWithDefault);
41
+ }
42
+ mergedProps = mergeProps(stateProps, contextProps, ownProps);
43
+ return mergedProps;
44
+ }
45
+ function handleNewState() {
46
+ const nextStateProps = mapStateToProps(state, ownPropsWithDefault);
47
+ const statePropsChanged = !areStatePropsEqual(nextStateProps, stateProps);
48
+ stateProps = nextStateProps;
49
+ if (statePropsChanged) {
50
+ mergedProps = mergeProps(stateProps, contextProps, ownProps);
51
+ }
52
+ return mergedProps;
53
+ }
54
+ function handleSubsequentCalls(nextState, nextOwnProps) {
55
+ const propsChanged = !areOwnPropsEqual(nextOwnProps, ownProps);
56
+ const stateChanged = !areStatesEqual(nextState, state);
57
+ state = nextState;
58
+ ownProps = nextOwnProps;
59
+ ownPropsWithDefault = { ...defaultProps, ...nextOwnProps };
60
+ if (propsChanged && stateChanged) {
61
+ return handleNewPropsAndNewState();
62
+ }
63
+ if (propsChanged) {
64
+ return handleNewProps();
65
+ }
66
+ if (stateChanged) {
67
+ return handleNewState();
68
+ }
69
+ return mergedProps;
70
+ }
71
+ return function pureFinalPropsSelector(nextState, nextOwnProps) {
72
+ return hasRunAtLeastOnce
73
+ ? handleSubsequentCalls(nextState, nextOwnProps)
74
+ : handleFirstCall(nextState, nextOwnProps);
75
+ };
76
+ }
77
+ // TODO: Add more comments
78
+ // If pure is true, the selector returned by selectorFactory will memoize its results,
79
+ // allowing connectAdvanced's shouldComponentUpdate to return false if final
80
+ // props have not changed. If false, the selector will always return a new
81
+ // object and shouldComponentUpdate will always return true.
82
+ function finalPropsSelectorFactory(context, { initMapStateToProps, initMapContextToProps, initMergeProps, ...options }) {
83
+ let mapStateToProps = initMapStateToProps(context, options);
84
+ const mapContextToProps = initMapContextToProps(context, options);
85
+ const mergeProps = initMergeProps(context, options);
86
+ if (process.env.NODE_ENV !== 'production') {
87
+ mapStateToProps = verifyMapToProps(mapStateToProps, options.WrappedComponent.name);
88
+ }
89
+ const selectorFactory = options.pure
90
+ ? pureFinalPropsSelectorFactory
91
+ : impureFinalPropsSelectorFactory;
92
+ return selectorFactory(mapStateToProps, mapContextToProps, mergeProps, context, options);
93
+ }
94
+
95
+ export { finalPropsSelectorFactory, impureFinalPropsSelectorFactory, pureFinalPropsSelectorFactory };
@@ -0,0 +1,101 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var verifyMapToProps = require('./utils/verifyMapToProps.js');
6
+
7
+ function impureFinalPropsSelectorFactory(mapStateToProps, mapContextToProps, mergeProps, context) {
8
+ return function impureFinalPropsSelector(state, ownProps) {
9
+ return mergeProps(mapStateToProps(state, ownProps), mapContextToProps(context, ownProps), ownProps);
10
+ };
11
+ }
12
+ // eslint-disable-next-line max-params
13
+ function pureFinalPropsSelectorFactory(mapStateToProps, mapContextToProps, mergeProps, context, { areStatesEqual, areOwnPropsEqual, areStatePropsEqual, WrappedComponent: { defaultProps } }) {
14
+ let hasRunAtLeastOnce = false;
15
+ let state;
16
+ let ownProps;
17
+ let ownPropsWithDefault;
18
+ let stateProps;
19
+ let contextProps;
20
+ let mergedProps;
21
+ function handleFirstCall(firstState, firstOwnProps) {
22
+ state = firstState;
23
+ ownProps = firstOwnProps;
24
+ ownPropsWithDefault = { ...defaultProps, ...firstOwnProps }; // TODO проверить зачем мержить пропсы с defaultProps, взято из старого connect, иначе падают некоторые тесты
25
+ stateProps = mapStateToProps(state, ownPropsWithDefault);
26
+ contextProps = mapContextToProps(context, ownPropsWithDefault);
27
+ mergedProps = mergeProps(stateProps, contextProps, ownProps);
28
+ hasRunAtLeastOnce = true;
29
+ return mergedProps;
30
+ }
31
+ function handleNewPropsAndNewState() {
32
+ stateProps = mapStateToProps(state, ownPropsWithDefault);
33
+ if (mapContextToProps.dependsOnOwnProps) {
34
+ contextProps = mapContextToProps(context, ownPropsWithDefault);
35
+ }
36
+ mergedProps = mergeProps(stateProps, contextProps, ownProps);
37
+ return mergedProps;
38
+ }
39
+ function handleNewProps() {
40
+ if (mapStateToProps.dependsOnOwnProps) {
41
+ stateProps = mapStateToProps(state, ownPropsWithDefault);
42
+ }
43
+ if (mapContextToProps.dependsOnOwnProps) {
44
+ contextProps = mapContextToProps(context, ownPropsWithDefault);
45
+ }
46
+ mergedProps = mergeProps(stateProps, contextProps, ownProps);
47
+ return mergedProps;
48
+ }
49
+ function handleNewState() {
50
+ const nextStateProps = mapStateToProps(state, ownPropsWithDefault);
51
+ const statePropsChanged = !areStatePropsEqual(nextStateProps, stateProps);
52
+ stateProps = nextStateProps;
53
+ if (statePropsChanged) {
54
+ mergedProps = mergeProps(stateProps, contextProps, ownProps);
55
+ }
56
+ return mergedProps;
57
+ }
58
+ function handleSubsequentCalls(nextState, nextOwnProps) {
59
+ const propsChanged = !areOwnPropsEqual(nextOwnProps, ownProps);
60
+ const stateChanged = !areStatesEqual(nextState, state);
61
+ state = nextState;
62
+ ownProps = nextOwnProps;
63
+ ownPropsWithDefault = { ...defaultProps, ...nextOwnProps };
64
+ if (propsChanged && stateChanged) {
65
+ return handleNewPropsAndNewState();
66
+ }
67
+ if (propsChanged) {
68
+ return handleNewProps();
69
+ }
70
+ if (stateChanged) {
71
+ return handleNewState();
72
+ }
73
+ return mergedProps;
74
+ }
75
+ return function pureFinalPropsSelector(nextState, nextOwnProps) {
76
+ return hasRunAtLeastOnce
77
+ ? handleSubsequentCalls(nextState, nextOwnProps)
78
+ : handleFirstCall(nextState, nextOwnProps);
79
+ };
80
+ }
81
+ // TODO: Add more comments
82
+ // If pure is true, the selector returned by selectorFactory will memoize its results,
83
+ // allowing connectAdvanced's shouldComponentUpdate to return false if final
84
+ // props have not changed. If false, the selector will always return a new
85
+ // object and shouldComponentUpdate will always return true.
86
+ function finalPropsSelectorFactory(context, { initMapStateToProps, initMapContextToProps, initMergeProps, ...options }) {
87
+ let mapStateToProps = initMapStateToProps(context, options);
88
+ const mapContextToProps = initMapContextToProps(context, options);
89
+ const mergeProps = initMergeProps(context, options);
90
+ if (process.env.NODE_ENV !== 'production') {
91
+ mapStateToProps = verifyMapToProps.verifyMapToProps(mapStateToProps, options.WrappedComponent.name);
92
+ }
93
+ const selectorFactory = options.pure
94
+ ? pureFinalPropsSelectorFactory
95
+ : impureFinalPropsSelectorFactory;
96
+ return selectorFactory(mapStateToProps, mapContextToProps, mergeProps, context, options);
97
+ }
98
+
99
+ exports.finalPropsSelectorFactory = finalPropsSelectorFactory;
100
+ exports.impureFinalPropsSelectorFactory = impureFinalPropsSelectorFactory;
101
+ exports.pureFinalPropsSelectorFactory = pureFinalPropsSelectorFactory;
@@ -0,0 +1,23 @@
1
+ import always from '@tinkoff/utils/function/always';
2
+ import { wrapMapToPropsFunc, wrapMapToPropsConstant, wrapMapToPropsObject } from './wrapMapToProps.es.js';
3
+
4
+ function whenMapContextToPropsIsFunction(mapContextToProps) {
5
+ return typeof mapContextToProps === 'function'
6
+ ? wrapMapToPropsFunc(mapContextToProps, 'mapContextToProps')
7
+ : undefined;
8
+ }
9
+ function whenMapContextToPropsIsMissing(mapContextToProps) {
10
+ return !mapContextToProps ? wrapMapToPropsConstant(always({})) : undefined;
11
+ }
12
+ function whenMapContextToPropsIsObject(mapContextToProps) {
13
+ return typeof mapContextToProps === 'object' && mapContextToProps !== null
14
+ ? wrapMapToPropsObject(mapContextToProps)
15
+ : undefined;
16
+ }
17
+ const mapContextToPropsFactories = [
18
+ whenMapContextToPropsIsObject,
19
+ whenMapContextToPropsIsFunction,
20
+ whenMapContextToPropsIsMissing,
21
+ ];
22
+
23
+ export { mapContextToPropsFactories, whenMapContextToPropsIsFunction, whenMapContextToPropsIsMissing, whenMapContextToPropsIsObject };
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var always = require('@tinkoff/utils/function/always');
6
+ var wrapMapToProps = require('./wrapMapToProps.js');
7
+
8
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
+
10
+ var always__default = /*#__PURE__*/_interopDefaultLegacy(always);
11
+
12
+ function whenMapContextToPropsIsFunction(mapContextToProps) {
13
+ return typeof mapContextToProps === 'function'
14
+ ? wrapMapToProps.wrapMapToPropsFunc(mapContextToProps, 'mapContextToProps')
15
+ : undefined;
16
+ }
17
+ function whenMapContextToPropsIsMissing(mapContextToProps) {
18
+ return !mapContextToProps ? wrapMapToProps.wrapMapToPropsConstant(always__default["default"]({})) : undefined;
19
+ }
20
+ function whenMapContextToPropsIsObject(mapContextToProps) {
21
+ return typeof mapContextToProps === 'object' && mapContextToProps !== null
22
+ ? wrapMapToProps.wrapMapToPropsObject(mapContextToProps)
23
+ : undefined;
24
+ }
25
+ const mapContextToPropsFactories = [
26
+ whenMapContextToPropsIsObject,
27
+ whenMapContextToPropsIsFunction,
28
+ whenMapContextToPropsIsMissing,
29
+ ];
30
+
31
+ exports.mapContextToPropsFactories = mapContextToPropsFactories;
32
+ exports.whenMapContextToPropsIsFunction = whenMapContextToPropsIsFunction;
33
+ exports.whenMapContextToPropsIsMissing = whenMapContextToPropsIsMissing;
34
+ exports.whenMapContextToPropsIsObject = whenMapContextToPropsIsObject;
@@ -0,0 +1,17 @@
1
+ import always from '@tinkoff/utils/function/always';
2
+ import { wrapMapToPropsFunc, wrapMapToPropsConstant } from './wrapMapToProps.es.js';
3
+
4
+ function whenMapStateToPropsIsFunction(mapStateToProps) {
5
+ return typeof mapStateToProps === 'function'
6
+ ? wrapMapToPropsFunc(mapStateToProps, 'mapStateToProps')
7
+ : undefined;
8
+ }
9
+ function whenMapStateToPropsIsMissing(mapStateToProps) {
10
+ return !mapStateToProps ? wrapMapToPropsConstant(always({})) : undefined;
11
+ }
12
+ const mapStateToPropsFactories = [
13
+ whenMapStateToPropsIsFunction,
14
+ whenMapStateToPropsIsMissing,
15
+ ];
16
+
17
+ export { mapStateToPropsFactories, whenMapStateToPropsIsFunction, whenMapStateToPropsIsMissing };
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var always = require('@tinkoff/utils/function/always');
6
+ var wrapMapToProps = require('./wrapMapToProps.js');
7
+
8
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
+
10
+ var always__default = /*#__PURE__*/_interopDefaultLegacy(always);
11
+
12
+ function whenMapStateToPropsIsFunction(mapStateToProps) {
13
+ return typeof mapStateToProps === 'function'
14
+ ? wrapMapToProps.wrapMapToPropsFunc(mapStateToProps, 'mapStateToProps')
15
+ : undefined;
16
+ }
17
+ function whenMapStateToPropsIsMissing(mapStateToProps) {
18
+ return !mapStateToProps ? wrapMapToProps.wrapMapToPropsConstant(always__default["default"]({})) : undefined;
19
+ }
20
+ const mapStateToPropsFactories = [
21
+ whenMapStateToPropsIsFunction,
22
+ whenMapStateToPropsIsMissing,
23
+ ];
24
+
25
+ exports.mapStateToPropsFactories = mapStateToPropsFactories;
26
+ exports.whenMapStateToPropsIsFunction = whenMapStateToPropsIsFunction;
27
+ exports.whenMapStateToPropsIsMissing = whenMapStateToPropsIsMissing;