fullbleed 0.1.2 → 0.1.4

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
@@ -4,9 +4,11 @@ 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.6** engine.
8
- The Node package has its own version, **0.1.2**. This patch keeps synthesized-bold
9
- headings searchable once instead of exposing duplicate text to PDF readers.
7
+ This is an optional integration around the published **Fullbleed 2.5.7** engine.
8
+ The Node package has its own version, **0.1.4**. This release reduces embedded
9
+ font metadata while preserving the retained glyph outlines, metrics, and font
10
+ notices. See the [installed-package font checks](docs/font-subsets.md) for the
11
+ fixtures and verification commands.
10
12
 
11
13
  ## Install and render
12
14
 
@@ -16,9 +18,9 @@ Use Node.js 22 or newer. Install the [npm package](https://www.npmjs.com/package
16
18
  npm install fullbleed
17
19
  ```
18
20
 
19
- For a version-pinned installation, use `npm install --save-exact fullbleed@0.1.2`.
21
+ For a version-pinned installation, use `npm install --save-exact fullbleed@0.1.4`.
20
22
  The npm tarball is byte-identical to the verified
21
- [GitHub release](https://github.com/fullbleed-engine/fullbleed-node/releases/tag/v0.1.2).
23
+ [GitHub release](https://github.com/fullbleed-engine/fullbleed-node/releases/tag/v0.1.4).
22
24
  See the [installation verification records](https://github.com/fullbleed-engine/fullbleed-node/tree/main/verification).
23
25
 
24
26
  Save this as `invoice.mjs` and run `node invoice.mjs`:
@@ -121,7 +123,12 @@ native engine.
121
123
  | `allowMissingGlyphs` | Default `false`: reject engine-reported missing glyphs. |
122
124
 
123
125
  Rendering runs in a dedicated worker. Concurrent calls use separate workers and
124
- document state. Bound concurrency in a server according to its available memory;
126
+ document state. The returned promise waits for that worker to exit on success,
127
+ render failure, timeout, or cancellation. Awaiting jobs in sequence therefore
128
+ does not overlap their worker lifetimes. A timeout or abort starts termination;
129
+ settlement includes the time needed to stop the worker.
130
+
131
+ Bound concurrency in a server according to its available memory;
125
132
  each worker's WebAssembly memory has a 512 MiB ceiling. HTML and CSS together are
126
133
  limited to 4,000,000 UTF-8 bytes; supplied fonts and assets together to 64 MiB.
127
134
  Preview images can use substantially more memory than PDF-only rendering.
@@ -158,8 +165,8 @@ arbitrary browser pages.
158
165
  ## Build and verify from source
159
166
 
160
167
  Contributors need Node.js 22+ and Rust 1.97.0 with the WASI target. The independent
161
- PDF text check also uses Python with the test-only `pypdf==6.19.0` reader. Package
162
- users do not need a compiler or Python. Dependencies are pinned in both lockfiles.
168
+ PDF checks also use Python with the test-only readers listed below. Package users
169
+ do not need a compiler or Python. Dependencies are pinned in both lockfiles.
163
170
 
164
171
  ```bash
165
172
  rustup target add wasm32-wasip1
@@ -169,8 +176,10 @@ npm test
169
176
  npm run check:types
170
177
  npm run verify:native
171
178
  npm run verify:pack
172
- python -m pip install pypdf==6.19.0
179
+ python -m pip install pypdf==6.19.0 pypdfium2==5.14.0 fonttools==4.65.0 pillow==12.3.0
173
180
  npm run verify:text
181
+ npm run render:fonts
182
+ npm run verify:fonts
174
183
  ```
175
184
 
176
185
  The build records engine metadata, licenses, and artifact hashes in `dist/`.
@@ -179,6 +188,16 @@ fonts, and image assets; compares native and WebAssembly PDF/PNG bytes; checks
179
188
  error recovery; and installs the packed tarball into a separate directory with
180
189
  spaces in its path. CI exercises Node 22, 24, and 26 on Windows, Linux, and macOS.
181
190
  Retained release evidence describes the verified fixtures and scope.
191
+ The font check reads PDFs from the isolated tarball installation, checks the
192
+ embedded TrueType programs against their source fonts, and compares two
193
+ independent text readers. CI also compares text and native/PDFium pixels with
194
+ the previous public npm release.
195
+
196
+ An intermittent process crash observed on Linux with Node 24.21.0 remains under
197
+ investigation in [issue #7](https://github.com/fullbleed-engine/fullbleed-node/issues/7).
198
+ Version 0.1.3 fixes worker shutdown timing, but does not establish that this crash
199
+ is resolved. See the [runtime investigation and diagnostic](docs/runtime-diagnostics.md)
200
+ for the observed scope, retained results, and a synthetic reproducer.
182
201
 
183
202
  ## License and support
184
203
 
@@ -1,4 +1,4 @@
1
- fullbleed 2.5.6 / LICENSE
1
+ fullbleed 2.5.7 / 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.6 / THIRD_PARTY_LICENSES.md
26
+ fullbleed 2.5.7 / 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.2",
3
- "engineVersion": "2.5.6",
4
- "engineSource": "https://crates.io/crates/fullbleed/2.5.6",
2
+ "packageVersion": "0.1.4",
3
+ "engineVersion": "2.5.7",
4
+ "engineSource": "https://crates.io/crates/fullbleed/2.5.7",
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.6",
16
+ "version": "2.5.7",
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": 5053312,
48
- "sha256": "2e9c27d67f21483df2e9e63414346eb01170ae5a8ba4a04f48c0a7d647a577a6"
47
+ "bytes": 5064368,
48
+ "sha256": "3b5b0200268264b947f7b5bdc658a2d32d9fd160b8652f0ee6834e5296db9abb"
49
49
  },
50
50
  "dist/THIRD_PARTY_NOTICES.txt": {
51
51
  "bytes": 57660,
52
- "sha256": "4a945a683c5f4be6a4c74b59f45aa1f5e6627022a80addddb6eaf68ed3916d9f"
52
+ "sha256": "90c2828609b2a61323dfd97564a023123e38e1df7c9e9a9db0a29bb12aad1438"
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.2",
3
+ "version": "0.1.4",
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",
@@ -35,7 +35,9 @@
35
35
  "verify:native": "node tools/verify-native.mjs",
36
36
  "example": "node examples/invoice.mjs",
37
37
  "verify:pack": "node tools/verify-pack.mjs",
38
- "verify:text": "python tools/verify-installed-text.py"
38
+ "verify:text": "python tools/verify-installed-text.py",
39
+ "render:fonts": "node tools/render-font-subsets.mjs",
40
+ "verify:fonts": "python tools/verify-font-subsets.py"
39
41
  },
40
42
  "dependencies": {
41
43
  "@bjorn3/browser_wasi_shim": "0.4.2"
@@ -63,7 +65,7 @@
63
65
  "access": "public"
64
66
  },
65
67
  "fullbleed": {
66
- "engineVersion": "2.5.6"
68
+ "engineVersion": "2.5.7"
67
69
  },
68
70
  "devDependencies": {
69
71
  "@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
- const termination = worker?.terminate();
96
- if (termination) termination.catch(() => {});
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());