Releases: Fundaments-Work/Theorem
Release list
Theorem v1.5.7
Fixed
- Mobile EPUB Navigation & Image Rendering Stabilization — Restored immediate, fluid page turns and eliminated blank pages across illustrated and media-rich EPUBs:
- In
foliate-js-runtime/paginator.js, eliminated the blocking pre-layout image decoding wait and 200msvisibility: hiddenblanking, restoring immediate synchronous layout rendering and zero-latency#turnPageresolution. - Fixed CSS multi-column fragmentation: removed
break-inside: avoidand-webkit-column-break-inside: avoidon parent<p>,<div>, and<figure>containers that caused the browser column formatter to abandon columns and generate blank pages before images. - Removed
display: blockandheight: auto !importantoverrides onimgelements, preserving natural aspect ratios and fluid column fitting withobject-fit: contain. - Calibrated touch gesture axis locking to 10px with natural horizontal dominance, preventing swipe drops on diagonal thumb arcs.
- Preserved chapter blob URLs during active reading sessions to prevent broken image assets on previous-chapter navigation.
- Fixed iframe initial visibility transition ensuring content is immediately rendered visible upon load completion.
- In
- Ghost Book Elimination on P2P Sync Deletions — Fixed ghost book cards remaining in the library when a book was deleted on a paired peer:
- In
src-tauri/src/file_transfer.rs, added checks againstdeletion_tombstonesanddeletedAtmetadata, returning an explicitPEER_BOOK_DELETEDstatus if a requested book has been deleted. - In
src/core/lib/sync-orchestrator.ts, immediately merged incomingdeletion_tombstonesover Iroh gossip and purged deleted book cards from local state without delay. - In
src/features/reader/Reader.tsx, handledPEER_BOOK_DELETEDby pruning the local ghost card, displaying an informative toast ("This book was deleted on the source device."), and routing to the Library.
- In
- Android Hardware Back Button Navigation Stack — Intercepted Tauri
onCloseRequested/ hardware back button events insrc/App.tsx:- Dismisses active overlays, sheets, and reader panels in LIFO order via
dispatchBackAction(). - Navigates from Reader view back to Library before closing.
- Minimizes or exits the app only when on the root Library route with no active overlays.
- Dismisses active overlays, sheets, and reader panels in LIFO order via
Improved & Performance
- Note Export Clean Typography & Knap AST Templating —
- In
src-tauri/src/vault_export.rsandsrc/core/lib/vault-sync.ts, cleaned YAML frontmatter to include only essential properties (title,author,type: "theorem-book-highlights", singletotal_highlights: N, andtags: [theorem, highlights]), removing internal paths, formats, and redundant duplicate counts. - Overhauled Markdown body formatting: removed artificial numbered headings (
### 1. Highlight), redundant color labels, timestamps, and divider lines. Quotes are formatted cleanly as> ==quote==with user notes placed directly underneath. - Integrated
@obsidianmd/knapAST template engine in frontend export settings for safe, custom Markdown templates with 0 bytes added to the native Rust binary.
- In
- SQLite Memory Reclaim & Low-Memory OS Trimming —
- Enhanced native
trim_memorycommand insrc-tauri/src/database.rsandlib.rsto runPRAGMA shrink_memory;andPRAGMA wal_checkpoint(PASSIVE);on SQLite connections alongsidelibc::malloc_trim(0)on Linux and Android Bionicmallopt(-101, 0)(M_PURGE). - Wired
document.visibilityState === 'hidden'insrc/App.tsxto automatically triggertrim_memorywhenever Theorem is minimized or backgrounded, preventing background process termination by the Android OS Low Memory Killer (LMK).
- Enhanced native
- Native Rust Readability Engine — Integrated Mozilla's Readability port in Rust (
readabilitycrate) with full DOM scoring intosrc-tauri/src/article_extractor.rs, parsing and scoring article HTML in Rust in <3ms. - Store & Build Modernization —
- Declared explicit ESM module type (
"type": "module") inpackage.jsonfor full Vite 8 native configuration loader compliance. - Optimized O(1) library store lookups in
libraryStore.tsvia direct iterator access, eliminating transient array allocations during large library hydration.
- Declared explicit ESM module type (
Download & install
| Platform | Download |
|---|---|
| Windows (x64) | Theorem_1.5.7_x64-setup.exe |
| macOS (Apple Silicon) | Theorem_1.5.7_aarch64.dmg |
| macOS (Intel) | Theorem_1.5.7_x64.dmg |
| Linux (Debian/Ubuntu) | Theorem_1.5.7_amd64.deb |
| Linux (any) | Theorem_1.5.7_amd64.AppImage |
| Android (arm64) | app-arm64-release.apk |
| Android (arm) | app-arm-release.apk |
| Android (x86_64) | app-x86_64-release.apk |
Linux one-liner: curl -fsSL https://raw.githubusercontent.com/Fundaments-Work/Theorem/main/scripts/install-linux.sh | bash
Desktop builds auto-update in place (Settings → About → Check for Updates). Android updates are manual unless installed via F-Droid.
Theorem v1.5.6
Fixed
- Memory & CPU Spike on Book Opening — Eliminated excessive ~1.3GB memory consumption and CPU pegging when opening books:
- In
src/features/reader/Reader.tsx, decoupledtts_engine_preloadfrom unconditional book open hooks so neural ONNX models are compiled only when Immersion Reading is actively enabled. - Added an unmount hook that triggers
tts_engine_unloadand a new nativetrim_memorycommand callinglibc::malloc_trim(0), releasing dormant glibc thread arenas back to the OS kernel. - Reaped Linux
spd-sayandkillallchild processes insrc-tauri/src/tts_linux.rsvia detached wait threads, preventing<defunct>zombie process accumulation.
- In
- P2P Device Sync PDF & Non-Materialized On-Demand File Transfers — Fixed persistent "Book File Not Available" errors when attempting to open or download PDFs and EPUBs synced from paired devices:
- SQLite Persistence Key Alignment: Fixed
find_in_dbinsrc-tauri/src/file_transfer.rsqueryingpersist:theorem-library. Theorem stores state underzustand:theorem-libraryviaSQLITE_PERSIST_KEY_PREFIX. Updated queries to checkzustand:theorem-library(and fallback variations) to accurately extract desktop-imported book file paths (filePath,storagePath). - File Path Normalization & Percent-Decoding: Added
normalize_candidate_pathinfile_transfer.rshandlingfile://scheme prefixes, percent-encoded spaces and symbols (percent_decode_str), and Windows drive formats (/C:/...->C:/...). - Direct LAN IP/Port Connection Fallback: Configured
EndpointAddrwithlast_ipandlast_portsocket addresses inconnect_and_requestto ensure reliable direct peer connections on local networks when relays are delayed or unreachable. Refreshes and persists verified socket addresses upon successful transfers. - Two-Way Pairing Address Capture: Updated
PairingProtocolHandler::acceptinsrc-tauri/src/iroh_sync.rsto extract remote IP and port fromconn.paths()and record them inPairedDevice, establishing direct LAN addressing immediately upon pairing. - Atomic Safe Downloads: Updated
download_book_fileto stream incoming bytes into a.download.tmptemporary file before atomically renaming to.book, cleaning up incomplete artifacts on network timeout or failure. - Immediate Progress & Reload Flow: Emitted an initial
0.0%event immediately upon connection infile_transfer.rsand attached the progress listener on mount inReader.tsx. ClearedloadedBookIdRef.currentupon transfer completion so the reader seamlessly mounts the newly acquired book without stalling on "Book File Not Available".
- SQLite Persistence Key Alignment: Fixed
- Mobile EPUB Navigation & Touch Gesture Handling — Restored smooth EPUB navigation and thumb gesture ergonomics:
- In
foliate-js-runtime/paginator.js, restored GPU-promoted 300ms CSS transform slide transitions for page turns and snap releases while keeping transitions cleanly disabled during finger drags and frame-by-frame JS interpolation. - Refined gesture axis arbitration (
absDx > 16 && absDx > absDy * 1.3) so natural curved thumb swipes reliably turn pages without locking into vertical scroll. - Set
touchAction: 'none'on paginated viewport containers inReaderViewport.tsx, eliminating mobile WebView gesture arbitration delays.
- In
- Download Failure UI Polish — Removed the extraneous "Go to Sync Settings" button from the reader download failure modal, establishing a clean, unified two-button action group (Back to Library and Try Again).
Improved & Performance
- Dependency Modernization —
- Removed deprecated
@types/dompurifyand@types/uuid(types are now bundled upstream). - Updated frontend dependencies to latest versions, including
vitest&@vitest/coverage-v85.0.1,@tanstack/react-virtual3.14.13,zod4.6.5,react-i18next17.0.14,lucide-react1.47.0, andjsdom30.1.0. - Updated 44 Rust crates via
cargo updateto latest compatible releases.
- Removed deprecated
- Dynamic Deferred Sentry Loading — Refactored
src/core/lib/sentry.tsandsrc/main.tsxto dynamically import@sentry/reactonly when a valid Sentry DSN is resolved at runtime. Sheds 270 KB (88 KB gzip) from the synchronous critical startup path for local, offline, and dev instances. - React Re-render Isolation & Fine-Grained Selectors —
- In
Library.tsx, extracted<DailyHighlightBanner />as an isolated memoized component, removing theannotationsarray subscription fromLibraryPage. Prevents full library re-renders (1,000+ cards) when annotations are created, updated, or synced. - In
Sidebar.tsx, replaced whole-objectstatssubscriptions with primitivecurrentStreakselectors, preventing sidebar thrashing during background reading progress flushes. - In
Reader.tsx, decoupled thefeedsarray subscription from the active book reader and isolated reader-specific settings via shallow derivation, ensuring background RSS feed refreshes and non-reader settings modifications never trigger reader viewport re-renders.
- In
- SQLite Composite Query Indexes — Added
idx_rss_articles_feed_fetched ON rss_articles(feed_id, fetched_at DESC),idx_rss_articles_fetched_at ON rss_articles(fetched_at DESC), andidx_reading_sessions_date_created ON reading_sessions(session_date DESC, created_at DESC)insrc-tauri/src/database.rs, converting in-memory sort scans into instant index lookups. - Zero-Allocation Rust Search & Clone Elimination —
- Replaced allocating string-lowercasing search in
src-tauri/src/epub_rewriter.rs(find_ci) with zero-allocation byte window scanning (windows(len).position(|w| w.eq_ignore_ascii_case(...))), saving tens of 100KB–500KB OPF string allocations per metadata write. - In
src-tauri/src/epub_parser.rs(prefetch_sync), moved ownedEpubMetafields directly, eliminating redundant heap string clones and pre-inflated chapter map duplication. - In
src-tauri/src/batch_ingest.rs, moved base64 cover strings directly intoNativeBookRecordwithout cloning.
- Replaced allocating string-lowercasing search in
- Cloudflare DTO Data Layouts — Applied
Box<str>andBox<[T]>across Rust DTOs (book_search.rs,opds_parser.rs,article_extractor.rs,mobi_parser.rs,audiobook.rs,mdict.rs,stardict.rs), shedding 8 bytes of excess allocator capacity per field.
Download & install
| Platform | Download |
|---|---|
| Windows (x64) | Theorem_v1.5.6_x64-setup.exe |
| macOS (Apple Silicon) | Theorem_v1.5.6_aarch64.dmg |
| macOS (Intel) | Theorem_v1.5.6_x64.dmg |
| Linux (Debian/Ubuntu) | Theorem_v1.5.6_amd64.deb |
| Linux (any) | Theorem_v1.5.6_amd64.AppImage |
| Android (arm64) | app-arm64-release.apk |
Linux one-liner: curl -fsSL https://raw.githubusercontent.com/Fundaments-Work/Theorem/main/scripts/install-linux.sh | bash
Desktop builds auto-update in place (Settings → About → Check for Updates). Android updates are manual unless installed via F-Droid.
Theorem v1.5.5
Fixed
- P2P Device Sync PDF On-Demand Downloads (Issue #89) — Fixed on-demand book download failures from paired devices for books imported on desktop. Enhanced
FileTransferHandler::locate_bookinsrc-tauri/src/file_transfer.rsto locate books across all local storage targets: materializedbook-cache/{id}.bookandbook-cache/{id}, SQLitebooks.dataBLOBs,book_metadatatable entries (filePath,file_path,storagePath,storage_path), and the Zustand library state stored in SQLitekv_store(persist:theorem-library). Replaced in-memory whole-file buffering with zero-RAM-spike streaming from filesystemFilehandles to QUIC send streams viatokio::io::copy. - Cross-Page Text Highlighting in PDF and EPUB Readers (Issue #90) — In
PDFAnnotationLayer.tsx, implemented sub-range clipping totextLayerNodewith boundary point comparison so selections spanning across pages isolate text belonging strictly to each respective page. Filtered client rects to the page layer's physical bounding box (layerRect), preventing inverted coordinates on previous pages. Replaced immediateselection.removeAllRanges()with a deferred cleanup (80ms) to allow multiple intersecting page layers to capture their segment of a multi-page selection. InReader.tsx, updatedresolvePickerPosition()to anchor using the last client rect fromRange.getClientRects()rather thangetBoundingClientRect(), preventing popover menu offset across CSS multi-column paginated layouts. - Mobile Immersion Reading and Text-to-Speech on Android (Issue #91) — Handled
nullvoice lists returned by Android'sTextToSpeech.getVoices()inTtsAudioPlugin.kt(doSpeak,getVoices,synthesizeToFile) withcurrentTts.voices?.let { ... }, eliminating unhandled KotlinNullPointerExceptioncrashes whendefaultTtsSettings.voiceis set. Enabled TTS by default insettingsStore.ts(defaultTtsSettings.enabled: true) and ensuredonToggleImmersionis always available for non-PDF books inReader.tsx, automatically enabling TTS when toggled. Allowed mobile users to access the voice and speed settings popup inReaderNavbar.tsxon Android ((neuralReady || isAndroid())) to adjust narration speed (0.75×–1.5×). - Sync Gossip and Reading Progress Propagation (Issue #92) — Fixed a premature bailout in
provisionToIrohDocs()(src/core/lib/sync-orchestrator.ts) whereneedsProvisionevaluated tofalseafter the first application launch, causing subsequent reading progress mutations and last read timestamps to skipdocsSetEntry(). Removed the premature bailout so that per-key diffing against_provisionedValuesruns on every sync round, correctly pushing modifiedprogress,currentLocation, andlastReadAttimestamps toiroh-docsand triggeringiroh-gossippropagation across connected peers. UpdateddefaultDeviceSyncSettingsinsettingsStore.tsto defaultautoSyncEnabled: trueandsyncOnConnect: true, migrating legacy configurations to schema version 12.
Download & install
| Platform | Download |
|---|---|
| Windows (x64) | Theorem_v1.5.5_x64-setup.exe |
| macOS (Apple Silicon) | Theorem_v1.5.5_aarch64.dmg |
| macOS (Intel) | Theorem_v1.5.5_x64.dmg |
| Linux (Debian/Ubuntu) | Theorem_v1.5.5_amd64.deb |
| Linux (any) | Theorem_v1.5.5_amd64.AppImage |
| Android (arm64) | app-arm64-release.apk |
Linux one-liner: curl -fsSL https://raw.githubusercontent.com/Fundaments-Work/Theorem/main/scripts/install-linux.sh | bash
Desktop builds auto-update in place (Settings → About → Check for Updates). Android updates are manual unless installed via F-Droid.
Theorem v1.5.4
Added
- Pitch-Preserving Audio Time-Stretching (WSOLA) — Integrated high-fidelity Waveform Similarity Overlap-Add (WSOLA) time-domain algorithm into native Rust playback (
src-tauri/src/audio_player.rs) with normalized cross-correlation phase alignment and Hann window crossfading. Enables smooth narration playback speed control (0.5×–3.0×) without pitch shifting or robotic frequency distortion across both mono and stereo channels. - Native Audio Volume & Speed Controls — Exposed Tauri commands
tts_audio_set_speed,tts_audio_get_speed,tts_audio_set_volume, andtts_audio_get_volumecontrolling the native Rodio sink and WSOLA buffer stretching directly in Rust, wired dynamically throughImmersionPlayer.ts. - Native PDF In-Book Search Engine — Implemented a streaming, zero-allocation PDF content search engine in native Rust (
src-tauri/src/book_search.rs). Parses indirect PDF object streams, decompresses Flate/Deflate content streams, parses PDF text operators (Tj,TJ,',", hex strings, and glyph kerning offsets), and runs Rayon parallel page searches with UTF-8 byte-slice context snippet extraction. - Instant Native PDF Search Fast-Path — Integrated the native PDF search engine directly into the reader viewport (
src/features/reader/engines/pdfjs-engine.tsx). In Tauri desktop/mobile environments, queries execute in parallel in Rust (~15ms) and stream directly into the search panel with instantpdf:page:Njump coordinates, falling back cleanly to the JS worker in pure web browsers. - Native Readability Article Extractor — Added
extract_article_from_html_nativeinsrc-tauri/src/article_extractor.rs, executing fast HTML cleaning, article candidate scoring, and metadata extraction viaquick-xmldirectly in Rust. - Dynamic Frontend Readability Code-Splitting — Code-split
@mozilla/readabilityanddompurifyinArticleExtractorService.ts, dynamically loading them only when parsing web articles in browser environments. This sheds over 120KB of minified parser code from the initial frontend chunk. - Direct In-Rust SQLite P2P Sync Merging — Added
sqlite_merge_sync_entriesinsrc-tauri/src/database.rs, merging incoming Iroh-gossip documents directly inside an atomic SQLite transaction. Directly updatesbook_metadata,book_annotations,books_fts, andkv_storewhile cascadingdeletion_tombstones, eliminating double-hop IPC serialization and preventing Last-Write-Wins collisions. - Relational SQLite Vocabulary Storage Subsystem — Added a dedicated normalized
vocabularytable insrc-tauri/src/database.rswith indexed lookup by(normalized_term, language)andcreated_at. Automatic idempotent zero-data-loss database migration (run_v154_database_migrations) unpacks existing terms fromzustand:theorem-vocabularyinto the relational store inside an atomic transaction while preserving the originalkv_storeblob as an immutable backup. - Native EPUB Table of Contents (TOC) Pre-Parsing — Implemented zero-copy streaming pre-parsing for both EPUB 3 Navigation documents (
<nav epub:type="toc">/<nav role="doc-toc">) and EPUB 2 NCX files (<navMap><navPoint>...) insrc-tauri/src/epub_parser.rsusingquick-xml. Parses nested chapter hierarchies, resolves intra-book relative hrefs with URL fragments, unescapes entities, and packages the result into compactBox<str>/Option<Box<[TocItemDto]>>Cloudflare data layouts insideprefetch_zip_metadata. - Instant Foliate Reader Table of Contents Display — Wired the pre-parsed TOC directly into the EPUB bridge (
src/core/lib/tauri-epub-bridge.ts) and reader runtime (src/features/reader/foliate-js-runtime/view.jsandepub.js), allowing the webview reader to immediately populate chapters and landmarks without blocking on DOMParser XML parsing on the main thread. - Direct Library Annotation Navigation — Added interactive "Open in book" navigation directly from cards and context menus in
src/features/library/Annotations.tsx, instantly opening the book and jumping to the precise highlight or note location. - SQLite Vocabulary Persistence & Sync Integration — Connected
saveVocabularyTerm,deleteVocabularyTerm, andonRehydrateStorageinvocabularyStore.tsandsync-orchestrator.tsto SQLite relational CRUD operations (sqlite_get_vocabulary_terms,sqlite_save_vocabulary_term,sqlite_delete_vocabulary_term). Automatically reconciles relational SQLite terms on app startup and synchronizes mutations.
Fixed
- Reader Page Turn Component Thrashing — Eliminated full 2,800-line React component tree re-renders on every page turn in
src/features/reader/Reader.tsx. Decoupled thestatssubscription from the active component tree and deferred visible word count extraction torequestIdleCallbackafter a 1,000ms reading dwell timeout, ensuring buttery 60fps page turns. - Instant Intra-Section Navigation & Deadlocks — Removed artificial
await wait(100)delay during intra-section page turns insrc/features/reader/foliate-js-runtime/paginator.js. Ensured the#lockedflag is released in afinallyblock so failed or aborted section loads can never wedge the page turning pipeline. - Bounded Section Navigation & Spine Error Suppression — Added
#canGoToIndex()boundary checks prior to#goTocalls inpaginator.js, preventing spuriousFailed to load sectionwarnings and blank screen states when swiping past the boundaries of the book. - Event Listener Leak in Reader Iframe — Guarded iframe selection listener attachments with
(doc).__theorem_selection_attachedidempotency flag insrc/features/reader/engines/foliate-engine.ts, eliminating runaway event listener accumulation and duplicated tap triggers across chapter transitions. - Controls Tap-to-Toggle Latency — Removed the artificial 120ms tap-suppression delay in
foliate-engine.tsand accelerated chrome toggle transitions from 300ms to 150msease-out, restoring instant responsive chrome toggling. - Mobile Swipe Sensitivity & Axis Disambiguation — Calibrated mobile touch swipe thresholds in
paginator.js(20% width displacement, 0.2 px/ms velocity) and removed the 180ms hold timer lock, allowing diagonal and hesitant thumb swipes to complete naturally without false-positive selection locks. - PDF Continuous Scroll Blanks & Height Collapse — Expanded
PAGE_PROXY_KEEP_WINDOWto 50 insrc/features/reader/engines/pdfjs-engine.tsx(retaining up to 80 loaded page proxies), keeping page placeholders sized accurately and preventing DOM collapse, scroll jumping, and blank renders during rapid scrolling. - Cross-Device Goal & Reminder Duplication — Synchronized
lastGoalNotifiedDateandlastDailyReminderDateinsrc/core/store/settingsStore.tsandsrc/core/lib/sync-import.ts. Flushes reading stats silently on book close and suppresses foreground OS notifications when the application window is focused. - Paginator Uncollapse Non-Object Anchor Error — Fixed an unhandled promise rejection in
paginator.jswhere('collapsed' in range)was evaluated on numeric anchors (1,0, fractions) during settings re-renders and column layout updates. - Highlight Recovery via Text Walker — Added
findRangeByTextfallback insrc/features/reader/foliate-js-runtime/view.jsto reliably render highlights even when DOM restructuring invalidates serialized CFI character offsets.
Improved & Performance
-
Complete Elimination of
fuse.js— Removed thefuse.jsruntime dependency frompackage.jsonand replaced it insrc/core/lib/search/fuzzy.tswith a lightweight, zero-dependency fuzzy matching engine. Provides exact prefix, word-boundary, substring, and subsequence compactness scoring while reducing bundle overhead to 2KB. -
High-Velocity PDF Edge Prefetching — Increased PDF continuous scroll edge prefetch lookahead to
$2.0 \times \text{viewport}$ and expanded concurrent batch loading to 8 pages for seamless continuous scrolling. -
Testing Integrity & Boundary Hardening — Expanded
tests/reading-time-adaptive.test.tsandtests/paginator-navigation.test.tswith rigorous edge-case and outlier suites (0 words, negative words, 100,000 words, exact 5.0s/180.0s dwell boundaries, corrupt fractions, lock safety, and gesture classification). All 348 Vitest tests and Rust unit tests pass cleanly.
Download & install
| Platform | Download |
|---|---|
| Windows (x64) | Theorem_v1.5.4_x64-setup.exe |
| macOS (Apple Silicon) | Theorem_v1.5.4_aarch64.dmg |
| macOS (Intel) | Theorem_v1.5.4_x64.dmg |
| Linux (Debian/Ubuntu) | Theorem_v1.5.4_amd64.deb |
| Linux (any) | Theorem_v1.5.4_amd64.AppImage |
| Android (arm64) | app-arm64-release.apk |
Linux one-liner: curl -fsSL https://raw.githubusercontent.com/Fundaments-Work/Theorem/main/scripts/install-linux.sh | bash
Desktop builds auto-update in place (Settings → About → Check for Updates). Android updates are manual unless installed via F-Droid.
Theorem v1.5.3
Added
- Hybrid Two-Tier Search Engine (
SQLite FTS5+nucleo-matcher) — Completely replaced JavaScriptfuse.jsin desktop and mobile environments with a native Rust two-tier search architecture (src-tauri/src/fuzzy_search.rs). Tier 1 leverages SQLitebooks_ftsFTS5 index to prune large libraries on disk down to candidate sets in ~1ms without heap allocation. Tier 2 uses SIMD-accelerated Smith-Waterman matching (nucleo-matcher, powering Helix editor) to rank candidates, recover typos, and compute exact matching UTF-32 character indices in ~0.1ms. - UI Match Character Highlighting (
<HighlightMatch />) — Reusable, high-performance UI letter highlighting component (src/ui/HighlightMatch.tsx) that visually accentuates matched character segments in book titles, authors, annotations, and bookmarks across grid, compact, and list views as the user types. Grouping contiguous matched characters minimizes React DOM nodes for zero-lag 60fps typing. - Native Standards-Compliant Article EPUB Packaging — Offloaded EPUB packaging directly to Rust using the
zipcrate (src-tauri/src/article_epub.rs), eliminating JavaScriptfflate(zipSync) on the main thread and preventing UI thread stutters when opening web articles and RSS entries. - Morphological Lemmatizer & Irregular Inflection Stemmer — Native Rust stemmer (
src-tauri/src/stemmer.rs) integrated into MDict (mdict.rs) and StarDict (stardict.rs) dictionary engines. Provides automatic inflection, irregular verb, and plural normalization for near-100% dictionary hit rates without network fallbacks. - Zero-Data-Loss Relational Migration Subsystem — Added dedicated SQLite relational tables for
rss_feeds,rss_articles,rss_article_content(separating heavy article bodies from metadata), andreading_sessions(time-series analytics) insrc-tauri/src/database.rs. Automatically and idempotently migrates legacy JSON blobs fromkv_storeinto normalized tables inside an atomic transaction while preserving the originalkv_storevalues as immutable backups. - Decoupled Relational RSS & KV Store Footprint Reduction — Decoupled full HTML content from Zustand persistence, shrinking
zustand:theorem-rssfrom 25MB+ down to <50KB and eliminating 150ms V8 GC stalls on feed mutations. - Full Relational Storage & Session Telemetry API — Exposed native Tauri commands and typed TypeScript wrappers for RSS feed/article/content CRUD and reading session recording. Reading time hook flushes active session telemetry directly to relational tables while feeding daily goal reminders.
- Atomic P2P Annotation Sync — Hardened Iroh Docs P2P synchronization with atomic item-level keys (
anno:<bookId>:<annotationId>) to prevent overwrite collisions and ensure rapid delta replication across paired devices. - Windowed Library Query API — Added
sqlite_query_books_windowTauri command with native limit/offset cursor queries to support large library virtualization.
Improved & Performance
- Off-Thread Cover Downsampling Across All Ingestion Paths — Fully wired native Rayon cover downsampling (
downsample_cover) intocover-extractor.tsandstorage.ts, eliminating DOM<canvas>image resizing on desktop and mobile Tauri runtimes. - Eliminated JS
Fuse.jsOverhead — Removed runtimeFuseobject instantiation and heap-allocated searchable item caches infiltering.ts, dropping library filtering memory pressure and query latency to near-zero. - Robust Cross-Platform Search Fallbacks — Seamlessly falls back to token matching in pure browser and mock environments while running native two-tier search in desktop and mobile Tauri runtimes.
Download & install
| Platform | Download |
|---|---|
| Windows (x64) | Theorem_v1.5.3_x64-setup.exe |
| macOS (Apple Silicon) | Theorem_v1.5.3_aarch64.dmg |
| macOS (Intel) | Theorem_v1.5.3_x64.dmg |
| Linux (Debian/Ubuntu) | Theorem_v1.5.3_amd64.deb |
| Linux (any) | Theorem_v1.5.3_amd64.AppImage |
| Android (arm64) | app-arm64-release.apk |
Linux one-liner: curl -fsSL https://raw.githubusercontent.com/Fundaments-Work/Theorem/main/scripts/install-linux.sh | bash
Desktop builds auto-update in place (Settings → About → Check for Updates). Android updates are manual unless installed via F-Droid.
Theorem v1.5.2
Added
- Native Speech Text Normalizer — High-performance deterministic rule-based expansion of numbers, dates, 4-digit years, Roman numerals, currencies, percentages, fractions, units, and abbreviations in native Rust (
src-tauri/src/text_normalizer.rs). Shared across Supertonic neural TTS runtime, desktop platform narration, and offline companion audiobook generation. - Single-Shot Rayon Obsidian Vault Exporter — Rayon multi-threaded native batch export for Obsidian book highlight notes and Lemma SRS flashcard decks (
src-tauri/src/vault_export.rs). Replaces sequential IPC file-write loops with a single concurrent native filesystem export (<5ms). - Native quick-xml Streaming RSS Parser — Zero-copy SAX feed parsing over byte slices (
src-tauri/src/rss_parser.rs), cutting feed ingestion from 150ms–400ms down to 2ms–5ms. Adopts Cloudflare data layouts (Box<str>andBox<[T]>) to eliminate heap capacity slack. - Off-Thread Cover Processing & Dominant Color Extraction — Offloads cover downsampling and WebP encoding to a background thread pool via the native
imagecrate (src-tauri/src/image_ops.rs), accompanied by fast 32x32 histogram dominant color palette quantization (<0.2ms) without main-thread DOM<canvas>overhead. - EPUB CFI Range Parsing & Spatial Ordering — Added native Rust parsing and spatial ordering for EPUB CFI ranges (
src-tauri/src/epubcfi.rs), enabling exact start-anchor resolution across reflowable chapters.
Improved & Performance
- Zero-Allocation In-Book Search Snippets — Refactored snippet context slicing (
src-tauri/src/book_search.rs) to usetext.char_indices()byte slicing, eliminating transientVec<char>heap allocations for 10× faster search throughput. - Cross-Column & Cross-Page Highlight Engine — Precision refactoring of Foliate's Overlayer (
foliate-js-runtime/overlayer.js) to render individual line fragments viaRange.getClientRects(), strictly filtering zero-dimension rects across column gutters and multi-column pagination spreads. - Foliate Paginator Anchor Stabilization — Locked non-collapsed range anchors to
startContainerinpaginator.js, completely eliminating page-flipping oscillations when highlights span column or viewport page boundaries. - Mobile Touch Disambiguation Barrier — Introduced a 120ms tap-suppression barrier in
foliate-engine.ts, establishing a strict gesture hierarchy that eliminates false-positive page turns during mobile selection and drag gestures.
Download & install
| Platform | Download |
|---|---|
| Windows (x64) | Theorem_v1.5.2_x64-setup.exe |
| macOS (Apple Silicon) | Theorem_v1.5.2_aarch64.dmg |
| macOS (Intel) | Theorem_v1.5.2_x64.dmg |
| Linux (Debian/Ubuntu) | Theorem_v1.5.2_amd64.deb |
| Linux (any) | Theorem_v1.5.2_amd64.AppImage |
| Android (arm64) | app-arm64-release.apk |
Linux one-liner: curl -fsSL https://raw.githubusercontent.com/Fundaments-Work/Theorem/main/scripts/install-linux.sh | bash
Desktop builds auto-update in place (Settings → About → Check for Updates). Android updates are manual unless installed via F-Droid.
Theorem v1.5.1
Added
- Set-and-Forget Obsidian Vault Auto-Sync — Automatically synchronizes markdown notes to your Obsidian vault without needing manual clicks. Sync triggers immediately upon choosing an export folder and runs seamlessly in the background with a 2-second debounce on any highlight, note, or vocabulary change.
- Lemma Spaced-Repetition (FSRS) Deck Export — Vocabulary exports to
<VaultRoot>/Theorem/Vocabulary.mdstructured as a native flashcard deck for the Lemma Obsidian plugin. Frontmatter includestags: [flashcards]for automatic deck indexing, while cards use standard---card---delimiters, pronunciation, context quotes, and stable^fsrs-vocab-<id>block IDs to preserve FSRS review history and scheduling across exports. - Idiomatic Obsidian Book Highlights — Book notes are now organized under
<VaultRoot>/Theorem/Books/using native Obsidian> ==highlight==markdown formatting instead of raw HTML<mark>tags. Removed dead/unregistered deep links in favor of portable, clean markdown.
Fixed
- Silent Reader Exit — Eliminated nagging "You're X min short" toast notifications whenever closing a book or navigating away from the reader. Exiting the reader now flushes reading stats completely silently.
- Deduplicated Goal Met Celebrations — Enforced daily celebration deduplication via
stats.lastGoalNotifiedDate, guaranteeing that achieving your daily reading goal only triggers a celebration notification strictly once per calendar day. - Global Daily Goal Reminder (8 PM) — Moved the daily goal reminder hook to the global application root (
App.tsx) and removed the restriction requiring >0 minutes read today, ensuring that users who haven't yet opened the app or read are reliably reminded to read at their scheduled reminder time.
Download & install
| Platform | Download |
|---|---|
| Windows (x64) | Theorem_v1.5.1_x64-setup.exe |
| macOS (Apple Silicon) | Theorem_v1.5.1_aarch64.dmg |
| macOS (Intel) | Theorem_v1.5.1_x64.dmg |
| Linux (Debian/Ubuntu) | Theorem_v1.5.1_amd64.deb |
| Linux (any) | Theorem_v1.5.1_amd64.AppImage |
| Android (arm64) | app-arm64-release.apk |
Linux one-liner: curl -fsSL https://raw.githubusercontent.com/Fundaments-Work/Theorem/main/scripts/install-linux.sh | bash
Desktop builds auto-update in place (Settings → About → Check for Updates). Android updates are manual unless installed via F-Droid.
Theorem v1.5.0
Added
-
Adaptive Reading Time Estimation — Pure mathematical calculation engine for reading speed and progress (
src/features/reader/lib/reading-time.ts). Tracks organic dwell time on each page turn, filtering out rapid skimming (<5s) and idle periods (>180s), clamped between 80 and 800 WPM, and smoothed with exponential moving average ($\alpha = 0.15$ ). The reader navbar now displays both chapter and book remaining time (e.g."14 min in chapter · 2 hr left"), intelligently omitting redundant chapter time on the final chapter. -
Immersion Reading Pace Lock — When Text-to-Speech narration is active, reading time estimates automatically lock to the true machine speaking cadence (
$160 \times \text{speed}$ WPM) without polluting the reader's human reading average. -
Audiobook-Grade Text Normalization — Added automated text pre-processing for natural speech synthesis (
src/features/reader/audio/text-normalization.ts), expanding cardinal integers into words, ordinal numbers (1st$\rightarrow$ "first"), 4-digit years (1984$\rightarrow$ "nineteen eighty-four"), Roman numerals in titles and names (Chapter IV,Henry VIII), currencies ($12.50), percentages, fractions, and common abbreviations (Dr.,Mr.,e.g.,etc.).
Improved & Performance
- Fast Streaming TTS & Reduced Latency — Reduced intra-sentence silence from 300ms to 80ms for seamless audio playback across sentence chunks without jarring acoustic gaps.
- Dynamic ONNX Memory Management — Supertonic neural sessions are automatically unloaded after 60 seconds of idle inactivity, freeing ~400MB of RAM. Memory is also immediately released on reader exit.
- Idempotent ORT Initialization — Wrapped dynamic ONNX Runtime initialization in a process-wide
OnceLock, enabling fast and reliable session recreation whenever narration resumes after an idle unload. - Disk Cache Cap & Background Eviction — Lowered the local WAV audio cache limit from 1GB to a lean 150MB, moving LRU cache trimming to a background thread to prevent disk I/O from stalling the audio synthesis pipeline.
- Optimized Prefetching — Aligned prefetch cache keys with streaming chunk normalization, caching only the leading chunk of the upcoming page to eliminate redundant background computation.
Fixed
- Highlight Navigation Context Popup — Navigating to an existing highlight or bookmark from the sidebar or annotations panel no longer falsely triggers text selection or pops open the highlight context menu.
- TTS Auto-Play on Pause Bug — Added explicit
pausedstate tracking in Rust'sNativePlayer(audio_player.rs), preventing background chunks appended during pause from resuming audio unexpectedly. - Initial TTS Premature Page Turn — Eliminated an errant boundary check that triggered an immediate page-turn when clicking Play for the first time.
- Instant Playback Resume — Clicking Play while paused immediately unpauses the active native player instead of restarting speech synthesis from scratch.
- Fallback Text Extraction on Play — If page text extraction has not finished caching when Play is clicked, the player extracts visible text on-demand rather than failing silently.
- Sentence Highlighting Cleanup — Removed sentence-level overlay DOM mutations during TTS playback, preventing layout shifts and scrolling disruptions.
Download & install
| Platform | Download |
|---|---|
| Windows (x64) | Theorem_v1.5.0_x64-setup.exe |
| macOS (Apple Silicon) | Theorem_v1.5.0_aarch64.dmg |
| macOS (Intel) | Theorem_v1.5.0_x64.dmg |
| Linux (Debian/Ubuntu) | Theorem_v1.5.0_amd64.deb |
| Linux (any) | Theorem_v1.5.0_amd64.AppImage |
| Android (arm64) | app-arm64-release.apk |
Linux one-liner: curl -fsSL https://raw.githubusercontent.com/Fundaments-Work/Theorem/main/scripts/install-linux.sh | bash
Desktop builds auto-update in place (Settings → About → Check for Updates). Android updates are manual unless installed via F-Droid.
Theorem v1.4.3
Fixed
- Settings panel hidden by bottom bar on mobile — The
FloatingPanel(used for reader settings, bookmarks, TOC, etc.) was rendered withz-[var(--z-dropdown)](z-50) while the reader's bottom navigation bar usesz-[140]. On mobile, where the panel slides up as a full-width bottom sheet, the navbar was painting on top of it, cropping off the bottom portion. RaisedFloatingPaneltoz-[150]to ensure it always appears above the reader chrome. - Touch highlight toolbar flash / selection glitch — When dragging to extend a text selection on touch devices,
selectionchangewas firing continuously mid-drag, causing theHighlightColorPickertoolbar to appear and disappear repeatedly (visible flicker). The selection capture is now deferred:touchstartsets anisTouchActiveflag andselectionchangeonly updates the navigation lock during an active touch gesture; the actual callback is processed exactly once ontouchend. This eliminates the mid-drag toolbar flash. Based on the same deferred-popup pattern used by Readest. - iOS native callout menu obscuring highlight toolbar — Added
-webkit-touch-callout: noneto the reader iframe CSS. On iOS, this suppresses the system "Look Up / Copy / Share" bubble that appeared over Theorem's ownHighlightColorPickertoolbar after text selection. Native selection handles and the magnifying loupe remain fully functional.
Theorem v1.4.2
Fixed
- Touch selection & swipe gesture decoupling — Fixed glitching and accidental page turns when selecting text to highlight using touch/stylus. In
paginator.js, a finger hold (>180ms) now locks the gesture into selection mode and prevents swiping; swipe movement threshold was raised from 8px to 20px with horizontal dominance requirements; and active selections automatically snap the viewport back to full-page alignment if displaced. - Removed duplicate FoliateEngine swipe handler — Stripped redundant
touchendpage-turning logic infoliate-engine.tsthat competed with Paginator and triggered false page-turns during selection drag gestures. - Non-blocking highlight overlays — Highlight SVG elements now use
pointer-events: none, allowing native touch and mouse selection to freely pass through or cross over existing highlights without interference. Highlight taps continue to be resolved via native document click hit-testing.