@ordergroove/offers 2.40.2 → 2.40.4-alpha-PR-1091-3.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.
- package/CHANGELOG.md +11 -0
- package/dist/bundle-report.html +15 -12
- package/dist/offers.js +35 -35
- package/dist/offers.js.map +4 -4
- package/package.json +2 -2
- package/src/core/__tests__/actions.spec.js +1 -43
- package/src/core/__tests__/localStorage.spec.js +14 -0
- package/src/core/__tests__/offerRequest.spec.js +81 -0
- package/src/core/actions.js +1 -20
- package/src/core/experiments.js +23 -12
- package/src/core/localStorage.js +7 -0
- package/src/core/offerRequest.js +96 -0
- package/src/core/reducer.js +1 -1
- package/src/core/store.js +15 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ordergroove/offers",
|
|
3
|
-
"version": "2.40.
|
|
3
|
+
"version": "2.40.4-alpha-PR-1091-3.0+b3ec3088",
|
|
4
4
|
"description": "offer state component",
|
|
5
5
|
"author": "Eugenio Lattanzio <eugenio63@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/ordergroove/plush-toys#readme",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"@ordergroove/offers-templates": "^0.9.6",
|
|
50
50
|
"@types/lodash.memoize": "^4.1.9"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "b3ec3088230992d2339dd18c604084b6f4cd2044"
|
|
53
53
|
}
|
|
@@ -157,49 +157,7 @@ describe('redux actions', function () {
|
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
it('fetchOffer should return a function', () => {
|
|
160
|
-
expect(fetchOffer()).toEqual(
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('should call api.fetchOffer with environment.apiUrl from state as first param ', async () => {
|
|
164
|
-
const state = {
|
|
165
|
-
merchantId: 'the merchantId',
|
|
166
|
-
sessionId: 'the sessionId',
|
|
167
|
-
environment: { apiUrl: 'the environment.apiUrl' }
|
|
168
|
-
};
|
|
169
|
-
const getState = jasmine.createSpy('getState').and.returnValue(state);
|
|
170
|
-
const fetchOfferSpy = spyOn(api, 'fetchOffer').and.resolveTo({ hey: 'ho' });
|
|
171
|
-
await fetchOffer('the product')(this.dispatch, getState);
|
|
172
|
-
expect(fetchOfferSpy).toHaveBeenCalledWith(
|
|
173
|
-
'the environment.apiUrl',
|
|
174
|
-
'the merchantId',
|
|
175
|
-
'the sessionId',
|
|
176
|
-
'the product',
|
|
177
|
-
'pdp',
|
|
178
|
-
state
|
|
179
|
-
);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it('should dispatch the receiveOffer if api returns', async () => {
|
|
183
|
-
const fetchOfferSpy = spyOn(api, 'fetchOffer').and.resolveTo({ hey: 'ho' });
|
|
184
|
-
|
|
185
|
-
await fetchOffer('yum product')(this.dispatch, this.getState);
|
|
186
|
-
|
|
187
|
-
expect(this.dispatch.calls.count()).toEqual(3);
|
|
188
|
-
expect(this.dispatch.calls.argsFor(0)[0]).toEqual(requestOffer('yum product', 'pdp'));
|
|
189
|
-
expect(this.dispatch.calls.argsFor(1)[0]).toEqual(receiveOffer({ hey: 'ho' }));
|
|
190
|
-
expect(this.getState).toHaveBeenCalled();
|
|
191
|
-
expect(fetchOfferSpy).toHaveBeenCalledWith('some-apiUrl', 'foo', 'bar', 'yum product', 'pdp', theState);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('should dispatch fetchResponseError if api fails', async () => {
|
|
195
|
-
const fetchOfferSpy = spyOn(api, 'fetchOffer').and.rejectWith(Error({ hey: 'ho' }));
|
|
196
|
-
await fetchOffer('yum product')(this.dispatch, this.getState);
|
|
197
|
-
|
|
198
|
-
expect(this.dispatch.calls.count()).toEqual(3);
|
|
199
|
-
expect(this.dispatch.calls.argsFor(0)[0]).toEqual(requestOffer('yum product', 'pdp'));
|
|
200
|
-
expect(this.dispatch.calls.argsFor(1)[0]).toEqual(fetchResponseError(Error({ hey: 'ho' })));
|
|
201
|
-
expect(fetchOfferSpy).toHaveBeenCalledWith('some-apiUrl', 'foo', 'bar', 'yum product', 'pdp', theState);
|
|
202
|
-
expect(this.getState).toHaveBeenCalled();
|
|
160
|
+
expect(fetchOffer()).toEqual(requestOffer());
|
|
203
161
|
});
|
|
204
162
|
});
|
|
205
163
|
|
|
@@ -60,6 +60,7 @@ describe('loadState', () => {
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
it('should load empty object if preview mode', () => {
|
|
63
|
+
window.og = window.og || {};
|
|
63
64
|
const tmp = window.og.previewMode;
|
|
64
65
|
window.og.previewMode = true;
|
|
65
66
|
expect(loadState()).toEqual({});
|
|
@@ -68,10 +69,21 @@ describe('loadState', () => {
|
|
|
68
69
|
});
|
|
69
70
|
|
|
70
71
|
describe('saveState', () => {
|
|
72
|
+
let cookieSpy;
|
|
71
73
|
let getItemSpy, setItemSpy;
|
|
72
74
|
beforeEach(() => {
|
|
73
75
|
getItemSpy = spyOn(Object.getPrototypeOf(localStorage), 'getItem');
|
|
74
76
|
setItemSpy = spyOn(Object.getPrototypeOf(localStorage), 'setItem');
|
|
77
|
+
cookieSpy = '';
|
|
78
|
+
Object.defineProperty(document, 'cookie', {
|
|
79
|
+
get: function () {
|
|
80
|
+
return cookieSpy;
|
|
81
|
+
},
|
|
82
|
+
set: function (value) {
|
|
83
|
+
cookieSpy = value;
|
|
84
|
+
},
|
|
85
|
+
configurable: true // Ensure property can be redefined in future tests
|
|
86
|
+
});
|
|
75
87
|
});
|
|
76
88
|
|
|
77
89
|
it('should not save empty state', function () {
|
|
@@ -83,6 +95,7 @@ describe('saveState', () => {
|
|
|
83
95
|
it('should not save if same state', function () {
|
|
84
96
|
getItemSpy.and.returnValue(JSON.stringify({ sessionId: 'yum' }));
|
|
85
97
|
saveState({ sessionId: 'yum' });
|
|
98
|
+
expect(cookieSpy).toEqual('og_session_id=yum; path=/; expires=Fri, 31 Dec 9999 23:59:59 GMT; SameSite=Lax');
|
|
86
99
|
expect(getItemSpy).toHaveBeenCalledWith(STORE_ROOT);
|
|
87
100
|
expect(setItemSpy).not.toHaveBeenCalled();
|
|
88
101
|
});
|
|
@@ -90,6 +103,7 @@ describe('saveState', () => {
|
|
|
90
103
|
it('should save if different state', function () {
|
|
91
104
|
const payload = { sessionId: 'yum' };
|
|
92
105
|
saveState(payload);
|
|
106
|
+
expect(cookieSpy).toEqual('og_session_id=yum; path=/; expires=Fri, 31 Dec 9999 23:59:59 GMT; SameSite=Lax');
|
|
93
107
|
expect(getItemSpy).toHaveBeenCalledWith(STORE_ROOT);
|
|
94
108
|
expect(setItemSpy).toHaveBeenCalledWith(STORE_ROOT, JSON.stringify({ sessionId: 'yum' }));
|
|
95
109
|
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { offerRequestMiddleware } from '../offerRequest';
|
|
2
|
+
|
|
3
|
+
import { environment, merchantId, offer, sessionId } from '../reducer';
|
|
4
|
+
import { requestOffer } from '../actions';
|
|
5
|
+
import { createStore, combineReducers, applyMiddleware } from 'redux';
|
|
6
|
+
import { FETCH_RESPONSE_ERROR } from '../constants';
|
|
7
|
+
|
|
8
|
+
const mockOfferResponse = (productId, inStock = true, autoship = true, defaultFrequency) => {
|
|
9
|
+
return Promise.resolve({
|
|
10
|
+
json() {
|
|
11
|
+
return Promise.resolve({
|
|
12
|
+
in_stock: { [productId]: inStock },
|
|
13
|
+
eligibility_groups: { [productId]: ['subscription', 'upsell'] },
|
|
14
|
+
result: 'success',
|
|
15
|
+
autoship: { [productId]: autoship },
|
|
16
|
+
autoship_by_default: { [productId]: false },
|
|
17
|
+
modifiers: {},
|
|
18
|
+
module_view: { regular: '096135e6650111e9a444bc764e106cf4' },
|
|
19
|
+
incentives_display: {},
|
|
20
|
+
incentives: {
|
|
21
|
+
[productId]: { initial: [], ongoing: [] }
|
|
22
|
+
},
|
|
23
|
+
...(defaultFrequency && {
|
|
24
|
+
default_frequencies: {
|
|
25
|
+
[productId]: defaultFrequency
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
describe('offerRequest', () => {
|
|
34
|
+
let fetch, store;
|
|
35
|
+
const lastError = (acc = null, cur) => (cur.type == FETCH_RESPONSE_ERROR ? cur : acc);
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
fetch = spyOn(window, 'fetch');
|
|
38
|
+
|
|
39
|
+
store = createStore(
|
|
40
|
+
combineReducers({ offer, environment, merchantId, sessionId, lastError }),
|
|
41
|
+
{
|
|
42
|
+
environment: { apiUrl: 'http://localhost' },
|
|
43
|
+
merchantId: 'abc-merchant',
|
|
44
|
+
sessionId: 'x.y.z',
|
|
45
|
+
lastError: null
|
|
46
|
+
},
|
|
47
|
+
applyMiddleware(offerRequestMiddleware)
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should call fetch offer with environment apiUrl from state as first param', async () => {
|
|
52
|
+
fetch.and.returnValue(mockOfferResponse('123', true, true));
|
|
53
|
+
store.dispatch(requestOffer('123'));
|
|
54
|
+
expect(fetch).toHaveBeenCalledTimes(1);
|
|
55
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
56
|
+
new URL(
|
|
57
|
+
'http://localhost/offer/abc-merchant/pdp?session_id=x.y.z&page_type=1&module_view=%5B%22regular%22%5D&p=%5B%22123%22%5D'
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
await new Promise(r => setTimeout(r, 10));
|
|
62
|
+
expect(store.getState().offer.offerId).toEqual('096135e6650111e9a444bc764e106cf4');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should dispatch fetchResponseError if api fails', async () => {
|
|
66
|
+
fetch.and.rejectWith({
|
|
67
|
+
result: 'error'
|
|
68
|
+
});
|
|
69
|
+
store.dispatch(requestOffer('123'));
|
|
70
|
+
expect(fetch).toHaveBeenCalledTimes(1);
|
|
71
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
72
|
+
new URL(
|
|
73
|
+
'http://localhost/offer/abc-merchant/pdp?session_id=x.y.z&page_type=1&module_view=%5B%22regular%22%5D&p=%5B%22123%22%5D'
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
await new Promise(r => setTimeout(r, 10));
|
|
78
|
+
|
|
79
|
+
expect(store.getState().lastError).toEqual({ type: FETCH_RESPONSE_ERROR, payload: { result: 'error' } });
|
|
80
|
+
});
|
|
81
|
+
});
|
package/src/core/actions.js
CHANGED
|
@@ -199,26 +199,7 @@ export const requestOffer = (product, module = constants.DEFAULT_OFFER_MODULE, o
|
|
|
199
199
|
});
|
|
200
200
|
|
|
201
201
|
export const fetchOffer = (product, module = constants.DEFAULT_OFFER_MODULE, offerElement) =>
|
|
202
|
-
|
|
203
|
-
const state = getState();
|
|
204
|
-
const {
|
|
205
|
-
merchantId,
|
|
206
|
-
sessionId,
|
|
207
|
-
environment: { apiUrl }
|
|
208
|
-
} = state;
|
|
209
|
-
const requestAction = requestOffer(product, module, offerElement);
|
|
210
|
-
dispatch(requestAction);
|
|
211
|
-
|
|
212
|
-
const productId = safeProductId(product);
|
|
213
|
-
if (!productId) return null;
|
|
214
|
-
return api
|
|
215
|
-
.fetchOffer(apiUrl, merchantId, sessionId, productId, module, state)
|
|
216
|
-
.then(
|
|
217
|
-
response => dispatch(receiveOffer(response, offerElement)),
|
|
218
|
-
err => dispatch(fetchResponseError(err))
|
|
219
|
-
)
|
|
220
|
-
.finally(() => dispatch(fetchDone(requestAction)));
|
|
221
|
-
};
|
|
202
|
+
requestOffer(product, module, offerElement);
|
|
222
203
|
|
|
223
204
|
export const checkout = () => ({
|
|
224
205
|
type: constants.CHECKOUT
|
package/src/core/experiments.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RECEIVE_MERCHANT_SETTINGS, SET_EXPERIMENT_VARIANT } from './constants';
|
|
1
|
+
import { RECEIVE_MERCHANT_SETTINGS, REQUEST_OFFER, SET_EXPERIMENT_VARIANT } from './constants';
|
|
2
2
|
import murmur from 'murmurhash-js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -82,22 +82,33 @@ export function getAssignedExperimentVariant(experimentSettings, sessionId) {
|
|
|
82
82
|
* @return {function} A function that takes the next middleware function and an action as arguments.
|
|
83
83
|
*/
|
|
84
84
|
export function experimentsMiddleware(store) {
|
|
85
|
+
let variant, experimentSettings;
|
|
86
|
+
|
|
85
87
|
return next => action => {
|
|
86
88
|
const response = next(action);
|
|
87
|
-
if (action.type
|
|
88
|
-
|
|
89
|
-
}
|
|
89
|
+
if (action.type === RECEIVE_MERCHANT_SETTINGS) {
|
|
90
|
+
experimentSettings = action.payload.experiments;
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
const variant = getAssignedExperimentVariant(experimentSettings, sessionId);
|
|
92
|
+
const { sessionId } = store.getState();
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
store.dispatch({
|
|
96
|
-
type: SET_EXPERIMENT_VARIANT,
|
|
97
|
-
payload: variant
|
|
98
|
-
});
|
|
99
|
-
}
|
|
94
|
+
variant = getAssignedExperimentVariant(experimentSettings, sessionId);
|
|
100
95
|
|
|
96
|
+
if (variant) {
|
|
97
|
+
store.dispatch({
|
|
98
|
+
type: SET_EXPERIMENT_VARIANT,
|
|
99
|
+
payload: variant
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
} else if (action.type === REQUEST_OFFER) {
|
|
103
|
+
if (variant) {
|
|
104
|
+
action.payload.searchParams = {
|
|
105
|
+
...action.payload.searchParams,
|
|
106
|
+
variant: variant.public_id
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
101
110
|
return response;
|
|
102
111
|
};
|
|
103
112
|
}
|
|
113
|
+
|
|
114
|
+
experimentsMiddleware.position = -1;
|
package/src/core/localStorage.js
CHANGED
|
@@ -39,6 +39,13 @@ export const serializeState = state => {
|
|
|
39
39
|
|
|
40
40
|
export const saveState = state => {
|
|
41
41
|
if (isPreviewMode()) return;
|
|
42
|
+
if (state && state.sessionId) {
|
|
43
|
+
document.cookie =
|
|
44
|
+
'og_session_id=' +
|
|
45
|
+
encodeURIComponent(state.sessionId) +
|
|
46
|
+
'; path=/; expires=Fri, 31 Dec 9999 23:59:59 GMT; SameSite=Lax';
|
|
47
|
+
}
|
|
48
|
+
|
|
42
49
|
const serializedState = serializeState(state);
|
|
43
50
|
if (serializedState && localStorage.getItem(STORE_ROOT) !== serializedState) {
|
|
44
51
|
localStorage.setItem(STORE_ROOT, serializedState);
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { toProductId } from './api';
|
|
2
|
+
import { DEFAULT_OFFER_MODULE, FETCH_RESPONSE_ERROR, RECEIVE_FETCH, RECEIVE_OFFER, REQUEST_OFFER } from './constants';
|
|
3
|
+
import { safeProductId } from './utils';
|
|
4
|
+
|
|
5
|
+
function mapStateToOfferURL(state, { module = DEFAULT_OFFER_MODULE, ...params } = {}) {
|
|
6
|
+
const {
|
|
7
|
+
merchantId,
|
|
8
|
+
sessionId,
|
|
9
|
+
environment: { apiUrl }
|
|
10
|
+
} = state;
|
|
11
|
+
|
|
12
|
+
const url = new URL(`/offer/${merchantId}/${module}`, apiUrl);
|
|
13
|
+
|
|
14
|
+
[
|
|
15
|
+
['session_id', sessionId],
|
|
16
|
+
['page_type', 1],
|
|
17
|
+
['module_view', JSON.stringify(['regular'])],
|
|
18
|
+
...Object.entries(params)
|
|
19
|
+
].forEach(([k, v]) => url.searchParams.set(k, v));
|
|
20
|
+
|
|
21
|
+
return url;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates a function that processes a batch of actions by sending an offer request
|
|
26
|
+
* based on the product IDs extracted from the actions' payloads. The created function
|
|
27
|
+
* dispatches appropriate actions to the store depending on the success or failure of the offer request.
|
|
28
|
+
*
|
|
29
|
+
* @function makeDoOfferRequest
|
|
30
|
+
* @param {Object} store - The Redux store instance used to dispatch actions and retrieve the state.
|
|
31
|
+
* @returns {Function} A function that accepts a spread of actions and processes them
|
|
32
|
+
* by making an offer request and dispatching the appropriate responses.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* const doOfferRequest = makeDoOfferRequest(store);
|
|
36
|
+
*
|
|
37
|
+
* const actions = [
|
|
38
|
+
* { payload: { product: 'product1', offer: 'offer1' } },
|
|
39
|
+
* { payload: { product: 'product2', offer: 'offer2' } }
|
|
40
|
+
* ];
|
|
41
|
+
*
|
|
42
|
+
* doOfferRequest(...actions);
|
|
43
|
+
*
|
|
44
|
+
* // The returned function will:
|
|
45
|
+
* // 1. Extract product IDs from the actions' payloads.
|
|
46
|
+
* // 2. Construct the offer request URL.
|
|
47
|
+
* // 3. Make an HTTP request to fetch the offers.
|
|
48
|
+
* // 4. Dispatch appropriate actions to the store based on the response.
|
|
49
|
+
* // 5. Handle errors and dispatch error actions if necessary.
|
|
50
|
+
* // 6. Finally, dispatch a `fetchDone` action to signal completion.
|
|
51
|
+
*/
|
|
52
|
+
function createOfferRequestHandler(store) {
|
|
53
|
+
return async function doOfferRequest(action) {
|
|
54
|
+
const state = store.getState();
|
|
55
|
+
|
|
56
|
+
const offerRequestUrl = mapStateToOfferURL(state, {
|
|
57
|
+
p: toProductId(safeProductId(action.payload.product)),
|
|
58
|
+
...action.payload.searchParams
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const httpResponse = await fetch(offerRequestUrl);
|
|
63
|
+
const jsonResponse = await httpResponse.json();
|
|
64
|
+
|
|
65
|
+
store.dispatch({
|
|
66
|
+
type: RECEIVE_OFFER,
|
|
67
|
+
payload: {
|
|
68
|
+
...jsonResponse,
|
|
69
|
+
offer: action.payload.offer
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.log(err);
|
|
74
|
+
store.dispatch({
|
|
75
|
+
type: FETCH_RESPONSE_ERROR,
|
|
76
|
+
payload: err
|
|
77
|
+
});
|
|
78
|
+
} finally {
|
|
79
|
+
store.dispatch({
|
|
80
|
+
type: RECEIVE_FETCH,
|
|
81
|
+
payload: action
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function offerRequestMiddleware(store) {
|
|
88
|
+
const doOfferRequests = createOfferRequestHandler(store);
|
|
89
|
+
|
|
90
|
+
return next => action => {
|
|
91
|
+
next(action);
|
|
92
|
+
if (action.type === REQUEST_OFFER) {
|
|
93
|
+
doOfferRequests(action);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
package/src/core/reducer.js
CHANGED
|
@@ -271,7 +271,7 @@ export const productOffer = (state = {}, action) => {
|
|
|
271
271
|
...state,
|
|
272
272
|
...Object.entries(action.payload.autoship)
|
|
273
273
|
.map(([key]) => ({ [key]: Object.keys(action.payload.modifiers) }))
|
|
274
|
-
.reduce((acc, object) => ({ ...acc, ...object }))
|
|
274
|
+
.reduce((acc, object) => ({ ...acc, ...object }), {})
|
|
275
275
|
};
|
|
276
276
|
case constants.CHECKOUT:
|
|
277
277
|
return {};
|
package/src/core/store.js
CHANGED
|
@@ -4,6 +4,7 @@ import thunk from 'redux-thunk';
|
|
|
4
4
|
import { loadState } from './localStorage';
|
|
5
5
|
import { dispatchMiddleware, localStorageMiddleware, offerEvents } from './middleware';
|
|
6
6
|
import { waitUntilOffersReady } from './waitUntilOffersReady';
|
|
7
|
+
import { offerRequestMiddleware } from './offerRequest';
|
|
7
8
|
|
|
8
9
|
export function makeStore(reducer, ...extraMiddlewares) {
|
|
9
10
|
if (window.og && window.og.store) return window.og.store;
|
|
@@ -17,7 +18,13 @@ export function makeStore(reducer, ...extraMiddlewares) {
|
|
|
17
18
|
})
|
|
18
19
|
: compose;
|
|
19
20
|
|
|
20
|
-
const middlewares = [
|
|
21
|
+
const middlewares = [
|
|
22
|
+
waitUntilOffersReady,
|
|
23
|
+
thunk, // remove thisone after migration, it will save some KB
|
|
24
|
+
offerRequestMiddleware,
|
|
25
|
+
dispatchMiddleware,
|
|
26
|
+
offerEvents
|
|
27
|
+
];
|
|
21
28
|
|
|
22
29
|
let initial = {};
|
|
23
30
|
|
|
@@ -30,7 +37,13 @@ export function makeStore(reducer, ...extraMiddlewares) {
|
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
39
|
|
|
33
|
-
const
|
|
40
|
+
const sortedMiddlewares = extraMiddlewares
|
|
41
|
+
.filter(it => (it?.position || 0) < 0)
|
|
42
|
+
.concat(middlewares)
|
|
43
|
+
.concat(extraMiddlewares.filter(it => it && (it?.position || 0) >= 0));
|
|
44
|
+
|
|
45
|
+
const enhancer = composeEnhancers(applyMiddleware(...sortedMiddlewares));
|
|
46
|
+
|
|
34
47
|
const store = createStore(reducer, initial, enhancer);
|
|
35
48
|
|
|
36
49
|
window.og = window.og || {};
|