fullbleed 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -7
- package/dist/THIRD_PARTY_NOTICES.txt +2 -2
- package/dist/build.json +7 -7
- package/dist/engine.wasm +0 -0
- package/package.json +4 -3
- package/src/index.cjs +10 -3
package/README.md
CHANGED
|
@@ -4,17 +4,24 @@ Generate PDFs from static HTML and CSS in Node.js. The package includes the
|
|
|
4
4
|
Fullbleed Rust engine compiled to WebAssembly and four font faces, so installing
|
|
5
5
|
it does not require Python, Rust, a browser, or system fonts. MIT licensed.
|
|
6
6
|
|
|
7
|
-
This is an optional integration around the unchanged **Fullbleed 2.5.
|
|
8
|
-
The Node package has its own version, **0.1.
|
|
7
|
+
This is an optional integration around the unchanged **Fullbleed 2.5.6** engine.
|
|
8
|
+
The Node package has its own version, **0.1.3**. Render promises now wait for their
|
|
9
|
+
worker to exit, including after errors, timeouts, and cancellation, so sequential
|
|
10
|
+
calls do not overlap worker lifetimes.
|
|
9
11
|
|
|
10
12
|
## Install and render
|
|
11
13
|
|
|
12
|
-
Use Node.js 22 or newer. Install the
|
|
14
|
+
Use Node.js 22 or newer. Install the [npm package](https://www.npmjs.com/package/fullbleed):
|
|
13
15
|
|
|
14
16
|
```bash
|
|
15
|
-
npm install
|
|
17
|
+
npm install fullbleed
|
|
16
18
|
```
|
|
17
19
|
|
|
20
|
+
For a version-pinned installation, use `npm install --save-exact fullbleed@0.1.3`.
|
|
21
|
+
The npm tarball is byte-identical to the verified
|
|
22
|
+
[GitHub release](https://github.com/fullbleed-engine/fullbleed-node/releases/tag/v0.1.3).
|
|
23
|
+
See the [installation verification records](https://github.com/fullbleed-engine/fullbleed-node/tree/main/verification).
|
|
24
|
+
|
|
18
25
|
Save this as `invoice.mjs` and run `node invoice.mjs`:
|
|
19
26
|
|
|
20
27
|
```javascript
|
|
@@ -57,6 +64,14 @@ npm run example
|
|
|
57
64
|
Open `output/invoice/invoice.pdf` and `page-1.png`. The [three-page report
|
|
58
65
|
sources](examples/report.html) demonstrate pagination, tables, and vector artwork.
|
|
59
66
|
|
|
67
|
+
## Use it in Next.js
|
|
68
|
+
|
|
69
|
+
For a web application, start with the [Next.js PDF download example](examples/nextjs).
|
|
70
|
+
It includes a designed invoice, an App Router handler, production build settings
|
|
71
|
+
for the worker and bundled assets, and a standalone-server verification script.
|
|
72
|
+
The route bounds rendering and returns private PDF attachments from fictional
|
|
73
|
+
data; connect your own authenticated record lookup when adapting it.
|
|
74
|
+
|
|
60
75
|
## Fonts and assets
|
|
61
76
|
|
|
62
77
|
Supply file bytes explicitly. Additional fonts are registered alongside the
|
|
@@ -107,7 +122,12 @@ native engine.
|
|
|
107
122
|
| `allowMissingGlyphs` | Default `false`: reject engine-reported missing glyphs. |
|
|
108
123
|
|
|
109
124
|
Rendering runs in a dedicated worker. Concurrent calls use separate workers and
|
|
110
|
-
document state.
|
|
125
|
+
document state. The returned promise waits for that worker to exit on success,
|
|
126
|
+
render failure, timeout, or cancellation. Awaiting jobs in sequence therefore
|
|
127
|
+
does not overlap their worker lifetimes. A timeout or abort starts termination;
|
|
128
|
+
settlement includes the time needed to stop the worker.
|
|
129
|
+
|
|
130
|
+
Bound concurrency in a server according to its available memory;
|
|
111
131
|
each worker's WebAssembly memory has a 512 MiB ceiling. HTML and CSS together are
|
|
112
132
|
limited to 4,000,000 UTF-8 bytes; supplied fonts and assets together to 64 MiB.
|
|
113
133
|
Preview images can use substantially more memory than PDF-only rendering.
|
|
@@ -143,8 +163,9 @@ arbitrary browser pages.
|
|
|
143
163
|
|
|
144
164
|
## Build and verify from source
|
|
145
165
|
|
|
146
|
-
Contributors need Node.js 22+ and Rust 1.97.0 with the WASI target.
|
|
147
|
-
|
|
166
|
+
Contributors need Node.js 22+ and Rust 1.97.0 with the WASI target. The independent
|
|
167
|
+
PDF text check also uses Python with the test-only `pypdf==6.19.0` reader. Package
|
|
168
|
+
users do not need a compiler or Python. Dependencies are pinned in both lockfiles.
|
|
148
169
|
|
|
149
170
|
```bash
|
|
150
171
|
rustup target add wasm32-wasip1
|
|
@@ -154,6 +175,8 @@ npm test
|
|
|
154
175
|
npm run check:types
|
|
155
176
|
npm run verify:native
|
|
156
177
|
npm run verify:pack
|
|
178
|
+
python -m pip install pypdf==6.19.0
|
|
179
|
+
npm run verify:text
|
|
157
180
|
```
|
|
158
181
|
|
|
159
182
|
The build records engine metadata, licenses, and artifact hashes in `dist/`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
fullbleed 2.5.
|
|
1
|
+
fullbleed 2.5.6 / LICENSE
|
|
2
2
|
|
|
3
3
|
MIT License
|
|
4
4
|
|
|
@@ -23,7 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
23
23
|
SOFTWARE.
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
fullbleed 2.5.
|
|
26
|
+
fullbleed 2.5.6 / THIRD_PARTY_LICENSES.md
|
|
27
27
|
|
|
28
28
|
<!-- SPDX-License-Identifier: MIT -->
|
|
29
29
|
# Third-Party Licenses
|
package/dist/build.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"packageVersion": "0.1.
|
|
3
|
-
"engineVersion": "2.5.
|
|
4
|
-
"engineSource": "https://crates.io/crates/fullbleed/2.5.
|
|
2
|
+
"packageVersion": "0.1.3",
|
|
3
|
+
"engineVersion": "2.5.6",
|
|
4
|
+
"engineSource": "https://crates.io/crates/fullbleed/2.5.6",
|
|
5
5
|
"target": "wasm32-wasip1",
|
|
6
6
|
"memoryMaximumBytes": 536870912,
|
|
7
7
|
"fonts": [
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"dependencies": [
|
|
14
14
|
{
|
|
15
15
|
"name": "fullbleed",
|
|
16
|
-
"version": "2.5.
|
|
16
|
+
"version": "2.5.6",
|
|
17
17
|
"source": "registry+https://github.com/rust-lang/crates.io-index",
|
|
18
18
|
"license": "MIT"
|
|
19
19
|
},
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
],
|
|
45
45
|
"files": {
|
|
46
46
|
"dist/engine.wasm": {
|
|
47
|
-
"bytes":
|
|
48
|
-
"sha256": "
|
|
47
|
+
"bytes": 5053312,
|
|
48
|
+
"sha256": "20bc142538c5acf826b162531ed57541d410b033e3666a827934b89ef2fc84cb"
|
|
49
49
|
},
|
|
50
50
|
"dist/THIRD_PARTY_NOTICES.txt": {
|
|
51
51
|
"bytes": 57660,
|
|
52
|
-
"sha256": "
|
|
52
|
+
"sha256": "4a945a683c5f4be6a4c74b59f45aa1f5e6627022a80addddb6eaf68ed3916d9f"
|
|
53
53
|
},
|
|
54
54
|
"assets/fonts/BebasNeue-OFL.txt": {
|
|
55
55
|
"bytes": 4337,
|
package/dist/engine.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fullbleed",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Generate PDFs from HTML and CSS in Node.js with the Fullbleed Rust engine, bundled fonts, and optional PNG previews.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.cjs",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"check:types": "tsc -p tsconfig.json",
|
|
35
35
|
"verify:native": "node tools/verify-native.mjs",
|
|
36
36
|
"example": "node examples/invoice.mjs",
|
|
37
|
-
"verify:pack": "node tools/verify-pack.mjs"
|
|
37
|
+
"verify:pack": "node tools/verify-pack.mjs",
|
|
38
|
+
"verify:text": "python tools/verify-installed-text.py"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"@bjorn3/browser_wasi_shim": "0.4.2"
|
|
@@ -62,7 +63,7 @@
|
|
|
62
63
|
"access": "public"
|
|
63
64
|
},
|
|
64
65
|
"fullbleed": {
|
|
65
|
-
"engineVersion": "2.5.
|
|
66
|
+
"engineVersion": "2.5.6"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@types/node": "22.20.5",
|
package/src/index.cjs
CHANGED
|
@@ -87,13 +87,20 @@ async function renderPdf(options) {
|
|
|
87
87
|
if (remaining <= 0) throw new FullbleedError('TIMEOUT', `PDF rendering exceeded ${job.timeoutMs} ms.`);
|
|
88
88
|
return new Promise((resolve, reject) => {
|
|
89
89
|
let worker, timer, settled = false;
|
|
90
|
-
const finish = (error, result) => {
|
|
90
|
+
const finish = async (error, result) => {
|
|
91
91
|
if (settled) return;
|
|
92
92
|
settled = true;
|
|
93
93
|
clearTimeout(timer);
|
|
94
94
|
job.signal?.removeEventListener('abort', abort);
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
// A process 'worker' listener can abort synchronously inside the Worker
|
|
96
|
+
// constructor. Let that constructor assign its handle before cleanup.
|
|
97
|
+
await Promise.resolve();
|
|
98
|
+
try {
|
|
99
|
+
await worker?.terminate();
|
|
100
|
+
} catch (cause) {
|
|
101
|
+
reject(new FullbleedError('WORKER_FAILED', 'Could not stop the rendering worker.', { cause }));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
97
104
|
if (error) reject(error); else resolve(result);
|
|
98
105
|
};
|
|
99
106
|
const abort = () => finish(aborted());
|