Files
Epic-The-Musical-Timeline/docs/ARCHITECTURE.md
T

3.3 KiB

Architecture

How epic-the-musical-timeline is built today. Update in the same commit as any structural change.

Overview

A Bun server (Bun.serve) with HTML-import routes serves an index page and seven mockup pages. Bun's bundler turns each HTML page and its imported TS/CSS into hashed assets. bun run build bundles the server and every page into dist/; the Docker image runs that bundle. All pages read one typed sample dataset and mount one shared credits snippet.

Map

Path Responsibility
src/server.ts startServer(port): routes /, /mockups/NN-slug/ (+ 302 from the no-slash form), 404 otherwise. Runs when import.meta.main; PORT env, default 3000.
src/index.html, src/index.ts, src/index.css Index page: static cards linking each mockup, then mountCredits().
src/mockups/registry.ts mockups: MockupInfo[] — slug, number, name, pitch, what to try.
src/mockups/NN-slug/ One design direction: index.html (links ../../shared/credits.css, has <footer data-fan-credits>), main.ts, style.css, plus optional helper modules (e.g. scene.ts, layout.ts).
src/data/types.ts Saga, Song, Part, Motif, StoryTime, OdysseyRef, Video.
src/data/sample.ts sagas, motifs, songs. Placeholder lyrics; unverified fields // TODO(verify).
src/data/query.ts songsWithMotif, motifsInSong, gapYears, sagaOf.
src/shared/credits.ts FAN_NOTICE, mountCredits(target?).
src/shared/audio-slot.ts createAudioSlot(song): <audio> for song.audio, else an empty-state slot.
src/shared/video-cards.ts createVideoCards(song): YouTube link cards, no embeds.
src/shared/credits.css Styles for credits, audio slot, video cards.
tests/ data.test.ts (dataset invariants), shared.test.ts (DOM modules under happy-dom), server.test.ts (every route 200s, index links every registry slug, each mockup has the credits hook).
Dockerfile Two-stage oven/bun:1.3: install + build, then copy dist/ and run from WORKDIR /app/dist.

Data flow

  1. Request hits Bun.serve; an HTML-import route returns the bundled page (dev: bundled on demand with HMR via bun --hot; production: prebuilt assets from dist/).
  2. The page's main.ts imports src/data/* and src/shared/* (bundled in; no runtime API).
  3. main.ts renders the direction and calls mountCredits() into <footer data-fan-credits>.

External dependencies

None at runtime. Fonts (@fontsource/*) and three.js are bundled from npm. Outbound links only: YouTube (video cards) and Project Gutenberg (Odyssey references) — the site works without them.

Invariants

  • Every page renders FAN_NOTICE via mountCredits().
  • src/server.ts routes, src/mockups/registry.ts and the cards in src/index.html list the same slugs (tests/server.test.ts).
  • Every motif id used by a part exists; every motif appears in at least one song (tests/data.test.ts).
  • No two mockups ship byte-identical style.css (the build fails otherwise).

Known rough edges

  • The production bundle only runs with dist/ as the cwd (bun run start, Docker WORKDIR /app/dist); bun dist/server.js from the repo root crashes. See docs/TODO.md.
  • Routes, registry and index cards are three hand-maintained lists. See docs/TODO.md.