@lpdfio/lpdf 0.31.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.
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LpdfRenderError = exports.ENGINE_CRASHED = void 0;
4
+ /** What a render that crashes the engine rejects with, the same in every SDK of Lpdf. */
5
+ exports.ENGINE_CRASHED = 'The engine crashed during the render. This is a bug in Lpdf, or the render ran out of memory before its cap ' +
6
+ 'stopped it: please report it with the document at https://github.com/lpdfio/lpdf/issues.';
7
+ /**
8
+ * Thrown when the lpdf engine returns a layout or parse error, a render runs past its timeout or its memory cap, or
9
+ * the engine crashes.
10
+ */
11
+ class LpdfRenderError extends Error {
12
+ constructor(message, cause) {
13
+ super(message);
14
+ this.name = 'LpdfRenderError';
15
+ if (cause !== undefined)
16
+ this.cause = cause;
17
+ }
18
+ }
19
+ exports.LpdfRenderError = LpdfRenderError;
@@ -0,0 +1,67 @@
1
+ /** The engine's render calls, as wasm-bindgen exposes them in both builds. */
2
+ export interface WasmRenderEngine {
3
+ render_pdf(xml: string, json_data: string | null, user_password: string | null, owner_password: string | null, skip_encryption: boolean, entropy: Uint8Array): Uint8Array;
4
+ render_tree_pdf(json: string, user_password: string | null, owner_password: string | null, skip_encryption: boolean, entropy: Uint8Array): Uint8Array;
5
+ stamp(pdf: Uint8Array, stamps: string): Uint8Array;
6
+ load_font(name: string, bytes: Uint8Array): void;
7
+ load_image(name: string, bytes: Uint8Array): void;
8
+ load_file(name: string, bytes: Uint8Array): void;
9
+ load_profile(name: string, bytes: Uint8Array): void;
10
+ load_markdown_styles(src: string, xml: string): void;
11
+ set_created_on(iso: string): void;
12
+ set_now(unix: bigint): void;
13
+ set_max_memory_mb(mb: number): void;
14
+ free(): void;
15
+ }
16
+ /** The user password, the owner password, `skipEncryption` and the entropy, in the order the render calls take them. */
17
+ export type EncryptionArguments = [string | null, string | null, boolean, Uint8Array];
18
+ /**
19
+ * One render: the document and every file it needs, already read, since a worker reads nothing itself. A stamp runs as
20
+ * a render does, with the PDF and the JSON of its stamps as its document and their PNGs as its images.
21
+ */
22
+ export interface RenderJob {
23
+ licenseKey: string;
24
+ /** The host's clock in Unix seconds, for the key's expiry. */
25
+ now: bigint;
26
+ /** The megabytes the render may allocate. */
27
+ maxMemoryMb: number;
28
+ createdOn: string | undefined;
29
+ fonts: Map<string, Uint8Array>;
30
+ images: Map<string, Uint8Array>;
31
+ files: Map<string, Uint8Array>;
32
+ profiles: Map<string, Uint8Array>;
33
+ markdownStyles: Map<string, string>;
34
+ /** An XML document with its data as JSON, a document tree as JSON, or a PDF to stamp. */
35
+ document: {
36
+ xml: string;
37
+ data: string | null;
38
+ } | {
39
+ tree: string;
40
+ } | {
41
+ pdf: Uint8Array;
42
+ stamps: string;
43
+ };
44
+ encryption: EncryptionArguments;
45
+ }
46
+ /**
47
+ * What the worker sends back: the PDF, or the engine's error. `broken` says that the engine trapped, after which its
48
+ * memory can't be trusted, so the worker is replaced before the next render. A crash of the engine has the error every
49
+ * SDK gives for one, and the engine's own as its `cause`.
50
+ */
51
+ export type RenderReply = {
52
+ pdf: Uint8Array;
53
+ } | {
54
+ error: string;
55
+ broken: boolean;
56
+ cause?: string;
57
+ };
58
+ /**
59
+ * Runs a render on an engine of its own, which is freed after it, and returns the PDF or the error. It never throws: a
60
+ * failure is the reply.
61
+ */
62
+ export declare function runRenderJob(createEngine: (licenseKey: string) => WasmRenderEngine, job: RenderJob): RenderReply;
63
+ /**
64
+ * The buffers a reply moves to the other thread instead of copying: the PDF's, when the PDF has a buffer of its own.
65
+ * A view into a larger buffer, such as the engine's memory, is copied.
66
+ */
67
+ export declare function transferList(reply: RenderReply): ArrayBuffer[];
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runRenderJob = runRenderJob;
4
+ exports.transferList = transferList;
5
+ /**
6
+ * A render as a worker runs it: everything the engine needs, sent in one message, and the reply that comes back.
7
+ * Shared by the Node worker and the browser's.
8
+ */
9
+ const render_error_1 = require("./render-error");
10
+ /**
11
+ * Runs a render on an engine of its own, which is freed after it, and returns the PDF or the error. It never throws: a
12
+ * failure is the reply.
13
+ */
14
+ function runRenderJob(createEngine, job) {
15
+ let engine;
16
+ let reply;
17
+ try {
18
+ engine = createEngine(job.licenseKey);
19
+ // Without a clock the engine cannot check the key's expiry, and an expired key renders as though it were
20
+ // current.
21
+ engine.set_now(job.now);
22
+ engine.set_max_memory_mb(job.maxMemoryMb);
23
+ if (job.createdOn)
24
+ engine.set_created_on(job.createdOn);
25
+ for (const [name, bytes] of job.fonts)
26
+ engine.load_font(name, bytes);
27
+ for (const [name, bytes] of job.images)
28
+ engine.load_image(name, bytes);
29
+ for (const [name, bytes] of job.files)
30
+ engine.load_file(name, bytes);
31
+ for (const [name, bytes] of job.profiles)
32
+ engine.load_profile(name, bytes);
33
+ for (const [src, text] of job.markdownStyles)
34
+ engine.load_markdown_styles(src, text);
35
+ const { document } = job;
36
+ const pdf = 'xml' in document
37
+ ? engine.render_pdf(document.xml, document.data, ...job.encryption)
38
+ : 'tree' in document
39
+ ? engine.render_tree_pdf(document.tree, ...job.encryption)
40
+ : engine.stamp(document.pdf, document.stamps);
41
+ reply = { pdf };
42
+ }
43
+ catch (e) {
44
+ // A trap, or the stack running out inside the engine, which some browsers report as a RangeError, leaves the
45
+ // engine part way through a call: its memory can't be trusted. Either is a crash of the engine.
46
+ const crashed = e instanceof WebAssembly.RuntimeError || e instanceof RangeError;
47
+ reply = crashed
48
+ ? { error: render_error_1.ENGINE_CRASHED, broken: true, cause: `${e.name}: ${e.message}` }
49
+ : { error: e instanceof Error ? e.message : String(e), broken: false };
50
+ }
51
+ // An engine left part way through a call is still borrowed, and wasm-bindgen's free() throws "attempted to take
52
+ // ownership of Rust value while it was borrowed". Such an engine goes with its worker; the reply keeps the
53
+ // engine's own error.
54
+ if ('pdf' in reply || !reply.broken) {
55
+ try {
56
+ engine?.free();
57
+ }
58
+ catch {
59
+ if ('error' in reply)
60
+ reply = { ...reply, broken: true };
61
+ }
62
+ }
63
+ return reply;
64
+ }
65
+ /**
66
+ * The buffers a reply moves to the other thread instead of copying: the PDF's, when the PDF has a buffer of its own.
67
+ * A view into a larger buffer, such as the engine's memory, is copied.
68
+ */
69
+ function transferList(reply) {
70
+ if (!('pdf' in reply))
71
+ return [];
72
+ const { buffer, byteLength } = reply.pdf;
73
+ return buffer instanceof ArrayBuffer && buffer.byteLength === byteLength ? [buffer] : [];
74
+ }
@@ -0,0 +1,52 @@
1
+ import type { RenderJob, RenderReply } from './render-job';
2
+ /** The seconds a render may run when `timeout` is left out. A timeout of 0 means no limit. */
3
+ export declare const DEFAULT_TIMEOUT = 5;
4
+ /** A worker as the queue drives it, in Node or in the browser. */
5
+ export interface RenderWorker {
6
+ /** Sends it a render. */
7
+ post(job: RenderJob): void;
8
+ /** Stops it, whatever it is doing. */
9
+ terminate(): void;
10
+ /** In Node: whether the worker keeps the process running, which it does only while it renders. */
11
+ hold?(busy: boolean): void;
12
+ }
13
+ /** What a worker tells the queue. */
14
+ export interface RenderWorkerEvents {
15
+ /** The render it was sent ended, with a PDF or an error. */
16
+ replied(reply: RenderReply): void;
17
+ /** The worker failed outside a render, or stopped. */
18
+ failed(message: string): void;
19
+ }
20
+ /** Starts a worker that reports to `events`. */
21
+ export type StartRenderWorker = (events: RenderWorkerEvents) => RenderWorker;
22
+ /**
23
+ * The seconds a render may run, from the `timeout` of the engine's options: 5 when left out, no limit at 0.
24
+ *
25
+ * @throws {RangeError} when `timeout` is negative or not a finite number.
26
+ */
27
+ export declare function renderTimeout(timeout: number | undefined): number;
28
+ /**
29
+ * Renders one at a time on one worker, kept warm between renders with the engine loaded. A render that runs past its
30
+ * timeout ends the worker, since a running WebAssembly call can't be stopped any other way, and the next render
31
+ * starts a new one.
32
+ */
33
+ export declare class RenderQueue {
34
+ private readonly _start;
35
+ private _worker;
36
+ private _running;
37
+ private readonly _waiting;
38
+ constructor(_start: StartRenderWorker);
39
+ /**
40
+ * Renders `job` once the renders before it have ended. Its timeout counts from when it starts.
41
+ *
42
+ * @param timeout - The seconds it may run, 0 for no limit.
43
+ * @returns The PDF; rejects with an `LpdfRenderError` when the engine refuses the document or the render runs
44
+ * past its timeout.
45
+ */
46
+ render(job: RenderJob, timeout: number): Promise<Uint8Array>;
47
+ private _next;
48
+ private _startWorker;
49
+ private _dropWorker;
50
+ private _settle;
51
+ private _timedOut;
52
+ }
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RenderQueue = exports.DEFAULT_TIMEOUT = void 0;
4
+ exports.renderTimeout = renderTimeout;
5
+ const render_error_1 = require("./render-error");
6
+ /** The seconds a render may run when `timeout` is left out. A timeout of 0 means no limit. */
7
+ exports.DEFAULT_TIMEOUT = 5;
8
+ // The longest delay setTimeout takes: a longer one fires at once. A limit of 24 days is no limit for a render.
9
+ const MAX_DELAY_MS = 2 ** 31 - 1;
10
+ /**
11
+ * The seconds a render may run, from the `timeout` of the engine's options: 5 when left out, no limit at 0.
12
+ *
13
+ * @throws {RangeError} when `timeout` is negative or not a finite number.
14
+ */
15
+ function renderTimeout(timeout) {
16
+ if (timeout === undefined)
17
+ return exports.DEFAULT_TIMEOUT;
18
+ if (!Number.isFinite(timeout) || timeout < 0) {
19
+ throw new RangeError(`timeout must be a number of seconds, 0 for no limit, not ${timeout}`);
20
+ }
21
+ return timeout;
22
+ }
23
+ function seconds(count) {
24
+ return count === 1 ? '1 second' : `${count} seconds`;
25
+ }
26
+ /**
27
+ * Renders one at a time on one worker, kept warm between renders with the engine loaded. A render that runs past its
28
+ * timeout ends the worker, since a running WebAssembly call can't be stopped any other way, and the next render
29
+ * starts a new one.
30
+ */
31
+ class RenderQueue {
32
+ constructor(_start) {
33
+ this._start = _start;
34
+ this._waiting = [];
35
+ }
36
+ /**
37
+ * Renders `job` once the renders before it have ended. Its timeout counts from when it starts.
38
+ *
39
+ * @param timeout - The seconds it may run, 0 for no limit.
40
+ * @returns The PDF; rejects with an `LpdfRenderError` when the engine refuses the document or the render runs
41
+ * past its timeout.
42
+ */
43
+ render(job, timeout) {
44
+ return new Promise((resolve, reject) => {
45
+ this._waiting.push({ job, timeout, resolve, reject });
46
+ this._next();
47
+ });
48
+ }
49
+ _next() {
50
+ if (this._running)
51
+ return;
52
+ const pending = this._waiting.shift();
53
+ if (!pending) {
54
+ this._worker?.hold?.(false);
55
+ return;
56
+ }
57
+ this._running = pending;
58
+ try {
59
+ const worker = this._worker ?? (this._worker = this._startWorker());
60
+ worker.hold?.(true);
61
+ if (pending.timeout > 0) {
62
+ pending.timer = setTimeout(() => this._timedOut(pending), Math.min(pending.timeout * 1000, MAX_DELAY_MS));
63
+ }
64
+ worker.post(pending.job);
65
+ }
66
+ catch (e) {
67
+ // A worker that can't be started or sent the render fails this render, and the next one tries a new worker.
68
+ this._dropWorker();
69
+ this._settle({ error: `The render worker failed: ${e instanceof Error ? e.message : String(e)}`, broken: true });
70
+ }
71
+ }
72
+ _startWorker() {
73
+ // A worker that was ended still delivers what it sent before, and its exit: only the current one counts.
74
+ const worker = this._start({
75
+ replied: reply => {
76
+ if (worker !== this._worker)
77
+ return;
78
+ if ('error' in reply && reply.broken)
79
+ this._dropWorker();
80
+ this._settle(reply);
81
+ },
82
+ failed: message => {
83
+ if (worker !== this._worker)
84
+ return;
85
+ this._dropWorker();
86
+ this._settle({ error: message, broken: true });
87
+ },
88
+ });
89
+ return worker;
90
+ }
91
+ _dropWorker() {
92
+ this._worker?.terminate();
93
+ this._worker = undefined;
94
+ }
95
+ _settle(reply) {
96
+ const pending = this._running;
97
+ if (!pending)
98
+ return;
99
+ this._running = undefined;
100
+ clearTimeout(pending.timer);
101
+ if ('pdf' in reply) {
102
+ pending.resolve(reply.pdf);
103
+ }
104
+ else {
105
+ pending.reject(new render_error_1.LpdfRenderError(reply.error, reply.cause));
106
+ }
107
+ this._next();
108
+ }
109
+ _timedOut(pending) {
110
+ if (pending !== this._running)
111
+ return;
112
+ this._dropWorker();
113
+ this._settle({ error: `The render timed out after ${seconds(pending.timeout)}.`, broken: true });
114
+ }
115
+ }
116
+ exports.RenderQueue = RenderQueue;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * The Node worker a `PdfEngine` renders on: it loads the engine once and runs each render it is sent.
5
+ */
6
+ const node_worker_threads_1 = require("node:worker_threads");
7
+ const render_job_1 = require("./render-job");
8
+ // require() path is relative to the compiled output at dist/render-worker.js, as engine.ts's is.
9
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
10
+ const wasm = require('./wasm/lpdf.js');
11
+ // The file runs only as a worker, where parentPort is the port to the thread that started it.
12
+ const port = node_worker_threads_1.parentPort;
13
+ port.on('message', (job) => {
14
+ const reply = (0, render_job_1.runRenderJob)(licenseKey => new wasm.LpdfEngine(licenseKey), job);
15
+ port.postMessage(reply, (0, render_job_1.transferList)(reply));
16
+ });
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Stamps: PNG images drawn over the pages of an existing PDF, by `stamp` on the engine. Shared by the Node.js and
3
+ * browser entry points.
4
+ */
5
+ /**
6
+ * One stamp: a PNG, the pages it goes on, and the box it is drawn in on each. The box is placed as a layer element
7
+ * is, and the image is fitted in it without distortion.
8
+ */
9
+ export interface StampAttr {
10
+ /** The PNG's bytes. An image given to several stamps is embedded in the PDF once. */
11
+ image: Uint8Array;
12
+ /** The pages: a page scope, such as `3`, `1-2`, `last`, `each`, `odd` or `1,3,5-last`. A page the PDF doesn't have is an error. */
13
+ page: string;
14
+ /**
15
+ * Where the box goes, in `pt`, `mm` or `in`: its top-left corner, from the page's top-left corner as a viewer shows
16
+ * it, or with `anchor`, signed offsets from that point of the page. Required without `anchor`.
17
+ */
18
+ x?: string;
19
+ y?: string;
20
+ /**
21
+ * The point of the page the box is placed from, and the point of the box that goes there: `top-left`,
22
+ * `top-center`, `top-right`, `center-left`, `center`, `center-right`, `bottom-left`, `bottom-center` or
23
+ * `bottom-right`.
24
+ */
25
+ anchor?: string;
26
+ /** The size of the box, in `pt`, `mm` or `in`. */
27
+ width: string;
28
+ height: string;
29
+ /** Where the image sits across the box, in the room it leaves: `start`, `center` (the default) or `end`. */
30
+ align?: string;
31
+ /** Where the image sits down the box, in the room it leaves: `start`, `center` (the default) or `end`. */
32
+ justify?: string;
33
+ /**
34
+ * How the image is sized in the box, keeping its proportions: `fit` (the default) shrinks an image larger than the
35
+ * box and keeps a smaller one at its natural size, from the resolution the PNG records, or a pixel to a point;
36
+ * `fill` takes the largest size that fits.
37
+ */
38
+ scale?: string;
39
+ /** How many times its natural size `fit` may grow an image, never past the box: 1, the default, or more. */
40
+ maxGrow?: number;
41
+ }
42
+ /**
43
+ * The stamps as the engine takes them: the JSON of the stamps, each naming its image, and the images by name. The same
44
+ * bytes, given to several stamps, go under one name.
45
+ *
46
+ * @throws {TypeError} when a stamp's `image` is not the PNG's bytes.
47
+ */
48
+ export declare function stampRequest(stamps: StampAttr[]): {
49
+ stamps: string;
50
+ images: Map<string, Uint8Array>;
51
+ };
package/dist/stamp.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /**
3
+ * Stamps: PNG images drawn over the pages of an existing PDF, by `stamp` on the engine. Shared by the Node.js and
4
+ * browser entry points.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.stampRequest = stampRequest;
8
+ /**
9
+ * The stamps as the engine takes them: the JSON of the stamps, each naming its image, and the images by name. The same
10
+ * bytes, given to several stamps, go under one name.
11
+ *
12
+ * @throws {TypeError} when a stamp's `image` is not the PNG's bytes.
13
+ */
14
+ function stampRequest(stamps) {
15
+ const images = new Map();
16
+ const names = new Map();
17
+ const list = stamps.map(({ image, maxGrow, ...rest }, i) => {
18
+ if (!(image instanceof Uint8Array)) {
19
+ throw new TypeError(`stamp ${i + 1}: image must be the PNG's bytes, a Uint8Array`);
20
+ }
21
+ let name = names.get(image);
22
+ if (name === undefined) {
23
+ name = `stamp-${names.size}`;
24
+ names.set(image, name);
25
+ images.set(name, image);
26
+ }
27
+ return { ...rest, image: name, ...(maxGrow === undefined ? {} : { 'max-grow': maxGrow }) };
28
+ });
29
+ return { stamps: JSON.stringify(list), images };
30
+ }
@@ -67,6 +67,19 @@ export class LpdfEngine {
67
67
  const len1 = WASM_VECTOR_LEN;
68
68
  wasm.lpdfengine_load_markdown_styles(this.__wbg_ptr, ptr0, len0, ptr1, len1);
69
69
  }
70
+ /**
71
+ * Register the bytes of an ICC colour profile, for the `<profile>` of a document's `<assets>` whose `ref`, or with
72
+ * no ref whose name, is `name`: the press profile a PDF/X document names in `<output profile>`.
73
+ * @param {string} name
74
+ * @param {Uint8Array} bytes
75
+ */
76
+ load_profile(name, bytes) {
77
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
78
+ const len0 = WASM_VECTOR_LEN;
79
+ const ptr1 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
80
+ const len1 = WASM_VECTOR_LEN;
81
+ wasm.lpdfengine_load_profile(this.__wbg_ptr, ptr0, len0, ptr1, len1);
82
+ }
70
83
  /**
71
84
  * @param {string} license_key
72
85
  */
@@ -222,6 +235,20 @@ export class LpdfEngine {
222
235
  const len0 = WASM_VECTOR_LEN;
223
236
  wasm.lpdfengine_set_font_metrics(this.__wbg_ptr, ptr0, len0);
224
237
  }
238
+ /**
239
+ * Set the memory a render may allocate, in megabytes: 1024 when it isn't set. A render that needs more stops
240
+ * with an error that names the cap. What the engine holds before the render, such as its loaded fonts, doesn't
241
+ * count.
242
+ *
243
+ * Returns an error when `mb` is 0 or above 4096, the most 32-bit WebAssembly addresses.
244
+ * @param {number} mb
245
+ */
246
+ set_max_memory_mb(mb) {
247
+ const ret = wasm.lpdfengine_set_max_memory_mb(this.__wbg_ptr, mb);
248
+ if (ret[1]) {
249
+ throw takeFromExternrefTable0(ret[0]);
250
+ }
251
+ }
225
252
  /**
226
253
  * Set the current Unix timestamp (seconds) for license expiry checking.
227
254
  * Must be called before `render_pdf` when using a time-limited token.
@@ -231,6 +258,32 @@ export class LpdfEngine {
231
258
  set_now(unix) {
232
259
  wasm.lpdfengine_set_now(this.__wbg_ptr, unix);
233
260
  }
261
+ /**
262
+ * Draw PNG stamps over the pages of an existing PDF, and return the file with them added as an incremental
263
+ * update: the input, byte for byte, then the images and the pages they change. The original bytes stay as they
264
+ * were, so an owner password and its permissions stay, and so does a digital signature's revision.
265
+ *
266
+ * `stamps` is a JSON list of stamps, each with an `image`, the name of a PNG loaded with `load_image`, a `page`
267
+ * scope, a box (`x`, `y`, `anchor`, `width`, `height`, placed as a layer element is) and how the image sits in it
268
+ * (`align`, `justify`, `scale`, `max-grow`). Without a valid license key, each stamped page gets the attribution
269
+ * line of a render in its top-right corner.
270
+ * @param {Uint8Array} pdf
271
+ * @param {string} stamps
272
+ * @returns {Uint8Array}
273
+ */
274
+ stamp(pdf, stamps) {
275
+ const ptr0 = passArray8ToWasm0(pdf, wasm.__wbindgen_malloc);
276
+ const len0 = WASM_VECTOR_LEN;
277
+ const ptr1 = passStringToWasm0(stamps, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
278
+ const len1 = WASM_VECTOR_LEN;
279
+ const ret = wasm.lpdfengine_stamp(this.__wbg_ptr, ptr0, len0, ptr1, len1);
280
+ if (ret[3]) {
281
+ throw takeFromExternrefTable0(ret[2]);
282
+ }
283
+ var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
284
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
285
+ return v3;
286
+ }
234
287
  }
235
288
  if (Symbol.dispose) LpdfEngine.prototype[Symbol.dispose] = LpdfEngine.prototype.free;
236
289
 
@@ -279,7 +332,7 @@ export function check_license(token, now_unix) {
279
332
  * in multiple target languages.
280
333
  *
281
334
  * `options_json` accepts the same shape as `codegen_wasm`:
282
- * - `target`: `"js"`, `"dotnet"`, `"php"`, or `"python"` (required)
335
+ * - `target`: `"js"`, `"dotnet"`, `"php"`, `"python"` or `"java"` (required)
283
336
  * - `indent`: `2` or `4` (optional, default `4`)
284
337
  * @param {string} xml
285
338
  * @param {string} options_json
@@ -312,7 +365,7 @@ export function codegen_fragment_wasm(xml, options_json) {
312
365
  * Generate SDK source code from an Lpdf XML string.
313
366
  *
314
367
  * `options_json` is a JSON object with:
315
- * - `target`: `"js"` (required)
368
+ * - `target`: `"js"`, `"dotnet"`, `"php"`, `"python"` or `"java"` (required)
316
369
  * - `indent`: `2` or `4` (optional, default `4`)
317
370
  *
318
371
  * Returns the generated source code as a string.
@@ -505,6 +558,9 @@ function __wbg_get_imports() {
505
558
  __wbg___wbindgen_throw_6b64449b9b9ed33c: function(arg0, arg1) {
506
559
  throw new Error(getStringFromWasm0(arg0, arg1));
507
560
  },
561
+ __wbg_getRandomValues_cc7f052a444bb2ce: function() { return handleError(function (arg0, arg1) {
562
+ globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));
563
+ }, arguments); },
508
564
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
509
565
  // Cast intrinsic for `Ref(String) -> Externref`.
510
566
  const ret = getStringFromWasm0(arg0, arg1);
@@ -530,6 +586,12 @@ const LpdfEngineFinalization = (typeof FinalizationRegistry === 'undefined')
530
586
  ? { register: () => {}, unregister: () => {} }
531
587
  : new FinalizationRegistry(ptr => wasm.__wbg_lpdfengine_free(ptr >>> 0, 1));
532
588
 
589
+ function addToExternrefTable0(obj) {
590
+ const idx = wasm.__externref_table_alloc();
591
+ wasm.__wbindgen_externrefs.set(idx, obj);
592
+ return idx;
593
+ }
594
+
533
595
  function getArrayU8FromWasm0(ptr, len) {
534
596
  ptr = ptr >>> 0;
535
597
  return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
@@ -548,6 +610,15 @@ function getUint8ArrayMemory0() {
548
610
  return cachedUint8ArrayMemory0;
549
611
  }
550
612
 
613
+ function handleError(f, args) {
614
+ try {
615
+ return f.apply(this, args);
616
+ } catch (e) {
617
+ const idx = addToExternrefTable0(e);
618
+ wasm.__wbindgen_exn_store(idx);
619
+ }
620
+ }
621
+
551
622
  function isLikeNone(x) {
552
623
  return x === undefined || x === null;
553
624
  }