dralkh_spaceforge/models/review-schedule.ts
dralkh e80dfda20d release: v1.0.5
JS/TS:
- Replace builtin-modules with node:module (esbuild.config.mjs)
- Replace fs-extra with native fs (install.js), remove from deps
- Fix createEl deprecation: use createDiv/createSpan
- Remove unnecessary type assertions, fix unsafe casts
- Bind event handlers with arrow functions

CSS:
- Remove all !important declarations (~30 instances) — replace with
  chained selectors (.class.class) for equal specificity
- Merge all duplicate selectors across 7 CSS files (~50+ instances)
- Convert 3-digit hex to 6-digit format (_variables.css)
- Fix duplicate CSS properties (overflow-y in mcq.css)
- Delete leftover display:none suppression rule in calendar.css

Meta:
- Bump version to 1.0.5
- Update minAppVersion to 1.8.7
- Add versions.json entry for 1.0.5
2026-05-20 11:02:54 +03:00

172 lines
4.3 KiB
TypeScript

/**
* Represents a note's review schedule in the spaced repetition system
*/
export interface ReviewSchedule {
/**
* Path to the note file - unique identifier
*/
path: string;
/**
* Timestamp of the last review
*/
lastReviewDate: number | null;
/**
* Timestamp of the next scheduled review
*/
nextReviewDate: number;
/**
* Ease factor - affects interval growth (higher = longer intervals)
* In SM-2, this is a value typically starting at 2.5 (stored as 250 internally)
*/
ease: number;
/**
* Current interval in days
*/
interval: number;
/**
* Number of consecutive successful reviews (for backward compatibility)
*/
consecutive: number;
/**
* Total number of completed reviews (for backward compatibility)
*/
reviewCount: number;
/**
* SM-2 repetition count - used to determine interval calculation (n)
* This is 1 for items in "learning" phase and increments for each successful review
*/
repetitionCount?: number;
/**
* Defines the scheduling category for the note.
* 'initial': Note is following the initial learning intervals.
* 'spaced': Note is using standard SM-2 from the start.
* 'graduated': Note has completed initial intervals and now uses SM-2.
*/
scheduleCategory?: 'initial' | 'spaced' | 'graduated'; // Made optional for FSRS cards
// --- FSRS Specific Data ---
fsrsData?: {
stability: number;
difficulty: number;
elapsed_days: number;
scheduled_days: number;
reps: number;
lapses: number;
state: number; // ts-fsrs.State enum (0:New, 1:Learning, 2:Review, 3:Relearning)
last_review?: number; // Timestamp of last FSRS review for this card
};
schedulingAlgorithm: 'sm2' | 'fsrs'; // Determines which algo rules apply
// Recurring notes settings
isRecurring?: boolean;
recurrenceInterval?: number; // Interval in days for recurring notes
recurrenceEndDate?: number | null; // Optional end date for recurrence (timestamp)
originalSchedule?: ReviewSchedule | null; // Store original schedule for reference
}
// Removed INITIAL_INTERVALS, isInitialPhase, and getInitialInterval.
// This logic will now be handled in ReviewScheduleService using settings.initialScheduleCustomIntervals.
/**
* Represents a user's response for FSRS (1-4 rating)
*/
export enum FsrsRating {
Again = 1,
Hard = 2,
Good = 3,
Easy = 4,
}
/**
* Represents a user's response during review (SM-2 quality rating 0-5)
*/
export enum ReviewResponse {
/**
* Complete blackout (0) - No recognition at all
*/
CompleteBlackout = 0,
/**
* Incorrect response (1) - Wrong answer but upon seeing the correct answer, it felt familiar
*/
IncorrectResponse = 1,
/**
* Incorrect response (2) - Wrong answer but upon seeing the correct answer, it felt very familiar
*/
IncorrectButFamiliar = 2,
/**
* Correct with difficulty (3) - Correct answer but required significant effort to recall
*/
CorrectWithDifficulty = 3,
/**
* Correct with hesitation (4) - Correct answer after some hesitation
*/
CorrectWithHesitation = 4,
/**
* Perfect recall (5) - Correct answer with no hesitation
*/
PerfectRecall = 5
}
/**
* Convert any response to SM-2 quality ratings (0-5)
*
* @param response The review response to convert
* @returns SM-2 quality rating (0-5)
*/
export function toSM2Quality(response: ReviewResponse): number {
// Ensure response is within 0-5 range
if (response as number >= 0 && response as number <= 5) {
return response;
}
// Default fallback
return ReviewResponse.CorrectWithDifficulty;
}
/**
* Review history entry
*/
export interface ReviewHistoryItem {
/**
* Path to the note file
*/
path: string;
/**
* Timestamp of the review
*/
timestamp: number;
/**
* User's response during review
*/
response: ReviewResponse;
/**
* Interval at the time of review
*/
interval: number;
/**
* Ease at the time of review
*/
ease: number;
/**
* Whether this review was explicitly skipped by the user
*/
isSkipped?: boolean;
}