js.documents 4.0.20 → 4.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +43 -29
  2. package/dist/cell-typing-CEWlywIc.d.cts +22 -0
  3. package/dist/cell-typing-CEWlywIc.d.ts +22 -0
  4. package/dist/codecs/read.cjs +66 -0
  5. package/dist/codecs/read.d.cts +15 -0
  6. package/dist/codecs/read.d.ts +15 -0
  7. package/dist/codecs/read.js +64 -0
  8. package/dist/codecs/registry.cjs +13 -59
  9. package/dist/codecs/registry.d.cts +2 -8
  10. package/dist/codecs/registry.d.ts +2 -8
  11. package/dist/codecs/registry.js +20 -64
  12. package/dist/convert/codec.cjs +11 -10
  13. package/dist/convert/codec.js +2 -1
  14. package/dist/convert/composition-to-pdf.cjs +133 -0
  15. package/dist/convert/composition-to-pdf.d.cts +7 -0
  16. package/dist/convert/composition-to-pdf.d.ts +7 -0
  17. package/dist/convert/composition-to-pdf.js +131 -0
  18. package/dist/convert/composition.cjs +31 -129
  19. package/dist/convert/composition.d.cts +14 -4
  20. package/dist/convert/composition.d.ts +14 -4
  21. package/dist/convert/composition.js +25 -128
  22. package/dist/convert/convert.cjs +35 -75
  23. package/dist/convert/convert.d.cts +5 -20
  24. package/dist/convert/convert.d.ts +5 -20
  25. package/dist/convert/convert.js +2 -32
  26. package/dist/convert/from-package.cjs +2 -1
  27. package/dist/convert/from-package.js +2 -1
  28. package/dist/convert/from-pdf.cjs +50 -0
  29. package/dist/convert/from-pdf.d.cts +26 -0
  30. package/dist/convert/from-pdf.d.ts +26 -0
  31. package/dist/convert/from-pdf.js +39 -0
  32. package/dist/convert/local.cjs +2 -1
  33. package/dist/convert/local.js +2 -1
  34. package/dist/convert/pdf-package-tables.cjs +76 -0
  35. package/dist/convert/pdf-package-tables.d.cts +6 -0
  36. package/dist/convert/pdf-package-tables.d.ts +6 -0
  37. package/dist/convert/pdf-package-tables.js +75 -0
  38. package/dist/csv/read.d.cts +1 -1
  39. package/dist/csv/read.d.ts +1 -1
  40. package/dist/diagnostics-DVAXKgcf.d.cts +10 -0
  41. package/dist/diagnostics-DVAXKgcf.d.ts +10 -0
  42. package/dist/edit/docx/content.cjs +1 -0
  43. package/dist/edit/docx/content.js +1 -0
  44. package/dist/edit/docx/paragraph.cjs +18 -1
  45. package/dist/edit/docx/paragraph.d.cts +3 -0
  46. package/dist/edit/docx/paragraph.d.ts +3 -0
  47. package/dist/edit/docx/paragraph.js +18 -1
  48. package/dist/edit/docx/props.cjs +1 -0
  49. package/dist/edit/docx/props.js +1 -0
  50. package/dist/edit/markdown/editor.cjs +1 -1
  51. package/dist/edit/markdown/editor.js +1 -1
  52. package/dist/edit/pdf/item.cjs +42 -1
  53. package/dist/edit/pdf/item.d.cts +2 -2
  54. package/dist/edit/pdf/item.d.ts +2 -2
  55. package/dist/edit/pdf/item.js +42 -2
  56. package/dist/edit/pdf/page.d.cts +1 -1
  57. package/dist/edit/pdf/page.d.ts +1 -1
  58. package/dist/fonts/registry.d.cts +1 -19
  59. package/dist/fonts/registry.d.ts +1 -19
  60. package/dist/hsqldb/binary-script.d.cts +1 -1
  61. package/dist/hsqldb/binary-script.d.ts +1 -1
  62. package/dist/hsqldb/cache.d.cts +1 -1
  63. package/dist/hsqldb/cache.d.ts +1 -1
  64. package/dist/hsqldb/rowformat.d.cts +1 -24
  65. package/dist/hsqldb/rowformat.d.ts +1 -24
  66. package/dist/index.cjs +17 -16
  67. package/dist/index.d.cts +11 -10
  68. package/dist/index.d.ts +11 -10
  69. package/dist/index.js +8 -7
  70. package/dist/{item-D9vQKT0T.d.cts → item-DhXpJNAQ.d.cts} +17 -3
  71. package/dist/{item-D9vQKT0T.d.ts → item-DhXpJNAQ.d.ts} +17 -3
  72. package/dist/layout/cell-typing.d.cts +1 -21
  73. package/dist/layout/cell-typing.d.ts +1 -21
  74. package/dist/layout/reconstruct.cjs +177 -14
  75. package/dist/layout/reconstruct.d.cts +1 -1
  76. package/dist/layout/reconstruct.d.ts +1 -1
  77. package/dist/layout/reconstruct.js +175 -12
  78. package/dist/layout/shared.cjs +2 -2
  79. package/dist/layout/shared.js +1 -1
  80. package/dist/markdown/math.cjs +5 -7
  81. package/dist/markdown/math.js +5 -7
  82. package/dist/markdown/read.cjs +15 -1
  83. package/dist/markdown/read.js +16 -2
  84. package/dist/markdown/write.cjs +7 -10
  85. package/dist/markdown/write.d.cts +3 -6
  86. package/dist/markdown/write.d.ts +3 -6
  87. package/dist/markdown/write.js +8 -11
  88. package/dist/metadata/write.cjs +2 -1
  89. package/dist/metadata/write.js +2 -1
  90. package/dist/model/bytes.cjs +8 -0
  91. package/dist/model/bytes.d.cts +2 -1
  92. package/dist/model/bytes.d.ts +2 -1
  93. package/dist/model/bytes.js +8 -1
  94. package/dist/odb/read.d.cts +1 -1
  95. package/dist/odb/read.d.ts +1 -1
  96. package/dist/odb/report/content.d.cts +1 -1
  97. package/dist/odb/report/content.d.ts +1 -1
  98. package/dist/odb/report/source.d.cts +1 -1
  99. package/dist/odb/report/source.d.ts +1 -1
  100. package/dist/odf/odt/read.cjs +1 -1
  101. package/dist/odf/odt/read.js +1 -1
  102. package/dist/registry-BcBT-bnX.d.cts +20 -0
  103. package/dist/registry-D1Pu5XxB.d.ts +20 -0
  104. package/dist/rowformat-Cl2exlEh.d.cts +25 -0
  105. package/dist/rowformat-Cl2exlEh.d.ts +25 -0
  106. package/dist/svg/diagnostics.d.cts +1 -9
  107. package/dist/svg/diagnostics.d.ts +1 -9
  108. package/dist/svg/read.d.cts +1 -1
  109. package/dist/svg/read.d.ts +1 -1
  110. package/dist/svg/write.d.cts +1 -1
  111. package/dist/svg/write.d.ts +1 -1
  112. package/package.json +27 -10
  113. package/dist/metadata/read.cjs +0 -15
  114. package/dist/metadata/read.d.cts +0 -9
  115. package/dist/metadata/read.d.ts +0 -9
  116. package/dist/metadata/read.js +0 -14
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # documents.js
2
2
 
3
- [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/documents.js) [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/documents.js) [![Release](https://img.shields.io/github/v/release/ExaDev/documents.js)](https://github.com/ExaDev/documents.js/releases/latest) [![CI](https://img.shields.io/github/actions/workflow/status/ExaDev/documents.js/ci.yml?branch=main)](https://github.com/ExaDev/documents.js/actions)
3
+ [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/documents.js/tree/main/packages/documents.js) [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/documents.js) [![npm version](https://img.shields.io/npm/v/documents.js)](https://www.npmjs.com/package/documents.js) [![CI](https://img.shields.io/github/actions/workflow/status/ExaDev/documents.js/ci.yml?branch=main)](https://github.com/ExaDev/documents.js/actions)
4
4
 
5
- > Converts between any two compatible document formats through a shared content/layout pivot. docx, pptx, odt, odp, ods, odg, xlsx, csv (TSV is the same format with a tab delimiter), svg, and markdown all read into and build from the same shared `ContentDocument` model (reported to callers as the tree-form `DocumentPackage`), with PDF — reached through pdf-codec's own `LayoutDocument` view — as the one format every variant can reach. A composition engine (`convertDocument`) routes 111 (source, target) pairs across the ten content formats and PDF, including twenty PDF-pivot round trips (the eight layout-engine formats, plus xlsx and csv composing through ods), twenty-four cross-format bridge functions (same-variant direct copies, cross-variant semantic transforms, and PDF-composed), plus special-case conversions for `.odm` master documents, `.odb` database front-ends (HSQLDB and Firebird, four storage tiers), standalone `.odf` formula documents, and a bounded SQL/rpt-formula engine for `.odb` reports. Also includes: read-and-write live-view editors for all six editable formats, docx comment/footnote/header-footer exposure via `readDocxExtras`, real font resolution (source-embedded faces ahead of caller-supplied, vendored substitutes, and the standard 14), a hand-written MathML typesetting engine with embedded-font PDF rendering and a matching MathML ⇄ OMML translator, LaTeX lowering into the schema's two-layer semantic math core (pinned temml parser, symbol tables from prose, a coherence lint), and a fully hand-written PDF codec. Built on [ooxml.js](https://github.com/ExaDev/ooxml.js), [odf.js](https://github.com/ExaDev/odf.js), [pdf-codec](https://github.com/ExaDev/pdf-codec), [markdown-codec](https://github.com/ExaDev/markdown-codec), and [document-schema.js](https://github.com/ExaDev/document-schema.js).
5
+ > Converts between any two compatible document formats through a shared content/layout pivot. docx, pptx, odt, odp, ods, odg, xlsx, csv (TSV is the same format with a tab delimiter), svg, and markdown all read into and build from the same shared `ContentDocument` model (reported to callers as the tree-form `DocumentPackage`), with PDF — reached through pdf-codec's own `LayoutDocument` view — as the one format every variant can reach. A composition engine (`convertDocument`) routes 111 (source, target) pairs across the ten content formats and PDF, including twenty PDF-pivot round trips (the eight layout-engine formats, plus xlsx and csv composing through ods), twenty-four cross-format bridge functions (same-variant direct copies, cross-variant semantic transforms, and PDF-composed), plus special-case conversions for `.odm` master documents, `.odb` database front-ends (HSQLDB and Firebird, four storage tiers), standalone `.odf` formula documents, and a bounded SQL/rpt-formula engine for `.odb` reports. Also includes: read-and-write live-view editors for all six editable formats, docx comment/footnote/header-footer exposure via `readDocxExtras`, real font resolution (source-embedded faces ahead of caller-supplied, vendored substitutes, and the standard 14), a hand-written MathML typesetting engine with embedded-font PDF rendering and a matching MathML ⇄ OMML translator, LaTeX lowering into the schema's two-layer semantic math core (pinned temml parser, symbol tables from prose, a coherence lint), and a fully hand-written PDF codec. Built on [ooxml.js](../ooxml.js/README.md), [odf.js](../odf.js/README.md), [pdf-codec](../pdf-codec/README.md), [markdown-codec](../markdown-codec/README.md), and [document-schema.js](../document-schema.js/README.md).
6
6
 
7
7
  `documents.js` extends `ooxml.js` in two directions `ooxml.js` deliberately does not cover: full PDF support (parsing and generating, via `pdf-codec`), and a read-**and-write** manipulation API for docx/pptx content — `ooxml.js`'s own typed readers are one-way. The PDF codec is hand-written against ISO 32000-1, with no external PDF library as a dependency — see [Fidelity](#fidelity) and pdf-codec's own README for the honest trade-off (not as robust against adversarial PDFs as a 15+-year-hardened library; fully auditable and dependency-free instead). `src/mathml/` (the MathML typesetting engine) stays in this package and is hand-written too, for the same supply-chain reason. The one deliberate exception on the math side is the LaTeX parser: `src/latex/` lowers LaTeX into the schema's semantic core over a pinned exact-version [temml](https://temml.org) dependency — see [LaTeX lowering into the semantic core](#latex-lowering-into-the-semantic-core) for why a LaTeX grammar is the one component not worth hand-writing and what the pin guarantees.
8
8
 
@@ -35,15 +35,15 @@ graph TD
35
35
  odf --> cli
36
36
  pdfcodec --> cli
37
37
 
38
- click schema "https://github.com/ExaDev/document-schema.js" "document-schema.js"
39
- click ooxml "https://github.com/ExaDev/ooxml.js" "ooxml.js"
40
- click odf "https://github.com/ExaDev/odf.js" "odf.js"
41
- click pdfcodec "https://github.com/ExaDev/pdf-codec" "pdf-codec"
42
- click mdcodec "https://github.com/ExaDev/markdown-codec" "markdown-codec"
43
- click bytecodec "https://github.com/ExaDev/byte-codec" "byte-codec"
38
+ click schema "https://github.com/ExaDev/documents.js/tree/main/packages/document-schema.js" "document-schema.js"
39
+ click ooxml "https://github.com/ExaDev/documents.js/tree/main/packages/ooxml.js" "ooxml.js"
40
+ click odf "https://github.com/ExaDev/documents.js/tree/main/packages/odf.js" "odf.js"
41
+ click pdfcodec "https://github.com/ExaDev/documents.js/tree/main/packages/pdf-codec" "pdf-codec"
42
+ click mdcodec "https://github.com/ExaDev/documents.js/tree/main/packages/markdown-codec" "markdown-codec"
43
+ click bytecodec "https://github.com/ExaDev/documents.js/tree/main/packages/byte-codec" "byte-codec"
44
44
  click documents "https://github.com/ExaDev/documents.js" "documents.js"
45
- click mcp "https://github.com/ExaDev/document-mcp" "document-mcp"
46
- click cli "https://github.com/ExaDev/document-cli" "document-cli"
45
+ click mcp "https://github.com/ExaDev/documents.js/tree/main/packages/document-mcp" "document-mcp"
46
+ click cli "https://github.com/ExaDev/documents.js/tree/main/packages/document-cli" "document-cli"
47
47
 
48
48
  style documents fill:#f9a825,stroke:#333,stroke-width:3px
49
49
  ```
@@ -116,7 +116,7 @@ const pdfFromXlsx = xlsxToPdf(xlsxBytes); // composes xlsxToOds -> odsToPdf inte
116
116
  const xlsxBytes2 = pdfToXlsx(pdfFromXlsx); // composes pdfToOds -> odsToXlsx internally
117
117
 
118
118
  const pdfFromMarkdown = markdownToPdf(markdownBytes);
119
- const markdownBytes2 = pdfToMarkdown(pdfFromMarkdown); // the lossiest conversion in the whole package -- see Fidelity
119
+ const markdownBytes2 = pdfToMarkdown(pdfFromMarkdown); // the lossiest conversion in the whole package -- see Fidelity; it does carry page boundaries (one '<!-- page break -->' marker per page) and rank-inferred heading levels
120
120
 
121
121
  const pdfFromCsv = csvToPdf(csvBytes); // composes csvToOds -> odsToPdf internally
122
122
  const csvBytes2 = pdfToCsv(pdfFromCsv); // composes pdfToOds -> odsToCsv internally; recovers what was printed, then heuristically re-types it
@@ -127,6 +127,8 @@ const svgBytes2 = pdfToSvg(pdfFromSvg); // readPdf -> reconstructDrawing -> buil
127
127
 
128
128
  Each accepts an optional `signal` (`AbortSignal`) and either `onSubstitution` (X → PDF, called per character not representable in a standard-14 font) or `sink` (PDF → X, called per recoverable parse diagnostic). Every X → PDF conversion additionally accepts `fonts` (extra `ProvidedFont` faces) and `onFontSubstitution` (per family+weight+style that resolved to something else). Neither is needed for the common case — see [Fonts](#fonts).
129
129
 
130
+ **Cancellation granularity, for CPU-metered runtimes** (ExaDev/documents.js#585): every conversion here is synchronous end to end, and the `signal` is honoured at page boundaries — once per page in pdf-codec's `readPdf`/`writePdf` page loops and once per page in each of this package's four reconstructors (wordprocessing/presentation/drawing/spreadsheet). An abort arriving mid-conversion therefore takes effect at the next page boundary, not instantly: a single page's content-stream interpretation, pdf-codec's document-open phase, and the per-target build/encode stage after reconstruction are not interruptible, and parse cost is roughly linear in decompressed content length — budget for the worst single page, not the page count. A shared `AbortSignal` makes a deadline enforceable at that granularity on Cloudflare Workers; it cannot convert a synchronous conversion into a resumable or streaming one (an async page-at-a-time API is a deliberate non-goal of the current surface — see pdf-codec's README for the same statement from the codec side).
131
+
130
132
  ### Cross-format bridges
131
133
 
132
134
  Twenty-four bridge functions across twelve pairs bypass the PDF pivot where a direct path exists. Eight same-variant direct-copy pairs (`odtToDocx`/`docxToOdt`, `odpToPptx`/`pptxToOdp`, `odsToXlsx`/`xlsxToOds`, `csvToOds`/`odsToCsv`, `csvToXlsx`/`xlsxToCsv`, `svgToOdg`/`odgToSvg`, `markdownToDocx`/`docxToMarkdown`, `markdownToOdt`/`odtToMarkdown`) compose a direct `readXContent` → `buildYPackage` pivot copy — the csv pairs are one hop to its spreadsheet siblings, so csv never needs PDF to reach ods or xlsx, and `svgToOdg`/`odgToSvg` bridge svg to its drawing sibling odg the same way. Two cross-variant semantic-transform pairs (`docxToPptx`/`pptxToDocx`, `odtToOdp`/`odpToOdt`) go through `src/convert/variant-bridges.ts`. Two PDF-composed pairs (`xlsxToMarkdown`/`markdownToXlsx`, `csvToMarkdown`/`markdownToCsv`) route through PDF internally — the lossiest conversions in the package.
@@ -159,6 +161,8 @@ const { document, diagnostics } = await converter.convert(
159
161
 
160
162
  `DocumentFormat` includes `docx`/`pptx`/`xlsx`/`odt`/`odp`/`ods`/`odg`/`svg`/`odf`/`csv`/`markdown`/`pdf` — twelve members. The port's `conversions` list is derived from `resolveCompositionPlan` plus the `odf`→`pdf` special case — 111 pairs total. `DocumentFormat` is inferred from `DocumentFormatSchema` (a real Zod schema); `DOCUMENT_FORMATS` is exported as a plain array derived from the same schema:
161
163
 
164
+ The port also exposes `contractVersion: number`, bumped only when `DocumentConverter`'s own contract shape changes — a new field on `ConversionResult` a caller might need to branch on, or a new `ConversionOptions` field an implementation is now expected to honour — never when the `conversions` table simply grows with more supported source/target pairs (that's discoverable at runtime via `conversions` itself). It is currently `7`: the bump from `6` reflects `ConversionResult.package` changing type to the tree-form `DocumentPackage` described below, which a caller reading that field must now flatten rather than read directly.
165
+
162
166
  ```ts
163
167
  import { DOCUMENT_FORMATS, DocumentFormatSchema } from 'documents.js';
164
168
 
@@ -187,7 +191,7 @@ const pdfBytes = docxToPdf(docxBytes, {
187
191
 
188
192
  The tree and the flat `ContentDocument` are one format in two encodings, related by three laws (stated on [document-schema.js#20](https://github.com/ExaDev/document-schema.js/issues/20), proven over this package's real corpus by the bijection suite in `src/convert/bijection.test.ts`): (i) `flattenPackage(assemblePackage(c))` reproduces `c` exactly, up to one declared normalisation (a present-but-empty sheet `embeddedObjects` array normalises to the field absent); (ii) effective-property equality holds universally — a factored and an unfactored serialisation of one document resolve to the same properties; (iii) minting is idempotent — factoring a second time produces the identical styles table.
189
193
 
190
- Three flat-form signals drive the grouping, and all three are reproduced exactly on the way back: `headingLevel`, `list.level`, and — since document-schema.js 4.2.0 — the `constructStart`/`constructEnd` block pair that delimits a fidelity construct (a docx SDT, an ODF field, a tracked-change span, a bookmark, a hyperlink region, a division). `decompose` promotes each marker pair to a construct group carrying the `ConstructDescriptor` and holding the delimited region as its children, decomposed on its own; `flattenPackage` writes the pair back around that region. A construct is a semantic wrapper rather than a container, so it neither disturbs the enclosing heading/list nesting it sits inside nor resets the style chain resolving onto it — content inside a construct still inherits the ambient heading's or section's factored properties, exactly as if the construct were not there. Markers must pair up within one container's block flow: an unmatched `constructEnd`, or a `constructStart` a container never closes, throws document-schema.js's `ConstructMarkerImbalanceError` (carrying its `ConstructMarkerImbalance` payload, so the offending block index is available without parsing the message) rather than being repaired into a plausible tree. The format codecs do not emit markers yet — construct extraction per format is tracked separately on [document-schema.js#22](https://github.com/ExaDev/document-schema.js/issues/22) — but the decompose/flatten boundary itself handles them today, so a caller hand-building marker content needs no change at that boundary specifically. Reaching further than the boundary is a mixed picture, not a blanket guarantee: `buildMarkdownText` refuses a marker with the named `MarkdownConstructUnsupportedError` rather than crashing inside markdown-codec's own writer, which has no arm for either marker kind; building docx/odt bytes back from marker-carrying flat content silently drops the markers, since neither builder reads or writes them yet; and the layout engines (`convertWordprocessingToLayout`, `convertShape`) silently skip a marker block during pagination — harmless there, since a marker carries no content of its own to render.
194
+ Three flat-form signals drive the grouping, and all three are reproduced exactly on the way back: `headingLevel`, `list.level`, and — since document-schema.js 4.2.0 — the `constructStart`/`constructEnd` block pair that delimits a fidelity construct (a docx SDT, an ODF field, a tracked-change span, a bookmark, a hyperlink region, a division). `decompose` promotes each marker pair to a construct group carrying the `ConstructDescriptor` and holding the delimited region as its children, decomposed on its own; `flattenPackage` writes the pair back around that region. A construct is a semantic wrapper rather than a container, so it neither disturbs the enclosing heading/list nesting it sits inside nor resets the style chain resolving onto it — content inside a construct still inherits the ambient heading's or section's factored properties, exactly as if the construct were not there. Markers must pair up within one container's block flow: an unmatched `constructEnd`, or a `constructStart` a container never closes, throws document-schema.js's `ConstructMarkerImbalanceError` (carrying its `ConstructMarkerImbalance` payload, so the offending block index is available without parsing the message) rather than being repaired into a plausible tree. The format codecs do not emit markers yet — construct extraction per format is tracked separately on [document-schema.js#22](https://github.com/ExaDev/document-schema.js/issues/22) — but the decompose/flatten boundary itself handles them today, so a caller hand-building marker content needs no change at that boundary specifically. Reaching further than the boundary is a mixed picture, not a blanket guarantee: `buildMarkdownText` passes markers through to markdown-codec's own bracket-resolving writer, which renders each construct it has a markdown spelling for (a footnote definition, a blockquote division, a titled image's link wrapper) and renders the rest transparently with a diagnostic markdown-codec's own read side emits those pairs, so this package's editor and conversion round trips depend on it; building docx/odt bytes back from marker-carrying flat content silently drops the markers, since neither builder reads or writes them yet; and the layout engines (`convertWordprocessingToLayout`, `convertShape`) silently skip a marker block during pagination — harmless there, since a marker carries no content of its own to render.
191
195
 
192
196
  `assemblePackage` is the one constructor behind every construction site — decompose, then `factorStyles`, the minting pass that hoists property tuples occurring two or more times onto a group-wrapper ref plus a `styles` table entry (deterministic order; `frames`/`sourcePath`/`styleId` are per-node facts and never factor). The transform belongs to `document-schema.js`, which owns both encodings and publishes `assemblePackage`, `decompose`, `flattenPackage`, `factorStyles`, `ConstructMarkerImbalanceError`, and the `PackageChildren` type for any caller composing its own boundary — import them from there, not from this package. documents.js consumes that transform at its own boundary and re-exports none of it; the readers, builders, layout engines, and editors here keep producing and consuming the flat form, so the tree exists only where a `DocumentPackage` is constructed or consumed:
193
197
 
@@ -234,7 +238,7 @@ const docxBytesAgain = encodeDocumentPackage('docx', pkg);
234
238
  const odbPkg = decodeOdbPackage(odbBytes);
235
239
  ```
236
240
 
237
- `readDocumentMetadata`/`setDocumentMetadata` read or patch metadata across any `DocumentFormat`. `setDocumentMetadata` patches in place (source/target formats must match); `odf` is rejected in both directions, and `csv` is rejected in both directions too (RFC 4180 text has no metadata container) — `readDocumentMetadata('csv', ...)` answers an empty `LayoutMetadata` for the same reason. `svg` reads its root `<title>` as `metadata.title` and is rejected as a `setDocumentMetadata` source/target for the mirror-image reason: `<title>` is svg's whole metadata surface, so any other override would be silently dropped by the rebuild. `readDocumentMetadata('xlsx', ...)` is a named exception: it renders via `xlsxToPdf` and reads the PDF's metadata, because a direct read and the PDF-preview path genuinely disagree on `createdIso`/`modifiedIso`/`producer`.
241
+ `readDocumentMetadata`/`setDocumentMetadata` read or patch metadata across any `DocumentFormat`. `setDocumentMetadata` patches in place (source/target formats must match); `odf` is rejected in both directions, and `csv` is rejected in both directions too (RFC 4180 text has no metadata container) — `readDocumentMetadata('csv', ...)` answers an empty `LayoutMetadata` for the same reason. `svg` reads its root `<title>` as `metadata.title` and is rejected as a `setDocumentMetadata` source/target for the mirror-image reason: `<title>` is svg's whole metadata surface, so any other override would be silently dropped by the rebuild. `readDocumentMetadata('xlsx', ...)` reads the workbook's own `docProps` like every other content format — `createdIso`/`modifiedIso` from `docProps/core.xml` when the file declares them, `docProps/app.xml`'s Application as `creator`, and `producer` unset (a PDF-only concept no semantic reader sets). It previously rendered a `xlsxToPdf` preview and read that PDF's metadata instead, which for a file carrying no timestamps of its own reported facts about the render rather than the workbook: timestamps stamped at the render moment and a producer naming the preview PDF's writer.
238
242
 
239
243
  ```ts
240
244
  import { readDocumentMetadata, setDocumentMetadata } from 'documents.js';
@@ -250,6 +254,14 @@ import { emuToPt } from 'documents.js/model/units';
250
254
  import { buildOdtPackage } from 'documents.js/edit/odt/content';
251
255
  ```
252
256
 
257
+ One subpath is a declared entry point in its own right: **`documents.js/read`** (an explicit `exports` entry onto `src/convert/from-pdf.ts`, where the `pdfTo*` family lives). A consumer that only ever converts FROM pdf and imports the root barrel statically reaches every X-to-PDF renderer — and through pdf-codec's root barrel, ~2.9 MB of vendored font binaries it can never execute, which on Cloudflare Workers' free plan (3 MB gzipped for an entire Worker) is most of the budget. The read entry's module graph provably excludes them, all the way across the workspace boundary into pdf-codec's own source:
258
+
259
+ ```ts
260
+ import { pdfToMarkdown } from 'documents.js/read';
261
+ ```
262
+
263
+ It carries the ten `pdfTo*` conversions, `PdfToDocumentOptions`, and `readDocumentMetadata` (with `ReadDocumentMetadataOptions`) — identical functions to the root barrel's (the same forwarders, run through the composition engine's read half, and the same metadata reader dispatched through the read-only codec half `src/codecs/read.ts`), never a forked behaviour; `convertDocument` and every X-to-PDF direction stay on the root barrel. `src/read-graph.test.ts` walks the entry's static import graph, follows `pdf-codec` specifiers through that package's real `exports` map into its source, and fails the build if the write path or any font asset becomes reachable.
264
+
253
265
  ### Reading and building xlsx content directly
254
266
 
255
267
  Every other content format has its own standalone `readXContent`-shaped entry point (`readDocxContent`, `readPptxContent`, `readOdtContent`, `readOdpContent`, `readOdsContent`, `readOdgContent`) — xlsx is no longer the exception. `readXlsxContent`/`buildXlsxPackage` are this package's names for `ooxml.js`'s own spreadsheet `ContentDocument` read/build pair — the same one the `ods⇄xlsx` bridge and every xlsx metadata-rebuild path already use internally — re-exported here directly rather than wrapped, since `readXlsxContent` already produces the right shape on its own. (Since `ooxml.js` 4.0.0 the upstream flat builder is named `buildXlsxPackageFromContent` — the bare `buildXlsxPackage` name moved to that package's tree-form `DocumentPackage` builder — so this package re-exports the flat builder under its own long-standing `buildXlsxPackage` name and the `ContentDocument`-in/`Package`-out contract is unchanged.) csv's `readCsvContent`/`buildCsvText` are the same kind of directly-exported stage pair, one level further in: they operate on RFC 4180 text rather than a decoded package (see `src/csv/` under Architecture). svg's `readSvgContent`/`buildSvgText` are the drawing-variant counterpart of csv's pair, operating on SVG text rather than a decoded package (see `src/svg/` under Architecture).
@@ -553,11 +565,11 @@ The package is layered from generic primitives outward to the two conversion dir
553
565
  - **`src/markdown/`** — third adapter family, via `markdown-codec`. `readMarkdownContent` passes `readMarkdownContent`'s (markdown-codec's flat reader, so named since that package's 4.0.0; the bare `readMarkdown` name is now its tree-form `DocumentPackage` reader) result through the math-lowering pass (`math.ts` — markdown-codec's preserved `$$` display blocks and `\( \)` inline spans become two-layer formula blocks, with the document's symbol table seeded from its own prose). `buildMarkdownText` wraps `writeMarkdownContent`, reconstructing markdown math syntax from formula blocks carrying a presentation layer. `text.ts` is the byte↔text boundary. `MarkdownEditor` holds a mutable in-memory `ContentDocument`.
554
566
  - **`src/csv/`** — fourth adapter family, sharing the spreadsheet variant with xlsx/ods. `records.ts` is the RFC 4180 record parser/writer (one shared `quoteCsvField`, also used by the `.odb` CSV exporter); `text.ts` is the byte↔text boundary, rejecting malformed UTF-8; `read.ts` turns records into a spreadsheet `ContentDocument` (first record as verbatim string header, data cells through the same cell-typing heuristic `pdfToOds` uses); `write.ts` turns one sheet of a spreadsheet `ContentDocument` back into records via each cell's `displayText`. TSV is the same format with `{ delimiter: '\t' }` on either side.
555
567
  - **`src/svg/`** — fifth adapter family, sharing the drawing variant with odg. `text.ts` is the byte↔text boundary, rejecting malformed UTF-8; `read.ts` maps the six SVG shape primitives (rect/circle/ellipse/line/polyline/polygon/path) onto a one-page drawing `ContentDocument`, with transform lists composed as 2×3 affines and CSS lengths and the viewBox map resolved into page points; `write.ts` writes the six primitives back out, one shape element each; `path.ts` is the full SVG path-data grammar (M/L/H/V/C/S/Z plus Q/T/A and the relative forms — S/Q/T convert exactly, A is the one bounded approximation at ≤90° per cubic); `transform.ts` parses and composes the transform attribute and classifies the result by frame representability; `units.ts` resolves CSS length units and the viewBox; `paint.ts` resolves fill/stroke presentation attributes and dash styles; `diagnostics.ts` is the shared scope-limit vocabulary.
556
- - **`src/layout/`** — the pure conversion algorithms: `engine.ts` (wordprocessing → layout: flow, line-breaking, pagination), `slides.ts` (presentation → layout: direct placement), `sheets.ts` (spreadsheet → layout: grid, print settings, the first algorithm accepting `AbortSignal`), `drawing.ts` (drawing → layout: vector primitives + shape reuse), `reconstruct.ts` (layout → content: baseline clustering for wordprocessing/presentation, near-1:1 mapping for drawing, gridline-lattice-or-text-clustering for spreadsheet).
568
+ - **`src/layout/`** — the pure conversion algorithms: `engine.ts` (wordprocessing → layout: flow, line-breaking, pagination), `slides.ts` (presentation → layout: direct placement), `sheets.ts` (spreadsheet → layout: grid, print settings, the first algorithm accepting `AbortSignal`), `drawing.ts` (drawing → layout: vector primitives + shape reuse), `reconstruct.ts` (layout → content: baseline clustering for wordprocessing/presentation, near-1:1 mapping for drawing, gridline-lattice-or-text-clustering for spreadsheet; plus the PDF construct surfacing — link reconciliation to `ContentRun.hyperlink` or link constructs, hidden-layer content dropped, anchor/comment and AcroForm contentControl constructs).
557
569
  - **`src/hsqldb/`** — `.odb` decoders, four tiers: `script.ts` (TEXT-script DDL/DML parser), `rowformat.ts`/`cache.ts` (CACHED binary row-store), `binary-script.ts` (BINARY/COMPRESSED whole-script). All import only `document-schema.js` — no odf.js knowledge.
558
570
  - **`src/firebird/`** — Tier 3: gbak logical-backup reader. `reader.ts` (attribute framing + RLE decompression + XDR decoding), `schema.ts`/`data.ts` (table/row walking). No ratified spec — built against Firebird's own engine source.
559
571
  - **`src/odb/`** — decoder-selection and pivot-mapping: `read.ts` routes to the right tier, `spreadsheet.ts`/`csv.ts` map to output formats. `odb/sql/` is the bounded SQL engine, `odb/formula/` is the rpt formula engine, `odb/report/` is the renderer, `odb/values.ts` is shared comparison/aggregation semantics.
560
- - **`src/convert/`** — the composition layer: `convert.ts` (all named functions + `convertDocument` + `resolveCompositionPlan`), `composition.ts` (the pathfinder and primitive registry), `codec.ts` (`z.codec()` pairs), `port.ts`/`local.ts` (the `DocumentConverter` port), `variant-bridges.ts` (cross-variant semantic transforms), and `from-package.ts` (`buildDocumentBytes`, which flattens once at the boundary). The tree ⇄ flat transform those construction sites call — `assemblePackage`, `decompose`, `flattenPackage`, `factorStyles` — is not implemented here: it lives in `document-schema.js`, which owns both encodings. `bijection.test.ts` is this package's own gate on it, re-running the three laws over the real corpus every reader, editor, and conversion here produces.
572
+ - **`src/convert/`** — the composition layer: `convert.ts` (the named conversion functions and their option types), `composition.ts` (the pathfinder, the primitive registry, the bridge/fromPdf executors, and `convertDocumentFromPdf` — the read half of the engine), `composition-to-pdf.ts` (`executeToPdf`, the layout-engine registry, and the full `convertDocument` binding — the write half, split out so a read-only consumer never statically imports a renderer), `from-pdf.ts` (the `pdfTo*` family and the `documents.js/read` entry), `codec.ts` (`z.codec()` pairs), `port.ts`/`local.ts` (the `DocumentConverter` port), `variant-bridges.ts` (cross-variant semantic transforms), and `from-package.ts` (`buildDocumentBytes`, which flattens once at the boundary). The tree ⇄ flat transform those construction sites call — `assemblePackage`, `decompose`, `flattenPackage`, `factorStyles` — is not implemented here: it lives in `document-schema.js`, which owns both encodings. `bijection.test.ts` is this package's own gate on it, re-running the three laws over the real corpus every reader, editor, and conversion here produces.
561
573
  - **`src/codecs/`** — `DOCUMENT_FORMAT_CODECS`: every format's read/build capability as data, so `readDocumentMetadata`/`setDocumentMetadata`/`buildDocumentBytes` dispatch through one registry.
562
574
  - **`src/metadata/`** — cross-format metadata read/write via `DOCUMENT_FORMAT_CODECS`.
563
575
  - **`src/package-codec.ts`** — `decodeDocumentPackage`/`encodeDocumentPackage`/`decodeOdbPackage`.
@@ -587,7 +599,7 @@ To run a single test file: `pnpm vitest run src/path/to/file.test.ts`.
587
599
  - **Live views, not flatten-and-regenerate.** Editor classes hold a reference into the real `Package`/`XmlElement` objects; saving is `encodePackage(pkg)`.
588
600
  - **Three-tier PDF-read failure policy** — throw for unprocessable files, recover-with-diagnostic for malformed-but-salvageable, degrade-with-diagnostic for unsupported features. See pdf-codec's README.
589
601
  - **Conventional commits**, enforced via commitlint + husky.
590
- - **Worker-isomorphic runtime.** `src/` is typechecked against a web-only environment (`lib: ["ES2024", "WebWorker"]`, no `@types/node`); `eslint` bans Node-only imports/globals; `test:workers` proves PDF-bypassing paths run in `workerd`.
602
+ - **Worker-isomorphic runtime.** `src/` is typechecked against a web-only environment (`lib: ["ES2024", "WebWorker"]`, no `@types/node`); `eslint` bans Node-only imports/globals; `test:workers` proves both the PDF-bypassing paths and the PDF pivot itself (`pdfToMarkdown` through the read-only entry module, `markdownToPdf` through the full write path) run in `workerd`.
591
603
 
592
604
  ## Gotchas and quirks
593
605
 
@@ -666,10 +678,10 @@ To run a single test file: `pnpm vitest run src/path/to/file.test.ts`.
666
678
  - **OMML read/write are deliberately asymmetric** — the reader covers more (`m:d`, `m:nary`, `m:acc`, `m:bar`, `m:func`, `m:sPre`) because it must read what Word wrote. `docx → odt → docx` round trips keep the mathematics but may change the OMML construct.
667
679
  - **The OMML translator covers exactly what `src/mathml/layout.ts` typesets.** A stretchy fence diverges: PDF stretches it, docx writes it at base size. `munderover` becomes nested `m:limUpp`/`m:limLow` (no operand scope in MathML).
668
680
  - **`sourcePath` traces a `LayoutItem` to its `ContentDocument` origin, but only within one read+layout pass** — not an edit-tracking mechanism. Since the frames fusion it survives as traceability only: the authoritative node↔position association is each content node's own `frames`, stamped at the moment of layout (or of reconstruction) rather than re-matched by string afterwards.
669
- - **`readMarkdownContent` runs markdown-codec's result through the math-lowering pass** — `markdown-codec` already produces a full `ContentDocument`, but it deliberately carries `$$` display blocks and `\( \)` inline spans through as raw LaTeX text (styled paragraphs and marker runs); the pass lowers that LaTeX into two-layer formula blocks so markdown math typesets, edits, and computes like math from any other format (see [LaTeX lowering into the semantic core](#latex-lowering-into-the-semantic-core)).
670
- - **Every markdown construct-mapping gap is a documented `MarkdownDiagnosticCodes` entry** (`md/invented-page-geometry`, `md/nested-emphasis-flattened`, `md/link-title-dropped`, `md/code-block-info-string-dropped`, `md/blockquote-nested-depth`, `md/list-item-block-unlisted`, `md/list-item-multi-block-flattened`, `md/image-unresolved`, `md/raw-html-preserved-as-text`/`md/raw-html-dropped`, `md/front-matter-key-unmapped`, `md/heading-level-clamped`, `md/adjacent-links-merged`, `md/code-span-as-monospace-run`, `md/paragraph-indent-dropped`, `md/list-numid-fallback`, `md/table-cell-formatting-dropped`, `md/table-cell-multi-paragraph-joined`) — never a silent approximation.
681
+ - **`readMarkdownContent` runs markdown-codec's result through the math-lowering pass** — `markdown-codec` already produces a full `ContentDocument`, but it deliberately stops short of lowering math: a `$$` display block arrives as an embedded formula object holding only the verbatim presentation LaTeX, an inline `\( \)` span as a Cambria-Math-marked raw-LaTeX run; the pass lowers that LaTeX into two-layer formula blocks so markdown math typesets, edits, and computes like math from any other format (see [LaTeX lowering into the semantic core](#latex-lowering-into-the-semantic-core)).
682
+ - **Every markdown construct-mapping gap is a documented `MarkdownDiagnosticCodes` entry** (`md/invented-page-geometry`, `md/nested-emphasis-flattened`, `md/link-title-dropped`, `md/blockquote-container-skipped`, `md/list-item-block-unlisted`, `md/image-unresolved`, `md/raw-html-preserved-as-text`/`md/raw-html-dropped`, `md/front-matter-key-unmapped`, `md/heading-level-clamped`, `md/adjacent-links-merged`, `md/code-span-as-monospace-run`, `md/paragraph-indent-dropped`, `md/list-numid-fallback`, `md/table-cell-formatting-dropped`, `md/table-cell-multi-paragraph-joined`) — never a silent approximation. The info-string, multi-block-item, and blockquote-depth gaps that used to be in this list are closed: a fence's language word rides `ContentParagraph.codeLanguage`, item identity rides `ContentListMembership.itemId`, and a blockquote carries a `division` construct pair.
671
683
  - **`buildMarkdownText` throws for non-`'wordprocessing'` `ContentDocument`.**
672
- - **`buildMarkdownText` throws `MarkdownConstructUnsupportedError` for a `constructStart`/`constructEnd` marker** CommonMark/GFM has no spelling for a construct wrapper and, unlike an embedded formula, no plain-text stand-in either (a division's column count or a tracked-change's author has nothing defensible to render as visible text), so this is a refusal rather than a degradation. Named so a caller can branch on it and, for a `constructStart`, read the wrapped `ConstructDescriptor`'s own `kind` (`contentControl`/`field`/`anchor`/`link`/`provenance`/`division`) off `descriptorKind` without parsing the message.
684
+ - **`buildMarkdownText` passes `constructStart`/`constructEnd` markers through to markdown-codec's own writer**, which resolves them as balanced brackets: a construct with a markdown spelling renders as that syntax (a footnote definition, a blockquote division, a titled image's link wrapper), one without renders its extent transparently under a diagnostic. A genuinely unbalanced list still throws — markdown-codec's own `MarkdownUnbalancedConstructMarkersError`, the shared definition of that check. The old `MarkdownConstructUnsupportedError` refusal is gone: markdown-codec's read side now emits marker pairs of its own (blockquotes, titled images), so a writer that refused markers would refuse this package's own editor round trips.
673
685
  - **`decodeMarkdownText` throws on malformed UTF-8** rather than producing U+FFFD.
674
686
  - **The composition engine routes every pair generically** through a declarative primitive registry and minimum-cost pathfinder. `resolveCompositionPlan` finds the minimum-cost route (same-variant bridge < cross-variant transform < via-PDF multi-hop). Named functions are thin forwarders.
675
687
 
@@ -706,7 +718,7 @@ Read as **row → column**. `✓` lossless, `~` bounded, `✗` lossy, `✗✗` s
706
718
 
707
719
  **PDF → ods** recovers what was printed, not what was entered. The printed string always survives in `displayText`; re-typed `value` is explicitly probabilistic inference.
708
720
 
709
- **`markdownToPdf`/`pdfToMarkdown`** is the lossiest round trip: `markdownToPdf` is faithful, but `pdfToMarkdown` stacks reconstruction lossiness PLUS markdown's coarser vocabulary (no colour, font, size, alignment). The PDF-composed markdown bridges (`xlsxToMarkdown`/`markdownToXlsx`, `csvToMarkdown`/`markdownToCsv`) stack the same two losses in both directions — hence their `✗✗` cells.
721
+ **`markdownToPdf`/`pdfToMarkdown`** is the lossiest round trip: `markdownToPdf` is faithful, but `pdfToMarkdown` stacks reconstruction lossiness PLUS markdown's coarser vocabulary (no colour, font, size, alignment). Two structure signals do survive it (ExaDev/documents.js#584): every page boundary arrives as an exact `<!-- page break -->` marker (one per boundary — the one fact a rendered PDF states precisely), and headings are inferred from font size — each distinct size at least 2pt above the document's modal body size is a heading, ranked largest-first into `Heading1..6`, which inverts this package's own heading render sizes exactly and is a heuristic (the well-worn "largest text is the title" reading) for any other producer. Tables reach markdown as GFM pipe tables wherever the gridline-lattice gate succeeds; a table rendered without drawn gridlines (which includes every `markdownToPdf`-authored one, markdown carrying no border concept) correctly comes back as tab-separated prose rather than invented structure. The PDF-composed markdown bridges (`xlsxToMarkdown`/`markdownToXlsx`, `csvToMarkdown`/`markdownToCsv`) stack the same two losses in both directions — hence their `✗✗` cells.
710
722
 
711
723
  **The six same-variant bridge pairs** (odt⇄docx, odp⇄pptx, ods⇄xlsx, csv⇄ods, csv⇄xlsx, svg⇄odg) bypass PDF entirely — no layout engine, no reconstruction. Text, styling, tables, lists, rotated shapes survive completely. `ods⇄xlsx` has small format-boundary limits (time cells, formula dialects). Embedded formulas survive `odtToDocx` as real OOXML math. The csv pairs are bounded by what csv itself carries: toward ods/xlsx nothing the csv had is lost, while writing to csv collapses each cell to its `displayText` — formulas become their rendered values, formatting disappears, and a multi-sheet source must name the sheet it wants. The svg pair carries the six vector primitives losslessly in both directions; its one asymmetry is paint defaults — SVG's absent-fill-is-black versus a drawing frame's no-fill.
712
724
 
@@ -722,29 +734,31 @@ Read as **row → column**. `✓` lossless, `~` bounded, `✗` lossy, `✗✗` s
722
734
 
723
735
  ## Release and publishing
724
736
 
725
- `.github/workflows/ci.yml` runs commitlint, lint, typecheck, unit suite, and smoke test on every push/PR. On push to `main` where all pass, `release.config.ts` drives semantic-release: commit history decides the version bump, `CHANGELOG.md` and `package.json` are committed back, a GitHub Release is cut, and the package publishes to npmjs.org via OIDC trusted publishing (no `NPM_TOKEN`). Publication is detected by diffing `package.json`'s version before/after. A second job republishes under `@exadev/documents.js` to GitHub Packages; a third generates an SPDX SBOM and signs build-provenance attestations.
737
+ Release, CI, and commit-message conventions are all workspace-wide, not package-local see the [monorepo root README](../../README.md#releases) for the mechanism (topological per-package `semantic-release` via `@exadev/semantic-release-workspace`, OIDC trusted npm publishing, automatic sibling dependency-range rewriting) and its [known gap](../../README.md#releases) note on GitHub Packages republishing and SBOM/provenance signing, both dropped in the migration to this monorepo and not yet restored.
726
738
 
727
739
  ## Contributing
728
740
 
729
- Conventional Commits (`feat:`, `fix:`, `test:`, `chore:`, …), enforced by commitlint via a husky `commit-msg` hook — semantic-release's version bump depends on these. `pre-commit` runs `lint-staged`; `pre-push` runs the test suite. Single `main` branch, no open PR workflow established.
741
+ Conventional Commits, enforced workspace-wide by commitlint through a root `commit-msg` hook. Work inside `packages/documents.js/`; see [CONTRIBUTING.md](../../CONTRIBUTING.md) for the shared git hooks and history conventions.
730
742
 
731
743
  ## References
732
744
 
733
- - [ooxml.js](https://github.com/ExaDev/ooxml.js) — docx/pptx/xlsx ⇄ JSON handling and typed reading, including `readXlsxContent` and the flat spreadsheet builder it pairs with, `buildXlsxPackageFromContent` (consumed by the `odsToXlsx`/`xlsxToOds` bridge and internal codecs, and re-exported directly from this package's own surface under the long-standing `buildXlsxPackage` name — see [Reading and building xlsx content directly](#reading-and-building-xlsx-content-directly)).
734
- - [document-schema.js](https://github.com/ExaDev/document-schema.js) — owns `ContentDocument`, the tree-form `DocumentPackage` and its styles-table facility, and the port contracts; shared by all sibling packages.
735
- - [markdown-codec](https://github.com/ExaDev/markdown-codec) — CommonMark+GFM ⇄ `ContentDocument` handling. The third format (after docx/odt) sharing the wordprocessing pivot.
736
- - [pdf-codec](https://github.com/ExaDev/pdf-codec) — the hand-written PDF codec (`readPdf`/`writePdf`/`pdfCodec`), the embedded STIX Two Math font, and text-measurement/font-resolution primitives.
737
- - [byte-codec](https://github.com/ExaDev/byte-codec) — generic byte/image utilities (ByteWriter, CRC-32, deflate/inflate, PNG/JPEG), extracted from pdf-codec.
738
- - [odf.js](https://github.com/ExaDev/odf.js) — ODF codec (odt/ods/odp/odg), also built on `document-schema.js`. Style interning, rotation, `svg:d` parsing, and manifest handling consumed directly.
745
+ - [ooxml.js](../ooxml.js/README.md) — docx/pptx/xlsx ⇄ JSON handling and typed reading, including `readXlsxContent` and the flat spreadsheet builder it pairs with, `buildXlsxPackageFromContent` (consumed by the `odsToXlsx`/`xlsxToOds` bridge and internal codecs, and re-exported directly from this package's own surface under the long-standing `buildXlsxPackage` name — see [Reading and building xlsx content directly](#reading-and-building-xlsx-content-directly)).
746
+ - [document-schema.js](../document-schema.js/README.md) — owns `ContentDocument`, the tree-form `DocumentPackage` and its styles-table facility, and the port contracts; shared by all sibling packages.
747
+ - [markdown-codec](../markdown-codec/README.md) — CommonMark+GFM ⇄ `ContentDocument` handling. The third format (after docx/odt) sharing the wordprocessing pivot.
748
+ - [pdf-codec](../pdf-codec/README.md) — the hand-written PDF codec (`readPdf`/`writePdf`/`pdfCodec`), the embedded STIX Two Math font, and text-measurement/font-resolution primitives.
749
+ - [byte-codec](../byte-codec/README.md) — generic byte/image utilities (ByteWriter, CRC-32, deflate/inflate, PNG/JPEG), extracted from pdf-codec.
750
+ - [odf.js](../odf.js/README.md) — ODF codec (odt/ods/odp/odg), also built on `document-schema.js`. Style interning, rotation, `svg:d` parsing, and manifest handling consumed directly.
739
751
  - [STIX Two Math](https://github.com/stipub/stixfonts) — the embedded math font. Vendored within pdf-codec (OFL-1.1).
740
752
  - [firebirdsql/firebird](https://github.com/FirebirdSQL/firebird) — ground truth for `src/firebird/`, since gbak backup format has no ratified spec. Read as source material only, not a build/runtime dependency.
741
753
 
742
754
  ## npm aliases
743
755
 
744
- This package also publishes under:
756
+ This package also published under an alternate name from the pre-monorepo pipeline:
745
757
 
746
758
  - [js.documents](https://www.npmjs.com/package/js.documents)
747
759
 
760
+ **Frozen since the monorepo migration** — see the [root README's release note](../../README.md#releases): the alias republish step was dropped along with GitHub Packages mirroring and SBOM/provenance signing, and nothing today keeps this name in sync with `documents.js`'s own releases. Tracked in [ExaDev/documents.js#731](https://github.com/ExaDev/documents.js/issues/731).
761
+
748
762
  ## License
749
763
 
750
764
  MIT
@@ -0,0 +1,22 @@
1
+ import { ContentCellValue } from "document-schema.js";
2
+ //#region src/layout/cell-typing.d.ts
3
+ type CellTypeRule = 'boolean-literal' | 'iso-date' | 'named-month-date' | 'plain-number' | 'grouped-number' | 'percentage' | 'currency';
4
+ type CellTypeDeclineReason = 'ambiguous-boolean-word' | 'ambiguous-date-order' | 'ambiguous-grouping-separator' | 'leading-zero-digits' | 'precision-loss';
5
+ type CellTypeInferenceResult = {
6
+ readonly outcome: 'retyped';
7
+ readonly value: ContentCellValue;
8
+ readonly rule: CellTypeRule;
9
+ } | {
10
+ readonly outcome: 'declined';
11
+ readonly reason: CellTypeDeclineReason;
12
+ };
13
+ type CellTypeInference = {
14
+ readonly sheetIndex: number;
15
+ readonly row: number;
16
+ readonly column: number;
17
+ readonly displayText: string;
18
+ } & CellTypeInferenceResult;
19
+ type CellTypeInferenceSink = (inference: CellTypeInference) => void;
20
+ declare function inferCellValue(displayText: string): CellTypeInferenceResult | undefined;
21
+ //#endregion
22
+ export { CellTypeRule as a, CellTypeInferenceSink as i, CellTypeInference as n, inferCellValue as o, CellTypeInferenceResult as r, CellTypeDeclineReason as t };
@@ -0,0 +1,22 @@
1
+ import { ContentCellValue } from "document-schema.js";
2
+ //#region src/layout/cell-typing.d.ts
3
+ type CellTypeRule = 'boolean-literal' | 'iso-date' | 'named-month-date' | 'plain-number' | 'grouped-number' | 'percentage' | 'currency';
4
+ type CellTypeDeclineReason = 'ambiguous-boolean-word' | 'ambiguous-date-order' | 'ambiguous-grouping-separator' | 'leading-zero-digits' | 'precision-loss';
5
+ type CellTypeInferenceResult = {
6
+ readonly outcome: 'retyped';
7
+ readonly value: ContentCellValue;
8
+ readonly rule: CellTypeRule;
9
+ } | {
10
+ readonly outcome: 'declined';
11
+ readonly reason: CellTypeDeclineReason;
12
+ };
13
+ type CellTypeInference = {
14
+ readonly sheetIndex: number;
15
+ readonly row: number;
16
+ readonly column: number;
17
+ readonly displayText: string;
18
+ } & CellTypeInferenceResult;
19
+ type CellTypeInferenceSink = (inference: CellTypeInference) => void;
20
+ declare function inferCellValue(displayText: string): CellTypeInferenceResult | undefined;
21
+ //#endregion
22
+ export { CellTypeRule as a, CellTypeInferenceSink as i, CellTypeInference as n, inferCellValue as o, CellTypeInferenceResult as r, CellTypeDeclineReason as t };
@@ -0,0 +1,66 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_model_bytes = require("../model/bytes.cjs");
3
+ const require_markdown_read = require("../markdown/read.cjs");
4
+ const require_ooxml_docx_read = require("../ooxml/docx/read.cjs");
5
+ const require_ooxml_pptx_read = require("../ooxml/pptx/read.cjs");
6
+ const require_odf_formula_read = require("../odf/formula/read.cjs");
7
+ const require_odf_odt_read = require("../odf/odt/read.cjs");
8
+ const require_odf_odp_read = require("../odf/odp/read.cjs");
9
+ const require_odf_ods_read = require("../odf/ods/read.cjs");
10
+ const require_odf_odg_read = require("../odf/odg/read.cjs");
11
+ const require_markdown_text = require("../markdown/text.cjs");
12
+ const require_csv_text = require("../csv/text.cjs");
13
+ const require_csv_read = require("../csv/read.cjs");
14
+ const require_svg_text = require("../svg/text.cjs");
15
+ const require_svg_read = require("../svg/read.cjs");
16
+ const require_ports_abort = require("../ports/abort.cjs");
17
+ const require_package_codec = require("../package-codec.cjs");
18
+ let ooxml_js = require("ooxml.js");
19
+ let pdf_codec_read = require("pdf-codec/read");
20
+ //#region src/codecs/read.ts
21
+ const CONTENT_READERS = {
22
+ docx: (bytes, options) => {
23
+ require_ports_abort.throwIfAborted(options?.signal);
24
+ return require_ooxml_docx_read.readDocxContent(require_package_codec.decodeDocumentPackage("docx", require_model_bytes.requireArrayBufferBytes(bytes)));
25
+ },
26
+ pptx: (bytes, options) => {
27
+ require_ports_abort.throwIfAborted(options?.signal);
28
+ return require_ooxml_pptx_read.readPptxContent(require_package_codec.decodeDocumentPackage("pptx", require_model_bytes.requireArrayBufferBytes(bytes)));
29
+ },
30
+ odt: (bytes, options) => {
31
+ require_ports_abort.throwIfAborted(options?.signal);
32
+ return require_odf_odt_read.readOdtContent(require_package_codec.decodeDocumentPackage("odt", require_model_bytes.requireArrayBufferBytes(bytes)));
33
+ },
34
+ odp: (bytes, options) => {
35
+ require_ports_abort.throwIfAborted(options?.signal);
36
+ return require_odf_odp_read.readOdpContent(require_package_codec.decodeDocumentPackage("odp", require_model_bytes.requireArrayBufferBytes(bytes)));
37
+ },
38
+ ods: (bytes, options) => {
39
+ require_ports_abort.throwIfAborted(options?.signal);
40
+ return require_odf_ods_read.readOdsContent(require_package_codec.decodeDocumentPackage("ods", require_model_bytes.requireArrayBufferBytes(bytes)));
41
+ },
42
+ odg: (bytes, options) => {
43
+ require_ports_abort.throwIfAborted(options?.signal);
44
+ return require_odf_odg_read.readOdgContent(require_package_codec.decodeDocumentPackage("odg", require_model_bytes.requireArrayBufferBytes(bytes)));
45
+ },
46
+ odf: (bytes, options) => {
47
+ require_ports_abort.throwIfAborted(options?.signal);
48
+ return require_odf_formula_read.readOdfFormulaContent(require_package_codec.decodeDocumentPackage("odf", require_model_bytes.requireArrayBufferBytes(bytes)));
49
+ },
50
+ markdown: (bytes, options) => require_markdown_read.readMarkdownContent(require_markdown_text.decodeMarkdownText(bytes), {
51
+ signal: options?.signal,
52
+ images: options?.images
53
+ }),
54
+ csv: (bytes) => require_csv_read.readCsvContent(require_csv_text.decodeCsvText(bytes)),
55
+ svg: (bytes) => require_svg_read.readSvgContent(require_svg_text.decodeSvgText(bytes)),
56
+ xlsx: (bytes, options) => {
57
+ require_ports_abort.throwIfAborted(options?.signal);
58
+ return (0, ooxml_js.readXlsxContent)(require_package_codec.decodeDocumentPackage("xlsx", require_model_bytes.requireArrayBufferBytes(bytes)));
59
+ }
60
+ };
61
+ function readDocumentLayout(bytes, options) {
62
+ return (0, pdf_codec_read.readPdf)(require_model_bytes.requireArrayBufferBytes(bytes), { signal: options?.signal });
63
+ }
64
+ //#endregion
65
+ exports.CONTENT_READERS = CONTENT_READERS;
66
+ exports.readDocumentLayout = readDocumentLayout;
@@ -0,0 +1,15 @@
1
+ import { DocumentFormat } from "../convert/port.cjs";
2
+ import { ContentDocument } from "document-schema.js";
3
+ import { LayoutDocument } from "pdf-codec";
4
+ import { MarkdownImageResolver } from "markdown-codec";
5
+ //#region src/codecs/read.d.ts
6
+ interface DocumentCodecOptions {
7
+ readonly signal?: AbortSignal;
8
+ readonly images?: MarkdownImageResolver;
9
+ }
10
+ type ReadContentFormat = Exclude<DocumentFormat, 'pdf'>;
11
+ type ContentReader = (bytes: Uint8Array, options?: DocumentCodecOptions) => ContentDocument;
12
+ declare const CONTENT_READERS: Readonly<Record<ReadContentFormat, ContentReader>>;
13
+ declare function readDocumentLayout(bytes: Uint8Array, options?: DocumentCodecOptions): LayoutDocument;
14
+ //#endregion
15
+ export { CONTENT_READERS, ContentReader, DocumentCodecOptions, ReadContentFormat, readDocumentLayout };
@@ -0,0 +1,15 @@
1
+ import { DocumentFormat } from "../convert/port.js";
2
+ import { ContentDocument } from "document-schema.js";
3
+ import { LayoutDocument } from "pdf-codec";
4
+ import { MarkdownImageResolver } from "markdown-codec";
5
+ //#region src/codecs/read.d.ts
6
+ interface DocumentCodecOptions {
7
+ readonly signal?: AbortSignal;
8
+ readonly images?: MarkdownImageResolver;
9
+ }
10
+ type ReadContentFormat = Exclude<DocumentFormat, 'pdf'>;
11
+ type ContentReader = (bytes: Uint8Array, options?: DocumentCodecOptions) => ContentDocument;
12
+ declare const CONTENT_READERS: Readonly<Record<ReadContentFormat, ContentReader>>;
13
+ declare function readDocumentLayout(bytes: Uint8Array, options?: DocumentCodecOptions): LayoutDocument;
14
+ //#endregion
15
+ export { CONTENT_READERS, ContentReader, DocumentCodecOptions, ReadContentFormat, readDocumentLayout };
@@ -0,0 +1,64 @@
1
+ import { requireArrayBufferBytes } from "../model/bytes.js";
2
+ import { readMarkdownContent } from "../markdown/read.js";
3
+ import { readDocxContent as readDocxContent$1 } from "../ooxml/docx/read.js";
4
+ import { readPptxContent as readPptxContent$1 } from "../ooxml/pptx/read.js";
5
+ import { readOdfFormulaContent } from "../odf/formula/read.js";
6
+ import { readOdtContent } from "../odf/odt/read.js";
7
+ import { readOdpContent } from "../odf/odp/read.js";
8
+ import { readOdsContent } from "../odf/ods/read.js";
9
+ import { readOdgContent } from "../odf/odg/read.js";
10
+ import { decodeMarkdownText } from "../markdown/text.js";
11
+ import { decodeCsvText } from "../csv/text.js";
12
+ import { readCsvContent } from "../csv/read.js";
13
+ import { decodeSvgText } from "../svg/text.js";
14
+ import { readSvgContent } from "../svg/read.js";
15
+ import { throwIfAborted } from "../ports/abort.js";
16
+ import { decodeDocumentPackage } from "../package-codec.js";
17
+ import { readXlsxContent } from "ooxml.js";
18
+ import { readPdf } from "pdf-codec/read";
19
+ //#region src/codecs/read.ts
20
+ const CONTENT_READERS = {
21
+ docx: (bytes, options) => {
22
+ throwIfAborted(options?.signal);
23
+ return readDocxContent$1(decodeDocumentPackage("docx", requireArrayBufferBytes(bytes)));
24
+ },
25
+ pptx: (bytes, options) => {
26
+ throwIfAborted(options?.signal);
27
+ return readPptxContent$1(decodeDocumentPackage("pptx", requireArrayBufferBytes(bytes)));
28
+ },
29
+ odt: (bytes, options) => {
30
+ throwIfAborted(options?.signal);
31
+ return readOdtContent(decodeDocumentPackage("odt", requireArrayBufferBytes(bytes)));
32
+ },
33
+ odp: (bytes, options) => {
34
+ throwIfAborted(options?.signal);
35
+ return readOdpContent(decodeDocumentPackage("odp", requireArrayBufferBytes(bytes)));
36
+ },
37
+ ods: (bytes, options) => {
38
+ throwIfAborted(options?.signal);
39
+ return readOdsContent(decodeDocumentPackage("ods", requireArrayBufferBytes(bytes)));
40
+ },
41
+ odg: (bytes, options) => {
42
+ throwIfAborted(options?.signal);
43
+ return readOdgContent(decodeDocumentPackage("odg", requireArrayBufferBytes(bytes)));
44
+ },
45
+ odf: (bytes, options) => {
46
+ throwIfAborted(options?.signal);
47
+ return readOdfFormulaContent(decodeDocumentPackage("odf", requireArrayBufferBytes(bytes)));
48
+ },
49
+ markdown: (bytes, options) => readMarkdownContent(decodeMarkdownText(bytes), {
50
+ signal: options?.signal,
51
+ images: options?.images
52
+ }),
53
+ csv: (bytes) => readCsvContent(decodeCsvText(bytes)),
54
+ svg: (bytes) => readSvgContent(decodeSvgText(bytes)),
55
+ xlsx: (bytes, options) => {
56
+ throwIfAborted(options?.signal);
57
+ return readXlsxContent(decodeDocumentPackage("xlsx", requireArrayBufferBytes(bytes)));
58
+ }
59
+ };
60
+ function readDocumentLayout(bytes, options) {
61
+ return readPdf(requireArrayBufferBytes(bytes), { signal: options?.signal });
62
+ }
63
+ //#endregion
64
+ export { CONTENT_READERS, readDocumentLayout };
@@ -5,109 +5,63 @@ const require_edit_odt_content = require("../edit/odt/content.cjs");
5
5
  const require_edit_odp_content = require("../edit/odp/content.cjs");
6
6
  const require_edit_ods_content = require("../edit/ods/content.cjs");
7
7
  const require_edit_odg_content = require("../edit/odg/content.cjs");
8
- const require_markdown_read = require("../markdown/read.cjs");
9
8
  const require_markdown_write = require("../markdown/write.cjs");
10
- const require_ooxml_docx_read = require("../ooxml/docx/read.cjs");
11
- const require_ooxml_pptx_read = require("../ooxml/pptx/read.cjs");
12
- const require_odf_formula_read = require("../odf/formula/read.cjs");
13
- const require_odf_odt_read = require("../odf/odt/read.cjs");
14
- const require_odf_odp_read = require("../odf/odp/read.cjs");
15
- const require_odf_ods_read = require("../odf/ods/read.cjs");
16
- const require_odf_odg_read = require("../odf/odg/read.cjs");
17
9
  const require_markdown_text = require("../markdown/text.cjs");
18
10
  const require_csv_text = require("../csv/text.cjs");
19
- const require_csv_read = require("../csv/read.cjs");
20
11
  const require_csv_write = require("../csv/write.cjs");
21
12
  const require_svg_text = require("../svg/text.cjs");
22
- const require_svg_read = require("../svg/read.cjs");
23
13
  const require_svg_write = require("../svg/write.cjs");
24
- const require_ports_abort = require("../ports/abort.cjs");
25
14
  const require_package_codec = require("../package-codec.cjs");
15
+ const require_codecs_read = require("./read.cjs");
26
16
  let ooxml_js = require("ooxml.js");
27
17
  let pdf_codec = require("pdf-codec");
28
18
  //#region src/codecs/registry.ts
29
- function isArrayBufferBacked(bytes) {
30
- return bytes.buffer instanceof ArrayBuffer;
31
- }
32
- function requireArrayBufferBytes(bytes) {
33
- if (!isArrayBufferBacked(bytes)) throw new TypeError("expected an ArrayBuffer-backed Uint8Array, received one backed by a SharedArrayBuffer");
34
- return bytes;
35
- }
36
19
  const DOCUMENT_FORMAT_CODECS = {
37
20
  docx: { content: {
38
- read: (bytes, options) => {
39
- require_ports_abort.throwIfAborted(options?.signal);
40
- return require_ooxml_docx_read.readDocxContent(require_package_codec.decodeDocumentPackage("docx", requireArrayBufferBytes(bytes)));
41
- },
21
+ read: require_codecs_read.CONTENT_READERS.docx,
42
22
  write: (content) => require_package_codec.encodeDocumentPackage("docx", require_edit_docx_content.buildDocxPackage(content))
43
23
  } },
44
24
  pptx: { content: {
45
- read: (bytes, options) => {
46
- require_ports_abort.throwIfAborted(options?.signal);
47
- return require_ooxml_pptx_read.readPptxContent(require_package_codec.decodeDocumentPackage("pptx", requireArrayBufferBytes(bytes)));
48
- },
25
+ read: require_codecs_read.CONTENT_READERS.pptx,
49
26
  write: (content) => require_package_codec.encodeDocumentPackage("pptx", require_edit_pptx_content.buildPptxPackage(content))
50
27
  } },
51
28
  odt: { content: {
52
- read: (bytes, options) => {
53
- require_ports_abort.throwIfAborted(options?.signal);
54
- return require_odf_odt_read.readOdtContent(require_package_codec.decodeDocumentPackage("odt", requireArrayBufferBytes(bytes)));
55
- },
29
+ read: require_codecs_read.CONTENT_READERS.odt,
56
30
  write: (content) => require_package_codec.encodeDocumentPackage("odt", require_edit_odt_content.buildOdtPackage(content))
57
31
  } },
58
32
  odp: { content: {
59
- read: (bytes, options) => {
60
- require_ports_abort.throwIfAborted(options?.signal);
61
- return require_odf_odp_read.readOdpContent(require_package_codec.decodeDocumentPackage("odp", requireArrayBufferBytes(bytes)));
62
- },
33
+ read: require_codecs_read.CONTENT_READERS.odp,
63
34
  write: (content) => require_package_codec.encodeDocumentPackage("odp", require_edit_odp_content.buildOdpPackage(content))
64
35
  } },
65
36
  ods: { content: {
66
- read: (bytes, options) => {
67
- require_ports_abort.throwIfAborted(options?.signal);
68
- return require_odf_ods_read.readOdsContent(require_package_codec.decodeDocumentPackage("ods", requireArrayBufferBytes(bytes)));
69
- },
37
+ read: require_codecs_read.CONTENT_READERS.ods,
70
38
  write: (content) => require_package_codec.encodeDocumentPackage("ods", require_edit_ods_content.buildOdsPackage(content))
71
39
  } },
72
40
  odg: { content: {
73
- read: (bytes, options) => {
74
- require_ports_abort.throwIfAborted(options?.signal);
75
- return require_odf_odg_read.readOdgContent(require_package_codec.decodeDocumentPackage("odg", requireArrayBufferBytes(bytes)));
76
- },
41
+ read: require_codecs_read.CONTENT_READERS.odg,
77
42
  write: (content) => require_package_codec.encodeDocumentPackage("odg", require_edit_odg_content.buildOdgPackage(content))
78
43
  } },
79
- odf: { content: { read: (bytes, options) => {
80
- require_ports_abort.throwIfAborted(options?.signal);
81
- return require_odf_formula_read.readOdfFormulaContent(require_package_codec.decodeDocumentPackage("odf", requireArrayBufferBytes(bytes)));
82
- } } },
44
+ odf: { content: { read: require_codecs_read.CONTENT_READERS.odf } },
83
45
  markdown: { content: {
84
- read: (bytes, options) => require_markdown_read.readMarkdownContent(require_markdown_text.decodeMarkdownText(bytes), {
85
- signal: options?.signal,
86
- images: options?.images
87
- }),
46
+ read: require_codecs_read.CONTENT_READERS.markdown,
88
47
  write: (content) => require_markdown_text.encodeMarkdownText(require_markdown_write.buildMarkdownText(content))
89
48
  } },
90
49
  csv: { content: {
91
- read: (bytes) => require_csv_read.readCsvContent(require_csv_text.decodeCsvText(bytes)),
50
+ read: require_codecs_read.CONTENT_READERS.csv,
92
51
  write: (content) => require_csv_text.encodeCsvText(require_csv_write.buildCsvText(content))
93
52
  } },
94
53
  svg: { content: {
95
- read: (bytes) => require_svg_read.readSvgContent(require_svg_text.decodeSvgText(bytes)),
54
+ read: require_codecs_read.CONTENT_READERS.svg,
96
55
  write: (content) => require_svg_text.encodeSvgText(require_svg_write.buildSvgText(content))
97
56
  } },
98
57
  pdf: { layout: {
99
- read: (bytes, options) => (0, pdf_codec.readPdf)(requireArrayBufferBytes(bytes), { signal: options?.signal }),
58
+ read: require_codecs_read.readDocumentLayout,
100
59
  write: (layout, options) => (0, pdf_codec.writePdf)(layout, { signal: options?.signal })
101
60
  } },
102
61
  xlsx: { content: {
103
- read: (bytes, options) => {
104
- require_ports_abort.throwIfAborted(options?.signal);
105
- return (0, ooxml_js.readXlsxContent)(require_package_codec.decodeDocumentPackage("xlsx", requireArrayBufferBytes(bytes)));
106
- },
62
+ read: require_codecs_read.CONTENT_READERS.xlsx,
107
63
  write: (content) => require_package_codec.encodeDocumentPackage("xlsx", (0, ooxml_js.buildXlsxPackageFromContent)(content))
108
64
  } }
109
65
  };
110
66
  //#endregion
111
67
  exports.DOCUMENT_FORMAT_CODECS = DOCUMENT_FORMAT_CODECS;
112
- exports.isArrayBufferBacked = isArrayBufferBacked;
113
- exports.requireArrayBufferBytes = requireArrayBufferBytes;
@@ -1,14 +1,8 @@
1
1
  import { DocumentFormat } from "../convert/port.cjs";
2
+ import { DocumentCodecOptions } from "./read.cjs";
2
3
  import { ContentCodec } from "document-schema.js";
3
4
  import { LayoutDocument } from "pdf-codec";
4
- import { MarkdownImageResolver } from "markdown-codec";
5
5
  //#region src/codecs/registry.d.ts
6
- declare function isArrayBufferBacked(bytes: Uint8Array): bytes is Uint8Array<ArrayBuffer>;
7
- declare function requireArrayBufferBytes(bytes: Uint8Array): Uint8Array<ArrayBuffer>;
8
- interface DocumentCodecOptions {
9
- readonly signal?: AbortSignal;
10
- readonly images?: MarkdownImageResolver;
11
- }
12
6
  interface LayoutEntryCodec {
13
7
  read(bytes: Uint8Array, options?: DocumentCodecOptions): LayoutDocument;
14
8
  write(layout: LayoutDocument, options?: DocumentCodecOptions): Uint8Array;
@@ -19,4 +13,4 @@ interface DocumentFormatCodecs {
19
13
  }
20
14
  declare const DOCUMENT_FORMAT_CODECS: Readonly<Record<DocumentFormat, DocumentFormatCodecs>>;
21
15
  //#endregion
22
- export { DOCUMENT_FORMAT_CODECS, DocumentCodecOptions, DocumentFormatCodecs, LayoutEntryCodec, isArrayBufferBacked, requireArrayBufferBytes };
16
+ export { DOCUMENT_FORMAT_CODECS, DocumentFormatCodecs, LayoutEntryCodec };