Changed
- Consolidated conversion into one canonical
pdfToPng()path. Option normalization, page planning, bounded main-thread scheduling, mode selection, output finalization, and document teardown now live together; the CLI delegates to that public API instead of a normalized internal core. The public package exports and option/result behavior are unchanged. - Colocated one-consumer implementation details with their owners: pdf.js parameter mapping and portable asset URLs with the loader, page identity with main-thread finalization, worker protocol types with the pool, and public declarations in
src/types.ts. The source tree is reduced from 27 to 11 TypeScript modules without removing execution modes. - Reworked
npm run bencharound fresh child processes, structured Node IPC, and the published interface. It now records wall time, CPU time, and process peak RSS for configurable page counts and default, parallel, worker, file, and metadata modes without presenting lifetime high-water deltas as conversion memory growth. - Added an explicit
npm run checkCI/publish gate for both type-checks, formatting, lint, production licenses, and coverage tests. A plainnpm testnow runs the coverage suite without an implicit build/tooling chain. - Raised the enforced V8 coverage floor to 98% for statements, lines, functions, and branches, including the production worker entry through in-process protocol coverage.
- Expanded regression coverage for worker startup, dispatch, fatal ordering, queued and malformed responses, growing file inputs, non-
ErrorCLI failures, portable pdf.js factory URLs, Windows output-path escape detection, and missing renderer content in file mode. The clean suite reaches 99.78% statements, 99.68% branches, 100% functions, and 99.77% lines. - Refreshed dependency ranges, including
@napi-rs/canvasfrom~1.0.3to~1.0.8, Vitest and@vitest/coverage-v8from^4.1.10to^4.1.11, ESLint from^10.8.0to^10.9.1, and@types/nodefrom^26.1.2to^26.3.0, plus compatible typescript-eslint, lint-staged, and visual-comparison tooling updates. The publish workflow now pins npm 12.0.2. - Removed the obsolete
brace-expansionoverride after refreshing the audited lockfile, moved the publisher's npm pin from package metadata to the workflow, and recorded the permittedfsevents@2.3.3lifecycle script inallowScripts. - CI now validates the supported Node.js floor (22.13) as well as the Node.js 24 development and publishing line, including a Node.js 24 Windows native smoke run.
Fixed
- Page cleanup now covers viewport and canvas-allocation failures, a created canvas is destroyed even when page cleanup throws, and worker-pool settlement waits for both main-thread page finalization and the promise returned by
Worker.terminate(). A teardown-only termination failure no longer discards otherwise successful page results. - Duplicate output-name detection is now linear rather than repeatedly copying the accumulated page list for every collision.
- The CLI again validates semantic options before printing progress, then emits its processing and output-folder banners before conversion work starts. Its fail-fast pass returns the normalized snapshot used for CLI-only policy, and typed usage/conversion errors replace message and
causesniffing.pdfToPng()still revalidates at the public boundary; the small duplicate pass replaces the former normalized internal-core coupling. - Main-thread and worker schedulers now call one shared lowest-index error selector, keeping their deterministic page-error policy aligned. Main-thread limit selection and worker-mode selection each have one source of truth.
- Release prechecks now require the worker-thread entry and root type declarations in the dry-run tarball, catching incomplete packages before publication.
- Release prechecks and postchecks now accept both npm 11's direct
npm view --jsonvalues and npm 12's one-element array envelope. This prevents the precheck from misclassifying an already-published version as new and keeps post-publish version, dist-tag, and provenance verification working under the pinned npm 12 toolchain. - Vitest discovery is now anchored to the root
__tests__/directory. Hidden nested worktrees created by local review tools are no longer collected as a second copy of the suite, preventing concurrent integration tests from deleting or exclusively creating the same files undertest-results/. - The Node.js test matrix now feeds a stable aggregate
ubuntustatus check, preserving the context required bymainbranch protection while retaining separate Node.js 22.13 and 24 results.
Security
- Path inputs are opened once with nonblocking read-only flags, then checked and bounded-read through that same file handle. This closes the previous path-swap gap between
stat()andreadFile(), rejects special files without blocking on FIFOs, and prevents a growing file from allocating beyondmaxInputBytesbefore rejection. - Disk filenames are validated before folder creation as well as at the write boundary, including NUL, empty names, and
"."/".."aliases. Windows preflight also rejects invalid characters and control bytes, alternate data streams, reserved device basenames (including the documentedCOM¹–COM³andLPT¹–LPT³aliases), and trailing dots/spaces before output I/O. The host-separator predicate again has one owner shared by naming and writing. Output documentation now states the residual directory-inode replacement race accurately instead of claiming canonical-path equality is atomic.
Removed
- Removed the one-implementation
OutputSink/FilesystemSink,PageMode, page orchestrator, normalized-core wrapper, mapper/path helper files, internal type barrels, and standalone worker/canvas protocol files. - Removed generated
CODEMAP.mdand its 732-line generator/checking path; the maintained architecture guide now documents the compact live module tree directly.
Full changelog: https://github.com/dichovsky/pdf-to-png-converter/blob/v4.2.1/CHANGELOG.md