#快速开始
已有应用升级请参阅 v5 → v6 与 FSRS-7 迁移指南。
#安装
ts-fsrs 需要 Node.js 24 或更高版本。
npm install ts-fsrsyarn add ts-fsrspnpm add ts-fsrsbun add ts-fsrsdeno add npm: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" | undefinedFSRS 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 | undefinedEnable explicit learning steps. FSRS-7 always retains its intrinsic fast trace.
enableShortTerm : true,
DefaultSchedulerOptions<"FSRS-7">.learningSteps?: readonly (`${number}d` | `${number}m` | `${number}h`)[] | undefinedDefaults to ['1m', '10m'].
learningSteps : ['1m', '10m'],
DefaultSchedulerOptions<"FSRS-7">.relearningSteps?: readonly (`${number}d` | `${number}m` | `${number}h`)[] | undefinedDefaults 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,再创建用户专属的调度器。