feat!: migrate DocumentPackage onto schema 3's fused content + pages shape - #611
Merged
Conversation
…f in DocumentPackage
Bump document-schema.js to ^3.2.0, ooxml.js to ^2.16.0, odf.js to ^3.0.1
and markdown-codec to ^2.0.0 in the same change: holding markdown-codec
1.4.2 (schema ^2) alongside schema ^3 installs two schema copies and
fails typecheck, so the bumps and the code migration cannot land apart.
The four layout engines stamp every placement they compute onto the
corresponding content node's own frames array -- one frame per rendered
fragment on a run, the cell box on a cell, the emitted item's box on an
image, vector or shape -- and return the package's pages array alongside
the internal LayoutDocument, which remains pdf-codec's writePdf
contract. buildDocumentBytes('pdf') rebuilds that LayoutDocument from
the package's own frames and pages (layoutDocumentFromPackage) instead
of reading a layout half the schema no longer carries; a run's frames
carry positions, not wrap decisions, so a wrapped run re-renders once at
its first recorded placement.
BREAKING CHANGE: DocumentPackage is document-schema.js 3's fused shape
({ formatVersion: 2, content, pages }); onDocument and
ConversionResult.package no longer report a layout,
buildDocumentBytes(pkg, 'pdf') throws for a package with no pages and
rebuilds from frames otherwise, convertDrawingToLayout returns
{ document, pages } rather than a bare LayoutDocument, and content read
by markdown-codec 2.0.0 carries headingLevel on heading paragraphs.
… content nodes The four reconstructors stamp every node they build with frames taken from the exact LayoutItems it was clustered from -- each recovered run carries its source item's box, each paragraph the bounding box of its line, each lattice-recovered cell and table its measured grid box, each recovered vector the PDF-space box of the item it came from -- so PDF-to-X conversions surface genuine positions in the same unified package shape the layout engines produce. sourcePath survives on recovered items as traceability only.
Code Coverage OverviewLanguages: TypeScript TypeScript / unitThe overall coverage in commit e9ed390 in the Show a code coverage summary of the most impacted files.
|
This was referenced Aug 17, 2026
Contributor
|
🎉 This PR is included in version 2.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This was referenced Aug 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #569
Migrates the package onto document-schema.js 3's fused
DocumentPackage:{ formatVersion: 2, content, pages }, with every content leaf carrying its own rendered positions asframes— the second, independentLayoutDocumenthalf correlated back bysourcePathstrings is gone from the package surface.Dependency set (one PR because splitting them leaves the tree unable to typecheck — markdown-codec 1.4.2 pins schema
^2.7.17, which dual-copies against schema^3):document-schema.js@^3.2.0,ooxml.js@^2.16.0,odf.js@^3.0.1,markdown-codec@^2.0.0. pdf-codec was already on schema 3.What changed
convertWordprocessingToLayout,convertPresentationToLayout,convertSpreadsheetToLayout,convertDrawingToLayout) stamp every placement they compute onto the corresponding content node's ownframesarray, in place — one frame per rendered fragment on a run, the cell box on a table/sheet cell, the emitted item's box on an image, vector, or shape — and return the package'spagesarray alongside the internalLayoutDocument, which remains pdf-codec'swritePdfcontract.convertDrawingToLayoutnow returns{ document, pages }like its three siblings.LayoutItems each reconstructed node was clustered from, so every PDF-to-X conversion's content carries genuine positions too.sourcePathsurvives as traceability only.onDocument/ConversionResult.packagesurface the unified package:pages+ frame-stamped content for toPdf/fromPdf hops, content-only (no pages, no frames) for bridges.odfToPdfreports its single A4 page.buildDocumentBytes(pkg, 'pdf')rebuilds the pdf-codec view from the package's own frames + pages (layoutDocumentFromPackage, exported) — a mechanical inverse walking the content tree and emittingLayoutItems from each node's recorded placements, with drawing vectors re-emitted through the layout engine's own conversion so geometry cannot drift. Two honest limits, documented in the README: a run's frames carry positions, not the wrap decisions that distributed its text across them, so a wrapped run re-renders once, whole, at its first recorded placement; and no font registry or positioned formula survives a bare package (same as before the fusion).GENERATE_EXAMPLES=1):document-package.jsonnow shows formatVersion 2 +pages+ frame-stamped runs; the six content examples carry formatVersion 3. README'sDocumentPackagedocumentation, the snapshot gotcha, and thesourcePathnote updated.Breaking (semantic-release should cut 2.0.0): package
formatVersion1 → 2,layoutgone,buildDocumentBytes(pkg, 'pdf')throws/has no pages/for bridge dumps instead of/has no layout/,convertDrawingToLayoutreturn shape widened, markdown content carriesheadingLevelon heading paragraphs.Generated by Claude Code