UNPKG

@open-spaced-repetition/sm-2

Version:
138 lines (136 loc) 3.56 kB
// src/Card.ts var Card = class _Card { constructor(cardId = null, n = 0, EF = 2.5, I = 0, due = null, needsExtraReview = false) { if (cardId == null) { cardId = Date.now(); } this.cardId = cardId; this.n = n; this.EF = EF; this.I = I; if (due == null) { due = /* @__PURE__ */ new Date(); } this.due = due; this.needsExtraReview = needsExtraReview; } equals(other) { return this.cardId == other.cardId && this.n == other.n && this.EF == other.EF && this.I == other.I && this.due.getTime() == other.due.getTime() && this.needsExtraReview == other.needsExtraReview; } clone() { return new _Card( this.cardId, this.n, this.EF, this.I, new Date(this.due), this.needsExtraReview ); } toJSON() { return { cardId: this.cardId, n: this.n, EF: this.EF, I: this.I, due: this.due.toISOString(), needsExtraReview: this.needsExtraReview }; } static fromJSON(json) { return new _Card( json.cardId, json.n, json.EF, json.I, new Date(json.due), json.needsExtraReview ); } }; // src/ReviewLog.ts var ReviewLog = class _ReviewLog { constructor(cardId, rating, reviewDatetime, reviewDuration = null) { this.cardId = cardId; this.rating = rating; this.reviewDatetime = reviewDatetime; this.reviewDuration = reviewDuration; } equals(other) { return this.cardId == other.cardId && this.rating == other.rating && this.reviewDatetime.getTime() == other.reviewDatetime.getTime() && this.reviewDuration == other.reviewDuration; } clone() { return new _ReviewLog( this.cardId, this.rating, new Date(this.reviewDatetime), this.reviewDuration ); } toJSON() { return { cardId: this.cardId, rating: this.rating, reviewDatetime: this.reviewDatetime.toISOString(), reviewDuration: this.reviewDuration }; } static fromJSON(json) { return new _ReviewLog( json.cardId, json.rating, new Date(json.reviewDatetime), json.reviewDuration ); } }; // src/Scheduler.ts var Scheduler = class { static reviewCard(card, rating, reviewDatetime = null, reviewDuration = null) { card = card.clone(); if (reviewDatetime == null) { reviewDatetime = /* @__PURE__ */ new Date(); } let cardIsDue = reviewDatetime >= card.due; if (!cardIsDue) { throw new Error(`Card is not due for review until ${card.due}`); } if (card.needsExtraReview) { if (rating >= 4) { card.needsExtraReview = false; card.due.setDate(card.due.getDate() + card.I); } } else { if (rating >= 3) { card.EF = card.EF + (0.1 - (5 - rating) * (0.08 + (5 - rating) * 0.02)); card.EF = Math.max(1.3, card.EF); if (card.n == 0) { card.I = 1; } else if (card.n == 1) { card.I = 6; } else { card.I = Math.ceil(card.I * card.EF); } card.n += 1; if (rating >= 4) { card.due.setDate(card.due.getDate() + card.I); } else { card.needsExtraReview = true; card.due = reviewDatetime; } } else { card.n = 0; card.I = 0; card.due = reviewDatetime; } } const reviewLog = new ReviewLog(card.cardId, rating, reviewDatetime, reviewDuration); return { card, reviewLog }; } }; export { Card, ReviewLog, Scheduler }; //# sourceMappingURL=index.js.map