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/middleware/index.md.
  • 简体中文
  • 中间件概览

    中间件为调度器添加调度策略和应用所需的字段。模型计算记忆状态与间隔,chrono 预设把这些间隔转换为到期时间;中间件位于两者之间,可以调整目标保留率或间隔、管理学习步骤,以及维护模型从未见过的额外卡片数据。各部分的职责见整体架构。

    中间件边界

    调度器由模型、chrono 与中间件组合而成。让模型只负责记忆状态更新与间隔计算,让 chrono 负责时间值与天数运算;中间件在核心操作之前提供输入、在其后调整结果,并承载这两者未定义的字段。

    For your Agent
    实现或解释一个中间件策略

    复制这段提示词,让 AI Agent 遵守 Middleware 契约,避免混入调度器内部实现或持久化逻辑。

    定义字段与行为

    Middleware 定义包含必填的 name,以及可选的 schema、默认值和处理函数。defineMiddleware() 根据 schema 推导处理函数中的类型。可以从 ts-fsrs 导入;内置策略也可从 ts-fsrs/middlewares 导入。

    定义用途
    schema.config校验传给 create({ config }) 的配置。中间件共用调度器的配置对象。
    schema.card声明并校验输入、输出卡片上的字段。
    schema.revlog声明并校验复习日志字段,包括撤销所需的旧值。
    schema.cardInitInput声明 newCard() 接受的额外输入,例如卡片 ID。
    scheduleStatus注册自定义调度状态,例如 scheduleStatus: ['buried'],使组合后的类型和结果校验接受这些状态。
    handlers.nextInterval在 next() 前调整 ctx.candidate.desiredRetention[ctx.input.grade],或在其后调整 ctx.scheduledDays。复习和直接调用 scheduler.nextInterval() 时都会执行。
    defaultValue.card在创建或重置卡片时提供字段值,通过 ctx.operation 区分这两种操作。
    handlers.review / handlers.rollback在调用下一个处理函数前后,更新 ctx.result。运行方式见生命周期。

    Schema 同时提供运行时校验与 TypeScript 类型推导。下面使用实现了 Standard Schema 的 Zod。在自己的应用中运行示例时,除 ts-fsrs 外还需要安装它:

    npm
    yarn
    pnpm
    bun
    deno
    npm install zod

    添加支持撤销的连续答对计数

    示例中,除 Again 外的评分都会让 streak 加一,最多累积到 streakLimit;Again 会将它清零。复习处理函数把原计数保存到 revlog,因此即使清零后撤销,也能恢复之前的值:

    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 defineMiddleware<const Name extends PropertyKey, const Schema extends MiddlewareDefinitionSchema = EmptyPart, const Status extends string = never>(definition: MiddlewareDefinition<Schema, Name, Status>): Middleware<Name, Prettify<Assign<MiddlewareStatusEnv<Status>, Schema>> extends MiddlewareEnv ? MiddlewareEnv & Prettify<Assign<MiddlewareStatusEnv<Status>, Schema>> : never>
    defineMiddleware
    ,
    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 FSRS6_DEFAULT_WEIGHTS: number[]
    FSRS6_DEFAULT_WEIGHTS
    ,
    const FSRS6Model: Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>
    FSRS6Model
    } from 'ts-fsrs/models/fsrs-6'
    import { z } from 'zod' const streakFields = z.object({ streak: z.int().nonnegative() }) const
    const streakMiddleware: Middleware<symbol, {
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }>
    streakMiddleware
    =
    defineMiddleware<symbol, {
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }, never>(definition: MiddlewareDefinition<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }, symbol, never>): Middleware<...>
    defineMiddleware
    ({
    name: Symbol('guide.streak'), schema: { config: z.object({ streakLimit: z.int().positive() }), card: streakFields, revlog: streakFields, },
    defaultValue?: {
        readonly card?: FieldDefault<z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>, MiddlewareDefaultValueContext<{
            readonly config: z.ZodObject<{
                streakLimit: z.ZodInt;
            }, z.core.$strip>;
            readonly card: z.ZodObject<{
                streak: z.ZodInt;
            }, z.core.$strip>;
            readonly revlog: z.ZodObject<{
                streak: z.ZodInt;
            }, z.core.$strip>;
        }>> | undefined;
        readonly revlog?: FieldDefault<z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>, MiddlewareDefaultValueContext<{
            readonly config: z.ZodObject<{
                streakLimit: z.ZodInt;
            }, z.core.$strip>;
            readonly card: z.ZodObject<{
                streak: z.ZodInt;
            }, z.core.$strip>;
            readonly revlog: z.ZodObject<{
                streak: z.ZodInt;
            }, z.core.$strip>;
        }>> | undefined;
    } | undefined
    defaultValue
    : {
    card?: FieldDefault<z.ZodObject<{
        streak: z.ZodInt;
    }, z.core.$strip>, MiddlewareDefaultValueContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }>> | undefined
    card
    : () => ({ streak: 0 }) },
    handlers?: {
        readonly nextInterval?: NextIntervalMiddlewareHandler<{
            readonly config: z.ZodObject<{
                streakLimit: z.ZodInt;
            }, z.core.$strip>;
            readonly card: z.ZodObject<{
                streak: z.ZodInt;
            }, z.core.$strip>;
            readonly revlog: z.ZodObject<{
                streak: z.ZodInt;
            }, z.core.$strip>;
        }> | undefined;
        readonly review?: MiddlewareHandler<ReviewMiddlewareContext<{
            readonly config: z.ZodObject<{
                streakLimit: z.ZodInt;
            }, z.core.$strip>;
            readonly card: z.ZodObject<{
                streak: z.ZodInt;
            }, z.core.$strip>;
            readonly revlog: z.ZodObject<{
                streak: z.ZodInt;
            }, z.core.$strip>;
        }> & MiddlewareStatusContext<...>> | undefined;
        readonly rollback?: MiddlewareHandler<...> | undefined;
    } | undefined
    handlers
    : {
    review?: MiddlewareHandler<ReviewMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card", "card" | "revlog">> | undefined
    review
    (
    ctx: ReviewMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card", "card" | "revlog">
    ctx
    , next) {
    next() const { card, grade } =
    ctx: ReviewMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card", "card" | "revlog">
    ctx
    .
    input: {
        readonly card: {
            streak: number;
        } & SchedulerCoreFields<string>;
        readonly grade: Grade;
        readonly desiredRetention?: number;
    } & {
        readonly now: unknown;
    } & {
        readonly card: {
            readonly scheduleStatus: "new" | "learning" | "review";
        };
    }
    input
    ctx: ReviewMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card", "card" | "revlog">
    ctx
    .
    result: ReviewMiddlewareResult<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & {
        readonly card: {
            scheduleStatus?: "new" | "learning" | "review" | undefined;
        };
        readonly revlog: {
            scheduleStatus?: "new" | "learning" | "review" | undefined;
        };
    }
    result
    .
    revlog: Partial<Mutable<{
        streak: number;
    } & SchedulerCoreFields<string> & {
        readonly rating: Grade;
    }>> & Record<string, unknown> & {
        scheduleStatus?: "new" | "learning" | "review" | undefined;
    }
    revlog
    .streak = card.streak
    ctx: ReviewMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card", "card" | "revlog">
    ctx
    .
    result: ReviewMiddlewareResult<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & {
        readonly card: {
            scheduleStatus?: "new" | "learning" | "review" | undefined;
        };
        readonly revlog: {
            scheduleStatus?: "new" | "learning" | "review" | undefined;
        };
    }
    result
    .
    card: Partial<Mutable<{
        streak: number;
    } & SchedulerCoreFields<string>>> & Record<string, unknown> & {
        scheduleStatus?: "new" | "learning" | "review" | undefined;
    }
    card
    .streak =
    grade ===
    const Rating: Readonly<{
        readonly Manual: 0;
        readonly Again: 1;
        readonly Hard: 2;
        readonly Good: 3;
        readonly Easy: 4;
    }>
    Rating
    .Again
    ? 0 : Math.min(card.streak + 1,
    ctx: ReviewMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card", "card" | "revlog">
    ctx
    .
    MiddlewareContextBase<{ readonly config: ZodObject<{ streakLimit: ZodInt; }, $strip>; readonly card: ZodObject<{ streak: ZodInt; }, $strip>; readonly revlog: ZodObject<...>; }>.config: MiddlewareContextConfig<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }>
    config
    .streakLimit)
    },
    rollback?: MiddlewareHandler<RollbackMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card" | "revlog", "card">> | undefined
    rollback
    (
    ctx: RollbackMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card" | "revlog", "card">
    ctx
    , next) {
    next()
    ctx: RollbackMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card" | "revlog", "card">
    ctx
    .
    result: RollbackMiddlewareResult<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & {
        readonly card: {
            scheduleStatus?: "new" | "learning" | "review" | undefined;
        };
    }
    result
    .
    card: Partial<Mutable<{
        streak: number;
    } & SchedulerCoreFields<string>>> & Record<string, unknown> & {
        scheduleStatus?: "new" | "learning" | "review" | undefined;
    }
    card
    .streak =
    ctx: RollbackMiddlewareContext<{
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }> & MiddlewareStatusContext<never, "card" | "revlog", "card">
    ctx
    .
    input: {
        readonly card: {
            streak: number;
        } & SchedulerCoreFields<string>;
        readonly revlog: {
            streak: number;
        } & SchedulerCoreFields<string> & {
            readonly rating: Grade;
        };
    } & {
        readonly card: {
            readonly scheduleStatus: "new" | "learning" | "review";
        };
        readonly revlog: {
            readonly scheduleStatus: "new" | "learning" | "review";
        };
    }
    input
    .
    revlog: {
        streak: number;
    } & SchedulerCoreFields<string> & {
        readonly rating: Grade;
    } & {
        readonly scheduleStatus: "new" | "learning" | "review";
    }
    revlog
    .streak
    }, }, }) const
    const base: CustomScheduler<"fsrs-6", SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, Model<...>, Chrono<...>>
    base
    =
    defineScheduler<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>>(definition: {
        ...;
    }): CustomScheduler<...>
    defineScheduler
    ({
    model: Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>
    model
    :
    const FSRS6Model: Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>
    FSRS6Model
    ,
    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
    })
    const
    const scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
    scheduler
    =
    const base: CustomScheduler<"fsrs-6", SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, Model<...>, Chrono<...>>
    base
    .
    CustomScheduler<"fsrs-6", SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, Model<...>, Chrono<...>>.use: <readonly [Middleware<symbol, {
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }>]>(middlewares_0: Middleware<symbol, {
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }>) => CustomScheduler<...>

    Returns a new scheduler definition extended with the supplied middleware. The current scheduler and any cores created from it remain unchanged.

    use
    (
    const streakMiddleware: Middleware<symbol, {
        readonly config: z.ZodObject<{
            streakLimit: z.ZodInt;
        }, z.core.$strip>;
        readonly card: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
        readonly revlog: z.ZodObject<{
            streak: z.ZodInt;
        }, z.core.$strip>;
    }>
    streakMiddleware
    ).
    CustomScheduler<"fsrs-6", ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>, Model<...>, Chrono<...>>.create: (ctx: {
        readonly config: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        } & {
            readonly fractionalDays?: boolean | undefined;
        } & EmptyPart & {
            streakLimit: number;
        };
    }) => SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
    create
    ({
    config: {
        readonly weights: number[];
        readonly enableShortTerm: boolean;
        readonly numRelearningSteps: number;
    } & {
        readonly fractionalDays?: boolean | undefined;
    } & EmptyPart & {
        streakLimit: number;
    }
    config
    : {
    weights:
    const FSRS6_DEFAULT_WEIGHTS: number[]
    FSRS6_DEFAULT_WEIGHTS
    ,
    enableShortTerm: false, numRelearningSteps: 0, streakLimit: 2, }, }) const now = new Date('2026-01-01T00:00:00.000Z') const
    const initial: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    initial
    =
    const scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
    scheduler
    .
    SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>.newCard: (options?: {
        readonly now?: Date | undefined;
    } | undefined) => {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    newCard
    ({ now })
    const
    const good: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    good
    =
    const scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
    scheduler
    .
    SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>.review: (input: {
        readonly card: Readonly<Omit<Readonly<Omit<Readonly<{
            stability: number;
            difficulty: number;
        } & {
            dueAt: Date;
            lastReviewAt: Date | null;
        } & SchedulerCoreFields$1<"new" | "learning" | "review">> & {
            streak: number;
        }, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>;
        readonly grade: Grade;
        readonly now?: Date | undefined;
    }) => {
        ...;
    }
    review
    ({ card:
    const initial: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    initial
    , grade:
    const Rating: Readonly<{
        readonly Manual: 0;
        readonly Again: 1;
        readonly Hard: 2;
        readonly Good: 3;
        readonly Easy: 4;
    }>
    Rating
    .Good, now })
    const
    const again: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    again
    =
    const scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
    scheduler
    .
    SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>.review: (input: {
        readonly card: Readonly<Omit<Readonly<Omit<Readonly<{
            stability: number;
            difficulty: number;
        } & {
            dueAt: Date;
            lastReviewAt: Date | null;
        } & SchedulerCoreFields$1<"new" | "learning" | "review">> & {
            streak: number;
        }, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>;
        readonly grade: Grade;
        readonly now?: Date | undefined;
    }) => {
        ...;
    }
    review
    ({
    card:
    const good: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    good
    .
    card: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    card
    ,
    grade:
    const Rating: Readonly<{
        readonly Manual: 0;
        readonly Again: 1;
        readonly Hard: 2;
        readonly Good: 3;
        readonly Easy: 4;
    }>
    Rating
    .Again,
    now:
    const good: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    good
    .
    card: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    card
    .dueAt,
    }) const
    const restored: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    restored
    =
    const scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
    scheduler
    .
    SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>.rollback: (input: {
        readonly card: Mutable<Omit<Mutable<Omit<Mutable<{
            stability: number;
            difficulty: number;
        } & {
            dueAt: Date;
            lastReviewAt: Date | null;
        } & SchedulerCoreFields$1<"new" | "learning" | "review">> & {
            streak: number;
        }, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>;
        readonly revlog: Mutable<...>;
    }) => {
        ...;
    }
    rollback
    (
    const again: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    again
    )
    const
    const preview: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
        readonly grade: Grade;
    }[]
    preview
    = Array.
    ArrayConstructor.from<{
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
        readonly grade: Grade;
    }>(iterable: Iterable<{
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
        readonly grade: Grade;
    }> | ArrayLike<...>): {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
        readonly grade: Grade;
    }[] (+3 overloads)

    Creates an array from an iterable object.

    @paramiterable An iterable object to convert to an array.
    from
    (
    const scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
        readonly name: "fsrs-6";
        readonly config: SRSSchema<{
            input: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
            output: {
                readonly weights: number[];
                readonly enableShortTerm: boolean;
                readonly numRelearningSteps: number;
            };
        }>;
        readonly memoryState: SRSSchema<{
            input: {
                stability: number;
                difficulty: number;
            };
            output: {
                stability: number;
                difficulty: number;
            };
        }>;
        readonly algorithm: FSRS6Algorithm;
    }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
    scheduler
    .
    SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>.preview: (input: {
        readonly card: Readonly<Omit<Readonly<Omit<Readonly<{
            stability: number;
            difficulty: number;
        } & {
            dueAt: Date;
            lastReviewAt: Date | null;
        } & SchedulerCoreFields$1<"new" | "learning" | "review">> & {
            streak: number;
        }, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>;
        readonly now?: Date | undefined;
    }) => PreviewResult<...>
    preview
    ({ card:
    const restored: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    restored
    , now:
    const good: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    good
    .
    card: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    card
    .dueAt })
    ) console.log( JSON.stringify( { initial:
    const initial: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    initial
    .streak,
    afterGood:
    const good: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    good
    .
    card: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    card
    .streak,
    afterAgain:
    const again: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    again
    .
    card: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    card
    .streak,
    savedBeforeAgain:
    const again: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
    }
    again
    .
    revlog: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reviewTime: Date;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
        rating: Grade;
    }
    revlog
    .streak,
    restored:
    const restored: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    restored
    .streak,
    preview:
    const preview: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
        readonly grade: Grade;
    }[]
    preview
    .
    Array<{ card: { streak: number; stability: number; difficulty: number; dueAt: Date; lastReviewAt: Date | null; state: State; scheduleStatus: "new" | "learning" | "review"; }; revlog: { ...; }; readonly grade: Grade; }>.map<number>(callbackfn: (value: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
        readonly grade: Grade;
    }, index: number, array: {
        card: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
        };
        revlog: {
            streak: number;
            stability: number;
            difficulty: number;
            dueAt: Date;
            lastReviewAt: Date | null;
            reviewTime: Date;
            state: State;
            scheduleStatus: "new" | "learning" | "review";
            rating: Grade;
        };
        readonly grade: Grade;
    }[]) => number, thisArg?: any): number[]

    Calls a defined callback function on each element of an array, and returns an array that contains the results.

    @paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
    map
    (({
    card: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    card
    }) =>
    card: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    card
    .streak),
    afterPreview:
    const restored: {
        streak: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        state: State;
        scheduleStatus: "new" | "learning" | "review";
    }
    restored
    .streak,
    }, null, 2 ) )

    计数从 0 增加到 1,评为 Again 后回到 0,撤销后恢复为 1。预览中,Again、Hard、Good、Easy 对应的计数分别是 0、2、2、2,输入卡片的计数仍为 1。

    base.use(streakMiddleware) 返回新的调度器定义,原来的 base 不变。需要保存返回值,或像示例一样继续调用 .create()。由于中间件通过 use 组合,处理函数会按固定顺序环绕调度器核心——详见生命周期。

    现成的策略覆盖了常见场景,DefaultScheduler 已组合了它们。见内置策略;直接使用现成调度器见快速开始。