Skip to content

[2/3] refactor(painter): collapse legacy API surface (SD-2836)#3117

Merged
luccas-harbour merged 7 commits intotadeu/sd-2836-1-consume-resolved-layoutfrom
tadeu/sd-2836-2-collapse-legacy-api
May 5, 2026
Merged

[2/3] refactor(painter): collapse legacy API surface (SD-2836)#3117
luccas-harbour merged 7 commits intotadeu/sd-2836-1-consume-resolved-layoutfrom
tadeu/sd-2836-2-collapse-legacy-api

Conversation

@tupizz
Copy link
Copy Markdown
Contributor

@tupizz tupizz commented May 4, 2026

Stack

# PR Branch Status
1 #3116 tadeu/sd-2836-1-consume-resolved-layout open
2 this PR tadeu/sd-2836-2-collapse-legacy-api open
3 #3118 tadeu/sd-2836-3-lock-boundary open

Review in order. PR2 depends on PR1; merge PR1 first. PR3 depends on PR2.

What changed

Builds on PR1 (which made DomPainter consume ResolvedLayout internally) by collapsing the legacy public surface so that ResolvedLayout is the only painter input.

Painter (packages/layout-engine/painters/dom)

  • index.ts collapsed to a thin pass-through. Deleted: buildLegacyPaintInput, normalizeDomPainterInput, isDomPainterInput, wrapProvider, resolveDecorationItems, normalizeOptionalBlockMeasurePair, assertRequiredBlockMeasurePair, createEmptyResolvedLayout.
  • paint() now accepts { resolvedLayout, mount, mapping? } only. The legacy (layout, mount) shape is gone.
  • _test-utils.ts (new) hosts a createTestPainter helper that wraps a painter for tests still expressing inputs in the legacy shape, chaining the user's onPaintSnapshot after the internal one.

Tests

  • pm-adapter integration tests migrated to ResolvedLayout.
  • layout-bridge perf benchmark migrated to resolveLayout() + paint({ resolvedLayout }).
  • super-editor PresentationEditor.test.ts mock for resolveLayout synthesizes a ResolvedPage per source Layout page so rebuildRegions(resolvedLayout) populates regions correctly.

Why this split

PR1 keeps the internal migration reviewable on its own. This PR removes the legacy entry points and forces every consumer onto ResolvedLayout. PR3 then locks the boundary (test guard + drops @superdoc/layout-resolved from runtime deps).

Verification

  • All package tests pass: painter-dom, pm-adapter, layout-bridge, layout-engine, super-editor.
  • HEAD-vs-origin/main corpus snapshot diff: 0 changed / 407 unchanged (rendering-neutral).

Test plan

  • CI green
  • Reviewer confirms no remaining references to deleted helpers
  • PR3 boundary guard catches any future regressions

@tupizz tupizz requested a review from a team as a code owner May 4, 2026 16:51
@linear
Copy link
Copy Markdown

linear Bot commented May 4, 2026

@tupizz tupizz force-pushed the tadeu/sd-2836-1-consume-resolved-layout branch from 33e0471 to c5d0b09 Compare May 4, 2026 17:10
@tupizz tupizz force-pushed the tadeu/sd-2836-2-collapse-legacy-api branch 3 times, most recently from 8f18041 to 1c869c1 Compare May 4, 2026 18:05
@tupizz tupizz self-assigned this May 4, 2026
Copy link
Copy Markdown
Contributor

@luccas-harbour luccas-harbour left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @tupizz!
I started reviewing this one and ran into an issue running tests, both packages/layout-engine/layout-bridge/test/performance.test.ts and packages/layout-engine/pm-adapter/src/integration.test.ts failed for me. It looks like you need to add @superdoc/layout-resolved as a test dependency to both @superdoc/pm-adapter and @superdoc/layout-bridge

tupizz added 4 commits May 5, 2026 11:18
Make ResolvedLayout the only painter input contract:

* DomPainterInput collapses to `{ resolvedLayout: ResolvedLayout }`.
  sourceLayout, blocks/measures, headerBlocks/Measures,
  footerBlocks/Measures all removed.
* DomPainterOptions: drop blocks/measures.
* DomPainterHandle: drop setData, setResolvedLayout. paint takes only
  DomPainterInput. Drops the `paint(Layout)` overload across painter,
  PresentationPainterAdapter, and (transitively) PresentationEditor's
  paintInput.
* createDomPainter shrinks to a thin pass-through. Removes
  buildLegacyPaintInput, normalizeDomPainterInput, isDomPainterInput,
  wrapProvider, resolveDecorationItems, normalizeOptionalBlockMeasurePair,
  assertRequiredBlockMeasurePair, createEmptyResolvedLayout,
  LegacyDomPainterState, OptionalBlockMeasurePair.
* PageDecorationPayload.items becomes required (the synthesis path
  is gone).

Tests:
* New `_test-utils.ts` exposes a legacy-shaped `createTestPainter`
  that test files import in place of `createDomPainter`. The helper
  builds a real DomPainterInput internally and synthesizes decoration
  items so existing test bodies don't have to be rewritten.
* All 17 painter test files migrated to the helper.
* Two source-anchor tests still failing under investigation;
  remaining work is bounded and tracked.
createTestPainter was overwriting the user-supplied onPaintSnapshot callback with its own, so tests that relied on the callback (source-anchor tests) saw an undefined snapshot. Chain the user callback after the internal one.
The three integration tests in pm-adapter were calling painter.paint(layout, mount) with raw Layout. They now resolveLayout() first and call painter.paint({ resolvedLayout }, mount). All 1794 pm-adapter tests pass.
The layout-bridge incremental-pipeline performance benchmark called painter.paint(layout, mount) and painter.setData(...). Both are removed by the API collapse. Migrate to resolveLayout() + DomPainterInput so the benchmark continues to exercise the painter under the new contract.
@tupizz tupizz force-pushed the tadeu/sd-2836-2-collapse-legacy-api branch from 1c869c1 to 87ddc92 Compare May 5, 2026 14:19
…use it (SD-2836)

PR1 added test imports of @superdoc/layout-resolved in
pm-adapter/src/integration.test.ts and layout-bridge/test/benchmarks/index.ts
without declaring it as a devDependency. Both packages now resolve the
import locally via pnpm.
Copy link
Copy Markdown
Contributor Author

@tupizz tupizz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and fixed in 528efe4. The two test files (pm-adapter/src/integration.test.ts:14 and layout-bridge/test/benchmarks/index.ts:6) imported @superdoc/layout-resolved without their parent packages declaring it as a devDependency.

Added @superdoc/layout-resolved: workspace:* to devDependencies of both pm-adapter/package.json and layout-bridge/package.json, regenerated the lockfile.

Verified locally:

  • pnpm --filter @superdoc/pm-adapter test → 1794/1794 pass
  • pnpm --filter @superdoc/layout-bridge test → 1192/1192 pass (incl. performance.test.ts)

PR3 rebased on top.

When resolveAlignedDecorationItems cannot align items 1:1 with fragments
(returns undefined), HeaderFooterSessionManager now bails out with null
instead of emitting a payload with items: undefined, which would violate
the now-required PageDecorationPayload.items contract from PR2.
normalizeDecorationItems narrowed to ResolvedPaintItem[] -> ResolvedPaintItem[].

Also refresh painter-dom README: drop blocks/measures/setData/paint(layout)
examples; document the ResolvedLayout-only paint() and the items-aligned-
with-fragments invariant on PageDecorationPayload.
Copy link
Copy Markdown
Contributor Author

@tupizz tupizz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both items addressed in commit 198adac:

P2 — PageDecorationPayload.items contract honored

The upstream issue: resolveAlignedDecorationItems() returns undefined when items cannot be aligned 1:1 with fragments (it logs a warning and gives up). The provider was still constructing a payload with items: normalizedItems where normalizedItems could be undefined, violating the contract this PR is meant to enforce.

Fix: when alignedItems / alignedVariantItems is undefined, the provider now returns null (decoration skipped for that page) instead of emitting a payload with items: undefined. Also tightened normalizeDecorationItems(items: ResolvedPaintItem[]) -> ResolvedPaintItem[] so the type system prevents a regression.

Verified: super-editor tsc --noEmit no longer reports the PageDecorationPayload.items mismatch (older unrelated super-editor type errors remain). 12251/12251 super-editor tests still pass; 22/22 in HeaderFooterSessionManager.test.ts.

P3 — README updated

packages/layout-engine/painters/dom/README.md now documents the ResolvedLayout-only API path (no blocks/measures props, no paint(layout), no setData), with a brief note about the items 1:1-with-fragments invariant on PageDecorationPayload.

PR3 rebased on top.

@tupizz tupizz requested a review from luccas-harbour May 5, 2026 15:24
Copy link
Copy Markdown
Contributor

@luccas-harbour luccas-harbour left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

* test(painter): lock ResolvedLayout-only boundary (SD-2836)

* chore(painter): drop unused imports and skipped legacy tests (SD-2836)

renderer.ts: drop unused Layout, Page, Measure, FlowBlock, ParagraphBorder type imports left over from the migration. index.test.ts: delete the skipped 'decoration item synthesis' describe block (it was protecting the synthesis path that has been removed).

* chore(deps): regenerate lockfile after dropping layout-resolved runtime dep (SD-2836)

Moves @superdoc/layout-resolved to devDependencies in the lockfile to
match package.json, so CI's --frozen-lockfile install matches. Boundary
tests still need it under devDependencies.
@luccas-harbour luccas-harbour merged commit b22c3a1 into tadeu/sd-2836-1-consume-resolved-layout May 5, 2026
4 checks passed
@luccas-harbour luccas-harbour deleted the tadeu/sd-2836-2-collapse-legacy-api branch May 5, 2026 17:43
tupizz added a commit that referenced this pull request May 5, 2026
* refactor(painter): collapse legacy API surface (SD-2836)

Make ResolvedLayout the only painter input contract:

* DomPainterInput collapses to `{ resolvedLayout: ResolvedLayout }`.
  sourceLayout, blocks/measures, headerBlocks/Measures,
  footerBlocks/Measures all removed.
* DomPainterOptions: drop blocks/measures.
* DomPainterHandle: drop setData, setResolvedLayout. paint takes only
  DomPainterInput. Drops the `paint(Layout)` overload across painter,
  PresentationPainterAdapter, and (transitively) PresentationEditor's
  paintInput.
* createDomPainter shrinks to a thin pass-through. Removes
  buildLegacyPaintInput, normalizeDomPainterInput, isDomPainterInput,
  wrapProvider, resolveDecorationItems, normalizeOptionalBlockMeasurePair,
  assertRequiredBlockMeasurePair, createEmptyResolvedLayout,
  LegacyDomPainterState, OptionalBlockMeasurePair.
* PageDecorationPayload.items becomes required (the synthesis path
  is gone).

Tests:
* New `_test-utils.ts` exposes a legacy-shaped `createTestPainter`
  that test files import in place of `createDomPainter`. The helper
  builds a real DomPainterInput internally and synthesizes decoration
  items so existing test bodies don't have to be rewritten.
* All 17 painter test files migrated to the helper.
* Two source-anchor tests still failing under investigation;
  remaining work is bounded and tracked.

* fix(painter): chain user onPaintSnapshot in test utility (SD-2836)

createTestPainter was overwriting the user-supplied onPaintSnapshot callback with its own, so tests that relied on the callback (source-anchor tests) saw an undefined snapshot. Chain the user callback after the internal one.

* test(pm-adapter): migrate integration tests to ResolvedLayout (SD-2836)

The three integration tests in pm-adapter were calling painter.paint(layout, mount) with raw Layout. They now resolveLayout() first and call painter.paint({ resolvedLayout }, mount). All 1794 pm-adapter tests pass.

* test(layout-bridge): migrate perf benchmark to ResolvedLayout (SD-2836)

The layout-bridge incremental-pipeline performance benchmark called painter.paint(layout, mount) and painter.setData(...). Both are removed by the API collapse. Migrate to resolveLayout() + DomPainterInput so the benchmark continues to exercise the painter under the new contract.

* chore(deps): declare @superdoc/layout-resolved as devDep where tests use it (SD-2836)

PR1 added test imports of @superdoc/layout-resolved in
pm-adapter/src/integration.test.ts and layout-bridge/test/benchmarks/index.ts
without declaring it as a devDependency. Both packages now resolve the
import locally via pnpm.

* fix(super-editor): honor PageDecorationPayload.items contract (SD-2836)

When resolveAlignedDecorationItems cannot align items 1:1 with fragments
(returns undefined), HeaderFooterSessionManager now bails out with null
instead of emitting a payload with items: undefined, which would violate
the now-required PageDecorationPayload.items contract from PR2.
normalizeDecorationItems narrowed to ResolvedPaintItem[] -> ResolvedPaintItem[].

Also refresh painter-dom README: drop blocks/measures/setData/paint(layout)
examples; document the ResolvedLayout-only paint() and the items-aligned-
with-fragments invariant on PageDecorationPayload.

* [3/3] test(painter): lock ResolvedLayout-only boundary (SD-2836) (#3118)

* test(painter): lock ResolvedLayout-only boundary (SD-2836)

* chore(painter): drop unused imports and skipped legacy tests (SD-2836)

renderer.ts: drop unused Layout, Page, Measure, FlowBlock, ParagraphBorder type imports left over from the migration. index.test.ts: delete the skipped 'decoration item synthesis' describe block (it was protecting the synthesis path that has been removed).

* chore(deps): regenerate lockfile after dropping layout-resolved runtime dep (SD-2836)

Moves @superdoc/layout-resolved to devDependencies in the lockfile to
match package.json, so CI's --frozen-lockfile install matches. Boundary
tests still need it under devDependencies.
luccas-harbour pushed a commit that referenced this pull request May 5, 2026
* refactor(contracts): host expandRunsForInlineNewlines (SD-2836)

Move the inline-newline run expander from @superdoc/pm-adapter into
@superdoc/contracts. The function is a pure transformation on Run[]
shapes already defined here; relocating it lets painter-dom consume the
helper without depending on pm-adapter (per the SD-2836 acceptance
criterion: no painter-dom imports from pm-adapter or layout-bridge).

pm-adapter chains its public re-export through contracts, keeping the
import path stable until painter-dom is migrated to consume directly.

* refactor(contracts): host sliceRunsForLine (SD-2836)

Move the line-aware run slicer from @superdoc/layout-bridge into
@superdoc/contracts, alongside expandRunsForInlineNewlines. The function
is a pure transformation on Run/Line shapes already defined here;
relocating it lets painter-dom consume the helper without depending on
layout-bridge (per the SD-2836 acceptance criterion).

layout-bridge chains its public re-export through contracts, keeping
the import path stable until painter-dom is migrated to consume directly.

Also restore a TrackedChangeMeta import in pm-adapter's paragraph.test.ts
that the prior commit dropped; the type is still referenced outside the
migrated describe block.

* refactor(painter): consume run helpers from contracts (SD-2836)

Switch the painter's two cross-package run-helper imports
(expandRunsForInlineNewlines, sliceRunsForLine) to source from
@superdoc/contracts directly, then drop @superdoc/pm-adapter and
@superdoc/layout-bridge from painter-dom's runtime dependencies.

This closes the painter-dom -> pm-adapter / layout-bridge import edge
called out in the SD-2836 acceptance criteria. Architecture-boundary
guards added in [3/3] of this stack will prevent reintroduction.

* refactor(layout): add fragment back-pointer to resolved items (SD-2836)

Add a `fragment: Fragment` field to ResolvedFragmentItem,
ResolvedTableItem, ResolvedImageItem, and ResolvedDrawingItem, and
populate it from the corresponding resolve* helper. The reference is
shared, not copied: items now carry the same Fragment object that lives
on the source page.

This is the precondition for stopping painter iteration over
`page.fragments`. The next commit drops getResolvedFragmentItem and
switches the painter to iterate ResolvedPage.items, reading the source
fragment via `item.fragment` instead of indexing back into the legacy
fragments array.

Includes focused tests in resolveLayout.test.ts asserting back-pointer
identity for each kind.

* refactor(painter): drop getResolvedFragmentItem; iterate resolved items (SD-2836)

Replace the three `page.fragments.forEach((fragment, index) => ...)`
loops in renderPage / patchPage / initPage with iterations over
`resolvedItems` (the resolved page's items), reading the source
Fragment via the back-pointer added in the previous commit.

Removes:
- getResolvedFragmentItem (parallel-array index lookup into resolved items)
- direct iteration of `page.fragments` from the painter render path

Updates affected hand-rolled resolved-layout tests to populate the new
required `fragment` back-pointer; the painter now treats items without
a fragment as not-yet-renderable rather than indexing back into the
legacy fragments array.

* refactor(painter): paint() body reads ResolvedLayout (SD-2836)

Switch paint()'s top-level reads from input.sourceLayout to
input.resolvedLayout for: layoutEpoch, page count, and the mounted-page
indices.

The local `layout = input.sourceLayout` binding stays for one more
commit because the four legacy-Layout helpers (beginPaintSnapshot,
fullRender, patchLayout, renderHorizontal, renderBookMode,
renderVirtualized) still take a Layout argument. The next commit
migrates those signatures and removes the binding entirely.

* refactor(painter): drop fragments param from sdt+border helpers (SD-2836)

computeSdtBoundaries and computeBetweenBorderFlags previously took both
the raw `fragments` array and the parallel resolvedItems array. They
now take only resolvedItems and read each fragment via the back-pointer
added in [PR1#4]. Updates all four call sites in renderer.ts plus the
between-borders test fixture.

This eliminates the painter's lookup into `page.fragments` from the
helper-call layer, leaving only the deeper-method Layout dependency
(beginPaintSnapshot, fullRender, patchLayout, renderHorizontal,
renderBookMode, renderVirtualized) to migrate next.

* refactor(painter): migrate internals to ResolvedLayout (SD-2836)

Switch DomPainter's internal state and helpers from raw Layout/Page to
ResolvedLayout/ResolvedPage:

* The six top-level legacy-Layout methods (beginPaintSnapshot,
  fullRender, patchLayout, renderHorizontal, renderBookMode,
  renderVirtualized) take ResolvedLayout. paint() drops the
  `const layout = input.sourceLayout` binding and calls every method
  with input.resolvedLayout.
* The page-level helpers (renderPage, createPageState, patchPage,
  renderDecorationsForPage, renderDecorationSection,
  getDecorationAnchorPageOriginY, renderPageRuler,
  renderColumnSeparators) take ResolvedPage and read width/height/
  margins/numberText/etc. directly. Drops every redundant
  `resolvedPage?: ResolvedPage | null` parameter.
* `currentLayout: Layout | null` -> `ResolvedLayout | null`. Strips
  the `(page.size ?? layout.pageSize)` cascades inside virtualization
  + page-iteration code; uses ResolvedPage.width/.height directly.
* Lifts `columns` and `columnRegions` onto ResolvedPage so the
  column-separator renderer can read them without falling back to
  raw Page.

Couples PageDecorationProvider (planned PR2 work) since the painter
now passes ResolvedPage to the third callback argument:

* `PageDecorationProvider`'s `page?` parameter is `ResolvedPage`.
* `HeaderFooterSessionManager.rebuildRegions` takes ResolvedLayout.
  `updateDecorationProviders(layout, resolvedLayout)` plumbed through
  PresentationEditor.
* The provider closure body and internal helpers
  (`#stripFootnoteReserveFromBottomMargin`, `#computeExpectedSectionType`)
  now operate on ResolvedPage; `page?.size?.h` -> `page?.height`.
* `buildLegacyPaintInput` always calls `resolveLayout` so the legacy
  paint(Layout) path produces ResolvedPages even when no body
  blocks/measures are supplied (preserves page-level metadata).

Skips a "decoration item synthesis" describe block that exercises
`paint(Layout)` + `setData` + `setResolvedLayout`. Those legacy entry
points get deleted in the next commit; the block is being preserved as
.skip so the deletion is visible in diff.

* chore(deps): regenerate lockfile after painter-dom dep cleanup (SD-2836)

Drops the now-unused @superdoc/layout-bridge and @superdoc/pm-adapter
entries from pnpm-lock.yaml so CI's --frozen-lockfile install matches
package.json.

* test(super-editor): synthesize ResolvedLayout in PresentationEditor mock (SD-2836)

rebuildRegions now iterates resolvedLayout.pages (was layout.pages). The PresentationEditor test mocked resolveLayout to return empty pages, which caused the header/footer region tests to populate zero regions and bookmark navigation to fail. The mock now synthesizes a minimal ResolvedPage per source Layout page so region tests stay green.

* refactor(painter,super-editor): address PR review feedback (SD-2836)

- Drop redundant pageSize parameter from createPageState/patchPage; read
  page.width/height directly from ResolvedPage.
- Migrate createDecorationProvider to ResolvedLayout; updateDecorationProviders
  no longer needs the legacy Layout parameter.
- Add direct rebuildRegions(resolvedLayout) tests covering footnoteReserved>0,
  per-page height variation, and sectionIndex>0.
- Assert columns and columnRegions forward through to ResolvedPage in
  resolveLayout tests.

* [2/3] refactor(painter): collapse legacy API surface (SD-2836) (#3117)

* refactor(painter): collapse legacy API surface (SD-2836)

Make ResolvedLayout the only painter input contract:

* DomPainterInput collapses to `{ resolvedLayout: ResolvedLayout }`.
  sourceLayout, blocks/measures, headerBlocks/Measures,
  footerBlocks/Measures all removed.
* DomPainterOptions: drop blocks/measures.
* DomPainterHandle: drop setData, setResolvedLayout. paint takes only
  DomPainterInput. Drops the `paint(Layout)` overload across painter,
  PresentationPainterAdapter, and (transitively) PresentationEditor's
  paintInput.
* createDomPainter shrinks to a thin pass-through. Removes
  buildLegacyPaintInput, normalizeDomPainterInput, isDomPainterInput,
  wrapProvider, resolveDecorationItems, normalizeOptionalBlockMeasurePair,
  assertRequiredBlockMeasurePair, createEmptyResolvedLayout,
  LegacyDomPainterState, OptionalBlockMeasurePair.
* PageDecorationPayload.items becomes required (the synthesis path
  is gone).

Tests:
* New `_test-utils.ts` exposes a legacy-shaped `createTestPainter`
  that test files import in place of `createDomPainter`. The helper
  builds a real DomPainterInput internally and synthesizes decoration
  items so existing test bodies don't have to be rewritten.
* All 17 painter test files migrated to the helper.
* Two source-anchor tests still failing under investigation;
  remaining work is bounded and tracked.

* fix(painter): chain user onPaintSnapshot in test utility (SD-2836)

createTestPainter was overwriting the user-supplied onPaintSnapshot callback with its own, so tests that relied on the callback (source-anchor tests) saw an undefined snapshot. Chain the user callback after the internal one.

* test(pm-adapter): migrate integration tests to ResolvedLayout (SD-2836)

The three integration tests in pm-adapter were calling painter.paint(layout, mount) with raw Layout. They now resolveLayout() first and call painter.paint({ resolvedLayout }, mount). All 1794 pm-adapter tests pass.

* test(layout-bridge): migrate perf benchmark to ResolvedLayout (SD-2836)

The layout-bridge incremental-pipeline performance benchmark called painter.paint(layout, mount) and painter.setData(...). Both are removed by the API collapse. Migrate to resolveLayout() + DomPainterInput so the benchmark continues to exercise the painter under the new contract.

* chore(deps): declare @superdoc/layout-resolved as devDep where tests use it (SD-2836)

PR1 added test imports of @superdoc/layout-resolved in
pm-adapter/src/integration.test.ts and layout-bridge/test/benchmarks/index.ts
without declaring it as a devDependency. Both packages now resolve the
import locally via pnpm.

* fix(super-editor): honor PageDecorationPayload.items contract (SD-2836)

When resolveAlignedDecorationItems cannot align items 1:1 with fragments
(returns undefined), HeaderFooterSessionManager now bails out with null
instead of emitting a payload with items: undefined, which would violate
the now-required PageDecorationPayload.items contract from PR2.
normalizeDecorationItems narrowed to ResolvedPaintItem[] -> ResolvedPaintItem[].

Also refresh painter-dom README: drop blocks/measures/setData/paint(layout)
examples; document the ResolvedLayout-only paint() and the items-aligned-
with-fragments invariant on PageDecorationPayload.

* [3/3] test(painter): lock ResolvedLayout-only boundary (SD-2836) (#3118)

* test(painter): lock ResolvedLayout-only boundary (SD-2836)

* chore(painter): drop unused imports and skipped legacy tests (SD-2836)

renderer.ts: drop unused Layout, Page, Measure, FlowBlock, ParagraphBorder type imports left over from the migration. index.test.ts: delete the skipped 'decoration item synthesis' describe block (it was protecting the synthesis path that has been removed).

* chore(deps): regenerate lockfile after dropping layout-resolved runtime dep (SD-2836)

Moves @superdoc/layout-resolved to devDependencies in the lockfile to
match package.json, so CI's --frozen-lockfile install matches. Boundary
tests still need it under devDependencies.

* fix(painter): adapt content-presence gate to ResolvedPage (SD-2836)

After rebasing PR1's painter migration onto main, the new column-separator
content-presence gate added by SD-2452 (a5ff6ed) reads page.fragments
directly. On the new architecture the painter receives a ResolvedPage whose
fragments live as page.items[]. Switch the in-region scan to iterate items
(every ResolvedPaintItem carries x/y).

Also extend the test-only createTestPainter shim to auto-synthesize minimal
ParagraphBlock/ParagraphMeasure entries for any layout fragment whose blockId
isn't covered by the supplied blocks. Tests that only exercise wrapper-level
rendering (column separators, page chrome) can keep using fragAt(...) without
boilerplate matching blocks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants