UNPKG

endfield-mcp

Version:

MCP Server for Arknights: Endfield (TypeScript / stdio + Streamable HTTP)

105 lines (104 loc) • 5.01 kB
/** * Worldview reader core — store binding, RichContent bridge, catalog loading. * * This module is the shared spine of the worldview (PRTS archive + in-game * wiki) domain, mirroring `storyCore.ts`'s role in the story domain. It owns * the JsonStore reference, the RichContentTable bridge cache, and the * eager-loaded catalog caches (categories, first-level groups, wiki * structure). The categories/documents/search sub-modules import the lazy * loaders exported here. * * ## The RichContent bridge (the one worldview-specific capability) * * Unlike the tables domain (where `{id, text}` carries a direct int64 hash), * PRTS documents carry a **string `contentId`** (e.g. "text_v0d8_10"). That * key indexes RichContentTable.json, whose entry is a titled list of content * segments: * * `RichContentTable[contentId]` = `{ title: {id, text}, contentList: [{content: {id, text}}, ...] }` * * Each segment's `content.id` is an int64 hash resolved through i18n. * `resolveContent(contentId)` walks that structure and concatenates the * resolved segments into one body string (image tags like `<image>...</image>` * are passed through verbatim — the caller decides whether to render them). * * This keeps `texts.ts` hash-only (its design contract) while giving the * worldview domain a contentId resolver. The bridge is local to this module. * * ## Loading strategy * * Catalogs (categories / firstLv / wiki categories+groups) load eagerly on * first access — together they are <1.5MB. The RichContentTable (~390KB, * 586 entries) also loads eagerly because document bodies and the search * index both need it. All parsed once and cached for the process lifetime; * invalidated together on sync refresh via `clearWorldviewCatalogCaches()`. * * ## Cache lifecycle * * This module owns the RichContent + catalog caches. `clearWorldviewCatalogCaches()` * resets just those. The full-domain orchestrators (`bindWorldviewStore`, * `clearWorldviewCaches`) live in `./worldview.ts` (the barrel facade) so * they can clear sibling caches atomically without this module reaching into * its siblings (preserving one-directional layering). */ import type { JsonStore } from "./stores.js"; import type { LocalizedText } from "./texts.js"; import type { PrtsCategory, PrtsFirstLvGroup, PrtsItem, WikiCategory, WikiGroup } from "./worldviewTypes.js"; /** One segment of a RichContent entry — its text, keyed by an int64 hash. */ interface RawRichContentSegment { content: LocalizedText; } /** A RichContentTable entry — a titled list of content segments. */ interface RawRichContentEntry { title?: LocalizedText; contentList?: RawRichContentSegment[]; } /** * Wire the JsonStore. Called once at startup by the barrel's * `bindWorldviewStore` orchestrator, which also clears all sibling caches. */ export declare function setWorldviewStore(store: JsonStore): void; /** Reset only the caches owned by this module (RichContent + catalogs). */ export declare function clearWorldviewCatalogCaches(): void; /** Whether the worldview bundle is present in the bound store. */ export declare function hasWorldviewData(): boolean; export declare function store(): JsonStore; /** * The RichContentTable as a `Map<string, RawRichContentEntry>`. * * Loaded eagerly and cached. Built with `readJsonInt64Safe` because the * `id` values in title/content are int64 hashes stored as numeric literals * upstream (plain readJson would truncate them — the same hazard texts.ts * guards against). */ export declare function richContentTable(): Map<string, RawRichContentEntry>; /** PRTS categories, sorted by `order`. */ export declare function prtsCategories(): PrtsCategory[]; /** First-level groups, sorted by `order`. */ export declare function firstLvGroups(): PrtsFirstLvGroup[]; /** * All PRTS narrative items, keyed by id. * * Built as a Map because both document reads and search look items up by id * repeatedly — an O(1) lookup beats a linear scan over 414 entries each time. */ export declare function allItems(): Map<string, PrtsItem>; /** Wiki categories, sorted by `categoryPriority` (lower first). */ export declare function wikiCategories(): WikiCategory[]; /** Wiki groups keyed by category id. */ export declare function wikiGroups(): Map<string, WikiGroup[]>; /** * Resolve a PRTS item's body text via its `contentId` string key. * * Walks the RichContent entry: resolves each `contentList` segment's int64 * hash through i18n and joins them with newlines. The entry's `title` is * intentionally NOT included here — the item's own `name` field already * carries the title (resolved separately by callers), so folding it in would * duplicate it. * * Returns the concatenated body, or `""` when the contentId is missing/empty * or has no resolvable segments (some items — e.g. multimedia with no * transcript — legitimately have none). */ export declare function resolveContent(contentId: string | undefined): string; export {};