Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/engines/src/lib/pdfium/web/direct-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ export interface CreatePdfiumEngineOptions {
* when it encounters text that requires fonts not embedded in the PDF.
*/
fontFallback?: FontFallbackConfig;
/**
* URL to the PDFium worker script (worker mode only).
* Avoids `worker-src blob:` in strict CSP environments.
*/
workerUrl?: string;
/**
* URL to the image encoder worker script (worker mode only).
* Avoids `worker-src blob:` in strict CSP environments.
*/
encoderWorkerUrl?: string;
}

/**
Expand Down
41 changes: 30 additions & 11 deletions packages/engines/src/lib/pdfium/web/worker-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,27 @@ export interface CreatePdfiumEngineOptions {
* when it encounters text that requires fonts not embedded in the PDF.
*/
fontFallback?: FontFallbackConfig;
/**
* URL to the PDFium worker script.
* When provided, the worker is loaded from this URL instead of a blob: URL,
* allowing strict CSP without `worker-src blob:`.
*
* @example
* // Vite
* workerUrl: new URL('@embedpdf/engines/pdfium-worker', import.meta.url).href
* // Or a static asset
* workerUrl: '/assets/embedpdf-worker.js'
Comment on lines +38 to +41
*/
workerUrl?: string;
/**
* URL to the image encoder worker script.
* When provided, the encoder pool workers are loaded from this URL instead
* of a blob: URL, allowing strict CSP without `worker-src blob:`.
*
* @example
* encoderWorkerUrl: '/assets/embedpdf-encoder-worker.js'
*/
encoderWorkerUrl?: string;
}

/**
Expand Down Expand Up @@ -70,22 +91,20 @@ export function createPdfiumEngine(
? { logger: options as Logger }
: (options as CreatePdfiumEngineOptions) || {};

const { logger, encoderPoolSize, fontFallback } = config;
const { logger, encoderPoolSize, fontFallback, workerUrl, encoderWorkerUrl } = config;

// Create PDFium worker
const worker = new Worker(
URL.createObjectURL(new Blob([__WEBWORKER_BODY__], { type: 'application/javascript' })),
{
type: 'module',
},
);
// Create PDFium worker — use a static URL when provided to avoid blob: in CSP
const resolvedWorkerUrl =
workerUrl ??
URL.createObjectURL(new Blob([__WEBWORKER_BODY__], { type: 'application/javascript' }));
const worker = new Worker(resolvedWorkerUrl, { type: 'module' });

// Create RemoteExecutor (proxy to worker) - handles wasmInit internally
const remoteExecutor = new RemoteExecutor(worker, { wasmUrl, logger, fontFallback });

const finalEncoderWorkerUrl = URL.createObjectURL(
new Blob([__ENCODER_WORKER_BODY__], { type: 'application/javascript' }),
);
const finalEncoderWorkerUrl =
encoderWorkerUrl ??
URL.createObjectURL(new Blob([__ENCODER_WORKER_BODY__], { type: 'application/javascript' }));
const encoderPool = new ImageEncoderWorkerPool(
encoderPoolSize ?? 2,
finalEncoderWorkerUrl,
Expand Down
10 changes: 9 additions & 1 deletion packages/engines/src/shared/hooks/use-pdfium-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ interface UsePdfiumEngineProps {
* Font fallback configuration for handling missing fonts in PDFs.
*/
fontFallback?: FontFallbackConfig;
/** URL to the PDFium worker script. Avoids `worker-src blob:` in strict CSP. */
workerUrl?: string;
/** URL to the image encoder worker script. Avoids `worker-src blob:` in strict CSP. */
encoderWorkerUrl?: string;
}

export function usePdfiumEngine(config?: UsePdfiumEngineProps) {
Expand All @@ -22,6 +26,8 @@ export function usePdfiumEngine(config?: UsePdfiumEngineProps) {
logger,
encoderPoolSize,
fontFallback,
workerUrl,
encoderWorkerUrl,
} = config ?? {};

const [engine, setEngine] = useState<PdfEngine | null>(null);
Expand All @@ -42,6 +48,8 @@ export function usePdfiumEngine(config?: UsePdfiumEngineProps) {
logger,
encoderPoolSize,
fontFallback,
workerUrl,
encoderWorkerUrl,
});
engineRef.current = pdfEngine;
setEngine(pdfEngine);
Expand All @@ -61,7 +69,7 @@ export function usePdfiumEngine(config?: UsePdfiumEngineProps) {
engineRef.current = null;
}, ignore);
};
}, [wasmUrl, worker, logger, fontFallback]);
}, [wasmUrl, worker, logger, fontFallback, workerUrl, encoderWorkerUrl]);

return { engine, isLoading: loading, error };
}
8 changes: 6 additions & 2 deletions packages/engines/src/svelte/hooks/use-pdfium-engine.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ export interface UsePdfiumEngineProps {
* Font fallback configuration for handling missing fonts in PDFs.
*/
fontFallback?: FontFallbackConfig;
/** URL to the PDFium worker script. Avoids `worker-src blob:` in strict CSP. */
workerUrl?: string;
/** URL to the image encoder worker script. Avoids `worker-src blob:` in strict CSP. */
encoderWorkerUrl?: string;
}

export function usePdfiumEngine(config?: UsePdfiumEngineProps) {
const { wasmUrl = defaultWasmUrl, worker = true, logger, fontFallback } = config ?? {};
const { wasmUrl = defaultWasmUrl, worker = true, logger, fontFallback, workerUrl, encoderWorkerUrl } = config ?? {};

// Create a reactive state object
const state = $state({
Expand All @@ -38,7 +42,7 @@ export function usePdfiumEngine(config?: UsePdfiumEngineProps) {
? await import('@embedpdf/engines/pdfium-worker-engine')
: await import('@embedpdf/engines/pdfium-direct-engine');

const pdfEngine = await createPdfiumEngine(wasmUrl, { logger, fontFallback });
const pdfEngine = await createPdfiumEngine(wasmUrl, { logger, fontFallback, workerUrl, encoderWorkerUrl });
engineRef = pdfEngine;
state.engine = pdfEngine;
state.isLoading = false;
Expand Down
8 changes: 6 additions & 2 deletions packages/engines/src/vue/composables/use-pdfium-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ interface UsePdfiumEngineProps {
* Font fallback configuration for handling missing fonts in PDFs.
*/
fontFallback?: FontFallbackConfig;
/** URL to the PDFium worker script. Avoids `worker-src blob:` in strict CSP. */
workerUrl?: string;
/** URL to the image encoder worker script. Avoids `worker-src blob:` in strict CSP. */
encoderWorkerUrl?: string;
}

interface UsePdfiumEngineResult {
Expand All @@ -26,7 +30,7 @@ interface UsePdfiumEngineResult {
* and keeps its lifetime tied to the component.
*/
export function usePdfiumEngine(props: UsePdfiumEngineProps = {}): UsePdfiumEngineResult {
const { wasmUrl = defaultWasmUrl, worker = true, logger, fontFallback } = props;
const { wasmUrl = defaultWasmUrl, worker = true, logger, fontFallback, workerUrl, encoderWorkerUrl } = props;

const engine = ref<PdfEngine | null>(null);
const isLoading = ref(true);
Expand All @@ -51,7 +55,7 @@ export function usePdfiumEngine(props: UsePdfiumEngineProps = {}): UsePdfiumEngi
? await import('@embedpdf/engines/pdfium-worker-engine')
: await import('@embedpdf/engines/pdfium-direct-engine');

const pdfEngine = await createPdfiumEngine(wasmUrl, { logger, fontFallback });
const pdfEngine = await createPdfiumEngine(wasmUrl, { logger, fontFallback, workerUrl, encoderWorkerUrl });
engine.value = pdfEngine;
isLoading.value = false;
} catch (e) {
Expand Down
Loading