Function
The lesson whose position is tracked
The three handlers a player binds to its lifecycle events
time-update fires several times a second, so those writes are debounced at
TIME_UPDATE_DEBOUNCE_MS. pause, seeking, and ended write
immediately — they are the moments a learner is most likely to leave, and
losing a debounce window of progress there is exactly what they would
notice; those three also skip the server write window. The pending write is
flushed on unmount, and on pagehide it leaves by navigator.sendBeacon,
so a route change or a closed tab costs nothing.
Nothing is written before PlaybackPositionPersistence.openWriteGate
is called. A cold load fires time-update at 0, and writing that would
destroy the saved position before the learner is ever offered it.
Range and finiteness are not re-checked here — the PlaybackPosition
value object owns those, and a second copy of the rules would be one to keep
in sync. A detached player reporting NaN is silently dropped there.
Persists where the learner is in a lesson, on the cadence the
playback-positioncapability specifies.