dart_srs 1.0.1 copy "dart_srs: ^1.0.1" to clipboard
dart_srs: ^1.0.1 copied to clipboard

Pluggable spaced repetition engine with FSRS-6 scheduling, study-type adapters, optional review logging, and session support. Storage-agnostic (bring your own CardStateStore).

dart_srs #

Pub Version License: MIT Pub Points

A pluggable spaced repetition (SRS) engine for Dart (no Flutter SDK required). Use it from Flutter apps, servers, or CLI tools. It ships with an FSRS-6-style scheduler, study-type adapters (flashcards, MCQ, typing, true/false), optional review logging, and a study session helper for linear review flows.

The package is storage-agnostic: you implement CardStateStore (SQLite, Hive, REST, etc.) and plug it into SRSEngine.

Repository: github.com/amritmalla/dart_srs

Requirements #

  • Dart SDK ^3.10.7 (see pubspec.yaml)

Installation #

Add dart_srs to your project:

dart pub add dart_srs

This will add a line to your package's pubspec.yaml (and run dart pub get):

dependencies:
  dart_srs: ^1.0.1

Alternatively, you can depend on Git directly:

dependencies:
  dart_srs:
    git:
      url: https://github.com/amritmalla/dart_srs.git
      ref: main

Features #

  • SRSAlgorithm — implement your own scheduler; FSRS6Algorithm is the built-in default with FSRS6Config (21 weights, learning/relearning steps, desired retention, fuzzing, etc.).
  • SRSEngine<T> — coordinates algorithm + StudyTypeAdapter<T> + CardStateStore; maps typed outcomes to SRSRating and persists SRSCardState.
  • StudySession — queue-based session with RequeuingStrategy (default requeues Again and some Hard/Good learning cases).
  • Scheduling preview — human-readable intervals for all four ratings (SchedulingPreview).
  • Optional ReviewLogger — audit trail via ReviewLog (failures in logging are swallowed so reviews still complete).
  • Testing — import package:dart_srs/testing.dart for InMemoryCardStateStore.

Quick start #

Full runnable sample: example/example.dart.

import 'package:dart_srs/dart_srs.dart';
import 'package:dart_srs/testing.dart';

Future<void> main() async {
  final algorithm = FSRS6Algorithm(config: FSRS6Config());
  final store = InMemoryCardStateStore();

  await store.saveCardState(algorithm.getInitialCardState('word_1'));

  final engine = SRSEngine<FlashcardOutcome>(
    algorithm: algorithm,
    adapter: const FlashcardAdapter(),
    store: store,
  );

  final next = await engine.reviewCard(
    'word_1',
    const FlashcardOutcome(rating: SRSRating.good),
  );
  // Use next.dueDate, next.cardPhase, next.stability, etc.
}

Study session #

final session = engine.createSession(['id_a', 'id_b', 'id_c']);
await session.start();

while (session.state == SessionState.active) {
  final card = session.currentCard!;
  // Show card to the user, then:
  await session.submitReview(SRSRating.good);
}

final summary = session.result; // stats, duration, cardsReviewed

Scheduling buttons (preview) #

final preview = await engine.getSchedulingPreview('word_1');
// preview.againInterval, .hardInterval, .goodInterval, .easyInterval (strings)
// preview.againDays, … (numeric days from now)

Architecture #

Piece Role
SRSAlgorithm Given current SRSCardState + SRSRating, returns the next state.
SRSEngine Loads state from store, runs adapter + algorithm, saves state, optional logging.
StudyTypeAdapter<T> Maps your UI outcome type T to SRSRating (Again / Hard / Good / Easy).
CardStateStore Persistence for SRSCardState (due queries, bulk load by id, etc.).
StudySession In-memory queue over a fixed id list; calls algorithm + store per rating.

Ratings align with common SRS UIs: SRSRating.again, hard, good, easy. Card lifecycle phases are CardPhase: newCard, learning, review, relearning.

Built-in adapters and outcomes #

Adapter Outcome type Notes
FlashcardAdapter FlashcardOutcome User picks the rating directly.
MCQAdapter MCQOutcome Maps correctness + response time + option count to a rating.
TypingAdapter TypingOutcome Uses TypingAccuracy (exact / close / wrong).
TrueFalseAdapter TrueFalseOutcome Similar heuristics to MCQ-style timing.

Implement StudyTypeAdapter<MyOutcome> for custom modalities.

Configuration (FSRS-6) #

FSRS6Config validates on construction:

  • weights — exactly 21 doubles (defaults in FSRS6Constants.defaultWeights).
  • desiredRetention — in (0.0, 1.0); default 0.9.
  • learningSteps / relearningSteps — positive minute-based steps (see defaults in FSRS6Constants).
  • maximumInterval, graduatingInterval, easyInterval, enableFuzzing.

Invalid values throw InvalidConfigurationException.

Implementing storage #

Implement CardStateStore with your database or backend. You must support:

  • getCardState / saveCardState / saveCardStates
  • getDueCards(DateTime now) — cards that are not new and dueDate is before now
  • getNewCards(int limit) — cards in CardPhase.newCard
  • getCardsByIds — order should match how you want the session queue built (the session uses the list returned; missing ids are omitted)
  • deleteCardState

See the doc/ folder for split guides (storage, engine vs session, adapters, FSRS-6, testing).

Testing #

import 'package:dart_srs/testing.dart';

final store = InMemoryCardStateStore();
store.seed([/* SRSCardState ... */]);
store.clear();

InMemoryCardStateStore is intended for tests and demos, not production persistence.

Exceptions #

Type Typical cause
CardNotFoundException Engine asked for a missing cardId.
SessionStateException Invalid session transition (e.g. submit after complete).
InvalidConfigurationException Bad FSRS6Config.

Documentation #

  • doc/README.md — index of topic guides (overview, installation, architecture, storage, engine/session, adapters, FSRS-6, testing, exceptions).
  • API reference — run dart doc in this package; HTML is emitted under doc/api/.

Development #

dart pub get
dart analyze
dart test
dart run example/example.dart

References #

  • FSRS family of algorithms (weights and behavior are configured via FSRS6Config; tune weights for your dataset when optimizing retention).
1
likes
160
points
38
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Pluggable spaced repetition engine with FSRS-6 scheduling, study-type adapters, optional review logging, and session support. Storage-agnostic (bring your own CardStateStore).

Homepage
Repository (GitHub)
View/report issues

Topics

#spaced-repetition #srs #fsrs #flashcards #learning

License

MIT (license)

More

Packages that depend on dart_srs