Skip to content

Commit

Permalink
Merge pull request #12 from 4Catalyzer/ResolverUtils
Browse files Browse the repository at this point in the history
PromiseUtils -> ResolverUtils; use route matches
  • Loading branch information
taion authored Oct 27, 2016
2 parents 46ae92b + 223f64c commit 6d5ab65
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 45 deletions.
15 changes: 0 additions & 15 deletions src/PromiseUtils.js

This file was deleted.

38 changes: 38 additions & 0 deletions src/ResolverUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import isPromise from 'is-promise';

const UNRESOLVED = {};

export function checkResolved(value) {
if (!isPromise(value)) {
return value;
}

return Promise.race([value, UNRESOLVED]);
}

export function isResolved(value) {
return value !== UNRESOLVED;
}

export function getRouteMatches(match) {
return match.routes.map((route, i) => ({
...match, route, routeParams: match.routeParams[i],
}));
}

// This should work better with Flow than the obvious solution with keys.
export function getRouteValues(routeMatches, getGetter, getValue) {
return routeMatches.map((match) => {
const { route } = match;
const getter = getGetter(route);
return getter ? getter.call(route, match) : getValue(route);
});
}

export function getComponents(routeMatches) {
return getRouteValues(
routeMatches,
route => route.getComponent,
route => route.Component,
);
}
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export HttpError from './HttpError';
export Link from './Link';
export Matcher from './Matcher';
export matchReducer from './matchReducer';
export PromiseUtils from './PromiseUtils';
export Redirect from './Redirect';
export RedirectException from './RedirectException';
export resolveElements from './resolveElements';
export ResolverUtils from './ResolverUtils';
48 changes: 19 additions & 29 deletions src/resolveElements.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,28 @@ import isPromise from 'is-promise';
import React from 'react';
import warning from 'warning';

import { checkResolved, isResolved } from './PromiseUtils';
import {
checkResolved, getComponents, getRouteMatches, getRouteValues, isResolved,
} from './ResolverUtils';

function createElements(match, Components, matchData) {
const { routes, routeParams: matchRouteParams } = match;
function createElements(routeMatches, Components, matchData) {
return routeMatches.map((match, i) => {
const { route } = match;

return routes.map((route, i) => {
const Component = Components[i];
const data = matchData[i];
const routeParams = matchRouteParams[i];

const isComponentResolved = isResolved(Component);
const isDataResolved = isResolved(data);

const routeMatch = {
...match,
route,
routeParams: routeParams[i],
};

if (route.render) {
// Perhaps undefined here would be more correct for "not ready", but
// Relay uses null in RelayReadyStateRenderer, so let's follow that
// convention.
return route.render({
match,
Component: isComponentResolved ? Component : null,
props: isDataResolved ? { ...routeMatch, data } : null,
match: routeMatch,
props: isDataResolved ? { ...match, data } : null,
data: isDataResolved ? data : null,
});
}
Expand All @@ -48,25 +43,19 @@ function createElements(match, Components, matchData) {
return null;
}

return (
<Component
{...routeMatch}
data={data}
/>
);
return <Component {...match} data={data} />;
});
}

export default async function* resolveElements(match) {
const { routes } = match;
const routeMatches = getRouteMatches(match);

// TODO: These should use routeMatch objects as above.
const Components = routes.map(route => (
route.getComponent ? route.getComponent(match) : route.Component
));
const data = routes.map(route => (
route.getData ? route.getData(match) : route.data
));
const Components = getComponents(routeMatches);
const data = getRouteValues(
routeMatches,
route => route.getData,
route => route.data,
);

const earlyComponents = Components.some(isPromise) ?
await Promise.all(Components.map(checkResolved)) : Components;
Expand All @@ -77,7 +66,8 @@ export default async function* resolveElements(match) {
let resolvedData;

if (!earlyComponents.every(isResolved) || !earlyData.every(isResolved)) {
const pendingElements = createElements(match, earlyComponents, earlyData);
const pendingElements =
createElements(routeMatches, earlyComponents, earlyData);
yield pendingElements.every(element => element !== undefined) ?
pendingElements : undefined;

Expand All @@ -88,5 +78,5 @@ export default async function* resolveElements(match) {
resolvedData = earlyData;
}

yield createElements(match, resolvedComponents, resolvedData);
yield createElements(routeMatches, resolvedComponents, resolvedData);
}

0 comments on commit 6d5ab65

Please sign in to comment.