Scenario generator for vore roleplay and story ideas. https://scenario-generator.deliciousreya.net/responses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

84 lines
3.3 KiB

import { type IRequestStrict, Router } from 'itty-router';
import type { Database } from '../db/database.js';
import { buildGeneratorPage, buildResponsesPage, wrapPage } from './template.js';
import { CSS, JS } from './client.generated.js';
import type { HashedBundled } from '../../common/bundle.js';
import { getSourceMapFileName, SourceMapExtension, SourceMaps } from './sourcemaps.js';
import { collapseWhiteSpace } from 'collapse-white-space';
import { getQuerySingleton, takeLast } from '../request/query.js';
interface WebEnv {
readonly BASE_URL: string,
readonly CREDITS_URL: string,
readonly DISCORD_APP_ID: string
}
export function webRouter(base: string) {
function getSourceMappedJS(name: keyof typeof JS) {
const { bundled, hash }: HashedBundled = JS[name];
return bundled + `\n//# sourceMappingURL=${getSourceMapFileName(name, hash, SourceMapExtension.JS)}`;
}
function getSourceMappedCSS(name: keyof typeof CSS) {
const { bundled, hash }: HashedBundled = CSS[name];
return bundled + `\n/*# sourceMappingURL=${getSourceMapFileName(name, hash, SourceMapExtension.CSS)} */`;
}
async function handleMainPage(req: IRequestStrict, env: WebEnv, db: Database): Promise<string> {
const startAt = performance.now()
const results = await db.getGeneratorPageForDiscordSet(getQuerySingleton(req.query['server'], takeLast));
const resultsAt = performance.now()
const generator = buildGeneratorPage({
creditsUrl: env.CREDITS_URL,
clientId: env.DISCORD_APP_ID,
baseUrl: env.BASE_URL,
results: results.rolled,
selected: results.selected,
includesResponses: true
})
const generatorAt = performance.now()
const responses = buildResponsesPage({
tables: Array.from(results.db.tables.values()),
results: results.rolled,
creditsUrl: env.CREDITS_URL,
includesGenerator: true
})
const responsesAt = performance.now()
const wrapped = wrapPage({
title: 'Vore Scenario Generator',
script: getSourceMappedJS('combinedGeneratorResponses'),
styles: getSourceMappedCSS('combinedGeneratorResponses'),
noscriptStyles: getSourceMappedCSS('noscript'),
bodyContent: [generator, responses].join('')
})
const wrappedAt = performance.now()
const trimmed = collapseWhiteSpace(wrapped, {style: 'html'})
const trimmedAt = performance.now()
console.log(`database: ${resultsAt - startAt}, generator: ${generatorAt - resultsAt}, responses: ${responsesAt - generatorAt}, wrapped: ${wrappedAt - responsesAt}, trimmed: ${trimmedAt - wrappedAt}`)
return trimmed;
}
const router = Router<IRequestStrict, [env: WebEnv, db: Database, ctx: ExecutionContext]>({ base })
.get('/responses', async (req, _env, _db, _ctx) => {
const url = new URL(req.url);
url.pathname = base;
url.hash = '#responses';
return Response.redirect(url.toString(), 303);
})
.get('/generator', async (req, _env, _db, _ctx) => {
const url = new URL(req.url);
url.pathname = base;
url.hash = '#generator';
return Response.redirect(url.toString(), 303);
})
.get('/scenario', async (_req, _env, _db, _ctx) => {
// TODO: implement me
return new Response('Not yet supported', { status: 404 });
})
.get('/', handleMainPage)
.post('/', handleMainPage);
for (const [filename, contents] of SourceMaps) {
router.get(`/${filename}`, () => contents);
}
return router;
}