source move

main
Sam Thorogood 4 years ago
parent 39e3f6ed6e
commit 0d4df09d0a

@ -2,7 +2,6 @@ const fs = require('fs');
const mimeTypes = require('mime-types');
const path = require('path');
const watchTimeout = 30 * 1000;
@ -64,6 +63,7 @@ function watch(paths, done, timeout) {
return false;
});
if (!valid.length) {
console.info('bailing, could not find any valid', paths);
return null;
}
@ -76,6 +76,7 @@ function watch(paths, done, timeout) {
// dependant files anyway. This will only cause problems for scenes, which build whole dirs, but
// observing the directory reveals immediate subtree changes regardless.
watchers = valid.map((cand) => fs.watch(cand, {recursive: true}, shutdown));
console.info('got valid files to watch', valid);
return setTimeout(shutdown, timeout);
}
@ -117,15 +118,15 @@ async function load(loader, filename, cleanup) {
/**
* Builds a Koa transform which wraps the given Loader.
* Builds asynchronous HTTP middleware which wraps the given Loader.
*
* @param {function(string): ?Object} loader to load file from disk or build it
*/
module.exports = function(loader) {
const cached = {};
return async (ctx, next) => {
let filename = ctx.path.substr(1);
return async (req, res, next) => {
let filename = req.path.substr(1);
if (filename.endsWith('/') || filename === '') {
filename += 'index.html';
}
@ -138,12 +139,31 @@ module.exports = function(loader) {
cached[filename] = p;
}
const result = await p;
let result;
try {
result = await p;
}
catch (e) {
if (e.code === 'ENOENT') {
res.writeHead(404);
} else {
console.warn(filename, e);
res.writeHead(500);
}
return res.end();
}
if (result === null) {
return next();
}
ctx.response.body = result;
ctx.response.type = mimeTypes.lookup(filename) || ctx.response.type;
const headers = {};
const mimeType = mimeTypes.lookup(filename);
if (mimeType) {
// TODO: utf-8?
headers['Content-Type'] = mimeType;
}
res.writeHead(200, headers);
res.end(result);
};
};

@ -1,6 +1,6 @@
{
"name": "santatracker",
"version": "2018.1.0",
"version": "2019.1.0",
"license": "Apache-2.0",
"scripts": {
"start": "./serve.js",
@ -14,10 +14,12 @@
"@tensorflow-models/posenet": "^0.2.3",
"@tensorflow/tfjs": "^0.13.0",
"@webcomponents/webcomponentsjs": "latest",
"ansi-colors": "^3.1.0",
"autoprefixer": "^9.3.0",
"chai": "^4.2.0",
"chalk": "^2.4.2",
"clipboardy": "^2.1.0",
"dat.gui": "^0.7.3",
"dhost": "^0.1.7",
"event-target": "^1.2.3",
"fancy-log": "^1.3.2",
"fast-async": "^6.3.8",
@ -27,7 +29,8 @@
"jquery": "^3.3.1",
"jsdom": "^12.2.0",
"json5": "^2.1.0",
"koa": "^2.5.3",
"koa": "^2.7.0",
"koa-mount": "^4.0.0",
"koa-static": "^5.0.0",
"lit-element": "^2.2.1",
"mime-types": "^2.1.21",
@ -35,6 +38,7 @@
"mocha": "^5.2.0",
"mocha-headless-server": "^0.1.2",
"parse5": "^5.1.0",
"polka": "^0.5.2",
"pretty-ms": "^4.0.0",
"redux": "^4.0.1",
"rollup": "^0.66.6",

@ -80,6 +80,8 @@ body:not(.loading) #loader {
<noscript>
<meta http-equiv="refresh" content="0;url=/upgrade.html" />
</noscript>
<script type="module" src="loader.js"></script>
<script nomodule src="legacy.js"></script>
<script>
// nb. This code is intentionally ES5, as it runs minified (but not transpiled) on our minimum
// browser target (currently IE11), including for feature detection.

@ -1,11 +1,14 @@
#!/usr/bin/env node
const colors = require('ansi-colors');
const chalk = require('chalk');
const clipboardy = require('clipboardy');
const compileHtml = require('./build/compile-html.js');
const fsp = require('./build/fsp.js');
const i18n = require('./build/i18n.js');
const Koa = require('koa');
const koaStatic = require('koa-static');
const polka = require('polka');
const dhost = require('dhost');
const log = require('fancy-log');
const path = require('path');
@ -15,8 +18,8 @@ const yargs = require('yargs')
.option('port', {
alias: 'p',
type: 'number',
default: process.env.PORT || 5000,
describe: 'Serving port (+1 for prod)',
default: process.env.PORT || 8000,
describe: 'Static port',
})
.option('lang', {
type: 'string',
@ -26,17 +29,55 @@ const yargs = require('yargs')
.option('compile', {
type: 'boolean',
default: false,
describe: 'Compile dependencies',
describe: 'Compile complex dependencies',
})
.argv;
function listen(server, port) {
return new Promise((resolve) => server.listen(port, resolve));
return new Promise((r) => server.listen(port, 'localhost', r));
}
function clipboardCopy(v) {
try {
clipboardy.writeSync(v);
} catch (e) {
return e;
}
return null;
}
const messages = i18n(yargs.lang);
log(messages('santatracker'));
async function prod(req, res, next) {
let servePath = 'index.html';
const simplePathMatch = /^\/(\w+)\.html$/.exec(req.path);
if (simplePathMatch) {
const cand = `${simplePathMatch[1]}.html`;
const exists = await fsp.exists(path.join('prod', cand));
if (exists) {
// load the top-level path if the file doesn't already exist (e.g. error/upgrade/cast)
servePath = cand;
}
} else if (res.path !== '/') {
return next();
}
// compile the HTML locally to include i18n and static URL
const filename = path.join('prod', servePath);
const options = {
compile: yargs.compile,
messages,
body: {
static: staticURL,
},
};
res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
res.end(await compileHtml(filename, options));
}
async function serve() {
const loader = require('./loader.js')({
compile: yargs.compile,
@ -45,48 +86,24 @@ async function serve() {
});
const loaderTransform = require('./loader-transform.js');
const server = new Koa();
server.use(loaderTransform(loader));
server.use(koaStatic('.'));
await listen(server, yargs.port);
log(`=> ${colors.blue(`http://localhost:${yargs.port}`)}`);
const prod = new Koa();
prod.use(async (ctx, next) => {
const simplePathMatch = /^\/(\w+)\.html$/.exec(ctx.path);
if (simplePathMatch) {
const sceneName = simplePathMatch[1];
const exists = await fsp.exists(path.join('prod', `${sceneName}.html`));
if (!exists) {
// load the top-level path if the file doesn't already exist (e.g. error/upgrade/cast)
ctx.url = '/index.html';
}
} else if (ctx.path === '/') {
ctx.url = '/index.html';
}
const staticServer = polka();
staticServer.use(loaderTransform(loader));
staticServer.use('static', dhost({path: 'static', cors: true, listing: true}));
if (path.extname(ctx.path) !== '.html') {
return next();
}
await listen(staticServer, yargs.port + 1000);
const staticURL = `http://127.0.0.1:${yargs.port + 1000}/static`;
log('Static', chalk.green(staticURL));
// compile the HTML locally to include i18n and static URL
const filename = path.join('prod', ctx.path);
const options = {
compile: yargs.compile,
messages,
body: {
static: `http://localhost:${yargs.port}/index.html`,
},
};
ctx.response.body = await compileHtml(filename, options);
ctx.response.type = 'text/html';
});
prod.use(koaStatic('prod'));
const prodServer = polka();
prodServer.use(prod);
prodServer.use(dhost({path: 'prod', listing: false}));
// advertise 127.0.0.1, not localhost, as this emulates-ish CORS for Chrome
await listen(prod, yargs.port + 1);
log(`=> ${colors.blue(`http://127.0.0.1:${yargs.port + 1}`)} prod`);
// listen, copy and announce prod URL
await listen(prodServer, yargs.port);
const prodURL = `http://localhost:${yargs.port}`;
const clipboardError = clipboardCopy(prodURL);
const suffix = clipboardError ? chalk.red('(could not copy to clipboard)') : chalk.dim('(on your clipboard!)');
log('Prod', chalk.greenBright(`http://localhost:${yargs.port}`), suffix);
}
serve().catch((err) => {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save