perf: pre-generate Bible verse data and reduce DOM via conditional rendering
- Extract Bible lookup logic into shared src/lib/server/bible.ts module - Add build script to pre-generate all 20 mystery verse lookups as static data, eliminating runtime API calls on rosary page load - Update Prayer.svelte to pass showLatin/urlLang as snippet parameters; all 14 prayer components now conditionally render only visible language elements instead of hiding via CSS - Extract 4 inline mystery selector SVGs into MysteryIcon.svelte component - Remove unused CSS selectors from angelus page
This commit is contained in:
@@ -1,94 +1,8 @@
|
||||
import { json, error } from '@sveltejs/kit';
|
||||
import type { RequestHandler } from './$types';
|
||||
import { lookupReference } from '$lib/server/bible';
|
||||
|
||||
interface BibleVerse {
|
||||
bookName: string;
|
||||
abbreviation: string;
|
||||
bookNumber: number;
|
||||
chapter: number;
|
||||
verseNumber: number;
|
||||
text: string;
|
||||
}
|
||||
|
||||
// Cache for parsed verses to avoid reading file repeatedly
|
||||
let cachedVerses: BibleVerse[] | null = null;
|
||||
|
||||
async function loadVerses(fetch: typeof globalThis.fetch): Promise<BibleVerse[]> {
|
||||
if (cachedVerses) {
|
||||
return cachedVerses;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/allioli.tsv');
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const content = await response.text();
|
||||
const lines = content.trim().split('\n');
|
||||
|
||||
cachedVerses = lines.map(line => {
|
||||
const [bookName, abbreviation, bookNumber, chapter, verseNumber, text] = line.split('\t');
|
||||
return {
|
||||
bookName,
|
||||
abbreviation,
|
||||
bookNumber: parseInt(bookNumber),
|
||||
chapter: parseInt(chapter),
|
||||
verseNumber: parseInt(verseNumber),
|
||||
text
|
||||
};
|
||||
});
|
||||
|
||||
return cachedVerses;
|
||||
} catch (err) {
|
||||
console.error('Error loading Bible verses:', err);
|
||||
throw new Error('Failed to load Bible verses');
|
||||
}
|
||||
}
|
||||
|
||||
function parseReference(reference: string): { bookRef: string; isFullName: boolean; chapter: number; startVerse: number; endVerse: number } | null {
|
||||
// Parse various reference formats:
|
||||
// "Mt 3, 16-17", "Mt3:16-17", "Mt 3:16-17", "Lk1:3", "Matthäus 3, 16-17"
|
||||
// Match book name (letters and umlauts), optional space, chapter, separator (: or ,), optional space, verse(s)
|
||||
const match = reference.match(/^([A-Za-zäöüÄÖÜß]+)\s*(\d+)[\s,:]+(\d+)(?:[-:](\d+))?$/);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [, bookRef, chapterStr, startVerseStr, endVerseStr] = match;
|
||||
|
||||
// If book reference is longer than 5 characters, assume it's a full name
|
||||
// Otherwise, assume it's an abbreviation
|
||||
const isFullName = bookRef.length > 5;
|
||||
|
||||
return {
|
||||
bookRef,
|
||||
isFullName,
|
||||
chapter: parseInt(chapterStr),
|
||||
startVerse: parseInt(startVerseStr),
|
||||
endVerse: endVerseStr ? parseInt(endVerseStr) : parseInt(startVerseStr)
|
||||
};
|
||||
}
|
||||
|
||||
function getVersesByReference(verses: BibleVerse[], reference: string): BibleVerse[] {
|
||||
const parsed = parseReference(reference);
|
||||
if (!parsed) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return verses.filter(v => {
|
||||
// Match based on whether we're using full name or abbreviation
|
||||
const bookMatches = parsed.isFullName
|
||||
? v.bookName === parsed.bookRef
|
||||
: v.abbreviation === parsed.bookRef;
|
||||
|
||||
return bookMatches &&
|
||||
v.chapter === parsed.chapter &&
|
||||
v.verseNumber >= parsed.startVerse &&
|
||||
v.verseNumber <= parsed.endVerse;
|
||||
});
|
||||
}
|
||||
|
||||
export const GET: RequestHandler = async ({ params, fetch }) => {
|
||||
export const GET: RequestHandler = async ({ params }) => {
|
||||
const reference = params.reference;
|
||||
|
||||
if (!reference) {
|
||||
@@ -96,25 +10,13 @@ export const GET: RequestHandler = async ({ params, fetch }) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const verses = await loadVerses(fetch);
|
||||
const matchedVerses = getVersesByReference(verses, reference);
|
||||
const result = lookupReference(reference);
|
||||
|
||||
if (matchedVerses.length === 0) {
|
||||
if (!result) {
|
||||
return error(404, 'No verses found for the given reference');
|
||||
}
|
||||
|
||||
// Extract book and chapter from first verse (they're all the same)
|
||||
const firstVerse = matchedVerses[0];
|
||||
|
||||
return json({
|
||||
reference,
|
||||
book: firstVerse.bookName,
|
||||
chapter: firstVerse.chapter,
|
||||
verses: matchedVerses.map(v => ({
|
||||
verse: v.verseNumber,
|
||||
text: v.text
|
||||
}))
|
||||
});
|
||||
return json(result);
|
||||
} catch (err) {
|
||||
console.error('Error fetching Bible verses:', err);
|
||||
return error(500, 'Failed to fetch Bible verses');
|
||||
|
||||
Reference in New Issue
Block a user