設計から型安全
一つのスキーマが実行時の検証と入力・出力の型推論を同時に担います。
TypeScript のための型安全なスケジューラーフレームワーク。FSRS-7 から始めて、API ファミリーを切り替えることなく、モデル・クロノ・ミドルウェアを組み合わせられます。
import { function DefaultScheduler<Version extends DefaultSchedulerVersion = "FSRS-7">(options?: DefaultSchedulerOptions<Version>): Promise<DefaultScheduler<Version>>
type DefaultScheduler<Version extends DefaultSchedulerVersion = "FSRS-7"> = (Version extends "FSRS-7" ? Omit<SchedulerCore<SchedulerCoreEnv<SchedulerEnvFor<FSRS7DefaultSchedulerModel, Chrono<{
readonly time: SRSSchema<{
input: Date;
output: Date;
}>;
readonly config: SRSSchema<{
input: {
readonly fractionalDays?: boolean | undefined;
};
output: {
readonly fractionalDays: boolean;
};
}>;
readonly fields: {
readonly card: SRSSchema<{
input: {
dueAt: Date;
lastReviewAt?: (Date | null) | undefined;
};
output: {
dueAt: Date;
lastReviewAt: Date | null;
};
}>;
readonly revlog: SRSSchema<{
input: {
dueAt: Date;
lastReviewAt?: (Date | null) | undefined;
reviewTime: Date;
};
output: {
dueAt: Date;
lastReviewAt: Date | null;
reviewTime: Date;
};
}>;
};
}>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>, "definition"> : Omit<...> & {
...;
}) & {
...;
}
DefaultScheduler } from 'ts-fsrs'
const createdAt = new Date('2026-01-01T00:00:00.000Z')
export const now = new Date('2026-01-02T09:30:00.000Z')
export const const scheduler: DefaultScheduler<"FSRS-7"> scheduler = await DefaultScheduler<"FSRS-7">(options?: DefaultSchedulerOptions<"FSRS-7"> | undefined): Promise<DefaultScheduler<"FSRS-7">> DefaultScheduler ({
DefaultSchedulerOptions<Version extends DefaultSchedulerVersion = DefaultSchedulerVersion>.desiredRetention?: number | undefined desiredRetention : 0.9,
})
export const const card: {
cardId: string | number;
stabilityFast: number;
stability: number;
difficulty: number;
dueAt: Date;
lastReviewAt: Date | null;
reps: number;
lapses: number;
scheduledDays: number;
learningStep: number;
state: State;
scheduleStatus: "review" | "new" | "learning";
}
card = const scheduler: DefaultScheduler<"FSRS-7"> scheduler .newCard: (options?: ({
readonly cardId?: string | number | undefined;
} & {
readonly now?: Date | undefined;
}) | undefined) => {
cardId: string | number;
stabilityFast: number;
stability: number;
difficulty: number;
dueAt: Date;
lastReviewAt: Date | null;
reps: number;
lapses: number;
scheduledDays: number;
learningStep: number;
state: State;
scheduleStatus: "review" | "new" | "learning";
}
newCard ({
cardId: 'landing-demo',
now: createdAt,
})
// One `{ grade, card, revlog }` row per grade — the panel renders exactly this.
export const const outcomes: PreviewResult<{
card: {
cardId: string | number;
stabilityFast: number;
stability: number;
difficulty: number;
dueAt: Date;
lastReviewAt: Date | null;
reps: number;
lapses: number;
scheduledDays: number;
learningStep: number;
state: State;
scheduleStatus: "review" | "new" | "learning";
};
revlog: {
cardId: string | number;
stabilityFast: number;
stability: number;
difficulty: number;
dueAt: Date;
lastReviewAt: Date | null;
scheduledDays: number;
learningStep: number;
reviewTime: Date;
state: State;
scheduleStatus: "review" | "new" | "learning";
rating: Grade;
};
}>
outcomes = const scheduler: DefaultScheduler<"FSRS-7"> scheduler .preview: (input: {
readonly card: Readonly<Omit<Readonly<{
stabilityFast: number;
stability: number;
difficulty: number;
} & {
dueAt: Date;
lastReviewAt: Date | null;
} & {
readonly cardId: string | number;
readonly reps: number;
readonly lapses: number;
readonly scheduledDays: number;
readonly learningStep?: number | undefined;
} & SchedulerCoreFields$1<"review" | "new" | "learning">>, keyof SchedulerCoreFields$1<"review" | "new" | "learning">> & SchedulerCoreFields$1<"review" | "new" | "learning">>;
readonly now?: Date | undefined;
}) => PreviewResult<...>
preview ({ card, now })一つのスキーマが実行時の検証と入力・出力の型推論を同時に担います。
デフォルトのスケジューラーから始め、同じコアの上でモデル・クロノ・ポリシーを差し替えられます。
遅延プレビュー、バージョン単位のコード分割、tree-shaking 可能なサブパスエクスポート。
段階的な API
デフォルトの FSRS スケジューラーをそのまま使うことも、独自のスケジューリング方針を組み立てることも、新しいモデルを実装することも、すべて同じコアの上でできます。
DefaultScheduler は適切なデフォルト値を備えた FSRS スケジューラーです。FSRS-3 から FSRS-7 までをサポートし、デフォルトでは FSRS-7 を使います。DefaultScheduler
モデルとクロノを選び、必要なポリシーをミドルウェアとして一つ一つ追加します。defineScheduler.use(middleware)
組み込みで足りなくなったら、ミドルウェアや時間システム、モデルを自分で書けます。defineMiddlewaredefineChrono
型安全性
Standard Schema は、設定・カード・復習ログ・記憶状態・時刻値に共通の実行時検証と型契約を提供します。
scheduleStatus: 'new' | 'review' | 'suspended'
組み込み機能
カードに復習回数(reps)と忘却回数(lapses)のカウンターを追加し、維持します。
設定された目標保持率を間隔計算に渡します。
記憶状態と復習コストに応じて保持率を調整します。固定の目標保持率ポリシーの代わりに使用します。
カード ID と復習回数をシードに、間隔へ決定的な揺らぎを加えます。
学習・再学習ステップを分・時間・日の単位でスケジュールします。
忘却回数が設定したしきい値の倍数に達するたびに、カードを一時停止します。
最終的なスケジュール間隔を設定された上限以内に収めます。
高い評価で短い間隔にならないよう調整します。
間隔と復元用の旧値を保存し、小数日が有効な場合は小数の間隔を保持します。
アーキテクチャ
各コンポーネントは互換性があり、自由に組み合わせられます。
use() は新しい definition を返します。既存の definition も、そこから作成済みスケジューラーも変更されません。
パフォーマンス
API は、遅延評価、コード分割、不変な結果を前提に設計されています。
DefaultScheduler は指定された FSRS バージョンを必要に応じて読み込み、初回読み込みに不要なモデルコードが含まれるのを抑えるのに役立ちます。
preview() は実際にイテレートした評価だけを計算します。
スケジューラのスキーマは宣言時ではなく、最初にアクセスされたときに作られます。
sideEffects は false で、モデルとミドルウェアはサブパスで提供されます。
review は新しいカードを返し、入力を一切変更しません。
rollback() は revlog から直前のカードを、ミドルウェアのフィールドごと復元します。
コントリビューター
プロジェクトのモデルやミドルウェアをはじめとするさまざまな改善は、コミュニティからプルリクエストを通じて寄せられる提案や貢献に支えられています。
スポンサー
ひとつひとつのご支援が、ts-fsrs の継続的なメンテナンスと FSRS 研究への追従を支えています。
デフォルトのスケジューラーで一般的な用途をカバーできます。必要に応じて、異なるモデル、時間システム、ミドルウェアで独自のスケジューラーを構成できます。