UNPKG

@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
'use strict'; 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;