For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/llms-full.txt, and this page is available as Markdown at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/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 已組合了它們。見內建策略;直接使用現成排程器見快速開始。