2026-06-30 18:49:27 +02:00
2026-06-30 19:17:55 +02:00
2026-09-26 13:24:24 +02:00
2026-09-26 13:24:24 +02:00
2026-06-30 19:37:27 +02:00
2026-09-29 10:22:57 +02:00
2026-09-26 13:24:24 +02:00
2026-09-29 10:22:57 +02:00

efits

A server-rendered site for EVE fits and skillplans. Each fit carries pyfa's simulation of it, and every number on a fit's page is coloured by where it ranks among the other fits on the same hull. A fit without a skillplan of its own borrows the newest plan on its hull. The fleet page adds fits up into wings and a fleet, and keeps the whole fleet in its link.

The browser gets HTML, the small scripts for the editors, the searches and the fleet page, and the fitter's components. Every list searches as the term is typed: fits in Typesense straight from the browser with a search-only key, and skillplans by the names already on the page. The fit lists also narrow by facets, either the hull's class, race, tech, meta and faction (joined from eve's eve-types) or the fit's own cap stability and sensors. They filter by ranges typed under the stat columns and sort on any of those columns, and the link holds all of it. The fitter also prices its shopping list from the browser with a select-only ClickHouse user. Everything else reaches ClickHouse and Typesense from the server.

Pages

/                               newest fits, or a search: ?q=, a facet (?group_name=Frigate),
                                a range (?targeting_misc_speed=2000..), ?sort=-defense_ehp_total
/ship/<hull>                    every fit on a hull, searched the same way
/ship/<hull>/fit/<id>           a fit
/ship/<hull>/fit/<id>/fit       the fit as EFT text
/ship/<hull>/fit/<id>/skillplan the plan it shows, as text
/fit/<id>                       redirects to the fit under its hull; /fit and /skillplan work here too
/skillplans                     every plan, or a search with ?q=
/skillplan/<id>                 a plan; /skillplan/<id>/skillplan is its text
/fleet?s=<base64 JSON>          a fleet
/fitter                         opens the first fitter workspace
/fitter/<id>                    a fitter workspace: fits and a hangar, and the shopping list between them

The fitter is the one page rendered from Svelte components, since it recomputes as it is edited. Its workspaces are shared, and every edit saves to /api/fitter/workspaces/<id>, where the server splits charges out of their modules and cuts pasted contracts into items. The browser prices the shopping list itself, off eve's market_orders as the select-only eve_market user, and finds the fits it adds in the efits-fits Typesense collection with the read-only efits_search key.

Every page also answers under /admin, where the fit list shows every fit and the fit and skillplan pages carry editors. Edits save as a field loses focus.

Code

src/middleware.ts picks the site a request is in and rewrites /admin reads to the public page. It also turns a thrown HttpError into its status and anything else into a 500. Pages load all their data in their own frontmatter, since a component that fails mid-render can no longer change the status.

src/lib holds everything that is not markup: the ClickHouse and Typesense clients, the stat definitions the fit page draws (stats.ts), ranking (compare.ts), skillplan parsing, and reading and totalling fleets. The browser scripts are in src/scripts, and admin writes go to the endpoints in src/pages/admin/api.

Data

realdb.toml declares the efits project on the shared ClickHouse: fits, skillplans and the fitter's workspaces. Each replaces on updated, so an edit or a delete is a new row. src/lib/realdb.ts is generated from it with realdb gen .ts. Skill ranks come from the EVE static data in Typesense.

typesense.toml is this repo's copy of the efits project on the shared Typesense: the fits collection the pyfa sync fills, and the keys that read it.

Commands

bun run dev     dev server on :4321
./vet.sh        tests, build and nag; done means it exits 0
task            tag, build and push the docker image, then deploy it with cooler
task publish    tag, build and push the docker image, tagged with the commit, latest and any tag on it
Description
No description provided
Readme 579 KiB
Languages
TypeScript 76.3%
Astro 12.4%
Svelte 11.1%