ts-fsrs 5.3.0 → 5.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README_JA.md ADDED
@@ -0,0 +1,251 @@
1
+ # ts-fsrs
2
+
3
+ [Introduction](./README.md) | [简体中文](./README_CN.md) | [はじめに](./README_JA.md)
4
+
5
+ [![fsrs version](https://img.shields.io/badge/FSRS-v6-blue?style=flat-square)](https://github.com/open-spaced-repetition/fsrs4anki/wiki/The-Algorithm#fsrs-6)
6
+ [![npm version](https://img.shields.io/npm/v/ts-fsrs.svg?style=flat-square&logo=npm)](https://www.npmjs.com/package/ts-fsrs)
7
+ [![downloads](https://img.shields.io/npm/dm/ts-fsrs?style=flat-square)](https://www.npmjs.com/package/ts-fsrs)
8
+
9
+ **ts-fsrs は、Free Spaced Repetition Scheduler (FSRS) アルゴリズムを使って独自の間隔反復システムを構築するための TypeScript パッケージです。**
10
+
11
+ ## 目次
12
+
13
+ - [ts-fsrs](#ts-fsrs)
14
+ - [目次](#目次)
15
+ - [インストール](#インストール)
16
+ - [クイックスタート](#クイックスタート)
17
+ - [使い方](#使い方)
18
+ - [カスタムパラメータ](#カスタムパラメータ)
19
+ - [`generatorParameters`](#generatorparameters)
20
+ - [`repeat` と `next`](#repeat-と-next)
21
+ - [想起確率](#想起確率)
22
+ - [`next_state` と `next_interval`](#next_state-と-next_interval)
23
+ - [履歴関連のヘルパー](#履歴関連のヘルパー)
24
+ - [リファレンス](#リファレンス)
25
+ - [API ドキュメント](#api-ドキュメント)
26
+ - [例](#例)
27
+ - [コントリビュート](#コントリビュート)
28
+
29
+ ## インストール
30
+
31
+ `ts-fsrs` は Node.js `>=20.0.0` を必要とします。
32
+
33
+ ```bash
34
+ npm install ts-fsrs
35
+ yarn add ts-fsrs
36
+ pnpm install ts-fsrs
37
+ bun add ts-fsrs
38
+ ```
39
+
40
+ ## クイックスタート
41
+
42
+ スケジューラーを初期化します。
43
+
44
+ ```ts
45
+ import { createEmptyCard, fsrs, Rating } from 'ts-fsrs'
46
+
47
+ const scheduler = fsrs()
48
+ ```
49
+
50
+ 新しいカードを作成します。
51
+
52
+ ```ts
53
+ const card = createEmptyCard()
54
+ ```
55
+
56
+ 4 つの評価に対する結果をまとめてプレビューします。
57
+
58
+ ```ts
59
+ const preview = scheduler.repeat(card, new Date())
60
+
61
+ console.log(preview[Rating.Again].card)
62
+ console.log(preview[Rating.Hard].card)
63
+ console.log(preview[Rating.Good].card)
64
+ console.log(preview[Rating.Easy].card)
65
+ ```
66
+
67
+ ユーザーの評価がすでに確定している場合は、その評価を直接適用します。
68
+
69
+ ```ts
70
+ const result = scheduler.next(card, new Date(), Rating.Good)
71
+
72
+ console.log(result.card)
73
+ console.log(result.log)
74
+ ```
75
+
76
+ ## 使い方
77
+
78
+ ### カスタムパラメータ
79
+
80
+ ```ts
81
+ import { fsrs } from 'ts-fsrs'
82
+
83
+ const scheduler = fsrs({
84
+ request_retention: 0.9,
85
+ maximum_interval: 36500,
86
+ enable_fuzz: true,
87
+ enable_short_term: true,
88
+ learning_steps: ['1m', '10m'],
89
+ relearning_steps: ['10m'],
90
+ })
91
+ ```
92
+
93
+ `request_retention` は、スケジューラーが維持したい最低保持率(0%から100%)を表します。値を高くすると復習回数は増え、低くすると減ります。
94
+
95
+ `maximum_interval` は、カードをどれだけ先までスケジュールできるかの上限です。
96
+
97
+ `enable_fuzz` は、長い間隔に少量のランダムな揺らぎを加えます。
98
+
99
+ `enable_short_term`、`learning_steps`、`relearning_steps` は短期学習と再学習のステップ挙動を制御します。
100
+
101
+ ### `generatorParameters`
102
+
103
+ `fsrs()` は内部で `generatorParameters()` を使って入力を正規化するため、通常の初期化では部分的な設定オブジェクトをそのまま `fsrs()` に渡せます。
104
+
105
+ `generatorParameters()` は、シリアライズ、保存、または完全な `FSRSParameters` オブジェクトの再利用が必要な場合に使ってください。
106
+
107
+ ```ts
108
+ import { fsrs, generatorParameters } from 'ts-fsrs'
109
+
110
+ const params = generatorParameters({
111
+ request_retention: 0.9,
112
+ maximum_interval: 36500,
113
+ })
114
+
115
+ console.log(JSON.stringify(params))
116
+
117
+ const scheduler = fsrs(params)
118
+ ```
119
+
120
+ 保存したパラメータをあとで読み込む場合も、パースしたオブジェクトをそのまま `fsrs()` に渡せます。
121
+
122
+ ```ts
123
+ import { fsrs, type FSRSParameters } from 'ts-fsrs'
124
+
125
+ const serializedParams = '{"request_retention":0.9,"maximum_interval":36500}'
126
+ const params = JSON.parse(serializedParams) as FSRSParameters
127
+ const scheduler = fsrs(params)
128
+ ```
129
+
130
+ これらのパラメータが外部ストレージ、ユーザー入力、またはネットワークから来る場合は、`fsrs()` に渡す前にアプリケーション境界でランタイム検証を行うことを推奨します。`zod` のようなランタイム schema ライブラリはこの用途に適しています。
131
+
132
+ ### `repeat` と `next`
133
+
134
+ ユーザーが回答する前に 4 通りの結果を見たい場合は `repeat` を使います。
135
+
136
+ ```ts
137
+ const preview = scheduler.repeat(card, new Date())
138
+ ```
139
+
140
+ ユーザーの評価がすでに分かっている場合は `next` を使います。
141
+
142
+ ```ts
143
+ const result = scheduler.next(card, new Date(), Rating.Good)
144
+ ```
145
+
146
+ 結果をそのまま自分の保存形式に変換したい場合は `afterHandler` を使えます。
147
+
148
+ ```ts
149
+ const saved = scheduler.next(card, new Date(), Rating.Good, ({ card, log }) => ({
150
+ card: {
151
+ ...card,
152
+ due: card.due.getTime(),
153
+ last_review: card.last_review?.getTime() ?? null,
154
+ },
155
+ log: {
156
+ ...log,
157
+ due: log.due.getTime(),
158
+ review: log.review.getTime(),
159
+ },
160
+ }))
161
+ ```
162
+
163
+ ### 想起確率
164
+
165
+ ```ts
166
+ const retrievability = scheduler.get_retrievability(result.card, new Date(), false)
167
+ console.log(retrievability)
168
+ ```
169
+
170
+ `elapsed_days`、`stability`、そして有効な decay 値がすでにある場合は、`forgetting_curve()` を直接使って想起確率を計算することもできます。
171
+
172
+ ```ts
173
+ import { forgetting_curve } from 'ts-fsrs'
174
+
175
+ const retrievability = forgetting_curve(0.5, 12, result.card.stability)
176
+ console.log(retrievability)
177
+ ```
178
+
179
+ decay 値を直接渡す場合は、正の数であり、`0.1` から `0.8` の範囲内である必要があります。
180
+
181
+ ### `next_state` と `next_interval`
182
+
183
+ 記憶状態を直接扱う場合は、`next_state()` と `next_interval()` を組み合わせて使えます。
184
+
185
+ ```ts
186
+ import { fsrs, Rating, type FSRSState } from 'ts-fsrs'
187
+
188
+ const scheduler = fsrs({ enable_fuzz: false })
189
+
190
+ const memoryState: FSRSState = {
191
+ stability: 3.2,
192
+ difficulty: 5.6,
193
+ }
194
+
195
+ const elapsedDays = 12
196
+ const nextState = scheduler.next_state(memoryState, elapsedDays, Rating.Good)
197
+ const nextInterval = scheduler.next_interval(nextState.stability, elapsedDays)
198
+
199
+ console.log(nextState)
200
+ console.log(nextInterval)
201
+ ```
202
+
203
+ これはシミュレーション、分析、または `{ stability, difficulty }` を自前で扱うカスタムスケジューリングに便利です。通常の復習フローでは `repeat()` または `next()` を使うほうが自然です。
204
+
205
+ ### 履歴関連のヘルパー
206
+
207
+ スケジューラーは次の補助メソッドも提供します。
208
+
209
+ - `rollback(card, log)`
210
+ - `forget(card, now, reset_count?)`
211
+ - `reschedule(card, reviews, options?)`
212
+
213
+ これらは、既存データのインポート、履歴の再生、保存済みログからの状態再構築に便利です。
214
+
215
+ ## リファレンス
216
+
217
+ カードの状態:
218
+
219
+ ```ts
220
+ State.New
221
+ State.Learning
222
+ State.Review
223
+ State.Relearning
224
+ ```
225
+
226
+ レビュー評価:
227
+
228
+ ```ts
229
+ Rating.Again
230
+ Rating.Hard
231
+ Rating.Good
232
+ Rating.Easy
233
+ ```
234
+
235
+ ## API ドキュメント
236
+
237
+ - リポジトリ概要:[github.com/open-spaced-repetition/ts-fsrs](https://github.com/open-spaced-repetition/ts-fsrs#readme)
238
+ - TypeDoc API ドキュメント:[open-spaced-repetition.github.io/ts-fsrs](https://open-spaced-repetition.github.io/ts-fsrs/)
239
+ - オプティマイザーパッケージ:[`@open-spaced-repetition/binding`](https://www.npmjs.com/package/@open-spaced-repetition/binding)
240
+
241
+ ## 例
242
+
243
+ - ブラウザ例:[example/example.html](https://github.com/open-spaced-repetition/ts-fsrs/blob/main/example/example.html)
244
+ - フルスタックデモ:[ts-fsrs-demo](https://github.com/ishiko732/ts-fsrs-demo)
245
+ - その他の例:
246
+ - [spaced](https://github.com/zsh-eng/spaced)
247
+ - [Anki Search Stats Extended](https://github.com/Luc-Mcgrady/Anki-Search-Stats-Extended)
248
+
249
+ ## コントリビュート
250
+
251
+ 貢献ガイドは [`CONTRIBUTING.md`](https://github.com/open-spaced-repetition/ts-fsrs/blob/main/CONTRIBUTING.md) を参照してください。
package/dist/index.cjs CHANGED
@@ -483,7 +483,7 @@ function alea(seed) {
483
483
  return prng;
484
484
  }
485
485
 
486
- const version="5.3.0";
486
+ const version="5.3.2";
487
487
 
488
488
  const default_request_retention = 0.9;
489
489
  const default_maximum_interval = 36500;
@@ -971,9 +971,7 @@ class BasicScheduler extends AbstractScheduler {
971
971
  const steps_strategy = this.learningStepsStrategy(
972
972
  parameters,
973
973
  card.state,
974
- // In the original learning steps setup (Again = 5m, Hard = 10m, Good = FSRS),
975
- // not adding 1 can cause slight variations in the memory state’s ds.
976
- this.current.state === State.Learning && grade !== Rating.Again && grade !== Rating.Hard ? card.learning_steps + 1 : card.learning_steps
974
+ card.learning_steps
977
975
  );
978
976
  const scheduled_minutes = Math.max(
979
977
  0,