This repository was archived by the owner on Aug 20, 2026. It is now read-only.
docs: state why the public API has no DocumentPackage read/write pair - #73
Merged
Merged
Conversation
Every other codec in this family reads its format into the flat ContentDocument, so each can layer a tree-native entry point on top of its own flat one -- decompose/assemblePackage outward, flattenPackage back, now that document-schema.js 4.3.0 exports all four. PDF cannot follow that pattern in either direction. A PDF states positions, not structure: readPdf yields layout cheaply because positioned glyphs and paths are all the format actually carries, and semantic content comes only from a separate, lossy reconstruction pass that infers paragraphs, headings, tables, and shapes back out of geometry. The write direction is asymmetric for the same reason -- a DocumentPackage reaches PDF bytes only through a font-measuring, line-breaking layout engine, and writePdf takes the positioned LayoutDocument that engine produces. Both passes are semantic policy rather than codec business and live in documents.js, which also means a wrapper here would invert the dependency onto the package that already depends on this one. Records that in the barrel header, next to the readPdf/writePdf exports a reader would otherwise expect a package-native pair beside, and in the README's usage section, naming convertDocument's onDocument callback and ConversionResult.package as where a caller gets a PDF as a tree.
The write-direction claim was wrong: turning a DocumentPackage into PDF bytes does not need a font-measuring, line-breaking layout engine. documents.js's buildDocumentBytes reaches PDF only for a package that already carries frames from a prior layout pass, and layoutDocumentFromPackage is a mechanical walk of those existing positions, not a layout pass of its own; a frameless package (a bridge conversion's own dump) cannot reach PDF at all. Restate the real asymmetry: read needs a lossy geometry-to-structure reconstruction, write needs frames a layout pass already stamped, and both the stamping and the walk-back live in documents.js. Also fix three adjacent inaccuracies in the same passage: convertDocument returns bytes only and never exposes ConversionResult.package, which is populated separately by createLocalDocumentConverter()'s DocumentConverter port; the #65 citation quoted only the reconstruction-stays- in-documents.js bullet while omitting that the frames-mapping half it scoped to this package was never implemented here; and "every other codec reads into ContentDocument" doesn't hold at the codec level -- ooxml.js's readDocx/readPptx and odf.js's readOdt/readOds return their own native models, and it's documents.js's own readXContent wrapper layer that projects each into the flat ContentDocument.
Contributor
|
🎉 This PR is included in version 3.0.4 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Went in to give this package a
DocumentPackage-native read/write pair alongside aContentDocument-based one, the same way the other codecs in the family are getting one now thatdocument-schema.js4.3.0 exportsdecompose/flattenPackage/factorStyles/assemblePackage. There is nothing here to wrap: this package has noContentDocumentsurface at all, public or internal.What the inventory actually found, against
origin/main:readPdf(bytes, options?) -> LayoutDocumentandwritePdf(doc, options?) -> Uint8Array, pluspdfCodec, az.codec()over the pair withLayoutDocumentSchemaon the far side. That is the whole content-level surface.LayoutDocumentis this package's own type since the 4.0.0 layout demotion (src/layout.ts, Demote LayoutDocument to codec-private; map to and from frames at the edge #65), soreadPdf/writePdfnever touchdocument-schema.js's content model.src/content-read.tsandsrc/content-write.tsare PDF content streams (the graphics operator sequence), notContentDocument. Both are internal and unexported. The only occurrences of the stringContentDocumentanywhere undersrc/are in comments explaining what asourcePathvalue points back at.documents.jsownsreconstructWordprocessing/reconstructPresentation/reconstructDrawing/reconstructSpreadsheetand callsreadPdffrom its own composition graph.So the rename half of the plan (
readPdf->readPdfContent, new tree-nativereadPdf) has nothing to rename, and the wrapper half would have to invent the missing piece rather than wrap it. Reading, that means owning a geometry-to-structure reconstruction heuristic; writing, a font-measuring, line-breaking layout engine. Both are semantic policy thatdocuments.jsalready owns, and either one here would point this package at the package that depends on it.The change is therefore documentation only: the barrel header and the README's usage section now say that the absence is deliberate, and point a caller wanting PDF to or from a
DocumentPackageatconvertDocument'sonDocumentcallback andConversionResult.packageindocuments.js. Worth writing down because the next reader hittingreadPdfwith the sibling packages' new API in mind will otherwise ask exactly this question, and the plausible-looking answer is the wrong one.document-schema.jsneeded no bump:origin/mainis already on^4.3.0, and the lockfile resolves 4.3.0.typecheck,lint,test(1119 tests),test:workers, andbuildare all green.Generated with Claude Code