Merge branch 'master' into gh-103

This commit is contained in:
Rich Harris
2018-03-04 19:00:28 -05:00
4 changed files with 29 additions and 9 deletions

View File

@@ -59,9 +59,6 @@ function render(Component: ComponentConstructor, data: any, scroll: ScrollPositi
detach(start); detach(start);
detach(end); detach(end);
} }
// preload additional routes
routes.reduce((promise: Promise<any>, route) => promise.then(route.load), Promise.resolve());
} }
component = new Component({ component = new Component({
@@ -268,3 +265,20 @@ export function goto(href: string, opts = { replaceState: false }) {
window.location.href = href; window.location.href = href;
} }
} }
export function preloadRoutes(pathnames: string[]) {
if (!routes) throw new Error(`You must call init() first`);
return routes
.filter(route => {
if (!pathnames) return true;
return pathnames.some(pathname => {
return route.error
? route.error === pathname
: route.pattern.test(pathname)
});
})
.reduce((promise: Promise<any>, route) => {
return promise.then(route.load);
}, Promise.resolve());
}

View File

@@ -13,8 +13,9 @@ export interface Component {
export type Route = { export type Route = {
pattern: RegExp; pattern: RegExp;
params: (match: RegExpExecArray) => Record<string, string>;
load: () => Promise<{ default: ComponentConstructor }>; load: () => Promise<{ default: ComponentConstructor }>;
error?: string;
params?: (match: RegExpExecArray) => Record<string, string>;
ignore?: boolean; ignore?: boolean;
}; };

View File

@@ -1,6 +1,8 @@
import { init } from '../../../runtime.js'; import { init, preloadRoutes } from '../../../runtime.js';
import { routes } from './manifest/client.js'; import { routes } from './manifest/client.js';
window.init = () => { window.init = () => {
return init(document.querySelector('#sapper'), routes); return init(document.querySelector('#sapper'), routes);
}; };
window.preloadRoutes = preloadRoutes;

View File

@@ -23,6 +23,10 @@ Nightmare.action('init', function(done) {
this.evaluate_now(() => window.init(), done); this.evaluate_now(() => window.init(), done);
}); });
Nightmare.action('preloadRoutes', function(done) {
this.evaluate_now(() => window.preloadRoutes(), done);
});
function run(env) { function run(env) {
describe(`env=${env}`, function () { describe(`env=${env}`, function () {
this.timeout(30000); this.timeout(30000);
@@ -155,7 +159,7 @@ function run(env) {
}); });
it('navigates to a new page without reloading', () => { it('navigates to a new page without reloading', () => {
return capture(() => nightmare.goto(base).init().wait(400)) return capture(() => nightmare.goto(base).init().preloadRoutes())
.then(() => { .then(() => {
return capture(() => nightmare.click('a[href="/about"]')); return capture(() => nightmare.click('a[href="/about"]'));
}) })
@@ -189,7 +193,6 @@ function run(env) {
return nightmare return nightmare
.goto(`${base}/about`) .goto(`${base}/about`)
.init() .init()
.wait(200)
.then(() => { .then(() => {
return capture(() => { return capture(() => {
return nightmare return nightmare
@@ -215,7 +218,7 @@ function run(env) {
it('reuses prefetch promise', () => { it('reuses prefetch promise', () => {
return nightmare return nightmare
.goto(`${base}/blog`) .goto(`${base}/blog`)
.init().wait(300) .init()
.then(() => { .then(() => {
return capture(() => { return capture(() => {
return nightmare return nightmare