Skip to content

Commit 223cc01

Browse files
author
Tiago Azevedo
committed
Client route parsing
1 parent 4e204c2 commit 223cc01

File tree

8 files changed

+61
-17
lines changed

8 files changed

+61
-17
lines changed

client.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./lib/client');

spec/unit/server/middleware/render.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe('Render Middleware', () => {
2828
.get('/')
2929
.end((err, res) => {
3030
if (err) throw err;
31-
assert.match(res.text, /<html><body><script type=\"application\/json\" id=\"myapp-state\">(?:.+)<\/script><div(?:.*)id="myapp"(?:.*)>(?:.*)<\/div><\/body><\/html>/)
31+
assert.match(res.text, /<html><body><script type=\"application\/json\" id=\"myapp-state\">(?:.+)<\/script>\n<div(?:.*)id="myapp"(?:.*)>(?:.*)<\/div><\/body><\/html>/)
3232
done();
3333
});
3434
});

src/client/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import render from './render';
2+
3+
export default { render };

src/client/render.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { parse } from '../shared/route-parser';
2+
import React from 'react';
3+
import ReactDOM from 'react-dom';
4+
import decode from 'ent/decode';
5+
6+
export default function render(application) {
7+
let url = `${window.location.protocol}//${window.location.host}${window.location.pathname}${window.location.search}`;
8+
9+
let matches = parse(application.routes, url);
10+
11+
if (matches) {
12+
let { route, context } = matches;
13+
const stateNode = document.getElementById(`${application.domRoot}-state`);
14+
const state = JSON.parse(decode(stateNode.text));
15+
let rootNode = document.getElementById(application.domRoot);
16+
const Component = route.component;
17+
18+
ReactDOM.render(
19+
<Component
20+
context={context}
21+
state={state}
22+
/>,
23+
rootNode);
24+
}
25+
}

src/server/index.js

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import koa from 'koa';
2-
32
import init from './middleware/init';
4-
import render from './middleware/render';
53
import router from './middleware/router';
4+
import render from './middleware/render';
65

76
/**
87
* Instantiate a server given an application.
@@ -11,11 +10,14 @@ import router from './middleware/router';
1110

1211
export default function server(application, options) {
1312
const app = koa();
14-
15-
app
16-
.use(init(application, options))
17-
.use(router)
18-
.use(render)
19-
20-
return app;
13+
return {
14+
use: (mw) => app.use(mw),
15+
start: () => {
16+
return app
17+
.use(init(application, options))
18+
.use(router)
19+
.use(render)
20+
.listen(options.port)
21+
}
22+
}
2123
}

src/server/middleware/render.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ export default function* renderMiddleware(next) {
1010
let Component = this.arch.route.component;
1111

1212
let body = ReactDOMServer.renderToString(
13-
<Component context={this.arch.context} />
13+
<Component
14+
context={this.arch.context}
15+
state={this.arch.state}
16+
/>
1417
);
1518

16-
this.body = template.replace('{{root}}', `<script type="application/json" id="${domRoot}-state">${encode(JSON.stringify(this.arch.state))}</script><div id="${domRoot}">${body}</div>`);
19+
this.body = template.replace('{{root}}', `<script type="application/json" id="${domRoot}-state">${encode(JSON.stringify(this.arch.state))}</script>\n<div id="${domRoot}">${body}</div>`);
1720
yield next;
1821
}

src/server/middleware/router.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import { match } from '../../shared/route-parser';
1+
import { parse } from '../../shared/route-parser';
22

33
export default function* routerMiddleware(next) {
44
if (typeof this.arch === 'undefined') throw new Error('Router middleware must be run inside an Arch server.');
55

6-
let routes = this.arch.application.routes;
7-
let context;
8-
let route = routes.find(({ path }) => context = match(this.originalUrl, path));
6+
let matched = parse(this.arch.application.routes, this.originalUrl);
97

10-
if (route) {
8+
if (matched) {
9+
let { route, context } = matched;
1110
this.arch.route = route;
1211
this.arch.context = context;
1312
yield next;

src/shared/route-parser.js

+11
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,14 @@ export function match(originalUrl, route) {
4242
route
4343
};
4444
}
45+
46+
export function parse(routes, url) {
47+
let context;
48+
let route = routes.find(({ path }) => context = match(url, path));
49+
50+
if (route) {
51+
return { route, context };
52+
} else {
53+
return null;
54+
}
55+
}

0 commit comments

Comments
 (0)