Primitives / Time
ticks: a clock the Model drives
Both bundles own a running flag at an interval fixed where they are placed.
When the parent's Model already decides whether the clock runs and how fast (a
game's phase and score), a second flag would be a second owner of that fact.
ticks is the entry for that case: intervalMs reads the interval from the
Model, None while stopped, and onTick makes the parent's Message:
import { Option } from 'effect'
import * as Subscription from 'foldkit/subscription'
import { ticks } from 'foldkit-primitives/time'
const subscriptions = Subscription.make<Game, GameMessage>()(() => ({
clock: ticks({
intervalMs: (game: Game) =>
game.playing ? Option.some(Math.max(80, 150 - game.points)) : Option.none(),
onTick: () => GameMessage.TickedClock(),
}),
}))A Model change that leaves the interval alone does nothing. A new interval
applies from the next tick without restarting the clock, so a game that speeds
up keeps its rhythm instead of ticking at once; None stops it, and Some
again starts afresh, one interval before the first tick. Timer and Interval
are built on it. An interval that answers zero, negative, or non-finite throws,
which crashes the runtime naming the mistake.