{"id":22356874,"url":"https://github.com/ayamflow/srs-system","last_synced_at":"2025-09-07T07:06:43.323Z","repository":{"id":149854549,"uuid":"324586393","full_name":"ayamflow/srs-system","owner":"ayamflow","description":"A (naive) javascript Spaced-Repetition System (SRS) for flashcards-based learning","archived":false,"fork":false,"pushed_at":"2021-01-07T14:15:13.000Z","size":171,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-02T14:10:47.508Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ayamflow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-26T15:48:42.000Z","updated_at":"2023-06-13T05:05:28.000Z","dependencies_parsed_at":"2023-04-05T09:23:59.707Z","dependency_job_id":null,"html_url":"https://github.com/ayamflow/srs-system","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ayamflow/srs-system","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayamflow%2Fsrs-system","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayamflow%2Fsrs-system/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayamflow%2Fsrs-system/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayamflow%2Fsrs-system/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ayamflow","download_url":"https://codeload.github.com/ayamflow/srs-system/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ayamflow%2Fsrs-system/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274005465,"owners_count":25205968,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-04T14:12:17.327Z","updated_at":"2025-09-07T07:06:43.294Z","avatar_url":"https://github.com/ayamflow.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"SRS System\n===\n\nA dependency-free javascript Spaced Repetition System (SRS).\n\nSee more about SRS [on Wikipedia](https://en.wikipedia.org/wiki/Spaced_repetition).\n\nOften used for memorizing a new language's vocabulary, it's a learning system based on cards, where the ones that you fail to remember are asked more often than the ones you remember.\nCards have 2 sides, usually the meaning (in your native tongue), and the word in the learned language on the other side.\n\n\nIt includes 3 classes:\n- `Card` which represents a \"learnable item\", which can be inherited to override validation.\n- `Scheduler` which manages when a card has to be reviewed.\n- `Review` which is a series of questions asking both sides of each card provided.\n\n\u003e :warning: this package is in alpha version - the API and classes are still being defined.\n\n## Usage\n\n```js\nimport { Schedule, Card, Review } from 'srs-system'\n\n// Create the scheduler which determines when cards are ready to be reviewed\nconst scheduler = new Scheduler({\n    computeStage: function(card) {\n        let errorFactor = Math.ceil(card.wrongAnswersCount * 0.5)\n        let stage = card.stage - errorFactor\n        return stage\n    },\n\n    stages: [{\n        name: 'newbie',\n        interval: 0 \n    }, {\n        name: 'advanced beginner',\n        interval: 4 * 60 * 60 * 1000 // 4 hours\n    }, {\n        name: 'intermediate',\n        interval: 24 * 60 * 60 * 1000 // 1 day\n    }, {\n        name: 'advanced',\n        interval: 2 * 24 * 60 * 60 * 1000 // 2 days\n    }, {\n        name: 'expert',\n        interval: 7 * 24 * 60 * 60 * 1000 // 1 week\n    }]\n\n    // In real life, cards would be associated to a question and a set of answers\n    cards: [\n\t    new Card('Bonjour', 'Hello'),\n        new Card('Merci', ['Thanks', 'Thank you'])\n    ]\n})\n\n// Create a review, a sequence of questions to check your knowledge\n// Passing a wrong answer will push the card to the back of the review queue.\n// Passing a correct answer will remove the card from the queue.\nscheduler.cards.forEach(card =\u003e card.enable())\nlet review = new Review(scheduler)\nlet current = review.getNext()\nwhile(current) {\n    console.log(card.side) // Question to be answered\n    review.answer(value) // 'bonjour'\n    console.log(`Reviewed ${review.done} / ${review.length}`)\n    current = review.getNext()\n}\nconsole.log('Review session completed!') // The review is over when all cards have been answered properly\n\n// You can query the scheduler to know when cards are going to be reviewed\n// Cards answered correctly will be reviewed later than the one answered wrongly\nlet timeline = scheduler.getTimeline()\n// 2d array of cards ordered by day/hour as: [dayIndex][hourIndex]\n\n```\n\n## API\n\n### Scheduler\n#### Constructor\n- new Scheduler(options)\n    - `options.computeStage(card)` function used to return the new `stage` value for a card after its review. The stage indicates how that specific card is known - 1 is the lowest (not known)\n    - `cards`: array of `Card`\n    - `intervals`: ordered array of object with a `.interval` property defining the time before the next review for each `stage`, in milliseconds.\n#### Methods\n- `getCards()` Return all cards ready for review right now\n- `getTimeline(start = now, end = -1)` Return a timeline (day/hour) of upcoming reviews between \u003cstart\u003e and \u003cend\u003e timestamps, up to a week ahead.\n- `update(card)` update a given card interval, after its been answered\n- `toJSON()` Return a JSON representation of all the cards. Used for saving state into a DB or filesystem.\n- `fromJSON(json)` Import previously saved cards from JSON data. Used for restoring state from a DB or filesystem.\n\n#### Properties\n- `cards`: array of `Card` classes\n\n### Card\nRepresents a learnable item. It has 2 sides, a \"frontSide\" and \"backSide\" which are usually a question/answer couple.\n#### Constructor\n- new Card(frontSide, backSide)\n\t- `frontSide` a string or array of strings representing the value of the front side of the card\n\t- `backSide` a string or array of strings representing the value of the back side of the card\n#### Methods\n- `answer(true/false)` Answer the card with correct (true) or incorrect (false) answer\n- `checkAnswer(value, isFrontSide)` Checks if the answer value is correct for that side of the card\n- `reset()` Reset all properties of this card\n- `enable()` Mark a card as enabled so that it will be processed. By default, card are disabled so that you can implement custom logic for unlocking new cards.\n- `checkFrontSide(value)` Logic for determining if an answer matches the card front side. Inherit the class to override.\n- `checkBackSide(value)` Logic for determining if an answer matches the card front side. Inherit the class to override.\n\n#### Properties\n- `stage` (get/set) index of the current interval for this card\n- `timestamp` (get/set) next timestamp for the card to be reviewed\n- `rightAnswersCount` (get) The number of time the card has been answered correctly\n- `wrongAnswersCount` (get) The number of time the card has been answered wrongly\n- `enabled` (get) true if the card is enabled, false otherwise\n\n### Review\nA sequence of questions testing each side of the cards ready for review.\n#### Constructor\nnew Review(scheduler)\n\t- `scheduler` an instance of a Scheduler\n#### Methods\n- `getNext()` returns the next question, if any.\n\tThis is an object such as: \n    ```js\n    {\n    \tside: \u003cvalues from card.frontSide or card.backSide\u003e,\n        isFrontSide: true/false,\n        errored: false,\n        card: \u003cinstance of Card\u003e\n    }\n\t```\n- `answer(value)` answer the current card (with `Card.answer(value)`), updates the review queue and internally call `scheduler.update(card)` if needed.\n\n#### Properties\n- `length` the number of question in the review - by default, twice as much as available cards (1 question per card side).\n- `done` the number of questions successfully answered.\n\n\n## Roadmap\n- Make sure it's possible to implement supermemo \u0026 other popular algorithms\n\n## License\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fayamflow%2Fsrs-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fayamflow%2Fsrs-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fayamflow%2Fsrs-system/lists"}