@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
75 lines (68 loc) • 3.42 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var tslib = require('tslib');
var React = require('react');
var redux = require('redux');
var Error = require('@shopify/app-bridge-core/actions/Error');
var useHostContext = require('./hooks/useHostContext.js');
var HostProvider = require('./HostProvider.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
/**
* A higher order component that takes a feature and make its actions and reducer available
* @public
* @returns a component which has access to the feature actions and local state
*/
function withFeature(feature) {
return function (WrappedComponent) {
return function AsyncConnector(props) {
var actions = feature.actions, key = feature.key, reducer = feature.reducer, initialState = feature.initialState;
var context = useHostContext.useHostContext();
var app = context.app, addReducer = context.addReducer;
React.useEffect(function () {
addReducer({ key: key, reducer: reducer, initialState: initialState });
}, [addReducer, initialState, key, reducer]);
var localActions = React.useMemo(function () {
return redux.bindActionCreators(actions, app.dispatch);
}, [app, actions]);
useSetFeatureApi(feature, localActions);
var globalStore = props.globalStore, localProps = tslib.__rest(props, ["globalStore"]);
var localStore = globalStore === null || globalStore === void 0 ? void 0 : globalStore[key];
if (localStore === undefined) {
return null;
}
return (React__default.default.createElement(WrappedComponent, tslib.__assign({}, localProps, { actions: localActions, store: localStore })));
};
};
}
function isFeatureWithApi(feature) {
return Object.prototype.hasOwnProperty.call(feature, 'getApi');
}
function isFeatureWithRouterApi(feature) {
return Object.prototype.hasOwnProperty.call(feature, 'getApi') && feature.requiresRouter === true;
}
function useSetFeatureApi(feature, localActions) {
var _a = useHostContext.useHostContext(), app = _a.app, config = _a.config, api = _a.api;
var router = React.useContext(HostProvider.RouterContext);
React.useEffect(function () {
if (!isFeatureWithApi(feature) || !api || !localActions) {
return;
}
if (isFeatureWithRouterApi(feature)) {
if (!router) {
throw Error.fromAction('Missing required Host Context. Your component must be wrapped in a <HostProvider> component with the `router` prop provided', Error.AppActionType.MISSING_ROUTER_CONTEXT);
}
}
var castedKey = feature.key;
var apifeature = feature.getApi({
config: tslib.__assign(tslib.__assign({}, config), { hostName: isFeatureWithRouterApi(feature) ? router === null || router === void 0 ? void 0 : router.hostname : undefined }),
actions: localActions,
subscribe: app.hostSubscribe,
getState: app.getState,
dispatch: app.dispatch,
});
api.setApi(castedKey, apifeature);
}, [config, feature, localActions, api]);
}
exports.default = withFeature;
exports.useSetFeatureApi = useSetFeatureApi;