openpencil/tests/engine/render/canvas
Danila Poyarkov 418457bfb5
feat: preview streamed JSX on the canvas (#692)
* feat: preview streamed JSX on the canvas

Project incomplete JSX into isolated scene graphs and disposable pictures without mutating the document or adding intermediate undo entries. Share placement with final rendering and cover lifecycle and placement parity with AI SDK mocks and visual tests.

* test: require partial input for unfinished coordinates

Assert the complete partial object so rejecting the entire input cannot satisfy the truncated-exponent regression test. Addresses CodeRabbit's review finding on #692.

* feat(ai): keep a chat run on its page across page switches

Page switches go through the editor's preparation flow, and the chat panel treated every preparation as a document change: it dropped its Chat and reloaded history, detaching the panel from a reply still in progress. The panel now keeps the live chat unless the tab or the conversation changes.

AI tools also followed the page on screen, so a user browsing mid-run sent the next edits elsewhere, and the agent's own switch_page affected only one call. A run now pins the page where the message started; switch_page moves the run and the user's view, and streamed previews stay attached to the run's page, which the renderer draws only while that page is on screen.

Page snapshots now restore the page they were taken of, so undoing an AI edit works while another page is visible.

* refactor(core): share picture recording and export preparation with previews

Preview recording reimplemented three pieces Core already had: world-bounds picture recording (also duplicated by render chunks and the retained backing), font and layout preparation (prepareForExport), and page subgraph extraction. Extract recordWorldPicture and withWorldViewport for all three recorders, reuse prepareForExport, and add extractPageContext and findPageChildId next to the other subgraph helpers instead of editing a cloned graph's nodes.

prepareForExport also kept the shared layout text measurer overridden across an await, so a concurrent layout could measure with the export renderer. withTextMeasurer scopes the override to the synchronous layout.

* fix(design-jsx): inline nested fragments in streamed previews

The streaming projection kept a nested fragment as an empty-type node, which rendered trees inline, so a preview of <Frame><>…</></Frame> failed with 'Unknown element: <>'.

* refactor(ai): schedule previews and gate test streams with VueUse

The preview controller hand-rolled a trailing timer and abort-listener cleanup, and the test stream gate a promise resolver and listener set. Use useDebounceFn with maxWait (a lone delta still flushes, unlike useThrottleFn with leading off), useEventListener, and until(). Share the mock token usage between chat tests.

* fix(ai): keep previews alive through document edits and slow builds

Document edits finished every preview call, and onInputStart never restarts one, so a render call committing while a second was still streaming ended the second call's preview for good. Edits now invalidate: drop the shown artifact and rebuild on the new document.

A build that finished after another delta arrived was discarded, so a steady stream that outpaced staging and recording never showed a preview. Show it, then render the newer revision.

* docs(changelog): separate the Fixed heading from its entries

Add the blank line markdownlint (MD022) expects after the heading, and drop the one that split the Fixed list in two.
2026-10-01 10:52:36 +04:00
..
chunks ci: shard unit tests by owner and cut the quick suite from 100 s to 13 s (#715) 2026-09-17 10:18:16 +03:00
effects feat(editor): checkpoint live interaction improvements 2026-09-15 11:36:17 +03:00
guides feat(canvas): add Figma guide feedback parity 2026-08-20 14:02:33 +03:00
labels perf(canvas): reuse labels with shared font fallback 2026-09-15 23:08:53 +03:00
tiles ci: shard unit tests by owner and cut the quick suite from 100 s to 13 s (#715) 2026-09-17 10:18:16 +03:00
visual ci: shard unit tests by owner and cut the quick suite from 100 s to 13 s (#715) 2026-09-17 10:18:16 +03:00
arrow-heads-draw.test.ts feat(canvas): render arrow stroke caps on lines and open vectors 2026-08-31 21:25:38 +03:00
blend.test.ts feat(editor): checkpoint live interaction improvements 2026-09-15 11:36:17 +03:00
boolean.test.ts refactor(canvas): adopt immutable CanvasKit paths (#554) 2026-08-18 23:09:45 +03:00
cache.test.ts Merge remote-tracking branch 'joey/feature-overlapping-element-analysis-tool' into pr352-local-merge 2026-06-30 09:47:07 +03:00
component-label-text.test.ts fix(canvas): ellipsize frame labels 2026-05-18 03:11:48 +03:00
corner-smoothing.test.ts refactor(canvas): adopt immutable CanvasKit paths (#554) 2026-08-18 23:09:45 +03:00
culling.test.ts feat(editor): checkpoint live interaction improvements 2026-09-15 11:36:17 +03:00
derived-text.test.ts fix(canvas): preserve path text with loaded fonts 2026-09-16 00:59:26 +03:00
diamond-gradient.test.ts fix(canvas): preserve paint geometry and color fidelity 2026-09-16 02:57:56 +03:00
effect-raster-cache.test.ts refactor(canvas): share bounded resource cache bookkeeping 2026-09-15 21:28:16 +03:00
effect-raster-integration.test.ts refactor(canvas): share bounded resource cache bookkeeping 2026-09-15 21:28:16 +03:00
font-readiness.test.ts feat: split SceneGraph and Pen packages 2026-06-30 10:54:32 +03:00
gradient.test.ts fix(canvas): orient linear gradients like Figma 2026-05-18 03:21:16 +03:00
image-fill.test.ts fix(renderer): preserve proportions of FIT image fills 2026-09-13 13:48:11 +03:00
label-cache.test.ts test: align label cache contracts with component members 2026-09-16 16:14:12 +03:00
layout-grids.test.ts feat: split SceneGraph and Pen packages 2026-06-30 10:54:32 +03:00
line.test.ts fix(fig): preserve imported hug container bounds 2026-05-18 04:20:22 +03:00
masks.test.ts feat(editor): checkpoint live interaction improvements 2026-09-15 11:36:17 +03:00
measurement.test.ts feat(canvas): measure distances between layers (#515) 2026-08-14 18:18:55 +03:00
normalize-dash-pattern.test.ts fix(canvas): normalize imported dash patterns 2026-08-31 22:25:48 +03:00
painted-text.test.ts test(canvas): load painted-text font fixtures explicitly 2026-09-16 03:27:10 +03:00
picture-invalidation.test.ts refactor(canvas): share bounded resource cache bookkeeping 2026-09-15 21:28:16 +03:00
raster-export.test.ts fix(fig): preserve component instance rendering 2026-08-10 04:30:06 -03:00
renderer-lifecycle.test.ts feat: preview streamed JSX on the canvas (#692) 2026-10-01 10:52:36 +04:00
retained-backing-pixels.test.ts fix(canvas): discard stale zoom fallback pictures 2026-09-15 17:40:34 +03:00
retained-backing.test.ts fix(renderer): rasterize settled scenes at viewport origin 2026-09-15 13:25:43 +03:00
schema-fill-fallback.test.ts fix(fig): preserve multi-color vector fills 2026-07-28 11:45:58 +03:00
surface-replacement.test.ts perf(canvas): rebuild navigation rendering (#591) 2026-08-31 13:39:40 +03:00
text-font-variations.test.ts fix(text): render variable font styles at their named instances (#773) 2026-09-26 11:25:01 +04:00
text-preparation-cache.test.ts perf(text): preserve coverage across paragraph eviction 2026-09-15 16:32:07 +03:00
text.test.ts fix(fonts): explain PingFang substitution and draw its CJK text (#781) 2026-09-26 11:14:30 +04:00
variable-modes.test.ts fix(fig): honor node-scoped variable modes 2026-07-21 00:23:00 +03:00