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

ミドルウェア概要

ミドルウェアは、スケジューラにスケジューリングのポリシーやアプリケーション固有のフィールドを追加します。モデルが記憶状態と間隔を計算し、chrono のプリセットがその間隔を期限に変換します。ミドルウェアはその間に位置し、目標保持率や間隔の調整、学習ステップの管理、モデルが扱わないカードの追加データの更新を担います。各部分の役割はアーキテクチャを参照してください。

ミドルウェアの境界

スケジューラはモデル・chrono・ミドルウェアを組み合わせます。モデルは記憶状態の更新と間隔計算に限定し、chrono は時間値と日数演算を担います。ミドルウェアはコア操作の前に入力を提供し、その後に結果を調整し、両者が定義しないフィールドを保持します。

For your Agent
ミドルウェアポリシーを実装または説明する

このプロンプトをコピーすると、AI Agent がスケジューラの内部や永続化に踏み込まずに Middleware 契約へ従います。

フィールドと処理を定義する

Middleware の定義には必須の name と、任意のスキーマ、デフォルト値、ハンドラがあります。defineMiddleware() はスキーマからハンドラ内の型を推論します。ts-fsrs からインポートでき、組み込みポリシーは ts-fsrs/middlewares からも利用できます。

定義用途
schema.configcreate({ config }) に渡す設定を検証します。ミドルウェアはスケジューラの設定オブジェクトを共有します。
schema.card入出力カードのフィールドを宣言し、検証します。
schema.revlogロールバックに必要な値を含め、復習ログのフィールドを宣言し、検証します。
schema.cardInitInputカード ID など、newCard() が受け取る追加の入力を宣言します。
scheduleStatusscheduleStatus: ['buried'] などで独自の状態を登録し、合成後の型と結果の検証で受け入れられるようにします。
handlers.nextIntervalnext() の前に ctx.candidate.desiredRetention[ctx.input.grade]、または後に ctx.scheduledDays を調整します。復習時と scheduler.nextInterval() の直接呼び出し時に実行されます。
defaultValue.cardカードの作成時とリセット時にフィールドの値を設定します。ctx.operation で操作を区別できます。
handlers.review / handlers.rollback次のハンドラを呼び出す前後で ctx.result を更新します。実行方法はライフサイクルを参照してください。

スキーマは実行時の検証と 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 は既にそれらを組み合わせています。組み込みポリシー を参照するか、既成のスケジューラを使う場合はクイックスタートを参照してください。