@docmentis/udoc-viewer 0.4.3 → 0.5.0

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,26 +1,43 @@
1
1
  # @docmentis/udoc-viewer
2
2
 
3
- Embedded document viewer and headless document parsing/rendering API, powered by WebAssembly.
3
+ A free, open-source, universal document viewer for the web. Render PDF, PPTX, and images with high fidelity — no server required.
4
4
 
5
- **Free. Unlimited. Forever.** Provided by [docMentis.com](https://docmentis.com).
5
+ [![npm version](https://img.shields.io/npm/v/@docmentis/udoc-viewer)](https://www.npmjs.com/package/@docmentis/udoc-viewer)
6
+ [![license](https://img.shields.io/npm/l/@docmentis/udoc-viewer)](./LICENSE)
7
+
8
+ **[Live Demo](https://docmentis.com/viewer/demo)** · **[Guide](https://docmentis.com/viewer/guide)** · **[Report Issue](https://github.com/docmentis/udoc-viewer/issues)**
9
+
10
+ ---
11
+
12
+ ## Why udoc-viewer?
13
+
14
+ Most web document viewers only handle PDF, rely on server-side rendering, or require expensive commercial licenses. udoc-viewer is different:
15
+
16
+ - **Truly universal** — PDF, PowerPoint, and images in a single viewer, with more formats coming
17
+ - **High fidelity** — powered by a custom Rust/WebAssembly rendering engine, not PDF.js
18
+ - **Client-side only** — everything runs in the browser, no server round-trips
19
+ - **Framework agnostic** — works with React, Vue, Angular, Svelte, or plain HTML
20
+ - **Free for commercial use** — MIT-licensed wrapper, free WASM engine
6
21
 
7
22
  ## Supported Formats
8
23
 
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 |
24
+ | Format | Extensions |
25
+ |--------|------------|
26
+ | PDF | .pdf |
27
+ | PPTX | .pptx |
28
+ | Images | .png, .jpg, .jpeg, .gif, .webp, .bmp, .tif, .tiff, .ico, .tga, .ppm, .pgm, .pbm, .hdr, .exr, .qoi |
14
29
 
15
- ## Installation
30
+ ## Quick Start
31
+
32
+ ### Install
16
33
 
17
34
  ```bash
18
35
  npm install @docmentis/udoc-viewer
19
36
  ```
20
37
 
21
- ## Quick Start
38
+ ### Basic Usage
22
39
 
23
- ```typescript
40
+ ```js
24
41
  import { UDocClient } from '@docmentis/udoc-viewer';
25
42
 
26
43
  // Create a client (loads the WASM engine)
@@ -28,7 +45,7 @@ const client = await UDocClient.create();
28
45
 
29
46
  // Create a viewer attached to a container element
30
47
  const viewer = await client.createViewer({
31
- container: '#viewer'
48
+ container: '#viewer',
32
49
  });
33
50
 
34
51
  // Load a document
@@ -39,7 +56,62 @@ viewer.destroy();
39
56
  client.destroy();
40
57
  ```
41
58
 
42
- ## Loading Documents
59
+ ### HTML
60
+
61
+ ```html
62
+ <div id="viewer" style="width: 100%; height: 600px;"></div>
63
+
64
+ <script type="module">
65
+ import { UDocClient } from '@docmentis/udoc-viewer';
66
+
67
+ const client = await UDocClient.create();
68
+ const viewer = await client.createViewer({ container: '#viewer' });
69
+ await viewer.load('/path/to/document.pdf');
70
+ </script>
71
+ ```
72
+
73
+ ### React
74
+
75
+ ```jsx
76
+ import { useEffect, useRef } from 'react';
77
+ import { UDocClient } from '@docmentis/udoc-viewer';
78
+
79
+ function DocumentViewer({ src }) {
80
+ const containerRef = useRef(null);
81
+
82
+ useEffect(() => {
83
+ let client, viewer;
84
+
85
+ (async () => {
86
+ client = await UDocClient.create();
87
+ viewer = await client.createViewer({
88
+ container: containerRef.current,
89
+ });
90
+ await viewer.load(src);
91
+ })();
92
+
93
+ return () => {
94
+ viewer?.destroy();
95
+ client?.destroy();
96
+ };
97
+ }, [src]);
98
+
99
+ return <div ref={containerRef} style={{ width: '100%', height: '600px' }} />;
100
+ }
101
+ ```
102
+
103
+ ## Features
104
+
105
+ - 📄 **Multi-format rendering** — PDF, PPTX, and images in one unified viewer
106
+ - 🎯 **High-fidelity output** — custom Rust rendering engine compiled to WebAssembly
107
+ - 🔍 **Zoom & navigation** — toolbar with zoom controls, page thumbnails, and keyboard navigation
108
+ - 📱 **Responsive** — works on desktop and mobile browsers
109
+ - 🌊 **Streaming** — pages render progressively as the document loads
110
+ - 🔒 **Private** — documents never leave the browser; no server upload required
111
+
112
+ ## API Reference
113
+
114
+ ### Loading Documents
43
115
 
44
116
  The viewer accepts multiple document sources:
45
117
 
@@ -57,62 +129,92 @@ await viewer.load(new Uint8Array(buffer));
57
129
  viewer.close();
58
130
  ```
59
131
 
60
- ## Client Options
132
+ ### Password-Protected Documents
133
+
134
+ 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:
135
+
136
+ ```typescript
137
+ await viewer.load(source);
138
+
139
+ if (await viewer.needsPassword()) {
140
+ const success = await viewer.authenticate('my-password');
141
+ if (!success) {
142
+ console.error('Incorrect password');
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### Client Options
61
148
 
62
149
  ```typescript
63
150
  const client = await UDocClient.create({
64
151
  // Custom base URL for worker and WASM files (optional)
152
+ // Expected files: {baseUrl}/worker.js and {baseUrl}/udoc_bg.wasm
65
153
  baseUrl: 'https://cdn.example.com/udoc/',
66
154
  });
67
155
  ```
68
156
 
69
- ## Viewer Options
157
+ ### Viewer Options
70
158
 
71
159
  ```typescript
72
160
  const viewer = await client.createViewer({
73
- // Container element or CSS selector (required for UI mode)
161
+ // Container element or CSS selector (required for UI mode, omit for headless)
74
162
  container: '#viewer',
75
163
 
76
- // Scroll mode: 'continuous' or 'single-page'
77
- scrollMode: ScrollMode.Continuous,
164
+ // Scroll mode: 'continuous' or 'spread' (default: 'continuous')
165
+ scrollMode: 'continuous',
78
166
 
79
- // Layout mode: 'single-page', 'two-page', 'two-page-cover'
80
- layoutMode: LayoutMode.SinglePage,
167
+ // Layout mode: 'single-page', 'double-page', 'double-page-odd-right', 'double-page-odd-left'
168
+ // (default: 'single-page')
169
+ layoutMode: 'single-page',
81
170
 
82
- // Zoom mode: 'fit-width', 'fit-page', 'fit-height', 'actual-size', 'custom'
83
- zoomMode: ZoomMode.FitSpreadWidth,
171
+ // Zoom mode: 'fit-spread-width', 'fit-spread-height', 'fit-spread', 'custom'
172
+ // (default: 'fit-spread-width')
173
+ zoomMode: 'fit-spread-width',
84
174
 
85
- // Initial zoom level (when zoomMode is 'custom')
175
+ // Initial zoom level (when zoomMode is 'custom', default: 1)
86
176
  zoom: 1,
87
177
 
88
178
  // Custom zoom steps for zoom in/out
89
- zoomSteps: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4],
179
+ // (default: [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 5])
180
+ zoomSteps: [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 5],
90
181
 
91
- // Spacing between pages in pixels
182
+ // Spacing between pages in pixels (default: 10)
92
183
  pageSpacing: 10,
93
184
 
94
- // Initially active panel: 'thumbnails', 'outline', or null
185
+ // Spacing between spreads in pixels (default: 20)
186
+ spreadSpacing: 20,
187
+
188
+ // Initially active panel, or null for no panel (default: null)
189
+ // Left panels: 'thumbnail', 'outline', 'bookmarks', 'layers', 'attachments'
190
+ // Right panels: 'search', 'comments'
95
191
  activePanel: null,
96
192
 
97
193
  // Target display DPI (default: 96)
98
194
  dpi: 96,
195
+
196
+ // Enable Google Fonts for automatic font fetching (default: true)
197
+ googleFonts: true,
198
+
199
+ // Enable performance tracking (default: false)
200
+ enablePerformanceCounter: false,
99
201
  });
100
202
  ```
101
203
 
102
- ## Navigation
204
+ ### Navigation
103
205
 
104
206
  ```typescript
105
207
  // Get current page (1-based)
106
208
  const page = viewer.currentPage;
107
209
 
108
- // Go to a specific page
210
+ // Go to a specific page (1-based)
109
211
  viewer.goToPage(5);
110
212
 
111
213
  // Navigate to a destination (from outline)
112
214
  viewer.goToDestination(destination);
113
215
  ```
114
216
 
115
- ## Document Information
217
+ ### Document Information
116
218
 
117
219
  ```typescript
118
220
  // Check if document is loaded
@@ -120,6 +222,10 @@ if (viewer.isLoaded) {
120
222
  // Get page count
121
223
  const total = viewer.pageCount;
122
224
 
225
+ // Get document metadata
226
+ const meta = viewer.metadata;
227
+ console.log(meta?.title, meta?.author);
228
+
123
229
  // Get page dimensions (0-based index)
124
230
  const info = await viewer.getPageInfo(0);
125
231
  console.log(`Page 1: ${info.width} x ${info.height} points`);
@@ -127,12 +233,12 @@ if (viewer.isLoaded) {
127
233
  // Get document outline (table of contents)
128
234
  const outline = await viewer.getOutline();
129
235
 
130
- // Get annotations on a page
236
+ // Get annotations on a page (0-based index)
131
237
  const annotations = await viewer.getPageAnnotations(0);
132
238
  }
133
239
  ```
134
240
 
135
- ## Headless Rendering
241
+ ### Headless Rendering
136
242
 
137
243
  Render pages to images without UI:
138
244
 
@@ -141,24 +247,37 @@ Render pages to images without UI:
141
247
  const viewer = await client.createViewer();
142
248
  await viewer.load(pdfBytes);
143
249
 
144
- // Render page to ImageData
250
+ // Render page to ImageData (0-based page index)
145
251
  const imageData = await viewer.renderPage(0, { scale: 2 });
146
252
 
147
253
  // Render to Blob
148
254
  const blob = await viewer.renderPage(0, {
149
255
  format: 'blob',
150
- imageType: 'image/png'
256
+ imageType: 'image/png',
151
257
  });
152
258
 
153
259
  // Render to data URL
154
260
  const dataUrl = await viewer.renderPage(0, {
155
261
  format: 'data-url',
156
262
  imageType: 'image/jpeg',
157
- quality: 0.9
263
+ quality: 0.9,
158
264
  });
265
+
266
+ // Render thumbnail
267
+ const thumb = await viewer.renderThumbnail(0, { scale: 1 });
159
268
  ```
160
269
 
161
- ## Document Composition
270
+ ### Document Export
271
+
272
+ ```typescript
273
+ // Export document as raw bytes
274
+ const bytes = await viewer.toBytes();
275
+
276
+ // Download document as a file
277
+ await viewer.download('document.pdf');
278
+ ```
279
+
280
+ ### Document Composition
162
281
 
163
282
  Compose new documents by cherry-picking and rotating pages:
164
283
 
@@ -166,9 +285,9 @@ Compose new documents by cherry-picking and rotating pages:
166
285
  // Create a new document from pages of existing documents
167
286
  const [newDoc] = await client.compose([
168
287
  [
169
- { doc: viewerA, pages: "1-3" },
170
- { doc: viewerB, pages: "5", rotation: 90 }
171
- ]
288
+ { doc: viewerA, pages: '1-3' },
289
+ { doc: viewerB, pages: '5', rotation: 90 },
290
+ ],
172
291
  ]);
173
292
 
174
293
  // Export the composed document
@@ -176,7 +295,31 @@ const bytes = await newDoc.toBytes();
176
295
  await newDoc.download('composed.pdf');
177
296
  ```
178
297
 
179
- ## Events
298
+ ### Document Utilities
299
+
300
+ ```typescript
301
+ // Split a document by its outline (table of contents)
302
+ const { viewers, sections } = await client.splitByOutline(source, {
303
+ maxLevel: 2,
304
+ splitMidPage: false,
305
+ });
306
+
307
+ // Extract images from a document
308
+ const images = await client.extractImages(source, {
309
+ convertRawToPng: true,
310
+ });
311
+
312
+ // Extract fonts from a document
313
+ const fonts = await client.extractFonts(source);
314
+
315
+ // Compress a document
316
+ const compressed = await client.compress(source);
317
+
318
+ // Decompress a document
319
+ const decompressed = await client.decompress(source);
320
+ ```
321
+
322
+ ### Events
180
323
 
181
324
  ```typescript
182
325
  // Document loaded
@@ -189,6 +332,11 @@ viewer.on('document:close', () => {
189
332
  console.log('Document closed');
190
333
  });
191
334
 
335
+ // Download progress
336
+ viewer.on('download:progress', ({ loaded, total, percent }) => {
337
+ console.log(`Downloaded ${loaded}/${total} bytes (${percent}%)`);
338
+ });
339
+
192
340
  // Error occurred
193
341
  viewer.on('error', ({ error, phase }) => {
194
342
  console.error(`Error during ${phase}:`, error);
@@ -198,6 +346,38 @@ viewer.on('error', ({ error, phase }) => {
198
346
  unsubscribe();
199
347
  ```
200
348
 
349
+ ## How It Works
350
+
351
+ udoc-viewer uses a custom document processing engine written in Rust, compiled to WebAssembly. Documents are parsed and rendered entirely in the browser with near-native performance — no PDF.js, no iframe hacks, no server-side conversion.
352
+
353
+ The JavaScript wrapper (`@docmentis/udoc-viewer`) is MIT-licensed and open source. The WASM rendering engine is free to use, including in commercial applications. See [LICENSE](./LICENSE) for details.
354
+
355
+ ## Browser Support
356
+
357
+ | Browser | Supported |
358
+ |---------|-----------|
359
+ | Chrome / Edge | ✅ 80+ |
360
+ | Firefox | ✅ 80+ |
361
+ | Safari | ✅ 15+ |
362
+
363
+ Requires WebAssembly support.
364
+
365
+ ## Contributing
366
+
367
+ We welcome bug reports, feature requests, and pull requests.
368
+
369
+ - **Issues**: [github.com/docmentis/udoc-viewer/issues](https://github.com/docmentis/udoc-viewer/issues)
370
+ - **Discussions**: [github.com/docmentis/udoc-viewer/discussions](https://github.com/docmentis/udoc-viewer/discussions)
371
+
201
372
  ## License
202
373
 
203
- MIT
374
+ The JavaScript/TypeScript source code is licensed under the [MIT License](../../LICENSE).
375
+
376
+ The WebAssembly binary (`src/wasm/udoc_bg.wasm`) is distributed under the [docMentis WASM Runtime License](src/wasm/LICENSE) -- free to use with the docMentis Viewer in commercial and non-commercial applications.
377
+
378
+ ## Links
379
+
380
+ - 🌐 [docmentis.com](https://docmentis.com)
381
+ - 📦 [npm package](https://www.npmjs.com/package/@docmentis/udoc-viewer)
382
+ - 📂 [GitHub](https://github.com/docmentis/udoc-viewer)
383
+ - 💬 [Report an issue](https://github.com/docmentis/udoc-viewer/issues)
package/dist/package.json CHANGED
@@ -1,14 +1,30 @@
1
1
  {
2
2
  "name": "@docmentis/udoc-viewer",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
- "description": "Universal document viewer for PDF and PPTX files",
6
+ "description": "Free, open-source, universal document viewer for the web. Render PDF, PPTX, and images with high fidelity — no server required.",
7
+ "homepage": "https://docmentis.com/viewer/guide",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/docmentis/udoc-viewer.git",
11
+ "directory": "packages/udoc-viewer"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/docmentis/udoc-viewer/issues"
15
+ },
7
16
  "keywords": [
8
17
  "pdf",
18
+ "pptx",
19
+ "powerpoint",
9
20
  "viewer",
10
21
  "document",
11
- "wasm"
22
+ "document-viewer",
23
+ "pdf-viewer",
24
+ "wasm",
25
+ "webassembly",
26
+ "image-viewer",
27
+ "client-side"
12
28
  ],
13
29
  "main": "dist/src/index.js",
14
30
  "types": "dist/src/index.d.ts",
@@ -0,0 +1,104 @@
1
+ docMentis WASM Runtime License
2
+
3
+ Version 1.0
4
+
5
+ Copyright (c) 2026 docMentis
6
+ All rights reserved.
7
+
8
+ 1. Definitions
9
+
10
+ "Software" means the docMentis WebAssembly ("WASM") runtime and all
11
+ associated binary artifacts distributed by docMentis.
12
+
13
+ "Viewer" means the open-source JavaScript/TypeScript viewer published by
14
+ docMentis that loads and interacts with the Software.
15
+
16
+ "You" means the individual or legal entity using the Software.
17
+
18
+ "Derivative Work" means any modification, adaptation, or work based on
19
+ the Software.
20
+
21
+ 2. License Grant
22
+
23
+ Subject to the terms of this License, docMentis grants You a non-exclusive,
24
+ worldwide, royalty-free license to:
25
+
26
+ (a) Use the Software solely in conjunction with the docMentis Viewer;
27
+ (b) Redistribute the unmodified Software as bundled with the Viewer;
28
+ (c) Use the Software in commercial or non-commercial applications.
29
+
30
+ This License does not grant You any rights to the Software's source code.
31
+
32
+ 3. Restrictions
33
+
34
+ You may not, directly or indirectly:
35
+
36
+ (a) Reverse engineer, decompile, disassemble, or otherwise attempt to
37
+ derive the source code of the Software;
38
+ (b) Modify, patch, translate, or create Derivative Works of the Software;
39
+ (c) Use the Software independently of the docMentis Viewer;
40
+ (d) Sell, sublicense, rent, lease, or otherwise commercially distribute
41
+ the Software on a standalone basis;
42
+ (e) Use the Software to build or operate a competing document viewer,
43
+ document processing library, or document SaaS platform;
44
+ (f) Remove or obscure any copyright, license, or attribution notices.
45
+
46
+ 4. SaaS and Hosting Limitation
47
+
48
+ You may use the Software in a hosted or SaaS environment only as part of an
49
+ application that embeds the docMentis Viewer for end-user document viewing.
50
+
51
+ Using the Software as part of a document processing service, API product, or
52
+ competing hosted offering requires a separate commercial license from
53
+ docMentis.
54
+
55
+ 5. Ownership
56
+
57
+ The Software is licensed, not sold.
58
+
59
+ docMentis retains all right, title, and interest in and to the Software,
60
+ including all intellectual property rights therein.
61
+
62
+ No rights are granted except as expressly stated in this License.
63
+
64
+ 6. Attribution
65
+
66
+ When redistributing the Software with the Viewer, You must retain all
67
+ copyright and license notices included by docMentis.
68
+
69
+ 7. Termination
70
+
71
+ This License is effective until terminated.
72
+
73
+ docMentis may terminate this License immediately if You violate any of its
74
+ terms. Upon termination, You must cease all use and redistribution of the
75
+ Software.
76
+
77
+ 8. Disclaimer of Warranty
78
+
79
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80
+ IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS
81
+ FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
82
+
83
+ 9. Limitation of Liability
84
+
85
+ IN NO EVENT SHALL DOCMENTIS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
86
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING
87
+ FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
88
+ DEALINGS IN THE SOFTWARE.
89
+
90
+ 10. Future Licensing
91
+
92
+ docMentis may offer alternative licensing terms, including commercial
93
+ licenses, enterprise agreements, or source-available options, in the future.
94
+
95
+ 11. Governing Law
96
+
97
+ This License shall be governed by and construed in accordance with the laws
98
+ of the State of California, USA, without regard to its conflict of law
99
+ principles.
100
+
101
+ 12. Contact
102
+
103
+ For licensing questions or commercial agreements:
104
+ Email: licensing@docmentis.com
Binary file
package/package.json CHANGED
@@ -1,14 +1,30 @@
1
1
  {
2
2
  "name": "@docmentis/udoc-viewer",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
- "description": "Universal document viewer for PDF and PPTX files",
6
+ "description": "Free, open-source, universal document viewer for the web. Render PDF, PPTX, and images with high fidelity — no server required.",
7
+ "homepage": "https://docmentis.com/viewer/guide",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/docmentis/udoc-viewer.git",
11
+ "directory": "packages/udoc-viewer"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/docmentis/udoc-viewer/issues"
15
+ },
7
16
  "keywords": [
8
17
  "pdf",
18
+ "pptx",
19
+ "powerpoint",
9
20
  "viewer",
10
21
  "document",
11
- "wasm"
22
+ "document-viewer",
23
+ "pdf-viewer",
24
+ "wasm",
25
+ "webassembly",
26
+ "image-viewer",
27
+ "client-side"
12
28
  ],
13
29
  "main": "dist/src/index.js",
14
30
  "types": "dist/src/index.d.ts",