Skip to content

chore: sync upstream cella v0.14.0 (79ee6cde) - #148

Merged
flipvh merged 1 commit into
mainfrom
cella/sync/20261002-1357
Oct 2, 2026
Merged

flipvh merged 1 commit into
mainfrom
cella/sync/20261002-1357

Conversation

@flipvh

@flipvh flipvh commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

Syncs upstream cellajs/cella to 79ee6cd (v0.14.0).

8 upstream commits since last sync (compare):

Migration notes: all 98 handled.

Step 2 of .todos/CELLA_SYNC_BRIEF_20261002.md: cella#1260 (description sync redesign, release 1) and what followed it on cella main. Merged without conflicts. The raak work is in the four sections below.

Summary is now block JSON

tasks.summary now holds the summary block as a one-block BlockNote document, the deriveDocument output, and the client renders it with BlockNoteFullHtml.

  • Backend. deriveDescriptionProps is synchronous and built on deriveDocument (summary, summaryLength and counts), and the server no longer renders HTML with ServerBlockNoteEditor.
    • keywords stays raak's deduplicated extractKeywords word list: server task search matches only that column, and the shared derivation caps keywords at 900 characters.
  • Backfill. Migration 20261002120603_task_summary_block_json is hand-written SQL that mirrors findSummarySource. It writes only changed rows, so a rerun does nothing.
    • It has no RLS wrapper: the migrate role owns tasks, and RLS has not been forced since the 10-rls side effect. Re-forcing RLS the way the July backfills did would block the CDC worker's seq stamps (seen at runtime).
  • Cache. clientCacheVersion → v14-summary-block-json.
  • Other summary readers. The OG cover title and the CSV export use titleFromDocument(summary). Seeds and mocks write block JSON.

Client derivation

  • task/query.ts registers registerDescriptionDerivation('task', …) for summary, summaryLength, expandable, the counts and attachments.
  • It registers the same fields plus keywords as Yjs-owned.
  • The collaborative patch no longer passes extra.
  • Optimistic create and update run the same synchronous derivation, so the create form no longer waits for an HTML render.

Card slot on useDescriptionSlot and <DescriptionLayers>

  • task/card/preserve-description-height.tsx and the outer wrapper in task-card.tsx are gone.
  • Hover warms the editor after 200 ms with the 'hover' reason, and only with edit rights.
  • waitingFallback fades only for editors.

Two changes beyond the note's sketch, both found at runtime:

  • No autoFocus on TaskUpdateForm. tiptap's deferred autofocus moved the cursor to the start after the slot had placed it.
  • The slot's onEditorReady runs one frame late. Dev StrictMode remounts the editor view after the ready effect, which dropped the cursor. fix(blocknote): raak's release 1 adoption findings cella#1276 moves this deferral into the hook; remove the wrapper after that sync.

Auth notes

Notes 1005, 1022 and 1037 need nothing in raak: no raak code imports or mocks the moved auth internals (typecheck is clean, and no stale vi.mock paths remain). They are marked handled.

Before deploying

  • Run select count(*) from tasks on prod first. The backfill is a single UPDATE at about 0.45 ms per row locally, and the new migrate session statement_timeout is 120 s, so it fits up to roughly 250k tasks.
  • The CDC worker logs one task.updated activity (changedFields summary) per backfilled row, as the earlier task backfills did.
  • Deploy the relay and the frontend together (the note's blast radius).

Verification

  • Gates: pnpm check is clean.
    • pnpm test:core: 482 files and 3,916 tests pass, run on this branch.
    • The new task/helpers/description.test.ts (4 tests) pins the backend columns to deriveDocument.
  • Backfill SQL against deriveDocument:
    • 0 mismatches on 13 edge cases and 11,285 sampled dev rows.
    • On 114,771 seeded rows, run as the non-bypass owner role: every row converted with 0 mismatches. A rerun updates 0 rows, and RLS stays enabled and unforced.
  • Runtime: an offset stack with Playwright and three users (admin, member, guest). Everything below passed, unless noted with StrictMode on.
    • Hover: the editor warms invisibly after 200 ms and cools on mouseleave.
    • Click to edit: the cursor lands at the summary end from collapsed and at the click point from expanded, with the editor warm or cold.
    • Leaving edit: Escape collapses. Going from editing to expanded keeps the description visible in every frame at a constant height.
    • Checkboxes on the static: a checkbox toggles, the collapsed counts follow at once, and the relay persists the change. This held warm and cold, with and without StrictMode.
    • Guest: no warm editor, no relay socket, and an unfaded static.
    • Offline mid-edit: the editor stays live with a status line, and the unload guard fires while edits are unsaved and releases after. Back online, the edit reaches the row in 3.5 s.
    • Two users: B's collapsed summary shows A's edit after 3.5 s, and with both editing, keystrokes reach B in 260 ms.

Known gap, fix in progress upstream

The field-stamp guard only protects rows that carry a description stamp, and creates carry none. So the first collaborative edit after a task is created can revert for about 3 s if a stale full-row read (for example, another user's write) lands before the relay saves it. This is reproduced. cellajs/cella#1276 treats a field neither row stamps as unwritten when both rows carry stx.

Drift

  • Before and after: diverged 0, behind 0, drifted 3. All three are fork-marked.
  • No new pinned files.

🤖 Generated with Claude Code

@flipvh
flipvh merged commit f6f1c7f into main Oct 2, 2026
11 checks passed
@flipvh
flipvh deleted the cella/sync/20261002-1357 branch October 2, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant