Skip to content

Releases: rainhuang0220/wePaper

v1.7.0 — Automatic Zotero sync

Choose a tag to compare

@rainhuang0220 rainhuang0220 released this 08 Sep 07:43

Automatic near-real-time Zotero synchronization and live catalog refresh.

What changed

  • A background daemon polls Zotero Last-Modified-Version, debounces writes, then reconciles the configured collection. Startup, a 5-minute reconcile, and sleep/wake catch-up cover missed events.
  • The previous LaunchAgent died on transient network errors (thousands of exit-1 respawns). The process now retries instead of exiting, and launchd uses an isolated venv plus crash-only KeepAlive.
  • wepaper daemon install|uninstall|status and wepaper status show whether automatic sync is alive. The plist does not embed the sync token.
  • Public GET /api/v1/library/version. An already-open catalog tab updates in place within a few seconds and keeps search/filters. Visibility/focus runs an immediate check.

wepaper sync --once remains for diagnostics and repair. It is not the normal workflow.

This is interval-based (seconds), not sub-100ms realtime.

v1.6.0 — mobile recovery, open status, paper discussions

Choose a tag to compare

@rainhuang0220 rainhuang0220 released this 07 Sep 14:19

What’s new

v1.6.0 recovers mobile reading and adds lightweight paper discussions. Desktop PDF behavior is unchanged.

  • Mobile recovery. The broken v1.5 Android inline viewer is no longer the default. Every device uses Library → /paper/:id → 302 → /paper/:id/pdf.
  • Raw PDF fallback. Mobile may display the file in the browser or offer a download. That is the shipped safe path, not a bug. wePaper does not claim a reliable inline Android viewer.
  • Reading status. 待泛读 / 待精读 / 泛读中 / 精读中 / 已泛读 / 已精读. Any visitor can set or clear a label from the catalog. /owner is gone.
  • Discussions. Each paper has comments, one-level replies, and likes at /paper/:id/discussion. Desktop and mobile: 评论 · N. Mobile: long-press the title (a normal tap still opens the PDF).
  • No accounts. Status and comments are intentionally open for a small audience. Writes are validated; they are not authenticated.
  • Test isolation. Automated status/comment tests use a fixture database. They do not write the production papers.

Tests

uv run pytest (83 passed). Playwright E2E on an isolated server (18 passed, 12 skipped opt-in benches).

Known limitation

No real Android Chrome/WebView inline viewer was verified. Mobile stays on raw PDF.

Demo: https://wepaper.plainlist.space

v1.5.0 — mobile inline reader and reading status

Choose a tag to compare

@rainhuang0220 rainhuang0220 released this 07 Sep 11:37

Superseded by v1.6.0. Mobile default is now 302 → raw PDF. Reading status is openly editable. /owner was removed.

Summary (historical)

  • Desktop still reads papers in the browser-native PDF viewer: Library → /paper/:id → 302 → /paper/:id/pdf.
  • Mobile opened the same canonical /paper/:id URL in a lazy official Mozilla PDF.js viewer (pdfjs-dist@5.7.284). That default later failed on real Android (“The PDF could not be opened.”).
  • /paper/:id/pdf remained raw application/pdf (Range / 206) on every device.
  • Owner reading-status labels (待泛读 / 待精读 / 泛读中 / 精读中 / 已泛读 / 已精读) were server-persisted and only editable after /owner sign-in.

Production: https://wepaper.plainlist.space
Code commit: 4bdc8b47c3f37c4028388323211f1eb9afdbe414
Release commit: a4ce6edf873156f8e16b5f557d5a462091acc81b

v1.4.0

Choose a tag to compare

@rainhuang0220 rainhuang0220 released this 07 Sep 07:24

Summary

  • Paper titles now open native PDF directly (/paper/:id/pdf).
  • /paper/:id redirects (HTTP 302) to the native PDF route.
  • Native PDF is now the default reading experience.
  • The in-app PDF.js viewer is removed.

Notes

Click a catalog title to read the real PDF in the browser. Bookmarked /paper/:id URLs land on the same native PDF. There is no second “Open PDF” click and no in-app canvas viewer.

v1.3.0 — official PDF.js viewer

Choose a tag to compare

@rainhuang0220 rainhuang0220 released this 07 Sep 06:36

Default reader migrated from the custom canvas renderer to Mozilla's official PDF.js viewer layer (PDFViewer + EventBus + find/history/link services).

Clicking a paper title on https://wepaper.plainlist.space now opens /paper/:id in that mature reader immediately. Open PDF remains a secondary action for the raw /paper/:id/pdf bytes (browser-native view, print, download).

The old custom stack is gone (PdfReader, canvasScale 32M ceiling, zoomSteps, pdfWindow, findHits). Zoom, search, continuous scroll, and high-DPI detail canvas are owned by pdf.js. V1.2 Range transport and first-page timing are unchanged.

Public cold-open (click → readable page 1): desktop P50 1410 ms / P95 2365 ms; mobile P50 1350 ms / P95 2334 ms. Gate remains P50 ≤ 2.0 s / P95 ≤ 3.0 s.

Commit: d1a563e
Production JS: /assets/index-Bu5KI4pS.js
SHA-256: 6e966ea60288122193c93ef15f95faf9ef92c656d4b3443bafb1cefb77558f09

wePaper v1.2.2

Choose a tag to compare

@rainhuang0220 rainhuang0220 released this 06 Sep 19:39

wePaper v1.2.2

Follow-up to v1.2.1 after re-measuring against the real production IP (175.24.134.228). Clash’s fake-IP path had made v1.2.1 benches look faster than production.

Root cause

A single Range of ~378–512 KB on this path takes ~3.5 s. doc.getData() (Cache API persist) also started before the first canvas paint and contended with page 1.

Fix

  • Custom PDFDataRangeTransport that never issues a Range larger than 256 KiB
  • Persist the full PDF only after [data-ready=true]
  • Playwright benches pin DNS to 175.24.134.228

Isolated cold catalog click (real IP)

Paper Desktop Mobile
228 KB 1336 ms 846 ms
2.7 MB 1377 ms 2360 ms
1.9 MB 1861 ms 1343 ms
5.6 MB 1855 ms 1855 ms

Desktop P50 1.38 s / P95 1.86 s. Mobile P50 1.34 s / P95 2.36 s.
Warm reload of the 2.7 MB paper: 308 ms.

Public library: https://wepaper.plainlist.space

wePaper v1.2.1

Choose a tag to compare

@rainhuang0220 rainhuang0220 released this 06 Sep 19:25

wePaper v1.2.1

Follow-up to v1.2.0 after the adversarial review. Ordinary PDFs under 15 MB now meet the click → readable first page gate on production.

Performance

  • Linearized serve copies (original Zotero checksums unchanged)
  • Range-only PDF.js load (streaming a linearized file still waited on the full GET)
  • Isolated cold catalog clicks, production Chromium:
Paper Desktop Mobile
228 KB 839 ms 840 ms
2.7 MB 2360 ms 1849 ms
1.9 MB 1896 ms 2863 ms
5.6 MB 2355 ms 2854 ms

Desktop P50 1.90 s / P95 2.36 s. Mobile P50 1.85 s / P95 2.86 s.
Warm reload of the 2.7 MB paper: 314 ms.

Fidelity

  • Canvas pixel cap 32M so 300% on a 390×844 @3 viewport is a larger backing store than 200%
  • Zoom still re-renders; continuous scroll / find / select unchanged

Cache

  • If-None-Match → 304
  • Cache API persist after first page

Public library: https://wepaper.plainlist.space

wePaper v1.2.0

Choose a tag to compare

@rainhuang0220 rainhuang0220 released this 06 Sep 19:01

wePaper v1.2.0

Public library: https://wepaper.plainlist.space

First-page performance

  • Reader mounts immediately (no metadata waterfall).
  • PDF.js loads with Range only (disableStream / disableAutoFetch), so page 1 is not held hostage to the rest of the file.
  • Gzip for JS/CSS (PDFs stay uncompressed so byte ranges stay valid).
  • PDF.js worker is module-preloaded.
  • nginx proxy_cache is off for this vhost — a cached 206 can no longer replace a PDF with a 64 KB fragment.

Target for ordinary small papers: click → readable first page P50 ≤ 2.0 s / P95 ≤ 3.0 s. Measured cold opens of a 228 KB paper: ~0.33–0.85 s.

PDF fidelity

  • High-DPI canvas using devicePixelRatio (cap 3, 16M pixel clamp).
  • Zoom 50–400% re-renders the page (not CSS stretch).
  • Continuous vertical scroll, text layer, find, and select preserved.

Zotero sync

Unchanged: Local API → agent → server → public catalog.

Dedicated origin and repository

Security

Public read / bearer write. /openapi.json stays 404. PDF Cache-Control is private so shared proxies do not store Range fragments.