feat: hydration

This commit is contained in:
cha0s 2020-07-15 20:23:06 -05:00
parent c6d5919571
commit af1336e859
7 changed files with 78 additions and 13 deletions

View File

@ -22,6 +22,7 @@
"ansi-html": "0.0.7",
"bcrypt": "^5.0.0",
"classnames": "2.2.6",
"concat-stream-p": "0.1.2",
"connect-redis": "^5.0.0",
"contempo": "1.x",
"debug": "^4.1.1",

View File

@ -5,6 +5,7 @@
<meta charset="utf-8">
<link rel="icon" href="/favicon.ico"/>
<title><%= htmlWebpackPlugin.options.title %></title>
<script>window.__HYDRATION__ = {};</script>
</head>
<body>
<div id="<%= htmlWebpackPlugin.options.appMountId %>">

View File

@ -1,14 +1,31 @@
/* eslint-disable import/no-extraneous-dependencies */
import express from 'express';
import {createReadStream} from 'fs';
import http, {ServerResponse} from 'http';
import httpProxy from 'http-proxy';
import {join} from 'path';
import concat from 'concat-stream-p';
import express from 'express';
import httpProxy from 'http-proxy';
import {invokeHookFlat} from 'scwp';
import userRoutes from './routes/user';
import passport from './passport';
import session from './session';
export function createHttpServer() {
const hydration = async (req, buffer) => {
const hydration = JSON.stringify(
(await Promise.all(invokeHookFlat('hydration', req)))
.reduce((hydration, result) => ({...hydration, ...result}), {}),
);
return buffer
.toString()
.replace(
'window.__HYDRATION__ = {};',
`window.__HYDRATION__ = ${hydration};`,
);
};
export async function createHttpServer() {
const app = express();
app.use(express.urlencoded({extended: true}));
app.use(session());
@ -22,19 +39,23 @@ export function createHttpServer() {
secure: false,
target: 'http://127.0.0.1:31345',
});
proxy.on('proxyRes', async (proxyRes, req, res) => {
const buffer = await proxyRes.pipe(concat());
res.end(await hydration(req, buffer));
});
proxy.on('error', (err, req, res) => {
if (res instanceof ServerResponse) {
res.status(502).end('Bad Gateway (WDS)');
}
});
app.get('*', (req, res) => proxy.web(req, res));
app.get('*', (req, res) => proxy.web(req, res, {selfHandleResponse: true}));
httpServer.on('close', () => proxy.close());
}
else {
app.use(express.static(join(__dirname, '..', 'client')));
app.get('*', (req, res) => {
res.sendFile(join(__dirname, '..', 'client', 'index.html'));
});
const stream = createReadStream(join(__dirname, '..', 'client', 'index.html'));
const buffer = await stream.pipe(concat());
app.get('*', async (req, res) => res.end(await hydration(req, buffer)));
}
return httpServer;
}

View File

@ -2,11 +2,10 @@ import {Model} from 'sequelize';
class BaseModel extends Model {
// eslint-disable-next-line no-unused-vars
static associate(map) {}
static associate(/* map */) {}
static attributes() {
throw new ReferenceError('You must define a static attributes() method in your model.');
static get attributes() {
return {};
}
}

View File

@ -3,9 +3,10 @@ import {randomBytes} from 'crypto';
import bcrypt from 'bcrypt';
import {registerHooks} from 'scwp';
import {DataTypes as Types} from 'sequelize';
import {DataTypes as Types, Op} from 'sequelize';
import BaseModel from './base';
import {allModels} from './registrar';
class User extends BaseModel {
@ -33,6 +34,19 @@ class User extends BaseModel {
});
}
async friends() {
const {Friendship} = allModels();
const friendships = await Friendship.findAll({
where: {
[Op.or]: [
{adderId: this.id},
{addeeId: this.id},
],
},
});
return friendships.map(({adderId, addeeId}) => (adderId === this.id ? addeeId : adderId));
}
validatePassword(plaintext) {
return bcrypt.compare(plaintext, this.hash);
}

View File

@ -1,5 +1,6 @@
import redis from 'redis';
import session from 'express-session';
import redis from 'redis';
import {registerHooks} from 'scwp';
const {
REDIS_HOST,
@ -20,3 +21,18 @@ export default (options = {}) => (
...options,
})
);
registerHooks({
hydration: async (req) => {
const hydration = {};
const {user} = req;
if (user) {
hydration.redditUsername = user.redditUsername;
hydration.friends = await user.friends();
}
else {
hydration.user = null;
}
return hydration;
},
}, module.id);

View File

@ -1924,6 +1924,11 @@ block-stream@*:
dependencies:
inherits "~2.0.0"
bluebird@^2.10.0:
version "2.11.0"
resolved "https://npm.i12e.cha0s.io/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=
bluebird@^3.5.5, bluebird@^3.7.2:
version "3.7.2"
resolved "https://npm.i12e.cha0s.io/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@ -2600,6 +2605,14 @@ concat-map@0.0.1:
resolved "https://npm.i12e.cha0s.io/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
concat-stream-p@0.1.2:
version "0.1.2"
resolved "https://npm.i12e.cha0s.io/concat-stream-p/-/concat-stream-p-0.1.2.tgz#5de0386a3d0a27e2013627f58cddb5c46d8e2d22"
integrity sha1-XeA4aj0KJ+IBNif1jN21xG2OLSI=
dependencies:
bluebird "^2.10.0"
concat-stream "^1.5.0"
concat-stream@^1.5.0:
version "1.6.2"
resolved "https://npm.i12e.cha0s.io/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"