Skip to content

Latest commit

 

History

History
153 lines (121 loc) · 6.91 KB

File metadata and controls

153 lines (121 loc) · 6.91 KB

Contributing to Torchtimer

Contributions are welcome: bug fixes, accessibility improvements, UX enhancements, and build tooling changes. This guide covers local setup, conventions, and the PR process.

Local setup

Prerequisites: Deno v2+.

Clone with --recurse-submodules (or run git submodule update --init after cloning) to populate common-web/.

On the submodule: common-web includes web components shared by other Lodes & Lanterns projects. Torchtimer is self-contained and deployed on its own subdomain.

Dev server

deno task dev
# open http://localhost:3000

Starts an esbuild dev server at the project root. CSS and HTML changes take effect on refresh. TypeScript changes are bundled on demand with no rebuild step.

Full build

Bundles TypeScript, cache-busts assets, and assembles the staging/ deploy payload:

deno task build

Serve and browse the result:

cd staging
deno run --allow-net --allow-read jsr:@std/http/file-server --port 8000
# open http://localhost:8000

Testing

Unit tests cover the pure-logic modules. Run them with:

deno task test

No flags required; the tested modules don't access the DOM, filesystem, or network.

File What it covers
tests/timer.test.ts Timer lifecycle: create, light, add time, tick, pause, reset, death; round mode create, advance, add, convert
tests/sync.test.ts serializeForSync and deserializeFromSync across all four timer states
tests/share.test.ts buildFragment, decodeFragmentToData encoding/decoding, round-trips
tests/flame.test.ts flameParams, glowParams, computeWind, computeHeadBg
tests/sway.test.ts computeTorchSway: determinism, amplitude, seed independence, bounds
tests/noise.test.ts valueNoise and fbm: range, determinism, octave stacking
tests/smokegl.test.ts buildSmokeInstances: empty pool, particle layout, instance count
tests/cracks.test.ts generateCracks: structure, determinism
tests/qr.test.ts getQrModules: module grid dimensions, content variation
tests/utils.test.ts formatTime, nextTorchNumber, and other pure utility functions

The DOM-manipulating and WebGL setup code in render.ts, dom.ts, torches.ts, overlay.ts, live.ts, viewer.ts, audio.ts, and main.ts requires a browser environment and is not covered.

When to add tests: any new pure function (no DOM, no network, deterministic output) should have unit tests. When fixing a bug in a pure function, add a regression test that would have caught it before adding the fix. Don't write tests for coverage alone; write them to document a real behavior or guard a real failure mode.

Guidelines

  • No framework. The frontend is plain TypeScript with native ES modules and a thin esbuild bundling step.
  • No CSS framework. All styles live in css/ and common-web/ using custom properties.
  • Minimal dependencies. Torchtimer aims for as few dependencies as reasonably possible.
  • Pure functions, please. Extract pure logic out of modules without DOM dependencies so they can be unit tested. Side-effectful code (rendering, WebGL, event handlers) is expected to be manually tested.
  • Module structure. src/main.ts is the entry point (wiring + boot only). Logic lives in:
    • src/timer.ts: immutable timer state machine (unlit/running/paused/dead) for both time-based and round-based modes
    • src/sync.ts: live-sync serialization/deserialization
    • src/share.ts: URL fragment encoding and decoding
    • src/types.ts: shared TypeScript types and interfaces
    • src/state.ts: global application state singletons and shared constants
    • src/utils.ts: pure math, color, and formatting utilities
    • src/noise.ts: 2D value noise and fractal Brownian motion
    • src/flame.ts: particle system parameter computation for flame, smoke, and sparks
    • src/sway.ts: per-torch body sway computation
    • src/glow.ts: canvas and DOM glow effects for lit torches
    • src/cracks.ts: procedural glowing crack lines and specks on the torch head
    • src/audio.ts: procedural per-torch audio (flame and popping sounds)
    • src/render.ts: per-frame render loop
    • src/dom.ts: DOM manipulation for torch elements
    • src/torches.ts: torch lifecycle and interaction
    • src/duration.ts: Pass Time/Rounds, Add Time/Rounds, custom duration modal, and mode toggle logic
    • src/live.ts: Torchbearer live-hosting UI and session management
    • src/viewer.ts: viewer mode entry, exit, and poll-driven state application
    • src/overlay.ts: canvas overlay initialisation and resize handling
    • src/smokegl.ts: WebGL2 instanced smoke particle renderer
  • Build script is build-time only. build.ts handles bundling and cache-busting. No runtime logic belongs there.

Deployment

Deployment is fully automated via GitHub Actions (.github/workflows/deploy.yml).

On every push to main, the workflow runs tests, builds to staging/, and force-pushes that directory to the gh-pages branch. GitHub Pages serves that branch at torchtimer.lodesandlanterns.com. After a successful deploy, the workflow tags the commit with the current UTC date in CalVer format (YYYY.MM.DD), appending a numeric patch suffix if multiple releases land on the same day (2026.03.28 -> 2026.03.28.1, etc.).

PRs to main run tests automatically via .github/workflows/test.yml.

The live sync backend, torchtimer-service, is a Cloudflare Worker deployed separately using Wrangler.

Filing issues

Open an issue in this repository for bugs, accessibility problems, or feature requests.

Pull requests

  1. Fork the repository and create a branch.
  2. Make your changes. Test locally using the dev workflow above.
  3. Open a PR against main with a clear description of what changed and why.
  4. CI runs tests automatically. A failing test run blocks merge.

Keep PRs focused. A bug fix and an unrelated refactor are two separate PRs. If you're unsure whether a larger change is the right direction, open an issue to discuss first.