blitz-pdf 0.1.7 → 0.1.8
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 +43 -5
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/api.d.ts +2 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +31 -6
- package/dist/api.js.map +1 -1
- package/dist/browser.d.ts +2 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/node.d.ts +2 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +6 -2
- package/dist/node.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/worker-host.d.ts +10 -5
- package/dist/worker-host.d.ts.map +1 -1
- package/dist/worker-host.js +149 -28
- package/dist/worker-host.js.map +1 -1
- package/dist/worker-protocol.d.ts +5 -0
- package/dist/worker-protocol.d.ts.map +1 -1
- package/dist/worker-runtime.d.ts +1 -1
- package/dist/worker-runtime.d.ts.map +1 -1
- package/dist/worker-runtime.js +22 -6
- package/dist/worker-runtime.js.map +1 -1
- package/licenses/RUST_DEPENDENCIES.txt +34 -40
- package/package.json +1 -1
- package/src/api.ts +32 -7
- package/src/browser.ts +2 -1
- package/src/node.ts +7 -2
- package/src/types.ts +15 -0
- package/src/worker-host.ts +148 -29
- package/src/worker-protocol.ts +5 -5
- package/src/worker-runtime.ts +20 -6
- package/vendor/README.md +19 -5
- package/vendor/blitz-dom/Cargo.toml +6 -6
- package/vendor/blitz-dom/src/accessibility.rs +175 -2
- package/vendor/blitz-dom/src/config.rs +8 -10
- package/vendor/blitz-dom/src/document.rs +66 -3
- package/vendor/blitz-dom/src/events/keyboard.rs +2 -6
- package/vendor/blitz-dom/src/layout/construct.rs +5 -300
- package/vendor/blitz-dom/src/layout/inline/build.rs +309 -0
- package/vendor/blitz-dom/src/layout/{inline.rs → inline/layout.rs} +1 -1
- package/vendor/blitz-dom/src/layout/inline/mod.rs +4 -0
- package/vendor/blitz-dom/src/layout/mod.rs +3 -1
- package/vendor/blitz-dom/src/layout/replaced.rs +13 -4
- package/vendor/blitz-dom/src/mutator.rs +47 -0
- package/vendor/blitz-dom/src/node/element.rs +17 -0
- package/vendor/blitz-dom/src/node/mod.rs +1 -0
- package/vendor/blitz-dom/src/node/node.rs +46 -5
- package/vendor/blitz-dom/src/node/text.rs +11 -11
- package/vendor/blitz-dom/src/resolve.rs +2 -2
- package/vendor/blitz-dom/src/stylo.rs +30 -22
- package/vendor/blitz-dom/src/util.rs +1 -1
- package/vendor/blitz-paint/Cargo.toml +4 -4
- package/wasm/blitz_pdf_bg.wasm +2 -2
package/dist/worker-runtime.js
CHANGED
|
@@ -1,34 +1,50 @@
|
|
|
1
1
|
import { initSync } from "../wasm/blitz_pdf.js";
|
|
2
2
|
import { render } from "./render.js";
|
|
3
|
-
/**
|
|
3
|
+
/** One document at a time; retain the initialized engine and its bundled-font cache. */
|
|
4
4
|
export function serve(endpoint) {
|
|
5
|
+
let initialized = false;
|
|
6
|
+
let activeId;
|
|
5
7
|
let receiveAssets;
|
|
6
8
|
endpoint.onMessage(async (message) => {
|
|
7
9
|
if (message.type === "assets") {
|
|
10
|
+
if (message.id !== activeId)
|
|
11
|
+
return;
|
|
8
12
|
const receive = receiveAssets;
|
|
9
13
|
receiveAssets = undefined;
|
|
10
14
|
receive?.(message.data);
|
|
11
15
|
return;
|
|
12
16
|
}
|
|
17
|
+
if (activeId !== undefined) {
|
|
18
|
+
endpoint.post({ type: "error", id: message.id, error: new Error("Worker already has an active document") }, []);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
activeId = message.id;
|
|
13
22
|
try {
|
|
14
|
-
|
|
23
|
+
if (!initialized) {
|
|
24
|
+
initSync({ module: message.module });
|
|
25
|
+
initialized = true;
|
|
26
|
+
}
|
|
15
27
|
const load = message.external
|
|
16
28
|
? (urls) => new Promise(resolve => {
|
|
17
29
|
receiveAssets = resolve;
|
|
18
|
-
endpoint.post({ type: "assets", urls }, []);
|
|
30
|
+
endpoint.post({ type: "assets", id: message.id, urls }, []);
|
|
19
31
|
})
|
|
20
32
|
: undefined;
|
|
21
33
|
const pdf = await render(message.html, message.options, load);
|
|
22
|
-
endpoint.post({ type: "done", pdf }, [pdf.buffer]);
|
|
34
|
+
endpoint.post({ type: "done", id: message.id, pdf }, [pdf.buffer]);
|
|
23
35
|
}
|
|
24
36
|
catch (error) {
|
|
25
37
|
try {
|
|
26
|
-
endpoint.post({ type: "error", error }, []);
|
|
38
|
+
endpoint.post({ type: "error", id: message.id, error }, []);
|
|
27
39
|
}
|
|
28
40
|
catch {
|
|
29
|
-
endpoint.post({ type: "error", error: new Error(String(error)) }, []);
|
|
41
|
+
endpoint.post({ type: "error", id: message.id, error: new Error(String(error)) }, []);
|
|
30
42
|
}
|
|
31
43
|
}
|
|
44
|
+
finally {
|
|
45
|
+
activeId = undefined;
|
|
46
|
+
receiveAssets = undefined;
|
|
47
|
+
}
|
|
32
48
|
});
|
|
33
49
|
}
|
|
34
50
|
//# sourceMappingURL=worker-runtime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-runtime.js","sourceRoot":"","sources":["../src/worker-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,
|
|
1
|
+
{"version":3,"file":"worker-runtime.js","sourceRoot":"","sources":["../src/worker-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,wFAAwF;AACxF,MAAM,UAAU,KAAK,CAAC,QAAwB;IAC5C,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,QAA4B,CAAC;IACjC,IAAI,aAAyD,CAAC;IAC9D,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;QACjC,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,OAAO,CAAC,EAAE,KAAK,QAAQ;gBAAE,OAAO;YACpC,MAAM,OAAO,GAAG,aAAa,CAAC;YAC9B,aAAa,GAAG,SAAS,CAAC;YAC1B,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,uCAAuC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAChH,OAAO;QACT,CAAC;QACD,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;gBACrC,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ;gBAC3B,CAAC,CAAC,CAAC,IAAc,EAAE,EAAE,CAAC,IAAI,OAAO,CAAe,OAAO,CAAC,EAAE;oBACxD,aAAa,GAAG,OAAO,CAAC;oBACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC9D,CAAC,CAAC;gBACF,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC9D,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAqB,CAAC,CAAC,CAAC;QACpF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC;gBAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;YAAC,CAAC;YACpE,MAAM,CAAC;gBAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAAC,CAAC;QAClG,CAAC;gBAAS,CAAC;YACT,QAAQ,GAAG,SAAS,CAAC;YACrB,aAAa,GAAG,SAAS,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -49,19 +49,19 @@ bitflags 2.13.2
|
|
|
49
49
|
License: MIT OR Apache-2.0
|
|
50
50
|
Source: https://github.com/bitflags/bitflags
|
|
51
51
|
|
|
52
|
-
blitz-dom 0.3.0-beta.
|
|
52
|
+
blitz-dom 0.3.0-beta.4
|
|
53
53
|
License: MIT OR Apache-2.0
|
|
54
54
|
Source: https://github.com/dioxuslabs/blitz
|
|
55
55
|
|
|
56
|
-
blitz-html 0.3.0-beta.
|
|
56
|
+
blitz-html 0.3.0-beta.4
|
|
57
57
|
License: MIT OR Apache-2.0
|
|
58
58
|
Source: https://github.com/dioxuslabs/blitz
|
|
59
59
|
|
|
60
|
-
blitz-paint 0.3.0-beta.
|
|
60
|
+
blitz-paint 0.3.0-beta.4
|
|
61
61
|
License: MIT OR Apache-2.0
|
|
62
62
|
Source: https://github.com/dioxuslabs/blitz
|
|
63
63
|
|
|
64
|
-
blitz-traits 0.3.0-beta.
|
|
64
|
+
blitz-traits 0.3.0-beta.4
|
|
65
65
|
License: MIT OR Apache-2.0
|
|
66
66
|
Source: https://github.com/dioxuslabs/blitz
|
|
67
67
|
|
|
@@ -121,7 +121,7 @@ core_maths 0.1.1
|
|
|
121
121
|
License: MIT
|
|
122
122
|
Source: https://github.com/robertbastian/core_maths
|
|
123
123
|
|
|
124
|
-
crc32fast 1.5.
|
|
124
|
+
crc32fast 1.5.3
|
|
125
125
|
License: MIT OR Apache-2.0
|
|
126
126
|
Source: https://github.com/srijs/rust-crc32fast
|
|
127
127
|
|
|
@@ -197,7 +197,7 @@ encoding_rs 0.8.42
|
|
|
197
197
|
License: (Apache-2.0 OR MIT) AND BSD-3-Clause
|
|
198
198
|
Source: https://github.com/hsivonen/encoding_rs
|
|
199
199
|
|
|
200
|
-
equivalent 1.0.
|
|
200
|
+
equivalent 1.0.3
|
|
201
201
|
License: Apache-2.0 OR MIT
|
|
202
202
|
Source: https://github.com/indexmap-rs/equivalent
|
|
203
203
|
|
|
@@ -233,7 +233,7 @@ font-types 0.11.3
|
|
|
233
233
|
License: MIT OR Apache-2.0
|
|
234
234
|
Source: https://github.com/googlefonts/fontations
|
|
235
235
|
|
|
236
|
-
font-types 0.12.
|
|
236
|
+
font-types 0.12.7
|
|
237
237
|
License: MIT OR Apache-2.0
|
|
238
238
|
Source: https://github.com/googlefonts/fontations
|
|
239
239
|
|
|
@@ -385,9 +385,9 @@ js-sys 0.3.106
|
|
|
385
385
|
License: MIT OR Apache-2.0
|
|
386
386
|
Source: https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/js-sys
|
|
387
387
|
|
|
388
|
-
keyboard-types 0.
|
|
388
|
+
keyboard-types 0.8.3
|
|
389
389
|
License: MIT OR Apache-2.0
|
|
390
|
-
Source: https://github.com/
|
|
390
|
+
Source: https://github.com/rust-windowing/keyboard-types
|
|
391
391
|
|
|
392
392
|
krilla 0.8.2
|
|
393
393
|
License: MIT OR Apache-2.0
|
|
@@ -397,7 +397,7 @@ kurbo 0.13.1
|
|
|
397
397
|
License: Apache-2.0 OR MIT
|
|
398
398
|
Source: https://github.com/linebender/kurbo
|
|
399
399
|
|
|
400
|
-
libc 0.2.
|
|
400
|
+
libc 0.2.191
|
|
401
401
|
License: MIT OR Apache-2.0
|
|
402
402
|
Source: https://github.com/rust-lang/libc
|
|
403
403
|
|
|
@@ -721,7 +721,7 @@ smallvec 1.16.3
|
|
|
721
721
|
License: MIT OR Apache-2.0
|
|
722
722
|
Source: https://github.com/servo/rust-smallvec
|
|
723
723
|
|
|
724
|
-
smol_str 0.3.
|
|
724
|
+
smol_str 0.3.7
|
|
725
725
|
License: MIT OR Apache-2.0
|
|
726
726
|
Source: https://github.com/rust-lang/rust-analyzer/tree/master/lib/smol_str
|
|
727
727
|
|
|
@@ -777,7 +777,7 @@ stylo_static_prefs 0.22.0
|
|
|
777
777
|
License: MPL-2.0
|
|
778
778
|
Source: https://github.com/servo/stylo
|
|
779
779
|
|
|
780
|
-
stylo_taffy 0.3.0-beta.
|
|
780
|
+
stylo_taffy 0.3.0-beta.4
|
|
781
781
|
License: MIT OR Apache-2.0 OR MPL-2.0
|
|
782
782
|
Source: https://github.com/dioxuslabs/blitz
|
|
783
783
|
|
|
@@ -877,10 +877,6 @@ unicode-script 0.5.8
|
|
|
877
877
|
License: MIT OR Apache-2.0
|
|
878
878
|
Source: https://github.com/unicode-rs/unicode-script
|
|
879
879
|
|
|
880
|
-
unicode-segmentation 1.13.3
|
|
881
|
-
License: MIT OR Apache-2.0
|
|
882
|
-
Source: https://github.com/unicode-rs/unicode-segmentation
|
|
883
|
-
|
|
884
880
|
unicode-vo 0.1.0
|
|
885
881
|
License: MIT/Apache-2.0
|
|
886
882
|
Source: https://github.com/RazrFalcon/unicode-vo
|
|
@@ -1263,7 +1259,7 @@ serde_bytes 0.11.19 (LICENSE-MIT)
|
|
|
1263
1259
|
serde_core 1.0.229 (LICENSE-MIT)
|
|
1264
1260
|
serde_derive 1.0.229 (LICENSE-MIT)
|
|
1265
1261
|
servo_arc 0.5.0 (LICENSE-MIT)
|
|
1266
|
-
smol_str 0.3.
|
|
1262
|
+
smol_str 0.3.7 (LICENSE-MIT)
|
|
1267
1263
|
stylo_malloc_size_of 0.22.0 (LICENSE-MIT)
|
|
1268
1264
|
syn 2.0.119 (LICENSE-MIT)
|
|
1269
1265
|
syn 3.0.9 (LICENSE-MIT)
|
|
@@ -1361,7 +1357,7 @@ crossbeam-utils 0.8.23 (LICENSE-APACHE)
|
|
|
1361
1357
|
data-url 0.3.2 (LICENSE-APACHE)
|
|
1362
1358
|
displaydoc 0.2.7 (LICENSE-APACHE)
|
|
1363
1359
|
either 1.19.0 (LICENSE-APACHE)
|
|
1364
|
-
equivalent 1.0.
|
|
1360
|
+
equivalent 1.0.3 (LICENSE-APACHE)
|
|
1365
1361
|
euclid 0.22.14 (LICENSE-APACHE)
|
|
1366
1362
|
fastrand 2.5.0 (LICENSE-APACHE)
|
|
1367
1363
|
flate2 1.1.10 (LICENSE-APACHE)
|
|
@@ -1404,7 +1400,7 @@ servo_arc 0.5.0 (LICENSE-APACHE)
|
|
|
1404
1400
|
simplecss 0.2.2 (LICENSE-APACHE)
|
|
1405
1401
|
smallbitvec 2.6.1 (LICENSE-APACHE)
|
|
1406
1402
|
smallvec 1.16.3 (LICENSE-APACHE)
|
|
1407
|
-
smol_str 0.3.
|
|
1403
|
+
smol_str 0.3.7 (LICENSE-APACHE)
|
|
1408
1404
|
stable_deref_trait 1.2.1 (LICENSE-APACHE)
|
|
1409
1405
|
string_cache 0.11.0 (LICENSE-APACHE)
|
|
1410
1406
|
string_cache_codegen 0.11.2 (LICENSE-APACHE)
|
|
@@ -1413,7 +1409,6 @@ svgtypes 0.16.1 (LICENSE-APACHE)
|
|
|
1413
1409
|
tendril 0.5.1 (LICENSE-APACHE)
|
|
1414
1410
|
thread_local 1.1.10 (LICENSE-APACHE)
|
|
1415
1411
|
unicode-bidi 0.3.18 (LICENSE-APACHE)
|
|
1416
|
-
unicode-segmentation 1.13.3 (LICENSE-APACHE)
|
|
1417
1412
|
unicode-vo 0.1.0 (LICENSE-APACHE)
|
|
1418
1413
|
url 2.5.8 (LICENSE-APACHE)
|
|
1419
1414
|
version_check 0.9.5 (LICENSE-APACHE)
|
|
@@ -2016,13 +2011,13 @@ DEALINGS IN THE SOFTWARE.
|
|
|
2016
2011
|
|
|
2017
2012
|
|
|
2018
2013
|
========================================================================
|
|
2019
|
-
blitz-dom 0.3.0-beta.
|
|
2020
|
-
blitz-html 0.3.0-beta.
|
|
2021
|
-
blitz-paint 0.3.0-beta.
|
|
2022
|
-
blitz-traits 0.3.0-beta.
|
|
2014
|
+
blitz-dom 0.3.0-beta.4 (LICENSE-APACHE)
|
|
2015
|
+
blitz-html 0.3.0-beta.4 (LICENSE-APACHE)
|
|
2016
|
+
blitz-paint 0.3.0-beta.4 (LICENSE-APACHE)
|
|
2017
|
+
blitz-traits 0.3.0-beta.4 (LICENSE-APACHE)
|
|
2023
2018
|
debug_timer 0.1.3 (LICENSE-APACHE)
|
|
2024
2019
|
rustc-hash 2.1.3 (LICENSE-APACHE)
|
|
2025
|
-
stylo_taffy 0.3.0-beta.
|
|
2020
|
+
stylo_taffy 0.3.0-beta.4 (LICENSE-APACHE)
|
|
2026
2021
|
========================================================================
|
|
2027
2022
|
|
|
2028
2023
|
Apache License
|
|
@@ -2203,13 +2198,13 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
|
2203
2198
|
END OF TERMS AND CONDITIONS
|
|
2204
2199
|
|
|
2205
2200
|
========================================================================
|
|
2206
|
-
blitz-dom 0.3.0-beta.
|
|
2207
|
-
blitz-html 0.3.0-beta.
|
|
2208
|
-
blitz-paint 0.3.0-beta.
|
|
2209
|
-
blitz-traits 0.3.0-beta.
|
|
2201
|
+
blitz-dom 0.3.0-beta.4 (LICENSE-MIT)
|
|
2202
|
+
blitz-html 0.3.0-beta.4 (LICENSE-MIT)
|
|
2203
|
+
blitz-paint 0.3.0-beta.4 (LICENSE-MIT)
|
|
2204
|
+
blitz-traits 0.3.0-beta.4 (LICENSE-MIT)
|
|
2210
2205
|
debug_timer 0.1.3 (LICENSE-MIT)
|
|
2211
2206
|
rustc-hash 2.1.3 (LICENSE-MIT)
|
|
2212
|
-
stylo_taffy 0.3.0-beta.
|
|
2207
|
+
stylo_taffy 0.3.0-beta.4 (LICENSE-MIT)
|
|
2213
2208
|
========================================================================
|
|
2214
2209
|
|
|
2215
2210
|
Permission is hereby granted, free of charge, to any
|
|
@@ -2946,7 +2941,7 @@ SOFTWARE.
|
|
|
2946
2941
|
========================================================================
|
|
2947
2942
|
core_detect 1.0.0 (LICENSE-APACHE)
|
|
2948
2943
|
gif 0.14.2 (LICENSE-APACHE)
|
|
2949
|
-
keyboard-types 0.
|
|
2944
|
+
keyboard-types 0.8.3 (LICENSE-APACHE)
|
|
2950
2945
|
weezl 0.1.12 (LICENSE-APACHE)
|
|
2951
2946
|
========================================================================
|
|
2952
2947
|
|
|
@@ -3210,7 +3205,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
3210
3205
|
SOFTWARE.
|
|
3211
3206
|
|
|
3212
3207
|
========================================================================
|
|
3213
|
-
crc32fast 1.5.
|
|
3208
|
+
crc32fast 1.5.3 (LICENSE-APACHE)
|
|
3214
3209
|
quick-error 2.0.1 (LICENSE-APACHE)
|
|
3215
3210
|
========================================================================
|
|
3216
3211
|
|
|
@@ -3419,7 +3414,7 @@ quick-error 2.0.1 (LICENSE-APACHE)
|
|
|
3419
3414
|
|
|
3420
3415
|
|
|
3421
3416
|
========================================================================
|
|
3422
|
-
crc32fast 1.5.
|
|
3417
|
+
crc32fast 1.5.3 (LICENSE-MIT)
|
|
3423
3418
|
========================================================================
|
|
3424
3419
|
|
|
3425
3420
|
MIT License
|
|
@@ -4204,7 +4199,7 @@ SOFTWARE.
|
|
|
4204
4199
|
========================================================================
|
|
4205
4200
|
dtoa 1.0.11 (LICENSE-APACHE)
|
|
4206
4201
|
itoa 1.0.18 (LICENSE-APACHE)
|
|
4207
|
-
libc 0.2.
|
|
4202
|
+
libc 0.2.191 (LICENSE-APACHE)
|
|
4208
4203
|
parley_engine 0.12.0 (LICENSE-APACHE)
|
|
4209
4204
|
pdf-writer 0.15.0 (LICENSE-APACHE)
|
|
4210
4205
|
proc-macro2 1.0.107 (LICENSE-APACHE)
|
|
@@ -5095,7 +5090,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
5095
5090
|
|
|
5096
5091
|
|
|
5097
5092
|
========================================================================
|
|
5098
|
-
equivalent 1.0.
|
|
5093
|
+
equivalent 1.0.3 (LICENSE-MIT)
|
|
5099
5094
|
========================================================================
|
|
5100
5095
|
|
|
5101
5096
|
Copyright (c) 2016--2023
|
|
@@ -5602,7 +5597,7 @@ DEALINGS IN THE SOFTWARE.
|
|
|
5602
5597
|
|
|
5603
5598
|
|
|
5604
5599
|
========================================================================
|
|
5605
|
-
font-types 0.12.
|
|
5600
|
+
font-types 0.12.7 (LICENSE-APACHE)
|
|
5606
5601
|
read-fonts 0.41.0 (LICENSE-APACHE)
|
|
5607
5602
|
skrifa 0.44.0 (LICENSE-APACHE)
|
|
5608
5603
|
========================================================================
|
|
@@ -5677,7 +5672,7 @@ limitations under the License.
|
|
|
5677
5672
|
|
|
5678
5673
|
|
|
5679
5674
|
========================================================================
|
|
5680
|
-
font-types 0.12.
|
|
5675
|
+
font-types 0.12.7 (LICENSE-MIT)
|
|
5681
5676
|
read-fonts 0.41.0 (LICENSE-MIT)
|
|
5682
5677
|
skrifa 0.44.0 (LICENSE-MIT)
|
|
5683
5678
|
========================================================================
|
|
@@ -6158,7 +6153,6 @@ DEALINGS IN THE SOFTWARE.
|
|
|
6158
6153
|
========================================================================
|
|
6159
6154
|
heck 0.5.0 (LICENSE-MIT)
|
|
6160
6155
|
unicode-bidi 0.3.18 (LICENSE-MIT)
|
|
6161
|
-
unicode-segmentation 1.13.3 (LICENSE-MIT)
|
|
6162
6156
|
========================================================================
|
|
6163
6157
|
|
|
6164
6158
|
Copyright (c) 2015 The Rust Project Developers
|
|
@@ -6677,7 +6671,7 @@ DEALINGS IN THE SOFTWARE.
|
|
|
6677
6671
|
|
|
6678
6672
|
|
|
6679
6673
|
========================================================================
|
|
6680
|
-
keyboard-types 0.
|
|
6674
|
+
keyboard-types 0.8.3 (LICENSE-MIT)
|
|
6681
6675
|
========================================================================
|
|
6682
6676
|
|
|
6683
6677
|
Copyright (c) 2017 Pyfisch
|
|
@@ -6760,7 +6754,7 @@ DEALINGS IN THE SOFTWARE.
|
|
|
6760
6754
|
|
|
6761
6755
|
|
|
6762
6756
|
========================================================================
|
|
6763
|
-
libc 0.2.
|
|
6757
|
+
libc 0.2.191 (LICENSE-MIT)
|
|
6764
6758
|
========================================================================
|
|
6765
6759
|
|
|
6766
6760
|
Copyright (c) The Rust Project Developers
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { createAssetLoader } from "./assets.js";
|
|
|
3
3
|
import { normalizeOptions } from "./options.js";
|
|
4
4
|
import { render, validateHtml } from "./render.js";
|
|
5
5
|
import { compileWasm } from "./wasm.js";
|
|
6
|
-
import {
|
|
7
|
-
import type { InitOptions, PdfOptions, WasmSource } from "./types.js";
|
|
6
|
+
import { createWorkerPool, type SpawnWorker } from "./worker-host.js";
|
|
7
|
+
import type { InitOptions, PdfOptions, PdfWorkerPool, PdfWorkerPoolOptions, WasmSource } from "./types.js";
|
|
8
8
|
|
|
9
9
|
export interface ApiConfig {
|
|
10
10
|
defaultSource: () => Promise<WasmSource> | WasmSource;
|
|
@@ -15,6 +15,7 @@ export interface ApiConfig {
|
|
|
15
15
|
export function createApi({ defaultSource, prepare = async source => source, spawnWorker }: ApiConfig) {
|
|
16
16
|
let compiled: Promise<WebAssembly.Module> | undefined;
|
|
17
17
|
let ready: Promise<void> | undefined;
|
|
18
|
+
let defaultPool: PdfWorkerPool | undefined;
|
|
18
19
|
|
|
19
20
|
function compile(source?: WasmSource): Promise<WebAssembly.Module> {
|
|
20
21
|
if (compiled) return compiled;
|
|
@@ -43,13 +44,37 @@ export function createApi({ defaultSource, prepare = async source => source, spa
|
|
|
43
44
|
return render(html, normalized, assetResolver && createAssetLoader(assetResolver));
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
/**
|
|
47
|
+
/** Create an owned pool, with independent concurrency and shutdown. No workers start until needed. */
|
|
48
|
+
function createPdfWorkerPool(options: PdfWorkerPoolOptions = {}): PdfWorkerPool {
|
|
49
|
+
const pool = createWorkerPool(spawnWorker, options);
|
|
50
|
+
// Include compilation in accepted work so close also drains renders waiting for WASM.
|
|
51
|
+
const pending = new Set<Promise<Uint8Array>>();
|
|
52
|
+
let closing: Promise<void> | undefined;
|
|
53
|
+
return {
|
|
54
|
+
renderPdf(html: string, options: PdfOptions = {}): Promise<Uint8Array> {
|
|
55
|
+
if (closing) return Promise.reject(new Error("PDF worker pool is closed"));
|
|
56
|
+
const work = (async () => {
|
|
57
|
+
validateHtml(html);
|
|
58
|
+
const { assetResolver, ...normalized } = normalizeOptions(options);
|
|
59
|
+
return pool.render(await compile(), html, normalized, assetResolver);
|
|
60
|
+
})();
|
|
61
|
+
pending.add(work);
|
|
62
|
+
void work.then(() => pending.delete(work), () => pending.delete(work));
|
|
63
|
+
return work;
|
|
64
|
+
},
|
|
65
|
+
close(): Promise<void> {
|
|
66
|
+
closing ??= Promise.allSettled([...pending]).then(() => pool.close());
|
|
67
|
+
return closing;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Render in the shared bounded pool. An assets function still runs on the calling thread. */
|
|
47
73
|
async function renderPdfInWorker(html: string, options: PdfOptions = {}): Promise<Uint8Array> {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return renderInWorker(spawnWorker, await compile(), html, normalized, assetResolver);
|
|
74
|
+
defaultPool ??= createPdfWorkerPool();
|
|
75
|
+
return defaultPool.renderPdf(html, options);
|
|
51
76
|
}
|
|
52
77
|
|
|
53
78
|
async function getEngineVersion(): Promise<string> { await init(); return engine_version(); }
|
|
54
|
-
return { init, renderPdf, renderPdfInWorker, getWasmModule, getEngineVersion };
|
|
79
|
+
return { init, renderPdf, renderPdfInWorker, createPdfWorkerPool, getWasmModule, getEngineVersion };
|
|
55
80
|
}
|
package/src/browser.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createApi } from "./api.js";
|
|
2
2
|
|
|
3
3
|
export type { AssetData, AssetMap, AssetResolver, AttachmentRelationship, BinaryData, InitOptions, Length, PageFormat, PageNumberOptions, PdfAttachment, PdfDate, PdfMetadata, PdfOptions, PdfXmpProperty, PdfXmpSchema, WasmSource } from "./types.js";
|
|
4
|
-
export
|
|
4
|
+
export type { PdfWorkerPool, PdfWorkerPoolOptions } from "./types.js";
|
|
5
|
+
export const { init, renderPdf, renderPdfInWorker, createPdfWorkerPool, getWasmModule, getEngineVersion } = createApi({
|
|
5
6
|
defaultSource: () => new URL("../wasm/blitz_pdf_bg.wasm", import.meta.url),
|
|
6
7
|
spawnWorker: events => {
|
|
7
8
|
const worker = new Worker(new URL("./worker.js", import.meta.url), { type: "module" });
|
package/src/node.ts
CHANGED
|
@@ -3,7 +3,8 @@ import { Worker } from "node:worker_threads";
|
|
|
3
3
|
import { createApi } from "./api.js";
|
|
4
4
|
|
|
5
5
|
export type { AssetData, AssetMap, AssetResolver, AttachmentRelationship, BinaryData, InitOptions, Length, PageFormat, PageNumberOptions, PdfAttachment, PdfDate, PdfMetadata, PdfOptions, PdfXmpProperty, PdfXmpSchema, WasmSource } from "./types.js";
|
|
6
|
-
export
|
|
6
|
+
export type { PdfWorkerPool, PdfWorkerPoolOptions } from "./types.js";
|
|
7
|
+
export const { init, renderPdf, renderPdfInWorker, createPdfWorkerPool, getWasmModule, getEngineVersion } = createApi({
|
|
7
8
|
defaultSource: () => readFile(new URL("../wasm/blitz_pdf_bg.wasm", import.meta.url)),
|
|
8
9
|
prepare: async source => {
|
|
9
10
|
if (source instanceof URL && source.protocol === "file:") return readFile(source);
|
|
@@ -16,6 +17,10 @@ export const { init, renderPdf, renderPdfInWorker, getWasmModule, getEngineVersi
|
|
|
16
17
|
worker.on("error", events.error);
|
|
17
18
|
worker.on("messageerror", events.error);
|
|
18
19
|
worker.on("exit", code => events.error(new Error(`Render worker exited with code ${code}`)));
|
|
19
|
-
return {
|
|
20
|
+
return {
|
|
21
|
+
post: (message, transfer) => worker.postMessage(message, transfer),
|
|
22
|
+
terminate: async () => { await worker.terminate(); },
|
|
23
|
+
ref: () => { worker.ref(); }, unref: () => { worker.unref(); },
|
|
24
|
+
};
|
|
20
25
|
},
|
|
21
26
|
});
|
package/src/types.ts
CHANGED
|
@@ -123,3 +123,18 @@ export interface PdfOptions {
|
|
|
123
123
|
/** Reject larger documents. Default: 100; maximum: 1000. */
|
|
124
124
|
maxPages?: number;
|
|
125
125
|
}
|
|
126
|
+
/** Limits for a pool of reusable, independent PDF engines. */
|
|
127
|
+
export interface PdfWorkerPoolOptions {
|
|
128
|
+
/** Maximum simultaneous renders. Default: 4. */
|
|
129
|
+
maxWorkers?: number;
|
|
130
|
+
/** Release an unused worker after this many milliseconds. Default: 30000; 0 disables reuse. */
|
|
131
|
+
idleTimeoutMs?: number;
|
|
132
|
+
/** Recreate a worker after this many documents to bound retained engine memory. Default: 100. */
|
|
133
|
+
maxJobsPerWorker?: number;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface PdfWorkerPool {
|
|
137
|
+
renderPdf(html: string, options?: PdfOptions): Promise<Uint8Array>;
|
|
138
|
+
/** Stop accepting work, finish accepted renders, and release every worker. Idempotent. */
|
|
139
|
+
close(): Promise<void>;
|
|
140
|
+
}
|
package/src/worker-host.ts
CHANGED
|
@@ -1,45 +1,164 @@
|
|
|
1
1
|
import { createAssetLoader } from "./assets.js";
|
|
2
2
|
import type { RenderOptions } from "./render.js";
|
|
3
|
-
import type { AssetResolver } from "./types.js";
|
|
3
|
+
import type { AssetResolver, PdfWorkerPoolOptions } from "./types.js";
|
|
4
4
|
import type { HostMessage, WorkerMessage } from "./worker-protocol.js";
|
|
5
5
|
|
|
6
6
|
export interface WorkerEvents {
|
|
7
7
|
message(message: WorkerMessage): void;
|
|
8
|
-
/** Crashes, unreadable messages, or an exit
|
|
8
|
+
/** Crashes, unreadable messages, or an unexpected exit, including while idle. */
|
|
9
9
|
error(error: unknown): void;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface WorkerHandle {
|
|
13
13
|
post(message: HostMessage, transfer: ArrayBuffer[]): void;
|
|
14
|
-
terminate(): void
|
|
14
|
+
terminate(): void | Promise<void>;
|
|
15
|
+
ref?(): void;
|
|
16
|
+
unref?(): void;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export type SpawnWorker = (events: WorkerEvents) => WorkerHandle;
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
21
|
+
interface Job {
|
|
22
|
+
id: number;
|
|
23
|
+
message: Extract<HostMessage, { type: "render" }>;
|
|
24
|
+
load: ReturnType<typeof createAssetLoader> | undefined;
|
|
25
|
+
resolve(pdf: Uint8Array): void;
|
|
26
|
+
reject(error: unknown): void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface Slot {
|
|
30
|
+
worker?: WorkerHandle;
|
|
31
|
+
job?: Job;
|
|
32
|
+
timer?: ReturnType<typeof setTimeout>;
|
|
33
|
+
completed: number;
|
|
34
|
+
retired: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function integer(value: number, min: number, max: number, name: string): number {
|
|
38
|
+
if (!Number.isSafeInteger(value) || value < min || value > max) {
|
|
39
|
+
throw new RangeError(`${name} must be an integer from ${min} to ${max}`);
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Jobs have their own resolver and document; only the initialized engine survives. */
|
|
45
|
+
export function createWorkerPool(spawn: SpawnWorker, options: PdfWorkerPoolOptions = {}) {
|
|
46
|
+
const maxWorkers = integer(options.maxWorkers ?? 4, 1, Number.MAX_SAFE_INTEGER, "maxWorkers");
|
|
47
|
+
const idleTimeoutMs = integer(options.idleTimeoutMs ?? 30_000, 0, 2_147_483_647, "idleTimeoutMs");
|
|
48
|
+
const maxJobs = integer(options.maxJobsPerWorker ?? 100, 1, Number.MAX_SAFE_INTEGER, "maxJobsPerWorker");
|
|
49
|
+
const slots = new Set<Slot>();
|
|
50
|
+
const queue: Job[] = [];
|
|
51
|
+
const terminating = new Set<Promise<void>>();
|
|
52
|
+
let nextId = 0;
|
|
53
|
+
let closing: Promise<void> | undefined;
|
|
54
|
+
let resolveClosed: (() => void) | undefined;
|
|
55
|
+
let pumping = false;
|
|
56
|
+
|
|
57
|
+
function checkClosed() {
|
|
58
|
+
if (closing && queue.length === 0 && slots.size === 0 && terminating.size === 0) resolveClosed?.();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function retire(slot: Slot) {
|
|
62
|
+
if (slot.retired) return;
|
|
63
|
+
slot.retired = true;
|
|
64
|
+
clearTimeout(slot.timer);
|
|
65
|
+
slots.delete(slot);
|
|
66
|
+
// Observe asynchronous termination before close resolves; late exit events are ignored.
|
|
67
|
+
const done = Promise.resolve().then(() => slot.worker?.terminate()).then(() => {}, () => {});
|
|
68
|
+
terminating.add(done);
|
|
69
|
+
void done.then(() => { terminating.delete(done); checkClosed(); });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function fail(slot: Slot, error: unknown) {
|
|
73
|
+
if (slot.retired) return;
|
|
74
|
+
const job = slot.job;
|
|
75
|
+
delete slot.job;
|
|
76
|
+
retire(slot);
|
|
77
|
+
job?.reject(error);
|
|
78
|
+
pump();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function release(slot: Slot) {
|
|
82
|
+
slot.completed++;
|
|
83
|
+
if (slot.completed >= maxJobs || idleTimeoutMs === 0 || (closing && queue.length === 0)) {
|
|
84
|
+
retire(slot);
|
|
85
|
+
} else if (queue.length === 0) {
|
|
86
|
+
slot.worker?.unref?.();
|
|
87
|
+
slot.timer = setTimeout(() => { retire(slot); checkClosed(); }, idleTimeoutMs);
|
|
88
|
+
// A warm worker and its eviction timer must not keep a CLI alive.
|
|
89
|
+
slot.timer.unref?.();
|
|
90
|
+
}
|
|
91
|
+
pump();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function message(slot: Slot, value: WorkerMessage) {
|
|
95
|
+
const job = slot.job;
|
|
96
|
+
if (slot.retired || !job || value.id !== job.id) return;
|
|
97
|
+
if (value.type === "done") {
|
|
98
|
+
delete slot.job;
|
|
99
|
+
release(slot);
|
|
100
|
+
job.resolve(value.pdf);
|
|
101
|
+
} else if (value.type === "error") {
|
|
102
|
+
fail(slot, value.error);
|
|
103
|
+
} else if (!job.load) {
|
|
104
|
+
fail(slot, new Error("Render worker requested assets without a resolver"));
|
|
105
|
+
} else {
|
|
106
|
+
void job.load(value.urls).then(data => {
|
|
107
|
+
// Resolver promises can finish after a crash or retirement. Never send them to another job.
|
|
108
|
+
if (slot.retired || slot.job !== job) return;
|
|
109
|
+
try {
|
|
110
|
+
slot.worker!.post({ type: "assets", id: job.id, data }, data.map(bytes => bytes.buffer as ArrayBuffer));
|
|
111
|
+
} catch (error) { fail(slot, error); }
|
|
112
|
+
}, error => { if (!slot.retired && slot.job === job) fail(slot, error); });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function pump() {
|
|
117
|
+
if (pumping) return;
|
|
118
|
+
pumping = true;
|
|
119
|
+
try {
|
|
120
|
+
while (queue.length > 0) {
|
|
121
|
+
let slot = [...slots].find(candidate => !candidate.job);
|
|
122
|
+
if (!slot && slots.size >= maxWorkers) break;
|
|
123
|
+
const job = queue.shift()!;
|
|
124
|
+
if (!slot) {
|
|
125
|
+
slot = { completed: 0, retired: false, job };
|
|
126
|
+
slots.add(slot);
|
|
127
|
+
const created = slot;
|
|
128
|
+
try {
|
|
129
|
+
created.worker = spawn({ message: value => message(created, value), error: error => fail(created, error) });
|
|
130
|
+
} catch (error) { fail(created, error); continue; }
|
|
131
|
+
} else {
|
|
132
|
+
clearTimeout(slot.timer);
|
|
133
|
+
delete slot.timer;
|
|
134
|
+
slot.job = job;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
slot.worker!.ref?.();
|
|
138
|
+
slot.worker!.post(job.message, []);
|
|
139
|
+
} catch (error) { fail(slot, error); }
|
|
140
|
+
}
|
|
141
|
+
if (closing && queue.length === 0) for (const slot of slots) if (!slot.job) retire(slot);
|
|
142
|
+
} finally { pumping = false; }
|
|
143
|
+
checkClosed();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
render(module: WebAssembly.Module, html: string, options: RenderOptions, resolver?: AssetResolver): Promise<Uint8Array> {
|
|
148
|
+
if (closing) return Promise.reject(new Error("PDF worker pool is closed"));
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
const id = ++nextId;
|
|
151
|
+
queue.push({ id, message: { type: "render", id, module, html, options, external: resolver !== undefined },
|
|
152
|
+
load: resolver ? createAssetLoader(resolver) : undefined, resolve, reject });
|
|
153
|
+
pump();
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
close(): Promise<void> {
|
|
157
|
+
if (!closing) {
|
|
158
|
+
closing = new Promise(resolve => { resolveClosed = resolve; });
|
|
159
|
+
pump();
|
|
160
|
+
}
|
|
161
|
+
return closing;
|
|
162
|
+
},
|
|
163
|
+
};
|
|
45
164
|
}
|
package/src/worker-protocol.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { RenderOptions } from "./render.js";
|
|
2
2
|
|
|
3
3
|
export type HostMessage =
|
|
4
|
-
| { type: "render"; module: WebAssembly.Module; html: string; options: RenderOptions; external: boolean }
|
|
5
|
-
| { type: "assets"; data: Uint8Array[] };
|
|
4
|
+
| { type: "render"; id: number; module: WebAssembly.Module; html: string; options: RenderOptions; external: boolean }
|
|
5
|
+
| { type: "assets"; id: number; data: Uint8Array[] };
|
|
6
6
|
|
|
7
7
|
export type WorkerMessage =
|
|
8
|
-
| { type: "assets"; urls: string[] }
|
|
9
|
-
| { type: "done"; pdf: Uint8Array }
|
|
10
|
-
| { type: "error"; error: unknown };
|
|
8
|
+
| { type: "assets"; id: number; urls: string[] }
|
|
9
|
+
| { type: "done"; id: number; pdf: Uint8Array }
|
|
10
|
+
| { type: "error"; id: number; error: unknown };
|