Research: extracting the calternal.js block editor as packages/editor #4

Closed
opened 2026-09-24 07:05:41 +00:00 by kayg · 8 comments
Owner

Codex job editor-study. Task brief lives with the orchestrator; the job comments progress here.

Base: 5f15b1e66a

Codex job `editor-study`. Task brief lives with the orchestrator; the job comments progress here. Base: 5f15b1e66ac9f1e781add30ed77a2594dda4472e
Author
Owner

Starting the read-only editor extraction study on branch handover/2026-09-22.
Current HEAD: 62276d132fcc9e28643adc4525e287eaa2db4af0.
Issue base recorded here: 5f15b1e66ac9f1e781add30ed77a2594dda4472e.
No repository files will change.

Starting the read-only editor extraction study on branch `handover/2026-09-22`. Current HEAD: `62276d132fcc9e28643adc4525e287eaa2db4af0`. Issue base recorded here: `5f15b1e66ac9f1e781add30ed77a2594dda4472e`. No repository files will change.
Author
Owner

Finding: the editor's Markdown parser and serializer already run in TypeScript. packages/web/src/lib/editor/markdown.ts (1,865 lines) owns Markdown structure and inline marks. bridge.ts calls Rust canonicalizeMarkdown after serialization. packages/core/src/markdown.rs (527 lines) only splits blocks at blank lines, preserves each block's text, and lifts/re-emits trailing ^block-id; it is not the full Markdown parser. This supports extracting the existing TS pair and removing the old WASM crossing. Evidence: markdown.ts lines 1-17 and bridge.ts lines 1-10, 43-80; markdown.rs lines 1-35, 86-117.

Finding: the editor's Markdown parser and serializer already run in TypeScript. `packages/web/src/lib/editor/markdown.ts` (1,865 lines) owns Markdown structure and inline marks. `bridge.ts` calls Rust `canonicalizeMarkdown` after serialization. `packages/core/src/markdown.rs` (527 lines) only splits blocks at blank lines, preserves each block's text, and lifts/re-emits trailing `^block-id`; it is not the full Markdown parser. This supports extracting the existing TS pair and removing the old WASM crossing. Evidence: `markdown.ts` lines 1-17 and `bridge.ts` lines 1-10, 43-80; `markdown.rs` lines 1-35, 86-117.
Author
Owner

Finding: extraction is not a move of one small component. The shared surface is 4,538 lines and the Notes host is 3,167 lines. EditorSurface.svelte imports app Pill/EntryMenu, shortcut handling and $lib/time; NoteEditor.svelte owns DB reads/writes, frontmatter, sync reconciliation and app stores. The composer adapter is also used by Composer.svelte and FeedShell.svelte. Keep those persistence and product flows in the new app; extract the editor surface behind callbacks and injected resolvers. Evidence: EditorSurface.svelte lines 1-120; NoteEditor.svelte lines 85-230; composerNoteSession.ts and its callers.

Finding: extraction is not a move of one small component. The shared surface is 4,538 lines and the Notes host is 3,167 lines. `EditorSurface.svelte` imports app `Pill`/`EntryMenu`, shortcut handling and `$lib/time`; `NoteEditor.svelte` owns DB reads/writes, frontmatter, sync reconciliation and app stores. The composer adapter is also used by `Composer.svelte` and `FeedShell.svelte`. Keep those persistence and product flows in the new app; extract the editor surface behind callbacks and injected resolvers. Evidence: `EditorSurface.svelte` lines 1-120; `NoteEditor.svelte` lines 85-230; `composerNoteSession.ts` and its callers.
Author
Owner

Finding: there is no Yjs or collaboration package or API in the current web/core source. Collaboration will add a new binding. The current StarterKit.configure() does not disable its undo extension; Tiptap's Collaboration extension supplies shared undo/redo and its docs say to disable StarterKit's UndoRedo. Custom Svelte node views and selection/card decorations are local ProseMirror view state, so they need tests for remote attribute edits, position mapping, and stale drag/selection cancellation. Evidence: packages/web/package.json and bun.lock have no Yjs packages; extensions.ts lines 883-944; Tiptap Collaboration docs: https://tiptap.dev/docs/editor/extensions/functionality/collaboration.

Finding: there is no Yjs or collaboration package or API in the current web/core source. Collaboration will add a new binding. The current `StarterKit.configure()` does not disable its undo extension; Tiptap's Collaboration extension supplies shared undo/redo and its docs say to disable StarterKit's `UndoRedo`. Custom Svelte node views and selection/card decorations are local ProseMirror view state, so they need tests for remote attribute edits, position mapping, and stale drag/selection cancellation. Evidence: `packages/web/package.json` and `bun.lock` have no Yjs packages; `extensions.ts` lines 883-944; Tiptap Collaboration docs: https://tiptap.dev/docs/editor/extensions/functionality/collaboration.
Author
Owner

Finding: round-trip is lossless for canonical Markdown that the writer produced and for supported schema content, but not for arbitrary source spelling. The contract documents whitespace trimming, dropped edge blank blocks, LF normalization, table alignment loss, and cell-span normalization. Frontmatter is split outside the editor. The new package must carry these rules as test vectors or choose a new contract. Evidence: docs/contracts.md lines 2986-3060 and markdown.ts lines 1-78, 1238-1260.

Finding: round-trip is lossless for canonical Markdown that the writer produced and for supported schema content, but not for arbitrary source spelling. The contract documents whitespace trimming, dropped edge blank blocks, LF normalization, table alignment loss, and cell-span normalization. Frontmatter is split outside the editor. The new package must carry these rules as test vectors or choose a new contract. Evidence: `docs/contracts.md` lines 2986-3060 and `markdown.ts` lines 1-78, 1238-1260.
Author
Owner

Finding: recommend a shared contracts/vectors/markdown/ corpus as the cross-language compatibility gate. Keep the browser's existing TypeScript parser/serializer and write the matching Yrs XML fragment conversion in Rust. The server is a Rust binary and must materialize Markdown files, so running the TypeScript serializer on the server would add a JS runtime. Plain-text diffing alone cannot create or read the structured TipTap document. Each vector should include source Markdown, expected normalized ProseMirror JSON, and exact serialized Markdown; test those through both the TypeScript adapter and Yrs conversion. Then add a live Yjs/Yrs update compatibility test. Evidence: calternal/docs/DESIGN.md §§2, 3, 9, and the current round-trip contract in docs/contracts.md.

Finding: recommend a shared `contracts/vectors/markdown/` corpus as the cross-language compatibility gate. Keep the browser's existing TypeScript parser/serializer and write the matching Yrs XML fragment conversion in Rust. The server is a Rust binary and must materialize Markdown files, so running the TypeScript serializer on the server would add a JS runtime. Plain-text diffing alone cannot create or read the structured TipTap document. Each vector should include source Markdown, expected normalized ProseMirror JSON, and exact serialized Markdown; test those through both the TypeScript adapter and Yrs conversion. Then add a live Yjs/Yrs update compatibility test. Evidence: `calternal/docs/DESIGN.md` §§2, 3, 9, and the current round-trip contract in `docs/contracts.md`.
Author
Owner

Finished the read-only editor extraction study.
HEAD SHA: 62276d132fcc9e28643adc4525e287eaa2db4af0.
Gate output: Not run — READ ONLY extraction study; no code changed, and no build or test command was run.
No repository files changed. I left the pre-existing handover worktree changes untouched.

Finished the read-only editor extraction study. HEAD SHA: `62276d132fcc9e28643adc4525e287eaa2db4af0`. Gate output: Not run — READ ONLY extraction study; no code changed, and no build or test command was run. No repository files changed. I left the pre-existing handover worktree changes untouched.
Author
Owner

Research is complete in the issue report. packages/editor is present on origin/dev, and DESIGN §§3 and 9 record its ownership and role.

Research is complete in the issue report. `packages/editor` is present on origin/dev, and DESIGN §§3 and 9 record its ownership and role.
kayg closed this issue 2026-10-03 11:55:01 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#4
No description provided.