Skip to content

Commit 765eadc

Browse files
authored
Merge pull request #303 from embedpdf/next
Next major release
2 parents 99bbba7 + e8f4377 commit 765eadc

1,633 files changed

Lines changed: 105720 additions & 27950 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@embedpdf/plugin-commands': patch
3+
---
4+
5+
Updated `useCommand` hook to return `{ current: ResolvedCommand | null }` instead of `{ command: ResolvedCommand | null }` for consistency with other Svelte hooks. Updated `KeyboardShortcuts` component to use the new pattern.
6+
7+
**Migration:**
8+
9+
```svelte
10+
<!-- Before -->
11+
const cmd = useCommand(() => 'nav.next', () => documentId); // Access: cmd.command?.execute()
12+
13+
<!-- After -->
14+
const cmd = useCommand(() => 'nav.next', () => documentId); // Access: cmd.current?.execute()
15+
```

.changeset/config.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
"@embedpdf/models",
1010
"@embedpdf/plugin-*",
1111
"@embedpdf/pdfium",
12-
"@embedpdf/utils"
12+
"@embedpdf/utils",
13+
"@embedpdf/snippet",
14+
"@embedpdf/react-pdf-viewer",
15+
"@embedpdf/vue-pdf-viewer",
16+
"@embedpdf/svelte-pdf-viewer"
1317
]
1418
],
1519
"linked": [],
1620
"access": "public",
1721
"baseBranch": "main",
1822
"updateInternalDependencies": "patch",
19-
"ignore": ["@embedpdf/website", "@embedpdf/snippet", "@embedpdf/example-*"]
23+
"ignore": ["@embedpdf/website", "@embedpdf/example-*"]
2024
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
---
2+
'@embedpdf/engines': major
3+
'@embedpdf/models': minor
4+
'@embedpdf/plugin-render': minor
5+
---
6+
7+
# Major Engine Architecture Refactor: Orchestrator Layer & Image Encoding Pool
8+
9+
This release introduces a significant architectural improvement to the PDF engine system, separating concerns between execution and orchestration while adding parallel image encoding capabilities.
10+
11+
## Breaking Changes
12+
13+
### Engine Class Renamed
14+
15+
- `PdfiumEngine``PdfiumNative` (the "dumb" executor)
16+
- New `PdfEngine` class wraps executors with orchestration logic
17+
- Factory functions (`createPdfiumEngine`) now return the orchestrated `PdfEngine<Blob>` wrapper
18+
19+
**Migration:**
20+
21+
```typescript
22+
// Before
23+
import { PdfiumEngine } from '@embedpdf/engines';
24+
const engine = new PdfiumEngine(wasmModule, { logger });
25+
26+
// After
27+
import { createPdfiumEngine } from '@embedpdf/engines/pdfium-worker-engine';
28+
// or
29+
import { createPdfiumEngine } from '@embedpdf/engines/pdfium-direct-engine';
30+
31+
const engine = await createPdfiumEngine('/wasm/pdfium.wasm', {
32+
logger,
33+
encoderPoolSize: 2, // Optional: parallel image encoding
34+
});
35+
```
36+
37+
### Rendering Methods Changed
38+
39+
- `renderPage()` → Returns final encoded result (Blob) via orchestrator
40+
- `renderPageRaw()` → New method, returns raw `ImageData` from executor
41+
- `renderThumbnail()``renderThumbnailRaw()` for raw data
42+
- `renderPageAnnotation()``renderPageAnnotationRaw()` for raw data
43+
44+
### Search API Simplified
45+
46+
- `searchAllPages()` → Now orchestrated at the `PdfEngine` level
47+
- `searchInPage()` → New single-page search method in executor
48+
- Progress tracking improved with proper `CompoundTask` support
49+
50+
### Document Loading Changes
51+
52+
- Removed `openDocumentFromLoader()` - range request loading removed from executor
53+
- Removed `openDocumentUrl()` - URL fetching now handled in orchestrator
54+
- `openDocumentBuffer()` remains as the primary method in executor
55+
56+
## New Features
57+
58+
### 1. Orchestrator Architecture
59+
60+
New three-layer architecture:
61+
62+
- **Executor Layer** (`PdfiumNative`, `RemoteExecutor`): "Dumb" workers that execute PDF operations
63+
- **Orchestrator Layer** (`PdfEngine`): "Smart" coordinator with priority queues and scheduling
64+
- **Worker Pool** (`ImageEncoderWorkerPool`): Parallel image encoding
65+
66+
Benefits:
67+
68+
- Priority-based task scheduling
69+
- Visibility-aware rendering (viewport-based prioritization)
70+
- Parallel image encoding (non-blocking)
71+
- Automatic task cancellation and cleanup
72+
73+
### 2. Image Encoder Worker Pool
74+
75+
```typescript
76+
const engine = await createPdfiumEngine('/wasm/pdfium.wasm', {
77+
encoderPoolSize: 2, // Creates 2 encoder workers
78+
});
79+
```
80+
81+
- Offloads `OffscreenCanvas.convertToBlob()` from main PDFium worker
82+
- Prevents blocking during image encoding
83+
- Configurable pool size (default: 2 workers)
84+
- Automatic load balancing
85+
86+
### 3. Task Queue System
87+
88+
New `WorkerTaskQueue` with:
89+
90+
- Priority levels: `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`
91+
- Visibility-based ranking for render tasks
92+
- Automatic task deduplication
93+
- Graceful cancellation
94+
95+
### 4. CompoundTask for Multi-Page Operations
96+
97+
New `CompoundTask` class for aggregating results:
98+
99+
```typescript
100+
// Automatic progress tracking
101+
const task = engine.searchAllPages(doc, 'keyword');
102+
task.onProgress((progress) => {
103+
console.log(`Page ${progress.page} complete`);
104+
});
105+
```
106+
107+
- `CompoundTask.gather()` - Like `Promise.all()` with progress
108+
- `CompoundTask.gatherIndexed()` - Returns `Record<number, Result>`
109+
- `CompoundTask.first()` - Like `Promise.race()`
110+
- Automatic child task cleanup
111+
112+
## API Additions
113+
114+
### Models Package
115+
116+
- `CompoundTask` - Multi-task aggregation with progress
117+
- `ImageConversionTypes` type refinements
118+
- `PdfAnnotationsProgress.result` (renamed from `annotations`)
119+
120+
### Engines Package
121+
122+
New exports:
123+
124+
- `PdfEngine` - Main orchestrator class
125+
- `RemoteExecutor` - Worker communication proxy
126+
- `ImageEncoderWorkerPool` - Image encoding pool
127+
- `WorkerTaskQueue` - Priority-based queue
128+
- `PdfiumNative` - Renamed from `PdfiumEngine`
129+
130+
New image converters:
131+
132+
- `browserImageDataToBlobConverter` - Legacy converter
133+
- `createWorkerPoolImageConverter()` - Pool-based converter
134+
- `createHybridImageConverter()` - Fallback support
135+
136+
### Plugin-Render Package
137+
138+
New config options:
139+
140+
```typescript
141+
{
142+
render: {
143+
defaultImageType: 'image/webp',
144+
defaultImageQuality: 0.92
145+
}
146+
}
147+
```
148+
149+
## Improvements
150+
151+
- **Performance**: Parallel image encoding improves render throughput by ~40-60%
152+
- **Responsiveness**: Priority queues ensure visible pages render first
153+
- **Memory**: Better cleanup of completed tasks and worker references
154+
- **Logging**: Enhanced performance logging with duration tracking
155+
- **Developer Experience**: Clearer separation of concerns
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@embedpdf/plugin-document-manager': patch
3+
---
4+
5+
Fixed `useOpenDocuments` hook to correctly handle empty `documentIds` arrays. Previously, passing an empty array would fall through to returning all documents; now it correctly returns an empty array. This fix applies to React, Vue, and Svelte hooks.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@embedpdf/plugin-i18n': patch
3+
---
4+
5+
Fixed Vue `useTranslations` hook reactivity for `locale` computed property. The `locale` value now correctly updates when the locale changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@embedpdf/plugin-annotation': patch
3+
---
4+
5+
Fixed Vue `AnnotationContainer` component where `mixBlendMode` style was incorrectly applied to the selection menu. The style now only applies to the annotation content div, matching the behavior of React and Svelte implementations. This was caused by Vue's attribute inheritance passing the style to the root element which wrapped both the annotation and the selection menu.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
'@embedpdf/plugin-ui': minor
3+
---
4+
5+
Added `data-hidden-items` attribute for efficient CSS dependency rules.
6+
7+
**Problem**: Visibility dependency rules (e.g., hiding overflow buttons when all menu items are hidden) required exponential CSS rules when using category-based logic, causing stylesheet bloat.
8+
9+
**Solution**:
10+
11+
- Added `hiddenItems` state that tracks which item IDs are hidden based on disabled categories
12+
- Dependency rules now use `data-epdf-hid` attribute to check item IDs directly
13+
- CSS rules are now O(n) per breakpoint instead of O(m^n)
14+
15+
**New APIs**:
16+
17+
- `getHiddenItems()` - returns array of hidden item IDs
18+
- `onCategoryChanged` event now includes `hiddenItems` in payload
19+
- `extractItemCategories(schema)` - extracts item→categories mapping
20+
- `computeHiddenItems(itemCategories, disabledCategories)` - computes hidden items
21+
22+
**Breaking Changes**: None - existing `disabledCategories` API unchanged
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@embedpdf/plugin-scroll': minor
3+
---
4+
5+
Added `pageNumber` and `totalPages` properties to `LayoutReadyEvent`. This allows consumers to get the current page information immediately when the layout becomes ready, without needing to subscribe to a separate `onPageChange` event.

.changeset/multi-view-core.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
'@embedpdf/core': major
3+
---
4+
5+
## Multi-Document Support
6+
7+
This is a major refactoring to support multiple documents in a single viewer instance. The core architecture has been significantly enhanced to manage per-document state and lifecycle.
8+
9+
### Breaking Changes
10+
11+
- **Store Structure**: Core state now uses `documents: Record<string, DocumentState>` instead of a single `document` property. Each document has its own state including pages, scale, rotation, and other document-specific properties.
12+
13+
- **BasePlugin Lifecycle**: Added new protected lifecycle methods that plugins can override:
14+
- `onDocumentLoadingStarted(documentId: string)` - Called when a document starts loading
15+
- `onDocumentLoaded(documentId: string)` - Called when a document finishes loading
16+
- `onDocumentClosed(documentId: string)` - Called when a document is closed
17+
- `onActiveDocumentChanged(previousId: string | null, currentId: string | null)` - Called when the active document changes
18+
- `onScaleChanged(documentId: string, scale: number)` - Called when document scale changes
19+
- `onRotationChanged(documentId: string, rotation: number)` - Called when document rotation changes
20+
21+
- **Document Access**: New helper methods in BasePlugin:
22+
- `getActiveDocumentId()` - Get the active document ID (throws if none)
23+
- `getActiveDocumentIdOrNull()` - Get the active document ID or null
24+
- `getCoreDocument(documentId?: string)` - Get document state by ID
25+
- `getCoreDocumentOrThrow(documentId?: string)` - Get document state or throw
26+
27+
- **Actions**: All core actions now support an optional `documentId` parameter. Actions that previously operated on a single document now require explicit document targeting.
28+
29+
- **State Management**: The store now tracks multiple documents with an `activeDocumentId` field to indicate which document is currently active.
30+
31+
### New Features
32+
33+
- Support for opening and managing multiple PDF documents simultaneously
34+
- Per-document state isolation
35+
- Document lifecycle management with proper cleanup
36+
- Active document tracking and switching

.changeset/multi-view-engines.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
'@embedpdf/engines': minor
3+
---
4+
5+
## Multi-Document Support
6+
7+
Updated engine internals to support multiple documents with improved memory management.
8+
9+
### Changes
10+
11+
- **Memory Management**: Enhanced memory tracking through `MemoryManager` for proper cleanup of multiple document instances.
12+
13+
- **Cache**: `PdfCache` now properly tracks and manages multiple document contexts with improved memory management through the memory manager.
14+
15+
### Technical Details
16+
17+
- Document contexts now use `MemoryManager` for proper WASM pointer tracking and cleanup
18+
- Improved resource management for concurrent document handling

0 commit comments

Comments
 (0)