Imported from emptylower/seichigo (
features/map/AGENTS.md). Install upstream withnpx skills add emptylower/seichigo --skill map. Copyright stays with the author.
MAP FEATURE MODULE
OVERVIEW
features/map/ is the primary client-side map feature module (21 files, 8952 lines). Uses a "mega-hook ctx injection" pattern where AnitabiMapPageClientImpl.tsx (~800 lines) orchestrates state passed to specialized hooks.
STRUCTURE
features/map/
|- AnitabiMapPageClientImpl.tsx # Main orchestrator (~800 lines, ctx hub)
|- AnitabiMapPageClient.tsx # Universal entry point
`- anitabi/
|- shared.ts # Types, constants, FIFO cache (~776 lines)
|- useAnitabiBootstrapData.ts # Data fetching, pagination, caching
|- useAnitabiWarmup.ts # Image/metadata preloading (~694 lines)
|- useAnitabiSelection.ts # Selection state machine, URL sync
|- useAnitabiDerivedState.ts # Filtering, sorting, distance computation
|- useCompleteMode.ts # "Complete" visualization mode (~788 lines)
|- useMapInteractionActions.tsx # Click/hover handlers (~661 lines)
|- media.ts # Image/URL helpers (~685 lines)
|- AnitabiMapLayout.tsx # Visual shell (sidebar, panels, map)
`- geo.ts # Spatial math utilities
WHERE TO LOOK
| Task | Location | Notes |
|---|---|---|
| Bootstrap data flow | anitabi/useAnitabiBootstrapData.ts |
Manifest → cards → detail fetch chain |
| Selection behavior | anitabi/useAnitabiSelection.ts |
State machine for bangumi/point selection |
| Performance preloading | anitabi/useAnitabiWarmup.ts |
Parallel image/metadata warmup with cacheStoreRef |
| Complete mode logic | anitabi/useCompleteMode.ts |
Extended visualization with all points |
| Map interaction | anitabi/useMapInteractionActions.tsx |
Click, hover, popup triggers |
| Shared types/cache | anitabi/shared.ts |
bangumiDetailCache (FIFO Map), constants, L dict |
CONVENTIONS
- State flows through a single
ctxobject from AnitabiMapPageClientImpl to hooks — do not create parallel state channels. - Extensive useRef for MapLibre instances and abort controllers — avoid converting refs to useState.
- Manual FIFO cache in shared.ts bypasses render cycles intentionally — do not replace with React state.
- Rendering logic belongs in
components/map/; state/data logic stays here.
ANTI-PATTERNS
- Do not add useState where useRef is used for performance (MapLibre instances, abort controllers, counters).
- Do not break the ctx injection pattern by creating new contexts or stores.
- Do not move data transformation logic into
components/map/render paths. - Do not add direct Prisma or server calls — this is client-only code.
NOTES
- 8 of 21 files exceed 500 lines; most are on the line-budget allowlist.
- Data flow: Bootstrap → Warmup → Selection → DerivedState → Render.
QuickPilgrimageMode(incomponents/quickPilgrimage/) consumes data from this module's state.- Warmup progress has two calibers (since 2026-09): internal
warmupProgress/warmupMetricRefkeep the 4-task weighted model (map/cards/details/images,WARMUP_TASK_WEIGHTS); the visible progress card is derived inuseAnitabiMapControllerviaWARMUP_VISIBLE_TASK_WEIGHTS(map+cards only). details/images prefetch continues in background — do not feed them back into the visible card. - Visible card copy is gated at the source (since 2026-09-10):
useWarmupProgressState.updateWarmupTaskonly lets map/cards write the visiblewarmupProgress.detail; details/images fine-grained text (e.g. 点位分块/图片预热) still lands inwarmupMetricRef.last_progress_detailfor server/log diagnostics only.