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

66 lines (63 loc) 3.13 kB
import { __rest, __assign } from 'tslib'; import React, { useEffect, useMemo, useContext } from 'react'; import { bindActionCreators } from 'redux'; import { fromAction, AppActionType } from '@shopify/app-bridge-core/actions/Error'; import { useHostContext } from './hooks/useHostContext.js'; import { RouterContext } from './HostProvider.js'; /** * 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(); var app = context.app, addReducer = context.addReducer; useEffect(function () { addReducer({ key: key, reducer: reducer, initialState: initialState }); }, [addReducer, initialState, key, reducer]); var localActions = useMemo(function () { return bindActionCreators(actions, app.dispatch); }, [app, actions]); useSetFeatureApi(feature, localActions); var globalStore = props.globalStore, localProps = __rest(props, ["globalStore"]); var localStore = globalStore === null || globalStore === void 0 ? void 0 : globalStore[key]; if (localStore === undefined) { return null; } return (React.createElement(WrappedComponent, __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(), app = _a.app, config = _a.config, api = _a.api; var router = useContext(RouterContext); useEffect(function () { if (!isFeatureWithApi(feature) || !api || !localActions) { return; } if (isFeatureWithRouterApi(feature)) { if (!router) { throw fromAction('Missing required Host Context. Your component must be wrapped in a <HostProvider> component with the `router` prop provided', AppActionType.MISSING_ROUTER_CONTEXT); } } var castedKey = feature.key; var apifeature = feature.getApi({ config: __assign(__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]); } export { withFeature as default, useSetFeatureApi };