Skip to content

Releases: Fundaments-Work/Theorem

Theorem v1.5.7

Theorem v1.5.7 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 18 Sep 12:25

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 200ms visibility: hidden blanking, restoring immediate synchronous layout rendering and zero-latency #turnPage resolution.
    • Fixed CSS multi-column fragmentation: removed break-inside: avoid and -webkit-column-break-inside: avoid on parent <p>, <div>, and <figure> containers that caused the browser column formatter to abandon columns and generate blank pages before images.
    • Removed display: block and height: auto !important overrides on img elements, preserving natural aspect ratios and fluid column fitting with object-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.
  • 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 against deletion_tombstones and deletedAt metadata, returning an explicit PEER_BOOK_DELETED status if a requested book has been deleted.
    • In src/core/lib/sync-orchestrator.ts, immediately merged incoming deletion_tombstones over Iroh gossip and purged deleted book cards from local state without delay.
    • In src/features/reader/Reader.tsx, handled PEER_BOOK_DELETED by pruning the local ghost card, displaying an informative toast ("This book was deleted on the source device."), and routing to the Library.
  • Android Hardware Back Button Navigation Stack — Intercepted Tauri onCloseRequested / hardware back button events in src/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.

Improved & Performance

  • Note Export Clean Typography & Knap AST Templating
    • In src-tauri/src/vault_export.rs and src/core/lib/vault-sync.ts, cleaned YAML frontmatter to include only essential properties (title, author, type: "theorem-book-highlights", single total_highlights: N, and tags: [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/knap AST template engine in frontend export settings for safe, custom Markdown templates with 0 bytes added to the native Rust binary.
  • SQLite Memory Reclaim & Low-Memory OS Trimming
    • Enhanced native trim_memory command in src-tauri/src/database.rs and lib.rs to run PRAGMA shrink_memory; and PRAGMA wal_checkpoint(PASSIVE); on SQLite connections alongside libc::malloc_trim(0) on Linux and Android Bionic mallopt(-101, 0) (M_PURGE).
    • Wired document.visibilityState === 'hidden' in src/App.tsx to automatically trigger trim_memory whenever Theorem is minimized or backgrounded, preventing background process termination by the Android OS Low Memory Killer (LMK).
  • Native Rust Readability Engine — Integrated Mozilla's Readability port in Rust (readability crate) with full DOM scoring into src-tauri/src/article_extractor.rs, parsing and scoring article HTML in Rust in <3ms.
  • Store & Build Modernization
    • Declared explicit ESM module type ("type": "module") in package.json for full Vite 8 native configuration loader compliance.
    • Optimized O(1) library store lookups in libraryStore.ts via direct iterator access, eliminating transient array allocations during large library hydration.

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

Theorem v1.5.6 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 18 Sep 04:30

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, decoupled tts_engine_preload from 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_unload and a new native trim_memory command calling libc::malloc_trim(0), releasing dormant glibc thread arenas back to the OS kernel.
    • Reaped Linux spd-say and killall child processes in src-tauri/src/tts_linux.rs via detached wait threads, preventing <defunct> zombie process accumulation.
  • 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_db in src-tauri/src/file_transfer.rs querying persist:theorem-library. Theorem stores state under zustand:theorem-library via SQLITE_PERSIST_KEY_PREFIX. Updated queries to check zustand:theorem-library (and fallback variations) to accurately extract desktop-imported book file paths (filePath, storagePath).
    • File Path Normalization & Percent-Decoding: Added normalize_candidate_path in file_transfer.rs handling file:// scheme prefixes, percent-encoded spaces and symbols (percent_decode_str), and Windows drive formats (/C:/... -> C:/...).
    • Direct LAN IP/Port Connection Fallback: Configured EndpointAddr with last_ip and last_port socket addresses in connect_and_request to 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::accept in src-tauri/src/iroh_sync.rs to extract remote IP and port from conn.paths() and record them in PairedDevice, establishing direct LAN addressing immediately upon pairing.
    • Atomic Safe Downloads: Updated download_book_file to stream incoming bytes into a .download.tmp temporary 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 in file_transfer.rs and attached the progress listener on mount in Reader.tsx. Cleared loadedBookIdRef.current upon transfer completion so the reader seamlessly mounts the newly acquired book without stalling on "Book File Not Available".
  • 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 in ReaderViewport.tsx, eliminating mobile WebView gesture arbitration delays.
  • 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/dompurify and @types/uuid (types are now bundled upstream).
    • Updated frontend dependencies to latest versions, including vitest & @vitest/coverage-v8 5.0.1, @tanstack/react-virtual 3.14.13, zod 4.6.5, react-i18next 17.0.14, lucide-react 1.47.0, and jsdom 30.1.0.
    • Updated 44 Rust crates via cargo update to latest compatible releases.
  • Dynamic Deferred Sentry Loading — Refactored src/core/lib/sentry.ts and src/main.tsx to dynamically import @sentry/react only 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 the annotations array subscription from LibraryPage. Prevents full library re-renders (1,000+ cards) when annotations are created, updated, or synced.
    • In Sidebar.tsx, replaced whole-object stats subscriptions with primitive currentStreak selectors, preventing sidebar thrashing during background reading progress flushes.
    • In Reader.tsx, decoupled the feeds array 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.
  • 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), and idx_reading_sessions_date_created ON reading_sessions(session_date DESC, created_at DESC) in src-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 owned EpubMeta fields directly, eliminating redundant heap string clones and pre-inflated chapter map duplication.
    • In src-tauri/src/batch_ingest.rs, moved base64 cover strings directly into NativeBookRecord without cloning.
  • Cloudflare DTO Data Layouts — Applied Box<str> and Box<[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

Theorem v1.5.5 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 14 Sep 12:32

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_book in src-tauri/src/file_transfer.rs to locate books across all local storage targets: materialized book-cache/{id}.book and book-cache/{id}, SQLite books.data BLOBs, book_metadata table entries (filePath, file_path, storagePath, storage_path), and the Zustand library state stored in SQLite kv_store (persist:theorem-library). Replaced in-memory whole-file buffering with zero-RAM-spike streaming from filesystem File handles to QUIC send streams via tokio::io::copy.
  • Cross-Page Text Highlighting in PDF and EPUB Readers (Issue #90) — In PDFAnnotationLayer.tsx, implemented sub-range clipping to textLayerNode with 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 immediate selection.removeAllRanges() with a deferred cleanup (80ms) to allow multiple intersecting page layers to capture their segment of a multi-page selection. In Reader.tsx, updated resolvePickerPosition() to anchor using the last client rect from Range.getClientRects() rather than getBoundingClientRect(), preventing popover menu offset across CSS multi-column paginated layouts.
  • Mobile Immersion Reading and Text-to-Speech on Android (Issue #91) — Handled null voice lists returned by Android's TextToSpeech.getVoices() in TtsAudioPlugin.kt (doSpeak, getVoices, synthesizeToFile) with currentTts.voices?.let { ... }, eliminating unhandled Kotlin NullPointerException crashes when defaultTtsSettings.voice is set. Enabled TTS by default in settingsStore.ts (defaultTtsSettings.enabled: true) and ensured onToggleImmersion is always available for non-PDF books in Reader.tsx, automatically enabling TTS when toggled. Allowed mobile users to access the voice and speed settings popup in ReaderNavbar.tsx on 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) where needsProvision evaluated to false after the first application launch, causing subsequent reading progress mutations and last read timestamps to skip docsSetEntry(). Removed the premature bailout so that per-key diffing against _provisionedValues runs on every sync round, correctly pushing modified progress, currentLocation, and lastReadAt timestamps to iroh-docs and triggering iroh-gossip propagation across connected peers. Updated defaultDeviceSyncSettings in settingsStore.ts to default autoSyncEnabled: true and syncOnConnect: 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

Theorem v1.5.4 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 14 Sep 10:14

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, and tts_audio_get_volume controlling the native Rodio sink and WSOLA buffer stretching directly in Rust, wired dynamically through ImmersionPlayer.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 instant pdf:page:N jump coordinates, falling back cleanly to the JS worker in pure web browsers.
  • Native Readability Article Extractor — Added extract_article_from_html_native in src-tauri/src/article_extractor.rs, executing fast HTML cleaning, article candidate scoring, and metadata extraction via quick-xml directly in Rust.
  • Dynamic Frontend Readability Code-Splitting — Code-split @mozilla/readability and dompurify in ArticleExtractorService.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_entries in src-tauri/src/database.rs, merging incoming Iroh-gossip documents directly inside an atomic SQLite transaction. Directly updates book_metadata, book_annotations, books_fts, and kv_store while cascading deletion_tombstones, eliminating double-hop IPC serialization and preventing Last-Write-Wins collisions.
  • Relational SQLite Vocabulary Storage Subsystem — Added a dedicated normalized vocabulary table in src-tauri/src/database.rs with indexed lookup by (normalized_term, language) and created_at. Automatic idempotent zero-data-loss database migration (run_v154_database_migrations) unpacks existing terms from zustand:theorem-vocabulary into the relational store inside an atomic transaction while preserving the original kv_store blob 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>...) in src-tauri/src/epub_parser.rs using quick-xml. Parses nested chapter hierarchies, resolves intra-book relative hrefs with URL fragments, unescapes entities, and packages the result into compact Box<str> / Option<Box<[TocItemDto]>> Cloudflare data layouts inside prefetch_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.js and epub.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, and onRehydrateStorage in vocabularyStore.ts and sync-orchestrator.ts to 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 the stats subscription from the active component tree and deferred visible word count extraction to requestIdleCallback after 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 in src/features/reader/foliate-js-runtime/paginator.js. Ensured the #locked flag is released in a finally block 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 #goTo calls in paginator.js, preventing spurious Failed to load section warnings 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_attached idempotency flag in src/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.ts and accelerated chrome toggle transitions from 300ms to 150ms ease-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_WINDOW to 50 in src/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 lastGoalNotifiedDate and lastDailyReminderDate in src/core/store/settingsStore.ts and src/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.js where ('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 findRangeByText fallback in src/features/reader/foliate-js-runtime/view.js to reliably render highlights even when DOM restructuring invalidates serialized CFI character offsets.

Improved & Performance

  • Complete Elimination of fuse.js — Removed the fuse.js runtime dependency from package.json and replaced it in src/core/lib/search/fuzzy.ts with 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.ts and tests/paginator-navigation.test.ts with 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

Theorem v1.5.3 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 13 Sep 18:11

Added

  • Hybrid Two-Tier Search Engine (SQLite FTS5 + nucleo-matcher) — Completely replaced JavaScript fuse.js in desktop and mobile environments with a native Rust two-tier search architecture (src-tauri/src/fuzzy_search.rs). Tier 1 leverages SQLite books_fts FTS5 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 zip crate (src-tauri/src/article_epub.rs), eliminating JavaScript fflate (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), and reading_sessions (time-series analytics) in src-tauri/src/database.rs. Automatically and idempotently migrates legacy JSON blobs from kv_store into normalized tables inside an atomic transaction while preserving the original kv_store values as immutable backups.
  • Decoupled Relational RSS & KV Store Footprint Reduction — Decoupled full HTML content from Zustand persistence, shrinking zustand:theorem-rss from 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_window Tauri 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) into cover-extractor.ts and storage.ts, eliminating DOM <canvas> image resizing on desktop and mobile Tauri runtimes.
  • Eliminated JS Fuse.js Overhead — Removed runtime Fuse object instantiation and heap-allocated searchable item caches in filtering.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

Theorem v1.5.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 13 Sep 11:24

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> and Box<[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 image crate (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 use text.char_indices() byte slicing, eliminating transient Vec<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 via Range.getClientRects(), strictly filtering zero-dimension rects across column gutters and multi-column pagination spreads.
  • Foliate Paginator Anchor Stabilization — Locked non-collapsed range anchors to startContainer in paginator.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

Theorem v1.5.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 13 Sep 08:43

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.md structured as a native flashcard deck for the Lemma Obsidian plugin. Frontmatter includes tags: [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

Choose a tag to compare

@github-actions github-actions released this 11 Sep 11:34

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 paused state tracking in Rust's NativePlayer (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

Theorem v1.4.3 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Sep 12:28

Fixed

  • Settings panel hidden by bottom bar on mobile — The FloatingPanel (used for reader settings, bookmarks, TOC, etc.) was rendered with z-[var(--z-dropdown)] (z-50) while the reader's bottom navigation bar uses z-[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. Raised FloatingPanel to z-[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, selectionchange was firing continuously mid-drag, causing the HighlightColorPicker toolbar to appear and disappear repeatedly (visible flicker). The selection capture is now deferred: touchstart sets an isTouchActive flag and selectionchange only updates the navigation lock during an active touch gesture; the actual callback is processed exactly once on touchend. 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: none to the reader iframe CSS. On iOS, this suppresses the system "Look Up / Copy / Share" bubble that appeared over Theorem's own HighlightColorPicker toolbar after text selection. Native selection handles and the magnifying loupe remain fully functional.

Theorem v1.4.2

Theorem v1.4.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Sep 11:15

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 touchend page-turning logic in foliate-engine.ts that 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.