Instruction file imported from janmbaco/Kronometa (
.github/instructions/kronometa-src.instructions.md). Copyright stays with the author.
Kronometa Source Instructions
Scope
- Applies to source changes under
src/**. - Keep the feature-first structure.
- Keep race timing behavior real and domain-driven, not demo-only.
Component Boundaries
- Components expose reactive view state and user intentions.
- Components must not call race, storage, clock, or export services directly.
- Use
PickInitializerfor initial hydration before render. - Use
PickLifecycleManagerto subscribe to component intent properties and call services. - In decorators, resolving lifecycle/initializer factories through
Services.get(...)is allowed and expected. - Resolve dependencies by class, not string service tokens.
- Repeated components must receive a fresh
PickLifecycleManagerper component instance. Mark lifecycle managers as InjectKit@Transient({ deps: [...] })and resolve them withServices.get(LifecycleClass).
Domain and Services
- Keep the domain model unified for both
mass_startandstaggered_start. - Preserve these core concepts:
RaceMode = "mass_start" | "staggered_start"RunnerStatus = "pending" | "running" | "finished"- shared runner fields:
id,bib,label,status, optionalstartAt,finishAt,resultMs
- Compute live elapsed time against the current global clock.
- Freeze
resultMswhen a runner finishes. - Rank only finished runners by ascending
resultMs. - Compute gap as
resultMs - bestResultMs.
PickComponents Details
- Follow installed
pick-componentsbehavior and existing Kronometa usage. @Pickand@PickRenderare both valid. Choose based on clarity, locality, and feature ownership, not perceived capability.- Use
@Pickwhen compactctx.state,ctx.html,ctx.css,ctx.listen,ctx.on,ctx.initializer, orctx.lifecyclemakes the component clearer. - Use
@PickRenderwhen explicit class fields, methods,@Listen, or separate initializer/lifecycle classes make the feature clearer. - Use
pick-actionfor intent events where it matches existing local patterns. - Use
pick-selectfor conditional branches. - Use
pick-forfor repeated rows/items. - For delegated
@Listen(selector, event)handlers, derive the matched element fromevent.target.closest(...). - App services use
@janmbaco/injectkitdecorators. Prefer@Singleton()for domain/app services and@Transient({ deps: [...] })for initializers/lifecycle managers. - Keep
src/app/app-injectables.tsaligned when adding a new decorated service, initializer, or lifecycle manager. - Keep InjectKit container initialization explicit in
src/main.ts;Services.get(...)should resolve only, not build the container.
Styling and UI
- Keep Pico CSS as the base.
- Add project CSS only when it supports the timing UI clearly.
- Keep the primary experience immediate and functional.
- Do not add marketing/landing-page framing.
- Preserve clean, readable mobile layouts.
Validation
- After source changes, run:
npm run typecheck
npm run build
- For timing or rendering changes, verify at least one realistic race flow in the browser.