### Install and Build Cubedex Source: https://github.com/poliva/cubedex/blob/main/README.md Commands to install project dependencies and build the project for preview. Ensure you have Node.js and npm installed. ```bash $ npm install $ npm run build && npm run preview ``` -------------------------------- ### Use Scramble State Hook for Guided Cube Setup Source: https://context7.com/poliva/cubedex/llms.txt This hook computes the optimal scramble sequence to set up a physical smartcube for the next algorithm. It tracks physical cube move progress against the scramble sequence and resolves when the cube matches the target state. Import `useScrambleState` and use its methods to manage the scramble process. ```tsx import { useScrambleState } from './src/hooks/useScrambleState'; import type { CaseCardData } from './src/lib/case-cards'; function ScrambleExample({ currentCase, smartcubePattern }: any) { const scramble = useScrambleState(); // scramble.scrambleMode: boolean // scramble.remainingMoves: string[] — moves left to complete the scramble // scramble.targetAlgorithm: string — the alg being scrambled to async function startScramble() { const started = await scramble.startScrambleTo( currentCase.algorithm, currentCase, smartcubePattern, true, // randomizeAUF ); if (started) { console.log('Scramble started, target:', scramble.targetAlgorithm); } } // Called for each smartcube MOVE event while scramble.scrambleMode is true: async function onMove(move: string) { const completed = await scramble.advanceScramble(move, smartcubePattern); if (completed) { console.log('Cube is now in starting position — begin solve!'); } } return (
{scramble.scrambleMode && (
Remaining: {scramble.remainingMoves.join(' ')}
)}
); } ``` -------------------------------- ### `prepareTrainingAlgorithm(inputMoves, category, randomizeAUF)` Source: https://context7.com/poliva/cubedex/llms.txt Prepares an algorithm for training purposes. It can optionally add a random AUF (Adjust U Face) and simplifies the move sequence. ```APIDOC ## `prepareTrainingAlgorithm(inputMoves, category, randomizeAUF)` — Prepare algorithm for display Optionally adds a random AUF (Adjust U Face) before/after the algorithm for PLL/ZBLL training, or verifies OLL symmetry to decide whether to add pre-AUF, then returns the final display algorithm and the underlying move array. ### Parameters #### Path Parameters - **inputMoves** (string[]) - Required - The initial sequence of moves. - **category** (string) - Required - The training category (e.g., 'PLL', 'OLL'). - **randomizeAUF** (boolean) - Required - Whether to randomize the AUF. ### Request Example ```ts import { prepareTrainingAlgorithm } from './src/lib/auf'; const prepared = await prepareTrainingAlgorithm( ["R", "U", "R'", "U'"], // input moves 'PLL', true, // randomizeAUF: true ); // prepared.displayAlgorithm: e.g. "U R U R' U' U'" (with random pre- and post-AUF) // prepared.moves: ["U", "R", "U", "R'", "U2"] (simplified with cancellations) // prepared.originalMoves: ["R", "U", "R'", "U'"] (unchanged input) // Without AUF: const exact = await prepareTrainingAlgorithm(["R", "U2", "R'"], 'OLL', false); // exact.displayAlgorithm: "R U2 R'" // exact.moves: ["R", "U2", "R'"] ``` ### Response #### Success Response - **displayAlgorithm** (string) - The algorithm formatted for display, potentially with AUF. - **moves** (string[]) - The simplified array of moves. - **originalMoves** (string[]) - The original input moves. ``` -------------------------------- ### Initialize Algorithm Library and Manage Case Selection with useCaseLibrary Source: https://context7.com/poliva/cubedex/llms.txt Initializes the algorithm library from IndexedDB and manages selection state. Provides callbacks to toggle subsets, select/deselect cases, and cycle learned status. ```tsx import { useCaseLibrary } from './src/hooks/useCaseLibrary'; function LibraryComponent() { const lib = useCaseLibrary({ autoUpdateLearningState: true, smartReviewScheduling: true, }); if (!lib.isReady) return
Loading…
; if (lib.initError) return
Error: {lib.initError}
; // lib.categories: ['OLL', 'PLL', 'CMLL', ...] // lib.selectedCategory: 'OLL' // lib.subsets: ['All Cases'] // lib.caseCards: CaseCardData[] // lib.selectedCaseIds: string[] return (
{lib.categories.map(cat => ( ))} {lib.subsets.map(subset => ( ))} {lib.caseCards.map(card => (
{card.name}: {card.algorithm} Best: {card.bestTime ? `${card.bestTime}ms` : '-'} Learned: {card.learned}
))}
); } ``` -------------------------------- ### useCaseLibrary Source: https://context7.com/poliva/cubedex/llms.txt Initializes the algorithm library from IndexedDB, exposes the full category/subset/case tree, and manages selection state. Provides callbacks to toggle subsets, select/deselect individual cases, cycle learned status, and reload after import. ```APIDOC ## `useCaseLibrary(options)` ### Description Initializes the algorithm library from IndexedDB, exposes the full category/subset/case tree, and manages selection state (all cases, by learned status, or manual). Provides callbacks to toggle subsets, select/deselect individual cases, cycle learned status, and reload after import. ### Parameters * `options` (object) - Configuration options for the hook. * `autoUpdateLearningState` (boolean) - Whether to automatically update learning state. * `smartReviewScheduling` (boolean) - Whether to enable smart review scheduling. ### Returns An object containing the following properties: * `isReady` (boolean) - Indicates if the library is ready. * `initError` (string | null) - An error message if initialization failed. * `categories` (string[]) - An array of available categories. * `selectedCategory` (string) - The currently selected category. * `subsets` (string[]) - An array of available subsets. * `caseCards` (CaseCardData[]) - An array of case card data. * `selectedCaseIds` (string[]) - An array of selected case IDs. * `setSelectedCategory` (function) - Function to set the selected category. * `toggleSubset` (function) - Function to toggle a subset's selection state. * `selectVisibleCases` (function) - Function to select all visible cases. * `clearSelectedCases` (function) - Function to clear all selected cases. * `cycleCaseLearnedState` (function) - Function to cycle the learned state of a case. ``` -------------------------------- ### exportAlgorithms and exportBackup Source: https://context7.com/poliva/cubedex/llms.txt Provides functions to download algorithm data. `exportAlgorithms` downloads only the algorithm library, while `exportBackup` includes the library, stats, and SRS records in a versioned backup format. ```APIDOC ## exportAlgorithms() / exportBackup() ### Description `exportAlgorithms()` downloads a JSON file containing only the algorithm library. `exportBackup()` includes both the library and all stats/SRS records in a versioned backup format. ### Method `exportAlgorithms` or `exportBackup` ### Parameters None ### Request Example ```ts import { exportAlgorithms, exportBackup } from './src/lib/storage'; // Download just the algorithm library await exportAlgorithms(); // Download a full backup await exportBackup(); ``` ### Response #### Success Response (void) Initiates a file download containing the exported data. #### Response Example (for exportBackup) ```json { "backupFormatVersion": 2, "exportedAt": "2024-06-01T12:00:00.000Z", "algorithms": { "OLL": [...], "PLL": [...] }, "stats": [{ "scopeId": "case:OLL:All%20Cases:R-U-Rp-U-R-U2-Rp", "attemptHistory": [...], "srs": {...}, ... }] } ``` ``` -------------------------------- ### Prepare Algorithm for Training Display Source: https://context7.com/poliva/cubedex/llms.txt Prepares an algorithm for training by optionally adding random AUF (Adjust U Face) or verifying OLL symmetry. Returns the display algorithm and the underlying move array. ```ts import { prepareTrainingAlgorithm } from './src/lib/auf'; const prepared = await prepareTrainingAlgorithm( ["R", "U", "R'", "U'"], // input moves 'PLL', true, // randomizeAUF: true ); // prepared.displayAlgorithm: e.g. "U R U R' U' U'" (with random pre- and post-AUF) // prepared.moves: ["U", "R", "U", "R'", "U2"] (simplified with cancellations) // prepared.originalMoves: ["R", "U", "R'", "U'"] (unchanged input) // Without AUF: const exact = await prepareTrainingAlgorithm(["R", "U2", "R'"], 'OLL', false); // exact.displayAlgorithm: "R U2 R'" // exact.moves: ["R", "U2", "R'"] ``` -------------------------------- ### Initialize Cubedex Storage Source: https://context7.com/poliva/cubedex/llms.txt Initializes the IndexedDB database, migrates legacy data, and loads algorithms and stats into memory. Must be awaited before other storage operations. ```typescript import defaultAlgs from './src/data/defaultAlgs.json'; import { initializeDefaultAlgorithms, getSavedAlgorithms } from './src/lib/storage'; // In main.tsx / React root async function bootstrap() { const result = await initializeDefaultAlgorithms(defaultAlgs as SavedAlgorithms); if (result.alertMessage) { // e.g. "Algorithms have been migrated to a new format…" console.warn(result.alertMessage); } // result.migratedSavedAlgorithmsV1 === true when old v1 categories were found const algorithms = getSavedAlgorithms(); // { OLL: [{ subset: 'All Cases', algorithms: [{ name: 'OLL-1', algorithm: 'R U2 R2 F R F U2 R F2' }, ...] }], PLL: [...], ... } console.log(Object.keys(algorithms)); // ['OLL', 'PLL', 'CMLL', ...] } ``` -------------------------------- ### useAppSettings Source: https://context7.com/poliva/cubedex/llms.txt Reads and writes all user preferences from `localStorage` (theme, visualization, gyroscope, countdown mode, etc.) and exposes typed setters for each option. ```APIDOC ## `useAppSettings()` ### Description Reads and writes all user preferences from `localStorage` (theme, visualization, gyroscope, countdown mode, always-scramble-to, flashing indicator, full stickering, cube size, etc.) and exposes typed setters for each option. ### Returns An object containing the following properties: * `theme` (string) - The current theme ('dark', 'light', 'system'). * `countdownMode` (boolean) - Whether countdown mode is enabled. * `randomizeAUF` (boolean) - Whether to randomize AUF (in practiceToggles). * `alwaysScrambleTo` (boolean) - Whether to always scramble to a specific state. * `gyroscope` (boolean) - Whether gyroscope is enabled. * `fullStickering` (boolean) - Whether full stickering is enabled. * `flashingIndicatorEnabled` (boolean) - Whether the flashing indicator is enabled. * `autoUpdateLearningState` (boolean) - Whether to automatically update learning state. * `cubeSizePx` (number) - The size of the cube in pixels. * `setCountdownMode` (function) - Function to set the countdown mode. * `setAlwaysScrambleTo` (function) - Function to set the always scramble to option. * `setCubeSizePx` (function) - Function to set the cube size in pixels. ``` -------------------------------- ### Convert Smartcube State to Player Algorithm Source: https://context7.com/poliva/cubedex/llms.txt Converts the current Bluetooth cube state (`KPattern`) into the shortest algorithm to reach that state from solved. Useful for displaying scrambles on screen. ```ts import { patternToPlayerAlg } from './src/lib/scramble'; import { solvedPattern } from './src/lib/cube-utils'; const pattern = await solvedPattern(); const playerAlg = patternToPlayerAlg(pattern); // '' — already solved // After applying some moves via smartcube events: // const movedPattern = pattern.applyAlg("R U R' U'"); // patternToPlayerAlg(movedPattern) → "R U R' U'" (the inverse of the solve path) ``` -------------------------------- ### getStickeringForCategory(category, fullStickeringEnabled) Source: https://context7.com/poliva/cubedex/llms.txt Maps a given algorithm category to its corresponding cube stickering scheme string. Falls back to 'full' for unrecognized categories or when full stickering is explicitly enabled. ```APIDOC ## getStickeringForCategory(category, fullStickeringEnabled) ### Description Maps a category to its cubing.js stickering scheme string (e.g., `'OLL'`, `'PLL'`, `'F2L'`) for the 3-D cube visualization. Falls back to `'full'` for unrecognized categories or when full stickering is forced. ### Parameters #### Path Parameters - **category** (string) - Required - The algorithm category (e.g., 'OLL', 'PLL'). - **fullStickeringEnabled** (boolean) - Required - A flag to force full stickering. ### Request Example ```ts import { getStickeringForCategory } from './src/lib/stickering'; getStickeringForCategory('OLL', false) // 'OLL' getStickeringForCategory('PLL', false) // 'PLL' getStickeringForCategory('CMLL', false) // 'CMLL' getStickeringForCategory('My OLL Set', false) // 'OLL' (word match) getStickeringForCategory('Unknown', false) // 'full' (fallback) getStickeringForCategory('OLL', true) // 'full' (forced full stickering) ``` ``` -------------------------------- ### `patternToPlayerAlg(pattern)` Source: https://context7.com/poliva/cubedex/llms.txt Converts a smartcube state (`KPattern`) into the shortest algorithm to reach that state from a solved cube. This is useful for displaying scrambles on a 3D cube. ```APIDOC ## `patternToPlayerAlg(pattern)` — Convert smartcube state to displayable algorithm Takes a `KPattern` (the current Bluetooth cube state) and returns the shortest algorithm that, when executed from solved, reaches that state — used to set up the on-screen 3-D cube as a "scramble" display. ### Parameters #### Path Parameters - **pattern** (KPattern) - Required - The current Bluetooth cube state. ### Request Example ```ts import { patternToPlayerAlg } from './src/lib/scramble'; import { solvedPattern } from './src/lib/cube-utils'; const pattern = await solvedPattern(); const playerAlg = patternToPlayerAlg(pattern); // '' — already solved // After applying some moves via smartcube events: // const movedPattern = pattern.applyAlg("R U R' U'"); // patternToPlayerAlg(movedPattern) → "R U R' U'" (the inverse of the solve path) ``` ### Response #### Success Response - **playerAlg** (string) - The shortest algorithm to reach the given pattern from solved. ``` -------------------------------- ### getCaseCards(savedAlgorithms, category, checkedSubsets, options) Source: https://context7.com/poliva/cubedex/llms.txt Builds practice card data by compiling algorithm information for a given category and subset selection. It enriches each algorithm with its best time, ao5, learned status, SRS due date, and urgency score. ```APIDOC ## getCaseCards(savedAlgorithms, category, checkedSubsets, options) ### Description Builds practice card data for a given category and subset selection. Enriches each algorithm with its best time, ao5, learned status, SRS due date, and urgency score. This is the primary data structure consumed by the training state and case grid UI. ### Parameters #### Path Parameters - **savedAlgorithms** (Array) - Required - A list of saved algorithms. - **category** (string) - Required - The category of algorithms to process (e.g., 'OLL', 'PLL'). - **checkedSubsets** (Array) - Required - A list of subsets to include. - **options** (Object) - Optional - Configuration options. - **autoUpdateLearningState** (boolean) - Optional - Whether to automatically update the learning state. ### Request Example ```ts import { getCaseCards } from './src/lib/case-cards'; import { getSavedAlgorithms } from './src/lib/storage'; const saved = getSavedAlgorithms(); const cards = getCaseCards(saved, 'OLL', ['All Cases'], { autoUpdateLearningState: true }); // cards[0] shape: // { // id: "case:OLL:All%20Cases:R-U2-R2-F-R-F-U2-R-F2", // name: "OLL-1", // algorithm: "R U2 R2 F R F U2 R F2", // subset: "All Cases", // category: "OLL", // bestTime: 1230, // ms, or null // ao5: 1450, // ms, or null // learned: 2, // 0 | 1 | 2 // manualLearned: 1, // reviewCount: 24, // smartReviewDueAt: 1717200000000, // smartReviewDue: true, // smartReviewUrgency: -3600000, // negative = overdue // } ``` ``` -------------------------------- ### Import Algorithms and Backups from JSON Source: https://context7.com/poliva/cubedex/llms.txt Use `importAlgorithmsFromJson` to restore only algorithms or `importBackupFromJson` for a full library and stats restore. Both functions parse JSON strings and persist data to IndexedDB. `importBackupFromJson` may throw an error for unsupported backup format versions. ```typescript import { importAlgorithmsFromJson, importBackupFromJson } from './src/lib/storage'; // Restore just algorithms from a JSON string const algJson = JSON.stringify({ OLL: [{ subset: 'All Cases', algorithms: [{ name: 'OLL-1', algorithm: 'R U2 R2 F R F U2 R F2' }] }] }); const newLib = await importAlgorithmsFromJson(algJson); // newLib === getSavedAlgorithms() — the updated library snapshot // Restore full backup (replaces all stats too) const backupJson = await fetch('/path/to/cubedex_backup.json').then(r => r.text()); const { savedAlgorithms, stats } = await importBackupFromJson(backupJson); // savedAlgorithms: SavedAlgorithms // stats: ScopedStatsRecord[] // Throws 'Unsupported backup format version' if the format version is unrecognized ``` -------------------------------- ### initializeDefaultAlgorithms Source: https://context7.com/poliva/cubedex/llms.txt Initializes the persistent storage (IndexedDB) for Cubedex. This function must be awaited before any other storage operations can be performed. It handles database creation, migration of legacy data, loading algorithms and stats, and pruning orphan entries. ```APIDOC ## initializeDefaultAlgorithms(defaultAlgs) ### Description Opens (or creates) the Cubedex IndexedDB database, migrates legacy `localStorage` data if needed, loads the saved algorithm library and all stats records into an in-memory cache, and prunes orphan stats entries. Must be awaited before any read/write storage calls are made. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **defaultAlgs** (SavedAlgorithms) - Required - The default set of algorithms to initialize the storage with. ### Request Example ```ts import defaultAlgs from './src/data/defaultAlgs.json'; import { initializeDefaultAlgorithms } from './src/lib/storage'; async function bootstrap() { const result = await initializeDefaultAlgorithms(defaultAlgs as SavedAlgorithms); if (result.alertMessage) { console.warn(result.alertMessage); } } ``` ### Response #### Success Response (void) Returns an object with potential `alertMessage` and `migratedSavedAlgorithmsV1` properties. #### Response Example ```json { "alertMessage": "Algorithms have been migrated to a new format…", "migratedSavedAlgorithmsV1": true } ``` ``` -------------------------------- ### Map Category to Cube Stickering Scheme Source: https://context7.com/poliva/cubedex/llms.txt Returns the appropriate stickering scheme string (e.g., 'OLL', 'PLL') for a given algorithm category to be used in 3-D cube visualizations. Falls back to 'full' for unrecognized categories or when full stickering is explicitly enabled. ```typescript import { getStickeringForCategory } from './src/lib/stickering'; getStickeringForCategory('OLL', false) // 'OLL' getStickeringForCategory('PLL', false) // 'PLL' getStickeringForCategory('CMLL', false) // 'CMLL' getStickeringForCategory('My OLL Set', false) // 'OLL' (word match) getStickeringForCategory('Unknown', false) // 'full' (fallback) getStickeringForCategory('OLL', true) // 'full' (forced full stickering) ``` -------------------------------- ### useSmartcubeConnection Source: https://context7.com/poliva/cubedex/llms.txt Handles the full Web Bluetooth connection lifecycle for Bluetooth Rubik's cubes: connecting/disconnecting, receiving events, detecting slice moves, correcting for cube orientation, and streaming move updates. ```APIDOC ## `useSmartcubeConnection(gyroscopeEnabled)` ### Description Handles the full Web Bluetooth connection lifecycle for Bluetooth Rubik's cubes: connecting/disconnecting, receiving MOVE/FACELETS/BATTERY/GYRO/HARDWARE events, detecting slice moves (M, S, E) by pairing consecutive face moves with a 100 ms buffer, correcting for cube orientation, and streaming a `lastProcessedMove` state update for each validated move. ### Parameters * `gyroscopeEnabled` (boolean) - Whether to enable gyroscope data. ### Returns An object containing the following properties: * `connected` (boolean) - Indicates if the cube is connected. * `connecting` (boolean) - Indicates if the cube is currently connecting. * `connectLabel` (string) - Label for the connect/disconnect button. * `battery` (object) - Battery information. * `level` (number) - Battery level (0-100). * `color` (string) - Battery indicator color. * `currentPattern` (KPattern | null) - The live state of the cube. * `lastProcessedMove` (object | null) - The last processed move. * `key` (string) - Move key. * `move` (string) - Visual move representation. * `rawMoves` (string[]) - Raw moves detected. * `currentPattern` (KPattern) - Cube state after the move. * `isBugged` (boolean) - Whether the move detection was buggy. * `cubeQuaternion` (object | null) - The cube's orientation as a quaternion. * `x` (number) * `y` (number) * `z` (number) * `w` (number) * `info` (object) - Device information. * `deviceName` (string) * `deviceMAC` (string) * `deviceProtocol` (string) * `connectOrDisconnect` (function) - Function to initiate connection or disconnection. * `resetOrientation` (function) - Function to reset the cube's orientation. * `resetGyro` (function) - Function to reset the gyroscope. * `resetState` (function) - Function to reset the cube's internal state. ``` -------------------------------- ### importAlgorithmsFromJson / importBackupFromJson Source: https://context7.com/poliva/cubedex/llms.txt Restores data by parsing and loading either an algorithm JSON or a full backup JSON. This operation replaces the current library and optionally stats, then persists the changes to IndexedDB. ```APIDOC ## `importAlgorithmsFromJson(json)` / `importBackupFromJson(json)` — Restore data Parses and loads an algorithm JSON or a full backup JSON, replacing the current library (and optionally stats), then persists to IndexedDB. ```ts import { importAlgorithmsFromJson, importBackupFromJson } from './src/lib/storage'; // Restore just algorithms from a JSON string const algJson = JSON.stringify({ OLL: [{ subset: 'All Cases', algorithms: [{ name: 'OLL-1', algorithm: 'R U2 R2 F R F U2 R F2' }] }] }); const newLib = await importAlgorithmsFromJson(algJson); // newLib === getSavedAlgorithms() — the updated library snapshot // Restore full backup (replaces all stats too) const backupJson = await fetch('/path/to/cubedex_backup.json').then(r => r.text()); const { savedAlgorithms, stats } = await importBackupFromJson(backupJson); // savedAlgorithms: SavedAlgorithms // stats: ScopedStatsRecord[] // Throws 'Unsupported backup format version' if the format version is unrecognized ``` ``` -------------------------------- ### Export Algorithm Data Source: https://context7.com/poliva/cubedex/llms.txt Provides functions to download algorithm data. `exportAlgorithms` downloads only the algorithm library, while `exportBackup` includes the library, stats, and SRS records in a versioned format. ```typescript import { exportAlgorithms, exportBackup } from './src/lib/storage'; // Download just the algorithm library as cubedex_algorithms.json await exportAlgorithms(); // Download a full backup (algorithms + all stats) as cubedex_backup.json // Backup JSON shape: // { // backupFormatVersion: 2, // exportedAt: "2024-06-01T12:00:00.000Z", // algorithms: { OLL: [...], PLL: [...] }, // stats: [{ scopeId: "case:OLL:All%20Cases:R-U-Rp-U-R-U2-Rp", attemptHistory: [...], srs: {...}, ... }] // } await exportBackup(); ``` -------------------------------- ### `patternToFacelets(pattern)` / `faceletsToPattern(facelets)` Source: https://context7.com/poliva/cubedex/llms.txt Utility functions to convert between `KPattern` objects and their string representation (facelet strings). ```APIDOC ## `patternToFacelets(pattern)` / `faceletsToPattern(facelets)` — Convert between KPattern and facelet strings `patternToFacelets` converts a `KPattern` to the 54-character URFDLB facelet string. `faceletsToPattern` does the reverse, parsing the facelet string into a `KPattern` by mapping sticker colors to piece positions and orientations. ### Parameters #### `patternToFacelets` - **pattern** (KPattern) - Required - The cube state to convert. #### `faceletsToPattern` - **facelets** (string) - Required - The 54-character facelet string. ### Request Example ```ts import { patternToFacelets, faceletsToPattern, solvedPattern } from './src/lib/cube-utils'; // Solved state facelet string const solved = await solvedPattern(); const facelets = patternToFacelets(solved); // 'UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB' // Round-trip const roundTripped = await faceletsToPattern(facelets); roundTripped.isIdentical(solved); // true // After applying a move const moved = solved.applyAlg("R"); patternToFacelets(moved); // 'UUFUUFUUFRRRRRRRRRFFFDDDFFFUUUDDDDDDLLLLLLLLLBBBRRRBBBRRRBBBBBB...' (approximately) ``` ### Response #### `patternToFacelets` Success Response - **facelets** (string) - The 54-character facelet string. #### `faceletsToPattern` Success Response - **pattern** (KPattern) - The `KPattern` object representing the facelet string. ``` -------------------------------- ### Handle Bluetooth Smartcube Connection with useSmartcubeConnection Source: https://context7.com/poliva/cubedex/llms.txt Manages the Web Bluetooth connection lifecycle for smartcubes, including connection, event handling, and cube orientation correction. Streams `lastProcessedMove` for validated moves. ```tsx import { useSmartcubeConnection } from './src/hooks/useSmartcubeConnection'; function SmartcubePanel() { const cube = useSmartcubeConnection(true /* gyroscopeEnabled */); // cube.connected: boolean // cube.connecting: boolean // cube.connectLabel: 'Connect' | 'Disconnect' | 'Scanning…' // cube.battery: { level: 85, color: 'green' } // cube.currentPattern: KPattern | null — live cube state // cube.lastProcessedMove: { key, move, visualMove, rawMoves, currentPattern, isBugged } | null // cube.cubeQuaternion: { x, y, z, w } | null — gyro orientation return (
{cube.connected && ( <>
Battery: {cube.battery.level}%
Device: {cube.info.deviceName} ({cube.info.deviceMAC})
Protocol: {cube.info.deviceProtocol}
Last move: {cube.lastProcessedMove?.visualMove}
)}
); } ``` -------------------------------- ### `useTrainingState(selectedCases, category, options)` Source: https://context7.com/poliva/cubedex/llms.txt A React hook that manages the entire lifecycle of a training session, including state management for timers, move tracking, and smartcube integration. ```APIDOC ## `useTrainingState(selectedCases, category, options)` — Core training React hook Manages the full training session lifecycle: queue management (random order, slow-case prioritization, SRS smart review), countdown, timer state machine (`IDLE → READY → RUNNING → STOPPED`), smartcube move tracking with per-move progress coloring, solve recording, and SRS state updates. ### Parameters #### Path Parameters - **selectedCases** (CaseCardData[]) - Required - The list of cases to train on. - **category** (string) - Required - The training category (e.g., 'OLL'). - **options** (object) - Optional - Configuration options for the training session. - **selectionChangeMode** (string) - 'bulk' - **countdownMode** (boolean) - **randomizeAUF** (boolean) - **randomOrder** (boolean) - **timeAttack** (boolean) - **prioritizeSlowCases** (boolean) - **prioritizeFailedCases** (boolean) - **smartReviewScheduling** (boolean) - **smartcubeConnected** (boolean) ### Request Example ```tsx import { useTrainingState } from './src/hooks/useTrainingState'; import type { CaseCardData } from './src/lib/case-cards'; function PracticeComponent({ selectedCases }: { selectedCases: CaseCardData[] }) { const training = useTrainingState(selectedCases, 'OLL', { selectionChangeMode: 'bulk', countdownMode: false, randomizeAUF: true, randomOrder: true, timeAttack: false, prioritizeSlowCases: false, prioritizeFailedCases: true, smartReviewScheduling: true, smartcubeConnected: false, }); // training.timerState: 'IDLE' | 'READY' | 'RUNNING' | 'STOPPED' // training.displayAlg: "R U R' U R U2 R'" (with AUF applied) // training.displayMoves: [{ prefix:'', token:'R', suffix:'', color:'next', circle:true }, ...] // training.stats: { best: '1.23', ao5: '1.45', average: '1.50', averageTps: '8.20', ... } // training.currentCase: CaseCardData | null // training.timerText: '0:01.234' return (
{ if (e.code === 'Space') training.handleSpaceKeyDown(); }} onKeyUp={(e) => { if (e.code === 'Space') training.handleSpaceKeyUp(); }} tabIndex={0} >
{training.displayAlg}
{training.timerText || '0:00.000'}
Best: {training.stats.best} Ao5: {training.stats.ao5}
{training.fixVisible &&
Fix: {training.fixText}
}
); } ``` ### Response #### Success Response - **timerState** (string) - The current state of the timer ('IDLE', 'READY', 'RUNNING', 'STOPPED'). - **displayAlg** (string) - The algorithm formatted for display, including AUF. - **displayMoves** (array) - An array of objects representing moves with formatting information. - **stats** (object) - Statistics for the training session (e.g., best time, average). - **currentCase** (CaseCardData | null) - The current training case. - **timerText** (string) - The formatted timer display string. - **fixVisible** (boolean) - Whether a fix is visible. - **fixText** (string) - The text for the fix. - **handleSpaceKeyDown** (function) - Handler for space key down event. - **handleSpaceKeyUp** (function) - Handler for space key up event. ``` -------------------------------- ### Manage Persistent App Settings with useAppSettings Source: https://context7.com/poliva/cubedex/llms.txt Reads and writes user preferences from `localStorage`, exposing typed setters for various options like theme, gyroscope, and cube size. Ensures settings are persistent across sessions. ```tsx import { useAppSettings } from './src/hooks/useAppSettings'; function OptionsPanel() { const options = useAppSettings(); // options.theme: 'dark' | 'light' | 'system' // options.countdownMode: boolean // options.randomizeAUF (in practiceToggles) // options.alwaysScrambleTo: boolean // options.gyroscope: boolean // options.fullStickering: boolean // options.flashingIndicatorEnabled: boolean // options.autoUpdateLearningState: boolean // options.cubeSizePx: number return (
); } ``` -------------------------------- ### Convert KPattern to Facelet String and Vice Versa Source: https://context7.com/poliva/cubedex/llms.txt Converts between `KPattern` objects and their 54-character URFDLB facelet string representations. `faceletsToPattern` parses the string into a `KPattern`. ```ts import { patternToFacelets, faceletsToPattern, solvedPattern } from './src/lib/cube-utils'; // Solved state facelet string const solved = await solvedPattern(); const facelets = patternToFacelets(solved); // 'UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB' // Round-trip const roundTripped = await faceletsToPattern(facelets); roundTripped.isIdentical(solved); // true // After applying a move const moved = solved.applyAlg("R"); patternToFacelets(moved); // 'UUFUUFUUFRRRRRRRRRFFFDDDFFFUUUDDDDDDLLLLLLLLLBBBRRRBBBRRRBBBBBB...' (approximately) ``` -------------------------------- ### isCaseDue(state, now) / getCaseUrgency(state, now) Source: https://context7.com/poliva/cubedex/llms.txt Provides SRS scheduling assistance. `isCaseDue` determines if a case is due for review, and `getCaseUrgency` returns a numerical priority indicating how overdue or far in the future a case is. ```APIDOC ## isCaseDue(state, now) / getCaseUrgency(state, now) ### Description SRS scheduling helpers. `isCaseDue` returns `true` when a case's next review date has passed or when it has no SRS state. `getCaseUrgency` returns a numeric priority: a large negative number means highly overdue, a large positive number means far in the future. ### Parameters #### Path Parameters - **state** (CaseSrsState) - Required - The current SRS state of the case. - **now** (number) - Optional - The current timestamp (defaults to `Date.now()`). ### Request Example ```ts import { isCaseDue, getCaseUrgency, type CaseSrsState } from './src/lib/srs'; const state: CaseSrsState = { dueAt: Date.now() - 3600_000, // due 1 hour ago stabilityDays: 2, difficulty: 5, reps: 3, lapses: 0, lastReviewedAt: Date.now() - 86400_000, lastGrade: 'good', }; isCaseDue(state); // true (overdue) getCaseUrgency(state); // a negative number (more negative = more urgent) const futureState = { ...state, dueAt: Date.now() + 86400_000 }; isCaseDue(futureState); // false getCaseUrgency(futureState); // large positive number ``` ``` -------------------------------- ### expandNotation Source: https://context7.com/poliva/cubedex/llms.txt Sanitizes and normalizes user-entered algorithm strings. It performs various transformations including replacing curly quotes, converting bracket notation to parentheses, enforcing spacing rules, fixing notation errors like `R'2` to `R2'`, and stripping illegal characters. ```APIDOC ## `expandNotation(input)` — Normalize cube move notation Sanitizes and normalizes user-entered algorithm strings: replaces curly quotes, converts bracket notation to parentheses, enforces spacing rules, fixes `R'2` → `R2'`, and strips illegal characters. ```ts import { expandNotation } from './src/lib/storage'; expandNotation("RUR'U'") // "R U R' U'" expandNotation("R[U]R´U'") // "R (U) R' U'" expandNotation("r'2 F") // "r2' F" expandNotation("R U R' U R U2R'") // "R U R' U R U2 R'" expandNotation("XYZrUf") // "x y z r U f" (uppercase XYZ lowercased) expandNotation("R!!U??R'") // "R U R'" (illegal chars stripped) ``` ``` -------------------------------- ### Core Training React Hook Source: https://context7.com/poliva/cubedex/llms.txt Manages the full training session lifecycle, including queue management, timers, smartcube move tracking, and state updates. Use this hook to build a practice interface. ```tsx import { useTrainingState } from './src/hooks/useTrainingState'; import type { CaseCardData } from './src/lib/case-cards'; function PracticeComponent({ selectedCases }: { selectedCases: CaseCardData[] }) { const training = useTrainingState(selectedCases, 'OLL', { selectionChangeMode: 'bulk', countdownMode: false, randomizeAUF: true, randomOrder: true, timeAttack: false, prioritizeSlowCases: false, prioritizeFailedCases: true, smartReviewScheduling: true, smartcubeConnected: false, }); // training.timerState: 'IDLE' | 'READY' | 'RUNNING' | 'STOPPED' // training.displayAlg: "R U R' U R U2 R'" (with AUF applied) // training.displayMoves: [{ prefix:'', token:'R', suffix:'', color:'next', circle:true }, ...] // training.stats: { best: '1.23', ao5: '1.45', average: '1.50', averageTps: '8.20', ... } // training.currentCase: CaseCardData | null // training.timerText: '0:01.234' return (
{ if (e.code === 'Space') training.handleSpaceKeyDown(); }} onKeyUp={(e) => { if (e.code === 'Space') training.handleSpaceKeyUp(); }} tabIndex={0} >
{training.displayAlg}
{training.timerText || '0:00.000'}
Best: {training.stats.best} Ao5: {training.stats.ao5}
{training.fixVisible &&
Fix: {training.fixText}
}
); } ``` -------------------------------- ### Build Practice Card Data Source: https://context7.com/poliva/cubedex/llms.txt Compiles the `CaseCardData` array for a given category and subset selection. Enriches algorithms with performance metrics like best time, ao5, learned status, and SRS urgency. This is the primary data structure for the training state and case grid UI. ```typescript import { getCaseCards } from './src/lib/case-cards'; import { getSavedAlgorithms } from './src/lib/storage'; const saved = getSavedAlgorithms(); const cards = getCaseCards(saved, 'OLL', ['All Cases'], { autoUpdateLearningState: true }); // cards[0] shape: // { // id: "case:OLL:All%20Cases:R-U2-R2-F-R-F-U2-R-F2", // name: "OLL-1", // algorithm: "R U2 R2 F R F U2 R F2", // subset: "All Cases", // category: "OLL", // bestTime: 1230, // ms, or null // ao5: 1450, // ms, or null // learned: 2, // 0 | 1 | 2 // manualLearned: 1, // reviewCount: 24, // smartReviewDueAt: 1717200000000, // smartReviewDue: true, // smartReviewUrgency: -3600000, // negative = overdue // } ``` -------------------------------- ### averageOfFiveTimeNumber(algId) Source: https://context7.com/poliva/cubedex/llms.txt Computes the average of five (trimmed mean) from the last five execution times recorded for a given algorithm scope ID. ```APIDOC ## averageOfFiveTimeNumber(algId) ### Description Computes the average of five (trimmed mean: drop best and worst) from the last 5 execution times stored for an algorithm scope ID. ### Parameters #### Path Parameters - **algId** (string) - Required - The scope ID of the algorithm. ### Request Example ```ts import { averageOfFiveTimeNumber } from './src/lib/case-cards'; import { createScopeId, getAlgorithmId } from './src/lib/storage'; const scopeId = createScopeId('PLL', 'All Cases', getAlgorithmId("x R2 D2 R U R' D2 R U' R x'")); const ao5 = averageOfFiveTimeNumber(scopeId); // null if fewer than 5 solves recorded, otherwise number in ms // e.g. 1350 (1.350 seconds) ``` ``` -------------------------------- ### Expand and Normalize Cube Notation Source: https://context7.com/poliva/cubedex/llms.txt The `expandNotation` function sanitizes and standardizes user-inputted algorithm strings. It handles various formatting issues like curly quotes, bracket notation, spacing, and illegal characters. ```typescript import { expandNotation } from './src/lib/storage'; expandNotation("RUR'U'") // "R U R' U'" expandNotation("R[U]R´U'") // "R (U) R' U'" expandNotation("r'2 F") // "r2' F" expandNotation("R U R' U R U2R'") // "R U R' U R U2 R'" expandNotation("XYZrUf") // "x y z r U f" (uppercase XYZ lowercased) expandNotation("R!!U??R'") // "R U R'" (illegal chars stripped) ```