Skip to content

Commit

Permalink
Merge/Dev 3.1.0-beta8 (#52)
Browse files Browse the repository at this point in the history
* Feat/rollback card (#40)

* Doc/wrong annotations

* Fix/missing 'last_review' in the data returned by the 'createEmptyCard' function

* Fix/incorrect log in record_log

* Feat/rollback card utilizing the current card and log

* Test/rollback

* Test/first repeat (#39)

* Feat/forget (#42)

* Feat/forget

* cherry-pick Feat/grades

* Fix/elapsed days (#45)

* Fix/ incorrect calculation of elapsed_days in the revlog caused by rollback

* pref/remove calculation of last_elapsed_days by rollback

* Chore/rollup (#46)

* Fix/Circular Dependencies

* chore/compilation using Rollup

* example/update

* Chore/rollup (#47)

* pref/remove umd

* Chore/rollup (#48)

* fix/cannot read properties of undefined in umd.js

* pref/remove umd.js

* Refactor/remove dotenv (#49)

* Fix/forget (#50)

* Fix/wrong scheduled_days in forget

* Chore/example (#51)

* chore/change example

* chroe/deploy github pages

* Fix/README.md

* pref/update workflow

* chore/add pr-test-action
  • Loading branch information
ishiko732 authored Nov 20, 2023
1 parent 55c7ab5 commit 44586b3
Show file tree
Hide file tree
Showing 31 changed files with 2,835 additions and 978 deletions.
5 changes: 5 additions & 0 deletions .babelrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"presets": [
["@babel/env", {"modules": false}]
]
}
38 changes: 38 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Deploy to GitHub Pages

on:
push:
branches:
- master

permissions:
contents: read
pages: write
id-token: write

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 16

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build docs
run: pnpm run docs
- name: Copy example folder
run: cp -R example docs/example

- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@4.1.1
with:
branch: gh-pages
folder: docs
30 changes: 30 additions & 0 deletions .github/workflows/npm-beta-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages

name: Publish Beta Package to npm.js

on:
push:
branches:
- dev

jobs:
publish-npm:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v2
- uses: pnpm/action-setup@v2.2.2
with:
version: 8.7.1
- run: pnpm install
- run: pnpm lint
- run: pnpm test
- run: pnpm build
- uses: JS-DevTools/npm-publish@v2
with:
token: ${{secrets.npm_token}}
provenance: true
tag: beta
19 changes: 4 additions & 15 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,12 @@ name: Publish Package to npm.js
on:
release:
types: [published]
push:
branches:
- master
repository_dispatch:
types: [publish-npm]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: pnpm/action-setup@v2.2.2
with:
version: 8.7.1
- run: pnpm install
- run: pnpm lint
- run: pnpm test
- run: pnpm build

publish-npm:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
Expand All @@ -35,6 +22,8 @@ jobs:
with:
version: 8.7.1
- run: pnpm install
- run: pnpm lint
- run: pnpm test
- run: pnpm build
- uses: JS-DevTools/npm-publish@v2
with:
Expand Down
57 changes: 57 additions & 0 deletions .github/workflows/pr-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: PR Test

on:
pull_request:
branches:
- master

jobs:
test:
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 16

- uses: pnpm/action-setup@v2.2.2
with:
version: 8.7.1

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run tests
run: pnpm test

- name: jest coverage report
uses: ArtiomTr/jest-coverage-report-action@v2.0-rc.6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Check test status
id: test-status
run: echo "::set-output name=status::$(if grep -q 'Test failed' test-results.txt; then echo 'failure'; else echo 'success'; fi)"

merge:
needs: test
runs-on: ubuntu-latest
if: ${{ needs.test.outputs.status == 'success' }}

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Trigger npm-publish workflow
uses: peter-evans/repository-dispatch@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ishiko732/ts-fsrs
event-type: publish-npm
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# About The
[![ts-fsrs npm version](https://img.shields.io/npm/v/ts-fsrs.svg)](https://www.npmjs.com/package/ts-fsrs)
[![ts-fsrs beta npm version](https://img.shields.io/npm/v/ts-fsrs/beta.svg)](https://www.npmjs.com/package/ts-fsrs)
[![Build and Publish](https://github.com/ishiko732/ts-fsrs/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/ishiko732/ts-fsrs/actions/workflows/npm-publish.yml)
[![Deploy](https://github.com/ishiko732/ts-fsrs/actions/workflows/deploy.yml/badge.svg)](https://github.com/ishiko732/ts-fsrs/actions/workflows/deploy.yml)

ts-fsrs is a TypeScript package used to implement the [Free Spaced Repetition Scheduler (FSRS) algorithm](https://github.com/open-spaced-repetition/free-spaced-repetition-scheduler). It helps
developers apply FSRS to their flashcard applications, there by improving the user learning experience.
Expand All @@ -7,15 +11,8 @@ developers apply FSRS to their flashcard applications, there by improving the us

```
npm install ts-fsrs
```

# Environment Variables
If you need to customize default parameters, you can modify the values using `.env`/`.env.local`/`.env.production`/`.env.development`.

Copy the [.env.local.example](./example/.env.local.example) file in this directory to .env.local (which will be ignored by Git):

```bash
cp .env.local.example .env.local
yarn install ts-fsrs
pnpm install ts-fsrs
```

# Example
Expand Down Expand Up @@ -51,7 +48,9 @@ Grades.forEach(grade => { // [Rating.Again, Rating.Hard, Rating.Good, Rating.Eas
});
```

> More examples refer to the [Example](https://github.com/ishiko732/ts-fsrs/blob/master/example/index.ts)
More examples refer:
- [Browser](https://github.com/ishiko732/ts-fsrs/blob/master/example/example.html) (ts-fsrs package using CDN)
- [Next.js+Prisma](https://github.com/ishiko732/ts-fsrs-demo)


# Basic Use
Expand Down
57 changes: 56 additions & 1 deletion __tests__/FSRSV4.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
generatorParameters,
FSRS,
createEmptyCard,
State,
Grade,
Grades,
} from "../src/fsrs";

Expand Down Expand Up @@ -47,11 +49,12 @@ describe("FSRS V4 AC by py-fsrs", () => {
],
enable_fuzz: false,
});
const grade: Grade[] = [Rating.Again, Rating.Hard, Rating.Good, Rating.Easy];
it("ivl_history", () => {
let card = createEmptyCard();
let now = new Date(2022, 11, 29, 12, 30, 0, 0);
let scheduling_cards = f.repeat(card, now);
const ratings = [
const ratings: Grade[] = [
Rating.Good,
Rating.Good,
Rating.Good,
Expand All @@ -68,6 +71,16 @@ describe("FSRS V4 AC by py-fsrs", () => {
];
const ivl_history: number[] = [];
for (const rating of ratings) {
for (const check of grade) {
const rollbackCard = f.rollback(
scheduling_cards[check].card,
scheduling_cards[check].log,
);
expect(rollbackCard).toEqual(card);
expect(scheduling_cards[check].log.elapsed_days).toEqual(
card.last_review ? now.diff(card.last_review as Date, "days") : 0,
);
}
card = scheduling_cards[rating].card;
const ivl = card.scheduled_days;
ivl_history.push(ivl);
Expand All @@ -79,4 +92,46 @@ describe("FSRS V4 AC by py-fsrs", () => {
0, 5, 16, 43, 106, 236, 0, 0, 12, 25, 47, 85, 147,
]);
});

it("first repeat", () => {
const card = createEmptyCard();
const now = new Date(2022, 11, 29, 12, 30, 0, 0);
const scheduling_cards = f.repeat(card, now);
const grades: Grade[] = [
Rating.Again,
Rating.Hard,
Rating.Good,
Rating.Easy,
];

const stability: number[] = [];
const difficulty: number[] = [];
const elapsed_days: number[] = [];
const scheduled_days: number[] = [];
const reps: number[] = [];
const lapses: number[] = [];
const states: State[] = [];
for (const rating of grades) {
const first_card = scheduling_cards[rating].card;
stability.push(first_card.stability);
difficulty.push(first_card.difficulty);
reps.push(first_card.reps);
lapses.push(first_card.lapses);
elapsed_days.push(first_card.elapsed_days);
scheduled_days.push(first_card.scheduled_days);
states.push(first_card.state);
}
expect(stability).toEqual([1.14, 1.01, 5.44, 14.67]);
expect(difficulty).toEqual([8.4348, 6.8686, 5.3024, 3.7361999999999993]);
expect(reps).toEqual([1, 1, 1, 1]);
expect(lapses).toEqual([1, 0, 0, 0]);
expect(elapsed_days).toEqual([0, 0, 0, 0]);
expect(scheduled_days).toEqual([0, 0, 0, 15]);
expect(states).toEqual([
State.Learning,
State.Learning,
State.Learning,
State.Review,
]);
});
});
74 changes: 74 additions & 0 deletions __tests__/elapsed_days.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Ref:https://github.com/ishiko732/ts-fsrs/issues/44

import { fsrs, FSRS, createEmptyCard, Rating, Grade } from "../src/fsrs";

describe("elapsed_days", () => {
const f: FSRS = fsrs();

const createDue = new Date(Date.UTC(2023, 9, 18, 14, 32, 3, 370));
const grades: Grade[] = [
Rating.Good,
Rating.Again,
Rating.Again,
Rating.Good,
];
let currentLog = null;
let index = 0;
let card = createEmptyCard(createDue);
test("first repeat[Rating.Good]", () => {
const firstDue = new Date(Date.UTC(2023, 10, 5, 8, 27, 2, 605));
const sc = f.repeat(card, firstDue);
currentLog = sc[grades[index]].log;

expect(currentLog.elapsed_days).toEqual(0);
// console.log(sc[grades[index]].log)
card = sc[grades[index]].card;
// console.log(card)
index += 1;
});

test("second repeat[Rating.Again]", () => {
// 2023-11-08 15:02:09.791,4.93,2023-11-05 08:27:02.605
const secondDue = new Date(Date.UTC(2023, 10, 8, 15, 2, 9, 791));
expect(card).not.toBeNull()
const sc = f.repeat(card, secondDue);

currentLog = sc[grades[index]].log;
expect(currentLog.elapsed_days).toEqual(secondDue.diff(card.last_review as Date,'days')); // 3
expect(currentLog.elapsed_days).toEqual(3); // 0
card = sc[grades[index]].card;
// console.log(card)
// console.log(currentLog)
index += 1;
});

test("third repeat[Rating.Again]", () => {
// 2023-11-08 15:02:30.799,4.93,2023-11-08 15:02:09.791
const secondDue = new Date(Date.UTC(2023, 10, 8, 15, 2, 30, 799));
expect(card).not.toBeNull()
const sc = f.repeat(card, secondDue);

currentLog = sc[grades[index]].log;
expect(currentLog.elapsed_days).toEqual(secondDue.diff(card.last_review as Date,'days')); // 0
expect(currentLog.elapsed_days).toEqual(0); // 0
// console.log(currentLog);
card = sc[grades[index]].card;
// console.log(card);
index += 1;
});

test("fourth repeat[Rating.Good]", () => {
// 2023-11-08 15:04:08.739,4.93,2023-11-08 15:02:30.799
const secondDue = new Date(Date.UTC(2023, 10, 8, 15, 4, 8, 739));
expect(card).not.toBeNull()
const sc = f.repeat(card, secondDue);

currentLog = sc[grades[index]].log;
expect(currentLog.elapsed_days).toEqual(secondDue.diff(card.last_review as Date,'days')); // 0
expect(currentLog.elapsed_days).toEqual(0); // 0
// console.log(currentLog);
card = sc[grades[index]].card;
// console.log(card);
index += 1;
})
});
Loading

0 comments on commit 44586b3

Please sign in to comment.