98 lines
3.2 KiB
TypeScript
98 lines
3.2 KiB
TypeScript
|
import { logger } from './rendertron.logging.js';
|
||
|
import { PrerenderResult } from './rendertron.classes.prerenderresult.js';
|
||
|
import * as plugins from './rendertron.plugins.js';
|
||
|
|
||
|
export class PrerenderManager {
|
||
|
public smartssrInstance: plugins.smartssr.SmartSSR;
|
||
|
public smartrobotsInstance: plugins.smartrobots.Smartrobots;
|
||
|
public smartsitemapInstance: plugins.smartsitemap.SmartSitemap;
|
||
|
|
||
|
constructor() {}
|
||
|
|
||
|
/**
|
||
|
* starts the manager
|
||
|
*/
|
||
|
public async start() {
|
||
|
this.smartssrInstance = new plugins.smartssr.SmartSSR();
|
||
|
this.smartrobotsInstance = new plugins.smartrobots.Smartrobots();
|
||
|
this.smartsitemapInstance = new plugins.smartsitemap.SmartSitemap();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* stops the manager
|
||
|
*/
|
||
|
public async stop() {}
|
||
|
|
||
|
public async getPrerenderResultForUrl(urlArg: string): Promise<string> {
|
||
|
const done = plugins.smartpromise.defer<string>();
|
||
|
const prerenderResult = await PrerenderResult.getPrerenderResultForUrl(this, urlArg).catch(
|
||
|
() => {
|
||
|
done.resolve(`Cannot render ${urlArg} due to internal error.`);
|
||
|
return null;
|
||
|
}
|
||
|
);
|
||
|
done.resolve(prerenderResult.renderResultString);
|
||
|
return done.promise;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* prerenders a sitemap
|
||
|
*/
|
||
|
public async prerenderDomain(domainArg: string) {
|
||
|
logger.log('info', `prerendering domain: ${domainArg}`);
|
||
|
await this.getPrerenderResultForUrl(`https://${domainArg}/`).catch((err) => {
|
||
|
logger.log('error', `failed to prerender ${domainArg}`);
|
||
|
});
|
||
|
await this.getPrerenderResultForUrl(`https://${domainArg}`).catch((err) => {
|
||
|
logger.log('error', `failed to prerender ${domainArg}`);
|
||
|
});
|
||
|
const robotsTxt = await this.smartrobotsInstance
|
||
|
.parseRobotsTxtFromUrl(`https://${domainArg}/robots.txt`)
|
||
|
.catch((err) => {
|
||
|
logger.log('warn', `no robots for ${domainArg}`);
|
||
|
});
|
||
|
if (!robotsTxt) {
|
||
|
return;
|
||
|
}
|
||
|
if (robotsTxt.sitemaps.length === 0) {
|
||
|
logger.log('warn', `robot-txt for ${domainArg} does bot sepcify any sitemaps`);
|
||
|
}
|
||
|
for (const sitemapUrl of robotsTxt.sitemaps) {
|
||
|
await this.prerenderSitemap(sitemapUrl);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public async prerenderSitemap(sitemapUrlArg: string) {
|
||
|
logger.log('info', `prerendering sitemap: ${sitemapUrlArg}`);
|
||
|
const parsedSitemap = await this.smartsitemapInstance.parseSitemapUrl(sitemapUrlArg);
|
||
|
if (!parsedSitemap.urlset?.url) {
|
||
|
return;
|
||
|
}
|
||
|
if (!(parsedSitemap.urlset.url instanceof Array)) {
|
||
|
await this.getPrerenderResultForUrl(parsedSitemap.urlset.url.loc);
|
||
|
} else {
|
||
|
for (const url of parsedSitemap.urlset.url) {
|
||
|
if (!url?.loc) {
|
||
|
continue;
|
||
|
}
|
||
|
await this.getPrerenderResultForUrl(url.loc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public async cleanPrerenderResults() {
|
||
|
const allPrerenderResults = await PrerenderResult.getInstances<PrerenderResult>({});
|
||
|
for (const prerenderResult of allPrerenderResults) {
|
||
|
const extendedDate = plugins.smarttime.ExtendedDate.fromMillis(prerenderResult.timestamp);
|
||
|
const stillValid = extendedDate.lessTimePassedToNow({ hours: 24 });
|
||
|
if (!stillValid) {
|
||
|
logger.log(
|
||
|
'warn',
|
||
|
`deleted prerender result for ${prerenderResult.url} since it is older than 24 hours`
|
||
|
);
|
||
|
await prerenderResult.delete();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|