-
Notifications
You must be signed in to change notification settings - Fork 0
/
glitch-please.js
103 lines (96 loc) · 3.13 KB
/
glitch-please.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
const http = require('http');
const reload = require('reload');
const express = require('express');
const cheerio = require('cheerio');
const chokidar = require('chokidar');
const exec = require('child_process').exec;
const interceptor = require('express-interceptor');
let WAITING = false;
let RUNNING = false;
let START = new Date();
// Runs a command and keeps track of when it finishes.
const newCmd = (cmd, cb) => {
RUNNING = true;
return exec(cmd, (error, stdout, stderr) => {
if (error) {
console.error(`${error}`);
return;
}
console.log(`${stdout}`);
console.log(`${stderr}`);
RUNNING = false;
cb();
});
};
// Waits until changes stop coming in for one second.
const waitForPause = callback => {
const check = () => {
const now = new Date();
if(RUNNING || now - START < 1000){
setTimeout(check, 20);
} else {
callback();
}
};
check();
};
// Creates a static file server that can reload clients when a build completes.
// Watches files for changes and kicks off a build when there is a pause in changes.
module.exports = function(watchPlease, runPlease, staticPlease) {
const watcher = chokidar.watch(watchPlease);
watcher.on('ready', () => {
// Wait until the initial scan is done, then start regenerating
// whenever a file changes.
watcher.on('all', () => {
START = new Date();
if (!WAITING) {
WAITING = true;
waitForPause(() => {
console.log('BEGIN GENERATING SITE');
WAITING = false;
newCmd(runPlease, () => {
console.log('DONE GENERATING SITE');
reloadServer.reload();
});
});
}
});
});
const scriptInterceptor = interceptor((req, res) => ({
// Only HTML responses will be intercepted
isInterceptable() {
return /text\/html/.test(res.get('Content-Type'));
},
// Appends a script tag at the end of the response body
intercept(body, send) {
const $document = cheerio.load(body);
$document('body').append('<script src="/reload/reload-client.js"></script>');
$document('body').append(`
<script>
var article = document.getElementsByTagName('ARTICLE')[0];
var h1 = document.createElement('H1');
var t1 = document.createTextNode('docObject');
h1.appendChild(t1);
var pre = document.createElement('PRE');
pre.className = 'prettyprint lang-json';
var t2 = document.createTextNode(JSON.stringify(docObject, null, ' '));
pre.appendChild(t2);
article.appendChild(h1);
article.appendChild(pre);
</script>
`);
send($document.html());
}
}));
// Creates the static file server capable of reloading clients.
const app = express();
app.set('port', process.env.PORT || 3000)
app.use('/reload', express.static(`${__dirname}/node_modules/reload/lib`));
app.use(scriptInterceptor);
app.use(express.static(staticPlease));
const server = http.createServer(app);
const reloadServer = reload(server, app);
server.listen(app.get('port'), () => {
console.log(`Web server listening on port ${app.get('port')}`);
});
};