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
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;
|
|
}
|
|
|