@laminapdf/sdk 0.2.0-alpha.3 → 0.2.0-alpha.4

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 (408) hide show
  1. package/README.md +21 -1
  2. package/dist/api.d.ts +4 -2
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +1 -0
  5. package/dist/api.js.map +1 -1
  6. package/dist/builder.d.ts +8 -3
  7. package/dist/builder.d.ts.map +1 -1
  8. package/dist/builder.js +8 -3
  9. package/dist/builder.js.map +1 -1
  10. package/dist/document.d.ts +42 -1
  11. package/dist/document.d.ts.map +1 -1
  12. package/dist/document.js +65 -0
  13. package/dist/document.js.map +1 -1
  14. package/dist/extract-job.d.ts +100 -0
  15. package/dist/extract-job.d.ts.map +1 -0
  16. package/dist/extract-job.js +177 -0
  17. package/dist/extract-job.js.map +1 -0
  18. package/dist/extract.d.ts +1 -1
  19. package/dist/extract.d.ts.map +1 -1
  20. package/dist/extract.js.map +1 -1
  21. package/dist/generated/builder-enums.d.ts +3 -3
  22. package/dist/generated/builder-enums.d.ts.map +1 -1
  23. package/dist/generated/builder-enums.js +10 -0
  24. package/dist/generated/builder-enums.js.map +1 -1
  25. package/dist/generated/codes.d.ts +2 -2
  26. package/dist/generated/codes.d.ts.map +1 -1
  27. package/dist/generated/codes.js +55 -1
  28. package/dist/generated/codes.js.map +1 -1
  29. package/dist/generated/explain.d.ts.map +1 -1
  30. package/dist/generated/explain.js +19 -2
  31. package/dist/generated/explain.js.map +1 -1
  32. package/dist/generated/extract.d.ts +50 -3
  33. package/dist/generated/extract.d.ts.map +1 -1
  34. package/dist/source/http.d.ts +1 -1
  35. package/dist/source/http.js +1 -1
  36. package/dist/types.d.ts +19 -1
  37. package/dist/types.d.ts.map +1 -1
  38. package/dist/version.d.ts +1 -1
  39. package/dist/version.js +1 -1
  40. package/dist/worker/support.d.ts +7 -1
  41. package/dist/worker/support.d.ts.map +1 -1
  42. package/dist/worker/support.js +4 -0
  43. package/dist/worker/support.js.map +1 -1
  44. package/docs/AGENTS.md +1 -1
  45. package/docs/api/README.md +20 -1
  46. package/docs/api/classes/Builder.md +1 -1
  47. package/docs/api/classes/Document.md +113 -1
  48. package/docs/api/classes/ExtractJob.md +236 -0
  49. package/docs/api/classes/Font.md +1 -1
  50. package/docs/api/classes/Image.md +1 -1
  51. package/docs/api/classes/LaminaPdfError.md +1 -1
  52. package/docs/api/classes/Page.md +1 -1
  53. package/docs/api/classes/PageRef.md +1 -1
  54. package/docs/api/classes/PageText.md +1 -1
  55. package/docs/api/classes/PageTextRun.md +1 -1
  56. package/docs/api/classes/PendingPath.md +1 -1
  57. package/docs/api/classes/SaveJob.md +1 -1
  58. package/docs/api/classes/Surface.md +10 -5
  59. package/docs/api/classes/Transaction.md +1 -1
  60. package/docs/api/functions/callbackSource.md +1 -1
  61. package/docs/api/functions/extractWithModels.md +70 -0
  62. package/docs/api/functions/httpRangeSource.md +2 -2
  63. package/docs/api/functions/init.md +1 -1
  64. package/docs/api/functions/isExtractLoaded.md +1 -1
  65. package/docs/api/functions/isInitialized.md +1 -1
  66. package/docs/api/functions/isLaminaPdfError.md +1 -1
  67. package/docs/api/functions/isTextLoaded.md +1 -1
  68. package/docs/api/functions/loadExtract.md +1 -1
  69. package/docs/api/functions/loadText.md +1 -1
  70. package/docs/api/functions/onLeak.md +1 -1
  71. package/docs/api/functions/reset.md +1 -1
  72. package/docs/api/functions/wasmMemory.md +1 -1
  73. package/docs/api/interfaces/BuilderOptions.md +1 -1
  74. package/docs/api/interfaces/ByteRange.md +1 -1
  75. package/docs/api/interfaces/ChunkOptions.md +1 -1
  76. package/docs/api/interfaces/Diagnostic.md +1 -1
  77. package/docs/api/interfaces/ExtractOptions.md +1 -1
  78. package/docs/api/interfaces/ExtractResult.md +1 -1
  79. package/docs/api/interfaces/FontInfo.md +1 -1
  80. package/docs/api/interfaces/HostModels.md +57 -0
  81. package/docs/api/interfaces/HttpRangeOptions.md +1 -1
  82. package/docs/api/interfaces/InitOptions.md +1 -1
  83. package/docs/api/interfaces/LayoutRegion.md +38 -0
  84. package/docs/api/interfaces/Leak.md +1 -1
  85. package/docs/api/interfaces/Location.md +1 -1
  86. package/docs/api/interfaces/ModelInfo.md +45 -0
  87. package/docs/api/interfaces/ModelRequest.md +45 -0
  88. package/docs/api/interfaces/Models.md +45 -0
  89. package/docs/api/interfaces/OcrWord.md +37 -0
  90. package/docs/api/interfaces/OpLog.md +1 -1
  91. package/docs/api/interfaces/OpenOptions.md +1 -1
  92. package/docs/api/interfaces/PageTextOptions.md +1 -1
  93. package/docs/api/interfaces/PathBuilder.md +1 -1
  94. package/docs/api/interfaces/QuadPoint.md +1 -1
  95. package/docs/api/interfaces/RangeOptions.md +1 -1
  96. package/docs/api/interfaces/RangeSource.md +1 -1
  97. package/docs/api/interfaces/StrokeStyle.md +1 -1
  98. package/docs/api/interfaces/TagSpec.md +3 -3
  99. package/docs/api/interfaces/TextBoxOptions.md +1 -1
  100. package/docs/api/interfaces/TextGlyph.md +1 -1
  101. package/docs/api/interfaces/TextOptions.md +1 -1
  102. package/docs/api/interfaces/WasmMemory.md +1 -1
  103. package/docs/api/type-aliases/AfRelationship.md +1 -1
  104. package/docs/api/type-aliases/Align.md +1 -1
  105. package/docs/api/type-aliases/ArtifactKind.md +2 -2
  106. package/docs/api/type-aliases/AttachmentOptions.md +1 -1
  107. package/docs/api/type-aliases/BlendMode.md +1 -1
  108. package/docs/api/type-aliases/BoxRect.md +1 -1
  109. package/docs/api/type-aliases/BuildOptions.md +1 -1
  110. package/docs/api/type-aliases/Cell.md +1 -1
  111. package/docs/api/type-aliases/Chunk.md +1 -1
  112. package/docs/api/type-aliases/Color.md +1 -1
  113. package/docs/api/type-aliases/Coordinates.md +1 -1
  114. package/docs/api/type-aliases/Direction.md +1 -1
  115. package/docs/api/type-aliases/DocumentInfo.md +1 -1
  116. package/docs/api/type-aliases/DropReason.md +2 -2
  117. package/docs/api/type-aliases/Dropped.md +1 -1
  118. package/docs/api/type-aliases/Edited.md +1 -1
  119. package/docs/api/type-aliases/ErrorCode.md +2 -2
  120. package/docs/api/type-aliases/ErrorKind.md +1 -1
  121. package/docs/api/type-aliases/ExtractFormat.md +1 -1
  122. package/docs/api/type-aliases/ExtractJobOptions.md +31 -0
  123. package/docs/api/type-aliases/ExtractStep.md +61 -0
  124. package/docs/api/type-aliases/ExtractedBlock.md +13 -1
  125. package/docs/api/type-aliases/ExtractedPage.md +9 -1
  126. package/docs/api/type-aliases/ExtractedSource.md +1 -1
  127. package/docs/api/type-aliases/Extraction.md +1 -1
  128. package/docs/api/type-aliases/FillRule.md +1 -1
  129. package/docs/api/type-aliases/Fit.md +1 -1
  130. package/docs/api/type-aliases/Flags.md +1 -1
  131. package/docs/api/type-aliases/Generator.md +5 -3
  132. package/docs/api/type-aliases/GlyphQuad.md +1 -1
  133. package/docs/api/type-aliases/InfoPatch.md +1 -1
  134. package/docs/api/type-aliases/LaminaPdfWarning.md +1 -1
  135. package/docs/api/type-aliases/LimitName.md +1 -1
  136. package/docs/api/type-aliases/Limits.md +1 -1
  137. package/docs/api/type-aliases/LineBox.md +1 -1
  138. package/docs/api/type-aliases/LineCap.md +1 -1
  139. package/docs/api/type-aliases/LineJoin.md +1 -1
  140. package/docs/api/type-aliases/LinkTarget.md +1 -1
  141. package/docs/api/type-aliases/Metadata.md +1 -1
  142. package/docs/api/type-aliases/ModelResult.md +15 -0
  143. package/docs/api/type-aliases/Op.md +1 -1
  144. package/docs/api/type-aliases/OutlineEntry.md +1 -1
  145. package/docs/api/type-aliases/OutlineNode.md +15 -0
  146. package/docs/api/type-aliases/Overflow.md +1 -1
  147. package/docs/api/type-aliases/PageInfo.md +1 -1
  148. package/docs/api/type-aliases/PageLabel.md +1 -1
  149. package/docs/api/type-aliases/PageSizeName.md +1 -1
  150. package/docs/api/type-aliases/Point.md +1 -1
  151. package/docs/api/type-aliases/Profile.md +1 -1
  152. package/docs/api/type-aliases/Progress.md +1 -1
  153. package/docs/api/type-aliases/ReadingOrder.md +1 -1
  154. package/docs/api/type-aliases/Rect.md +1 -1
  155. package/docs/api/type-aliases/Region.md +1 -1
  156. package/docs/api/type-aliases/RegionLabel.md +15 -0
  157. package/docs/api/type-aliases/RenderMode.md +1 -1
  158. package/docs/api/type-aliases/Rotation.md +1 -1
  159. package/docs/api/type-aliases/SaveOptions.md +1 -1
  160. package/docs/api/type-aliases/SaveReport.md +1 -1
  161. package/docs/api/type-aliases/Span.md +12 -1
  162. package/docs/api/type-aliases/SplitOn.md +1 -1
  163. package/docs/api/type-aliases/Standard14.md +1 -1
  164. package/docs/api/type-aliases/StructRef.md +1 -1
  165. package/docs/api/type-aliases/StructSource.md +1 -1
  166. package/docs/api/type-aliases/StructureKid.md +15 -0
  167. package/docs/api/type-aliases/StructureNode.md +16 -0
  168. package/docs/api/type-aliases/TableDetector.md +1 -1
  169. package/docs/api/type-aliases/TableMode.md +1 -1
  170. package/docs/api/type-aliases/TableScope.md +1 -1
  171. package/docs/api/type-aliases/Tag.md +1 -1
  172. package/docs/api/type-aliases/TagName.md +1 -1
  173. package/docs/api/type-aliases/Target.md +15 -0
  174. package/docs/api/type-aliases/TargetView.md +18 -0
  175. package/docs/api/type-aliases/TextLayer.md +72 -0
  176. package/docs/api/type-aliases/TextLayerStatus.md +15 -0
  177. package/docs/api/type-aliases/TextLayout.md +1 -1
  178. package/docs/api/type-aliases/TextRange.md +1 -1
  179. package/docs/api/type-aliases/TextRunInfo.md +1 -1
  180. package/docs/api/type-aliases/Transform.md +1 -1
  181. package/docs/api/type-aliases/UndoOutcome.md +1 -1
  182. package/docs/api/type-aliases/ViewerPreferences.md +1 -1
  183. package/docs/api/type-aliases/WarningCode.md +2 -2
  184. package/docs/api/type-aliases/WasmSource.md +1 -1
  185. package/docs/api/variables/Matrix.md +1 -1
  186. package/docs/api/variables/PAGE_SIZES.md +1 -1
  187. package/docs/api/variables/TAG_NAMES.md +2 -2
  188. package/docs/errors/README.md +18 -1
  189. package/docs/errors/aes-padding-invalid.md +1 -1
  190. package/docs/errors/already-initialized.md +1 -1
  191. package/docs/errors/binary-output-to-terminal.md +1 -1
  192. package/docs/errors/builder-finished.md +1 -1
  193. package/docs/errors/cancelled.md +1 -1
  194. package/docs/errors/cmap-invalid.md +1 -1
  195. package/docs/errors/collection-index.md +1 -1
  196. package/docs/errors/color-components.md +1 -1
  197. package/docs/errors/content-bad-operands.md +1 -1
  198. package/docs/errors/content-path-unpainted.md +1 -1
  199. package/docs/errors/content-resource-missing.md +1 -1
  200. package/docs/errors/content-syntax.md +1 -1
  201. package/docs/errors/content-unbalanced-bt.md +1 -1
  202. package/docs/errors/content-unbalanced-marked.md +1 -1
  203. package/docs/errors/content-unbalanced-q.md +1 -1
  204. package/docs/errors/content-unknown-operator.md +1 -1
  205. package/docs/errors/covered-text.md +33 -0
  206. package/docs/errors/data-pending.md +1 -1
  207. package/docs/errors/decompress.md +1 -1
  208. package/docs/errors/device-color-without-output-intent.md +1 -1
  209. package/docs/errors/direct-page.md +1 -1
  210. package/docs/errors/disposed.md +1 -1
  211. package/docs/errors/document-changed.md +1 -1
  212. package/docs/errors/embedded-file-forbidden.md +1 -1
  213. package/docs/errors/embedded-file-without-mime-type.md +1 -1
  214. package/docs/errors/encoding-full.md +1 -1
  215. package/docs/errors/encrypted-base.md +1 -1
  216. package/docs/errors/extract-column-order-uncertain.md +38 -0
  217. package/docs/errors/extract-limit-blocks.md +1 -1
  218. package/docs/errors/extract-module-not-loaded.md +1 -1
  219. package/docs/errors/extract-needs-ocr.md +37 -0
  220. package/docs/errors/extract-reading-order-ambiguous.md +1 -1
  221. package/docs/errors/extract-struct-tree-ignored.md +1 -1
  222. package/docs/errors/extract-table-ambiguous.md +1 -1
  223. package/docs/errors/extract-table-limit.md +1 -1
  224. package/docs/errors/extract-untagged-content.md +1 -1
  225. package/docs/errors/fetch-failed.md +3 -3
  226. package/docs/errors/flate-truncated.md +1 -1
  227. package/docs/errors/flow-content-too-large.md +34 -0
  228. package/docs/errors/flow-keep-broken.md +34 -0
  229. package/docs/errors/flow-layout-unstable.md +38 -0
  230. package/docs/errors/font-invalid.md +1 -1
  231. package/docs/errors/font-mismatch.md +1 -1
  232. package/docs/errors/font-not-embeddable.md +1 -1
  233. package/docs/errors/font-not-embedded.md +1 -1
  234. package/docs/errors/font-not-shapable.md +1 -1
  235. package/docs/errors/glyph-out-of-range.md +1 -1
  236. package/docs/errors/glyph-without-unicode.md +7 -5
  237. package/docs/errors/heading-level-skipped.md +1 -1
  238. package/docs/errors/image-data-length.md +1 -1
  239. package/docs/errors/image-too-large.md +1 -1
  240. package/docs/errors/inline-image-unterminated.md +1 -1
  241. package/docs/errors/input-unreadable.md +1 -1
  242. package/docs/errors/instance-reset.md +1 -1
  243. package/docs/errors/invalid-argument.md +1 -1
  244. package/docs/errors/invalid-axis-value.md +1 -1
  245. package/docs/errors/invalid-box.md +1 -1
  246. package/docs/errors/invalid-color.md +1 -1
  247. package/docs/errors/invalid-command-line.md +1 -1
  248. package/docs/errors/invalid-date.md +1 -1
  249. package/docs/errors/invalid-entry.md +1 -1
  250. package/docs/errors/invalid-feature.md +1 -1
  251. package/docs/errors/invalid-font.md +1 -1
  252. package/docs/errors/invalid-geometry.md +1 -1
  253. package/docs/errors/invalid-icc-profile.md +1 -1
  254. package/docs/errors/invalid-image.md +1 -1
  255. package/docs/errors/invalid-op-log.md +1 -1
  256. package/docs/errors/invalid-page-label.md +1 -1
  257. package/docs/errors/invalid-page-labels.md +1 -1
  258. package/docs/errors/invalid-page-range.md +1 -1
  259. package/docs/errors/invalid-rotate.md +1 -1
  260. package/docs/errors/invalid-spans.md +39 -0
  261. package/docs/errors/invalid-structure-nesting.md +1 -1
  262. package/docs/errors/invalid-structure.md +1 -1
  263. package/docs/errors/invalid-text-range.md +1 -1
  264. package/docs/errors/job-finished.md +1 -1
  265. package/docs/errors/limit-exceeded.md +1 -1
  266. package/docs/errors/link-without-contents.md +1 -1
  267. package/docs/errors/link-without-structure.md +1 -1
  268. package/docs/errors/markdown-html-ignored.md +33 -0
  269. package/docs/errors/markdown-image-missing.md +34 -0
  270. package/docs/errors/missing-alt-text.md +1 -1
  271. package/docs/errors/missing-glyph.md +1 -1
  272. package/docs/errors/missing-header.md +1 -1
  273. package/docs/errors/missing-lang.md +1 -1
  274. package/docs/errors/missing-root.md +1 -1
  275. package/docs/errors/missing-title.md +1 -1
  276. package/docs/errors/model-failed.md +33 -0
  277. package/docs/errors/model-needs-host.md +40 -0
  278. package/docs/errors/model-result-unexpected.md +36 -0
  279. package/docs/errors/name-tree-node-skipped.md +1 -1
  280. package/docs/errors/nested-transaction.md +1 -1
  281. package/docs/errors/no-pending-save.md +1 -1
  282. package/docs/errors/no-transaction.md +1 -1
  283. package/docs/errors/not-initialized.md +1 -1
  284. package/docs/errors/not-pdf.md +1 -1
  285. package/docs/errors/not-rebased.md +1 -1
  286. package/docs/errors/object-number-out-of-range.md +1 -1
  287. package/docs/errors/objstm-index-mismatch.md +1 -1
  288. package/docs/errors/out-of-memory.md +1 -1
  289. package/docs/errors/outline-cycle.md +1 -1
  290. package/docs/errors/outline-item-skipped.md +1 -1
  291. package/docs/errors/output-unwritable.md +1 -1
  292. package/docs/errors/overwrite-refused.md +1 -1
  293. package/docs/errors/page-count-mismatch.md +1 -1
  294. package/docs/errors/page-index-out-of-range.md +1 -1
  295. package/docs/errors/page-tree-node-skipped.md +1 -1
  296. package/docs/errors/password-required.md +1 -1
  297. package/docs/errors/path-outside-roots.md +1 -1
  298. package/docs/errors/perms-mismatch.md +1 -1
  299. package/docs/errors/profile-version-conflict.md +1 -1
  300. package/docs/errors/redaction-not-applied.md +32 -0
  301. package/docs/errors/reference-cycle.md +1 -1
  302. package/docs/errors/render-backend-unavailable.md +1 -1
  303. package/docs/errors/render-failed.md +1 -1
  304. package/docs/errors/render-too-large.md +1 -1
  305. package/docs/errors/repaired-base.md +1 -1
  306. package/docs/errors/requires-rewrite.md +1 -1
  307. package/docs/errors/revision-index-out-of-range.md +34 -0
  308. package/docs/errors/saved-not-rebased.md +1 -1
  309. package/docs/errors/sink-not-empty.md +1 -1
  310. package/docs/errors/sink.md +1 -1
  311. package/docs/errors/source-budget-exceeded.md +1 -1
  312. package/docs/errors/source-changed.md +1 -1
  313. package/docs/errors/source.md +1 -1
  314. package/docs/errors/stale-generation.md +1 -1
  315. package/docs/errors/stream-length-recovered.md +1 -1
  316. package/docs/errors/strict.md +1 -1
  317. package/docs/errors/subset-failed.md +1 -1
  318. package/docs/errors/syntax.md +1 -1
  319. package/docs/errors/tag-element-not-open.md +41 -0
  320. package/docs/errors/tag-element-unclosed.md +34 -0
  321. package/docs/errors/text-in-earlier-revision.md +36 -0
  322. package/docs/errors/text-module-not-loaded.md +1 -1
  323. package/docs/errors/text-overflow.md +1 -1
  324. package/docs/errors/tounicode-conflict.md +1 -1
  325. package/docs/errors/type.md +1 -1
  326. package/docs/errors/unexpected-eof.md +1 -1
  327. package/docs/errors/unknown-axis.md +1 -1
  328. package/docs/errors/unknown-code.md +1 -1
  329. package/docs/errors/unknown-destination.md +1 -1
  330. package/docs/errors/unknown-font.md +1 -1
  331. package/docs/errors/unknown-option.md +1 -1
  332. package/docs/errors/unknown-page.md +1 -1
  333. package/docs/errors/unmapped-glyph.md +1 -1
  334. package/docs/errors/unnumbered-heading-misused.md +1 -1
  335. package/docs/errors/unset-object.md +1 -1
  336. package/docs/errors/unsupported-filter.md +1 -1
  337. package/docs/errors/unsupported-image.md +1 -1
  338. package/docs/errors/unsupported-layout-option.md +1 -1
  339. package/docs/errors/unsupported-security-handler.md +1 -1
  340. package/docs/errors/unsupported-version.md +1 -1
  341. package/docs/errors/untagged-content.md +1 -1
  342. package/docs/errors/warnings-truncated.md +1 -1
  343. package/docs/errors/wasm-trap.md +1 -1
  344. package/docs/errors/whole-font-rebuilt.md +1 -1
  345. package/docs/errors/worker-crashed.md +1 -1
  346. package/docs/errors/worker-failed.md +1 -1
  347. package/docs/errors/worker-version-mismatch.md +1 -1
  348. package/docs/errors/would-invalidate-signatures.md +1 -1
  349. package/docs/errors/wrong-document.md +1 -1
  350. package/docs/errors/wrong-password.md +1 -1
  351. package/docs/errors/xobject-cycle.md +1 -1
  352. package/docs/errors/xref-repaired.md +1 -1
  353. package/docs/errors/xrefstm-ignored.md +1 -1
  354. package/docs/llms.txt +7 -1
  355. package/docs/pages/concepts/dependencies.md +2 -2
  356. package/docs/pages/concepts/drawing-pages.md +76 -0
  357. package/docs/pages/concepts/errors-and-warnings.md +6 -2
  358. package/docs/pages/concepts/how-lamina-thinks.md +13 -1
  359. package/docs/pages/concepts/pages-and-coordinates.md +9 -1
  360. package/docs/pages/guides/accessible-pdfs.md +3 -1
  361. package/docs/pages/guides/archival-pdfs.md +5 -1
  362. package/docs/pages/guides/edit-a-pdf.md +8 -2
  363. package/docs/pages/guides/flowing-pages.md +379 -0
  364. package/docs/pages/guides/fonts-and-text.md +3 -1
  365. package/docs/pages/guides/images-and-vectors.md +3 -1
  366. package/docs/pages/guides/keep-the-page-responsive.md +8 -4
  367. package/docs/pages/guides/links-outlines-and-metadata.md +3 -1
  368. package/docs/pages/guides/open-large-files.md +69 -0
  369. package/docs/pages/guides/password-protected-files.md +1 -1
  370. package/docs/pages/guides/save-a-pdf.md +12 -2
  371. package/docs/pages/guides/test-generated-pdfs.md +324 -0
  372. package/docs/pages/guides/untrusted-files.md +3 -1
  373. package/docs/pages/index.md +2 -2
  374. package/docs/pages/install.md +9 -5
  375. package/docs/pages/quick-start/browser.md +5 -1
  376. package/docs/pages/quick-start/bun.md +5 -1
  377. package/docs/pages/quick-start/deno.md +5 -1
  378. package/docs/pages/quick-start/node.md +5 -1
  379. package/docs/pages/quick-start/rust.md +6 -2
  380. package/docs/pages/quick-start/workers.md +2 -2
  381. package/docs/pages/recipes/cloudflare-worker.md +1 -1
  382. package/docs/pages/recipes/element-flow.md +248 -0
  383. package/docs/pages/recipes/extract-markdown.md +44 -6
  384. package/docs/pages/recipes/generate-then-edit.md +13 -6
  385. package/docs/pages/recipes/hello.md +13 -6
  386. package/docs/pages/recipes/images-and-vectors.md +13 -6
  387. package/docs/pages/recipes/invoice.md +13 -6
  388. package/docs/pages/recipes/links-and-outlines.md +13 -6
  389. package/docs/pages/recipes/multilingual.md +13 -6
  390. package/docs/pages/recipes/open-untrusted.md +1 -1
  391. package/docs/pages/recipes/pdf-a-archive.md +13 -6
  392. package/docs/pages/recipes/pdf-a3-invoice-with-xml.md +13 -6
  393. package/docs/pages/recipes/pdf-ua-report.md +13 -6
  394. package/docs/pages/recipes/report.md +2 -2
  395. package/docs/pages/recipes/web-worker-client.md +1 -1
  396. package/docs/pages/recipes.md +3 -2
  397. package/docs/pages/reference/benchmarks.md +93 -0
  398. package/docs/pages/reference/changelog.md +49 -1
  399. package/docs/pages/reference/codes.md +1 -1
  400. package/docs/pages/reference/glossary.md +1 -1
  401. package/docs/pages/reference/rust.md +11 -11
  402. package/docs/pages/reference/stability.md +3 -3
  403. package/docs/pages/start/coding-agents.md +1 -1
  404. package/docs/pages/start/first-pdf.md +6 -2
  405. package/docs/pages/troubleshooting.md +1 -1
  406. package/docs/schemas/error.schema.json +18 -1
  407. package/package.json +4 -2
  408. package/schemas/error.schema.json +18 -1
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "source"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/source/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "stale-generation"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/stale-generation/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "stream-length-recovered"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/stream-length-recovered/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "strict"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/strict/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "subset-failed"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/subset-failed/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "syntax"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/syntax/"
5
5
  ---
6
6
 
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: "tag-element-not-open"
3
+ version: "0.2.0-alpha.4"
4
+ url: "https://docs.laminapdf.com/reference/codes/tag-element-not-open/"
5
+ ---
6
+
7
+ # tag-element-not-open
8
+
9
+ - Type: error
10
+ - Kind: `usage` (the caller misused the API)
11
+
12
+ ## What happened
13
+
14
+ `Surface::resume` or `Builder::close_element` was given a structure element that isn't open. When `resume` names one, the page's `PageBuilder::finish` fails.
15
+
16
+ ## Why
17
+
18
+ An element that continues across pages is open from `Surface::open_element` until `Builder::close_element` writes it, and only then. The element named was one of these:
19
+
20
+ - closed already;
21
+ - opened by another builder;
22
+ - opened inside an artifact, so it is part of the artifact (ISO 32000-2 §14.8.2.2);
23
+ - opened on a page added to an existing document, which is never tagged;
24
+ - opened on a page whose `PageBuilder::finish` failed, so it was never written.
25
+
26
+ ## How to fix
27
+
28
+ Open the element on a page of the same builder, outside every artifact, and close it once, after its last page is finished.
29
+
30
+ ## Example
31
+
32
+ ```rust
33
+ let paragraph = page.surface().open_element(TagKind::P);
34
+ page.finish()?;
35
+ builder.close_element(paragraph)?;
36
+ builder.close_element(paragraph)?; // tag-element-not-open: closed already
37
+ ```
38
+
39
+ ## Data fields
40
+
41
+ None.
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: "tag-element-unclosed"
3
+ version: "0.2.0-alpha.4"
4
+ url: "https://docs.laminapdf.com/reference/codes/tag-element-unclosed/"
5
+ ---
6
+
7
+ # tag-element-unclosed
8
+
9
+ - Type: error
10
+ - Kind: `usage` (the caller misused the API)
11
+
12
+ ## What happened
13
+
14
+ `Builder::finish` was called while structure elements opened with `Surface::open_element` were still open.
15
+
16
+ ## Why
17
+
18
+ An element that continues across pages is written when `Builder::close_element` closes it, since only then is its content complete. An element never closed would leave the structure tree with a reference to an element that doesn't exist (ISO 32000-2 §14.7.2), so the build stops instead.
19
+
20
+ ## How to fix
21
+
22
+ Close every element from `Surface::open_element` with `Builder::close_element` once its last page is finished, before `Builder::finish`.
23
+
24
+ ## Example
25
+
26
+ ```rust
27
+ let paragraph = page.surface().open_element(TagKind::P);
28
+ page.finish()?;
29
+ builder.finish()?; // tag-element-unclosed: the paragraph is still open
30
+ ```
31
+
32
+ ## Data fields
33
+
34
+ - `count`: how many elements are still open.
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: "text-in-earlier-revision"
3
+ version: "0.2.0-alpha.4"
4
+ url: "https://docs.laminapdf.com/reference/codes/text-in-earlier-revision/"
5
+ ---
6
+
7
+ # text-in-earlier-revision
8
+
9
+ - Type: warning
10
+ - Kind: `security` (encryption, permissions or signatures block the call, or look tampered with)
11
+
12
+ ## What happened
13
+
14
+ The file was saved with incremental updates, and an earlier revision holds words that the latest revision has nowhere. Anyone can cut the file back to that revision and read them.
15
+
16
+ ## Why
17
+
18
+ An incremental save appends the changes to the end of the file and keeps everything before them (ISO 32000-2 §7.5.6). Deleting a paragraph and saving that way leaves the paragraph in the bytes of the earlier revision. Signing, filling a form and some editors' plain "Save" all save incrementally.
19
+
20
+ Not every removed word is a leak: fixing a typo removes the misspelt word too. The warning states that the earlier text is still in the file; whether that matters depends on what was removed.
21
+
22
+ ## How to fix
23
+
24
+ Save the file as a full rewrite, which keeps only the latest revision. A signed file loses its signatures that way, so sign it again afterwards.
25
+
26
+ ## Example
27
+
28
+ `fixtures/corpus/hello-incremental.pdf` first draws "Hello, World", and its update replaces that with "Hello, Update". `laminapdf check` reports `text-in-earlier-revision` with `revision` 0, `words` 1 and `pages` `[0]`.
29
+
30
+ ## Data fields
31
+
32
+ - `revision`: the earlier revision's index, 0 for the original file.
33
+ - `words`: how many words that revision has more often than the latest one (only words of two or more letters or digits count).
34
+ - `pages`: the indices of that revision's pages where those words are.
35
+
36
+ The warning has no `location`, and it never holds the words themselves.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "text-module-not-loaded"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/text-module-not-loaded/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "text-overflow"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/text-overflow/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "tounicode-conflict"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/tounicode-conflict/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "type"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/type/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unexpected-eof"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unexpected-eof/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unknown-axis"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unknown-axis/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unknown-code"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unknown-code/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unknown-destination"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unknown-destination/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unknown-font"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unknown-font/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unknown-option"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unknown-option/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unknown-page"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unknown-page/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unmapped-glyph"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unmapped-glyph/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unnumbered-heading-misused"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unnumbered-heading-misused/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unset-object"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unset-object/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unsupported-filter"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unsupported-filter/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unsupported-image"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unsupported-image/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unsupported-layout-option"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unsupported-layout-option/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unsupported-security-handler"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unsupported-security-handler/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "unsupported-version"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/unsupported-version/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "untagged-content"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/untagged-content/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "warnings-truncated"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/warnings-truncated/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "wasm-trap"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/wasm-trap/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "whole-font-rebuilt"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/whole-font-rebuilt/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "worker-crashed"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/worker-crashed/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "worker-failed"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/worker-failed/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "worker-version-mismatch"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/worker-version-mismatch/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "would-invalidate-signatures"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/would-invalidate-signatures/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "wrong-document"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/wrong-document/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "wrong-password"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/wrong-password/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "xobject-cycle"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/xobject-cycle/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "xref-repaired"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/xref-repaired/"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: "xrefstm-ignored"
3
- version: "0.2.0-alpha.3"
3
+ version: "0.2.0-alpha.4"
4
4
  url: "https://docs.laminapdf.com/reference/codes/xrefstm-ignored/"
5
5
  ---
6
6
 
package/docs/llms.txt CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Lamina PDF creates, reads, edits and saves PDF files from TypeScript and Rust: one Rust core, run as WebAssembly in browsers, Node, Deno, Bun and Cloudflare Workers (`@laminapdf/sdk`), or natively from the `laminapdf` crate. Positions are top-left points of the displayed page and page indexes start at 0; every error has a stable code with its own page.
4
4
 
5
- These docs describe version 0.2.0-alpha.3, the version of this package. The same docs are online at https://docs.laminapdf.com/llms.txt.
5
+ These docs describe version 0.2.0-alpha.4, the version of this package. The same docs are online at https://docs.laminapdf.com/llms.txt.
6
6
 
7
7
  - [Using Lamina PDF with coding agents](AGENTS.md)
8
8
  - [What old names became](renames.json)
@@ -29,12 +29,14 @@ These docs describe version 0.2.0-alpha.3, the version of this package. The same
29
29
  - [Pages and coordinates](pages/concepts/pages-and-coordinates.md): Points from the top-left corner of the page as it's displayed, y going down, and pages numbered from 0.
30
30
  - [Errors and warnings](pages/concepts/errors-and-warnings.md): One coded error shape on every surface, and warnings for what Lamina PDF repaired.
31
31
  - [What Lamina PDF writes and what it borrows](pages/concepts/dependencies.md): Lamina PDF writes the parts that decide a PDF's bytes, borrows the rest from permissive projects, and pins and checks everything it borrows.
32
+ - [How a page is drawn](pages/concepts/drawing-pages.md): A renderer turns a page into pixels; Lamina PDF reads the page's text, links and selection itself, from the same bytes.
32
33
 
33
34
  ## Create PDFs
34
35
 
35
36
  - [Text and fonts](pages/guides/fonts-and-text.md): Draw text in any script with your own fonts or the standard 14, one line at a time or as a paragraph that wraps in a box.
36
37
  - [Shapes, colour and images](pages/guides/images-and-vectors.md): Draw lines, shapes and images on a page, in any colour, with transparency, clipping and transforms.
37
38
  - [Links, outlines and metadata](pages/guides/links-outlines-and-metadata.md): Add links, named destinations, an outline, page labels, viewer preferences and metadata to a document.
39
+ - [Pages that flow](pages/guides/flowing-pages.md): Pour headings, paragraphs, tables and images, or a Markdown file, into as many pages as they need, with footnotes, a contents page and "Page X of Y" footers.
38
40
  - [Accessible PDFs](pages/guides/accessible-pdfs.md): Build PDF/UA-1 documents that screen readers can follow, with every machine-checkable rule checked when the builder finishes.
39
41
  - [Archival PDFs](pages/guides/archival-pdfs.md): Build PDF/A-2b, PDF/A-2u and PDF/A-3b documents that look the same in years to come, and attach files such as an e-invoice's XML.
40
42
 
@@ -44,10 +46,12 @@ These docs describe version 0.2.0-alpha.3, the version of this package. The same
44
46
  - [Save a PDF](pages/guides/save-a-pdf.md): Save edits as a revision appended to the original bytes or as a whole new file, and see when a file refuses a save.
45
47
  - [Open password-protected files](pages/guides/password-protected-files.md): Open PDFs that need a password, ask again when it is missing or wrong, and save them afterwards.
46
48
  - [Open files you don't trust](pages/guides/untrusted-files.md): Cap how much work an uploaded PDF can make Lamina PDF do, and refuse damaged files with strict mode.
49
+ - [Open large files by ranges](pages/guides/open-large-files.md): Open a PDF on a web server without downloading all of it, fetching only the byte ranges each read needs.
47
50
 
48
51
  ## Production
49
52
 
50
53
  - [Keep the page responsive](pages/guides/keep-the-page-responsive.md): Run Lamina PDF in a Web Worker with @laminapdf/sdk/worker, so a large file never freezes the page.
54
+ - [Test the PDFs you generate](pages/guides/test-generated-pdfs.md): Compare the PDFs your code makes with reference PDFs you approved, byte for byte, and draw both files' pages to see what changed.
51
55
 
52
56
  ## Recipes
53
57
 
@@ -56,6 +60,7 @@ These docs describe version 0.2.0-alpha.3, the version of this package. The same
56
60
  - [An invoice](pages/recipes/invoice.md): A tagged one-page invoice with an embedded font, a table of line items with right-aligned amounts and a total, in TypeScript and Rust.
57
61
  - [Multilingual text](pages/recipes/multilingual.md): Latin, Arabic, Devanagari, Hebrew and Chinese on one page, each in its own embedded font, as a shaped line and a wrapped paragraph.
58
62
  - [Images and vectors](pages/recipes/images-and-vectors.md): Shapes, a dashed curve, gray, RGB, CMYK and hex colour, transparency, a blend mode, a clip, a rotation, a JPEG and an RGBA image on one page.
63
+ - [Element flow](pages/recipes/element-flow.md): A report whose title, paragraphs and photo each start below wherever the one before ended, with a body that continues on a new page.
59
64
  - [Links and outlines](pages/recipes/links-and-outlines.md): Four A5 pages joined by web, page and named links, with a nested outline, page labels that read i, ii, 1, 2 and the outline shown on open.
60
65
  - [Generate, then edit](pages/recipes/generate-then-edit.md): Build a one-page draft, open its bytes, retitle it in one transaction and save the edit as a revision after the original bytes.
61
66
  - [Extract text for an LLM](pages/recipes/extract-markdown.md): Turn a PDF into Markdown in reading order, JSON with a box for every block, and chunks sized for retrieval, in TypeScript and Rust.
@@ -76,6 +81,7 @@ These docs describe version 0.2.0-alpha.3, the version of this package. The same
76
81
  - [Rust API (rustdoc)](pages/reference/rust.md): Where to read the API documentation of the Lamina PDF crates.
77
82
  - [Error and warning codes](pages/reference/codes.md): Every code Lamina PDF raises, generated from fixtures/codes.json when the site is built.
78
83
  - [Stability policy](pages/reference/stability.md): What a Lamina PDF version number promises, and what stays the same in every version.
84
+ - [Benchmarks](pages/reference/benchmarks.md): How fast Lamina PDF makes PDFs in each runtime, how large its WebAssembly files are, and how well it extracts text on a public benchmark.
79
85
  - [Changelog](pages/reference/changelog.md): What changed in each Lamina PDF release, newest first.
80
86
  - [Glossary](pages/reference/glossary.md): The PDF and Lamina PDF terms the docs use, each in a sentence or two.
81
87
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "What Lamina PDF writes and what it borrows"
3
3
  description: "Lamina PDF writes the parts that decide a PDF's bytes, borrows the rest from permissive projects, and pins and checks everything it borrows."
4
- version: "0.2.0-alpha.3"
4
+ version: "0.2.0-alpha.4"
5
5
  url: "https://docs.laminapdf.com/concepts/dependencies/"
6
6
  ---
7
7
 
@@ -25,7 +25,7 @@ Lamina PDF hands one big job to another project: turning pages into pixels. Real
25
25
 
26
26
  ## PDFium only draws, and only in a Web Worker
27
27
 
28
- PDFium is C++ reading files you didn't write, so Lamina PDF keeps it at arm's length. The viewer runs it inside a Web Worker, away from your page. PDFium never changes the document either: every edit goes through Lamina PDF, which also writes the saved file. Text, selection and links come from Lamina PDF's own reading of the file, never from the renderer. Lamina PDF also checks that the two agree: its tests compare each page's size and every character's position with PDFium's.
28
+ PDFium is C++ reading files you didn't write, so Lamina PDF keeps it at arm's length. The viewer runs it inside a Web Worker, away from your page. PDFium never changes the document either: every edit goes through Lamina PDF, which also writes the saved file. Text, selection and links come from Lamina PDF's own model of the file, never from the renderer. Lamina PDF also checks that the two agree: its tests compare each page's size and every character's position with PDFium's. [How a page is drawn](../../pages/concepts/drawing-pages.md) shows the two side by side.
29
29
 
30
30
  ## You pay for PDFium only when you show pages
31
31
 
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: "How a page is drawn"
3
+ description: "A renderer turns a page into pixels; Lamina PDF reads the page's text, links and selection itself, from the same bytes."
4
+ version: "0.2.0-alpha.4"
5
+ url: "https://docs.laminapdf.com/concepts/drawing-pages/"
6
+ ---
7
+
8
+ # How a page is drawn
9
+
10
+ A renderer turns a page into pixels; Lamina PDF reads the page's text, links and selection itself, from the same bytes.
11
+
12
+ Two readers go through every page you show. A renderer, PDFium or hayro, turns the page into pixels. Lamina PDF's own model of the file gives you everything you can select, search or click: the text, the links and the selection boxes. Both read the same bytes.
13
+
14
+ *A renderer draws the pixels; Lamina PDF reads the text from the same bytes.*
15
+
16
+ Two readers use your PDF's bytes. To draw, a render request names the page, the scale, the tile to draw (its clip) and a rotation. The request becomes a tile plan, which fixes the size in pixels, and a renderer, PDFium or hayro, draws the tile as RGBA pixels. Text, links and selection never come from the renderer. Lamina PDF reads them from its own model of the same bytes, the model that also edits and saves the file.
17
+
18
+ ## You ask for a tile, and get RGBA pixels back
19
+
20
+ A render request names the page, the scale in pixels per point, and optionally a clip and a rotation. The clip is the part of the page you want, as a rectangle in pixels: a viewer asks for tiles of a large page rather than the whole page at once, so it only draws what's on screen. A scale of 2 draws 144 pixels per inch, sharp on most screens.
21
+
22
+ Before it draws, the renderer turns the request into a tile plan: the whole page's size in pixels after the rotation, and the tile inside it. The renderer checks the tile against its limits first: by default, a tile wider or taller than 16,384 pixels, or larger than about 16.7 million pixels, fails with `render-too-large` instead of filling your memory. The renderer then draws the tile as straight RGBA, four bytes a pixel, row by row from the top-left corner.
23
+
24
+ This example draws a page with hayro and reads the same page's text:
25
+
26
+ `packages/sdk/examples/draw-page.ts`:
27
+
28
+ ```ts
29
+ // Draws one page to pixels and reads the same page's text, to show who does which job: a renderer
30
+ // turns the page into RGBA pixels, and Lamina PDF reads the text from its own model of the file.
31
+ // Both read the same bytes. In Node, load the hayro renderer with the module's bytes:
32
+ //
33
+ // const wasm = fileURLToPath(import.meta.resolve("@laminapdf/wasm/lamina_pdf_render_hayro.wasm"));
34
+ // const renderer = await initHayro(readFileSync(wasm));
35
+ //
36
+ // Text needs Lamina PDF's text or extract module: `await init({ text: true })`.
37
+
38
+ import { bytesSource, type RenderBackend } from "@laminapdf/render";
39
+ import { Document } from "@laminapdf/sdk";
40
+
41
+ /** Pixels per point: 2 draws at 144 dpi, sharp on most screens. */
42
+ const SCALE = 2;
43
+
44
+ /** One page as pixels, with its text beside them. */
45
+ export interface DrawnPage {
46
+ readonly width: number;
47
+ readonly height: number;
48
+ /** Straight RGBA, four bytes a pixel, row by row from the top-left corner. */
49
+ readonly pixels: Uint8ClampedArray;
50
+ readonly text: string;
51
+ }
52
+
53
+ /** Draws page `index` of `bytes` with `renderer` and reads its text with Lamina PDF. */
54
+ export function drawPage(renderer: RenderBackend, bytes: Uint8Array, index: number): DrawnPage {
55
+ // The renderer draws the page and nothing else: it never supplies text, links or selection.
56
+ using drawing = renderer.open(bytesSource(bytes));
57
+ const { width, height, pixels } = drawing.render({ page: index, scale: SCALE });
58
+ // The text comes from Lamina PDF, which also edits and saves the file, so what you select is what
59
+ // an edit changes.
60
+ using doc = Document.open(bytes);
61
+ const text = doc.page(index).text().text();
62
+ return { width, height, pixels, text };
63
+ }
64
+ ```
65
+
66
+ ## The text never comes from the renderer
67
+
68
+ A renderer draws glyphs, but its idea of the text can differ from the file's: it may guess the order of letters or lose the characters behind a ligature. So Lamina PDF reads text, links and selection from its own model of the file, the same model that edits and saves it. What you select is what `page.text()` returns and what an edit changes.
69
+
70
+ The two readers can still disagree on where a glyph sits, since each reads the fonts its own way. Lamina PDF's tests compare each page's size and every character's position with PDFium's, and a difference becomes a bug to fix.
71
+
72
+ ## PDFium in the browser, hayro on servers
73
+
74
+ PDFium, the engine behind Chrome's PDF viewer, draws the pages in the viewer. It runs in a Web Worker, away from your page, and only draws: it never changes the document. hayro is a renderer written in Rust. It's the lighter choice on a server or in a Cloudflare Worker, and it draws in the tests that compare pages. [What Lamina PDF writes and what it borrows](../../pages/concepts/dependencies.md) explains why each one is there.
75
+
76
+ Next, see [how to compare pages in tests](../../pages/guides/test-generated-pdfs.md), which draws two PDFs and counts the pixels that differ.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "Errors and warnings"
3
3
  description: "One coded error shape on every surface, and warnings for what Lamina PDF repaired."
4
- version: "0.2.0-alpha.3"
4
+ version: "0.2.0-alpha.4"
5
5
  url: "https://docs.laminapdf.com/concepts/errors-and-warnings/"
6
6
  ---
7
7
 
@@ -21,7 +21,11 @@ A warning means the call went ahead, but Lamina PDF had to repair, drop or appro
21
21
 
22
22
  ## Every surface has the same fields
23
23
 
24
- Errors and warnings have the same fields in TypeScript and Rust: `code`, `kind`, `message`, `hint`, `location`, `data` and `docsUrl`. `toJSON()` in TypeScript gives the same object as `serde` does in Rust, so a server and a browser can pass them to each other unchanged.
24
+ Errors and warnings have the same fields in TypeScript and Rust: `code`, `kind`, `message`, `hint`, `location`, `data` and `docsUrl`. A usage error can also carry `didYouMean`, the closest names to one Lamina PDF didn't recognise. `toJSON()` in TypeScript gives the same object as `serde` does in Rust, so a server and a browser can pass them to each other unchanged.
25
+
26
+ *A call stops with an error or completes with warnings, and both carry the same core fields.*
27
+
28
+ A call either stops with a `LaminaPdfError` or completes, with any warnings on `doc.warnings`. Errors and warnings carry the same fields: `code`, `kind`, `message`, `hint`, `location`, `data` and `docsUrl`; an error can also carry `didYouMean`. Text from the document goes only in `data`, never in `message` or `hint`.
25
29
 
26
30
  - **`kind` sorts errors by who can fix them**, such as `input`, `limit`, `usage`, `state` or `io`. For example, a server returns a 4xx status for `input` and `limit` and a 5xx for the rest, as the [Cloudflare Workers quick start](../../pages/quick-start/workers.md) does.
27
31
  - **Text from the document is untrusted**, so it never appears in `message` or `hint`. It goes only in `data`, where you can escape it before you show it.