Function
Every lesson slice in the course, in any order
The course tally, its fraction, and the same tally per module
Counts with countsAsComplete, the same rule useLessonWatchState applies
to a single lesson and useModuleWatchProgress to a module, so a course
meter can never disagree with the lesson rows it sits above.
A lesson with no runtime — a reading lesson, whose slice reports zero
seconds — is counted by its mark alone, which is the same thing
LessonWatchProgress says when it renders no bar for one.
It takes progress slices rather than whole lessons so the home can count
from the catalog's projection without shipping lesson bodies; callers that
hold entities map them through toLessonProgressSlice.
The per-module breakdown is returned rather than left to the caller because a course's module count varies: a hook call per module would break the rules of hooks the moment a course is reordered. It is keyed, not ordered, so the caller's own module list decides what order the segments draw in.
Browser-side only — do NOT call from a Server Component. The reading appears
at hydration, so a caller rendering a meter must keep its track on the
server and gate only the fill (see useIsHydrated).
How far the learner has got through a course, in whole lessons.