Remove all Dexie/IndexedDB code and dependencies, including document and preview caches, local config, onboarding, and migration logic. Replace with server-backed React Query hooks for documents, folders, preferences, onboarding, and progress. Add browser Cache Storage for blob caching of documents, previews, and audio. Update API routes, database schema, and tests to support folder management, onboarding state, and server-side persistence of all user data. Refactor UI and hooks to use server state exclusively, ensuring all user state is synced and portable across devices.
BREAKING CHANGE: All user data, preferences, onboarding, and document state are now stored and synced on the server; browser IndexedDB is no longer used. Existing local-only data will not be available after this update.
- Extract database schema and migrations into @openreader/database
- Extract startup and orchestration scripts into @openreader/bootstrap
- Move compute-worker into packages/compute-worker
- Remove runtime dependency on drizzle-kit
- Update Dockerfile to deploy isolated packages without merging node_modules
- Removed deprecated functions related to document parsing and blob storage in blobstore.ts.
- Introduced new PDF rendering logic in pdf-preview-renderer.ts and pdf-preview-pdfjs-runtime.ts.
- Updated previews-render.ts to utilize the new PDF rendering functions.
- Refactored user-whisper-align-job.ts to use the compute-worker client for alignment requests.
- Enhanced artifact.ts and operation.ts to validate parsed PDF artifacts and resolve current PDF parses.
- Updated snapshot.ts to align with new worker operation types.
- Adjusted runtime-config.ts to check for compute-worker availability.
- Modified types in parsed-pdf.ts and tts.ts to reflect changes in the compute-worker protocol.
- Added unit tests for PDF artifact validation and compute-worker client contract.
- Removed obsolete pdf-op-key.vitest.spec.ts test file.
Adds 'speech-sdk' as a fifth built-in TTS provider backed by @speech-sdk/core
(Apache 2.0). Models use the provider/model format; requests go from the
server directly to the provider's API with the user's own key. Existing
providers, defaults, and config are untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Switch SSRF protection in web-loader to use @microsoft/antissrf, removing
custom IP range logic. This centralizes and future-proofs SSRF mitigation by
leveraging maintained policy sets and DNS-aware enforcement. Error handling in
the import-url API route is updated to recognize new policy error messages.
Dependency added to package.json.
Introduce a unified upload menu dialog enabling users to upload files,
create markdown/text documents, or import content directly from web URLs.
Implement a secure server-side loader for fetching and parsing web pages
with SSRF protection, content-type checks, and size limits. Add new API
route for importing documents from URLs, and update dependencies to
support HTML parsing and markdown conversion.
- Add UploadMenuDialog component with file, create, and URL import tabs
- Implement SSRF-mitigated web-loader using linkedom, readability, turndown
- Add /api/documents/import-url endpoint for web imports
- Update DocumentList to use new upload dialog
- Add BrowserIcon and supporting UI elements
- Update dependencies: @mozilla/readability, linkedom, turndown
- Expose importUrl client API
This improves document onboarding flexibility and enhances security for
web-based imports.
Refactor Dockerfile to optimize layering, embed entrypoint migration tools and compute worker as deployable bundles, and merge only required dependencies for runtime scripts. Add docker/entrypoint-migration-tools package and update workspace configuration. Refactor PDF parsing to resolve standard font data path robustly at runtime. Update dependencies and output config for Next.js standalone mode. Enhance entrypoint script to launch embedded compute worker from deployed bundle.
- Dockerfile now deploys migration tools and compute worker as separate bundles
- compute/core/pdf uses new pdfjs-runtime utility for robust font path resolution
- docker/entrypoint-migration-tools added for migration script dependencies
- scripts/openreader-entrypoint.mjs launches embedded worker from deployed bundle
- next.config.ts enables standalone output and includes standard_fonts in tracing
- Dependency updates across package.json and compute/worker/package.json
BREAKING CHANGE: Docker image structure and runtime entrypoint logic have changed; custom deployment scripts or Docker overrides may require updates.
move worker startup logic from server.ts to runtime.ts for better modularity
add worker-loop-policy.ts for loop control abstraction
delete legacy unit tests under tests/unit/ related to compute worker and control-plane
add vitest config and test directories for compute-core and compute-worker
add vitest workflow for CI
update package.json scripts for new test commands and add vitest as dev dependency
BREAKING CHANGE: worker entrypoint is now compute/worker/src/runtime.ts instead of server.ts; legacy Playwright-based unit tests for compute worker are removed in favor of Vitest
Revamp the document list experience by introducing a Finder-style window
interface with multiple views (icons, list, columns, gallery) and a new
sidebar filter system. Remove legacy folder and list item components in
favor of modular, windowed views. Integrate react-dnd-touch-backend and
custom DnD context for improved drag-and-drop, including mobile support.
Update uploader and dialog styles for consistency. Extend document types
to support new view modes, icon sizing, and sidebar state.
Introduce `serverLogger` utility based on pino for consistent, structured logging across all server and API modules. Replace direct console logging with `serverLogger` and add request-scoped logging helpers. Update environment variable handling, documentation, and deployment guides to reflect new logging configuration (`LOG_FORMAT`, `LOG_LEVEL`, `COMPUTE_LOG_LEVEL`). Enforce no-console in server code via ESLint and add pino/pino-pretty dependencies.
This change standardizes log output, improves observability, and prepares the codebase for ingestion by log platforms.
Restructure compute core by extracting job contracts and runtime logic into separate
modules (`contracts.ts`, `local-runtime.ts`) for improved modularity and clearer
API boundaries. Update exports and imports across worker, server, and local
compute backends to use the new modules. Enhance Next.js config to support
dynamic backend selection via build-time constants and aliasing, enabling
seamless switching between local and worker compute modes. Adjust TypeScript
paths and Dockerfile entrypoint to align with the new structure.
Replace Redis and BullMQ with NATS JetStream and KV for job queuing and state management
in the compute worker service. Update environment variables, Docker Compose, and documentation
to reflect the new message queue backend. Adjust dependencies and code to use NATS-based
work queue and key-value storage for durable job processing.
This change improves scalability and reliability of distributed compute workloads by leveraging
NATS JetStream's work queue and persistence features. Documentation and configuration examples
are updated to guide deployments using the new backend.
Introduce support for external compute worker mode (`COMPUTE_MODE=worker`) using a new `WorkerComputeBackend`. This enables offloading heavy ONNX Whisper alignment and PDF layout parsing to a standalone worker service (Redis + BullMQ), improving scalability and compatibility with serverless/limited environments.
- Add `@openreader/compute-core` as a shared package for ONNX inference and PDF parsing logic.
- Implement `WorkerComputeBackend` and worker contract/types for remote job execution.
- Update compute backend selection logic and remove previous worker mode guards.
- Extend `WhisperAlignInput` and `PdfLayoutInput` types to support object keys for remote data access.
- Refactor local compute backend to use `@openreader/compute-core` and support both buffer and object key inputs.
- Update job runner, TTS segment alignment, and PDF layout parsing flows to use new compute backend APIs.
- Add scripts, Docker workflow, and documentation for deploying and running the compute worker.
- Update environment variable docs and examples for worker mode, including storage requirements and configuration.
- Document published images and stack changes to reflect the new compute worker architecture.
BREAKING CHANGE: `COMPUTE_MODE=worker` now requires an external compute worker service and S3-compatible object storage. Embedded SeaweedFS (`weed mini`) is not supported in worker mode. See the new documentation for deployment and configuration details.
Replace the previous whisper.cpp-based word alignment with a fully ONNX-based
implementation using onnxruntime-node and @huggingface/tokenizers. Add new
Whisper ONNX model management, alignment mapping, and spectral analysis modules.
Remove all code and documentation referencing whisper.cpp, update environment
variables, Dockerfile, and docs to reflect ONNX-only alignment. Add unit tests
for alignment and ONNX model logic.
Migrate PDF parsing to use ONNX Docling layout model for structured block extraction, enabling improved TTS segmentation and chaptering. Add compute backend abstraction for heavy tasks (alignment, layout parsing) with configuration via `OPENREADER_COMPUTE_MODE`. Integrate block-level locators and document settings for per-document PDF parsing options. Update S3 storage for parsed PDF JSON, add migration and schema changes, and extend client and server APIs for parsed data and settings. Remove legacy word highlight flag in favor of compute capability detection.
- Add ONNX model download, local/none compute modes, and `onnxruntime-node` dependency
- Update PDF viewer and TTS pipeline to use parsed blocks and block-level locators
- Add document settings storage and APIs for per-document PDF options
- Update S3 storage layout for parsed PDF JSON
- Add admin/config/docs updates for new compute and parsing features
- Remove obsolete word highlight runtime flag and UI
BREAKING CHANGE: PDF parsing and word highlighting now require `OPENREADER_COMPUTE_MODE=local` and ONNX model; document settings and S3 layout updated; legacy word highlight flag removed.
Update GitHub Actions workflows to latest action versions and improve pnpm usage by introducing per-package workspace configs. Add docs-site/pnpm-workspace.yaml and update Dockerfile/package.json for better monorepo support. Upgrade dependencies across main and docs-site packages for compatibility and security. Refine TypeScript types and hooks for improved type safety and maintainability.
Adopt @tanstack/react-query for data fetching and cache management in admin
settings, provider management, shared provider hooks, and context providers.
Replace legacy useState/useEffect data loading with react-query's useQuery and
useMutation patterns. Refactor document, rate-limit, and shared provider
contexts to use query keys and cache invalidation for consistent state across
the app. Add QueryClientProvider to root providers. Update package.json to
include react-query dependency.
- Updated environment variables documentation to include Replicate as a TTS provider option.
- Added Replicate to the sidebar for TTS provider guides.
- Included Replicate as a dependency in package.json and pnpm-lock.yaml.
- Enhanced audiobook chapter generation to normalize native speed settings based on the TTS provider.
- Improved error handling in TTS API routes to provide retry information for rate-limited responses.
- Updated AudiobookExportModal to reflect native speed support for Replicate models.
- Modified SettingsModal to set default model for Replicate.
- Enhanced SpeedControl component to conditionally render native speed controls based on provider support.
- Updated TTSContext to utilize effective native speed for TTS requests.
- Implemented Replicate request handling in the TTS generation logic.
- Added new documentation for configuring Replicate as a TTS provider.
Add ZIP-based user data download endpoint, enable AES-256 server-side S3 encryption for all stored documents and audiobooks. Rewrite privacy policy with detailed CCPA categories, service provider disclosures (Vercel/Neon/Railway), and user rights sections. Replace privacy modal with checkbox agreement flow.
Replace ffprobe-static with ffmpeg-static for metadata extraction in
migration scripts. This removes the requirement for ffprobe binaries
across Docker, CI, and Vercel environments, simplifying the dependency
graph.
- Add document preview caching logic with in-memory and persisted storage.
- Implement S3 blobstore functions for managing document previews.
- Create rendering functions for PDF and EPUB cover images to JPEG format.
- Introduce database schema and functions for managing document preview metadata.
- Add unit tests for rendering PDF and EPUB previews.
Configure Next.js output tracing to properly include ffmpeg and ffprobe
static binaries for audiobook processing endpoints. This ensures the
required binaries are bundled correctly during deployment across all
audiobook API routes.
This commit restructures the audiobook generation and serving layer to rely exclusively on S3-compatible blob storage, removing the dependency on local filesystem paths.
- Bundle `ffmpeg` and `ffprobe` binaries via npm to ensure portability across environments.
- Update API routes to stream audio directly from blob storage instead of local disk.
- Remove legacy migration endpoints and filesystem-based indexing logic.
- Add startup scripts to facilitate the transition from local to remote storage.
BREAKING CHANGE: Audiobook functionality is now strictly dependent on S3 configuration. The previous filesystem-based storage method has been removed.
Replaces local filesystem document storage with S3-compatible object storage.
Adds embedded SeaweedFS 'weed mini' for local development and Docker deployments.
Updates document upload flow to use presigned URLs with a server fallback proxy.
Refactors auth configuration to use BASE_URL and AUTH_SECRET.
BREAKING CHANGE: Renamed BETTER_AUTH_URL to BASE_URL and BETTER_AUTH_SECRET to AUTH_SECRET. Removed legacy document upload/content endpoints. Requires S3 environment variables (auto-configured for embedded SeaweedFS).
- replace custom DB adapter with Drizzle setup (SQLite/Postgres schemas) and add `drizzle.config.ts` plus migrations in `drizzle/` and `drizzle_pg/`
- switch better-auth to drizzleAdapter, add auth helpers (`getAuthContext`, `requireAuthContext`, `requireAudiobookOwned`), and make `useAuth`/`useAuthSession` safe no-ops when auth is disabled
- persist documents/audiobooks in DB with ownership checks, unclaimed fallback, and ref-counted deletes; add FS scan helper for no-auth mode
- gate docx-to-pdf, library, voices, whisper, and migration endpoints behind auth when enabled
- add unclaimed data scan/claim flow with `/api/user/claim`, `ClaimDataModal`, and server-side scan/claim helpers
- refactor rate limiting and account deletion to use Drizzle tables (`user_tts_chars`, `user`)
- run migrations via `scripts/migrate-if-auth.mjs` (auto on `pnpm start` + `pnpm migrate`), remove Docker entrypoint and old better-auth migration file
- update README and lockfile for the new migration workflow and dependencies
- Implement user sign-in, sign-up, and account management using better-auth
- Add rate limiting for TTS API with daily character limits for authenticated and anonymous users
- Integrate SQLite and PostgreSQL database support for user sessions and data persistence
- Update UI components to include authentication flows, user menu, and privacy popup
- Modify Dockerfile and package.json for new dependencies and entrypoint script
- Bump version to v1.3.0
- Introduces `DocumentPreview` component to display rich previews for documents.
- PDFs generate a thumbnail of their first page.
- EPUBs extract and display their cover image.
- HTML, TXT, and Markdown files show a text snippet.
- Refactors document list and folder views to a responsive grid layout.
- Expands main content areas to accommodate the new grid.
- Updates Dockerfile to use Node.js LTS image.
- Updates various development and runtime dependencies.
Replaces custom IndexedDB implementation with Dexie ORM, eliminating 850+ lines of
boilerplate code and introducing reactive live queries across all document types.
Transforms document management from imperative refresh patterns to automatic
reactive updates using dexie-react-hooks.
Simplifies TTS backend by removing concurrency semaphore while maintaining
request de-duplication through in-flight tracking. Streamlines document hooks
by removing manual state management and refresh methods.
Updates package dependencies and type definitions to support new database
architecture while maintaining full backward compatibility for existing
documents and settings.
BREAKING CHANGE: Document hooks no longer expose refresh() methods as updates
are now reactive through live queries.
- Created `issues-to-components.md` to summarize open issues and their mappings to components for v1 development.
- Documented key features, bugs, and proposed solutions for issues #59, #48, #47, #44, and #40.
- Outlined global guardrails and cross-cutting improvements for the v1 architecture.
chore: Establish v1 todo and planning framework
- Created `todo.md` to capture the 1.0 rewrite plan, including scope, architecture overview, phased milestones, and a master checklist.
- Defined action items, dependency ordering, and issue mapping alignment for efficient development.
chore: Update pnpm workspace configuration
- Added `ignoredBuiltDependencies` for `canvas` in `pnpm-workspace.yaml` to prevent build issues.
Add comprehensive multi-provider TTS support enabling users to choose between OpenAI, Deepinfra, and custom OpenAI-compatible endpoints. Implement provider-specific voice management with automatic voice restoration per provider-model combination, and migrate package manager to pnpm for improved dependency handling.
Key changes:
- Add TTS provider selection (OpenAI, Deepinfra, custom-openai) in settings UI
- Implement provider-specific model and voice lists with dynamic fetching
- Add voice persistence per provider-model combination in savedVoices
- Support Deepinfra models: Kokoro-82M, Orpheus-3B, Sesame-1B with their voice libraries
- Migrate to pnpm with frozen lockfile for reproducible builds
- Update Docker configuration to use pnpm and Deepinfra API defaults
- Add migration logic for existing users to infer provider from stored baseUrl
- Update test helpers and Playwright configuration for Deepinfra API
- Add example docker-compose.yml with Kokoro-FastAPI integration
BREAKING CHANGE: Voice selection is now provider-model specific. Previously saved voices will be migrated to the new savedVoices structure, but users may need to reselect voices if switching providers.