### Initialize FSRS WASM Module Source: https://github.com/open-spaced-repetition/fsrs-browser/blob/main/index.html Initializes the FSRS WebAssembly module and creates an instance of the FSRS class. It handles potential errors during module loading and provides a callback for when the module is ready. The initialized `fsrs` object is then available for further use. ```javascript import { default as wasm, Fsrs } from "./pkg/fsrs_browser.js"; let fsrs; wasm() .then((module) => { fsrs = new Fsrs(); }) .catch((error) => { console.error("An error occurred while initializing the WASM module:", error); }); ``` -------------------------------- ### Calculate Memory State with FSRS Browser Source: https://github.com/open-spaced-repetition/fsrs-browser/blob/main/index.html Calculates the memory state based on a series of past review ratings and the time elapsed between them. This function requires the FSRS object to be initialized and takes two Uint32Array arguments: `ratings` and `delta_ts`. It outputs an object representing the current memory state. ```javascript document.getElementById("memory-state-btn").addEventListener("click", () => { if (fsrs) { const ratings = new Uint32Array([3, 3, 3]); const delta_ts = new Uint32Array([0, 3, 6]); const result = fsrs.memoryState(ratings, delta_ts); console.log("Memory state:", result); } }); ``` -------------------------------- ### Calculate Next Interval with FSRS Browser Source: https://github.com/open-spaced-repetition/fsrs-browser/blob/main/index.html Predicts the next review interval for an item based on its current stability, the desired retention probability, and the rating given during the last review. This function requires the FSRS object to be initialized and takes `stability`, `desired_retention`, and `rating` as arguments. It returns the calculated next interval in days. ```javascript document.getElementById("next-interval-btn").addEventListener("click", () => { if (fsrs) { const stability = 1.5; // or undefined const desired_retention = 0.9; const rating = 3; const result = fsrs.nextInterval(stability, desired_retention, rating); console.log("Next interval:", result); } }); ``` -------------------------------- ### Initialize FSRS Instance (JavaScript) Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Initializes the WebAssembly module and creates a new FSRS instance. Supports default parameters or custom-defined FSRS parameters. Remember to free memory when the instance is no longer needed. ```javascript import init, { Fsrs } from 'fsrs-browser/fsrs_browser'; // Initialize the WASM module await init(); // Create FSRS instance with default parameters const fsrs = new Fsrs(); // Create FSRS instance with custom parameters const customParams = new Float32Array([ 0.4, 1.8, 5.8, -0.5, -0.5, 0.2, 1.4, 0.0, 0.8, 2.0, 0.2, 0.25, 2.5, 0.0, 0.2, 2.2, 0.0, 0.3, 1.5, 0.0, 1.2 ]); const customFsrs = new Fsrs(customParams); // Remember to free memory when done fsrs.free(); ``` -------------------------------- ### Multi-threaded Training with Web Workers (JavaScript) Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Offloads intensive FSRS parameter optimization training computations to a Web Worker, preventing the main UI thread from freezing. This involves initializing the WebAssembly module and thread pool in the worker, sending review data, performing computations, and posting progress and final results back to the main thread. ```javascript // train-worker.js import init, { Fsrs, Progress, initThreadPool } from 'fsrs-browser/fsrs_browser'; let initOutput = null; self.onmessage = async (event) => { if (initOutput === null) { initOutput = await init(); await initThreadPool(navigator.hardwareConcurrency); } const { cids, eases, ids, types } = event.data; const fsrs = new Fsrs(); const progress = Progress.new(); // Send progress updates to main thread self.postMessage({ tag: 'Start', buffer: initOutput.memory.buffer, pointer: progress.pointer() }); const timeZoneOffset = new Date().getTimezoneOffset() * -1; const parameters = fsrs.computeParametersAnki( timeZoneOffset - (4 * 60), cids, eases, ids, types, progress, true ); self.postMessage({ tag: 'Stop', parameters }); fsrs.free(); }; // main.js import TrainWorker from './train-worker.js?worker'; const worker = new TrainWorker(); worker.addEventListener('message', (event) => { if (event.data.tag === 'Start') { console.log('Training started...'); } else if (event.data.tag === 'Stop') { console.log('Training finished:', event.data.parameters); } }); // Send training data to worker worker.postMessage({ cids: new BigInt64Array([1n, 1n, 2n, 2n]), eases: new Uint8Array([4, 3, 3, 4]), ids: new BigInt64Array([1609459200000n, 1609545600000n, 1609632000000n, 1609718400000n]), types: new Uint8Array([0, 1, 0, 1]) }); ``` -------------------------------- ### Monitor Training Progress with getProgress() Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Enables real-time monitoring of FSRS parameter training progress, allowing for responsive UI updates. This function is used in conjunction with Web Workers to poll the training status periodically. It requires the 'fsrs-browser' library, thread pool initialization, and a message event listener for worker communication. ```javascript import init, { Fsrs, Progress, getProgress, initThreadPool } from 'fsrs-browser/fsrs_browser'; import TrainWorker from './train.ts?worker'; await init(); await initThreadPool(navigator.hardwareConcurrency); const worker = new TrainWorker(); let intervalId; worker.addEventListener('message', (event) => { const msg = event.data; if (msg.tag === 'Start') { // Set up progress polling intervalId = setInterval(() => { const { itemsProcessed, itemsTotal } = getProgress(msg.buffer, msg.pointer); console.log(`Progress: ${itemsProcessed}/${itemsTotal}`); const percentage = (itemsProcessed / itemsTotal * 100).toFixed(1); document.getElementById('progress').textContent = `${percentage}%`; // Update progress bar document.getElementById('progress-bar').style.width = `${percentage}%`; }, 100); // Poll every 100ms } else if (msg.tag === 'Stop') { clearInterval(intervalId); console.log('Training complete! Parameters:', msg.parameters); document.getElementById('progress').textContent = '100%'; document.getElementById('parameters').textContent = msg.parameters.toString(); } }); // Start training with Anki database file const response = await fetch('/collection.anki21'); const data = await response.arrayBuffer(); worker.postMessage(data, [data]); ``` -------------------------------- ### Train FSRS Parameters from Anki Database using JavaScript Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Loads review history from Anki SQLite database files and trains optimal parameters using Web Workers. It requires the sql.js and fsrs-browser libraries. The function takes an ArrayBuffer of the SQLite file and returns the trained parameters. ```javascript import initSqlJs, { Database } from 'sql.js'; import init, { Fsrs, Progress, initThreadPool } from 'fsrs-browser/fsrs_browser'; import sqliteWasmUrl from './sql-wasm.wasm?url'; // Initialize SQL.js const sqlJs = await initSqlJs({ locateFile: () => sqliteWasmUrl }); async function trainFromAnkiDb(arrayBuffer) { await init(); await initThreadPool(navigator.hardwareConcurrency); const db = new sqlJs.Database(new Uint8Array(arrayBuffer)); // Query Anki review logs const query = ` SELECT cid, ease, id, type FROM revlog WHERE id < ${Date.now()} AND cid < ${Date.now()} AND cid IN (SELECT id FROM cards WHERE queue != 0) AND (type <> 4 AND ease <> 0) AND (type <> 3 OR factor <> 0) ORDER BY cid `; const stmt = db.prepare(query); const cids = []; const eases = []; const ids = []; const types = []; while (stmt.step()) { const row = stmt.getAsObject(); cids.push(BigInt(row.cid)); eases.push(row.ease); ids.push(BigInt(row.id)); types.push(row.type); } stmt.free(); db.close(); // Train parameters const fsrs = new Fsrs(); const progress = Progress.new(); const timeZoneOffset = new Date().getTimezoneOffset() * -1; const ankiDayStart = 4 * 60; // 4 AM const parameters = fsrs.computeParametersAnki( timeZoneOffset - ankiDayStart, new BigInt64Array(cids), new Uint8Array(eases), new BigInt64Array(ids), new Uint8Array(types), progress, true ); console.log(`Trained on ${cids.length} reviews`); console.log('Parameters:', parameters); fsrs.free(); return parameters; } // Usage const fileInput = document.getElementById('file-input'); fileInput.addEventListener('change', async (event) => { const file = event.target.files[0]; const buffer = await file.arrayBuffer(); const params = await trainFromAnkiDb(buffer); console.log('Training complete:', params); }); ``` -------------------------------- ### Train FSRS Parameters from CSV using JavaScript Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Processes CSV-formatted review logs for parameter training using the PapaParse library for CSV parsing and fsrs-browser for FSRS computations. It supports the standard FSRS CSV format and streams the data for efficient processing. The function returns the trained parameters. ```javascript import Papa from 'papaparse'; import init, { Fsrs, Progress } from 'fsrs-browser/fsrs_browser'; async function trainFromCsv(csvFile) { await init(); const cids = []; const eases = []; const ids = []; const types = []; return new Promise((resolve) => { Papa.parse(csvFile, { header: true, delimiter: ',', step: function({ data }) { // CSV columns: review_time, card_id, review_rating, review_duration, review_state if (data.card_id === undefined) return; cids.push(BigInt(data.card_id)); ids.push(BigInt(data.review_time)); eases.push(Number(data.review_rating)); // 1-4 // Convert review_state to RevlogReviewKind // 0,1 -> Learning (0), 2 -> Review (1), 3 -> Relearning (2) const state = Number(data.review_state); types.push(state <= 1 ? 0 : state === 2 ? 1 : 2); }, complete: function() { const fsrs = new Fsrs(); const progress = Progress.new(); const timeZoneOffset = new Date().getTimezoneOffset() * -1; const parameters = fsrs.computeParametersAnki( timeZoneOffset - (4 * 60), new BigInt64Array(cids), new Uint8Array(eases), new BigInt64Array(ids), new Uint8Array(types), progress, true ); console.log(`Processed ${cids.length} reviews from CSV`); fsrs.free(); resolve(parameters); } }); }); } // Usage const fileInput = document.getElementById('csv-input'); fileInput.addEventListener('change', async (event) => { const file = event.target.files[0]; const parameters = await trainFromCsv(file); console.log('Trained parameters:', parameters); }); ``` -------------------------------- ### Compute FSRS Parameters from Review History Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Trains and optimizes FSRS parameters using review history data. It accepts arrays of ratings, elapsed times, and the number of reviews per card. The `enable_short_term` flag can be set to true to include early review data. Requires the 'fsrs-browser' library and returns an optimized parameter array. ```javascript import init, { Fsrs, Progress } from 'fsrs-browser/fsrs_browser'; await init(); const fsrs = new Fsrs(); // Serialize multiple cards' review histories const ratings = new Uint32Array([ 4, 3, 3, // Card 1: Easy, Good, Good 3, 2, 3, 4, // Card 2: Good, Hard, Good, Easy 1, 3 // Card 3: Again, Good ]); const delta_ts = new Uint32Array([ 0, 5, 12, // Card 1 intervals in days 0, 3, 7, 18, // Card 2 intervals 0, 1 // Card 3 intervals ]); const lengths = new Uint32Array([3, 4, 2]); // Number of reviews per card // Create progress tracker for UI updates const progress = Progress.new(); // Train parameters (enable_short_term: true includes early review data) const parameters = fsrs.computeParameters( ratings, delta_ts, lengths, progress, true // enable_short_term ); console.log('Optimized parameters:', parameters); // Returns Float32Array with 21 optimized parameter values progress.free(); // Rust handles this automatically fsrs.free(); ``` -------------------------------- ### Compute Next States with FSRS Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Calculates the next memory states and intervals for a given review based on current stability, difficulty, desired retention, and days elapsed. It returns the computed states for 'Again', 'Hard', 'Good', and 'Easy' responses. Requires the 'fsrs-browser' library to be initialized. ```javascript import init, { Fsrs } from 'fsrs-browser/fsrs_browser'; await init(); const fsrs = new Fsrs(); const stability = 10.5; const difficulty = 6.2; const desired_retention = 0.9; const days_elapsed = 7; const states = fsrs.nextStates(stability, difficulty, desired_retention, days_elapsed); console.log('Again:', states.again); // { memory: { stability: 2.14, difficulty: 7.45 }, interval: 1.83 } console.log('Hard:', states.hard); // { memory: { stability: 12.67, difficulty: 6.78 }, interval: 16.21 } console.log('Good:', states.good); // { memory: { stability: 23.45, difficulty: 6.20 }, interval: 29.87 } console.log('Easy:', states.easy); // { memory: { stability: 45.32, difficulty: 5.82 }, interval: 58.43 } fsrs.free(); ``` -------------------------------- ### Compute FSRS Parameters from Anki Database Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Trains FSRS parameters directly from Anki database review logs, automatically handling Anki-specific formats and conversions. This function requires initialization of the thread pool for parallel processing and accepts Anki review data along with a progress tracker. It returns the trained parameters. ```javascript import init, { Fsrs, Progress, initThreadPool } from 'fsrs-browser/fsrs_browser'; await init(); await initThreadPool(navigator.hardwareConcurrency); // Enable parallel processing const fsrs = new Fsrs(); // Anki review log data from database query const minute_offset = new Date().getTimezoneOffset() * -1 - (4 * 60); const cids = new BigInt64Array([1n, 1n, 2n, 2n, 2n]); // Card IDs const eases = new Uint8Array([1, 3, 4, 2, 3]); // Button pressed const ids = new BigInt64Array([1609459200000n, 1609545600000n, 1609459200000n, 1609632000000n, 1609718400000n]); const types = new Uint8Array([0, 1, 0, 1, 1]); // Review types const progress = Progress.new(); // Train with progress tracking const parameters = fsrs.computeParametersAnki( minute_offset, cids, eases, ids, types, progress, true // enable_short_term ); console.log('Trained parameters:', parameters); console.log('Total cards processed:', [...new Set(cids)].length); // Progress is automatically freed by Rust fsrs.free(); ``` -------------------------------- ### Calculate Memory State from Review History (JavaScript) Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Calculates the current memory state (stability and difficulty) for a card using its review history. Inputs include an array of past ratings and the time deltas in days between those reviews. Returns an array containing stability and difficulty. ```javascript import init, { Fsrs } from 'fsrs-browser/fsrs_browser'; await init(); const fsrs = new Fsrs(); // Review history: ratings and time deltas in days const ratings = new Uint32Array([3, 3, 3]); // 1=Again, 2=Hard, 3=Good, 4=Easy const delta_ts = new Uint32Array([0, 3, 6]); // Days between reviews // Returns [stability, difficulty] const result = fsrs.memoryState(ratings, delta_ts); console.log(`Stability: ${result[0]}, Difficulty: ${result[1]}`); // Expected output: Stability: 18.41, Difficulty: 5.83 fsrs.free(); ``` -------------------------------- ### Calculate Memory State from Anki Data (JavaScript) Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Calculates memory state using Anki review log data. This function handles Anki-specific formats, including timezone conversions. It requires card IDs, ease values, review timestamps, and review types. Returns stability and difficulty, or null if multiple cards are detected. ```javascript import init, { Fsrs } from 'fsrs-browser/fsrs_browser'; await init(); const fsrs = new Fsrs(); // Anki review log data for a single card const minute_offset = new Date().getTimezoneOffset() * -1 - (4 * 60); // User timezone - Anki's "next day starts at" const cids = new BigInt64Array([1234567890n, 1234567890n]); // Card IDs (must be same card) const eases = new Uint8Array([1, 3]); // Button pressed (1-4) const ids = new BigInt64Array([1609459200000n, 1609545600000n]); // Review timestamps (milliseconds) const types = new Uint8Array([0, 1]); // 0=Learning, 1=Review, 2=Relearning const result = fsrs.memoryStateAnki(minute_offset, cids, eases, ids, types); if (result) { console.log(`Stability: ${result[0]}, Difficulty: ${result[1]}`); } else { console.log('Invalid input: multiple cards detected'); } fsrs.free(); ``` -------------------------------- ### Predict Next Review Interval (JavaScript) Source: https://context7.com/open-spaced-repetition/fsrs-browser/llms.txt Calculates the optimal number of days until the next review. It takes the current card stability, the desired retention rate, and the rating of the last review as input. Can be used for new cards (undefined stability) or existing cards. ```javascript import init, { Fsrs } from 'fsrs-browser/fsrs_browser'; await init(); const fsrs = new Fsrs(); // For a new card (no stability yet) const interval1 = fsrs.nextInterval(undefined, 0.9, 3); // 90% retention, Good rating console.log(`Next interval: ${interval1} days`); // Expected output: Next interval: 3.46 days // For an existing card with known stability const stability = 15.2; const desired_retention = 0.9; const rating = 3; // Good const interval2 = fsrs.nextInterval(stability, desired_retention, rating); console.log(`Next interval: ${interval2} days`); // Expected output: Next interval: 34.87 days fsrs.free(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.