ポモドーロタイマー
このパッケージの要点は、動作中のタイマーが秒を持たないことです。動作中の state が持つのは
endsAt(壁時計の epoch ミリ秒)だけで、カウントダウンはクライアントがそこから描きます。
だから下の時計は毎秒動くのに、state はあなたが何かを押したときと、フェーズが実際に切れた
ときにしか変わりません。
試してみること
Section titled “試してみること”- start を押し、もう一度 start を押す。2回目は
nullが返ります —reduceは動作中の タイマーに対する start を、例外でも再スタートでもなく no-op として扱います。 - pause を押して、
endsAtがnullになりremainingが残り秒で凍結するのを見る。 - skip を何回か押す。フェーズは交互に変わるのに
cyclesは増えません — 完了サイクルとして 数えるのは、自然に時間切れになったフェーズだけです。 - work に
0を入れて送る。現在の config にフォールバックせず1分にクランプされます。0は 「数値に変換できる値」だからです。999も試すと 120 にクランプされます。 - 動作中に configure を送る。
nullが返ります — フェーズの途中で長さを変える意味が曖昧なので、 停止中しか受け付けません。
裏で動いているコード
Section titled “裏で動いているコード”デモが import しているのは、公開されているパッケージだけです:
import { defaultState, onTimer, reduce, timerDelay } from '@insession/extension-pomodoro';
let state = defaultState();
// ボタンが押されたときconst next = reduce(state, 'start');if (next) state = next;
// フェーズ遷移は自分のタイマーで駆動するconst delay = timerDelay(state); // フェーズが終わるまでのミリ秒、動作中でなければ nullif (delay !== null) setTimeout(() => { state = onTimer(state); }, delay);reduce は純関数です — I/O をせず、内部でタイマーも張りません。スケジューリングが呼ぶ側の責務で
あることが、同じ状態機械をサーバーでも、テストでも、このページでも動かせる理由です。
アクションの全一覧と永続化のヘルパー(restore / persistState)は
パッケージのリファレンスを参照してください。