@shopify/app-bridge-host
Version:
App Bridge Host contains components and middleware to be consumed by the app's host, as well as the host itself. The middleware and `Frame` component are responsible for facilitating communication between the client and host, and used to act on actions se
173 lines (169 loc) • 7.22 kB
JavaScript
;
var tslib = require('tslib');
var redux = require('redux');
var actions$1 = require('../actions.js');
require('@shopify/app-bridge-core/actions');
var store_reducers_embeddedApp_features_reducer = require('./reducers/embeddedApp/features/reducer.js');
var utilities = require('./reducers/embeddedApp/utilities.js');
var middleware = require('./middlewares/mobile/middleware.js');
var helpers = require('./middlewares/mobile/helpers.js');
var store_reducers_index = require('./reducers/index.js');
var actions = require('./reducers/embeddedApp/appBridge/actions.js');
/**
* The constant key `appBridge`
* @public
*/
var APP_BRIDGE_KEY = 'appBridge';
/**
* Returns a combined reducer for the `appBridge` key
* Always includes the `features` reducer
* @public
* @param stateReducers - a reducer map for the dynamic app state
* @param initialState - an optional default value for the store
*/
function createReducers(stateReducers, initialState) {
var _a;
if (stateReducers === void 0) { stateReducers = {}; }
if (initialState === void 0) { initialState = {}; }
var allReducers = redux.combineReducers((_a = {},
_a[APP_BRIDGE_KEY] = redux.combineReducers(utilities.wrapReducers(tslib.__assign({ features: store_reducers_embeddedApp_features_reducer.default }, stateReducers), utilities.resetAppReducer, initialState)),
_a));
return function (state, action) {
var _a, _b, _c;
if (state === void 0) { state = (_a = {}, _a[APP_BRIDGE_KEY] = { features: {} }, _a); }
if (actions$1.isLoadReducerAction(action)) {
var feature = action.payload.feature;
var currenState = state[APP_BRIDGE_KEY];
return _b = {},
_b[APP_BRIDGE_KEY] = tslib.__assign(tslib.__assign({}, currenState), (_c = {}, _c[feature] = initialState[feature], _c)),
_b;
}
return allReducers(state, action);
};
}
/**
* Creates a store containing only the default `features` reducer
* @public
*/
function createStore(middleware, initialState, debug) {
var _a;
if (middleware === void 0) { middleware = []; }
if (initialState === void 0) { initialState = { features: {} }; }
if (debug === void 0) { debug = false; }
var defaultState = (_a = {}, _a[APP_BRIDGE_KEY] = initialState, _a);
var composeEnhancers = debug && typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ name: 'App Bridge', shouldHotReload: false })
: redux.compose;
return redux.createStore(createReducers({}, initialState), defaultState, composeEnhancers(redux.applyMiddleware.apply(void 0, middleware)));
}
/**
* Creates a method that when called, dynamically adds a reducer to
* the provided store
* @internal
* @param store - a Redux store
* @param globalInitialState - custom overrides for resolving the app state when adding a new reducer
* */
function createAddReducer(store, globalInitialState) {
if (globalInitialState === void 0) { globalInitialState = {}; }
var asyncReducers = {};
return function addReducer(_a) {
var _b;
var key = _a.key, reducer = _a.reducer, initialState = _a.initialState;
// not adding 'features' reducer to store fixes https://github.com/Shopify/app-bridge/issues/2571
if (Object.prototype.hasOwnProperty.call(asyncReducers, key) || key === 'features') {
return;
}
asyncReducers[key] = reducer;
store.replaceReducer(createReducers(asyncReducers, tslib.__assign((_b = {}, _b[key] = initialState, _b), globalInitialState)));
store.dispatch(actions$1.hostLoadReducer(key));
store.dispatch(actions$1.hostLoadCompleteReducer(key));
};
}
/**
* Creates an action queue for the provided store
* @internal
* */
function createActionsQueue(store) {
var queue = new Map();
var hostQueue = new Set();
return {
add: function (context, action) {
if (!queue.has(context)) {
queue.set(context, new Set());
}
var contextQueue = queue.get(context);
contextQueue.add(action);
},
addHostAction: function (action) {
hostQueue.add(action);
},
clear: function (context) {
var contextQueue = queue.get(context);
if (contextQueue) {
contextQueue.clear();
}
},
resolve: function (feature) {
hostQueue.forEach(function (action) {
var actionKey = groupToFeatureKey(action.group);
if (actionKey === feature) {
store.dispatch(action);
hostQueue.delete(action);
}
});
queue.forEach(function (contextQueue) {
contextQueue.forEach(function (action) {
var actionKey = groupToFeatureKey(action.group);
if (actionKey === feature) {
store.dispatch(action);
contextQueue.delete(action);
}
});
});
},
};
}
/**
* Returns the reducer key from a group
* @internal
*/
function groupToFeatureKey(group) {
return group[0].toLowerCase().concat(group.substr(1).replace('_', ''));
}
/**
* Predicate to determine if a reducer for the associated action is already loaded
* @internal
*/
function isReducerLoaded(state, action) {
var group = action ? action.group : undefined;
if (!group)
return false;
var key = groupToFeatureKey(action.group);
return Object.prototype.hasOwnProperty.call(state, key);
}
exports.setFeaturesAvailable = store_reducers_embeddedApp_features_reducer.setFeaturesAvailable;
exports.getMobileMiddleware = middleware.getMobileMiddleware;
exports.CART_PERMISSION_MESSAGE = helpers.CART_PERMISSION_MESSAGE;
exports.applyPrintToLegacyButton = helpers.applyPrintToLegacyButton;
exports.buildCallbackQueueItem = helpers.buildCallbackQueueItem;
exports.buildQueueItem = helpers.buildQueueItem;
exports.fixDiscountInCartResponse = helpers.fixDiscountInCartResponse;
exports.isCartAction = helpers.isCartAction;
exports.isLegacyShopifyMobile = helpers.isLegacyShopifyMobile;
exports.isLegacyShopifyPOS = helpers.isLegacyShopifyPOS;
exports.isMobile = helpers.isMobile;
exports.isMobileMiddlewareAvailable = helpers.isMobileMiddlewareAvailable;
exports.isMobileMiddlewareSupported = helpers.isMobileMiddlewareSupported;
exports.isShopifyMobile = helpers.isShopifyMobile;
exports.isShopifyPOS = helpers.isShopifyPOS;
exports.isShopifyPing = helpers.isShopifyPing;
exports.traverseButtonPayload = helpers.traverseButtonPayload;
exports.mapAppDispatchToProps = store_reducers_index.mapAppDispatchToProps;
exports.mapAppStoreToProps = store_reducers_index.mapAppStoreToProps;
exports.StoreReadyAction = actions.StoreReadyAction;
exports.APP_BRIDGE_KEY = APP_BRIDGE_KEY;
exports.createActionsQueue = createActionsQueue;
exports.createAddReducer = createAddReducer;
exports.createReducers = createReducers;
exports.createStore = createStore;
exports.isReducerLoaded = isReducerLoaded;