unpdf 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # unpdf
2
2
 
3
- A collection of utilities for PDF extraction and rendering. Designed specifically for Bun, Deno, and serverless environments. However, it also works in Node.js and the browser.
3
+ A collection of utilities for PDF extraction and rendering. Designed specifically for serverless environments, but it also works in Node.js, Deno, Bun and the browser. `unpdf` is particularly useful for serverless AI applications, especially for summarizing PDF documents in document analysis workflows.
4
4
 
5
- `unpdf` ships with a serverless build/redistribution of Mozilla's [PDF.js](https://github.com/mozilla/pdf.js) for serverless environments. Some string replacements and inlining the PDF.js worker allow the browser code to become platform agnostic. See [`pdfjs.rollup.config.ts`](./pdfjs.rollup.config.ts) for all the details.
5
+ This library ships with a serverless build/redistribution of Mozilla's [PDF.js](https://github.com/mozilla/pdf.js) that is optimized for edge environments. Some string replacements, global mocks and inlining the PDF.js worker allow the browser code to become platform agnostic. See [`pdfjs.rollup.config.ts`](./pdfjs.rollup.config.ts) for the details.
6
6
 
7
7
  This library is also intended as a modern alternative to the unmaintained but still popular [`pdf-parse`](https://www.npmjs.com/package/pdf-parse).
8
8
 
@@ -11,6 +11,7 @@ This library is also intended as a modern alternative to the unmaintained but st
11
11
  - 🏗️ Made for Node.js, browser and serverless environments
12
12
  - 🪭 Includes serverless build of PDF.js ([`unpdf/pdfjs`](./package.json#L34))
13
13
  - 💬 Extract [text](#extract-text-from-pdf) and [images](#extractimages) from PDF files
14
+ - 🧠 Perfect for AI applications and PDF summarization
14
15
  - 🧱 Opt-in to legacy PDF.js build
15
16
  - 💨 Zero dependencies
16
17
 
@@ -19,7 +20,7 @@ This library is also intended as a modern alternative to the unmaintained but st
19
20
  > [!Tip]
20
21
  > The serverless PDF.js bundle provided by `unpdf` is built from PDF.js v5.2.133.
21
22
 
22
- You can use an [official PDF.js build](#use-official-or-legacy-pdfjs-build) by using the [`definePDFJSModule`](#definepdfjsmodule) method. This is useful if you want to use a specific version or a custom build of PDF.js.
23
+ You can use an [official PDF.js build](#official-or-legacy-pdfjs-build) by using the [`definePDFJSModule`](#definepdfjsmodule) method. This is useful if you want to use a specific version or a custom build of PDF.js.
23
24
 
24
25
  ## Installation
25
26
 
@@ -58,6 +59,25 @@ console.log(`Total pages: ${totalPages}`)
58
59
  console.log(text)
59
60
  ```
60
61
 
62
+ ### Official or Legacy PDF.js Build
63
+
64
+ Usually you don't need to worry about the PDF.js build. `unpdf` ships with a serverless build of the latest PDF.js version. However, if you want to use the official PDF.js version or the legacy build, you can define a custom PDF.js module.
65
+
66
+ > [!WARNING]
67
+ > PDF.js v5.x uses `Promise.withResolvers`, which may not be supported in all environments, such as Node < 22. Consider to use the bundled serverless build, which includes a polyfill, or use an older version of PDF.js.
68
+
69
+ For example, if you want to use the official PDF.js build, you can do the following:
70
+
71
+ ```ts
72
+ import { definePDFJSModule } from 'unpdf'
73
+
74
+ // Define the PDF.js build before using any other unpdf method
75
+ await definePDFJSModule(() => import('pdfjs-dist'))
76
+
77
+ // Now, you can use all unpdf methods with the official PDF.js build
78
+ const { text } = await extractText(pdf)
79
+ ```
80
+
61
81
  ### PDF.js API
62
82
 
63
83
  `unpdf` provides helpful [methods](#api) to work with PDF files, such as `extractText` and `extractImages`, which should cover most use cases. However, if you need more control over the PDF.js API, you can use the `getResolvedPDFJS` method to get the resolved PDF.js module.
@@ -80,37 +100,18 @@ import { getResolvedPDFJS } from 'unpdf'
80
100
 
81
101
  const { getDocument } = await getResolvedPDFJS()
82
102
  const data = Deno.readFileSync('dummy.pdf')
83
- const doc = await getDocument(data).promise
103
+ const document = await getDocument(data).promise
84
104
 
85
- console.log(await doc.getMetadata())
105
+ console.log(await document.getMetadata())
86
106
 
87
- for (let i = 1; i <= doc.numPages; i++) {
88
- const page = await doc.getPage(i)
107
+ for (let i = 1; i <= document.numPages; i++) {
108
+ const page = await document.getPage(i)
89
109
  const textContent = await page.getTextContent()
90
110
  const contents = textContent.items.map(item => item.str).join(' ')
91
111
  console.log(contents)
92
112
  }
93
113
  ```
94
114
 
95
- ### Use Official or Legacy PDF.js Build
96
-
97
- Usually you don't need to worry about the PDF.js build. `unpdf` ships with a serverless build of the latest PDF.js version. However, if you want to use the official PDF.js version or the legacy build, you can define a custom PDF.js module.
98
-
99
- > [!WARNING]
100
- > Later PDF.js v4.x versions uses `Promise.withResolvers`, which may not be supported in all environments, such as Node < 22. Consider to use the bundled serverless build, which includes a polyfill, or use an older version of PDF.js.
101
-
102
- For example, if you want to use the official PDF.js build, you can do the following:
103
-
104
- ```ts
105
- import { definePDFJSModule } from 'unpdf'
106
-
107
- // Define the PDF.js build before using any other unpdf method
108
- await definePDFJSModule(() => import('pdfjs-dist'))
109
-
110
- // Now, you can use all unpdf methods with the official PDF.js build
111
- const { text } = await extractText(pdf)
112
- ```
113
-
114
115
  ## API
115
116
 
116
117
  ### `definePDFJSModule`
package/dist/index.cjs CHANGED
@@ -35,7 +35,7 @@ async function resolvePDFJSImport(pdfjsResolver, { reload = false } = {}) {
35
35
  try {
36
36
  resolvedModule = await import('unpdf/pdfjs');
37
37
  } catch (error) {
38
- throw new Error(`Built-in PDF.js module could not be resolved: ${error}`);
38
+ throw new Error(`Serverless PDF.js bundle could not be resolved: ${error}`);
39
39
  }
40
40
  }
41
41
  function isPDFDocumentProxy(data) {
@@ -46,7 +46,7 @@ async function interopDefault(m) {
46
46
  return resolved.default || resolved;
47
47
  }
48
48
 
49
- let canvasModule;
49
+ let resolvedCanvasModule;
50
50
  /**
51
51
  * Derived from the PDF.js project by the Mozilla Foundation.
52
52
  * @see https://github.com/mozilla/pdf.js/blob/b8de9a372f9bbf7e33adb362eeae5ef1919dba73/src/display/canvas_factory.js#L18
@@ -110,21 +110,24 @@ class NodeCanvasFactory extends BaseCanvasFactory {
110
110
  super({ enableHWA });
111
111
  }
112
112
  _createCanvas(width, height) {
113
- if (!canvasModule) {
113
+ if (!resolvedCanvasModule) {
114
114
  throw new Error("@napi-rs/canvas module is not resolved");
115
115
  }
116
- return canvasModule.createCanvas(width, height);
116
+ return resolvedCanvasModule.createCanvas(width, height);
117
117
  }
118
118
  }
119
119
  async function resolveCanvasModule(canvasImport) {
120
- canvasModule ??= await interopDefault(canvasImport());
120
+ resolvedCanvasModule ??= await interopDefault(canvasImport());
121
121
  }
122
122
  function injectCanvasConstructors() {
123
- if (!canvasModule)
123
+ if (!resolvedCanvasModule)
124
124
  return;
125
- globalThis.DOMMatrix ??= canvasModule.DOMMatrix;
126
- globalThis.ImageData ??= canvasModule.ImageData;
127
- globalThis.Path2D ??= canvasModule.Path2D;
125
+ if (typeof globalThis.DOMMatrix === "undefined")
126
+ globalThis.DOMMatrix = resolvedCanvasModule.DOMMatrix;
127
+ if (typeof globalThis.ImageData === "undefined")
128
+ globalThis.ImageData = resolvedCanvasModule.ImageData;
129
+ if (typeof globalThis.Path2D === "undefined")
130
+ globalThis.Path2D = resolvedCanvasModule.Path2D;
128
131
  }
129
132
 
130
133
  async function extractImages$1(data, pageNumber) {
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _napi_rs_canvas from '@napi-rs/canvas';
2
2
  import { DocumentInitParameters, PDFDocumentProxy } from './types/src/display/api';
3
- import * as _PDFJS from './types/src/pdf';
3
+ import * as PDFJS from './types/src/pdf';
4
4
 
5
5
  interface ExtractedImageObject {
6
6
  data: Uint8ClampedArray;
@@ -69,8 +69,6 @@ declare function configureUnPDF(options: {
69
69
  pdfjs?: () => Promise<any>;
70
70
  }): Promise<void>;
71
71
 
72
- type PDFJS = typeof _PDFJS;
73
-
74
72
  /**
75
73
  * Returns a PDFDocumentProxy instance from a given binary data.
76
74
  *
@@ -79,7 +77,7 @@ type PDFJS = typeof _PDFJS;
79
77
  * - `useSystemFonts: true`
80
78
  */
81
79
  declare function getDocumentProxy(data: DocumentInitParameters['data'], options?: DocumentInitParameters): Promise<PDFDocumentProxy>;
82
- declare function getResolvedPDFJS(): Promise<PDFJS>;
80
+ declare function getResolvedPDFJS(): Promise<typeof PDFJS>;
83
81
  declare function resolvePDFJSImport(pdfjsResolver?: () => Promise<any>, { reload }?: {
84
82
  reload?: boolean | undefined;
85
83
  }): Promise<void>;
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _napi_rs_canvas from '@napi-rs/canvas';
2
2
  import { DocumentInitParameters, PDFDocumentProxy } from './types/src/display/api';
3
- import * as _PDFJS from './types/src/pdf';
3
+ import * as PDFJS from './types/src/pdf';
4
4
 
5
5
  interface ExtractedImageObject {
6
6
  data: Uint8ClampedArray;
@@ -69,8 +69,6 @@ declare function configureUnPDF(options: {
69
69
  pdfjs?: () => Promise<any>;
70
70
  }): Promise<void>;
71
71
 
72
- type PDFJS = typeof _PDFJS;
73
-
74
72
  /**
75
73
  * Returns a PDFDocumentProxy instance from a given binary data.
76
74
  *
@@ -79,7 +77,7 @@ type PDFJS = typeof _PDFJS;
79
77
  * - `useSystemFonts: true`
80
78
  */
81
79
  declare function getDocumentProxy(data: DocumentInitParameters['data'], options?: DocumentInitParameters): Promise<PDFDocumentProxy>;
82
- declare function getResolvedPDFJS(): Promise<PDFJS>;
80
+ declare function getResolvedPDFJS(): Promise<typeof PDFJS>;
83
81
  declare function resolvePDFJSImport(pdfjsResolver?: () => Promise<any>, { reload }?: {
84
82
  reload?: boolean | undefined;
85
83
  }): Promise<void>;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _napi_rs_canvas from '@napi-rs/canvas';
2
2
  import { DocumentInitParameters, PDFDocumentProxy } from './types/src/display/api';
3
- import * as _PDFJS from './types/src/pdf';
3
+ import * as PDFJS from './types/src/pdf';
4
4
 
5
5
  interface ExtractedImageObject {
6
6
  data: Uint8ClampedArray;
@@ -69,8 +69,6 @@ declare function configureUnPDF(options: {
69
69
  pdfjs?: () => Promise<any>;
70
70
  }): Promise<void>;
71
71
 
72
- type PDFJS = typeof _PDFJS;
73
-
74
72
  /**
75
73
  * Returns a PDFDocumentProxy instance from a given binary data.
76
74
  *
@@ -79,7 +77,7 @@ type PDFJS = typeof _PDFJS;
79
77
  * - `useSystemFonts: true`
80
78
  */
81
79
  declare function getDocumentProxy(data: DocumentInitParameters['data'], options?: DocumentInitParameters): Promise<PDFDocumentProxy>;
82
- declare function getResolvedPDFJS(): Promise<PDFJS>;
80
+ declare function getResolvedPDFJS(): Promise<typeof PDFJS>;
83
81
  declare function resolvePDFJSImport(pdfjsResolver?: () => Promise<any>, { reload }?: {
84
82
  reload?: boolean | undefined;
85
83
  }): Promise<void>;
package/dist/index.mjs CHANGED
@@ -33,7 +33,7 @@ async function resolvePDFJSImport(pdfjsResolver, { reload = false } = {}) {
33
33
  try {
34
34
  resolvedModule = await import('unpdf/pdfjs');
35
35
  } catch (error) {
36
- throw new Error(`Built-in PDF.js module could not be resolved: ${error}`);
36
+ throw new Error(`Serverless PDF.js bundle could not be resolved: ${error}`);
37
37
  }
38
38
  }
39
39
  function isPDFDocumentProxy(data) {
@@ -44,7 +44,7 @@ async function interopDefault(m) {
44
44
  return resolved.default || resolved;
45
45
  }
46
46
 
47
- let canvasModule;
47
+ let resolvedCanvasModule;
48
48
  /**
49
49
  * Derived from the PDF.js project by the Mozilla Foundation.
50
50
  * @see https://github.com/mozilla/pdf.js/blob/b8de9a372f9bbf7e33adb362eeae5ef1919dba73/src/display/canvas_factory.js#L18
@@ -108,21 +108,24 @@ class NodeCanvasFactory extends BaseCanvasFactory {
108
108
  super({ enableHWA });
109
109
  }
110
110
  _createCanvas(width, height) {
111
- if (!canvasModule) {
111
+ if (!resolvedCanvasModule) {
112
112
  throw new Error("@napi-rs/canvas module is not resolved");
113
113
  }
114
- return canvasModule.createCanvas(width, height);
114
+ return resolvedCanvasModule.createCanvas(width, height);
115
115
  }
116
116
  }
117
117
  async function resolveCanvasModule(canvasImport) {
118
- canvasModule ??= await interopDefault(canvasImport());
118
+ resolvedCanvasModule ??= await interopDefault(canvasImport());
119
119
  }
120
120
  function injectCanvasConstructors() {
121
- if (!canvasModule)
121
+ if (!resolvedCanvasModule)
122
122
  return;
123
- globalThis.DOMMatrix ??= canvasModule.DOMMatrix;
124
- globalThis.ImageData ??= canvasModule.ImageData;
125
- globalThis.Path2D ??= canvasModule.Path2D;
123
+ if (typeof globalThis.DOMMatrix === "undefined")
124
+ globalThis.DOMMatrix = resolvedCanvasModule.DOMMatrix;
125
+ if (typeof globalThis.ImageData === "undefined")
126
+ globalThis.ImageData = resolvedCanvasModule.ImageData;
127
+ if (typeof globalThis.Path2D === "undefined")
128
+ globalThis.Path2D = resolvedCanvasModule.Path2D;
126
129
  }
127
130
 
128
131
  async function extractImages$1(data, pageNumber) {