Skip to content

Commit c213652

Browse files
committed
This commit removes the initialize() method from all engine classes. PDFium is now automatically initialized in the constructor, simplifying the API and reducing boilerplate.
1 parent 3c1e5ce commit c213652

28 files changed

Lines changed: 267 additions & 319 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
'@embedpdf/engines': major
3+
'@embedpdf/models': major
4+
'@embedpdf/core': minor
5+
---
6+
7+
# Remove `initialize()` - PDFium Now Initializes in Constructor
8+
9+
This release removes the `initialize()` method from all engine classes. PDFium is now automatically initialized in the constructor, simplifying the API and reducing boilerplate.
10+
11+
## Breaking Changes
12+
13+
### `initialize()` Method Removed
14+
15+
The `initialize()` method has been removed from:
16+
17+
- `PdfiumNative` (formerly `PdfiumEngine`)
18+
- `PdfEngine` orchestrator
19+
- `RemoteExecutor`
20+
- `WebWorkerEngine`
21+
- `IPdfiumExecutor` interface
22+
- `PdfEngine` interface (in models)
23+
24+
**Migration:**
25+
26+
```typescript
27+
// Before
28+
const native = new PdfiumNative(wasmModule, { logger });
29+
native.initialize();
30+
31+
const engine = new PdfEngine(native, { imageConverter, logger });
32+
engine.initialize();
33+
34+
// After - no initialize() needed!
35+
const native = new PdfiumNative(wasmModule, { logger });
36+
const engine = new PdfEngine(native, { imageConverter, logger });
37+
38+
// Ready to use immediately
39+
const doc = await engine.openDocumentBuffer(file).toPromise();
40+
```
41+
42+
### Framework Hooks Simplified
43+
44+
The `usePdfiumEngine` hooks (React, Vue, Svelte) no longer require calling `initialize()`:
45+
46+
```typescript
47+
// Before
48+
const { engine, isLoading } = usePdfiumEngine();
49+
const [initialized, setInitialized] = useState(false);
50+
51+
useEffect(() => {
52+
if (engine && !initialized) {
53+
engine.initialize().wait(setInitialized, ignore);
54+
}
55+
}, [engine, initialized]);
56+
57+
// After - engine is ready when returned!
58+
const { engine, isLoading } = usePdfiumEngine();
59+
60+
if (!isLoading && engine) {
61+
// Ready to use immediately
62+
}
63+
```
64+
65+
### `PluginRegistry.ensureEngineInitialized()` Removed
66+
67+
The `ensureEngineInitialized()` method and `engineInitialized` property have been removed from `PluginRegistry` since engines are now initialized in their constructors.
68+
69+
## Cross-Platform Image Data
70+
71+
### `ImageData``ImageDataLike`
72+
73+
The engine now returns `ImageDataLike` (a plain object with `data`, `width`, `height`) instead of the browser-specific `ImageData` class. This enables Node.js compatibility without polyfills.
74+
75+
**Affected types:**
76+
77+
- `PdfImageObject.imageData` now uses `ImageDataLike`
78+
- All raw render methods return `ImageDataLike`
79+
80+
### Browser Converter Fallback
81+
82+
`browserImageDataToBlobConverter` now falls back to regular `<canvas>` when `OffscreenCanvas` is not available (older browsers). The hybrid converter (`createHybridImageConverter`) uses:
83+
84+
1. Worker pool with `OffscreenCanvas` (preferred, non-blocking)
85+
2. Main-thread `<canvas>` fallback (blocking, but works everywhere)
86+
87+
## Benefits
88+
89+
- **Simpler API**: One less step to get started
90+
- **Less boilerplate**: No more `initialize()` calls in every component
91+
- **Node.js compatible**: `ImageDataLike` works without browser APIs
92+
- **Broader browser support**: Canvas fallback for older browsers

packages/core/src/lib/registry/plugin-registry.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export class PluginRegistry {
3434
private resolver: DependencyResolver;
3535
private configurations: Map<string, unknown> = new Map();
3636
private engine: PdfEngine;
37-
private engineInitialized = false;
3837
private store: Store<CoreState, CoreAction>;
3938
private initPromise: Promise<void> | null = null;
4039
private logger: Logger;
@@ -62,23 +61,6 @@ export class PluginRegistry {
6261
return this.logger;
6362
}
6463

65-
/**
66-
* Ensure engine is initialized before proceeding
67-
*/
68-
private async ensureEngineInitialized(): Promise<void> {
69-
if (this.engineInitialized) {
70-
return;
71-
}
72-
73-
if (this.engine.initialize) {
74-
const task = this.engine.initialize();
75-
await task.toPromise();
76-
this.engineInitialized = true;
77-
} else {
78-
this.engineInitialized = true;
79-
}
80-
}
81-
8264
/**
8365
* Register a plugin without initializing it
8466
*/
@@ -181,7 +163,6 @@ export class PluginRegistry {
181163
this.isInitializing = true;
182164

183165
try {
184-
await this.ensureEngineInitialized();
185166
if (this.destroyed) return;
186167

187168
while (this.pendingRegistrations.length > 0) {

packages/engines/README.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
# @embedpdf/engines
1212

13-
Pluggable rendering engines for EmbedPDF. Ships with **`PdfiumEngine`** – a highlevel, promise‑first wrapper built on top of `@embedpdf/pdfium`.
13+
Pluggable rendering engines for EmbedPDF. Ships with **`PdfiumNative`** (low-level executor) and **`PdfEngine`** (high-level orchestrator) – a promise‑first API built on top of `@embedpdf/pdfium`.
1414

1515
## Documentation
1616

@@ -43,23 +43,29 @@ npm install @embedpdf/engines @embedpdf/pdfium
4343

4444
```typescript
4545
import { init } from '@embedpdf/pdfium';
46-
import { PdfiumEngine } from '@embedpdf/engines/pdfium';
46+
import { PdfiumNative, PdfEngine } from '@embedpdf/engines/pdfium';
47+
import { browserImageDataToBlobConverter } from '@embedpdf/engines/converters';
4748

4849
const pdfiumWasm =
4950
'https://cdn.jsdelivr.net/npm/@embedpdf/pdfium/dist/pdfium.wasm';
5051

5152
(async () => {
5253
const response = await fetch(pdfiumWasm);
5354
const wasmBinary = await response.arrayBuffer();
54-
// 1 – boot the low‑level WASM module
55-
const pdfium = await init({ wasmBinary });
5655

57-
// 2 – create the high‑level engine
58-
const engine = new PdfiumEngine(pdfium);
59-
engine.initialize();
56+
// 1 – boot the low‑level WASM module
57+
const pdfiumModule = await init({ wasmBinary });
6058

61-
// 3 – open & render
62-
const document = await engine
59+
// 2 – create the native executor (initializes PDFium automatically)
60+
const native = new PdfiumNative(pdfiumModule);
61+
62+
// 3 – create the orchestrator with image converter
63+
const engine = new PdfEngine(native, {
64+
imageConverter: browserImageDataToBlobConverter,
65+
});
66+
67+
// 4 – open & render
68+
const doc = await engine
6369
.openDocumentUrl({ id: 'demo', url: '/demo.pdf' })
6470
.toPromise();
6571
const page0 = doc.pages[0];

packages/engines/demo/main.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ async function run() {
3636
});
3737
const engine = new WebWorkerEngine(worker, logger);
3838

39-
engine.initialize();
40-
4139
const passwordElem = document.getElementById('pdf-password') as HTMLInputElement;
4240
const inputElem = document.getElementById('pdf-file') as HTMLInputElement;
4341
const bookmarksElem = document.getElementById('pdf-bookmarks') as HTMLParagraphElement;

packages/engines/examples/node/annotation-render-example.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,31 @@ import { fileURLToPath } from 'url';
44
import sharp from 'sharp';
55

66
import { init } from '@embedpdf/pdfium';
7-
import { PdfiumEngine } from '@embedpdf/engines/pdfium';
7+
import { PdfiumNative, PdfEngine } from '@embedpdf/engines/pdfium';
88
import { createNodeImageDataToBufferConverter } from '@embedpdf/engines/converters';
99
import { ConsoleLogger, Rotation } from '@embedpdf/models';
1010

1111
const __filename = fileURLToPath(import.meta.url);
1212
const __dirname = dirname(__filename);
1313

1414
async function runExample() {
15-
const consoleLogger = new ConsoleLogger();
15+
const logger = new ConsoleLogger();
1616

17+
// Create the image converter using sharp
1718
const imageConverter = createNodeImageDataToBufferConverter(sharp);
1819

19-
// Initialize PDFium
20-
const pdfiumInstance = await init();
21-
const engine = new PdfiumEngine(pdfiumInstance, {
22-
logger: consoleLogger,
23-
imageDataConverter: imageConverter,
20+
// Initialize PDFium WASM module
21+
const pdfiumModule = await init();
22+
23+
// Create the native executor (low-level PDFium wrapper)
24+
const native = new PdfiumNative(pdfiumModule, { logger });
25+
26+
// Create the orchestrator (high-level API with priority scheduling)
27+
// PdfiumNative initializes PDFium in its constructor, no separate init needed
28+
const engine = new PdfEngine(native, {
29+
imageConverter,
30+
logger,
2431
});
25-
engine.initialize();
2632

2733
const pdfPath = process.argv[2] || join(__dirname, 'sample.pdf');
2834
const pdfBuffer = await readFile(pdfPath);

packages/engines/examples/node/basic-example.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,31 @@ import { fileURLToPath } from 'url';
44
import sharp from 'sharp';
55

66
import { init } from '@embedpdf/pdfium';
7-
import { PdfiumEngine } from '@embedpdf/engines/pdfium';
7+
import { PdfiumNative, PdfEngine } from '@embedpdf/engines/pdfium';
88
import { createNodeImageDataToBufferConverter } from '@embedpdf/engines/converters';
99
import { ConsoleLogger, Rotation } from '@embedpdf/models';
1010

1111
const __filename = fileURLToPath(import.meta.url);
1212
const __dirname = dirname(__filename);
1313

1414
async function runExample() {
15-
const consoleLogger = new ConsoleLogger();
15+
const logger = new ConsoleLogger();
1616

17+
// Create the image converter using sharp
1718
const imageConverter = createNodeImageDataToBufferConverter(sharp);
1819

19-
// Initialize PDFium
20-
const pdfiumInstance = await init();
21-
const engine = new PdfiumEngine(pdfiumInstance, {
22-
logger: consoleLogger,
23-
imageDataConverter: imageConverter,
20+
// Initialize PDFium WASM module
21+
const pdfiumModule = await init();
22+
23+
// Create the native executor (low-level PDFium wrapper)
24+
const native = new PdfiumNative(pdfiumModule, { logger });
25+
26+
// Create the orchestrator (high-level API with priority scheduling)
27+
// PdfiumNative initializes PDFium in its constructor, no separate init needed
28+
const engine = new PdfEngine(native, {
29+
imageConverter,
30+
logger,
2431
});
25-
engine.initialize();
2632

2733
const pdfPath = process.argv[2] || join(__dirname, 'sample.pdf');
2834
const pdfBuffer = await readFile(pdfPath);

packages/engines/examples/node/read-write-metadata.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,31 @@ import { fileURLToPath } from 'url';
44
import sharp from 'sharp';
55

66
import { init } from '@embedpdf/pdfium';
7-
import { PdfiumEngine } from '@embedpdf/engines/pdfium';
7+
import { PdfiumNative, PdfEngine } from '@embedpdf/engines/pdfium';
88
import { createNodeImageDataToBufferConverter } from '@embedpdf/engines/converters';
99
import { ConsoleLogger, PdfTrappedStatus } from '@embedpdf/models';
1010

1111
const __filename = fileURLToPath(import.meta.url);
1212
const __dirname = dirname(__filename);
1313

1414
async function runExample() {
15-
const consoleLogger = new ConsoleLogger();
15+
const logger = new ConsoleLogger();
1616

17+
// Create the image converter using sharp
1718
const imageConverter = createNodeImageDataToBufferConverter(sharp);
1819

19-
// Initialize PDFium
20-
const pdfiumInstance = await init();
21-
const engine = new PdfiumEngine(pdfiumInstance, {
22-
logger: consoleLogger,
23-
imageDataConverter: imageConverter,
20+
// Initialize PDFium WASM module
21+
const pdfiumModule = await init();
22+
23+
// Create the native executor (low-level PDFium wrapper)
24+
const native = new PdfiumNative(pdfiumModule, { logger });
25+
26+
// Create the orchestrator (high-level API with priority scheduling)
27+
// PdfiumNative initializes PDFium in its constructor, no separate init needed
28+
const engine = new PdfEngine(native, {
29+
imageConverter,
30+
logger,
2431
});
25-
engine.initialize();
2632

2733
const pdfPath = process.argv[2] || join(__dirname, 'ebook.pdf');
2834
const pdfBuffer = await readFile(pdfPath);

0 commit comments

Comments
 (0)