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

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 (139) hide show
  1. package/README.md +208 -2
  2. package/dist/api.d.ts +23 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +11 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/builder.d.ts +319 -0
  7. package/dist/builder.d.ts.map +1 -0
  8. package/dist/builder.js +540 -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 +241 -0
  15. package/dist/document.d.ts.map +1 -0
  16. package/dist/document.js +427 -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 +137 -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/font.d.ts +66 -0
  35. package/dist/font.d.ts.map +1 -0
  36. package/dist/font.js +103 -0
  37. package/dist/font.js.map +1 -0
  38. package/dist/generated/builder-enums.d.ts +29 -0
  39. package/dist/generated/builder-enums.d.ts.map +1 -0
  40. package/dist/generated/builder-enums.js +80 -0
  41. package/dist/generated/builder-enums.js.map +1 -0
  42. package/dist/generated/codes.d.ts +97 -0
  43. package/dist/generated/codes.d.ts.map +1 -0
  44. package/dist/generated/codes.js +453 -0
  45. package/dist/generated/codes.js.map +1 -0
  46. package/dist/generated/explain.d.ts +6 -0
  47. package/dist/generated/explain.d.ts.map +1 -0
  48. package/dist/generated/explain.js +138 -0
  49. package/dist/generated/explain.js.map +1 -0
  50. package/dist/index.d.ts +30 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +37 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/init.d.ts +80 -0
  55. package/dist/init.d.ts.map +1 -0
  56. package/dist/init.js +127 -0
  57. package/dist/init.js.map +1 -0
  58. package/dist/loader/fetch.d.ts +3 -0
  59. package/dist/loader/fetch.d.ts.map +1 -0
  60. package/dist/loader/fetch.js +2 -0
  61. package/dist/loader/fetch.js.map +1 -0
  62. package/dist/loader/node.d.ts +3 -0
  63. package/dist/loader/node.d.ts.map +1 -0
  64. package/dist/loader/node.js +9 -0
  65. package/dist/loader/node.js.map +1 -0
  66. package/dist/loader/workerd.d.ts +3 -0
  67. package/dist/loader/workerd.d.ts.map +1 -0
  68. package/dist/loader/workerd.js +15 -0
  69. package/dist/loader/workerd.js.map +1 -0
  70. package/dist/matrix.d.ts +16 -0
  71. package/dist/matrix.d.ts.map +1 -0
  72. package/dist/matrix.js +36 -0
  73. package/dist/matrix.js.map +1 -0
  74. package/dist/path.d.ts +34 -0
  75. package/dist/path.d.ts.map +1 -0
  76. package/dist/path.js +49 -0
  77. package/dist/path.js.map +1 -0
  78. package/dist/source/http.d.ts +36 -0
  79. package/dist/source/http.d.ts.map +1 -0
  80. package/dist/source/http.js +211 -0
  81. package/dist/source/http.js.map +1 -0
  82. package/dist/source/range.d.ts +70 -0
  83. package/dist/source/range.d.ts.map +1 -0
  84. package/dist/source/range.js +96 -0
  85. package/dist/source/range.js.map +1 -0
  86. package/dist/text.d.ts +90 -0
  87. package/dist/text.d.ts.map +1 -0
  88. package/dist/text.js +127 -0
  89. package/dist/text.js.map +1 -0
  90. package/dist/transaction.d.ts +36 -0
  91. package/dist/transaction.d.ts.map +1 -0
  92. package/dist/transaction.js +47 -0
  93. package/dist/transaction.js.map +1 -0
  94. package/dist/types.d.ts +79 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/types.js +2 -0
  97. package/dist/types.js.map +1 -0
  98. package/dist/version.d.ts +3 -0
  99. package/dist/version.d.ts.map +1 -0
  100. package/dist/version.js +6 -0
  101. package/dist/version.js.map +1 -0
  102. package/dist/worker/client.d.ts +87 -0
  103. package/dist/worker/client.d.ts.map +1 -0
  104. package/dist/worker/client.js +405 -0
  105. package/dist/worker/client.js.map +1 -0
  106. package/dist/worker/emitter.d.ts +12 -0
  107. package/dist/worker/emitter.d.ts.map +1 -0
  108. package/dist/worker/emitter.js +34 -0
  109. package/dist/worker/emitter.js.map +1 -0
  110. package/dist/worker/entry.d.ts +2 -0
  111. package/dist/worker/entry.d.ts.map +1 -0
  112. package/dist/worker/entry.js +4 -0
  113. package/dist/worker/entry.js.map +1 -0
  114. package/dist/worker/index.d.ts +7 -0
  115. package/dist/worker/index.d.ts.map +1 -0
  116. package/dist/worker/index.js +4 -0
  117. package/dist/worker/index.js.map +1 -0
  118. package/dist/worker/protocol.d.ts +82 -0
  119. package/dist/worker/protocol.d.ts.map +1 -0
  120. package/dist/worker/protocol.js +11 -0
  121. package/dist/worker/protocol.js.map +1 -0
  122. package/dist/worker/server.d.ts +51 -0
  123. package/dist/worker/server.d.ts.map +1 -0
  124. package/dist/worker/server.js +460 -0
  125. package/dist/worker/server.js.map +1 -0
  126. package/dist/worker/support.d.ts +39 -0
  127. package/dist/worker/support.d.ts.map +1 -0
  128. package/dist/worker/support.js +25 -0
  129. package/dist/worker/support.js.map +1 -0
  130. package/dist/worker/transfer.d.ts +3 -0
  131. package/dist/worker/transfer.d.ts.map +1 -0
  132. package/dist/worker/transfer.js +13 -0
  133. package/dist/worker/transfer.js.map +1 -0
  134. package/dist/worker/types.d.ts +43 -0
  135. package/dist/worker/types.d.ts.map +1 -0
  136. package/dist/worker/types.js +2 -0
  137. package/dist/worker/types.js.map +1 -0
  138. package/package.json +91 -3
  139. package/schemas/error.schema.json +288 -0
package/README.md CHANGED
@@ -1,3 +1,209 @@
1
- # Temporary Holding Version
1
+ # `@laminapdf/sdk`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Create, read, edit and save PDFs from TypeScript. Lamina PDF's Rust core runs as WebAssembly, so after one `await init()` the API is synchronous and the same in browsers, Node, Deno, Bun and Cloudflare Workers.
4
+
5
+ ```ts
6
+ import { Document, init } from "@laminapdf/sdk";
7
+
8
+ await init();
9
+ const doc = Document.open(bytes);
10
+ console.log(doc.pageCount);
11
+ ```
12
+
13
+ The package is ESM only. It isn't published to npm yet.
14
+
15
+ ## Quick start
16
+
17
+ ```ts
18
+ import { Builder, Document, Font, init } from "@laminapdf/sdk";
19
+
20
+ await init({ text: true }); // the base module, and the text module for fonts and text
21
+
22
+ // Generate
23
+ const b = new Builder({ producer: "my app" });
24
+ const page = b.page("A4");
25
+ page.surface().text("Hello, world!", { font: Font.standard("Helvetica"), size: 24, at: [72, 96] });
26
+ page.finish();
27
+ const bytes: Uint8Array = b.finish().save();
28
+
29
+ // Read and edit
30
+ const doc = Document.open(bytes);
31
+ doc.transact((tx) => tx.setInfo({ title: "Hello" })); // synchronous: collected ops are applied as one transaction
32
+ const edited = doc.save({ mode: "incremental" }); // the original bytes, then one appended revision
33
+ doc.free();
34
+ ```
35
+
36
+ Coordinates are in page space: points from the top-left of the displayed page, with y going down. A text run's `at[1]` is its baseline. Page indexes start at 0.
37
+
38
+ ## Two modules
39
+
40
+ | Module | gzip | What it can do |
41
+ | --- | ---: | --- |
42
+ | base (`init()`) | ≈ 373 KB | Open (passwords, limits, strict mode), read pages and Info, warnings, edit with ops (transactions, undo/redo), save (auto, incremental, full rewrite; save jobs); build vector and image pages with links, outline, page labels, metadata |
43
+ | extract (`init({ extract: true })` or `loadExtract()`) | ≈ 526 KB | Everything in base, plus text extraction (`page.text()`) |
44
+ | text (`init({ text: true })` or `loadText()`) | ≈ 1,009 KB | Everything in base, plus fonts (`Font.fromBytes`, the standard 14), shaped text runs and text boxes, and text extraction |
45
+
46
+ A page that never draws text never downloads the text module. A `Builder` is built in the text module when it is loaded at the time the builder is created (or with `new Builder({ text: true })`); drawing text on a base-module builder throws `text-module-not-loaded`.
47
+
48
+ ## Loading per runtime
49
+
50
+ `package.json` `exports` resolves one entry per runtime, each with its own loader (no environment sniffing):
51
+
52
+ | Condition | Entry | How the `.wasm` is loaded |
53
+ | --- | --- | --- |
54
+ | `workerd` | `dist/entry/workerd.js` | `import wasm from "@laminapdf/wasm/lamina_pdf_base.wasm"`: a `WebAssembly.Module` bundled with the Worker (both modules) |
55
+ | `deno`, `browser`, `default` | `dist/index.js` | `new URL("lamina_pdf_base.wasm", import.meta.url)` in the package's loader, fetched and compiled streaming; bundlers emit it as an asset |
56
+ | `node` (Node, Bun) | `dist/entry/node.js` | the file of `@laminapdf/wasm`, read as bytes |
57
+
58
+ The escape hatch is the input of `init`: a URL or string, a `Response` (or a promise of one), bytes (`ArrayBuffer`, `Uint8Array`) or a compiled `WebAssembly.Module`, for the base module (`init(source)` or `init({ module })`) and the text module (`init({ text: source })` or `loadText(source)`). `init` is idempotent and a failed load can be retried; naming a different source after a module is loaded (or loading) throws `already-initialized`.
59
+
60
+ **Vite:** exclude the package from dependency pre-bundling, so the `.wasm` files stay next to the JavaScript that loads them:
61
+
62
+ ```ts
63
+ // vite.config.ts
64
+ export default { optimizeDeps: { exclude: ["@laminapdf/sdk"] } };
65
+ ```
66
+
67
+ ## Passwords, fonts and images
68
+
69
+ - A password is tried as given, then (after `wrong-password`) in its NFKC form, so older passwords reach the core unchanged and AES-256 ones match SASLprep's normalisation.
70
+ - Equal fonts are one PDF font per builder: standard 14 fonts by name, others by their bytes, however many `Font` objects name them.
71
+ - `Image` copies its input and decodes it in the module of first use; bad data surfaces there (or when `width`/`height` is read).
72
+
73
+ ## Tagged PDF
74
+
75
+ `new Builder({ tagged: true })` tags a document before anything is drawn; a page that uses `tag` or `artifact` tags it either way. Structure is drawn with callbacks, as paths and transactions are:
76
+
77
+ ```ts
78
+ s.artifact("pagination", (s) => s.text("Page 1", { font, size: 9, at: [520, 810] }));
79
+ s.text("Invoice 42", { font, size: 24, at: [56, 80], tag: "H1" });
80
+ s.tag("Table", (s) => {
81
+ s.tag("TR", (s) => {
82
+ s.text("Item", { font, size: 11, at: [56, 160], tag: { type: "TH", scope: "column" } });
83
+ });
84
+ });
85
+ s.image(logo, [440, 56, 100, 40], "The Acme logo"); // a Figure with /Alt
86
+ s.text("Pay online", { font, size: 11, at: [56, 320], link: { target, contents: "Pay invoice 42 online" }, tag: "P" });
87
+ ```
88
+
89
+ `tag` takes a standard type (`TagName`) or a `TagSpec` (`{ type, role, alt, actualText, lang, expansion, scope }`; a custom `type` needs the standard `role` it maps to); text and text boxes take a `tag` option; a link inside an element becomes a `Link` element holding its annotation. Elements and artifacts the callback leaves open end with it, also when it throws. Elements are per page.
90
+
91
+ ## Errors and warnings
92
+
93
+ Every error is a `LaminaPdfError`. Its fields are `code` (one of the `ErrorCode` union), `kind`, `message`, `hint`, `didYouMean`, `location`, `data` (the only place document text appears) and `docsUrl`, a link to the code's page in the [error reference](https://docs.laminapdf.com/reference/codes/). `toJSON()` gives the plain object back.
94
+
95
+ ```ts
96
+ try {
97
+ Document.open(bytes, { password });
98
+ } catch (e) {
99
+ if (isLaminaPdfError(e, "wrong-password")) askAgain();
100
+ else throw e;
101
+ }
102
+ ```
103
+
104
+ `isLaminaPdfError(e, code)` narrows: inside the `if`, `e.code` has the type `"wrong-password"`. `LaminaPdfError<C>` is generic over the `ErrorCode` union, so a `switch (e.code)` with a `never` default is checked for exhaustiveness, and stops compiling when a new code arrives until you handle it. `toJSON()` validates against the `laminapdf.error/1` JSON Schema, shipped as `@laminapdf/sdk/schemas/error.schema.json`.
105
+
106
+ `doc.warnings` lists what the reader repaired, as `LaminaPdfWarning` objects of the same shape (without `didYouMean`), typed by `WarningCode`.
107
+
108
+ `@laminapdf/sdk/explain` is a separate entry, kept out of the main bundle: `explain(code)` returns the code's page as Markdown (what happened, why, how to fix, an example, the `data` fields), with `KINDS`, `HINTS` and `docsUrl(code)` for every code.
109
+
110
+ ```ts
111
+ import { explain } from "@laminapdf/sdk/explain";
112
+ if (isLaminaPdfError(e)) console.error(e.message, e.hint, explain(e.code));
113
+ ```
114
+
115
+ ## Extracting text
116
+
117
+ `page.text()` returns a page's text in four forms:
118
+
119
+ - `lines`: the lines in content order, trimmed.
120
+ - `text()`: the lines joined with `\n`.
121
+ - `runs`: font, size, direction, marked-content ID, `ActualText`, visibility and bounds; `glyphs()` gives each glyph's text and quad.
122
+ - `buffers`: every glyph's quad in one `Float32Array` (8 numbers per glyph, in page space) and the glyph text with UTF-16 offsets, ready to transfer from a Web Worker.
123
+
124
+ Documents open in the richest module loaded: text, then extract, then base. Load the extract or text module before you open or build a document whose text you need; otherwise `page.text()` throws `extract-module-not-loaded`. `doc.canExtractText` tells which module a document is in.
125
+
126
+ The text module also extracts text. Once it is loaded, Lamina PDF doesn't load the extract module, and documents live in the text module's memory. In a Cloudflare Worker, pass the module yourself: then only a Cloudflare Worker that extracts text bundles it: `import extract from "@laminapdf/wasm/lamina_pdf_extract.wasm"; await loadExtract(extract);`.
127
+
128
+ ```ts
129
+ await init({ extract: true });
130
+ const doc = Document.open(bytes);
131
+ const text = doc.page(0).text({ skipInvisible: true });
132
+ console.log(text.text());
133
+ ```
134
+
135
+ ## Remote and large files
136
+
137
+ `Document.openRange(source, options)` opens a file whose bytes are fetched range by range, so a remote PDF opens without downloading it whole. Only what the open needs is fetched: the end of the file (the xref), the catalog, the page tree. The document stays synchronous; a call that needs bytes not fetched yet throws `data-pending` with `e.ranges`, and `await doc.ensure(() => …)` fetches them and calls again.
138
+
139
+ ```ts
140
+ const doc = await Document.openRange(httpRangeSource("https://example.com/big.pdf"));
141
+ const pages = await doc.ensure(() => doc.pages);
142
+ const bytes = await doc.ensure(() => doc.save({ mode: "fullRewrite" })); // fetches the rest
143
+ ```
144
+
145
+ - **`httpRangeSource(url, { headers, credentials, signal, blockSize })`:** the first request asks for the last 64 KiB with `Range: bytes=-65536`, which also gives the size. Later requests are aligned to 16 KiB blocks and send `If-Range` with the first strong `ETag` (else `Last-Modified`); a different `ETag`, `Last-Modified` or size fails with `source-changed`. A server without either validator can't be checked: serve one. A server that answers `200` (no range support) is read from that one full download. HTTP errors are `fetch-failed` with `data.status`; the URL never appears in an error.
146
+ - **CORS:** a `Range` header makes a cross-origin request preflighted. The server must answer with `Access-Control-Allow-Headers: Range` and expose `Content-Range`, `Content-Length` and `ETag` (`Access-Control-Expose-Headers`). It must not compress the response: `Content-Encoding` breaks byte ranges.
147
+ - **`callbackSource(size, read)`:** any other random-access input (a `Blob`'s `slice`, a file handle, an IPC call).
148
+ - **Options:** `signal` (for the open; aborting rejects and cancels its requests in flight; `ensure(f, { signal })` takes its own), `blockSize`, `readahead`, `budget` (the most bytes the document may hold; more is `source-budget-exceeded`) and `maxRounds`.
149
+ - **Off the main thread:** each `ensure` call can take several round trips. `client.openUrl` in a Web Worker hides the loop behind its async API (see below).
150
+ - **Large local files in Rust:** the `laminapdf-source` crate's `FileSource` (positioned reads) or, for files nothing changes, `MmapSource`; its rustdoc describes both.
151
+
152
+ ## Off the main thread: `@laminapdf/sdk/worker`
153
+
154
+ The API is synchronous, so a large file opened on the main thread blocks the page. `@laminapdf/sdk/worker` runs the same API in a Web Worker and gives you async twins of `Document` and its pages.
155
+
156
+ ```ts
157
+ import { connect } from "@laminapdf/sdk/worker";
158
+
159
+ const client = await connect(); // starts the Web Worker, checks its version, calls init() there
160
+ await using doc = await client.open(bytes); // copied; { transfer: true } moves it instead
161
+ console.log(await doc.pageCount());
162
+ const page = await doc.page(0);
163
+ const text = await page.text(); // a PageText, rebuilt from the transferred arrays (after client.loadExtract())
164
+ const updated = await doc.save({ mode: "incremental" }, { signal, onProgress: (p) => bar(p) });
165
+ ```
166
+
167
+ - **Same names, async:** every served member of `Document` and `PageRef` is a method of the same name returning a `Promise`. Getters become methods: `await doc.pageCount()`. A page is a remote handle too.
168
+ - **Not served:**
169
+ - `transact`: a callback can't cross to the Web Worker. Use `apply(ops)` instead.
170
+ - `saveJob`: the remote `save` is a stepped job already.
171
+ - `ensure`: the Web Worker fetches a range document's bytes itself.
172
+ - `free`: use `close()` or `await using`.
173
+ - `Builder`: its callbacks (`path`, `tag`) can't cross either. Build on the main thread or in your own Web Worker.
174
+
175
+ - **Remote files:** `client.openUrl(url, options)` opens a file by range requests in the Web Worker; every call fetches what it needs first. Its options are `httpRangeSource`'s, without a custom `fetch` (a function can't be sent to the Web Worker), and `openRange`'s (`budget`, `readahead`, `maxRounds`). Aborting the call's `signal` also cancels the fetches in flight.
176
+ - **Cancellation:** pass `signal` to any call. An aborted call rejects at once with `LaminaPdfError` `cancelled`, whose `cause` is the signal's reason, and a late answer is dropped.
177
+ - **Not started yet:** the call never runs.
178
+ - **`save` / `saveWithReport`:** they run as stepped jobs and stop at the next step. The document stays usable.
179
+ - **Every other call:** one synchronous call in the Web Worker, so it can't be stopped midway (`open` included). `client.terminate()` is the hard stop.
180
+ - **Transfers:** `save()` bytes and page text arrays come back transferred. Inputs are copied unless you pass `transfer: true`, which detaches your buffer.
181
+ - **Errors:** errors are `LaminaPdfError` on the main thread, with every field. If the Web Worker crashes (an uncaught error, a WebAssembly trap, out of memory), pending calls reject with `worker-crashed` and `client.on("crashed", …)` fires. `client.restart()` starts a new Web Worker. Calls made while it starts wait for it, and the old Web Worker's handles reject with `disposed` (their `close()` does nothing). `terminate()` doesn't fire `crashed`. There's no heartbeat, so a long call is not a crash.
182
+ - **Unsendable parameters:** a parameter the Web Worker can't receive (a function) rejects with `invalid-argument`, as do unknown methods. With `transfer: true`, only a buffer the input covers whole moves; a subarray or a `SharedArrayBuffer` view is copied. An error inside the Web Worker that isn't Lamina PDF's is `worker-failed` (internal: a bug to report).
183
+ - **`init`:** `connect({ init })` takes what can be sent to a Web Worker: a URL (string or `URL`, resolved against the page), bytes or a `WebAssembly.Module`, alone or as `{ module, text, extract }`. A `Response` can't cross.
184
+ - **Version handshake:** on connect, the Web Worker and the client compare their protocol and package versions. A Web Worker from another build rejects `connect()` with `worker-version-mismatch`.
185
+ - **Bundlers:** `connect()` contains the literal `new Worker(new URL("./entry.js", import.meta.url), { type: "module" })`, which Vite and webpack bundle with no config. In Vite, keep the package out of pre-bundling (`optimizeDeps: { exclude: ["@laminapdf/sdk"] }`), as for the main entry.
186
+ - **CSP or your own hosting:** pass `connect({ worker: () => new Worker(url, { type: "module" }) })`. A factory, so that `restart()` can make a new one.
187
+ - **Runtimes:** browsers (Chromium, Firefox, WebKit), and Deno and Bun Web Workers (smoke-tested). Node's `worker_threads` isn't a web `Worker` and isn't supported.
188
+ - **Extending the Web Worker:** `@laminapdf/sdk/worker/server`'s `serve({ methods })` serves the same protocol with more methods in the same Web Worker. `@laminapdf/viewer` adds its render methods this way.
189
+ - The page calls them with `client.request(method, params, { priority, key, signal })`.
190
+ - The Web Worker runs the highest `priority` first, and runs calls with the same `key` once. Each caller still gets its own answer: an extension method's `reply(result)` builds one per caller, so each can be given its own transferables.
191
+ - `emit(name, data)` in the Web Worker reaches `client.on("event", …)`.
192
+ - `connect({ onDiscard })` sees the answers of calls already rejected. By default it closes the `ImageBitmap`s in them.
193
+ - `serve({ methods, saveBudget })` sets how many work units each step of a save takes (20,000 by default). A smaller budget answers a cancel sooner and reports progress more often, at some cost in speed.
194
+ - `workerStats()` in the Web Worker reports the calls started, the handles the page holds and the calls queued. A handle the page never frees keeps its document's WebAssembly memory alive, so a growing count finds the `RemoteDocument` an app forgot to close.
195
+ - `Emitter`, from `@laminapdf/sdk/worker`, is the typed event emitter the client uses, for a package that wraps it: `on(event, listener)` returns a function that stops listening, and a listener that throws doesn't stop the others.
196
+
197
+ ## Memory
198
+
199
+ Documents, builders, pages and images live in WebAssembly memory. `doc.free()` (or `using doc = Document.open(…)`) frees a document at once; `page.finish()` and `builder.finish()` free their own side; the garbage collector frees anything you don't release, through a `FinalizationRegistry`. `wasmMemory()` reports each module's memory size.
200
+
201
+ ## Examples
202
+
203
+ The [examples](https://docs.laminapdf.com/examples/) are `hello`, `invoice`, `multilingual`, `images-and-vectors`, `links-and-outlines` and `generate-then-edit`, plus `report`, 100 pages with two embedded fonts. Each produces the same bytes as its Rust twin.
204
+
205
+ A Cloudflare Worker example generates a PDF per request: `/?name=Ada` returns a letter in Helvetica, or a 400 with the error as JSON for a name it can't draw, and `/report` returns the report. The [Cloudflare Workers quick start](https://docs.laminapdf.com/quick-start/workers/) shows it and how to run it.
206
+
207
+ ## Working on this package
208
+
209
+ How the package is built and tested in every runtime is in `CONTRIBUTING.md`, next to this README in the repository.
package/dist/api.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ export type { ArtifactKind, BlendMode, BuilderOptions, FillRule, LineCap, LineJoin, PageSizeName, StrokeStyle, TableScope, Tag, TagName, TagSpec, TextBoxOptions, TextOptions, } from "./builder.js";
2
+ export { Builder, PAGE_SIZES, Page, PendingPath, Surface, TAG_NAMES } from "./builder.js";
3
+ export { Document, PageRef, SaveJob } from "./document.js";
4
+ export type { Diagnostic, ErrorKind, LaminaPdfWarning, Location } from "./errors.js";
5
+ export { isLaminaPdfError, LaminaPdfError } from "./errors.js";
6
+ export type { FontInfo, Standard14 } from "./font.js";
7
+ export { Font, Image } from "./font.js";
8
+ export type { ErrorCode, LimitName, WarningCode } from "./generated/codes.js";
9
+ export type { InitOptions, WasmMemory, WasmSource } from "./init.js";
10
+ export { isExtractLoaded, isInitialized, isTextLoaded, wasmMemory } from "./init.js";
11
+ export type { Transform } from "./matrix.js";
12
+ export { Matrix } from "./matrix.js";
13
+ export type { PathBuilder } from "./path.js";
14
+ export type { HttpRangeOptions } from "./source/http.js";
15
+ export { httpRangeSource } from "./source/http.js";
16
+ export type { ByteRange, RangeOptions, RangeSource } from "./source/range.js";
17
+ export { callbackSource } from "./source/range.js";
18
+ export type { GlyphQuad, QuadPoint, TextGlyph, TextOptions as PageTextOptions } from "./text.js";
19
+ export { PageText, TextRun as PageTextRun } from "./text.js";
20
+ export type { InfoPatch, Rotation } from "./transaction.js";
21
+ export { Transaction } from "./transaction.js";
22
+ export type { AfRelationship, Align, AttachmentOptions, BoxRect, BuildOptions, Color, Direction, DocumentInfo, Edited, Fit, Limits, LineBox, LinkTarget, Metadata, Op, OpenOptions, OpLog, OutlineEntry, Overflow, PageInfo, PageLabel, Point, Profile, Progress, Rect, RenderMode, SaveOptions, SaveReport, TextLayout, TextRunInfo, UndoOutcome, ViewerPreferences, } from "./types.js";
23
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,UAAU,EACV,GAAG,EACH,OAAO,EACP,OAAO,EACP,cAAc,EACd,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC3D,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACxC,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9E,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACrF,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,WAAW,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7D,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EACV,cAAc,EACd,KAAK,EACL,iBAAiB,EACjB,OAAO,EACP,YAAY,EACZ,KAAK,EACL,SAAS,EACT,YAAY,EACZ,MAAM,EACN,GAAG,EACH,MAAM,EACN,OAAO,EACP,UAAU,EACV,QAAQ,EACR,EAAE,EACF,WAAW,EACX,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,KAAK,EACL,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
package/dist/api.js ADDED
@@ -0,0 +1,11 @@
1
+ export { Builder, PAGE_SIZES, Page, PendingPath, Surface, TAG_NAMES } from "./builder.js";
2
+ export { Document, PageRef, SaveJob } from "./document.js";
3
+ export { isLaminaPdfError, LaminaPdfError } from "./errors.js";
4
+ export { Font, Image } from "./font.js";
5
+ export { isExtractLoaded, isInitialized, isTextLoaded, wasmMemory } from "./init.js";
6
+ export { Matrix } from "./matrix.js";
7
+ export { httpRangeSource } from "./source/http.js";
8
+ export { callbackSource } from "./source/range.js";
9
+ export { PageText, TextRun as PageTextRun } from "./text.js";
10
+ export { Transaction } from "./transaction.js";
11
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE3D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAGxC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAErF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,319 @@
1
+ import type { WasmPageBuilder as TextPageBuilder, WasmFont } from "@laminapdf/wasm/text";
2
+ import { Document } from "./document.js";
3
+ import type { Font, FontInfo, Image } from "./font.js";
4
+ import { type ArtifactKind, type BlendMode, type FillRule, type LineCap, type LineJoin, type TableScope, type TagName } from "./generated/builder-enums.js";
5
+ import { type BaseGlue, type TextGlue } from "./init.js";
6
+ import type { Transform } from "./matrix.js";
7
+ import { type PathBuilder } from "./path.js";
8
+ import type { Align, AttachmentOptions, BuildOptions, Color, Direction, Fit, LinkTarget, Metadata, OutlineEntry, Overflow, PageLabel, Point, Rect, RenderMode, TextLayout, TextRunInfo, ViewerPreferences } from "./types.js";
9
+ /** Named page sizes (ISO 216 sizes from millimetres, as the Rust `PageSize` computes them). */
10
+ export type PageSizeName = "A0" | "A1" | "A2" | "A3" | "A4" | "A5" | "A6" | "Letter" | "Legal" | "Tabloid";
11
+ /** Each named size in points, width × height. */
12
+ export declare const PAGE_SIZES: Readonly<Record<PageSizeName, readonly [width: number, height: number]>>;
13
+ /** Options for a new {@link Builder}. */
14
+ export interface BuilderOptions extends Omit<BuildOptions, "id"> {
15
+ /** `/ID[0]`: 16 bytes, as 32 hex digits or a `Uint8Array` (default: derived from the content). */
16
+ readonly id?: string | Uint8Array;
17
+ /**
18
+ * Build in the text module (fonts and text). Default: when it is loaded. `true` without the
19
+ * text module loaded throws `text-module-not-loaded`.
20
+ */
21
+ readonly text?: boolean;
22
+ }
23
+ /** How strokes are drawn. */
24
+ export interface StrokeStyle {
25
+ /** Line width in points (default 1). */
26
+ readonly width?: number;
27
+ /** Line ends (default `butt`). */
28
+ readonly cap?: LineCap;
29
+ /** Corners (default `miter`). */
30
+ readonly join?: LineJoin;
31
+ /** Miter limit (default 10). */
32
+ readonly miterLimit?: number;
33
+ /** Dash pattern in points (default: solid). */
34
+ readonly dash?: readonly number[];
35
+ /** Where the dash pattern starts (default 0). */
36
+ readonly dashPhase?: number;
37
+ }
38
+ export type { ArtifactKind, BlendMode, FillRule, LineCap, LineJoin, TableScope, TagName, } from "./generated/builder-enums.js";
39
+ export { TAG_NAMES } from "./generated/builder-enums.js";
40
+ /** A structure element with attributes; `type` may be a custom name when `role` is given. */
41
+ export interface TagSpec {
42
+ /** A standard type, or a custom name written with a `RoleMap` entry to `role`. */
43
+ readonly type: TagName | (string & {});
44
+ /** The standard type a custom `type` stands for. */
45
+ readonly role?: TagName;
46
+ /** `/Alt`: alternate text (a `Figure` needs it). */
47
+ readonly alt?: string;
48
+ /** `/ActualText`: the exact text the content stands for. */
49
+ readonly actualText?: string;
50
+ /** `/Lang`: the element's language (BCP 47). */
51
+ readonly lang?: string;
52
+ /** `/E`: the expansion of an abbreviation. */
53
+ readonly expansion?: string;
54
+ /** `/Scope` of a `TH`. */
55
+ readonly scope?: TableScope;
56
+ }
57
+ /** A structure element: a type, or a type with attributes. */
58
+ export type Tag = TagName | TagSpec;
59
+ /** Options of {@link Surface.text}. */
60
+ export interface TextOptions {
61
+ /** The font (needs the text module). */
62
+ readonly font: Font;
63
+ /** Size in points. */
64
+ readonly size: number;
65
+ /** Where the first line starts: `x`, and `y` is the baseline (ADR 0027 §5). */
66
+ readonly at: Point;
67
+ /** Fill colour. */
68
+ readonly fill?: Color;
69
+ /** Rendering mode (`invisible` for an OCR layer). */
70
+ readonly renderMode?: RenderMode;
71
+ /** A link over the run. */
72
+ readonly link?: {
73
+ readonly target: LinkTarget;
74
+ readonly contents?: string;
75
+ };
76
+ /** OpenType features (`liga=0`, `smcp`). */
77
+ readonly features?: readonly string[];
78
+ /** Language (BCP 47). */
79
+ readonly language?: string;
80
+ /** Paragraph direction (default: from the first strong character). */
81
+ readonly direction?: Direction;
82
+ /** The structure element the run is (as drawing it inside {@link Surface.tag}). */
83
+ readonly tag?: Tag;
84
+ }
85
+ /** Options of {@link Surface.textBox}. */
86
+ export interface TextBoxOptions {
87
+ /** The font (needs the text module). */
88
+ readonly font: Font;
89
+ /** Size in points. */
90
+ readonly size: number;
91
+ /** The box the lines are broken into. */
92
+ readonly box: Rect;
93
+ /** Line alignment (default `start`). */
94
+ readonly align?: Align;
95
+ /** Line height as a factor of the size (default 1.2). */
96
+ readonly lineHeight?: number;
97
+ /** What happens to text that doesn't fit (default `clip`; `error` throws `text-overflow`). */
98
+ readonly overflow?: Overflow;
99
+ /** Paragraph direction. */
100
+ readonly direction?: Direction;
101
+ /** Language (BCP 47). */
102
+ readonly language?: string;
103
+ /** OpenType features. */
104
+ readonly features?: readonly string[];
105
+ /** The structure element the box is (as drawing it inside {@link Surface.tag}). */
106
+ readonly tag?: Tag;
107
+ }
108
+ /** The raw page of a {@link Page}: freed when the page finishes, `builder-finished` afterwards. */
109
+ declare class LivePage {
110
+ #private;
111
+ constructor(raw: TextPageBuilder, onFree: (page: LivePage) => void);
112
+ get(): TextPageBuilder;
113
+ free(): void;
114
+ }
115
+ /** A path waiting to be painted: fill it, stroke it, both, or clip to it. */
116
+ export declare class PendingPath {
117
+ #private;
118
+ /** @internal */
119
+ constructor(surface: Surface, page: LivePage, path: Float64Array);
120
+ /** Fills the path with the fill colour. @returns the surface. */
121
+ fill(rule?: FillRule): Surface;
122
+ /** Strokes the path with the stroke colour and `style`. @returns the surface. */
123
+ stroke(style?: StrokeStyle): Surface;
124
+ /** Fills, then strokes the path. @returns the surface. */
125
+ fillStroke(rule?: FillRule, style?: StrokeStyle): Surface;
126
+ /** Clips what is drawn next to the path, until the next `restore`. @returns the surface. */
127
+ clip(rule?: FillRule): Surface;
128
+ }
129
+ /**
130
+ * What a page is drawn with. Methods that set state return the surface, so calls chain; invalid
131
+ * geometry is reported by {@link Page.finish} (`invalid-geometry`).
132
+ */
133
+ export declare class Surface {
134
+ #private;
135
+ /** @internal */
136
+ constructor(builder: Builder, page: LivePage);
137
+ /** Saves the graphics state (`q`). */
138
+ save(): this;
139
+ /** Restores the graphics state (`Q`). */
140
+ restore(): this;
141
+ /** Applies `matrix` (page space) to what is drawn next. See {@link Matrix}. */
142
+ transform(matrix: Transform): this;
143
+ /** The colour fills (and text) use. */
144
+ fillColor(color: Color): this;
145
+ /** The colour strokes use. */
146
+ strokeColor(color: Color): this;
147
+ /** Fill and stroke opacity, 0 to 1. */
148
+ opacity(fill: number, stroke: number): this;
149
+ /** The blend mode. */
150
+ blendMode(mode: BlendMode): this;
151
+ /** @internal The stroke style the next stroke uses. */
152
+ strokeStyle(style: StrokeStyle): void;
153
+ /**
154
+ * A path, built by `build`, to paint.
155
+ *
156
+ * @example
157
+ * ```ts
158
+ * surface.path((p) => p.moveTo(56, 590).lineTo(539, 590)).stroke({ width: 0.5 });
159
+ * ```
160
+ */
161
+ path(build: (p: PathBuilder) => void): PendingPath;
162
+ /**
163
+ * Draws `image` scaled into `rect`; with `alt`, as a `Figure` structure element with that
164
+ * alternate text.
165
+ */
166
+ image(image: Image, rect: Rect, alt?: string): this;
167
+ /**
168
+ * Draws what `draw` draws inside the structure element `tag`: its text, paths and images
169
+ * become the element's content, elements opened inside it its children, links its `Link`
170
+ * children, in reading order. Elements and artifacts `draw` leaves open end with it, also when
171
+ * it throws. A page using an element makes the document tagged.
172
+ *
173
+ * @example
174
+ * ```ts
175
+ * s.tag("Sect", (s) => {
176
+ * s.text("Results", { font, size: 18, at: [56, 96], tag: "H1" });
177
+ * s.tag({ type: "P", lang: "en-GB" }, (s) => s.textBox(summary, { font, size: 11, box }));
178
+ * });
179
+ * ```
180
+ * @throws {@link LaminaPdfError} `invalid-argument` for an unknown type without a `role`.
181
+ */
182
+ tag(tag: Tag, draw: (s: this) => void): this;
183
+ /**
184
+ * Draws what `draw` draws as an artifact: decoration, running heads and footers, backgrounds;
185
+ * content outside the structure tree.
186
+ */
187
+ artifact(kind: ArtifactKind, draw: (s: this) => void): this;
188
+ /** A link annotation over `rect`, with `contents` as its alternate text. */
189
+ link(rect: Rect, target: LinkTarget, contents?: string): this;
190
+ /**
191
+ * Draws `text`: shaped, bidi-resolved, one line per line break (needs the text module).
192
+ *
193
+ * @returns what the run measures.
194
+ * @throws {@link LaminaPdfError} `text-module-not-loaded`, `missing-glyph`, `font-not-shapable`, …
195
+ */
196
+ text(text: string, options: TextOptions): TextRunInfo;
197
+ /**
198
+ * Lays `text` out in `options.box`, breaking lines at Unicode line-break opportunities.
199
+ *
200
+ * @returns the lines drawn and where the overflow starts (UTF-16 offsets).
201
+ * @throws {@link LaminaPdfError} as {@link Surface.text}; `text-overflow` with `overflow: "error"`.
202
+ */
203
+ textBox(text: string, options: TextBoxOptions): TextLayout;
204
+ }
205
+ /** A page being drawn: its boxes and rotation, its {@link Surface}, then {@link Page.finish}. */
206
+ export declare class Page {
207
+ #private;
208
+ /** @internal */
209
+ constructor(builder: Builder, page: LivePage);
210
+ /** What the page is drawn with (the same object on every call). */
211
+ surface(): Surface;
212
+ /** `/Rotate`: 0, 90, 180 or 270 degrees. */
213
+ rotate(degrees: 0 | 90 | 180 | 270): this;
214
+ /** `/UserUnit`, for pages larger than 14,400 units. */
215
+ userUnit(unit: number): this;
216
+ /** `/CropBox` (the visible region), in the media box's page space. */
217
+ cropBox(rect: Rect): this;
218
+ /** `/BleedBox`. */
219
+ bleedBox(rect: Rect): this;
220
+ /** `/TrimBox`. */
221
+ trimBox(rect: Rect): this;
222
+ /** `/ArtBox`. */
223
+ artBox(rect: Rect): this;
224
+ /**
225
+ * Writes the page into its builder and frees the page's WASM side; the page takes no more
226
+ * drawing afterwards (`builder-finished`).
227
+ *
228
+ * @returns the page's ID.
229
+ * @throws {@link LaminaPdfError} `invalid-geometry`, `builder-finished`.
230
+ */
231
+ finish(): string;
232
+ /** Drops the page without writing it (frees its WASM side). */
233
+ free(): void;
234
+ }
235
+ /**
236
+ * Builds a new document: pages, navigation and metadata; {@link Builder.finish} returns a
237
+ * {@link Document} to save. Created in the text module when it is loaded (or `text: true`),
238
+ * else in the reading module (text, extract, then base; vector and image pages only).
239
+ *
240
+ * @example
241
+ * ```ts
242
+ * await init({ text: true });
243
+ * const b = new Builder({ producer: "my app" });
244
+ * const page = b.page("A4");
245
+ * page.surface().text("Hello, world!", { font: Font.standard("Helvetica"), size: 24, at: [72, 96] });
246
+ * page.finish();
247
+ * const bytes = b.finish().save();
248
+ * ```
249
+ */
250
+ export declare class Builder {
251
+ #private;
252
+ /** @internal The module the document is built in. */
253
+ readonly glue: BaseGlue | TextGlue;
254
+ /**
255
+ * @param options - version, file ID, producer, creation date, compression, tagging,
256
+ * conformance `profiles`; `text`.
257
+ * @throws {@link LaminaPdfError} `not-initialized`, `text-module-not-loaded`; `unknown-option`.
258
+ */
259
+ constructor(options?: BuilderOptions);
260
+ /** As `new Builder(options)`. */
261
+ static create(options?: BuilderOptions): Builder;
262
+ /** Whether this builder draws in the text module (fonts and text). */
263
+ get hasText(): boolean;
264
+ /** A new page of a named size or `[width, height]` in points. */
265
+ page(size?: PageSizeName | readonly [width: number, height: number]): Page;
266
+ /**
267
+ * Registers `font` with this builder (otherwise it is registered at first use).
268
+ *
269
+ * @throws {@link LaminaPdfError} `text-module-not-loaded`, `invalid-font`, `font-not-embeddable`.
270
+ */
271
+ font(font: Font): FontInfo;
272
+ /** @internal The font in this builder's instance. */
273
+ wasmFont(font: Font): WasmFont;
274
+ /** Defines the named destination `name`: page `index`, shown as `fit` (default: the page). */
275
+ destination(name: string, index: number, fit?: Fit): this;
276
+ /** Adds outline (bookmark) items with their children. @returns their IDs, in pre-order. */
277
+ outline(entries: readonly OutlineEntry[]): string[];
278
+ /** The page labels (`i, ii, 1, 2…`), ranges by first page; checked at finish. */
279
+ pageLabels(ranges: readonly PageLabel[]): this;
280
+ /** The metadata, written as the Info dictionary and an XMP packet. */
281
+ metadata(metadata: Metadata): this;
282
+ /** The natural language (`/Lang`), a BCP 47 tag. */
283
+ lang(tag: string): this;
284
+ /**
285
+ * Attaches a file: PDF/A-3b's associated files, such as an e-invoice's XML. The same name
286
+ * again replaces the file. PDF/A-2b and PDF/A-2u refuse attachments at {@link Builder.finish},
287
+ * and every PDF/A profile refuses one without a MIME type there.
288
+ *
289
+ * @param name - the file name viewers show.
290
+ * @param bytes - the file's contents.
291
+ * @param mime - its MIME type, such as `text/xml`.
292
+ * @param options - how the file relates to the document (`relationship`, default
293
+ * `unspecified`), its `description` and `modDate`.
294
+ * @throws {@link LaminaPdfError} `invalid-argument` for a `modDate` that isn't a PDF date,
295
+ * `unknown-option` for an unknown key, `builder-finished` after {@link Builder.finish}.
296
+ */
297
+ attach(name: string, bytes: Uint8Array, mime: string, options?: AttachmentOptions): this;
298
+ /** How viewers present the document when it opens. */
299
+ viewerPreferences(preferences: ViewerPreferences): this;
300
+ /**
301
+ * Writes fonts, links, the page tree, outline and metadata; the builder (and its unfinished
302
+ * pages) take no more calls afterwards.
303
+ *
304
+ * @returns the new document (unsaved; its save is a full rewrite).
305
+ * @throws {@link LaminaPdfError} `page-index-out-of-range`, `unknown-destination`,
306
+ * `invalid-page-labels`, `invalid-geometry`, `subset-failed`, `builder-finished`; under a
307
+ * profile (`profiles` in the options), the first rule the document breaks, with that rule's
308
+ * code (the error reference lists them, from `profile-version-conflict` on).
309
+ */
310
+ finish(): Document;
311
+ /**
312
+ * Frees the builder's WASM memory now (`finish` does this itself); the builder takes no more
313
+ * calls afterwards. Unfinished pages are freed with {@link Page.free}.
314
+ */
315
+ free(): void;
316
+ /** Frees the builder at the end of a `using` block. */
317
+ [Symbol.dispose](): void;
318
+ }
319
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}