<commit_before>import { StoredJsonProp, storedJsonProp } from 'common/storage';
import { PuzzleData, Puzzle, PuzzleId, PuzzleGame } from './interfaces';

interface Current {
  puzzle: Puzzle;
  game: PuzzleGame;
}

interface StreakData {
  ids: PuzzleId[];
  index: number;
  skip: boolean;
  current: Current;
}

export default class PuzzleStreak {
  data: StreakData;
  fail = false;
  store: StoredJsonProp<StreakData | null>;

  constructor(data: PuzzleData) {
    this.store = storedJsonProp<StreakData | null>(`puzzle.streak.${data.user?.id || 'anon'}`, () => null);
    this.data = this.store() || {
      ids: data.streak!.split(' '),
      index: 0,
      skip: true,
      current: {
        puzzle: data.puzzle,
        game: data.game,
      },
    };
  }

  onComplete = (win: boolean, current?: Current) => {
    if (win) {
      this.data.index++;
      if (current)
        this.data.current = {
          puzzle: current.puzzle,
          game: current.game,
        };
      this.store(this.data);
    } else {
      this.fail = true;
      this.store(null);
    }
  };

  nextId = () => this.data.ids[this.data.index + 1];

  skip = (): void => {
    this.data.skip = false;
    this.store(this.data);
  };
}<commit_msg>unlock streak when overflowing<commit_after>import { StoredJsonProp, storedJsonProp } from 'common/storage';
import { PuzzleData, Puzzle, PuzzleId, PuzzleGame } from './interfaces';

interface Current {
  puzzle: Puzzle;
  game: PuzzleGame;
}

interface StreakData {
  ids: PuzzleId[];
  index: number;
  skip: boolean;
  current: Current;
}

export default class PuzzleStreak {
  data: StreakData;
  fail = false;
  store: StoredJsonProp<StreakData | null>;

  constructor(data: PuzzleData) {
    this.store = storedJsonProp<StreakData | null>(`puzzle.streak.${data.user?.id || 'anon'}`, () => null);
    this.data = this.store() || {
      ids: data.streak!.split(' '),
      index: 0,
      skip: true,
      current: {
        puzzle: data.puzzle,
        game: data.game,
      },
    };
  }

  onComplete = (win: boolean, current?: Current) => {
    if (win) {
      if (this.nextId()) {
        this.data.index++;
        if (current)
          this.data.current = {
            puzzle: current.puzzle,
            game: current.game,
          };
        this.store(this.data);
      } else {
        this.store(null);
        lichess.reload();
      }
    } else {
      this.fail = true;
      this.store(null);
    }
  };

  nextId = () => this.data.ids[this.data.index + 1];

  skip = (): void => {
    this.data.skip = false;
    this.store(this.data);
  };
}
{'fraction_non_alphanumeric': 0.15511298353121408, 'fraction_numerical': 0.0015319800842589046, 'mean_word_length': 2.4278215223097113, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5182122', 'n_tokens_mistral': 915, 'n_tokens_neox': 888, 'n_words': 182}