@pdfluent/sdk-wasm 1.0.0-beta.10
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/LICENSE +242 -0
- package/README.md +321 -0
- package/package.json +30 -0
- package/xfa_wasm.d.ts +526 -0
- package/xfa_wasm.js +2086 -0
- package/xfa_wasm_bg.wasm +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
PDFluent Commercial License
|
|
2
|
+
Version 1.0
|
|
3
|
+
Effective: 2026-05-02
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2026 Innovation Trigger BV (operating as PDFluent).
|
|
6
|
+
All rights reserved.
|
|
7
|
+
|
|
8
|
+
IMPORTANT — READ CAREFULLY. This is a legal agreement between you ("Licensee")
|
|
9
|
+
and Innovation Trigger BV, a private limited company organized under the laws
|
|
10
|
+
of the Netherlands and operating under the trade name "PDFluent" ("PDFluent",
|
|
11
|
+
"we", "us"). By installing, copying, downloading, or otherwise using the
|
|
12
|
+
Software, you agree to be bound by the terms of this License. If you do not
|
|
13
|
+
agree, do not install or use the Software.
|
|
14
|
+
|
|
15
|
+
This License governs the use of all Rust crates published by PDFluent that
|
|
16
|
+
reference this LICENSE file in their Cargo manifest. PDFluent also publishes
|
|
17
|
+
separate crates under permissive open-source licenses (MIT or Apache-2.0);
|
|
18
|
+
those crates are NOT governed by this License and may be used under their
|
|
19
|
+
respective open-source terms. See the NOTICE file for the list of crates
|
|
20
|
+
covered by each license.
|
|
21
|
+
|
|
22
|
+
----------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
1. DEFINITIONS
|
|
25
|
+
|
|
26
|
+
"Software" means the source code, compiled object code, binary artefacts,
|
|
27
|
+
and accompanying documentation of the PDFluent crates that reference this
|
|
28
|
+
LICENSE file.
|
|
29
|
+
|
|
30
|
+
"Production Use" means any use of the Software in connection with the
|
|
31
|
+
operation of a business or for the benefit of a third party, including
|
|
32
|
+
without limitation: (a) processing data of customers, clients, or other
|
|
33
|
+
third parties; (b) integration into a commercial product, service, or
|
|
34
|
+
internal business application; (c) deployment in a production environment.
|
|
35
|
+
|
|
36
|
+
"Evaluation Use" means use of the Software solely for the purpose of
|
|
37
|
+
evaluating its suitability for Production Use, including in development,
|
|
38
|
+
testing, demonstration, and non-public staging environments. Evaluation
|
|
39
|
+
Use does not include any form of Production Use.
|
|
40
|
+
|
|
41
|
+
"Valid License" means a current and active license entitlement issued by
|
|
42
|
+
PDFluent or an authorized reseller, identified by an Ed25519-signed
|
|
43
|
+
license key file or by other written commercial terms agreed with
|
|
44
|
+
PDFluent.
|
|
45
|
+
|
|
46
|
+
"Authorized Use" means the scope of Production Use granted under a Valid
|
|
47
|
+
License, including the number of developers, locations, products, and
|
|
48
|
+
deployment configurations described in the commercial terms applicable to
|
|
49
|
+
that Valid License.
|
|
50
|
+
|
|
51
|
+
----------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
2. EVALUATION GRANT
|
|
54
|
+
|
|
55
|
+
Subject to compliance with this License, PDFluent grants Licensee a
|
|
56
|
+
non-exclusive, non-transferable, worldwide, royalty-free license to:
|
|
57
|
+
|
|
58
|
+
(a) install and use the Software for Evaluation Use; and
|
|
59
|
+
|
|
60
|
+
(b) make a reasonable number of internal copies of the Software for the
|
|
61
|
+
sole purpose of supporting Evaluation Use.
|
|
62
|
+
|
|
63
|
+
The Software, when used without a Valid License, may produce output that
|
|
64
|
+
contains identifying markers indicating that the output was generated by
|
|
65
|
+
an unlicensed copy of the Software (including but not limited to a
|
|
66
|
+
"Producer" string in PDF metadata and a one-time warning emitted to
|
|
67
|
+
standard error). Licensee shall not remove, modify, suppress, or
|
|
68
|
+
circumvent these markers, nor any license-enforcement mechanism within
|
|
69
|
+
the Software.
|
|
70
|
+
|
|
71
|
+
----------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
3. PRODUCTION GRANT
|
|
74
|
+
|
|
75
|
+
Production Use of the Software is permitted ONLY when Licensee holds a
|
|
76
|
+
Valid License covering the intended use. The scope of Production Use
|
|
77
|
+
permitted is determined by the Valid License and by the commercial terms
|
|
78
|
+
referenced therein. The current commercial terms, including pricing,
|
|
79
|
+
tiers, add-ons, and definitions of permitted use, are published at:
|
|
80
|
+
|
|
81
|
+
https://pdfluent.com/terms
|
|
82
|
+
https://pdfluent.com/pricing
|
|
83
|
+
|
|
84
|
+
Production Use exceeding the Authorized Use of the applicable Valid
|
|
85
|
+
License is a material breach of this License.
|
|
86
|
+
|
|
87
|
+
----------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
4. RESTRICTIONS
|
|
90
|
+
|
|
91
|
+
Except as expressly permitted by this License or by a separately
|
|
92
|
+
negotiated written agreement with PDFluent, Licensee shall not:
|
|
93
|
+
|
|
94
|
+
(a) use the Software in Production Use without a Valid License;
|
|
95
|
+
|
|
96
|
+
(b) remove, disable, alter, or circumvent any license-enforcement,
|
|
97
|
+
watermarking, telemetry, or attribution mechanism contained in the
|
|
98
|
+
Software;
|
|
99
|
+
|
|
100
|
+
(c) redistribute, publish, sell, sublicense, lease, rent, or otherwise
|
|
101
|
+
make the Software available to any third party, except under a
|
|
102
|
+
separately purchased OEM Redistribution add-on as described in the
|
|
103
|
+
commercial terms;
|
|
104
|
+
|
|
105
|
+
(d) reverse engineer, decompile, or disassemble the Software, except to
|
|
106
|
+
the limited extent that such activity is expressly permitted by
|
|
107
|
+
applicable law notwithstanding this restriction;
|
|
108
|
+
|
|
109
|
+
(e) modify the Software with the intent of, or in a manner that has the
|
|
110
|
+
effect of, evading any restriction in this License;
|
|
111
|
+
|
|
112
|
+
(f) remove, obscure, or alter any copyright, trademark, attribution, or
|
|
113
|
+
other proprietary notices contained in the Software or its
|
|
114
|
+
documentation; or
|
|
115
|
+
|
|
116
|
+
(g) redistribute, sublicense, expose, or offer the Software as a
|
|
117
|
+
standalone SDK, library, API, platform, service, or substantially
|
|
118
|
+
similar substitute for PDFluent, except as expressly permitted under
|
|
119
|
+
an OEM Redistribution add-on.
|
|
120
|
+
|
|
121
|
+
For clarity, restriction (g) is intended to prevent re-packaging or
|
|
122
|
+
re-offering the Software (in whole or in substantial part) as a competing
|
|
123
|
+
PDF SDK or service. It does not restrict Licensee from using the Software
|
|
124
|
+
inside its own application, product, or service that delivers
|
|
125
|
+
functionality beyond what the Software itself provides.
|
|
126
|
+
|
|
127
|
+
----------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
5. RESERVATION OF RIGHTS
|
|
130
|
+
|
|
131
|
+
The Software is licensed, not sold. Title, ownership, and all
|
|
132
|
+
intellectual property rights in and to the Software remain at all times
|
|
133
|
+
with PDFluent and its licensors. All rights not expressly granted under
|
|
134
|
+
this License are reserved by PDFluent.
|
|
135
|
+
|
|
136
|
+
Feedback, suggestions, or improvements that Licensee voluntarily provides
|
|
137
|
+
to PDFluent regarding the Software may be used by PDFluent without
|
|
138
|
+
restriction, without obligation of confidentiality, and without
|
|
139
|
+
compensation to Licensee.
|
|
140
|
+
|
|
141
|
+
----------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
6. THIRD-PARTY COMPONENTS
|
|
144
|
+
|
|
145
|
+
The Software may include or depend upon third-party components,
|
|
146
|
+
including upstream open-source crates from which certain PDFluent crates
|
|
147
|
+
are derived. Such components remain subject to their respective licenses,
|
|
148
|
+
which are reproduced in the THIRD_PARTY_LICENSES.txt file accompanying
|
|
149
|
+
the Software. Nothing in this License is intended to limit or override
|
|
150
|
+
any rights granted under those third-party licenses with respect to those
|
|
151
|
+
third-party components.
|
|
152
|
+
|
|
153
|
+
----------------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
7. NO WARRANTY
|
|
156
|
+
|
|
157
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
158
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
159
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
|
|
160
|
+
NON-INFRINGEMENT. PDFLUENT DOES NOT WARRANT THAT THE SOFTWARE WILL MEET
|
|
161
|
+
LICENSEE'S REQUIREMENTS, OPERATE WITHOUT INTERRUPTION, OR BE FREE OF
|
|
162
|
+
ERRORS OR DEFECTS.
|
|
163
|
+
|
|
164
|
+
----------------------------------------------------------------------------
|
|
165
|
+
|
|
166
|
+
8. LIMITATION OF LIABILITY
|
|
167
|
+
|
|
168
|
+
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
|
169
|
+
PDFLUENT OR ITS CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
|
|
170
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED
|
|
171
|
+
TO PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR
|
|
172
|
+
PROFITS, OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
173
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
174
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
|
|
175
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
176
|
+
|
|
177
|
+
PDFLUENT'S TOTAL CUMULATIVE LIABILITY UNDER OR IN CONNECTION WITH THIS
|
|
178
|
+
LICENSE SHALL NOT EXCEED THE GREATER OF (i) THE FEES PAID BY LICENSEE TO
|
|
179
|
+
PDFLUENT UNDER THE APPLICABLE VALID LICENSE IN THE TWELVE (12) MONTHS
|
|
180
|
+
IMMEDIATELY PRECEDING THE EVENT GIVING RISE TO LIABILITY, OR (ii) ONE
|
|
181
|
+
HUNDRED EUROS (€100).
|
|
182
|
+
|
|
183
|
+
----------------------------------------------------------------------------
|
|
184
|
+
|
|
185
|
+
9. TERMINATION
|
|
186
|
+
|
|
187
|
+
This License is effective until terminated. This License terminates
|
|
188
|
+
automatically and without notice if Licensee fails to comply with any
|
|
189
|
+
term of this License. Upon termination, Licensee shall cease all use of
|
|
190
|
+
the Software, destroy all copies in its possession or control, and, on
|
|
191
|
+
request, certify such destruction in writing to PDFluent.
|
|
192
|
+
|
|
193
|
+
Sections 4 (Restrictions), 5 (Reservation of Rights), 7 (No Warranty),
|
|
194
|
+
8 (Limitation of Liability), 10 (Governing Law), and 11 (Entire
|
|
195
|
+
Agreement) survive any termination of this License.
|
|
196
|
+
|
|
197
|
+
----------------------------------------------------------------------------
|
|
198
|
+
|
|
199
|
+
10. GOVERNING LAW AND JURISDICTION
|
|
200
|
+
|
|
201
|
+
This License shall be governed by and construed in accordance with the
|
|
202
|
+
laws of the Netherlands, excluding its conflict-of-laws provisions and
|
|
203
|
+
the United Nations Convention on Contracts for the International Sale
|
|
204
|
+
of Goods. The courts of Amsterdam, the Netherlands, shall have
|
|
205
|
+
exclusive jurisdiction over any dispute arising from or in connection
|
|
206
|
+
with this License, except that PDFluent may seek injunctive relief in
|
|
207
|
+
any court of competent jurisdiction to protect its intellectual
|
|
208
|
+
property rights.
|
|
209
|
+
|
|
210
|
+
----------------------------------------------------------------------------
|
|
211
|
+
|
|
212
|
+
11. ENTIRE AGREEMENT
|
|
213
|
+
|
|
214
|
+
This License, together with any Valid License terms and any commercial
|
|
215
|
+
terms expressly incorporated by reference, constitutes the entire
|
|
216
|
+
agreement between Licensee and PDFluent with respect to the Software
|
|
217
|
+
and supersedes all prior or contemporaneous communications,
|
|
218
|
+
representations, or agreements, whether oral or written. No
|
|
219
|
+
modification or amendment of this License shall be effective unless in
|
|
220
|
+
writing and signed by an authorized representative of PDFluent.
|
|
221
|
+
|
|
222
|
+
----------------------------------------------------------------------------
|
|
223
|
+
|
|
224
|
+
CONTACT
|
|
225
|
+
|
|
226
|
+
Innovation Trigger BV
|
|
227
|
+
Operating as PDFluent
|
|
228
|
+
Email: hello@pdfluent.com
|
|
229
|
+
Web: https://pdfluent.com
|
|
230
|
+
|
|
231
|
+
For commercial terms, pricing, evaluation policies, trial keys, and OEM
|
|
232
|
+
licensing options, visit https://pdfluent.com/pricing.
|
|
233
|
+
|
|
234
|
+
----------------------------------------------------------------------------
|
|
235
|
+
|
|
236
|
+
NOTE ON HISTORICAL VERSIONS
|
|
237
|
+
|
|
238
|
+
Versions of PDFluent crates published to crates.io prior to 2026-05-02
|
|
239
|
+
under the MIT license remain available under the MIT license. This License
|
|
240
|
+
applies to versions published on or after that date that reference this
|
|
241
|
+
LICENSE file in their Cargo manifest. See CHANGELOG.md for the version
|
|
242
|
+
boundary.
|
package/README.md
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# PDFluent browser SDK (WASM)
|
|
2
|
+
|
|
3
|
+
WebAssembly distribution of the PDFluent PDF engine. Read, edit, annotate,
|
|
4
|
+
redact, sign, and validate PDFs (including XFA) entirely in the browser —
|
|
5
|
+
zero bytes go to a server.
|
|
6
|
+
|
|
7
|
+
Published as `@pdfluent/xfa-wasm` on npm. (Crate name reflects historical
|
|
8
|
+
XFA roots; the package now covers the full SDK surface needed for an
|
|
9
|
+
in-browser PDF editor.)
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **XFA Forms**: Parse, calculate, import/export XFA form data
|
|
14
|
+
- **PDF Analysis**: Metadata, signatures, PDF/A compliance validation
|
|
15
|
+
- **Page Rendering** (feature `render`): Render pages to RGBA pixels or Canvas2D
|
|
16
|
+
- **Page Manipulation**: delete, rotate, reorder, extract, split via re-extract, merge
|
|
17
|
+
- **Forms write-back**: set AcroForm field values, save modified PDF bytes
|
|
18
|
+
- **Annotations** (feature `annotate`): highlight, sticky note, free text
|
|
19
|
+
- **Text watermark**: diagonal text watermark with configurable opacity
|
|
20
|
+
- **Redaction**: by region (rectangle) or by search query (GDPR-safe permanent removal)
|
|
21
|
+
- **Stream compression**: re-deflate content streams for smaller file size
|
|
22
|
+
- **License activation**: process-global tier activation via key string or file
|
|
23
|
+
- **`PdfDocMut`** (Wave 3): stateful editing handle — open once, mutate in
|
|
24
|
+
place, save once. 2.7× faster than the stateless `PdfDoc` chain for
|
|
25
|
+
multi-step edits, identical output bytes.
|
|
26
|
+
|
|
27
|
+
## Building
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Install wasm-pack
|
|
31
|
+
cargo install wasm-pack
|
|
32
|
+
|
|
33
|
+
# Build the WASM package
|
|
34
|
+
wasm-pack build crates/@pdfluent/wasm --target web
|
|
35
|
+
|
|
36
|
+
# Without rendering (smaller bundle)
|
|
37
|
+
wasm-pack build crates/@pdfluent/wasm --target web -- --no-default-features
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### XFA Forms
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import init, { XfaEngine } from './pkg/xfa_wasm';
|
|
46
|
+
|
|
47
|
+
await init();
|
|
48
|
+
|
|
49
|
+
const engine = XfaEngine.fromFields(JSON.stringify([
|
|
50
|
+
{ name: "Name", value: "Alice" },
|
|
51
|
+
{ name: "Total", value: "", calculate: "100 + 21" },
|
|
52
|
+
]));
|
|
53
|
+
|
|
54
|
+
engine.runCalculations();
|
|
55
|
+
console.log(engine.getFieldValue("form1.Total")); // "121"
|
|
56
|
+
|
|
57
|
+
const json = engine.exportJson();
|
|
58
|
+
engine.importJson('{"fields": {"form1.Name": "Bob"}}');
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### PDF Analysis
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import init, { PdfDoc } from './pkg/xfa_wasm';
|
|
65
|
+
|
|
66
|
+
await init();
|
|
67
|
+
|
|
68
|
+
const response = await fetch('document.pdf');
|
|
69
|
+
const data = new Uint8Array(await response.arrayBuffer());
|
|
70
|
+
const doc = PdfDoc.open(data);
|
|
71
|
+
|
|
72
|
+
console.log(`Pages: ${doc.pageCount()}`);
|
|
73
|
+
|
|
74
|
+
// Metadata
|
|
75
|
+
const meta = JSON.parse(doc.metadata());
|
|
76
|
+
console.log(`Title: ${meta.title}`);
|
|
77
|
+
|
|
78
|
+
// Signatures
|
|
79
|
+
if (doc.hasSignatures()) {
|
|
80
|
+
const sigs = JSON.parse(doc.verifySignatures());
|
|
81
|
+
for (const sig of sigs) {
|
|
82
|
+
console.log(`${sig.signer}: integrity ${sig.structural_integrity}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// PDF/A validation
|
|
87
|
+
const report = JSON.parse(doc.validatePdfA("pdfa2b"));
|
|
88
|
+
console.log(`Compliant: ${report.compliant}`);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Page Rendering
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
const raw = doc.renderPage(0, 1.5); // scale factor
|
|
95
|
+
const view = new DataView(raw.buffer);
|
|
96
|
+
const w = view.getUint32(0, true); // little-endian
|
|
97
|
+
const h = view.getUint32(4, true);
|
|
98
|
+
const pixels = raw.slice(8);
|
|
99
|
+
const imageData = new ImageData(new Uint8ClampedArray(pixels), w, h);
|
|
100
|
+
ctx.putImageData(imageData, 0, 0);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Annotations
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
// Read existing annotations
|
|
107
|
+
const annots = JSON.parse(doc.getAnnotations(0));
|
|
108
|
+
for (const a of annots) {
|
|
109
|
+
console.log(`${a.subtype} at (${a.rect?.x0}, ${a.rect?.y0})`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Add a highlight (returns new PDF bytes)
|
|
113
|
+
const newPdf = PdfDoc.addHighlight(pdfBytes, 0,
|
|
114
|
+
100, 700, 400, 720, // rect: x0, y0, x1, y1
|
|
115
|
+
1.0, 1.0, 0.0); // color: yellow RGB
|
|
116
|
+
|
|
117
|
+
// Add a sticky note
|
|
118
|
+
const withNote = PdfDoc.addStickyNote(pdfBytes, 0,
|
|
119
|
+
50, 750, "Review this section");
|
|
120
|
+
|
|
121
|
+
// Add free text
|
|
122
|
+
const withText = PdfDoc.addFreeText(pdfBytes, 0,
|
|
123
|
+
100, 600, 300, 620, "Important!", 12.0);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## TypeScript Support
|
|
127
|
+
|
|
128
|
+
Typed wrappers are provided in `ts/index.ts`:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { XfaForms, PdfDocument, FieldDef } from './ts/index';
|
|
132
|
+
|
|
133
|
+
const fields: FieldDef[] = [
|
|
134
|
+
{ name: "Amount", value: "100" },
|
|
135
|
+
];
|
|
136
|
+
const forms = XfaForms.fromFields(fields);
|
|
137
|
+
forms.runCalculations();
|
|
138
|
+
const data = forms.exportJson();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Features
|
|
142
|
+
|
|
143
|
+
| Feature | Default | Description |
|
|
144
|
+
|---------|---------|-------------|
|
|
145
|
+
| `render` | Yes | Page rendering via pdf-render |
|
|
146
|
+
| `annotate` | Yes | Annotation read/write via pdf-annot + lopdf |
|
|
147
|
+
|
|
148
|
+
Build without optional features for a smaller WASM binary:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
wasm-pack build crates/@pdfluent/wasm --target web -- --no-default-features
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## API Reference
|
|
155
|
+
|
|
156
|
+
### XfaEngine
|
|
157
|
+
|
|
158
|
+
| Method | Description |
|
|
159
|
+
|--------|-------------|
|
|
160
|
+
| `XfaEngine.fromFields(json)` | Create from JSON field definitions |
|
|
161
|
+
| `XfaEngine.fromJson(json)` | Create from exported JSON |
|
|
162
|
+
| `runCalculations()` | Execute FormCalc calculate scripts |
|
|
163
|
+
| `exportJson()` | Export field values as JSON |
|
|
164
|
+
| `exportSchema()` | Export form schema as JSON |
|
|
165
|
+
| `importJson(json)` | Import field values from JSON |
|
|
166
|
+
| `getFieldValue(path)` | Get field value by SOM path |
|
|
167
|
+
| `setFieldValue(path, value)` | Set field value by SOM path |
|
|
168
|
+
| `nodeCount()` | Number of form nodes |
|
|
169
|
+
| `version()` | Engine version string |
|
|
170
|
+
|
|
171
|
+
### License Activation
|
|
172
|
+
|
|
173
|
+
The WASM build runs in Trial mode by default. Output produced by the engine
|
|
174
|
+
is marked via `/Producer` metadata in Trial. Activate a license to remove
|
|
175
|
+
the mark and unlock paid capabilities.
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
import init, { activateLicenseKey, licenseStatus } from '@pdfluent/xfa-wasm';
|
|
179
|
+
|
|
180
|
+
await init();
|
|
181
|
+
activateLicenseKey('tier:enterprise');
|
|
182
|
+
|
|
183
|
+
const s = licenseStatus();
|
|
184
|
+
console.log(s.tier); // "Enterprise"
|
|
185
|
+
console.log(s.source); // "Explicit" | "EnvVar" | "Default"
|
|
186
|
+
console.log(s.outputIsMarked); // false
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Browser-specific caveats:**
|
|
190
|
+
|
|
191
|
+
- `activateLicenseFile` is intentionally **not** exposed. Browsers and
|
|
192
|
+
Workers have no synchronous filesystem access. Fetch the key text
|
|
193
|
+
yourself (`await fetch(...).then(r => r.text())`) and pass it to
|
|
194
|
+
`activateLicenseKey`.
|
|
195
|
+
- The `PDFLUENT_LICENSE_KEY` environment variable is honoured only when a
|
|
196
|
+
Node host provides it; browsers do not expose process env vars.
|
|
197
|
+
- The active tier is **process-global and set-once** within a single WASM
|
|
198
|
+
instance. Activating a second time with a different tier throws; reload
|
|
199
|
+
the page or re-initialise the WASM module to switch tiers.
|
|
200
|
+
|
|
201
|
+
Invalid keys throw `Error`. The key string is never logged.
|
|
202
|
+
|
|
203
|
+
### PdfDoc
|
|
204
|
+
|
|
205
|
+
| Method | Description |
|
|
206
|
+
|--------|-------------|
|
|
207
|
+
| `PdfDoc.open(data)` | Open PDF from Uint8Array |
|
|
208
|
+
| `pageCount()` | Number of pages |
|
|
209
|
+
| `pageWidth(index)` | Page width in points |
|
|
210
|
+
| `pageHeight(index)` | Page height in points |
|
|
211
|
+
| `metadata()` | Document metadata as JSON |
|
|
212
|
+
| `signatures()` | Signature info as JSON array |
|
|
213
|
+
| `hasSignatures()` | Whether document has signatures |
|
|
214
|
+
| `verifySignatures()` | Verify signatures, returns JSON |
|
|
215
|
+
| `validatePdfA(level)` | PDF/A compliance check |
|
|
216
|
+
| `dssInfo()` | Document Security Store info |
|
|
217
|
+
| `renderPage(index, scale)` | Render page to RGBA (feature: render) |
|
|
218
|
+
| `renderThumbnail(index, maxDim)` | Render thumbnail (feature: render) |
|
|
219
|
+
| `renderPageToCanvas(canvas, index, scale)` | Render page directly to a Canvas2D (feature: render) |
|
|
220
|
+
| `getAnnotations(index)` | Read annotations as JSON (feature: annotate) |
|
|
221
|
+
| `getTextPositions(index)` | Per-glyph text positions as JSON |
|
|
222
|
+
| `merge(other)` | Append another PDF, returns merged bytes |
|
|
223
|
+
| `flattenXfa()` | Flatten XFA form fields into static PDF content |
|
|
224
|
+
| `convertToPdfa(level)` | Convert to PDF/A 1b/2b/3b, returns bytes |
|
|
225
|
+
|
|
226
|
+
### Page manipulation (Wave 2)
|
|
227
|
+
|
|
228
|
+
| Method | Description |
|
|
229
|
+
|--------|-------------|
|
|
230
|
+
| `deletePages(pages: Uint32Array)` | Remove the listed 0-based pages; returns new bytes |
|
|
231
|
+
| `rotatePage(pageIndex, degrees)` | Rotate one page by 90/180/270 (or negative); returns new bytes |
|
|
232
|
+
| `reorderPages(newOrder: Uint32Array)` | Permute pages; returns new bytes |
|
|
233
|
+
| `extractPages(pages: Uint32Array)` | Extract the listed pages into a new PDF (use for split) |
|
|
234
|
+
|
|
235
|
+
### Edit, annotate, redact, optimise (Wave 2)
|
|
236
|
+
|
|
237
|
+
| Method | Description |
|
|
238
|
+
|--------|-------------|
|
|
239
|
+
| `setFormField(path, value)` | Set a single AcroForm text field; returns new bytes |
|
|
240
|
+
| `setFormFields(jsonObject)` | Bulk-set form fields from a JSON `{path: value}` map |
|
|
241
|
+
| `addHighlight(pageIndex, x, y, w, h, colorHex?)` | Highlight annotation (feature: annotate) |
|
|
242
|
+
| `addStickyNote(pageIndex, x, y, contents)` | Sticky note annotation (feature: annotate) |
|
|
243
|
+
| `addFreeText(pageIndex, x, y, w, h, contents)` | Free-text annotation (feature: annotate) |
|
|
244
|
+
| `addTextWatermark(text, opacity)` | Diagonal text watermark on all pages |
|
|
245
|
+
| `redactRegion(pageIndex, x, y, w, h)` | Permanently remove content in a rectangle (GDPR-safe) |
|
|
246
|
+
| `redactSearch(query)` | Find all literal matches of `query` and redact each |
|
|
247
|
+
| `compress()` | Re-deflate content streams; returns optimised bytes |
|
|
248
|
+
|
|
249
|
+
### PdfDocMut (Wave 3) — **recommended for editor workflows**
|
|
250
|
+
|
|
251
|
+
`PdfDocMut` is a stateful editing handle. Open once, mutate in place,
|
|
252
|
+
save once. The `PdfDoc` class above is great for inspection and
|
|
253
|
+
single-shot transformations, but for an editor that applies multiple
|
|
254
|
+
operations to the same document, **`PdfDocMut` is dramatically faster**:
|
|
255
|
+
9-step sessions go from ~16 parse passes to **1 parse + 1 serialise**
|
|
256
|
+
(measured 2.7× wall-clock speedup; bigger on larger documents).
|
|
257
|
+
|
|
258
|
+
| Method | Description |
|
|
259
|
+
|--------|-------------|
|
|
260
|
+
| `PdfDocMut.open(bytes)` | Open for editing |
|
|
261
|
+
| `pageCount()` | Live page count after any mutations so far |
|
|
262
|
+
| `save()` | Serialise current state to `Uint8Array`. Non-consuming — keep editing after |
|
|
263
|
+
| `free()` | Release the WASM-side memory deterministically |
|
|
264
|
+
| `deletePages(pages)` | In place |
|
|
265
|
+
| `rotatePage(pageIndex, degrees)` | In place |
|
|
266
|
+
| `reorderPages(newOrder)` | In place |
|
|
267
|
+
| `extractPages(pages)` | Returns bytes for a NEW subdocument; current editor unchanged |
|
|
268
|
+
| `setFormField(path, value)` | In place |
|
|
269
|
+
| `setFormFields(jsonObject)` | In place, bulk |
|
|
270
|
+
| `addHighlight(pageIndex, x, y, w, h, colorHex?)` | In place (feature: annotate) |
|
|
271
|
+
| `addStickyNote(pageIndex, x, y, contents)` | In place (feature: annotate) |
|
|
272
|
+
| `addFreeText(pageIndex, x, y, w, h, contents)` | In place (feature: annotate) |
|
|
273
|
+
| `addTextWatermark(text, opacity)` | In place |
|
|
274
|
+
| `redactRegion(pageIndex, x, y, w, h)` | In place (GDPR-safe permanent removal) |
|
|
275
|
+
| `redactSearch(query)` | In place |
|
|
276
|
+
| `compress()` | In place |
|
|
277
|
+
|
|
278
|
+
#### Editor flow with PdfDocMut
|
|
279
|
+
|
|
280
|
+
```js
|
|
281
|
+
import init, { PdfDocMut } from '@pdfluent/xfa-wasm';
|
|
282
|
+
|
|
283
|
+
await init();
|
|
284
|
+
const bytes = new Uint8Array(await (await fetch('/document.pdf')).arrayBuffer());
|
|
285
|
+
const editor = PdfDocMut.open(bytes);
|
|
286
|
+
|
|
287
|
+
// All edits operate on the same internal lopdf::Document — no re-parse.
|
|
288
|
+
editor.reorderPages(new Uint32Array([1, 0, 2]));
|
|
289
|
+
editor.addTextWatermark('CONCEPT', 0.3);
|
|
290
|
+
editor.addHighlight(0, 100, 700, 200, 20, '#ffeb3b');
|
|
291
|
+
editor.redactSearch('John Doe');
|
|
292
|
+
editor.compress();
|
|
293
|
+
|
|
294
|
+
// Save once at the end.
|
|
295
|
+
const out = editor.save();
|
|
296
|
+
editor.free();
|
|
297
|
+
const blob = new Blob([out], { type: 'application/pdf' });
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
#### One-shot helpers on PdfDoc (kept for compatibility)
|
|
301
|
+
|
|
302
|
+
For a workflow with a single mutation, the stateless `PdfDoc` methods
|
|
303
|
+
are equally fine. They are kept for backward compatibility but the
|
|
304
|
+
recommended path for any multi-step edit is `PdfDocMut`.
|
|
305
|
+
|
|
306
|
+
```js
|
|
307
|
+
import init, { PdfDoc } from '@pdfluent/xfa-wasm';
|
|
308
|
+
await init();
|
|
309
|
+
const doc = PdfDoc.open(bytes);
|
|
310
|
+
const merged = doc.merge(otherBytes); // single op, one-shot
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Bundle size
|
|
314
|
+
|
|
315
|
+
| Build | Tarball | Unpacked |
|
|
316
|
+
|-------|---------|----------|
|
|
317
|
+
| 1.0.0-beta.8 (pre-Wave 2) | 3.6 MB | 10.2 MB |
|
|
318
|
+
| **1.0.0-beta.9 (Wave 2)** | **3.8 MB** | **~11 MB** |
|
|
319
|
+
|
|
320
|
+
Wave 2 added 13 new methods for ~0.2 MB of binary growth. Well under the
|
|
321
|
+
15 MB hard limit and well under the 5 MB gzipped soft target.
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pdfluent/sdk-wasm",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"description": "PDFluent browser SDK — read, edit, annotate, redact, sign, and validate PDFs (including XFA) entirely client-side via WASM.",
|
|
5
|
+
"version": "1.0.0-beta.10",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
7
|
+
"files": [
|
|
8
|
+
"xfa_wasm_bg.wasm",
|
|
9
|
+
"xfa_wasm.js",
|
|
10
|
+
"xfa_wasm.d.ts"
|
|
11
|
+
],
|
|
12
|
+
"main": "xfa_wasm.js",
|
|
13
|
+
"types": "xfa_wasm.d.ts",
|
|
14
|
+
"sideEffects": [
|
|
15
|
+
"./snippets/*"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"pdf",
|
|
19
|
+
"wasm",
|
|
20
|
+
"pdfluent",
|
|
21
|
+
"browser",
|
|
22
|
+
"sdk",
|
|
23
|
+
"xfa",
|
|
24
|
+
"forms",
|
|
25
|
+
"annotate",
|
|
26
|
+
"redact"
|
|
27
|
+
],
|
|
28
|
+
"homepage": "https://pdfluent.com",
|
|
29
|
+
"author": "Innovation Trigger BV <team@pdfluent.com>"
|
|
30
|
+
}
|