31 tests in test/, run in a plain Node env with a tiny localStorage shim (no jsdom — its Node-22.4 transitive-dep breakage isn't worth working around for logic tests): - type-chart: modern effectiveness, dual-type stacking, and the era rules (no Fairy pre-6, Steel resists Ghost/Dark pre-6, the Gen 1 Ghost→Psychic and Bug↔Poison quirks). - damage-calc: nature multipliers, the Gen 3+ stat formula (Garchomp reference values), STAB/effectiveness/immunity, pre/post-Gen-6 crit. - savedex: a synthetic Gen 1 SRAM (bitfields + checksum) round-trips; checksum-mismatch and size guards. - selection: normalizeSelection v2→v3 migration, per-game isolation, global favourite, stats vs statsNational. - pokedex-resolver: prettify, dex resolution against a mini snapshot. `npm test` wired into CI after format:check. Also: docker-compose host port 8080 → 4753 (README updated). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
137 lines
5.3 KiB
Markdown
137 lines
5.3 KiB
Markdown
# Contributing to Pocketdex
|
|
|
|
Thanks for taking the time. This is a small, framework-free codebase and
|
|
easy to get into.
|
|
|
|
## Ground rules
|
|
|
|
- **No copyrighted assets.** Don't commit Pokémon sprites, artwork, audio,
|
|
ROMs or save files. Everything visual is fetched at runtime from PokéAPI.
|
|
PRs that add such files will be asked to remove them.
|
|
- **Non-commercial.** No ads, analytics, telemetry, paid tiers, affiliate
|
|
links or "sign in" flows.
|
|
- **Stay framework-free.** No React/Vue/Svelte/etc., and no new runtime
|
|
dependencies without discussing it in an issue first. Build-time dev
|
|
dependencies are a lower bar but still worth raising.
|
|
- **Offline-first stays true.** The list, search, sort, filters and game
|
|
switching must keep working with no network. New always-needed data goes
|
|
in the snapshot, not a runtime fetch.
|
|
- **Be kind.** Assume good faith in issues and reviews.
|
|
|
|
## Getting set up
|
|
|
|
Requires **Node 20+**.
|
|
|
|
```bash
|
|
npm install
|
|
npm run snapshot # build src/data/snapshot.json from PokéAPI (git-ignored)
|
|
npm run dev # http://localhost:5173
|
|
```
|
|
|
|
To exercise the service worker, offline behaviour or the install prompt,
|
|
you need a real build:
|
|
|
|
```bash
|
|
npm run build && npm run preview
|
|
```
|
|
|
|
## Where things live
|
|
|
|
See the **Project layout** and **How it works** sections in
|
|
[README.md](README.md). In short:
|
|
|
|
- `src/views/<Name>.js` — one file per route, an `async` function returning
|
|
a DOM node. Register it in `src/router.js`.
|
|
- `src/components/` — reusable pieces (`Card`, `Sprite`, `TypeChip`, …).
|
|
- `src/store/` — `createStore()`-backed reactive state, persisted to
|
|
`localStorage` under `pdx.*`.
|
|
- `src/lib/` — framework-y helpers with no app knowledge (`dom`, `anim`,
|
|
`damage-calc`, `savedex`, …).
|
|
- `src/data/` — the snapshot loader, the Pokédex resolver, the lazy PokéAPI
|
|
client, the type chart, natures.
|
|
- `scripts/build-snapshot.mjs` — the only thing that talks to PokéAPI at
|
|
build time.
|
|
|
|
## Code style
|
|
|
|
Formatting is **Prettier** (`.prettierrc.json`). Run `npm run format`
|
|
before committing; CI runs `npm run format:check` and will fail on
|
|
unformatted code. There's no ESLint — for everything Prettier doesn't
|
|
decide, **match the surrounding code**:
|
|
|
|
- 2-space indent, semicolons, single quotes, 100-col width, trailing
|
|
commas (all handled by Prettier).
|
|
- Build DOM with the `el()` helper from `src/lib/dom.js`, not template
|
|
strings or `innerHTML` (except the deliberate `html:` prop for trusted
|
|
inline SVG).
|
|
- Stores: `set(fn)` **replaces** state — spread `...s` yourself. Read with
|
|
`get()`, react with `subscribe()`, and unsubscribe in the view's
|
|
teardown (`onTeardown(view, off)`).
|
|
- Keep comments about _why_, not _what_. Match the existing density.
|
|
- Respect `prefersReducedMotion()` for any new animation.
|
|
- Keep everything game-aware: if you touch typings, type effectiveness,
|
|
learnsets or evolution, honour the selected game's generation
|
|
(`typesForGen`, `multiplier(atk, def, gen)`, `past_values`, …).
|
|
|
|
## Common tasks
|
|
|
|
**Add a setting** — add the key + default to `src/store/settings.js`
|
|
(and `applyTheme()` if it affects the document), then a field in
|
|
`src/views/SettingsView.js`. Add it to the export payload if it should
|
|
survive a backup.
|
|
|
|
**Add a snapshot field** — add it in `scripts/build-snapshot.mjs`, run
|
|
`npm run snapshot -- --force`, and consume it via `loadSnapshot()`. Keep
|
|
the snapshot small; it's precached on every install.
|
|
|
|
**Add a route** — new file in `src/views/`, one entry in the `routes`
|
|
array in `src/router.js`. Add a skeleton if the view does async work
|
|
before it can render.
|
|
|
|
## Testing your change
|
|
|
|
There's a small [Vitest](https://vitest.dev/) suite in `test/` covering
|
|
pure logic — the type chart, damage formula, the save-file parser, and the
|
|
per-game selection store. Run it with `npm test` (watch mode:
|
|
`npm run test:watch`). If you change any of those modules, update or add a
|
|
test. There are no UI/integration tests.
|
|
|
|
CI runs `npm run format:check`, `npm test`, and `npm run build`. Before
|
|
opening a PR also check by hand:
|
|
|
|
- The **dex grid** — filters, sort, the progress ring, catching from a
|
|
card.
|
|
- **Switching games** (the Games sheet) — regional numbers, era typings,
|
|
and per-game seen/caught all update.
|
|
- A **detail page** — every tab, form switching, the track buttons.
|
|
- `npm run preview` still works offline (DevTools → Network → Offline,
|
|
then reload).
|
|
- Light **and** dark theme, and a narrow (mobile) viewport.
|
|
|
|
Describe what you tested in the PR.
|
|
|
|
## Commits & pull requests
|
|
|
|
- Branch off `main`. One focused change per PR.
|
|
- Imperative commit subjects ("Add …", "Fix …"), with a body explaining
|
|
the _why_ when it isn't obvious.
|
|
- Don't commit `dist/` or `src/data/snapshot.json` (both git-ignored).
|
|
- Fill in the PR template. Screenshots or a short clip for anything
|
|
visual.
|
|
- It's fine to open a draft PR early to discuss direction.
|
|
- AI-assisted contributions are welcome — say so in the PR description if a
|
|
tool wrote a meaningful part of it, and review it yourself first. The
|
|
same bar applies either way. This project is itself built this way (see
|
|
the README).
|
|
|
|
## Reporting bugs
|
|
|
|
Open an issue with: what you did, what you expected, what happened, the
|
|
browser/OS, and the selected game if it's relevant. A screenshot or the
|
|
console output helps a lot.
|
|
|
|
## License
|
|
|
|
By contributing you agree that your contributions are licensed under the
|
|
[MIT License](LICENSE).
|