Skip to content

Latest commit

 

History

History
47 lines (40 loc) · 3.32 KB

File metadata and controls

47 lines (40 loc) · 3.32 KB

DevKeys — Syntax Highlighting & Architecture

Syntax Highlighting Pipeline

  • Renderer: The editor surface is a custom React component (TypingFeedback) rather than Monaco. Characters are animated with framer-motion and coloured via Tailwind utility classes.
  • Token source: highlight.js performs static tokenisation for each prompt. We parse the produced HTML using DOMParser to recover token spans and map them to character indices.
  • Colour mapping: getSyntaxColorClass converts highlight.js token types (keyword, string, comment, …) into VS Code-inspired Tailwind classes and adapts opacity for “pending” versus “typed” characters.
  • Fallback behaviour: If highlight.js does not recognise a language, the UI still renders but falls back to neutral colours.

Frontend Architecture (React + Vite)

  • UI composition: App stitches together a set of focused components—BackgroundGrid, ProjectHeader, MenuBar, and EditorSurface.
  • State management: Zustand holds the session state (targetSnippet, typed, attempts, timestamps, status) so external components can subscribe without prop drilling.
  • Hooks:
    • useLanguageSelection handles persisted language choices by reading/writing localStorage and validating against available packs.
    • usePromptSelection keeps the active prompt for the chosen language, randomises initial selection, and emits updates to the store.
    • useMenuToggle encapsulates menu open/close logic, including escape-to-close and outside click handling.
  • Typing surface: EditorSurface keeps focus on an invisible <textarea> layered over the visual rendering. All text updates flow through the session store’s handleInput.
  • Metrics: WPM and elapsed time derive from calculateMetrics, which combines the engine summary with session timestamps.
  • Tab-to-indent: handleTabAdvance inspects the remaining prompt content, injects whitespace into the store, and restores the caret, enabling editor-like indentation without losing accuracy tracking.

Engine & Persistence

  • Engine loading: initializeEngine tries to import the WASM bundle generated by crates/engine. If present it uses the Rust implementation (evaluate_typed); otherwise a TypeScript diff evaluator runs in process.
  • Session storage: storage/sessionRepository.ts manages an IndexedDB database (devkeys/sessions) for completed runs. Summaries include accuracy, WPM, elapsed time, attempt snapshots, and prompt metadata. Helper functions return the most recent sessions or export the full history.
  • Metrics calculator: lib/metrics.ts converts the raw engine summary plus timestamps into elapsed milliseconds and words-per-minute.

Data Flow Overview

flowchart LR
  subgraph UI
    KB[Keyboard Input]
    TF[TypingFeedback]
    MB[MenuBar]
  end

  KB --> Store(Zustand Session Store)
  MB --> Store
  Store --> Engine{evaluateTyping}
  Engine --> Metrics[calculateMetrics]
  Store --> TF
  Metrics --> Store
  Store --> IDB[(IndexedDB Sessions)]
  %% Toast removed from the app
Loading

Backend & Integrations

  • AI proxy: Not yet implemented. Future designs must preserve the privacy boundary—only derived weakness metadata may leave the device, never raw keystrokes.
  • Tree-sitter: Still on the roadmap; highlight.js currently handles syntax needs adequately for MVP.