91 lines
3.6 KiB
TypeScript
91 lines
3.6 KiB
TypeScript
|
import * as plugins from './rendertron.plugins.js';
|
||
|
import * as paths from './rendertron.paths.js';
|
||
|
import { logger } from './rendertron.logging.js';
|
||
|
import { PrerenderResult } from './rendertron.classes.prerenderresult.js';
|
||
|
import { PrerenderManager } from './rendertron.classes.prerendermanager.js';
|
||
|
import { TaskManager } from './rendertron.taskmanager.js';
|
||
|
|
||
|
export class Rendertron {
|
||
|
public projectinfo: plugins.projectinfo.ProjectInfo;
|
||
|
public serviceServerInstance: plugins.typedserver.utilityservers.UtilityServiceServer;
|
||
|
public prerenderManager: PrerenderManager;
|
||
|
public taskManager: TaskManager;
|
||
|
|
||
|
/**
|
||
|
* starts the financeflow instance
|
||
|
*/
|
||
|
public async start() {
|
||
|
this.projectinfo = new plugins.projectinfo.ProjectInfo(paths.packageDir);
|
||
|
this.prerenderManager = new PrerenderManager();
|
||
|
this.taskManager = new TaskManager(this);
|
||
|
await this.prerenderManager.start();
|
||
|
await this.taskManager.start();
|
||
|
this.serviceServerInstance = new plugins.typedserver.utilityservers.UtilityServiceServer({
|
||
|
serviceDomain: 'rendertron.lossless.one',
|
||
|
serviceName: 'rendertron',
|
||
|
serviceVersion: this.projectinfo.npm.version,
|
||
|
addCustomRoutes: async (serverArg) => {
|
||
|
serverArg.addRoute(
|
||
|
'/render/*',
|
||
|
new plugins.typedserver.servertools.Handler('GET', async (req, res) => {
|
||
|
const requestedUrl = req.url.replace('/render/', '');
|
||
|
logger.log('info', `Got SSR request for ${requestedUrl}`);
|
||
|
if (requestedUrl.startsWith('https://url(')) {
|
||
|
logger.log('warn', `relative url error for ${requestedUrl}`);
|
||
|
res.status(500);
|
||
|
res.write('error due to relative protocol');
|
||
|
res.end();
|
||
|
return;
|
||
|
}
|
||
|
const originResponse = await plugins.smartrequest
|
||
|
.request(
|
||
|
requestedUrl,
|
||
|
{
|
||
|
method: 'GET',
|
||
|
keepAlive: false,
|
||
|
// headers: req.headers,
|
||
|
},
|
||
|
true
|
||
|
)
|
||
|
.catch((error) => {
|
||
|
logger.log('warn', `the origin request errored for ${requestedUrl}`);
|
||
|
res.write(`rendertron encountered an error for ${requestedUrl}`);
|
||
|
res.end();
|
||
|
});
|
||
|
if (!originResponse) {
|
||
|
return;
|
||
|
}
|
||
|
for (const header of Object.keys(originResponse.headers)) {
|
||
|
res.setHeader(header, originResponse.headers[header]);
|
||
|
}
|
||
|
if (originResponse.headers['content-type']?.includes('text/html')) {
|
||
|
logger.log('info', `Piping ${requestedUrl} through smartssr.`);
|
||
|
res.write(await this.prerenderManager.getPrerenderResultForUrl(requestedUrl));
|
||
|
res.end();
|
||
|
} else {
|
||
|
logger.log('info', `Serving ${requestedUrl} directly.`);
|
||
|
for (const headerKey of Object.keys(originResponse.headers)) {
|
||
|
console.log(`${headerKey}: ${originResponse.headers[headerKey]}`);
|
||
|
res.set(headerKey, originResponse.headers[headerKey]);
|
||
|
}
|
||
|
originResponse.on('data', (data) => {
|
||
|
res.write(data);
|
||
|
});
|
||
|
originResponse.on('end', () => {
|
||
|
res.end();
|
||
|
});
|
||
|
}
|
||
|
})
|
||
|
);
|
||
|
},
|
||
|
});
|
||
|
await this.serviceServerInstance.start();
|
||
|
}
|
||
|
|
||
|
public async stop() {
|
||
|
this.serviceServerInstance ? await this.serviceServerInstance.stop() : null;
|
||
|
this.prerenderManager ? await this.prerenderManager.stop() : null;
|
||
|
this.taskManager ? await this.taskManager.stop() : null;
|
||
|
}
|
||
|
}
|