@zephyr424/wb-sdk 0.1.1 → 0.2.0

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.
@@ -0,0 +1,112 @@
1
+ import { defineConfig } from 'vitepress'
2
+
3
+ export default defineConfig({
4
+ title: "wb-sdk",
5
+ description: "A spaced repetition engine for vocabulary building",
6
+
7
+ // 网站图标
8
+ head: [
9
+ ['link', { rel: 'icon', href: '/logo.png' }],
10
+ // Google Analytics(替换为你的 GA ID)
11
+ ['script', { async: '', src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX' }],
12
+ ['script', {}, `
13
+ window.dataLayer = window.dataLayer || [];
14
+ function gtag(){dataLayer.push(arguments);}
15
+ gtag('js', new Date());
16
+ gtag('config', 'G-XXXXXXXXXX');
17
+ `]
18
+ ],
19
+
20
+ // 深浅主题(默认已支持)
21
+ appearance: true,
22
+
23
+ themeConfig: {
24
+ // 搜索
25
+ search: {
26
+ provider: 'local'
27
+ },
28
+
29
+ // 导航栏
30
+ nav: [
31
+ { text: 'Home', link: '/' },
32
+ { text: 'Guide', link: '/guide/' },
33
+ { text: 'API', link: '/api/word' },
34
+ { text: 'Blog', link: '/blog/' },
35
+ { text: 'GitHub', link: 'https://github.com/Zephyr424/wb-sdk' },
36
+ { text: 'npm', link: 'https://www.npmjs.com/package/@zephyr424/wb-sdk' }
37
+ ],
38
+
39
+ // 侧边栏
40
+ sidebar: {
41
+ '/guide/': [
42
+ {
43
+ text: 'Guide',
44
+ items: [
45
+ { text: 'Getting Started', link: '/guide/' },
46
+ { text: 'Core Concepts', link: '/guide/core-concepts' }
47
+ ]
48
+ }
49
+ ],
50
+ '/api/': [
51
+ {
52
+ text: 'API Reference',
53
+ items: [
54
+ { text: 'Word Management', link: '/api/word' },
55
+ { text: 'Review Scheduling', link: '/api/review' },
56
+ { text: 'Types', link: '/api/types' }
57
+ ]
58
+ }
59
+ ],
60
+ '/blog/': [
61
+ {
62
+ text: 'Blog',
63
+ items: [
64
+ { text: 'Why SM-2 Algorithm', link: '/blog/why-sm2' },
65
+ { text: 'Designing wb.word API', link: '/blog/designing-api' },
66
+ { text: 'How I Published to npm', link: '/blog/publishing-to-npm' }
67
+ ]
68
+ }
69
+ ]
70
+ },
71
+
72
+ // 社交链接
73
+ socialLinks: [
74
+ { icon: 'github', link: 'https://github.com/Zephyr424/wb-sdk' }
75
+ ],
76
+
77
+ // 页脚
78
+ footer: {
79
+ message: 'Released under the MIT License',
80
+ copyright: 'Copyright © 2026 Zephyr424'
81
+ },
82
+
83
+ // 上次更新时间
84
+ lastUpdated: {
85
+ text: 'Last updated'
86
+ },
87
+
88
+ // 贡献者展示(需要 GitHub API 支持,先配置)
89
+ contributors: {
90
+ avatarSize: 32
91
+ },
92
+
93
+ // 编辑链接(指向 GitHub)
94
+ editLink: {
95
+ pattern: 'https://github.com/Zephyr424/wb-sdk/edit/main/docs/:path',
96
+ text: 'Edit this page on GitHub'
97
+ }
98
+ },
99
+
100
+ // 多语言支持 (i18n)
101
+ locales: {
102
+ root: {
103
+ label: '简体中文',
104
+ lang: 'zh-CN'
105
+ },
106
+ en: {
107
+ label: 'English',
108
+ lang: 'en',
109
+ link: '/en/'
110
+ }
111
+ }
112
+ })
@@ -0,0 +1,155 @@
1
+ # Review Scheduling API
2
+
3
+ The `wb.review` module handles all spaced repetition logic — determining which words are due, recording review performance, and forecasting future workload.
4
+
5
+ ---
6
+
7
+ ## `wb.review.getDue([today])`
8
+
9
+ Returns all words that are due for review on a given date.
10
+
11
+ **Parameters:**
12
+
13
+ | Parameter | Type | Required | Description |
14
+ | :--- | :--- | :--- | :--- |
15
+ | `today` | `Date` | ❌ No | The date to check (defaults to `new Date()`). |
16
+
17
+ **Returns:** `Word[]` — an array of `Word` objects that are due.
18
+
19
+ **Example:**
20
+
21
+ ```javascript
22
+ // Get words due today
23
+ const dueToday = wb.review.getDue();
24
+ console.log(`📚 ${dueToday.length} words due today`);
25
+
26
+ // Get words due on a specific date
27
+ const christmasDue = wb.review.getDue(new Date('2026-12-25'));
28
+ ```
29
+
30
+ ---
31
+
32
+ ## `wb.review.submit(id, quality)`
33
+
34
+ Records a review attempt for a specific word and updates its SM‑2 state (interval, repetitions, ease factor, and last reviewed date).
35
+
36
+ **Parameters:**
37
+
38
+ | Parameter | Type | Required | Description |
39
+ | :--- | :--- | :--- | :--- |
40
+ | `id` | `string` | ✅ Yes | The ID of the word being reviewed. |
41
+ | `quality` | `number` | ✅ Yes | Self‑rated recall quality from `0` (completely forgot) to `5` (perfect recall). |
42
+
43
+ **Returns:** `Word` — the updated `Word` object.
44
+
45
+ **Quality Scale:**
46
+
47
+ | Score | Meaning |
48
+ | :--- | :--- |
49
+ | `5` | Perfect recall |
50
+ | `4` | Good recall, slight hesitation |
51
+ | `3` | Recalled with difficulty |
52
+ | `2` | Forgot, but recognized |
53
+ | `1` | Almost forgot |
54
+ | `0` | Completely forgot |
55
+
56
+ **Example:**
57
+
58
+ ```javascript
59
+ // Review the word with ID 'apple' and rate it as 4/5
60
+ const updated = wb.review.submit('apple', 4);
61
+ console.log(`Next review in ${updated.interval} days`);
62
+ ```
63
+
64
+ ---
65
+
66
+ ## `wb.review.forecast([days])`
67
+
68
+ Predicts how many words will become due for each day over the next N days, based on current word states.
69
+
70
+ **Parameters:**
71
+
72
+ | Parameter | Type | Required | Description |
73
+ | :--- | :--- | :--- | :--- |
74
+ | `days` | `number` | ❌ No | Number of days to forecast (default: `7`). |
75
+
76
+ **Returns:** `Object` — a dictionary where keys are date strings (`YYYY-MM-DD`) and values are the number of words due on that day.
77
+
78
+ **Example:**
79
+
80
+ ```javascript
81
+ const forecast = wb.review.forecast(7);
82
+ console.log(forecast);
83
+ // {
84
+ // '2026-09-01': 5,
85
+ // '2026-09-02': 8,
86
+ // '2026-09-03': 3,
87
+ // '2026-09-04': 0,
88
+ // '2026-09-05': 2,
89
+ // '2026-09-06': 4,
90
+ // '2026-09-07': 1
91
+ // }
92
+ ```
93
+
94
+ ---
95
+
96
+ ## `wb.review.progress()`
97
+
98
+ Returns an overview of your overall learning status — total words, mastered, remaining, and estimated days to mastery.
99
+
100
+ **Returns:** `Object` with the following fields:
101
+
102
+ | Field | Type | Description |
103
+ | :--- | :--- | :--- |
104
+ | `total` | `number` | Total number of words in the bank. |
105
+ | `mastered` | `number` | Number of words with an interval ≥ 30 days. |
106
+ | `remaining` | `number` | Words not yet mastered (`total - mastered`). |
107
+ | `daysToMaster` | `number` | Estimated days until all words are mastered (based on an assumed rate of 5 new words mastered per day). |
108
+
109
+ **Example:**
110
+
111
+ ```javascript
112
+ const stats = wb.review.progress();
113
+ console.log(stats);
114
+ // { total: 5000, mastered: 1200, remaining: 3800, daysToMaster: 760 }
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Understanding the SM‑2 Algorithm
120
+
121
+ The `submit` method implements the **SM‑2** algorithm, which works as follows:
122
+
123
+ - If `quality < 3` (failed recall):
124
+ - The word's `repetitions` counter is reset to `0`.
125
+ - The `interval` is set to `1` day (review again tomorrow).
126
+ - The `easeFactor` remains unchanged.
127
+
128
+ - If `quality >= 3` (successful recall):
129
+ - The `interval` is updated based on the current `repetitions` count:
130
+ - `repetitions == 0` → interval = `1` day
131
+ - `repetitions == 1` → interval = `6` days
132
+ - `repetitions >= 2` → interval = `round(interval * easeFactor)`
133
+ - The `repetitions` count is incremented.
134
+ - The `easeFactor` is adjusted using the formula:
135
+ ```
136
+ ease += 0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02)
137
+ ```
138
+ The result is clamped between `1.3` and `2.5`.
139
+
140
+ This dynamic adjustment ensures that words you find difficult appear more frequently, while easy words are spaced out over longer intervals.
141
+
142
+ ---
143
+
144
+ ## Summary of `wb.review` Methods
145
+
146
+ | Method | Description |
147
+ | :--- | :--- |
148
+ | `getDue([today])` | Get words due for review today (or on a custom date). |
149
+ | `submit(id, quality)` | Record a review and update the word's SM‑2 state. |
150
+ | `forecast([days])` | Predict how many words will be due each day for the next N days. |
151
+ | `progress()` | Get overall learning statistics (total, mastered, remaining, days to mastery). |
152
+
153
+ For word management methods (`list`, `get`, `add`, `remove`, `search`, `top`), see the [Word Management API](/api/word).
154
+
155
+ ---
Binary file
@@ -0,0 +1,189 @@
1
+ # Word Management API
2
+
3
+ The `wb.word` module provides methods for managing your word bank — adding, retrieving, searching, and deleting words.
4
+
5
+ ---
6
+
7
+ ## `wb.word.list()`
8
+
9
+ Returns all words currently stored in the bank.
10
+
11
+ **Returns:** `Word[]` — an array of `Word` objects.
12
+
13
+ **Example:**
14
+
15
+ ```javascript
16
+ const allWords = wb.word.list();
17
+ console.log(allWords);
18
+ // [
19
+ // Word { id: '1', word: 'apple', definition: 'a fruit', ... },
20
+ // Word { id: '2', word: 'book', definition: 'a set of pages', ... }
21
+ // ]
22
+ ```
23
+
24
+ ---
25
+
26
+ ## `wb.word.get(id)`
27
+
28
+ Retrieves a single word by its unique identifier.
29
+
30
+ **Parameters:**
31
+
32
+ | Parameter | Type | Required | Description |
33
+ | :--- | :--- | :--- | :--- |
34
+ | `id` | `string` | ✅ Yes | The unique ID of the word |
35
+
36
+ **Returns:** `Word | null` — the word object if found, otherwise `null`.
37
+
38
+ **Example:**
39
+
40
+ ```javascript
41
+ const word = wb.word.get('apple');
42
+ if (word) {
43
+ console.log(word.definition); // "a fruit"
44
+ } else {
45
+ console.log('Word not found');
46
+ }
47
+ ```
48
+
49
+ ---
50
+
51
+ ## `wb.word.add(data)`
52
+
53
+ Adds a new word to the bank. If a word with the same ID already exists, it will be overwritten.
54
+
55
+ **Parameters:**
56
+
57
+ | Parameter | Type | Required | Description |
58
+ | :--- | :--- | :--- | :--- |
59
+ | `data.id` | `string` | ✅ Yes | Unique identifier |
60
+ | `data.word` | `string` | ✅ Yes | The word itself |
61
+ | `data.definition` | `string` | ✅ Yes | Meaning or translation |
62
+ | `data.repetitions` | `number` | ❌ No | Default: `0` |
63
+ | `data.interval` | `number` | ❌ No | Default: `0` (days) |
64
+ | `data.easeFactor` | `number` | ❌ No | Default: `2.5` (range 1.3–2.5) |
65
+ | `data.lastReviewed` | `string \| Date \| null` | ❌ No | Default: `null` (ISO string or Date object) |
66
+
67
+ **Returns:** `Word` — the newly created (or updated) word object.
68
+
69
+ **Example:**
70
+
71
+ ```javascript
72
+ // Add a simple word
73
+ wb.word.add({
74
+ id: 'grok',
75
+ word: 'grok',
76
+ definition: 'to understand intuitively'
77
+ });
78
+
79
+ // Add a word with explicit SM‑2 state (e.g., when importing data)
80
+ wb.word.add({
81
+ id: 'serendipity',
82
+ word: 'serendipity',
83
+ definition: 'the occurrence of events by chance in a happy way',
84
+ repetitions: 3,
85
+ interval: 15,
86
+ easeFactor: 2.3,
87
+ lastReviewed: '2026-08-15T10:00:00.000Z'
88
+ });
89
+ ```
90
+
91
+ ---
92
+
93
+ ## `wb.word.remove(id)`
94
+
95
+ Permanently deletes a word from the bank by its ID.
96
+
97
+ **Parameters:**
98
+
99
+ | Parameter | Type | Required | Description |
100
+ | :--- | :--- | :--- | :--- |
101
+ | `id` | `string` | ✅ Yes | The unique ID of the word to remove |
102
+
103
+ **Returns:** `void`
104
+
105
+ **Example:**
106
+
107
+ ```javascript
108
+ wb.word.remove('grok');
109
+ // Now 'grok' is no longer in the bank
110
+ ```
111
+
112
+ ---
113
+
114
+ ## `wb.word.search(keyword)`
115
+
116
+ Searches for words whose **word** or **definition** contains the given keyword (case‑insensitive).
117
+
118
+ **Parameters:**
119
+
120
+ | Parameter | Type | Required | Description |
121
+ | :--- | :--- | :--- | :--- |
122
+ | `keyword` | `string` | ✅ Yes | The search term (case‑insensitive) |
123
+
124
+ **Returns:** `Word[]` — an array of matching words (empty if none found).
125
+
126
+ **Example:**
127
+
128
+ ```javascript
129
+ const results = wb.word.search('bene');
130
+ // Returns words like "benevolent", "beneficial", "benefit"
131
+ results.forEach(w => console.log(`${w.word}: ${w.definition}`));
132
+ ```
133
+
134
+ ---
135
+
136
+ ## `wb.word.top(n)`
137
+
138
+ Returns the top `n` words with the **highest repetition count** — i.e., the words you have reviewed most often.
139
+
140
+ **Parameters:**
141
+
142
+ | Parameter | Type | Required | Description |
143
+ | :--- | :--- | :--- | :--- |
144
+ | `n` | `number` | ✅ Yes | Number of top words to return |
145
+
146
+ **Returns:** `Word[]` — an array of the top `n` words (sorted descending by repetitions).
147
+
148
+ **Example:**
149
+
150
+ ```javascript
151
+ const mostPracticed = wb.word.top(10);
152
+ console.log('Your top 10 most practiced words:');
153
+ mostPracticed.forEach(w => console.log(`${w.word} (${w.repetitions} reviews)`));
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Data Type: `Word`
159
+
160
+ The `Word` object contains the following fields:
161
+
162
+ | Field | Type | Description |
163
+ | :--- | :--- | :--- |
164
+ | `id` | `string` | Unique identifier |
165
+ | `word` | `string` | The word itself |
166
+ | `definition` | `string` | Meaning or translation |
167
+ | `repetitions` | `number` | Number of successful reviews |
168
+ | `interval` | `number` | Current interval in days |
169
+ | `easeFactor` | `number` | Difficulty factor (1.3 – 2.5) |
170
+ | `lastReviewed` | `Date \| null` | Timestamp of the last review (Date object or null) |
171
+ | `isDue(today?: Date)` | `function` | Returns `true` if the word is due for review on the given date (default: today) |
172
+ | `toJSON()` | `function` | Returns a plain object suitable for serialization (e.g., to store in JSON) |
173
+
174
+ ---
175
+
176
+ ## Summary of `wb.word` Methods
177
+
178
+ | Method | Description |
179
+ | :--- | :--- |
180
+ | `list()` | Get all words |
181
+ | `get(id)` | Get a word by ID |
182
+ | `add(data)` | Add or update a word |
183
+ | `remove(id)` | Delete a word |
184
+ | `search(keyword)` | Search words by word or definition |
185
+ | `top(n)` | Get the most frequently reviewed words |
186
+
187
+ For the review‑scheduling methods, see the [Review Scheduling API](/api/review).
188
+
189
+ ---
@@ -0,0 +1,30 @@
1
+ # Designing wb.word API
2
+
3
+ The **API design** is the most important part of any library. A well-designed API makes developers want to use your library — and a bad one makes them run away.
4
+
5
+ ## Design principles
6
+
7
+ 1. **Intuitive**: Developers should guess how to use it without reading the docs.
8
+ 2. **Chainable**: Group related methods under clear namespaces.
9
+ 3. **Minimal**: Don't expose internal complexity.
10
+
11
+ ## Why wb.word and wb.review?
12
+
13
+ I wanted developers to write code that reads like English:
14
+
15
+ ```javascript
16
+ wb.word.add({ id: '1', word: 'apple', definition: 'a fruit' });
17
+ const due = wb.review.getDue();
18
+ ```
19
+
20
+ This is **self-documenting code** — you don't need comments to understand what it does.
21
+
22
+ ## What I learned
23
+
24
+ - **Simplicity wins**: Remove unnecessary options and configurations.
25
+ - **Document everything**: Even the most intuitive API needs examples.
26
+ - **Listen to users**: The first user feedback I got helped me improve the design.
27
+
28
+ ---
29
+
30
+ *Written on September 1, 2026*
@@ -0,0 +1,19 @@
1
+ # Blog
2
+
3
+ Welcome to the wb-sdk blog! Here I share my thoughts, learnings, and updates about the project.
4
+
5
+ ## Latest Posts
6
+
7
+ - [Why SM-2 Algorithm](./why-sm2) — Understanding the science behind spaced repetition
8
+ - [Designing wb.word API](./designing-api) — How I designed the word management interface
9
+ - [How I Published to npm](./publishing-to-npm) — The journey from local code to global package
10
+
11
+ ---
12
+
13
+ ## All Posts
14
+
15
+ | Date | Title | Description |
16
+ | :--- | :--- | :--- |
17
+ | 2026-09-01 | [Why SM-2 Algorithm](./why-sm2) | Why I chose SM-2 over other algorithms |
18
+ | 2026-09-01 | [Designing wb.word API](./designing-api) | The design principles behind the API |
19
+ | 2026-08-31 | [How I Published to npm](./publishing-to-npm) | A step-by-step guide to npm publishing |
@@ -0,0 +1,36 @@
1
+ # How I Published to npm
2
+
3
+ Publishing my first npm package was harder than writing the code itself.
4
+
5
+ ## The challenges
6
+
7
+ 1. **2FA setup**: npm requires two-factor authentication, and I had to generate tokens properly.
8
+ 2. **Scoped package name**: wb-sdk was too similar to ws-sdk, so I had to use @zephyr424/wb-sdk.
9
+ 3. **GitHub integration**: Configuring the repository link and GitHub Pages deployment.
10
+
11
+ ## Step-by-step guide
12
+
13
+ \\\ash
14
+ # 1. Login to npm
15
+ npm login
16
+
17
+ # 2. Build and test locally
18
+ npm run test
19
+
20
+ # 3. Bump version
21
+ npm version patch
22
+
23
+ # 4. Publish to npm
24
+ npm publish --access public
25
+ \\\
26
+
27
+ ## Lessons learned
28
+
29
+ - **Read the error messages**: npm tells you exactly what's wrong.
30
+ - **Test before publishing**: Always test with
31
+ pm link first.
32
+ - **Use a .npmignore file**: Control which files get published.
33
+
34
+ ---
35
+
36
+ *Written on August 31, 2026*
@@ -0,0 +1,26 @@
1
+ # Why SM-2 Algorithm
2
+
3
+ The **SM-2** algorithm, developed by Piotr Woźniak in the 1980s, is the foundation of **spaced repetition** — a technique that optimizes memory retention by scheduling reviews at increasing intervals.
4
+
5
+ ## Why I chose SM-2
6
+
7
+ 1. **Proven track record**: SM-2 is the algorithm behind Anki, the most popular flashcard app.
8
+ 2. **Simple implementation**: The algorithm is elegant and easy to code.
9
+ 3. **Highly effective**: Research shows spaced repetition can boost retention by over 200%.
10
+
11
+ ## How it works
12
+
13
+ When you rate your recall quality from 0 to 5:
14
+
15
+ - **Quality < 3**: You forgot the word → reset interval to 1 day.
16
+ - **Quality ≥ 3**: You remembered it → increase the interval and adjust the ease factor.
17
+
18
+ This dynamic adjustment ensures you spend time on words you're about to forget.
19
+
20
+ ## Future plans
21
+
22
+ I'm planning to add **FSRS** support in a future version — a more advanced algorithm that uses machine learning to optimize intervals.
23
+
24
+ ---
25
+
26
+ *Written on September 1, 2026*
@@ -0,0 +1,16 @@
1
+ # Contributors
2
+
3
+ Thank you to everyone who has contributed to \wb-sdk\!
4
+
5
+ ## Core Contributors
6
+
7
+ - [@Zephyr424](https://github.com/Zephyr424) — Creator and maintainer
8
+
9
+ ## How to Contribute
10
+
11
+ Want to join this list? Check out the [GitHub repository](https://github.com/Zephyr424/wb-sdk) and submit a pull request!
12
+
13
+ - 🐛 Found a bug? Open an issue.
14
+ - 💡 Have an idea? Start a discussion.
15
+ - 📝 Want to improve docs? Send a PR.
16
+ - 🧪 Want to add a feature? Fork and contribute!