Skip to content

Commit 7eb8b5b

Browse files
committed
Make the native runtimes work
1 parent aed9539 commit 7eb8b5b

27 files changed

Lines changed: 4706 additions & 800 deletions
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!doctype html>
2+
<html>
3+
<body>
4+
<h1>pdf-runtime browser demo</h1>
5+
<pre id="out">Loading...</pre>
6+
<script type="module" src="/src/browser.ts"></script>
7+
</body>
8+
</html>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "@embedpdf/example-pdf-runtime-demo",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"node": "tsx src/node.ts",
9+
"node:wasm": "PDF_RUNTIME_PREFER=wasm tsx src/node.ts"
10+
},
11+
"dependencies": {
12+
"@embedpdf/pdf-runtime": "workspace:*"
13+
},
14+
"devDependencies": {
15+
"@types/node": "^22.19.0",
16+
"tsx": "^4.19.0",
17+
"vite": "^5.4.0"
18+
}
19+
}
513 KB
Binary file not shown.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { createPdfRuntime } from '@embedpdf/pdf-runtime';
2+
import { runDemo } from './demo.ts';
3+
4+
const out = document.getElementById('out');
5+
if (!out) throw new Error('out element not found');
6+
7+
try {
8+
const runtime = await createPdfRuntime({ prefer: 'wasm' });
9+
const bytes = new Uint8Array(await (await fetch('/sample.pdf')).arrayBuffer());
10+
const result = await runDemo(runtime, bytes);
11+
out.textContent = JSON.stringify(result, null, 2);
12+
await runtime.destroy();
13+
} catch (e) {
14+
out.textContent = 'Error: ' + (e instanceof Error ? (e.stack ?? e.message) : String(e));
15+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type { PdfRuntimeModule } from '@embedpdf/pdf-runtime';
2+
3+
export interface DemoResult {
4+
platform: string;
5+
kind: PdfRuntimeModule['kind'];
6+
pageCount: number;
7+
}
8+
9+
export async function runDemo(
10+
runtime: PdfRuntimeModule,
11+
pdfBytes: Uint8Array,
12+
): Promise<DemoResult> {
13+
const { fn, mem } = runtime;
14+
15+
fn.FPDF_InitLibrary();
16+
17+
const ptr = mem.alloc(pdfBytes.byteLength);
18+
mem.writeBytes(ptr, pdfBytes);
19+
const doc = fn.FPDF_LoadMemDocument(ptr, pdfBytes.byteLength, '');
20+
if (!doc) {
21+
mem.free(ptr);
22+
fn.FPDF_DestroyLibrary();
23+
throw new Error('FPDF_LoadMemDocument returned null');
24+
}
25+
26+
const pageCount = fn.FPDF_GetPageCount(doc);
27+
28+
fn.FPDF_CloseDocument(doc);
29+
mem.free(ptr);
30+
fn.FPDF_DestroyLibrary();
31+
32+
return { platform: runtime.platform, kind: runtime.kind, pageCount };
33+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { readFile } from 'node:fs/promises';
2+
import { dirname, resolve } from 'node:path';
3+
import { fileURLToPath } from 'node:url';
4+
import { createPdfRuntime } from '@embedpdf/pdf-runtime';
5+
import { runDemo } from './demo.ts';
6+
7+
const here = dirname(fileURLToPath(import.meta.url));
8+
const pdfPath = process.argv[2] ?? resolve(here, '..', 'public', 'sample.pdf');
9+
const bytes = new Uint8Array(await readFile(pdfPath));
10+
11+
const prefer = process.env.PDF_RUNTIME_PREFER === 'wasm' ? 'wasm' : 'auto';
12+
const runtime = await createPdfRuntime({ prefer });
13+
14+
try {
15+
const result = await runDemo(runtime, bytes);
16+
console.log(JSON.stringify(result, null, 2));
17+
} finally {
18+
await runtime.destroy();
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ESNext",
4+
"module": "ESNext",
5+
"moduleResolution": "Bundler",
6+
"allowImportingTsExtensions": true,
7+
"noEmit": true,
8+
"strict": true,
9+
"esModuleInterop": true,
10+
"skipLibCheck": true,
11+
"resolveJsonModule": true,
12+
"isolatedModules": true,
13+
"lib": ["ESNext", "DOM"],
14+
"types": ["node"]
15+
},
16+
"include": ["src/**/*"]
17+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { defineConfig } from 'vite';
2+
3+
export default defineConfig({
4+
optimizeDeps: { exclude: ['@embedpdf/pdf-runtime-wasm32'] },
5+
});

packages/pdf-runtime/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ build/local-staging/
1010

1111
npm/*/pdf-runtime.node
1212
npm/win32-*/pdfium.dll
13+
npm/darwin-*/libpdfium.dylib
14+
npm/linux-*/libpdfium.so
1315
npm/wasm32/pdfium.js
1416
npm/wasm32/pdfium.cjs
1517
npm/wasm32/pdfium.wasm

packages/pdf-runtime/build/CMakeLists.txt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,22 @@ target_include_directories(${PROJECT_NAME} PRIVATE
2525

2626
if(WIN32)
2727
set(PDFIUM_LIB "${PDFIUM_LIB_DIR}/pdfium.dll.lib")
28-
else()
29-
set(PDFIUM_LIB "${PDFIUM_LIB_DIR}/libpdfium.a")
28+
elseif(APPLE)
29+
set(PDFIUM_LIB "${PDFIUM_LIB_DIR}/libpdfium.dylib")
30+
set_target_properties(${PROJECT_NAME} PROPERTIES
31+
BUILD_RPATH "@loader_path"
32+
INSTALL_RPATH "@loader_path"
33+
)
34+
elseif(UNIX)
35+
if(EXISTS "${PDFIUM_LIB_DIR}/libpdfium.so")
36+
set(PDFIUM_LIB "${PDFIUM_LIB_DIR}/libpdfium.so")
37+
set_target_properties(${PROJECT_NAME} PROPERTIES
38+
BUILD_RPATH "$ORIGIN"
39+
INSTALL_RPATH "$ORIGIN"
40+
)
41+
else()
42+
set(PDFIUM_LIB "${PDFIUM_LIB_DIR}/libpdfium.a")
43+
endif()
3044
endif()
3145

3246
target_link_libraries(${PROJECT_NAME} PRIVATE

0 commit comments

Comments
 (0)