For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/llms-full.txt, and this page is available as Markdown at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/guide/quick-start.md.

クイックスタート

既存アプリケーションの更新は v5 → v6 と FSRS-7 への移行ガイドを参照してください。

インストール

ts-fsrs には Node.js 24 以降が必要です。

npm
yarn
pnpm
bun
deno
npm install ts-fsrs

FSRS パラメーターの学習や復習ログ CSV の変換が必要な場合にのみ、@open-spaced-repetition/binding を追加でインストールします。

DefaultScheduler から始める

DefaultScheduler() は FSRS スケジューリングを最短で導入する方法です。既定で FSRS-7 を使用し、目標保持率、統計、学習ステップ、最大間隔、単調間隔、スケジュール日数の標準ポリシーを含みます。ファジングはオプションで有効にできます。

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
,
type Rating = 0 | 1 | 2 | 3 | 4
const Rating: Readonly<{
    readonly Manual: 0;
    readonly Again: 1;
    readonly Hard: 2;
    readonly Good: 3;
    readonly Easy: 4;
}>
Rating
} from 'ts-fsrs'
const now = new Date('2026-01-01T00:00:00.000Z') const
const scheduler: DefaultScheduler<"FSRS-7">
scheduler
= await
DefaultScheduler<"FSRS-7">(options?: DefaultSchedulerOptions<"FSRS-7"> | undefined): Promise<DefaultScheduler<"FSRS-7">>
DefaultScheduler
({
DefaultSchedulerOptions<"FSRS-7">.version?: "FSRS-7" | undefined

FSRS model and parameter migration version; defaults to FSRS-7.

version
: 'FSRS-7',
DefaultSchedulerOptions<Version extends DefaultSchedulerVersion = DefaultSchedulerVersion>.desiredRetention?: number | undefined
desiredRetention
: 0.9,
DefaultSchedulerOptions<Version extends DefaultSchedulerVersion = DefaultSchedulerVersion>.enableShortTerm?: boolean | undefined

Enable explicit learning steps. FSRS-7 always retains its intrinsic fast trace.

enableShortTerm
: true,
DefaultSchedulerOptions<"FSRS-7">.learningSteps?: readonly (`${number}d` | `${number}m` | `${number}h`)[] | undefined

Defaults to ['1m', '10m'].

learningSteps
: ['1m', '10m'],
DefaultSchedulerOptions<"FSRS-7">.relearningSteps?: readonly (`${number}d` | `${number}m` | `${number}h`)[] | undefined

Defaults to ['10m'].

relearningSteps
: ['10m'],
DefaultSchedulerOptions<Version extends DefaultSchedulerVersion = DefaultSchedulerVersion>.enableFuzz?: boolean | undefined
enableFuzz
: false,
DefaultSchedulerOptions<Version extends DefaultSchedulerVersion = DefaultSchedulerVersion>.maximumInterval?: number | undefined
maximumInterval
: 36_500,
}) 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: 'quick-start', now })
const
const result: {
    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;
    };
}
result
=
const scheduler: DefaultScheduler<"FSRS-7">
scheduler
.
review: (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 grade: Grade;
    readonly now?: Date | undefined;
}) => {
    ...;
}
review
({ card, grade:
const Rating: Readonly<{
    readonly Manual: 0;
    readonly Again: 1;
    readonly Hard: 2;
    readonly Good: 3;
    readonly Easy: 4;
}>
Rating
.Good, now })
console.log( JSON.stringify( { state:
const result: {
    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;
    };
}
result
.
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
.state,
dueAt:
const result: {
    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;
    };
}
result
.
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
.dueAt,
stability:
const result: {
    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;
    };
}
result
.
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
.stability,
stabilityFast:
const result: {
    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;
    };
}
result
.
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
.stabilityFast,
difficulty:
const result: {
    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;
    };
}
result
.
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
.difficulty,
rating:
const result: {
    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;
    };
}
result
.
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;
}
revlog
.rating,
}, null, 2 ) )

この例では一般的な既定値を明示しています。製品に合わせて desiredRetention、学習・再学習ステップ、ファジング、maximumInterval を変更できます。weights を省略すると、選択した FSRS バージョンのプリセット重みが使われます。

スケジューラーを作成する

モデルや時刻体系を選ぶ場合、または middleware を自分で組み合わせる場合は defineScheduler を使います。再利用可能な definition を作成し、.create() が設定を検証して独立したスケジューラーを返します。

chrono は、時間の表現方法、カードや復習ログへの保存方法、スケジューリング計算での扱い方を定義し、JavaScript の Date、Temporal、数値による時間表現を利用できるようにします。 chrono.normalize は ChronoTimeNormalizer スキーマを使い、カードや復習ログの時刻フィールドを { previous, current } に変換して、スケジューリングとロールバックに使用します。

import { 
const dateChrono: 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;
            };
        }>;
    };
}>
dateChrono
,
function defineScheduler<const M extends AnyModel, const C extends AnyChrono>(definition: {
    readonly model: M;
    readonly chrono: C;
}): CustomScheduler<SchedulerNameOf<M>, SchedulerEnvFor<M, C, readonly []>, M, C>
defineScheduler
,
type Rating = 0 | 1 | 2 | 3 | 4
const Rating: Readonly<{
    readonly Manual: 0;
    readonly Again: 1;
    readonly Hard: 2;
    readonly Good: 3;
    readonly Easy: 4;
}>
Rating
} from 'ts-fsrs'
import {
const FSRS7_DEFAULT_WEIGHTS: number[]
FSRS7_DEFAULT_WEIGHTS
,
const FSRS7Model: Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>
FSRS7Model
} from 'ts-fsrs/models/fsrs-7'
// Reuse this definition as the program's scheduling preset. const
const schedulerDefinition: CustomScheduler<"fsrs-7", SchedulerEnvFor<Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>, Chrono<...>, readonly []>, Model<...>, Chrono<...>>
schedulerDefinition
=
defineScheduler<Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>, Chrono<...>>(definition: {
    ...;
}): CustomScheduler<...>
defineScheduler
({
model: Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>
model
:
const FSRS7Model: Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>
FSRS7Model
,
chrono: 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;
            };
        }>;
    };
}>
chrono
:
const dateChrono: 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;
            };
        }>;
    };
}>
dateChrono
,
}) // Create an independent scheduler when a user's config is available. const
const scheduler: SchedulerCore<SchedulerCoreEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>, Chrono<...>, readonly []>>, ModelCore<...>, ChronoCore<...>>
scheduler
=
const schedulerDefinition: CustomScheduler<"fsrs-7", SchedulerEnvFor<Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>, Chrono<...>, readonly []>, Model<...>, Chrono<...>>
schedulerDefinition
.
CustomScheduler<"fsrs-7", SchedulerEnvFor<Model<{ readonly name: "fsrs-7"; readonly config: SRSSchema<{ input: { readonly weights: readonly number[]; }; output: { readonly weights: readonly number[]; }; }>; readonly memoryState: SRSSchema<{ input: { stabilityFast: number; stability: number; difficulty: number; }; output: { stabilityFast: number; stability: number; difficulty: number; }; }>; readonly algorithm: FSRS7Algorithm; }>, Chrono<...>, readonly []>, Model<...>, Chrono<...>>.create: (ctx: {
    readonly config: SchedulerConfigInput<Model<{
        readonly name: "fsrs-7";
        readonly config: SRSSchema<{
            input: {
                readonly weights: readonly number[];
            };
            output: {
                readonly weights: readonly number[];
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stabilityFast: number;
                stability: number;
                difficulty: number;
            };
            output: {
                stabilityFast: number;
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS7Algorithm;
    }>, Chrono<...>, readonly []>;
}) => SchedulerCore<...>
create
({
config: SchedulerConfigInput<Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>, Chrono<...>, readonly []>
config
: {
weights:
const FSRS7_DEFAULT_WEIGHTS: number[]
FSRS7_DEFAULT_WEIGHTS
,
fractionalDays: true, }, }) const now = new Date('2026-01-01T00:00:00.000Z') const
const card: {
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
card
=
const scheduler: SchedulerCore<SchedulerCoreEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>, Chrono<...>, readonly []>>, ModelCore<...>, ChronoCore<...>>
scheduler
.
SchedulerCore<SchedulerCoreEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-7"; readonly config: SRSSchema<{ input: { readonly weights: readonly number[]; }; output: { readonly weights: readonly number[]; }; }>; readonly memoryState: SRSSchema<{ input: { stabilityFast: number; stability: number; difficulty: number; }; output: { stabilityFast: number; stability: number; difficulty: number; }; }>; readonly algorithm: FSRS7Algorithm; }>, Chrono<...>, readonly []>>, ModelCore<...>, ChronoCore<...>>.newCard: (options?: {
    readonly now?: Date | undefined;
} | undefined) => {
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
newCard
({ now })
const
const result: {
    card: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    };
    revlog: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reviewTime: Date;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
        rating: Grade;
    };
}
result
=
const scheduler: SchedulerCore<SchedulerCoreEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-7";
    readonly config: SRSSchema<{
        input: {
            readonly weights: readonly number[];
        };
        output: {
            readonly weights: readonly number[];
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
        output: {
            stabilityFast: number;
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS7Algorithm;
}>, Chrono<...>, readonly []>>, ModelCore<...>, ChronoCore<...>>
scheduler
.
SchedulerCore<SchedulerCoreEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-7"; readonly config: SRSSchema<{ input: { readonly weights: readonly number[]; }; output: { readonly weights: readonly number[]; }; }>; readonly memoryState: SRSSchema<{ input: { stabilityFast: number; stability: number; difficulty: number; }; output: { stabilityFast: number; stability: number; difficulty: number; }; }>; readonly algorithm: FSRS7Algorithm; }>, Chrono<...>, readonly []>>, ModelCore<...>, ChronoCore<...>>.review: (input: {
    readonly card: Readonly<Omit<Readonly<{
        stabilityFast: number;
        stability: number;
        difficulty: number;
    } & {
        dueAt: Date;
        lastReviewAt: Date | null;
    } & SchedulerCoreFields$1<"new" | "learning" | "review">>, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>;
    readonly grade: Grade;
    readonly now?: Date | undefined;
}) => {
    card: {
        stabilityFast: number;
        ... 5 more ...;
        scheduleStatus: "new" | ... 1 more ... | "review";
    };
    revlog: {
        ...;
    };
}
review
({ card, grade:
const Rating: Readonly<{
    readonly Manual: 0;
    readonly Again: 1;
    readonly Hard: 2;
    readonly Good: 3;
    readonly Easy: 4;
}>
Rating
.Good, now })
console.log( JSON.stringify( { state:
const result: {
    card: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    };
    revlog: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reviewTime: Date;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
        rating: Grade;
    };
}
result
.
card: {
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
card
.state,
dueAt:
const result: {
    card: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    };
    revlog: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reviewTime: Date;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
        rating: Grade;
    };
}
result
.
card: {
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
card
.dueAt,
stability:
const result: {
    card: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    };
    revlog: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reviewTime: Date;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
        rating: Grade;
    };
}
result
.
card: {
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
card
.stability,
difficulty:
const result: {
    card: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    };
    revlog: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reviewTime: Date;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
        rating: Grade;
    };
}
result
.
card: {
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
card
.difficulty,
stabilityFast:
const result: {
    card: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    };
    revlog: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reviewTime: Date;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
        rating: Grade;
    };
}
result
.
card: {
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
card
.stabilityFast,
rating:
const result: {
    card: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    };
    revlog: {
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reviewTime: Date;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
        rating: Grade;
    };
}
result
.
revlog: {
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    reviewTime: Date;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
    rating: Grade;
}
revlog
.rating,
}, null, 2 ) )
スケジューラー定義を再利用する

defineScheduler(...) の結果は、.use(...) で組み合わせた middleware を含めて、プログラム共通のプリセットとして保持します。ユーザーやコレクションにスケジューラーが必要になった時点で schedulerDefinition.create({ config }) を呼び出してください。呼び出すたびに設定が検証され、独立したインスタンスが返ります。

コードブロックのコピーボタンは元のソースをコピーします。専用 Worker でそのまま実行することもできます。固定した now により出力を再現できます。

  • newCard() はスケジューラー既定のカードを作成します。
  • review() は新しいカードと復習ログを返し、入力カードを変更しません。
  • 再利用する definition に .use(...) でポリシー middleware を追加してから、ユーザーごとのスケジューラーを作成します。