Skip to content

Latest commit

 

History

History
64 lines (53 loc) · 3.6 KB

File metadata and controls

64 lines (53 loc) · 3.6 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

crystal is a Scala library that provides a toolbelt for building reactive UI apps in Scala. It targets Scala 3 and cross-compiles to both the JVM and Scala.js. Publishing (organization, versioning, Maven Central release) is handled by the sbt-lucuma-lib plugin under the edu.gemini organization — the com.rpiaggio coordinate in the README badge is outdated. The README has extensive, authoritative API documentation — read it before changing public APIs.

Core abstractions:

  • Pot[A] / PotOption[A] (modules/core/shared): sum types for delayed/requested values (Pending / Ready / Error, plus ReadyNone for PotOption).
  • ViewF[F, A] and variants ViewOptF / ViewListF (viewF.scala): a value plus an effectful modify callback (A => A) => F[Unit], with zoom (via Monocle optics) to drill into substructure. View[A] is the Callback-fixed alias used by the react layer.
  • Reuse[A] (modules/core/js): attaches a hidden B with a Reusability[B] to a value so that types without a natural Reusability (functions, VdomNode) can participate in reuse.
  • Throttling: Throttler, ThrottlingViewF, ViewThrottlerF, Deglitcher coordinate UI vs. server-driven updates.
  • scalajs-react hooks (modules/core/js/.../react/hooks): monadic hooks integrating cats-effect IO and fs2.Stream with scalajs-react (e.g. useSingleEffect, useStreamView, useStreamResource, useEffectStream, useSignalStream). New hooks are added only in their monadic form; builder-style is being phased out.

The library assumes scalajs-react's core-bundle-cb_io bundle (sync effect CallbackTo, async effect IO).

Module structure

Three cross-projects (JVM + JS), defined in build.sbt:

  • core (modules/core): the library. shared/ holds platform-agnostic code (Pot, ViewF, throttling); js/ holds the scalajs-react integration (react/, hooks, Reuse). There is no meaningful jvm/-only source — the JS layer is where react lives.
  • testkit (modules/testkit): ScalaCheck Arbitrary/Eq instances for the core types, published for downstream test use. Depends on core.
  • tests (modules/tests): the test suite (MUnit + discipline law checks). Not published. JS tests run in a JSDOM environment. Depends on testkit.

Build, test, lint

The build uses sbt via the bundled sbt-launch.jar and the sbt-lucuma-lib plugin (which derives versioning, CI config, scalafmt/scalafix config, and publishing). Dependency versions are centralized in project/Settings.scala. JS tests require npm ci first (provides jsdom, react, react-dom).

sbt compile                  # compile all (JVM + JS)
sbt test                     # run all tests (JVM + JS)
sbt rootJVM/test             # only JVM tests
sbt rootJS/test              # only JS tests (requires `npm ci` first)
sbt "tests / Test / testOnly crystal.PotSpec"   # a single test suite
sbt scalafmtAll              # format
sbt scalafmtCheckAll         # verify formatting (CI gate)
sbt "scalafixAll OrganizeImports"   # organize imports (the configured scalafix rule)

Notes:

  • Scala 3 only (3.3.8 cross-version in build.sbt). maxColumn = 100; vertical alignment is on.
  • Don't hand-edit .scalafmt*.conf / .scalafix*.conf — they are generated by sbt-lucuma.
  • CI (.github/workflows/ci.yml) sets up Node 24 + npm ci only for the rootJS matrix project.
  • Both core and testkit are published; treat their public APIs as compatibility-sensitive.