@laminapdf/sdk 0.0.0-stage → 0.2.0-alpha.3

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 (478) hide show
  1. package/README.md +243 -2
  2. package/dist/api.d.ts +26 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +12 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/builder.d.ts +335 -0
  7. package/dist/builder.d.ts.map +1 -0
  8. package/dist/builder.js +574 -0
  9. package/dist/builder.js.map +1 -0
  10. package/dist/defined.d.ts +5 -0
  11. package/dist/defined.d.ts.map +1 -0
  12. package/dist/defined.js +7 -0
  13. package/dist/defined.js.map +1 -0
  14. package/dist/document.d.ts +267 -0
  15. package/dist/document.d.ts.map +1 -0
  16. package/dist/document.js +472 -0
  17. package/dist/document.js.map +1 -0
  18. package/dist/entry/node.d.ts +30 -0
  19. package/dist/entry/node.d.ts.map +1 -0
  20. package/dist/entry/node.js +37 -0
  21. package/dist/entry/node.js.map +1 -0
  22. package/dist/entry/workerd.d.ts +30 -0
  23. package/dist/entry/workerd.d.ts.map +1 -0
  24. package/dist/entry/workerd.js +37 -0
  25. package/dist/entry/workerd.js.map +1 -0
  26. package/dist/errors.d.ts +102 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +131 -0
  29. package/dist/errors.js.map +1 -0
  30. package/dist/explain.d.ts +20 -0
  31. package/dist/explain.d.ts.map +1 -0
  32. package/dist/explain.js +14 -0
  33. package/dist/explain.js.map +1 -0
  34. package/dist/extract.d.ts +57 -0
  35. package/dist/extract.d.ts.map +1 -0
  36. package/dist/extract.js +5 -0
  37. package/dist/extract.js.map +1 -0
  38. package/dist/font.d.ts +73 -0
  39. package/dist/font.d.ts.map +1 -0
  40. package/dist/font.js +133 -0
  41. package/dist/font.js.map +1 -0
  42. package/dist/generated/builder-enums.d.ts +29 -0
  43. package/dist/generated/builder-enums.d.ts.map +1 -0
  44. package/dist/generated/builder-enums.js +80 -0
  45. package/dist/generated/builder-enums.js.map +1 -0
  46. package/dist/generated/codes.d.ts +109 -0
  47. package/dist/generated/codes.d.ts.map +1 -0
  48. package/dist/generated/codes.js +508 -0
  49. package/dist/generated/codes.js.map +1 -0
  50. package/dist/generated/explain.d.ts +6 -0
  51. package/dist/generated/explain.d.ts.map +1 -0
  52. package/dist/generated/explain.js +155 -0
  53. package/dist/generated/explain.js.map +1 -0
  54. package/dist/generated/extract.d.ts +235 -0
  55. package/dist/generated/extract.d.ts.map +1 -0
  56. package/dist/generated/extract.js +4 -0
  57. package/dist/generated/extract.js.map +1 -0
  58. package/dist/index.d.ts +30 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +37 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/init.d.ts +88 -0
  63. package/dist/init.d.ts.map +1 -0
  64. package/dist/init.js +139 -0
  65. package/dist/init.js.map +1 -0
  66. package/dist/internal/handle.d.ts +58 -0
  67. package/dist/internal/handle.d.ts.map +1 -0
  68. package/dist/internal/handle.js +113 -0
  69. package/dist/internal/handle.js.map +1 -0
  70. package/dist/internal/instance.d.ts +56 -0
  71. package/dist/internal/instance.d.ts.map +1 -0
  72. package/dist/internal/instance.js +125 -0
  73. package/dist/internal/instance.js.map +1 -0
  74. package/dist/loader/fetch.d.ts +3 -0
  75. package/dist/loader/fetch.d.ts.map +1 -0
  76. package/dist/loader/fetch.js +2 -0
  77. package/dist/loader/fetch.js.map +1 -0
  78. package/dist/loader/node.d.ts +3 -0
  79. package/dist/loader/node.d.ts.map +1 -0
  80. package/dist/loader/node.js +9 -0
  81. package/dist/loader/node.js.map +1 -0
  82. package/dist/loader/workerd.d.ts +3 -0
  83. package/dist/loader/workerd.d.ts.map +1 -0
  84. package/dist/loader/workerd.js +15 -0
  85. package/dist/loader/workerd.js.map +1 -0
  86. package/dist/matrix.d.ts +16 -0
  87. package/dist/matrix.d.ts.map +1 -0
  88. package/dist/matrix.js +36 -0
  89. package/dist/matrix.js.map +1 -0
  90. package/dist/path.d.ts +34 -0
  91. package/dist/path.d.ts.map +1 -0
  92. package/dist/path.js +49 -0
  93. package/dist/path.js.map +1 -0
  94. package/dist/source/http.d.ts +36 -0
  95. package/dist/source/http.d.ts.map +1 -0
  96. package/dist/source/http.js +211 -0
  97. package/dist/source/http.js.map +1 -0
  98. package/dist/source/range.d.ts +75 -0
  99. package/dist/source/range.d.ts.map +1 -0
  100. package/dist/source/range.js +100 -0
  101. package/dist/source/range.js.map +1 -0
  102. package/dist/text.d.ts +90 -0
  103. package/dist/text.d.ts.map +1 -0
  104. package/dist/text.js +127 -0
  105. package/dist/text.js.map +1 -0
  106. package/dist/transaction.d.ts +36 -0
  107. package/dist/transaction.d.ts.map +1 -0
  108. package/dist/transaction.js +47 -0
  109. package/dist/transaction.js.map +1 -0
  110. package/dist/types.d.ts +79 -0
  111. package/dist/types.d.ts.map +1 -0
  112. package/dist/types.js +2 -0
  113. package/dist/types.js.map +1 -0
  114. package/dist/version.d.ts +3 -0
  115. package/dist/version.d.ts.map +1 -0
  116. package/dist/version.js +6 -0
  117. package/dist/version.js.map +1 -0
  118. package/dist/worker/client.d.ts +88 -0
  119. package/dist/worker/client.d.ts.map +1 -0
  120. package/dist/worker/client.js +407 -0
  121. package/dist/worker/client.js.map +1 -0
  122. package/dist/worker/emitter.d.ts +12 -0
  123. package/dist/worker/emitter.d.ts.map +1 -0
  124. package/dist/worker/emitter.js +34 -0
  125. package/dist/worker/emitter.js.map +1 -0
  126. package/dist/worker/entry.d.ts +2 -0
  127. package/dist/worker/entry.d.ts.map +1 -0
  128. package/dist/worker/entry.js +4 -0
  129. package/dist/worker/entry.js.map +1 -0
  130. package/dist/worker/index.d.ts +7 -0
  131. package/dist/worker/index.d.ts.map +1 -0
  132. package/dist/worker/index.js +4 -0
  133. package/dist/worker/index.js.map +1 -0
  134. package/dist/worker/protocol.d.ts +82 -0
  135. package/dist/worker/protocol.d.ts.map +1 -0
  136. package/dist/worker/protocol.js +11 -0
  137. package/dist/worker/protocol.js.map +1 -0
  138. package/dist/worker/server.d.ts +51 -0
  139. package/dist/worker/server.d.ts.map +1 -0
  140. package/dist/worker/server.js +493 -0
  141. package/dist/worker/server.js.map +1 -0
  142. package/dist/worker/support.d.ts +43 -0
  143. package/dist/worker/support.d.ts.map +1 -0
  144. package/dist/worker/support.js +26 -0
  145. package/dist/worker/support.js.map +1 -0
  146. package/dist/worker/transfer.d.ts +3 -0
  147. package/dist/worker/transfer.d.ts.map +1 -0
  148. package/dist/worker/transfer.js +13 -0
  149. package/dist/worker/transfer.js.map +1 -0
  150. package/dist/worker/types.d.ts +50 -0
  151. package/dist/worker/types.d.ts.map +1 -0
  152. package/dist/worker/types.js +2 -0
  153. package/dist/worker/types.js.map +1 -0
  154. package/docs/AGENTS.md +14 -0
  155. package/docs/api/README.md +147 -0
  156. package/docs/api/classes/Builder.md +467 -0
  157. package/docs/api/classes/Document.md +742 -0
  158. package/docs/api/classes/Font.md +74 -0
  159. package/docs/api/classes/Image.md +140 -0
  160. package/docs/api/classes/LaminaPdfError.md +189 -0
  161. package/docs/api/classes/Page.md +178 -0
  162. package/docs/api/classes/PageRef.md +253 -0
  163. package/docs/api/classes/PageText.md +129 -0
  164. package/docs/api/classes/PageTextRun.md +167 -0
  165. package/docs/api/classes/PendingPath.md +97 -0
  166. package/docs/api/classes/SaveJob.md +205 -0
  167. package/docs/api/classes/Surface.md +326 -0
  168. package/docs/api/classes/Transaction.md +111 -0
  169. package/docs/api/functions/callbackSource.md +33 -0
  170. package/docs/api/functions/httpRangeSource.md +48 -0
  171. package/docs/api/functions/init.md +36 -0
  172. package/docs/api/functions/isExtractLoaded.md +21 -0
  173. package/docs/api/functions/isInitialized.md +19 -0
  174. package/docs/api/functions/isLaminaPdfError.md +41 -0
  175. package/docs/api/functions/isTextLoaded.md +19 -0
  176. package/docs/api/functions/loadExtract.md +28 -0
  177. package/docs/api/functions/loadText.md +28 -0
  178. package/docs/api/functions/onLeak.md +29 -0
  179. package/docs/api/functions/reset.md +22 -0
  180. package/docs/api/functions/wasmMemory.md +22 -0
  181. package/docs/api/interfaces/BuilderOptions.md +108 -0
  182. package/docs/api/interfaces/ByteRange.md +29 -0
  183. package/docs/api/interfaces/ChunkOptions.md +37 -0
  184. package/docs/api/interfaces/Diagnostic.md +67 -0
  185. package/docs/api/interfaces/ExtractOptions.md +92 -0
  186. package/docs/api/interfaces/ExtractResult.md +37 -0
  187. package/docs/api/interfaces/FontInfo.md +37 -0
  188. package/docs/api/interfaces/HttpRangeOptions.md +78 -0
  189. package/docs/api/interfaces/InitOptions.md +40 -0
  190. package/docs/api/interfaces/Leak.md +21 -0
  191. package/docs/api/interfaces/Location.md +53 -0
  192. package/docs/api/interfaces/OpLog.md +25 -0
  193. package/docs/api/interfaces/OpenOptions.md +37 -0
  194. package/docs/api/interfaces/PageTextOptions.md +21 -0
  195. package/docs/api/interfaces/PathBuilder.md +195 -0
  196. package/docs/api/interfaces/QuadPoint.md +25 -0
  197. package/docs/api/interfaces/RangeOptions.md +54 -0
  198. package/docs/api/interfaces/RangeSource.md +59 -0
  199. package/docs/api/interfaces/StrokeStyle.md +61 -0
  200. package/docs/api/interfaces/TagSpec.md +69 -0
  201. package/docs/api/interfaces/TextBoxOptions.md +93 -0
  202. package/docs/api/interfaces/TextGlyph.md +29 -0
  203. package/docs/api/interfaces/TextOptions.md +101 -0
  204. package/docs/api/interfaces/WasmMemory.md +37 -0
  205. package/docs/api/type-aliases/AfRelationship.md +15 -0
  206. package/docs/api/type-aliases/Align.md +15 -0
  207. package/docs/api/type-aliases/ArtifactKind.md +15 -0
  208. package/docs/api/type-aliases/AttachmentOptions.md +15 -0
  209. package/docs/api/type-aliases/BlendMode.md +15 -0
  210. package/docs/api/type-aliases/BoxRect.md +15 -0
  211. package/docs/api/type-aliases/BuildOptions.md +15 -0
  212. package/docs/api/type-aliases/Cell.md +71 -0
  213. package/docs/api/type-aliases/Chunk.md +79 -0
  214. package/docs/api/type-aliases/Color.md +16 -0
  215. package/docs/api/type-aliases/Coordinates.md +55 -0
  216. package/docs/api/type-aliases/Direction.md +15 -0
  217. package/docs/api/type-aliases/DocumentInfo.md +15 -0
  218. package/docs/api/type-aliases/DropReason.md +15 -0
  219. package/docs/api/type-aliases/Dropped.md +59 -0
  220. package/docs/api/type-aliases/Edited.md +15 -0
  221. package/docs/api/type-aliases/ErrorCode.md +15 -0
  222. package/docs/api/type-aliases/ErrorKind.md +15 -0
  223. package/docs/api/type-aliases/ExtractFormat.md +15 -0
  224. package/docs/api/type-aliases/ExtractedBlock.md +82 -0
  225. package/docs/api/type-aliases/ExtractedPage.md +65 -0
  226. package/docs/api/type-aliases/ExtractedSource.md +48 -0
  227. package/docs/api/type-aliases/Extraction.md +22 -0
  228. package/docs/api/type-aliases/FillRule.md +15 -0
  229. package/docs/api/type-aliases/Fit.md +15 -0
  230. package/docs/api/type-aliases/Flags.md +15 -0
  231. package/docs/api/type-aliases/Generator.md +41 -0
  232. package/docs/api/type-aliases/GlyphQuad.md +15 -0
  233. package/docs/api/type-aliases/InfoPatch.md +15 -0
  234. package/docs/api/type-aliases/LaminaPdfWarning.md +16 -0
  235. package/docs/api/type-aliases/LimitName.md +15 -0
  236. package/docs/api/type-aliases/Limits.md +15 -0
  237. package/docs/api/type-aliases/LineBox.md +15 -0
  238. package/docs/api/type-aliases/LineCap.md +15 -0
  239. package/docs/api/type-aliases/LineJoin.md +15 -0
  240. package/docs/api/type-aliases/LinkTarget.md +15 -0
  241. package/docs/api/type-aliases/Metadata.md +15 -0
  242. package/docs/api/type-aliases/Op.md +15 -0
  243. package/docs/api/type-aliases/OutlineEntry.md +15 -0
  244. package/docs/api/type-aliases/Overflow.md +15 -0
  245. package/docs/api/type-aliases/PageInfo.md +15 -0
  246. package/docs/api/type-aliases/PageLabel.md +15 -0
  247. package/docs/api/type-aliases/PageSizeName.md +15 -0
  248. package/docs/api/type-aliases/Point.md +15 -0
  249. package/docs/api/type-aliases/Profile.md +15 -0
  250. package/docs/api/type-aliases/Progress.md +15 -0
  251. package/docs/api/type-aliases/ReadingOrder.md +15 -0
  252. package/docs/api/type-aliases/Rect.md +15 -0
  253. package/docs/api/type-aliases/Region.md +31 -0
  254. package/docs/api/type-aliases/RenderMode.md +15 -0
  255. package/docs/api/type-aliases/Rotation.md +15 -0
  256. package/docs/api/type-aliases/SaveOptions.md +15 -0
  257. package/docs/api/type-aliases/SaveReport.md +15 -0
  258. package/docs/api/type-aliases/Span.md +63 -0
  259. package/docs/api/type-aliases/SplitOn.md +15 -0
  260. package/docs/api/type-aliases/Standard14.md +15 -0
  261. package/docs/api/type-aliases/StructRef.md +41 -0
  262. package/docs/api/type-aliases/StructSource.md +17 -0
  263. package/docs/api/type-aliases/TableDetector.md +15 -0
  264. package/docs/api/type-aliases/TableMode.md +15 -0
  265. package/docs/api/type-aliases/TableScope.md +15 -0
  266. package/docs/api/type-aliases/Tag.md +15 -0
  267. package/docs/api/type-aliases/TagName.md +15 -0
  268. package/docs/api/type-aliases/TextLayout.md +15 -0
  269. package/docs/api/type-aliases/TextRange.md +33 -0
  270. package/docs/api/type-aliases/TextRunInfo.md +15 -0
  271. package/docs/api/type-aliases/Transform.md +15 -0
  272. package/docs/api/type-aliases/UndoOutcome.md +15 -0
  273. package/docs/api/type-aliases/ViewerPreferences.md +15 -0
  274. package/docs/api/type-aliases/WarningCode.md +15 -0
  275. package/docs/api/type-aliases/WasmSource.md +16 -0
  276. package/docs/api/variables/Matrix.md +99 -0
  277. package/docs/api/variables/PAGE_SIZES.md +15 -0
  278. package/docs/api/variables/TAG_NAMES.md +15 -0
  279. package/docs/errors/README.md +156 -0
  280. package/docs/errors/aes-padding-invalid.md +34 -0
  281. package/docs/errors/already-initialized.md +34 -0
  282. package/docs/errors/binary-output-to-terminal.md +35 -0
  283. package/docs/errors/builder-finished.md +35 -0
  284. package/docs/errors/cancelled.md +35 -0
  285. package/docs/errors/cmap-invalid.md +42 -0
  286. package/docs/errors/collection-index.md +33 -0
  287. package/docs/errors/color-components.md +33 -0
  288. package/docs/errors/content-bad-operands.md +36 -0
  289. package/docs/errors/content-path-unpainted.md +36 -0
  290. package/docs/errors/content-resource-missing.md +37 -0
  291. package/docs/errors/content-syntax.md +36 -0
  292. package/docs/errors/content-unbalanced-bt.md +36 -0
  293. package/docs/errors/content-unbalanced-marked.md +36 -0
  294. package/docs/errors/content-unbalanced-q.md +36 -0
  295. package/docs/errors/content-unknown-operator.md +37 -0
  296. package/docs/errors/data-pending.md +34 -0
  297. package/docs/errors/decompress.md +34 -0
  298. package/docs/errors/device-color-without-output-intent.md +33 -0
  299. package/docs/errors/direct-page.md +34 -0
  300. package/docs/errors/disposed.md +34 -0
  301. package/docs/errors/document-changed.md +34 -0
  302. package/docs/errors/embedded-file-forbidden.md +35 -0
  303. package/docs/errors/embedded-file-without-mime-type.md +36 -0
  304. package/docs/errors/encoding-full.md +34 -0
  305. package/docs/errors/encrypted-base.md +33 -0
  306. package/docs/errors/extract-limit-blocks.md +35 -0
  307. package/docs/errors/extract-module-not-loaded.md +37 -0
  308. package/docs/errors/extract-reading-order-ambiguous.md +32 -0
  309. package/docs/errors/extract-struct-tree-ignored.md +32 -0
  310. package/docs/errors/extract-table-ambiguous.md +32 -0
  311. package/docs/errors/extract-table-limit.md +35 -0
  312. package/docs/errors/extract-untagged-content.md +32 -0
  313. package/docs/errors/fetch-failed.md +34 -0
  314. package/docs/errors/flate-truncated.md +34 -0
  315. package/docs/errors/font-invalid.md +36 -0
  316. package/docs/errors/font-mismatch.md +34 -0
  317. package/docs/errors/font-not-embeddable.md +34 -0
  318. package/docs/errors/font-not-embedded.md +35 -0
  319. package/docs/errors/font-not-shapable.md +33 -0
  320. package/docs/errors/glyph-out-of-range.md +34 -0
  321. package/docs/errors/glyph-without-unicode.md +35 -0
  322. package/docs/errors/heading-level-skipped.md +36 -0
  323. package/docs/errors/image-data-length.md +33 -0
  324. package/docs/errors/image-too-large.md +32 -0
  325. package/docs/errors/inline-image-unterminated.md +36 -0
  326. package/docs/errors/input-unreadable.md +37 -0
  327. package/docs/errors/instance-reset.md +34 -0
  328. package/docs/errors/invalid-argument.md +33 -0
  329. package/docs/errors/invalid-axis-value.md +32 -0
  330. package/docs/errors/invalid-box.md +34 -0
  331. package/docs/errors/invalid-color.md +32 -0
  332. package/docs/errors/invalid-command-line.md +44 -0
  333. package/docs/errors/invalid-date.md +34 -0
  334. package/docs/errors/invalid-entry.md +34 -0
  335. package/docs/errors/invalid-feature.md +32 -0
  336. package/docs/errors/invalid-font.md +32 -0
  337. package/docs/errors/invalid-geometry.md +32 -0
  338. package/docs/errors/invalid-icc-profile.md +32 -0
  339. package/docs/errors/invalid-image.md +33 -0
  340. package/docs/errors/invalid-op-log.md +33 -0
  341. package/docs/errors/invalid-page-label.md +34 -0
  342. package/docs/errors/invalid-page-labels.md +32 -0
  343. package/docs/errors/invalid-page-range.md +37 -0
  344. package/docs/errors/invalid-rotate.md +34 -0
  345. package/docs/errors/invalid-structure-nesting.md +38 -0
  346. package/docs/errors/invalid-structure.md +34 -0
  347. package/docs/errors/invalid-text-range.md +33 -0
  348. package/docs/errors/job-finished.md +34 -0
  349. package/docs/errors/limit-exceeded.md +38 -0
  350. package/docs/errors/link-without-contents.md +33 -0
  351. package/docs/errors/link-without-structure.md +37 -0
  352. package/docs/errors/missing-alt-text.md +33 -0
  353. package/docs/errors/missing-glyph.md +33 -0
  354. package/docs/errors/missing-header.md +37 -0
  355. package/docs/errors/missing-lang.md +32 -0
  356. package/docs/errors/missing-root.md +34 -0
  357. package/docs/errors/missing-title.md +32 -0
  358. package/docs/errors/name-tree-node-skipped.md +34 -0
  359. package/docs/errors/nested-transaction.md +34 -0
  360. package/docs/errors/no-pending-save.md +32 -0
  361. package/docs/errors/no-transaction.md +33 -0
  362. package/docs/errors/not-initialized.md +35 -0
  363. package/docs/errors/not-pdf.md +33 -0
  364. package/docs/errors/not-rebased.md +35 -0
  365. package/docs/errors/object-number-out-of-range.md +38 -0
  366. package/docs/errors/objstm-index-mismatch.md +36 -0
  367. package/docs/errors/out-of-memory.md +38 -0
  368. package/docs/errors/outline-cycle.md +34 -0
  369. package/docs/errors/outline-item-skipped.md +34 -0
  370. package/docs/errors/output-unwritable.md +37 -0
  371. package/docs/errors/overwrite-refused.md +36 -0
  372. package/docs/errors/page-count-mismatch.md +34 -0
  373. package/docs/errors/page-index-out-of-range.md +34 -0
  374. package/docs/errors/page-tree-node-skipped.md +35 -0
  375. package/docs/errors/password-required.md +36 -0
  376. package/docs/errors/path-outside-roots.md +32 -0
  377. package/docs/errors/perms-mismatch.md +34 -0
  378. package/docs/errors/profile-version-conflict.md +35 -0
  379. package/docs/errors/reference-cycle.md +35 -0
  380. package/docs/errors/render-backend-unavailable.md +32 -0
  381. package/docs/errors/render-failed.md +33 -0
  382. package/docs/errors/render-too-large.md +36 -0
  383. package/docs/errors/repaired-base.md +34 -0
  384. package/docs/errors/requires-rewrite.md +38 -0
  385. package/docs/errors/saved-not-rebased.md +34 -0
  386. package/docs/errors/sink-not-empty.md +33 -0
  387. package/docs/errors/sink.md +31 -0
  388. package/docs/errors/source-budget-exceeded.md +34 -0
  389. package/docs/errors/source-changed.md +33 -0
  390. package/docs/errors/source.md +30 -0
  391. package/docs/errors/stale-generation.md +34 -0
  392. package/docs/errors/stream-length-recovered.md +37 -0
  393. package/docs/errors/strict.md +34 -0
  394. package/docs/errors/subset-failed.md +31 -0
  395. package/docs/errors/syntax.md +34 -0
  396. package/docs/errors/text-module-not-loaded.md +36 -0
  397. package/docs/errors/text-overflow.md +34 -0
  398. package/docs/errors/tounicode-conflict.md +32 -0
  399. package/docs/errors/type.md +34 -0
  400. package/docs/errors/unexpected-eof.md +34 -0
  401. package/docs/errors/unknown-axis.md +33 -0
  402. package/docs/errors/unknown-code.md +36 -0
  403. package/docs/errors/unknown-destination.md +33 -0
  404. package/docs/errors/unknown-font.md +33 -0
  405. package/docs/errors/unknown-option.md +33 -0
  406. package/docs/errors/unknown-page.md +34 -0
  407. package/docs/errors/unmapped-glyph.md +36 -0
  408. package/docs/errors/unnumbered-heading-misused.md +34 -0
  409. package/docs/errors/unset-object.md +30 -0
  410. package/docs/errors/unsupported-filter.md +34 -0
  411. package/docs/errors/unsupported-image.md +33 -0
  412. package/docs/errors/unsupported-layout-option.md +33 -0
  413. package/docs/errors/unsupported-security-handler.md +34 -0
  414. package/docs/errors/unsupported-version.md +32 -0
  415. package/docs/errors/untagged-content.md +35 -0
  416. package/docs/errors/warnings-truncated.md +35 -0
  417. package/docs/errors/wasm-trap.md +37 -0
  418. package/docs/errors/whole-font-rebuilt.md +30 -0
  419. package/docs/errors/worker-crashed.md +33 -0
  420. package/docs/errors/worker-failed.md +32 -0
  421. package/docs/errors/worker-version-mismatch.md +34 -0
  422. package/docs/errors/would-invalidate-signatures.md +38 -0
  423. package/docs/errors/wrong-document.md +33 -0
  424. package/docs/errors/wrong-password.md +34 -0
  425. package/docs/errors/xobject-cycle.md +36 -0
  426. package/docs/errors/xref-repaired.md +36 -0
  427. package/docs/errors/xrefstm-ignored.md +34 -0
  428. package/docs/llms.txt +88 -0
  429. package/docs/pages/concepts/dependencies.md +44 -0
  430. package/docs/pages/concepts/errors-and-warnings.md +64 -0
  431. package/docs/pages/concepts/how-lamina-thinks.md +86 -0
  432. package/docs/pages/concepts/pages-and-coordinates.md +67 -0
  433. package/docs/pages/guides/accessible-pdfs.md +260 -0
  434. package/docs/pages/guides/archival-pdfs.md +429 -0
  435. package/docs/pages/guides/edit-a-pdf.md +137 -0
  436. package/docs/pages/guides/fonts-and-text.md +202 -0
  437. package/docs/pages/guides/images-and-vectors.md +219 -0
  438. package/docs/pages/guides/keep-the-page-responsive.md +81 -0
  439. package/docs/pages/guides/links-outlines-and-metadata.md +222 -0
  440. package/docs/pages/guides/password-protected-files.md +70 -0
  441. package/docs/pages/guides/save-a-pdf.md +144 -0
  442. package/docs/pages/guides/untrusted-files.md +80 -0
  443. package/docs/pages/index.md +33 -0
  444. package/docs/pages/install.md +75 -0
  445. package/docs/pages/quick-start/browser.md +67 -0
  446. package/docs/pages/quick-start/bun.md +60 -0
  447. package/docs/pages/quick-start/deno.md +58 -0
  448. package/docs/pages/quick-start/node.md +61 -0
  449. package/docs/pages/quick-start/rust.md +58 -0
  450. package/docs/pages/quick-start/workers.md +139 -0
  451. package/docs/pages/recipes/cloudflare-worker.md +115 -0
  452. package/docs/pages/recipes/extract-markdown.md +114 -0
  453. package/docs/pages/recipes/generate-then-edit.md +135 -0
  454. package/docs/pages/recipes/hello.md +94 -0
  455. package/docs/pages/recipes/images-and-vectors.md +209 -0
  456. package/docs/pages/recipes/invoice.md +226 -0
  457. package/docs/pages/recipes/links-and-outlines.md +215 -0
  458. package/docs/pages/recipes/multilingual.md +189 -0
  459. package/docs/pages/recipes/open-untrusted.md +65 -0
  460. package/docs/pages/recipes/pdf-a-archive.md +205 -0
  461. package/docs/pages/recipes/pdf-a3-invoice-with-xml.md +222 -0
  462. package/docs/pages/recipes/pdf-ua-report.md +237 -0
  463. package/docs/pages/recipes/report.md +125 -0
  464. package/docs/pages/recipes/web-worker-client.md +64 -0
  465. package/docs/pages/recipes.md +47 -0
  466. package/docs/pages/reference/changelog.md +86 -0
  467. package/docs/pages/reference/codes.md +14 -0
  468. package/docs/pages/reference/glossary.md +108 -0
  469. package/docs/pages/reference/rust.md +36 -0
  470. package/docs/pages/reference/stability.md +59 -0
  471. package/docs/pages/start/coding-agents.md +45 -0
  472. package/docs/pages/start/first-pdf.md +77 -0
  473. package/docs/pages/troubleshooting.md +74 -0
  474. package/docs/renames.json +86 -0
  475. package/docs/schemas/error.schema.json +305 -0
  476. package/docs/schemas/renames.schema.json +29 -0
  477. package/package.json +93 -3
  478. package/schemas/error.schema.json +305 -0
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: "xobject-cycle"
3
+ version: "0.2.0-alpha.3"
4
+ url: "https://docs.laminapdf.com/reference/codes/xobject-cycle/"
5
+ ---
6
+
7
+ # xobject-cycle
8
+
9
+ - Type: warning
10
+ - Kind: `input` (the input is malformed beyond what tolerance repairs)
11
+
12
+ ## What happened
13
+
14
+ A Form XObject draws itself, directly or through other forms; the inner `Do` was skipped.
15
+
16
+ ## Why
17
+
18
+ A malformed or hostile file: forms that draw each other without end would never finish.
19
+
20
+ ## How to fix
21
+
22
+ Nothing to do.
23
+
24
+ ## Example
25
+
26
+ ```text
27
+ 8 0 obj << /Subtype /Form /Resources << /XObject << /Me 8 0 R >> >> >> stream /Me Do endstream
28
+ ```
29
+
30
+ The form draws itself: the inner `/Me Do` is skipped once Lamina PDF sees form 8 a second time.
31
+
32
+ ## Data fields
33
+
34
+ - `object`: the form reached again.
35
+
36
+ The `location` is `object` (the form reached again).
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: "xref-repaired"
3
+ version: "0.2.0-alpha.3"
4
+ url: "https://docs.laminapdf.com/reference/codes/xref-repaired/"
5
+ ---
6
+
7
+ # xref-repaired
8
+
9
+ - Type: warning
10
+ - Kind: `input` (the input is malformed beyond what tolerance repairs)
11
+
12
+ ## What happened
13
+
14
+ The stored cross-reference data was unusable and was rebuilt by scanning the file.
15
+
16
+ ## Why
17
+
18
+ Edited, truncated or concatenated files often have stale offsets.
19
+
20
+ ## How to fix
21
+
22
+ Nothing, if the result is right. Incremental saves refuse a repaired base (`repaired-base`); save in full instead.
23
+
24
+ ## Example
25
+
26
+ ```text
27
+ startxref
28
+ 123456
29
+ %%EOF
30
+ ```
31
+
32
+ `startxref` points past the end of a file that was truncated and re-padded. Lamina PDF scans the file for `n g obj` headers, rebuilds the table, raises `xref-repaired` and opens normally. `save(SaveMode::Incremental)` is then refused with [`repaired-base`](repaired-base.md); `SaveMode::Auto` rewrites the file.
33
+
34
+ ## Data fields
35
+
36
+ None.
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: "xrefstm-ignored"
3
+ version: "0.2.0-alpha.3"
4
+ url: "https://docs.laminapdf.com/reference/codes/xrefstm-ignored/"
5
+ ---
6
+
7
+ # xrefstm-ignored
8
+
9
+ - Type: warning
10
+ - Kind: `input` (the input is malformed beyond what tolerance repairs)
11
+
12
+ ## What happened
13
+
14
+ A hybrid file's `/XRefStm` could not be read and was ignored.
15
+
16
+ ## Why
17
+
18
+ Hybrid files carry a classic xref table for old readers and an xref stream for objects in object streams. An editor that moved bytes without updating `/XRefStm`, or a damaged stream, leaves the stream unreadable.
19
+
20
+ ## How to fix
21
+
22
+ Nothing; the classic table is used.
23
+
24
+ ## Example
25
+
26
+ ```text
27
+ trailer << /Size 40 /Root 1 0 R /XRefStm 99999 >>
28
+ ```
29
+
30
+ A hybrid-reference file (ISO 32000-2 §7.5.8.4) points `/XRefStm` at an offset with no stream. Lamina PDF ignores it and reads the classic table; objects only the stream listed may be missing.
31
+
32
+ ## Data fields
33
+
34
+ `offset` (where `/XRefStm` points).
package/docs/llms.txt ADDED
@@ -0,0 +1,88 @@
1
+ # Lamina PDF
2
+
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
+
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.
6
+
7
+ - [Using Lamina PDF with coding agents](AGENTS.md)
8
+ - [What old names became](renames.json)
9
+
10
+ ## Start here
11
+
12
+ - [Lamina PDF](pages/index.md): Create, read, edit and save PDFs from Rust and TypeScript, with one Rust core that runs natively and as WebAssembly.
13
+ - [Install](pages/install.md): Install Lamina PDF from npm or crates.io, and find every published package.
14
+ - [Your first PDF](pages/start/first-pdf.md): Write hello.pdf from Node in five minutes.
15
+ - [Use Lamina PDF with coding agents](pages/start/coding-agents.md): Point a coding agent at the docs inside the installed package, so its answers match the version you use.
16
+
17
+ ## Your runtime
18
+
19
+ - [Browser and bundlers](pages/quick-start/browser.md): Load @laminapdf/sdk in a web page through Vite or another bundler.
20
+ - [Node](pages/quick-start/node.md): Generate a PDF from Node with @laminapdf/sdk.
21
+ - [Deno](pages/quick-start/deno.md): Use @laminapdf/sdk in Deno.
22
+ - [Bun](pages/quick-start/bun.md): Use @laminapdf/sdk in Bun.
23
+ - [Cloudflare Workers](pages/quick-start/workers.md): Generate PDFs per request in a Cloudflare Worker.
24
+ - [Rust](pages/quick-start/rust.md): Generate a PDF with the Lamina PDF crate.
25
+
26
+ ## Concepts
27
+
28
+ - [How Lamina PDF thinks about a PDF](pages/concepts/how-lamina-thinks.md): Bytes in and out, the same bytes every time, edits kept apart from the opened file, two ways to save, memory you free, three JavaScript modules.
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
+ - [Errors and warnings](pages/concepts/errors-and-warnings.md): One coded error shape on every surface, and warnings for what Lamina PDF repaired.
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
+
33
+ ## Create PDFs
34
+
35
+ - [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
+ - [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
+ - [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.
38
+ - [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
+ - [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
+
41
+ ## Read and edit PDFs
42
+
43
+ - [Edit a PDF](pages/guides/edit-a-pdf.md): Change an existing PDF in transactions you can undo, and replay edits stored as JSON.
44
+ - [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
+ - [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
+ - [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.
47
+
48
+ ## Production
49
+
50
+ - [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.
51
+
52
+ ## Recipes
53
+
54
+ - [Recipes](pages/recipes.md): Complete Lamina PDF programs, from one page of text to an archived invoice, each with its code and the PDF it writes.
55
+ - [Hello, world](pages/recipes/hello.md): One A4 page with a line of text in a standard 14 font, the smallest PDF Lamina PDF writes, in TypeScript and Rust.
56
+ - [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
+ - [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
+ - [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.
59
+ - [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
+ - [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
+ - [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.
62
+ - [A PDF/UA report](pages/recipes/pdf-ua-report.md): A one-page sales report a screen reader can follow, with headings, a table, a described chart and a link, checked against PDF/UA-1 as it's built.
63
+ - [A PDF/A archive](pages/recipes/pdf-a-archive.md): An order confirmation for long-term archiving, written as PDF/A-2b and as PDF/A-2u that is also PDF/UA-1, with an embedded font and a photo.
64
+ - [A PDF/A-3 invoice with XML](pages/recipes/pdf-a3-invoice-with-xml.md): A PDF/A-3b invoice that carries the same invoice as an attached XML file, for people to read and for software to process.
65
+ - [A 100-page report](pages/recipes/report.md): A 100-page A4 report with two embedded fonts and a table on every page, the document Lamina PDF times in each JavaScript runtime.
66
+ - [Open someone else's file](pages/recipes/open-untrusted.md): Open an uploaded PDF with an optional password and tighter limits, and get its page count and warnings, or the error, back as a value.
67
+ - [Save in a Web Worker](pages/recipes/web-worker-client.md): Open and save a PDF in a Web Worker, so a large file never freezes the page, with progress as it saves and a signal that stops the work.
68
+ - [A Cloudflare Worker](pages/recipes/cloudflare-worker.md): A Cloudflare Worker that returns a one-page letter per request, in a standard 14 font or a bundled one, and a 400 for a name the font can't draw.
69
+
70
+ ## Troubleshooting
71
+
72
+ - [Troubleshooting](pages/troubleshooting.md): The problems people hit with Lamina PDF, from a missing init() to a signed file that won't save, with the cause and the fix of each.
73
+
74
+ ## Reference
75
+
76
+ - [Rust API (rustdoc)](pages/reference/rust.md): Where to read the API documentation of the Lamina PDF crates.
77
+ - [Error and warning codes](pages/reference/codes.md): Every code Lamina PDF raises, generated from fixtures/codes.json when the site is built.
78
+ - [Stability policy](pages/reference/stability.md): What a Lamina PDF version number promises, and what stays the same in every version.
79
+ - [Changelog](pages/reference/changelog.md): What changed in each Lamina PDF release, newest first.
80
+ - [Glossary](pages/reference/glossary.md): The PDF and Lamina PDF terms the docs use, each in a sentence or two.
81
+
82
+ ## API reference
83
+
84
+ - [@laminapdf/sdk](api/README.md)
85
+
86
+ ## Optional
87
+
88
+ - [Error and warning codes](errors/README.md)
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: "What Lamina PDF writes and what it borrows"
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"
5
+ url: "https://docs.laminapdf.com/concepts/dependencies/"
6
+ ---
7
+
8
+ # What Lamina PDF writes and what it borrows
9
+
10
+ Lamina PDF writes the parts that decide a PDF's bytes, borrows the rest from permissive projects, and pins and checks everything it borrows.
11
+
12
+ Add `@laminapdf/viewer` to your app, and it downloads about 2 MB of WebAssembly from a project called EmbedPDF. That WebAssembly is PDFium, the C++ engine behind Chrome's PDF viewer. You may wonder why a Rust library ships someone else's C++, and what else comes along with it. Lamina PDF follows one rule: it writes the parts that decide what your PDF contains. It borrows the rest only from permissively licensed projects that do the job better, and it pins and checks every borrowed piece.
13
+
14
+ ## Lamina PDF writes the parts that decide your bytes
15
+
16
+ Lamina PDF's own Rust code reads, edits and saves your PDFs. Those parts take files from strangers, and they decide every byte of the file you save. A bug there corrupts documents or breaks signatures, so Lamina PDF owns them. Rust also keeps that code memory-safe while it reads damaged or hostile files. And because Lamina PDF wrote it, the same input gives the same bytes in a browser, on a server and inside a Cloudflare Worker.
17
+
18
+ ## It borrows the work others already do well
19
+
20
+ Fonts and text shaping are deep problems with good open-source answers, so Lamina PDF reuses them. `skrifa` reads font files, `subsetter` cuts them down to the glyphs you use, and HarfRust shapes Arabic, Hindi and other scripts. ICU4X finds line breaks, and `pdf-writer` writes PDF syntax. Each one is permissively licensed Rust that compiles to WebAssembly. Lamina PDF measured krilla, a complete PDF generator built on the same crates. But krilla can't add content to a file you opened, so Lamina PDF builds on the crates beneath it.
21
+
22
+ ## Drawing pages is the one job it hands to PDFium
23
+
24
+ Lamina PDF hands one big job to another project: turning pages into pixels. Real-world PDFs often break the specification, and PDFium draws them for everyone who opens a PDF in Chrome. Lamina PDF measured the alternative, hayro, a renderer written in Rust. It drew 91% of 2,196 test pages the same as PDFium or close to it, and most of the rest went wrong on fonts and annotations. A viewer that becomes an editor needs that fidelity from the start, so PDFium draws the pages. `@embedpdf/pdfium` is PDFium compiled to WebAssembly.
25
+
26
+ ## PDFium only draws, and only in a Web Worker
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.
29
+
30
+ ## You pay for PDFium only when you show pages
31
+
32
+ `@laminapdf/sdk`, the package that creates, reads and edits PDFs, depends only on `@laminapdf/wasm`, Lamina PDF's own WebAssembly. PDFium comes only with `@laminapdf/render-pdfium` and the viewer built on it. For pages as pixels on a server or in a Cloudflare Worker, `@laminapdf/render-hayro` is the lighter choice: pure Rust, with no C++, and a smaller download than PDFium. Every night, Lamina PDF's tests draw thousands of pages with both renderers, so hayro can take over once it matches PDFium.
33
+
34
+ ## Every dependency is permissively licensed
35
+
36
+ Lamina PDF is `MIT OR Apache-2.0`, so you can use it in a closed product or a paid service. That promise only holds if every dependency allows the same. So Lamina PDF accepts no GPL, AGPL or LGPL code in anything it ships, and a licence check enforces the rule on every change. MuPDF is a fine PDF engine, but it is AGPL, so Lamina PDF never uses it, in any form. Copyleft tools such as veraPDF run as separate programs in Lamina PDF's tests and are never shipped.
37
+
38
+ ## Everything borrowed is pinned and checked
39
+
40
+ A dependency can change under you, so Lamina PDF's lockfiles pin every one to an exact version. For PDFium, Lamina PDF goes further: the build checks the SHA-256 of `pdfium.wasm`, and any other file fails the build. `@embedpdf/pdfium` ships no notices for the libraries compiled into it, such as libpng, zlib and FreeType. So `@laminapdf/render-pdfium` includes a third-party notices file, and an app that bundles it ships that file too. An update to PDFium arrives as its own reviewed change, and the next release picks up its security fixes.
41
+
42
+ ## What this means for your app
43
+
44
+ You can build Lamina PDF into closed software, and `@laminapdf/sdk` brings no third-party engine with it. Add the viewer when you need to show pages, and ship PDFium's notices file with it. Next, see [how Lamina PDF thinks about a PDF](../../pages/concepts/how-lamina-thinks.md), or start with [your first PDF](../../pages/start/first-pdf.md).
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: "Errors and warnings"
3
+ description: "One coded error shape on every surface, and warnings for what Lamina PDF repaired."
4
+ version: "0.2.0-alpha.3"
5
+ url: "https://docs.laminapdf.com/concepts/errors-and-warnings/"
6
+ ---
7
+
8
+ # Errors and warnings
9
+
10
+ One coded error shape on every surface, and warnings for what Lamina PDF repaired.
11
+
12
+ Real PDFs are often damaged, so Lamina PDF separates a call that failed from one that worked around a problem. An error stops the call. A warning lets it finish and tells you what was repaired, dropped or approximated. Both carry a stable code your program can branch on.
13
+
14
+ ## Errors stop the call
15
+
16
+ In TypeScript an error is a `LaminaPdfError`, and in Rust it's a `laminapdf::Error`. Branch on its `code`, never on its `message`: `isLaminaPdfError(e, "wrong-password")` checks the code and narrows the type in one step.
17
+
18
+ ## Warnings say what was repaired
19
+
20
+ A warning means the call went ahead, but Lamina PDF had to repair, drop or approximate something in the file. Read them with `doc.warnings` in TypeScript or `doc.warnings()` in Rust. Show them to the user when the difference matters, such as a page that may not look the way its author intended.
21
+
22
+ ## Every surface has the same fields
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.
25
+
26
+ - **`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
+ - **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.
28
+
29
+ This example opens someone else's file and returns the error's code and hint as a value, instead of letting the error escape:
30
+
31
+ `packages/sdk/examples/open-untrusted.ts`:
32
+
33
+ ```ts
34
+ // Open bytes from someone else: an optional password, tighter limits than the defaults, and the
35
+ // outcome as a value rather than an exception. The example writes nothing: it returns what it found.
36
+ import { Document, isLaminaPdfError } from "@laminapdf/sdk";
37
+
38
+ const MiB = 1024 * 1024;
39
+ /** Limits for an upload endpoint: each decoded stream, and all of them together. */
40
+ const LIMITS = { maxStreamDecoded: 16 * MiB, maxDecodedTotal: 64 * MiB } as const;
41
+
42
+ /** What opening a file gave: its page count and warning codes, or why it didn't open. */
43
+ export type Opened =
44
+ | { readonly ok: true; readonly pages: number; readonly warnings: readonly string[] }
45
+ | { readonly ok: false; readonly code: string; readonly hint: string | undefined };
46
+
47
+ /** Opens `bytes`, with `password` if the file needs one, under {@link LIMITS}. Needs `init()`. */
48
+ export function openUntrusted(bytes: Uint8Array, password?: string): Opened {
49
+ try {
50
+ using doc = Document.open(bytes, { ...(password === undefined ? {} : { password }), limits: LIMITS });
51
+ // Repairs and dropped values are warnings: the file opened, but not exactly as written.
52
+ return { ok: true, pages: doc.pageCount, warnings: doc.warnings.map((w) => w.code) };
53
+ } catch (e) {
54
+ // `password-required`, `wrong-password`, `not-pdf`, `limit-exceeded`, …: a coded error whose
55
+ // message and hint never contain text from the file. Anything else is a bug: let it throw.
56
+ if (isLaminaPdfError(e)) return { ok: false, code: e.code, hint: e.hint };
57
+ throw e;
58
+ }
59
+ }
60
+ ```
61
+
62
+ The [error and warning codes](../../errors/README.md) list every code with its kind, a summary and a hint.
63
+
64
+ Next: make a PDF with [text and fonts](../../pages/guides/fonts-and-text.md).
@@ -0,0 +1,86 @@
1
+ ---
2
+ title: "How Lamina PDF thinks about a PDF"
3
+ description: "Bytes in and out, the same bytes every time, edits kept apart from the opened file, two ways to save, memory you free, three JavaScript modules."
4
+ version: "0.2.0-alpha.3"
5
+ url: "https://docs.laminapdf.com/concepts/how-lamina-thinks/"
6
+ ---
7
+
8
+ # How Lamina PDF thinks about a PDF
9
+
10
+ Bytes in and out, the same bytes every time, edits kept apart from the opened file, two ways to save, memory you free, three JavaScript modules.
11
+
12
+ The rest of the docs build on six ideas. The first two follow from one choice: Lamina PDF treats a PDF as bytes, which you give it and it gives back.
13
+
14
+ ## Bytes in, bytes out
15
+
16
+ Lamina PDF's core never touches the file system or the network, and it never reads the clock. Your app reads the file, hands Lamina PDF the bytes and stores whatever comes back. The only fetches are the ones you ask for, such as opening a remote file by range requests. That's why the same code runs in a browser, on a server and inside a Cloudflare Worker.
17
+
18
+ ## Same input, same bytes
19
+
20
+ Because Lamina PDF reads no clock, you pass in dates and file IDs yourself. It then writes the same bytes for the same input, on every run and every platform, so you can test, cache and compare its output byte for byte.
21
+
22
+ ## The file you opened never changes
23
+
24
+ When you open a document, Lamina PDF keeps its bytes exactly as they were. Every edit goes into an [overlay](../../pages/reference/glossary.md#overlay) on top of them. Reading the document reads the overlay first, so you see your edits; undo and redo move through them.
25
+
26
+ ## Two ways to save
27
+
28
+ A save writes the overlay out in one of two ways:
29
+
30
+ - **[Incremental save](../../pages/reference/glossary.md#incremental-save):** the original bytes, unchanged, followed by a new revision that holds your edits. Signatures over the original stay valid.
31
+ - **[Full rewrite](../../pages/reference/glossary.md#full-rewrite):** the whole file written again, smaller and tidier, but no longer the original bytes.
32
+
33
+ The default, `auto`, saves incrementally when it can. A signed file saves only incrementally, and a save fails if your edits break its signatures, unless you pass `invalidateSignatures: true`. [Save a PDF](../../pages/guides/save-a-pdf.md) has the details.
34
+
35
+ This example builds a document, opens its bytes, changes the title and saves incrementally. The saved file starts with the original bytes:
36
+
37
+ `packages/sdk/examples/generate-then-edit.ts`:
38
+
39
+ ```ts
40
+ // Generate a document, then open its bytes, edit them and save incrementally. The edit changes
41
+ // the Info dictionary in one transaction, and the incremental save keeps the generated bytes as
42
+ // they are, with one revision appended.
43
+ import { Builder, type BuilderOptions, Document, Font } from "@laminapdf/sdk";
44
+
45
+ /**
46
+ * The generated file followed by the edit's revision. Needs `init({ text: true })`.
47
+ *
48
+ * @param options - can fix the file ID, the producer and the creation date.
49
+ * @param editedAt - the modification date to record, as a PDF date string.
50
+ */
51
+ export function generateThenEdit(options: BuilderOptions = {}, editedAt?: string): Uint8Array<ArrayBuffer> {
52
+ return edit(generate(options), editedAt);
53
+ }
54
+
55
+ /** A one-page draft, saved (a new document is always saved as a full rewrite). */
56
+ export function generate(options: BuilderOptions = {}): Uint8Array<ArrayBuffer> {
57
+ using b = new Builder(options);
58
+ const page = b.page("A4");
59
+ page.surface().text("Draft report", { font: Font.standard("Helvetica"), size: 20, at: [72, 96] });
60
+ page.finish();
61
+ b.metadata({ title: "Draft report" });
62
+ using doc = b.finish();
63
+ return doc.save();
64
+ }
65
+
66
+ /** Opens `bytes`, edits the Info dictionary in one transaction (which `undo` could revert) and saves incrementally. */
67
+ function edit(bytes: Uint8Array, editedAt?: string): Uint8Array<ArrayBuffer> {
68
+ using doc = Document.open(bytes);
69
+ doc.transact((tx) => tx.setInfo({ title: "Final report", author: "Ada Lovelace" }, editedAt));
70
+ return doc.save({ mode: "incremental" });
71
+ }
72
+ ```
73
+
74
+ ## You free what you create
75
+
76
+ In JavaScript, documents and builders live in WebAssembly memory. The garbage collector frees them eventually, but late, so free each one when you're done: `using doc = …` frees it at the end of the block, and `doc.free()` frees it at once. A short script can skip this, but a long-running server shouldn't.
77
+
78
+ ## Three modules in JavaScript
79
+
80
+ In JavaScript, Lamina PDF is WebAssembly, split into three modules so a page downloads only what it uses:
81
+
82
+ - **Base:** open, read, edit and save; vector and image pages.
83
+ - **Extract:** everything in base, plus text extraction.
84
+ - **Text:** everything in base, plus fonts, shaped text and extraction.
85
+
86
+ `init()` loads the base module, and `init({ text: true })` or `init({ extract: true })` loads one of the others. Call `loadText()` or `loadExtract()` to add a module later, when a page first needs it. Rust has one crate, with features instead.
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: "Pages and coordinates"
3
+ description: "Points from the top-left corner of the page as it's displayed, y going down, and pages numbered from 0."
4
+ version: "0.2.0-alpha.3"
5
+ url: "https://docs.laminapdf.com/concepts/pages-and-coordinates/"
6
+ ---
7
+
8
+ # Pages and coordinates
9
+
10
+ Points from the top-left corner of the page as it's displayed, y going down, and pages numbered from 0.
11
+
12
+ Every position you pass Lamina PDF is in [page space](../../pages/reference/glossary.md#page-space): points measured from the top-left corner of the page, with y going down. It's the way a screen or a sheet of paper reads, so a number means the same thing in every part of the API.
13
+
14
+ ## Points
15
+
16
+ A point is 1/72 of an inch. An A4 page is about 595 × 842 points, and a US Letter page is 612 × 792. Some pages set a [user unit](../../pages/reference/glossary.md#user-unit), which scales the file's own units; Lamina PDF applies it, so a point is always 1/72 inch.
17
+
18
+ ## The top-left corner of the page you see
19
+
20
+ The origin is the top-left corner of the page as a viewer displays it: its visible area (its [crop box](../../pages/reference/glossary.md#crop-box)), turned the way the page is rotated. So `[72, 96]` is one inch from the left edge and 96 points from the top, whichever way the page is rotated in the file.
21
+
22
+ For text, the second number is the baseline, the line the letters sit on. Letters reach up from it, and descenders such as "g" and "p" hang below it.
23
+
24
+ This app places "Hello, world!" one inch from the top-left corner, with its baseline one text size lower:
25
+
26
+ `packages/sdk/examples/quick-start/node.ts`:
27
+
28
+ ```ts
29
+ // Builds a one-page PDF that says "Hello, world!" and writes it to hello.pdf, in Node.
30
+ import { writeFile } from "node:fs/promises";
31
+ import { Builder, type BuilderOptions, Font, init } from "@laminapdf/sdk";
32
+
33
+ /** The space between the page's edge and the text, in points (72 points = 1 inch). */
34
+ const MARGIN = 72;
35
+ /** The text's size in points; its baseline sits this far below the margin. */
36
+ const FONT_SIZE = 24;
37
+
38
+ /** Builds the page and hands its bytes to `save`, which writes hello.pdf unless you pass another `save` function. */
39
+ export async function hello(
40
+ save: (pdf: Uint8Array) => void | Promise<void> = (pdf) => writeFile("hello.pdf", pdf),
41
+ options: BuilderOptions = {},
42
+ ): Promise<void> {
43
+ await init({ text: true });
44
+ using builder = new Builder(options);
45
+ const page = builder.page("A4");
46
+ // Points from the page's top-left corner, y down; the text's baseline sits FONT_SIZE points below the margin.
47
+ page.surface().text("Hello, world!", {
48
+ font: Font.standard("Helvetica"),
49
+ size: FONT_SIZE,
50
+ at: [MARGIN, MARGIN + FONT_SIZE],
51
+ });
52
+ page.finish();
53
+ using doc = builder.finish();
54
+ await save(doc.save());
55
+ }
56
+
57
+ // `node hello.ts` runs it (Node 24.2 or newer); imported, it only exports `hello`.
58
+ if (import.meta.main) await hello();
59
+ ```
60
+
61
+ ## Pages count from 0
62
+
63
+ The first page is page 0 everywhere: `doc.page(0)`, a link's target, a page label's start.
64
+
65
+ ## PDF's own coordinates
66
+
67
+ Inside the file, PDF measures from the bottom-left corner with y going up, before rotation. That's [user space](../../pages/reference/glossary.md#user-space). Lamina PDF converts for you, so you only meet it in Rust, in names that contain `UserSpace` or `user_space`.