UNPKG

found-relay

Version:
183 lines (145 loc) 6.54 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _awaitAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/awaitAsyncGenerator")); var _wrapAsyncGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapAsyncGenerator")); var _dequal = require("dequal"); var _ResolverUtils = require("found/ResolverUtils"); var _isPromise = _interopRequireDefault(require("is-promise")); var _react = _interopRequireDefault(require("react")); var _QuerySubscription = _interopRequireDefault(require("./QuerySubscription")); var _ReadyStateRenderer = _interopRequireDefault(require("./ReadyStateRenderer")); var _renderElement = _interopRequireDefault(require("./renderElement")); class Resolver { constructor(environment) { this.environment = environment; this.lastQuerySubscriptions = []; } createQuerySubscription(options) { return new _QuerySubscription.default(options); } resolveElements(match) { var _this = this; return (0, _wrapAsyncGenerator2.default)(function* () { const routeMatches = (0, _ResolverUtils.getRouteMatches)(match); const Components = (0, _ResolverUtils.getComponents)(routeMatches); const queries = (0, _ResolverUtils.getRouteValues)(routeMatches, route => route.getQuery, route => route.query); const cacheConfigs = (0, _ResolverUtils.getRouteValues)(routeMatches, route => route.getCacheConfig, route => route.cacheConfig); const fetchPolicies = (0, _ResolverUtils.getRouteValues)(routeMatches, route => route.getFetchPolicy, route => route.fetchPolicy); const routeVariables = _this.getRouteVariables(match, routeMatches); const querySubscriptions = _this.updateQuerySubscriptions(queries, routeVariables, cacheConfigs, fetchPolicies); const fetches = querySubscriptions.map(querySubscription => querySubscription == null ? void 0 : querySubscription.fetch()); const earlyComponents = Components.some(_isPromise.default) ? yield (0, _awaitAsyncGenerator2.default)(Promise.all(Components.map(_ResolverUtils.checkResolved))) : Components; const earlyData = yield (0, _awaitAsyncGenerator2.default)(Promise.all(fetches.map(_ResolverUtils.checkResolved))); let fetchedComponents; if (!earlyComponents.every(_ResolverUtils.isResolved) || !earlyData.every(_ResolverUtils.isResolved)) { const pendingElements = _this.createElements(routeMatches, earlyComponents, querySubscriptions, false); yield pendingElements.every(element => element !== undefined) ? pendingElements : undefined; fetchedComponents = yield (0, _awaitAsyncGenerator2.default)(Promise.all(Components)); yield (0, _awaitAsyncGenerator2.default)(Promise.all(fetches)); } else { fetchedComponents = earlyComponents; } yield _this.createElements(routeMatches, fetchedComponents, querySubscriptions, true); })(); } getRouteVariables(match, routeMatches) { return (0, _ResolverUtils.accumulateRouteValues)(routeMatches, match.routeIndices, (variables, routeMatch) => { const { route, routeParams } = routeMatch; // We need to always run this to make sure we don't miss route params. let nextVariables = Object.assign({}, variables, routeParams); if (route.prepareVariables) { nextVariables = route.prepareVariables(nextVariables, routeMatch); } return nextVariables; }, null); } updateQuerySubscriptions(queries, routeVariables, cacheConfigs, fetchPolicies) { const querySubscriptions = queries.map((query, i) => { if (!query) { return null; } const variables = routeVariables[i]; const cacheConfig = cacheConfigs[i]; const fetchPolicy = fetchPolicies[i]; const lastQuerySubscription = this.lastQuerySubscriptions[i]; // Match the logic in <QueryRenderer> for not refetching. if (lastQuerySubscription && lastQuerySubscription.query === query && (0, _dequal.dequal)(lastQuerySubscription.variables, variables) && (0, _dequal.dequal)(lastQuerySubscription.cacheConfig, cacheConfig)) { this.lastQuerySubscriptions[i] = null; lastQuerySubscription.fetchPolicy = fetchPolicy; return lastQuerySubscription; } return this.createQuerySubscription({ environment: this.environment, query, variables, cacheConfig, fetchPolicy }); }); this.lastQuerySubscriptions.forEach(querySubscription => { if (querySubscription) { querySubscription.dispose(); } }); this.lastQuerySubscriptions = [...querySubscriptions]; return querySubscriptions; } createElements(routeMatches, Components, querySubscriptions, fetched) { return routeMatches.map((match, i) => { const { route, router } = match; const Component = Components[i]; const querySubscription = querySubscriptions[i]; const isComponentResolved = (0, _ResolverUtils.isResolved)(Component); // Handle non-Relay routes. if (!querySubscription) { if (route.render) { return route.render({ match, Component: isComponentResolved ? Component : null, props: { match, router } }); } if (!isComponentResolved) { return undefined; } return Component ? /*#__PURE__*/_react.default.createElement(Component, { match: match, router: router }) : null; } const resolvedComponent = isComponentResolved ? Component : null; const hasComponent = Component != null; const element = (0, _renderElement.default)({ match, Component: resolvedComponent, isComponentResolved, hasComponent, querySubscription, resolving: true }); if (!element) { return element; } return routeChildren => /*#__PURE__*/_react.default.createElement(_ReadyStateRenderer.default, { match: match, Component: resolvedComponent, isComponentResolved: isComponentResolved, hasComponent: hasComponent, element: element, routeChildren: routeChildren, querySubscription: querySubscription, fetched: fetched }); }); } } exports.default = Resolver; module.exports = exports.default;