Skip to content

v0.0.4 — co-edit polish + large-file pipeline + UX rounds 1–7

Choose a tag to compare

@schnsrw schnsrw released this 18 May 18:48
· 299 commits to main since this release
a547b70

Highlights

Co-editing

  • Polished share dialog — file picker / password / role (edit | view-only), two copyable share URLs, password stash so the owner skips their own prompt.
  • Presence in the title bar — avatar stack with initials, color per peer, "Active now / Last seen Ns ago" tooltips, idle fade past 8 s.
  • Live cursors on the grid — peer selection rendered as a colored rect with name label, tracks scroll via api.Event.Scroll.
  • Live-typing ghost — peers see characters appear in your cell as you type, not just on commit. 30 ms-throttled awareness broadcast on SheetEditChanging.
  • View-only role — joiner's edits stay local; bridge skips outbound op-log writes.
  • Server: SHA-256 + timingSafeEqual password gate on the WS upgrade; /api/rooms/:id/info preflight; /seed + /snapshot upload+fetch.

Large-file pipeline (docs/LARGE_FILE_PIPELINE.md)

  • Stage 0initialFormulaComputing: NO_CALCULATION, INITIAL_COLUMNS 128 → 26, single wb.save() per export.
  • Stage 1 — xlsx parser in a Web Worker.
  • Stage 1b — xlsx exporter in a Web Worker. Main bundle 8.3 MB → 6.3 MB (ExcelJS now only in worker chunks).
  • Stage 2 — server-cached gzipped IWorkbookData snapshot for joiners; skips ExcelJS entirely on the fast path.
  • Stage 3WorkbookMeta + snapshotRef: full IWorkbookData no longer lives in React state alongside Univer's copy. ~30–50% peak heap cut on big files.
  • Stage 4 — lazy plugin loader. CF / DV / hyperlink / drawing / note / thread-comment / table / sort / filter / find-replace each ship as their own chunk. Eager-loaded on snapshot inspection when the workbook needs them.
  • Stage 5 — hyperlinks inline in cell.p.body.customRanges; no more O(N) AddHyperLinkCommand replay at mount.
  • Stage 7apps/web/src/perf.ts profiling harness wrapping the five hot paths, locked in by perf-harness.spec.ts.
  • Op-log batching — collab bridge transacts a microtask's worth of mutations. One paste / sort / fill = one Yjs encode = one WS frame.
  • Selection-stats cap — Cmd+A on a million-row sheet no longer freezes computing Count / Sum / Avg.

Loading + error UX

  • Phase-aware loading overlay — "Reading file…" → "Parsing…" → "Loading into editor…", with elapsed timer, step indicator, and a "this is a large workbook" hint above VITE_SOFT_WARN_MB.
  • Hard reject above VITE_MAX_OPEN_MB (default 100 MB) instead of letting the worker OOM-crash the tab.
  • Retry button on the error card.

Excel-fidelity UX + 7 polish rounds

  • Range picker, keybindings, toolbar overflow + shortcut hints, disabled-state contrast, tooltip snappiness, dialog focus trap + scroll lock, hidden-sheet visibility + unhide affordance, peer label collision avoidance, multi-line formula paste, Excel-paste merge / column-width / row-height preservation, tables empty-state CTA.

Configuration

New .env.example documents every knob — wired through docker-compose.yml (env + build args) and Dockerfile:

Knob Default What for
MAX_UPLOAD_MB 100 Server seed/snapshot upload cap
ROOM_TTL_MIN 15 Idle room eviction window
REDIS_URL unset Y.Doc persistence (7-day TTL)
VITE_MAX_OPEN_MB 100 Hard reject for File → Open
VITE_SOFT_WARN_MB 25 "Large workbook" hint threshold
VITE_COLLAB_ENABLED 1 (Docker) / unset (Pages) Ship co-edit code

Docker

```sh
docker run --rm -p 3000:3000 schnsrw/casual-sheets:0.0.4
```
Note: :0.0.4 lands on Docker Hub once the Publish Docker image workflow succeeds — currently blocked on DOCKERHUB_USERNAME / DOCKERHUB_TOKEN secrets being added to the repo's Actions scope.

Tests

181 Playwright specs passing (+ 4 fixme).

Full diff

`v0.0.3...v0.0.4`