@lpdfio/lpdf 0.32.0 → 0.33.0

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.
package/README.md CHANGED
@@ -47,6 +47,8 @@ An ES module or a TypeScript file imports the same names, and gets the same clas
47
47
  import { L, NoAttr } from '@lpdfio/lpdf'
48
48
  ```
49
49
 
50
+ A render runs on a worker thread, one at a time, and doesn't hold up the event loop. It stops with an `LpdfRenderError` after 5 seconds; `L.engine({ timeout: 60 })` sets another limit in seconds, and `timeout: 0` sets none. It also stops once it needs more than 1024 MB of memory; `L.engine({ maxMemoryMb: 2048 })` sets another cap, from 1 to 4096 MB.
51
+
50
52
  ## Requirements
51
53
 
52
54
  - Node.js 20+
package/dist/L.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { DocumentAssets, DocumentTokens, PdfDocument } from './kit';
2
+ import type { EngineOptions } from './_shared';
2
3
  import { PdfEngine } from './engine';
3
4
  /** Pass as `attrs` when a node has no attributes. Equivalent to `null`. */
4
5
  export declare const NoAttr: null;
@@ -25,8 +26,13 @@ export declare const NoAttr: null;
25
26
  * ```
26
27
  */
27
28
  export declare const L: Readonly<{
28
- /** Create a new {@link PdfEngine} instance. Call `.setLicenseKey()` to configure. */
29
- engine: () => PdfEngine;
29
+ /**
30
+ * Create a new {@link PdfEngine} instance. Call `.setLicenseKey()` to configure.
31
+ *
32
+ * @param options - `timeout`: the seconds a render may run, 5 when left out, no limit at 0. `maxMemoryMb`: the
33
+ * megabytes a render may allocate, 1024 when left out, from 1 to 4096.
34
+ */
35
+ engine: (options?: EngineOptions) => PdfEngine;
30
36
  /** Convert a `PdfDocument` tree to an lpdf XML string. */
31
37
  toXml: (doc: PdfDocument) => string;
32
38
  document: (attrs: import("./kit").DocumentAttr | null, nodes?: import("./kit").LpdfSectionNode[]) => PdfDocument;
package/dist/L.js CHANGED
@@ -32,8 +32,13 @@ exports.NoAttr = null;
32
32
  * ```
33
33
  */
34
34
  exports.L = Object.freeze({
35
- /** Create a new {@link PdfEngine} instance. Call `.setLicenseKey()` to configure. */
36
- engine: () => new engine_1.PdfEngine(),
35
+ /**
36
+ * Create a new {@link PdfEngine} instance. Call `.setLicenseKey()` to configure.
37
+ *
38
+ * @param options - `timeout`: the seconds a render may run, 5 when left out, no limit at 0. `maxMemoryMb`: the
39
+ * megabytes a render may allocate, 1024 when left out, from 1 to 4096.
40
+ */
41
+ engine: (options) => new engine_1.PdfEngine(options),
37
42
  /** Convert a `PdfDocument` tree to an lpdf XML string. */
38
43
  toXml: (doc) => (0, kit_to_xml_1.kitToXml)(doc),
39
44
  // ── Kit ───────────────────────────────────────────────────────────────────
package/dist/_shared.d.ts CHANGED
@@ -1,9 +1,29 @@
1
1
  /**
2
2
  * Shared types used by both the Node.js and browser entry points.
3
3
  */
4
- /** Construction-time configuration for {@link PdfEngine}. Node has no infra options. */
4
+ import type { EncryptionArguments } from './render-job';
5
+ /** Construction-time configuration for `PdfEngine`, `L.engine()` and `initLpdf`. */
5
6
  export interface EngineOptions {
7
+ /**
8
+ * The seconds a render may run before it rejects with an `LpdfRenderError` that names the limit: 5 when left out,
9
+ * no limit at 0. A render runs on a worker, which is stopped at the limit and replaced for the next render.
10
+ */
11
+ timeout?: number;
12
+ /**
13
+ * The megabytes of memory a render may allocate: 1024 when left out, a whole number from 1 to 4096. A render that
14
+ * needs more rejects with an `LpdfRenderError` that names the cap. What the engine holds before the render, such as
15
+ * the fonts it loaded, doesn't count.
16
+ */
17
+ maxMemoryMb?: number;
6
18
  }
19
+ /** The megabytes a render may allocate when `maxMemoryMb` is left out. */
20
+ export declare const DEFAULT_MAX_MEMORY_MB = 1024;
21
+ /**
22
+ * The megabytes a render may allocate, from the `maxMemoryMb` of the engine's options: 1024 when left out.
23
+ *
24
+ * @throws {RangeError} when `maxMemoryMb` is not a whole number from 1 to 4096.
25
+ */
26
+ export declare function maxMemoryMb(value: number | undefined): number;
7
27
  export interface RenderOptions {
8
28
  /**
9
29
  * Optional ISO 8601 creation timestamp (e.g. `"2024-06-01T12:00:00"`).
@@ -41,7 +61,7 @@ export interface RenderOptions {
41
61
  * and, when there is a password, 32 bytes from the platform's secure generator for AES-256 to cut its key, salts
42
62
  * and IVs from, fresh for each render.
43
63
  */
44
- export declare function encryptionArguments(options: RenderOptions, randomBytes: (count: number) => Uint8Array): [string | null, string | null, boolean, Uint8Array];
64
+ export declare function encryptionArguments(options: RenderOptions, randomBytes: (count: number) => Uint8Array): EncryptionArguments;
45
65
  /** The value of an attribute in a document tree: a string, a number or a boolean, as the schema types it. */
46
66
  export type AttrValue = string | number | boolean;
47
67
  /**
package/dist/_shared.js CHANGED
@@ -1,12 +1,28 @@
1
1
  "use strict";
2
- /**
3
- * Shared types used by both the Node.js and browser entry points.
4
- */
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_MAX_MEMORY_MB = void 0;
4
+ exports.maxMemoryMb = maxMemoryMb;
6
5
  exports.encryptionArguments = encryptionArguments;
7
6
  exports.buildAttrs = buildAttrs;
8
7
  exports.assertFinite = assertFinite;
9
8
  exports.assertFiniteIn = assertFiniteIn;
9
+ /** The megabytes a render may allocate when `maxMemoryMb` is left out. */
10
+ exports.DEFAULT_MAX_MEMORY_MB = 1024;
11
+ /** The most `maxMemoryMb` may be: 32-bit WebAssembly addresses 4 GB at most. */
12
+ const MAX_MEMORY_MB = 4096;
13
+ /**
14
+ * The megabytes a render may allocate, from the `maxMemoryMb` of the engine's options: 1024 when left out.
15
+ *
16
+ * @throws {RangeError} when `maxMemoryMb` is not a whole number from 1 to 4096.
17
+ */
18
+ function maxMemoryMb(value) {
19
+ if (value === undefined)
20
+ return exports.DEFAULT_MAX_MEMORY_MB;
21
+ if (!Number.isInteger(value) || value < 1 || value > MAX_MEMORY_MB) {
22
+ throw new RangeError(`maxMemoryMb must be a whole number of megabytes from 1 to ${MAX_MEMORY_MB}, not ${value}`);
23
+ }
24
+ return value;
25
+ }
10
26
  /** The random bytes AES-256 needs from the host, one 256-bit key's worth. The engine makes none itself. */
11
27
  const ENTROPY_BYTES = 32;
12
28
  /**
package/dist/attrs.d.ts CHANGED
@@ -76,6 +76,20 @@ export interface ColumnAttr {
76
76
  * line; in a column it takes the full width.
77
77
  */
78
78
  width?: string;
79
+ /**
80
+ * true lays out the texts that the text with data-source repeats one page at a time, straight
81
+ * from the data, for logs and lists of tens of thousands of lines and more. The pages are the
82
+ * ones the same column would have without bulk, but where a page would end inside a text of four
83
+ * lines or more: without bulk the text splits there, and with bulk it moves whole to the next
84
+ * page. The column holds texts only, and they follow rules: a text holds plain words with no
85
+ * span, link, bookmark, footnote or reference, sets no widows or orphans and has no data-source
86
+ * inside it, and a text without max-lines holds one line and ends in an ellipsis. The column sits
87
+ * directly in the layout, has no data-source of its own and one text with it, has no height, and
88
+ * neither it nor anything in it has paginate. Its document has no table of contents, no reference
89
+ * to a bookmark, no pdfua and no pdfa of level a, and its section's columns are not balanced.
90
+ * Breaking a rule is an error that names it. Default false.
91
+ */
92
+ bulk?: boolean;
79
93
  }
80
94
  /**
81
95
  * Children side by side, continuing on the next line when they run out of width. A child with width
@@ -236,6 +250,20 @@ export interface GridAttr {
236
250
  width?: string;
237
251
  colWidth?: string;
238
252
  cols?: number;
253
+ /**
254
+ * true lays out the cells that the child with data-source repeats one page at a time, straight
255
+ * from the data, for sheets of tens of thousands of labels or cards and more. The pages are the
256
+ * ones the same grid would have without bulk. The cells follow rules, and so do the grid's other
257
+ * children: a cell is a text, or a column that holds texts, a text holds plain words with no
258
+ * span, link, bookmark, footnote or reference, and sets no widows or orphans, a text without
259
+ * max-lines holds one line and ends in an ellipsis, and nothing in a cell has data-source. A row
260
+ * of cells never splits across pages. The grid sits directly in the layout, has no data-source of
261
+ * its own and one child with it, has no height, and neither it nor anything in it has paginate.
262
+ * Its document has no table of contents, no reference to a bookmark, no pdfua and no pdfa of
263
+ * level a, and its section's columns are not balanced. Breaking a rule is an error that names it.
264
+ * Default false.
265
+ */
266
+ bulk?: boolean;
239
267
  }
240
268
  /**
241
269
  * A list of items, each with a marker: a bullet drawn as a shape, or a number the engine gives. The
@@ -350,6 +378,21 @@ export interface ListAttr {
350
378
  * line; in a column it takes the full width.
351
379
  */
352
380
  width?: string;
381
+ /**
382
+ * true lays out the items that the li with data-source repeats one page at a time, straight from
383
+ * the data, for logs and lists of tens of thousands of items and more. The pages are the ones the
384
+ * same list would have without bulk, but where a page would end inside an item, between its texts
385
+ * or inside a text of four lines or more: without bulk the item splits there, and with bulk it
386
+ * moves whole to the next page. A number list numbers the items as it does without bulk. The list
387
+ * has one level, and its items follow rules: an li holds texts only, a text holds plain words
388
+ * with no span, link, bookmark, footnote or reference, and sets no widows or orphans, a text
389
+ * without max-lines holds one line and ends in an ellipsis, and nothing in an item has
390
+ * data-source. The list sits directly in the layout, has no data-source of its own and one li
391
+ * with it, has no height, and neither it nor anything in it has paginate. Its document has no
392
+ * table of contents, no reference to a bookmark, no pdfua and no pdfa of level a, and its
393
+ * section's columns are not balanced. Breaking a rule is an error that names it. Default false.
394
+ */
395
+ bulk?: boolean;
353
396
  }
354
397
  /**
355
398
  * One item of a list: a box that holds what a layout holds, such as a text, an image, a table or
@@ -617,9 +660,10 @@ export interface CodeSpanAttr {
617
660
  export interface ImgAttr {
618
661
  name: string;
619
662
  /**
620
- * What the image shows, which a screen reader reads in a PDF/UA document; alt="" marks it as
621
- * decoration, which a reader skips. A PDF/UA document needs it on every image of the layout. A
622
- * document without pdfua ignores it.
663
+ * What the image shows, which a screen reader reads in a tagged document, one with pdfua or a
664
+ * pdfa of level a; alt="" marks it as decoration, which a reader skips. A PDF/UA document needs
665
+ * it on every image of the layout; at PDF/A level a without pdfua, an image without it is
666
+ * decoration. A document that is not tagged ignores it.
623
667
  */
624
668
  alt?: string;
625
669
  height?: string;
@@ -728,9 +772,11 @@ export interface BarcodeAttr {
728
772
  */
729
773
  width?: string;
730
774
  /**
731
- * What the barcode is for, which a screen reader reads in a PDF/UA document in place of its data,
732
- * which means nothing read aloud: "QR code to pay this invoice". alt="" marks it as decoration. A
733
- * PDF/UA document needs it on every barcode of the layout. A document without pdfua ignores it.
775
+ * What the barcode is for, which a screen reader reads in a tagged document, one with pdfua or a
776
+ * pdfa of level a, in place of its data, which means nothing read aloud: "QR code to pay this
777
+ * invoice". alt="" marks it as decoration. A PDF/UA document needs it on every barcode of the
778
+ * layout; at PDF/A level a without pdfua, a barcode without it is decoration. A document that is
779
+ * not tagged ignores it.
734
780
  */
735
781
  alt?: string;
736
782
  paginate?: string;
@@ -790,10 +836,11 @@ export interface TextAttr {
790
836
  */
791
837
  width?: string;
792
838
  /**
793
- * Makes the text a heading, h1 to h6, which a PDF/UA document tags as one: a screen reader lists
794
- * the headings and moves between them. A text without role is a paragraph. A PDF/UA document's
795
- * headings start at h1 and go down one level at a time. It changes nothing a page shows: set the
796
- * size and the weight as on any text. A document without pdfua ignores it.
839
+ * Makes the text a heading, h1 to h6, which a tagged document, one with pdfua or a pdfa of level
840
+ * a, tags as one: a screen reader lists the headings and moves between them. A text without role
841
+ * is a paragraph. A PDF/UA document's headings start at h1 and go down one level at a time. It
842
+ * changes nothing a page shows: set the size and the weight as on any text. A document that is
843
+ * not tagged ignores it.
797
844
  */
798
845
  role?: string;
799
846
  /**
@@ -1134,6 +1181,20 @@ export interface TableAttr {
1134
1181
  height?: string;
1135
1182
  paginate?: string;
1136
1183
  debug?: boolean;
1184
+ /**
1185
+ * true lays out the rows that the tr with data-source repeats one page at a time, straight from
1186
+ * the data, for reports of tens of thousands of rows and more. The pages are the ones the same
1187
+ * table would have without bulk. The rows follow rules, and so do the thead and the other rows:
1188
+ * each td holds one text or none, a text holds plain words with no span, link, bookmark, footnote
1189
+ * or reference, and sets no widows or orphans, a text without max-lines holds one line and ends
1190
+ * in an ellipsis, a td has no rowspan, a row no keep, and nothing in a row has data-source. A row
1191
+ * never splits across pages. The table sits directly in the layout, has no data-source of its own
1192
+ * and one tr with it, sets its cols in fr, pt or %, has no height, and neither it nor anything in
1193
+ * it has paginate. Its document has no table of contents, no reference to a bookmark, no pdfua
1194
+ * and no pdfa of level a, and its section's columns are not balanced. Breaking a rule is an error
1195
+ * that names it. Default false.
1196
+ */
1197
+ bulk?: boolean;
1137
1198
  /**
1138
1199
  * Puts the element, and everything in it, in an optional content group, which the viewer shows or
1139
1200
  * hides. print: printed, and not shown on screen. screen: shown on screen, and not printed. The
@@ -1220,21 +1281,50 @@ export interface BookmarkAttr {
1220
1281
  * Pins content to the top or bottom edge of pages, outside the normal flow, for headers and
1221
1282
  * footers. It reserves that space on every page it appears on. Only allowed directly inside layout.
1222
1283
  * Where it is written among the flow does not matter: pin chooses the edge, and regions on one edge
1223
- * stack in the order written.
1284
+ * stack in the order written. With pin set to inset, it is a block at a spot inside the section's
1285
+ * columns instead, such as a picture or a box across two columns of a newsletter: top and height
1286
+ * place it, col and colspan say which columns it covers, and those columns flow around it, filling
1287
+ * above it and carrying on below it.
1224
1288
  */
1225
1289
  export interface RegionAttr {
1226
1290
  /**
1227
1291
  * Which edge the region sticks to. top and bottom work. left and right pass validation but are
1228
- * not implemented yet.
1292
+ * not implemented yet. inset places the region inside the columns, where top, height, col and
1293
+ * colspan say.
1229
1294
  */
1230
1295
  pin: string;
1231
1296
  /**
1232
- * Which pages show the region: each, first, last, odd, even, or a range such as 2-last. Defaults
1233
- * to each.
1297
+ * Which pages show the region: each, first, last, odd, even, or a range such as 2-last. odd and
1298
+ * even follow the number printed on the page, so in a section that starts on page 4 even shows on
1299
+ * its first page. first, last and ranges count the section's own pages, whatever their numbers.
1300
+ * Defaults to each. An inset on last goes on the last page of the flow filled without it; if it
1301
+ * then pushes text on to a new page, it stays where it is, one page before the end.
1234
1302
  */
1235
1303
  page?: string;
1236
1304
  w?: string;
1237
1305
  debug?: boolean;
1306
+ /**
1307
+ * For pin set to inset: the column the inset starts in, counted from 1 at the left. Defaults to
1308
+ * 1. With colspan, it may not run past the section's columns. An error on any other pin.
1309
+ */
1310
+ col?: number;
1311
+ /**
1312
+ * For pin set to inset: how many columns the inset covers, from col. It is as wide as those
1313
+ * columns and the gaps between them. Defaults to 1. An error on any other pin.
1314
+ */
1315
+ colspan?: number;
1316
+ /**
1317
+ * For pin set to inset, and required with it: how far below the top of the columns the inset
1318
+ * starts, under the headers. An error on any other pin.
1319
+ */
1320
+ top?: string;
1321
+ /**
1322
+ * For pin set to inset, and required with it: how tall the inset is. Content taller than it is
1323
+ * clipped at its foot, and the inset is never cut across pages: one whose top and height reach
1324
+ * below the room the headers and footers leave, on a page it is on, is an error. Footnotes give
1325
+ * way to it. An error on any other pin.
1326
+ */
1327
+ height?: string;
1238
1328
  }
1239
1329
  /**
1240
1330
  * Markdown as the content of a section, where a layout would go. It holds only Markdown: optional
@@ -1534,6 +1624,12 @@ export interface MarkdownTdAttr {
1534
1624
  * of its text. Layers cannot be nested.
1535
1625
  */
1536
1626
  export interface LayerAttr {
1627
+ /**
1628
+ * Which pages of the section show the layer: each, first, last, odd, even, or a range such as
1629
+ * 2-last. odd and even follow the number printed on the page, so in a section that starts on page
1630
+ * 4 even shows on its first page. first, last and ranges count the section's own pages, whatever
1631
+ * their numbers. Defaults to each.
1632
+ */
1537
1633
  page?: string;
1538
1634
  /**
1539
1635
  * How opaque everything in the layer is, from 0 to 1. To fade one element, put it in a layer of
@@ -1560,10 +1656,11 @@ export interface LayerAttr {
1560
1656
  */
1561
1657
  color?: string;
1562
1658
  /**
1563
- * In a PDF/UA document, what the layer shows, which a screen reader reads as one figure at the
1564
- * layer's place in the document: a layer before the layout before it, one after the layout after
1565
- * it. Without alt a layer is decoration, as a header is, and a screen reader skips it with all
1566
- * its text: a watermark, a running title, a logo's letters. A document without pdfua ignores it.
1659
+ * In a tagged document, one with pdfua or a pdfa of level a, what the layer shows, which a screen
1660
+ * reader reads as one figure at the layer's place in the document: a layer before the layout
1661
+ * before it, one after the layout after it. Without alt a layer is decoration, as a header is,
1662
+ * and a screen reader skips it with all its text: a watermark, a running title, a logo's letters.
1663
+ * A document that is not tagged ignores it.
1567
1664
  */
1568
1665
  alt?: string;
1569
1666
  /**
@@ -1952,12 +2049,14 @@ export interface FileAttr {
1952
2049
  ref?: string;
1953
2050
  /**
1954
2051
  * The type of the file, such as text/xml, application/pdf or text/csv. Defaults to
1955
- * application/octet-stream, which says only that it is a file.
2052
+ * application/octet-stream, which says only that it is a file, and to text/xml for the invoice of
2053
+ * a Factur-X e-invoice.
1956
2054
  */
1957
2055
  mime?: string;
1958
2056
  /**
1959
2057
  * How the file relates to the document: source, data, alternative, supplement or unspecified, the
1960
- * default. An e-invoice's XML is data.
2058
+ * default. The invoice of a Factur-X e-invoice defaults to data for the MINIMUM and BASIC WL
2059
+ * profiles, and to alternative for the others, as the Factur-X spec asks.
1961
2060
  */
1962
2061
  relationship?: string;
1963
2062
  /** A line about the file, which a reader shows beside its name. */
@@ -2029,3 +2128,75 @@ export interface GradientToken {
2029
2128
  */
2030
2129
  stops?: GradientStop[];
2031
2130
  }
2131
+ /**
2132
+ * One set of lines of a ruling, cut by a step or by a count in each direction: x for the lines that
2133
+ * run down the page, y for the lines that run across it. A direction with neither has no lines, so
2134
+ * step-y alone is ruled paper and step both is squared paper. A step and a count in the same
2135
+ * direction is an error. Each set is drawn after the one before it, so a heavier set paints over a
2136
+ * finer one.
2137
+ */
2138
+ export interface RulingLines {
2139
+ /**
2140
+ * The distance between two lines in both directions, a length such as 5mm. step-x and step-y take
2141
+ * its place in their direction. A cell narrower than 2.5pt is an error.
2142
+ */
2143
+ step?: string;
2144
+ /**
2145
+ * The distance between two lines that run down the page, from left to right, a length such as
2146
+ * 10mm.
2147
+ */
2148
+ stepX?: string;
2149
+ /**
2150
+ * The distance between two lines that run across the page, from top to bottom, a length such as
2151
+ * 8mm: ruled paper.
2152
+ */
2153
+ stepY?: string;
2154
+ /**
2155
+ * Cuts the space into this many equal parts in both directions, from 1 to 100, so the lines land
2156
+ * on its edges whatever its size. count-x and count-y take its place in their direction. A part
2157
+ * narrower than 2.5pt is an error.
2158
+ */
2159
+ count?: number;
2160
+ /** Cuts the space into this many equal columns, from 1 to 100. */
2161
+ countX?: number;
2162
+ /** Cuts the space into this many equal rows, from 1 to 100. */
2163
+ countY?: number;
2164
+ /**
2165
+ * The color of the lines: hex, cmyk(), rgb(), hsl() or a color token. Defaults to line-muted.
2166
+ */
2167
+ color?: string;
2168
+ /**
2169
+ * The thickness of the lines, a length or a name from the border row of the tokens. Defaults to
2170
+ * 0.4pt.
2171
+ */
2172
+ thickness?: string;
2173
+ }
2174
+ /**
2175
+ * Lines on every page of a section, for paper to write or draw on, or a grid to place things by:
2176
+ * ruled paper, squared paper, or a page cut into equal parts. A section names it with
2177
+ * ruling="name", and the lines are drawn under everything else on its pages, over the background.
2178
+ * They are decoration, which a screen reader skips.
2179
+ */
2180
+ export interface RulingToken {
2181
+ /**
2182
+ * The space the lines fill and a count divides. page, the default, is the whole page up to its
2183
+ * trim edge. margin is the area inside the margin of the section's layout or markdown. A step
2184
+ * starts at its top left corner, and the lines stop at its edges.
2185
+ */
2186
+ origin?: 'page' | 'margin';
2187
+ /**
2188
+ * Whether the lines on the edges of that space are drawn: the first one, and the last one where a
2189
+ * step lands on the far edge. A count of 12 draws 13 lines with them and 11 without. Defaults to
2190
+ * true.
2191
+ */
2192
+ edges?: boolean;
2193
+ /**
2194
+ * Puts the lines in an optional content group, as ocg does on an element: print, printed and not
2195
+ * shown on screen, or screen, shown on screen and not printed, such as a grid to place things by.
2196
+ */
2197
+ ocg?: 'print' | 'screen';
2198
+ /**
2199
+ * The sets of lines, at least one, drawn in this order: a later set paints over an earlier one.
2200
+ */
2201
+ lines: RulingLines[];
2202
+ }