For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/llms-full.txt, and this page is available as Markdown at https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/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 schema,将卡片或复习日志的时间字段转换为 { 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,再创建用户专属的调度器。