@docmentis/udoc-viewer 0.4.2 → 0.4.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,16 +1,16 @@
1
1
  # @docmentis/udoc-viewer
2
2
 
3
- Embedded document viewer and headless document parsing/rendering API, powered by WebAssembly.
3
+ Universal Document Viewer built on top of a WebAssembly engine.
4
4
 
5
5
  **Free. Unlimited. Forever.** Provided by [docMentis.com](https://docmentis.com).
6
6
 
7
7
  ## Supported Formats
8
8
 
9
- | Format | Extensions | Notes |
10
- |--------|------------|-------|
11
- | PDF | .pdf | |
12
- | PPTX | .pptx | Early stage - shapes, text, images, gradients supported |
13
- | Images | .jpg, .jpeg, .png, .gif, .bmp, .tif, .tiff, .webp, .ico, .tga, .ppm, .pgm, .pbm, .hdr, .exr, .qoi | Multi-page TIFF supported |
9
+ | Format | Extensions |
10
+ |--------|------------|
11
+ | PDF | .pdf |
12
+ | PPTX | .pptx |
13
+ | Images | .jpg, .jpeg, .png, .gif, .bmp, .tif, .tiff, .webp, .ico, .tga, .ppm, .pgm, .pbm, .hdr, .exr, .qoi |
14
14
 
15
15
  ## Installation
16
16
 
@@ -28,7 +28,7 @@ const client = await UDocClient.create();
28
28
 
29
29
  // Create a viewer attached to a container element
30
30
  const viewer = await client.createViewer({
31
- container: '#viewer'
31
+ container: '#viewer',
32
32
  });
33
33
 
34
34
  // Load a document
@@ -57,11 +57,27 @@ await viewer.load(new Uint8Array(buffer));
57
57
  viewer.close();
58
58
  ```
59
59
 
60
+ ## Password-Protected Documents
61
+
62
+ When a password-protected document is loaded in UI mode, the viewer automatically prompts the user to enter the password. For headless mode, you can handle it programmatically:
63
+
64
+ ```typescript
65
+ await viewer.load(source);
66
+
67
+ if (await viewer.needsPassword()) {
68
+ const success = await viewer.authenticate('my-password');
69
+ if (!success) {
70
+ console.error('Incorrect password');
71
+ }
72
+ }
73
+ ```
74
+
60
75
  ## Client Options
61
76
 
62
77
  ```typescript
63
78
  const client = await UDocClient.create({
64
79
  // Custom base URL for worker and WASM files (optional)
80
+ // Expected files: {baseUrl}/worker.js and {baseUrl}/udoc_bg.wasm
65
81
  baseUrl: 'https://cdn.example.com/udoc/',
66
82
  });
67
83
  ```
@@ -70,32 +86,46 @@ const client = await UDocClient.create({
70
86
 
71
87
  ```typescript
72
88
  const viewer = await client.createViewer({
73
- // Container element or CSS selector (required for UI mode)
89
+ // Container element or CSS selector (required for UI mode, omit for headless)
74
90
  container: '#viewer',
75
91
 
76
- // Scroll mode: 'continuous' or 'single-page'
77
- scrollMode: ScrollMode.Continuous,
92
+ // Scroll mode: 'continuous' or 'spread' (default: 'continuous')
93
+ scrollMode: 'continuous',
78
94
 
79
- // Layout mode: 'single-page', 'two-page', 'two-page-cover'
80
- layoutMode: LayoutMode.SinglePage,
95
+ // Layout mode: 'single-page', 'double-page', 'double-page-odd-right', 'double-page-odd-left'
96
+ // (default: 'single-page')
97
+ layoutMode: 'single-page',
81
98
 
82
- // Zoom mode: 'fit-width', 'fit-page', 'fit-height', 'actual-size', 'custom'
83
- zoomMode: ZoomMode.FitSpreadWidth,
99
+ // Zoom mode: 'fit-spread-width', 'fit-spread-height', 'fit-spread', 'custom'
100
+ // (default: 'fit-spread-width')
101
+ zoomMode: 'fit-spread-width',
84
102
 
85
- // Initial zoom level (when zoomMode is 'custom')
103
+ // Initial zoom level (when zoomMode is 'custom', default: 1)
86
104
  zoom: 1,
87
105
 
88
106
  // Custom zoom steps for zoom in/out
89
- zoomSteps: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4],
107
+ // (default: [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 5])
108
+ zoomSteps: [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 5],
90
109
 
91
- // Spacing between pages in pixels
110
+ // Spacing between pages in pixels (default: 10)
92
111
  pageSpacing: 10,
93
112
 
94
- // Initially active panel: 'thumbnails', 'outline', or null
113
+ // Spacing between spreads in pixels (default: 20)
114
+ spreadSpacing: 20,
115
+
116
+ // Initially active panel, or null for no panel (default: null)
117
+ // Left panels: 'thumbnail', 'outline', 'bookmarks', 'layers', 'attachments'
118
+ // Right panels: 'search', 'comments'
95
119
  activePanel: null,
96
120
 
97
121
  // Target display DPI (default: 96)
98
122
  dpi: 96,
123
+
124
+ // Enable Google Fonts for automatic font fetching (default: true)
125
+ googleFonts: true,
126
+
127
+ // Enable performance tracking (default: false)
128
+ enablePerformanceCounter: false,
99
129
  });
100
130
  ```
101
131
 
@@ -105,7 +135,7 @@ const viewer = await client.createViewer({
105
135
  // Get current page (1-based)
106
136
  const page = viewer.currentPage;
107
137
 
108
- // Go to a specific page
138
+ // Go to a specific page (1-based)
109
139
  viewer.goToPage(5);
110
140
 
111
141
  // Navigate to a destination (from outline)
@@ -120,6 +150,10 @@ if (viewer.isLoaded) {
120
150
  // Get page count
121
151
  const total = viewer.pageCount;
122
152
 
153
+ // Get document metadata
154
+ const meta = viewer.metadata;
155
+ console.log(meta?.title, meta?.author);
156
+
123
157
  // Get page dimensions (0-based index)
124
158
  const info = await viewer.getPageInfo(0);
125
159
  console.log(`Page 1: ${info.width} x ${info.height} points`);
@@ -127,7 +161,7 @@ if (viewer.isLoaded) {
127
161
  // Get document outline (table of contents)
128
162
  const outline = await viewer.getOutline();
129
163
 
130
- // Get annotations on a page
164
+ // Get annotations on a page (0-based index)
131
165
  const annotations = await viewer.getPageAnnotations(0);
132
166
  }
133
167
  ```
@@ -141,21 +175,34 @@ Render pages to images without UI:
141
175
  const viewer = await client.createViewer();
142
176
  await viewer.load(pdfBytes);
143
177
 
144
- // Render page to ImageData
178
+ // Render page to ImageData (0-based page index)
145
179
  const imageData = await viewer.renderPage(0, { scale: 2 });
146
180
 
147
181
  // Render to Blob
148
182
  const blob = await viewer.renderPage(0, {
149
183
  format: 'blob',
150
- imageType: 'image/png'
184
+ imageType: 'image/png',
151
185
  });
152
186
 
153
187
  // Render to data URL
154
188
  const dataUrl = await viewer.renderPage(0, {
155
189
  format: 'data-url',
156
190
  imageType: 'image/jpeg',
157
- quality: 0.9
191
+ quality: 0.9,
158
192
  });
193
+
194
+ // Render thumbnail
195
+ const thumb = await viewer.renderThumbnail(0, { scale: 1 });
196
+ ```
197
+
198
+ ## Document Export
199
+
200
+ ```typescript
201
+ // Export document as raw bytes
202
+ const bytes = await viewer.toBytes();
203
+
204
+ // Download document as a file
205
+ await viewer.download('document.pdf');
159
206
  ```
160
207
 
161
208
  ## Document Composition
@@ -166,9 +213,9 @@ Compose new documents by cherry-picking and rotating pages:
166
213
  // Create a new document from pages of existing documents
167
214
  const [newDoc] = await client.compose([
168
215
  [
169
- { doc: viewerA, pages: "1-3" },
170
- { doc: viewerB, pages: "5", rotation: 90 }
171
- ]
216
+ { doc: viewerA, pages: '1-3' },
217
+ { doc: viewerB, pages: '5', rotation: 90 },
218
+ ],
172
219
  ]);
173
220
 
174
221
  // Export the composed document
@@ -176,6 +223,30 @@ const bytes = await newDoc.toBytes();
176
223
  await newDoc.download('composed.pdf');
177
224
  ```
178
225
 
226
+ ## Document Utilities
227
+
228
+ ```typescript
229
+ // Split a document by its outline (table of contents)
230
+ const { viewers, sections } = await client.splitByOutline(source, {
231
+ maxLevel: 2,
232
+ splitMidPage: false,
233
+ });
234
+
235
+ // Extract images from a document
236
+ const images = await client.extractImages(source, {
237
+ convertRawToPng: true,
238
+ });
239
+
240
+ // Extract fonts from a document
241
+ const fonts = await client.extractFonts(source);
242
+
243
+ // Compress a document
244
+ const compressed = await client.compress(source);
245
+
246
+ // Decompress a document
247
+ const decompressed = await client.decompress(source);
248
+ ```
249
+
179
250
  ## Events
180
251
 
181
252
  ```typescript
@@ -189,6 +260,11 @@ viewer.on('document:close', () => {
189
260
  console.log('Document closed');
190
261
  });
191
262
 
263
+ // Download progress
264
+ viewer.on('download:progress', ({ loaded, total, percent }) => {
265
+ console.log(`Downloaded ${loaded}/${total} bytes (${percent}%)`);
266
+ });
267
+
192
268
  // Error occurred
193
269
  viewer.on('error', ({ error, phase }) => {
194
270
  console.error(`Error during ${phase}:`, error);
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docmentis/udoc-viewer",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Universal document viewer for PDF and PPTX files",
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docmentis/udoc-viewer",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Universal document viewer for PDF and PPTX files",