Implement the 029-on-demand-bestiary feature that replaces the bundled XMM bestiary JSON with a compact search index (~350KB) and on-demand source loading, where users explicitly provide a URL or upload a JSON file to fetch full stat block data per source, which is then normalized and cached in IndexedDB (with in-memory fallback) so creature stat blocks load instantly on subsequent visits while keeping the app bundle small and never auto-fetching copyrighted content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-10 22:46:13 +01:00
parent 99d1ba1bcd
commit 91120d7c82
31 changed files with 38321 additions and 63422 deletions

View File

@@ -75,6 +75,23 @@ export interface Creature {
readonly spellcasting?: readonly SpellcastingBlock[];
}
export interface BestiaryIndexEntry {
readonly name: string;
readonly source: string;
readonly ac: number;
readonly hp: number;
readonly dex: number;
readonly cr: string;
readonly initiativeProficiency: number;
readonly size: string;
readonly type: string;
}
export interface BestiaryIndex {
readonly sources: Readonly<Record<string, string>>;
readonly creatures: readonly BestiaryIndexEntry[];
}
/** Maps a CR string to the corresponding proficiency bonus. */
export function proficiencyBonus(cr: string): number {
const numericCr = cr.includes("/")

View File

@@ -13,6 +13,8 @@ export {
VALID_CONDITION_IDS,
} from "./conditions.js";
export {
type BestiaryIndex,
type BestiaryIndexEntry,
type BestiarySource,
type Creature,
type CreatureId,