@automattic/shopping-cart
Version:
A library to use the WordPress.com shopping cart.
106 lines • 4.33 kB
JavaScript
import debugFactory from 'debug';
import { convertTempResponseCartToResponseCart } from './cart-functions';
import { getEmptyResponseCart } from './empty-carts';
const debug = debugFactory('shopping-cart:managers');
export function getShoppingCartManagerState(state) {
const { cacheStatus, queuedActions, couponStatus, loadingErrorType, loadingError, lastValidResponseCart, } = state;
const isLoading = cacheStatus === 'fresh' || cacheStatus === 'fresh-pending';
const isPendingUpdate = queuedActions.length > 0 || cacheStatus !== 'valid';
const loadingErrorForManager = cacheStatus === 'error' ? loadingError : null;
debug('manager isLoading', isLoading, 'isPendingUpdate', isPendingUpdate, 'loadingError', loadingErrorForManager);
return {
isLoading,
loadingError: loadingErrorForManager,
loadingErrorType,
isPendingUpdate,
couponStatus,
responseCart: lastValidResponseCart,
};
}
export function createSubscriptionManager(cartKey) {
let subscribedClients = [];
const subscribe = (callback) => {
debug(`adding subscriber for cartKey ${cartKey}`);
subscribedClients.push(callback);
return () => {
debug(`removing subscriber for cartKey ${cartKey}`);
subscribedClients = subscribedClients.filter((prevCallback) => prevCallback !== callback);
};
};
const notifySubscribers = () => {
debug(`notifying ${subscribedClients.length} subscribers for cartKey ${cartKey}`);
subscribedClients.forEach((clientCallback) => {
try {
clientCallback();
}
catch (err) {
// eslint-disable-next-line no-console
console.error('An error ocurred while notifying a subscriber of a ShoppingCartManager change', err.message);
throw err;
}
});
debug(`completed notification of subscribers for cartKey ${cartKey}`);
};
return { subscribe, notifySubscribers };
}
/**
* Create an object that manages the Promises returned by cart actions.
*
* When an action is requested, we create a Promise for that action dispatcher
* to return and store it in this object. Later when we know if the action
* resulted in a success or a failure, the resolve or reject methods are called
* on this object; those methods then resolve or reject each Promise that was
* waiting for a response.
*/
export function createActionPromisesManager() {
let actionPromises = [];
return {
resolve(tempResponseCart) {
if (actionPromises.length > 0) {
debug(`resolving ${actionPromises.length} action promises`);
const responseCart = convertTempResponseCartToResponseCart(tempResponseCart);
actionPromises.forEach((actionPromise) => actionPromise.resolve(responseCart));
actionPromises = [];
}
},
reject(error) {
if (actionPromises.length > 0) {
debug(`rejecting ${actionPromises.length} action promises`);
actionPromises.forEach((actionPromise) => actionPromise.reject(error));
actionPromises = [];
}
},
add(actionPromise) {
actionPromises.push(actionPromise);
},
};
}
const emptyCart = getEmptyResponseCart();
const noopCartAction = () => Promise.reject('Cart actions cannot be taken without a cart key.');
const noopState = {
isLoading: true,
loadingError: undefined,
loadingErrorType: undefined,
isPendingUpdate: true,
couponStatus: 'fresh',
responseCart: emptyCart,
};
const noopGetState = () => noopState;
const noopActions = {
addProductsToCart: noopCartAction,
removeProductFromCart: noopCartAction,
applyCoupon: noopCartAction,
removeCoupon: noopCartAction,
updateLocation: noopCartAction,
replaceProductInCart: noopCartAction,
replaceProductsInCart: noopCartAction,
reloadFromServer: () => Promise.resolve(emptyCart),
clearMessages: () => Promise.resolve(emptyCart),
};
export const noopManager = {
actions: noopActions,
getState: noopGetState,
subscribe: () => () => null,
fetchInitialCart: () => Promise.resolve(emptyCart),
};
//# sourceMappingURL=managers.js.map